kfree(pointer);
}
EXPORT_SYMBOL_GPL(CsrMemFree);
+
+/*----------------------------------------------------------------------------*
+ * NAME
+ * CsrMemAllocDma
+ *
+ * DESCRIPTION
+ * Allocate DMA capable dynamic memory of a given size.
+ *
+ * RETURNS
+ * Pointer to allocated memory, or NULL in case of failure.
+ * Allocated memory is not initialised.
+ *
+ *----------------------------------------------------------------------------*/
+void *CsrMemAllocDma(CsrSize size)
+{
+ return kmalloc(size, GFP_KERNEL | GFP_DMA);
+}
+EXPORT_SYMBOL_GPL(CsrMemAllocDma);
+
+/*----------------------------------------------------------------------------*
+ * NAME
+ * CsrMemFreeDma
+ *
+ * DESCRIPTION
+ * Free DMA capable dynamic allocated memory.
+ *
+ * RETURNS
+ * void
+ *
+ *----------------------------------------------------------------------------*/
+void CsrMemFreeDma(void *pointer)
+{
+ kfree(pointer);
+}
+EXPORT_SYMBOL_GPL(CsrMemFreeDma);
#include <stddef.h>
#include <sys/types.h>
#include <stdarg.h>
+#include <string.h>
#endif
#ifdef __cplusplus
/*------------------------------------------------------------------*/
/* String */
/*------------------------------------------------------------------*/
+#ifndef CSR_USE_STDC_LIB
void *CsrMemCpy(void *dest, const void *src, CsrSize count)
{
return memcpy(dest, src, count);
return buf2;
}
+#endif
+#ifndef CSR_USE_STDC_LIB
CsrCharString *CsrStrCpy(CsrCharString *dest, const CsrCharString *src)
{
return strcpy(dest, src);
{
return strchr(string, c);
}
+#endif
CsrInt32 CsrVsnprintf(CsrCharString *string, CsrSize count, const CsrCharString *format, va_list args)
{
void CsrUInt32ToHex(CsrUint32 number, CsrCharString *str);
/*------------------------------------------------------------------*/
-/* String */
+/* Standard C Library functions */
/*------------------------------------------------------------------*/
+#ifdef CSR_USE_STDC_LIB
+#define CsrMemCpy memcpy
+#define CsrMemMove memmove
+#define CsrStrCpy strcpy
+#define CsrStrNCpy strncpy
+#define CsrStrCat strcat
+#define CsrStrNCat strncat
+#define CsrMemCmp(s1, s2, n) ((CsrInt32) memcmp((s1), (s2), (n)))
+#define CsrStrCmp(s1, s2) ((CsrInt32) strcmp((s1), (s2)))
+#define CsrStrNCmp(s1, s2, n) ((CsrInt32) strncmp((s1), (s2), (n)))
+/*#define CsrMemChr memchr*/
+#define CsrStrChr strchr
+/*#define CsrStrCSpn strcspn*/
+/*#define CsrStrPBrk strpbrk*/
+/*#define CsrStrRChr strrchr*/
+/*#define CsrStrSpn strspn*/
+#define CsrStrStr strstr
+/*#define CsrStrTok strtok*/
+#define CsrMemSet memset
+#define CsrStrLen strlen
+/*#define CsrVsnprintf(s, n, format, arg) ((CsrInt32) vsnprintf((s), (n), (format), (arg)))*/
+#else /* !CSR_USE_STDC_LIB */
void *CsrMemCpy(void *dest, const void *src, CsrSize count);
-void *CsrMemSet(void *dest, CsrUint8 c, CsrSize count);
void *CsrMemMove(void *dest, const void *src, CsrSize count);
-CsrInt32 CsrMemCmp(const void *buf1, const void *buf2, CsrSize count);
-void *CsrMemDup(const void *buf1, CsrSize count);
CsrCharString *CsrStrCpy(CsrCharString *dest, const CsrCharString *src);
CsrCharString *CsrStrNCpy(CsrCharString *dest, const CsrCharString *src, CsrSize count);
-int CsrStrNICmp(const CsrCharString *string1, const CsrCharString *string2, CsrSize count);
CsrCharString *CsrStrCat(CsrCharString *dest, const CsrCharString *src);
CsrCharString *CsrStrNCat(CsrCharString *dest, const CsrCharString *src, CsrSize count);
-CsrCharString *CsrStrStr(const CsrCharString *string1, const CsrCharString *string2);
-CsrSize CsrStrLen(const CsrCharString *string);
+CsrInt32 CsrMemCmp(const void *buf1, const void *buf2, CsrSize count);
CsrInt32 CsrStrCmp(const CsrCharString *string1, const CsrCharString *string2);
CsrInt32 CsrStrNCmp(const CsrCharString *string1, const CsrCharString *string2, CsrSize count);
-CsrCharString *CsrStrDup(const CsrCharString *string);
CsrCharString *CsrStrChr(const CsrCharString *string, CsrCharString c);
-CsrUint32 CsrStrToInt(const CsrCharString *string);
+CsrCharString *CsrStrStr(const CsrCharString *string1, const CsrCharString *string2);
+void *CsrMemSet(void *dest, CsrUint8 c, CsrSize count);
+CsrSize CsrStrLen(const CsrCharString *string);
+#endif /* !CSR_USE_STDC_LIB */
CsrInt32 CsrVsnprintf(CsrCharString *string, CsrSize count, const CsrCharString *format, va_list args);
+
+/*------------------------------------------------------------------*/
+/* Non-standard utility functions */
+/*------------------------------------------------------------------*/
+void *CsrMemDup(const void *buf1, CsrSize count);
+int CsrStrNICmp(const CsrCharString *string1, const CsrCharString *string2, CsrSize count);
+CsrCharString *CsrStrDup(const CsrCharString *string);
+CsrUint32 CsrStrToInt(const CsrCharString *string);
CsrCharString *CsrStrNCpyZero(CsrCharString *dest, const CsrCharString *src, CsrSize count);
/*------------------------------------------------------------------*/
#define CSR_WIFI_RESULT_INVALID_INTERFACE_TAG ((CsrResult) 0x000B)
#define CSR_WIFI_RESULT_P2P_NOA_CONFIG_CONFLICT ((CsrResult) 0x000C)
-#define CSR_WIFI_VERSION "5.0.3.0"
+#define CSR_WIFI_VERSION "5.1.0.0"
#ifdef __cplusplus
}
/*****************************************************************************
- (c) Cambridge Silicon Radio Limited 2011
+ (c) Cambridge Silicon Radio Limited 2012
All rights reserved and confidential information of CSR
Refer to LICENSE.txt included with this source for details
*/
void CardClearFromHostDataSlot(card_t *card, const CsrInt16 aSlotNum);
+#ifdef CSR_WIFI_REQUEUE_PACKET_TO_HAL
+/*****************************************************************************
+ * CardClearFromHostDataSlotWithoutFreeingBulkData - Clear the data stot
+ * without freeing the bulk data
+ */
+
+void CardClearFromHostDataSlotWithoutFreeingBulkData(card_t *card, const CsrInt16 aSlotNum);
+#endif
+
/*****************************************************************************
* CardGetFreeFromHostDataSlots -
*/
/*****************************************************************************
- (c) Cambridge Silicon Radio Limited 2011
+ (c) Cambridge Silicon Radio Limited 2012
All rights reserved and confidential information of CSR
Refer to LICENSE.txt included with this source for details
* have requested a mini-coredump which needs to be captured now the
* SDIO interface is alive.
*/
- unifi_coredump_handle_request(card);
+ (void)unifi_coredump_handle_request(card);
/*
* Probe to see if the UniFi has ROM/flash to boot from. CSR6xxx should do.
/* Reset any state carried forward from a previous life */
card->fh_command_queue.q_rd_ptr = 0;
card->fh_command_queue.q_wr_ptr = 0;
- CsrSnprintf(card->fh_command_queue.name, UNIFI_QUEUE_NAME_MAX_LENGTH,
- "fh_cmd_q");
+ (void)CsrSnprintf(card->fh_command_queue.name, UNIFI_QUEUE_NAME_MAX_LENGTH,
+ "fh_cmd_q");
for (i = 0; i < UNIFI_NO_OF_TX_QS; i++)
{
card->fh_traffic_queue[i].q_rd_ptr = 0;
card->fh_traffic_queue[i].q_wr_ptr = 0;
- CsrSnprintf(card->fh_traffic_queue[i].name,
- UNIFI_QUEUE_NAME_MAX_LENGTH, "fh_data_q%d", i);
+ (void)CsrSnprintf(card->fh_traffic_queue[i].name,
+ UNIFI_QUEUE_NAME_MAX_LENGTH, "fh_data_q%d", i);
}
#ifndef CSR_WIFI_HIP_TA_DISABLE
unifi_ta_sampling_init(card);
/*
* Allocate memory for the from-host and to-host signal buffers.
*/
- card->fh_buffer.buf = CsrMemAlloc(UNIFI_FH_BUF_SIZE);
+ card->fh_buffer.buf = CsrMemAllocDma(UNIFI_FH_BUF_SIZE);
if (card->fh_buffer.buf == NULL)
{
unifi_error(card->ospriv, "Failed to allocate memory for F-H signals\n");
card->fh_buffer.ptr = card->fh_buffer.buf;
card->fh_buffer.count = 0;
- card->th_buffer.buf = CsrMemAlloc(UNIFI_FH_BUF_SIZE);
+ card->th_buffer.buf = CsrMemAllocDma(UNIFI_FH_BUF_SIZE);
if (card->th_buffer.buf == NULL)
{
unifi_error(card->ospriv, "Failed to allocate memory for T-H signals\n");
return CSR_WIFI_HIP_RESULT_NO_MEMORY;
}
+ /* Initialise host tag entries for from-host bulk data slots */
+ for (i = 0; i < n; i++)
+ {
+ card->fh_slot_host_tag_record[i] = CSR_WIFI_HIP_RESERVED_HOST_TAG;
+ }
+
/* Allocate memory for the array of pointers */
n = cfg_data->num_tohost_data_slots;
if (card->fh_buffer.buf)
{
- CsrMemFree(card->fh_buffer.buf);
+ CsrMemFreeDma(card->fh_buffer.buf);
}
card->fh_buffer.ptr = card->fh_buffer.buf = NULL;
card->fh_buffer.bufsize = 0;
if (card->th_buffer.buf)
{
- CsrMemFree(card->th_buffer.buf);
+ CsrMemFreeDma(card->th_buffer.buf);
}
card->th_buffer.ptr = card->th_buffer.buf = NULL;
card->th_buffer.bufsize = 0;
/* Reset any state carried forward from a previous life */
card->fh_command_queue.q_rd_ptr = 0;
card->fh_command_queue.q_wr_ptr = 0;
- CsrSnprintf(card->fh_command_queue.name, UNIFI_QUEUE_NAME_MAX_LENGTH,
- "fh_cmd_q");
+ (void)CsrSnprintf(card->fh_command_queue.name, UNIFI_QUEUE_NAME_MAX_LENGTH,
+ "fh_cmd_q");
for (i = 0; i < UNIFI_NO_OF_TX_QS; i++)
{
card->fh_traffic_queue[i].q_rd_ptr = 0;
card->fh_traffic_queue[i].q_wr_ptr = 0;
- CsrSnprintf(card->fh_traffic_queue[i].name,
- UNIFI_QUEUE_NAME_MAX_LENGTH, "fh_data_q%d", i);
+ (void)CsrSnprintf(card->fh_traffic_queue[i].name,
+ UNIFI_QUEUE_NAME_MAX_LENGTH, "fh_data_q%d", i);
}
#ifndef CSR_WIFI_HIP_TA_DISABLE
unifi_ta_sampling_init(card);
} /* CardClearFromHostDataSlot() */
+#ifdef CSR_WIFI_REQUEUE_PACKET_TO_HAL
+/*
+ * ---------------------------------------------------------------------------
+ * CardClearFromHostDataSlotWithoutFreeingBulkData
+ *
+ * Clear the given data slot with out freeing the bulk data.
+ *
+ * Arguments:
+ * card Pointer to Card object
+ * slot Index of the signal slot to clear.
+ *
+ * Returns:
+ * None.
+ * ---------------------------------------------------------------------------
+ */
+void CardClearFromHostDataSlotWithoutFreeingBulkData(card_t *card, const CsrInt16 slot)
+{
+ CsrUint8 queue = card->from_host_data[slot].queue;
+
+ /* Initialise the from_host data slot so it can be re-used,
+ * Set length field in from_host_data array to 0.
+ */
+ UNIFI_INIT_BULK_DATA(&card->from_host_data[slot].bd);
+
+ queue = card->from_host_data[slot].queue;
+
+ if (queue < UNIFI_NO_OF_TX_QS)
+ {
+ if (card->dynamic_slot_data.from_host_used_slots[queue] == 0)
+ {
+ unifi_error(card->ospriv, "Goofed up used slots q = %d used slots = %d\n",
+ queue,
+ card->dynamic_slot_data.from_host_used_slots[queue]);
+ }
+ else
+ {
+ card->dynamic_slot_data.from_host_used_slots[queue]--;
+ }
+ card->dynamic_slot_data.packets_txed[queue]++;
+ card->dynamic_slot_data.total_packets_txed++;
+ if (card->dynamic_slot_data.total_packets_txed >=
+ card->dynamic_slot_data.packets_interval)
+ {
+ CardReassignDynamicReservation(card);
+ }
+ }
+} /* CardClearFromHostDataSlotWithoutFreeingBulkData() */
+
+
+#endif
+
CsrUint16 CardGetDataSlotSize(card_t *card)
{
return card->config_data.data_slot_size;
/*****************************************************************************
- (c) Cambridge Silicon Radio Limited 2011
+ (c) Cambridge Silicon Radio Limited 2012
All rights reserved and confidential information of CSR
Refer to LICENSE.txt included with this source for details
CsrCharString s[5];
CsrUint16 i;
- for (i = 0; i < length; i++)
+ for (i = 0; i < length; i = i + 2)
{
- CsrUInt16ToHex(0xff & buff[i], s);
+ CsrUInt16ToHex(*((CsrUint16 *)(buff + i)), s);
unifi_debug_string_to_buf(s);
}
}
* Then ask the OS layer to run the unifi_bh to give attention to the UniFi.
*/
card->bh_reason_unifi = 1;
- unifi_run_bh(card->ospriv);
+ (void)unifi_run_bh(card->ospriv);
} /* sdio_interrupt_handler() */
(low_power_mode == UNIFI_LOW_POWER_DISABLED)?"disabled" : "enabled",
(periodic_wake_mode == UNIFI_PERIODIC_WAKE_HOST_DISABLED)?"FALSE" : "TRUE");
- unifi_run_bh(card->ospriv);
+ (void)unifi_run_bh(card->ospriv);
return CSR_RESULT_SUCCESS;
} /* unifi_configure_low_power_mode() */
(low_power_mode == UNIFI_LOW_POWER_DISABLED)?"disabled" : "enabled");
/* Try to capture firmware panic codes */
- unifi_capture_panic(card);
+ (void)unifi_capture_panic(card);
/* Ask for a mini-coredump when the driver has reset UniFi */
- unifi_coredump_request_at_next_reset(card, 1);
+ (void)unifi_coredump_request_at_next_reset(card, 1);
}
return r;
return r;
}
}
+
+#ifdef CSR_WIFI_RX_PATH_SPLIT
#ifdef CSR_WIFI_RX_PATH_SPLIT_DONT_USE_WQ
unifi_rx_queue_flush(card->ospriv);
#endif
+#endif
+
/* See if we can re-enable transmission now */
restart_packet_flow(card);
if (status && (card->fh_slot_host_tag_record))
{
CsrUint16 num_fh_slots = card->config_data.num_fromhost_data_slots;
- CsrUint16 i = 0;
/* search through the list of slot records and match with host tag
* If a slot is not yet cleared then clear the slot from here
{
if (card->fh_slot_host_tag_record[i] == host_tag)
{
+#ifdef CSR_WIFI_REQUEUE_PACKET_TO_HAL
+ /* Invoke the HAL module function to requeue it back to HAL Queues */
+ r = unifi_reque_ma_packet_request(card->ospriv, host_tag, status, &card->from_host_data[i].bd);
+ card->fh_slot_host_tag_record[i] = CSR_WIFI_HIP_RESERVED_HOST_TAG;
+ if (CSR_RESULT_SUCCESS != r)
+ {
+ unifi_trace(card->ospriv, UDBG5, "process_to_host_signals: Failed to requeue Packet(hTag:%x) back to HAL \n", host_tag);
+ CardClearFromHostDataSlot(card, i);
+ }
+ else
+ {
+ CardClearFromHostDataSlotWithoutFreeingBulkData(card, i);
+ }
+
+#else
unifi_trace(card->ospriv, UDBG4, "process_to_host_signals Clear slot=%x host tag=%x\n", i, host_tag);
card->fh_slot_host_tag_record[i] = CSR_WIFI_HIP_RESERVED_HOST_TAG;
/* Set length field in from_host_data array to 0 */
CardClearFromHostDataSlot(card, i);
-
+#endif
break;
}
}
if (len != 0 && (dir == UNIFI_SDIO_WRITE) && (((CsrIntptr)bdslot->os_data_ptr + offset) & 3))
{
- host_bulk_data_slot = CsrMemAlloc(len);
+ host_bulk_data_slot = CsrMemAllocDma(len);
if (!host_bulk_data_slot)
{
/* moving this check before we clear host data slot */
if ((len != 0) && (dir == UNIFI_SDIO_WRITE) && (((CsrIntptr)bdslot->os_data_ptr + offset) & 3))
{
- CsrMemFree(host_bulk_data_slot);
+ CsrMemFreeDma(host_bulk_data_slot);
}
#endif
/*****************************************************************************
- (c) Cambridge Silicon Radio Limited 2011
+ (c) Cambridge Silicon Radio Limited 2012
All rights reserved and confidential information of CSR
Refer to LICENSE.txt included with this source for details
*/
if (card->chip_id <= SDIO_CARD_ID_UNIFI_2)
{
- unifi_set_host_state(card, UNIFI_HOST_STATE_AWAKE);
+ (void)unifi_set_host_state(card, UNIFI_HOST_STATE_AWAKE);
}
/* If csr_sdio_block_rw() failed in a non-retryable way, or retries exhausted
/*****************************************************************************
- (c) Cambridge Silicon Radio Limited 2011
+ (c) Cambridge Silicon Radio Limited 2012
All rights reserved and confidential information of CSR
Refer to LICENSE.txt included with this source for details
return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
}
- buf = CsrMemAlloc(buf_size);
+ buf = CsrMemAllocDma(buf_size);
if (buf == NULL)
{
unifi_error(card->ospriv, "Failed to allocate transfer buffer for firmware download\n");
}
}
- CsrMemFree(buf);
+ CsrMemFreeDma(buf);
if (r != CSR_RESULT_SUCCESS && r != CSR_WIFI_HIP_RESULT_NO_DEVICE)
{
/*****************************************************************************
- (c) Cambridge Silicon Radio Limited 2011
+ (c) Cambridge Silicon Radio Limited 2012
All rights reserved and confidential information of CSR
Refer to LICENSE.txt included with this source for details
* Notes:
* ---------------------------------------------------------------------------
*/
-static CsrInt32 get_value_from_coredump(const coredump_buffer *dump,
+static CsrInt32 get_value_from_coredump(const coredump_buffer *coreDump,
const unifi_coredump_space_t space,
const CsrUint16 offset_in_space)
{
{
/* Calculate the offset of data within the zone buffer */
offset_in_zone = offset_in_space - def->offset;
- r = (CsrInt32) * (dump->zone[i] + offset_in_zone);
+ r = (CsrInt32) * (coreDump->zone[i] + offset_in_zone);
unifi_trace(NULL, UDBG6,
"sp %d, offs 0x%04x = 0x%04x (in z%d 0x%04x->0x%04x)\n",
/*****************************************************************************
- (c) Cambridge Silicon Radio Limited 2011
+ (c) Cambridge Silicon Radio Limited 2012
All rights reserved and confidential information of CSR
Refer to LICENSE.txt included with this source for details
#define TA_EAPOL_TYPE_OFFSET 9
#define TA_EAPOL_TYPE_START 0x01
-static const CsrUint8 snap_802_2[3] = { 0xAA, 0xAA, 0x03 };
-static const CsrUint8 oui_rfc1042[3] = { 0x00, 0x00, 0x00 };
-static const CsrUint8 oui_8021h[3] = { 0x00, 0x00, 0xf8 };
+#define snap_802_2 0xAAAA0300
+#define oui_rfc1042 0x00000000
+#define oui_8021h 0x0000f800
static const CsrUint8 aironet_snap[5] = { 0x00, 0x40, 0x96, 0x00, 0x00 };
CsrUint16 proto;
CsrUint16 source_port, dest_port;
CsrWifiMacAddress srcAddress;
+ CsrUint32 snap_hdr, oui_hdr;
if (data->data_length < TA_LLC_HEADER_SIZE)
{
return TA_FRAME_UNKNOWN;
}
- if (CsrMemCmp(data->os_data_ptr, snap_802_2, 3))
+ snap_hdr = (((CsrUint32)data->os_data_ptr[0]) << 24) |
+ (((CsrUint32)data->os_data_ptr[1]) << 16) |
+ (((CsrUint32)data->os_data_ptr[2]) << 8);
+ if (snap_hdr != snap_802_2)
{
return TA_FRAME_UNKNOWN;
}
*/
}
- if (!CsrMemCmp(data->os_data_ptr + 3, oui_rfc1042, 3) ||
- !CsrMemCmp(data->os_data_ptr + 3, oui_8021h, 3))
+ oui_hdr = (((CsrUint32)data->os_data_ptr[3]) << 24) |
+ (((CsrUint32)data->os_data_ptr[4]) << 16) |
+ (((CsrUint32)data->os_data_ptr[5]) << 8);
+ if ((oui_hdr == oui_rfc1042) || (oui_hdr == oui_8021h))
{
proto = (data->os_data_ptr[TA_ETHERNET_TYPE_OFFSET] * 256) +
data->os_data_ptr[TA_ETHERNET_TYPE_OFFSET + 1];
/* The DHCP should have at least a message type (request, ack, nack, etc) */
if (data->data_length > TA_DHCP_MESSAGE_TYPE_OFFSET + 6)
{
- CsrMemCpy(srcAddress.a, saddr, 6);
+ UNIFI_MAC_ADDRESS_COPY(srcAddress.a, saddr);
if (direction == CSR_WIFI_ROUTER_CTRL_PROTOCOL_DIRECTION_TX)
{
}
/* DHCPACK is a special indication */
- if (!CsrMemCmp(data->os_data_ptr + TA_BOOTP_CLIENT_MAC_ADDR_OFFSET, sta_macaddr, 6))
+ if (UNIFI_MAC_ADDRESS_CMP(data->os_data_ptr + TA_BOOTP_CLIENT_MAC_ADDR_OFFSET, sta_macaddr) == TRUE)
{
if (data->os_data_ptr[TA_DHCP_MESSAGE_TYPE_OFFSET] == TA_DHCP_MESSAGE_TYPE_ACK)
{
if ((TA_PROTO_TYPE_WAI == proto) || (direction != CSR_WIFI_ROUTER_CTRL_PROTOCOL_DIRECTION_TX) ||
(data->os_data_ptr[TA_EAPOL_TYPE_OFFSET] == TA_EAPOL_TYPE_START))
{
- CsrMemCpy(srcAddress.a, saddr, 6);
+ UNIFI_MAC_ADDRESS_COPY(srcAddress.a, saddr);
unifi_ta_indicate_protocol(card->ospriv,
CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_EAPOL,
direction, &srcAddress);
{
if (proto == TA_PROTO_TYPE_ARP)
{
- CsrMemCpy(srcAddress.a, saddr, 6);
+ UNIFI_MAC_ADDRESS_COPY(srcAddress.a, saddr);
unifi_ta_indicate_protocol(card->ospriv,
CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_ARP,
direction, &srcAddress);
/* detect Aironet frames */
if (!CsrMemCmp(data->os_data_ptr + 3, aironet_snap, 5))
{
- CsrMemCpy(srcAddress.a, saddr, 6);
+ UNIFI_MAC_ADDRESS_COPY(srcAddress.a, saddr);
unifi_ta_indicate_protocol(card->ospriv, CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_AIRONET,
direction, &srcAddress);
}
/*****************************************************************************
- (c) Cambridge Silicon Radio Limited 2011
+ (c) Cambridge Silicon Radio Limited 2012
All rights reserved and confidential information of CSR
Refer to LICENSE.txt included with this source for details
#include "csr_formatted_io.h" /* from the synergy gsp folder */
#include "csr_wifi_result.h"
+/* Utility MACROS. Note that UNIFI_MAC_ADDRESS_CMP returns TRUE on success */
+#define UNIFI_MAC_ADDRESS_COPY(dst, src) \
+ do { (dst)[0] = (src)[0]; (dst)[1] = (src)[1]; \
+ (dst)[2] = (src)[2]; (dst)[3] = (src)[3]; \
+ (dst)[4] = (src)[4]; (dst)[5] = (src)[5]; \
+ } while (0)
+
+#define UNIFI_MAC_ADDRESS_CMP(addr1, addr2) \
+ (((addr1)[0] == (addr2)[0]) && ((addr1)[1] == (addr2)[1]) && \
+ ((addr1)[2] == (addr2)[2]) && ((addr1)[3] == (addr2)[3]) && \
+ ((addr1)[4] == (addr2)[4]) && ((addr1)[5] == (addr2)[5]))
/* Traffic queue ordered according to priority
* EAPOL/Uncontrolled port Queue should be the last
CsrUint8 *sigdata, CsrUint32 siglen,
const bulk_data_param_t *bulkdata);
+#ifdef CSR_WIFI_REQUEUE_PACKET_TO_HAL
+/**
+ *
+ * Used to reque the failed ma packet request back to hal queues
+ *
+ * @param ospriv the OS layer context.
+ *
+ * @param host_tag host tag for the packet to requeue.
+ *
+ * @param bulkDataDesc pointer to the bulk data.
+ *
+ * @ingroup upperedge
+ */
+CsrResult unifi_reque_ma_packet_request(void *ospriv, CsrUint32 host_tag,
+ CsrUint16 status,
+ bulk_data_desc_t *bulkDataDesc);
+#endif
typedef struct
{
CsrUint16 free_fh_sig_queue_slots[UNIFI_NO_OF_TX_QS];
/* Function to log HIP's global debug buffer */
#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
void unifi_debug_buf_dump(void);
+void unifi_debug_log_to_buf(const CsrCharString *fmt, ...);
+void unifi_debug_hex_to_buf(const CsrCharString *buff, CsrUint16 length);
#endif
/* Mini-coredump utility functions */
/*****************************************************************************
- (c) Cambridge Silicon Radio Limited 2011
+ (c) Cambridge Silicon Radio Limited 2012
All rights reserved and confidential information of CSR
Refer to LICENSE.txt included with this source for details
static CsrUint32 write_uint32(void *buf, const CsrUint32 offset, const CsrUint32 val)
{
- write_uint16(buf, offset + 0, (CsrUint16)(val & 0xffff));
- write_uint16(buf, offset + 2, (CsrUint16)(val >> 16));
+ (void)write_uint16(buf, offset + 0, (CsrUint16)(val & 0xffff));
+ (void)write_uint16(buf, offset + 2, (CsrUint16)(val >> 16));
return sizeof(CsrUint32);
}
patch_offs += write_reset_ptdl(patch_buf, patch_offs, fwinfo, fw_id);
/* Now the length is known, update the LIST.length */
- write_uint32(patch_buf, list_len_offs,
- (patch_offs - ptdl_start_offs) + PTCH_LIST_SIZE);
+ (void)write_uint32(patch_buf, list_len_offs,
+ (patch_offs - ptdl_start_offs) + PTCH_LIST_SIZE);
/* Re write XBV headers just to fill in the correct file size */
- write_xbv_header(patch_buf, 0, (patch_offs - payload_offs));
+ (void)write_xbv_header(patch_buf, 0, (patch_offs - payload_offs));
unifi_trace(card->ospriv, UDBG1, "XBV:PTCH size %u, fw_id %u\n",
patch_offs, fw_id);
/*****************************************************************************
- (c) Cambridge Silicon Radio Limited 2011
+ (c) Cambridge Silicon Radio Limited 2012
All rights reserved and confidential information of CSR
Refer to LICENSE.txt included with this source for details
apCredentials - Security credential configuration.
maxConnections - Maximum number of stations/P2P clients allowed
p2pGoParam - P2P specific GO parameters.
- NOT USED FOR CURRENT RELEASE
wpsEnabled - Indicates whether WPS should be enabled or not
*******************************************************************************/
/*****************************************************************************
- (c) Cambridge Silicon Radio Limited 2011
+ (c) Cambridge Silicon Radio Limited 2012
All rights reserved and confidential information of CSR
Refer to LICENSE.txt included with this source for details
apCredentials - Security credential configuration.
maxConnections - Maximum number of stations/P2P clients allowed
p2pGoParam - P2P specific GO parameters.
- NOT USED FOR CURRENT RELEASE
wpsEnabled - Indicates whether WPS should be enabled or not
*******************************************************************************/
/*****************************************************************************
- (c) Cambridge Silicon Radio Limited 2011
+ (c) Cambridge Silicon Radio Limited 2012
All rights reserved and confidential information of CSR
Refer to LICENSE.txt included with this source for details
{
if (msgType & CSR_PRIM_UPSTREAM)
{
- CsrUint16 index = (msgType & ~CSR_PRIM_UPSTREAM) + CSR_WIFI_ROUTER_PRIM_DOWNSTREAM_COUNT;
- if (index < (CSR_WIFI_ROUTER_PRIM_UPSTREAM_COUNT + CSR_WIFI_ROUTER_PRIM_DOWNSTREAM_COUNT) &&
- csrwifirouter_conv_lut[index].msgType == msgType)
+ CsrUint16 idx = (msgType & ~CSR_PRIM_UPSTREAM) + CSR_WIFI_ROUTER_PRIM_DOWNSTREAM_COUNT;
+ if (idx < (CSR_WIFI_ROUTER_PRIM_UPSTREAM_COUNT + CSR_WIFI_ROUTER_PRIM_DOWNSTREAM_COUNT) &&
+ csrwifirouter_conv_lut[idx].msgType == msgType)
{
- return &csrwifirouter_conv_lut[index];
+ return &csrwifirouter_conv_lut[idx];
}
}
else
/*****************************************************************************
- (c) Cambridge Silicon Radio Limited 2011
+ (c) Cambridge Silicon Radio Limited 2012
All rights reserved and confidential information of CSR
Refer to LICENSE.txt included with this source for details
{ CSR_WIFI_ROUTER_CTRL_CAPABILITIES_REQ, CsrWifiRouterCtrlCapabilitiesReqSizeof, CsrWifiRouterCtrlCapabilitiesReqSer, CsrWifiRouterCtrlCapabilitiesReqDes, CsrWifiRouterCtrlCapabilitiesReqSerFree },
{ CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_ENABLE_REQ, CsrWifiRouterCtrlBlockAckEnableReqSizeof, CsrWifiRouterCtrlBlockAckEnableReqSer, CsrWifiRouterCtrlBlockAckEnableReqDes, CsrWifiRouterCtrlBlockAckEnableReqSerFree },
{ CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_DISABLE_REQ, CsrWifiRouterCtrlBlockAckDisableReqSizeof, CsrWifiRouterCtrlBlockAckDisableReqSer, CsrWifiRouterCtrlBlockAckDisableReqDes, CsrWifiRouterCtrlBlockAckDisableReqSerFree },
- { CSR_WIFI_ROUTER_CTRL_WAPI_MULTICAST_REQ, CsrWifiRouterCtrlWapiMulticastReqSizeof, CsrWifiRouterCtrlWapiMulticastReqSer, CsrWifiRouterCtrlWapiMulticastReqDes, CsrWifiRouterCtrlWapiMulticastReqSerFree },
+ { CSR_WIFI_ROUTER_CTRL_WAPI_RX_PKT_REQ, CsrWifiRouterCtrlWapiRxPktReqSizeof, CsrWifiRouterCtrlWapiRxPktReqSer, CsrWifiRouterCtrlWapiRxPktReqDes, CsrWifiRouterCtrlWapiRxPktReqSerFree },
{ CSR_WIFI_ROUTER_CTRL_WAPI_MULTICAST_FILTER_REQ, CsrWifiRouterCtrlWapiMulticastFilterReqSizeof, CsrWifiRouterCtrlWapiMulticastFilterReqSer, CsrWifiRouterCtrlWapiMulticastFilterReqDes, CsrWifiRouterCtrlWapiMulticastFilterReqSerFree },
{ CSR_WIFI_ROUTER_CTRL_WAPI_UNICAST_FILTER_REQ, CsrWifiRouterCtrlWapiUnicastFilterReqSizeof, CsrWifiRouterCtrlWapiUnicastFilterReqSer, CsrWifiRouterCtrlWapiUnicastFilterReqDes, CsrWifiRouterCtrlWapiUnicastFilterReqSerFree },
+ { CSR_WIFI_ROUTER_CTRL_WAPI_UNICAST_TX_PKT_REQ, CsrWifiRouterCtrlWapiUnicastTxPktReqSizeof, CsrWifiRouterCtrlWapiUnicastTxPktReqSer, CsrWifiRouterCtrlWapiUnicastTxPktReqDes, CsrWifiRouterCtrlWapiUnicastTxPktReqSerFree },
+ { CSR_WIFI_ROUTER_CTRL_WAPI_FILTER_REQ, CsrWifiRouterCtrlWapiFilterReqSizeof, CsrWifiRouterCtrlWapiFilterReqSer, CsrWifiRouterCtrlWapiFilterReqDes, CsrWifiRouterCtrlWapiFilterReqSerFree },
{ CSR_WIFI_ROUTER_CTRL_HIP_IND, CsrWifiRouterCtrlHipIndSizeof, CsrWifiRouterCtrlHipIndSer, CsrWifiRouterCtrlHipIndDes, CsrWifiRouterCtrlHipIndSerFree },
{ CSR_WIFI_ROUTER_CTRL_MULTICAST_ADDRESS_IND, CsrWifiRouterCtrlMulticastAddressIndSizeof, CsrWifiRouterCtrlMulticastAddressIndSer, CsrWifiRouterCtrlMulticastAddressIndDes, CsrWifiRouterCtrlMulticastAddressIndSerFree },
{ CSR_WIFI_ROUTER_CTRL_PORT_CONFIGURE_CFM, CsrWifiRouterCtrlPortConfigureCfmSizeof, CsrWifiRouterCtrlPortConfigureCfmSer, CsrWifiRouterCtrlPortConfigureCfmDes, CsrWifiRouterCtrlPortConfigureCfmSerFree },
{ CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_DISABLE_CFM, CsrWifiRouterCtrlBlockAckDisableCfmSizeof, CsrWifiRouterCtrlBlockAckDisableCfmSer, CsrWifiRouterCtrlBlockAckDisableCfmDes, CsrWifiRouterCtrlBlockAckDisableCfmSerFree },
{ CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_ERROR_IND, CsrWifiRouterCtrlBlockAckErrorIndSizeof, CsrWifiRouterCtrlBlockAckErrorIndSer, CsrWifiRouterCtrlBlockAckErrorIndDes, CsrWifiRouterCtrlBlockAckErrorIndSerFree },
{ CSR_WIFI_ROUTER_CTRL_STA_INACTIVE_IND, CsrWifiRouterCtrlStaInactiveIndSizeof, CsrWifiRouterCtrlStaInactiveIndSer, CsrWifiRouterCtrlStaInactiveIndDes, CsrWifiRouterCtrlStaInactiveIndSerFree },
- { CSR_WIFI_ROUTER_CTRL_WAPI_MULTICAST_IND, CsrWifiRouterCtrlWapiMulticastIndSizeof, CsrWifiRouterCtrlWapiMulticastIndSer, CsrWifiRouterCtrlWapiMulticastIndDes, CsrWifiRouterCtrlWapiMulticastIndSerFree },
+ { CSR_WIFI_ROUTER_CTRL_WAPI_RX_MIC_CHECK_IND, CsrWifiRouterCtrlWapiRxMicCheckIndSizeof, CsrWifiRouterCtrlWapiRxMicCheckIndSer, CsrWifiRouterCtrlWapiRxMicCheckIndDes, CsrWifiRouterCtrlWapiRxMicCheckIndSerFree },
+ { CSR_WIFI_ROUTER_CTRL_MODE_SET_CFM, CsrWifiRouterCtrlModeSetCfmSizeof, CsrWifiRouterCtrlModeSetCfmSer, CsrWifiRouterCtrlModeSetCfmDes, CsrWifiRouterCtrlModeSetCfmSerFree },
+ { CSR_WIFI_ROUTER_CTRL_WAPI_UNICAST_TX_ENCRYPT_IND, CsrWifiRouterCtrlWapiUnicastTxEncryptIndSizeof, CsrWifiRouterCtrlWapiUnicastTxEncryptIndSer, CsrWifiRouterCtrlWapiUnicastTxEncryptIndDes, CsrWifiRouterCtrlWapiUnicastTxEncryptIndSerFree },
{ 0, NULL, NULL, NULL, NULL },
};
{
if (msgType & CSR_PRIM_UPSTREAM)
{
- CsrUint16 index = (msgType & ~CSR_PRIM_UPSTREAM) + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_COUNT;
- if (index < (CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_COUNT + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_COUNT) &&
- csrwifirouterctrl_conv_lut[index].msgType == msgType)
+ CsrUint16 idx = (msgType & ~CSR_PRIM_UPSTREAM) + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_COUNT;
+ if (idx < (CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_COUNT + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_COUNT) &&
+ csrwifirouterctrl_conv_lut[idx].msgType == msgType)
{
- return &csrwifirouterctrl_conv_lut[index];
+ return &csrwifirouterctrl_conv_lut[idx];
}
}
else
/*****************************************************************************
- (c) Cambridge Silicon Radio Limited 2011
+ (c) Cambridge Silicon Radio Limited 2012
All rights reserved and confidential information of CSR
Refer to LICENSE.txt included with this source for details
p->tclas = NULL;
break;
}
+ case CSR_WIFI_ROUTER_CTRL_WIFI_ON_REQ:
+ {
+ CsrWifiRouterCtrlWifiOnReq *p = (CsrWifiRouterCtrlWifiOnReq *)message;
+ CsrPmemFree(p->data);
+ p->data = NULL;
+ break;
+ }
case CSR_WIFI_ROUTER_CTRL_WIFI_ON_RES:
{
CsrWifiRouterCtrlWifiOnRes *p = (CsrWifiRouterCtrlWifiOnRes *)message;
p->smeVersions.smeBuild = NULL;
break;
}
- case CSR_WIFI_ROUTER_CTRL_WAPI_MULTICAST_REQ:
+ case CSR_WIFI_ROUTER_CTRL_WAPI_RX_PKT_REQ:
{
- CsrWifiRouterCtrlWapiMulticastReq *p = (CsrWifiRouterCtrlWapiMulticastReq *)message;
+ CsrWifiRouterCtrlWapiRxPktReq *p = (CsrWifiRouterCtrlWapiRxPktReq *)message;
CsrPmemFree(p->signal);
p->signal = NULL;
CsrPmemFree(p->data);
p->data = NULL;
break;
}
+ case CSR_WIFI_ROUTER_CTRL_WAPI_UNICAST_TX_PKT_REQ:
+ {
+ CsrWifiRouterCtrlWapiUnicastTxPktReq *p = (CsrWifiRouterCtrlWapiUnicastTxPktReq *)message;
+ CsrPmemFree(p->data);
+ p->data = NULL;
+ break;
+ }
default:
break;
/*****************************************************************************
- (c) Cambridge Silicon Radio Limited 2011
+ (c) Cambridge Silicon Radio Limited 2012
All rights reserved and confidential information of CSR
Refer to LICENSE.txt included with this source for details
p->versions.routerBuild = NULL;
break;
}
- case CSR_WIFI_ROUTER_CTRL_WAPI_MULTICAST_IND:
+ case CSR_WIFI_ROUTER_CTRL_WAPI_RX_MIC_CHECK_IND:
{
- CsrWifiRouterCtrlWapiMulticastInd *p = (CsrWifiRouterCtrlWapiMulticastInd *)message;
+ CsrWifiRouterCtrlWapiRxMicCheckInd *p = (CsrWifiRouterCtrlWapiRxMicCheckInd *)message;
CsrPmemFree(p->signal);
p->signal = NULL;
CsrPmemFree(p->data);
p->data = NULL;
break;
}
+ case CSR_WIFI_ROUTER_CTRL_WAPI_UNICAST_TX_ENCRYPT_IND:
+ {
+ CsrWifiRouterCtrlWapiUnicastTxEncryptInd *p = (CsrWifiRouterCtrlWapiUnicastTxEncryptInd *)message;
+ CsrPmemFree(p->data);
+ p->data = NULL;
+ break;
+ }
default:
break;
/*****************************************************************************
- (c) Cambridge Silicon Radio Limited 2011
+ (c) Cambridge Silicon Radio Limited 2012
All rights reserved and confidential information of CSR
Refer to LICENSE.txt included with this source for details
#define CsrWifiRouterCtrlModeSetReqSend(src__, interfaceTag__, clientData__, mode__, bssid__, protection__, intraBssDistEnabled__) \
CsrWifiRouterCtrlModeSetReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, interfaceTag__, clientData__, mode__, bssid__, protection__, intraBssDistEnabled__)
+/*******************************************************************************
+
+ NAME
+ CsrWifiRouterCtrlModeSetCfmSend
+
+ DESCRIPTION
+
+ PARAMETERS
+ queue - Destination Task Queue
+ clientData -
+ interfaceTag -
+ mode -
+ status -
+
+*******************************************************************************/
+#define CsrWifiRouterCtrlModeSetCfmCreate(msg__, dst__, src__, clientData__, interfaceTag__, mode__, status__) \
+ msg__ = (CsrWifiRouterCtrlModeSetCfm *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlModeSetCfm)); \
+ CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_MODE_SET_CFM, dst__, src__); \
+ msg__->clientData = (clientData__); \
+ msg__->interfaceTag = (interfaceTag__); \
+ msg__->mode = (mode__); \
+ msg__->status = (status__);
+
+#define CsrWifiRouterCtrlModeSetCfmSendTo(dst__, src__, clientData__, interfaceTag__, mode__, status__) \
+ { \
+ CsrWifiRouterCtrlModeSetCfm *msg__; \
+ CsrWifiRouterCtrlModeSetCfmCreate(msg__, dst__, src__, clientData__, interfaceTag__, mode__, status__); \
+ CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
+ }
+
+#define CsrWifiRouterCtrlModeSetCfmSend(dst__, clientData__, interfaceTag__, mode__, status__) \
+ CsrWifiRouterCtrlModeSetCfmSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, interfaceTag__, mode__, status__)
+
/*******************************************************************************
NAME
#define CsrWifiRouterCtrlUnexpectedFrameIndSend(dst__, clientData__, interfaceTag__, peerMacAddress__) \
CsrWifiRouterCtrlUnexpectedFrameIndSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, interfaceTag__, peerMacAddress__)
+/*******************************************************************************
+
+ NAME
+ CsrWifiRouterCtrlWapiFilterReqSend
+
+ DESCRIPTION
+
+ PARAMETERS
+ queue - Message Source Task Queue (Cfm's will be sent to this Queue)
+ interfaceTag -
+ isWapiConnected -
+
+*******************************************************************************/
+#define CsrWifiRouterCtrlWapiFilterReqCreate(msg__, dst__, src__, interfaceTag__, isWapiConnected__) \
+ msg__ = (CsrWifiRouterCtrlWapiFilterReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlWapiFilterReq)); \
+ CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_WAPI_FILTER_REQ, dst__, src__); \
+ msg__->interfaceTag = (interfaceTag__); \
+ msg__->isWapiConnected = (isWapiConnected__);
+
+#define CsrWifiRouterCtrlWapiFilterReqSendTo(dst__, src__, interfaceTag__, isWapiConnected__) \
+ { \
+ CsrWifiRouterCtrlWapiFilterReq *msg__; \
+ CsrWifiRouterCtrlWapiFilterReqCreate(msg__, dst__, src__, interfaceTag__, isWapiConnected__); \
+ CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
+ }
+
+#define CsrWifiRouterCtrlWapiFilterReqSend(src__, interfaceTag__, isWapiConnected__) \
+ CsrWifiRouterCtrlWapiFilterReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, interfaceTag__, isWapiConnected__)
+
/*******************************************************************************
NAME
DESCRIPTION
PARAMETERS
- queue - Message Source Task Queue (Cfm's will be sent to this Queue)
- status -
+ queue - Message Source Task Queue (Cfm's will be sent to this Queue)
+ interfaceTag -
+ status -
*******************************************************************************/
-#define CsrWifiRouterCtrlWapiMulticastFilterReqCreate(msg__, dst__, src__, status__) \
+#define CsrWifiRouterCtrlWapiMulticastFilterReqCreate(msg__, dst__, src__, interfaceTag__, status__) \
msg__ = (CsrWifiRouterCtrlWapiMulticastFilterReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlWapiMulticastFilterReq)); \
CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_WAPI_MULTICAST_FILTER_REQ, dst__, src__); \
+ msg__->interfaceTag = (interfaceTag__); \
msg__->status = (status__);
-#define CsrWifiRouterCtrlWapiMulticastFilterReqSendTo(dst__, src__, status__) \
+#define CsrWifiRouterCtrlWapiMulticastFilterReqSendTo(dst__, src__, interfaceTag__, status__) \
{ \
CsrWifiRouterCtrlWapiMulticastFilterReq *msg__; \
- CsrWifiRouterCtrlWapiMulticastFilterReqCreate(msg__, dst__, src__, status__); \
+ CsrWifiRouterCtrlWapiMulticastFilterReqCreate(msg__, dst__, src__, interfaceTag__, status__); \
CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
}
-#define CsrWifiRouterCtrlWapiMulticastFilterReqSend(src__, status__) \
- CsrWifiRouterCtrlWapiMulticastFilterReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, status__)
+#define CsrWifiRouterCtrlWapiMulticastFilterReqSend(src__, interfaceTag__, status__) \
+ CsrWifiRouterCtrlWapiMulticastFilterReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, interfaceTag__, status__)
/*******************************************************************************
NAME
- CsrWifiRouterCtrlWapiMulticastReqSend
+ CsrWifiRouterCtrlWapiRxMicCheckIndSend
DESCRIPTION
PARAMETERS
- queue - Message Source Task Queue (Cfm's will be sent to this Queue)
+ queue - Destination Task Queue
+ clientData -
+ interfaceTag -
signalLength -
signal -
dataLength -
data -
*******************************************************************************/
-#define CsrWifiRouterCtrlWapiMulticastReqCreate(msg__, dst__, src__, signalLength__, signal__, dataLength__, data__) \
- msg__ = (CsrWifiRouterCtrlWapiMulticastReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlWapiMulticastReq)); \
- CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_WAPI_MULTICAST_REQ, dst__, src__); \
+#define CsrWifiRouterCtrlWapiRxMicCheckIndCreate(msg__, dst__, src__, clientData__, interfaceTag__, signalLength__, signal__, dataLength__, data__) \
+ msg__ = (CsrWifiRouterCtrlWapiRxMicCheckInd *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlWapiRxMicCheckInd)); \
+ CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_WAPI_RX_MIC_CHECK_IND, dst__, src__); \
+ msg__->clientData = (clientData__); \
+ msg__->interfaceTag = (interfaceTag__); \
msg__->signalLength = (signalLength__); \
msg__->signal = (signal__); \
msg__->dataLength = (dataLength__); \
msg__->data = (data__);
-#define CsrWifiRouterCtrlWapiMulticastReqSendTo(dst__, src__, signalLength__, signal__, dataLength__, data__) \
+#define CsrWifiRouterCtrlWapiRxMicCheckIndSendTo(dst__, src__, clientData__, interfaceTag__, signalLength__, signal__, dataLength__, data__) \
{ \
- CsrWifiRouterCtrlWapiMulticastReq *msg__; \
- CsrWifiRouterCtrlWapiMulticastReqCreate(msg__, dst__, src__, signalLength__, signal__, dataLength__, data__); \
- CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
+ CsrWifiRouterCtrlWapiRxMicCheckInd *msg__; \
+ CsrWifiRouterCtrlWapiRxMicCheckIndCreate(msg__, dst__, src__, clientData__, interfaceTag__, signalLength__, signal__, dataLength__, data__); \
+ CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
}
-#define CsrWifiRouterCtrlWapiMulticastReqSend(src__, signalLength__, signal__, dataLength__, data__) \
- CsrWifiRouterCtrlWapiMulticastReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, signalLength__, signal__, dataLength__, data__)
+#define CsrWifiRouterCtrlWapiRxMicCheckIndSend(dst__, clientData__, interfaceTag__, signalLength__, signal__, dataLength__, data__) \
+ CsrWifiRouterCtrlWapiRxMicCheckIndSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, interfaceTag__, signalLength__, signal__, dataLength__, data__)
/*******************************************************************************
NAME
- CsrWifiRouterCtrlWapiMulticastIndSend
+ CsrWifiRouterCtrlWapiRxPktReqSend
DESCRIPTION
PARAMETERS
- queue - Destination Task Queue
- clientData -
+ queue - Message Source Task Queue (Cfm's will be sent to this Queue)
interfaceTag -
signalLength -
signal -
data -
*******************************************************************************/
-#define CsrWifiRouterCtrlWapiMulticastIndCreate(msg__, dst__, src__, clientData__, interfaceTag__, signalLength__, signal__, dataLength__, data__) \
- msg__ = (CsrWifiRouterCtrlWapiMulticastInd *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlWapiMulticastInd)); \
- CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_WAPI_MULTICAST_IND, dst__, src__); \
- msg__->clientData = (clientData__); \
+#define CsrWifiRouterCtrlWapiRxPktReqCreate(msg__, dst__, src__, interfaceTag__, signalLength__, signal__, dataLength__, data__) \
+ msg__ = (CsrWifiRouterCtrlWapiRxPktReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlWapiRxPktReq)); \
+ CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_WAPI_RX_PKT_REQ, dst__, src__); \
msg__->interfaceTag = (interfaceTag__); \
msg__->signalLength = (signalLength__); \
msg__->signal = (signal__); \
msg__->dataLength = (dataLength__); \
msg__->data = (data__);
-#define CsrWifiRouterCtrlWapiMulticastIndSendTo(dst__, src__, clientData__, interfaceTag__, signalLength__, signal__, dataLength__, data__) \
+#define CsrWifiRouterCtrlWapiRxPktReqSendTo(dst__, src__, interfaceTag__, signalLength__, signal__, dataLength__, data__) \
{ \
- CsrWifiRouterCtrlWapiMulticastInd *msg__; \
- CsrWifiRouterCtrlWapiMulticastIndCreate(msg__, dst__, src__, clientData__, interfaceTag__, signalLength__, signal__, dataLength__, data__); \
- CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
+ CsrWifiRouterCtrlWapiRxPktReq *msg__; \
+ CsrWifiRouterCtrlWapiRxPktReqCreate(msg__, dst__, src__, interfaceTag__, signalLength__, signal__, dataLength__, data__); \
+ CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
}
-#define CsrWifiRouterCtrlWapiMulticastIndSend(dst__, clientData__, interfaceTag__, signalLength__, signal__, dataLength__, data__) \
- CsrWifiRouterCtrlWapiMulticastIndSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, interfaceTag__, signalLength__, signal__, dataLength__, data__)
+#define CsrWifiRouterCtrlWapiRxPktReqSend(src__, interfaceTag__, signalLength__, signal__, dataLength__, data__) \
+ CsrWifiRouterCtrlWapiRxPktReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, interfaceTag__, signalLength__, signal__, dataLength__, data__)
/*******************************************************************************
DESCRIPTION
PARAMETERS
- queue - Message Source Task Queue (Cfm's will be sent to this Queue)
- status -
+ queue - Message Source Task Queue (Cfm's will be sent to this Queue)
+ interfaceTag -
+ status -
*******************************************************************************/
-#define CsrWifiRouterCtrlWapiUnicastFilterReqCreate(msg__, dst__, src__, status__) \
+#define CsrWifiRouterCtrlWapiUnicastFilterReqCreate(msg__, dst__, src__, interfaceTag__, status__) \
msg__ = (CsrWifiRouterCtrlWapiUnicastFilterReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlWapiUnicastFilterReq)); \
CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_WAPI_UNICAST_FILTER_REQ, dst__, src__); \
+ msg__->interfaceTag = (interfaceTag__); \
msg__->status = (status__);
-#define CsrWifiRouterCtrlWapiUnicastFilterReqSendTo(dst__, src__, status__) \
+#define CsrWifiRouterCtrlWapiUnicastFilterReqSendTo(dst__, src__, interfaceTag__, status__) \
{ \
CsrWifiRouterCtrlWapiUnicastFilterReq *msg__; \
- CsrWifiRouterCtrlWapiUnicastFilterReqCreate(msg__, dst__, src__, status__); \
+ CsrWifiRouterCtrlWapiUnicastFilterReqCreate(msg__, dst__, src__, interfaceTag__, status__); \
+ CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
+ }
+
+#define CsrWifiRouterCtrlWapiUnicastFilterReqSend(src__, interfaceTag__, status__) \
+ CsrWifiRouterCtrlWapiUnicastFilterReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, interfaceTag__, status__)
+
+/*******************************************************************************
+
+ NAME
+ CsrWifiRouterCtrlWapiUnicastTxEncryptIndSend
+
+ DESCRIPTION
+
+ PARAMETERS
+ queue - Destination Task Queue
+ clientData -
+ interfaceTag -
+ dataLength -
+ data -
+
+*******************************************************************************/
+#define CsrWifiRouterCtrlWapiUnicastTxEncryptIndCreate(msg__, dst__, src__, clientData__, interfaceTag__, dataLength__, data__) \
+ msg__ = (CsrWifiRouterCtrlWapiUnicastTxEncryptInd *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlWapiUnicastTxEncryptInd)); \
+ CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_WAPI_UNICAST_TX_ENCRYPT_IND, dst__, src__); \
+ msg__->clientData = (clientData__); \
+ msg__->interfaceTag = (interfaceTag__); \
+ msg__->dataLength = (dataLength__); \
+ msg__->data = (data__);
+
+#define CsrWifiRouterCtrlWapiUnicastTxEncryptIndSendTo(dst__, src__, clientData__, interfaceTag__, dataLength__, data__) \
+ { \
+ CsrWifiRouterCtrlWapiUnicastTxEncryptInd *msg__; \
+ CsrWifiRouterCtrlWapiUnicastTxEncryptIndCreate(msg__, dst__, src__, clientData__, interfaceTag__, dataLength__, data__); \
+ CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
+ }
+
+#define CsrWifiRouterCtrlWapiUnicastTxEncryptIndSend(dst__, clientData__, interfaceTag__, dataLength__, data__) \
+ CsrWifiRouterCtrlWapiUnicastTxEncryptIndSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, interfaceTag__, dataLength__, data__)
+
+/*******************************************************************************
+
+ NAME
+ CsrWifiRouterCtrlWapiUnicastTxPktReqSend
+
+ DESCRIPTION
+
+ PARAMETERS
+ queue - Message Source Task Queue (Cfm's will be sent to this Queue)
+ interfaceTag -
+ dataLength -
+ data -
+
+*******************************************************************************/
+#define CsrWifiRouterCtrlWapiUnicastTxPktReqCreate(msg__, dst__, src__, interfaceTag__, dataLength__, data__) \
+ msg__ = (CsrWifiRouterCtrlWapiUnicastTxPktReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlWapiUnicastTxPktReq)); \
+ CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_WAPI_UNICAST_TX_PKT_REQ, dst__, src__); \
+ msg__->interfaceTag = (interfaceTag__); \
+ msg__->dataLength = (dataLength__); \
+ msg__->data = (data__);
+
+#define CsrWifiRouterCtrlWapiUnicastTxPktReqSendTo(dst__, src__, interfaceTag__, dataLength__, data__) \
+ { \
+ CsrWifiRouterCtrlWapiUnicastTxPktReq *msg__; \
+ CsrWifiRouterCtrlWapiUnicastTxPktReqCreate(msg__, dst__, src__, interfaceTag__, dataLength__, data__); \
CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
}
-#define CsrWifiRouterCtrlWapiUnicastFilterReqSend(src__, status__) \
- CsrWifiRouterCtrlWapiUnicastFilterReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, status__)
+#define CsrWifiRouterCtrlWapiUnicastTxPktReqSend(src__, interfaceTag__, dataLength__, data__) \
+ CsrWifiRouterCtrlWapiUnicastTxPktReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, interfaceTag__, dataLength__, data__)
/*******************************************************************************
PARAMETERS
queue - Message Source Task Queue (Cfm's will be sent to this Queue)
clientData -
+ dataLength - Number of bytes in the buffer pointed to by 'data'
+ data - Pointer to the buffer containing 'dataLength' bytes
*******************************************************************************/
-#define CsrWifiRouterCtrlWifiOnReqCreate(msg__, dst__, src__, clientData__) \
+#define CsrWifiRouterCtrlWifiOnReqCreate(msg__, dst__, src__, clientData__, dataLength__, data__) \
msg__ = (CsrWifiRouterCtrlWifiOnReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlWifiOnReq)); \
CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_WIFI_ON_REQ, dst__, src__); \
- msg__->clientData = (clientData__);
+ msg__->clientData = (clientData__); \
+ msg__->dataLength = (dataLength__); \
+ msg__->data = (data__);
-#define CsrWifiRouterCtrlWifiOnReqSendTo(dst__, src__, clientData__) \
+#define CsrWifiRouterCtrlWifiOnReqSendTo(dst__, src__, clientData__, dataLength__, data__) \
{ \
CsrWifiRouterCtrlWifiOnReq *msg__; \
- CsrWifiRouterCtrlWifiOnReqCreate(msg__, dst__, src__, clientData__); \
+ CsrWifiRouterCtrlWifiOnReqCreate(msg__, dst__, src__, clientData__, dataLength__, data__); \
CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
}
-#define CsrWifiRouterCtrlWifiOnReqSend(src__, clientData__) \
- CsrWifiRouterCtrlWifiOnReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, clientData__)
+#define CsrWifiRouterCtrlWifiOnReqSend(src__, clientData__, dataLength__, data__) \
+ CsrWifiRouterCtrlWifiOnReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, clientData__, dataLength__, data__)
/*******************************************************************************
/*****************************************************************************
- (c) Cambridge Silicon Radio Limited 2011
+ (c) Cambridge Silicon Radio Limited 2012
All rights reserved and confidential information of CSR
Refer to LICENSE.txt included with this source for details
#define CSR_WIFI_ROUTER_CTRL_CAPABILITIES_REQ ((CsrWifiRouterCtrlPrim) (0x0017 + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST))
#define CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_ENABLE_REQ ((CsrWifiRouterCtrlPrim) (0x0018 + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST))
#define CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_DISABLE_REQ ((CsrWifiRouterCtrlPrim) (0x0019 + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_ROUTER_CTRL_WAPI_MULTICAST_REQ ((CsrWifiRouterCtrlPrim) (0x001A + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST))
+#define CSR_WIFI_ROUTER_CTRL_WAPI_RX_PKT_REQ ((CsrWifiRouterCtrlPrim) (0x001A + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST))
#define CSR_WIFI_ROUTER_CTRL_WAPI_MULTICAST_FILTER_REQ ((CsrWifiRouterCtrlPrim) (0x001B + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST))
#define CSR_WIFI_ROUTER_CTRL_WAPI_UNICAST_FILTER_REQ ((CsrWifiRouterCtrlPrim) (0x001C + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST))
+#define CSR_WIFI_ROUTER_CTRL_WAPI_UNICAST_TX_PKT_REQ ((CsrWifiRouterCtrlPrim) (0x001D + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST))
+#define CSR_WIFI_ROUTER_CTRL_WAPI_FILTER_REQ ((CsrWifiRouterCtrlPrim) (0x001E + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_HIGHEST (0x001C + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST)
+#define CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_HIGHEST (0x001E + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST)
/* Upstream */
#define CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST (0x0000 + CSR_PRIM_UPSTREAM)
#define CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_DISABLE_CFM ((CsrWifiRouterCtrlPrim)(0x0019 + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST))
#define CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_ERROR_IND ((CsrWifiRouterCtrlPrim)(0x001A + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST))
#define CSR_WIFI_ROUTER_CTRL_STA_INACTIVE_IND ((CsrWifiRouterCtrlPrim)(0x001B + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_ROUTER_CTRL_WAPI_MULTICAST_IND ((CsrWifiRouterCtrlPrim)(0x001C + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST))
+#define CSR_WIFI_ROUTER_CTRL_WAPI_RX_MIC_CHECK_IND ((CsrWifiRouterCtrlPrim)(0x001C + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST))
+#define CSR_WIFI_ROUTER_CTRL_MODE_SET_CFM ((CsrWifiRouterCtrlPrim)(0x001D + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST))
+#define CSR_WIFI_ROUTER_CTRL_WAPI_UNICAST_TX_ENCRYPT_IND ((CsrWifiRouterCtrlPrim)(0x001E + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_HIGHEST (0x001C + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST)
+#define CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_HIGHEST (0x001E + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST)
#define CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_COUNT (CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_HIGHEST + 1 - CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST)
#define CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_COUNT (CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_HIGHEST + 1 - CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST)
MEMBERS
common - Common header for use with the CsrWifiFsm Module
clientData -
+ dataLength - Number of bytes in the buffer pointed to by 'data'
+ data - Pointer to the buffer containing 'dataLength' bytes
*******************************************************************************/
typedef struct
{
CsrWifiFsmEvent common;
CsrWifiRouterCtrlRequestorInfo clientData;
+ CsrUint32 dataLength;
+ CsrUint8 *data;
} CsrWifiRouterCtrlWifiOnReq;
/*******************************************************************************
/*******************************************************************************
NAME
- CsrWifiRouterCtrlWapiMulticastReq
+ CsrWifiRouterCtrlWapiRxPktReq
DESCRIPTION
MEMBERS
common - Common header for use with the CsrWifiFsm Module
+ interfaceTag -
signalLength -
signal -
dataLength -
typedef struct
{
CsrWifiFsmEvent common;
+ CsrUint16 interfaceTag;
CsrUint16 signalLength;
CsrUint8 *signal;
CsrUint16 dataLength;
CsrUint8 *data;
-} CsrWifiRouterCtrlWapiMulticastReq;
+} CsrWifiRouterCtrlWapiRxPktReq;
/*******************************************************************************
DESCRIPTION
MEMBERS
- common - Common header for use with the CsrWifiFsm Module
- status -
+ common - Common header for use with the CsrWifiFsm Module
+ interfaceTag -
+ status -
*******************************************************************************/
typedef struct
{
CsrWifiFsmEvent common;
+ CsrUint16 interfaceTag;
CsrUint8 status;
} CsrWifiRouterCtrlWapiMulticastFilterReq;
DESCRIPTION
MEMBERS
- common - Common header for use with the CsrWifiFsm Module
- status -
+ common - Common header for use with the CsrWifiFsm Module
+ interfaceTag -
+ status -
*******************************************************************************/
typedef struct
{
CsrWifiFsmEvent common;
+ CsrUint16 interfaceTag;
CsrUint8 status;
} CsrWifiRouterCtrlWapiUnicastFilterReq;
+/*******************************************************************************
+
+ NAME
+ CsrWifiRouterCtrlWapiUnicastTxPktReq
+
+ DESCRIPTION
+
+ MEMBERS
+ common - Common header for use with the CsrWifiFsm Module
+ interfaceTag -
+ dataLength -
+ data -
+
+*******************************************************************************/
+typedef struct
+{
+ CsrWifiFsmEvent common;
+ CsrUint16 interfaceTag;
+ CsrUint16 dataLength;
+ CsrUint8 *data;
+} CsrWifiRouterCtrlWapiUnicastTxPktReq;
+
+/*******************************************************************************
+
+ NAME
+ CsrWifiRouterCtrlWapiFilterReq
+
+ DESCRIPTION
+
+ MEMBERS
+ common - Common header for use with the CsrWifiFsm Module
+ interfaceTag -
+ isWapiConnected -
+
+*******************************************************************************/
+typedef struct
+{
+ CsrWifiFsmEvent common;
+ CsrUint16 interfaceTag;
+ CsrBool isWapiConnected;
+} CsrWifiRouterCtrlWapiFilterReq;
+
/*******************************************************************************
NAME
/*******************************************************************************
NAME
- CsrWifiRouterCtrlWapiMulticastInd
+ CsrWifiRouterCtrlWapiRxMicCheckInd
DESCRIPTION
CsrUint8 *signal;
CsrUint16 dataLength;
CsrUint8 *data;
-} CsrWifiRouterCtrlWapiMulticastInd;
+} CsrWifiRouterCtrlWapiRxMicCheckInd;
+
+/*******************************************************************************
+
+ NAME
+ CsrWifiRouterCtrlModeSetCfm
+
+ DESCRIPTION
+
+ MEMBERS
+ common - Common header for use with the CsrWifiFsm Module
+ clientData -
+ interfaceTag -
+ mode -
+ status -
+
+*******************************************************************************/
+typedef struct
+{
+ CsrWifiFsmEvent common;
+ CsrWifiRouterCtrlRequestorInfo clientData;
+ CsrUint16 interfaceTag;
+ CsrWifiRouterCtrlMode mode;
+ CsrResult status;
+} CsrWifiRouterCtrlModeSetCfm;
+
+/*******************************************************************************
+
+ NAME
+ CsrWifiRouterCtrlWapiUnicastTxEncryptInd
+
+ DESCRIPTION
+
+ MEMBERS
+ common - Common header for use with the CsrWifiFsm Module
+ clientData -
+ interfaceTag -
+ dataLength -
+ data -
+
+*******************************************************************************/
+typedef struct
+{
+ CsrWifiFsmEvent common;
+ CsrWifiRouterCtrlRequestorInfo clientData;
+ CsrUint16 interfaceTag;
+ CsrUint16 dataLength;
+ CsrUint8 *data;
+} CsrWifiRouterCtrlWapiUnicastTxEncryptInd;
#ifdef __cplusplus
/* 0x0015 */ CsrWifiRouterCtrlPeerDelReqHandler,
/* 0x0016 */ CsrWifiRouterCtrlPeerUpdateReqHandler,
/* 0x0017 */ CsrWifiRouterCtrlCapabilitiesReqHandler,
- CsrWifiRouterCtrlBlockAckEnableReqHandler, /* 0x0018 */
- CsrWifiRouterCtrlBlockAckDisableReqHandler, /* 0x0019 */
- CsrWifiRouterCtrlWapiMulticastReqHandler, /* 0x001A */
- CsrWifiRouterCtrlWapiMulticastFilterReqHandler, /* 0x001B */
- CsrWifiRouterCtrlWapiUnicastFilterReqHandler, /* 0x001C */
+ /* 0x0018 */ CsrWifiRouterCtrlBlockAckEnableReqHandler,
+ /* 0x0019 */ CsrWifiRouterCtrlBlockAckDisableReqHandler,
+ /* 0x001A */ CsrWifiRouterCtrlWapiRxPktReqHandler,
+ /* 0x001B */ CsrWifiRouterCtrlWapiMulticastFilterReqHandler,
+ /* 0x001C */ CsrWifiRouterCtrlWapiUnicastFilterReqHandler,
+ /* 0x001D */ CsrWifiRouterCtrlWapiUnicastTxPktReqHandler,
+ /* 0x001E */ CsrWifiRouterCtrlWapiFilterReqHandler,
};
extern void CsrWifiRouterCtrlBlockAckEnableReqHandler(void* drvpriv, CsrWifiFsmEvent* msg);
extern void CsrWifiRouterCtrlBlockAckDisableReqHandler(void* drvpriv, CsrWifiFsmEvent* msg);
extern void CsrWifiRouterCtrlWapiMulticastFilterReqHandler(void* drvpriv, CsrWifiFsmEvent* msg);
- extern void CsrWifiRouterCtrlWapiMulticastReqHandler(void* drvpriv, CsrWifiFsmEvent* msg);
+ extern void CsrWifiRouterCtrlWapiRxPktReqHandler(void* drvpriv, CsrWifiFsmEvent* msg);
+ extern void CsrWifiRouterCtrlWapiUnicastTxPktReqHandler(void* drvpriv, CsrWifiFsmEvent* msg);
extern void CsrWifiRouterCtrlWapiUnicastFilterReqHandler(void* drvpriv, CsrWifiFsmEvent* msg);
+ extern void CsrWifiRouterCtrlWapiFilterReqHandler(void* drvpriv, CsrWifiFsmEvent* msg);
#ifdef __cplusplus
}
#endif
/*****************************************************************************
- (c) Cambridge Silicon Radio Limited 2011
+ (c) Cambridge Silicon Radio Limited 2012
All rights reserved and confidential information of CSR
Refer to LICENSE.txt included with this source for details
}
+CsrSize CsrWifiRouterCtrlWifiOnReqSizeof(void *msg)
+{
+ CsrWifiRouterCtrlWifiOnReq *primitive = (CsrWifiRouterCtrlWifiOnReq *) msg;
+ CsrSize bufferSize = 2;
+
+ /* Calculate the Size of the Serialised Data. Could be more efficient (Try 10) */
+ bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */
+ bufferSize += 4; /* CsrUint32 primitive->dataLength */
+ bufferSize += primitive->dataLength; /* CsrUint8 primitive->data */
+ return bufferSize;
+}
+
+
+CsrUint8* CsrWifiRouterCtrlWifiOnReqSer(CsrUint8 *ptr, CsrSize *len, void *msg)
+{
+ CsrWifiRouterCtrlWifiOnReq *primitive = (CsrWifiRouterCtrlWifiOnReq *)msg;
+ *len = 0;
+ CsrUint16Ser(ptr, len, primitive->common.type);
+ CsrUint16Ser(ptr, len, (CsrUint16) primitive->clientData);
+ CsrUint32Ser(ptr, len, (CsrUint32) primitive->dataLength);
+ if (primitive->dataLength)
+ {
+ CsrMemCpySer(ptr, len, (const void *) primitive->data, ((CsrUint16) (primitive->dataLength)));
+ }
+ return(ptr);
+}
+
+
+void* CsrWifiRouterCtrlWifiOnReqDes(CsrUint8 *buffer, CsrSize length)
+{
+ CsrWifiRouterCtrlWifiOnReq *primitive = (CsrWifiRouterCtrlWifiOnReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlWifiOnReq));
+ CsrSize offset;
+ offset = 0;
+
+ CsrUint16Des(&primitive->common.type, buffer, &offset);
+ CsrUint16Des((CsrUint16 *) &primitive->clientData, buffer, &offset);
+ CsrUint32Des((CsrUint32 *) &primitive->dataLength, buffer, &offset);
+ if (primitive->dataLength)
+ {
+ primitive->data = (CsrUint8 *)CsrPmemAlloc(primitive->dataLength);
+ CsrMemCpyDes(primitive->data, buffer, &offset, ((CsrUint16) (primitive->dataLength)));
+ }
+ else
+ {
+ primitive->data = NULL;
+ }
+
+ return primitive;
+}
+
+
+void CsrWifiRouterCtrlWifiOnReqSerFree(void *voidPrimitivePointer)
+{
+ CsrWifiRouterCtrlWifiOnReq *primitive = (CsrWifiRouterCtrlWifiOnReq *) voidPrimitivePointer;
+ CsrPmemFree(primitive->data);
+ CsrPmemFree(primitive);
+}
+
+
CsrSize CsrWifiRouterCtrlWifiOnResSizeof(void *msg)
{
CsrWifiRouterCtrlWifiOnRes *primitive = (CsrWifiRouterCtrlWifiOnRes *) msg;
}
-CsrSize CsrWifiRouterCtrlWapiMulticastReqSizeof(void *msg)
+CsrSize CsrWifiRouterCtrlWapiRxPktReqSizeof(void *msg)
{
- CsrWifiRouterCtrlWapiMulticastReq *primitive = (CsrWifiRouterCtrlWapiMulticastReq *) msg;
+ CsrWifiRouterCtrlWapiRxPktReq *primitive = (CsrWifiRouterCtrlWapiRxPktReq *) msg;
CsrSize bufferSize = 2;
- /* Calculate the Size of the Serialised Data. Could be more efficient (Try 9) */
+ /* Calculate the Size of the Serialised Data. Could be more efficient (Try 11) */
+ bufferSize += 2; /* CsrUint16 primitive->interfaceTag */
bufferSize += 2; /* CsrUint16 primitive->signalLength */
bufferSize += primitive->signalLength; /* CsrUint8 primitive->signal */
bufferSize += 2; /* CsrUint16 primitive->dataLength */
}
-CsrUint8* CsrWifiRouterCtrlWapiMulticastReqSer(CsrUint8 *ptr, CsrSize *len, void *msg)
+CsrUint8* CsrWifiRouterCtrlWapiRxPktReqSer(CsrUint8 *ptr, CsrSize *len, void *msg)
{
- CsrWifiRouterCtrlWapiMulticastReq *primitive = (CsrWifiRouterCtrlWapiMulticastReq *)msg;
+ CsrWifiRouterCtrlWapiRxPktReq *primitive = (CsrWifiRouterCtrlWapiRxPktReq *)msg;
*len = 0;
CsrUint16Ser(ptr, len, primitive->common.type);
+ CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag);
CsrUint16Ser(ptr, len, (CsrUint16) primitive->signalLength);
if (primitive->signalLength)
{
}
-void* CsrWifiRouterCtrlWapiMulticastReqDes(CsrUint8 *buffer, CsrSize length)
+void* CsrWifiRouterCtrlWapiRxPktReqDes(CsrUint8 *buffer, CsrSize length)
{
- CsrWifiRouterCtrlWapiMulticastReq *primitive = (CsrWifiRouterCtrlWapiMulticastReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlWapiMulticastReq));
+ CsrWifiRouterCtrlWapiRxPktReq *primitive = (CsrWifiRouterCtrlWapiRxPktReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlWapiRxPktReq));
CsrSize offset;
offset = 0;
CsrUint16Des(&primitive->common.type, buffer, &offset);
+ CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset);
CsrUint16Des((CsrUint16 *) &primitive->signalLength, buffer, &offset);
if (primitive->signalLength)
{
}
-void CsrWifiRouterCtrlWapiMulticastReqSerFree(void *voidPrimitivePointer)
+void CsrWifiRouterCtrlWapiRxPktReqSerFree(void *voidPrimitivePointer)
{
- CsrWifiRouterCtrlWapiMulticastReq *primitive = (CsrWifiRouterCtrlWapiMulticastReq *) voidPrimitivePointer;
+ CsrWifiRouterCtrlWapiRxPktReq *primitive = (CsrWifiRouterCtrlWapiRxPktReq *) voidPrimitivePointer;
CsrPmemFree(primitive->signal);
CsrPmemFree(primitive->data);
CsrPmemFree(primitive);
}
+CsrSize CsrWifiRouterCtrlWapiUnicastTxPktReqSizeof(void *msg)
+{
+ CsrWifiRouterCtrlWapiUnicastTxPktReq *primitive = (CsrWifiRouterCtrlWapiUnicastTxPktReq *) msg;
+ CsrSize bufferSize = 2;
+
+ /* Calculate the Size of the Serialised Data. Could be more efficient (Try 8) */
+ bufferSize += 2; /* CsrUint16 primitive->interfaceTag */
+ bufferSize += 2; /* CsrUint16 primitive->dataLength */
+ bufferSize += primitive->dataLength; /* CsrUint8 primitive->data */
+ return bufferSize;
+}
+
+
+CsrUint8* CsrWifiRouterCtrlWapiUnicastTxPktReqSer(CsrUint8 *ptr, CsrSize *len, void *msg)
+{
+ CsrWifiRouterCtrlWapiUnicastTxPktReq *primitive = (CsrWifiRouterCtrlWapiUnicastTxPktReq *)msg;
+ *len = 0;
+ CsrUint16Ser(ptr, len, primitive->common.type);
+ CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag);
+ CsrUint16Ser(ptr, len, (CsrUint16) primitive->dataLength);
+ if (primitive->dataLength)
+ {
+ CsrMemCpySer(ptr, len, (const void *) primitive->data, ((CsrUint16) (primitive->dataLength)));
+ }
+ return(ptr);
+}
+
+
+void* CsrWifiRouterCtrlWapiUnicastTxPktReqDes(CsrUint8 *buffer, CsrSize length)
+{
+ CsrWifiRouterCtrlWapiUnicastTxPktReq *primitive = (CsrWifiRouterCtrlWapiUnicastTxPktReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlWapiUnicastTxPktReq));
+ CsrSize offset;
+ offset = 0;
+
+ CsrUint16Des(&primitive->common.type, buffer, &offset);
+ CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset);
+ CsrUint16Des((CsrUint16 *) &primitive->dataLength, buffer, &offset);
+ if (primitive->dataLength)
+ {
+ primitive->data = (CsrUint8 *)CsrPmemAlloc(primitive->dataLength);
+ CsrMemCpyDes(primitive->data, buffer, &offset, ((CsrUint16) (primitive->dataLength)));
+ }
+ else
+ {
+ primitive->data = NULL;
+ }
+
+ return primitive;
+}
+
+
+void CsrWifiRouterCtrlWapiUnicastTxPktReqSerFree(void *voidPrimitivePointer)
+{
+ CsrWifiRouterCtrlWapiUnicastTxPktReq *primitive = (CsrWifiRouterCtrlWapiUnicastTxPktReq *) voidPrimitivePointer;
+ CsrPmemFree(primitive->data);
+ CsrPmemFree(primitive);
+}
+
+
CsrSize CsrWifiRouterCtrlHipIndSizeof(void *msg)
{
CsrWifiRouterCtrlHipInd *primitive = (CsrWifiRouterCtrlHipInd *) msg;
}
-CsrSize CsrWifiRouterCtrlWapiMulticastIndSizeof(void *msg)
+CsrSize CsrWifiRouterCtrlWapiRxMicCheckIndSizeof(void *msg)
{
- CsrWifiRouterCtrlWapiMulticastInd *primitive = (CsrWifiRouterCtrlWapiMulticastInd *) msg;
+ CsrWifiRouterCtrlWapiRxMicCheckInd *primitive = (CsrWifiRouterCtrlWapiRxMicCheckInd *) msg;
CsrSize bufferSize = 2;
/* Calculate the Size of the Serialised Data. Could be more efficient (Try 13) */
}
-CsrUint8* CsrWifiRouterCtrlWapiMulticastIndSer(CsrUint8 *ptr, CsrSize *len, void *msg)
+CsrUint8* CsrWifiRouterCtrlWapiRxMicCheckIndSer(CsrUint8 *ptr, CsrSize *len, void *msg)
{
- CsrWifiRouterCtrlWapiMulticastInd *primitive = (CsrWifiRouterCtrlWapiMulticastInd *)msg;
+ CsrWifiRouterCtrlWapiRxMicCheckInd *primitive = (CsrWifiRouterCtrlWapiRxMicCheckInd *)msg;
*len = 0;
CsrUint16Ser(ptr, len, primitive->common.type);
CsrUint16Ser(ptr, len, (CsrUint16) primitive->clientData);
}
-void* CsrWifiRouterCtrlWapiMulticastIndDes(CsrUint8 *buffer, CsrSize length)
+void* CsrWifiRouterCtrlWapiRxMicCheckIndDes(CsrUint8 *buffer, CsrSize length)
{
- CsrWifiRouterCtrlWapiMulticastInd *primitive = (CsrWifiRouterCtrlWapiMulticastInd *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlWapiMulticastInd));
+ CsrWifiRouterCtrlWapiRxMicCheckInd *primitive = (CsrWifiRouterCtrlWapiRxMicCheckInd *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlWapiRxMicCheckInd));
CsrSize offset;
offset = 0;
}
-void CsrWifiRouterCtrlWapiMulticastIndSerFree(void *voidPrimitivePointer)
+void CsrWifiRouterCtrlWapiRxMicCheckIndSerFree(void *voidPrimitivePointer)
{
- CsrWifiRouterCtrlWapiMulticastInd *primitive = (CsrWifiRouterCtrlWapiMulticastInd *) voidPrimitivePointer;
+ CsrWifiRouterCtrlWapiRxMicCheckInd *primitive = (CsrWifiRouterCtrlWapiRxMicCheckInd *) voidPrimitivePointer;
CsrPmemFree(primitive->signal);
CsrPmemFree(primitive->data);
CsrPmemFree(primitive);
}
+CsrSize CsrWifiRouterCtrlModeSetCfmSizeof(void *msg)
+{
+ CsrSize bufferSize = 2;
+
+ /* Calculate the Size of the Serialised Data. Could be more efficient (Try 10) */
+ bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */
+ bufferSize += 2; /* CsrUint16 primitive->interfaceTag */
+ bufferSize += 1; /* CsrWifiRouterCtrlMode primitive->mode */
+ bufferSize += 2; /* CsrResult primitive->status */
+ return bufferSize;
+}
+
+
+CsrUint8* CsrWifiRouterCtrlModeSetCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg)
+{
+ CsrWifiRouterCtrlModeSetCfm *primitive = (CsrWifiRouterCtrlModeSetCfm *)msg;
+ *len = 0;
+ CsrUint16Ser(ptr, len, primitive->common.type);
+ CsrUint16Ser(ptr, len, (CsrUint16) primitive->clientData);
+ CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag);
+ CsrUint8Ser(ptr, len, (CsrUint8) primitive->mode);
+ CsrUint16Ser(ptr, len, (CsrUint16) primitive->status);
+ return(ptr);
+}
+
+
+void* CsrWifiRouterCtrlModeSetCfmDes(CsrUint8 *buffer, CsrSize length)
+{
+ CsrWifiRouterCtrlModeSetCfm *primitive = (CsrWifiRouterCtrlModeSetCfm *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlModeSetCfm));
+ CsrSize offset;
+ offset = 0;
+
+ CsrUint16Des(&primitive->common.type, buffer, &offset);
+ CsrUint16Des((CsrUint16 *) &primitive->clientData, buffer, &offset);
+ CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset);
+ CsrUint8Des((CsrUint8 *) &primitive->mode, buffer, &offset);
+ CsrUint16Des((CsrUint16 *) &primitive->status, buffer, &offset);
+
+ return primitive;
+}
+
+
+CsrSize CsrWifiRouterCtrlWapiUnicastTxEncryptIndSizeof(void *msg)
+{
+ CsrWifiRouterCtrlWapiUnicastTxEncryptInd *primitive = (CsrWifiRouterCtrlWapiUnicastTxEncryptInd *) msg;
+ CsrSize bufferSize = 2;
+
+ /* Calculate the Size of the Serialised Data. Could be more efficient (Try 10) */
+ bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */
+ bufferSize += 2; /* CsrUint16 primitive->interfaceTag */
+ bufferSize += 2; /* CsrUint16 primitive->dataLength */
+ bufferSize += primitive->dataLength; /* CsrUint8 primitive->data */
+ return bufferSize;
+}
+
+
+CsrUint8* CsrWifiRouterCtrlWapiUnicastTxEncryptIndSer(CsrUint8 *ptr, CsrSize *len, void *msg)
+{
+ CsrWifiRouterCtrlWapiUnicastTxEncryptInd *primitive = (CsrWifiRouterCtrlWapiUnicastTxEncryptInd *)msg;
+ *len = 0;
+ CsrUint16Ser(ptr, len, primitive->common.type);
+ CsrUint16Ser(ptr, len, (CsrUint16) primitive->clientData);
+ CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag);
+ CsrUint16Ser(ptr, len, (CsrUint16) primitive->dataLength);
+ if (primitive->dataLength)
+ {
+ CsrMemCpySer(ptr, len, (const void *) primitive->data, ((CsrUint16) (primitive->dataLength)));
+ }
+ return(ptr);
+}
+
+
+void* CsrWifiRouterCtrlWapiUnicastTxEncryptIndDes(CsrUint8 *buffer, CsrSize length)
+{
+ CsrWifiRouterCtrlWapiUnicastTxEncryptInd *primitive = (CsrWifiRouterCtrlWapiUnicastTxEncryptInd *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlWapiUnicastTxEncryptInd));
+ CsrSize offset;
+ offset = 0;
+
+ CsrUint16Des(&primitive->common.type, buffer, &offset);
+ CsrUint16Des((CsrUint16 *) &primitive->clientData, buffer, &offset);
+ CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset);
+ CsrUint16Des((CsrUint16 *) &primitive->dataLength, buffer, &offset);
+ if (primitive->dataLength)
+ {
+ primitive->data = (CsrUint8 *)CsrPmemAlloc(primitive->dataLength);
+ CsrMemCpyDes(primitive->data, buffer, &offset, ((CsrUint16) (primitive->dataLength)));
+ }
+ else
+ {
+ primitive->data = NULL;
+ }
+
+ return primitive;
+}
+
+
+void CsrWifiRouterCtrlWapiUnicastTxEncryptIndSerFree(void *voidPrimitivePointer)
+{
+ CsrWifiRouterCtrlWapiUnicastTxEncryptInd *primitive = (CsrWifiRouterCtrlWapiUnicastTxEncryptInd *) voidPrimitivePointer;
+ CsrPmemFree(primitive->data);
+ CsrPmemFree(primitive);
+}
+
+
/*****************************************************************************
- (c) Cambridge Silicon Radio Limited 2011
+ (c) Cambridge Silicon Radio Limited 2012
All rights reserved and confidential information of CSR
Refer to LICENSE.txt included with this source for details
#define CsrWifiRouterCtrlWifiOffResSizeof CsrWifiEventCsrUint16Sizeof
#define CsrWifiRouterCtrlWifiOffResSerFree CsrWifiRouterCtrlPfree
-#define CsrWifiRouterCtrlWifiOnReqSer CsrWifiEventCsrUint16Ser
-#define CsrWifiRouterCtrlWifiOnReqDes CsrWifiEventCsrUint16Des
-#define CsrWifiRouterCtrlWifiOnReqSizeof CsrWifiEventCsrUint16Sizeof
-#define CsrWifiRouterCtrlWifiOnReqSerFree CsrWifiRouterCtrlPfree
+extern CsrUint8* CsrWifiRouterCtrlWifiOnReqSer(CsrUint8 *ptr, CsrSize *len, void *msg);
+extern void* CsrWifiRouterCtrlWifiOnReqDes(CsrUint8 *buffer, CsrSize len);
+extern CsrSize CsrWifiRouterCtrlWifiOnReqSizeof(void *msg);
+extern void CsrWifiRouterCtrlWifiOnReqSerFree(void *msg);
extern CsrUint8* CsrWifiRouterCtrlWifiOnResSer(CsrUint8 *ptr, CsrSize *len, void *msg);
extern void* CsrWifiRouterCtrlWifiOnResDes(CsrUint8 *buffer, CsrSize len);
extern CsrSize CsrWifiRouterCtrlBlockAckDisableReqSizeof(void *msg);
#define CsrWifiRouterCtrlBlockAckDisableReqSerFree CsrWifiRouterCtrlPfree
-extern CsrUint8* CsrWifiRouterCtrlWapiMulticastReqSer(CsrUint8 *ptr, CsrSize *len, void *msg);
-extern void* CsrWifiRouterCtrlWapiMulticastReqDes(CsrUint8 *buffer, CsrSize len);
-extern CsrSize CsrWifiRouterCtrlWapiMulticastReqSizeof(void *msg);
-extern void CsrWifiRouterCtrlWapiMulticastReqSerFree(void *msg);
+extern CsrUint8* CsrWifiRouterCtrlWapiRxPktReqSer(CsrUint8 *ptr, CsrSize *len, void *msg);
+extern void* CsrWifiRouterCtrlWapiRxPktReqDes(CsrUint8 *buffer, CsrSize len);
+extern CsrSize CsrWifiRouterCtrlWapiRxPktReqSizeof(void *msg);
+extern void CsrWifiRouterCtrlWapiRxPktReqSerFree(void *msg);
-#define CsrWifiRouterCtrlWapiMulticastFilterReqSer CsrWifiEventCsrUint8Ser
-#define CsrWifiRouterCtrlWapiMulticastFilterReqDes CsrWifiEventCsrUint8Des
-#define CsrWifiRouterCtrlWapiMulticastFilterReqSizeof CsrWifiEventCsrUint8Sizeof
+#define CsrWifiRouterCtrlWapiMulticastFilterReqSer CsrWifiEventCsrUint16CsrUint8Ser
+#define CsrWifiRouterCtrlWapiMulticastFilterReqDes CsrWifiEventCsrUint16CsrUint8Des
+#define CsrWifiRouterCtrlWapiMulticastFilterReqSizeof CsrWifiEventCsrUint16CsrUint8Sizeof
#define CsrWifiRouterCtrlWapiMulticastFilterReqSerFree CsrWifiRouterCtrlPfree
-#define CsrWifiRouterCtrlWapiUnicastFilterReqSer CsrWifiEventCsrUint8Ser
-#define CsrWifiRouterCtrlWapiUnicastFilterReqDes CsrWifiEventCsrUint8Des
-#define CsrWifiRouterCtrlWapiUnicastFilterReqSizeof CsrWifiEventCsrUint8Sizeof
+#define CsrWifiRouterCtrlWapiUnicastFilterReqSer CsrWifiEventCsrUint16CsrUint8Ser
+#define CsrWifiRouterCtrlWapiUnicastFilterReqDes CsrWifiEventCsrUint16CsrUint8Des
+#define CsrWifiRouterCtrlWapiUnicastFilterReqSizeof CsrWifiEventCsrUint16CsrUint8Sizeof
#define CsrWifiRouterCtrlWapiUnicastFilterReqSerFree CsrWifiRouterCtrlPfree
+extern CsrUint8* CsrWifiRouterCtrlWapiUnicastTxPktReqSer(CsrUint8 *ptr, CsrSize *len, void *msg);
+extern void* CsrWifiRouterCtrlWapiUnicastTxPktReqDes(CsrUint8 *buffer, CsrSize len);
+extern CsrSize CsrWifiRouterCtrlWapiUnicastTxPktReqSizeof(void *msg);
+extern void CsrWifiRouterCtrlWapiUnicastTxPktReqSerFree(void *msg);
+
+#define CsrWifiRouterCtrlWapiFilterReqSer CsrWifiEventCsrUint16CsrUint8Ser
+#define CsrWifiRouterCtrlWapiFilterReqDes CsrWifiEventCsrUint16CsrUint8Des
+#define CsrWifiRouterCtrlWapiFilterReqSizeof CsrWifiEventCsrUint16CsrUint8Sizeof
+#define CsrWifiRouterCtrlWapiFilterReqSerFree CsrWifiRouterCtrlPfree
+
extern CsrUint8* CsrWifiRouterCtrlHipIndSer(CsrUint8 *ptr, CsrSize *len, void *msg);
extern void* CsrWifiRouterCtrlHipIndDes(CsrUint8 *buffer, CsrSize len);
extern CsrSize CsrWifiRouterCtrlHipIndSizeof(void *msg);
extern CsrSize CsrWifiRouterCtrlStaInactiveIndSizeof(void *msg);
#define CsrWifiRouterCtrlStaInactiveIndSerFree CsrWifiRouterCtrlPfree
-extern CsrUint8* CsrWifiRouterCtrlWapiMulticastIndSer(CsrUint8 *ptr, CsrSize *len, void *msg);
-extern void* CsrWifiRouterCtrlWapiMulticastIndDes(CsrUint8 *buffer, CsrSize len);
-extern CsrSize CsrWifiRouterCtrlWapiMulticastIndSizeof(void *msg);
-extern void CsrWifiRouterCtrlWapiMulticastIndSerFree(void *msg);
+extern CsrUint8* CsrWifiRouterCtrlWapiRxMicCheckIndSer(CsrUint8 *ptr, CsrSize *len, void *msg);
+extern void* CsrWifiRouterCtrlWapiRxMicCheckIndDes(CsrUint8 *buffer, CsrSize len);
+extern CsrSize CsrWifiRouterCtrlWapiRxMicCheckIndSizeof(void *msg);
+extern void CsrWifiRouterCtrlWapiRxMicCheckIndSerFree(void *msg);
+
+extern CsrUint8* CsrWifiRouterCtrlModeSetCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg);
+extern void* CsrWifiRouterCtrlModeSetCfmDes(CsrUint8 *buffer, CsrSize len);
+extern CsrSize CsrWifiRouterCtrlModeSetCfmSizeof(void *msg);
+#define CsrWifiRouterCtrlModeSetCfmSerFree CsrWifiRouterCtrlPfree
+
+extern CsrUint8* CsrWifiRouterCtrlWapiUnicastTxEncryptIndSer(CsrUint8 *ptr, CsrSize *len, void *msg);
+extern void* CsrWifiRouterCtrlWapiUnicastTxEncryptIndDes(CsrUint8 *buffer, CsrSize len);
+extern CsrSize CsrWifiRouterCtrlWapiUnicastTxEncryptIndSizeof(void *msg);
+extern void CsrWifiRouterCtrlWapiUnicastTxEncryptIndSerFree(void *msg);
#ifdef __cplusplus
/*****************************************************************************
- (c) Cambridge Silicon Radio Limited 2011
+ (c) Cambridge Silicon Radio Limited 2012
All rights reserved and confidential information of CSR
Refer to LICENSE.txt included with this source for details
const CsrCharString* CsrWifiSmeApAccessTypeToString(CsrWifiSmeApAccessType value);
const CsrCharString* CsrWifiSmeApAuthSupportToString(CsrWifiSmeApAuthSupport value);
const CsrCharString* CsrWifiSmeApAuthTypeToString(CsrWifiSmeApAuthType value);
+const CsrCharString* CsrWifiSmeApDirectionToString(CsrWifiSmeApDirection value);
const CsrCharString* CsrWifiSmeApPhySupportToString(CsrWifiSmeApPhySupport value);
const CsrCharString* CsrWifiSmeApTypeToString(CsrWifiSmeApType value);
extern const CsrCharString *CsrWifiSmeApUpstreamPrimNames[CSR_WIFI_SME_AP_PRIM_UPSTREAM_COUNT];
extern const CsrCharString *CsrWifiSmeApDownstreamPrimNames[CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_COUNT];
+/*******************************************************************************
+
+ NAME
+ CsrWifiSmeApActiveBaGetReqSend
+
+ DESCRIPTION
+ This primitive used to retrieve information related to the active block
+ ack sessions
+
+ PARAMETERS
+ queue - Message Source Task Queue (Cfm's will be sent to this Queue)
+ interfaceTag -
+
+*******************************************************************************/
+#define CsrWifiSmeApActiveBaGetReqCreate(msg__, dst__, src__, interfaceTag__) \
+ msg__ = (CsrWifiSmeApActiveBaGetReq *) CsrPmemAlloc(sizeof(CsrWifiSmeApActiveBaGetReq)); \
+ CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_AP_PRIM, CSR_WIFI_SME_AP_ACTIVE_BA_GET_REQ, dst__, src__); \
+ msg__->interfaceTag = (interfaceTag__);
+
+#define CsrWifiSmeApActiveBaGetReqSendTo(dst__, src__, interfaceTag__) \
+ { \
+ CsrWifiSmeApActiveBaGetReq *msg__; \
+ CsrWifiSmeApActiveBaGetReqCreate(msg__, dst__, src__, interfaceTag__); \
+ CsrMsgTransport(dst__, CSR_WIFI_SME_AP_PRIM, msg__); \
+ }
+
+#define CsrWifiSmeApActiveBaGetReqSend(src__, interfaceTag__) \
+ CsrWifiSmeApActiveBaGetReqSendTo(CSR_WIFI_SME_IFACEQUEUE, src__, interfaceTag__)
+
+/*******************************************************************************
+
+ NAME
+ CsrWifiSmeApActiveBaGetCfmSend
+
+ DESCRIPTION
+ This primitive carries the information related to the active ba sessions
+
+ PARAMETERS
+ queue - Destination Task Queue
+ interfaceTag -
+ status - Reports the result of the request
+ activeBaCount - Number of active block ack session
+ activeBaSessions - Points to a buffer containing an array of
+ CsrWifiSmeApBaSession structures.
+
+*******************************************************************************/
+#define CsrWifiSmeApActiveBaGetCfmCreate(msg__, dst__, src__, interfaceTag__, status__, activeBaCount__, activeBaSessions__) \
+ msg__ = (CsrWifiSmeApActiveBaGetCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeApActiveBaGetCfm)); \
+ CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_AP_PRIM, CSR_WIFI_SME_AP_ACTIVE_BA_GET_CFM, dst__, src__); \
+ msg__->interfaceTag = (interfaceTag__); \
+ msg__->status = (status__); \
+ msg__->activeBaCount = (activeBaCount__); \
+ msg__->activeBaSessions = (activeBaSessions__);
+
+#define CsrWifiSmeApActiveBaGetCfmSendTo(dst__, src__, interfaceTag__, status__, activeBaCount__, activeBaSessions__) \
+ { \
+ CsrWifiSmeApActiveBaGetCfm *msg__; \
+ CsrWifiSmeApActiveBaGetCfmCreate(msg__, dst__, src__, interfaceTag__, status__, activeBaCount__, activeBaSessions__); \
+ CsrSchedMessagePut(dst__, CSR_WIFI_SME_AP_PRIM, msg__); \
+ }
+
+#define CsrWifiSmeApActiveBaGetCfmSend(dst__, interfaceTag__, status__, activeBaCount__, activeBaSessions__) \
+ CsrWifiSmeApActiveBaGetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, status__, activeBaCount__, activeBaSessions__)
+
+/*******************************************************************************
+
+ NAME
+ CsrWifiSmeApBaDeleteReqSend
+
+ DESCRIPTION
+ This primitive is used to delete an active block ack session
+
+ PARAMETERS
+ queue - Message Source Task Queue (Cfm's will be sent to this Queue)
+ interfaceTag -
+ reason -
+ baSession - BA session to be deleted
+
+*******************************************************************************/
+#define CsrWifiSmeApBaDeleteReqCreate(msg__, dst__, src__, interfaceTag__, reason__, baSession__) \
+ msg__ = (CsrWifiSmeApBaDeleteReq *) CsrPmemAlloc(sizeof(CsrWifiSmeApBaDeleteReq)); \
+ CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_AP_PRIM, CSR_WIFI_SME_AP_BA_DELETE_REQ, dst__, src__); \
+ msg__->interfaceTag = (interfaceTag__); \
+ msg__->reason = (reason__); \
+ msg__->baSession = (baSession__);
+
+#define CsrWifiSmeApBaDeleteReqSendTo(dst__, src__, interfaceTag__, reason__, baSession__) \
+ { \
+ CsrWifiSmeApBaDeleteReq *msg__; \
+ CsrWifiSmeApBaDeleteReqCreate(msg__, dst__, src__, interfaceTag__, reason__, baSession__); \
+ CsrMsgTransport(dst__, CSR_WIFI_SME_AP_PRIM, msg__); \
+ }
+
+#define CsrWifiSmeApBaDeleteReqSend(src__, interfaceTag__, reason__, baSession__) \
+ CsrWifiSmeApBaDeleteReqSendTo(CSR_WIFI_SME_IFACEQUEUE, src__, interfaceTag__, reason__, baSession__)
+
+/*******************************************************************************
+
+ NAME
+ CsrWifiSmeApBaDeleteCfmSend
+
+ DESCRIPTION
+ This primitive confirms the BA is deleted
+
+ PARAMETERS
+ queue - Destination Task Queue
+ interfaceTag -
+ status - Reports the result of the request
+ baSession - deleted BA session
+
+*******************************************************************************/
+#define CsrWifiSmeApBaDeleteCfmCreate(msg__, dst__, src__, interfaceTag__, status__, baSession__) \
+ msg__ = (CsrWifiSmeApBaDeleteCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeApBaDeleteCfm)); \
+ CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_AP_PRIM, CSR_WIFI_SME_AP_BA_DELETE_CFM, dst__, src__); \
+ msg__->interfaceTag = (interfaceTag__); \
+ msg__->status = (status__); \
+ msg__->baSession = (baSession__);
+
+#define CsrWifiSmeApBaDeleteCfmSendTo(dst__, src__, interfaceTag__, status__, baSession__) \
+ { \
+ CsrWifiSmeApBaDeleteCfm *msg__; \
+ CsrWifiSmeApBaDeleteCfmCreate(msg__, dst__, src__, interfaceTag__, status__, baSession__); \
+ CsrSchedMessagePut(dst__, CSR_WIFI_SME_AP_PRIM, msg__); \
+ }
+
+#define CsrWifiSmeApBaDeleteCfmSend(dst__, interfaceTag__, status__, baSession__) \
+ CsrWifiSmeApBaDeleteCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, status__, baSession__)
+
/*******************************************************************************
NAME
/*****************************************************************************
- (c) Cambridge Silicon Radio Limited 2011
+ (c) Cambridge Silicon Radio Limited 2012
All rights reserved and confidential information of CSR
Refer to LICENSE.txt included with this source for details
#define CSR_WIFI_SME_AP_AUTH_TYPE_PERSONAL ((CsrWifiSmeApAuthType) 0x01)
#define CSR_WIFI_SME_AP_AUTH_TYPE_WEP ((CsrWifiSmeApAuthType) 0x02)
+/*******************************************************************************
+
+ NAME
+ CsrWifiSmeApDirection
+
+ DESCRIPTION
+ Definition of Direction
+
+ VALUES
+ CSR_WIFI_AP_DIRECTION_RECEIPIENT - Receipient
+ CSR_WIFI_AP_DIRECTION_ORIGINATOR - Originator
+
+*******************************************************************************/
+typedef CsrUint8 CsrWifiSmeApDirection;
+#define CSR_WIFI_AP_DIRECTION_RECEIPIENT ((CsrWifiSmeApDirection) 0x00)
+#define CSR_WIFI_AP_DIRECTION_ORIGINATOR ((CsrWifiSmeApDirection) 0x01)
+
/*******************************************************************************
NAME
CsrWifiSmeApWapiCapabilitiesMask wapiCapabilities;
} CsrWifiSmeApAuthPers;
+/*******************************************************************************
+
+ NAME
+ CsrWifiSmeApBaSession
+
+ DESCRIPTION
+
+ MEMBERS
+ peerMacAddress - Indicates MAC address of the peer station
+ tid - Specifies the TID of the MSDUs for which this Block Ack has
+ been set up. Range: 0-15
+ direction - Specifies if the AP is the originator or the recipient of
+ the data stream that uses the Block Ack.
+
+*******************************************************************************/
+typedef struct
+{
+ CsrWifiMacAddress peerMacAddress;
+ CsrUint8 tid;
+ CsrWifiSmeApDirection direction;
+} CsrWifiSmeApBaSession;
+
/*******************************************************************************
NAME
#define CSR_WIFI_SME_AP_WMM_PARAM_UPDATE_REQ ((CsrWifiSmeApPrim) (0x0004 + CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_LOWEST))
#define CSR_WIFI_SME_AP_STA_DISCONNECT_REQ ((CsrWifiSmeApPrim) (0x0005 + CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_LOWEST))
#define CSR_WIFI_SME_AP_WPS_CONFIGURATION_REQ ((CsrWifiSmeApPrim) (0x0006 + CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_LOWEST))
+#define CSR_WIFI_SME_AP_ACTIVE_BA_GET_REQ ((CsrWifiSmeApPrim) (0x0007 + CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_LOWEST))
+#define CSR_WIFI_SME_AP_BA_DELETE_REQ ((CsrWifiSmeApPrim) (0x0008 + CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_HIGHEST (0x0006 + CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_LOWEST)
+#define CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_HIGHEST (0x0008 + CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_LOWEST)
/* Upstream */
#define CSR_WIFI_SME_AP_PRIM_UPSTREAM_LOWEST (0x0000 + CSR_PRIM_UPSTREAM)
#define CSR_WIFI_SME_AP_STA_DISCONNECT_CFM ((CsrWifiSmeApPrim)(0x0007 + CSR_WIFI_SME_AP_PRIM_UPSTREAM_LOWEST))
#define CSR_WIFI_SME_AP_WPS_CONFIGURATION_CFM ((CsrWifiSmeApPrim)(0x0008 + CSR_WIFI_SME_AP_PRIM_UPSTREAM_LOWEST))
#define CSR_WIFI_SME_AP_ERROR_IND ((CsrWifiSmeApPrim)(0x0009 + CSR_WIFI_SME_AP_PRIM_UPSTREAM_LOWEST))
+#define CSR_WIFI_SME_AP_ACTIVE_BA_GET_CFM ((CsrWifiSmeApPrim)(0x000A + CSR_WIFI_SME_AP_PRIM_UPSTREAM_LOWEST))
+#define CSR_WIFI_SME_AP_BA_DELETE_CFM ((CsrWifiSmeApPrim)(0x000B + CSR_WIFI_SME_AP_PRIM_UPSTREAM_LOWEST))
-#define CSR_WIFI_SME_AP_PRIM_UPSTREAM_HIGHEST (0x0009 + CSR_WIFI_SME_AP_PRIM_UPSTREAM_LOWEST)
+#define CSR_WIFI_SME_AP_PRIM_UPSTREAM_HIGHEST (0x000B + CSR_WIFI_SME_AP_PRIM_UPSTREAM_LOWEST)
#define CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_COUNT (CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_HIGHEST + 1 - CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_LOWEST)
#define CSR_WIFI_SME_AP_PRIM_UPSTREAM_COUNT (CSR_WIFI_SME_AP_PRIM_UPSTREAM_HIGHEST + 1 - CSR_WIFI_SME_AP_PRIM_UPSTREAM_LOWEST)
CsrWifiSmeWpsConfig wpsConfig;
} CsrWifiSmeApWpsConfigurationReq;
+/*******************************************************************************
+
+ NAME
+ CsrWifiSmeApActiveBaGetReq
+
+ DESCRIPTION
+ This primitive used to retrieve information related to the active block
+ ack sessions
+
+ MEMBERS
+ common - Common header for use with the CsrWifiFsm Module
+ interfaceTag -
+
+*******************************************************************************/
+typedef struct
+{
+ CsrWifiFsmEvent common;
+ CsrUint16 interfaceTag;
+} CsrWifiSmeApActiveBaGetReq;
+
+/*******************************************************************************
+
+ NAME
+ CsrWifiSmeApBaDeleteReq
+
+ DESCRIPTION
+ This primitive is used to delete an active block ack session
+
+ MEMBERS
+ common - Common header for use with the CsrWifiFsm Module
+ interfaceTag -
+ reason -
+ baSession - BA session to be deleted
+
+*******************************************************************************/
+typedef struct
+{
+ CsrWifiFsmEvent common;
+ CsrUint16 interfaceTag;
+ CsrWifiSmeIEEE80211Reason reason;
+ CsrWifiSmeApBaSession baSession;
+} CsrWifiSmeApBaDeleteReq;
+
/*******************************************************************************
NAME
CsrResult status;
} CsrWifiSmeApErrorInd;
+/*******************************************************************************
+
+ NAME
+ CsrWifiSmeApActiveBaGetCfm
+
+ DESCRIPTION
+ This primitive carries the information related to the active ba sessions
+
+ MEMBERS
+ common - Common header for use with the CsrWifiFsm Module
+ interfaceTag -
+ status - Reports the result of the request
+ activeBaCount - Number of active block ack session
+ activeBaSessions - Points to a buffer containing an array of
+ CsrWifiSmeApBaSession structures.
+
+*******************************************************************************/
+typedef struct
+{
+ CsrWifiFsmEvent common;
+ CsrUint16 interfaceTag;
+ CsrResult status;
+ CsrUint16 activeBaCount;
+ CsrWifiSmeApBaSession *activeBaSessions;
+} CsrWifiSmeApActiveBaGetCfm;
+
+/*******************************************************************************
+
+ NAME
+ CsrWifiSmeApBaDeleteCfm
+
+ DESCRIPTION
+ This primitive confirms the BA is deleted
+
+ MEMBERS
+ common - Common header for use with the CsrWifiFsm Module
+ interfaceTag -
+ status - Reports the result of the request
+ baSession - deleted BA session
+
+*******************************************************************************/
+typedef struct
+{
+ CsrWifiFsmEvent common;
+ CsrUint16 interfaceTag;
+ CsrResult status;
+ CsrWifiSmeApBaSession baSession;
+} CsrWifiSmeApBaDeleteCfm;
+
#ifdef __cplusplus
}
/*****************************************************************************
- (c) Cambridge Silicon Radio Limited 2011
+ (c) Cambridge Silicon Radio Limited 2012
All rights reserved and confidential information of CSR
Refer to LICENSE.txt included with this source for details
{ CSR_WIFI_SME_SME_COMMON_CONFIG_SET_REQ, CsrWifiSmeSmeCommonConfigSetReqSizeof, CsrWifiSmeSmeCommonConfigSetReqSer, CsrWifiSmeSmeCommonConfigSetReqDes, CsrWifiSmeSmeCommonConfigSetReqSerFree },
{ CSR_WIFI_SME_INTERFACE_CAPABILITY_GET_REQ, CsrWifiSmeInterfaceCapabilityGetReqSizeof, CsrWifiSmeInterfaceCapabilityGetReqSer, CsrWifiSmeInterfaceCapabilityGetReqDes, CsrWifiSmeInterfaceCapabilityGetReqSerFree },
{ CSR_WIFI_SME_WPS_CONFIGURATION_REQ, CsrWifiSmeWpsConfigurationReqSizeof, CsrWifiSmeWpsConfigurationReqSer, CsrWifiSmeWpsConfigurationReqDes, CsrWifiSmeWpsConfigurationReqSerFree },
+ { CSR_WIFI_SME_SET_REQ, CsrWifiSmeSetReqSizeof, CsrWifiSmeSetReqSer, CsrWifiSmeSetReqDes, CsrWifiSmeSetReqSerFree },
{ CSR_WIFI_SME_ACTIVATE_CFM, CsrWifiSmeActivateCfmSizeof, CsrWifiSmeActivateCfmSer, CsrWifiSmeActivateCfmDes, CsrWifiSmeActivateCfmSerFree },
{ CSR_WIFI_SME_ADHOC_CONFIG_GET_CFM, CsrWifiSmeAdhocConfigGetCfmSizeof, CsrWifiSmeAdhocConfigGetCfmSer, CsrWifiSmeAdhocConfigGetCfmDes, CsrWifiSmeAdhocConfigGetCfmSerFree },
{ CSR_WIFI_SME_ADHOC_CONFIG_SET_CFM, CsrWifiSmeAdhocConfigSetCfmSizeof, CsrWifiSmeAdhocConfigSetCfmSer, CsrWifiSmeAdhocConfigSetCfmDes, CsrWifiSmeAdhocConfigSetCfmSerFree },
{
if (msgType & CSR_PRIM_UPSTREAM)
{
- CsrUint16 index = (msgType & ~CSR_PRIM_UPSTREAM) + CSR_WIFI_SME_PRIM_DOWNSTREAM_COUNT;
- if (index < (CSR_WIFI_SME_PRIM_UPSTREAM_COUNT + CSR_WIFI_SME_PRIM_DOWNSTREAM_COUNT) &&
- csrwifisme_conv_lut[index].msgType == msgType)
+ CsrUint16 idx = (msgType & ~CSR_PRIM_UPSTREAM) + CSR_WIFI_SME_PRIM_DOWNSTREAM_COUNT;
+ if (idx < (CSR_WIFI_SME_PRIM_UPSTREAM_COUNT + CSR_WIFI_SME_PRIM_DOWNSTREAM_COUNT) &&
+ csrwifisme_conv_lut[idx].msgType == msgType)
{
- return &csrwifisme_conv_lut[index];
+ return &csrwifisme_conv_lut[idx];
}
}
else
/*****************************************************************************
- (c) Cambridge Silicon Radio Limited 2011
+ (c) Cambridge Silicon Radio Limited 2012
All rights reserved and confidential information of CSR
Refer to LICENSE.txt included with this source for details
/*****************************************************************************
- (c) Cambridge Silicon Radio Limited 2011
+ (c) Cambridge Silicon Radio Limited 2012
All rights reserved and confidential information of CSR
Refer to LICENSE.txt included with this source for details
p->wpsConfig.secondaryDeviceType = NULL;
break;
}
+ case CSR_WIFI_SME_SET_REQ:
+ {
+ CsrWifiSmeSetReq *p = (CsrWifiSmeSetReq *)message;
+ CsrPmemFree(p->data);
+ p->data = NULL;
+ break;
+ }
default:
break;
/*****************************************************************************
- (c) Cambridge Silicon Radio Limited 2011
+ (c) Cambridge Silicon Radio Limited 2012
All rights reserved and confidential information of CSR
Refer to LICENSE.txt included with this source for details
#define CsrWifiSmeScanResultsGetCfmSend(dst__, status__, scanResultsCount__, scanResults__) \
CsrWifiSmeScanResultsGetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__, scanResultsCount__, scanResults__)
+/*******************************************************************************
+
+ NAME
+ CsrWifiSmeSetReqSend
+
+ DESCRIPTION
+ Used to pass custom data to the SME. Format is the same as 802.11 Info
+ Elements => | Id | Length | Data
+ 1) Cmanr Test Mode "Id:0 Length:1 Data:0x00 = OFF 0x01 = ON" "0x00 0x01
+ (0x00|0x01)"
+
+ PARAMETERS
+ queue - Message Source Task Queue (Cfm's will be sent to this Queue)
+ dataLength - Number of bytes in the buffer pointed to by 'data'
+ data - Pointer to the buffer containing 'dataLength' bytes
+
+*******************************************************************************/
+#define CsrWifiSmeSetReqCreate(msg__, dst__, src__, dataLength__, data__) \
+ msg__ = (CsrWifiSmeSetReq *) CsrPmemAlloc(sizeof(CsrWifiSmeSetReq)); \
+ CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_SET_REQ, dst__, src__); \
+ msg__->dataLength = (dataLength__); \
+ msg__->data = (data__);
+
+#define CsrWifiSmeSetReqSendTo(dst__, src__, dataLength__, data__) \
+ { \
+ CsrWifiSmeSetReq *msg__; \
+ CsrWifiSmeSetReqCreate(msg__, dst__, src__, dataLength__, data__); \
+ CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \
+ }
+
+#define CsrWifiSmeSetReqSend(src__, dataLength__, data__) \
+ CsrWifiSmeSetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, dataLength__, data__)
+
/*******************************************************************************
NAME
/*****************************************************************************
- (c) Cambridge Silicon Radio Limited 2011
+ (c) Cambridge Silicon Radio Limited 2012
All rights reserved and confidential information of CSR
Refer to LICENSE.txt included with this source for details
CsrWifiSmeWmmMode
DESCRIPTION
- Defines bits for wmmModeMask: enable/disable WMM features.
+ Defines bits for CsrWifiSmeWmmModeMask: enable/disable WMM features.
VALUES
CSR_WIFI_SME_WMM_MODE_DISABLED - Disables the WMM features.
CsrUint16 maxPassiveChannelTimeTu;
} CsrWifiSmeScanConfigData;
-/*******************************************************************************
-
- NAME
- CsrWifiSmeStaConfig
-
- DESCRIPTION
- Station configuration options in the SME
-
- MEMBERS
- connectionQualityRssiChangeTrigger - Sets the difference of RSSI
- measurements which triggers reports
- from the Firmware
- connectionQualitySnrChangeTrigger - Sets the difference of SNR measurements
- which triggers reports from the
- Firmware
- wmmModeMask - Mask containing one or more values from
- CsrWifiSmeWmmMode
- ifIndex - Indicates the band of frequencies used
- allowUnicastUseGroupCipher - If TRUE, it allows to use groupwise
- keys if no pairwise key is specified
- enableOpportunisticKeyCaching - If TRUE, enables the Opportunistic Key
- Caching feature
-
-*******************************************************************************/
-typedef struct
-{
- CsrUint8 connectionQualityRssiChangeTrigger;
- CsrUint8 connectionQualitySnrChangeTrigger;
- CsrUint8 wmmModeMask;
- CsrWifiSmeRadioIF ifIndex;
- CsrBool allowUnicastUseGroupCipher;
- CsrBool enableOpportunisticKeyCaching;
-} CsrWifiSmeStaConfig;
-
/*******************************************************************************
NAME
} deviceInfo;
} CsrWifiSmeScanResult;
+/*******************************************************************************
+
+ NAME
+ CsrWifiSmeStaConfig
+
+ DESCRIPTION
+ Station configuration options in the SME
+
+ MEMBERS
+ connectionQualityRssiChangeTrigger - Sets the difference of RSSI
+ measurements which triggers reports
+ from the Firmware
+ connectionQualitySnrChangeTrigger - Sets the difference of SNR measurements
+ which triggers reports from the
+ Firmware
+ wmmModeMask - Mask containing one or more values from
+ CsrWifiSmeWmmMode
+ ifIndex - Indicates the band of frequencies used
+ allowUnicastUseGroupCipher - If TRUE, it allows to use groupwise
+ keys if no pairwise key is specified
+ enableOpportunisticKeyCaching - If TRUE, enables the Opportunistic Key
+ Caching feature
+
+*******************************************************************************/
+typedef struct
+{
+ CsrUint8 connectionQualityRssiChangeTrigger;
+ CsrUint8 connectionQualitySnrChangeTrigger;
+ CsrWifiSmeWmmModeMask wmmModeMask;
+ CsrWifiSmeRadioIF ifIndex;
+ CsrBool allowUnicastUseGroupCipher;
+ CsrBool enableOpportunisticKeyCaching;
+} CsrWifiSmeStaConfig;
+
/*******************************************************************************
NAME
#define CSR_WIFI_SME_SME_COMMON_CONFIG_SET_REQ ((CsrWifiSmePrim) (0x0034 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST))
#define CSR_WIFI_SME_INTERFACE_CAPABILITY_GET_REQ ((CsrWifiSmePrim) (0x0035 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST))
#define CSR_WIFI_SME_WPS_CONFIGURATION_REQ ((CsrWifiSmePrim) (0x0036 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST))
+#define CSR_WIFI_SME_SET_REQ ((CsrWifiSmePrim) (0x0037 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST))
-#define CSR_WIFI_SME_PRIM_DOWNSTREAM_HIGHEST (0x0036 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST)
+#define CSR_WIFI_SME_PRIM_DOWNSTREAM_HIGHEST (0x0037 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST)
/* Upstream */
#define CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST (0x0000 + CSR_PRIM_UPSTREAM)
CsrWifiSmeWpsConfig wpsConfig;
} CsrWifiSmeWpsConfigurationReq;
+/*******************************************************************************
+
+ NAME
+ CsrWifiSmeSetReq
+
+ DESCRIPTION
+ Used to pass custom data to the SME. Format is the same as 802.11 Info
+ Elements => | Id | Length | Data
+ 1) Cmanr Test Mode "Id:0 Length:1 Data:0x00 = OFF 0x01 = ON" "0x00 0x01
+ (0x00|0x01)"
+
+ MEMBERS
+ common - Common header for use with the CsrWifiFsm Module
+ dataLength - Number of bytes in the buffer pointed to by 'data'
+ data - Pointer to the buffer containing 'dataLength' bytes
+
+*******************************************************************************/
+typedef struct
+{
+ CsrWifiFsmEvent common;
+ CsrUint32 dataLength;
+ CsrUint8 *data;
+} CsrWifiSmeSetReq;
+
/*******************************************************************************
NAME
/*****************************************************************************
- (c) Cambridge Silicon Radio Limited 2011
+ (c) Cambridge Silicon Radio Limited 2012
All rights reserved and confidential information of CSR
Refer to LICENSE.txt included with this source for details
bufferSize += 2; /* CsrUint16 primitive->interfaceTag */
bufferSize += 1; /* CsrUint8 primitive->smeConfig.connectionQualityRssiChangeTrigger */
bufferSize += 1; /* CsrUint8 primitive->smeConfig.connectionQualitySnrChangeTrigger */
- bufferSize += 1; /* CsrUint8 primitive->smeConfig.wmmModeMask */
+ bufferSize += 1; /* CsrWifiSmeWmmModeMask primitive->smeConfig.wmmModeMask */
bufferSize += 1; /* CsrWifiSmeRadioIF primitive->smeConfig.ifIndex */
bufferSize += 1; /* CsrBool primitive->smeConfig.allowUnicastUseGroupCipher */
bufferSize += 1; /* CsrBool primitive->smeConfig.enableOpportunisticKeyCaching */
}
+CsrSize CsrWifiSmeSetReqSizeof(void *msg)
+{
+ CsrWifiSmeSetReq *primitive = (CsrWifiSmeSetReq *) msg;
+ CsrSize bufferSize = 2;
+
+ /* Calculate the Size of the Serialised Data. Could be more efficient (Try 8) */
+ bufferSize += 4; /* CsrUint32 primitive->dataLength */
+ bufferSize += primitive->dataLength; /* CsrUint8 primitive->data */
+ return bufferSize;
+}
+
+
+CsrUint8* CsrWifiSmeSetReqSer(CsrUint8 *ptr, CsrSize *len, void *msg)
+{
+ CsrWifiSmeSetReq *primitive = (CsrWifiSmeSetReq *)msg;
+ *len = 0;
+ CsrUint16Ser(ptr, len, primitive->common.type);
+ CsrUint32Ser(ptr, len, (CsrUint32) primitive->dataLength);
+ if (primitive->dataLength)
+ {
+ CsrMemCpySer(ptr, len, (const void *) primitive->data, ((CsrUint16) (primitive->dataLength)));
+ }
+ return(ptr);
+}
+
+
+void* CsrWifiSmeSetReqDes(CsrUint8 *buffer, CsrSize length)
+{
+ CsrWifiSmeSetReq *primitive = (CsrWifiSmeSetReq *) CsrPmemAlloc(sizeof(CsrWifiSmeSetReq));
+ CsrSize offset;
+ offset = 0;
+
+ CsrUint16Des(&primitive->common.type, buffer, &offset);
+ CsrUint32Des((CsrUint32 *) &primitive->dataLength, buffer, &offset);
+ if (primitive->dataLength)
+ {
+ primitive->data = (CsrUint8 *)CsrPmemAlloc(primitive->dataLength);
+ CsrMemCpyDes(primitive->data, buffer, &offset, ((CsrUint16) (primitive->dataLength)));
+ }
+ else
+ {
+ primitive->data = NULL;
+ }
+
+ return primitive;
+}
+
+
+void CsrWifiSmeSetReqSerFree(void *voidPrimitivePointer)
+{
+ CsrWifiSmeSetReq *primitive = (CsrWifiSmeSetReq *) voidPrimitivePointer;
+ CsrPmemFree(primitive->data);
+ CsrPmemFree(primitive);
+}
+
+
CsrSize CsrWifiSmeAdhocConfigGetCfmSizeof(void *msg)
{
CsrSize bufferSize = 2;
bufferSize += 2; /* CsrResult primitive->status */
bufferSize += 1; /* CsrUint8 primitive->smeConfig.connectionQualityRssiChangeTrigger */
bufferSize += 1; /* CsrUint8 primitive->smeConfig.connectionQualitySnrChangeTrigger */
- bufferSize += 1; /* CsrUint8 primitive->smeConfig.wmmModeMask */
+ bufferSize += 1; /* CsrWifiSmeWmmModeMask primitive->smeConfig.wmmModeMask */
bufferSize += 1; /* CsrWifiSmeRadioIF primitive->smeConfig.ifIndex */
bufferSize += 1; /* CsrBool primitive->smeConfig.allowUnicastUseGroupCipher */
bufferSize += 1; /* CsrBool primitive->smeConfig.enableOpportunisticKeyCaching */
/*****************************************************************************
- (c) Cambridge Silicon Radio Limited 2011
+ (c) Cambridge Silicon Radio Limited 2012
All rights reserved and confidential information of CSR
Refer to LICENSE.txt included with this source for details
extern CsrSize CsrWifiSmeWpsConfigurationReqSizeof(void *msg);
extern void CsrWifiSmeWpsConfigurationReqSerFree(void *msg);
+extern CsrUint8* CsrWifiSmeSetReqSer(CsrUint8 *ptr, CsrSize *len, void *msg);
+extern void* CsrWifiSmeSetReqDes(CsrUint8 *buffer, CsrSize len);
+extern CsrSize CsrWifiSmeSetReqSizeof(void *msg);
+extern void CsrWifiSmeSetReqSerFree(void *msg);
+
#define CsrWifiSmeActivateCfmSer CsrWifiEventCsrUint16Ser
#define CsrWifiSmeActivateCfmDes CsrWifiEventCsrUint16Des
#define CsrWifiSmeActivateCfmSizeof CsrWifiEventCsrUint16Sizeof
int buswidth = 0; /* 0 means use default, values 1,4 */
int sdio_clock = 50000; /* kHz */
int unifi_debug = 0;
-/*
- * fw_init prevents f/w initialisation on error.
- * Unless necessary, avoid usage in the CSR_SME_EMB build because it prevents
- * UniFi initialisation after getting out of suspend and also leaves
- * UniFi powered when the module unloads.
- */
+/* fw_init prevents f/w initialisation on error. */
int fw_init[MAX_UNIFI_DEVS] = {-1, -1};
int use_5g = 0;
int led_mask = 0; /* 0x0c00 for dev-pc-1503c, dev-pc-1528a */
int coredump_max = CSR_WIFI_HIP_NUM_COREDUMP_BUFFERS;
int run_bh_once = -1; /* Set for scheduled interrupt mode, -1 = default */
int bh_priority = -1;
+#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
+#define UNIFI_LOG_HIP_SIGNALS_FILTER_SIGNAL (1 << 0)
+#define UNIFI_LOG_HIP_SIGNALS_FILTER_BULKDATA (1 << 1)
+#define UNIFI_LOG_HIP_SIGNALS_FILTER_TIMESTAMP (1 << 2)
+int log_hip_signals = 0;
+#endif
MODULE_DESCRIPTION("CSR UniFi (SDIO)");
module_param(coredump_max, int, S_IRUGO|S_IWUSR);
module_param(run_bh_once, int, S_IRUGO|S_IWUSR);
module_param(bh_priority, int, S_IRUGO|S_IWUSR);
+#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
+module_param(log_hip_signals, int, S_IRUGO|S_IWUSR);
+#endif
MODULE_PARM_DESC(buswidth, "SDIO bus width (0=default), set 1 for 1-bit or 4 for 4-bit mode");
MODULE_PARM_DESC(sdio_clock, "SDIO bus frequency in kHz, (default = 50 MHz)");
MODULE_PARM_DESC(coredump_max, "Number of chip mini-coredump buffers to allocate");
MODULE_PARM_DESC(run_bh_once, "Run BH only when firmware interrupts");
MODULE_PARM_DESC(bh_priority, "Modify the BH thread priority");
+#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
+MODULE_PARM_DESC(log_hip_signals, "Set to 1 to enable HIP signal offline logging");
+#endif
+
/* Callback for event logging to UDI clients */
static void udi_log_event(ul_client_t *client,
}
}
+#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
+int uf_register_hip_offline_debug(unifi_priv_t *priv)
+{
+ ul_client_t *udi_cli;
+ int i;
+
+ udi_cli = ul_register_client(priv, CLI_USING_WIRE_FORMAT, udi_log_event);
+ if (udi_cli == NULL) {
+ /* Too many clients already using this device */
+ unifi_error(priv, "Too many UDI clients already open\n");
+ return -ENOSPC;
+ }
+ unifi_trace(priv, UDBG1, "Offline HIP client is registered\n");
+
+ down(&priv->udi_logging_mutex);
+ udi_cli->event_hook = udi_log_event;
+ unifi_set_udi_hook(priv->card, logging_handler);
+ /* Log all signals by default */
+ for (i = 0; i < SIG_FILTER_SIZE; i++) {
+ udi_cli->signal_filter[i] = 0xFFFF;
+ }
+ priv->logging_client = udi_cli;
+ up(&priv->udi_logging_mutex);
+
+ return 0;
+}
+
+int uf_unregister_hip_offline_debug(unifi_priv_t *priv)
+{
+ ul_client_t *udi_cli = priv->logging_client;
+ if (udi_cli == NULL)
+ {
+ unifi_error(priv, "Unknown HIP client unregister request\n");
+ return -ERANGE;
+ }
+
+ unifi_trace(priv, UDBG1, "Offline HIP client is unregistered\n");
+
+ down(&priv->udi_logging_mutex);
+ priv->logging_client = NULL;
+ udi_cli->event_hook = NULL;
+ up(&priv->udi_logging_mutex);
+
+ ul_deregister_client(udi_cli);
+
+ return 0;
+}
+#endif
/*
} /* unifi_open() */
-
static int
unifi_release(struct inode *inode, struct file *filp)
{
}
uf_sme_deinit(priv);
+
+ /* It is possible that a blocking SME request was made from another process
+ * which did not get read by the SME before the WifiOffReq.
+ * So check for a pending request which will go unanswered and cancel
+ * the wait for event. As only one blocking request can be in progress at
+ * a time, up to one event should be completed.
+ */
+ uf_sme_cancel_request(priv, 0);
+
#endif /* CSR_SME_USERSPACE */
} else {
goto out;
}
+#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
+ if (log_hip_signals) {
+ unifi_error(priv, "omnicli cannot be used when log_hip_signals is used\n");
+ r = -EFAULT;
+ goto out;
+ }
+#endif
+
down(&priv->udi_logging_mutex);
if (int_param) {
pcli->event_hook = udi_log_event;
unifi_info(priv, "UniFi ready\n");
+#ifdef ANDROID_BUILD
+ /* Release the wakelock */
+ unifi_trace(priv, UDBG1, "netdev_init: release wake lock\n");
+ wake_unlock(&unifi_sdio_wake_lock);
+#endif
#ifdef CSR_NATIVE_SOFTMAC /* For softmac dev, force-enable the network interface rather than wait for a connected-ind */
{
struct net_device *dev = priv->netdev[interfaceTag];
return;
}
+#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
+ /* When HIP offline signal logging is enabled, omnicli cannot run */
+ if (log_hip_signals)
+ {
+ /* Add timestamp */
+ if (log_hip_signals & UNIFI_LOG_HIP_SIGNALS_FILTER_TIMESTAMP)
+ {
+ int timestamp = jiffies_to_msecs(jiffies);
+ unifi_debug_log_to_buf("T:");
+ unifi_debug_log_to_buf("%04X%04X ", *(((CsrUint16*)×tamp) + 1),
+ *(CsrUint16*)×tamp);
+ }
+
+ /* Add signal */
+ unifi_debug_log_to_buf("S%s:%04X R:%04X D:%04X ",
+ dir ? "T" : "F",
+ *(CsrUint16*)signal,
+ *(CsrUint16*)(signal + 2),
+ *(CsrUint16*)(signal + 4));
+ unifi_debug_hex_to_buf(signal + 6, signal_len - 6);
+
+ /* Add bulk data (assume 1 bulk data per signal) */
+ if ((log_hip_signals & UNIFI_LOG_HIP_SIGNALS_FILTER_BULKDATA) &&
+ (bulkdata->d[0].data_length > 0))
+ {
+ unifi_debug_log_to_buf("\nD:");
+ unifi_debug_hex_to_buf(bulkdata->d[0].os_data_ptr, bulkdata->d[0].data_length);
+ }
+ unifi_debug_log_to_buf("\n");
+
+ return;
+ }
+#endif
+
#ifdef CSR_NATIVE_LINUX
uf_native_process_udi_signal(pcli, signal, signal_len, bulkdata, dir);
#endif
priv->unifiudi_cdev.owner = THIS_MODULE;
devno = MKDEV(MAJOR(unifi_first_devno),
- MINOR(unifi_first_devno) + (bus_id * MAX_UNIFI_DEVS) + 1);
+ MINOR(unifi_first_devno) + (bus_id * 2) + 1);
r = cdev_add(&priv->unifiudi_cdev, devno, 1);
if (r) {
device_destroy(unifi_class, priv->unifi_cdev.dev);
#endif
printk("CSR native no WEXT support\n");
#endif
-
+#ifdef CSR_WIFI_SPLIT_PATCH
+ printk("Split patch support\n");
+#endif
printk("Kernel %d.%d.%d\n",
((LINUX_VERSION_CODE) >> 16) & 0xff,
((LINUX_VERSION_CODE) >> 8) & 0xff,
#endif
} /* uf_run_unifihelper() */
+#ifdef CSR_WIFI_SPLIT_PATCH
+static CsrBool is_ap_mode(unifi_priv_t *priv)
+{
+ if (priv == NULL || priv->interfacePriv[0] == NULL)
+ {
+ return FALSE;
+ }
+ /* Test for mode requiring AP patch */
+ return(CSR_WIFI_HIP_IS_AP_FW(priv->interfacePriv[0]->interfaceMode));
+}
+#endif
/*
* ---------------------------------------------------------------------------
if (is_fw == UNIFI_FW_STA) {
/* Free kernel buffer and reload */
uf_release_firmware(priv, &priv->fw_sta);
+#ifdef CSR_WIFI_SPLIT_PATCH
scnprintf(fw_name, UNIFI_MAX_FW_PATH_LEN, "unifi-sdio-%d/%s",
- postfix, "sta.xbv");
+ postfix, (is_ap_mode(priv) ? "ap.xbv" : "staonly.xbv") );
+#else
+ scnprintf(fw_name, UNIFI_MAX_FW_PATH_LEN, "unifi-sdio-%d/%s",
+ postfix, "sta.xbv" );
+#endif
r = request_firmware(&fw_entry, fw_name, priv->unifi_device);
if (r == 0) {
priv->fw_sta.dl_data = fw_entry->data;
INIT_WORK(&priv->rx_work_struct, rx_wq_handler);
#endif
+#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
+ if (log_hip_signals)
+ {
+ uf_register_hip_offline_debug(priv);
+ }
+#endif
+
/* Initialise the SME related threads and parameters */
r = uf_sme_init(priv);
if (r) {
return priv;
failed4:
+#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
+if (log_hip_signals)
+{
+ uf_unregister_hip_offline_debug(priv);
+}
+#endif
#ifdef CSR_WIFI_RX_PATH_SPLIT
flush_workqueue(priv->rx_workqueue);
destroy_workqueue(priv->rx_workqueue);
priv->smepriv = NULL;
#endif
+#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
+ if (log_hip_signals)
+ {
+ uf_unregister_hip_offline_debug(priv);
+ }
+#endif
+
/* Free any packets left in the Rx queues */
for(i=0;i<CSR_WIFI_NUM_INTERFACES;i++)
{
priv->sta_wmm_capabilities = 0;
+#if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_SUPPORT_SME))
priv->wapi_multicast_filter = 0;
priv->wapi_unicast_filter = 0;
priv->wapi_unicast_queued_pkt_filter = 0;
+#ifdef CSR_WIFI_SECURITY_WAPI_QOSCTRL_MIC_WORKAROUND
+ priv->isWapiConnection = FALSE;
+#endif
+#endif
/* Enable all queues by default */
interfacePriv->queueEnabled[0] = 1;
spin_lock_init(&priv->send_signal_lock);
spin_lock_init(&priv->m4_lock);
- spin_lock_init(&priv->ba_lock);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)
+ sema_init(&priv->ba_mutex, 1);
+#else
+ init_MUTEX(&priv->ba_mutex);
+#endif
+
+#if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION))
+ spin_lock_init(&priv->wapi_lock);
+#endif
#ifdef CSR_SUPPORT_SME
spin_lock_init(&priv->staRecord_lock);
/* Create m4 buffering work structure */
INIT_WORK(&interfacePriv->send_m4_ready_task, uf_send_m4_ready_wq);
+
+#if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION))
+ /* Create work structure to buffer the WAPI data packets to be sent to SME for encryption */
+ INIT_WORK(&interfacePriv->send_pkt_to_encrypt, uf_send_pkt_to_encrypt);
+#endif
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
}
#endif /* CSR_SUPPORT_WEXT */
+#ifdef CSR_WIFI_SPLIT_PATCH
+ /* set it to some invalid value */
+ priv->pending_mode_set.common.destination = 0xaaaa;
+#endif
+
return priv;
} /* uf_alloc_netdevice() */
}
spin_unlock_irqrestore(&priv->m4_lock, flags);
+#if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION))
+ /* Free any bulkdata buffers allocated for M4 caching */
+ spin_lock_irqsave(&priv->wapi_lock, flags);
+ for (i = 0; i < CSR_WIFI_NUM_INTERFACES; i++) {
+ netInterface_priv_t *interfacePriv = priv->interfacePriv[i];
+ if (interfacePriv->wapi_unicast_bulk_data.data_length > 0) {
+ unifi_trace(priv, UDBG5, "uf_free_netdevice: free WAPI PKT bulk data %d\n", i);
+ unifi_net_data_free(priv, &interfacePriv->wapi_unicast_bulk_data);
+ }
+ }
+ spin_unlock_irqrestore(&priv->wapi_lock, flags);
+#endif
+
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
#ifdef CONFIG_NET_SCHED
/* Unregister the qdisc operations */
/* IF Qos Data or Qos Null Data then set QosControl field */
if ((priority != CSR_CONTENTION) && (macHeaderLengthInBytes >= QOS_CONTROL_HEADER_SIZE)) {
- if (priority >= 7) {
+ if (priority > 7) {
unifi_trace(priv, UDBG1, "data packets priority is more than 7, priority = %x\n", priority);
qc |= 7;
} else {
CSR_TRANSMISSION_CONTROL transmissionControl = CSR_NO_CONFIRM_REQUIRED;
CsrInt8 protection;
netInterface_priv_t *interfacePriv = NULL;
+ CSR_RATE TransmitRate = (CSR_RATE)0;
unifi_trace(priv, UDBG5, "entering send_ma_pkt_request\n");
return 0;
}
#endif
+ }/*EAPOL or WAI packet*/
+
+#if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION))
+ if ((CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode) && \
+ (priv->wapi_unicast_filter) && \
+ (proto != ETH_P_PAE) && \
+ (proto != ETH_P_WAI) && \
+ (skb->len > 0))
+ {
+ CSR_SIGNAL signal;
+ CSR_MA_PACKET_REQUEST *req = &signal.u.MaPacketRequest;
+ netInterface_priv_t *netpriv = (netInterface_priv_t *)netdev_priv(priv->netdev[interfaceTag]);
+
+ unifi_trace(priv, UDBG4, "send_ma_pkt_request() - WAPI unicast data packet when USKID = 1 \n");
+
+ /* initialize signal to zero */
+ memset(&signal, 0, sizeof(CSR_SIGNAL));
+ /* Frame MA_PACKET request */
+ signal.SignalPrimitiveHeader.SignalId = CSR_MA_PACKET_REQUEST_ID;
+ signal.SignalPrimitiveHeader.ReceiverProcessId = 0;
+ signal.SignalPrimitiveHeader.SenderProcessId = priv->netdev_client->sender_id;
+
+ /* Fill the MA-PACKET.req */
+ req->TransmissionControl = 0;
+ req->Priority = priority;
+ unifi_trace(priv, UDBG3, "Tx Frame with Priority: %x\n", req->Priority);
+ req->TransmitRate = (CSR_RATE) 0; /* rate selected by firmware */
+ req->HostTag = 0xffffffff; /* Ask for a new HostTag */
+ /* RA address matching with address 1 of Mac header */
+ memcpy(req->Ra.x, ((CsrUint8 *) bulkdata.d[0].os_data_ptr) + 4, ETH_ALEN);
+
+ /* Store the M4-PACKET.req for later */
+ spin_lock(&priv->wapi_lock);
+ interfacePriv->wapi_unicast_ma_pkt_sig = signal;
+ interfacePriv->wapi_unicast_bulk_data.net_buf_length = bulkdata.d[0].net_buf_length;
+ interfacePriv->wapi_unicast_bulk_data.data_length = bulkdata.d[0].data_length;
+ interfacePriv->wapi_unicast_bulk_data.os_data_ptr = bulkdata.d[0].os_data_ptr;
+ interfacePriv->wapi_unicast_bulk_data.os_net_buf_ptr = bulkdata.d[0].os_net_buf_ptr;
+ spin_unlock(&priv->wapi_lock);
+
+ /* Signal the workqueue to call CsrWifiRouterCtrlWapiUnicastTxEncryptIndSend().
+ * It cannot be called directly from the tx path because it
+ * does a non-atomic kmalloc via the framework's CsrPmemAlloc().
+ */
+ queue_work(priv->unifi_workqueue, &netpriv->send_pkt_to_encrypt);
+
+ return 0;
+ }
+#endif
+
+ if(priv->cmanrTestMode)
+ {
+ TransmitRate = priv->cmanrTestModeTransmitRate;
+ unifi_trace(priv, UDBG2, "send_ma_pkt_request: cmanrTestModeTransmitRate = %d TransmitRate=%d\n",
+ priv->cmanrTestModeTransmitRate,
+ TransmitRate
+ );
}
/* Send UniFi msg */
0xffffffff, /* Ask for a new HostTag */
interfaceTag,
transmissionControl,
- (CSR_RATE)0,
+ TransmitRate,
priority,
priv->netdev_client->sender_id,
&bulkdata);
#endif /* CONFIG_NET_SCHED */
if (result == NETDEV_TX_OK) {
+#if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION))
+ /* Don't update the tx stats when the pkt is to be sent for sw encryption*/
+ if (!((CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode) &&
+ (priv->wapi_unicast_filter == 1)))
+ {
+ dev->trans_start = jiffies;
+ /* Should really count tx stats in the UNITDATA.status signal but
+ * that doesn't have the length.
+ */
+ interfacePriv->stats.tx_packets++;
+ /* count only the packet payload */
+ interfacePriv->stats.tx_bytes += skb->len;
- dev->trans_start = jiffies;
+ }
+#else
+ dev->trans_start = jiffies;
/*
* Should really count tx stats in the UNITDATA.status signal but
interfacePriv->stats.tx_packets++;
/* count only the packet payload */
interfacePriv->stats.tx_bytes += skb->len;
-
+#endif
} else if (result < 0) {
/* Failed to send: fh queue was full, and the skb was discarded.
}
+ if(priv->cmanrTestMode)
+ {
+ const CSR_MA_PACKET_INDICATION *pkt_ind = &signal->u.MaPacketIndication;
+ priv->cmanrTestModeTransmitRate = pkt_ind->ReceivedRate;
+ unifi_trace(priv, UDBG2, "indicate_rx_skb: cmanrTestModeTransmitRate=%d\n", priv->cmanrTestModeTransmitRate);
+ }
+
/* Pass SKB up the stack */
#ifdef CSR_WIFI_USE_NETIF_RX
netif_rx(skb);
if((dataFrameType == QOS_DATA) || (dataFrameType == QOS_DATA_NULL)){
/*
- QoS control field is offset from frame control by 2 (frame control)
- + 2 (duration/ID) + 2 (sequence control) + 3*ETH_ALEN or 4*ETH_ALEN
- */
+ * QoS control field is offset from frame control by 2 (frame control)
+ * + 2 (duration/ID) + 2 (sequence control) + 3*ETH_ALEN or 4*ETH_ALEN
+ */
if((frameControl & IEEE802_11_FC_TO_DS_MASK) && (frameControl & IEEE802_11_FC_FROM_DS_MASK)){
qosControl= CSR_GET_UINT16_FROM_LITTLE_ENDIAN(pData->os_data_ptr + 30);
}
else{
qosControl = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(pData->os_data_ptr + 24);
}
-
- if((IS_DTIM_ACTIVE(interfacePriv->dtimActive,interfacePriv->multicastPduHostTag))){
- CSR_PRIORITY priority;
- unifi_TrafficQueue priority_q;
- priority = (CSR_PRIORITY)(qosControl & IEEE802_11_QC_TID_MASK);
- priority_q = unifi_frame_priority_to_queue((CSR_PRIORITY) priority);
- if((srcStaInfo->powersaveMode[priority_q]==CSR_WIFI_AC_TRIGGER_ONLY_ENABLED)
- ||(srcStaInfo->powersaveMode[priority_q]==CSR_WIFI_AC_TRIGGER_AND_DELIVERY_ENABLED)){
- unsigned long lock_flags;
- spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
- srcStaInfo->uapsdSuspended = TRUE;
- spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
- unifi_trace(priv, UDBG3, "%s: qos Trigger Frame received while DTIM Active for staid: 0x%x\n",__FUNCTION__,srcStaInfo->aid);
- }
- }
- else{
-
-
- unifi_trace(priv, UDBG5, "%s: Check if U-APSD operations are triggered for qosControl: 0x%x\n",__FUNCTION__,qosControl);
- uf_process_wmm_deliver_ac_uapsd(priv,srcStaInfo,qosControl,interfaceTag);
- }
+ unifi_trace(priv, UDBG5, "%s: Check if U-APSD operations are triggered for qosControl: 0x%x\n",__FUNCTION__,qosControl);
+ uf_process_wmm_deliver_ac_uapsd(priv,srcStaInfo,qosControl,interfaceTag);
}
}
}
ba_addr = bssid;
}
- spin_lock(&priv->ba_lock);
+ down(&priv->ba_mutex);
for (ba_session_idx=0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_RX; ba_session_idx++){
ba_session = interfacePriv->ba_session_rx[ba_session_idx];
if (ba_session){
frame_desc.active = TRUE;
unifi_trace(priv, UDBG6, "%s: calling process_ba_frame (session=%d)\n", __FUNCTION__, ba_session_idx);
process_ba_frame(priv, interfacePriv, ba_session, &frame_desc);
- spin_unlock(&priv->ba_lock);
+ up(&priv->ba_mutex);
process_ba_complete(priv, interfacePriv);
break;
}
}
}
if (ba_session_idx == MAX_SUPPORTED_BA_SESSIONS_RX){
- spin_unlock(&priv->ba_lock);
+ up(&priv->ba_mutex);
unifi_trace(priv, UDBG6, "%s: calling process_amsdu()", __FUNCTION__);
process_amsdu(priv, signal, bulkdata);
}
* And also this code here takes care that timeout check is made for all
* the receive indications
*/
- spin_lock(&priv->ba_lock);
+ down(&priv->ba_mutex);
for (i=0; i < MAX_SUPPORTED_BA_SESSIONS_RX; i++){
ba_session_rx_struct *ba_session;
ba_session = interfacePriv->ba_session_rx[i];
check_ba_frame_age_timeout(priv, interfacePriv, ba_session);
}
}
+ up(&priv->ba_mutex);
process_ba_complete(priv, interfacePriv);
- spin_unlock(&priv->ba_lock);
func_exit();
}
}
sn = pkt_err_ind->SequenceNumber;
- spin_lock(&priv->ba_lock);
+ down(&priv->ba_mutex);
/* To find the right ba_session loop through the BA sessions, compare MAC address and tID */
for (ba_session_idx=0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_RX; ba_session_idx++){
ba_session = interfacePriv->ba_session_rx[ba_session_idx];
}
}
- spin_unlock(&priv->ba_lock);
+ up(&priv->ba_mutex);
process_ba_complete(priv, interfacePriv);
func_exit();
}
(_s)[DEBUG_BUFFER_SIZE - 1] = 0; \
} \
} while (0)
-#endif /* UNIFI_DEBUG */
void
unifi_error(void* ospriv, const char *fmt, ...)
{
-#ifdef UNIFI_DEBUG
unifi_priv_t *priv = (unifi_priv_t*) ospriv;
char s[DEBUG_BUFFER_SIZE];
va_list args;
FORMAT_TRACE(s, len, args, fmt);
printk("%s", s);
-#endif /* UNIFI_DEBUG */
}
void
unifi_warning(void* ospriv, const char *fmt, ...)
{
-#ifdef UNIFI_DEBUG
unifi_priv_t *priv = (unifi_priv_t*) ospriv;
char s[DEBUG_BUFFER_SIZE];
va_list args;
FORMAT_TRACE(s, len, args, fmt);
printk("%s", s);
-#endif /* UNIFI_DEBUG */
}
void
unifi_notice(void* ospriv, const char *fmt, ...)
{
-#ifdef UNIFI_DEBUG
unifi_priv_t *priv = (unifi_priv_t*) ospriv;
char s[DEBUG_BUFFER_SIZE];
va_list args;
FORMAT_TRACE(s, len, args, fmt);
printk("%s", s);
-#endif /* UNIFI_DEBUG */
}
void
unifi_info(void* ospriv, const char *fmt, ...)
{
-#ifdef UNIFI_DEBUG
unifi_priv_t *priv = (unifi_priv_t*) ospriv;
char s[DEBUG_BUFFER_SIZE];
va_list args;
FORMAT_TRACE(s, len, args, fmt);
printk("%s", s);
-#endif /* UNIFI_DEBUG */
}
/* debugging */
void
unifi_trace(void* ospriv, int level, const char *fmt, ...)
{
-#ifdef UNIFI_DEBUG
unifi_priv_t *priv = (unifi_priv_t*) ospriv;
char s[DEBUG_BUFFER_SIZE];
va_list args;
printk("%s", s);
}
-#endif /* UNIFI_DEBUG */
}
+#else
+
+void
+unifi_error_nop(void* ospriv, const char *fmt, ...)
+{
+}
+
+void
+unifi_trace_nop(void* ospriv, int level, const char *fmt, ...)
+{
+}
+
+#endif /* UNIFI_DEBUG */
+
+
/*
* ---------------------------------------------------------------------------
*
"unifi_putest_gp_read16: Failed to get the params\n");
return -EFAULT;
}
-
+ CsrSdioClaim(priv->sdio);
csrResult = unifi_card_read16(priv->card, gp_r16_params.addr, &gp_r16_params.data);
+ CsrSdioRelease(priv->sdio);
if (csrResult != CSR_RESULT_SUCCESS) {
unifi_error(priv,
"unifi_putest_gp_read16: unifi_card_read16() GP=0x%x failed (csrResult=0x%x)\n", gp_r16_params.addr, csrResult);
}
unifi_trace(priv, UDBG2, "gp_w16: GP=0x%08x, data=0x%04x\n", gp_w16_params.addr, gp_w16_params.data);
-
+ CsrSdioClaim(priv->sdio);
csrResult = unifi_card_write16(priv->card, gp_w16_params.addr, gp_w16_params.data);
+ CsrSdioRelease(priv->sdio);
if (csrResult != CSR_RESULT_SUCCESS) {
unifi_error(priv,
"unifi_putest_gp_write16: unifi_card_write16() GP=%x failed (csrResult=0x%x)\n", gp_w16_params.addr, csrResult);
unifi_trace(priv, UDBG2, "set sdio clock: %d KHz\n", sdio_clock_speed);
CsrSdioClaim(priv->sdio);
- csrResult = CsrSdioMaxBusClockFrequencySet(priv->sdio, sdio_clock_speed);
+ csrResult = CsrSdioMaxBusClockFrequencySet(priv->sdio, sdio_clock_speed * 1000);
CsrSdioRelease(priv->sdio);
if (csrResult != CSR_RESULT_SUCCESS) {
unifi_error(priv,
/* Application may have stopped the XAPs, but they are needed for reset */
if (already_in_test) {
+ CsrSdioClaim(priv->sdio);
csrResult = unifi_start_processors(priv->card);
+ CsrSdioRelease(priv->sdio);
if (csrResult != CSR_RESULT_SUCCESS) {
unifi_error(priv, "Failed to start XAPs. Hard reset required.\n");
}
unifi_error(priv, "CsrSdioPowerOn csrResult = %d\n", csrResult);
}
}
-
+ CsrSdioClaim(priv->sdio);
csrResult = unifi_init(priv->card);
+ CsrSdioRelease(priv->sdio);
if (csrResult != CSR_RESULT_SUCCESS) {
unifi_error(priv,
"unifi_putest_start: failed to init UniFi\n");
CsrResult csrResult;
/* Application may have stopped the XAPs, but they are needed for reset */
+ CsrSdioClaim(priv->sdio);
csrResult = unifi_start_processors(priv->card);
+ CsrSdioRelease(priv->sdio);
if (csrResult != CSR_RESULT_SUCCESS) {
unifi_error(priv, "Failed to start XAPs. Hard reset required.\n");
}
}
/* Application may have stopped the XAPs, but they are needed for reset */
+ CsrSdioClaim(priv->sdio);
csrResult = unifi_start_processors(priv->card);
+ CsrSdioRelease(priv->sdio);
if (csrResult != CSR_RESULT_SUCCESS) {
unifi_error(priv, "Failed to start XAPs. Hard reset required.\n");
}
/* Download the f/w. On UF6xxx this will cause the f/w file to convert
* into patch format and download via the ROM boot loader
*/
+ CsrSdioClaim(priv->sdio);
csrResult = unifi_download(priv->card, 0x0c00);
+ CsrSdioRelease(priv->sdio);
if (csrResult != CSR_RESULT_SUCCESS) {
unifi_error(priv,
"unifi_putest_dl_fw: failed to download the f/w\n");
priv->fw_sta.dl_len = fw_length;
/* Application may have stopped the XAPs, but they are needed for reset */
+ CsrSdioClaim(priv->sdio);
csrResult = unifi_start_processors(priv->card);
+ CsrSdioRelease(priv->sdio);
if (csrResult != CSR_RESULT_SUCCESS) {
unifi_error(priv, "Failed to start XAPs. Hard reset required.\n");
}
/* Download the f/w. On UF6xxx this will cause the f/w file to convert
* into patch format and download via the ROM boot loader
*/
+ CsrSdioClaim(priv->sdio);
csrResult = unifi_download(priv->card, 0x0c00);
+ CsrSdioRelease(priv->sdio);
if (csrResult != CSR_RESULT_SUCCESS) {
unifi_error(priv,
"unifi_putest_dl_fw_buff: failed to download the f/w\n");
}
/* Card software reset */
+ CsrSdioClaim(priv->sdio);
r = unifi_card_hard_reset(priv->card);
+ CsrSdioRelease(priv->sdio);
if (r != CSR_RESULT_SUCCESS) {
unifi_error(priv, "unifi_card_hard_reset() failed %d\n", r);
}
/* Stop the XAPs for coredump. The PUTEST_STOP must be called, e.g. at
* Raw SDIO deinit, to resume them.
*/
+ CsrSdioClaim(priv->sdio);
r = unifi_card_stop_processor(priv->card, UNIFI_PROC_BOTH);
+ CsrSdioRelease(priv->sdio);
if (r != CSR_RESULT_SUCCESS) {
unifi_error(priv, "Failed to stop processors\n");
}
return -ENOMEM;
}
+ CsrSdioClaim(priv->sdio);
r = unifi_card_readn(priv->card, block_cmd52.addr, block_local_buffer, block_cmd52.length);
+ CsrSdioRelease(priv->sdio);
if (r != CSR_RESULT_SUCCESS) {
unifi_error(priv, "cmd52r_block: unifi_readn failed\n");
return -EIO;
*/
#include <linux/kmod.h>
#include <linux/init.h>
+#include <linux/suspend.h>
#include "csr_wifi_hip_unifi.h"
#include "unifi_priv.h"
/* The function driver context, i.e the UniFi Driver */
static CsrSdioFunctionDriver *sdio_func_drv;
+#ifdef CONFIG_PM
+static int uf_sdio_emb_power_event(struct notifier_block *this, unsigned long event, void *ptr);
+#endif
+/* The Android wakelock is here for completeness. Typically the MMC driver is used
+ * instead of sdioemb, but sdioemb may be used for CSPI.
+ */
+#ifdef ANDROID_BUILD
+struct wake_lock unifi_sdio_wake_lock; /* wakelock to prevent suspend while resuming */
+#endif
/* sdioemb driver uses POSIX error codes */
static CsrResult
}
}
+#ifdef CONFIG_PM
+
+/*
+ * Power Management notifier
+ */
+struct uf_sdio_emb_pm_notifier
+{
+ struct list_head list;
+
+ CsrSdioFunction *sdio_ctx;
+ struct notifier_block pm_notifier;
+};
+
+/* PM notifier list head */
+static struct uf_sdio_emb_pm_notifier uf_sdio_emb_pm_notifiers = {
+ .sdio_ctx = NULL,
+};
+
+/*
+ * ---------------------------------------------------------------------------
+ * uf_sdio_emb_register_pm_notifier
+ * uf_sdio_emb_unregister_pm_notifier
+ *
+ * Register/unregister for power management events. A list is used to
+ * allow multiple card instances to be supported.
+ *
+ * Arguments:
+ * sdio_ctx - CSR SDIO context to associate PM notifier to
+ *
+ * Returns:
+ * Register function returns NULL on error
+ * ---------------------------------------------------------------------------
+ */
+static struct uf_sdio_emb_pm_notifier *
+uf_sdio_emb_register_pm_notifier(CsrSdioFunction *sdio_ctx)
+{
+ /* Allocate notifier context for this card instance */
+ struct uf_sdio_emb_pm_notifier *notifier_ctx = kmalloc(sizeof(struct uf_sdio_emb_pm_notifier), GFP_KERNEL);
+
+ if (notifier_ctx)
+ {
+ notifier_ctx->sdio_ctx = sdio_ctx;
+ notifier_ctx->pm_notifier.notifier_call = uf_sdio_emb_power_event;
+
+ list_add(¬ifier_ctx->list, &uf_sdio_emb_pm_notifiers.list);
+
+ if (register_pm_notifier(¬ifier_ctx->pm_notifier)) {
+ printk(KERN_ERR "unifi: register_pm_notifier failed\n");
+ }
+ }
+
+ return notifier_ctx;
+}
+
+static void
+uf_sdio_emb_unregister_pm_notifier(CsrSdioFunction *sdio_ctx)
+{
+ struct uf_sdio_emb_pm_notifier *notifier_ctx;
+ struct list_head *node, *q;
+
+ list_for_each_safe(node, q, &uf_sdio_emb_pm_notifiers.list) {
+ notifier_ctx = list_entry(node, struct uf_sdio_emb_pm_notifier, list);
+
+ /* If it matches, unregister and free the notifier context */
+ if (notifier_ctx && notifier_ctx->sdio_ctx == sdio_ctx)
+ {
+ if (unregister_pm_notifier(¬ifier_ctx->pm_notifier)) {
+ printk(KERN_ERR "unifi: unregister_pm_notifier failed\n");
+ }
+
+ /* Remove from list */
+ notifier_ctx->sdio_ctx = NULL;
+ list_del(node);
+ kfree(notifier_ctx);
+ }
+ }
+}
+
+/*
+ * ---------------------------------------------------------------------------
+ * uf_sdio_emb_power_event
+ *
+ * Handler for power management events.
+ *
+ * We need to handle suspend/resume events while the userspace is unsuspended
+ * to allow the SME to run its suspend/resume state machines.
+ *
+ * Arguments:
+ * event event ID
+ *
+ * Returns:
+ * Status of the event handling
+ * ---------------------------------------------------------------------------
+ */
+static int
+uf_sdio_emb_power_event(struct notifier_block *this, unsigned long event, void *ptr)
+{
+ struct uf_sdio_emb_pm_notifier *notifier_ctx = container_of(this,
+ struct uf_sdio_emb_pm_notifier,
+ pm_notifier);
+
+ /* Call the CSR SDIO function driver's suspend/resume method
+ * while the userspace is unsuspended.
+ */
+ switch (event) {
+ case PM_POST_HIBERNATION:
+ case PM_POST_SUSPEND:
+ printk(KERN_INFO "%s:%d resume\n", __FUNCTION__, __LINE__ );
+ if (sdio_func_drv && sdio_func_drv->resume) {
+ sdio_func_drv->resume(notifier_ctx->sdio_ctx);
+ }
+ break;
+
+ case PM_HIBERNATION_PREPARE:
+ case PM_SUSPEND_PREPARE:
+ printk(KERN_INFO "%s:%d suspend\n", __FUNCTION__, __LINE__ );
+ if (sdio_func_drv && sdio_func_drv->suspend) {
+ sdio_func_drv->suspend(notifier_ctx->sdio_ctx);
+ }
+ break;
+ }
+ return NOTIFY_DONE;
+}
+
+#endif /* CONFIG_PM */
/*
* ---------------------------------------------------------------------------
unifi_trace(NULL, UDBG1, "Setting SDIO bus clock to %d kHz\n", sdio_clock);
sdioemb_set_max_bus_freq(fdev, 1000 * sdio_clock);
+#ifdef CONFIG_PM
+ /* Register to get PM events */
+ if (uf_sdio_emb_register_pm_notifier(sdio_ctx) == NULL) {
+ unifi_error(NULL, "%s: Failed to register for PM events\n", __FUNCTION__);
+ }
+#endif
+
/* Call the main UniFi driver inserted handler */
if (sdio_func_drv && sdio_func_drv->inserted) {
uf_add_os_device(fdev->slot_id, fdev->os_device);
sdio_func_drv->inserted(sdio_ctx);
}
+#ifdef ANDROID_BUILD
+ /* Take the wakelock */
+ unifi_trace(NULL, UDBG1, "emb probe: take wake lock\n");
+ wake_lock(&unifi_sdio_wake_lock);
+#endif
+
return 0;
} /* uf_glue_sdio_probe() */
+
/*
* ---------------------------------------------------------------------------
* uf_sdio_remove
sdio_func_drv->removed(sdio_ctx);
}
+#ifdef CONFIG_PM
+ /* Unregister for PM events */
+ uf_sdio_emb_unregister_pm_notifier(sdio_ctx);
+#endif
+
kfree(sdio_ctx);
} /* uf_sdio_remove */
static void
uf_glue_sdio_suspend(struct sdioemb_dev *fdev)
{
- CsrSdioFunction *sdio_ctx = fdev->drv_data;
-
- unifi_trace(NULL, UDBG3, "Suspending...\n");
-
- /* Pass event to UniFi Driver. */
- if (sdio_func_drv && sdio_func_drv->suspend) {
- sdio_func_drv->suspend(sdio_ctx);
- }
+ unifi_info(NULL, "Suspending...\n");
} /* uf_glue_sdio_suspend() */
static void
uf_glue_sdio_resume(struct sdioemb_dev *fdev)
{
- CsrSdioFunction *sdio_ctx = fdev->drv_data;
+ unifi_info(NULL, "Resuming...\n");
- unifi_trace(NULL, UDBG3, "Resuming...\n");
+#ifdef ANDROID_BUILD
+ unifi_trace(NULL, UDBG1, "emb resume: take wakelock\n");
+ wake_lock(&unifi_sdio_wake_lock);
+#endif
- /* Pass event to UniFi Driver. */
- if (sdio_func_drv && sdio_func_drv->resume) {
- sdio_func_drv->resume(sdio_ctx);
- }
} /* uf_glue_sdio_resume() */
/* Save the registered driver description */
sdio_func_drv = sdio_drv;
+#ifdef CONFIG_PM
+ /* Initialise PM notifier list */
+ INIT_LIST_HEAD(&uf_sdio_emb_pm_notifiers.list);
+#endif
+
+#ifdef ANDROID_BUILD
+ wake_lock_init(&unifi_sdio_wake_lock, WAKE_LOCK_SUSPEND, "unifi_sdio_work");
+#endif
+
/* Register ourself with sdioemb */
r = sdioemb_driver_register(&unifi_sdioemb);
if (r) {
{
sdioemb_driver_unregister(&unifi_sdioemb);
+#ifdef ANDROID_BUILD
+ wake_lock_destroy(&unifi_sdio_wake_lock);
+#endif
+
sdio_func_drv = NULL;
CsrPmemFree(unifi_sdioemb.id_table);
unifi_priv_t *priv = ospriv;
int interfaceTag=0;
+ /* For powered suspend, tell the resume's wifi_on() not to reinit UniFi */
+ priv->wol_suspend = (enable_wol == UNIFI_WOL_OFF) ? FALSE : TRUE;
+
+ unifi_trace(priv, UDBG1, "unifi_suspend: wol_suspend %d, enable_wol %d",
+ priv->wol_suspend, enable_wol );
+
/* Stop network traffic. */
/* need to stop all the netdevices*/
for( interfaceTag=0;interfaceTag<CSR_WIFI_NUM_INTERFACES;interfaceTag++)
netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
if (interfacePriv->netdev_registered == 1)
{
- netif_carrier_off(priv->netdev[interfaceTag]);
+ if( priv->wol_suspend ) {
+ unifi_trace(priv, UDBG1, "unifi_suspend: Don't netif_carrier_off");
+ } else {
+ unifi_trace(priv, UDBG1, "unifi_suspend: netif_carrier_off");
+ netif_carrier_off(priv->netdev[interfaceTag]);
+ }
UF_NETIF_TX_STOP_ALL_QUEUES(priv->netdev[interfaceTag]);
}
}
+
+ unifi_trace(priv, UDBG1, "unifi_suspend: suspend SME");
+
sme_sys_suspend(priv);
+
} /* unifi_suspend() */
void unifi_resume(void *ospriv)
{
unifi_priv_t *priv = ospriv;
+ int interfaceTag=0;
int r;
+ int wol = priv->wol_suspend;
+
+ unifi_trace(priv, UDBG1, "unifi_resume: resume SME, enable_wol=%d", enable_wol);
+ /* The resume causes wifi-on which will re-enable the BH and reinstall the ISR */
r = sme_sys_resume(priv);
if (r) {
unifi_error(priv, "Failed to resume UniFi\n");
}
+ /* Resume the network interfaces. For the cold resume case, this will
+ * happen upon reconnection.
+ */
+ if (wol) {
+ unifi_trace(priv, UDBG1, "unifi_resume: try to enable carrier");
+
+ /* need to start all the netdevices*/
+ for( interfaceTag=0;interfaceTag<CSR_WIFI_NUM_INTERFACES;interfaceTag++) {
+ netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
+
+ unifi_trace(priv, UDBG1, "unifi_resume: interfaceTag %d netdev_registered %d mode %d\n",
+ interfaceTag, interfacePriv->netdev_registered, interfacePriv->interfaceMode);
+
+ if (interfacePriv->netdev_registered == 1)
+ {
+ netif_carrier_on(priv->netdev[interfaceTag]);
+ UF_NETIF_TX_START_ALL_QUEUES(priv->netdev[interfaceTag]);
+ }
+ }
+
+ /* Kick the BH thread (with reason=host) to poll for data that may have
+ * arrived during a powered suspend. This caters for the case where the SME
+ * doesn't interact with the chip (e.g install autonomous scans) during resume.
+ */
+ unifi_send_signal(priv->card, NULL, 0, NULL);
+ }
+
} /* unifi_resume() */
#include <linux/mmc/sdio_func.h>
#include <linux/mmc/sdio_ids.h>
#include <linux/mmc/sdio.h>
+#include <linux/suspend.h>
#include "unifi_priv.h"
+#ifdef ANDROID_BUILD
+struct wake_lock unifi_sdio_wake_lock; /* wakelock to prevent suspend while resuming */
+#endif
static CsrSdioFunctionDriver *sdio_func_drv;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)
+#ifdef CONFIG_PM
+static int uf_sdio_mmc_power_event(struct notifier_block *this, unsigned long event, void *ptr);
+#endif
+
/*
* We need to keep track of the power on/off because we can not call
* mmc_power_restore_host() when the card is already powered.
* Even then, we need to patch the MMC driver to add a power_restore handler
- * in the mmc_sdio_ops structure. If the MMC driver is not patched,
- * mmc_power_save_host() and mmc_power_restore_host() are no-ops.
+ * in the mmc_sdio_ops structure. If the MMC driver before 2.6.37 is not patched,
+ * mmc_power_save_host() and mmc_power_restore_host() are no-ops in the kernel,
+ * returning immediately (at least on x86).
*/
static int card_is_powered = 1;
#endif /* 2.6.32 */
int ret;
u8 speed;
- if (!(card->host->caps & MMC_CAP_SD_HIGHSPEED))
+ if (!(card->host->caps & MMC_CAP_SD_HIGHSPEED)) {
+ /* We've asked for HS clock rates, but controller doesn't
+ * claim to support it. We should limit the clock
+ * to 25MHz via module parameter.
+ */
+ printk(KERN_INFO "unifi: request HS but not MMC_CAP_SD_HIGHSPEED");
return 0;
+ }
if (!card->cccr.high_speed)
return 0;
+#if 1
ret = csr_io_rw_direct(card, 0, 0, SDIO_CCCR_SPEED, 0, &speed);
if (ret)
return ret;
speed |= SDIO_SPEED_EHS;
+#else
+ /* Optimisation: Eliminate read by always assuming SHS and that reserved bits can be zero */
+ speed = SDIO_SPEED_EHS | SDIO_SPEED_SHS;
+#endif
ret = csr_io_rw_direct(card, 1, 0, SDIO_CCCR_SPEED, speed, NULL);
if (ret)
if (!card->cccr.high_speed)
return 0;
-
+#if 1
ret = csr_io_rw_direct(card, 0, 0, SDIO_CCCR_SPEED, 0, &speed);
if (ret)
return ret;
speed &= ~SDIO_SPEED_EHS;
+#else
+ /* Optimisation: Eliminate read by always assuming SHS and that reserved bits can be zero */
+ speed = SDIO_SPEED_SHS; /* clear SDIO_SPEED_EHS */
+#endif
ret = csr_io_rw_direct(card, 1, 0, SDIO_CCCR_SPEED, speed, NULL);
if (ret)
func_exit();
if (err) {
+ printk(KERN_ERR "unifi: %s: error %d writing IENx\n", __FUNCTION__, err);
return ConvertSdioToCsrSdioResult(err);
}
#endif
func_exit();
if (err) {
+ printk(KERN_ERR "unifi: %s: error %d writing IENx\n", __FUNCTION__, err);
return ConvertSdioToCsrSdioResult(err);
}
#endif
if (!sdio_ctx) {
return;
}
+
#ifndef CSR_CONFIG_MMC_INT_BYPASS_KSOFTIRQD
/*
* Normally, we are not allowed to do any SDIO commands here.
r = csr_io_rw_direct(func->card, 1, 0, SDIO_CCCR_IENx, 0x00, NULL);
#endif
if (r) {
- printk(KERN_ERR "UniFi MMC Int handler: Failed to disable interrupts\n");
+ printk(KERN_ERR "UniFi MMC Int handler: Failed to disable interrupts %d\n", r);
}
#endif
struct sdio_func *func = (struct sdio_func *)function->priv;
int r;
+ unifi_trace(NULL, UDBG1, "csr_sdio_linux_remove_irq\n");
+
sdio_claim_host(func);
r = sdio_release_irq(func);
sdio_release_host(func);
struct sdio_func *func = (struct sdio_func *)function->priv;
int r;
+ unifi_trace(NULL, UDBG1, "csr_sdio_linux_install_irq\n");
+
/* Register our interrupt handle */
sdio_claim_host(func);
r = sdio_claim_irq(func, uf_glue_sdio_int_handler);
return r;
} /* csr_sdio_linux_install_irq() */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)
+#ifdef CONFIG_PM
+
+/*
+ * Power Management notifier
+ */
+struct uf_sdio_mmc_pm_notifier
+{
+ struct list_head list;
+
+ CsrSdioFunction *sdio_ctx;
+ struct notifier_block pm_notifier;
+};
+
+/* PM notifier list head */
+static struct uf_sdio_mmc_pm_notifier uf_sdio_mmc_pm_notifiers = {
+ .sdio_ctx = NULL,
+};
+
+/*
+ * ---------------------------------------------------------------------------
+ * uf_sdio_mmc_register_pm_notifier
+ * uf_sdio_mmc_unregister_pm_notifier
+ *
+ * Register/unregister for power management events. A list is used to
+ * allow multiple card instances to be supported.
+ *
+ * Arguments:
+ * sdio_ctx - CSR SDIO context to associate PM notifier to
+ *
+ * Returns:
+ * Register function returns NULL on error
+ * ---------------------------------------------------------------------------
+ */
+static struct uf_sdio_mmc_pm_notifier *
+uf_sdio_mmc_register_pm_notifier(CsrSdioFunction *sdio_ctx)
+{
+ /* Allocate notifier context for this card instance */
+ struct uf_sdio_mmc_pm_notifier *notifier_ctx = kmalloc(sizeof(struct uf_sdio_mmc_pm_notifier), GFP_KERNEL);
+
+ if (notifier_ctx)
+ {
+ notifier_ctx->sdio_ctx = sdio_ctx;
+ notifier_ctx->pm_notifier.notifier_call = uf_sdio_mmc_power_event;
+
+ list_add(¬ifier_ctx->list, &uf_sdio_mmc_pm_notifiers.list);
+
+ if (register_pm_notifier(¬ifier_ctx->pm_notifier)) {
+ printk(KERN_ERR "unifi: register_pm_notifier failed\n");
+ }
+ }
+
+ return notifier_ctx;
+}
+
+static void
+uf_sdio_mmc_unregister_pm_notifier(CsrSdioFunction *sdio_ctx)
+{
+ struct uf_sdio_mmc_pm_notifier *notifier_ctx;
+ struct list_head *node, *q;
+
+ list_for_each_safe(node, q, &uf_sdio_mmc_pm_notifiers.list) {
+ notifier_ctx = list_entry(node, struct uf_sdio_mmc_pm_notifier, list);
+
+ /* If it matches, unregister and free the notifier context */
+ if (notifier_ctx && notifier_ctx->sdio_ctx == sdio_ctx)
+ {
+ if (unregister_pm_notifier(¬ifier_ctx->pm_notifier)) {
+ printk(KERN_ERR "unifi: unregister_pm_notifier failed\n");
+ }
+
+ /* Remove from list */
+ notifier_ctx->sdio_ctx = NULL;
+ list_del(node);
+ kfree(notifier_ctx);
+ }
+ }
+}
+
+/*
+ * ---------------------------------------------------------------------------
+ * uf_sdio_mmc_power_event
+ *
+ * Handler for power management events.
+ *
+ * We need to handle suspend/resume events while the userspace is unsuspended
+ * to allow the SME to run its suspend/resume state machines.
+ *
+ * Arguments:
+ * event event ID
+ *
+ * Returns:
+ * Status of the event handling
+ * ---------------------------------------------------------------------------
+ */
+static int
+uf_sdio_mmc_power_event(struct notifier_block *this, unsigned long event, void *ptr)
+{
+ struct uf_sdio_mmc_pm_notifier *notifier_ctx = container_of(this,
+ struct uf_sdio_mmc_pm_notifier,
+ pm_notifier);
+
+ /* Call the CSR SDIO function driver's suspend/resume method
+ * while the userspace is unsuspended.
+ */
+ switch (event) {
+ case PM_POST_HIBERNATION:
+ case PM_POST_SUSPEND:
+ printk(KERN_INFO "%s:%d resume\n", __FUNCTION__, __LINE__ );
+ if (sdio_func_drv && sdio_func_drv->resume) {
+ sdio_func_drv->resume(notifier_ctx->sdio_ctx);
+ }
+ break;
+
+ case PM_HIBERNATION_PREPARE:
+ case PM_SUSPEND_PREPARE:
+ printk(KERN_INFO "%s:%d suspend\n", __FUNCTION__, __LINE__ );
+ if (sdio_func_drv && sdio_func_drv->suspend) {
+ sdio_func_drv->suspend(notifier_ctx->sdio_ctx);
+ }
+ break;
+ }
+ return NOTIFY_DONE;
+}
+#endif /* CONFIG_PM */
+#endif /* 2.6.32 */
/*
* ---------------------------------------------------------------------------
sdio_ctx->features |= CSR_SDIO_FEATURE_BYTE_MODE;
}
+ if (func->card->host->caps & MMC_CAP_SD_HIGHSPEED) {
+ unifi_trace(NULL, UDBG1, "MMC_CAP_SD_HIGHSPEED is available\n");
+ }
+
#ifdef MMC_QUIRK_LENIENT_FN0
func->card->quirks |= MMC_QUIRK_LENIENT_FN0;
#endif
/* Pass context to the SDIO driver */
sdio_set_drvdata(func, sdio_ctx);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)
+#ifdef CONFIG_PM
+ /* Register to get PM events */
+ if (uf_sdio_mmc_register_pm_notifier(sdio_ctx) == NULL) {
+ unifi_error(NULL, "%s: Failed to register for PM events\n", __FUNCTION__);
+ }
+#endif
+#endif
+
/* Register this device with the SDIO function driver */
/* Call the main UniFi driver inserted handler */
if (sdio_func_drv && sdio_func_drv->inserted) {
/* We have finished, so release the SDIO driver */
sdio_release_host(func);
+#ifdef ANDROID_BUILD
+ /* Take the wakelock */
+ unifi_trace(NULL, UDBG1, "probe: take wake lock\n");
+ wake_lock(&unifi_sdio_wake_lock);
+#endif
+
func_exit();
return 0;
} /* uf_glue_sdio_probe() */
sdio_func_drv->removed(sdio_ctx);
}
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)
+#ifdef CONFIG_PM
+ /* Unregister for PM events */
+ uf_sdio_mmc_unregister_pm_notifier(sdio_ctx);
+#endif
+#endif
+
kfree(sdio_ctx);
func_exit();
* ---------------------------------------------------------------------------
* uf_glue_sdio_suspend
*
- * Card suspend callback.
+ * Card suspend callback. The userspace will already be suspended.
*
* Arguments:
* dev The struct device owned by the MMC driver
static int
uf_glue_sdio_suspend(struct device *dev)
{
- struct sdio_func *func;
- CsrSdioFunction *sdio_ctx;
-
func_enter();
- func = dev_to_sdio_func(dev);
- WARN_ON(!func);
-
- sdio_ctx = sdio_get_drvdata(func);
- WARN_ON(!sdio_ctx);
-
- unifi_trace(NULL, UDBG1, "System Suspend...\n");
-
- /* Clean up the SDIO function driver */
- if (sdio_func_drv && sdio_func_drv->suspend) {
- sdio_func_drv->suspend(sdio_ctx);
- }
+ unifi_trace(NULL, UDBG1, "uf_glue_sdio_suspend");
func_exit();
return 0;
* ---------------------------------------------------------------------------
* uf_glue_sdio_resume
*
- * Card resume callback.
+ * Card resume callback. The userspace will still be suspended.
*
* Arguments:
* dev The struct device owned by the MMC driver
static int
uf_glue_sdio_resume(struct device *dev)
{
- struct sdio_func *func;
- CsrSdioFunction *sdio_ctx;
-
func_enter();
- func = dev_to_sdio_func(dev);
- WARN_ON(!func);
-
- sdio_ctx = sdio_get_drvdata(func);
- WARN_ON(!sdio_ctx);
+ unifi_trace(NULL, UDBG1, "uf_glue_sdio_resume");
- unifi_trace(NULL, UDBG1, "System Resume...\n");
-
- /* Clean up the SDIO function driver */
- if (sdio_func_drv && sdio_func_drv->resume) {
- sdio_func_drv->resume(sdio_ctx);
- }
+#ifdef ANDROID_BUILD
+ unifi_trace(NULL, UDBG1, "resume: take wakelock\n");
+ wake_lock(&unifi_sdio_wake_lock);
+#endif
func_exit();
return 0;
return CSR_SDIO_RESULT_INVALID_VALUE;
}
+#ifdef ANDROID_BUILD
+ wake_lock_init(&unifi_sdio_wake_lock, WAKE_LOCK_SUSPEND, "unifi_sdio_work");
+#endif
+
/* Save the registered driver description */
/*
* FIXME:
*/
sdio_func_drv = sdio_drv;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)
+#ifdef CONFIG_PM
+ /* Initialise PM notifier list */
+ INIT_LIST_HEAD(&uf_sdio_mmc_pm_notifiers.list);
+#endif
+#endif
+
/* Register ourself with mmc_core */
r = sdio_register_driver(&unifi_driver);
if (r) {
CsrSdioFunctionDriverUnregister(CsrSdioFunctionDriver *sdio_drv)
{
printk(KERN_INFO "UniFi: unregister from MMC sdio\n");
+
+#ifdef ANDROID_BUILD
+ wake_lock_destroy(&unifi_sdio_wake_lock);
+#endif
sdio_unregister_driver(&unifi_driver);
sdio_func_drv = NULL;
return -EIO;
}
+ unifi_trace(priv, UDBG5, "sme_init_request: wait sem\n");
+
/* Grab the SME semaphore until the reply comes, or timeout */
if (down_interruptible(&priv->sme_sem)) {
unifi_error(priv, "sme_init_request: Failed to get SME semaphore\n");
return -EIO;
}
+ unifi_trace(priv, UDBG5, "sme_init_request: got sem: pending\n");
+
priv->sme_reply.request_status = SME_REQUEST_PENDING;
return 0;
(func ? func : ""), priv->sme_reply.request_status);
return;
}
+ unifi_trace(priv, UDBG5,
+ "sme_complete_request: completed %s (s:%d)\n",
+ (func ? func : ""), priv->sme_reply.request_status);
+
priv->sme_reply.request_status = SME_REQUEST_RECEIVED;
priv->sme_reply.reply_status = reply_status;
}
+void
+uf_sme_cancel_request(unifi_priv_t *priv, CsrResult reply_status)
+{
+ /* Check for a blocking SME request in progress, and cancel the wait.
+ * This should be used when the character device is closed.
+ */
+
+ if (priv == NULL) {
+ unifi_error(priv, "sme_cancel_request: Invalid priv\n");
+ return;
+ }
+
+ /* If no request is pending, nothing to wake up */
+ if (priv->sme_reply.request_status != SME_REQUEST_PENDING) {
+ unifi_trace(priv, UDBG5,
+ "sme_cancel_request: no request was pending (s:%d)\n",
+ priv->sme_reply.request_status);
+ /* Nothing to do */
+ return;
+ }
+ unifi_trace(priv, UDBG5,
+ "sme_cancel_request: request cancelled (s:%d)\n",
+ priv->sme_reply.request_status);
+
+ /* Wake up the wait with an error status */
+ priv->sme_reply.request_status = SME_REQUEST_CANCELLED;
+ priv->sme_reply.reply_status = reply_status; /* unimportant since the CANCELLED state will fail the ioctl */
+
+ wake_up_interruptible(&priv->sme_request_wq);
+
+ return;
+}
+
+
static int
_sme_wait_for_reply(unifi_priv_t *priv,
unsigned long timeout, const char *func)
{
long r;
- unifi_trace(priv, UDBG5, "sme_wait_for_reply: sleep\n");
+ unifi_trace(priv, UDBG5, "sme_wait_for_reply: %s sleep\n", func ? func : "");
r = wait_event_interruptible_timeout(priv->sme_request_wq,
(priv->sme_reply.request_status != SME_REQUEST_PENDING),
msecs_to_jiffies(timeout));
- unifi_trace(priv, UDBG5, "sme_wait_for_reply: awake\n");
+ unifi_trace(priv, UDBG5, "sme_wait_for_reply: %s awake (%d)\n", func ? func : "", r);
if (r == -ERESTARTSYS) {
/* The thread was killed */
+ unifi_info(priv, "ERESTARTSYS in _sme_wait_for_reply\n");
up(&priv->sme_sem);
return r;
}
+ if (priv->sme_reply.request_status == SME_REQUEST_CANCELLED) {
+ unifi_trace(priv, UDBG5, "Cancelled waiting for SME to reply (%s s:%d, t:%d, r:%d)\n",
+ (func ? func : ""), priv->sme_reply.request_status, timeout, r);
+
+ /* Release the SME semaphore that was downed in sme_init_request() */
+ up(&priv->sme_sem);
+ return -EIO; /* fail the ioctl */
+ }
if ((r == 0) && (priv->sme_reply.request_status != SME_REQUEST_RECEIVED)) {
unifi_notice(priv, "Timeout waiting for SME to reply (%s s:%d, t:%d)\n",
(func ? func : ""), priv->sme_reply.request_status, timeout);
return -ETIMEDOUT;
}
+ unifi_trace(priv, UDBG5, "sme_wait_for_reply: %s received (%d)\n",
+ func ? func : "", r);
+
/* Release the SME semaphore that was downed in sme_init_request() */
up(&priv->sme_sem);
return -EIO;
}
- /* For powered suspend, tell the resume's wifi_on() not to reinit UniFi */
- priv->wol_suspend = (enable_wol == UNIFI_WOL_OFF) ? FALSE : TRUE;
-
- /* Suspend the SME, which will cause it to power down UniFi */
+ /* Suspend the SME, which MAY cause it to power down UniFi */
CsrWifiRouterCtrlSuspendIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,0, 0, priv->wol_suspend);
r = sme_wait_for_reply(priv, UNIFI_SME_SYS_LONG_TIMEOUT);
if (r) {
/* No reply - forcibly power down in case the request wasn't processed */
unifi_notice(priv,
"suspend: SME did not reply %s, ",
- priv->ptest_mode ? "leave powered" : "power off UniFi anyway\n");
+ (priv->ptest_mode | priv->wol_suspend) ? "leave powered" : "power off UniFi anyway\n");
/* Leave power on for production test, though */
if (!priv->ptest_mode) {
/* Put UniFi to deep sleep, in case we can not power it off */
CsrSdioClaim(priv->sdio);
+ unifi_trace(priv, UDBG1, "Force deep sleep");
csrResult = unifi_force_low_power_mode(priv->card);
/* For WOL, the UniFi must stay powered */
if (priv->wol_suspend) {
unifi_trace(priv, UDBG1, "UniFi left powered for WOL\n");
- /* For PIO WOL, disable SDIO interrupt to enable PIO mode in the f/w */
- if (enable_wol == UNIFI_WOL_PIO) {
- unifi_trace(priv, UDBG1, "Remove IRQ to enable PIO WOL\n");
- if (csr_sdio_linux_remove_irq(priv->sdio)) {
- unifi_notice(priv, "WOL csr_sdio_linux_remove_irq failed\n");
+ /* Remove the IRQ, which also disables the card SDIO interrupt.
+ * Disabling the card SDIO interrupt enables the PIO WOL source.
+ * Removal of the of the handler ensures that in both SDIO and PIO cases
+ * the card interrupt only wakes the host. The card will be polled
+ * after resume to handle any pending data.
+ */
+ if (csr_sdio_linux_remove_irq(priv->sdio)) {
+ unifi_notice(priv, "WOL csr_sdio_linux_remove_irq failed\n");
+ }
+
+ if (enable_wol == UNIFI_WOL_SDIO) {
+ /* Because csr_sdio_linux_remove_irq() disabled the card SDIO interrupt,
+ * it must be left enabled to wake-on-SDIO.
+ */
+ unifi_trace(priv, UDBG1, "Enable card SDIO interrupt for SDIO WOL\n");
+
+ CsrSdioClaim(priv->sdio);
+ csrResult = CsrSdioInterruptEnable(priv->sdio);
+ CsrSdioRelease(priv->sdio);
+
+ if (csrResult != CSR_RESULT_SUCCESS) {
+ unifi_error(priv, "WOL CsrSdioInterruptEnable failed %d\n", csrResult);
}
+ } else {
+ unifi_trace(priv, UDBG1, "Disabled card SDIO interrupt for PIO WOL\n");
}
+
+ /* Prevent the BH thread from running during the suspend.
+ * Upon resume, sme_sys_resume() will trigger a wifi-on, this will cause
+ * the BH thread to be re-enabled and reinstall the ISR.
+ */
+ priv->bh_thread.block_thread = 1;
+
+ unifi_trace(priv, UDBG1, "unifi_suspend: suspended BH");
}
/* Consider UniFi to be uninitialised */
CsrWifiRouterCtrlResumeIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,0, priv->wol_suspend);
- if (priv->ptest_mode == 1) {
- r = sme_wait_for_reply(priv, UNIFI_SME_SYS_LONG_TIMEOUT);
- if (r) {
- /* No reply - forcibly power down in case the request wasn't processed */
- unifi_notice(priv,
- "resume: SME did not reply, return success anyway\n");
- }
- } else {
-
- /*
- * We are not going to wait for the reply because the SME might be in
- * the userspace. In this case the event will reach it when the kernel
- * resumes. So, release now the SME semaphore that was downed in
- * sme_init_request().
- */
- up(&priv->sme_sem);
+ r = sme_wait_for_reply(priv, UNIFI_SME_SYS_LONG_TIMEOUT);
+ if (r) {
+ unifi_notice(priv,
+ "resume: SME did not reply, return success anyway\n");
}
return 0;
#ifdef CSR_SUPPORT_WEXT_AP
#include "sme_csr/csr_wifi_sme_sef.h"
#endif
+
+
/*
* This file implements the SME SYS API and contains the following functions:
* CsrWifiRouterCtrlMediaStatusReqHandler()
* CsrWifiRouterCtrlTclasDelReqHandler()
* CsrWifiRouterCtrlSetModeReqHandler()
* CsrWifiRouterCtrlWapiMulticastFilterReqHandler()
- * CsrWifiRouterCtrlWapiMulticastReqHandler()
* CsrWifiRouterCtrlWapiUnicastFilterReqHandler()
+ * CsrWifiRouterCtrlWapiUnicastTxPktReqHandler()
+ * CsrWifiRouterCtrlWapiRxPktReqHandler()
+ * CsrWifiRouterCtrlWapiFilterReqHandler()
*/
#ifdef CSR_SUPPORT_SME
if (priv == NULL) {
return;
}
- for (i=0; i<CSR_WIFI_NUM_INTERFACES; i++) {
- priv->interfacePriv[i]->interfaceMode = 0;
+ if( priv->wol_suspend ) {
+ unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWifiOnReqHandler: Don't reset mode\n");
+ } else {
+#ifdef ANDROID_BUILD
+ /* Take the wakelock while Wi-Fi On is in progress */
+ unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWifiOnReqHandler: take wake lock\n");
+ wake_lock(&unifi_sdio_wake_lock);
+#endif
+ for (i=0; i<CSR_WIFI_NUM_INTERFACES; i++) {
+ unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWifiOnReqHandler: Setting interface %d to NONE\n", i );
+
+ priv->interfacePriv[i]->interfaceMode = 0;
+ }
+ }
+ unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWifiOnReqHandler(0x%.4X) req->dataLength=%d req->data=0x%x\n", msg->source, req->dataLength, req->data);
+
+ if(req->dataLength==3 && req->data && req->data[0]==0 && req->data[1]==1 && req->data[2]==1)
+ {
+ priv->cmanrTestMode = TRUE;
+ unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWifiOnReqHandler: cmanrTestMode=%d\n", priv->cmanrTestMode);
+ }
+ else
+ {
+ priv->cmanrTestMode = FALSE;
}
- unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWifiOnReqHandler(0x%.4X)\n", msg->source);
/*
* The request to initialise UniFi might come while UniFi is running.
/* Update the wifi_on state */
priv->wifi_on_state = wifi_on_in_progress;
- r = uf_request_firmware_files(priv, UNIFI_FW_STA);
- if (r) {
- unifi_error(priv, "CsrWifiRouterCtrlWifiOnReqHandler: Failed to get f/w\n");
- CsrWifiRouterCtrlWifiOnCfmSend(msg->source, req->clientData, CSR_RESULT_FAILURE);
- return;
+ /* If UniFi was unpowered, acquire the firmware for download to chip */
+ if (!priv->wol_suspend) {
+ r = uf_request_firmware_files(priv, UNIFI_FW_STA);
+ if (r) {
+ unifi_error(priv, "CsrWifiRouterCtrlWifiOnReqHandler: Failed to get f/w\n");
+ CsrWifiRouterCtrlWifiOnCfmSend(msg->source, req->clientData, CSR_RESULT_FAILURE);
+ return;
+ }
+ } else {
+ unifi_trace(priv, UDBG1, "Don't need firmware\n");
}
/* Power on UniFi (which may not necessarily have been off) */
int i;
CsrResult csrResult;
+
+ /* Already off? */
+ if (priv->wifi_on_state == wifi_on_unspecified) {
+ unifi_trace(priv, UDBG1, "wifi_off already\n");
+ return;
+ }
+
unifi_trace(priv, UDBG1, "wifi_off\n");
/* Destroy the Traffic Analysis Module */
cancel_work_sync(&priv->ta_sample_ind_work.task);
#ifdef CSR_SUPPORT_WEXT
cancel_work_sync(&priv->sme_config_task);
+ wext_send_disassoc_event(priv);
#endif
/* Cancel pending M4 stuff */
unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
CsrWifiRouterCtrlWifiOffReq* req = (CsrWifiRouterCtrlWifiOffReq*)msg;
int i = 0;
-#ifdef CSR_SUPPORT_WEXT_AP
- CsrWifiSmeWifiOffCfm cfm;
-#endif
if (priv == NULL) {
return;
if (interfacePriv->netdev_registered == 1) {
netif_carrier_off(priv->netdev[i]);
UF_NETIF_TX_STOP_ALL_QUEUES(priv->netdev[i]);
+ interfacePriv->connected = UnifiConnectedUnknown;
}
interfacePriv->interfaceMode = 0;
wifi_off(priv);
CsrWifiRouterCtrlWifiOffCfmSend(msg->source,req->clientData);
-#ifdef CSR_SUPPORT_WEXT_AP
- /* Router is turned off when WifiOffCfm is received
- * hence for wext we don't see WifiOffCfm in the wext
- * files. So just tell the waiting process that
- * Wifi off is successful
+
+ /* If this is called in response to closing the character device, the
+ * caller must use uf_sme_cancel_request() to terminate any pending SME
+ * blocking request or there will be a delay while the operation times out.
*/
- cfm.status = CSR_RESULT_SUCCESS;
- CsrWifiSmeWifiOffCfmHandler(priv,(CsrWifiFsmEvent*)(&cfm));
-#endif
}
{
int i; /* used as a loop counter */
CsrUint32 intmode = CSR_WIFI_INTMODE_DEFAULT;
-
+#ifdef CSR_WIFI_SPLIT_PATCH
+ CsrBool switching_ap_fw = FALSE;
+#endif
/* Register the UniFi device with the OS network manager */
unifi_trace(priv, UDBG3, "Card Init Completed Successfully\n");
return;
}
}
+#ifdef CSR_WIFI_SPLIT_PATCH
+ else
+ {
+ /* If a netdev is already registered, we have received this WifiOnRes
+ * in response to switching AP/STA firmware in a ModeSetReq.
+ * Rememeber this in order to send a ModeSetCfm once
+ */
+ switching_ap_fw = TRUE;
+ }
+#endif
}
priv->totalInterfaceCount = res->numInterfaceAddress;
/* Acknowledge the CsrWifiRouterCtrlWifiOnReq now */
CsrWifiRouterCtrlWifiOnCfmSend(msg->source, res->clientData, CSR_RESULT_SUCCESS);
+#ifdef CSR_WIFI_SPLIT_PATCH
+ if (switching_ap_fw && (priv->pending_mode_set.common.destination != 0xaaaa)) {
+ unifi_info(priv, "Completed firmware reload with %s patch\n",
+ CSR_WIFI_HIP_IS_AP_FW(priv->interfacePriv[0]->interfaceMode) ? "AP" : "STA");
+
+ /* Confirm the ModeSetReq that requested the AP/STA patch switch */
+ CsrWifiRouterCtrlModeSetCfmSend(priv->pending_mode_set.common.source,
+ priv->pending_mode_set.clientData,
+ priv->pending_mode_set.interfaceTag,
+ priv->pending_mode_set.mode,
+ CSR_RESULT_SUCCESS);
+ priv->pending_mode_set.common.destination = 0xaaaa;
+ }
+#endif
unifi_info(priv, "UniFi ready\n");
+#ifdef ANDROID_BUILD
+ /* Release the wakelock */
+ unifi_trace(priv, UDBG1, "ready: release wake lock\n");
+ wake_unlock(&unifi_sdio_wake_lock);
+#endif
/* Firmware initialisation is complete, so let the SDIO bus
* clock be raised when convienent to the core.
*/
return;
}
- /*
- * Unless we are in ptest mode, nothing is waiting for the response.
- * Do not call sme_complete_request(), otherwise the driver
- * and the SME will be out of step.
- */
- if (priv->ptest_mode == 1) {
- sme_complete_request(priv, res->status);
- }
-
+ sme_complete_request(priv, res->status);
}
&(interfacePriv->genericMulticastOrBroadCastFrames));
uf_flush_list(priv,&(interfacePriv->genericMulticastOrBroadCastFrames));
- uf_flush_maPktlist(priv,&(interfacePriv->directedMaPktReq));
/* process the list of frames that requested cfm
and send cfm to requestor one by one */
if (req->interfaceTag < CSR_WIFI_NUM_INTERFACES)
{
netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag];
-
+#ifdef CSR_WIFI_SPLIT_PATCH
+ CsrUint8 old_mode = interfacePriv->interfaceMode;
+#endif
unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlModeSetReqHandler: interfacePriv->interfaceMode = %d\n",
interfacePriv->interfaceMode);
- /* Cleanup the database first for current existing mode, Then take
- * care of setting the new mode (Transition seq: AnyMode->NoneMode->newMode)
- * So for Every mode changes, Database Initialization/cleanup needed
+ interfacePriv->interfaceMode = req->mode;
+
+#ifdef CSR_WIFI_SPLIT_PATCH
+ /* Detect a change in mode that requires a switch to/from the AP firmware patch.
+ * This should only happen when transitioning in/out of AP modes.
*/
- CsrWifiRouterCtrlInterfaceReset(priv,req->interfaceTag);
+ if (CSR_WIFI_HIP_IS_AP_FW(req->mode) != CSR_WIFI_HIP_IS_AP_FW(old_mode))
+ {
+ CsrWifiRouterCtrlVersions versions;
+ int r;
+
+#ifdef ANDROID_BUILD
+ /* Take the wakelock while switching patch */
+ unifi_trace(priv, UDBG1, "patch switch: take wake lock\n");
+ wake_lock(&unifi_sdio_wake_lock);
+#endif
+ unifi_info(priv, "Resetting UniFi with %s patch\n", CSR_WIFI_HIP_IS_AP_FW(req->mode) ? "AP" : "STA");
+
+ r = uf_request_firmware_files(priv, UNIFI_FW_STA);
+ if (r) {
+ unifi_error(priv, "CsrWifiRouterCtrlModeSetReqHandler: Failed to get f/w\n");
+ CsrWifiRouterCtrlModeSetCfmSend(msg->source, req->clientData, req->interfaceTag,
+ req->mode, CSR_RESULT_FAILURE);
+ return;
+ }
+
+ /* Block the I/O thread */
+ priv->bh_thread.block_thread = 1;
+
+ /* Reset and download the new patch */
+ r = uf_init_hw(priv);
+ if (r) {
+ unifi_error(priv, "CsrWifiRouterCtrlWifiOnReqHandler: Failed to initialise h/w, error %d\n", r);
+ CsrWifiRouterCtrlModeSetCfmSend(msg->source, req->clientData, req->interfaceTag,
+ req->mode, CSR_RESULT_FAILURE);
+ return;
+ }
+
+ /* Re-enable the I/O thread */
+ priv->bh_thread.block_thread = 0;
+
+ /* Get the version information from the core */
+ unifi_card_info(priv->card, &priv->card_info);
+
+ /* Copy to the unifiio_card_info structure. */
+ versions.chipId = priv->card_info.chip_id;
+ versions.chipVersion = priv->card_info.chip_version;
+ versions.firmwareBuild = priv->card_info.fw_build;
+ versions.firmwareHip = priv->card_info.fw_hip_version;
+ versions.routerBuild = (CsrCharString*)CSR_WIFI_VERSION;
+ versions.routerHip = (UNIFI_HIP_MAJOR_VERSION << 8) | UNIFI_HIP_MINOR_VERSION;
+
+ /* Now that new firmware is running, send a WifiOnInd to the NME. This will
+ * cause it to retransfer the MIB.
+ */
+ CsrWifiRouterCtrlWifiOnIndSend(msg->source, 0, CSR_RESULT_SUCCESS, versions);
+
+ /* Store the request so we know where to send the ModeSetCfm */
+ priv->pending_mode_set = *req;
+ }
+ else
+#endif
+ {
+ /* No patch switch, confirm straightaway */
+ CsrWifiRouterCtrlModeSetCfmSend(msg->source, req->clientData, req->interfaceTag,
+ req->mode, CSR_RESULT_SUCCESS);
+ }
- interfacePriv->interfaceMode = req->mode;
interfacePriv->bssid = req->bssid;
/* For modes other than AP/P2PGO, set below member FALSE */
interfacePriv->intraBssEnabled = FALSE;
-
+ /* Initialise the variable bcTimSet with a value
+ * other then CSR_WIFI_TIM_SET or CSR_WIFI_TIM_RESET value
+ */
+ interfacePriv->bcTimSet = 0xFF;
+ interfacePriv->bcTimSetReqPendingFlag = FALSE;
+ /* Initialise the variable bcTimSetReqQueued with a value
+ * other then CSR_WIFI_TIM_SET or CSR_WIFI_TIM_RESET value
+ */
+ interfacePriv->bcTimSetReqQueued =0xFF;
+ CsrWifiRouterCtrlInterfaceReset(priv,req->interfaceTag);
if(req->mode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
req->mode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
unifi_port_config_t *controlledPort;
unifi_port_config_t *unControlledPort;
netInterface_priv_t *interfacePriv;
- maPktReqList_t *maPktreq;
- struct list_head *listHeadMaPktreq,*placeHolderMaPktreq;
CsrUint8 ba_session_idx = 0;
ba_session_rx_struct *ba_session_rx = NULL;
uf_flush_list(priv,&(staInfo->dataPdu[j]));
}
- /* There may be race condition
- before getting the ma_packet_cfm from f/w, driver may receive peer del from SME
- */
- spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
- list_for_each_safe(listHeadMaPktreq, placeHolderMaPktreq, &interfacePriv->directedMaPktReq) {
- maPktreq = list_entry(listHeadMaPktreq, maPktReqList_t, q);
- if(maPktreq->staHandler== staInfo->assignedHandle){
- dev_kfree_skb(maPktreq->skb);
- list_del(listHeadMaPktreq);
- kfree(maPktreq);
- }
-
- }
- spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
-
spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
/* clear the port configure array info, for the corresponding peer entry */
controlledPort = &interfacePriv->controlled_data_port;
/* Stop BA session if it is active, for this peer address all BA sessions
(per tID per role) are closed */
- spin_lock(&priv->ba_lock);
+ down(&priv->ba_mutex);
for(ba_session_idx=0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_RX; ba_session_idx++){
ba_session_rx = priv->interfacePriv[req->interfaceTag]->ba_session_rx[ba_session_idx];
if(ba_session_rx) {
}
}
- spin_unlock(&priv->ba_lock);
+ up(&priv->ba_mutex);
#ifdef CSR_SUPPORT_SME
unifi_trace(priv, UDBG1, "Canceling work queue for STA with AID: %d\n", staInfo->aid);
newRecord->txSuspend = FALSE;
/*U-APSD related data structure*/
+ newRecord->timRequestPendingFlag = FALSE;
+
+ /* Initialise the variable updateTimReqQueued with a value
+ * other then CSR_WIFI_TIM_SET or CSR_WIFI_TIM_RESET value
+ */
+ newRecord->updateTimReqQueued = 0xFF;
+ newRecord->timSet = CSR_WIFI_TIM_RESET;
newRecord->uapsdActive = FALSE;
newRecord->noOfSpFramesSent =0;
+ newRecord->triggerFramePriority = CSR_QOS_UP0;
/* The protection bit is updated once the port opens for corresponding peer in
* routerPortConfigure request */
unifi_trace(priv, UDBG6, "%s: in ok\n", __FUNCTION__);
- spin_lock(&priv->ba_lock);
+ down(&priv->ba_mutex);
r = blockack_session_stop(priv,
req->interfaceTag,
req->role,
req->trafficStreamID,
req->macAddress);
- spin_unlock(&priv->ba_lock);
+ up(&priv->ba_mutex);
CsrWifiRouterCtrlBlockAckDisableCfmSend(msg->source,
req->clientData,
init_timer(&ba_session_rx->timer);
mod_timer(&ba_session_rx->timer, (jiffies + usecs_to_jiffies((ba_session_rx->timeout) * 1024)));
}
+ /*
+ * The starting sequence number shall remain same if the BA
+ * enable request is issued to update BA parameters only. If
+ * it is not same, then we scroll our window to the new starting
+ * sequence number. This could happen if the DELBA frame from
+ * originator is lost and then we receive ADDBA frame with new SSN.
+ */
+ if(ba_session_rx->start_sn != start_sn) {
+ scroll_ba_window(priv, interfacePriv, ba_session_rx, start_sn);
+ }
return TRUE;
}
}
return FALSE;
}
+ /* It is observed that with some devices there is a race between
+ * EAPOL exchanges and BA session establishment. This results in
+ * some EAPOL authentication packets getting stuck in BA reorder
+ * buffer and hence the conection cannot be established. To avoid
+ * this we check here if the EAPOL authentication is complete and
+ * if so then only allow the BA session to establish.
+ *
+ * It is verified that the peers normally re-establish
+ * the BA session after the initial rejection.
+ */
+ if (CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN != uf_sme_port_state(priv, macAddress.a, UF_CONTROLLED_PORT_Q, interfacePriv->InterfaceTag))
+ {
+ unifi_warning(priv, "blockack_session_start: Controlled port not opened, Reject BA request\n");
+ return FALSE;
+ }
ba_session_rx = kmalloc(sizeof(ba_session_rx_struct), GFP_KERNEL);
if (!ba_session_rx) {
unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
unifi_trace(priv, UDBG6, ">>%s\n", __FUNCTION__);
- spin_lock(&priv->ba_lock);
+ down(&priv->ba_mutex);
r = blockack_session_start(priv,
req->interfaceTag,
req->trafficStreamID,
req->ssn,
req->macAddress
);
- spin_unlock(&priv->ba_lock);
+ up(&priv->ba_mutex);
CsrWifiRouterCtrlBlockAckEnableCfmSend(msg->source,
req->clientData,
void CsrWifiRouterCtrlWapiMulticastFilterReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
{
+#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
+
unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
CsrWifiRouterCtrlWapiMulticastFilterReq* req = (CsrWifiRouterCtrlWapiMulticastFilterReq*)msg;
+ netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag];
- unifi_trace(priv, UDBG6, ">>%s\n", __FUNCTION__);
- unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWapiMulticastFilterReq: req->status = %d\n", req->status);
+ if (CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode) {
+
+ unifi_trace(priv, UDBG6, ">>%s\n", __FUNCTION__);
+
+ unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWapiMulticastFilterReq: req->status = %d\n", req->status);
+
+ /* status 1 - Filter on
+ * status 0 - Filter off */
+ priv->wapi_multicast_filter = req->status;
+
+ unifi_trace(priv, UDBG6, "<<%s\n", __FUNCTION__);
+ } else {
- /* status 1 - Filter on
- * status 0 - Filter off */
- priv->wapi_multicast_filter = req->status;
+ unifi_warning(priv, "%s is NOT applicable for interface mode - %d\n", __FUNCTION__,interfacePriv->interfaceMode);
- unifi_trace(priv, UDBG6, "<<%s\n", __FUNCTION__);
+ }
+#elif defined(UNIFI_DEBUG)
+ /*WAPI Disabled*/
+ unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
+ unifi_error(priv,"CsrWifiRouterCtrlWapiMulticastFilterReqHandler: called when WAPI isn't enabled\n");
+#endif
}
void CsrWifiRouterCtrlWapiUnicastFilterReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
{
+#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
+
unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
CsrWifiRouterCtrlWapiUnicastFilterReq* req = (CsrWifiRouterCtrlWapiUnicastFilterReq*)msg;
+ netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag];
- unifi_trace(priv, UDBG6, ">>%s\n", __FUNCTION__);
- unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWapiUnicastFilterReq: req->status= %d\n", req->status);
+ if (CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode) {
- if ((priv->wapi_unicast_filter == 1) && (req->status == 0)) {
- /* When we have successfully re-associated and obtained a new unicast key with keyid = 0 */
- priv->wapi_unicast_queued_pkt_filter = 1;
- }
+ unifi_trace(priv, UDBG6, ">>%s\n", __FUNCTION__);
- /* status 1 - Filter ON
- * status 0 - Filter OFF */
- priv->wapi_unicast_filter = req->status;
+ unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWapiUnicastFilterReq: req->status= %d\n", req->status);
- unifi_trace(priv, UDBG6, "<<%s\n", __FUNCTION__);
-}
+ if ((priv->wapi_unicast_filter == 1) && (req->status == 0)) {
+ /* When we have successfully re-associated and obtained a new unicast key with keyid = 0 */
+ priv->wapi_unicast_queued_pkt_filter = 1;
+ }
+ /* status 1 - Filter ON
+ * status 0 - Filter OFF */
+ priv->wapi_unicast_filter = req->status;
-void CsrWifiRouterCtrlWapiMulticastReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
-{
+ unifi_trace(priv, UDBG6, "<<%s\n", __FUNCTION__);
+ } else {
+
+ unifi_warning(priv, "%s is NOT applicable for interface mode - %d\n", __FUNCTION__,interfacePriv->interfaceMode);
+
+ }
+#elif defined(UNIFI_DEBUG)
+ /*WAPI Disabled*/
unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
- CsrWifiRouterCtrlWapiMulticastReq* req = (CsrWifiRouterCtrlWapiMulticastReq*)msg;
+ unifi_error(priv,"CsrWifiRouterCtrlWapiUnicastFilterReqHandler: called when WAPI isn't enabled\n");
+#endif
+}
+
+void CsrWifiRouterCtrlWapiRxPktReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
+{
+#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
+ unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
+ CsrWifiRouterCtrlWapiRxPktReq* req = (CsrWifiRouterCtrlWapiRxPktReq*)msg;
int client_id, receiver_id;
bulk_data_param_t bulkdata;
CsrResult res;
ul_client_t *client;
-
CSR_SIGNAL signal;
CSR_MA_PACKET_INDICATION *pkt_ind;
+ netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag];
- unifi_trace(priv, UDBG6, ">>%s\n", __FUNCTION__);
- unifi_trace(priv, UDBG4, "CsrWifiRouterCtrlWapiMulticastReqHandler: \n");
+ if (CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode) {
- if (priv == NULL) {
- unifi_error(priv, "CsrWifiRouterCtrlWapiMulticastReqHandler : invalid priv\n",__FUNCTION__);
- return;
- }
+ unifi_trace(priv, UDBG6, ">>%s\n", __FUNCTION__);
- if (priv->smepriv == NULL) {
- unifi_error(priv, "CsrWifiRouterCtrlWapiMulticastReqHandler : invalid sme priv\n",__FUNCTION__);
- return;
- }
+ if (priv == NULL) {
+ unifi_error(priv, "CsrWifiRouterCtrlWapiRxPktReq : invalid priv\n",__FUNCTION__);
+ return;
+ }
- if (req->dataLength == 0 || req->data == NULL) {
- unifi_error(priv, "CsrWifiRouterCtrlWapiMulticastReqHandler: invalid request\n",__FUNCTION__);
- return;
- }
+ if (priv->smepriv == NULL) {
+ unifi_error(priv, "CsrWifiRouterCtrlWapiRxPktReq : invalid sme priv\n",__FUNCTION__);
+ return;
+ }
- res = unifi_net_data_malloc(priv, &bulkdata.d[0], req->dataLength);
- if (res != CSR_RESULT_SUCCESS) {
- unifi_error(priv, "CsrWifiRouterCtrlWapiMulticastReqHandler: Could not allocate net data\n",__FUNCTION__);
- return;
- }
+ if (req->dataLength == 0 || req->data == NULL) {
+ unifi_error(priv, "CsrWifiRouterCtrlWapiRxPktReq: invalid request\n",__FUNCTION__);
+ return;
+ }
- /* This function is expected to be called only when the MIC has been verified by SME to be correct
- * So reset the reception status to rx_success */
- res = read_unpack_signal(req->signal, &signal);
- if (res) {
- unifi_error(priv,"CsrWifiRouterCtrlWapiMulticastReqHandler: Received unknown or corrupted signal.\n");
- return;
- }
- pkt_ind = (CSR_MA_PACKET_INDICATION*) (&((&signal)->u).MaPacketIndication);
- if (pkt_ind->ReceptionStatus != CSR_MICHAEL_MIC_ERROR) {
- unifi_error(priv,"CsrWifiRouterCtrlWapiMulticastReqHandler: Unknown signal with reception status = %d\n",pkt_ind->ReceptionStatus);
- return;
- }
- else {
- unifi_trace(priv, UDBG4,"CsrWifiRouterCtrlWapiMulticastReqHandler: MIC verified , RX_SUCCESS \n",__FUNCTION__);
- pkt_ind->ReceptionStatus = CSR_RX_SUCCESS;
- write_pack(&signal, req->signal, &(req->signalLength));
+ res = unifi_net_data_malloc(priv, &bulkdata.d[0], req->dataLength);
+ if (res != CSR_RESULT_SUCCESS) {
+ unifi_error(priv, "CsrWifiRouterCtrlWapiRxPktReq: Could not allocate net data\n",__FUNCTION__);
+ return;
+ }
+
+ /* This function is expected to be called only when the MIC has been verified by SME to be correct
+ * So reset the reception status to rx_success */
+ res = read_unpack_signal(req->signal, &signal);
+ if (res) {
+ unifi_error(priv,"CsrWifiRouterCtrlWapiRxPktReqHandler: Received unknown or corrupted signal.\n");
+ return;
+ }
+ pkt_ind = (CSR_MA_PACKET_INDICATION*) (&((&signal)->u).MaPacketIndication);
+ if (pkt_ind->ReceptionStatus != CSR_MICHAEL_MIC_ERROR) {
+ unifi_error(priv,"CsrWifiRouterCtrlWapiRxPktReqHandler: Unknown signal with reception status = %d\n",pkt_ind->ReceptionStatus);
+ return;
+ } else {
+ unifi_trace(priv, UDBG4,"CsrWifiRouterCtrlWapiRxPktReqHandler: MIC verified , RX_SUCCESS \n",__FUNCTION__);
+ pkt_ind->ReceptionStatus = CSR_RX_SUCCESS;
+ write_pack(&signal, req->signal, &(req->signalLength));
+ }
+
+ memcpy((void*)bulkdata.d[0].os_data_ptr, req->data, req->dataLength);
+
+ receiver_id = CSR_GET_UINT16_FROM_LITTLE_ENDIAN((req->signal) + sizeof(CsrInt16)) & 0xFFF0;
+ client_id = (receiver_id & 0x0F00) >> UDI_SENDER_ID_SHIFT;
+
+ client = &priv->ul_clients[client_id];
+
+ if (client && client->event_hook) {
+ unifi_trace(priv, UDBG3,
+ "CsrWifiRouterCtrlWapiRxPktReq: "
+ "Sending signal to client %d, (s:0x%X, r:0x%X) - Signal 0x%X \n",
+ client->client_id, client->sender_id, receiver_id,
+ CSR_GET_UINT16_FROM_LITTLE_ENDIAN(req->signal));
+
+ client->event_hook(client, req->signal, req->signalLength, &bulkdata, UDI_TO_HOST);
+ } else {
+ unifi_trace(priv, UDBG4, "No client to give the packet to\n");
+ unifi_net_data_free(priv, &bulkdata.d[0]);
+ }
+
+ unifi_trace(priv, UDBG6, "<<%s\n", __FUNCTION__);
+ } else {
+ unifi_warning(priv, "%s is NOT applicable for interface mode - %d\n", __FUNCTION__,interfacePriv->interfaceMode);
}
+#elif defined(UNIFI_DEBUG)
+ /*WAPI Disabled*/
+ unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
+ unifi_error(priv,"CsrWifiRouterCtrlWapiRxPktReqHandler: called when WAPI isn't enabled\n");
+#endif
+}
- memcpy((void*)bulkdata.d[0].os_data_ptr, req->data, req->dataLength);
+void CsrWifiRouterCtrlWapiUnicastTxPktReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
+{
+#if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION))
- receiver_id = CSR_GET_UINT16_FROM_LITTLE_ENDIAN((req->signal) + sizeof(CsrInt16)) & 0xFFF0;
- client_id = (receiver_id & 0x0F00) >> UDI_SENDER_ID_SHIFT;
+ unifi_priv_t *priv = (unifi_priv_t*) drvpriv;
+ CsrWifiRouterCtrlWapiUnicastTxPktReq *req = (CsrWifiRouterCtrlWapiUnicastTxPktReq*) msg;
+ netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag];
+ bulk_data_param_t bulkdata;
+ CsrUint8 macHeaderLengthInBytes = MAC_HEADER_SIZE;
+ /*KeyID, Reserved, PN, MIC*/
+ CsrUint8 appendedCryptoFields = 1 + 1 + 16 + 16;
+ CsrResult result;
+ /* Retrieve the MA PACKET REQ fields from the Signal retained from send_ma_pkt_request() */
+ CSR_MA_PACKET_REQUEST *storedSignalMAPktReq = &interfacePriv->wapi_unicast_ma_pkt_sig.u.MaPacketRequest;
- client = &priv->ul_clients[client_id];
+ if (CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode) {
+
+ unifi_trace(priv, UDBG6, ">>%s\n", __FUNCTION__);
+
+ if (priv == NULL) {
+ unifi_error(priv, "CsrWifiRouterCtrlWapiUnicastTxPktReqHandler : invalid priv\n",__FUNCTION__);
+ return;
+ }
+ if (priv->smepriv == NULL) {
+ unifi_error(priv, "CsrWifiRouterCtrlWapiUnicastTxPktReqHandler : invalid sme priv\n",__FUNCTION__);
+ return;
+ }
+ if (req->data == NULL) {
+ unifi_error(priv, "CsrWifiRouterCtrlWapiUnicastTxPktReqHandler: invalid request\n",__FUNCTION__);
+ return;
+ } else {
+ /* If it is QoS data (type = data subtype = QoS), frame header contains QoS control field */
+ if ((req->data[0] & 0x88) == 0x88) {
+ macHeaderLengthInBytes = macHeaderLengthInBytes + QOS_CONTROL_HEADER_SIZE;
+ }
+ }
+ if ( !(req->dataLength>(macHeaderLengthInBytes+appendedCryptoFields)) ) {
+ unifi_error(priv, "CsrWifiRouterCtrlWapiUnicastTxPktReqHandler: invalid dataLength\n",__FUNCTION__);
+ return;
+ }
+
+ /* Encrypted DATA Packet contained in (req->data)
+ * -------------------------------------------------------------------
+ * |MAC Header| KeyId | Reserved | PN | xxDataxx | xxMICxxx |
+ * -------------------------------------------------------------------
+ * (<-----Encrypted----->)
+ * -------------------------------------------------------------------
+ * |24/26(QoS)| 1 | 1 | 16 | x | 16 |
+ * -------------------------------------------------------------------
+ */
+ result = unifi_net_data_malloc(priv, &bulkdata.d[0], req->dataLength);
+ if (result != CSR_RESULT_SUCCESS) {
+ unifi_error(priv, "CsrWifiRouterCtrlWapiUnicastTxPktReqHandler: Could not allocate net data\n",__FUNCTION__);
+ return;
+ }
+ memcpy((void*)bulkdata.d[0].os_data_ptr, req->data, req->dataLength);
+ bulkdata.d[0].data_length = req->dataLength;
+ bulkdata.d[1].os_data_ptr = NULL;
+ bulkdata.d[1].data_length = 0;
+
+ /* Send UniFi msg */
+ /* Here hostTag is been sent as 0xffffffff, its been appended properly while framing MA-Packet request in pdu_processing.c file */
+ result = uf_process_ma_packet_req(priv,
+ storedSignalMAPktReq->Ra.x,
+ storedSignalMAPktReq->HostTag,/* Ask for a new HostTag */
+ req->interfaceTag,
+ storedSignalMAPktReq->TransmissionControl,
+ storedSignalMAPktReq->TransmitRate,
+ storedSignalMAPktReq->Priority, /* Retained value */
+ interfacePriv->wapi_unicast_ma_pkt_sig.SignalPrimitiveHeader.SenderProcessId, /*FIXME AP: VALIDATE ???*/
+ &bulkdata);
+
+ if (result == NETDEV_TX_OK) {
+ (priv->netdev[req->interfaceTag])->trans_start = jiffies;
+ /* Should really count tx stats in the UNITDATA.status signal but
+ * that doesn't have the length.
+ */
+ interfacePriv->stats.tx_packets++;
+
+ /* count only the packet payload */
+ interfacePriv->stats.tx_bytes += req->dataLength - macHeaderLengthInBytes - appendedCryptoFields;
+ unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWapiUnicastTxPktReqHandler: (Packet Sent), sent count = %x\n", interfacePriv->stats.tx_packets);
+ } else {
+ /* Failed to send: fh queue was full, and the skb was discarded*/
+ unifi_trace(priv, UDBG1, "(HIP validation failure) Result = %d\n", result);
+ unifi_net_data_free(priv, &bulkdata.d[0]);
+
+ interfacePriv->stats.tx_dropped++;
+ unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWapiUnicastTxPktReqHandler: (Packet Drop), dropped count = %x\n", interfacePriv->stats.tx_dropped);
+ }
- if (client && client->event_hook) {
- unifi_trace(priv, UDBG3,
- "CsrWifiRouterCtrlWapiMulticastReqHandler: "
- "Sending signal to client %d, (s:0x%X, r:0x%X) - Signal 0x%X \n",
- client->client_id, client->sender_id, receiver_id,
- CSR_GET_UINT16_FROM_LITTLE_ENDIAN(req->signal));
+ unifi_trace(priv, UDBG6, "<<%s\n", __FUNCTION__);
+
+ } else {
+
+ unifi_warning(priv, "%s is NOT applicable for interface mode - %d\n", __FUNCTION__,interfacePriv->interfaceMode);
- client->event_hook(client, req->signal, req->signalLength, &bulkdata, UDI_TO_HOST);
}
- else {
- unifi_trace(priv, UDBG4, "No client to give the packet to\n");
- unifi_net_data_free(priv, &bulkdata.d[0]);
+#elif defined(UNIFI_DEBUG)
+ /*WAPI Disabled*/
+ unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
+ unifi_error(priv,"CsrWifiRouterCtrlWapiUnicastTxPktReqHandler: called when WAPI SW ENCRYPTION isn't enabled\n");
+#endif
+}
+
+void CsrWifiRouterCtrlWapiFilterReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
+{
+#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
+
+#ifdef CSR_WIFI_SECURITY_WAPI_QOSCTRL_MIC_WORKAROUND
+ unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
+ CsrWifiRouterCtrlWapiFilterReq* req = (CsrWifiRouterCtrlWapiFilterReq*)msg;
+ netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag];
+
+ if (CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode) {
+
+ unifi_trace(priv, UDBG6, ">>%s\n", __FUNCTION__);
+
+ unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWapiFilterReq: req->isWapiConnected [0/1] = %d \n",req->isWapiConnected);
+
+ priv->isWapiConnection = req->isWapiConnected;
+
+ unifi_trace(priv, UDBG6, "<<%s\n", __FUNCTION__);
+ } else {
+
+ unifi_warning(priv, "%s is NOT applicable for interface mode - %d\n", __FUNCTION__,interfacePriv->interfaceMode);
+
}
+#endif
- unifi_trace(priv, UDBG6, "<<%s\n", __FUNCTION__);
+#elif defined(UNIFI_DEBUG)
+ /*WAPI Disabled*/
+ unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
+ unifi_error(priv,"CsrWifiRouterCtrlWapiFilterReq: called when WAPI isn't enabled\n");
+#endif
}
INIT_LIST_HEAD(&interfacePriv->genericMgtFrames);
INIT_LIST_HEAD(&interfacePriv->genericMulticastOrBroadCastMgtFrames);
INIT_LIST_HEAD(&interfacePriv->genericMulticastOrBroadCastFrames);
- INIT_LIST_HEAD(&interfacePriv->directedMaPktReq);
for(j = 0; j < UNIFI_MAX_CONNECTIONS; j++) {
interfacePriv->staInfo[j] = NULL;
/* Remove all the Peer database, before going down */
for (i = 0; i < CSR_WIFI_NUM_INTERFACES; i++) {
- spin_lock(&priv->ba_lock);
+ down(&priv->ba_mutex);
for(ba_session_idx=0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_RX; ba_session_idx++){
ba_session_rx = priv->interfacePriv[i]->ba_session_rx[ba_session_idx];
if(ba_session_rx) {
}
}
- spin_unlock(&priv->ba_lock);
+ up(&priv->ba_mutex);
interfacePriv = priv->interfacePriv[i];
if(interfacePriv){
for(j = 0; j < UNIFI_MAX_CONNECTIONS; j++) {
} \
} while (0)
-/* Workaround for the wpa_supplicant hanging issue */
+/* Workaround for the wpa_supplicant hanging issue - disabled on Android */
+#ifndef ANDROID_BUILD
#define CSR_WIFI_WEXT_HANG_WORKAROUND
+#endif
#ifdef CSR_WIFI_WEXT_HANG_WORKAROUND
# define UF_RTNL_LOCK() rtnl_lock()
/* wifi_off_ind (error or exit) */
CsrWifiRouterCtrlWifiOffIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,0, (CsrWifiRouterCtrlControlIndication)(*conf_param));
}
-
+#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
+ unifi_debug_buf_dump();
+#endif
#else
bulk_data_param_t bulkdata;
CsrResult csrResult;
unsigned long lock_flags;
int r;
-#ifdef CSR_SUPPORT_SME
- netInterface_priv_t *interfacePriv = priv->interfacePriv[0];
- CsrUint32 alignOffset = 0;
-#endif
csrResult = write_pack(sigptr, sigbuf, &packed_siglen);
unifi_error(priv, "Malformed HIP signal in ul_send_signal_unpacked()\n");
return CsrHipResultToStatus(csrResult);
}
-#ifdef CSR_SUPPORT_SME
- if (bulkdata != NULL){
- alignOffset = (CsrUint32)(long)(bulkdata->d[0].os_data_ptr) & (CSR_WIFI_ALIGN_BYTES-1);
-
- }
-#endif
r = _align_bulk_data_buffers(priv, sigbuf, (bulk_data_param_t*)bulkdata);
if (r) {
return r;
spin_unlock_irqrestore(&priv->send_signal_lock, lock_flags);
return CsrHipResultToStatus(csrResult);
}
-#ifdef CSR_SUPPORT_SME
- if (sigptr->SignalPrimitiveHeader.SignalId == CSR_MA_PACKET_REQUEST_ID) {
- if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
- interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
-
- uf_store_directed_ma_packet_referenece(priv, bulkdata, sigptr,alignOffset);
-
- }
- }
-#endif
-
spin_unlock_irqrestore(&priv->send_signal_lock, lock_flags);
return 0;
static const CsrUint8 wapiProtocolIdSNAPHeaderOffset = 6;
CsrUint8 *destAddr;
CsrUint8 *srcAddr;
- CsrBool isUnicastPkt = FALSE;
+ CsrBool isWapiUnicastPkt = FALSE;
+
+#ifdef CSR_WIFI_SECURITY_WAPI_QOSCTRL_MIC_WORKAROUND
+ CsrUint16 qosControl;
+#endif
CsrUint8 llcSnapHeaderOffset = 0;
srcAddr = (CsrUint8 *) bulkdata->d[0].os_data_ptr + MAC_HEADER_ADDR2_OFFSET;
/*Individual/Group bit - Bit 0 of first byte*/
- isUnicastPkt = (!(destAddr[0] & 0x01)) ? TRUE : FALSE;
+ isWapiUnicastPkt = (!(destAddr[0] & 0x01)) ? TRUE : FALSE;
#endif
#define CSR_WIFI_MA_PKT_IND_RECEPTION_STATUS_OFFSET sizeof(CSR_SIGNAL_PRIMITIVE_HEADER) + 22
if (interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_STA) {
+#ifdef CSR_WIFI_SECURITY_WAPI_QOSCTRL_MIC_WORKAROUND
+ if ((isDataFrame) &&
+ ((IEEE802_11_FC_TYPE_QOS_DATA & IEEE80211_FC_SUBTYPE_MASK) == (frmCtrl & IEEE80211_FC_SUBTYPE_MASK)) &&
+ (priv->isWapiConnection))
+ {
+ qosControl = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(macHdrLocation + (((frmCtrl & IEEE802_11_FC_TO_DS_MASK) && (frmCtrl & IEEE802_11_FC_FROM_DS_MASK)) ? 30 : 24) );
+
+ unifi_trace(priv, UDBG4, "check_routing_pkt_data_ind() :: Value of the QoS control field - 0x%04x \n", qosControl);
+
+ if (qosControl & IEEE802_11_QC_NON_TID_BITS_MASK)
+ {
+ unifi_trace(priv, UDBG4, "Ignore the MIC failure and pass the MPDU to the stack when any of bits [4-15] is set in the QoS control field\n");
+
+ /*Exclude the MIC [16] and the PN [16] that are appended by the firmware*/
+ ((bulk_data_param_t*)bulkdata)->d[0].data_length = bulkdata->d[0].data_length - 32;
+
+ /*Clear the reception status of the signal (CSR_RX_SUCCESS)*/
+ *(sigdata + CSR_WIFI_MA_PKT_IND_RECEPTION_STATUS_OFFSET) = 0x00;
+ *(sigdata + CSR_WIFI_MA_PKT_IND_RECEPTION_STATUS_OFFSET+1) = 0x00;
+
+ *freeBulkData = FALSE;
+
+ return FALSE;
+ }
+ }
+#endif
/* If this MIC ERROR reported by the firmware is either for
- * [1] a WAPI Multicast Packet and the Multicast filter has NOT been set (It is set only when group key index (MSKID) = 1 in Group Rekeying) OR
- * [2] a WAPI Unicast Packet and either the CONTROL PORT is open or the WAPI Unicast filter or filter(s) is NOT set
+ * [1] a WAPI Multicast MPDU and the Multicast filter has NOT been set (It is set only when group key index (MSKID) = 1 in Group Rekeying) OR
+ * [2] a WAPI Unicast MPDU and either the CONTROL PORT is open or the WAPI Unicast filter or filter(s) is NOT set
* then report a MIC FAILURE indication to the SME.
*/
- if ((priv->wapi_multicast_filter == 0) || isUnicastPkt) {
-
+#ifndef CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION
+ if ((priv->wapi_multicast_filter == 0) || isWapiUnicastPkt) {
+#else
+ /*When SW encryption is enabled and USKID=1 (wapi_unicast_filter = 1), we are expected
+ *to receive MIC failure INDs for unicast MPDUs*/
+ if ( ((priv->wapi_multicast_filter == 0) && !isWapiUnicastPkt) ||
+ ((priv->wapi_unicast_filter == 0) && isWapiUnicastPkt) ) {
+#endif
/*Discard the frame*/
*freeBulkData = TRUE;
unifi_trace(priv, UDBG4, "Discarding the contents of the frame with MIC failure \n");
- if (isUnicastPkt &&
+ if (isWapiUnicastPkt &&
((uf_sme_port_state(priv,srcAddr,UF_CONTROLLED_PORT_Q,interfaceTag) != CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN)||
+#ifndef CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION
(priv->wapi_unicast_filter) ||
+#endif
(priv->wapi_unicast_queued_pkt_filter))) {
/* Workaround to handle MIC failures reported by the firmware for encrypted packets from the AP
/* To ignore MIC failures reported due to the WAPI AP using the old key for queued packets before
* starting to use the new key negotiated as part of unicast re-keying
*/
- if (isUnicastPkt &&
+ if ((interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_STA)&&
+ isWapiUnicastPkt &&
(receptionStatus == CSR_RX_SUCCESS) &&
(priv->wapi_unicast_queued_pkt_filter==1)) {
return FALSE;
}
}
-#ifdef CSR_WIFI_RX_PATH_SPLIT
-static CsrBool signal_buffer_is_full(unifi_priv_t* priv)
-{
- return (((priv->rxSignalBuffer.writePointer + 1)% priv->rxSignalBuffer.size) == (priv->rxSignalBuffer.readPointer));
-}
-#endif
/*
* ---------------------------------------------------------------------------
- * unifi_receive_event
+ * unifi_process_receive_event
*
* Dispatcher for received signals.
*
* binded to the host interface specification.
* ---------------------------------------------------------------------------
*/
-
-
-void
-unifi_receive_event(void *ospriv,
- CsrUint8 *sigdata, CsrUint32 siglen,
- const bulk_data_param_t *bulkdata)
+static void
+unifi_process_receive_event(void *ospriv,
+ CsrUint8 *sigdata, CsrUint32 siglen,
+ const bulk_data_param_t *bulkdata)
{
-#ifdef CSR_WIFI_RX_PATH_SPLIT
- unifi_priv_t *priv = (unifi_priv_t*)ospriv;
- CsrUint8 writePointer;
- int i;
- rx_buff_struct_t * rx_buff;
- func_enter();
-
- unifi_trace(priv, UDBG5, "unifi_receive_event: "
- "%04x %04x %04x %04x %04x %04x %04x %04x (%d)\n",
- CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*0) & 0xFFFF,
- CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*1) & 0xFFFF,
- CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*2) & 0xFFFF,
- CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*3) & 0xFFFF,
- CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*4) & 0xFFFF,
- CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*5) & 0xFFFF,
- CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*6) & 0xFFFF,
- CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*7) & 0xFFFF, siglen);
- if(signal_buffer_is_full(priv)) {
- unifi_error(priv,"TO HOST signal queue FULL dropping the PDU\n");
- for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++) {
- if (bulkdata->d[i].data_length != 0) {
- unifi_net_data_free(priv, (void *)&bulkdata->d[i]);
- }
- }
- return;
- }
- writePointer = priv->rxSignalBuffer.writePointer;
- rx_buff = &priv->rxSignalBuffer.rx_buff[writePointer];
- memcpy(rx_buff->bufptr,sigdata,siglen);
- rx_buff->sig_len = siglen;
- rx_buff->data_ptrs = *bulkdata;
- writePointer++;
- if(writePointer >= priv->rxSignalBuffer.size) {
- writePointer =0;
- }
- unifi_trace(priv, UDBG4, "unifi_receive_event:writePtr = %d\n",priv->rxSignalBuffer.writePointer);
- priv->rxSignalBuffer.writePointer = writePointer;
-
-#ifndef CSR_WIFI_RX_PATH_SPLIT_DONT_USE_WQ
- queue_work(priv->rx_workqueue, &priv->rx_work_struct);
-#endif
-
-#else
unifi_priv_t *priv = (unifi_priv_t*)ospriv;
int i, receiver_id;
int client_id;
func_enter();
- unifi_trace(priv, UDBG5, "unifi_receive_event: "
- "%04x %04x %04x %04x %04x %04x %04x %04x (%d)\n",
- CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*0) & 0xFFFF,
- CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*1) & 0xFFFF,
- CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*2) & 0xFFFF,
- CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*3) & 0xFFFF,
- CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*4) & 0xFFFF,
- CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*5) & 0xFFFF,
- CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*6) & 0xFFFF,
- CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*7) & 0xFFFF, siglen);
+ unifi_trace(priv, UDBG5, "unifi_process_receive_event: "
+ "%04x %04x %04x %04x %04x %04x %04x %04x (%d)\n",
+ CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*0) & 0xFFFF,
+ CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*1) & 0xFFFF,
+ CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*2) & 0xFFFF,
+ CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*3) & 0xFFFF,
+ CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*4) & 0xFFFF,
+ CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*5) & 0xFFFF,
+ CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*6) & 0xFFFF,
+ CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*7) & 0xFFFF,
+ siglen);
receiver_id = CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)) & 0xFF00;
client_id = (receiver_id & 0x0F00) >> UDI_SENDER_ID_SHIFT;
/* check for the type of frame received (checks for 802.11 management frames) */
if (signal_id == CSR_MA_PACKET_INDICATION_ID)
{
+#define CSR_MA_PACKET_INDICATION_INTERFACETAG_OFFSET 14
CsrUint8 interfaceTag;
netInterface_priv_t *interfacePriv;
/* Pull out interface tag from virtual interface identifier */
- interfaceTag = (CSR_GET_UINT16_FROM_LITTLE_ENDIAN(sigdata + 14)) & 0xff;
+ interfaceTag = (CSR_GET_UINT16_FROM_LITTLE_ENDIAN(sigdata + CSR_MA_PACKET_INDICATION_INTERFACETAG_OFFSET)) & 0xff;
interfacePriv = priv->interfacePriv[interfaceTag];
/* Update activity for this station in case of IBSS */
#ifdef CSR_SUPPORT_SME
-
- if (interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_IBSS) {
-
+ if (interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_IBSS)
+ {
CsrUint8 *saddr;
/* Fetch the source address from mac header */
saddr = (CsrUint8 *) bulkdata->d[0].os_data_ptr + MAC_HEADER_ADDR2_OFFSET;
pktIndToSme = check_routing_pkt_data_ind(priv, sigdata, bulkdata, &freeBulkData, interfacePriv);
unifi_trace(priv, UDBG6, "RX: packet entry point to driver from HIP,pkt to SME ?(%s) \n", (pktIndToSme)? "YES":"NO");
+
}
if (pktIndToSme)
send_to_client(priv, priv->sme_cli, receiver_id, sigdata, siglen, bulkdata);
}
else{
- unifi_error(priv, "unifi_receive_event: sigdata or Bulkdata is NULL \n");
+ unifi_error(priv, "unifi_receive_event2: sigdata or Bulkdata is NULL \n");
}
#ifdef CSR_NATIVE_LINUX
send_to_client(priv, priv->wext_client,
* unless they are data/control MA_PACKET_INDs or VIF_AVAILABILITY_INDs
*/
if (!receiver_id) {
- if(signal_id == CSR_MA_VIF_AVAILABILITY_INDICATION_ID)
- {
- uf_process_ma_vif_availibility_ind(priv, sigdata, siglen);
- }
- else if (signal_id != CSR_MA_PACKET_INDICATION_ID)
- {
- send_to_client(priv, priv->sme_cli, receiver_id, sigdata, siglen, bulkdata);
+ if(signal_id == CSR_MA_VIF_AVAILABILITY_INDICATION_ID) {
+ uf_process_ma_vif_availibility_ind(priv, sigdata, siglen);
+ }
+ else if (signal_id != CSR_MA_PACKET_INDICATION_ID) {
+ send_to_client(priv, priv->sme_cli, receiver_id, sigdata, siglen, bulkdata);
#ifdef CSR_NATIVE_LINUX
- send_to_client(priv, priv->wext_client,
- receiver_id,
- sigdata, siglen, bulkdata);
+ send_to_client(priv, priv->wext_client,
+ receiver_id,
+ sigdata, siglen, bulkdata);
#endif
- }
- }/*if (receiver_id==0) */
-
-#ifdef CSR_SUPPORT_SME
-#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
- /* Send a WAPI Multicast Indication to SME if the filter has been set
- * and this is a multicast data packet
- */
- if ((priv->wapi_multicast_filter == 1) && (signal_id == CSR_MA_PACKET_INDICATION_ID)) {
- CSR_SIGNAL signal;
- CsrUint8 *destAddr;
- CsrResult res;
- CsrUint16 interfaceTag = 0;
-
- /* Check if it is a multicast packet from the destination address in the MAC header */
- res = read_unpack_signal(sigdata, &signal);
- destAddr = (CsrUint8 *) bulkdata->d[0].os_data_ptr + MAC_HEADER_ADDR1_OFFSET;
- if (res) {
- unifi_error(priv, "Received unknown or corrupted signal.\n");
- return;
- }
- /*Individual/Group bit - Bit 0 of first byte*/
- if (destAddr[0] & 0x01) {
- unifi_trace(priv, UDBG4, "Received a WAPI multicast packet ind\n");
-
- CsrWifiRouterCtrlWapiMulticastIndSend(priv->CSR_WIFI_SME_IFACEQUEUE, 0, interfaceTag, siglen, sigdata, bulkdata->d[0].data_length, (CsrUint8*)bulkdata->d[0].os_data_ptr);
-
- for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++) {
- if (bulkdata->d[i].data_length != 0) {
- unifi_net_data_free(priv, (void *)&bulkdata->d[i]);
- }
- }
- func_exit();
- return;
- }
- }
+ }
+ else
+ {
+
+#if (defined(CSR_SUPPORT_SME) && defined(CSR_WIFI_SECURITY_WAPI_ENABLE))
+ #define CSR_MA_PACKET_INDICATION_RECEPTION_STATUS_OFFSET sizeof(CSR_SIGNAL_PRIMITIVE_HEADER) + 22
+ netInterface_priv_t *interfacePriv;
+ CsrUint8 interfaceTag;
+ CsrUint16 receptionStatus = CSR_RX_SUCCESS;
+
+ /* Pull out interface tag from virtual interface identifier */
+ interfaceTag = (CSR_GET_UINT16_FROM_LITTLE_ENDIAN(sigdata + CSR_MA_PACKET_INDICATION_INTERFACETAG_OFFSET)) & 0xff;
+ interfacePriv = priv->interfacePriv[interfaceTag];
+
+ /* check for MIC failure */
+ receptionStatus = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(sigdata + CSR_MA_PACKET_INDICATION_RECEPTION_STATUS_OFFSET);
+
+ /* Send a WAPI MPDU to SME for re-check MIC if the respective filter has been set*/
+ if ((!freeBulkData) &&
+ (interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_STA) &&
+ (receptionStatus == CSR_MICHAEL_MIC_ERROR) &&
+ ((priv->wapi_multicast_filter == 1)
+#ifdef CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION
+ || (priv->wapi_unicast_filter == 1)
#endif
+ ))
+ {
+ CSR_SIGNAL signal;
+ CsrUint8 *destAddr;
+ CsrResult res;
+ CsrUint16 interfaceTag = 0;
+ CsrBool isMcastPkt = TRUE;
+
+ unifi_trace(priv, UDBG6, "Received a WAPI data packet when the Unicast/Multicast filter is set\n");
+ res = read_unpack_signal(sigdata, &signal);
+ if (res) {
+ unifi_error(priv, "Received unknown or corrupted signal (0x%x).\n",
+ CSR_GET_UINT16_FROM_LITTLE_ENDIAN(sigdata));
+ return;
+ }
+
+ /* Check if the type of MPDU and the respective filter status*/
+ destAddr = (CsrUint8 *) bulkdata->d[0].os_data_ptr + MAC_HEADER_ADDR1_OFFSET;
+ isMcastPkt = (destAddr[0] & 0x01) ? TRUE : FALSE;
+ unifi_trace(priv, UDBG6,
+ "1.MPDU type: (%s), 2.Multicast filter: (%s), 3. Unicast filter: (%s)\n",
+ ((isMcastPkt) ? "Multiast":"Unicast"),
+ ((priv->wapi_multicast_filter) ? "Enabled":"Disabled"),
+ ((priv->wapi_unicast_filter) ? "Enabled":"Disabled"));
+
+ if (((isMcastPkt) && (priv->wapi_multicast_filter == 1))
+#ifdef CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION
+ || ((!isMcastPkt) && (priv->wapi_unicast_filter == 1))
#endif
+ )
+ {
+ unifi_trace(priv, UDBG4, "Sending the WAPI MPDU for MIC check\n");
+ CsrWifiRouterCtrlWapiRxMicCheckIndSend(priv->CSR_WIFI_SME_IFACEQUEUE, 0, interfaceTag, siglen, sigdata, bulkdata->d[0].data_length, (CsrUint8*)bulkdata->d[0].os_data_ptr);
+
+ for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++) {
+ if (bulkdata->d[i].data_length != 0) {
+ unifi_net_data_free(priv, (void *)&bulkdata->d[i]);
+ }
+ }
+ func_exit();
+ return;
+ }
+ } /* CSR_MA_PACKET_INDICATION_ID */
+#endif /*CSR_SUPPORT_SME && CSR_WIFI_SECURITY_WAPI_ENABLE*/
+ }
+ }
/* calls the registered clients handler callback func.
* netdev_mlme_event_handler is one of the registered handler used to route
* data packet to network stack or AMP/EAPOL related data to SME
- */
- /* The freeBulkData check ensures that, it has received a management frame and
+ *
+ * The freeBulkData check ensures that, it has received a management frame and
* the frame needs to be freed here. So not to be passed to netdev handler
*/
if(!freeBulkData){
if ((client_id < MAX_UDI_CLIENTS) &&
(&priv->ul_clients[client_id] != priv->logging_client)) {
+ unifi_trace(priv, UDBG6, "Call the registered clients handler callback func\n");
send_to_client(priv, &priv->ul_clients[client_id],
receiver_id,
sigdata, siglen, bulkdata);
}
}
}
-#endif
+
func_exit();
-} /* unifi_receive_event() */
+} /* unifi_process_receive_event() */
+
#ifdef CSR_WIFI_RX_PATH_SPLIT
+static CsrBool signal_buffer_is_full(unifi_priv_t* priv)
+{
+ return (((priv->rxSignalBuffer.writePointer + 1)% priv->rxSignalBuffer.size) == (priv->rxSignalBuffer.readPointer));
+}
+
+void unifi_rx_queue_flush(void *ospriv)
+{
+ unifi_priv_t *priv = (unifi_priv_t*)ospriv;
+
+ func_enter();
+ unifi_trace(priv, UDBG4, "rx_wq_handler: RdPtr = %d WritePtr = %d\n",
+ priv->rxSignalBuffer.readPointer,priv->rxSignalBuffer.writePointer);
+ if(priv != NULL) {
+ CsrUint8 readPointer = priv->rxSignalBuffer.readPointer;
+ while (readPointer != priv->rxSignalBuffer.writePointer)
+ {
+ rx_buff_struct_t *buf = &priv->rxSignalBuffer.rx_buff[readPointer];
+ unifi_trace(priv, UDBG6, "rx_wq_handler: RdPtr = %d WritePtr = %d\n",
+ readPointer,priv->rxSignalBuffer.writePointer);
+ unifi_process_receive_event(priv, buf->bufptr, buf->sig_len, &buf->data_ptrs);
+ readPointer ++;
+ if(readPointer >= priv->rxSignalBuffer.size) {
+ readPointer = 0;
+ }
+ }
+ priv->rxSignalBuffer.readPointer = readPointer;
+ }
+ func_exit();
+}
+
+void rx_wq_handler(struct work_struct *work)
+{
+ unifi_priv_t *priv = container_of(work, unifi_priv_t, rx_work_struct);
+ unifi_rx_queue_flush(priv);
+}
+#endif
+
+
+
/*
* ---------------------------------------------------------------------------
- * unifi_receive_event2
+ * unifi_receive_event
*
* Dispatcher for received signals.
*
* binded to the host interface specification.
* ---------------------------------------------------------------------------
*/
-static void
-unifi_receive_event2(void *ospriv,
- CsrUint8 *sigdata, CsrUint32 siglen,
- const bulk_data_param_t *bulkdata)
+void
+unifi_receive_event(void *ospriv,
+ CsrUint8 *sigdata, CsrUint32 siglen,
+ const bulk_data_param_t *bulkdata)
{
+#ifdef CSR_WIFI_RX_PATH_SPLIT
unifi_priv_t *priv = (unifi_priv_t*)ospriv;
- int i, receiver_id;
- int client_id;
- CsrInt16 signal_id;
- CsrBool pktIndToSme = FALSE, freeBulkData = FALSE;
-
+ CsrUint8 writePointer;
+ int i;
+ rx_buff_struct_t * rx_buff;
func_enter();
- unifi_trace(priv, UDBG5, "unifi_receive_event2: "
+ unifi_trace(priv, UDBG5, "unifi_receive_event: "
"%04x %04x %04x %04x %04x %04x %04x %04x (%d)\n",
CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*0) & 0xFFFF,
CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*1) & 0xFFFF,
CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*5) & 0xFFFF,
CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*6) & 0xFFFF,
CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*7) & 0xFFFF, siglen);
-
- receiver_id = CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)) & 0xFF00;
- client_id = (receiver_id & 0x0F00) >> UDI_SENDER_ID_SHIFT;
- signal_id = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(sigdata);
-
-
-
- /* check for the type of frame received (checks for 802.11 management frames) */
- if (signal_id == CSR_MA_PACKET_INDICATION_ID)
- {
- CsrUint8 interfaceTag;
- netInterface_priv_t *interfacePriv;
-
- /* Pull out interface tag from virtual interface identifier */
- interfaceTag = (CSR_GET_UINT16_FROM_LITTLE_ENDIAN(sigdata + 14)) & 0xff;
- interfacePriv = priv->interfacePriv[interfaceTag];
-
- /* Update activity for this station in case of IBSS */
-#ifdef CSR_SUPPORT_SME
-
- if (interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_IBSS) {
-
- CsrUint8 *saddr;
- /* Fetch the source address from mac header */
- saddr = (CsrUint8 *) bulkdata->d[0].os_data_ptr + MAC_HEADER_ADDR2_OFFSET;
- unifi_trace(priv, UDBG5,
- "Updating sta activity in IBSS interfaceTag %x Src Addr %x:%x:%x:%x:%x:%x\n",
- interfaceTag, saddr[0], saddr[1], saddr[2], saddr[3], saddr[4], saddr[5]);
-
- uf_update_sta_activity(priv, interfaceTag, saddr);
+ if(signal_buffer_is_full(priv)) {
+ unifi_error(priv,"TO HOST signal queue FULL dropping the PDU\n");
+ for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++) {
+ if (bulkdata->d[i].data_length != 0) {
+ unifi_net_data_free(priv, (void *)&bulkdata->d[i]);
+ }
}
-#endif
-
- pktIndToSme = check_routing_pkt_data_ind(priv, sigdata, bulkdata, &freeBulkData, interfacePriv);
-
- unifi_trace(priv, UDBG6, "RX: packet entry point to driver from HIP,pkt to SME ?(%s) \n", (pktIndToSme)? "YES":"NO");
-
+ return;
}
-
- if (pktIndToSme)
- {
- /* Management MA_PACKET_IND for SME */
- if(sigdata != NULL && bulkdata != NULL){
- send_to_client(priv, priv->sme_cli, receiver_id, sigdata, siglen, bulkdata);
- }
- else{
- unifi_error(priv, "unifi_receive_event2: sigdata or Bulkdata is NULL \n");
- }
-#ifdef CSR_NATIVE_LINUX
- send_to_client(priv, priv->wext_client,
- receiver_id,
- sigdata, siglen, bulkdata);
-#endif
+ writePointer = priv->rxSignalBuffer.writePointer;
+ rx_buff = &priv->rxSignalBuffer.rx_buff[writePointer];
+ memcpy(rx_buff->bufptr,sigdata,siglen);
+ rx_buff->sig_len = siglen;
+ rx_buff->data_ptrs = *bulkdata;
+ writePointer++;
+ if(writePointer >= priv->rxSignalBuffer.size) {
+ writePointer =0;
}
- else
- {
- /* Signals with ReceiverId==0 are also reported to SME / WEXT,
- * unless they are data/control MA_PACKET_INDs or VIF_AVAILABILITY_INDs
- */
- if (!receiver_id) {
- if(signal_id == CSR_MA_VIF_AVAILABILITY_INDICATION_ID)
- {
- uf_process_ma_vif_availibility_ind(priv, sigdata, siglen);
- }
- else if (signal_id != CSR_MA_PACKET_INDICATION_ID)
- {
- send_to_client(priv, priv->sme_cli, receiver_id, sigdata, siglen, bulkdata);
-#ifdef CSR_NATIVE_LINUX
- send_to_client(priv, priv->wext_client,
- receiver_id,
- sigdata, siglen, bulkdata);
-#endif
- }
- }
-
-#ifdef CSR_SUPPORT_SME
-#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
- /* Send a WAPI Multicast Indication to SME if the filter has been set
- * and this is a multicast data packet
- */
- if ((priv->wapi_multicast_filter == 1) && (signal_id == CSR_MA_PACKET_INDICATION_ID)) {
- CSR_SIGNAL signal;
- CsrUint8 *destAddr;
- CsrResult res;
- CsrUint16 interfaceTag = 0;
-
- /* Check if it is a multicast packet from the destination address in the MAC header */
- res = read_unpack_signal(sigdata, &signal);
- destAddr = (CsrUint8 *) bulkdata->d[0].os_data_ptr + MAC_HEADER_ADDR1_OFFSET;
- if (res) {
- unifi_error(priv, "Received unknown or corrupted signal.\n");
- return;
- }
- /*Individual/Group bit - Bit 0 of first byte*/
- if (destAddr[0] & 0x01) {
- unifi_trace(priv, UDBG4, "Received a WAPI multicast packet ind\n");
-
- CsrWifiRouterCtrlWapiMulticastIndSend(priv->CSR_WIFI_SME_IFACEQUEUE, 0, interfaceTag, siglen, sigdata, bulkdata->d[0].data_length, (CsrUint8*)bulkdata->d[0].os_data_ptr);
+ unifi_trace(priv, UDBG4, "unifi_receive_event:writePtr = %d\n",priv->rxSignalBuffer.writePointer);
+ priv->rxSignalBuffer.writePointer = writePointer;
- for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++) {
- if (bulkdata->d[i].data_length != 0) {
- unifi_net_data_free(priv, (void *)&bulkdata->d[i]);
- }
- }
- func_exit();
- return;
- }
- }
-#endif
+#ifndef CSR_WIFI_RX_PATH_SPLIT_DONT_USE_WQ
+ queue_work(priv->rx_workqueue, &priv->rx_work_struct);
#endif
- /* calls the registered clients handler callback func.
- * netdev_mlme_event_handler is one of the registered handler used to route
- * data packet to network stack or AMP/EAPOL related data to SME
- */
- /* The freeBulkData check ensures that, it has received a management frame and
- * the frame needs to be freed here. So not to be passed to netdev handler
- */
- if(!freeBulkData){
- if ((client_id < MAX_UDI_CLIENTS) &&
- (&priv->ul_clients[client_id] != priv->logging_client)) {
- send_to_client(priv, &priv->ul_clients[client_id],
- receiver_id,
- sigdata, siglen, bulkdata);
- }
- }
- }
-
- /*
- * Free bulk data buffers here unless it is a CSR_MA_PACKET_INDICATION
- */
- switch (signal_id)
- {
-#ifdef UNIFI_SNIFF_ARPHRD
- case CSR_MA_SNIFFDATA_INDICATION_ID:
+#else
+ unifi_process_receive_event(ospriv, sigdata, siglen, bulkdata);
#endif
- break;
-
- case CSR_MA_PACKET_INDICATION_ID:
- if (!freeBulkData)
- {
- break;
- }
- /* FALLS THROUGH... */
- default:
- for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++) {
- if (bulkdata->d[i].data_length != 0) {
- unifi_net_data_free(priv, (void *)&bulkdata->d[i]);
- }
- }
- }
-
func_exit();
-} /* unifi_receive_event2() */
-
-void unifi_rx_queue_flush(void *ospriv)
-{
- unifi_priv_t *priv = (unifi_priv_t*)ospriv;
-
- func_enter();
- unifi_trace(priv, UDBG4, "rx_wq_handler: RdPtr = %d WritePtr = %d\n",
- priv->rxSignalBuffer.readPointer,priv->rxSignalBuffer.writePointer);
- if(priv != NULL) {
- CsrUint8 readPointer = priv->rxSignalBuffer.readPointer;
- while(readPointer != priv->rxSignalBuffer.writePointer) {
- rx_buff_struct_t * buf = &priv->rxSignalBuffer.rx_buff[readPointer];
- unifi_trace(priv, UDBG6, "rx_wq_handler: RdPtr = %d WritePtr = %d\n",
- readPointer,priv->rxSignalBuffer.writePointer);
- unifi_receive_event2(priv,buf->bufptr,buf->sig_len,&buf->data_ptrs);
- readPointer ++;
- if(readPointer >= priv->rxSignalBuffer.size) {
- readPointer = 0;
- }
- }
- priv->rxSignalBuffer.readPointer = readPointer;
- }
- func_exit();
-}
-
-void rx_wq_handler(struct work_struct *work)
-{
- unifi_priv_t *priv = container_of(work,unifi_priv_t,rx_work_struct);
- unifi_rx_queue_flush(priv);
-}
+} /* unifi_receive_event() */
-#endif
void dump_str(void *mem, CsrUint16 len);
#endif /* CSR_WIFI_HIP_DEBUG_OFFLINE */
+void unifi_error(void* ospriv, const char *fmt, ...);
+void unifi_warning(void* ospriv, const char *fmt, ...);
+void unifi_notice(void* ospriv, const char *fmt, ...);
+void unifi_info(void* ospriv, const char *fmt, ...);
+
+void unifi_trace(void* ospriv, int level, const char *fmt, ...);
+
#else
/* Stubs */
static inline void dump_str(void *mem, CsrUint16 len) {}
#endif /* CSR_WIFI_HIP_DEBUG_OFFLINE */
-#endif /* UNIFI_DEBUG */
+void unifi_error_nop(void* ospriv, const char *fmt, ...);
+void unifi_trace_nop(void* ospriv, int level, const char *fmt, ...);
+#define unifi_error if(1);else unifi_error_nop
+#define unifi_warning if(1);else unifi_error_nop
+#define unifi_notice if(1);else unifi_error_nop
+#define unifi_info if(1);else unifi_error_nop
+#define unifi_trace if(1);else unifi_trace_nop
+#endif /* UNIFI_DEBUG */
-void unifi_error(void* ospriv, const char *fmt, ...);
-void unifi_warning(void* ospriv, const char *fmt, ...);
-void unifi_notice(void* ospriv, const char *fmt, ...);
-void unifi_info(void* ospriv, const char *fmt, ...);
-
-void unifi_trace(void* ospriv, int level, const char *fmt, ...);
/* Different levels of diagnostic detail... */
#define UDBG0 0 /* always prints in debug build */
static void _update_buffered_pkt_params_after_alignment(unifi_priv_t *priv, bulk_data_param_t *bulkdata,
tx_buffered_packets_t* buffered_pkt)
{
-
struct sk_buff *skb ;
CsrUint32 align_offset;
if (priv == NULL || bulkdata == NULL || buffered_pkt == NULL){
return;
}
+
skb = (struct sk_buff*)bulkdata->d[0].os_net_buf_ptr;
align_offset = (CsrUint32)(long)(bulkdata->d[0].os_data_ptr) & (CSR_WIFI_ALIGN_BYTES-1);
if(align_offset){
skb_pull(skb,align_offset);
}
- buffered_pkt->bulkdata.os_data_ptr = skb->data;
- buffered_pkt->bulkdata.data_length = skb->len;
-
+ buffered_pkt->bulkdata.os_data_ptr = bulkdata->d[0].os_data_ptr;
+ buffered_pkt->bulkdata.data_length = bulkdata->d[0].data_length;
+ buffered_pkt->bulkdata.os_net_buf_ptr = bulkdata->d[0].os_net_buf_ptr;
+ buffered_pkt->bulkdata.net_buf_length = bulkdata->d[0].net_buf_length;
}
#endif
#ifdef CSR_SUPPORT_SME
#define TRANSMISSION_CONTROL_TRIGGER_MASK 0x0001
-#define TRANSMISSION_CONTROL_ESOP_MASK 0x0002
+#define TRANSMISSION_CONTROL_EOSP_MASK 0x0002
static
int frame_and_send_queued_pdu(unifi_priv_t* priv,tx_buffered_packets_t* buffered_pkt,
case IEEE802_11_FC_TYPE_QOS_DATA & IEEE80211_FC_SUBTYPE_MASK:
case IEEE802_11_FC_TYPE_QOS_NULL & IEEE80211_FC_SUBTYPE_MASK:
/* If both are set then the Address4 exists (only for AP) */
- if (fromDs && toDs)
- {
+ if (fromDs && toDs) {
/* 6 is the size of Address4 field */
macHeaderLengthInBytes += (QOS_CONTROL_HEADER_SIZE + 6);
- }
- else
- {
+ } else {
macHeaderLengthInBytes += QOS_CONTROL_HEADER_SIZE;
}
/* If order bit set then HT control field is the part of MAC header */
if (*fc & cpu_to_le16(IEEE80211_FC_ORDER_MASK)) {
macHeaderLengthInBytes += HT_CONTROL_HEADER_SIZE;
+ qc = (CsrUint8*)(buffered_pkt->bulkdata.os_data_ptr + (macHeaderLengthInBytes-6));
+ } else {
+ qc = (CsrUint8*)(buffered_pkt->bulkdata.os_data_ptr + (macHeaderLengthInBytes-2));
}
+ *qc = eosp ? *qc | (1 << 4) : *qc & (~(1 << 4));
break;
default:
if (fromDs && toDs)
macHeaderLengthInBytes += 6;
- break;
- }
-
- if (*fc & cpu_to_le16(IEEE80211_FC_ORDER_MASK)) {
- qc = (CsrUint8*)(buffered_pkt->bulkdata.os_data_ptr + (macHeaderLengthInBytes-6));
- } else {
- qc = (CsrUint8*)(buffered_pkt->bulkdata.os_data_ptr + (macHeaderLengthInBytes-2));
}
- *qc = eosp ? *qc | (1 << 4) : *qc & (~(1 << 4));
}
result = ul_send_signal_unpacked(priv, &signal, &bulkdata);
if(result){
spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
list_for_each_prev_safe(listHead, placeHolder, txList) {
tx_q_item = list_entry(listHead, tx_buffered_packets_t, q);
- tx_q_item->transmissionControl |= TRANSMISSION_CONTROL_ESOP_MASK;
+ tx_q_item->transmissionControl |= TRANSMISSION_CONTROL_EOSP_MASK;
tx_q_item->transmissionControl = (tx_q_item->transmissionControl & ~(CSR_NO_CONFIRM_REQUIRED));
unifi_trace(priv, UDBG1,
"set_eosp_transmit_ctrl Transmission Control = 0x%x hostTag = 0x%x \n",tx_q_item->transmissionControl,tx_q_item->hostTag);
bulk_data_param_t *bulkdata = NULL;
int r;
+ unifi_trace(priv, UDBG3, "send_vif_availibility_rsp : invoked with resultCode = %d \n", resultCode);
+
memset(&signal,0,sizeof(CSR_SIGNAL));
rsp = &signal.u.MaVifAvailabilityResponse;
rsp->VirtualInterfaceIdentifier = vif;
if(r) {
unifi_error(priv,"Availibility response sending failed %x status %d\n",vif,r);
}
+ else {
+ unifi_trace(priv, UDBG3, "send_vif_availibility_rsp : status = %d \n", r);
+ }
}
#endif
list_for_each_safe(listHead, placeHolder, &interfacePriv->genericMulticastOrBroadCastFrames) {
tx_q_item = list_entry(listHead, tx_buffered_packets_t, q);
if(eospFramedeleted){
- tx_q_item->transmissionControl |= TRANSMISSION_CONTROL_ESOP_MASK;
+ tx_q_item->transmissionControl |= TRANSMISSION_CONTROL_EOSP_MASK;
tx_q_item->transmissionControl = (tx_q_item->transmissionControl & ~(CSR_NO_CONFIRM_REQUIRED));
unifi_trace(priv, UDBG1,"updating eosp for next packet hostTag:= 0x%x ",tx_q_item->hostTag);
eospFramedeleted =0;
break;
}
- if(tx_q_item->transmissionControl & TRANSMISSION_CONTROL_ESOP_MASK ){
+ if(tx_q_item->transmissionControl & TRANSMISSION_CONTROL_EOSP_MASK ){
eospFramedeleted = 1;
}
unifi_trace(priv,UDBG1, "freeing of multicast packets ToC = 0x%x hostTag = 0x%x \n",tx_q_item->transmissionControl,tx_q_item->hostTag);
unifi_trace(priv, UDBG5, "leaving enque_tx_data_pdu\n");
return CSR_RESULT_SUCCESS;
}
-static
-CsrResult enque_direceted_ma_pkt_cfm_data_pdu(unifi_priv_t *priv, bulk_data_param_t *bulkdata,
- struct list_head *list, CSR_SIGNAL *signal,
- CsrBool requeueOnSamePos)
+
+#ifdef CSR_WIFI_REQUEUE_PACKET_TO_HAL
+CsrResult unifi_reque_ma_packet_request (void *ospriv, CsrUint32 host_tag,
+ CsrUint16 txStatus, bulk_data_desc_t *bulkDataDesc)
{
+ CsrResult status = CSR_RESULT_SUCCESS;
+ unifi_priv_t *priv = (unifi_priv_t*)ospriv;
+ netInterface_priv_t *interfacePriv;
+ struct list_head *list = NULL;
+ CsrWifiRouterCtrlStaInfo_t *staRecord = NULL;
+ bulk_data_param_t bulkData;
+ CSR_SIGNAL signal;
+ CSR_PRIORITY priority = 0;
+ CsrUint16 interfaceTag = 0;
+ unifi_TrafficQueue priority_q;
+ CsrUint16 frameControl = 0, frameType = 0;
+ unsigned long lock_flags;
- /* queue the tx data packets on to appropriate queue */
- CSR_MA_PACKET_REQUEST *req = &signal->u.MaPacketRequest;
- tx_buffered_packets_t *tx_q_item;
+ interfacePriv = priv->interfacePriv[interfaceTag];
+
+ /* If the current mode is not AP or P2PGO then just return failure
+ * to clear the hip slot
+ */
+ if(!((interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP) ||
+ (interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO))) {
+ return CSR_RESULT_FAILURE;
+ }
+ unifi_trace(priv, UDBG6, "unifi_reque_ma_packet_request: host_tag = 0x%x\n", host_tag);
- unifi_trace(priv, UDBG5, "entering enque_tx_data_pdu\n");
- if(!list ) {
- unifi_error(priv,"List is not specified\n");
- return CSR_RESULT_FAILURE;
+ staRecord = CsrWifiRouterCtrlGetStationRecordFromPeerMacAddress(priv,
+ (((CsrUint8 *) bulkDataDesc->os_data_ptr) + 4),
+ interfaceTag);
+ if (NULL == staRecord) {
+ unifi_trace(priv, UDBG5, "unifi_reque_ma_packet_request: Invalid STA record \n");
+ return CSR_RESULT_FAILURE;
}
- if(!requeueOnSamePos && !list->prev){
- unifi_error(priv,"List prev is NULL so don't requeu it\n");
- return CSR_RESULT_FAILURE;
+ /* Update TIM if MA-PACKET.cfm fails with status as Tx-retry-limit or No-BSS and then just return failure
+ * to clear the hip slot associated with the Packet
+ */
+ if (CSR_TX_RETRY_LIMIT == txStatus || CSR_TX_NO_BSS == txStatus) {
+ if (staRecord->timSet == CSR_WIFI_TIM_RESET || staRecord->timSet == CSR_WIFI_TIM_RESETTING)
+ {
+ unifi_trace(priv, UDBG2, "unifi_reque_ma_packet_request: CFM failed with Retry Limit or No BSS-->update TIM\n");
+ if (!staRecord->timRequestPendingFlag) {
+ update_tim(priv, staRecord->aid, 1, interfaceTag, staRecord->assignedHandle);
+ }
+ else {
+ /* Cache the TimSet value so that it will processed immidiatly after
+ * completing the current setTim Request
+ */
+ staRecord->updateTimReqQueued = 1;
+ unifi_trace(priv, UDBG6, "unifi_reque_ma_packet_request: One more UpdateTim Request(:%d)Queued for AID %x\n",
+ staRecord->updateTimReqQueued, staRecord->aid);
+ }
+ }
+ return CSR_RESULT_FAILURE;
}
+ else if ((CSR_TX_LIFETIME == txStatus) || (CSR_TX_BLOCK_ACK_TIMEOUT == txStatus) ||
+ (CSR_TX_FAIL_TRANSMISSION_VIF_INTERRUPTED == txStatus) ||
+ (CSR_TX_REJECTED_PEER_STATION_SLEEPING == txStatus) ||
+ (CSR_TX_REJECTED_DTIM_STARTED == txStatus)) {
+ /* Extract the Frame control and the frame type */
+ frameControl = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(bulkDataDesc->os_data_ptr);
+ frameType = ((frameControl & IEEE80211_FC_TYPE_MASK) >> FRAME_CONTROL_TYPE_FIELD_OFFSET);
+ /* Mgmt frames will not be re-queued for Tx
+ * so just return failure to clear the hip slot
+ */
+ if (IEEE802_11_FRAMETYPE_MANAGEMENT == frameType) {
+ return CSR_RESULT_FAILURE;
+ }
+ else if (IEEE802_11_FRAMETYPE_DATA == frameType) {
+ /* QOS NULL and DATA NULL frames will not be re-queued for Tx
+ * so just return failure to clear the hip slot
+ */
+ if ((((frameControl & IEEE80211_FC_SUBTYPE_MASK) >> FRAME_CONTROL_SUBTYPE_FIELD_OFFSET) == QOS_DATA_NULL) ||
+ (((frameControl & IEEE80211_FC_SUBTYPE_MASK) >> FRAME_CONTROL_SUBTYPE_FIELD_OFFSET)== DATA_NULL )) {
+ return CSR_RESULT_FAILURE;
+ }
+ }
+ /* Extract the Packet priority */
+ if (TRUE == staRecord->wmmOrQosEnabled) {
+ CsrUint16 qosControl = 0;
+ CsrUint8 dataFrameType = 0;
- tx_q_item = (tx_buffered_packets_t *)kmalloc(sizeof(tx_buffered_packets_t), GFP_ATOMIC);
- if (tx_q_item == NULL) {
- unifi_error(priv,
- "Failed to allocate %d bytes for tx packet record\n",
- sizeof(tx_buffered_packets_t));
- func_exit();
- return CSR_RESULT_FAILURE;
- }
- /* disable the preemption */
- INIT_LIST_HEAD(&tx_q_item->q);
- /* fill the tx_q structure members */
- tx_q_item->bulkdata.os_data_ptr = bulkdata->d[0].os_data_ptr;
- tx_q_item->bulkdata.data_length = bulkdata->d[0].data_length;
- tx_q_item->bulkdata.os_net_buf_ptr = bulkdata->d[0].os_net_buf_ptr;
- tx_q_item->bulkdata.net_buf_length = bulkdata->d[0].net_buf_length;
- tx_q_item->interfaceTag = req->VirtualInterfaceIdentifier & 0xff;
- tx_q_item->hostTag = req->HostTag;
- tx_q_item->leSenderProcessId = signal->SignalPrimitiveHeader.SenderProcessId;
- tx_q_item->transmissionControl = req->TransmissionControl;
- tx_q_item->priority = req->Priority;
- tx_q_item->rate = req->TransmitRate;
- memcpy(tx_q_item->peerMacAddress.a, req->Ra.x, ETH_ALEN);
+ dataFrameType =((frameControl & IEEE80211_FC_SUBTYPE_MASK) >> 4);
+ if (dataFrameType == QOS_DATA) {
+ /* QoS control field is offset from frame control by 2 (frame control)
+ * + 2 (duration/ID) + 2 (sequence control) + 3*ETH_ALEN or 4*ETH_ALEN
+ */
+ if((frameControl & IEEE802_11_FC_TO_DS_MASK) && (frameControl & IEEE802_11_FC_FROM_DS_MASK)) {
+ qosControl= CSR_GET_UINT16_FROM_LITTLE_ENDIAN(bulkDataDesc->os_data_ptr + 30);
+ }
+ else {
+ qosControl = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(bulkDataDesc->os_data_ptr + 24);
+ }
+ }
+ priority = (CSR_PRIORITY)(qosControl & IEEE802_11_QC_TID_MASK);
- if (requeueOnSamePos) {
- list_add(&tx_q_item->q, list);
- } else {
- list_add_tail(&tx_q_item->q, list);
+ if (priority < CSR_QOS_UP0 || priority > CSR_QOS_UP7) {
+ unifi_trace(priv, UDBG5, "unifi_reque_ma_packet_request: Invalid priority:%x \n", priority);
+ return CSR_RESULT_FAILURE;
+ }
+ }
+ else {
+ priority = CSR_CONTENTION;
+ }
+
+ /* Frame Bulk data to requeue it back to HAL Queues */
+ bulkData.d[0].os_data_ptr = bulkDataDesc->os_data_ptr;
+ bulkData.d[0].data_length = bulkDataDesc->data_length;
+ bulkData.d[0].os_net_buf_ptr = bulkDataDesc->os_net_buf_ptr;
+ bulkData.d[0].net_buf_length = bulkDataDesc->net_buf_length;
+
+ bulkData.d[1].os_data_ptr = NULL;
+ bulkData.d[1].os_net_buf_ptr = NULL;
+ bulkData.d[1].data_length = bulkData.d[1].net_buf_length = 0;
+
+ /* Initialize signal to zero */
+ memset(&signal, 0, sizeof(CSR_SIGNAL));
+
+ /* Frame MA Packet Req */
+ unifi_frame_ma_packet_req(priv, priority, 0, host_tag,
+ interfaceTag, CSR_NO_CONFIRM_REQUIRED,
+ priv->netdev_client->sender_id,
+ staRecord->peerMacAddress.a, &signal);
+
+ /* Find the Q-Priority */
+ priority_q = unifi_frame_priority_to_queue(priority);
+ list = &staRecord->dataPdu[priority_q];
+
+ /* Place the Packet on to HAL Queue */
+ status = enque_tx_data_pdu(priv, &bulkData, list, &signal, TRUE);
+
+ /* Update the Per-station queued packet counter */
+ if (!status) {
+ spin_lock_irqsave(&priv->staRecord_lock, lock_flags);
+ staRecord->noOfPktQueued++;
+ spin_unlock_irqrestore(&priv->staRecord_lock, lock_flags);
+ }
+ }
+ else {
+ /* Packet will not be re-queued for any of the other MA Packet Tx failure
+ * reasons so just return failure to clear the hip slot
+ */
+ return CSR_RESULT_FAILURE;
}
- /* Count of packet queued in driver */
- priv->noOfPktQueuedInDriver++;
- unifi_trace(priv, UDBG5, "leaving enque_tx_data_pdu\n");
- return CSR_RESULT_SUCCESS;
+ return status;
}
+#endif
static void is_all_ac_deliver_enabled_and_moredata(CsrWifiRouterCtrlStaInfo_t *staRecord, CsrUint8 *allDeliveryEnabled, CsrUint8 *dataAvailable)
{
unifi_trace(priv, UDBG3, "receiver processID = %x, success: request & confirm states are not matching in TIM cfm: Debug status = %x, staRecord->timSet = %x, handle = %x\n",
receiverProcessId, timSetStatus, staRecord->timSet, handle);
}
+
+ /* Reset TIM pending flag to send next TIM request */
+ staRecord->timRequestPendingFlag = FALSE;
+
+ /* Make sure that one more UpdateTim request is queued, if Queued its value
+ * should be CSR_WIFI_TIM_SET or CSR_WIFI_TIM_RESET
+ */
+ if (0xFF != staRecord->updateTimReqQueued)
+ {
+ /* Process the UpdateTim Request which is queued while previous UpdateTim was in progress */
+ if (staRecord->timSet != staRecord->updateTimReqQueued)
+ {
+ unifi_trace(priv, UDBG2, "uf_handle_tim_cfm : Processing Queued UpdateTimReq \n");
+
+ update_tim(priv, staRecord->aid, staRecord->updateTimReqQueued, interfaceTag, handle);
+
+ staRecord->updateTimReqQueued = 0xFF;
+ }
+ }
} else {
+
+ interfacePriv->bcTimSet = timSetValue;
/* fh_cmd_q can also be full at some point of time!,
* resetting count as queue is cleaned by firmware at this point
*/
retryCount = 0;
unifi_trace(priv, UDBG3, "tim (%s) successfully for broadcast frame in firmware\n", (timSetValue)?"SET":"RESET");
+
+ /* Reset DTIM pending flag to send next DTIM request */
+ interfacePriv->bcTimSetReqPendingFlag = FALSE;
+
+ /* Make sure that one more UpdateDTim request is queued, if Queued its value
+ * should be CSR_WIFI_TIM_SET or CSR_WIFI_TIM_RESET
+ */
+ if (0xFF != interfacePriv->bcTimSetReqQueued)
+ {
+ /* Process the UpdateTim Request which is queued while previous UpdateTim was in progress */
+ if (interfacePriv->bcTimSet != interfacePriv->bcTimSetReqQueued)
+ {
+ unifi_trace(priv, UDBG2, "uf_handle_tim_cfm : Processing Queued UpdateDTimReq \n");
+
+ update_tim(priv, 0, interfacePriv->bcTimSetReqQueued, interfaceTag, 0xFFFFFFFF);
+
+ interfacePriv->bcTimSetReqQueued = 0xFF;
+ }
+ }
+
}
break;
case CSR_RC_INVALID_PARAMETERS:
default:
unifi_warning(priv, "tim update request failed resultcode = %x\n", cfm->ResultCode);
}
+
unifi_trace(priv, UDBG2, "leaving %s\n", __FUNCTION__);
}
unifi_trace(priv, UDBG5, "entering the update_tim routine\n");
+
if (handle == 0xFFFFFFFF) {
handle &= CSR_WIFI_BROADCAST_OR_MULTICAST_HANDLE;
+ if (setTim == interfacePriv->bcTimSet)
+ {
+ unifi_trace(priv, UDBG3, "update_tim, Drop:Hdl=%x, timval=%d, globalTim=%d\n", handle, setTim, interfacePriv->bcTimSet);
+ return;
+ }
} else if ((handle != 0xFFFFFFFF) && (handle >= UNIFI_MAX_CONNECTIONS)) {
unifi_warning(priv, "bad station Handle = %x\n", handle);
return;
if (staRecord) {
staRecord->timSet = oldTimSetStatus ;
}
+ else
+ {
+ /* MLME_SET_TIM.req sending failed here for AID0, so revert back our bcTimSet status */
+ interfacePriv->bcTimSet = !setTim;
+ }
+ }
+ else {
+ /* Update tim request pending flag and ensure no more TIM set requests are send
+ for the same station until TIM confirm is received */
+ if (staRecord) {
+ staRecord->timRequestPendingFlag = TRUE;
+ }
+ else
+ {
+ /* Update tim request (for AID 0) pending flag and ensure no more DTIM set requests are send
+ * for the same station until TIM confirm is received
+ */
+ interfacePriv->bcTimSetReqPendingFlag = TRUE;
+ }
}
unifi_trace(priv, UDBG5, "leaving the update_tim routine\n");
}
if(IS_DTIM_ACTIVE(interfacePriv->dtimActive,interfacePriv->multicastPduHostTag)) {
/* giving more priority to multicast packets so delaying unicast packets*/
- unifi_trace(priv,UDBG2," multicast transmission is going on so resume unicast transmission after DTIM over\n");
+ unifi_trace(priv,UDBG2, "Multicast transmission is going on so resume unicast transmission after DTIM over\n");
+
+ /* As station is active now, even though AP is not able to send frames to it
+ * because of DTIM, it needs to reset the TIM here
+ */
+ if (!staRecord->timRequestPendingFlag){
+ if((staRecord->timSet == CSR_WIFI_TIM_SET) || (staRecord->timSet == CSR_WIFI_TIM_SETTING)){
+ update_tim(priv, staRecord->aid, 0, interfaceTag, staRecord->assignedHandle);
+ }
+ }
+ else
+ {
+ /* Cache the TimSet value so that it will processed immidiatly after
+ * completing the current setTim Request
+ */
+ staRecord->updateTimReqQueued = 0;
+ unifi_trace(priv, UDBG6, "update_tim : One more UpdateTim Request (Tim value:%d) Queued for AID %x\n", staRecord->updateTimReqQueued,
+ staRecord->aid);
+ }
return;
}
while((buffered_pkt=dequeue_tx_data_pdu(priv, &staRecord->mgtFrames))) {
buffered_pkt->transmissionControl &=
- ~(TRANSMISSION_CONTROL_TRIGGER_MASK|TRANSMISSION_CONTROL_ESOP_MASK);
+ ~(TRANSMISSION_CONTROL_TRIGGER_MASK|TRANSMISSION_CONTROL_EOSP_MASK);
if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staRecord,0,FALSE)) == -ENOSPC) {
unifi_trace(priv, UDBG2, "p_p_a_t:(ENOSPC) Mgt Frame queueing \n");
/* Enqueue at the head of the queue */
kfree(buffered_pkt);
}
}
- if (staRecord->txSuspend) {
- if(staRecord->timSet == CSR_WIFI_TIM_SET) {
- update_tim(priv,staRecord->aid,0,interfaceTag, staRecord->assignedHandle);
+ if (!staRecord->timRequestPendingFlag) {
+ if (staRecord->txSuspend) {
+ if(staRecord->timSet == CSR_WIFI_TIM_SET) {
+ update_tim(priv,staRecord->aid,0,interfaceTag, staRecord->assignedHandle);
+ }
+ return;
}
- return;
+ }
+ else
+ {
+ /* Cache the TimSet value so that it will processed immidiatly after
+ * completing the current setTim Request
+ */
+ staRecord->updateTimReqQueued = 0;
+ unifi_trace(priv, UDBG6, "update_tim : One more UpdateTim Request (Tim value:%d) Queued for AID %x\n", staRecord->updateTimReqQueued,
+ staRecord->aid);
}
for(i=3;i>=0;i--) {
if(!spaceAvail[i])
unifi_trace(priv, UDBG6, "p_p_a_t:data pkt sending for AC %d \n",i);
while((buffered_pkt=dequeue_tx_data_pdu(priv, &staRecord->dataPdu[i]))) {
buffered_pkt->transmissionControl &=
- ~(TRANSMISSION_CONTROL_TRIGGER_MASK|TRANSMISSION_CONTROL_ESOP_MASK);
+ ~(TRANSMISSION_CONTROL_TRIGGER_MASK|TRANSMISSION_CONTROL_EOSP_MASK);
if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staRecord,0,FALSE)) == -ENOSPC) {
/* Clear the trigger bit transmission control*/
/* Enqueue at the head of the queue */
}
}
}
- if((staRecord->timSet == CSR_WIFI_TIM_SET) || (staRecord->timSet == CSR_WIFI_TIM_SETTING)){
- unifi_trace(priv, UDBG3, "p_p_a_t:resetting tim .....\n");
- update_tim(priv,staRecord->aid,0,interfaceTag, staRecord->assignedHandle);
+ if (!staRecord->timRequestPendingFlag){
+ if((staRecord->timSet == CSR_WIFI_TIM_SET) || (staRecord->timSet == CSR_WIFI_TIM_SETTING)) {
+ unifi_trace(priv, UDBG3, "p_p_a_t:resetting tim .....\n");
+ update_tim(priv,staRecord->aid,0,interfaceTag, staRecord->assignedHandle);
+ }
+ }
+ else
+ {
+ /* Cache the TimSet value so that it will processed immidiatly after
+ * completing the current setTim Request
+ */
+ staRecord->updateTimReqQueued = 0;
+ unifi_trace(priv, UDBG6, "update_tim : One more UpdateTim Request (Tim value:%d) Queued for AID %x\n", staRecord->updateTimReqQueued,
+ staRecord->aid);
}
unifi_trace(priv, UDBG5, "leaving process_peer_active_transition\n");
}
netInterface_priv_t *interfacePriv;
CsrUint8 i;
CsrWifiRouterCtrlStaInfo_t *staRecord = NULL;
- struct list_head *listHeadMaPktreq,*listHeadStaQueue;
- struct list_head *placeHolderMaPktreq,*placeHolderStaQueue;
- unsigned long lock_flags;
- unsigned long lock_flags1;
- maPktReqList_t *maPktreq = NULL;
- tx_buffered_packets_t *tx_q_item = NULL;
- bulk_data_param_t bulkdata;
- CsrBool entryFound = FALSE;
interfacePriv = priv->interfacePriv[interfaceTag];
if(list_empty(&interfacePriv->genericMulticastOrBroadCastMgtFrames) &&
list_empty(&interfacePriv->genericMulticastOrBroadCastFrames)) {
unifi_trace(priv,UDBG1,"Resetting multicastTIM");
- update_tim(priv,0,0,interfaceTag, 0xFFFFFFFF);
- }
- return;
- }
-
- /* Check if a copy of the same frame (identified by host tag) is queued in driver */
- spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
- list_for_each_safe(listHeadMaPktreq, placeHolderMaPktreq, &interfacePriv->directedMaPktReq) {
- maPktreq = list_entry(listHeadMaPktreq, maPktReqList_t, q);
- if(maPktreq->hostTag == pkt_cfm->HostTag){
- entryFound = TRUE;
- break;
- }
- }
- spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
-
- if(entryFound){
-
- /* Monitor the time difference between the MA-PACKET.req and MA-PACKET.cfm */
- unsigned long timeout;
- timeout = (long)jiffies - (long)maPktreq->jiffeTime;
-
- /* convert into milliseconds */
- timeout = jiffies_to_msecs(timeout);
- unifi_trace(priv, UDBG3, "Jiffies Time: Host Tag(%x) --> Req(%u) Cfm(%u) Diff (in ms): %u\n",maPktreq->hostTag,maPktreq->jiffeTime, jiffies, timeout);
-
- if( (timeout/1000) > 1)
- {
- unifi_trace(priv, UDBG1, "Confirm time > 2 Seconds: time = %u Status = %x\n", (timeout/1000), pkt_cfm->TransmissionStatus);
- }
-
- if( CSR_TX_LIFETIME == pkt_cfm->TransmissionStatus ||
- CSR_TX_BLOCK_ACK_TIMEOUT== pkt_cfm->TransmissionStatus ||
- CSR_TX_FAIL_TRANSMISSION_VIF_INTERRUPTED== pkt_cfm->TransmissionStatus ||
- CSR_TX_REJECTED_PEER_STATION_SLEEPING== pkt_cfm->TransmissionStatus ||
- CSR_TX_REJECTED_DTIM_STARTED== pkt_cfm->TransmissionStatus ){
-
- CsrWifiRouterCtrlStaInfo_t *staRecord = interfacePriv->staInfo[maPktreq->staHandler];
- unifi_TrafficQueue priority_q;
- struct list_head *list;
- CsrResult result;
- CSR_MA_PACKET_REQUEST *req = &maPktreq->signal.u.MaPacketRequest;
- CsrUint16 ii=0;
- CsrBool locationFound = FALSE;
- CsrUint8 *sigbuffer;
-
- sigbuffer = (CsrUint8*)&maPktreq->signal;
- if(req->Priority == CSR_MANAGEMENT){
- list = &staRecord->mgtFrames;
- unifi_trace(priv,UDBG5,"mgmt list priority %d\n",req->Priority);
- }
- else{
- priority_q= unifi_frame_priority_to_queue(req->Priority);
- list = &staRecord->dataPdu[priority_q];
- unifi_trace(priv,UDBG5,"data list priority %d\n",req->Priority);
- }
-
- spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
- list_for_each_safe(listHeadStaQueue, placeHolderStaQueue, list){
- tx_q_item = list_entry(listHeadStaQueue, tx_buffered_packets_t, q);
- COMPARE_HOST_TAG_TO_ENQUEUE(tx_q_item->hostTag ,maPktreq->hostTag)
-
-
- }
- if(sigbuffer[SIZEOF_SIGNAL_HEADER + 1]){
- skb_pull(maPktreq->skb,sigbuffer[SIZEOF_SIGNAL_HEADER + 1]);
- }
-
- /* enqueue the failed packet sta queue*/
- bulkdata.d[0].os_net_buf_ptr= (unsigned char*)maPktreq->skb;
- bulkdata.d[0].os_data_ptr = maPktreq->skb->data;
- bulkdata.d[0].data_length = bulkdata.d[0].net_buf_length = maPktreq->skb->len;
- bulkdata.d[1].os_data_ptr = NULL;
- bulkdata.d[1].os_net_buf_ptr = NULL;
- bulkdata.d[1].data_length = bulkdata.d[0].net_buf_length = 0;
- unifi_trace(priv,UDBG4,"Cfm Fail for HosTag = %x with status %d so requeue it\n",maPktreq->hostTag,pkt_cfm->TransmissionStatus );
- req->TransmissionControl = 0;
-
- if(!locationFound){
-
- if(list_empty(list)){
- result = enque_direceted_ma_pkt_cfm_data_pdu(priv, &bulkdata, list,&maPktreq->signal,1);
- }
- else{
- unifi_trace(priv,UDBG4,"did not find location so add to end of list \n");
- result = enque_direceted_ma_pkt_cfm_data_pdu(priv, &bulkdata, list,&maPktreq->signal,0);
- }
-
-
- }
-
- else {
- if(ii > 1){
- unifi_trace(priv,UDBG4,"find the location in the middle of list \n");
- result = enque_direceted_ma_pkt_cfm_data_pdu(priv, &bulkdata, listHeadStaQueue,&maPktreq->signal,0);
-
- }
- else{
- unifi_trace(priv,UDBG4," add at begining of list \n");
- result = enque_direceted_ma_pkt_cfm_data_pdu(priv, &bulkdata, list,&maPktreq->signal,1);
+ if (!interfacePriv->bcTimSetReqPendingFlag)
+ {
+ update_tim(priv,0,CSR_WIFI_TIM_RESET,interfaceTag, 0xFFFFFFFF);
}
- }
-
- spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
-
- /* Increment the counter */
- spin_lock_irqsave(&priv->staRecord_lock,lock_flags1);
- staRecord->noOfPktQueued++;
- spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags1);
-
-
-
-
- /* after enqueuing update the TIM */
- if(CSR_RESULT_SUCCESS == result){
- if(CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE == staRecord->currentPeerState) {
- if(staRecord->timSet == CSR_WIFI_TIM_RESET || staRecord->timSet == CSR_WIFI_TIM_RESETTING) {
- if(!staRecord->wmmOrQosEnabled) {
- unifi_trace(priv, UDBG3, "uf_process_ma_pkt_cfm_for_ap :tim set due to unicast pkt & peer in powersave\n");
- update_tim(priv,staRecord->aid,1,interfaceTag, staRecord->assignedHandle);
- }
- else {
- /* Check for non delivery enable(i.e trigger enable), all delivery enable & legacy AC for TIM update in firmware */
- CsrUint8 allDeliveryEnabled = 0, dataAvailable = 0;
- /* Check if all AC's are Delivery Enabled */
- is_all_ac_deliver_enabled_and_moredata(staRecord, &allDeliveryEnabled, &dataAvailable);
- if (uf_is_more_data_for_non_delivery_ac(staRecord) || (allDeliveryEnabled && dataAvailable)) {
- update_tim(priv,staRecord->aid,1,interfaceTag, staRecord->assignedHandle);
- }
- }
- }
- }
- }
- else{
- dev_kfree_skb(maPktreq->skb);
- }
- }
- else
- {
- CsrWifiRouterCtrlStaInfo_t *staRecord = interfacePriv->staInfo[maPktreq->staHandler];
- if (CSR_TX_RETRY_LIMIT == pkt_cfm->TransmissionStatus ||
- CSR_TX_NO_BSS == pkt_cfm->TransmissionStatus)
- {
- if (staRecord->timSet == CSR_WIFI_TIM_RESET || staRecord->timSet == CSR_WIFI_TIM_RESETTING)
+ else
{
- unifi_trace(priv, UDBG2, "CFM failed with Retry Limit or No BSS --> update TIM\n");
- update_tim(priv, staRecord->aid, 1, interfaceTag, staRecord->assignedHandle);
+ /* Cache the DTimSet value so that it will processed immidiatly after
+ * completing the current setDTim Request
+ */
+ interfacePriv->bcTimSetReqQueued = CSR_WIFI_TIM_RESET;
+ unifi_trace(priv, UDBG2, "uf_process_ma_pkt_cfm_for_ap : One more UpdateDTim Request(%d) Queued \n",
+ interfacePriv->bcTimSetReqQueued);
}
+
}
- else if (CSR_TX_SUCCESSFUL == pkt_cfm->TransmissionStatus)
- {
- staRecord->activity_flag = TRUE;
- }
- unifi_trace(priv, UDBG5, "CFM for HosTag = %x Status = %d, Free SKB reference\n",
- maPktreq->hostTag,
- pkt_cfm->TransmissionStatus );
+ return;
+ }
- dev_kfree_skb(maPktreq->skb);
+ /* Check if it is a Confirm for null data frame used
+ * for probing station activity
+ */
+ for(i =0; i < UNIFI_MAX_CONNECTIONS; i++) {
+ staRecord = (CsrWifiRouterCtrlStaInfo_t *) (interfacePriv->staInfo[i]);
+ if (staRecord && (staRecord->nullDataHostTag == pkt_cfm->HostTag)) {
+
+ unifi_trace(priv, UDBG1, "CFM for Inactive probe Null frame (tag = %x, status = %d)\n",
+ pkt_cfm->HostTag,
+ pkt_cfm->TransmissionStatus
+ );
+ staRecord->nullDataHostTag = INVALID_HOST_TAG;
+
+ if(pkt_cfm->TransmissionStatus == CSR_TX_RETRY_LIMIT){
+ CsrTime now;
+ CsrTime inactive_time;
+
+ unifi_trace(priv, UDBG1, "Nulldata to probe STA ALIVE Failed with retry limit\n");
+ /* Recheck if there is some activity after null data is sent.
+ *
+ * If still there is no activity then send a disconnected indication
+ * to SME to delete the station record.
+ */
+ if (staRecord->activity_flag){
+ return;
+ }
+ now = CsrTimeGet(NULL);
- }
- list_del(listHeadMaPktreq);
- kfree(maPktreq);
+ if (staRecord->lastActivity > now)
+ {
+ /* simple timer wrap (for 1 wrap) */
+ inactive_time = CsrTimeAdd((CsrTime)CsrTimeSub(CSR_SCHED_TIME_MAX, staRecord->lastActivity),
+ now);
+ }
+ else
+ {
+ inactive_time = (CsrTime)CsrTimeSub(now, staRecord->lastActivity);
+ }
- }else{
- /* Check if it is a Confirm for null data frame used
- * for probing station activity
- */
- for(i =0; i < UNIFI_MAX_CONNECTIONS; i++) {
- staRecord = (CsrWifiRouterCtrlStaInfo_t *) (interfacePriv->staInfo[i]);
- if (staRecord && (staRecord->nullDataHostTag == pkt_cfm->HostTag)) {
-
- unifi_trace(priv, UDBG1, "CFM for Inactive probe Null frame (tag = %x, status = %d)\n",
- pkt_cfm->HostTag,
- pkt_cfm->TransmissionStatus
- );
- staRecord->nullDataHostTag = INVALID_HOST_TAG;
-
- if(pkt_cfm->TransmissionStatus == CSR_TX_RETRY_LIMIT){
- CsrTime now;
- CsrTime inactive_time;
-
- unifi_trace(priv, UDBG1, "Nulldata to probe STA ALIVE Failed with retry limit\n");
- /* Recheck if there is some activity after null data is sent.
- *
- * If still there is no activity then send a disconnected indication
- * to SME to delete the station record.
- */
- if (staRecord->activity_flag){
- return;
- }
- now = CsrTimeGet(NULL);
+ if (inactive_time >= STA_INACTIVE_TIMEOUT_VAL)
+ {
+ struct list_head send_cfm_list;
+ CsrUint8 j;
+
+ /* The SME/NME may be waiting for confirmation for requested frames to this station.
+ * Though this is --VERY UNLIKELY-- in case of station in active mode. But still as a
+ * a defensive check, it loops through buffered frames for this station and if confirmation
+ * is requested, send auto confirmation with failure status. Also flush the frames so
+ * that these are not processed again in PEER_DEL_REQ handler.
+ */
+ INIT_LIST_HEAD(&send_cfm_list);
- if (staRecord->lastActivity > now)
- {
- /* simple timer wrap (for 1 wrap) */
- inactive_time = CsrTimeAdd((CsrTime)CsrTimeSub(CSR_SCHED_TIME_MAX, staRecord->lastActivity),
- now);
- }
- else
- {
- inactive_time = (CsrTime)CsrTimeSub(now, staRecord->lastActivity);
- }
+ uf_prepare_send_cfm_list_for_queued_pkts(priv,
+ &send_cfm_list,
+ &(staRecord->mgtFrames));
- if (inactive_time >= STA_INACTIVE_TIMEOUT_VAL)
- {
- struct list_head send_cfm_list;
- CsrUint8 j;
-
- /* The SME/NME may be waiting for confirmation for requested frames to this station.
- * Though this is --VERY UNLIKELY-- in case of station in active mode. But still as a
- * a defensive check, it loops through buffered frames for this station and if confirmation
- * is requested, send auto confirmation with failure status. Also flush the frames so
- * that these are not processed again in PEER_DEL_REQ handler.
- */
- INIT_LIST_HEAD(&send_cfm_list);
+ uf_flush_list(priv, &(staRecord->mgtFrames));
+ for(j = 0; j < MAX_ACCESS_CATOGORY; j++){
uf_prepare_send_cfm_list_for_queued_pkts(priv,
&send_cfm_list,
- &(staRecord->mgtFrames));
-
- uf_flush_list(priv, &(staRecord->mgtFrames));
+ &(staRecord->dataPdu[j]));
- for(j = 0; j < MAX_ACCESS_CATOGORY; j++){
- uf_prepare_send_cfm_list_for_queued_pkts(priv,
- &send_cfm_list,
- &(staRecord->dataPdu[j]));
-
- uf_flush_list(priv,&(staRecord->dataPdu[j]));
- }
-
- send_auto_ma_packet_confirm(priv, staRecord->interfacePriv, &send_cfm_list);
+ uf_flush_list(priv,&(staRecord->dataPdu[j]));
+ }
+ send_auto_ma_packet_confirm(priv, staRecord->interfacePriv, &send_cfm_list);
- unifi_warning(priv, "uf_process_ma_pkt_cfm_for_ap: Router Disconnected IND Peer (%x-%x-%x-%x-%x-%x)\n",
- staRecord->peerMacAddress.a[0],
- staRecord->peerMacAddress.a[1],
- staRecord->peerMacAddress.a[2],
- staRecord->peerMacAddress.a[3],
- staRecord->peerMacAddress.a[4],
- staRecord->peerMacAddress.a[5]);
- CsrWifiRouterCtrlConnectedIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,
- 0,
- staRecord->interfacePriv->InterfaceTag,
- staRecord->peerMacAddress,
- CSR_WIFI_ROUTER_CTRL_PEER_DISCONNECTED);
- }
+ unifi_warning(priv, "uf_process_ma_pkt_cfm_for_ap: Router Disconnected IND Peer (%x-%x-%x-%x-%x-%x)\n",
+ staRecord->peerMacAddress.a[0],
+ staRecord->peerMacAddress.a[1],
+ staRecord->peerMacAddress.a[2],
+ staRecord->peerMacAddress.a[3],
+ staRecord->peerMacAddress.a[4],
+ staRecord->peerMacAddress.a[5]);
+ CsrWifiRouterCtrlConnectedIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,
+ 0,
+ staRecord->interfacePriv->InterfaceTag,
+ staRecord->peerMacAddress,
+ CSR_WIFI_ROUTER_CTRL_PEER_DISCONNECTED);
}
- else if (pkt_cfm->TransmissionStatus == CSR_TX_SUCCESSFUL)
- {
- staRecord->activity_flag = TRUE;
- }
+
+ }
+ else if (pkt_cfm->TransmissionStatus == CSR_TX_SUCCESSFUL)
+ {
+ staRecord->activity_flag = TRUE;
}
}
}
CsrResult csrResult;
unifi_trace(priv, UDBG5, "normal Data packet, NO QOS \n");
- *priority = CSR_CONTENTION;
if (qosDestination) {
CsrUint8 qc = 0;
unifi_trace(priv, UDBG3, "destination is QOS station \n");
- /* prepare the qos control field */
- qc |= CSR_QOS_UP0;
+ /* Set Ma-Packet.req UP to UP0 */
+ *priority = CSR_QOS_UP0;
+ /* prepare the qos control field */
+ qc |= CSR_QOS_UP0;
/* no Amsdu is in ap buffer so eosp is left 0 */
-
if (da[0] & 0x1) {
/* multicast/broadcast frames, no acknowledgement needed */
qc |= 1 << 5;
*/
list = &interfacePriv->genericMulticastOrBroadCastMgtFrames;
- spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
- interfacePriv->noOfbroadcastPktQueued++;
- spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
if((interfacePriv->interfaceMode != CSR_WIFI_ROUTER_CTRL_MODE_IBSS) &&
(list_empty(&interfacePriv->genericMulticastOrBroadCastMgtFrames))) {
setBcTim=TRUE;
/* if multicast traffic is going on, buffet the unicast packets */
unifi_trace(priv, UDBG2, "Enqueued to staRecord->dataPdu[%d] queuePacketDozing=%d,\
Buffering enabled = %d \n", priority_q,queuePacketDozing,isRouterBufferEnabled(priv,priority_q));
- signal.u.MaPacketRequest.TransmissionControl &= ~(CSR_NO_CONFIRM_REQUIRED);
list = &staRecord->dataPdu[priority_q];
} else {
unifi_trace(priv, UDBG5, "staRecord->dataPdu[%d] list is empty uf_process_ma_packet_req \n", priority_q);
- signal.u.MaPacketRequest.TransmissionControl &= ~(CSR_NO_CONFIRM_REQUIRED);
/* Pdu allowed to send to unifi */
result = ul_send_signal_unpacked(priv, &signal, bulkdata);
if(result == -ENOSPC) {
* will be sent when we receive VIF AVAILABILITY from firmware as part of DTIM
*/
list = &interfacePriv->genericMulticastOrBroadCastFrames;
- spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
- interfacePriv->noOfbroadcastPktQueued++;
- spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
if(list_empty(&interfacePriv->genericMulticastOrBroadCastFrames)) {
setBcTim = TRUE;
}
staRecord->noOfPktQueued++;
spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
}
+ else if ((pktType == CSR_WIFI_MULTICAST_PDU) && (!status))
+ {
+ /* If broadcast Tim is set && queuing is successfull, then only update TIM */
+ spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
+ interfacePriv->noOfbroadcastPktQueued++;
+ spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
+ }
}
- if(setBcTim) {
+ /* If broadcast Tim is set && queuing is successfull, then only update TIM */
+ if(setBcTim && !status) {
unifi_trace(priv, UDBG3, "tim set due to broadcast pkt\n");
- update_tim(priv,0,1,interfaceTag, handle);
+ if (!interfacePriv->bcTimSetReqPendingFlag)
+ {
+ update_tim(priv,0,CSR_WIFI_TIM_SET,interfaceTag, handle);
+ }
+ else
+ {
+ /* Cache the TimSet value so that it will processed immidiatly after
+ * completing the current setTim Request
+ */
+ interfacePriv->bcTimSetReqQueued = CSR_WIFI_TIM_SET;
+ unifi_trace(priv, UDBG2, "uf_process_ma_packet_req : One more UpdateDTim Request(:%d) Queued \n",
+ interfacePriv->bcTimSetReqQueued);
+ }
} else if(staRecord && staRecord->currentPeerState ==
CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE) {
if(staRecord->timSet == CSR_WIFI_TIM_RESET || staRecord->timSet == CSR_WIFI_TIM_RESETTING) {
!list_empty(&staRecord->dataPdu[3]) ||
!list_empty(&staRecord->dataPdu[UNIFI_TRAFFIC_Q_CONTENTION])) {
unifi_trace(priv, UDBG3, "tim set due to unicast pkt & peer in powersave\n");
- update_tim(priv,staRecord->aid,1,interfaceTag, handle);
- }
- } else {
- /* Check for non delivery enable(i.e trigger enable), all delivery enable & legacy AC for TIM update in firmware */
- CsrUint8 allDeliveryEnabled = 0, dataAvailable = 0;
+ if (!staRecord->timRequestPendingFlag){
+ update_tim(priv,staRecord->aid,1,interfaceTag, handle);
+ }
+ else
+ {
+ /* Cache the TimSet value so that it will processed immidiatly after
+ * completing the current setTim Request
+ */
+ staRecord->updateTimReqQueued = 1;
+ unifi_trace(priv, UDBG6, "update_tim : One more UpdateTim Request (Tim value:%d) Queued for AID %x\n", staRecord->updateTimReqQueued,
+ staRecord->aid);
+ }
+ }
+ } else {
+ /* Check for non delivery enable(i.e trigger enable), all delivery enable & legacy AC for TIM update in firmware */
+ CsrUint8 allDeliveryEnabled = 0, dataAvailable = 0;
/* Check if all AC's are Delivery Enabled */
is_all_ac_deliver_enabled_and_moredata(staRecord, &allDeliveryEnabled, &dataAvailable);
- if (uf_is_more_data_for_non_delivery_ac(staRecord) || (allDeliveryEnabled && dataAvailable)) {
- update_tim(priv,staRecord->aid,1,interfaceTag, handle);
+ if (uf_is_more_data_for_non_delivery_ac(staRecord) || (allDeliveryEnabled && dataAvailable)
+ || (!list_empty(&staRecord->mgtFrames))) {
+ if (!staRecord->timRequestPendingFlag) {
+ update_tim(priv,staRecord->aid,1,interfaceTag, handle);
+ }
+ else
+ {
+ /* Cache the TimSet value so that it will processed immidiatly after
+ * completing the current setTim Request
+ */
+ staRecord->updateTimReqQueued = 1;
+ unifi_trace(priv, UDBG6, "update_tim : One more UpdateTim Request (Tim value:%d) Queued for AID %x\n", staRecord->updateTimReqQueued,
+ staRecord->aid);
+ }
}
}
}
if(!isRouterBufferEnabled(priv,UNIFI_TRAFFIC_Q_VO)) {
while((interfacePriv->dtimActive)&& (buffered_pkt=dequeue_tx_data_pdu(priv,&interfacePriv->genericMulticastOrBroadCastMgtFrames))) {
buffered_pkt->transmissionControl |= (TRANSMISSION_CONTROL_TRIGGER_MASK);
- moreData = (buffered_pkt->transmissionControl & TRANSMISSION_CONTROL_ESOP_MASK)?FALSE:TRUE;
+ moreData = (buffered_pkt->transmissionControl & TRANSMISSION_CONTROL_EOSP_MASK)?FALSE:TRUE;
unifi_trace(priv,UDBG2,"DTIM Occurred for interface:sending Mgt packet %d\n",interfaceTag);
if(!isRouterBufferEnabled(priv,UNIFI_TRAFFIC_Q_CONTENTION)) {
while((interfacePriv->dtimActive)&& (buffered_pkt=dequeue_tx_data_pdu(priv,&interfacePriv->genericMulticastOrBroadCastFrames))) {
buffered_pkt->transmissionControl |= TRANSMISSION_CONTROL_TRIGGER_MASK;
- moreData = (buffered_pkt->transmissionControl & TRANSMISSION_CONTROL_ESOP_MASK)?FALSE:TRUE;
+ moreData = (buffered_pkt->transmissionControl & TRANSMISSION_CONTROL_EOSP_MASK)?FALSE:TRUE;
if((r=frame_and_send_queued_pdu(priv,buffered_pkt,NULL,moreData,FALSE)) == -ENOSPC) {
if(interfacePriv->multicastPduHostTag == 0xffffffff) {
unifi_notice(priv,"ma_vif_availibility_ind recevied for multicast but queues are empty%d\n",interfaceTag);
/* This may be an extra request in very rare race conditions but it is fine as it would atleast remove the potential lock up */
- update_tim(priv,0,0,interfaceTag, 0xFFFFFFFF);
+ if (!interfacePriv->bcTimSetReqPendingFlag)
+ {
+ update_tim(priv,0,CSR_WIFI_TIM_RESET,interfaceTag, 0xFFFFFFFF);
+ }
+ else
+ {
+ /* Cache the TimSet value so that it will processed immidiatly after
+ * completing the current setTim Request
+ */
+ interfacePriv->bcTimSetReqQueued = CSR_WIFI_TIM_RESET;
+ unifi_trace(priv, UDBG2, "uf_process_ma_vif_availibility_ind : One more UpdateDTim Request(%d) Queued \n",
+ interfacePriv->bcTimSetReqQueued);
+ }
}
return;
}
#define GET_ACTIVE_INTERFACE_TAG(priv) 0
-
-void uf_continue_uapsd(unifi_priv_t *priv, CsrWifiRouterCtrlStaInfo_t * staInfo)
+static CsrBool uf_is_more_data_for_delivery_ac(unifi_priv_t *priv, CsrWifiRouterCtrlStaInfo_t *staRecord)
{
-
CsrInt8 i;
- func_enter();
-
- if(((staInfo->powersaveMode[UNIFI_TRAFFIC_Q_VO]==CSR_WIFI_AC_TRIGGER_AND_DELIVERY_ENABLED)||
- (staInfo->powersaveMode[UNIFI_TRAFFIC_Q_VO]==CSR_WIFI_AC_DELIVERY_ONLY_ENABLE))
- &&(!list_empty(&staInfo->mgtFrames))){
-
- unifi_trace(priv, UDBG5, "uf_continue_uapsd : U-APSD ACTIVE and sending buffered mgt frames\n");
- uf_send_buffered_data_from_delivery_ac(priv, staInfo, UNIFI_TRAFFIC_Q_VO, &staInfo->mgtFrames);
-
- /*This may happen because U-APSD was completed
- with previous AC transfer*/
-
- if(staInfo->uapsdActive == FALSE) {
- return;
+ for(i=UNIFI_TRAFFIC_Q_VO; i >= UNIFI_TRAFFIC_Q_BK; i--)
+ {
+ if(((staRecord->powersaveMode[i]==CSR_WIFI_AC_DELIVERY_ONLY_ENABLE)
+ ||(staRecord->powersaveMode[i]==CSR_WIFI_AC_TRIGGER_AND_DELIVERY_ENABLED))
+ &&(!list_empty(&staRecord->dataPdu[i]))) {
+ unifi_trace(priv,UDBG2,"uf_is_more_data_for_delivery_ac: Data Available AC = %d\n", i);
+ return TRUE;
}
}
- for(i=3;i>=0;i--) {
+ unifi_trace(priv,UDBG2,"uf_is_more_data_for_delivery_ac: Data NOT Available \n");
+ return FALSE;
+}
- if(((staInfo->powersaveMode[i]== CSR_WIFI_AC_DELIVERY_ONLY_ENABLE)
- ||(staInfo->powersaveMode[i] == CSR_WIFI_AC_TRIGGER_AND_DELIVERY_ENABLED))
- &&(!list_empty(&staInfo->dataPdu[i]))) {
- unifi_trace(priv, UDBG5, "uf_continue_uapsd : U-APSD ACTIVE and sending buffered data frames\n");
- uf_send_buffered_data_from_delivery_ac(priv, staInfo, i, &staInfo->dataPdu[i]);
- }
+static CsrBool uf_is_more_data_for_usp_delivery(unifi_priv_t *priv, CsrWifiRouterCtrlStaInfo_t *staRecord, unifi_TrafficQueue queue)
+{
+ CsrInt8 i;
- /*This may happen because U-APSD was completed
- with previous AC transfer*/
- if (staInfo->uapsdActive == FALSE) {
- return;
+ for(i = queue; i >= UNIFI_TRAFFIC_Q_BK; i--)
+ {
+ if(((staRecord->powersaveMode[i]==CSR_WIFI_AC_DELIVERY_ONLY_ENABLE)
+ ||(staRecord->powersaveMode[i]==CSR_WIFI_AC_TRIGGER_AND_DELIVERY_ENABLED))
+ &&(!list_empty(&staRecord->dataPdu[i]))) {
+ unifi_trace(priv,UDBG2,"uf_is_more_data_for_usp_delivery: Data Available AC = %d\n", i);
+ return TRUE;
}
}
- if (staInfo->uapsdActive && !uf_is_more_data_for_delivery_ac(priv, staInfo, TRUE)) {
- /* If last packet not able to transfer due to ENOSPC & buffer management algorithm
- * would have removed last packet. Then we wont update staInfo->UapsdActive = FALSE (suppose
- * to update as we dont have packet to transfer at this USP) because above if loop fails as list is empty &
- * update of UAPSD activity done in uf_send_buffered_data_from_delivery_ac().
- * In this situation we send QOS null & mean time update UapsdActive to FALSE here
- */
- staInfo->uapsdActive = FALSE;
- uf_send_qos_null(priv, GET_ACTIVE_INTERFACE_TAG(priv), staInfo->peerMacAddress.a, CSR_QOS_UP0 , staInfo);
- }
- func_exit();
+ unifi_trace(priv,UDBG2,"uf_is_more_data_for_usp_delivery: Data NOT Available \n");
+ return FALSE;
}
-
+/*
+ * ---------------------------------------------------------------------------
+ * uf_send_buffered_data_from_delivery_ac
+ *
+ * This function takes care of
+ * -> Parsing the delivery enabled queue & sending frame down to HIP
+ * -> Setting EOSP=1 when USP to be terminated
+ * -> Depending on MAX SP length services the USP
+ *
+ * NOTE:This function always called from uf_handle_uspframes_delivery(), Dont
+ * call this function from any other location in code
+ *
+ * Arguments:
+ * priv Pointer to device private context struct
+ * vif interface specific HIP vif instance
+ * staInfo peer for which UAPSD to be scheduled
+ * queue AC from which Data to be sent in USP
+ * txList access category for processing list
+ * ---------------------------------------------------------------------------
+ */
void uf_send_buffered_data_from_delivery_ac(unifi_priv_t *priv,
CsrWifiRouterCtrlStaInfo_t * staInfo,
CsrUint8 queue,
CsrBool eosp=FALSE;
CsrInt8 r =0;
CsrBool moreData = FALSE;
+ netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
- CsrUint8 allDeliveryEnabled = 0, dataAvailable = 0;
- netInterface_priv_t *interfacePriv;
- interfacePriv = priv->interfacePriv[interfaceTag];
- func_enter();
-
- /*Check U-APSD conditions if not met return from here*/
- if((staInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE)&&
- (staInfo->uapsdActive == TRUE)&&
- (!IS_DELIVERY_AND_TRIGGER_ENABLED(staInfo->powersaveMode[queue]))){
-
- unifi_trace(priv,UDBG4,"uf_send_buffered_data_from_queue : U-APSD active. %d :Queue NOT delivery enbaled.return %\n",queue);
+ unifi_trace(priv, UDBG2, "++uf_send_buffered_data_from_delivery_ac, active=%x\n", staInfo->uapsdActive);
+ if (queue > UNIFI_TRAFFIC_Q_VO)
+ {
return;
- }
+ }
+ while((buffered_pkt=dequeue_tx_data_pdu(priv, txList))) {
+ if((IS_DTIM_ACTIVE(interfacePriv->dtimActive,interfacePriv->multicastPduHostTag))) {
+ unifi_trace(priv, UDBG2, "uf_send_buffered_data_from_delivery_ac: DTIM Active, suspend UAPSD, staId: 0x%x\n",
+ staInfo->aid);
- while(!isRouterBufferEnabled(priv,queue) &&
- ((buffered_pkt=dequeue_tx_data_pdu(priv, txList))!=NULL)){
- if((IS_DTIM_ACTIVE(interfacePriv->dtimActive,interfacePriv->multicastPduHostTag))){
+ /* Once resume called, the U-APSD delivery operation will resume */
spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
- staInfo->uapsdSuspended = TRUE;
- staInfo->uapsdActive = FALSE;
+ staInfo->uspSuspend = TRUE;
spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
/* re-queueing the packet as DTIM started */
spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
list_add(&buffered_pkt->q,txList);
spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
- unifi_trace(priv, UDBG3, "%s: DTIM Active while UAPSD in progress for staId: 0x%x\n",__FUNCTION__,staInfo->aid);
break;
}
buffered_pkt->transmissionControl &=
- ~(TRANSMISSION_CONTROL_TRIGGER_MASK|TRANSMISSION_CONTROL_ESOP_MASK);
-
+ ~(TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK);
- if((staInfo->wmmOrQosEnabled == TRUE)&&(staInfo->uapsdActive == TRUE)){
- moreData = uf_is_more_data_for_delivery_ac(priv,staInfo,TRUE);
+ if((staInfo->wmmOrQosEnabled == TRUE)&&(staInfo->uapsdActive == TRUE)) {
buffered_pkt->transmissionControl = TRANSMISSION_CONTROL_TRIGGER_MASK;
- if(staInfo->noOfSpFramesSent == (staInfo->maxSpLength-1)){
- moreData = FALSE;
- }
-
- if(moreData == FALSE){
- eosp = TRUE;
- staInfo->uapsdActive = FALSE;
- staInfo->noOfSpFramesSent = FALSE;
- buffered_pkt->transmissionControl =
- (TRANSMISSION_CONTROL_TRIGGER_MASK|TRANSMISSION_CONTROL_ESOP_MASK);
+ /* Check All delivery enables Ac for more data, because caller of this
+ * function not aware about last packet
+ * (First check in moreData fetching helps in draining out Mgt frames Q)
+ */
+ moreData = (!list_empty(txList) || uf_is_more_data_for_usp_delivery(priv, staInfo, queue));
- /* Check if all AC's are Delivery Enabled */
- is_all_ac_deliver_enabled_and_moredata(staInfo, &allDeliveryEnabled, &dataAvailable);
- if ((allDeliveryEnabled && !dataAvailable)) {
- update_tim(priv,staInfo->aid,0,interfaceTag, staInfo->assignedHandle);
- }
- /* check the moer data for non delivery ac and update accordingly */
- else if(uf_is_more_data_for_non_delivery_ac(staInfo) ) {
- update_tim(priv,staInfo->aid,1,interfaceTag, staInfo->assignedHandle);
- }
- else if(!uf_is_more_data_for_non_delivery_ac(staInfo) ){
- unifi_trace(priv, UDBG3, "more data = NULL, set tim to 0 in uf_send_buffered_data_from_delivery_ac\n");
- update_tim(priv,staInfo->aid,0,interfaceTag, staInfo->assignedHandle);
- }
+ if(staInfo->noOfSpFramesSent == (staInfo->maxSpLength - 1)) {
+ moreData = FALSE;
+ }
- }
- }
- else
- {
- /*Non QoS and non U-APSD.*/
- eosp = FALSE;
- moreData = FALSE;
- unifi_warning(priv,"uf_send_buffered_data_from_delivery_ac :non U-APSD !!! \n");
+ if(moreData == FALSE) {
+ eosp = TRUE;
+ buffered_pkt->transmissionControl =
+ (TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK);
+ }
+ } else {
+ /* Non QoS and non U-APSD */
+ unifi_warning(priv, "uf_send_buffered_data_from_delivery_ac: non U-APSD !!! \n");
}
unifi_trace(priv,UDBG2,"uf_send_buffered_data_from_delivery_ac : MoreData:%d, EOSP:%d\n",moreData,eosp);
if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staInfo,moreData,eosp)) == -ENOSPC) {
- /* Enqueue at the head of the queue */
- spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
- list_add(&buffered_pkt->q,txList);
- spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
- priv->pausedStaHandle[queue]=(CsrUint8)(staInfo->assignedHandle);
- unifi_notice (priv," U-APSD: PDU sending failed .. no space for queue %d \n",queue);
- /*Break the loop for this queue.Try for next available Delivery enabled
- Queue*/
- break;
+
+ unifi_trace(priv, UDBG2, "uf_send_buffered_data_from_delivery_ac: UASPD suspended, ENOSPC in hipQ=%x\n", queue);
+
+ /* Once resume called, the U-APSD delivery operation will resume */
+ spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
+ staInfo->uspSuspend = TRUE;
+ spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
+
+ spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
+ list_add(&buffered_pkt->q,txList);
+ spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
+ priv->pausedStaHandle[queue]=(CsrUint8)(staInfo->assignedHandle);
+ break;
} else {
if(r){
/* the PDU failed where we can't do any thing so free the storage */
unifi_net_data_free(priv, &buffered_pkt->bulkdata);
}
-
kfree(buffered_pkt);
- if(staInfo->uapsdActive == TRUE){
- spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
- staInfo->noOfSpFramesSent = staInfo->noOfSpFramesSent + 1;
- if(staInfo->noOfSpFramesSent == staInfo->maxSpLength){
- staInfo->uapsdActive = FALSE;
- staInfo->noOfSpFramesSent = FALSE;
- spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
- break;
- }
+ spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
+ staInfo->noOfSpFramesSent++;
+ if((!moreData) || (staInfo->noOfSpFramesSent == staInfo->maxSpLength)) {
+ unifi_trace(priv, UDBG2, "uf_send_buffered_data_from_delivery_ac: Terminating USP\n");
+ staInfo->uapsdActive = FALSE;
+ staInfo->uspSuspend = FALSE;
+ staInfo->noOfSpFramesSent = 0;
spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
+ break;
}
+ spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
}
}
-
- func_exit();
-
+ unifi_trace(priv, UDBG2, "--uf_send_buffered_data_from_delivery_ac, active=%x\n", staInfo->uapsdActive);
}
void uf_send_buffered_data_from_ac(unifi_priv_t *priv,
((buffered_pkt=dequeue_tx_data_pdu(priv, txList))!=NULL)){
buffered_pkt->transmissionControl &=
- ~(TRANSMISSION_CONTROL_TRIGGER_MASK|TRANSMISSION_CONTROL_ESOP_MASK);
+ ~(TRANSMISSION_CONTROL_TRIGGER_MASK|TRANSMISSION_CONTROL_EOSP_MASK);
unifi_trace(priv,UDBG3,"uf_send_buffered_data_from_ac : MoreData:%d, EOSP:%d\n",moreData,eosp);
moreData = (!list_empty(&interfacePriv->genericMulticastOrBroadCastMgtFrames) ||
!list_empty(&interfacePriv->genericMulticastOrBroadCastFrames));
if(!moreData) {
- update_tim(priv,0,0,interfaceTag, 0XFFFFFFFF);
+ if (!interfacePriv->bcTimSetReqPendingFlag)
+ {
+ update_tim(priv,0,CSR_WIFI_TIM_RESET,interfaceTag, 0XFFFFFFFF);
+ }
+ else
+ {
+ /* Cache the TimSet value so that it will processed immidiatly after
+ * completing the current setTim Request
+ */
+ interfacePriv->bcTimSetReqQueued = CSR_WIFI_TIM_RESET;
+ unifi_trace(priv, UDBG2, "uf_send_buffered_frames : One more UpdateDTim Request(%d) Queued \n",
+ interfacePriv->bcTimSetReqQueued);
+ }
}
} else {
moreData = (!list_empty(&interfacePriv->genericMulticastOrBroadCastMgtFrames) ||
uf_send_buffered_data_from_ac(priv,staInfo, UNIFI_TRAFFIC_Q_VO, &staInfo->mgtFrames);
}
}
- else if((staInfo != NULL)&&(staInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE)
- &&(staInfo->uapsdActive == TRUE)&&(IS_DELIVERY_AND_TRIGGER_ENABLED(staInfo->powersaveMode[UNIFI_TRAFFIC_Q_VO]))){
-
-
- if(!list_empty(&staInfo->mgtFrames)){
- /*UNIFI_TRAFFIC_Q_VO is delivery enabled push the managment frames out*/
- uf_send_buffered_data_from_delivery_ac(priv, staInfo, UNIFI_TRAFFIC_Q_VO, &staInfo->mgtFrames);
-
- }
- }
if(isRouterBufferEnabled(priv,queue)) {
unifi_notice(priv,"uf_send_buffered_frames : No space Left for queue = %d\n",queue);
break;
}
}
-
-
/*push generic management frames out*/
-
- if(!list_empty(&interfacePriv->genericMgtFrames)){
-
- unifi_trace(priv,UDBG2,"uf_send_buffered_frames : trying generic mgt from queue=%d\n",queue);
- uf_send_buffered_data_from_ac(priv,staInfo, UNIFI_TRAFFIC_Q_VO, &interfacePriv->genericMgtFrames);
-
+ if(!list_empty(&interfacePriv->genericMgtFrames)) {
+ unifi_trace(priv,UDBG2,"uf_send_buffered_frames : trying generic mgt from queue=%d\n",queue);
+ uf_send_buffered_data_from_ac(priv,staInfo, UNIFI_TRAFFIC_Q_VO, &interfacePriv->genericMgtFrames);
}
-
}
staInfo = CsrWifiRouterCtrlGetStationRecordFromHandle(priv,startIndex,interfaceTag);
if(!staInfo) {
startIndex ++;
- if(startIndex >= UNIFI_MAX_CONNECTIONS){
+ if(startIndex >= UNIFI_MAX_CONNECTIONS) {
startIndex = 0;
}
continue;
} else if((staInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE)
- &&(staInfo->uapsdActive == FALSE)){
+ &&(staInfo->uapsdActive == FALSE)) {
startIndex ++;
- if(startIndex >= UNIFI_MAX_CONNECTIONS){
+ if(startIndex >= UNIFI_MAX_CONNECTIONS) {
startIndex = 0;
}
continue;
if((staInfo != NULL)&&(staInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_ACTIVE)
- &&(staInfo->uapsdActive == FALSE)){
-
- if(!list_empty(&staInfo->dataPdu[queue])){
+ &&(staInfo->uapsdActive == FALSE)) {
+ if(!list_empty(&staInfo->dataPdu[queue])) {
- /*Non-UAPSD case push the AC frames out*/
- uf_send_buffered_data_from_ac(priv, staInfo, queue, (&staInfo->dataPdu[queue]));
+ /*Non-UAPSD case push the AC frames out*/
+ uf_send_buffered_data_from_ac(priv, staInfo, queue, (&staInfo->dataPdu[queue]));
}
}
- else if((staInfo != NULL)&&(staInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE)
- &&(staInfo->uapsdActive == TRUE)&&(IS_DELIVERY_AND_TRIGGER_ENABLED(staInfo->powersaveMode[queue]))){
- if(!list_empty(&staInfo->dataPdu[queue])){
- uf_send_buffered_data_from_delivery_ac(priv, staInfo, queue, &staInfo->dataPdu[queue]);
- }
- }
-
startIndex ++;
- if(startIndex >= UNIFI_MAX_CONNECTIONS){
+ if(startIndex >= UNIFI_MAX_CONNECTIONS) {
startIndex = 0;
}
}
priv->pausedStaHandle[queue] = 0;
}
- /*U-APSD might have stopped because of pause.So restart it if U-APSD
- was active with any of the station*/
- for(startIndex= 0; startIndex < UNIFI_MAX_CONNECTIONS;startIndex++) {
- staInfo = CsrWifiRouterCtrlGetStationRecordFromHandle(priv,startIndex,interfaceTag);
- if(!staInfo ) {
- continue;
- } else if((staInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE)
- &&(staInfo->uapsdActive == TRUE)) {
-
- /*U-APSD Still active, it means trigger frame is received,so continue U-APSD by
- sending data from remaining delivery enabled queues*/
- uf_continue_uapsd(priv,staInfo);
- }
- }
+ /* U-APSD might have stopped because of ENOSPC in lib_hip (pause activity).
+ * So restart it if U-APSD was active with any of the station
+ */
+ unifi_trace(priv, UDBG4, "csrWifiHipSendBufferedFrames: UAPSD Resume Q=%x\n", queue);
+ resume_suspended_uapsd(priv, interfaceTag);
func_exit();
}
-CsrBool uf_is_more_data_for_delivery_ac(unifi_priv_t *priv,CsrWifiRouterCtrlStaInfo_t *staRecord,CsrBool mgtCheck)
-{
- CsrUint8 i;
-
- for(i=0;i<=3;i++)
- {
- if(((staRecord->powersaveMode[i]==CSR_WIFI_AC_DELIVERY_ONLY_ENABLE)
- ||(staRecord->powersaveMode[i]==CSR_WIFI_AC_TRIGGER_AND_DELIVERY_ENABLED))
- &&(!list_empty(&staRecord->dataPdu[i]))){
- unifi_trace(priv,UDBG2,"uf_is_more_data_for_delivery_ac: Data Available \n");
- return TRUE;
- }
- }
- if((mgtCheck == TRUE)&&(IS_DELIVERY_AND_TRIGGER_ENABLED(staRecord->powersaveMode[UNIFI_TRAFFIC_Q_VO]))
- &&(!list_empty(&staRecord->mgtFrames))){
-
- unifi_trace(priv,UDBG2,"uf_is_more_data_for_delivery_ac: Management Data Available \n");
-
- return TRUE;
- }
-
- unifi_trace(priv,UDBG2,"uf_is_more_data_for_delivery_ac: Data NOT Available \n");
- return FALSE;
-}
CsrBool uf_is_more_data_for_non_delivery_ac(CsrWifiRouterCtrlStaInfo_t *staRecord)
{
return 0;
}
-void uf_process_wmm_deliver_ac_uapsd(unifi_priv_t * priv,
- CsrWifiRouterCtrlStaInfo_t * srcStaInfo,
- CsrUint16 qosControl,
- CsrUint16 interfaceTag)
+
+/*
+ * ---------------------------------------------------------------------------
+ * uf_handle_uspframes_delivery
+ *
+ * This function takes care of handling USP session for peer, when
+ * -> trigger frame from peer
+ * -> suspended USP to be processed (resumed)
+ *
+ * NOTE: uf_send_buffered_data_from_delivery_ac() always called from this function, Dont
+ * make a direct call to uf_send_buffered_data_from_delivery_ac() from any other part of
+ * code
+ *
+ * Arguments:
+ * priv Pointer to device private context struct
+ * staInfo peer for which UAPSD to be scheduled
+ * interfaceTag virtual interface tag
+ * ---------------------------------------------------------------------------
+ */
+static void uf_handle_uspframes_delivery(unifi_priv_t * priv, CsrWifiRouterCtrlStaInfo_t *staInfo, CsrUint16 interfaceTag)
{
- CSR_PRIORITY priority;
CsrInt8 i;
- unifi_TrafficQueue priority_q;
+ CsrUint8 allDeliveryEnabled = 0, dataAvailable = 0;
+ netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
unsigned long lock_flags;
- func_enter();
-
- /* start the U-APSD operation only if it not active*/
- if(srcStaInfo->uapsdActive == FALSE){
- /*if recceived Frames trigger Frame and Devlivery enabled AC has data
- then transmit from High priorty delivery enabled AC*/
+ unifi_trace(priv, UDBG2, " ++ uf_handle_uspframes_delivery, uapsd active=%x, suspended?=%x\n",
+ staInfo->uapsdActive, staInfo->uspSuspend);
+ /* Check for Buffered frames according to priority order & deliver it
+ * 1. AC_VO delivery enable & Mgt frames available
+ * 2. Process remaining Ac's from order AC_VO to AC_BK
+ */
- priority = (CSR_PRIORITY)(qosControl & IEEE802_11_QC_TID_MASK);
-
- priority_q = unifi_frame_priority_to_queue((CSR_PRIORITY) priority);
-
- if((srcStaInfo->powersaveMode[priority_q]==CSR_WIFI_AC_TRIGGER_ONLY_ENABLED)
- ||(srcStaInfo->powersaveMode[priority_q]==CSR_WIFI_AC_TRIGGER_AND_DELIVERY_ENABLED)){
+ /* USP initiated by WMMPS enabled peer & SET the status flag to TRUE */
+ if (!staInfo->uspSuspend && staInfo->uapsdActive)
+ {
+ unifi_notice(priv, "uf_handle_uspframes_delivery: U-APSD already active! STA=%x:%x:%x:%x:%x:%x\n",
+ staInfo->peerMacAddress.a[0], staInfo->peerMacAddress.a[1],
+ staInfo->peerMacAddress.a[2], staInfo->peerMacAddress.a[3],
+ staInfo->peerMacAddress.a[4], staInfo->peerMacAddress.a[5]);
+ return;
+ }
- unifi_trace(priv, UDBG3, "uf_process_wmm_deliver_ac_uapsd starting U-APSD operations\n");
+ spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
+ staInfo->uapsdActive = TRUE;
+ staInfo->uspSuspend = FALSE;
+ spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
- /*Received Frame is trigger frame*/
- unifi_trace(priv, UDBG5, "uf_process_wmm_deliver_ac_uapsd : Received Frame is trigger frame %d\n",priority_q);
+ if(((staInfo->powersaveMode[UNIFI_TRAFFIC_Q_VO]==CSR_WIFI_AC_TRIGGER_AND_DELIVERY_ENABLED)||
+ (staInfo->powersaveMode[UNIFI_TRAFFIC_Q_VO]==CSR_WIFI_AC_DELIVERY_ONLY_ENABLE))
+ && (!list_empty(&staInfo->mgtFrames))) {
- if(((srcStaInfo->powersaveMode[UNIFI_TRAFFIC_Q_VO]==CSR_WIFI_AC_TRIGGER_AND_DELIVERY_ENABLED)||
- (srcStaInfo->powersaveMode[UNIFI_TRAFFIC_Q_VO]==CSR_WIFI_AC_DELIVERY_ONLY_ENABLE))
- &&(!list_empty(&srcStaInfo->mgtFrames))){
+ /* Management queue has data && UNIFI_TRAFFIC_Q_VO is delivery enable */
+ unifi_trace(priv, UDBG4, "uf_handle_uspframes_delivery: Sending buffered management frames\n");
+ uf_send_buffered_data_from_delivery_ac(priv, staInfo, UNIFI_TRAFFIC_Q_VO, &staInfo->mgtFrames);
+ }
- /*Trigger frame received and Data available in Delivery enabled AC
- or in Management queue when UNIFI_TRAFFIC_Q_VO is delivery enabled*/
+ if (!uf_is_more_data_for_delivery_ac(priv, staInfo)) {
+ /* All delivery enable AC's are empty, so QNULL to be sent to terminate the USP
+ * NOTE: If we have sent Mgt frame also, we must send QNULL followed to terminate USP
+ */
+ if (!staInfo->uspSuspend) {
spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
- srcStaInfo->uapsdActive = TRUE;
+ staInfo->uapsdActive = FALSE;
spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
- unifi_trace(priv, UDBG5, "uf_process_wmm_deliver_ac_uapsd : U-APSD ACTIVE and sending buffered mgt frames\n");
-
- /* uf_send_buffered_frames(priv, priority_q); */
- uf_send_buffered_data_from_delivery_ac(priv, srcStaInfo, UNIFI_TRAFFIC_Q_VO, &srcStaInfo->mgtFrames);
-
-
- /*This may happen because U-APSD was completed
- with previous AC transfer*/
-
- if(srcStaInfo->uapsdActive == FALSE){
- return;
- }
-
- }
-
-
- for(i=3;i>=0;i--){
-
- if(((srcStaInfo->powersaveMode[i]==CSR_WIFI_AC_DELIVERY_ONLY_ENABLE)
- ||(srcStaInfo->powersaveMode[i]==CSR_WIFI_AC_TRIGGER_AND_DELIVERY_ENABLED))
- &&(!list_empty(&srcStaInfo->dataPdu[i]))){
-
-
- /*Trigger frame received and Data available in Delivery enabled AC
- or in Management queue when UNIFI_TRAFFIC_Q_VO is delivery enabled*/
- spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
- srcStaInfo->uapsdActive = TRUE;
- spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
-
- unifi_trace(priv, UDBG5, "uf_process_wmm_deliver_ac_uapsd : U-APSD ACTIVE and sending buffered data frames\n");
-
- uf_send_buffered_data_from_delivery_ac(priv, srcStaInfo, i, &srcStaInfo->dataPdu[i]);
+ unifi_trace(priv, UDBG2, "uf_handle_uspframes_delivery: sending QNull for trigger\n");
+ uf_send_qos_null(priv, interfaceTag, staInfo->peerMacAddress.a, (CSR_PRIORITY) staInfo->triggerFramePriority, staInfo);
+ staInfo->triggerFramePriority = CSR_QOS_UP0;
+ } else {
+ unifi_trace(priv, UDBG2, "uf_handle_uspframes_delivery: MgtQ xfer suspended\n");
+ }
+ } else {
+ for(i = UNIFI_TRAFFIC_Q_VO; i >= UNIFI_TRAFFIC_Q_BK; i--) {
+ if(((staInfo->powersaveMode[i]==CSR_WIFI_AC_DELIVERY_ONLY_ENABLE)
+ ||(staInfo->powersaveMode[i]==CSR_WIFI_AC_TRIGGER_AND_DELIVERY_ENABLED))
+ && (!list_empty(&staInfo->dataPdu[i]))) {
+ /* Deliver Data according to AC priority (from VO to BK) as part of USP */
+ unifi_trace(priv, UDBG4, "uf_handle_uspframes_delivery: Buffered data frames from Queue (%d) for USP\n", i);
+ uf_send_buffered_data_from_delivery_ac(priv, staInfo, i, &staInfo->dataPdu[i]);
+ }
- /*This may happen because U-APSD was completed
- with previous AC transfer*/
+ if ((!staInfo->uapsdActive) ||
+ (staInfo->uspSuspend && IS_DTIM_ACTIVE(interfacePriv->dtimActive,interfacePriv->multicastPduHostTag))) {
+ /* If DTIM active found on one AC, No need to parse the remaining AC's
+ * as USP suspended. Break out of loop
+ */
+ unifi_trace(priv, UDBG2, "uf_handle_uspframes_delivery: suspend=%x, DTIM=%x, USP terminated=%s\n",
+ staInfo->uspSuspend, IS_DTIM_ACTIVE(interfacePriv->dtimActive,interfacePriv->multicastPduHostTag),
+ staInfo->uapsdActive?"NO":"YES");
+ break;
+ }
+ }
+ }
- if(srcStaInfo->uapsdActive == FALSE){
- return;
- }
+ /* Depending on the USP status, update the TIM accordingly for delivery enabled AC only
+ * (since we are not manipulating any Non-delivery list(AC))
+ */
+ is_all_ac_deliver_enabled_and_moredata(staInfo, &allDeliveryEnabled, &dataAvailable);
+ if ((allDeliveryEnabled && !dataAvailable)) {
+ if ((staInfo->timSet != CSR_WIFI_TIM_RESET) || (staInfo->timSet != CSR_WIFI_TIM_RESETTING)) {
+ staInfo->updateTimReqQueued = (CsrUint8) CSR_WIFI_TIM_RESET;
+ unifi_trace(priv, UDBG4, " --uf_handle_uspframes_delivery, UAPSD timset\n");
+ if (!staInfo->timRequestPendingFlag) {
+ update_tim(priv, staInfo->aid, 0, interfaceTag, staInfo->assignedHandle);
}
+ }
+ }
+ unifi_trace(priv, UDBG2, " --uf_handle_uspframes_delivery, uapsd active=%x, suspend?=%x\n",
+ staInfo->uapsdActive, staInfo->uspSuspend);
+}
- }
- if(srcStaInfo->uapsdActive == FALSE && !(uf_is_more_data_for_delivery_ac(priv,srcStaInfo,TRUE))){
- unifi_trace(priv, UDBG3, "uf_process_wmm_deliver_ac_uapsd : No buffer frames so sending QOS Null in response of trigger frame\n");
- uf_send_qos_null(priv,interfaceTag,srcStaInfo->peerMacAddress.a,priority,srcStaInfo);
- }
+void uf_process_wmm_deliver_ac_uapsd(unifi_priv_t * priv,
+ CsrWifiRouterCtrlStaInfo_t * srcStaInfo,
+ CsrUint16 qosControl,
+ CsrUint16 interfaceTag)
+{
+ CSR_PRIORITY priority;
+ unifi_TrafficQueue priority_q;
+ unsigned long lock_flags;
- }
+ unifi_trace(priv, UDBG2, "++uf_process_wmm_deliver_ac_uapsd: uapsdactive?=%x\n", srcStaInfo->uapsdActive);
+ /* If recceived Frames trigger Frame and Devlivery enabled AC has data
+ * then transmit from High priorty delivery enabled AC
+ */
+ priority = (CSR_PRIORITY)(qosControl & IEEE802_11_QC_TID_MASK);
+ priority_q = unifi_frame_priority_to_queue((CSR_PRIORITY) priority);
- }
+ if((srcStaInfo->powersaveMode[priority_q]==CSR_WIFI_AC_TRIGGER_ONLY_ENABLED)
+ ||(srcStaInfo->powersaveMode[priority_q]==CSR_WIFI_AC_TRIGGER_AND_DELIVERY_ENABLED)) {
+ spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
+ srcStaInfo->triggerFramePriority = priority;
+ spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
+ unifi_trace(priv, UDBG2, "uf_process_wmm_deliver_ac_uapsd: trigger frame, Begin U-APSD, triggerQ=%x\n", priority_q);
+ uf_handle_uspframes_delivery(priv, srcStaInfo, interfaceTag);
+ }
+ unifi_trace(priv, UDBG2, "--uf_process_wmm_deliver_ac_uapsd: uapsdactive?=%x\n", srcStaInfo->uapsdActive);
+}
- func_exit();
-}
void uf_send_qos_null(unifi_priv_t * priv,CsrUint16 interfaceTag, const CsrUint8 *da,CSR_PRIORITY priority,CsrWifiRouterCtrlStaInfo_t * srcStaInfo)
{
bulk_data_param_t bulkdata;
struct sk_buff *skb, *newSkb = NULL;
CsrWifiMacAddress peerAddress;
netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
- CSR_TRANSMISSION_CONTROL transmissionControl = (TRANSMISSION_CONTROL_ESOP_MASK | TRANSMISSION_CONTROL_TRIGGER_MASK);
+ CSR_TRANSMISSION_CONTROL transmissionControl = (TRANSMISSION_CONTROL_EOSP_MASK | TRANSMISSION_CONTROL_TRIGGER_MASK);
int r;
CSR_SIGNAL signal;
CsrUint32 priority_q;
!list_empty(&srcStaInfo->dataPdu[UNIFI_TRAFFIC_Q_CONTENTION]));
if(moreData && (srcStaInfo->timSet == CSR_WIFI_TIM_RESET)) {
unifi_trace(priv, UDBG3, "This condition should not occur\n");
- update_tim(priv,srcStaInfo->aid,1,interfaceTag, srcStaInfo->assignedHandle);
+ if (!srcStaInfo->timRequestPendingFlag){
+ update_tim(priv,srcStaInfo->aid,1,interfaceTag, srcStaInfo->assignedHandle);
+ }
+ else
+ {
+ /* Cache the TimSet value so that it will processed immidiatly after
+ * completing the current setTim Request
+ */
+ srcStaInfo->updateTimReqQueued = 1;
+ unifi_trace(priv, UDBG6, "update_tim : One more UpdateTim Request (Tim value:%d) Queued for AID %x\n", srcStaInfo->updateTimReqQueued,
+ srcStaInfo->aid);
+ }
+
}
} else {
CsrUint8 allDeliveryEnabled = 0, dataAvailable = 0;
moreData = (uf_is_more_data_for_non_delivery_ac(srcStaInfo) || (allDeliveryEnabled && dataAvailable));
if(moreData && (srcStaInfo->timSet == CSR_WIFI_TIM_RESET)) {
- update_tim(priv,srcStaInfo->aid,1,interfaceTag, srcStaInfo->assignedHandle);
+ if (!srcStaInfo->timRequestPendingFlag){
+ update_tim(priv,srcStaInfo->aid,1,interfaceTag, srcStaInfo->assignedHandle);
+ }
+ else
+ {
+ /* Cache the TimSet value so that it will processed immidiatly after
+ * completing the current setTim Request
+ */
+ srcStaInfo->updateTimReqQueued = 1;
+ unifi_trace(priv, UDBG6, "update_tim : One more UpdateTim Request (Tim value:%d) Queued for AID %x\n", srcStaInfo->updateTimReqQueued,
+ srcStaInfo->aid);
+ }
}
}
}
!list_empty(&staRecord->dataPdu[UNIFI_TRAFFIC_Q_VO]) ||
!list_empty(&staRecord->mgtFrames));
- buffered_pkt->transmissionControl |= (TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_ESOP_MASK);
+ buffered_pkt->transmissionControl |= (TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK);
if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staRecord,moreData,FALSE)) == -ENOSPC) {
/* Clear the trigger bit transmission control*/
- buffered_pkt->transmissionControl &= ~(TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_ESOP_MASK);
+ buffered_pkt->transmissionControl &= ~(TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK);
/* Enqueue at the head of the queue */
spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
list_add(&buffered_pkt->q, &staRecord->mgtFrames);
moreData = (!list_empty(&staRecord->dataPdu[UNIFI_TRAFFIC_Q_CONTENTION]) ||
!list_empty(&staRecord->dataPdu[UNIFI_TRAFFIC_Q_VO]));
- buffered_pkt->transmissionControl |= (TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_ESOP_MASK);
+ buffered_pkt->transmissionControl |= (TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK);
if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staRecord,moreData,FALSE)) == -ENOSPC) {
/* Clear the trigger bit transmission control*/
- buffered_pkt->transmissionControl &= ~(TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_ESOP_MASK);
+ buffered_pkt->transmissionControl &= ~(TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK);
/* Enqueue at the head of the queue */
spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
list_add(&buffered_pkt->q, &staRecord->dataPdu[UNIFI_TRAFFIC_Q_VO]);
buffered_pkt->transmissionControl |= TRANSMISSION_CONTROL_TRIGGER_MASK;
moreData = !list_empty(&staRecord->dataPdu[UNIFI_TRAFFIC_Q_CONTENTION]);
- buffered_pkt->transmissionControl |= (TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_ESOP_MASK);
+ buffered_pkt->transmissionControl |= (TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK);
if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staRecord,moreData,FALSE)) == -ENOSPC) {
/* Clear the trigger bit transmission control*/
- buffered_pkt->transmissionControl &= ~(TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_ESOP_MASK);
+ buffered_pkt->transmissionControl &= ~(TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK);
/* Enqueue at the head of the queue */
spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
list_add(&buffered_pkt->q, &staRecord->dataPdu[UNIFI_TRAFFIC_Q_CONTENTION]);
!list_empty(&staRecord->mgtFrames));
if(!moreData && (staRecord->timSet == CSR_WIFI_TIM_SET)) {
unifi_trace(priv, UDBG3, "more data = NULL, set tim to 0 in uf_process_ps_poll\n");
- update_tim(priv,staRecord->aid,0,interfaceTag, staRecord->assignedHandle);
+ if (!staRecord->timRequestPendingFlag){
+ update_tim(priv,staRecord->aid,0,interfaceTag, staRecord->assignedHandle);
+ }
+ else
+ {
+ /* Cache the TimSet value so that it will processed immidiatly after
+ * completing the current setTim Request
+ */
+ staRecord->updateTimReqQueued = 0;
+ unifi_trace(priv, UDBG6, "update_tim : One more UpdateTim Request (Tim value:%d) Queued for AID %x\n", staRecord->updateTimReqQueued,
+ staRecord->aid);
+ }
}
} else {
/*Send Data From Management Frames*/
/* Priority orders for delivering the buffered packets are
- * 1. UNIFI_TRAFFIC_Q_VO, if its non delivery enabled
- * 2. management frames
- * 3. Other access catagory frames which are non deliver enable
+ * 1. Deliver the Management frames if there
+ * 2. Other access catagory frames which are non deliver enable including UNIFI_TRAFFIC_Q_VO
+ * priority is from VO->BK
*/
/* Check if all AC's are Delivery Enabled */
return;
}
- if ((!IS_DELIVERY_ENABLED(staRecord->powersaveMode[UNIFI_TRAFFIC_Q_VO])) &&
- (!list_empty(&staRecord->dataPdu[UNIFI_TRAFFIC_Q_VO]) || !list_empty(&staRecord->mgtFrames))) {
- /* UNIFI_TRAFFIC_Q_VO is non delivery enabled, & check for packets are there to send from this AC */
- if((buffered_pkt=dequeue_tx_data_pdu(priv, &staRecord->dataPdu[UNIFI_TRAFFIC_Q_VO]))) {
- moreData = uf_is_more_data_for_non_delivery_ac(staRecord);
- buffered_pkt->transmissionControl |= (TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_ESOP_MASK);
-
- /* Last parameter is EOSP & its false always for PS-POLL processing */
- if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staRecord,moreData,FALSE)) == -ENOSPC) {
- /* Clear the trigger bit transmission control*/
- buffered_pkt->transmissionControl &= ~(TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_ESOP_MASK);
- /* Enqueue at the head of the queue */
- spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
- list_add(&buffered_pkt->q, &staRecord->dataPdu[UNIFI_TRAFFIC_Q_VO]);
- spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
- priv->pausedStaHandle[0]=(CsrUint8)(staRecord->assignedHandle);
- unifi_trace(priv, UDBG1, "(ENOSPC) PS-POLL received : PDU sending failed \n");
- } else {
- if(r){
- unifi_trace (priv, UDBG1, " HIP validation failure : PDU sending failed \n");
- /* the PDU failed where we can't do any thing so free the storage */
- unifi_net_data_free(priv, &buffered_pkt->bulkdata);
- }
- kfree(buffered_pkt);
- }
- } else if ((buffered_pkt=dequeue_tx_data_pdu(priv, &staRecord->mgtFrames))) {
+ if (!list_empty(&staRecord->mgtFrames)) {
+ if ((buffered_pkt=dequeue_tx_data_pdu(priv, &staRecord->mgtFrames))) {
/* We dont have packets in non delivery enabled UNIFI_TRAFFIC_Q_VO, So we are looking in management
* queue of the station record
*/
moreData = uf_is_more_data_for_non_delivery_ac(staRecord);
- buffered_pkt->transmissionControl |= (TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_ESOP_MASK);
+ buffered_pkt->transmissionControl |= (TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK);
/* Last parameter is EOSP & its false always for PS-POLL processing */
if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staRecord,moreData,FALSE)) == -ENOSPC) {
/* Clear the trigger bit transmission control*/
- buffered_pkt->transmissionControl &= ~(TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_ESOP_MASK);
+ buffered_pkt->transmissionControl &= ~(TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK);
/* Enqueue at the head of the queue */
spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
list_add(&buffered_pkt->q, &staRecord->mgtFrames);
}
kfree(buffered_pkt);
}
+ } else {
+ unifi_error(priv, "uf_process_ps_poll: Mgt frame list empty!! \n");
}
+
} else {
CsrInt8 i;
- /* We dont have buffered packet in UNIFI_TRAFFIC_Q_VO & mangement frame queue (1 & 2 failed), So proceed with 3 condition
- * UNIFI_TRAFFIC_Q_VO is taken care so start with i index = 2
+ /* We dont have buffered packet in mangement frame queue (1 failed), So proceed with condition 2
+ * UNIFI_TRAFFIC_Q_VO -> VI -> BE -> BK
*/
- for(i= 2; i>=0; i--) {
+ for(i= 3; i>=0; i--) {
if (!IS_DELIVERY_ENABLED(staRecord->powersaveMode[i])) {
/* Send One packet, if queue is NULL then continue */
if((buffered_pkt=dequeue_tx_data_pdu(priv, &staRecord->dataPdu[i]))) {
moreData = uf_is_more_data_for_non_delivery_ac(staRecord);
- buffered_pkt->transmissionControl |= (TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_ESOP_MASK);
+ buffered_pkt->transmissionControl |= (TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK);
/* Last parameter is EOSP & its false always for PS-POLL processing */
if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staRecord,moreData,FALSE)) == -ENOSPC) {
/* Clear the trigger bit transmission control*/
- buffered_pkt->transmissionControl &= ~(TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_ESOP_MASK);
+ buffered_pkt->transmissionControl &= ~(TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK);
/* Enqueue at the head of the queue */
spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
list_add(&buffered_pkt->q, &staRecord->dataPdu[i]);
moreData = (uf_is_more_data_for_non_delivery_ac(staRecord) || (allDeliveryEnabled && dataAvailable));
if(!moreData && (staRecord->timSet == CSR_WIFI_TIM_SET)) {
unifi_trace(priv, UDBG3, "more data = NULL, set tim to 0 in uf_process_ps_poll\n");
- update_tim(priv,staRecord->aid,0,interfaceTag, staRecord->assignedHandle);
+ if (!staRecord->timRequestPendingFlag){
+ update_tim(priv,staRecord->aid,0,interfaceTag, staRecord->assignedHandle);
+ }
+ else
+ {
+ /* Cache the TimSet value so that it will processed immidiatly after
+ * completing the current setTim Request
+ */
+ staRecord->updateTimReqQueued = 0;
+ unifi_trace(priv, UDBG6, "update_tim : One more UpdateTim Request (Tim value:%d) Queued for AID %x\n", staRecord->updateTimReqQueued,
+ staRecord->aid);
+ }
+
}
}
}
spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
}
-void uf_flush_maPktlist(unifi_priv_t * priv, struct list_head * list)
-{
- struct list_head *listHeadMaPktreq,*placeHolderMaPktreq;
- maPktReqList_t *maPktreq;
- unsigned long lock_flags;
- unifi_trace(priv, UDBG5, "entering the uf_flush_maPktlist \n");
-
- spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
- /* go through list, delete & free memory */
- list_for_each_safe(listHeadMaPktreq, placeHolderMaPktreq, list) {
- maPktreq = list_entry(listHeadMaPktreq, maPktReqList_t, q);
-
- if(!maPktreq) {
- unifi_error(priv, "entry should exists, otherwise crashes (bug)\n");
- }
- /* free the allocated memory */
- dev_kfree_skb(maPktreq->skb);
- list_del(listHeadMaPktreq);
- kfree(maPktreq);
- maPktreq = NULL;
-
- }
- spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
-}
tx_buffered_packets_t *dequeue_tx_data_pdu(unifi_priv_t *priv, struct list_head *txList)
{
/* dequeue the tx data packets from the appropriate queue */
while(!isRouterBufferEnabled(priv,3) &&
((buffered_pkt=dequeue_tx_data_pdu(priv,&interfacePriv->genericMgtFrames))!=NULL)) {
buffered_pkt->transmissionControl &=
- ~(TRANSMISSION_CONTROL_TRIGGER_MASK|TRANSMISSION_CONTROL_ESOP_MASK);
+ ~(TRANSMISSION_CONTROL_TRIGGER_MASK|TRANSMISSION_CONTROL_EOSP_MASK);
if((r=frame_and_send_queued_pdu(priv,buffered_pkt,NULL,0,FALSE)) == -ENOSPC) {
/* Enqueue at the head of the queue */
spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
if (staInfo && (staInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_ACTIVE)) {
while((( TRUE == hipslotFree[3] ) && (buffered_pkt=dequeue_tx_data_pdu(priv, &staInfo->mgtFrames)))) {
buffered_pkt->transmissionControl &=
- ~(TRANSMISSION_CONTROL_TRIGGER_MASK|TRANSMISSION_CONTROL_ESOP_MASK);
+ ~(TRANSMISSION_CONTROL_TRIGGER_MASK|TRANSMISSION_CONTROL_EOSP_MASK);
if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staInfo,0,FALSE)) == -ENOSPC) {
unifi_trace(priv, UDBG3, "(ENOSPC) in resume_unicast_buffered_frames:: hip slots are full for voice queue\n");
/* Enqueue at the head of the queue */
while((buffered_pkt=dequeue_tx_data_pdu(priv, &staInfo->dataPdu[j]))) {
buffered_pkt->transmissionControl &=
- ~(TRANSMISSION_CONTROL_TRIGGER_MASK|TRANSMISSION_CONTROL_ESOP_MASK);
+ ~(TRANSMISSION_CONTROL_TRIGGER_MASK|TRANSMISSION_CONTROL_EOSP_MASK);
if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staInfo,0,FALSE)) == -ENOSPC) {
/* Enqueue at the head of the queue */
spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
list_for_each_safe(listHead, placeHolder, &interfacePriv->genericMulticastOrBroadCastFrames) {
tx_q_item = list_entry(listHead, tx_buffered_packets_t, q);
- tx_q_item->transmissionControl |= TRANSMISSION_CONTROL_ESOP_MASK;
+ tx_q_item->transmissionControl |= TRANSMISSION_CONTROL_EOSP_MASK;
tx_q_item->transmissionControl = (tx_q_item->transmissionControl & ~(CSR_NO_CONFIRM_REQUIRED));
unifi_trace(priv, UDBG1,"updating eosp for list Head hostTag:= 0x%x ",tx_q_item->hostTag);
break;
}
func_exit();
}
+
+/*
+ * ---------------------------------------------------------------------------
+ * resume_suspended_uapsd
+ *
+ * This function takes care processing packets of Unscheduled Service Period,
+ * which been suspended earlier due to DTIM/HIP ENOSPC scenarios
+ *
+ * Arguments:
+ * priv Pointer to device private context struct
+ * interfaceTag For which resume should happen
+ * ---------------------------------------------------------------------------
+ */
void resume_suspended_uapsd(unifi_priv_t* priv,CsrUint16 interfaceTag)
{
CsrUint8 startIndex;
CsrWifiRouterCtrlStaInfo_t * staInfo = NULL;
- unsigned long lock_flags;
- /*U-APSD might have stopped because of multicast. So restart it if U-APSD
- was active with any of the station*/
+ unsigned long lock_flags;
+
+ unifi_trace(priv, UDBG2, "++resume_suspended_uapsd: \n");
for(startIndex= 0; startIndex < UNIFI_MAX_CONNECTIONS;startIndex++) {
staInfo = CsrWifiRouterCtrlGetStationRecordFromHandle(priv,startIndex,interfaceTag);
- if(!staInfo ) {
+
+ if(!staInfo || !staInfo->wmmOrQosEnabled) {
continue;
} else if((staInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE)
- &&(staInfo->uapsdSuspended == TRUE)) {
-
- /*U-APSD Still active, it means trigger frame is received,so continue U-APSD by
- sending data from remaining delivery enabled queues*/
- spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
- staInfo->uapsdActive = TRUE;
- staInfo->uapsdSuspended = FALSE;
- spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
- uf_continue_uapsd(priv,staInfo);
- }
- }
-
-}
-void uf_store_directed_ma_packet_referenece(unifi_priv_t *priv, bulk_data_param_t *bulkdata,
- CSR_SIGNAL *sigptr, CsrUint32 alignOffset)
-{
-
- maPktReqList_t *maPktreq = NULL;
- CSR_MA_PACKET_REQUEST *req = &sigptr->u.MaPacketRequest;
- CsrWifiRouterCtrlStaInfo_t *staRecord = NULL;
- CsrUint16 frmCtrl,interfaceTag = 0;
- const CsrUint8* macHdrLocation;
- struct sk_buff *skb ;
- unsigned long lock_flags;
- netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
- CsrUint8 *sigbuffer;
- CsrUint8 frameType = 0;
- func_enter();
-
- if(bulkdata == NULL || (0 == bulkdata->d[0].data_length )){
- unifi_trace (priv, UDBG3, "uf_store_directed_ma_packet_referenece:bulk data NULL \n");
- func_exit();
- return;
- }
- macHdrLocation = bulkdata->d[0].os_data_ptr;
- skb = (struct sk_buff*)bulkdata->d[0].os_net_buf_ptr;
- /* fectch the frame control value from mac header */
- frmCtrl = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(macHdrLocation);
-
- /* Processing done according to Frame/Packet type */
- frameType = ((frmCtrl & 0x000c) >> FRAME_CONTROL_TYPE_FIELD_OFFSET);
-
- if( (((frmCtrl & 0xff) == IEEE802_11_FC_TYPE_QOS_NULL) ||
- ((frmCtrl & 0xff) == IEEE802_11_FC_TYPE_NULL ) ) ||
- ( IEEE802_11_FRAMETYPE_MANAGEMENT== frameType)){
-
- /* if packet is NULL or Qos Null no need of retransmit so dont queue it*/
- unifi_trace (priv, UDBG3, "uf_store_directed_ma_packet_referenece: NULL data Pkt or mgmt\n");
- func_exit();
- return;
- }
-
- /* fetch the station record for corresponding peer mac address */
- if ((staRecord = CsrWifiRouterCtrlGetStationRecordFromPeerMacAddress(priv, req->Ra.x, interfaceTag))) {
- maPktreq = (maPktReqList_t*)kmalloc(sizeof(maPktReqList_t),GFP_ATOMIC);
- if(maPktreq == NULL){
- unifi_error(priv,
- "uf_store_directed_ma_packet_referenece :: Failed to allocate %d byter for maPktreq\n",
- sizeof(maPktReqList_t));
- func_exit();
- return;
+ &&staInfo->uapsdActive && staInfo->uspSuspend) {
+ /* U-APSD Still active & previously suspended either ENOSPC of FH queues OR
+ * due to DTIM activity
+ */
+ uf_handle_uspframes_delivery(priv, staInfo, interfaceTag);
+ } else {
+ unifi_trace(priv, UDBG2, "resume_suspended_uapsd: PS state=%x, uapsdActive?=%x, suspend?=%x\n",
+ staInfo->currentPeerState, staInfo->uapsdActive, staInfo->uspSuspend);
+ if (staInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_ACTIVE)
+ {
+ spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
+ staInfo->uapsdActive = FALSE;
+ staInfo->uspSuspend = FALSE;
+ spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
+ }
}
}
-
- /* staRecord not present that means packet is multicast or generic mgmt so no need to queue it */
- else{
- unifi_trace (priv, UDBG3, "uf_store_directed_ma_packet_referenece: multicast pkt \n");
- func_exit();
- return ;
- }
-
- /* disbale preemption */
- spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
- INIT_LIST_HEAD(&maPktreq->q);
- maPktreq->staHandler = staRecord->assignedHandle;
- memcpy(&maPktreq->signal,sigptr,sizeof(CSR_SIGNAL_PRIMITIVE_HEADER) + sizeof(CSR_MA_PACKET_REQUEST));
- sigbuffer = (CsrUint8*)&maPktreq->signal;
- sigbuffer[SIZEOF_SIGNAL_HEADER + 1] = alignOffset;
- maPktreq->skb = skb_get(skb);
- maPktreq->hostTag = req->HostTag;
- maPktreq->jiffeTime = jiffies;
- list_add_tail(&maPktreq->q,&interfacePriv->directedMaPktReq);
-
- spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
- func_exit();
-
+ unifi_trace(priv, UDBG2, "--resume_suspended_uapsd:\n");
}
#endif
#include <linux/fs.h>
+#ifdef ANDROID_BUILD
+#include <linux/wakelock.h>
+#endif
+
#include "csr_wifi_hip_unifi.h"
#include "csr_wifi_hip_unifi_udi.h"
#include "csr_wifi_router_lib.h"
#include "unifi_wext.h"
#endif
+#ifdef ANDROID_BUILD
+extern struct wake_lock unifi_sdio_wake_lock;
+#endif
+
#include "unifi_clients.h"
#include "unifi_sme.h"
#endif
-#undef COMPARE_HOST_TAG_TO_ENQUEUE
-#define COMPARE_HOST_TAG_TO_ENQUEUE(tx_q_item_hosttag,maPktHostTag) \
- if(tx_q_item_hosttag > maPktHostTag){ \
- locationFound = TRUE; \
- ii++; \
- break; \
- } \
- ii++; \
-
-
/* The device major number to use when registering the udi driver */
#define UNIFI_NAME "unifi"
+/*
+ * MAX_UNIFI_DEVS defines the maximum number of UniFi devices that can be present.
+ * This number should be set to the number of SDIO slots supported by the SDIO
+ * host controller on the platform.
+ * Note: If MAX_UNIFI_DEVS value changes, fw_init[] needs to be corrected in drv.c
+ */
#define MAX_UNIFI_DEVS 2
/* 802.11 Mac header offsets */
#define IEEE802_11_QC_TID_MASK 0x0f
#define IEEE802_11_QC_A_MSDU_PRESENT 0x80
+#if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_QOSCTRL_MIC_WORKAROUND))
+#define IEEE802_11_QC_NON_TID_BITS_MASK 0xFFF0
+#endif
+
#define CSR_WIFI_EAPOL_M4_HOST_TAG 0x50000000
#define IEEE802_11_DATA_FRAME_MAC_HEADER_SIZE 36
#define MAX_ACCESS_CATOGORY 4
#define STA_INACTIVE_DETECTION_TIMER_INTERVAL 30 /* in seconds */
#define STA_INACTIVE_TIMEOUT_VAL 120*1000*1000 /* 120 seconds */
+/* Test for modes requiring AP firmware patch */
+#define CSR_WIFI_HIP_IS_AP_FW(mode) ((((mode) == CSR_WIFI_ROUTER_CTRL_MODE_AP) || \
+ ((mode) == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO)) ? TRUE : FALSE)
/* Defines used in beacon filtering in case of P2P */
#define CSR_WIFI_P2P_WILDCARD_SSID_LENGTH 0x7
extern int coredump_max;
extern int run_bh_once;
extern int bh_priority;
+#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
+extern int log_hip_signals;
+#endif
struct dlpriv {
const unsigned char *dl_data;
CsrTime lastActivity;
/* during m/c transmission sp suspended */
- CsrBool uapsdSuspended;
+ CsrBool uspSuspend;
+ CSR_PRIORITY triggerFramePriority;
#endif
CsrWifiRouterCtrlPeerStatus currentPeerState;
struct list_head dataPdu[MAX_ACCESS_CATOGORY];
#define CSR_WIFI_TIM_RESETTING 2
#define CSR_WIFI_TIM_SETTING 3
+ CsrBool timRequestPendingFlag;
+ CsrUint8 updateTimReqQueued;
CsrUint16 noOfPktQueued;
}CsrWifiRouterCtrlStaInfo_t;
/* Spinlock to protect M4 data */
spinlock_t m4_lock;
- /* Spinlock to protect BA RX data */
- spinlock_t ba_lock;
+ /* Mutex to protect BA RX data */
+ struct semaphore ba_mutex;
+
+#if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION))
+ /* Spinlock to protect the WAPI data */
+ spinlock_t wapi_lock;
+#endif
+
#ifndef ALLOW_Q_PAUSE
/* Array to indicate if a particular Tx queue is paused, this may not be
* required in a multiqueue implementation since we can directly stop kernel
CsrUint32 rxUdpThroughput;
CsrUint32 txUdpThroughput;
-
+#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
+ /*Set if multicast KeyID = 1*/
CsrUint8 wapi_multicast_filter;
+ /*Set if unicast KeyID = 1*/
CsrUint8 wapi_unicast_filter;
CsrUint8 wapi_unicast_queued_pkt_filter;
+#ifdef CSR_WIFI_SECURITY_WAPI_QOSCTRL_MIC_WORKAROUND
+ CsrBool isWapiConnection;
+#endif
+#endif
+
+#ifdef CSR_WIFI_SPLIT_PATCH
+ CsrWifiRouterCtrlModeSetReq pending_mode_set;
+#endif
+
+ CsrBool cmanrTestMode;
+ CSR_RATE cmanrTestModeTransmitRate;
+
};
typedef struct {
CsrUint8 ba_complete_index;
CsrUint8 queueEnabled[UNIFI_NO_OF_TX_QS];
struct work_struct send_m4_ready_task;
+#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
+ struct work_struct send_pkt_to_encrypt;
+#endif
struct net_device_stats stats;
CsrUint8 interfaceMode;
CsrBool protect;
struct list_head genericMgtFrames;
struct list_head genericMulticastOrBroadCastFrames;
struct list_head genericMulticastOrBroadCastMgtFrames;
- struct list_head directedMaPktReq;
/* Timer for detecting station inactivity */
struct timer_list sta_activity_check_timer;
/* Buffered M4 signal to take care of WPA race condition */
CSR_SIGNAL m4_signal;
bulk_data_desc_t m4_bulk_data;
+
+#if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION))
+ /* Buffered WAPI Unicast MA Packet Request for encryption in Sme */
+ CSR_SIGNAL wapi_unicast_ma_pkt_sig;
+ bulk_data_desc_t wapi_unicast_bulk_data;
+#endif
+
/* This should be removed and m4_hostTag should be used for checking*/
CsrBool m4_sent;
CSR_CLIENT_TAG m4_hostTag;
CsrBool intraBssEnabled;
CsrUint32 multicastPduHostTag; /* Used to set the tim after getting
a confirm for it */
+ CsrBool bcTimSet;
+ CsrBool bcTimSetReqPendingFlag;
+ CsrBool bcTimSetReqQueued;
} netInterface_priv_t;
-typedef struct maPktReqList{
- struct list_head q;
- struct sk_buff *skb;
- CSR_SIGNAL signal;
- CSR_CLIENT_TAG hostTag;
- CsrUint32 staHandler;
- unsigned long jiffeTime;
-}maPktReqList_t;
-
#ifndef ALLOW_Q_PAUSE
#define net_is_tx_q_paused(priv, q) (priv->tx_q_paused_flag[q])
#define net_tx_q_unpause(priv, q) (priv->tx_q_paused_flag[q] = 0)
bulk_data_param_t *bulkdata,
CsrUint8 macHeaderLengthInBytes);
CsrBool uf_is_more_data_for_non_delivery_ac(CsrWifiRouterCtrlStaInfo_t *staRecord);
-CsrBool uf_is_more_data_for_delivery_ac(unifi_priv_t *priv,CsrWifiRouterCtrlStaInfo_t *staRecord,CsrBool mgtCheck);
void uf_process_wmm_deliver_ac_uapsd ( unifi_priv_t * priv,
CsrWifiRouterCtrlStaInfo_t * srcStaInfo,
CsrUint16 qosControl,
void uf_continue_uapsd(unifi_priv_t *priv, CsrWifiRouterCtrlStaInfo_t * staInfo);
void uf_send_qos_null(unifi_priv_t * priv,CsrUint16 interfaceTag, const CsrUint8 *da,CSR_PRIORITY priority,CsrWifiRouterCtrlStaInfo_t * srcStaInfo);
void uf_send_nulldata(unifi_priv_t * priv,CsrUint16 interfaceTag, const CsrUint8 *da,CSR_PRIORITY priority,CsrWifiRouterCtrlStaInfo_t * srcStaInfo);
-void uf_store_directed_ma_packet_referenece(unifi_priv_t *priv, bulk_data_param_t *bulkdata,CSR_SIGNAL *sigptr,CsrUint32 alignOffset);
netInterface_priv_t *interfacePriv,
struct list_head *buffered_frames_list);
void uf_flush_list(unifi_priv_t * priv, struct list_head * list);
-void uf_flush_maPktlist(unifi_priv_t * priv, struct list_head * list);
tx_buffered_packets_t *dequeue_tx_data_pdu(unifi_priv_t *priv, struct list_head *txList);
void resume_unicast_buffered_frames(unifi_priv_t *priv, CsrUint16 interfaceTag);
void update_eosp_to_head_of_broadcast_list_head(unifi_priv_t *priv,CsrUint16 interfaceTag);
CsrWifiMacAddress source_address,
int indicate, CsrUint16 interfaceTag);
+#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
+int uf_register_hip_offline_debug(unifi_priv_t *priv);
+int uf_unregister_hip_offline_debug(unifi_priv_t *priv);
+#endif
+
/*
* inet.c
*/
{
unifi_cfg_power_t cfg_power;
int rc;
+ int wol;
if (get_user(cfg_power, (unifi_cfg_power_t*)(((unifi_cfg_command_t*)arg) + 1))) {
unifi_error(priv, "UNIFI_CFG: Failed to get the argument\n");
switch (cfg_power) {
case UNIFI_CFG_POWER_OFF:
+ priv->wol_suspend = (enable_wol == UNIFI_WOL_OFF) ? FALSE : TRUE;
rc = sme_sys_suspend(priv);
if (rc) {
return rc;
}
break;
case UNIFI_CFG_POWER_ON:
+ wol = priv->wol_suspend;
rc = sme_sys_resume(priv);
if (rc) {
return rc;
}
+ if (wol) {
+ /* Kick the BH to ensure pending transfers are handled when
+ * a suspend happened with card powered.
+ */
+ unifi_send_signal(priv->card, NULL, 0, NULL);
+ }
break;
default:
unifi_error(priv, "WIFI POWER: Unknown value.\n");
supportedRates[i++]=0x8b;
supportedRates[i++]=0x96;
} else if(n) {
+ /* For some strange reasons WiFi stack needs both b and g rates*/
supportedRates[i++]=0x02;
supportedRates[i++]=0x04;
supportedRates[i++]=0x0b;
supportedRates[i++]=0x16;
+ supportedRates[i++]=0x0c;
+ supportedRates[i++]=0x12;
+ supportedRates[i++]=0x18;
+ supportedRates[i++]=0x24;
+ supportedRates[i++]=0x30;
+ supportedRates[i++]=0x48;
+ supportedRates[i++]=0x60;
+ supportedRates[i++]=0x6c;
}
if(g) {
if(!b) {
} /* uf_send_m4_ready_wq() */
+#if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION))
+/*
+ * ---------------------------------------------------------------------------
+ * uf_send_pkt_to_encrypt
+ *
+ * Deferred work queue function to send the WAPI data pkts to SME when unicast KeyId = 1
+ * These are done in a deferred work queue for two reasons:
+ * - the CsrWifiRouterCtrl...Send() functions are not safe for atomic context
+ * - we want to load the main driver data path as lightly as possible
+ *
+ * Arguments:
+ * work Pointer to work queue item.
+ *
+ * Returns:
+ * None.
+ * ---------------------------------------------------------------------------
+ */
+void uf_send_pkt_to_encrypt(struct work_struct *work)
+{
+ netInterface_priv_t *interfacePriv = container_of(work, netInterface_priv_t, send_pkt_to_encrypt);
+ CsrUint16 interfaceTag = interfacePriv->InterfaceTag;
+ unifi_priv_t *priv = interfacePriv->privPtr;
+
+ CsrUint32 pktBulkDataLength;
+ CsrUint8 *pktBulkData;
+ unsigned long flags;
+
+ if (interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_STA) {
+
+ func_enter();
+
+ pktBulkDataLength = interfacePriv->wapi_unicast_bulk_data.data_length;
+
+ if (pktBulkDataLength > 0) {
+ pktBulkData = (CsrUint8 *)CsrPmemAlloc(pktBulkDataLength);
+ CsrMemSet(pktBulkData, 0, pktBulkDataLength);
+ } else {
+ unifi_error(priv, "uf_send_pkt_to_encrypt() : invalid buffer\n");
+ return;
+ }
+
+ spin_lock_irqsave(&priv->wapi_lock, flags);
+ /* Copy over the MA PKT REQ bulk data */
+ CsrMemCpy(pktBulkData, (CsrUint8*)interfacePriv->wapi_unicast_bulk_data.os_data_ptr, pktBulkDataLength);
+ /* Free any bulk data buffers allocated for the WAPI Data pkt */
+ unifi_net_data_free(priv, &interfacePriv->wapi_unicast_bulk_data);
+ interfacePriv->wapi_unicast_bulk_data.net_buf_length = 0;
+ interfacePriv->wapi_unicast_bulk_data.data_length = 0;
+ interfacePriv->wapi_unicast_bulk_data.os_data_ptr = interfacePriv->wapi_unicast_bulk_data.os_net_buf_ptr = NULL;
+ spin_unlock_irqrestore(&priv->wapi_lock, flags);
+
+ CsrWifiRouterCtrlWapiUnicastTxEncryptIndSend(priv->CSR_WIFI_SME_IFACEQUEUE, 0, interfaceTag, pktBulkDataLength, pktBulkData);
+ unifi_trace(priv, UDBG1, "WapiUnicastTxEncryptInd sent to SME\n");
+
+ CsrPmemFree(pktBulkData); /* Would have been copied over by the SME Handler */
+
+ func_exit();
+ } else {
+ unifi_warning(priv, "uf_send_pkt_to_encrypt() is NOT applicable for interface mode - %d\n",interfacePriv->interfaceMode);
+ }
+}/* uf_send_pkt_to_encrypt() */
+#endif
SME_REQUEST_PENDING,
SME_REQUEST_RECEIVED,
SME_REQUEST_TIMEDOUT,
+ SME_REQUEST_CANCELLED,
};
/* Structure to hold a UDI logged signal */
#endif
void uf_sme_complete_request(unifi_priv_t *priv, CsrResult reply_status, const char *func);
+void uf_sme_cancel_request(unifi_priv_t *priv, CsrResult reply_status);
/*
*/
void uf_send_m4_ready_wq(struct work_struct *work);
+#if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION))
+/*
+ * To send data pkt to Sme for encryption
+ */
+void uf_send_pkt_to_encrypt(struct work_struct *work);
+#endif
+
int sme_mgt_power_config_set(unifi_priv_t *priv, CsrWifiSmePowerConfig *powerConfig);
int sme_mgt_power_config_get(unifi_priv_t *priv, CsrWifiSmePowerConfig *powerConfig);
int sme_mgt_host_config_set(unifi_priv_t *priv, CsrWifiSmeHostConfig *hostConfig);
-typedef enum unifi_putest_command {
- UNIFI_PUTEST_START,
- UNIFI_PUTEST_STOP,
- UNIFI_PUTEST_SET_SDIO_CLOCK,
- UNIFI_PUTEST_CMD52_READ,
- UNIFI_PUTEST_CMD52_WRITE,
- UNIFI_PUTEST_DL_FW,
- UNIFI_PUTEST_DL_FW_BUFF,
- UNIFI_PUTEST_CMD52_BLOCK_READ,
- UNIFI_PUTEST_COREDUMP_PREPARE,
- UNIFI_PUTEST_GP_READ16,
- UNIFI_PUTEST_GP_WRITE16
-
-} unifi_putest_command_t;
+typedef CsrUint8 unifi_putest_command_t;
+
+#define UNIFI_PUTEST_START 0
+#define UNIFI_PUTEST_STOP 1
+#define UNIFI_PUTEST_SET_SDIO_CLOCK 2
+#define UNIFI_PUTEST_CMD52_READ 3
+#define UNIFI_PUTEST_CMD52_WRITE 4
+#define UNIFI_PUTEST_DL_FW 5
+#define UNIFI_PUTEST_DL_FW_BUFF 6
+#define UNIFI_PUTEST_CMD52_BLOCK_READ 7
+#define UNIFI_PUTEST_COREDUMP_PREPARE 8
+#define UNIFI_PUTEST_GP_READ16 9
+#define UNIFI_PUTEST_GP_WRITE16 10
struct unifi_putest_cmd52 {