summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Lin <dlin@marvell.com>2015-03-20 11:16:45 +0800
committerDavid Lin <dlin@marvell.com>2015-03-20 11:29:48 +0800
commit4774b30dce69a8e97c9431e2dc920ea92b5a976c (patch)
tree75c7d498af3835bec0dc0a9c04f4b48aee72be1d
parentf92c46695d92dc23606d65bb32611e92235c30fc (diff)
Commit mwlwifi driver 10.2.8.5.p0
1. Added support for station mode. 2. Upgraded firmware to version 7.2.8.5. 3. Added support to parse DTS file to configure band, antenna and power table. 4. Enhanced interoperability with some MAC clients. 5. Removed module parameters. 6. Cleaned up code based on the feedback from community. 7. Updated README, script and sample configuration files.
-rw-r--r--bin/firmware/7.2.6.1/88W8864.binbin113244 -> 0 bytes
-rwxr-xr-xbin/firmware/88W8864.binbin0 -> 116208 bytes
-rw-r--r--bin/firmware/Marvell_license.txt2
-rw-r--r--bin/powertable/Mamba/Mamba_FCC_v1.2_5G4TX.ini39
-rw-r--r--mwl_debug.c21
-rw-r--r--mwl_debug.h2
-rw-r--r--mwl_dev.h146
-rw-r--r--mwl_fwcmd.c594
-rw-r--r--mwl_fwcmd.h28
-rw-r--r--mwl_fwdl.c13
-rw-r--r--mwl_fwdl.h2
-rw-r--r--mwl_mac80211.c304
-rw-r--r--mwl_mac80211.h2
-rw-r--r--mwl_main.c474
-rw-r--r--mwl_rx.c56
-rw-r--r--mwl_rx.h2
-rw-r--r--mwl_sysadpt.h8
-rw-r--r--mwl_tx.c144
-rw-r--r--mwl_tx.h2
-rw-r--r--test/README89
-rw-r--r--test/setup.sh2
-rw-r--r--test/setup_multi_bssid.sh2
-rwxr-xr-xtest/wpa_supplicant.conf.open8
-rwxr-xr-xtest/wpa_supplicant.conf.psk9
24 files changed, 915 insertions, 1034 deletions
diff --git a/bin/firmware/7.2.6.1/88W8864.bin b/bin/firmware/7.2.6.1/88W8864.bin
deleted file mode 100644
index 6aaee12..0000000
--- a/bin/firmware/7.2.6.1/88W8864.bin
+++ /dev/null
Binary files differ
diff --git a/bin/firmware/88W8864.bin b/bin/firmware/88W8864.bin
new file mode 100755
index 0000000..ccdf825
--- /dev/null
+++ b/bin/firmware/88W8864.bin
Binary files differ
diff --git a/bin/firmware/Marvell_license.txt b/bin/firmware/Marvell_license.txt
index fe7d6de..945a549 100644
--- a/bin/firmware/Marvell_license.txt
+++ b/bin/firmware/Marvell_license.txt
@@ -1,5 +1,5 @@
WIRELESS CORE LIBRARY & FIRMWARE LICENSE TERMS
-Copyright (c) 2002-2014 Marvell International Ltd.
+Copyright (c) 2002-2015 Marvell International Ltd.
All rights reserved.
Redistribution. Redistribution and use in binary form, without modification,
diff --git a/bin/powertable/Mamba/Mamba_FCC_v1.2_5G4TX.ini b/bin/powertable/Mamba/Mamba_FCC_v1.2_5G4TX.ini
deleted file mode 100644
index 11a8304..0000000
--- a/bin/powertable/Mamba/Mamba_FCC_v1.2_5G4TX.ini
+++ /dev/null
@@ -1,39 +0,0 @@
-1 0 0x17 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x0F 0x0F 0x0F 0x0F 0x00 0x00 0x00 0x00 off 0x00F
-2 0 0x17 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x10 0x10 0x10 0x10 0x00 0x00 0x00 0x00 off 0x00F
-3 0 0x17 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x10 0x10 0x10 0x10 0x00 0x00 0x00 0x00 off 0x00F
-4 0 0x17 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x10 0x10 0x10 0x10 0x00 0x00 0x00 0x00 off 0x00F
-5 0 0x17 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x10 0x10 0x10 0x10 0x00 0x00 0x00 0x00 off 0x00F
-6 0 0x17 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x10 0x10 0x10 0x10 0x00 0x00 0x00 0x00 off 0x00F
-7 0 0x17 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x10 0x10 0x10 0x10 0x00 0x00 0x00 0x00 off 0x00F
-8 0 0x17 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x10 0x10 0x10 0x10 0x00 0x00 0x00 0x00 off 0x00F
-9 0 0x17 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x10 0x10 0x10 0x10 0x00 0x00 0x00 0x00 off 0x00F
-10 0 0x17 0x16 0x16 0x16 0x16 0x16 0x16 0x14 0x10 0x10 0x10 0x10 0x00 0x00 0x00 0x00 off 0x00F
-11 0 0x17 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x00 0x00 0x00 0x00 off 0x00F
-12 0 0x17 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x00 0x00 0x00 0x00 off 0x00F
-13 0 0x17 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x00 0x00 0x00 0x00 off 0x00F
-14 0 0x17 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x10 0x10 0x10 0x10 0x00 0x00 0x00 0x00 off 0x00F
-36 0 0x08 0x08 0x08 0x08 0x08 0x08 0x08 0x08 0x09 0x09 0x09 0x09 0x09 0x09 0x09 0x09 off 0x00F
-40 0 0x08 0x08 0x08 0x08 0x09 0x09 0x09 0x09 0x09 0x09 0x09 0x09 0x09 0x09 0x09 0x09 off 0x00F
-44 0 0x08 0x08 0x08 0x08 0x09 0x09 0x09 0x09 0x09 0x09 0x09 0x09 0x09 0x09 0x09 0x09 off 0x00F
-48 0 0x08 0x08 0x08 0x08 0x09 0x09 0x09 0x09 0x09 0x09 0x09 0x09 0x09 0x09 0x09 0x09 off 0x00F
-52 0 0x0F 0x0F 0x0F 0x0F 0x0F 0x0F 0x0F 0x0F 0x12 0x12 0x12 0x12 0x12 0x12 0x12 0x12 off 0x00F
-56 0 0x0F 0x0F 0x0F 0x0F 0x0F 0x0F 0x0F 0x0F 0x12 0x12 0x12 0x12 0x12 0x12 0x12 0x12 off 0x00F
-60 0 0x0F 0x0F 0x0F 0x0F 0x0F 0x0F 0x0F 0x0F 0x12 0x12 0x12 0x12 0x12 0x12 0x12 0x12 off 0x00F
-64 0 0x0F 0x0F 0x0F 0x0F 0x0F 0x0F 0x0F 0x0F 0x12 0x12 0x12 0x12 0x12 0x12 0x12 0x12 off 0x00F
-100 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 off 0x00F
-104 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 off 0x00F
-108 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 off 0x00F
-112 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 off 0x00F
-116 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 off 0x00F
-120 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 off 0x00F
-124 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 off 0x00F
-128 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 off 0x00F
-132 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 off 0x00F
-136 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 off 0x00F
-140 0 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 0x14 off 0x00F
-149 0 0x16 0x16 0x16 0x16 0x14 0x14 0x14 0x14 0x15 0x15 0x15 0x15 0x14 0x14 0x14 0x14 off 0x00F
-153 0 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x14 0x14 0x14 0x14 off 0x00F
-157 0 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x14 0x14 0x14 0x14 off 0x00F
-161 0 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x15 0x14 0x14 0x14 0x14 off 0x00F
-165 0 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x16 0x15 0x15 0x15 0x15 0x14 0x14 0x14 0x14 off 0x00F
-
diff --git a/mwl_debug.c b/mwl_debug.c
index 821b0c0..3402e99 100644
--- a/mwl_debug.c
+++ b/mwl_debug.c
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2006-2014 Marvell International Ltd.
+* Copyright (c) 2006-2015 Marvell International Ltd.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -59,7 +59,6 @@ void mwl_debug_prt(u32 classlevel, const char *func, const char *format, ...)
return;
if ((level & dbg_levels) != level) {
-
if (class != DBG_CLASS_PANIC && class != DBG_CLASS_ERROR)
return;
}
@@ -69,18 +68,14 @@ void mwl_debug_prt(u32 classlevel, const char *func, const char *format, ...)
return;
if (format != NULL) {
-
va_start(a_start, format);
vsprintf(debug_string, format, a_start);
va_end(a_start);
-
} else {
-
debug_string[0] = '\0';
}
switch (class) {
-
case DBG_CLASS_ENTER:
printk("Enter %s() ...\n", func);
break;
@@ -101,7 +96,6 @@ void mwl_debug_prt(u32 classlevel, const char *func, const char *format, ...)
}
if (strlen(debug_string) > 0) {
-
if (debug_string[strlen(debug_string)-1] == '\n')
debug_string[strlen(debug_string)-1] = '\0';
printk("%s(): %s\n", func, debug_string);
@@ -132,31 +126,23 @@ void mwl_debug_prtdata(u32 classlevel, const char *func, const void *data, int l
return;
if (format != NULL) {
-
va_start(a_start, format);
vsprintf(dbg_string, format, a_start);
va_end(a_start);
-
} else {
-
dbg_string[0] = '\0';
}
if (strlen(dbg_string) > 0) {
-
if (dbg_string[strlen(dbg_string) - 1] == '\n')
dbg_string[strlen(dbg_string)-1] = '\0';
printk("%s() %s\n", func, dbg_string);
-
} else {
-
printk("%s()\n", func);
}
for (curr_byte = 0; curr_byte < len; curr_byte = curr_byte + 8) {
-
if ((curr_byte + 8) < len) {
-
printk("0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n",
*(memptr + curr_byte + 0),
*(memptr + curr_byte + 1),
@@ -167,11 +153,9 @@ void mwl_debug_prtdata(u32 classlevel, const char *func, const void *data, int l
*(memptr + curr_byte + 6),
*(memptr + curr_byte + 7));
} else {
-
num_bytes = len - curr_byte;
offset = curr_byte;
for (curr_byte = 0; curr_byte < num_bytes; curr_byte++) {
-
sprintf(dbg_data, "0x%02x ", *(memptr + offset + curr_byte));
strcat(dbg_string, dbg_data);
}
@@ -193,9 +177,7 @@ void mwl_debug_dumpdata(const void *data, int len, char *marker)
printk("%s\n", marker);
for (curr_byte = 0; curr_byte < len; curr_byte = curr_byte + 8) {
-
if ((curr_byte + 8) < len) {
-
printk("0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n",
*(memptr + curr_byte + 0),
*(memptr + curr_byte + 1),
@@ -206,7 +188,6 @@ void mwl_debug_dumpdata(const void *data, int len, char *marker)
*(memptr + curr_byte + 6),
*(memptr + curr_byte + 7));
} else {
-
num_bytes = len - curr_byte;
offset = curr_byte;
for (curr_byte = 0; curr_byte < num_bytes; curr_byte++)
diff --git a/mwl_debug.h b/mwl_debug.h
index 6e9d74e..423a409 100644
--- a/mwl_debug.h
+++ b/mwl_debug.h
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2006-2014 Marvell International Ltd.
+* Copyright (c) 2006-2015 Marvell International Ltd.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
diff --git a/mwl_dev.h b/mwl_dev.h
index 8c9148e..a0f63d7 100644
--- a/mwl_dev.h
+++ b/mwl_dev.h
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2006-2014 Marvell International Ltd.
+* Copyright (c) 2006-2015 Marvell International Ltd.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -34,24 +34,24 @@
/* Map to 0x80000000 (Bus control) on BAR0
*/
-#define MACREG_REG_H2A_INTERRUPT_EVENTS 0x00000C18 /* (From host to ARM) */
-#define MACREG_REG_H2A_INTERRUPT_CAUSE 0x00000C1C /* (From host to ARM) */
-#define MACREG_REG_H2A_INTERRUPT_MASK 0x00000C20 /* (From host to ARM) */
-#define MACREG_REG_H2A_INTERRUPT_CLEAR_SEL 0x00000C24 /* (From host to ARM) */
-#define MACREG_REG_H2A_INTERRUPT_STATUS_MASK 0x00000C28 /* (From host to ARM) */
-
-#define MACREG_REG_A2H_INTERRUPT_EVENTS 0x00000C2C /* (From ARM to host) */
-#define MACREG_REG_A2H_INTERRUPT_CAUSE 0x00000C30 /* (From ARM to host) */
-#define MACREG_REG_A2H_INTERRUPT_MASK 0x00000C34 /* (From ARM to host) */
-#define MACREG_REG_A2H_INTERRUPT_CLEAR_SEL 0x00000C38 /* (From ARM to host) */
-#define MACREG_REG_A2H_INTERRUPT_STATUS_MASK 0x00000C3C /* (From ARM to host) */
+#define MACREG_REG_H2A_INTERRUPT_EVENTS 0x00000C18 /* (From host to ARM) */
+#define MACREG_REG_H2A_INTERRUPT_CAUSE 0x00000C1C /* (From host to ARM) */
+#define MACREG_REG_H2A_INTERRUPT_MASK 0x00000C20 /* (From host to ARM) */
+#define MACREG_REG_H2A_INTERRUPT_CLEAR_SEL 0x00000C24 /* (From host to ARM) */
+#define MACREG_REG_H2A_INTERRUPT_STATUS_MASK 0x00000C28 /* (From host to ARM) */
+
+#define MACREG_REG_A2H_INTERRUPT_EVENTS 0x00000C2C /* (From ARM to host) */
+#define MACREG_REG_A2H_INTERRUPT_CAUSE 0x00000C30 /* (From ARM to host) */
+#define MACREG_REG_A2H_INTERRUPT_MASK 0x00000C34 /* (From ARM to host) */
+#define MACREG_REG_A2H_INTERRUPT_CLEAR_SEL 0x00000C38 /* (From ARM to host) */
+#define MACREG_REG_A2H_INTERRUPT_STATUS_MASK 0x00000C3C /* (From ARM to host) */
/* Map to 0x80000000 on BAR1
*/
#define MACREG_REG_GEN_PTR 0x00000C10
#define MACREG_REG_INT_CODE 0x00000C14
#define MACREG_REG_SCRATCH 0x00000C40
-#define MACREG_REG_FW_PRESENT 0x0000BFFC
+#define MACREG_REG_FW_PRESENT 0x0000BFFC
/* Bit definitio for MACREG_REG_A2H_INTERRUPT_CAUSE (A2HRIC)
*/
@@ -60,18 +60,18 @@
#define MACREG_A2HRIC_BIT_OPC_DONE 0x00000004 /* bit 2 */
#define MACREG_A2HRIC_BIT_MAC_EVENT 0x00000008 /* bit 3 */
#define MACREG_A2HRIC_BIT_RX_PROBLEM 0x00000010 /* bit 4 */
-#define MACREG_A2HRIC_BIT_RADIO_OFF 0x00000020 /* bit 5 */
-#define MACREG_A2HRIC_BIT_RADIO_ON 0x00000040 /* bit 6 */
+#define MACREG_A2HRIC_BIT_RADIO_OFF 0x00000020 /* bit 5 */
+#define MACREG_A2HRIC_BIT_RADIO_ON 0x00000040 /* bit 6 */
#define MACREG_A2HRIC_BIT_RADAR_DETECT 0x00000080 /* bit 7 - IEEE80211_DH */
#define MACREG_A2HRIC_BIT_ICV_ERROR 0x00000100 /* bit 8 */
#define MACREG_A2HRIC_BIT_WEAKIV_ERROR 0x00000200 /* bit 9 */
-#define MACREG_A2HRIC_BIT_QUEUE_EMPTY (1<<10)
-#define MACREG_A2HRIC_BIT_QUEUE_FULL (1<<11)
+#define MACREG_A2HRIC_BIT_QUEUE_EMPTY (1<<10)
+#define MACREG_A2HRIC_BIT_QUEUE_FULL (1<<11)
#define MACREG_A2HRIC_BIT_CHAN_SWITCH (1<<12) /* IEEE80211_DH */
-#define MACREG_A2HRIC_BIT_TX_WATCHDOG (1<<13)
+#define MACREG_A2HRIC_BIT_TX_WATCHDOG (1<<13)
#define MACREG_A2HRIC_BA_WATCHDOG (1<<14)
#define MACREG_A2HRIC_BIT_SSU_DONE (1<<16)
-#define MACREG_A2HRIC_CONSEC_TXFAIL (1<<17) /* 15 taken by ISR_TXACK */
+#define MACREG_A2HRIC_CONSEC_TXFAIL (1<<17) /* 15 taken by ISR_TXACK */
#define ISR_SRC_BITS ((MACREG_A2HRIC_BIT_RX_RDY) | \
(MACREG_A2HRIC_BIT_TX_DONE) | \
@@ -82,7 +82,7 @@
(MACREG_A2HRIC_BIT_SSU_DONE) | \
(MACREG_A2HRIC_BIT_RADAR_DETECT)| \
(MACREG_A2HRIC_BIT_CHAN_SWITCH)| \
- (MACREG_A2HRIC_BIT_TX_WATCHDOG)| \
+ (MACREG_A2HRIC_BIT_TX_WATCHDOG)| \
(MACREG_A2HRIC_BIT_QUEUE_EMPTY)| \
(MACREG_A2HRIC_BA_WATCHDOG) | \
(MACREG_A2HRIC_CONSEC_TXFAIL))
@@ -93,9 +93,9 @@
*/
#define MACREG_H2ARIC_BIT_PPA_READY 0x00000001 /* bit 0 */
#define MACREG_H2ARIC_BIT_DOOR_BELL 0x00000002 /* bit 1 */
-#define MACREG_H2ARIC_BIT_PS 0x00000004 /* bit 2 */
-#define MACREG_H2ARIC_BIT_PSPOLL 0x00000008 /* bit 3 */
-#define ISR_RESET (1<<15)
+#define MACREG_H2ARIC_BIT_PS 0x00000004 /* bit 2 */
+#define MACREG_H2ARIC_BIT_PSPOLL 0x00000008 /* bit 3 */
+#define ISR_RESET (1<<15)
#define ISR_RESET_AP33 (1<<26)
/* Data descriptor related constants
@@ -130,6 +130,13 @@
#define NBR_BYTES_FW_RX_PREPEND_LEN 2
#define NBR_BYTES_FW_TX_PREPEND_LEN 2
+/* Antenna control
+*/
+#define ANTENNA_TX_4_AUTO 0
+#define ANTENNA_TX_2 3
+#define ANTENNA_RX_4_AUTO 0
+#define ANTENNA_RX_2 2
+
/* Misc
*/
#define WL_SEC_SLEEP(num_secs) mdelay(num_secs * 1000)
@@ -158,41 +165,32 @@
*/
enum {
-
AP_MODE_11AC = 0x10, /* generic 11ac indication mode */
- AP_MODE_2_4GHZ_11AC_MIXED = 0x17,
-
+ AP_MODE_2_4GHZ_11AC_MIXED = 0x17,
};
enum {
-
AMPDU_NO_STREAM,
AMPDU_STREAM_NEW,
AMPDU_STREAM_IN_PROGRESS,
AMPDU_STREAM_ACTIVE,
-
};
enum {
-
IEEE_TYPE_MANAGEMENT = 0,
IEEE_TYPE_CONTROL,
IEEE_TYPE_DATA
-
};
struct mwl_tx_pwr_tbl {
-
u8 channel;
u8 setcap;
u16 tx_power[SYSADPT_TX_POWER_LEVEL_TOTAL];
u8 cdd; /* 0: off, 1: on */
u16 txantenna2;
-
};
struct mwl_hw_data {
-
u32 fw_release_num; /* MajNbr:MinNbr:SubMin:PatchLevel */
u8 hw_version; /* plain number indicating version */
u8 host_interface; /* plain number of interface */
@@ -201,11 +199,9 @@ struct mwl_hw_data {
u16 num_antennas; /* number antennas used */
u16 region_code; /* region (eg. 0x10 for USA FCC) */
unsigned char mac_addr[ETH_ALEN]; /* well known -> AA:BB:CC:DD:EE:FF */
-
};
struct mwl_rate_info {
-
u32 format:1; /* 0 = Legacy format, 1 = Hi-throughput format */
u32 short_gi:1; /* 0 = Use standard guard interval,1 = Use short guard interval */
u32 bandwidth:1; /* 0 = Use 20 MHz channel,1 = Use 40 MHz channel */
@@ -222,11 +218,9 @@ struct mwl_rate_info {
u32 count:4;
u32 rsvd2:3;
u32 drop:1;
-
} __packed;
struct mwl_tx_desc {
-
u8 data_rate;
u8 tx_priority;
u16 qos_ctrl;
@@ -238,41 +232,45 @@ struct mwl_tx_desc {
struct mwl_rate_info rate_info;
u8 type;
u8 xmit_control; /* bit 0: use rateinfo, bit 1: disable ampdu */
- u16 reserved;
+ u16 reserved;
u32 tcpack_sn;
u32 tcpack_src_dst;
struct sk_buff *psk_buff;
struct mwl_tx_desc *pnext;
- u32 soft_stat;
- u32 ack_wcb_addr;
+ u8 reserved1[2];
+ u8 packet_info;
+ u8 packet_id;
+ u16 packet_len_and_retry;
+ u16 packet_rate_info;
u8 *sta_info;
- u32 status;
-
+ u32 status;
} __packed;
struct mwl_hw_rssi_info {
-
u32 rssi_a:8;
u32 rssi_b:8;
u32 rssi_c:8;
u32 rssi_d:8;
-
} __packed;
struct mwl_hw_noise_floor_info {
-
u32 noise_floor_a:8;
u32 noise_floor_b:8;
u32 noise_floor_c:8;
u32 noise_floor_d:8;
-
} __packed;
-struct mwl_rx_desc {
+struct mwl_rxrate_info {
+ u16 format:3; /* 0: 11a, 1: 11b, 2: 11n, 4: 11ac */
+ u16 nss:2; /* number space spectrum */
+ u16 bw:2; /* 0: ht20, 1: ht40, 2: ht80 */
+ u16 gi:1; /* 0: long interval, 1: short interval*/
+ u16 rt:8; /* 11a/11b: 1,2,5,11,22,6,9,12,18,24,36,48,54,72*/
+} __packed; /* 11n/11ac: MCS */
+struct mwl_rx_desc {
u16 pkt_len; /* total length of received data */
- u8 sq2; /* unused at the moment */
- u8 rate; /* received data rate */
+ struct mwl_rxrate_info rate; /* receive rate information */
u32 pphys_buff_data; /* physical address of payload data */
u32 pphys_next; /* physical address of next RX desc */
u16 qos_ctrl; /* received QosCtrl field variable */
@@ -289,11 +287,9 @@ struct mwl_rx_desc {
struct sk_buff *psk_buff; /* associated sk_buff for Linux */
void *pbuff_data; /* virtual address of payload data */
struct mwl_rx_desc *pnext; /* virtual address of next RX desc */
-
} __packed;
struct mwl_desc_data {
-
dma_addr_t pphys_tx_ring; /* ptr to first TX desc (phys.) */
struct mwl_tx_desc *ptx_ring; /* ptr to first TX desc (virt.) */
struct mwl_tx_desc *pnext_tx_desc; /* next TX desc that can be used */
@@ -305,32 +301,30 @@ struct mwl_desc_data {
unsigned int rx_desc_write; /* FW descriptor write position */
unsigned int rx_desc_read; /* FW descriptor read position */
unsigned int rx_buf_size; /* length of the RX buffers */
-
} __packed;
struct mwl_locks {
-
DECLARE_LOCK(xmit_lock); /* used to protect TX actions */
DECLARE_LOCK(fwcmd_lock); /* used to protect FW commands */
DECLARE_LOCK(stream_lock); /* used to protect stream */
-
};
struct mwl_ampdu_stream {
-
struct ieee80211_sta *sta;
u8 tid;
u8 state;
u8 idx;
-
};
struct mwl_priv {
-
struct ieee80211_hw *hw;
-
const struct firmware *fw_ucode;
-
+ struct device_node *dt_node;
+ struct device_node *pwr_node;
+ bool disable_2g;
+ bool disable_5g;
+ int antenna_tx;
+ int antenna_rx;
struct mwl_tx_pwr_tbl tx_pwr_tbl[SYSADPT_MAX_NUM_CHANNELS];
u32 cdd; /* 0: off, 1: on */
u16 txantenna2;
@@ -338,27 +332,20 @@ struct mwl_priv {
u16 max_tx_pow[SYSADPT_TX_POWER_LEVEL_TOTAL]; /* max tx power (dBm) */
u16 target_powers[SYSADPT_TX_POWER_LEVEL_TOTAL]; /* target powers (dBm) */
u8 cal_tbl[200];
-
struct pci_dev *pdev;
void *iobase0; /* MEM Base Address Register 0 */
void *iobase1; /* MEM Base Address Register 1 */
u32 next_bar_num;
-
unsigned short *pcmd_buf; /* pointer to CmdBuf (virtual) */
dma_addr_t pphys_cmd_buf; /* pointer to CmdBuf (physical) */
bool in_send_cmd;
-
int irq;
-
struct mwl_hw_data hw_data; /* Adapter HW specific info */
-
struct mwl_desc_data desc_data[SYSADPT_NUM_OF_DESC_DATA]; /* various descriptor data */
struct sk_buff_head txq[SYSADPT_NUM_OF_DESC_DATA];
struct sk_buff_head delay_freeq;
int fw_desc_cnt[SYSADPT_NUM_OF_DESC_DATA]; /* number of descriptors owned by fw at any one time */
-
struct mwl_locks locks; /* various spinlocks */
-
struct tasklet_struct tx_task;
struct tasklet_struct rx_task;
int txq_limit;
@@ -366,35 +353,28 @@ struct mwl_priv {
int recv_limit;
bool is_rx_schedule;
s8 noise; /* Most recently reported noise in dBm */
-
struct ieee80211_supported_band band_24;
struct ieee80211_channel channels_24[14];
struct ieee80211_rate rates_24[13];
struct ieee80211_supported_band band_50;
struct ieee80211_channel channels_50[24];
struct ieee80211_rate rates_50[8];
-
u32 ap_macids_supported;
u32 sta_macids_supported;
u32 macids_used;
struct list_head vif_list; /* List of interfaces. */
u32 running_bsses; /* bitmap of running BSSes */
-
bool radio_on;
bool radio_short_preamble;
-
bool wmm_enabled;
struct ieee80211_tx_queue_params wmm_params[SYSADPT_TX_WMM_QUEUES];
-
/* Ampdu stream information */
u8 num_ampdu_queues;
struct mwl_ampdu_stream ampdu[SYSADPT_TX_AMPDU_QUEUES];
struct work_struct watchdog_ba_handle;
-
};
struct beacon_info {
-
bool valid;
u16 cap_info;
u8 bss_basic_rate_set[SYSADPT_MAX_DATA_RATES_G];
@@ -414,69 +394,53 @@ struct beacon_info {
};
struct mwl_vif {
-
struct list_head list;
struct ieee80211_vif *vif;
-
int macid; /* Firmware macid for this vif. */
-
u16 seqno; /* Non AMPDU sequence number assigned by driver. */
-
struct { /* Saved WEP keys */
u8 enabled;
u8 key[sizeof(struct ieee80211_key_conf) + MAX_WEP_KEY_LEN];
} wep_key_conf[NUM_WEP_KEYS];
-
u8 bssid[ETH_ALEN]; /* BSSID */
-
+ u8 sta_mac[ETH_ALEN]; /* Station mac address */
bool is_hw_crypto_enabled; /* A flag to indicate is HW crypto is enabled for this bssid */
-
+ bool is_sta; /* Indicate if this is station mode */
struct beacon_info beacon_info;
-
u16 iv16;
u32 iv32;
s8 keyidx;
-
};
struct mwl_tx_info {
-
u32 start_time;
u32 pkts;
-
};
struct mwl_sta {
-
u8 is_ampdu_allowed;
struct mwl_tx_info tx_stats[MWL_MAX_TID];
-
u16 iv16;
u32 iv32;
-
};
/* DMA header used by firmware and hardware.
*/
struct mwl_dma_data {
-
u16 fwlen;
struct ieee80211_hdr wh;
char data[0];
-
} __packed;
/* Transmission information to transmit a socket buffer.
*/
struct mwl_tx_ctrl {
-
u8 tx_priority;
u16 qos_ctrl;
u8 type;
u8 xmit_control;
u8 *sta_info;
bool ccmp;
-
} __packed;
#endif /* _mwl_dev_h_ */
diff --git a/mwl_fwcmd.c b/mwl_fwcmd.c
index 9cb95bd..6270177 100644
--- a/mwl_fwcmd.c
+++ b/mwl_fwcmd.c
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2006-2014 Marvell International Ltd.
+* Copyright (c) 2006-2015 Marvell International Ltd.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -34,28 +34,32 @@
* 16 bit host command code
*/
#define HOSTCMD_CMD_GET_HW_SPEC 0x0003
-#define HOSTCMD_CMD_SET_HW_SPEC 0x0004
+#define HOSTCMD_CMD_SET_HW_SPEC 0x0004
#define HOSTCMD_CMD_802_11_GET_STAT 0x0014
#define HOSTCMD_CMD_802_11_RADIO_CONTROL 0x001c
#define HOSTCMD_CMD_802_11_TX_POWER 0x001f
#define HOSTCMD_CMD_802_11_RF_ANTENNA 0x0020
#define HOSTCMD_CMD_BROADCAST_SSID_ENABLE 0x0050 /* per-vif */
#define HOSTCMD_CMD_SET_RF_CHANNEL 0x010a
+#define HOSTCMD_CMD_SET_AID 0x010d /* per-vif */
+#define HOSTCMD_CMD_SET_INFRA_MODE 0x010e /* per-vif */
#define HOSTCMD_CMD_802_11_RTS_THSD 0x0113
#define HOSTCMD_CMD_SET_EDCA_PARAMS 0x0115
#define HOSTCMD_CMD_SET_WMM_MODE 0x0123
#define HOSTCMD_CMD_SET_FIXED_RATE 0x0126
#define HOSTCMD_CMD_SET_IES 0x0127
-#define HOSTCMD_CMD_SET_RATE_ADAPT_MODE 0x0203
+#define HOSTCMD_CMD_SET_MAC_ADDR 0x0202 /* per-vif */
+#define HOSTCMD_CMD_SET_RATE_ADAPT_MODE 0x0203
#define HOSTCMD_CMD_GET_WATCHDOG_BITMAP 0x0205
+#define HOSTCMD_CMD_DEL_MAC_ADDR 0x0206 /* pre-vif */
#define HOSTCMD_CMD_BSS_START 0x1100 /* per-vif */
#define HOSTCMD_CMD_AP_BEACON 0x1101 /* per-vif */
#define HOSTCMD_CMD_SET_NEW_STN 0x1111 /* per-vif */
#define HOSTCMD_CMD_SET_APMODE 0x1114
-#define HOSTCMD_CMD_UPDATE_ENCRYPTION 0x1122 /* per-vif */
-#define HOSTCMD_CMD_BASTREAM 0x1125
-#define HOSTCMD_CMD_DWDS_ENABLE 0x1144
-#define HOSTCMD_CMD_FW_FLUSH_TIMER 0x1148
+#define HOSTCMD_CMD_UPDATE_ENCRYPTION 0x1122 /* per-vif */
+#define HOSTCMD_CMD_BASTREAM 0x1125
+#define HOSTCMD_CMD_DWDS_ENABLE 0x1144
+#define HOSTCMD_CMD_FW_FLUSH_TIMER 0x1148
#define HOSTCMD_CMD_SET_CDD 0x1150
/*
@@ -71,8 +75,8 @@
/*
* Define channel related constants
*/
-#define FREQ_BAND_2DOT4GHZ 0x1
-#define FREQ_BAND_4DOT9GHZ 0x2
+#define FREQ_BAND_2DOT4GHZ 0x1
+#define FREQ_BAND_4DOT9GHZ 0x2
#define FREQ_BAND_5GHZ 0x4
#define FREQ_BAND_5DOT2GHZ 0x8
#define CH_AUTO_WIDTH 0
@@ -111,15 +115,15 @@
#define MAX_ENCR_KEY_LENGTH 16
#define MIC_KEY_LENGTH 8
-#define KEY_TYPE_ID_WEP 0x00 /* Key type is WEP */
-#define KEY_TYPE_ID_TKIP 0x01 /* Key type is TKIP */
-#define KEY_TYPE_ID_AES 0x02 /* Key type is AES-CCMP */
+#define KEY_TYPE_ID_WEP 0x00 /* Key type is WEP */
+#define KEY_TYPE_ID_TKIP 0x01 /* Key type is TKIP */
+#define KEY_TYPE_ID_AES 0x02 /* Key type is AES-CCMP */
-#define ENCR_KEY_FLAG_TXGROUPKEY 0x00000004 /* Group key for TX */
-#define ENCR_KEY_FLAG_PAIRWISE 0x00000008 /* pairwise */
-#define ENCR_KEY_FLAG_TSC_VALID 0x00000040 /* Sequence counters are valid */
-#define ENCR_KEY_FLAG_WEP_TXKEY 0x01000000 /* Tx key for WEP */
-#define ENCR_KEY_FLAG_MICKEY_VALID 0x02000000 /* Tx/Rx MIC keys are valid */
+#define ENCR_KEY_FLAG_TXGROUPKEY 0x00000004 /* Group key for TX */
+#define ENCR_KEY_FLAG_PAIRWISE 0x00000008 /* pairwise */
+#define ENCR_KEY_FLAG_TSC_VALID 0x00000040 /* Sequence counters are valid */
+#define ENCR_KEY_FLAG_WEP_TXKEY 0x01000000 /* Tx key for WEP */
+#define ENCR_KEY_FLAG_MICKEY_VALID 0x02000000 /* Tx/Rx MIC keys are valid */
/*
* Define block ack related constants
@@ -137,7 +141,7 @@
/* Misc
*/
#define MWL_SPIN_LOCK(X) SPIN_LOCK_IRQSAVE(X, flags)
-#define MWL_SPIN_UNLOCK(X) SPIN_UNLOCK_IRQRESTORE(X, flags)
+#define MWL_SPIN_UNLOCK(X) SPIN_UNLOCK_IRQRESTORE(X, flags)
#define MAX_ENCR_KEY_LENGTH 16
#define MIC_KEY_LENGTH 8
@@ -146,31 +150,24 @@
*/
enum {
-
WL_DISABLE = 0,
WL_ENABLE = 1,
WL_DISABLE_VMAC = 0x80,
-
};
enum {
-
WL_GET = 0,
WL_SET = 1,
WL_RESET = 2,
-
};
enum {
-
WL_LONG_PREAMBLE = 1,
WL_SHORT_PREAMBLE = 3,
WL_AUTO_PREAMBLE = 5,
-
};
enum encr_action_type {
-
/* request to enable/disable HW encryption */
ENCR_ACTION_ENABLE_HW_ENCR,
/* request to set encryption key */
@@ -178,17 +175,21 @@ enum encr_action_type {
/* request to remove one or more keys */
ENCR_ACTION_TYPE_REMOVE_KEY,
ENCR_ACTION_TYPE_SET_GROUP_KEY,
-
};
enum ba_action_type {
-
BA_CREATE_STREAM,
BA_UPDATE_STREAM,
BA_DESTROY_STREAM,
BA_FLUSH_STREAM,
BA_CHECK_STREAM,
+};
+enum mac_type {
+ WL_MAC_TYPE_PRIMARY_CLIENT,
+ WL_MAC_TYPE_SECONDARY_CLIENT,
+ WL_MAC_TYPE_PRIMARY_AP,
+ WL_MAC_TYPE_SECONDARY_AP,
};
/*
@@ -196,13 +197,11 @@ enum ba_action_type {
*/
struct hostcmd_header {
-
u16 cmd;
u16 len;
u8 seq_num;
u8 macid;
u16 result;
-
} __packed;
/*
@@ -210,7 +209,6 @@ struct hostcmd_header {
*/
struct hostcmd_cmd_get_hw_spec {
-
struct hostcmd_header cmd_hdr;
u8 version; /* version of the HW */
u8 host_if; /* host interface */
@@ -225,7 +223,6 @@ struct hostcmd_cmd_get_hw_spec {
u32 rxpd_rd_ptr;
u32 fw_awake_cookie;
u32 wcb_base[SYSADPT_TOTAL_TX_QUEUES - 1];
-
} __packed;
/*
@@ -233,7 +230,6 @@ struct hostcmd_cmd_get_hw_spec {
*/
struct hostcmd_cmd_set_hw_spec {
-
struct hostcmd_header cmd_hdr;
u8 version; /* HW revision */
u8 host_if; /* Host interface */
@@ -259,7 +255,6 @@ struct hostcmd_cmd_set_hw_spec {
u32 reserved: 21; /* Reserved */
u32 tx_wcb_num_per_queue;
u32 total_rx_wcb;
-
} __packed;
/*
@@ -267,7 +262,6 @@ struct hostcmd_cmd_set_hw_spec {
*/
struct hostcmd_cmd_802_11_get_stat {
-
struct hostcmd_header cmd_hdr;
u32 tx_retry_successes;
u32 tx_multiple_retry_successes;
@@ -302,7 +296,6 @@ struct hostcmd_cmd_802_11_get_stat {
u32 rx_errors;
u32 rx_rts_count;
u32 tx_cts_count;
-
} __packed;
/*
@@ -310,12 +303,10 @@ struct hostcmd_cmd_802_11_get_stat {
*/
struct hostcmd_cmd_802_11_radio_control {
-
struct hostcmd_header cmd_hdr;
u16 action;
u16 control; /* @bit0: 1/0,on/off, @bit1: 1/0, long/short @bit2: 1/0,auto/fix */
u16 radio_on;
-
} __packed;
/*
@@ -323,7 +314,6 @@ struct hostcmd_cmd_802_11_radio_control {
*/
struct hostcmd_cmd_802_11_tx_power {
-
struct hostcmd_header cmd_hdr;
u16 action;
u16 band;
@@ -331,7 +321,6 @@ struct hostcmd_cmd_802_11_tx_power {
u16 bw;
u16 sub_ch;
u16 power_level_list[SYSADPT_TX_POWER_LEVEL_TOTAL];
-
} __packed;
/*
@@ -339,11 +328,9 @@ struct hostcmd_cmd_802_11_tx_power {
*/
struct hostcmd_cmd_802_11_rf_antenna {
-
struct hostcmd_header cmd_hdr;
u16 action;
u16 antenna_mode; /* Number of antennas or 0xffff(diversity) */
-
} __packed;
/*
@@ -351,10 +338,8 @@ struct hostcmd_cmd_802_11_rf_antenna {
*/
struct hostcmd_cmd_broadcast_ssid_enable {
-
struct hostcmd_header cmd_hdr;
u32 enable;
-
} __packed;
/*
@@ -362,21 +347,37 @@ struct hostcmd_cmd_broadcast_ssid_enable {
*/
struct chnl_flags_11ac {
-
u32 freq_band:6; /* bit0=1: 2.4GHz,bit1=1: 4.9GHz,bit2=1: 5GHz,bit3=1: 5.2GHz, */
u32 chnl_width:5; /* bit6=1:10MHz, bit7=1:20MHz, bit8=1:40MHz */
u32 act_primary:3; /* 000: 1st 20MHz chan, 001:2nd 20MHz chan, 011:3rd 20MHz chan, 100:4th 20MHz chan */
u32 reserved:18;
-
} __packed;
struct hostcmd_cmd_set_rf_channel {
-
struct hostcmd_header cmd_hdr;
u16 action;
u8 curr_chnl;
struct chnl_flags_11ac chnl_flags;
+} __packed;
+
+/*
+ * HOSTCMD_CMD_SET_AID
+ */
+
+struct hostcmd_cmd_set_aid {
+ struct hostcmd_header cmd_hdr;
+ u16 aid;
+ u8 mac_addr[ETH_ALEN]; /* AP's Mac Address(BSSID) */
+ u32 gprotect;
+ u8 ap_rates[SYSADPT_MAX_DATA_RATES_G];
+} __packed;
+/*
+ * HOSTCMD_CMD_SET_INFRA_MODE
+ */
+
+struct hostcmd_cmd_set_infra_mode {
+ struct hostcmd_header cmd_hdr;
} __packed;
/*
@@ -384,11 +385,9 @@ struct hostcmd_cmd_set_rf_channel {
*/
struct hostcmd_cmd_802_11_rts_thsd {
-
struct hostcmd_header cmd_hdr;
u16 action;
u16 threshold;
-
} __packed;
/*
@@ -396,7 +395,6 @@ struct hostcmd_cmd_802_11_rts_thsd {
*/
struct hostcmd_cmd_set_edca_params {
-
struct hostcmd_header cmd_hdr;
u16 action; /* 0 = get all, 0x1 =set CWMin/Max, 0x2 = set TXOP , 0x4 =set AIFSN */
u16 txop; /* in unit of 32 us */
@@ -404,7 +402,6 @@ struct hostcmd_cmd_set_edca_params {
u32 cw_min; /* 0~15 */
u8 aifsn;
u8 txq_num; /* Tx Queue number. */
-
} __packed;
/*
@@ -412,33 +409,26 @@ struct hostcmd_cmd_set_edca_params {
*/
struct hostcmd_cmd_set_wmm_mode {
-
struct hostcmd_header cmd_hdr;
u16 action; /* 0->unset, 1->set */
-
} __packed;
/*
* HOSTCMD_CMD_SET_FIXED_RATE
*/
-struct fix_rate_flag {
- /* lower rate after the retry count */
+struct fix_rate_flag { /* lower rate after the retry count */
u32 fix_rate_type; /* 0: legacy, 1: HT */
u32 retry_count_valid; /* 0: retry count is not valid, 1: use retry count specified */
-
} __packed;
struct fix_rate_entry {
-
struct fix_rate_flag fix_rate_type_flags;
u32 fixed_rate; /* depending on the flags above, this can be either a legacy rate(not index) or an MCS code. */
u32 retry_count;
-
} __packed;
struct hostcmd_cmd_set_fixed_rate {
-
struct hostcmd_header cmd_hdr;
u32 action; /* HOSTCMD_ACT_NOT_USE_FIXED_RATE 0x0002 */
u32 allow_rate_drop; /* use fixed rate specified but firmware can drop to */
@@ -447,7 +437,6 @@ struct hostcmd_cmd_set_fixed_rate {
u8 multicast_rate;
u8 multi_rate_tx_type;
u8 management_rate;
-
} __packed;
/*
@@ -455,7 +444,6 @@ struct hostcmd_cmd_set_fixed_rate {
*/
struct hostcmd_cmd_set_ies {
-
struct hostcmd_header cmd_hdr;
u16 action; /* 0->unset, 1->set */
u16 ie_list_len_ht;
@@ -465,7 +453,6 @@ struct hostcmd_cmd_set_ies {
u8 ie_list_ht[148];
u8 ie_list_vht[24];
u8 ie_list_proprietary[112];
-
} __packed;
/*
@@ -473,11 +460,19 @@ struct hostcmd_cmd_set_ies {
*/
struct hostcmd_cmd_set_rate_adapt_mode {
-
struct hostcmd_header cmd_hdr;
u16 action;
u16 rate_adapt_mode; /* 0:Indoor, 1:Outdoor */
+} __packed;
+/*
+ * HOSTCMD_CMD_SET_MAC_ADDR, HOSTCMD_CMD_DEL_MAC_ADDR
+ */
+
+struct hostcmd_cmd_set_mac_addr {
+ struct hostcmd_header cmd_hdr;
+ u16 mac_type;
+ u8 mac_addr[ETH_ALEN];
} __packed;
/*
@@ -485,10 +480,8 @@ struct hostcmd_cmd_set_rate_adapt_mode {
*/
struct hostcmd_cmd_get_watchdog_bitmap {
-
struct hostcmd_header cmd_hdr;
u8 watchdog_bitmap; /* for SW/BA */
-
} __packed;
/*
@@ -496,10 +489,8 @@ struct hostcmd_cmd_get_watchdog_bitmap {
*/
struct hostcmd_cmd_bss_start {
-
struct hostcmd_header cmd_hdr;
u32 enable; /* FALSE: Disable or TRUE: Enable */
-
} __packed;
/*
@@ -507,59 +498,46 @@ struct hostcmd_cmd_bss_start {
*/
struct cf_params {
-
u8 elem_id;
u8 len;
u8 cfp_cnt;
u8 cfp_period;
u16 cfp_max_duration;
u16 cfp_duration_remaining;
-
} __packed;
struct ibss_params {
-
u8 elem_id;
u8 len;
u16 atim_window;
-
} __packed;
union ss_params {
-
struct cf_params cf_param_set;
struct ibss_params ibss_param_set;
-
} __packed;
struct fh_params {
-
u8 elem_id;
u8 len;
u16 dwell_time;
u8 hop_set;
u8 hop_pattern;
u8 hop_index;
-
} __packed;
struct ds_params {
-
u8 elem_id;
u8 len;
u8 current_chnl;
-
} __packed;
union phy_params {
-
struct fh_params fh_param_set;
struct ds_params ds_param_set;
-
} __packed;
struct rsn_ie {
-
u8 elem_id;
u8 len;
u8 oui_type[4]; /* 00:50:f2:01 */
@@ -569,11 +547,9 @@ struct rsn_ie {
u8 pws_key_cipher_list[4];
u8 auth_key_cnt[2];
u8 auth_key_list[4];
-
} __packed;
struct rsn48_ie {
-
u8 elem_id;
u8 len;
u8 ver[2];
@@ -583,35 +559,30 @@ struct rsn48_ie {
u8 auth_key_cnt[2];
u8 auth_key_list[4];
u8 rsn_cap[2];
-
+ u8 pmk_id_cnt[2];
+ u8 pmk_id_list[16]; /* Should modify to 16 * S */
+ u8 reserved[8];
} __packed;
struct aci_aifsn_field {
-
u8 aifsn:4;
u8 acm:1;
u8 aci:2;
u8 rsvd:1;
-
} __packed;
struct ecw_min_max_field {
-
u8 ecw_min:4;
u8 ecw_max:4;
-
} __packed;
struct ac_param_rcd {
-
struct aci_aifsn_field aci_aifsn;
struct ecw_min_max_field ecw_min_max;
u16 txop_lim;
-
} __packed;
struct wmm_param_elem {
-
u8 elem_id;
u8 len;
u8 oui[3];
@@ -623,28 +594,22 @@ struct wmm_param_elem {
struct ac_param_rcd ac_bk;
struct ac_param_rcd ac_vi;
struct ac_param_rcd ac_vo;
-
} __packed;
struct channel_info {
-
u8 first_channel_num;
u8 num_channels;
u8 max_tx_pwr_level;
-
} __packed;
struct country {
-
u8 elem_id;
u8 len;
u8 country_str[3];
struct channel_info channel_info[40];
-
} __packetd;
struct start_cmd {
-
u8 sta_mac_addr[ETH_ALEN];
u8 ssid[IEEE80211_MAX_SSID_LEN];
u8 bss_type;
@@ -661,14 +626,11 @@ struct start_cmd {
struct wmm_param_elem wmm_param;
struct country country;
u32 ap_rf_type; /* 0->B, 1->G, 2->Mixed, 3->A, 4->11J */
-
} __packed;
struct hostcmd_cmd_ap_beacon {
-
struct hostcmd_header cmd_hdr;
struct start_cmd start_cmd;
-
} __packed;
/*
@@ -676,7 +638,6 @@ struct hostcmd_cmd_ap_beacon {
*/
struct cap_info {
-
u16 ess:1;
u16 ibss:1;
u16 cf_pollable:1;
@@ -693,31 +654,25 @@ struct cap_info {
u16 dsss_ofdm:1;
u16 block_ack:1;
u16 rsrvd2:1;
-
} __packed;
struct add_ht_chnl {
-
u8 ext_chnl_offset:2;
u8 sta_chnl_width:1;
u8 rifs_mode:1;
u8 psmp_stas_only:1;
u8 srvc_intvl_gran:3;
-
} __packed;
struct add_ht_op_mode {
-
u16 op_mode:2;
u16 non_gf_sta_present:1;
u16 rrans_burst_limit:1;
u16 non_ht_sta_present:1;
u16 rsrv:11;
-
} __packed;
struct add_ht_stbc {
-
u16 bsc_stbc:7;
u16 dual_stbc_proc:1;
u16 scd_bcn:1;
@@ -725,20 +680,16 @@ struct add_ht_stbc {
u16 pco_active:1;
u16 pco_phase:1;
u16 rsrv:4;
-
} __packed;
struct add_ht_info {
-
u8 control_chnl;
struct add_ht_chnl add_chnl;
struct add_ht_op_mode op_mode;
struct add_ht_stbc stbc;
-
} __packed;
struct peer_info {
-
u32 legacy_rate_bitmap;
u8 ht_rates[4];
struct cap_info cap_info;
@@ -750,11 +701,9 @@ struct peer_info {
u32 vht_max_rx_mcs;
u32 vht_cap;
u8 vht_rx_channel_width; /* 0:20Mhz, 1:40Mhz, 2:80Mhz, 3:160 or 80+80Mhz */
-
} __packed;
struct hostcmd_cmd_set_new_stn {
-
struct hostcmd_header cmd_hdr;
u16 aid;
u8 mac_addr[ETH_ALEN];
@@ -766,7 +715,6 @@ struct hostcmd_cmd_set_new_stn {
u8 qos_info;
u8 is_qos_sta;
u32 fw_sta_ptr;
-
} __packed;
/*
@@ -774,10 +722,8 @@ struct hostcmd_cmd_set_new_stn {
*/
struct hostcmd_cmd_set_apmode {
-
struct hostcmd_header cmd_hdr;
u8 apmode;
-
} __packed;
/*
@@ -785,7 +731,6 @@ struct hostcmd_cmd_set_apmode {
*/
struct hostcmd_cmd_update_encryptoin {
-
struct hostcmd_header cmd_hdr;
/* Action type - see encr_action_type */
u32 action_type; /* encr_action_type */
@@ -793,25 +738,19 @@ struct hostcmd_cmd_update_encryptoin {
u32 data_length;
u8 mac_addr[ETH_ALEN];
u8 action_data[1];
-
} __packed;
struct wep_type_key {
-
/* WEP key material (max 128bit) */
u8 key_material[MAX_ENCR_KEY_LENGTH];
-
} __packed;
struct encr_tkip_seqcnt {
-
u16 low;
u32 high;
-
} __packed;
struct tkip_type_key {
-
/* TKIP Key material. Key type (group or pairwise key) is determined by flags */
/* in KEY_PARAM_SET structure. */
u8 key_material[MAX_ENCR_KEY_LENGTH];
@@ -820,26 +759,20 @@ struct tkip_type_key {
u8 tkip_rx_mic_key[MIC_KEY_LENGTH];
struct encr_tkip_seqcnt tkip_rsc;
struct encr_tkip_seqcnt tkip_tsc;
-
} __packed;
struct aes_type_key {
-
/* AES Key material */
u8 key_material[MAX_ENCR_KEY_LENGTH];
-
} __packed;
union mwl_key_type {
-
struct wep_type_key wep_key;
struct tkip_type_key tkip_key;
struct aes_type_key aes_key;
-
} __packed;
struct key_param_set {
-
/* Total length of this structure (Key is variable size array) */
u16 length;
/* Key type - WEP, TKIP or AES-CCMP. */
@@ -854,11 +787,9 @@ struct key_param_set {
/* Key material (variable size array) */
union mwl_key_type key;
u8 mac_addr[ETH_ALEN];
-
} __packed;
struct hostcmd_cmd_set_key {
-
struct hostcmd_header cmd_hdr;
/* Action type - see encr_action_type */
u32 action_type; /* encr_action_type */
@@ -866,7 +797,6 @@ struct hostcmd_cmd_set_key {
u32 data_length;
/* data buffer - maps to one KEY_PARAM_SET structure */
struct key_param_set key_param;
-
} __packed;
/*
@@ -874,17 +804,13 @@ struct hostcmd_cmd_set_key {
*/
struct ba_stream_flags {
-
u32 ba_type:1;
u32 ba_direction:3;
u32 reserved:24;
-
} __packed;
struct ba_context {
-
u32 context;
-
} __packed;
/* parameters for block ack creation */
@@ -912,32 +838,26 @@ struct create_ba_params {
u8 reset_seq_no; /** 0 or 1**/
u16 current_seq;
u8 sta_src_mac_addr[ETH_ALEN]; /* This is for virtual station in Sta proxy mode for V6FW */
-
} __packed;
/* new transmit sequence number information */
struct ba_update_seq_num {
-
/* BA flags - see above */
struct ba_stream_flags flags;
/* returned by firmware in the create ba stream response */
struct ba_context fw_ba_context;
/* new sequence number for this block ack stream */
u16 ba_seq_num;
-
} __packed;
struct ba_stream_context {
-
/* BA Stream flags */
struct ba_stream_flags flags;
/* returned by firmware in the create ba stream response */
struct ba_context fw_ba_context;
-
} __packed;
union ba_info {
-
/* information required to create BA Stream... */
struct create_ba_params create_params;
/* update starting/new sequence number etc. */
@@ -946,15 +866,12 @@ union ba_info {
struct ba_stream_context destroy_params;
/* destroy an existing stream... */
struct ba_stream_context flush_params;
-
} __packed;
struct hostcmd_cmd_bastream {
-
struct hostcmd_header cmd_hdr;
u32 action_type;
union ba_info ba_info;
-
} __packed;
/*
@@ -962,10 +879,8 @@ struct hostcmd_cmd_bastream {
*/
struct hostcmd_cmd_dwds_enable {
-
struct hostcmd_header cmd_hdr;
u32 enable; /* 0 -- Disable. or 1 -- Enable. */
-
} __packed;
/*
@@ -973,10 +888,8 @@ struct hostcmd_cmd_dwds_enable {
*/
struct hostcmd_cmd_fw_flush_timer {
-
struct hostcmd_header cmd_hdr;
u32 value; /* 0 -- Disable. > 0 -- holds time value in usecs. */
-
} __packed;
/*
@@ -984,10 +897,8 @@ struct hostcmd_cmd_fw_flush_timer {
*/
struct hostcmd_cmd_set_cdd {
-
struct hostcmd_header cmd_hdr;
u32 enable;
-
} __packed;
/* PRIVATE FUNCTION DECLARATION
@@ -1030,7 +941,6 @@ void mwl_fwcmd_reset(struct ieee80211_hw *hw)
BUG_ON(!priv);
if (mwl_fwcmd_chk_adapter(priv)) {
-
writel(ISR_RESET, priv->iobase1 + MACREG_REG_H2A_INTERRUPT_EVENTS);
}
@@ -1048,9 +958,7 @@ void mwl_fwcmd_int_enable(struct ieee80211_hw *hw)
BUG_ON(!priv);
if (mwl_fwcmd_chk_adapter(priv)) {
-
writel(0x00, priv->iobase1 + MACREG_REG_A2H_INTERRUPT_MASK);
-
writel((MACREG_A2HRIC_BIT_MASK),
priv->iobase1 + MACREG_REG_A2H_INTERRUPT_MASK);
}
@@ -1069,7 +977,6 @@ void mwl_fwcmd_int_disable(struct ieee80211_hw *hw)
BUG_ON(!priv);
if (mwl_fwcmd_chk_adapter(priv)) {
-
writel(0x00, priv->iobase1 + MACREG_REG_A2H_INTERRUPT_MASK);
}
@@ -1103,7 +1010,6 @@ int mwl_fwcmd_get_hw_specs(struct ieee80211_hw *hw)
WLDBG_DUMP_DATA(DBG_LEVEL_2, (void *)pcmd, sizeof(*pcmd));
while (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_GET_HW_SPEC)) {
-
WLDBG_PRINT("failed execution");
WL_MSEC_SLEEP(1000);
WLDBG_PRINT("repeat command = %x", (unsigned int)pcmd);
@@ -1178,7 +1084,6 @@ int mwl_fwcmd_set_hw_specs(struct ieee80211_hw *hw)
pcmd->disablembss = 0;
if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_SET_HW_SPEC)) {
-
MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
return -EIO;
@@ -1212,7 +1117,6 @@ int mwl_fwcmd_get_stat(struct ieee80211_hw *hw,
pcmd->cmd_hdr.len = ENDIAN_SWAP16(sizeof(*pcmd));
if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_802_11_GET_STAT)) {
-
MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
return -EIO;
@@ -1306,7 +1210,6 @@ int mwl_fwcmd_max_tx_power(struct ieee80211_hw *hw,
BUG_ON(!priv);
switch (fraction) {
-
case 0:
reduce_val = 0; /* Max */
break;
@@ -1331,23 +1234,17 @@ int mwl_fwcmd_max_tx_power(struct ieee80211_hw *hw,
if ((conf->chandef.width == NL80211_CHAN_WIDTH_20_NOHT) ||
(conf->chandef.width == NL80211_CHAN_WIDTH_20)) {
-
width = CH_20_MHz_WIDTH;
sub_ch = NO_EXT_CHANNEL;
} else if (conf->chandef.width == NL80211_CHAN_WIDTH_40) {
-
width = CH_40_MHz_WIDTH;
-
if (conf->chandef.center_freq1 > channel->center_freq)
sub_ch = EXT_CH_ABOVE_CTRL_CH;
else
sub_ch = EXT_CH_BELOW_CTRL_CH;
-
} else if (conf->chandef.width == NL80211_CHAN_WIDTH_80) {
-
width = CH_80_MHz_WIDTH;
-
if (conf->chandef.center_freq1 > channel->center_freq)
sub_ch = EXT_CH_ABOVE_CTRL_CH;
else
@@ -1355,28 +1252,22 @@ int mwl_fwcmd_max_tx_power(struct ieee80211_hw *hw,
}
if ((priv->powinited & 2) == 0) {
-
mwl_fwcmd_get_tx_powers(priv, priv->max_tx_pow,
channel->hw_value, band, width, sub_ch);
-
priv->powinited |= 2;
}
if ((priv->powinited & 1) == 0) {
-
mwl_fwcmd_get_tx_powers(priv, priv->target_powers,
channel->hw_value, band, width, sub_ch);
-
priv->powinited |= 1;
}
for (i = 0; i < SYSADPT_TX_POWER_LEVEL_TOTAL; i++) {
-
if (priv->target_powers[i] > priv->max_tx_pow[i])
tmp = priv->max_tx_pow[i];
else
tmp = priv->target_powers[i];
-
maxtxpow[i] = ((tmp - reduce_val) > 0) ? (tmp - reduce_val) : 0;
}
@@ -1407,7 +1298,6 @@ int mwl_fwcmd_tx_power(struct ieee80211_hw *hw,
BUG_ON(!priv);
switch (fraction) {
-
case 0:
reduce_val = 0; /* Max */
break;
@@ -1432,23 +1322,16 @@ int mwl_fwcmd_tx_power(struct ieee80211_hw *hw,
if ((conf->chandef.width == NL80211_CHAN_WIDTH_20_NOHT) ||
(conf->chandef.width == NL80211_CHAN_WIDTH_20)) {
-
width = CH_20_MHz_WIDTH;
sub_ch = NO_EXT_CHANNEL;
-
} else if (conf->chandef.width == NL80211_CHAN_WIDTH_40) {
-
width = CH_40_MHz_WIDTH;
-
if (conf->chandef.center_freq1 > channel->center_freq)
sub_ch = EXT_CH_ABOVE_CTRL_CH;
else
sub_ch = EXT_CH_BELOW_CTRL_CH;
-
} else if (conf->chandef.width == NL80211_CHAN_WIDTH_80) {
-
width = CH_80_MHz_WIDTH;
-
if (conf->chandef.center_freq1 > channel->center_freq)
sub_ch = EXT_CH_ABOVE_CTRL_CH;
else
@@ -1458,14 +1341,12 @@ int mwl_fwcmd_tx_power(struct ieee80211_hw *hw,
/* search tx power table if exist
*/
for (index = 0; index < SYSADPT_MAX_NUM_CHANNELS; index++) {
-
/* do nothing if table is not loaded
*/
if (priv->tx_pwr_tbl[index].channel == 0)
break;
if (priv->tx_pwr_tbl[index].channel == channel->hw_value) {
-
priv->cdd = priv->tx_pwr_tbl[index].cdd;
priv->txantenna2 = priv->tx_pwr_tbl[index].txantenna2;
@@ -1475,7 +1356,6 @@ int mwl_fwcmd_tx_power(struct ieee80211_hw *hw,
priv->powinited = 0x02;
for (i = 0; i < SYSADPT_TX_POWER_LEVEL_TOTAL; i++) {
-
if (priv->tx_pwr_tbl[index].setcap)
priv->max_tx_pow[i] = priv->tx_pwr_tbl[index].tx_power[i];
else
@@ -1488,7 +1368,6 @@ int mwl_fwcmd_tx_power(struct ieee80211_hw *hw,
}
if ((priv->powinited & 2) == 0) {
-
mwl_fwcmd_get_tx_powers(priv, priv->max_tx_pow,
channel->hw_value, band, width, sub_ch);
@@ -1496,7 +1375,6 @@ int mwl_fwcmd_tx_power(struct ieee80211_hw *hw,
}
if ((priv->powinited & 1) == 0) {
-
mwl_fwcmd_get_tx_powers(priv, priv->target_powers,
channel->hw_value, band, width, sub_ch);
@@ -1504,17 +1382,13 @@ int mwl_fwcmd_tx_power(struct ieee80211_hw *hw,
}
for (i = 0; i < SYSADPT_TX_POWER_LEVEL_TOTAL; i++) {
-
if (found) {
-
if ((priv->tx_pwr_tbl[index].setcap)
&& (priv->tx_pwr_tbl[index].tx_power[i] > priv->max_tx_pow[i]))
tmp = priv->max_tx_pow[i];
else
tmp = priv->tx_pwr_tbl[index].tx_power[i];
-
} else {
-
if (priv->target_powers[i] > priv->max_tx_pow[i])
tmp = priv->max_tx_pow[i];
else
@@ -1555,29 +1429,24 @@ int mwl_fwcmd_rf_antenna(struct ieee80211_hw *hw, int dir, int antenna)
pcmd->action = ENDIAN_SWAP16(dir);
if (dir == WL_ANTENNATYPE_RX) {
-
u8 rx_antenna = 4; /* if auto, set 4 rx antennas in SC2 */
-
+
if (antenna != 0)
pcmd->antenna_mode = ENDIAN_SWAP16(antenna);
else
pcmd->antenna_mode = ENDIAN_SWAP16(rx_antenna);
-
} else {
-
u8 tx_antenna = 0xf; /* if auto, set 4 tx antennas in SC2 */
if (antenna != 0)
pcmd->antenna_mode = ENDIAN_SWAP16(antenna);
else
pcmd->antenna_mode = ENDIAN_SWAP16(tx_antenna);
-
}
WLDBG_DUMP_DATA(DBG_LEVEL_2, (void *)pcmd, sizeof(*pcmd));
if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_802_11_RF_ANTENNA)) {
-
MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
return -EIO;
@@ -1618,7 +1487,6 @@ int mwl_fwcmd_broadcast_ssid_enable(struct ieee80211_hw *hw,
pcmd->enable = ENDIAN_SWAP32(enable);
if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_BROADCAST_SSID_ENABLE)) {
-
MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
return -EIO;
@@ -1661,31 +1529,103 @@ int mwl_fwcmd_set_rf_channel(struct ieee80211_hw *hw,
if ((conf->chandef.width == NL80211_CHAN_WIDTH_20_NOHT) ||
(conf->chandef.width == NL80211_CHAN_WIDTH_20)) {
-
pcmd->chnl_flags.chnl_width = CH_20_MHz_WIDTH;
pcmd->chnl_flags.act_primary = ACT_PRIMARY_CHAN_0;
-
} else if (conf->chandef.width == NL80211_CHAN_WIDTH_40) {
-
pcmd->chnl_flags.chnl_width = CH_40_MHz_WIDTH;
-
if (conf->chandef.center_freq1 > channel->center_freq)
pcmd->chnl_flags.act_primary = ACT_PRIMARY_CHAN_0;
else
pcmd->chnl_flags.act_primary = ACT_PRIMARY_CHAN_1;
-
} else if (conf->chandef.width == NL80211_CHAN_WIDTH_80) {
-
pcmd->chnl_flags.chnl_width = CH_80_MHz_WIDTH;
pcmd->chnl_flags.act_primary =
mwl_fwcmd_get_80m_pri_chnl_offset(pcmd->curr_chnl);
-
}
WLDBG_DUMP_DATA(DBG_LEVEL_2, (void *)pcmd, sizeof(*pcmd));
if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_SET_RF_CHANNEL)) {
+ MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
+ WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
+ return -EIO;
+ }
+
+ MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
+ WLDBG_EXIT(DBG_LEVEL_2);
+
+ return 0;
+}
+
+int mwl_fwcmd_set_aid(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif, u8 *bssid, u16 aid)
+{
+ struct mwl_priv *priv;
+ struct mwl_vif *mwl_vif;
+ struct hostcmd_cmd_set_aid *pcmd;
+ unsigned long flags;
+
+ WLDBG_ENTER(DBG_LEVEL_2);
+
+ BUG_ON(!hw);
+ priv = hw->priv;
+ BUG_ON(!priv);
+
+ BUG_ON(!vif);
+ mwl_vif = MWL_VIF(vif);
+ BUG_ON(!mwl_vif);
+ pcmd = (struct hostcmd_cmd_set_aid *)&priv->pcmd_buf[0];
+
+ MWL_SPIN_LOCK(&priv->locks.fwcmd_lock);
+
+ memset(pcmd, 0x00, sizeof(*pcmd));
+ pcmd->cmd_hdr.cmd = ENDIAN_SWAP16(HOSTCMD_CMD_SET_AID);
+ pcmd->cmd_hdr.len = ENDIAN_SWAP16(sizeof(*pcmd));
+ pcmd->cmd_hdr.macid = mwl_vif->macid;
+ pcmd->aid = ENDIAN_SWAP16(aid);
+ memcpy(pcmd->mac_addr, bssid, ETH_ALEN);
+
+ if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_SET_AID)) {
+ MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
+ WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
+ return -EIO;
+ }
+
+ MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
+ WLDBG_EXIT(DBG_LEVEL_2);
+
+ return 0;
+}
+
+int mwl_fwcmd_set_infra_mode(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif)
+{
+ struct mwl_priv *priv;
+ struct mwl_vif *mwl_vif;
+ struct hostcmd_cmd_set_infra_mode *pcmd;
+ unsigned long flags;
+
+ WLDBG_ENTER(DBG_LEVEL_2);
+
+ BUG_ON(!hw);
+ priv = hw->priv;
+ BUG_ON(!priv);
+
+ BUG_ON(!vif);
+ mwl_vif = MWL_VIF(vif);
+ BUG_ON(!mwl_vif);
+
+ pcmd = (struct hostcmd_cmd_set_infra_mode *)&priv->pcmd_buf[0];
+
+ MWL_SPIN_LOCK(&priv->locks.fwcmd_lock);
+
+ memset(pcmd, 0x00, sizeof(*pcmd));
+ pcmd->cmd_hdr.cmd = ENDIAN_SWAP16(HOSTCMD_CMD_SET_INFRA_MODE);
+ pcmd->cmd_hdr.len = ENDIAN_SWAP16(sizeof(*pcmd));
+ pcmd->cmd_hdr.macid = mwl_vif->macid;
+
+ if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_SET_INFRA_MODE)) {
MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
return -EIO;
@@ -1720,7 +1660,6 @@ int mwl_fwcmd_set_rts_threshold(struct ieee80211_hw *hw, int threshold)
pcmd->threshold = ENDIAN_SWAP16(threshold);
if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_802_11_RTS_THSD)) {
-
MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
return -EIO;
@@ -1772,7 +1711,6 @@ int mwl_fwcmd_set_edca_params(struct ieee80211_hw *hw, u8 index,
WLDBG_DUMP_DATA(DBG_LEVEL_2, (void *)pcmd, sizeof(*pcmd));
if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_SET_EDCA_PARAMS)) {
-
MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
return -EIO;
@@ -1806,7 +1744,6 @@ int mwl_fwcmd_set_wmm_mode(struct ieee80211_hw *hw, bool enable)
pcmd->action = ENDIAN_SWAP16(enable ? WL_ENABLE : WL_DISABLE);
if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_SET_WMM_MODE)) {
-
MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
return -EIO;
@@ -1843,7 +1780,6 @@ int mwl_fwcmd_use_fixed_rate(struct ieee80211_hw *hw, int mcast, int mgmt)
pcmd->management_rate = mgmt;
if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_SET_FIXED_RATE)) {
-
MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
return -EIO;
@@ -1878,7 +1814,47 @@ int mwl_fwcmd_set_rate_adapt_mode(struct ieee80211_hw *hw, u16 mode)
pcmd->rate_adapt_mode = ENDIAN_SWAP16(mode);
if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_SET_RATE_ADAPT_MODE)) {
+ MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
+ WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
+ return -EIO;
+ }
+
+ MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
+ WLDBG_EXIT(DBG_LEVEL_2);
+
+ return 0;
+}
+
+int mwl_fwcmd_set_mac_addr_client(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif, u8 *mac_addr)
+{
+ struct mwl_priv *priv;
+ struct mwl_vif *mwl_vif;
+ struct hostcmd_cmd_set_mac_addr *pcmd;
+ unsigned long flags;
+
+ WLDBG_ENTER(DBG_LEVEL_2);
+
+ BUG_ON(!hw);
+ priv = hw->priv;
+ BUG_ON(!priv);
+
+ BUG_ON(!vif);
+ mwl_vif = MWL_VIF(vif);
+ BUG_ON(!mwl_vif);
+
+ pcmd = (struct hostcmd_cmd_set_mac_addr *)&priv->pcmd_buf[0];
+ MWL_SPIN_LOCK(&priv->locks.fwcmd_lock);
+
+ memset(pcmd, 0x00, sizeof(*pcmd));
+ pcmd->cmd_hdr.cmd = ENDIAN_SWAP16(HOSTCMD_CMD_SET_MAC_ADDR);
+ pcmd->cmd_hdr.len = ENDIAN_SWAP16(sizeof(*pcmd));
+ pcmd->cmd_hdr.macid = mwl_vif->macid;
+ pcmd->mac_type = WL_MAC_TYPE_SECONDARY_CLIENT;
+ memcpy(pcmd->mac_addr, mac_addr, ETH_ALEN);
+
+ if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_SET_MAC_ADDR)) {
MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
return -EIO;
@@ -1911,7 +1887,6 @@ int mwl_fwcmd_get_watchdog_bitmap(struct ieee80211_hw *hw, u8 *bitmap)
pcmd->cmd_hdr.len = ENDIAN_SWAP16(sizeof(*pcmd));
if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_GET_WATCHDOG_BITMAP)) {
-
MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
return -EIO;
@@ -1925,6 +1900,46 @@ int mwl_fwcmd_get_watchdog_bitmap(struct ieee80211_hw *hw, u8 *bitmap)
return 0;
}
+int mwl_fwcmd_remove_mac_addr(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif, u8 *mac_addr)
+{
+ struct mwl_priv *priv;
+ struct mwl_vif *mwl_vif;
+ struct hostcmd_cmd_set_mac_addr *pcmd;
+ unsigned long flags;
+
+ WLDBG_ENTER(DBG_LEVEL_2);
+
+ BUG_ON(!hw);
+ priv = hw->priv;
+ BUG_ON(!priv);
+
+ BUG_ON(!vif);
+ mwl_vif = MWL_VIF(vif);
+ BUG_ON(!mwl_vif);
+
+ pcmd = (struct hostcmd_cmd_set_mac_addr *)&priv->pcmd_buf[0];
+
+ MWL_SPIN_LOCK(&priv->locks.fwcmd_lock);
+
+ memset(pcmd, 0x00, sizeof(*pcmd));
+ pcmd->cmd_hdr.cmd = ENDIAN_SWAP16(HOSTCMD_CMD_DEL_MAC_ADDR);
+ pcmd->cmd_hdr.len = ENDIAN_SWAP16(sizeof(*pcmd));
+ pcmd->cmd_hdr.macid = mwl_vif->macid;
+ memcpy(pcmd->mac_addr, mac_addr, ETH_ALEN);
+
+ if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_DEL_MAC_ADDR)) {
+ MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
+ WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
+ return -EIO;
+ }
+
+ MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
+ WLDBG_EXIT(DBG_LEVEL_2);
+
+ return 0;
+}
+
int mwl_fwcmd_bss_start(struct ieee80211_hw *hw,
struct ieee80211_vif *vif, bool enable)
{
@@ -1959,20 +1974,15 @@ int mwl_fwcmd_bss_start(struct ieee80211_hw *hw,
pcmd->cmd_hdr.macid = mwl_vif->macid;
if (enable) {
-
pcmd->enable = ENDIAN_SWAP32(WL_ENABLE);
-
} else {
-
if (mwl_vif->macid == 0)
pcmd->enable = ENDIAN_SWAP32(WL_DISABLE);
else
pcmd->enable = ENDIAN_SWAP32(WL_DISABLE_VMAC);
-
}
if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_BSS_START)) {
-
MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
return -EIO;
@@ -2030,7 +2040,7 @@ err:
int mwl_fwcmd_set_new_stn_add(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
- struct ieee80211_sta *sta)
+ struct ieee80211_sta *sta)
{
struct mwl_priv *priv;
struct mwl_vif *mwl_vif;
@@ -2060,9 +2070,14 @@ int mwl_fwcmd_set_new_stn_add(struct ieee80211_hw *hw,
pcmd->cmd_hdr.macid = mwl_vif->macid;
pcmd->action = ENDIAN_SWAP16(HOSTCMD_ACT_STA_ACTION_ADD);
- pcmd->aid = ENDIAN_SWAP16(sta->aid);
+ if (mwl_vif->is_sta == true) {
+ pcmd->aid = 0;
+ pcmd->stn_id = 0;
+ } else {
+ pcmd->aid = ENDIAN_SWAP16(sta->aid);
+ pcmd->stn_id = ENDIAN_SWAP16(sta->aid);
+ }
memcpy(pcmd->mac_addr, sta->addr, ETH_ALEN);
- pcmd->stn_id = ENDIAN_SWAP16(sta->aid);
if (hw->conf.chandef.chan->band == IEEE80211_BAND_2GHZ)
rates = sta->supp_rates[IEEE80211_BAND_2GHZ];
@@ -2071,7 +2086,6 @@ int mwl_fwcmd_set_new_stn_add(struct ieee80211_hw *hw,
pcmd->peer_info.legacy_rate_bitmap = ENDIAN_SWAP32(rates);
if (sta->ht_cap.ht_supported) {
-
pcmd->peer_info.ht_rates[0] = sta->ht_cap.mcs.rx_mask[0];
pcmd->peer_info.ht_rates[1] = sta->ht_cap.mcs.rx_mask[1];
pcmd->peer_info.ht_rates[2] = sta->ht_cap.mcs.rx_mask[2];
@@ -2082,7 +2096,6 @@ int mwl_fwcmd_set_new_stn_add(struct ieee80211_hw *hw,
}
if (sta->vht_cap.vht_supported) {
-
pcmd->peer_info.vht_max_rx_mcs = ENDIAN_SWAP32(*((u32 *)&sta->vht_cap.vht_mcs.rx_mcs_map));
pcmd->peer_info.vht_cap = ENDIAN_SWAP32(sta->vht_cap.cap);
pcmd->peer_info.vht_rx_channel_width = sta->bandwidth;
@@ -2092,12 +2105,21 @@ int mwl_fwcmd_set_new_stn_add(struct ieee80211_hw *hw,
pcmd->qos_info = ((sta->uapsd_queues << 4) | (sta->max_sp << 1));
if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_SET_NEW_STN)) {
-
MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
return -EIO;
}
+ if (mwl_vif->is_sta == true) {
+ memcpy(pcmd->mac_addr, mwl_vif->sta_mac, ETH_ALEN);
+
+ if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_SET_NEW_STN)) {
+ MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
+ WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
+ return -EIO;
+ }
+ }
+
MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
WLDBG_EXIT(DBG_LEVEL_2);
@@ -2135,7 +2157,6 @@ int mwl_fwcmd_set_new_stn_add_self(struct ieee80211_hw *hw,
memcpy(pcmd->mac_addr, vif->addr, ETH_ALEN);
if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_SET_NEW_STN)) {
-
MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
return -EIO;
@@ -2178,12 +2199,21 @@ int mwl_fwcmd_set_new_stn_del(struct ieee80211_hw *hw,
memcpy(pcmd->mac_addr, addr, ETH_ALEN);
if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_SET_NEW_STN)) {
-
MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
return -EIO;
}
+ if (mwl_vif->is_sta == true) {
+ memcpy(pcmd->mac_addr, mwl_vif->sta_mac, ETH_ALEN);
+
+ if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_SET_NEW_STN)) {
+ MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
+ WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
+ return -EIO;
+ }
+ }
+
MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
WLDBG_EXIT(DBG_LEVEL_2);
@@ -2212,7 +2242,6 @@ int mwl_fwcmd_set_apmode(struct ieee80211_hw *hw, u8 apmode)
pcmd->apmode = apmode;
if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_SET_APMODE)) {
-
MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
return -EIO;
@@ -2256,12 +2285,24 @@ int mwl_fwcmd_update_encryption_enable(struct ieee80211_hw *hw,
pcmd->action_data[0] = encr_type;
if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_UPDATE_ENCRYPTION)) {
-
MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
return -EIO;
}
+ if (mwl_vif->is_sta == true) {
+ if (memcmp(mwl_vif->bssid, addr, ETH_ALEN) == 0)
+ memcpy(pcmd->mac_addr, mwl_vif->sta_mac, ETH_ALEN);
+ else
+ memcpy(pcmd->mac_addr, mwl_vif->bssid, ETH_ALEN);
+
+ if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_UPDATE_ENCRYPTION)) {
+ MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
+ WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
+ return -EIO;
+ }
+ }
+
MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
WLDBG_EXIT(DBG_LEVEL_2);
@@ -2270,7 +2311,7 @@ int mwl_fwcmd_update_encryption_enable(struct ieee80211_hw *hw,
int mwl_fwcmd_encryption_set_key(struct ieee80211_hw *hw,
struct ieee80211_vif *vif, u8 *addr,
- struct ieee80211_key_conf *key)
+ struct ieee80211_key_conf *key)
{
struct mwl_priv *priv;
struct mwl_vif *mwl_vif;
@@ -2302,7 +2343,6 @@ int mwl_fwcmd_encryption_set_key(struct ieee80211_hw *hw,
rc = mwl_fwcmd_encryption_set_cmd_info(pcmd, addr, key);
if (rc) {
-
MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
WLDBG_EXIT_INFO(DBG_LEVEL_2, "encryption not support");
return rc;
@@ -2316,12 +2356,9 @@ int mwl_fwcmd_encryption_set_key(struct ieee80211_hw *hw,
action = ENCR_ACTION_TYPE_SET_GROUP_KEY;
switch (key->cipher) {
-
case WLAN_CIPHER_SUITE_WEP40:
case WLAN_CIPHER_SUITE_WEP104:
-
if (!mwl_vif->wep_key_conf[idx].enabled) {
-
memcpy(mwl_vif->wep_key_conf[idx].key, key,
sizeof(*key) + key->keylen);
mwl_vif->wep_key_conf[idx].enabled = 1;
@@ -2330,19 +2367,13 @@ int mwl_fwcmd_encryption_set_key(struct ieee80211_hw *hw,
keymlen = key->keylen;
action = ENCR_ACTION_TYPE_SET_KEY;
break;
-
case WLAN_CIPHER_SUITE_TKIP:
-
keymlen = MAX_ENCR_KEY_LENGTH + 2 * MIC_KEY_LENGTH;
break;
-
case WLAN_CIPHER_SUITE_CCMP:
-
keymlen = key->keylen;
break;
-
default:
-
MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
WLDBG_EXIT_INFO(DBG_LEVEL_2, "encryption not support");
return -ENOTSUPP;
@@ -2352,12 +2383,24 @@ int mwl_fwcmd_encryption_set_key(struct ieee80211_hw *hw,
pcmd->action_type = ENDIAN_SWAP32(action);
if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_UPDATE_ENCRYPTION)) {
-
MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
return -EIO;
}
+ if (mwl_vif->is_sta == true) {
+ if (memcmp(mwl_vif->bssid, addr, ETH_ALEN) == 0)
+ memcpy(pcmd->key_param.mac_addr, mwl_vif->sta_mac, ETH_ALEN);
+ else
+ memcpy(pcmd->key_param.mac_addr, mwl_vif->bssid, ETH_ALEN);
+
+ if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_UPDATE_ENCRYPTION)) {
+ MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
+ WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
+ return -EIO;
+ }
+ }
+
MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
WLDBG_EXIT(DBG_LEVEL_2);
@@ -2366,7 +2409,7 @@ int mwl_fwcmd_encryption_set_key(struct ieee80211_hw *hw,
int mwl_fwcmd_encryption_remove_key(struct ieee80211_hw *hw,
struct ieee80211_vif *vif, u8 *addr,
- struct ieee80211_key_conf *key)
+ struct ieee80211_key_conf *key)
{
struct mwl_priv *priv;
struct mwl_vif *mwl_vif;
@@ -2395,7 +2438,6 @@ int mwl_fwcmd_encryption_remove_key(struct ieee80211_hw *hw,
rc = mwl_fwcmd_encryption_set_cmd_info(pcmd, addr, key);
if (rc) {
-
MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
WLDBG_EXIT_INFO(DBG_LEVEL_2, "encryption not support");
return rc;
@@ -2408,7 +2450,6 @@ int mwl_fwcmd_encryption_remove_key(struct ieee80211_hw *hw,
mwl_vif->wep_key_conf[key->keyidx].enabled = 0;
if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_UPDATE_ENCRYPTION)) {
-
MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
return -EIO;
@@ -2422,7 +2463,7 @@ int mwl_fwcmd_encryption_remove_key(struct ieee80211_hw *hw,
int mwl_fwcmd_check_ba(struct ieee80211_hw *hw,
struct mwl_ampdu_stream *stream,
- struct ieee80211_vif *vif)
+ struct ieee80211_vif *vif)
{
struct mwl_priv *priv;
struct mwl_vif *mwl_vif;
@@ -2464,14 +2505,12 @@ int mwl_fwcmd_check_ba(struct ieee80211_hw *hw,
WLDBG_DUMP_DATA(DBG_LEVEL_2, (void *)pcmd, sizeof(*pcmd));
if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_BASTREAM)) {
-
MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
return -EIO;
}
if (pcmd->cmd_hdr.result != 0) {
-
MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
WLDBG_EXIT_INFO(DBG_LEVEL_2, "result error");
return -EINVAL;
@@ -2485,7 +2524,7 @@ int mwl_fwcmd_check_ba(struct ieee80211_hw *hw,
int mwl_fwcmd_create_ba(struct ieee80211_hw *hw,
struct mwl_ampdu_stream *stream,
- u8 buf_size, struct ieee80211_vif *vif)
+ u8 buf_size, struct ieee80211_vif *vif)
{
struct mwl_priv *priv;
struct mwl_vif *mwl_vif;
@@ -2536,14 +2575,12 @@ int mwl_fwcmd_create_ba(struct ieee80211_hw *hw,
WLDBG_DUMP_DATA(DBG_LEVEL_2, (void *)pcmd, sizeof(*pcmd));
if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_BASTREAM)) {
-
MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
return -EIO;
}
if (pcmd->cmd_hdr.result != 0) {
-
MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
WLDBG_EXIT_INFO(DBG_LEVEL_2, "result error");
return -EINVAL;
@@ -2558,7 +2595,6 @@ int mwl_fwcmd_create_ba(struct ieee80211_hw *hw,
int mwl_fwcmd_destroy_ba(struct ieee80211_hw *hw,
u8 idx)
{
-
struct mwl_priv *priv;
struct hostcmd_cmd_bastream *pcmd;
unsigned long flags;
@@ -2585,7 +2621,6 @@ int mwl_fwcmd_destroy_ba(struct ieee80211_hw *hw,
pcmd->ba_info.destroy_params.fw_ba_context.context = ENDIAN_SWAP32(idx);
if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_BASTREAM)) {
-
MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
return -EIO;
@@ -2613,11 +2648,9 @@ struct mwl_ampdu_stream *mwl_fwcmd_add_stream(struct ieee80211_hw *hw,
BUG_ON(!sta);
for (i = 0; i < SYSADPT_TX_AMPDU_QUEUES; i++) {
-
stream = &priv->ampdu[i];
if (stream->state == AMPDU_NO_STREAM) {
-
stream->sta = sta;
stream->state = AMPDU_STREAM_NEW;
stream->tid = tid;
@@ -2664,7 +2697,6 @@ struct mwl_ampdu_stream *mwl_fwcmd_lookup_stream(struct ieee80211_hw *hw,
BUG_ON(!priv);
for (i = 0; i < SYSADPT_TX_AMPDU_QUEUES; i++) {
-
stream = &priv->ampdu[i];
if (stream->state == AMPDU_NO_STREAM)
@@ -2673,7 +2705,6 @@ struct mwl_ampdu_stream *mwl_fwcmd_lookup_stream(struct ieee80211_hw *hw,
if (!memcmp(stream->sta->addr, addr, ETH_ALEN) &&
stream->tid == tid)
return stream;
-
}
return NULL;
@@ -2718,7 +2749,6 @@ int mwl_fwcmd_set_dwds_stamode(struct ieee80211_hw *hw, bool enable)
pcmd->enable = ENDIAN_SWAP32(enable);
if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_DWDS_ENABLE)) {
-
MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
return -EIO;
@@ -2752,7 +2782,6 @@ int mwl_fwcmd_set_fw_flush_timer(struct ieee80211_hw *hw, u32 value)
pcmd->value = ENDIAN_SWAP32(value);
if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_FW_FLUSH_TIMER)) {
-
MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
return -EIO;
@@ -2786,7 +2815,6 @@ int mwl_fwcmd_set_cdd(struct ieee80211_hw *hw)
pcmd->enable = ENDIAN_SWAP32(priv->cdd);
if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_SET_CDD)) {
-
MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
return -EIO;
@@ -2812,7 +2840,6 @@ static bool mwl_fwcmd_chk_adapter(struct mwl_priv *priv)
regval = readl(priv->iobase1 + MACREG_REG_INT_CODE);
if (regval == 0xffffffff) {
-
WLDBG_ERROR(DBG_LEVEL_2, "adapter is not existed");
WLDBG_EXIT_INFO(DBG_LEVEL_2, "adapter is not existed");
@@ -2833,7 +2860,6 @@ static int mwl_fwcmd_exec_cmd(struct mwl_priv *priv, unsigned short cmd)
BUG_ON(!priv);
if (!mwl_fwcmd_chk_adapter(priv)) {
-
WLDBG_ERROR(DBG_LEVEL_2, "no adapter existed");
WLDBG_EXIT_INFO(DBG_LEVEL_2, "no adapter plugged in");
priv->in_send_cmd = false;
@@ -2841,21 +2867,15 @@ static int mwl_fwcmd_exec_cmd(struct mwl_priv *priv, unsigned short cmd)
}
if (!priv->in_send_cmd) {
-
priv->in_send_cmd = true;
-
mwl_fwcmd_send_cmd(priv);
-
if (mwl_fwcmd_wait_complete(priv, 0x8000 | cmd)) {
-
WLDBG_ERROR(DBG_LEVEL_2, "timeout");
WLDBG_EXIT_INFO(DBG_LEVEL_2, "timeout");
priv->in_send_cmd = false;
return -EIO;
}
-
} else {
-
WLDBG_WARNING(DBG_LEVEL_2, "previous command is still running");
busy = true;
}
@@ -2891,19 +2911,14 @@ static int mwl_fwcmd_wait_complete(struct mwl_priv *priv, unsigned short cmd)
BUG_ON(!priv);
do {
-
int_code = ENDIAN_SWAP16(priv->pcmd_buf[0]);
WL_MSEC_SLEEP(1);
-
} while ((int_code != cmd) && (--curr_iteration));
- if (curr_iteration == 0)
- {
+ if (curr_iteration == 0) {
WLDBG_ERROR(DBG_LEVEL_2, "cmd 0x%04x=%s timed out",
cmd, mwl_fwcmd_get_cmd_string(cmd));
-
WLDBG_EXIT_INFO(DBG_LEVEL_2, "timeout");
-
return -EIO;
}
@@ -2941,7 +2956,6 @@ static int mwl_fwcmd_802_11_radio_control(struct mwl_priv *priv, bool enable, bo
WLDBG_DUMP_DATA(DBG_LEVEL_2, (void *)pcmd, sizeof(*pcmd));
if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_802_11_RADIO_CONTROL)) {
-
MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
return -EIO;
@@ -2980,7 +2994,6 @@ static int mwl_fwcmd_get_tx_powers(struct mwl_priv *priv, u16 *powlist, u16 ch,
pcmd->sub_ch = ENDIAN_SWAP16(sub_ch);
if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_802_11_TX_POWER)) {
-
MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
return -EIO;
@@ -3023,7 +3036,6 @@ static int mwl_fwcmd_set_tx_powers(struct mwl_priv *priv, u16 txpow[], u8 action
pcmd->power_level_list[i] = ENDIAN_SWAP16(txpow[i]);
if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_802_11_TX_POWER)) {
-
MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
return -EIO;
@@ -3040,7 +3052,6 @@ static u8 mwl_fwcmd_get_80m_pri_chnl_offset(u8 channel)
u8 act_primary = ACT_PRIMARY_CHAN_0;
switch (channel) {
-
case 36:
act_primary = ACT_PRIMARY_CHAN_0;
break;
@@ -3053,7 +3064,6 @@ static u8 mwl_fwcmd_get_80m_pri_chnl_offset(u8 channel)
case 48:
act_primary = ACT_PRIMARY_CHAN_3;
break;
-
case 52:
act_primary = ACT_PRIMARY_CHAN_0;
break;
@@ -3066,7 +3076,6 @@ static u8 mwl_fwcmd_get_80m_pri_chnl_offset(u8 channel)
case 64:
act_primary = ACT_PRIMARY_CHAN_3;
break;
-
case 100:
act_primary = ACT_PRIMARY_CHAN_0;
break;
@@ -3079,7 +3088,6 @@ static u8 mwl_fwcmd_get_80m_pri_chnl_offset(u8 channel)
case 112:
act_primary = ACT_PRIMARY_CHAN_3;
break;
-
case 116:
act_primary = ACT_PRIMARY_CHAN_0;
break;
@@ -3092,7 +3100,6 @@ static u8 mwl_fwcmd_get_80m_pri_chnl_offset(u8 channel)
case 128:
act_primary = ACT_PRIMARY_CHAN_3;
break;
-
case 132:
act_primary = ACT_PRIMARY_CHAN_0;
break;
@@ -3105,7 +3112,6 @@ static u8 mwl_fwcmd_get_80m_pri_chnl_offset(u8 channel)
case 144:
act_primary = ACT_PRIMARY_CHAN_3;
break;
-
case 149:
act_primary = ACT_PRIMARY_CHAN_0;
break;
@@ -3158,7 +3164,6 @@ static void mwl_fwcmd_parse_beacon(struct mwl_priv *priv,
elem_parse_failed = false;
while (left >= 2) {
-
u8 id, elen;
id = *pos++;
@@ -3166,13 +3171,11 @@ static void mwl_fwcmd_parse_beacon(struct mwl_priv *priv,
left -= 2;
if (elen > left) {
-
elem_parse_failed = true;
break;
}
switch (id) {
-
case WLAN_EID_SUPP_RATES:
case WLAN_EID_EXT_SUPP_RATES:
{
@@ -3180,23 +3183,19 @@ static void mwl_fwcmd_parse_beacon(struct mwl_priv *priv,
u8 rate;
for (basic_idx = 0; basic_idx < SYSADPT_MAX_DATA_RATES_G; basic_idx++) {
-
if (beacon_info->bss_basic_rate_set[basic_idx] == 0)
break;
}
for (oprate_idx = 0; oprate_idx < SYSADPT_MAX_DATA_RATES_G; oprate_idx++) {
-
if (beacon_info->op_rate_set[oprate_idx] == 0)
break;
}
for (idx = 0; idx < elen; idx++) {
-
rate = pos[idx];
if ((rate & 0x80) != 0) {
-
if (basic_idx < SYSADPT_MAX_DATA_RATES_G)
beacon_info->bss_basic_rate_set[basic_idx++] = rate & 0x7f;
else {
@@ -3214,12 +3213,10 @@ static void mwl_fwcmd_parse_beacon(struct mwl_priv *priv,
}
}
break;
-
case WLAN_EID_RSN:
beacon_info->ie_rsn48_len = (elen + 2);
beacon_info->ie_rsn48_ptr = (pos - 2);
break;
-
case WLAN_EID_HT_CAPABILITY:
case WLAN_EID_HT_OPERATION:
case WLAN_EID_OVERLAP_BSS_SCAN_PARAM:
@@ -3235,7 +3232,6 @@ static void mwl_fwcmd_parse_beacon(struct mwl_priv *priv,
beacon_info->ie_ht_ptr += elen;
}
break;
-
case WLAN_EID_VHT_CAPABILITY:
case WLAN_EID_VHT_OPERATION:
case WLAN_EID_OPMODE_NOTIF:
@@ -3250,10 +3246,8 @@ static void mwl_fwcmd_parse_beacon(struct mwl_priv *priv,
beacon_info->ie_vht_ptr += elen;
}
break;
-
case WLAN_EID_VENDOR_SPECIFIC:
if ((pos[0] == 0x00) && (pos[1] == 0x50) && (pos[2] == 0xf2)) {
-
if (pos[3] == 0x01) {
beacon_info->ie_rsn_len = (elen + 2);
beacon_info->ie_rsn_ptr = (pos - 2);
@@ -3265,10 +3259,8 @@ static void mwl_fwcmd_parse_beacon(struct mwl_priv *priv,
}
}
break;
-
default:
break;
-
}
left -= elen;
@@ -3276,7 +3268,6 @@ static void mwl_fwcmd_parse_beacon(struct mwl_priv *priv,
}
if (elem_parse_failed == false) {
-
beacon_info->ie_ht_ptr = &beacon_info->ie_list_ht[0];
beacon_info->ie_vht_ptr = &beacon_info->ie_list_vht[0];
beacon_info->valid = true;
@@ -3338,7 +3329,6 @@ static int mwl_fwcmd_set_ies(struct mwl_priv *priv, struct mwl_vif *mwl_vif)
WLDBG_DUMP_DATA(DBG_LEVEL_2, (void *)pcmd, sizeof(*pcmd));
if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_SET_IES)) {
-
MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
return -EIO;
@@ -3425,7 +3415,6 @@ static int mwl_fwcmd_set_ap_beacon(struct mwl_priv *priv, struct mwl_vif *mwl_vi
WLDBG_DUMP_DATA(DBG_LEVEL_2, (void *)pcmd, sizeof(*pcmd));
if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_AP_BEACON)) {
-
MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
return -EIO;
@@ -3455,18 +3444,13 @@ static int mwl_fwcmd_encryption_set_cmd_info(struct hostcmd_cmd_set_key *cmd,
memcpy(cmd->key_param.mac_addr, addr, ETH_ALEN);
switch (key->cipher) {
-
case WLAN_CIPHER_SUITE_WEP40:
case WLAN_CIPHER_SUITE_WEP104:
-
cmd->key_param.key_type_id = ENDIAN_SWAP16(KEY_TYPE_ID_WEP);
if (key->keyidx == 0)
cmd->key_param.key_info = ENDIAN_SWAP32(ENCR_KEY_FLAG_WEP_TXKEY);
-
break;
-
case WLAN_CIPHER_SUITE_TKIP:
-
cmd->key_param.key_type_id = ENDIAN_SWAP16(KEY_TYPE_ID_TKIP);
cmd->key_param.key_info = (key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
? ENDIAN_SWAP32(ENCR_KEY_FLAG_PAIRWISE)
@@ -3474,17 +3458,13 @@ static int mwl_fwcmd_encryption_set_cmd_info(struct hostcmd_cmd_set_key *cmd,
cmd->key_param.key_info |= ENDIAN_SWAP32(ENCR_KEY_FLAG_MICKEY_VALID
| ENCR_KEY_FLAG_TSC_VALID);
break;
-
case WLAN_CIPHER_SUITE_CCMP:
-
cmd->key_param.key_type_id = ENDIAN_SWAP16(KEY_TYPE_ID_AES);
cmd->key_param.key_info = (key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
? ENDIAN_SWAP32(ENCR_KEY_FLAG_PAIRWISE)
: ENDIAN_SWAP32(ENCR_KEY_FLAG_TXGROUPKEY);
break;
-
default:
-
return -ENOTSUPP;
}
@@ -3498,12 +3478,9 @@ static char *mwl_fwcmd_get_cmd_string(unsigned short cmd)
int curr_cmd = 0;
static const struct {
-
u16 cmd;
char *cmd_string;
-
} cmds[] = {
-
{ HOSTCMD_CMD_GET_HW_SPEC, "GetHwSpecifications" },
{ HOSTCMD_CMD_SET_HW_SPEC, "SetHwSepcifications" },
{ HOSTCMD_CMD_802_11_GET_STAT, "80211GetStat" },
@@ -3512,14 +3489,18 @@ static char *mwl_fwcmd_get_cmd_string(unsigned short cmd)
{ HOSTCMD_CMD_802_11_RF_ANTENNA, "80211RfAntenna" },
{ HOSTCMD_CMD_BROADCAST_SSID_ENABLE, "broadcast_ssid_enable" },
{ HOSTCMD_CMD_SET_RF_CHANNEL, "SetRfChannel" },
- { HOSTCMD_CMD_802_11_RTS_THSD, "80211RtsThreshold" },
- { HOSTCMD_CMD_SET_EDCA_PARAMS, "SetEDCAParams" },
+ { HOSTCMD_CMD_SET_AID, "SetAid" },
+ { HOSTCMD_CMD_SET_INFRA_MODE, "SetInfraMode" },
+ { HOSTCMD_CMD_802_11_RTS_THSD, "80211RtsThreshold" },
+ { HOSTCMD_CMD_SET_EDCA_PARAMS, "SetEDCAParams" },
{ HOSTCMD_CMD_SET_WMM_MODE, "SetWMMMode" },
{ HOSTCMD_CMD_SET_FIXED_RATE, "SetFixedRate" },
{ HOSTCMD_CMD_SET_IES, "SetInformationElements" },
{ HOSTCMD_CMD_SET_RATE_ADAPT_MODE, "SetRateAdaptationMode" },
+ { HOSTCMD_CMD_SET_MAC_ADDR, "SetMacAddr" },
{ HOSTCMD_CMD_GET_WATCHDOG_BITMAP, "GetWatchdogBitMap" },
- { HOSTCMD_CMD_BSS_START, "BssStart" },
+ { HOSTCMD_CMD_DEL_MAC_ADDR. "DelMacAddr" },
+ { HOSTCMD_CMD_BSS_START, "BssStart" },
{ HOSTCMD_CMD_AP_BEACON, "SetApBeacon" },
{ HOSTCMD_CMD_SET_NEW_STN, "SetNewStation" },
{ HOSTCMD_CMD_SET_APMODE, "SetApMode" },
@@ -3535,11 +3516,8 @@ static char *mwl_fwcmd_get_cmd_string(unsigned short cmd)
max_entries = sizeof(cmds) / sizeof(cmds[0]);
for (curr_cmd = 0; curr_cmd < max_entries; curr_cmd++) {
-
if ((cmd & 0x7fff) == cmds[curr_cmd].cmd) {
-
WLDBG_EXIT(DBG_LEVEL_2);
-
return cmds[curr_cmd].cmd_string;
}
}
diff --git a/mwl_fwcmd.h b/mwl_fwcmd.h
index fed69ba..70749b6 100644
--- a/mwl_fwcmd.h
+++ b/mwl_fwcmd.h
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2006-2014 Marvell International Ltd.
+* Copyright (c) 2006-2015 Marvell International Ltd.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -44,20 +44,16 @@
*/
enum {
-
WL_ANTENNATYPE_RX = 1,
WL_ANTENNATYPE_TX = 2,
-
};
enum encr_type {
-
ENCR_TYPE_WEP = 0,
ENCR_TYPE_DISABLE = 1,
ENCR_TYPE_TKIP = 4,
ENCR_TYPE_AES = 6,
ENCR_TYPE_MIX = 7,
-
};
/* PUBLIC FUNCTION DECLARATION
@@ -97,6 +93,12 @@ int mwl_fwcmd_broadcast_ssid_enable(struct ieee80211_hw *hw,
int mwl_fwcmd_set_rf_channel(struct ieee80211_hw *hw,
struct ieee80211_conf *conf);
+int mwl_fwcmd_set_aid(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif, u8 *bssid, u16 aid);
+
+int mwl_fwcmd_set_infra_mode(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif);
+
int mwl_fwcmd_set_rts_threshold(struct ieee80211_hw *hw,
int threshold);
@@ -112,9 +114,15 @@ int mwl_fwcmd_use_fixed_rate(struct ieee80211_hw *hw,
int mwl_fwcmd_set_rate_adapt_mode(struct ieee80211_hw *hw,
u16 mode);
+int mwl_fwcmd_set_mac_addr_client(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif, u8 *mac_addr);
+
int mwl_fwcmd_get_watchdog_bitmap(struct ieee80211_hw *hw,
u8 *bitmap);
+int mwl_fwcmd_remove_mac_addr(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif, u8 *mac_addr);
+
int mwl_fwcmd_bss_start(struct ieee80211_hw *hw,
struct ieee80211_vif *vif, bool enable);
@@ -123,7 +131,7 @@ int mwl_fwcmd_set_beacon(struct ieee80211_hw *hw,
int mwl_fwcmd_set_new_stn_add(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
- struct ieee80211_sta *sta);
+ struct ieee80211_sta *sta);
int mwl_fwcmd_set_new_stn_add_self(struct ieee80211_hw *hw,
struct ieee80211_vif *vif);
@@ -138,19 +146,19 @@ int mwl_fwcmd_update_encryption_enable(struct ieee80211_hw *hw,
int mwl_fwcmd_encryption_set_key(struct ieee80211_hw *hw,
struct ieee80211_vif *vif, u8 *addr,
- struct ieee80211_key_conf *key);
+ struct ieee80211_key_conf *key);
int mwl_fwcmd_encryption_remove_key(struct ieee80211_hw *hw,
struct ieee80211_vif *vif, u8 *addr,
- struct ieee80211_key_conf *key);
+ struct ieee80211_key_conf *key);
int mwl_fwcmd_check_ba(struct ieee80211_hw *hw,
struct mwl_ampdu_stream *stream,
- struct ieee80211_vif *vif);
+ struct ieee80211_vif *vif);
int mwl_fwcmd_create_ba(struct ieee80211_hw *hw,
struct mwl_ampdu_stream *stream,
- u8 buf_size, struct ieee80211_vif *vif);
+ u8 buf_size, struct ieee80211_vif *vif);
int mwl_fwcmd_destroy_ba(struct ieee80211_hw *hw,
u8 idx);
diff --git a/mwl_fwdl.c b/mwl_fwdl.c
index 5f9ef91..0f1c916 100644
--- a/mwl_fwdl.c
+++ b/mwl_fwdl.c
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2006-2014 Marvell International Ltd.
+* Copyright (c) 2006-2015 Marvell International Ltd.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -16,7 +16,7 @@
/*
*
-* Description: This file implements frimware downloa related functions.
+* Description: This file implements firmware download related functions.
*
*/
@@ -89,7 +89,6 @@ int mwl_fwdl_download_firmware(struct ieee80211_hw *hw)
while (readl(priv->iobase1 + 0xc40) == 0);
while (size_fw_downloaded < fw->size) {
-
len = readl(priv->iobase1 + 0xc40);
if (!len)
@@ -112,25 +111,20 @@ int mwl_fwdl_download_firmware(struct ieee80211_hw *hw)
* can alternatively tweak this routines to fit your platform
*/
do {
-
int_code = readl(priv->iobase1 + 0xc1c);
if (int_code != 0)
break;
curr_iteration--;
-
} while (curr_iteration);
do {
-
int_code = readl(priv->iobase1 + 0xc1c);
if ((int_code & MACREG_H2ARIC_BIT_DOOR_BELL) != MACREG_H2ARIC_BIT_DOOR_BELL)
break;
curr_iteration--;
-
} while (curr_iteration);
if (curr_iteration == 0) {
-
/* This limited loop check allows you to exit gracefully without locking up
* your entire system just because fw download failed
*/
@@ -153,18 +147,15 @@ int mwl_fwdl_download_firmware(struct ieee80211_hw *hw)
mwl_fwdl_trig_pcicmd(priv);
curr_iteration = FW_MAX_NUM_CHECKS;
do {
-
curr_iteration--;
writel(HOSTCMD_SOFTAP_MODE, priv->iobase1 + MACREG_REG_GEN_PTR);
WL_MSEC_SLEEP(FW_CHECK_MSECS);
int_code = readl(priv->iobase1 + MACREG_REG_INT_CODE);
if (!(curr_iteration % 0xff))
WLDBG_PRINT("%x;", int_code);
-
} while ((curr_iteration) && (int_code != HOSTCMD_SOFTAP_FWRDY_SIGNATURE));
if (curr_iteration == 0) {
-
WLDBG_PRINT("Exhausted curr_iteration waiting for fw signature; firmware seems failed to operate");
goto err_download;
}
diff --git a/mwl_fwdl.h b/mwl_fwdl.h
index c9efe24..698a4d0 100644
--- a/mwl_fwdl.h
+++ b/mwl_fwdl.h
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2006-2014 Marvell International Ltd.
+* Copyright (c) 2006-2015 Marvell International Ltd.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
diff --git a/mwl_mac80211.c b/mwl_mac80211.c
index 5f14bdc..17a9438 100644
--- a/mwl_mac80211.c
+++ b/mwl_mac80211.c
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2006-2014 Marvell International Ltd.
+* Copyright (c) 2006-2015 Marvell International Ltd.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -39,7 +39,7 @@
static void mwl_mac80211_tx(struct ieee80211_hw *hw,
struct ieee80211_tx_control *control,
- struct sk_buff *skb);
+ struct sk_buff *skb);
static int mwl_mac80211_start(struct ieee80211_hw *hw);
static void mwl_mac80211_stop(struct ieee80211_hw *hw);
static int mwl_mac80211_add_interface(struct ieee80211_hw *hw,
@@ -50,42 +50,49 @@ static int mwl_mac80211_config(struct ieee80211_hw *hw,
u32 changed);
static void mwl_mac80211_bss_info_changed(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
- struct ieee80211_bss_conf *info,
- u32 changed);
+ struct ieee80211_bss_conf *info,
+ u32 changed);
static void mwl_mac80211_configure_filter(struct ieee80211_hw *hw,
unsigned int changed_flags,
- unsigned int *total_flags,
- u64 multicast);
+ unsigned int *total_flags,
+ u64 multicast);
static int mwl_mac80211_set_key(struct ieee80211_hw *hw,
enum set_key_cmd cmd_param,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta,
- struct ieee80211_key_conf *key);
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta,
+ struct ieee80211_key_conf *key);
static int mwl_mac80211_set_rts_threshold(struct ieee80211_hw *hw,
u32 value);
static int mwl_mac80211_sta_add(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
- struct ieee80211_sta *sta);
+ struct ieee80211_sta *sta);
static int mwl_mac80211_sta_remove(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
- struct ieee80211_sta *sta);
+ struct ieee80211_sta *sta);
static int mwl_mac80211_conf_tx(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
- u16 queue,
- const struct ieee80211_tx_queue_params *params);
+ u16 queue,
+ const struct ieee80211_tx_queue_params *params);
static int mwl_mac80211_get_stats(struct ieee80211_hw *hw,
struct ieee80211_low_level_stats *stats);
static int mwl_mac80211_get_survey(struct ieee80211_hw *hw,
int idx,
- struct survey_info *survey);
+ struct survey_info *survey);
static int mwl_mac80211_ampdu_action(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
- enum ieee80211_ampdu_mlme_action action,
- struct ieee80211_sta *sta,
- u16 tid, u16 *ssn, u8 buf_size);
-
+ enum ieee80211_ampdu_mlme_action action,
+ struct ieee80211_sta *sta,
+ u16 tid, u16 *ssn, u8 buf_size);
static void mwl_mac80211_remove_vif(struct mwl_priv *priv,
struct mwl_vif *vif);
+static void mwl_mac80211_bss_info_changed_sta(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_bss_conf *info,
+ u32 changed);
+static void mwl_mac80211_bss_info_changed_ap(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_bss_conf *info,
+ u32 changed);
/* PRIVATE VARIABLES
*/
@@ -174,7 +181,6 @@ static void mwl_mac80211_tx(struct ieee80211_hw *hw,
BUG_ON(!skb);
if (!priv->radio_on) {
-
WLDBG_EXIT_INFO(DBG_LEVEL_5,
"dropped TX frame since radio disabled");
dev_kfree_skb_any(skb);
@@ -232,17 +238,13 @@ static int mwl_mac80211_start(struct ieee80211_hw *hw)
rc = mwl_fwcmd_set_fw_flush_timer(hw, 0);
if (rc) {
-
mwl_fwcmd_int_disable(hw);
free_irq(priv->pdev->irq, hw);
priv->irq = -1;
tasklet_disable(&priv->tx_task);
tasklet_disable(&priv->rx_task);
-
} else {
-
ieee80211_wake_queues(hw);
-
}
WLDBG_EXIT(DBG_LEVEL_5);
@@ -297,12 +299,20 @@ static int mwl_mac80211_add_interface(struct ieee80211_hw *hw,
WLDBG_ENTER(DBG_LEVEL_5);
- macids_supported = priv->ap_macids_supported;
+ switch (vif->type) {
+ case NL80211_IFTYPE_AP:
+ macids_supported = priv->ap_macids_supported;
+ break;
+ case NL80211_IFTYPE_STATION:
+ macids_supported = priv->sta_macids_supported;
+ break;
+ default:
+ return -EINVAL;
+ }
macid = ffs(macids_supported & ~priv->macids_used);
if (!macid--) {
-
WLDBG_EXIT_INFO(DBG_LEVEL_5, "no macid can be allocated");
return -EBUSY;
}
@@ -314,13 +324,25 @@ static int mwl_mac80211_add_interface(struct ieee80211_hw *hw,
mwl_vif->vif = vif;
mwl_vif->macid = macid;
mwl_vif->seqno = 0;
- memcpy(mwl_vif->bssid, vif->addr, ETH_ALEN);
mwl_vif->is_hw_crypto_enabled = false;
+ mwl_vif->is_sta = false;
mwl_vif->beacon_info.valid = false;
mwl_vif->iv16 = 1;
mwl_vif->iv32 = 0;
+ mwl_vif->keyidx = 0;
+
+ if (vif->type == NL80211_IFTYPE_STATION) {
+ memcpy(mwl_vif->sta_mac, vif->addr, ETH_ALEN);
+ mwl_vif->is_sta = true;
+ mwl_fwcmd_bss_start(hw, vif, true);
+ mwl_fwcmd_set_infra_mode(hw, vif);
+ mwl_fwcmd_set_mac_addr_client(hw, vif, vif->addr);
+ }
- mwl_fwcmd_set_new_stn_add_self(hw, vif);
+ if (vif->type == NL80211_IFTYPE_AP) {
+ memcpy(mwl_vif->bssid, vif->addr, ETH_ALEN);
+ mwl_fwcmd_set_new_stn_add_self(hw, vif);
+ }
priv->macids_used |= 1 << mwl_vif->macid;
list_add_tail(&mwl_vif->list, &priv->vif_list);
@@ -338,7 +360,11 @@ static void mwl_mac80211_remove_interface(struct ieee80211_hw *hw,
WLDBG_ENTER(DBG_LEVEL_5);
- mwl_fwcmd_set_new_stn_del(hw, vif, vif->addr);
+ if (vif->type == NL80211_IFTYPE_STATION)
+ mwl_fwcmd_remove_mac_addr(hw, vif, vif->addr);
+
+ if (vif->type == NL80211_IFTYPE_AP)
+ mwl_fwcmd_set_new_stn_del(hw, vif, vif->addr);
mwl_mac80211_remove_vif(priv, mwl_vif);
@@ -364,17 +390,26 @@ static int mwl_mac80211_config(struct ieee80211_hw *hw,
goto out;
if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
-
- if (conf->chandef.chan->band == IEEE80211_BAND_2GHZ)
+ int rate = 0;
+
+ if (conf->chandef.chan->band == IEEE80211_BAND_2GHZ) {
mwl_fwcmd_set_apmode(hw, AP_MODE_2_4GHZ_11AC_MIXED);
- else if (conf->chandef.chan->band == IEEE80211_BAND_5GHZ)
+ rate = mwl_rates_24[0].hw_value;
+ } else if (conf->chandef.chan->band == IEEE80211_BAND_5GHZ) {
mwl_fwcmd_set_apmode(hw, AP_MODE_11AC);
+ rate = mwl_rates_50[0].hw_value;
+ }
rc = mwl_fwcmd_set_rf_channel(hw, conf);
if (rc)
goto out;
+ rc = mwl_fwcmd_use_fixed_rate(hw, rate, rate);
+
+ if (rc)
+ goto out;
+
rc = mwl_fwcmd_max_tx_power(hw, conf, 0);
if (rc)
@@ -397,71 +432,26 @@ out:
static void mwl_mac80211_bss_info_changed(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
- struct ieee80211_bss_conf *info,
- u32 changed)
+ struct ieee80211_bss_conf *info,
+ u32 changed)
{
WLDBG_ENTER(DBG_LEVEL_5);
- WLDBG_INFO(DBG_LEVEL_5, "change: 0x%x", changed);
-
- if (changed & BSS_CHANGED_ERP_PREAMBLE) {
-
- mwl_fwcmd_set_radio_preamble(hw,
- vif->bss_conf.use_short_preamble);
- }
-
- if (changed & BSS_CHANGED_BASIC_RATES) {
-
- int idx;
- int rate;
-
- /*
- * Use lowest supported basic rate for multicasts
- * and management frames (such as probe responses --
- * beacons will always go out at 1 Mb/s).
- */
- idx = ffs(vif->bss_conf.basic_rates);
- if (idx)
- idx--;
-
- if (hw->conf.chandef.chan->band == IEEE80211_BAND_2GHZ)
- rate = mwl_rates_24[idx].hw_value;
- else
- rate = mwl_rates_50[idx].hw_value;
-
- mwl_fwcmd_use_fixed_rate(hw, rate, rate);
- }
-
- if (changed & (BSS_CHANGED_BEACON_INT | BSS_CHANGED_BEACON)) {
-
- struct sk_buff *skb;
+ WLDBG_INFO(DBG_LEVEL_5, "interface: %d, change: 0x%x", vif->type, changed);
- skb = ieee80211_beacon_get(hw, vif);
+ if (vif->type == NL80211_IFTYPE_STATION)
+ mwl_mac80211_bss_info_changed_sta(hw, vif, info, changed);
- if (skb != NULL) {
-
- mwl_fwcmd_set_beacon(hw, vif, skb->data, skb->len);
- dev_kfree_skb_any(skb);
- }
-
- if ((info->ssid[0] != '\0') && (info->ssid_len != 0))
- mwl_fwcmd_broadcast_ssid_enable(hw, vif, true);
- else
- mwl_fwcmd_broadcast_ssid_enable(hw, vif, false);
- }
-
- if (changed & BSS_CHANGED_BEACON_ENABLED) {
-
- mwl_fwcmd_bss_start(hw, vif, info->enable_beacon);
- }
+ if (vif->type == NL80211_IFTYPE_AP)
+ mwl_mac80211_bss_info_changed_ap(hw, vif, info, changed);
WLDBG_EXIT(DBG_LEVEL_5);
}
static void mwl_mac80211_configure_filter(struct ieee80211_hw *hw,
unsigned int changed_flags,
- unsigned int *total_flags,
- u64 multicast)
+ unsigned int *total_flags,
+ u64 multicast)
{
WLDBG_ENTER(DBG_LEVEL_5);
@@ -476,9 +466,9 @@ static void mwl_mac80211_configure_filter(struct ieee80211_hw *hw,
static int mwl_mac80211_set_key(struct ieee80211_hw *hw,
enum set_key_cmd cmd_param,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta,
- struct ieee80211_key_conf *key)
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta,
+ struct ieee80211_key_conf *key)
{
int rc = 0;
u8 encr_type;
@@ -491,19 +481,15 @@ static int mwl_mac80211_set_key(struct ieee80211_hw *hw,
BUG_ON(!mwl_vif);
BUG_ON(!sta_info);
- if (vif->type == NL80211_IFTYPE_STATION) {
-
- WLDBG_EXIT_INFO(DBG_LEVEL_5, "station mode is not supported");
- return -EOPNOTSUPP;
- }
-
- if (sta == NULL)
+ if (sta == NULL) {
addr = vif->addr;
- else
+ } else {
addr = sta->addr;
+ if (mwl_vif->is_sta == true)
+ memcpy(mwl_vif->bssid, addr, ETH_ALEN);
+ }
if (cmd_param == SET_KEY) {
-
rc = mwl_fwcmd_encryption_set_key(hw, vif, addr, key);
if (rc)
@@ -511,24 +497,17 @@ static int mwl_mac80211_set_key(struct ieee80211_hw *hw,
if ((key->cipher == WLAN_CIPHER_SUITE_WEP40)
|| (key->cipher == WLAN_CIPHER_SUITE_WEP104)) {
-
encr_type = ENCR_TYPE_WEP;
-
} else if (key->cipher == WLAN_CIPHER_SUITE_CCMP) {
-
encr_type = ENCR_TYPE_AES;
-
- if ((key->flags & IEEE80211_KEY_FLAG_PAIRWISE) == 0)
- mwl_vif->keyidx = key->keyidx;
-
+ if ((key->flags & IEEE80211_KEY_FLAG_PAIRWISE) == 0) {
+ if (mwl_vif->is_sta == false)
+ mwl_vif->keyidx = key->keyidx;
+ }
} else if (key->cipher == WLAN_CIPHER_SUITE_TKIP) {
-
encr_type = ENCR_TYPE_TKIP;
-
} else {
-
encr_type = ENCR_TYPE_DISABLE;
-
}
rc = mwl_fwcmd_update_encryption_enable(hw, vif, addr,
@@ -538,14 +517,11 @@ static int mwl_mac80211_set_key(struct ieee80211_hw *hw,
goto out;
mwl_vif->is_hw_crypto_enabled = true;
-
} else {
-
rc = mwl_fwcmd_encryption_remove_key(hw, vif, addr, key);
if (rc)
goto out;
-
}
out:
@@ -571,7 +547,7 @@ static int mwl_mac80211_set_rts_threshold(struct ieee80211_hw *hw,
static int mwl_mac80211_sta_add(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
- struct ieee80211_sta *sta)
+ struct ieee80211_sta *sta)
{
struct mwl_vif *mwl_vif = MWL_VIF(vif);
struct mwl_sta *sta_info = MWL_STA(sta);
@@ -590,10 +566,12 @@ static int mwl_mac80211_sta_add(struct ieee80211_hw *hw,
if (sta->ht_cap.ht_supported)
sta_info->is_ampdu_allowed = true;
+ if (mwl_vif->is_sta == true)
+ mwl_fwcmd_set_new_stn_del(hw, vif, sta->addr);
+
rc = mwl_fwcmd_set_new_stn_add(hw, vif, sta);
for (i = 0; i < NUM_WEP_KEYS; i++) {
-
key = IEEE80211_KEY_CONF(mwl_vif->wep_key_conf[i].key);
if (mwl_vif->wep_key_conf[i].enabled)
@@ -607,7 +585,7 @@ static int mwl_mac80211_sta_add(struct ieee80211_hw *hw,
static int mwl_mac80211_sta_remove(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
- struct ieee80211_sta *sta)
+ struct ieee80211_sta *sta)
{
int rc;
@@ -622,8 +600,8 @@ static int mwl_mac80211_sta_remove(struct ieee80211_hw *hw,
static int mwl_mac80211_conf_tx(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
- u16 queue,
- const struct ieee80211_tx_queue_params *params)
+ u16 queue,
+ const struct ieee80211_tx_queue_params *params)
{
struct mwl_priv *priv = hw->priv;
int rc = 0;
@@ -635,13 +613,11 @@ static int mwl_mac80211_conf_tx(struct ieee80211_hw *hw,
memcpy(&priv->wmm_params[queue], params, sizeof(*params));
if (!priv->wmm_enabled) {
-
rc = mwl_fwcmd_set_wmm_mode(hw, true);
priv->wmm_enabled = true;
}
if (!rc) {
-
int q = SYSADPT_TX_WMM_QUEUES - 1 - queue;
rc = mwl_fwcmd_set_edca_params(hw, q,
@@ -691,9 +667,9 @@ static int mwl_mac80211_get_survey(struct ieee80211_hw *hw,
static int mwl_mac80211_ampdu_action(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
- enum ieee80211_ampdu_mlme_action action,
- struct ieee80211_sta *sta,
- u16 tid, u16 *ssn, u8 buf_size)
+ enum ieee80211_ampdu_mlme_action action,
+ struct ieee80211_sta *sta,
+ u16 tid, u16 *ssn, u8 buf_size)
{
int i, rc = 0;
struct mwl_priv *priv = hw->priv;
@@ -704,7 +680,6 @@ static int mwl_mac80211_ampdu_action(struct ieee80211_hw *hw,
WLDBG_ENTER(DBG_LEVEL_5);
if (!(hw->flags & IEEE80211_HW_AMPDU_AGGREGATION)) {
-
WLDBG_EXIT_INFO(DBG_LEVEL_5, "no HW AMPDU");
return -ENOTSUPP;
}
@@ -714,11 +689,9 @@ static int mwl_mac80211_ampdu_action(struct ieee80211_hw *hw,
stream = mwl_fwcmd_lookup_stream(hw, addr, tid);
switch (action) {
-
case IEEE80211_AMPDU_RX_START:
case IEEE80211_AMPDU_RX_STOP:
break;
-
case IEEE80211_AMPDU_TX_START:
/* By the time we get here the hw queues may contain outgoing
* packets for this RA/TID that are not part of this BA
@@ -732,7 +705,6 @@ static int mwl_mac80211_ampdu_action(struct ieee80211_hw *hw,
*ssn = 0;
if (stream == NULL) {
-
/* This means that somebody outside this driver called
* ieee80211_start_tx_ba_session. This is unexpected
* because we do our own rate control. Just warn and
@@ -742,7 +714,6 @@ static int mwl_mac80211_ampdu_action(struct ieee80211_hw *hw,
}
if (stream == NULL) {
-
WLDBG_EXIT_INFO(DBG_LEVEL_5, "no stream found");
rc = -EBUSY;
break;
@@ -755,11 +726,9 @@ static int mwl_mac80211_ampdu_action(struct ieee80211_hw *hw,
SPIN_UNLOCK(&priv->locks.stream_lock);
for (i = 0; i < MAX_AMPDU_ATTEMPTS; i++) {
-
/* Check if link is still valid
*/
if (!sta_info->is_ampdu_allowed) {
-
SPIN_LOCK(&priv->locks.stream_lock);
mwl_fwcmd_remove_stream(hw, stream);
SPIN_UNLOCK(&priv->locks.stream_lock);
@@ -778,7 +747,6 @@ static int mwl_mac80211_ampdu_action(struct ieee80211_hw *hw,
SPIN_LOCK(&priv->locks.stream_lock);
if (rc) {
-
mwl_fwcmd_remove_stream(hw, stream);
WLDBG_EXIT_INFO(DBG_LEVEL_5, "error code: %d", rc);
rc = -EBUSY;
@@ -787,15 +755,11 @@ static int mwl_mac80211_ampdu_action(struct ieee80211_hw *hw,
ieee80211_start_tx_ba_cb_irqsafe(vif, addr, tid);
break;
-
case IEEE80211_AMPDU_TX_STOP_CONT:
case IEEE80211_AMPDU_TX_STOP_FLUSH:
case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
-
if (stream) {
-
if (stream->state == AMPDU_STREAM_ACTIVE) {
-
idx = stream->idx;
SPIN_UNLOCK(&priv->locks.stream_lock);
mwl_fwcmd_destroy_ba(hw, idx);
@@ -807,9 +771,7 @@ static int mwl_mac80211_ampdu_action(struct ieee80211_hw *hw,
ieee80211_stop_tx_ba_cb_irqsafe(vif, addr, tid);
break;
-
case IEEE80211_AMPDU_TX_OPERATIONAL:
-
BUG_ON(stream == NULL);
BUG_ON(stream->state != AMPDU_STREAM_IN_PROGRESS);
SPIN_UNLOCK(&priv->locks.stream_lock);
@@ -819,7 +781,6 @@ static int mwl_mac80211_ampdu_action(struct ieee80211_hw *hw,
if (!rc)
stream->state = AMPDU_STREAM_ACTIVE;
else {
-
idx = stream->idx;
SPIN_UNLOCK(&priv->locks.stream_lock);
mwl_fwcmd_destroy_ba(hw, idx);
@@ -827,10 +788,8 @@ static int mwl_mac80211_ampdu_action(struct ieee80211_hw *hw,
mwl_fwcmd_remove_stream(hw, stream);
}
break;
-
default:
rc = -ENOTSUPP;
-
}
SPIN_UNLOCK(&priv->locks.stream_lock);
@@ -848,3 +807,72 @@ static void mwl_mac80211_remove_vif(struct mwl_priv *priv, struct mwl_vif *vif)
priv->macids_used &= ~(1 << vif->macid);
list_del(&vif->list);
}
+
+static void mwl_mac80211_bss_info_changed_sta(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_bss_conf *info,
+ u32 changed)
+{
+ if (changed & BSS_CHANGED_ERP_PREAMBLE) {
+ mwl_fwcmd_set_radio_preamble(hw,
+ vif->bss_conf.use_short_preamble);
+ }
+
+ if ((changed & BSS_CHANGED_ASSOC) && vif->bss_conf.assoc) {
+
+ mwl_fwcmd_set_aid(hw, vif, (u8 *) vif->bss_conf.bssid,
+ vif->bss_conf.aid);
+ }
+}
+
+static void mwl_mac80211_bss_info_changed_ap(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_bss_conf *info,
+ u32 changed)
+{
+ if (changed & BSS_CHANGED_ERP_PREAMBLE) {
+ mwl_fwcmd_set_radio_preamble(hw,
+ vif->bss_conf.use_short_preamble);
+ }
+
+ if (changed & BSS_CHANGED_BASIC_RATES) {
+ int idx;
+ int rate;
+
+ /*
+ * Use lowest supported basic rate for multicasts
+ * and management frames (such as probe responses --
+ * beacons will always go out at 1 Mb/s).
+ */
+ idx = ffs(vif->bss_conf.basic_rates);
+ if (idx)
+ idx--;
+
+ if (hw->conf.chandef.chan->band == IEEE80211_BAND_2GHZ)
+ rate = mwl_rates_24[idx].hw_value;
+ else
+ rate = mwl_rates_50[idx].hw_value;
+
+ mwl_fwcmd_use_fixed_rate(hw, rate, rate);
+ }
+
+ if (changed & (BSS_CHANGED_BEACON_INT | BSS_CHANGED_BEACON)) {
+ struct sk_buff *skb;
+
+ skb = ieee80211_beacon_get(hw, vif);
+
+ if (skb != NULL) {
+
+ mwl_fwcmd_set_beacon(hw, vif, skb->data, skb->len);
+ dev_kfree_skb_any(skb);
+ }
+
+ if ((info->ssid[0] != '\0') && (info->ssid_len != 0))
+ mwl_fwcmd_broadcast_ssid_enable(hw, vif, true);
+ else
+ mwl_fwcmd_broadcast_ssid_enable(hw, vif, false);
+ }
+
+ if (changed & BSS_CHANGED_BEACON_ENABLED)
+ mwl_fwcmd_bss_start(hw, vif, info->enable_beacon);
+}
diff --git a/mwl_mac80211.h b/mwl_mac80211.h
index 1432e02..1d4b57c 100644
--- a/mwl_mac80211.h
+++ b/mwl_mac80211.h
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2006-2014 Marvell International Ltd.
+* Copyright (c) 2006-2015 Marvell International Ltd.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
diff --git a/mwl_main.c b/mwl_main.c
index c0b70df..21a5a28 100644
--- a/mwl_main.c
+++ b/mwl_main.c
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2006-2014 Marvell International Ltd.
+* Copyright (c) 2006-2015 Marvell International Ltd.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -38,13 +38,14 @@
#define MWL_DESC "Marvell 802.11ac Wireless Network Driver"
#define MWL_DEV_NAME "Marvell 88W8864 802.11ac Adapter"
#define MWL_DRV_NAME KBUILD_MODNAME
-#define MWL_DRV_VERSION "10.2.6.1.p4"
+#define MWL_DRV_VERSION "10.2.8.5.p0"
#define FILE_PATH_LEN 64
#define CMD_BUF_SIZE 0x4000
#define INVALID_WATCHDOG 0xAA
+
/* PRIVATE FUNCTION DECLARATION
*/
@@ -53,10 +54,12 @@ static void mwl_remove(struct pci_dev *pdev);
static int mwl_alloc_pci_resource(struct mwl_priv *priv);
static void mwl_free_pci_resource(struct mwl_priv *priv);
static int mwl_init_firmware(struct mwl_priv *priv, char *fw_image);
-static int mwl_load_tx_pwr_tbl(struct mwl_priv *priv, char *pwr_tbl);
-static void mwl_set_ht_caps(struct ieee80211_hw *hw,
+static void mwl_reg_notifier(struct wiphy *wiphy,
+ struct regulatory_request *request);
+static void mwl_process_of_dts(struct mwl_priv *priv);
+static void mwl_set_ht_caps(struct mwl_priv *priv,
struct ieee80211_supported_band *band);
-static void mwl_set_vht_caps(struct ieee80211_hw *hw,
+static void mwl_set_vht_caps(struct mwl_priv *priv,
struct ieee80211_supported_band *band);
static void mwl_set_caps(struct mwl_priv *priv);
static int mwl_wl_init(struct mwl_priv *priv);
@@ -64,34 +67,25 @@ static void mwl_wl_deinit(struct mwl_priv *priv);
static void mwl_watchdog_ba_events(struct work_struct *work);
static irqreturn_t mwl_interrupt(int irq, void *dev_id);
-static int atoi(const char *num_str);
-static long atohex(const char *number);
-static long atohex2(const char *number);
/* PRIVATE VARIABLES
*/
-static char fw_image_path[FILE_PATH_LEN] = "88W8864.bin";
-static char pwr_tbl_path[FILE_PATH_LEN] = "PWR_TABLE.ini";
+static char fw_image_path[FILE_PATH_LEN] = "mwlwifi/88W8864.bin";
static struct pci_device_id mwl_pci_id_tbl[SYSADPT_MAX_CARDS_SUPPORT + 1] = {
-
{ 0x11ab, 0x2a55, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (unsigned long)MWL_DEV_NAME },
{ 0, 0, 0, 0, 0, 0, 0 }
-
};
static struct pci_driver mwl_pci_driver = {
-
.name = MWL_DRV_NAME,
.id_table = mwl_pci_id_tbl,
.probe = mwl_probe,
.remove = mwl_remove
-
};
static const struct ieee80211_channel mwl_channels_24[] = {
-
{ .band = IEEE80211_BAND_2GHZ, .center_freq = 2412, .hw_value = 1, },
{ .band = IEEE80211_BAND_2GHZ, .center_freq = 2417, .hw_value = 2, },
{ .band = IEEE80211_BAND_2GHZ, .center_freq = 2422, .hw_value = 3, },
@@ -106,11 +100,9 @@ static const struct ieee80211_channel mwl_channels_24[] = {
{ .band = IEEE80211_BAND_2GHZ, .center_freq = 2467, .hw_value = 12, },
{ .band = IEEE80211_BAND_2GHZ, .center_freq = 2472, .hw_value = 13, },
{ .band = IEEE80211_BAND_2GHZ, .center_freq = 2484, .hw_value = 14, },
-
};
static const struct ieee80211_rate mwl_rates_24[] = {
-
{ .bitrate = 10, .hw_value = 2, },
{ .bitrate = 20, .hw_value = 4, },
{ .bitrate = 55, .hw_value = 11, },
@@ -124,11 +116,9 @@ static const struct ieee80211_rate mwl_rates_24[] = {
{ .bitrate = 360, .hw_value = 72, },
{ .bitrate = 480, .hw_value = 96, },
{ .bitrate = 540, .hw_value = 108, },
-
};
static const struct ieee80211_channel mwl_channels_50[] = {
-
{ .band = IEEE80211_BAND_5GHZ, .center_freq = 5180, .hw_value = 36, },
{ .band = IEEE80211_BAND_5GHZ, .center_freq = 5200, .hw_value = 40, },
{ .band = IEEE80211_BAND_5GHZ, .center_freq = 5220, .hw_value = 44, },
@@ -153,11 +143,9 @@ static const struct ieee80211_channel mwl_channels_50[] = {
{ .band = IEEE80211_BAND_5GHZ, .center_freq = 5765, .hw_value = 153, },
{ .band = IEEE80211_BAND_5GHZ, .center_freq = 5785, .hw_value = 157, },
{ .band = IEEE80211_BAND_5GHZ, .center_freq = 5805, .hw_value = 161, },
-
};
static const struct ieee80211_rate mwl_rates_50[] = {
-
{ .bitrate = 60, .hw_value = 12, },
{ .bitrate = 90, .hw_value = 18, },
{ .bitrate = 120, .hw_value = 24, },
@@ -166,48 +154,27 @@ static const struct ieee80211_rate mwl_rates_50[] = {
{ .bitrate = 360, .hw_value = 72, },
{ .bitrate = 480, .hw_value = 96, },
{ .bitrate = 540, .hw_value = 108, },
-
};
static const struct ieee80211_iface_limit ap_if_limits[] = {
-
- { .max = 8, .types = BIT(NL80211_IFTYPE_AP) },
+ { .max = SYSADPT_NUM_OF_AP, .types = BIT(NL80211_IFTYPE_AP) },
{ .max = 1, .types = BIT(NL80211_IFTYPE_STATION) },
-
};
static const struct ieee80211_iface_combination ap_if_comb = {
-
.limits = ap_if_limits,
.n_limits = ARRAY_SIZE(ap_if_limits),
- .max_interfaces = 8,
+ .max_interfaces = SYSADPT_NUM_OF_AP,
.num_different_channels = 1,
-
};
-/* PUBLIC FUNCTION DEFINITION
-*/
-
-module_param_string(fw_name, fw_image_path, FILE_PATH_LEN, 0);
-MODULE_PARM_DESC(fw_name, "Specify where to load the F/W image");
-module_param_string(pwr_tbl, pwr_tbl_path, FILE_PATH_LEN, 0);
-MODULE_PARM_DESC(pwr_tbl, "Specify where to load TX power table");
-
-module_pci_driver(mwl_pci_driver);
-
-MODULE_DESCRIPTION(MWL_DESC);
-MODULE_VERSION(MWL_DRV_VERSION);
-MODULE_AUTHOR("Marvell Semiconductor, Inc.");
-MODULE_LICENSE("Dual BSD/GPL");
-MODULE_SUPPORTED_DEVICE(MWL_DEV_NAME);
-MODULE_DEVICE_TABLE(pci, mwl_pci_id_tbl);
/* PRIVATE FUNCTION DEFINITION
*/
static int mwl_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
- static int printed_version;
+ static bool printed_version = false;
struct ieee80211_hw *hw;
struct mwl_priv *priv;
int rc = 0;
@@ -215,14 +182,12 @@ static int mwl_probe(struct pci_dev *pdev, const struct pci_device_id *id)
WLDBG_ENTER(DBG_LEVEL_0);
if (!printed_version) {
-
WLDBG_PRINT("<<%s version %s>>", MWL_DESC, MWL_DRV_VERSION);
- printed_version = 1;
+ printed_version = true;
}
rc = pci_enable_device(pdev);
if (rc) {
-
WLDBG_ERROR(DBG_LEVEL_0, "%s: cannot enable new PCI device",
MWL_DRV_NAME);
WLDBG_EXIT_INFO(DBG_LEVEL_0, "init error");
@@ -231,7 +196,6 @@ static int mwl_probe(struct pci_dev *pdev, const struct pci_device_id *id)
rc = pci_set_dma_mask(pdev, 0xffffffff);
if (rc) {
-
WLDBG_ERROR(DBG_LEVEL_0, "%s: 32-bit PCI DMA not supported",
MWL_DRV_NAME);
goto err_pci_disable_device;
@@ -241,13 +205,16 @@ static int mwl_probe(struct pci_dev *pdev, const struct pci_device_id *id)
hw = ieee80211_alloc_hw(sizeof(*priv), mwl_mac80211_get_ops());
if (hw == NULL) {
-
WLDBG_ERROR(DBG_LEVEL_0, "%s: ieee80211 alloc failed",
MWL_DRV_NAME);
rc = -ENOMEM;
goto err_pci_disable_device;
}
+ /* hook regulatory domain change notification
+ */
+ hw->wiphy->reg_notifier = mwl_reg_notifier;
+
/* set interrupt service routine to mac80211 module
*/
mwl_mac80211_set_isr(mwl_interrupt);
@@ -265,7 +232,6 @@ static int mwl_probe(struct pci_dev *pdev, const struct pci_device_id *id)
rc = mwl_init_firmware(priv, fw_image_path);
if (rc) {
-
WLDBG_ERROR(DBG_LEVEL_0, "%s: fail to initialize firmware",
MWL_DRV_NAME);
goto err_init_firmware;
@@ -275,16 +241,10 @@ static int mwl_probe(struct pci_dev *pdev, const struct pci_device_id *id)
*/
release_firmware(priv->fw_ucode);
- rc = mwl_load_tx_pwr_tbl(priv, pwr_tbl_path);
- if (rc) {
-
- WLDBG_PRINT("%s: fail to load tx power table",
- MWL_DRV_NAME);
- }
+ mwl_process_of_dts(priv);
rc = mwl_wl_init(priv);
if (rc) {
-
WLDBG_ERROR(DBG_LEVEL_0, "%s: fail to initialize wireless lan",
MWL_DRV_NAME);
goto err_wl_init;
@@ -321,7 +281,6 @@ static void mwl_remove(struct pci_dev *pdev)
WLDBG_ENTER(DBG_LEVEL_0);
if (hw == NULL) {
-
WLDBG_EXIT_INFO(DBG_LEVEL_0, "ieee80211 hw is null");
return;
}
@@ -390,8 +349,7 @@ static int mwl_alloc_pci_resource(struct mwl_priv *priv)
phys_addr2[1] = 0;
priv->iobase1 = phys_addr2[0];
- if (!priv->iobase1)
- {
+ if (!priv->iobase1) {
WLDBG_ERROR(DBG_LEVEL_0, "%s: cannot remap PCI memory region 1",
MWL_DRV_NAME);
goto err_release_mem_region_bar1;
@@ -400,10 +358,9 @@ static int mwl_alloc_pci_resource(struct mwl_priv *priv)
WLDBG_PRINT("priv->iobase1 = %x", (unsigned int)priv->iobase1);
priv->pcmd_buf = (unsigned short *)
- pci_alloc_consistent(priv->pdev, CMD_BUF_SIZE, &priv->pphys_cmd_buf);
+ dma_alloc_coherent(&priv->pdev->dev, CMD_BUF_SIZE, &priv->pphys_cmd_buf, GFP_KERNEL);
if (priv->pcmd_buf == NULL) {
-
WLDBG_ERROR(DBG_LEVEL_0, "%s: cannot alloc memory for command buffer",
MWL_DRV_NAME);
goto err_iounmap_iobase1;
@@ -456,7 +413,7 @@ static void mwl_free_pci_resource(struct mwl_priv *priv)
iounmap(priv->iobase1);
release_mem_region(pci_resource_start(pdev, priv->next_bar_num), pci_resource_len(pdev, priv->next_bar_num));
release_mem_region(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0));
- pci_free_consistent(priv->pdev, CMD_BUF_SIZE, priv->pcmd_buf, priv->pphys_cmd_buf);
+ dma_free_coherent(&priv->pdev->dev, CMD_BUF_SIZE, priv->pcmd_buf, priv->pphys_cmd_buf);
WLDBG_EXIT(DBG_LEVEL_0);
}
@@ -474,7 +431,6 @@ static int mwl_init_firmware(struct mwl_priv *priv, char *fw_name)
rc = request_firmware(&priv->fw_ucode, fw_name, &priv->pdev->dev);
if (rc) {
-
WLDBG_ERROR(DBG_LEVEL_0, "%s: cannot load firmware image <%s>",
MWL_DRV_NAME, fw_name);
goto err_load_fw;
@@ -482,7 +438,6 @@ static int mwl_init_firmware(struct mwl_priv *priv, char *fw_name)
rc = mwl_fwdl_download_firmware(priv->hw);
if (rc) {
-
WLDBG_ERROR(DBG_LEVEL_0, "%s: cannot download firmware image <%s>",
MWL_DRV_NAME, fw_name);
goto err_download_fw;
@@ -503,100 +458,179 @@ err_load_fw:
return rc;
}
-static int mwl_load_tx_pwr_tbl(struct mwl_priv *priv, char *pwr_tbl)
+static void mwl_reg_notifier(struct wiphy *wiphy,
+ struct regulatory_request *request)
{
- struct file *filp = NULL;
- mm_segment_t oldfs;
- char buff[120], *s;
- int len, index = 0, i, value = 0;
- char param[20][32];
- int rc = 0;
+ struct ieee80211_hw *hw;
+ struct mwl_priv *priv;
+ struct property *prop;
+ struct property *fcc_prop = NULL;
+ struct property *etsi_prop = NULL;
+ struct property *specific_prop = NULL;
+ u32 prop_value;
+ int i, j, k;
WLDBG_ENTER(DBG_LEVEL_0);
+ BUG_ON(!wiphy);
+ hw = (struct ieee80211_hw *) wiphy_priv(wiphy);
+ BUG_ON(!hw);
+ priv = hw->priv;
BUG_ON(!priv);
- oldfs = get_fs();
- set_fs(KERNEL_DS);
-
- filp = filp_open(pwr_tbl, O_RDONLY, 0);
-
- if (!IS_ERR(filp)) { /* MUST use this one, important!!! */
-
- WLDBG_PRINT("open tx power table <%s>: OK", pwr_tbl);
-
- /* reset the whole table */
- for (i = 0; i < SYSADPT_MAX_NUM_CHANNELS; i++)
- memset(&priv->tx_pwr_tbl[i], 0, sizeof(struct mwl_tx_pwr_tbl));
+ if (priv->pwr_node != NULL) {
+ for_each_property_of_node(priv->pwr_node, prop) {
+ if(strcmp(prop->name, "FCC") == 0)
+ fcc_prop = prop;
+ if (strcmp(prop->name, "ETSI") == 0)
+ etsi_prop = prop;
+ if ((prop->name[0] == request->alpha2[0]) &&
+ (prop->name[1] == request->alpha2[1]))
+ specific_prop = prop;
+ }
- while (1) {
+ prop = NULL;
- s = buff;
- while ((len = vfs_read(filp, s, 0x01, &filp->f_pos)) == 1) {
+ if (specific_prop != NULL) {
+ prop = specific_prop;
+ } else {
+ if (request->dfs_region == NL80211_DFS_ETSI)
+ prop = etsi_prop;
+ else
+ prop = fcc_prop;
+ }
- if (*s == '\n') {
- /* skip blank line */
- if (s == buff)
- break;
+ if (prop != NULL) {
+ /* Reset the whole table
+ */
+ for (i = 0; i < SYSADPT_MAX_NUM_CHANNELS; i++)
+ memset(&priv->tx_pwr_tbl[i], 0,
+ sizeof(struct mwl_tx_pwr_tbl));
+
+ /* Load related power table
+ */
+ i = 0;
+ j = 0;
+ while (i < prop->length) {
+ prop_value = be32_to_cpu(*(u32 *)(prop->value + i));
+ priv->tx_pwr_tbl[j].channel = prop_value;
+ i += 4;
+ prop_value = be32_to_cpu(*(u32 *)(prop->value + i));
+ priv->tx_pwr_tbl[j].setcap = prop_value;
+ i += 4;
+ for (k = 0; k < SYSADPT_TX_POWER_LEVEL_TOTAL; k++) {
+ prop_value = be32_to_cpu(*(u32 *)(prop->value + i));
+ priv->tx_pwr_tbl[j].tx_power[k] = prop_value;
+ i += 4;
+ }
+ prop_value = be32_to_cpu(*(u32 *)(prop->value + i));
+ priv->tx_pwr_tbl[j].cdd = prop_value;
+ i += 4;
+ prop_value = be32_to_cpu(*(u32 *)(prop->value + i));
+ priv->tx_pwr_tbl[j].txantenna2 = prop_value;
+ i += 4;
+ j++;
+ }
- /* parse this line and assign value to data structure */
- *s = '\0';
- /* WLDBG_PRINT("index=<%d>: <%s>", index, buff); */
- /* 8864 total param: ch + setcap + 16 txpower + CDD + tx2 = 16 */
- sscanf(buff, "%s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s\n", param[0], param[1], param[2], param[3], param[4], param[5]
- , param[6], param[7], param[8], param[9], param[10], param[11], param[12], param[13], param[14], param[15], param[16], param[17]
- , param[18], param[19]);
+ /* Dump loaded power tabel
+ */
+ WLDBG_PRINT("%s: %s\n", dev_name(&wiphy->dev), prop->name);
+ for (i = 0; i < SYSADPT_MAX_NUM_CHANNELS; i++) {
+ char disp_buf[64];
+ char *disp_ptr;
+
+ if (priv->tx_pwr_tbl[i].channel == 0)
+ break;
+ WLDBG_PRINT("Channel: %d: 0x%x 0x%x 0x%x",
+ priv->tx_pwr_tbl[i].channel,
+ priv->tx_pwr_tbl[i].setcap,
+ priv->tx_pwr_tbl[i].cdd,
+ priv->tx_pwr_tbl[i].txantenna2);
+ disp_ptr = disp_buf;
+ for (j = 0; j < SYSADPT_TX_POWER_LEVEL_TOTAL; j++) {
+ disp_ptr +=
+ sprintf(disp_ptr, "%x ",
+ priv->tx_pwr_tbl[i].tx_power[j]);
+ }
+ WLDBG_PRINT("%s", disp_buf);
+ }
+ }
+ }
- if (strcmp(param[18], "on") == 0)
- value = 1;
- else if (strcmp(param[18], "off") == 0)
- value = 0;
- else {
- WLDBG_PRINT("txpower table format error: CCD should be on|off");
- break;
- }
+ WLDBG_EXIT(DBG_LEVEL_0);
+}
- priv->tx_pwr_tbl[index].cdd = value;
- priv->tx_pwr_tbl[index].txantenna2 = atohex2(param[19]);
- priv->tx_pwr_tbl[index].channel = atoi(param[0]);
- priv->tx_pwr_tbl[index].setcap = atoi(param[1]);
+static void mwl_process_of_dts(struct mwl_priv *priv)
+{
+ struct property *prop;
+ u32 prop_value;
- for (i = 0; i < SYSADPT_TX_POWER_LEVEL_TOTAL; i++)
- priv->tx_pwr_tbl[index].tx_power[i] = atohex2(param[i+2]);
+ WLDBG_ENTER(DBG_LEVEL_0);
- index++;
- break;
+ BUG_ON(!priv);
- } else {
+ priv->disable_2g = false;
+ priv->disable_5g = false;
+ priv->antenna_tx = ANTENNA_TX_4_AUTO;
+ priv->antenna_rx = ANTENNA_RX_4_AUTO;
- s++;
+ priv->dt_node =
+ of_find_node_by_name(pci_bus_to_OF_node(priv->pdev->bus),
+ "mwlwifi");
- }
+ /* look for all matching property names
+ */
+ if (priv->dt_node != NULL) {
+ for_each_property_of_node(priv->dt_node, prop) {
+ if (strcmp(prop->name, "marvell,2ghz") == 0)
+ priv->disable_2g = true;
+ if (strcmp(prop->name, "marvell,5ghz") == 0)
+ priv->disable_5g = true;
+ if (strcmp(prop->name, "marvell,chainmask") == 0) {
+ prop_value = be32_to_cpu(*((u32 *)prop->value));
+ if (prop_value == 2)
+ priv->antenna_tx = ANTENNA_TX_2;
+
+ prop_value = be32_to_cpu(*((u32 *)(prop->value + 4)));
+ if (prop_value == 2)
+ priv->antenna_rx = ANTENNA_RX_2;
}
-
- if (len <= 0)
- break;
}
- filp_close(filp, current->files);
-
- } else {
-
- WLDBG_PRINT("open tx power table <%s>: FAIL", pwr_tbl);
- rc = -EIO;
-
+ priv->pwr_node = of_find_node_by_name(priv->dt_node,
+ "marvell,powertable");
}
- set_fs(oldfs);
+ WLDBG_PRINT("2G: %s\n", priv->disable_2g ? "disable" : "enable");
+ WLDBG_PRINT("5G: %s\n", priv->disable_5g ? "disable" : "enable");
- WLDBG_EXIT_INFO(DBG_LEVEL_0, "result: %d", rc);
+ if (priv->antenna_tx == ANTENNA_TX_4_AUTO)
+ WLDBG_PRINT("TX: 4 antennas\n");
+ else if (priv->antenna_tx == ANTENNA_TX_2)
+ WLDBG_PRINT("TX: 2 antennas\n");
+ else
+ WLDBG_PRINT("TX: unknown\n");
+ if (priv->antenna_rx == ANTENNA_RX_4_AUTO)
+ WLDBG_PRINT("RX: 4 antennas\n");
+ else if (priv->antenna_rx == ANTENNA_RX_2)
+ WLDBG_PRINT("RX: 2 antennas\n");
+ else
+ WLDBG_PRINT("RX: unknown\n");
- return rc;
+ WLDBG_EXIT(DBG_LEVEL_0);
}
-static void mwl_set_ht_caps(struct ieee80211_hw *hw,
+static void mwl_set_ht_caps(struct mwl_priv *priv,
struct ieee80211_supported_band *band)
{
+ struct ieee80211_hw *hw;
+
+ WLDBG_ENTER(DBG_LEVEL_0);
+
+ BUG_ON(!priv);
+ hw = priv->hw;
+ BUG_ON(!hw);
+
band->ht_cap.ht_supported = 1;
band->ht_cap.cap |= IEEE80211_HT_CAP_LDPC_CODING;
@@ -611,15 +645,20 @@ static void mwl_set_ht_caps(struct ieee80211_hw *hw,
band->ht_cap.mcs.rx_mask[0] = 0xff;
band->ht_cap.mcs.rx_mask[1] = 0xff;
- band->ht_cap.mcs.rx_mask[2] = 0xff;
+ if (priv->antenna_rx == ANTENNA_RX_4_AUTO)
+ band->ht_cap.mcs.rx_mask[2] = 0xff;
band->ht_cap.mcs.rx_mask[4] = 0x01;
band->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
+
+ WLDBG_EXIT(DBG_LEVEL_0);
}
-static void mwl_set_vht_caps(struct ieee80211_hw *hw,
+static void mwl_set_vht_caps(struct mwl_priv *priv,
struct ieee80211_supported_band *band)
{
+ WLDBG_ENTER(DBG_LEVEL_0);
+
band->vht_cap.vht_supported = 1;
band->vht_cap.cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454;
@@ -634,8 +673,17 @@ static void mwl_set_vht_caps(struct ieee80211_hw *hw,
band->vht_cap.cap |= IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN;
band->vht_cap.cap |= IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN;
- band->vht_cap.vht_mcs.rx_mcs_map = 0xffea;
- band->vht_cap.vht_mcs.tx_mcs_map = 0xffea;
+ if (priv->antenna_rx == ANTENNA_RX_2)
+ band->vht_cap.vht_mcs.rx_mcs_map = 0xfffa;
+ else
+ band->vht_cap.vht_mcs.rx_mcs_map = 0xffea;
+
+ if (priv->antenna_tx == ANTENNA_TX_2)
+ band->vht_cap.vht_mcs.tx_mcs_map = 0xfffa;
+ else
+ band->vht_cap.vht_mcs.tx_mcs_map = 0xffea;
+
+ WLDBG_EXIT(DBG_LEVEL_0);
}
static void mwl_set_caps(struct mwl_priv *priv)
@@ -650,41 +698,45 @@ static void mwl_set_caps(struct mwl_priv *priv)
/* set up band information for 2.4G
*/
- BUILD_BUG_ON(sizeof(priv->channels_24) != sizeof(mwl_channels_24));
- memcpy(priv->channels_24, mwl_channels_24, sizeof(mwl_channels_24));
+ if (priv->disable_2g == false) {
+ BUILD_BUG_ON(sizeof(priv->channels_24) != sizeof(mwl_channels_24));
+ memcpy(priv->channels_24, mwl_channels_24, sizeof(mwl_channels_24));
- BUILD_BUG_ON(sizeof(priv->rates_24) != sizeof(mwl_rates_24));
- memcpy(priv->rates_24, mwl_rates_24, sizeof(mwl_rates_24));
+ BUILD_BUG_ON(sizeof(priv->rates_24) != sizeof(mwl_rates_24));
+ memcpy(priv->rates_24, mwl_rates_24, sizeof(mwl_rates_24));
- priv->band_24.band = IEEE80211_BAND_2GHZ;
- priv->band_24.channels = priv->channels_24;
- priv->band_24.n_channels = ARRAY_SIZE(mwl_channels_24);
- priv->band_24.bitrates = priv->rates_24;
- priv->band_24.n_bitrates = ARRAY_SIZE(mwl_rates_24);
+ priv->band_24.band = IEEE80211_BAND_2GHZ;
+ priv->band_24.channels = priv->channels_24;
+ priv->band_24.n_channels = ARRAY_SIZE(mwl_channels_24);
+ priv->band_24.bitrates = priv->rates_24;
+ priv->band_24.n_bitrates = ARRAY_SIZE(mwl_rates_24);
- mwl_set_ht_caps(hw, &priv->band_24);
- mwl_set_vht_caps(hw, &priv->band_24);
+ mwl_set_ht_caps(priv, &priv->band_24);
+ mwl_set_vht_caps(priv, &priv->band_24);
- hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band_24;
+ hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band_24;
+ }
/* set up band information for 5G
*/
- BUILD_BUG_ON(sizeof(priv->channels_50) != sizeof(mwl_channels_50));
- memcpy(priv->channels_50, mwl_channels_50, sizeof(mwl_channels_50));
+ if (priv->disable_5g == false) {
+ BUILD_BUG_ON(sizeof(priv->channels_50) != sizeof(mwl_channels_50));
+ memcpy(priv->channels_50, mwl_channels_50, sizeof(mwl_channels_50));
- BUILD_BUG_ON(sizeof(priv->rates_50) != sizeof(mwl_rates_50));
- memcpy(priv->rates_50, mwl_rates_50, sizeof(mwl_rates_50));
+ BUILD_BUG_ON(sizeof(priv->rates_50) != sizeof(mwl_rates_50));
+ memcpy(priv->rates_50, mwl_rates_50, sizeof(mwl_rates_50));
- priv->band_50.band = IEEE80211_BAND_5GHZ;
- priv->band_50.channels = priv->channels_50;
- priv->band_50.n_channels = ARRAY_SIZE(mwl_channels_50);
- priv->band_50.bitrates = priv->rates_50;
- priv->band_50.n_bitrates = ARRAY_SIZE(mwl_rates_50);
+ priv->band_50.band = IEEE80211_BAND_5GHZ;
+ priv->band_50.channels = priv->channels_50;
+ priv->band_50.n_channels = ARRAY_SIZE(mwl_channels_50);
+ priv->band_50.bitrates = priv->rates_50;
+ priv->band_50.n_bitrates = ARRAY_SIZE(mwl_rates_50);
- mwl_set_ht_caps(hw, &priv->band_50);
- mwl_set_vht_caps(hw, &priv->band_50);
+ mwl_set_ht_caps(priv, &priv->band_50);
+ mwl_set_vht_caps(priv, &priv->band_50);
- hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &priv->band_50;
+ hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &priv->band_50;
+ }
WLDBG_EXIT(DBG_LEVEL_0);
}
@@ -722,8 +774,8 @@ static int mwl_wl_init(struct mwl_priv *priv)
hw->vif_data_size = sizeof(struct mwl_vif);
hw->sta_data_size = sizeof(struct mwl_sta);
- priv->ap_macids_supported = 0x000000ff;
- priv->sta_macids_supported = 0x00000100;
+ priv->ap_macids_supported = 0x0000ffff;
+ priv->sta_macids_supported = 0x00010000;
priv->macids_used = 0;
INIT_LIST_HEAD(&priv->vif_list);
@@ -754,7 +806,6 @@ static int mwl_wl_init(struct mwl_priv *priv)
rc = mwl_tx_init(hw);
if (rc) {
-
WLDBG_ERROR(DBG_LEVEL_0, "%s: fail to initialize TX",
MWL_DRV_NAME);
goto err_mwl_tx_init;
@@ -762,7 +813,6 @@ static int mwl_wl_init(struct mwl_priv *priv)
rc = mwl_rx_init(hw);
if (rc) {
-
WLDBG_ERROR(DBG_LEVEL_0, "%s: fail to initialize RX",
MWL_DRV_NAME);
goto err_mwl_rx_init;
@@ -770,7 +820,6 @@ static int mwl_wl_init(struct mwl_priv *priv)
rc = mwl_fwcmd_get_hw_specs(hw);
if (rc) {
-
WLDBG_ERROR(DBG_LEVEL_0, "%s: fail to get HW specifications",
MWL_DRV_NAME);
goto err_get_hw_specs;
@@ -792,17 +841,18 @@ static int mwl_wl_init(struct mwl_priv *priv)
rc = mwl_fwcmd_set_hw_specs(hw);
if (rc) {
-
WLDBG_ERROR(DBG_LEVEL_0, "%s: fail to set HW specifications",
MWL_DRV_NAME);
goto err_set_hw_specs;
}
+ WLDBG_PRINT("firmware version: 0x%x", priv->hw_data.fw_release_num);
+
mwl_fwcmd_radio_disable(hw);
- mwl_fwcmd_rf_antenna(hw, WL_ANTENNATYPE_RX, 0);
+ mwl_fwcmd_rf_antenna(hw, WL_ANTENNATYPE_TX, priv->antenna_tx);
- mwl_fwcmd_rf_antenna(hw, WL_ANTENNATYPE_TX, 0);
+ mwl_fwcmd_rf_antenna(hw, WL_ANTENNATYPE_RX, priv->antenna_rx);
hw->wiphy->interface_modes = 0;
hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP);
@@ -814,7 +864,6 @@ static int mwl_wl_init(struct mwl_priv *priv)
rc = ieee80211_register_hw(hw);
if (rc) {
-
WLDBG_ERROR(DBG_LEVEL_0, "%s: fail to register device",
MWL_DRV_NAME);
goto err_register_hw;
@@ -881,7 +930,6 @@ static void mwl_watchdog_ba_events(struct work_struct *work)
/* the bitmap is the hw queue number. Map it to the ampdu queue.
*/
if (bitmap != INVALID_WATCHDOG) {
-
if (bitmap == SYSADPT_TX_AMPDU_QUEUES)
stream_index = 0;
else if (bitmap > SYSADPT_TX_AMPDU_QUEUES)
@@ -890,28 +938,22 @@ static void mwl_watchdog_ba_events(struct work_struct *work)
stream_index = bitmap + 3; /** queue 0 is stream 3*/
if (bitmap != 0xFF) {
-
/* Check if the stream is in use before disabling it
*/
streams = &priv->ampdu[stream_index];
if (streams->state == AMPDU_STREAM_ACTIVE) {
-
ieee80211_stop_tx_ba_session(streams->sta,
streams->tid);
SPIN_UNLOCK(&priv->locks.stream_lock);
mwl_fwcmd_destroy_ba(hw, stream_index);
SPIN_LOCK(&priv->locks.stream_lock);
}
-
} else {
-
for (stream_index = 0; stream_index < SYSADPT_TX_AMPDU_QUEUES; stream_index++) {
-
streams = &priv->ampdu[stream_index];
if (streams->state == AMPDU_STREAM_ACTIVE) {
-
ieee80211_stop_tx_ba_session(streams->sta,
streams->tid);
SPIN_UNLOCK(&priv->locks.stream_lock);
@@ -950,19 +992,14 @@ static irqreturn_t mwl_interrupt(int irq, void *dev_id)
return IRQ_NONE;
if (int_status == 0xffffffff) {
-
WLDBG_INFO(DBG_LEVEL_0, "card plugged out???");
-
} else {
-
clr_status = int_status;
if (int_status & MACREG_A2HRIC_BIT_TX_DONE) {
-
int_status &= ~MACREG_A2HRIC_BIT_TX_DONE;
if (priv->is_tx_schedule == false) {
-
status = readl(priv->iobase1 + MACREG_REG_A2H_INTERRUPT_STATUS_MASK);
writel((status & ~MACREG_A2HRIC_BIT_TX_DONE),
priv->iobase1 + MACREG_REG_A2H_INTERRUPT_STATUS_MASK);
@@ -972,11 +1009,9 @@ static irqreturn_t mwl_interrupt(int irq, void *dev_id)
}
if (int_status & MACREG_A2HRIC_BIT_RX_RDY) {
-
int_status &= ~MACREG_A2HRIC_BIT_RX_RDY;
if (priv->is_rx_schedule == false) {
-
status = readl(priv->iobase1 + MACREG_REG_A2H_INTERRUPT_STATUS_MASK);
writel((status & ~MACREG_A2HRIC_BIT_RX_RDY),
priv->iobase1 + MACREG_REG_A2H_INTERRUPT_STATUS_MASK);
@@ -986,7 +1021,6 @@ static irqreturn_t mwl_interrupt(int irq, void *dev_id)
}
if (int_status & MACREG_A2HRIC_BA_WATCHDOG) {
-
status = readl(priv->iobase1 + MACREG_REG_A2H_INTERRUPT_STATUS_MASK);
writel((status & ~MACREG_A2HRIC_BA_WATCHDOG),
priv->iobase1 + MACREG_REG_A2H_INTERRUPT_STATUS_MASK);
@@ -1001,70 +1035,12 @@ static irqreturn_t mwl_interrupt(int irq, void *dev_id)
return IRQ_HANDLED;
}
-static int atoi(const char *num_str)
-{
- int val = 0;
-
- for (;; num_str++) {
-
- switch (*num_str) {
-
- case '0'...'9':
- val = 10*val+(*num_str-'0');
- break;
-
- default:
- return val;
- }
- }
-}
-
-static long atohex(const char *number)
-{
- long n = 0;
-
- if (*number == '0' && (*(number + 1) == 'x' || *(number + 1) == 'X'))
- number += 2;
-
- while (*number <= ' ' && *number > 0)
- ++number;
-
- while ((*number >= '0' && *number <= '9') ||
- (*number >= 'A' && *number <= 'F') ||
- (*number >= 'a' && *number <= 'f')) {
-
- if (*number >= '0' && *number <= '9') {
-
- n = (n * 0x10) + ((*number++) - '0');
-
- } else if (*number >= 'A' && *number <= 'F') {
-
- n = (n * 0x10) + ((*number++) - 'A' + 10);
-
- } else {
-
- n = (n * 0x10) + ((*number++) - 'a' + 10);
-
- }
- }
-
- return n;
-}
-
-static long atohex2(const char *number)
-{
- long n = 0;
-
- while (*number <= ' ' && *number > 0)
- ++number;
- if (*number == 0)
- return n;
-
- if (*number == '0' && (*(number + 1) == 'x' || *(number + 1) == 'X'))
- n = atohex(number+2);
- else
- n = atoi(number);
+module_pci_driver(mwl_pci_driver);
- return n;
-}
+MODULE_DESCRIPTION(MWL_DESC);
+MODULE_VERSION(MWL_DRV_VERSION);
+MODULE_AUTHOR("Marvell Semiconductor, Inc.");
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_SUPPORTED_DEVICE(MWL_DEV_NAME);
+MODULE_DEVICE_TABLE(pci, mwl_pci_id_tbl);
diff --git a/mwl_rx.c b/mwl_rx.c
index 90cea3a..f34c6db 100644
--- a/mwl_rx.c
+++ b/mwl_rx.c
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2006-2014 Marvell International Ltd.
+* Copyright (c) 2006-2015 Marvell International Ltd.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -20,6 +20,8 @@
*
*/
+#include <linux/skbuff.h>
+
#include "mwl_sysadpt.h"
#include "mwl_dev.h"
#include "mwl_debug.h"
@@ -72,14 +74,10 @@ int mwl_rx_init(struct ieee80211_hw *hw)
rc = mwl_rx_ring_alloc(priv);
if (rc) {
-
WLDBG_ERROR(DBG_LEVEL_4, "allocating RX ring failed");
-
} else {
-
rc = mwl_rx_ring_init(priv);
if (rc) {
-
mwl_rx_ring_free(priv);
WLDBG_ERROR(DBG_LEVEL_4, "initializing RX ring failed");
}
@@ -128,7 +126,6 @@ void mwl_rx_recv(unsigned long data)
curr_desc = priv->desc_data[0].pnext_rx_desc;
if (curr_desc == NULL) {
-
status_mask = readl(priv->iobase1 + MACREG_REG_A2H_INTERRUPT_STATUS_MASK);
writel(status_mask | MACREG_A2HRIC_BIT_RX_RDY,
priv->iobase1 + MACREG_REG_A2H_INTERRUPT_STATUS_MASK);
@@ -141,21 +138,18 @@ void mwl_rx_recv(unsigned long data)
while ((curr_desc->rx_control == EAGLE_RXD_CTRL_DMA_OWN)
&& (work_done < priv->recv_limit)) {
-
prx_skb = curr_desc->psk_buff;
if (prx_skb == NULL)
goto out;
pci_unmap_single(priv->pdev,
- ENDIAN_SWAP32(curr_desc->pphys_buff_data),
+ ENDIAN_SWAP32(curr_desc->pphys_buff_data),
priv->desc_data[0].rx_buf_size,
PCI_DMA_FROMDEVICE);
pkt_len = curr_desc->pkt_len;
if (skb_tailroom(prx_skb) < pkt_len) {
-
- WLDBG_INFO(DBG_LEVEL_4, "Not enough tail room =%x pkt_len=%x, curr_desc=%x, curr_desc_data=%x",
- skb_tailroom(prx_skb), pkt_len, curr_desc, curr_desc->pbuff_data);
- dev_kfree_skb_any(prx_skb);
+ WLDBG_PRINT("Critical error: not enough tail room =%x pkt_len=%x, curr_desc=%x, curr_desc_data=%x",
+ skb_tailroom(prx_skb), pkt_len, curr_desc, curr_desc->pbuff_data);
goto out;
}
@@ -166,13 +160,16 @@ void mwl_rx_recv(unsigned long data)
wh = &((struct mwl_dma_data *)prx_skb->data)->wh;
if (ieee80211_has_protected(wh->frame_control)) {
-
/* Check if hw crypto has been enabled for
* this bss. If yes, set the status flags
* accordingly
*/
- mwl_vif = mwl_rx_find_vif_bss(&priv->vif_list,
- wh->addr1);
+ if (ieee80211_has_tods(wh->frame_control))
+ mwl_vif = mwl_rx_find_vif_bss(&priv->vif_list,
+ wh->addr1);
+ else
+ mwl_vif = mwl_rx_find_vif_bss(&priv->vif_list,
+ wh->addr2);
if (mwl_vif != NULL &&
mwl_vif->is_hw_crypto_enabled) {
@@ -190,7 +187,6 @@ void mwl_rx_recv(unsigned long data)
* Measure of MMIC failure.
*/
if (status.flag & RX_FLAG_MMIC_ERROR) {
-
struct mwl_dma_data *tr;
tr = (struct mwl_dma_data *)prx_skb->data;
@@ -199,7 +195,6 @@ void mwl_rx_recv(unsigned long data)
}
if (!ieee80211_is_auth(wh->frame_control))
-
status.flag |= RX_FLAG_IV_STRIPPED |
RX_FLAG_DECRYPTED |
RX_FLAG_MMIC_STRIPPED;
@@ -242,12 +237,11 @@ static int mwl_rx_ring_alloc(struct mwl_priv *priv)
BUG_ON(!priv);
priv->desc_data[0].prx_ring =
- (struct mwl_rx_desc *)pci_alloc_consistent(priv->pdev,
+ (struct mwl_rx_desc *)dma_alloc_coherent(&priv->pdev->dev,
MAX_NUM_RX_RING_BYTES,
- &priv->desc_data[0].pphys_rx_ring);
+ &priv->desc_data[0].pphys_rx_ring, GFP_KERNEL);
if (priv->desc_data[0].prx_ring == NULL) {
-
WLDBG_ERROR(DBG_LEVEL_4, "can not alloc mem");
WLDBG_EXIT_INFO(DBG_LEVEL_4, "no memory");
return -ENOMEM;
@@ -268,15 +262,12 @@ static int mwl_rx_ring_init(struct mwl_priv *priv)
WLDBG_ENTER_INFO(DBG_LEVEL_4, "initializing %i descriptors", SYSADPT_MAX_NUM_RX_DESC);
if (priv->desc_data[0].prx_ring != NULL) {
-
priv->desc_data[0].rx_buf_size = SYSADPT_MAX_AGGR_SIZE;
for (curr_desc = 0; curr_desc < SYSADPT_MAX_NUM_RX_DESC; curr_desc++) {
-
CURR_RXD.psk_buff = dev_alloc_skb(priv->desc_data[0].rx_buf_size);
if (skb_linearize(CURR_RXD.psk_buff)) {
-
dev_kfree_skb_any(CURR_RXD.psk_buff);
WLDBG_ERROR(DBG_LEVEL_4, "need linearize memory");
WLDBG_EXIT_INFO(DBG_LEVEL_4, "no suitable memory");
@@ -289,10 +280,8 @@ static int mwl_rx_ring_init(struct mwl_priv *priv)
CURR_RXD.qos_ctrl = 0x0000;
CURR_RXD.channel = 0x00;
CURR_RXD.rssi = 0x00;
- CURR_RXD.sq2 = 0x00;
if (CURR_RXD.psk_buff != NULL) {
-
CURR_RXD.pkt_len = SYSADPT_MAX_AGGR_SIZE;
CURR_RXD.pbuff_data = CURR_RXD.psk_buff->data;
CURR_RXD.pphys_buff_data =
@@ -312,7 +301,6 @@ static int mwl_rx_ring_init(struct mwl_priv *priv)
"rxdesc: %i vnext: 0x%p pnext: 0x%x", curr_desc,
CURR_RXD.pnext, ENDIAN_SWAP32(CURR_RXD.pphys_next));
} else {
-
WLDBG_ERROR(DBG_LEVEL_4,
"rxdesc %i: no skbuff available", curr_desc);
WLDBG_EXIT_INFO(DBG_LEVEL_4, "no socket buffer");
@@ -347,11 +335,8 @@ static void mwl_rx_ring_cleanup(struct mwl_priv *priv)
BUG_ON(!priv);
if (priv->desc_data[0].prx_ring != NULL) {
-
for (curr_desc = 0; curr_desc < SYSADPT_MAX_NUM_RX_DESC; curr_desc++) {
-
if (CURR_RXD.psk_buff != NULL) {
-
if (skb_shinfo(CURR_RXD.psk_buff)->nr_frags)
skb_shinfo(CURR_RXD.psk_buff)->nr_frags = 0;
@@ -387,11 +372,10 @@ static void mwl_rx_ring_free(struct mwl_priv *priv)
BUG_ON(!priv);
if (priv->desc_data[0].prx_ring != NULL) {
-
mwl_rx_ring_cleanup(priv);
- pci_free_consistent(priv->pdev,
- MAX_NUM_RX_RING_BYTES,
+ dma_free_coherent(&priv->pdev->dev,
+ MAX_NUM_RX_RING_BYTES,
priv->desc_data[0].prx_ring,
priv->desc_data[0].pphys_rx_ring);
@@ -415,7 +399,7 @@ static inline void mwl_rx_prepare_status(struct mwl_rx_desc *pdesc,
status->signal = -(pdesc->rssi + W836X_RSSI_OFFSET);
- /* TODO: rate & antenna
+ /* TODO: rate information report
*/
if (pdesc->channel > 14)
@@ -429,12 +413,10 @@ static inline void mwl_rx_prepare_status(struct mwl_rx_desc *pdesc,
/* check if status has a specific error bit (bit 7)set or indicates a general decrypt error
*/
if ((pdesc->status == GENERAL_DECRYPT_ERR) || (pdesc->status & DECRYPT_ERR_MASK)) {
-
/* check if status is not equal to 0xFF
* the 0xFF check is for backward compatibility
*/
if (pdesc->status != GENERAL_DECRYPT_ERR) {
-
if (((pdesc->status & (~DECRYPT_ERR_MASK)) & TKIP_DECRYPT_MIC_ERR) &&
!((pdesc->status & (WEP_DECRYPT_ICV_ERR | TKIP_DECRYPT_ICV_ERR)))) {
@@ -451,7 +433,6 @@ static inline struct mwl_vif *mwl_rx_find_vif_bss(struct list_head *vif_list, u8
struct mwl_vif *mwl_vif;
list_for_each_entry(mwl_vif, vif_list, list) {
-
if (memcmp(bssid, mwl_vif->bssid, ETH_ALEN) == 0)
return mwl_vif;
}
@@ -468,7 +449,6 @@ static inline void mwl_rx_remove_dma_header(struct sk_buff *skb, u16 qos)
hdrlen = ieee80211_hdrlen(tr->wh.frame_control);
if (hdrlen != sizeof(tr->wh)) {
-
if (ieee80211_is_data_qos(tr->wh.frame_control)) {
memmove(tr->data - hdrlen, &tr->wh, hdrlen - 2);
*((u16 *)(tr->data - 2)) = qos;
@@ -494,7 +474,6 @@ static int mwl_rx_refill(struct mwl_priv *priv, struct mwl_rx_desc *pdesc)
goto nomem;
if (skb_linearize(pdesc->psk_buff)) {
-
dev_kfree_skb_any(pdesc->psk_buff);
WLDBG_ERROR(DBG_LEVEL_4, "need linearize memory");
goto nomem;
@@ -506,7 +485,6 @@ static int mwl_rx_refill(struct mwl_priv *priv, struct mwl_rx_desc *pdesc)
pdesc->qos_ctrl = 0x0000;
pdesc->channel = 0x00;
pdesc->rssi = 0x00;
- pdesc->sq2 = 0x00;
pdesc->pkt_len = priv->desc_data[0].rx_buf_size;
pdesc->pbuff_data = pdesc->psk_buff->data;
diff --git a/mwl_rx.h b/mwl_rx.h
index 191280e..9922134 100644
--- a/mwl_rx.h
+++ b/mwl_rx.h
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2006-2014 Marvell International Ltd.
+* Copyright (c) 2006-2015 Marvell International Ltd.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
diff --git a/mwl_sysadpt.h b/mwl_sysadpt.h
index 5c509e1..1d7ac67 100644
--- a/mwl_sysadpt.h
+++ b/mwl_sysadpt.h
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2006-2014 Marvell International Ltd.
+* Copyright (c) 2006-2015 Marvell International Ltd.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -38,11 +38,13 @@
#define SYSADPT_TX_AMPDU_QUEUES 4
-#define SYSADPT_TOTAL_TX_QUEUES SYSADPT_TX_WMM_QUEUES
+#define SYSADPT_NUM_OF_AP 16
+
+#define SYSADPT_TOTAL_TX_QUEUES (SYSADPT_TX_WMM_QUEUES + SYSADPT_NUM_OF_AP)
#define SYSADPT_TOTAL_HW_QUEUES (SYSADPT_TX_WMM_QUEUES + SYSADPT_TX_AMPDU_QUEUES)
-#define SYSADPT_NUM_OF_DESC_DATA 4
+#define SYSADPT_NUM_OF_DESC_DATA (4 + SYSADPT_NUM_OF_AP)
#define SYSADPT_MAX_NUM_TX_DESC 256
diff --git a/mwl_tx.c b/mwl_tx.c
index 4594537..294df9a 100644
--- a/mwl_tx.c
+++ b/mwl_tx.c
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2006-2014 Marvell International Ltd.
+* Copyright (c) 2006-2015 Marvell International Ltd.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -21,6 +21,7 @@
*/
#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
#include "mwl_sysadpt.h"
#include "mwl_dev.h"
@@ -85,14 +86,10 @@ int mwl_tx_init(struct ieee80211_hw *hw)
rc = mwl_tx_ring_alloc(priv);
if (rc) {
-
WLDBG_ERROR(DBG_LEVEL_3, "allocating TX ring failed");
-
} else {
-
rc = mwl_tx_ring_init(priv);
if (rc) {
-
mwl_tx_ring_free(priv);
WLDBG_ERROR(DBG_LEVEL_3, "initializing TX ring failed");
}
@@ -158,13 +155,11 @@ void mwl_tx_xmit(struct ieee80211_hw *hw,
qos = 0;
if (skb->protocol == cpu_to_be16(ETH_P_PAE)) {
-
index = IEEE80211_AC_VO;
eapol_frame = true;
}
if (ieee80211_is_mgmt(wh->frame_control)) {
-
mgmtframe = true;
mgmt = (struct ieee80211_mgmt *)skb->data;
}
@@ -177,7 +172,6 @@ void mwl_tx_xmit(struct ieee80211_hw *hw,
mwl_vif = MWL_VIF(tx_info->control.vif);
if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
-
wh->seq_ctrl &= ENDIAN_SWAP16(IEEE80211_SCTL_FRAG);
wh->seq_ctrl |= ENDIAN_SWAP16(mwl_vif->seqno);
mwl_vif->seqno += 0x10;
@@ -188,11 +182,8 @@ void mwl_tx_xmit(struct ieee80211_hw *hw,
xmitcontrol = 0;
if (mgmtframe || ieee80211_is_ctl(wh->frame_control)) {
-
qos = 0;
-
} else if (ieee80211_is_data(wh->frame_control)) {
-
qos &= ~MWL_QOS_ACK_POLICY_MASK;
if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
@@ -204,25 +195,31 @@ void mwl_tx_xmit(struct ieee80211_hw *hw,
}
if (is_multicast_ether_addr(wh->addr1)) {
-
xmitcontrol |= EAGLE_TXD_XMITCTRL_USE_MC_RATE;
if (ccmp) {
-
mwl_tx_insert_ccmp_hdr(((struct mwl_dma_data *)skb->data)->data,
- mwl_vif->keyidx, mwl_vif->iv16, mwl_vif->iv32);
+ mwl_vif->keyidx,
+ mwl_vif->iv16,
+ mwl_vif->iv32);
INCREASE_IV(mwl_vif->iv16, mwl_vif->iv32);
}
-
} else {
-
if (ccmp) {
+ if (mwl_vif->is_sta == true) {
+ mwl_tx_insert_ccmp_hdr(((struct mwl_dma_data *)skb->data)->data,
+ mwl_vif->keyidx,
+ mwl_vif->iv16,
+ mwl_vif->iv32);
+ INCREASE_IV(mwl_vif->iv16, mwl_vif->iv32);
+ } else {
+ struct mwl_sta *sta_info = MWL_STA(sta);
- struct mwl_sta *sta_info = MWL_STA(sta);
-
- mwl_tx_insert_ccmp_hdr(((struct mwl_dma_data *)skb->data)->data,
- 0, sta_info->iv16, sta_info->iv32);
- INCREASE_IV(sta_info->iv16, sta_info->iv32);
+ mwl_tx_insert_ccmp_hdr(((struct mwl_dma_data *)skb->data)->data,
+ 0, sta_info->iv16,
+ sta_info->iv32);
+ INCREASE_IV(sta_info->iv16, sta_info->iv32);
+ }
}
}
}
@@ -237,13 +234,10 @@ void mwl_tx_xmit(struct ieee80211_hw *hw,
* been setup.
*/
if (mgmtframe) {
-
if (unlikely(ieee80211_is_action(wh->frame_control) &&
- mgmt->u.action.category == WLAN_CATEGORY_BACK &&
- mgmt->u.action.u.addba_req.action_code == WLAN_ACTION_ADDBA_REQ)) {
-
+ mgmt->u.action.category == WLAN_CATEGORY_BACK &&
+ mgmt->u.action.u.addba_req.action_code == WLAN_ACTION_ADDBA_REQ)) {
u16 capab = ENDIAN_SWAP16(mgmt->u.action.u.addba_req.capab);
-
tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2;
index = mwl_tx_tid_queue_mapping(tid);
}
@@ -253,7 +247,6 @@ void mwl_tx_xmit(struct ieee80211_hw *hw,
if (sta && sta->ht_cap.ht_supported && !eapol_frame &&
ieee80211_is_data_qos(wh->frame_control)) {
-
tid = qos & 0xf;
mwl_tx_count_packet(sta, tid);
@@ -261,14 +254,11 @@ void mwl_tx_xmit(struct ieee80211_hw *hw,
stream = mwl_fwcmd_lookup_stream(hw, sta->addr, tid);
if (stream != NULL) {
-
if (stream->state == AMPDU_STREAM_ACTIVE) {
-
WARN_ON(!(qos & MWL_QOS_ACK_POLICY_BLOCKACK));
txpriority = (SYSADPT_TX_WMM_QUEUES + stream->idx) %
SYSADPT_TOTAL_HW_QUEUES;
-
} else if (stream->state == AMPDU_STREAM_NEW) {
/* We get here if the driver sends us packets
* after we've initiated a stream, but before
@@ -297,7 +287,6 @@ void mwl_tx_xmit(struct ieee80211_hw *hw,
dev_kfree_skb_any(skb);
return;
}
-
} else {
/* Defer calling mwl8k_start_stream so that the current
* skb can go out before the ADDBA request. This
@@ -305,7 +294,6 @@ void mwl_tx_xmit(struct ieee80211_hw *hw,
* as described above.
*/
if (mwl_fwcmd_ampdu_allowed(sta, tid)) {
-
stream = mwl_fwcmd_add_stream(hw, sta, tid);
if (stream != NULL)
@@ -314,9 +302,7 @@ void mwl_tx_xmit(struct ieee80211_hw *hw,
}
SPIN_UNLOCK(&priv->locks.stream_lock);
-
} else {
-
qos &= ~MWL_QOS_ACK_POLICY_MASK;
qos |= MWL_QOS_ACK_POLICY_NORMAL;
}
@@ -330,12 +316,9 @@ void mwl_tx_xmit(struct ieee80211_hw *hw,
tx_ctrl->ccmp = ccmp;
if (skb_queue_len(&priv->txq[index]) > priv->txq_limit) {
-
dev_kfree_skb_any(skb);
WLDBG_INFO(DBG_LEVEL_3, "queue len > limit");
-
} else {
-
skb_queue_tail(&priv->txq[index], skb);
}
@@ -344,7 +327,6 @@ void mwl_tx_xmit(struct ieee80211_hw *hw,
/* Initiate the ampdu session here
*/
if (start_ba_session) {
-
SPIN_LOCK(&priv->locks.stream_lock);
if (mwl_fwcmd_start_stream(hw, stream))
mwl_fwcmd_remove_stream(hw, stream);
@@ -371,13 +353,11 @@ void mwl_tx_done(unsigned long data)
SPIN_LOCK_IRQSAVE(&priv->locks.xmit_lock, flags);
for (num = 0; num < SYSADPT_NUM_OF_DESC_DATA; num++) {
-
while (STALE_TXD(num)
&& (STALE_TXD(num)->status & ENDIAN_SWAP32(EAGLE_TXD_STATUS_OK))
&& (!(STALE_TXD(num)->status & ENDIAN_SWAP32(EAGLE_TXD_STATUS_FW_OWNED)))) {
-
pci_unmap_single(priv->pdev,
- ENDIAN_SWAP32(STALE_TXD(num)->pkt_ptr),
+ ENDIAN_SWAP32(STALE_TXD(num)->pkt_ptr),
STALE_TXD(num)->psk_buff->len,
PCI_DMA_TODEVICE);
done_skb = STALE_TXD(num)->psk_buff;
@@ -395,8 +375,11 @@ void mwl_tx_done(unsigned long data)
tr = (struct mwl_dma_data *)done_skb->data;
- if (ieee80211_is_assoc_resp(tr->wh.frame_control)) {
-
+ if (ieee80211_is_assoc_resp(tr->wh.frame_control) ||
+ ieee80211_is_reassoc_resp(tr->wh.frame_control) ||
+ ieee80211_is_auth(tr->wh.frame_control) ||
+ ieee80211_is_nullfunc(tr->wh.frame_control) ||
+ ieee80211_is_qos_nullfunc(tr->wh.frame_control)) {
/* Remove H/W dma header
*/
hdrlen = ieee80211_hdrlen(tr->wh.frame_control);
@@ -416,9 +399,7 @@ void mwl_tx_done(unsigned long data)
info->flags |= IEEE80211_TX_STAT_ACK;
ieee80211_tx_status(hw, done_skb);
-
} else {
-
/* Due to firmware does not return real tx status,
* we should not ACK data frame, otherwise, hostap will
* think station is always existed.
@@ -432,10 +413,9 @@ void mwl_tx_done(unsigned long data)
}
}
- SPIN_UNLOCK_IRQRESTORE(&priv->locks.xmit_lock, flags);
+ SPIN_UNLOCK_IRQRESTORE(&priv->locks.xmit_lock, flags);
if (priv->irq != -1) {
-
u32 status;
status = readl(priv->iobase1 + MACREG_REG_A2H_INTERRUPT_STATUS_MASK);
@@ -462,19 +442,17 @@ static int mwl_tx_ring_alloc(struct mwl_priv *priv)
BUG_ON(!priv);
- mem = (u8 *)pci_alloc_consistent(priv->pdev,
+ mem = (u8 *)dma_alloc_coherent(&priv->pdev->dev,
MAX_NUM_TX_RING_BYTES * SYSADPT_NUM_OF_DESC_DATA,
- &priv->desc_data[0].pphys_tx_ring);
+ &priv->desc_data[0].pphys_tx_ring, GFP_KERNEL);
if (mem == NULL) {
-
WLDBG_ERROR(DBG_LEVEL_3, "can not alloc mem");
WLDBG_EXIT_INFO(DBG_LEVEL_3, "no memory");
return -ENOMEM;
}
for (num = 0; num < SYSADPT_NUM_OF_DESC_DATA; num++) {
-
WLDBG_INFO(DBG_LEVEL_3, "allocating %i (0x%x) bytes",
MAX_NUM_TX_RING_BYTES, MAX_NUM_TX_RING_BYTES);
@@ -505,16 +483,13 @@ static int mwl_tx_ring_init(struct mwl_priv *priv)
BUG_ON(!priv);
for (num = 0; num < SYSADPT_NUM_OF_DESC_DATA; num++) {
-
skb_queue_head_init(&priv->txq[num]);
priv->fw_desc_cnt[num] = 0;
if (priv->desc_data[num].ptx_ring != NULL) {
-
WLDBG_INFO(DBG_LEVEL_3, "initializing %i descriptors", SYSADPT_MAX_NUM_TX_DESC);
for (curr_desc = 0; curr_desc < SYSADPT_MAX_NUM_TX_DESC; curr_desc++) {
-
CURR_TXD(num).status = ENDIAN_SWAP32(EAGLE_TXD_STATUS_IDLE);
CURR_TXD(num).pnext = &NEXT_TXD(num);
CURR_TXD(num).pphys_next =
@@ -535,8 +510,7 @@ static int mwl_tx_ring_init(struct mwl_priv *priv)
"last txdesc vnext: 0x%p pnext: 0x%x pstale 0x%x vfirst 0x%x",
LAST_TXD(num).pnext, ENDIAN_SWAP32(LAST_TXD(num).pphys_next),
priv->desc_data[num].pstale_tx_desc, priv->desc_data[num].pnext_tx_desc);
- } else
- {
+ } else {
WLDBG_ERROR(DBG_LEVEL_3, "no valid TX mem");
WLDBG_EXIT_INFO(DBG_LEVEL_3, "no valid memory");
return -ENOMEM;
@@ -559,15 +533,11 @@ static void mwl_tx_ring_cleanup(struct mwl_priv *priv)
BUG_ON(!priv);
for (num = 0; num < SYSADPT_NUM_OF_DESC_DATA; num++) {
-
skb_queue_purge(&priv->txq[num]);
priv->fw_desc_cnt[num] = 0;
if (priv->desc_data[num].ptx_ring != NULL) {
-
for (curr_desc = 0; curr_desc < SYSADPT_MAX_NUM_TX_DESC; curr_desc++) {
-
if (CURR_TXD(num).psk_buff != NULL) {
-
WLDBG_INFO(DBG_LEVEL_3,
"unmapped and free'd txdesc %i vaddr: 0x%p paddr: 0x%x",
curr_desc, CURR_TXD(num).psk_buff->data,
@@ -599,15 +569,13 @@ static void mwl_tx_ring_free(struct mwl_priv *priv)
BUG_ON(!priv);
if (priv->desc_data[0].ptx_ring != NULL) {
-
- pci_free_consistent(priv->pdev,
- MAX_NUM_TX_RING_BYTES * SYSADPT_NUM_OF_DESC_DATA,
+ dma_free_coherent(&priv->pdev->dev,
+ MAX_NUM_TX_RING_BYTES * SYSADPT_NUM_OF_DESC_DATA,
priv->desc_data[0].ptx_ring,
priv->desc_data[0].pphys_tx_ring);
}
for (num = 0; num < SYSADPT_NUM_OF_DESC_DATA; num++) {
-
if (priv->desc_data[num].ptx_ring != NULL)
priv->desc_data[num].ptx_ring = NULL;
priv->desc_data[num].pstale_tx_desc = NULL;
@@ -689,20 +657,16 @@ static inline void mwl_tx_encapsulate_frame(struct mwl_priv *priv,
data_pad = 0;
if (key_conf != NULL) {
-
head_pad = key_conf->iv_len;
switch (key_conf->cipher) {
-
case WLAN_CIPHER_SUITE_WEP40:
case WLAN_CIPHER_SUITE_WEP104:
data_pad = 4;
break;
-
case WLAN_CIPHER_SUITE_TKIP:
data_pad = 12;
break;
-
case WLAN_CIPHER_SUITE_CCMP:
data_pad = 8;
*ccmp = true;
@@ -770,10 +734,8 @@ static inline void mwl_tx_count_packet(struct ieee80211_sta *sta, u8 tid)
* an ampdu stream to be started.
*/
if (jiffies - tx_stats->start_time > HZ) {
-
tx_stats->pkts = 0;
tx_stats->start_time = 0;
-
} else
tx_stats->pkts++;
}
@@ -796,9 +758,7 @@ static inline void mwl_tx_skbs(struct ieee80211_hw *hw)
SPIN_LOCK_IRQSAVE(&priv->locks.xmit_lock, flags);
while (num--) {
-
while (skb_queue_len(&priv->txq[num]) > 0) {
-
if (priv->desc_data[num].pnext_tx_desc == NULL)
break;
@@ -808,7 +768,6 @@ static inline void mwl_tx_skbs(struct ieee80211_hw *hw)
* when fwDescCnt==256 and pStaleTxDesc->Status==0.
*/
if (priv->desc_data[num].pnext_tx_desc->status != EAGLE_TXD_STATUS_IDLE) {
-
/* Interrupt F/W anyway
*/
if (priv->desc_data[num].pnext_tx_desc->status & ENDIAN_SWAP32(EAGLE_TXD_STATUS_FW_OWNED))
@@ -816,7 +775,6 @@ static inline void mwl_tx_skbs(struct ieee80211_hw *hw)
priv->iobase1 + MACREG_REG_H2A_INTERRUPT_EVENTS);
break;
-
}
tx_skb = skb_dequeue(&priv->txq[num]);
@@ -830,7 +788,7 @@ static inline void mwl_tx_skbs(struct ieee80211_hw *hw)
priv->desc_data[num].pnext_tx_desc->qos_ctrl = tx_ctrl->qos_ctrl;
priv->desc_data[num].pnext_tx_desc->psk_buff = tx_skb;
priv->desc_data[num].pnext_tx_desc->pkt_len = ENDIAN_SWAP16(tx_skb->len);
- priv->desc_data[num].pnext_tx_desc->ack_wcb_addr = 0;
+ priv->desc_data[num].pnext_tx_desc->packet_info = 0;
priv->desc_data[num].pnext_tx_desc->data_rate = 0;
priv->desc_data[num].pnext_tx_desc->sta_info = tx_ctrl->sta_info;
priv->desc_data[num].pnext_tx_desc->type = tx_ctrl->type;
@@ -853,39 +811,3 @@ static inline void mwl_tx_skbs(struct ieee80211_hw *hw)
WLDBG_EXIT(DBG_LEVEL_3);
}
-
-#if 0
-static void mwl_tx_descriptor_dump(struct mwl_priv *priv)
-{
- int curr_desc;
- int num;
- char *p1 = NULL;
- char *p2 = NULL;
- char str1[12] = " <- CURR_TXD";
- char str2[14] = " <- NEXT_TXD";
- char blank[2] = " ";
-
- WLDBG_ENTER(DBG_LEVEL_3);
-
- BUG_ON(!priv);
-
- for (num = 0; num < SYSADPT_NUM_OF_DESC_DATA; num++) {
-
- if (priv->desc_data[num].ptx_ring != NULL) {
-
- for (curr_desc = 0; curr_desc < SYSADPT_MAX_NUM_TX_DESC; curr_desc++) {
-
- p1 = blank;
- p2 = blank;
- if ((u32)&CURR_TXD(num) == (u32)priv->desc_data[num].pstale_tx_desc)
- p1 = str1;
- if ((u32)&CURR_TXD(num) == (u32)priv->desc_data[num].pnext_tx_desc)
- p2 = str2;
- WLDBG_PRINT("TxDescriptor(%d.%d) Status=0x%x %s %s", num, curr_desc, CURR_TXD(num).status, p1, p2);
- }
- }
- }
-
- WLDBG_EXIT(DBG_LEVEL_3);
-}
-#endif
diff --git a/mwl_tx.h b/mwl_tx.h
index 5cd3a97..6b2d4bb 100644
--- a/mwl_tx.h
+++ b/mwl_tx.h
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2006-2014 Marvell International Ltd.
+* Copyright (c) 2006-2015 Marvell International Ltd.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
diff --git a/test/README b/test/README
index a59a2c4..a299f47 100644
--- a/test/README
+++ b/test/README
@@ -1,16 +1,16 @@
1. Files for test:
- a. 88W8864.bin: F/W binary. Please put this file under directory '/lib/firmware'.
- b. Mamba_FCC_v1.2_5G4TX.ini: power table for Mamba.
- c. mwlwifi.ko: 88W8864 mac80211 driver kernel module.
- d. hostapd.conf: configuration file used to configure hostapd.
- e. openwrt-mvebu-jffs2-128k.img: OpenWRT download image (built with kernel cfg80211/mac80211, iw and hostapd).
+ a. 88W8864.bin: F/W binary. Please put this file under directory '/lib/firmware/mwlwifi'.
+ b. mwlwifi.ko: 88W8864 mac80211 driver kernel module.
+ c. hostapd.conf: configuration file used to configure hostapd.
+ d. wpa_supplicant.conf: configuration file used to configure wpa_supplicant.
+ e. openwrt-mvebu-armada-xp-mamba-squashfs-factory.img: OpenWRT download image (built with kernel cfg80211/mac80211, iw, hostapd and wpa_supplicant).
2. Bring up driver:
a. iw reg set US
--> set regulatory domain (Note: cfg80211 will disable DFS channels).
- b. insmod mwlwifi.ko fw_name=88W8864.bin pwr_tbl=Mamba_FCC_v1.2_5G4TX.ini
+ b. insmod mwlwifi.ko
--> After module is inserted, physical interfaces phy0 and phy1 and network device wlan0 and wlan1
will be created. You can issue "iw dev" to check them.
c. hostapd -B ./hostapd.conf
@@ -46,7 +46,7 @@
(5490 - 5590 @ 80), (30, 0)
(5650 - 5710 @ 40), (30, 0)
(5735 - 5835 @ 80), (30, 0)
- It allows you set use two ranges to do 80 MHz operation (100 ~ 116) and (149 ~ 161).
+ It allows you to use two ranges to do 80 MHz operation (100 ~ 116) and (149 ~ 161).
b. After regulatory is set and make sure the channel range you want to use is allowable by the
setting regulatory, you can modify hostapd.conf to run 80 Mhz as:
@@ -76,3 +76,78 @@
ht_capab=[LDPC][HT40-][SHORT-GI-20][SHORT-GI-40]
vht_oper_centr_freq_seg0_idx=106
+5. Station mode:
+
+ a. Use iw utlity to set correct regulatory domain.
+
+ b. Make sure dirver is loaded.
+
+ c. wpa_supplicant -B -D nl80211 -i wlan1 -c wpa_supplicant.conf
+ --> There are few sample configuration files under this directory. Please use them to do test.
+
+ d. There are two ways to change configuration for wpa_supplicant:
+
+ * Kill and rerun
+ killall wpa_supplicant
+ <Modify configuration file for new setting>
+ wpa_supplicant -B -D nl80211 -i wlan1 -c wpa_supplicant.conf
+
+ * Reload configuration file
+ <Modify configuration file for new setting>
+ kill -1 <PID of wpa_supplicant>
+
+6. Debug mode:
+
+ a. hostapd:
+
+ hostapd -d[dd] ./hostapd.conf
+
+ b. wpa_supplicant:
+
+ wpa_supplicant -ddK -D nl80211 -i wlan1 -c wpa_supplicant.conf
+
+7. Add/Delete interface via iw:
+
+ iw dev <devname> del
+ iw dev <devname> interface add <name> type <type>
+
+ You can omit the 'phy' or 'dev' if the identification is unique,
+ e.g. "iw wlan0 info" or "iw phy0 info". (Don't when scripting.)
+
+ Example:
+ root@OpenWrt:/test# iw dev
+ phy#1
+ Interface wlan1
+ ifindex 6
+ wdev 0x100000001
+ addr 00:25:9c:13:01:9a
+ type managed
+ phy#0
+ Interface wlan0
+ ifindex 8
+ wdev 0x3
+ addr 00:25:9c:13:01:99
+ type AP
+ root@OpenWrt:/test# iw wlan0 del
+ root@OpenWrt:/test# iw dev
+ phy#1
+ Interface wlan1
+ ifindex 6
+ wdev 0x100000001
+ addr 00:25:9c:13:01:9a
+ type managed
+ root@OpenWrt:/test# iw phy0 interface add wlan0 type managed
+ root@OpenWrt:/test# iw dev
+ phy#1
+ Interface wlan1
+ ifindex 6
+ wdev 0x100000001
+ addr 00:25:9c:13:01:9a
+ type managed
+ phy#0
+ Interface wlan0
+ ifindex 9
+ wdev 0x4
+ addr 00:25:9c:13:01:99
+ type managed
+ root@OpenWrt:/test# \ No newline at end of file
diff --git a/test/setup.sh b/test/setup.sh
index 142ec83..30fd0b3 100644
--- a/test/setup.sh
+++ b/test/setup.sh
@@ -1,4 +1,4 @@
iw reg set US
-insmod mwlwifi.ko fw_name=88W8864.bin pwr_tbl=Mamba_FCC_v1.2_5G4TX.ini
+insmod mwlwifi.ko
hostapd -B ./hostapd.conf
brctl addif br-lan wlan1
diff --git a/test/setup_multi_bssid.sh b/test/setup_multi_bssid.sh
index 3e76607..8ca3d61 100644
--- a/test/setup_multi_bssid.sh
+++ b/test/setup_multi_bssid.sh
@@ -1,5 +1,5 @@
iw reg set US
-insmod mwlwifi.ko fw_name=88W8864.bin pwr_tbl=Mamba_FCC_v1.2_5G4TX.ini
+insmod mwlwifi.ko
hostapd -B ./hostapd.conf
brctl addif br-lan wlan1
brctl addif br-lan wlan1_0
diff --git a/test/wpa_supplicant.conf.open b/test/wpa_supplicant.conf.open
new file mode 100755
index 0000000..d7677b9
--- /dev/null
+++ b/test/wpa_supplicant.conf.open
@@ -0,0 +1,8 @@
+ctrl_interface=/var/run/wpa_supplicant
+
+network={
+
+ssid="mwlwifi_ap_test"
+key_mgmt=NONE
+
+}
diff --git a/test/wpa_supplicant.conf.psk b/test/wpa_supplicant.conf.psk
new file mode 100755
index 0000000..ce154a6
--- /dev/null
+++ b/test/wpa_supplicant.conf.psk
@@ -0,0 +1,9 @@
+ctrl_interface=/var/run/wpa_supplicant
+
+network={
+
+ssid="mwlwifi_ap_test"
+key_mgmt=WPA-PSK
+psk="12345678"
+
+}