summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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"
+
+}