aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/staging/csr/csr_framework_ext.c35
-rw-r--r--drivers/staging/csr/csr_types.h1
-rw-r--r--drivers/staging/csr/csr_util.c4
-rw-r--r--drivers/staging/csr/csr_util.h45
-rw-r--r--drivers/staging/csr/csr_wifi_common.h2
-rw-r--r--drivers/staging/csr/csr_wifi_hip_card.h11
-rw-r--r--drivers/staging/csr/csr_wifi_hip_card_sdio.c85
-rw-r--r--drivers/staging/csr/csr_wifi_hip_card_sdio_intr.c40
-rw-r--r--drivers/staging/csr/csr_wifi_hip_card_sdio_mem.c4
-rw-r--r--drivers/staging/csr/csr_wifi_hip_download.c6
-rw-r--r--drivers/staging/csr/csr_wifi_hip_dump.c6
-rw-r--r--drivers/staging/csr/csr_wifi_hip_ta_sampling.c30
-rw-r--r--drivers/staging/csr/csr_wifi_hip_unifi.h32
-rw-r--r--drivers/staging/csr/csr_wifi_hip_xbv.c12
-rw-r--r--drivers/staging/csr/csr_wifi_nme_ap_lib.h3
-rw-r--r--drivers/staging/csr/csr_wifi_nme_ap_prim.h3
-rw-r--r--drivers/staging/csr/csr_wifi_router_converter_init.c10
-rw-r--r--drivers/staging/csr/csr_wifi_router_ctrl_converter_init.c18
-rw-r--r--drivers/staging/csr/csr_wifi_router_ctrl_free_downstream_contents.c20
-rw-r--r--drivers/staging/csr/csr_wifi_router_ctrl_free_upstream_contents.c13
-rw-r--r--drivers/staging/csr/csr_wifi_router_ctrl_lib.h226
-rw-r--r--drivers/staging/csr/csr_wifi_router_ctrl_prim.h130
-rw-r--r--drivers/staging/csr/csr_wifi_router_ctrl_sef.c12
-rw-r--r--drivers/staging/csr/csr_wifi_router_ctrl_sef.h4
-rw-r--r--drivers/staging/csr/csr_wifi_router_ctrl_serialize.c261
-rw-r--r--drivers/staging/csr/csr_wifi_router_ctrl_serialize.h58
-rw-r--r--drivers/staging/csr/csr_wifi_sme_ap_lib.h131
-rw-r--r--drivers/staging/csr/csr_wifi_sme_ap_prim.h141
-rw-r--r--drivers/staging/csr/csr_wifi_sme_converter_init.c11
-rw-r--r--drivers/staging/csr/csr_wifi_sme_converter_init.h2
-rw-r--r--drivers/staging/csr/csr_wifi_sme_free_downstream_contents.c9
-rw-r--r--drivers/staging/csr/csr_wifi_sme_lib.h35
-rw-r--r--drivers/staging/csr/csr_wifi_sme_prim.h99
-rw-r--r--drivers/staging/csr/csr_wifi_sme_serialize.c62
-rw-r--r--drivers/staging/csr/csr_wifi_sme_serialize.h7
-rw-r--r--drivers/staging/csr/drv.c131
-rw-r--r--drivers/staging/csr/firmware.c18
-rw-r--r--drivers/staging/csr/io.c20
-rw-r--r--drivers/staging/csr/netdev.c168
-rw-r--r--drivers/staging/csr/os.c26
-rw-r--r--drivers/staging/csr/putest.c29
-rw-r--r--drivers/staging/csr/sdio_emb.c187
-rw-r--r--drivers/staging/csr/sdio_events.c49
-rw-r--r--drivers/staging/csr/sdio_mmc.c247
-rw-r--r--drivers/staging/csr/sme_blocking.c123
-rw-r--r--drivers/staging/csr/sme_sys.c582
-rw-r--r--drivers/staging/csr/sme_userspace.c5
-rw-r--r--drivers/staging/csr/sme_wext.c4
-rw-r--r--drivers/staging/csr/ul_int.c25
-rw-r--r--drivers/staging/csr/unifi_event.c540
-rw-r--r--drivers/staging/csr/unifi_os.h22
-rw-r--r--drivers/staging/csr/unifi_pdu_processing.c1551
-rw-r--r--drivers/staging/csr/unifi_priv.h96
-rw-r--r--drivers/staging/csr/unifi_sme.c80
-rw-r--r--drivers/staging/csr/unifi_sme.h9
-rw-r--r--drivers/staging/csr/unifiio.h27
56 files changed, 3841 insertions, 1666 deletions
diff --git a/drivers/staging/csr/csr_framework_ext.c b/drivers/staging/csr/csr_framework_ext.c
index 0406a4b0f78..1586b235e29 100644
--- a/drivers/staging/csr/csr_framework_ext.c
+++ b/drivers/staging/csr/csr_framework_ext.c
@@ -211,3 +211,38 @@ void CsrMemFree(void *pointer)
211 kfree(pointer); 211 kfree(pointer);
212} 212}
213EXPORT_SYMBOL_GPL(CsrMemFree); 213EXPORT_SYMBOL_GPL(CsrMemFree);
214
215/*----------------------------------------------------------------------------*
216 * NAME
217 * CsrMemAllocDma
218 *
219 * DESCRIPTION
220 * Allocate DMA capable dynamic memory of a given size.
221 *
222 * RETURNS
223 * Pointer to allocated memory, or NULL in case of failure.
224 * Allocated memory is not initialised.
225 *
226 *----------------------------------------------------------------------------*/
227void *CsrMemAllocDma(CsrSize size)
228{
229 return kmalloc(size, GFP_KERNEL | GFP_DMA);
230}
231EXPORT_SYMBOL_GPL(CsrMemAllocDma);
232
233/*----------------------------------------------------------------------------*
234 * NAME
235 * CsrMemFreeDma
236 *
237 * DESCRIPTION
238 * Free DMA capable dynamic allocated memory.
239 *
240 * RETURNS
241 * void
242 *
243 *----------------------------------------------------------------------------*/
244void CsrMemFreeDma(void *pointer)
245{
246 kfree(pointer);
247}
248EXPORT_SYMBOL_GPL(CsrMemFreeDma);
diff --git a/drivers/staging/csr/csr_types.h b/drivers/staging/csr/csr_types.h
index d7d2c5d061f..23193ea4429 100644
--- a/drivers/staging/csr/csr_types.h
+++ b/drivers/staging/csr/csr_types.h
@@ -21,6 +21,7 @@
21#include <stddef.h> 21#include <stddef.h>
22#include <sys/types.h> 22#include <sys/types.h>
23#include <stdarg.h> 23#include <stdarg.h>
24#include <string.h>
24#endif 25#endif
25 26
26#ifdef __cplusplus 27#ifdef __cplusplus
diff --git a/drivers/staging/csr/csr_util.c b/drivers/staging/csr/csr_util.c
index 0ae11531e26..939c87c638a 100644
--- a/drivers/staging/csr/csr_util.c
+++ b/drivers/staging/csr/csr_util.c
@@ -221,6 +221,7 @@ void CsrUInt32ToHex(CsrUint32 number, CsrCharString *str)
221/*------------------------------------------------------------------*/ 221/*------------------------------------------------------------------*/
222/* String */ 222/* String */
223/*------------------------------------------------------------------*/ 223/*------------------------------------------------------------------*/
224#ifndef CSR_USE_STDC_LIB
224void *CsrMemCpy(void *dest, const void *src, CsrSize count) 225void *CsrMemCpy(void *dest, const void *src, CsrSize count)
225{ 226{
226 return memcpy(dest, src, count); 227 return memcpy(dest, src, count);
@@ -257,7 +258,9 @@ void *CsrMemDup(const void *buf1, CsrSize count)
257 258
258 return buf2; 259 return buf2;
259} 260}
261#endif
260 262
263#ifndef CSR_USE_STDC_LIB
261CsrCharString *CsrStrCpy(CsrCharString *dest, const CsrCharString *src) 264CsrCharString *CsrStrCpy(CsrCharString *dest, const CsrCharString *src)
262{ 265{
263 return strcpy(dest, src); 266 return strcpy(dest, src);
@@ -303,6 +306,7 @@ CsrCharString *CsrStrChr(const CsrCharString *string, CsrCharString c)
303{ 306{
304 return strchr(string, c); 307 return strchr(string, c);
305} 308}
309#endif
306 310
307CsrInt32 CsrVsnprintf(CsrCharString *string, CsrSize count, const CsrCharString *format, va_list args) 311CsrInt32 CsrVsnprintf(CsrCharString *string, CsrSize count, const CsrCharString *format, va_list args)
308{ 312{
diff --git a/drivers/staging/csr/csr_util.h b/drivers/staging/csr/csr_util.h
index a19baddc021..ce39c7e8dab 100644
--- a/drivers/staging/csr/csr_util.h
+++ b/drivers/staging/csr/csr_util.h
@@ -35,26 +35,53 @@ void CsrUInt16ToHex(CsrUint16 number, CsrCharString *str);
35void CsrUInt32ToHex(CsrUint32 number, CsrCharString *str); 35void CsrUInt32ToHex(CsrUint32 number, CsrCharString *str);
36 36
37/*------------------------------------------------------------------*/ 37/*------------------------------------------------------------------*/
38/* String */ 38/* Standard C Library functions */
39/*------------------------------------------------------------------*/ 39/*------------------------------------------------------------------*/
40#ifdef CSR_USE_STDC_LIB
41#define CsrMemCpy memcpy
42#define CsrMemMove memmove
43#define CsrStrCpy strcpy
44#define CsrStrNCpy strncpy
45#define CsrStrCat strcat
46#define CsrStrNCat strncat
47#define CsrMemCmp(s1, s2, n) ((CsrInt32) memcmp((s1), (s2), (n)))
48#define CsrStrCmp(s1, s2) ((CsrInt32) strcmp((s1), (s2)))
49#define CsrStrNCmp(s1, s2, n) ((CsrInt32) strncmp((s1), (s2), (n)))
50/*#define CsrMemChr memchr*/
51#define CsrStrChr strchr
52/*#define CsrStrCSpn strcspn*/
53/*#define CsrStrPBrk strpbrk*/
54/*#define CsrStrRChr strrchr*/
55/*#define CsrStrSpn strspn*/
56#define CsrStrStr strstr
57/*#define CsrStrTok strtok*/
58#define CsrMemSet memset
59#define CsrStrLen strlen
60/*#define CsrVsnprintf(s, n, format, arg) ((CsrInt32) vsnprintf((s), (n), (format), (arg)))*/
61#else /* !CSR_USE_STDC_LIB */
40void *CsrMemCpy(void *dest, const void *src, CsrSize count); 62void *CsrMemCpy(void *dest, const void *src, CsrSize count);
41void *CsrMemSet(void *dest, CsrUint8 c, CsrSize count);
42void *CsrMemMove(void *dest, const void *src, CsrSize count); 63void *CsrMemMove(void *dest, const void *src, CsrSize count);
43CsrInt32 CsrMemCmp(const void *buf1, const void *buf2, CsrSize count);
44void *CsrMemDup(const void *buf1, CsrSize count);
45CsrCharString *CsrStrCpy(CsrCharString *dest, const CsrCharString *src); 64CsrCharString *CsrStrCpy(CsrCharString *dest, const CsrCharString *src);
46CsrCharString *CsrStrNCpy(CsrCharString *dest, const CsrCharString *src, CsrSize count); 65CsrCharString *CsrStrNCpy(CsrCharString *dest, const CsrCharString *src, CsrSize count);
47int CsrStrNICmp(const CsrCharString *string1, const CsrCharString *string2, CsrSize count);
48CsrCharString *CsrStrCat(CsrCharString *dest, const CsrCharString *src); 66CsrCharString *CsrStrCat(CsrCharString *dest, const CsrCharString *src);
49CsrCharString *CsrStrNCat(CsrCharString *dest, const CsrCharString *src, CsrSize count); 67CsrCharString *CsrStrNCat(CsrCharString *dest, const CsrCharString *src, CsrSize count);
50CsrCharString *CsrStrStr(const CsrCharString *string1, const CsrCharString *string2); 68CsrInt32 CsrMemCmp(const void *buf1, const void *buf2, CsrSize count);
51CsrSize CsrStrLen(const CsrCharString *string);
52CsrInt32 CsrStrCmp(const CsrCharString *string1, const CsrCharString *string2); 69CsrInt32 CsrStrCmp(const CsrCharString *string1, const CsrCharString *string2);
53CsrInt32 CsrStrNCmp(const CsrCharString *string1, const CsrCharString *string2, CsrSize count); 70CsrInt32 CsrStrNCmp(const CsrCharString *string1, const CsrCharString *string2, CsrSize count);
54CsrCharString *CsrStrDup(const CsrCharString *string);
55CsrCharString *CsrStrChr(const CsrCharString *string, CsrCharString c); 71CsrCharString *CsrStrChr(const CsrCharString *string, CsrCharString c);
56CsrUint32 CsrStrToInt(const CsrCharString *string); 72CsrCharString *CsrStrStr(const CsrCharString *string1, const CsrCharString *string2);
73void *CsrMemSet(void *dest, CsrUint8 c, CsrSize count);
74CsrSize CsrStrLen(const CsrCharString *string);
75#endif /* !CSR_USE_STDC_LIB */
57CsrInt32 CsrVsnprintf(CsrCharString *string, CsrSize count, const CsrCharString *format, va_list args); 76CsrInt32 CsrVsnprintf(CsrCharString *string, CsrSize count, const CsrCharString *format, va_list args);
77
78/*------------------------------------------------------------------*/
79/* Non-standard utility functions */
80/*------------------------------------------------------------------*/
81void *CsrMemDup(const void *buf1, CsrSize count);
82int CsrStrNICmp(const CsrCharString *string1, const CsrCharString *string2, CsrSize count);
83CsrCharString *CsrStrDup(const CsrCharString *string);
84CsrUint32 CsrStrToInt(const CsrCharString *string);
58CsrCharString *CsrStrNCpyZero(CsrCharString *dest, const CsrCharString *src, CsrSize count); 85CsrCharString *CsrStrNCpyZero(CsrCharString *dest, const CsrCharString *src, CsrSize count);
59 86
60/*------------------------------------------------------------------*/ 87/*------------------------------------------------------------------*/
diff --git a/drivers/staging/csr/csr_wifi_common.h b/drivers/staging/csr/csr_wifi_common.h
index 1cdde5c7bd8..442dcc6e4e0 100644
--- a/drivers/staging/csr/csr_wifi_common.h
+++ b/drivers/staging/csr/csr_wifi_common.h
@@ -99,7 +99,7 @@ typedef struct
99#define CSR_WIFI_RESULT_INVALID_INTERFACE_TAG ((CsrResult) 0x000B) 99#define CSR_WIFI_RESULT_INVALID_INTERFACE_TAG ((CsrResult) 0x000B)
100#define CSR_WIFI_RESULT_P2P_NOA_CONFIG_CONFLICT ((CsrResult) 0x000C) 100#define CSR_WIFI_RESULT_P2P_NOA_CONFIG_CONFLICT ((CsrResult) 0x000C)
101 101
102#define CSR_WIFI_VERSION "5.0.3.0" 102#define CSR_WIFI_VERSION "5.1.0.0"
103 103
104#ifdef __cplusplus 104#ifdef __cplusplus
105} 105}
diff --git a/drivers/staging/csr/csr_wifi_hip_card.h b/drivers/staging/csr/csr_wifi_hip_card.h
index 8904211d331..2ab47843bcc 100644
--- a/drivers/staging/csr/csr_wifi_hip_card.h
+++ b/drivers/staging/csr/csr_wifi_hip_card.h
@@ -1,6 +1,6 @@
1/***************************************************************************** 1/*****************************************************************************
2 2
3 (c) Cambridge Silicon Radio Limited 2011 3 (c) Cambridge Silicon Radio Limited 2012
4 All rights reserved and confidential information of CSR 4 All rights reserved and confidential information of CSR
5 5
6 Refer to LICENSE.txt included with this source for details 6 Refer to LICENSE.txt included with this source for details
@@ -81,6 +81,15 @@ CsrResult CardWriteBulkData(card_t *card, card_signal_t *csptr, unifi_TrafficQue
81 */ 81 */
82void CardClearFromHostDataSlot(card_t *card, const CsrInt16 aSlotNum); 82void CardClearFromHostDataSlot(card_t *card, const CsrInt16 aSlotNum);
83 83
84#ifdef CSR_WIFI_REQUEUE_PACKET_TO_HAL
85/*****************************************************************************
86 * CardClearFromHostDataSlotWithoutFreeingBulkData - Clear the data stot
87 * without freeing the bulk data
88 */
89
90void CardClearFromHostDataSlotWithoutFreeingBulkData(card_t *card, const CsrInt16 aSlotNum);
91#endif
92
84/***************************************************************************** 93/*****************************************************************************
85 * CardGetFreeFromHostDataSlots - 94 * CardGetFreeFromHostDataSlots -
86 */ 95 */
diff --git a/drivers/staging/csr/csr_wifi_hip_card_sdio.c b/drivers/staging/csr/csr_wifi_hip_card_sdio.c
index 719c608d18b..91976b824a4 100644
--- a/drivers/staging/csr/csr_wifi_hip_card_sdio.c
+++ b/drivers/staging/csr/csr_wifi_hip_card_sdio.c
@@ -1,6 +1,6 @@
1/***************************************************************************** 1/*****************************************************************************
2 2
3 (c) Cambridge Silicon Radio Limited 2011 3 (c) Cambridge Silicon Radio Limited 2012
4 All rights reserved and confidential information of CSR 4 All rights reserved and confidential information of CSR
5 5
6 Refer to LICENSE.txt included with this source for details 6 Refer to LICENSE.txt included with this source for details
@@ -323,7 +323,7 @@ CsrResult unifi_init(card_t *card)
323 * have requested a mini-coredump which needs to be captured now the 323 * have requested a mini-coredump which needs to be captured now the
324 * SDIO interface is alive. 324 * SDIO interface is alive.
325 */ 325 */
326 unifi_coredump_handle_request(card); 326 (void)unifi_coredump_handle_request(card);
327 327
328 /* 328 /*
329 * Probe to see if the UniFi has ROM/flash to boot from. CSR6xxx should do. 329 * Probe to see if the UniFi has ROM/flash to boot from. CSR6xxx should do.
@@ -1616,14 +1616,14 @@ static CsrResult card_allocate_memory_resources(card_t *card)
1616 /* Reset any state carried forward from a previous life */ 1616 /* Reset any state carried forward from a previous life */
1617 card->fh_command_queue.q_rd_ptr = 0; 1617 card->fh_command_queue.q_rd_ptr = 0;
1618 card->fh_command_queue.q_wr_ptr = 0; 1618 card->fh_command_queue.q_wr_ptr = 0;
1619 CsrSnprintf(card->fh_command_queue.name, UNIFI_QUEUE_NAME_MAX_LENGTH, 1619 (void)CsrSnprintf(card->fh_command_queue.name, UNIFI_QUEUE_NAME_MAX_LENGTH,
1620 "fh_cmd_q"); 1620 "fh_cmd_q");
1621 for (i = 0; i < UNIFI_NO_OF_TX_QS; i++) 1621 for (i = 0; i < UNIFI_NO_OF_TX_QS; i++)
1622 { 1622 {
1623 card->fh_traffic_queue[i].q_rd_ptr = 0; 1623 card->fh_traffic_queue[i].q_rd_ptr = 0;
1624 card->fh_traffic_queue[i].q_wr_ptr = 0; 1624 card->fh_traffic_queue[i].q_wr_ptr = 0;
1625 CsrSnprintf(card->fh_traffic_queue[i].name, 1625 (void)CsrSnprintf(card->fh_traffic_queue[i].name,
1626 UNIFI_QUEUE_NAME_MAX_LENGTH, "fh_data_q%d", i); 1626 UNIFI_QUEUE_NAME_MAX_LENGTH, "fh_data_q%d", i);
1627 } 1627 }
1628#ifndef CSR_WIFI_HIP_TA_DISABLE 1628#ifndef CSR_WIFI_HIP_TA_DISABLE
1629 unifi_ta_sampling_init(card); 1629 unifi_ta_sampling_init(card);
@@ -1634,7 +1634,7 @@ static CsrResult card_allocate_memory_resources(card_t *card)
1634 /* 1634 /*
1635 * Allocate memory for the from-host and to-host signal buffers. 1635 * Allocate memory for the from-host and to-host signal buffers.
1636 */ 1636 */
1637 card->fh_buffer.buf = CsrMemAlloc(UNIFI_FH_BUF_SIZE); 1637 card->fh_buffer.buf = CsrMemAllocDma(UNIFI_FH_BUF_SIZE);
1638 if (card->fh_buffer.buf == NULL) 1638 if (card->fh_buffer.buf == NULL)
1639 { 1639 {
1640 unifi_error(card->ospriv, "Failed to allocate memory for F-H signals\n"); 1640 unifi_error(card->ospriv, "Failed to allocate memory for F-H signals\n");
@@ -1645,7 +1645,7 @@ static CsrResult card_allocate_memory_resources(card_t *card)
1645 card->fh_buffer.ptr = card->fh_buffer.buf; 1645 card->fh_buffer.ptr = card->fh_buffer.buf;
1646 card->fh_buffer.count = 0; 1646 card->fh_buffer.count = 0;
1647 1647
1648 card->th_buffer.buf = CsrMemAlloc(UNIFI_FH_BUF_SIZE); 1648 card->th_buffer.buf = CsrMemAllocDma(UNIFI_FH_BUF_SIZE);
1649 if (card->th_buffer.buf == NULL) 1649 if (card->th_buffer.buf == NULL)
1650 { 1650 {
1651 unifi_error(card->ospriv, "Failed to allocate memory for T-H signals\n"); 1651 unifi_error(card->ospriv, "Failed to allocate memory for T-H signals\n");
@@ -1693,6 +1693,12 @@ static CsrResult card_allocate_memory_resources(card_t *card)
1693 return CSR_WIFI_HIP_RESULT_NO_MEMORY; 1693 return CSR_WIFI_HIP_RESULT_NO_MEMORY;
1694 } 1694 }
1695 1695
1696 /* Initialise host tag entries for from-host bulk data slots */
1697 for (i = 0; i < n; i++)
1698 {
1699 card->fh_slot_host_tag_record[i] = CSR_WIFI_HIP_RESERVED_HOST_TAG;
1700 }
1701
1696 1702
1697 /* Allocate memory for the array of pointers */ 1703 /* Allocate memory for the array of pointers */
1698 n = cfg_data->num_tohost_data_slots; 1704 n = cfg_data->num_tohost_data_slots;
@@ -1811,7 +1817,7 @@ static void card_free_memory_resources(card_t *card)
1811 1817
1812 if (card->fh_buffer.buf) 1818 if (card->fh_buffer.buf)
1813 { 1819 {
1814 CsrMemFree(card->fh_buffer.buf); 1820 CsrMemFreeDma(card->fh_buffer.buf);
1815 } 1821 }
1816 card->fh_buffer.ptr = card->fh_buffer.buf = NULL; 1822 card->fh_buffer.ptr = card->fh_buffer.buf = NULL;
1817 card->fh_buffer.bufsize = 0; 1823 card->fh_buffer.bufsize = 0;
@@ -1819,7 +1825,7 @@ static void card_free_memory_resources(card_t *card)
1819 1825
1820 if (card->th_buffer.buf) 1826 if (card->th_buffer.buf)
1821 { 1827 {
1822 CsrMemFree(card->th_buffer.buf); 1828 CsrMemFreeDma(card->th_buffer.buf);
1823 } 1829 }
1824 card->th_buffer.ptr = card->th_buffer.buf = NULL; 1830 card->th_buffer.ptr = card->th_buffer.buf = NULL;
1825 card->th_buffer.bufsize = 0; 1831 card->th_buffer.bufsize = 0;
@@ -1842,14 +1848,14 @@ static void card_init_soft_queues(card_t *card)
1842 /* Reset any state carried forward from a previous life */ 1848 /* Reset any state carried forward from a previous life */
1843 card->fh_command_queue.q_rd_ptr = 0; 1849 card->fh_command_queue.q_rd_ptr = 0;
1844 card->fh_command_queue.q_wr_ptr = 0; 1850 card->fh_command_queue.q_wr_ptr = 0;
1845 CsrSnprintf(card->fh_command_queue.name, UNIFI_QUEUE_NAME_MAX_LENGTH, 1851 (void)CsrSnprintf(card->fh_command_queue.name, UNIFI_QUEUE_NAME_MAX_LENGTH,
1846 "fh_cmd_q"); 1852 "fh_cmd_q");
1847 for (i = 0; i < UNIFI_NO_OF_TX_QS; i++) 1853 for (i = 0; i < UNIFI_NO_OF_TX_QS; i++)
1848 { 1854 {
1849 card->fh_traffic_queue[i].q_rd_ptr = 0; 1855 card->fh_traffic_queue[i].q_rd_ptr = 0;
1850 card->fh_traffic_queue[i].q_wr_ptr = 0; 1856 card->fh_traffic_queue[i].q_wr_ptr = 0;
1851 CsrSnprintf(card->fh_traffic_queue[i].name, 1857 (void)CsrSnprintf(card->fh_traffic_queue[i].name,
1852 UNIFI_QUEUE_NAME_MAX_LENGTH, "fh_data_q%d", i); 1858 UNIFI_QUEUE_NAME_MAX_LENGTH, "fh_data_q%d", i);
1853 } 1859 }
1854#ifndef CSR_WIFI_HIP_TA_DISABLE 1860#ifndef CSR_WIFI_HIP_TA_DISABLE
1855 unifi_ta_sampling_init(card); 1861 unifi_ta_sampling_init(card);
@@ -2399,6 +2405,57 @@ void CardClearFromHostDataSlot(card_t *card, const CsrInt16 slot)
2399} /* CardClearFromHostDataSlot() */ 2405} /* CardClearFromHostDataSlot() */
2400 2406
2401 2407
2408#ifdef CSR_WIFI_REQUEUE_PACKET_TO_HAL
2409/*
2410 * ---------------------------------------------------------------------------
2411 * CardClearFromHostDataSlotWithoutFreeingBulkData
2412 *
2413 * Clear the given data slot with out freeing the bulk data.
2414 *
2415 * Arguments:
2416 * card Pointer to Card object
2417 * slot Index of the signal slot to clear.
2418 *
2419 * Returns:
2420 * None.
2421 * ---------------------------------------------------------------------------
2422 */
2423void CardClearFromHostDataSlotWithoutFreeingBulkData(card_t *card, const CsrInt16 slot)
2424{
2425 CsrUint8 queue = card->from_host_data[slot].queue;
2426
2427 /* Initialise the from_host data slot so it can be re-used,
2428 * Set length field in from_host_data array to 0.
2429 */
2430 UNIFI_INIT_BULK_DATA(&card->from_host_data[slot].bd);
2431
2432 queue = card->from_host_data[slot].queue;
2433
2434 if (queue < UNIFI_NO_OF_TX_QS)
2435 {
2436 if (card->dynamic_slot_data.from_host_used_slots[queue] == 0)
2437 {
2438 unifi_error(card->ospriv, "Goofed up used slots q = %d used slots = %d\n",
2439 queue,
2440 card->dynamic_slot_data.from_host_used_slots[queue]);
2441 }
2442 else
2443 {
2444 card->dynamic_slot_data.from_host_used_slots[queue]--;
2445 }
2446 card->dynamic_slot_data.packets_txed[queue]++;
2447 card->dynamic_slot_data.total_packets_txed++;
2448 if (card->dynamic_slot_data.total_packets_txed >=
2449 card->dynamic_slot_data.packets_interval)
2450 {
2451 CardReassignDynamicReservation(card);
2452 }
2453 }
2454} /* CardClearFromHostDataSlotWithoutFreeingBulkData() */
2455
2456
2457#endif
2458
2402CsrUint16 CardGetDataSlotSize(card_t *card) 2459CsrUint16 CardGetDataSlotSize(card_t *card)
2403{ 2460{
2404 return card->config_data.data_slot_size; 2461 return card->config_data.data_slot_size;
diff --git a/drivers/staging/csr/csr_wifi_hip_card_sdio_intr.c b/drivers/staging/csr/csr_wifi_hip_card_sdio_intr.c
index 3d563c13ff5..8fefbdfc715 100644
--- a/drivers/staging/csr/csr_wifi_hip_card_sdio_intr.c
+++ b/drivers/staging/csr/csr_wifi_hip_card_sdio_intr.c
@@ -1,6 +1,6 @@
1/***************************************************************************** 1/*****************************************************************************
2 2
3 (c) Cambridge Silicon Radio Limited 2011 3 (c) Cambridge Silicon Radio Limited 2012
4 All rights reserved and confidential information of CSR 4 All rights reserved and confidential information of CSR
5 5
6 Refer to LICENSE.txt included with this source for details 6 Refer to LICENSE.txt included with this source for details
@@ -148,9 +148,9 @@ void unifi_debug_hex_to_buf(const CsrCharString *buff, CsrUint16 length)
148 CsrCharString s[5]; 148 CsrCharString s[5];
149 CsrUint16 i; 149 CsrUint16 i;
150 150
151 for (i = 0; i < length; i++) 151 for (i = 0; i < length; i = i + 2)
152 { 152 {
153 CsrUInt16ToHex(0xff & buff[i], s); 153 CsrUInt16ToHex(*((CsrUint16 *)(buff + i)), s);
154 unifi_debug_string_to_buf(s); 154 unifi_debug_string_to_buf(s);
155 } 155 }
156} 156}
@@ -277,7 +277,7 @@ void unifi_sdio_interrupt_handler(card_t *card)
277 * Then ask the OS layer to run the unifi_bh to give attention to the UniFi. 277 * Then ask the OS layer to run the unifi_bh to give attention to the UniFi.
278 */ 278 */
279 card->bh_reason_unifi = 1; 279 card->bh_reason_unifi = 1;
280 unifi_run_bh(card->ospriv); 280 (void)unifi_run_bh(card->ospriv);
281} /* sdio_interrupt_handler() */ 281} /* sdio_interrupt_handler() */
282 282
283 283
@@ -309,7 +309,7 @@ CsrResult unifi_configure_low_power_mode(card_t *card,
309 (low_power_mode == UNIFI_LOW_POWER_DISABLED)?"disabled" : "enabled", 309 (low_power_mode == UNIFI_LOW_POWER_DISABLED)?"disabled" : "enabled",
310 (periodic_wake_mode == UNIFI_PERIODIC_WAKE_HOST_DISABLED)?"FALSE" : "TRUE"); 310 (periodic_wake_mode == UNIFI_PERIODIC_WAKE_HOST_DISABLED)?"FALSE" : "TRUE");
311 311
312 unifi_run_bh(card->ospriv); 312 (void)unifi_run_bh(card->ospriv);
313 return CSR_RESULT_SUCCESS; 313 return CSR_RESULT_SUCCESS;
314} /* unifi_configure_low_power_mode() */ 314} /* unifi_configure_low_power_mode() */
315 315
@@ -614,10 +614,10 @@ exit:
614 (low_power_mode == UNIFI_LOW_POWER_DISABLED)?"disabled" : "enabled"); 614 (low_power_mode == UNIFI_LOW_POWER_DISABLED)?"disabled" : "enabled");
615 615
616 /* Try to capture firmware panic codes */ 616 /* Try to capture firmware panic codes */
617 unifi_capture_panic(card); 617 (void)unifi_capture_panic(card);
618 618
619 /* Ask for a mini-coredump when the driver has reset UniFi */ 619 /* Ask for a mini-coredump when the driver has reset UniFi */
620 unifi_coredump_request_at_next_reset(card, 1); 620 (void)unifi_coredump_request_at_next_reset(card, 1);
621 } 621 }
622 622
623 return r; 623 return r;
@@ -932,9 +932,13 @@ static CsrResult handle_host_protocol(card_t *card, CsrBool *processed_something
932 return r; 932 return r;
933 } 933 }
934 } 934 }
935
936#ifdef CSR_WIFI_RX_PATH_SPLIT
935#ifdef CSR_WIFI_RX_PATH_SPLIT_DONT_USE_WQ 937#ifdef CSR_WIFI_RX_PATH_SPLIT_DONT_USE_WQ
936 unifi_rx_queue_flush(card->ospriv); 938 unifi_rx_queue_flush(card->ospriv);
937#endif 939#endif
940#endif
941
938 /* See if we can re-enable transmission now */ 942 /* See if we can re-enable transmission now */
939 restart_packet_flow(card); 943 restart_packet_flow(card);
940 944
@@ -1324,7 +1328,6 @@ static CsrResult process_to_host_signals(card_t *card, CsrInt32 *processed)
1324 if (status && (card->fh_slot_host_tag_record)) 1328 if (status && (card->fh_slot_host_tag_record))
1325 { 1329 {
1326 CsrUint16 num_fh_slots = card->config_data.num_fromhost_data_slots; 1330 CsrUint16 num_fh_slots = card->config_data.num_fromhost_data_slots;
1327 CsrUint16 i = 0;
1328 1331
1329 /* search through the list of slot records and match with host tag 1332 /* search through the list of slot records and match with host tag
1330 * If a slot is not yet cleared then clear the slot from here 1333 * If a slot is not yet cleared then clear the slot from here
@@ -1333,12 +1336,27 @@ static CsrResult process_to_host_signals(card_t *card, CsrInt32 *processed)
1333 { 1336 {
1334 if (card->fh_slot_host_tag_record[i] == host_tag) 1337 if (card->fh_slot_host_tag_record[i] == host_tag)
1335 { 1338 {
1339#ifdef CSR_WIFI_REQUEUE_PACKET_TO_HAL
1340 /* Invoke the HAL module function to requeue it back to HAL Queues */
1341 r = unifi_reque_ma_packet_request(card->ospriv, host_tag, status, &card->from_host_data[i].bd);
1342 card->fh_slot_host_tag_record[i] = CSR_WIFI_HIP_RESERVED_HOST_TAG;
1343 if (CSR_RESULT_SUCCESS != r)
1344 {
1345 unifi_trace(card->ospriv, UDBG5, "process_to_host_signals: Failed to requeue Packet(hTag:%x) back to HAL \n", host_tag);
1346 CardClearFromHostDataSlot(card, i);
1347 }
1348 else
1349 {
1350 CardClearFromHostDataSlotWithoutFreeingBulkData(card, i);
1351 }
1352
1353#else
1336 unifi_trace(card->ospriv, UDBG4, "process_to_host_signals Clear slot=%x host tag=%x\n", i, host_tag); 1354 unifi_trace(card->ospriv, UDBG4, "process_to_host_signals Clear slot=%x host tag=%x\n", i, host_tag);
1337 card->fh_slot_host_tag_record[i] = CSR_WIFI_HIP_RESERVED_HOST_TAG; 1355 card->fh_slot_host_tag_record[i] = CSR_WIFI_HIP_RESERVED_HOST_TAG;
1338 1356
1339 /* Set length field in from_host_data array to 0 */ 1357 /* Set length field in from_host_data array to 0 */
1340 CardClearFromHostDataSlot(card, i); 1358 CardClearFromHostDataSlot(card, i);
1341 1359#endif
1342 break; 1360 break;
1343 } 1361 }
1344 } 1362 }
@@ -1724,7 +1742,7 @@ static CsrResult process_bulk_data_command(card_t *card, const CsrUint8 *cmdptr,
1724 1742
1725 if (len != 0 && (dir == UNIFI_SDIO_WRITE) && (((CsrIntptr)bdslot->os_data_ptr + offset) & 3)) 1743 if (len != 0 && (dir == UNIFI_SDIO_WRITE) && (((CsrIntptr)bdslot->os_data_ptr + offset) & 3))
1726 { 1744 {
1727 host_bulk_data_slot = CsrMemAlloc(len); 1745 host_bulk_data_slot = CsrMemAllocDma(len);
1728 1746
1729 if (!host_bulk_data_slot) 1747 if (!host_bulk_data_slot)
1730 { 1748 {
@@ -1783,7 +1801,7 @@ static CsrResult process_bulk_data_command(card_t *card, const CsrUint8 *cmdptr,
1783 /* moving this check before we clear host data slot */ 1801 /* moving this check before we clear host data slot */
1784 if ((len != 0) && (dir == UNIFI_SDIO_WRITE) && (((CsrIntptr)bdslot->os_data_ptr + offset) & 3)) 1802 if ((len != 0) && (dir == UNIFI_SDIO_WRITE) && (((CsrIntptr)bdslot->os_data_ptr + offset) & 3))
1785 { 1803 {
1786 CsrMemFree(host_bulk_data_slot); 1804 CsrMemFreeDma(host_bulk_data_slot);
1787 } 1805 }
1788#endif 1806#endif
1789 1807
diff --git a/drivers/staging/csr/csr_wifi_hip_card_sdio_mem.c b/drivers/staging/csr/csr_wifi_hip_card_sdio_mem.c
index 403641d4df0..8bc2d74e8d5 100644
--- a/drivers/staging/csr/csr_wifi_hip_card_sdio_mem.c
+++ b/drivers/staging/csr/csr_wifi_hip_card_sdio_mem.c
@@ -1,6 +1,6 @@
1/***************************************************************************** 1/*****************************************************************************
2 2
3 (c) Cambridge Silicon Radio Limited 2011 3 (c) Cambridge Silicon Radio Limited 2012
4 All rights reserved and confidential information of CSR 4 All rights reserved and confidential information of CSR
5 5
6 Refer to LICENSE.txt included with this source for details 6 Refer to LICENSE.txt included with this source for details
@@ -1565,7 +1565,7 @@ CsrResult unifi_bulk_rw(card_t *card, CsrUint32 handle, void *pdata,
1565 */ 1565 */
1566 if (card->chip_id <= SDIO_CARD_ID_UNIFI_2) 1566 if (card->chip_id <= SDIO_CARD_ID_UNIFI_2)
1567 { 1567 {
1568 unifi_set_host_state(card, UNIFI_HOST_STATE_AWAKE); 1568 (void)unifi_set_host_state(card, UNIFI_HOST_STATE_AWAKE);
1569 } 1569 }
1570 1570
1571 /* If csr_sdio_block_rw() failed in a non-retryable way, or retries exhausted 1571 /* If csr_sdio_block_rw() failed in a non-retryable way, or retries exhausted
diff --git a/drivers/staging/csr/csr_wifi_hip_download.c b/drivers/staging/csr/csr_wifi_hip_download.c
index fb6f04e1bbf..47178afe586 100644
--- a/drivers/staging/csr/csr_wifi_hip_download.c
+++ b/drivers/staging/csr/csr_wifi_hip_download.c
@@ -1,6 +1,6 @@
1/***************************************************************************** 1/*****************************************************************************
2 2
3 (c) Cambridge Silicon Radio Limited 2011 3 (c) Cambridge Silicon Radio Limited 2012
4 All rights reserved and confidential information of CSR 4 All rights reserved and confidential information of CSR
5 5
6 Refer to LICENSE.txt included with this source for details 6 Refer to LICENSE.txt included with this source for details
@@ -674,7 +674,7 @@ static CsrResult send_ptdl_to_unifi(card_t *card, void *dlpriv,
674 return CSR_WIFI_HIP_RESULT_INVALID_VALUE; 674 return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
675 } 675 }
676 676
677 buf = CsrMemAlloc(buf_size); 677 buf = CsrMemAllocDma(buf_size);
678 if (buf == NULL) 678 if (buf == NULL)
679 { 679 {
680 unifi_error(card->ospriv, "Failed to allocate transfer buffer for firmware download\n"); 680 unifi_error(card->ospriv, "Failed to allocate transfer buffer for firmware download\n");
@@ -720,7 +720,7 @@ static CsrResult send_ptdl_to_unifi(card_t *card, void *dlpriv,
720 } 720 }
721 } 721 }
722 722
723 CsrMemFree(buf); 723 CsrMemFreeDma(buf);
724 724
725 if (r != CSR_RESULT_SUCCESS && r != CSR_WIFI_HIP_RESULT_NO_DEVICE) 725 if (r != CSR_RESULT_SUCCESS && r != CSR_WIFI_HIP_RESULT_NO_DEVICE)
726 { 726 {
diff --git a/drivers/staging/csr/csr_wifi_hip_dump.c b/drivers/staging/csr/csr_wifi_hip_dump.c
index c191ea13504..5297f103e9e 100644
--- a/drivers/staging/csr/csr_wifi_hip_dump.c
+++ b/drivers/staging/csr/csr_wifi_hip_dump.c
@@ -1,6 +1,6 @@
1/***************************************************************************** 1/*****************************************************************************
2 2
3 (c) Cambridge Silicon Radio Limited 2011 3 (c) Cambridge Silicon Radio Limited 2012
4 All rights reserved and confidential information of CSR 4 All rights reserved and confidential information of CSR
5 5
6 Refer to LICENSE.txt included with this source for details 6 Refer to LICENSE.txt included with this source for details
@@ -293,7 +293,7 @@ done:
293 * Notes: 293 * Notes:
294 * --------------------------------------------------------------------------- 294 * ---------------------------------------------------------------------------
295 */ 295 */
296static CsrInt32 get_value_from_coredump(const coredump_buffer *dump, 296static CsrInt32 get_value_from_coredump(const coredump_buffer *coreDump,
297 const unifi_coredump_space_t space, 297 const unifi_coredump_space_t space,
298 const CsrUint16 offset_in_space) 298 const CsrUint16 offset_in_space)
299{ 299{
@@ -316,7 +316,7 @@ static CsrInt32 get_value_from_coredump(const coredump_buffer *dump,
316 { 316 {
317 /* Calculate the offset of data within the zone buffer */ 317 /* Calculate the offset of data within the zone buffer */
318 offset_in_zone = offset_in_space - def->offset; 318 offset_in_zone = offset_in_space - def->offset;
319 r = (CsrInt32) * (dump->zone[i] + offset_in_zone); 319 r = (CsrInt32) * (coreDump->zone[i] + offset_in_zone);
320 320
321 unifi_trace(NULL, UDBG6, 321 unifi_trace(NULL, UDBG6,
322 "sp %d, offs 0x%04x = 0x%04x (in z%d 0x%04x->0x%04x)\n", 322 "sp %d, offs 0x%04x = 0x%04x (in z%d 0x%04x->0x%04x)\n",
diff --git a/drivers/staging/csr/csr_wifi_hip_ta_sampling.c b/drivers/staging/csr/csr_wifi_hip_ta_sampling.c
index 4fa8f607f15..7afcd3c90fc 100644
--- a/drivers/staging/csr/csr_wifi_hip_ta_sampling.c
+++ b/drivers/staging/csr/csr_wifi_hip_ta_sampling.c
@@ -1,6 +1,6 @@
1/***************************************************************************** 1/*****************************************************************************
2 2
3 (c) Cambridge Silicon Radio Limited 2011 3 (c) Cambridge Silicon Radio Limited 2012
4 All rights reserved and confidential information of CSR 4 All rights reserved and confidential information of CSR
5 5
6 Refer to LICENSE.txt included with this source for details 6 Refer to LICENSE.txt included with this source for details
@@ -69,9 +69,9 @@ enum ta_frame_identity
69#define TA_EAPOL_TYPE_OFFSET 9 69#define TA_EAPOL_TYPE_OFFSET 9
70#define TA_EAPOL_TYPE_START 0x01 70#define TA_EAPOL_TYPE_START 0x01
71 71
72static const CsrUint8 snap_802_2[3] = { 0xAA, 0xAA, 0x03 }; 72#define snap_802_2 0xAAAA0300
73static const CsrUint8 oui_rfc1042[3] = { 0x00, 0x00, 0x00 }; 73#define oui_rfc1042 0x00000000
74static const CsrUint8 oui_8021h[3] = { 0x00, 0x00, 0xf8 }; 74#define oui_8021h 0x0000f800
75static const CsrUint8 aironet_snap[5] = { 0x00, 0x40, 0x96, 0x00, 0x00 }; 75static const CsrUint8 aironet_snap[5] = { 0x00, 0x40, 0x96, 0x00, 0x00 };
76 76
77 77
@@ -100,13 +100,17 @@ static enum ta_frame_identity ta_detect_protocol(card_t *card, CsrWifiRouterCtrl
100 CsrUint16 proto; 100 CsrUint16 proto;
101 CsrUint16 source_port, dest_port; 101 CsrUint16 source_port, dest_port;
102 CsrWifiMacAddress srcAddress; 102 CsrWifiMacAddress srcAddress;
103 CsrUint32 snap_hdr, oui_hdr;
103 104
104 if (data->data_length < TA_LLC_HEADER_SIZE) 105 if (data->data_length < TA_LLC_HEADER_SIZE)
105 { 106 {
106 return TA_FRAME_UNKNOWN; 107 return TA_FRAME_UNKNOWN;
107 } 108 }
108 109
109 if (CsrMemCmp(data->os_data_ptr, snap_802_2, 3)) 110 snap_hdr = (((CsrUint32)data->os_data_ptr[0]) << 24) |
111 (((CsrUint32)data->os_data_ptr[1]) << 16) |
112 (((CsrUint32)data->os_data_ptr[2]) << 8);
113 if (snap_hdr != snap_802_2)
110 { 114 {
111 return TA_FRAME_UNKNOWN; 115 return TA_FRAME_UNKNOWN;
112 } 116 }
@@ -118,8 +122,10 @@ static enum ta_frame_identity ta_detect_protocol(card_t *card, CsrWifiRouterCtrl
118 */ 122 */
119 } 123 }
120 124
121 if (!CsrMemCmp(data->os_data_ptr + 3, oui_rfc1042, 3) || 125 oui_hdr = (((CsrUint32)data->os_data_ptr[3]) << 24) |
122 !CsrMemCmp(data->os_data_ptr + 3, oui_8021h, 3)) 126 (((CsrUint32)data->os_data_ptr[4]) << 16) |
127 (((CsrUint32)data->os_data_ptr[5]) << 8);
128 if ((oui_hdr == oui_rfc1042) || (oui_hdr == oui_8021h))
123 { 129 {
124 proto = (data->os_data_ptr[TA_ETHERNET_TYPE_OFFSET] * 256) + 130 proto = (data->os_data_ptr[TA_ETHERNET_TYPE_OFFSET] * 256) +
125 data->os_data_ptr[TA_ETHERNET_TYPE_OFFSET + 1]; 131 data->os_data_ptr[TA_ETHERNET_TYPE_OFFSET + 1];
@@ -177,7 +183,7 @@ static enum ta_frame_identity ta_detect_protocol(card_t *card, CsrWifiRouterCtrl
177 /* The DHCP should have at least a message type (request, ack, nack, etc) */ 183 /* The DHCP should have at least a message type (request, ack, nack, etc) */
178 if (data->data_length > TA_DHCP_MESSAGE_TYPE_OFFSET + 6) 184 if (data->data_length > TA_DHCP_MESSAGE_TYPE_OFFSET + 6)
179 { 185 {
180 CsrMemCpy(srcAddress.a, saddr, 6); 186 UNIFI_MAC_ADDRESS_COPY(srcAddress.a, saddr);
181 187
182 if (direction == CSR_WIFI_ROUTER_CTRL_PROTOCOL_DIRECTION_TX) 188 if (direction == CSR_WIFI_ROUTER_CTRL_PROTOCOL_DIRECTION_TX)
183 { 189 {
@@ -189,7 +195,7 @@ static enum ta_frame_identity ta_detect_protocol(card_t *card, CsrWifiRouterCtrl
189 } 195 }
190 196
191 /* DHCPACK is a special indication */ 197 /* DHCPACK is a special indication */
192 if (!CsrMemCmp(data->os_data_ptr + TA_BOOTP_CLIENT_MAC_ADDR_OFFSET, sta_macaddr, 6)) 198 if (UNIFI_MAC_ADDRESS_CMP(data->os_data_ptr + TA_BOOTP_CLIENT_MAC_ADDR_OFFSET, sta_macaddr) == TRUE)
193 { 199 {
194 if (data->os_data_ptr[TA_DHCP_MESSAGE_TYPE_OFFSET] == TA_DHCP_MESSAGE_TYPE_ACK) 200 if (data->os_data_ptr[TA_DHCP_MESSAGE_TYPE_OFFSET] == TA_DHCP_MESSAGE_TYPE_ACK)
195 { 201 {
@@ -224,7 +230,7 @@ static enum ta_frame_identity ta_detect_protocol(card_t *card, CsrWifiRouterCtrl
224 if ((TA_PROTO_TYPE_WAI == proto) || (direction != CSR_WIFI_ROUTER_CTRL_PROTOCOL_DIRECTION_TX) || 230 if ((TA_PROTO_TYPE_WAI == proto) || (direction != CSR_WIFI_ROUTER_CTRL_PROTOCOL_DIRECTION_TX) ||
225 (data->os_data_ptr[TA_EAPOL_TYPE_OFFSET] == TA_EAPOL_TYPE_START)) 231 (data->os_data_ptr[TA_EAPOL_TYPE_OFFSET] == TA_EAPOL_TYPE_START))
226 { 232 {
227 CsrMemCpy(srcAddress.a, saddr, 6); 233 UNIFI_MAC_ADDRESS_COPY(srcAddress.a, saddr);
228 unifi_ta_indicate_protocol(card->ospriv, 234 unifi_ta_indicate_protocol(card->ospriv,
229 CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_EAPOL, 235 CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_EAPOL,
230 direction, &srcAddress); 236 direction, &srcAddress);
@@ -238,7 +244,7 @@ static enum ta_frame_identity ta_detect_protocol(card_t *card, CsrWifiRouterCtrl
238 { 244 {
239 if (proto == TA_PROTO_TYPE_ARP) 245 if (proto == TA_PROTO_TYPE_ARP)
240 { 246 {
241 CsrMemCpy(srcAddress.a, saddr, 6); 247 UNIFI_MAC_ADDRESS_COPY(srcAddress.a, saddr);
242 unifi_ta_indicate_protocol(card->ospriv, 248 unifi_ta_indicate_protocol(card->ospriv,
243 CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_ARP, 249 CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_ARP,
244 direction, &srcAddress); 250 direction, &srcAddress);
@@ -253,7 +259,7 @@ static enum ta_frame_identity ta_detect_protocol(card_t *card, CsrWifiRouterCtrl
253 /* detect Aironet frames */ 259 /* detect Aironet frames */
254 if (!CsrMemCmp(data->os_data_ptr + 3, aironet_snap, 5)) 260 if (!CsrMemCmp(data->os_data_ptr + 3, aironet_snap, 5))
255 { 261 {
256 CsrMemCpy(srcAddress.a, saddr, 6); 262 UNIFI_MAC_ADDRESS_COPY(srcAddress.a, saddr);
257 unifi_ta_indicate_protocol(card->ospriv, CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_AIRONET, 263 unifi_ta_indicate_protocol(card->ospriv, CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_AIRONET,
258 direction, &srcAddress); 264 direction, &srcAddress);
259 } 265 }
diff --git a/drivers/staging/csr/csr_wifi_hip_unifi.h b/drivers/staging/csr/csr_wifi_hip_unifi.h
index feda2e051c2..5f1c67b7c6e 100644
--- a/drivers/staging/csr/csr_wifi_hip_unifi.h
+++ b/drivers/staging/csr/csr_wifi_hip_unifi.h
@@ -1,6 +1,6 @@
1/***************************************************************************** 1/*****************************************************************************
2 2
3 (c) Cambridge Silicon Radio Limited 2011 3 (c) Cambridge Silicon Radio Limited 2012
4 All rights reserved and confidential information of CSR 4 All rights reserved and confidential information of CSR
5 5
6 Refer to LICENSE.txt included with this source for details 6 Refer to LICENSE.txt included with this source for details
@@ -103,6 +103,17 @@ extern "C" {
103#include "csr_formatted_io.h" /* from the synergy gsp folder */ 103#include "csr_formatted_io.h" /* from the synergy gsp folder */
104#include "csr_wifi_result.h" 104#include "csr_wifi_result.h"
105 105
106/* Utility MACROS. Note that UNIFI_MAC_ADDRESS_CMP returns TRUE on success */
107#define UNIFI_MAC_ADDRESS_COPY(dst, src) \
108 do { (dst)[0] = (src)[0]; (dst)[1] = (src)[1]; \
109 (dst)[2] = (src)[2]; (dst)[3] = (src)[3]; \
110 (dst)[4] = (src)[4]; (dst)[5] = (src)[5]; \
111 } while (0)
112
113#define UNIFI_MAC_ADDRESS_CMP(addr1, addr2) \
114 (((addr1)[0] == (addr2)[0]) && ((addr1)[1] == (addr2)[1]) && \
115 ((addr1)[2] == (addr2)[2]) && ((addr1)[3] == (addr2)[3]) && \
116 ((addr1)[4] == (addr2)[4]) && ((addr1)[5] == (addr2)[5]))
106 117
107/* Traffic queue ordered according to priority 118/* Traffic queue ordered according to priority
108 * EAPOL/Uncontrolled port Queue should be the last 119 * EAPOL/Uncontrolled port Queue should be the last
@@ -635,7 +646,24 @@ void unifi_receive_event(void *ospriv,
635 CsrUint8 *sigdata, CsrUint32 siglen, 646 CsrUint8 *sigdata, CsrUint32 siglen,
636 const bulk_data_param_t *bulkdata); 647 const bulk_data_param_t *bulkdata);
637 648
649#ifdef CSR_WIFI_REQUEUE_PACKET_TO_HAL
650/**
651 *
652 * Used to reque the failed ma packet request back to hal queues
653 *
654 * @param ospriv the OS layer context.
655 *
656 * @param host_tag host tag for the packet to requeue.
657 *
658 * @param bulkDataDesc pointer to the bulk data.
659 *
660 * @ingroup upperedge
661 */
662CsrResult unifi_reque_ma_packet_request(void *ospriv, CsrUint32 host_tag,
663 CsrUint16 status,
664 bulk_data_desc_t *bulkDataDesc);
638 665
666#endif
639typedef struct 667typedef struct
640{ 668{
641 CsrUint16 free_fh_sig_queue_slots[UNIFI_NO_OF_TX_QS]; 669 CsrUint16 free_fh_sig_queue_slots[UNIFI_NO_OF_TX_QS];
@@ -836,6 +864,8 @@ const CsrCharString* lookup_bulkcmd_name(CsrUint16 id);
836/* Function to log HIP's global debug buffer */ 864/* Function to log HIP's global debug buffer */
837#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE 865#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
838void unifi_debug_buf_dump(void); 866void unifi_debug_buf_dump(void);
867void unifi_debug_log_to_buf(const CsrCharString *fmt, ...);
868void unifi_debug_hex_to_buf(const CsrCharString *buff, CsrUint16 length);
839#endif 869#endif
840 870
841/* Mini-coredump utility functions */ 871/* Mini-coredump utility functions */
diff --git a/drivers/staging/csr/csr_wifi_hip_xbv.c b/drivers/staging/csr/csr_wifi_hip_xbv.c
index 5d0fdcce1a9..5aaec4da441 100644
--- a/drivers/staging/csr/csr_wifi_hip_xbv.c
+++ b/drivers/staging/csr/csr_wifi_hip_xbv.c
@@ -1,6 +1,6 @@
1/***************************************************************************** 1/*****************************************************************************
2 2
3 (c) Cambridge Silicon Radio Limited 2011 3 (c) Cambridge Silicon Radio Limited 2012
4 All rights reserved and confidential information of CSR 4 All rights reserved and confidential information of CSR
5 5
6 Refer to LICENSE.txt included with this source for details 6 Refer to LICENSE.txt included with this source for details
@@ -579,8 +579,8 @@ static CsrUint32 write_uint16(void *buf, const CsrUint32 offset, const CsrUint16
579 579
580static CsrUint32 write_uint32(void *buf, const CsrUint32 offset, const CsrUint32 val) 580static CsrUint32 write_uint32(void *buf, const CsrUint32 offset, const CsrUint32 val)
581{ 581{
582 write_uint16(buf, offset + 0, (CsrUint16)(val & 0xffff)); 582 (void)write_uint16(buf, offset + 0, (CsrUint16)(val & 0xffff));
583 write_uint16(buf, offset + 2, (CsrUint16)(val >> 16)); 583 (void)write_uint16(buf, offset + 2, (CsrUint16)(val >> 16));
584 return sizeof(CsrUint32); 584 return sizeof(CsrUint32);
585} 585}
586 586
@@ -1055,11 +1055,11 @@ void* xbv_to_patch(card_t *card, fwreadfn_t readfn,
1055 patch_offs += write_reset_ptdl(patch_buf, patch_offs, fwinfo, fw_id); 1055 patch_offs += write_reset_ptdl(patch_buf, patch_offs, fwinfo, fw_id);
1056 1056
1057 /* Now the length is known, update the LIST.length */ 1057 /* Now the length is known, update the LIST.length */
1058 write_uint32(patch_buf, list_len_offs, 1058 (void)write_uint32(patch_buf, list_len_offs,
1059 (patch_offs - ptdl_start_offs) + PTCH_LIST_SIZE); 1059 (patch_offs - ptdl_start_offs) + PTCH_LIST_SIZE);
1060 1060
1061 /* Re write XBV headers just to fill in the correct file size */ 1061 /* Re write XBV headers just to fill in the correct file size */
1062 write_xbv_header(patch_buf, 0, (patch_offs - payload_offs)); 1062 (void)write_xbv_header(patch_buf, 0, (patch_offs - payload_offs));
1063 1063
1064 unifi_trace(card->ospriv, UDBG1, "XBV:PTCH size %u, fw_id %u\n", 1064 unifi_trace(card->ospriv, UDBG1, "XBV:PTCH size %u, fw_id %u\n",
1065 patch_offs, fw_id); 1065 patch_offs, fw_id);
diff --git a/drivers/staging/csr/csr_wifi_nme_ap_lib.h b/drivers/staging/csr/csr_wifi_nme_ap_lib.h
index fc5692476dd..aa632d5dd0d 100644
--- a/drivers/staging/csr/csr_wifi_nme_ap_lib.h
+++ b/drivers/staging/csr/csr_wifi_nme_ap_lib.h
@@ -1,6 +1,6 @@
1/***************************************************************************** 1/*****************************************************************************
2 2
3 (c) Cambridge Silicon Radio Limited 2011 3 (c) Cambridge Silicon Radio Limited 2012
4 All rights reserved and confidential information of CSR 4 All rights reserved and confidential information of CSR
5 5
6 Refer to LICENSE.txt included with this source for details 6 Refer to LICENSE.txt included with this source for details
@@ -196,7 +196,6 @@ extern const CsrCharString *CsrWifiNmeApDownstreamPrimNames[CSR_WIFI_NME_AP_PRIM
196 apCredentials - Security credential configuration. 196 apCredentials - Security credential configuration.
197 maxConnections - Maximum number of stations/P2P clients allowed 197 maxConnections - Maximum number of stations/P2P clients allowed
198 p2pGoParam - P2P specific GO parameters. 198 p2pGoParam - P2P specific GO parameters.
199 NOT USED FOR CURRENT RELEASE
200 wpsEnabled - Indicates whether WPS should be enabled or not 199 wpsEnabled - Indicates whether WPS should be enabled or not
201 200
202*******************************************************************************/ 201*******************************************************************************/
diff --git a/drivers/staging/csr/csr_wifi_nme_ap_prim.h b/drivers/staging/csr/csr_wifi_nme_ap_prim.h
index e3b56b4b44e..561c2fdc379 100644
--- a/drivers/staging/csr/csr_wifi_nme_ap_prim.h
+++ b/drivers/staging/csr/csr_wifi_nme_ap_prim.h
@@ -1,6 +1,6 @@
1/***************************************************************************** 1/*****************************************************************************
2 2
3 (c) Cambridge Silicon Radio Limited 2011 3 (c) Cambridge Silicon Radio Limited 2012
4 All rights reserved and confidential information of CSR 4 All rights reserved and confidential information of CSR
5 5
6 Refer to LICENSE.txt included with this source for details 6 Refer to LICENSE.txt included with this source for details
@@ -248,7 +248,6 @@ typedef struct
248 apCredentials - Security credential configuration. 248 apCredentials - Security credential configuration.
249 maxConnections - Maximum number of stations/P2P clients allowed 249 maxConnections - Maximum number of stations/P2P clients allowed
250 p2pGoParam - P2P specific GO parameters. 250 p2pGoParam - P2P specific GO parameters.
251 NOT USED FOR CURRENT RELEASE
252 wpsEnabled - Indicates whether WPS should be enabled or not 251 wpsEnabled - Indicates whether WPS should be enabled or not
253 252
254*******************************************************************************/ 253*******************************************************************************/
diff --git a/drivers/staging/csr/csr_wifi_router_converter_init.c b/drivers/staging/csr/csr_wifi_router_converter_init.c
index f7ee3f0ec37..6ff59c01e14 100644
--- a/drivers/staging/csr/csr_wifi_router_converter_init.c
+++ b/drivers/staging/csr/csr_wifi_router_converter_init.c
@@ -1,6 +1,6 @@
1/***************************************************************************** 1/*****************************************************************************
2 2
3 (c) Cambridge Silicon Radio Limited 2011 3 (c) Cambridge Silicon Radio Limited 2012
4 All rights reserved and confidential information of CSR 4 All rights reserved and confidential information of CSR
5 5
6 Refer to LICENSE.txt included with this source for details 6 Refer to LICENSE.txt included with this source for details
@@ -41,11 +41,11 @@ CsrMsgConvMsgEntry* CsrWifiRouterConverterLookup(CsrMsgConvMsgEntry *ce, CsrUint
41{ 41{
42 if (msgType & CSR_PRIM_UPSTREAM) 42 if (msgType & CSR_PRIM_UPSTREAM)
43 { 43 {
44 CsrUint16 index = (msgType & ~CSR_PRIM_UPSTREAM) + CSR_WIFI_ROUTER_PRIM_DOWNSTREAM_COUNT; 44 CsrUint16 idx = (msgType & ~CSR_PRIM_UPSTREAM) + CSR_WIFI_ROUTER_PRIM_DOWNSTREAM_COUNT;
45 if (index < (CSR_WIFI_ROUTER_PRIM_UPSTREAM_COUNT + CSR_WIFI_ROUTER_PRIM_DOWNSTREAM_COUNT) && 45 if (idx < (CSR_WIFI_ROUTER_PRIM_UPSTREAM_COUNT + CSR_WIFI_ROUTER_PRIM_DOWNSTREAM_COUNT) &&
46 csrwifirouter_conv_lut[index].msgType == msgType) 46 csrwifirouter_conv_lut[idx].msgType == msgType)
47 { 47 {
48 return &csrwifirouter_conv_lut[index]; 48 return &csrwifirouter_conv_lut[idx];
49 } 49 }
50 } 50 }
51 else 51 else
diff --git a/drivers/staging/csr/csr_wifi_router_ctrl_converter_init.c b/drivers/staging/csr/csr_wifi_router_ctrl_converter_init.c
index 36403fcf97e..32d0bb632d9 100644
--- a/drivers/staging/csr/csr_wifi_router_ctrl_converter_init.c
+++ b/drivers/staging/csr/csr_wifi_router_ctrl_converter_init.c
@@ -1,6 +1,6 @@
1/***************************************************************************** 1/*****************************************************************************
2 2
3 (c) Cambridge Silicon Radio Limited 2011 3 (c) Cambridge Silicon Radio Limited 2012
4 All rights reserved and confidential information of CSR 4 All rights reserved and confidential information of CSR
5 5
6 Refer to LICENSE.txt included with this source for details 6 Refer to LICENSE.txt included with this source for details
@@ -50,9 +50,11 @@ static CsrMsgConvMsgEntry csrwifirouterctrl_conv_lut[] = {
50 { CSR_WIFI_ROUTER_CTRL_CAPABILITIES_REQ, CsrWifiRouterCtrlCapabilitiesReqSizeof, CsrWifiRouterCtrlCapabilitiesReqSer, CsrWifiRouterCtrlCapabilitiesReqDes, CsrWifiRouterCtrlCapabilitiesReqSerFree }, 50 { CSR_WIFI_ROUTER_CTRL_CAPABILITIES_REQ, CsrWifiRouterCtrlCapabilitiesReqSizeof, CsrWifiRouterCtrlCapabilitiesReqSer, CsrWifiRouterCtrlCapabilitiesReqDes, CsrWifiRouterCtrlCapabilitiesReqSerFree },
51 { CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_ENABLE_REQ, CsrWifiRouterCtrlBlockAckEnableReqSizeof, CsrWifiRouterCtrlBlockAckEnableReqSer, CsrWifiRouterCtrlBlockAckEnableReqDes, CsrWifiRouterCtrlBlockAckEnableReqSerFree }, 51 { CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_ENABLE_REQ, CsrWifiRouterCtrlBlockAckEnableReqSizeof, CsrWifiRouterCtrlBlockAckEnableReqSer, CsrWifiRouterCtrlBlockAckEnableReqDes, CsrWifiRouterCtrlBlockAckEnableReqSerFree },
52 { CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_DISABLE_REQ, CsrWifiRouterCtrlBlockAckDisableReqSizeof, CsrWifiRouterCtrlBlockAckDisableReqSer, CsrWifiRouterCtrlBlockAckDisableReqDes, CsrWifiRouterCtrlBlockAckDisableReqSerFree }, 52 { CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_DISABLE_REQ, CsrWifiRouterCtrlBlockAckDisableReqSizeof, CsrWifiRouterCtrlBlockAckDisableReqSer, CsrWifiRouterCtrlBlockAckDisableReqDes, CsrWifiRouterCtrlBlockAckDisableReqSerFree },
53 { CSR_WIFI_ROUTER_CTRL_WAPI_MULTICAST_REQ, CsrWifiRouterCtrlWapiMulticastReqSizeof, CsrWifiRouterCtrlWapiMulticastReqSer, CsrWifiRouterCtrlWapiMulticastReqDes, CsrWifiRouterCtrlWapiMulticastReqSerFree }, 53 { CSR_WIFI_ROUTER_CTRL_WAPI_RX_PKT_REQ, CsrWifiRouterCtrlWapiRxPktReqSizeof, CsrWifiRouterCtrlWapiRxPktReqSer, CsrWifiRouterCtrlWapiRxPktReqDes, CsrWifiRouterCtrlWapiRxPktReqSerFree },
54 { CSR_WIFI_ROUTER_CTRL_WAPI_MULTICAST_FILTER_REQ, CsrWifiRouterCtrlWapiMulticastFilterReqSizeof, CsrWifiRouterCtrlWapiMulticastFilterReqSer, CsrWifiRouterCtrlWapiMulticastFilterReqDes, CsrWifiRouterCtrlWapiMulticastFilterReqSerFree }, 54 { CSR_WIFI_ROUTER_CTRL_WAPI_MULTICAST_FILTER_REQ, CsrWifiRouterCtrlWapiMulticastFilterReqSizeof, CsrWifiRouterCtrlWapiMulticastFilterReqSer, CsrWifiRouterCtrlWapiMulticastFilterReqDes, CsrWifiRouterCtrlWapiMulticastFilterReqSerFree },
55 { CSR_WIFI_ROUTER_CTRL_WAPI_UNICAST_FILTER_REQ, CsrWifiRouterCtrlWapiUnicastFilterReqSizeof, CsrWifiRouterCtrlWapiUnicastFilterReqSer, CsrWifiRouterCtrlWapiUnicastFilterReqDes, CsrWifiRouterCtrlWapiUnicastFilterReqSerFree }, 55 { CSR_WIFI_ROUTER_CTRL_WAPI_UNICAST_FILTER_REQ, CsrWifiRouterCtrlWapiUnicastFilterReqSizeof, CsrWifiRouterCtrlWapiUnicastFilterReqSer, CsrWifiRouterCtrlWapiUnicastFilterReqDes, CsrWifiRouterCtrlWapiUnicastFilterReqSerFree },
56 { CSR_WIFI_ROUTER_CTRL_WAPI_UNICAST_TX_PKT_REQ, CsrWifiRouterCtrlWapiUnicastTxPktReqSizeof, CsrWifiRouterCtrlWapiUnicastTxPktReqSer, CsrWifiRouterCtrlWapiUnicastTxPktReqDes, CsrWifiRouterCtrlWapiUnicastTxPktReqSerFree },
57 { CSR_WIFI_ROUTER_CTRL_WAPI_FILTER_REQ, CsrWifiRouterCtrlWapiFilterReqSizeof, CsrWifiRouterCtrlWapiFilterReqSer, CsrWifiRouterCtrlWapiFilterReqDes, CsrWifiRouterCtrlWapiFilterReqSerFree },
56 { CSR_WIFI_ROUTER_CTRL_HIP_IND, CsrWifiRouterCtrlHipIndSizeof, CsrWifiRouterCtrlHipIndSer, CsrWifiRouterCtrlHipIndDes, CsrWifiRouterCtrlHipIndSerFree }, 58 { CSR_WIFI_ROUTER_CTRL_HIP_IND, CsrWifiRouterCtrlHipIndSizeof, CsrWifiRouterCtrlHipIndSer, CsrWifiRouterCtrlHipIndDes, CsrWifiRouterCtrlHipIndSerFree },
57 { CSR_WIFI_ROUTER_CTRL_MULTICAST_ADDRESS_IND, CsrWifiRouterCtrlMulticastAddressIndSizeof, CsrWifiRouterCtrlMulticastAddressIndSer, CsrWifiRouterCtrlMulticastAddressIndDes, CsrWifiRouterCtrlMulticastAddressIndSerFree }, 59 { CSR_WIFI_ROUTER_CTRL_MULTICAST_ADDRESS_IND, CsrWifiRouterCtrlMulticastAddressIndSizeof, CsrWifiRouterCtrlMulticastAddressIndSer, CsrWifiRouterCtrlMulticastAddressIndDes, CsrWifiRouterCtrlMulticastAddressIndSerFree },
58 { CSR_WIFI_ROUTER_CTRL_PORT_CONFIGURE_CFM, CsrWifiRouterCtrlPortConfigureCfmSizeof, CsrWifiRouterCtrlPortConfigureCfmSer, CsrWifiRouterCtrlPortConfigureCfmDes, CsrWifiRouterCtrlPortConfigureCfmSerFree }, 60 { CSR_WIFI_ROUTER_CTRL_PORT_CONFIGURE_CFM, CsrWifiRouterCtrlPortConfigureCfmSizeof, CsrWifiRouterCtrlPortConfigureCfmSer, CsrWifiRouterCtrlPortConfigureCfmDes, CsrWifiRouterCtrlPortConfigureCfmSerFree },
@@ -81,7 +83,9 @@ static CsrMsgConvMsgEntry csrwifirouterctrl_conv_lut[] = {
81 { CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_DISABLE_CFM, CsrWifiRouterCtrlBlockAckDisableCfmSizeof, CsrWifiRouterCtrlBlockAckDisableCfmSer, CsrWifiRouterCtrlBlockAckDisableCfmDes, CsrWifiRouterCtrlBlockAckDisableCfmSerFree }, 83 { CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_DISABLE_CFM, CsrWifiRouterCtrlBlockAckDisableCfmSizeof, CsrWifiRouterCtrlBlockAckDisableCfmSer, CsrWifiRouterCtrlBlockAckDisableCfmDes, CsrWifiRouterCtrlBlockAckDisableCfmSerFree },
82 { CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_ERROR_IND, CsrWifiRouterCtrlBlockAckErrorIndSizeof, CsrWifiRouterCtrlBlockAckErrorIndSer, CsrWifiRouterCtrlBlockAckErrorIndDes, CsrWifiRouterCtrlBlockAckErrorIndSerFree }, 84 { CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_ERROR_IND, CsrWifiRouterCtrlBlockAckErrorIndSizeof, CsrWifiRouterCtrlBlockAckErrorIndSer, CsrWifiRouterCtrlBlockAckErrorIndDes, CsrWifiRouterCtrlBlockAckErrorIndSerFree },
83 { CSR_WIFI_ROUTER_CTRL_STA_INACTIVE_IND, CsrWifiRouterCtrlStaInactiveIndSizeof, CsrWifiRouterCtrlStaInactiveIndSer, CsrWifiRouterCtrlStaInactiveIndDes, CsrWifiRouterCtrlStaInactiveIndSerFree }, 85 { CSR_WIFI_ROUTER_CTRL_STA_INACTIVE_IND, CsrWifiRouterCtrlStaInactiveIndSizeof, CsrWifiRouterCtrlStaInactiveIndSer, CsrWifiRouterCtrlStaInactiveIndDes, CsrWifiRouterCtrlStaInactiveIndSerFree },
84 { CSR_WIFI_ROUTER_CTRL_WAPI_MULTICAST_IND, CsrWifiRouterCtrlWapiMulticastIndSizeof, CsrWifiRouterCtrlWapiMulticastIndSer, CsrWifiRouterCtrlWapiMulticastIndDes, CsrWifiRouterCtrlWapiMulticastIndSerFree }, 86 { CSR_WIFI_ROUTER_CTRL_WAPI_RX_MIC_CHECK_IND, CsrWifiRouterCtrlWapiRxMicCheckIndSizeof, CsrWifiRouterCtrlWapiRxMicCheckIndSer, CsrWifiRouterCtrlWapiRxMicCheckIndDes, CsrWifiRouterCtrlWapiRxMicCheckIndSerFree },
87 { CSR_WIFI_ROUTER_CTRL_MODE_SET_CFM, CsrWifiRouterCtrlModeSetCfmSizeof, CsrWifiRouterCtrlModeSetCfmSer, CsrWifiRouterCtrlModeSetCfmDes, CsrWifiRouterCtrlModeSetCfmSerFree },
88 { CSR_WIFI_ROUTER_CTRL_WAPI_UNICAST_TX_ENCRYPT_IND, CsrWifiRouterCtrlWapiUnicastTxEncryptIndSizeof, CsrWifiRouterCtrlWapiUnicastTxEncryptIndSer, CsrWifiRouterCtrlWapiUnicastTxEncryptIndDes, CsrWifiRouterCtrlWapiUnicastTxEncryptIndSerFree },
85 89
86 { 0, NULL, NULL, NULL, NULL }, 90 { 0, NULL, NULL, NULL, NULL },
87}; 91};
@@ -90,11 +94,11 @@ CsrMsgConvMsgEntry* CsrWifiRouterCtrlConverterLookup(CsrMsgConvMsgEntry *ce, Csr
90{ 94{
91 if (msgType & CSR_PRIM_UPSTREAM) 95 if (msgType & CSR_PRIM_UPSTREAM)
92 { 96 {
93 CsrUint16 index = (msgType & ~CSR_PRIM_UPSTREAM) + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_COUNT; 97 CsrUint16 idx = (msgType & ~CSR_PRIM_UPSTREAM) + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_COUNT;
94 if (index < (CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_COUNT + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_COUNT) && 98 if (idx < (CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_COUNT + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_COUNT) &&
95 csrwifirouterctrl_conv_lut[index].msgType == msgType) 99 csrwifirouterctrl_conv_lut[idx].msgType == msgType)
96 { 100 {
97 return &csrwifirouterctrl_conv_lut[index]; 101 return &csrwifirouterctrl_conv_lut[idx];
98 } 102 }
99 } 103 }
100 else 104 else
diff --git a/drivers/staging/csr/csr_wifi_router_ctrl_free_downstream_contents.c b/drivers/staging/csr/csr_wifi_router_ctrl_free_downstream_contents.c
index 57aa3673959..d161fad8460 100644
--- a/drivers/staging/csr/csr_wifi_router_ctrl_free_downstream_contents.c
+++ b/drivers/staging/csr/csr_wifi_router_ctrl_free_downstream_contents.c
@@ -1,6 +1,6 @@
1/***************************************************************************** 1/*****************************************************************************
2 2
3 (c) Cambridge Silicon Radio Limited 2011 3 (c) Cambridge Silicon Radio Limited 2012
4 All rights reserved and confidential information of CSR 4 All rights reserved and confidential information of CSR
5 5
6 Refer to LICENSE.txt included with this source for details 6 Refer to LICENSE.txt included with this source for details
@@ -70,6 +70,13 @@ void CsrWifiRouterCtrlFreeDownstreamMessageContents(CsrUint16 eventClass, void *
70 p->tclas = NULL; 70 p->tclas = NULL;
71 break; 71 break;
72 } 72 }
73 case CSR_WIFI_ROUTER_CTRL_WIFI_ON_REQ:
74 {
75 CsrWifiRouterCtrlWifiOnReq *p = (CsrWifiRouterCtrlWifiOnReq *)message;
76 CsrPmemFree(p->data);
77 p->data = NULL;
78 break;
79 }
73 case CSR_WIFI_ROUTER_CTRL_WIFI_ON_RES: 80 case CSR_WIFI_ROUTER_CTRL_WIFI_ON_RES:
74 { 81 {
75 CsrWifiRouterCtrlWifiOnRes *p = (CsrWifiRouterCtrlWifiOnRes *)message; 82 CsrWifiRouterCtrlWifiOnRes *p = (CsrWifiRouterCtrlWifiOnRes *)message;
@@ -77,15 +84,22 @@ void CsrWifiRouterCtrlFreeDownstreamMessageContents(CsrUint16 eventClass, void *
77 p->smeVersions.smeBuild = NULL; 84 p->smeVersions.smeBuild = NULL;
78 break; 85 break;
79 } 86 }
80 case CSR_WIFI_ROUTER_CTRL_WAPI_MULTICAST_REQ: 87 case CSR_WIFI_ROUTER_CTRL_WAPI_RX_PKT_REQ:
81 { 88 {
82 CsrWifiRouterCtrlWapiMulticastReq *p = (CsrWifiRouterCtrlWapiMulticastReq *)message; 89 CsrWifiRouterCtrlWapiRxPktReq *p = (CsrWifiRouterCtrlWapiRxPktReq *)message;
83 CsrPmemFree(p->signal); 90 CsrPmemFree(p->signal);
84 p->signal = NULL; 91 p->signal = NULL;
85 CsrPmemFree(p->data); 92 CsrPmemFree(p->data);
86 p->data = NULL; 93 p->data = NULL;
87 break; 94 break;
88 } 95 }
96 case CSR_WIFI_ROUTER_CTRL_WAPI_UNICAST_TX_PKT_REQ:
97 {
98 CsrWifiRouterCtrlWapiUnicastTxPktReq *p = (CsrWifiRouterCtrlWapiUnicastTxPktReq *)message;
99 CsrPmemFree(p->data);
100 p->data = NULL;
101 break;
102 }
89 103
90 default: 104 default:
91 break; 105 break;
diff --git a/drivers/staging/csr/csr_wifi_router_ctrl_free_upstream_contents.c b/drivers/staging/csr/csr_wifi_router_ctrl_free_upstream_contents.c
index 25e327357a3..b6bf11d566d 100644
--- a/drivers/staging/csr/csr_wifi_router_ctrl_free_upstream_contents.c
+++ b/drivers/staging/csr/csr_wifi_router_ctrl_free_upstream_contents.c
@@ -1,6 +1,6 @@
1/***************************************************************************** 1/*****************************************************************************
2 2
3 (c) Cambridge Silicon Radio Limited 2011 3 (c) Cambridge Silicon Radio Limited 2012
4 All rights reserved and confidential information of CSR 4 All rights reserved and confidential information of CSR
5 5
6 Refer to LICENSE.txt included with this source for details 6 Refer to LICENSE.txt included with this source for details
@@ -63,15 +63,22 @@ void CsrWifiRouterCtrlFreeUpstreamMessageContents(CsrUint16 eventClass, void *me
63 p->versions.routerBuild = NULL; 63 p->versions.routerBuild = NULL;
64 break; 64 break;
65 } 65 }
66 case CSR_WIFI_ROUTER_CTRL_WAPI_MULTICAST_IND: 66 case CSR_WIFI_ROUTER_CTRL_WAPI_RX_MIC_CHECK_IND:
67 { 67 {
68 CsrWifiRouterCtrlWapiMulticastInd *p = (CsrWifiRouterCtrlWapiMulticastInd *)message; 68 CsrWifiRouterCtrlWapiRxMicCheckInd *p = (CsrWifiRouterCtrlWapiRxMicCheckInd *)message;
69 CsrPmemFree(p->signal); 69 CsrPmemFree(p->signal);
70 p->signal = NULL; 70 p->signal = NULL;
71 CsrPmemFree(p->data); 71 CsrPmemFree(p->data);
72 p->data = NULL; 72 p->data = NULL;
73 break; 73 break;
74 } 74 }
75 case CSR_WIFI_ROUTER_CTRL_WAPI_UNICAST_TX_ENCRYPT_IND:
76 {
77 CsrWifiRouterCtrlWapiUnicastTxEncryptInd *p = (CsrWifiRouterCtrlWapiUnicastTxEncryptInd *)message;
78 CsrPmemFree(p->data);
79 p->data = NULL;
80 break;
81 }
75 82
76 default: 83 default:
77 break; 84 break;
diff --git a/drivers/staging/csr/csr_wifi_router_ctrl_lib.h b/drivers/staging/csr/csr_wifi_router_ctrl_lib.h
index f0ad836b00c..6c7e9743757 100644
--- a/drivers/staging/csr/csr_wifi_router_ctrl_lib.h
+++ b/drivers/staging/csr/csr_wifi_router_ctrl_lib.h
@@ -1,6 +1,6 @@
1/***************************************************************************** 1/*****************************************************************************
2 2
3 (c) Cambridge Silicon Radio Limited 2011 3 (c) Cambridge Silicon Radio Limited 2012
4 All rights reserved and confidential information of CSR 4 All rights reserved and confidential information of CSR
5 5
6 Refer to LICENSE.txt included with this source for details 6 Refer to LICENSE.txt included with this source for details
@@ -661,6 +661,39 @@ extern const CsrCharString *CsrWifiRouterCtrlDownstreamPrimNames[CSR_WIFI_ROUTER
661/******************************************************************************* 661/*******************************************************************************
662 662
663 NAME 663 NAME
664 CsrWifiRouterCtrlModeSetCfmSend
665
666 DESCRIPTION
667
668 PARAMETERS
669 queue - Destination Task Queue
670 clientData -
671 interfaceTag -
672 mode -
673 status -
674
675*******************************************************************************/
676#define CsrWifiRouterCtrlModeSetCfmCreate(msg__, dst__, src__, clientData__, interfaceTag__, mode__, status__) \
677 msg__ = (CsrWifiRouterCtrlModeSetCfm *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlModeSetCfm)); \
678 CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_MODE_SET_CFM, dst__, src__); \
679 msg__->clientData = (clientData__); \
680 msg__->interfaceTag = (interfaceTag__); \
681 msg__->mode = (mode__); \
682 msg__->status = (status__);
683
684#define CsrWifiRouterCtrlModeSetCfmSendTo(dst__, src__, clientData__, interfaceTag__, mode__, status__) \
685 { \
686 CsrWifiRouterCtrlModeSetCfm *msg__; \
687 CsrWifiRouterCtrlModeSetCfmCreate(msg__, dst__, src__, clientData__, interfaceTag__, mode__, status__); \
688 CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
689 }
690
691#define CsrWifiRouterCtrlModeSetCfmSend(dst__, clientData__, interfaceTag__, mode__, status__) \
692 CsrWifiRouterCtrlModeSetCfmSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, interfaceTag__, mode__, status__)
693
694/*******************************************************************************
695
696 NAME
664 CsrWifiRouterCtrlMulticastAddressIndSend 697 CsrWifiRouterCtrlMulticastAddressIndSend
665 698
666 DESCRIPTION 699 DESCRIPTION
@@ -1597,73 +1630,107 @@ extern const CsrCharString *CsrWifiRouterCtrlDownstreamPrimNames[CSR_WIFI_ROUTER
1597/******************************************************************************* 1630/*******************************************************************************
1598 1631
1599 NAME 1632 NAME
1633 CsrWifiRouterCtrlWapiFilterReqSend
1634
1635 DESCRIPTION
1636
1637 PARAMETERS
1638 queue - Message Source Task Queue (Cfm's will be sent to this Queue)
1639 interfaceTag -
1640 isWapiConnected -
1641
1642*******************************************************************************/
1643#define CsrWifiRouterCtrlWapiFilterReqCreate(msg__, dst__, src__, interfaceTag__, isWapiConnected__) \
1644 msg__ = (CsrWifiRouterCtrlWapiFilterReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlWapiFilterReq)); \
1645 CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_WAPI_FILTER_REQ, dst__, src__); \
1646 msg__->interfaceTag = (interfaceTag__); \
1647 msg__->isWapiConnected = (isWapiConnected__);
1648
1649#define CsrWifiRouterCtrlWapiFilterReqSendTo(dst__, src__, interfaceTag__, isWapiConnected__) \
1650 { \
1651 CsrWifiRouterCtrlWapiFilterReq *msg__; \
1652 CsrWifiRouterCtrlWapiFilterReqCreate(msg__, dst__, src__, interfaceTag__, isWapiConnected__); \
1653 CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
1654 }
1655
1656#define CsrWifiRouterCtrlWapiFilterReqSend(src__, interfaceTag__, isWapiConnected__) \
1657 CsrWifiRouterCtrlWapiFilterReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, interfaceTag__, isWapiConnected__)
1658
1659/*******************************************************************************
1660
1661 NAME
1600 CsrWifiRouterCtrlWapiMulticastFilterReqSend 1662 CsrWifiRouterCtrlWapiMulticastFilterReqSend
1601 1663
1602 DESCRIPTION 1664 DESCRIPTION
1603 1665
1604 PARAMETERS 1666 PARAMETERS
1605 queue - Message Source Task Queue (Cfm's will be sent to this Queue) 1667 queue - Message Source Task Queue (Cfm's will be sent to this Queue)
1606 status - 1668 interfaceTag -
1669 status -
1607 1670
1608*******************************************************************************/ 1671*******************************************************************************/
1609#define CsrWifiRouterCtrlWapiMulticastFilterReqCreate(msg__, dst__, src__, status__) \ 1672#define CsrWifiRouterCtrlWapiMulticastFilterReqCreate(msg__, dst__, src__, interfaceTag__, status__) \
1610 msg__ = (CsrWifiRouterCtrlWapiMulticastFilterReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlWapiMulticastFilterReq)); \ 1673 msg__ = (CsrWifiRouterCtrlWapiMulticastFilterReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlWapiMulticastFilterReq)); \
1611 CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_WAPI_MULTICAST_FILTER_REQ, dst__, src__); \ 1674 CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_WAPI_MULTICAST_FILTER_REQ, dst__, src__); \
1675 msg__->interfaceTag = (interfaceTag__); \
1612 msg__->status = (status__); 1676 msg__->status = (status__);
1613 1677
1614#define CsrWifiRouterCtrlWapiMulticastFilterReqSendTo(dst__, src__, status__) \ 1678#define CsrWifiRouterCtrlWapiMulticastFilterReqSendTo(dst__, src__, interfaceTag__, status__) \
1615 { \ 1679 { \
1616 CsrWifiRouterCtrlWapiMulticastFilterReq *msg__; \ 1680 CsrWifiRouterCtrlWapiMulticastFilterReq *msg__; \
1617 CsrWifiRouterCtrlWapiMulticastFilterReqCreate(msg__, dst__, src__, status__); \ 1681 CsrWifiRouterCtrlWapiMulticastFilterReqCreate(msg__, dst__, src__, interfaceTag__, status__); \
1618 CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ 1682 CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
1619 } 1683 }
1620 1684
1621#define CsrWifiRouterCtrlWapiMulticastFilterReqSend(src__, status__) \ 1685#define CsrWifiRouterCtrlWapiMulticastFilterReqSend(src__, interfaceTag__, status__) \
1622 CsrWifiRouterCtrlWapiMulticastFilterReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, status__) 1686 CsrWifiRouterCtrlWapiMulticastFilterReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, interfaceTag__, status__)
1623 1687
1624/******************************************************************************* 1688/*******************************************************************************
1625 1689
1626 NAME 1690 NAME
1627 CsrWifiRouterCtrlWapiMulticastReqSend 1691 CsrWifiRouterCtrlWapiRxMicCheckIndSend
1628 1692
1629 DESCRIPTION 1693 DESCRIPTION
1630 1694
1631 PARAMETERS 1695 PARAMETERS
1632 queue - Message Source Task Queue (Cfm's will be sent to this Queue) 1696 queue - Destination Task Queue
1697 clientData -
1698 interfaceTag -
1633 signalLength - 1699 signalLength -
1634 signal - 1700 signal -
1635 dataLength - 1701 dataLength -
1636 data - 1702 data -
1637 1703
1638*******************************************************************************/ 1704*******************************************************************************/
1639#define CsrWifiRouterCtrlWapiMulticastReqCreate(msg__, dst__, src__, signalLength__, signal__, dataLength__, data__) \ 1705#define CsrWifiRouterCtrlWapiRxMicCheckIndCreate(msg__, dst__, src__, clientData__, interfaceTag__, signalLength__, signal__, dataLength__, data__) \
1640 msg__ = (CsrWifiRouterCtrlWapiMulticastReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlWapiMulticastReq)); \ 1706 msg__ = (CsrWifiRouterCtrlWapiRxMicCheckInd *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlWapiRxMicCheckInd)); \
1641 CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_WAPI_MULTICAST_REQ, dst__, src__); \ 1707 CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_WAPI_RX_MIC_CHECK_IND, dst__, src__); \
1708 msg__->clientData = (clientData__); \
1709 msg__->interfaceTag = (interfaceTag__); \
1642 msg__->signalLength = (signalLength__); \ 1710 msg__->signalLength = (signalLength__); \
1643 msg__->signal = (signal__); \ 1711 msg__->signal = (signal__); \
1644 msg__->dataLength = (dataLength__); \ 1712 msg__->dataLength = (dataLength__); \
1645 msg__->data = (data__); 1713 msg__->data = (data__);
1646 1714
1647#define CsrWifiRouterCtrlWapiMulticastReqSendTo(dst__, src__, signalLength__, signal__, dataLength__, data__) \ 1715#define CsrWifiRouterCtrlWapiRxMicCheckIndSendTo(dst__, src__, clientData__, interfaceTag__, signalLength__, signal__, dataLength__, data__) \
1648 { \ 1716 { \
1649 CsrWifiRouterCtrlWapiMulticastReq *msg__; \ 1717 CsrWifiRouterCtrlWapiRxMicCheckInd *msg__; \
1650 CsrWifiRouterCtrlWapiMulticastReqCreate(msg__, dst__, src__, signalLength__, signal__, dataLength__, data__); \ 1718 CsrWifiRouterCtrlWapiRxMicCheckIndCreate(msg__, dst__, src__, clientData__, interfaceTag__, signalLength__, signal__, dataLength__, data__); \
1651 CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ 1719 CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
1652 } 1720 }
1653 1721
1654#define CsrWifiRouterCtrlWapiMulticastReqSend(src__, signalLength__, signal__, dataLength__, data__) \ 1722#define CsrWifiRouterCtrlWapiRxMicCheckIndSend(dst__, clientData__, interfaceTag__, signalLength__, signal__, dataLength__, data__) \
1655 CsrWifiRouterCtrlWapiMulticastReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, signalLength__, signal__, dataLength__, data__) 1723 CsrWifiRouterCtrlWapiRxMicCheckIndSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, interfaceTag__, signalLength__, signal__, dataLength__, data__)
1656 1724
1657/******************************************************************************* 1725/*******************************************************************************
1658 1726
1659 NAME 1727 NAME
1660 CsrWifiRouterCtrlWapiMulticastIndSend 1728 CsrWifiRouterCtrlWapiRxPktReqSend
1661 1729
1662 DESCRIPTION 1730 DESCRIPTION
1663 1731
1664 PARAMETERS 1732 PARAMETERS
1665 queue - Destination Task Queue 1733 queue - Message Source Task Queue (Cfm's will be sent to this Queue)
1666 clientData -
1667 interfaceTag - 1734 interfaceTag -
1668 signalLength - 1735 signalLength -
1669 signal - 1736 signal -
@@ -1671,25 +1738,24 @@ extern const CsrCharString *CsrWifiRouterCtrlDownstreamPrimNames[CSR_WIFI_ROUTER
1671 data - 1738 data -
1672 1739
1673*******************************************************************************/ 1740*******************************************************************************/
1674#define CsrWifiRouterCtrlWapiMulticastIndCreate(msg__, dst__, src__, clientData__, interfaceTag__, signalLength__, signal__, dataLength__, data__) \ 1741#define CsrWifiRouterCtrlWapiRxPktReqCreate(msg__, dst__, src__, interfaceTag__, signalLength__, signal__, dataLength__, data__) \
1675 msg__ = (CsrWifiRouterCtrlWapiMulticastInd *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlWapiMulticastInd)); \ 1742 msg__ = (CsrWifiRouterCtrlWapiRxPktReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlWapiRxPktReq)); \
1676 CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_WAPI_MULTICAST_IND, dst__, src__); \ 1743 CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_WAPI_RX_PKT_REQ, dst__, src__); \
1677 msg__->clientData = (clientData__); \
1678 msg__->interfaceTag = (interfaceTag__); \ 1744 msg__->interfaceTag = (interfaceTag__); \
1679 msg__->signalLength = (signalLength__); \ 1745 msg__->signalLength = (signalLength__); \
1680 msg__->signal = (signal__); \ 1746 msg__->signal = (signal__); \
1681 msg__->dataLength = (dataLength__); \ 1747 msg__->dataLength = (dataLength__); \
1682 msg__->data = (data__); 1748 msg__->data = (data__);
1683 1749
1684#define CsrWifiRouterCtrlWapiMulticastIndSendTo(dst__, src__, clientData__, interfaceTag__, signalLength__, signal__, dataLength__, data__) \ 1750#define CsrWifiRouterCtrlWapiRxPktReqSendTo(dst__, src__, interfaceTag__, signalLength__, signal__, dataLength__, data__) \
1685 { \ 1751 { \
1686 CsrWifiRouterCtrlWapiMulticastInd *msg__; \ 1752 CsrWifiRouterCtrlWapiRxPktReq *msg__; \
1687 CsrWifiRouterCtrlWapiMulticastIndCreate(msg__, dst__, src__, clientData__, interfaceTag__, signalLength__, signal__, dataLength__, data__); \ 1753 CsrWifiRouterCtrlWapiRxPktReqCreate(msg__, dst__, src__, interfaceTag__, signalLength__, signal__, dataLength__, data__); \
1688 CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ 1754 CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
1689 } 1755 }
1690 1756
1691#define CsrWifiRouterCtrlWapiMulticastIndSend(dst__, clientData__, interfaceTag__, signalLength__, signal__, dataLength__, data__) \ 1757#define CsrWifiRouterCtrlWapiRxPktReqSend(src__, interfaceTag__, signalLength__, signal__, dataLength__, data__) \
1692 CsrWifiRouterCtrlWapiMulticastIndSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, interfaceTag__, signalLength__, signal__, dataLength__, data__) 1758 CsrWifiRouterCtrlWapiRxPktReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, interfaceTag__, signalLength__, signal__, dataLength__, data__)
1693 1759
1694/******************************************************************************* 1760/*******************************************************************************
1695 1761
@@ -1699,24 +1765,90 @@ extern const CsrCharString *CsrWifiRouterCtrlDownstreamPrimNames[CSR_WIFI_ROUTER
1699 DESCRIPTION 1765 DESCRIPTION
1700 1766
1701 PARAMETERS 1767 PARAMETERS
1702 queue - Message Source Task Queue (Cfm's will be sent to this Queue) 1768 queue - Message Source Task Queue (Cfm's will be sent to this Queue)
1703 status - 1769 interfaceTag -
1770 status -
1704 1771
1705*******************************************************************************/ 1772*******************************************************************************/
1706#define CsrWifiRouterCtrlWapiUnicastFilterReqCreate(msg__, dst__, src__, status__) \ 1773#define CsrWifiRouterCtrlWapiUnicastFilterReqCreate(msg__, dst__, src__, interfaceTag__, status__) \
1707 msg__ = (CsrWifiRouterCtrlWapiUnicastFilterReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlWapiUnicastFilterReq)); \ 1774 msg__ = (CsrWifiRouterCtrlWapiUnicastFilterReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlWapiUnicastFilterReq)); \
1708 CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_WAPI_UNICAST_FILTER_REQ, dst__, src__); \ 1775 CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_WAPI_UNICAST_FILTER_REQ, dst__, src__); \
1776 msg__->interfaceTag = (interfaceTag__); \
1709 msg__->status = (status__); 1777 msg__->status = (status__);
1710 1778
1711#define CsrWifiRouterCtrlWapiUnicastFilterReqSendTo(dst__, src__, status__) \ 1779#define CsrWifiRouterCtrlWapiUnicastFilterReqSendTo(dst__, src__, interfaceTag__, status__) \
1712 { \ 1780 { \
1713 CsrWifiRouterCtrlWapiUnicastFilterReq *msg__; \ 1781 CsrWifiRouterCtrlWapiUnicastFilterReq *msg__; \
1714 CsrWifiRouterCtrlWapiUnicastFilterReqCreate(msg__, dst__, src__, status__); \ 1782 CsrWifiRouterCtrlWapiUnicastFilterReqCreate(msg__, dst__, src__, interfaceTag__, status__); \
1783 CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
1784 }
1785
1786#define CsrWifiRouterCtrlWapiUnicastFilterReqSend(src__, interfaceTag__, status__) \
1787 CsrWifiRouterCtrlWapiUnicastFilterReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, interfaceTag__, status__)
1788
1789/*******************************************************************************
1790
1791 NAME
1792 CsrWifiRouterCtrlWapiUnicastTxEncryptIndSend
1793
1794 DESCRIPTION
1795
1796 PARAMETERS
1797 queue - Destination Task Queue
1798 clientData -
1799 interfaceTag -
1800 dataLength -
1801 data -
1802
1803*******************************************************************************/
1804#define CsrWifiRouterCtrlWapiUnicastTxEncryptIndCreate(msg__, dst__, src__, clientData__, interfaceTag__, dataLength__, data__) \
1805 msg__ = (CsrWifiRouterCtrlWapiUnicastTxEncryptInd *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlWapiUnicastTxEncryptInd)); \
1806 CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_WAPI_UNICAST_TX_ENCRYPT_IND, dst__, src__); \
1807 msg__->clientData = (clientData__); \
1808 msg__->interfaceTag = (interfaceTag__); \
1809 msg__->dataLength = (dataLength__); \
1810 msg__->data = (data__);
1811
1812#define CsrWifiRouterCtrlWapiUnicastTxEncryptIndSendTo(dst__, src__, clientData__, interfaceTag__, dataLength__, data__) \
1813 { \
1814 CsrWifiRouterCtrlWapiUnicastTxEncryptInd *msg__; \
1815 CsrWifiRouterCtrlWapiUnicastTxEncryptIndCreate(msg__, dst__, src__, clientData__, interfaceTag__, dataLength__, data__); \
1816 CsrSchedMessagePut(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
1817 }
1818
1819#define CsrWifiRouterCtrlWapiUnicastTxEncryptIndSend(dst__, clientData__, interfaceTag__, dataLength__, data__) \
1820 CsrWifiRouterCtrlWapiUnicastTxEncryptIndSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, interfaceTag__, dataLength__, data__)
1821
1822/*******************************************************************************
1823
1824 NAME
1825 CsrWifiRouterCtrlWapiUnicastTxPktReqSend
1826
1827 DESCRIPTION
1828
1829 PARAMETERS
1830 queue - Message Source Task Queue (Cfm's will be sent to this Queue)
1831 interfaceTag -
1832 dataLength -
1833 data -
1834
1835*******************************************************************************/
1836#define CsrWifiRouterCtrlWapiUnicastTxPktReqCreate(msg__, dst__, src__, interfaceTag__, dataLength__, data__) \
1837 msg__ = (CsrWifiRouterCtrlWapiUnicastTxPktReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlWapiUnicastTxPktReq)); \
1838 CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_WAPI_UNICAST_TX_PKT_REQ, dst__, src__); \
1839 msg__->interfaceTag = (interfaceTag__); \
1840 msg__->dataLength = (dataLength__); \
1841 msg__->data = (data__);
1842
1843#define CsrWifiRouterCtrlWapiUnicastTxPktReqSendTo(dst__, src__, interfaceTag__, dataLength__, data__) \
1844 { \
1845 CsrWifiRouterCtrlWapiUnicastTxPktReq *msg__; \
1846 CsrWifiRouterCtrlWapiUnicastTxPktReqCreate(msg__, dst__, src__, interfaceTag__, dataLength__, data__); \
1715 CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ 1847 CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
1716 } 1848 }
1717 1849
1718#define CsrWifiRouterCtrlWapiUnicastFilterReqSend(src__, status__) \ 1850#define CsrWifiRouterCtrlWapiUnicastTxPktReqSend(src__, interfaceTag__, dataLength__, data__) \
1719 CsrWifiRouterCtrlWapiUnicastFilterReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, status__) 1851 CsrWifiRouterCtrlWapiUnicastTxPktReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, interfaceTag__, dataLength__, data__)
1720 1852
1721/******************************************************************************* 1853/*******************************************************************************
1722 1854
@@ -1837,22 +1969,26 @@ extern const CsrCharString *CsrWifiRouterCtrlDownstreamPrimNames[CSR_WIFI_ROUTER
1837 PARAMETERS 1969 PARAMETERS
1838 queue - Message Source Task Queue (Cfm's will be sent to this Queue) 1970 queue - Message Source Task Queue (Cfm's will be sent to this Queue)
1839 clientData - 1971 clientData -
1972 dataLength - Number of bytes in the buffer pointed to by 'data'
1973 data - Pointer to the buffer containing 'dataLength' bytes
1840 1974
1841*******************************************************************************/ 1975*******************************************************************************/
1842#define CsrWifiRouterCtrlWifiOnReqCreate(msg__, dst__, src__, clientData__) \ 1976#define CsrWifiRouterCtrlWifiOnReqCreate(msg__, dst__, src__, clientData__, dataLength__, data__) \
1843 msg__ = (CsrWifiRouterCtrlWifiOnReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlWifiOnReq)); \ 1977 msg__ = (CsrWifiRouterCtrlWifiOnReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlWifiOnReq)); \
1844 CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_WIFI_ON_REQ, dst__, src__); \ 1978 CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_ROUTER_CTRL_PRIM, CSR_WIFI_ROUTER_CTRL_WIFI_ON_REQ, dst__, src__); \
1845 msg__->clientData = (clientData__); 1979 msg__->clientData = (clientData__); \
1980 msg__->dataLength = (dataLength__); \
1981 msg__->data = (data__);
1846 1982
1847#define CsrWifiRouterCtrlWifiOnReqSendTo(dst__, src__, clientData__) \ 1983#define CsrWifiRouterCtrlWifiOnReqSendTo(dst__, src__, clientData__, dataLength__, data__) \
1848 { \ 1984 { \
1849 CsrWifiRouterCtrlWifiOnReq *msg__; \ 1985 CsrWifiRouterCtrlWifiOnReq *msg__; \
1850 CsrWifiRouterCtrlWifiOnReqCreate(msg__, dst__, src__, clientData__); \ 1986 CsrWifiRouterCtrlWifiOnReqCreate(msg__, dst__, src__, clientData__, dataLength__, data__); \
1851 CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \ 1987 CsrMsgTransport(dst__, CSR_WIFI_ROUTER_CTRL_PRIM, msg__); \
1852 } 1988 }
1853 1989
1854#define CsrWifiRouterCtrlWifiOnReqSend(src__, clientData__) \ 1990#define CsrWifiRouterCtrlWifiOnReqSend(src__, clientData__, dataLength__, data__) \
1855 CsrWifiRouterCtrlWifiOnReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, clientData__) 1991 CsrWifiRouterCtrlWifiOnReqSendTo(CSR_WIFI_ROUTER_IFACEQUEUE, src__, clientData__, dataLength__, data__)
1856 1992
1857/******************************************************************************* 1993/*******************************************************************************
1858 1994
diff --git a/drivers/staging/csr/csr_wifi_router_ctrl_prim.h b/drivers/staging/csr/csr_wifi_router_ctrl_prim.h
index 954f600b4ff..810482a8fba 100644
--- a/drivers/staging/csr/csr_wifi_router_ctrl_prim.h
+++ b/drivers/staging/csr/csr_wifi_router_ctrl_prim.h
@@ -1,6 +1,6 @@
1/***************************************************************************** 1/*****************************************************************************
2 2
3 (c) Cambridge Silicon Radio Limited 2011 3 (c) Cambridge Silicon Radio Limited 2012
4 All rights reserved and confidential information of CSR 4 All rights reserved and confidential information of CSR
5 5
6 Refer to LICENSE.txt included with this source for details 6 Refer to LICENSE.txt included with this source for details
@@ -616,12 +616,14 @@ typedef struct
616#define CSR_WIFI_ROUTER_CTRL_CAPABILITIES_REQ ((CsrWifiRouterCtrlPrim) (0x0017 + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST)) 616#define CSR_WIFI_ROUTER_CTRL_CAPABILITIES_REQ ((CsrWifiRouterCtrlPrim) (0x0017 + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST))
617#define CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_ENABLE_REQ ((CsrWifiRouterCtrlPrim) (0x0018 + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST)) 617#define CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_ENABLE_REQ ((CsrWifiRouterCtrlPrim) (0x0018 + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST))
618#define CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_DISABLE_REQ ((CsrWifiRouterCtrlPrim) (0x0019 + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST)) 618#define CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_DISABLE_REQ ((CsrWifiRouterCtrlPrim) (0x0019 + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST))
619#define CSR_WIFI_ROUTER_CTRL_WAPI_MULTICAST_REQ ((CsrWifiRouterCtrlPrim) (0x001A + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST)) 619#define CSR_WIFI_ROUTER_CTRL_WAPI_RX_PKT_REQ ((CsrWifiRouterCtrlPrim) (0x001A + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST))
620#define CSR_WIFI_ROUTER_CTRL_WAPI_MULTICAST_FILTER_REQ ((CsrWifiRouterCtrlPrim) (0x001B + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST)) 620#define CSR_WIFI_ROUTER_CTRL_WAPI_MULTICAST_FILTER_REQ ((CsrWifiRouterCtrlPrim) (0x001B + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST))
621#define CSR_WIFI_ROUTER_CTRL_WAPI_UNICAST_FILTER_REQ ((CsrWifiRouterCtrlPrim) (0x001C + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST)) 621#define CSR_WIFI_ROUTER_CTRL_WAPI_UNICAST_FILTER_REQ ((CsrWifiRouterCtrlPrim) (0x001C + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST))
622#define CSR_WIFI_ROUTER_CTRL_WAPI_UNICAST_TX_PKT_REQ ((CsrWifiRouterCtrlPrim) (0x001D + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST))
623#define CSR_WIFI_ROUTER_CTRL_WAPI_FILTER_REQ ((CsrWifiRouterCtrlPrim) (0x001E + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST))
622 624
623 625
624#define CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_HIGHEST (0x001C + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST) 626#define CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_HIGHEST (0x001E + CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST)
625 627
626/* Upstream */ 628/* Upstream */
627#define CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST (0x0000 + CSR_PRIM_UPSTREAM) 629#define CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST (0x0000 + CSR_PRIM_UPSTREAM)
@@ -654,9 +656,11 @@ typedef struct
654#define CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_DISABLE_CFM ((CsrWifiRouterCtrlPrim)(0x0019 + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST)) 656#define CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_DISABLE_CFM ((CsrWifiRouterCtrlPrim)(0x0019 + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST))
655#define CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_ERROR_IND ((CsrWifiRouterCtrlPrim)(0x001A + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST)) 657#define CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_ERROR_IND ((CsrWifiRouterCtrlPrim)(0x001A + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST))
656#define CSR_WIFI_ROUTER_CTRL_STA_INACTIVE_IND ((CsrWifiRouterCtrlPrim)(0x001B + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST)) 658#define CSR_WIFI_ROUTER_CTRL_STA_INACTIVE_IND ((CsrWifiRouterCtrlPrim)(0x001B + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST))
657#define CSR_WIFI_ROUTER_CTRL_WAPI_MULTICAST_IND ((CsrWifiRouterCtrlPrim)(0x001C + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST)) 659#define CSR_WIFI_ROUTER_CTRL_WAPI_RX_MIC_CHECK_IND ((CsrWifiRouterCtrlPrim)(0x001C + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST))
660#define CSR_WIFI_ROUTER_CTRL_MODE_SET_CFM ((CsrWifiRouterCtrlPrim)(0x001D + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST))
661#define CSR_WIFI_ROUTER_CTRL_WAPI_UNICAST_TX_ENCRYPT_IND ((CsrWifiRouterCtrlPrim)(0x001E + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST))
658 662
659#define CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_HIGHEST (0x001C + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST) 663#define CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_HIGHEST (0x001E + CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST)
660 664
661#define CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_COUNT (CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_HIGHEST + 1 - CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST) 665#define CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_COUNT (CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_HIGHEST + 1 - CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST)
662#define CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_COUNT (CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_HIGHEST + 1 - CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST) 666#define CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_COUNT (CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_HIGHEST + 1 - CSR_WIFI_ROUTER_CTRL_PRIM_UPSTREAM_LOWEST)
@@ -1032,12 +1036,16 @@ typedef struct
1032 MEMBERS 1036 MEMBERS
1033 common - Common header for use with the CsrWifiFsm Module 1037 common - Common header for use with the CsrWifiFsm Module
1034 clientData - 1038 clientData -
1039 dataLength - Number of bytes in the buffer pointed to by 'data'
1040 data - Pointer to the buffer containing 'dataLength' bytes
1035 1041
1036*******************************************************************************/ 1042*******************************************************************************/
1037typedef struct 1043typedef struct
1038{ 1044{
1039 CsrWifiFsmEvent common; 1045 CsrWifiFsmEvent common;
1040 CsrWifiRouterCtrlRequestorInfo clientData; 1046 CsrWifiRouterCtrlRequestorInfo clientData;
1047 CsrUint32 dataLength;
1048 CsrUint8 *data;
1041} CsrWifiRouterCtrlWifiOnReq; 1049} CsrWifiRouterCtrlWifiOnReq;
1042 1050
1043/******************************************************************************* 1051/*******************************************************************************
@@ -1273,12 +1281,13 @@ typedef struct
1273/******************************************************************************* 1281/*******************************************************************************
1274 1282
1275 NAME 1283 NAME
1276 CsrWifiRouterCtrlWapiMulticastReq 1284 CsrWifiRouterCtrlWapiRxPktReq
1277 1285
1278 DESCRIPTION 1286 DESCRIPTION
1279 1287
1280 MEMBERS 1288 MEMBERS
1281 common - Common header for use with the CsrWifiFsm Module 1289 common - Common header for use with the CsrWifiFsm Module
1290 interfaceTag -
1282 signalLength - 1291 signalLength -
1283 signal - 1292 signal -
1284 dataLength - 1293 dataLength -
@@ -1288,11 +1297,12 @@ typedef struct
1288typedef struct 1297typedef struct
1289{ 1298{
1290 CsrWifiFsmEvent common; 1299 CsrWifiFsmEvent common;
1300 CsrUint16 interfaceTag;
1291 CsrUint16 signalLength; 1301 CsrUint16 signalLength;
1292 CsrUint8 *signal; 1302 CsrUint8 *signal;
1293 CsrUint16 dataLength; 1303 CsrUint16 dataLength;
1294 CsrUint8 *data; 1304 CsrUint8 *data;
1295} CsrWifiRouterCtrlWapiMulticastReq; 1305} CsrWifiRouterCtrlWapiRxPktReq;
1296 1306
1297/******************************************************************************* 1307/*******************************************************************************
1298 1308
@@ -1302,13 +1312,15 @@ typedef struct
1302 DESCRIPTION 1312 DESCRIPTION
1303 1313
1304 MEMBERS 1314 MEMBERS
1305 common - Common header for use with the CsrWifiFsm Module 1315 common - Common header for use with the CsrWifiFsm Module
1306 status - 1316 interfaceTag -
1317 status -
1307 1318
1308*******************************************************************************/ 1319*******************************************************************************/
1309typedef struct 1320typedef struct
1310{ 1321{
1311 CsrWifiFsmEvent common; 1322 CsrWifiFsmEvent common;
1323 CsrUint16 interfaceTag;
1312 CsrUint8 status; 1324 CsrUint8 status;
1313} CsrWifiRouterCtrlWapiMulticastFilterReq; 1325} CsrWifiRouterCtrlWapiMulticastFilterReq;
1314 1326
@@ -1320,19 +1332,63 @@ typedef struct
1320 DESCRIPTION 1332 DESCRIPTION
1321 1333
1322 MEMBERS 1334 MEMBERS
1323 common - Common header for use with the CsrWifiFsm Module 1335 common - Common header for use with the CsrWifiFsm Module
1324 status - 1336 interfaceTag -
1337 status -
1325 1338
1326*******************************************************************************/ 1339*******************************************************************************/
1327typedef struct 1340typedef struct
1328{ 1341{
1329 CsrWifiFsmEvent common; 1342 CsrWifiFsmEvent common;
1343 CsrUint16 interfaceTag;
1330 CsrUint8 status; 1344 CsrUint8 status;
1331} CsrWifiRouterCtrlWapiUnicastFilterReq; 1345} CsrWifiRouterCtrlWapiUnicastFilterReq;
1332 1346
1333/******************************************************************************* 1347/*******************************************************************************
1334 1348
1335 NAME 1349 NAME
1350 CsrWifiRouterCtrlWapiUnicastTxPktReq
1351
1352 DESCRIPTION
1353
1354 MEMBERS
1355 common - Common header for use with the CsrWifiFsm Module
1356 interfaceTag -
1357 dataLength -
1358 data -
1359
1360*******************************************************************************/
1361typedef struct
1362{
1363 CsrWifiFsmEvent common;
1364 CsrUint16 interfaceTag;
1365 CsrUint16 dataLength;
1366 CsrUint8 *data;
1367} CsrWifiRouterCtrlWapiUnicastTxPktReq;
1368
1369/*******************************************************************************
1370
1371 NAME
1372 CsrWifiRouterCtrlWapiFilterReq
1373
1374 DESCRIPTION
1375
1376 MEMBERS
1377 common - Common header for use with the CsrWifiFsm Module
1378 interfaceTag -
1379 isWapiConnected -
1380
1381*******************************************************************************/
1382typedef struct
1383{
1384 CsrWifiFsmEvent common;
1385 CsrUint16 interfaceTag;
1386 CsrBool isWapiConnected;
1387} CsrWifiRouterCtrlWapiFilterReq;
1388
1389/*******************************************************************************
1390
1391 NAME
1336 CsrWifiRouterCtrlHipInd 1392 CsrWifiRouterCtrlHipInd
1337 1393
1338 DESCRIPTION 1394 DESCRIPTION
@@ -1984,7 +2040,7 @@ typedef struct
1984/******************************************************************************* 2040/*******************************************************************************
1985 2041
1986 NAME 2042 NAME
1987 CsrWifiRouterCtrlWapiMulticastInd 2043 CsrWifiRouterCtrlWapiRxMicCheckInd
1988 2044
1989 DESCRIPTION 2045 DESCRIPTION
1990 2046
@@ -2007,7 +2063,55 @@ typedef struct
2007 CsrUint8 *signal; 2063 CsrUint8 *signal;
2008 CsrUint16 dataLength; 2064 CsrUint16 dataLength;
2009 CsrUint8 *data; 2065 CsrUint8 *data;
2010} CsrWifiRouterCtrlWapiMulticastInd; 2066} CsrWifiRouterCtrlWapiRxMicCheckInd;
2067
2068/*******************************************************************************
2069
2070 NAME
2071 CsrWifiRouterCtrlModeSetCfm
2072
2073 DESCRIPTION
2074
2075 MEMBERS
2076 common - Common header for use with the CsrWifiFsm Module
2077 clientData -
2078 interfaceTag -
2079 mode -
2080 status -
2081
2082*******************************************************************************/
2083typedef struct
2084{
2085 CsrWifiFsmEvent common;
2086 CsrWifiRouterCtrlRequestorInfo clientData;
2087 CsrUint16 interfaceTag;
2088 CsrWifiRouterCtrlMode mode;
2089 CsrResult status;
2090} CsrWifiRouterCtrlModeSetCfm;
2091
2092/*******************************************************************************
2093
2094 NAME
2095 CsrWifiRouterCtrlWapiUnicastTxEncryptInd
2096
2097 DESCRIPTION
2098
2099 MEMBERS
2100 common - Common header for use with the CsrWifiFsm Module
2101 clientData -
2102 interfaceTag -
2103 dataLength -
2104 data -
2105
2106*******************************************************************************/
2107typedef struct
2108{
2109 CsrWifiFsmEvent common;
2110 CsrWifiRouterCtrlRequestorInfo clientData;
2111 CsrUint16 interfaceTag;
2112 CsrUint16 dataLength;
2113 CsrUint8 *data;
2114} CsrWifiRouterCtrlWapiUnicastTxEncryptInd;
2011 2115
2012 2116
2013#ifdef __cplusplus 2117#ifdef __cplusplus
diff --git a/drivers/staging/csr/csr_wifi_router_ctrl_sef.c b/drivers/staging/csr/csr_wifi_router_ctrl_sef.c
index b7fa6a1eb52..33d92b698c5 100644
--- a/drivers/staging/csr/csr_wifi_router_ctrl_sef.c
+++ b/drivers/staging/csr/csr_wifi_router_ctrl_sef.c
@@ -35,9 +35,11 @@ const CsrWifiRouterCtrlStateHandlerType CsrWifiRouterCtrlDownstreamStateHandlers
35 /* 0x0015 */ CsrWifiRouterCtrlPeerDelReqHandler, 35 /* 0x0015 */ CsrWifiRouterCtrlPeerDelReqHandler,
36 /* 0x0016 */ CsrWifiRouterCtrlPeerUpdateReqHandler, 36 /* 0x0016 */ CsrWifiRouterCtrlPeerUpdateReqHandler,
37 /* 0x0017 */ CsrWifiRouterCtrlCapabilitiesReqHandler, 37 /* 0x0017 */ CsrWifiRouterCtrlCapabilitiesReqHandler,
38 CsrWifiRouterCtrlBlockAckEnableReqHandler, /* 0x0018 */ 38 /* 0x0018 */ CsrWifiRouterCtrlBlockAckEnableReqHandler,
39 CsrWifiRouterCtrlBlockAckDisableReqHandler, /* 0x0019 */ 39 /* 0x0019 */ CsrWifiRouterCtrlBlockAckDisableReqHandler,
40 CsrWifiRouterCtrlWapiMulticastReqHandler, /* 0x001A */ 40 /* 0x001A */ CsrWifiRouterCtrlWapiRxPktReqHandler,
41 CsrWifiRouterCtrlWapiMulticastFilterReqHandler, /* 0x001B */ 41 /* 0x001B */ CsrWifiRouterCtrlWapiMulticastFilterReqHandler,
42 CsrWifiRouterCtrlWapiUnicastFilterReqHandler, /* 0x001C */ 42 /* 0x001C */ CsrWifiRouterCtrlWapiUnicastFilterReqHandler,
43 /* 0x001D */ CsrWifiRouterCtrlWapiUnicastTxPktReqHandler,
44 /* 0x001E */ CsrWifiRouterCtrlWapiFilterReqHandler,
43}; 45};
diff --git a/drivers/staging/csr/csr_wifi_router_ctrl_sef.h b/drivers/staging/csr/csr_wifi_router_ctrl_sef.h
index 07382ef8cce..e0ee5cf45f9 100644
--- a/drivers/staging/csr/csr_wifi_router_ctrl_sef.h
+++ b/drivers/staging/csr/csr_wifi_router_ctrl_sef.h
@@ -47,8 +47,10 @@ extern "C" {
47 extern void CsrWifiRouterCtrlBlockAckEnableReqHandler(void* drvpriv, CsrWifiFsmEvent* msg); 47 extern void CsrWifiRouterCtrlBlockAckEnableReqHandler(void* drvpriv, CsrWifiFsmEvent* msg);
48 extern void CsrWifiRouterCtrlBlockAckDisableReqHandler(void* drvpriv, CsrWifiFsmEvent* msg); 48 extern void CsrWifiRouterCtrlBlockAckDisableReqHandler(void* drvpriv, CsrWifiFsmEvent* msg);
49 extern void CsrWifiRouterCtrlWapiMulticastFilterReqHandler(void* drvpriv, CsrWifiFsmEvent* msg); 49 extern void CsrWifiRouterCtrlWapiMulticastFilterReqHandler(void* drvpriv, CsrWifiFsmEvent* msg);
50 extern void CsrWifiRouterCtrlWapiMulticastReqHandler(void* drvpriv, CsrWifiFsmEvent* msg); 50 extern void CsrWifiRouterCtrlWapiRxPktReqHandler(void* drvpriv, CsrWifiFsmEvent* msg);
51 extern void CsrWifiRouterCtrlWapiUnicastTxPktReqHandler(void* drvpriv, CsrWifiFsmEvent* msg);
51 extern void CsrWifiRouterCtrlWapiUnicastFilterReqHandler(void* drvpriv, CsrWifiFsmEvent* msg); 52 extern void CsrWifiRouterCtrlWapiUnicastFilterReqHandler(void* drvpriv, CsrWifiFsmEvent* msg);
53 extern void CsrWifiRouterCtrlWapiFilterReqHandler(void* drvpriv, CsrWifiFsmEvent* msg);
52#ifdef __cplusplus 54#ifdef __cplusplus
53} 55}
54#endif 56#endif
diff --git a/drivers/staging/csr/csr_wifi_router_ctrl_serialize.c b/drivers/staging/csr/csr_wifi_router_ctrl_serialize.c
index cb1f6dc2988..3239c9bad18 100644
--- a/drivers/staging/csr/csr_wifi_router_ctrl_serialize.c
+++ b/drivers/staging/csr/csr_wifi_router_ctrl_serialize.c
@@ -1,6 +1,6 @@
1/***************************************************************************** 1/*****************************************************************************
2 2
3 (c) Cambridge Silicon Radio Limited 2011 3 (c) Cambridge Silicon Radio Limited 2012
4 All rights reserved and confidential information of CSR 4 All rights reserved and confidential information of CSR
5 5
6 Refer to LICENSE.txt included with this source for details 6 Refer to LICENSE.txt included with this source for details
@@ -656,6 +656,65 @@ void* CsrWifiRouterCtrlTrafficConfigReqDes(CsrUint8 *buffer, CsrSize length)
656} 656}
657 657
658 658
659CsrSize CsrWifiRouterCtrlWifiOnReqSizeof(void *msg)
660{
661 CsrWifiRouterCtrlWifiOnReq *primitive = (CsrWifiRouterCtrlWifiOnReq *) msg;
662 CsrSize bufferSize = 2;
663
664 /* Calculate the Size of the Serialised Data. Could be more efficient (Try 10) */
665 bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */
666 bufferSize += 4; /* CsrUint32 primitive->dataLength */
667 bufferSize += primitive->dataLength; /* CsrUint8 primitive->data */
668 return bufferSize;
669}
670
671
672CsrUint8* CsrWifiRouterCtrlWifiOnReqSer(CsrUint8 *ptr, CsrSize *len, void *msg)
673{
674 CsrWifiRouterCtrlWifiOnReq *primitive = (CsrWifiRouterCtrlWifiOnReq *)msg;
675 *len = 0;
676 CsrUint16Ser(ptr, len, primitive->common.type);
677 CsrUint16Ser(ptr, len, (CsrUint16) primitive->clientData);
678 CsrUint32Ser(ptr, len, (CsrUint32) primitive->dataLength);
679 if (primitive->dataLength)
680 {
681 CsrMemCpySer(ptr, len, (const void *) primitive->data, ((CsrUint16) (primitive->dataLength)));
682 }
683 return(ptr);
684}
685
686
687void* CsrWifiRouterCtrlWifiOnReqDes(CsrUint8 *buffer, CsrSize length)
688{
689 CsrWifiRouterCtrlWifiOnReq *primitive = (CsrWifiRouterCtrlWifiOnReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlWifiOnReq));
690 CsrSize offset;
691 offset = 0;
692
693 CsrUint16Des(&primitive->common.type, buffer, &offset);
694 CsrUint16Des((CsrUint16 *) &primitive->clientData, buffer, &offset);
695 CsrUint32Des((CsrUint32 *) &primitive->dataLength, buffer, &offset);
696 if (primitive->dataLength)
697 {
698 primitive->data = (CsrUint8 *)CsrPmemAlloc(primitive->dataLength);
699 CsrMemCpyDes(primitive->data, buffer, &offset, ((CsrUint16) (primitive->dataLength)));
700 }
701 else
702 {
703 primitive->data = NULL;
704 }
705
706 return primitive;
707}
708
709
710void CsrWifiRouterCtrlWifiOnReqSerFree(void *voidPrimitivePointer)
711{
712 CsrWifiRouterCtrlWifiOnReq *primitive = (CsrWifiRouterCtrlWifiOnReq *) voidPrimitivePointer;
713 CsrPmemFree(primitive->data);
714 CsrPmemFree(primitive);
715}
716
717
659CsrSize CsrWifiRouterCtrlWifiOnResSizeof(void *msg) 718CsrSize CsrWifiRouterCtrlWifiOnResSizeof(void *msg)
660{ 719{
661 CsrWifiRouterCtrlWifiOnRes *primitive = (CsrWifiRouterCtrlWifiOnRes *) msg; 720 CsrWifiRouterCtrlWifiOnRes *primitive = (CsrWifiRouterCtrlWifiOnRes *) msg;
@@ -1055,12 +1114,13 @@ void* CsrWifiRouterCtrlBlockAckDisableReqDes(CsrUint8 *buffer, CsrSize length)
1055} 1114}
1056 1115
1057 1116
1058CsrSize CsrWifiRouterCtrlWapiMulticastReqSizeof(void *msg) 1117CsrSize CsrWifiRouterCtrlWapiRxPktReqSizeof(void *msg)
1059{ 1118{
1060 CsrWifiRouterCtrlWapiMulticastReq *primitive = (CsrWifiRouterCtrlWapiMulticastReq *) msg; 1119 CsrWifiRouterCtrlWapiRxPktReq *primitive = (CsrWifiRouterCtrlWapiRxPktReq *) msg;
1061 CsrSize bufferSize = 2; 1120 CsrSize bufferSize = 2;
1062 1121
1063 /* Calculate the Size of the Serialised Data. Could be more efficient (Try 9) */ 1122 /* Calculate the Size of the Serialised Data. Could be more efficient (Try 11) */
1123 bufferSize += 2; /* CsrUint16 primitive->interfaceTag */
1064 bufferSize += 2; /* CsrUint16 primitive->signalLength */ 1124 bufferSize += 2; /* CsrUint16 primitive->signalLength */
1065 bufferSize += primitive->signalLength; /* CsrUint8 primitive->signal */ 1125 bufferSize += primitive->signalLength; /* CsrUint8 primitive->signal */
1066 bufferSize += 2; /* CsrUint16 primitive->dataLength */ 1126 bufferSize += 2; /* CsrUint16 primitive->dataLength */
@@ -1069,11 +1129,12 @@ CsrSize CsrWifiRouterCtrlWapiMulticastReqSizeof(void *msg)
1069} 1129}
1070 1130
1071 1131
1072CsrUint8* CsrWifiRouterCtrlWapiMulticastReqSer(CsrUint8 *ptr, CsrSize *len, void *msg) 1132CsrUint8* CsrWifiRouterCtrlWapiRxPktReqSer(CsrUint8 *ptr, CsrSize *len, void *msg)
1073{ 1133{
1074 CsrWifiRouterCtrlWapiMulticastReq *primitive = (CsrWifiRouterCtrlWapiMulticastReq *)msg; 1134 CsrWifiRouterCtrlWapiRxPktReq *primitive = (CsrWifiRouterCtrlWapiRxPktReq *)msg;
1075 *len = 0; 1135 *len = 0;
1076 CsrUint16Ser(ptr, len, primitive->common.type); 1136 CsrUint16Ser(ptr, len, primitive->common.type);
1137 CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag);
1077 CsrUint16Ser(ptr, len, (CsrUint16) primitive->signalLength); 1138 CsrUint16Ser(ptr, len, (CsrUint16) primitive->signalLength);
1078 if (primitive->signalLength) 1139 if (primitive->signalLength)
1079 { 1140 {
@@ -1088,13 +1149,14 @@ CsrUint8* CsrWifiRouterCtrlWapiMulticastReqSer(CsrUint8 *ptr, CsrSize *len, void
1088} 1149}
1089 1150
1090 1151
1091void* CsrWifiRouterCtrlWapiMulticastReqDes(CsrUint8 *buffer, CsrSize length) 1152void* CsrWifiRouterCtrlWapiRxPktReqDes(CsrUint8 *buffer, CsrSize length)
1092{ 1153{
1093 CsrWifiRouterCtrlWapiMulticastReq *primitive = (CsrWifiRouterCtrlWapiMulticastReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlWapiMulticastReq)); 1154 CsrWifiRouterCtrlWapiRxPktReq *primitive = (CsrWifiRouterCtrlWapiRxPktReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlWapiRxPktReq));
1094 CsrSize offset; 1155 CsrSize offset;
1095 offset = 0; 1156 offset = 0;
1096 1157
1097 CsrUint16Des(&primitive->common.type, buffer, &offset); 1158 CsrUint16Des(&primitive->common.type, buffer, &offset);
1159 CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset);
1098 CsrUint16Des((CsrUint16 *) &primitive->signalLength, buffer, &offset); 1160 CsrUint16Des((CsrUint16 *) &primitive->signalLength, buffer, &offset);
1099 if (primitive->signalLength) 1161 if (primitive->signalLength)
1100 { 1162 {
@@ -1120,15 +1182,74 @@ void* CsrWifiRouterCtrlWapiMulticastReqDes(CsrUint8 *buffer, CsrSize length)
1120} 1182}
1121 1183
1122 1184
1123void CsrWifiRouterCtrlWapiMulticastReqSerFree(void *voidPrimitivePointer) 1185void CsrWifiRouterCtrlWapiRxPktReqSerFree(void *voidPrimitivePointer)
1124{ 1186{
1125 CsrWifiRouterCtrlWapiMulticastReq *primitive = (CsrWifiRouterCtrlWapiMulticastReq *) voidPrimitivePointer; 1187 CsrWifiRouterCtrlWapiRxPktReq *primitive = (CsrWifiRouterCtrlWapiRxPktReq *) voidPrimitivePointer;
1126 CsrPmemFree(primitive->signal); 1188 CsrPmemFree(primitive->signal);
1127 CsrPmemFree(primitive->data); 1189 CsrPmemFree(primitive->data);
1128 CsrPmemFree(primitive); 1190 CsrPmemFree(primitive);
1129} 1191}
1130 1192
1131 1193
1194CsrSize CsrWifiRouterCtrlWapiUnicastTxPktReqSizeof(void *msg)
1195{
1196 CsrWifiRouterCtrlWapiUnicastTxPktReq *primitive = (CsrWifiRouterCtrlWapiUnicastTxPktReq *) msg;
1197 CsrSize bufferSize = 2;
1198
1199 /* Calculate the Size of the Serialised Data. Could be more efficient (Try 8) */
1200 bufferSize += 2; /* CsrUint16 primitive->interfaceTag */
1201 bufferSize += 2; /* CsrUint16 primitive->dataLength */
1202 bufferSize += primitive->dataLength; /* CsrUint8 primitive->data */
1203 return bufferSize;
1204}
1205
1206
1207CsrUint8* CsrWifiRouterCtrlWapiUnicastTxPktReqSer(CsrUint8 *ptr, CsrSize *len, void *msg)
1208{
1209 CsrWifiRouterCtrlWapiUnicastTxPktReq *primitive = (CsrWifiRouterCtrlWapiUnicastTxPktReq *)msg;
1210 *len = 0;
1211 CsrUint16Ser(ptr, len, primitive->common.type);
1212 CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag);
1213 CsrUint16Ser(ptr, len, (CsrUint16) primitive->dataLength);
1214 if (primitive->dataLength)
1215 {
1216 CsrMemCpySer(ptr, len, (const void *) primitive->data, ((CsrUint16) (primitive->dataLength)));
1217 }
1218 return(ptr);
1219}
1220
1221
1222void* CsrWifiRouterCtrlWapiUnicastTxPktReqDes(CsrUint8 *buffer, CsrSize length)
1223{
1224 CsrWifiRouterCtrlWapiUnicastTxPktReq *primitive = (CsrWifiRouterCtrlWapiUnicastTxPktReq *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlWapiUnicastTxPktReq));
1225 CsrSize offset;
1226 offset = 0;
1227
1228 CsrUint16Des(&primitive->common.type, buffer, &offset);
1229 CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset);
1230 CsrUint16Des((CsrUint16 *) &primitive->dataLength, buffer, &offset);
1231 if (primitive->dataLength)
1232 {
1233 primitive->data = (CsrUint8 *)CsrPmemAlloc(primitive->dataLength);
1234 CsrMemCpyDes(primitive->data, buffer, &offset, ((CsrUint16) (primitive->dataLength)));
1235 }
1236 else
1237 {
1238 primitive->data = NULL;
1239 }
1240
1241 return primitive;
1242}
1243
1244
1245void CsrWifiRouterCtrlWapiUnicastTxPktReqSerFree(void *voidPrimitivePointer)
1246{
1247 CsrWifiRouterCtrlWapiUnicastTxPktReq *primitive = (CsrWifiRouterCtrlWapiUnicastTxPktReq *) voidPrimitivePointer;
1248 CsrPmemFree(primitive->data);
1249 CsrPmemFree(primitive);
1250}
1251
1252
1132CsrSize CsrWifiRouterCtrlHipIndSizeof(void *msg) 1253CsrSize CsrWifiRouterCtrlHipIndSizeof(void *msg)
1133{ 1254{
1134 CsrWifiRouterCtrlHipInd *primitive = (CsrWifiRouterCtrlHipInd *) msg; 1255 CsrWifiRouterCtrlHipInd *primitive = (CsrWifiRouterCtrlHipInd *) msg;
@@ -2287,9 +2408,9 @@ void* CsrWifiRouterCtrlStaInactiveIndDes(CsrUint8 *buffer, CsrSize length)
2287} 2408}
2288 2409
2289 2410
2290CsrSize CsrWifiRouterCtrlWapiMulticastIndSizeof(void *msg) 2411CsrSize CsrWifiRouterCtrlWapiRxMicCheckIndSizeof(void *msg)
2291{ 2412{
2292 CsrWifiRouterCtrlWapiMulticastInd *primitive = (CsrWifiRouterCtrlWapiMulticastInd *) msg; 2413 CsrWifiRouterCtrlWapiRxMicCheckInd *primitive = (CsrWifiRouterCtrlWapiRxMicCheckInd *) msg;
2293 CsrSize bufferSize = 2; 2414 CsrSize bufferSize = 2;
2294 2415
2295 /* Calculate the Size of the Serialised Data. Could be more efficient (Try 13) */ 2416 /* Calculate the Size of the Serialised Data. Could be more efficient (Try 13) */
@@ -2303,9 +2424,9 @@ CsrSize CsrWifiRouterCtrlWapiMulticastIndSizeof(void *msg)
2303} 2424}
2304 2425
2305 2426
2306CsrUint8* CsrWifiRouterCtrlWapiMulticastIndSer(CsrUint8 *ptr, CsrSize *len, void *msg) 2427CsrUint8* CsrWifiRouterCtrlWapiRxMicCheckIndSer(CsrUint8 *ptr, CsrSize *len, void *msg)
2307{ 2428{
2308 CsrWifiRouterCtrlWapiMulticastInd *primitive = (CsrWifiRouterCtrlWapiMulticastInd *)msg; 2429 CsrWifiRouterCtrlWapiRxMicCheckInd *primitive = (CsrWifiRouterCtrlWapiRxMicCheckInd *)msg;
2309 *len = 0; 2430 *len = 0;
2310 CsrUint16Ser(ptr, len, primitive->common.type); 2431 CsrUint16Ser(ptr, len, primitive->common.type);
2311 CsrUint16Ser(ptr, len, (CsrUint16) primitive->clientData); 2432 CsrUint16Ser(ptr, len, (CsrUint16) primitive->clientData);
@@ -2324,9 +2445,9 @@ CsrUint8* CsrWifiRouterCtrlWapiMulticastIndSer(CsrUint8 *ptr, CsrSize *len, void
2324} 2445}
2325 2446
2326 2447
2327void* CsrWifiRouterCtrlWapiMulticastIndDes(CsrUint8 *buffer, CsrSize length) 2448void* CsrWifiRouterCtrlWapiRxMicCheckIndDes(CsrUint8 *buffer, CsrSize length)
2328{ 2449{
2329 CsrWifiRouterCtrlWapiMulticastInd *primitive = (CsrWifiRouterCtrlWapiMulticastInd *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlWapiMulticastInd)); 2450 CsrWifiRouterCtrlWapiRxMicCheckInd *primitive = (CsrWifiRouterCtrlWapiRxMicCheckInd *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlWapiRxMicCheckInd));
2330 CsrSize offset; 2451 CsrSize offset;
2331 offset = 0; 2452 offset = 0;
2332 2453
@@ -2358,12 +2479,116 @@ void* CsrWifiRouterCtrlWapiMulticastIndDes(CsrUint8 *buffer, CsrSize length)
2358} 2479}
2359 2480
2360 2481
2361void CsrWifiRouterCtrlWapiMulticastIndSerFree(void *voidPrimitivePointer) 2482void CsrWifiRouterCtrlWapiRxMicCheckIndSerFree(void *voidPrimitivePointer)
2362{ 2483{
2363 CsrWifiRouterCtrlWapiMulticastInd *primitive = (CsrWifiRouterCtrlWapiMulticastInd *) voidPrimitivePointer; 2484 CsrWifiRouterCtrlWapiRxMicCheckInd *primitive = (CsrWifiRouterCtrlWapiRxMicCheckInd *) voidPrimitivePointer;
2364 CsrPmemFree(primitive->signal); 2485 CsrPmemFree(primitive->signal);
2365 CsrPmemFree(primitive->data); 2486 CsrPmemFree(primitive->data);
2366 CsrPmemFree(primitive); 2487 CsrPmemFree(primitive);
2367} 2488}
2368 2489
2369 2490
2491CsrSize CsrWifiRouterCtrlModeSetCfmSizeof(void *msg)
2492{
2493 CsrSize bufferSize = 2;
2494
2495 /* Calculate the Size of the Serialised Data. Could be more efficient (Try 10) */
2496 bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */
2497 bufferSize += 2; /* CsrUint16 primitive->interfaceTag */
2498 bufferSize += 1; /* CsrWifiRouterCtrlMode primitive->mode */
2499 bufferSize += 2; /* CsrResult primitive->status */
2500 return bufferSize;
2501}
2502
2503
2504CsrUint8* CsrWifiRouterCtrlModeSetCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg)
2505{
2506 CsrWifiRouterCtrlModeSetCfm *primitive = (CsrWifiRouterCtrlModeSetCfm *)msg;
2507 *len = 0;
2508 CsrUint16Ser(ptr, len, primitive->common.type);
2509 CsrUint16Ser(ptr, len, (CsrUint16) primitive->clientData);
2510 CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag);
2511 CsrUint8Ser(ptr, len, (CsrUint8) primitive->mode);
2512 CsrUint16Ser(ptr, len, (CsrUint16) primitive->status);
2513 return(ptr);
2514}
2515
2516
2517void* CsrWifiRouterCtrlModeSetCfmDes(CsrUint8 *buffer, CsrSize length)
2518{
2519 CsrWifiRouterCtrlModeSetCfm *primitive = (CsrWifiRouterCtrlModeSetCfm *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlModeSetCfm));
2520 CsrSize offset;
2521 offset = 0;
2522
2523 CsrUint16Des(&primitive->common.type, buffer, &offset);
2524 CsrUint16Des((CsrUint16 *) &primitive->clientData, buffer, &offset);
2525 CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset);
2526 CsrUint8Des((CsrUint8 *) &primitive->mode, buffer, &offset);
2527 CsrUint16Des((CsrUint16 *) &primitive->status, buffer, &offset);
2528
2529 return primitive;
2530}
2531
2532
2533CsrSize CsrWifiRouterCtrlWapiUnicastTxEncryptIndSizeof(void *msg)
2534{
2535 CsrWifiRouterCtrlWapiUnicastTxEncryptInd *primitive = (CsrWifiRouterCtrlWapiUnicastTxEncryptInd *) msg;
2536 CsrSize bufferSize = 2;
2537
2538 /* Calculate the Size of the Serialised Data. Could be more efficient (Try 10) */
2539 bufferSize += 2; /* CsrWifiRouterCtrlRequestorInfo primitive->clientData */
2540 bufferSize += 2; /* CsrUint16 primitive->interfaceTag */
2541 bufferSize += 2; /* CsrUint16 primitive->dataLength */
2542 bufferSize += primitive->dataLength; /* CsrUint8 primitive->data */
2543 return bufferSize;
2544}
2545
2546
2547CsrUint8* CsrWifiRouterCtrlWapiUnicastTxEncryptIndSer(CsrUint8 *ptr, CsrSize *len, void *msg)
2548{
2549 CsrWifiRouterCtrlWapiUnicastTxEncryptInd *primitive = (CsrWifiRouterCtrlWapiUnicastTxEncryptInd *)msg;
2550 *len = 0;
2551 CsrUint16Ser(ptr, len, primitive->common.type);
2552 CsrUint16Ser(ptr, len, (CsrUint16) primitive->clientData);
2553 CsrUint16Ser(ptr, len, (CsrUint16) primitive->interfaceTag);
2554 CsrUint16Ser(ptr, len, (CsrUint16) primitive->dataLength);
2555 if (primitive->dataLength)
2556 {
2557 CsrMemCpySer(ptr, len, (const void *) primitive->data, ((CsrUint16) (primitive->dataLength)));
2558 }
2559 return(ptr);
2560}
2561
2562
2563void* CsrWifiRouterCtrlWapiUnicastTxEncryptIndDes(CsrUint8 *buffer, CsrSize length)
2564{
2565 CsrWifiRouterCtrlWapiUnicastTxEncryptInd *primitive = (CsrWifiRouterCtrlWapiUnicastTxEncryptInd *) CsrPmemAlloc(sizeof(CsrWifiRouterCtrlWapiUnicastTxEncryptInd));
2566 CsrSize offset;
2567 offset = 0;
2568
2569 CsrUint16Des(&primitive->common.type, buffer, &offset);
2570 CsrUint16Des((CsrUint16 *) &primitive->clientData, buffer, &offset);
2571 CsrUint16Des((CsrUint16 *) &primitive->interfaceTag, buffer, &offset);
2572 CsrUint16Des((CsrUint16 *) &primitive->dataLength, buffer, &offset);
2573 if (primitive->dataLength)
2574 {
2575 primitive->data = (CsrUint8 *)CsrPmemAlloc(primitive->dataLength);
2576 CsrMemCpyDes(primitive->data, buffer, &offset, ((CsrUint16) (primitive->dataLength)));
2577 }
2578 else
2579 {
2580 primitive->data = NULL;
2581 }
2582
2583 return primitive;
2584}
2585
2586
2587void CsrWifiRouterCtrlWapiUnicastTxEncryptIndSerFree(void *voidPrimitivePointer)
2588{
2589 CsrWifiRouterCtrlWapiUnicastTxEncryptInd *primitive = (CsrWifiRouterCtrlWapiUnicastTxEncryptInd *) voidPrimitivePointer;
2590 CsrPmemFree(primitive->data);
2591 CsrPmemFree(primitive);
2592}
2593
2594
diff --git a/drivers/staging/csr/csr_wifi_router_ctrl_serialize.h b/drivers/staging/csr/csr_wifi_router_ctrl_serialize.h
index 5d82f8d0daa..3b7834dad52 100644
--- a/drivers/staging/csr/csr_wifi_router_ctrl_serialize.h
+++ b/drivers/staging/csr/csr_wifi_router_ctrl_serialize.h
@@ -1,6 +1,6 @@
1/***************************************************************************** 1/*****************************************************************************
2 2
3 (c) Cambridge Silicon Radio Limited 2011 3 (c) Cambridge Silicon Radio Limited 2012
4 All rights reserved and confidential information of CSR 4 All rights reserved and confidential information of CSR
5 5
6 Refer to LICENSE.txt included with this source for details 6 Refer to LICENSE.txt included with this source for details
@@ -105,10 +105,10 @@ extern CsrSize CsrWifiRouterCtrlTrafficConfigReqSizeof(void *msg);
105#define CsrWifiRouterCtrlWifiOffResSizeof CsrWifiEventCsrUint16Sizeof 105#define CsrWifiRouterCtrlWifiOffResSizeof CsrWifiEventCsrUint16Sizeof
106#define CsrWifiRouterCtrlWifiOffResSerFree CsrWifiRouterCtrlPfree 106#define CsrWifiRouterCtrlWifiOffResSerFree CsrWifiRouterCtrlPfree
107 107
108#define CsrWifiRouterCtrlWifiOnReqSer CsrWifiEventCsrUint16Ser 108extern CsrUint8* CsrWifiRouterCtrlWifiOnReqSer(CsrUint8 *ptr, CsrSize *len, void *msg);
109#define CsrWifiRouterCtrlWifiOnReqDes CsrWifiEventCsrUint16Des 109extern void* CsrWifiRouterCtrlWifiOnReqDes(CsrUint8 *buffer, CsrSize len);
110#define CsrWifiRouterCtrlWifiOnReqSizeof CsrWifiEventCsrUint16Sizeof 110extern CsrSize CsrWifiRouterCtrlWifiOnReqSizeof(void *msg);
111#define CsrWifiRouterCtrlWifiOnReqSerFree CsrWifiRouterCtrlPfree 111extern void CsrWifiRouterCtrlWifiOnReqSerFree(void *msg);
112 112
113extern CsrUint8* CsrWifiRouterCtrlWifiOnResSer(CsrUint8 *ptr, CsrSize *len, void *msg); 113extern CsrUint8* CsrWifiRouterCtrlWifiOnResSer(CsrUint8 *ptr, CsrSize *len, void *msg);
114extern void* CsrWifiRouterCtrlWifiOnResDes(CsrUint8 *buffer, CsrSize len); 114extern void* CsrWifiRouterCtrlWifiOnResDes(CsrUint8 *buffer, CsrSize len);
@@ -155,21 +155,31 @@ extern void* CsrWifiRouterCtrlBlockAckDisableReqDes(CsrUint8 *buffer, CsrSize le
155extern CsrSize CsrWifiRouterCtrlBlockAckDisableReqSizeof(void *msg); 155extern CsrSize CsrWifiRouterCtrlBlockAckDisableReqSizeof(void *msg);
156#define CsrWifiRouterCtrlBlockAckDisableReqSerFree CsrWifiRouterCtrlPfree 156#define CsrWifiRouterCtrlBlockAckDisableReqSerFree CsrWifiRouterCtrlPfree
157 157
158extern CsrUint8* CsrWifiRouterCtrlWapiMulticastReqSer(CsrUint8 *ptr, CsrSize *len, void *msg); 158extern CsrUint8* CsrWifiRouterCtrlWapiRxPktReqSer(CsrUint8 *ptr, CsrSize *len, void *msg);
159extern void* CsrWifiRouterCtrlWapiMulticastReqDes(CsrUint8 *buffer, CsrSize len); 159extern void* CsrWifiRouterCtrlWapiRxPktReqDes(CsrUint8 *buffer, CsrSize len);
160extern CsrSize CsrWifiRouterCtrlWapiMulticastReqSizeof(void *msg); 160extern CsrSize CsrWifiRouterCtrlWapiRxPktReqSizeof(void *msg);
161extern void CsrWifiRouterCtrlWapiMulticastReqSerFree(void *msg); 161extern void CsrWifiRouterCtrlWapiRxPktReqSerFree(void *msg);
162 162
163#define CsrWifiRouterCtrlWapiMulticastFilterReqSer CsrWifiEventCsrUint8Ser 163#define CsrWifiRouterCtrlWapiMulticastFilterReqSer CsrWifiEventCsrUint16CsrUint8Ser
164#define CsrWifiRouterCtrlWapiMulticastFilterReqDes CsrWifiEventCsrUint8Des 164#define CsrWifiRouterCtrlWapiMulticastFilterReqDes CsrWifiEventCsrUint16CsrUint8Des
165#define CsrWifiRouterCtrlWapiMulticastFilterReqSizeof CsrWifiEventCsrUint8Sizeof 165#define CsrWifiRouterCtrlWapiMulticastFilterReqSizeof CsrWifiEventCsrUint16CsrUint8Sizeof
166#define CsrWifiRouterCtrlWapiMulticastFilterReqSerFree CsrWifiRouterCtrlPfree 166#define CsrWifiRouterCtrlWapiMulticastFilterReqSerFree CsrWifiRouterCtrlPfree
167 167
168#define CsrWifiRouterCtrlWapiUnicastFilterReqSer CsrWifiEventCsrUint8Ser 168#define CsrWifiRouterCtrlWapiUnicastFilterReqSer CsrWifiEventCsrUint16CsrUint8Ser
169#define CsrWifiRouterCtrlWapiUnicastFilterReqDes CsrWifiEventCsrUint8Des 169#define CsrWifiRouterCtrlWapiUnicastFilterReqDes CsrWifiEventCsrUint16CsrUint8Des
170#define CsrWifiRouterCtrlWapiUnicastFilterReqSizeof CsrWifiEventCsrUint8Sizeof 170#define CsrWifiRouterCtrlWapiUnicastFilterReqSizeof CsrWifiEventCsrUint16CsrUint8Sizeof
171#define CsrWifiRouterCtrlWapiUnicastFilterReqSerFree CsrWifiRouterCtrlPfree 171#define CsrWifiRouterCtrlWapiUnicastFilterReqSerFree CsrWifiRouterCtrlPfree
172 172
173extern CsrUint8* CsrWifiRouterCtrlWapiUnicastTxPktReqSer(CsrUint8 *ptr, CsrSize *len, void *msg);
174extern void* CsrWifiRouterCtrlWapiUnicastTxPktReqDes(CsrUint8 *buffer, CsrSize len);
175extern CsrSize CsrWifiRouterCtrlWapiUnicastTxPktReqSizeof(void *msg);
176extern void CsrWifiRouterCtrlWapiUnicastTxPktReqSerFree(void *msg);
177
178#define CsrWifiRouterCtrlWapiFilterReqSer CsrWifiEventCsrUint16CsrUint8Ser
179#define CsrWifiRouterCtrlWapiFilterReqDes CsrWifiEventCsrUint16CsrUint8Des
180#define CsrWifiRouterCtrlWapiFilterReqSizeof CsrWifiEventCsrUint16CsrUint8Sizeof
181#define CsrWifiRouterCtrlWapiFilterReqSerFree CsrWifiRouterCtrlPfree
182
173extern CsrUint8* CsrWifiRouterCtrlHipIndSer(CsrUint8 *ptr, CsrSize *len, void *msg); 183extern CsrUint8* CsrWifiRouterCtrlHipIndSer(CsrUint8 *ptr, CsrSize *len, void *msg);
174extern void* CsrWifiRouterCtrlHipIndDes(CsrUint8 *buffer, CsrSize len); 184extern void* CsrWifiRouterCtrlHipIndDes(CsrUint8 *buffer, CsrSize len);
175extern CsrSize CsrWifiRouterCtrlHipIndSizeof(void *msg); 185extern CsrSize CsrWifiRouterCtrlHipIndSizeof(void *msg);
@@ -310,10 +320,20 @@ extern void* CsrWifiRouterCtrlStaInactiveIndDes(CsrUint8 *buffer, CsrSize len);
310extern CsrSize CsrWifiRouterCtrlStaInactiveIndSizeof(void *msg); 320extern CsrSize CsrWifiRouterCtrlStaInactiveIndSizeof(void *msg);
311#define CsrWifiRouterCtrlStaInactiveIndSerFree CsrWifiRouterCtrlPfree 321#define CsrWifiRouterCtrlStaInactiveIndSerFree CsrWifiRouterCtrlPfree
312 322
313extern CsrUint8* CsrWifiRouterCtrlWapiMulticastIndSer(CsrUint8 *ptr, CsrSize *len, void *msg); 323extern CsrUint8* CsrWifiRouterCtrlWapiRxMicCheckIndSer(CsrUint8 *ptr, CsrSize *len, void *msg);
314extern void* CsrWifiRouterCtrlWapiMulticastIndDes(CsrUint8 *buffer, CsrSize len); 324extern void* CsrWifiRouterCtrlWapiRxMicCheckIndDes(CsrUint8 *buffer, CsrSize len);
315extern CsrSize CsrWifiRouterCtrlWapiMulticastIndSizeof(void *msg); 325extern CsrSize CsrWifiRouterCtrlWapiRxMicCheckIndSizeof(void *msg);
316extern void CsrWifiRouterCtrlWapiMulticastIndSerFree(void *msg); 326extern void CsrWifiRouterCtrlWapiRxMicCheckIndSerFree(void *msg);
327
328extern CsrUint8* CsrWifiRouterCtrlModeSetCfmSer(CsrUint8 *ptr, CsrSize *len, void *msg);
329extern void* CsrWifiRouterCtrlModeSetCfmDes(CsrUint8 *buffer, CsrSize len);
330extern CsrSize CsrWifiRouterCtrlModeSetCfmSizeof(void *msg);
331#define CsrWifiRouterCtrlModeSetCfmSerFree CsrWifiRouterCtrlPfree
332
333extern CsrUint8* CsrWifiRouterCtrlWapiUnicastTxEncryptIndSer(CsrUint8 *ptr, CsrSize *len, void *msg);
334extern void* CsrWifiRouterCtrlWapiUnicastTxEncryptIndDes(CsrUint8 *buffer, CsrSize len);
335extern CsrSize CsrWifiRouterCtrlWapiUnicastTxEncryptIndSizeof(void *msg);
336extern void CsrWifiRouterCtrlWapiUnicastTxEncryptIndSerFree(void *msg);
317 337
318 338
319#ifdef __cplusplus 339#ifdef __cplusplus
diff --git a/drivers/staging/csr/csr_wifi_sme_ap_lib.h b/drivers/staging/csr/csr_wifi_sme_ap_lib.h
index edef7c8de40..bb9e79f95ec 100644
--- a/drivers/staging/csr/csr_wifi_sme_ap_lib.h
+++ b/drivers/staging/csr/csr_wifi_sme_ap_lib.h
@@ -1,6 +1,6 @@
1/***************************************************************************** 1/*****************************************************************************
2 2
3 (c) Cambridge Silicon Radio Limited 2011 3 (c) Cambridge Silicon Radio Limited 2012
4 All rights reserved and confidential information of CSR 4 All rights reserved and confidential information of CSR
5 5
6 Refer to LICENSE.txt included with this source for details 6 Refer to LICENSE.txt included with this source for details
@@ -63,6 +63,7 @@ void CsrWifiSmeApFreeDownstreamMessageContents(CsrUint16 eventClass, void *messa
63const CsrCharString* CsrWifiSmeApAccessTypeToString(CsrWifiSmeApAccessType value); 63const CsrCharString* CsrWifiSmeApAccessTypeToString(CsrWifiSmeApAccessType value);
64const CsrCharString* CsrWifiSmeApAuthSupportToString(CsrWifiSmeApAuthSupport value); 64const CsrCharString* CsrWifiSmeApAuthSupportToString(CsrWifiSmeApAuthSupport value);
65const CsrCharString* CsrWifiSmeApAuthTypeToString(CsrWifiSmeApAuthType value); 65const CsrCharString* CsrWifiSmeApAuthTypeToString(CsrWifiSmeApAuthType value);
66const CsrCharString* CsrWifiSmeApDirectionToString(CsrWifiSmeApDirection value);
66const CsrCharString* CsrWifiSmeApPhySupportToString(CsrWifiSmeApPhySupport value); 67const CsrCharString* CsrWifiSmeApPhySupportToString(CsrWifiSmeApPhySupport value);
67const CsrCharString* CsrWifiSmeApTypeToString(CsrWifiSmeApType value); 68const CsrCharString* CsrWifiSmeApTypeToString(CsrWifiSmeApType value);
68 69
@@ -82,6 +83,134 @@ extern const CsrCharString *CsrWifiSmeApDownstreamPrimNames[CSR_WIFI_SME_AP_PRIM
82/******************************************************************************* 83/*******************************************************************************
83 84
84 NAME 85 NAME
86 CsrWifiSmeApActiveBaGetReqSend
87
88 DESCRIPTION
89 This primitive used to retrieve information related to the active block
90 ack sessions
91
92 PARAMETERS
93 queue - Message Source Task Queue (Cfm's will be sent to this Queue)
94 interfaceTag -
95
96*******************************************************************************/
97#define CsrWifiSmeApActiveBaGetReqCreate(msg__, dst__, src__, interfaceTag__) \
98 msg__ = (CsrWifiSmeApActiveBaGetReq *) CsrPmemAlloc(sizeof(CsrWifiSmeApActiveBaGetReq)); \
99 CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_AP_PRIM, CSR_WIFI_SME_AP_ACTIVE_BA_GET_REQ, dst__, src__); \
100 msg__->interfaceTag = (interfaceTag__);
101
102#define CsrWifiSmeApActiveBaGetReqSendTo(dst__, src__, interfaceTag__) \
103 { \
104 CsrWifiSmeApActiveBaGetReq *msg__; \
105 CsrWifiSmeApActiveBaGetReqCreate(msg__, dst__, src__, interfaceTag__); \
106 CsrMsgTransport(dst__, CSR_WIFI_SME_AP_PRIM, msg__); \
107 }
108
109#define CsrWifiSmeApActiveBaGetReqSend(src__, interfaceTag__) \
110 CsrWifiSmeApActiveBaGetReqSendTo(CSR_WIFI_SME_IFACEQUEUE, src__, interfaceTag__)
111
112/*******************************************************************************
113
114 NAME
115 CsrWifiSmeApActiveBaGetCfmSend
116
117 DESCRIPTION
118 This primitive carries the information related to the active ba sessions
119
120 PARAMETERS
121 queue - Destination Task Queue
122 interfaceTag -
123 status - Reports the result of the request
124 activeBaCount - Number of active block ack session
125 activeBaSessions - Points to a buffer containing an array of
126 CsrWifiSmeApBaSession structures.
127
128*******************************************************************************/
129#define CsrWifiSmeApActiveBaGetCfmCreate(msg__, dst__, src__, interfaceTag__, status__, activeBaCount__, activeBaSessions__) \
130 msg__ = (CsrWifiSmeApActiveBaGetCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeApActiveBaGetCfm)); \
131 CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_AP_PRIM, CSR_WIFI_SME_AP_ACTIVE_BA_GET_CFM, dst__, src__); \
132 msg__->interfaceTag = (interfaceTag__); \
133 msg__->status = (status__); \
134 msg__->activeBaCount = (activeBaCount__); \
135 msg__->activeBaSessions = (activeBaSessions__);
136
137#define CsrWifiSmeApActiveBaGetCfmSendTo(dst__, src__, interfaceTag__, status__, activeBaCount__, activeBaSessions__) \
138 { \
139 CsrWifiSmeApActiveBaGetCfm *msg__; \
140 CsrWifiSmeApActiveBaGetCfmCreate(msg__, dst__, src__, interfaceTag__, status__, activeBaCount__, activeBaSessions__); \
141 CsrSchedMessagePut(dst__, CSR_WIFI_SME_AP_PRIM, msg__); \
142 }
143
144#define CsrWifiSmeApActiveBaGetCfmSend(dst__, interfaceTag__, status__, activeBaCount__, activeBaSessions__) \
145 CsrWifiSmeApActiveBaGetCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, status__, activeBaCount__, activeBaSessions__)
146
147/*******************************************************************************
148
149 NAME
150 CsrWifiSmeApBaDeleteReqSend
151
152 DESCRIPTION
153 This primitive is used to delete an active block ack session
154
155 PARAMETERS
156 queue - Message Source Task Queue (Cfm's will be sent to this Queue)
157 interfaceTag -
158 reason -
159 baSession - BA session to be deleted
160
161*******************************************************************************/
162#define CsrWifiSmeApBaDeleteReqCreate(msg__, dst__, src__, interfaceTag__, reason__, baSession__) \
163 msg__ = (CsrWifiSmeApBaDeleteReq *) CsrPmemAlloc(sizeof(CsrWifiSmeApBaDeleteReq)); \
164 CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_AP_PRIM, CSR_WIFI_SME_AP_BA_DELETE_REQ, dst__, src__); \
165 msg__->interfaceTag = (interfaceTag__); \
166 msg__->reason = (reason__); \
167 msg__->baSession = (baSession__);
168
169#define CsrWifiSmeApBaDeleteReqSendTo(dst__, src__, interfaceTag__, reason__, baSession__) \
170 { \
171 CsrWifiSmeApBaDeleteReq *msg__; \
172 CsrWifiSmeApBaDeleteReqCreate(msg__, dst__, src__, interfaceTag__, reason__, baSession__); \
173 CsrMsgTransport(dst__, CSR_WIFI_SME_AP_PRIM, msg__); \
174 }
175
176#define CsrWifiSmeApBaDeleteReqSend(src__, interfaceTag__, reason__, baSession__) \
177 CsrWifiSmeApBaDeleteReqSendTo(CSR_WIFI_SME_IFACEQUEUE, src__, interfaceTag__, reason__, baSession__)
178
179/*******************************************************************************
180
181 NAME
182 CsrWifiSmeApBaDeleteCfmSend
183
184 DESCRIPTION
185 This primitive confirms the BA is deleted
186
187 PARAMETERS
188 queue - Destination Task Queue
189 interfaceTag -
190 status - Reports the result of the request
191 baSession - deleted BA session
192
193*******************************************************************************/
194#define CsrWifiSmeApBaDeleteCfmCreate(msg__, dst__, src__, interfaceTag__, status__, baSession__) \
195 msg__ = (CsrWifiSmeApBaDeleteCfm *) CsrPmemAlloc(sizeof(CsrWifiSmeApBaDeleteCfm)); \
196 CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_AP_PRIM, CSR_WIFI_SME_AP_BA_DELETE_CFM, dst__, src__); \
197 msg__->interfaceTag = (interfaceTag__); \
198 msg__->status = (status__); \
199 msg__->baSession = (baSession__);
200
201#define CsrWifiSmeApBaDeleteCfmSendTo(dst__, src__, interfaceTag__, status__, baSession__) \
202 { \
203 CsrWifiSmeApBaDeleteCfm *msg__; \
204 CsrWifiSmeApBaDeleteCfmCreate(msg__, dst__, src__, interfaceTag__, status__, baSession__); \
205 CsrSchedMessagePut(dst__, CSR_WIFI_SME_AP_PRIM, msg__); \
206 }
207
208#define CsrWifiSmeApBaDeleteCfmSend(dst__, interfaceTag__, status__, baSession__) \
209 CsrWifiSmeApBaDeleteCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, status__, baSession__)
210
211/*******************************************************************************
212
213 NAME
85 CsrWifiSmeApBeaconingStartReqSend 214 CsrWifiSmeApBeaconingStartReqSend
86 215
87 DESCRIPTION 216 DESCRIPTION
diff --git a/drivers/staging/csr/csr_wifi_sme_ap_prim.h b/drivers/staging/csr/csr_wifi_sme_ap_prim.h
index 3310cd287fd..41594395c65 100644
--- a/drivers/staging/csr/csr_wifi_sme_ap_prim.h
+++ b/drivers/staging/csr/csr_wifi_sme_ap_prim.h
@@ -1,6 +1,6 @@
1/***************************************************************************** 1/*****************************************************************************
2 2
3 (c) Cambridge Silicon Radio Limited 2011 3 (c) Cambridge Silicon Radio Limited 2012
4 All rights reserved and confidential information of CSR 4 All rights reserved and confidential information of CSR
5 5
6 Refer to LICENSE.txt included with this source for details 6 Refer to LICENSE.txt included with this source for details
@@ -98,6 +98,23 @@ typedef CsrUint8 CsrWifiSmeApAuthType;
98/******************************************************************************* 98/*******************************************************************************
99 99
100 NAME 100 NAME
101 CsrWifiSmeApDirection
102
103 DESCRIPTION
104 Definition of Direction
105
106 VALUES
107 CSR_WIFI_AP_DIRECTION_RECEIPIENT - Receipient
108 CSR_WIFI_AP_DIRECTION_ORIGINATOR - Originator
109
110*******************************************************************************/
111typedef CsrUint8 CsrWifiSmeApDirection;
112#define CSR_WIFI_AP_DIRECTION_RECEIPIENT ((CsrWifiSmeApDirection) 0x00)
113#define CSR_WIFI_AP_DIRECTION_ORIGINATOR ((CsrWifiSmeApDirection) 0x01)
114
115/*******************************************************************************
116
117 NAME
101 CsrWifiSmeApPhySupport 118 CsrWifiSmeApPhySupport
102 119
103 DESCRIPTION 120 DESCRIPTION
@@ -305,6 +322,28 @@ typedef struct
305/******************************************************************************* 322/*******************************************************************************
306 323
307 NAME 324 NAME
325 CsrWifiSmeApBaSession
326
327 DESCRIPTION
328
329 MEMBERS
330 peerMacAddress - Indicates MAC address of the peer station
331 tid - Specifies the TID of the MSDUs for which this Block Ack has
332 been set up. Range: 0-15
333 direction - Specifies if the AP is the originator or the recipient of
334 the data stream that uses the Block Ack.
335
336*******************************************************************************/
337typedef struct
338{
339 CsrWifiMacAddress peerMacAddress;
340 CsrUint8 tid;
341 CsrWifiSmeApDirection direction;
342} CsrWifiSmeApBaSession;
343
344/*******************************************************************************
345
346 NAME
308 CsrWifiSmeApMacConfig 347 CsrWifiSmeApMacConfig
309 348
310 DESCRIPTION 349 DESCRIPTION
@@ -456,9 +495,11 @@ typedef struct
456#define CSR_WIFI_SME_AP_WMM_PARAM_UPDATE_REQ ((CsrWifiSmeApPrim) (0x0004 + CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_LOWEST)) 495#define CSR_WIFI_SME_AP_WMM_PARAM_UPDATE_REQ ((CsrWifiSmeApPrim) (0x0004 + CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_LOWEST))
457#define CSR_WIFI_SME_AP_STA_DISCONNECT_REQ ((CsrWifiSmeApPrim) (0x0005 + CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_LOWEST)) 496#define CSR_WIFI_SME_AP_STA_DISCONNECT_REQ ((CsrWifiSmeApPrim) (0x0005 + CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_LOWEST))
458#define CSR_WIFI_SME_AP_WPS_CONFIGURATION_REQ ((CsrWifiSmeApPrim) (0x0006 + CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_LOWEST)) 497#define CSR_WIFI_SME_AP_WPS_CONFIGURATION_REQ ((CsrWifiSmeApPrim) (0x0006 + CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_LOWEST))
498#define CSR_WIFI_SME_AP_ACTIVE_BA_GET_REQ ((CsrWifiSmeApPrim) (0x0007 + CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_LOWEST))
499#define CSR_WIFI_SME_AP_BA_DELETE_REQ ((CsrWifiSmeApPrim) (0x0008 + CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_LOWEST))
459 500
460 501
461#define CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_HIGHEST (0x0006 + CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_LOWEST) 502#define CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_HIGHEST (0x0008 + CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_LOWEST)
462 503
463/* Upstream */ 504/* Upstream */
464#define CSR_WIFI_SME_AP_PRIM_UPSTREAM_LOWEST (0x0000 + CSR_PRIM_UPSTREAM) 505#define CSR_WIFI_SME_AP_PRIM_UPSTREAM_LOWEST (0x0000 + CSR_PRIM_UPSTREAM)
@@ -473,8 +514,10 @@ typedef struct
473#define CSR_WIFI_SME_AP_STA_DISCONNECT_CFM ((CsrWifiSmeApPrim)(0x0007 + CSR_WIFI_SME_AP_PRIM_UPSTREAM_LOWEST)) 514#define CSR_WIFI_SME_AP_STA_DISCONNECT_CFM ((CsrWifiSmeApPrim)(0x0007 + CSR_WIFI_SME_AP_PRIM_UPSTREAM_LOWEST))
474#define CSR_WIFI_SME_AP_WPS_CONFIGURATION_CFM ((CsrWifiSmeApPrim)(0x0008 + CSR_WIFI_SME_AP_PRIM_UPSTREAM_LOWEST)) 515#define CSR_WIFI_SME_AP_WPS_CONFIGURATION_CFM ((CsrWifiSmeApPrim)(0x0008 + CSR_WIFI_SME_AP_PRIM_UPSTREAM_LOWEST))
475#define CSR_WIFI_SME_AP_ERROR_IND ((CsrWifiSmeApPrim)(0x0009 + CSR_WIFI_SME_AP_PRIM_UPSTREAM_LOWEST)) 516#define CSR_WIFI_SME_AP_ERROR_IND ((CsrWifiSmeApPrim)(0x0009 + CSR_WIFI_SME_AP_PRIM_UPSTREAM_LOWEST))
517#define CSR_WIFI_SME_AP_ACTIVE_BA_GET_CFM ((CsrWifiSmeApPrim)(0x000A + CSR_WIFI_SME_AP_PRIM_UPSTREAM_LOWEST))
518#define CSR_WIFI_SME_AP_BA_DELETE_CFM ((CsrWifiSmeApPrim)(0x000B + CSR_WIFI_SME_AP_PRIM_UPSTREAM_LOWEST))
476 519
477#define CSR_WIFI_SME_AP_PRIM_UPSTREAM_HIGHEST (0x0009 + CSR_WIFI_SME_AP_PRIM_UPSTREAM_LOWEST) 520#define CSR_WIFI_SME_AP_PRIM_UPSTREAM_HIGHEST (0x000B + CSR_WIFI_SME_AP_PRIM_UPSTREAM_LOWEST)
478 521
479#define CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_COUNT (CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_HIGHEST + 1 - CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_LOWEST) 522#define CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_COUNT (CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_HIGHEST + 1 - CSR_WIFI_SME_AP_PRIM_DOWNSTREAM_LOWEST)
480#define CSR_WIFI_SME_AP_PRIM_UPSTREAM_COUNT (CSR_WIFI_SME_AP_PRIM_UPSTREAM_HIGHEST + 1 - CSR_WIFI_SME_AP_PRIM_UPSTREAM_LOWEST) 523#define CSR_WIFI_SME_AP_PRIM_UPSTREAM_COUNT (CSR_WIFI_SME_AP_PRIM_UPSTREAM_HIGHEST + 1 - CSR_WIFI_SME_AP_PRIM_UPSTREAM_LOWEST)
@@ -658,6 +701,49 @@ typedef struct
658/******************************************************************************* 701/*******************************************************************************
659 702
660 NAME 703 NAME
704 CsrWifiSmeApActiveBaGetReq
705
706 DESCRIPTION
707 This primitive used to retrieve information related to the active block
708 ack sessions
709
710 MEMBERS
711 common - Common header for use with the CsrWifiFsm Module
712 interfaceTag -
713
714*******************************************************************************/
715typedef struct
716{
717 CsrWifiFsmEvent common;
718 CsrUint16 interfaceTag;
719} CsrWifiSmeApActiveBaGetReq;
720
721/*******************************************************************************
722
723 NAME
724 CsrWifiSmeApBaDeleteReq
725
726 DESCRIPTION
727 This primitive is used to delete an active block ack session
728
729 MEMBERS
730 common - Common header for use with the CsrWifiFsm Module
731 interfaceTag -
732 reason -
733 baSession - BA session to be deleted
734
735*******************************************************************************/
736typedef struct
737{
738 CsrWifiFsmEvent common;
739 CsrUint16 interfaceTag;
740 CsrWifiSmeIEEE80211Reason reason;
741 CsrWifiSmeApBaSession baSession;
742} CsrWifiSmeApBaDeleteReq;
743
744/*******************************************************************************
745
746 NAME
661 CsrWifiSmeApBeaconingStartCfm 747 CsrWifiSmeApBeaconingStartCfm
662 748
663 DESCRIPTION 749 DESCRIPTION
@@ -895,6 +981,55 @@ typedef struct
895 CsrResult status; 981 CsrResult status;
896} CsrWifiSmeApErrorInd; 982} CsrWifiSmeApErrorInd;
897 983
984/*******************************************************************************
985
986 NAME
987 CsrWifiSmeApActiveBaGetCfm
988
989 DESCRIPTION
990 This primitive carries the information related to the active ba sessions
991
992 MEMBERS
993 common - Common header for use with the CsrWifiFsm Module
994 interfaceTag -
995 status - Reports the result of the request
996 activeBaCount - Number of active block ack session
997 activeBaSessions - Points to a buffer containing an array of
998 CsrWifiSmeApBaSession structures.
999
1000*******************************************************************************/
1001typedef struct
1002{
1003 CsrWifiFsmEvent common;
1004 CsrUint16 interfaceTag;
1005 CsrResult status;
1006 CsrUint16 activeBaCount;
1007 CsrWifiSmeApBaSession *activeBaSessions;
1008} CsrWifiSmeApActiveBaGetCfm;
1009
1010/*******************************************************************************
1011
1012 NAME
1013 CsrWifiSmeApBaDeleteCfm
1014
1015 DESCRIPTION
1016 This primitive confirms the BA is deleted
1017
1018 MEMBERS
1019 common - Common header for use with the CsrWifiFsm Module
1020 interfaceTag -
1021 status - Reports the result of the request
1022 baSession - deleted BA session
1023
1024*******************************************************************************/
1025typedef struct
1026{
1027 CsrWifiFsmEvent common;
1028 CsrUint16 interfaceTag;
1029 CsrResult status;
1030 CsrWifiSmeApBaSession baSession;
1031} CsrWifiSmeApBaDeleteCfm;
1032
898 1033
899#ifdef __cplusplus 1034#ifdef __cplusplus
900} 1035}
diff --git a/drivers/staging/csr/csr_wifi_sme_converter_init.c b/drivers/staging/csr/csr_wifi_sme_converter_init.c
index bafd1b411a9..6897a77faf2 100644
--- a/drivers/staging/csr/csr_wifi_sme_converter_init.c
+++ b/drivers/staging/csr/csr_wifi_sme_converter_init.c
@@ -1,6 +1,6 @@
1/***************************************************************************** 1/*****************************************************************************
2 2
3 (c) Cambridge Silicon Radio Limited 2011 3 (c) Cambridge Silicon Radio Limited 2012
4 All rights reserved and confidential information of CSR 4 All rights reserved and confidential information of CSR
5 5
6 Refer to LICENSE.txt included with this source for details 6 Refer to LICENSE.txt included with this source for details
@@ -79,6 +79,7 @@ static CsrMsgConvMsgEntry csrwifisme_conv_lut[] = {
79 { CSR_WIFI_SME_SME_COMMON_CONFIG_SET_REQ, CsrWifiSmeSmeCommonConfigSetReqSizeof, CsrWifiSmeSmeCommonConfigSetReqSer, CsrWifiSmeSmeCommonConfigSetReqDes, CsrWifiSmeSmeCommonConfigSetReqSerFree }, 79 { CSR_WIFI_SME_SME_COMMON_CONFIG_SET_REQ, CsrWifiSmeSmeCommonConfigSetReqSizeof, CsrWifiSmeSmeCommonConfigSetReqSer, CsrWifiSmeSmeCommonConfigSetReqDes, CsrWifiSmeSmeCommonConfigSetReqSerFree },
80 { CSR_WIFI_SME_INTERFACE_CAPABILITY_GET_REQ, CsrWifiSmeInterfaceCapabilityGetReqSizeof, CsrWifiSmeInterfaceCapabilityGetReqSer, CsrWifiSmeInterfaceCapabilityGetReqDes, CsrWifiSmeInterfaceCapabilityGetReqSerFree }, 80 { CSR_WIFI_SME_INTERFACE_CAPABILITY_GET_REQ, CsrWifiSmeInterfaceCapabilityGetReqSizeof, CsrWifiSmeInterfaceCapabilityGetReqSer, CsrWifiSmeInterfaceCapabilityGetReqDes, CsrWifiSmeInterfaceCapabilityGetReqSerFree },
81 { CSR_WIFI_SME_WPS_CONFIGURATION_REQ, CsrWifiSmeWpsConfigurationReqSizeof, CsrWifiSmeWpsConfigurationReqSer, CsrWifiSmeWpsConfigurationReqDes, CsrWifiSmeWpsConfigurationReqSerFree }, 81 { CSR_WIFI_SME_WPS_CONFIGURATION_REQ, CsrWifiSmeWpsConfigurationReqSizeof, CsrWifiSmeWpsConfigurationReqSer, CsrWifiSmeWpsConfigurationReqDes, CsrWifiSmeWpsConfigurationReqSerFree },
82 { CSR_WIFI_SME_SET_REQ, CsrWifiSmeSetReqSizeof, CsrWifiSmeSetReqSer, CsrWifiSmeSetReqDes, CsrWifiSmeSetReqSerFree },
82 { CSR_WIFI_SME_ACTIVATE_CFM, CsrWifiSmeActivateCfmSizeof, CsrWifiSmeActivateCfmSer, CsrWifiSmeActivateCfmDes, CsrWifiSmeActivateCfmSerFree }, 83 { CSR_WIFI_SME_ACTIVATE_CFM, CsrWifiSmeActivateCfmSizeof, CsrWifiSmeActivateCfmSer, CsrWifiSmeActivateCfmDes, CsrWifiSmeActivateCfmSerFree },
83 { CSR_WIFI_SME_ADHOC_CONFIG_GET_CFM, CsrWifiSmeAdhocConfigGetCfmSizeof, CsrWifiSmeAdhocConfigGetCfmSer, CsrWifiSmeAdhocConfigGetCfmDes, CsrWifiSmeAdhocConfigGetCfmSerFree }, 84 { CSR_WIFI_SME_ADHOC_CONFIG_GET_CFM, CsrWifiSmeAdhocConfigGetCfmSizeof, CsrWifiSmeAdhocConfigGetCfmSer, CsrWifiSmeAdhocConfigGetCfmDes, CsrWifiSmeAdhocConfigGetCfmSerFree },
84 { CSR_WIFI_SME_ADHOC_CONFIG_SET_CFM, CsrWifiSmeAdhocConfigSetCfmSizeof, CsrWifiSmeAdhocConfigSetCfmSer, CsrWifiSmeAdhocConfigSetCfmDes, CsrWifiSmeAdhocConfigSetCfmSerFree }, 85 { CSR_WIFI_SME_ADHOC_CONFIG_SET_CFM, CsrWifiSmeAdhocConfigSetCfmSizeof, CsrWifiSmeAdhocConfigSetCfmSer, CsrWifiSmeAdhocConfigSetCfmDes, CsrWifiSmeAdhocConfigSetCfmSerFree },
@@ -159,11 +160,11 @@ CsrMsgConvMsgEntry* CsrWifiSmeConverterLookup(CsrMsgConvMsgEntry *ce, CsrUint16
159{ 160{
160 if (msgType & CSR_PRIM_UPSTREAM) 161 if (msgType & CSR_PRIM_UPSTREAM)
161 { 162 {
162 CsrUint16 index = (msgType & ~CSR_PRIM_UPSTREAM) + CSR_WIFI_SME_PRIM_DOWNSTREAM_COUNT; 163 CsrUint16 idx = (msgType & ~CSR_PRIM_UPSTREAM) + CSR_WIFI_SME_PRIM_DOWNSTREAM_COUNT;
163 if (index < (CSR_WIFI_SME_PRIM_UPSTREAM_COUNT + CSR_WIFI_SME_PRIM_DOWNSTREAM_COUNT) && 164 if (idx < (CSR_WIFI_SME_PRIM_UPSTREAM_COUNT + CSR_WIFI_SME_PRIM_DOWNSTREAM_COUNT) &&
164 csrwifisme_conv_lut[index].msgType == msgType) 165 csrwifisme_conv_lut[idx].msgType == msgType)
165 { 166 {
166 return &csrwifisme_conv_lut[index]; 167 return &csrwifisme_conv_lut[idx];
167 } 168 }
168 } 169 }
169 else 170 else
diff --git a/drivers/staging/csr/csr_wifi_sme_converter_init.h b/drivers/staging/csr/csr_wifi_sme_converter_init.h
index 8637eb7baaf..fb895dec768 100644
--- a/drivers/staging/csr/csr_wifi_sme_converter_init.h
+++ b/drivers/staging/csr/csr_wifi_sme_converter_init.h
@@ -1,6 +1,6 @@
1/***************************************************************************** 1/*****************************************************************************
2 2
3 (c) Cambridge Silicon Radio Limited 2011 3 (c) Cambridge Silicon Radio Limited 2012
4 All rights reserved and confidential information of CSR 4 All rights reserved and confidential information of CSR
5 5
6 Refer to LICENSE.txt included with this source for details 6 Refer to LICENSE.txt included with this source for details
diff --git a/drivers/staging/csr/csr_wifi_sme_free_downstream_contents.c b/drivers/staging/csr/csr_wifi_sme_free_downstream_contents.c
index c8e66be899c..93e75e5ace1 100644
--- a/drivers/staging/csr/csr_wifi_sme_free_downstream_contents.c
+++ b/drivers/staging/csr/csr_wifi_sme_free_downstream_contents.c
@@ -1,6 +1,6 @@
1/***************************************************************************** 1/*****************************************************************************
2 2
3 (c) Cambridge Silicon Radio Limited 2011 3 (c) Cambridge Silicon Radio Limited 2012
4 All rights reserved and confidential information of CSR 4 All rights reserved and confidential information of CSR
5 5
6 Refer to LICENSE.txt included with this source for details 6 Refer to LICENSE.txt included with this source for details
@@ -172,6 +172,13 @@ void CsrWifiSmeFreeDownstreamMessageContents(CsrUint16 eventClass, void *message
172 p->wpsConfig.secondaryDeviceType = NULL; 172 p->wpsConfig.secondaryDeviceType = NULL;
173 break; 173 break;
174 } 174 }
175 case CSR_WIFI_SME_SET_REQ:
176 {
177 CsrWifiSmeSetReq *p = (CsrWifiSmeSetReq *)message;
178 CsrPmemFree(p->data);
179 p->data = NULL;
180 break;
181 }
175 182
176 default: 183 default:
177 break; 184 break;
diff --git a/drivers/staging/csr/csr_wifi_sme_lib.h b/drivers/staging/csr/csr_wifi_sme_lib.h
index 16053fb6ed4..67dcb48448c 100644
--- a/drivers/staging/csr/csr_wifi_sme_lib.h
+++ b/drivers/staging/csr/csr_wifi_sme_lib.h
@@ -1,6 +1,6 @@
1/***************************************************************************** 1/*****************************************************************************
2 2
3 (c) Cambridge Silicon Radio Limited 2011 3 (c) Cambridge Silicon Radio Limited 2012
4 All rights reserved and confidential information of CSR 4 All rights reserved and confidential information of CSR
5 5
6 Refer to LICENSE.txt included with this source for details 6 Refer to LICENSE.txt included with this source for details
@@ -3445,6 +3445,39 @@ extern const CsrCharString *CsrWifiSmeDownstreamPrimNames[CSR_WIFI_SME_PRIM_DOWN
3445/******************************************************************************* 3445/*******************************************************************************
3446 3446
3447 NAME 3447 NAME
3448 CsrWifiSmeSetReqSend
3449
3450 DESCRIPTION
3451 Used to pass custom data to the SME. Format is the same as 802.11 Info
3452 Elements => | Id | Length | Data
3453 1) Cmanr Test Mode "Id:0 Length:1 Data:0x00 = OFF 0x01 = ON" "0x00 0x01
3454 (0x00|0x01)"
3455
3456 PARAMETERS
3457 queue - Message Source Task Queue (Cfm's will be sent to this Queue)
3458 dataLength - Number of bytes in the buffer pointed to by 'data'
3459 data - Pointer to the buffer containing 'dataLength' bytes
3460
3461*******************************************************************************/
3462#define CsrWifiSmeSetReqCreate(msg__, dst__, src__, dataLength__, data__) \
3463 msg__ = (CsrWifiSmeSetReq *) CsrPmemAlloc(sizeof(CsrWifiSmeSetReq)); \
3464 CsrWifiFsmEventInit(&msg__->common, CSR_WIFI_SME_PRIM, CSR_WIFI_SME_SET_REQ, dst__, src__); \
3465 msg__->dataLength = (dataLength__); \
3466 msg__->data = (data__);
3467
3468#define CsrWifiSmeSetReqSendTo(dst__, src__, dataLength__, data__) \
3469 { \
3470 CsrWifiSmeSetReq *msg__; \
3471 CsrWifiSmeSetReqCreate(msg__, dst__, src__, dataLength__, data__); \
3472 CsrMsgTransport(dst__, CSR_WIFI_SME_PRIM, msg__); \
3473 }
3474
3475#define CsrWifiSmeSetReqSend(src__, dataLength__, data__) \
3476 CsrWifiSmeSetReqSendTo(CSR_WIFI_SME_LIB_DESTINATION_QUEUE, src__, dataLength__, data__)
3477
3478/*******************************************************************************
3479
3480 NAME
3448 CsrWifiSmeSmeCommonConfigGetReqSend 3481 CsrWifiSmeSmeCommonConfigGetReqSend
3449 3482
3450 DESCRIPTION 3483 DESCRIPTION
diff --git a/drivers/staging/csr/csr_wifi_sme_prim.h b/drivers/staging/csr/csr_wifi_sme_prim.h
index 4bc8520dbd0..8ffa50a6c04 100644
--- a/drivers/staging/csr/csr_wifi_sme_prim.h
+++ b/drivers/staging/csr/csr_wifi_sme_prim.h
@@ -1,6 +1,6 @@
1/***************************************************************************** 1/*****************************************************************************
2 2
3 (c) Cambridge Silicon Radio Limited 2011 3 (c) Cambridge Silicon Radio Limited 2012
4 All rights reserved and confidential information of CSR 4 All rights reserved and confidential information of CSR
5 5
6 Refer to LICENSE.txt included with this source for details 6 Refer to LICENSE.txt included with this source for details
@@ -1434,7 +1434,7 @@ typedef CsrUint8 CsrWifiSmeWepCredentialType;
1434 CsrWifiSmeWmmMode 1434 CsrWifiSmeWmmMode
1435 1435
1436 DESCRIPTION 1436 DESCRIPTION
1437 Defines bits for wmmModeMask: enable/disable WMM features. 1437 Defines bits for CsrWifiSmeWmmModeMask: enable/disable WMM features.
1438 1438
1439 VALUES 1439 VALUES
1440 CSR_WIFI_SME_WMM_MODE_DISABLED - Disables the WMM features. 1440 CSR_WIFI_SME_WMM_MODE_DISABLED - Disables the WMM features.
@@ -2413,40 +2413,6 @@ typedef struct
2413/******************************************************************************* 2413/*******************************************************************************
2414 2414
2415 NAME 2415 NAME
2416 CsrWifiSmeStaConfig
2417
2418 DESCRIPTION
2419 Station configuration options in the SME
2420
2421 MEMBERS
2422 connectionQualityRssiChangeTrigger - Sets the difference of RSSI
2423 measurements which triggers reports
2424 from the Firmware
2425 connectionQualitySnrChangeTrigger - Sets the difference of SNR measurements
2426 which triggers reports from the
2427 Firmware
2428 wmmModeMask - Mask containing one or more values from
2429 CsrWifiSmeWmmMode
2430 ifIndex - Indicates the band of frequencies used
2431 allowUnicastUseGroupCipher - If TRUE, it allows to use groupwise
2432 keys if no pairwise key is specified
2433 enableOpportunisticKeyCaching - If TRUE, enables the Opportunistic Key
2434 Caching feature
2435
2436*******************************************************************************/
2437typedef struct
2438{
2439 CsrUint8 connectionQualityRssiChangeTrigger;
2440 CsrUint8 connectionQualitySnrChangeTrigger;
2441 CsrUint8 wmmModeMask;
2442 CsrWifiSmeRadioIF ifIndex;
2443 CsrBool allowUnicastUseGroupCipher;
2444 CsrBool enableOpportunisticKeyCaching;
2445} CsrWifiSmeStaConfig;
2446
2447/*******************************************************************************
2448
2449 NAME
2450 CsrWifiSmeTsfTime 2416 CsrWifiSmeTsfTime
2451 2417
2452 DESCRIPTION 2418 DESCRIPTION
@@ -3200,6 +3166,40 @@ typedef struct
3200/******************************************************************************* 3166/*******************************************************************************
3201 3167
3202 NAME 3168 NAME
3169 CsrWifiSmeStaConfig
3170
3171 DESCRIPTION
3172 Station configuration options in the SME
3173
3174 MEMBERS
3175 connectionQualityRssiChangeTrigger - Sets the difference of RSSI
3176 measurements which triggers reports
3177 from the Firmware
3178 connectionQualitySnrChangeTrigger - Sets the difference of SNR measurements
3179 which triggers reports from the
3180 Firmware
3181 wmmModeMask - Mask containing one or more values from
3182 CsrWifiSmeWmmMode
3183 ifIndex - Indicates the band of frequencies used
3184 allowUnicastUseGroupCipher - If TRUE, it allows to use groupwise
3185 keys if no pairwise key is specified
3186 enableOpportunisticKeyCaching - If TRUE, enables the Opportunistic Key
3187 Caching feature
3188
3189*******************************************************************************/
3190typedef struct
3191{
3192 CsrUint8 connectionQualityRssiChangeTrigger;
3193 CsrUint8 connectionQualitySnrChangeTrigger;
3194 CsrWifiSmeWmmModeMask wmmModeMask;
3195 CsrWifiSmeRadioIF ifIndex;
3196 CsrBool allowUnicastUseGroupCipher;
3197 CsrBool enableOpportunisticKeyCaching;
3198} CsrWifiSmeStaConfig;
3199
3200/*******************************************************************************
3201
3202 NAME
3203 CsrWifiSmeWep128Keys 3203 CsrWifiSmeWep128Keys
3204 3204
3205 DESCRIPTION 3205 DESCRIPTION
@@ -3393,9 +3393,10 @@ typedef struct
3393#define CSR_WIFI_SME_SME_COMMON_CONFIG_SET_REQ ((CsrWifiSmePrim) (0x0034 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST)) 3393#define CSR_WIFI_SME_SME_COMMON_CONFIG_SET_REQ ((CsrWifiSmePrim) (0x0034 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST))
3394#define CSR_WIFI_SME_INTERFACE_CAPABILITY_GET_REQ ((CsrWifiSmePrim) (0x0035 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST)) 3394#define CSR_WIFI_SME_INTERFACE_CAPABILITY_GET_REQ ((CsrWifiSmePrim) (0x0035 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST))
3395#define CSR_WIFI_SME_WPS_CONFIGURATION_REQ ((CsrWifiSmePrim) (0x0036 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST)) 3395#define CSR_WIFI_SME_WPS_CONFIGURATION_REQ ((CsrWifiSmePrim) (0x0036 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST))
3396#define CSR_WIFI_SME_SET_REQ ((CsrWifiSmePrim) (0x0037 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST))
3396 3397
3397 3398
3398#define CSR_WIFI_SME_PRIM_DOWNSTREAM_HIGHEST (0x0036 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST) 3399#define CSR_WIFI_SME_PRIM_DOWNSTREAM_HIGHEST (0x0037 + CSR_WIFI_SME_PRIM_DOWNSTREAM_LOWEST)
3399 3400
3400/* Upstream */ 3401/* Upstream */
3401#define CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST (0x0000 + CSR_PRIM_UPSTREAM) 3402#define CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST (0x0000 + CSR_PRIM_UPSTREAM)
@@ -4812,6 +4813,30 @@ typedef struct
4812/******************************************************************************* 4813/*******************************************************************************
4813 4814
4814 NAME 4815 NAME
4816 CsrWifiSmeSetReq
4817
4818 DESCRIPTION
4819 Used to pass custom data to the SME. Format is the same as 802.11 Info
4820 Elements => | Id | Length | Data
4821 1) Cmanr Test Mode "Id:0 Length:1 Data:0x00 = OFF 0x01 = ON" "0x00 0x01
4822 (0x00|0x01)"
4823
4824 MEMBERS
4825 common - Common header for use with the CsrWifiFsm Module
4826 dataLength - Number of bytes in the buffer pointed to by 'data'
4827 data - Pointer to the buffer containing 'dataLength' bytes
4828
4829*******************************************************************************/
4830typedef struct
4831{
4832 CsrWifiFsmEvent common;
4833 CsrUint32 dataLength;
4834 CsrUint8 *data;
4835} CsrWifiSmeSetReq;
4836
4837/*******************************************************************************
4838
4839 NAME
4815 CsrWifiSmeActivateCfm 4840 CsrWifiSmeActivateCfm
4816 4841
4817 DESCRIPTION 4842 DESCRIPTION
diff --git a/drivers/staging/csr/csr_wifi_sme_serialize.c b/drivers/staging/csr/csr_wifi_sme_serialize.c
index 489c378186b..5c1bc31f2dd 100644
--- a/drivers/staging/csr/csr_wifi_sme_serialize.c
+++ b/drivers/staging/csr/csr_wifi_sme_serialize.c
@@ -1,6 +1,6 @@
1/***************************************************************************** 1/*****************************************************************************
2 2
3 (c) Cambridge Silicon Radio Limited 2011 3 (c) Cambridge Silicon Radio Limited 2012
4 All rights reserved and confidential information of CSR 4 All rights reserved and confidential information of CSR
5 5
6 Refer to LICENSE.txt included with this source for details 6 Refer to LICENSE.txt included with this source for details
@@ -1356,7 +1356,7 @@ CsrSize CsrWifiSmeSmeStaConfigSetReqSizeof(void *msg)
1356 bufferSize += 2; /* CsrUint16 primitive->interfaceTag */ 1356 bufferSize += 2; /* CsrUint16 primitive->interfaceTag */
1357 bufferSize += 1; /* CsrUint8 primitive->smeConfig.connectionQualityRssiChangeTrigger */ 1357 bufferSize += 1; /* CsrUint8 primitive->smeConfig.connectionQualityRssiChangeTrigger */
1358 bufferSize += 1; /* CsrUint8 primitive->smeConfig.connectionQualitySnrChangeTrigger */ 1358 bufferSize += 1; /* CsrUint8 primitive->smeConfig.connectionQualitySnrChangeTrigger */
1359 bufferSize += 1; /* CsrUint8 primitive->smeConfig.wmmModeMask */ 1359 bufferSize += 1; /* CsrWifiSmeWmmModeMask primitive->smeConfig.wmmModeMask */
1360 bufferSize += 1; /* CsrWifiSmeRadioIF primitive->smeConfig.ifIndex */ 1360 bufferSize += 1; /* CsrWifiSmeRadioIF primitive->smeConfig.ifIndex */
1361 bufferSize += 1; /* CsrBool primitive->smeConfig.allowUnicastUseGroupCipher */ 1361 bufferSize += 1; /* CsrBool primitive->smeConfig.allowUnicastUseGroupCipher */
1362 bufferSize += 1; /* CsrBool primitive->smeConfig.enableOpportunisticKeyCaching */ 1362 bufferSize += 1; /* CsrBool primitive->smeConfig.enableOpportunisticKeyCaching */
@@ -1898,6 +1898,62 @@ void CsrWifiSmeWpsConfigurationReqSerFree(void *voidPrimitivePointer)
1898} 1898}
1899 1899
1900 1900
1901CsrSize CsrWifiSmeSetReqSizeof(void *msg)
1902{
1903 CsrWifiSmeSetReq *primitive = (CsrWifiSmeSetReq *) msg;
1904 CsrSize bufferSize = 2;
1905
1906 /* Calculate the Size of the Serialised Data. Could be more efficient (Try 8) */
1907 bufferSize += 4; /* CsrUint32 primitive->dataLength */
1908 bufferSize += primitive->dataLength; /* CsrUint8 primitive->data */
1909 return bufferSize;
1910}
1911
1912
1913CsrUint8* CsrWifiSmeSetReqSer(CsrUint8 *ptr, CsrSize *len, void *msg)
1914{
1915 CsrWifiSmeSetReq *primitive = (CsrWifiSmeSetReq *)msg;
1916 *len = 0;
1917 CsrUint16Ser(ptr, len, primitive->common.type);
1918 CsrUint32Ser(ptr, len, (CsrUint32) primitive->dataLength);
1919 if (primitive->dataLength)
1920 {
1921 CsrMemCpySer(ptr, len, (const void *) primitive->data, ((CsrUint16) (primitive->dataLength)));
1922 }
1923 return(ptr);
1924}
1925
1926
1927void* CsrWifiSmeSetReqDes(CsrUint8 *buffer, CsrSize length)
1928{
1929 CsrWifiSmeSetReq *primitive = (CsrWifiSmeSetReq *) CsrPmemAlloc(sizeof(CsrWifiSmeSetReq));
1930 CsrSize offset;
1931 offset = 0;
1932
1933 CsrUint16Des(&primitive->common.type, buffer, &offset);
1934 CsrUint32Des((CsrUint32 *) &primitive->dataLength, buffer, &offset);
1935 if (primitive->dataLength)
1936 {
1937 primitive->data = (CsrUint8 *)CsrPmemAlloc(primitive->dataLength);
1938 CsrMemCpyDes(primitive->data, buffer, &offset, ((CsrUint16) (primitive->dataLength)));
1939 }
1940 else
1941 {
1942 primitive->data = NULL;
1943 }
1944
1945 return primitive;
1946}
1947
1948
1949void CsrWifiSmeSetReqSerFree(void *voidPrimitivePointer)
1950{
1951 CsrWifiSmeSetReq *primitive = (CsrWifiSmeSetReq *) voidPrimitivePointer;
1952 CsrPmemFree(primitive->data);
1953 CsrPmemFree(primitive);
1954}
1955
1956
1901CsrSize CsrWifiSmeAdhocConfigGetCfmSizeof(void *msg) 1957CsrSize CsrWifiSmeAdhocConfigGetCfmSizeof(void *msg)
1902{ 1958{
1903 CsrSize bufferSize = 2; 1959 CsrSize bufferSize = 2;
@@ -5085,7 +5141,7 @@ CsrSize CsrWifiSmeSmeStaConfigGetCfmSizeof(void *msg)
5085 bufferSize += 2; /* CsrResult primitive->status */ 5141 bufferSize += 2; /* CsrResult primitive->status */
5086 bufferSize += 1; /* CsrUint8 primitive->smeConfig.connectionQualityRssiChangeTrigger */ 5142 bufferSize += 1; /* CsrUint8 primitive->smeConfig.connectionQualityRssiChangeTrigger */
5087 bufferSize += 1; /* CsrUint8 primitive->smeConfig.connectionQualitySnrChangeTrigger */ 5143 bufferSize += 1; /* CsrUint8 primitive->smeConfig.connectionQualitySnrChangeTrigger */
5088 bufferSize += 1; /* CsrUint8 primitive->smeConfig.wmmModeMask */ 5144 bufferSize += 1; /* CsrWifiSmeWmmModeMask primitive->smeConfig.wmmModeMask */
5089 bufferSize += 1; /* CsrWifiSmeRadioIF primitive->smeConfig.ifIndex */ 5145 bufferSize += 1; /* CsrWifiSmeRadioIF primitive->smeConfig.ifIndex */
5090 bufferSize += 1; /* CsrBool primitive->smeConfig.allowUnicastUseGroupCipher */ 5146 bufferSize += 1; /* CsrBool primitive->smeConfig.allowUnicastUseGroupCipher */
5091 bufferSize += 1; /* CsrBool primitive->smeConfig.enableOpportunisticKeyCaching */ 5147 bufferSize += 1; /* CsrBool primitive->smeConfig.enableOpportunisticKeyCaching */
diff --git a/drivers/staging/csr/csr_wifi_sme_serialize.h b/drivers/staging/csr/csr_wifi_sme_serialize.h
index c2d7fd68c4a..0080bf43a6c 100644
--- a/drivers/staging/csr/csr_wifi_sme_serialize.h
+++ b/drivers/staging/csr/csr_wifi_sme_serialize.h
@@ -1,6 +1,6 @@
1/***************************************************************************** 1/*****************************************************************************
2 2
3 (c) Cambridge Silicon Radio Limited 2011 3 (c) Cambridge Silicon Radio Limited 2012
4 All rights reserved and confidential information of CSR 4 All rights reserved and confidential information of CSR
5 5
6 Refer to LICENSE.txt included with this source for details 6 Refer to LICENSE.txt included with this source for details
@@ -300,6 +300,11 @@ extern void* CsrWifiSmeWpsConfigurationReqDes(CsrUint8 *buffer, CsrSize len);
300extern CsrSize CsrWifiSmeWpsConfigurationReqSizeof(void *msg); 300extern CsrSize CsrWifiSmeWpsConfigurationReqSizeof(void *msg);
301extern void CsrWifiSmeWpsConfigurationReqSerFree(void *msg); 301extern void CsrWifiSmeWpsConfigurationReqSerFree(void *msg);
302 302
303extern CsrUint8* CsrWifiSmeSetReqSer(CsrUint8 *ptr, CsrSize *len, void *msg);
304extern void* CsrWifiSmeSetReqDes(CsrUint8 *buffer, CsrSize len);
305extern CsrSize CsrWifiSmeSetReqSizeof(void *msg);
306extern void CsrWifiSmeSetReqSerFree(void *msg);
307
303#define CsrWifiSmeActivateCfmSer CsrWifiEventCsrUint16Ser 308#define CsrWifiSmeActivateCfmSer CsrWifiEventCsrUint16Ser
304#define CsrWifiSmeActivateCfmDes CsrWifiEventCsrUint16Des 309#define CsrWifiSmeActivateCfmDes CsrWifiEventCsrUint16Des
305#define CsrWifiSmeActivateCfmSizeof CsrWifiEventCsrUint16Sizeof 310#define CsrWifiSmeActivateCfmSizeof CsrWifiEventCsrUint16Sizeof
diff --git a/drivers/staging/csr/drv.c b/drivers/staging/csr/drv.c
index 4545fb2b063..fbe86301816 100644
--- a/drivers/staging/csr/drv.c
+++ b/drivers/staging/csr/drv.c
@@ -47,12 +47,7 @@
47int buswidth = 0; /* 0 means use default, values 1,4 */ 47int buswidth = 0; /* 0 means use default, values 1,4 */
48int sdio_clock = 50000; /* kHz */ 48int sdio_clock = 50000; /* kHz */
49int unifi_debug = 0; 49int unifi_debug = 0;
50/* 50/* fw_init prevents f/w initialisation on error. */
51 * fw_init prevents f/w initialisation on error.
52 * Unless necessary, avoid usage in the CSR_SME_EMB build because it prevents
53 * UniFi initialisation after getting out of suspend and also leaves
54 * UniFi powered when the module unloads.
55 */
56int fw_init[MAX_UNIFI_DEVS] = {-1, -1}; 51int fw_init[MAX_UNIFI_DEVS] = {-1, -1};
57int use_5g = 0; 52int use_5g = 0;
58int led_mask = 0; /* 0x0c00 for dev-pc-1503c, dev-pc-1528a */ 53int led_mask = 0; /* 0x0c00 for dev-pc-1503c, dev-pc-1528a */
@@ -67,6 +62,12 @@ int sdio_byte_mode = 0; /* 0 for block mode + padding, 1 for byte mode */
67int coredump_max = CSR_WIFI_HIP_NUM_COREDUMP_BUFFERS; 62int coredump_max = CSR_WIFI_HIP_NUM_COREDUMP_BUFFERS;
68int run_bh_once = -1; /* Set for scheduled interrupt mode, -1 = default */ 63int run_bh_once = -1; /* Set for scheduled interrupt mode, -1 = default */
69int bh_priority = -1; 64int bh_priority = -1;
65#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
66#define UNIFI_LOG_HIP_SIGNALS_FILTER_SIGNAL (1 << 0)
67#define UNIFI_LOG_HIP_SIGNALS_FILTER_BULKDATA (1 << 1)
68#define UNIFI_LOG_HIP_SIGNALS_FILTER_TIMESTAMP (1 << 2)
69int log_hip_signals = 0;
70#endif
70 71
71MODULE_DESCRIPTION("CSR UniFi (SDIO)"); 72MODULE_DESCRIPTION("CSR UniFi (SDIO)");
72 73
@@ -87,6 +88,9 @@ module_param(sdio_byte_mode, int, S_IRUGO|S_IWUSR);
87module_param(coredump_max, int, S_IRUGO|S_IWUSR); 88module_param(coredump_max, int, S_IRUGO|S_IWUSR);
88module_param(run_bh_once, int, S_IRUGO|S_IWUSR); 89module_param(run_bh_once, int, S_IRUGO|S_IWUSR);
89module_param(bh_priority, int, S_IRUGO|S_IWUSR); 90module_param(bh_priority, int, S_IRUGO|S_IWUSR);
91#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
92module_param(log_hip_signals, int, S_IRUGO|S_IWUSR);
93#endif
90 94
91MODULE_PARM_DESC(buswidth, "SDIO bus width (0=default), set 1 for 1-bit or 4 for 4-bit mode"); 95MODULE_PARM_DESC(buswidth, "SDIO bus width (0=default), set 1 for 1-bit or 4 for 4-bit mode");
92MODULE_PARM_DESC(sdio_clock, "SDIO bus frequency in kHz, (default = 50 MHz)"); 96MODULE_PARM_DESC(sdio_clock, "SDIO bus frequency in kHz, (default = 50 MHz)");
@@ -105,6 +109,10 @@ MODULE_PARM_DESC(sdio_byte_mode, "Set to 1 for byte mode SDIO");
105MODULE_PARM_DESC(coredump_max, "Number of chip mini-coredump buffers to allocate"); 109MODULE_PARM_DESC(coredump_max, "Number of chip mini-coredump buffers to allocate");
106MODULE_PARM_DESC(run_bh_once, "Run BH only when firmware interrupts"); 110MODULE_PARM_DESC(run_bh_once, "Run BH only when firmware interrupts");
107MODULE_PARM_DESC(bh_priority, "Modify the BH thread priority"); 111MODULE_PARM_DESC(bh_priority, "Modify the BH thread priority");
112#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
113MODULE_PARM_DESC(log_hip_signals, "Set to 1 to enable HIP signal offline logging");
114#endif
115
108 116
109/* Callback for event logging to UDI clients */ 117/* Callback for event logging to UDI clients */
110static void udi_log_event(ul_client_t *client, 118static void udi_log_event(ul_client_t *client,
@@ -193,6 +201,54 @@ trace_putest_cmdid(unifi_putest_command_t putest_cmd)
193 } 201 }
194 } 202 }
195 203
204#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
205int uf_register_hip_offline_debug(unifi_priv_t *priv)
206{
207 ul_client_t *udi_cli;
208 int i;
209
210 udi_cli = ul_register_client(priv, CLI_USING_WIRE_FORMAT, udi_log_event);
211 if (udi_cli == NULL) {
212 /* Too many clients already using this device */
213 unifi_error(priv, "Too many UDI clients already open\n");
214 return -ENOSPC;
215 }
216 unifi_trace(priv, UDBG1, "Offline HIP client is registered\n");
217
218 down(&priv->udi_logging_mutex);
219 udi_cli->event_hook = udi_log_event;
220 unifi_set_udi_hook(priv->card, logging_handler);
221 /* Log all signals by default */
222 for (i = 0; i < SIG_FILTER_SIZE; i++) {
223 udi_cli->signal_filter[i] = 0xFFFF;
224 }
225 priv->logging_client = udi_cli;
226 up(&priv->udi_logging_mutex);
227
228 return 0;
229}
230
231int uf_unregister_hip_offline_debug(unifi_priv_t *priv)
232{
233 ul_client_t *udi_cli = priv->logging_client;
234 if (udi_cli == NULL)
235 {
236 unifi_error(priv, "Unknown HIP client unregister request\n");
237 return -ERANGE;
238 }
239
240 unifi_trace(priv, UDBG1, "Offline HIP client is unregistered\n");
241
242 down(&priv->udi_logging_mutex);
243 priv->logging_client = NULL;
244 udi_cli->event_hook = NULL;
245 up(&priv->udi_logging_mutex);
246
247 ul_deregister_client(udi_cli);
248
249 return 0;
250}
251#endif
196 252
197 253
198/* 254/*
@@ -312,7 +368,6 @@ unifi_open(struct inode *inode, struct file *file)
312} /* unifi_open() */ 368} /* unifi_open() */
313 369
314 370
315
316static int 371static int
317unifi_release(struct inode *inode, struct file *filp) 372unifi_release(struct inode *inode, struct file *filp)
318{ 373{
@@ -354,6 +409,15 @@ unifi_release(struct inode *inode, struct file *filp)
354 } 409 }
355 410
356 uf_sme_deinit(priv); 411 uf_sme_deinit(priv);
412
413 /* It is possible that a blocking SME request was made from another process
414 * which did not get read by the SME before the WifiOffReq.
415 * So check for a pending request which will go unanswered and cancel
416 * the wait for event. As only one blocking request can be in progress at
417 * a time, up to one event should be completed.
418 */
419 uf_sme_cancel_request(priv, 0);
420
357#endif /* CSR_SME_USERSPACE */ 421#endif /* CSR_SME_USERSPACE */
358 } else { 422 } else {
359 423
@@ -979,6 +1043,14 @@ unifi_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
979 goto out; 1043 goto out;
980 } 1044 }
981 1045
1046#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
1047 if (log_hip_signals) {
1048 unifi_error(priv, "omnicli cannot be used when log_hip_signals is used\n");
1049 r = -EFAULT;
1050 goto out;
1051 }
1052#endif
1053
982 down(&priv->udi_logging_mutex); 1054 down(&priv->udi_logging_mutex);
983 if (int_param) { 1055 if (int_param) {
984 pcli->event_hook = udi_log_event; 1056 pcli->event_hook = udi_log_event;
@@ -1264,6 +1336,11 @@ unifi_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
1264 1336
1265 unifi_info(priv, "UniFi ready\n"); 1337 unifi_info(priv, "UniFi ready\n");
1266 1338
1339#ifdef ANDROID_BUILD
1340 /* Release the wakelock */
1341 unifi_trace(priv, UDBG1, "netdev_init: release wake lock\n");
1342 wake_unlock(&unifi_sdio_wake_lock);
1343#endif
1267#ifdef CSR_NATIVE_SOFTMAC /* For softmac dev, force-enable the network interface rather than wait for a connected-ind */ 1344#ifdef CSR_NATIVE_SOFTMAC /* For softmac dev, force-enable the network interface rather than wait for a connected-ind */
1268 { 1345 {
1269 struct net_device *dev = priv->netdev[interfaceTag]; 1346 struct net_device *dev = priv->netdev[interfaceTag];
@@ -1720,6 +1797,40 @@ udi_log_event(ul_client_t *pcli,
1720 return; 1797 return;
1721 } 1798 }
1722 1799
1800#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
1801 /* When HIP offline signal logging is enabled, omnicli cannot run */
1802 if (log_hip_signals)
1803 {
1804 /* Add timestamp */
1805 if (log_hip_signals & UNIFI_LOG_HIP_SIGNALS_FILTER_TIMESTAMP)
1806 {
1807 int timestamp = jiffies_to_msecs(jiffies);
1808 unifi_debug_log_to_buf("T:");
1809 unifi_debug_log_to_buf("%04X%04X ", *(((CsrUint16*)&timestamp) + 1),
1810 *(CsrUint16*)&timestamp);
1811 }
1812
1813 /* Add signal */
1814 unifi_debug_log_to_buf("S%s:%04X R:%04X D:%04X ",
1815 dir ? "T" : "F",
1816 *(CsrUint16*)signal,
1817 *(CsrUint16*)(signal + 2),
1818 *(CsrUint16*)(signal + 4));
1819 unifi_debug_hex_to_buf(signal + 6, signal_len - 6);
1820
1821 /* Add bulk data (assume 1 bulk data per signal) */
1822 if ((log_hip_signals & UNIFI_LOG_HIP_SIGNALS_FILTER_BULKDATA) &&
1823 (bulkdata->d[0].data_length > 0))
1824 {
1825 unifi_debug_log_to_buf("\nD:");
1826 unifi_debug_hex_to_buf(bulkdata->d[0].os_data_ptr, bulkdata->d[0].data_length);
1827 }
1828 unifi_debug_log_to_buf("\n");
1829
1830 return;
1831 }
1832#endif
1833
1723#ifdef CSR_NATIVE_LINUX 1834#ifdef CSR_NATIVE_LINUX
1724 uf_native_process_udi_signal(pcli, signal, signal_len, bulkdata, dir); 1835 uf_native_process_udi_signal(pcli, signal, signal_len, bulkdata, dir);
1725#endif 1836#endif
@@ -1950,7 +2061,7 @@ int uf_create_device_nodes(unifi_priv_t *priv, int bus_id)
1950 priv->unifiudi_cdev.owner = THIS_MODULE; 2061 priv->unifiudi_cdev.owner = THIS_MODULE;
1951 2062
1952 devno = MKDEV(MAJOR(unifi_first_devno), 2063 devno = MKDEV(MAJOR(unifi_first_devno),
1953 MINOR(unifi_first_devno) + (bus_id * MAX_UNIFI_DEVS) + 1); 2064 MINOR(unifi_first_devno) + (bus_id * 2) + 1);
1954 r = cdev_add(&priv->unifiudi_cdev, devno, 1); 2065 r = cdev_add(&priv->unifiudi_cdev, devno, 1);
1955 if (r) { 2066 if (r) {
1956 device_destroy(unifi_class, priv->unifi_cdev.dev); 2067 device_destroy(unifi_class, priv->unifi_cdev.dev);
@@ -2081,7 +2192,9 @@ unifi_load(void)
2081#endif 2192#endif
2082 printk("CSR native no WEXT support\n"); 2193 printk("CSR native no WEXT support\n");
2083#endif 2194#endif
2084 2195#ifdef CSR_WIFI_SPLIT_PATCH
2196 printk("Split patch support\n");
2197#endif
2085 printk("Kernel %d.%d.%d\n", 2198 printk("Kernel %d.%d.%d\n",
2086 ((LINUX_VERSION_CODE) >> 16) & 0xff, 2199 ((LINUX_VERSION_CODE) >> 16) & 0xff,
2087 ((LINUX_VERSION_CODE) >> 8) & 0xff, 2200 ((LINUX_VERSION_CODE) >> 8) & 0xff,
diff --git a/drivers/staging/csr/firmware.c b/drivers/staging/csr/firmware.c
index 4ac3c89baa5..03da0d5c247 100644
--- a/drivers/staging/csr/firmware.c
+++ b/drivers/staging/csr/firmware.c
@@ -296,7 +296,18 @@ uf_run_unifihelper(unifi_priv_t *priv)
296#endif 296#endif
297} /* uf_run_unifihelper() */ 297} /* uf_run_unifihelper() */
298 298
299#ifdef CSR_WIFI_SPLIT_PATCH
300static CsrBool is_ap_mode(unifi_priv_t *priv)
301{
302 if (priv == NULL || priv->interfacePriv[0] == NULL)
303 {
304 return FALSE;
305 }
299 306
307 /* Test for mode requiring AP patch */
308 return(CSR_WIFI_HIP_IS_AP_FW(priv->interfacePriv[0]->interfaceMode));
309}
310#endif
300 311
301/* 312/*
302 * --------------------------------------------------------------------------- 313 * ---------------------------------------------------------------------------
@@ -334,8 +345,13 @@ int uf_request_firmware_files(unifi_priv_t *priv, int is_fw)
334 if (is_fw == UNIFI_FW_STA) { 345 if (is_fw == UNIFI_FW_STA) {
335 /* Free kernel buffer and reload */ 346 /* Free kernel buffer and reload */
336 uf_release_firmware(priv, &priv->fw_sta); 347 uf_release_firmware(priv, &priv->fw_sta);
348#ifdef CSR_WIFI_SPLIT_PATCH
337 scnprintf(fw_name, UNIFI_MAX_FW_PATH_LEN, "unifi-sdio-%d/%s", 349 scnprintf(fw_name, UNIFI_MAX_FW_PATH_LEN, "unifi-sdio-%d/%s",
338 postfix, "sta.xbv"); 350 postfix, (is_ap_mode(priv) ? "ap.xbv" : "staonly.xbv") );
351#else
352 scnprintf(fw_name, UNIFI_MAX_FW_PATH_LEN, "unifi-sdio-%d/%s",
353 postfix, "sta.xbv" );
354#endif
339 r = request_firmware(&fw_entry, fw_name, priv->unifi_device); 355 r = request_firmware(&fw_entry, fw_name, priv->unifi_device);
340 if (r == 0) { 356 if (r == 0) {
341 priv->fw_sta.dl_data = fw_entry->data; 357 priv->fw_sta.dl_data = fw_entry->data;
diff --git a/drivers/staging/csr/io.c b/drivers/staging/csr/io.c
index fbf1b2099cc..f489ade7f1b 100644
--- a/drivers/staging/csr/io.c
+++ b/drivers/staging/csr/io.c
@@ -407,6 +407,13 @@ register_unifi_sdio(CsrSdioFunction *sdio_dev, int bus_id, struct device *dev)
407 INIT_WORK(&priv->rx_work_struct, rx_wq_handler); 407 INIT_WORK(&priv->rx_work_struct, rx_wq_handler);
408#endif 408#endif
409 409
410#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
411 if (log_hip_signals)
412 {
413 uf_register_hip_offline_debug(priv);
414 }
415#endif
416
410 /* Initialise the SME related threads and parameters */ 417 /* Initialise the SME related threads and parameters */
411 r = uf_sme_init(priv); 418 r = uf_sme_init(priv);
412 if (r) { 419 if (r) {
@@ -431,6 +438,12 @@ register_unifi_sdio(CsrSdioFunction *sdio_dev, int bus_id, struct device *dev)
431 return priv; 438 return priv;
432 439
433failed4: 440failed4:
441#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
442if (log_hip_signals)
443{
444 uf_unregister_hip_offline_debug(priv);
445}
446#endif
434#ifdef CSR_WIFI_RX_PATH_SPLIT 447#ifdef CSR_WIFI_RX_PATH_SPLIT
435 flush_workqueue(priv->rx_workqueue); 448 flush_workqueue(priv->rx_workqueue);
436 destroy_workqueue(priv->rx_workqueue); 449 destroy_workqueue(priv->rx_workqueue);
@@ -547,6 +560,13 @@ cleanup_unifi_sdio(unifi_priv_t *priv)
547 priv->smepriv = NULL; 560 priv->smepriv = NULL;
548#endif 561#endif
549 562
563#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
564 if (log_hip_signals)
565 {
566 uf_unregister_hip_offline_debug(priv);
567 }
568#endif
569
550 /* Free any packets left in the Rx queues */ 570 /* Free any packets left in the Rx queues */
551 for(i=0;i<CSR_WIFI_NUM_INTERFACES;i++) 571 for(i=0;i<CSR_WIFI_NUM_INTERFACES;i++)
552 { 572 {
diff --git a/drivers/staging/csr/netdev.c b/drivers/staging/csr/netdev.c
index b0335f6fff4..cf19f1116c2 100644
--- a/drivers/staging/csr/netdev.c
+++ b/drivers/staging/csr/netdev.c
@@ -402,9 +402,14 @@ uf_alloc_netdevice(CsrSdioFunction *sdio_dev, int bus_id)
402 402
403 priv->sta_wmm_capabilities = 0; 403 priv->sta_wmm_capabilities = 0;
404 404
405#if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_SUPPORT_SME))
405 priv->wapi_multicast_filter = 0; 406 priv->wapi_multicast_filter = 0;
406 priv->wapi_unicast_filter = 0; 407 priv->wapi_unicast_filter = 0;
407 priv->wapi_unicast_queued_pkt_filter = 0; 408 priv->wapi_unicast_queued_pkt_filter = 0;
409#ifdef CSR_WIFI_SECURITY_WAPI_QOSCTRL_MIC_WORKAROUND
410 priv->isWapiConnection = FALSE;
411#endif
412#endif
408 413
409 /* Enable all queues by default */ 414 /* Enable all queues by default */
410 interfacePriv->queueEnabled[0] = 1; 415 interfacePriv->queueEnabled[0] = 1;
@@ -450,7 +455,15 @@ uf_alloc_netdevice(CsrSdioFunction *sdio_dev, int bus_id)
450 spin_lock_init(&priv->send_signal_lock); 455 spin_lock_init(&priv->send_signal_lock);
451 456
452 spin_lock_init(&priv->m4_lock); 457 spin_lock_init(&priv->m4_lock);
453 spin_lock_init(&priv->ba_lock); 458#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)
459 sema_init(&priv->ba_mutex, 1);
460#else
461 init_MUTEX(&priv->ba_mutex);
462#endif
463
464#if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION))
465 spin_lock_init(&priv->wapi_lock);
466#endif
454 467
455#ifdef CSR_SUPPORT_SME 468#ifdef CSR_SUPPORT_SME
456 spin_lock_init(&priv->staRecord_lock); 469 spin_lock_init(&priv->staRecord_lock);
@@ -472,6 +485,11 @@ uf_alloc_netdevice(CsrSdioFunction *sdio_dev, int bus_id)
472 485
473 /* Create m4 buffering work structure */ 486 /* Create m4 buffering work structure */
474 INIT_WORK(&interfacePriv->send_m4_ready_task, uf_send_m4_ready_wq); 487 INIT_WORK(&interfacePriv->send_m4_ready_task, uf_send_m4_ready_wq);
488
489#if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION))
490 /* Create work structure to buffer the WAPI data packets to be sent to SME for encryption */
491 INIT_WORK(&interfacePriv->send_pkt_to_encrypt, uf_send_pkt_to_encrypt);
492#endif
475#endif 493#endif
476 494
477#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28) 495#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
@@ -504,6 +522,11 @@ uf_alloc_netdevice(CsrSdioFunction *sdio_dev, int bus_id)
504 } 522 }
505#endif /* CSR_SUPPORT_WEXT */ 523#endif /* CSR_SUPPORT_WEXT */
506 524
525#ifdef CSR_WIFI_SPLIT_PATCH
526 /* set it to some invalid value */
527 priv->pending_mode_set.common.destination = 0xaaaa;
528#endif
529
507 return priv; 530 return priv;
508} /* uf_alloc_netdevice() */ 531} /* uf_alloc_netdevice() */
509 532
@@ -655,6 +678,19 @@ uf_free_netdevice(unifi_priv_t *priv)
655 } 678 }
656 spin_unlock_irqrestore(&priv->m4_lock, flags); 679 spin_unlock_irqrestore(&priv->m4_lock, flags);
657 680
681#if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION))
682 /* Free any bulkdata buffers allocated for M4 caching */
683 spin_lock_irqsave(&priv->wapi_lock, flags);
684 for (i = 0; i < CSR_WIFI_NUM_INTERFACES; i++) {
685 netInterface_priv_t *interfacePriv = priv->interfacePriv[i];
686 if (interfacePriv->wapi_unicast_bulk_data.data_length > 0) {
687 unifi_trace(priv, UDBG5, "uf_free_netdevice: free WAPI PKT bulk data %d\n", i);
688 unifi_net_data_free(priv, &interfacePriv->wapi_unicast_bulk_data);
689 }
690 }
691 spin_unlock_irqrestore(&priv->wapi_lock, flags);
692#endif
693
658#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28) 694#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
659#ifdef CONFIG_NET_SCHED 695#ifdef CONFIG_NET_SCHED
660 /* Unregister the qdisc operations */ 696 /* Unregister the qdisc operations */
@@ -1556,7 +1592,7 @@ int prepare_and_add_macheader(unifi_priv_t *priv, struct sk_buff *skb, struct sk
1556 /* IF Qos Data or Qos Null Data then set QosControl field */ 1592 /* IF Qos Data or Qos Null Data then set QosControl field */
1557 if ((priority != CSR_CONTENTION) && (macHeaderLengthInBytes >= QOS_CONTROL_HEADER_SIZE)) { 1593 if ((priority != CSR_CONTENTION) && (macHeaderLengthInBytes >= QOS_CONTROL_HEADER_SIZE)) {
1558 1594
1559 if (priority >= 7) { 1595 if (priority > 7) {
1560 unifi_trace(priv, UDBG1, "data packets priority is more than 7, priority = %x\n", priority); 1596 unifi_trace(priv, UDBG1, "data packets priority is more than 7, priority = %x\n", priority);
1561 qc |= 7; 1597 qc |= 7;
1562 } else { 1598 } else {
@@ -1628,6 +1664,7 @@ send_ma_pkt_request(unifi_priv_t *priv, struct sk_buff *skb, const struct ethhdr
1628 CSR_TRANSMISSION_CONTROL transmissionControl = CSR_NO_CONFIRM_REQUIRED; 1664 CSR_TRANSMISSION_CONTROL transmissionControl = CSR_NO_CONFIRM_REQUIRED;
1629 CsrInt8 protection; 1665 CsrInt8 protection;
1630 netInterface_priv_t *interfacePriv = NULL; 1666 netInterface_priv_t *interfacePriv = NULL;
1667 CSR_RATE TransmitRate = (CSR_RATE)0;
1631 1668
1632 unifi_trace(priv, UDBG5, "entering send_ma_pkt_request\n"); 1669 unifi_trace(priv, UDBG5, "entering send_ma_pkt_request\n");
1633 1670
@@ -1780,6 +1817,63 @@ send_ma_pkt_request(unifi_priv_t *priv, struct sk_buff *skb, const struct ethhdr
1780 return 0; 1817 return 0;
1781 } 1818 }
1782#endif 1819#endif
1820 }/*EAPOL or WAI packet*/
1821
1822#if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION))
1823 if ((CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode) && \
1824 (priv->wapi_unicast_filter) && \
1825 (proto != ETH_P_PAE) && \
1826 (proto != ETH_P_WAI) && \
1827 (skb->len > 0))
1828 {
1829 CSR_SIGNAL signal;
1830 CSR_MA_PACKET_REQUEST *req = &signal.u.MaPacketRequest;
1831 netInterface_priv_t *netpriv = (netInterface_priv_t *)netdev_priv(priv->netdev[interfaceTag]);
1832
1833 unifi_trace(priv, UDBG4, "send_ma_pkt_request() - WAPI unicast data packet when USKID = 1 \n");
1834
1835 /* initialize signal to zero */
1836 memset(&signal, 0, sizeof(CSR_SIGNAL));
1837 /* Frame MA_PACKET request */
1838 signal.SignalPrimitiveHeader.SignalId = CSR_MA_PACKET_REQUEST_ID;
1839 signal.SignalPrimitiveHeader.ReceiverProcessId = 0;
1840 signal.SignalPrimitiveHeader.SenderProcessId = priv->netdev_client->sender_id;
1841
1842 /* Fill the MA-PACKET.req */
1843 req->TransmissionControl = 0;
1844 req->Priority = priority;
1845 unifi_trace(priv, UDBG3, "Tx Frame with Priority: %x\n", req->Priority);
1846 req->TransmitRate = (CSR_RATE) 0; /* rate selected by firmware */
1847 req->HostTag = 0xffffffff; /* Ask for a new HostTag */
1848 /* RA address matching with address 1 of Mac header */
1849 memcpy(req->Ra.x, ((CsrUint8 *) bulkdata.d[0].os_data_ptr) + 4, ETH_ALEN);
1850
1851 /* Store the M4-PACKET.req for later */
1852 spin_lock(&priv->wapi_lock);
1853 interfacePriv->wapi_unicast_ma_pkt_sig = signal;
1854 interfacePriv->wapi_unicast_bulk_data.net_buf_length = bulkdata.d[0].net_buf_length;
1855 interfacePriv->wapi_unicast_bulk_data.data_length = bulkdata.d[0].data_length;
1856 interfacePriv->wapi_unicast_bulk_data.os_data_ptr = bulkdata.d[0].os_data_ptr;
1857 interfacePriv->wapi_unicast_bulk_data.os_net_buf_ptr = bulkdata.d[0].os_net_buf_ptr;
1858 spin_unlock(&priv->wapi_lock);
1859
1860 /* Signal the workqueue to call CsrWifiRouterCtrlWapiUnicastTxEncryptIndSend().
1861 * It cannot be called directly from the tx path because it
1862 * does a non-atomic kmalloc via the framework's CsrPmemAlloc().
1863 */
1864 queue_work(priv->unifi_workqueue, &netpriv->send_pkt_to_encrypt);
1865
1866 return 0;
1867 }
1868#endif
1869
1870 if(priv->cmanrTestMode)
1871 {
1872 TransmitRate = priv->cmanrTestModeTransmitRate;
1873 unifi_trace(priv, UDBG2, "send_ma_pkt_request: cmanrTestModeTransmitRate = %d TransmitRate=%d\n",
1874 priv->cmanrTestModeTransmitRate,
1875 TransmitRate
1876 );
1783 } 1877 }
1784 1878
1785 /* Send UniFi msg */ 1879 /* Send UniFi msg */
@@ -1789,7 +1883,7 @@ send_ma_pkt_request(unifi_priv_t *priv, struct sk_buff *skb, const struct ethhdr
1789 0xffffffff, /* Ask for a new HostTag */ 1883 0xffffffff, /* Ask for a new HostTag */
1790 interfaceTag, 1884 interfaceTag,
1791 transmissionControl, 1885 transmissionControl,
1792 (CSR_RATE)0, 1886 TransmitRate,
1793 priority, 1887 priority,
1794 priv->netdev_client->sender_id, 1888 priv->netdev_client->sender_id,
1795 &bulkdata); 1889 &bulkdata);
@@ -1900,8 +1994,22 @@ uf_net_xmit(struct sk_buff *skb, struct net_device *dev)
1900#endif /* CONFIG_NET_SCHED */ 1994#endif /* CONFIG_NET_SCHED */
1901 1995
1902 if (result == NETDEV_TX_OK) { 1996 if (result == NETDEV_TX_OK) {
1997#if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION))
1998 /* Don't update the tx stats when the pkt is to be sent for sw encryption*/
1999 if (!((CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode) &&
2000 (priv->wapi_unicast_filter == 1)))
2001 {
2002 dev->trans_start = jiffies;
2003 /* Should really count tx stats in the UNITDATA.status signal but
2004 * that doesn't have the length.
2005 */
2006 interfacePriv->stats.tx_packets++;
2007 /* count only the packet payload */
2008 interfacePriv->stats.tx_bytes += skb->len;
1903 2009
1904 dev->trans_start = jiffies; 2010 }
2011#else
2012 dev->trans_start = jiffies;
1905 2013
1906 /* 2014 /*
1907 * Should really count tx stats in the UNITDATA.status signal but 2015 * Should really count tx stats in the UNITDATA.status signal but
@@ -1910,7 +2018,7 @@ uf_net_xmit(struct sk_buff *skb, struct net_device *dev)
1910 interfacePriv->stats.tx_packets++; 2018 interfacePriv->stats.tx_packets++;
1911 /* count only the packet payload */ 2019 /* count only the packet payload */
1912 interfacePriv->stats.tx_bytes += skb->len; 2020 interfacePriv->stats.tx_bytes += skb->len;
1913 2021#endif
1914 } else if (result < 0) { 2022 } else if (result < 0) {
1915 2023
1916 /* Failed to send: fh queue was full, and the skb was discarded. 2024 /* Failed to send: fh queue was full, and the skb was discarded.
@@ -2118,6 +2226,13 @@ indicate_rx_skb(unifi_priv_t *priv, CsrUint16 ifTag, CsrUint8* dst_a, CsrUint8*
2118 } 2226 }
2119 2227
2120 2228
2229 if(priv->cmanrTestMode)
2230 {
2231 const CSR_MA_PACKET_INDICATION *pkt_ind = &signal->u.MaPacketIndication;
2232 priv->cmanrTestModeTransmitRate = pkt_ind->ReceivedRate;
2233 unifi_trace(priv, UDBG2, "indicate_rx_skb: cmanrTestModeTransmitRate=%d\n", priv->cmanrTestModeTransmitRate);
2234 }
2235
2121 /* Pass SKB up the stack */ 2236 /* Pass SKB up the stack */
2122#ifdef CSR_WIFI_USE_NETIF_RX 2237#ifdef CSR_WIFI_USE_NETIF_RX
2123 netif_rx(skb); 2238 netif_rx(skb);
@@ -2780,36 +2895,17 @@ static void process_ma_packet_ind(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_d
2780 if((dataFrameType == QOS_DATA) || (dataFrameType == QOS_DATA_NULL)){ 2895 if((dataFrameType == QOS_DATA) || (dataFrameType == QOS_DATA_NULL)){
2781 2896
2782 /* 2897 /*
2783 QoS control field is offset from frame control by 2 (frame control) 2898 * QoS control field is offset from frame control by 2 (frame control)
2784 + 2 (duration/ID) + 2 (sequence control) + 3*ETH_ALEN or 4*ETH_ALEN 2899 * + 2 (duration/ID) + 2 (sequence control) + 3*ETH_ALEN or 4*ETH_ALEN
2785 */ 2900 */
2786 if((frameControl & IEEE802_11_FC_TO_DS_MASK) && (frameControl & IEEE802_11_FC_FROM_DS_MASK)){ 2901 if((frameControl & IEEE802_11_FC_TO_DS_MASK) && (frameControl & IEEE802_11_FC_FROM_DS_MASK)){
2787 qosControl= CSR_GET_UINT16_FROM_LITTLE_ENDIAN(pData->os_data_ptr + 30); 2902 qosControl= CSR_GET_UINT16_FROM_LITTLE_ENDIAN(pData->os_data_ptr + 30);
2788 } 2903 }
2789 else{ 2904 else{
2790 qosControl = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(pData->os_data_ptr + 24); 2905 qosControl = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(pData->os_data_ptr + 24);
2791 } 2906 }
2792 2907 unifi_trace(priv, UDBG5, "%s: Check if U-APSD operations are triggered for qosControl: 0x%x\n",__FUNCTION__,qosControl);
2793 if((IS_DTIM_ACTIVE(interfacePriv->dtimActive,interfacePriv->multicastPduHostTag))){ 2908 uf_process_wmm_deliver_ac_uapsd(priv,srcStaInfo,qosControl,interfaceTag);
2794 CSR_PRIORITY priority;
2795 unifi_TrafficQueue priority_q;
2796 priority = (CSR_PRIORITY)(qosControl & IEEE802_11_QC_TID_MASK);
2797 priority_q = unifi_frame_priority_to_queue((CSR_PRIORITY) priority);
2798 if((srcStaInfo->powersaveMode[priority_q]==CSR_WIFI_AC_TRIGGER_ONLY_ENABLED)
2799 ||(srcStaInfo->powersaveMode[priority_q]==CSR_WIFI_AC_TRIGGER_AND_DELIVERY_ENABLED)){
2800 unsigned long lock_flags;
2801 spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
2802 srcStaInfo->uapsdSuspended = TRUE;
2803 spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
2804 unifi_trace(priv, UDBG3, "%s: qos Trigger Frame received while DTIM Active for staid: 0x%x\n",__FUNCTION__,srcStaInfo->aid);
2805 }
2806 }
2807 else{
2808
2809
2810 unifi_trace(priv, UDBG5, "%s: Check if U-APSD operations are triggered for qosControl: 0x%x\n",__FUNCTION__,qosControl);
2811 uf_process_wmm_deliver_ac_uapsd(priv,srcStaInfo,qosControl,interfaceTag);
2812 }
2813 } 2909 }
2814 } 2910 }
2815 } 2911 }
@@ -2829,7 +2925,7 @@ static void process_ma_packet_ind(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_d
2829 ba_addr = bssid; 2925 ba_addr = bssid;
2830 } 2926 }
2831 2927
2832 spin_lock(&priv->ba_lock); 2928 down(&priv->ba_mutex);
2833 for (ba_session_idx=0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_RX; ba_session_idx++){ 2929 for (ba_session_idx=0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_RX; ba_session_idx++){
2834 ba_session = interfacePriv->ba_session_rx[ba_session_idx]; 2930 ba_session = interfacePriv->ba_session_rx[ba_session_idx];
2835 if (ba_session){ 2931 if (ba_session){
@@ -2842,14 +2938,14 @@ static void process_ma_packet_ind(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_d
2842 frame_desc.active = TRUE; 2938 frame_desc.active = TRUE;
2843 unifi_trace(priv, UDBG6, "%s: calling process_ba_frame (session=%d)\n", __FUNCTION__, ba_session_idx); 2939 unifi_trace(priv, UDBG6, "%s: calling process_ba_frame (session=%d)\n", __FUNCTION__, ba_session_idx);
2844 process_ba_frame(priv, interfacePriv, ba_session, &frame_desc); 2940 process_ba_frame(priv, interfacePriv, ba_session, &frame_desc);
2845 spin_unlock(&priv->ba_lock); 2941 up(&priv->ba_mutex);
2846 process_ba_complete(priv, interfacePriv); 2942 process_ba_complete(priv, interfacePriv);
2847 break; 2943 break;
2848 } 2944 }
2849 } 2945 }
2850 } 2946 }
2851 if (ba_session_idx == MAX_SUPPORTED_BA_SESSIONS_RX){ 2947 if (ba_session_idx == MAX_SUPPORTED_BA_SESSIONS_RX){
2852 spin_unlock(&priv->ba_lock); 2948 up(&priv->ba_mutex);
2853 unifi_trace(priv, UDBG6, "%s: calling process_amsdu()", __FUNCTION__); 2949 unifi_trace(priv, UDBG6, "%s: calling process_amsdu()", __FUNCTION__);
2854 process_amsdu(priv, signal, bulkdata); 2950 process_amsdu(priv, signal, bulkdata);
2855 } 2951 }
@@ -2865,7 +2961,7 @@ static void process_ma_packet_ind(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_d
2865 * And also this code here takes care that timeout check is made for all 2961 * And also this code here takes care that timeout check is made for all
2866 * the receive indications 2962 * the receive indications
2867 */ 2963 */
2868 spin_lock(&priv->ba_lock); 2964 down(&priv->ba_mutex);
2869 for (i=0; i < MAX_SUPPORTED_BA_SESSIONS_RX; i++){ 2965 for (i=0; i < MAX_SUPPORTED_BA_SESSIONS_RX; i++){
2870 ba_session_rx_struct *ba_session; 2966 ba_session_rx_struct *ba_session;
2871 ba_session = interfacePriv->ba_session_rx[i]; 2967 ba_session = interfacePriv->ba_session_rx[i];
@@ -2873,8 +2969,8 @@ static void process_ma_packet_ind(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_d
2873 check_ba_frame_age_timeout(priv, interfacePriv, ba_session); 2969 check_ba_frame_age_timeout(priv, interfacePriv, ba_session);
2874 } 2970 }
2875 } 2971 }
2972 up(&priv->ba_mutex);
2876 process_ba_complete(priv, interfacePriv); 2973 process_ba_complete(priv, interfacePriv);
2877 spin_unlock(&priv->ba_lock);
2878 2974
2879 func_exit(); 2975 func_exit();
2880} 2976}
@@ -3879,7 +3975,7 @@ static void process_ma_packet_error_ind(unifi_priv_t *priv, CSR_SIGNAL *signal,
3879 } 3975 }
3880 sn = pkt_err_ind->SequenceNumber; 3976 sn = pkt_err_ind->SequenceNumber;
3881 3977
3882 spin_lock(&priv->ba_lock); 3978 down(&priv->ba_mutex);
3883 /* To find the right ba_session loop through the BA sessions, compare MAC address and tID */ 3979 /* To find the right ba_session loop through the BA sessions, compare MAC address and tID */
3884 for (ba_session_idx=0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_RX; ba_session_idx++){ 3980 for (ba_session_idx=0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_RX; ba_session_idx++){
3885 ba_session = interfacePriv->ba_session_rx[ba_session_idx]; 3981 ba_session = interfacePriv->ba_session_rx[ba_session_idx];
@@ -3894,7 +3990,7 @@ static void process_ma_packet_error_ind(unifi_priv_t *priv, CSR_SIGNAL *signal,
3894 } 3990 }
3895 } 3991 }
3896 3992
3897 spin_unlock(&priv->ba_lock); 3993 up(&priv->ba_mutex);
3898 process_ba_complete(priv, interfacePriv); 3994 process_ba_complete(priv, interfacePriv);
3899 func_exit(); 3995 func_exit();
3900} 3996}
diff --git a/drivers/staging/csr/os.c b/drivers/staging/csr/os.c
index 6dfce422675..f5a9352ce78 100644
--- a/drivers/staging/csr/os.c
+++ b/drivers/staging/csr/os.c
@@ -204,12 +204,10 @@ extern int unifi_debug;
204 (_s)[DEBUG_BUFFER_SIZE - 1] = 0; \ 204 (_s)[DEBUG_BUFFER_SIZE - 1] = 0; \
205 } \ 205 } \
206 } while (0) 206 } while (0)
207#endif /* UNIFI_DEBUG */
208 207
209void 208void
210unifi_error(void* ospriv, const char *fmt, ...) 209unifi_error(void* ospriv, const char *fmt, ...)
211{ 210{
212#ifdef UNIFI_DEBUG
213 unifi_priv_t *priv = (unifi_priv_t*) ospriv; 211 unifi_priv_t *priv = (unifi_priv_t*) ospriv;
214 char s[DEBUG_BUFFER_SIZE]; 212 char s[DEBUG_BUFFER_SIZE];
215 va_list args; 213 va_list args;
@@ -230,13 +228,11 @@ unifi_error(void* ospriv, const char *fmt, ...)
230 FORMAT_TRACE(s, len, args, fmt); 228 FORMAT_TRACE(s, len, args, fmt);
231 229
232 printk("%s", s); 230 printk("%s", s);
233#endif /* UNIFI_DEBUG */
234} 231}
235 232
236void 233void
237unifi_warning(void* ospriv, const char *fmt, ...) 234unifi_warning(void* ospriv, const char *fmt, ...)
238{ 235{
239#ifdef UNIFI_DEBUG
240 unifi_priv_t *priv = (unifi_priv_t*) ospriv; 236 unifi_priv_t *priv = (unifi_priv_t*) ospriv;
241 char s[DEBUG_BUFFER_SIZE]; 237 char s[DEBUG_BUFFER_SIZE];
242 va_list args; 238 va_list args;
@@ -259,14 +255,12 @@ unifi_warning(void* ospriv, const char *fmt, ...)
259 FORMAT_TRACE(s, len, args, fmt); 255 FORMAT_TRACE(s, len, args, fmt);
260 256
261 printk("%s", s); 257 printk("%s", s);
262#endif /* UNIFI_DEBUG */
263} 258}
264 259
265 260
266void 261void
267unifi_notice(void* ospriv, const char *fmt, ...) 262unifi_notice(void* ospriv, const char *fmt, ...)
268{ 263{
269#ifdef UNIFI_DEBUG
270 unifi_priv_t *priv = (unifi_priv_t*) ospriv; 264 unifi_priv_t *priv = (unifi_priv_t*) ospriv;
271 char s[DEBUG_BUFFER_SIZE]; 265 char s[DEBUG_BUFFER_SIZE];
272 va_list args; 266 va_list args;
@@ -289,14 +283,12 @@ unifi_notice(void* ospriv, const char *fmt, ...)
289 FORMAT_TRACE(s, len, args, fmt); 283 FORMAT_TRACE(s, len, args, fmt);
290 284
291 printk("%s", s); 285 printk("%s", s);
292#endif /* UNIFI_DEBUG */
293} 286}
294 287
295 288
296void 289void
297unifi_info(void* ospriv, const char *fmt, ...) 290unifi_info(void* ospriv, const char *fmt, ...)
298{ 291{
299#ifdef UNIFI_DEBUG
300 unifi_priv_t *priv = (unifi_priv_t*) ospriv; 292 unifi_priv_t *priv = (unifi_priv_t*) ospriv;
301 char s[DEBUG_BUFFER_SIZE]; 293 char s[DEBUG_BUFFER_SIZE];
302 va_list args; 294 va_list args;
@@ -319,14 +311,12 @@ unifi_info(void* ospriv, const char *fmt, ...)
319 FORMAT_TRACE(s, len, args, fmt); 311 FORMAT_TRACE(s, len, args, fmt);
320 312
321 printk("%s", s); 313 printk("%s", s);
322#endif /* UNIFI_DEBUG */
323} 314}
324 315
325/* debugging */ 316/* debugging */
326void 317void
327unifi_trace(void* ospriv, int level, const char *fmt, ...) 318unifi_trace(void* ospriv, int level, const char *fmt, ...)
328{ 319{
329#ifdef UNIFI_DEBUG
330 unifi_priv_t *priv = (unifi_priv_t*) ospriv; 320 unifi_priv_t *priv = (unifi_priv_t*) ospriv;
331 char s[DEBUG_BUFFER_SIZE]; 321 char s[DEBUG_BUFFER_SIZE];
332 va_list args; 322 va_list args;
@@ -351,9 +341,23 @@ unifi_trace(void* ospriv, int level, const char *fmt, ...)
351 341
352 printk("%s", s); 342 printk("%s", s);
353 } 343 }
354#endif /* UNIFI_DEBUG */
355} 344}
356 345
346#else
347
348void
349unifi_error_nop(void* ospriv, const char *fmt, ...)
350{
351}
352
353void
354unifi_trace_nop(void* ospriv, int level, const char *fmt, ...)
355{
356}
357
358#endif /* UNIFI_DEBUG */
359
360
357/* 361/*
358 * --------------------------------------------------------------------------- 362 * ---------------------------------------------------------------------------
359 * 363 *
diff --git a/drivers/staging/csr/putest.c b/drivers/staging/csr/putest.c
index 1b2c7c299a6..22614e7e8f7 100644
--- a/drivers/staging/csr/putest.c
+++ b/drivers/staging/csr/putest.c
@@ -180,8 +180,9 @@ int unifi_putest_gp_read16(unifi_priv_t *priv, unsigned char *arg)
180 "unifi_putest_gp_read16: Failed to get the params\n"); 180 "unifi_putest_gp_read16: Failed to get the params\n");
181 return -EFAULT; 181 return -EFAULT;
182 } 182 }
183 183 CsrSdioClaim(priv->sdio);
184 csrResult = unifi_card_read16(priv->card, gp_r16_params.addr, &gp_r16_params.data); 184 csrResult = unifi_card_read16(priv->card, gp_r16_params.addr, &gp_r16_params.data);
185 CsrSdioRelease(priv->sdio);
185 if (csrResult != CSR_RESULT_SUCCESS) { 186 if (csrResult != CSR_RESULT_SUCCESS) {
186 unifi_error(priv, 187 unifi_error(priv,
187 "unifi_putest_gp_read16: unifi_card_read16() GP=0x%x failed (csrResult=0x%x)\n", gp_r16_params.addr, csrResult); 188 "unifi_putest_gp_read16: unifi_card_read16() GP=0x%x failed (csrResult=0x%x)\n", gp_r16_params.addr, csrResult);
@@ -240,8 +241,9 @@ int unifi_putest_gp_write16(unifi_priv_t *priv, unsigned char *arg)
240 } 241 }
241 242
242 unifi_trace(priv, UDBG2, "gp_w16: GP=0x%08x, data=0x%04x\n", gp_w16_params.addr, gp_w16_params.data); 243 unifi_trace(priv, UDBG2, "gp_w16: GP=0x%08x, data=0x%04x\n", gp_w16_params.addr, gp_w16_params.data);
243 244 CsrSdioClaim(priv->sdio);
244 csrResult = unifi_card_write16(priv->card, gp_w16_params.addr, gp_w16_params.data); 245 csrResult = unifi_card_write16(priv->card, gp_w16_params.addr, gp_w16_params.data);
246 CsrSdioRelease(priv->sdio);
245 if (csrResult != CSR_RESULT_SUCCESS) { 247 if (csrResult != CSR_RESULT_SUCCESS) {
246 unifi_error(priv, 248 unifi_error(priv,
247 "unifi_putest_gp_write16: unifi_card_write16() GP=%x failed (csrResult=0x%x)\n", gp_w16_params.addr, csrResult); 249 "unifi_putest_gp_write16: unifi_card_write16() GP=%x failed (csrResult=0x%x)\n", gp_w16_params.addr, csrResult);
@@ -265,7 +267,7 @@ int unifi_putest_set_sdio_clock(unifi_priv_t *priv, unsigned char *arg)
265 unifi_trace(priv, UDBG2, "set sdio clock: %d KHz\n", sdio_clock_speed); 267 unifi_trace(priv, UDBG2, "set sdio clock: %d KHz\n", sdio_clock_speed);
266 268
267 CsrSdioClaim(priv->sdio); 269 CsrSdioClaim(priv->sdio);
268 csrResult = CsrSdioMaxBusClockFrequencySet(priv->sdio, sdio_clock_speed); 270 csrResult = CsrSdioMaxBusClockFrequencySet(priv->sdio, sdio_clock_speed * 1000);
269 CsrSdioRelease(priv->sdio); 271 CsrSdioRelease(priv->sdio);
270 if (csrResult != CSR_RESULT_SUCCESS) { 272 if (csrResult != CSR_RESULT_SUCCESS) {
271 unifi_error(priv, 273 unifi_error(priv,
@@ -304,7 +306,9 @@ int unifi_putest_start(unifi_priv_t *priv, unsigned char *arg)
304 306
305 /* Application may have stopped the XAPs, but they are needed for reset */ 307 /* Application may have stopped the XAPs, but they are needed for reset */
306 if (already_in_test) { 308 if (already_in_test) {
309 CsrSdioClaim(priv->sdio);
307 csrResult = unifi_start_processors(priv->card); 310 csrResult = unifi_start_processors(priv->card);
311 CsrSdioRelease(priv->sdio);
308 if (csrResult != CSR_RESULT_SUCCESS) { 312 if (csrResult != CSR_RESULT_SUCCESS) {
309 unifi_error(priv, "Failed to start XAPs. Hard reset required.\n"); 313 unifi_error(priv, "Failed to start XAPs. Hard reset required.\n");
310 } 314 }
@@ -317,8 +321,9 @@ int unifi_putest_start(unifi_priv_t *priv, unsigned char *arg)
317 unifi_error(priv, "CsrSdioPowerOn csrResult = %d\n", csrResult); 321 unifi_error(priv, "CsrSdioPowerOn csrResult = %d\n", csrResult);
318 } 322 }
319 } 323 }
320 324 CsrSdioClaim(priv->sdio);
321 csrResult = unifi_init(priv->card); 325 csrResult = unifi_init(priv->card);
326 CsrSdioRelease(priv->sdio);
322 if (csrResult != CSR_RESULT_SUCCESS) { 327 if (csrResult != CSR_RESULT_SUCCESS) {
323 unifi_error(priv, 328 unifi_error(priv,
324 "unifi_putest_start: failed to init UniFi\n"); 329 "unifi_putest_start: failed to init UniFi\n");
@@ -335,7 +340,9 @@ int unifi_putest_stop(unifi_priv_t *priv, unsigned char *arg)
335 CsrResult csrResult; 340 CsrResult csrResult;
336 341
337 /* Application may have stopped the XAPs, but they are needed for reset */ 342 /* Application may have stopped the XAPs, but they are needed for reset */
343 CsrSdioClaim(priv->sdio);
338 csrResult = unifi_start_processors(priv->card); 344 csrResult = unifi_start_processors(priv->card);
345 CsrSdioRelease(priv->sdio);
339 if (csrResult != CSR_RESULT_SUCCESS) { 346 if (csrResult != CSR_RESULT_SUCCESS) {
340 unifi_error(priv, "Failed to start XAPs. Hard reset required.\n"); 347 unifi_error(priv, "Failed to start XAPs. Hard reset required.\n");
341 } 348 }
@@ -428,7 +435,9 @@ int unifi_putest_dl_fw(unifi_priv_t *priv, unsigned char *arg)
428 } 435 }
429 436
430 /* Application may have stopped the XAPs, but they are needed for reset */ 437 /* Application may have stopped the XAPs, but they are needed for reset */
438 CsrSdioClaim(priv->sdio);
431 csrResult = unifi_start_processors(priv->card); 439 csrResult = unifi_start_processors(priv->card);
440 CsrSdioRelease(priv->sdio);
432 if (csrResult != CSR_RESULT_SUCCESS) { 441 if (csrResult != CSR_RESULT_SUCCESS) {
433 unifi_error(priv, "Failed to start XAPs. Hard reset required.\n"); 442 unifi_error(priv, "Failed to start XAPs. Hard reset required.\n");
434 } 443 }
@@ -436,7 +445,9 @@ int unifi_putest_dl_fw(unifi_priv_t *priv, unsigned char *arg)
436 /* Download the f/w. On UF6xxx this will cause the f/w file to convert 445 /* Download the f/w. On UF6xxx this will cause the f/w file to convert
437 * into patch format and download via the ROM boot loader 446 * into patch format and download via the ROM boot loader
438 */ 447 */
448 CsrSdioClaim(priv->sdio);
439 csrResult = unifi_download(priv->card, 0x0c00); 449 csrResult = unifi_download(priv->card, 0x0c00);
450 CsrSdioRelease(priv->sdio);
440 if (csrResult != CSR_RESULT_SUCCESS) { 451 if (csrResult != CSR_RESULT_SUCCESS) {
441 unifi_error(priv, 452 unifi_error(priv,
442 "unifi_putest_dl_fw: failed to download the f/w\n"); 453 "unifi_putest_dl_fw: failed to download the f/w\n");
@@ -504,7 +515,9 @@ int unifi_putest_dl_fw_buff(unifi_priv_t *priv, unsigned char *arg)
504 priv->fw_sta.dl_len = fw_length; 515 priv->fw_sta.dl_len = fw_length;
505 516
506 /* Application may have stopped the XAPs, but they are needed for reset */ 517 /* Application may have stopped the XAPs, but they are needed for reset */
518 CsrSdioClaim(priv->sdio);
507 csrResult = unifi_start_processors(priv->card); 519 csrResult = unifi_start_processors(priv->card);
520 CsrSdioRelease(priv->sdio);
508 if (csrResult != CSR_RESULT_SUCCESS) { 521 if (csrResult != CSR_RESULT_SUCCESS) {
509 unifi_error(priv, "Failed to start XAPs. Hard reset required.\n"); 522 unifi_error(priv, "Failed to start XAPs. Hard reset required.\n");
510 } 523 }
@@ -512,7 +525,9 @@ int unifi_putest_dl_fw_buff(unifi_priv_t *priv, unsigned char *arg)
512 /* Download the f/w. On UF6xxx this will cause the f/w file to convert 525 /* Download the f/w. On UF6xxx this will cause the f/w file to convert
513 * into patch format and download via the ROM boot loader 526 * into patch format and download via the ROM boot loader
514 */ 527 */
528 CsrSdioClaim(priv->sdio);
515 csrResult = unifi_download(priv->card, 0x0c00); 529 csrResult = unifi_download(priv->card, 0x0c00);
530 CsrSdioRelease(priv->sdio);
516 if (csrResult != CSR_RESULT_SUCCESS) { 531 if (csrResult != CSR_RESULT_SUCCESS) {
517 unifi_error(priv, 532 unifi_error(priv,
518 "unifi_putest_dl_fw_buff: failed to download the f/w\n"); 533 "unifi_putest_dl_fw_buff: failed to download the f/w\n");
@@ -581,7 +596,9 @@ int unifi_putest_coredump_prepare(unifi_priv_t *priv, unsigned char *arg)
581 } 596 }
582 597
583 /* Card software reset */ 598 /* Card software reset */
599 CsrSdioClaim(priv->sdio);
584 r = unifi_card_hard_reset(priv->card); 600 r = unifi_card_hard_reset(priv->card);
601 CsrSdioRelease(priv->sdio);
585 if (r != CSR_RESULT_SUCCESS) { 602 if (r != CSR_RESULT_SUCCESS) {
586 unifi_error(priv, "unifi_card_hard_reset() failed %d\n", r); 603 unifi_error(priv, "unifi_card_hard_reset() failed %d\n", r);
587 } 604 }
@@ -599,7 +616,9 @@ int unifi_putest_coredump_prepare(unifi_priv_t *priv, unsigned char *arg)
599 /* Stop the XAPs for coredump. The PUTEST_STOP must be called, e.g. at 616 /* Stop the XAPs for coredump. The PUTEST_STOP must be called, e.g. at
600 * Raw SDIO deinit, to resume them. 617 * Raw SDIO deinit, to resume them.
601 */ 618 */
619 CsrSdioClaim(priv->sdio);
602 r = unifi_card_stop_processor(priv->card, UNIFI_PROC_BOTH); 620 r = unifi_card_stop_processor(priv->card, UNIFI_PROC_BOTH);
621 CsrSdioRelease(priv->sdio);
603 if (r != CSR_RESULT_SUCCESS) { 622 if (r != CSR_RESULT_SUCCESS) {
604 unifi_error(priv, "Failed to stop processors\n"); 623 unifi_error(priv, "Failed to stop processors\n");
605 } 624 }
@@ -646,7 +665,9 @@ int unifi_putest_cmd52_block_read(unifi_priv_t *priv, unsigned char *arg)
646 return -ENOMEM; 665 return -ENOMEM;
647 } 666 }
648 667
668 CsrSdioClaim(priv->sdio);
649 r = unifi_card_readn(priv->card, block_cmd52.addr, block_local_buffer, block_cmd52.length); 669 r = unifi_card_readn(priv->card, block_cmd52.addr, block_local_buffer, block_cmd52.length);
670 CsrSdioRelease(priv->sdio);
650 if (r != CSR_RESULT_SUCCESS) { 671 if (r != CSR_RESULT_SUCCESS) {
651 unifi_error(priv, "cmd52r_block: unifi_readn failed\n"); 672 unifi_error(priv, "cmd52r_block: unifi_readn failed\n");
652 return -EIO; 673 return -EIO;
diff --git a/drivers/staging/csr/sdio_emb.c b/drivers/staging/csr/sdio_emb.c
index f61fdb130e6..b6a7d6f513b 100644
--- a/drivers/staging/csr/sdio_emb.c
+++ b/drivers/staging/csr/sdio_emb.c
@@ -17,6 +17,7 @@
17 */ 17 */
18#include <linux/kmod.h> 18#include <linux/kmod.h>
19#include <linux/init.h> 19#include <linux/init.h>
20#include <linux/suspend.h>
20#include "csr_wifi_hip_unifi.h" 21#include "csr_wifi_hip_unifi.h"
21#include "unifi_priv.h" 22#include "unifi_priv.h"
22 23
@@ -25,7 +26,16 @@
25/* The function driver context, i.e the UniFi Driver */ 26/* The function driver context, i.e the UniFi Driver */
26static CsrSdioFunctionDriver *sdio_func_drv; 27static CsrSdioFunctionDriver *sdio_func_drv;
27 28
29#ifdef CONFIG_PM
30static int uf_sdio_emb_power_event(struct notifier_block *this, unsigned long event, void *ptr);
31#endif
28 32
33/* The Android wakelock is here for completeness. Typically the MMC driver is used
34 * instead of sdioemb, but sdioemb may be used for CSPI.
35 */
36#ifdef ANDROID_BUILD
37struct wake_lock unifi_sdio_wake_lock; /* wakelock to prevent suspend while resuming */
38#endif
29 39
30/* sdioemb driver uses POSIX error codes */ 40/* sdioemb driver uses POSIX error codes */
31static CsrResult 41static CsrResult
@@ -501,6 +511,131 @@ uf_glue_sdio_int_handler(struct sdioemb_dev *fdev)
501 } 511 }
502} 512}
503 513
514#ifdef CONFIG_PM
515
516/*
517 * Power Management notifier
518 */
519struct uf_sdio_emb_pm_notifier
520{
521 struct list_head list;
522
523 CsrSdioFunction *sdio_ctx;
524 struct notifier_block pm_notifier;
525};
526
527/* PM notifier list head */
528static struct uf_sdio_emb_pm_notifier uf_sdio_emb_pm_notifiers = {
529 .sdio_ctx = NULL,
530};
531
532/*
533 * ---------------------------------------------------------------------------
534 * uf_sdio_emb_register_pm_notifier
535 * uf_sdio_emb_unregister_pm_notifier
536 *
537 * Register/unregister for power management events. A list is used to
538 * allow multiple card instances to be supported.
539 *
540 * Arguments:
541 * sdio_ctx - CSR SDIO context to associate PM notifier to
542 *
543 * Returns:
544 * Register function returns NULL on error
545 * ---------------------------------------------------------------------------
546 */
547static struct uf_sdio_emb_pm_notifier *
548uf_sdio_emb_register_pm_notifier(CsrSdioFunction *sdio_ctx)
549{
550 /* Allocate notifier context for this card instance */
551 struct uf_sdio_emb_pm_notifier *notifier_ctx = kmalloc(sizeof(struct uf_sdio_emb_pm_notifier), GFP_KERNEL);
552
553 if (notifier_ctx)
554 {
555 notifier_ctx->sdio_ctx = sdio_ctx;
556 notifier_ctx->pm_notifier.notifier_call = uf_sdio_emb_power_event;
557
558 list_add(&notifier_ctx->list, &uf_sdio_emb_pm_notifiers.list);
559
560 if (register_pm_notifier(&notifier_ctx->pm_notifier)) {
561 printk(KERN_ERR "unifi: register_pm_notifier failed\n");
562 }
563 }
564
565 return notifier_ctx;
566}
567
568static void
569uf_sdio_emb_unregister_pm_notifier(CsrSdioFunction *sdio_ctx)
570{
571 struct uf_sdio_emb_pm_notifier *notifier_ctx;
572 struct list_head *node, *q;
573
574 list_for_each_safe(node, q, &uf_sdio_emb_pm_notifiers.list) {
575 notifier_ctx = list_entry(node, struct uf_sdio_emb_pm_notifier, list);
576
577 /* If it matches, unregister and free the notifier context */
578 if (notifier_ctx && notifier_ctx->sdio_ctx == sdio_ctx)
579 {
580 if (unregister_pm_notifier(&notifier_ctx->pm_notifier)) {
581 printk(KERN_ERR "unifi: unregister_pm_notifier failed\n");
582 }
583
584 /* Remove from list */
585 notifier_ctx->sdio_ctx = NULL;
586 list_del(node);
587 kfree(notifier_ctx);
588 }
589 }
590}
591
592/*
593 * ---------------------------------------------------------------------------
594 * uf_sdio_emb_power_event
595 *
596 * Handler for power management events.
597 *
598 * We need to handle suspend/resume events while the userspace is unsuspended
599 * to allow the SME to run its suspend/resume state machines.
600 *
601 * Arguments:
602 * event event ID
603 *
604 * Returns:
605 * Status of the event handling
606 * ---------------------------------------------------------------------------
607 */
608static int
609uf_sdio_emb_power_event(struct notifier_block *this, unsigned long event, void *ptr)
610{
611 struct uf_sdio_emb_pm_notifier *notifier_ctx = container_of(this,
612 struct uf_sdio_emb_pm_notifier,
613 pm_notifier);
614
615 /* Call the CSR SDIO function driver's suspend/resume method
616 * while the userspace is unsuspended.
617 */
618 switch (event) {
619 case PM_POST_HIBERNATION:
620 case PM_POST_SUSPEND:
621 printk(KERN_INFO "%s:%d resume\n", __FUNCTION__, __LINE__ );
622 if (sdio_func_drv && sdio_func_drv->resume) {
623 sdio_func_drv->resume(notifier_ctx->sdio_ctx);
624 }
625 break;
626
627 case PM_HIBERNATION_PREPARE:
628 case PM_SUSPEND_PREPARE:
629 printk(KERN_INFO "%s:%d suspend\n", __FUNCTION__, __LINE__ );
630 if (sdio_func_drv && sdio_func_drv->suspend) {
631 sdio_func_drv->suspend(notifier_ctx->sdio_ctx);
632 }
633 break;
634 }
635 return NOTIFY_DONE;
636}
637
638#endif /* CONFIG_PM */
504 639
505/* 640/*
506 * --------------------------------------------------------------------------- 641 * ---------------------------------------------------------------------------
@@ -550,16 +685,30 @@ uf_glue_sdio_probe(struct sdioemb_dev *fdev)
550 unifi_trace(NULL, UDBG1, "Setting SDIO bus clock to %d kHz\n", sdio_clock); 685 unifi_trace(NULL, UDBG1, "Setting SDIO bus clock to %d kHz\n", sdio_clock);
551 sdioemb_set_max_bus_freq(fdev, 1000 * sdio_clock); 686 sdioemb_set_max_bus_freq(fdev, 1000 * sdio_clock);
552 687
688#ifdef CONFIG_PM
689 /* Register to get PM events */
690 if (uf_sdio_emb_register_pm_notifier(sdio_ctx) == NULL) {
691 unifi_error(NULL, "%s: Failed to register for PM events\n", __FUNCTION__);
692 }
693#endif
694
553 /* Call the main UniFi driver inserted handler */ 695 /* Call the main UniFi driver inserted handler */
554 if (sdio_func_drv && sdio_func_drv->inserted) { 696 if (sdio_func_drv && sdio_func_drv->inserted) {
555 uf_add_os_device(fdev->slot_id, fdev->os_device); 697 uf_add_os_device(fdev->slot_id, fdev->os_device);
556 sdio_func_drv->inserted(sdio_ctx); 698 sdio_func_drv->inserted(sdio_ctx);
557 } 699 }
558 700
701#ifdef ANDROID_BUILD
702 /* Take the wakelock */
703 unifi_trace(NULL, UDBG1, "emb probe: take wake lock\n");
704 wake_lock(&unifi_sdio_wake_lock);
705#endif
706
559 return 0; 707 return 0;
560} /* uf_glue_sdio_probe() */ 708} /* uf_glue_sdio_probe() */
561 709
562 710
711
563/* 712/*
564 * --------------------------------------------------------------------------- 713 * ---------------------------------------------------------------------------
565 * uf_sdio_remove 714 * uf_sdio_remove
@@ -585,6 +734,11 @@ uf_sdio_remove(struct sdioemb_dev *fdev)
585 sdio_func_drv->removed(sdio_ctx); 734 sdio_func_drv->removed(sdio_ctx);
586 } 735 }
587 736
737#ifdef CONFIG_PM
738 /* Unregister for PM events */
739 uf_sdio_emb_unregister_pm_notifier(sdio_ctx);
740#endif
741
588 kfree(sdio_ctx); 742 kfree(sdio_ctx);
589 743
590} /* uf_sdio_remove */ 744} /* uf_sdio_remove */
@@ -606,14 +760,7 @@ uf_sdio_remove(struct sdioemb_dev *fdev)
606static void 760static void
607uf_glue_sdio_suspend(struct sdioemb_dev *fdev) 761uf_glue_sdio_suspend(struct sdioemb_dev *fdev)
608{ 762{
609 CsrSdioFunction *sdio_ctx = fdev->drv_data; 763 unifi_info(NULL, "Suspending...\n");
610
611 unifi_trace(NULL, UDBG3, "Suspending...\n");
612
613 /* Pass event to UniFi Driver. */
614 if (sdio_func_drv && sdio_func_drv->suspend) {
615 sdio_func_drv->suspend(sdio_ctx);
616 }
617 764
618} /* uf_glue_sdio_suspend() */ 765} /* uf_glue_sdio_suspend() */
619 766
@@ -634,14 +781,13 @@ uf_glue_sdio_suspend(struct sdioemb_dev *fdev)
634static void 781static void
635uf_glue_sdio_resume(struct sdioemb_dev *fdev) 782uf_glue_sdio_resume(struct sdioemb_dev *fdev)
636{ 783{
637 CsrSdioFunction *sdio_ctx = fdev->drv_data; 784 unifi_info(NULL, "Resuming...\n");
638 785
639 unifi_trace(NULL, UDBG3, "Resuming...\n"); 786#ifdef ANDROID_BUILD
787 unifi_trace(NULL, UDBG1, "emb resume: take wakelock\n");
788 wake_lock(&unifi_sdio_wake_lock);
789#endif
640 790
641 /* Pass event to UniFi Driver. */
642 if (sdio_func_drv && sdio_func_drv->resume) {
643 sdio_func_drv->resume(sdio_ctx);
644 }
645} /* uf_glue_sdio_resume() */ 791} /* uf_glue_sdio_resume() */
646 792
647 793
@@ -708,6 +854,15 @@ CsrSdioFunctionDriverRegister(CsrSdioFunctionDriver *sdio_drv)
708 /* Save the registered driver description */ 854 /* Save the registered driver description */
709 sdio_func_drv = sdio_drv; 855 sdio_func_drv = sdio_drv;
710 856
857#ifdef CONFIG_PM
858 /* Initialise PM notifier list */
859 INIT_LIST_HEAD(&uf_sdio_emb_pm_notifiers.list);
860#endif
861
862#ifdef ANDROID_BUILD
863 wake_lock_init(&unifi_sdio_wake_lock, WAKE_LOCK_SUSPEND, "unifi_sdio_work");
864#endif
865
711 /* Register ourself with sdioemb */ 866 /* Register ourself with sdioemb */
712 r = sdioemb_driver_register(&unifi_sdioemb); 867 r = sdioemb_driver_register(&unifi_sdioemb);
713 if (r) { 868 if (r) {
@@ -724,6 +879,10 @@ CsrSdioFunctionDriverUnregister(CsrSdioFunctionDriver *sdio_drv)
724{ 879{
725 sdioemb_driver_unregister(&unifi_sdioemb); 880 sdioemb_driver_unregister(&unifi_sdioemb);
726 881
882#ifdef ANDROID_BUILD
883 wake_lock_destroy(&unifi_sdio_wake_lock);
884#endif
885
727 sdio_func_drv = NULL; 886 sdio_func_drv = NULL;
728 887
729 CsrPmemFree(unifi_sdioemb.id_table); 888 CsrPmemFree(unifi_sdioemb.id_table);
diff --git a/drivers/staging/csr/sdio_events.c b/drivers/staging/csr/sdio_events.c
index e4f2d0d82fb..6892c2e281b 100644
--- a/drivers/staging/csr/sdio_events.c
+++ b/drivers/staging/csr/sdio_events.c
@@ -47,6 +47,12 @@ void unifi_suspend(void *ospriv)
47 unifi_priv_t *priv = ospriv; 47 unifi_priv_t *priv = ospriv;
48 int interfaceTag=0; 48 int interfaceTag=0;
49 49
50 /* For powered suspend, tell the resume's wifi_on() not to reinit UniFi */
51 priv->wol_suspend = (enable_wol == UNIFI_WOL_OFF) ? FALSE : TRUE;
52
53 unifi_trace(priv, UDBG1, "unifi_suspend: wol_suspend %d, enable_wol %d",
54 priv->wol_suspend, enable_wol );
55
50 /* Stop network traffic. */ 56 /* Stop network traffic. */
51 /* need to stop all the netdevices*/ 57 /* need to stop all the netdevices*/
52 for( interfaceTag=0;interfaceTag<CSR_WIFI_NUM_INTERFACES;interfaceTag++) 58 for( interfaceTag=0;interfaceTag<CSR_WIFI_NUM_INTERFACES;interfaceTag++)
@@ -54,11 +60,20 @@ void unifi_suspend(void *ospriv)
54 netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag]; 60 netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
55 if (interfacePriv->netdev_registered == 1) 61 if (interfacePriv->netdev_registered == 1)
56 { 62 {
57 netif_carrier_off(priv->netdev[interfaceTag]); 63 if( priv->wol_suspend ) {
64 unifi_trace(priv, UDBG1, "unifi_suspend: Don't netif_carrier_off");
65 } else {
66 unifi_trace(priv, UDBG1, "unifi_suspend: netif_carrier_off");
67 netif_carrier_off(priv->netdev[interfaceTag]);
68 }
58 UF_NETIF_TX_STOP_ALL_QUEUES(priv->netdev[interfaceTag]); 69 UF_NETIF_TX_STOP_ALL_QUEUES(priv->netdev[interfaceTag]);
59 } 70 }
60 } 71 }
72
73 unifi_trace(priv, UDBG1, "unifi_suspend: suspend SME");
74
61 sme_sys_suspend(priv); 75 sme_sys_suspend(priv);
76
62} /* unifi_suspend() */ 77} /* unifi_suspend() */
63 78
64 79
@@ -76,12 +91,44 @@ void unifi_suspend(void *ospriv)
76void unifi_resume(void *ospriv) 91void unifi_resume(void *ospriv)
77{ 92{
78 unifi_priv_t *priv = ospriv; 93 unifi_priv_t *priv = ospriv;
94 int interfaceTag=0;
79 int r; 95 int r;
96 int wol = priv->wol_suspend;
97
98 unifi_trace(priv, UDBG1, "unifi_resume: resume SME, enable_wol=%d", enable_wol);
80 99
100 /* The resume causes wifi-on which will re-enable the BH and reinstall the ISR */
81 r = sme_sys_resume(priv); 101 r = sme_sys_resume(priv);
82 if (r) { 102 if (r) {
83 unifi_error(priv, "Failed to resume UniFi\n"); 103 unifi_error(priv, "Failed to resume UniFi\n");
84 } 104 }
85 105
106 /* Resume the network interfaces. For the cold resume case, this will
107 * happen upon reconnection.
108 */
109 if (wol) {
110 unifi_trace(priv, UDBG1, "unifi_resume: try to enable carrier");
111
112 /* need to start all the netdevices*/
113 for( interfaceTag=0;interfaceTag<CSR_WIFI_NUM_INTERFACES;interfaceTag++) {
114 netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
115
116 unifi_trace(priv, UDBG1, "unifi_resume: interfaceTag %d netdev_registered %d mode %d\n",
117 interfaceTag, interfacePriv->netdev_registered, interfacePriv->interfaceMode);
118
119 if (interfacePriv->netdev_registered == 1)
120 {
121 netif_carrier_on(priv->netdev[interfaceTag]);
122 UF_NETIF_TX_START_ALL_QUEUES(priv->netdev[interfaceTag]);
123 }
124 }
125
126 /* Kick the BH thread (with reason=host) to poll for data that may have
127 * arrived during a powered suspend. This caters for the case where the SME
128 * doesn't interact with the chip (e.g install autonomous scans) during resume.
129 */
130 unifi_send_signal(priv->card, NULL, 0, NULL);
131 }
132
86} /* unifi_resume() */ 133} /* unifi_resume() */
87 134
diff --git a/drivers/staging/csr/sdio_mmc.c b/drivers/staging/csr/sdio_mmc.c
index c8508341597..24be0872b0a 100644
--- a/drivers/staging/csr/sdio_mmc.c
+++ b/drivers/staging/csr/sdio_mmc.c
@@ -21,19 +21,28 @@
21#include <linux/mmc/sdio_func.h> 21#include <linux/mmc/sdio_func.h>
22#include <linux/mmc/sdio_ids.h> 22#include <linux/mmc/sdio_ids.h>
23#include <linux/mmc/sdio.h> 23#include <linux/mmc/sdio.h>
24#include <linux/suspend.h>
24 25
25#include "unifi_priv.h" 26#include "unifi_priv.h"
26 27
28#ifdef ANDROID_BUILD
29struct wake_lock unifi_sdio_wake_lock; /* wakelock to prevent suspend while resuming */
30#endif
27 31
28static CsrSdioFunctionDriver *sdio_func_drv; 32static CsrSdioFunctionDriver *sdio_func_drv;
29 33
30#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32) 34#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)
35#ifdef CONFIG_PM
36static int uf_sdio_mmc_power_event(struct notifier_block *this, unsigned long event, void *ptr);
37#endif
38
31/* 39/*
32 * We need to keep track of the power on/off because we can not call 40 * We need to keep track of the power on/off because we can not call
33 * mmc_power_restore_host() when the card is already powered. 41 * mmc_power_restore_host() when the card is already powered.
34 * Even then, we need to patch the MMC driver to add a power_restore handler 42 * Even then, we need to patch the MMC driver to add a power_restore handler
35 * in the mmc_sdio_ops structure. If the MMC driver is not patched, 43 * in the mmc_sdio_ops structure. If the MMC driver before 2.6.37 is not patched,
36 * mmc_power_save_host() and mmc_power_restore_host() are no-ops. 44 * mmc_power_save_host() and mmc_power_restore_host() are no-ops in the kernel,
45 * returning immediately (at least on x86).
37 */ 46 */
38static int card_is_powered = 1; 47static int card_is_powered = 1;
39#endif /* 2.6.32 */ 48#endif /* 2.6.32 */
@@ -312,17 +321,28 @@ csr_sdio_enable_hs(struct mmc_card *card)
312 int ret; 321 int ret;
313 u8 speed; 322 u8 speed;
314 323
315 if (!(card->host->caps & MMC_CAP_SD_HIGHSPEED)) 324 if (!(card->host->caps & MMC_CAP_SD_HIGHSPEED)) {
325 /* We've asked for HS clock rates, but controller doesn't
326 * claim to support it. We should limit the clock
327 * to 25MHz via module parameter.
328 */
329 printk(KERN_INFO "unifi: request HS but not MMC_CAP_SD_HIGHSPEED");
316 return 0; 330 return 0;
331 }
317 332
318 if (!card->cccr.high_speed) 333 if (!card->cccr.high_speed)
319 return 0; 334 return 0;
320 335
336#if 1
321 ret = csr_io_rw_direct(card, 0, 0, SDIO_CCCR_SPEED, 0, &speed); 337 ret = csr_io_rw_direct(card, 0, 0, SDIO_CCCR_SPEED, 0, &speed);
322 if (ret) 338 if (ret)
323 return ret; 339 return ret;
324 340
325 speed |= SDIO_SPEED_EHS; 341 speed |= SDIO_SPEED_EHS;
342#else
343 /* Optimisation: Eliminate read by always assuming SHS and that reserved bits can be zero */
344 speed = SDIO_SPEED_EHS | SDIO_SPEED_SHS;
345#endif
326 346
327 ret = csr_io_rw_direct(card, 1, 0, SDIO_CCCR_SPEED, speed, NULL); 347 ret = csr_io_rw_direct(card, 1, 0, SDIO_CCCR_SPEED, speed, NULL);
328 if (ret) 348 if (ret)
@@ -346,12 +366,16 @@ csr_sdio_disable_hs(struct mmc_card *card)
346 366
347 if (!card->cccr.high_speed) 367 if (!card->cccr.high_speed)
348 return 0; 368 return 0;
349 369#if 1
350 ret = csr_io_rw_direct(card, 0, 0, SDIO_CCCR_SPEED, 0, &speed); 370 ret = csr_io_rw_direct(card, 0, 0, SDIO_CCCR_SPEED, 0, &speed);
351 if (ret) 371 if (ret)
352 return ret; 372 return ret;
353 373
354 speed &= ~SDIO_SPEED_EHS; 374 speed &= ~SDIO_SPEED_EHS;
375#else
376 /* Optimisation: Eliminate read by always assuming SHS and that reserved bits can be zero */
377 speed = SDIO_SPEED_SHS; /* clear SDIO_SPEED_EHS */
378#endif
355 379
356 ret = csr_io_rw_direct(card, 1, 0, SDIO_CCCR_SPEED, speed, NULL); 380 ret = csr_io_rw_direct(card, 1, 0, SDIO_CCCR_SPEED, speed, NULL);
357 if (ret) 381 if (ret)
@@ -460,6 +484,7 @@ CsrSdioInterruptEnable(CsrSdioFunction *function)
460 484
461 func_exit(); 485 func_exit();
462 if (err) { 486 if (err) {
487 printk(KERN_ERR "unifi: %s: error %d writing IENx\n", __FUNCTION__, err);
463 return ConvertSdioToCsrSdioResult(err); 488 return ConvertSdioToCsrSdioResult(err);
464 } 489 }
465#endif 490#endif
@@ -486,6 +511,7 @@ CsrSdioInterruptDisable(CsrSdioFunction *function)
486 511
487 func_exit(); 512 func_exit();
488 if (err) { 513 if (err) {
514 printk(KERN_ERR "unifi: %s: error %d writing IENx\n", __FUNCTION__, err);
489 return ConvertSdioToCsrSdioResult(err); 515 return ConvertSdioToCsrSdioResult(err);
490 } 516 }
491#endif 517#endif
@@ -772,6 +798,7 @@ uf_glue_sdio_int_handler(struct sdio_func *func)
772 if (!sdio_ctx) { 798 if (!sdio_ctx) {
773 return; 799 return;
774 } 800 }
801
775#ifndef CSR_CONFIG_MMC_INT_BYPASS_KSOFTIRQD 802#ifndef CSR_CONFIG_MMC_INT_BYPASS_KSOFTIRQD
776 /* 803 /*
777 * Normally, we are not allowed to do any SDIO commands here. 804 * Normally, we are not allowed to do any SDIO commands here.
@@ -785,7 +812,7 @@ uf_glue_sdio_int_handler(struct sdio_func *func)
785 r = csr_io_rw_direct(func->card, 1, 0, SDIO_CCCR_IENx, 0x00, NULL); 812 r = csr_io_rw_direct(func->card, 1, 0, SDIO_CCCR_IENx, 0x00, NULL);
786#endif 813#endif
787 if (r) { 814 if (r) {
788 printk(KERN_ERR "UniFi MMC Int handler: Failed to disable interrupts\n"); 815 printk(KERN_ERR "UniFi MMC Int handler: Failed to disable interrupts %d\n", r);
789 } 816 }
790#endif 817#endif
791 818
@@ -824,6 +851,8 @@ csr_sdio_linux_remove_irq(CsrSdioFunction *function)
824 struct sdio_func *func = (struct sdio_func *)function->priv; 851 struct sdio_func *func = (struct sdio_func *)function->priv;
825 int r; 852 int r;
826 853
854 unifi_trace(NULL, UDBG1, "csr_sdio_linux_remove_irq\n");
855
827 sdio_claim_host(func); 856 sdio_claim_host(func);
828 r = sdio_release_irq(func); 857 r = sdio_release_irq(func);
829 sdio_release_host(func); 858 sdio_release_host(func);
@@ -853,6 +882,8 @@ csr_sdio_linux_install_irq(CsrSdioFunction *function)
853 struct sdio_func *func = (struct sdio_func *)function->priv; 882 struct sdio_func *func = (struct sdio_func *)function->priv;
854 int r; 883 int r;
855 884
885 unifi_trace(NULL, UDBG1, "csr_sdio_linux_install_irq\n");
886
856 /* Register our interrupt handle */ 887 /* Register our interrupt handle */
857 sdio_claim_host(func); 888 sdio_claim_host(func);
858 r = sdio_claim_irq(func, uf_glue_sdio_int_handler); 889 r = sdio_claim_irq(func, uf_glue_sdio_int_handler);
@@ -866,7 +897,133 @@ csr_sdio_linux_install_irq(CsrSdioFunction *function)
866 return r; 897 return r;
867} /* csr_sdio_linux_install_irq() */ 898} /* csr_sdio_linux_install_irq() */
868 899
900#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)
901#ifdef CONFIG_PM
902
903/*
904 * Power Management notifier
905 */
906struct uf_sdio_mmc_pm_notifier
907{
908 struct list_head list;
909
910 CsrSdioFunction *sdio_ctx;
911 struct notifier_block pm_notifier;
912};
913
914/* PM notifier list head */
915static struct uf_sdio_mmc_pm_notifier uf_sdio_mmc_pm_notifiers = {
916 .sdio_ctx = NULL,
917};
918
919/*
920 * ---------------------------------------------------------------------------
921 * uf_sdio_mmc_register_pm_notifier
922 * uf_sdio_mmc_unregister_pm_notifier
923 *
924 * Register/unregister for power management events. A list is used to
925 * allow multiple card instances to be supported.
926 *
927 * Arguments:
928 * sdio_ctx - CSR SDIO context to associate PM notifier to
929 *
930 * Returns:
931 * Register function returns NULL on error
932 * ---------------------------------------------------------------------------
933 */
934static struct uf_sdio_mmc_pm_notifier *
935uf_sdio_mmc_register_pm_notifier(CsrSdioFunction *sdio_ctx)
936{
937 /* Allocate notifier context for this card instance */
938 struct uf_sdio_mmc_pm_notifier *notifier_ctx = kmalloc(sizeof(struct uf_sdio_mmc_pm_notifier), GFP_KERNEL);
939
940 if (notifier_ctx)
941 {
942 notifier_ctx->sdio_ctx = sdio_ctx;
943 notifier_ctx->pm_notifier.notifier_call = uf_sdio_mmc_power_event;
944
945 list_add(&notifier_ctx->list, &uf_sdio_mmc_pm_notifiers.list);
946
947 if (register_pm_notifier(&notifier_ctx->pm_notifier)) {
948 printk(KERN_ERR "unifi: register_pm_notifier failed\n");
949 }
950 }
951
952 return notifier_ctx;
953}
954
955static void
956uf_sdio_mmc_unregister_pm_notifier(CsrSdioFunction *sdio_ctx)
957{
958 struct uf_sdio_mmc_pm_notifier *notifier_ctx;
959 struct list_head *node, *q;
960
961 list_for_each_safe(node, q, &uf_sdio_mmc_pm_notifiers.list) {
962 notifier_ctx = list_entry(node, struct uf_sdio_mmc_pm_notifier, list);
963
964 /* If it matches, unregister and free the notifier context */
965 if (notifier_ctx && notifier_ctx->sdio_ctx == sdio_ctx)
966 {
967 if (unregister_pm_notifier(&notifier_ctx->pm_notifier)) {
968 printk(KERN_ERR "unifi: unregister_pm_notifier failed\n");
969 }
970
971 /* Remove from list */
972 notifier_ctx->sdio_ctx = NULL;
973 list_del(node);
974 kfree(notifier_ctx);
975 }
976 }
977}
978
979/*
980 * ---------------------------------------------------------------------------
981 * uf_sdio_mmc_power_event
982 *
983 * Handler for power management events.
984 *
985 * We need to handle suspend/resume events while the userspace is unsuspended
986 * to allow the SME to run its suspend/resume state machines.
987 *
988 * Arguments:
989 * event event ID
990 *
991 * Returns:
992 * Status of the event handling
993 * ---------------------------------------------------------------------------
994 */
995static int
996uf_sdio_mmc_power_event(struct notifier_block *this, unsigned long event, void *ptr)
997{
998 struct uf_sdio_mmc_pm_notifier *notifier_ctx = container_of(this,
999 struct uf_sdio_mmc_pm_notifier,
1000 pm_notifier);
1001
1002 /* Call the CSR SDIO function driver's suspend/resume method
1003 * while the userspace is unsuspended.
1004 */
1005 switch (event) {
1006 case PM_POST_HIBERNATION:
1007 case PM_POST_SUSPEND:
1008 printk(KERN_INFO "%s:%d resume\n", __FUNCTION__, __LINE__ );
1009 if (sdio_func_drv && sdio_func_drv->resume) {
1010 sdio_func_drv->resume(notifier_ctx->sdio_ctx);
1011 }
1012 break;
1013
1014 case PM_HIBERNATION_PREPARE:
1015 case PM_SUSPEND_PREPARE:
1016 printk(KERN_INFO "%s:%d suspend\n", __FUNCTION__, __LINE__ );
1017 if (sdio_func_drv && sdio_func_drv->suspend) {
1018 sdio_func_drv->suspend(notifier_ctx->sdio_ctx);
1019 }
1020 break;
1021 }
1022 return NOTIFY_DONE;
1023}
869 1024
1025#endif /* CONFIG_PM */
1026#endif /* 2.6.32 */
870 1027
871/* 1028/*
872 * --------------------------------------------------------------------------- 1029 * ---------------------------------------------------------------------------
@@ -925,6 +1082,10 @@ uf_glue_sdio_probe(struct sdio_func *func,
925 sdio_ctx->features |= CSR_SDIO_FEATURE_BYTE_MODE; 1082 sdio_ctx->features |= CSR_SDIO_FEATURE_BYTE_MODE;
926 } 1083 }
927 1084
1085 if (func->card->host->caps & MMC_CAP_SD_HIGHSPEED) {
1086 unifi_trace(NULL, UDBG1, "MMC_CAP_SD_HIGHSPEED is available\n");
1087 }
1088
928#ifdef MMC_QUIRK_LENIENT_FN0 1089#ifdef MMC_QUIRK_LENIENT_FN0
929 func->card->quirks |= MMC_QUIRK_LENIENT_FN0; 1090 func->card->quirks |= MMC_QUIRK_LENIENT_FN0;
930#endif 1091#endif
@@ -932,6 +1093,15 @@ uf_glue_sdio_probe(struct sdio_func *func,
932 /* Pass context to the SDIO driver */ 1093 /* Pass context to the SDIO driver */
933 sdio_set_drvdata(func, sdio_ctx); 1094 sdio_set_drvdata(func, sdio_ctx);
934 1095
1096#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)
1097#ifdef CONFIG_PM
1098 /* Register to get PM events */
1099 if (uf_sdio_mmc_register_pm_notifier(sdio_ctx) == NULL) {
1100 unifi_error(NULL, "%s: Failed to register for PM events\n", __FUNCTION__);
1101 }
1102#endif
1103#endif
1104
935 /* Register this device with the SDIO function driver */ 1105 /* Register this device with the SDIO function driver */
936 /* Call the main UniFi driver inserted handler */ 1106 /* Call the main UniFi driver inserted handler */
937 if (sdio_func_drv && sdio_func_drv->inserted) { 1107 if (sdio_func_drv && sdio_func_drv->inserted) {
@@ -942,6 +1112,12 @@ uf_glue_sdio_probe(struct sdio_func *func,
942 /* We have finished, so release the SDIO driver */ 1112 /* We have finished, so release the SDIO driver */
943 sdio_release_host(func); 1113 sdio_release_host(func);
944 1114
1115#ifdef ANDROID_BUILD
1116 /* Take the wakelock */
1117 unifi_trace(NULL, UDBG1, "probe: take wake lock\n");
1118 wake_lock(&unifi_sdio_wake_lock);
1119#endif
1120
945 func_exit(); 1121 func_exit();
946 return 0; 1122 return 0;
947} /* uf_glue_sdio_probe() */ 1123} /* uf_glue_sdio_probe() */
@@ -980,6 +1156,13 @@ uf_glue_sdio_remove(struct sdio_func *func)
980 sdio_func_drv->removed(sdio_ctx); 1156 sdio_func_drv->removed(sdio_ctx);
981 } 1157 }
982 1158
1159#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)
1160#ifdef CONFIG_PM
1161 /* Unregister for PM events */
1162 uf_sdio_mmc_unregister_pm_notifier(sdio_ctx);
1163#endif
1164#endif
1165
983 kfree(sdio_ctx); 1166 kfree(sdio_ctx);
984 1167
985 func_exit(); 1168 func_exit();
@@ -1006,7 +1189,7 @@ MODULE_DEVICE_TABLE(sdio, unifi_ids);
1006 * --------------------------------------------------------------------------- 1189 * ---------------------------------------------------------------------------
1007 * uf_glue_sdio_suspend 1190 * uf_glue_sdio_suspend
1008 * 1191 *
1009 * Card suspend callback. 1192 * Card suspend callback. The userspace will already be suspended.
1010 * 1193 *
1011 * Arguments: 1194 * Arguments:
1012 * dev The struct device owned by the MMC driver 1195 * dev The struct device owned by the MMC driver
@@ -1018,23 +1201,9 @@ MODULE_DEVICE_TABLE(sdio, unifi_ids);
1018static int 1201static int
1019uf_glue_sdio_suspend(struct device *dev) 1202uf_glue_sdio_suspend(struct device *dev)
1020{ 1203{
1021 struct sdio_func *func;
1022 CsrSdioFunction *sdio_ctx;
1023
1024 func_enter(); 1204 func_enter();
1025 1205
1026 func = dev_to_sdio_func(dev); 1206 unifi_trace(NULL, UDBG1, "uf_glue_sdio_suspend");
1027 WARN_ON(!func);
1028
1029 sdio_ctx = sdio_get_drvdata(func);
1030 WARN_ON(!sdio_ctx);
1031
1032 unifi_trace(NULL, UDBG1, "System Suspend...\n");
1033
1034 /* Clean up the SDIO function driver */
1035 if (sdio_func_drv && sdio_func_drv->suspend) {
1036 sdio_func_drv->suspend(sdio_ctx);
1037 }
1038 1207
1039 func_exit(); 1208 func_exit();
1040 return 0; 1209 return 0;
@@ -1045,7 +1214,7 @@ uf_glue_sdio_suspend(struct device *dev)
1045 * --------------------------------------------------------------------------- 1214 * ---------------------------------------------------------------------------
1046 * uf_glue_sdio_resume 1215 * uf_glue_sdio_resume
1047 * 1216 *
1048 * Card resume callback. 1217 * Card resume callback. The userspace will still be suspended.
1049 * 1218 *
1050 * Arguments: 1219 * Arguments:
1051 * dev The struct device owned by the MMC driver 1220 * dev The struct device owned by the MMC driver
@@ -1057,23 +1226,14 @@ uf_glue_sdio_suspend(struct device *dev)
1057static int 1226static int
1058uf_glue_sdio_resume(struct device *dev) 1227uf_glue_sdio_resume(struct device *dev)
1059{ 1228{
1060 struct sdio_func *func;
1061 CsrSdioFunction *sdio_ctx;
1062
1063 func_enter(); 1229 func_enter();
1064 1230
1065 func = dev_to_sdio_func(dev); 1231 unifi_trace(NULL, UDBG1, "uf_glue_sdio_resume");
1066 WARN_ON(!func);
1067
1068 sdio_ctx = sdio_get_drvdata(func);
1069 WARN_ON(!sdio_ctx);
1070 1232
1071 unifi_trace(NULL, UDBG1, "System Resume...\n"); 1233#ifdef ANDROID_BUILD
1072 1234 unifi_trace(NULL, UDBG1, "resume: take wakelock\n");
1073 /* Clean up the SDIO function driver */ 1235 wake_lock(&unifi_sdio_wake_lock);
1074 if (sdio_func_drv && sdio_func_drv->resume) { 1236#endif
1075 sdio_func_drv->resume(sdio_ctx);
1076 }
1077 1237
1078 func_exit(); 1238 func_exit();
1079 return 0; 1239 return 0;
@@ -1133,6 +1293,10 @@ CsrSdioFunctionDriverRegister(CsrSdioFunctionDriver *sdio_drv)
1133 return CSR_SDIO_RESULT_INVALID_VALUE; 1293 return CSR_SDIO_RESULT_INVALID_VALUE;
1134 } 1294 }
1135 1295
1296#ifdef ANDROID_BUILD
1297 wake_lock_init(&unifi_sdio_wake_lock, WAKE_LOCK_SUSPEND, "unifi_sdio_work");
1298#endif
1299
1136 /* Save the registered driver description */ 1300 /* Save the registered driver description */
1137 /* 1301 /*
1138 * FIXME: 1302 * FIXME:
@@ -1141,6 +1305,13 @@ CsrSdioFunctionDriverRegister(CsrSdioFunctionDriver *sdio_drv)
1141 */ 1305 */
1142 sdio_func_drv = sdio_drv; 1306 sdio_func_drv = sdio_drv;
1143 1307
1308#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)
1309#ifdef CONFIG_PM
1310 /* Initialise PM notifier list */
1311 INIT_LIST_HEAD(&uf_sdio_mmc_pm_notifiers.list);
1312#endif
1313#endif
1314
1144 /* Register ourself with mmc_core */ 1315 /* Register ourself with mmc_core */
1145 r = sdio_register_driver(&unifi_driver); 1316 r = sdio_register_driver(&unifi_driver);
1146 if (r) { 1317 if (r) {
@@ -1157,6 +1328,10 @@ void
1157CsrSdioFunctionDriverUnregister(CsrSdioFunctionDriver *sdio_drv) 1328CsrSdioFunctionDriverUnregister(CsrSdioFunctionDriver *sdio_drv)
1158{ 1329{
1159 printk(KERN_INFO "UniFi: unregister from MMC sdio\n"); 1330 printk(KERN_INFO "UniFi: unregister from MMC sdio\n");
1331
1332#ifdef ANDROID_BUILD
1333 wake_lock_destroy(&unifi_sdio_wake_lock);
1334#endif
1160 sdio_unregister_driver(&unifi_driver); 1335 sdio_unregister_driver(&unifi_driver);
1161 1336
1162 sdio_func_drv = NULL; 1337 sdio_func_drv = NULL;
diff --git a/drivers/staging/csr/sme_blocking.c b/drivers/staging/csr/sme_blocking.c
index f30eda950ad..8461baca2de 100644
--- a/drivers/staging/csr/sme_blocking.c
+++ b/drivers/staging/csr/sme_blocking.c
@@ -92,11 +92,15 @@ sme_init_request(unifi_priv_t *priv)
92 return -EIO; 92 return -EIO;
93 } 93 }
94 94
95 unifi_trace(priv, UDBG5, "sme_init_request: wait sem\n");
96
95 /* Grab the SME semaphore until the reply comes, or timeout */ 97 /* Grab the SME semaphore until the reply comes, or timeout */
96 if (down_interruptible(&priv->sme_sem)) { 98 if (down_interruptible(&priv->sme_sem)) {
97 unifi_error(priv, "sme_init_request: Failed to get SME semaphore\n"); 99 unifi_error(priv, "sme_init_request: Failed to get SME semaphore\n");
98 return -EIO; 100 return -EIO;
99 } 101 }
102 unifi_trace(priv, UDBG5, "sme_init_request: got sem: pending\n");
103
100 priv->sme_reply.request_status = SME_REQUEST_PENDING; 104 priv->sme_reply.request_status = SME_REQUEST_PENDING;
101 105
102 return 0; 106 return 0;
@@ -118,6 +122,10 @@ uf_sme_complete_request(unifi_priv_t *priv, CsrResult reply_status, const char *
118 (func ? func : ""), priv->sme_reply.request_status); 122 (func ? func : ""), priv->sme_reply.request_status);
119 return; 123 return;
120 } 124 }
125 unifi_trace(priv, UDBG5,
126 "sme_complete_request: completed %s (s:%d)\n",
127 (func ? func : ""), priv->sme_reply.request_status);
128
121 priv->sme_reply.request_status = SME_REQUEST_RECEIVED; 129 priv->sme_reply.request_status = SME_REQUEST_RECEIVED;
122 priv->sme_reply.reply_status = reply_status; 130 priv->sme_reply.reply_status = reply_status;
123 131
@@ -127,23 +135,66 @@ uf_sme_complete_request(unifi_priv_t *priv, CsrResult reply_status, const char *
127} 135}
128 136
129 137
138void
139uf_sme_cancel_request(unifi_priv_t *priv, CsrResult reply_status)
140{
141 /* Check for a blocking SME request in progress, and cancel the wait.
142 * This should be used when the character device is closed.
143 */
144
145 if (priv == NULL) {
146 unifi_error(priv, "sme_cancel_request: Invalid priv\n");
147 return;
148 }
149
150 /* If no request is pending, nothing to wake up */
151 if (priv->sme_reply.request_status != SME_REQUEST_PENDING) {
152 unifi_trace(priv, UDBG5,
153 "sme_cancel_request: no request was pending (s:%d)\n",
154 priv->sme_reply.request_status);
155 /* Nothing to do */
156 return;
157 }
158 unifi_trace(priv, UDBG5,
159 "sme_cancel_request: request cancelled (s:%d)\n",
160 priv->sme_reply.request_status);
161
162 /* Wake up the wait with an error status */
163 priv->sme_reply.request_status = SME_REQUEST_CANCELLED;
164 priv->sme_reply.reply_status = reply_status; /* unimportant since the CANCELLED state will fail the ioctl */
165
166 wake_up_interruptible(&priv->sme_request_wq);
167
168 return;
169}
170
171
130static int 172static int
131_sme_wait_for_reply(unifi_priv_t *priv, 173_sme_wait_for_reply(unifi_priv_t *priv,
132 unsigned long timeout, const char *func) 174 unsigned long timeout, const char *func)
133{ 175{
134 long r; 176 long r;
135 177
136 unifi_trace(priv, UDBG5, "sme_wait_for_reply: sleep\n"); 178 unifi_trace(priv, UDBG5, "sme_wait_for_reply: %s sleep\n", func ? func : "");
137 r = wait_event_interruptible_timeout(priv->sme_request_wq, 179 r = wait_event_interruptible_timeout(priv->sme_request_wq,
138 (priv->sme_reply.request_status != SME_REQUEST_PENDING), 180 (priv->sme_reply.request_status != SME_REQUEST_PENDING),
139 msecs_to_jiffies(timeout)); 181 msecs_to_jiffies(timeout));
140 unifi_trace(priv, UDBG5, "sme_wait_for_reply: awake\n"); 182 unifi_trace(priv, UDBG5, "sme_wait_for_reply: %s awake (%d)\n", func ? func : "", r);
141 183
142 if (r == -ERESTARTSYS) { 184 if (r == -ERESTARTSYS) {
143 /* The thread was killed */ 185 /* The thread was killed */
186 unifi_info(priv, "ERESTARTSYS in _sme_wait_for_reply\n");
144 up(&priv->sme_sem); 187 up(&priv->sme_sem);
145 return r; 188 return r;
146 } 189 }
190 if (priv->sme_reply.request_status == SME_REQUEST_CANCELLED) {
191 unifi_trace(priv, UDBG5, "Cancelled waiting for SME to reply (%s s:%d, t:%d, r:%d)\n",
192 (func ? func : ""), priv->sme_reply.request_status, timeout, r);
193
194 /* Release the SME semaphore that was downed in sme_init_request() */
195 up(&priv->sme_sem);
196 return -EIO; /* fail the ioctl */
197 }
147 if ((r == 0) && (priv->sme_reply.request_status != SME_REQUEST_RECEIVED)) { 198 if ((r == 0) && (priv->sme_reply.request_status != SME_REQUEST_RECEIVED)) {
148 unifi_notice(priv, "Timeout waiting for SME to reply (%s s:%d, t:%d)\n", 199 unifi_notice(priv, "Timeout waiting for SME to reply (%s s:%d, t:%d)\n",
149 (func ? func : ""), priv->sme_reply.request_status, timeout); 200 (func ? func : ""), priv->sme_reply.request_status, timeout);
@@ -156,6 +207,9 @@ _sme_wait_for_reply(unifi_priv_t *priv,
156 return -ETIMEDOUT; 207 return -ETIMEDOUT;
157 } 208 }
158 209
210 unifi_trace(priv, UDBG5, "sme_wait_for_reply: %s received (%d)\n",
211 func ? func : "", r);
212
159 /* Release the SME semaphore that was downed in sme_init_request() */ 213 /* Release the SME semaphore that was downed in sme_init_request() */
160 up(&priv->sme_sem); 214 up(&priv->sme_sem);
161 215
@@ -1289,22 +1343,20 @@ int sme_sys_suspend(unifi_priv_t *priv)
1289 return -EIO; 1343 return -EIO;
1290 } 1344 }
1291 1345
1292 /* For powered suspend, tell the resume's wifi_on() not to reinit UniFi */ 1346 /* Suspend the SME, which MAY cause it to power down UniFi */
1293 priv->wol_suspend = (enable_wol == UNIFI_WOL_OFF) ? FALSE : TRUE;
1294
1295 /* Suspend the SME, which will cause it to power down UniFi */
1296 CsrWifiRouterCtrlSuspendIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,0, 0, priv->wol_suspend); 1347 CsrWifiRouterCtrlSuspendIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,0, 0, priv->wol_suspend);
1297 r = sme_wait_for_reply(priv, UNIFI_SME_SYS_LONG_TIMEOUT); 1348 r = sme_wait_for_reply(priv, UNIFI_SME_SYS_LONG_TIMEOUT);
1298 if (r) { 1349 if (r) {
1299 /* No reply - forcibly power down in case the request wasn't processed */ 1350 /* No reply - forcibly power down in case the request wasn't processed */
1300 unifi_notice(priv, 1351 unifi_notice(priv,
1301 "suspend: SME did not reply %s, ", 1352 "suspend: SME did not reply %s, ",
1302 priv->ptest_mode ? "leave powered" : "power off UniFi anyway\n"); 1353 (priv->ptest_mode | priv->wol_suspend) ? "leave powered" : "power off UniFi anyway\n");
1303 1354
1304 /* Leave power on for production test, though */ 1355 /* Leave power on for production test, though */
1305 if (!priv->ptest_mode) { 1356 if (!priv->ptest_mode) {
1306 /* Put UniFi to deep sleep, in case we can not power it off */ 1357 /* Put UniFi to deep sleep, in case we can not power it off */
1307 CsrSdioClaim(priv->sdio); 1358 CsrSdioClaim(priv->sdio);
1359 unifi_trace(priv, UDBG1, "Force deep sleep");
1308 csrResult = unifi_force_low_power_mode(priv->card); 1360 csrResult = unifi_force_low_power_mode(priv->card);
1309 1361
1310 /* For WOL, the UniFi must stay powered */ 1362 /* For WOL, the UniFi must stay powered */
@@ -1319,13 +1371,40 @@ int sme_sys_suspend(unifi_priv_t *priv)
1319 if (priv->wol_suspend) { 1371 if (priv->wol_suspend) {
1320 unifi_trace(priv, UDBG1, "UniFi left powered for WOL\n"); 1372 unifi_trace(priv, UDBG1, "UniFi left powered for WOL\n");
1321 1373
1322 /* For PIO WOL, disable SDIO interrupt to enable PIO mode in the f/w */ 1374 /* Remove the IRQ, which also disables the card SDIO interrupt.
1323 if (enable_wol == UNIFI_WOL_PIO) { 1375 * Disabling the card SDIO interrupt enables the PIO WOL source.
1324 unifi_trace(priv, UDBG1, "Remove IRQ to enable PIO WOL\n"); 1376 * Removal of the of the handler ensures that in both SDIO and PIO cases
1325 if (csr_sdio_linux_remove_irq(priv->sdio)) { 1377 * the card interrupt only wakes the host. The card will be polled
1326 unifi_notice(priv, "WOL csr_sdio_linux_remove_irq failed\n"); 1378 * after resume to handle any pending data.
1379 */
1380 if (csr_sdio_linux_remove_irq(priv->sdio)) {
1381 unifi_notice(priv, "WOL csr_sdio_linux_remove_irq failed\n");
1382 }
1383
1384 if (enable_wol == UNIFI_WOL_SDIO) {
1385 /* Because csr_sdio_linux_remove_irq() disabled the card SDIO interrupt,
1386 * it must be left enabled to wake-on-SDIO.
1387 */
1388 unifi_trace(priv, UDBG1, "Enable card SDIO interrupt for SDIO WOL\n");
1389
1390 CsrSdioClaim(priv->sdio);
1391 csrResult = CsrSdioInterruptEnable(priv->sdio);
1392 CsrSdioRelease(priv->sdio);
1393
1394 if (csrResult != CSR_RESULT_SUCCESS) {
1395 unifi_error(priv, "WOL CsrSdioInterruptEnable failed %d\n", csrResult);
1327 } 1396 }
1397 } else {
1398 unifi_trace(priv, UDBG1, "Disabled card SDIO interrupt for PIO WOL\n");
1328 } 1399 }
1400
1401 /* Prevent the BH thread from running during the suspend.
1402 * Upon resume, sme_sys_resume() will trigger a wifi-on, this will cause
1403 * the BH thread to be re-enabled and reinstall the ISR.
1404 */
1405 priv->bh_thread.block_thread = 1;
1406
1407 unifi_trace(priv, UDBG1, "unifi_suspend: suspended BH");
1329 } 1408 }
1330 1409
1331 /* Consider UniFi to be uninitialised */ 1410 /* Consider UniFi to be uninitialised */
@@ -1354,22 +1433,10 @@ int sme_sys_resume(unifi_priv_t *priv)
1354 1433
1355 CsrWifiRouterCtrlResumeIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,0, priv->wol_suspend); 1434 CsrWifiRouterCtrlResumeIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,0, priv->wol_suspend);
1356 1435
1357 if (priv->ptest_mode == 1) { 1436 r = sme_wait_for_reply(priv, UNIFI_SME_SYS_LONG_TIMEOUT);
1358 r = sme_wait_for_reply(priv, UNIFI_SME_SYS_LONG_TIMEOUT); 1437 if (r) {
1359 if (r) { 1438 unifi_notice(priv,
1360 /* No reply - forcibly power down in case the request wasn't processed */ 1439 "resume: SME did not reply, return success anyway\n");
1361 unifi_notice(priv,
1362 "resume: SME did not reply, return success anyway\n");
1363 }
1364 } else {
1365
1366 /*
1367 * We are not going to wait for the reply because the SME might be in
1368 * the userspace. In this case the event will reach it when the kernel
1369 * resumes. So, release now the SME semaphore that was downed in
1370 * sme_init_request().
1371 */
1372 up(&priv->sme_sem);
1373 } 1440 }
1374 1441
1375 return 0; 1442 return 0;
diff --git a/drivers/staging/csr/sme_sys.c b/drivers/staging/csr/sme_sys.c
index f5760444bfe..da12807434b 100644
--- a/drivers/staging/csr/sme_sys.c
+++ b/drivers/staging/csr/sme_sys.c
@@ -20,6 +20,8 @@
20#ifdef CSR_SUPPORT_WEXT_AP 20#ifdef CSR_SUPPORT_WEXT_AP
21#include "sme_csr/csr_wifi_sme_sef.h" 21#include "sme_csr/csr_wifi_sme_sef.h"
22#endif 22#endif
23
24
23/* 25/*
24 * This file implements the SME SYS API and contains the following functions: 26 * This file implements the SME SYS API and contains the following functions:
25 * CsrWifiRouterCtrlMediaStatusReqHandler() 27 * CsrWifiRouterCtrlMediaStatusReqHandler()
@@ -40,8 +42,10 @@
40 * CsrWifiRouterCtrlTclasDelReqHandler() 42 * CsrWifiRouterCtrlTclasDelReqHandler()
41 * CsrWifiRouterCtrlSetModeReqHandler() 43 * CsrWifiRouterCtrlSetModeReqHandler()
42 * CsrWifiRouterCtrlWapiMulticastFilterReqHandler() 44 * CsrWifiRouterCtrlWapiMulticastFilterReqHandler()
43 * CsrWifiRouterCtrlWapiMulticastReqHandler()
44 * CsrWifiRouterCtrlWapiUnicastFilterReqHandler() 45 * CsrWifiRouterCtrlWapiUnicastFilterReqHandler()
46 * CsrWifiRouterCtrlWapiUnicastTxPktReqHandler()
47 * CsrWifiRouterCtrlWapiRxPktReqHandler()
48 * CsrWifiRouterCtrlWapiFilterReqHandler()
45 */ 49 */
46 50
47#ifdef CSR_SUPPORT_SME 51#ifdef CSR_SUPPORT_SME
@@ -731,10 +735,31 @@ void CsrWifiRouterCtrlWifiOnReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
731 if (priv == NULL) { 735 if (priv == NULL) {
732 return; 736 return;
733 } 737 }
734 for (i=0; i<CSR_WIFI_NUM_INTERFACES; i++) { 738 if( priv->wol_suspend ) {
735 priv->interfacePriv[i]->interfaceMode = 0; 739 unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWifiOnReqHandler: Don't reset mode\n");
740 } else {
741#ifdef ANDROID_BUILD
742 /* Take the wakelock while Wi-Fi On is in progress */
743 unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWifiOnReqHandler: take wake lock\n");
744 wake_lock(&unifi_sdio_wake_lock);
745#endif
746 for (i=0; i<CSR_WIFI_NUM_INTERFACES; i++) {
747 unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWifiOnReqHandler: Setting interface %d to NONE\n", i );
748
749 priv->interfacePriv[i]->interfaceMode = 0;
750 }
751 }
752 unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWifiOnReqHandler(0x%.4X) req->dataLength=%d req->data=0x%x\n", msg->source, req->dataLength, req->data);
753
754 if(req->dataLength==3 && req->data && req->data[0]==0 && req->data[1]==1 && req->data[2]==1)
755 {
756 priv->cmanrTestMode = TRUE;
757 unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWifiOnReqHandler: cmanrTestMode=%d\n", priv->cmanrTestMode);
758 }
759 else
760 {
761 priv->cmanrTestMode = FALSE;
736 } 762 }
737 unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWifiOnReqHandler(0x%.4X)\n", msg->source);
738 763
739 /* 764 /*
740 * The request to initialise UniFi might come while UniFi is running. 765 * The request to initialise UniFi might come while UniFi is running.
@@ -747,11 +772,16 @@ void CsrWifiRouterCtrlWifiOnReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
747 /* Update the wifi_on state */ 772 /* Update the wifi_on state */
748 priv->wifi_on_state = wifi_on_in_progress; 773 priv->wifi_on_state = wifi_on_in_progress;
749 774
750 r = uf_request_firmware_files(priv, UNIFI_FW_STA); 775 /* If UniFi was unpowered, acquire the firmware for download to chip */
751 if (r) { 776 if (!priv->wol_suspend) {
752 unifi_error(priv, "CsrWifiRouterCtrlWifiOnReqHandler: Failed to get f/w\n"); 777 r = uf_request_firmware_files(priv, UNIFI_FW_STA);
753 CsrWifiRouterCtrlWifiOnCfmSend(msg->source, req->clientData, CSR_RESULT_FAILURE); 778 if (r) {
754 return; 779 unifi_error(priv, "CsrWifiRouterCtrlWifiOnReqHandler: Failed to get f/w\n");
780 CsrWifiRouterCtrlWifiOnCfmSend(msg->source, req->clientData, CSR_RESULT_FAILURE);
781 return;
782 }
783 } else {
784 unifi_trace(priv, UDBG1, "Don't need firmware\n");
755 } 785 }
756 786
757 /* Power on UniFi (which may not necessarily have been off) */ 787 /* Power on UniFi (which may not necessarily have been off) */
@@ -832,6 +862,13 @@ wifi_off(unifi_priv_t *priv)
832 int i; 862 int i;
833 CsrResult csrResult; 863 CsrResult csrResult;
834 864
865
866 /* Already off? */
867 if (priv->wifi_on_state == wifi_on_unspecified) {
868 unifi_trace(priv, UDBG1, "wifi_off already\n");
869 return;
870 }
871
835 unifi_trace(priv, UDBG1, "wifi_off\n"); 872 unifi_trace(priv, UDBG1, "wifi_off\n");
836 873
837 /* Destroy the Traffic Analysis Module */ 874 /* Destroy the Traffic Analysis Module */
@@ -840,6 +877,7 @@ wifi_off(unifi_priv_t *priv)
840 cancel_work_sync(&priv->ta_sample_ind_work.task); 877 cancel_work_sync(&priv->ta_sample_ind_work.task);
841#ifdef CSR_SUPPORT_WEXT 878#ifdef CSR_SUPPORT_WEXT
842 cancel_work_sync(&priv->sme_config_task); 879 cancel_work_sync(&priv->sme_config_task);
880 wext_send_disassoc_event(priv);
843#endif 881#endif
844 882
845 /* Cancel pending M4 stuff */ 883 /* Cancel pending M4 stuff */
@@ -908,9 +946,6 @@ void CsrWifiRouterCtrlWifiOffReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
908 unifi_priv_t *priv = (unifi_priv_t*)drvpriv; 946 unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
909 CsrWifiRouterCtrlWifiOffReq* req = (CsrWifiRouterCtrlWifiOffReq*)msg; 947 CsrWifiRouterCtrlWifiOffReq* req = (CsrWifiRouterCtrlWifiOffReq*)msg;
910 int i = 0; 948 int i = 0;
911#ifdef CSR_SUPPORT_WEXT_AP
912 CsrWifiSmeWifiOffCfm cfm;
913#endif
914 949
915 if (priv == NULL) { 950 if (priv == NULL) {
916 return; 951 return;
@@ -924,6 +959,7 @@ void CsrWifiRouterCtrlWifiOffReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
924 if (interfacePriv->netdev_registered == 1) { 959 if (interfacePriv->netdev_registered == 1) {
925 netif_carrier_off(priv->netdev[i]); 960 netif_carrier_off(priv->netdev[i]);
926 UF_NETIF_TX_STOP_ALL_QUEUES(priv->netdev[i]); 961 UF_NETIF_TX_STOP_ALL_QUEUES(priv->netdev[i]);
962 interfacePriv->connected = UnifiConnectedUnknown;
927 } 963 }
928 interfacePriv->interfaceMode = 0; 964 interfacePriv->interfaceMode = 0;
929 965
@@ -936,15 +972,11 @@ void CsrWifiRouterCtrlWifiOffReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
936 wifi_off(priv); 972 wifi_off(priv);
937 973
938 CsrWifiRouterCtrlWifiOffCfmSend(msg->source,req->clientData); 974 CsrWifiRouterCtrlWifiOffCfmSend(msg->source,req->clientData);
939#ifdef CSR_SUPPORT_WEXT_AP 975
940 /* Router is turned off when WifiOffCfm is received 976 /* If this is called in response to closing the character device, the
941 * hence for wext we don't see WifiOffCfm in the wext 977 * caller must use uf_sme_cancel_request() to terminate any pending SME
942 * files. So just tell the waiting process that 978 * blocking request or there will be a delay while the operation times out.
943 * Wifi off is successful
944 */ 979 */
945 cfm.status = CSR_RESULT_SUCCESS;
946 CsrWifiSmeWifiOffCfmHandler(priv,(CsrWifiFsmEvent*)(&cfm));
947#endif
948} 980}
949 981
950 982
@@ -1065,7 +1097,9 @@ void CsrWifiRouterCtrlWifiOnResHandler(void* drvpriv, CsrWifiFsmEvent* msg)
1065 { 1097 {
1066 int i; /* used as a loop counter */ 1098 int i; /* used as a loop counter */
1067 CsrUint32 intmode = CSR_WIFI_INTMODE_DEFAULT; 1099 CsrUint32 intmode = CSR_WIFI_INTMODE_DEFAULT;
1068 1100#ifdef CSR_WIFI_SPLIT_PATCH
1101 CsrBool switching_ap_fw = FALSE;
1102#endif
1069 /* Register the UniFi device with the OS network manager */ 1103 /* Register the UniFi device with the OS network manager */
1070 unifi_trace(priv, UDBG3, "Card Init Completed Successfully\n"); 1104 unifi_trace(priv, UDBG3, "Card Init Completed Successfully\n");
1071 1105
@@ -1099,6 +1133,16 @@ void CsrWifiRouterCtrlWifiOnResHandler(void* drvpriv, CsrWifiFsmEvent* msg)
1099 return; 1133 return;
1100 } 1134 }
1101 } 1135 }
1136#ifdef CSR_WIFI_SPLIT_PATCH
1137 else
1138 {
1139 /* If a netdev is already registered, we have received this WifiOnRes
1140 * in response to switching AP/STA firmware in a ModeSetReq.
1141 * Rememeber this in order to send a ModeSetCfm once
1142 */
1143 switching_ap_fw = TRUE;
1144 }
1145#endif
1102 } 1146 }
1103 priv->totalInterfaceCount = res->numInterfaceAddress; 1147 priv->totalInterfaceCount = res->numInterfaceAddress;
1104 1148
@@ -1117,8 +1161,27 @@ void CsrWifiRouterCtrlWifiOnResHandler(void* drvpriv, CsrWifiFsmEvent* msg)
1117 /* Acknowledge the CsrWifiRouterCtrlWifiOnReq now */ 1161 /* Acknowledge the CsrWifiRouterCtrlWifiOnReq now */
1118 CsrWifiRouterCtrlWifiOnCfmSend(msg->source, res->clientData, CSR_RESULT_SUCCESS); 1162 CsrWifiRouterCtrlWifiOnCfmSend(msg->source, res->clientData, CSR_RESULT_SUCCESS);
1119 1163
1164#ifdef CSR_WIFI_SPLIT_PATCH
1165 if (switching_ap_fw && (priv->pending_mode_set.common.destination != 0xaaaa)) {
1166 unifi_info(priv, "Completed firmware reload with %s patch\n",
1167 CSR_WIFI_HIP_IS_AP_FW(priv->interfacePriv[0]->interfaceMode) ? "AP" : "STA");
1168
1169 /* Confirm the ModeSetReq that requested the AP/STA patch switch */
1170 CsrWifiRouterCtrlModeSetCfmSend(priv->pending_mode_set.common.source,
1171 priv->pending_mode_set.clientData,
1172 priv->pending_mode_set.interfaceTag,
1173 priv->pending_mode_set.mode,
1174 CSR_RESULT_SUCCESS);
1175 priv->pending_mode_set.common.destination = 0xaaaa;
1176 }
1177#endif
1120 unifi_info(priv, "UniFi ready\n"); 1178 unifi_info(priv, "UniFi ready\n");
1121 1179
1180#ifdef ANDROID_BUILD
1181 /* Release the wakelock */
1182 unifi_trace(priv, UDBG1, "ready: release wake lock\n");
1183 wake_unlock(&unifi_sdio_wake_lock);
1184#endif
1122 /* Firmware initialisation is complete, so let the SDIO bus 1185 /* Firmware initialisation is complete, so let the SDIO bus
1123 * clock be raised when convienent to the core. 1186 * clock be raised when convienent to the core.
1124 */ 1187 */
@@ -1257,15 +1320,7 @@ void CsrWifiRouterCtrlResumeResHandler(void* drvpriv, CsrWifiFsmEvent* msg)
1257 return; 1320 return;
1258 } 1321 }
1259 1322
1260 /* 1323 sme_complete_request(priv, res->status);
1261 * Unless we are in ptest mode, nothing is waiting for the response.
1262 * Do not call sme_complete_request(), otherwise the driver
1263 * and the SME will be out of step.
1264 */
1265 if (priv->ptest_mode == 1) {
1266 sme_complete_request(priv, res->status);
1267 }
1268
1269} 1324}
1270 1325
1271 1326
@@ -1709,7 +1764,6 @@ void CsrWifiRouterCtrlInterfaceReset(unifi_priv_t *priv, CsrUint16 interfaceTag)
1709 &(interfacePriv->genericMulticastOrBroadCastFrames)); 1764 &(interfacePriv->genericMulticastOrBroadCastFrames));
1710 1765
1711 uf_flush_list(priv,&(interfacePriv->genericMulticastOrBroadCastFrames)); 1766 uf_flush_list(priv,&(interfacePriv->genericMulticastOrBroadCastFrames));
1712 uf_flush_maPktlist(priv,&(interfacePriv->directedMaPktReq));
1713 1767
1714 /* process the list of frames that requested cfm 1768 /* process the list of frames that requested cfm
1715 and send cfm to requestor one by one */ 1769 and send cfm to requestor one by one */
@@ -1747,21 +1801,93 @@ void CsrWifiRouterCtrlModeSetReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
1747 if (req->interfaceTag < CSR_WIFI_NUM_INTERFACES) 1801 if (req->interfaceTag < CSR_WIFI_NUM_INTERFACES)
1748 { 1802 {
1749 netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag]; 1803 netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag];
1750 1804#ifdef CSR_WIFI_SPLIT_PATCH
1805 CsrUint8 old_mode = interfacePriv->interfaceMode;
1806#endif
1751 unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlModeSetReqHandler: interfacePriv->interfaceMode = %d\n", 1807 unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlModeSetReqHandler: interfacePriv->interfaceMode = %d\n",
1752 interfacePriv->interfaceMode); 1808 interfacePriv->interfaceMode);
1753 1809
1754 /* Cleanup the database first for current existing mode, Then take 1810 interfacePriv->interfaceMode = req->mode;
1755 * care of setting the new mode (Transition seq: AnyMode->NoneMode->newMode) 1811
1756 * So for Every mode changes, Database Initialization/cleanup needed 1812#ifdef CSR_WIFI_SPLIT_PATCH
1813 /* Detect a change in mode that requires a switch to/from the AP firmware patch.
1814 * This should only happen when transitioning in/out of AP modes.
1757 */ 1815 */
1758 CsrWifiRouterCtrlInterfaceReset(priv,req->interfaceTag); 1816 if (CSR_WIFI_HIP_IS_AP_FW(req->mode) != CSR_WIFI_HIP_IS_AP_FW(old_mode))
1817 {
1818 CsrWifiRouterCtrlVersions versions;
1819 int r;
1820
1821#ifdef ANDROID_BUILD
1822 /* Take the wakelock while switching patch */
1823 unifi_trace(priv, UDBG1, "patch switch: take wake lock\n");
1824 wake_lock(&unifi_sdio_wake_lock);
1825#endif
1826 unifi_info(priv, "Resetting UniFi with %s patch\n", CSR_WIFI_HIP_IS_AP_FW(req->mode) ? "AP" : "STA");
1827
1828 r = uf_request_firmware_files(priv, UNIFI_FW_STA);
1829 if (r) {
1830 unifi_error(priv, "CsrWifiRouterCtrlModeSetReqHandler: Failed to get f/w\n");
1831 CsrWifiRouterCtrlModeSetCfmSend(msg->source, req->clientData, req->interfaceTag,
1832 req->mode, CSR_RESULT_FAILURE);
1833 return;
1834 }
1835
1836 /* Block the I/O thread */
1837 priv->bh_thread.block_thread = 1;
1838
1839 /* Reset and download the new patch */
1840 r = uf_init_hw(priv);
1841 if (r) {
1842 unifi_error(priv, "CsrWifiRouterCtrlWifiOnReqHandler: Failed to initialise h/w, error %d\n", r);
1843 CsrWifiRouterCtrlModeSetCfmSend(msg->source, req->clientData, req->interfaceTag,
1844 req->mode, CSR_RESULT_FAILURE);
1845 return;
1846 }
1847
1848 /* Re-enable the I/O thread */
1849 priv->bh_thread.block_thread = 0;
1850
1851 /* Get the version information from the core */
1852 unifi_card_info(priv->card, &priv->card_info);
1853
1854 /* Copy to the unifiio_card_info structure. */
1855 versions.chipId = priv->card_info.chip_id;
1856 versions.chipVersion = priv->card_info.chip_version;
1857 versions.firmwareBuild = priv->card_info.fw_build;
1858 versions.firmwareHip = priv->card_info.fw_hip_version;
1859 versions.routerBuild = (CsrCharString*)CSR_WIFI_VERSION;
1860 versions.routerHip = (UNIFI_HIP_MAJOR_VERSION << 8) | UNIFI_HIP_MINOR_VERSION;
1861
1862 /* Now that new firmware is running, send a WifiOnInd to the NME. This will
1863 * cause it to retransfer the MIB.
1864 */
1865 CsrWifiRouterCtrlWifiOnIndSend(msg->source, 0, CSR_RESULT_SUCCESS, versions);
1866
1867 /* Store the request so we know where to send the ModeSetCfm */
1868 priv->pending_mode_set = *req;
1869 }
1870 else
1871#endif
1872 {
1873 /* No patch switch, confirm straightaway */
1874 CsrWifiRouterCtrlModeSetCfmSend(msg->source, req->clientData, req->interfaceTag,
1875 req->mode, CSR_RESULT_SUCCESS);
1876 }
1759 1877
1760 interfacePriv->interfaceMode = req->mode;
1761 interfacePriv->bssid = req->bssid; 1878 interfacePriv->bssid = req->bssid;
1762 /* For modes other than AP/P2PGO, set below member FALSE */ 1879 /* For modes other than AP/P2PGO, set below member FALSE */
1763 interfacePriv->intraBssEnabled = FALSE; 1880 interfacePriv->intraBssEnabled = FALSE;
1764 1881 /* Initialise the variable bcTimSet with a value
1882 * other then CSR_WIFI_TIM_SET or CSR_WIFI_TIM_RESET value
1883 */
1884 interfacePriv->bcTimSet = 0xFF;
1885 interfacePriv->bcTimSetReqPendingFlag = FALSE;
1886 /* Initialise the variable bcTimSetReqQueued with a value
1887 * other then CSR_WIFI_TIM_SET or CSR_WIFI_TIM_RESET value
1888 */
1889 interfacePriv->bcTimSetReqQueued =0xFF;
1890 CsrWifiRouterCtrlInterfaceReset(priv,req->interfaceTag);
1765 1891
1766 if(req->mode == CSR_WIFI_ROUTER_CTRL_MODE_AP || 1892 if(req->mode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
1767 req->mode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) { 1893 req->mode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
@@ -1797,8 +1923,6 @@ static int peer_delete_record(unifi_priv_t *priv, CsrWifiRouterCtrlPeerDelReq *r
1797 unifi_port_config_t *controlledPort; 1923 unifi_port_config_t *controlledPort;
1798 unifi_port_config_t *unControlledPort; 1924 unifi_port_config_t *unControlledPort;
1799 netInterface_priv_t *interfacePriv; 1925 netInterface_priv_t *interfacePriv;
1800 maPktReqList_t *maPktreq;
1801 struct list_head *listHeadMaPktreq,*placeHolderMaPktreq;
1802 1926
1803 CsrUint8 ba_session_idx = 0; 1927 CsrUint8 ba_session_idx = 0;
1804 ba_session_rx_struct *ba_session_rx = NULL; 1928 ba_session_rx_struct *ba_session_rx = NULL;
@@ -1832,21 +1956,6 @@ static int peer_delete_record(unifi_priv_t *priv, CsrWifiRouterCtrlPeerDelReq *r
1832 uf_flush_list(priv,&(staInfo->dataPdu[j])); 1956 uf_flush_list(priv,&(staInfo->dataPdu[j]));
1833 } 1957 }
1834 1958
1835 /* There may be race condition
1836 before getting the ma_packet_cfm from f/w, driver may receive peer del from SME
1837 */
1838 spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
1839 list_for_each_safe(listHeadMaPktreq, placeHolderMaPktreq, &interfacePriv->directedMaPktReq) {
1840 maPktreq = list_entry(listHeadMaPktreq, maPktReqList_t, q);
1841 if(maPktreq->staHandler== staInfo->assignedHandle){
1842 dev_kfree_skb(maPktreq->skb);
1843 list_del(listHeadMaPktreq);
1844 kfree(maPktreq);
1845 }
1846
1847 }
1848 spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
1849
1850 spin_lock_irqsave(&priv->staRecord_lock,lock_flags); 1959 spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
1851 /* clear the port configure array info, for the corresponding peer entry */ 1960 /* clear the port configure array info, for the corresponding peer entry */
1852 controlledPort = &interfacePriv->controlled_data_port; 1961 controlledPort = &interfacePriv->controlled_data_port;
@@ -1885,7 +1994,7 @@ static int peer_delete_record(unifi_priv_t *priv, CsrWifiRouterCtrlPeerDelReq *r
1885 /* Stop BA session if it is active, for this peer address all BA sessions 1994 /* Stop BA session if it is active, for this peer address all BA sessions
1886 (per tID per role) are closed */ 1995 (per tID per role) are closed */
1887 1996
1888 spin_lock(&priv->ba_lock); 1997 down(&priv->ba_mutex);
1889 for(ba_session_idx=0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_RX; ba_session_idx++){ 1998 for(ba_session_idx=0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_RX; ba_session_idx++){
1890 ba_session_rx = priv->interfacePriv[req->interfaceTag]->ba_session_rx[ba_session_idx]; 1999 ba_session_rx = priv->interfacePriv[req->interfaceTag]->ba_session_rx[ba_session_idx];
1891 if(ba_session_rx) { 2000 if(ba_session_rx) {
@@ -1912,7 +2021,7 @@ static int peer_delete_record(unifi_priv_t *priv, CsrWifiRouterCtrlPeerDelReq *r
1912 } 2021 }
1913 } 2022 }
1914 2023
1915 spin_unlock(&priv->ba_lock); 2024 up(&priv->ba_mutex);
1916 2025
1917#ifdef CSR_SUPPORT_SME 2026#ifdef CSR_SUPPORT_SME
1918 unifi_trace(priv, UDBG1, "Canceling work queue for STA with AID: %d\n", staInfo->aid); 2027 unifi_trace(priv, UDBG1, "Canceling work queue for STA with AID: %d\n", staInfo->aid);
@@ -2134,8 +2243,16 @@ static int peer_add_new_record(unifi_priv_t *priv,CsrWifiRouterCtrlPeerAddReq *r
2134 newRecord->txSuspend = FALSE; 2243 newRecord->txSuspend = FALSE;
2135 2244
2136 /*U-APSD related data structure*/ 2245 /*U-APSD related data structure*/
2246 newRecord->timRequestPendingFlag = FALSE;
2247
2248 /* Initialise the variable updateTimReqQueued with a value
2249 * other then CSR_WIFI_TIM_SET or CSR_WIFI_TIM_RESET value
2250 */
2251 newRecord->updateTimReqQueued = 0xFF;
2252 newRecord->timSet = CSR_WIFI_TIM_RESET;
2137 newRecord->uapsdActive = FALSE; 2253 newRecord->uapsdActive = FALSE;
2138 newRecord->noOfSpFramesSent =0; 2254 newRecord->noOfSpFramesSent =0;
2255 newRecord->triggerFramePriority = CSR_QOS_UP0;
2139 2256
2140 /* The protection bit is updated once the port opens for corresponding peer in 2257 /* The protection bit is updated once the port opens for corresponding peer in
2141 * routerPortConfigure request */ 2258 * routerPortConfigure request */
@@ -2602,13 +2719,13 @@ void CsrWifiRouterCtrlBlockAckDisableReqHandler(void* drvpriv, CsrWifiFsmEvent*
2602 2719
2603 unifi_trace(priv, UDBG6, "%s: in ok\n", __FUNCTION__); 2720 unifi_trace(priv, UDBG6, "%s: in ok\n", __FUNCTION__);
2604 2721
2605 spin_lock(&priv->ba_lock); 2722 down(&priv->ba_mutex);
2606 r = blockack_session_stop(priv, 2723 r = blockack_session_stop(priv,
2607 req->interfaceTag, 2724 req->interfaceTag,
2608 req->role, 2725 req->role,
2609 req->trafficStreamID, 2726 req->trafficStreamID,
2610 req->macAddress); 2727 req->macAddress);
2611 spin_unlock(&priv->ba_lock); 2728 up(&priv->ba_mutex);
2612 2729
2613 CsrWifiRouterCtrlBlockAckDisableCfmSend(msg->source, 2730 CsrWifiRouterCtrlBlockAckDisableCfmSend(msg->source,
2614 req->clientData, 2731 req->clientData,
@@ -2746,6 +2863,16 @@ CsrBool blockack_session_start(unifi_priv_t *priv,
2746 init_timer(&ba_session_rx->timer); 2863 init_timer(&ba_session_rx->timer);
2747 mod_timer(&ba_session_rx->timer, (jiffies + usecs_to_jiffies((ba_session_rx->timeout) * 1024))); 2864 mod_timer(&ba_session_rx->timer, (jiffies + usecs_to_jiffies((ba_session_rx->timeout) * 1024)));
2748 } 2865 }
2866 /*
2867 * The starting sequence number shall remain same if the BA
2868 * enable request is issued to update BA parameters only. If
2869 * it is not same, then we scroll our window to the new starting
2870 * sequence number. This could happen if the DELBA frame from
2871 * originator is lost and then we receive ADDBA frame with new SSN.
2872 */
2873 if(ba_session_rx->start_sn != start_sn) {
2874 scroll_ba_window(priv, interfacePriv, ba_session_rx, start_sn);
2875 }
2749 return TRUE; 2876 return TRUE;
2750 } 2877 }
2751 } 2878 }
@@ -2768,6 +2895,21 @@ CsrBool blockack_session_start(unifi_priv_t *priv,
2768 return FALSE; 2895 return FALSE;
2769 } 2896 }
2770 2897
2898 /* It is observed that with some devices there is a race between
2899 * EAPOL exchanges and BA session establishment. This results in
2900 * some EAPOL authentication packets getting stuck in BA reorder
2901 * buffer and hence the conection cannot be established. To avoid
2902 * this we check here if the EAPOL authentication is complete and
2903 * if so then only allow the BA session to establish.
2904 *
2905 * It is verified that the peers normally re-establish
2906 * the BA session after the initial rejection.
2907 */
2908 if (CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN != uf_sme_port_state(priv, macAddress.a, UF_CONTROLLED_PORT_Q, interfacePriv->InterfaceTag))
2909 {
2910 unifi_warning(priv, "blockack_session_start: Controlled port not opened, Reject BA request\n");
2911 return FALSE;
2912 }
2771 2913
2772 ba_session_rx = kmalloc(sizeof(ba_session_rx_struct), GFP_KERNEL); 2914 ba_session_rx = kmalloc(sizeof(ba_session_rx_struct), GFP_KERNEL);
2773 if (!ba_session_rx) { 2915 if (!ba_session_rx) {
@@ -2814,7 +2956,7 @@ void CsrWifiRouterCtrlBlockAckEnableReqHandler(void* drvpriv, CsrWifiFsmEvent* m
2814 unifi_priv_t *priv = (unifi_priv_t*)drvpriv; 2956 unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
2815 2957
2816 unifi_trace(priv, UDBG6, ">>%s\n", __FUNCTION__); 2958 unifi_trace(priv, UDBG6, ">>%s\n", __FUNCTION__);
2817 spin_lock(&priv->ba_lock); 2959 down(&priv->ba_mutex);
2818 r = blockack_session_start(priv, 2960 r = blockack_session_start(priv,
2819 req->interfaceTag, 2961 req->interfaceTag,
2820 req->trafficStreamID, 2962 req->trafficStreamID,
@@ -2824,7 +2966,7 @@ void CsrWifiRouterCtrlBlockAckEnableReqHandler(void* drvpriv, CsrWifiFsmEvent* m
2824 req->ssn, 2966 req->ssn,
2825 req->macAddress 2967 req->macAddress
2826 ); 2968 );
2827 spin_unlock(&priv->ba_lock); 2969 up(&priv->ba_mutex);
2828 2970
2829 CsrWifiRouterCtrlBlockAckEnableCfmSend(msg->source, 2971 CsrWifiRouterCtrlBlockAckEnableCfmSend(msg->source,
2830 req->clientData, 2972 req->clientData,
@@ -2836,115 +2978,291 @@ void CsrWifiRouterCtrlBlockAckEnableReqHandler(void* drvpriv, CsrWifiFsmEvent* m
2836 2978
2837void CsrWifiRouterCtrlWapiMulticastFilterReqHandler(void* drvpriv, CsrWifiFsmEvent* msg) 2979void CsrWifiRouterCtrlWapiMulticastFilterReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
2838{ 2980{
2981#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
2982
2839 unifi_priv_t *priv = (unifi_priv_t*)drvpriv; 2983 unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
2840 CsrWifiRouterCtrlWapiMulticastFilterReq* req = (CsrWifiRouterCtrlWapiMulticastFilterReq*)msg; 2984 CsrWifiRouterCtrlWapiMulticastFilterReq* req = (CsrWifiRouterCtrlWapiMulticastFilterReq*)msg;
2985 netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag];
2841 2986
2842 unifi_trace(priv, UDBG6, ">>%s\n", __FUNCTION__); 2987 if (CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode) {
2843 unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWapiMulticastFilterReq: req->status = %d\n", req->status); 2988
2989 unifi_trace(priv, UDBG6, ">>%s\n", __FUNCTION__);
2990
2991 unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWapiMulticastFilterReq: req->status = %d\n", req->status);
2992
2993 /* status 1 - Filter on
2994 * status 0 - Filter off */
2995 priv->wapi_multicast_filter = req->status;
2996
2997 unifi_trace(priv, UDBG6, "<<%s\n", __FUNCTION__);
2998 } else {
2844 2999
2845 /* status 1 - Filter on 3000 unifi_warning(priv, "%s is NOT applicable for interface mode - %d\n", __FUNCTION__,interfacePriv->interfaceMode);
2846 * status 0 - Filter off */
2847 priv->wapi_multicast_filter = req->status;
2848 3001
2849 unifi_trace(priv, UDBG6, "<<%s\n", __FUNCTION__); 3002 }
3003#elif defined(UNIFI_DEBUG)
3004 /*WAPI Disabled*/
3005 unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
3006 unifi_error(priv,"CsrWifiRouterCtrlWapiMulticastFilterReqHandler: called when WAPI isn't enabled\n");
3007#endif
2850} 3008}
2851 3009
2852void CsrWifiRouterCtrlWapiUnicastFilterReqHandler(void* drvpriv, CsrWifiFsmEvent* msg) 3010void CsrWifiRouterCtrlWapiUnicastFilterReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
2853{ 3011{
3012#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
3013
2854 unifi_priv_t *priv = (unifi_priv_t*)drvpriv; 3014 unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
2855 CsrWifiRouterCtrlWapiUnicastFilterReq* req = (CsrWifiRouterCtrlWapiUnicastFilterReq*)msg; 3015 CsrWifiRouterCtrlWapiUnicastFilterReq* req = (CsrWifiRouterCtrlWapiUnicastFilterReq*)msg;
3016 netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag];
2856 3017
2857 unifi_trace(priv, UDBG6, ">>%s\n", __FUNCTION__); 3018 if (CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode) {
2858 unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWapiUnicastFilterReq: req->status= %d\n", req->status);
2859 3019
2860 if ((priv->wapi_unicast_filter == 1) && (req->status == 0)) { 3020 unifi_trace(priv, UDBG6, ">>%s\n", __FUNCTION__);
2861 /* When we have successfully re-associated and obtained a new unicast key with keyid = 0 */
2862 priv->wapi_unicast_queued_pkt_filter = 1;
2863 }
2864 3021
2865 /* status 1 - Filter ON 3022 unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWapiUnicastFilterReq: req->status= %d\n", req->status);
2866 * status 0 - Filter OFF */
2867 priv->wapi_unicast_filter = req->status;
2868 3023
2869 unifi_trace(priv, UDBG6, "<<%s\n", __FUNCTION__); 3024 if ((priv->wapi_unicast_filter == 1) && (req->status == 0)) {
2870} 3025 /* When we have successfully re-associated and obtained a new unicast key with keyid = 0 */
3026 priv->wapi_unicast_queued_pkt_filter = 1;
3027 }
2871 3028
3029 /* status 1 - Filter ON
3030 * status 0 - Filter OFF */
3031 priv->wapi_unicast_filter = req->status;
2872 3032
2873void CsrWifiRouterCtrlWapiMulticastReqHandler(void* drvpriv, CsrWifiFsmEvent* msg) 3033 unifi_trace(priv, UDBG6, "<<%s\n", __FUNCTION__);
2874{ 3034 } else {
3035
3036 unifi_warning(priv, "%s is NOT applicable for interface mode - %d\n", __FUNCTION__,interfacePriv->interfaceMode);
3037
3038 }
3039#elif defined(UNIFI_DEBUG)
3040 /*WAPI Disabled*/
2875 unifi_priv_t *priv = (unifi_priv_t*)drvpriv; 3041 unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
2876 CsrWifiRouterCtrlWapiMulticastReq* req = (CsrWifiRouterCtrlWapiMulticastReq*)msg; 3042 unifi_error(priv,"CsrWifiRouterCtrlWapiUnicastFilterReqHandler: called when WAPI isn't enabled\n");
3043#endif
3044}
3045
3046void CsrWifiRouterCtrlWapiRxPktReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
3047{
3048#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
2877 3049
3050 unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
3051 CsrWifiRouterCtrlWapiRxPktReq* req = (CsrWifiRouterCtrlWapiRxPktReq*)msg;
2878 int client_id, receiver_id; 3052 int client_id, receiver_id;
2879 bulk_data_param_t bulkdata; 3053 bulk_data_param_t bulkdata;
2880 CsrResult res; 3054 CsrResult res;
2881 ul_client_t *client; 3055 ul_client_t *client;
2882
2883 CSR_SIGNAL signal; 3056 CSR_SIGNAL signal;
2884 CSR_MA_PACKET_INDICATION *pkt_ind; 3057 CSR_MA_PACKET_INDICATION *pkt_ind;
3058 netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag];
2885 3059
2886 unifi_trace(priv, UDBG6, ">>%s\n", __FUNCTION__); 3060 if (CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode) {
2887 unifi_trace(priv, UDBG4, "CsrWifiRouterCtrlWapiMulticastReqHandler: \n");
2888 3061
2889 if (priv == NULL) { 3062 unifi_trace(priv, UDBG6, ">>%s\n", __FUNCTION__);
2890 unifi_error(priv, "CsrWifiRouterCtrlWapiMulticastReqHandler : invalid priv\n",__FUNCTION__);
2891 return;
2892 }
2893 3063
2894 if (priv->smepriv == NULL) { 3064 if (priv == NULL) {
2895 unifi_error(priv, "CsrWifiRouterCtrlWapiMulticastReqHandler : invalid sme priv\n",__FUNCTION__); 3065 unifi_error(priv, "CsrWifiRouterCtrlWapiRxPktReq : invalid priv\n",__FUNCTION__);
2896 return; 3066 return;
2897 } 3067 }
2898 3068
2899 if (req->dataLength == 0 || req->data == NULL) { 3069 if (priv->smepriv == NULL) {
2900 unifi_error(priv, "CsrWifiRouterCtrlWapiMulticastReqHandler: invalid request\n",__FUNCTION__); 3070 unifi_error(priv, "CsrWifiRouterCtrlWapiRxPktReq : invalid sme priv\n",__FUNCTION__);
2901 return; 3071 return;
2902 } 3072 }
2903 3073
2904 res = unifi_net_data_malloc(priv, &bulkdata.d[0], req->dataLength); 3074 if (req->dataLength == 0 || req->data == NULL) {
2905 if (res != CSR_RESULT_SUCCESS) { 3075 unifi_error(priv, "CsrWifiRouterCtrlWapiRxPktReq: invalid request\n",__FUNCTION__);
2906 unifi_error(priv, "CsrWifiRouterCtrlWapiMulticastReqHandler: Could not allocate net data\n",__FUNCTION__); 3076 return;
2907 return; 3077 }
2908 }
2909 3078
2910 /* This function is expected to be called only when the MIC has been verified by SME to be correct 3079 res = unifi_net_data_malloc(priv, &bulkdata.d[0], req->dataLength);
2911 * So reset the reception status to rx_success */ 3080 if (res != CSR_RESULT_SUCCESS) {
2912 res = read_unpack_signal(req->signal, &signal); 3081 unifi_error(priv, "CsrWifiRouterCtrlWapiRxPktReq: Could not allocate net data\n",__FUNCTION__);
2913 if (res) { 3082 return;
2914 unifi_error(priv,"CsrWifiRouterCtrlWapiMulticastReqHandler: Received unknown or corrupted signal.\n"); 3083 }
2915 return; 3084
2916 } 3085 /* This function is expected to be called only when the MIC has been verified by SME to be correct
2917 pkt_ind = (CSR_MA_PACKET_INDICATION*) (&((&signal)->u).MaPacketIndication); 3086 * So reset the reception status to rx_success */
2918 if (pkt_ind->ReceptionStatus != CSR_MICHAEL_MIC_ERROR) { 3087 res = read_unpack_signal(req->signal, &signal);
2919 unifi_error(priv,"CsrWifiRouterCtrlWapiMulticastReqHandler: Unknown signal with reception status = %d\n",pkt_ind->ReceptionStatus); 3088 if (res) {
2920 return; 3089 unifi_error(priv,"CsrWifiRouterCtrlWapiRxPktReqHandler: Received unknown or corrupted signal.\n");
2921 } 3090 return;
2922 else { 3091 }
2923 unifi_trace(priv, UDBG4,"CsrWifiRouterCtrlWapiMulticastReqHandler: MIC verified , RX_SUCCESS \n",__FUNCTION__); 3092 pkt_ind = (CSR_MA_PACKET_INDICATION*) (&((&signal)->u).MaPacketIndication);
2924 pkt_ind->ReceptionStatus = CSR_RX_SUCCESS; 3093 if (pkt_ind->ReceptionStatus != CSR_MICHAEL_MIC_ERROR) {
2925 write_pack(&signal, req->signal, &(req->signalLength)); 3094 unifi_error(priv,"CsrWifiRouterCtrlWapiRxPktReqHandler: Unknown signal with reception status = %d\n",pkt_ind->ReceptionStatus);
3095 return;
3096 } else {
3097 unifi_trace(priv, UDBG4,"CsrWifiRouterCtrlWapiRxPktReqHandler: MIC verified , RX_SUCCESS \n",__FUNCTION__);
3098 pkt_ind->ReceptionStatus = CSR_RX_SUCCESS;
3099 write_pack(&signal, req->signal, &(req->signalLength));
3100 }
3101
3102 memcpy((void*)bulkdata.d[0].os_data_ptr, req->data, req->dataLength);
3103
3104 receiver_id = CSR_GET_UINT16_FROM_LITTLE_ENDIAN((req->signal) + sizeof(CsrInt16)) & 0xFFF0;
3105 client_id = (receiver_id & 0x0F00) >> UDI_SENDER_ID_SHIFT;
3106
3107 client = &priv->ul_clients[client_id];
3108
3109 if (client && client->event_hook) {
3110 unifi_trace(priv, UDBG3,
3111 "CsrWifiRouterCtrlWapiRxPktReq: "
3112 "Sending signal to client %d, (s:0x%X, r:0x%X) - Signal 0x%X \n",
3113 client->client_id, client->sender_id, receiver_id,
3114 CSR_GET_UINT16_FROM_LITTLE_ENDIAN(req->signal));
3115
3116 client->event_hook(client, req->signal, req->signalLength, &bulkdata, UDI_TO_HOST);
3117 } else {
3118 unifi_trace(priv, UDBG4, "No client to give the packet to\n");
3119 unifi_net_data_free(priv, &bulkdata.d[0]);
3120 }
3121
3122 unifi_trace(priv, UDBG6, "<<%s\n", __FUNCTION__);
3123 } else {
3124 unifi_warning(priv, "%s is NOT applicable for interface mode - %d\n", __FUNCTION__,interfacePriv->interfaceMode);
2926 } 3125 }
3126#elif defined(UNIFI_DEBUG)
3127 /*WAPI Disabled*/
3128 unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
3129 unifi_error(priv,"CsrWifiRouterCtrlWapiRxPktReqHandler: called when WAPI isn't enabled\n");
3130#endif
3131}
2927 3132
2928 memcpy((void*)bulkdata.d[0].os_data_ptr, req->data, req->dataLength); 3133void CsrWifiRouterCtrlWapiUnicastTxPktReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
3134{
3135#if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION))
2929 3136
2930 receiver_id = CSR_GET_UINT16_FROM_LITTLE_ENDIAN((req->signal) + sizeof(CsrInt16)) & 0xFFF0; 3137 unifi_priv_t *priv = (unifi_priv_t*) drvpriv;
2931 client_id = (receiver_id & 0x0F00) >> UDI_SENDER_ID_SHIFT; 3138 CsrWifiRouterCtrlWapiUnicastTxPktReq *req = (CsrWifiRouterCtrlWapiUnicastTxPktReq*) msg;
3139 netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag];
3140 bulk_data_param_t bulkdata;
3141 CsrUint8 macHeaderLengthInBytes = MAC_HEADER_SIZE;
3142 /*KeyID, Reserved, PN, MIC*/
3143 CsrUint8 appendedCryptoFields = 1 + 1 + 16 + 16;
3144 CsrResult result;
3145 /* Retrieve the MA PACKET REQ fields from the Signal retained from send_ma_pkt_request() */
3146 CSR_MA_PACKET_REQUEST *storedSignalMAPktReq = &interfacePriv->wapi_unicast_ma_pkt_sig.u.MaPacketRequest;
2932 3147
2933 client = &priv->ul_clients[client_id]; 3148 if (CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode) {
3149
3150 unifi_trace(priv, UDBG6, ">>%s\n", __FUNCTION__);
3151
3152 if (priv == NULL) {
3153 unifi_error(priv, "CsrWifiRouterCtrlWapiUnicastTxPktReqHandler : invalid priv\n",__FUNCTION__);
3154 return;
3155 }
3156 if (priv->smepriv == NULL) {
3157 unifi_error(priv, "CsrWifiRouterCtrlWapiUnicastTxPktReqHandler : invalid sme priv\n",__FUNCTION__);
3158 return;
3159 }
3160 if (req->data == NULL) {
3161 unifi_error(priv, "CsrWifiRouterCtrlWapiUnicastTxPktReqHandler: invalid request\n",__FUNCTION__);
3162 return;
3163 } else {
3164 /* If it is QoS data (type = data subtype = QoS), frame header contains QoS control field */
3165 if ((req->data[0] & 0x88) == 0x88) {
3166 macHeaderLengthInBytes = macHeaderLengthInBytes + QOS_CONTROL_HEADER_SIZE;
3167 }
3168 }
3169 if ( !(req->dataLength>(macHeaderLengthInBytes+appendedCryptoFields)) ) {
3170 unifi_error(priv, "CsrWifiRouterCtrlWapiUnicastTxPktReqHandler: invalid dataLength\n",__FUNCTION__);
3171 return;
3172 }
3173
3174 /* Encrypted DATA Packet contained in (req->data)
3175 * -------------------------------------------------------------------
3176 * |MAC Header| KeyId | Reserved | PN | xxDataxx | xxMICxxx |
3177 * -------------------------------------------------------------------
3178 * (<-----Encrypted----->)
3179 * -------------------------------------------------------------------
3180 * |24/26(QoS)| 1 | 1 | 16 | x | 16 |
3181 * -------------------------------------------------------------------
3182 */
3183 result = unifi_net_data_malloc(priv, &bulkdata.d[0], req->dataLength);
3184 if (result != CSR_RESULT_SUCCESS) {
3185 unifi_error(priv, "CsrWifiRouterCtrlWapiUnicastTxPktReqHandler: Could not allocate net data\n",__FUNCTION__);
3186 return;
3187 }
3188 memcpy((void*)bulkdata.d[0].os_data_ptr, req->data, req->dataLength);
3189 bulkdata.d[0].data_length = req->dataLength;
3190 bulkdata.d[1].os_data_ptr = NULL;
3191 bulkdata.d[1].data_length = 0;
3192
3193 /* Send UniFi msg */
3194 /* Here hostTag is been sent as 0xffffffff, its been appended properly while framing MA-Packet request in pdu_processing.c file */
3195 result = uf_process_ma_packet_req(priv,
3196 storedSignalMAPktReq->Ra.x,
3197 storedSignalMAPktReq->HostTag,/* Ask for a new HostTag */
3198 req->interfaceTag,
3199 storedSignalMAPktReq->TransmissionControl,
3200 storedSignalMAPktReq->TransmitRate,
3201 storedSignalMAPktReq->Priority, /* Retained value */
3202 interfacePriv->wapi_unicast_ma_pkt_sig.SignalPrimitiveHeader.SenderProcessId, /*FIXME AP: VALIDATE ???*/
3203 &bulkdata);
3204
3205 if (result == NETDEV_TX_OK) {
3206 (priv->netdev[req->interfaceTag])->trans_start = jiffies;
3207 /* Should really count tx stats in the UNITDATA.status signal but
3208 * that doesn't have the length.
3209 */
3210 interfacePriv->stats.tx_packets++;
3211
3212 /* count only the packet payload */
3213 interfacePriv->stats.tx_bytes += req->dataLength - macHeaderLengthInBytes - appendedCryptoFields;
3214 unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWapiUnicastTxPktReqHandler: (Packet Sent), sent count = %x\n", interfacePriv->stats.tx_packets);
3215 } else {
3216 /* Failed to send: fh queue was full, and the skb was discarded*/
3217 unifi_trace(priv, UDBG1, "(HIP validation failure) Result = %d\n", result);
3218 unifi_net_data_free(priv, &bulkdata.d[0]);
3219
3220 interfacePriv->stats.tx_dropped++;
3221 unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWapiUnicastTxPktReqHandler: (Packet Drop), dropped count = %x\n", interfacePriv->stats.tx_dropped);
3222 }
2934 3223
2935 if (client && client->event_hook) { 3224 unifi_trace(priv, UDBG6, "<<%s\n", __FUNCTION__);
2936 unifi_trace(priv, UDBG3, 3225
2937 "CsrWifiRouterCtrlWapiMulticastReqHandler: " 3226 } else {
2938 "Sending signal to client %d, (s:0x%X, r:0x%X) - Signal 0x%X \n", 3227
2939 client->client_id, client->sender_id, receiver_id, 3228 unifi_warning(priv, "%s is NOT applicable for interface mode - %d\n", __FUNCTION__,interfacePriv->interfaceMode);
2940 CSR_GET_UINT16_FROM_LITTLE_ENDIAN(req->signal));
2941 3229
2942 client->event_hook(client, req->signal, req->signalLength, &bulkdata, UDI_TO_HOST);
2943 } 3230 }
2944 else { 3231#elif defined(UNIFI_DEBUG)
2945 unifi_trace(priv, UDBG4, "No client to give the packet to\n"); 3232 /*WAPI Disabled*/
2946 unifi_net_data_free(priv, &bulkdata.d[0]); 3233 unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
3234 unifi_error(priv,"CsrWifiRouterCtrlWapiUnicastTxPktReqHandler: called when WAPI SW ENCRYPTION isn't enabled\n");
3235#endif
3236}
3237
3238void CsrWifiRouterCtrlWapiFilterReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
3239{
3240#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
3241
3242#ifdef CSR_WIFI_SECURITY_WAPI_QOSCTRL_MIC_WORKAROUND
3243 unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
3244 CsrWifiRouterCtrlWapiFilterReq* req = (CsrWifiRouterCtrlWapiFilterReq*)msg;
3245 netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag];
3246
3247 if (CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode) {
3248
3249 unifi_trace(priv, UDBG6, ">>%s\n", __FUNCTION__);
3250
3251 unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWapiFilterReq: req->isWapiConnected [0/1] = %d \n",req->isWapiConnected);
3252
3253 priv->isWapiConnection = req->isWapiConnected;
3254
3255 unifi_trace(priv, UDBG6, "<<%s\n", __FUNCTION__);
3256 } else {
3257
3258 unifi_warning(priv, "%s is NOT applicable for interface mode - %d\n", __FUNCTION__,interfacePriv->interfaceMode);
3259
2947 } 3260 }
3261#endif
2948 3262
2949 unifi_trace(priv, UDBG6, "<<%s\n", __FUNCTION__); 3263#elif defined(UNIFI_DEBUG)
3264 /*WAPI Disabled*/
3265 unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
3266 unifi_error(priv,"CsrWifiRouterCtrlWapiFilterReq: called when WAPI isn't enabled\n");
3267#endif
2950} 3268}
diff --git a/drivers/staging/csr/sme_userspace.c b/drivers/staging/csr/sme_userspace.c
index 38df94b69e9..d87a6e304ff 100644
--- a/drivers/staging/csr/sme_userspace.c
+++ b/drivers/staging/csr/sme_userspace.c
@@ -101,7 +101,6 @@ uf_sme_init(unifi_priv_t *priv)
101 INIT_LIST_HEAD(&interfacePriv->genericMgtFrames); 101 INIT_LIST_HEAD(&interfacePriv->genericMgtFrames);
102 INIT_LIST_HEAD(&interfacePriv->genericMulticastOrBroadCastMgtFrames); 102 INIT_LIST_HEAD(&interfacePriv->genericMulticastOrBroadCastMgtFrames);
103 INIT_LIST_HEAD(&interfacePriv->genericMulticastOrBroadCastFrames); 103 INIT_LIST_HEAD(&interfacePriv->genericMulticastOrBroadCastFrames);
104 INIT_LIST_HEAD(&interfacePriv->directedMaPktReq);
105 104
106 for(j = 0; j < UNIFI_MAX_CONNECTIONS; j++) { 105 for(j = 0; j < UNIFI_MAX_CONNECTIONS; j++) {
107 interfacePriv->staInfo[j] = NULL; 106 interfacePriv->staInfo[j] = NULL;
@@ -139,7 +138,7 @@ uf_sme_deinit(unifi_priv_t *priv)
139 138
140 /* Remove all the Peer database, before going down */ 139 /* Remove all the Peer database, before going down */
141 for (i = 0; i < CSR_WIFI_NUM_INTERFACES; i++) { 140 for (i = 0; i < CSR_WIFI_NUM_INTERFACES; i++) {
142 spin_lock(&priv->ba_lock); 141 down(&priv->ba_mutex);
143 for(ba_session_idx=0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_RX; ba_session_idx++){ 142 for(ba_session_idx=0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_RX; ba_session_idx++){
144 ba_session_rx = priv->interfacePriv[i]->ba_session_rx[ba_session_idx]; 143 ba_session_rx = priv->interfacePriv[i]->ba_session_rx[ba_session_idx];
145 if(ba_session_rx) { 144 if(ba_session_rx) {
@@ -161,7 +160,7 @@ uf_sme_deinit(unifi_priv_t *priv)
161 } 160 }
162 } 161 }
163 162
164 spin_unlock(&priv->ba_lock); 163 up(&priv->ba_mutex);
165 interfacePriv = priv->interfacePriv[i]; 164 interfacePriv = priv->interfacePriv[i];
166 if(interfacePriv){ 165 if(interfacePriv){
167 for(j = 0; j < UNIFI_MAX_CONNECTIONS; j++) { 166 for(j = 0; j < UNIFI_MAX_CONNECTIONS; j++) {
diff --git a/drivers/staging/csr/sme_wext.c b/drivers/staging/csr/sme_wext.c
index 384ccd46982..3ba7b4cef2d 100644
--- a/drivers/staging/csr/sme_wext.c
+++ b/drivers/staging/csr/sme_wext.c
@@ -29,8 +29,10 @@
29 } \ 29 } \
30 } while (0) 30 } while (0)
31 31
32/* Workaround for the wpa_supplicant hanging issue */ 32/* Workaround for the wpa_supplicant hanging issue - disabled on Android */
33#ifndef ANDROID_BUILD
33#define CSR_WIFI_WEXT_HANG_WORKAROUND 34#define CSR_WIFI_WEXT_HANG_WORKAROUND
35#endif
34 36
35#ifdef CSR_WIFI_WEXT_HANG_WORKAROUND 37#ifdef CSR_WIFI_WEXT_HANG_WORKAROUND
36# define UF_RTNL_LOCK() rtnl_lock() 38# define UF_RTNL_LOCK() rtnl_lock()
diff --git a/drivers/staging/csr/ul_int.c b/drivers/staging/csr/ul_int.c
index ae14f235436..958b8a1a9eb 100644
--- a/drivers/staging/csr/ul_int.c
+++ b/drivers/staging/csr/ul_int.c
@@ -265,7 +265,9 @@ ul_log_config_ind(unifi_priv_t *priv, u8 *conf_param, int len)
265 /* wifi_off_ind (error or exit) */ 265 /* wifi_off_ind (error or exit) */
266 CsrWifiRouterCtrlWifiOffIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,0, (CsrWifiRouterCtrlControlIndication)(*conf_param)); 266 CsrWifiRouterCtrlWifiOffIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,0, (CsrWifiRouterCtrlControlIndication)(*conf_param));
267 } 267 }
268 268#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
269 unifi_debug_buf_dump();
270#endif
269#else 271#else
270 bulk_data_param_t bulkdata; 272 bulk_data_param_t bulkdata;
271 273
@@ -420,10 +422,6 @@ ul_send_signal_unpacked(unifi_priv_t *priv, CSR_SIGNAL *sigptr,
420 CsrResult csrResult; 422 CsrResult csrResult;
421 unsigned long lock_flags; 423 unsigned long lock_flags;
422 int r; 424 int r;
423#ifdef CSR_SUPPORT_SME
424 netInterface_priv_t *interfacePriv = priv->interfacePriv[0];
425 CsrUint32 alignOffset = 0;
426#endif
427 425
428 426
429 csrResult = write_pack(sigptr, sigbuf, &packed_siglen); 427 csrResult = write_pack(sigptr, sigbuf, &packed_siglen);
@@ -431,12 +429,6 @@ ul_send_signal_unpacked(unifi_priv_t *priv, CSR_SIGNAL *sigptr,
431 unifi_error(priv, "Malformed HIP signal in ul_send_signal_unpacked()\n"); 429 unifi_error(priv, "Malformed HIP signal in ul_send_signal_unpacked()\n");
432 return CsrHipResultToStatus(csrResult); 430 return CsrHipResultToStatus(csrResult);
433 } 431 }
434#ifdef CSR_SUPPORT_SME
435 if (bulkdata != NULL){
436 alignOffset = (CsrUint32)(long)(bulkdata->d[0].os_data_ptr) & (CSR_WIFI_ALIGN_BYTES-1);
437
438 }
439#endif
440 r = _align_bulk_data_buffers(priv, sigbuf, (bulk_data_param_t*)bulkdata); 432 r = _align_bulk_data_buffers(priv, sigbuf, (bulk_data_param_t*)bulkdata);
441 if (r) { 433 if (r) {
442 return r; 434 return r;
@@ -449,17 +441,6 @@ ul_send_signal_unpacked(unifi_priv_t *priv, CSR_SIGNAL *sigptr,
449 spin_unlock_irqrestore(&priv->send_signal_lock, lock_flags); 441 spin_unlock_irqrestore(&priv->send_signal_lock, lock_flags);
450 return CsrHipResultToStatus(csrResult); 442 return CsrHipResultToStatus(csrResult);
451 } 443 }
452#ifdef CSR_SUPPORT_SME
453 if (sigptr->SignalPrimitiveHeader.SignalId == CSR_MA_PACKET_REQUEST_ID) {
454 if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
455 interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
456
457 uf_store_directed_ma_packet_referenece(priv, bulkdata, sigptr,alignOffset);
458
459 }
460 }
461#endif
462
463 spin_unlock_irqrestore(&priv->send_signal_lock, lock_flags); 444 spin_unlock_irqrestore(&priv->send_signal_lock, lock_flags);
464 445
465 return 0; 446 return 0;
diff --git a/drivers/staging/csr/unifi_event.c b/drivers/staging/csr/unifi_event.c
index cfc5b32d4a6..8b5d4669e12 100644
--- a/drivers/staging/csr/unifi_event.c
+++ b/drivers/staging/csr/unifi_event.c
@@ -109,7 +109,11 @@ static CsrBool check_routing_pkt_data_ind(unifi_priv_t *priv,
109 static const CsrUint8 wapiProtocolIdSNAPHeaderOffset = 6; 109 static const CsrUint8 wapiProtocolIdSNAPHeaderOffset = 6;
110 CsrUint8 *destAddr; 110 CsrUint8 *destAddr;
111 CsrUint8 *srcAddr; 111 CsrUint8 *srcAddr;
112 CsrBool isUnicastPkt = FALSE; 112 CsrBool isWapiUnicastPkt = FALSE;
113
114#ifdef CSR_WIFI_SECURITY_WAPI_QOSCTRL_MIC_WORKAROUND
115 CsrUint16 qosControl;
116#endif
113 117
114 CsrUint8 llcSnapHeaderOffset = 0; 118 CsrUint8 llcSnapHeaderOffset = 0;
115 119
@@ -117,7 +121,7 @@ static CsrBool check_routing_pkt_data_ind(unifi_priv_t *priv,
117 srcAddr = (CsrUint8 *) bulkdata->d[0].os_data_ptr + MAC_HEADER_ADDR2_OFFSET; 121 srcAddr = (CsrUint8 *) bulkdata->d[0].os_data_ptr + MAC_HEADER_ADDR2_OFFSET;
118 122
119 /*Individual/Group bit - Bit 0 of first byte*/ 123 /*Individual/Group bit - Bit 0 of first byte*/
120 isUnicastPkt = (!(destAddr[0] & 0x01)) ? TRUE : FALSE; 124 isWapiUnicastPkt = (!(destAddr[0] & 0x01)) ? TRUE : FALSE;
121#endif 125#endif
122 126
123#define CSR_WIFI_MA_PKT_IND_RECEPTION_STATUS_OFFSET sizeof(CSR_SIGNAL_PRIMITIVE_HEADER) + 22 127#define CSR_WIFI_MA_PKT_IND_RECEPTION_STATUS_OFFSET sizeof(CSR_SIGNAL_PRIMITIVE_HEADER) + 22
@@ -158,20 +162,54 @@ static CsrBool check_routing_pkt_data_ind(unifi_priv_t *priv,
158 162
159 if (interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_STA) { 163 if (interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_STA) {
160 164
165#ifdef CSR_WIFI_SECURITY_WAPI_QOSCTRL_MIC_WORKAROUND
166 if ((isDataFrame) &&
167 ((IEEE802_11_FC_TYPE_QOS_DATA & IEEE80211_FC_SUBTYPE_MASK) == (frmCtrl & IEEE80211_FC_SUBTYPE_MASK)) &&
168 (priv->isWapiConnection))
169 {
170 qosControl = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(macHdrLocation + (((frmCtrl & IEEE802_11_FC_TO_DS_MASK) && (frmCtrl & IEEE802_11_FC_FROM_DS_MASK)) ? 30 : 24) );
171
172 unifi_trace(priv, UDBG4, "check_routing_pkt_data_ind() :: Value of the QoS control field - 0x%04x \n", qosControl);
173
174 if (qosControl & IEEE802_11_QC_NON_TID_BITS_MASK)
175 {
176 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");
177
178 /*Exclude the MIC [16] and the PN [16] that are appended by the firmware*/
179 ((bulk_data_param_t*)bulkdata)->d[0].data_length = bulkdata->d[0].data_length - 32;
180
181 /*Clear the reception status of the signal (CSR_RX_SUCCESS)*/
182 *(sigdata + CSR_WIFI_MA_PKT_IND_RECEPTION_STATUS_OFFSET) = 0x00;
183 *(sigdata + CSR_WIFI_MA_PKT_IND_RECEPTION_STATUS_OFFSET+1) = 0x00;
184
185 *freeBulkData = FALSE;
186
187 return FALSE;
188 }
189 }
190#endif
161 /* If this MIC ERROR reported by the firmware is either for 191 /* If this MIC ERROR reported by the firmware is either for
162 * [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 192 * [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
163 * [2] a WAPI Unicast Packet and either the CONTROL PORT is open or the WAPI Unicast filter or filter(s) is NOT set 193 * [2] a WAPI Unicast MPDU and either the CONTROL PORT is open or the WAPI Unicast filter or filter(s) is NOT set
164 * then report a MIC FAILURE indication to the SME. 194 * then report a MIC FAILURE indication to the SME.
165 */ 195 */
166 if ((priv->wapi_multicast_filter == 0) || isUnicastPkt) { 196#ifndef CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION
167 197 if ((priv->wapi_multicast_filter == 0) || isWapiUnicastPkt) {
198#else
199 /*When SW encryption is enabled and USKID=1 (wapi_unicast_filter = 1), we are expected
200 *to receive MIC failure INDs for unicast MPDUs*/
201 if ( ((priv->wapi_multicast_filter == 0) && !isWapiUnicastPkt) ||
202 ((priv->wapi_unicast_filter == 0) && isWapiUnicastPkt) ) {
203#endif
168 /*Discard the frame*/ 204 /*Discard the frame*/
169 *freeBulkData = TRUE; 205 *freeBulkData = TRUE;
170 unifi_trace(priv, UDBG4, "Discarding the contents of the frame with MIC failure \n"); 206 unifi_trace(priv, UDBG4, "Discarding the contents of the frame with MIC failure \n");
171 207
172 if (isUnicastPkt && 208 if (isWapiUnicastPkt &&
173 ((uf_sme_port_state(priv,srcAddr,UF_CONTROLLED_PORT_Q,interfaceTag) != CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN)|| 209 ((uf_sme_port_state(priv,srcAddr,UF_CONTROLLED_PORT_Q,interfaceTag) != CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN)||
210#ifndef CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION
174 (priv->wapi_unicast_filter) || 211 (priv->wapi_unicast_filter) ||
212#endif
175 (priv->wapi_unicast_queued_pkt_filter))) { 213 (priv->wapi_unicast_queued_pkt_filter))) {
176 214
177 /* Workaround to handle MIC failures reported by the firmware for encrypted packets from the AP 215 /* Workaround to handle MIC failures reported by the firmware for encrypted packets from the AP
@@ -225,7 +263,8 @@ static CsrBool check_routing_pkt_data_ind(unifi_priv_t *priv,
225 /* To ignore MIC failures reported due to the WAPI AP using the old key for queued packets before 263 /* To ignore MIC failures reported due to the WAPI AP using the old key for queued packets before
226 * starting to use the new key negotiated as part of unicast re-keying 264 * starting to use the new key negotiated as part of unicast re-keying
227 */ 265 */
228 if (isUnicastPkt && 266 if ((interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_STA)&&
267 isWapiUnicastPkt &&
229 (receptionStatus == CSR_RX_SUCCESS) && 268 (receptionStatus == CSR_RX_SUCCESS) &&
230 (priv->wapi_unicast_queued_pkt_filter==1)) { 269 (priv->wapi_unicast_queued_pkt_filter==1)) {
231 270
@@ -297,16 +336,10 @@ static CsrBool check_routing_pkt_data_ind(unifi_priv_t *priv,
297 return FALSE; 336 return FALSE;
298 } 337 }
299} 338}
300#ifdef CSR_WIFI_RX_PATH_SPLIT
301static CsrBool signal_buffer_is_full(unifi_priv_t* priv)
302{
303 return (((priv->rxSignalBuffer.writePointer + 1)% priv->rxSignalBuffer.size) == (priv->rxSignalBuffer.readPointer));
304 339
305}
306#endif
307/* 340/*
308 * --------------------------------------------------------------------------- 341 * ---------------------------------------------------------------------------
309 * unifi_receive_event 342 * unifi_process_receive_event
310 * 343 *
311 * Dispatcher for received signals. 344 * Dispatcher for received signals.
312 * 345 *
@@ -332,56 +365,11 @@ static CsrBool signal_buffer_is_full(unifi_priv_t* priv)
332 * binded to the host interface specification. 365 * binded to the host interface specification.
333 * --------------------------------------------------------------------------- 366 * ---------------------------------------------------------------------------
334 */ 367 */
335 368static void
336 369unifi_process_receive_event(void *ospriv,
337void 370 CsrUint8 *sigdata, CsrUint32 siglen,
338unifi_receive_event(void *ospriv, 371 const bulk_data_param_t *bulkdata)
339 CsrUint8 *sigdata, CsrUint32 siglen,
340 const bulk_data_param_t *bulkdata)
341{ 372{
342#ifdef CSR_WIFI_RX_PATH_SPLIT
343 unifi_priv_t *priv = (unifi_priv_t*)ospriv;
344 CsrUint8 writePointer;
345 int i;
346 rx_buff_struct_t * rx_buff;
347 func_enter();
348
349 unifi_trace(priv, UDBG5, "unifi_receive_event: "
350 "%04x %04x %04x %04x %04x %04x %04x %04x (%d)\n",
351 CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*0) & 0xFFFF,
352 CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*1) & 0xFFFF,
353 CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*2) & 0xFFFF,
354 CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*3) & 0xFFFF,
355 CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*4) & 0xFFFF,
356 CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*5) & 0xFFFF,
357 CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*6) & 0xFFFF,
358 CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*7) & 0xFFFF, siglen);
359 if(signal_buffer_is_full(priv)) {
360 unifi_error(priv,"TO HOST signal queue FULL dropping the PDU\n");
361 for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++) {
362 if (bulkdata->d[i].data_length != 0) {
363 unifi_net_data_free(priv, (void *)&bulkdata->d[i]);
364 }
365 }
366 return;
367 }
368 writePointer = priv->rxSignalBuffer.writePointer;
369 rx_buff = &priv->rxSignalBuffer.rx_buff[writePointer];
370 memcpy(rx_buff->bufptr,sigdata,siglen);
371 rx_buff->sig_len = siglen;
372 rx_buff->data_ptrs = *bulkdata;
373 writePointer++;
374 if(writePointer >= priv->rxSignalBuffer.size) {
375 writePointer =0;
376 }
377 unifi_trace(priv, UDBG4, "unifi_receive_event:writePtr = %d\n",priv->rxSignalBuffer.writePointer);
378 priv->rxSignalBuffer.writePointer = writePointer;
379
380#ifndef CSR_WIFI_RX_PATH_SPLIT_DONT_USE_WQ
381 queue_work(priv->rx_workqueue, &priv->rx_work_struct);
382#endif
383
384#else
385 unifi_priv_t *priv = (unifi_priv_t*)ospriv; 373 unifi_priv_t *priv = (unifi_priv_t*)ospriv;
386 int i, receiver_id; 374 int i, receiver_id;
387 int client_id; 375 int client_id;
@@ -390,16 +378,17 @@ unifi_receive_event(void *ospriv,
390 378
391 func_enter(); 379 func_enter();
392 380
393 unifi_trace(priv, UDBG5, "unifi_receive_event: " 381 unifi_trace(priv, UDBG5, "unifi_process_receive_event: "
394 "%04x %04x %04x %04x %04x %04x %04x %04x (%d)\n", 382 "%04x %04x %04x %04x %04x %04x %04x %04x (%d)\n",
395 CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*0) & 0xFFFF, 383 CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*0) & 0xFFFF,
396 CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*1) & 0xFFFF, 384 CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*1) & 0xFFFF,
397 CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*2) & 0xFFFF, 385 CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*2) & 0xFFFF,
398 CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*3) & 0xFFFF, 386 CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*3) & 0xFFFF,
399 CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*4) & 0xFFFF, 387 CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*4) & 0xFFFF,
400 CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*5) & 0xFFFF, 388 CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*5) & 0xFFFF,
401 CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*6) & 0xFFFF, 389 CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*6) & 0xFFFF,
402 CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*7) & 0xFFFF, siglen); 390 CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*7) & 0xFFFF,
391 siglen);
403 392
404 receiver_id = CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)) & 0xFF00; 393 receiver_id = CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)) & 0xFF00;
405 client_id = (receiver_id & 0x0F00) >> UDI_SENDER_ID_SHIFT; 394 client_id = (receiver_id & 0x0F00) >> UDI_SENDER_ID_SHIFT;
@@ -410,18 +399,18 @@ unifi_receive_event(void *ospriv,
410 /* check for the type of frame received (checks for 802.11 management frames) */ 399 /* check for the type of frame received (checks for 802.11 management frames) */
411 if (signal_id == CSR_MA_PACKET_INDICATION_ID) 400 if (signal_id == CSR_MA_PACKET_INDICATION_ID)
412 { 401 {
402#define CSR_MA_PACKET_INDICATION_INTERFACETAG_OFFSET 14
413 CsrUint8 interfaceTag; 403 CsrUint8 interfaceTag;
414 netInterface_priv_t *interfacePriv; 404 netInterface_priv_t *interfacePriv;
415 405
416 /* Pull out interface tag from virtual interface identifier */ 406 /* Pull out interface tag from virtual interface identifier */
417 interfaceTag = (CSR_GET_UINT16_FROM_LITTLE_ENDIAN(sigdata + 14)) & 0xff; 407 interfaceTag = (CSR_GET_UINT16_FROM_LITTLE_ENDIAN(sigdata + CSR_MA_PACKET_INDICATION_INTERFACETAG_OFFSET)) & 0xff;
418 interfacePriv = priv->interfacePriv[interfaceTag]; 408 interfacePriv = priv->interfacePriv[interfaceTag];
419 409
420 /* Update activity for this station in case of IBSS */ 410 /* Update activity for this station in case of IBSS */
421#ifdef CSR_SUPPORT_SME 411#ifdef CSR_SUPPORT_SME
422 412 if (interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_IBSS)
423 if (interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_IBSS) { 413 {
424
425 CsrUint8 *saddr; 414 CsrUint8 *saddr;
426 /* Fetch the source address from mac header */ 415 /* Fetch the source address from mac header */
427 saddr = (CsrUint8 *) bulkdata->d[0].os_data_ptr + MAC_HEADER_ADDR2_OFFSET; 416 saddr = (CsrUint8 *) bulkdata->d[0].os_data_ptr + MAC_HEADER_ADDR2_OFFSET;
@@ -436,6 +425,7 @@ unifi_receive_event(void *ospriv,
436 pktIndToSme = check_routing_pkt_data_ind(priv, sigdata, bulkdata, &freeBulkData, interfacePriv); 425 pktIndToSme = check_routing_pkt_data_ind(priv, sigdata, bulkdata, &freeBulkData, interfacePriv);
437 426
438 unifi_trace(priv, UDBG6, "RX: packet entry point to driver from HIP,pkt to SME ?(%s) \n", (pktIndToSme)? "YES":"NO"); 427 unifi_trace(priv, UDBG6, "RX: packet entry point to driver from HIP,pkt to SME ?(%s) \n", (pktIndToSme)? "YES":"NO");
428
439 } 429 }
440 430
441 if (pktIndToSme) 431 if (pktIndToSme)
@@ -445,7 +435,7 @@ unifi_receive_event(void *ospriv,
445 send_to_client(priv, priv->sme_cli, receiver_id, sigdata, siglen, bulkdata); 435 send_to_client(priv, priv->sme_cli, receiver_id, sigdata, siglen, bulkdata);
446 } 436 }
447 else{ 437 else{
448 unifi_error(priv, "unifi_receive_event: sigdata or Bulkdata is NULL \n"); 438 unifi_error(priv, "unifi_receive_event2: sigdata or Bulkdata is NULL \n");
449 } 439 }
450#ifdef CSR_NATIVE_LINUX 440#ifdef CSR_NATIVE_LINUX
451 send_to_client(priv, priv->wext_client, 441 send_to_client(priv, priv->wext_client,
@@ -459,67 +449,99 @@ unifi_receive_event(void *ospriv,
459 * unless they are data/control MA_PACKET_INDs or VIF_AVAILABILITY_INDs 449 * unless they are data/control MA_PACKET_INDs or VIF_AVAILABILITY_INDs
460 */ 450 */
461 if (!receiver_id) { 451 if (!receiver_id) {
462 if(signal_id == CSR_MA_VIF_AVAILABILITY_INDICATION_ID) 452 if(signal_id == CSR_MA_VIF_AVAILABILITY_INDICATION_ID) {
463 { 453 uf_process_ma_vif_availibility_ind(priv, sigdata, siglen);
464 uf_process_ma_vif_availibility_ind(priv, sigdata, siglen); 454 }
465 } 455 else if (signal_id != CSR_MA_PACKET_INDICATION_ID) {
466 else if (signal_id != CSR_MA_PACKET_INDICATION_ID) 456 send_to_client(priv, priv->sme_cli, receiver_id, sigdata, siglen, bulkdata);
467 {
468 send_to_client(priv, priv->sme_cli, receiver_id, sigdata, siglen, bulkdata);
469#ifdef CSR_NATIVE_LINUX 457#ifdef CSR_NATIVE_LINUX
470 send_to_client(priv, priv->wext_client, 458 send_to_client(priv, priv->wext_client,
471 receiver_id, 459 receiver_id,
472 sigdata, siglen, bulkdata); 460 sigdata, siglen, bulkdata);
473#endif 461#endif
474 } 462 }
475 }/*if (receiver_id==0) */ 463 else
476 464 {
477#ifdef CSR_SUPPORT_SME 465
478#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE 466#if (defined(CSR_SUPPORT_SME) && defined(CSR_WIFI_SECURITY_WAPI_ENABLE))
479 /* Send a WAPI Multicast Indication to SME if the filter has been set 467 #define CSR_MA_PACKET_INDICATION_RECEPTION_STATUS_OFFSET sizeof(CSR_SIGNAL_PRIMITIVE_HEADER) + 22
480 * and this is a multicast data packet 468 netInterface_priv_t *interfacePriv;
481 */ 469 CsrUint8 interfaceTag;
482 if ((priv->wapi_multicast_filter == 1) && (signal_id == CSR_MA_PACKET_INDICATION_ID)) { 470 CsrUint16 receptionStatus = CSR_RX_SUCCESS;
483 CSR_SIGNAL signal; 471
484 CsrUint8 *destAddr; 472 /* Pull out interface tag from virtual interface identifier */
485 CsrResult res; 473 interfaceTag = (CSR_GET_UINT16_FROM_LITTLE_ENDIAN(sigdata + CSR_MA_PACKET_INDICATION_INTERFACETAG_OFFSET)) & 0xff;
486 CsrUint16 interfaceTag = 0; 474 interfacePriv = priv->interfacePriv[interfaceTag];
487 475
488 /* Check if it is a multicast packet from the destination address in the MAC header */ 476 /* check for MIC failure */
489 res = read_unpack_signal(sigdata, &signal); 477 receptionStatus = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(sigdata + CSR_MA_PACKET_INDICATION_RECEPTION_STATUS_OFFSET);
490 destAddr = (CsrUint8 *) bulkdata->d[0].os_data_ptr + MAC_HEADER_ADDR1_OFFSET; 478
491 if (res) { 479 /* Send a WAPI MPDU to SME for re-check MIC if the respective filter has been set*/
492 unifi_error(priv, "Received unknown or corrupted signal.\n"); 480 if ((!freeBulkData) &&
493 return; 481 (interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_STA) &&
494 } 482 (receptionStatus == CSR_MICHAEL_MIC_ERROR) &&
495 /*Individual/Group bit - Bit 0 of first byte*/ 483 ((priv->wapi_multicast_filter == 1)
496 if (destAddr[0] & 0x01) { 484#ifdef CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION
497 unifi_trace(priv, UDBG4, "Received a WAPI multicast packet ind\n"); 485 || (priv->wapi_unicast_filter == 1)
498
499 CsrWifiRouterCtrlWapiMulticastIndSend(priv->CSR_WIFI_SME_IFACEQUEUE, 0, interfaceTag, siglen, sigdata, bulkdata->d[0].data_length, (CsrUint8*)bulkdata->d[0].os_data_ptr);
500
501 for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++) {
502 if (bulkdata->d[i].data_length != 0) {
503 unifi_net_data_free(priv, (void *)&bulkdata->d[i]);
504 }
505 }
506 func_exit();
507 return;
508 }
509 }
510#endif 486#endif
487 ))
488 {
489 CSR_SIGNAL signal;
490 CsrUint8 *destAddr;
491 CsrResult res;
492 CsrUint16 interfaceTag = 0;
493 CsrBool isMcastPkt = TRUE;
494
495 unifi_trace(priv, UDBG6, "Received a WAPI data packet when the Unicast/Multicast filter is set\n");
496 res = read_unpack_signal(sigdata, &signal);
497 if (res) {
498 unifi_error(priv, "Received unknown or corrupted signal (0x%x).\n",
499 CSR_GET_UINT16_FROM_LITTLE_ENDIAN(sigdata));
500 return;
501 }
502
503 /* Check if the type of MPDU and the respective filter status*/
504 destAddr = (CsrUint8 *) bulkdata->d[0].os_data_ptr + MAC_HEADER_ADDR1_OFFSET;
505 isMcastPkt = (destAddr[0] & 0x01) ? TRUE : FALSE;
506 unifi_trace(priv, UDBG6,
507 "1.MPDU type: (%s), 2.Multicast filter: (%s), 3. Unicast filter: (%s)\n",
508 ((isMcastPkt) ? "Multiast":"Unicast"),
509 ((priv->wapi_multicast_filter) ? "Enabled":"Disabled"),
510 ((priv->wapi_unicast_filter) ? "Enabled":"Disabled"));
511
512 if (((isMcastPkt) && (priv->wapi_multicast_filter == 1))
513#ifdef CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION
514 || ((!isMcastPkt) && (priv->wapi_unicast_filter == 1))
511#endif 515#endif
516 )
517 {
518 unifi_trace(priv, UDBG4, "Sending the WAPI MPDU for MIC check\n");
519 CsrWifiRouterCtrlWapiRxMicCheckIndSend(priv->CSR_WIFI_SME_IFACEQUEUE, 0, interfaceTag, siglen, sigdata, bulkdata->d[0].data_length, (CsrUint8*)bulkdata->d[0].os_data_ptr);
520
521 for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++) {
522 if (bulkdata->d[i].data_length != 0) {
523 unifi_net_data_free(priv, (void *)&bulkdata->d[i]);
524 }
525 }
526 func_exit();
527 return;
528 }
529 } /* CSR_MA_PACKET_INDICATION_ID */
530#endif /*CSR_SUPPORT_SME && CSR_WIFI_SECURITY_WAPI_ENABLE*/
531 }
532 }
512 533
513 /* calls the registered clients handler callback func. 534 /* calls the registered clients handler callback func.
514 * netdev_mlme_event_handler is one of the registered handler used to route 535 * netdev_mlme_event_handler is one of the registered handler used to route
515 * data packet to network stack or AMP/EAPOL related data to SME 536 * data packet to network stack or AMP/EAPOL related data to SME
516 */ 537 *
517 /* The freeBulkData check ensures that, it has received a management frame and 538 * The freeBulkData check ensures that, it has received a management frame and
518 * the frame needs to be freed here. So not to be passed to netdev handler 539 * the frame needs to be freed here. So not to be passed to netdev handler
519 */ 540 */
520 if(!freeBulkData){ 541 if(!freeBulkData){
521 if ((client_id < MAX_UDI_CLIENTS) && 542 if ((client_id < MAX_UDI_CLIENTS) &&
522 (&priv->ul_clients[client_id] != priv->logging_client)) { 543 (&priv->ul_clients[client_id] != priv->logging_client)) {
544 unifi_trace(priv, UDBG6, "Call the registered clients handler callback func\n");
523 send_to_client(priv, &priv->ul_clients[client_id], 545 send_to_client(priv, &priv->ul_clients[client_id],
524 receiver_id, 546 receiver_id,
525 sigdata, siglen, bulkdata); 547 sigdata, siglen, bulkdata);
@@ -550,14 +572,54 @@ unifi_receive_event(void *ospriv,
550 } 572 }
551 } 573 }
552 } 574 }
553#endif 575
554 func_exit(); 576 func_exit();
555} /* unifi_receive_event() */ 577} /* unifi_process_receive_event() */
578
556 579
557#ifdef CSR_WIFI_RX_PATH_SPLIT 580#ifdef CSR_WIFI_RX_PATH_SPLIT
581static CsrBool signal_buffer_is_full(unifi_priv_t* priv)
582{
583 return (((priv->rxSignalBuffer.writePointer + 1)% priv->rxSignalBuffer.size) == (priv->rxSignalBuffer.readPointer));
584}
585
586void unifi_rx_queue_flush(void *ospriv)
587{
588 unifi_priv_t *priv = (unifi_priv_t*)ospriv;
589
590 func_enter();
591 unifi_trace(priv, UDBG4, "rx_wq_handler: RdPtr = %d WritePtr = %d\n",
592 priv->rxSignalBuffer.readPointer,priv->rxSignalBuffer.writePointer);
593 if(priv != NULL) {
594 CsrUint8 readPointer = priv->rxSignalBuffer.readPointer;
595 while (readPointer != priv->rxSignalBuffer.writePointer)
596 {
597 rx_buff_struct_t *buf = &priv->rxSignalBuffer.rx_buff[readPointer];
598 unifi_trace(priv, UDBG6, "rx_wq_handler: RdPtr = %d WritePtr = %d\n",
599 readPointer,priv->rxSignalBuffer.writePointer);
600 unifi_process_receive_event(priv, buf->bufptr, buf->sig_len, &buf->data_ptrs);
601 readPointer ++;
602 if(readPointer >= priv->rxSignalBuffer.size) {
603 readPointer = 0;
604 }
605 }
606 priv->rxSignalBuffer.readPointer = readPointer;
607 }
608 func_exit();
609}
610
611void rx_wq_handler(struct work_struct *work)
612{
613 unifi_priv_t *priv = container_of(work, unifi_priv_t, rx_work_struct);
614 unifi_rx_queue_flush(priv);
615}
616#endif
617
618
619
558/* 620/*
559 * --------------------------------------------------------------------------- 621 * ---------------------------------------------------------------------------
560 * unifi_receive_event2 622 * unifi_receive_event
561 * 623 *
562 * Dispatcher for received signals. 624 * Dispatcher for received signals.
563 * 625 *
@@ -583,20 +645,19 @@ unifi_receive_event(void *ospriv,
583 * binded to the host interface specification. 645 * binded to the host interface specification.
584 * --------------------------------------------------------------------------- 646 * ---------------------------------------------------------------------------
585 */ 647 */
586static void 648void
587unifi_receive_event2(void *ospriv, 649unifi_receive_event(void *ospriv,
588 CsrUint8 *sigdata, CsrUint32 siglen, 650 CsrUint8 *sigdata, CsrUint32 siglen,
589 const bulk_data_param_t *bulkdata) 651 const bulk_data_param_t *bulkdata)
590{ 652{
653#ifdef CSR_WIFI_RX_PATH_SPLIT
591 unifi_priv_t *priv = (unifi_priv_t*)ospriv; 654 unifi_priv_t *priv = (unifi_priv_t*)ospriv;
592 int i, receiver_id; 655 CsrUint8 writePointer;
593 int client_id; 656 int i;
594 CsrInt16 signal_id; 657 rx_buff_struct_t * rx_buff;
595 CsrBool pktIndToSme = FALSE, freeBulkData = FALSE;
596
597 func_enter(); 658 func_enter();
598 659
599 unifi_trace(priv, UDBG5, "unifi_receive_event2: " 660 unifi_trace(priv, UDBG5, "unifi_receive_event: "
600 "%04x %04x %04x %04x %04x %04x %04x %04x (%d)\n", 661 "%04x %04x %04x %04x %04x %04x %04x %04x (%d)\n",
601 CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*0) & 0xFFFF, 662 CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*0) & 0xFFFF,
602 CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*1) & 0xFFFF, 663 CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*1) & 0xFFFF,
@@ -606,189 +667,34 @@ unifi_receive_event2(void *ospriv,
606 CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*5) & 0xFFFF, 667 CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*5) & 0xFFFF,
607 CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*6) & 0xFFFF, 668 CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*6) & 0xFFFF,
608 CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*7) & 0xFFFF, siglen); 669 CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)*7) & 0xFFFF, siglen);
609 670 if(signal_buffer_is_full(priv)) {
610 receiver_id = CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(CsrInt16)) & 0xFF00; 671 unifi_error(priv,"TO HOST signal queue FULL dropping the PDU\n");
611 client_id = (receiver_id & 0x0F00) >> UDI_SENDER_ID_SHIFT; 672 for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++) {
612 signal_id = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(sigdata); 673 if (bulkdata->d[i].data_length != 0) {
613 674 unifi_net_data_free(priv, (void *)&bulkdata->d[i]);
614 675 }
615
616 /* check for the type of frame received (checks for 802.11 management frames) */
617 if (signal_id == CSR_MA_PACKET_INDICATION_ID)
618 {
619 CsrUint8 interfaceTag;
620 netInterface_priv_t *interfacePriv;
621
622 /* Pull out interface tag from virtual interface identifier */
623 interfaceTag = (CSR_GET_UINT16_FROM_LITTLE_ENDIAN(sigdata + 14)) & 0xff;
624 interfacePriv = priv->interfacePriv[interfaceTag];
625
626 /* Update activity for this station in case of IBSS */
627#ifdef CSR_SUPPORT_SME
628
629 if (interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_IBSS) {
630
631 CsrUint8 *saddr;
632 /* Fetch the source address from mac header */
633 saddr = (CsrUint8 *) bulkdata->d[0].os_data_ptr + MAC_HEADER_ADDR2_OFFSET;
634 unifi_trace(priv, UDBG5,
635 "Updating sta activity in IBSS interfaceTag %x Src Addr %x:%x:%x:%x:%x:%x\n",
636 interfaceTag, saddr[0], saddr[1], saddr[2], saddr[3], saddr[4], saddr[5]);
637
638 uf_update_sta_activity(priv, interfaceTag, saddr);
639 } 676 }
640#endif 677 return;
641
642 pktIndToSme = check_routing_pkt_data_ind(priv, sigdata, bulkdata, &freeBulkData, interfacePriv);
643
644 unifi_trace(priv, UDBG6, "RX: packet entry point to driver from HIP,pkt to SME ?(%s) \n", (pktIndToSme)? "YES":"NO");
645
646 } 678 }
647 679 writePointer = priv->rxSignalBuffer.writePointer;
648 if (pktIndToSme) 680 rx_buff = &priv->rxSignalBuffer.rx_buff[writePointer];
649 { 681 memcpy(rx_buff->bufptr,sigdata,siglen);
650 /* Management MA_PACKET_IND for SME */ 682 rx_buff->sig_len = siglen;
651 if(sigdata != NULL && bulkdata != NULL){ 683 rx_buff->data_ptrs = *bulkdata;
652 send_to_client(priv, priv->sme_cli, receiver_id, sigdata, siglen, bulkdata); 684 writePointer++;
653 } 685 if(writePointer >= priv->rxSignalBuffer.size) {
654 else{ 686 writePointer =0;
655 unifi_error(priv, "unifi_receive_event2: sigdata or Bulkdata is NULL \n");
656 }
657#ifdef CSR_NATIVE_LINUX
658 send_to_client(priv, priv->wext_client,
659 receiver_id,
660 sigdata, siglen, bulkdata);
661#endif
662 } 687 }
663 else 688 unifi_trace(priv, UDBG4, "unifi_receive_event:writePtr = %d\n",priv->rxSignalBuffer.writePointer);
664 { 689 priv->rxSignalBuffer.writePointer = writePointer;
665 /* Signals with ReceiverId==0 are also reported to SME / WEXT,
666 * unless they are data/control MA_PACKET_INDs or VIF_AVAILABILITY_INDs
667 */
668 if (!receiver_id) {
669 if(signal_id == CSR_MA_VIF_AVAILABILITY_INDICATION_ID)
670 {
671 uf_process_ma_vif_availibility_ind(priv, sigdata, siglen);
672 }
673 else if (signal_id != CSR_MA_PACKET_INDICATION_ID)
674 {
675 send_to_client(priv, priv->sme_cli, receiver_id, sigdata, siglen, bulkdata);
676#ifdef CSR_NATIVE_LINUX
677 send_to_client(priv, priv->wext_client,
678 receiver_id,
679 sigdata, siglen, bulkdata);
680#endif
681 }
682 }
683
684#ifdef CSR_SUPPORT_SME
685#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
686 /* Send a WAPI Multicast Indication to SME if the filter has been set
687 * and this is a multicast data packet
688 */
689 if ((priv->wapi_multicast_filter == 1) && (signal_id == CSR_MA_PACKET_INDICATION_ID)) {
690 CSR_SIGNAL signal;
691 CsrUint8 *destAddr;
692 CsrResult res;
693 CsrUint16 interfaceTag = 0;
694
695 /* Check if it is a multicast packet from the destination address in the MAC header */
696 res = read_unpack_signal(sigdata, &signal);
697 destAddr = (CsrUint8 *) bulkdata->d[0].os_data_ptr + MAC_HEADER_ADDR1_OFFSET;
698 if (res) {
699 unifi_error(priv, "Received unknown or corrupted signal.\n");
700 return;
701 }
702 /*Individual/Group bit - Bit 0 of first byte*/
703 if (destAddr[0] & 0x01) {
704 unifi_trace(priv, UDBG4, "Received a WAPI multicast packet ind\n");
705
706 CsrWifiRouterCtrlWapiMulticastIndSend(priv->CSR_WIFI_SME_IFACEQUEUE, 0, interfaceTag, siglen, sigdata, bulkdata->d[0].data_length, (CsrUint8*)bulkdata->d[0].os_data_ptr);
707 690
708 for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++) { 691#ifndef CSR_WIFI_RX_PATH_SPLIT_DONT_USE_WQ
709 if (bulkdata->d[i].data_length != 0) { 692 queue_work(priv->rx_workqueue, &priv->rx_work_struct);
710 unifi_net_data_free(priv, (void *)&bulkdata->d[i]);
711 }
712 }
713 func_exit();
714 return;
715 }
716 }
717#endif
718#endif 693#endif
719 694
720 /* calls the registered clients handler callback func. 695#else
721 * netdev_mlme_event_handler is one of the registered handler used to route 696 unifi_process_receive_event(ospriv, sigdata, siglen, bulkdata);
722 * data packet to network stack or AMP/EAPOL related data to SME
723 */
724 /* The freeBulkData check ensures that, it has received a management frame and
725 * the frame needs to be freed here. So not to be passed to netdev handler
726 */
727 if(!freeBulkData){
728 if ((client_id < MAX_UDI_CLIENTS) &&
729 (&priv->ul_clients[client_id] != priv->logging_client)) {
730 send_to_client(priv, &priv->ul_clients[client_id],
731 receiver_id,
732 sigdata, siglen, bulkdata);
733 }
734 }
735 }
736
737 /*
738 * Free bulk data buffers here unless it is a CSR_MA_PACKET_INDICATION
739 */
740 switch (signal_id)
741 {
742#ifdef UNIFI_SNIFF_ARPHRD
743 case CSR_MA_SNIFFDATA_INDICATION_ID:
744#endif 697#endif
745 break;
746
747 case CSR_MA_PACKET_INDICATION_ID:
748 if (!freeBulkData)
749 {
750 break;
751 }
752 /* FALLS THROUGH... */
753 default:
754 for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++) {
755 if (bulkdata->d[i].data_length != 0) {
756 unifi_net_data_free(priv, (void *)&bulkdata->d[i]);
757 }
758 }
759 }
760
761 func_exit(); 698 func_exit();
762} /* unifi_receive_event2() */ 699} /* unifi_receive_event() */
763
764void unifi_rx_queue_flush(void *ospriv)
765{
766 unifi_priv_t *priv = (unifi_priv_t*)ospriv;
767
768 func_enter();
769 unifi_trace(priv, UDBG4, "rx_wq_handler: RdPtr = %d WritePtr = %d\n",
770 priv->rxSignalBuffer.readPointer,priv->rxSignalBuffer.writePointer);
771 if(priv != NULL) {
772 CsrUint8 readPointer = priv->rxSignalBuffer.readPointer;
773 while(readPointer != priv->rxSignalBuffer.writePointer) {
774 rx_buff_struct_t * buf = &priv->rxSignalBuffer.rx_buff[readPointer];
775 unifi_trace(priv, UDBG6, "rx_wq_handler: RdPtr = %d WritePtr = %d\n",
776 readPointer,priv->rxSignalBuffer.writePointer);
777 unifi_receive_event2(priv,buf->bufptr,buf->sig_len,&buf->data_ptrs);
778 readPointer ++;
779 if(readPointer >= priv->rxSignalBuffer.size) {
780 readPointer = 0;
781 }
782 }
783 priv->rxSignalBuffer.readPointer = readPointer;
784 }
785 func_exit();
786}
787
788void rx_wq_handler(struct work_struct *work)
789{
790 unifi_priv_t *priv = container_of(work,unifi_priv_t,rx_work_struct);
791 unifi_rx_queue_flush(priv);
792}
793 700
794#endif
diff --git a/drivers/staging/csr/unifi_os.h b/drivers/staging/csr/unifi_os.h
index 579c7e0544a..0a974945068 100644
--- a/drivers/staging/csr/unifi_os.h
+++ b/drivers/staging/csr/unifi_os.h
@@ -97,6 +97,13 @@ void dump16(void *mem, CsrUint16 len);
97void dump_str(void *mem, CsrUint16 len); 97void dump_str(void *mem, CsrUint16 len);
98#endif /* CSR_WIFI_HIP_DEBUG_OFFLINE */ 98#endif /* CSR_WIFI_HIP_DEBUG_OFFLINE */
99 99
100void unifi_error(void* ospriv, const char *fmt, ...);
101void unifi_warning(void* ospriv, const char *fmt, ...);
102void unifi_notice(void* ospriv, const char *fmt, ...);
103void unifi_info(void* ospriv, const char *fmt, ...);
104
105void unifi_trace(void* ospriv, int level, const char *fmt, ...);
106
100#else 107#else
101 108
102/* Stubs */ 109/* Stubs */
@@ -113,15 +120,16 @@ static inline void dump16(void *mem, CsrUint16 len) {}
113static inline void dump_str(void *mem, CsrUint16 len) {} 120static inline void dump_str(void *mem, CsrUint16 len) {}
114#endif /* CSR_WIFI_HIP_DEBUG_OFFLINE */ 121#endif /* CSR_WIFI_HIP_DEBUG_OFFLINE */
115 122
116#endif /* UNIFI_DEBUG */ 123void unifi_error_nop(void* ospriv, const char *fmt, ...);
124void unifi_trace_nop(void* ospriv, int level, const char *fmt, ...);
125#define unifi_error if(1);else unifi_error_nop
126#define unifi_warning if(1);else unifi_error_nop
127#define unifi_notice if(1);else unifi_error_nop
128#define unifi_info if(1);else unifi_error_nop
129#define unifi_trace if(1);else unifi_trace_nop
117 130
131#endif /* UNIFI_DEBUG */
118 132
119void unifi_error(void* ospriv, const char *fmt, ...);
120void unifi_warning(void* ospriv, const char *fmt, ...);
121void unifi_notice(void* ospriv, const char *fmt, ...);
122void unifi_info(void* ospriv, const char *fmt, ...);
123
124void unifi_trace(void* ospriv, int level, const char *fmt, ...);
125 133
126/* Different levels of diagnostic detail... */ 134/* Different levels of diagnostic detail... */
127#define UDBG0 0 /* always prints in debug build */ 135#define UDBG0 0 /* always prints in debug build */
diff --git a/drivers/staging/csr/unifi_pdu_processing.c b/drivers/staging/csr/unifi_pdu_processing.c
index 36b871e02c9..e35747c0831 100644
--- a/drivers/staging/csr/unifi_pdu_processing.c
+++ b/drivers/staging/csr/unifi_pdu_processing.c
@@ -32,22 +32,23 @@
32static void _update_buffered_pkt_params_after_alignment(unifi_priv_t *priv, bulk_data_param_t *bulkdata, 32static void _update_buffered_pkt_params_after_alignment(unifi_priv_t *priv, bulk_data_param_t *bulkdata,
33 tx_buffered_packets_t* buffered_pkt) 33 tx_buffered_packets_t* buffered_pkt)
34{ 34{
35
36 struct sk_buff *skb ; 35 struct sk_buff *skb ;
37 CsrUint32 align_offset; 36 CsrUint32 align_offset;
38 37
39 if (priv == NULL || bulkdata == NULL || buffered_pkt == NULL){ 38 if (priv == NULL || bulkdata == NULL || buffered_pkt == NULL){
40 return; 39 return;
41 } 40 }
41
42 skb = (struct sk_buff*)bulkdata->d[0].os_net_buf_ptr; 42 skb = (struct sk_buff*)bulkdata->d[0].os_net_buf_ptr;
43 align_offset = (CsrUint32)(long)(bulkdata->d[0].os_data_ptr) & (CSR_WIFI_ALIGN_BYTES-1); 43 align_offset = (CsrUint32)(long)(bulkdata->d[0].os_data_ptr) & (CSR_WIFI_ALIGN_BYTES-1);
44 if(align_offset){ 44 if(align_offset){
45 skb_pull(skb,align_offset); 45 skb_pull(skb,align_offset);
46 } 46 }
47 buffered_pkt->bulkdata.os_data_ptr = skb->data;
48 buffered_pkt->bulkdata.data_length = skb->len;
49
50 47
48 buffered_pkt->bulkdata.os_data_ptr = bulkdata->d[0].os_data_ptr;
49 buffered_pkt->bulkdata.data_length = bulkdata->d[0].data_length;
50 buffered_pkt->bulkdata.os_net_buf_ptr = bulkdata->d[0].os_net_buf_ptr;
51 buffered_pkt->bulkdata.net_buf_length = bulkdata->d[0].net_buf_length;
51} 52}
52#endif 53#endif
53 54
@@ -122,7 +123,7 @@ unifi_frame_ma_packet_req(unifi_priv_t *priv, CSR_PRIORITY priority,
122#ifdef CSR_SUPPORT_SME 123#ifdef CSR_SUPPORT_SME
123 124
124#define TRANSMISSION_CONTROL_TRIGGER_MASK 0x0001 125#define TRANSMISSION_CONTROL_TRIGGER_MASK 0x0001
125#define TRANSMISSION_CONTROL_ESOP_MASK 0x0002 126#define TRANSMISSION_CONTROL_EOSP_MASK 0x0002
126 127
127static 128static
128int frame_and_send_queued_pdu(unifi_priv_t* priv,tx_buffered_packets_t* buffered_pkt, 129int frame_and_send_queued_pdu(unifi_priv_t* priv,tx_buffered_packets_t* buffered_pkt,
@@ -167,34 +168,27 @@ int frame_and_send_queued_pdu(unifi_priv_t* priv,tx_buffered_packets_t* buffered
167 case IEEE802_11_FC_TYPE_QOS_DATA & IEEE80211_FC_SUBTYPE_MASK: 168 case IEEE802_11_FC_TYPE_QOS_DATA & IEEE80211_FC_SUBTYPE_MASK:
168 case IEEE802_11_FC_TYPE_QOS_NULL & IEEE80211_FC_SUBTYPE_MASK: 169 case IEEE802_11_FC_TYPE_QOS_NULL & IEEE80211_FC_SUBTYPE_MASK:
169 /* If both are set then the Address4 exists (only for AP) */ 170 /* If both are set then the Address4 exists (only for AP) */
170 if (fromDs && toDs) 171 if (fromDs && toDs) {
171 {
172 /* 6 is the size of Address4 field */ 172 /* 6 is the size of Address4 field */
173 macHeaderLengthInBytes += (QOS_CONTROL_HEADER_SIZE + 6); 173 macHeaderLengthInBytes += (QOS_CONTROL_HEADER_SIZE + 6);
174 } 174 } else {
175 else
176 {
177 macHeaderLengthInBytes += QOS_CONTROL_HEADER_SIZE; 175 macHeaderLengthInBytes += QOS_CONTROL_HEADER_SIZE;
178 } 176 }
179 177
180 /* If order bit set then HT control field is the part of MAC header */ 178 /* If order bit set then HT control field is the part of MAC header */
181 if (*fc & cpu_to_le16(IEEE80211_FC_ORDER_MASK)) { 179 if (*fc & cpu_to_le16(IEEE80211_FC_ORDER_MASK)) {
182 macHeaderLengthInBytes += HT_CONTROL_HEADER_SIZE; 180 macHeaderLengthInBytes += HT_CONTROL_HEADER_SIZE;
181 qc = (CsrUint8*)(buffered_pkt->bulkdata.os_data_ptr + (macHeaderLengthInBytes-6));
182 } else {
183 qc = (CsrUint8*)(buffered_pkt->bulkdata.os_data_ptr + (macHeaderLengthInBytes-2));
183 } 184 }
185 *qc = eosp ? *qc | (1 << 4) : *qc & (~(1 << 4));
184 break; 186 break;
185 default: 187 default:
186 if (fromDs && toDs) 188 if (fromDs && toDs)
187 macHeaderLengthInBytes += 6; 189 macHeaderLengthInBytes += 6;
188 break;
189 } 190 }
190 191
191 if (*fc & cpu_to_le16(IEEE80211_FC_ORDER_MASK)) {
192 qc = (CsrUint8*)(buffered_pkt->bulkdata.os_data_ptr + (macHeaderLengthInBytes-6));
193 } else {
194 qc = (CsrUint8*)(buffered_pkt->bulkdata.os_data_ptr + (macHeaderLengthInBytes-2));
195 }
196
197 *qc = eosp ? *qc | (1 << 4) : *qc & (~(1 << 4));
198 } 192 }
199 result = ul_send_signal_unpacked(priv, &signal, &bulkdata); 193 result = ul_send_signal_unpacked(priv, &signal, &bulkdata);
200 if(result){ 194 if(result){
@@ -254,7 +248,7 @@ void set_eosp_transmit_ctrl(unifi_priv_t *priv, struct list_head *txList)
254 spin_lock_irqsave(&priv->tx_q_lock,lock_flags); 248 spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
255 list_for_each_prev_safe(listHead, placeHolder, txList) { 249 list_for_each_prev_safe(listHead, placeHolder, txList) {
256 tx_q_item = list_entry(listHead, tx_buffered_packets_t, q); 250 tx_q_item = list_entry(listHead, tx_buffered_packets_t, q);
257 tx_q_item->transmissionControl |= TRANSMISSION_CONTROL_ESOP_MASK; 251 tx_q_item->transmissionControl |= TRANSMISSION_CONTROL_EOSP_MASK;
258 tx_q_item->transmissionControl = (tx_q_item->transmissionControl & ~(CSR_NO_CONFIRM_REQUIRED)); 252 tx_q_item->transmissionControl = (tx_q_item->transmissionControl & ~(CSR_NO_CONFIRM_REQUIRED));
259 unifi_trace(priv, UDBG1, 253 unifi_trace(priv, UDBG1,
260 "set_eosp_transmit_ctrl Transmission Control = 0x%x hostTag = 0x%x \n",tx_q_item->transmissionControl,tx_q_item->hostTag); 254 "set_eosp_transmit_ctrl Transmission Control = 0x%x hostTag = 0x%x \n",tx_q_item->transmissionControl,tx_q_item->hostTag);
@@ -275,6 +269,8 @@ void send_vif_availibility_rsp(unifi_priv_t *priv,CSR_VIF_IDENTIFIER vif,CSR_RES
275 bulk_data_param_t *bulkdata = NULL; 269 bulk_data_param_t *bulkdata = NULL;
276 int r; 270 int r;
277 271
272 unifi_trace(priv, UDBG3, "send_vif_availibility_rsp : invoked with resultCode = %d \n", resultCode);
273
278 memset(&signal,0,sizeof(CSR_SIGNAL)); 274 memset(&signal,0,sizeof(CSR_SIGNAL));
279 rsp = &signal.u.MaVifAvailabilityResponse; 275 rsp = &signal.u.MaVifAvailabilityResponse;
280 rsp->VirtualInterfaceIdentifier = vif; 276 rsp->VirtualInterfaceIdentifier = vif;
@@ -288,6 +284,9 @@ void send_vif_availibility_rsp(unifi_priv_t *priv,CSR_VIF_IDENTIFIER vif,CSR_RES
288 if(r) { 284 if(r) {
289 unifi_error(priv,"Availibility response sending failed %x status %d\n",vif,r); 285 unifi_error(priv,"Availibility response sending failed %x status %d\n",vif,r);
290 } 286 }
287 else {
288 unifi_trace(priv, UDBG3, "send_vif_availibility_rsp : status = %d \n", r);
289 }
291} 290}
292#endif 291#endif
293 292
@@ -354,14 +353,14 @@ void verify_and_accomodate_tx_packet(unifi_priv_t *priv)
354 list_for_each_safe(listHead, placeHolder, &interfacePriv->genericMulticastOrBroadCastFrames) { 353 list_for_each_safe(listHead, placeHolder, &interfacePriv->genericMulticastOrBroadCastFrames) {
355 tx_q_item = list_entry(listHead, tx_buffered_packets_t, q); 354 tx_q_item = list_entry(listHead, tx_buffered_packets_t, q);
356 if(eospFramedeleted){ 355 if(eospFramedeleted){
357 tx_q_item->transmissionControl |= TRANSMISSION_CONTROL_ESOP_MASK; 356 tx_q_item->transmissionControl |= TRANSMISSION_CONTROL_EOSP_MASK;
358 tx_q_item->transmissionControl = (tx_q_item->transmissionControl & ~(CSR_NO_CONFIRM_REQUIRED)); 357 tx_q_item->transmissionControl = (tx_q_item->transmissionControl & ~(CSR_NO_CONFIRM_REQUIRED));
359 unifi_trace(priv, UDBG1,"updating eosp for next packet hostTag:= 0x%x ",tx_q_item->hostTag); 358 unifi_trace(priv, UDBG1,"updating eosp for next packet hostTag:= 0x%x ",tx_q_item->hostTag);
360 eospFramedeleted =0; 359 eospFramedeleted =0;
361 break; 360 break;
362 } 361 }
363 362
364 if(tx_q_item->transmissionControl & TRANSMISSION_CONTROL_ESOP_MASK ){ 363 if(tx_q_item->transmissionControl & TRANSMISSION_CONTROL_EOSP_MASK ){
365 eospFramedeleted = 1; 364 eospFramedeleted = 1;
366 } 365 }
367 unifi_trace(priv,UDBG1, "freeing of multicast packets ToC = 0x%x hostTag = 0x%x \n",tx_q_item->transmissionControl,tx_q_item->hostTag); 366 unifi_trace(priv,UDBG1, "freeing of multicast packets ToC = 0x%x hostTag = 0x%x \n",tx_q_item->transmissionControl,tx_q_item->hostTag);
@@ -445,66 +444,162 @@ CsrResult enque_tx_data_pdu(unifi_priv_t *priv, bulk_data_param_t *bulkdata,
445 unifi_trace(priv, UDBG5, "leaving enque_tx_data_pdu\n"); 444 unifi_trace(priv, UDBG5, "leaving enque_tx_data_pdu\n");
446 return CSR_RESULT_SUCCESS; 445 return CSR_RESULT_SUCCESS;
447} 446}
448static 447
449CsrResult enque_direceted_ma_pkt_cfm_data_pdu(unifi_priv_t *priv, bulk_data_param_t *bulkdata, 448#ifdef CSR_WIFI_REQUEUE_PACKET_TO_HAL
450 struct list_head *list, CSR_SIGNAL *signal, 449CsrResult unifi_reque_ma_packet_request (void *ospriv, CsrUint32 host_tag,
451 CsrBool requeueOnSamePos) 450 CsrUint16 txStatus, bulk_data_desc_t *bulkDataDesc)
452{ 451{
452 CsrResult status = CSR_RESULT_SUCCESS;
453 unifi_priv_t *priv = (unifi_priv_t*)ospriv;
454 netInterface_priv_t *interfacePriv;
455 struct list_head *list = NULL;
456 CsrWifiRouterCtrlStaInfo_t *staRecord = NULL;
457 bulk_data_param_t bulkData;
458 CSR_SIGNAL signal;
459 CSR_PRIORITY priority = 0;
460 CsrUint16 interfaceTag = 0;
461 unifi_TrafficQueue priority_q;
462 CsrUint16 frameControl = 0, frameType = 0;
463 unsigned long lock_flags;
453 464
454 /* queue the tx data packets on to appropriate queue */ 465 interfacePriv = priv->interfacePriv[interfaceTag];
455 CSR_MA_PACKET_REQUEST *req = &signal->u.MaPacketRequest;
456 tx_buffered_packets_t *tx_q_item;
457 466
467 /* If the current mode is not AP or P2PGO then just return failure
468 * to clear the hip slot
469 */
470 if(!((interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP) ||
471 (interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO))) {
472 return CSR_RESULT_FAILURE;
473 }
458 474
459 unifi_trace(priv, UDBG5, "entering enque_tx_data_pdu\n"); 475 unifi_trace(priv, UDBG6, "unifi_reque_ma_packet_request: host_tag = 0x%x\n", host_tag);
460 if(!list ) { 476
461 unifi_error(priv,"List is not specified\n"); 477 staRecord = CsrWifiRouterCtrlGetStationRecordFromPeerMacAddress(priv,
462 return CSR_RESULT_FAILURE; 478 (((CsrUint8 *) bulkDataDesc->os_data_ptr) + 4),
479 interfaceTag);
480 if (NULL == staRecord) {
481 unifi_trace(priv, UDBG5, "unifi_reque_ma_packet_request: Invalid STA record \n");
482 return CSR_RESULT_FAILURE;
463 } 483 }
464 if(!requeueOnSamePos && !list->prev){
465 unifi_error(priv,"List prev is NULL so don't requeu it\n");
466 return CSR_RESULT_FAILURE;
467 484
485 /* Update TIM if MA-PACKET.cfm fails with status as Tx-retry-limit or No-BSS and then just return failure
486 * to clear the hip slot associated with the Packet
487 */
488 if (CSR_TX_RETRY_LIMIT == txStatus || CSR_TX_NO_BSS == txStatus) {
489 if (staRecord->timSet == CSR_WIFI_TIM_RESET || staRecord->timSet == CSR_WIFI_TIM_RESETTING)
490 {
491 unifi_trace(priv, UDBG2, "unifi_reque_ma_packet_request: CFM failed with Retry Limit or No BSS-->update TIM\n");
492 if (!staRecord->timRequestPendingFlag) {
493 update_tim(priv, staRecord->aid, 1, interfaceTag, staRecord->assignedHandle);
494 }
495 else {
496 /* Cache the TimSet value so that it will processed immidiatly after
497 * completing the current setTim Request
498 */
499 staRecord->updateTimReqQueued = 1;
500 unifi_trace(priv, UDBG6, "unifi_reque_ma_packet_request: One more UpdateTim Request(:%d)Queued for AID %x\n",
501 staRecord->updateTimReqQueued, staRecord->aid);
502 }
503 }
504 return CSR_RESULT_FAILURE;
468 } 505 }
506 else if ((CSR_TX_LIFETIME == txStatus) || (CSR_TX_BLOCK_ACK_TIMEOUT == txStatus) ||
507 (CSR_TX_FAIL_TRANSMISSION_VIF_INTERRUPTED == txStatus) ||
508 (CSR_TX_REJECTED_PEER_STATION_SLEEPING == txStatus) ||
509 (CSR_TX_REJECTED_DTIM_STARTED == txStatus)) {
510 /* Extract the Frame control and the frame type */
511 frameControl = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(bulkDataDesc->os_data_ptr);
512 frameType = ((frameControl & IEEE80211_FC_TYPE_MASK) >> FRAME_CONTROL_TYPE_FIELD_OFFSET);
469 513
514 /* Mgmt frames will not be re-queued for Tx
515 * so just return failure to clear the hip slot
516 */
517 if (IEEE802_11_FRAMETYPE_MANAGEMENT == frameType) {
518 return CSR_RESULT_FAILURE;
519 }
520 else if (IEEE802_11_FRAMETYPE_DATA == frameType) {
521 /* QOS NULL and DATA NULL frames will not be re-queued for Tx
522 * so just return failure to clear the hip slot
523 */
524 if ((((frameControl & IEEE80211_FC_SUBTYPE_MASK) >> FRAME_CONTROL_SUBTYPE_FIELD_OFFSET) == QOS_DATA_NULL) ||
525 (((frameControl & IEEE80211_FC_SUBTYPE_MASK) >> FRAME_CONTROL_SUBTYPE_FIELD_OFFSET)== DATA_NULL )) {
526 return CSR_RESULT_FAILURE;
527 }
528 }
470 529
530 /* Extract the Packet priority */
531 if (TRUE == staRecord->wmmOrQosEnabled) {
532 CsrUint16 qosControl = 0;
533 CsrUint8 dataFrameType = 0;
471 534
472 tx_q_item = (tx_buffered_packets_t *)kmalloc(sizeof(tx_buffered_packets_t), GFP_ATOMIC); 535 dataFrameType =((frameControl & IEEE80211_FC_SUBTYPE_MASK) >> 4);
473 if (tx_q_item == NULL) {
474 unifi_error(priv,
475 "Failed to allocate %d bytes for tx packet record\n",
476 sizeof(tx_buffered_packets_t));
477 func_exit();
478 return CSR_RESULT_FAILURE;
479 }
480 /* disable the preemption */
481 INIT_LIST_HEAD(&tx_q_item->q);
482 /* fill the tx_q structure members */
483 tx_q_item->bulkdata.os_data_ptr = bulkdata->d[0].os_data_ptr;
484 tx_q_item->bulkdata.data_length = bulkdata->d[0].data_length;
485 tx_q_item->bulkdata.os_net_buf_ptr = bulkdata->d[0].os_net_buf_ptr;
486 tx_q_item->bulkdata.net_buf_length = bulkdata->d[0].net_buf_length;
487 tx_q_item->interfaceTag = req->VirtualInterfaceIdentifier & 0xff;
488 tx_q_item->hostTag = req->HostTag;
489 tx_q_item->leSenderProcessId = signal->SignalPrimitiveHeader.SenderProcessId;
490 tx_q_item->transmissionControl = req->TransmissionControl;
491 tx_q_item->priority = req->Priority;
492 tx_q_item->rate = req->TransmitRate;
493 memcpy(tx_q_item->peerMacAddress.a, req->Ra.x, ETH_ALEN);
494 536
537 if (dataFrameType == QOS_DATA) {
538 /* QoS control field is offset from frame control by 2 (frame control)
539 * + 2 (duration/ID) + 2 (sequence control) + 3*ETH_ALEN or 4*ETH_ALEN
540 */
541 if((frameControl & IEEE802_11_FC_TO_DS_MASK) && (frameControl & IEEE802_11_FC_FROM_DS_MASK)) {
542 qosControl= CSR_GET_UINT16_FROM_LITTLE_ENDIAN(bulkDataDesc->os_data_ptr + 30);
543 }
544 else {
545 qosControl = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(bulkDataDesc->os_data_ptr + 24);
546 }
547 }
495 548
549 priority = (CSR_PRIORITY)(qosControl & IEEE802_11_QC_TID_MASK);
496 550
497 if (requeueOnSamePos) { 551 if (priority < CSR_QOS_UP0 || priority > CSR_QOS_UP7) {
498 list_add(&tx_q_item->q, list); 552 unifi_trace(priv, UDBG5, "unifi_reque_ma_packet_request: Invalid priority:%x \n", priority);
499 } else { 553 return CSR_RESULT_FAILURE;
500 list_add_tail(&tx_q_item->q, list); 554 }
555 }
556 else {
557 priority = CSR_CONTENTION;
558 }
559
560 /* Frame Bulk data to requeue it back to HAL Queues */
561 bulkData.d[0].os_data_ptr = bulkDataDesc->os_data_ptr;
562 bulkData.d[0].data_length = bulkDataDesc->data_length;
563 bulkData.d[0].os_net_buf_ptr = bulkDataDesc->os_net_buf_ptr;
564 bulkData.d[0].net_buf_length = bulkDataDesc->net_buf_length;
565
566 bulkData.d[1].os_data_ptr = NULL;
567 bulkData.d[1].os_net_buf_ptr = NULL;
568 bulkData.d[1].data_length = bulkData.d[1].net_buf_length = 0;
569
570 /* Initialize signal to zero */
571 memset(&signal, 0, sizeof(CSR_SIGNAL));
572
573 /* Frame MA Packet Req */
574 unifi_frame_ma_packet_req(priv, priority, 0, host_tag,
575 interfaceTag, CSR_NO_CONFIRM_REQUIRED,
576 priv->netdev_client->sender_id,
577 staRecord->peerMacAddress.a, &signal);
578
579 /* Find the Q-Priority */
580 priority_q = unifi_frame_priority_to_queue(priority);
581 list = &staRecord->dataPdu[priority_q];
582
583 /* Place the Packet on to HAL Queue */
584 status = enque_tx_data_pdu(priv, &bulkData, list, &signal, TRUE);
585
586 /* Update the Per-station queued packet counter */
587 if (!status) {
588 spin_lock_irqsave(&priv->staRecord_lock, lock_flags);
589 staRecord->noOfPktQueued++;
590 spin_unlock_irqrestore(&priv->staRecord_lock, lock_flags);
591 }
592 }
593 else {
594 /* Packet will not be re-queued for any of the other MA Packet Tx failure
595 * reasons so just return failure to clear the hip slot
596 */
597 return CSR_RESULT_FAILURE;
501 } 598 }
502 599
503 /* Count of packet queued in driver */ 600 return status;
504 priv->noOfPktQueuedInDriver++;
505 unifi_trace(priv, UDBG5, "leaving enque_tx_data_pdu\n");
506 return CSR_RESULT_SUCCESS;
507} 601}
602#endif
508 603
509static void is_all_ac_deliver_enabled_and_moredata(CsrWifiRouterCtrlStaInfo_t *staRecord, CsrUint8 *allDeliveryEnabled, CsrUint8 *dataAvailable) 604static void is_all_ac_deliver_enabled_and_moredata(CsrWifiRouterCtrlStaInfo_t *staRecord, CsrUint8 *allDeliveryEnabled, CsrUint8 *dataAvailable)
510{ 605{
@@ -601,12 +696,53 @@ void uf_handle_tim_cfm(unifi_priv_t *priv, CSR_MLME_SET_TIM_CONFIRM *cfm, CsrUin
601 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", 696 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",
602 receiverProcessId, timSetStatus, staRecord->timSet, handle); 697 receiverProcessId, timSetStatus, staRecord->timSet, handle);
603 } 698 }
699
700 /* Reset TIM pending flag to send next TIM request */
701 staRecord->timRequestPendingFlag = FALSE;
702
703 /* Make sure that one more UpdateTim request is queued, if Queued its value
704 * should be CSR_WIFI_TIM_SET or CSR_WIFI_TIM_RESET
705 */
706 if (0xFF != staRecord->updateTimReqQueued)
707 {
708 /* Process the UpdateTim Request which is queued while previous UpdateTim was in progress */
709 if (staRecord->timSet != staRecord->updateTimReqQueued)
710 {
711 unifi_trace(priv, UDBG2, "uf_handle_tim_cfm : Processing Queued UpdateTimReq \n");
712
713 update_tim(priv, staRecord->aid, staRecord->updateTimReqQueued, interfaceTag, handle);
714
715 staRecord->updateTimReqQueued = 0xFF;
716 }
717 }
604 } else { 718 } else {
719
720 interfacePriv->bcTimSet = timSetValue;
605 /* fh_cmd_q can also be full at some point of time!, 721 /* fh_cmd_q can also be full at some point of time!,
606 * resetting count as queue is cleaned by firmware at this point 722 * resetting count as queue is cleaned by firmware at this point
607 */ 723 */
608 retryCount = 0; 724 retryCount = 0;
609 unifi_trace(priv, UDBG3, "tim (%s) successfully for broadcast frame in firmware\n", (timSetValue)?"SET":"RESET"); 725 unifi_trace(priv, UDBG3, "tim (%s) successfully for broadcast frame in firmware\n", (timSetValue)?"SET":"RESET");
726
727 /* Reset DTIM pending flag to send next DTIM request */
728 interfacePriv->bcTimSetReqPendingFlag = FALSE;
729
730 /* Make sure that one more UpdateDTim request is queued, if Queued its value
731 * should be CSR_WIFI_TIM_SET or CSR_WIFI_TIM_RESET
732 */
733 if (0xFF != interfacePriv->bcTimSetReqQueued)
734 {
735 /* Process the UpdateTim Request which is queued while previous UpdateTim was in progress */
736 if (interfacePriv->bcTimSet != interfacePriv->bcTimSetReqQueued)
737 {
738 unifi_trace(priv, UDBG2, "uf_handle_tim_cfm : Processing Queued UpdateDTimReq \n");
739
740 update_tim(priv, 0, interfacePriv->bcTimSetReqQueued, interfaceTag, 0xFFFFFFFF);
741
742 interfacePriv->bcTimSetReqQueued = 0xFF;
743 }
744 }
745
610 } 746 }
611 break; 747 break;
612 case CSR_RC_INVALID_PARAMETERS: 748 case CSR_RC_INVALID_PARAMETERS:
@@ -684,6 +820,7 @@ void uf_handle_tim_cfm(unifi_priv_t *priv, CSR_MLME_SET_TIM_CONFIRM *cfm, CsrUin
684 default: 820 default:
685 unifi_warning(priv, "tim update request failed resultcode = %x\n", cfm->ResultCode); 821 unifi_warning(priv, "tim update request failed resultcode = %x\n", cfm->ResultCode);
686 } 822 }
823
687 unifi_trace(priv, UDBG2, "leaving %s\n", __FUNCTION__); 824 unifi_trace(priv, UDBG2, "leaving %s\n", __FUNCTION__);
688} 825}
689 826
@@ -733,8 +870,14 @@ void update_tim(unifi_priv_t * priv, CsrUint16 aid, CsrUint8 setTim, CsrUint16 i
733 870
734 unifi_trace(priv, UDBG5, "entering the update_tim routine\n"); 871 unifi_trace(priv, UDBG5, "entering the update_tim routine\n");
735 872
873
736 if (handle == 0xFFFFFFFF) { 874 if (handle == 0xFFFFFFFF) {
737 handle &= CSR_WIFI_BROADCAST_OR_MULTICAST_HANDLE; 875 handle &= CSR_WIFI_BROADCAST_OR_MULTICAST_HANDLE;
876 if (setTim == interfacePriv->bcTimSet)
877 {
878 unifi_trace(priv, UDBG3, "update_tim, Drop:Hdl=%x, timval=%d, globalTim=%d\n", handle, setTim, interfacePriv->bcTimSet);
879 return;
880 }
738 } else if ((handle != 0xFFFFFFFF) && (handle >= UNIFI_MAX_CONNECTIONS)) { 881 } else if ((handle != 0xFFFFFFFF) && (handle >= UNIFI_MAX_CONNECTIONS)) {
739 unifi_warning(priv, "bad station Handle = %x\n", handle); 882 unifi_warning(priv, "bad station Handle = %x\n", handle);
740 return; 883 return;
@@ -785,6 +928,25 @@ void update_tim(unifi_priv_t * priv, CsrUint16 aid, CsrUint8 setTim, CsrUint16 i
785 if (staRecord) { 928 if (staRecord) {
786 staRecord->timSet = oldTimSetStatus ; 929 staRecord->timSet = oldTimSetStatus ;
787 } 930 }
931 else
932 {
933 /* MLME_SET_TIM.req sending failed here for AID0, so revert back our bcTimSet status */
934 interfacePriv->bcTimSet = !setTim;
935 }
936 }
937 else {
938 /* Update tim request pending flag and ensure no more TIM set requests are send
939 for the same station until TIM confirm is received */
940 if (staRecord) {
941 staRecord->timRequestPendingFlag = TRUE;
942 }
943 else
944 {
945 /* Update tim request (for AID 0) pending flag and ensure no more DTIM set requests are send
946 * for the same station until TIM confirm is received
947 */
948 interfacePriv->bcTimSetReqPendingFlag = TRUE;
949 }
788 } 950 }
789 unifi_trace(priv, UDBG5, "leaving the update_tim routine\n"); 951 unifi_trace(priv, UDBG5, "leaving the update_tim routine\n");
790} 952}
@@ -804,12 +966,30 @@ void process_peer_active_transition(unifi_priv_t * priv,
804 966
805 if(IS_DTIM_ACTIVE(interfacePriv->dtimActive,interfacePriv->multicastPduHostTag)) { 967 if(IS_DTIM_ACTIVE(interfacePriv->dtimActive,interfacePriv->multicastPduHostTag)) {
806 /* giving more priority to multicast packets so delaying unicast packets*/ 968 /* giving more priority to multicast packets so delaying unicast packets*/
807 unifi_trace(priv,UDBG2," multicast transmission is going on so resume unicast transmission after DTIM over\n"); 969 unifi_trace(priv,UDBG2, "Multicast transmission is going on so resume unicast transmission after DTIM over\n");
970
971 /* As station is active now, even though AP is not able to send frames to it
972 * because of DTIM, it needs to reset the TIM here
973 */
974 if (!staRecord->timRequestPendingFlag){
975 if((staRecord->timSet == CSR_WIFI_TIM_SET) || (staRecord->timSet == CSR_WIFI_TIM_SETTING)){
976 update_tim(priv, staRecord->aid, 0, interfaceTag, staRecord->assignedHandle);
977 }
978 }
979 else
980 {
981 /* Cache the TimSet value so that it will processed immidiatly after
982 * completing the current setTim Request
983 */
984 staRecord->updateTimReqQueued = 0;
985 unifi_trace(priv, UDBG6, "update_tim : One more UpdateTim Request (Tim value:%d) Queued for AID %x\n", staRecord->updateTimReqQueued,
986 staRecord->aid);
987 }
808 return; 988 return;
809 } 989 }
810 while((buffered_pkt=dequeue_tx_data_pdu(priv, &staRecord->mgtFrames))) { 990 while((buffered_pkt=dequeue_tx_data_pdu(priv, &staRecord->mgtFrames))) {
811 buffered_pkt->transmissionControl &= 991 buffered_pkt->transmissionControl &=
812 ~(TRANSMISSION_CONTROL_TRIGGER_MASK|TRANSMISSION_CONTROL_ESOP_MASK); 992 ~(TRANSMISSION_CONTROL_TRIGGER_MASK|TRANSMISSION_CONTROL_EOSP_MASK);
813 if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staRecord,0,FALSE)) == -ENOSPC) { 993 if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staRecord,0,FALSE)) == -ENOSPC) {
814 unifi_trace(priv, UDBG2, "p_p_a_t:(ENOSPC) Mgt Frame queueing \n"); 994 unifi_trace(priv, UDBG2, "p_p_a_t:(ENOSPC) Mgt Frame queueing \n");
815 /* Enqueue at the head of the queue */ 995 /* Enqueue at the head of the queue */
@@ -828,11 +1008,22 @@ void process_peer_active_transition(unifi_priv_t * priv,
828 kfree(buffered_pkt); 1008 kfree(buffered_pkt);
829 } 1009 }
830 } 1010 }
831 if (staRecord->txSuspend) { 1011 if (!staRecord->timRequestPendingFlag) {
832 if(staRecord->timSet == CSR_WIFI_TIM_SET) { 1012 if (staRecord->txSuspend) {
833 update_tim(priv,staRecord->aid,0,interfaceTag, staRecord->assignedHandle); 1013 if(staRecord->timSet == CSR_WIFI_TIM_SET) {
1014 update_tim(priv,staRecord->aid,0,interfaceTag, staRecord->assignedHandle);
1015 }
1016 return;
834 } 1017 }
835 return; 1018 }
1019 else
1020 {
1021 /* Cache the TimSet value so that it will processed immidiatly after
1022 * completing the current setTim Request
1023 */
1024 staRecord->updateTimReqQueued = 0;
1025 unifi_trace(priv, UDBG6, "update_tim : One more UpdateTim Request (Tim value:%d) Queued for AID %x\n", staRecord->updateTimReqQueued,
1026 staRecord->aid);
836 } 1027 }
837 for(i=3;i>=0;i--) { 1028 for(i=3;i>=0;i--) {
838 if(!spaceAvail[i]) 1029 if(!spaceAvail[i])
@@ -840,7 +1031,7 @@ void process_peer_active_transition(unifi_priv_t * priv,
840 unifi_trace(priv, UDBG6, "p_p_a_t:data pkt sending for AC %d \n",i); 1031 unifi_trace(priv, UDBG6, "p_p_a_t:data pkt sending for AC %d \n",i);
841 while((buffered_pkt=dequeue_tx_data_pdu(priv, &staRecord->dataPdu[i]))) { 1032 while((buffered_pkt=dequeue_tx_data_pdu(priv, &staRecord->dataPdu[i]))) {
842 buffered_pkt->transmissionControl &= 1033 buffered_pkt->transmissionControl &=
843 ~(TRANSMISSION_CONTROL_TRIGGER_MASK|TRANSMISSION_CONTROL_ESOP_MASK); 1034 ~(TRANSMISSION_CONTROL_TRIGGER_MASK|TRANSMISSION_CONTROL_EOSP_MASK);
844 if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staRecord,0,FALSE)) == -ENOSPC) { 1035 if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staRecord,0,FALSE)) == -ENOSPC) {
845 /* Clear the trigger bit transmission control*/ 1036 /* Clear the trigger bit transmission control*/
846 /* Enqueue at the head of the queue */ 1037 /* Enqueue at the head of the queue */
@@ -859,9 +1050,20 @@ void process_peer_active_transition(unifi_priv_t * priv,
859 } 1050 }
860 } 1051 }
861 } 1052 }
862 if((staRecord->timSet == CSR_WIFI_TIM_SET) || (staRecord->timSet == CSR_WIFI_TIM_SETTING)){ 1053 if (!staRecord->timRequestPendingFlag){
863 unifi_trace(priv, UDBG3, "p_p_a_t:resetting tim .....\n"); 1054 if((staRecord->timSet == CSR_WIFI_TIM_SET) || (staRecord->timSet == CSR_WIFI_TIM_SETTING)) {
864 update_tim(priv,staRecord->aid,0,interfaceTag, staRecord->assignedHandle); 1055 unifi_trace(priv, UDBG3, "p_p_a_t:resetting tim .....\n");
1056 update_tim(priv,staRecord->aid,0,interfaceTag, staRecord->assignedHandle);
1057 }
1058 }
1059 else
1060 {
1061 /* Cache the TimSet value so that it will processed immidiatly after
1062 * completing the current setTim Request
1063 */
1064 staRecord->updateTimReqQueued = 0;
1065 unifi_trace(priv, UDBG6, "update_tim : One more UpdateTim Request (Tim value:%d) Queued for AID %x\n", staRecord->updateTimReqQueued,
1066 staRecord->aid);
865 } 1067 }
866 unifi_trace(priv, UDBG5, "leaving process_peer_active_transition\n"); 1068 unifi_trace(priv, UDBG5, "leaving process_peer_active_transition\n");
867} 1069}
@@ -873,14 +1075,6 @@ void uf_process_ma_pkt_cfm_for_ap(unifi_priv_t *priv,CsrUint16 interfaceTag, con
873 netInterface_priv_t *interfacePriv; 1075 netInterface_priv_t *interfacePriv;
874 CsrUint8 i; 1076 CsrUint8 i;
875 CsrWifiRouterCtrlStaInfo_t *staRecord = NULL; 1077 CsrWifiRouterCtrlStaInfo_t *staRecord = NULL;
876 struct list_head *listHeadMaPktreq,*listHeadStaQueue;
877 struct list_head *placeHolderMaPktreq,*placeHolderStaQueue;
878 unsigned long lock_flags;
879 unsigned long lock_flags1;
880 maPktReqList_t *maPktreq = NULL;
881 tx_buffered_packets_t *tx_q_item = NULL;
882 bulk_data_param_t bulkdata;
883 CsrBool entryFound = FALSE;
884 interfacePriv = priv->interfacePriv[interfaceTag]; 1078 interfacePriv = priv->interfacePriv[interfaceTag];
885 1079
886 1080
@@ -892,260 +1086,113 @@ void uf_process_ma_pkt_cfm_for_ap(unifi_priv_t *priv,CsrUint16 interfaceTag, con
892 if(list_empty(&interfacePriv->genericMulticastOrBroadCastMgtFrames) && 1086 if(list_empty(&interfacePriv->genericMulticastOrBroadCastMgtFrames) &&
893 list_empty(&interfacePriv->genericMulticastOrBroadCastFrames)) { 1087 list_empty(&interfacePriv->genericMulticastOrBroadCastFrames)) {
894 unifi_trace(priv,UDBG1,"Resetting multicastTIM"); 1088 unifi_trace(priv,UDBG1,"Resetting multicastTIM");
895 update_tim(priv,0,0,interfaceTag, 0xFFFFFFFF); 1089 if (!interfacePriv->bcTimSetReqPendingFlag)
896 } 1090 {
897 return; 1091 update_tim(priv,0,CSR_WIFI_TIM_RESET,interfaceTag, 0xFFFFFFFF);
898 }
899
900 /* Check if a copy of the same frame (identified by host tag) is queued in driver */
901 spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
902 list_for_each_safe(listHeadMaPktreq, placeHolderMaPktreq, &interfacePriv->directedMaPktReq) {
903 maPktreq = list_entry(listHeadMaPktreq, maPktReqList_t, q);
904 if(maPktreq->hostTag == pkt_cfm->HostTag){
905 entryFound = TRUE;
906 break;
907 }
908 }
909 spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
910
911 if(entryFound){
912
913 /* Monitor the time difference between the MA-PACKET.req and MA-PACKET.cfm */
914 unsigned long timeout;
915 timeout = (long)jiffies - (long)maPktreq->jiffeTime;
916
917 /* convert into milliseconds */
918 timeout = jiffies_to_msecs(timeout);
919 unifi_trace(priv, UDBG3, "Jiffies Time: Host Tag(%x) --> Req(%u) Cfm(%u) Diff (in ms): %u\n",maPktreq->hostTag,maPktreq->jiffeTime, jiffies, timeout);
920
921 if( (timeout/1000) > 1)
922 {
923 unifi_trace(priv, UDBG1, "Confirm time > 2 Seconds: time = %u Status = %x\n", (timeout/1000), pkt_cfm->TransmissionStatus);
924 }
925
926 if( CSR_TX_LIFETIME == pkt_cfm->TransmissionStatus ||
927 CSR_TX_BLOCK_ACK_TIMEOUT== pkt_cfm->TransmissionStatus ||
928 CSR_TX_FAIL_TRANSMISSION_VIF_INTERRUPTED== pkt_cfm->TransmissionStatus ||
929 CSR_TX_REJECTED_PEER_STATION_SLEEPING== pkt_cfm->TransmissionStatus ||
930 CSR_TX_REJECTED_DTIM_STARTED== pkt_cfm->TransmissionStatus ){
931
932 CsrWifiRouterCtrlStaInfo_t *staRecord = interfacePriv->staInfo[maPktreq->staHandler];
933 unifi_TrafficQueue priority_q;
934 struct list_head *list;
935 CsrResult result;
936 CSR_MA_PACKET_REQUEST *req = &maPktreq->signal.u.MaPacketRequest;
937 CsrUint16 ii=0;
938 CsrBool locationFound = FALSE;
939 CsrUint8 *sigbuffer;
940
941 sigbuffer = (CsrUint8*)&maPktreq->signal;
942 if(req->Priority == CSR_MANAGEMENT){
943 list = &staRecord->mgtFrames;
944 unifi_trace(priv,UDBG5,"mgmt list priority %d\n",req->Priority);
945 }
946 else{
947 priority_q= unifi_frame_priority_to_queue(req->Priority);
948 list = &staRecord->dataPdu[priority_q];
949 unifi_trace(priv,UDBG5,"data list priority %d\n",req->Priority);
950 }
951
952 spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
953 list_for_each_safe(listHeadStaQueue, placeHolderStaQueue, list){
954 tx_q_item = list_entry(listHeadStaQueue, tx_buffered_packets_t, q);
955 COMPARE_HOST_TAG_TO_ENQUEUE(tx_q_item->hostTag ,maPktreq->hostTag)
956
957
958 }
959 if(sigbuffer[SIZEOF_SIGNAL_HEADER + 1]){
960 skb_pull(maPktreq->skb,sigbuffer[SIZEOF_SIGNAL_HEADER + 1]);
961 }
962
963 /* enqueue the failed packet sta queue*/
964 bulkdata.d[0].os_net_buf_ptr= (unsigned char*)maPktreq->skb;
965 bulkdata.d[0].os_data_ptr = maPktreq->skb->data;
966 bulkdata.d[0].data_length = bulkdata.d[0].net_buf_length = maPktreq->skb->len;
967 bulkdata.d[1].os_data_ptr = NULL;
968 bulkdata.d[1].os_net_buf_ptr = NULL;
969 bulkdata.d[1].data_length = bulkdata.d[0].net_buf_length = 0;
970 unifi_trace(priv,UDBG4,"Cfm Fail for HosTag = %x with status %d so requeue it\n",maPktreq->hostTag,pkt_cfm->TransmissionStatus );
971 req->TransmissionControl = 0;
972
973 if(!locationFound){
974
975 if(list_empty(list)){
976 result = enque_direceted_ma_pkt_cfm_data_pdu(priv, &bulkdata, list,&maPktreq->signal,1);
977 }
978 else{
979 unifi_trace(priv,UDBG4,"did not find location so add to end of list \n");
980 result = enque_direceted_ma_pkt_cfm_data_pdu(priv, &bulkdata, list,&maPktreq->signal,0);
981 }
982
983
984 }
985
986 else {
987 if(ii > 1){
988 unifi_trace(priv,UDBG4,"find the location in the middle of list \n");
989 result = enque_direceted_ma_pkt_cfm_data_pdu(priv, &bulkdata, listHeadStaQueue,&maPktreq->signal,0);
990
991 }
992 else{
993 unifi_trace(priv,UDBG4," add at begining of list \n");
994 result = enque_direceted_ma_pkt_cfm_data_pdu(priv, &bulkdata, list,&maPktreq->signal,1);
995 } 1092 }
996 } 1093 else
997
998 spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
999
1000 /* Increment the counter */
1001 spin_lock_irqsave(&priv->staRecord_lock,lock_flags1);
1002 staRecord->noOfPktQueued++;
1003 spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags1);
1004
1005
1006
1007
1008 /* after enqueuing update the TIM */
1009 if(CSR_RESULT_SUCCESS == result){
1010 if(CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE == staRecord->currentPeerState) {
1011 if(staRecord->timSet == CSR_WIFI_TIM_RESET || staRecord->timSet == CSR_WIFI_TIM_RESETTING) {
1012 if(!staRecord->wmmOrQosEnabled) {
1013 unifi_trace(priv, UDBG3, "uf_process_ma_pkt_cfm_for_ap :tim set due to unicast pkt & peer in powersave\n");
1014 update_tim(priv,staRecord->aid,1,interfaceTag, staRecord->assignedHandle);
1015 }
1016 else {
1017 /* Check for non delivery enable(i.e trigger enable), all delivery enable & legacy AC for TIM update in firmware */
1018 CsrUint8 allDeliveryEnabled = 0, dataAvailable = 0;
1019 /* Check if all AC's are Delivery Enabled */
1020 is_all_ac_deliver_enabled_and_moredata(staRecord, &allDeliveryEnabled, &dataAvailable);
1021 if (uf_is_more_data_for_non_delivery_ac(staRecord) || (allDeliveryEnabled && dataAvailable)) {
1022 update_tim(priv,staRecord->aid,1,interfaceTag, staRecord->assignedHandle);
1023 }
1024 }
1025 }
1026 }
1027 }
1028 else{
1029 dev_kfree_skb(maPktreq->skb);
1030 }
1031 }
1032 else
1033 {
1034 CsrWifiRouterCtrlStaInfo_t *staRecord = interfacePriv->staInfo[maPktreq->staHandler];
1035 if (CSR_TX_RETRY_LIMIT == pkt_cfm->TransmissionStatus ||
1036 CSR_TX_NO_BSS == pkt_cfm->TransmissionStatus)
1037 {
1038 if (staRecord->timSet == CSR_WIFI_TIM_RESET || staRecord->timSet == CSR_WIFI_TIM_RESETTING)
1039 { 1094 {
1040 unifi_trace(priv, UDBG2, "CFM failed with Retry Limit or No BSS --> update TIM\n"); 1095 /* Cache the DTimSet value so that it will processed immidiatly after
1041 update_tim(priv, staRecord->aid, 1, interfaceTag, staRecord->assignedHandle); 1096 * completing the current setDTim Request
1097 */
1098 interfacePriv->bcTimSetReqQueued = CSR_WIFI_TIM_RESET;
1099 unifi_trace(priv, UDBG2, "uf_process_ma_pkt_cfm_for_ap : One more UpdateDTim Request(%d) Queued \n",
1100 interfacePriv->bcTimSetReqQueued);
1042 } 1101 }
1102
1043 } 1103 }
1044 else if (CSR_TX_SUCCESSFUL == pkt_cfm->TransmissionStatus) 1104 return;
1045 { 1105 }
1046 staRecord->activity_flag = TRUE;
1047 }
1048 unifi_trace(priv, UDBG5, "CFM for HosTag = %x Status = %d, Free SKB reference\n",
1049 maPktreq->hostTag,
1050 pkt_cfm->TransmissionStatus );
1051 1106
1052 dev_kfree_skb(maPktreq->skb); 1107 /* Check if it is a Confirm for null data frame used
1108 * for probing station activity
1109 */
1110 for(i =0; i < UNIFI_MAX_CONNECTIONS; i++) {
1111 staRecord = (CsrWifiRouterCtrlStaInfo_t *) (interfacePriv->staInfo[i]);
1112 if (staRecord && (staRecord->nullDataHostTag == pkt_cfm->HostTag)) {
1113
1114 unifi_trace(priv, UDBG1, "CFM for Inactive probe Null frame (tag = %x, status = %d)\n",
1115 pkt_cfm->HostTag,
1116 pkt_cfm->TransmissionStatus
1117 );
1118 staRecord->nullDataHostTag = INVALID_HOST_TAG;
1119
1120 if(pkt_cfm->TransmissionStatus == CSR_TX_RETRY_LIMIT){
1121 CsrTime now;
1122 CsrTime inactive_time;
1123
1124 unifi_trace(priv, UDBG1, "Nulldata to probe STA ALIVE Failed with retry limit\n");
1125 /* Recheck if there is some activity after null data is sent.
1126 *
1127 * If still there is no activity then send a disconnected indication
1128 * to SME to delete the station record.
1129 */
1130 if (staRecord->activity_flag){
1131 return;
1132 }
1133 now = CsrTimeGet(NULL);
1053 1134
1054 } 1135 if (staRecord->lastActivity > now)
1055 list_del(listHeadMaPktreq); 1136 {
1056 kfree(maPktreq); 1137 /* simple timer wrap (for 1 wrap) */
1138 inactive_time = CsrTimeAdd((CsrTime)CsrTimeSub(CSR_SCHED_TIME_MAX, staRecord->lastActivity),
1139 now);
1140 }
1141 else
1142 {
1143 inactive_time = (CsrTime)CsrTimeSub(now, staRecord->lastActivity);
1144 }
1057 1145
1058 }else{ 1146 if (inactive_time >= STA_INACTIVE_TIMEOUT_VAL)
1059 /* Check if it is a Confirm for null data frame used 1147 {
1060 * for probing station activity 1148 struct list_head send_cfm_list;
1061 */ 1149 CsrUint8 j;
1062 for(i =0; i < UNIFI_MAX_CONNECTIONS; i++) { 1150
1063 staRecord = (CsrWifiRouterCtrlStaInfo_t *) (interfacePriv->staInfo[i]); 1151 /* The SME/NME may be waiting for confirmation for requested frames to this station.
1064 if (staRecord && (staRecord->nullDataHostTag == pkt_cfm->HostTag)) { 1152 * Though this is --VERY UNLIKELY-- in case of station in active mode. But still as a
1065 1153 * a defensive check, it loops through buffered frames for this station and if confirmation
1066 unifi_trace(priv, UDBG1, "CFM for Inactive probe Null frame (tag = %x, status = %d)\n", 1154 * is requested, send auto confirmation with failure status. Also flush the frames so
1067 pkt_cfm->HostTag, 1155 * that these are not processed again in PEER_DEL_REQ handler.
1068 pkt_cfm->TransmissionStatus 1156 */
1069 ); 1157 INIT_LIST_HEAD(&send_cfm_list);
1070 staRecord->nullDataHostTag = INVALID_HOST_TAG;
1071
1072 if(pkt_cfm->TransmissionStatus == CSR_TX_RETRY_LIMIT){
1073 CsrTime now;
1074 CsrTime inactive_time;
1075
1076 unifi_trace(priv, UDBG1, "Nulldata to probe STA ALIVE Failed with retry limit\n");
1077 /* Recheck if there is some activity after null data is sent.
1078 *
1079 * If still there is no activity then send a disconnected indication
1080 * to SME to delete the station record.
1081 */
1082 if (staRecord->activity_flag){
1083 return;
1084 }
1085 now = CsrTimeGet(NULL);
1086 1158
1087 if (staRecord->lastActivity > now) 1159 uf_prepare_send_cfm_list_for_queued_pkts(priv,
1088 { 1160 &send_cfm_list,
1089 /* simple timer wrap (for 1 wrap) */ 1161 &(staRecord->mgtFrames));
1090 inactive_time = CsrTimeAdd((CsrTime)CsrTimeSub(CSR_SCHED_TIME_MAX, staRecord->lastActivity),
1091 now);
1092 }
1093 else
1094 {
1095 inactive_time = (CsrTime)CsrTimeSub(now, staRecord->lastActivity);
1096 }
1097 1162
1098 if (inactive_time >= STA_INACTIVE_TIMEOUT_VAL) 1163 uf_flush_list(priv, &(staRecord->mgtFrames));
1099 {
1100 struct list_head send_cfm_list;
1101 CsrUint8 j;
1102
1103 /* The SME/NME may be waiting for confirmation for requested frames to this station.
1104 * Though this is --VERY UNLIKELY-- in case of station in active mode. But still as a
1105 * a defensive check, it loops through buffered frames for this station and if confirmation
1106 * is requested, send auto confirmation with failure status. Also flush the frames so
1107 * that these are not processed again in PEER_DEL_REQ handler.
1108 */
1109 INIT_LIST_HEAD(&send_cfm_list);
1110 1164
1165 for(j = 0; j < MAX_ACCESS_CATOGORY; j++){
1111 uf_prepare_send_cfm_list_for_queued_pkts(priv, 1166 uf_prepare_send_cfm_list_for_queued_pkts(priv,
1112 &send_cfm_list, 1167 &send_cfm_list,
1113 &(staRecord->mgtFrames)); 1168 &(staRecord->dataPdu[j]));
1114
1115 uf_flush_list(priv, &(staRecord->mgtFrames));
1116 1169
1117 for(j = 0; j < MAX_ACCESS_CATOGORY; j++){ 1170 uf_flush_list(priv,&(staRecord->dataPdu[j]));
1118 uf_prepare_send_cfm_list_for_queued_pkts(priv, 1171 }
1119 &send_cfm_list,
1120 &(staRecord->dataPdu[j]));
1121
1122 uf_flush_list(priv,&(staRecord->dataPdu[j]));
1123 }
1124
1125 send_auto_ma_packet_confirm(priv, staRecord->interfacePriv, &send_cfm_list);
1126 1172
1173 send_auto_ma_packet_confirm(priv, staRecord->interfacePriv, &send_cfm_list);
1127 1174
1128 1175
1129 unifi_warning(priv, "uf_process_ma_pkt_cfm_for_ap: Router Disconnected IND Peer (%x-%x-%x-%x-%x-%x)\n",
1130 staRecord->peerMacAddress.a[0],
1131 staRecord->peerMacAddress.a[1],
1132 staRecord->peerMacAddress.a[2],
1133 staRecord->peerMacAddress.a[3],
1134 staRecord->peerMacAddress.a[4],
1135 staRecord->peerMacAddress.a[5]);
1136 1176
1137 CsrWifiRouterCtrlConnectedIndSend(priv->CSR_WIFI_SME_IFACEQUEUE, 1177 unifi_warning(priv, "uf_process_ma_pkt_cfm_for_ap: Router Disconnected IND Peer (%x-%x-%x-%x-%x-%x)\n",
1138 0, 1178 staRecord->peerMacAddress.a[0],
1139 staRecord->interfacePriv->InterfaceTag, 1179 staRecord->peerMacAddress.a[1],
1140 staRecord->peerMacAddress, 1180 staRecord->peerMacAddress.a[2],
1141 CSR_WIFI_ROUTER_CTRL_PEER_DISCONNECTED); 1181 staRecord->peerMacAddress.a[3],
1142 } 1182 staRecord->peerMacAddress.a[4],
1183 staRecord->peerMacAddress.a[5]);
1143 1184
1185 CsrWifiRouterCtrlConnectedIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,
1186 0,
1187 staRecord->interfacePriv->InterfaceTag,
1188 staRecord->peerMacAddress,
1189 CSR_WIFI_ROUTER_CTRL_PEER_DISCONNECTED);
1144 } 1190 }
1145 else if (pkt_cfm->TransmissionStatus == CSR_TX_SUCCESSFUL) 1191
1146 { 1192 }
1147 staRecord->activity_flag = TRUE; 1193 else if (pkt_cfm->TransmissionStatus == CSR_TX_SUCCESSFUL)
1148 } 1194 {
1195 staRecord->activity_flag = TRUE;
1149 } 1196 }
1150 } 1197 }
1151 } 1198 }
@@ -1336,16 +1383,16 @@ static int update_macheader(unifi_priv_t *priv, struct sk_buff *skb,
1336 CsrResult csrResult; 1383 CsrResult csrResult;
1337 unifi_trace(priv, UDBG5, "normal Data packet, NO QOS \n"); 1384 unifi_trace(priv, UDBG5, "normal Data packet, NO QOS \n");
1338 1385
1339 *priority = CSR_CONTENTION;
1340 if (qosDestination) { 1386 if (qosDestination) {
1341 CsrUint8 qc = 0; 1387 CsrUint8 qc = 0;
1342 unifi_trace(priv, UDBG3, "destination is QOS station \n"); 1388 unifi_trace(priv, UDBG3, "destination is QOS station \n");
1343 /* prepare the qos control field */
1344 1389
1345 qc |= CSR_QOS_UP0; 1390 /* Set Ma-Packet.req UP to UP0 */
1391 *priority = CSR_QOS_UP0;
1346 1392
1393 /* prepare the qos control field */
1394 qc |= CSR_QOS_UP0;
1347 /* no Amsdu is in ap buffer so eosp is left 0 */ 1395 /* no Amsdu is in ap buffer so eosp is left 0 */
1348
1349 if (da[0] & 0x1) { 1396 if (da[0] & 0x1) {
1350 /* multicast/broadcast frames, no acknowledgement needed */ 1397 /* multicast/broadcast frames, no acknowledgement needed */
1351 qc |= 1 << 5; 1398 qc |= 1 << 5;
@@ -1763,9 +1810,6 @@ CsrResult uf_process_ma_packet_req(unifi_priv_t *priv,
1763 */ 1810 */
1764 1811
1765 list = &interfacePriv->genericMulticastOrBroadCastMgtFrames; 1812 list = &interfacePriv->genericMulticastOrBroadCastMgtFrames;
1766 spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
1767 interfacePriv->noOfbroadcastPktQueued++;
1768 spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
1769 if((interfacePriv->interfaceMode != CSR_WIFI_ROUTER_CTRL_MODE_IBSS) && 1813 if((interfacePriv->interfaceMode != CSR_WIFI_ROUTER_CTRL_MODE_IBSS) &&
1770 (list_empty(&interfacePriv->genericMulticastOrBroadCastMgtFrames))) { 1814 (list_empty(&interfacePriv->genericMulticastOrBroadCastMgtFrames))) {
1771 setBcTim=TRUE; 1815 setBcTim=TRUE;
@@ -1789,11 +1833,9 @@ CsrResult uf_process_ma_packet_req(unifi_priv_t *priv,
1789 /* if multicast traffic is going on, buffet the unicast packets */ 1833 /* if multicast traffic is going on, buffet the unicast packets */
1790 unifi_trace(priv, UDBG2, "Enqueued to staRecord->dataPdu[%d] queuePacketDozing=%d,\ 1834 unifi_trace(priv, UDBG2, "Enqueued to staRecord->dataPdu[%d] queuePacketDozing=%d,\
1791 Buffering enabled = %d \n", priority_q,queuePacketDozing,isRouterBufferEnabled(priv,priority_q)); 1835 Buffering enabled = %d \n", priority_q,queuePacketDozing,isRouterBufferEnabled(priv,priority_q));
1792 signal.u.MaPacketRequest.TransmissionControl &= ~(CSR_NO_CONFIRM_REQUIRED);
1793 list = &staRecord->dataPdu[priority_q]; 1836 list = &staRecord->dataPdu[priority_q];
1794 } else { 1837 } else {
1795 unifi_trace(priv, UDBG5, "staRecord->dataPdu[%d] list is empty uf_process_ma_packet_req \n", priority_q); 1838 unifi_trace(priv, UDBG5, "staRecord->dataPdu[%d] list is empty uf_process_ma_packet_req \n", priority_q);
1796 signal.u.MaPacketRequest.TransmissionControl &= ~(CSR_NO_CONFIRM_REQUIRED);
1797 /* Pdu allowed to send to unifi */ 1839 /* Pdu allowed to send to unifi */
1798 result = ul_send_signal_unpacked(priv, &signal, bulkdata); 1840 result = ul_send_signal_unpacked(priv, &signal, bulkdata);
1799 if(result == -ENOSPC) { 1841 if(result == -ENOSPC) {
@@ -1816,9 +1858,6 @@ CsrResult uf_process_ma_packet_req(unifi_priv_t *priv,
1816 * will be sent when we receive VIF AVAILABILITY from firmware as part of DTIM 1858 * will be sent when we receive VIF AVAILABILITY from firmware as part of DTIM
1817 */ 1859 */
1818 list = &interfacePriv->genericMulticastOrBroadCastFrames; 1860 list = &interfacePriv->genericMulticastOrBroadCastFrames;
1819 spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
1820 interfacePriv->noOfbroadcastPktQueued++;
1821 spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
1822 if(list_empty(&interfacePriv->genericMulticastOrBroadCastFrames)) { 1861 if(list_empty(&interfacePriv->genericMulticastOrBroadCastFrames)) {
1823 setBcTim = TRUE; 1862 setBcTim = TRUE;
1824 } 1863 }
@@ -1838,10 +1877,30 @@ CsrResult uf_process_ma_packet_req(unifi_priv_t *priv,
1838 staRecord->noOfPktQueued++; 1877 staRecord->noOfPktQueued++;
1839 spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags); 1878 spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
1840 } 1879 }
1880 else if ((pktType == CSR_WIFI_MULTICAST_PDU) && (!status))
1881 {
1882 /* If broadcast Tim is set && queuing is successfull, then only update TIM */
1883 spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
1884 interfacePriv->noOfbroadcastPktQueued++;
1885 spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
1886 }
1841 } 1887 }
1842 if(setBcTim) { 1888 /* If broadcast Tim is set && queuing is successfull, then only update TIM */
1889 if(setBcTim && !status) {
1843 unifi_trace(priv, UDBG3, "tim set due to broadcast pkt\n"); 1890 unifi_trace(priv, UDBG3, "tim set due to broadcast pkt\n");
1844 update_tim(priv,0,1,interfaceTag, handle); 1891 if (!interfacePriv->bcTimSetReqPendingFlag)
1892 {
1893 update_tim(priv,0,CSR_WIFI_TIM_SET,interfaceTag, handle);
1894 }
1895 else
1896 {
1897 /* Cache the TimSet value so that it will processed immidiatly after
1898 * completing the current setTim Request
1899 */
1900 interfacePriv->bcTimSetReqQueued = CSR_WIFI_TIM_SET;
1901 unifi_trace(priv, UDBG2, "uf_process_ma_packet_req : One more UpdateDTim Request(:%d) Queued \n",
1902 interfacePriv->bcTimSetReqQueued);
1903 }
1845 } else if(staRecord && staRecord->currentPeerState == 1904 } else if(staRecord && staRecord->currentPeerState ==
1846 CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE) { 1905 CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE) {
1847 if(staRecord->timSet == CSR_WIFI_TIM_RESET || staRecord->timSet == CSR_WIFI_TIM_RESETTING) { 1906 if(staRecord->timSet == CSR_WIFI_TIM_RESET || staRecord->timSet == CSR_WIFI_TIM_RESETTING) {
@@ -1850,15 +1909,38 @@ CsrResult uf_process_ma_packet_req(unifi_priv_t *priv,
1850 !list_empty(&staRecord->dataPdu[3]) || 1909 !list_empty(&staRecord->dataPdu[3]) ||
1851 !list_empty(&staRecord->dataPdu[UNIFI_TRAFFIC_Q_CONTENTION])) { 1910 !list_empty(&staRecord->dataPdu[UNIFI_TRAFFIC_Q_CONTENTION])) {
1852 unifi_trace(priv, UDBG3, "tim set due to unicast pkt & peer in powersave\n"); 1911 unifi_trace(priv, UDBG3, "tim set due to unicast pkt & peer in powersave\n");
1853 update_tim(priv,staRecord->aid,1,interfaceTag, handle); 1912 if (!staRecord->timRequestPendingFlag){
1913 update_tim(priv,staRecord->aid,1,interfaceTag, handle);
1914 }
1915 else
1916 {
1917 /* Cache the TimSet value so that it will processed immidiatly after
1918 * completing the current setTim Request
1919 */
1920 staRecord->updateTimReqQueued = 1;
1921 unifi_trace(priv, UDBG6, "update_tim : One more UpdateTim Request (Tim value:%d) Queued for AID %x\n", staRecord->updateTimReqQueued,
1922 staRecord->aid);
1923 }
1854 } 1924 }
1855 } else { 1925 } else {
1856 /* Check for non delivery enable(i.e trigger enable), all delivery enable & legacy AC for TIM update in firmware */ 1926 /* Check for non delivery enable(i.e trigger enable), all delivery enable & legacy AC for TIM update in firmware */
1857 CsrUint8 allDeliveryEnabled = 0, dataAvailable = 0; 1927 CsrUint8 allDeliveryEnabled = 0, dataAvailable = 0;
1858 /* Check if all AC's are Delivery Enabled */ 1928 /* Check if all AC's are Delivery Enabled */
1859 is_all_ac_deliver_enabled_and_moredata(staRecord, &allDeliveryEnabled, &dataAvailable); 1929 is_all_ac_deliver_enabled_and_moredata(staRecord, &allDeliveryEnabled, &dataAvailable);
1860 if (uf_is_more_data_for_non_delivery_ac(staRecord) || (allDeliveryEnabled && dataAvailable)) { 1930 if (uf_is_more_data_for_non_delivery_ac(staRecord) || (allDeliveryEnabled && dataAvailable)
1861 update_tim(priv,staRecord->aid,1,interfaceTag, handle); 1931 || (!list_empty(&staRecord->mgtFrames))) {
1932 if (!staRecord->timRequestPendingFlag) {
1933 update_tim(priv,staRecord->aid,1,interfaceTag, handle);
1934 }
1935 else
1936 {
1937 /* Cache the TimSet value so that it will processed immidiatly after
1938 * completing the current setTim Request
1939 */
1940 staRecord->updateTimReqQueued = 1;
1941 unifi_trace(priv, UDBG6, "update_tim : One more UpdateTim Request (Tim value:%d) Queued for AID %x\n", staRecord->updateTimReqQueued,
1942 staRecord->aid);
1943 }
1862 } 1944 }
1863 } 1945 }
1864 } 1946 }
@@ -1945,7 +2027,7 @@ CsrUint8 send_multicast_frames(unifi_priv_t *priv, CsrUint16 interfaceTag)
1945 if(!isRouterBufferEnabled(priv,UNIFI_TRAFFIC_Q_VO)) { 2027 if(!isRouterBufferEnabled(priv,UNIFI_TRAFFIC_Q_VO)) {
1946 while((interfacePriv->dtimActive)&& (buffered_pkt=dequeue_tx_data_pdu(priv,&interfacePriv->genericMulticastOrBroadCastMgtFrames))) { 2028 while((interfacePriv->dtimActive)&& (buffered_pkt=dequeue_tx_data_pdu(priv,&interfacePriv->genericMulticastOrBroadCastMgtFrames))) {
1947 buffered_pkt->transmissionControl |= (TRANSMISSION_CONTROL_TRIGGER_MASK); 2029 buffered_pkt->transmissionControl |= (TRANSMISSION_CONTROL_TRIGGER_MASK);
1948 moreData = (buffered_pkt->transmissionControl & TRANSMISSION_CONTROL_ESOP_MASK)?FALSE:TRUE; 2030 moreData = (buffered_pkt->transmissionControl & TRANSMISSION_CONTROL_EOSP_MASK)?FALSE:TRUE;
1949 2031
1950 2032
1951 unifi_trace(priv,UDBG2,"DTIM Occurred for interface:sending Mgt packet %d\n",interfaceTag); 2033 unifi_trace(priv,UDBG2,"DTIM Occurred for interface:sending Mgt packet %d\n",interfaceTag);
@@ -1986,7 +2068,7 @@ CsrUint8 send_multicast_frames(unifi_priv_t *priv, CsrUint16 interfaceTag)
1986 if(!isRouterBufferEnabled(priv,UNIFI_TRAFFIC_Q_CONTENTION)) { 2068 if(!isRouterBufferEnabled(priv,UNIFI_TRAFFIC_Q_CONTENTION)) {
1987 while((interfacePriv->dtimActive)&& (buffered_pkt=dequeue_tx_data_pdu(priv,&interfacePriv->genericMulticastOrBroadCastFrames))) { 2069 while((interfacePriv->dtimActive)&& (buffered_pkt=dequeue_tx_data_pdu(priv,&interfacePriv->genericMulticastOrBroadCastFrames))) {
1988 buffered_pkt->transmissionControl |= TRANSMISSION_CONTROL_TRIGGER_MASK; 2070 buffered_pkt->transmissionControl |= TRANSMISSION_CONTROL_TRIGGER_MASK;
1989 moreData = (buffered_pkt->transmissionControl & TRANSMISSION_CONTROL_ESOP_MASK)?FALSE:TRUE; 2071 moreData = (buffered_pkt->transmissionControl & TRANSMISSION_CONTROL_EOSP_MASK)?FALSE:TRUE;
1990 2072
1991 2073
1992 if((r=frame_and_send_queued_pdu(priv,buffered_pkt,NULL,moreData,FALSE)) == -ENOSPC) { 2074 if((r=frame_and_send_queued_pdu(priv,buffered_pkt,NULL,moreData,FALSE)) == -ENOSPC) {
@@ -2076,7 +2158,19 @@ void uf_process_ma_vif_availibility_ind(unifi_priv_t *priv,CsrUint8 *sigdata,
2076 if(interfacePriv->multicastPduHostTag == 0xffffffff) { 2158 if(interfacePriv->multicastPduHostTag == 0xffffffff) {
2077 unifi_notice(priv,"ma_vif_availibility_ind recevied for multicast but queues are empty%d\n",interfaceTag); 2159 unifi_notice(priv,"ma_vif_availibility_ind recevied for multicast but queues are empty%d\n",interfaceTag);
2078 /* This may be an extra request in very rare race conditions but it is fine as it would atleast remove the potential lock up */ 2160 /* This may be an extra request in very rare race conditions but it is fine as it would atleast remove the potential lock up */
2079 update_tim(priv,0,0,interfaceTag, 0xFFFFFFFF); 2161 if (!interfacePriv->bcTimSetReqPendingFlag)
2162 {
2163 update_tim(priv,0,CSR_WIFI_TIM_RESET,interfaceTag, 0xFFFFFFFF);
2164 }
2165 else
2166 {
2167 /* Cache the TimSet value so that it will processed immidiatly after
2168 * completing the current setTim Request
2169 */
2170 interfacePriv->bcTimSetReqQueued = CSR_WIFI_TIM_RESET;
2171 unifi_trace(priv, UDBG2, "uf_process_ma_vif_availibility_ind : One more UpdateDTim Request(%d) Queued \n",
2172 interfacePriv->bcTimSetReqQueued);
2173 }
2080 } 2174 }
2081 return; 2175 return;
2082 } 2176 }
@@ -2105,59 +2199,62 @@ void uf_process_ma_vif_availibility_ind(unifi_priv_t *priv,CsrUint8 *sigdata,
2105 2199
2106#define GET_ACTIVE_INTERFACE_TAG(priv) 0 2200#define GET_ACTIVE_INTERFACE_TAG(priv) 0
2107 2201
2108 2202static CsrBool uf_is_more_data_for_delivery_ac(unifi_priv_t *priv, CsrWifiRouterCtrlStaInfo_t *staRecord)
2109void uf_continue_uapsd(unifi_priv_t *priv, CsrWifiRouterCtrlStaInfo_t * staInfo)
2110{ 2203{
2111
2112 CsrInt8 i; 2204 CsrInt8 i;
2113 2205
2114 func_enter(); 2206 for(i=UNIFI_TRAFFIC_Q_VO; i >= UNIFI_TRAFFIC_Q_BK; i--)
2115 2207 {
2116 if(((staInfo->powersaveMode[UNIFI_TRAFFIC_Q_VO]==CSR_WIFI_AC_TRIGGER_AND_DELIVERY_ENABLED)|| 2208 if(((staRecord->powersaveMode[i]==CSR_WIFI_AC_DELIVERY_ONLY_ENABLE)
2117 (staInfo->powersaveMode[UNIFI_TRAFFIC_Q_VO]==CSR_WIFI_AC_DELIVERY_ONLY_ENABLE)) 2209 ||(staRecord->powersaveMode[i]==CSR_WIFI_AC_TRIGGER_AND_DELIVERY_ENABLED))
2118 &&(!list_empty(&staInfo->mgtFrames))){ 2210 &&(!list_empty(&staRecord->dataPdu[i]))) {
2119 2211 unifi_trace(priv,UDBG2,"uf_is_more_data_for_delivery_ac: Data Available AC = %d\n", i);
2120 unifi_trace(priv, UDBG5, "uf_continue_uapsd : U-APSD ACTIVE and sending buffered mgt frames\n"); 2212 return TRUE;
2121 uf_send_buffered_data_from_delivery_ac(priv, staInfo, UNIFI_TRAFFIC_Q_VO, &staInfo->mgtFrames);
2122
2123 /*This may happen because U-APSD was completed
2124 with previous AC transfer*/
2125
2126 if(staInfo->uapsdActive == FALSE) {
2127 return;
2128 } 2213 }
2129 } 2214 }
2130 2215
2131 for(i=3;i>=0;i--) { 2216 unifi_trace(priv,UDBG2,"uf_is_more_data_for_delivery_ac: Data NOT Available \n");
2217 return FALSE;
2218}
2132 2219
2133 if(((staInfo->powersaveMode[i]== CSR_WIFI_AC_DELIVERY_ONLY_ENABLE) 2220static CsrBool uf_is_more_data_for_usp_delivery(unifi_priv_t *priv, CsrWifiRouterCtrlStaInfo_t *staRecord, unifi_TrafficQueue queue)
2134 ||(staInfo->powersaveMode[i] == CSR_WIFI_AC_TRIGGER_AND_DELIVERY_ENABLED)) 2221{
2135 &&(!list_empty(&staInfo->dataPdu[i]))) { 2222 CsrInt8 i;
2136 unifi_trace(priv, UDBG5, "uf_continue_uapsd : U-APSD ACTIVE and sending buffered data frames\n");
2137 uf_send_buffered_data_from_delivery_ac(priv, staInfo, i, &staInfo->dataPdu[i]);
2138 }
2139 2223
2140 /*This may happen because U-APSD was completed 2224 for(i = queue; i >= UNIFI_TRAFFIC_Q_BK; i--)
2141 with previous AC transfer*/ 2225 {
2142 if (staInfo->uapsdActive == FALSE) { 2226 if(((staRecord->powersaveMode[i]==CSR_WIFI_AC_DELIVERY_ONLY_ENABLE)
2143 return; 2227 ||(staRecord->powersaveMode[i]==CSR_WIFI_AC_TRIGGER_AND_DELIVERY_ENABLED))
2228 &&(!list_empty(&staRecord->dataPdu[i]))) {
2229 unifi_trace(priv,UDBG2,"uf_is_more_data_for_usp_delivery: Data Available AC = %d\n", i);
2230 return TRUE;
2144 } 2231 }
2145 } 2232 }
2146 2233
2147 if (staInfo->uapsdActive && !uf_is_more_data_for_delivery_ac(priv, staInfo, TRUE)) { 2234 unifi_trace(priv,UDBG2,"uf_is_more_data_for_usp_delivery: Data NOT Available \n");
2148 /* If last packet not able to transfer due to ENOSPC & buffer management algorithm 2235 return FALSE;
2149 * would have removed last packet. Then we wont update staInfo->UapsdActive = FALSE (suppose
2150 * to update as we dont have packet to transfer at this USP) because above if loop fails as list is empty &
2151 * update of UAPSD activity done in uf_send_buffered_data_from_delivery_ac().
2152 * In this situation we send QOS null & mean time update UapsdActive to FALSE here
2153 */
2154 staInfo->uapsdActive = FALSE;
2155 uf_send_qos_null(priv, GET_ACTIVE_INTERFACE_TAG(priv), staInfo->peerMacAddress.a, CSR_QOS_UP0 , staInfo);
2156 }
2157 func_exit();
2158} 2236}
2159 2237
2160 2238/*
2239 * ---------------------------------------------------------------------------
2240 * uf_send_buffered_data_from_delivery_ac
2241 *
2242 * This function takes care of
2243 * -> Parsing the delivery enabled queue & sending frame down to HIP
2244 * -> Setting EOSP=1 when USP to be terminated
2245 * -> Depending on MAX SP length services the USP
2246 *
2247 * NOTE:This function always called from uf_handle_uspframes_delivery(), Dont
2248 * call this function from any other location in code
2249 *
2250 * Arguments:
2251 * priv Pointer to device private context struct
2252 * vif interface specific HIP vif instance
2253 * staInfo peer for which UAPSD to be scheduled
2254 * queue AC from which Data to be sent in USP
2255 * txList access category for processing list
2256 * ---------------------------------------------------------------------------
2257 */
2161void uf_send_buffered_data_from_delivery_ac(unifi_priv_t *priv, 2258void uf_send_buffered_data_from_delivery_ac(unifi_priv_t *priv,
2162 CsrWifiRouterCtrlStaInfo_t * staInfo, 2259 CsrWifiRouterCtrlStaInfo_t * staInfo,
2163 CsrUint8 queue, 2260 CsrUint8 queue,
@@ -2170,117 +2267,94 @@ void uf_send_buffered_data_from_delivery_ac(unifi_priv_t *priv,
2170 CsrBool eosp=FALSE; 2267 CsrBool eosp=FALSE;
2171 CsrInt8 r =0; 2268 CsrInt8 r =0;
2172 CsrBool moreData = FALSE; 2269 CsrBool moreData = FALSE;
2270 netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
2173 2271
2174 CsrUint8 allDeliveryEnabled = 0, dataAvailable = 0; 2272 unifi_trace(priv, UDBG2, "++uf_send_buffered_data_from_delivery_ac, active=%x\n", staInfo->uapsdActive);
2175 netInterface_priv_t *interfacePriv;
2176 interfacePriv = priv->interfacePriv[interfaceTag];
2177 func_enter();
2178
2179 /*Check U-APSD conditions if not met return from here*/
2180 if((staInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE)&&
2181 (staInfo->uapsdActive == TRUE)&&
2182 (!IS_DELIVERY_AND_TRIGGER_ENABLED(staInfo->powersaveMode[queue]))){
2183
2184 unifi_trace(priv,UDBG4,"uf_send_buffered_data_from_queue : U-APSD active. %d :Queue NOT delivery enbaled.return %\n",queue);
2185 2273
2274 if (queue > UNIFI_TRAFFIC_Q_VO)
2275 {
2186 return; 2276 return;
2187 } 2277 }
2278 while((buffered_pkt=dequeue_tx_data_pdu(priv, txList))) {
2279 if((IS_DTIM_ACTIVE(interfacePriv->dtimActive,interfacePriv->multicastPduHostTag))) {
2280 unifi_trace(priv, UDBG2, "uf_send_buffered_data_from_delivery_ac: DTIM Active, suspend UAPSD, staId: 0x%x\n",
2281 staInfo->aid);
2188 2282
2189 while(!isRouterBufferEnabled(priv,queue) && 2283 /* Once resume called, the U-APSD delivery operation will resume */
2190 ((buffered_pkt=dequeue_tx_data_pdu(priv, txList))!=NULL)){
2191 if((IS_DTIM_ACTIVE(interfacePriv->dtimActive,interfacePriv->multicastPduHostTag))){
2192 spin_lock_irqsave(&priv->staRecord_lock,lock_flags); 2284 spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
2193 staInfo->uapsdSuspended = TRUE; 2285 staInfo->uspSuspend = TRUE;
2194 staInfo->uapsdActive = FALSE;
2195 spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags); 2286 spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
2196 /* re-queueing the packet as DTIM started */ 2287 /* re-queueing the packet as DTIM started */
2197 spin_lock_irqsave(&priv->tx_q_lock,lock_flags); 2288 spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
2198 list_add(&buffered_pkt->q,txList); 2289 list_add(&buffered_pkt->q,txList);
2199 spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags); 2290 spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
2200 unifi_trace(priv, UDBG3, "%s: DTIM Active while UAPSD in progress for staId: 0x%x\n",__FUNCTION__,staInfo->aid);
2201 break; 2291 break;
2202 } 2292 }
2203 2293
2204 buffered_pkt->transmissionControl &= 2294 buffered_pkt->transmissionControl &=
2205 ~(TRANSMISSION_CONTROL_TRIGGER_MASK|TRANSMISSION_CONTROL_ESOP_MASK); 2295 ~(TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK);
2206
2207 2296
2208 if((staInfo->wmmOrQosEnabled == TRUE)&&(staInfo->uapsdActive == TRUE)){
2209 2297
2210 moreData = uf_is_more_data_for_delivery_ac(priv,staInfo,TRUE); 2298 if((staInfo->wmmOrQosEnabled == TRUE)&&(staInfo->uapsdActive == TRUE)) {
2211 2299
2212 buffered_pkt->transmissionControl = TRANSMISSION_CONTROL_TRIGGER_MASK; 2300 buffered_pkt->transmissionControl = TRANSMISSION_CONTROL_TRIGGER_MASK;
2213 2301
2214 if(staInfo->noOfSpFramesSent == (staInfo->maxSpLength-1)){ 2302 /* Check All delivery enables Ac for more data, because caller of this
2215 moreData = FALSE; 2303 * function not aware about last packet
2216 } 2304 * (First check in moreData fetching helps in draining out Mgt frames Q)
2217 2305 */
2218 if(moreData == FALSE){ 2306 moreData = (!list_empty(txList) || uf_is_more_data_for_usp_delivery(priv, staInfo, queue));
2219 eosp = TRUE;
2220 staInfo->uapsdActive = FALSE;
2221 staInfo->noOfSpFramesSent = FALSE;
2222 buffered_pkt->transmissionControl =
2223 (TRANSMISSION_CONTROL_TRIGGER_MASK|TRANSMISSION_CONTROL_ESOP_MASK);
2224 2307
2225 /* Check if all AC's are Delivery Enabled */ 2308 if(staInfo->noOfSpFramesSent == (staInfo->maxSpLength - 1)) {
2226 is_all_ac_deliver_enabled_and_moredata(staInfo, &allDeliveryEnabled, &dataAvailable); 2309 moreData = FALSE;
2227 if ((allDeliveryEnabled && !dataAvailable)) { 2310 }
2228 update_tim(priv,staInfo->aid,0,interfaceTag, staInfo->assignedHandle);
2229 }
2230 /* check the moer data for non delivery ac and update accordingly */
2231 else if(uf_is_more_data_for_non_delivery_ac(staInfo) ) {
2232 update_tim(priv,staInfo->aid,1,interfaceTag, staInfo->assignedHandle);
2233 }
2234 else if(!uf_is_more_data_for_non_delivery_ac(staInfo) ){
2235 unifi_trace(priv, UDBG3, "more data = NULL, set tim to 0 in uf_send_buffered_data_from_delivery_ac\n");
2236 update_tim(priv,staInfo->aid,0,interfaceTag, staInfo->assignedHandle);
2237 }
2238 2311
2239 } 2312 if(moreData == FALSE) {
2240 } 2313 eosp = TRUE;
2241 else 2314 buffered_pkt->transmissionControl =
2242 { 2315 (TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK);
2243 /*Non QoS and non U-APSD.*/ 2316 }
2244 eosp = FALSE; 2317 } else {
2245 moreData = FALSE; 2318 /* Non QoS and non U-APSD */
2246 unifi_warning(priv,"uf_send_buffered_data_from_delivery_ac :non U-APSD !!! \n"); 2319 unifi_warning(priv, "uf_send_buffered_data_from_delivery_ac: non U-APSD !!! \n");
2247 } 2320 }
2248 2321
2249 unifi_trace(priv,UDBG2,"uf_send_buffered_data_from_delivery_ac : MoreData:%d, EOSP:%d\n",moreData,eosp); 2322 unifi_trace(priv,UDBG2,"uf_send_buffered_data_from_delivery_ac : MoreData:%d, EOSP:%d\n",moreData,eosp);
2250 2323
2251 if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staInfo,moreData,eosp)) == -ENOSPC) { 2324 if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staInfo,moreData,eosp)) == -ENOSPC) {
2252 /* Enqueue at the head of the queue */ 2325
2253 spin_lock_irqsave(&priv->tx_q_lock,lock_flags); 2326 unifi_trace(priv, UDBG2, "uf_send_buffered_data_from_delivery_ac: UASPD suspended, ENOSPC in hipQ=%x\n", queue);
2254 list_add(&buffered_pkt->q,txList); 2327
2255 spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags); 2328 /* Once resume called, the U-APSD delivery operation will resume */
2256 priv->pausedStaHandle[queue]=(CsrUint8)(staInfo->assignedHandle); 2329 spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
2257 unifi_notice (priv," U-APSD: PDU sending failed .. no space for queue %d \n",queue); 2330 staInfo->uspSuspend = TRUE;
2258 /*Break the loop for this queue.Try for next available Delivery enabled 2331 spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
2259 Queue*/ 2332
2260 break; 2333 spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
2334 list_add(&buffered_pkt->q,txList);
2335 spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
2336 priv->pausedStaHandle[queue]=(CsrUint8)(staInfo->assignedHandle);
2337 break;
2261 } else { 2338 } else {
2262 if(r){ 2339 if(r){
2263 /* the PDU failed where we can't do any thing so free the storage */ 2340 /* the PDU failed where we can't do any thing so free the storage */
2264 unifi_net_data_free(priv, &buffered_pkt->bulkdata); 2341 unifi_net_data_free(priv, &buffered_pkt->bulkdata);
2265 } 2342 }
2266
2267 kfree(buffered_pkt); 2343 kfree(buffered_pkt);
2268 if(staInfo->uapsdActive == TRUE){ 2344 spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
2269 spin_lock_irqsave(&priv->staRecord_lock,lock_flags); 2345 staInfo->noOfSpFramesSent++;
2270 staInfo->noOfSpFramesSent = staInfo->noOfSpFramesSent + 1; 2346 if((!moreData) || (staInfo->noOfSpFramesSent == staInfo->maxSpLength)) {
2271 if(staInfo->noOfSpFramesSent == staInfo->maxSpLength){ 2347 unifi_trace(priv, UDBG2, "uf_send_buffered_data_from_delivery_ac: Terminating USP\n");
2272 staInfo->uapsdActive = FALSE; 2348 staInfo->uapsdActive = FALSE;
2273 staInfo->noOfSpFramesSent = FALSE; 2349 staInfo->uspSuspend = FALSE;
2274 spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags); 2350 staInfo->noOfSpFramesSent = 0;
2275 break;
2276 }
2277 spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags); 2351 spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
2352 break;
2278 } 2353 }
2354 spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
2279 } 2355 }
2280 } 2356 }
2281 2357 unifi_trace(priv, UDBG2, "--uf_send_buffered_data_from_delivery_ac, active=%x\n", staInfo->uapsdActive);
2282 func_exit();
2283
2284} 2358}
2285 2359
2286void uf_send_buffered_data_from_ac(unifi_priv_t *priv, 2360void uf_send_buffered_data_from_ac(unifi_priv_t *priv,
@@ -2302,7 +2376,7 @@ void uf_send_buffered_data_from_ac(unifi_priv_t *priv,
2302 ((buffered_pkt=dequeue_tx_data_pdu(priv, txList))!=NULL)){ 2376 ((buffered_pkt=dequeue_tx_data_pdu(priv, txList))!=NULL)){
2303 2377
2304 buffered_pkt->transmissionControl &= 2378 buffered_pkt->transmissionControl &=
2305 ~(TRANSMISSION_CONTROL_TRIGGER_MASK|TRANSMISSION_CONTROL_ESOP_MASK); 2379 ~(TRANSMISSION_CONTROL_TRIGGER_MASK|TRANSMISSION_CONTROL_EOSP_MASK);
2306 2380
2307 unifi_trace(priv,UDBG3,"uf_send_buffered_data_from_ac : MoreData:%d, EOSP:%d\n",moreData,eosp); 2381 unifi_trace(priv,UDBG3,"uf_send_buffered_data_from_ac : MoreData:%d, EOSP:%d\n",moreData,eosp);
2308 2382
@@ -2352,7 +2426,19 @@ void uf_send_buffered_frames(unifi_priv_t *priv,unifi_TrafficQueue q)
2352 moreData = (!list_empty(&interfacePriv->genericMulticastOrBroadCastMgtFrames) || 2426 moreData = (!list_empty(&interfacePriv->genericMulticastOrBroadCastMgtFrames) ||
2353 !list_empty(&interfacePriv->genericMulticastOrBroadCastFrames)); 2427 !list_empty(&interfacePriv->genericMulticastOrBroadCastFrames));
2354 if(!moreData) { 2428 if(!moreData) {
2355 update_tim(priv,0,0,interfaceTag, 0XFFFFFFFF); 2429 if (!interfacePriv->bcTimSetReqPendingFlag)
2430 {
2431 update_tim(priv,0,CSR_WIFI_TIM_RESET,interfaceTag, 0XFFFFFFFF);
2432 }
2433 else
2434 {
2435 /* Cache the TimSet value so that it will processed immidiatly after
2436 * completing the current setTim Request
2437 */
2438 interfacePriv->bcTimSetReqQueued = CSR_WIFI_TIM_RESET;
2439 unifi_trace(priv, UDBG2, "uf_send_buffered_frames : One more UpdateDTim Request(%d) Queued \n",
2440 interfacePriv->bcTimSetReqQueued);
2441 }
2356 } 2442 }
2357 } else { 2443 } else {
2358 moreData = (!list_empty(&interfacePriv->genericMulticastOrBroadCastMgtFrames) || 2444 moreData = (!list_empty(&interfacePriv->genericMulticastOrBroadCastMgtFrames) ||
@@ -2391,33 +2477,17 @@ void uf_send_buffered_frames(unifi_priv_t *priv,unifi_TrafficQueue q)
2391 uf_send_buffered_data_from_ac(priv,staInfo, UNIFI_TRAFFIC_Q_VO, &staInfo->mgtFrames); 2477 uf_send_buffered_data_from_ac(priv,staInfo, UNIFI_TRAFFIC_Q_VO, &staInfo->mgtFrames);
2392 } 2478 }
2393 } 2479 }
2394 else if((staInfo != NULL)&&(staInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE)
2395 &&(staInfo->uapsdActive == TRUE)&&(IS_DELIVERY_AND_TRIGGER_ENABLED(staInfo->powersaveMode[UNIFI_TRAFFIC_Q_VO]))){
2396
2397
2398 if(!list_empty(&staInfo->mgtFrames)){
2399 /*UNIFI_TRAFFIC_Q_VO is delivery enabled push the managment frames out*/
2400 uf_send_buffered_data_from_delivery_ac(priv, staInfo, UNIFI_TRAFFIC_Q_VO, &staInfo->mgtFrames);
2401
2402 }
2403 }
2404 2480
2405 if(isRouterBufferEnabled(priv,queue)) { 2481 if(isRouterBufferEnabled(priv,queue)) {
2406 unifi_notice(priv,"uf_send_buffered_frames : No space Left for queue = %d\n",queue); 2482 unifi_notice(priv,"uf_send_buffered_frames : No space Left for queue = %d\n",queue);
2407 break; 2483 break;
2408 } 2484 }
2409 } 2485 }
2410
2411
2412 /*push generic management frames out*/ 2486 /*push generic management frames out*/
2413 2487 if(!list_empty(&interfacePriv->genericMgtFrames)) {
2414 if(!list_empty(&interfacePriv->genericMgtFrames)){ 2488 unifi_trace(priv,UDBG2,"uf_send_buffered_frames : trying generic mgt from queue=%d\n",queue);
2415 2489 uf_send_buffered_data_from_ac(priv,staInfo, UNIFI_TRAFFIC_Q_VO, &interfacePriv->genericMgtFrames);
2416 unifi_trace(priv,UDBG2,"uf_send_buffered_frames : trying generic mgt from queue=%d\n",queue);
2417 uf_send_buffered_data_from_ac(priv,staInfo, UNIFI_TRAFFIC_Q_VO, &interfacePriv->genericMgtFrames);
2418
2419 } 2490 }
2420
2421 } 2491 }
2422 2492
2423 2493
@@ -2431,14 +2501,14 @@ void uf_send_buffered_frames(unifi_priv_t *priv,unifi_TrafficQueue q)
2431 staInfo = CsrWifiRouterCtrlGetStationRecordFromHandle(priv,startIndex,interfaceTag); 2501 staInfo = CsrWifiRouterCtrlGetStationRecordFromHandle(priv,startIndex,interfaceTag);
2432 if(!staInfo) { 2502 if(!staInfo) {
2433 startIndex ++; 2503 startIndex ++;
2434 if(startIndex >= UNIFI_MAX_CONNECTIONS){ 2504 if(startIndex >= UNIFI_MAX_CONNECTIONS) {
2435 startIndex = 0; 2505 startIndex = 0;
2436 } 2506 }
2437 continue; 2507 continue;
2438 } else if((staInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE) 2508 } else if((staInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE)
2439 &&(staInfo->uapsdActive == FALSE)){ 2509 &&(staInfo->uapsdActive == FALSE)) {
2440 startIndex ++; 2510 startIndex ++;
2441 if(startIndex >= UNIFI_MAX_CONNECTIONS){ 2511 if(startIndex >= UNIFI_MAX_CONNECTIONS) {
2442 startIndex = 0; 2512 startIndex = 0;
2443 } 2513 }
2444 continue; 2514 continue;
@@ -2448,23 +2518,15 @@ void uf_send_buffered_frames(unifi_priv_t *priv,unifi_TrafficQueue q)
2448 2518
2449 2519
2450 if((staInfo != NULL)&&(staInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_ACTIVE) 2520 if((staInfo != NULL)&&(staInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_ACTIVE)
2451 &&(staInfo->uapsdActive == FALSE)){ 2521 &&(staInfo->uapsdActive == FALSE)) {
2522 if(!list_empty(&staInfo->dataPdu[queue])) {
2452 2523
2453 if(!list_empty(&staInfo->dataPdu[queue])){ 2524 /*Non-UAPSD case push the AC frames out*/
2454 2525 uf_send_buffered_data_from_ac(priv, staInfo, queue, (&staInfo->dataPdu[queue]));
2455 /*Non-UAPSD case push the AC frames out*/
2456 uf_send_buffered_data_from_ac(priv, staInfo, queue, (&staInfo->dataPdu[queue]));
2457 } 2526 }
2458 } 2527 }
2459 else if((staInfo != NULL)&&(staInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE)
2460 &&(staInfo->uapsdActive == TRUE)&&(IS_DELIVERY_AND_TRIGGER_ENABLED(staInfo->powersaveMode[queue]))){
2461 if(!list_empty(&staInfo->dataPdu[queue])){
2462 uf_send_buffered_data_from_delivery_ac(priv, staInfo, queue, &staInfo->dataPdu[queue]);
2463 }
2464 }
2465
2466 startIndex ++; 2528 startIndex ++;
2467 if(startIndex >= UNIFI_MAX_CONNECTIONS){ 2529 if(startIndex >= UNIFI_MAX_CONNECTIONS) {
2468 startIndex = 0; 2530 startIndex = 0;
2469 } 2531 }
2470 } 2532 }
@@ -2474,47 +2536,14 @@ void uf_send_buffered_frames(unifi_priv_t *priv,unifi_TrafficQueue q)
2474 priv->pausedStaHandle[queue] = 0; 2536 priv->pausedStaHandle[queue] = 0;
2475 } 2537 }
2476 2538
2477 /*U-APSD might have stopped because of pause.So restart it if U-APSD 2539 /* U-APSD might have stopped because of ENOSPC in lib_hip (pause activity).
2478 was active with any of the station*/ 2540 * So restart it if U-APSD was active with any of the station
2479 for(startIndex= 0; startIndex < UNIFI_MAX_CONNECTIONS;startIndex++) { 2541 */
2480 staInfo = CsrWifiRouterCtrlGetStationRecordFromHandle(priv,startIndex,interfaceTag); 2542 unifi_trace(priv, UDBG4, "csrWifiHipSendBufferedFrames: UAPSD Resume Q=%x\n", queue);
2481 if(!staInfo ) { 2543 resume_suspended_uapsd(priv, interfaceTag);
2482 continue;
2483 } else if((staInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE)
2484 &&(staInfo->uapsdActive == TRUE)) {
2485
2486 /*U-APSD Still active, it means trigger frame is received,so continue U-APSD by
2487 sending data from remaining delivery enabled queues*/
2488 uf_continue_uapsd(priv,staInfo);
2489 }
2490 }
2491 func_exit(); 2544 func_exit();
2492} 2545}
2493 2546
2494CsrBool uf_is_more_data_for_delivery_ac(unifi_priv_t *priv,CsrWifiRouterCtrlStaInfo_t *staRecord,CsrBool mgtCheck)
2495{
2496 CsrUint8 i;
2497
2498 for(i=0;i<=3;i++)
2499 {
2500 if(((staRecord->powersaveMode[i]==CSR_WIFI_AC_DELIVERY_ONLY_ENABLE)
2501 ||(staRecord->powersaveMode[i]==CSR_WIFI_AC_TRIGGER_AND_DELIVERY_ENABLED))
2502 &&(!list_empty(&staRecord->dataPdu[i]))){
2503 unifi_trace(priv,UDBG2,"uf_is_more_data_for_delivery_ac: Data Available \n");
2504 return TRUE;
2505 }
2506 }
2507 if((mgtCheck == TRUE)&&(IS_DELIVERY_AND_TRIGGER_ENABLED(staRecord->powersaveMode[UNIFI_TRAFFIC_Q_VO]))
2508 &&(!list_empty(&staRecord->mgtFrames))){
2509
2510 unifi_trace(priv,UDBG2,"uf_is_more_data_for_delivery_ac: Management Data Available \n");
2511
2512 return TRUE;
2513 }
2514
2515 unifi_trace(priv,UDBG2,"uf_is_more_data_for_delivery_ac: Data NOT Available \n");
2516 return FALSE;
2517}
2518 2547
2519CsrBool uf_is_more_data_for_non_delivery_ac(CsrWifiRouterCtrlStaInfo_t *staRecord) 2548CsrBool uf_is_more_data_for_non_delivery_ac(CsrWifiRouterCtrlStaInfo_t *staRecord)
2520{ 2549{
@@ -2584,101 +2613,148 @@ int uf_process_station_records_for_sending_data(unifi_priv_t *priv,CsrUint16 int
2584 return 0; 2613 return 0;
2585} 2614}
2586 2615
2587void uf_process_wmm_deliver_ac_uapsd(unifi_priv_t * priv, 2616
2588 CsrWifiRouterCtrlStaInfo_t * srcStaInfo, 2617/*
2589 CsrUint16 qosControl, 2618 * ---------------------------------------------------------------------------
2590 CsrUint16 interfaceTag) 2619 * uf_handle_uspframes_delivery
2620 *
2621 * This function takes care of handling USP session for peer, when
2622 * -> trigger frame from peer
2623 * -> suspended USP to be processed (resumed)
2624 *
2625 * NOTE: uf_send_buffered_data_from_delivery_ac() always called from this function, Dont
2626 * make a direct call to uf_send_buffered_data_from_delivery_ac() from any other part of
2627 * code
2628 *
2629 * Arguments:
2630 * priv Pointer to device private context struct
2631 * staInfo peer for which UAPSD to be scheduled
2632 * interfaceTag virtual interface tag
2633 * ---------------------------------------------------------------------------
2634 */
2635static void uf_handle_uspframes_delivery(unifi_priv_t * priv, CsrWifiRouterCtrlStaInfo_t *staInfo, CsrUint16 interfaceTag)
2591{ 2636{
2592 2637
2593 CSR_PRIORITY priority;
2594 CsrInt8 i; 2638 CsrInt8 i;
2595 unifi_TrafficQueue priority_q; 2639 CsrUint8 allDeliveryEnabled = 0, dataAvailable = 0;
2640 netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
2596 unsigned long lock_flags; 2641 unsigned long lock_flags;
2597 2642
2598 func_enter(); 2643 unifi_trace(priv, UDBG2, " ++ uf_handle_uspframes_delivery, uapsd active=%x, suspended?=%x\n",
2599 2644 staInfo->uapsdActive, staInfo->uspSuspend);
2600 /* start the U-APSD operation only if it not active*/
2601 if(srcStaInfo->uapsdActive == FALSE){
2602 /*if recceived Frames trigger Frame and Devlivery enabled AC has data
2603 then transmit from High priorty delivery enabled AC*/
2604
2605
2606 priority = (CSR_PRIORITY)(qosControl & IEEE802_11_QC_TID_MASK);
2607 2645
2608 priority_q = unifi_frame_priority_to_queue((CSR_PRIORITY) priority); 2646 /* Check for Buffered frames according to priority order & deliver it
2647 * 1. AC_VO delivery enable & Mgt frames available
2648 * 2. Process remaining Ac's from order AC_VO to AC_BK
2649 */
2609 2650
2610 if((srcStaInfo->powersaveMode[priority_q]==CSR_WIFI_AC_TRIGGER_ONLY_ENABLED) 2651 /* USP initiated by WMMPS enabled peer & SET the status flag to TRUE */
2611 ||(srcStaInfo->powersaveMode[priority_q]==CSR_WIFI_AC_TRIGGER_AND_DELIVERY_ENABLED)){ 2652 if (!staInfo->uspSuspend && staInfo->uapsdActive)
2653 {
2654 unifi_notice(priv, "uf_handle_uspframes_delivery: U-APSD already active! STA=%x:%x:%x:%x:%x:%x\n",
2655 staInfo->peerMacAddress.a[0], staInfo->peerMacAddress.a[1],
2656 staInfo->peerMacAddress.a[2], staInfo->peerMacAddress.a[3],
2657 staInfo->peerMacAddress.a[4], staInfo->peerMacAddress.a[5]);
2658 return;
2659 }
2612 2660
2613 unifi_trace(priv, UDBG3, "uf_process_wmm_deliver_ac_uapsd starting U-APSD operations\n"); 2661 spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
2662 staInfo->uapsdActive = TRUE;
2663 staInfo->uspSuspend = FALSE;
2664 spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
2614 2665
2615 /*Received Frame is trigger frame*/ 2666 if(((staInfo->powersaveMode[UNIFI_TRAFFIC_Q_VO]==CSR_WIFI_AC_TRIGGER_AND_DELIVERY_ENABLED)||
2616 unifi_trace(priv, UDBG5, "uf_process_wmm_deliver_ac_uapsd : Received Frame is trigger frame %d\n",priority_q); 2667 (staInfo->powersaveMode[UNIFI_TRAFFIC_Q_VO]==CSR_WIFI_AC_DELIVERY_ONLY_ENABLE))
2668 && (!list_empty(&staInfo->mgtFrames))) {
2617 2669
2618 if(((srcStaInfo->powersaveMode[UNIFI_TRAFFIC_Q_VO]==CSR_WIFI_AC_TRIGGER_AND_DELIVERY_ENABLED)|| 2670 /* Management queue has data && UNIFI_TRAFFIC_Q_VO is delivery enable */
2619 (srcStaInfo->powersaveMode[UNIFI_TRAFFIC_Q_VO]==CSR_WIFI_AC_DELIVERY_ONLY_ENABLE)) 2671 unifi_trace(priv, UDBG4, "uf_handle_uspframes_delivery: Sending buffered management frames\n");
2620 &&(!list_empty(&srcStaInfo->mgtFrames))){ 2672 uf_send_buffered_data_from_delivery_ac(priv, staInfo, UNIFI_TRAFFIC_Q_VO, &staInfo->mgtFrames);
2673 }
2621 2674
2622 /*Trigger frame received and Data available in Delivery enabled AC 2675 if (!uf_is_more_data_for_delivery_ac(priv, staInfo)) {
2623 or in Management queue when UNIFI_TRAFFIC_Q_VO is delivery enabled*/ 2676 /* All delivery enable AC's are empty, so QNULL to be sent to terminate the USP
2677 * NOTE: If we have sent Mgt frame also, we must send QNULL followed to terminate USP
2678 */
2679 if (!staInfo->uspSuspend) {
2624 spin_lock_irqsave(&priv->staRecord_lock,lock_flags); 2680 spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
2625 srcStaInfo->uapsdActive = TRUE; 2681 staInfo->uapsdActive = FALSE;
2626 spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags); 2682 spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
2627 2683
2628 unifi_trace(priv, UDBG5, "uf_process_wmm_deliver_ac_uapsd : U-APSD ACTIVE and sending buffered mgt frames\n"); 2684 unifi_trace(priv, UDBG2, "uf_handle_uspframes_delivery: sending QNull for trigger\n");
2629 2685 uf_send_qos_null(priv, interfaceTag, staInfo->peerMacAddress.a, (CSR_PRIORITY) staInfo->triggerFramePriority, staInfo);
2630 /* uf_send_buffered_frames(priv, priority_q); */ 2686 staInfo->triggerFramePriority = CSR_QOS_UP0;
2631 uf_send_buffered_data_from_delivery_ac(priv, srcStaInfo, UNIFI_TRAFFIC_Q_VO, &srcStaInfo->mgtFrames); 2687 } else {
2632 2688 unifi_trace(priv, UDBG2, "uf_handle_uspframes_delivery: MgtQ xfer suspended\n");
2633 2689 }
2634 /*This may happen because U-APSD was completed 2690 } else {
2635 with previous AC transfer*/ 2691 for(i = UNIFI_TRAFFIC_Q_VO; i >= UNIFI_TRAFFIC_Q_BK; i--) {
2636 2692 if(((staInfo->powersaveMode[i]==CSR_WIFI_AC_DELIVERY_ONLY_ENABLE)
2637 if(srcStaInfo->uapsdActive == FALSE){ 2693 ||(staInfo->powersaveMode[i]==CSR_WIFI_AC_TRIGGER_AND_DELIVERY_ENABLED))
2638 return; 2694 && (!list_empty(&staInfo->dataPdu[i]))) {
2639 } 2695 /* Deliver Data according to AC priority (from VO to BK) as part of USP */
2640 2696 unifi_trace(priv, UDBG4, "uf_handle_uspframes_delivery: Buffered data frames from Queue (%d) for USP\n", i);
2641 } 2697 uf_send_buffered_data_from_delivery_ac(priv, staInfo, i, &staInfo->dataPdu[i]);
2642 2698 }
2643
2644 for(i=3;i>=0;i--){
2645
2646 if(((srcStaInfo->powersaveMode[i]==CSR_WIFI_AC_DELIVERY_ONLY_ENABLE)
2647 ||(srcStaInfo->powersaveMode[i]==CSR_WIFI_AC_TRIGGER_AND_DELIVERY_ENABLED))
2648 &&(!list_empty(&srcStaInfo->dataPdu[i]))){
2649
2650
2651 /*Trigger frame received and Data available in Delivery enabled AC
2652 or in Management queue when UNIFI_TRAFFIC_Q_VO is delivery enabled*/
2653 spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
2654 srcStaInfo->uapsdActive = TRUE;
2655 spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
2656
2657 unifi_trace(priv, UDBG5, "uf_process_wmm_deliver_ac_uapsd : U-APSD ACTIVE and sending buffered data frames\n");
2658
2659 uf_send_buffered_data_from_delivery_ac(priv, srcStaInfo, i, &srcStaInfo->dataPdu[i]);
2660 2699
2661 /*This may happen because U-APSD was completed 2700 if ((!staInfo->uapsdActive) ||
2662 with previous AC transfer*/ 2701 (staInfo->uspSuspend && IS_DTIM_ACTIVE(interfacePriv->dtimActive,interfacePriv->multicastPduHostTag))) {
2702 /* If DTIM active found on one AC, No need to parse the remaining AC's
2703 * as USP suspended. Break out of loop
2704 */
2705 unifi_trace(priv, UDBG2, "uf_handle_uspframes_delivery: suspend=%x, DTIM=%x, USP terminated=%s\n",
2706 staInfo->uspSuspend, IS_DTIM_ACTIVE(interfacePriv->dtimActive,interfacePriv->multicastPduHostTag),
2707 staInfo->uapsdActive?"NO":"YES");
2708 break;
2709 }
2710 }
2711 }
2663 2712
2664 if(srcStaInfo->uapsdActive == FALSE){ 2713 /* Depending on the USP status, update the TIM accordingly for delivery enabled AC only
2665 return; 2714 * (since we are not manipulating any Non-delivery list(AC))
2666 } 2715 */
2716 is_all_ac_deliver_enabled_and_moredata(staInfo, &allDeliveryEnabled, &dataAvailable);
2717 if ((allDeliveryEnabled && !dataAvailable)) {
2718 if ((staInfo->timSet != CSR_WIFI_TIM_RESET) || (staInfo->timSet != CSR_WIFI_TIM_RESETTING)) {
2719 staInfo->updateTimReqQueued = (CsrUint8) CSR_WIFI_TIM_RESET;
2720 unifi_trace(priv, UDBG4, " --uf_handle_uspframes_delivery, UAPSD timset\n");
2721 if (!staInfo->timRequestPendingFlag) {
2722 update_tim(priv, staInfo->aid, 0, interfaceTag, staInfo->assignedHandle);
2667 } 2723 }
2724 }
2725 }
2726 unifi_trace(priv, UDBG2, " --uf_handle_uspframes_delivery, uapsd active=%x, suspend?=%x\n",
2727 staInfo->uapsdActive, staInfo->uspSuspend);
2728}
2668 2729
2669 } 2730void uf_process_wmm_deliver_ac_uapsd(unifi_priv_t * priv,
2670 if(srcStaInfo->uapsdActive == FALSE && !(uf_is_more_data_for_delivery_ac(priv,srcStaInfo,TRUE))){ 2731 CsrWifiRouterCtrlStaInfo_t * srcStaInfo,
2671 unifi_trace(priv, UDBG3, "uf_process_wmm_deliver_ac_uapsd : No buffer frames so sending QOS Null in response of trigger frame\n"); 2732 CsrUint16 qosControl,
2672 uf_send_qos_null(priv,interfaceTag,srcStaInfo->peerMacAddress.a,priority,srcStaInfo); 2733 CsrUint16 interfaceTag)
2673 } 2734{
2735 CSR_PRIORITY priority;
2736 unifi_TrafficQueue priority_q;
2737 unsigned long lock_flags;
2674 2738
2675 } 2739 unifi_trace(priv, UDBG2, "++uf_process_wmm_deliver_ac_uapsd: uapsdactive?=%x\n", srcStaInfo->uapsdActive);
2740 /* If recceived Frames trigger Frame and Devlivery enabled AC has data
2741 * then transmit from High priorty delivery enabled AC
2742 */
2743 priority = (CSR_PRIORITY)(qosControl & IEEE802_11_QC_TID_MASK);
2744 priority_q = unifi_frame_priority_to_queue((CSR_PRIORITY) priority);
2676 2745
2677 } 2746 if((srcStaInfo->powersaveMode[priority_q]==CSR_WIFI_AC_TRIGGER_ONLY_ENABLED)
2747 ||(srcStaInfo->powersaveMode[priority_q]==CSR_WIFI_AC_TRIGGER_AND_DELIVERY_ENABLED)) {
2748 spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
2749 srcStaInfo->triggerFramePriority = priority;
2750 spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
2751 unifi_trace(priv, UDBG2, "uf_process_wmm_deliver_ac_uapsd: trigger frame, Begin U-APSD, triggerQ=%x\n", priority_q);
2752 uf_handle_uspframes_delivery(priv, srcStaInfo, interfaceTag);
2753 }
2754 unifi_trace(priv, UDBG2, "--uf_process_wmm_deliver_ac_uapsd: uapsdactive?=%x\n", srcStaInfo->uapsdActive);
2755}
2678 2756
2679 func_exit();
2680 2757
2681}
2682void uf_send_qos_null(unifi_priv_t * priv,CsrUint16 interfaceTag, const CsrUint8 *da,CSR_PRIORITY priority,CsrWifiRouterCtrlStaInfo_t * srcStaInfo) 2758void uf_send_qos_null(unifi_priv_t * priv,CsrUint16 interfaceTag, const CsrUint8 *da,CSR_PRIORITY priority,CsrWifiRouterCtrlStaInfo_t * srcStaInfo)
2683{ 2759{
2684 bulk_data_param_t bulkdata; 2760 bulk_data_param_t bulkdata;
@@ -2686,7 +2762,7 @@ void uf_send_qos_null(unifi_priv_t * priv,CsrUint16 interfaceTag, const CsrUint8
2686 struct sk_buff *skb, *newSkb = NULL; 2762 struct sk_buff *skb, *newSkb = NULL;
2687 CsrWifiMacAddress peerAddress; 2763 CsrWifiMacAddress peerAddress;
2688 netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag]; 2764 netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
2689 CSR_TRANSMISSION_CONTROL transmissionControl = (TRANSMISSION_CONTROL_ESOP_MASK | TRANSMISSION_CONTROL_TRIGGER_MASK); 2765 CSR_TRANSMISSION_CONTROL transmissionControl = (TRANSMISSION_CONTROL_EOSP_MASK | TRANSMISSION_CONTROL_TRIGGER_MASK);
2690 int r; 2766 int r;
2691 CSR_SIGNAL signal; 2767 CSR_SIGNAL signal;
2692 CsrUint32 priority_q; 2768 CsrUint32 priority_q;
@@ -2928,7 +3004,19 @@ CsrBool uf_process_pm_bit_for_peer(unifi_priv_t * priv, CsrWifiRouterCtrlStaInfo
2928 !list_empty(&srcStaInfo->dataPdu[UNIFI_TRAFFIC_Q_CONTENTION])); 3004 !list_empty(&srcStaInfo->dataPdu[UNIFI_TRAFFIC_Q_CONTENTION]));
2929 if(moreData && (srcStaInfo->timSet == CSR_WIFI_TIM_RESET)) { 3005 if(moreData && (srcStaInfo->timSet == CSR_WIFI_TIM_RESET)) {
2930 unifi_trace(priv, UDBG3, "This condition should not occur\n"); 3006 unifi_trace(priv, UDBG3, "This condition should not occur\n");
2931 update_tim(priv,srcStaInfo->aid,1,interfaceTag, srcStaInfo->assignedHandle); 3007 if (!srcStaInfo->timRequestPendingFlag){
3008 update_tim(priv,srcStaInfo->aid,1,interfaceTag, srcStaInfo->assignedHandle);
3009 }
3010 else
3011 {
3012 /* Cache the TimSet value so that it will processed immidiatly after
3013 * completing the current setTim Request
3014 */
3015 srcStaInfo->updateTimReqQueued = 1;
3016 unifi_trace(priv, UDBG6, "update_tim : One more UpdateTim Request (Tim value:%d) Queued for AID %x\n", srcStaInfo->updateTimReqQueued,
3017 srcStaInfo->aid);
3018 }
3019
2932 } 3020 }
2933 } else { 3021 } else {
2934 CsrUint8 allDeliveryEnabled = 0, dataAvailable = 0; 3022 CsrUint8 allDeliveryEnabled = 0, dataAvailable = 0;
@@ -2939,7 +3027,18 @@ CsrBool uf_process_pm_bit_for_peer(unifi_priv_t * priv, CsrWifiRouterCtrlStaInfo
2939 moreData = (uf_is_more_data_for_non_delivery_ac(srcStaInfo) || (allDeliveryEnabled && dataAvailable)); 3027 moreData = (uf_is_more_data_for_non_delivery_ac(srcStaInfo) || (allDeliveryEnabled && dataAvailable));
2940 3028
2941 if(moreData && (srcStaInfo->timSet == CSR_WIFI_TIM_RESET)) { 3029 if(moreData && (srcStaInfo->timSet == CSR_WIFI_TIM_RESET)) {
2942 update_tim(priv,srcStaInfo->aid,1,interfaceTag, srcStaInfo->assignedHandle); 3030 if (!srcStaInfo->timRequestPendingFlag){
3031 update_tim(priv,srcStaInfo->aid,1,interfaceTag, srcStaInfo->assignedHandle);
3032 }
3033 else
3034 {
3035 /* Cache the TimSet value so that it will processed immidiatly after
3036 * completing the current setTim Request
3037 */
3038 srcStaInfo->updateTimReqQueued = 1;
3039 unifi_trace(priv, UDBG6, "update_tim : One more UpdateTim Request (Tim value:%d) Queued for AID %x\n", srcStaInfo->updateTimReqQueued,
3040 srcStaInfo->aid);
3041 }
2943 } 3042 }
2944 } 3043 }
2945 } 3044 }
@@ -2993,10 +3092,10 @@ void uf_process_ps_poll(unifi_priv_t *priv,CsrUint8* sa,CsrUint8* da,CsrUint8 pm
2993 !list_empty(&staRecord->dataPdu[UNIFI_TRAFFIC_Q_VO]) || 3092 !list_empty(&staRecord->dataPdu[UNIFI_TRAFFIC_Q_VO]) ||
2994 !list_empty(&staRecord->mgtFrames)); 3093 !list_empty(&staRecord->mgtFrames));
2995 3094
2996 buffered_pkt->transmissionControl |= (TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_ESOP_MASK); 3095 buffered_pkt->transmissionControl |= (TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK);
2997 if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staRecord,moreData,FALSE)) == -ENOSPC) { 3096 if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staRecord,moreData,FALSE)) == -ENOSPC) {
2998 /* Clear the trigger bit transmission control*/ 3097 /* Clear the trigger bit transmission control*/
2999 buffered_pkt->transmissionControl &= ~(TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_ESOP_MASK); 3098 buffered_pkt->transmissionControl &= ~(TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK);
3000 /* Enqueue at the head of the queue */ 3099 /* Enqueue at the head of the queue */
3001 spin_lock_irqsave(&priv->tx_q_lock,lock_flags); 3100 spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
3002 list_add(&buffered_pkt->q, &staRecord->mgtFrames); 3101 list_add(&buffered_pkt->q, &staRecord->mgtFrames);
@@ -3016,10 +3115,10 @@ void uf_process_ps_poll(unifi_priv_t *priv,CsrUint8* sa,CsrUint8* da,CsrUint8 pm
3016 moreData = (!list_empty(&staRecord->dataPdu[UNIFI_TRAFFIC_Q_CONTENTION]) || 3115 moreData = (!list_empty(&staRecord->dataPdu[UNIFI_TRAFFIC_Q_CONTENTION]) ||
3017 !list_empty(&staRecord->dataPdu[UNIFI_TRAFFIC_Q_VO])); 3116 !list_empty(&staRecord->dataPdu[UNIFI_TRAFFIC_Q_VO]));
3018 3117
3019 buffered_pkt->transmissionControl |= (TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_ESOP_MASK); 3118 buffered_pkt->transmissionControl |= (TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK);
3020 if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staRecord,moreData,FALSE)) == -ENOSPC) { 3119 if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staRecord,moreData,FALSE)) == -ENOSPC) {
3021 /* Clear the trigger bit transmission control*/ 3120 /* Clear the trigger bit transmission control*/
3022 buffered_pkt->transmissionControl &= ~(TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_ESOP_MASK); 3121 buffered_pkt->transmissionControl &= ~(TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK);
3023 /* Enqueue at the head of the queue */ 3122 /* Enqueue at the head of the queue */
3024 spin_lock_irqsave(&priv->tx_q_lock,lock_flags); 3123 spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
3025 list_add(&buffered_pkt->q, &staRecord->dataPdu[UNIFI_TRAFFIC_Q_VO]); 3124 list_add(&buffered_pkt->q, &staRecord->dataPdu[UNIFI_TRAFFIC_Q_VO]);
@@ -3038,10 +3137,10 @@ void uf_process_ps_poll(unifi_priv_t *priv,CsrUint8* sa,CsrUint8* da,CsrUint8 pm
3038 buffered_pkt->transmissionControl |= TRANSMISSION_CONTROL_TRIGGER_MASK; 3137 buffered_pkt->transmissionControl |= TRANSMISSION_CONTROL_TRIGGER_MASK;
3039 moreData = !list_empty(&staRecord->dataPdu[UNIFI_TRAFFIC_Q_CONTENTION]); 3138 moreData = !list_empty(&staRecord->dataPdu[UNIFI_TRAFFIC_Q_CONTENTION]);
3040 3139
3041 buffered_pkt->transmissionControl |= (TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_ESOP_MASK); 3140 buffered_pkt->transmissionControl |= (TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK);
3042 if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staRecord,moreData,FALSE)) == -ENOSPC) { 3141 if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staRecord,moreData,FALSE)) == -ENOSPC) {
3043 /* Clear the trigger bit transmission control*/ 3142 /* Clear the trigger bit transmission control*/
3044 buffered_pkt->transmissionControl &= ~(TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_ESOP_MASK); 3143 buffered_pkt->transmissionControl &= ~(TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK);
3045 /* Enqueue at the head of the queue */ 3144 /* Enqueue at the head of the queue */
3046 spin_lock_irqsave(&priv->tx_q_lock,lock_flags); 3145 spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
3047 list_add(&buffered_pkt->q, &staRecord->dataPdu[UNIFI_TRAFFIC_Q_CONTENTION]); 3146 list_add(&buffered_pkt->q, &staRecord->dataPdu[UNIFI_TRAFFIC_Q_CONTENTION]);
@@ -3065,7 +3164,18 @@ void uf_process_ps_poll(unifi_priv_t *priv,CsrUint8* sa,CsrUint8* da,CsrUint8 pm
3065 !list_empty(&staRecord->mgtFrames)); 3164 !list_empty(&staRecord->mgtFrames));
3066 if(!moreData && (staRecord->timSet == CSR_WIFI_TIM_SET)) { 3165 if(!moreData && (staRecord->timSet == CSR_WIFI_TIM_SET)) {
3067 unifi_trace(priv, UDBG3, "more data = NULL, set tim to 0 in uf_process_ps_poll\n"); 3166 unifi_trace(priv, UDBG3, "more data = NULL, set tim to 0 in uf_process_ps_poll\n");
3068 update_tim(priv,staRecord->aid,0,interfaceTag, staRecord->assignedHandle); 3167 if (!staRecord->timRequestPendingFlag){
3168 update_tim(priv,staRecord->aid,0,interfaceTag, staRecord->assignedHandle);
3169 }
3170 else
3171 {
3172 /* Cache the TimSet value so that it will processed immidiatly after
3173 * completing the current setTim Request
3174 */
3175 staRecord->updateTimReqQueued = 0;
3176 unifi_trace(priv, UDBG6, "update_tim : One more UpdateTim Request (Tim value:%d) Queued for AID %x\n", staRecord->updateTimReqQueued,
3177 staRecord->aid);
3178 }
3069 } 3179 }
3070 } else { 3180 } else {
3071 3181
@@ -3074,9 +3184,9 @@ void uf_process_ps_poll(unifi_priv_t *priv,CsrUint8* sa,CsrUint8* da,CsrUint8 pm
3074 3184
3075 /*Send Data From Management Frames*/ 3185 /*Send Data From Management Frames*/
3076 /* Priority orders for delivering the buffered packets are 3186 /* Priority orders for delivering the buffered packets are
3077 * 1. UNIFI_TRAFFIC_Q_VO, if its non delivery enabled 3187 * 1. Deliver the Management frames if there
3078 * 2. management frames 3188 * 2. Other access catagory frames which are non deliver enable including UNIFI_TRAFFIC_Q_VO
3079 * 3. Other access catagory frames which are non deliver enable 3189 * priority is from VO->BK
3080 */ 3190 */
3081 3191
3082 /* Check if all AC's are Delivery Enabled */ 3192 /* Check if all AC's are Delivery Enabled */
@@ -3088,42 +3198,18 @@ void uf_process_ps_poll(unifi_priv_t *priv,CsrUint8* sa,CsrUint8* da,CsrUint8 pm
3088 return; 3198 return;
3089 } 3199 }
3090 3200
3091 if ((!IS_DELIVERY_ENABLED(staRecord->powersaveMode[UNIFI_TRAFFIC_Q_VO])) && 3201 if (!list_empty(&staRecord->mgtFrames)) {
3092 (!list_empty(&staRecord->dataPdu[UNIFI_TRAFFIC_Q_VO]) || !list_empty(&staRecord->mgtFrames))) { 3202 if ((buffered_pkt=dequeue_tx_data_pdu(priv, &staRecord->mgtFrames))) {
3093 /* UNIFI_TRAFFIC_Q_VO is non delivery enabled, & check for packets are there to send from this AC */
3094 if((buffered_pkt=dequeue_tx_data_pdu(priv, &staRecord->dataPdu[UNIFI_TRAFFIC_Q_VO]))) {
3095 moreData = uf_is_more_data_for_non_delivery_ac(staRecord);
3096 buffered_pkt->transmissionControl |= (TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_ESOP_MASK);
3097
3098 /* Last parameter is EOSP & its false always for PS-POLL processing */
3099 if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staRecord,moreData,FALSE)) == -ENOSPC) {
3100 /* Clear the trigger bit transmission control*/
3101 buffered_pkt->transmissionControl &= ~(TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_ESOP_MASK);
3102 /* Enqueue at the head of the queue */
3103 spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
3104 list_add(&buffered_pkt->q, &staRecord->dataPdu[UNIFI_TRAFFIC_Q_VO]);
3105 spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
3106 priv->pausedStaHandle[0]=(CsrUint8)(staRecord->assignedHandle);
3107 unifi_trace(priv, UDBG1, "(ENOSPC) PS-POLL received : PDU sending failed \n");
3108 } else {
3109 if(r){
3110 unifi_trace (priv, UDBG1, " HIP validation failure : PDU sending failed \n");
3111 /* the PDU failed where we can't do any thing so free the storage */
3112 unifi_net_data_free(priv, &buffered_pkt->bulkdata);
3113 }
3114 kfree(buffered_pkt);
3115 }
3116 } else if ((buffered_pkt=dequeue_tx_data_pdu(priv, &staRecord->mgtFrames))) {
3117 /* We dont have packets in non delivery enabled UNIFI_TRAFFIC_Q_VO, So we are looking in management 3203 /* We dont have packets in non delivery enabled UNIFI_TRAFFIC_Q_VO, So we are looking in management
3118 * queue of the station record 3204 * queue of the station record
3119 */ 3205 */
3120 moreData = uf_is_more_data_for_non_delivery_ac(staRecord); 3206 moreData = uf_is_more_data_for_non_delivery_ac(staRecord);
3121 buffered_pkt->transmissionControl |= (TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_ESOP_MASK); 3207 buffered_pkt->transmissionControl |= (TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK);
3122 3208
3123 /* Last parameter is EOSP & its false always for PS-POLL processing */ 3209 /* Last parameter is EOSP & its false always for PS-POLL processing */
3124 if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staRecord,moreData,FALSE)) == -ENOSPC) { 3210 if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staRecord,moreData,FALSE)) == -ENOSPC) {
3125 /* Clear the trigger bit transmission control*/ 3211 /* Clear the trigger bit transmission control*/
3126 buffered_pkt->transmissionControl &= ~(TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_ESOP_MASK); 3212 buffered_pkt->transmissionControl &= ~(TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK);
3127 /* Enqueue at the head of the queue */ 3213 /* Enqueue at the head of the queue */
3128 spin_lock_irqsave(&priv->tx_q_lock,lock_flags); 3214 spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
3129 list_add(&buffered_pkt->q, &staRecord->mgtFrames); 3215 list_add(&buffered_pkt->q, &staRecord->mgtFrames);
@@ -3138,24 +3224,27 @@ void uf_process_ps_poll(unifi_priv_t *priv,CsrUint8* sa,CsrUint8* da,CsrUint8 pm
3138 } 3224 }
3139 kfree(buffered_pkt); 3225 kfree(buffered_pkt);
3140 } 3226 }
3227 } else {
3228 unifi_error(priv, "uf_process_ps_poll: Mgt frame list empty!! \n");
3141 } 3229 }
3230
3142 } else { 3231 } else {
3143 CsrInt8 i; 3232 CsrInt8 i;
3144 /* We dont have buffered packet in UNIFI_TRAFFIC_Q_VO & mangement frame queue (1 & 2 failed), So proceed with 3 condition 3233 /* We dont have buffered packet in mangement frame queue (1 failed), So proceed with condition 2
3145 * UNIFI_TRAFFIC_Q_VO is taken care so start with i index = 2 3234 * UNIFI_TRAFFIC_Q_VO -> VI -> BE -> BK
3146 */ 3235 */
3147 for(i= 2; i>=0; i--) { 3236 for(i= 3; i>=0; i--) {
3148 if (!IS_DELIVERY_ENABLED(staRecord->powersaveMode[i])) { 3237 if (!IS_DELIVERY_ENABLED(staRecord->powersaveMode[i])) {
3149 /* Send One packet, if queue is NULL then continue */ 3238 /* Send One packet, if queue is NULL then continue */
3150 if((buffered_pkt=dequeue_tx_data_pdu(priv, &staRecord->dataPdu[i]))) { 3239 if((buffered_pkt=dequeue_tx_data_pdu(priv, &staRecord->dataPdu[i]))) {
3151 moreData = uf_is_more_data_for_non_delivery_ac(staRecord); 3240 moreData = uf_is_more_data_for_non_delivery_ac(staRecord);
3152 3241
3153 buffered_pkt->transmissionControl |= (TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_ESOP_MASK); 3242 buffered_pkt->transmissionControl |= (TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK);
3154 3243
3155 /* Last parameter is EOSP & its false always for PS-POLL processing */ 3244 /* Last parameter is EOSP & its false always for PS-POLL processing */
3156 if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staRecord,moreData,FALSE)) == -ENOSPC) { 3245 if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staRecord,moreData,FALSE)) == -ENOSPC) {
3157 /* Clear the trigger bit transmission control*/ 3246 /* Clear the trigger bit transmission control*/
3158 buffered_pkt->transmissionControl &= ~(TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_ESOP_MASK); 3247 buffered_pkt->transmissionControl &= ~(TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK);
3159 /* Enqueue at the head of the queue */ 3248 /* Enqueue at the head of the queue */
3160 spin_lock_irqsave(&priv->tx_q_lock,lock_flags); 3249 spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
3161 list_add(&buffered_pkt->q, &staRecord->dataPdu[i]); 3250 list_add(&buffered_pkt->q, &staRecord->dataPdu[i]);
@@ -3181,7 +3270,19 @@ void uf_process_ps_poll(unifi_priv_t *priv,CsrUint8* sa,CsrUint8* da,CsrUint8 pm
3181 moreData = (uf_is_more_data_for_non_delivery_ac(staRecord) || (allDeliveryEnabled && dataAvailable)); 3270 moreData = (uf_is_more_data_for_non_delivery_ac(staRecord) || (allDeliveryEnabled && dataAvailable));
3182 if(!moreData && (staRecord->timSet == CSR_WIFI_TIM_SET)) { 3271 if(!moreData && (staRecord->timSet == CSR_WIFI_TIM_SET)) {
3183 unifi_trace(priv, UDBG3, "more data = NULL, set tim to 0 in uf_process_ps_poll\n"); 3272 unifi_trace(priv, UDBG3, "more data = NULL, set tim to 0 in uf_process_ps_poll\n");
3184 update_tim(priv,staRecord->aid,0,interfaceTag, staRecord->assignedHandle); 3273 if (!staRecord->timRequestPendingFlag){
3274 update_tim(priv,staRecord->aid,0,interfaceTag, staRecord->assignedHandle);
3275 }
3276 else
3277 {
3278 /* Cache the TimSet value so that it will processed immidiatly after
3279 * completing the current setTim Request
3280 */
3281 staRecord->updateTimReqQueued = 0;
3282 unifi_trace(priv, UDBG6, "update_tim : One more UpdateTim Request (Tim value:%d) Queued for AID %x\n", staRecord->updateTimReqQueued,
3283 staRecord->aid);
3284 }
3285
3185 } 3286 }
3186 } 3287 }
3187 3288
@@ -3297,31 +3398,7 @@ void uf_flush_list(unifi_priv_t * priv, struct list_head * list)
3297 } 3398 }
3298 spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags); 3399 spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
3299} 3400}
3300void uf_flush_maPktlist(unifi_priv_t * priv, struct list_head * list)
3301{
3302 struct list_head *listHeadMaPktreq,*placeHolderMaPktreq;
3303 maPktReqList_t *maPktreq;
3304 unsigned long lock_flags;
3305
3306 unifi_trace(priv, UDBG5, "entering the uf_flush_maPktlist \n");
3307
3308 spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
3309 /* go through list, delete & free memory */
3310 list_for_each_safe(listHeadMaPktreq, placeHolderMaPktreq, list) {
3311 maPktreq = list_entry(listHeadMaPktreq, maPktReqList_t, q);
3312
3313 if(!maPktreq) {
3314 unifi_error(priv, "entry should exists, otherwise crashes (bug)\n");
3315 }
3316 /* free the allocated memory */
3317 dev_kfree_skb(maPktreq->skb);
3318 list_del(listHeadMaPktreq);
3319 kfree(maPktreq);
3320 maPktreq = NULL;
3321 3401
3322 }
3323 spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
3324}
3325tx_buffered_packets_t *dequeue_tx_data_pdu(unifi_priv_t *priv, struct list_head *txList) 3402tx_buffered_packets_t *dequeue_tx_data_pdu(unifi_priv_t *priv, struct list_head *txList)
3326{ 3403{
3327 /* dequeue the tx data packets from the appropriate queue */ 3404 /* dequeue the tx data packets from the appropriate queue */
@@ -3521,7 +3598,7 @@ void resume_unicast_buffered_frames(unifi_priv_t *priv, CsrUint16 interfaceTag)
3521 while(!isRouterBufferEnabled(priv,3) && 3598 while(!isRouterBufferEnabled(priv,3) &&
3522 ((buffered_pkt=dequeue_tx_data_pdu(priv,&interfacePriv->genericMgtFrames))!=NULL)) { 3599 ((buffered_pkt=dequeue_tx_data_pdu(priv,&interfacePriv->genericMgtFrames))!=NULL)) {
3523 buffered_pkt->transmissionControl &= 3600 buffered_pkt->transmissionControl &=
3524 ~(TRANSMISSION_CONTROL_TRIGGER_MASK|TRANSMISSION_CONTROL_ESOP_MASK); 3601 ~(TRANSMISSION_CONTROL_TRIGGER_MASK|TRANSMISSION_CONTROL_EOSP_MASK);
3525 if((r=frame_and_send_queued_pdu(priv,buffered_pkt,NULL,0,FALSE)) == -ENOSPC) { 3602 if((r=frame_and_send_queued_pdu(priv,buffered_pkt,NULL,0,FALSE)) == -ENOSPC) {
3526 /* Enqueue at the head of the queue */ 3603 /* Enqueue at the head of the queue */
3527 spin_lock_irqsave(&priv->tx_q_lock,lock_flags); 3604 spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
@@ -3547,7 +3624,7 @@ void resume_unicast_buffered_frames(unifi_priv_t *priv, CsrUint16 interfaceTag)
3547 if (staInfo && (staInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_ACTIVE)) { 3624 if (staInfo && (staInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_ACTIVE)) {
3548 while((( TRUE == hipslotFree[3] ) && (buffered_pkt=dequeue_tx_data_pdu(priv, &staInfo->mgtFrames)))) { 3625 while((( TRUE == hipslotFree[3] ) && (buffered_pkt=dequeue_tx_data_pdu(priv, &staInfo->mgtFrames)))) {
3549 buffered_pkt->transmissionControl &= 3626 buffered_pkt->transmissionControl &=
3550 ~(TRANSMISSION_CONTROL_TRIGGER_MASK|TRANSMISSION_CONTROL_ESOP_MASK); 3627 ~(TRANSMISSION_CONTROL_TRIGGER_MASK|TRANSMISSION_CONTROL_EOSP_MASK);
3551 if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staInfo,0,FALSE)) == -ENOSPC) { 3628 if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staInfo,0,FALSE)) == -ENOSPC) {
3552 unifi_trace(priv, UDBG3, "(ENOSPC) in resume_unicast_buffered_frames:: hip slots are full for voice queue\n"); 3629 unifi_trace(priv, UDBG3, "(ENOSPC) in resume_unicast_buffered_frames:: hip slots are full for voice queue\n");
3553 /* Enqueue at the head of the queue */ 3630 /* Enqueue at the head of the queue */
@@ -3573,7 +3650,7 @@ void resume_unicast_buffered_frames(unifi_priv_t *priv, CsrUint16 interfaceTag)
3573 3650
3574 while((buffered_pkt=dequeue_tx_data_pdu(priv, &staInfo->dataPdu[j]))) { 3651 while((buffered_pkt=dequeue_tx_data_pdu(priv, &staInfo->dataPdu[j]))) {
3575 buffered_pkt->transmissionControl &= 3652 buffered_pkt->transmissionControl &=
3576 ~(TRANSMISSION_CONTROL_TRIGGER_MASK|TRANSMISSION_CONTROL_ESOP_MASK); 3653 ~(TRANSMISSION_CONTROL_TRIGGER_MASK|TRANSMISSION_CONTROL_EOSP_MASK);
3577 if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staInfo,0,FALSE)) == -ENOSPC) { 3654 if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staInfo,0,FALSE)) == -ENOSPC) {
3578 /* Enqueue at the head of the queue */ 3655 /* Enqueue at the head of the queue */
3579 spin_lock_irqsave(&priv->tx_q_lock,lock_flags); 3656 spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
@@ -3615,7 +3692,7 @@ void update_eosp_to_head_of_broadcast_list_head(unifi_priv_t *priv,CsrUint16 int
3615 spin_lock_irqsave(&priv->tx_q_lock,lock_flags); 3692 spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
3616 list_for_each_safe(listHead, placeHolder, &interfacePriv->genericMulticastOrBroadCastFrames) { 3693 list_for_each_safe(listHead, placeHolder, &interfacePriv->genericMulticastOrBroadCastFrames) {
3617 tx_q_item = list_entry(listHead, tx_buffered_packets_t, q); 3694 tx_q_item = list_entry(listHead, tx_buffered_packets_t, q);
3618 tx_q_item->transmissionControl |= TRANSMISSION_CONTROL_ESOP_MASK; 3695 tx_q_item->transmissionControl |= TRANSMISSION_CONTROL_EOSP_MASK;
3619 tx_q_item->transmissionControl = (tx_q_item->transmissionControl & ~(CSR_NO_CONFIRM_REQUIRED)); 3696 tx_q_item->transmissionControl = (tx_q_item->transmissionControl & ~(CSR_NO_CONFIRM_REQUIRED));
3620 unifi_trace(priv, UDBG1,"updating eosp for list Head hostTag:= 0x%x ",tx_q_item->hostTag); 3697 unifi_trace(priv, UDBG1,"updating eosp for list Head hostTag:= 0x%x ",tx_q_item->hostTag);
3621 break; 3698 break;
@@ -3624,105 +3701,51 @@ void update_eosp_to_head_of_broadcast_list_head(unifi_priv_t *priv,CsrUint16 int
3624 } 3701 }
3625 func_exit(); 3702 func_exit();
3626} 3703}
3704
3705/*
3706 * ---------------------------------------------------------------------------
3707 * resume_suspended_uapsd
3708 *
3709 * This function takes care processing packets of Unscheduled Service Period,
3710 * which been suspended earlier due to DTIM/HIP ENOSPC scenarios
3711 *
3712 * Arguments:
3713 * priv Pointer to device private context struct
3714 * interfaceTag For which resume should happen
3715 * ---------------------------------------------------------------------------
3716 */
3627void resume_suspended_uapsd(unifi_priv_t* priv,CsrUint16 interfaceTag) 3717void resume_suspended_uapsd(unifi_priv_t* priv,CsrUint16 interfaceTag)
3628{ 3718{
3629 3719
3630 CsrUint8 startIndex; 3720 CsrUint8 startIndex;
3631 CsrWifiRouterCtrlStaInfo_t * staInfo = NULL; 3721 CsrWifiRouterCtrlStaInfo_t * staInfo = NULL;
3632 unsigned long lock_flags; 3722 unsigned long lock_flags;
3633 /*U-APSD might have stopped because of multicast. So restart it if U-APSD 3723
3634 was active with any of the station*/ 3724 unifi_trace(priv, UDBG2, "++resume_suspended_uapsd: \n");
3635 for(startIndex= 0; startIndex < UNIFI_MAX_CONNECTIONS;startIndex++) { 3725 for(startIndex= 0; startIndex < UNIFI_MAX_CONNECTIONS;startIndex++) {
3636 staInfo = CsrWifiRouterCtrlGetStationRecordFromHandle(priv,startIndex,interfaceTag); 3726 staInfo = CsrWifiRouterCtrlGetStationRecordFromHandle(priv,startIndex,interfaceTag);
3637 if(!staInfo ) { 3727
3728 if(!staInfo || !staInfo->wmmOrQosEnabled) {
3638 continue; 3729 continue;
3639 } else if((staInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE) 3730 } else if((staInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE)
3640 &&(staInfo->uapsdSuspended == TRUE)) { 3731 &&staInfo->uapsdActive && staInfo->uspSuspend) {
3641 3732 /* U-APSD Still active & previously suspended either ENOSPC of FH queues OR
3642 /*U-APSD Still active, it means trigger frame is received,so continue U-APSD by 3733 * due to DTIM activity
3643 sending data from remaining delivery enabled queues*/ 3734 */
3644 spin_lock_irqsave(&priv->staRecord_lock,lock_flags); 3735 uf_handle_uspframes_delivery(priv, staInfo, interfaceTag);
3645 staInfo->uapsdActive = TRUE; 3736 } else {
3646 staInfo->uapsdSuspended = FALSE; 3737 unifi_trace(priv, UDBG2, "resume_suspended_uapsd: PS state=%x, uapsdActive?=%x, suspend?=%x\n",
3647 spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags); 3738 staInfo->currentPeerState, staInfo->uapsdActive, staInfo->uspSuspend);
3648 uf_continue_uapsd(priv,staInfo); 3739 if (staInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_ACTIVE)
3649 } 3740 {
3650 } 3741 spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
3651 3742 staInfo->uapsdActive = FALSE;
3652} 3743 staInfo->uspSuspend = FALSE;
3653void uf_store_directed_ma_packet_referenece(unifi_priv_t *priv, bulk_data_param_t *bulkdata, 3744 spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
3654 CSR_SIGNAL *sigptr, CsrUint32 alignOffset) 3745 }
3655{
3656
3657 maPktReqList_t *maPktreq = NULL;
3658 CSR_MA_PACKET_REQUEST *req = &sigptr->u.MaPacketRequest;
3659 CsrWifiRouterCtrlStaInfo_t *staRecord = NULL;
3660 CsrUint16 frmCtrl,interfaceTag = 0;
3661 const CsrUint8* macHdrLocation;
3662 struct sk_buff *skb ;
3663 unsigned long lock_flags;
3664 netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
3665 CsrUint8 *sigbuffer;
3666 CsrUint8 frameType = 0;
3667 func_enter();
3668
3669 if(bulkdata == NULL || (0 == bulkdata->d[0].data_length )){
3670 unifi_trace (priv, UDBG3, "uf_store_directed_ma_packet_referenece:bulk data NULL \n");
3671 func_exit();
3672 return;
3673 }
3674 macHdrLocation = bulkdata->d[0].os_data_ptr;
3675 skb = (struct sk_buff*)bulkdata->d[0].os_net_buf_ptr;
3676 /* fectch the frame control value from mac header */
3677 frmCtrl = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(macHdrLocation);
3678
3679 /* Processing done according to Frame/Packet type */
3680 frameType = ((frmCtrl & 0x000c) >> FRAME_CONTROL_TYPE_FIELD_OFFSET);
3681
3682 if( (((frmCtrl & 0xff) == IEEE802_11_FC_TYPE_QOS_NULL) ||
3683 ((frmCtrl & 0xff) == IEEE802_11_FC_TYPE_NULL ) ) ||
3684 ( IEEE802_11_FRAMETYPE_MANAGEMENT== frameType)){
3685
3686 /* if packet is NULL or Qos Null no need of retransmit so dont queue it*/
3687 unifi_trace (priv, UDBG3, "uf_store_directed_ma_packet_referenece: NULL data Pkt or mgmt\n");
3688 func_exit();
3689 return;
3690 }
3691
3692 /* fetch the station record for corresponding peer mac address */
3693 if ((staRecord = CsrWifiRouterCtrlGetStationRecordFromPeerMacAddress(priv, req->Ra.x, interfaceTag))) {
3694 maPktreq = (maPktReqList_t*)kmalloc(sizeof(maPktReqList_t),GFP_ATOMIC);
3695 if(maPktreq == NULL){
3696 unifi_error(priv,
3697 "uf_store_directed_ma_packet_referenece :: Failed to allocate %d byter for maPktreq\n",
3698 sizeof(maPktReqList_t));
3699 func_exit();
3700 return;
3701 } 3746 }
3702 } 3747 }
3703 3748 unifi_trace(priv, UDBG2, "--resume_suspended_uapsd:\n");
3704 /* staRecord not present that means packet is multicast or generic mgmt so no need to queue it */
3705 else{
3706 unifi_trace (priv, UDBG3, "uf_store_directed_ma_packet_referenece: multicast pkt \n");
3707 func_exit();
3708 return ;
3709 }
3710
3711 /* disbale preemption */
3712 spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
3713 INIT_LIST_HEAD(&maPktreq->q);
3714 maPktreq->staHandler = staRecord->assignedHandle;
3715 memcpy(&maPktreq->signal,sigptr,sizeof(CSR_SIGNAL_PRIMITIVE_HEADER) + sizeof(CSR_MA_PACKET_REQUEST));
3716 sigbuffer = (CsrUint8*)&maPktreq->signal;
3717 sigbuffer[SIZEOF_SIGNAL_HEADER + 1] = alignOffset;
3718 maPktreq->skb = skb_get(skb);
3719 maPktreq->hostTag = req->HostTag;
3720 maPktreq->jiffeTime = jiffies;
3721 list_add_tail(&maPktreq->q,&interfacePriv->directedMaPktReq);
3722
3723 spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
3724 func_exit();
3725
3726} 3749}
3727 3750
3728#endif 3751#endif
diff --git a/drivers/staging/csr/unifi_priv.h b/drivers/staging/csr/unifi_priv.h
index f687f270a69..b23c8445657 100644
--- a/drivers/staging/csr/unifi_priv.h
+++ b/drivers/staging/csr/unifi_priv.h
@@ -44,6 +44,10 @@
44 44
45#include <linux/fs.h> 45#include <linux/fs.h>
46 46
47#ifdef ANDROID_BUILD
48#include <linux/wakelock.h>
49#endif
50
47#include "csr_wifi_hip_unifi.h" 51#include "csr_wifi_hip_unifi.h"
48#include "csr_wifi_hip_unifi_udi.h" 52#include "csr_wifi_hip_unifi_udi.h"
49#include "csr_wifi_router_lib.h" 53#include "csr_wifi_router_lib.h"
@@ -63,6 +67,10 @@ typedef struct CsrWifiSmeApConfig CsrWifiSmeApConfig_t;
63#include "unifi_wext.h" 67#include "unifi_wext.h"
64#endif 68#endif
65 69
70#ifdef ANDROID_BUILD
71extern struct wake_lock unifi_sdio_wake_lock;
72#endif
73
66#include "unifi_clients.h" 74#include "unifi_clients.h"
67 75
68 76
@@ -98,18 +106,14 @@ typedef struct CsrWifiSmeApConfig CsrWifiSmeApConfig_t;
98#include "unifi_sme.h" 106#include "unifi_sme.h"
99#endif 107#endif
100 108
101#undef COMPARE_HOST_TAG_TO_ENQUEUE
102#define COMPARE_HOST_TAG_TO_ENQUEUE(tx_q_item_hosttag,maPktHostTag) \
103 if(tx_q_item_hosttag > maPktHostTag){ \
104 locationFound = TRUE; \
105 ii++; \
106 break; \
107 } \
108 ii++; \
109
110
111/* The device major number to use when registering the udi driver */ 109/* The device major number to use when registering the udi driver */
112#define UNIFI_NAME "unifi" 110#define UNIFI_NAME "unifi"
111/*
112 * MAX_UNIFI_DEVS defines the maximum number of UniFi devices that can be present.
113 * This number should be set to the number of SDIO slots supported by the SDIO
114 * host controller on the platform.
115 * Note: If MAX_UNIFI_DEVS value changes, fw_init[] needs to be corrected in drv.c
116 */
113#define MAX_UNIFI_DEVS 2 117#define MAX_UNIFI_DEVS 2
114 118
115/* 802.11 Mac header offsets */ 119/* 802.11 Mac header offsets */
@@ -156,6 +160,10 @@ typedef struct CsrWifiSmeApConfig CsrWifiSmeApConfig_t;
156#define IEEE802_11_QC_TID_MASK 0x0f 160#define IEEE802_11_QC_TID_MASK 0x0f
157#define IEEE802_11_QC_A_MSDU_PRESENT 0x80 161#define IEEE802_11_QC_A_MSDU_PRESENT 0x80
158 162
163#if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_QOSCTRL_MIC_WORKAROUND))
164#define IEEE802_11_QC_NON_TID_BITS_MASK 0xFFF0
165#endif
166
159#define CSR_WIFI_EAPOL_M4_HOST_TAG 0x50000000 167#define CSR_WIFI_EAPOL_M4_HOST_TAG 0x50000000
160#define IEEE802_11_DATA_FRAME_MAC_HEADER_SIZE 36 168#define IEEE802_11_DATA_FRAME_MAC_HEADER_SIZE 36
161#define MAX_ACCESS_CATOGORY 4 169#define MAX_ACCESS_CATOGORY 4
@@ -185,6 +193,9 @@ typedef struct CsrWifiSmeApConfig CsrWifiSmeApConfig_t;
185#define STA_INACTIVE_DETECTION_TIMER_INTERVAL 30 /* in seconds */ 193#define STA_INACTIVE_DETECTION_TIMER_INTERVAL 30 /* in seconds */
186#define STA_INACTIVE_TIMEOUT_VAL 120*1000*1000 /* 120 seconds */ 194#define STA_INACTIVE_TIMEOUT_VAL 120*1000*1000 /* 120 seconds */
187 195
196/* Test for modes requiring AP firmware patch */
197#define CSR_WIFI_HIP_IS_AP_FW(mode) ((((mode) == CSR_WIFI_ROUTER_CTRL_MODE_AP) || \
198 ((mode) == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO)) ? TRUE : FALSE)
188 199
189/* Defines used in beacon filtering in case of P2P */ 200/* Defines used in beacon filtering in case of P2P */
190#define CSR_WIFI_P2P_WILDCARD_SSID_LENGTH 0x7 201#define CSR_WIFI_P2P_WILDCARD_SSID_LENGTH 0x7
@@ -220,6 +231,9 @@ extern int sdio_block_size;
220extern int coredump_max; 231extern int coredump_max;
221extern int run_bh_once; 232extern int run_bh_once;
222extern int bh_priority; 233extern int bh_priority;
234#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
235extern int log_hip_signals;
236#endif
223 237
224struct dlpriv { 238struct dlpriv {
225 const unsigned char *dl_data; 239 const unsigned char *dl_data;
@@ -331,7 +345,8 @@ typedef struct CsrWifiRouterCtrlStaInfo_t {
331 CsrTime lastActivity; 345 CsrTime lastActivity;
332 346
333 /* during m/c transmission sp suspended */ 347 /* during m/c transmission sp suspended */
334 CsrBool uapsdSuspended; 348 CsrBool uspSuspend;
349 CSR_PRIORITY triggerFramePriority;
335#endif 350#endif
336 CsrWifiRouterCtrlPeerStatus currentPeerState; 351 CsrWifiRouterCtrlPeerStatus currentPeerState;
337 struct list_head dataPdu[MAX_ACCESS_CATOGORY]; 352 struct list_head dataPdu[MAX_ACCESS_CATOGORY];
@@ -349,6 +364,8 @@ typedef struct CsrWifiRouterCtrlStaInfo_t {
349#define CSR_WIFI_TIM_RESETTING 2 364#define CSR_WIFI_TIM_RESETTING 2
350#define CSR_WIFI_TIM_SETTING 3 365#define CSR_WIFI_TIM_SETTING 3
351 366
367 CsrBool timRequestPendingFlag;
368 CsrUint8 updateTimReqQueued;
352 CsrUint16 noOfPktQueued; 369 CsrUint16 noOfPktQueued;
353}CsrWifiRouterCtrlStaInfo_t; 370}CsrWifiRouterCtrlStaInfo_t;
354 371
@@ -609,8 +626,14 @@ struct unifi_priv {
609 626
610 /* Spinlock to protect M4 data */ 627 /* Spinlock to protect M4 data */
611 spinlock_t m4_lock; 628 spinlock_t m4_lock;
612 /* Spinlock to protect BA RX data */ 629 /* Mutex to protect BA RX data */
613 spinlock_t ba_lock; 630 struct semaphore ba_mutex;
631
632#if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION))
633 /* Spinlock to protect the WAPI data */
634 spinlock_t wapi_lock;
635#endif
636
614#ifndef ALLOW_Q_PAUSE 637#ifndef ALLOW_Q_PAUSE
615 /* Array to indicate if a particular Tx queue is paused, this may not be 638 /* Array to indicate if a particular Tx queue is paused, this may not be
616 * required in a multiqueue implementation since we can directly stop kernel 639 * required in a multiqueue implementation since we can directly stop kernel
@@ -630,10 +653,24 @@ struct unifi_priv {
630 CsrUint32 rxUdpThroughput; 653 CsrUint32 rxUdpThroughput;
631 CsrUint32 txUdpThroughput; 654 CsrUint32 txUdpThroughput;
632 655
633 656#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
657 /*Set if multicast KeyID = 1*/
634 CsrUint8 wapi_multicast_filter; 658 CsrUint8 wapi_multicast_filter;
659 /*Set if unicast KeyID = 1*/
635 CsrUint8 wapi_unicast_filter; 660 CsrUint8 wapi_unicast_filter;
636 CsrUint8 wapi_unicast_queued_pkt_filter; 661 CsrUint8 wapi_unicast_queued_pkt_filter;
662#ifdef CSR_WIFI_SECURITY_WAPI_QOSCTRL_MIC_WORKAROUND
663 CsrBool isWapiConnection;
664#endif
665#endif
666
667#ifdef CSR_WIFI_SPLIT_PATCH
668 CsrWifiRouterCtrlModeSetReq pending_mode_set;
669#endif
670
671 CsrBool cmanrTestMode;
672 CSR_RATE cmanrTestModeTransmitRate;
673
637}; 674};
638 675
639typedef struct { 676typedef struct {
@@ -682,6 +719,9 @@ typedef struct netInterface_priv
682 CsrUint8 ba_complete_index; 719 CsrUint8 ba_complete_index;
683 CsrUint8 queueEnabled[UNIFI_NO_OF_TX_QS]; 720 CsrUint8 queueEnabled[UNIFI_NO_OF_TX_QS];
684 struct work_struct send_m4_ready_task; 721 struct work_struct send_m4_ready_task;
722#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
723 struct work_struct send_pkt_to_encrypt;
724#endif
685 struct net_device_stats stats; 725 struct net_device_stats stats;
686 CsrUint8 interfaceMode; 726 CsrUint8 interfaceMode;
687 CsrBool protect; 727 CsrBool protect;
@@ -721,7 +761,6 @@ typedef struct netInterface_priv
721 struct list_head genericMgtFrames; 761 struct list_head genericMgtFrames;
722 struct list_head genericMulticastOrBroadCastFrames; 762 struct list_head genericMulticastOrBroadCastFrames;
723 struct list_head genericMulticastOrBroadCastMgtFrames; 763 struct list_head genericMulticastOrBroadCastMgtFrames;
724 struct list_head directedMaPktReq;
725 764
726 /* Timer for detecting station inactivity */ 765 /* Timer for detecting station inactivity */
727 struct timer_list sta_activity_check_timer; 766 struct timer_list sta_activity_check_timer;
@@ -740,6 +779,13 @@ typedef struct netInterface_priv
740 /* Buffered M4 signal to take care of WPA race condition */ 779 /* Buffered M4 signal to take care of WPA race condition */
741 CSR_SIGNAL m4_signal; 780 CSR_SIGNAL m4_signal;
742 bulk_data_desc_t m4_bulk_data; 781 bulk_data_desc_t m4_bulk_data;
782
783#if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION))
784 /* Buffered WAPI Unicast MA Packet Request for encryption in Sme */
785 CSR_SIGNAL wapi_unicast_ma_pkt_sig;
786 bulk_data_desc_t wapi_unicast_bulk_data;
787#endif
788
743 /* This should be removed and m4_hostTag should be used for checking*/ 789 /* This should be removed and m4_hostTag should be used for checking*/
744 CsrBool m4_sent; 790 CsrBool m4_sent;
745 CSR_CLIENT_TAG m4_hostTag; 791 CSR_CLIENT_TAG m4_hostTag;
@@ -747,17 +793,11 @@ typedef struct netInterface_priv
747 CsrBool intraBssEnabled; 793 CsrBool intraBssEnabled;
748 CsrUint32 multicastPduHostTag; /* Used to set the tim after getting 794 CsrUint32 multicastPduHostTag; /* Used to set the tim after getting
749 a confirm for it */ 795 a confirm for it */
796 CsrBool bcTimSet;
797 CsrBool bcTimSetReqPendingFlag;
798 CsrBool bcTimSetReqQueued;
750} netInterface_priv_t; 799} netInterface_priv_t;
751 800
752typedef struct maPktReqList{
753 struct list_head q;
754 struct sk_buff *skb;
755 CSR_SIGNAL signal;
756 CSR_CLIENT_TAG hostTag;
757 CsrUint32 staHandler;
758 unsigned long jiffeTime;
759}maPktReqList_t;
760
761#ifndef ALLOW_Q_PAUSE 801#ifndef ALLOW_Q_PAUSE
762#define net_is_tx_q_paused(priv, q) (priv->tx_q_paused_flag[q]) 802#define net_is_tx_q_paused(priv, q) (priv->tx_q_paused_flag[q])
763#define net_tx_q_unpause(priv, q) (priv->tx_q_paused_flag[q] = 0) 803#define net_tx_q_unpause(priv, q) (priv->tx_q_paused_flag[q] = 0)
@@ -925,7 +965,6 @@ int uf_ap_process_data_pdu(unifi_priv_t *priv, struct sk_buff *skb,
925 bulk_data_param_t *bulkdata, 965 bulk_data_param_t *bulkdata,
926 CsrUint8 macHeaderLengthInBytes); 966 CsrUint8 macHeaderLengthInBytes);
927CsrBool uf_is_more_data_for_non_delivery_ac(CsrWifiRouterCtrlStaInfo_t *staRecord); 967CsrBool uf_is_more_data_for_non_delivery_ac(CsrWifiRouterCtrlStaInfo_t *staRecord);
928CsrBool uf_is_more_data_for_delivery_ac(unifi_priv_t *priv,CsrWifiRouterCtrlStaInfo_t *staRecord,CsrBool mgtCheck);
929void uf_process_wmm_deliver_ac_uapsd ( unifi_priv_t * priv, 968void uf_process_wmm_deliver_ac_uapsd ( unifi_priv_t * priv,
930 CsrWifiRouterCtrlStaInfo_t * srcStaInfo, 969 CsrWifiRouterCtrlStaInfo_t * srcStaInfo,
931 CsrUint16 qosControl, 970 CsrUint16 qosControl,
@@ -937,7 +976,6 @@ void uf_send_buffered_data_from_delivery_ac(unifi_priv_t *priv, CsrWifiRouterCtr
937void uf_continue_uapsd(unifi_priv_t *priv, CsrWifiRouterCtrlStaInfo_t * staInfo); 976void uf_continue_uapsd(unifi_priv_t *priv, CsrWifiRouterCtrlStaInfo_t * staInfo);
938void uf_send_qos_null(unifi_priv_t * priv,CsrUint16 interfaceTag, const CsrUint8 *da,CSR_PRIORITY priority,CsrWifiRouterCtrlStaInfo_t * srcStaInfo); 977void uf_send_qos_null(unifi_priv_t * priv,CsrUint16 interfaceTag, const CsrUint8 *da,CSR_PRIORITY priority,CsrWifiRouterCtrlStaInfo_t * srcStaInfo);
939void uf_send_nulldata(unifi_priv_t * priv,CsrUint16 interfaceTag, const CsrUint8 *da,CSR_PRIORITY priority,CsrWifiRouterCtrlStaInfo_t * srcStaInfo); 978void uf_send_nulldata(unifi_priv_t * priv,CsrUint16 interfaceTag, const CsrUint8 *da,CSR_PRIORITY priority,CsrWifiRouterCtrlStaInfo_t * srcStaInfo);
940void uf_store_directed_ma_packet_referenece(unifi_priv_t *priv, bulk_data_param_t *bulkdata,CSR_SIGNAL *sigptr,CsrUint32 alignOffset);
941 979
942 980
943 981
@@ -956,7 +994,6 @@ void send_auto_ma_packet_confirm(unifi_priv_t *priv,
956 netInterface_priv_t *interfacePriv, 994 netInterface_priv_t *interfacePriv,
957 struct list_head *buffered_frames_list); 995 struct list_head *buffered_frames_list);
958void uf_flush_list(unifi_priv_t * priv, struct list_head * list); 996void uf_flush_list(unifi_priv_t * priv, struct list_head * list);
959void uf_flush_maPktlist(unifi_priv_t * priv, struct list_head * list);
960tx_buffered_packets_t *dequeue_tx_data_pdu(unifi_priv_t *priv, struct list_head *txList); 997tx_buffered_packets_t *dequeue_tx_data_pdu(unifi_priv_t *priv, struct list_head *txList);
961void resume_unicast_buffered_frames(unifi_priv_t *priv, CsrUint16 interfaceTag); 998void resume_unicast_buffered_frames(unifi_priv_t *priv, CsrUint16 interfaceTag);
962void update_eosp_to_head_of_broadcast_list_head(unifi_priv_t *priv,CsrUint16 interfaceTag); 999void update_eosp_to_head_of_broadcast_list_head(unifi_priv_t *priv,CsrUint16 interfaceTag);
@@ -1073,6 +1110,11 @@ void uf_process_rx_pending_queue(unifi_priv_t *priv, int queue,
1073 CsrWifiMacAddress source_address, 1110 CsrWifiMacAddress source_address,
1074 int indicate, CsrUint16 interfaceTag); 1111 int indicate, CsrUint16 interfaceTag);
1075 1112
1113#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
1114int uf_register_hip_offline_debug(unifi_priv_t *priv);
1115int uf_unregister_hip_offline_debug(unifi_priv_t *priv);
1116#endif
1117
1076/* 1118/*
1077 * inet.c 1119 * inet.c
1078 */ 1120 */
diff --git a/drivers/staging/csr/unifi_sme.c b/drivers/staging/csr/unifi_sme.c
index 4ee663fe4e4..54414ed2ed1 100644
--- a/drivers/staging/csr/unifi_sme.c
+++ b/drivers/staging/csr/unifi_sme.c
@@ -447,6 +447,7 @@ int unifi_cfg_power(unifi_priv_t *priv, unsigned char *arg)
447{ 447{
448 unifi_cfg_power_t cfg_power; 448 unifi_cfg_power_t cfg_power;
449 int rc; 449 int rc;
450 int wol;
450 451
451 if (get_user(cfg_power, (unifi_cfg_power_t*)(((unifi_cfg_command_t*)arg) + 1))) { 452 if (get_user(cfg_power, (unifi_cfg_power_t*)(((unifi_cfg_command_t*)arg) + 1))) {
452 unifi_error(priv, "UNIFI_CFG: Failed to get the argument\n"); 453 unifi_error(priv, "UNIFI_CFG: Failed to get the argument\n");
@@ -455,16 +456,24 @@ int unifi_cfg_power(unifi_priv_t *priv, unsigned char *arg)
455 456
456 switch (cfg_power) { 457 switch (cfg_power) {
457 case UNIFI_CFG_POWER_OFF: 458 case UNIFI_CFG_POWER_OFF:
459 priv->wol_suspend = (enable_wol == UNIFI_WOL_OFF) ? FALSE : TRUE;
458 rc = sme_sys_suspend(priv); 460 rc = sme_sys_suspend(priv);
459 if (rc) { 461 if (rc) {
460 return rc; 462 return rc;
461 } 463 }
462 break; 464 break;
463 case UNIFI_CFG_POWER_ON: 465 case UNIFI_CFG_POWER_ON:
466 wol = priv->wol_suspend;
464 rc = sme_sys_resume(priv); 467 rc = sme_sys_resume(priv);
465 if (rc) { 468 if (rc) {
466 return rc; 469 return rc;
467 } 470 }
471 if (wol) {
472 /* Kick the BH to ensure pending transfers are handled when
473 * a suspend happened with card powered.
474 */
475 unifi_send_signal(priv->card, NULL, 0, NULL);
476 }
468 break; 477 break;
469 default: 478 default:
470 unifi_error(priv, "WIFI POWER: Unknown value.\n"); 479 unifi_error(priv, "WIFI POWER: Unknown value.\n");
@@ -921,10 +930,19 @@ int
921 supportedRates[i++]=0x8b; 930 supportedRates[i++]=0x8b;
922 supportedRates[i++]=0x96; 931 supportedRates[i++]=0x96;
923 } else if(n) { 932 } else if(n) {
933 /* For some strange reasons WiFi stack needs both b and g rates*/
924 supportedRates[i++]=0x02; 934 supportedRates[i++]=0x02;
925 supportedRates[i++]=0x04; 935 supportedRates[i++]=0x04;
926 supportedRates[i++]=0x0b; 936 supportedRates[i++]=0x0b;
927 supportedRates[i++]=0x16; 937 supportedRates[i++]=0x16;
938 supportedRates[i++]=0x0c;
939 supportedRates[i++]=0x12;
940 supportedRates[i++]=0x18;
941 supportedRates[i++]=0x24;
942 supportedRates[i++]=0x30;
943 supportedRates[i++]=0x48;
944 supportedRates[i++]=0x60;
945 supportedRates[i++]=0x6c;
928 } 946 }
929 if(g) { 947 if(g) {
930 if(!b) { 948 if(!b) {
@@ -1162,3 +1180,65 @@ uf_send_m4_ready_wq(struct work_struct *work)
1162 1180
1163} /* uf_send_m4_ready_wq() */ 1181} /* uf_send_m4_ready_wq() */
1164 1182
1183#if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION))
1184/*
1185 * ---------------------------------------------------------------------------
1186 * uf_send_pkt_to_encrypt
1187 *
1188 * Deferred work queue function to send the WAPI data pkts to SME when unicast KeyId = 1
1189 * These are done in a deferred work queue for two reasons:
1190 * - the CsrWifiRouterCtrl...Send() functions are not safe for atomic context
1191 * - we want to load the main driver data path as lightly as possible
1192 *
1193 * Arguments:
1194 * work Pointer to work queue item.
1195 *
1196 * Returns:
1197 * None.
1198 * ---------------------------------------------------------------------------
1199 */
1200void uf_send_pkt_to_encrypt(struct work_struct *work)
1201{
1202 netInterface_priv_t *interfacePriv = container_of(work, netInterface_priv_t, send_pkt_to_encrypt);
1203 CsrUint16 interfaceTag = interfacePriv->InterfaceTag;
1204 unifi_priv_t *priv = interfacePriv->privPtr;
1205
1206 CsrUint32 pktBulkDataLength;
1207 CsrUint8 *pktBulkData;
1208 unsigned long flags;
1209
1210 if (interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_STA) {
1211
1212 func_enter();
1213
1214 pktBulkDataLength = interfacePriv->wapi_unicast_bulk_data.data_length;
1215
1216 if (pktBulkDataLength > 0) {
1217 pktBulkData = (CsrUint8 *)CsrPmemAlloc(pktBulkDataLength);
1218 CsrMemSet(pktBulkData, 0, pktBulkDataLength);
1219 } else {
1220 unifi_error(priv, "uf_send_pkt_to_encrypt() : invalid buffer\n");
1221 return;
1222 }
1223
1224 spin_lock_irqsave(&priv->wapi_lock, flags);
1225 /* Copy over the MA PKT REQ bulk data */
1226 CsrMemCpy(pktBulkData, (CsrUint8*)interfacePriv->wapi_unicast_bulk_data.os_data_ptr, pktBulkDataLength);
1227 /* Free any bulk data buffers allocated for the WAPI Data pkt */
1228 unifi_net_data_free(priv, &interfacePriv->wapi_unicast_bulk_data);
1229 interfacePriv->wapi_unicast_bulk_data.net_buf_length = 0;
1230 interfacePriv->wapi_unicast_bulk_data.data_length = 0;
1231 interfacePriv->wapi_unicast_bulk_data.os_data_ptr = interfacePriv->wapi_unicast_bulk_data.os_net_buf_ptr = NULL;
1232 spin_unlock_irqrestore(&priv->wapi_lock, flags);
1233
1234 CsrWifiRouterCtrlWapiUnicastTxEncryptIndSend(priv->CSR_WIFI_SME_IFACEQUEUE, 0, interfaceTag, pktBulkDataLength, pktBulkData);
1235 unifi_trace(priv, UDBG1, "WapiUnicastTxEncryptInd sent to SME\n");
1236
1237 CsrPmemFree(pktBulkData); /* Would have been copied over by the SME Handler */
1238
1239 func_exit();
1240 } else {
1241 unifi_warning(priv, "uf_send_pkt_to_encrypt() is NOT applicable for interface mode - %d\n",interfacePriv->interfaceMode);
1242 }
1243}/* uf_send_pkt_to_encrypt() */
1244#endif
diff --git a/drivers/staging/csr/unifi_sme.h b/drivers/staging/csr/unifi_sme.h
index 51ca92e8905..3cbee81f1b0 100644
--- a/drivers/staging/csr/unifi_sme.h
+++ b/drivers/staging/csr/unifi_sme.h
@@ -50,6 +50,7 @@ enum sme_request_status {
50 SME_REQUEST_PENDING, 50 SME_REQUEST_PENDING,
51 SME_REQUEST_RECEIVED, 51 SME_REQUEST_RECEIVED,
52 SME_REQUEST_TIMEDOUT, 52 SME_REQUEST_TIMEDOUT,
53 SME_REQUEST_CANCELLED,
53}; 54};
54 55
55/* Structure to hold a UDI logged signal */ 56/* Structure to hold a UDI logged signal */
@@ -123,6 +124,7 @@ void uf_ta_wq(struct work_struct *work);
123#endif 124#endif
124 125
125void uf_sme_complete_request(unifi_priv_t *priv, CsrResult reply_status, const char *func); 126void uf_sme_complete_request(unifi_priv_t *priv, CsrResult reply_status, const char *func);
127void uf_sme_cancel_request(unifi_priv_t *priv, CsrResult reply_status);
126 128
127 129
128/* 130/*
@@ -148,6 +150,13 @@ void uf_sme_config_wq(struct work_struct *work);
148 */ 150 */
149void uf_send_m4_ready_wq(struct work_struct *work); 151void uf_send_m4_ready_wq(struct work_struct *work);
150 152
153#if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION))
154/*
155 * To send data pkt to Sme for encryption
156 */
157void uf_send_pkt_to_encrypt(struct work_struct *work);
158#endif
159
151int sme_mgt_power_config_set(unifi_priv_t *priv, CsrWifiSmePowerConfig *powerConfig); 160int sme_mgt_power_config_set(unifi_priv_t *priv, CsrWifiSmePowerConfig *powerConfig);
152int sme_mgt_power_config_get(unifi_priv_t *priv, CsrWifiSmePowerConfig *powerConfig); 161int sme_mgt_power_config_get(unifi_priv_t *priv, CsrWifiSmePowerConfig *powerConfig);
153int sme_mgt_host_config_set(unifi_priv_t *priv, CsrWifiSmeHostConfig *hostConfig); 162int sme_mgt_host_config_set(unifi_priv_t *priv, CsrWifiSmeHostConfig *hostConfig);
diff --git a/drivers/staging/csr/unifiio.h b/drivers/staging/csr/unifiio.h
index e707eedef29..4ab050bc71c 100644
--- a/drivers/staging/csr/unifiio.h
+++ b/drivers/staging/csr/unifiio.h
@@ -212,20 +212,19 @@ typedef struct {
212 212
213 213
214 214
215typedef enum unifi_putest_command { 215typedef CsrUint8 unifi_putest_command_t;
216 UNIFI_PUTEST_START, 216
217 UNIFI_PUTEST_STOP, 217#define UNIFI_PUTEST_START 0
218 UNIFI_PUTEST_SET_SDIO_CLOCK, 218#define UNIFI_PUTEST_STOP 1
219 UNIFI_PUTEST_CMD52_READ, 219#define UNIFI_PUTEST_SET_SDIO_CLOCK 2
220 UNIFI_PUTEST_CMD52_WRITE, 220#define UNIFI_PUTEST_CMD52_READ 3
221 UNIFI_PUTEST_DL_FW, 221#define UNIFI_PUTEST_CMD52_WRITE 4
222 UNIFI_PUTEST_DL_FW_BUFF, 222#define UNIFI_PUTEST_DL_FW 5
223 UNIFI_PUTEST_CMD52_BLOCK_READ, 223#define UNIFI_PUTEST_DL_FW_BUFF 6
224 UNIFI_PUTEST_COREDUMP_PREPARE, 224#define UNIFI_PUTEST_CMD52_BLOCK_READ 7
225 UNIFI_PUTEST_GP_READ16, 225#define UNIFI_PUTEST_COREDUMP_PREPARE 8
226 UNIFI_PUTEST_GP_WRITE16 226#define UNIFI_PUTEST_GP_READ16 9
227 227#define UNIFI_PUTEST_GP_WRITE16 10
228} unifi_putest_command_t;
229 228
230 229
231struct unifi_putest_cmd52 { 230struct unifi_putest_cmd52 {