aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/ABI/testing/sysfs-bus-bcma31
-rw-r--r--MAINTAINERS7
-rw-r--r--drivers/Kconfig2
-rw-r--r--drivers/Makefile1
-rw-r--r--drivers/bcma/Kconfig33
-rw-r--r--drivers/bcma/Makefile7
-rw-r--r--drivers/bcma/README19
-rw-r--r--drivers/bcma/TODO3
-rw-r--r--drivers/bcma/bcma_private.h28
-rw-r--r--drivers/bcma/core.c51
-rw-r--r--drivers/bcma/driver_chipcommon.c89
-rw-r--r--drivers/bcma/driver_chipcommon_pmu.c134
-rw-r--r--drivers/bcma/driver_pci.c163
-rw-r--r--drivers/bcma/host_pci.c196
-rw-r--r--drivers/bcma/main.c247
-rw-r--r--drivers/bcma/scan.c360
-rw-r--r--drivers/bcma/scan.h56
-rw-r--r--drivers/bluetooth/ath3k.c1
-rw-r--r--drivers/bluetooth/btusb.c1
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_mac.c10
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_phy.c44
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_eeprom.c78
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_mac.c11
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.c46
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.h22
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h3
-rw-r--r--drivers/net/wireless/ath/ath9k/beacon.c15
-rw-r--r--drivers/net/wireless/ath/ath9k/calib.c21
-rw-r--r--drivers/net/wireless/ath/ath9k/calib.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/hw-ops.h16
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c16
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h15
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.c9
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c47
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c215
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c11
-rw-r--r--drivers/net/wireless/ath/carl9170/main.c2
-rw-r--r--drivers/net/wireless/ath/carl9170/tx.c9
-rw-r--r--drivers/net/wireless/b43/main.c69
-rw-r--r--drivers/net/wireless/b43/main.h1
-rw-r--r--drivers/net/wireless/b43/phy_n.c13
-rw-r--r--drivers/net/wireless/b43legacy/main.c52
-rw-r--r--drivers/net/wireless/iwlegacy/iwl-4965-rs.c2
-rw-r--r--drivers/net/wireless/iwlwifi/Kconfig10
-rw-r--r--drivers/net/wireless/iwlwifi/Makefile1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-1000.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-2000.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c7
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-tx.c105
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-ucode.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c143
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.h22
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h34
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-led.c20
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sv-open.c469
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-testmode.h151
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c22
-rw-r--r--drivers/net/wireless/iwmc3200wifi/rx.c3
-rw-r--r--drivers/net/wireless/libertas/cfg.c16
-rw-r--r--drivers/net/wireless/libertas/cmd.c40
-rw-r--r--drivers/net/wireless/libertas/cmdresp.c27
-rw-r--r--drivers/net/wireless/libertas/debugfs.c5
-rw-r--r--drivers/net/wireless/libertas/defs.h7
-rw-r--r--drivers/net/wireless/libertas/if_cs.c57
-rw-r--r--drivers/net/wireless/libertas/if_sdio.c37
-rw-r--r--drivers/net/wireless/libertas/if_spi.c83
-rw-r--r--drivers/net/wireless/libertas/if_usb.c44
-rw-r--r--drivers/net/wireless/libertas/main.c72
-rw-r--r--drivers/net/wireless/libertas/mesh.c8
-rw-r--r--drivers/net/wireless/libertas/rx.c7
-rw-r--r--drivers/net/wireless/mwifiex/11n.c7
-rw-r--r--drivers/net/wireless/mwifiex/11n_aggr.c136
-rw-r--r--drivers/net/wireless/mwifiex/11n_rxreorder.c15
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.c48
-rw-r--r--drivers/net/wireless/mwifiex/cmdevt.c51
-rw-r--r--drivers/net/wireless/mwifiex/debugfs.c10
-rw-r--r--drivers/net/wireless/mwifiex/fw.h21
-rw-r--r--drivers/net/wireless/mwifiex/init.c59
-rw-r--r--drivers/net/wireless/mwifiex/ioctl.h81
-rw-r--r--drivers/net/wireless/mwifiex/join.c9
-rw-r--r--drivers/net/wireless/mwifiex/main.c27
-rw-r--r--drivers/net/wireless/mwifiex/main.h8
-rw-r--r--drivers/net/wireless/mwifiex/scan.c30
-rw-r--r--drivers/net/wireless/mwifiex/sdio.c35
-rw-r--r--drivers/net/wireless/mwifiex/sta_cmd.c8
-rw-r--r--drivers/net/wireless/mwifiex/sta_cmdresp.c28
-rw-r--r--drivers/net/wireless/mwifiex/sta_ioctl.c80
-rw-r--r--drivers/net/wireless/mwifiex/sta_rx.c26
-rw-r--r--drivers/net/wireless/mwifiex/sta_tx.c4
-rw-r--r--drivers/net/wireless/mwifiex/txrx.c10
-rw-r--r--drivers/net/wireless/mwifiex/util.c29
-rw-r--r--drivers/net/wireless/mwifiex/wmm.c2
-rw-r--r--drivers/net/wireless/mwl8k.c18
-rw-r--r--drivers/net/wireless/p54/p54pci.c3
-rw-r--r--drivers/net/wireless/rt2x00/Kconfig11
-rw-r--r--drivers/net/wireless/rt2x00/rt2800.h2
-rw-r--r--drivers/net/wireless/rt2x00/rt2800lib.c5
-rw-r--r--drivers/net/wireless/rt2x00/rt2800usb.c8
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.c6
-rw-r--r--drivers/net/wireless/rtlwifi/Kconfig15
-rw-r--r--drivers/net/wireless/rtlwifi/Makefile1
-rw-r--r--drivers/net/wireless/rtlwifi/efuse.c35
-rw-r--r--drivers/net/wireless/rtlwifi/pci.c1
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/trx.c4
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/Makefile15
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/def.h598
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/dm.c733
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/dm.h164
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/fw.c654
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/fw.h375
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/hw.c2512
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/hw.h79
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/led.c149
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/led.h37
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/phy.c1740
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/phy.h101
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/reg.h1188
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/rf.c546
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/rf.h43
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/sw.c423
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/sw.h36
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/table.c634
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/table.h49
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/trx.c976
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/trx.h45
-rw-r--r--drivers/net/wireless/wl12xx/acx.c190
-rw-r--r--drivers/net/wireless/wl12xx/acx.h103
-rw-r--r--drivers/net/wireless/wl12xx/boot.c6
-rw-r--r--drivers/net/wireless/wl12xx/cmd.c18
-rw-r--r--drivers/net/wireless/wl12xx/conf.h111
-rw-r--r--drivers/net/wireless/wl12xx/debugfs.c240
-rw-r--r--drivers/net/wireless/wl12xx/event.c70
-rw-r--r--drivers/net/wireless/wl12xx/event.h12
-rw-r--r--drivers/net/wireless/wl12xx/init.c110
-rw-r--r--drivers/net/wireless/wl12xx/init.h2
-rw-r--r--drivers/net/wireless/wl12xx/main.c492
-rw-r--r--drivers/net/wireless/wl12xx/ps.c30
-rw-r--r--drivers/net/wireless/wl12xx/ps.h2
-rw-r--r--drivers/net/wireless/wl12xx/rx.c36
-rw-r--r--drivers/net/wireless/wl12xx/scan.c243
-rw-r--r--drivers/net/wireless/wl12xx/scan.h114
-rw-r--r--drivers/net/wireless/wl12xx/sdio.c64
-rw-r--r--drivers/net/wireless/wl12xx/tx.c13
-rw-r--r--drivers/net/wireless/wl12xx/tx.h2
-rw-r--r--drivers/net/wireless/wl12xx/wl12xx.h14
-rw-r--r--drivers/ssb/driver_pcicore.c26
-rw-r--r--drivers/ssb/main.c31
-rw-r--r--drivers/ssb/scan.c5
-rw-r--r--include/linux/bcma/bcma.h224
-rw-r--r--include/linux/bcma/bcma_driver_chipcommon.h302
-rw-r--r--include/linux/bcma/bcma_driver_pci.h89
-rw-r--r--include/linux/bcma/bcma_regs.h34
-rw-r--r--include/linux/ieee80211.h11
-rw-r--r--include/linux/mod_devicetable.h17
-rw-r--r--include/linux/nl80211.h302
-rw-r--r--include/linux/ssb/ssb.h1
-rw-r--r--include/net/bluetooth/hci_core.h1
-rw-r--r--include/net/bluetooth/l2cap.h9
-rw-r--r--include/net/cfg80211.h237
-rw-r--r--include/net/mac80211.h66
-rw-r--r--net/bluetooth/hci_conn.c17
-rw-r--r--net/bluetooth/hci_event.c5
-rw-r--r--net/bluetooth/l2cap_core.c193
-rw-r--r--net/bluetooth/l2cap_sock.c72
-rw-r--r--net/bluetooth/mgmt.c3
-rw-r--r--net/bluetooth/rfcomm/core.c2
-rw-r--r--net/mac80211/agg-rx.c3
-rw-r--r--net/mac80211/agg-tx.c59
-rw-r--r--net/mac80211/cfg.c135
-rw-r--r--net/mac80211/debugfs.c2
-rw-r--r--net/mac80211/debugfs_key.c21
-rw-r--r--net/mac80211/driver-ops.h56
-rw-r--r--net/mac80211/driver-trace.h228
-rw-r--r--net/mac80211/ht.c27
-rw-r--r--net/mac80211/ibss.c11
-rw-r--r--net/mac80211/ieee80211_i.h41
-rw-r--r--net/mac80211/iface.c3
-rw-r--r--net/mac80211/key.c30
-rw-r--r--net/mac80211/key.h4
-rw-r--r--net/mac80211/main.c37
-rw-r--r--net/mac80211/mesh.c47
-rw-r--r--net/mac80211/mesh.h6
-rw-r--r--net/mac80211/mesh_hwmp.c38
-rw-r--r--net/mac80211/mesh_pathtbl.c123
-rw-r--r--net/mac80211/mesh_plink.c83
-rw-r--r--net/mac80211/mlme.c22
-rw-r--r--net/mac80211/pm.c13
-rw-r--r--net/mac80211/rc80211_minstrel.c4
-rw-r--r--net/mac80211/rc80211_minstrel_ht.c27
-rw-r--r--net/mac80211/rx.c17
-rw-r--r--net/mac80211/scan.c122
-rw-r--r--net/mac80211/sta_info.c19
-rw-r--r--net/mac80211/sta_info.h50
-rw-r--r--net/mac80211/tx.c10
-rw-r--r--net/mac80211/util.c19
-rw-r--r--net/rfkill/core.c2
-rw-r--r--net/wireless/core.c89
-rw-r--r--net/wireless/core.h33
-rw-r--r--net/wireless/lib80211_crypt_wep.c3
-rw-r--r--net/wireless/mlme.c10
-rw-r--r--net/wireless/nl80211.c670
-rw-r--r--net/wireless/nl80211.h4
-rw-r--r--net/wireless/reg.c2
-rw-r--r--net/wireless/scan.c77
-rw-r--r--net/wireless/sysfs.c2
-rw-r--r--net/wireless/util.c126
-rw-r--r--scripts/mod/file2alias.c22
213 files changed, 19165 insertions, 2154 deletions
diff --git a/Documentation/ABI/testing/sysfs-bus-bcma b/Documentation/ABI/testing/sysfs-bus-bcma
new file mode 100644
index 000000000000..06b62badddd1
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-bus-bcma
@@ -0,0 +1,31 @@
1What: /sys/bus/bcma/devices/.../manuf
2Date: May 2011
3KernelVersion: 2.6.40
4Contact: Rafał Miłecki <zajec5@gmail.com>
5Description:
6 Each BCMA core has it's manufacturer id. See
7 include/linux/bcma/bcma.h for possible values.
8
9What: /sys/bus/bcma/devices/.../id
10Date: May 2011
11KernelVersion: 2.6.40
12Contact: Rafał Miłecki <zajec5@gmail.com>
13Description:
14 There are a few types of BCMA cores, they can be identified by
15 id field.
16
17What: /sys/bus/bcma/devices/.../rev
18Date: May 2011
19KernelVersion: 2.6.40
20Contact: Rafał Miłecki <zajec5@gmail.com>
21Description:
22 BCMA cores of the same type can still slightly differ depending
23 on their revision. Use it for detailed programming.
24
25What: /sys/bus/bcma/devices/.../class
26Date: May 2011
27KernelVersion: 2.6.40
28Contact: Rafał Miłecki <zajec5@gmail.com>
29Description:
30 Each BCMA core is identified by few fields, including class it
31 belongs to. See include/linux/bcma/bcma.h for possible values.
diff --git a/MAINTAINERS b/MAINTAINERS
index e653a99ddc4c..e23cbd16f1bd 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5812,6 +5812,13 @@ S: Maintained
5812F: drivers/ssb/ 5812F: drivers/ssb/
5813F: include/linux/ssb/ 5813F: include/linux/ssb/
5814 5814
5815BROADCOM SPECIFIC AMBA DRIVER (BCMA)
5816M: Rafał Miłecki <zajec5@gmail.com>
5817L: linux-wireless@vger.kernel.org
5818S: Maintained
5819F: drivers/bcma/
5820F: include/linux/bcma/
5821
5815SONY VAIO CONTROL DEVICE DRIVER 5822SONY VAIO CONTROL DEVICE DRIVER
5816M: Mattia Dongili <malattia@linux.it> 5823M: Mattia Dongili <malattia@linux.it>
5817L: platform-driver-x86@vger.kernel.org 5824L: platform-driver-x86@vger.kernel.org
diff --git a/drivers/Kconfig b/drivers/Kconfig
index 177c7d156933..aca706751469 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -68,6 +68,8 @@ source "drivers/watchdog/Kconfig"
68 68
69source "drivers/ssb/Kconfig" 69source "drivers/ssb/Kconfig"
70 70
71source "drivers/bcma/Kconfig"
72
71source "drivers/mfd/Kconfig" 73source "drivers/mfd/Kconfig"
72 74
73source "drivers/regulator/Kconfig" 75source "drivers/regulator/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
index 3f135b6fb014..a29527f4ded6 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -110,6 +110,7 @@ obj-$(CONFIG_HID) += hid/
110obj-$(CONFIG_PPC_PS3) += ps3/ 110obj-$(CONFIG_PPC_PS3) += ps3/
111obj-$(CONFIG_OF) += of/ 111obj-$(CONFIG_OF) += of/
112obj-$(CONFIG_SSB) += ssb/ 112obj-$(CONFIG_SSB) += ssb/
113obj-$(CONFIG_BCMA) += bcma/
113obj-$(CONFIG_VHOST_NET) += vhost/ 114obj-$(CONFIG_VHOST_NET) += vhost/
114obj-$(CONFIG_VLYNQ) += vlynq/ 115obj-$(CONFIG_VLYNQ) += vlynq/
115obj-$(CONFIG_STAGING) += staging/ 116obj-$(CONFIG_STAGING) += staging/
diff --git a/drivers/bcma/Kconfig b/drivers/bcma/Kconfig
new file mode 100644
index 000000000000..353781b5b78b
--- /dev/null
+++ b/drivers/bcma/Kconfig
@@ -0,0 +1,33 @@
1config BCMA_POSSIBLE
2 bool
3 depends on HAS_IOMEM && HAS_DMA
4 default y
5
6menu "Broadcom specific AMBA"
7 depends on BCMA_POSSIBLE
8
9config BCMA
10 tristate "BCMA support"
11 depends on BCMA_POSSIBLE
12 help
13 Bus driver for Broadcom specific Advanced Microcontroller Bus
14 Architecture.
15
16config BCMA_HOST_PCI_POSSIBLE
17 bool
18 depends on BCMA && PCI = y
19 default y
20
21config BCMA_HOST_PCI
22 bool "Support for BCMA on PCI-host bus"
23 depends on BCMA_HOST_PCI_POSSIBLE
24
25config BCMA_DEBUG
26 bool "BCMA debugging"
27 depends on BCMA
28 help
29 This turns on additional debugging messages.
30
31 If unsure, say N
32
33endmenu
diff --git a/drivers/bcma/Makefile b/drivers/bcma/Makefile
new file mode 100644
index 000000000000..0d56245bcb79
--- /dev/null
+++ b/drivers/bcma/Makefile
@@ -0,0 +1,7 @@
1bcma-y += main.o scan.o core.o
2bcma-y += driver_chipcommon.o driver_chipcommon_pmu.o
3bcma-y += driver_pci.o
4bcma-$(CONFIG_BCMA_HOST_PCI) += host_pci.o
5obj-$(CONFIG_BCMA) += bcma.o
6
7ccflags-$(CONFIG_BCMA_DEBUG) := -DDEBUG
diff --git a/drivers/bcma/README b/drivers/bcma/README
new file mode 100644
index 000000000000..f7e7ce46c603
--- /dev/null
+++ b/drivers/bcma/README
@@ -0,0 +1,19 @@
1Broadcom introduced new bus as replacement for older SSB. It is based on AMBA,
2however from programming point of view there is nothing AMBA specific we use.
3
4Standard AMBA drivers are platform specific, have hardcoded addresses and use
5AMBA standard fields like CID and PID.
6
7In case of Broadcom's cards every device consists of:
81) Broadcom specific AMBA device. It is put on AMBA bus, but can not be treated
9 as standard AMBA device. Reading it's CID or PID can cause machine lockup.
102) AMBA standard devices called ports or wrappers. They have CIDs (AMBA_CID)
11 and PIDs (0x103BB369), but we do not use that info for anything. One of that
12 devices is used for managing Broadcom specific core.
13
14Addresses of AMBA devices are not hardcoded in driver and have to be read from
15EPROM.
16
17In this situation we decided to introduce separated bus. It can contain up to
1816 devices identified by Broadcom specific fields: manufacturer, id, revision
19and class.
diff --git a/drivers/bcma/TODO b/drivers/bcma/TODO
new file mode 100644
index 000000000000..da7aa99fe81c
--- /dev/null
+++ b/drivers/bcma/TODO
@@ -0,0 +1,3 @@
1- Interrupts
2- Defines for PCI core driver
3- Create kernel Documentation (use info from README)
diff --git a/drivers/bcma/bcma_private.h b/drivers/bcma/bcma_private.h
new file mode 100644
index 000000000000..2f72e9c585fd
--- /dev/null
+++ b/drivers/bcma/bcma_private.h
@@ -0,0 +1,28 @@
1#ifndef LINUX_BCMA_PRIVATE_H_
2#define LINUX_BCMA_PRIVATE_H_
3
4#ifndef pr_fmt
5#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
6#endif
7
8#include <linux/bcma/bcma.h>
9#include <linux/delay.h>
10
11#define BCMA_CORE_SIZE 0x1000
12
13struct bcma_bus;
14
15/* main.c */
16extern int bcma_bus_register(struct bcma_bus *bus);
17extern void bcma_bus_unregister(struct bcma_bus *bus);
18
19/* scan.c */
20int bcma_bus_scan(struct bcma_bus *bus);
21
22#ifdef CONFIG_BCMA_HOST_PCI
23/* host_pci.c */
24extern int __init bcma_host_pci_init(void);
25extern void __exit bcma_host_pci_exit(void);
26#endif /* CONFIG_BCMA_HOST_PCI */
27
28#endif
diff --git a/drivers/bcma/core.c b/drivers/bcma/core.c
new file mode 100644
index 000000000000..ced379f7b371
--- /dev/null
+++ b/drivers/bcma/core.c
@@ -0,0 +1,51 @@
1/*
2 * Broadcom specific AMBA
3 * Core ops
4 *
5 * Licensed under the GNU/GPL. See COPYING for details.
6 */
7
8#include "bcma_private.h"
9#include <linux/bcma/bcma.h>
10
11bool bcma_core_is_enabled(struct bcma_device *core)
12{
13 if ((bcma_aread32(core, BCMA_IOCTL) & (BCMA_IOCTL_CLK | BCMA_IOCTL_FGC))
14 != BCMA_IOCTL_CLK)
15 return false;
16 if (bcma_aread32(core, BCMA_RESET_CTL) & BCMA_RESET_CTL_RESET)
17 return false;
18 return true;
19}
20EXPORT_SYMBOL_GPL(bcma_core_is_enabled);
21
22static void bcma_core_disable(struct bcma_device *core, u32 flags)
23{
24 if (bcma_aread32(core, BCMA_RESET_CTL) & BCMA_RESET_CTL_RESET)
25 return;
26
27 bcma_awrite32(core, BCMA_IOCTL, flags);
28 bcma_aread32(core, BCMA_IOCTL);
29 udelay(10);
30
31 bcma_awrite32(core, BCMA_RESET_CTL, BCMA_RESET_CTL_RESET);
32 udelay(1);
33}
34
35int bcma_core_enable(struct bcma_device *core, u32 flags)
36{
37 bcma_core_disable(core, flags);
38
39 bcma_awrite32(core, BCMA_IOCTL, (BCMA_IOCTL_CLK | BCMA_IOCTL_FGC | flags));
40 bcma_aread32(core, BCMA_IOCTL);
41
42 bcma_awrite32(core, BCMA_RESET_CTL, 0);
43 udelay(1);
44
45 bcma_awrite32(core, BCMA_IOCTL, (BCMA_IOCTL_CLK | flags));
46 bcma_aread32(core, BCMA_IOCTL);
47 udelay(1);
48
49 return 0;
50}
51EXPORT_SYMBOL_GPL(bcma_core_enable);
diff --git a/drivers/bcma/driver_chipcommon.c b/drivers/bcma/driver_chipcommon.c
new file mode 100644
index 000000000000..606102256b44
--- /dev/null
+++ b/drivers/bcma/driver_chipcommon.c
@@ -0,0 +1,89 @@
1/*
2 * Broadcom specific AMBA
3 * ChipCommon core driver
4 *
5 * Copyright 2005, Broadcom Corporation
6 * Copyright 2006, 2007, Michael Buesch <mb@bu3sch.de>
7 *
8 * Licensed under the GNU/GPL. See COPYING for details.
9 */
10
11#include "bcma_private.h"
12#include <linux/bcma/bcma.h>
13
14static inline u32 bcma_cc_write32_masked(struct bcma_drv_cc *cc, u16 offset,
15 u32 mask, u32 value)
16{
17 value &= mask;
18 value |= bcma_cc_read32(cc, offset) & ~mask;
19 bcma_cc_write32(cc, offset, value);
20
21 return value;
22}
23
24void bcma_core_chipcommon_init(struct bcma_drv_cc *cc)
25{
26 if (cc->core->id.rev >= 11)
27 cc->status = bcma_cc_read32(cc, BCMA_CC_CHIPSTAT);
28 cc->capabilities = bcma_cc_read32(cc, BCMA_CC_CAP);
29 if (cc->core->id.rev >= 35)
30 cc->capabilities_ext = bcma_cc_read32(cc, BCMA_CC_CAP_EXT);
31
32 if (cc->core->id.rev >= 20) {
33 bcma_cc_write32(cc, BCMA_CC_GPIOPULLUP, 0);
34 bcma_cc_write32(cc, BCMA_CC_GPIOPULLDOWN, 0);
35 }
36
37 if (cc->capabilities & BCMA_CC_CAP_PMU)
38 bcma_pmu_init(cc);
39 if (cc->capabilities & BCMA_CC_CAP_PCTL)
40 pr_err("Power control not implemented!\n");
41}
42
43/* Set chip watchdog reset timer to fire in 'ticks' backplane cycles */
44void bcma_chipco_watchdog_timer_set(struct bcma_drv_cc *cc, u32 ticks)
45{
46 /* instant NMI */
47 bcma_cc_write32(cc, BCMA_CC_WATCHDOG, ticks);
48}
49
50void bcma_chipco_irq_mask(struct bcma_drv_cc *cc, u32 mask, u32 value)
51{
52 bcma_cc_write32_masked(cc, BCMA_CC_IRQMASK, mask, value);
53}
54
55u32 bcma_chipco_irq_status(struct bcma_drv_cc *cc, u32 mask)
56{
57 return bcma_cc_read32(cc, BCMA_CC_IRQSTAT) & mask;
58}
59
60u32 bcma_chipco_gpio_in(struct bcma_drv_cc *cc, u32 mask)
61{
62 return bcma_cc_read32(cc, BCMA_CC_GPIOIN) & mask;
63}
64
65u32 bcma_chipco_gpio_out(struct bcma_drv_cc *cc, u32 mask, u32 value)
66{
67 return bcma_cc_write32_masked(cc, BCMA_CC_GPIOOUT, mask, value);
68}
69
70u32 bcma_chipco_gpio_outen(struct bcma_drv_cc *cc, u32 mask, u32 value)
71{
72 return bcma_cc_write32_masked(cc, BCMA_CC_GPIOOUTEN, mask, value);
73}
74
75u32 bcma_chipco_gpio_control(struct bcma_drv_cc *cc, u32 mask, u32 value)
76{
77 return bcma_cc_write32_masked(cc, BCMA_CC_GPIOCTL, mask, value);
78}
79EXPORT_SYMBOL_GPL(bcma_chipco_gpio_control);
80
81u32 bcma_chipco_gpio_intmask(struct bcma_drv_cc *cc, u32 mask, u32 value)
82{
83 return bcma_cc_write32_masked(cc, BCMA_CC_GPIOIRQ, mask, value);
84}
85
86u32 bcma_chipco_gpio_polarity(struct bcma_drv_cc *cc, u32 mask, u32 value)
87{
88 return bcma_cc_write32_masked(cc, BCMA_CC_GPIOPOL, mask, value);
89}
diff --git a/drivers/bcma/driver_chipcommon_pmu.c b/drivers/bcma/driver_chipcommon_pmu.c
new file mode 100644
index 000000000000..f44177a644c7
--- /dev/null
+++ b/drivers/bcma/driver_chipcommon_pmu.c
@@ -0,0 +1,134 @@
1/*
2 * Broadcom specific AMBA
3 * ChipCommon Power Management Unit driver
4 *
5 * Copyright 2009, Michael Buesch <mb@bu3sch.de>
6 * Copyright 2007, Broadcom Corporation
7 *
8 * Licensed under the GNU/GPL. See COPYING for details.
9 */
10
11#include "bcma_private.h"
12#include <linux/bcma/bcma.h>
13
14static void bcma_chipco_chipctl_maskset(struct bcma_drv_cc *cc,
15 u32 offset, u32 mask, u32 set)
16{
17 u32 value;
18
19 bcma_cc_read32(cc, BCMA_CC_CHIPCTL_ADDR);
20 bcma_cc_write32(cc, BCMA_CC_CHIPCTL_ADDR, offset);
21 bcma_cc_read32(cc, BCMA_CC_CHIPCTL_ADDR);
22 value = bcma_cc_read32(cc, BCMA_CC_CHIPCTL_DATA);
23 value &= mask;
24 value |= set;
25 bcma_cc_write32(cc, BCMA_CC_CHIPCTL_DATA, value);
26 bcma_cc_read32(cc, BCMA_CC_CHIPCTL_DATA);
27}
28
29static void bcma_pmu_pll_init(struct bcma_drv_cc *cc)
30{
31 struct bcma_bus *bus = cc->core->bus;
32
33 switch (bus->chipinfo.id) {
34 case 0x4313:
35 case 0x4331:
36 case 43224:
37 case 43225:
38 break;
39 default:
40 pr_err("PLL init unknown for device 0x%04X\n",
41 bus->chipinfo.id);
42 }
43}
44
45static void bcma_pmu_resources_init(struct bcma_drv_cc *cc)
46{
47 struct bcma_bus *bus = cc->core->bus;
48 u32 min_msk = 0, max_msk = 0;
49
50 switch (bus->chipinfo.id) {
51 case 0x4313:
52 min_msk = 0x200D;
53 max_msk = 0xFFFF;
54 break;
55 case 43224:
56 break;
57 default:
58 pr_err("PMU resource config unknown for device 0x%04X\n",
59 bus->chipinfo.id);
60 }
61
62 /* Set the resource masks. */
63 if (min_msk)
64 bcma_cc_write32(cc, BCMA_CC_PMU_MINRES_MSK, min_msk);
65 if (max_msk)
66 bcma_cc_write32(cc, BCMA_CC_PMU_MAXRES_MSK, max_msk);
67}
68
69void bcma_pmu_swreg_init(struct bcma_drv_cc *cc)
70{
71 struct bcma_bus *bus = cc->core->bus;
72
73 switch (bus->chipinfo.id) {
74 case 0x4313:
75 case 0x4331:
76 case 43224:
77 break;
78 default:
79 pr_err("PMU switch/regulators init unknown for device "
80 "0x%04X\n", bus->chipinfo.id);
81 }
82}
83
84void bcma_pmu_workarounds(struct bcma_drv_cc *cc)
85{
86 struct bcma_bus *bus = cc->core->bus;
87
88 switch (bus->chipinfo.id) {
89 case 0x4313:
90 bcma_chipco_chipctl_maskset(cc, 0, ~0, 0x7);
91 break;
92 case 0x4331:
93 pr_err("Enabling Ext PA lines not implemented\n");
94 break;
95 case 43224:
96 if (bus->chipinfo.rev == 0) {
97 pr_err("Workarounds for 43224 rev 0 not fully "
98 "implemented\n");
99 bcma_chipco_chipctl_maskset(cc, 0, ~0, 0xF0);
100 } else {
101 bcma_chipco_chipctl_maskset(cc, 0, ~0, 0xF0);
102 }
103 break;
104 default:
105 pr_err("Workarounds unknown for device 0x%04X\n",
106 bus->chipinfo.id);
107 }
108}
109
110void bcma_pmu_init(struct bcma_drv_cc *cc)
111{
112 u32 pmucap;
113
114 pmucap = bcma_cc_read32(cc, BCMA_CC_PMU_CAP);
115 cc->pmu.rev = (pmucap & BCMA_CC_PMU_CAP_REVISION);
116
117 pr_debug("Found rev %u PMU (capabilities 0x%08X)\n", cc->pmu.rev,
118 pmucap);
119
120 if (cc->pmu.rev == 1)
121 bcma_cc_mask32(cc, BCMA_CC_PMU_CTL,
122 ~BCMA_CC_PMU_CTL_NOILPONW);
123 else
124 bcma_cc_set32(cc, BCMA_CC_PMU_CTL,
125 BCMA_CC_PMU_CTL_NOILPONW);
126
127 if (cc->core->id.id == 0x4329 && cc->core->id.rev == 2)
128 pr_err("Fix for 4329b0 bad LPOM state not implemented!\n");
129
130 bcma_pmu_pll_init(cc);
131 bcma_pmu_resources_init(cc);
132 bcma_pmu_swreg_init(cc);
133 bcma_pmu_workarounds(cc);
134}
diff --git a/drivers/bcma/driver_pci.c b/drivers/bcma/driver_pci.c
new file mode 100644
index 000000000000..e757e4e3c7e2
--- /dev/null
+++ b/drivers/bcma/driver_pci.c
@@ -0,0 +1,163 @@
1/*
2 * Broadcom specific AMBA
3 * PCI Core
4 *
5 * Copyright 2005, Broadcom Corporation
6 * Copyright 2006, 2007, Michael Buesch <mb@bu3sch.de>
7 *
8 * Licensed under the GNU/GPL. See COPYING for details.
9 */
10
11#include "bcma_private.h"
12#include <linux/bcma/bcma.h>
13
14/**************************************************
15 * R/W ops.
16 **************************************************/
17
18static u32 bcma_pcie_read(struct bcma_drv_pci *pc, u32 address)
19{
20 pcicore_write32(pc, 0x130, address);
21 pcicore_read32(pc, 0x130);
22 return pcicore_read32(pc, 0x134);
23}
24
25#if 0
26static void bcma_pcie_write(struct bcma_drv_pci *pc, u32 address, u32 data)
27{
28 pcicore_write32(pc, 0x130, address);
29 pcicore_read32(pc, 0x130);
30 pcicore_write32(pc, 0x134, data);
31}
32#endif
33
34static void bcma_pcie_mdio_set_phy(struct bcma_drv_pci *pc, u8 phy)
35{
36 const u16 mdio_control = 0x128;
37 const u16 mdio_data = 0x12C;
38 u32 v;
39 int i;
40
41 v = (1 << 30); /* Start of Transaction */
42 v |= (1 << 28); /* Write Transaction */
43 v |= (1 << 17); /* Turnaround */
44 v |= (0x1F << 18);
45 v |= (phy << 4);
46 pcicore_write32(pc, mdio_data, v);
47
48 udelay(10);
49 for (i = 0; i < 200; i++) {
50 v = pcicore_read32(pc, mdio_control);
51 if (v & 0x100 /* Trans complete */)
52 break;
53 msleep(1);
54 }
55}
56
57static u16 bcma_pcie_mdio_read(struct bcma_drv_pci *pc, u8 device, u8 address)
58{
59 const u16 mdio_control = 0x128;
60 const u16 mdio_data = 0x12C;
61 int max_retries = 10;
62 u16 ret = 0;
63 u32 v;
64 int i;
65
66 v = 0x80; /* Enable Preamble Sequence */
67 v |= 0x2; /* MDIO Clock Divisor */
68 pcicore_write32(pc, mdio_control, v);
69
70 if (pc->core->id.rev >= 10) {
71 max_retries = 200;
72 bcma_pcie_mdio_set_phy(pc, device);
73 }
74
75 v = (1 << 30); /* Start of Transaction */
76 v |= (1 << 29); /* Read Transaction */
77 v |= (1 << 17); /* Turnaround */
78 if (pc->core->id.rev < 10)
79 v |= (u32)device << 22;
80 v |= (u32)address << 18;
81 pcicore_write32(pc, mdio_data, v);
82 /* Wait for the device to complete the transaction */
83 udelay(10);
84 for (i = 0; i < max_retries; i++) {
85 v = pcicore_read32(pc, mdio_control);
86 if (v & 0x100 /* Trans complete */) {
87 udelay(10);
88 ret = pcicore_read32(pc, mdio_data);
89 break;
90 }
91 msleep(1);
92 }
93 pcicore_write32(pc, mdio_control, 0);
94 return ret;
95}
96
97static void bcma_pcie_mdio_write(struct bcma_drv_pci *pc, u8 device,
98 u8 address, u16 data)
99{
100 const u16 mdio_control = 0x128;
101 const u16 mdio_data = 0x12C;
102 int max_retries = 10;
103 u32 v;
104 int i;
105
106 v = 0x80; /* Enable Preamble Sequence */
107 v |= 0x2; /* MDIO Clock Divisor */
108 pcicore_write32(pc, mdio_control, v);
109
110 if (pc->core->id.rev >= 10) {
111 max_retries = 200;
112 bcma_pcie_mdio_set_phy(pc, device);
113 }
114
115 v = (1 << 30); /* Start of Transaction */
116 v |= (1 << 28); /* Write Transaction */
117 v |= (1 << 17); /* Turnaround */
118 if (pc->core->id.rev < 10)
119 v |= (u32)device << 22;
120 v |= (u32)address << 18;
121 v |= data;
122 pcicore_write32(pc, mdio_data, v);
123 /* Wait for the device to complete the transaction */
124 udelay(10);
125 for (i = 0; i < max_retries; i++) {
126 v = pcicore_read32(pc, mdio_control);
127 if (v & 0x100 /* Trans complete */)
128 break;
129 msleep(1);
130 }
131 pcicore_write32(pc, mdio_control, 0);
132}
133
134/**************************************************
135 * Workarounds.
136 **************************************************/
137
138static u8 bcma_pcicore_polarity_workaround(struct bcma_drv_pci *pc)
139{
140 return (bcma_pcie_read(pc, 0x204) & 0x10) ? 0xC0 : 0x80;
141}
142
143static void bcma_pcicore_serdes_workaround(struct bcma_drv_pci *pc)
144{
145 const u8 serdes_pll_device = 0x1D;
146 const u8 serdes_rx_device = 0x1F;
147 u16 tmp;
148
149 bcma_pcie_mdio_write(pc, serdes_rx_device, 1 /* Control */,
150 bcma_pcicore_polarity_workaround(pc));
151 tmp = bcma_pcie_mdio_read(pc, serdes_pll_device, 1 /* Control */);
152 if (tmp & 0x4000)
153 bcma_pcie_mdio_write(pc, serdes_pll_device, 1, tmp & ~0x4000);
154}
155
156/**************************************************
157 * Init.
158 **************************************************/
159
160void bcma_core_pci_init(struct bcma_drv_pci *pc)
161{
162 bcma_pcicore_serdes_workaround(pc);
163}
diff --git a/drivers/bcma/host_pci.c b/drivers/bcma/host_pci.c
new file mode 100644
index 000000000000..99dd36e8500b
--- /dev/null
+++ b/drivers/bcma/host_pci.c
@@ -0,0 +1,196 @@
1/*
2 * Broadcom specific AMBA
3 * PCI Host
4 *
5 * Licensed under the GNU/GPL. See COPYING for details.
6 */
7
8#include "bcma_private.h"
9#include <linux/bcma/bcma.h>
10#include <linux/pci.h>
11
12static void bcma_host_pci_switch_core(struct bcma_device *core)
13{
14 pci_write_config_dword(core->bus->host_pci, BCMA_PCI_BAR0_WIN,
15 core->addr);
16 pci_write_config_dword(core->bus->host_pci, BCMA_PCI_BAR0_WIN2,
17 core->wrap);
18 core->bus->mapped_core = core;
19 pr_debug("Switched to core: 0x%X\n", core->id.id);
20}
21
22static u8 bcma_host_pci_read8(struct bcma_device *core, u16 offset)
23{
24 if (core->bus->mapped_core != core)
25 bcma_host_pci_switch_core(core);
26 return ioread8(core->bus->mmio + offset);
27}
28
29static u16 bcma_host_pci_read16(struct bcma_device *core, u16 offset)
30{
31 if (core->bus->mapped_core != core)
32 bcma_host_pci_switch_core(core);
33 return ioread16(core->bus->mmio + offset);
34}
35
36static u32 bcma_host_pci_read32(struct bcma_device *core, u16 offset)
37{
38 if (core->bus->mapped_core != core)
39 bcma_host_pci_switch_core(core);
40 return ioread32(core->bus->mmio + offset);
41}
42
43static void bcma_host_pci_write8(struct bcma_device *core, u16 offset,
44 u8 value)
45{
46 if (core->bus->mapped_core != core)
47 bcma_host_pci_switch_core(core);
48 iowrite8(value, core->bus->mmio + offset);
49}
50
51static void bcma_host_pci_write16(struct bcma_device *core, u16 offset,
52 u16 value)
53{
54 if (core->bus->mapped_core != core)
55 bcma_host_pci_switch_core(core);
56 iowrite16(value, core->bus->mmio + offset);
57}
58
59static void bcma_host_pci_write32(struct bcma_device *core, u16 offset,
60 u32 value)
61{
62 if (core->bus->mapped_core != core)
63 bcma_host_pci_switch_core(core);
64 iowrite32(value, core->bus->mmio + offset);
65}
66
67static u32 bcma_host_pci_aread32(struct bcma_device *core, u16 offset)
68{
69 if (core->bus->mapped_core != core)
70 bcma_host_pci_switch_core(core);
71 return ioread32(core->bus->mmio + (1 * BCMA_CORE_SIZE) + offset);
72}
73
74static void bcma_host_pci_awrite32(struct bcma_device *core, u16 offset,
75 u32 value)
76{
77 if (core->bus->mapped_core != core)
78 bcma_host_pci_switch_core(core);
79 iowrite32(value, core->bus->mmio + (1 * BCMA_CORE_SIZE) + offset);
80}
81
82const struct bcma_host_ops bcma_host_pci_ops = {
83 .read8 = bcma_host_pci_read8,
84 .read16 = bcma_host_pci_read16,
85 .read32 = bcma_host_pci_read32,
86 .write8 = bcma_host_pci_write8,
87 .write16 = bcma_host_pci_write16,
88 .write32 = bcma_host_pci_write32,
89 .aread32 = bcma_host_pci_aread32,
90 .awrite32 = bcma_host_pci_awrite32,
91};
92
93static int bcma_host_pci_probe(struct pci_dev *dev,
94 const struct pci_device_id *id)
95{
96 struct bcma_bus *bus;
97 int err = -ENOMEM;
98 const char *name;
99 u32 val;
100
101 /* Alloc */
102 bus = kzalloc(sizeof(*bus), GFP_KERNEL);
103 if (!bus)
104 goto out;
105
106 /* Basic PCI configuration */
107 err = pci_enable_device(dev);
108 if (err)
109 goto err_kfree_bus;
110
111 name = dev_name(&dev->dev);
112 if (dev->driver && dev->driver->name)
113 name = dev->driver->name;
114 err = pci_request_regions(dev, name);
115 if (err)
116 goto err_pci_disable;
117 pci_set_master(dev);
118
119 /* Disable the RETRY_TIMEOUT register (0x41) to keep
120 * PCI Tx retries from interfering with C3 CPU state */
121 pci_read_config_dword(dev, 0x40, &val);
122 if ((val & 0x0000ff00) != 0)
123 pci_write_config_dword(dev, 0x40, val & 0xffff00ff);
124
125 /* SSB needed additional powering up, do we have any AMBA PCI cards? */
126 if (!pci_is_pcie(dev))
127 pr_err("PCI card detected, report problems.\n");
128
129 /* Map MMIO */
130 err = -ENOMEM;
131 bus->mmio = pci_iomap(dev, 0, ~0UL);
132 if (!bus->mmio)
133 goto err_pci_release_regions;
134
135 /* Host specific */
136 bus->host_pci = dev;
137 bus->hosttype = BCMA_HOSTTYPE_PCI;
138 bus->ops = &bcma_host_pci_ops;
139
140 /* Register */
141 err = bcma_bus_register(bus);
142 if (err)
143 goto err_pci_unmap_mmio;
144
145 pci_set_drvdata(dev, bus);
146
147out:
148 return err;
149
150err_pci_unmap_mmio:
151 pci_iounmap(dev, bus->mmio);
152err_pci_release_regions:
153 pci_release_regions(dev);
154err_pci_disable:
155 pci_disable_device(dev);
156err_kfree_bus:
157 kfree(bus);
158 return err;
159}
160
161static void bcma_host_pci_remove(struct pci_dev *dev)
162{
163 struct bcma_bus *bus = pci_get_drvdata(dev);
164
165 bcma_bus_unregister(bus);
166 pci_iounmap(dev, bus->mmio);
167 pci_release_regions(dev);
168 pci_disable_device(dev);
169 kfree(bus);
170 pci_set_drvdata(dev, NULL);
171}
172
173static DEFINE_PCI_DEVICE_TABLE(bcma_pci_bridge_tbl) = {
174 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4331) },
175 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4353) },
176 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4727) },
177 { 0, },
178};
179MODULE_DEVICE_TABLE(pci, bcma_pci_bridge_tbl);
180
181static struct pci_driver bcma_pci_bridge_driver = {
182 .name = "bcma-pci-bridge",
183 .id_table = bcma_pci_bridge_tbl,
184 .probe = bcma_host_pci_probe,
185 .remove = bcma_host_pci_remove,
186};
187
188int __init bcma_host_pci_init(void)
189{
190 return pci_register_driver(&bcma_pci_bridge_driver);
191}
192
193void __exit bcma_host_pci_exit(void)
194{
195 pci_unregister_driver(&bcma_pci_bridge_driver);
196}
diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c
new file mode 100644
index 000000000000..be52344ed19d
--- /dev/null
+++ b/drivers/bcma/main.c
@@ -0,0 +1,247 @@
1/*
2 * Broadcom specific AMBA
3 * Bus subsystem
4 *
5 * Licensed under the GNU/GPL. See COPYING for details.
6 */
7
8#include "bcma_private.h"
9#include <linux/bcma/bcma.h>
10
11MODULE_DESCRIPTION("Broadcom's specific AMBA driver");
12MODULE_LICENSE("GPL");
13
14static int bcma_bus_match(struct device *dev, struct device_driver *drv);
15static int bcma_device_probe(struct device *dev);
16static int bcma_device_remove(struct device *dev);
17
18static ssize_t manuf_show(struct device *dev, struct device_attribute *attr, char *buf)
19{
20 struct bcma_device *core = container_of(dev, struct bcma_device, dev);
21 return sprintf(buf, "0x%03X\n", core->id.manuf);
22}
23static ssize_t id_show(struct device *dev, struct device_attribute *attr, char *buf)
24{
25 struct bcma_device *core = container_of(dev, struct bcma_device, dev);
26 return sprintf(buf, "0x%03X\n", core->id.id);
27}
28static ssize_t rev_show(struct device *dev, struct device_attribute *attr, char *buf)
29{
30 struct bcma_device *core = container_of(dev, struct bcma_device, dev);
31 return sprintf(buf, "0x%02X\n", core->id.rev);
32}
33static ssize_t class_show(struct device *dev, struct device_attribute *attr, char *buf)
34{
35 struct bcma_device *core = container_of(dev, struct bcma_device, dev);
36 return sprintf(buf, "0x%X\n", core->id.class);
37}
38static struct device_attribute bcma_device_attrs[] = {
39 __ATTR_RO(manuf),
40 __ATTR_RO(id),
41 __ATTR_RO(rev),
42 __ATTR_RO(class),
43 __ATTR_NULL,
44};
45
46static struct bus_type bcma_bus_type = {
47 .name = "bcma",
48 .match = bcma_bus_match,
49 .probe = bcma_device_probe,
50 .remove = bcma_device_remove,
51 .dev_attrs = bcma_device_attrs,
52};
53
54static struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid)
55{
56 struct bcma_device *core;
57
58 list_for_each_entry(core, &bus->cores, list) {
59 if (core->id.id == coreid)
60 return core;
61 }
62 return NULL;
63}
64
65static void bcma_release_core_dev(struct device *dev)
66{
67 struct bcma_device *core = container_of(dev, struct bcma_device, dev);
68 kfree(core);
69}
70
71static int bcma_register_cores(struct bcma_bus *bus)
72{
73 struct bcma_device *core;
74 int err, dev_id = 0;
75
76 list_for_each_entry(core, &bus->cores, list) {
77 /* We support that cores ourself */
78 switch (core->id.id) {
79 case BCMA_CORE_CHIPCOMMON:
80 case BCMA_CORE_PCI:
81 case BCMA_CORE_PCIE:
82 continue;
83 }
84
85 core->dev.release = bcma_release_core_dev;
86 core->dev.bus = &bcma_bus_type;
87 dev_set_name(&core->dev, "bcma%d:%d", 0/*bus->num*/, dev_id);
88
89 switch (bus->hosttype) {
90 case BCMA_HOSTTYPE_PCI:
91 core->dev.parent = &bus->host_pci->dev;
92 break;
93 case BCMA_HOSTTYPE_NONE:
94 case BCMA_HOSTTYPE_SDIO:
95 break;
96 }
97
98 err = device_register(&core->dev);
99 if (err) {
100 pr_err("Could not register dev for core 0x%03X\n",
101 core->id.id);
102 continue;
103 }
104 core->dev_registered = true;
105 dev_id++;
106 }
107
108 return 0;
109}
110
111static void bcma_unregister_cores(struct bcma_bus *bus)
112{
113 struct bcma_device *core;
114
115 list_for_each_entry(core, &bus->cores, list) {
116 if (core->dev_registered)
117 device_unregister(&core->dev);
118 }
119}
120
121int bcma_bus_register(struct bcma_bus *bus)
122{
123 int err;
124 struct bcma_device *core;
125
126 /* Scan for devices (cores) */
127 err = bcma_bus_scan(bus);
128 if (err) {
129 pr_err("Failed to scan: %d\n", err);
130 return -1;
131 }
132
133 /* Init CC core */
134 core = bcma_find_core(bus, BCMA_CORE_CHIPCOMMON);
135 if (core) {
136 bus->drv_cc.core = core;
137 bcma_core_chipcommon_init(&bus->drv_cc);
138 }
139
140 /* Init PCIE core */
141 core = bcma_find_core(bus, BCMA_CORE_PCIE);
142 if (core) {
143 bus->drv_pci.core = core;
144 bcma_core_pci_init(&bus->drv_pci);
145 }
146
147 /* Register found cores */
148 bcma_register_cores(bus);
149
150 pr_info("Bus registered\n");
151
152 return 0;
153}
154EXPORT_SYMBOL_GPL(bcma_bus_register);
155
156void bcma_bus_unregister(struct bcma_bus *bus)
157{
158 bcma_unregister_cores(bus);
159}
160EXPORT_SYMBOL_GPL(bcma_bus_unregister);
161
162int __bcma_driver_register(struct bcma_driver *drv, struct module *owner)
163{
164 drv->drv.name = drv->name;
165 drv->drv.bus = &bcma_bus_type;
166 drv->drv.owner = owner;
167
168 return driver_register(&drv->drv);
169}
170EXPORT_SYMBOL_GPL(__bcma_driver_register);
171
172void bcma_driver_unregister(struct bcma_driver *drv)
173{
174 driver_unregister(&drv->drv);
175}
176EXPORT_SYMBOL_GPL(bcma_driver_unregister);
177
178static int bcma_bus_match(struct device *dev, struct device_driver *drv)
179{
180 struct bcma_device *core = container_of(dev, struct bcma_device, dev);
181 struct bcma_driver *adrv = container_of(drv, struct bcma_driver, drv);
182 const struct bcma_device_id *cid = &core->id;
183 const struct bcma_device_id *did;
184
185 for (did = adrv->id_table; did->manuf || did->id || did->rev; did++) {
186 if ((did->manuf == cid->manuf || did->manuf == BCMA_ANY_MANUF) &&
187 (did->id == cid->id || did->id == BCMA_ANY_ID) &&
188 (did->rev == cid->rev || did->rev == BCMA_ANY_REV) &&
189 (did->class == cid->class || did->class == BCMA_ANY_CLASS))
190 return 1;
191 }
192 return 0;
193}
194
195static int bcma_device_probe(struct device *dev)
196{
197 struct bcma_device *core = container_of(dev, struct bcma_device, dev);
198 struct bcma_driver *adrv = container_of(dev->driver, struct bcma_driver,
199 drv);
200 int err = 0;
201
202 if (adrv->probe)
203 err = adrv->probe(core);
204
205 return err;
206}
207
208static int bcma_device_remove(struct device *dev)
209{
210 struct bcma_device *core = container_of(dev, struct bcma_device, dev);
211 struct bcma_driver *adrv = container_of(dev->driver, struct bcma_driver,
212 drv);
213
214 if (adrv->remove)
215 adrv->remove(core);
216
217 return 0;
218}
219
220static int __init bcma_modinit(void)
221{
222 int err;
223
224 err = bus_register(&bcma_bus_type);
225 if (err)
226 return err;
227
228#ifdef CONFIG_BCMA_HOST_PCI
229 err = bcma_host_pci_init();
230 if (err) {
231 pr_err("PCI host initialization failed\n");
232 err = 0;
233 }
234#endif
235
236 return err;
237}
238fs_initcall(bcma_modinit);
239
240static void __exit bcma_modexit(void)
241{
242#ifdef CONFIG_BCMA_HOST_PCI
243 bcma_host_pci_exit();
244#endif
245 bus_unregister(&bcma_bus_type);
246}
247module_exit(bcma_modexit)
diff --git a/drivers/bcma/scan.c b/drivers/bcma/scan.c
new file mode 100644
index 000000000000..40d7dcce8933
--- /dev/null
+++ b/drivers/bcma/scan.c
@@ -0,0 +1,360 @@
1/*
2 * Broadcom specific AMBA
3 * Bus scanning
4 *
5 * Licensed under the GNU/GPL. See COPYING for details.
6 */
7
8#include "scan.h"
9#include "bcma_private.h"
10
11#include <linux/bcma/bcma.h>
12#include <linux/bcma/bcma_regs.h>
13#include <linux/pci.h>
14#include <linux/io.h>
15#include <linux/dma-mapping.h>
16#include <linux/slab.h>
17
18struct bcma_device_id_name {
19 u16 id;
20 const char *name;
21};
22struct bcma_device_id_name bcma_device_names[] = {
23 { BCMA_CORE_OOB_ROUTER, "OOB Router" },
24 { BCMA_CORE_INVALID, "Invalid" },
25 { BCMA_CORE_CHIPCOMMON, "ChipCommon" },
26 { BCMA_CORE_ILINE20, "ILine 20" },
27 { BCMA_CORE_SRAM, "SRAM" },
28 { BCMA_CORE_SDRAM, "SDRAM" },
29 { BCMA_CORE_PCI, "PCI" },
30 { BCMA_CORE_MIPS, "MIPS" },
31 { BCMA_CORE_ETHERNET, "Fast Ethernet" },
32 { BCMA_CORE_V90, "V90" },
33 { BCMA_CORE_USB11_HOSTDEV, "USB 1.1 Hostdev" },
34 { BCMA_CORE_ADSL, "ADSL" },
35 { BCMA_CORE_ILINE100, "ILine 100" },
36 { BCMA_CORE_IPSEC, "IPSEC" },
37 { BCMA_CORE_UTOPIA, "UTOPIA" },
38 { BCMA_CORE_PCMCIA, "PCMCIA" },
39 { BCMA_CORE_INTERNAL_MEM, "Internal Memory" },
40 { BCMA_CORE_MEMC_SDRAM, "MEMC SDRAM" },
41 { BCMA_CORE_OFDM, "OFDM" },
42 { BCMA_CORE_EXTIF, "EXTIF" },
43 { BCMA_CORE_80211, "IEEE 802.11" },
44 { BCMA_CORE_PHY_A, "PHY A" },
45 { BCMA_CORE_PHY_B, "PHY B" },
46 { BCMA_CORE_PHY_G, "PHY G" },
47 { BCMA_CORE_MIPS_3302, "MIPS 3302" },
48 { BCMA_CORE_USB11_HOST, "USB 1.1 Host" },
49 { BCMA_CORE_USB11_DEV, "USB 1.1 Device" },
50 { BCMA_CORE_USB20_HOST, "USB 2.0 Host" },
51 { BCMA_CORE_USB20_DEV, "USB 2.0 Device" },
52 { BCMA_CORE_SDIO_HOST, "SDIO Host" },
53 { BCMA_CORE_ROBOSWITCH, "Roboswitch" },
54 { BCMA_CORE_PARA_ATA, "PATA" },
55 { BCMA_CORE_SATA_XORDMA, "SATA XOR-DMA" },
56 { BCMA_CORE_ETHERNET_GBIT, "GBit Ethernet" },
57 { BCMA_CORE_PCIE, "PCIe" },
58 { BCMA_CORE_PHY_N, "PHY N" },
59 { BCMA_CORE_SRAM_CTL, "SRAM Controller" },
60 { BCMA_CORE_MINI_MACPHY, "Mini MACPHY" },
61 { BCMA_CORE_ARM_1176, "ARM 1176" },
62 { BCMA_CORE_ARM_7TDMI, "ARM 7TDMI" },
63 { BCMA_CORE_PHY_LP, "PHY LP" },
64 { BCMA_CORE_PMU, "PMU" },
65 { BCMA_CORE_PHY_SSN, "PHY SSN" },
66 { BCMA_CORE_SDIO_DEV, "SDIO Device" },
67 { BCMA_CORE_ARM_CM3, "ARM CM3" },
68 { BCMA_CORE_PHY_HT, "PHY HT" },
69 { BCMA_CORE_MIPS_74K, "MIPS 74K" },
70 { BCMA_CORE_MAC_GBIT, "GBit MAC" },
71 { BCMA_CORE_DDR12_MEM_CTL, "DDR1/DDR2 Memory Controller" },
72 { BCMA_CORE_PCIE_RC, "PCIe Root Complex" },
73 { BCMA_CORE_OCP_OCP_BRIDGE, "OCP to OCP Bridge" },
74 { BCMA_CORE_SHARED_COMMON, "Common Shared" },
75 { BCMA_CORE_OCP_AHB_BRIDGE, "OCP to AHB Bridge" },
76 { BCMA_CORE_SPI_HOST, "SPI Host" },
77 { BCMA_CORE_I2S, "I2S" },
78 { BCMA_CORE_SDR_DDR1_MEM_CTL, "SDR/DDR1 Memory Controller" },
79 { BCMA_CORE_SHIM, "SHIM" },
80 { BCMA_CORE_DEFAULT, "Default" },
81};
82const char *bcma_device_name(struct bcma_device_id *id)
83{
84 int i;
85
86 if (id->manuf == BCMA_MANUF_BCM) {
87 for (i = 0; i < ARRAY_SIZE(bcma_device_names); i++) {
88 if (bcma_device_names[i].id == id->id)
89 return bcma_device_names[i].name;
90 }
91 }
92 return "UNKNOWN";
93}
94
95static u32 bcma_scan_read32(struct bcma_bus *bus, u8 current_coreidx,
96 u16 offset)
97{
98 return readl(bus->mmio + offset);
99}
100
101static void bcma_scan_switch_core(struct bcma_bus *bus, u32 addr)
102{
103 if (bus->hosttype == BCMA_HOSTTYPE_PCI)
104 pci_write_config_dword(bus->host_pci, BCMA_PCI_BAR0_WIN,
105 addr);
106}
107
108static u32 bcma_erom_get_ent(struct bcma_bus *bus, u32 **eromptr)
109{
110 u32 ent = readl(*eromptr);
111 (*eromptr)++;
112 return ent;
113}
114
115static void bcma_erom_push_ent(u32 **eromptr)
116{
117 (*eromptr)--;
118}
119
120static s32 bcma_erom_get_ci(struct bcma_bus *bus, u32 **eromptr)
121{
122 u32 ent = bcma_erom_get_ent(bus, eromptr);
123 if (!(ent & SCAN_ER_VALID))
124 return -ENOENT;
125 if ((ent & SCAN_ER_TAG) != SCAN_ER_TAG_CI)
126 return -ENOENT;
127 return ent;
128}
129
130static bool bcma_erom_is_end(struct bcma_bus *bus, u32 **eromptr)
131{
132 u32 ent = bcma_erom_get_ent(bus, eromptr);
133 bcma_erom_push_ent(eromptr);
134 return (ent == (SCAN_ER_TAG_END | SCAN_ER_VALID));
135}
136
137static bool bcma_erom_is_bridge(struct bcma_bus *bus, u32 **eromptr)
138{
139 u32 ent = bcma_erom_get_ent(bus, eromptr);
140 bcma_erom_push_ent(eromptr);
141 return (((ent & SCAN_ER_VALID)) &&
142 ((ent & SCAN_ER_TAGX) == SCAN_ER_TAG_ADDR) &&
143 ((ent & SCAN_ADDR_TYPE) == SCAN_ADDR_TYPE_BRIDGE));
144}
145
146static void bcma_erom_skip_component(struct bcma_bus *bus, u32 **eromptr)
147{
148 u32 ent;
149 while (1) {
150 ent = bcma_erom_get_ent(bus, eromptr);
151 if ((ent & SCAN_ER_VALID) &&
152 ((ent & SCAN_ER_TAG) == SCAN_ER_TAG_CI))
153 break;
154 if (ent == (SCAN_ER_TAG_END | SCAN_ER_VALID))
155 break;
156 }
157 bcma_erom_push_ent(eromptr);
158}
159
160static s32 bcma_erom_get_mst_port(struct bcma_bus *bus, u32 **eromptr)
161{
162 u32 ent = bcma_erom_get_ent(bus, eromptr);
163 if (!(ent & SCAN_ER_VALID))
164 return -ENOENT;
165 if ((ent & SCAN_ER_TAG) != SCAN_ER_TAG_MP)
166 return -ENOENT;
167 return ent;
168}
169
170static s32 bcma_erom_get_addr_desc(struct bcma_bus *bus, u32 **eromptr,
171 u32 type, u8 port)
172{
173 u32 addrl, addrh, sizel, sizeh = 0;
174 u32 size;
175
176 u32 ent = bcma_erom_get_ent(bus, eromptr);
177 if ((!(ent & SCAN_ER_VALID)) ||
178 ((ent & SCAN_ER_TAGX) != SCAN_ER_TAG_ADDR) ||
179 ((ent & SCAN_ADDR_TYPE) != type) ||
180 (((ent & SCAN_ADDR_PORT) >> SCAN_ADDR_PORT_SHIFT) != port)) {
181 bcma_erom_push_ent(eromptr);
182 return -EINVAL;
183 }
184
185 addrl = ent & SCAN_ADDR_ADDR;
186 if (ent & SCAN_ADDR_AG32)
187 addrh = bcma_erom_get_ent(bus, eromptr);
188 else
189 addrh = 0;
190
191 if ((ent & SCAN_ADDR_SZ) == SCAN_ADDR_SZ_SZD) {
192 size = bcma_erom_get_ent(bus, eromptr);
193 sizel = size & SCAN_SIZE_SZ;
194 if (size & SCAN_SIZE_SG32)
195 sizeh = bcma_erom_get_ent(bus, eromptr);
196 } else
197 sizel = SCAN_ADDR_SZ_BASE <<
198 ((ent & SCAN_ADDR_SZ) >> SCAN_ADDR_SZ_SHIFT);
199
200 return addrl;
201}
202
203int bcma_bus_scan(struct bcma_bus *bus)
204{
205 u32 erombase;
206 u32 __iomem *eromptr, *eromend;
207
208 s32 cia, cib;
209 u8 ports[2], wrappers[2];
210
211 s32 tmp;
212 u8 i, j;
213
214 int err;
215
216 INIT_LIST_HEAD(&bus->cores);
217 bus->nr_cores = 0;
218
219 bcma_scan_switch_core(bus, BCMA_ADDR_BASE);
220
221 tmp = bcma_scan_read32(bus, 0, BCMA_CC_ID);
222 bus->chipinfo.id = (tmp & BCMA_CC_ID_ID) >> BCMA_CC_ID_ID_SHIFT;
223 bus->chipinfo.rev = (tmp & BCMA_CC_ID_REV) >> BCMA_CC_ID_REV_SHIFT;
224 bus->chipinfo.pkg = (tmp & BCMA_CC_ID_PKG) >> BCMA_CC_ID_PKG_SHIFT;
225
226 erombase = bcma_scan_read32(bus, 0, BCMA_CC_EROM);
227 eromptr = bus->mmio;
228 eromend = eromptr + BCMA_CORE_SIZE / sizeof(u32);
229
230 bcma_scan_switch_core(bus, erombase);
231
232 while (eromptr < eromend) {
233 struct bcma_device *core = kzalloc(sizeof(*core), GFP_KERNEL);
234 if (!core)
235 return -ENOMEM;
236 INIT_LIST_HEAD(&core->list);
237 core->bus = bus;
238
239 /* get CIs */
240 cia = bcma_erom_get_ci(bus, &eromptr);
241 if (cia < 0) {
242 bcma_erom_push_ent(&eromptr);
243 if (bcma_erom_is_end(bus, &eromptr))
244 break;
245 err= -EILSEQ;
246 goto out;
247 }
248 cib = bcma_erom_get_ci(bus, &eromptr);
249 if (cib < 0) {
250 err= -EILSEQ;
251 goto out;
252 }
253
254 /* parse CIs */
255 core->id.class = (cia & SCAN_CIA_CLASS) >> SCAN_CIA_CLASS_SHIFT;
256 core->id.id = (cia & SCAN_CIA_ID) >> SCAN_CIA_ID_SHIFT;
257 core->id.manuf = (cia & SCAN_CIA_MANUF) >> SCAN_CIA_MANUF_SHIFT;
258 ports[0] = (cib & SCAN_CIB_NMP) >> SCAN_CIB_NMP_SHIFT;
259 ports[1] = (cib & SCAN_CIB_NSP) >> SCAN_CIB_NSP_SHIFT;
260 wrappers[0] = (cib & SCAN_CIB_NMW) >> SCAN_CIB_NMW_SHIFT;
261 wrappers[1] = (cib & SCAN_CIB_NSW) >> SCAN_CIB_NSW_SHIFT;
262 core->id.rev = (cib & SCAN_CIB_REV) >> SCAN_CIB_REV_SHIFT;
263
264 if (((core->id.manuf == BCMA_MANUF_ARM) &&
265 (core->id.id == 0xFFF)) ||
266 (ports[1] == 0)) {
267 bcma_erom_skip_component(bus, &eromptr);
268 continue;
269 }
270
271 /* check if component is a core at all */
272 if (wrappers[0] + wrappers[1] == 0) {
273 /* we could save addrl of the router
274 if (cid == BCMA_CORE_OOB_ROUTER)
275 */
276 bcma_erom_skip_component(bus, &eromptr);
277 continue;
278 }
279
280 if (bcma_erom_is_bridge(bus, &eromptr)) {
281 bcma_erom_skip_component(bus, &eromptr);
282 continue;
283 }
284
285 /* get & parse master ports */
286 for (i = 0; i < ports[0]; i++) {
287 u32 mst_port_d = bcma_erom_get_mst_port(bus, &eromptr);
288 if (mst_port_d < 0) {
289 err= -EILSEQ;
290 goto out;
291 }
292 }
293
294 /* get & parse slave ports */
295 for (i = 0; i < ports[1]; i++) {
296 for (j = 0; ; j++) {
297 tmp = bcma_erom_get_addr_desc(bus, &eromptr,
298 SCAN_ADDR_TYPE_SLAVE, i);
299 if (tmp < 0) {
300 /* no more entries for port _i_ */
301 /* pr_debug("erom: slave port %d "
302 * "has %d descriptors\n", i, j); */
303 break;
304 } else {
305 if (i == 0 && j == 0)
306 core->addr = tmp;
307 }
308 }
309 }
310
311 /* get & parse master wrappers */
312 for (i = 0; i < wrappers[0]; i++) {
313 for (j = 0; ; j++) {
314 tmp = bcma_erom_get_addr_desc(bus, &eromptr,
315 SCAN_ADDR_TYPE_MWRAP, i);
316 if (tmp < 0) {
317 /* no more entries for port _i_ */
318 /* pr_debug("erom: master wrapper %d "
319 * "has %d descriptors\n", i, j); */
320 break;
321 } else {
322 if (i == 0 && j == 0)
323 core->wrap = tmp;
324 }
325 }
326 }
327
328 /* get & parse slave wrappers */
329 for (i = 0; i < wrappers[1]; i++) {
330 u8 hack = (ports[1] == 1) ? 0 : 1;
331 for (j = 0; ; j++) {
332 tmp = bcma_erom_get_addr_desc(bus, &eromptr,
333 SCAN_ADDR_TYPE_SWRAP, i + hack);
334 if (tmp < 0) {
335 /* no more entries for port _i_ */
336 /* pr_debug("erom: master wrapper %d "
337 * has %d descriptors\n", i, j); */
338 break;
339 } else {
340 if (wrappers[0] == 0 && !i && !j)
341 core->wrap = tmp;
342 }
343 }
344 }
345
346 pr_info("Core %d found: %s "
347 "(manuf 0x%03X, id 0x%03X, rev 0x%02X, class 0x%X)\n",
348 bus->nr_cores, bcma_device_name(&core->id),
349 core->id.manuf, core->id.id, core->id.rev,
350 core->id.class);
351
352 core->core_index = bus->nr_cores++;
353 list_add(&core->list, &bus->cores);
354 continue;
355out:
356 return err;
357 }
358
359 return 0;
360}
diff --git a/drivers/bcma/scan.h b/drivers/bcma/scan.h
new file mode 100644
index 000000000000..113e6a66884c
--- /dev/null
+++ b/drivers/bcma/scan.h
@@ -0,0 +1,56 @@
1#ifndef BCMA_SCAN_H_
2#define BCMA_SCAN_H_
3
4#define BCMA_ADDR_BASE 0x18000000
5#define BCMA_WRAP_BASE 0x18100000
6
7#define SCAN_ER_VALID 0x00000001
8#define SCAN_ER_TAGX 0x00000006 /* we have to ignore 0x8 bit when checking tag for SCAN_ER_TAG_ADDR */
9#define SCAN_ER_TAG 0x0000000E
10#define SCAN_ER_TAG_CI 0x00000000
11#define SCAN_ER_TAG_MP 0x00000002
12#define SCAN_ER_TAG_ADDR 0x00000004
13#define SCAN_ER_TAG_END 0x0000000E
14#define SCAN_ER_BAD 0xFFFFFFFF
15
16#define SCAN_CIA_CLASS 0x000000F0
17#define SCAN_CIA_CLASS_SHIFT 4
18#define SCAN_CIA_ID 0x000FFF00
19#define SCAN_CIA_ID_SHIFT 8
20#define SCAN_CIA_MANUF 0xFFF00000
21#define SCAN_CIA_MANUF_SHIFT 20
22
23#define SCAN_CIB_NMP 0x000001F0
24#define SCAN_CIB_NMP_SHIFT 4
25#define SCAN_CIB_NSP 0x00003E00
26#define SCAN_CIB_NSP_SHIFT 9
27#define SCAN_CIB_NMW 0x0007C000
28#define SCAN_CIB_NMW_SHIFT 14
29#define SCAN_CIB_NSW 0x00F80000
30#define SCAN_CIB_NSW_SHIFT 17
31#define SCAN_CIB_REV 0xFF000000
32#define SCAN_CIB_REV_SHIFT 24
33
34#define SCAN_ADDR_AG32 0x00000008
35#define SCAN_ADDR_SZ 0x00000030
36#define SCAN_ADDR_SZ_SHIFT 4
37#define SCAN_ADDR_SZ_4K 0x00000000
38#define SCAN_ADDR_SZ_8K 0x00000010
39#define SCAN_ADDR_SZ_16K 0x00000020
40#define SCAN_ADDR_SZ_SZD 0x00000030
41#define SCAN_ADDR_TYPE 0x000000C0
42#define SCAN_ADDR_TYPE_SLAVE 0x00000000
43#define SCAN_ADDR_TYPE_BRIDGE 0x00000040
44#define SCAN_ADDR_TYPE_SWRAP 0x00000080
45#define SCAN_ADDR_TYPE_MWRAP 0x000000C0
46#define SCAN_ADDR_PORT 0x00000F00
47#define SCAN_ADDR_PORT_SHIFT 8
48#define SCAN_ADDR_ADDR 0xFFFFF000
49
50#define SCAN_ADDR_SZ_BASE 0x00001000 /* 4KB */
51
52#define SCAN_SIZE_SZ_ALIGN 0x00000FFF
53#define SCAN_SIZE_SZ 0xFFFFF000
54#define SCAN_SIZE_SG32 0x00000008
55
56#endif /* BCMA_SCAN_H_ */
diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c
index 695d4414bd4c..6bacef368fab 100644
--- a/drivers/bluetooth/ath3k.c
+++ b/drivers/bluetooth/ath3k.c
@@ -62,6 +62,7 @@ static struct usb_device_id ath3k_table[] = {
62 62
63 /* Atheros AR3011 with sflash firmware*/ 63 /* Atheros AR3011 with sflash firmware*/
64 { USB_DEVICE(0x0CF3, 0x3002) }, 64 { USB_DEVICE(0x0CF3, 0x3002) },
65 { USB_DEVICE(0x13d3, 0x3304) },
65 66
66 /* Atheros AR9285 Malbec with sflash firmware */ 67 /* Atheros AR9285 Malbec with sflash firmware */
67 { USB_DEVICE(0x03F0, 0x311D) }, 68 { USB_DEVICE(0x03F0, 0x311D) },
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 762a5109c68a..c2de8951e3fb 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -104,6 +104,7 @@ static struct usb_device_id blacklist_table[] = {
104 104
105 /* Atheros 3011 with sflash firmware */ 105 /* Atheros 3011 with sflash firmware */
106 { USB_DEVICE(0x0cf3, 0x3002), .driver_info = BTUSB_IGNORE }, 106 { USB_DEVICE(0x0cf3, 0x3002), .driver_info = BTUSB_IGNORE },
107 { USB_DEVICE(0x13d3, 0x3304), .driver_info = BTUSB_IGNORE },
107 108
108 /* Atheros AR9285 Malbec with sflash firmware */ 109 /* Atheros AR9285 Malbec with sflash firmware */
109 { USB_DEVICE(0x03f0, 0x311d), .driver_info = BTUSB_IGNORE }, 110 { USB_DEVICE(0x03f0, 0x311d), .driver_info = BTUSB_IGNORE },
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 203243bacc89..22047628ccfa 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -2394,7 +2394,7 @@ ath5k_init_softc(struct ath5k_softc *sc, const struct ath_bus_ops *bus_ops)
2394 spin_lock_init(&sc->rxbuflock); 2394 spin_lock_init(&sc->rxbuflock);
2395 spin_lock_init(&sc->txbuflock); 2395 spin_lock_init(&sc->txbuflock);
2396 spin_lock_init(&sc->block); 2396 spin_lock_init(&sc->block);
2397 2397 spin_lock_init(&sc->irqlock);
2398 2398
2399 /* Setup interrupt handler */ 2399 /* Setup interrupt handler */
2400 ret = request_irq(sc->irq, ath5k_intr, IRQF_SHARED, "ath", sc); 2400 ret = request_irq(sc->irq, ath5k_intr, IRQF_SHARED, "ath", sc);
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_mac.c b/drivers/net/wireless/ath/ath9k/ar9002_mac.c
index c338efbccf40..7a332f16b79a 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_mac.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_mac.c
@@ -415,15 +415,6 @@ static void ar9002_hw_clr11n_aggr(struct ath_hw *ah, void *ds)
415 ads->ds_ctl1 &= (~AR_IsAggr & ~AR_MoreAggr); 415 ads->ds_ctl1 &= (~AR_IsAggr & ~AR_MoreAggr);
416} 416}
417 417
418static void ar9002_hw_set11n_burstduration(struct ath_hw *ah, void *ds,
419 u32 burstDuration)
420{
421 struct ar5416_desc *ads = AR5416DESC(ds);
422
423 ads->ds_ctl2 &= ~AR_BurstDur;
424 ads->ds_ctl2 |= SM(burstDuration, AR_BurstDur);
425}
426
427void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds, 418void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds,
428 u32 size, u32 flags) 419 u32 size, u32 flags)
429{ 420{
@@ -456,6 +447,5 @@ void ar9002_hw_attach_mac_ops(struct ath_hw *ah)
456 ops->set11n_aggr_middle = ar9002_hw_set11n_aggr_middle; 447 ops->set11n_aggr_middle = ar9002_hw_set11n_aggr_middle;
457 ops->set11n_aggr_last = ar9002_hw_set11n_aggr_last; 448 ops->set11n_aggr_last = ar9002_hw_set11n_aggr_last;
458 ops->clr11n_aggr = ar9002_hw_clr11n_aggr; 449 ops->clr11n_aggr = ar9002_hw_clr11n_aggr;
459 ops->set11n_burstduration = ar9002_hw_set11n_burstduration;
460 ops->set_clrdmask = ar9002_hw_set_clrdmask; 450 ops->set_clrdmask = ar9002_hw_set_clrdmask;
461} 451}
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.c b/drivers/net/wireless/ath/ath9k/ar9002_phy.c
index 7d68d61e406b..a57e963cf0dc 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.c
@@ -517,23 +517,7 @@ static void ar9002_hw_set_nf_limits(struct ath_hw *ah)
517 } 517 }
518} 518}
519 519
520void ar9002_hw_attach_phy_ops(struct ath_hw *ah) 520static void ar9002_hw_antdiv_comb_conf_get(struct ath_hw *ah,
521{
522 struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
523
524 priv_ops->set_rf_regs = NULL;
525 priv_ops->rf_alloc_ext_banks = NULL;
526 priv_ops->rf_free_ext_banks = NULL;
527 priv_ops->rf_set_freq = ar9002_hw_set_channel;
528 priv_ops->spur_mitigate_freq = ar9002_hw_spur_mitigate;
529 priv_ops->olc_init = ar9002_olc_init;
530 priv_ops->compute_pll_control = ar9002_hw_compute_pll_control;
531 priv_ops->do_getnf = ar9002_hw_do_getnf;
532
533 ar9002_hw_set_nf_limits(ah);
534}
535
536void ath9k_hw_antdiv_comb_conf_get(struct ath_hw *ah,
537 struct ath_hw_antcomb_conf *antconf) 521 struct ath_hw_antcomb_conf *antconf)
538{ 522{
539 u32 regval; 523 u32 regval;
@@ -545,10 +529,11 @@ void ath9k_hw_antdiv_comb_conf_get(struct ath_hw *ah,
545 AR_PHY_9285_ANT_DIV_ALT_LNACONF_S; 529 AR_PHY_9285_ANT_DIV_ALT_LNACONF_S;
546 antconf->fast_div_bias = (regval & AR_PHY_9285_FAST_DIV_BIAS) >> 530 antconf->fast_div_bias = (regval & AR_PHY_9285_FAST_DIV_BIAS) >>
547 AR_PHY_9285_FAST_DIV_BIAS_S; 531 AR_PHY_9285_FAST_DIV_BIAS_S;
532 antconf->lna1_lna2_delta = -3;
533 antconf->div_group = 0;
548} 534}
549EXPORT_SYMBOL(ath9k_hw_antdiv_comb_conf_get);
550 535
551void ath9k_hw_antdiv_comb_conf_set(struct ath_hw *ah, 536static void ar9002_hw_antdiv_comb_conf_set(struct ath_hw *ah,
552 struct ath_hw_antcomb_conf *antconf) 537 struct ath_hw_antcomb_conf *antconf)
553{ 538{
554 u32 regval; 539 u32 regval;
@@ -566,4 +551,23 @@ void ath9k_hw_antdiv_comb_conf_set(struct ath_hw *ah,
566 551
567 REG_WRITE(ah, AR_PHY_MULTICHAIN_GAIN_CTL, regval); 552 REG_WRITE(ah, AR_PHY_MULTICHAIN_GAIN_CTL, regval);
568} 553}
569EXPORT_SYMBOL(ath9k_hw_antdiv_comb_conf_set); 554
555void ar9002_hw_attach_phy_ops(struct ath_hw *ah)
556{
557 struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
558 struct ath_hw_ops *ops = ath9k_hw_ops(ah);
559
560 priv_ops->set_rf_regs = NULL;
561 priv_ops->rf_alloc_ext_banks = NULL;
562 priv_ops->rf_free_ext_banks = NULL;
563 priv_ops->rf_set_freq = ar9002_hw_set_channel;
564 priv_ops->spur_mitigate_freq = ar9002_hw_spur_mitigate;
565 priv_ops->olc_init = ar9002_olc_init;
566 priv_ops->compute_pll_control = ar9002_hw_compute_pll_control;
567 priv_ops->do_getnf = ar9002_hw_do_getnf;
568
569 ops->antdiv_comb_conf_get = ar9002_hw_antdiv_comb_conf_get;
570 ops->antdiv_comb_conf_set = ar9002_hw_antdiv_comb_conf_set;
571
572 ar9002_hw_set_nf_limits(ah);
573}
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
index fb892e5d141a..1e220354e4be 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
@@ -652,7 +652,7 @@ static const struct ar9300_eeprom ar9300_x113 = {
652 .regDmn = { LE16(0), LE16(0x1f) }, 652 .regDmn = { LE16(0), LE16(0x1f) },
653 .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */ 653 .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */
654 .opCapFlags = { 654 .opCapFlags = {
655 .opFlags = AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A, 655 .opFlags = AR5416_OPFLAGS_11A,
656 .eepMisc = 0, 656 .eepMisc = 0,
657 }, 657 },
658 .rfSilent = 0, 658 .rfSilent = 0,
@@ -922,7 +922,7 @@ static const struct ar9300_eeprom ar9300_x113 = {
922 .db_stage2 = {3, 3, 3}, /* 3 chain */ 922 .db_stage2 = {3, 3, 3}, /* 3 chain */
923 .db_stage3 = {3, 3, 3}, /* doesn't exist for 2G */ 923 .db_stage3 = {3, 3, 3}, /* doesn't exist for 2G */
924 .db_stage4 = {3, 3, 3}, /* don't exist for 2G */ 924 .db_stage4 = {3, 3, 3}, /* don't exist for 2G */
925 .xpaBiasLvl = 0, 925 .xpaBiasLvl = 0xf,
926 .txFrameToDataStart = 0x0e, 926 .txFrameToDataStart = 0x0e,
927 .txFrameToPaOn = 0x0e, 927 .txFrameToPaOn = 0x0e,
928 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */ 928 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
@@ -3442,17 +3442,15 @@ static void ar9003_hw_xpa_bias_level_apply(struct ath_hw *ah, bool is2ghz)
3442{ 3442{
3443 int bias = ar9003_hw_xpa_bias_level_get(ah, is2ghz); 3443 int bias = ar9003_hw_xpa_bias_level_get(ah, is2ghz);
3444 3444
3445 if (AR_SREV_9485(ah)) 3445 if (AR_SREV_9485(ah) || AR_SREV_9340(ah))
3446 REG_RMW_FIELD(ah, AR_CH0_TOP2, AR_CH0_TOP2_XPABIASLVL, bias); 3446 REG_RMW_FIELD(ah, AR_CH0_TOP2, AR_CH0_TOP2_XPABIASLVL, bias);
3447 else { 3447 else {
3448 REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, bias); 3448 REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, bias);
3449 if (!AR_SREV_9340(ah)) { 3449 REG_RMW_FIELD(ah, AR_CH0_THERM,
3450 REG_RMW_FIELD(ah, AR_CH0_THERM, 3450 AR_CH0_THERM_XPABIASLVL_MSB,
3451 AR_CH0_THERM_XPABIASLVL_MSB, 3451 bias >> 2);
3452 bias >> 2); 3452 REG_RMW_FIELD(ah, AR_CH0_THERM,
3453 REG_RMW_FIELD(ah, AR_CH0_THERM, 3453 AR_CH0_THERM_XPASHORT2GND, 1);
3454 AR_CH0_THERM_XPASHORT2GND, 1);
3455 }
3456 } 3454 }
3457} 3455}
3458 3456
@@ -3500,6 +3498,8 @@ static u16 ar9003_hw_ant_ctrl_chain_get(struct ath_hw *ah,
3500static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz) 3498static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz)
3501{ 3499{
3502 int chain; 3500 int chain;
3501 u32 regval;
3502 u32 ant_div_ctl1;
3503 static const u32 switch_chain_reg[AR9300_MAX_CHAINS] = { 3503 static const u32 switch_chain_reg[AR9300_MAX_CHAINS] = {
3504 AR_PHY_SWITCH_CHAIN_0, 3504 AR_PHY_SWITCH_CHAIN_0,
3505 AR_PHY_SWITCH_CHAIN_1, 3505 AR_PHY_SWITCH_CHAIN_1,
@@ -3525,13 +3525,49 @@ static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz)
3525 3525
3526 if (AR_SREV_9485(ah)) { 3526 if (AR_SREV_9485(ah)) {
3527 value = ath9k_hw_ar9300_get_eeprom(ah, EEP_ANT_DIV_CTL1); 3527 value = ath9k_hw_ar9300_get_eeprom(ah, EEP_ANT_DIV_CTL1);
3528 REG_RMW_FIELD(ah, AR_PHY_MC_GAIN_CTRL, AR_ANT_DIV_CTRL_ALL, 3528 /*
3529 value); 3529 * main_lnaconf, alt_lnaconf, main_tb, alt_tb
3530 REG_RMW_FIELD(ah, AR_PHY_MC_GAIN_CTRL, AR_ANT_DIV_ENABLE, 3530 * are the fields present
3531 value >> 6); 3531 */
3532 REG_RMW_FIELD(ah, AR_PHY_CCK_DETECT, AR_FAST_DIV_ENABLE, 3532 regval = REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
3533 value >> 7); 3533 regval &= (~AR_ANT_DIV_CTRL_ALL);
3534 regval |= (value & 0x3f) << AR_ANT_DIV_CTRL_ALL_S;
3535 /* enable_lnadiv */
3536 regval &= (~AR_PHY_9485_ANT_DIV_LNADIV);
3537 regval |= ((value >> 6) & 0x1) <<
3538 AR_PHY_9485_ANT_DIV_LNADIV_S;
3539 REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
3540
3541 /*enable fast_div */
3542 regval = REG_READ(ah, AR_PHY_CCK_DETECT);
3543 regval &= (~AR_FAST_DIV_ENABLE);
3544 regval |= ((value >> 7) & 0x1) <<
3545 AR_FAST_DIV_ENABLE_S;
3546 REG_WRITE(ah, AR_PHY_CCK_DETECT, regval);
3547 ant_div_ctl1 =
3548 ah->eep_ops->get_eeprom(ah, EEP_ANT_DIV_CTL1);
3549 /* check whether antenna diversity is enabled */
3550 if ((ant_div_ctl1 >> 0x6) == 0x3) {
3551 regval = REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
3552 /*
3553 * clear bits 25-30 main_lnaconf, alt_lnaconf,
3554 * main_tb, alt_tb
3555 */
3556 regval &= (~(AR_PHY_9485_ANT_DIV_MAIN_LNACONF |
3557 AR_PHY_9485_ANT_DIV_ALT_LNACONF |
3558 AR_PHY_9485_ANT_DIV_ALT_GAINTB |
3559 AR_PHY_9485_ANT_DIV_MAIN_GAINTB));
3560 /* by default use LNA1 for the main antenna */
3561 regval |= (AR_PHY_9485_ANT_DIV_LNA1 <<
3562 AR_PHY_9485_ANT_DIV_MAIN_LNACONF_S);
3563 regval |= (AR_PHY_9485_ANT_DIV_LNA2 <<
3564 AR_PHY_9485_ANT_DIV_ALT_LNACONF_S);
3565 REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
3566 }
3567
3568
3534 } 3569 }
3570
3535} 3571}
3536 3572
3537static void ar9003_hw_drive_strength_apply(struct ath_hw *ah) 3573static void ar9003_hw_drive_strength_apply(struct ath_hw *ah)
@@ -4005,6 +4041,16 @@ static int ar9003_hw_tx_power_regwrite(struct ath_hw *ah, u8 * pPwrArray)
4005 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0) 4041 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0)
4006 ); 4042 );
4007 4043
4044 /* Write the power for duplicated frames - HT40 */
4045
4046 /* dup40_cck (LSB), dup40_ofdm, ext20_cck, ext20_ofdm (MSB) */
4047 REG_WRITE(ah, 0xa3e0,
4048 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 24) |
4049 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 16) |
4050 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 8) |
4051 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0)
4052 );
4053
4008 /* Write the HT20 power per rate set */ 4054 /* Write the HT20 power per rate set */
4009 4055
4010 /* 0/8/16 (LSB), 1-3/9-11/17-19, 4, 5 (MSB) */ 4056 /* 0/8/16 (LSB), 1-3/9-11/17-19, 4, 5 (MSB) */
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
index c1264d60c499..be6adec33ddb 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
@@ -484,16 +484,6 @@ static void ar9003_hw_clr11n_aggr(struct ath_hw *ah, void *ds)
484 ads->ctl12 &= (~AR_IsAggr & ~AR_MoreAggr); 484 ads->ctl12 &= (~AR_IsAggr & ~AR_MoreAggr);
485} 485}
486 486
487static void ar9003_hw_set11n_burstduration(struct ath_hw *ah, void *ds,
488 u32 burstDuration)
489{
490 struct ar9003_txc *ads = (struct ar9003_txc *) ds;
491
492 ads->ctl13 &= ~AR_BurstDur;
493 ads->ctl13 |= SM(burstDuration, AR_BurstDur);
494
495}
496
497void ar9003_hw_set_paprd_txdesc(struct ath_hw *ah, void *ds, u8 chains) 487void ar9003_hw_set_paprd_txdesc(struct ath_hw *ah, void *ds, u8 chains)
498{ 488{
499 struct ar9003_txc *ads = ds; 489 struct ar9003_txc *ads = ds;
@@ -518,7 +508,6 @@ void ar9003_hw_attach_mac_ops(struct ath_hw *hw)
518 ops->set11n_aggr_middle = ar9003_hw_set11n_aggr_middle; 508 ops->set11n_aggr_middle = ar9003_hw_set11n_aggr_middle;
519 ops->set11n_aggr_last = ar9003_hw_set11n_aggr_last; 509 ops->set11n_aggr_last = ar9003_hw_set11n_aggr_last;
520 ops->clr11n_aggr = ar9003_hw_clr11n_aggr; 510 ops->clr11n_aggr = ar9003_hw_clr11n_aggr;
521 ops->set11n_burstduration = ar9003_hw_set11n_burstduration;
522 ops->set_clrdmask = ar9003_hw_set_clrdmask; 511 ops->set_clrdmask = ar9003_hw_set_clrdmask;
523} 512}
524 513
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index c83be2dd5718..25f3c2fdf2bc 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -1184,9 +1184,52 @@ static void ar9003_hw_set_radar_conf(struct ath_hw *ah)
1184 conf->radar_inband = 8; 1184 conf->radar_inband = 8;
1185} 1185}
1186 1186
1187static void ar9003_hw_antdiv_comb_conf_get(struct ath_hw *ah,
1188 struct ath_hw_antcomb_conf *antconf)
1189{
1190 u32 regval;
1191
1192 regval = REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
1193 antconf->main_lna_conf = (regval & AR_PHY_9485_ANT_DIV_MAIN_LNACONF) >>
1194 AR_PHY_9485_ANT_DIV_MAIN_LNACONF_S;
1195 antconf->alt_lna_conf = (regval & AR_PHY_9485_ANT_DIV_ALT_LNACONF) >>
1196 AR_PHY_9485_ANT_DIV_ALT_LNACONF_S;
1197 antconf->fast_div_bias = (regval & AR_PHY_9485_ANT_FAST_DIV_BIAS) >>
1198 AR_PHY_9485_ANT_FAST_DIV_BIAS_S;
1199 antconf->lna1_lna2_delta = -9;
1200 antconf->div_group = 2;
1201}
1202
1203static void ar9003_hw_antdiv_comb_conf_set(struct ath_hw *ah,
1204 struct ath_hw_antcomb_conf *antconf)
1205{
1206 u32 regval;
1207
1208 regval = REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
1209 regval &= ~(AR_PHY_9485_ANT_DIV_MAIN_LNACONF |
1210 AR_PHY_9485_ANT_DIV_ALT_LNACONF |
1211 AR_PHY_9485_ANT_FAST_DIV_BIAS |
1212 AR_PHY_9485_ANT_DIV_MAIN_GAINTB |
1213 AR_PHY_9485_ANT_DIV_ALT_GAINTB);
1214 regval |= ((antconf->main_lna_conf <<
1215 AR_PHY_9485_ANT_DIV_MAIN_LNACONF_S)
1216 & AR_PHY_9485_ANT_DIV_MAIN_LNACONF);
1217 regval |= ((antconf->alt_lna_conf << AR_PHY_9485_ANT_DIV_ALT_LNACONF_S)
1218 & AR_PHY_9485_ANT_DIV_ALT_LNACONF);
1219 regval |= ((antconf->fast_div_bias << AR_PHY_9485_ANT_FAST_DIV_BIAS_S)
1220 & AR_PHY_9485_ANT_FAST_DIV_BIAS);
1221 regval |= ((antconf->main_gaintb << AR_PHY_9485_ANT_DIV_MAIN_GAINTB_S)
1222 & AR_PHY_9485_ANT_DIV_MAIN_GAINTB);
1223 regval |= ((antconf->alt_gaintb << AR_PHY_9485_ANT_DIV_ALT_GAINTB_S)
1224 & AR_PHY_9485_ANT_DIV_ALT_GAINTB);
1225
1226 REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
1227}
1228
1187void ar9003_hw_attach_phy_ops(struct ath_hw *ah) 1229void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
1188{ 1230{
1189 struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); 1231 struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
1232 struct ath_hw_ops *ops = ath9k_hw_ops(ah);
1190 static const u32 ar9300_cca_regs[6] = { 1233 static const u32 ar9300_cca_regs[6] = {
1191 AR_PHY_CCA_0, 1234 AR_PHY_CCA_0,
1192 AR_PHY_CCA_1, 1235 AR_PHY_CCA_1,
@@ -1213,6 +1256,9 @@ void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
1213 priv_ops->ani_cache_ini_regs = ar9003_hw_ani_cache_ini_regs; 1256 priv_ops->ani_cache_ini_regs = ar9003_hw_ani_cache_ini_regs;
1214 priv_ops->set_radar_params = ar9003_hw_set_radar_params; 1257 priv_ops->set_radar_params = ar9003_hw_set_radar_params;
1215 1258
1259 ops->antdiv_comb_conf_get = ar9003_hw_antdiv_comb_conf_get;
1260 ops->antdiv_comb_conf_set = ar9003_hw_antdiv_comb_conf_set;
1261
1216 ar9003_hw_set_nf_limits(ah); 1262 ar9003_hw_set_nf_limits(ah);
1217 ar9003_hw_set_radar_conf(ah); 1263 ar9003_hw_set_radar_conf(ah);
1218 memcpy(ah->nf_regs, ar9300_cca_regs, sizeof(ah->nf_regs)); 1264 memcpy(ah->nf_regs, ar9300_cca_regs, sizeof(ah->nf_regs));
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h
index 2a0d5cbb7e76..c7505b48e5c0 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h
@@ -261,12 +261,34 @@
261#define AR_PHY_EXT_CCA0 (AR_AGC_BASE + 0x20) 261#define AR_PHY_EXT_CCA0 (AR_AGC_BASE + 0x20)
262#define AR_PHY_RESTART (AR_AGC_BASE + 0x24) 262#define AR_PHY_RESTART (AR_AGC_BASE + 0x24)
263 263
264/*
265 * Antenna Diversity settings
266 */
264#define AR_PHY_MC_GAIN_CTRL (AR_AGC_BASE + 0x28) 267#define AR_PHY_MC_GAIN_CTRL (AR_AGC_BASE + 0x28)
265#define AR_ANT_DIV_CTRL_ALL 0x7e000000 268#define AR_ANT_DIV_CTRL_ALL 0x7e000000
266#define AR_ANT_DIV_CTRL_ALL_S 25 269#define AR_ANT_DIV_CTRL_ALL_S 25
267#define AR_ANT_DIV_ENABLE 0x1000000 270#define AR_ANT_DIV_ENABLE 0x1000000
268#define AR_ANT_DIV_ENABLE_S 24 271#define AR_ANT_DIV_ENABLE_S 24
269 272
273
274#define AR_PHY_9485_ANT_FAST_DIV_BIAS 0x00007e00
275#define AR_PHY_9485_ANT_FAST_DIV_BIAS_S 9
276#define AR_PHY_9485_ANT_DIV_LNADIV 0x01000000
277#define AR_PHY_9485_ANT_DIV_LNADIV_S 24
278#define AR_PHY_9485_ANT_DIV_ALT_LNACONF 0x06000000
279#define AR_PHY_9485_ANT_DIV_ALT_LNACONF_S 25
280#define AR_PHY_9485_ANT_DIV_MAIN_LNACONF 0x18000000
281#define AR_PHY_9485_ANT_DIV_MAIN_LNACONF_S 27
282#define AR_PHY_9485_ANT_DIV_ALT_GAINTB 0x20000000
283#define AR_PHY_9485_ANT_DIV_ALT_GAINTB_S 29
284#define AR_PHY_9485_ANT_DIV_MAIN_GAINTB 0x40000000
285#define AR_PHY_9485_ANT_DIV_MAIN_GAINTB_S 30
286
287#define AR_PHY_9485_ANT_DIV_LNA1_MINUS_LNA2 0x0
288#define AR_PHY_9485_ANT_DIV_LNA2 0x1
289#define AR_PHY_9485_ANT_DIV_LNA1 0x2
290#define AR_PHY_9485_ANT_DIV_LNA1_PLUS_LNA2 0x3
291
270#define AR_PHY_EXTCHN_PWRTHR1 (AR_AGC_BASE + 0x2c) 292#define AR_PHY_EXTCHN_PWRTHR1 (AR_AGC_BASE + 0x2c)
271#define AR_PHY_EXT_CHN_WIN (AR_AGC_BASE + 0x30) 293#define AR_PHY_EXT_CHN_WIN (AR_AGC_BASE + 0x30)
272#define AR_PHY_20_40_DET_THR (AR_AGC_BASE + 0x34) 294#define AR_PHY_20_40_DET_THR (AR_AGC_BASE + 0x34)
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 0312aa091807..03b37d7be1c3 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -62,7 +62,6 @@ struct ath_node;
62#define ATH_TXQ_SETUP(sc, i) ((sc)->tx.txqsetup & (1<<i)) 62#define ATH_TXQ_SETUP(sc, i) ((sc)->tx.txqsetup & (1<<i))
63 63
64struct ath_config { 64struct ath_config {
65 u32 ath_aggr_prot;
66 u16 txpowlimit; 65 u16 txpowlimit;
67 u8 cabqReadytime; 66 u8 cabqReadytime;
68}; 67};
@@ -484,7 +483,6 @@ static inline void ath_deinit_leds(struct ath_softc *sc)
484#define ATH_ANT_DIV_COMB_ALT_ANT_RATIO 30 483#define ATH_ANT_DIV_COMB_ALT_ANT_RATIO 30
485#define ATH_ANT_DIV_COMB_ALT_ANT_RATIO2 20 484#define ATH_ANT_DIV_COMB_ALT_ANT_RATIO2 20
486 485
487#define ATH_ANT_DIV_COMB_LNA1_LNA2_DELTA -3
488#define ATH_ANT_DIV_COMB_LNA1_LNA2_SWITCH_DELTA -1 486#define ATH_ANT_DIV_COMB_LNA1_LNA2_SWITCH_DELTA -1
489#define ATH_ANT_DIV_COMB_LNA1_DELTA_HI -4 487#define ATH_ANT_DIV_COMB_LNA1_DELTA_HI -4
490#define ATH_ANT_DIV_COMB_LNA1_DELTA_MID -2 488#define ATH_ANT_DIV_COMB_LNA1_DELTA_MID -2
@@ -565,6 +563,7 @@ struct ath_ant_comb {
565#define PS_WAIT_FOR_PSPOLL_DATA BIT(2) 563#define PS_WAIT_FOR_PSPOLL_DATA BIT(2)
566#define PS_WAIT_FOR_TX_ACK BIT(3) 564#define PS_WAIT_FOR_TX_ACK BIT(3)
567#define PS_BEACON_SYNC BIT(4) 565#define PS_BEACON_SYNC BIT(4)
566#define PS_TSFOOR_SYNC BIT(5)
568 567
569struct ath_rate_table; 568struct ath_rate_table;
570 569
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c
index 22cd241a098b..637dbc5f7b67 100644
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -620,7 +620,13 @@ static void ath_beacon_config_sta(struct ath_softc *sc,
620 ath9k_hw_disable_interrupts(ah); 620 ath9k_hw_disable_interrupts(ah);
621 ath9k_hw_set_sta_beacon_timers(ah, &bs); 621 ath9k_hw_set_sta_beacon_timers(ah, &bs);
622 ah->imask |= ATH9K_INT_BMISS; 622 ah->imask |= ATH9K_INT_BMISS;
623 ath9k_hw_set_interrupts(ah, ah->imask); 623
624 /*
625 * If the beacon config is called beacause of TSFOOR,
626 * Interrupts will be enabled back at the end of ath9k_tasklet
627 */
628 if (!(sc->ps_flags & PS_TSFOOR_SYNC))
629 ath9k_hw_set_interrupts(ah, ah->imask);
624} 630}
625 631
626static void ath_beacon_config_adhoc(struct ath_softc *sc, 632static void ath_beacon_config_adhoc(struct ath_softc *sc,
@@ -661,7 +667,12 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc,
661 ath9k_hw_disable_interrupts(ah); 667 ath9k_hw_disable_interrupts(ah);
662 ath9k_beacon_init(sc, nexttbtt, intval); 668 ath9k_beacon_init(sc, nexttbtt, intval);
663 sc->beacon.bmisscnt = 0; 669 sc->beacon.bmisscnt = 0;
664 ath9k_hw_set_interrupts(ah, ah->imask); 670 /*
671 * If the beacon config is called beacause of TSFOOR,
672 * Interrupts will be enabled back at the end of ath9k_tasklet
673 */
674 if (!(sc->ps_flags & PS_TSFOOR_SYNC))
675 ath9k_hw_set_interrupts(ah, ah->imask);
665} 676}
666 677
667static bool ath9k_allow_beacon_config(struct ath_softc *sc, 678static bool ath9k_allow_beacon_config(struct ath_softc *sc,
diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c
index 8649581fa4dd..558b228a717f 100644
--- a/drivers/net/wireless/ath/ath9k/calib.c
+++ b/drivers/net/wireless/ath/ath9k/calib.c
@@ -69,15 +69,21 @@ static void ath9k_hw_update_nfcal_hist_buffer(struct ath_hw *ah,
69 int16_t *nfarray) 69 int16_t *nfarray)
70{ 70{
71 struct ath_common *common = ath9k_hw_common(ah); 71 struct ath_common *common = ath9k_hw_common(ah);
72 struct ieee80211_conf *conf = &common->hw->conf;
72 struct ath_nf_limits *limit; 73 struct ath_nf_limits *limit;
73 struct ath9k_nfcal_hist *h; 74 struct ath9k_nfcal_hist *h;
74 bool high_nf_mid = false; 75 bool high_nf_mid = false;
76 u8 chainmask = (ah->rxchainmask << 3) | ah->rxchainmask;
75 int i; 77 int i;
76 78
77 h = cal->nfCalHist; 79 h = cal->nfCalHist;
78 limit = ath9k_hw_get_nf_limits(ah, ah->curchan); 80 limit = ath9k_hw_get_nf_limits(ah, ah->curchan);
79 81
80 for (i = 0; i < NUM_NF_READINGS; i++) { 82 for (i = 0; i < NUM_NF_READINGS; i++) {
83 if (!(chainmask & (1 << i)) ||
84 ((i >= AR5416_MAX_CHAINS) && !conf_is_ht40(conf)))
85 continue;
86
81 h[i].nfCalBuffer[h[i].currIndex] = nfarray[i]; 87 h[i].nfCalBuffer[h[i].currIndex] = nfarray[i];
82 88
83 if (++h[i].currIndex >= ATH9K_NF_CAL_HIST_MAX) 89 if (++h[i].currIndex >= ATH9K_NF_CAL_HIST_MAX)
@@ -225,6 +231,7 @@ void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
225 int32_t val; 231 int32_t val;
226 u8 chainmask = (ah->rxchainmask << 3) | ah->rxchainmask; 232 u8 chainmask = (ah->rxchainmask << 3) | ah->rxchainmask;
227 struct ath_common *common = ath9k_hw_common(ah); 233 struct ath_common *common = ath9k_hw_common(ah);
234 struct ieee80211_conf *conf = &common->hw->conf;
228 s16 default_nf = ath9k_hw_get_default_nf(ah, chan); 235 s16 default_nf = ath9k_hw_get_default_nf(ah, chan);
229 236
230 if (ah->caldata) 237 if (ah->caldata)
@@ -234,6 +241,9 @@ void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
234 if (chainmask & (1 << i)) { 241 if (chainmask & (1 << i)) {
235 s16 nfval; 242 s16 nfval;
236 243
244 if ((i >= AR5416_MAX_CHAINS) && !conf_is_ht40(conf))
245 continue;
246
237 if (h) 247 if (h)
238 nfval = h[i].privNF; 248 nfval = h[i].privNF;
239 else 249 else
@@ -293,6 +303,9 @@ void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
293 ENABLE_REGWRITE_BUFFER(ah); 303 ENABLE_REGWRITE_BUFFER(ah);
294 for (i = 0; i < NUM_NF_READINGS; i++) { 304 for (i = 0; i < NUM_NF_READINGS; i++) {
295 if (chainmask & (1 << i)) { 305 if (chainmask & (1 << i)) {
306 if ((i >= AR5416_MAX_CHAINS) && !conf_is_ht40(conf))
307 continue;
308
296 val = REG_READ(ah, ah->nf_regs[i]); 309 val = REG_READ(ah, ah->nf_regs[i]);
297 val &= 0xFFFFFE00; 310 val &= 0xFFFFFE00;
298 val |= (((u32) (-50) << 1) & 0x1ff); 311 val |= (((u32) (-50) << 1) & 0x1ff);
@@ -396,14 +409,6 @@ void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah,
396 } 409 }
397} 410}
398 411
399s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan)
400{
401 if (!ah->curchan || !ah->curchan->noisefloor)
402 return ath9k_hw_get_default_nf(ah, chan);
403
404 return ah->curchan->noisefloor;
405}
406EXPORT_SYMBOL(ath9k_hw_getchan_noise);
407 412
408void ath9k_hw_bstuck_nfcal(struct ath_hw *ah) 413void ath9k_hw_bstuck_nfcal(struct ath_hw *ah)
409{ 414{
diff --git a/drivers/net/wireless/ath/ath9k/calib.h b/drivers/net/wireless/ath/ath9k/calib.h
index b8973eb8d858..4420780fa3b8 100644
--- a/drivers/net/wireless/ath/ath9k/calib.h
+++ b/drivers/net/wireless/ath/ath9k/calib.h
@@ -106,7 +106,6 @@ bool ath9k_hw_getnf(struct ath_hw *ah, struct ath9k_channel *chan);
106void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah, 106void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah,
107 struct ath9k_channel *chan); 107 struct ath9k_channel *chan);
108void ath9k_hw_bstuck_nfcal(struct ath_hw *ah); 108void ath9k_hw_bstuck_nfcal(struct ath_hw *ah);
109s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan);
110void ath9k_hw_reset_calibration(struct ath_hw *ah, 109void ath9k_hw_reset_calibration(struct ath_hw *ah,
111 struct ath9k_cal_list *currCal); 110 struct ath9k_cal_list *currCal);
112 111
diff --git a/drivers/net/wireless/ath/ath9k/hw-ops.h b/drivers/net/wireless/ath/ath9k/hw-ops.h
index 9dd90a85ad63..8b8f0445aef8 100644
--- a/drivers/net/wireless/ath/ath9k/hw-ops.h
+++ b/drivers/net/wireless/ath/ath9k/hw-ops.h
@@ -116,15 +116,21 @@ static inline void ath9k_hw_clr11n_aggr(struct ath_hw *ah, void *ds)
116 ath9k_hw_ops(ah)->clr11n_aggr(ah, ds); 116 ath9k_hw_ops(ah)->clr11n_aggr(ah, ds);
117} 117}
118 118
119static inline void ath9k_hw_set11n_burstduration(struct ath_hw *ah, void *ds, 119static inline void ath9k_hw_set_clrdmask(struct ath_hw *ah, void *ds, bool val)
120 u32 burstDuration)
121{ 120{
122 ath9k_hw_ops(ah)->set11n_burstduration(ah, ds, burstDuration); 121 ath9k_hw_ops(ah)->set_clrdmask(ah, ds, val);
123} 122}
124 123
125static inline void ath9k_hw_set_clrdmask(struct ath_hw *ah, void *ds, bool val) 124static inline void ath9k_hw_antdiv_comb_conf_get(struct ath_hw *ah,
125 struct ath_hw_antcomb_conf *antconf)
126{ 126{
127 ath9k_hw_ops(ah)->set_clrdmask(ah, ds, val); 127 ath9k_hw_ops(ah)->antdiv_comb_conf_get(ah, antconf);
128}
129
130static inline void ath9k_hw_antdiv_comb_conf_set(struct ath_hw *ah,
131 struct ath_hw_antcomb_conf *antconf)
132{
133 ath9k_hw_ops(ah)->antdiv_comb_conf_set(ah, antconf);
128} 134}
129 135
130/* Private hardware call ops */ 136/* Private hardware call ops */
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 58f3d4210338..b75b5dca4e29 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -2022,6 +2022,22 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
2022 } 2022 }
2023 2023
2024 2024
2025 if (AR_SREV_9485(ah)) {
2026 ant_div_ctl1 = ah->eep_ops->get_eeprom(ah, EEP_ANT_DIV_CTL1);
2027 /*
2028 * enable the diversity-combining algorithm only when
2029 * both enable_lna_div and enable_fast_div are set
2030 * Table for Diversity
2031 * ant_div_alt_lnaconf bit 0-1
2032 * ant_div_main_lnaconf bit 2-3
2033 * ant_div_alt_gaintb bit 4
2034 * ant_div_main_gaintb bit 5
2035 * enable_ant_div_lnadiv bit 6
2036 * enable_ant_fast_div bit 7
2037 */
2038 if ((ant_div_ctl1 >> 0x6) == 0x3)
2039 pCap->hw_caps |= ATH9K_HW_CAP_ANT_DIV_COMB;
2040 }
2025 2041
2026 if (AR_SREV_9485_10(ah)) { 2042 if (AR_SREV_9485_10(ah)) {
2027 pCap->pcie_lcr_extsync_en = true; 2043 pCap->pcie_lcr_extsync_en = true;
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 34ed1bd0e855..7af2773d2bfc 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -479,6 +479,10 @@ struct ath_hw_antcomb_conf {
479 u8 main_lna_conf; 479 u8 main_lna_conf;
480 u8 alt_lna_conf; 480 u8 alt_lna_conf;
481 u8 fast_div_bias; 481 u8 fast_div_bias;
482 u8 main_gaintb;
483 u8 alt_gaintb;
484 int lna1_lna2_delta;
485 u8 div_group;
482}; 486};
483 487
484/** 488/**
@@ -628,9 +632,12 @@ struct ath_hw_ops {
628 u32 numDelims); 632 u32 numDelims);
629 void (*set11n_aggr_last)(struct ath_hw *ah, void *ds); 633 void (*set11n_aggr_last)(struct ath_hw *ah, void *ds);
630 void (*clr11n_aggr)(struct ath_hw *ah, void *ds); 634 void (*clr11n_aggr)(struct ath_hw *ah, void *ds);
631 void (*set11n_burstduration)(struct ath_hw *ah, void *ds,
632 u32 burstDuration);
633 void (*set_clrdmask)(struct ath_hw *ah, void *ds, bool val); 635 void (*set_clrdmask)(struct ath_hw *ah, void *ds, bool val);
636 void (*antdiv_comb_conf_get)(struct ath_hw *ah,
637 struct ath_hw_antcomb_conf *antconf);
638 void (*antdiv_comb_conf_set)(struct ath_hw *ah,
639 struct ath_hw_antcomb_conf *antconf);
640
634}; 641};
635 642
636struct ath_nf_limits { 643struct ath_nf_limits {
@@ -906,10 +913,6 @@ void ath9k_hw_cfg_output(struct ath_hw *ah, u32 gpio,
906void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val); 913void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val);
907u32 ath9k_hw_getdefantenna(struct ath_hw *ah); 914u32 ath9k_hw_getdefantenna(struct ath_hw *ah);
908void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna); 915void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna);
909void ath9k_hw_antdiv_comb_conf_get(struct ath_hw *ah,
910 struct ath_hw_antcomb_conf *antconf);
911void ath9k_hw_antdiv_comb_conf_set(struct ath_hw *ah,
912 struct ath_hw_antcomb_conf *antconf);
913 916
914/* General Operation */ 917/* General Operation */
915bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout); 918bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout);
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c
index 9cf7a7d0e118..bd6d2b9d736f 100644
--- a/drivers/net/wireless/ath/ath9k/mac.c
+++ b/drivers/net/wireless/ath/ath9k/mac.c
@@ -430,8 +430,13 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
430 SM(qi->tqi_shretry, AR_D_RETRY_LIMIT_FR_SH)); 430 SM(qi->tqi_shretry, AR_D_RETRY_LIMIT_FR_SH));
431 431
432 REG_WRITE(ah, AR_QMISC(q), AR_Q_MISC_DCU_EARLY_TERM_REQ); 432 REG_WRITE(ah, AR_QMISC(q), AR_Q_MISC_DCU_EARLY_TERM_REQ);
433 REG_WRITE(ah, AR_DMISC(q), 433
434 AR_D_MISC_CW_BKOFF_EN | AR_D_MISC_FRAG_WAIT_EN | 0x2); 434 if (AR_SREV_9340(ah))
435 REG_WRITE(ah, AR_DMISC(q),
436 AR_D_MISC_CW_BKOFF_EN | AR_D_MISC_FRAG_WAIT_EN | 0x1);
437 else
438 REG_WRITE(ah, AR_DMISC(q),
439 AR_D_MISC_CW_BKOFF_EN | AR_D_MISC_FRAG_WAIT_EN | 0x2);
435 440
436 if (qi->tqi_cbrPeriod) { 441 if (qi->tqi_cbrPeriod) {
437 REG_WRITE(ah, AR_QCBRCFG(q), 442 REG_WRITE(ah, AR_QCBRCFG(q),
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index c3dbf2661a3f..45303bdbc465 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -689,6 +689,17 @@ void ath9k_tasklet(unsigned long data)
689 !ath9k_hw_check_alive(ah)) 689 !ath9k_hw_check_alive(ah))
690 ieee80211_queue_work(sc->hw, &sc->hw_check_work); 690 ieee80211_queue_work(sc->hw, &sc->hw_check_work);
691 691
692 if ((status & ATH9K_INT_TSFOOR) && sc->ps_enabled) {
693 /*
694 * TSF sync does not look correct; remain awake to sync with
695 * the next Beacon.
696 */
697 ath_dbg(common, ATH_DBG_PS,
698 "TSFOOR - Sync with next Beacon\n");
699 sc->ps_flags |= PS_WAIT_FOR_BEACON | PS_BEACON_SYNC |
700 PS_TSFOOR_SYNC;
701 }
702
692 if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) 703 if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
693 rxmask = (ATH9K_INT_RXHP | ATH9K_INT_RXLP | ATH9K_INT_RXEOL | 704 rxmask = (ATH9K_INT_RXHP | ATH9K_INT_RXLP | ATH9K_INT_RXEOL |
694 ATH9K_INT_RXORN); 705 ATH9K_INT_RXORN);
@@ -711,16 +722,6 @@ void ath9k_tasklet(unsigned long data)
711 ath_tx_tasklet(sc); 722 ath_tx_tasklet(sc);
712 } 723 }
713 724
714 if ((status & ATH9K_INT_TSFOOR) && sc->ps_enabled) {
715 /*
716 * TSF sync does not look correct; remain awake to sync with
717 * the next Beacon.
718 */
719 ath_dbg(common, ATH_DBG_PS,
720 "TSFOOR - Sync with next Beacon\n");
721 sc->ps_flags |= PS_WAIT_FOR_BEACON | PS_BEACON_SYNC;
722 }
723
724 if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) 725 if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
725 if (status & ATH9K_INT_GENTIMER) 726 if (status & ATH9K_INT_GENTIMER)
726 ath_gen_timer_isr(sc->sc_ah); 727 ath_gen_timer_isr(sc->sc_ah);
@@ -1384,7 +1385,9 @@ static void ath9k_calculate_summary_state(struct ieee80211_hw *hw,
1384 ath9k_hw_set_tsfadjust(ah, 0); 1385 ath9k_hw_set_tsfadjust(ah, 0);
1385 sc->sc_flags &= ~SC_OP_TSF_RESET; 1386 sc->sc_flags &= ~SC_OP_TSF_RESET;
1386 1387
1387 if (iter_data.nwds + iter_data.nmeshes) 1388 if (iter_data.nmeshes)
1389 ah->opmode = NL80211_IFTYPE_MESH_POINT;
1390 else if (iter_data.nwds)
1388 ah->opmode = NL80211_IFTYPE_AP; 1391 ah->opmode = NL80211_IFTYPE_AP;
1389 else if (iter_data.nadhocs) 1392 else if (iter_data.nadhocs)
1390 ah->opmode = NL80211_IFTYPE_ADHOC; 1393 ah->opmode = NL80211_IFTYPE_ADHOC;
@@ -1408,6 +1411,7 @@ static void ath9k_calculate_summary_state(struct ieee80211_hw *hw,
1408 1411
1409 /* Set up ANI */ 1412 /* Set up ANI */
1410 if ((iter_data.naps + iter_data.nadhocs) > 0) { 1413 if ((iter_data.naps + iter_data.nadhocs) > 0) {
1414 sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER;
1411 sc->sc_flags |= SC_OP_ANI_RUN; 1415 sc->sc_flags |= SC_OP_ANI_RUN;
1412 ath_start_ani(common); 1416 ath_start_ani(common);
1413 } else { 1417 } else {
@@ -1778,6 +1782,11 @@ static int ath9k_sta_add(struct ieee80211_hw *hw,
1778 struct ieee80211_key_conf ps_key = { }; 1782 struct ieee80211_key_conf ps_key = { };
1779 1783
1780 ath_node_attach(sc, sta); 1784 ath_node_attach(sc, sta);
1785
1786 if (vif->type != NL80211_IFTYPE_AP &&
1787 vif->type != NL80211_IFTYPE_AP_VLAN)
1788 return 0;
1789
1781 an->ps_key = ath_key_config(common, vif, sta, &ps_key); 1790 an->ps_key = ath_key_config(common, vif, sta, &ps_key);
1782 1791
1783 return 0; 1792 return 0;
@@ -2039,9 +2048,6 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
2039 if (changed & BSS_CHANGED_BSSID) { 2048 if (changed & BSS_CHANGED_BSSID) {
2040 ath9k_config_bss(sc, vif); 2049 ath9k_config_bss(sc, vif);
2041 2050
2042 /* Set aggregation protection mode parameters */
2043 sc->config.ath_aggr_prot = 0;
2044
2045 ath_dbg(common, ATH_DBG_CONFIG, "BSSID: %pM aid: 0x%x\n", 2051 ath_dbg(common, ATH_DBG_CONFIG, "BSSID: %pM aid: 0x%x\n",
2046 common->curbssid, common->curaid); 2052 common->curbssid, common->curaid);
2047 } 2053 }
@@ -2261,6 +2267,7 @@ static void ath9k_flush(struct ieee80211_hw *hw, bool drop)
2261 struct ath_softc *sc = hw->priv; 2267 struct ath_softc *sc = hw->priv;
2262 int timeout = 200; /* ms */ 2268 int timeout = 200; /* ms */
2263 int i, j; 2269 int i, j;
2270 bool drain_txq;
2264 2271
2265 mutex_lock(&sc->mutex); 2272 mutex_lock(&sc->mutex);
2266 cancel_delayed_work_sync(&sc->tx_complete_work); 2273 cancel_delayed_work_sync(&sc->tx_complete_work);
@@ -2269,7 +2276,7 @@ static void ath9k_flush(struct ieee80211_hw *hw, bool drop)
2269 timeout = 1; 2276 timeout = 1;
2270 2277
2271 for (j = 0; j < timeout; j++) { 2278 for (j = 0; j < timeout; j++) {
2272 int npend = 0; 2279 bool npend = false;
2273 2280
2274 if (j) 2281 if (j)
2275 usleep_range(1000, 2000); 2282 usleep_range(1000, 2000);
@@ -2278,7 +2285,10 @@ static void ath9k_flush(struct ieee80211_hw *hw, bool drop)
2278 if (!ATH_TXQ_SETUP(sc, i)) 2285 if (!ATH_TXQ_SETUP(sc, i))
2279 continue; 2286 continue;
2280 2287
2281 npend += ath9k_has_pending_frames(sc, &sc->tx.txq[i]); 2288 npend = ath9k_has_pending_frames(sc, &sc->tx.txq[i]);
2289
2290 if (npend)
2291 break;
2282 } 2292 }
2283 2293
2284 if (!npend) 2294 if (!npend)
@@ -2286,7 +2296,10 @@ static void ath9k_flush(struct ieee80211_hw *hw, bool drop)
2286 } 2296 }
2287 2297
2288 ath9k_ps_wakeup(sc); 2298 ath9k_ps_wakeup(sc);
2289 if (!ath_drain_all_txq(sc, false)) 2299 spin_lock_bh(&sc->sc_pcu_lock);
2300 drain_txq = ath_drain_all_txq(sc, false);
2301 spin_unlock_bh(&sc->sc_pcu_lock);
2302 if (!drain_txq)
2290 ath_reset(sc, false); 2303 ath_reset(sc, false);
2291 ath9k_ps_restore(sc); 2304 ath9k_ps_restore(sc);
2292 ieee80211_wake_queues(hw); 2305 ieee80211_wake_queues(hw);
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index c5b7cbe59bfa..4f52e0429f99 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -28,6 +28,33 @@ static inline bool ath_is_alt_ant_ratio_better(int alt_ratio, int maxdelta,
28 (alt_rssi_avg > main_rssi_avg + mindelta)) && (pkt_count > 50); 28 (alt_rssi_avg > main_rssi_avg + mindelta)) && (pkt_count > 50);
29} 29}
30 30
31static inline bool ath_ant_div_comb_alt_check(u8 div_group, int alt_ratio,
32 int curr_main_set, int curr_alt_set,
33 int alt_rssi_avg, int main_rssi_avg)
34{
35 bool result = false;
36 switch (div_group) {
37 case 0:
38 if (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)
39 result = true;
40 break;
41 case 1:
42 if ((((curr_main_set == ATH_ANT_DIV_COMB_LNA2) &&
43 (curr_alt_set == ATH_ANT_DIV_COMB_LNA1) &&
44 (alt_rssi_avg >= (main_rssi_avg - 5))) ||
45 ((curr_main_set == ATH_ANT_DIV_COMB_LNA1) &&
46 (curr_alt_set == ATH_ANT_DIV_COMB_LNA2) &&
47 (alt_rssi_avg >= (main_rssi_avg - 2)))) &&
48 (alt_rssi_avg >= 4))
49 result = true;
50 else
51 result = false;
52 break;
53 }
54
55 return result;
56}
57
31static inline bool ath9k_check_auto_sleep(struct ath_softc *sc) 58static inline bool ath9k_check_auto_sleep(struct ath_softc *sc)
32{ 59{
33 return sc->ps_enabled && 60 return sc->ps_enabled &&
@@ -572,6 +599,7 @@ static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb)
572 ath_dbg(common, ATH_DBG_PS, 599 ath_dbg(common, ATH_DBG_PS,
573 "Reconfigure Beacon timers based on timestamp from the AP\n"); 600 "Reconfigure Beacon timers based on timestamp from the AP\n");
574 ath_set_beacon(sc); 601 ath_set_beacon(sc);
602 sc->ps_flags &= ~PS_TSFOOR_SYNC;
575 } 603 }
576 604
577 if (ath_beacon_dtim_pending_cab(skb)) { 605 if (ath_beacon_dtim_pending_cab(skb)) {
@@ -916,7 +944,8 @@ static void ath9k_process_rssi(struct ath_common *common,
916 int last_rssi; 944 int last_rssi;
917 __le16 fc; 945 __le16 fc;
918 946
919 if (ah->opmode != NL80211_IFTYPE_STATION) 947 if ((ah->opmode != NL80211_IFTYPE_STATION) &&
948 (ah->opmode != NL80211_IFTYPE_ADHOC))
920 return; 949 return;
921 950
922 fc = hdr->frame_control; 951 fc = hdr->frame_control;
@@ -1288,49 +1317,138 @@ static void ath_select_ant_div_from_quick_scan(struct ath_ant_comb *antcomb,
1288 } 1317 }
1289} 1318}
1290 1319
1291static void ath_ant_div_conf_fast_divbias(struct ath_hw_antcomb_conf *ant_conf) 1320static void ath_ant_div_conf_fast_divbias(struct ath_hw_antcomb_conf *ant_conf,
1321 struct ath_ant_comb *antcomb, int alt_ratio)
1292{ 1322{
1293 /* Adjust the fast_div_bias based on main and alt lna conf */ 1323 if (ant_conf->div_group == 0) {
1294 switch ((ant_conf->main_lna_conf << 4) | ant_conf->alt_lna_conf) { 1324 /* Adjust the fast_div_bias based on main and alt lna conf */
1295 case (0x01): /* A-B LNA2 */ 1325 switch ((ant_conf->main_lna_conf << 4) |
1296 ant_conf->fast_div_bias = 0x3b; 1326 ant_conf->alt_lna_conf) {
1297 break; 1327 case (0x01): /* A-B LNA2 */
1298 case (0x02): /* A-B LNA1 */ 1328 ant_conf->fast_div_bias = 0x3b;
1299 ant_conf->fast_div_bias = 0x3d; 1329 break;
1300 break; 1330 case (0x02): /* A-B LNA1 */
1301 case (0x03): /* A-B A+B */ 1331 ant_conf->fast_div_bias = 0x3d;
1302 ant_conf->fast_div_bias = 0x1; 1332 break;
1303 break; 1333 case (0x03): /* A-B A+B */
1304 case (0x10): /* LNA2 A-B */ 1334 ant_conf->fast_div_bias = 0x1;
1305 ant_conf->fast_div_bias = 0x7; 1335 break;
1306 break; 1336 case (0x10): /* LNA2 A-B */
1307 case (0x12): /* LNA2 LNA1 */ 1337 ant_conf->fast_div_bias = 0x7;
1308 ant_conf->fast_div_bias = 0x2; 1338 break;
1309 break; 1339 case (0x12): /* LNA2 LNA1 */
1310 case (0x13): /* LNA2 A+B */ 1340 ant_conf->fast_div_bias = 0x2;
1311 ant_conf->fast_div_bias = 0x7; 1341 break;
1312 break; 1342 case (0x13): /* LNA2 A+B */
1313 case (0x20): /* LNA1 A-B */ 1343 ant_conf->fast_div_bias = 0x7;
1314 ant_conf->fast_div_bias = 0x6; 1344 break;
1315 break; 1345 case (0x20): /* LNA1 A-B */
1316 case (0x21): /* LNA1 LNA2 */ 1346 ant_conf->fast_div_bias = 0x6;
1317 ant_conf->fast_div_bias = 0x0; 1347 break;
1318 break; 1348 case (0x21): /* LNA1 LNA2 */
1319 case (0x23): /* LNA1 A+B */ 1349 ant_conf->fast_div_bias = 0x0;
1320 ant_conf->fast_div_bias = 0x6; 1350 break;
1321 break; 1351 case (0x23): /* LNA1 A+B */
1322 case (0x30): /* A+B A-B */ 1352 ant_conf->fast_div_bias = 0x6;
1323 ant_conf->fast_div_bias = 0x1; 1353 break;
1324 break; 1354 case (0x30): /* A+B A-B */
1325 case (0x31): /* A+B LNA2 */ 1355 ant_conf->fast_div_bias = 0x1;
1326 ant_conf->fast_div_bias = 0x3b; 1356 break;
1327 break; 1357 case (0x31): /* A+B LNA2 */
1328 case (0x32): /* A+B LNA1 */ 1358 ant_conf->fast_div_bias = 0x3b;
1329 ant_conf->fast_div_bias = 0x3d; 1359 break;
1330 break; 1360 case (0x32): /* A+B LNA1 */
1331 default: 1361 ant_conf->fast_div_bias = 0x3d;
1332 break; 1362 break;
1363 default:
1364 break;
1365 }
1366 } else if (ant_conf->div_group == 2) {
1367 /* Adjust the fast_div_bias based on main and alt_lna_conf */
1368 switch ((ant_conf->main_lna_conf << 4) |
1369 ant_conf->alt_lna_conf) {
1370 case (0x01): /* A-B LNA2 */
1371 ant_conf->fast_div_bias = 0x1;
1372 ant_conf->main_gaintb = 0;
1373 ant_conf->alt_gaintb = 0;
1374 break;
1375 case (0x02): /* A-B LNA1 */
1376 ant_conf->fast_div_bias = 0x1;
1377 ant_conf->main_gaintb = 0;
1378 ant_conf->alt_gaintb = 0;
1379 break;
1380 case (0x03): /* A-B A+B */
1381 ant_conf->fast_div_bias = 0x1;
1382 ant_conf->main_gaintb = 0;
1383 ant_conf->alt_gaintb = 0;
1384 break;
1385 case (0x10): /* LNA2 A-B */
1386 if (!(antcomb->scan) &&
1387 (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO))
1388 ant_conf->fast_div_bias = 0x1;
1389 else
1390 ant_conf->fast_div_bias = 0x2;
1391 ant_conf->main_gaintb = 0;
1392 ant_conf->alt_gaintb = 0;
1393 break;
1394 case (0x12): /* LNA2 LNA1 */
1395 ant_conf->fast_div_bias = 0x1;
1396 ant_conf->main_gaintb = 0;
1397 ant_conf->alt_gaintb = 0;
1398 break;
1399 case (0x13): /* LNA2 A+B */
1400 if (!(antcomb->scan) &&
1401 (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO))
1402 ant_conf->fast_div_bias = 0x1;
1403 else
1404 ant_conf->fast_div_bias = 0x2;
1405 ant_conf->main_gaintb = 0;
1406 ant_conf->alt_gaintb = 0;
1407 break;
1408 case (0x20): /* LNA1 A-B */
1409 if (!(antcomb->scan) &&
1410 (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO))
1411 ant_conf->fast_div_bias = 0x1;
1412 else
1413 ant_conf->fast_div_bias = 0x2;
1414 ant_conf->main_gaintb = 0;
1415 ant_conf->alt_gaintb = 0;
1416 break;
1417 case (0x21): /* LNA1 LNA2 */
1418 ant_conf->fast_div_bias = 0x1;
1419 ant_conf->main_gaintb = 0;
1420 ant_conf->alt_gaintb = 0;
1421 break;
1422 case (0x23): /* LNA1 A+B */
1423 if (!(antcomb->scan) &&
1424 (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO))
1425 ant_conf->fast_div_bias = 0x1;
1426 else
1427 ant_conf->fast_div_bias = 0x2;
1428 ant_conf->main_gaintb = 0;
1429 ant_conf->alt_gaintb = 0;
1430 break;
1431 case (0x30): /* A+B A-B */
1432 ant_conf->fast_div_bias = 0x1;
1433 ant_conf->main_gaintb = 0;
1434 ant_conf->alt_gaintb = 0;
1435 break;
1436 case (0x31): /* A+B LNA2 */
1437 ant_conf->fast_div_bias = 0x1;
1438 ant_conf->main_gaintb = 0;
1439 ant_conf->alt_gaintb = 0;
1440 break;
1441 case (0x32): /* A+B LNA1 */
1442 ant_conf->fast_div_bias = 0x1;
1443 ant_conf->main_gaintb = 0;
1444 ant_conf->alt_gaintb = 0;
1445 break;
1446 default:
1447 break;
1448 }
1449
1333 } 1450 }
1451
1334} 1452}
1335 1453
1336/* Antenna diversity and combining */ 1454/* Antenna diversity and combining */
@@ -1350,8 +1468,8 @@ static void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs)
1350 main_ant_conf = (rs->rs_rssi_ctl2 >> ATH_ANT_RX_MAIN_SHIFT) & 1468 main_ant_conf = (rs->rs_rssi_ctl2 >> ATH_ANT_RX_MAIN_SHIFT) &
1351 ATH_ANT_RX_MASK; 1469 ATH_ANT_RX_MASK;
1352 1470
1353 /* Record packet only when alt_rssi is positive */ 1471 /* Record packet only when both main_rssi and alt_rssi is positive */
1354 if (alt_rssi > 0) { 1472 if (main_rssi > 0 && alt_rssi > 0) {
1355 antcomb->total_pkt_count++; 1473 antcomb->total_pkt_count++;
1356 antcomb->main_total_rssi += main_rssi; 1474 antcomb->main_total_rssi += main_rssi;
1357 antcomb->alt_total_rssi += alt_rssi; 1475 antcomb->alt_total_rssi += alt_rssi;
@@ -1411,7 +1529,9 @@ static void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs)
1411 } 1529 }
1412 1530
1413 if (!antcomb->scan) { 1531 if (!antcomb->scan) {
1414 if (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO) { 1532 if (ath_ant_div_comb_alt_check(div_ant_conf.div_group,
1533 alt_ratio, curr_main_set, curr_alt_set,
1534 alt_rssi_avg, main_rssi_avg)) {
1415 if (curr_alt_set == ATH_ANT_DIV_COMB_LNA2) { 1535 if (curr_alt_set == ATH_ANT_DIV_COMB_LNA2) {
1416 /* Switch main and alt LNA */ 1536 /* Switch main and alt LNA */
1417 div_ant_conf.main_lna_conf = 1537 div_ant_conf.main_lna_conf =
@@ -1440,7 +1560,7 @@ static void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs)
1440 } 1560 }
1441 1561
1442 if ((alt_rssi_avg < (main_rssi_avg + 1562 if ((alt_rssi_avg < (main_rssi_avg +
1443 ATH_ANT_DIV_COMB_LNA1_LNA2_DELTA))) 1563 div_ant_conf.lna1_lna2_delta)))
1444 goto div_comb_done; 1564 goto div_comb_done;
1445 } 1565 }
1446 1566
@@ -1554,8 +1674,7 @@ static void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs)
1554 antcomb->quick_scan_cnt++; 1674 antcomb->quick_scan_cnt++;
1555 1675
1556div_comb_done: 1676div_comb_done:
1557 ath_ant_div_conf_fast_divbias(&div_ant_conf); 1677 ath_ant_div_conf_fast_divbias(&div_ant_conf, antcomb, alt_ratio);
1558
1559 ath9k_hw_antdiv_comb_conf_set(sc->sc_ah, &div_ant_conf); 1678 ath9k_hw_antdiv_comb_conf_set(sc->sc_ah, &div_ant_conf);
1560 1679
1561 antcomb->scan_start_time = jiffies; 1680 antcomb->scan_start_time = jiffies;
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 7b91b2aa6240..97dd1fac98b6 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -1663,8 +1663,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len)
1663 rix = rates[i].idx; 1663 rix = rates[i].idx;
1664 series[i].Tries = rates[i].count; 1664 series[i].Tries = rates[i].count;
1665 1665
1666 if ((sc->config.ath_aggr_prot && bf_isaggr(bf)) || 1666 if (rates[i].flags & IEEE80211_TX_RC_USE_RTS_CTS) {
1667 (rates[i].flags & IEEE80211_TX_RC_USE_RTS_CTS)) {
1668 series[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS; 1667 series[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS;
1669 flags |= ATH9K_TXDESC_RTSENA; 1668 flags |= ATH9K_TXDESC_RTSENA;
1670 } else if (rates[i].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) { 1669 } else if (rates[i].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
@@ -1733,8 +1732,6 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len)
1733 !is_pspoll, ctsrate, 1732 !is_pspoll, ctsrate,
1734 0, series, 4, flags); 1733 0, series, 4, flags);
1735 1734
1736 if (sc->config.ath_aggr_prot && flags)
1737 ath9k_hw_set11n_burstduration(sc->sc_ah, bf->bf_desc, 8192);
1738} 1735}
1739 1736
1740static struct ath_buf *ath_tx_setup_buffer(struct ieee80211_hw *hw, 1737static struct ath_buf *ath_tx_setup_buffer(struct ieee80211_hw *hw,
@@ -1848,6 +1845,7 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
1848 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 1845 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
1849 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 1846 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1850 struct ieee80211_sta *sta = info->control.sta; 1847 struct ieee80211_sta *sta = info->control.sta;
1848 struct ieee80211_vif *vif = info->control.vif;
1851 struct ath_softc *sc = hw->priv; 1849 struct ath_softc *sc = hw->priv;
1852 struct ath_txq *txq = txctl->txq; 1850 struct ath_txq *txq = txctl->txq;
1853 struct ath_buf *bf; 1851 struct ath_buf *bf;
@@ -1885,6 +1883,11 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
1885 memmove(skb->data, skb->data + padsize, padpos); 1883 memmove(skb->data, skb->data + padsize, padpos);
1886 } 1884 }
1887 1885
1886 if ((vif && vif->type != NL80211_IFTYPE_AP &&
1887 vif->type != NL80211_IFTYPE_AP_VLAN) ||
1888 !ieee80211_is_data(hdr->frame_control))
1889 info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT;
1890
1888 setup_frame_info(hw, skb, frmlen); 1891 setup_frame_info(hw, skb, frmlen);
1889 1892
1890 /* 1893 /*
diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c
index 1638468be5a3..7d5c65ea94e6 100644
--- a/drivers/net/wireless/ath/carl9170/main.c
+++ b/drivers/net/wireless/ath/carl9170/main.c
@@ -883,7 +883,7 @@ static void carl9170_op_configure_filter(struct ieee80211_hw *hw,
883 * then checking the error flags, later. 883 * then checking the error flags, later.
884 */ 884 */
885 885
886 if (changed_flags & FIF_ALLMULTI && *new_flags & FIF_ALLMULTI) 886 if (*new_flags & FIF_ALLMULTI)
887 multicast = ~0ULL; 887 multicast = ~0ULL;
888 888
889 if (multicast != ar->cur_mc_hash) 889 if (multicast != ar->cur_mc_hash)
diff --git a/drivers/net/wireless/ath/carl9170/tx.c b/drivers/net/wireless/ath/carl9170/tx.c
index bf2eff9dd582..e94084fcf6f5 100644
--- a/drivers/net/wireless/ath/carl9170/tx.c
+++ b/drivers/net/wireless/ath/carl9170/tx.c
@@ -156,10 +156,8 @@ out_rcu:
156 156
157static void carl9170_tx_accounting_free(struct ar9170 *ar, struct sk_buff *skb) 157static void carl9170_tx_accounting_free(struct ar9170 *ar, struct sk_buff *skb)
158{ 158{
159 struct ieee80211_tx_info *txinfo;
160 int queue; 159 int queue;
161 160
162 txinfo = IEEE80211_SKB_CB(skb);
163 queue = skb_get_queue_mapping(skb); 161 queue = skb_get_queue_mapping(skb);
164 162
165 spin_lock_bh(&ar->tx_stats_lock); 163 spin_lock_bh(&ar->tx_stats_lock);
@@ -380,7 +378,6 @@ static void carl9170_tx_status_process_ampdu(struct ar9170 *ar,
380{ 378{
381 struct _carl9170_tx_superframe *super = (void *) skb->data; 379 struct _carl9170_tx_superframe *super = (void *) skb->data;
382 struct ieee80211_hdr *hdr = (void *) super->frame_data; 380 struct ieee80211_hdr *hdr = (void *) super->frame_data;
383 struct carl9170_tx_info *ar_info;
384 struct ieee80211_sta *sta; 381 struct ieee80211_sta *sta;
385 struct carl9170_sta_info *sta_info; 382 struct carl9170_sta_info *sta_info;
386 struct carl9170_sta_tid *tid_info; 383 struct carl9170_sta_tid *tid_info;
@@ -391,8 +388,6 @@ static void carl9170_tx_status_process_ampdu(struct ar9170 *ar,
391 (!(super->f.mac_control & cpu_to_le16(AR9170_TX_MAC_AGGR)))) 388 (!(super->f.mac_control & cpu_to_le16(AR9170_TX_MAC_AGGR))))
392 return; 389 return;
393 390
394 ar_info = (void *) txinfo->rate_driver_data;
395
396 rcu_read_lock(); 391 rcu_read_lock();
397 sta = __carl9170_get_tx_sta(ar, skb); 392 sta = __carl9170_get_tx_sta(ar, skb);
398 if (unlikely(!sta)) 393 if (unlikely(!sta))
@@ -623,7 +618,6 @@ static void __carl9170_tx_process_status(struct ar9170 *ar,
623{ 618{
624 struct sk_buff *skb; 619 struct sk_buff *skb;
625 struct ieee80211_tx_info *txinfo; 620 struct ieee80211_tx_info *txinfo;
626 struct carl9170_tx_info *arinfo;
627 unsigned int r, t, q; 621 unsigned int r, t, q;
628 bool success = true; 622 bool success = true;
629 623
@@ -639,7 +633,6 @@ static void __carl9170_tx_process_status(struct ar9170 *ar,
639 } 633 }
640 634
641 txinfo = IEEE80211_SKB_CB(skb); 635 txinfo = IEEE80211_SKB_CB(skb);
642 arinfo = (void *) txinfo->rate_driver_data;
643 636
644 if (!(info & CARL9170_TX_STATUS_SUCCESS)) 637 if (!(info & CARL9170_TX_STATUS_SUCCESS))
645 success = false; 638 success = false;
@@ -1321,7 +1314,6 @@ static bool carl9170_tx_ampdu_queue(struct ar9170 *ar,
1321 struct carl9170_sta_info *sta_info; 1314 struct carl9170_sta_info *sta_info;
1322 struct carl9170_sta_tid *agg; 1315 struct carl9170_sta_tid *agg;
1323 struct sk_buff *iter; 1316 struct sk_buff *iter;
1324 unsigned int max;
1325 u16 tid, seq, qseq, off; 1317 u16 tid, seq, qseq, off;
1326 bool run = false; 1318 bool run = false;
1327 1319
@@ -1331,7 +1323,6 @@ static bool carl9170_tx_ampdu_queue(struct ar9170 *ar,
1331 1323
1332 rcu_read_lock(); 1324 rcu_read_lock();
1333 agg = rcu_dereference(sta_info->agg[tid]); 1325 agg = rcu_dereference(sta_info->agg[tid]);
1334 max = sta_info->ampdu_max_len;
1335 1326
1336 if (!agg) 1327 if (!agg)
1337 goto err_unlock_rcu; 1328 goto err_unlock_rcu;
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 5af40d9170a0..5a43984bdcea 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -2686,6 +2686,17 @@ out:
2686 dev->mac_suspended++; 2686 dev->mac_suspended++;
2687} 2687}
2688 2688
2689/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/MacPhyClkSet */
2690void b43_mac_phy_clock_set(struct b43_wldev *dev, bool on)
2691{
2692 u32 tmslow = ssb_read32(dev->dev, SSB_TMSLOW);
2693 if (on)
2694 tmslow |= B43_TMSLOW_MACPHYCLKEN;
2695 else
2696 tmslow &= ~B43_TMSLOW_MACPHYCLKEN;
2697 ssb_write32(dev->dev, SSB_TMSLOW, tmslow);
2698}
2699
2689static void b43_adjust_opmode(struct b43_wldev *dev) 2700static void b43_adjust_opmode(struct b43_wldev *dev)
2690{ 2701{
2691 struct b43_wl *wl = dev->wl; 2702 struct b43_wl *wl = dev->wl;
@@ -2842,7 +2853,7 @@ static int b43_chip_init(struct b43_wldev *dev)
2842{ 2853{
2843 struct b43_phy *phy = &dev->phy; 2854 struct b43_phy *phy = &dev->phy;
2844 int err; 2855 int err;
2845 u32 value32, macctl; 2856 u32 macctl;
2846 u16 value16; 2857 u16 value16;
2847 2858
2848 /* Initialize the MAC control */ 2859 /* Initialize the MAC control */
@@ -2920,9 +2931,7 @@ static int b43_chip_init(struct b43_wldev *dev)
2920 b43_write32(dev, B43_MMIO_DMA4_IRQ_MASK, 0x0000DC00); 2931 b43_write32(dev, B43_MMIO_DMA4_IRQ_MASK, 0x0000DC00);
2921 b43_write32(dev, B43_MMIO_DMA5_IRQ_MASK, 0x0000DC00); 2932 b43_write32(dev, B43_MMIO_DMA5_IRQ_MASK, 0x0000DC00);
2922 2933
2923 value32 = ssb_read32(dev->dev, SSB_TMSLOW); 2934 b43_mac_phy_clock_set(dev, true);
2924 value32 |= 0x00100000;
2925 ssb_write32(dev->dev, SSB_TMSLOW, value32);
2926 2935
2927 b43_write16(dev, B43_MMIO_POWERUP_DELAY, 2936 b43_write16(dev, B43_MMIO_POWERUP_DELAY,
2928 dev->dev->bus->chipco.fast_pwrup_delay); 2937 dev->dev->bus->chipco.fast_pwrup_delay);
@@ -4213,33 +4222,18 @@ static void b43_bluetooth_coext_disable(struct b43_wldev *dev)
4213 4222
4214static void b43_imcfglo_timeouts_workaround(struct b43_wldev *dev) 4223static void b43_imcfglo_timeouts_workaround(struct b43_wldev *dev)
4215{ 4224{
4216#ifdef CONFIG_SSB_DRIVER_PCICORE
4217 struct ssb_bus *bus = dev->dev->bus; 4225 struct ssb_bus *bus = dev->dev->bus;
4218 u32 tmp; 4226 u32 tmp;
4219 4227
4220 if (bus->pcicore.dev && 4228 if ((bus->chip_id == 0x4311 && bus->chip_rev == 2) ||
4221 bus->pcicore.dev->id.coreid == SSB_DEV_PCI && 4229 (bus->chip_id == 0x4312)) {
4222 bus->pcicore.dev->id.revision <= 5) {
4223 /* IMCFGLO timeouts workaround. */
4224 tmp = ssb_read32(dev->dev, SSB_IMCFGLO); 4230 tmp = ssb_read32(dev->dev, SSB_IMCFGLO);
4225 switch (bus->bustype) { 4231 tmp &= ~SSB_IMCFGLO_REQTO;
4226 case SSB_BUSTYPE_PCI: 4232 tmp &= ~SSB_IMCFGLO_SERTO;
4227 case SSB_BUSTYPE_PCMCIA: 4233 tmp |= 0x3;
4228 tmp &= ~SSB_IMCFGLO_REQTO;
4229 tmp &= ~SSB_IMCFGLO_SERTO;
4230 tmp |= 0x32;
4231 break;
4232 case SSB_BUSTYPE_SSB:
4233 tmp &= ~SSB_IMCFGLO_REQTO;
4234 tmp &= ~SSB_IMCFGLO_SERTO;
4235 tmp |= 0x53;
4236 break;
4237 default:
4238 break;
4239 }
4240 ssb_write32(dev->dev, SSB_IMCFGLO, tmp); 4234 ssb_write32(dev->dev, SSB_IMCFGLO, tmp);
4235 ssb_commit_settings(bus);
4241 } 4236 }
4242#endif /* CONFIG_SSB_DRIVER_PCICORE */
4243} 4237}
4244 4238
4245static void b43_set_synth_pu_delay(struct b43_wldev *dev, bool idle) 4239static void b43_set_synth_pu_delay(struct b43_wldev *dev, bool idle)
@@ -4863,25 +4857,8 @@ static void b43_one_core_detach(struct ssb_device *dev)
4863static int b43_one_core_attach(struct ssb_device *dev, struct b43_wl *wl) 4857static int b43_one_core_attach(struct ssb_device *dev, struct b43_wl *wl)
4864{ 4858{
4865 struct b43_wldev *wldev; 4859 struct b43_wldev *wldev;
4866 struct pci_dev *pdev;
4867 int err = -ENOMEM; 4860 int err = -ENOMEM;
4868 4861
4869 if (!list_empty(&wl->devlist)) {
4870 /* We are not the first core on this chip. */
4871 pdev = (dev->bus->bustype == SSB_BUSTYPE_PCI) ? dev->bus->host_pci : NULL;
4872 /* Only special chips support more than one wireless
4873 * core, although some of the other chips have more than
4874 * one wireless core as well. Check for this and
4875 * bail out early.
4876 */
4877 if (!pdev ||
4878 ((pdev->device != 0x4321) &&
4879 (pdev->device != 0x4313) && (pdev->device != 0x431A))) {
4880 b43dbg(wl, "Ignoring unconnected 802.11 core\n");
4881 return -ENODEV;
4882 }
4883 }
4884
4885 wldev = kzalloc(sizeof(*wldev), GFP_KERNEL); 4862 wldev = kzalloc(sizeof(*wldev), GFP_KERNEL);
4886 if (!wldev) 4863 if (!wldev)
4887 goto out; 4864 goto out;
@@ -5002,7 +4979,7 @@ out:
5002 return err; 4979 return err;
5003} 4980}
5004 4981
5005static int b43_probe(struct ssb_device *dev, const struct ssb_device_id *id) 4982static int b43_ssb_probe(struct ssb_device *dev, const struct ssb_device_id *id)
5006{ 4983{
5007 struct b43_wl *wl; 4984 struct b43_wl *wl;
5008 int err; 4985 int err;
@@ -5040,7 +5017,7 @@ static int b43_probe(struct ssb_device *dev, const struct ssb_device_id *id)
5040 return err; 5017 return err;
5041} 5018}
5042 5019
5043static void b43_remove(struct ssb_device *dev) 5020static void b43_ssb_remove(struct ssb_device *dev)
5044{ 5021{
5045 struct b43_wl *wl = ssb_get_devtypedata(dev); 5022 struct b43_wl *wl = ssb_get_devtypedata(dev);
5046 struct b43_wldev *wldev = ssb_get_drvdata(dev); 5023 struct b43_wldev *wldev = ssb_get_drvdata(dev);
@@ -5083,8 +5060,8 @@ void b43_controller_restart(struct b43_wldev *dev, const char *reason)
5083static struct ssb_driver b43_ssb_driver = { 5060static struct ssb_driver b43_ssb_driver = {
5084 .name = KBUILD_MODNAME, 5061 .name = KBUILD_MODNAME,
5085 .id_table = b43_ssb_tbl, 5062 .id_table = b43_ssb_tbl,
5086 .probe = b43_probe, 5063 .probe = b43_ssb_probe,
5087 .remove = b43_remove, 5064 .remove = b43_ssb_remove,
5088}; 5065};
5089 5066
5090static void b43_print_driverinfo(void) 5067static void b43_print_driverinfo(void)
diff --git a/drivers/net/wireless/b43/main.h b/drivers/net/wireless/b43/main.h
index 40db03678d9f..a0d327f13183 100644
--- a/drivers/net/wireless/b43/main.h
+++ b/drivers/net/wireless/b43/main.h
@@ -133,6 +133,7 @@ void b43_power_saving_ctl_bits(struct b43_wldev *dev, unsigned int ps_flags);
133 133
134void b43_mac_suspend(struct b43_wldev *dev); 134void b43_mac_suspend(struct b43_wldev *dev);
135void b43_mac_enable(struct b43_wldev *dev); 135void b43_mac_enable(struct b43_wldev *dev);
136void b43_mac_phy_clock_set(struct b43_wldev *dev, bool on);
136 137
137 138
138struct b43_request_fw_context; 139struct b43_request_fw_context;
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c
index 6755063f955a..b075a3f82a43 100644
--- a/drivers/net/wireless/b43/phy_n.c
+++ b/drivers/net/wireless/b43/phy_n.c
@@ -3540,17 +3540,6 @@ static int b43_nphy_cal_rx_iq(struct b43_wldev *dev,
3540 return b43_nphy_rev2_cal_rx_iq(dev, target, type, debug); 3540 return b43_nphy_rev2_cal_rx_iq(dev, target, type, debug);
3541} 3541}
3542 3542
3543/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/MacPhyClkSet */
3544static void b43_nphy_mac_phy_clock_set(struct b43_wldev *dev, bool on)
3545{
3546 u32 tmslow = ssb_read32(dev->dev, SSB_TMSLOW);
3547 if (on)
3548 tmslow |= B43_TMSLOW_MACPHYCLKEN;
3549 else
3550 tmslow &= ~B43_TMSLOW_MACPHYCLKEN;
3551 ssb_write32(dev->dev, SSB_TMSLOW, tmslow);
3552}
3553
3554/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RxCoreSetState */ 3543/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RxCoreSetState */
3555static void b43_nphy_set_rx_core_state(struct b43_wldev *dev, u8 mask) 3544static void b43_nphy_set_rx_core_state(struct b43_wldev *dev, u8 mask)
3556{ 3545{
@@ -3691,7 +3680,7 @@ int b43_phy_initn(struct b43_wldev *dev)
3691 b43_phy_write(dev, B43_NPHY_BBCFG, tmp & ~B43_NPHY_BBCFG_RSTCCA); 3680 b43_phy_write(dev, B43_NPHY_BBCFG, tmp & ~B43_NPHY_BBCFG_RSTCCA);
3692 b43_nphy_bmac_clock_fgc(dev, 0); 3681 b43_nphy_bmac_clock_fgc(dev, 0);
3693 3682
3694 b43_nphy_mac_phy_clock_set(dev, true); 3683 b43_mac_phy_clock_set(dev, true);
3695 3684
3696 b43_nphy_pa_override(dev, false); 3685 b43_nphy_pa_override(dev, false);
3697 b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RX2TX); 3686 b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RX2TX);
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c
index c7fd73e3ad76..1ab8861dd43a 100644
--- a/drivers/net/wireless/b43legacy/main.c
+++ b/drivers/net/wireless/b43legacy/main.c
@@ -2234,7 +2234,7 @@ static int b43legacy_chip_init(struct b43legacy_wldev *dev)
2234 b43legacy_write32(dev, B43legacy_MMIO_DMA5_IRQ_MASK, 0x0000DC00); 2234 b43legacy_write32(dev, B43legacy_MMIO_DMA5_IRQ_MASK, 0x0000DC00);
2235 2235
2236 value32 = ssb_read32(dev->dev, SSB_TMSLOW); 2236 value32 = ssb_read32(dev->dev, SSB_TMSLOW);
2237 value32 |= 0x00100000; 2237 value32 |= B43legacy_TMSLOW_MACPHYCLKEN;
2238 ssb_write32(dev->dev, SSB_TMSLOW, value32); 2238 ssb_write32(dev->dev, SSB_TMSLOW, value32);
2239 2239
2240 b43legacy_write16(dev, B43legacy_MMIO_POWERUP_DELAY, 2240 b43legacy_write16(dev, B43legacy_MMIO_POWERUP_DELAY,
@@ -3104,37 +3104,6 @@ static void setup_struct_wldev_for_init(struct b43legacy_wldev *dev)
3104 memset(&dev->noisecalc, 0, sizeof(dev->noisecalc)); 3104 memset(&dev->noisecalc, 0, sizeof(dev->noisecalc));
3105} 3105}
3106 3106
3107static void b43legacy_imcfglo_timeouts_workaround(struct b43legacy_wldev *dev)
3108{
3109#ifdef CONFIG_SSB_DRIVER_PCICORE
3110 struct ssb_bus *bus = dev->dev->bus;
3111 u32 tmp;
3112
3113 if (bus->pcicore.dev &&
3114 bus->pcicore.dev->id.coreid == SSB_DEV_PCI &&
3115 bus->pcicore.dev->id.revision <= 5) {
3116 /* IMCFGLO timeouts workaround. */
3117 tmp = ssb_read32(dev->dev, SSB_IMCFGLO);
3118 switch (bus->bustype) {
3119 case SSB_BUSTYPE_PCI:
3120 case SSB_BUSTYPE_PCMCIA:
3121 tmp &= ~SSB_IMCFGLO_REQTO;
3122 tmp &= ~SSB_IMCFGLO_SERTO;
3123 tmp |= 0x32;
3124 break;
3125 case SSB_BUSTYPE_SSB:
3126 tmp &= ~SSB_IMCFGLO_REQTO;
3127 tmp &= ~SSB_IMCFGLO_SERTO;
3128 tmp |= 0x53;
3129 break;
3130 default:
3131 break;
3132 }
3133 ssb_write32(dev->dev, SSB_IMCFGLO, tmp);
3134 }
3135#endif /* CONFIG_SSB_DRIVER_PCICORE */
3136}
3137
3138static void b43legacy_set_synth_pu_delay(struct b43legacy_wldev *dev, 3107static void b43legacy_set_synth_pu_delay(struct b43legacy_wldev *dev,
3139 bool idle) { 3108 bool idle) {
3140 u16 pu_delay = 1050; 3109 u16 pu_delay = 1050;
@@ -3278,7 +3247,6 @@ static int b43legacy_wireless_core_init(struct b43legacy_wldev *dev)
3278 /* Enable IRQ routing to this device. */ 3247 /* Enable IRQ routing to this device. */
3279 ssb_pcicore_dev_irqvecs_enable(&bus->pcicore, dev->dev); 3248 ssb_pcicore_dev_irqvecs_enable(&bus->pcicore, dev->dev);
3280 3249
3281 b43legacy_imcfglo_timeouts_workaround(dev);
3282 prepare_phy_data_for_init(dev); 3250 prepare_phy_data_for_init(dev);
3283 b43legacy_phy_calibrate(dev); 3251 b43legacy_phy_calibrate(dev);
3284 err = b43legacy_chip_init(dev); 3252 err = b43legacy_chip_init(dev);
@@ -3728,26 +3696,8 @@ static int b43legacy_one_core_attach(struct ssb_device *dev,
3728 struct b43legacy_wl *wl) 3696 struct b43legacy_wl *wl)
3729{ 3697{
3730 struct b43legacy_wldev *wldev; 3698 struct b43legacy_wldev *wldev;
3731 struct pci_dev *pdev;
3732 int err = -ENOMEM; 3699 int err = -ENOMEM;
3733 3700
3734 if (!list_empty(&wl->devlist)) {
3735 /* We are not the first core on this chip. */
3736 pdev = (dev->bus->bustype == SSB_BUSTYPE_PCI) ? dev->bus->host_pci : NULL;
3737 /* Only special chips support more than one wireless
3738 * core, although some of the other chips have more than
3739 * one wireless core as well. Check for this and
3740 * bail out early.
3741 */
3742 if (!pdev ||
3743 ((pdev->device != 0x4321) &&
3744 (pdev->device != 0x4313) &&
3745 (pdev->device != 0x431A))) {
3746 b43legacydbg(wl, "Ignoring unconnected 802.11 core\n");
3747 return -ENODEV;
3748 }
3749 }
3750
3751 wldev = kzalloc(sizeof(*wldev), GFP_KERNEL); 3701 wldev = kzalloc(sizeof(*wldev), GFP_KERNEL);
3752 if (!wldev) 3702 if (!wldev)
3753 goto out; 3703 goto out;
diff --git a/drivers/net/wireless/iwlegacy/iwl-4965-rs.c b/drivers/net/wireless/iwlegacy/iwl-4965-rs.c
index 89509392ef5d..24d149909ba3 100644
--- a/drivers/net/wireless/iwlegacy/iwl-4965-rs.c
+++ b/drivers/net/wireless/iwlegacy/iwl-4965-rs.c
@@ -2604,7 +2604,7 @@ static ssize_t iwl4965_rs_sta_dbgfs_scale_table_write(struct file *file,
2604 struct iwl_lq_sta *lq_sta = file->private_data; 2604 struct iwl_lq_sta *lq_sta = file->private_data;
2605 struct iwl_priv *priv; 2605 struct iwl_priv *priv;
2606 char buf[64]; 2606 char buf[64];
2607 int buf_size; 2607 size_t buf_size;
2608 u32 parsed_rate; 2608 u32 parsed_rate;
2609 struct iwl_station_priv *sta_priv = 2609 struct iwl_station_priv *sta_priv =
2610 container_of(lq_sta, struct iwl_station_priv, lq_sta); 2610 container_of(lq_sta, struct iwl_station_priv, lq_sta);
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig
index 17d555f2215a..ad3bdba6beed 100644
--- a/drivers/net/wireless/iwlwifi/Kconfig
+++ b/drivers/net/wireless/iwlwifi/Kconfig
@@ -102,6 +102,16 @@ config IWLWIFI_DEVICE_TRACING
102 occur. 102 occur.
103endmenu 103endmenu
104 104
105config IWLWIFI_DEVICE_SVTOOL
106 bool "iwlwifi device svtool support"
107 depends on IWLAGN
108 select NL80211_TESTMODE
109 help
110 This option enables the svtool support for iwlwifi device through
111 NL80211_TESTMODE. svtool is a software validation tool that runs in
112 the user space and interacts with the device in the kernel space
113 through the generic netlink message via NL80211_TESTMODE channel.
114
105config IWL_P2P 115config IWL_P2P
106 bool "iwlwifi experimental P2P support" 116 bool "iwlwifi experimental P2P support"
107 depends on IWLAGN 117 depends on IWLAGN
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile
index 89a41d320c36..822660483f9f 100644
--- a/drivers/net/wireless/iwlwifi/Makefile
+++ b/drivers/net/wireless/iwlwifi/Makefile
@@ -16,6 +16,7 @@ iwlagn-objs += iwl-2000.o
16 16
17iwlagn-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o 17iwlagn-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o
18iwlagn-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o 18iwlagn-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o
19iwlagn-$(CONFIG_IWLWIFI_DEVICE_SVTOOL) += iwl-sv-open.o
19 20
20CFLAGS_iwl-devtrace.o := -I$(src) 21CFLAGS_iwl-devtrace.o := -I$(src)
21 22
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index 3da8cf27dcb9..b4c81931e136 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -171,8 +171,6 @@ static int iwl1000_hw_set_hw_params(struct iwl_priv *priv)
171 171
172static struct iwl_lib_ops iwl1000_lib = { 172static struct iwl_lib_ops iwl1000_lib = {
173 .set_hw_params = iwl1000_hw_set_hw_params, 173 .set_hw_params = iwl1000_hw_set_hw_params,
174 .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl,
175 .txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl,
176 .txq_set_sched = iwlagn_txq_set_sched, 174 .txq_set_sched = iwlagn_txq_set_sched,
177 .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd, 175 .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd,
178 .txq_free_tfd = iwl_hw_txq_free_tfd, 176 .txq_free_tfd = iwl_hw_txq_free_tfd,
diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c
index bca462c47e37..89b8da7a6c8b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-2000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-2000.c
@@ -252,8 +252,6 @@ static int iwl2030_hw_channel_switch(struct iwl_priv *priv,
252 252
253static struct iwl_lib_ops iwl2000_lib = { 253static struct iwl_lib_ops iwl2000_lib = {
254 .set_hw_params = iwl2000_hw_set_hw_params, 254 .set_hw_params = iwl2000_hw_set_hw_params,
255 .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl,
256 .txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl,
257 .txq_set_sched = iwlagn_txq_set_sched, 255 .txq_set_sched = iwlagn_txq_set_sched,
258 .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd, 256 .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd,
259 .txq_free_tfd = iwl_hw_txq_free_tfd, 257 .txq_free_tfd = iwl_hw_txq_free_tfd,
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index 561f2cd65dd4..98f81df166e3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -339,8 +339,6 @@ static int iwl5000_hw_channel_switch(struct iwl_priv *priv,
339 339
340static struct iwl_lib_ops iwl5000_lib = { 340static struct iwl_lib_ops iwl5000_lib = {
341 .set_hw_params = iwl5000_hw_set_hw_params, 341 .set_hw_params = iwl5000_hw_set_hw_params,
342 .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl,
343 .txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl,
344 .txq_set_sched = iwlagn_txq_set_sched, 342 .txq_set_sched = iwlagn_txq_set_sched,
345 .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd, 343 .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd,
346 .txq_free_tfd = iwl_hw_txq_free_tfd, 344 .txq_free_tfd = iwl_hw_txq_free_tfd,
@@ -376,8 +374,6 @@ static struct iwl_lib_ops iwl5000_lib = {
376 374
377static struct iwl_lib_ops iwl5150_lib = { 375static struct iwl_lib_ops iwl5150_lib = {
378 .set_hw_params = iwl5150_hw_set_hw_params, 376 .set_hw_params = iwl5150_hw_set_hw_params,
379 .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl,
380 .txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl,
381 .txq_set_sched = iwlagn_txq_set_sched, 377 .txq_set_sched = iwlagn_txq_set_sched,
382 .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd, 378 .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd,
383 .txq_free_tfd = iwl_hw_txq_free_tfd, 379 .txq_free_tfd = iwl_hw_txq_free_tfd,
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index 6045457cc722..a7921f9a03c6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -278,8 +278,6 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv,
278 278
279static struct iwl_lib_ops iwl6000_lib = { 279static struct iwl_lib_ops iwl6000_lib = {
280 .set_hw_params = iwl6000_hw_set_hw_params, 280 .set_hw_params = iwl6000_hw_set_hw_params,
281 .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl,
282 .txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl,
283 .txq_set_sched = iwlagn_txq_set_sched, 281 .txq_set_sched = iwlagn_txq_set_sched,
284 .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd, 282 .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd,
285 .txq_free_tfd = iwl_hw_txq_free_tfd, 283 .txq_free_tfd = iwl_hw_txq_free_tfd,
@@ -316,8 +314,6 @@ static struct iwl_lib_ops iwl6000_lib = {
316 314
317static struct iwl_lib_ops iwl6030_lib = { 315static struct iwl_lib_ops iwl6030_lib = {
318 .set_hw_params = iwl6000_hw_set_hw_params, 316 .set_hw_params = iwl6000_hw_set_hw_params,
319 .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl,
320 .txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl,
321 .txq_set_sched = iwlagn_txq_set_sched, 317 .txq_set_sched = iwlagn_txq_set_sched,
322 .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd, 318 .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd,
323 .txq_free_tfd = iwl_hw_txq_free_tfd, 319 .txq_free_tfd = iwl_hw_txq_free_tfd,
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
index 49dd03f9feda..b12c72d63ccb 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
@@ -54,12 +54,6 @@ int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant)
54 } 54 }
55} 55}
56 56
57/* Currently this is the superset of everything */
58static u16 iwlagn_get_hcmd_size(u8 cmd_id, u16 len)
59{
60 return len;
61}
62
63static u16 iwlagn_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data) 57static u16 iwlagn_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data)
64{ 58{
65 u16 size = (u16)sizeof(struct iwl_addsta_cmd); 59 u16 size = (u16)sizeof(struct iwl_addsta_cmd);
@@ -332,7 +326,6 @@ struct iwl_hcmd_ops iwlagn_bt_hcmd = {
332}; 326};
333 327
334struct iwl_hcmd_utils_ops iwlagn_hcmd_utils = { 328struct iwl_hcmd_utils_ops iwlagn_hcmd_utils = {
335 .get_hcmd_size = iwlagn_get_hcmd_size,
336 .build_addsta_hcmd = iwlagn_build_addsta_hcmd, 329 .build_addsta_hcmd = iwlagn_build_addsta_hcmd,
337 .gain_computation = iwlagn_gain_computation, 330 .gain_computation = iwlagn_gain_computation,
338 .chain_noise_reset = iwlagn_chain_noise_reset, 331 .chain_noise_reset = iwlagn_chain_noise_reset,
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index dbe6295bbf23..91f26556ac23 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -3086,7 +3086,7 @@ static ssize_t rs_sta_dbgfs_scale_table_write(struct file *file,
3086 struct iwl_lq_sta *lq_sta = file->private_data; 3086 struct iwl_lq_sta *lq_sta = file->private_data;
3087 struct iwl_priv *priv; 3087 struct iwl_priv *priv;
3088 char buf[64]; 3088 char buf[64];
3089 int buf_size; 3089 size_t buf_size;
3090 u32 parsed_rate; 3090 u32 parsed_rate;
3091 struct iwl_station_priv *sta_priv = 3091 struct iwl_station_priv *sta_priv =
3092 container_of(lq_sta, struct iwl_station_priv, lq_sta); 3092 container_of(lq_sta, struct iwl_station_priv, lq_sta);
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
index 4afae1446582..342de780a366 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
@@ -98,9 +98,9 @@ static inline int get_fifo_from_tid(struct iwl_rxon_context *ctx, u16 tid)
98/** 98/**
99 * iwlagn_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array 99 * iwlagn_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array
100 */ 100 */
101void iwlagn_txq_update_byte_cnt_tbl(struct iwl_priv *priv, 101static void iwlagn_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
102 struct iwl_tx_queue *txq, 102 struct iwl_tx_queue *txq,
103 u16 byte_cnt) 103 u16 byte_cnt)
104{ 104{
105 struct iwlagn_scd_bc_tbl *scd_bc_tbl = priv->scd_bc_tbls.addr; 105 struct iwlagn_scd_bc_tbl *scd_bc_tbl = priv->scd_bc_tbls.addr;
106 int write_ptr = txq->q.write_ptr; 106 int write_ptr = txq->q.write_ptr;
@@ -112,21 +112,19 @@ void iwlagn_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
112 112
113 WARN_ON(len > 0xFFF || write_ptr >= TFD_QUEUE_SIZE_MAX); 113 WARN_ON(len > 0xFFF || write_ptr >= TFD_QUEUE_SIZE_MAX);
114 114
115 if (txq_id != priv->cmd_queue) { 115 sta_id = txq->cmd[txq->q.write_ptr]->cmd.tx.sta_id;
116 sta_id = txq->cmd[txq->q.write_ptr]->cmd.tx.sta_id; 116 sec_ctl = txq->cmd[txq->q.write_ptr]->cmd.tx.sec_ctl;
117 sec_ctl = txq->cmd[txq->q.write_ptr]->cmd.tx.sec_ctl; 117
118 118 switch (sec_ctl & TX_CMD_SEC_MSK) {
119 switch (sec_ctl & TX_CMD_SEC_MSK) { 119 case TX_CMD_SEC_CCM:
120 case TX_CMD_SEC_CCM: 120 len += CCMP_MIC_LEN;
121 len += CCMP_MIC_LEN; 121 break;
122 break; 122 case TX_CMD_SEC_TKIP:
123 case TX_CMD_SEC_TKIP: 123 len += TKIP_ICV_LEN;
124 len += TKIP_ICV_LEN; 124 break;
125 break; 125 case TX_CMD_SEC_WEP:
126 case TX_CMD_SEC_WEP: 126 len += WEP_IV_LEN + WEP_ICV_LEN;
127 len += WEP_IV_LEN + WEP_ICV_LEN; 127 break;
128 break;
129 }
130 } 128 }
131 129
132 bc_ent = cpu_to_le16((len & 0xFFF) | (sta_id << 12)); 130 bc_ent = cpu_to_le16((len & 0xFFF) | (sta_id << 12));
@@ -138,8 +136,8 @@ void iwlagn_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
138 tfd_offset[TFD_QUEUE_SIZE_MAX + write_ptr] = bc_ent; 136 tfd_offset[TFD_QUEUE_SIZE_MAX + write_ptr] = bc_ent;
139} 137}
140 138
141void iwlagn_txq_inval_byte_cnt_tbl(struct iwl_priv *priv, 139static void iwlagn_txq_inval_byte_cnt_tbl(struct iwl_priv *priv,
142 struct iwl_tx_queue *txq) 140 struct iwl_tx_queue *txq)
143{ 141{
144 struct iwlagn_scd_bc_tbl *scd_bc_tbl = priv->scd_bc_tbls.addr; 142 struct iwlagn_scd_bc_tbl *scd_bc_tbl = priv->scd_bc_tbls.addr;
145 int txq_id = txq->q.id; 143 int txq_id = txq->q.id;
@@ -539,7 +537,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
539 struct iwl_tx_cmd *tx_cmd; 537 struct iwl_tx_cmd *tx_cmd;
540 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; 538 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
541 int txq_id; 539 int txq_id;
542 dma_addr_t phys_addr; 540 dma_addr_t phys_addr = 0;
543 dma_addr_t txcmd_phys; 541 dma_addr_t txcmd_phys;
544 dma_addr_t scratch_phys; 542 dma_addr_t scratch_phys;
545 u16 len, firstlen, secondlen; 543 u16 len, firstlen, secondlen;
@@ -566,7 +564,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
566 spin_lock_irqsave(&priv->lock, flags); 564 spin_lock_irqsave(&priv->lock, flags);
567 if (iwl_is_rfkill(priv)) { 565 if (iwl_is_rfkill(priv)) {
568 IWL_DEBUG_DROP(priv, "Dropping - RF KILL\n"); 566 IWL_DEBUG_DROP(priv, "Dropping - RF KILL\n");
569 goto drop_unlock; 567 goto drop_unlock_priv;
570 } 568 }
571 569
572 fc = hdr->frame_control; 570 fc = hdr->frame_control;
@@ -591,7 +589,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
591 if (sta_id == IWL_INVALID_STATION) { 589 if (sta_id == IWL_INVALID_STATION) {
592 IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n", 590 IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n",
593 hdr->addr1); 591 hdr->addr1);
594 goto drop_unlock; 592 goto drop_unlock_priv;
595 } 593 }
596 } 594 }
597 595
@@ -635,10 +633,10 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
635 if (ieee80211_is_data_qos(fc)) { 633 if (ieee80211_is_data_qos(fc)) {
636 qc = ieee80211_get_qos_ctl(hdr); 634 qc = ieee80211_get_qos_ctl(hdr);
637 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK; 635 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
638 if (WARN_ON_ONCE(tid >= MAX_TID_COUNT)) { 636
639 spin_unlock(&priv->sta_lock); 637 if (WARN_ON_ONCE(tid >= MAX_TID_COUNT))
640 goto drop_unlock; 638 goto drop_unlock_sta;
641 } 639
642 seq_number = priv->stations[sta_id].tid[tid].seq_number; 640 seq_number = priv->stations[sta_id].tid[tid].seq_number;
643 seq_number &= IEEE80211_SCTL_SEQ; 641 seq_number &= IEEE80211_SCTL_SEQ;
644 hdr->seq_ctrl = hdr->seq_ctrl & 642 hdr->seq_ctrl = hdr->seq_ctrl &
@@ -656,18 +654,8 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
656 txq = &priv->txq[txq_id]; 654 txq = &priv->txq[txq_id];
657 q = &txq->q; 655 q = &txq->q;
658 656
659 if (unlikely(iwl_queue_space(q) < q->high_mark)) { 657 if (unlikely(iwl_queue_space(q) < q->high_mark))
660 spin_unlock(&priv->sta_lock); 658 goto drop_unlock_sta;
661 goto drop_unlock;
662 }
663
664 if (ieee80211_is_data_qos(fc)) {
665 priv->stations[sta_id].tid[tid].tfds_in_queue++;
666 if (!ieee80211_has_morefrags(fc))
667 priv->stations[sta_id].tid[tid].seq_number = seq_number;
668 }
669
670 spin_unlock(&priv->sta_lock);
671 659
672 /* Set up driver data for this TFD */ 660 /* Set up driver data for this TFD */
673 memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl_tx_info)); 661 memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl_tx_info));
@@ -731,12 +719,10 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
731 txcmd_phys = pci_map_single(priv->pci_dev, 719 txcmd_phys = pci_map_single(priv->pci_dev,
732 &out_cmd->hdr, firstlen, 720 &out_cmd->hdr, firstlen,
733 PCI_DMA_BIDIRECTIONAL); 721 PCI_DMA_BIDIRECTIONAL);
722 if (unlikely(pci_dma_mapping_error(priv->pci_dev, txcmd_phys)))
723 goto drop_unlock_sta;
734 dma_unmap_addr_set(out_meta, mapping, txcmd_phys); 724 dma_unmap_addr_set(out_meta, mapping, txcmd_phys);
735 dma_unmap_len_set(out_meta, len, firstlen); 725 dma_unmap_len_set(out_meta, len, firstlen);
736 /* Add buffer containing Tx command and MAC(!) header to TFD's
737 * first entry */
738 priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq,
739 txcmd_phys, firstlen, 1, 0);
740 726
741 if (!ieee80211_has_morefrags(hdr->frame_control)) { 727 if (!ieee80211_has_morefrags(hdr->frame_control)) {
742 txq->need_update = 1; 728 txq->need_update = 1;
@@ -751,10 +737,30 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
751 if (secondlen > 0) { 737 if (secondlen > 0) {
752 phys_addr = pci_map_single(priv->pci_dev, skb->data + hdr_len, 738 phys_addr = pci_map_single(priv->pci_dev, skb->data + hdr_len,
753 secondlen, PCI_DMA_TODEVICE); 739 secondlen, PCI_DMA_TODEVICE);
740 if (unlikely(pci_dma_mapping_error(priv->pci_dev, phys_addr))) {
741 pci_unmap_single(priv->pci_dev,
742 dma_unmap_addr(out_meta, mapping),
743 dma_unmap_len(out_meta, len),
744 PCI_DMA_BIDIRECTIONAL);
745 goto drop_unlock_sta;
746 }
747 }
748
749 if (ieee80211_is_data_qos(fc)) {
750 priv->stations[sta_id].tid[tid].tfds_in_queue++;
751 if (!ieee80211_has_morefrags(fc))
752 priv->stations[sta_id].tid[tid].seq_number = seq_number;
753 }
754
755 spin_unlock(&priv->sta_lock);
756
757 /* Attach buffers to TFD */
758 priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq,
759 txcmd_phys, firstlen, 1, 0);
760 if (secondlen > 0)
754 priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq, 761 priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq,
755 phys_addr, secondlen, 762 phys_addr, secondlen,
756 0, 0); 763 0, 0);
757 }
758 764
759 scratch_phys = txcmd_phys + sizeof(struct iwl_cmd_header) + 765 scratch_phys = txcmd_phys + sizeof(struct iwl_cmd_header) +
760 offsetof(struct iwl_tx_cmd, scratch); 766 offsetof(struct iwl_tx_cmd, scratch);
@@ -773,8 +779,8 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
773 779
774 /* Set up entry for this TFD in Tx byte-count array */ 780 /* Set up entry for this TFD in Tx byte-count array */
775 if (info->flags & IEEE80211_TX_CTL_AMPDU) 781 if (info->flags & IEEE80211_TX_CTL_AMPDU)
776 priv->cfg->ops->lib->txq_update_byte_cnt_tbl(priv, txq, 782 iwlagn_txq_update_byte_cnt_tbl(priv, txq,
777 le16_to_cpu(tx_cmd->len)); 783 le16_to_cpu(tx_cmd->len));
778 784
779 pci_dma_sync_single_for_device(priv->pci_dev, txcmd_phys, 785 pci_dma_sync_single_for_device(priv->pci_dev, txcmd_phys,
780 firstlen, PCI_DMA_BIDIRECTIONAL); 786 firstlen, PCI_DMA_BIDIRECTIONAL);
@@ -820,7 +826,9 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
820 826
821 return 0; 827 return 0;
822 828
823drop_unlock: 829drop_unlock_sta:
830 spin_unlock(&priv->sta_lock);
831drop_unlock_priv:
824 spin_unlock_irqrestore(&priv->lock, flags); 832 spin_unlock_irqrestore(&priv->lock, flags);
825 return -1; 833 return -1;
826} 834}
@@ -1253,8 +1261,7 @@ int iwlagn_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index)
1253 txq_id >= IWLAGN_FIRST_AMPDU_QUEUE); 1261 txq_id >= IWLAGN_FIRST_AMPDU_QUEUE);
1254 tx_info->skb = NULL; 1262 tx_info->skb = NULL;
1255 1263
1256 if (priv->cfg->ops->lib->txq_inval_byte_cnt_tbl) 1264 iwlagn_txq_inval_byte_cnt_tbl(priv, txq);
1257 priv->cfg->ops->lib->txq_inval_byte_cnt_tbl(priv, txq);
1258 1265
1259 priv->cfg->ops->lib->txq_free_tfd(priv, txq); 1266 priv->cfg->ops->lib->txq_free_tfd(priv, txq);
1260 } 1267 }
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
index c3ae2e44fcc9..8bda0e8d6661 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
@@ -269,7 +269,7 @@ void iwlagn_rx_calib_result(struct iwl_priv *priv,
269 iwl_calib_set(&priv->calib_results[index], pkt->u.raw, len); 269 iwl_calib_set(&priv->calib_results[index], pkt->u.raw, len);
270} 270}
271 271
272static int iwlagn_init_alive_start(struct iwl_priv *priv) 272int iwlagn_init_alive_start(struct iwl_priv *priv)
273{ 273{
274 int ret; 274 int ret;
275 275
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 003d5243542b..3ecc3198d9bf 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -102,70 +102,6 @@ void iwl_update_chain_flags(struct iwl_priv *priv)
102 } 102 }
103} 103}
104 104
105static void iwl_clear_free_frames(struct iwl_priv *priv)
106{
107 struct list_head *element;
108
109 IWL_DEBUG_INFO(priv, "%d frames on pre-allocated heap on clear.\n",
110 priv->frames_count);
111
112 while (!list_empty(&priv->free_frames)) {
113 element = priv->free_frames.next;
114 list_del(element);
115 kfree(list_entry(element, struct iwl_frame, list));
116 priv->frames_count--;
117 }
118
119 if (priv->frames_count) {
120 IWL_WARN(priv, "%d frames still in use. Did we lose one?\n",
121 priv->frames_count);
122 priv->frames_count = 0;
123 }
124}
125
126static struct iwl_frame *iwl_get_free_frame(struct iwl_priv *priv)
127{
128 struct iwl_frame *frame;
129 struct list_head *element;
130 if (list_empty(&priv->free_frames)) {
131 frame = kzalloc(sizeof(*frame), GFP_KERNEL);
132 if (!frame) {
133 IWL_ERR(priv, "Could not allocate frame!\n");
134 return NULL;
135 }
136
137 priv->frames_count++;
138 return frame;
139 }
140
141 element = priv->free_frames.next;
142 list_del(element);
143 return list_entry(element, struct iwl_frame, list);
144}
145
146static void iwl_free_frame(struct iwl_priv *priv, struct iwl_frame *frame)
147{
148 memset(frame, 0, sizeof(*frame));
149 list_add(&frame->list, &priv->free_frames);
150}
151
152static u32 iwl_fill_beacon_frame(struct iwl_priv *priv,
153 struct ieee80211_hdr *hdr,
154 int left)
155{
156 lockdep_assert_held(&priv->mutex);
157
158 if (!priv->beacon_skb)
159 return 0;
160
161 if (priv->beacon_skb->len > left)
162 return 0;
163
164 memcpy(hdr, priv->beacon_skb->data, priv->beacon_skb->len);
165
166 return priv->beacon_skb->len;
167}
168
169/* Parse the beacon frame to find the TIM element and set tim_idx & tim_size */ 105/* Parse the beacon frame to find the TIM element and set tim_idx & tim_size */
170static void iwl_set_beacon_tim(struct iwl_priv *priv, 106static void iwl_set_beacon_tim(struct iwl_priv *priv,
171 struct iwl_tx_beacon_cmd *tx_beacon_cmd, 107 struct iwl_tx_beacon_cmd *tx_beacon_cmd,
@@ -193,13 +129,18 @@ static void iwl_set_beacon_tim(struct iwl_priv *priv,
193 IWL_WARN(priv, "Unable to find TIM Element in beacon\n"); 129 IWL_WARN(priv, "Unable to find TIM Element in beacon\n");
194} 130}
195 131
196static unsigned int iwl_hw_get_beacon_cmd(struct iwl_priv *priv, 132int iwlagn_send_beacon_cmd(struct iwl_priv *priv)
197 struct iwl_frame *frame)
198{ 133{
199 struct iwl_tx_beacon_cmd *tx_beacon_cmd; 134 struct iwl_tx_beacon_cmd *tx_beacon_cmd;
135 struct iwl_host_cmd cmd = {
136 .id = REPLY_TX_BEACON,
137 .flags = CMD_SIZE_HUGE,
138 };
200 u32 frame_size; 139 u32 frame_size;
201 u32 rate_flags; 140 u32 rate_flags;
202 u32 rate; 141 u32 rate;
142 int err;
143
203 /* 144 /*
204 * We have to set up the TX command, the TX Beacon command, and the 145 * We have to set up the TX command, the TX Beacon command, and the
205 * beacon contents. 146 * beacon contents.
@@ -212,17 +153,19 @@ static unsigned int iwl_hw_get_beacon_cmd(struct iwl_priv *priv,
212 return 0; 153 return 0;
213 } 154 }
214 155
215 /* Initialize memory */ 156 if (WARN_ON(!priv->beacon_skb))
216 tx_beacon_cmd = &frame->u.beacon; 157 return -EINVAL;
217 memset(tx_beacon_cmd, 0, sizeof(*tx_beacon_cmd)); 158
159 /* Allocate beacon memory */
160 tx_beacon_cmd = kzalloc(sizeof(*tx_beacon_cmd) + priv->beacon_skb->len,
161 GFP_KERNEL);
162 if (!tx_beacon_cmd)
163 return -ENOMEM;
164
165 frame_size = priv->beacon_skb->len;
218 166
219 /* Set up TX beacon contents */ 167 /* Set up TX beacon contents */
220 frame_size = iwl_fill_beacon_frame(priv, tx_beacon_cmd->frame, 168 memcpy(tx_beacon_cmd->frame, priv->beacon_skb->data, frame_size);
221 sizeof(frame->u) - sizeof(*tx_beacon_cmd));
222 if (WARN_ON_ONCE(frame_size > MAX_MPDU_SIZE))
223 return 0;
224 if (!frame_size)
225 return 0;
226 169
227 /* Set up TX command fields */ 170 /* Set up TX command fields */
228 tx_beacon_cmd->tx.len = cpu_to_le16((u16)frame_size); 171 tx_beacon_cmd->tx.len = cpu_to_le16((u16)frame_size);
@@ -245,41 +188,16 @@ static unsigned int iwl_hw_get_beacon_cmd(struct iwl_priv *priv,
245 tx_beacon_cmd->tx.rate_n_flags = iwl_hw_set_rate_n_flags(rate, 188 tx_beacon_cmd->tx.rate_n_flags = iwl_hw_set_rate_n_flags(rate,
246 rate_flags); 189 rate_flags);
247 190
248 return sizeof(*tx_beacon_cmd) + frame_size; 191 /* Submit command */
249} 192 cmd.len = sizeof(*tx_beacon_cmd) + frame_size;
193 cmd.data = tx_beacon_cmd;
250 194
251int iwlagn_send_beacon_cmd(struct iwl_priv *priv) 195 err = iwl_send_cmd_sync(priv, &cmd);
252{
253 struct iwl_frame *frame;
254 unsigned int frame_size;
255 int rc;
256 struct iwl_host_cmd cmd = {
257 .id = REPLY_TX_BEACON,
258 .flags = CMD_SIZE_HUGE,
259 };
260
261 frame = iwl_get_free_frame(priv);
262 if (!frame) {
263 IWL_ERR(priv, "Could not obtain free frame buffer for beacon "
264 "command.\n");
265 return -ENOMEM;
266 }
267
268 frame_size = iwl_hw_get_beacon_cmd(priv, frame);
269 if (!frame_size) {
270 IWL_ERR(priv, "Error configuring the beacon command\n");
271 iwl_free_frame(priv, frame);
272 return -EINVAL;
273 }
274
275 cmd.len = frame_size;
276 cmd.data = &frame->u.cmd[0];
277
278 rc = iwl_send_cmd_sync(priv, &cmd);
279 196
280 iwl_free_frame(priv, frame); 197 /* Free temporary storage */
198 kfree(tx_beacon_cmd);
281 199
282 return rc; 200 return err;
283} 201}
284 202
285static inline dma_addr_t iwl_tfd_tb_get_addr(struct iwl_tfd *tfd, u8 idx) 203static inline dma_addr_t iwl_tfd_tb_get_addr(struct iwl_tfd *tfd, u8 idx)
@@ -776,6 +694,8 @@ static void iwl_rx_handle(struct iwl_priv *priv)
776 694
777 wake_up_all(&priv->_agn.notif_waitq); 695 wake_up_all(&priv->_agn.notif_waitq);
778 } 696 }
697 if (priv->pre_rx_handler)
698 priv->pre_rx_handler(priv, rxb);
779 699
780 /* Based on type of command response or notification, 700 /* Based on type of command response or notification,
781 * handle those that need handling via function in 701 * handle those that need handling via function in
@@ -2211,7 +2131,7 @@ static int iwlagn_send_calib_cfg_rt(struct iwl_priv *priv, u32 cfg)
2211 * from protocol/runtime uCode (initialization uCode's 2131 * from protocol/runtime uCode (initialization uCode's
2212 * Alive gets handled by iwl_init_alive_start()). 2132 * Alive gets handled by iwl_init_alive_start()).
2213 */ 2133 */
2214static int iwl_alive_start(struct iwl_priv *priv) 2134int iwl_alive_start(struct iwl_priv *priv)
2215{ 2135{
2216 int ret = 0; 2136 int ret = 0;
2217 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; 2137 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
@@ -2354,9 +2274,6 @@ static void __iwl_down(struct iwl_priv *priv)
2354 2274
2355 dev_kfree_skb(priv->beacon_skb); 2275 dev_kfree_skb(priv->beacon_skb);
2356 priv->beacon_skb = NULL; 2276 priv->beacon_skb = NULL;
2357
2358 /* clear out any free frames */
2359 iwl_clear_free_frames(priv);
2360} 2277}
2361 2278
2362static void iwl_down(struct iwl_priv *priv) 2279static void iwl_down(struct iwl_priv *priv)
@@ -3414,8 +3331,6 @@ static int iwl_init_drv(struct iwl_priv *priv)
3414 spin_lock_init(&priv->sta_lock); 3331 spin_lock_init(&priv->sta_lock);
3415 spin_lock_init(&priv->hcmd_lock); 3332 spin_lock_init(&priv->hcmd_lock);
3416 3333
3417 INIT_LIST_HEAD(&priv->free_frames);
3418
3419 mutex_init(&priv->mutex); 3334 mutex_init(&priv->mutex);
3420 3335
3421 priv->ieee_channels = NULL; 3336 priv->ieee_channels = NULL;
@@ -3507,6 +3422,7 @@ struct ieee80211_ops iwlagn_hw_ops = {
3507 .cancel_remain_on_channel = iwl_mac_cancel_remain_on_channel, 3422 .cancel_remain_on_channel = iwl_mac_cancel_remain_on_channel,
3508 .offchannel_tx = iwl_mac_offchannel_tx, 3423 .offchannel_tx = iwl_mac_offchannel_tx,
3509 .offchannel_tx_cancel_wait = iwl_mac_offchannel_tx_cancel_wait, 3424 .offchannel_tx_cancel_wait = iwl_mac_offchannel_tx_cancel_wait,
3425 CFG80211_TESTMODE_CMD(iwl_testmode_cmd)
3510}; 3426};
3511 3427
3512static u32 iwl_hw_detect(struct iwl_priv *priv) 3428static u32 iwl_hw_detect(struct iwl_priv *priv)
@@ -3816,6 +3732,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
3816 3732
3817 iwl_setup_deferred_work(priv); 3733 iwl_setup_deferred_work(priv);
3818 iwl_setup_rx_handlers(priv); 3734 iwl_setup_rx_handlers(priv);
3735 iwl_testmode_init(priv);
3819 3736
3820 /********************************************* 3737 /*********************************************
3821 * 8. Enable interrupts and read RFKILL state 3738 * 8. Enable interrupts and read RFKILL state
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h
index b477336ff53a..fe33fe8aa418 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.h
@@ -139,11 +139,6 @@ void iwlagn_set_wr_ptrs(struct iwl_priv *priv,
139void iwlagn_tx_queue_set_status(struct iwl_priv *priv, 139void iwlagn_tx_queue_set_status(struct iwl_priv *priv,
140 struct iwl_tx_queue *txq, 140 struct iwl_tx_queue *txq,
141 int tx_fifo_id, int scd_retry); 141 int tx_fifo_id, int scd_retry);
142void iwlagn_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
143 struct iwl_tx_queue *txq,
144 u16 byte_cnt);
145void iwlagn_txq_inval_byte_cnt_tbl(struct iwl_priv *priv,
146 struct iwl_tx_queue *txq);
147void iwlagn_txq_set_sched(struct iwl_priv *priv, u32 mask); 142void iwlagn_txq_set_sched(struct iwl_priv *priv, u32 mask);
148void iwl_free_tfds_in_queue(struct iwl_priv *priv, 143void iwl_free_tfds_in_queue(struct iwl_priv *priv,
149 int sta_id, int tid, int freed); 144 int sta_id, int tid, int freed);
@@ -344,5 +339,22 @@ iwlagn_wait_notification(struct iwl_priv *priv,
344void __releases(wait_entry) 339void __releases(wait_entry)
345iwlagn_remove_notification(struct iwl_priv *priv, 340iwlagn_remove_notification(struct iwl_priv *priv,
346 struct iwl_notification_wait *wait_entry); 341 struct iwl_notification_wait *wait_entry);
342extern int iwlagn_init_alive_start(struct iwl_priv *priv);
343extern int iwl_alive_start(struct iwl_priv *priv);
344/* svtool */
345#ifdef CONFIG_IWLWIFI_DEVICE_SVTOOL
346extern int iwl_testmode_cmd(struct ieee80211_hw *hw, void *data, int len);
347extern void iwl_testmode_init(struct iwl_priv *priv);
348#else
349static inline
350int iwl_testmode_cmd(struct ieee80211_hw *hw, void *data, int len)
351{
352 return -ENOSYS;
353}
354static inline
355void iwl_testmode_init(struct iwl_priv *priv)
356{
357}
358#endif
347 359
348#endif /* __iwl_agn_h__ */ 360#endif /* __iwl_agn_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index dec9820753f8..5b5b0cce4a54 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -99,7 +99,6 @@ struct iwl_hcmd_ops {
99}; 99};
100 100
101struct iwl_hcmd_utils_ops { 101struct iwl_hcmd_utils_ops {
102 u16 (*get_hcmd_size)(u8 cmd_id, u16 len);
103 u16 (*build_addsta_hcmd)(const struct iwl_addsta_cmd *cmd, u8 *data); 102 u16 (*build_addsta_hcmd)(const struct iwl_addsta_cmd *cmd, u8 *data);
104 void (*gain_computation)(struct iwl_priv *priv, 103 void (*gain_computation)(struct iwl_priv *priv,
105 u32 *average_noise, 104 u32 *average_noise,
@@ -129,11 +128,6 @@ struct iwl_lib_ops {
129 /* set hw dependent parameters */ 128 /* set hw dependent parameters */
130 int (*set_hw_params)(struct iwl_priv *priv); 129 int (*set_hw_params)(struct iwl_priv *priv);
131 /* Handling TX */ 130 /* Handling TX */
132 void (*txq_update_byte_cnt_tbl)(struct iwl_priv *priv,
133 struct iwl_tx_queue *txq,
134 u16 byte_cnt);
135 void (*txq_inval_byte_cnt_tbl)(struct iwl_priv *priv,
136 struct iwl_tx_queue *txq);
137 void (*txq_set_sched)(struct iwl_priv *priv, u32 mask); 131 void (*txq_set_sched)(struct iwl_priv *priv, u32 mask);
138 int (*txq_attach_buf_to_tfd)(struct iwl_priv *priv, 132 int (*txq_attach_buf_to_tfd)(struct iwl_priv *priv,
139 struct iwl_tx_queue *txq, 133 struct iwl_tx_queue *txq,
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index f098eff263f8..214e4658c495 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -238,15 +238,6 @@ struct iwl_channel_info {
238#define IEEE80211_HLEN (IEEE80211_4ADDR_LEN) 238#define IEEE80211_HLEN (IEEE80211_4ADDR_LEN)
239#define IEEE80211_FRAME_LEN (IEEE80211_DATA_LEN + IEEE80211_HLEN) 239#define IEEE80211_FRAME_LEN (IEEE80211_DATA_LEN + IEEE80211_HLEN)
240 240
241struct iwl_frame {
242 union {
243 struct ieee80211_hdr frame;
244 struct iwl_tx_beacon_cmd beacon;
245 u8 raw[IEEE80211_FRAME_LEN];
246 u8 cmd[360];
247 } u;
248 struct list_head list;
249};
250 241
251#define SEQ_TO_SN(seq) (((seq) & IEEE80211_SCTL_SEQ) >> 4) 242#define SEQ_TO_SN(seq) (((seq) & IEEE80211_SCTL_SEQ) >> 4)
252#define SN_TO_SEQ(ssn) (((ssn) << 4) & IEEE80211_SCTL_SEQ) 243#define SN_TO_SEQ(ssn) (((ssn) << 4) & IEEE80211_SCTL_SEQ)
@@ -1188,12 +1179,10 @@ struct iwl_priv {
1188 struct ieee80211_rate *ieee_rates; 1179 struct ieee80211_rate *ieee_rates;
1189 struct iwl_cfg *cfg; 1180 struct iwl_cfg *cfg;
1190 1181
1191 /* temporary frame storage list */
1192 struct list_head free_frames;
1193 int frames_count;
1194
1195 enum ieee80211_band band; 1182 enum ieee80211_band band;
1196 1183
1184 void (*pre_rx_handler)(struct iwl_priv *priv,
1185 struct iwl_rx_mem_buffer *rxb);
1197 void (*rx_handlers[REPLY_MAX])(struct iwl_priv *priv, 1186 void (*rx_handlers[REPLY_MAX])(struct iwl_priv *priv,
1198 struct iwl_rx_mem_buffer *rxb); 1187 struct iwl_rx_mem_buffer *rxb);
1199 1188
@@ -1569,21 +1558,24 @@ iwl_rxon_ctx_from_vif(struct ieee80211_vif *vif)
1569 ctx < &priv->contexts[NUM_IWL_RXON_CTX]; ctx++) \ 1558 ctx < &priv->contexts[NUM_IWL_RXON_CTX]; ctx++) \
1570 if (priv->valid_contexts & BIT(ctx->ctxid)) 1559 if (priv->valid_contexts & BIT(ctx->ctxid))
1571 1560
1572static inline int iwl_is_associated(struct iwl_priv *priv, 1561static inline int iwl_is_associated_ctx(struct iwl_rxon_context *ctx)
1573 enum iwl_rxon_context_id ctxid)
1574{ 1562{
1575 return (priv->contexts[ctxid].active.filter_flags & 1563 return (ctx->active.filter_flags & RXON_FILTER_ASSOC_MSK) ? 1 : 0;
1576 RXON_FILTER_ASSOC_MSK) ? 1 : 0;
1577} 1564}
1578 1565
1579static inline int iwl_is_any_associated(struct iwl_priv *priv) 1566static inline int iwl_is_associated(struct iwl_priv *priv,
1567 enum iwl_rxon_context_id ctxid)
1580{ 1568{
1581 return iwl_is_associated(priv, IWL_RXON_CTX_BSS); 1569 return iwl_is_associated_ctx(&priv->contexts[ctxid]);
1582} 1570}
1583 1571
1584static inline int iwl_is_associated_ctx(struct iwl_rxon_context *ctx) 1572static inline int iwl_is_any_associated(struct iwl_priv *priv)
1585{ 1573{
1586 return (ctx->active.filter_flags & RXON_FILTER_ASSOC_MSK) ? 1 : 0; 1574 struct iwl_rxon_context *ctx;
1575 for_each_context(priv, ctx)
1576 if (iwl_is_associated_ctx(ctx))
1577 return true;
1578 return false;
1587} 1579}
1588 1580
1589static inline int is_channel_valid(const struct iwl_channel_info *ch_info) 1581static inline int is_channel_valid(const struct iwl_channel_info *ch_info)
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c
index d798c2a152d3..439187f903c9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-led.c
+++ b/drivers/net/wireless/iwlwifi/iwl-led.c
@@ -48,8 +48,21 @@ module_param(led_mode, int, S_IRUGO);
48MODULE_PARM_DESC(led_mode, "0=system default, " 48MODULE_PARM_DESC(led_mode, "0=system default, "
49 "1=On(RF On)/Off(RF Off), 2=blinking"); 49 "1=On(RF On)/Off(RF Off), 2=blinking");
50 50
51/* Throughput OFF time(ms) ON time (ms)
52 * >300 25 25
53 * >200 to 300 40 40
54 * >100 to 200 55 55
55 * >70 to 100 65 65
56 * >50 to 70 75 75
57 * >20 to 50 85 85
58 * >10 to 20 95 95
59 * >5 to 10 110 110
60 * >1 to 5 130 130
61 * >0 to 1 167 167
62 * <=0 SOLID ON
63 */
51static const struct ieee80211_tpt_blink iwl_blink[] = { 64static const struct ieee80211_tpt_blink iwl_blink[] = {
52 { .throughput = 0 * 1024 - 1, .blink_time = 334 }, 65 { .throughput = 0, .blink_time = 334 },
53 { .throughput = 1 * 1024 - 1, .blink_time = 260 }, 66 { .throughput = 1 * 1024 - 1, .blink_time = 260 },
54 { .throughput = 5 * 1024 - 1, .blink_time = 220 }, 67 { .throughput = 5 * 1024 - 1, .blink_time = 220 },
55 { .throughput = 10 * 1024 - 1, .blink_time = 190 }, 68 { .throughput = 10 * 1024 - 1, .blink_time = 190 },
@@ -125,6 +138,11 @@ static int iwl_led_cmd(struct iwl_priv *priv,
125 if (priv->blink_on == on && priv->blink_off == off) 138 if (priv->blink_on == on && priv->blink_off == off)
126 return 0; 139 return 0;
127 140
141 if (off == 0) {
142 /* led is SOLID_ON */
143 on = IWL_LED_SOLID;
144 }
145
128 IWL_DEBUG_LED(priv, "Led blink time compensation=%u\n", 146 IWL_DEBUG_LED(priv, "Led blink time compensation=%u\n",
129 priv->cfg->base_params->led_compensation); 147 priv->cfg->base_params->led_compensation);
130 led_cmd.on = iwl_blink_compensation(priv, on, 148 led_cmd.on = iwl_blink_compensation(priv, on,
diff --git a/drivers/net/wireless/iwlwifi/iwl-sv-open.c b/drivers/net/wireless/iwlwifi/iwl-sv-open.c
new file mode 100644
index 000000000000..89b6696622c1
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-sv-open.c
@@ -0,0 +1,469 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2010 - 2011 Intel Corporation. All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL.
26 *
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2010 - 2011 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *
62 *****************************************************************************/
63#include <linux/init.h>
64#include <linux/kernel.h>
65#include <linux/module.h>
66#include <net/net_namespace.h>
67#include <linux/netdevice.h>
68#include <net/cfg80211.h>
69#include <net/mac80211.h>
70#include <net/netlink.h>
71
72
73#include "iwl-dev.h"
74#include "iwl-core.h"
75#include "iwl-debug.h"
76#include "iwl-fh.h"
77#include "iwl-io.h"
78#include "iwl-agn.h"
79#include "iwl-testmode.h"
80
81
82/* The TLVs used in the gnl message policy between the kernel module and
83 * user space application. iwl_testmode_gnl_msg_policy is to be carried
84 * through the NL80211_CMD_TESTMODE channel regulated by nl80211.
85 * See iwl-testmode.h
86 */
87static
88struct nla_policy iwl_testmode_gnl_msg_policy[IWL_TM_ATTR_MAX] = {
89 [IWL_TM_ATTR_COMMAND] = { .type = NLA_U32, },
90
91 [IWL_TM_ATTR_UCODE_CMD_ID] = { .type = NLA_U8, },
92 [IWL_TM_ATTR_UCODE_CMD_DATA] = { .type = NLA_UNSPEC, },
93
94 [IWL_TM_ATTR_REG_OFFSET] = { .type = NLA_U32, },
95 [IWL_TM_ATTR_REG_VALUE8] = { .type = NLA_U8, },
96 [IWL_TM_ATTR_REG_VALUE32] = { .type = NLA_U32, },
97
98 [IWL_TM_ATTR_SYNC_RSP] = { .type = NLA_UNSPEC, },
99 [IWL_TM_ATTR_UCODE_RX_PKT] = { .type = NLA_UNSPEC, },
100};
101
102/*
103 * See the struct iwl_rx_packet in iwl-commands.h for the format of the
104 * received events from the device
105 */
106static inline int get_event_length(struct iwl_rx_mem_buffer *rxb)
107{
108 struct iwl_rx_packet *pkt = rxb_addr(rxb);
109 if (pkt)
110 return le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
111 else
112 return 0;
113}
114
115
116/*
117 * This function multicasts the spontaneous messages from the device to the
118 * user space. It is invoked whenever there is a received messages
119 * from the device. This function is called within the ISR of the rx handlers
120 * in iwlagn driver.
121 *
122 * The parsing of the message content is left to the user space application,
123 * The message content is treated as unattacked raw data and is encapsulated
124 * with IWL_TM_ATTR_UCODE_RX_PKT multicasting to the user space.
125 *
126 * @priv: the instance of iwlwifi device
127 * @rxb: pointer to rx data content received by the ISR
128 *
129 * See the message policies and TLVs in iwl_testmode_gnl_msg_policy[].
130 * For the messages multicasting to the user application, the mandatory
131 * TLV fields are :
132 * IWL_TM_ATTR_COMMAND must be IWL_TM_CMD_DEV2APP_UCODE_RX_PKT
133 * IWL_TM_ATTR_UCODE_RX_PKT for carrying the message content
134 */
135
136static void iwl_testmode_ucode_rx_pkt(struct iwl_priv *priv,
137 struct iwl_rx_mem_buffer *rxb)
138{
139 struct ieee80211_hw *hw = priv->hw;
140 struct sk_buff *skb;
141 void *data;
142 int length;
143
144 data = (void *)rxb_addr(rxb);
145 length = get_event_length(rxb);
146
147 if (!data || length == 0)
148 return;
149
150 skb = cfg80211_testmode_alloc_event_skb(hw->wiphy, 20 + length,
151 GFP_ATOMIC);
152 if (skb == NULL) {
153 IWL_DEBUG_INFO(priv,
154 "Run out of memory for messages to user space ?\n");
155 return;
156 }
157 NLA_PUT_U32(skb, IWL_TM_ATTR_COMMAND, IWL_TM_CMD_DEV2APP_UCODE_RX_PKT);
158 NLA_PUT(skb, IWL_TM_ATTR_UCODE_RX_PKT, length, data);
159 cfg80211_testmode_event(skb, GFP_ATOMIC);
160 return;
161
162nla_put_failure:
163 kfree_skb(skb);
164 IWL_DEBUG_INFO(priv, "Ouch, overran buffer, check allocation!\n");
165}
166
167void iwl_testmode_init(struct iwl_priv *priv)
168{
169 priv->pre_rx_handler = iwl_testmode_ucode_rx_pkt;
170}
171
172/*
173 * This function handles the user application commands to the ucode.
174 *
175 * It retrieves the mandatory fields IWL_TM_ATTR_UCODE_CMD_ID and
176 * IWL_TM_ATTR_UCODE_CMD_DATA and calls to the handler to send the
177 * host command to the ucode.
178 *
179 * If any mandatory field is missing, -ENOMSG is replied to the user space
180 * application; otherwise, the actual execution result of the host command to
181 * ucode is replied.
182 *
183 * @hw: ieee80211_hw object that represents the device
184 * @tb: gnl message fields from the user space
185 */
186static int iwl_testmode_ucode(struct ieee80211_hw *hw, struct nlattr **tb)
187{
188 struct iwl_priv *priv = hw->priv;
189 struct iwl_host_cmd cmd;
190
191 memset(&cmd, 0, sizeof(struct iwl_host_cmd));
192
193 if (!tb[IWL_TM_ATTR_UCODE_CMD_ID] ||
194 !tb[IWL_TM_ATTR_UCODE_CMD_DATA]) {
195 IWL_DEBUG_INFO(priv,
196 "Error finding ucode command mandatory fields\n");
197 return -ENOMSG;
198 }
199
200 cmd.id = nla_get_u8(tb[IWL_TM_ATTR_UCODE_CMD_ID]);
201 cmd.data = nla_data(tb[IWL_TM_ATTR_UCODE_CMD_DATA]);
202 cmd.len = nla_len(tb[IWL_TM_ATTR_UCODE_CMD_DATA]);
203 IWL_INFO(priv, "testmode ucode command ID 0x%x, flags 0x%x,"
204 " len %d\n", cmd.id, cmd.flags, cmd.len);
205 /* ok, let's submit the command to ucode */
206 return iwl_send_cmd(priv, &cmd);
207}
208
209
210/*
211 * This function handles the user application commands for register access.
212 *
213 * It retrieves command ID carried with IWL_TM_ATTR_COMMAND and calls to the
214 * handlers respectively.
215 *
216 * If it's an unknown commdn ID, -ENOSYS is returned; or -ENOMSG if the
217 * mandatory fields(IWL_TM_ATTR_REG_OFFSET,IWL_TM_ATTR_REG_VALUE32,
218 * IWL_TM_ATTR_REG_VALUE8) are missing; Otherwise 0 is replied indicating
219 * the success of the command execution.
220 *
221 * If IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_REG_READ32, the register read
222 * value is returned with IWL_TM_ATTR_REG_VALUE32.
223 *
224 * @hw: ieee80211_hw object that represents the device
225 * @tb: gnl message fields from the user space
226 */
227static int iwl_testmode_reg(struct ieee80211_hw *hw, struct nlattr **tb)
228{
229 struct iwl_priv *priv = hw->priv;
230 u32 ofs, val32;
231 u8 val8;
232 struct sk_buff *skb;
233 int status = 0;
234
235 if (!tb[IWL_TM_ATTR_REG_OFFSET]) {
236 IWL_DEBUG_INFO(priv, "Error finding register offset\n");
237 return -ENOMSG;
238 }
239 ofs = nla_get_u32(tb[IWL_TM_ATTR_REG_OFFSET]);
240 IWL_INFO(priv, "testmode register access command offset 0x%x\n", ofs);
241
242 switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) {
243 case IWL_TM_CMD_APP2DEV_REG_READ32:
244 val32 = iwl_read32(priv, ofs);
245 IWL_INFO(priv, "32bit value to read 0x%x\n", val32);
246
247 skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20);
248 if (!skb) {
249 IWL_DEBUG_INFO(priv, "Error allocating memory\n");
250 return -ENOMEM;
251 }
252 NLA_PUT_U32(skb, IWL_TM_ATTR_REG_VALUE32, val32);
253 status = cfg80211_testmode_reply(skb);
254 if (status < 0)
255 IWL_DEBUG_INFO(priv,
256 "Error sending msg : %d\n", status);
257 break;
258 case IWL_TM_CMD_APP2DEV_REG_WRITE32:
259 if (!tb[IWL_TM_ATTR_REG_VALUE32]) {
260 IWL_DEBUG_INFO(priv,
261 "Error finding value to write\n");
262 return -ENOMSG;
263 } else {
264 val32 = nla_get_u32(tb[IWL_TM_ATTR_REG_VALUE32]);
265 IWL_INFO(priv, "32bit value to write 0x%x\n", val32);
266 iwl_write32(priv, ofs, val32);
267 }
268 break;
269 case IWL_TM_CMD_APP2DEV_REG_WRITE8:
270 if (!tb[IWL_TM_ATTR_REG_VALUE8]) {
271 IWL_DEBUG_INFO(priv, "Error finding value to write\n");
272 return -ENOMSG;
273 } else {
274 val8 = nla_get_u8(tb[IWL_TM_ATTR_REG_VALUE8]);
275 IWL_INFO(priv, "8bit value to write 0x%x\n", val8);
276 iwl_write8(priv, ofs, val8);
277 }
278 break;
279 default:
280 IWL_DEBUG_INFO(priv, "Unknown testmode register command ID\n");
281 return -ENOSYS;
282 }
283
284 return status;
285
286nla_put_failure:
287 kfree_skb(skb);
288 return -EMSGSIZE;
289}
290
291
292static int iwl_testmode_cfg_init_calib(struct iwl_priv *priv)
293{
294 struct iwl_notification_wait calib_wait;
295 int ret;
296
297 iwlagn_init_notification_wait(priv, &calib_wait,
298 CALIBRATION_COMPLETE_NOTIFICATION,
299 NULL, NULL);
300 ret = iwlagn_init_alive_start(priv);
301 if (ret) {
302 IWL_DEBUG_INFO(priv,
303 "Error configuring init calibration: %d\n", ret);
304 goto cfg_init_calib_error;
305 }
306
307 ret = iwlagn_wait_notification(priv, &calib_wait, 2 * HZ);
308 if (ret)
309 IWL_DEBUG_INFO(priv, "Error detecting"
310 " CALIBRATION_COMPLETE_NOTIFICATION: %d\n", ret);
311 return ret;
312
313cfg_init_calib_error:
314 iwlagn_remove_notification(priv, &calib_wait);
315 return ret;
316}
317
318/*
319 * This function handles the user application commands for driver.
320 *
321 * It retrieves command ID carried with IWL_TM_ATTR_COMMAND and calls to the
322 * handlers respectively.
323 *
324 * If it's an unknown commdn ID, -ENOSYS is replied; otherwise, the returned
325 * value of the actual command execution is replied to the user application.
326 *
327 * If there's any message responding to the user space, IWL_TM_ATTR_SYNC_RSP
328 * is used for carry the message while IWL_TM_ATTR_COMMAND must set to
329 * IWL_TM_CMD_DEV2APP_SYNC_RSP.
330 *
331 * @hw: ieee80211_hw object that represents the device
332 * @tb: gnl message fields from the user space
333 */
334static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb)
335{
336 struct iwl_priv *priv = hw->priv;
337 struct sk_buff *skb;
338 unsigned char *rsp_data_ptr = NULL;
339 int status = 0, rsp_data_len = 0;
340
341 switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) {
342 case IWL_TM_CMD_APP2DEV_GET_DEVICENAME:
343 rsp_data_ptr = (unsigned char *)priv->cfg->name;
344 rsp_data_len = strlen(priv->cfg->name);
345 skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy,
346 rsp_data_len + 20);
347 if (!skb) {
348 IWL_DEBUG_INFO(priv,
349 "Error allocating memory\n");
350 return -ENOMEM;
351 }
352 NLA_PUT_U32(skb, IWL_TM_ATTR_COMMAND,
353 IWL_TM_CMD_DEV2APP_SYNC_RSP);
354 NLA_PUT(skb, IWL_TM_ATTR_SYNC_RSP,
355 rsp_data_len, rsp_data_ptr);
356 status = cfg80211_testmode_reply(skb);
357 if (status < 0)
358 IWL_DEBUG_INFO(priv, "Error sending msg : %d\n",
359 status);
360 break;
361
362 case IWL_TM_CMD_APP2DEV_LOAD_INIT_FW:
363 status = iwlagn_load_ucode_wait_alive(priv, &priv->ucode_init,
364 UCODE_SUBTYPE_INIT, -1);
365 if (status)
366 IWL_DEBUG_INFO(priv,
367 "Error loading init ucode: %d\n", status);
368 break;
369
370 case IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB:
371 iwl_testmode_cfg_init_calib(priv);
372 iwlagn_stop_device(priv);
373 break;
374
375 case IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW:
376 status = iwlagn_load_ucode_wait_alive(priv,
377 &priv->ucode_rt,
378 UCODE_SUBTYPE_REGULAR,
379 UCODE_SUBTYPE_REGULAR_NEW);
380 if (status) {
381 IWL_DEBUG_INFO(priv,
382 "Error loading runtime ucode: %d\n", status);
383 break;
384 }
385 status = iwl_alive_start(priv);
386 if (status)
387 IWL_DEBUG_INFO(priv,
388 "Error starting the device: %d\n", status);
389 break;
390
391 default:
392 IWL_DEBUG_INFO(priv, "Unknown testmode driver command ID\n");
393 return -ENOSYS;
394 }
395 return status;
396
397nla_put_failure:
398 kfree_skb(skb);
399 return -EMSGSIZE;
400}
401
402/* The testmode gnl message handler that takes the gnl message from the
403 * user space and parses it per the policy iwl_testmode_gnl_msg_policy, then
404 * invoke the corresponding handlers.
405 *
406 * This function is invoked when there is user space application sending
407 * gnl message through the testmode tunnel NL80211_CMD_TESTMODE regulated
408 * by nl80211.
409 *
410 * It retrieves the mandatory field, IWL_TM_ATTR_COMMAND, before
411 * dispatching it to the corresponding handler.
412 *
413 * If IWL_TM_ATTR_COMMAND is missing, -ENOMSG is replied to user application;
414 * -ENOSYS is replied to the user application if the command is unknown;
415 * Otherwise, the command is dispatched to the respective handler.
416 *
417 * @hw: ieee80211_hw object that represents the device
418 * @data: pointer to user space message
419 * @len: length in byte of @data
420 */
421int iwl_testmode_cmd(struct ieee80211_hw *hw, void *data, int len)
422{
423 struct nlattr *tb[IWL_TM_ATTR_MAX - 1];
424 struct iwl_priv *priv = hw->priv;
425 int result;
426
427 result = nla_parse(tb, IWL_TM_ATTR_MAX - 1, data, len,
428 iwl_testmode_gnl_msg_policy);
429 if (result != 0) {
430 IWL_DEBUG_INFO(priv,
431 "Error parsing the gnl message : %d\n", result);
432 return result;
433 }
434
435 /* IWL_TM_ATTR_COMMAND is absolutely mandatory */
436 if (!tb[IWL_TM_ATTR_COMMAND]) {
437 IWL_DEBUG_INFO(priv, "Error finding testmode command type\n");
438 return -ENOMSG;
439 }
440 /* in case multiple accesses to the device happens */
441 mutex_lock(&priv->mutex);
442
443 switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) {
444 case IWL_TM_CMD_APP2DEV_UCODE:
445 IWL_DEBUG_INFO(priv, "testmode cmd to uCode\n");
446 result = iwl_testmode_ucode(hw, tb);
447 break;
448 case IWL_TM_CMD_APP2DEV_REG_READ32:
449 case IWL_TM_CMD_APP2DEV_REG_WRITE32:
450 case IWL_TM_CMD_APP2DEV_REG_WRITE8:
451 IWL_DEBUG_INFO(priv, "testmode cmd to register\n");
452 result = iwl_testmode_reg(hw, tb);
453 break;
454 case IWL_TM_CMD_APP2DEV_GET_DEVICENAME:
455 case IWL_TM_CMD_APP2DEV_LOAD_INIT_FW:
456 case IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB:
457 case IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW:
458 IWL_DEBUG_INFO(priv, "testmode cmd to driver\n");
459 result = iwl_testmode_driver(hw, tb);
460 break;
461 default:
462 IWL_DEBUG_INFO(priv, "Unknown testmode command\n");
463 result = -ENOSYS;
464 break;
465 }
466
467 mutex_unlock(&priv->mutex);
468 return result;
469}
diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.h b/drivers/net/wireless/iwlwifi/iwl-testmode.h
new file mode 100644
index 000000000000..31f8949f2801
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-testmode.h
@@ -0,0 +1,151 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2010 - 2011 Intel Corporation. All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL.
26 *
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2010 - 2011 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *
62 *****************************************************************************/
63#ifndef __IWL_TESTMODE_H__
64#define __IWL_TESTMODE_H__
65
66#include <linux/types.h>
67
68
69/* Commands from user space to kernel space(IWL_TM_CMD_ID_APP2DEV_XX) and
70 * from and kernel space to user space(IWL_TM_CMD_ID_DEV2APP_XX).
71 * The command ID is carried with IWL_TM_ATTR_COMMAND. There are three types of
72 * of command from user space and two types of command from kernel space.
73 * See below.
74 */
75enum iwl_tm_cmd_t {
76 /* commands from user application to the uCode,
77 * the actual uCode host command ID is carried with
78 * IWL_TM_ATTR_UCODE_CMD_ID */
79 IWL_TM_CMD_APP2DEV_UCODE = 1,
80
81 /* commands from user applicaiton to access register */
82 IWL_TM_CMD_APP2DEV_REG_READ32,
83 IWL_TM_CMD_APP2DEV_REG_WRITE32,
84 IWL_TM_CMD_APP2DEV_REG_WRITE8,
85
86 /* commands fom user space for pure driver level operations */
87 IWL_TM_CMD_APP2DEV_GET_DEVICENAME,
88 IWL_TM_CMD_APP2DEV_LOAD_INIT_FW,
89 IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB,
90 IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW,
91 /* if there is other new command for the driver layer operation,
92 * append them here */
93
94
95 /* commands from kernel space to carry the synchronous response
96 * to user application */
97 IWL_TM_CMD_DEV2APP_SYNC_RSP,
98
99 /* commands from kernel space to multicast the spontaneous messages
100 * to user application */
101 IWL_TM_CMD_DEV2APP_UCODE_RX_PKT,
102 IWL_TM_CMD_MAX,
103};
104
105enum iwl_tm_attr_t {
106 IWL_TM_ATTR_NOT_APPLICABLE = 0,
107
108 /* From user space to kernel space:
109 * the command either destines to ucode, driver, or register;
110 * See enum iwl_tm_cmd_t.
111 *
112 * From kernel space to user space:
113 * the command either carries synchronous response,
114 * or the spontaneous message multicast from the device;
115 * See enum iwl_tm_cmd_t. */
116 IWL_TM_ATTR_COMMAND,
117
118 /* When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_UCODE,
119 * The mandatory fields are :
120 * IWL_TM_ATTR_UCODE_CMD_ID for recognizable command ID;
121 * IWL_TM_ATTR_COMMAND_FLAG for the flags of the commands;
122 * The optional fields are:
123 * IWL_TM_ATTR_UCODE_CMD_DATA for the actual command payload
124 * to the ucode */
125 IWL_TM_ATTR_UCODE_CMD_ID,
126 IWL_TM_ATTR_UCODE_CMD_DATA,
127
128 /* When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_REG_XXX,
129 * The mandatory fields are:
130 * IWL_TM_ATTR_REG_OFFSET for the offset of the target register;
131 * IWL_TM_ATTR_REG_VALUE8 or IWL_TM_ATTR_REG_VALUE32 for value */
132 IWL_TM_ATTR_REG_OFFSET,
133 IWL_TM_ATTR_REG_VALUE8,
134 IWL_TM_ATTR_REG_VALUE32,
135
136 /* When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_DEV2APP_SYNC_RSP,
137 * The mandatory fields are:
138 * IWL_TM_ATTR_SYNC_RSP for the data content responding to the user
139 * application command */
140 IWL_TM_ATTR_SYNC_RSP,
141 /* When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_DEV2APP_UCODE_RX_PKT,
142 * The mandatory fields are:
143 * IWL_TM_ATTR_UCODE_RX_PKT for the data content multicast to the user
144 * application */
145 IWL_TM_ATTR_UCODE_RX_PKT,
146
147 IWL_TM_ATTR_MAX,
148};
149
150
151#endif
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index 52b1b66f32d0..e69597ea43e2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -442,12 +442,10 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
442 struct iwl_cmd_meta *out_meta; 442 struct iwl_cmd_meta *out_meta;
443 dma_addr_t phys_addr; 443 dma_addr_t phys_addr;
444 unsigned long flags; 444 unsigned long flags;
445 int len;
446 u32 idx; 445 u32 idx;
447 u16 fix_size; 446 u16 fix_size;
448 bool is_ct_kill = false; 447 bool is_ct_kill = false;
449 448
450 cmd->len = priv->cfg->ops->utils->get_hcmd_size(cmd->id, cmd->len);
451 fix_size = (u16)(cmd->len + sizeof(out_cmd->hdr)); 449 fix_size = (u16)(cmd->len + sizeof(out_cmd->hdr));
452 450
453 /* 451 /*
@@ -502,7 +500,6 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
502 } 500 }
503 501
504 memset(out_meta, 0, sizeof(*out_meta)); /* re-initialize to NULL */ 502 memset(out_meta, 0, sizeof(*out_meta)); /* re-initialize to NULL */
505 out_meta->flags = cmd->flags | CMD_MAPPED;
506 if (cmd->flags & CMD_WANT_SKB) 503 if (cmd->flags & CMD_WANT_SKB)
507 out_meta->source = cmd; 504 out_meta->source = cmd;
508 if (cmd->flags & CMD_ASYNC) 505 if (cmd->flags & CMD_ASYNC)
@@ -519,9 +516,6 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
519 INDEX_TO_SEQ(q->write_ptr)); 516 INDEX_TO_SEQ(q->write_ptr));
520 if (cmd->flags & CMD_SIZE_HUGE) 517 if (cmd->flags & CMD_SIZE_HUGE)
521 out_cmd->hdr.sequence |= SEQ_HUGE_FRAME; 518 out_cmd->hdr.sequence |= SEQ_HUGE_FRAME;
522 len = sizeof(struct iwl_device_cmd);
523 if (idx == TFD_CMD_SLOTS)
524 len = IWL_MAX_CMD_SIZE;
525 519
526#ifdef CONFIG_IWLWIFI_DEBUG 520#ifdef CONFIG_IWLWIFI_DEBUG
527 switch (out_cmd->hdr.cmd) { 521 switch (out_cmd->hdr.cmd) {
@@ -543,17 +537,20 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
543 q->write_ptr, idx, priv->cmd_queue); 537 q->write_ptr, idx, priv->cmd_queue);
544 } 538 }
545#endif 539#endif
546 txq->need_update = 1;
547
548 if (priv->cfg->ops->lib->txq_update_byte_cnt_tbl)
549 /* Set up entry in queue's byte count circular buffer */
550 priv->cfg->ops->lib->txq_update_byte_cnt_tbl(priv, txq, 0);
551
552 phys_addr = pci_map_single(priv->pci_dev, &out_cmd->hdr, 540 phys_addr = pci_map_single(priv->pci_dev, &out_cmd->hdr,
553 fix_size, PCI_DMA_BIDIRECTIONAL); 541 fix_size, PCI_DMA_BIDIRECTIONAL);
542 if (unlikely(pci_dma_mapping_error(priv->pci_dev, phys_addr))) {
543 idx = -ENOMEM;
544 goto out;
545 }
546
554 dma_unmap_addr_set(out_meta, mapping, phys_addr); 547 dma_unmap_addr_set(out_meta, mapping, phys_addr);
555 dma_unmap_len_set(out_meta, len, fix_size); 548 dma_unmap_len_set(out_meta, len, fix_size);
556 549
550 out_meta->flags = cmd->flags | CMD_MAPPED;
551
552 txq->need_update = 1;
553
557 trace_iwlwifi_dev_hcmd(priv, &out_cmd->hdr, fix_size, cmd->flags); 554 trace_iwlwifi_dev_hcmd(priv, &out_cmd->hdr, fix_size, cmd->flags);
558 555
559 priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq, 556 priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq,
@@ -564,6 +561,7 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
564 q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); 561 q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);
565 iwl_txq_update_write_ptr(priv, txq); 562 iwl_txq_update_write_ptr(priv, txq);
566 563
564 out:
567 spin_unlock_irqrestore(&priv->hcmd_lock, flags); 565 spin_unlock_irqrestore(&priv->hcmd_lock, flags);
568 return idx; 566 return idx;
569} 567}
diff --git a/drivers/net/wireless/iwmc3200wifi/rx.c b/drivers/net/wireless/iwmc3200wifi/rx.c
index 9a57cf6a488f..5665a1a9b99e 100644
--- a/drivers/net/wireless/iwmc3200wifi/rx.c
+++ b/drivers/net/wireless/iwmc3200wifi/rx.c
@@ -1576,7 +1576,8 @@ static void iwm_rx_process_amsdu(struct iwm_priv *iwm, struct sk_buff *skb)
1576 IWM_HEXDUMP(iwm, DBG, RX, "A-MSDU: ", skb->data, skb->len); 1576 IWM_HEXDUMP(iwm, DBG, RX, "A-MSDU: ", skb->data, skb->len);
1577 1577
1578 __skb_queue_head_init(&list); 1578 __skb_queue_head_init(&list);
1579 ieee80211_amsdu_to_8023s(skb, &list, ndev->dev_addr, wdev->iftype, 0); 1579 ieee80211_amsdu_to_8023s(skb, &list, ndev->dev_addr, wdev->iftype, 0,
1580 true);
1580 1581
1581 while ((frame = __skb_dequeue(&list))) { 1582 while ((frame = __skb_dequeue(&list))) {
1582 ndev->stats.rx_packets++; 1583 ndev->stats.rx_packets++;
diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c
index 486544e01a56..5d637af2d7c3 100644
--- a/drivers/net/wireless/libertas/cfg.c
+++ b/drivers/net/wireless/libertas/cfg.c
@@ -6,6 +6,8 @@
6 * 6 *
7 */ 7 */
8 8
9#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
10
9#include <linux/sched.h> 11#include <linux/sched.h>
10#include <linux/wait.h> 12#include <linux/wait.h>
11#include <linux/slab.h> 13#include <linux/slab.h>
@@ -1322,8 +1324,8 @@ static int lbs_cfg_connect(struct wiphy *wiphy, struct net_device *dev,
1322 sme->ssid, sme->ssid_len, 1324 sme->ssid, sme->ssid_len,
1323 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); 1325 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
1324 if (!bss) { 1326 if (!bss) {
1325 lbs_pr_err("assoc: bss %pM not in scan results\n", 1327 wiphy_err(wiphy, "assoc: bss %pM not in scan results\n",
1326 sme->bssid); 1328 sme->bssid);
1327 ret = -ENOENT; 1329 ret = -ENOENT;
1328 goto done; 1330 goto done;
1329 } 1331 }
@@ -1380,8 +1382,8 @@ static int lbs_cfg_connect(struct wiphy *wiphy, struct net_device *dev,
1380 lbs_enable_rsn(priv, sme->crypto.cipher_group != 0); 1382 lbs_enable_rsn(priv, sme->crypto.cipher_group != 0);
1381 break; 1383 break;
1382 default: 1384 default:
1383 lbs_pr_err("unsupported cipher group 0x%x\n", 1385 wiphy_err(wiphy, "unsupported cipher group 0x%x\n",
1384 sme->crypto.cipher_group); 1386 sme->crypto.cipher_group);
1385 ret = -ENOTSUPP; 1387 ret = -ENOTSUPP;
1386 goto done; 1388 goto done;
1387 } 1389 }
@@ -1499,7 +1501,7 @@ static int lbs_cfg_add_key(struct wiphy *wiphy, struct net_device *netdev,
1499 params->key, params->key_len); 1501 params->key, params->key_len);
1500 break; 1502 break;
1501 default: 1503 default:
1502 lbs_pr_err("unhandled cipher 0x%x\n", params->cipher); 1504 wiphy_err(wiphy, "unhandled cipher 0x%x\n", params->cipher);
1503 ret = -ENOTSUPP; 1505 ret = -ENOTSUPP;
1504 break; 1506 break;
1505 } 1507 }
@@ -2127,13 +2129,13 @@ int lbs_cfg_register(struct lbs_private *priv)
2127 2129
2128 ret = wiphy_register(wdev->wiphy); 2130 ret = wiphy_register(wdev->wiphy);
2129 if (ret < 0) 2131 if (ret < 0)
2130 lbs_pr_err("cannot register wiphy device\n"); 2132 pr_err("cannot register wiphy device\n");
2131 2133
2132 priv->wiphy_registered = true; 2134 priv->wiphy_registered = true;
2133 2135
2134 ret = register_netdev(priv->dev); 2136 ret = register_netdev(priv->dev);
2135 if (ret) 2137 if (ret)
2136 lbs_pr_err("cannot register network device\n"); 2138 pr_err("cannot register network device\n");
2137 2139
2138 INIT_DELAYED_WORK(&priv->scan_work, lbs_scan_worker); 2140 INIT_DELAYED_WORK(&priv->scan_work, lbs_scan_worker);
2139 2141
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c
index 6a96fc9c1cea..6d59b4cf8fce 100644
--- a/drivers/net/wireless/libertas/cmd.c
+++ b/drivers/net/wireless/libertas/cmd.c
@@ -110,7 +110,7 @@ int lbs_update_hw_spec(struct lbs_private *priv)
110 * CF card firmware 5.0.16p0: cap 0x00000303 110 * CF card firmware 5.0.16p0: cap 0x00000303
111 * USB dongle firmware 5.110.17p2: cap 0x00000303 111 * USB dongle firmware 5.110.17p2: cap 0x00000303
112 */ 112 */
113 lbs_pr_info("%pM, fw %u.%u.%up%u, cap 0x%08x\n", 113 netdev_info(priv->dev, "%pM, fw %u.%u.%up%u, cap 0x%08x\n",
114 cmd.permanentaddr, 114 cmd.permanentaddr,
115 priv->fwrelease >> 24 & 0xff, 115 priv->fwrelease >> 24 & 0xff,
116 priv->fwrelease >> 16 & 0xff, 116 priv->fwrelease >> 16 & 0xff,
@@ -141,7 +141,8 @@ int lbs_update_hw_spec(struct lbs_private *priv)
141 /* if it's unidentified region code, use the default (USA) */ 141 /* if it's unidentified region code, use the default (USA) */
142 if (i >= MRVDRV_MAX_REGION_CODE) { 142 if (i >= MRVDRV_MAX_REGION_CODE) {
143 priv->regioncode = 0x10; 143 priv->regioncode = 0x10;
144 lbs_pr_info("unidentified region code; using the default (USA)\n"); 144 netdev_info(priv->dev,
145 "unidentified region code; using the default (USA)\n");
145 } 146 }
146 147
147 if (priv->current_addr[0] == 0xff) 148 if (priv->current_addr[0] == 0xff)
@@ -211,7 +212,7 @@ int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria,
211 (uint8_t *)&cmd_config.wol_conf, 212 (uint8_t *)&cmd_config.wol_conf,
212 sizeof(struct wol_config)); 213 sizeof(struct wol_config));
213 } else { 214 } else {
214 lbs_pr_info("HOST_SLEEP_CFG failed %d\n", ret); 215 netdev_info(priv->dev, "HOST_SLEEP_CFG failed %d\n", ret);
215 } 216 }
216 217
217 return ret; 218 return ret;
@@ -314,7 +315,7 @@ static int lbs_wait_for_ds_awake(struct lbs_private *priv)
314 if (priv->is_deep_sleep) { 315 if (priv->is_deep_sleep) {
315 if (!wait_event_interruptible_timeout(priv->ds_awake_q, 316 if (!wait_event_interruptible_timeout(priv->ds_awake_q,
316 !priv->is_deep_sleep, (10 * HZ))) { 317 !priv->is_deep_sleep, (10 * HZ))) {
317 lbs_pr_err("ds_awake_q: timer expired\n"); 318 netdev_err(priv->dev, "ds_awake_q: timer expired\n");
318 ret = -1; 319 ret = -1;
319 } 320 }
320 } 321 }
@@ -339,7 +340,7 @@ int lbs_set_deep_sleep(struct lbs_private *priv, int deep_sleep)
339 netif_carrier_off(priv->dev); 340 netif_carrier_off(priv->dev);
340 } 341 }
341 } else { 342 } else {
342 lbs_pr_err("deep sleep: already enabled\n"); 343 netdev_err(priv->dev, "deep sleep: already enabled\n");
343 } 344 }
344 } else { 345 } else {
345 if (priv->is_deep_sleep) { 346 if (priv->is_deep_sleep) {
@@ -349,8 +350,8 @@ int lbs_set_deep_sleep(struct lbs_private *priv, int deep_sleep)
349 if (!ret) { 350 if (!ret) {
350 ret = lbs_wait_for_ds_awake(priv); 351 ret = lbs_wait_for_ds_awake(priv);
351 if (ret) 352 if (ret)
352 lbs_pr_err("deep sleep: wakeup" 353 netdev_err(priv->dev,
353 "failed\n"); 354 "deep sleep: wakeup failed\n");
354 } 355 }
355 } 356 }
356 } 357 }
@@ -384,8 +385,9 @@ int lbs_set_host_sleep(struct lbs_private *priv, int host_sleep)
384 ret = lbs_host_sleep_cfg(priv, priv->wol_criteria, 385 ret = lbs_host_sleep_cfg(priv, priv->wol_criteria,
385 (struct wol_config *)NULL); 386 (struct wol_config *)NULL);
386 if (ret) { 387 if (ret) {
387 lbs_pr_info("Host sleep configuration failed: " 388 netdev_info(priv->dev,
388 "%d\n", ret); 389 "Host sleep configuration failed: %d\n",
390 ret);
389 return ret; 391 return ret;
390 } 392 }
391 if (priv->psstate == PS_STATE_FULL_POWER) { 393 if (priv->psstate == PS_STATE_FULL_POWER) {
@@ -395,19 +397,21 @@ int lbs_set_host_sleep(struct lbs_private *priv, int host_sleep)
395 sizeof(cmd), 397 sizeof(cmd),
396 lbs_ret_host_sleep_activate, 0); 398 lbs_ret_host_sleep_activate, 0);
397 if (ret) 399 if (ret)
398 lbs_pr_info("HOST_SLEEP_ACTIVATE " 400 netdev_info(priv->dev,
399 "failed: %d\n", ret); 401 "HOST_SLEEP_ACTIVATE failed: %d\n",
402 ret);
400 } 403 }
401 404
402 if (!wait_event_interruptible_timeout( 405 if (!wait_event_interruptible_timeout(
403 priv->host_sleep_q, 406 priv->host_sleep_q,
404 priv->is_host_sleep_activated, 407 priv->is_host_sleep_activated,
405 (10 * HZ))) { 408 (10 * HZ))) {
406 lbs_pr_err("host_sleep_q: timer expired\n"); 409 netdev_err(priv->dev,
410 "host_sleep_q: timer expired\n");
407 ret = -1; 411 ret = -1;
408 } 412 }
409 } else { 413 } else {
410 lbs_pr_err("host sleep: already enabled\n"); 414 netdev_err(priv->dev, "host sleep: already enabled\n");
411 } 415 }
412 } else { 416 } else {
413 if (priv->is_host_sleep_activated) 417 if (priv->is_host_sleep_activated)
@@ -1007,7 +1011,8 @@ static void lbs_submit_command(struct lbs_private *priv,
1007 ret = priv->hw_host_to_card(priv, MVMS_CMD, (u8 *) cmd, cmdsize); 1011 ret = priv->hw_host_to_card(priv, MVMS_CMD, (u8 *) cmd, cmdsize);
1008 1012
1009 if (ret) { 1013 if (ret) {
1010 lbs_pr_info("DNLD_CMD: hw_host_to_card failed: %d\n", ret); 1014 netdev_info(priv->dev, "DNLD_CMD: hw_host_to_card failed: %d\n",
1015 ret);
1011 /* Let the timer kick in and retry, and potentially reset 1016 /* Let the timer kick in and retry, and potentially reset
1012 the whole thing if the condition persists */ 1017 the whole thing if the condition persists */
1013 timeo = HZ/4; 1018 timeo = HZ/4;
@@ -1276,7 +1281,8 @@ int lbs_execute_next_command(struct lbs_private *priv)
1276 spin_lock_irqsave(&priv->driver_lock, flags); 1281 spin_lock_irqsave(&priv->driver_lock, flags);
1277 1282
1278 if (priv->cur_cmd) { 1283 if (priv->cur_cmd) {
1279 lbs_pr_alert( "EXEC_NEXT_CMD: already processing command!\n"); 1284 netdev_alert(priv->dev,
1285 "EXEC_NEXT_CMD: already processing command!\n");
1280 spin_unlock_irqrestore(&priv->driver_lock, flags); 1286 spin_unlock_irqrestore(&priv->driver_lock, flags);
1281 ret = -1; 1287 ret = -1;
1282 goto done; 1288 goto done;
@@ -1438,7 +1444,7 @@ static void lbs_send_confirmsleep(struct lbs_private *priv)
1438 ret = priv->hw_host_to_card(priv, MVMS_CMD, (u8 *) &confirm_sleep, 1444 ret = priv->hw_host_to_card(priv, MVMS_CMD, (u8 *) &confirm_sleep,
1439 sizeof(confirm_sleep)); 1445 sizeof(confirm_sleep));
1440 if (ret) { 1446 if (ret) {
1441 lbs_pr_alert("confirm_sleep failed\n"); 1447 netdev_alert(priv->dev, "confirm_sleep failed\n");
1442 goto out; 1448 goto out;
1443 } 1449 }
1444 1450
@@ -1664,7 +1670,7 @@ int __lbs_cmd(struct lbs_private *priv, uint16_t command,
1664 spin_lock_irqsave(&priv->driver_lock, flags); 1670 spin_lock_irqsave(&priv->driver_lock, flags);
1665 ret = cmdnode->result; 1671 ret = cmdnode->result;
1666 if (ret) 1672 if (ret)
1667 lbs_pr_info("PREP_CMD: command 0x%04x failed: %d\n", 1673 netdev_info(priv->dev, "PREP_CMD: command 0x%04x failed: %d\n",
1668 command, ret); 1674 command, ret);
1669 1675
1670 __lbs_cleanup_and_insert_cmd(priv, cmdnode); 1676 __lbs_cleanup_and_insert_cmd(priv, cmdnode);
diff --git a/drivers/net/wireless/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c
index 03e528994a9e..207fc361db84 100644
--- a/drivers/net/wireless/libertas/cmdresp.c
+++ b/drivers/net/wireless/libertas/cmdresp.c
@@ -2,6 +2,7 @@
2 * This file contains the handling of command 2 * This file contains the handling of command
3 * responses as well as events generated by firmware. 3 * responses as well as events generated by firmware.
4 */ 4 */
5
5#include <linux/slab.h> 6#include <linux/slab.h>
6#include <linux/delay.h> 7#include <linux/delay.h>
7#include <linux/sched.h> 8#include <linux/sched.h>
@@ -85,15 +86,18 @@ int lbs_process_command_response(struct lbs_private *priv, u8 *data, u32 len)
85 lbs_deb_hex(LBS_DEB_CMD, "CMD_RESP", (void *) resp, len); 86 lbs_deb_hex(LBS_DEB_CMD, "CMD_RESP", (void *) resp, len);
86 87
87 if (resp->seqnum != priv->cur_cmd->cmdbuf->seqnum) { 88 if (resp->seqnum != priv->cur_cmd->cmdbuf->seqnum) {
88 lbs_pr_info("Received CMD_RESP with invalid sequence %d (expected %d)\n", 89 netdev_info(priv->dev,
89 le16_to_cpu(resp->seqnum), le16_to_cpu(priv->cur_cmd->cmdbuf->seqnum)); 90 "Received CMD_RESP with invalid sequence %d (expected %d)\n",
91 le16_to_cpu(resp->seqnum),
92 le16_to_cpu(priv->cur_cmd->cmdbuf->seqnum));
90 spin_unlock_irqrestore(&priv->driver_lock, flags); 93 spin_unlock_irqrestore(&priv->driver_lock, flags);
91 ret = -1; 94 ret = -1;
92 goto done; 95 goto done;
93 } 96 }
94 if (respcmd != CMD_RET(curcmd) && 97 if (respcmd != CMD_RET(curcmd) &&
95 respcmd != CMD_RET_802_11_ASSOCIATE && curcmd != CMD_802_11_ASSOCIATE) { 98 respcmd != CMD_RET_802_11_ASSOCIATE && curcmd != CMD_802_11_ASSOCIATE) {
96 lbs_pr_info("Invalid CMD_RESP %x to command %x!\n", respcmd, curcmd); 99 netdev_info(priv->dev, "Invalid CMD_RESP %x to command %x!\n",
100 respcmd, curcmd);
97 spin_unlock_irqrestore(&priv->driver_lock, flags); 101 spin_unlock_irqrestore(&priv->driver_lock, flags);
98 ret = -1; 102 ret = -1;
99 goto done; 103 goto done;
@@ -102,7 +106,8 @@ int lbs_process_command_response(struct lbs_private *priv, u8 *data, u32 len)
102 if (resp->result == cpu_to_le16(0x0004)) { 106 if (resp->result == cpu_to_le16(0x0004)) {
103 /* 0x0004 means -EAGAIN. Drop the response, let it time out 107 /* 0x0004 means -EAGAIN. Drop the response, let it time out
104 and be resubmitted */ 108 and be resubmitted */
105 lbs_pr_info("Firmware returns DEFER to command %x. Will let it time out...\n", 109 netdev_info(priv->dev,
110 "Firmware returns DEFER to command %x. Will let it time out...\n",
106 le16_to_cpu(resp->command)); 111 le16_to_cpu(resp->command));
107 spin_unlock_irqrestore(&priv->driver_lock, flags); 112 spin_unlock_irqrestore(&priv->driver_lock, flags);
108 ret = -1; 113 ret = -1;
@@ -314,28 +319,28 @@ int lbs_process_event(struct lbs_private *priv, u32 event)
314 lbs_deb_cmd("EVENT: ADHOC beacon lost\n"); 319 lbs_deb_cmd("EVENT: ADHOC beacon lost\n");
315 break; 320 break;
316 case MACREG_INT_CODE_RSSI_LOW: 321 case MACREG_INT_CODE_RSSI_LOW:
317 lbs_pr_alert("EVENT: rssi low\n"); 322 netdev_alert(priv->dev, "EVENT: rssi low\n");
318 break; 323 break;
319 case MACREG_INT_CODE_SNR_LOW: 324 case MACREG_INT_CODE_SNR_LOW:
320 lbs_pr_alert("EVENT: snr low\n"); 325 netdev_alert(priv->dev, "EVENT: snr low\n");
321 break; 326 break;
322 case MACREG_INT_CODE_MAX_FAIL: 327 case MACREG_INT_CODE_MAX_FAIL:
323 lbs_pr_alert("EVENT: max fail\n"); 328 netdev_alert(priv->dev, "EVENT: max fail\n");
324 break; 329 break;
325 case MACREG_INT_CODE_RSSI_HIGH: 330 case MACREG_INT_CODE_RSSI_HIGH:
326 lbs_pr_alert("EVENT: rssi high\n"); 331 netdev_alert(priv->dev, "EVENT: rssi high\n");
327 break; 332 break;
328 case MACREG_INT_CODE_SNR_HIGH: 333 case MACREG_INT_CODE_SNR_HIGH:
329 lbs_pr_alert("EVENT: snr high\n"); 334 netdev_alert(priv->dev, "EVENT: snr high\n");
330 break; 335 break;
331 336
332 case MACREG_INT_CODE_MESH_AUTO_STARTED: 337 case MACREG_INT_CODE_MESH_AUTO_STARTED:
333 /* Ignore spurious autostart events */ 338 /* Ignore spurious autostart events */
334 lbs_pr_info("EVENT: MESH_AUTO_STARTED (ignoring)\n"); 339 netdev_info(priv->dev, "EVENT: MESH_AUTO_STARTED (ignoring)\n");
335 break; 340 break;
336 341
337 default: 342 default:
338 lbs_pr_alert("EVENT: unknown event id %d\n", event); 343 netdev_alert(priv->dev, "EVENT: unknown event id %d\n", event);
339 break; 344 break;
340 } 345 }
341 346
diff --git a/drivers/net/wireless/libertas/debugfs.c b/drivers/net/wireless/libertas/debugfs.c
index 851fe7bd4ba4..23250f621761 100644
--- a/drivers/net/wireless/libertas/debugfs.c
+++ b/drivers/net/wireless/libertas/debugfs.c
@@ -151,13 +151,14 @@ static ssize_t lbs_host_sleep_write(struct file *file,
151 ret = lbs_set_host_sleep(priv, 0); 151 ret = lbs_set_host_sleep(priv, 0);
152 else if (host_sleep == 1) { 152 else if (host_sleep == 1) {
153 if (priv->wol_criteria == EHS_REMOVE_WAKEUP) { 153 if (priv->wol_criteria == EHS_REMOVE_WAKEUP) {
154 lbs_pr_info("wake parameters not configured"); 154 netdev_info(priv->dev,
155 "wake parameters not configured\n");
155 ret = -EINVAL; 156 ret = -EINVAL;
156 goto out_unlock; 157 goto out_unlock;
157 } 158 }
158 ret = lbs_set_host_sleep(priv, 1); 159 ret = lbs_set_host_sleep(priv, 1);
159 } else { 160 } else {
160 lbs_pr_err("invalid option\n"); 161 netdev_err(priv->dev, "invalid option\n");
161 ret = -EINVAL; 162 ret = -EINVAL;
162 } 163 }
163 164
diff --git a/drivers/net/wireless/libertas/defs.h b/drivers/net/wireless/libertas/defs.h
index 92b5b1f8fd75..ab966f08024a 100644
--- a/drivers/net/wireless/libertas/defs.h
+++ b/drivers/net/wireless/libertas/defs.h
@@ -89,13 +89,6 @@ do { if ((lbs_debug & (grp)) == (grp)) \
89#define lbs_deb_spi(fmt, args...) LBS_DEB_LL(LBS_DEB_SPI, " spi", fmt, ##args) 89#define lbs_deb_spi(fmt, args...) LBS_DEB_LL(LBS_DEB_SPI, " spi", fmt, ##args)
90#define lbs_deb_cfg80211(fmt, args...) LBS_DEB_LL(LBS_DEB_CFG80211, " cfg80211", fmt, ##args) 90#define lbs_deb_cfg80211(fmt, args...) LBS_DEB_LL(LBS_DEB_CFG80211, " cfg80211", fmt, ##args)
91 91
92#define lbs_pr_info(format, args...) \
93 printk(KERN_INFO DRV_NAME": " format, ## args)
94#define lbs_pr_err(format, args...) \
95 printk(KERN_ERR DRV_NAME": " format, ## args)
96#define lbs_pr_alert(format, args...) \
97 printk(KERN_ALERT DRV_NAME": " format, ## args)
98
99#ifdef DEBUG 92#ifdef DEBUG
100static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, int len) 93static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, int len)
101{ 94{
diff --git a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c
index 4dfd48fe8b6e..63ed5798365c 100644
--- a/drivers/net/wireless/libertas/if_cs.c
+++ b/drivers/net/wireless/libertas/if_cs.c
@@ -21,6 +21,8 @@
21 21
22*/ 22*/
23 23
24#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
25
24#include <linux/module.h> 26#include <linux/module.h>
25#include <linux/slab.h> 27#include <linux/slab.h>
26#include <linux/delay.h> 28#include <linux/delay.h>
@@ -362,7 +364,7 @@ static int if_cs_send_cmd(struct lbs_private *priv, u8 *buf, u16 nb)
362 if (status & IF_CS_BIT_COMMAND) 364 if (status & IF_CS_BIT_COMMAND)
363 break; 365 break;
364 if (++loops > 100) { 366 if (++loops > 100) {
365 lbs_pr_err("card not ready for commands\n"); 367 netdev_err(priv->dev, "card not ready for commands\n");
366 goto done; 368 goto done;
367 } 369 }
368 mdelay(1); 370 mdelay(1);
@@ -432,14 +434,16 @@ static int if_cs_receive_cmdres(struct lbs_private *priv, u8 *data, u32 *len)
432 /* is hardware ready? */ 434 /* is hardware ready? */
433 status = if_cs_read16(priv->card, IF_CS_CARD_STATUS); 435 status = if_cs_read16(priv->card, IF_CS_CARD_STATUS);
434 if ((status & IF_CS_BIT_RESP) == 0) { 436 if ((status & IF_CS_BIT_RESP) == 0) {
435 lbs_pr_err("no cmd response in card\n"); 437 netdev_err(priv->dev, "no cmd response in card\n");
436 *len = 0; 438 *len = 0;
437 goto out; 439 goto out;
438 } 440 }
439 441
440 *len = if_cs_read16(priv->card, IF_CS_RESP_LEN); 442 *len = if_cs_read16(priv->card, IF_CS_RESP_LEN);
441 if ((*len == 0) || (*len > LBS_CMD_BUFFER_SIZE)) { 443 if ((*len == 0) || (*len > LBS_CMD_BUFFER_SIZE)) {
442 lbs_pr_err("card cmd buffer has invalid # of bytes (%d)\n", *len); 444 netdev_err(priv->dev,
445 "card cmd buffer has invalid # of bytes (%d)\n",
446 *len);
443 goto out; 447 goto out;
444 } 448 }
445 449
@@ -473,7 +477,9 @@ static struct sk_buff *if_cs_receive_data(struct lbs_private *priv)
473 477
474 len = if_cs_read16(priv->card, IF_CS_READ_LEN); 478 len = if_cs_read16(priv->card, IF_CS_READ_LEN);
475 if (len == 0 || len > MRVDRV_ETH_RX_PACKET_BUFFER_SIZE) { 479 if (len == 0 || len > MRVDRV_ETH_RX_PACKET_BUFFER_SIZE) {
476 lbs_pr_err("card data buffer has invalid # of bytes (%d)\n", len); 480 netdev_err(priv->dev,
481 "card data buffer has invalid # of bytes (%d)\n",
482 len);
477 priv->dev->stats.rx_dropped++; 483 priv->dev->stats.rx_dropped++;
478 goto dat_err; 484 goto dat_err;
479 } 485 }
@@ -653,8 +659,8 @@ static int if_cs_prog_helper(struct if_cs_card *card, const struct firmware *fw)
653 ret = if_cs_poll_while_fw_download(card, IF_CS_CARD_STATUS, 659 ret = if_cs_poll_while_fw_download(card, IF_CS_CARD_STATUS,
654 IF_CS_BIT_COMMAND); 660 IF_CS_BIT_COMMAND);
655 if (ret < 0) { 661 if (ret < 0) {
656 lbs_pr_err("can't download helper at 0x%x, ret %d\n", 662 pr_err("can't download helper at 0x%x, ret %d\n",
657 sent, ret); 663 sent, ret);
658 goto done; 664 goto done;
659 } 665 }
660 666
@@ -684,7 +690,7 @@ static int if_cs_prog_real(struct if_cs_card *card, const struct firmware *fw)
684 ret = if_cs_poll_while_fw_download(card, IF_CS_SQ_READ_LOW, 690 ret = if_cs_poll_while_fw_download(card, IF_CS_SQ_READ_LOW,
685 IF_CS_SQ_HELPER_OK); 691 IF_CS_SQ_HELPER_OK);
686 if (ret < 0) { 692 if (ret < 0) {
687 lbs_pr_err("helper firmware doesn't answer\n"); 693 pr_err("helper firmware doesn't answer\n");
688 goto done; 694 goto done;
689 } 695 }
690 696
@@ -692,13 +698,13 @@ static int if_cs_prog_real(struct if_cs_card *card, const struct firmware *fw)
692 len = if_cs_read16(card, IF_CS_SQ_READ_LOW); 698 len = if_cs_read16(card, IF_CS_SQ_READ_LOW);
693 if (len & 1) { 699 if (len & 1) {
694 retry++; 700 retry++;
695 lbs_pr_info("odd, need to retry this firmware block\n"); 701 pr_info("odd, need to retry this firmware block\n");
696 } else { 702 } else {
697 retry = 0; 703 retry = 0;
698 } 704 }
699 705
700 if (retry > 20) { 706 if (retry > 20) {
701 lbs_pr_err("could not download firmware\n"); 707 pr_err("could not download firmware\n");
702 ret = -ENODEV; 708 ret = -ENODEV;
703 goto done; 709 goto done;
704 } 710 }
@@ -718,14 +724,14 @@ static int if_cs_prog_real(struct if_cs_card *card, const struct firmware *fw)
718 ret = if_cs_poll_while_fw_download(card, IF_CS_CARD_STATUS, 724 ret = if_cs_poll_while_fw_download(card, IF_CS_CARD_STATUS,
719 IF_CS_BIT_COMMAND); 725 IF_CS_BIT_COMMAND);
720 if (ret < 0) { 726 if (ret < 0) {
721 lbs_pr_err("can't download firmware at 0x%x\n", sent); 727 pr_err("can't download firmware at 0x%x\n", sent);
722 goto done; 728 goto done;
723 } 729 }
724 } 730 }
725 731
726 ret = if_cs_poll_while_fw_download(card, IF_CS_SCRATCH, 0x5a); 732 ret = if_cs_poll_while_fw_download(card, IF_CS_SCRATCH, 0x5a);
727 if (ret < 0) 733 if (ret < 0)
728 lbs_pr_err("firmware download failed\n"); 734 pr_err("firmware download failed\n");
729 735
730done: 736done:
731 lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret); 737 lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret);
@@ -759,7 +765,8 @@ static int if_cs_host_to_card(struct lbs_private *priv,
759 ret = if_cs_send_cmd(priv, buf, nb); 765 ret = if_cs_send_cmd(priv, buf, nb);
760 break; 766 break;
761 default: 767 default:
762 lbs_pr_err("%s: unsupported type %d\n", __func__, type); 768 netdev_err(priv->dev, "%s: unsupported type %d\n",
769 __func__, type);
763 } 770 }
764 771
765 lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret); 772 lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret);
@@ -788,7 +795,7 @@ static int if_cs_ioprobe(struct pcmcia_device *p_dev, void *priv_data)
788 p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO; 795 p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
789 796
790 if (p_dev->resource[1]->end) { 797 if (p_dev->resource[1]->end) {
791 lbs_pr_err("wrong CIS (check number of IO windows)\n"); 798 pr_err("wrong CIS (check number of IO windows)\n");
792 return -ENODEV; 799 return -ENODEV;
793 } 800 }
794 801
@@ -809,7 +816,7 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
809 816
810 card = kzalloc(sizeof(struct if_cs_card), GFP_KERNEL); 817 card = kzalloc(sizeof(struct if_cs_card), GFP_KERNEL);
811 if (!card) { 818 if (!card) {
812 lbs_pr_err("error in kzalloc\n"); 819 pr_err("error in kzalloc\n");
813 goto out; 820 goto out;
814 } 821 }
815 card->p_dev = p_dev; 822 card->p_dev = p_dev;
@@ -818,7 +825,7 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
818 p_dev->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO; 825 p_dev->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
819 826
820 if (pcmcia_loop_config(p_dev, if_cs_ioprobe, NULL)) { 827 if (pcmcia_loop_config(p_dev, if_cs_ioprobe, NULL)) {
821 lbs_pr_err("error in pcmcia_loop_config\n"); 828 pr_err("error in pcmcia_loop_config\n");
822 goto out1; 829 goto out1;
823 } 830 }
824 831
@@ -834,14 +841,14 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
834 card->iobase = ioport_map(p_dev->resource[0]->start, 841 card->iobase = ioport_map(p_dev->resource[0]->start,
835 resource_size(p_dev->resource[0])); 842 resource_size(p_dev->resource[0]));
836 if (!card->iobase) { 843 if (!card->iobase) {
837 lbs_pr_err("error in ioport_map\n"); 844 pr_err("error in ioport_map\n");
838 ret = -EIO; 845 ret = -EIO;
839 goto out1; 846 goto out1;
840 } 847 }
841 848
842 ret = pcmcia_enable_device(p_dev); 849 ret = pcmcia_enable_device(p_dev);
843 if (ret) { 850 if (ret) {
844 lbs_pr_err("error in pcmcia_enable_device\n"); 851 pr_err("error in pcmcia_enable_device\n");
845 goto out2; 852 goto out2;
846 } 853 }
847 854
@@ -856,8 +863,8 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
856 863
857 card->model = get_model(p_dev->manf_id, p_dev->card_id); 864 card->model = get_model(p_dev->manf_id, p_dev->card_id);
858 if (card->model == MODEL_UNKNOWN) { 865 if (card->model == MODEL_UNKNOWN) {
859 lbs_pr_err("unsupported manf_id 0x%04x / card_id 0x%04x\n", 866 pr_err("unsupported manf_id 0x%04x / card_id 0x%04x\n",
860 p_dev->manf_id, p_dev->card_id); 867 p_dev->manf_id, p_dev->card_id);
861 goto out2; 868 goto out2;
862 } 869 }
863 870
@@ -866,20 +873,20 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
866 if (card->model == MODEL_8305) { 873 if (card->model == MODEL_8305) {
867 card->align_regs = 1; 874 card->align_regs = 1;
868 if (prod_id < IF_CS_CF8305_B1_REV) { 875 if (prod_id < IF_CS_CF8305_B1_REV) {
869 lbs_pr_err("8305 rev B0 and older are not supported\n"); 876 pr_err("8305 rev B0 and older are not supported\n");
870 ret = -ENODEV; 877 ret = -ENODEV;
871 goto out2; 878 goto out2;
872 } 879 }
873 } 880 }
874 881
875 if ((card->model == MODEL_8381) && prod_id < IF_CS_CF8381_B3_REV) { 882 if ((card->model == MODEL_8381) && prod_id < IF_CS_CF8381_B3_REV) {
876 lbs_pr_err("8381 rev B2 and older are not supported\n"); 883 pr_err("8381 rev B2 and older are not supported\n");
877 ret = -ENODEV; 884 ret = -ENODEV;
878 goto out2; 885 goto out2;
879 } 886 }
880 887
881 if ((card->model == MODEL_8385) && prod_id < IF_CS_CF8385_B1_REV) { 888 if ((card->model == MODEL_8385) && prod_id < IF_CS_CF8385_B1_REV) {
882 lbs_pr_err("8385 rev B0 and older are not supported\n"); 889 pr_err("8385 rev B0 and older are not supported\n");
883 ret = -ENODEV; 890 ret = -ENODEV;
884 goto out2; 891 goto out2;
885 } 892 }
@@ -887,7 +894,7 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
887 ret = lbs_get_firmware(&p_dev->dev, NULL, NULL, card->model, 894 ret = lbs_get_firmware(&p_dev->dev, NULL, NULL, card->model,
888 &fw_table[0], &helper, &mainfw); 895 &fw_table[0], &helper, &mainfw);
889 if (ret) { 896 if (ret) {
890 lbs_pr_err("failed to find firmware (%d)\n", ret); 897 pr_err("failed to find firmware (%d)\n", ret);
891 goto out2; 898 goto out2;
892 } 899 }
893 900
@@ -918,7 +925,7 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
918 ret = request_irq(p_dev->irq, if_cs_interrupt, 925 ret = request_irq(p_dev->irq, if_cs_interrupt,
919 IRQF_SHARED, DRV_NAME, card); 926 IRQF_SHARED, DRV_NAME, card);
920 if (ret) { 927 if (ret) {
921 lbs_pr_err("error in request_irq\n"); 928 pr_err("error in request_irq\n");
922 goto out3; 929 goto out3;
923 } 930 }
924 931
@@ -931,7 +938,7 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
931 938
932 /* And finally bring the card up */ 939 /* And finally bring the card up */
933 if (lbs_start_card(priv) != 0) { 940 if (lbs_start_card(priv) != 0) {
934 lbs_pr_err("could not activate card\n"); 941 pr_err("could not activate card\n");
935 goto out3; 942 goto out3;
936 } 943 }
937 944
diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c
index b4de0ca10feb..a7b5cb0c2753 100644
--- a/drivers/net/wireless/libertas/if_sdio.c
+++ b/drivers/net/wireless/libertas/if_sdio.c
@@ -26,6 +26,8 @@
26 * if_sdio_card_to_host() to pad the data. 26 * if_sdio_card_to_host() to pad the data.
27 */ 27 */
28 28
29#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
30
29#include <linux/kernel.h> 31#include <linux/kernel.h>
30#include <linux/moduleparam.h> 32#include <linux/moduleparam.h>
31#include <linux/slab.h> 33#include <linux/slab.h>
@@ -409,7 +411,7 @@ static int if_sdio_card_to_host(struct if_sdio_card *card)
409 411
410out: 412out:
411 if (ret) 413 if (ret)
412 lbs_pr_err("problem fetching packet from firmware\n"); 414 pr_err("problem fetching packet from firmware\n");
413 415
414 lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret); 416 lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
415 417
@@ -446,7 +448,7 @@ static void if_sdio_host_to_card_worker(struct work_struct *work)
446 } 448 }
447 449
448 if (ret) 450 if (ret)
449 lbs_pr_err("error %d sending packet to firmware\n", ret); 451 pr_err("error %d sending packet to firmware\n", ret);
450 452
451 sdio_release_host(card->func); 453 sdio_release_host(card->func);
452 454
@@ -555,7 +557,7 @@ release:
555 557
556out: 558out:
557 if (ret) 559 if (ret)
558 lbs_pr_err("failed to load helper firmware\n"); 560 pr_err("failed to load helper firmware\n");
559 561
560 lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret); 562 lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
561 return ret; 563 return ret;
@@ -669,7 +671,7 @@ release:
669 671
670out: 672out:
671 if (ret) 673 if (ret)
672 lbs_pr_err("failed to load firmware\n"); 674 pr_err("failed to load firmware\n");
673 675
674 lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret); 676 lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
675 return ret; 677 return ret;
@@ -723,7 +725,7 @@ static int if_sdio_prog_firmware(struct if_sdio_card *card)
723 ret = lbs_get_firmware(&card->func->dev, lbs_helper_name, lbs_fw_name, 725 ret = lbs_get_firmware(&card->func->dev, lbs_helper_name, lbs_fw_name,
724 card->model, &fw_table[0], &helper, &mainfw); 726 card->model, &fw_table[0], &helper, &mainfw);
725 if (ret) { 727 if (ret) {
726 lbs_pr_err("failed to find firmware (%d)\n", ret); 728 pr_err("failed to find firmware (%d)\n", ret);
727 goto out; 729 goto out;
728 } 730 }
729 731
@@ -849,7 +851,7 @@ static int if_sdio_enter_deep_sleep(struct lbs_private *priv)
849 ret = __lbs_cmd(priv, CMD_802_11_DEEP_SLEEP, &cmd, sizeof(cmd), 851 ret = __lbs_cmd(priv, CMD_802_11_DEEP_SLEEP, &cmd, sizeof(cmd),
850 lbs_cmd_copyback, (unsigned long) &cmd); 852 lbs_cmd_copyback, (unsigned long) &cmd);
851 if (ret) 853 if (ret)
852 lbs_pr_err("DEEP_SLEEP cmd failed\n"); 854 netdev_err(priv->dev, "DEEP_SLEEP cmd failed\n");
853 855
854 mdelay(200); 856 mdelay(200);
855 return ret; 857 return ret;
@@ -865,7 +867,7 @@ static int if_sdio_exit_deep_sleep(struct lbs_private *priv)
865 867
866 sdio_writeb(card->func, HOST_POWER_UP, CONFIGURATION_REG, &ret); 868 sdio_writeb(card->func, HOST_POWER_UP, CONFIGURATION_REG, &ret);
867 if (ret) 869 if (ret)
868 lbs_pr_err("sdio_writeb failed!\n"); 870 netdev_err(priv->dev, "sdio_writeb failed!\n");
869 871
870 sdio_release_host(card->func); 872 sdio_release_host(card->func);
871 lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret); 873 lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
@@ -882,7 +884,7 @@ static int if_sdio_reset_deep_sleep_wakeup(struct lbs_private *priv)
882 884
883 sdio_writeb(card->func, 0, CONFIGURATION_REG, &ret); 885 sdio_writeb(card->func, 0, CONFIGURATION_REG, &ret);
884 if (ret) 886 if (ret)
885 lbs_pr_err("sdio_writeb failed!\n"); 887 netdev_err(priv->dev, "sdio_writeb failed!\n");
886 888
887 sdio_release_host(card->func); 889 sdio_release_host(card->func);
888 lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret); 890 lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
@@ -961,7 +963,7 @@ static int if_sdio_probe(struct sdio_func *func,
961 } 963 }
962 964
963 if (i == func->card->num_info) { 965 if (i == func->card->num_info) {
964 lbs_pr_err("unable to identify card model\n"); 966 pr_err("unable to identify card model\n");
965 return -ENODEV; 967 return -ENODEV;
966 } 968 }
967 969
@@ -995,7 +997,7 @@ static int if_sdio_probe(struct sdio_func *func,
995 break; 997 break;
996 } 998 }
997 if (i == ARRAY_SIZE(fw_table)) { 999 if (i == ARRAY_SIZE(fw_table)) {
998 lbs_pr_err("unknown card model 0x%x\n", card->model); 1000 pr_err("unknown card model 0x%x\n", card->model);
999 ret = -ENODEV; 1001 ret = -ENODEV;
1000 goto free; 1002 goto free;
1001 } 1003 }
@@ -1101,7 +1103,7 @@ static int if_sdio_probe(struct sdio_func *func,
1101 lbs_deb_sdio("send function INIT command\n"); 1103 lbs_deb_sdio("send function INIT command\n");
1102 if (__lbs_cmd(priv, CMD_FUNC_INIT, &cmd, sizeof(cmd), 1104 if (__lbs_cmd(priv, CMD_FUNC_INIT, &cmd, sizeof(cmd),
1103 lbs_cmd_copyback, (unsigned long) &cmd)) 1105 lbs_cmd_copyback, (unsigned long) &cmd))
1104 lbs_pr_alert("CMD_FUNC_INIT cmd failed\n"); 1106 netdev_alert(priv->dev, "CMD_FUNC_INIT cmd failed\n");
1105 } 1107 }
1106 1108
1107 ret = lbs_start_card(priv); 1109 ret = lbs_start_card(priv);
@@ -1163,7 +1165,7 @@ static void if_sdio_remove(struct sdio_func *func)
1163 if (__lbs_cmd(card->priv, CMD_FUNC_SHUTDOWN, 1165 if (__lbs_cmd(card->priv, CMD_FUNC_SHUTDOWN,
1164 &cmd, sizeof(cmd), lbs_cmd_copyback, 1166 &cmd, sizeof(cmd), lbs_cmd_copyback,
1165 (unsigned long) &cmd)) 1167 (unsigned long) &cmd))
1166 lbs_pr_alert("CMD_FUNC_SHUTDOWN cmd failed\n"); 1168 pr_alert("CMD_FUNC_SHUTDOWN cmd failed\n");
1167 } 1169 }
1168 1170
1169 1171
@@ -1202,20 +1204,19 @@ static int if_sdio_suspend(struct device *dev)
1202 1204
1203 mmc_pm_flag_t flags = sdio_get_host_pm_caps(func); 1205 mmc_pm_flag_t flags = sdio_get_host_pm_caps(func);
1204 1206
1205 lbs_pr_info("%s: suspend: PM flags = 0x%x\n", 1207 dev_info(dev, "%s: suspend: PM flags = 0x%x\n",
1206 sdio_func_id(func), flags); 1208 sdio_func_id(func), flags);
1207 1209
1208 /* If we aren't being asked to wake on anything, we should bail out 1210 /* If we aren't being asked to wake on anything, we should bail out
1209 * and let the SD stack power down the card. 1211 * and let the SD stack power down the card.
1210 */ 1212 */
1211 if (card->priv->wol_criteria == EHS_REMOVE_WAKEUP) { 1213 if (card->priv->wol_criteria == EHS_REMOVE_WAKEUP) {
1212 lbs_pr_info("Suspend without wake params -- " 1214 dev_info(dev, "Suspend without wake params -- powering down card\n");
1213 "powering down card.");
1214 return -ENOSYS; 1215 return -ENOSYS;
1215 } 1216 }
1216 1217
1217 if (!(flags & MMC_PM_KEEP_POWER)) { 1218 if (!(flags & MMC_PM_KEEP_POWER)) {
1218 lbs_pr_err("%s: cannot remain alive while host is suspended\n", 1219 dev_err(dev, "%s: cannot remain alive while host is suspended\n",
1219 sdio_func_id(func)); 1220 sdio_func_id(func));
1220 return -ENOSYS; 1221 return -ENOSYS;
1221 } 1222 }
@@ -1237,7 +1238,7 @@ static int if_sdio_resume(struct device *dev)
1237 struct if_sdio_card *card = sdio_get_drvdata(func); 1238 struct if_sdio_card *card = sdio_get_drvdata(func);
1238 int ret; 1239 int ret;
1239 1240
1240 lbs_pr_info("%s: resume: we're back\n", sdio_func_id(func)); 1241 dev_info(dev, "%s: resume: we're back\n", sdio_func_id(func));
1241 1242
1242 ret = lbs_resume(card->priv); 1243 ret = lbs_resume(card->priv);
1243 1244
diff --git a/drivers/net/wireless/libertas/if_spi.c b/drivers/net/wireless/libertas/if_spi.c
index 67de5b3c68b2..463352c890d7 100644
--- a/drivers/net/wireless/libertas/if_spi.c
+++ b/drivers/net/wireless/libertas/if_spi.c
@@ -17,6 +17,8 @@
17 * (at your option) any later version. 17 * (at your option) any later version.
18 */ 18 */
19 19
20#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
21
20#include <linux/moduleparam.h> 22#include <linux/moduleparam.h>
21#include <linux/firmware.h> 23#include <linux/firmware.h>
22#include <linux/jiffies.h> 24#include <linux/jiffies.h>
@@ -305,8 +307,7 @@ static int spu_wait_for_u16(struct if_spi_card *card, u16 reg,
305 } 307 }
306 udelay(100); 308 udelay(100);
307 if (time_after(jiffies, timeout)) { 309 if (time_after(jiffies, timeout)) {
308 lbs_pr_err("%s: timeout with val=%02x, " 310 pr_err("%s: timeout with val=%02x, target_mask=%02x, target=%02x\n",
309 "target_mask=%02x, target=%02x\n",
310 __func__, val, target_mask, target); 311 __func__, val, target_mask, target);
311 return -ETIMEDOUT; 312 return -ETIMEDOUT;
312 } 313 }
@@ -405,7 +406,7 @@ static int spu_set_bus_mode(struct if_spi_card *card, u16 mode)
405 if (err) 406 if (err)
406 return err; 407 return err;
407 if ((rval & 0xF) != mode) { 408 if ((rval & 0xF) != mode) {
408 lbs_pr_err("Can't read bus mode register.\n"); 409 pr_err("Can't read bus mode register\n");
409 return -EIO; 410 return -EIO;
410 } 411 }
411 return 0; 412 return 0;
@@ -534,7 +535,7 @@ static int if_spi_prog_helper_firmware(struct if_spi_card *card,
534 535
535out: 536out:
536 if (err) 537 if (err)
537 lbs_pr_err("failed to load helper firmware (err=%d)\n", err); 538 pr_err("failed to load helper firmware (err=%d)\n", err);
538 lbs_deb_leave_args(LBS_DEB_SPI, "err %d", err); 539 lbs_deb_leave_args(LBS_DEB_SPI, "err %d", err);
539 return err; 540 return err;
540} 541}
@@ -557,7 +558,7 @@ static int if_spi_prog_main_firmware_check_len(struct if_spi_card *card,
557 IF_SPI_HIST_CMD_DOWNLOAD_RDY, 558 IF_SPI_HIST_CMD_DOWNLOAD_RDY,
558 IF_SPI_HIST_CMD_DOWNLOAD_RDY); 559 IF_SPI_HIST_CMD_DOWNLOAD_RDY);
559 if (err) { 560 if (err) {
560 lbs_pr_err("timed out waiting for host_int_status\n"); 561 pr_err("timed out waiting for host_int_status\n");
561 return err; 562 return err;
562 } 563 }
563 564
@@ -567,9 +568,8 @@ static int if_spi_prog_main_firmware_check_len(struct if_spi_card *card,
567 return err; 568 return err;
568 569
569 if (len > IF_SPI_CMD_BUF_SIZE) { 570 if (len > IF_SPI_CMD_BUF_SIZE) {
570 lbs_pr_err("firmware load device requested a larger " 571 pr_err("firmware load device requested a larger transfer than we are prepared to handle (len = %d)\n",
571 "tranfer than we are prepared to " 572 len);
572 "handle. (len = %d)\n", len);
573 return -EIO; 573 return -EIO;
574 } 574 }
575 if (len & 0x1) { 575 if (len & 0x1) {
@@ -585,6 +585,7 @@ static int if_spi_prog_main_firmware_check_len(struct if_spi_card *card,
585static int if_spi_prog_main_firmware(struct if_spi_card *card, 585static int if_spi_prog_main_firmware(struct if_spi_card *card,
586 const struct firmware *firmware) 586 const struct firmware *firmware)
587{ 587{
588 struct lbs_private *priv = card->priv;
588 int len, prev_len; 589 int len, prev_len;
589 int bytes, crc_err = 0, err = 0; 590 int bytes, crc_err = 0, err = 0;
590 const u8 *fw; 591 const u8 *fw;
@@ -598,8 +599,9 @@ static int if_spi_prog_main_firmware(struct if_spi_card *card,
598 599
599 err = spu_wait_for_u16(card, IF_SPI_SCRATCH_1_REG, 0, 0); 600 err = spu_wait_for_u16(card, IF_SPI_SCRATCH_1_REG, 0, 0);
600 if (err) { 601 if (err) {
601 lbs_pr_err("%s: timed out waiting for initial " 602 netdev_err(priv->dev,
602 "scratch reg = 0\n", __func__); 603 "%s: timed out waiting for initial scratch reg = 0\n",
604 __func__);
603 goto out; 605 goto out;
604 } 606 }
605 607
@@ -617,15 +619,14 @@ static int if_spi_prog_main_firmware(struct if_spi_card *card,
617 * If there are no more bytes left, we would normally 619 * If there are no more bytes left, we would normally
618 * expect to have terminated with len = 0 620 * expect to have terminated with len = 0
619 */ 621 */
620 lbs_pr_err("Firmware load wants more bytes " 622 netdev_err(priv->dev,
621 "than we have to offer.\n"); 623 "Firmware load wants more bytes than we have to offer.\n");
622 break; 624 break;
623 } 625 }
624 if (crc_err) { 626 if (crc_err) {
625 /* Previous transfer failed. */ 627 /* Previous transfer failed. */
626 if (++num_crc_errs > MAX_MAIN_FW_LOAD_CRC_ERR) { 628 if (++num_crc_errs > MAX_MAIN_FW_LOAD_CRC_ERR) {
627 lbs_pr_err("Too many CRC errors encountered " 629 pr_err("Too many CRC errors encountered in firmware load.\n");
628 "in firmware load.\n");
629 err = -EIO; 630 err = -EIO;
630 goto out; 631 goto out;
631 } 632 }
@@ -654,21 +655,20 @@ static int if_spi_prog_main_firmware(struct if_spi_card *card,
654 prev_len = len; 655 prev_len = len;
655 } 656 }
656 if (bytes > prev_len) { 657 if (bytes > prev_len) {
657 lbs_pr_err("firmware load wants fewer bytes than " 658 pr_err("firmware load wants fewer bytes than we have to offer\n");
658 "we have to offer.\n");
659 } 659 }
660 660
661 /* Confirm firmware download */ 661 /* Confirm firmware download */
662 err = spu_wait_for_u32(card, IF_SPI_SCRATCH_4_REG, 662 err = spu_wait_for_u32(card, IF_SPI_SCRATCH_4_REG,
663 SUCCESSFUL_FW_DOWNLOAD_MAGIC); 663 SUCCESSFUL_FW_DOWNLOAD_MAGIC);
664 if (err) { 664 if (err) {
665 lbs_pr_err("failed to confirm the firmware download\n"); 665 pr_err("failed to confirm the firmware download\n");
666 goto out; 666 goto out;
667 } 667 }
668 668
669out: 669out:
670 if (err) 670 if (err)
671 lbs_pr_err("failed to load firmware (err=%d)\n", err); 671 pr_err("failed to load firmware (err=%d)\n", err);
672 lbs_deb_leave_args(LBS_DEB_SPI, "err %d", err); 672 lbs_deb_leave_args(LBS_DEB_SPI, "err %d", err);
673 return err; 673 return err;
674} 674}
@@ -709,13 +709,13 @@ static int if_spi_c2h_cmd(struct if_spi_card *card)
709 if (err) 709 if (err)
710 goto out; 710 goto out;
711 if (!len) { 711 if (!len) {
712 lbs_pr_err("%s: error: card has no data for host\n", 712 netdev_err(priv->dev, "%s: error: card has no data for host\n",
713 __func__); 713 __func__);
714 err = -EINVAL; 714 err = -EINVAL;
715 goto out; 715 goto out;
716 } else if (len > IF_SPI_CMD_BUF_SIZE) { 716 } else if (len > IF_SPI_CMD_BUF_SIZE) {
717 lbs_pr_err("%s: error: response packet too large: " 717 netdev_err(priv->dev,
718 "%d bytes, but maximum is %d\n", 718 "%s: error: response packet too large: %d bytes, but maximum is %d\n",
719 __func__, len, IF_SPI_CMD_BUF_SIZE); 719 __func__, len, IF_SPI_CMD_BUF_SIZE);
720 err = -EINVAL; 720 err = -EINVAL;
721 goto out; 721 goto out;
@@ -737,7 +737,7 @@ static int if_spi_c2h_cmd(struct if_spi_card *card)
737 737
738out: 738out:
739 if (err) 739 if (err)
740 lbs_pr_err("%s: err=%d\n", __func__, err); 740 netdev_err(priv->dev, "%s: err=%d\n", __func__, err);
741 lbs_deb_leave(LBS_DEB_SPI); 741 lbs_deb_leave(LBS_DEB_SPI);
742 return err; 742 return err;
743} 743}
@@ -745,6 +745,7 @@ out:
745/* Move data from the card to the host */ 745/* Move data from the card to the host */
746static int if_spi_c2h_data(struct if_spi_card *card) 746static int if_spi_c2h_data(struct if_spi_card *card)
747{ 747{
748 struct lbs_private *priv = card->priv;
748 struct sk_buff *skb; 749 struct sk_buff *skb;
749 char *data; 750 char *data;
750 u16 len; 751 u16 len;
@@ -757,13 +758,13 @@ static int if_spi_c2h_data(struct if_spi_card *card)
757 if (err) 758 if (err)
758 goto out; 759 goto out;
759 if (!len) { 760 if (!len) {
760 lbs_pr_err("%s: error: card has no data for host\n", 761 netdev_err(priv->dev, "%s: error: card has no data for host\n",
761 __func__); 762 __func__);
762 err = -EINVAL; 763 err = -EINVAL;
763 goto out; 764 goto out;
764 } else if (len > MRVDRV_ETH_RX_PACKET_BUFFER_SIZE) { 765 } else if (len > MRVDRV_ETH_RX_PACKET_BUFFER_SIZE) {
765 lbs_pr_err("%s: error: card has %d bytes of data, but " 766 netdev_err(priv->dev,
766 "our maximum skb size is %zu\n", 767 "%s: error: card has %d bytes of data, but our maximum skb size is %zu\n",
767 __func__, len, MRVDRV_ETH_RX_PACKET_BUFFER_SIZE); 768 __func__, len, MRVDRV_ETH_RX_PACKET_BUFFER_SIZE);
768 err = -EINVAL; 769 err = -EINVAL;
769 goto out; 770 goto out;
@@ -795,7 +796,7 @@ free_skb:
795 dev_kfree_skb(skb); 796 dev_kfree_skb(skb);
796out: 797out:
797 if (err) 798 if (err)
798 lbs_pr_err("%s: err=%d\n", __func__, err); 799 netdev_err(priv->dev, "%s: err=%d\n", __func__, err);
799 lbs_deb_leave(LBS_DEB_SPI); 800 lbs_deb_leave(LBS_DEB_SPI);
800 return err; 801 return err;
801} 802}
@@ -804,6 +805,7 @@ out:
804static void if_spi_h2c(struct if_spi_card *card, 805static void if_spi_h2c(struct if_spi_card *card,
805 struct if_spi_packet *packet, int type) 806 struct if_spi_packet *packet, int type)
806{ 807{
808 struct lbs_private *priv = card->priv;
807 int err = 0; 809 int err = 0;
808 u16 int_type, port_reg; 810 u16 int_type, port_reg;
809 811
@@ -817,7 +819,8 @@ static void if_spi_h2c(struct if_spi_card *card,
817 port_reg = IF_SPI_CMD_RDWRPORT_REG; 819 port_reg = IF_SPI_CMD_RDWRPORT_REG;
818 break; 820 break;
819 default: 821 default:
820 lbs_pr_err("can't transfer buffer of type %d\n", type); 822 netdev_err(priv->dev, "can't transfer buffer of type %d\n",
823 type);
821 err = -EINVAL; 824 err = -EINVAL;
822 goto out; 825 goto out;
823 } 826 }
@@ -831,7 +834,7 @@ out:
831 kfree(packet); 834 kfree(packet);
832 835
833 if (err) 836 if (err)
834 lbs_pr_err("%s: error %d\n", __func__, err); 837 netdev_err(priv->dev, "%s: error %d\n", __func__, err);
835} 838}
836 839
837/* Inform the host about a card event */ 840/* Inform the host about a card event */
@@ -855,7 +858,7 @@ static void if_spi_e2h(struct if_spi_card *card)
855 lbs_queue_event(priv, cause & 0xff); 858 lbs_queue_event(priv, cause & 0xff);
856out: 859out:
857 if (err) 860 if (err)
858 lbs_pr_err("%s: error %d\n", __func__, err); 861 netdev_err(priv->dev, "%s: error %d\n", __func__, err);
859} 862}
860 863
861static void if_spi_host_to_card_worker(struct work_struct *work) 864static void if_spi_host_to_card_worker(struct work_struct *work)
@@ -865,8 +868,10 @@ static void if_spi_host_to_card_worker(struct work_struct *work)
865 u16 hiStatus; 868 u16 hiStatus;
866 unsigned long flags; 869 unsigned long flags;
867 struct if_spi_packet *packet; 870 struct if_spi_packet *packet;
871 struct lbs_private *priv;
868 872
869 card = container_of(work, struct if_spi_card, packet_work); 873 card = container_of(work, struct if_spi_card, packet_work);
874 priv = card->priv;
870 875
871 lbs_deb_enter(LBS_DEB_SPI); 876 lbs_deb_enter(LBS_DEB_SPI);
872 877
@@ -877,7 +882,7 @@ static void if_spi_host_to_card_worker(struct work_struct *work)
877 err = spu_read_u16(card, IF_SPI_HOST_INT_STATUS_REG, 882 err = spu_read_u16(card, IF_SPI_HOST_INT_STATUS_REG,
878 &hiStatus); 883 &hiStatus);
879 if (err) { 884 if (err) {
880 lbs_pr_err("I/O error\n"); 885 netdev_err(priv->dev, "I/O error\n");
881 goto err; 886 goto err;
882 } 887 }
883 888
@@ -940,7 +945,7 @@ static void if_spi_host_to_card_worker(struct work_struct *work)
940 945
941err: 946err:
942 if (err) 947 if (err)
943 lbs_pr_err("%s: got error %d\n", __func__, err); 948 netdev_err(priv->dev, "%s: got error %d\n", __func__, err);
944 949
945 lbs_deb_leave(LBS_DEB_SPI); 950 lbs_deb_leave(LBS_DEB_SPI);
946} 951}
@@ -963,7 +968,8 @@ static int if_spi_host_to_card(struct lbs_private *priv,
963 lbs_deb_enter_args(LBS_DEB_SPI, "type %d, bytes %d", type, nb); 968 lbs_deb_enter_args(LBS_DEB_SPI, "type %d, bytes %d", type, nb);
964 969
965 if (nb == 0) { 970 if (nb == 0) {
966 lbs_pr_err("%s: invalid size requested: %d\n", __func__, nb); 971 netdev_err(priv->dev, "%s: invalid size requested: %d\n",
972 __func__, nb);
967 err = -EINVAL; 973 err = -EINVAL;
968 goto out; 974 goto out;
969 } 975 }
@@ -991,7 +997,8 @@ static int if_spi_host_to_card(struct lbs_private *priv,
991 spin_unlock_irqrestore(&card->buffer_lock, flags); 997 spin_unlock_irqrestore(&card->buffer_lock, flags);
992 break; 998 break;
993 default: 999 default:
994 lbs_pr_err("can't transfer buffer of type %d", type); 1000 netdev_err(priv->dev, "can't transfer buffer of type %d\n",
1001 type);
995 err = -EINVAL; 1002 err = -EINVAL;
996 break; 1003 break;
997 } 1004 }
@@ -1024,6 +1031,7 @@ static irqreturn_t if_spi_host_interrupt(int irq, void *dev_id)
1024 1031
1025static int if_spi_init_card(struct if_spi_card *card) 1032static int if_spi_init_card(struct if_spi_card *card)
1026{ 1033{
1034 struct lbs_private *priv = card->priv;
1027 struct spi_device *spi = card->spi; 1035 struct spi_device *spi = card->spi;
1028 int err, i; 1036 int err, i;
1029 u32 scratch; 1037 u32 scratch;
@@ -1052,8 +1060,8 @@ static int if_spi_init_card(struct if_spi_card *card)
1052 break; 1060 break;
1053 } 1061 }
1054 if (i == ARRAY_SIZE(fw_table)) { 1062 if (i == ARRAY_SIZE(fw_table)) {
1055 lbs_pr_err("Unsupported chip_id: 0x%02x\n", 1063 netdev_err(priv->dev, "Unsupported chip_id: 0x%02x\n",
1056 card->card_id); 1064 card->card_id);
1057 err = -ENODEV; 1065 err = -ENODEV;
1058 goto out; 1066 goto out;
1059 } 1067 }
@@ -1062,7 +1070,8 @@ static int if_spi_init_card(struct if_spi_card *card)
1062 card->card_id, &fw_table[0], &helper, 1070 card->card_id, &fw_table[0], &helper,
1063 &mainfw); 1071 &mainfw);
1064 if (err) { 1072 if (err) {
1065 lbs_pr_err("failed to find firmware (%d)\n", err); 1073 netdev_err(priv->dev, "failed to find firmware (%d)\n",
1074 err);
1066 goto out; 1075 goto out;
1067 } 1076 }
1068 1077
@@ -1187,7 +1196,7 @@ static int __devinit if_spi_probe(struct spi_device *spi)
1187 err = request_irq(spi->irq, if_spi_host_interrupt, 1196 err = request_irq(spi->irq, if_spi_host_interrupt,
1188 IRQF_TRIGGER_FALLING, "libertas_spi", card); 1197 IRQF_TRIGGER_FALLING, "libertas_spi", card);
1189 if (err) { 1198 if (err) {
1190 lbs_pr_err("can't get host irq line-- request_irq failed\n"); 1199 pr_err("can't get host irq line-- request_irq failed\n");
1191 goto terminate_workqueue; 1200 goto terminate_workqueue;
1192 } 1201 }
1193 1202
diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c
index e1e2128f4113..b5acc393a65a 100644
--- a/drivers/net/wireless/libertas/if_usb.c
+++ b/drivers/net/wireless/libertas/if_usb.c
@@ -1,6 +1,9 @@
1/* 1/*
2 * This file contains functions used in USB interface module. 2 * This file contains functions used in USB interface module.
3 */ 3 */
4
5#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
6
4#include <linux/delay.h> 7#include <linux/delay.h>
5#include <linux/moduleparam.h> 8#include <linux/moduleparam.h>
6#include <linux/firmware.h> 9#include <linux/firmware.h>
@@ -153,7 +156,7 @@ static void if_usb_write_bulk_callback(struct urb *urb)
153 lbs_host_to_card_done(priv); 156 lbs_host_to_card_done(priv);
154 } else { 157 } else {
155 /* print the failure status number for debug */ 158 /* print the failure status number for debug */
156 lbs_pr_info("URB in failure status: %d\n", urb->status); 159 pr_info("URB in failure status: %d\n", urb->status);
157 } 160 }
158} 161}
159 162
@@ -203,7 +206,7 @@ static void if_usb_setup_firmware(struct lbs_private *priv)
203 wake_method.hdr.size = cpu_to_le16(sizeof(wake_method)); 206 wake_method.hdr.size = cpu_to_le16(sizeof(wake_method));
204 wake_method.action = cpu_to_le16(CMD_ACT_GET); 207 wake_method.action = cpu_to_le16(CMD_ACT_GET);
205 if (lbs_cmd_with_response(priv, CMD_802_11_FW_WAKE_METHOD, &wake_method)) { 208 if (lbs_cmd_with_response(priv, CMD_802_11_FW_WAKE_METHOD, &wake_method)) {
206 lbs_pr_info("Firmware does not seem to support PS mode\n"); 209 netdev_info(priv->dev, "Firmware does not seem to support PS mode\n");
207 priv->fwcapinfo &= ~FW_CAPINFO_PS; 210 priv->fwcapinfo &= ~FW_CAPINFO_PS;
208 } else { 211 } else {
209 if (le16_to_cpu(wake_method.method) == CMD_WAKE_METHOD_COMMAND_INT) { 212 if (le16_to_cpu(wake_method.method) == CMD_WAKE_METHOD_COMMAND_INT) {
@@ -212,7 +215,8 @@ static void if_usb_setup_firmware(struct lbs_private *priv)
212 /* The versions which boot up this way don't seem to 215 /* The versions which boot up this way don't seem to
213 work even if we set it to the command interrupt */ 216 work even if we set it to the command interrupt */
214 priv->fwcapinfo &= ~FW_CAPINFO_PS; 217 priv->fwcapinfo &= ~FW_CAPINFO_PS;
215 lbs_pr_info("Firmware doesn't wake via command interrupt; disabling PS mode\n"); 218 netdev_info(priv->dev,
219 "Firmware doesn't wake via command interrupt; disabling PS mode\n");
216 } 220 }
217 } 221 }
218} 222}
@@ -224,7 +228,7 @@ static void if_usb_fw_timeo(unsigned long priv)
224 if (cardp->fwdnldover) { 228 if (cardp->fwdnldover) {
225 lbs_deb_usb("Download complete, no event. Assuming success\n"); 229 lbs_deb_usb("Download complete, no event. Assuming success\n");
226 } else { 230 } else {
227 lbs_pr_err("Download timed out\n"); 231 pr_err("Download timed out\n");
228 cardp->surprise_removed = 1; 232 cardp->surprise_removed = 1;
229 } 233 }
230 wake_up(&cardp->fw_wq); 234 wake_up(&cardp->fw_wq);
@@ -258,7 +262,7 @@ static int if_usb_probe(struct usb_interface *intf,
258 262
259 cardp = kzalloc(sizeof(struct if_usb_card), GFP_KERNEL); 263 cardp = kzalloc(sizeof(struct if_usb_card), GFP_KERNEL);
260 if (!cardp) { 264 if (!cardp) {
261 lbs_pr_err("Out of memory allocating private data.\n"); 265 pr_err("Out of memory allocating private data\n");
262 goto error; 266 goto error;
263 } 267 }
264 268
@@ -348,10 +352,12 @@ static int if_usb_probe(struct usb_interface *intf,
348 usb_set_intfdata(intf, cardp); 352 usb_set_intfdata(intf, cardp);
349 353
350 if (device_create_file(&priv->dev->dev, &dev_attr_lbs_flash_fw)) 354 if (device_create_file(&priv->dev->dev, &dev_attr_lbs_flash_fw))
351 lbs_pr_err("cannot register lbs_flash_fw attribute\n"); 355 netdev_err(priv->dev,
356 "cannot register lbs_flash_fw attribute\n");
352 357
353 if (device_create_file(&priv->dev->dev, &dev_attr_lbs_flash_boot2)) 358 if (device_create_file(&priv->dev->dev, &dev_attr_lbs_flash_boot2))
354 lbs_pr_err("cannot register lbs_flash_boot2 attribute\n"); 359 netdev_err(priv->dev,
360 "cannot register lbs_flash_boot2 attribute\n");
355 361
356 /* 362 /*
357 * EHS_REMOVE_WAKEUP is not supported on all versions of the firmware. 363 * EHS_REMOVE_WAKEUP is not supported on all versions of the firmware.
@@ -536,7 +542,7 @@ static int __if_usb_submit_rx_urb(struct if_usb_card *cardp,
536 int ret = -1; 542 int ret = -1;
537 543
538 if (!(skb = dev_alloc_skb(MRVDRV_ETH_RX_PACKET_BUFFER_SIZE))) { 544 if (!(skb = dev_alloc_skb(MRVDRV_ETH_RX_PACKET_BUFFER_SIZE))) {
539 lbs_pr_err("No free skb\n"); 545 pr_err("No free skb\n");
540 goto rx_ret; 546 goto rx_ret;
541 } 547 }
542 548
@@ -595,7 +601,7 @@ static void if_usb_receive_fwload(struct urb *urb)
595 601
596 if (tmp[0] == cpu_to_le32(CMD_TYPE_INDICATION) && 602 if (tmp[0] == cpu_to_le32(CMD_TYPE_INDICATION) &&
597 tmp[1] == cpu_to_le32(MACREG_INT_CODE_FIRMWARE_READY)) { 603 tmp[1] == cpu_to_le32(MACREG_INT_CODE_FIRMWARE_READY)) {
598 lbs_pr_info("Firmware ready event received\n"); 604 pr_info("Firmware ready event received\n");
599 wake_up(&cardp->fw_wq); 605 wake_up(&cardp->fw_wq);
600 } else { 606 } else {
601 lbs_deb_usb("Waiting for confirmation; got %x %x\n", 607 lbs_deb_usb("Waiting for confirmation; got %x %x\n",
@@ -622,20 +628,20 @@ static void if_usb_receive_fwload(struct urb *urb)
622 bootcmdresp.magic == cpu_to_le32(CMD_TYPE_DATA) || 628 bootcmdresp.magic == cpu_to_le32(CMD_TYPE_DATA) ||
623 bootcmdresp.magic == cpu_to_le32(CMD_TYPE_INDICATION)) { 629 bootcmdresp.magic == cpu_to_le32(CMD_TYPE_INDICATION)) {
624 if (!cardp->bootcmdresp) 630 if (!cardp->bootcmdresp)
625 lbs_pr_info("Firmware already seems alive; resetting\n"); 631 pr_info("Firmware already seems alive; resetting\n");
626 cardp->bootcmdresp = -1; 632 cardp->bootcmdresp = -1;
627 } else { 633 } else {
628 lbs_pr_info("boot cmd response wrong magic number (0x%x)\n", 634 pr_info("boot cmd response wrong magic number (0x%x)\n",
629 le32_to_cpu(bootcmdresp.magic)); 635 le32_to_cpu(bootcmdresp.magic));
630 } 636 }
631 } else if ((bootcmdresp.cmd != BOOT_CMD_FW_BY_USB) && 637 } else if ((bootcmdresp.cmd != BOOT_CMD_FW_BY_USB) &&
632 (bootcmdresp.cmd != BOOT_CMD_UPDATE_FW) && 638 (bootcmdresp.cmd != BOOT_CMD_UPDATE_FW) &&
633 (bootcmdresp.cmd != BOOT_CMD_UPDATE_BOOT2)) { 639 (bootcmdresp.cmd != BOOT_CMD_UPDATE_BOOT2)) {
634 lbs_pr_info("boot cmd response cmd_tag error (%d)\n", 640 pr_info("boot cmd response cmd_tag error (%d)\n",
635 bootcmdresp.cmd); 641 bootcmdresp.cmd);
636 } else if (bootcmdresp.result != BOOT_CMD_RESP_OK) { 642 } else if (bootcmdresp.result != BOOT_CMD_RESP_OK) {
637 lbs_pr_info("boot cmd response result error (%d)\n", 643 pr_info("boot cmd response result error (%d)\n",
638 bootcmdresp.result); 644 bootcmdresp.result);
639 } else { 645 } else {
640 cardp->bootcmdresp = 1; 646 cardp->bootcmdresp = 1;
641 lbs_deb_usbd(&cardp->udev->dev, 647 lbs_deb_usbd(&cardp->udev->dev,
@@ -901,7 +907,7 @@ static int check_fwfile_format(const uint8_t *data, uint32_t totlen)
901 } while (!exit); 907 } while (!exit);
902 908
903 if (ret) 909 if (ret)
904 lbs_pr_err("firmware file format check FAIL\n"); 910 pr_err("firmware file format check FAIL\n");
905 else 911 else
906 lbs_deb_fw("firmware file format check PASS\n"); 912 lbs_deb_fw("firmware file format check PASS\n");
907 913
@@ -998,7 +1004,7 @@ static int __if_usb_prog_firmware(struct if_usb_card *cardp,
998 1004
999 ret = get_fw(cardp, fwname); 1005 ret = get_fw(cardp, fwname);
1000 if (ret) { 1006 if (ret) {
1001 lbs_pr_err("failed to find firmware (%d)\n", ret); 1007 pr_err("failed to find firmware (%d)\n", ret);
1002 goto done; 1008 goto done;
1003 } 1009 }
1004 1010
@@ -1073,13 +1079,13 @@ restart:
1073 usb_kill_urb(cardp->rx_urb); 1079 usb_kill_urb(cardp->rx_urb);
1074 1080
1075 if (!cardp->fwdnldover) { 1081 if (!cardp->fwdnldover) {
1076 lbs_pr_info("failed to load fw, resetting device!\n"); 1082 pr_info("failed to load fw, resetting device!\n");
1077 if (--reset_count >= 0) { 1083 if (--reset_count >= 0) {
1078 if_usb_reset_device(cardp); 1084 if_usb_reset_device(cardp);
1079 goto restart; 1085 goto restart;
1080 } 1086 }
1081 1087
1082 lbs_pr_info("FW download failure, time = %d ms\n", i * 100); 1088 pr_info("FW download failure, time = %d ms\n", i * 100);
1083 ret = -EIO; 1089 ret = -EIO;
1084 goto release_fw; 1090 goto release_fw;
1085 } 1091 }
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c
index ed57cf863b69..8c40949cb076 100644
--- a/drivers/net/wireless/libertas/main.c
+++ b/drivers/net/wireless/libertas/main.c
@@ -4,6 +4,8 @@
4 * thread etc.. 4 * thread etc..
5 */ 5 */
6 6
7#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
8
7#include <linux/moduleparam.h> 9#include <linux/moduleparam.h>
8#include <linux/delay.h> 10#include <linux/delay.h>
9#include <linux/etherdevice.h> 11#include <linux/etherdevice.h>
@@ -34,6 +36,10 @@ unsigned int lbs_debug;
34EXPORT_SYMBOL_GPL(lbs_debug); 36EXPORT_SYMBOL_GPL(lbs_debug);
35module_param_named(libertas_debug, lbs_debug, int, 0644); 37module_param_named(libertas_debug, lbs_debug, int, 0644);
36 38
39unsigned int lbs_disablemesh;
40EXPORT_SYMBOL_GPL(lbs_disablemesh);
41module_param_named(libertas_disablemesh, lbs_disablemesh, int, 0644);
42
37 43
38/* 44/*
39 * This global structure is used to send the confirm_sleep command as 45 * This global structure is used to send the confirm_sleep command as
@@ -149,28 +155,6 @@ static int lbs_eth_stop(struct net_device *dev)
149 return 0; 155 return 0;
150} 156}
151 157
152static void lbs_tx_timeout(struct net_device *dev)
153{
154 struct lbs_private *priv = dev->ml_priv;
155
156 lbs_deb_enter(LBS_DEB_TX);
157
158 lbs_pr_err("tx watch dog timeout\n");
159
160 dev->trans_start = jiffies; /* prevent tx timeout */
161
162 if (priv->currenttxskb)
163 lbs_send_tx_feedback(priv, 0);
164
165 /* XX: Shouldn't we also call into the hw-specific driver
166 to kick it somehow? */
167 lbs_host_to_card_done(priv);
168
169 /* FIXME: reset the card */
170
171 lbs_deb_leave(LBS_DEB_TX);
172}
173
174void lbs_host_to_card_done(struct lbs_private *priv) 158void lbs_host_to_card_done(struct lbs_private *priv)
175{ 159{
176 unsigned long flags; 160 unsigned long flags;
@@ -464,8 +448,8 @@ static int lbs_thread(void *data)
464 if (priv->cmd_timed_out && priv->cur_cmd) { 448 if (priv->cmd_timed_out && priv->cur_cmd) {
465 struct cmd_ctrl_node *cmdnode = priv->cur_cmd; 449 struct cmd_ctrl_node *cmdnode = priv->cur_cmd;
466 450
467 lbs_pr_info("Timeout submitting command 0x%04x\n", 451 netdev_info(dev, "Timeout submitting command 0x%04x\n",
468 le16_to_cpu(cmdnode->cmdbuf->command)); 452 le16_to_cpu(cmdnode->cmdbuf->command));
469 lbs_complete_command(priv, cmdnode, -ETIMEDOUT); 453 lbs_complete_command(priv, cmdnode, -ETIMEDOUT);
470 if (priv->reset_card) 454 if (priv->reset_card)
471 priv->reset_card(priv); 455 priv->reset_card(priv);
@@ -492,8 +476,8 @@ static int lbs_thread(void *data)
492 * after firmware fixes it 476 * after firmware fixes it
493 */ 477 */
494 priv->psstate = PS_STATE_AWAKE; 478 priv->psstate = PS_STATE_AWAKE;
495 lbs_pr_alert("ignore PS_SleepConfirm in " 479 netdev_alert(dev,
496 "non-connected state\n"); 480 "ignore PS_SleepConfirm in non-connected state\n");
497 } 481 }
498 } 482 }
499 483
@@ -587,7 +571,8 @@ int lbs_suspend(struct lbs_private *priv)
587 if (priv->is_deep_sleep) { 571 if (priv->is_deep_sleep) {
588 ret = lbs_set_deep_sleep(priv, 0); 572 ret = lbs_set_deep_sleep(priv, 0);
589 if (ret) { 573 if (ret) {
590 lbs_pr_err("deep sleep cancellation failed: %d\n", ret); 574 netdev_err(priv->dev,
575 "deep sleep cancellation failed: %d\n", ret);
591 return ret; 576 return ret;
592 } 577 }
593 priv->deep_sleep_required = 1; 578 priv->deep_sleep_required = 1;
@@ -620,7 +605,8 @@ int lbs_resume(struct lbs_private *priv)
620 priv->deep_sleep_required = 0; 605 priv->deep_sleep_required = 0;
621 ret = lbs_set_deep_sleep(priv, 1); 606 ret = lbs_set_deep_sleep(priv, 1);
622 if (ret) 607 if (ret)
623 lbs_pr_err("deep sleep activation failed: %d\n", ret); 608 netdev_err(priv->dev,
609 "deep sleep activation failed: %d\n", ret);
624 } 610 }
625 611
626 if (priv->setup_fw_on_resume) 612 if (priv->setup_fw_on_resume)
@@ -648,8 +634,8 @@ static void lbs_cmd_timeout_handler(unsigned long data)
648 if (!priv->cur_cmd) 634 if (!priv->cur_cmd)
649 goto out; 635 goto out;
650 636
651 lbs_pr_info("command 0x%04x timed out\n", 637 netdev_info(priv->dev, "command 0x%04x timed out\n",
652 le16_to_cpu(priv->cur_cmd->cmdbuf->command)); 638 le16_to_cpu(priv->cur_cmd->cmdbuf->command));
653 639
654 priv->cmd_timed_out = 1; 640 priv->cmd_timed_out = 1;
655 wake_up_interruptible(&priv->waitq); 641 wake_up_interruptible(&priv->waitq);
@@ -754,7 +740,7 @@ static int lbs_init_adapter(struct lbs_private *priv)
754 740
755 /* Allocate the command buffers */ 741 /* Allocate the command buffers */
756 if (lbs_allocate_cmd_buffer(priv)) { 742 if (lbs_allocate_cmd_buffer(priv)) {
757 lbs_pr_err("Out of memory allocating command buffers\n"); 743 pr_err("Out of memory allocating command buffers\n");
758 ret = -ENOMEM; 744 ret = -ENOMEM;
759 goto out; 745 goto out;
760 } 746 }
@@ -764,7 +750,7 @@ static int lbs_init_adapter(struct lbs_private *priv)
764 /* Create the event FIFO */ 750 /* Create the event FIFO */
765 ret = kfifo_alloc(&priv->event_fifo, sizeof(u32) * 16, GFP_KERNEL); 751 ret = kfifo_alloc(&priv->event_fifo, sizeof(u32) * 16, GFP_KERNEL);
766 if (ret) { 752 if (ret) {
767 lbs_pr_err("Out of memory allocating event FIFO buffer\n"); 753 pr_err("Out of memory allocating event FIFO buffer\n");
768 goto out; 754 goto out;
769 } 755 }
770 756
@@ -791,7 +777,6 @@ static const struct net_device_ops lbs_netdev_ops = {
791 .ndo_stop = lbs_eth_stop, 777 .ndo_stop = lbs_eth_stop,
792 .ndo_start_xmit = lbs_hard_start_xmit, 778 .ndo_start_xmit = lbs_hard_start_xmit,
793 .ndo_set_mac_address = lbs_set_mac_address, 779 .ndo_set_mac_address = lbs_set_mac_address,
794 .ndo_tx_timeout = lbs_tx_timeout,
795 .ndo_set_multicast_list = lbs_set_multicast_list, 780 .ndo_set_multicast_list = lbs_set_multicast_list,
796 .ndo_change_mtu = eth_change_mtu, 781 .ndo_change_mtu = eth_change_mtu,
797 .ndo_validate_addr = eth_validate_addr, 782 .ndo_validate_addr = eth_validate_addr,
@@ -816,7 +801,7 @@ struct lbs_private *lbs_add_card(void *card, struct device *dmdev)
816 /* Allocate an Ethernet device and register it */ 801 /* Allocate an Ethernet device and register it */
817 wdev = lbs_cfg_alloc(dmdev); 802 wdev = lbs_cfg_alloc(dmdev);
818 if (IS_ERR(wdev)) { 803 if (IS_ERR(wdev)) {
819 lbs_pr_err("cfg80211 init failed\n"); 804 pr_err("cfg80211 init failed\n");
820 goto done; 805 goto done;
821 } 806 }
822 807
@@ -825,7 +810,7 @@ struct lbs_private *lbs_add_card(void *card, struct device *dmdev)
825 priv->wdev = wdev; 810 priv->wdev = wdev;
826 811
827 if (lbs_init_adapter(priv)) { 812 if (lbs_init_adapter(priv)) {
828 lbs_pr_err("failed to initialize adapter structure.\n"); 813 pr_err("failed to initialize adapter structure\n");
829 goto err_wdev; 814 goto err_wdev;
830 } 815 }
831 816
@@ -957,17 +942,20 @@ int lbs_start_card(struct lbs_private *priv)
957 goto done; 942 goto done;
958 943
959 if (lbs_cfg_register(priv)) { 944 if (lbs_cfg_register(priv)) {
960 lbs_pr_err("cannot register device\n"); 945 pr_err("cannot register device\n");
961 goto done; 946 goto done;
962 } 947 }
963 948
964 lbs_update_channel(priv); 949 lbs_update_channel(priv);
965 950
966 lbs_init_mesh(priv); 951 if (!lbs_disablemesh)
952 lbs_init_mesh(priv);
953 else
954 pr_info("%s: mesh disabled\n", dev->name);
967 955
968 lbs_debugfs_init_one(priv, dev); 956 lbs_debugfs_init_one(priv, dev);
969 957
970 lbs_pr_info("%s: Marvell WLAN 802.11 adapter\n", dev->name); 958 netdev_info(dev, "Marvell WLAN 802.11 adapter\n");
971 959
972 ret = 0; 960 ret = 0;
973 961
@@ -1094,16 +1082,16 @@ int lbs_get_firmware(struct device *dev, const char *user_helper,
1094 if (user_helper) { 1082 if (user_helper) {
1095 ret = request_firmware(helper, user_helper, dev); 1083 ret = request_firmware(helper, user_helper, dev);
1096 if (ret) { 1084 if (ret) {
1097 lbs_pr_err("couldn't find helper firmware %s", 1085 dev_err(dev, "couldn't find helper firmware %s\n",
1098 user_helper); 1086 user_helper);
1099 goto fail; 1087 goto fail;
1100 } 1088 }
1101 } 1089 }
1102 if (user_mainfw) { 1090 if (user_mainfw) {
1103 ret = request_firmware(mainfw, user_mainfw, dev); 1091 ret = request_firmware(mainfw, user_mainfw, dev);
1104 if (ret) { 1092 if (ret) {
1105 lbs_pr_err("couldn't find main firmware %s", 1093 dev_err(dev, "couldn't find main firmware %s\n",
1106 user_mainfw); 1094 user_mainfw);
1107 goto fail; 1095 goto fail;
1108 } 1096 }
1109 } 1097 }
diff --git a/drivers/net/wireless/libertas/mesh.c b/drivers/net/wireless/libertas/mesh.c
index a0804d12bf20..24cf06680c6b 100644
--- a/drivers/net/wireless/libertas/mesh.c
+++ b/drivers/net/wireless/libertas/mesh.c
@@ -1,3 +1,5 @@
1#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
2
1#include <linux/delay.h> 3#include <linux/delay.h>
2#include <linux/etherdevice.h> 4#include <linux/etherdevice.h>
3#include <linux/netdevice.h> 5#include <linux/netdevice.h>
@@ -267,7 +269,7 @@ int lbs_init_mesh(struct lbs_private *priv)
267 lbs_add_mesh(priv); 269 lbs_add_mesh(priv);
268 270
269 if (device_create_file(&dev->dev, &dev_attr_lbs_mesh)) 271 if (device_create_file(&dev->dev, &dev_attr_lbs_mesh))
270 lbs_pr_err("cannot register lbs_mesh attribute\n"); 272 netdev_err(dev, "cannot register lbs_mesh attribute\n");
271 273
272 ret = 1; 274 ret = 1;
273 } 275 }
@@ -395,7 +397,7 @@ int lbs_add_mesh(struct lbs_private *priv)
395 /* Register virtual mesh interface */ 397 /* Register virtual mesh interface */
396 ret = register_netdev(mesh_dev); 398 ret = register_netdev(mesh_dev);
397 if (ret) { 399 if (ret) {
398 lbs_pr_err("cannot register mshX virtual interface\n"); 400 pr_err("cannot register mshX virtual interface\n");
399 goto err_free; 401 goto err_free;
400 } 402 }
401 403
@@ -973,7 +975,7 @@ static ssize_t mesh_id_get(struct device *dev, struct device_attribute *attr,
973 return ret; 975 return ret;
974 976
975 if (defs.meshie.val.mesh_id_len > IEEE80211_MAX_SSID_LEN) { 977 if (defs.meshie.val.mesh_id_len > IEEE80211_MAX_SSID_LEN) {
976 lbs_pr_err("inconsistent mesh ID length"); 978 dev_err(dev, "inconsistent mesh ID length\n");
977 defs.meshie.val.mesh_id_len = IEEE80211_MAX_SSID_LEN; 979 defs.meshie.val.mesh_id_len = IEEE80211_MAX_SSID_LEN;
978 } 980 }
979 981
diff --git a/drivers/net/wireless/libertas/rx.c b/drivers/net/wireless/libertas/rx.c
index a3f4b55aa41f..fdb0448301a0 100644
--- a/drivers/net/wireless/libertas/rx.c
+++ b/drivers/net/wireless/libertas/rx.c
@@ -1,6 +1,9 @@
1/* 1/*
2 * This file contains the handling of RX in wlan driver. 2 * This file contains the handling of RX in wlan driver.
3 */ 3 */
4
5#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
6
4#include <linux/etherdevice.h> 7#include <linux/etherdevice.h>
5#include <linux/slab.h> 8#include <linux/slab.h>
6#include <linux/types.h> 9#include <linux/types.h>
@@ -191,7 +194,7 @@ static u8 convert_mv_rate_to_radiotap(u8 rate)
191 case 12: /* 54 Mbps */ 194 case 12: /* 54 Mbps */
192 return 108; 195 return 108;
193 } 196 }
194 lbs_pr_alert("Invalid Marvell WLAN rate %i\n", rate); 197 pr_alert("Invalid Marvell WLAN rate %i\n", rate);
195 return 0; 198 return 0;
196} 199}
197 200
@@ -248,7 +251,7 @@ static int process_rxed_802_11_packet(struct lbs_private *priv,
248 /* add space for the new radio header */ 251 /* add space for the new radio header */
249 if ((skb_headroom(skb) < sizeof(struct rx_radiotap_hdr)) && 252 if ((skb_headroom(skb) < sizeof(struct rx_radiotap_hdr)) &&
250 pskb_expand_head(skb, sizeof(struct rx_radiotap_hdr), 0, GFP_ATOMIC)) { 253 pskb_expand_head(skb, sizeof(struct rx_radiotap_hdr), 0, GFP_ATOMIC)) {
251 lbs_pr_alert("%s: couldn't pskb_expand_head\n", __func__); 254 netdev_alert(dev, "%s: couldn't pskb_expand_head\n", __func__);
252 ret = -ENOMEM; 255 ret = -ENOMEM;
253 kfree_skb(skb); 256 kfree_skb(skb);
254 goto done; 257 goto done;
diff --git a/drivers/net/wireless/mwifiex/11n.c b/drivers/net/wireless/mwifiex/11n.c
index 1d294cfa6c9b..916183d39009 100644
--- a/drivers/net/wireless/mwifiex/11n.c
+++ b/drivers/net/wireless/mwifiex/11n.c
@@ -187,7 +187,7 @@ int mwifiex_ret_11n_addba_req(struct mwifiex_private *priv,
187 */ 187 */
188int mwifiex_ret_11n_cfg(struct host_cmd_ds_command *resp, void *data_buf) 188int mwifiex_ret_11n_cfg(struct host_cmd_ds_command *resp, void *data_buf)
189{ 189{
190 struct mwifiex_ds_11n_tx_cfg *tx_cfg = NULL; 190 struct mwifiex_ds_11n_tx_cfg *tx_cfg;
191 struct host_cmd_ds_11n_cfg *htcfg = &resp->params.htcfg; 191 struct host_cmd_ds_11n_cfg *htcfg = &resp->params.htcfg;
192 192
193 if (data_buf) { 193 if (data_buf) {
@@ -274,7 +274,7 @@ int mwifiex_cmd_amsdu_aggr_ctrl(struct host_cmd_ds_command *cmd,
274int mwifiex_ret_amsdu_aggr_ctrl(struct host_cmd_ds_command *resp, 274int mwifiex_ret_amsdu_aggr_ctrl(struct host_cmd_ds_command *resp,
275 void *data_buf) 275 void *data_buf)
276{ 276{
277 struct mwifiex_ds_11n_amsdu_aggr_ctrl *amsdu_aggr_ctrl = NULL; 277 struct mwifiex_ds_11n_amsdu_aggr_ctrl *amsdu_aggr_ctrl;
278 struct host_cmd_ds_amsdu_aggr_ctrl *amsdu_ctrl = 278 struct host_cmd_ds_amsdu_aggr_ctrl *amsdu_ctrl =
279 &resp->params.amsdu_aggr_ctrl; 279 &resp->params.amsdu_aggr_ctrl;
280 280
@@ -461,8 +461,7 @@ mwifiex_cfg_tx_buf(struct mwifiex_private *priv,
461 struct mwifiex_bssdescriptor *bss_desc) 461 struct mwifiex_bssdescriptor *bss_desc)
462{ 462{
463 u16 max_amsdu = MWIFIEX_TX_DATA_BUF_SIZE_2K; 463 u16 max_amsdu = MWIFIEX_TX_DATA_BUF_SIZE_2K;
464 u16 tx_buf = 0; 464 u16 tx_buf, curr_tx_buf_size = 0;
465 u16 curr_tx_buf_size = 0;
466 465
467 if (bss_desc->bcn_ht_cap) { 466 if (bss_desc->bcn_ht_cap) {
468 if (le16_to_cpu(bss_desc->bcn_ht_cap->cap_info) & 467 if (le16_to_cpu(bss_desc->bcn_ht_cap->cap_info) &
diff --git a/drivers/net/wireless/mwifiex/11n_aggr.c b/drivers/net/wireless/mwifiex/11n_aggr.c
index c9fb0627de43..d3d5e0853c45 100644
--- a/drivers/net/wireless/mwifiex/11n_aggr.c
+++ b/drivers/net/wireless/mwifiex/11n_aggr.c
@@ -60,7 +60,7 @@ mwifiex_11n_form_amsdu_pkt(struct sk_buff *skb_aggr,
60 * later with ethertype 60 * later with ethertype
61 */ 61 */
62 }; 62 };
63 struct tx_packet_hdr *tx_header = NULL; 63 struct tx_packet_hdr *tx_header;
64 64
65 skb_put(skb_aggr, sizeof(*tx_header)); 65 skb_put(skb_aggr, sizeof(*tx_header));
66 66
@@ -136,131 +136,6 @@ mwifiex_11n_form_amsdu_txpd(struct mwifiex_private *priv,
136} 136}
137 137
138/* 138/*
139 * Counts the number of subframes in an aggregate packet.
140 *
141 * This function parses an aggregate packet buffer, looking for
142 * subframes and counting the number of such subframe found. The
143 * function automatically skips the DA/SA fields at the beginning
144 * of each subframe and padding at the end.
145 */
146static int
147mwifiex_11n_get_num_aggr_pkts(u8 *data, int total_pkt_len)
148{
149 int pkt_count = 0, pkt_len, pad;
150
151 while (total_pkt_len > 0) {
152 /* Length will be in network format, change it to host */
153 pkt_len = ntohs((*(__be16 *)(data + 2 * ETH_ALEN)));
154 pad = (((pkt_len + sizeof(struct ethhdr)) & 3)) ?
155 (4 - ((pkt_len + sizeof(struct ethhdr)) & 3)) : 0;
156 data += pkt_len + pad + sizeof(struct ethhdr);
157 total_pkt_len -= pkt_len + pad + sizeof(struct ethhdr);
158 ++pkt_count;
159 }
160
161 return pkt_count;
162}
163
164/*
165 * De-aggregate received packets.
166 *
167 * This function parses the received aggregate buffer, extracts each subframe,
168 * strips off the SNAP header from them and sends the data portion for further
169 * processing.
170 *
171 * Each subframe body is copied onto a separate buffer, which are freed by
172 * upper layer after processing. The function also performs sanity tests on
173 * the received buffer.
174 */
175int mwifiex_11n_deaggregate_pkt(struct mwifiex_private *priv,
176 struct sk_buff *skb)
177{
178 u16 pkt_len;
179 int total_pkt_len;
180 u8 *data;
181 int pad;
182 struct mwifiex_rxinfo *rx_info = MWIFIEX_SKB_RXCB(skb);
183 struct rxpd *local_rx_pd = (struct rxpd *) skb->data;
184 struct sk_buff *skb_daggr;
185 struct mwifiex_rxinfo *rx_info_daggr = NULL;
186 int ret = -1;
187 struct rx_packet_hdr *rx_pkt_hdr;
188 struct mwifiex_adapter *adapter = priv->adapter;
189 u8 rfc1042_eth_hdr[ETH_ALEN] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
190
191 data = (u8 *) (local_rx_pd + local_rx_pd->rx_pkt_offset);
192 total_pkt_len = local_rx_pd->rx_pkt_length;
193
194 /* Sanity test */
195 if (total_pkt_len > MWIFIEX_RX_DATA_BUF_SIZE) {
196 dev_err(adapter->dev, "total pkt len greater than buffer"
197 " size %d\n", total_pkt_len);
198 return -1;
199 }
200
201 rx_info->use_count = mwifiex_11n_get_num_aggr_pkts(data, total_pkt_len);
202
203 while (total_pkt_len > 0) {
204 rx_pkt_hdr = (struct rx_packet_hdr *) data;
205 /* Length will be in network format, change it to host */
206 pkt_len = ntohs((*(__be16 *) (data + 2 * ETH_ALEN)));
207 if (pkt_len > total_pkt_len) {
208 dev_err(adapter->dev, "pkt_len %d > total_pkt_len %d\n",
209 total_pkt_len, pkt_len);
210 break;
211 }
212
213 pad = (((pkt_len + sizeof(struct ethhdr)) & 3)) ?
214 (4 - ((pkt_len + sizeof(struct ethhdr)) & 3)) : 0;
215
216 total_pkt_len -= pkt_len + pad + sizeof(struct ethhdr);
217
218 if (memcmp(&rx_pkt_hdr->rfc1042_hdr,
219 rfc1042_eth_hdr, sizeof(rfc1042_eth_hdr)) == 0) {
220 memmove(data + LLC_SNAP_LEN, data, 2 * ETH_ALEN);
221 data += LLC_SNAP_LEN;
222 pkt_len += sizeof(struct ethhdr) - LLC_SNAP_LEN;
223 } else {
224 *(u16 *) (data + 2 * ETH_ALEN) = (u16) 0;
225 pkt_len += sizeof(struct ethhdr);
226 }
227
228 skb_daggr = dev_alloc_skb(pkt_len);
229 if (!skb_daggr) {
230 dev_err(adapter->dev, "%s: failed to alloc skb_daggr\n",
231 __func__);
232 return -1;
233 }
234 rx_info_daggr = MWIFIEX_SKB_RXCB(skb_daggr);
235
236 rx_info_daggr->bss_index = rx_info->bss_index;
237 skb_daggr->tstamp = skb->tstamp;
238 rx_info_daggr->parent = skb;
239 skb_daggr->priority = skb->priority;
240 skb_put(skb_daggr, pkt_len);
241 memcpy(skb_daggr->data, data, pkt_len);
242
243 ret = mwifiex_recv_packet(adapter, skb_daggr);
244
245 switch (ret) {
246 case -EINPROGRESS:
247 break;
248 case -1:
249 dev_err(adapter->dev, "deaggr: host_to_card failed\n");
250 case 0:
251 mwifiex_recv_packet_complete(adapter, skb_daggr, ret);
252 break;
253 default:
254 break;
255 }
256
257 data += pkt_len + pad;
258 }
259
260 return ret;
261}
262
263/*
264 * Create aggregated packet. 139 * Create aggregated packet.
265 * 140 *
266 * This function creates an aggregated MSDU packet, by combining buffers 141 * This function creates an aggregated MSDU packet, by combining buffers
@@ -285,8 +160,7 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
285 struct mwifiex_adapter *adapter = priv->adapter; 160 struct mwifiex_adapter *adapter = priv->adapter;
286 struct sk_buff *skb_aggr, *skb_src; 161 struct sk_buff *skb_aggr, *skb_src;
287 struct mwifiex_txinfo *tx_info_aggr, *tx_info_src; 162 struct mwifiex_txinfo *tx_info_aggr, *tx_info_src;
288 int pad = 0; 163 int pad = 0, ret;
289 int ret = 0;
290 struct mwifiex_tx_param tx_param; 164 struct mwifiex_tx_param tx_param;
291 struct txpd *ptx_pd = NULL; 165 struct txpd *ptx_pd = NULL;
292 166
@@ -319,7 +193,8 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
319 else 193 else
320 skb_src = NULL; 194 skb_src = NULL;
321 195
322 pra_list->total_pkts_size -= skb_src->len; 196 if (skb_src)
197 pra_list->total_pkts_size -= skb_src->len;
323 198
324 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, 199 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
325 ra_list_flags); 200 ra_list_flags);
@@ -374,7 +249,8 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
374 (adapter->pps_uapsd_mode) && 249 (adapter->pps_uapsd_mode) &&
375 (adapter->tx_lock_flag)) { 250 (adapter->tx_lock_flag)) {
376 priv->adapter->tx_lock_flag = false; 251 priv->adapter->tx_lock_flag = false;
377 ptx_pd->flags = 0; 252 if (ptx_pd)
253 ptx_pd->flags = 0;
378 } 254 }
379 255
380 skb_queue_tail(&pra_list->skb_head, skb_aggr); 256 skb_queue_tail(&pra_list->skb_head, skb_aggr);
diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.c b/drivers/net/wireless/mwifiex/11n_rxreorder.c
index a93c03fdea82..e5dfdc39a921 100644
--- a/drivers/net/wireless/mwifiex/11n_rxreorder.c
+++ b/drivers/net/wireless/mwifiex/11n_rxreorder.c
@@ -39,7 +39,7 @@ mwifiex_11n_dispatch_pkt_until_start_win(struct mwifiex_private *priv,
39 *rx_reor_tbl_ptr, int start_win) 39 *rx_reor_tbl_ptr, int start_win)
40{ 40{
41 int no_pkt_to_send, i; 41 int no_pkt_to_send, i;
42 void *rx_tmp_ptr = NULL; 42 void *rx_tmp_ptr;
43 unsigned long flags; 43 unsigned long flags;
44 44
45 no_pkt_to_send = (start_win > rx_reor_tbl_ptr->start_win) ? 45 no_pkt_to_send = (start_win > rx_reor_tbl_ptr->start_win) ?
@@ -88,7 +88,7 @@ mwifiex_11n_scan_and_dispatch(struct mwifiex_private *priv,
88 struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr) 88 struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr)
89{ 89{
90 int i, j, xchg; 90 int i, j, xchg;
91 void *rx_tmp_ptr = NULL; 91 void *rx_tmp_ptr;
92 unsigned long flags; 92 unsigned long flags;
93 93
94 for (i = 0; i < rx_reor_tbl_ptr->win_size; ++i) { 94 for (i = 0; i < rx_reor_tbl_ptr->win_size; ++i) {
@@ -335,8 +335,8 @@ int mwifiex_cmd_11n_addba_rsp_gen(struct mwifiex_private *priv,
335 &cmd->params.add_ba_rsp; 335 &cmd->params.add_ba_rsp;
336 struct host_cmd_ds_11n_addba_req *cmd_addba_req = 336 struct host_cmd_ds_11n_addba_req *cmd_addba_req =
337 (struct host_cmd_ds_11n_addba_req *) data_buf; 337 (struct host_cmd_ds_11n_addba_req *) data_buf;
338 u8 tid = 0; 338 u8 tid;
339 int win_size = 0; 339 int win_size;
340 uint16_t block_ack_param_set; 340 uint16_t block_ack_param_set;
341 341
342 cmd->command = cpu_to_le16(HostCmd_CMD_11N_ADDBA_RSP); 342 cmd->command = cpu_to_le16(HostCmd_CMD_11N_ADDBA_RSP);
@@ -406,9 +406,8 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv,
406 u8 *ta, u8 pkt_type, void *payload) 406 u8 *ta, u8 pkt_type, void *payload)
407{ 407{
408 struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr; 408 struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr;
409 int start_win, end_win, win_size; 409 int start_win, end_win, win_size, ret;
410 int ret = 0; 410 u16 pkt_index;
411 u16 pkt_index = 0;
412 411
413 rx_reor_tbl_ptr = 412 rx_reor_tbl_ptr =
414 mwifiex_11n_get_rx_reorder_tbl((struct mwifiex_private *) priv, 413 mwifiex_11n_get_rx_reorder_tbl((struct mwifiex_private *) priv,
@@ -540,7 +539,7 @@ int mwifiex_ret_11n_addba_resp(struct mwifiex_private *priv,
540 (struct host_cmd_ds_11n_addba_rsp *) 539 (struct host_cmd_ds_11n_addba_rsp *)
541 &resp->params.add_ba_rsp; 540 &resp->params.add_ba_rsp;
542 int tid, win_size; 541 int tid, win_size;
543 struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr = NULL; 542 struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr;
544 uint16_t block_ack_param_set; 543 uint16_t block_ack_param_set;
545 544
546 block_ack_param_set = le16_to_cpu(add_ba_rsp->block_ack_param_set); 545 block_ack_param_set = le16_to_cpu(add_ba_rsp->block_ack_param_set);
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index 98009e2194c5..660831ce293c 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -77,18 +77,15 @@ mwifiex_channels_to_cfg80211_channel_type(int channel_type)
77static int 77static int
78mwifiex_is_alg_wep(u32 cipher) 78mwifiex_is_alg_wep(u32 cipher)
79{ 79{
80 int alg = 0;
81
82 switch (cipher) { 80 switch (cipher) {
83 case WLAN_CIPHER_SUITE_WEP40: 81 case WLAN_CIPHER_SUITE_WEP40:
84 case WLAN_CIPHER_SUITE_WEP104: 82 case WLAN_CIPHER_SUITE_WEP104:
85 alg = 1; 83 return 1;
86 break;
87 default: 84 default:
88 alg = 0;
89 break; 85 break;
90 } 86 }
91 return alg; 87
88 return 0;
92} 89}
93 90
94/* 91/*
@@ -408,7 +405,7 @@ mwifiex_cfg80211_set_channel(struct wiphy *wiphy, struct net_device *dev,
408static int 405static int
409mwifiex_set_frag(struct mwifiex_private *priv, u32 frag_thr) 406mwifiex_set_frag(struct mwifiex_private *priv, u32 frag_thr)
410{ 407{
411 int ret = 0; 408 int ret;
412 409
413 if (frag_thr < MWIFIEX_FRAG_MIN_VALUE 410 if (frag_thr < MWIFIEX_FRAG_MIN_VALUE
414 || frag_thr > MWIFIEX_FRAG_MAX_VALUE) 411 || frag_thr > MWIFIEX_FRAG_MAX_VALUE)
@@ -449,7 +446,6 @@ static int
449mwifiex_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed) 446mwifiex_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
450{ 447{
451 struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); 448 struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
452
453 int ret = 0; 449 int ret = 0;
454 450
455 if (changed & WIPHY_PARAM_RTS_THRESHOLD) { 451 if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
@@ -473,7 +469,7 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy,
473 enum nl80211_iftype type, u32 *flags, 469 enum nl80211_iftype type, u32 *flags,
474 struct vif_params *params) 470 struct vif_params *params)
475{ 471{
476 int ret = 0; 472 int ret;
477 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); 473 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
478 474
479 if (priv->bss_mode == type) { 475 if (priv->bss_mode == type) {
@@ -717,7 +713,7 @@ static int mwifiex_cfg80211_inform_ibss_bss(struct mwifiex_private *priv)
717{ 713{
718 struct ieee80211_channel *chan; 714 struct ieee80211_channel *chan;
719 struct mwifiex_bss_info bss_info; 715 struct mwifiex_bss_info bss_info;
720 int ie_len = 0; 716 int ie_len;
721 u8 ie_buf[IEEE80211_MAX_SSID_LEN + sizeof(struct ieee_types_header)]; 717 u8 ie_buf[IEEE80211_MAX_SSID_LEN + sizeof(struct ieee_types_header)];
722 718
723 if (mwifiex_get_bss_info(priv, &bss_info)) 719 if (mwifiex_get_bss_info(priv, &bss_info))
@@ -765,7 +761,6 @@ static int mwifiex_cfg80211_inform_ibss_bss(struct mwifiex_private *priv)
765static int mwifiex_inform_bss_from_scan_result(struct mwifiex_private *priv, 761static int mwifiex_inform_bss_from_scan_result(struct mwifiex_private *priv,
766 struct mwifiex_802_11_ssid *ssid) 762 struct mwifiex_802_11_ssid *ssid)
767{ 763{
768 struct mwifiex_scan_resp scan_resp;
769 struct mwifiex_bssdescriptor *scan_table; 764 struct mwifiex_bssdescriptor *scan_table;
770 int i, j; 765 int i, j;
771 struct ieee80211_channel *chan; 766 struct ieee80211_channel *chan;
@@ -775,10 +770,6 @@ static int mwifiex_inform_bss_from_scan_result(struct mwifiex_private *priv,
775 int beacon_size; 770 int beacon_size;
776 u8 element_id, element_len; 771 u8 element_id, element_len;
777 772
778 memset(&scan_resp, 0, sizeof(scan_resp));
779 scan_resp.scan_table = (u8 *) priv->adapter->scan_table;
780 scan_resp.num_in_scan_table = priv->adapter->num_in_scan_table;
781
782#define MAX_IE_BUF 2048 773#define MAX_IE_BUF 2048
783 ie_buf = kzalloc(MAX_IE_BUF, GFP_KERNEL); 774 ie_buf = kzalloc(MAX_IE_BUF, GFP_KERNEL);
784 if (!ie_buf) { 775 if (!ie_buf) {
@@ -787,8 +778,8 @@ static int mwifiex_inform_bss_from_scan_result(struct mwifiex_private *priv,
787 return -ENOMEM; 778 return -ENOMEM;
788 } 779 }
789 780
790 scan_table = (struct mwifiex_bssdescriptor *) scan_resp.scan_table; 781 scan_table = priv->adapter->scan_table;
791 for (i = 0; i < scan_resp.num_in_scan_table; i++) { 782 for (i = 0; i < priv->adapter->num_in_scan_table; i++) {
792 if (ssid) { 783 if (ssid) {
793 /* Inform specific BSS only */ 784 /* Inform specific BSS only */
794 if (memcmp(ssid->ssid, scan_table[i].ssid.ssid, 785 if (memcmp(ssid->ssid, scan_table[i].ssid.ssid,
@@ -903,8 +894,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid,
903{ 894{
904 struct mwifiex_802_11_ssid req_ssid; 895 struct mwifiex_802_11_ssid req_ssid;
905 struct mwifiex_ssid_bssid ssid_bssid; 896 struct mwifiex_ssid_bssid ssid_bssid;
906 int ret = 0; 897 int ret, auth_type = 0;
907 int auth_type = 0;
908 898
909 memset(&req_ssid, 0, sizeof(struct mwifiex_802_11_ssid)); 899 memset(&req_ssid, 0, sizeof(struct mwifiex_802_11_ssid));
910 memset(&ssid_bssid, 0, sizeof(struct mwifiex_ssid_bssid)); 900 memset(&ssid_bssid, 0, sizeof(struct mwifiex_ssid_bssid));
@@ -1044,7 +1034,7 @@ mwifiex_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
1044 goto done; 1034 goto done;
1045 } 1035 }
1046 1036
1047 priv->assoc_request = 1; 1037 priv->assoc_request = -EINPROGRESS;
1048 1038
1049 wiphy_dbg(wiphy, "info: Trying to associate to %s and bssid %pM\n", 1039 wiphy_dbg(wiphy, "info: Trying to associate to %s and bssid %pM\n",
1050 (char *) sme->ssid, sme->bssid); 1040 (char *) sme->ssid, sme->bssid);
@@ -1052,6 +1042,7 @@ mwifiex_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
1052 ret = mwifiex_cfg80211_assoc(priv, sme->ssid_len, sme->ssid, sme->bssid, 1042 ret = mwifiex_cfg80211_assoc(priv, sme->ssid_len, sme->ssid, sme->bssid,
1053 priv->bss_mode, sme->channel, sme, 0); 1043 priv->bss_mode, sme->channel, sme, 0);
1054 1044
1045 priv->assoc_request = 1;
1055done: 1046done:
1056 priv->assoc_result = ret; 1047 priv->assoc_result = ret;
1057 queue_work(priv->workqueue, &priv->cfg_workqueue); 1048 queue_work(priv->workqueue, &priv->cfg_workqueue);
@@ -1080,7 +1071,7 @@ mwifiex_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
1080 goto done; 1071 goto done;
1081 } 1072 }
1082 1073
1083 priv->ibss_join_request = 1; 1074 priv->ibss_join_request = -EINPROGRESS;
1084 1075
1085 wiphy_dbg(wiphy, "info: trying to join to %s and bssid %pM\n", 1076 wiphy_dbg(wiphy, "info: trying to join to %s and bssid %pM\n",
1086 (char *) params->ssid, params->bssid); 1077 (char *) params->ssid, params->bssid);
@@ -1088,6 +1079,8 @@ mwifiex_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
1088 ret = mwifiex_cfg80211_assoc(priv, params->ssid_len, params->ssid, 1079 ret = mwifiex_cfg80211_assoc(priv, params->ssid_len, params->ssid,
1089 params->bssid, priv->bss_mode, 1080 params->bssid, priv->bss_mode,
1090 params->channel, NULL, params->privacy); 1081 params->channel, NULL, params->privacy);
1082
1083 priv->ibss_join_request = 1;
1091done: 1084done:
1092 priv->ibss_join_result = ret; 1085 priv->ibss_join_result = ret;
1093 queue_work(priv->workqueue, &priv->cfg_workqueue); 1086 queue_work(priv->workqueue, &priv->cfg_workqueue);
@@ -1244,8 +1237,8 @@ static struct cfg80211_ops mwifiex_cfg80211_ops = {
1244int mwifiex_register_cfg80211(struct net_device *dev, u8 *mac, 1237int mwifiex_register_cfg80211(struct net_device *dev, u8 *mac,
1245 struct mwifiex_private *priv) 1238 struct mwifiex_private *priv)
1246{ 1239{
1247 int ret = 0; 1240 int ret;
1248 void *wdev_priv = NULL; 1241 void *wdev_priv;
1249 struct wireless_dev *wdev; 1242 struct wireless_dev *wdev;
1250 1243
1251 wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL); 1244 wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
@@ -1257,8 +1250,10 @@ int mwifiex_register_cfg80211(struct net_device *dev, u8 *mac,
1257 wdev->wiphy = 1250 wdev->wiphy =
1258 wiphy_new(&mwifiex_cfg80211_ops, 1251 wiphy_new(&mwifiex_cfg80211_ops,
1259 sizeof(struct mwifiex_private *)); 1252 sizeof(struct mwifiex_private *));
1260 if (!wdev->wiphy) 1253 if (!wdev->wiphy) {
1254 kfree(wdev);
1261 return -ENOMEM; 1255 return -ENOMEM;
1256 }
1262 wdev->iftype = NL80211_IFTYPE_STATION; 1257 wdev->iftype = NL80211_IFTYPE_STATION;
1263 wdev->wiphy->max_scan_ssids = 10; 1258 wdev->wiphy->max_scan_ssids = 10;
1264 wdev->wiphy->interface_modes = 1259 wdev->wiphy->interface_modes =
@@ -1298,6 +1293,7 @@ int mwifiex_register_cfg80211(struct net_device *dev, u8 *mac,
1298 dev_err(priv->adapter->dev, "%s: registering cfg80211 device\n", 1293 dev_err(priv->adapter->dev, "%s: registering cfg80211 device\n",
1299 __func__); 1294 __func__);
1300 wiphy_free(wdev->wiphy); 1295 wiphy_free(wdev->wiphy);
1296 kfree(wdev);
1301 return ret; 1297 return ret;
1302 } else { 1298 } else {
1303 dev_dbg(priv->adapter->dev, 1299 dev_dbg(priv->adapter->dev,
@@ -1380,7 +1376,7 @@ done:
1380 kfree(scan_req); 1376 kfree(scan_req);
1381 } 1377 }
1382 1378
1383 if (priv->assoc_request) { 1379 if (priv->assoc_request == 1) {
1384 if (!priv->assoc_result) { 1380 if (!priv->assoc_result) {
1385 cfg80211_connect_result(priv->netdev, priv->cfg_bssid, 1381 cfg80211_connect_result(priv->netdev, priv->cfg_bssid,
1386 NULL, 0, NULL, 0, 1382 NULL, 0, NULL, 0,
@@ -1399,7 +1395,7 @@ done:
1399 priv->assoc_result = 0; 1395 priv->assoc_result = 0;
1400 } 1396 }
1401 1397
1402 if (priv->ibss_join_request) { 1398 if (priv->ibss_join_request == 1) {
1403 if (!priv->ibss_join_result) { 1399 if (!priv->ibss_join_result) {
1404 cfg80211_ibss_joined(priv->netdev, priv->cfg_bssid, 1400 cfg80211_ibss_joined(priv->netdev, priv->cfg_bssid,
1405 GFP_KERNEL); 1401 GFP_KERNEL);
diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c
index 776146a104ec..cd89fed206ae 100644
--- a/drivers/net/wireless/mwifiex/cmdevt.c
+++ b/drivers/net/wireless/mwifiex/cmdevt.c
@@ -91,7 +91,7 @@ mwifiex_clean_cmd_node(struct mwifiex_adapter *adapter,
91 cmd_node->wait_q_enabled = false; 91 cmd_node->wait_q_enabled = false;
92 92
93 if (cmd_node->resp_skb) { 93 if (cmd_node->resp_skb) {
94 mwifiex_recv_complete(adapter, cmd_node->resp_skb, 0); 94 dev_kfree_skb_any(cmd_node->resp_skb);
95 cmd_node->resp_skb = NULL; 95 cmd_node->resp_skb = NULL;
96 } 96 }
97} 97}
@@ -128,7 +128,7 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv,
128{ 128{
129 129
130 struct mwifiex_adapter *adapter = priv->adapter; 130 struct mwifiex_adapter *adapter = priv->adapter;
131 int ret = 0; 131 int ret;
132 struct host_cmd_ds_command *host_cmd; 132 struct host_cmd_ds_command *host_cmd;
133 uint16_t cmd_code; 133 uint16_t cmd_code;
134 uint16_t cmd_size; 134 uint16_t cmd_size;
@@ -222,25 +222,24 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv,
222 */ 222 */
223static int mwifiex_dnld_sleep_confirm_cmd(struct mwifiex_adapter *adapter) 223static int mwifiex_dnld_sleep_confirm_cmd(struct mwifiex_adapter *adapter)
224{ 224{
225 int ret = 0; 225 int ret;
226 u16 cmd_len = 0;
227 struct mwifiex_private *priv; 226 struct mwifiex_private *priv;
228 struct mwifiex_opt_sleep_confirm_buffer *sleep_cfm_buf = 227 struct mwifiex_opt_sleep_confirm *sleep_cfm_buf =
229 (struct mwifiex_opt_sleep_confirm_buffer *) 228 (struct mwifiex_opt_sleep_confirm *)
230 adapter->sleep_cfm->data; 229 adapter->sleep_cfm->data;
231 cmd_len = sizeof(struct mwifiex_opt_sleep_confirm);
232 priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); 230 priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
233 231
234 sleep_cfm_buf->ps_cfm_sleep.seq_num = 232 sleep_cfm_buf->seq_num =
235 cpu_to_le16((HostCmd_SET_SEQ_NO_BSS_INFO 233 cpu_to_le16((HostCmd_SET_SEQ_NO_BSS_INFO
236 (adapter->seq_num, priv->bss_num, 234 (adapter->seq_num, priv->bss_num,
237 priv->bss_type))); 235 priv->bss_type)));
238 adapter->seq_num++; 236 adapter->seq_num++;
239 237
238 skb_push(adapter->sleep_cfm, INTF_HEADER_LEN);
240 ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_TYPE_CMD, 239 ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_TYPE_CMD,
241 adapter->sleep_cfm->data, 240 adapter->sleep_cfm->data,
242 adapter->sleep_cfm->len + 241 adapter->sleep_cfm->len, NULL);
243 INTF_HEADER_LEN, NULL); 242 skb_pull(adapter->sleep_cfm, INTF_HEADER_LEN);
244 243
245 if (ret == -1) { 244 if (ret == -1) {
246 dev_err(adapter->dev, "SLEEP_CFM: failed\n"); 245 dev_err(adapter->dev, "SLEEP_CFM: failed\n");
@@ -249,14 +248,14 @@ static int mwifiex_dnld_sleep_confirm_cmd(struct mwifiex_adapter *adapter)
249 } 248 }
250 if (GET_BSS_ROLE(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY)) 249 if (GET_BSS_ROLE(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY))
251 == MWIFIEX_BSS_ROLE_STA) { 250 == MWIFIEX_BSS_ROLE_STA) {
252 if (!sleep_cfm_buf->ps_cfm_sleep.resp_ctrl) 251 if (!sleep_cfm_buf->resp_ctrl)
253 /* Response is not needed for sleep 252 /* Response is not needed for sleep
254 confirm command */ 253 confirm command */
255 adapter->ps_state = PS_STATE_SLEEP; 254 adapter->ps_state = PS_STATE_SLEEP;
256 else 255 else
257 adapter->ps_state = PS_STATE_SLEEP_CFM; 256 adapter->ps_state = PS_STATE_SLEEP_CFM;
258 257
259 if (!sleep_cfm_buf->ps_cfm_sleep.resp_ctrl 258 if (!sleep_cfm_buf->resp_ctrl
260 && (adapter->is_hs_configured 259 && (adapter->is_hs_configured
261 && !adapter->sleep_period.period)) { 260 && !adapter->sleep_period.period)) {
262 adapter->pm_wakeup_card_req = true; 261 adapter->pm_wakeup_card_req = true;
@@ -292,7 +291,7 @@ int mwifiex_alloc_cmd_buffer(struct mwifiex_adapter *adapter)
292 if (!cmd_array) { 291 if (!cmd_array) {
293 dev_err(adapter->dev, "%s: failed to alloc cmd_array\n", 292 dev_err(adapter->dev, "%s: failed to alloc cmd_array\n",
294 __func__); 293 __func__);
295 return -1; 294 return -ENOMEM;
296 } 295 }
297 296
298 adapter->cmd_pool = cmd_array; 297 adapter->cmd_pool = cmd_array;
@@ -340,7 +339,7 @@ int mwifiex_free_cmd_buffer(struct mwifiex_adapter *adapter)
340 } 339 }
341 if (!cmd_array[i].resp_skb) 340 if (!cmd_array[i].resp_skb)
342 continue; 341 continue;
343 mwifiex_recv_complete(adapter, cmd_array[i].resp_skb, 0); 342 dev_kfree_skb_any(cmd_array[i].resp_skb);
344 } 343 }
345 /* Release struct cmd_ctrl_node */ 344 /* Release struct cmd_ctrl_node */
346 if (adapter->cmd_pool) { 345 if (adapter->cmd_pool) {
@@ -364,13 +363,13 @@ int mwifiex_free_cmd_buffer(struct mwifiex_adapter *adapter)
364 */ 363 */
365int mwifiex_process_event(struct mwifiex_adapter *adapter) 364int mwifiex_process_event(struct mwifiex_adapter *adapter)
366{ 365{
367 int ret = 0; 366 int ret;
368 struct mwifiex_private *priv = 367 struct mwifiex_private *priv =
369 mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); 368 mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
370 struct sk_buff *skb = adapter->event_skb; 369 struct sk_buff *skb = adapter->event_skb;
371 u32 eventcause = adapter->event_cause; 370 u32 eventcause = adapter->event_cause;
372 struct timeval tstamp; 371 struct timeval tstamp;
373 struct mwifiex_rxinfo *rx_info = NULL; 372 struct mwifiex_rxinfo *rx_info;
374 373
375 /* Save the last event to debug log */ 374 /* Save the last event to debug log */
376 adapter->dbg.last_event_index = 375 adapter->dbg.last_event_index =
@@ -403,7 +402,7 @@ int mwifiex_process_event(struct mwifiex_adapter *adapter)
403 adapter->event_cause = 0; 402 adapter->event_cause = 0;
404 adapter->event_skb = NULL; 403 adapter->event_skb = NULL;
405 404
406 mwifiex_recv_complete(adapter, skb, 0); 405 dev_kfree_skb_any(skb);
407 406
408 return ret; 407 return ret;
409} 408}
@@ -446,10 +445,10 @@ int mwifiex_send_cmd_sync(struct mwifiex_private *priv, uint16_t cmd_no,
446int mwifiex_send_cmd_async(struct mwifiex_private *priv, uint16_t cmd_no, 445int mwifiex_send_cmd_async(struct mwifiex_private *priv, uint16_t cmd_no,
447 u16 cmd_action, u32 cmd_oid, void *data_buf) 446 u16 cmd_action, u32 cmd_oid, void *data_buf)
448{ 447{
449 int ret = 0; 448 int ret;
450 struct mwifiex_adapter *adapter = priv->adapter; 449 struct mwifiex_adapter *adapter = priv->adapter;
451 struct cmd_ctrl_node *cmd_node = NULL; 450 struct cmd_ctrl_node *cmd_node;
452 struct host_cmd_ds_command *cmd_ptr = NULL; 451 struct host_cmd_ds_command *cmd_ptr;
453 452
454 if (!adapter) { 453 if (!adapter) {
455 pr_err("PREP_CMD: adapter is NULL\n"); 454 pr_err("PREP_CMD: adapter is NULL\n");
@@ -605,8 +604,8 @@ mwifiex_insert_cmd_to_pending_q(struct mwifiex_adapter *adapter,
605 */ 604 */
606int mwifiex_exec_next_cmd(struct mwifiex_adapter *adapter) 605int mwifiex_exec_next_cmd(struct mwifiex_adapter *adapter)
607{ 606{
608 struct mwifiex_private *priv = NULL; 607 struct mwifiex_private *priv;
609 struct cmd_ctrl_node *cmd_node = NULL; 608 struct cmd_ctrl_node *cmd_node;
610 int ret = 0; 609 int ret = 0;
611 struct host_cmd_ds_command *host_cmd; 610 struct host_cmd_ds_command *host_cmd;
612 unsigned long cmd_flags; 611 unsigned long cmd_flags;
@@ -673,7 +672,7 @@ int mwifiex_exec_next_cmd(struct mwifiex_adapter *adapter)
673 */ 672 */
674int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter) 673int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter)
675{ 674{
676 struct host_cmd_ds_command *resp = NULL; 675 struct host_cmd_ds_command *resp;
677 struct mwifiex_private *priv = 676 struct mwifiex_private *priv =
678 mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); 677 mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
679 int ret = 0; 678 int ret = 0;
@@ -805,7 +804,7 @@ mwifiex_cmd_timeout_func(unsigned long function_context)
805{ 804{
806 struct mwifiex_adapter *adapter = 805 struct mwifiex_adapter *adapter =
807 (struct mwifiex_adapter *) function_context; 806 (struct mwifiex_adapter *) function_context;
808 struct cmd_ctrl_node *cmd_node = NULL; 807 struct cmd_ctrl_node *cmd_node;
809 struct timeval tstamp; 808 struct timeval tstamp;
810 809
811 adapter->num_cmd_timeout++; 810 adapter->num_cmd_timeout++;
@@ -877,7 +876,7 @@ mwifiex_cmd_timeout_func(unsigned long function_context)
877void 876void
878mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter) 877mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter)
879{ 878{
880 struct cmd_ctrl_node *cmd_node = NULL, *tmp_node = NULL; 879 struct cmd_ctrl_node *cmd_node = NULL, *tmp_node;
881 unsigned long flags; 880 unsigned long flags;
882 881
883 /* Cancel current cmd */ 882 /* Cancel current cmd */
@@ -1160,7 +1159,7 @@ int mwifiex_cmd_enh_power_mode(struct mwifiex_private *priv,
1160{ 1159{
1161 struct host_cmd_ds_802_11_ps_mode_enh *psmode_enh = 1160 struct host_cmd_ds_802_11_ps_mode_enh *psmode_enh =
1162 &cmd->params.psmode_enh; 1161 &cmd->params.psmode_enh;
1163 u8 *tlv = NULL; 1162 u8 *tlv;
1164 u16 cmd_size = 0; 1163 u16 cmd_size = 0;
1165 1164
1166 cmd->command = cpu_to_le16(HostCmd_CMD_802_11_PS_MODE_ENH); 1165 cmd->command = cpu_to_le16(HostCmd_CMD_802_11_PS_MODE_ENH);
diff --git a/drivers/net/wireless/mwifiex/debugfs.c b/drivers/net/wireless/mwifiex/debugfs.c
index 7ddcb062f103..46d65e02c7ba 100644
--- a/drivers/net/wireless/mwifiex/debugfs.c
+++ b/drivers/net/wireless/mwifiex/debugfs.c
@@ -193,7 +193,7 @@ mwifiex_info_read(struct file *file, char __user *ubuf,
193 unsigned long page = get_zeroed_page(GFP_KERNEL); 193 unsigned long page = get_zeroed_page(GFP_KERNEL);
194 char *p = (char *) page, fmt[64]; 194 char *p = (char *) page, fmt[64];
195 struct mwifiex_bss_info info; 195 struct mwifiex_bss_info info;
196 ssize_t ret = 0; 196 ssize_t ret;
197 int i = 0; 197 int i = 0;
198 198
199 if (!p) 199 if (!p)
@@ -288,7 +288,7 @@ mwifiex_getlog_read(struct file *file, char __user *ubuf,
288 (struct mwifiex_private *) file->private_data; 288 (struct mwifiex_private *) file->private_data;
289 unsigned long page = get_zeroed_page(GFP_KERNEL); 289 unsigned long page = get_zeroed_page(GFP_KERNEL);
290 char *p = (char *) page; 290 char *p = (char *) page;
291 ssize_t ret = 0; 291 ssize_t ret;
292 struct mwifiex_ds_get_stats stats; 292 struct mwifiex_ds_get_stats stats;
293 293
294 if (!p) 294 if (!p)
@@ -400,7 +400,7 @@ mwifiex_debug_read(struct file *file, char __user *ubuf,
400 struct mwifiex_debug_data *d = &items[0]; 400 struct mwifiex_debug_data *d = &items[0];
401 unsigned long page = get_zeroed_page(GFP_KERNEL); 401 unsigned long page = get_zeroed_page(GFP_KERNEL);
402 char *p = (char *) page; 402 char *p = (char *) page;
403 ssize_t ret = 0; 403 ssize_t ret;
404 size_t size, addr; 404 size_t size, addr;
405 long val; 405 long val;
406 int i, j; 406 int i, j;
@@ -507,7 +507,7 @@ mwifiex_regrdwr_write(struct file *file,
507 unsigned long addr = get_zeroed_page(GFP_KERNEL); 507 unsigned long addr = get_zeroed_page(GFP_KERNEL);
508 char *buf = (char *) addr; 508 char *buf = (char *) addr;
509 size_t buf_size = min(count, (size_t) (PAGE_SIZE - 1)); 509 size_t buf_size = min(count, (size_t) (PAGE_SIZE - 1));
510 int ret = 0; 510 int ret;
511 u32 reg_type = 0, reg_offset = 0, reg_value = UINT_MAX; 511 u32 reg_type = 0, reg_offset = 0, reg_value = UINT_MAX;
512 512
513 if (!buf) 513 if (!buf)
@@ -650,7 +650,7 @@ mwifiex_rdeeprom_read(struct file *file, char __user *ubuf,
650 (struct mwifiex_private *) file->private_data; 650 (struct mwifiex_private *) file->private_data;
651 unsigned long addr = get_zeroed_page(GFP_KERNEL); 651 unsigned long addr = get_zeroed_page(GFP_KERNEL);
652 char *buf = (char *) addr; 652 char *buf = (char *) addr;
653 int pos = 0, ret = 0, i = 0; 653 int pos = 0, ret = 0, i;
654 u8 value[MAX_EEPROM_DATA]; 654 u8 value[MAX_EEPROM_DATA];
655 655
656 if (!buf) 656 if (!buf)
diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h
index 6d1c4545eda6..afdd145dff0b 100644
--- a/drivers/net/wireless/mwifiex/fw.h
+++ b/drivers/net/wireless/mwifiex/fw.h
@@ -816,14 +816,7 @@ struct host_cmd_ds_txpwr_cfg {
816 816
817struct mwifiex_scan_cmd_config { 817struct mwifiex_scan_cmd_config {
818 /* 818 /*
819 * BSS Type to be sent in the firmware command 819 * BSS mode to be sent in the firmware command
820 *
821 * Field can be used to restrict the types of networks returned in the
822 * scan. Valid settings are:
823 *
824 * - MWIFIEX_SCAN_MODE_BSS (infrastructure)
825 * - MWIFIEX_SCAN_MODE_IBSS (adhoc)
826 * - MWIFIEX_SCAN_MODE_ANY (unrestricted, adhoc and infrastructure)
827 */ 820 */
828 u8 bss_mode; 821 u8 bss_mode;
829 822
@@ -866,13 +859,6 @@ struct mwifiex_user_scan_cfg {
866 u8 keep_previous_scan; 859 u8 keep_previous_scan;
867 /* 860 /*
868 * BSS mode to be sent in the firmware command 861 * BSS mode to be sent in the firmware command
869 *
870 * Field can be used to restrict the types of networks returned in the
871 * scan. Valid settings are:
872 *
873 * - MWIFIEX_SCAN_MODE_BSS (infrastructure)
874 * - MWIFIEX_SCAN_MODE_IBSS (adhoc)
875 * - MWIFIEX_SCAN_MODE_ANY (unrestricted, adhoc and infrastructure)
876 */ 862 */
877 u8 bss_mode; 863 u8 bss_mode;
878 /* Configure the number of probe requests for active chan scans */ 864 /* Configure the number of probe requests for active chan scans */
@@ -1198,9 +1184,4 @@ struct mwifiex_opt_sleep_confirm {
1198 __le16 action; 1184 __le16 action;
1199 __le16 resp_ctrl; 1185 __le16 resp_ctrl;
1200} __packed; 1186} __packed;
1201
1202struct mwifiex_opt_sleep_confirm_buffer {
1203 u8 hdr[4];
1204 struct mwifiex_opt_sleep_confirm ps_cfm_sleep;
1205} __packed;
1206#endif /* !_MWIFIEX_FW_H_ */ 1187#endif /* !_MWIFIEX_FW_H_ */
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c
index fc2c0c5728d9..3f1559e61320 100644
--- a/drivers/net/wireless/mwifiex/init.c
+++ b/drivers/net/wireless/mwifiex/init.c
@@ -41,7 +41,7 @@ static int mwifiex_add_bss_prio_tbl(struct mwifiex_private *priv)
41 if (!bss_prio) { 41 if (!bss_prio) {
42 dev_err(adapter->dev, "%s: failed to alloc bss_prio\n", 42 dev_err(adapter->dev, "%s: failed to alloc bss_prio\n",
43 __func__); 43 __func__);
44 return -1; 44 return -ENOMEM;
45 } 45 }
46 46
47 bss_prio->priv = priv; 47 bss_prio->priv = priv;
@@ -151,7 +151,7 @@ static int mwifiex_init_priv(struct mwifiex_private *priv)
151 */ 151 */
152static int mwifiex_allocate_adapter(struct mwifiex_adapter *adapter) 152static int mwifiex_allocate_adapter(struct mwifiex_adapter *adapter)
153{ 153{
154 int ret = 0; 154 int ret;
155 u32 buf_size; 155 u32 buf_size;
156 struct mwifiex_bssdescriptor *temp_scan_table; 156 struct mwifiex_bssdescriptor *temp_scan_table;
157 157
@@ -161,7 +161,7 @@ static int mwifiex_allocate_adapter(struct mwifiex_adapter *adapter)
161 if (!temp_scan_table) { 161 if (!temp_scan_table) {
162 dev_err(adapter->dev, "%s: failed to alloc temp_scan_table\n", 162 dev_err(adapter->dev, "%s: failed to alloc temp_scan_table\n",
163 __func__); 163 __func__);
164 return -1; 164 return -ENOMEM;
165 } 165 }
166 166
167 adapter->scan_table = temp_scan_table; 167 adapter->scan_table = temp_scan_table;
@@ -175,7 +175,7 @@ static int mwifiex_allocate_adapter(struct mwifiex_adapter *adapter)
175 } 175 }
176 176
177 adapter->sleep_cfm = 177 adapter->sleep_cfm =
178 dev_alloc_skb(sizeof(struct mwifiex_opt_sleep_confirm_buffer) 178 dev_alloc_skb(sizeof(struct mwifiex_opt_sleep_confirm)
179 + INTF_HEADER_LEN); 179 + INTF_HEADER_LEN);
180 180
181 if (!adapter->sleep_cfm) { 181 if (!adapter->sleep_cfm) {
@@ -197,10 +197,10 @@ static int mwifiex_allocate_adapter(struct mwifiex_adapter *adapter)
197 */ 197 */
198static void mwifiex_init_adapter(struct mwifiex_adapter *adapter) 198static void mwifiex_init_adapter(struct mwifiex_adapter *adapter)
199{ 199{
200 struct mwifiex_opt_sleep_confirm_buffer *sleep_cfm_buf = NULL; 200 struct mwifiex_opt_sleep_confirm *sleep_cfm_buf = NULL;
201 201
202 skb_put(adapter->sleep_cfm, sizeof(sleep_cfm_buf->ps_cfm_sleep)); 202 skb_put(adapter->sleep_cfm, sizeof(struct mwifiex_opt_sleep_confirm));
203 sleep_cfm_buf = (struct mwifiex_opt_sleep_confirm_buffer *) 203 sleep_cfm_buf = (struct mwifiex_opt_sleep_confirm *)
204 (adapter->sleep_cfm->data); 204 (adapter->sleep_cfm->data);
205 205
206 adapter->cmd_sent = false; 206 adapter->cmd_sent = false;
@@ -268,16 +268,14 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter)
268 mwifiex_wmm_init(adapter); 268 mwifiex_wmm_init(adapter);
269 269
270 if (adapter->sleep_cfm) { 270 if (adapter->sleep_cfm) {
271 memset(&sleep_cfm_buf->ps_cfm_sleep, 0, 271 memset(sleep_cfm_buf, 0, adapter->sleep_cfm->len);
272 adapter->sleep_cfm->len); 272 sleep_cfm_buf->command =
273 sleep_cfm_buf->ps_cfm_sleep.command = 273 cpu_to_le16(HostCmd_CMD_802_11_PS_MODE_ENH);
274 cpu_to_le16(HostCmd_CMD_802_11_PS_MODE_ENH); 274 sleep_cfm_buf->size =
275 sleep_cfm_buf->ps_cfm_sleep.size = 275 cpu_to_le16(adapter->sleep_cfm->len);
276 cpu_to_le16(adapter->sleep_cfm->len); 276 sleep_cfm_buf->result = 0;
277 sleep_cfm_buf->ps_cfm_sleep.result = 0; 277 sleep_cfm_buf->action = cpu_to_le16(SLEEP_CONFIRM);
278 sleep_cfm_buf->ps_cfm_sleep.action = cpu_to_le16(SLEEP_CONFIRM); 278 sleep_cfm_buf->resp_ctrl = cpu_to_le16(RESP_NEEDED);
279 sleep_cfm_buf->ps_cfm_sleep.resp_ctrl =
280 cpu_to_le16(RESP_NEEDED);
281 } 279 }
282 memset(&adapter->sleep_params, 0, sizeof(adapter->sleep_params)); 280 memset(&adapter->sleep_params, 0, sizeof(adapter->sleep_params));
283 memset(&adapter->sleep_period, 0, sizeof(adapter->sleep_period)); 281 memset(&adapter->sleep_period, 0, sizeof(adapter->sleep_period));
@@ -342,9 +340,8 @@ mwifiex_free_adapter(struct mwifiex_adapter *adapter)
342 */ 340 */
343int mwifiex_init_lock_list(struct mwifiex_adapter *adapter) 341int mwifiex_init_lock_list(struct mwifiex_adapter *adapter)
344{ 342{
345 struct mwifiex_private *priv = NULL; 343 struct mwifiex_private *priv;
346 s32 i = 0; 344 s32 i, j;
347 u32 j = 0;
348 345
349 spin_lock_init(&adapter->mwifiex_lock); 346 spin_lock_init(&adapter->mwifiex_lock);
350 spin_lock_init(&adapter->int_lock); 347 spin_lock_init(&adapter->int_lock);
@@ -400,9 +397,8 @@ int mwifiex_init_lock_list(struct mwifiex_adapter *adapter)
400 */ 397 */
401void mwifiex_free_lock_list(struct mwifiex_adapter *adapter) 398void mwifiex_free_lock_list(struct mwifiex_adapter *adapter)
402{ 399{
403 struct mwifiex_private *priv = NULL; 400 struct mwifiex_private *priv;
404 s32 i = 0; 401 s32 i, j;
405 s32 j = 0;
406 402
407 /* Free lists */ 403 /* Free lists */
408 list_del(&adapter->cmd_free_q); 404 list_del(&adapter->cmd_free_q);
@@ -436,10 +432,9 @@ void mwifiex_free_lock_list(struct mwifiex_adapter *adapter)
436 */ 432 */
437int mwifiex_init_fw(struct mwifiex_adapter *adapter) 433int mwifiex_init_fw(struct mwifiex_adapter *adapter)
438{ 434{
439 int ret = 0; 435 int ret;
440 struct mwifiex_private *priv = NULL; 436 struct mwifiex_private *priv;
441 u8 i = 0; 437 u8 i, first_sta = true;
442 u8 first_sta = true;
443 int is_cmd_pend_q_empty; 438 int is_cmd_pend_q_empty;
444 unsigned long flags; 439 unsigned long flags;
445 440
@@ -497,8 +492,7 @@ static void mwifiex_delete_bss_prio_tbl(struct mwifiex_private *priv)
497{ 492{
498 int i; 493 int i;
499 struct mwifiex_adapter *adapter = priv->adapter; 494 struct mwifiex_adapter *adapter = priv->adapter;
500 struct mwifiex_bss_prio_node *bssprio_node = NULL, *tmp_node = NULL, 495 struct mwifiex_bss_prio_node *bssprio_node, *tmp_node, **cur;
501 **cur = NULL;
502 struct list_head *head; 496 struct list_head *head;
503 spinlock_t *lock; 497 spinlock_t *lock;
504 unsigned long flags; 498 unsigned long flags;
@@ -552,8 +546,8 @@ int
552mwifiex_shutdown_drv(struct mwifiex_adapter *adapter) 546mwifiex_shutdown_drv(struct mwifiex_adapter *adapter)
553{ 547{
554 int ret = -EINPROGRESS; 548 int ret = -EINPROGRESS;
555 struct mwifiex_private *priv = NULL; 549 struct mwifiex_private *priv;
556 s32 i = 0; 550 s32 i;
557 unsigned long flags; 551 unsigned long flags;
558 552
559 /* mwifiex already shutdown */ 553 /* mwifiex already shutdown */
@@ -608,9 +602,8 @@ mwifiex_shutdown_drv(struct mwifiex_adapter *adapter)
608int mwifiex_dnld_fw(struct mwifiex_adapter *adapter, 602int mwifiex_dnld_fw(struct mwifiex_adapter *adapter,
609 struct mwifiex_fw_image *pmfw) 603 struct mwifiex_fw_image *pmfw)
610{ 604{
611 int ret = 0; 605 int ret, winner;
612 u32 poll_num = 1; 606 u32 poll_num = 1;
613 int winner;
614 607
615 /* Check if firmware is already running */ 608 /* Check if firmware is already running */
616 ret = adapter->if_ops.check_fw_status(adapter, poll_num, &winner); 609 ret = adapter->if_ops.check_fw_status(adapter, poll_num, &winner);
diff --git a/drivers/net/wireless/mwifiex/ioctl.h b/drivers/net/wireless/mwifiex/ioctl.h
index 5488e111fd2c..7c1c5ee40eb9 100644
--- a/drivers/net/wireless/mwifiex/ioctl.h
+++ b/drivers/net/wireless/mwifiex/ioctl.h
@@ -23,49 +23,16 @@
23#include <net/mac80211.h> 23#include <net/mac80211.h>
24 24
25enum { 25enum {
26 MWIFIEX_SCAN_MODE_UNCHANGED = 0,
27 MWIFIEX_SCAN_MODE_BSS,
28 MWIFIEX_SCAN_MODE_IBSS,
29 MWIFIEX_SCAN_MODE_ANY
30};
31
32enum {
33 MWIFIEX_SCAN_TYPE_UNCHANGED = 0, 26 MWIFIEX_SCAN_TYPE_UNCHANGED = 0,
34 MWIFIEX_SCAN_TYPE_ACTIVE, 27 MWIFIEX_SCAN_TYPE_ACTIVE,
35 MWIFIEX_SCAN_TYPE_PASSIVE 28 MWIFIEX_SCAN_TYPE_PASSIVE
36}; 29};
37 30
38struct mwifiex_get_scan_table_fixed {
39 u8 bssid[ETH_ALEN];
40 u8 channel;
41 u8 rssi;
42 long long network_tsf;
43};
44
45struct mwifiex_scan_time_params {
46 u32 specific_scan_time;
47 u32 active_scan_time;
48 u32 passive_scan_time;
49};
50
51struct mwifiex_user_scan { 31struct mwifiex_user_scan {
52 u32 scan_cfg_len; 32 u32 scan_cfg_len;
53 u8 scan_cfg_buf[1]; 33 u8 scan_cfg_buf[1];
54}; 34};
55 35
56struct mwifiex_scan_req {
57 u32 scan_mode;
58 u32 scan_type;
59 struct mwifiex_802_11_ssid scan_ssid;
60 struct mwifiex_scan_time_params scan_time;
61 struct mwifiex_user_scan user_scan;
62};
63
64struct mwifiex_scan_resp {
65 u32 num_in_scan_table;
66 u8 *scan_table;
67};
68
69#define MWIFIEX_PROMISC_MODE 1 36#define MWIFIEX_PROMISC_MODE 1
70#define MWIFIEX_MULTICAST_MODE 2 37#define MWIFIEX_MULTICAST_MODE 2
71#define MWIFIEX_ALL_MULTI_MODE 4 38#define MWIFIEX_ALL_MULTI_MODE 4
@@ -77,18 +44,11 @@ struct mwifiex_multicast_list {
77 u8 mac_list[MWIFIEX_MAX_MULTICAST_LIST_SIZE][ETH_ALEN]; 44 u8 mac_list[MWIFIEX_MAX_MULTICAST_LIST_SIZE][ETH_ALEN];
78}; 45};
79 46
80#define MWIFIEX_MAX_CHANNEL_NUM 128
81
82struct mwifiex_chan_freq { 47struct mwifiex_chan_freq {
83 u32 channel; 48 u32 channel;
84 u32 freq; 49 u32 freq;
85}; 50};
86 51
87struct mwifiex_chan_list {
88 u32 num_of_chan;
89 struct mwifiex_chan_freq cf[MWIFIEX_MAX_CHANNEL_NUM];
90};
91
92struct mwifiex_ssid_bssid { 52struct mwifiex_ssid_bssid {
93 struct mwifiex_802_11_ssid ssid; 53 struct mwifiex_802_11_ssid ssid;
94 u8 bssid[ETH_ALEN]; 54 u8 bssid[ETH_ALEN];
@@ -136,18 +96,8 @@ struct mwifiex_ds_get_stats {
136 u32 wep_icv_error[4]; 96 u32 wep_icv_error[4];
137}; 97};
138 98
139#define BCN_RSSI_LAST_MASK 0x00000001
140#define BCN_RSSI_AVG_MASK 0x00000002 99#define BCN_RSSI_AVG_MASK 0x00000002
141#define DATA_RSSI_LAST_MASK 0x00000004
142#define DATA_RSSI_AVG_MASK 0x00000008
143#define BCN_SNR_LAST_MASK 0x00000010
144#define BCN_SNR_AVG_MASK 0x00000020
145#define DATA_SNR_LAST_MASK 0x00000040
146#define DATA_SNR_AVG_MASK 0x00000080
147#define BCN_NF_LAST_MASK 0x00000100
148#define BCN_NF_AVG_MASK 0x00000200 100#define BCN_NF_AVG_MASK 0x00000200
149#define DATA_NF_LAST_MASK 0x00000400
150#define DATA_NF_AVG_MASK 0x00000800
151#define ALL_RSSI_INFO_MASK 0x00000fff 101#define ALL_RSSI_INFO_MASK 0x00000fff
152 102
153struct mwifiex_ds_get_signal { 103struct mwifiex_ds_get_signal {
@@ -174,11 +124,6 @@ struct mwifiex_ds_get_signal {
174 s16 data_nf_avg; 124 s16 data_nf_avg;
175}; 125};
176 126
177struct mwifiex_fw_info {
178 u32 fw_ver;
179 u8 mac_addr[ETH_ALEN];
180};
181
182#define MWIFIEX_MAX_VER_STR_LEN 128 127#define MWIFIEX_MAX_VER_STR_LEN 128
183 128
184struct mwifiex_ver_ext { 129struct mwifiex_ver_ext {
@@ -286,11 +231,6 @@ struct mwifiex_rate_cfg {
286 u32 rate; 231 u32 rate;
287}; 232};
288 233
289struct mwifiex_data_rate {
290 u32 tx_data_rate;
291 u32 rx_data_rate;
292};
293
294struct mwifiex_power_cfg { 234struct mwifiex_power_cfg {
295 u32 is_power_auto; 235 u32 is_power_auto;
296 u32 power_level; 236 u32 power_level;
@@ -309,21 +249,14 @@ struct mwifiex_ds_hs_cfg {
309}; 249};
310 250
311#define DEEP_SLEEP_ON 1 251#define DEEP_SLEEP_ON 1
312#define DEEP_SLEEP_OFF 0
313
314#define DEEP_SLEEP_IDLE_TIME 100 252#define DEEP_SLEEP_IDLE_TIME 100
253#define PS_MODE_AUTO 1
315 254
316struct mwifiex_ds_auto_ds { 255struct mwifiex_ds_auto_ds {
317 u16 auto_ds; 256 u16 auto_ds;
318 u16 idle_time; 257 u16 idle_time;
319}; 258};
320 259
321#define PS_MODE_UNCHANGED 0
322#define PS_MODE_AUTO 1
323#define PS_MODE_POLL 2
324#define PS_MODE_NULL 3
325
326
327struct mwifiex_ds_pm_cfg { 260struct mwifiex_ds_pm_cfg {
328 union { 261 union {
329 u32 ps_mode; 262 u32 ps_mode;
@@ -333,18 +266,6 @@ struct mwifiex_ds_pm_cfg {
333 } param; 266 } param;
334}; 267};
335 268
336struct mwifiex_ioctl_wmm_queue_status_ac {
337 u8 wmm_acm;
338 u8 flow_required;
339 u8 flow_created;
340 u8 disabled;
341};
342
343struct mwifiex_ds_wmm_queue_status {
344 struct mwifiex_ioctl_wmm_queue_status_ac
345 ac_status[IEEE80211_MAX_QUEUES];
346};
347
348struct mwifiex_ds_11n_tx_cfg { 269struct mwifiex_ds_11n_tx_cfg {
349 u16 tx_htcap; 270 u16 tx_htcap;
350 u16 tx_htinfo; 271 u16 tx_htinfo;
diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c
index 85fca5eb4195..5eab3dc29b1c 100644
--- a/drivers/net/wireless/mwifiex/join.c
+++ b/drivers/net/wireless/mwifiex/join.c
@@ -143,9 +143,8 @@ mwifiex_cmd_append_tsf_tlv(struct mwifiex_private *priv, u8 **buffer,
143static int mwifiex_get_common_rates(struct mwifiex_private *priv, u8 *rate1, 143static int mwifiex_get_common_rates(struct mwifiex_private *priv, u8 *rate1,
144 u32 rate1_size, u8 *rate2, u32 rate2_size) 144 u32 rate1_size, u8 *rate2, u32 rate2_size)
145{ 145{
146 int ret = 0; 146 int ret;
147 u8 *ptr = rate1; 147 u8 *ptr = rate1, *tmp;
148 u8 *tmp = NULL;
149 u32 i, j; 148 u32 i, j;
150 149
151 tmp = kmalloc(rate1_size, GFP_KERNEL); 150 tmp = kmalloc(rate1_size, GFP_KERNEL);
@@ -203,7 +202,7 @@ mwifiex_setup_rates_from_bssdesc(struct mwifiex_private *priv,
203 u8 *out_rates, u32 *out_rates_size) 202 u8 *out_rates, u32 *out_rates_size)
204{ 203{
205 u8 card_rates[MWIFIEX_SUPPORTED_RATES]; 204 u8 card_rates[MWIFIEX_SUPPORTED_RATES];
206 u32 card_rates_size = 0; 205 u32 card_rates_size;
207 206
208 /* Copy AP supported rates */ 207 /* Copy AP supported rates */
209 memcpy(out_rates, bss_desc->supported_rates, MWIFIEX_SUPPORTED_RATES); 208 memcpy(out_rates, bss_desc->supported_rates, MWIFIEX_SUPPORTED_RATES);
@@ -1359,7 +1358,7 @@ int mwifiex_adhoc_join(struct mwifiex_private *priv,
1359static int mwifiex_deauthenticate_infra(struct mwifiex_private *priv, u8 *mac) 1358static int mwifiex_deauthenticate_infra(struct mwifiex_private *priv, u8 *mac)
1360{ 1359{
1361 u8 mac_address[ETH_ALEN]; 1360 u8 mac_address[ETH_ALEN];
1362 int ret = 0; 1361 int ret;
1363 u8 zero_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 }; 1362 u8 zero_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 };
1364 1363
1365 if (mac) { 1364 if (mac) {
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
index d16cea770fa3..f0582259c935 100644
--- a/drivers/net/wireless/mwifiex/main.c
+++ b/drivers/net/wireless/mwifiex/main.c
@@ -69,7 +69,7 @@ static int mwifiex_register(void *card, struct mwifiex_if_ops *if_ops,
69 69
70 adapter = kzalloc(sizeof(struct mwifiex_adapter), GFP_KERNEL); 70 adapter = kzalloc(sizeof(struct mwifiex_adapter), GFP_KERNEL);
71 if (!adapter) 71 if (!adapter)
72 return -1; 72 return -ENOMEM;
73 73
74 g_adapter = adapter; 74 g_adapter = adapter;
75 adapter->card = card; 75 adapter->card = card;
@@ -150,7 +150,7 @@ error:
150 */ 150 */
151static int mwifiex_unregister(struct mwifiex_adapter *adapter) 151static int mwifiex_unregister(struct mwifiex_adapter *adapter)
152{ 152{
153 s32 i = 0; 153 s32 i;
154 154
155 del_timer(&adapter->cmd_timer); 155 del_timer(&adapter->cmd_timer);
156 156
@@ -379,8 +379,7 @@ static void mwifiex_free_adapter(struct mwifiex_adapter *adapter)
379 */ 379 */
380static int mwifiex_init_hw_fw(struct mwifiex_adapter *adapter) 380static int mwifiex_init_hw_fw(struct mwifiex_adapter *adapter)
381{ 381{
382 int ret = 0; 382 int ret, err;
383 int err;
384 struct mwifiex_fw_image fw; 383 struct mwifiex_fw_image fw;
385 384
386 memset(&fw, 0, sizeof(struct mwifiex_fw_image)); 385 memset(&fw, 0, sizeof(struct mwifiex_fw_image));
@@ -449,7 +448,7 @@ done:
449static void 448static void
450mwifiex_fill_buffer(struct sk_buff *skb) 449mwifiex_fill_buffer(struct sk_buff *skb)
451{ 450{
452 struct ethhdr *eth = NULL; 451 struct ethhdr *eth;
453 struct iphdr *iph; 452 struct iphdr *iph;
454 struct timeval tv; 453 struct timeval tv;
455 u8 tid = 0; 454 u8 tid = 0;
@@ -510,20 +509,20 @@ static int
510mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) 509mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
511{ 510{
512 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); 511 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
513 struct sk_buff *new_skb = NULL; 512 struct sk_buff *new_skb;
514 struct mwifiex_txinfo *tx_info; 513 struct mwifiex_txinfo *tx_info;
515 514
516 dev_dbg(priv->adapter->dev, "data: %lu BSS(%d): Data <= kernel\n", 515 dev_dbg(priv->adapter->dev, "data: %lu BSS(%d): Data <= kernel\n",
517 jiffies, priv->bss_index); 516 jiffies, priv->bss_index);
518 517
519 if (priv->adapter->surprise_removed) { 518 if (priv->adapter->surprise_removed) {
520 kfree(skb); 519 kfree_skb(skb);
521 priv->stats.tx_dropped++; 520 priv->stats.tx_dropped++;
522 return 0; 521 return 0;
523 } 522 }
524 if (!skb->len || (skb->len > ETH_FRAME_LEN)) { 523 if (!skb->len || (skb->len > ETH_FRAME_LEN)) {
525 dev_err(priv->adapter->dev, "Tx: bad skb len %d\n", skb->len); 524 dev_err(priv->adapter->dev, "Tx: bad skb len %d\n", skb->len);
526 kfree(skb); 525 kfree_skb(skb);
527 priv->stats.tx_dropped++; 526 priv->stats.tx_dropped++;
528 return 0; 527 return 0;
529 } 528 }
@@ -536,7 +535,7 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
536 skb_realloc_headroom(skb, MWIFIEX_MIN_DATA_HEADER_LEN); 535 skb_realloc_headroom(skb, MWIFIEX_MIN_DATA_HEADER_LEN);
537 if (unlikely(!new_skb)) { 536 if (unlikely(!new_skb)) {
538 dev_err(priv->adapter->dev, "Tx: cannot alloca new_skb\n"); 537 dev_err(priv->adapter->dev, "Tx: cannot alloca new_skb\n");
539 kfree(skb); 538 kfree_skb(skb);
540 priv->stats.tx_dropped++; 539 priv->stats.tx_dropped++;
541 return 0; 540 return 0;
542 } 541 }
@@ -571,7 +570,7 @@ mwifiex_set_mac_address(struct net_device *dev, void *addr)
571{ 570{
572 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); 571 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
573 struct sockaddr *hw_addr = (struct sockaddr *) addr; 572 struct sockaddr *hw_addr = (struct sockaddr *) addr;
574 int ret = 0; 573 int ret;
575 574
576 memcpy(priv->curr_addr, hw_addr->sa_data, ETH_ALEN); 575 memcpy(priv->curr_addr, hw_addr->sa_data, ETH_ALEN);
577 576
@@ -696,9 +695,9 @@ static struct mwifiex_private *mwifiex_add_interface(
696 struct mwifiex_adapter *adapter, 695 struct mwifiex_adapter *adapter,
697 u8 bss_index, u8 bss_type) 696 u8 bss_index, u8 bss_type)
698{ 697{
699 struct net_device *dev = NULL; 698 struct net_device *dev;
700 struct mwifiex_private *priv = NULL; 699 struct mwifiex_private *priv;
701 void *mdev_priv = NULL; 700 void *mdev_priv;
702 701
703 dev = alloc_netdev_mq(sizeof(struct mwifiex_private *), "mlan%d", 702 dev = alloc_netdev_mq(sizeof(struct mwifiex_private *), "mlan%d",
704 ether_setup, 1); 703 ether_setup, 1);
@@ -759,7 +758,7 @@ error:
759static void 758static void
760mwifiex_remove_interface(struct mwifiex_adapter *adapter, u8 bss_index) 759mwifiex_remove_interface(struct mwifiex_adapter *adapter, u8 bss_index)
761{ 760{
762 struct net_device *dev = NULL; 761 struct net_device *dev;
763 struct mwifiex_private *priv = adapter->priv[bss_index]; 762 struct mwifiex_private *priv = adapter->priv[bss_index];
764 763
765 if (!priv) 764 if (!priv)
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index 5043fcd22565..672701dc2721 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -479,9 +479,9 @@ struct mwifiex_private {
479 u8 report_scan_result; 479 u8 report_scan_result;
480 struct cfg80211_scan_request *scan_request; 480 struct cfg80211_scan_request *scan_request;
481 int scan_result_status; 481 int scan_result_status;
482 bool assoc_request; 482 int assoc_request;
483 u16 assoc_result; 483 u16 assoc_result;
484 bool ibss_join_request; 484 int ibss_join_request;
485 u16 ibss_join_result; 485 u16 ibss_join_result;
486 bool disconnect; 486 bool disconnect;
487 u8 cfg_bssid[6]; 487 u8 cfg_bssid[6];
@@ -692,10 +692,6 @@ int mwifiex_shutdown_fw_complete(struct mwifiex_adapter *adapter);
692 692
693int mwifiex_dnld_fw(struct mwifiex_adapter *, struct mwifiex_fw_image *); 693int mwifiex_dnld_fw(struct mwifiex_adapter *, struct mwifiex_fw_image *);
694 694
695int mwifiex_recv_complete(struct mwifiex_adapter *,
696 struct sk_buff *skb,
697 int status);
698
699int mwifiex_recv_packet(struct mwifiex_adapter *, struct sk_buff *skb); 695int mwifiex_recv_packet(struct mwifiex_adapter *, struct sk_buff *skb);
700 696
701int mwifiex_process_event(struct mwifiex_adapter *adapter); 697int mwifiex_process_event(struct mwifiex_adapter *adapter);
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c
index 31a529578805..5c22860fb40a 100644
--- a/drivers/net/wireless/mwifiex/scan.c
+++ b/drivers/net/wireless/mwifiex/scan.c
@@ -117,8 +117,8 @@ mwifiex_search_oui_in_ie(struct ie_body *iebody, u8 *oui)
117static u8 117static u8
118mwifiex_is_rsn_oui_present(struct mwifiex_bssdescriptor *bss_desc, u32 cipher) 118mwifiex_is_rsn_oui_present(struct mwifiex_bssdescriptor *bss_desc, u32 cipher)
119{ 119{
120 u8 *oui = NULL; 120 u8 *oui;
121 struct ie_body *iebody = NULL; 121 struct ie_body *iebody;
122 u8 ret = MWIFIEX_OUI_NOT_PRESENT; 122 u8 ret = MWIFIEX_OUI_NOT_PRESENT;
123 123
124 if (((bss_desc->bcn_rsn_ie) && ((*(bss_desc->bcn_rsn_ie)). 124 if (((bss_desc->bcn_rsn_ie) && ((*(bss_desc->bcn_rsn_ie)).
@@ -144,8 +144,8 @@ mwifiex_is_rsn_oui_present(struct mwifiex_bssdescriptor *bss_desc, u32 cipher)
144static u8 144static u8
145mwifiex_is_wpa_oui_present(struct mwifiex_bssdescriptor *bss_desc, u32 cipher) 145mwifiex_is_wpa_oui_present(struct mwifiex_bssdescriptor *bss_desc, u32 cipher)
146{ 146{
147 u8 *oui = NULL; 147 u8 *oui;
148 struct ie_body *iebody = NULL; 148 struct ie_body *iebody;
149 u8 ret = MWIFIEX_OUI_NOT_PRESENT; 149 u8 ret = MWIFIEX_OUI_NOT_PRESENT;
150 150
151 if (((bss_desc->bcn_wpa_ie) && ((*(bss_desc->bcn_wpa_ie)). 151 if (((bss_desc->bcn_wpa_ie) && ((*(bss_desc->bcn_wpa_ie)).
@@ -181,7 +181,7 @@ int mwifiex_find_best_bss(struct mwifiex_private *priv,
181 struct mwifiex_ssid_bssid *ssid_bssid) 181 struct mwifiex_ssid_bssid *ssid_bssid)
182{ 182{
183 struct mwifiex_ssid_bssid tmp_ssid_bssid; 183 struct mwifiex_ssid_bssid tmp_ssid_bssid;
184 u8 *mac = NULL; 184 u8 *mac;
185 185
186 if (!ssid_bssid) 186 if (!ssid_bssid)
187 return -1; 187 return -1;
@@ -213,7 +213,7 @@ int mwifiex_find_best_bss(struct mwifiex_private *priv,
213int mwifiex_set_user_scan_ioctl(struct mwifiex_private *priv, 213int mwifiex_set_user_scan_ioctl(struct mwifiex_private *priv,
214 struct mwifiex_user_scan_cfg *scan_req) 214 struct mwifiex_user_scan_cfg *scan_req)
215{ 215{
216 int status = 0; 216 int status;
217 217
218 priv->adapter->cmd_wait_q.condition = false; 218 priv->adapter->cmd_wait_q.condition = false;
219 219
@@ -2253,8 +2253,8 @@ int mwifiex_scan_networks(struct mwifiex_private *priv,
2253{ 2253{
2254 int ret = 0; 2254 int ret = 0;
2255 struct mwifiex_adapter *adapter = priv->adapter; 2255 struct mwifiex_adapter *adapter = priv->adapter;
2256 struct cmd_ctrl_node *cmd_node = NULL; 2256 struct cmd_ctrl_node *cmd_node;
2257 union mwifiex_scan_cmd_config_tlv *scan_cfg_out = NULL; 2257 union mwifiex_scan_cmd_config_tlv *scan_cfg_out;
2258 struct mwifiex_ie_types_chan_list_param_set *chan_list_out; 2258 struct mwifiex_ie_types_chan_list_param_set *chan_list_out;
2259 u32 buf_size; 2259 u32 buf_size;
2260 struct mwifiex_chan_scan_param_set *scan_chan_list; 2260 struct mwifiex_chan_scan_param_set *scan_chan_list;
@@ -2283,7 +2283,7 @@ int mwifiex_scan_networks(struct mwifiex_private *priv,
2283 GFP_KERNEL); 2283 GFP_KERNEL);
2284 if (!scan_cfg_out) { 2284 if (!scan_cfg_out) {
2285 dev_err(adapter->dev, "failed to alloc scan_cfg_out\n"); 2285 dev_err(adapter->dev, "failed to alloc scan_cfg_out\n");
2286 return -1; 2286 return -ENOMEM;
2287 } 2287 }
2288 2288
2289 buf_size = sizeof(struct mwifiex_chan_scan_param_set) * 2289 buf_size = sizeof(struct mwifiex_chan_scan_param_set) *
@@ -2292,7 +2292,7 @@ int mwifiex_scan_networks(struct mwifiex_private *priv,
2292 if (!scan_chan_list) { 2292 if (!scan_chan_list) {
2293 dev_err(adapter->dev, "failed to alloc scan_chan_list\n"); 2293 dev_err(adapter->dev, "failed to alloc scan_chan_list\n");
2294 kfree(scan_cfg_out); 2294 kfree(scan_cfg_out);
2295 return -1; 2295 return -ENOMEM;
2296 } 2296 }
2297 2297
2298 keep_previous_scan = false; 2298 keep_previous_scan = false;
@@ -2404,8 +2404,8 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
2404{ 2404{
2405 int ret = 0; 2405 int ret = 0;
2406 struct mwifiex_adapter *adapter = priv->adapter; 2406 struct mwifiex_adapter *adapter = priv->adapter;
2407 struct cmd_ctrl_node *cmd_node = NULL; 2407 struct cmd_ctrl_node *cmd_node;
2408 struct host_cmd_ds_802_11_scan_rsp *scan_rsp = NULL; 2408 struct host_cmd_ds_802_11_scan_rsp *scan_rsp;
2409 struct mwifiex_bssdescriptor *bss_new_entry = NULL; 2409 struct mwifiex_bssdescriptor *bss_new_entry = NULL;
2410 struct mwifiex_ie_types_data *tlv_data; 2410 struct mwifiex_ie_types_data *tlv_data;
2411 struct mwifiex_ie_types_tsf_timestamp *tsf_tlv; 2411 struct mwifiex_ie_types_tsf_timestamp *tsf_tlv;
@@ -2491,7 +2491,7 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
2491 GFP_KERNEL); 2491 GFP_KERNEL);
2492 if (!bss_new_entry) { 2492 if (!bss_new_entry) {
2493 dev_err(adapter->dev, " failed to alloc bss_new_entry\n"); 2493 dev_err(adapter->dev, " failed to alloc bss_new_entry\n");
2494 return -1; 2494 return -ENOMEM;
2495 } 2495 }
2496 2496
2497 for (idx = 0; idx < scan_rsp->number_of_sets && bytes_left; idx++) { 2497 for (idx = 0; idx < scan_rsp->number_of_sets && bytes_left; idx++) {
@@ -2881,7 +2881,7 @@ static int mwifiex_scan_specific_ssid(struct mwifiex_private *priv,
2881 scan_cfg = kzalloc(sizeof(struct mwifiex_user_scan_cfg), GFP_KERNEL); 2881 scan_cfg = kzalloc(sizeof(struct mwifiex_user_scan_cfg), GFP_KERNEL);
2882 if (!scan_cfg) { 2882 if (!scan_cfg) {
2883 dev_err(adapter->dev, "failed to alloc scan_cfg\n"); 2883 dev_err(adapter->dev, "failed to alloc scan_cfg\n");
2884 return -1; 2884 return -ENOMEM;
2885 } 2885 }
2886 2886
2887 memcpy(scan_cfg->ssid_list[0].ssid, req_ssid->ssid, 2887 memcpy(scan_cfg->ssid_list[0].ssid, req_ssid->ssid,
@@ -2906,7 +2906,7 @@ static int mwifiex_scan_specific_ssid(struct mwifiex_private *priv,
2906int mwifiex_request_scan(struct mwifiex_private *priv, 2906int mwifiex_request_scan(struct mwifiex_private *priv,
2907 struct mwifiex_802_11_ssid *req_ssid) 2907 struct mwifiex_802_11_ssid *req_ssid)
2908{ 2908{
2909 int ret = 0; 2909 int ret;
2910 2910
2911 if (down_interruptible(&priv->async_sem)) { 2911 if (down_interruptible(&priv->async_sem)) {
2912 dev_err(priv->adapter->dev, "%s: acquire semaphore\n", 2912 dev_err(priv->adapter->dev, "%s: acquire semaphore\n",
diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c
index 5148d0e0fad6..d425dbd91d19 100644
--- a/drivers/net/wireless/mwifiex/sdio.c
+++ b/drivers/net/wireless/mwifiex/sdio.c
@@ -46,7 +46,7 @@ static struct semaphore add_remove_card_sem;
46static int 46static int
47mwifiex_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id) 47mwifiex_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id)
48{ 48{
49 int ret = 0; 49 int ret;
50 struct sdio_mmc_card *card = NULL; 50 struct sdio_mmc_card *card = NULL;
51 51
52 pr_debug("info: vendor=0x%4.04X device=0x%4.04X class=%d function=%d\n", 52 pr_debug("info: vendor=0x%4.04X device=0x%4.04X class=%d function=%d\n",
@@ -68,6 +68,7 @@ mwifiex_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id)
68 68
69 if (ret) { 69 if (ret) {
70 pr_err("%s: failed to enable function\n", __func__); 70 pr_err("%s: failed to enable function\n", __func__);
71 kfree(card);
71 return -EIO; 72 return -EIO;
72 } 73 }
73 74
@@ -119,7 +120,7 @@ static int mwifiex_sdio_suspend(struct device *dev)
119{ 120{
120 struct sdio_func *func = dev_to_sdio_func(dev); 121 struct sdio_func *func = dev_to_sdio_func(dev);
121 struct sdio_mmc_card *card; 122 struct sdio_mmc_card *card;
122 struct mwifiex_adapter *adapter = NULL; 123 struct mwifiex_adapter *adapter;
123 mmc_pm_flag_t pm_flag = 0; 124 mmc_pm_flag_t pm_flag = 0;
124 int hs_actived = 0; 125 int hs_actived = 0;
125 int i; 126 int i;
@@ -177,7 +178,7 @@ static int mwifiex_sdio_resume(struct device *dev)
177{ 178{
178 struct sdio_func *func = dev_to_sdio_func(dev); 179 struct sdio_func *func = dev_to_sdio_func(dev);
179 struct sdio_mmc_card *card; 180 struct sdio_mmc_card *card;
180 struct mwifiex_adapter *adapter = NULL; 181 struct mwifiex_adapter *adapter;
181 mmc_pm_flag_t pm_flag = 0; 182 mmc_pm_flag_t pm_flag = 0;
182 int i; 183 int i;
183 184
@@ -420,7 +421,7 @@ static int mwifiex_write_data_to_card(struct mwifiex_adapter *adapter,
420 u8 *payload, u32 pkt_len, u32 port) 421 u8 *payload, u32 pkt_len, u32 port)
421{ 422{
422 u32 i = 0; 423 u32 i = 0;
423 int ret = 0; 424 int ret;
424 425
425 do { 426 do {
426 ret = mwifiex_write_data_sync(adapter, payload, pkt_len, port); 427 ret = mwifiex_write_data_sync(adapter, payload, pkt_len, port);
@@ -531,7 +532,7 @@ static int
531mwifiex_sdio_poll_card_status(struct mwifiex_adapter *adapter, u8 bits) 532mwifiex_sdio_poll_card_status(struct mwifiex_adapter *adapter, u8 bits)
532{ 533{
533 u32 tries; 534 u32 tries;
534 u32 cs = 0; 535 u32 cs;
535 536
536 for (tries = 0; tries < MAX_POLL_TRIES; tries++) { 537 for (tries = 0; tries < MAX_POLL_TRIES; tries++) {
537 if (mwifiex_read_reg(adapter, CARD_STATUS_REG, &cs)) 538 if (mwifiex_read_reg(adapter, CARD_STATUS_REG, &cs))
@@ -553,7 +554,7 @@ mwifiex_sdio_poll_card_status(struct mwifiex_adapter *adapter, u8 bits)
553static int 554static int
554mwifiex_sdio_read_fw_status(struct mwifiex_adapter *adapter, u16 *dat) 555mwifiex_sdio_read_fw_status(struct mwifiex_adapter *adapter, u16 *dat)
555{ 556{
556 u32 fws0 = 0, fws1 = 0; 557 u32 fws0, fws1;
557 558
558 if (mwifiex_read_reg(adapter, CARD_FW_STATUS0_REG, &fws0)) 559 if (mwifiex_read_reg(adapter, CARD_FW_STATUS0_REG, &fws0))
559 return -1; 560 return -1;
@@ -574,7 +575,7 @@ mwifiex_sdio_read_fw_status(struct mwifiex_adapter *adapter, u16 *dat)
574 */ 575 */
575static int mwifiex_sdio_disable_host_int(struct mwifiex_adapter *adapter) 576static int mwifiex_sdio_disable_host_int(struct mwifiex_adapter *adapter)
576{ 577{
577 u32 host_int_mask = 0; 578 u32 host_int_mask;
578 579
579 /* Read back the host_int_mask register */ 580 /* Read back the host_int_mask register */
580 if (mwifiex_read_reg(adapter, HOST_INT_MASK_REG, &host_int_mask)) 581 if (mwifiex_read_reg(adapter, HOST_INT_MASK_REG, &host_int_mask))
@@ -614,7 +615,7 @@ static int mwifiex_sdio_card_to_host(struct mwifiex_adapter *adapter,
614 u32 *type, u8 *buffer, 615 u32 *type, u8 *buffer,
615 u32 npayload, u32 ioport) 616 u32 npayload, u32 ioport)
616{ 617{
617 int ret = 0; 618 int ret;
618 u32 nb; 619 u32 nb;
619 620
620 if (!buffer) { 621 if (!buffer) {
@@ -652,14 +653,14 @@ static int mwifiex_sdio_card_to_host(struct mwifiex_adapter *adapter,
652static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, 653static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
653 struct mwifiex_fw_image *fw) 654 struct mwifiex_fw_image *fw)
654{ 655{
655 int ret = 0; 656 int ret;
656 u8 *firmware = fw->fw_buf; 657 u8 *firmware = fw->fw_buf;
657 u32 firmware_len = fw->fw_len; 658 u32 firmware_len = fw->fw_len;
658 u32 offset = 0; 659 u32 offset = 0;
659 u32 base0, base1; 660 u32 base0, base1;
660 u8 *fwbuf; 661 u8 *fwbuf;
661 u16 len = 0; 662 u16 len = 0;
662 u32 txlen = 0, tx_blocks = 0, tries = 0; 663 u32 txlen, tx_blocks = 0, tries;
663 u32 i = 0; 664 u32 i = 0;
664 665
665 if (!firmware_len) { 666 if (!firmware_len) {
@@ -676,7 +677,7 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
676 if (!fwbuf) { 677 if (!fwbuf) {
677 dev_err(adapter->dev, "unable to alloc buffer for firmware." 678 dev_err(adapter->dev, "unable to alloc buffer for firmware."
678 " Terminating download\n"); 679 " Terminating download\n");
679 return -1; 680 return -ENOMEM;
680 } 681 }
681 682
682 /* Perform firmware data transfer */ 683 /* Perform firmware data transfer */
@@ -830,7 +831,7 @@ static int mwifiex_check_fw_status(struct mwifiex_adapter *adapter,
830static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter) 831static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter)
831{ 832{
832 struct sdio_mmc_card *card = adapter->card; 833 struct sdio_mmc_card *card = adapter->card;
833 u32 sdio_ireg = 0; 834 u32 sdio_ireg;
834 unsigned long flags; 835 unsigned long flags;
835 836
836 if (mwifiex_read_data_sync(adapter, card->mp_regs, MAX_MP_REGS, 837 if (mwifiex_read_data_sync(adapter, card->mp_regs, MAX_MP_REGS,
@@ -964,7 +965,7 @@ static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter,
964 s32 f_do_rx_cur = 0; 965 s32 f_do_rx_cur = 0;
965 s32 f_aggr_cur = 0; 966 s32 f_aggr_cur = 0;
966 struct sk_buff *skb_deaggr; 967 struct sk_buff *skb_deaggr;
967 u32 pind = 0; 968 u32 pind;
968 u32 pkt_len, pkt_type = 0; 969 u32 pkt_len, pkt_type = 0;
969 u8 *curr_ptr; 970 u8 *curr_ptr;
970 u32 rx_len = skb->len; 971 u32 rx_len = skb->len;
@@ -1114,7 +1115,7 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
1114 struct sdio_mmc_card *card = adapter->card; 1115 struct sdio_mmc_card *card = adapter->card;
1115 int ret = 0; 1116 int ret = 0;
1116 u8 sdio_ireg; 1117 u8 sdio_ireg;
1117 struct sk_buff *skb = NULL; 1118 struct sk_buff *skb;
1118 u8 port = CTRL_PORT; 1119 u8 port = CTRL_PORT;
1119 u32 len_reg_l, len_reg_u; 1120 u32 len_reg_l, len_reg_u;
1120 u32 rx_blocks; 1121 u32 rx_blocks;
@@ -1377,7 +1378,7 @@ static int mwifiex_sdio_host_to_card(struct mwifiex_adapter *adapter,
1377 struct mwifiex_tx_param *tx_param) 1378 struct mwifiex_tx_param *tx_param)
1378{ 1379{
1379 struct sdio_mmc_card *card = adapter->card; 1380 struct sdio_mmc_card *card = adapter->card;
1380 int ret = 0; 1381 int ret;
1381 u32 buf_block_len; 1382 u32 buf_block_len;
1382 u32 blk_size; 1383 u32 blk_size;
1383 u8 port = CTRL_PORT; 1384 u8 port = CTRL_PORT;
@@ -1560,7 +1561,7 @@ static int mwifiex_init_sdio(struct mwifiex_adapter *adapter)
1560{ 1561{
1561 struct sdio_mmc_card *card = adapter->card; 1562 struct sdio_mmc_card *card = adapter->card;
1562 int ret; 1563 int ret;
1563 u32 sdio_ireg = 0; 1564 u32 sdio_ireg;
1564 1565
1565 /* 1566 /*
1566 * Read the HOST_INT_STATUS_REG for ACK the first interrupt got 1567 * Read the HOST_INT_STATUS_REG for ACK the first interrupt got
@@ -1605,7 +1606,7 @@ static int mwifiex_init_sdio(struct mwifiex_adapter *adapter)
1605 card->mp_regs = kzalloc(MAX_MP_REGS, GFP_KERNEL); 1606 card->mp_regs = kzalloc(MAX_MP_REGS, GFP_KERNEL);
1606 if (!card->mp_regs) { 1607 if (!card->mp_regs) {
1607 dev_err(adapter->dev, "failed to alloc mp_regs\n"); 1608 dev_err(adapter->dev, "failed to alloc mp_regs\n");
1608 return -1; 1609 return -ENOMEM;
1609 } 1610 }
1610 1611
1611 ret = mwifiex_alloc_sdio_mpa_buffers(adapter, 1612 ret = mwifiex_alloc_sdio_mpa_buffers(adapter,
diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c
index 33c8ba1f5e33..8af3a78d2723 100644
--- a/drivers/net/wireless/mwifiex/sta_cmd.c
+++ b/drivers/net/wireless/mwifiex/sta_cmd.c
@@ -274,8 +274,8 @@ static int mwifiex_cmd_tx_rate_cfg(struct mwifiex_private *priv,
274static int mwifiex_cmd_tx_power_cfg(struct host_cmd_ds_command *cmd, 274static int mwifiex_cmd_tx_power_cfg(struct host_cmd_ds_command *cmd,
275 u16 cmd_action, void *data_buf) 275 u16 cmd_action, void *data_buf)
276{ 276{
277 struct mwifiex_types_power_group *pg_tlv = NULL; 277 struct mwifiex_types_power_group *pg_tlv;
278 struct host_cmd_ds_txpwr_cfg *txp = NULL; 278 struct host_cmd_ds_txpwr_cfg *txp;
279 struct host_cmd_ds_txpwr_cfg *cmd_txp_cfg = &cmd->params.txp_cfg; 279 struct host_cmd_ds_txpwr_cfg *cmd_txp_cfg = &cmd->params.txp_cfg;
280 280
281 cmd->command = cpu_to_le16(HostCmd_CMD_TXPWR_CFG); 281 cmd->command = cpu_to_le16(HostCmd_CMD_TXPWR_CFG);
@@ -478,7 +478,7 @@ mwifiex_set_keyparamset_wep(struct mwifiex_private *priv,
478 struct mwifiex_ie_type_key_param_set *key_param_set, 478 struct mwifiex_ie_type_key_param_set *key_param_set,
479 u16 *key_param_len) 479 u16 *key_param_len)
480{ 480{
481 int cur_key_param_len = 0; 481 int cur_key_param_len;
482 u8 i; 482 u8 i;
483 483
484 /* Multi-key_param_set TLV is supported */ 484 /* Multi-key_param_set TLV is supported */
@@ -1121,7 +1121,7 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no,
1121 */ 1121 */
1122int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta) 1122int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta)
1123{ 1123{
1124 int ret = 0; 1124 int ret;
1125 u16 enable = true; 1125 u16 enable = true;
1126 struct mwifiex_ds_11n_amsdu_aggr_ctrl amsdu_aggr_ctrl; 1126 struct mwifiex_ds_11n_amsdu_aggr_ctrl amsdu_aggr_ctrl;
1127 struct mwifiex_ds_auto_ds auto_ds; 1127 struct mwifiex_ds_auto_ds auto_ds;
diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c
index 7f4f10b752fb..d08f76429a0a 100644
--- a/drivers/net/wireless/mwifiex/sta_cmdresp.c
+++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c
@@ -43,7 +43,7 @@ static void
43mwifiex_process_cmdresp_error(struct mwifiex_private *priv, 43mwifiex_process_cmdresp_error(struct mwifiex_private *priv,
44 struct host_cmd_ds_command *resp) 44 struct host_cmd_ds_command *resp)
45{ 45{
46 struct cmd_ctrl_node *cmd_node = NULL, *tmp_node = NULL; 46 struct cmd_ctrl_node *cmd_node = NULL, *tmp_node;
47 struct mwifiex_adapter *adapter = priv->adapter; 47 struct mwifiex_adapter *adapter = priv->adapter;
48 struct host_cmd_ds_802_11_ps_mode_enh *pm; 48 struct host_cmd_ds_802_11_ps_mode_enh *pm;
49 unsigned long flags; 49 unsigned long flags;
@@ -124,7 +124,7 @@ static int mwifiex_ret_802_11_rssi_info(struct mwifiex_private *priv,
124{ 124{
125 struct host_cmd_ds_802_11_rssi_info_rsp *rssi_info_rsp = 125 struct host_cmd_ds_802_11_rssi_info_rsp *rssi_info_rsp =
126 &resp->params.rssi_info_rsp; 126 &resp->params.rssi_info_rsp;
127 struct mwifiex_ds_get_signal *signal = NULL; 127 struct mwifiex_ds_get_signal *signal;
128 128
129 priv->data_rssi_last = le16_to_cpu(rssi_info_rsp->data_rssi_last); 129 priv->data_rssi_last = le16_to_cpu(rssi_info_rsp->data_rssi_last);
130 priv->data_nf_last = le16_to_cpu(rssi_info_rsp->data_nf_last); 130 priv->data_nf_last = le16_to_cpu(rssi_info_rsp->data_nf_last);
@@ -232,7 +232,7 @@ static int mwifiex_ret_get_log(struct mwifiex_private *priv,
232{ 232{
233 struct host_cmd_ds_802_11_get_log *get_log = 233 struct host_cmd_ds_802_11_get_log *get_log =
234 (struct host_cmd_ds_802_11_get_log *) &resp->params.get_log; 234 (struct host_cmd_ds_802_11_get_log *) &resp->params.get_log;
235 struct mwifiex_ds_get_stats *stats = NULL; 235 struct mwifiex_ds_get_stats *stats;
236 236
237 if (data_buf) { 237 if (data_buf) {
238 stats = (struct mwifiex_ds_get_stats *) data_buf; 238 stats = (struct mwifiex_ds_get_stats *) data_buf;
@@ -280,10 +280,10 @@ static int mwifiex_ret_tx_rate_cfg(struct mwifiex_private *priv,
280 struct host_cmd_ds_command *resp, 280 struct host_cmd_ds_command *resp,
281 void *data_buf) 281 void *data_buf)
282{ 282{
283 struct mwifiex_rate_cfg *ds_rate = NULL; 283 struct mwifiex_rate_cfg *ds_rate;
284 struct host_cmd_ds_tx_rate_cfg *rate_cfg = &resp->params.tx_rate_cfg; 284 struct host_cmd_ds_tx_rate_cfg *rate_cfg = &resp->params.tx_rate_cfg;
285 struct mwifiex_rate_scope *rate_scope; 285 struct mwifiex_rate_scope *rate_scope;
286 struct mwifiex_ie_types_header *head = NULL; 286 struct mwifiex_ie_types_header *head;
287 u16 tlv, tlv_buf_len; 287 u16 tlv, tlv_buf_len;
288 u8 *tlv_buf; 288 u8 *tlv_buf;
289 u32 i; 289 u32 i;
@@ -368,9 +368,9 @@ static int mwifiex_ret_tx_rate_cfg(struct mwifiex_private *priv,
368 */ 368 */
369static int mwifiex_get_power_level(struct mwifiex_private *priv, void *data_buf) 369static int mwifiex_get_power_level(struct mwifiex_private *priv, void *data_buf)
370{ 370{
371 int length = -1, max_power = -1, min_power = -1; 371 int length, max_power = -1, min_power = -1;
372 struct mwifiex_types_power_group *pg_tlv_hdr = NULL; 372 struct mwifiex_types_power_group *pg_tlv_hdr;
373 struct mwifiex_power_group *pg = NULL; 373 struct mwifiex_power_group *pg;
374 374
375 if (data_buf) { 375 if (data_buf) {
376 pg_tlv_hdr = 376 pg_tlv_hdr =
@@ -418,8 +418,8 @@ static int mwifiex_ret_tx_power_cfg(struct mwifiex_private *priv,
418{ 418{
419 struct mwifiex_adapter *adapter = priv->adapter; 419 struct mwifiex_adapter *adapter = priv->adapter;
420 struct host_cmd_ds_txpwr_cfg *txp_cfg = &resp->params.txp_cfg; 420 struct host_cmd_ds_txpwr_cfg *txp_cfg = &resp->params.txp_cfg;
421 struct mwifiex_types_power_group *pg_tlv_hdr = NULL; 421 struct mwifiex_types_power_group *pg_tlv_hdr;
422 struct mwifiex_power_group *pg = NULL; 422 struct mwifiex_power_group *pg;
423 u16 action = le16_to_cpu(txp_cfg->action); 423 u16 action = le16_to_cpu(txp_cfg->action);
424 424
425 switch (action) { 425 switch (action) {
@@ -593,7 +593,7 @@ static int mwifiex_ret_802_11d_domain_info(struct mwifiex_private *priv,
593 &resp->params.domain_info_resp; 593 &resp->params.domain_info_resp;
594 struct mwifiex_ietypes_domain_param_set *domain = &domain_info->domain; 594 struct mwifiex_ietypes_domain_param_set *domain = &domain_info->domain;
595 u16 action = le16_to_cpu(domain_info->action); 595 u16 action = le16_to_cpu(domain_info->action);
596 u8 no_of_triplet = 0; 596 u8 no_of_triplet;
597 597
598 no_of_triplet = (u8) ((le16_to_cpu(domain->header.len) - 598 no_of_triplet = (u8) ((le16_to_cpu(domain->header.len) -
599 IEEE80211_COUNTRY_STRING_LEN) / 599 IEEE80211_COUNTRY_STRING_LEN) /
@@ -661,7 +661,7 @@ static int mwifiex_ret_ver_ext(struct mwifiex_private *priv,
661 void *data_buf) 661 void *data_buf)
662{ 662{
663 struct host_cmd_ds_version_ext *ver_ext = &resp->params.verext; 663 struct host_cmd_ds_version_ext *ver_ext = &resp->params.verext;
664 struct host_cmd_ds_version_ext *version_ext = NULL; 664 struct host_cmd_ds_version_ext *version_ext;
665 665
666 if (data_buf) { 666 if (data_buf) {
667 version_ext = (struct host_cmd_ds_version_ext *)data_buf; 667 version_ext = (struct host_cmd_ds_version_ext *)data_buf;
@@ -682,8 +682,8 @@ static int mwifiex_ret_ver_ext(struct mwifiex_private *priv,
682static int mwifiex_ret_reg_access(u16 type, struct host_cmd_ds_command *resp, 682static int mwifiex_ret_reg_access(u16 type, struct host_cmd_ds_command *resp,
683 void *data_buf) 683 void *data_buf)
684{ 684{
685 struct mwifiex_ds_reg_rw *reg_rw = NULL; 685 struct mwifiex_ds_reg_rw *reg_rw;
686 struct mwifiex_ds_read_eeprom *eeprom = NULL; 686 struct mwifiex_ds_read_eeprom *eeprom;
687 687
688 if (data_buf) { 688 if (data_buf) {
689 reg_rw = (struct mwifiex_ds_reg_rw *) data_buf; 689 reg_rw = (struct mwifiex_ds_reg_rw *) data_buf;
diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c
index e7adaab35226..d05907d05039 100644
--- a/drivers/net/wireless/mwifiex/sta_ioctl.c
+++ b/drivers/net/wireless/mwifiex/sta_ioctl.c
@@ -149,7 +149,7 @@ int mwifiex_request_set_multicast_list(struct mwifiex_private *priv,
149int mwifiex_bss_start(struct mwifiex_private *priv, 149int mwifiex_bss_start(struct mwifiex_private *priv,
150 struct mwifiex_ssid_bssid *ssid_bssid) 150 struct mwifiex_ssid_bssid *ssid_bssid)
151{ 151{
152 int ret = 0; 152 int ret;
153 struct mwifiex_adapter *adapter = priv->adapter; 153 struct mwifiex_adapter *adapter = priv->adapter;
154 s32 i = -1; 154 s32 i = -1;
155 155
@@ -376,7 +376,7 @@ int mwifiex_get_bss_info(struct mwifiex_private *priv,
376{ 376{
377 struct mwifiex_adapter *adapter = priv->adapter; 377 struct mwifiex_adapter *adapter = priv->adapter;
378 struct mwifiex_bssdescriptor *bss_desc; 378 struct mwifiex_bssdescriptor *bss_desc;
379 s32 tbl_idx = 0; 379 s32 tbl_idx;
380 380
381 if (!info) 381 if (!info)
382 return -1; 382 return -1;
@@ -436,9 +436,8 @@ int mwifiex_set_radio_band_cfg(struct mwifiex_private *priv,
436 struct mwifiex_ds_band_cfg *radio_cfg) 436 struct mwifiex_ds_band_cfg *radio_cfg)
437{ 437{
438 struct mwifiex_adapter *adapter = priv->adapter; 438 struct mwifiex_adapter *adapter = priv->adapter;
439 u8 infra_band = 0; 439 u8 infra_band, adhoc_band;
440 u8 adhoc_band = 0; 440 u32 adhoc_channel;
441 u32 adhoc_channel = 0;
442 441
443 infra_band = (u8) radio_cfg->config_bands; 442 infra_band = (u8) radio_cfg->config_bands;
444 adhoc_band = (u8) radio_cfg->adhoc_start_band; 443 adhoc_band = (u8) radio_cfg->adhoc_start_band;
@@ -636,7 +635,7 @@ int mwifiex_bss_ioctl_find_bss(struct mwifiex_private *priv,
636int 635int
637mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel) 636mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel)
638{ 637{
639 int ret = 0; 638 int ret;
640 struct mwifiex_bss_info bss_info; 639 struct mwifiex_bss_info bss_info;
641 struct mwifiex_ssid_bssid ssid_bssid; 640 struct mwifiex_ssid_bssid ssid_bssid;
642 u16 curr_chan = 0; 641 u16 curr_chan = 0;
@@ -755,11 +754,10 @@ static int mwifiex_rate_ioctl_set_rate_value(struct mwifiex_private *priv,
755 struct mwifiex_rate_cfg *rate_cfg) 754 struct mwifiex_rate_cfg *rate_cfg)
756{ 755{
757 u8 rates[MWIFIEX_SUPPORTED_RATES]; 756 u8 rates[MWIFIEX_SUPPORTED_RATES];
758 u8 *rate = NULL; 757 u8 *rate;
759 int rate_index = 0; 758 int rate_index, ret;
760 u16 bitmap_rates[MAX_BITMAP_RATES_SIZE]; 759 u16 bitmap_rates[MAX_BITMAP_RATES_SIZE];
761 u32 i = 0; 760 u32 i;
762 int ret = 0;
763 struct mwifiex_adapter *adapter = priv->adapter; 761 struct mwifiex_adapter *adapter = priv->adapter;
764 762
765 if (rate_cfg->is_rate_auto) { 763 if (rate_cfg->is_rate_auto) {
@@ -819,7 +817,7 @@ static int mwifiex_rate_ioctl_set_rate_value(struct mwifiex_private *priv,
819static int mwifiex_rate_ioctl_cfg(struct mwifiex_private *priv, 817static int mwifiex_rate_ioctl_cfg(struct mwifiex_private *priv,
820 struct mwifiex_rate_cfg *rate_cfg) 818 struct mwifiex_rate_cfg *rate_cfg)
821{ 819{
822 int status = 0; 820 int status;
823 821
824 if (!rate_cfg) 822 if (!rate_cfg)
825 return -1; 823 return -1;
@@ -841,7 +839,7 @@ static int mwifiex_rate_ioctl_cfg(struct mwifiex_private *priv,
841int mwifiex_drv_get_data_rate(struct mwifiex_private *priv, 839int mwifiex_drv_get_data_rate(struct mwifiex_private *priv,
842 struct mwifiex_rate_cfg *rate) 840 struct mwifiex_rate_cfg *rate)
843{ 841{
844 int ret = 0; 842 int ret;
845 843
846 memset(rate, 0, sizeof(struct mwifiex_rate_cfg)); 844 memset(rate, 0, sizeof(struct mwifiex_rate_cfg));
847 rate->action = HostCmd_ACT_GEN_GET; 845 rate->action = HostCmd_ACT_GEN_GET;
@@ -875,11 +873,11 @@ int mwifiex_drv_get_data_rate(struct mwifiex_private *priv,
875int mwifiex_set_tx_power(struct mwifiex_private *priv, 873int mwifiex_set_tx_power(struct mwifiex_private *priv,
876 struct mwifiex_power_cfg *power_cfg) 874 struct mwifiex_power_cfg *power_cfg)
877{ 875{
878 int ret = 0; 876 int ret;
879 struct host_cmd_ds_txpwr_cfg *txp_cfg = NULL; 877 struct host_cmd_ds_txpwr_cfg *txp_cfg;
880 struct mwifiex_types_power_group *pg_tlv = NULL; 878 struct mwifiex_types_power_group *pg_tlv;
881 struct mwifiex_power_group *pg = NULL; 879 struct mwifiex_power_group *pg;
882 u8 *buf = NULL; 880 u8 *buf;
883 u16 dbm = 0; 881 u16 dbm = 0;
884 882
885 if (!power_cfg->is_power_auto) { 883 if (!power_cfg->is_power_auto) {
@@ -897,7 +895,7 @@ int mwifiex_set_tx_power(struct mwifiex_private *priv,
897 if (!buf) { 895 if (!buf) {
898 dev_err(priv->adapter->dev, "%s: failed to alloc cmd buffer\n", 896 dev_err(priv->adapter->dev, "%s: failed to alloc cmd buffer\n",
899 __func__); 897 __func__);
900 return -1; 898 return -ENOMEM;
901 } 899 }
902 900
903 txp_cfg = (struct host_cmd_ds_txpwr_cfg *) buf; 901 txp_cfg = (struct host_cmd_ds_txpwr_cfg *) buf;
@@ -960,7 +958,7 @@ int mwifiex_set_tx_power(struct mwifiex_private *priv,
960 */ 958 */
961int mwifiex_drv_set_power(struct mwifiex_private *priv, u32 *ps_mode) 959int mwifiex_drv_set_power(struct mwifiex_private *priv, u32 *ps_mode)
962{ 960{
963 int ret = 0; 961 int ret;
964 struct mwifiex_adapter *adapter = priv->adapter; 962 struct mwifiex_adapter *adapter = priv->adapter;
965 u16 sub_cmd; 963 u16 sub_cmd;
966 964
@@ -1078,8 +1076,8 @@ static int mwifiex_sec_ioctl_set_wapi_key(struct mwifiex_private *priv,
1078static int mwifiex_sec_ioctl_set_wep_key(struct mwifiex_private *priv, 1076static int mwifiex_sec_ioctl_set_wep_key(struct mwifiex_private *priv,
1079 struct mwifiex_ds_encrypt_key *encrypt_key) 1077 struct mwifiex_ds_encrypt_key *encrypt_key)
1080{ 1078{
1081 int ret = 0; 1079 int ret;
1082 struct mwifiex_wep_key *wep_key = NULL; 1080 struct mwifiex_wep_key *wep_key;
1083 int index; 1081 int index;
1084 1082
1085 if (priv->wep_key_curr_index >= NUM_WEP_KEYS) 1083 if (priv->wep_key_curr_index >= NUM_WEP_KEYS)
@@ -1142,7 +1140,7 @@ static int mwifiex_sec_ioctl_set_wep_key(struct mwifiex_private *priv,
1142static int mwifiex_sec_ioctl_set_wpa_key(struct mwifiex_private *priv, 1140static int mwifiex_sec_ioctl_set_wpa_key(struct mwifiex_private *priv,
1143 struct mwifiex_ds_encrypt_key *encrypt_key) 1141 struct mwifiex_ds_encrypt_key *encrypt_key)
1144{ 1142{
1145 int ret = 0; 1143 int ret;
1146 u8 remove_key = false; 1144 u8 remove_key = false;
1147 struct host_cmd_ds_802_11_key_material *ibss_key; 1145 struct host_cmd_ds_802_11_key_material *ibss_key;
1148 1146
@@ -1209,7 +1207,7 @@ static int
1209mwifiex_sec_ioctl_encrypt_key(struct mwifiex_private *priv, 1207mwifiex_sec_ioctl_encrypt_key(struct mwifiex_private *priv,
1210 struct mwifiex_ds_encrypt_key *encrypt_key) 1208 struct mwifiex_ds_encrypt_key *encrypt_key)
1211{ 1209{
1212 int status = 0; 1210 int status;
1213 1211
1214 if (encrypt_key->is_wapi_key) 1212 if (encrypt_key->is_wapi_key)
1215 status = mwifiex_sec_ioctl_set_wapi_key(priv, encrypt_key); 1213 status = mwifiex_sec_ioctl_set_wapi_key(priv, encrypt_key);
@@ -1252,11 +1250,9 @@ mwifiex_drv_get_driver_version(struct mwifiex_adapter *adapter, char *version,
1252int mwifiex_get_signal_info(struct mwifiex_private *priv, 1250int mwifiex_get_signal_info(struct mwifiex_private *priv,
1253 struct mwifiex_ds_get_signal *signal) 1251 struct mwifiex_ds_get_signal *signal)
1254{ 1252{
1255 struct mwifiex_ds_get_signal info; 1253 int status;
1256 int status = 0;
1257 1254
1258 memset(&info, 0, sizeof(struct mwifiex_ds_get_signal)); 1255 signal->selector = ALL_RSSI_INFO_MASK;
1259 info.selector = ALL_RSSI_INFO_MASK;
1260 1256
1261 /* Signal info can be obtained only if connected */ 1257 /* Signal info can be obtained only if connected */
1262 if (!priv->media_connected) { 1258 if (!priv->media_connected) {
@@ -1269,13 +1265,10 @@ int mwifiex_get_signal_info(struct mwifiex_private *priv,
1269 HostCmd_ACT_GEN_GET, 0, signal); 1265 HostCmd_ACT_GEN_GET, 0, signal);
1270 1266
1271 if (!status) { 1267 if (!status) {
1272 if (signal) 1268 if (signal->selector & BCN_RSSI_AVG_MASK)
1273 memcpy(signal, &info, 1269 priv->w_stats.qual.level = signal->bcn_rssi_avg;
1274 sizeof(struct mwifiex_ds_get_signal)); 1270 if (signal->selector & BCN_NF_AVG_MASK)
1275 if (info.selector & BCN_RSSI_AVG_MASK) 1271 priv->w_stats.qual.noise = signal->bcn_nf_avg;
1276 priv->w_stats.qual.level = info.bcn_rssi_avg;
1277 if (info.selector & BCN_NF_AVG_MASK)
1278 priv->w_stats.qual.noise = info.bcn_nf_avg;
1279 } 1272 }
1280 1273
1281 return status; 1274 return status;
@@ -1334,20 +1327,15 @@ int
1334mwifiex_get_stats_info(struct mwifiex_private *priv, 1327mwifiex_get_stats_info(struct mwifiex_private *priv,
1335 struct mwifiex_ds_get_stats *log) 1328 struct mwifiex_ds_get_stats *log)
1336{ 1329{
1337 int ret = 0; 1330 int ret;
1338 struct mwifiex_ds_get_stats get_log;
1339 1331
1340 memset(&get_log, 0, sizeof(struct mwifiex_ds_get_stats));
1341 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_GET_LOG, 1332 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_GET_LOG,
1342 HostCmd_ACT_GEN_GET, 0, &get_log); 1333 HostCmd_ACT_GEN_GET, 0, log);
1343 1334
1344 if (!ret) { 1335 if (!ret) {
1345 if (log) 1336 priv->w_stats.discard.fragment = log->fcs_error;
1346 memcpy(log, &get_log, sizeof(struct 1337 priv->w_stats.discard.retries = log->retry;
1347 mwifiex_ds_get_stats)); 1338 priv->w_stats.discard.misc = log->ack_failure;
1348 priv->w_stats.discard.fragment = get_log.fcs_error;
1349 priv->w_stats.discard.retries = get_log.retry;
1350 priv->w_stats.discard.misc = get_log.ack_failure;
1351 } 1339 }
1352 1340
1353 return ret; 1341 return ret;
@@ -1425,7 +1413,7 @@ int
1425mwifiex_reg_read(struct mwifiex_private *priv, u32 reg_type, 1413mwifiex_reg_read(struct mwifiex_private *priv, u32 reg_type,
1426 u32 reg_offset, u32 *value) 1414 u32 reg_offset, u32 *value)
1427{ 1415{
1428 int ret = 0; 1416 int ret;
1429 struct mwifiex_ds_reg_rw reg_rw; 1417 struct mwifiex_ds_reg_rw reg_rw;
1430 1418
1431 reg_rw.type = cpu_to_le32(reg_type); 1419 reg_rw.type = cpu_to_le32(reg_type);
@@ -1451,7 +1439,7 @@ int
1451mwifiex_eeprom_read(struct mwifiex_private *priv, u16 offset, u16 bytes, 1439mwifiex_eeprom_read(struct mwifiex_private *priv, u16 offset, u16 bytes,
1452 u8 *value) 1440 u8 *value)
1453{ 1441{
1454 int ret = 0; 1442 int ret;
1455 struct mwifiex_ds_read_eeprom rd_eeprom; 1443 struct mwifiex_ds_read_eeprom rd_eeprom;
1456 1444
1457 rd_eeprom.offset = cpu_to_le16((u16) offset); 1445 rd_eeprom.offset = cpu_to_le16((u16) offset);
diff --git a/drivers/net/wireless/mwifiex/sta_rx.c b/drivers/net/wireless/mwifiex/sta_rx.c
index 8282679e64fd..1fdddece7479 100644
--- a/drivers/net/wireless/mwifiex/sta_rx.c
+++ b/drivers/net/wireless/mwifiex/sta_rx.c
@@ -41,7 +41,7 @@
41int mwifiex_process_rx_packet(struct mwifiex_adapter *adapter, 41int mwifiex_process_rx_packet(struct mwifiex_adapter *adapter,
42 struct sk_buff *skb) 42 struct sk_buff *skb)
43{ 43{
44 int ret = 0; 44 int ret;
45 struct mwifiex_rxinfo *rx_info = MWIFIEX_SKB_RXCB(skb); 45 struct mwifiex_rxinfo *rx_info = MWIFIEX_SKB_RXCB(skb);
46 struct mwifiex_private *priv = adapter->priv[rx_info->bss_index]; 46 struct mwifiex_private *priv = adapter->priv[rx_info->bss_index];
47 struct rx_packet_hdr *rx_pkt_hdr; 47 struct rx_packet_hdr *rx_pkt_hdr;
@@ -123,7 +123,7 @@ int mwifiex_process_sta_rx_packet(struct mwifiex_adapter *adapter,
123 struct mwifiex_rxinfo *rx_info = MWIFIEX_SKB_RXCB(skb); 123 struct mwifiex_rxinfo *rx_info = MWIFIEX_SKB_RXCB(skb);
124 struct rx_packet_hdr *rx_pkt_hdr; 124 struct rx_packet_hdr *rx_pkt_hdr;
125 u8 ta[ETH_ALEN]; 125 u8 ta[ETH_ALEN];
126 u16 rx_pkt_type = 0; 126 u16 rx_pkt_type;
127 struct mwifiex_private *priv = adapter->priv[rx_info->bss_index]; 127 struct mwifiex_private *priv = adapter->priv[rx_info->bss_index];
128 128
129 local_rx_pd = (struct rxpd *) (skb->data); 129 local_rx_pd = (struct rxpd *) (skb->data);
@@ -141,10 +141,28 @@ int mwifiex_process_sta_rx_packet(struct mwifiex_adapter *adapter,
141 dev_kfree_skb_any(skb); 141 dev_kfree_skb_any(skb);
142 return ret; 142 return ret;
143 } 143 }
144
144 if (local_rx_pd->rx_pkt_type == PKT_TYPE_AMSDU) { 145 if (local_rx_pd->rx_pkt_type == PKT_TYPE_AMSDU) {
145 mwifiex_11n_deaggregate_pkt(priv, skb); 146 struct sk_buff_head list;
146 return ret; 147 struct sk_buff *rx_skb;
148
149 __skb_queue_head_init(&list);
150
151 skb_pull(skb, local_rx_pd->rx_pkt_offset);
152 skb_trim(skb, local_rx_pd->rx_pkt_length);
153
154 ieee80211_amsdu_to_8023s(skb, &list, priv->curr_addr,
155 priv->wdev->iftype, 0, false);
156
157 while (!skb_queue_empty(&list)) {
158 rx_skb = __skb_dequeue(&list);
159 ret = mwifiex_recv_packet(adapter, rx_skb);
160 if (ret == -1)
161 dev_err(adapter->dev, "Rx of A-MSDU failed");
162 }
163 return 0;
147 } 164 }
165
148 /* 166 /*
149 * If the packet is not an unicast packet then send the packet 167 * If the packet is not an unicast packet then send the packet
150 * directly to os. Don't pass thru rx reordering 168 * directly to os. Don't pass thru rx reordering
diff --git a/drivers/net/wireless/mwifiex/sta_tx.c b/drivers/net/wireless/mwifiex/sta_tx.c
index 5d37ef160121..fa6221bc9104 100644
--- a/drivers/net/wireless/mwifiex/sta_tx.c
+++ b/drivers/net/wireless/mwifiex/sta_tx.c
@@ -113,8 +113,8 @@ int mwifiex_send_null_packet(struct mwifiex_private *priv, u8 flags)
113/* sizeof(struct txpd) + Interface specific header */ 113/* sizeof(struct txpd) + Interface specific header */
114#define NULL_PACKET_HDR 64 114#define NULL_PACKET_HDR 64
115 u32 data_len = NULL_PACKET_HDR; 115 u32 data_len = NULL_PACKET_HDR;
116 struct sk_buff *skb = NULL; 116 struct sk_buff *skb;
117 int ret = 0; 117 int ret;
118 struct mwifiex_txinfo *tx_info = NULL; 118 struct mwifiex_txinfo *tx_info = NULL;
119 119
120 if (adapter->surprise_removed) 120 if (adapter->surprise_removed)
diff --git a/drivers/net/wireless/mwifiex/txrx.c b/drivers/net/wireless/mwifiex/txrx.c
index ce772e078db8..210120889dfe 100644
--- a/drivers/net/wireless/mwifiex/txrx.c
+++ b/drivers/net/wireless/mwifiex/txrx.c
@@ -68,7 +68,7 @@ int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb,
68{ 68{
69 int ret = -1; 69 int ret = -1;
70 struct mwifiex_adapter *adapter = priv->adapter; 70 struct mwifiex_adapter *adapter = priv->adapter;
71 u8 *head_ptr = NULL; 71 u8 *head_ptr;
72 struct txpd *local_tx_pd = NULL; 72 struct txpd *local_tx_pd = NULL;
73 73
74 head_ptr = (u8 *) mwifiex_process_sta_txpd(priv, skb); 74 head_ptr = (u8 *) mwifiex_process_sta_txpd(priv, skb);
@@ -121,8 +121,8 @@ int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb,
121int mwifiex_write_data_complete(struct mwifiex_adapter *adapter, 121int mwifiex_write_data_complete(struct mwifiex_adapter *adapter,
122 struct sk_buff *skb, int status) 122 struct sk_buff *skb, int status)
123{ 123{
124 struct mwifiex_private *priv = NULL, *tpriv = NULL; 124 struct mwifiex_private *priv, *tpriv;
125 struct mwifiex_txinfo *tx_info = NULL; 125 struct mwifiex_txinfo *tx_info;
126 int i; 126 int i;
127 127
128 if (!skb) 128 if (!skb)
@@ -169,9 +169,9 @@ int mwifiex_recv_packet_complete(struct mwifiex_adapter *adapter,
169 struct sk_buff *skb, int status) 169 struct sk_buff *skb, int status)
170{ 170{
171 struct mwifiex_rxinfo *rx_info = MWIFIEX_SKB_RXCB(skb); 171 struct mwifiex_rxinfo *rx_info = MWIFIEX_SKB_RXCB(skb);
172 struct mwifiex_rxinfo *rx_info_parent = NULL; 172 struct mwifiex_rxinfo *rx_info_parent;
173 struct mwifiex_private *priv; 173 struct mwifiex_private *priv;
174 struct sk_buff *skb_parent = NULL; 174 struct sk_buff *skb_parent;
175 unsigned long flags; 175 unsigned long flags;
176 176
177 priv = adapter->priv[rx_info->bss_index]; 177 priv = adapter->priv[rx_info->bss_index];
diff --git a/drivers/net/wireless/mwifiex/util.c b/drivers/net/wireless/mwifiex/util.c
index 7ab4fb279f8a..d41291529bc0 100644
--- a/drivers/net/wireless/mwifiex/util.c
+++ b/drivers/net/wireless/mwifiex/util.c
@@ -152,8 +152,8 @@ int mwifiex_get_debug_info(struct mwifiex_private *priv,
152 */ 152 */
153int mwifiex_recv_packet(struct mwifiex_adapter *adapter, struct sk_buff *skb) 153int mwifiex_recv_packet(struct mwifiex_adapter *adapter, struct sk_buff *skb)
154{ 154{
155 struct mwifiex_rxinfo *rx_info = NULL; 155 struct mwifiex_rxinfo *rx_info;
156 struct mwifiex_private *priv = NULL; 156 struct mwifiex_private *priv;
157 157
158 if (!skb) 158 if (!skb)
159 return -1; 159 return -1;
@@ -177,31 +177,6 @@ int mwifiex_recv_packet(struct mwifiex_adapter *adapter, struct sk_buff *skb)
177} 177}
178 178
179/* 179/*
180 * Receive packet completion callback handler.
181 *
182 * This function updates the statistics and frees the buffer SKB.
183 */
184int mwifiex_recv_complete(struct mwifiex_adapter *adapter,
185 struct sk_buff *skb, int status)
186{
187 struct mwifiex_private *priv = NULL;
188 struct mwifiex_rxinfo *rx_info = NULL;
189
190 if (!skb)
191 return 0;
192
193 rx_info = MWIFIEX_SKB_RXCB(skb);
194 priv = mwifiex_bss_index_to_priv(adapter, rx_info->bss_index);
195
196 if (priv && (status == -1))
197 priv->stats.rx_dropped++;
198
199 dev_kfree_skb_any(skb);
200
201 return 0;
202}
203
204/*
205 * IOCTL completion callback handler. 180 * IOCTL completion callback handler.
206 * 181 *
207 * This function is called when a pending IOCTL is completed. 182 * This function is called when a pending IOCTL is completed.
diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c
index c009370f309e..faa09e32902e 100644
--- a/drivers/net/wireless/mwifiex/wmm.c
+++ b/drivers/net/wireless/mwifiex/wmm.c
@@ -799,7 +799,7 @@ u8
799mwifiex_wmm_compute_drv_pkt_delay(struct mwifiex_private *priv, 799mwifiex_wmm_compute_drv_pkt_delay(struct mwifiex_private *priv,
800 const struct sk_buff *skb) 800 const struct sk_buff *skb)
801{ 801{
802 u8 ret_val = 0; 802 u8 ret_val;
803 struct timeval out_tstamp, in_tstamp; 803 struct timeval out_tstamp, in_tstamp;
804 u32 queue_delay; 804 u32 queue_delay;
805 805
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index 9f5ecef297e5..32261189bcef 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -784,7 +784,8 @@ static inline void mwl8k_remove_dma_header(struct sk_buff *skb, __le16 qos)
784#define REDUCED_TX_HEADROOM 8 784#define REDUCED_TX_HEADROOM 8
785 785
786static void 786static void
787mwl8k_add_dma_header(struct mwl8k_priv *priv, struct sk_buff *skb, int tail_pad) 787mwl8k_add_dma_header(struct mwl8k_priv *priv, struct sk_buff *skb,
788 int head_pad, int tail_pad)
788{ 789{
789 struct ieee80211_hdr *wh; 790 struct ieee80211_hdr *wh;
790 int hdrlen; 791 int hdrlen;
@@ -816,7 +817,7 @@ mwl8k_add_dma_header(struct mwl8k_priv *priv, struct sk_buff *skb, int tail_pad)
816 skb->truesize += REDUCED_TX_HEADROOM; 817 skb->truesize += REDUCED_TX_HEADROOM;
817 } 818 }
818 819
819 reqd_hdrlen = sizeof(*tr); 820 reqd_hdrlen = sizeof(*tr) + head_pad;
820 821
821 if (hdrlen != reqd_hdrlen) 822 if (hdrlen != reqd_hdrlen)
822 skb_push(skb, reqd_hdrlen - hdrlen); 823 skb_push(skb, reqd_hdrlen - hdrlen);
@@ -845,6 +846,7 @@ static void mwl8k_encapsulate_tx_frame(struct mwl8k_priv *priv,
845 struct ieee80211_tx_info *tx_info; 846 struct ieee80211_tx_info *tx_info;
846 struct ieee80211_key_conf *key_conf; 847 struct ieee80211_key_conf *key_conf;
847 int data_pad; 848 int data_pad;
849 int head_pad = 0;
848 850
849 wh = (struct ieee80211_hdr *)skb->data; 851 wh = (struct ieee80211_hdr *)skb->data;
850 852
@@ -856,9 +858,7 @@ static void mwl8k_encapsulate_tx_frame(struct mwl8k_priv *priv,
856 858
857 /* 859 /*
858 * Make sure the packet header is in the DMA header format (4-address 860 * Make sure the packet header is in the DMA header format (4-address
859 * without QoS), the necessary crypto padding between the header and the 861 * without QoS), and add head & tail padding when HW crypto is enabled.
860 * payload has already been provided by mac80211, but it doesn't add
861 * tail padding when HW crypto is enabled.
862 * 862 *
863 * We have the following trailer padding requirements: 863 * We have the following trailer padding requirements:
864 * - WEP: 4 trailer bytes (ICV) 864 * - WEP: 4 trailer bytes (ICV)
@@ -867,6 +867,7 @@ static void mwl8k_encapsulate_tx_frame(struct mwl8k_priv *priv,
867 */ 867 */
868 data_pad = 0; 868 data_pad = 0;
869 if (key_conf != NULL) { 869 if (key_conf != NULL) {
870 head_pad = key_conf->iv_len;
870 switch (key_conf->cipher) { 871 switch (key_conf->cipher) {
871 case WLAN_CIPHER_SUITE_WEP40: 872 case WLAN_CIPHER_SUITE_WEP40:
872 case WLAN_CIPHER_SUITE_WEP104: 873 case WLAN_CIPHER_SUITE_WEP104:
@@ -880,7 +881,7 @@ static void mwl8k_encapsulate_tx_frame(struct mwl8k_priv *priv,
880 break; 881 break;
881 } 882 }
882 } 883 }
883 mwl8k_add_dma_header(priv, skb, data_pad); 884 mwl8k_add_dma_header(priv, skb, head_pad, data_pad);
884} 885}
885 886
886/* 887/*
@@ -1837,7 +1838,7 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb)
1837 if (priv->ap_fw) 1838 if (priv->ap_fw)
1838 mwl8k_encapsulate_tx_frame(priv, skb); 1839 mwl8k_encapsulate_tx_frame(priv, skb);
1839 else 1840 else
1840 mwl8k_add_dma_header(priv, skb, 0); 1841 mwl8k_add_dma_header(priv, skb, 0, 0);
1841 1842
1842 wh = &((struct mwl8k_dma_data *)skb->data)->wh; 1843 wh = &((struct mwl8k_dma_data *)skb->data)->wh;
1843 1844
@@ -3997,7 +3998,7 @@ static int mwl8k_cmd_encryption_set_key(struct ieee80211_hw *hw,
3997 mwl8k_vif->wep_key_conf[idx].enabled = 1; 3998 mwl8k_vif->wep_key_conf[idx].enabled = 1;
3998 } 3999 }
3999 4000
4000 keymlen = 0; 4001 keymlen = key->keylen;
4001 action = MWL8K_ENCR_SET_KEY; 4002 action = MWL8K_ENCR_SET_KEY;
4002 break; 4003 break;
4003 case WLAN_CIPHER_SUITE_TKIP: 4004 case WLAN_CIPHER_SUITE_TKIP:
@@ -4071,7 +4072,6 @@ static int mwl8k_set_key(struct ieee80211_hw *hw,
4071 addr = sta->addr; 4072 addr = sta->addr;
4072 4073
4073 if (cmd_param == SET_KEY) { 4074 if (cmd_param == SET_KEY) {
4074 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
4075 rc = mwl8k_cmd_encryption_set_key(hw, vif, addr, key); 4075 rc = mwl8k_cmd_encryption_set_key(hw, vif, addr, key);
4076 if (rc) 4076 if (rc)
4077 goto out; 4077 goto out;
diff --git a/drivers/net/wireless/p54/p54pci.c b/drivers/net/wireless/p54/p54pci.c
index 0494d7b102d4..1b753173680f 100644
--- a/drivers/net/wireless/p54/p54pci.c
+++ b/drivers/net/wireless/p54/p54pci.c
@@ -331,10 +331,9 @@ static void p54p_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
331 struct p54p_ring_control *ring_control = priv->ring_control; 331 struct p54p_ring_control *ring_control = priv->ring_control;
332 struct p54p_desc *desc; 332 struct p54p_desc *desc;
333 dma_addr_t mapping; 333 dma_addr_t mapping;
334 u32 device_idx, idx, i; 334 u32 idx, i;
335 335
336 spin_lock_irqsave(&priv->lock, flags); 336 spin_lock_irqsave(&priv->lock, flags);
337 device_idx = le32_to_cpu(ring_control->device_idx[1]);
338 idx = le32_to_cpu(ring_control->host_idx[1]); 337 idx = le32_to_cpu(ring_control->host_idx[1]);
339 i = idx % ARRAY_SIZE(ring_control->tx_data); 338 i = idx % ARRAY_SIZE(ring_control->tx_data);
340 339
diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig
index c45773108283..9def1e5369a1 100644
--- a/drivers/net/wireless/rt2x00/Kconfig
+++ b/drivers/net/wireless/rt2x00/Kconfig
@@ -93,7 +93,7 @@ config RT2800PCI_RT35XX
93 intended for testers and developers. 93 intended for testers and developers.
94 94
95config RT2800PCI_RT53XX 95config RT2800PCI_RT53XX
96 bool "rt2800-pci - Include support for rt53xx devices (EXPERIMENTAL)" 96 bool "rt2800pci - Include support for rt53xx devices (EXPERIMENTAL)"
97 depends on EXPERIMENTAL 97 depends on EXPERIMENTAL
98 default y 98 default y
99 ---help--- 99 ---help---
@@ -163,6 +163,15 @@ config RT2800USB_RT35XX
163 Support for these devices is non-functional at the moment and is 163 Support for these devices is non-functional at the moment and is
164 intended for testers and developers. 164 intended for testers and developers.
165 165
166config RT2800USB_RT53XX
167 bool "rt2800usb - Include support for rt53xx devices (EXPERIMENTAL)"
168 depends on EXPERIMENTAL
169 default y
170 ---help---
171 This adds support for rt53xx wireless chipset family to the
172 rt2800pci driver.
173 Supported chips: RT5370
174
166config RT2800USB_UNKNOWN 175config RT2800USB_UNKNOWN
167 bool "rt2800usb - Include support for unknown (USB) devices" 176 bool "rt2800usb - Include support for unknown (USB) devices"
168 default n 177 default n
diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h
index ce2010952886..f67bc9b31b28 100644
--- a/drivers/net/wireless/rt2x00/rt2800.h
+++ b/drivers/net/wireless/rt2x00/rt2800.h
@@ -51,6 +51,7 @@
51 * RF3320 2.4G 1T1R(RT3350/RT3370/RT3390) 51 * RF3320 2.4G 1T1R(RT3350/RT3370/RT3390)
52 * RF3322 2.4G 2T2R(RT3352/RT3371/RT3372/RT3391/RT3392) 52 * RF3322 2.4G 2T2R(RT3352/RT3371/RT3372/RT3391/RT3392)
53 * RF3853 2.4G/5G 3T3R(RT3883/RT3563/RT3573/RT3593/RT3662) 53 * RF3853 2.4G/5G 3T3R(RT3883/RT3563/RT3573/RT3593/RT3662)
54 * RF5370 2.4G 1T1R
54 * RF5390 2.4G 1T1R 55 * RF5390 2.4G 1T1R
55 */ 56 */
56#define RF2820 0x0001 57#define RF2820 0x0001
@@ -66,6 +67,7 @@
66#define RF3320 0x000b 67#define RF3320 0x000b
67#define RF3322 0x000c 68#define RF3322 0x000c
68#define RF3853 0x000d 69#define RF3853 0x000d
70#define RF5370 0x5370
69#define RF5390 0x5390 71#define RF5390 0x5390
70 72
71/* 73/*
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 790afd3ed946..2a6aa85cc6c9 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -1751,7 +1751,8 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
1751 rt2x00_rf(rt2x00dev, RF3052) || 1751 rt2x00_rf(rt2x00dev, RF3052) ||
1752 rt2x00_rf(rt2x00dev, RF3320)) 1752 rt2x00_rf(rt2x00dev, RF3320))
1753 rt2800_config_channel_rf3xxx(rt2x00dev, conf, rf, info); 1753 rt2800_config_channel_rf3xxx(rt2x00dev, conf, rf, info);
1754 else if (rt2x00_rf(rt2x00dev, RF5390)) 1754 else if (rt2x00_rf(rt2x00dev, RF5370) ||
1755 rt2x00_rf(rt2x00dev, RF5390))
1755 rt2800_config_channel_rf53xx(rt2x00dev, conf, rf, info); 1756 rt2800_config_channel_rf53xx(rt2x00dev, conf, rf, info);
1756 else 1757 else
1757 rt2800_config_channel_rf2xxx(rt2x00dev, conf, rf, info); 1758 rt2800_config_channel_rf2xxx(rt2x00dev, conf, rf, info);
@@ -3686,6 +3687,7 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
3686 !rt2x00_rf(rt2x00dev, RF3022) && 3687 !rt2x00_rf(rt2x00dev, RF3022) &&
3687 !rt2x00_rf(rt2x00dev, RF3052) && 3688 !rt2x00_rf(rt2x00dev, RF3052) &&
3688 !rt2x00_rf(rt2x00dev, RF3320) && 3689 !rt2x00_rf(rt2x00dev, RF3320) &&
3690 !rt2x00_rf(rt2x00dev, RF5370) &&
3689 !rt2x00_rf(rt2x00dev, RF5390)) { 3691 !rt2x00_rf(rt2x00dev, RF5390)) {
3690 ERROR(rt2x00dev, "Invalid RF chipset detected.\n"); 3692 ERROR(rt2x00dev, "Invalid RF chipset detected.\n");
3691 return -ENODEV; 3693 return -ENODEV;
@@ -3988,6 +3990,7 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
3988 rt2x00_rf(rt2x00dev, RF3021) || 3990 rt2x00_rf(rt2x00dev, RF3021) ||
3989 rt2x00_rf(rt2x00dev, RF3022) || 3991 rt2x00_rf(rt2x00dev, RF3022) ||
3990 rt2x00_rf(rt2x00dev, RF3320) || 3992 rt2x00_rf(rt2x00dev, RF3320) ||
3993 rt2x00_rf(rt2x00dev, RF5370) ||
3991 rt2x00_rf(rt2x00dev, RF5390)) { 3994 rt2x00_rf(rt2x00dev, RF5390)) {
3992 spec->num_channels = 14; 3995 spec->num_channels = 14;
3993 spec->channels = rf_vals_3x; 3996 spec->channels = rf_vals_3x;
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index 0eb44cf2f44a..ba82c972703a 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -1000,6 +1000,14 @@ static struct usb_device_id rt2800usb_device_table[] = {
1000 /* Zinwell */ 1000 /* Zinwell */
1001 { USB_DEVICE(0x5a57, 0x0284) }, 1001 { USB_DEVICE(0x5a57, 0x0284) },
1002#endif 1002#endif
1003#ifdef CONFIG_RT2800USB_RT53XX
1004 /* Azurewave */
1005 { USB_DEVICE(0x13d3, 0x3329) },
1006 { USB_DEVICE(0x13d3, 0x3365) },
1007 /* Ralink */
1008 { USB_DEVICE(0x148f, 0x5370) },
1009 { USB_DEVICE(0x148f, 0x5372) },
1010#endif
1003#ifdef CONFIG_RT2800USB_UNKNOWN 1011#ifdef CONFIG_RT2800USB_UNKNOWN
1004 /* 1012 /*
1005 * Unclear what kind of devices these are (they aren't supported by the 1013 * Unclear what kind of devices these are (they aren't supported by the
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 2eb5196977fd..c018d67aab8e 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -1159,9 +1159,9 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev)
1159 /* 1159 /*
1160 * Stop all work. 1160 * Stop all work.
1161 */ 1161 */
1162 del_timer_sync(&rt2x00dev->txstatus_timer);
1163 cancel_work_sync(&rt2x00dev->intf_work); 1162 cancel_work_sync(&rt2x00dev->intf_work);
1164 if (rt2x00_is_usb(rt2x00dev)) { 1163 if (rt2x00_is_usb(rt2x00dev)) {
1164 del_timer_sync(&rt2x00dev->txstatus_timer);
1165 cancel_work_sync(&rt2x00dev->rxdone_work); 1165 cancel_work_sync(&rt2x00dev->rxdone_work);
1166 cancel_work_sync(&rt2x00dev->txdone_work); 1166 cancel_work_sync(&rt2x00dev->txdone_work);
1167 } 1167 }
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c
index 39e1052123e3..8f90f6268077 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.c
@@ -298,7 +298,7 @@ static bool rt2x00usb_kick_tx_entry(struct queue_entry *entry, void* data)
298 298
299 if (!test_and_clear_bit(ENTRY_DATA_PENDING, &entry->flags) || 299 if (!test_and_clear_bit(ENTRY_DATA_PENDING, &entry->flags) ||
300 test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags)) 300 test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))
301 return true; 301 return false;
302 302
303 /* 303 /*
304 * USB devices cannot blindly pass the skb->len as the 304 * USB devices cannot blindly pass the skb->len as the
@@ -392,7 +392,7 @@ static bool rt2x00usb_kick_rx_entry(struct queue_entry *entry, void* data)
392 392
393 if (test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) || 393 if (test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) ||
394 test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags)) 394 test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))
395 return true; 395 return false;
396 396
397 rt2x00lib_dmastart(entry); 397 rt2x00lib_dmastart(entry);
398 398
@@ -447,7 +447,7 @@ static bool rt2x00usb_flush_entry(struct queue_entry *entry, void* data)
447 struct queue_entry_priv_usb_bcn *bcn_priv = entry->priv_data; 447 struct queue_entry_priv_usb_bcn *bcn_priv = entry->priv_data;
448 448
449 if (!test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) 449 if (!test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
450 return true; 450 return false;
451 451
452 usb_kill_urb(entry_priv->urb); 452 usb_kill_urb(entry_priv->urb);
453 453
diff --git a/drivers/net/wireless/rtlwifi/Kconfig b/drivers/net/wireless/rtlwifi/Kconfig
index ce49e0ce7cad..5aee8b22d74e 100644
--- a/drivers/net/wireless/rtlwifi/Kconfig
+++ b/drivers/net/wireless/rtlwifi/Kconfig
@@ -10,6 +10,17 @@ config RTL8192CE
10 10
11 If you choose to build it as a module, it will be called rtl8192ce 11 If you choose to build it as a module, it will be called rtl8192ce
12 12
13config RTL8192SE
14 tristate "Realtek RTL8192SE/RTL8191SE PCIe Wireless Network Adapter"
15 depends on MAC80211 && EXPERIMENTAL
16 select FW_LOADER
17 select RTLWIFI
18 ---help---
19 This is the driver for Realtek RTL8192SE/RTL8191SE 802.11n PCIe
20 wireless network adapters.
21
22 If you choose to build it as a module, it will be called rtl8192se
23
13config RTL8192CU 24config RTL8192CU
14 tristate "Realtek RTL8192CU/RTL8188CU USB Wireless Network Adapter" 25 tristate "Realtek RTL8192CU/RTL8188CU USB Wireless Network Adapter"
15 depends on MAC80211 && USB && EXPERIMENTAL 26 depends on MAC80211 && USB && EXPERIMENTAL
@@ -24,10 +35,10 @@ config RTL8192CU
24 35
25config RTLWIFI 36config RTLWIFI
26 tristate 37 tristate
27 depends on RTL8192CE || RTL8192CU 38 depends on RTL8192CE || RTL8192CU || RTL8192SE
28 default m 39 default m
29 40
30config RTL8192C_COMMON 41config RTL8192C_COMMON
31 tristate 42 tristate
32 depends on RTL8192CE || RTL8192CU 43 depends on RTL8192CE || RTL8192CU || RTL8192SE
33 default m 44 default m
diff --git a/drivers/net/wireless/rtlwifi/Makefile b/drivers/net/wireless/rtlwifi/Makefile
index ec9393f24799..7acce83c3785 100644
--- a/drivers/net/wireless/rtlwifi/Makefile
+++ b/drivers/net/wireless/rtlwifi/Makefile
@@ -22,5 +22,6 @@ endif
22obj-$(CONFIG_RTL8192C_COMMON) += rtl8192c/ 22obj-$(CONFIG_RTL8192C_COMMON) += rtl8192c/
23obj-$(CONFIG_RTL8192CE) += rtl8192ce/ 23obj-$(CONFIG_RTL8192CE) += rtl8192ce/
24obj-$(CONFIG_RTL8192CU) += rtl8192cu/ 24obj-$(CONFIG_RTL8192CU) += rtl8192cu/
25obj-$(CONFIG_RTL8192SE) += rtl8192se/
25 26
26ccflags-y += -D__CHECK_ENDIAN__ 27ccflags-y += -D__CHECK_ENDIAN__
diff --git a/drivers/net/wireless/rtlwifi/efuse.c b/drivers/net/wireless/rtlwifi/efuse.c
index 510d42edb8ca..50de6f5d8a56 100644
--- a/drivers/net/wireless/rtlwifi/efuse.c
+++ b/drivers/net/wireless/rtlwifi/efuse.c
@@ -235,7 +235,7 @@ void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf)
235{ 235{
236 struct rtl_priv *rtlpriv = rtl_priv(hw); 236 struct rtl_priv *rtlpriv = rtl_priv(hw);
237 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 237 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
238 u8 efuse_tbl[HWSET_MAX_SIZE]; 238 u8 *efuse_tbl;
239 u8 rtemp8[1]; 239 u8 rtemp8[1];
240 u16 efuse_addr = 0; 240 u16 efuse_addr = 0;
241 u8 offset, wren; 241 u8 offset, wren;
@@ -245,7 +245,7 @@ void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf)
245 rtlpriv->cfg->maps[EFUSE_MAX_SECTION_MAP]; 245 rtlpriv->cfg->maps[EFUSE_MAX_SECTION_MAP];
246 const u32 efuse_len = 246 const u32 efuse_len =
247 rtlpriv->cfg->maps[EFUSE_REAL_CONTENT_SIZE]; 247 rtlpriv->cfg->maps[EFUSE_REAL_CONTENT_SIZE];
248 u16 efuse_word[EFUSE_MAX_SECTION][EFUSE_MAX_WORD_UNIT]; 248 u16 **efuse_word;
249 u16 efuse_utilized = 0; 249 u16 efuse_utilized = 0;
250 u8 efuse_usage; 250 u8 efuse_usage;
251 251
@@ -256,9 +256,24 @@ void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf)
256 return; 256 return;
257 } 257 }
258 258
259 /* allocate memory for efuse_tbl and efuse_word */
260 efuse_tbl = kmalloc(rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE] *
261 sizeof(u8), GFP_ATOMIC);
262 if (!efuse_tbl)
263 return;
264 efuse_word = kmalloc(EFUSE_MAX_WORD_UNIT * sizeof(u16 *), GFP_ATOMIC);
265 if (!efuse_word)
266 goto done;
267 for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {
268 efuse_word[i] = kmalloc(efuse_max_section * sizeof(u16),
269 GFP_ATOMIC);
270 if (!efuse_word[i])
271 goto done;
272 }
273
259 for (i = 0; i < efuse_max_section; i++) 274 for (i = 0; i < efuse_max_section; i++)
260 for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++) 275 for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++)
261 efuse_word[i][j] = 0xFFFF; 276 efuse_word[j][i] = 0xFFFF;
262 277
263 read_efuse_byte(hw, efuse_addr, rtemp8); 278 read_efuse_byte(hw, efuse_addr, rtemp8);
264 if (*rtemp8 != 0xFF) { 279 if (*rtemp8 != 0xFF) {
@@ -285,7 +300,8 @@ void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf)
285 read_efuse_byte(hw, efuse_addr, rtemp8); 300 read_efuse_byte(hw, efuse_addr, rtemp8);
286 efuse_addr++; 301 efuse_addr++;
287 efuse_utilized++; 302 efuse_utilized++;
288 efuse_word[offset][i] = (*rtemp8 & 0xff); 303 efuse_word[i][offset] =
304 (*rtemp8 & 0xff);
289 305
290 if (efuse_addr >= efuse_len) 306 if (efuse_addr >= efuse_len)
291 break; 307 break;
@@ -297,7 +313,7 @@ void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf)
297 read_efuse_byte(hw, efuse_addr, rtemp8); 313 read_efuse_byte(hw, efuse_addr, rtemp8);
298 efuse_addr++; 314 efuse_addr++;
299 efuse_utilized++; 315 efuse_utilized++;
300 efuse_word[offset][i] |= 316 efuse_word[i][offset] |=
301 (((u16)*rtemp8 << 8) & 0xff00); 317 (((u16)*rtemp8 << 8) & 0xff00);
302 318
303 if (efuse_addr >= efuse_len) 319 if (efuse_addr >= efuse_len)
@@ -320,9 +336,9 @@ void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf)
320 for (i = 0; i < efuse_max_section; i++) { 336 for (i = 0; i < efuse_max_section; i++) {
321 for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++) { 337 for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++) {
322 efuse_tbl[(i * 8) + (j * 2)] = 338 efuse_tbl[(i * 8) + (j * 2)] =
323 (efuse_word[i][j] & 0xff); 339 (efuse_word[j][i] & 0xff);
324 efuse_tbl[(i * 8) + ((j * 2) + 1)] = 340 efuse_tbl[(i * 8) + ((j * 2) + 1)] =
325 ((efuse_word[i][j] >> 8) & 0xff); 341 ((efuse_word[j][i] >> 8) & 0xff);
326 } 342 }
327 } 343 }
328 344
@@ -336,6 +352,11 @@ void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf)
336 (u8 *)&efuse_utilized); 352 (u8 *)&efuse_utilized);
337 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_EFUSE_USAGE, 353 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_EFUSE_USAGE,
338 (u8 *)&efuse_usage); 354 (u8 *)&efuse_usage);
355done:
356 for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++)
357 kfree(efuse_word[i]);
358 kfree(efuse_word);
359 kfree(efuse_tbl);
339} 360}
340 361
341bool efuse_shadow_update_chk(struct ieee80211_hw *hw) 362bool efuse_shadow_update_chk(struct ieee80211_hw *hw)
diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c
index 3550c9fb96e5..a40952845436 100644
--- a/drivers/net/wireless/rtlwifi/pci.c
+++ b/drivers/net/wireless/rtlwifi/pci.c
@@ -1611,6 +1611,7 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev,
1611 u16 irqline; 1611 u16 irqline;
1612 u8 tmp; 1612 u8 tmp;
1613 1613
1614 pcipriv->ndis_adapter.pcibridge_vendor = PCI_BRIDGE_VENDOR_UNKNOWN;
1614 venderid = pdev->vendor; 1615 venderid = pdev->vendor;
1615 deviceid = pdev->device; 1616 deviceid = pdev->device;
1616 pci_read_config_byte(pdev, 0x8, &revisionid); 1617 pci_read_config_byte(pdev, 0x8, &revisionid);
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c
index 79c98f62175f..3a92ba3c4a1e 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c
@@ -372,7 +372,7 @@ static void _rtl_rx_process(struct ieee80211_hw *hw, struct sk_buff *skb)
372 __le16 fc; 372 __le16 fc;
373 struct ieee80211_hdr *hdr; 373 struct ieee80211_hdr *hdr;
374 374
375 memset(rx_status, 0, sizeof(rx_status)); 375 memset(rx_status, 0, sizeof(*rx_status));
376 rxdesc = skb->data; 376 rxdesc = skb->data;
377 skb_len = skb->len; 377 skb_len = skb->len;
378 drvinfo_len = (GET_RX_DESC_DRVINFO_SIZE(rxdesc) * RTL_RX_DRV_INFO_UNIT); 378 drvinfo_len = (GET_RX_DESC_DRVINFO_SIZE(rxdesc) * RTL_RX_DRV_INFO_UNIT);
@@ -434,7 +434,7 @@ static void _rtl_rx_process(struct ieee80211_hw *hw, struct sk_buff *skb)
434 "0x%02X\n", fc, (u32)hdr->addr1[0], (u32)hdr->addr1[1], 434 "0x%02X\n", fc, (u32)hdr->addr1[0], (u32)hdr->addr1[1],
435 (u32)hdr->addr1[2], (u32)hdr->addr1[3], (u32)hdr->addr1[4], 435 (u32)hdr->addr1[2], (u32)hdr->addr1[3], (u32)hdr->addr1[4],
436 (u32)hdr->addr1[5])); 436 (u32)hdr->addr1[5]));
437 memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status)); 437 memcpy(IEEE80211_SKB_RXCB(skb), rx_status, sizeof(*rx_status));
438 ieee80211_rx_irqsafe(hw, skb); 438 ieee80211_rx_irqsafe(hw, skb);
439} 439}
440 440
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/Makefile b/drivers/net/wireless/rtlwifi/rtl8192se/Makefile
new file mode 100644
index 000000000000..b7eb13819cbc
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/Makefile
@@ -0,0 +1,15 @@
1rtl8192se-objs := \
2 dm.o \
3 fw.o \
4 hw.o \
5 led.o \
6 phy.o \
7 rf.o \
8 sw.o \
9 table.o \
10 trx.o
11
12obj-$(CONFIG_RTL8192SE) += rtl8192se.o
13
14ccflags-y += -D__CHECK_ENDIAN__
15
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/def.h b/drivers/net/wireless/rtlwifi/rtl8192se/def.h
new file mode 100644
index 000000000000..69828f2b3fab
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/def.h
@@ -0,0 +1,598 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2010 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29#ifndef __REALTEK_92S_DEF_H__
30#define __REALTEK_92S_DEF_H__
31
32#define RX_MPDU_QUEUE 0
33#define RX_CMD_QUEUE 1
34#define RX_MAX_QUEUE 2
35
36#define DESC92S_RATE1M 0x00
37#define DESC92S_RATE2M 0x01
38#define DESC92S_RATE5_5M 0x02
39#define DESC92S_RATE11M 0x03
40#define DESC92S_RATE6M 0x04
41#define DESC92S_RATE9M 0x05
42#define DESC92S_RATE12M 0x06
43#define DESC92S_RATE18M 0x07
44#define DESC92S_RATE24M 0x08
45#define DESC92S_RATE36M 0x09
46#define DESC92S_RATE48M 0x0a
47#define DESC92S_RATE54M 0x0b
48#define DESC92S_RATEMCS0 0x0c
49#define DESC92S_RATEMCS1 0x0d
50#define DESC92S_RATEMCS2 0x0e
51#define DESC92S_RATEMCS3 0x0f
52#define DESC92S_RATEMCS4 0x10
53#define DESC92S_RATEMCS5 0x11
54#define DESC92S_RATEMCS6 0x12
55#define DESC92S_RATEMCS7 0x13
56#define DESC92S_RATEMCS8 0x14
57#define DESC92S_RATEMCS9 0x15
58#define DESC92S_RATEMCS10 0x16
59#define DESC92S_RATEMCS11 0x17
60#define DESC92S_RATEMCS12 0x18
61#define DESC92S_RATEMCS13 0x19
62#define DESC92S_RATEMCS14 0x1a
63#define DESC92S_RATEMCS15 0x1b
64#define DESC92S_RATEMCS15_SG 0x1c
65#define DESC92S_RATEMCS32 0x20
66
67#define SHORT_SLOT_TIME 9
68#define NON_SHORT_SLOT_TIME 20
69
70/* Rx smooth factor */
71#define RX_SMOOTH_FACTOR 20
72
73/* Queue Select Value in TxDesc */
74#define QSLT_BK 0x2
75#define QSLT_BE 0x0
76#define QSLT_VI 0x5
77#define QSLT_VO 0x6
78#define QSLT_BEACON 0x10
79#define QSLT_HIGH 0x11
80#define QSLT_MGNT 0x12
81#define QSLT_CMD 0x13
82
83#define PHY_RSSI_SLID_WIN_MAX 100
84#define PHY_LINKQUALITY_SLID_WIN_MAX 20
85#define PHY_BEACON_RSSI_SLID_WIN_MAX 10
86
87/* Tx Desc */
88#define TX_DESC_SIZE_RTL8192S (16 * 4)
89#define TX_CMDDESC_SIZE_RTL8192S (16 * 4)
90
91/* Define a macro that takes a le32 word, converts it to host ordering,
92 * right shifts by a specified count, creates a mask of the specified
93 * bit count, and extracts that number of bits.
94 */
95
96#define SHIFT_AND_MASK_LE(__pdesc, __shift, __mask) \
97 ((le32_to_cpu(*(((__le32 *)(__pdesc)))) >> (__shift)) & \
98 BIT_LEN_MASK_32(__mask))
99
100/* Define a macro that clears a bit field in an le32 word and
101 * sets the specified value into that bit field. The resulting
102 * value remains in le32 ordering; however, it is properly converted
103 * to host ordering for the clear and set operations before conversion
104 * back to le32.
105 */
106
107#define SET_BITS_OFFSET_LE(__pdesc, __shift, __len, __val) \
108 (*(__le32 *)(__pdesc) = \
109 (cpu_to_le32((le32_to_cpu(*((__le32 *)(__pdesc))) & \
110 (~(BIT_OFFSET_LEN_MASK_32((__shift), __len)))) | \
111 (((u32)(__val) & BIT_LEN_MASK_32(__len)) << (__shift)))));
112
113/* macros to read/write various fields in RX or TX descriptors */
114
115/* Dword 0 */
116#define SET_TX_DESC_PKT_SIZE(__pdesc, __val) \
117 SET_BITS_OFFSET_LE(__pdesc, 0, 16, __val)
118#define SET_TX_DESC_OFFSET(__pdesc, __val) \
119 SET_BITS_OFFSET_LE(__pdesc, 16, 8, __val)
120#define SET_TX_DESC_TYPE(__pdesc, __val) \
121 SET_BITS_OFFSET_LE(__pdesc, 24, 2, __val)
122#define SET_TX_DESC_LAST_SEG(__pdesc, __val) \
123 SET_BITS_OFFSET_LE(__pdesc, 26, 1, __val)
124#define SET_TX_DESC_FIRST_SEG(__pdesc, __val) \
125 SET_BITS_OFFSET_LE(__pdesc, 27, 1, __val)
126#define SET_TX_DESC_LINIP(__pdesc, __val) \
127 SET_BITS_OFFSET_LE(__pdesc, 28, 1, __val)
128#define SET_TX_DESC_AMSDU(__pdesc, __val) \
129 SET_BITS_OFFSET_LE(__pdesc, 29, 1, __val)
130#define SET_TX_DESC_GREEN_FIELD(__pdesc, __val) \
131 SET_BITS_OFFSET_LE(__pdesc, 30, 1, __val)
132#define SET_TX_DESC_OWN(__pdesc, __val) \
133 SET_BITS_OFFSET_LE(__pdesc, 31, 1, __val)
134
135#define GET_TX_DESC_OWN(__pdesc) \
136 SHIFT_AND_MASK_LE(__pdesc, 31, 1)
137
138/* Dword 1 */
139#define SET_TX_DESC_MACID(__pdesc, __val) \
140 SET_BITS_OFFSET_LE(__pdesc + 4, 0, 5, __val)
141#define SET_TX_DESC_MORE_DATA(__pdesc, __val) \
142 SET_BITS_OFFSET_LE(__pdesc + 4, 5, 1, __val)
143#define SET_TX_DESC_MORE_FRAG(__pdesc, __val) \
144 SET_BITS_OFFSET_LE(__pdesc + 4, 6, 1, __val)
145#define SET_TX_DESC_PIFS(__pdesc, __val) \
146 SET_BITS_OFFSET_LE(__pdesc + 4, 7, 1, __val)
147#define SET_TX_DESC_QUEUE_SEL(__pdesc, __val) \
148 SET_BITS_OFFSET_LE(__pdesc + 4, 8, 5, __val)
149#define SET_TX_DESC_ACK_POLICY(__pdesc, __val) \
150 SET_BITS_OFFSET_LE(__pdesc + 4, 13, 2, __val)
151#define SET_TX_DESC_NO_ACM(__pdesc, __val) \
152 SET_BITS_OFFSET_LE(__pdesc + 4, 15, 1, __val)
153#define SET_TX_DESC_NON_QOS(__pdesc, __val) \
154 SET_BITS_OFFSET_LE(__pdesc + 4, 16, 1, __val)
155#define SET_TX_DESC_KEY_ID(__pdesc, __val) \
156 SET_BITS_OFFSET_LE(__pdesc + 4, 17, 2, __val)
157#define SET_TX_DESC_OUI(__pdesc, __val) \
158 SET_BITS_OFFSET_LE(__pdesc + 4, 19, 1, __val)
159#define SET_TX_DESC_PKT_TYPE(__pdesc, __val) \
160 SET_BITS_OFFSET_LE(__pdesc + 4, 20, 1, __val)
161#define SET_TX_DESC_EN_DESC_ID(__pdesc, __val) \
162 SET_BITS_OFFSET_LE(__pdesc + 4, 21, 1, __val)
163#define SET_TX_DESC_SEC_TYPE(__pdesc, __val) \
164 SET_BITS_OFFSET_LE(__pdesc + 4, 22, 2, __val)
165#define SET_TX_DESC_WDS(__pdesc, __val) \
166 SET_BITS_OFFSET_LE(__pdesc + 4, 24, 1, __val)
167#define SET_TX_DESC_HTC(__pdesc, __val) \
168 SET_BITS_OFFSET_LE(__pdesc + 4, 25, 1, __val)
169#define SET_TX_DESC_PKT_OFFSET(__pdesc, __val) \
170 SET_BITS_OFFSET_LE(__pdesc + 4, 26, 5, __val)
171#define SET_TX_DESC_HWPC(__pdesc, __val) \
172 SET_BITS_OFFSET_LE(__pdesc + 4, 27, 1, __val)
173
174/* Dword 2 */
175#define SET_TX_DESC_DATA_RETRY_LIMIT(__pdesc, __val) \
176 SET_BITS_OFFSET_LE(__pdesc + 8, 0, 6, __val)
177#define SET_TX_DESC_RETRY_LIMIT_ENABLE(__pdesc, __val) \
178 SET_BITS_OFFSET_LE(__pdesc + 8, 6, 1, __val)
179#define SET_TX_DESC_TSFL(__pdesc, __val) \
180 SET_BITS_OFFSET_LE(__pdesc + 8, 7, 5, __val)
181#define SET_TX_DESC_RTS_RETRY_COUNT(__pdesc, __val) \
182 SET_BITS_OFFSET_LE(__pdesc + 8, 12, 6, __val)
183#define SET_TX_DESC_DATA_RETRY_COUNT(__pdesc, __val) \
184 SET_BITS_OFFSET_LE(__pdesc + 8, 18, 6, __val)
185#define SET_TX_DESC_RSVD_MACID(__pdesc, __val) \
186 SET_BITS_OFFSET_LE(((__pdesc) + 8), 24, 5, __val)
187#define SET_TX_DESC_AGG_ENABLE(__pdesc, __val) \
188 SET_BITS_OFFSET_LE(__pdesc + 8, 29, 1, __val)
189#define SET_TX_DESC_AGG_BREAK(__pdesc, __val) \
190 SET_BITS_OFFSET_LE(__pdesc + 8, 30, 1, __val)
191#define SET_TX_DESC_OWN_MAC(__pdesc, __val) \
192 SET_BITS_OFFSET_LE(__pdesc + 8, 31, 1, __val)
193
194/* Dword 3 */
195#define SET_TX_DESC_NEXT_HEAP_PAGE(__pdesc, __val) \
196 SET_BITS_OFFSET_LE(__pdesc + 12, 0, 8, __val)
197#define SET_TX_DESC_TAIL_PAGE(__pdesc, __val) \
198 SET_BITS_OFFSET_LE(__pdesc + 12, 8, 8, __val)
199#define SET_TX_DESC_SEQ(__pdesc, __val) \
200 SET_BITS_OFFSET_LE(__pdesc + 12, 16, 12, __val)
201#define SET_TX_DESC_FRAG(__pdesc, __val) \
202 SET_BITS_OFFSET_LE(__pdesc + 12, 28, 4, __val)
203
204/* Dword 4 */
205#define SET_TX_DESC_RTS_RATE(__pdesc, __val) \
206 SET_BITS_OFFSET_LE(__pdesc + 16, 0, 6, __val)
207#define SET_TX_DESC_DISABLE_RTS_FB(__pdesc, __val) \
208 SET_BITS_OFFSET_LE(__pdesc + 16, 6, 1, __val)
209#define SET_TX_DESC_RTS_RATE_FB_LIMIT(__pdesc, __val) \
210 SET_BITS_OFFSET_LE(__pdesc + 16, 7, 4, __val)
211#define SET_TX_DESC_CTS_ENABLE(__pdesc, __val) \
212 SET_BITS_OFFSET_LE(__pdesc + 16, 11, 1, __val)
213#define SET_TX_DESC_RTS_ENABLE(__pdesc, __val) \
214 SET_BITS_OFFSET_LE(__pdesc + 16, 12, 1, __val)
215#define SET_TX_DESC_RA_BRSR_ID(__pdesc, __val) \
216 SET_BITS_OFFSET_LE(__pdesc + 16, 13, 3, __val)
217#define SET_TX_DESC_TXHT(__pdesc, __val) \
218 SET_BITS_OFFSET_LE(__pdesc + 16, 16, 1, __val)
219#define SET_TX_DESC_TX_SHORT(__pdesc, __val) \
220 SET_BITS_OFFSET_LE(__pdesc + 16, 17, 1, __val)
221#define SET_TX_DESC_TX_BANDWIDTH(__pdesc, __val) \
222 SET_BITS_OFFSET_LE(__pdesc + 16, 18, 1, __val)
223#define SET_TX_DESC_TX_SUB_CARRIER(__pdesc, __val) \
224 SET_BITS_OFFSET_LE(__pdesc + 16, 19, 2, __val)
225#define SET_TX_DESC_TX_STBC(__pdesc, __val) \
226 SET_BITS_OFFSET_LE(__pdesc + 16, 21, 2, __val)
227#define SET_TX_DESC_TX_REVERSE_DIRECTION(__pdesc, __val) \
228 SET_BITS_OFFSET_LE(__pdesc + 16, 23, 1, __val)
229#define SET_TX_DESC_RTS_HT(__pdesc, __val) \
230 SET_BITS_OFFSET_LE(__pdesc + 16, 24, 1, __val)
231#define SET_TX_DESC_RTS_SHORT(__pdesc, __val) \
232 SET_BITS_OFFSET_LE(__pdesc + 16, 25, 1, __val)
233#define SET_TX_DESC_RTS_BANDWIDTH(__pdesc, __val) \
234 SET_BITS_OFFSET_LE(__pdesc + 16, 26, 1, __val)
235#define SET_TX_DESC_RTS_SUB_CARRIER(__pdesc, __val) \
236 SET_BITS_OFFSET_LE(__pdesc + 16, 27, 2, __val)
237#define SET_TX_DESC_RTS_STBC(__pdesc, __val) \
238 SET_BITS_OFFSET_LE(__pdesc + 16, 29, 2, __val)
239#define SET_TX_DESC_USER_RATE(__pdesc, __val) \
240 SET_BITS_OFFSET_LE(__pdesc + 16, 31, 1, __val)
241
242/* Dword 5 */
243#define SET_TX_DESC_PACKET_ID(__pdesc, __val) \
244 SET_BITS_OFFSET_LE(__pdesc + 20, 0, 9, __val)
245#define SET_TX_DESC_TX_RATE(__pdesc, __val) \
246 SET_BITS_OFFSET_LE(__pdesc + 20, 9, 6, __val)
247#define SET_TX_DESC_DISABLE_FB(__pdesc, __val) \
248 SET_BITS_OFFSET_LE(__pdesc + 20, 15, 1, __val)
249#define SET_TX_DESC_DATA_RATE_FB_LIMIT(__pdesc, __val) \
250 SET_BITS_OFFSET_LE(__pdesc + 20, 16, 5, __val)
251#define SET_TX_DESC_TX_AGC(__pdesc, __val) \
252 SET_BITS_OFFSET_LE(__pdesc + 20, 21, 11, __val)
253
254/* Dword 6 */
255#define SET_TX_DESC_IP_CHECK_SUM(__pdesc, __val) \
256 SET_BITS_OFFSET_LE(__pdesc + 24, 0, 16, __val)
257#define SET_TX_DESC_TCP_CHECK_SUM(__pdesc, __val) \
258 SET_BITS_OFFSET_LE(__pdesc + 24, 16, 16, __val)
259
260/* Dword 7 */
261#define SET_TX_DESC_TX_BUFFER_SIZE(__pdesc, __val) \
262 SET_BITS_OFFSET_LE(__pdesc + 28, 0, 16, __val)
263#define SET_TX_DESC_IP_HEADER_OFFSET(__pdesc, __val) \
264 SET_BITS_OFFSET_LE(__pdesc + 28, 16, 8, __val)
265#define SET_TX_DESC_TCP_ENABLE(__pdesc, __val) \
266 SET_BITS_OFFSET_LE(__pdesc + 28, 31, 1, __val)
267
268/* Dword 8 */
269#define SET_TX_DESC_TX_BUFFER_ADDRESS(__pdesc, __val) \
270 SET_BITS_OFFSET_LE(__pdesc + 32, 0, 32, __val)
271#define GET_TX_DESC_TX_BUFFER_ADDRESS(__pdesc) \
272 SHIFT_AND_MASK_LE(__pdesc + 32, 0, 32)
273
274/* Dword 9 */
275#define SET_TX_DESC_NEXT_DESC_ADDRESS(__pdesc, __val) \
276 SET_BITS_OFFSET_LE(__pdesc + 36, 0, 32, __val)
277
278/* Because the PCI Tx descriptors are chaied at the
279 * initialization and all the NextDescAddresses in
280 * these descriptors cannot not be cleared (,or
281 * driver/HW cannot find the next descriptor), the
282 * offset 36 (NextDescAddresses) is reserved when
283 * the desc is cleared. */
284#define TX_DESC_NEXT_DESC_OFFSET 36
285#define CLEAR_PCI_TX_DESC_CONTENT(__pdesc, _size) \
286do { \
287 if (_size > TX_DESC_NEXT_DESC_OFFSET) \
288 memset(__pdesc, 0, TX_DESC_NEXT_DESC_OFFSET); \
289 else \
290 memset(__pdesc, 0, _size); \
291} while (0);
292
293/* Rx Desc */
294#define RX_STATUS_DESC_SIZE 24
295#define RX_DRV_INFO_SIZE_UNIT 8
296
297/* DWORD 0 */
298#define SET_RX_STATUS_DESC_PKT_LEN(__pdesc, __val) \
299 SET_BITS_OFFSET_LE(__pdesc, 0, 14, __val)
300#define SET_RX_STATUS_DESC_CRC32(__pdesc, __val) \
301 SET_BITS_OFFSET_LE(__pdesc, 14, 1, __val)
302#define SET_RX_STATUS_DESC_ICV(__pdesc, __val) \
303 SET_BITS_OFFSET_LE(__pdesc, 15, 1, __val)
304#define SET_RX_STATUS_DESC_DRVINFO_SIZE(__pdesc, __val) \
305 SET_BITS_OFFSET_LE(__pdesc, 16, 4, __val)
306#define SET_RX_STATUS_DESC_SECURITY(__pdesc, __val) \
307 SET_BITS_OFFSET_LE(__pdesc, 20, 3, __val)
308#define SET_RX_STATUS_DESC_QOS(__pdesc, __val) \
309 SET_BITS_OFFSET_LE(__pdesc, 23, 1, __val)
310#define SET_RX_STATUS_DESC_SHIFT(__pdesc, __val) \
311 SET_BITS_OFFSET_LE(__pdesc, 24, 2, __val)
312#define SET_RX_STATUS_DESC_PHY_STATUS(__pdesc, __val) \
313 SET_BITS_OFFSET_LE(__pdesc, 26, 1, __val)
314#define SET_RX_STATUS_DESC_SWDEC(__pdesc, __val) \
315 SET_BITS_OFFSET_LE(__pdesc, 27, 1, __val)
316#define SET_RX_STATUS_DESC_LAST_SEG(__pdesc, __val) \
317 SET_BITS_OFFSET_LE(__pdesc, 28, 1, __val)
318#define SET_RX_STATUS_DESC_FIRST_SEG(__pdesc, __val) \
319 SET_BITS_OFFSET_LE(__pdesc, 29, 1, __val)
320#define SET_RX_STATUS_DESC_EOR(__pdesc, __val) \
321 SET_BITS_OFFSET_LE(__pdesc, 30, 1, __val)
322#define SET_RX_STATUS_DESC_OWN(__pdesc, __val) \
323 SET_BITS_OFFSET_LE(__pdesc, 31, 1, __val)
324
325#define GET_RX_STATUS_DESC_PKT_LEN(__pdesc) \
326 SHIFT_AND_MASK_LE(__pdesc, 0, 14)
327#define GET_RX_STATUS_DESC_CRC32(__pdesc) \
328 SHIFT_AND_MASK_LE(__pdesc, 14, 1)
329#define GET_RX_STATUS_DESC_ICV(__pdesc) \
330 SHIFT_AND_MASK_LE(__pdesc, 15, 1)
331#define GET_RX_STATUS_DESC_DRVINFO_SIZE(__pdesc) \
332 SHIFT_AND_MASK_LE(__pdesc, 16, 4)
333#define GET_RX_STATUS_DESC_SECURITY(__pdesc) \
334 SHIFT_AND_MASK_LE(__pdesc, 20, 3)
335#define GET_RX_STATUS_DESC_QOS(__pdesc) \
336 SHIFT_AND_MASK_LE(__pdesc, 23, 1)
337#define GET_RX_STATUS_DESC_SHIFT(__pdesc) \
338 SHIFT_AND_MASK_LE(__pdesc, 24, 2)
339#define GET_RX_STATUS_DESC_PHY_STATUS(__pdesc) \
340 SHIFT_AND_MASK_LE(__pdesc, 26, 1)
341#define GET_RX_STATUS_DESC_SWDEC(__pdesc) \
342 SHIFT_AND_MASK_LE(__pdesc, 27, 1)
343#define GET_RX_STATUS_DESC_LAST_SEG(__pdesc) \
344 SHIFT_AND_MASK_LE(__pdesc, 28, 1)
345#define GET_RX_STATUS_DESC_FIRST_SEG(__pdesc) \
346 SHIFT_AND_MASK_LE(__pdesc, 29, 1)
347#define GET_RX_STATUS_DESC_EOR(__pdesc) \
348 SHIFT_AND_MASK_LE(__pdesc, 30, 1)
349#define GET_RX_STATUS_DESC_OWN(__pdesc) \
350 SHIFT_AND_MASK_LE(__pdesc, 31, 1)
351
352/* DWORD 1 */
353#define SET_RX_STATUS_DESC_MACID(__pdesc, __val) \
354 SET_BITS_OFFSET_LE(__pdesc + 4, 0, 5, __val)
355#define SET_RX_STATUS_DESC_TID(__pdesc, __val) \
356 SET_BITS_OFFSET_LE(__pdesc + 4, 5, 4, __val)
357#define SET_RX_STATUS_DESC_PAGGR(__pdesc, __val) \
358 SET_BITS_OFFSET_LE(__pdesc + 4, 14, 1, __val)
359#define SET_RX_STATUS_DESC_FAGGR(__pdesc, __val) \
360 SET_BITS_OFFSET_LE(__pdesc + 4, 15, 1, __val)
361#define SET_RX_STATUS_DESC_A1_FIT(__pdesc, __val) \
362 SET_BITS_OFFSET_LE(__pdesc + 4, 16, 4, __val)
363#define SET_RX_STATUS_DESC_A2_FIT(__pdesc, __val) \
364 SET_BITS_OFFSET_LE(__pdesc + 4, 20, 4, __val)
365#define SET_RX_STATUS_DESC_PAM(__pdesc, __val) \
366 SET_BITS_OFFSET_LE(__pdesc + 4, 24, 1, __val)
367#define SET_RX_STATUS_DESC_PWR(__pdesc, __val) \
368 SET_BITS_OFFSET_LE(__pdesc + 4, 25, 1, __val)
369#define SET_RX_STATUS_DESC_MOREDATA(__pdesc, __val) \
370 SET_BITS_OFFSET_LE(__pdesc + 4, 26, 1, __val)
371#define SET_RX_STATUS_DESC_MOREFRAG(__pdesc, __val) \
372 SET_BITS_OFFSET_LE(__pdesc + 4, 27, 1, __val)
373#define SET_RX_STATUS_DESC_TYPE(__pdesc, __val) \
374 SET_BITS_OFFSET_LE(__pdesc + 4, 28, 2, __val)
375#define SET_RX_STATUS_DESC_MC(__pdesc, __val) \
376 SET_BITS_OFFSET_LE(__pdesc + 4, 30, 1, __val)
377#define SET_RX_STATUS_DESC_BC(__pdesc, __val) \
378 SET_BITS_OFFSET_LE(__pdesc + 4, 31, 1, __val)
379
380#define GET_RX_STATUS_DEC_MACID(__pdesc) \
381 SHIFT_AND_MASK_LE(__pdesc + 4, 0, 5)
382#define GET_RX_STATUS_DESC_TID(__pdesc) \
383 SHIFT_AND_MASK_LE(__pdesc + 4, 5, 4)
384#define GET_RX_STATUS_DESC_PAGGR(__pdesc) \
385 SHIFT_AND_MASK_LE(__pdesc + 4, 14, 1)
386#define GET_RX_STATUS_DESC_FAGGR(__pdesc) \
387 SHIFT_AND_MASK_LE(__pdesc + 4, 15, 1)
388#define GET_RX_STATUS_DESC_A1_FIT(__pdesc) \
389 SHIFT_AND_MASK_LE(__pdesc + 4, 16, 4)
390#define GET_RX_STATUS_DESC_A2_FIT(__pdesc) \
391 SHIFT_AND_MASK_LE(__pdesc + 4, 20, 4)
392#define GET_RX_STATUS_DESC_PAM(__pdesc) \
393 SHIFT_AND_MASK_LE(__pdesc + 4, 24, 1)
394#define GET_RX_STATUS_DESC_PWR(__pdesc) \
395 SHIFT_AND_MASK_LE(__pdesc + 4, 25, 1)
396#define GET_RX_STATUS_DESC_MORE_DATA(__pdesc) \
397 SHIFT_AND_MASK_LE(__pdesc + 4, 26, 1)
398#define GET_RX_STATUS_DESC_MORE_FRAG(__pdesc) \
399 SHIFT_AND_MASK_LE(__pdesc + 4, 27, 1)
400#define GET_RX_STATUS_DESC_TYPE(__pdesc) \
401 SHIFT_AND_MASK_LE(__pdesc + 4, 28, 2)
402#define GET_RX_STATUS_DESC_MC(__pdesc) \
403 SHIFT_AND_MASK_LE(__pdesc + 4, 30, 1)
404#define GET_RX_STATUS_DESC_BC(__pdesc) \
405 SHIFT_AND_MASK_LE(__pdesc + 4, 31, 1)
406
407/* DWORD 2 */
408#define SET_RX_STATUS_DESC_SEQ(__pdesc, __val) \
409 SET_BITS_OFFSET_LE(__pdesc + 8, 0, 12, __val)
410#define SET_RX_STATUS_DESC_FRAG(__pdesc, __val) \
411 SET_BITS_OFFSET_LE(__pdesc + 8, 12, 4, __val)
412#define SET_RX_STATUS_DESC_NEXT_PKTLEN(__pdesc, __val) \
413 SET_BITS_OFFSET_LE(__pdesc + 8, 16, 8, __val)
414#define SET_RX_STATUS_DESC_NEXT_IND(__pdesc, __val) \
415 SET_BITS_OFFSET_LE(__pdesc + 8, 30, 1, __val)
416
417#define GET_RX_STATUS_DESC_SEQ(__pdesc) \
418 SHIFT_AND_MASK_LE(__pdesc + 8, 0, 12)
419#define GET_RX_STATUS_DESC_FRAG(__pdesc) \
420 SHIFT_AND_MASK_LE(__pdesc + 8, 12, 4)
421#define GET_RX_STATUS_DESC_NEXT_PKTLEN(__pdesc) \
422 SHIFT_AND_MASK_LE(__pdesc + 8, 16, 8)
423#define GET_RX_STATUS_DESC_NEXT_IND(__pdesc) \
424 SHIFT_AND_MASK_LE(__pdesc + 8, 30, 1)
425
426/* DWORD 3 */
427#define SET_RX_STATUS_DESC_RX_MCS(__pdesc, __val) \
428 SET_BITS_OFFSET_LE(__pdesc + 12, 0, 6, __val)
429#define SET_RX_STATUS_DESC_RX_HT(__pdesc, __val) \
430 SET_BITS_OFFSET_LE(__pdesc + 12, 6, 1, __val)
431#define SET_RX_STATUS_DESC_AMSDU(__pdesc, __val) \
432 SET_BITS_OFFSET_LE(__pdesc + 12, 7, 1, __val)
433#define SET_RX_STATUS_DESC_SPLCP(__pdesc, __val) \
434 SET_BITS_OFFSET_LE(__pdesc + 12, 8, 1, __val)
435#define SET_RX_STATUS_DESC_BW(__pdesc, __val) \
436 SET_BITS_OFFSET_LE(__pdesc + 12, 9, 1, __val)
437#define SET_RX_STATUS_DESC_HTC(__pdesc, __val) \
438 SET_BITS_OFFSET_LE(__pdesc + 12, 10, 1, __val)
439#define SET_RX_STATUS_DESC_TCP_CHK_RPT(__pdesc, __val) \
440 SET_BITS_OFFSET_LE(__pdesc + 12, 11, 1, __val)
441#define SET_RX_STATUS_DESC_IP_CHK_RPT(__pdesc, __val) \
442 SET_BITS_OFFSET_LE(__pdesc + 12, 12, 1, __val)
443#define SET_RX_STATUS_DESC_TCP_CHK_VALID(__pdesc, __val) \
444 SET_BITS_OFFSET_LE(__pdesc + 12, 13, 1, __val)
445#define SET_RX_STATUS_DESC_HWPC_ERR(__pdesc, __val) \
446 SET_BITS_OFFSET_LE(__pdesc + 12, 14, 1, __val)
447#define SET_RX_STATUS_DESC_HWPC_IND(__pdesc, __val) \
448 SET_BITS_OFFSET_LE(__pdesc + 12, 15, 1, __val)
449#define SET_RX_STATUS_DESC_IV0(__pdesc, __val) \
450 SET_BITS_OFFSET_LE(__pdesc + 12, 16, 16, __val)
451
452#define GET_RX_STATUS_DESC_RX_MCS(__pdesc) \
453 SHIFT_AND_MASK_LE(__pdesc + 12, 0, 6)
454#define GET_RX_STATUS_DESC_RX_HT(__pdesc) \
455 SHIFT_AND_MASK_LE(__pdesc + 12, 6, 1)
456#define GET_RX_STATUS_DESC_AMSDU(__pdesc) \
457 SHIFT_AND_MASK_LE(__pdesc + 12, 7, 1)
458#define GET_RX_STATUS_DESC_SPLCP(__pdesc) \
459 SHIFT_AND_MASK_LE(__pdesc + 12, 8, 1)
460#define GET_RX_STATUS_DESC_BW(__pdesc) \
461 SHIFT_AND_MASK_LE(__pdesc + 12, 9, 1)
462#define GET_RX_STATUS_DESC_HTC(__pdesc) \
463 SHIFT_AND_MASK_LE(__pdesc + 12, 10, 1)
464#define GET_RX_STATUS_DESC_TCP_CHK_RPT(__pdesc) \
465 SHIFT_AND_MASK_LE(__pdesc + 12, 11, 1)
466#define GET_RX_STATUS_DESC_IP_CHK_RPT(__pdesc) \
467 SHIFT_AND_MASK_LE(__pdesc + 12, 12, 1)
468#define GET_RX_STATUS_DESC_TCP_CHK_VALID(__pdesc) \
469 SHIFT_AND_MASK_LE(__pdesc + 12, 13, 1)
470#define GET_RX_STATUS_DESC_HWPC_ERR(__pdesc) \
471 SHIFT_AND_MASK_LE(__pdesc + 12, 14, 1)
472#define GET_RX_STATUS_DESC_HWPC_IND(__pdesc) \
473 SHIFT_AND_MASK_LE(__pdesc + 12, 15, 1)
474#define GET_RX_STATUS_DESC_IV0(__pdesc) \
475 SHIFT_AND_MASK_LE(__pdesc + 12, 16, 16)
476
477/* DWORD 4 */
478#define SET_RX_STATUS_DESC_IV1(__pdesc, __val) \
479 SET_BITS_OFFSET_LE(__pdesc + 16, 0, 32, __val)
480#define GET_RX_STATUS_DESC_IV1(__pdesc) \
481 SHIFT_AND_MASK_LE(__pdesc + 16, 0, 32)
482
483/* DWORD 5 */
484#define SET_RX_STATUS_DESC_TSFL(__pdesc, __val) \
485 SET_BITS_OFFSET_LE(__pdesc + 20, 0, 32, __val)
486#define GET_RX_STATUS_DESC_TSFL(__pdesc) \
487 SHIFT_AND_MASK_LE(__pdesc + 20, 0, 32)
488
489/* DWORD 6 */
490#define SET_RX_STATUS__DESC_BUFF_ADDR(__pdesc, __val) \
491 SET_BITS_OFFSET_LE(__pdesc + 24, 0, 32, __val)
492
493#define RX_HAL_IS_CCK_RATE(_pdesc)\
494 (GET_RX_STATUS_DESC_RX_MCS(_pdesc) == DESC92S_RATE1M || \
495 GET_RX_STATUS_DESC_RX_MCS(_pdesc) == DESC92S_RATE2M || \
496 GET_RX_STATUS_DESC_RX_MCS(_pdesc) == DESC92S_RATE5_5M ||\
497 GET_RX_STATUS_DESC_RX_MCS(_pdesc) == DESC92S_RATE11M)
498
499enum rf_optype {
500 RF_OP_BY_SW_3WIRE = 0,
501 RF_OP_BY_FW,
502 RF_OP_MAX
503};
504
505enum ic_inferiority {
506 IC_INFERIORITY_A = 0,
507 IC_INFERIORITY_B = 1,
508};
509
510enum fwcmd_iotype {
511 /* For DIG DM */
512 FW_CMD_DIG_ENABLE = 0,
513 FW_CMD_DIG_DISABLE = 1,
514 FW_CMD_DIG_HALT = 2,
515 FW_CMD_DIG_RESUME = 3,
516 /* For High Power DM */
517 FW_CMD_HIGH_PWR_ENABLE = 4,
518 FW_CMD_HIGH_PWR_DISABLE = 5,
519 /* For Rate adaptive DM */
520 FW_CMD_RA_RESET = 6,
521 FW_CMD_RA_ACTIVE = 7,
522 FW_CMD_RA_REFRESH_N = 8,
523 FW_CMD_RA_REFRESH_BG = 9,
524 FW_CMD_RA_INIT = 10,
525 /* For FW supported IQK */
526 FW_CMD_IQK_INIT = 11,
527 /* Tx power tracking switch,
528 * MP driver only */
529 FW_CMD_TXPWR_TRACK_ENABLE = 12,
530 /* Tx power tracking switch,
531 * MP driver only */
532 FW_CMD_TXPWR_TRACK_DISABLE = 13,
533 /* Tx power tracking with thermal
534 * indication, for Normal driver */
535 FW_CMD_TXPWR_TRACK_THERMAL = 14,
536 FW_CMD_PAUSE_DM_BY_SCAN = 15,
537 FW_CMD_RESUME_DM_BY_SCAN = 16,
538 FW_CMD_RA_REFRESH_N_COMB = 17,
539 FW_CMD_RA_REFRESH_BG_COMB = 18,
540 FW_CMD_ANTENNA_SW_ENABLE = 19,
541 FW_CMD_ANTENNA_SW_DISABLE = 20,
542 /* Tx Status report for CCX from FW */
543 FW_CMD_TX_FEEDBACK_CCX_ENABLE = 21,
544 /* Indifate firmware that driver
545 * enters LPS, For PS-Poll issue */
546 FW_CMD_LPS_ENTER = 22,
547 /* Indicate firmware that driver
548 * leave LPS*/
549 FW_CMD_LPS_LEAVE = 23,
550 /* Set DIG mode to signal strength */
551 FW_CMD_DIG_MODE_SS = 24,
552 /* Set DIG mode to false alarm. */
553 FW_CMD_DIG_MODE_FA = 25,
554 FW_CMD_ADD_A2_ENTRY = 26,
555 FW_CMD_CTRL_DM_BY_DRIVER = 27,
556 FW_CMD_CTRL_DM_BY_DRIVER_NEW = 28,
557 FW_CMD_PAPE_CONTROL = 29,
558 FW_CMD_IQK_ENABLE = 30,
559};
560
561/*
562 * Driver info contain PHY status
563 * and other variabel size info
564 * PHY Status content as below
565 */
566struct rx_fwinfo {
567 /* DWORD 0 */
568 u8 gain_trsw[4];
569 /* DWORD 1 */
570 u8 pwdb_all;
571 u8 cfosho[4];
572 /* DWORD 2 */
573 u8 cfotail[4];
574 /* DWORD 3 */
575 s8 rxevm[2];
576 s8 rxsnr[4];
577 /* DWORD 4 */
578 u8 pdsnr[2];
579 /* DWORD 5 */
580 u8 csi_current[2];
581 u8 csi_target[2];
582 /* DWORD 6 */
583 u8 sigevm;
584 u8 max_ex_pwr;
585 u8 ex_intf_flag:1;
586 u8 sgi_en:1;
587 u8 rxsc:2;
588 u8 reserve:4;
589};
590
591struct phy_sts_cck_8192s_t {
592 u8 adc_pwdb_x[4];
593 u8 sq_rpt;
594 u8 cck_agc_rpt;
595};
596
597#endif
598
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/dm.c b/drivers/net/wireless/rtlwifi/rtl8192se/dm.c
new file mode 100644
index 000000000000..da86db86fa4a
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/dm.c
@@ -0,0 +1,733 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2010 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#include "../wifi.h"
31#include "../base.h"
32#include "reg.h"
33#include "def.h"
34#include "phy.h"
35#include "dm.h"
36#include "fw.h"
37
38struct dig_t digtable;
39static const u32 edca_setting_dl[PEER_MAX] = {
40 0xa44f, /* 0 UNKNOWN */
41 0x5ea44f, /* 1 REALTEK_90 */
42 0x5ea44f, /* 2 REALTEK_92SE */
43 0xa630, /* 3 BROAD */
44 0xa44f, /* 4 RAL */
45 0xa630, /* 5 ATH */
46 0xa630, /* 6 CISCO */
47 0xa42b, /* 7 MARV */
48};
49
50static const u32 edca_setting_dl_gmode[PEER_MAX] = {
51 0x4322, /* 0 UNKNOWN */
52 0xa44f, /* 1 REALTEK_90 */
53 0x5ea44f, /* 2 REALTEK_92SE */
54 0xa42b, /* 3 BROAD */
55 0x5e4322, /* 4 RAL */
56 0x4322, /* 5 ATH */
57 0xa430, /* 6 CISCO */
58 0x5ea44f, /* 7 MARV */
59};
60
61static const u32 edca_setting_ul[PEER_MAX] = {
62 0x5e4322, /* 0 UNKNOWN */
63 0xa44f, /* 1 REALTEK_90 */
64 0x5ea44f, /* 2 REALTEK_92SE */
65 0x5ea322, /* 3 BROAD */
66 0x5ea422, /* 4 RAL */
67 0x5ea322, /* 5 ATH */
68 0x3ea44f, /* 6 CISCO */
69 0x5ea44f, /* 7 MARV */
70};
71
72static void _rtl92s_dm_check_edca_turbo(struct ieee80211_hw *hw)
73{
74 struct rtl_priv *rtlpriv = rtl_priv(hw);
75 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
76
77 static u64 last_txok_cnt;
78 static u64 last_rxok_cnt;
79 u64 cur_txok_cnt = 0;
80 u64 cur_rxok_cnt = 0;
81
82 u32 edca_be_ul = edca_setting_ul[mac->vendor];
83 u32 edca_be_dl = edca_setting_dl[mac->vendor];
84 u32 edca_gmode = edca_setting_dl_gmode[mac->vendor];
85
86 if (mac->link_state != MAC80211_LINKED) {
87 rtlpriv->dm.current_turbo_edca = false;
88 goto dm_checkedcaturbo_exit;
89 }
90
91 if ((!rtlpriv->dm.is_any_nonbepkts) &&
92 (!rtlpriv->dm.disable_framebursting)) {
93 cur_txok_cnt = rtlpriv->stats.txbytesunicast - last_txok_cnt;
94 cur_rxok_cnt = rtlpriv->stats.rxbytesunicast - last_rxok_cnt;
95
96 if (rtlpriv->phy.rf_type == RF_1T2R) {
97 if (cur_txok_cnt > 4 * cur_rxok_cnt) {
98 /* Uplink TP is present. */
99 if (rtlpriv->dm.is_cur_rdlstate ||
100 !rtlpriv->dm.current_turbo_edca) {
101 rtl_write_dword(rtlpriv, EDCAPARA_BE,
102 edca_be_ul);
103 rtlpriv->dm.is_cur_rdlstate = false;
104 }
105 } else {/* Balance TP is present. */
106 if (!rtlpriv->dm.is_cur_rdlstate ||
107 !rtlpriv->dm.current_turbo_edca) {
108 if (mac->mode == WIRELESS_MODE_G ||
109 mac->mode == WIRELESS_MODE_B)
110 rtl_write_dword(rtlpriv,
111 EDCAPARA_BE,
112 edca_gmode);
113 else
114 rtl_write_dword(rtlpriv,
115 EDCAPARA_BE,
116 edca_be_dl);
117 rtlpriv->dm.is_cur_rdlstate = true;
118 }
119 }
120 rtlpriv->dm.current_turbo_edca = true;
121 } else {
122 if (cur_rxok_cnt > 4 * cur_txok_cnt) {
123 if (!rtlpriv->dm.is_cur_rdlstate ||
124 !rtlpriv->dm.current_turbo_edca) {
125 if (mac->mode == WIRELESS_MODE_G ||
126 mac->mode == WIRELESS_MODE_B)
127 rtl_write_dword(rtlpriv,
128 EDCAPARA_BE,
129 edca_gmode);
130 else
131 rtl_write_dword(rtlpriv,
132 EDCAPARA_BE,
133 edca_be_dl);
134 rtlpriv->dm.is_cur_rdlstate = true;
135 }
136 } else {
137 if (rtlpriv->dm.is_cur_rdlstate ||
138 !rtlpriv->dm.current_turbo_edca) {
139 rtl_write_dword(rtlpriv, EDCAPARA_BE,
140 edca_be_ul);
141 rtlpriv->dm.is_cur_rdlstate = false;
142 }
143 }
144 rtlpriv->dm.current_turbo_edca = true;
145 }
146 } else {
147 if (rtlpriv->dm.current_turbo_edca) {
148 u8 tmp = AC0_BE;
149 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM,
150 (u8 *)(&tmp));
151 rtlpriv->dm.current_turbo_edca = false;
152 }
153 }
154
155dm_checkedcaturbo_exit:
156 rtlpriv->dm.is_any_nonbepkts = false;
157 last_txok_cnt = rtlpriv->stats.txbytesunicast;
158 last_rxok_cnt = rtlpriv->stats.rxbytesunicast;
159}
160
161static void _rtl92s_dm_txpowertracking_callback_thermalmeter(
162 struct ieee80211_hw *hw)
163{
164 struct rtl_priv *rtlpriv = rtl_priv(hw);
165 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
166 u8 thermalvalue = 0;
167
168 rtlpriv->dm.txpower_trackinginit = true;
169
170 thermalvalue = (u8)rtl_get_rfreg(hw, RF90_PATH_A, RF_T_METER, 0x1f);
171
172 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
173 ("Readback Thermal Meter = 0x%x pre thermal meter 0x%x "
174 "eeprom_thermalmeter 0x%x\n", thermalvalue,
175 rtlpriv->dm.thermalvalue, rtlefuse->eeprom_thermalmeter));
176
177 if (thermalvalue) {
178 rtlpriv->dm.thermalvalue = thermalvalue;
179 rtl92s_phy_set_fw_cmd(hw, FW_CMD_TXPWR_TRACK_THERMAL);
180 }
181
182 rtlpriv->dm.txpowercount = 0;
183}
184
185static void _rtl92s_dm_check_txpowertracking_thermalmeter(
186 struct ieee80211_hw *hw)
187{
188 struct rtl_priv *rtlpriv = rtl_priv(hw);
189 struct rtl_phy *rtlphy = &(rtlpriv->phy);
190 static u8 tm_trigger;
191 u8 tx_power_checkcnt = 5;
192
193 /* 2T2R TP issue */
194 if (rtlphy->rf_type == RF_2T2R)
195 return;
196
197 if (!rtlpriv->dm.txpower_tracking)
198 return;
199
200 if (rtlpriv->dm.txpowercount <= tx_power_checkcnt) {
201 rtlpriv->dm.txpowercount++;
202 return;
203 }
204
205 if (!tm_trigger) {
206 rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER,
207 RFREG_OFFSET_MASK, 0x60);
208 tm_trigger = 1;
209 } else {
210 _rtl92s_dm_txpowertracking_callback_thermalmeter(hw);
211 tm_trigger = 0;
212 }
213}
214
215static void _rtl92s_dm_refresh_rateadaptive_mask(struct ieee80211_hw *hw)
216{
217 struct rtl_priv *rtlpriv = rtl_priv(hw);
218 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
219 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
220 struct rate_adaptive *ra = &(rtlpriv->ra);
221
222 u32 low_rssi_thresh = 0;
223 u32 middle_rssi_thresh = 0;
224 u32 high_rssi_thresh = 0;
225 u8 rssi_level;
226 struct ieee80211_sta *sta = NULL;
227
228 if (is_hal_stop(rtlhal))
229 return;
230
231 if (!rtlpriv->dm.useramask)
232 return;
233
234 if (!rtlpriv->dm.inform_fw_driverctrldm) {
235 rtl92s_phy_set_fw_cmd(hw, FW_CMD_CTRL_DM_BY_DRIVER);
236 rtlpriv->dm.inform_fw_driverctrldm = true;
237 }
238
239 rcu_read_lock();
240 if (mac->opmode == NL80211_IFTYPE_STATION)
241 sta = get_sta(hw, mac->vif, mac->bssid);
242 if ((mac->link_state == MAC80211_LINKED) &&
243 (mac->opmode == NL80211_IFTYPE_STATION)) {
244 switch (ra->pre_ratr_state) {
245 case DM_RATR_STA_HIGH:
246 high_rssi_thresh = 40;
247 middle_rssi_thresh = 30;
248 low_rssi_thresh = 20;
249 break;
250 case DM_RATR_STA_MIDDLE:
251 high_rssi_thresh = 44;
252 middle_rssi_thresh = 30;
253 low_rssi_thresh = 20;
254 break;
255 case DM_RATR_STA_LOW:
256 high_rssi_thresh = 44;
257 middle_rssi_thresh = 34;
258 low_rssi_thresh = 20;
259 break;
260 case DM_RATR_STA_ULTRALOW:
261 high_rssi_thresh = 44;
262 middle_rssi_thresh = 34;
263 low_rssi_thresh = 24;
264 break;
265 default:
266 high_rssi_thresh = 44;
267 middle_rssi_thresh = 34;
268 low_rssi_thresh = 24;
269 break;
270 }
271
272 if (rtlpriv->dm.undecorated_smoothed_pwdb >
273 (long)high_rssi_thresh) {
274 ra->ratr_state = DM_RATR_STA_HIGH;
275 rssi_level = 1;
276 } else if (rtlpriv->dm.undecorated_smoothed_pwdb >
277 (long)middle_rssi_thresh) {
278 ra->ratr_state = DM_RATR_STA_LOW;
279 rssi_level = 3;
280 } else if (rtlpriv->dm.undecorated_smoothed_pwdb >
281 (long)low_rssi_thresh) {
282 ra->ratr_state = DM_RATR_STA_LOW;
283 rssi_level = 5;
284 } else {
285 ra->ratr_state = DM_RATR_STA_ULTRALOW;
286 rssi_level = 6;
287 }
288
289 if (ra->pre_ratr_state != ra->ratr_state) {
290 RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, ("RSSI = %ld "
291 "RSSI_LEVEL = %d PreState = %d, CurState = %d\n",
292 rtlpriv->dm.undecorated_smoothed_pwdb,
293 ra->ratr_state,
294 ra->pre_ratr_state, ra->ratr_state));
295
296 rtlpriv->cfg->ops->update_rate_tbl(hw, sta,
297 ra->ratr_state);
298 ra->pre_ratr_state = ra->ratr_state;
299 }
300 }
301 rcu_read_unlock();
302}
303
304static void _rtl92s_dm_switch_baseband_mrc(struct ieee80211_hw *hw)
305{
306 struct rtl_priv *rtlpriv = rtl_priv(hw);
307 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
308 struct rtl_phy *rtlphy = &(rtlpriv->phy);
309 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
310 bool current_mrc;
311 bool enable_mrc = true;
312 long tmpentry_maxpwdb = 0;
313 u8 rssi_a = 0;
314 u8 rssi_b = 0;
315
316 if (is_hal_stop(rtlhal))
317 return;
318
319 if ((rtlphy->rf_type == RF_1T1R) || (rtlphy->rf_type == RF_2T2R))
320 return;
321
322 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_MRC, (u8 *)(&current_mrc));
323
324 if (mac->link_state >= MAC80211_LINKED) {
325 if (rtlpriv->dm.undecorated_smoothed_pwdb > tmpentry_maxpwdb) {
326 rssi_a = rtlpriv->stats.rx_rssi_percentage[RF90_PATH_A];
327 rssi_b = rtlpriv->stats.rx_rssi_percentage[RF90_PATH_B];
328 }
329 }
330
331 /* MRC settings would NOT affect TP on Wireless B mode. */
332 if (mac->mode != WIRELESS_MODE_B) {
333 if ((rssi_a == 0) && (rssi_b == 0)) {
334 enable_mrc = true;
335 } else if (rssi_b > 30) {
336 /* Turn on B-Path */
337 enable_mrc = true;
338 } else if (rssi_b < 5) {
339 /* Turn off B-path */
340 enable_mrc = false;
341 /* Take care of RSSI differentiation. */
342 } else if (rssi_a > 15 && (rssi_a >= rssi_b)) {
343 if ((rssi_a - rssi_b) > 15)
344 /* Turn off B-path */
345 enable_mrc = false;
346 else if ((rssi_a - rssi_b) < 10)
347 /* Turn on B-Path */
348 enable_mrc = true;
349 else
350 enable_mrc = current_mrc;
351 } else {
352 /* Turn on B-Path */
353 enable_mrc = true;
354 }
355 }
356
357 /* Update MRC settings if needed. */
358 if (enable_mrc != current_mrc)
359 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_MRC,
360 (u8 *)&enable_mrc);
361
362}
363
364void rtl92s_dm_init_edca_turbo(struct ieee80211_hw *hw)
365{
366 struct rtl_priv *rtlpriv = rtl_priv(hw);
367
368 rtlpriv->dm.current_turbo_edca = false;
369 rtlpriv->dm.is_any_nonbepkts = false;
370 rtlpriv->dm.is_cur_rdlstate = false;
371}
372
373static void _rtl92s_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw)
374{
375 struct rtl_priv *rtlpriv = rtl_priv(hw);
376 struct rate_adaptive *ra = &(rtlpriv->ra);
377
378 ra->ratr_state = DM_RATR_STA_MAX;
379 ra->pre_ratr_state = DM_RATR_STA_MAX;
380
381 if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER)
382 rtlpriv->dm.useramask = true;
383 else
384 rtlpriv->dm.useramask = false;
385
386 rtlpriv->dm.useramask = false;
387 rtlpriv->dm.inform_fw_driverctrldm = false;
388}
389
390static void _rtl92s_dm_init_txpowertracking_thermalmeter(
391 struct ieee80211_hw *hw)
392{
393 struct rtl_priv *rtlpriv = rtl_priv(hw);
394
395 rtlpriv->dm.txpower_tracking = true;
396 rtlpriv->dm.txpowercount = 0;
397 rtlpriv->dm.txpower_trackinginit = false;
398}
399
400static void _rtl92s_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw)
401{
402 struct rtl_priv *rtlpriv = rtl_priv(hw);
403 struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt);
404 u32 ret_value;
405
406 ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER1, MASKDWORD);
407 falsealm_cnt->cnt_parity_fail = ((ret_value & 0xffff0000) >> 16);
408
409 ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER2, MASKDWORD);
410 falsealm_cnt->cnt_rate_illegal = (ret_value & 0xffff);
411 falsealm_cnt->cnt_crc8_fail = ((ret_value & 0xffff0000) >> 16);
412 ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER3, MASKDWORD);
413 falsealm_cnt->cnt_mcs_fail = (ret_value & 0xffff);
414
415 falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail +
416 falsealm_cnt->cnt_rate_illegal + falsealm_cnt->cnt_crc8_fail +
417 falsealm_cnt->cnt_mcs_fail;
418
419 /* read CCK false alarm */
420 ret_value = rtl_get_bbreg(hw, 0xc64, MASKDWORD);
421 falsealm_cnt->cnt_cck_fail = (ret_value & 0xffff);
422 falsealm_cnt->cnt_all = falsealm_cnt->cnt_ofdm_fail +
423 falsealm_cnt->cnt_cck_fail;
424}
425
426static void rtl92s_backoff_enable_flag(struct ieee80211_hw *hw)
427{
428 struct rtl_priv *rtlpriv = rtl_priv(hw);
429 struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt);
430
431 if (falsealm_cnt->cnt_all > digtable.fa_highthresh) {
432 if ((digtable.backoff_val - 6) <
433 digtable.backoffval_range_min)
434 digtable.backoff_val = digtable.backoffval_range_min;
435 else
436 digtable.backoff_val -= 6;
437 } else if (falsealm_cnt->cnt_all < digtable.fa_lowthresh) {
438 if ((digtable.backoff_val + 6) >
439 digtable.backoffval_range_max)
440 digtable.backoff_val =
441 digtable.backoffval_range_max;
442 else
443 digtable.backoff_val += 6;
444 }
445}
446
447static void _rtl92s_dm_initial_gain_sta_beforeconnect(struct ieee80211_hw *hw)
448{
449 struct rtl_priv *rtlpriv = rtl_priv(hw);
450 struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt);
451 static u8 initialized, force_write;
452 u8 initial_gain = 0;
453
454 if ((digtable.pre_sta_connectstate == digtable.cur_sta_connectstate) ||
455 (digtable.cur_sta_connectstate == DIG_STA_BEFORE_CONNECT)) {
456 if (digtable.cur_sta_connectstate == DIG_STA_BEFORE_CONNECT) {
457 if (rtlpriv->psc.rfpwr_state != ERFON)
458 return;
459
460 if (digtable.backoff_enable_flag == true)
461 rtl92s_backoff_enable_flag(hw);
462 else
463 digtable.backoff_val = DM_DIG_BACKOFF;
464
465 if ((digtable.rssi_val + 10 - digtable.backoff_val) >
466 digtable.rx_gain_range_max)
467 digtable.cur_igvalue =
468 digtable.rx_gain_range_max;
469 else if ((digtable.rssi_val + 10 - digtable.backoff_val)
470 < digtable.rx_gain_range_min)
471 digtable.cur_igvalue =
472 digtable.rx_gain_range_min;
473 else
474 digtable.cur_igvalue = digtable.rssi_val + 10 -
475 digtable.backoff_val;
476
477 if (falsealm_cnt->cnt_all > 10000)
478 digtable.cur_igvalue =
479 (digtable.cur_igvalue > 0x33) ?
480 digtable.cur_igvalue : 0x33;
481
482 if (falsealm_cnt->cnt_all > 16000)
483 digtable.cur_igvalue =
484 digtable.rx_gain_range_max;
485 /* connected -> connected or disconnected -> disconnected */
486 } else {
487 /* Firmware control DIG, do nothing in driver dm */
488 return;
489 }
490 /* disconnected -> connected or connected ->
491 * disconnected or beforeconnect->(dis)connected */
492 } else {
493 /* Enable FW DIG */
494 digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX;
495 rtl92s_phy_set_fw_cmd(hw, FW_CMD_DIG_ENABLE);
496
497 digtable.backoff_val = DM_DIG_BACKOFF;
498 digtable.cur_igvalue = rtlpriv->phy.default_initialgain[0];
499 digtable.pre_igvalue = 0;
500 return;
501 }
502
503 /* Forced writing to prevent from fw-dig overwriting. */
504 if (digtable.pre_igvalue != rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1,
505 MASKBYTE0))
506 force_write = 1;
507
508 if ((digtable.pre_igvalue != digtable.cur_igvalue) ||
509 !initialized || force_write) {
510 /* Disable FW DIG */
511 rtl92s_phy_set_fw_cmd(hw, FW_CMD_DIG_DISABLE);
512
513 initial_gain = (u8)digtable.cur_igvalue;
514
515 /* Set initial gain. */
516 rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0, initial_gain);
517 rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0, initial_gain);
518 digtable.pre_igvalue = digtable.cur_igvalue;
519 initialized = 1;
520 force_write = 0;
521 }
522}
523
524static void _rtl92s_dm_ctrl_initgain_bytwoport(struct ieee80211_hw *hw)
525{
526 struct rtl_priv *rtlpriv = rtl_priv(hw);
527
528 if (rtlpriv->mac80211.act_scanning)
529 return;
530
531 /* Decide the current status and if modify initial gain or not */
532 if (rtlpriv->mac80211.link_state >= MAC80211_LINKED ||
533 rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC)
534 digtable.cur_sta_connectstate = DIG_STA_CONNECT;
535 else
536 digtable.cur_sta_connectstate = DIG_STA_DISCONNECT;
537
538 digtable.rssi_val = rtlpriv->dm.undecorated_smoothed_pwdb;
539
540 /* Change dig mode to rssi */
541 if (digtable.cur_sta_connectstate != DIG_STA_DISCONNECT) {
542 if (digtable.dig_twoport_algorithm ==
543 DIG_TWO_PORT_ALGO_FALSE_ALARM) {
544 digtable.dig_twoport_algorithm = DIG_TWO_PORT_ALGO_RSSI;
545 rtl92s_phy_set_fw_cmd(hw, FW_CMD_DIG_MODE_SS);
546 }
547 }
548
549 _rtl92s_dm_false_alarm_counter_statistics(hw);
550 _rtl92s_dm_initial_gain_sta_beforeconnect(hw);
551
552 digtable.pre_sta_connectstate = digtable.cur_sta_connectstate;
553}
554
555static void _rtl92s_dm_ctrl_initgain_byrssi(struct ieee80211_hw *hw)
556{
557 struct rtl_priv *rtlpriv = rtl_priv(hw);
558 struct rtl_phy *rtlphy = &(rtlpriv->phy);
559
560 /* 2T2R TP issue */
561 if (rtlphy->rf_type == RF_2T2R)
562 return;
563
564 if (!rtlpriv->dm.dm_initialgain_enable)
565 return;
566
567 if (digtable.dig_enable_flag == false)
568 return;
569
570 _rtl92s_dm_ctrl_initgain_bytwoport(hw);
571}
572
573static void _rtl92s_dm_dynamic_txpower(struct ieee80211_hw *hw)
574{
575 struct rtl_priv *rtlpriv = rtl_priv(hw);
576 struct rtl_phy *rtlphy = &(rtlpriv->phy);
577 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
578 long undecorated_smoothed_pwdb;
579 long txpwr_threshold_lv1, txpwr_threshold_lv2;
580
581 /* 2T2R TP issue */
582 if (rtlphy->rf_type == RF_2T2R)
583 return;
584
585 if (!rtlpriv->dm.dynamic_txpower_enable ||
586 rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) {
587 rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL;
588 return;
589 }
590
591 if ((mac->link_state < MAC80211_LINKED) &&
592 (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) {
593 RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
594 ("Not connected to any\n"));
595
596 rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL;
597
598 rtlpriv->dm.last_dtp_lvl = TX_HIGHPWR_LEVEL_NORMAL;
599 return;
600 }
601
602 if (mac->link_state >= MAC80211_LINKED) {
603 if (mac->opmode == NL80211_IFTYPE_ADHOC) {
604 undecorated_smoothed_pwdb =
605 rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
606 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
607 ("AP Client PWDB = 0x%lx\n",
608 undecorated_smoothed_pwdb));
609 } else {
610 undecorated_smoothed_pwdb =
611 rtlpriv->dm.undecorated_smoothed_pwdb;
612 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
613 ("STA Default Port PWDB = 0x%lx\n",
614 undecorated_smoothed_pwdb));
615 }
616 } else {
617 undecorated_smoothed_pwdb =
618 rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
619
620 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
621 ("AP Ext Port PWDB = 0x%lx\n",
622 undecorated_smoothed_pwdb));
623 }
624
625 txpwr_threshold_lv2 = TX_POWER_NEAR_FIELD_THRESH_LVL2;
626 txpwr_threshold_lv1 = TX_POWER_NEAR_FIELD_THRESH_LVL1;
627
628 if (rtl_get_bbreg(hw, 0xc90, MASKBYTE0) == 1)
629 rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL;
630 else if (undecorated_smoothed_pwdb >= txpwr_threshold_lv2)
631 rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL2;
632 else if ((undecorated_smoothed_pwdb < (txpwr_threshold_lv2 - 3)) &&
633 (undecorated_smoothed_pwdb >= txpwr_threshold_lv1))
634 rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL1;
635 else if (undecorated_smoothed_pwdb < (txpwr_threshold_lv1 - 3))
636 rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL;
637
638 if ((rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl))
639 rtl92s_phy_set_txpower(hw, rtlphy->current_channel);
640
641 rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl;
642}
643
644static void _rtl92s_dm_init_dig(struct ieee80211_hw *hw)
645{
646 struct rtl_priv *rtlpriv = rtl_priv(hw);
647
648 /* Disable DIG scheme now.*/
649 digtable.dig_enable_flag = true;
650 digtable.backoff_enable_flag = true;
651
652 if ((rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER) &&
653 (hal_get_firmwareversion(rtlpriv) >= 0x3c))
654 digtable.dig_algorithm = DIG_ALGO_BY_TOW_PORT;
655 else
656 digtable.dig_algorithm =
657 DIG_ALGO_BEFORE_CONNECT_BY_RSSI_AND_ALARM;
658
659 digtable.dig_twoport_algorithm = DIG_TWO_PORT_ALGO_RSSI;
660 digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX;
661 /* off=by real rssi value, on=by digtable.rssi_val for new dig */
662 digtable.dig_dbgmode = DM_DBG_OFF;
663 digtable.dig_slgorithm_switch = 0;
664
665 /* 2007/10/04 MH Define init gain threshol. */
666 digtable.dig_state = DM_STA_DIG_MAX;
667 digtable.dig_highpwrstate = DM_STA_DIG_MAX;
668
669 digtable.cur_sta_connectstate = DIG_STA_DISCONNECT;
670 digtable.pre_sta_connectstate = DIG_STA_DISCONNECT;
671 digtable.cur_ap_connectstate = DIG_AP_DISCONNECT;
672 digtable.pre_ap_connectstate = DIG_AP_DISCONNECT;
673
674 digtable.rssi_lowthresh = DM_DIG_THRESH_LOW;
675 digtable.rssi_highthresh = DM_DIG_THRESH_HIGH;
676
677 digtable.fa_lowthresh = DM_FALSEALARM_THRESH_LOW;
678 digtable.fa_highthresh = DM_FALSEALARM_THRESH_HIGH;
679
680 digtable.rssi_highpower_lowthresh = DM_DIG_HIGH_PWR_THRESH_LOW;
681 digtable.rssi_highpower_highthresh = DM_DIG_HIGH_PWR_THRESH_HIGH;
682
683 /* for dig debug rssi value */
684 digtable.rssi_val = 50;
685 digtable.backoff_val = DM_DIG_BACKOFF;
686 digtable.rx_gain_range_max = DM_DIG_MAX;
687
688 digtable.rx_gain_range_min = DM_DIG_MIN;
689
690 digtable.backoffval_range_max = DM_DIG_BACKOFF_MAX;
691 digtable.backoffval_range_min = DM_DIG_BACKOFF_MIN;
692}
693
694static void _rtl92s_dm_init_dynamic_txpower(struct ieee80211_hw *hw)
695{
696 struct rtl_priv *rtlpriv = rtl_priv(hw);
697
698 if ((hal_get_firmwareversion(rtlpriv) >= 60) &&
699 (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER))
700 rtlpriv->dm.dynamic_txpower_enable = true;
701 else
702 rtlpriv->dm.dynamic_txpower_enable = false;
703
704 rtlpriv->dm.last_dtp_lvl = TX_HIGHPWR_LEVEL_NORMAL;
705 rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL;
706}
707
708void rtl92s_dm_init(struct ieee80211_hw *hw)
709{
710 struct rtl_priv *rtlpriv = rtl_priv(hw);
711
712 rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER;
713 rtlpriv->dm.undecorated_smoothed_pwdb = -1;
714
715 _rtl92s_dm_init_dynamic_txpower(hw);
716 rtl92s_dm_init_edca_turbo(hw);
717 _rtl92s_dm_init_rate_adaptive_mask(hw);
718 _rtl92s_dm_init_txpowertracking_thermalmeter(hw);
719 _rtl92s_dm_init_dig(hw);
720
721 rtl_write_dword(rtlpriv, WFM5, FW_CCA_CHK_ENABLE);
722}
723
724void rtl92s_dm_watchdog(struct ieee80211_hw *hw)
725{
726 _rtl92s_dm_check_edca_turbo(hw);
727 _rtl92s_dm_check_txpowertracking_thermalmeter(hw);
728 _rtl92s_dm_ctrl_initgain_byrssi(hw);
729 _rtl92s_dm_dynamic_txpower(hw);
730 _rtl92s_dm_refresh_rateadaptive_mask(hw);
731 _rtl92s_dm_switch_baseband_mrc(hw);
732}
733
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/dm.h b/drivers/net/wireless/rtlwifi/rtl8192se/dm.h
new file mode 100644
index 000000000000..9051a556acc4
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/dm.h
@@ -0,0 +1,164 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2010 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29#ifndef __RTL_92S_DM_H__
30#define __RTL_92S_DM_H__
31
32struct dig_t {
33 u8 dig_enable_flag;
34 u8 dig_algorithm;
35 u8 dig_twoport_algorithm;
36 u8 dig_ext_port_stage;
37 u8 dig_dbgmode;
38 u8 dig_slgorithm_switch;
39
40 long rssi_lowthresh;
41 long rssi_highthresh;
42
43 u32 fa_lowthresh;
44 u32 fa_highthresh;
45
46 long rssi_highpower_lowthresh;
47 long rssi_highpower_highthresh;
48
49 u8 dig_state;
50 u8 dig_highpwrstate;
51 u8 cur_sta_connectstate;
52 u8 pre_sta_connectstate;
53 u8 cur_ap_connectstate;
54 u8 pre_ap_connectstate;
55
56 u8 cur_pd_thstate;
57 u8 pre_pd_thstate;
58 u8 cur_cs_ratiostate;
59 u8 pre_cs_ratiostate;
60
61 u32 pre_igvalue;
62 u32 cur_igvalue;
63
64 u8 backoff_enable_flag;
65 char backoff_val;
66 char backoffval_range_max;
67 char backoffval_range_min;
68 u8 rx_gain_range_max;
69 u8 rx_gain_range_min;
70
71 long rssi_val;
72};
73
74enum dm_dig_alg {
75 DIG_ALGO_BY_FALSE_ALARM = 0,
76 DIG_ALGO_BY_RSSI = 1,
77 DIG_ALGO_BEFORE_CONNECT_BY_RSSI_AND_ALARM = 2,
78 DIG_ALGO_BY_TOW_PORT = 3,
79 DIG_ALGO_MAX
80};
81
82enum dm_dig_two_port_alg {
83 DIG_TWO_PORT_ALGO_RSSI = 0,
84 DIG_TWO_PORT_ALGO_FALSE_ALARM = 1,
85};
86
87enum dm_dig_dbg {
88 DM_DBG_OFF = 0,
89 DM_DBG_ON = 1,
90 DM_DBG_MAX
91};
92
93enum dm_dig_sta {
94 DM_STA_DIG_OFF = 0,
95 DM_STA_DIG_ON,
96 DM_STA_DIG_MAX
97};
98
99enum dm_dig_connect {
100 DIG_STA_DISCONNECT = 0,
101 DIG_STA_CONNECT = 1,
102 DIG_STA_BEFORE_CONNECT = 2,
103 DIG_AP_DISCONNECT = 3,
104 DIG_AP_CONNECT = 4,
105 DIG_AP_ADD_STATION = 5,
106 DIG_CONNECT_MAX
107};
108
109enum dm_dig_ext_port_alg {
110 DIG_EXT_PORT_STAGE_0 = 0,
111 DIG_EXT_PORT_STAGE_1 = 1,
112 DIG_EXT_PORT_STAGE_2 = 2,
113 DIG_EXT_PORT_STAGE_3 = 3,
114 DIG_EXT_PORT_STAGE_MAX = 4,
115};
116
117enum dm_ratr_sta {
118 DM_RATR_STA_HIGH = 0,
119 DM_RATR_STA_MIDDLEHIGH = 1,
120 DM_RATR_STA_MIDDLE = 2,
121 DM_RATR_STA_MIDDLELOW = 3,
122 DM_RATR_STA_LOW = 4,
123 DM_RATR_STA_ULTRALOW = 5,
124 DM_RATR_STA_MAX
125};
126
127#define DM_TYPE_BYFW 0
128#define DM_TYPE_BYDRIVER 1
129
130#define TX_HIGH_PWR_LEVEL_NORMAL 0
131#define TX_HIGH_PWR_LEVEL_LEVEL1 1
132#define TX_HIGH_PWR_LEVEL_LEVEL2 2
133
134#define HAL_DM_DIG_DISABLE BIT(0) /* Disable Dig */
135#define HAL_DM_HIPWR_DISABLE BIT(1) /* Disable High Power */
136
137#define TX_HIGHPWR_LEVEL_NORMAL 0
138#define TX_HIGHPWR_LEVEL_NORMAL1 1
139#define TX_HIGHPWR_LEVEL_NORMAL2 2
140
141#define TX_POWER_NEAR_FIELD_THRESH_LVL2 74
142#define TX_POWER_NEAR_FIELD_THRESH_LVL1 67
143
144#define DM_DIG_THRESH_HIGH 40
145#define DM_DIG_THRESH_LOW 35
146#define DM_FALSEALARM_THRESH_LOW 40
147#define DM_FALSEALARM_THRESH_HIGH 1000
148#define DM_DIG_HIGH_PWR_THRESH_HIGH 75
149#define DM_DIG_HIGH_PWR_THRESH_LOW 70
150#define DM_DIG_BACKOFF 12
151#define DM_DIG_MAX 0x3e
152#define DM_DIG_MIN 0x1c
153#define DM_DIG_MIN_Netcore 0x12
154#define DM_DIG_BACKOFF_MAX 12
155#define DM_DIG_BACKOFF_MIN -4
156
157extern struct dig_t digtable;
158
159void rtl92s_dm_watchdog(struct ieee80211_hw *hw);
160void rtl92s_dm_init(struct ieee80211_hw *hw);
161void rtl92s_dm_init_edca_turbo(struct ieee80211_hw *hw);
162
163#endif
164
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/fw.c b/drivers/net/wireless/rtlwifi/rtl8192se/fw.c
new file mode 100644
index 000000000000..3b5af0113d7f
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/fw.c
@@ -0,0 +1,654 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2010 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#include "../wifi.h"
31#include "../pci.h"
32#include "../base.h"
33#include "reg.h"
34#include "def.h"
35#include "fw.h"
36
37static void _rtl92s_fw_set_rqpn(struct ieee80211_hw *hw)
38{
39 struct rtl_priv *rtlpriv = rtl_priv(hw);
40
41 rtl_write_dword(rtlpriv, RQPN, 0xffffffff);
42 rtl_write_dword(rtlpriv, RQPN + 4, 0xffffffff);
43 rtl_write_byte(rtlpriv, RQPN + 8, 0xff);
44 rtl_write_byte(rtlpriv, RQPN + 0xB, 0x80);
45}
46
47static bool _rtl92s_firmware_enable_cpu(struct ieee80211_hw *hw)
48{
49 struct rtl_priv *rtlpriv = rtl_priv(hw);
50 u32 ichecktime = 200;
51 u16 tmpu2b;
52 u8 tmpu1b, cpustatus = 0;
53
54 _rtl92s_fw_set_rqpn(hw);
55
56 /* Enable CPU. */
57 tmpu1b = rtl_read_byte(rtlpriv, SYS_CLKR);
58 /* AFE source */
59 rtl_write_byte(rtlpriv, SYS_CLKR, (tmpu1b | SYS_CPU_CLKSEL));
60
61 tmpu2b = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN);
62 rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, (tmpu2b | FEN_CPUEN));
63
64 /* Polling IMEM Ready after CPU has refilled. */
65 do {
66 cpustatus = rtl_read_byte(rtlpriv, TCR);
67 if (cpustatus & IMEM_RDY) {
68 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
69 ("IMEM Ready after CPU has refilled.\n"));
70 break;
71 }
72
73 udelay(100);
74 } while (ichecktime--);
75
76 if (!(cpustatus & IMEM_RDY))
77 return false;
78
79 return true;
80}
81
82static enum fw_status _rtl92s_firmware_get_nextstatus(
83 enum fw_status fw_currentstatus)
84{
85 enum fw_status next_fwstatus = 0;
86
87 switch (fw_currentstatus) {
88 case FW_STATUS_INIT:
89 next_fwstatus = FW_STATUS_LOAD_IMEM;
90 break;
91 case FW_STATUS_LOAD_IMEM:
92 next_fwstatus = FW_STATUS_LOAD_EMEM;
93 break;
94 case FW_STATUS_LOAD_EMEM:
95 next_fwstatus = FW_STATUS_LOAD_DMEM;
96 break;
97 case FW_STATUS_LOAD_DMEM:
98 next_fwstatus = FW_STATUS_READY;
99 break;
100 default:
101 break;
102 }
103
104 return next_fwstatus;
105}
106
107static u8 _rtl92s_firmware_header_map_rftype(struct ieee80211_hw *hw)
108{
109 struct rtl_priv *rtlpriv = rtl_priv(hw);
110 struct rtl_phy *rtlphy = &(rtlpriv->phy);
111
112 switch (rtlphy->rf_type) {
113 case RF_1T1R:
114 return 0x11;
115 break;
116 case RF_1T2R:
117 return 0x12;
118 break;
119 case RF_2T2R:
120 return 0x22;
121 break;
122 default:
123 RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
124 ("Unknown RF type(%x)\n",
125 rtlphy->rf_type));
126 break;
127 }
128 return 0x22;
129}
130
131static void _rtl92s_firmwareheader_priveupdate(struct ieee80211_hw *hw,
132 struct fw_priv *pfw_priv)
133{
134 /* Update RF types for RATR settings. */
135 pfw_priv->rf_config = _rtl92s_firmware_header_map_rftype(hw);
136}
137
138
139
140static bool _rtl92s_cmd_send_packet(struct ieee80211_hw *hw,
141 struct sk_buff *skb, u8 last)
142{
143 struct rtl_priv *rtlpriv = rtl_priv(hw);
144 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
145 struct rtl8192_tx_ring *ring;
146 struct rtl_tx_desc *pdesc;
147 unsigned long flags;
148 u8 idx = 0;
149
150 ring = &rtlpci->tx_ring[TXCMD_QUEUE];
151
152 spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
153
154 idx = (ring->idx + skb_queue_len(&ring->queue)) % ring->entries;
155 pdesc = &ring->desc[idx];
156 rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *)pdesc, 1, 1, skb);
157 __skb_queue_tail(&ring->queue, skb);
158
159 spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
160
161 return true;
162}
163
164static bool _rtl92s_firmware_downloadcode(struct ieee80211_hw *hw,
165 u8 *code_virtual_address, u32 buffer_len)
166{
167 struct rtl_priv *rtlpriv = rtl_priv(hw);
168 struct sk_buff *skb;
169 struct rtl_tcb_desc *tcb_desc;
170 unsigned char *seg_ptr;
171 u16 frag_threshold = MAX_FIRMWARE_CODE_SIZE;
172 u16 frag_length, frag_offset = 0;
173 u16 extra_descoffset = 0;
174 u8 last_inipkt = 0;
175
176 _rtl92s_fw_set_rqpn(hw);
177
178 if (buffer_len >= MAX_FIRMWARE_CODE_SIZE) {
179 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
180 ("Size over FIRMWARE_CODE_SIZE!\n"));
181
182 return false;
183 }
184
185 extra_descoffset = 0;
186
187 do {
188 if ((buffer_len - frag_offset) > frag_threshold) {
189 frag_length = frag_threshold + extra_descoffset;
190 } else {
191 frag_length = (u16)(buffer_len - frag_offset +
192 extra_descoffset);
193 last_inipkt = 1;
194 }
195
196 /* Allocate skb buffer to contain firmware */
197 /* info and tx descriptor info. */
198 skb = dev_alloc_skb(frag_length);
199 skb_reserve(skb, extra_descoffset);
200 seg_ptr = (u8 *)skb_put(skb, (u32)(frag_length -
201 extra_descoffset));
202 memcpy(seg_ptr, code_virtual_address + frag_offset,
203 (u32)(frag_length - extra_descoffset));
204
205 tcb_desc = (struct rtl_tcb_desc *)(skb->cb);
206 tcb_desc->queue_index = TXCMD_QUEUE;
207 tcb_desc->cmd_or_init = DESC_PACKET_TYPE_INIT;
208 tcb_desc->last_inipkt = last_inipkt;
209
210 _rtl92s_cmd_send_packet(hw, skb, last_inipkt);
211
212 frag_offset += (frag_length - extra_descoffset);
213
214 } while (frag_offset < buffer_len);
215
216 rtl_write_byte(rtlpriv, TP_POLL, TPPOLL_CQ);
217
218 return true ;
219}
220
221static bool _rtl92s_firmware_checkready(struct ieee80211_hw *hw,
222 u8 loadfw_status)
223{
224 struct rtl_priv *rtlpriv = rtl_priv(hw);
225 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
226 struct rt_firmware *firmware = (struct rt_firmware *)rtlhal->pfirmware;
227 u32 tmpu4b;
228 u8 cpustatus = 0;
229 short pollingcnt = 1000;
230 bool rtstatus = true;
231
232 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("LoadStaus(%d)\n",
233 loadfw_status));
234
235 firmware->fwstatus = (enum fw_status)loadfw_status;
236
237 switch (loadfw_status) {
238 case FW_STATUS_LOAD_IMEM:
239 /* Polling IMEM code done. */
240 do {
241 cpustatus = rtl_read_byte(rtlpriv, TCR);
242 if (cpustatus & IMEM_CODE_DONE)
243 break;
244 udelay(5);
245 } while (pollingcnt--);
246
247 if (!(cpustatus & IMEM_CHK_RPT) || (pollingcnt <= 0)) {
248 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
249 ("FW_STATUS_LOAD_IMEM"
250 " FAIL CPU, Status=%x\r\n", cpustatus));
251 goto status_check_fail;
252 }
253 break;
254
255 case FW_STATUS_LOAD_EMEM:
256 /* Check Put Code OK and Turn On CPU */
257 /* Polling EMEM code done. */
258 do {
259 cpustatus = rtl_read_byte(rtlpriv, TCR);
260 if (cpustatus & EMEM_CODE_DONE)
261 break;
262 udelay(5);
263 } while (pollingcnt--);
264
265 if (!(cpustatus & EMEM_CHK_RPT) || (pollingcnt <= 0)) {
266 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
267 ("FW_STATUS_LOAD_EMEM"
268 " FAIL CPU, Status=%x\r\n", cpustatus));
269 goto status_check_fail;
270 }
271
272 /* Turn On CPU */
273 rtstatus = _rtl92s_firmware_enable_cpu(hw);
274 if (rtstatus != true) {
275 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
276 ("Enable CPU fail!\n"));
277 goto status_check_fail;
278 }
279 break;
280
281 case FW_STATUS_LOAD_DMEM:
282 /* Polling DMEM code done */
283 do {
284 cpustatus = rtl_read_byte(rtlpriv, TCR);
285 if (cpustatus & DMEM_CODE_DONE)
286 break;
287 udelay(5);
288 } while (pollingcnt--);
289
290 if (!(cpustatus & DMEM_CODE_DONE) || (pollingcnt <= 0)) {
291 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
292 ("Polling DMEM code done"
293 " fail ! cpustatus(%#x)\n", cpustatus));
294 goto status_check_fail;
295 }
296
297 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
298 ("DMEM code download success,"
299 " cpustatus(%#x)\n", cpustatus));
300
301 /* Prevent Delay too much and being scheduled out */
302 /* Polling Load Firmware ready */
303 pollingcnt = 2000;
304 do {
305 cpustatus = rtl_read_byte(rtlpriv, TCR);
306 if (cpustatus & FWRDY)
307 break;
308 udelay(40);
309 } while (pollingcnt--);
310
311 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
312 ("Polling Load Firmware ready,"
313 " cpustatus(%x)\n", cpustatus));
314
315 if (((cpustatus & LOAD_FW_READY) != LOAD_FW_READY) ||
316 (pollingcnt <= 0)) {
317 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
318 ("Polling Load Firmware"
319 " ready fail ! cpustatus(%x)\n", cpustatus));
320 goto status_check_fail;
321 }
322
323 /* If right here, we can set TCR/RCR to desired value */
324 /* and config MAC lookback mode to normal mode */
325 tmpu4b = rtl_read_dword(rtlpriv, TCR);
326 rtl_write_dword(rtlpriv, TCR, (tmpu4b & (~TCR_ICV)));
327
328 tmpu4b = rtl_read_dword(rtlpriv, RCR);
329 rtl_write_dword(rtlpriv, RCR, (tmpu4b | RCR_APPFCS |
330 RCR_APP_ICV | RCR_APP_MIC));
331
332 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
333 ("Current RCR settings(%#x)\n", tmpu4b));
334
335 /* Set to normal mode. */
336 rtl_write_byte(rtlpriv, LBKMD_SEL, LBK_NORMAL);
337 break;
338
339 default:
340 RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
341 ("Unknown status check!\n"));
342 rtstatus = false;
343 break;
344 }
345
346status_check_fail:
347 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("loadfw_status(%d), "
348 "rtstatus(%x)\n", loadfw_status, rtstatus));
349 return rtstatus;
350}
351
352int rtl92s_download_fw(struct ieee80211_hw *hw)
353{
354 struct rtl_priv *rtlpriv = rtl_priv(hw);
355 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
356 struct rt_firmware *firmware = NULL;
357 struct fw_hdr *pfwheader;
358 struct fw_priv *pfw_priv = NULL;
359 u8 *puc_mappedfile = NULL;
360 u32 ul_filelength = 0;
361 u32 file_length = 0;
362 u8 fwhdr_size = RT_8192S_FIRMWARE_HDR_SIZE;
363 u8 fwstatus = FW_STATUS_INIT;
364 bool rtstatus = true;
365
366 if (!rtlhal->pfirmware)
367 return 1;
368
369 firmware = (struct rt_firmware *)rtlhal->pfirmware;
370 firmware->fwstatus = FW_STATUS_INIT;
371
372 puc_mappedfile = firmware->sz_fw_tmpbuffer;
373 file_length = firmware->sz_fw_tmpbufferlen;
374
375 /* 1. Retrieve FW header. */
376 firmware->pfwheader = (struct fw_hdr *) puc_mappedfile;
377 pfwheader = firmware->pfwheader;
378 firmware->firmwareversion = byte(pfwheader->version, 0);
379 firmware->pfwheader->fwpriv.hci_sel = 1;/* pcie */
380
381 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("signature:%x, version:"
382 "%x, size:%x,"
383 "imemsize:%x, sram size:%x\n", pfwheader->signature,
384 pfwheader->version, pfwheader->dmem_size,
385 pfwheader->img_imem_size, pfwheader->img_sram_size));
386
387 /* 2. Retrieve IMEM image. */
388 if ((pfwheader->img_imem_size == 0) || (pfwheader->img_imem_size >
389 sizeof(firmware->fw_imem))) {
390 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
391 ("memory for data image is less than IMEM required\n"));
392 goto fail;
393 } else {
394 puc_mappedfile += fwhdr_size;
395
396 memcpy(firmware->fw_imem, puc_mappedfile,
397 pfwheader->img_imem_size);
398 firmware->fw_imem_len = pfwheader->img_imem_size;
399 }
400
401 /* 3. Retriecve EMEM image. */
402 if (pfwheader->img_sram_size > sizeof(firmware->fw_emem)) {
403 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
404 ("memory for data image is less than EMEM required\n"));
405 goto fail;
406 } else {
407 puc_mappedfile += firmware->fw_imem_len;
408
409 memcpy(firmware->fw_emem, puc_mappedfile,
410 pfwheader->img_sram_size);
411 firmware->fw_emem_len = pfwheader->img_sram_size;
412 }
413
414 /* 4. download fw now */
415 fwstatus = _rtl92s_firmware_get_nextstatus(firmware->fwstatus);
416 while (fwstatus != FW_STATUS_READY) {
417 /* Image buffer redirection. */
418 switch (fwstatus) {
419 case FW_STATUS_LOAD_IMEM:
420 puc_mappedfile = firmware->fw_imem;
421 ul_filelength = firmware->fw_imem_len;
422 break;
423 case FW_STATUS_LOAD_EMEM:
424 puc_mappedfile = firmware->fw_emem;
425 ul_filelength = firmware->fw_emem_len;
426 break;
427 case FW_STATUS_LOAD_DMEM:
428 /* Partial update the content of header private. */
429 pfwheader = firmware->pfwheader;
430 pfw_priv = &pfwheader->fwpriv;
431 _rtl92s_firmwareheader_priveupdate(hw, pfw_priv);
432 puc_mappedfile = (u8 *)(firmware->pfwheader) +
433 RT_8192S_FIRMWARE_HDR_EXCLUDE_PRI_SIZE;
434 ul_filelength = fwhdr_size -
435 RT_8192S_FIRMWARE_HDR_EXCLUDE_PRI_SIZE;
436 break;
437 default:
438 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
439 ("Unexpected Download step!!\n"));
440 goto fail;
441 break;
442 }
443
444 /* <2> Download image file */
445 rtstatus = _rtl92s_firmware_downloadcode(hw, puc_mappedfile,
446 ul_filelength);
447
448 if (rtstatus != true) {
449 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("fail!\n"));
450 goto fail;
451 }
452
453 /* <3> Check whether load FW process is ready */
454 rtstatus = _rtl92s_firmware_checkready(hw, fwstatus);
455 if (rtstatus != true) {
456 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("fail!\n"));
457 goto fail;
458 }
459
460 fwstatus = _rtl92s_firmware_get_nextstatus(firmware->fwstatus);
461 }
462
463 return rtstatus;
464fail:
465 return 0;
466}
467
468static u32 _rtl92s_fill_h2c_cmd(struct sk_buff *skb, u32 h2cbufferlen,
469 u32 cmd_num, u32 *pelement_id, u32 *pcmd_len,
470 u8 **pcmb_buffer, u8 *cmd_start_seq)
471{
472 u32 totallen = 0, len = 0, tx_desclen = 0;
473 u32 pre_continueoffset = 0;
474 u8 *ph2c_buffer;
475 u8 i = 0;
476
477 do {
478 /* 8 - Byte aligment */
479 len = H2C_TX_CMD_HDR_LEN + N_BYTE_ALIGMENT(pcmd_len[i], 8);
480
481 /* Buffer length is not enough */
482 if (h2cbufferlen < totallen + len + tx_desclen)
483 break;
484
485 /* Clear content */
486 ph2c_buffer = (u8 *)skb_put(skb, (u32)len);
487 memset((ph2c_buffer + totallen + tx_desclen), 0, len);
488
489 /* CMD len */
490 SET_BITS_TO_LE_4BYTE((ph2c_buffer + totallen + tx_desclen),
491 0, 16, pcmd_len[i]);
492
493 /* CMD ID */
494 SET_BITS_TO_LE_4BYTE((ph2c_buffer + totallen + tx_desclen),
495 16, 8, pelement_id[i]);
496
497 /* CMD Sequence */
498 *cmd_start_seq = *cmd_start_seq % 0x80;
499 SET_BITS_TO_LE_4BYTE((ph2c_buffer + totallen + tx_desclen),
500 24, 7, *cmd_start_seq);
501 ++*cmd_start_seq;
502
503 /* Copy memory */
504 memcpy((ph2c_buffer + totallen + tx_desclen +
505 H2C_TX_CMD_HDR_LEN), pcmb_buffer[i], pcmd_len[i]);
506
507 /* CMD continue */
508 /* set the continue in prevoius cmd. */
509 if (i < cmd_num - 1)
510 SET_BITS_TO_LE_4BYTE((ph2c_buffer + pre_continueoffset),
511 31, 1, 1);
512
513 pre_continueoffset = totallen;
514
515 totallen += len;
516 } while (++i < cmd_num);
517
518 return totallen;
519}
520
521static u32 _rtl92s_get_h2c_cmdlen(u32 h2cbufferlen, u32 cmd_num, u32 *pcmd_len)
522{
523 u32 totallen = 0, len = 0, tx_desclen = 0;
524 u8 i = 0;
525
526 do {
527 /* 8 - Byte aligment */
528 len = H2C_TX_CMD_HDR_LEN + N_BYTE_ALIGMENT(pcmd_len[i], 8);
529
530 /* Buffer length is not enough */
531 if (h2cbufferlen < totallen + len + tx_desclen)
532 break;
533
534 totallen += len;
535 } while (++i < cmd_num);
536
537 return totallen + tx_desclen;
538}
539
540static bool _rtl92s_firmware_set_h2c_cmd(struct ieee80211_hw *hw, u8 h2c_cmd,
541 u8 *pcmd_buffer)
542{
543 struct rtl_priv *rtlpriv = rtl_priv(hw);
544 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
545 struct rtl_tcb_desc *cb_desc;
546 struct sk_buff *skb;
547 u32 element_id = 0;
548 u32 cmd_len = 0;
549 u32 len;
550
551 switch (h2c_cmd) {
552 case FW_H2C_SETPWRMODE:
553 element_id = H2C_SETPWRMODE_CMD ;
554 cmd_len = sizeof(struct h2c_set_pwrmode_parm);
555 break;
556 case FW_H2C_JOINBSSRPT:
557 element_id = H2C_JOINBSSRPT_CMD;
558 cmd_len = sizeof(struct h2c_joinbss_rpt_parm);
559 break;
560 case FW_H2C_WOWLAN_UPDATE_GTK:
561 element_id = H2C_WOWLAN_UPDATE_GTK_CMD;
562 cmd_len = sizeof(struct h2c_wpa_two_way_parm);
563 break;
564 case FW_H2C_WOWLAN_UPDATE_IV:
565 element_id = H2C_WOWLAN_UPDATE_IV_CMD;
566 cmd_len = sizeof(unsigned long long);
567 break;
568 case FW_H2C_WOWLAN_OFFLOAD:
569 element_id = H2C_WOWLAN_FW_OFFLOAD;
570 cmd_len = sizeof(u8);
571 break;
572 default:
573 break;
574 }
575
576 len = _rtl92s_get_h2c_cmdlen(MAX_TRANSMIT_BUFFER_SIZE, 1, &cmd_len);
577 skb = dev_alloc_skb(len);
578 cb_desc = (struct rtl_tcb_desc *)(skb->cb);
579 cb_desc->queue_index = TXCMD_QUEUE;
580 cb_desc->cmd_or_init = DESC_PACKET_TYPE_NORMAL;
581 cb_desc->last_inipkt = false;
582
583 _rtl92s_fill_h2c_cmd(skb, MAX_TRANSMIT_BUFFER_SIZE, 1, &element_id,
584 &cmd_len, &pcmd_buffer, &rtlhal->h2c_txcmd_seq);
585 _rtl92s_cmd_send_packet(hw, skb, false);
586 rtlpriv->cfg->ops->tx_polling(hw, TXCMD_QUEUE);
587
588 return true;
589}
590
591void rtl92s_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 Mode)
592{
593 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
594 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
595 struct h2c_set_pwrmode_parm pwrmode;
596 u16 max_wakeup_period = 0;
597
598 pwrmode.mode = Mode;
599 pwrmode.flag_low_traffic_en = 0;
600 pwrmode.flag_lpnav_en = 0;
601 pwrmode.flag_rf_low_snr_en = 0;
602 pwrmode.flag_dps_en = 0;
603 pwrmode.bcn_rx_en = 0;
604 pwrmode.bcn_to = 0;
605 SET_BITS_TO_LE_2BYTE((u8 *)(&pwrmode) + 8, 0, 16,
606 mac->vif->bss_conf.beacon_int);
607 pwrmode.app_itv = 0;
608 pwrmode.awake_bcn_itvl = ppsc->reg_max_lps_awakeintvl;
609 pwrmode.smart_ps = 1;
610 pwrmode.bcn_pass_period = 10;
611
612 /* Set beacon pass count */
613 if (pwrmode.mode == FW_PS_MIN_MODE)
614 max_wakeup_period = mac->vif->bss_conf.beacon_int;
615 else if (pwrmode.mode == FW_PS_MAX_MODE)
616 max_wakeup_period = mac->vif->bss_conf.beacon_int *
617 mac->vif->bss_conf.dtim_period;
618
619 if (max_wakeup_period >= 500)
620 pwrmode.bcn_pass_cnt = 1;
621 else if ((max_wakeup_period >= 300) && (max_wakeup_period < 500))
622 pwrmode.bcn_pass_cnt = 2;
623 else if ((max_wakeup_period >= 200) && (max_wakeup_period < 300))
624 pwrmode.bcn_pass_cnt = 3;
625 else if ((max_wakeup_period >= 20) && (max_wakeup_period < 200))
626 pwrmode.bcn_pass_cnt = 5;
627 else
628 pwrmode.bcn_pass_cnt = 1;
629
630 _rtl92s_firmware_set_h2c_cmd(hw, FW_H2C_SETPWRMODE, (u8 *)&pwrmode);
631
632}
633
634void rtl92s_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw,
635 u8 mstatus, u8 ps_qosinfo)
636{
637 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
638 struct h2c_joinbss_rpt_parm joinbss_rpt;
639
640 joinbss_rpt.opmode = mstatus;
641 joinbss_rpt.ps_qos_info = ps_qosinfo;
642 joinbss_rpt.bssid[0] = mac->bssid[0];
643 joinbss_rpt.bssid[1] = mac->bssid[1];
644 joinbss_rpt.bssid[2] = mac->bssid[2];
645 joinbss_rpt.bssid[3] = mac->bssid[3];
646 joinbss_rpt.bssid[4] = mac->bssid[4];
647 joinbss_rpt.bssid[5] = mac->bssid[5];
648 SET_BITS_TO_LE_2BYTE((u8 *)(&joinbss_rpt) + 8, 0, 16,
649 mac->vif->bss_conf.beacon_int);
650 SET_BITS_TO_LE_2BYTE((u8 *)(&joinbss_rpt) + 10, 0, 16, mac->assoc_id);
651
652 _rtl92s_firmware_set_h2c_cmd(hw, FW_H2C_JOINBSSRPT, (u8 *)&joinbss_rpt);
653}
654
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/fw.h b/drivers/net/wireless/rtlwifi/rtl8192se/fw.h
new file mode 100644
index 000000000000..74cc503efe8a
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/fw.h
@@ -0,0 +1,375 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2010 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29#ifndef __REALTEK_FIRMWARE92S_H__
30#define __REALTEK_FIRMWARE92S_H__
31
32#define RTL8190_MAX_FIRMWARE_CODE_SIZE 64000
33#define RTL8190_CPU_START_OFFSET 0x80
34/* Firmware Local buffer size. 64k */
35#define MAX_FIRMWARE_CODE_SIZE 0xFF00
36
37#define RT_8192S_FIRMWARE_HDR_SIZE 80
38#define RT_8192S_FIRMWARE_HDR_EXCLUDE_PRI_SIZE 32
39
40/* support till 64 bit bus width OS */
41#define MAX_DEV_ADDR_SIZE 8
42#define MAX_FIRMWARE_INFORMATION_SIZE 32
43#define MAX_802_11_HEADER_LENGTH (40 + \
44 MAX_FIRMWARE_INFORMATION_SIZE)
45#define ENCRYPTION_MAX_OVERHEAD 128
46#define MAX_FRAGMENT_COUNT 8
47#define MAX_TRANSMIT_BUFFER_SIZE (1600 + \
48 (MAX_802_11_HEADER_LENGTH + \
49 ENCRYPTION_MAX_OVERHEAD) *\
50 MAX_FRAGMENT_COUNT)
51
52#define H2C_TX_CMD_HDR_LEN 8
53
54/* The following DM control code are for Reg0x364, */
55#define FW_DIG_ENABLE_CTL BIT(0)
56#define FW_HIGH_PWR_ENABLE_CTL BIT(1)
57#define FW_SS_CTL BIT(2)
58#define FW_RA_INIT_CTL BIT(3)
59#define FW_RA_BG_CTL BIT(4)
60#define FW_RA_N_CTL BIT(5)
61#define FW_PWR_TRK_CTL BIT(6)
62#define FW_IQK_CTL BIT(7)
63#define FW_FA_CTL BIT(8)
64#define FW_DRIVER_CTRL_DM_CTL BIT(9)
65#define FW_PAPE_CTL_BY_SW_HW BIT(10)
66#define FW_DISABLE_ALL_DM 0
67#define FW_PWR_TRK_PARAM_CLR 0x0000ffff
68#define FW_RA_PARAM_CLR 0xffff0000
69
70enum desc_packet_type {
71 DESC_PACKET_TYPE_INIT = 0,
72 DESC_PACKET_TYPE_NORMAL = 1,
73};
74
75/* 8-bytes alignment required */
76struct fw_priv {
77 /* --- long word 0 ---- */
78 /* 0x12: CE product, 0x92: IT product */
79 u8 signature_0;
80 /* 0x87: CE product, 0x81: IT product */
81 u8 signature_1;
82 /* 0x81: PCI-AP, 01:PCIe, 02: 92S-U,
83 * 0x82: USB-AP, 0x12: 72S-U, 03:SDIO */
84 u8 hci_sel;
85 /* the same value as reigster value */
86 u8 chip_version;
87 /* customer ID low byte */
88 u8 customer_id_0;
89 /* customer ID high byte */
90 u8 customer_id_1;
91 /* 0x11: 1T1R, 0x12: 1T2R,
92 * 0x92: 1T2R turbo, 0x22: 2T2R */
93 u8 rf_config;
94 /* 4: 4EP, 6: 6EP, 11: 11EP */
95 u8 usb_ep_num;
96
97 /* --- long word 1 ---- */
98 /* regulatory class bit map 0 */
99 u8 regulatory_class_0;
100 /* regulatory class bit map 1 */
101 u8 regulatory_class_1;
102 /* regulatory class bit map 2 */
103 u8 regulatory_class_2;
104 /* regulatory class bit map 3 */
105 u8 regulatory_class_3;
106 /* 0:SWSI, 1:HWSI, 2:HWPI */
107 u8 rfintfs;
108 u8 def_nettype;
109 u8 rsvd010;
110 u8 rsvd011;
111
112 /* --- long word 2 ---- */
113 /* 0x00: normal, 0x03: MACLBK, 0x01: PHYLBK */
114 u8 lbk_mode;
115 /* 1: for MP use, 0: for normal
116 * driver (to be discussed) */
117 u8 mp_mode;
118 u8 rsvd020;
119 u8 rsvd021;
120 u8 rsvd022;
121 u8 rsvd023;
122 u8 rsvd024;
123 u8 rsvd025;
124
125 /* --- long word 3 ---- */
126 /* QoS enable */
127 u8 qos_en;
128 /* 40MHz BW enable */
129 /* 4181 convert AMSDU to AMPDU, 0: disable */
130 u8 bw_40mhz_en;
131 u8 amsdu2ampdu_en;
132 /* 11n AMPDU enable */
133 u8 ampdu_en;
134 /* FW offloads, 0: driver handles */
135 u8 rate_control_offload;
136 /* FW offloads, 0: driver handles */
137 u8 aggregation_offload;
138 u8 rsvd030;
139 u8 rsvd031;
140
141 /* --- long word 4 ---- */
142 /* 1. FW offloads, 0: driver handles */
143 u8 beacon_offload;
144 /* 2. FW offloads, 0: driver handles */
145 u8 mlme_offload;
146 /* 3. FW offloads, 0: driver handles */
147 u8 hwpc_offload;
148 /* 4. FW offloads, 0: driver handles */
149 u8 tcp_checksum_offload;
150 /* 5. FW offloads, 0: driver handles */
151 u8 tcp_offload;
152 /* 6. FW offloads, 0: driver handles */
153 u8 ps_control_offload;
154 /* 7. FW offloads, 0: driver handles */
155 u8 wwlan_offload;
156 u8 rsvd040;
157
158 /* --- long word 5 ---- */
159 /* tcp tx packet length low byte */
160 u8 tcp_tx_frame_len_L;
161 /* tcp tx packet length high byte */
162 u8 tcp_tx_frame_len_H;
163 /* tcp rx packet length low byte */
164 u8 tcp_rx_frame_len_L;
165 /* tcp rx packet length high byte */
166 u8 tcp_rx_frame_len_H;
167 u8 rsvd050;
168 u8 rsvd051;
169 u8 rsvd052;
170 u8 rsvd053;
171};
172
173/* 8-byte alinment required */
174struct fw_hdr {
175
176 /* --- LONG WORD 0 ---- */
177 u16 signature;
178 /* 0x8000 ~ 0x8FFF for FPGA version,
179 * 0x0000 ~ 0x7FFF for ASIC version, */
180 u16 version;
181 /* define the size of boot loader */
182 u32 dmem_size;
183
184
185 /* --- LONG WORD 1 ---- */
186 /* define the size of FW in IMEM */
187 u32 img_imem_size;
188 /* define the size of FW in SRAM */
189 u32 img_sram_size;
190
191 /* --- LONG WORD 2 ---- */
192 /* define the size of DMEM variable */
193 u32 fw_priv_size;
194 u32 rsvd0;
195
196 /* --- LONG WORD 3 ---- */
197 u32 rsvd1;
198 u32 rsvd2;
199
200 struct fw_priv fwpriv;
201
202} ;
203
204enum fw_status {
205 FW_STATUS_INIT = 0,
206 FW_STATUS_LOAD_IMEM = 1,
207 FW_STATUS_LOAD_EMEM = 2,
208 FW_STATUS_LOAD_DMEM = 3,
209 FW_STATUS_READY = 4,
210};
211
212struct rt_firmware {
213 struct fw_hdr *pfwheader;
214 enum fw_status fwstatus;
215 u16 firmwareversion;
216 u8 fw_imem[RTL8190_MAX_FIRMWARE_CODE_SIZE];
217 u8 fw_emem[RTL8190_MAX_FIRMWARE_CODE_SIZE];
218 u32 fw_imem_len;
219 u32 fw_emem_len;
220 u8 sz_fw_tmpbuffer[164000];
221 u32 sz_fw_tmpbufferlen;
222 u16 cmdpacket_fragthresold;
223};
224
225struct h2c_set_pwrmode_parm {
226 u8 mode;
227 u8 flag_low_traffic_en;
228 u8 flag_lpnav_en;
229 u8 flag_rf_low_snr_en;
230 /* 1: dps, 0: 32k */
231 u8 flag_dps_en;
232 u8 bcn_rx_en;
233 u8 bcn_pass_cnt;
234 /* beacon TO (ms). ¡§=0¡¨ no limit. */
235 u8 bcn_to;
236 u16 bcn_itv;
237 /* only for VOIP mode. */
238 u8 app_itv;
239 u8 awake_bcn_itvl;
240 u8 smart_ps;
241 /* unit: 100 ms */
242 u8 bcn_pass_period;
243};
244
245struct h2c_joinbss_rpt_parm {
246 u8 opmode;
247 u8 ps_qos_info;
248 u8 bssid[6];
249 u16 bcnitv;
250 u16 aid;
251} ;
252
253struct h2c_wpa_ptk {
254 /* EAPOL-Key Key Confirmation Key (KCK) */
255 u8 kck[16];
256 /* EAPOL-Key Key Encryption Key (KEK) */
257 u8 kek[16];
258 /* Temporal Key 1 (TK1) */
259 u8 tk1[16];
260 union {
261 /* Temporal Key 2 (TK2) */
262 u8 tk2[16];
263 struct {
264 u8 tx_mic_key[8];
265 u8 rx_mic_key[8];
266 } athu;
267 } u;
268};
269
270struct h2c_wpa_two_way_parm {
271 /* algorithm TKIP or AES */
272 u8 pairwise_en_alg;
273 u8 group_en_alg;
274 struct h2c_wpa_ptk wpa_ptk_value;
275} ;
276
277enum h2c_cmd {
278 FW_H2C_SETPWRMODE = 0,
279 FW_H2C_JOINBSSRPT = 1,
280 FW_H2C_WOWLAN_UPDATE_GTK = 2,
281 FW_H2C_WOWLAN_UPDATE_IV = 3,
282 FW_H2C_WOWLAN_OFFLOAD = 4,
283};
284
285enum fw_h2c_cmd {
286 H2C_READ_MACREG_CMD, /*0*/
287 H2C_WRITE_MACREG_CMD,
288 H2C_READBB_CMD,
289 H2C_WRITEBB_CMD,
290 H2C_READRF_CMD,
291 H2C_WRITERF_CMD, /*5*/
292 H2C_READ_EEPROM_CMD,
293 H2C_WRITE_EEPROM_CMD,
294 H2C_READ_EFUSE_CMD,
295 H2C_WRITE_EFUSE_CMD,
296 H2C_READ_CAM_CMD, /*10*/
297 H2C_WRITE_CAM_CMD,
298 H2C_SETBCNITV_CMD,
299 H2C_SETMBIDCFG_CMD,
300 H2C_JOINBSS_CMD,
301 H2C_DISCONNECT_CMD, /*15*/
302 H2C_CREATEBSS_CMD,
303 H2C_SETOPMode_CMD,
304 H2C_SITESURVEY_CMD,
305 H2C_SETAUTH_CMD,
306 H2C_SETKEY_CMD, /*20*/
307 H2C_SETSTAKEY_CMD,
308 H2C_SETASSOCSTA_CMD,
309 H2C_DELASSOCSTA_CMD,
310 H2C_SETSTAPWRSTATE_CMD,
311 H2C_SETBASICRATE_CMD, /*25*/
312 H2C_GETBASICRATE_CMD,
313 H2C_SETDATARATE_CMD,
314 H2C_GETDATARATE_CMD,
315 H2C_SETPHYINFO_CMD,
316 H2C_GETPHYINFO_CMD, /*30*/
317 H2C_SETPHY_CMD,
318 H2C_GETPHY_CMD,
319 H2C_READRSSI_CMD,
320 H2C_READGAIN_CMD,
321 H2C_SETATIM_CMD, /*35*/
322 H2C_SETPWRMODE_CMD,
323 H2C_JOINBSSRPT_CMD,
324 H2C_SETRATABLE_CMD,
325 H2C_GETRATABLE_CMD,
326 H2C_GETCCXREPORT_CMD, /*40*/
327 H2C_GETDTMREPORT_CMD,
328 H2C_GETTXRATESTATICS_CMD,
329 H2C_SETUSBSUSPEND_CMD,
330 H2C_SETH2CLBK_CMD,
331 H2C_TMP1, /*45*/
332 H2C_WOWLAN_UPDATE_GTK_CMD,
333 H2C_WOWLAN_FW_OFFLOAD,
334 H2C_TMP2,
335 H2C_TMP3,
336 H2C_WOWLAN_UPDATE_IV_CMD, /*50*/
337 H2C_TMP4,
338 MAX_H2CCMD /*52*/
339};
340
341/* The following macros are used for FW
342 * CMD map and parameter updated. */
343#define FW_CMD_IO_CLR(rtlpriv, _Bit) \
344 do { \
345 udelay(1000); \
346 rtlpriv->rtlhal.fwcmd_iomap &= (~_Bit); \
347 } while (0);
348
349#define FW_CMD_IO_UPDATE(rtlpriv, _val) \
350 rtlpriv->rtlhal.fwcmd_iomap = _val;
351
352#define FW_CMD_IO_SET(rtlpriv, _val) \
353 do { \
354 rtl_write_word(rtlpriv, LBUS_MON_ADDR, (u16)_val); \
355 FW_CMD_IO_UPDATE(rtlpriv, _val); \
356 } while (0);
357
358#define FW_CMD_PARA_SET(rtlpriv, _val) \
359 do { \
360 rtl_write_dword(rtlpriv, LBUS_ADDR_MASK, _val); \
361 rtlpriv->rtlhal.fwcmd_ioparam = _val; \
362 } while (0);
363
364#define FW_CMD_IO_QUERY(rtlpriv) \
365 (u16)(rtlpriv->rtlhal.fwcmd_iomap)
366#define FW_CMD_IO_PARA_QUERY(rtlpriv) \
367 ((u32)(rtlpriv->rtlhal.fwcmd_ioparam))
368
369int rtl92s_download_fw(struct ieee80211_hw *hw);
370void rtl92s_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode);
371void rtl92s_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw,
372 u8 mstatus, u8 ps_qosinfo);
373
374#endif
375
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c
new file mode 100644
index 000000000000..2e9005d0454b
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c
@@ -0,0 +1,2512 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2010 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#include "../wifi.h"
31#include "../efuse.h"
32#include "../base.h"
33#include "../regd.h"
34#include "../cam.h"
35#include "../ps.h"
36#include "../pci.h"
37#include "reg.h"
38#include "def.h"
39#include "phy.h"
40#include "dm.h"
41#include "fw.h"
42#include "led.h"
43#include "hw.h"
44
45void rtl92se_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
46{
47 struct rtl_priv *rtlpriv = rtl_priv(hw);
48 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
49 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
50
51 switch (variable) {
52 case HW_VAR_RCR: {
53 *((u32 *) (val)) = rtlpci->receive_config;
54 break;
55 }
56 case HW_VAR_RF_STATE: {
57 *((enum rf_pwrstate *)(val)) = ppsc->rfpwr_state;
58 break;
59 }
60 case HW_VAR_FW_PSMODE_STATUS: {
61 *((bool *) (val)) = ppsc->fw_current_inpsmode;
62 break;
63 }
64 case HW_VAR_CORRECT_TSF: {
65 u64 tsf;
66 u32 *ptsf_low = (u32 *)&tsf;
67 u32 *ptsf_high = ((u32 *)&tsf) + 1;
68
69 *ptsf_high = rtl_read_dword(rtlpriv, (TSFR + 4));
70 *ptsf_low = rtl_read_dword(rtlpriv, TSFR);
71
72 *((u64 *) (val)) = tsf;
73
74 break;
75 }
76 case HW_VAR_MRC: {
77 *((bool *)(val)) = rtlpriv->dm.current_mrc_switch;
78 break;
79 }
80 default: {
81 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
82 ("switch case not process\n"));
83 break;
84 }
85 }
86}
87
88void rtl92se_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
89{
90 struct rtl_priv *rtlpriv = rtl_priv(hw);
91 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
92 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
93 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
94 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
95 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
96
97 switch (variable) {
98 case HW_VAR_ETHER_ADDR:{
99 rtl_write_dword(rtlpriv, IDR0, ((u32 *)(val))[0]);
100 rtl_write_word(rtlpriv, IDR4, ((u16 *)(val + 4))[0]);
101 break;
102 }
103 case HW_VAR_BASIC_RATE:{
104 u16 rate_cfg = ((u16 *) val)[0];
105 u8 rate_index = 0;
106
107 if (rtlhal->version == VERSION_8192S_ACUT)
108 rate_cfg = rate_cfg & 0x150;
109 else
110 rate_cfg = rate_cfg & 0x15f;
111
112 rate_cfg |= 0x01;
113
114 rtl_write_byte(rtlpriv, RRSR, rate_cfg & 0xff);
115 rtl_write_byte(rtlpriv, RRSR + 1,
116 (rate_cfg >> 8) & 0xff);
117
118 while (rate_cfg > 0x1) {
119 rate_cfg = (rate_cfg >> 1);
120 rate_index++;
121 }
122 rtl_write_byte(rtlpriv, INIRTSMCS_SEL, rate_index);
123
124 break;
125 }
126 case HW_VAR_BSSID:{
127 rtl_write_dword(rtlpriv, BSSIDR, ((u32 *)(val))[0]);
128 rtl_write_word(rtlpriv, BSSIDR + 4,
129 ((u16 *)(val + 4))[0]);
130 break;
131 }
132 case HW_VAR_SIFS:{
133 rtl_write_byte(rtlpriv, SIFS_OFDM, val[0]);
134 rtl_write_byte(rtlpriv, SIFS_OFDM + 1, val[1]);
135 break;
136 }
137 case HW_VAR_SLOT_TIME:{
138 u8 e_aci;
139
140 RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
141 ("HW_VAR_SLOT_TIME %x\n", val[0]));
142
143 rtl_write_byte(rtlpriv, SLOT_TIME, val[0]);
144
145 for (e_aci = 0; e_aci < AC_MAX; e_aci++) {
146 rtlpriv->cfg->ops->set_hw_reg(hw,
147 HW_VAR_AC_PARAM,
148 (u8 *)(&e_aci));
149 }
150 break;
151 }
152 case HW_VAR_ACK_PREAMBLE:{
153 u8 reg_tmp;
154 u8 short_preamble = (bool) (*(u8 *) val);
155 reg_tmp = (mac->cur_40_prime_sc) << 5;
156 if (short_preamble)
157 reg_tmp |= 0x80;
158
159 rtl_write_byte(rtlpriv, RRSR + 2, reg_tmp);
160 break;
161 }
162 case HW_VAR_AMPDU_MIN_SPACE:{
163 u8 min_spacing_to_set;
164 u8 sec_min_space;
165
166 min_spacing_to_set = *((u8 *)val);
167 if (min_spacing_to_set <= 7) {
168 if (rtlpriv->sec.pairwise_enc_algorithm ==
169 NO_ENCRYPTION)
170 sec_min_space = 0;
171 else
172 sec_min_space = 1;
173
174 if (min_spacing_to_set < sec_min_space)
175 min_spacing_to_set = sec_min_space;
176 if (min_spacing_to_set > 5)
177 min_spacing_to_set = 5;
178
179 mac->min_space_cfg =
180 ((mac->min_space_cfg & 0xf8) |
181 min_spacing_to_set);
182
183 *val = min_spacing_to_set;
184
185 RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
186 ("Set HW_VAR_AMPDU_MIN_SPACE: %#x\n",
187 mac->min_space_cfg));
188
189 rtl_write_byte(rtlpriv, AMPDU_MIN_SPACE,
190 mac->min_space_cfg);
191 }
192 break;
193 }
194 case HW_VAR_SHORTGI_DENSITY:{
195 u8 density_to_set;
196
197 density_to_set = *((u8 *) val);
198 mac->min_space_cfg = rtlpriv->rtlhal.minspace_cfg;
199 mac->min_space_cfg |= (density_to_set << 3);
200
201 RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
202 ("Set HW_VAR_SHORTGI_DENSITY: %#x\n",
203 mac->min_space_cfg));
204
205 rtl_write_byte(rtlpriv, AMPDU_MIN_SPACE,
206 mac->min_space_cfg);
207
208 break;
209 }
210 case HW_VAR_AMPDU_FACTOR:{
211 u8 factor_toset;
212 u8 regtoset;
213 u8 factorlevel[18] = {
214 2, 4, 4, 7, 7, 13, 13,
215 13, 2, 7, 7, 13, 13,
216 15, 15, 15, 15, 0};
217 u8 index = 0;
218
219 factor_toset = *((u8 *) val);
220 if (factor_toset <= 3) {
221 factor_toset = (1 << (factor_toset + 2));
222 if (factor_toset > 0xf)
223 factor_toset = 0xf;
224
225 for (index = 0; index < 17; index++) {
226 if (factorlevel[index] > factor_toset)
227 factorlevel[index] =
228 factor_toset;
229 }
230
231 for (index = 0; index < 8; index++) {
232 regtoset = ((factorlevel[index * 2]) |
233 (factorlevel[index *
234 2 + 1] << 4));
235 rtl_write_byte(rtlpriv,
236 AGGLEN_LMT_L + index,
237 regtoset);
238 }
239
240 regtoset = ((factorlevel[16]) |
241 (factorlevel[17] << 4));
242 rtl_write_byte(rtlpriv, AGGLEN_LMT_H, regtoset);
243
244 RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
245 ("Set HW_VAR_AMPDU_FACTOR: %#x\n",
246 factor_toset));
247 }
248 break;
249 }
250 case HW_VAR_AC_PARAM:{
251 u8 e_aci = *((u8 *) val);
252 rtl92s_dm_init_edca_turbo(hw);
253
254 if (rtlpci->acm_method != eAcmWay2_SW)
255 rtlpriv->cfg->ops->set_hw_reg(hw,
256 HW_VAR_ACM_CTRL,
257 (u8 *)(&e_aci));
258 break;
259 }
260 case HW_VAR_ACM_CTRL:{
261 u8 e_aci = *((u8 *) val);
262 union aci_aifsn *p_aci_aifsn = (union aci_aifsn *)(&(
263 mac->ac[0].aifs));
264 u8 acm = p_aci_aifsn->f.acm;
265 u8 acm_ctrl = rtl_read_byte(rtlpriv, AcmHwCtrl);
266
267 acm_ctrl = acm_ctrl | ((rtlpci->acm_method == 2) ?
268 0x0 : 0x1);
269
270 if (acm) {
271 switch (e_aci) {
272 case AC0_BE:
273 acm_ctrl |= AcmHw_BeqEn;
274 break;
275 case AC2_VI:
276 acm_ctrl |= AcmHw_ViqEn;
277 break;
278 case AC3_VO:
279 acm_ctrl |= AcmHw_VoqEn;
280 break;
281 default:
282 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
283 ("HW_VAR_ACM_CTRL acm set "
284 "failed: eACI is %d\n", acm));
285 break;
286 }
287 } else {
288 switch (e_aci) {
289 case AC0_BE:
290 acm_ctrl &= (~AcmHw_BeqEn);
291 break;
292 case AC2_VI:
293 acm_ctrl &= (~AcmHw_ViqEn);
294 break;
295 case AC3_VO:
296 acm_ctrl &= (~AcmHw_BeqEn);
297 break;
298 default:
299 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
300 ("switch case not process\n"));
301 break;
302 }
303 }
304
305 RT_TRACE(rtlpriv, COMP_QOS, DBG_TRACE,
306 ("HW_VAR_ACM_CTRL Write 0x%X\n", acm_ctrl));
307 rtl_write_byte(rtlpriv, AcmHwCtrl, acm_ctrl);
308 break;
309 }
310 case HW_VAR_RCR:{
311 rtl_write_dword(rtlpriv, RCR, ((u32 *) (val))[0]);
312 rtlpci->receive_config = ((u32 *) (val))[0];
313 break;
314 }
315 case HW_VAR_RETRY_LIMIT:{
316 u8 retry_limit = ((u8 *) (val))[0];
317
318 rtl_write_word(rtlpriv, RETRY_LIMIT,
319 retry_limit << RETRY_LIMIT_SHORT_SHIFT |
320 retry_limit << RETRY_LIMIT_LONG_SHIFT);
321 break;
322 }
323 case HW_VAR_DUAL_TSF_RST: {
324 break;
325 }
326 case HW_VAR_EFUSE_BYTES: {
327 rtlefuse->efuse_usedbytes = *((u16 *) val);
328 break;
329 }
330 case HW_VAR_EFUSE_USAGE: {
331 rtlefuse->efuse_usedpercentage = *((u8 *) val);
332 break;
333 }
334 case HW_VAR_IO_CMD: {
335 break;
336 }
337 case HW_VAR_WPA_CONFIG: {
338 rtl_write_byte(rtlpriv, REG_SECR, *((u8 *) val));
339 break;
340 }
341 case HW_VAR_SET_RPWM:{
342 break;
343 }
344 case HW_VAR_H2C_FW_PWRMODE:{
345 break;
346 }
347 case HW_VAR_FW_PSMODE_STATUS: {
348 ppsc->fw_current_inpsmode = *((bool *) val);
349 break;
350 }
351 case HW_VAR_H2C_FW_JOINBSSRPT:{
352 break;
353 }
354 case HW_VAR_AID:{
355 break;
356 }
357 case HW_VAR_CORRECT_TSF:{
358 break;
359 }
360 case HW_VAR_MRC: {
361 bool bmrc_toset = *((bool *)val);
362 u8 u1bdata = 0;
363
364 if (bmrc_toset) {
365 rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE,
366 MASKBYTE0, 0x33);
367 u1bdata = (u8)rtl_get_bbreg(hw,
368 ROFDM1_TRXPATHENABLE,
369 MASKBYTE0);
370 rtl_set_bbreg(hw, ROFDM1_TRXPATHENABLE,
371 MASKBYTE0,
372 ((u1bdata & 0xf0) | 0x03));
373 u1bdata = (u8)rtl_get_bbreg(hw,
374 ROFDM0_TRXPATHENABLE,
375 MASKBYTE1);
376 rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE,
377 MASKBYTE1,
378 (u1bdata | 0x04));
379
380 /* Update current settings. */
381 rtlpriv->dm.current_mrc_switch = bmrc_toset;
382 } else {
383 rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE,
384 MASKBYTE0, 0x13);
385 u1bdata = (u8)rtl_get_bbreg(hw,
386 ROFDM1_TRXPATHENABLE,
387 MASKBYTE0);
388 rtl_set_bbreg(hw, ROFDM1_TRXPATHENABLE,
389 MASKBYTE0,
390 ((u1bdata & 0xf0) | 0x01));
391 u1bdata = (u8)rtl_get_bbreg(hw,
392 ROFDM0_TRXPATHENABLE,
393 MASKBYTE1);
394 rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE,
395 MASKBYTE1, (u1bdata & 0xfb));
396
397 /* Update current settings. */
398 rtlpriv->dm.current_mrc_switch = bmrc_toset;
399 }
400
401 break;
402 }
403 default:
404 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
405 ("switch case not process\n"));
406 break;
407 }
408
409}
410
411void rtl92se_enable_hw_security_config(struct ieee80211_hw *hw)
412{
413 struct rtl_priv *rtlpriv = rtl_priv(hw);
414 u8 sec_reg_value = 0x0;
415
416 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("PairwiseEncAlgorithm = %d "
417 "GroupEncAlgorithm = %d\n",
418 rtlpriv->sec.pairwise_enc_algorithm,
419 rtlpriv->sec.group_enc_algorithm));
420
421 if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) {
422 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
423 ("not open hw encryption\n"));
424 return;
425 }
426
427 sec_reg_value = SCR_TXENCENABLE | SCR_RXENCENABLE;
428
429 if (rtlpriv->sec.use_defaultkey) {
430 sec_reg_value |= SCR_TXUSEDK;
431 sec_reg_value |= SCR_RXUSEDK;
432 }
433
434 RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, ("The SECR-value %x\n",
435 sec_reg_value));
436
437 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value);
438
439}
440
441static u8 _rtl92ce_halset_sysclk(struct ieee80211_hw *hw, u8 data)
442{
443 struct rtl_priv *rtlpriv = rtl_priv(hw);
444 u8 waitcount = 100;
445 bool bresult = false;
446 u8 tmpvalue;
447
448 rtl_write_byte(rtlpriv, SYS_CLKR + 1, data);
449
450 /* Wait the MAC synchronized. */
451 udelay(400);
452
453 /* Check if it is set ready. */
454 tmpvalue = rtl_read_byte(rtlpriv, SYS_CLKR + 1);
455 bresult = ((tmpvalue & BIT(7)) == (data & BIT(7)));
456
457 if ((data & (BIT(6) | BIT(7))) == false) {
458 waitcount = 100;
459 tmpvalue = 0;
460
461 while (1) {
462 waitcount--;
463
464 tmpvalue = rtl_read_byte(rtlpriv, SYS_CLKR + 1);
465 if ((tmpvalue & BIT(6)))
466 break;
467
468 printk(KERN_ERR "wait for BIT(6) return value %x\n",
469 tmpvalue);
470 if (waitcount == 0)
471 break;
472
473 udelay(10);
474 }
475
476 if (waitcount == 0)
477 bresult = false;
478 else
479 bresult = true;
480 }
481
482 return bresult;
483}
484
485void rtl8192se_gpiobit3_cfg_inputmode(struct ieee80211_hw *hw)
486{
487 struct rtl_priv *rtlpriv = rtl_priv(hw);
488 u8 u1tmp;
489
490 /* The following config GPIO function */
491 rtl_write_byte(rtlpriv, MAC_PINMUX_CFG, (GPIOMUX_EN | GPIOSEL_GPIO));
492 u1tmp = rtl_read_byte(rtlpriv, GPIO_IO_SEL);
493
494 /* config GPIO3 to input */
495 u1tmp &= HAL_8192S_HW_GPIO_OFF_MASK;
496 rtl_write_byte(rtlpriv, GPIO_IO_SEL, u1tmp);
497
498}
499
500static u8 _rtl92se_rf_onoff_detect(struct ieee80211_hw *hw)
501{
502 struct rtl_priv *rtlpriv = rtl_priv(hw);
503 u8 u1tmp;
504 u8 retval = ERFON;
505
506 /* The following config GPIO function */
507 rtl_write_byte(rtlpriv, MAC_PINMUX_CFG, (GPIOMUX_EN | GPIOSEL_GPIO));
508 u1tmp = rtl_read_byte(rtlpriv, GPIO_IO_SEL);
509
510 /* config GPIO3 to input */
511 u1tmp &= HAL_8192S_HW_GPIO_OFF_MASK;
512 rtl_write_byte(rtlpriv, GPIO_IO_SEL, u1tmp);
513
514 /* On some of the platform, driver cannot read correct
515 * value without delay between Write_GPIO_SEL and Read_GPIO_IN */
516 mdelay(10);
517
518 /* check GPIO3 */
519 u1tmp = rtl_read_byte(rtlpriv, GPIO_IN);
520 retval = (u1tmp & HAL_8192S_HW_GPIO_OFF_BIT) ? ERFON : ERFOFF;
521
522 return retval;
523}
524
525static void _rtl92se_macconfig_before_fwdownload(struct ieee80211_hw *hw)
526{
527 struct rtl_priv *rtlpriv = rtl_priv(hw);
528 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
529 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
530
531 u8 i;
532 u8 tmpu1b;
533 u16 tmpu2b;
534 u8 pollingcnt = 20;
535
536 if (rtlpci->first_init) {
537 /* Reset PCIE Digital */
538 tmpu1b = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
539 tmpu1b &= 0xFE;
540 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmpu1b);
541 udelay(1);
542 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmpu1b | BIT(0));
543 }
544
545 /* Switch to SW IO control */
546 tmpu1b = rtl_read_byte(rtlpriv, (SYS_CLKR + 1));
547 if (tmpu1b & BIT(7)) {
548 tmpu1b &= ~(BIT(6) | BIT(7));
549
550 /* Set failed, return to prevent hang. */
551 if (!_rtl92ce_halset_sysclk(hw, tmpu1b))
552 return;
553 }
554
555 rtl_write_byte(rtlpriv, AFE_PLL_CTRL, 0x0);
556 udelay(50);
557 rtl_write_byte(rtlpriv, LDOA15_CTRL, 0x34);
558 udelay(50);
559
560 /* Clear FW RPWM for FW control LPS.*/
561 rtl_write_byte(rtlpriv, RPWM, 0x0);
562
563 /* Reset MAC-IO and CPU and Core Digital BIT(10)/11/15 */
564 tmpu1b = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
565 tmpu1b &= 0x73;
566 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmpu1b);
567 /* wait for BIT 10/11/15 to pull high automatically!! */
568 mdelay(1);
569
570 rtl_write_byte(rtlpriv, CMDR, 0);
571 rtl_write_byte(rtlpriv, TCR, 0);
572
573 /* Data sheet not define 0x562!!! Copy from WMAC!!!!! */
574 tmpu1b = rtl_read_byte(rtlpriv, 0x562);
575 tmpu1b |= 0x08;
576 rtl_write_byte(rtlpriv, 0x562, tmpu1b);
577 tmpu1b &= ~(BIT(3));
578 rtl_write_byte(rtlpriv, 0x562, tmpu1b);
579
580 /* Enable AFE clock source */
581 tmpu1b = rtl_read_byte(rtlpriv, AFE_XTAL_CTRL);
582 rtl_write_byte(rtlpriv, AFE_XTAL_CTRL, (tmpu1b | 0x01));
583 /* Delay 1.5ms */
584 mdelay(2);
585 tmpu1b = rtl_read_byte(rtlpriv, AFE_XTAL_CTRL + 1);
586 rtl_write_byte(rtlpriv, AFE_XTAL_CTRL + 1, (tmpu1b & 0xfb));
587
588 /* Enable AFE Macro Block's Bandgap */
589 tmpu1b = rtl_read_byte(rtlpriv, AFE_MISC);
590 rtl_write_byte(rtlpriv, AFE_MISC, (tmpu1b | BIT(0)));
591 mdelay(1);
592
593 /* Enable AFE Mbias */
594 tmpu1b = rtl_read_byte(rtlpriv, AFE_MISC);
595 rtl_write_byte(rtlpriv, AFE_MISC, (tmpu1b | 0x02));
596 mdelay(1);
597
598 /* Enable LDOA15 block */
599 tmpu1b = rtl_read_byte(rtlpriv, LDOA15_CTRL);
600 rtl_write_byte(rtlpriv, LDOA15_CTRL, (tmpu1b | BIT(0)));
601
602 /* Set Digital Vdd to Retention isolation Path. */
603 tmpu2b = rtl_read_word(rtlpriv, REG_SYS_ISO_CTRL);
604 rtl_write_word(rtlpriv, REG_SYS_ISO_CTRL, (tmpu2b | BIT(11)));
605
606 /* For warm reboot NIC disappera bug. */
607 tmpu2b = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN);
608 rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, (tmpu2b | BIT(13)));
609
610 rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL + 1, 0x68);
611
612 /* Enable AFE PLL Macro Block */
613 /* We need to delay 100u before enabling PLL. */
614 udelay(200);
615 tmpu1b = rtl_read_byte(rtlpriv, AFE_PLL_CTRL);
616 rtl_write_byte(rtlpriv, AFE_PLL_CTRL, (tmpu1b | BIT(0) | BIT(4)));
617
618 /* for divider reset */
619 udelay(100);
620 rtl_write_byte(rtlpriv, AFE_PLL_CTRL, (tmpu1b | BIT(0) |
621 BIT(4) | BIT(6)));
622 udelay(10);
623 rtl_write_byte(rtlpriv, AFE_PLL_CTRL, (tmpu1b | BIT(0) | BIT(4)));
624 udelay(10);
625
626 /* Enable MAC 80MHZ clock */
627 tmpu1b = rtl_read_byte(rtlpriv, AFE_PLL_CTRL + 1);
628 rtl_write_byte(rtlpriv, AFE_PLL_CTRL + 1, (tmpu1b | BIT(0)));
629 mdelay(1);
630
631 /* Release isolation AFE PLL & MD */
632 rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL, 0xA6);
633
634 /* Enable MAC clock */
635 tmpu2b = rtl_read_word(rtlpriv, SYS_CLKR);
636 rtl_write_word(rtlpriv, SYS_CLKR, (tmpu2b | BIT(12) | BIT(11)));
637
638 /* Enable Core digital and enable IOREG R/W */
639 tmpu2b = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN);
640 rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, (tmpu2b | BIT(11)));
641
642 tmpu1b = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
643 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmpu1b & ~(BIT(7)));
644
645 /* enable REG_EN */
646 rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, (tmpu2b | BIT(11) | BIT(15)));
647
648 /* Switch the control path. */
649 tmpu2b = rtl_read_word(rtlpriv, SYS_CLKR);
650 rtl_write_word(rtlpriv, SYS_CLKR, (tmpu2b & (~BIT(2))));
651
652 tmpu1b = rtl_read_byte(rtlpriv, (SYS_CLKR + 1));
653 tmpu1b = ((tmpu1b | BIT(7)) & (~BIT(6)));
654 if (!_rtl92ce_halset_sysclk(hw, tmpu1b))
655 return; /* Set failed, return to prevent hang. */
656
657 rtl_write_word(rtlpriv, CMDR, 0x07FC);
658
659 /* MH We must enable the section of code to prevent load IMEM fail. */
660 /* Load MAC register from WMAc temporarily We simulate macreg. */
661 /* txt HW will provide MAC txt later */
662 rtl_write_byte(rtlpriv, 0x6, 0x30);
663 rtl_write_byte(rtlpriv, 0x49, 0xf0);
664
665 rtl_write_byte(rtlpriv, 0x4b, 0x81);
666
667 rtl_write_byte(rtlpriv, 0xb5, 0x21);
668
669 rtl_write_byte(rtlpriv, 0xdc, 0xff);
670 rtl_write_byte(rtlpriv, 0xdd, 0xff);
671 rtl_write_byte(rtlpriv, 0xde, 0xff);
672 rtl_write_byte(rtlpriv, 0xdf, 0xff);
673
674 rtl_write_byte(rtlpriv, 0x11a, 0x00);
675 rtl_write_byte(rtlpriv, 0x11b, 0x00);
676
677 for (i = 0; i < 32; i++)
678 rtl_write_byte(rtlpriv, INIMCS_SEL + i, 0x1b);
679
680 rtl_write_byte(rtlpriv, 0x236, 0xff);
681
682 rtl_write_byte(rtlpriv, 0x503, 0x22);
683
684 if (ppsc->support_aspm && !ppsc->support_backdoor)
685 rtl_write_byte(rtlpriv, 0x560, 0x40);
686 else
687 rtl_write_byte(rtlpriv, 0x560, 0x00);
688
689 rtl_write_byte(rtlpriv, DBG_PORT, 0x91);
690
691 /* Set RX Desc Address */
692 rtl_write_dword(rtlpriv, RDQDA, rtlpci->rx_ring[RX_MPDU_QUEUE].dma);
693 rtl_write_dword(rtlpriv, RCDA, rtlpci->rx_ring[RX_CMD_QUEUE].dma);
694
695 /* Set TX Desc Address */
696 rtl_write_dword(rtlpriv, TBKDA, rtlpci->tx_ring[BK_QUEUE].dma);
697 rtl_write_dword(rtlpriv, TBEDA, rtlpci->tx_ring[BE_QUEUE].dma);
698 rtl_write_dword(rtlpriv, TVIDA, rtlpci->tx_ring[VI_QUEUE].dma);
699 rtl_write_dword(rtlpriv, TVODA, rtlpci->tx_ring[VO_QUEUE].dma);
700 rtl_write_dword(rtlpriv, TBDA, rtlpci->tx_ring[BEACON_QUEUE].dma);
701 rtl_write_dword(rtlpriv, TCDA, rtlpci->tx_ring[TXCMD_QUEUE].dma);
702 rtl_write_dword(rtlpriv, TMDA, rtlpci->tx_ring[MGNT_QUEUE].dma);
703 rtl_write_dword(rtlpriv, THPDA, rtlpci->tx_ring[HIGH_QUEUE].dma);
704 rtl_write_dword(rtlpriv, HDA, rtlpci->tx_ring[HCCA_QUEUE].dma);
705
706 rtl_write_word(rtlpriv, CMDR, 0x37FC);
707
708 /* To make sure that TxDMA can ready to download FW. */
709 /* We should reset TxDMA if IMEM RPT was not ready. */
710 do {
711 tmpu1b = rtl_read_byte(rtlpriv, TCR);
712 if ((tmpu1b & TXDMA_INIT_VALUE) == TXDMA_INIT_VALUE)
713 break;
714
715 udelay(5);
716 } while (pollingcnt--);
717
718 if (pollingcnt <= 0) {
719 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
720 ("Polling TXDMA_INIT_VALUE "
721 "timeout!! Current TCR(%#x)\n", tmpu1b));
722 tmpu1b = rtl_read_byte(rtlpriv, CMDR);
723 rtl_write_byte(rtlpriv, CMDR, tmpu1b & (~TXDMA_EN));
724 udelay(2);
725 /* Reset TxDMA */
726 rtl_write_byte(rtlpriv, CMDR, tmpu1b | TXDMA_EN);
727 }
728
729 /* After MACIO reset,we must refresh LED state. */
730 if ((ppsc->rfoff_reason == RF_CHANGE_BY_IPS) ||
731 (ppsc->rfoff_reason == 0)) {
732 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
733 struct rtl_led *pLed0 = &(pcipriv->ledctl.sw_led0);
734 enum rf_pwrstate rfpwr_state_toset;
735 rfpwr_state_toset = _rtl92se_rf_onoff_detect(hw);
736
737 if (rfpwr_state_toset == ERFON)
738 rtl92se_sw_led_on(hw, pLed0);
739 }
740}
741
742static void _rtl92se_macconfig_after_fwdownload(struct ieee80211_hw *hw)
743{
744 struct rtl_priv *rtlpriv = rtl_priv(hw);
745 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
746 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
747 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
748 u8 i;
749 u16 tmpu2b;
750
751 /* 1. System Configure Register (Offset: 0x0000 - 0x003F) */
752
753 /* 2. Command Control Register (Offset: 0x0040 - 0x004F) */
754 /* Turn on 0x40 Command register */
755 rtl_write_word(rtlpriv, CMDR, (BBRSTN | BB_GLB_RSTN |
756 SCHEDULE_EN | MACRXEN | MACTXEN | DDMA_EN | FW2HW_EN |
757 RXDMA_EN | TXDMA_EN | HCI_RXDMA_EN | HCI_TXDMA_EN));
758
759 /* Set TCR TX DMA pre 2 FULL enable bit */
760 rtl_write_dword(rtlpriv, TCR, rtl_read_dword(rtlpriv, TCR) |
761 TXDMAPRE2FULL);
762
763 /* Set RCR */
764 rtl_write_dword(rtlpriv, RCR, rtlpci->receive_config);
765
766 /* 3. MACID Setting Register (Offset: 0x0050 - 0x007F) */
767
768 /* 4. Timing Control Register (Offset: 0x0080 - 0x009F) */
769 /* Set CCK/OFDM SIFS */
770 /* CCK SIFS shall always be 10us. */
771 rtl_write_word(rtlpriv, SIFS_CCK, 0x0a0a);
772 rtl_write_word(rtlpriv, SIFS_OFDM, 0x1010);
773
774 /* Set AckTimeout */
775 rtl_write_byte(rtlpriv, ACK_TIMEOUT, 0x40);
776
777 /* Beacon related */
778 rtl_write_word(rtlpriv, BCN_INTERVAL, 100);
779 rtl_write_word(rtlpriv, ATIMWND, 2);
780
781 /* 5. FIFO Control Register (Offset: 0x00A0 - 0x015F) */
782 /* 5.1 Initialize Number of Reserved Pages in Firmware Queue */
783 /* Firmware allocate now, associate with FW internal setting.!!! */
784
785 /* 5.2 Setting TX/RX page size 0/1/2/3/4=64/128/256/512/1024 */
786 /* 5.3 Set driver info, we only accept PHY status now. */
787 /* 5.4 Set RXDMA arbitration to control RXDMA/MAC/FW R/W for RXFIFO */
788 rtl_write_byte(rtlpriv, RXDMA, rtl_read_byte(rtlpriv, RXDMA) | BIT(6));
789
790 /* 6. Adaptive Control Register (Offset: 0x0160 - 0x01CF) */
791 /* Set RRSR to all legacy rate and HT rate
792 * CCK rate is supported by default.
793 * CCK rate will be filtered out only when associated
794 * AP does not support it.
795 * Only enable ACK rate to OFDM 24M
796 * Disable RRSR for CCK rate in A-Cut */
797
798 if (rtlhal->version == VERSION_8192S_ACUT)
799 rtl_write_byte(rtlpriv, RRSR, 0xf0);
800 else if (rtlhal->version == VERSION_8192S_BCUT)
801 rtl_write_byte(rtlpriv, RRSR, 0xff);
802 rtl_write_byte(rtlpriv, RRSR + 1, 0x01);
803 rtl_write_byte(rtlpriv, RRSR + 2, 0x00);
804
805 /* A-Cut IC do not support CCK rate. We forbid ARFR to */
806 /* fallback to CCK rate */
807 for (i = 0; i < 8; i++) {
808 /*Disable RRSR for CCK rate in A-Cut */
809 if (rtlhal->version == VERSION_8192S_ACUT)
810 rtl_write_dword(rtlpriv, ARFR0 + i * 4, 0x1f0ff0f0);
811 }
812
813 /* Different rate use different AMPDU size */
814 /* MCS32/ MCS15_SG use max AMPDU size 15*2=30K */
815 rtl_write_byte(rtlpriv, AGGLEN_LMT_H, 0x0f);
816 /* MCS0/1/2/3 use max AMPDU size 4*2=8K */
817 rtl_write_word(rtlpriv, AGGLEN_LMT_L, 0x7442);
818 /* MCS4/5 use max AMPDU size 8*2=16K 6/7 use 10*2=20K */
819 rtl_write_word(rtlpriv, AGGLEN_LMT_L + 2, 0xddd7);
820 /* MCS8/9 use max AMPDU size 8*2=16K 10/11 use 10*2=20K */
821 rtl_write_word(rtlpriv, AGGLEN_LMT_L + 4, 0xd772);
822 /* MCS12/13/14/15 use max AMPDU size 15*2=30K */
823 rtl_write_word(rtlpriv, AGGLEN_LMT_L + 6, 0xfffd);
824
825 /* Set Data / Response auto rate fallack retry count */
826 rtl_write_dword(rtlpriv, DARFRC, 0x04010000);
827 rtl_write_dword(rtlpriv, DARFRC + 4, 0x09070605);
828 rtl_write_dword(rtlpriv, RARFRC, 0x04010000);
829 rtl_write_dword(rtlpriv, RARFRC + 4, 0x09070605);
830
831 /* 7. EDCA Setting Register (Offset: 0x01D0 - 0x01FF) */
832 /* Set all rate to support SG */
833 rtl_write_word(rtlpriv, SG_RATE, 0xFFFF);
834
835 /* 8. WMAC, BA, and CCX related Register (Offset: 0x0200 - 0x023F) */
836 /* Set NAV protection length */
837 rtl_write_word(rtlpriv, NAV_PROT_LEN, 0x0080);
838 /* CF-END Threshold */
839 rtl_write_byte(rtlpriv, CFEND_TH, 0xFF);
840 /* Set AMPDU minimum space */
841 rtl_write_byte(rtlpriv, AMPDU_MIN_SPACE, 0x07);
842 /* Set TXOP stall control for several queue/HI/BCN/MGT/ */
843 rtl_write_byte(rtlpriv, TXOP_STALL_CTRL, 0x00);
844
845 /* 9. Security Control Register (Offset: 0x0240 - 0x025F) */
846 /* 10. Power Save Control Register (Offset: 0x0260 - 0x02DF) */
847 /* 11. General Purpose Register (Offset: 0x02E0 - 0x02FF) */
848 /* 12. Host Interrupt Status Register (Offset: 0x0300 - 0x030F) */
849 /* 13. Test Mode and Debug Control Register (Offset: 0x0310 - 0x034F) */
850
851 /* 14. Set driver info, we only accept PHY status now. */
852 rtl_write_byte(rtlpriv, RXDRVINFO_SZ, 4);
853
854 /* 15. For EEPROM R/W Workaround */
855 /* 16. For EFUSE to share REG_SYS_FUNC_EN with EEPROM!!! */
856 tmpu2b = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN);
857 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, tmpu2b | BIT(13));
858 tmpu2b = rtl_read_byte(rtlpriv, REG_SYS_ISO_CTRL);
859 rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL, tmpu2b & (~BIT(8)));
860
861 /* 17. For EFUSE */
862 /* We may R/W EFUSE in EEPROM mode */
863 if (rtlefuse->epromtype == EEPROM_BOOT_EFUSE) {
864 u8 tempval;
865
866 tempval = rtl_read_byte(rtlpriv, REG_SYS_ISO_CTRL + 1);
867 tempval &= 0xFE;
868 rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL + 1, tempval);
869
870 /* Change Program timing */
871 rtl_write_byte(rtlpriv, REG_EFUSE_CTRL + 3, 0x72);
872 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("EFUSE CONFIG OK\n"));
873 }
874
875 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("OK\n"));
876
877}
878
879static void _rtl92se_hw_configure(struct ieee80211_hw *hw)
880{
881 struct rtl_priv *rtlpriv = rtl_priv(hw);
882 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
883 struct rtl_phy *rtlphy = &(rtlpriv->phy);
884 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
885
886 u8 reg_bw_opmode = 0;
887 u32 reg_ratr = 0, reg_rrsr = 0;
888 u8 regtmp = 0;
889
890 reg_bw_opmode = BW_OPMODE_20MHZ;
891 reg_ratr = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS |
892 RATE_ALL_OFDM_2SS;
893 reg_rrsr = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
894
895 regtmp = rtl_read_byte(rtlpriv, INIRTSMCS_SEL);
896 reg_rrsr = ((reg_rrsr & 0x000fffff) << 8) | regtmp;
897 rtl_write_dword(rtlpriv, INIRTSMCS_SEL, reg_rrsr);
898 rtl_write_byte(rtlpriv, BW_OPMODE, reg_bw_opmode);
899
900 /* Set Retry Limit here */
901 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RETRY_LIMIT,
902 (u8 *)(&rtlpci->shortretry_limit));
903
904 rtl_write_byte(rtlpriv, MLT, 0x8f);
905
906 /* For Min Spacing configuration. */
907 switch (rtlphy->rf_type) {
908 case RF_1T2R:
909 case RF_1T1R:
910 rtlhal->minspace_cfg = (MAX_MSS_DENSITY_1T << 3);
911 break;
912 case RF_2T2R:
913 case RF_2T2R_GREEN:
914 rtlhal->minspace_cfg = (MAX_MSS_DENSITY_2T << 3);
915 break;
916 }
917 rtl_write_byte(rtlpriv, AMPDU_MIN_SPACE, rtlhal->minspace_cfg);
918}
919
920int rtl92se_hw_init(struct ieee80211_hw *hw)
921{
922 struct rtl_priv *rtlpriv = rtl_priv(hw);
923 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
924 struct rtl_phy *rtlphy = &(rtlpriv->phy);
925 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
926 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
927 u8 tmp_byte = 0;
928
929 bool rtstatus = true;
930 u8 tmp_u1b;
931 int err = false;
932 u8 i;
933 int wdcapra_add[] = {
934 EDCAPARA_BE, EDCAPARA_BK,
935 EDCAPARA_VI, EDCAPARA_VO};
936 u8 secr_value = 0x0;
937
938 rtlpci->being_init_adapter = true;
939
940 rtlpriv->intf_ops->disable_aspm(hw);
941
942 /* 1. MAC Initialize */
943 /* Before FW download, we have to set some MAC register */
944 _rtl92se_macconfig_before_fwdownload(hw);
945
946 rtlhal->version = (enum version_8192s)((rtl_read_dword(rtlpriv,
947 PMC_FSM) >> 16) & 0xF);
948
949 rtl8192se_gpiobit3_cfg_inputmode(hw);
950
951 /* 2. download firmware */
952 rtstatus = rtl92s_download_fw(hw);
953 if (!rtstatus) {
954 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
955 ("Failed to download FW. "
956 "Init HW without FW now.., Please copy FW into"
957 "/lib/firmware/rtlwifi\n"));
958 rtlhal->fw_ready = false;
959 } else {
960 rtlhal->fw_ready = true;
961 }
962
963 /* After FW download, we have to reset MAC register */
964 _rtl92se_macconfig_after_fwdownload(hw);
965
966 /*Retrieve default FW Cmd IO map. */
967 rtlhal->fwcmd_iomap = rtl_read_word(rtlpriv, LBUS_MON_ADDR);
968 rtlhal->fwcmd_ioparam = rtl_read_dword(rtlpriv, LBUS_ADDR_MASK);
969
970 /* 3. Initialize MAC/PHY Config by MACPHY_reg.txt */
971 if (rtl92s_phy_mac_config(hw) != true) {
972 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("MAC Config failed\n"));
973 return rtstatus;
974 }
975
976 /* Make sure BB/RF write OK. We should prevent enter IPS. radio off. */
977 /* We must set flag avoid BB/RF config period later!! */
978 rtl_write_dword(rtlpriv, CMDR, 0x37FC);
979
980 /* 4. Initialize BB After MAC Config PHY_reg.txt, AGC_Tab.txt */
981 if (rtl92s_phy_bb_config(hw) != true) {
982 RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, ("BB Config failed\n"));
983 return rtstatus;
984 }
985
986 /* 5. Initiailze RF RAIO_A.txt RF RAIO_B.txt */
987 /* Before initalizing RF. We can not use FW to do RF-R/W. */
988
989 rtlphy->rf_mode = RF_OP_BY_SW_3WIRE;
990
991 /* RF Power Save */
992#if 0
993 /* H/W or S/W RF OFF before sleep. */
994 if (rtlpriv->psc.rfoff_reason > RF_CHANGE_BY_PS) {
995 u32 rfoffreason = rtlpriv->psc.rfoff_reason;
996
997 rtlpriv->psc.rfoff_reason = RF_CHANGE_BY_INIT;
998 rtlpriv->psc.rfpwr_state = ERFON;
999 rtl_ps_set_rf_state(hw, ERFOFF, rfoffreason, true);
1000 } else {
1001 /* gpio radio on/off is out of adapter start */
1002 if (rtlpriv->psc.hwradiooff == false) {
1003 rtlpriv->psc.rfpwr_state = ERFON;
1004 rtlpriv->psc.rfoff_reason = 0;
1005 }
1006 }
1007#endif
1008
1009 /* Before RF-R/W we must execute the IO from Scott's suggestion. */
1010 rtl_write_byte(rtlpriv, AFE_XTAL_CTRL + 1, 0xDB);
1011 if (rtlhal->version == VERSION_8192S_ACUT)
1012 rtl_write_byte(rtlpriv, SPS1_CTRL + 3, 0x07);
1013 else
1014 rtl_write_byte(rtlpriv, RF_CTRL, 0x07);
1015
1016 if (rtl92s_phy_rf_config(hw) != true) {
1017 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("RF Config failed\n"));
1018 return rtstatus;
1019 }
1020
1021 /* After read predefined TXT, we must set BB/MAC/RF
1022 * register as our requirement */
1023
1024 rtlphy->rfreg_chnlval[0] = rtl92s_phy_query_rf_reg(hw,
1025 (enum radio_path)0,
1026 RF_CHNLBW,
1027 RFREG_OFFSET_MASK);
1028 rtlphy->rfreg_chnlval[1] = rtl92s_phy_query_rf_reg(hw,
1029 (enum radio_path)1,
1030 RF_CHNLBW,
1031 RFREG_OFFSET_MASK);
1032
1033 /*---- Set CCK and OFDM Block "ON"----*/
1034 rtl_set_bbreg(hw, RFPGA0_RFMOD, BCCKEN, 0x1);
1035 rtl_set_bbreg(hw, RFPGA0_RFMOD, BOFDMEN, 0x1);
1036
1037 /*3 Set Hardware(Do nothing now) */
1038 _rtl92se_hw_configure(hw);
1039
1040 /* Read EEPROM TX power index and PHY_REG_PG.txt to capture correct */
1041 /* TX power index for different rate set. */
1042 /* Get original hw reg values */
1043 rtl92s_phy_get_hw_reg_originalvalue(hw);
1044 /* Write correct tx power index */
1045 rtl92s_phy_set_txpower(hw, rtlphy->current_channel);
1046
1047 /* We must set MAC address after firmware download. */
1048 for (i = 0; i < 6; i++)
1049 rtl_write_byte(rtlpriv, MACIDR0 + i, rtlefuse->dev_addr[i]);
1050
1051 /* EEPROM R/W workaround */
1052 tmp_u1b = rtl_read_byte(rtlpriv, MAC_PINMUX_CFG);
1053 rtl_write_byte(rtlpriv, MAC_PINMUX_CFG, tmp_u1b & (~BIT(3)));
1054
1055 rtl_write_byte(rtlpriv, 0x4d, 0x0);
1056
1057 if (hal_get_firmwareversion(rtlpriv) >= 0x49) {
1058 tmp_byte = rtl_read_byte(rtlpriv, FW_RSVD_PG_CRTL) & (~BIT(4));
1059 tmp_byte = tmp_byte | BIT(5);
1060 rtl_write_byte(rtlpriv, FW_RSVD_PG_CRTL, tmp_byte);
1061 rtl_write_dword(rtlpriv, TXDESC_MSK, 0xFFFFCFFF);
1062 }
1063
1064 /* We enable high power and RA related mechanism after NIC
1065 * initialized. */
1066 rtl92s_phy_set_fw_cmd(hw, FW_CMD_RA_INIT);
1067
1068 /* Add to prevent ASPM bug. */
1069 /* Always enable hst and NIC clock request. */
1070 rtl92s_phy_switch_ephy_parameter(hw);
1071
1072 /* Security related
1073 * 1. Clear all H/W keys.
1074 * 2. Enable H/W encryption/decryption. */
1075 rtl_cam_reset_all_entry(hw);
1076 secr_value |= SCR_TXENCENABLE;
1077 secr_value |= SCR_RXENCENABLE;
1078 secr_value |= SCR_NOSKMC;
1079 rtl_write_byte(rtlpriv, REG_SECR, secr_value);
1080
1081 for (i = 0; i < 4; i++)
1082 rtl_write_dword(rtlpriv, wdcapra_add[i], 0x5e4322);
1083
1084 if (rtlphy->rf_type == RF_1T2R) {
1085 bool mrc2set = true;
1086 /* Turn on B-Path */
1087 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_MRC, (u8 *)&mrc2set);
1088 }
1089
1090 rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_ON);
1091 rtl92s_dm_init(hw);
1092 rtlpci->being_init_adapter = false;
1093
1094 return err;
1095}
1096
1097void rtl92se_set_mac_addr(struct rtl_io *io, const u8 * addr)
1098{
1099}
1100
1101void rtl92se_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid)
1102{
1103 struct rtl_priv *rtlpriv = rtl_priv(hw);
1104 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1105 u32 reg_rcr = rtlpci->receive_config;
1106
1107 if (rtlpriv->psc.rfpwr_state != ERFON)
1108 return;
1109
1110 if (check_bssid == true) {
1111 reg_rcr |= (RCR_CBSSID);
1112 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *)(&reg_rcr));
1113 } else if (check_bssid == false) {
1114 reg_rcr &= (~RCR_CBSSID);
1115 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *)(&reg_rcr));
1116 }
1117
1118}
1119
1120static int _rtl92se_set_media_status(struct ieee80211_hw *hw,
1121 enum nl80211_iftype type)
1122{
1123 struct rtl_priv *rtlpriv = rtl_priv(hw);
1124 u8 bt_msr = rtl_read_byte(rtlpriv, MSR);
1125 enum led_ctl_mode ledaction = LED_CTL_NO_LINK;
1126 u32 temp;
1127 bt_msr &= ~MSR_LINK_MASK;
1128
1129 switch (type) {
1130 case NL80211_IFTYPE_UNSPECIFIED:
1131 bt_msr |= (MSR_LINK_NONE << MSR_LINK_SHIFT);
1132 ledaction = LED_CTL_LINK;
1133 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1134 ("Set Network type to NO LINK!\n"));
1135 break;
1136 case NL80211_IFTYPE_ADHOC:
1137 bt_msr |= (MSR_LINK_ADHOC << MSR_LINK_SHIFT);
1138 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1139 ("Set Network type to Ad Hoc!\n"));
1140 break;
1141 case NL80211_IFTYPE_STATION:
1142 bt_msr |= (MSR_LINK_MANAGED << MSR_LINK_SHIFT);
1143 ledaction = LED_CTL_LINK;
1144 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1145 ("Set Network type to STA!\n"));
1146 break;
1147 case NL80211_IFTYPE_AP:
1148 bt_msr |= (MSR_LINK_MASTER << MSR_LINK_SHIFT);
1149 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1150 ("Set Network type to AP!\n"));
1151 break;
1152 default:
1153 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1154 ("Network type %d not support!\n", type));
1155 return 1;
1156 break;
1157
1158 }
1159
1160 rtl_write_byte(rtlpriv, (MSR), bt_msr);
1161
1162 temp = rtl_read_dword(rtlpriv, TCR);
1163 rtl_write_dword(rtlpriv, TCR, temp & (~BIT(8)));
1164 rtl_write_dword(rtlpriv, TCR, temp | BIT(8));
1165
1166
1167 return 0;
1168}
1169
1170/* HW_VAR_MEDIA_STATUS & HW_VAR_CECHK_BSSID */
1171int rtl92se_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type)
1172{
1173 struct rtl_priv *rtlpriv = rtl_priv(hw);
1174
1175 if (_rtl92se_set_media_status(hw, type))
1176 return -EOPNOTSUPP;
1177
1178 if (rtlpriv->mac80211.link_state == MAC80211_LINKED) {
1179 if (type != NL80211_IFTYPE_AP)
1180 rtl92se_set_check_bssid(hw, true);
1181 } else {
1182 rtl92se_set_check_bssid(hw, false);
1183 }
1184
1185 return 0;
1186}
1187
1188/* don't set REG_EDCA_BE_PARAM here because mac80211 will send pkt when scan */
1189void rtl92se_set_qos(struct ieee80211_hw *hw, int aci)
1190{
1191 struct rtl_priv *rtlpriv = rtl_priv(hw);
1192 rtl92s_dm_init_edca_turbo(hw);
1193
1194 switch (aci) {
1195 case AC1_BK:
1196 rtl_write_dword(rtlpriv, EDCAPARA_BK, 0xa44f);
1197 break;
1198 case AC0_BE:
1199 /* rtl_write_dword(rtlpriv, EDCAPARA_BE, u4b_ac_param); */
1200 break;
1201 case AC2_VI:
1202 rtl_write_dword(rtlpriv, EDCAPARA_VI, 0x5e4322);
1203 break;
1204 case AC3_VO:
1205 rtl_write_dword(rtlpriv, EDCAPARA_VO, 0x2f3222);
1206 break;
1207 default:
1208 RT_ASSERT(false, ("invalid aci: %d !\n", aci));
1209 break;
1210 }
1211}
1212
1213void rtl92se_enable_interrupt(struct ieee80211_hw *hw)
1214{
1215 struct rtl_priv *rtlpriv = rtl_priv(hw);
1216 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1217
1218 rtl_write_dword(rtlpriv, INTA_MASK, rtlpci->irq_mask[0]);
1219 /* Support Bit 32-37(Assign as Bit 0-5) interrupt setting now */
1220 rtl_write_dword(rtlpriv, INTA_MASK + 4, rtlpci->irq_mask[1] & 0x3F);
1221
1222 rtlpci->irq_enabled = true;
1223}
1224
1225void rtl92se_disable_interrupt(struct ieee80211_hw *hw)
1226{
1227 struct rtl_priv *rtlpriv = rtl_priv(hw);
1228 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1229
1230 rtl_write_dword(rtlpriv, INTA_MASK, 0);
1231 rtl_write_dword(rtlpriv, INTA_MASK + 4, 0);
1232
1233 rtlpci->irq_enabled = false;
1234}
1235
1236
1237static u8 _rtl92s_set_sysclk(struct ieee80211_hw *hw, u8 data)
1238{
1239 struct rtl_priv *rtlpriv = rtl_priv(hw);
1240 u8 waitcnt = 100;
1241 bool result = false;
1242 u8 tmp;
1243
1244 rtl_write_byte(rtlpriv, SYS_CLKR + 1, data);
1245
1246 /* Wait the MAC synchronized. */
1247 udelay(400);
1248
1249 /* Check if it is set ready. */
1250 tmp = rtl_read_byte(rtlpriv, SYS_CLKR + 1);
1251 result = ((tmp & BIT(7)) == (data & BIT(7)));
1252
1253 if ((data & (BIT(6) | BIT(7))) == false) {
1254 waitcnt = 100;
1255 tmp = 0;
1256
1257 while (1) {
1258 waitcnt--;
1259 tmp = rtl_read_byte(rtlpriv, SYS_CLKR + 1);
1260
1261 if ((tmp & BIT(6)))
1262 break;
1263
1264 printk(KERN_ERR "wait for BIT(6) return value %x\n",
1265 tmp);
1266
1267 if (waitcnt == 0)
1268 break;
1269 udelay(10);
1270 }
1271
1272 if (waitcnt == 0)
1273 result = false;
1274 else
1275 result = true;
1276 }
1277
1278 return result;
1279}
1280
1281static void _rtl92s_phy_set_rfhalt(struct ieee80211_hw *hw)
1282{
1283 struct rtl_priv *rtlpriv = rtl_priv(hw);
1284 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1285 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
1286 u8 u1btmp;
1287
1288 if (rtlhal->driver_going2unload)
1289 rtl_write_byte(rtlpriv, 0x560, 0x0);
1290
1291 /* Power save for BB/RF */
1292 u1btmp = rtl_read_byte(rtlpriv, LDOV12D_CTRL);
1293 u1btmp |= BIT(0);
1294 rtl_write_byte(rtlpriv, LDOV12D_CTRL, u1btmp);
1295 rtl_write_byte(rtlpriv, SPS1_CTRL, 0x0);
1296 rtl_write_byte(rtlpriv, TXPAUSE, 0xFF);
1297 rtl_write_word(rtlpriv, CMDR, 0x57FC);
1298 udelay(100);
1299 rtl_write_word(rtlpriv, CMDR, 0x77FC);
1300 rtl_write_byte(rtlpriv, PHY_CCA, 0x0);
1301 udelay(10);
1302 rtl_write_word(rtlpriv, CMDR, 0x37FC);
1303 udelay(10);
1304 rtl_write_word(rtlpriv, CMDR, 0x77FC);
1305 udelay(10);
1306 rtl_write_word(rtlpriv, CMDR, 0x57FC);
1307 rtl_write_word(rtlpriv, CMDR, 0x0000);
1308
1309 if (rtlhal->driver_going2unload) {
1310 u1btmp = rtl_read_byte(rtlpriv, (REG_SYS_FUNC_EN + 1));
1311 u1btmp &= ~(BIT(0));
1312 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, u1btmp);
1313 }
1314
1315 u1btmp = rtl_read_byte(rtlpriv, (SYS_CLKR + 1));
1316
1317 /* Add description. After switch control path. register
1318 * after page1 will be invisible. We can not do any IO
1319 * for register>0x40. After resume&MACIO reset, we need
1320 * to remember previous reg content. */
1321 if (u1btmp & BIT(7)) {
1322 u1btmp &= ~(BIT(6) | BIT(7));
1323 if (!_rtl92s_set_sysclk(hw, u1btmp)) {
1324 printk(KERN_ERR "Switch ctrl path fail\n");
1325 return;
1326 }
1327 }
1328
1329 /* Power save for MAC */
1330 if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS &&
1331 !rtlhal->driver_going2unload) {
1332 /* enable LED function */
1333 rtl_write_byte(rtlpriv, 0x03, 0xF9);
1334 /* SW/HW radio off or halt adapter!! For example S3/S4 */
1335 } else {
1336 /* LED function disable. Power range is about 8mA now. */
1337 /* if write 0xF1 disconnet_pci power
1338 * ifconfig wlan0 down power are both high 35:70 */
1339 /* if write oxF9 disconnet_pci power
1340 * ifconfig wlan0 down power are both low 12:45*/
1341 rtl_write_byte(rtlpriv, 0x03, 0xF9);
1342 }
1343
1344 rtl_write_byte(rtlpriv, SYS_CLKR + 1, 0x70);
1345 rtl_write_byte(rtlpriv, AFE_PLL_CTRL + 1, 0x68);
1346 rtl_write_byte(rtlpriv, AFE_PLL_CTRL, 0x00);
1347 rtl_write_byte(rtlpriv, LDOA15_CTRL, 0x34);
1348 rtl_write_byte(rtlpriv, AFE_XTAL_CTRL, 0x0E);
1349 RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
1350
1351}
1352
1353static void _rtl92se_gen_refreshledstate(struct ieee80211_hw *hw)
1354{
1355 struct rtl_priv *rtlpriv = rtl_priv(hw);
1356 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1357 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
1358 struct rtl_led *pLed0 = &(pcipriv->ledctl.sw_led0);
1359
1360 if (rtlpci->up_first_time == 1)
1361 return;
1362
1363 if (rtlpriv->psc.rfoff_reason == RF_CHANGE_BY_IPS)
1364 rtl92se_sw_led_on(hw, pLed0);
1365 else
1366 rtl92se_sw_led_off(hw, pLed0);
1367}
1368
1369
1370static void _rtl92se_power_domain_init(struct ieee80211_hw *hw)
1371{
1372 struct rtl_priv *rtlpriv = rtl_priv(hw);
1373 u16 tmpu2b;
1374 u8 tmpu1b;
1375
1376 rtlpriv->psc.pwrdomain_protect = true;
1377
1378 tmpu1b = rtl_read_byte(rtlpriv, (SYS_CLKR + 1));
1379 if (tmpu1b & BIT(7)) {
1380 tmpu1b &= ~(BIT(6) | BIT(7));
1381 if (!_rtl92s_set_sysclk(hw, tmpu1b)) {
1382 rtlpriv->psc.pwrdomain_protect = false;
1383 return;
1384 }
1385 }
1386
1387 rtl_write_byte(rtlpriv, AFE_PLL_CTRL, 0x0);
1388 rtl_write_byte(rtlpriv, LDOA15_CTRL, 0x34);
1389
1390 /* Reset MAC-IO and CPU and Core Digital BIT10/11/15 */
1391 tmpu1b = rtl_read_byte(rtlpriv, SYS_FUNC_EN + 1);
1392
1393 /* If IPS we need to turn LED on. So we not
1394 * not disable BIT 3/7 of reg3. */
1395 if (rtlpriv->psc.rfoff_reason & (RF_CHANGE_BY_IPS | RF_CHANGE_BY_HW))
1396 tmpu1b &= 0xFB;
1397 else
1398 tmpu1b &= 0x73;
1399
1400 rtl_write_byte(rtlpriv, SYS_FUNC_EN + 1, tmpu1b);
1401 /* wait for BIT 10/11/15 to pull high automatically!! */
1402 mdelay(1);
1403
1404 rtl_write_byte(rtlpriv, CMDR, 0);
1405 rtl_write_byte(rtlpriv, TCR, 0);
1406
1407 /* Data sheet not define 0x562!!! Copy from WMAC!!!!! */
1408 tmpu1b = rtl_read_byte(rtlpriv, 0x562);
1409 tmpu1b |= 0x08;
1410 rtl_write_byte(rtlpriv, 0x562, tmpu1b);
1411 tmpu1b &= ~(BIT(3));
1412 rtl_write_byte(rtlpriv, 0x562, tmpu1b);
1413
1414 /* Enable AFE clock source */
1415 tmpu1b = rtl_read_byte(rtlpriv, AFE_XTAL_CTRL);
1416 rtl_write_byte(rtlpriv, AFE_XTAL_CTRL, (tmpu1b | 0x01));
1417 /* Delay 1.5ms */
1418 udelay(1500);
1419 tmpu1b = rtl_read_byte(rtlpriv, AFE_XTAL_CTRL + 1);
1420 rtl_write_byte(rtlpriv, AFE_XTAL_CTRL + 1, (tmpu1b & 0xfb));
1421
1422 /* Enable AFE Macro Block's Bandgap */
1423 tmpu1b = rtl_read_byte(rtlpriv, AFE_MISC);
1424 rtl_write_byte(rtlpriv, AFE_MISC, (tmpu1b | BIT(0)));
1425 mdelay(1);
1426
1427 /* Enable AFE Mbias */
1428 tmpu1b = rtl_read_byte(rtlpriv, AFE_MISC);
1429 rtl_write_byte(rtlpriv, AFE_MISC, (tmpu1b | 0x02));
1430 mdelay(1);
1431
1432 /* Enable LDOA15 block */
1433 tmpu1b = rtl_read_byte(rtlpriv, LDOA15_CTRL);
1434 rtl_write_byte(rtlpriv, LDOA15_CTRL, (tmpu1b | BIT(0)));
1435
1436 /* Set Digital Vdd to Retention isolation Path. */
1437 tmpu2b = rtl_read_word(rtlpriv, SYS_ISO_CTRL);
1438 rtl_write_word(rtlpriv, SYS_ISO_CTRL, (tmpu2b | BIT(11)));
1439
1440
1441 /* For warm reboot NIC disappera bug. */
1442 tmpu2b = rtl_read_word(rtlpriv, SYS_FUNC_EN);
1443 rtl_write_word(rtlpriv, SYS_FUNC_EN, (tmpu2b | BIT(13)));
1444
1445 rtl_write_byte(rtlpriv, SYS_ISO_CTRL + 1, 0x68);
1446
1447 /* Enable AFE PLL Macro Block */
1448 tmpu1b = rtl_read_byte(rtlpriv, AFE_PLL_CTRL);
1449 rtl_write_byte(rtlpriv, AFE_PLL_CTRL, (tmpu1b | BIT(0) | BIT(4)));
1450 /* Enable MAC 80MHZ clock */
1451 tmpu1b = rtl_read_byte(rtlpriv, AFE_PLL_CTRL + 1);
1452 rtl_write_byte(rtlpriv, AFE_PLL_CTRL + 1, (tmpu1b | BIT(0)));
1453 mdelay(1);
1454
1455 /* Release isolation AFE PLL & MD */
1456 rtl_write_byte(rtlpriv, SYS_ISO_CTRL, 0xA6);
1457
1458 /* Enable MAC clock */
1459 tmpu2b = rtl_read_word(rtlpriv, SYS_CLKR);
1460 rtl_write_word(rtlpriv, SYS_CLKR, (tmpu2b | BIT(12) | BIT(11)));
1461
1462 /* Enable Core digital and enable IOREG R/W */
1463 tmpu2b = rtl_read_word(rtlpriv, SYS_FUNC_EN);
1464 rtl_write_word(rtlpriv, SYS_FUNC_EN, (tmpu2b | BIT(11)));
1465 /* enable REG_EN */
1466 rtl_write_word(rtlpriv, SYS_FUNC_EN, (tmpu2b | BIT(11) | BIT(15)));
1467
1468 /* Switch the control path. */
1469 tmpu2b = rtl_read_word(rtlpriv, SYS_CLKR);
1470 rtl_write_word(rtlpriv, SYS_CLKR, (tmpu2b & (~BIT(2))));
1471
1472 tmpu1b = rtl_read_byte(rtlpriv, (SYS_CLKR + 1));
1473 tmpu1b = ((tmpu1b | BIT(7)) & (~BIT(6)));
1474 if (!_rtl92s_set_sysclk(hw, tmpu1b)) {
1475 rtlpriv->psc.pwrdomain_protect = false;
1476 return;
1477 }
1478
1479 rtl_write_word(rtlpriv, CMDR, 0x37FC);
1480
1481 /* After MACIO reset,we must refresh LED state. */
1482 _rtl92se_gen_refreshledstate(hw);
1483
1484 rtlpriv->psc.pwrdomain_protect = false;
1485}
1486
1487void rtl92se_card_disable(struct ieee80211_hw *hw)
1488{
1489 struct rtl_priv *rtlpriv = rtl_priv(hw);
1490 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1491 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1492 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
1493 enum nl80211_iftype opmode;
1494 u8 wait = 30;
1495
1496 rtlpriv->intf_ops->enable_aspm(hw);
1497
1498 if (rtlpci->driver_is_goingto_unload ||
1499 ppsc->rfoff_reason > RF_CHANGE_BY_PS)
1500 rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF);
1501
1502 /* we should chnge GPIO to input mode
1503 * this will drop away current about 25mA*/
1504 rtl8192se_gpiobit3_cfg_inputmode(hw);
1505
1506 /* this is very important for ips power save */
1507 while (wait-- >= 10 && rtlpriv->psc.pwrdomain_protect) {
1508 if (rtlpriv->psc.pwrdomain_protect)
1509 mdelay(20);
1510 else
1511 break;
1512 }
1513
1514 mac->link_state = MAC80211_NOLINK;
1515 opmode = NL80211_IFTYPE_UNSPECIFIED;
1516 _rtl92se_set_media_status(hw, opmode);
1517
1518 _rtl92s_phy_set_rfhalt(hw);
1519 udelay(100);
1520}
1521
1522void rtl92se_interrupt_recognized(struct ieee80211_hw *hw, u32 *p_inta,
1523 u32 *p_intb)
1524{
1525 struct rtl_priv *rtlpriv = rtl_priv(hw);
1526 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1527
1528 *p_inta = rtl_read_dword(rtlpriv, ISR) & rtlpci->irq_mask[0];
1529 rtl_write_dword(rtlpriv, ISR, *p_inta);
1530
1531 *p_intb = rtl_read_dword(rtlpriv, ISR + 4) & rtlpci->irq_mask[1];
1532 rtl_write_dword(rtlpriv, ISR + 4, *p_intb);
1533}
1534
1535void rtl92se_set_beacon_related_registers(struct ieee80211_hw *hw)
1536{
1537 struct rtl_priv *rtlpriv = rtl_priv(hw);
1538 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1539 u16 bcntime_cfg = 0;
1540 u16 bcn_cw = 6, bcn_ifs = 0xf;
1541 u16 atim_window = 2;
1542
1543 /* ATIM Window (in unit of TU). */
1544 rtl_write_word(rtlpriv, ATIMWND, atim_window);
1545
1546 /* Beacon interval (in unit of TU). */
1547 rtl_write_word(rtlpriv, BCN_INTERVAL, mac->beacon_interval);
1548
1549 /* DrvErlyInt (in unit of TU). (Time to send
1550 * interrupt to notify driver to change
1551 * beacon content) */
1552 rtl_write_word(rtlpriv, BCN_DRV_EARLY_INT, 10 << 4);
1553
1554 /* BcnDMATIM(in unit of us). Indicates the
1555 * time before TBTT to perform beacon queue DMA */
1556 rtl_write_word(rtlpriv, BCN_DMATIME, 256);
1557
1558 /* Force beacon frame transmission even
1559 * after receiving beacon frame from
1560 * other ad hoc STA */
1561 rtl_write_byte(rtlpriv, BCN_ERR_THRESH, 100);
1562
1563 /* Beacon Time Configuration */
1564 if (mac->opmode == NL80211_IFTYPE_ADHOC)
1565 bcntime_cfg |= (bcn_cw << BCN_TCFG_CW_SHIFT);
1566
1567 /* TODO: bcn_ifs may required to be changed on ASIC */
1568 bcntime_cfg |= bcn_ifs << BCN_TCFG_IFS;
1569
1570 /*for beacon changed */
1571 rtl92s_phy_set_beacon_hwreg(hw, mac->beacon_interval);
1572}
1573
1574void rtl92se_set_beacon_interval(struct ieee80211_hw *hw)
1575{
1576 struct rtl_priv *rtlpriv = rtl_priv(hw);
1577 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1578 u16 bcn_interval = mac->beacon_interval;
1579
1580 /* Beacon interval (in unit of TU). */
1581 rtl_write_word(rtlpriv, BCN_INTERVAL, bcn_interval);
1582 /* 2008.10.24 added by tynli for beacon changed. */
1583 rtl92s_phy_set_beacon_hwreg(hw, bcn_interval);
1584}
1585
1586void rtl92se_update_interrupt_mask(struct ieee80211_hw *hw,
1587 u32 add_msr, u32 rm_msr)
1588{
1589 struct rtl_priv *rtlpriv = rtl_priv(hw);
1590 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1591
1592 RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD,
1593 ("add_msr:%x, rm_msr:%x\n", add_msr, rm_msr));
1594
1595 if (add_msr)
1596 rtlpci->irq_mask[0] |= add_msr;
1597
1598 if (rm_msr)
1599 rtlpci->irq_mask[0] &= (~rm_msr);
1600
1601 rtl92se_disable_interrupt(hw);
1602 rtl92se_enable_interrupt(hw);
1603}
1604
1605static void _rtl8192se_get_IC_Inferiority(struct ieee80211_hw *hw)
1606{
1607 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1608 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1609 u8 efuse_id;
1610
1611 rtlhal->ic_class = IC_INFERIORITY_A;
1612
1613 /* Only retrieving while using EFUSE. */
1614 if ((rtlefuse->epromtype == EEPROM_BOOT_EFUSE) &&
1615 !rtlefuse->autoload_failflag) {
1616 efuse_id = efuse_read_1byte(hw, EFUSE_IC_ID_OFFSET);
1617
1618 if (efuse_id == 0xfe)
1619 rtlhal->ic_class = IC_INFERIORITY_B;
1620 }
1621}
1622
1623static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw)
1624{
1625 struct rtl_priv *rtlpriv = rtl_priv(hw);
1626 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1627 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1628 u16 i, usvalue;
1629 u16 eeprom_id;
1630 u8 tempval;
1631 u8 hwinfo[HWSET_MAX_SIZE_92S];
1632 u8 rf_path, index;
1633
1634 if (rtlefuse->epromtype == EEPROM_93C46) {
1635 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1636 ("RTL819X Not boot from eeprom, check it !!"));
1637 } else if (rtlefuse->epromtype == EEPROM_BOOT_EFUSE) {
1638 rtl_efuse_shadow_map_update(hw);
1639
1640 memcpy((void *)hwinfo, (void *)
1641 &rtlefuse->efuse_map[EFUSE_INIT_MAP][0],
1642 HWSET_MAX_SIZE_92S);
1643 }
1644
1645 RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, ("MAP\n"),
1646 hwinfo, HWSET_MAX_SIZE_92S);
1647
1648 eeprom_id = *((u16 *)&hwinfo[0]);
1649 if (eeprom_id != RTL8190_EEPROM_ID) {
1650 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1651 ("EEPROM ID(%#x) is invalid!!\n", eeprom_id));
1652 rtlefuse->autoload_failflag = true;
1653 } else {
1654 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload OK\n"));
1655 rtlefuse->autoload_failflag = false;
1656 }
1657
1658 if (rtlefuse->autoload_failflag == true)
1659 return;
1660
1661 _rtl8192se_get_IC_Inferiority(hw);
1662
1663 /* Read IC Version && Channel Plan */
1664 /* VID, DID SE 0xA-D */
1665 rtlefuse->eeprom_vid = *(u16 *)&hwinfo[EEPROM_VID];
1666 rtlefuse->eeprom_did = *(u16 *)&hwinfo[EEPROM_DID];
1667 rtlefuse->eeprom_svid = *(u16 *)&hwinfo[EEPROM_SVID];
1668 rtlefuse->eeprom_smid = *(u16 *)&hwinfo[EEPROM_SMID];
1669 rtlefuse->eeprom_version = *(u16 *)&hwinfo[EEPROM_VERSION];
1670
1671 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1672 ("EEPROMId = 0x%4x\n", eeprom_id));
1673 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1674 ("EEPROM VID = 0x%4x\n", rtlefuse->eeprom_vid));
1675 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1676 ("EEPROM DID = 0x%4x\n", rtlefuse->eeprom_did));
1677 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1678 ("EEPROM SVID = 0x%4x\n", rtlefuse->eeprom_svid));
1679 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1680 ("EEPROM SMID = 0x%4x\n", rtlefuse->eeprom_smid));
1681
1682 for (i = 0; i < 6; i += 2) {
1683 usvalue = *(u16 *)&hwinfo[EEPROM_MAC_ADDR + i];
1684 *((u16 *) (&rtlefuse->dev_addr[i])) = usvalue;
1685 }
1686
1687 for (i = 0; i < 6; i++)
1688 rtl_write_byte(rtlpriv, MACIDR0 + i, rtlefuse->dev_addr[i]);
1689
1690 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
1691 (MAC_FMT "\n", MAC_ARG(rtlefuse->dev_addr)));
1692
1693 /* Get Tx Power Level by Channel */
1694 /* Read Tx power of Channel 1 ~ 14 from EEPROM. */
1695 /* 92S suupport RF A & B */
1696 for (rf_path = 0; rf_path < 2; rf_path++) {
1697 for (i = 0; i < 3; i++) {
1698 /* Read CCK RF A & B Tx power */
1699 rtlefuse->eeprom_chnlarea_txpwr_cck[rf_path][i] =
1700 hwinfo[EEPROM_TXPOWERBASE + rf_path * 3 + i];
1701
1702 /* Read OFDM RF A & B Tx power for 1T */
1703 rtlefuse->eeprom_chnlarea_txpwr_ht40_1s[rf_path][i] =
1704 hwinfo[EEPROM_TXPOWERBASE + 6 + rf_path * 3 + i];
1705
1706 /* Read OFDM RF A & B Tx power for 2T */
1707 rtlefuse->eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path][i]
1708 = hwinfo[EEPROM_TXPOWERBASE + 12 +
1709 rf_path * 3 + i];
1710 }
1711 }
1712
1713 for (rf_path = 0; rf_path < 2; rf_path++)
1714 for (i = 0; i < 3; i++)
1715 RTPRINT(rtlpriv, FINIT, INIT_EEPROM,
1716 ("RF(%d) EEPROM CCK Area(%d) = 0x%x\n", rf_path,
1717 i, rtlefuse->eeprom_chnlarea_txpwr_cck
1718 [rf_path][i]));
1719 for (rf_path = 0; rf_path < 2; rf_path++)
1720 for (i = 0; i < 3; i++)
1721 RTPRINT(rtlpriv, FINIT, INIT_EEPROM,
1722 ("RF(%d) EEPROM HT40 1S Area(%d) = 0x%x\n",
1723 rf_path, i,
1724 rtlefuse->eeprom_chnlarea_txpwr_ht40_1s
1725 [rf_path][i]));
1726 for (rf_path = 0; rf_path < 2; rf_path++)
1727 for (i = 0; i < 3; i++)
1728 RTPRINT(rtlpriv, FINIT, INIT_EEPROM,
1729 ("RF(%d) EEPROM HT40 2S Diff Area(%d) = 0x%x\n",
1730 rf_path, i,
1731 rtlefuse->eeprom_chnlarea_txpwr_ht40_2sdiif
1732 [rf_path][i]));
1733
1734 for (rf_path = 0; rf_path < 2; rf_path++) {
1735
1736 /* Assign dedicated channel tx power */
1737 for (i = 0; i < 14; i++) {
1738 /* channel 1~3 use the same Tx Power Level. */
1739 if (i < 3)
1740 index = 0;
1741 /* Channel 4-8 */
1742 else if (i < 8)
1743 index = 1;
1744 /* Channel 9-14 */
1745 else
1746 index = 2;
1747
1748 /* Record A & B CCK /OFDM - 1T/2T Channel area
1749 * tx power */
1750 rtlefuse->txpwrlevel_cck[rf_path][i] =
1751 rtlefuse->eeprom_chnlarea_txpwr_cck
1752 [rf_path][index];
1753 rtlefuse->txpwrlevel_ht40_1s[rf_path][i] =
1754 rtlefuse->eeprom_chnlarea_txpwr_ht40_1s
1755 [rf_path][index];
1756 rtlefuse->txpwrlevel_ht40_2s[rf_path][i] =
1757 rtlefuse->eeprom_chnlarea_txpwr_ht40_2sdiif
1758 [rf_path][index];
1759 }
1760
1761 for (i = 0; i < 14; i++) {
1762 RTPRINT(rtlpriv, FINIT, INIT_TxPower,
1763 ("RF(%d)-Ch(%d) [CCK / HT40_1S / HT40_2S] = "
1764 "[0x%x / 0x%x / 0x%x]\n", rf_path, i,
1765 rtlefuse->txpwrlevel_cck[rf_path][i],
1766 rtlefuse->txpwrlevel_ht40_1s[rf_path][i],
1767 rtlefuse->txpwrlevel_ht40_2s[rf_path][i]));
1768 }
1769 }
1770
1771 for (rf_path = 0; rf_path < 2; rf_path++) {
1772 for (i = 0; i < 3; i++) {
1773 /* Read Power diff limit. */
1774 rtlefuse->eeprom_pwrgroup[rf_path][i] =
1775 hwinfo[EEPROM_TXPWRGROUP + rf_path * 3 + i];
1776 }
1777 }
1778
1779 for (rf_path = 0; rf_path < 2; rf_path++) {
1780 /* Fill Pwr group */
1781 for (i = 0; i < 14; i++) {
1782 /* Chanel 1-3 */
1783 if (i < 3)
1784 index = 0;
1785 /* Channel 4-8 */
1786 else if (i < 8)
1787 index = 1;
1788 /* Channel 9-13 */
1789 else
1790 index = 2;
1791
1792 rtlefuse->pwrgroup_ht20[rf_path][i] =
1793 (rtlefuse->eeprom_pwrgroup[rf_path][index] &
1794 0xf);
1795 rtlefuse->pwrgroup_ht40[rf_path][i] =
1796 ((rtlefuse->eeprom_pwrgroup[rf_path][index] &
1797 0xf0) >> 4);
1798
1799 RTPRINT(rtlpriv, FINIT, INIT_TxPower,
1800 ("RF-%d pwrgroup_ht20[%d] = 0x%x\n",
1801 rf_path, i,
1802 rtlefuse->pwrgroup_ht20[rf_path][i]));
1803 RTPRINT(rtlpriv, FINIT, INIT_TxPower,
1804 ("RF-%d pwrgroup_ht40[%d] = 0x%x\n",
1805 rf_path, i,
1806 rtlefuse->pwrgroup_ht40[rf_path][i]));
1807 }
1808 }
1809
1810 for (i = 0; i < 14; i++) {
1811 /* Read tx power difference between HT OFDM 20/40 MHZ */
1812 /* channel 1-3 */
1813 if (i < 3)
1814 index = 0;
1815 /* Channel 4-8 */
1816 else if (i < 8)
1817 index = 1;
1818 /* Channel 9-14 */
1819 else
1820 index = 2;
1821
1822 tempval = (*(u8 *)&hwinfo[EEPROM_TX_PWR_HT20_DIFF +
1823 index]) & 0xff;
1824 rtlefuse->txpwr_ht20diff[RF90_PATH_A][i] = (tempval & 0xF);
1825 rtlefuse->txpwr_ht20diff[RF90_PATH_B][i] =
1826 ((tempval >> 4) & 0xF);
1827
1828 /* Read OFDM<->HT tx power diff */
1829 /* Channel 1-3 */
1830 if (i < 3)
1831 index = 0;
1832 /* Channel 4-8 */
1833 else if (i < 8)
1834 index = 0x11;
1835 /* Channel 9-14 */
1836 else
1837 index = 1;
1838
1839 tempval = (*(u8 *)&hwinfo[EEPROM_TX_PWR_OFDM_DIFF + index])
1840 & 0xff;
1841 rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i] =
1842 (tempval & 0xF);
1843 rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i] =
1844 ((tempval >> 4) & 0xF);
1845
1846 tempval = (*(u8 *)&hwinfo[TX_PWR_SAFETY_CHK]);
1847 rtlefuse->txpwr_safetyflag = (tempval & 0x01);
1848 }
1849
1850 rtlefuse->eeprom_regulatory = 0;
1851 if (rtlefuse->eeprom_version >= 2) {
1852 /* BIT(0)~2 */
1853 if (rtlefuse->eeprom_version >= 4)
1854 rtlefuse->eeprom_regulatory =
1855 (hwinfo[EEPROM_REGULATORY] & 0x7);
1856 else /* BIT(0) */
1857 rtlefuse->eeprom_regulatory =
1858 (hwinfo[EEPROM_REGULATORY] & 0x1);
1859 }
1860 RTPRINT(rtlpriv, FINIT, INIT_TxPower,
1861 ("eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory));
1862
1863 for (i = 0; i < 14; i++)
1864 RTPRINT(rtlpriv, FINIT, INIT_TxPower,
1865 ("RF-A Ht20 to HT40 Diff[%d] = 0x%x\n", i,
1866 rtlefuse->txpwr_ht20diff[RF90_PATH_A][i]));
1867 for (i = 0; i < 14; i++)
1868 RTPRINT(rtlpriv, FINIT, INIT_TxPower,
1869 ("RF-A Legacy to Ht40 Diff[%d] = 0x%x\n", i,
1870 rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i]));
1871 for (i = 0; i < 14; i++)
1872 RTPRINT(rtlpriv, FINIT, INIT_TxPower,
1873 ("RF-B Ht20 to HT40 Diff[%d] = 0x%x\n", i,
1874 rtlefuse->txpwr_ht20diff[RF90_PATH_B][i]));
1875 for (i = 0; i < 14; i++)
1876 RTPRINT(rtlpriv, FINIT, INIT_TxPower,
1877 ("RF-B Legacy to HT40 Diff[%d] = 0x%x\n", i,
1878 rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i]));
1879
1880 RTPRINT(rtlpriv, FINIT, INIT_TxPower, ("TxPwrSafetyFlag = %d\n",
1881 rtlefuse->txpwr_safetyflag));
1882
1883 /* Read RF-indication and Tx Power gain
1884 * index diff of legacy to HT OFDM rate. */
1885 tempval = (*(u8 *)&hwinfo[EEPROM_RFIND_POWERDIFF]) & 0xff;
1886 rtlefuse->eeprom_txpowerdiff = tempval;
1887 rtlefuse->legacy_httxpowerdiff =
1888 rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][0];
1889
1890 RTPRINT(rtlpriv, FINIT, INIT_TxPower, ("TxPowerDiff = %#x\n",
1891 rtlefuse->eeprom_txpowerdiff));
1892
1893 /* Get TSSI value for each path. */
1894 usvalue = *(u16 *)&hwinfo[EEPROM_TSSI_A];
1895 rtlefuse->eeprom_tssi[RF90_PATH_A] = (u8)((usvalue & 0xff00) >> 8);
1896 usvalue = *(u8 *)&hwinfo[EEPROM_TSSI_B];
1897 rtlefuse->eeprom_tssi[RF90_PATH_B] = (u8)(usvalue & 0xff);
1898
1899 RTPRINT(rtlpriv, FINIT, INIT_TxPower, ("TSSI_A = 0x%x, TSSI_B = 0x%x\n",
1900 rtlefuse->eeprom_tssi[RF90_PATH_A],
1901 rtlefuse->eeprom_tssi[RF90_PATH_B]));
1902
1903 /* Read antenna tx power offset of B/C/D to A from EEPROM */
1904 /* and read ThermalMeter from EEPROM */
1905 tempval = *(u8 *)&hwinfo[EEPROM_THERMALMETER];
1906 rtlefuse->eeprom_thermalmeter = tempval;
1907 RTPRINT(rtlpriv, FINIT, INIT_TxPower, ("thermalmeter = 0x%x\n",
1908 rtlefuse->eeprom_thermalmeter));
1909
1910 /* ThermalMeter, BIT(0)~3 for RFIC1, BIT(4)~7 for RFIC2 */
1911 rtlefuse->thermalmeter[0] = (rtlefuse->eeprom_thermalmeter & 0x1f);
1912 rtlefuse->tssi_13dbm = rtlefuse->eeprom_thermalmeter * 100;
1913
1914 /* Read CrystalCap from EEPROM */
1915 tempval = (*(u8 *)&hwinfo[EEPROM_CRYSTALCAP]) >> 4;
1916 rtlefuse->eeprom_crystalcap = tempval;
1917 /* CrystalCap, BIT(12)~15 */
1918 rtlefuse->crystalcap = rtlefuse->eeprom_crystalcap;
1919
1920 /* Read IC Version && Channel Plan */
1921 /* Version ID, Channel plan */
1922 rtlefuse->eeprom_channelplan = *(u8 *)&hwinfo[EEPROM_CHANNELPLAN];
1923 rtlefuse->txpwr_fromeprom = true;
1924 RTPRINT(rtlpriv, FINIT, INIT_TxPower, ("EEPROM ChannelPlan = 0x%4x\n",
1925 rtlefuse->eeprom_channelplan));
1926
1927 /* Read Customer ID or Board Type!!! */
1928 tempval = *(u8 *)&hwinfo[EEPROM_BOARDTYPE];
1929 /* Change RF type definition */
1930 if (tempval == 0)
1931 rtlphy->rf_type = RF_2T2R;
1932 else if (tempval == 1)
1933 rtlphy->rf_type = RF_1T2R;
1934 else if (tempval == 2)
1935 rtlphy->rf_type = RF_1T2R;
1936 else if (tempval == 3)
1937 rtlphy->rf_type = RF_1T1R;
1938
1939 /* 1T2R but 1SS (1x1 receive combining) */
1940 rtlefuse->b1x1_recvcombine = false;
1941 if (rtlphy->rf_type == RF_1T2R) {
1942 tempval = rtl_read_byte(rtlpriv, 0x07);
1943 if (!(tempval & BIT(0))) {
1944 rtlefuse->b1x1_recvcombine = true;
1945 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1946 ("RF_TYPE=1T2R but only 1SS\n"));
1947 }
1948 }
1949 rtlefuse->b1ss_support = rtlefuse->b1x1_recvcombine;
1950 rtlefuse->eeprom_oemid = *(u8 *)&hwinfo[EEPROM_CUSTOMID];
1951
1952 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("EEPROM Customer ID: 0x%2x",
1953 rtlefuse->eeprom_oemid));
1954
1955 /* set channel paln to world wide 13 */
1956 rtlefuse->channel_plan = COUNTRY_CODE_WORLD_WIDE_13;
1957}
1958
1959void rtl92se_read_eeprom_info(struct ieee80211_hw *hw)
1960{
1961 struct rtl_priv *rtlpriv = rtl_priv(hw);
1962 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1963 u8 tmp_u1b = 0;
1964
1965 tmp_u1b = rtl_read_byte(rtlpriv, EPROM_CMD);
1966
1967 if (tmp_u1b & BIT(4)) {
1968 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Boot from EEPROM\n"));
1969 rtlefuse->epromtype = EEPROM_93C46;
1970 } else {
1971 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Boot from EFUSE\n"));
1972 rtlefuse->epromtype = EEPROM_BOOT_EFUSE;
1973 }
1974
1975 if (tmp_u1b & BIT(5)) {
1976 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload OK\n"));
1977 rtlefuse->autoload_failflag = false;
1978 _rtl92se_read_adapter_info(hw);
1979 } else {
1980 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Autoload ERR!!\n"));
1981 rtlefuse->autoload_failflag = true;
1982 }
1983}
1984
1985static void rtl92se_update_hal_rate_table(struct ieee80211_hw *hw,
1986 struct ieee80211_sta *sta)
1987{
1988 struct rtl_priv *rtlpriv = rtl_priv(hw);
1989 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1990 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1991 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1992 u32 ratr_value;
1993 u8 ratr_index = 0;
1994 u8 nmode = mac->ht_enable;
1995 u8 mimo_ps = IEEE80211_SMPS_OFF;
1996 u16 shortgi_rate = 0;
1997 u32 tmp_ratr_value = 0;
1998 u8 curtxbw_40mhz = mac->bw_40;
1999 u8 curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ?
2000 1 : 0;
2001 u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ?
2002 1 : 0;
2003 enum wireless_mode wirelessmode = mac->mode;
2004
2005 if (rtlhal->current_bandtype == BAND_ON_5G)
2006 ratr_value = sta->supp_rates[1] << 4;
2007 else
2008 ratr_value = sta->supp_rates[0];
2009 ratr_value |= (sta->ht_cap.mcs.rx_mask[1] << 20 |
2010 sta->ht_cap.mcs.rx_mask[0] << 12);
2011 switch (wirelessmode) {
2012 case WIRELESS_MODE_B:
2013 ratr_value &= 0x0000000D;
2014 break;
2015 case WIRELESS_MODE_G:
2016 ratr_value &= 0x00000FF5;
2017 break;
2018 case WIRELESS_MODE_N_24G:
2019 case WIRELESS_MODE_N_5G:
2020 nmode = 1;
2021 if (mimo_ps == IEEE80211_SMPS_STATIC) {
2022 ratr_value &= 0x0007F005;
2023 } else {
2024 u32 ratr_mask;
2025
2026 if (get_rf_type(rtlphy) == RF_1T2R ||
2027 get_rf_type(rtlphy) == RF_1T1R) {
2028 if (curtxbw_40mhz)
2029 ratr_mask = 0x000ff015;
2030 else
2031 ratr_mask = 0x000ff005;
2032 } else {
2033 if (curtxbw_40mhz)
2034 ratr_mask = 0x0f0ff015;
2035 else
2036 ratr_mask = 0x0f0ff005;
2037 }
2038
2039 ratr_value &= ratr_mask;
2040 }
2041 break;
2042 default:
2043 if (rtlphy->rf_type == RF_1T2R)
2044 ratr_value &= 0x000ff0ff;
2045 else
2046 ratr_value &= 0x0f0ff0ff;
2047
2048 break;
2049 }
2050
2051 if (rtlpriv->rtlhal.version >= VERSION_8192S_BCUT)
2052 ratr_value &= 0x0FFFFFFF;
2053 else if (rtlpriv->rtlhal.version == VERSION_8192S_ACUT)
2054 ratr_value &= 0x0FFFFFF0;
2055
2056 if (nmode && ((curtxbw_40mhz &&
2057 curshortgi_40mhz) || (!curtxbw_40mhz &&
2058 curshortgi_20mhz))) {
2059
2060 ratr_value |= 0x10000000;
2061 tmp_ratr_value = (ratr_value >> 12);
2062
2063 for (shortgi_rate = 15; shortgi_rate > 0; shortgi_rate--) {
2064 if ((1 << shortgi_rate) & tmp_ratr_value)
2065 break;
2066 }
2067
2068 shortgi_rate = (shortgi_rate << 12) | (shortgi_rate << 8) |
2069 (shortgi_rate << 4) | (shortgi_rate);
2070
2071 rtl_write_byte(rtlpriv, SG_RATE, shortgi_rate);
2072 }
2073
2074 rtl_write_dword(rtlpriv, ARFR0 + ratr_index * 4, ratr_value);
2075 if (ratr_value & 0xfffff000)
2076 rtl92s_phy_set_fw_cmd(hw, FW_CMD_RA_REFRESH_N);
2077 else
2078 rtl92s_phy_set_fw_cmd(hw, FW_CMD_RA_REFRESH_BG);
2079
2080 RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
2081 ("%x\n", rtl_read_dword(rtlpriv, ARFR0)));
2082}
2083
2084static void rtl92se_update_hal_rate_mask(struct ieee80211_hw *hw,
2085 struct ieee80211_sta *sta,
2086 u8 rssi_level)
2087{
2088 struct rtl_priv *rtlpriv = rtl_priv(hw);
2089 struct rtl_phy *rtlphy = &(rtlpriv->phy);
2090 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2091 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
2092 struct rtl_sta_info *sta_entry = NULL;
2093 u32 ratr_bitmap;
2094 u8 ratr_index = 0;
2095 u8 curtxbw_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)
2096 ? 1 : 0;
2097 u8 curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ?
2098 1 : 0;
2099 u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ?
2100 1 : 0;
2101 enum wireless_mode wirelessmode = 0;
2102 bool shortgi = false;
2103 u32 ratr_value = 0;
2104 u8 shortgi_rate = 0;
2105 u32 mask = 0;
2106 u32 band = 0;
2107 bool bmulticast = false;
2108 u8 macid = 0;
2109 u8 mimo_ps = IEEE80211_SMPS_OFF;
2110
2111 sta_entry = (struct rtl_sta_info *) sta->drv_priv;
2112 wirelessmode = sta_entry->wireless_mode;
2113 if (mac->opmode == NL80211_IFTYPE_STATION)
2114 curtxbw_40mhz = mac->bw_40;
2115 else if (mac->opmode == NL80211_IFTYPE_AP ||
2116 mac->opmode == NL80211_IFTYPE_ADHOC)
2117 macid = sta->aid + 1;
2118
2119 if (rtlhal->current_bandtype == BAND_ON_5G)
2120 ratr_bitmap = sta->supp_rates[1] << 4;
2121 else
2122 ratr_bitmap = sta->supp_rates[0];
2123 ratr_bitmap |= (sta->ht_cap.mcs.rx_mask[1] << 20 |
2124 sta->ht_cap.mcs.rx_mask[0] << 12);
2125 switch (wirelessmode) {
2126 case WIRELESS_MODE_B:
2127 band |= WIRELESS_11B;
2128 ratr_index = RATR_INX_WIRELESS_B;
2129 if (ratr_bitmap & 0x0000000c)
2130 ratr_bitmap &= 0x0000000d;
2131 else
2132 ratr_bitmap &= 0x0000000f;
2133 break;
2134 case WIRELESS_MODE_G:
2135 band |= (WIRELESS_11G | WIRELESS_11B);
2136 ratr_index = RATR_INX_WIRELESS_GB;
2137
2138 if (rssi_level == 1)
2139 ratr_bitmap &= 0x00000f00;
2140 else if (rssi_level == 2)
2141 ratr_bitmap &= 0x00000ff0;
2142 else
2143 ratr_bitmap &= 0x00000ff5;
2144 break;
2145 case WIRELESS_MODE_A:
2146 band |= WIRELESS_11A;
2147 ratr_index = RATR_INX_WIRELESS_A;
2148 ratr_bitmap &= 0x00000ff0;
2149 break;
2150 case WIRELESS_MODE_N_24G:
2151 case WIRELESS_MODE_N_5G:
2152 band |= (WIRELESS_11N | WIRELESS_11G | WIRELESS_11B);
2153 ratr_index = RATR_INX_WIRELESS_NGB;
2154
2155 if (mimo_ps == IEEE80211_SMPS_STATIC) {
2156 if (rssi_level == 1)
2157 ratr_bitmap &= 0x00070000;
2158 else if (rssi_level == 2)
2159 ratr_bitmap &= 0x0007f000;
2160 else
2161 ratr_bitmap &= 0x0007f005;
2162 } else {
2163 if (rtlphy->rf_type == RF_1T2R ||
2164 rtlphy->rf_type == RF_1T1R) {
2165 if (rssi_level == 1) {
2166 ratr_bitmap &= 0x000f0000;
2167 } else if (rssi_level == 3) {
2168 ratr_bitmap &= 0x000fc000;
2169 } else if (rssi_level == 5) {
2170 ratr_bitmap &= 0x000ff000;
2171 } else {
2172 if (curtxbw_40mhz)
2173 ratr_bitmap &= 0x000ff015;
2174 else
2175 ratr_bitmap &= 0x000ff005;
2176 }
2177 } else {
2178 if (rssi_level == 1) {
2179 ratr_bitmap &= 0x0f8f0000;
2180 } else if (rssi_level == 3) {
2181 ratr_bitmap &= 0x0f8fc000;
2182 } else if (rssi_level == 5) {
2183 ratr_bitmap &= 0x0f8ff000;
2184 } else {
2185 if (curtxbw_40mhz)
2186 ratr_bitmap &= 0x0f8ff015;
2187 else
2188 ratr_bitmap &= 0x0f8ff005;
2189 }
2190 }
2191 }
2192
2193 if ((curtxbw_40mhz && curshortgi_40mhz) ||
2194 (!curtxbw_40mhz && curshortgi_20mhz)) {
2195 if (macid == 0)
2196 shortgi = true;
2197 else if (macid == 1)
2198 shortgi = false;
2199 }
2200 break;
2201 default:
2202 band |= (WIRELESS_11N | WIRELESS_11G | WIRELESS_11B);
2203 ratr_index = RATR_INX_WIRELESS_NGB;
2204
2205 if (rtlphy->rf_type == RF_1T2R)
2206 ratr_bitmap &= 0x000ff0ff;
2207 else
2208 ratr_bitmap &= 0x0f8ff0ff;
2209 break;
2210 }
2211
2212 if (rtlpriv->rtlhal.version >= VERSION_8192S_BCUT)
2213 ratr_bitmap &= 0x0FFFFFFF;
2214 else if (rtlpriv->rtlhal.version == VERSION_8192S_ACUT)
2215 ratr_bitmap &= 0x0FFFFFF0;
2216
2217 if (shortgi) {
2218 ratr_bitmap |= 0x10000000;
2219 /* Get MAX MCS available. */
2220 ratr_value = (ratr_bitmap >> 12);
2221 for (shortgi_rate = 15; shortgi_rate > 0; shortgi_rate--) {
2222 if ((1 << shortgi_rate) & ratr_value)
2223 break;
2224 }
2225
2226 shortgi_rate = (shortgi_rate << 12) | (shortgi_rate << 8) |
2227 (shortgi_rate << 4) | (shortgi_rate);
2228 rtl_write_byte(rtlpriv, SG_RATE, shortgi_rate);
2229 }
2230
2231 mask |= (bmulticast ? 1 : 0) << 9 | (macid & 0x1f) << 4 | (band & 0xf);
2232
2233 RT_TRACE(rtlpriv, COMP_RATR, DBG_TRACE, ("mask = %x, bitmap = %x\n",
2234 mask, ratr_bitmap));
2235 rtl_write_dword(rtlpriv, 0x2c4, ratr_bitmap);
2236 rtl_write_dword(rtlpriv, WFM5, (FW_RA_UPDATE_MASK | (mask << 8)));
2237
2238 if (macid != 0)
2239 sta_entry->ratr_index = ratr_index;
2240}
2241
2242void rtl92se_update_hal_rate_tbl(struct ieee80211_hw *hw,
2243 struct ieee80211_sta *sta, u8 rssi_level)
2244{
2245 struct rtl_priv *rtlpriv = rtl_priv(hw);
2246
2247 if (rtlpriv->dm.useramask)
2248 rtl92se_update_hal_rate_mask(hw, sta, rssi_level);
2249 else
2250 rtl92se_update_hal_rate_table(hw, sta);
2251}
2252
2253void rtl92se_update_channel_access_setting(struct ieee80211_hw *hw)
2254{
2255 struct rtl_priv *rtlpriv = rtl_priv(hw);
2256 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2257 u16 sifs_timer;
2258
2259 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME,
2260 (u8 *)&mac->slot_time);
2261 sifs_timer = 0x0e0e;
2262 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SIFS, (u8 *)&sifs_timer);
2263
2264}
2265
2266/* this ifunction is for RFKILL, it's different with windows,
2267 * because UI will disable wireless when GPIO Radio Off.
2268 * And here we not check or Disable/Enable ASPM like windows*/
2269bool rtl92se_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid)
2270{
2271 struct rtl_priv *rtlpriv = rtl_priv(hw);
2272 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
2273 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
2274 enum rf_pwrstate rfpwr_toset, cur_rfstate;
2275 unsigned long flag = 0;
2276 bool actuallyset = false;
2277 bool turnonbypowerdomain = false;
2278
2279 /* just 8191se can check gpio before firstup, 92c/92d have fixed it */
2280 if ((rtlpci->up_first_time == 1) || (rtlpci->being_init_adapter))
2281 return false;
2282
2283 if (ppsc->swrf_processing)
2284 return false;
2285
2286 spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag);
2287 if (ppsc->rfchange_inprogress) {
2288 spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag);
2289 return false;
2290 } else {
2291 ppsc->rfchange_inprogress = true;
2292 spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag);
2293 }
2294
2295 cur_rfstate = ppsc->rfpwr_state;
2296
2297 /* because after _rtl92s_phy_set_rfhalt, all power
2298 * closed, so we must open some power for GPIO check,
2299 * or we will always check GPIO RFOFF here,
2300 * And we should close power after GPIO check */
2301 if (RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
2302 _rtl92se_power_domain_init(hw);
2303 turnonbypowerdomain = true;
2304 }
2305
2306 rfpwr_toset = _rtl92se_rf_onoff_detect(hw);
2307
2308 if ((ppsc->hwradiooff == true) && (rfpwr_toset == ERFON)) {
2309 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2310 ("RFKILL-HW Radio ON, RF ON\n"));
2311
2312 rfpwr_toset = ERFON;
2313 ppsc->hwradiooff = false;
2314 actuallyset = true;
2315 } else if ((ppsc->hwradiooff == false) && (rfpwr_toset == ERFOFF)) {
2316 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2317 ("RFKILL-HW Radio OFF, RF OFF\n"));
2318
2319 rfpwr_toset = ERFOFF;
2320 ppsc->hwradiooff = true;
2321 actuallyset = true;
2322 }
2323
2324 if (actuallyset) {
2325 spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag);
2326 ppsc->rfchange_inprogress = false;
2327 spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag);
2328
2329 /* this not include ifconfig wlan0 down case */
2330 /* } else if (rfpwr_toset == ERFOFF || cur_rfstate == ERFOFF) { */
2331 } else {
2332 /* because power_domain_init may be happen when
2333 * _rtl92s_phy_set_rfhalt, this will open some powers
2334 * and cause current increasing about 40 mA for ips,
2335 * rfoff and ifconfig down, so we set
2336 * _rtl92s_phy_set_rfhalt again here */
2337 if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC &&
2338 turnonbypowerdomain) {
2339 _rtl92s_phy_set_rfhalt(hw);
2340 RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
2341 }
2342
2343 spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag);
2344 ppsc->rfchange_inprogress = false;
2345 spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag);
2346 }
2347
2348 *valid = 1;
2349 return !ppsc->hwradiooff;
2350
2351}
2352
2353/* Is_wepkey just used for WEP used as group & pairwise key
2354 * if pairwise is AES ang group is WEP Is_wepkey == false.*/
2355void rtl92se_set_key(struct ieee80211_hw *hw, u32 key_index, u8 *p_macaddr,
2356 bool is_group, u8 enc_algo, bool is_wepkey, bool clear_all)
2357{
2358 struct rtl_priv *rtlpriv = rtl_priv(hw);
2359 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2360 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
2361 u8 *macaddr = p_macaddr;
2362
2363 u32 entry_id = 0;
2364 bool is_pairwise = false;
2365
2366 static u8 cam_const_addr[4][6] = {
2367 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
2368 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
2369 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
2370 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}
2371 };
2372 static u8 cam_const_broad[] = {
2373 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
2374 };
2375
2376 if (clear_all) {
2377 u8 idx = 0;
2378 u8 cam_offset = 0;
2379 u8 clear_number = 5;
2380
2381 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("clear_all\n"));
2382
2383 for (idx = 0; idx < clear_number; idx++) {
2384 rtl_cam_mark_invalid(hw, cam_offset + idx);
2385 rtl_cam_empty_entry(hw, cam_offset + idx);
2386
2387 if (idx < 5) {
2388 memset(rtlpriv->sec.key_buf[idx], 0,
2389 MAX_KEY_LEN);
2390 rtlpriv->sec.key_len[idx] = 0;
2391 }
2392 }
2393
2394 } else {
2395 switch (enc_algo) {
2396 case WEP40_ENCRYPTION:
2397 enc_algo = CAM_WEP40;
2398 break;
2399 case WEP104_ENCRYPTION:
2400 enc_algo = CAM_WEP104;
2401 break;
2402 case TKIP_ENCRYPTION:
2403 enc_algo = CAM_TKIP;
2404 break;
2405 case AESCCMP_ENCRYPTION:
2406 enc_algo = CAM_AES;
2407 break;
2408 default:
2409 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
2410 ("switch case not process\n"));
2411 enc_algo = CAM_TKIP;
2412 break;
2413 }
2414
2415 if (is_wepkey || rtlpriv->sec.use_defaultkey) {
2416 macaddr = cam_const_addr[key_index];
2417 entry_id = key_index;
2418 } else {
2419 if (is_group) {
2420 macaddr = cam_const_broad;
2421 entry_id = key_index;
2422 } else {
2423 if (mac->opmode == NL80211_IFTYPE_AP) {
2424 entry_id = rtl_cam_get_free_entry(hw,
2425 p_macaddr);
2426 if (entry_id >= TOTAL_CAM_ENTRY) {
2427 RT_TRACE(rtlpriv,
2428 COMP_SEC, DBG_EMERG,
2429 ("Can not find free hw"
2430 " security cam entry\n"));
2431 return;
2432 }
2433 } else {
2434 entry_id = CAM_PAIRWISE_KEY_POSITION;
2435 }
2436
2437 key_index = PAIRWISE_KEYIDX;
2438 is_pairwise = true;
2439 }
2440 }
2441
2442 if (rtlpriv->sec.key_len[key_index] == 0) {
2443 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
2444 ("delete one entry, entry_id is %d\n",
2445 entry_id));
2446 if (mac->opmode == NL80211_IFTYPE_AP)
2447 rtl_cam_del_entry(hw, p_macaddr);
2448 rtl_cam_delete_one_entry(hw, p_macaddr, entry_id);
2449 } else {
2450 RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
2451 ("The insert KEY length is %d\n",
2452 rtlpriv->sec.key_len[PAIRWISE_KEYIDX]));
2453 RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
2454 ("The insert KEY is %x %x\n",
2455 rtlpriv->sec.key_buf[0][0],
2456 rtlpriv->sec.key_buf[0][1]));
2457
2458 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
2459 ("add one entry\n"));
2460 if (is_pairwise) {
2461 RT_PRINT_DATA(rtlpriv, COMP_SEC, DBG_LOUD,
2462 "Pairwiase Key content :",
2463 rtlpriv->sec.pairwise_key,
2464 rtlpriv->sec.key_len[PAIRWISE_KEYIDX]);
2465
2466 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
2467 ("set Pairwiase key\n"));
2468
2469 rtl_cam_add_one_entry(hw, macaddr, key_index,
2470 entry_id, enc_algo,
2471 CAM_CONFIG_NO_USEDK,
2472 rtlpriv->sec.key_buf[key_index]);
2473 } else {
2474 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
2475 ("set group key\n"));
2476
2477 if (mac->opmode == NL80211_IFTYPE_ADHOC) {
2478 rtl_cam_add_one_entry(hw,
2479 rtlefuse->dev_addr,
2480 PAIRWISE_KEYIDX,
2481 CAM_PAIRWISE_KEY_POSITION,
2482 enc_algo, CAM_CONFIG_NO_USEDK,
2483 rtlpriv->sec.key_buf[entry_id]);
2484 }
2485
2486 rtl_cam_add_one_entry(hw, macaddr, key_index,
2487 entry_id, enc_algo,
2488 CAM_CONFIG_NO_USEDK,
2489 rtlpriv->sec.key_buf[entry_id]);
2490 }
2491
2492 }
2493 }
2494}
2495
2496void rtl92se_suspend(struct ieee80211_hw *hw)
2497{
2498 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
2499
2500 rtlpci->up_first_time = true;
2501}
2502
2503void rtl92se_resume(struct ieee80211_hw *hw)
2504{
2505 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
2506 u32 val;
2507
2508 pci_read_config_dword(rtlpci->pdev, 0x40, &val);
2509 if ((val & 0x0000ff00) != 0)
2510 pci_write_config_dword(rtlpci->pdev, 0x40,
2511 val & 0xffff00ff);
2512}
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/hw.h b/drivers/net/wireless/rtlwifi/rtl8192se/hw.h
new file mode 100644
index 000000000000..6160a9bfe98a
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/hw.h
@@ -0,0 +1,79 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2010 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29#ifndef __REALTEK_PCI92SE_HW_H__
30#define __REALTEK_PCI92SE_HW_H__
31
32#define MSR_LINK_MANAGED 2
33#define MSR_LINK_NONE 0
34#define MSR_LINK_SHIFT 0
35#define MSR_LINK_ADHOC 1
36#define MSR_LINK_MASTER 3
37
38enum WIRELESS_NETWORK_TYPE {
39 WIRELESS_11B = 1,
40 WIRELESS_11G = 2,
41 WIRELESS_11A = 4,
42 WIRELESS_11N = 8
43};
44
45void rtl92se_get_hw_reg(struct ieee80211_hw *hw,
46 u8 variable, u8 *val);
47void rtl92se_read_eeprom_info(struct ieee80211_hw *hw);
48void rtl92se_interrupt_recognized(struct ieee80211_hw *hw,
49 u32 *inta, u32 *intb);
50int rtl92se_hw_init(struct ieee80211_hw *hw);
51void rtl92se_card_disable(struct ieee80211_hw *hw);
52void rtl92se_enable_interrupt(struct ieee80211_hw *hw);
53void rtl92se_disable_interrupt(struct ieee80211_hw *hw);
54int rtl92se_set_network_type(struct ieee80211_hw *hw,
55 enum nl80211_iftype type);
56void rtl92se_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid);
57void rtl92se_set_mac_addr(struct rtl_io *io, const u8 * addr);
58void rtl92se_set_qos(struct ieee80211_hw *hw, int aci);
59void rtl92se_set_beacon_related_registers(struct ieee80211_hw *hw);
60void rtl92se_set_beacon_interval(struct ieee80211_hw *hw);
61void rtl92se_update_interrupt_mask(struct ieee80211_hw *hw,
62 u32 add_msr, u32 rm_msr);
63void rtl92se_set_hw_reg(struct ieee80211_hw *hw, u8 variable,
64 u8 *val);
65void rtl92se_update_hal_rate_tbl(struct ieee80211_hw *hw,
66 struct ieee80211_sta *sta, u8 rssi_level);
67void rtl92se_update_channel_access_setting(struct ieee80211_hw *hw);
68bool rtl92se_gpio_radio_on_off_checking(struct ieee80211_hw *hw,
69 u8 *valid);
70void rtl8192se_gpiobit3_cfg_inputmode(struct ieee80211_hw *hw);
71void rtl92se_enable_hw_security_config(struct ieee80211_hw *hw);
72void rtl92se_set_key(struct ieee80211_hw *hw,
73 u32 key_index, u8 *macaddr, bool is_group,
74 u8 enc_algo, bool is_wepkey, bool clear_all);
75void rtl92se_suspend(struct ieee80211_hw *hw);
76void rtl92se_resume(struct ieee80211_hw *hw);
77
78#endif
79
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/led.c b/drivers/net/wireless/rtlwifi/rtl8192se/led.c
new file mode 100644
index 000000000000..6d4f66616680
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/led.c
@@ -0,0 +1,149 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2010 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#include "../wifi.h"
31#include "../pci.h"
32#include "reg.h"
33#include "led.h"
34
35static void _rtl92se_init_led(struct ieee80211_hw *hw,
36 struct rtl_led *pled, enum rtl_led_pin ledpin)
37{
38 pled->hw = hw;
39 pled->ledpin = ledpin;
40 pled->ledon = false;
41}
42
43void rtl92se_init_sw_leds(struct ieee80211_hw *hw)
44{
45 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
46 _rtl92se_init_led(hw, &(pcipriv->ledctl.sw_led0), LED_PIN_LED0);
47 _rtl92se_init_led(hw, &(pcipriv->ledctl.sw_led1), LED_PIN_LED1);
48}
49
50void rtl92se_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled)
51{
52 u8 ledcfg;
53 struct rtl_priv *rtlpriv = rtl_priv(hw);
54
55 RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD,
56 ("LedAddr:%X ledpin=%d\n", LEDCFG, pled->ledpin));
57
58 ledcfg = rtl_read_byte(rtlpriv, LEDCFG);
59
60 switch (pled->ledpin) {
61 case LED_PIN_GPIO0:
62 break;
63 case LED_PIN_LED0:
64 rtl_write_byte(rtlpriv, LEDCFG, ledcfg & 0xf0);
65 break;
66 case LED_PIN_LED1:
67 rtl_write_byte(rtlpriv, LEDCFG, ledcfg & 0x0f);
68 break;
69 default:
70 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
71 ("switch case not process\n"));
72 break;
73 }
74 pled->ledon = true;
75}
76
77void rtl92se_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled)
78{
79 struct rtl_priv *rtlpriv = rtl_priv(hw);
80 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
81 u8 ledcfg;
82
83 RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD,
84 ("LedAddr:%X ledpin=%d\n", LEDCFG, pled->ledpin));
85
86 ledcfg = rtl_read_byte(rtlpriv, LEDCFG);
87
88 switch (pled->ledpin) {
89 case LED_PIN_GPIO0:
90 break;
91 case LED_PIN_LED0:
92 ledcfg &= 0xf0;
93 if (pcipriv->ledctl.led_opendrain == true)
94 rtl_write_byte(rtlpriv, LEDCFG, (ledcfg | BIT(1)));
95 else
96 rtl_write_byte(rtlpriv, LEDCFG, (ledcfg | BIT(3)));
97 break;
98 case LED_PIN_LED1:
99 ledcfg &= 0x0f;
100 rtl_write_byte(rtlpriv, LEDCFG, (ledcfg | BIT(3)));
101 break;
102 default:
103 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
104 ("switch case not process\n"));
105 break;
106 }
107 pled->ledon = false;
108}
109
110static void _rtl92se_sw_led_control(struct ieee80211_hw *hw,
111 enum led_ctl_mode ledaction)
112{
113 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
114 struct rtl_led *pLed0 = &(pcipriv->ledctl.sw_led0);
115 switch (ledaction) {
116 case LED_CTL_POWER_ON:
117 case LED_CTL_LINK:
118 case LED_CTL_NO_LINK:
119 rtl92se_sw_led_on(hw, pLed0);
120 break;
121 case LED_CTL_POWER_OFF:
122 rtl92se_sw_led_off(hw, pLed0);
123 break;
124 default:
125 break;
126 }
127}
128
129void rtl92se_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction)
130{
131 struct rtl_priv *rtlpriv = rtl_priv(hw);
132 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
133
134 if ((ppsc->rfoff_reason > RF_CHANGE_BY_PS) &&
135 (ledaction == LED_CTL_TX ||
136 ledaction == LED_CTL_RX ||
137 ledaction == LED_CTL_SITE_SURVEY ||
138 ledaction == LED_CTL_LINK ||
139 ledaction == LED_CTL_NO_LINK ||
140 ledaction == LED_CTL_START_TO_LINK ||
141 ledaction == LED_CTL_POWER_ON)) {
142 return;
143 }
144 RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, ("ledaction %d,\n",
145 ledaction));
146
147 _rtl92se_sw_led_control(hw, ledaction);
148}
149
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/led.h b/drivers/net/wireless/rtlwifi/rtl8192se/led.h
new file mode 100644
index 000000000000..8cce3870af3c
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/led.h
@@ -0,0 +1,37 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2010 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29#ifndef __REALTEK_PCI92SE_LED_H__
30#define __REALTEK_PCI92SE_LED_H__
31
32void rtl92se_init_sw_leds(struct ieee80211_hw *hw);
33void rtl92se_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled);
34void rtl92se_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled);
35void rtl92se_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction);
36
37#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/phy.c b/drivers/net/wireless/rtlwifi/rtl8192se/phy.c
new file mode 100644
index 000000000000..63b45e60a95e
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/phy.c
@@ -0,0 +1,1740 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2010 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#include "../wifi.h"
31#include "../pci.h"
32#include "../ps.h"
33#include "reg.h"
34#include "def.h"
35#include "phy.h"
36#include "rf.h"
37#include "dm.h"
38#include "fw.h"
39#include "hw.h"
40#include "table.h"
41
42static u32 _rtl92s_phy_calculate_bit_shift(u32 bitmask)
43{
44 u32 i;
45
46 for (i = 0; i <= 31; i++) {
47 if (((bitmask >> i) & 0x1) == 1)
48 break;
49 }
50
51 return i;
52}
53
54u32 rtl92s_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask)
55{
56 struct rtl_priv *rtlpriv = rtl_priv(hw);
57 u32 returnvalue = 0, originalvalue, bitshift;
58
59 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x)\n",
60 regaddr, bitmask));
61
62 originalvalue = rtl_read_dword(rtlpriv, regaddr);
63 bitshift = _rtl92s_phy_calculate_bit_shift(bitmask);
64 returnvalue = (originalvalue & bitmask) >> bitshift;
65
66 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
67 ("BBR MASK=0x%x Addr[0x%x]=0x%x\n",
68 bitmask, regaddr, originalvalue));
69
70 return returnvalue;
71
72}
73
74void rtl92s_phy_set_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask,
75 u32 data)
76{
77 struct rtl_priv *rtlpriv = rtl_priv(hw);
78 u32 originalvalue, bitshift;
79
80 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x),"
81 " data(%#x)\n", regaddr, bitmask, data));
82
83 if (bitmask != MASKDWORD) {
84 originalvalue = rtl_read_dword(rtlpriv, regaddr);
85 bitshift = _rtl92s_phy_calculate_bit_shift(bitmask);
86 data = ((originalvalue & (~bitmask)) | (data << bitshift));
87 }
88
89 rtl_write_dword(rtlpriv, regaddr, data);
90
91 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x),"
92 " data(%#x)\n", regaddr, bitmask, data));
93
94}
95
96static u32 _rtl92s_phy_rf_serial_read(struct ieee80211_hw *hw,
97 enum radio_path rfpath, u32 offset)
98{
99
100 struct rtl_priv *rtlpriv = rtl_priv(hw);
101 struct rtl_phy *rtlphy = &(rtlpriv->phy);
102 struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
103 u32 newoffset;
104 u32 tmplong, tmplong2;
105 u8 rfpi_enable = 0;
106 u32 retvalue = 0;
107
108 offset &= 0x3f;
109 newoffset = offset;
110
111 tmplong = rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD);
112
113 if (rfpath == RF90_PATH_A)
114 tmplong2 = tmplong;
115 else
116 tmplong2 = rtl_get_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD);
117
118 tmplong2 = (tmplong2 & (~BLSSI_READADDRESS)) | (newoffset << 23) |
119 BLSSI_READEDGE;
120
121 rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD,
122 tmplong & (~BLSSI_READEDGE));
123
124 mdelay(1);
125
126 rtl_set_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD, tmplong2);
127 mdelay(1);
128
129 rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD, tmplong |
130 BLSSI_READEDGE);
131 mdelay(1);
132
133 if (rfpath == RF90_PATH_A)
134 rfpi_enable = (u8)rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER1,
135 BIT(8));
136 else if (rfpath == RF90_PATH_B)
137 rfpi_enable = (u8)rtl_get_bbreg(hw, RFPGA0_XB_HSSIPARAMETER1,
138 BIT(8));
139
140 if (rfpi_enable)
141 retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readbackpi,
142 BLSSI_READBACK_DATA);
143 else
144 retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readback,
145 BLSSI_READBACK_DATA);
146
147 retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readback,
148 BLSSI_READBACK_DATA);
149
150 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFR-%d Addr[0x%x]=0x%x\n",
151 rfpath, pphyreg->rflssi_readback, retvalue));
152
153 return retvalue;
154
155}
156
157static void _rtl92s_phy_rf_serial_write(struct ieee80211_hw *hw,
158 enum radio_path rfpath, u32 offset,
159 u32 data)
160{
161 struct rtl_priv *rtlpriv = rtl_priv(hw);
162 struct rtl_phy *rtlphy = &(rtlpriv->phy);
163 struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
164 u32 data_and_addr = 0;
165 u32 newoffset;
166
167 offset &= 0x3f;
168 newoffset = offset;
169
170 data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff;
171 rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr);
172
173 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFW-%d Addr[0x%x]=0x%x\n",
174 rfpath, pphyreg->rf3wire_offset, data_and_addr));
175}
176
177
178u32 rtl92s_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
179 u32 regaddr, u32 bitmask)
180{
181 struct rtl_priv *rtlpriv = rtl_priv(hw);
182 u32 original_value, readback_value, bitshift;
183 unsigned long flags;
184
185 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), rfpath(%#x), "
186 "bitmask(%#x)\n", regaddr, rfpath, bitmask));
187
188 spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
189
190 original_value = _rtl92s_phy_rf_serial_read(hw, rfpath, regaddr);
191
192 bitshift = _rtl92s_phy_calculate_bit_shift(bitmask);
193 readback_value = (original_value & bitmask) >> bitshift;
194
195 spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
196
197 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), rfpath(%#x), "
198 "bitmask(%#x), original_value(%#x)\n", regaddr, rfpath,
199 bitmask, original_value));
200
201 return readback_value;
202}
203
204void rtl92s_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
205 u32 regaddr, u32 bitmask, u32 data)
206{
207 struct rtl_priv *rtlpriv = rtl_priv(hw);
208 struct rtl_phy *rtlphy = &(rtlpriv->phy);
209 u32 original_value, bitshift;
210 unsigned long flags;
211
212 if (!((rtlphy->rf_pathmap >> rfpath) & 0x1))
213 return;
214
215 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x),"
216 " data(%#x), rfpath(%#x)\n", regaddr, bitmask, data, rfpath));
217
218 spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
219
220 if (bitmask != RFREG_OFFSET_MASK) {
221 original_value = _rtl92s_phy_rf_serial_read(hw, rfpath,
222 regaddr);
223 bitshift = _rtl92s_phy_calculate_bit_shift(bitmask);
224 data = ((original_value & (~bitmask)) | (data << bitshift));
225 }
226
227 _rtl92s_phy_rf_serial_write(hw, rfpath, regaddr, data);
228
229 spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
230
231 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x), "
232 "data(%#x), rfpath(%#x)\n", regaddr, bitmask, data, rfpath));
233
234}
235
236void rtl92s_phy_scan_operation_backup(struct ieee80211_hw *hw,
237 u8 operation)
238{
239 struct rtl_priv *rtlpriv = rtl_priv(hw);
240 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
241
242 if (!is_hal_stop(rtlhal)) {
243 switch (operation) {
244 case SCAN_OPT_BACKUP:
245 rtl92s_phy_set_fw_cmd(hw, FW_CMD_PAUSE_DM_BY_SCAN);
246 break;
247 case SCAN_OPT_RESTORE:
248 rtl92s_phy_set_fw_cmd(hw, FW_CMD_RESUME_DM_BY_SCAN);
249 break;
250 default:
251 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
252 ("Unknown operation.\n"));
253 break;
254 }
255 }
256}
257
258void rtl92s_phy_set_bw_mode(struct ieee80211_hw *hw,
259 enum nl80211_channel_type ch_type)
260{
261 struct rtl_priv *rtlpriv = rtl_priv(hw);
262 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
263 struct rtl_phy *rtlphy = &(rtlpriv->phy);
264 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
265 u8 reg_bw_opmode;
266 u8 reg_prsr_rsc;
267
268 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("Switch to %s bandwidth\n",
269 rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
270 "20MHz" : "40MHz"));
271
272 if (rtlphy->set_bwmode_inprogress)
273 return;
274 if (is_hal_stop(rtlhal))
275 return;
276
277 rtlphy->set_bwmode_inprogress = true;
278
279 reg_bw_opmode = rtl_read_byte(rtlpriv, BW_OPMODE);
280 reg_prsr_rsc = rtl_read_byte(rtlpriv, RRSR + 2);
281
282 switch (rtlphy->current_chan_bw) {
283 case HT_CHANNEL_WIDTH_20:
284 reg_bw_opmode |= BW_OPMODE_20MHZ;
285 rtl_write_byte(rtlpriv, BW_OPMODE, reg_bw_opmode);
286 break;
287 case HT_CHANNEL_WIDTH_20_40:
288 reg_bw_opmode &= ~BW_OPMODE_20MHZ;
289 rtl_write_byte(rtlpriv, BW_OPMODE, reg_bw_opmode);
290 break;
291 default:
292 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
293 ("unknown bandwidth: %#X\n",
294 rtlphy->current_chan_bw));
295 break;
296 }
297
298 switch (rtlphy->current_chan_bw) {
299 case HT_CHANNEL_WIDTH_20:
300 rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0);
301 rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0);
302
303 if (rtlhal->version >= VERSION_8192S_BCUT)
304 rtl_write_byte(rtlpriv, RFPGA0_ANALOGPARAMETER2, 0x58);
305 break;
306 case HT_CHANNEL_WIDTH_20_40:
307 rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1);
308 rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1);
309
310 rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND,
311 (mac->cur_40_prime_sc >> 1));
312 rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc);
313
314 if (rtlhal->version >= VERSION_8192S_BCUT)
315 rtl_write_byte(rtlpriv, RFPGA0_ANALOGPARAMETER2, 0x18);
316 break;
317 default:
318 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
319 ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw));
320 break;
321 }
322
323 rtl92s_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
324 rtlphy->set_bwmode_inprogress = false;
325 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n"));
326}
327
328static bool _rtl92s_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable,
329 u32 cmdtableidx, u32 cmdtablesz, enum swchnlcmd_id cmdid,
330 u32 para1, u32 para2, u32 msdelay)
331{
332 struct swchnlcmd *pcmd;
333
334 if (cmdtable == NULL) {
335 RT_ASSERT(false, ("cmdtable cannot be NULL.\n"));
336 return false;
337 }
338
339 if (cmdtableidx >= cmdtablesz)
340 return false;
341
342 pcmd = cmdtable + cmdtableidx;
343 pcmd->cmdid = cmdid;
344 pcmd->para1 = para1;
345 pcmd->para2 = para2;
346 pcmd->msdelay = msdelay;
347
348 return true;
349}
350
351static bool _rtl92s_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,
352 u8 channel, u8 *stage, u8 *step, u32 *delay)
353{
354 struct rtl_priv *rtlpriv = rtl_priv(hw);
355 struct rtl_phy *rtlphy = &(rtlpriv->phy);
356 struct swchnlcmd precommoncmd[MAX_PRECMD_CNT];
357 u32 precommoncmdcnt;
358 struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT];
359 u32 postcommoncmdcnt;
360 struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT];
361 u32 rfdependcmdcnt;
362 struct swchnlcmd *currentcmd = NULL;
363 u8 rfpath;
364 u8 num_total_rfpath = rtlphy->num_total_rfpath;
365
366 precommoncmdcnt = 0;
367 _rtl92s_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
368 MAX_PRECMD_CNT, CMDID_SET_TXPOWEROWER_LEVEL, 0, 0, 0);
369 _rtl92s_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
370 MAX_PRECMD_CNT, CMDID_END, 0, 0, 0);
371
372 postcommoncmdcnt = 0;
373
374 _rtl92s_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++,
375 MAX_POSTCMD_CNT, CMDID_END, 0, 0, 0);
376
377 rfdependcmdcnt = 0;
378
379 RT_ASSERT((channel >= 1 && channel <= 14),
380 ("illegal channel for Zebra: %d\n", channel));
381
382 _rtl92s_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
383 MAX_RFDEPENDCMD_CNT, CMDID_RF_WRITEREG,
384 RF_CHNLBW, channel, 10);
385
386 _rtl92s_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
387 MAX_RFDEPENDCMD_CNT, CMDID_END, 0, 0, 0);
388
389 do {
390 switch (*stage) {
391 case 0:
392 currentcmd = &precommoncmd[*step];
393 break;
394 case 1:
395 currentcmd = &rfdependcmd[*step];
396 break;
397 case 2:
398 currentcmd = &postcommoncmd[*step];
399 break;
400 }
401
402 if (currentcmd->cmdid == CMDID_END) {
403 if ((*stage) == 2) {
404 return true;
405 } else {
406 (*stage)++;
407 (*step) = 0;
408 continue;
409 }
410 }
411
412 switch (currentcmd->cmdid) {
413 case CMDID_SET_TXPOWEROWER_LEVEL:
414 rtl92s_phy_set_txpower(hw, channel);
415 break;
416 case CMDID_WRITEPORT_ULONG:
417 rtl_write_dword(rtlpriv, currentcmd->para1,
418 currentcmd->para2);
419 break;
420 case CMDID_WRITEPORT_USHORT:
421 rtl_write_word(rtlpriv, currentcmd->para1,
422 (u16)currentcmd->para2);
423 break;
424 case CMDID_WRITEPORT_UCHAR:
425 rtl_write_byte(rtlpriv, currentcmd->para1,
426 (u8)currentcmd->para2);
427 break;
428 case CMDID_RF_WRITEREG:
429 for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) {
430 rtlphy->rfreg_chnlval[rfpath] =
431 ((rtlphy->rfreg_chnlval[rfpath] &
432 0xfffffc00) | currentcmd->para2);
433 rtl_set_rfreg(hw, (enum radio_path)rfpath,
434 currentcmd->para1,
435 RFREG_OFFSET_MASK,
436 rtlphy->rfreg_chnlval[rfpath]);
437 }
438 break;
439 default:
440 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
441 ("switch case not process\n"));
442 break;
443 }
444
445 break;
446 } while (true);
447
448 (*delay) = currentcmd->msdelay;
449 (*step)++;
450 return false;
451}
452
453u8 rtl92s_phy_sw_chnl(struct ieee80211_hw *hw)
454{
455 struct rtl_priv *rtlpriv = rtl_priv(hw);
456 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
457 struct rtl_phy *rtlphy = &(rtlpriv->phy);
458 u32 delay;
459 bool ret;
460
461 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
462 ("switch to channel%d\n",
463 rtlphy->current_channel));
464
465 if (rtlphy->sw_chnl_inprogress)
466 return 0;
467
468 if (rtlphy->set_bwmode_inprogress)
469 return 0;
470
471 if (is_hal_stop(rtlhal))
472 return 0;
473
474 rtlphy->sw_chnl_inprogress = true;
475 rtlphy->sw_chnl_stage = 0;
476 rtlphy->sw_chnl_step = 0;
477
478 do {
479 if (!rtlphy->sw_chnl_inprogress)
480 break;
481
482 ret = _rtl92s_phy_sw_chnl_step_by_step(hw,
483 rtlphy->current_channel,
484 &rtlphy->sw_chnl_stage,
485 &rtlphy->sw_chnl_step, &delay);
486 if (!ret) {
487 if (delay > 0)
488 mdelay(delay);
489 else
490 continue;
491 } else {
492 rtlphy->sw_chnl_inprogress = false;
493 }
494 break;
495 } while (true);
496
497 rtlphy->sw_chnl_inprogress = false;
498
499 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n"));
500
501 return 1;
502}
503
504static void _rtl92se_phy_set_rf_sleep(struct ieee80211_hw *hw)
505{
506 struct rtl_priv *rtlpriv = rtl_priv(hw);
507 u8 u1btmp;
508
509 u1btmp = rtl_read_byte(rtlpriv, LDOV12D_CTRL);
510 u1btmp |= BIT(0);
511
512 rtl_write_byte(rtlpriv, LDOV12D_CTRL, u1btmp);
513 rtl_write_byte(rtlpriv, SPS1_CTRL, 0x0);
514 rtl_write_byte(rtlpriv, TXPAUSE, 0xFF);
515 rtl_write_word(rtlpriv, CMDR, 0x57FC);
516 udelay(100);
517
518 rtl_write_word(rtlpriv, CMDR, 0x77FC);
519 rtl_write_byte(rtlpriv, PHY_CCA, 0x0);
520 udelay(10);
521
522 rtl_write_word(rtlpriv, CMDR, 0x37FC);
523 udelay(10);
524
525 rtl_write_word(rtlpriv, CMDR, 0x77FC);
526 udelay(10);
527
528 rtl_write_word(rtlpriv, CMDR, 0x57FC);
529
530 /* we should chnge GPIO to input mode
531 * this will drop away current about 25mA*/
532 rtl8192se_gpiobit3_cfg_inputmode(hw);
533}
534
535bool rtl92s_phy_set_rf_power_state(struct ieee80211_hw *hw,
536 enum rf_pwrstate rfpwr_state)
537{
538 struct rtl_priv *rtlpriv = rtl_priv(hw);
539 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
540 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
541 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
542 bool bresult = true;
543 u8 i, queue_id;
544 struct rtl8192_tx_ring *ring = NULL;
545
546 if (rfpwr_state == ppsc->rfpwr_state)
547 return false;
548
549 ppsc->set_rfpowerstate_inprogress = true;
550
551 switch (rfpwr_state) {
552 case ERFON:{
553 if ((ppsc->rfpwr_state == ERFOFF) &&
554 RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
555
556 bool rtstatus;
557 u32 InitializeCount = 0;
558 do {
559 InitializeCount++;
560 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
561 ("IPS Set eRf nic enable\n"));
562 rtstatus = rtl_ps_enable_nic(hw);
563 } while ((rtstatus != true) &&
564 (InitializeCount < 10));
565
566 RT_CLEAR_PS_LEVEL(ppsc,
567 RT_RF_OFF_LEVL_HALT_NIC);
568 } else {
569 RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG,
570 ("awake, sleeped:%d ms "
571 "state_inap:%x\n",
572 jiffies_to_msecs(jiffies -
573 ppsc->last_sleep_jiffies),
574 rtlpriv->psc.state_inap));
575 ppsc->last_awake_jiffies = jiffies;
576 rtl_write_word(rtlpriv, CMDR, 0x37FC);
577 rtl_write_byte(rtlpriv, TXPAUSE, 0x00);
578 rtl_write_byte(rtlpriv, PHY_CCA, 0x3);
579 }
580
581 if (mac->link_state == MAC80211_LINKED)
582 rtlpriv->cfg->ops->led_control(hw,
583 LED_CTL_LINK);
584 else
585 rtlpriv->cfg->ops->led_control(hw,
586 LED_CTL_NO_LINK);
587 break;
588 }
589 case ERFOFF:{
590 if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
591 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
592 ("IPS Set eRf nic disable\n"));
593 rtl_ps_disable_nic(hw);
594 RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
595 } else {
596 if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS)
597 rtlpriv->cfg->ops->led_control(hw,
598 LED_CTL_NO_LINK);
599 else
600 rtlpriv->cfg->ops->led_control(hw,
601 LED_CTL_POWER_OFF);
602 }
603 break;
604 }
605 case ERFSLEEP:
606 if (ppsc->rfpwr_state == ERFOFF)
607 break;
608
609 for (queue_id = 0, i = 0;
610 queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
611 ring = &pcipriv->dev.tx_ring[queue_id];
612 if (skb_queue_len(&ring->queue) == 0 ||
613 queue_id == BEACON_QUEUE) {
614 queue_id++;
615 continue;
616 } else {
617 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
618 ("eRf Off/Sleep: "
619 "%d times TcbBusyQueue[%d] = "
620 "%d before doze!\n",
621 (i + 1), queue_id,
622 skb_queue_len(&ring->queue)));
623
624 udelay(10);
625 i++;
626 }
627
628 if (i >= MAX_DOZE_WAITING_TIMES_9x) {
629 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
630 ("\nERFOFF: %d times"
631 "TcbBusyQueue[%d] = %d !\n",
632 MAX_DOZE_WAITING_TIMES_9x,
633 queue_id,
634 skb_queue_len(&ring->queue)));
635 break;
636 }
637 }
638
639 RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG,
640 ("Set ERFSLEEP awaked:%d ms\n",
641 jiffies_to_msecs(jiffies -
642 ppsc->last_awake_jiffies)));
643
644 RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG,
645 ("sleep awaked:%d ms "
646 "state_inap:%x\n", jiffies_to_msecs(jiffies -
647 ppsc->last_awake_jiffies),
648 rtlpriv->psc.state_inap));
649 ppsc->last_sleep_jiffies = jiffies;
650 _rtl92se_phy_set_rf_sleep(hw);
651 break;
652 default:
653 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
654 ("switch case not process\n"));
655 bresult = false;
656 break;
657 }
658
659 if (bresult)
660 ppsc->rfpwr_state = rfpwr_state;
661
662 ppsc->set_rfpowerstate_inprogress = false;
663
664 return bresult;
665}
666
667static bool _rtl92s_phy_config_rfpa_bias_current(struct ieee80211_hw *hw,
668 enum radio_path rfpath)
669{
670 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
671 bool rtstatus = true;
672 u32 tmpval = 0;
673
674 /* If inferiority IC, we have to increase the PA bias current */
675 if (rtlhal->ic_class != IC_INFERIORITY_A) {
676 tmpval = rtl92s_phy_query_rf_reg(hw, rfpath, RF_IPA, 0xf);
677 rtl92s_phy_set_rf_reg(hw, rfpath, RF_IPA, 0xf, tmpval + 1);
678 }
679
680 return rtstatus;
681}
682
683static void _rtl92s_store_pwrindex_diffrate_offset(struct ieee80211_hw *hw,
684 u32 reg_addr, u32 bitmask, u32 data)
685{
686 struct rtl_priv *rtlpriv = rtl_priv(hw);
687 struct rtl_phy *rtlphy = &(rtlpriv->phy);
688
689 if (reg_addr == RTXAGC_RATE18_06)
690 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][0] =
691 data;
692 if (reg_addr == RTXAGC_RATE54_24)
693 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][1] =
694 data;
695 if (reg_addr == RTXAGC_CCK_MCS32)
696 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][6] =
697 data;
698 if (reg_addr == RTXAGC_MCS03_MCS00)
699 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][2] =
700 data;
701 if (reg_addr == RTXAGC_MCS07_MCS04)
702 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][3] =
703 data;
704 if (reg_addr == RTXAGC_MCS11_MCS08)
705 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][4] =
706 data;
707 if (reg_addr == RTXAGC_MCS15_MCS12) {
708 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][5] =
709 data;
710 rtlphy->pwrgroup_cnt++;
711 }
712}
713
714static void _rtl92s_phy_init_register_definition(struct ieee80211_hw *hw)
715{
716 struct rtl_priv *rtlpriv = rtl_priv(hw);
717 struct rtl_phy *rtlphy = &(rtlpriv->phy);
718
719 /*RF Interface Sowrtware Control */
720 rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW;
721 rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW;
722 rtlphy->phyreg_def[RF90_PATH_C].rfintfs = RFPGA0_XCD_RFINTERFACESW;
723 rtlphy->phyreg_def[RF90_PATH_D].rfintfs = RFPGA0_XCD_RFINTERFACESW;
724
725 /* RF Interface Readback Value */
726 rtlphy->phyreg_def[RF90_PATH_A].rfintfi = RFPGA0_XAB_RFINTERFACERB;
727 rtlphy->phyreg_def[RF90_PATH_B].rfintfi = RFPGA0_XAB_RFINTERFACERB;
728 rtlphy->phyreg_def[RF90_PATH_C].rfintfi = RFPGA0_XCD_RFINTERFACERB;
729 rtlphy->phyreg_def[RF90_PATH_D].rfintfi = RFPGA0_XCD_RFINTERFACERB;
730
731 /* RF Interface Output (and Enable) */
732 rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE;
733 rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE;
734 rtlphy->phyreg_def[RF90_PATH_C].rfintfo = RFPGA0_XC_RFINTERFACEOE;
735 rtlphy->phyreg_def[RF90_PATH_D].rfintfo = RFPGA0_XD_RFINTERFACEOE;
736
737 /* RF Interface (Output and) Enable */
738 rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE;
739 rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE;
740 rtlphy->phyreg_def[RF90_PATH_C].rfintfe = RFPGA0_XC_RFINTERFACEOE;
741 rtlphy->phyreg_def[RF90_PATH_D].rfintfe = RFPGA0_XD_RFINTERFACEOE;
742
743 /* Addr of LSSI. Wirte RF register by driver */
744 rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset =
745 RFPGA0_XA_LSSIPARAMETER;
746 rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset =
747 RFPGA0_XB_LSSIPARAMETER;
748 rtlphy->phyreg_def[RF90_PATH_C].rf3wire_offset =
749 RFPGA0_XC_LSSIPARAMETER;
750 rtlphy->phyreg_def[RF90_PATH_D].rf3wire_offset =
751 RFPGA0_XD_LSSIPARAMETER;
752
753 /* RF parameter */
754 rtlphy->phyreg_def[RF90_PATH_A].rflssi_select = RFPGA0_XAB_RFPARAMETER;
755 rtlphy->phyreg_def[RF90_PATH_B].rflssi_select = RFPGA0_XAB_RFPARAMETER;
756 rtlphy->phyreg_def[RF90_PATH_C].rflssi_select = RFPGA0_XCD_RFPARAMETER;
757 rtlphy->phyreg_def[RF90_PATH_D].rflssi_select = RFPGA0_XCD_RFPARAMETER;
758
759 /* Tx AGC Gain Stage (same for all path. Should we remove this?) */
760 rtlphy->phyreg_def[RF90_PATH_A].rftxgain_stage = RFPGA0_TXGAINSTAGE;
761 rtlphy->phyreg_def[RF90_PATH_B].rftxgain_stage = RFPGA0_TXGAINSTAGE;
762 rtlphy->phyreg_def[RF90_PATH_C].rftxgain_stage = RFPGA0_TXGAINSTAGE;
763 rtlphy->phyreg_def[RF90_PATH_D].rftxgain_stage = RFPGA0_TXGAINSTAGE;
764
765 /* Tranceiver A~D HSSI Parameter-1 */
766 rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para1 = RFPGA0_XA_HSSIPARAMETER1;
767 rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para1 = RFPGA0_XB_HSSIPARAMETER1;
768 rtlphy->phyreg_def[RF90_PATH_C].rfhssi_para1 = RFPGA0_XC_HSSIPARAMETER1;
769 rtlphy->phyreg_def[RF90_PATH_D].rfhssi_para1 = RFPGA0_XD_HSSIPARAMETER1;
770
771 /* Tranceiver A~D HSSI Parameter-2 */
772 rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RFPGA0_XA_HSSIPARAMETER2;
773 rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RFPGA0_XB_HSSIPARAMETER2;
774 rtlphy->phyreg_def[RF90_PATH_C].rfhssi_para2 = RFPGA0_XC_HSSIPARAMETER2;
775 rtlphy->phyreg_def[RF90_PATH_D].rfhssi_para2 = RFPGA0_XD_HSSIPARAMETER2;
776
777 /* RF switch Control */
778 rtlphy->phyreg_def[RF90_PATH_A].rfswitch_control =
779 RFPGA0_XAB_SWITCHCONTROL;
780 rtlphy->phyreg_def[RF90_PATH_B].rfswitch_control =
781 RFPGA0_XAB_SWITCHCONTROL;
782 rtlphy->phyreg_def[RF90_PATH_C].rfswitch_control =
783 RFPGA0_XCD_SWITCHCONTROL;
784 rtlphy->phyreg_def[RF90_PATH_D].rfswitch_control =
785 RFPGA0_XCD_SWITCHCONTROL;
786
787 /* AGC control 1 */
788 rtlphy->phyreg_def[RF90_PATH_A].rfagc_control1 = ROFDM0_XAAGCCORE1;
789 rtlphy->phyreg_def[RF90_PATH_B].rfagc_control1 = ROFDM0_XBAGCCORE1;
790 rtlphy->phyreg_def[RF90_PATH_C].rfagc_control1 = ROFDM0_XCAGCCORE1;
791 rtlphy->phyreg_def[RF90_PATH_D].rfagc_control1 = ROFDM0_XDAGCCORE1;
792
793 /* AGC control 2 */
794 rtlphy->phyreg_def[RF90_PATH_A].rfagc_control2 = ROFDM0_XAAGCCORE2;
795 rtlphy->phyreg_def[RF90_PATH_B].rfagc_control2 = ROFDM0_XBAGCCORE2;
796 rtlphy->phyreg_def[RF90_PATH_C].rfagc_control2 = ROFDM0_XCAGCCORE2;
797 rtlphy->phyreg_def[RF90_PATH_D].rfagc_control2 = ROFDM0_XDAGCCORE2;
798
799 /* RX AFE control 1 */
800 rtlphy->phyreg_def[RF90_PATH_A].rfrxiq_imbalance =
801 ROFDM0_XARXIQIMBALANCE;
802 rtlphy->phyreg_def[RF90_PATH_B].rfrxiq_imbalance =
803 ROFDM0_XBRXIQIMBALANCE;
804 rtlphy->phyreg_def[RF90_PATH_C].rfrxiq_imbalance =
805 ROFDM0_XCRXIQIMBALANCE;
806 rtlphy->phyreg_def[RF90_PATH_D].rfrxiq_imbalance =
807 ROFDM0_XDRXIQIMBALANCE;
808
809 /* RX AFE control 1 */
810 rtlphy->phyreg_def[RF90_PATH_A].rfrx_afe = ROFDM0_XARXAFE;
811 rtlphy->phyreg_def[RF90_PATH_B].rfrx_afe = ROFDM0_XBRXAFE;
812 rtlphy->phyreg_def[RF90_PATH_C].rfrx_afe = ROFDM0_XCRXAFE;
813 rtlphy->phyreg_def[RF90_PATH_D].rfrx_afe = ROFDM0_XDRXAFE;
814
815 /* Tx AFE control 1 */
816 rtlphy->phyreg_def[RF90_PATH_A].rftxiq_imbalance =
817 ROFDM0_XATXIQIMBALANCE;
818 rtlphy->phyreg_def[RF90_PATH_B].rftxiq_imbalance =
819 ROFDM0_XBTXIQIMBALANCE;
820 rtlphy->phyreg_def[RF90_PATH_C].rftxiq_imbalance =
821 ROFDM0_XCTXIQIMBALANCE;
822 rtlphy->phyreg_def[RF90_PATH_D].rftxiq_imbalance =
823 ROFDM0_XDTXIQIMBALANCE;
824
825 /* Tx AFE control 2 */
826 rtlphy->phyreg_def[RF90_PATH_A].rftx_afe = ROFDM0_XATXAFE;
827 rtlphy->phyreg_def[RF90_PATH_B].rftx_afe = ROFDM0_XBTXAFE;
828 rtlphy->phyreg_def[RF90_PATH_C].rftx_afe = ROFDM0_XCTXAFE;
829 rtlphy->phyreg_def[RF90_PATH_D].rftx_afe = ROFDM0_XDTXAFE;
830
831 /* Tranceiver LSSI Readback */
832 rtlphy->phyreg_def[RF90_PATH_A].rflssi_readback =
833 RFPGA0_XA_LSSIREADBACK;
834 rtlphy->phyreg_def[RF90_PATH_B].rflssi_readback =
835 RFPGA0_XB_LSSIREADBACK;
836 rtlphy->phyreg_def[RF90_PATH_C].rflssi_readback =
837 RFPGA0_XC_LSSIREADBACK;
838 rtlphy->phyreg_def[RF90_PATH_D].rflssi_readback =
839 RFPGA0_XD_LSSIREADBACK;
840
841 /* Tranceiver LSSI Readback PI mode */
842 rtlphy->phyreg_def[RF90_PATH_A].rflssi_readbackpi =
843 TRANSCEIVERA_HSPI_READBACK;
844 rtlphy->phyreg_def[RF90_PATH_B].rflssi_readbackpi =
845 TRANSCEIVERB_HSPI_READBACK;
846}
847
848
849static bool _rtl92s_phy_config_bb(struct ieee80211_hw *hw, u8 configtype)
850{
851 int i;
852 u32 *phy_reg_table;
853 u32 *agc_table;
854 u16 phy_reg_len, agc_len;
855
856 agc_len = AGCTAB_ARRAYLENGTH;
857 agc_table = rtl8192seagctab_array;
858 /* Default RF_type: 2T2R */
859 phy_reg_len = PHY_REG_2T2RARRAYLENGTH;
860 phy_reg_table = rtl8192sephy_reg_2t2rarray;
861
862 if (configtype == BASEBAND_CONFIG_PHY_REG) {
863 for (i = 0; i < phy_reg_len; i = i + 2) {
864 if (phy_reg_table[i] == 0xfe)
865 mdelay(50);
866 else if (phy_reg_table[i] == 0xfd)
867 mdelay(5);
868 else if (phy_reg_table[i] == 0xfc)
869 mdelay(1);
870 else if (phy_reg_table[i] == 0xfb)
871 udelay(50);
872 else if (phy_reg_table[i] == 0xfa)
873 udelay(5);
874 else if (phy_reg_table[i] == 0xf9)
875 udelay(1);
876
877 /* Add delay for ECS T20 & LG malow platform, */
878 udelay(1);
879
880 rtl92s_phy_set_bb_reg(hw, phy_reg_table[i], MASKDWORD,
881 phy_reg_table[i + 1]);
882 }
883 } else if (configtype == BASEBAND_CONFIG_AGC_TAB) {
884 for (i = 0; i < agc_len; i = i + 2) {
885 rtl92s_phy_set_bb_reg(hw, agc_table[i], MASKDWORD,
886 agc_table[i + 1]);
887
888 /* Add delay for ECS T20 & LG malow platform */
889 udelay(1);
890 }
891 }
892
893 return true;
894}
895
896static bool _rtl92s_phy_set_bb_to_diff_rf(struct ieee80211_hw *hw,
897 u8 configtype)
898{
899 struct rtl_priv *rtlpriv = rtl_priv(hw);
900 struct rtl_phy *rtlphy = &(rtlpriv->phy);
901 u32 *phy_regarray2xtxr_table;
902 u16 phy_regarray2xtxr_len;
903 int i;
904
905 if (rtlphy->rf_type == RF_1T1R) {
906 phy_regarray2xtxr_table = rtl8192sephy_changeto_1t1rarray;
907 phy_regarray2xtxr_len = PHY_CHANGETO_1T1RARRAYLENGTH;
908 } else if (rtlphy->rf_type == RF_1T2R) {
909 phy_regarray2xtxr_table = rtl8192sephy_changeto_1t2rarray;
910 phy_regarray2xtxr_len = PHY_CHANGETO_1T2RARRAYLENGTH;
911 } else {
912 return false;
913 }
914
915 if (configtype == BASEBAND_CONFIG_PHY_REG) {
916 for (i = 0; i < phy_regarray2xtxr_len; i = i + 3) {
917 if (phy_regarray2xtxr_table[i] == 0xfe)
918 mdelay(50);
919 else if (phy_regarray2xtxr_table[i] == 0xfd)
920 mdelay(5);
921 else if (phy_regarray2xtxr_table[i] == 0xfc)
922 mdelay(1);
923 else if (phy_regarray2xtxr_table[i] == 0xfb)
924 udelay(50);
925 else if (phy_regarray2xtxr_table[i] == 0xfa)
926 udelay(5);
927 else if (phy_regarray2xtxr_table[i] == 0xf9)
928 udelay(1);
929
930 rtl92s_phy_set_bb_reg(hw, phy_regarray2xtxr_table[i],
931 phy_regarray2xtxr_table[i + 1],
932 phy_regarray2xtxr_table[i + 2]);
933 }
934 }
935
936 return true;
937}
938
939static bool _rtl92s_phy_config_bb_with_pg(struct ieee80211_hw *hw,
940 u8 configtype)
941{
942 int i;
943 u32 *phy_table_pg;
944 u16 phy_pg_len;
945
946 phy_pg_len = PHY_REG_ARRAY_PGLENGTH;
947 phy_table_pg = rtl8192sephy_reg_array_pg;
948
949 if (configtype == BASEBAND_CONFIG_PHY_REG) {
950 for (i = 0; i < phy_pg_len; i = i + 3) {
951 if (phy_table_pg[i] == 0xfe)
952 mdelay(50);
953 else if (phy_table_pg[i] == 0xfd)
954 mdelay(5);
955 else if (phy_table_pg[i] == 0xfc)
956 mdelay(1);
957 else if (phy_table_pg[i] == 0xfb)
958 udelay(50);
959 else if (phy_table_pg[i] == 0xfa)
960 udelay(5);
961 else if (phy_table_pg[i] == 0xf9)
962 udelay(1);
963
964 _rtl92s_store_pwrindex_diffrate_offset(hw,
965 phy_table_pg[i],
966 phy_table_pg[i + 1],
967 phy_table_pg[i + 2]);
968 rtl92s_phy_set_bb_reg(hw, phy_table_pg[i],
969 phy_table_pg[i + 1],
970 phy_table_pg[i + 2]);
971 }
972 }
973
974 return true;
975}
976
977static bool _rtl92s_phy_bb_config_parafile(struct ieee80211_hw *hw)
978{
979 struct rtl_priv *rtlpriv = rtl_priv(hw);
980 struct rtl_phy *rtlphy = &(rtlpriv->phy);
981 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
982 bool rtstatus = true;
983
984 /* 1. Read PHY_REG.TXT BB INIT!! */
985 /* We will separate as 1T1R/1T2R/1T2R_GREEN/2T2R */
986 if (rtlphy->rf_type == RF_1T2R || rtlphy->rf_type == RF_2T2R ||
987 rtlphy->rf_type == RF_1T1R || rtlphy->rf_type == RF_2T2R_GREEN) {
988 rtstatus = _rtl92s_phy_config_bb(hw, BASEBAND_CONFIG_PHY_REG);
989
990 if (rtlphy->rf_type != RF_2T2R &&
991 rtlphy->rf_type != RF_2T2R_GREEN)
992 /* so we should reconfig BB reg with the right
993 * PHY parameters. */
994 rtstatus = _rtl92s_phy_set_bb_to_diff_rf(hw,
995 BASEBAND_CONFIG_PHY_REG);
996 } else {
997 rtstatus = false;
998 }
999
1000 if (rtstatus != true) {
1001 RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
1002 ("Write BB Reg Fail!!"));
1003 goto phy_BB8190_Config_ParaFile_Fail;
1004 }
1005
1006 /* 2. If EEPROM or EFUSE autoload OK, We must config by
1007 * PHY_REG_PG.txt */
1008 if (rtlefuse->autoload_failflag == false) {
1009 rtlphy->pwrgroup_cnt = 0;
1010
1011 rtstatus = _rtl92s_phy_config_bb_with_pg(hw,
1012 BASEBAND_CONFIG_PHY_REG);
1013 }
1014 if (rtstatus != true) {
1015 RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
1016 ("_rtl92s_phy_bb_config_parafile(): "
1017 "BB_PG Reg Fail!!"));
1018 goto phy_BB8190_Config_ParaFile_Fail;
1019 }
1020
1021 /* 3. BB AGC table Initialization */
1022 rtstatus = _rtl92s_phy_config_bb(hw, BASEBAND_CONFIG_AGC_TAB);
1023
1024 if (rtstatus != true) {
1025 printk(KERN_ERR "_rtl92s_phy_bb_config_parafile(): "
1026 "AGC Table Fail\n");
1027 goto phy_BB8190_Config_ParaFile_Fail;
1028 }
1029
1030 /* Check if the CCK HighPower is turned ON. */
1031 /* This is used to calculate PWDB. */
1032 rtlphy->cck_high_power = (bool)(rtl92s_phy_query_bb_reg(hw,
1033 RFPGA0_XA_HSSIPARAMETER2, 0x200));
1034
1035phy_BB8190_Config_ParaFile_Fail:
1036 return rtstatus;
1037}
1038
1039u8 rtl92s_phy_config_rf(struct ieee80211_hw *hw, enum radio_path rfpath)
1040{
1041 struct rtl_priv *rtlpriv = rtl_priv(hw);
1042 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1043 int i;
1044 bool rtstatus = true;
1045 u32 *radio_a_table;
1046 u32 *radio_b_table;
1047 u16 radio_a_tblen, radio_b_tblen;
1048
1049 radio_a_tblen = RADIOA_1T_ARRAYLENGTH;
1050 radio_a_table = rtl8192seradioa_1t_array;
1051
1052 /* Using Green mode array table for RF_2T2R_GREEN */
1053 if (rtlphy->rf_type == RF_2T2R_GREEN) {
1054 radio_b_table = rtl8192seradiob_gm_array;
1055 radio_b_tblen = RADIOB_GM_ARRAYLENGTH;
1056 } else {
1057 radio_b_table = rtl8192seradiob_array;
1058 radio_b_tblen = RADIOB_ARRAYLENGTH;
1059 }
1060
1061 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Radio No %x\n", rfpath));
1062 rtstatus = true;
1063
1064 switch (rfpath) {
1065 case RF90_PATH_A:
1066 for (i = 0; i < radio_a_tblen; i = i + 2) {
1067 if (radio_a_table[i] == 0xfe)
1068 /* Delay specific ms. Only RF configuration
1069 * requires delay. */
1070 mdelay(50);
1071 else if (radio_a_table[i] == 0xfd)
1072 mdelay(5);
1073 else if (radio_a_table[i] == 0xfc)
1074 mdelay(1);
1075 else if (radio_a_table[i] == 0xfb)
1076 udelay(50);
1077 else if (radio_a_table[i] == 0xfa)
1078 udelay(5);
1079 else if (radio_a_table[i] == 0xf9)
1080 udelay(1);
1081 else
1082 rtl92s_phy_set_rf_reg(hw, rfpath,
1083 radio_a_table[i],
1084 MASK20BITS,
1085 radio_a_table[i + 1]);
1086
1087 /* Add delay for ECS T20 & LG malow platform */
1088 udelay(1);
1089 }
1090
1091 /* PA Bias current for inferiority IC */
1092 _rtl92s_phy_config_rfpa_bias_current(hw, rfpath);
1093 break;
1094 case RF90_PATH_B:
1095 for (i = 0; i < radio_b_tblen; i = i + 2) {
1096 if (radio_b_table[i] == 0xfe)
1097 /* Delay specific ms. Only RF configuration
1098 * requires delay.*/
1099 mdelay(50);
1100 else if (radio_b_table[i] == 0xfd)
1101 mdelay(5);
1102 else if (radio_b_table[i] == 0xfc)
1103 mdelay(1);
1104 else if (radio_b_table[i] == 0xfb)
1105 udelay(50);
1106 else if (radio_b_table[i] == 0xfa)
1107 udelay(5);
1108 else if (radio_b_table[i] == 0xf9)
1109 udelay(1);
1110 else
1111 rtl92s_phy_set_rf_reg(hw, rfpath,
1112 radio_b_table[i],
1113 MASK20BITS,
1114 radio_b_table[i + 1]);
1115
1116 /* Add delay for ECS T20 & LG malow platform */
1117 udelay(1);
1118 }
1119 break;
1120 case RF90_PATH_C:
1121 ;
1122 break;
1123 case RF90_PATH_D:
1124 ;
1125 break;
1126 default:
1127 break;
1128 }
1129
1130 return rtstatus;
1131}
1132
1133
1134bool rtl92s_phy_mac_config(struct ieee80211_hw *hw)
1135{
1136 struct rtl_priv *rtlpriv = rtl_priv(hw);
1137 u32 i;
1138 u32 arraylength;
1139 u32 *ptraArray;
1140
1141 arraylength = MAC_2T_ARRAYLENGTH;
1142 ptraArray = rtl8192semac_2t_array;
1143
1144 for (i = 0; i < arraylength; i = i + 2)
1145 rtl_write_byte(rtlpriv, ptraArray[i], (u8)ptraArray[i + 1]);
1146
1147 return true;
1148}
1149
1150
1151bool rtl92s_phy_bb_config(struct ieee80211_hw *hw)
1152{
1153 struct rtl_priv *rtlpriv = rtl_priv(hw);
1154 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1155 bool rtstatus = true;
1156 u8 pathmap, index, rf_num = 0;
1157 u8 path1, path2;
1158
1159 _rtl92s_phy_init_register_definition(hw);
1160
1161 /* Config BB and AGC */
1162 rtstatus = _rtl92s_phy_bb_config_parafile(hw);
1163
1164
1165 /* Check BB/RF confiuration setting. */
1166 /* We only need to configure RF which is turned on. */
1167 path1 = (u8)(rtl92s_phy_query_bb_reg(hw, RFPGA0_TXINFO, 0xf));
1168 mdelay(10);
1169 path2 = (u8)(rtl92s_phy_query_bb_reg(hw, ROFDM0_TRXPATHENABLE, 0xf));
1170 pathmap = path1 | path2;
1171
1172 rtlphy->rf_pathmap = pathmap;
1173 for (index = 0; index < 4; index++) {
1174 if ((pathmap >> index) & 0x1)
1175 rf_num++;
1176 }
1177
1178 if ((rtlphy->rf_type == RF_1T1R && rf_num != 1) ||
1179 (rtlphy->rf_type == RF_1T2R && rf_num != 2) ||
1180 (rtlphy->rf_type == RF_2T2R && rf_num != 2) ||
1181 (rtlphy->rf_type == RF_2T2R_GREEN && rf_num != 2)) {
1182 RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
1183 ("RF_Type(%x) does not match "
1184 "RF_Num(%x)!!\n", rtlphy->rf_type, rf_num));
1185 RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
1186 ("path1 0x%x, path2 0x%x, pathmap "
1187 "0x%x\n", path1, path2, pathmap));
1188 }
1189
1190 return rtstatus;
1191}
1192
1193bool rtl92s_phy_rf_config(struct ieee80211_hw *hw)
1194{
1195 struct rtl_priv *rtlpriv = rtl_priv(hw);
1196 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1197
1198 /* Initialize general global value */
1199 if (rtlphy->rf_type == RF_1T1R)
1200 rtlphy->num_total_rfpath = 1;
1201 else
1202 rtlphy->num_total_rfpath = 2;
1203
1204 /* Config BB and RF */
1205 return rtl92s_phy_rf6052_config(hw);
1206}
1207
1208void rtl92s_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)
1209{
1210 struct rtl_priv *rtlpriv = rtl_priv(hw);
1211 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1212
1213 /* read rx initial gain */
1214 rtlphy->default_initialgain[0] = rtl_get_bbreg(hw,
1215 ROFDM0_XAAGCCORE1, MASKBYTE0);
1216 rtlphy->default_initialgain[1] = rtl_get_bbreg(hw,
1217 ROFDM0_XBAGCCORE1, MASKBYTE0);
1218 rtlphy->default_initialgain[2] = rtl_get_bbreg(hw,
1219 ROFDM0_XCAGCCORE1, MASKBYTE0);
1220 rtlphy->default_initialgain[3] = rtl_get_bbreg(hw,
1221 ROFDM0_XDAGCCORE1, MASKBYTE0);
1222 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Default initial gain "
1223 "(c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x)\n",
1224 rtlphy->default_initialgain[0],
1225 rtlphy->default_initialgain[1],
1226 rtlphy->default_initialgain[2],
1227 rtlphy->default_initialgain[3]));
1228
1229 /* read framesync */
1230 rtlphy->framesync = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR3, MASKBYTE0);
1231 rtlphy->framesync_c34 = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR2,
1232 MASKDWORD);
1233 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1234 ("Default framesync (0x%x) = 0x%x\n",
1235 ROFDM0_RXDETECTOR3, rtlphy->framesync));
1236
1237}
1238
1239static void _rtl92s_phy_get_txpower_index(struct ieee80211_hw *hw, u8 channel,
1240 u8 *cckpowerlevel, u8 *ofdmpowerLevel)
1241{
1242 struct rtl_priv *rtlpriv = rtl_priv(hw);
1243 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1244 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1245 u8 index = (channel - 1);
1246
1247 /* 1. CCK */
1248 /* RF-A */
1249 cckpowerlevel[0] = rtlefuse->txpwrlevel_cck[0][index];
1250 /* RF-B */
1251 cckpowerlevel[1] = rtlefuse->txpwrlevel_cck[1][index];
1252
1253 /* 2. OFDM for 1T or 2T */
1254 if (rtlphy->rf_type == RF_1T2R || rtlphy->rf_type == RF_1T1R) {
1255 /* Read HT 40 OFDM TX power */
1256 ofdmpowerLevel[0] = rtlefuse->txpwrlevel_ht40_1s[0][index];
1257 ofdmpowerLevel[1] = rtlefuse->txpwrlevel_ht40_1s[1][index];
1258 } else if (rtlphy->rf_type == RF_2T2R) {
1259 /* Read HT 40 OFDM TX power */
1260 ofdmpowerLevel[0] = rtlefuse->txpwrlevel_ht40_2s[0][index];
1261 ofdmpowerLevel[1] = rtlefuse->txpwrlevel_ht40_2s[1][index];
1262 }
1263}
1264
1265static void _rtl92s_phy_ccxpower_indexcheck(struct ieee80211_hw *hw,
1266 u8 channel, u8 *cckpowerlevel, u8 *ofdmpowerlevel)
1267{
1268 struct rtl_priv *rtlpriv = rtl_priv(hw);
1269 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1270
1271 rtlphy->cur_cck_txpwridx = cckpowerlevel[0];
1272 rtlphy->cur_ofdm24g_txpwridx = ofdmpowerlevel[0];
1273}
1274
1275void rtl92s_phy_set_txpower(struct ieee80211_hw *hw, u8 channel)
1276{
1277 struct rtl_priv *rtlpriv = rtl_priv(hw);
1278 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1279 /* [0]:RF-A, [1]:RF-B */
1280 u8 cckpowerlevel[2], ofdmpowerLevel[2];
1281
1282 if (rtlefuse->txpwr_fromeprom == false)
1283 return;
1284
1285 /* Mainly we use RF-A Tx Power to write the Tx Power registers,
1286 * but the RF-B Tx Power must be calculated by the antenna diff.
1287 * So we have to rewrite Antenna gain offset register here.
1288 * Please refer to BB register 0x80c
1289 * 1. For CCK.
1290 * 2. For OFDM 1T or 2T */
1291 _rtl92s_phy_get_txpower_index(hw, channel, &cckpowerlevel[0],
1292 &ofdmpowerLevel[0]);
1293
1294 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
1295 ("Channel-%d, cckPowerLevel (A / B) = "
1296 "0x%x / 0x%x, ofdmPowerLevel (A / B) = 0x%x / 0x%x\n",
1297 channel, cckpowerlevel[0], cckpowerlevel[1],
1298 ofdmpowerLevel[0], ofdmpowerLevel[1]));
1299
1300 _rtl92s_phy_ccxpower_indexcheck(hw, channel, &cckpowerlevel[0],
1301 &ofdmpowerLevel[0]);
1302
1303 rtl92s_phy_rf6052_set_ccktxpower(hw, cckpowerlevel[0]);
1304 rtl92s_phy_rf6052_set_ofdmtxpower(hw, &ofdmpowerLevel[0], channel);
1305
1306}
1307
1308void rtl92s_phy_chk_fwcmd_iodone(struct ieee80211_hw *hw)
1309{
1310 struct rtl_priv *rtlpriv = rtl_priv(hw);
1311 u16 pollingcnt = 10000;
1312 u32 tmpvalue;
1313
1314 /* Make sure that CMD IO has be accepted by FW. */
1315 do {
1316 udelay(10);
1317
1318 tmpvalue = rtl_read_dword(rtlpriv, WFM5);
1319 if (tmpvalue == 0)
1320 break;
1321 } while (--pollingcnt);
1322
1323 if (pollingcnt == 0)
1324 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Set FW Cmd fail!!\n"));
1325}
1326
1327
1328static void _rtl92s_phy_set_fwcmd_io(struct ieee80211_hw *hw)
1329{
1330 struct rtl_priv *rtlpriv = rtl_priv(hw);
1331 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1332 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1333 u32 input, current_aid = 0;
1334
1335 if (is_hal_stop(rtlhal))
1336 return;
1337
1338 /* We re-map RA related CMD IO to combinational ones */
1339 /* if FW version is v.52 or later. */
1340 switch (rtlhal->current_fwcmd_io) {
1341 case FW_CMD_RA_REFRESH_N:
1342 rtlhal->current_fwcmd_io = FW_CMD_RA_REFRESH_N_COMB;
1343 break;
1344 case FW_CMD_RA_REFRESH_BG:
1345 rtlhal->current_fwcmd_io = FW_CMD_RA_REFRESH_BG_COMB;
1346 break;
1347 default:
1348 break;
1349 }
1350
1351 switch (rtlhal->current_fwcmd_io) {
1352 case FW_CMD_RA_RESET:
1353 RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
1354 ("FW_CMD_RA_RESET\n"));
1355 rtl_write_dword(rtlpriv, WFM5, FW_RA_RESET);
1356 rtl92s_phy_chk_fwcmd_iodone(hw);
1357 break;
1358 case FW_CMD_RA_ACTIVE:
1359 RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
1360 ("FW_CMD_RA_ACTIVE\n"));
1361 rtl_write_dword(rtlpriv, WFM5, FW_RA_ACTIVE);
1362 rtl92s_phy_chk_fwcmd_iodone(hw);
1363 break;
1364 case FW_CMD_RA_REFRESH_N:
1365 RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
1366 ("FW_CMD_RA_REFRESH_N\n"));
1367 input = FW_RA_REFRESH;
1368 rtl_write_dword(rtlpriv, WFM5, input);
1369 rtl92s_phy_chk_fwcmd_iodone(hw);
1370 rtl_write_dword(rtlpriv, WFM5, FW_RA_ENABLE_RSSI_MASK);
1371 rtl92s_phy_chk_fwcmd_iodone(hw);
1372 break;
1373 case FW_CMD_RA_REFRESH_BG:
1374 RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
1375 ("FW_CMD_RA_REFRESH_BG\n"));
1376 rtl_write_dword(rtlpriv, WFM5, FW_RA_REFRESH);
1377 rtl92s_phy_chk_fwcmd_iodone(hw);
1378 rtl_write_dword(rtlpriv, WFM5, FW_RA_DISABLE_RSSI_MASK);
1379 rtl92s_phy_chk_fwcmd_iodone(hw);
1380 break;
1381 case FW_CMD_RA_REFRESH_N_COMB:
1382 RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
1383 ("FW_CMD_RA_REFRESH_N_COMB\n"));
1384 input = FW_RA_IOT_N_COMB;
1385 rtl_write_dword(rtlpriv, WFM5, input);
1386 rtl92s_phy_chk_fwcmd_iodone(hw);
1387 break;
1388 case FW_CMD_RA_REFRESH_BG_COMB:
1389 RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
1390 ("FW_CMD_RA_REFRESH_BG_COMB\n"));
1391 input = FW_RA_IOT_BG_COMB;
1392 rtl_write_dword(rtlpriv, WFM5, input);
1393 rtl92s_phy_chk_fwcmd_iodone(hw);
1394 break;
1395 case FW_CMD_IQK_ENABLE:
1396 RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
1397 ("FW_CMD_IQK_ENABLE\n"));
1398 rtl_write_dword(rtlpriv, WFM5, FW_IQK_ENABLE);
1399 rtl92s_phy_chk_fwcmd_iodone(hw);
1400 break;
1401 case FW_CMD_PAUSE_DM_BY_SCAN:
1402 /* Lower initial gain */
1403 rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0, 0x17);
1404 rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0, 0x17);
1405 /* CCA threshold */
1406 rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0x40);
1407 break;
1408 case FW_CMD_RESUME_DM_BY_SCAN:
1409 /* CCA threshold */
1410 rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd);
1411 rtl92s_phy_set_txpower(hw, rtlphy->current_channel);
1412 break;
1413 case FW_CMD_HIGH_PWR_DISABLE:
1414 if (rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE)
1415 break;
1416
1417 /* Lower initial gain */
1418 rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0, 0x17);
1419 rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0, 0x17);
1420 /* CCA threshold */
1421 rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0x40);
1422 break;
1423 case FW_CMD_HIGH_PWR_ENABLE:
1424 if ((rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) ||
1425 (rtlpriv->dm.dynamic_txpower_enable == true))
1426 break;
1427
1428 /* CCA threshold */
1429 rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd);
1430 break;
1431 case FW_CMD_LPS_ENTER:
1432 RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
1433 ("FW_CMD_LPS_ENTER\n"));
1434 current_aid = rtlpriv->mac80211.assoc_id;
1435 rtl_write_dword(rtlpriv, WFM5, (FW_LPS_ENTER |
1436 ((current_aid | 0xc000) << 8)));
1437 rtl92s_phy_chk_fwcmd_iodone(hw);
1438 /* FW set TXOP disable here, so disable EDCA
1439 * turbo mode until driver leave LPS */
1440 break;
1441 case FW_CMD_LPS_LEAVE:
1442 RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
1443 ("FW_CMD_LPS_LEAVE\n"));
1444 rtl_write_dword(rtlpriv, WFM5, FW_LPS_LEAVE);
1445 rtl92s_phy_chk_fwcmd_iodone(hw);
1446 break;
1447 case FW_CMD_ADD_A2_ENTRY:
1448 RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
1449 ("FW_CMD_ADD_A2_ENTRY\n"));
1450 rtl_write_dword(rtlpriv, WFM5, FW_ADD_A2_ENTRY);
1451 rtl92s_phy_chk_fwcmd_iodone(hw);
1452 break;
1453 case FW_CMD_CTRL_DM_BY_DRIVER:
1454 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
1455 ("FW_CMD_CTRL_DM_BY_DRIVER\n"));
1456 rtl_write_dword(rtlpriv, WFM5, FW_CTRL_DM_BY_DRIVER);
1457 rtl92s_phy_chk_fwcmd_iodone(hw);
1458 break;
1459
1460 default:
1461 break;
1462 }
1463
1464 rtl92s_phy_chk_fwcmd_iodone(hw);
1465
1466 /* Clear FW CMD operation flag. */
1467 rtlhal->set_fwcmd_inprogress = false;
1468}
1469
1470bool rtl92s_phy_set_fw_cmd(struct ieee80211_hw *hw, enum fwcmd_iotype fw_cmdio)
1471{
1472 struct rtl_priv *rtlpriv = rtl_priv(hw);
1473 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1474 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1475 u32 fw_param = FW_CMD_IO_PARA_QUERY(rtlpriv);
1476 u16 fw_cmdmap = FW_CMD_IO_QUERY(rtlpriv);
1477 bool bPostProcessing = false;
1478
1479 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
1480 ("Set FW Cmd(%#x), set_fwcmd_inprogress(%d)\n",
1481 fw_cmdio, rtlhal->set_fwcmd_inprogress));
1482
1483 do {
1484 /* We re-map to combined FW CMD ones if firmware version */
1485 /* is v.53 or later. */
1486 switch (fw_cmdio) {
1487 case FW_CMD_RA_REFRESH_N:
1488 fw_cmdio = FW_CMD_RA_REFRESH_N_COMB;
1489 break;
1490 case FW_CMD_RA_REFRESH_BG:
1491 fw_cmdio = FW_CMD_RA_REFRESH_BG_COMB;
1492 break;
1493 default:
1494 break;
1495 }
1496
1497 /* If firmware version is v.62 or later,
1498 * use FW_CMD_IO_SET for FW_CMD_CTRL_DM_BY_DRIVER */
1499 if (hal_get_firmwareversion(rtlpriv) >= 0x3E) {
1500 if (fw_cmdio == FW_CMD_CTRL_DM_BY_DRIVER)
1501 fw_cmdio = FW_CMD_CTRL_DM_BY_DRIVER_NEW;
1502 }
1503
1504
1505 /* We shall revise all FW Cmd IO into Reg0x364
1506 * DM map table in the future. */
1507 switch (fw_cmdio) {
1508 case FW_CMD_RA_INIT:
1509 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("RA init!!\n"));
1510 fw_cmdmap |= FW_RA_INIT_CTL;
1511 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1512 /* Clear control flag to sync with FW. */
1513 FW_CMD_IO_CLR(rtlpriv, FW_RA_INIT_CTL);
1514 break;
1515 case FW_CMD_DIG_DISABLE:
1516 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
1517 ("Set DIG disable!!\n"));
1518 fw_cmdmap &= ~FW_DIG_ENABLE_CTL;
1519 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1520 break;
1521 case FW_CMD_DIG_ENABLE:
1522 case FW_CMD_DIG_RESUME:
1523 if (!(rtlpriv->dm.dm_flag & HAL_DM_DIG_DISABLE)) {
1524 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
1525 ("Set DIG enable or resume!!\n"));
1526 fw_cmdmap |= (FW_DIG_ENABLE_CTL | FW_SS_CTL);
1527 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1528 }
1529 break;
1530 case FW_CMD_DIG_HALT:
1531 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
1532 ("Set DIG halt!!\n"));
1533 fw_cmdmap &= ~(FW_DIG_ENABLE_CTL | FW_SS_CTL);
1534 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1535 break;
1536 case FW_CMD_TXPWR_TRACK_THERMAL: {
1537 u8 thermalval = 0;
1538 fw_cmdmap |= FW_PWR_TRK_CTL;
1539
1540 /* Clear FW parameter in terms of thermal parts. */
1541 fw_param &= FW_PWR_TRK_PARAM_CLR;
1542
1543 thermalval = rtlpriv->dm.thermalvalue;
1544 fw_param |= ((thermalval << 24) |
1545 (rtlefuse->thermalmeter[0] << 16));
1546
1547 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
1548 ("Set TxPwr tracking!! "
1549 "FwCmdMap(%#x), FwParam(%#x)\n",
1550 fw_cmdmap, fw_param));
1551
1552 FW_CMD_PARA_SET(rtlpriv, fw_param);
1553 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1554
1555 /* Clear control flag to sync with FW. */
1556 FW_CMD_IO_CLR(rtlpriv, FW_PWR_TRK_CTL);
1557 }
1558 break;
1559 /* The following FW CMDs are only compatible to
1560 * v.53 or later. */
1561 case FW_CMD_RA_REFRESH_N_COMB:
1562 fw_cmdmap |= FW_RA_N_CTL;
1563
1564 /* Clear RA BG mode control. */
1565 fw_cmdmap &= ~(FW_RA_BG_CTL | FW_RA_INIT_CTL);
1566
1567 /* Clear FW parameter in terms of RA parts. */
1568 fw_param &= FW_RA_PARAM_CLR;
1569
1570 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
1571 ("[FW CMD] [New Version] "
1572 "Set RA/IOT Comb in n mode!! FwCmdMap(%#x), "
1573 "FwParam(%#x)\n", fw_cmdmap, fw_param));
1574
1575 FW_CMD_PARA_SET(rtlpriv, fw_param);
1576 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1577
1578 /* Clear control flag to sync with FW. */
1579 FW_CMD_IO_CLR(rtlpriv, FW_RA_N_CTL);
1580 break;
1581 case FW_CMD_RA_REFRESH_BG_COMB:
1582 fw_cmdmap |= FW_RA_BG_CTL;
1583
1584 /* Clear RA n-mode control. */
1585 fw_cmdmap &= ~(FW_RA_N_CTL | FW_RA_INIT_CTL);
1586 /* Clear FW parameter in terms of RA parts. */
1587 fw_param &= FW_RA_PARAM_CLR;
1588
1589 FW_CMD_PARA_SET(rtlpriv, fw_param);
1590 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1591
1592 /* Clear control flag to sync with FW. */
1593 FW_CMD_IO_CLR(rtlpriv, FW_RA_BG_CTL);
1594 break;
1595 case FW_CMD_IQK_ENABLE:
1596 fw_cmdmap |= FW_IQK_CTL;
1597 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1598 /* Clear control flag to sync with FW. */
1599 FW_CMD_IO_CLR(rtlpriv, FW_IQK_CTL);
1600 break;
1601 /* The following FW CMD is compatible to v.62 or later. */
1602 case FW_CMD_CTRL_DM_BY_DRIVER_NEW:
1603 fw_cmdmap |= FW_DRIVER_CTRL_DM_CTL;
1604 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1605 break;
1606 /* The followed FW Cmds needs post-processing later. */
1607 case FW_CMD_RESUME_DM_BY_SCAN:
1608 fw_cmdmap |= (FW_DIG_ENABLE_CTL |
1609 FW_HIGH_PWR_ENABLE_CTL |
1610 FW_SS_CTL);
1611
1612 if (rtlpriv->dm.dm_flag & HAL_DM_DIG_DISABLE ||
1613 !digtable.dig_enable_flag)
1614 fw_cmdmap &= ~FW_DIG_ENABLE_CTL;
1615
1616 if ((rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) ||
1617 (rtlpriv->dm.dynamic_txpower_enable == true))
1618 fw_cmdmap &= ~FW_HIGH_PWR_ENABLE_CTL;
1619
1620 if ((digtable.dig_ext_port_stage ==
1621 DIG_EXT_PORT_STAGE_0) ||
1622 (digtable.dig_ext_port_stage ==
1623 DIG_EXT_PORT_STAGE_1))
1624 fw_cmdmap &= ~FW_DIG_ENABLE_CTL;
1625
1626 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1627 bPostProcessing = true;
1628 break;
1629 case FW_CMD_PAUSE_DM_BY_SCAN:
1630 fw_cmdmap &= ~(FW_DIG_ENABLE_CTL |
1631 FW_HIGH_PWR_ENABLE_CTL |
1632 FW_SS_CTL);
1633 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1634 bPostProcessing = true;
1635 break;
1636 case FW_CMD_HIGH_PWR_DISABLE:
1637 fw_cmdmap &= ~FW_HIGH_PWR_ENABLE_CTL;
1638 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1639 bPostProcessing = true;
1640 break;
1641 case FW_CMD_HIGH_PWR_ENABLE:
1642 if (!(rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) &&
1643 (rtlpriv->dm.dynamic_txpower_enable != true)) {
1644 fw_cmdmap |= (FW_HIGH_PWR_ENABLE_CTL |
1645 FW_SS_CTL);
1646 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1647 bPostProcessing = true;
1648 }
1649 break;
1650 case FW_CMD_DIG_MODE_FA:
1651 fw_cmdmap |= FW_FA_CTL;
1652 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1653 break;
1654 case FW_CMD_DIG_MODE_SS:
1655 fw_cmdmap &= ~FW_FA_CTL;
1656 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1657 break;
1658 case FW_CMD_PAPE_CONTROL:
1659 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
1660 ("[FW CMD] Set PAPE Control\n"));
1661 fw_cmdmap &= ~FW_PAPE_CTL_BY_SW_HW;
1662
1663 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1664 break;
1665 default:
1666 /* Pass to original FW CMD processing callback
1667 * routine. */
1668 bPostProcessing = true;
1669 break;
1670 }
1671 } while (false);
1672
1673 /* We shall post processing these FW CMD if
1674 * variable bPostProcessing is set. */
1675 if (bPostProcessing && !rtlhal->set_fwcmd_inprogress) {
1676 rtlhal->set_fwcmd_inprogress = true;
1677 /* Update current FW Cmd for callback use. */
1678 rtlhal->current_fwcmd_io = fw_cmdio;
1679 } else {
1680 return false;
1681 }
1682
1683 _rtl92s_phy_set_fwcmd_io(hw);
1684 return true;
1685}
1686
1687static void _rtl92s_phy_check_ephy_switchready(struct ieee80211_hw *hw)
1688{
1689 struct rtl_priv *rtlpriv = rtl_priv(hw);
1690 u32 delay = 100;
1691 u8 regu1;
1692
1693 regu1 = rtl_read_byte(rtlpriv, 0x554);
1694 while ((regu1 & BIT(5)) && (delay > 0)) {
1695 regu1 = rtl_read_byte(rtlpriv, 0x554);
1696 delay--;
1697 /* We delay only 50us to prevent
1698 * being scheduled out. */
1699 udelay(50);
1700 }
1701}
1702
1703void rtl92s_phy_switch_ephy_parameter(struct ieee80211_hw *hw)
1704{
1705 struct rtl_priv *rtlpriv = rtl_priv(hw);
1706 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
1707
1708 /* The way to be capable to switch clock request
1709 * when the PG setting does not support clock request.
1710 * This is the backdoor solution to switch clock
1711 * request before ASPM or D3. */
1712 rtl_write_dword(rtlpriv, 0x540, 0x73c11);
1713 rtl_write_dword(rtlpriv, 0x548, 0x2407c);
1714
1715 /* Switch EPHY parameter!!!! */
1716 rtl_write_word(rtlpriv, 0x550, 0x1000);
1717 rtl_write_byte(rtlpriv, 0x554, 0x20);
1718 _rtl92s_phy_check_ephy_switchready(hw);
1719
1720 rtl_write_word(rtlpriv, 0x550, 0xa0eb);
1721 rtl_write_byte(rtlpriv, 0x554, 0x3e);
1722 _rtl92s_phy_check_ephy_switchready(hw);
1723
1724 rtl_write_word(rtlpriv, 0x550, 0xff80);
1725 rtl_write_byte(rtlpriv, 0x554, 0x39);
1726 _rtl92s_phy_check_ephy_switchready(hw);
1727
1728 /* Delay L1 enter time */
1729 if (ppsc->support_aspm && !ppsc->support_backdoor)
1730 rtl_write_byte(rtlpriv, 0x560, 0x40);
1731 else
1732 rtl_write_byte(rtlpriv, 0x560, 0x00);
1733
1734}
1735
1736void rtl92s_phy_set_beacon_hwreg(struct ieee80211_hw *hw, u16 BeaconInterval)
1737{
1738 struct rtl_priv *rtlpriv = rtl_priv(hw);
1739 rtl_write_dword(rtlpriv, WFM5, 0xF1000000 | (BeaconInterval << 8));
1740}
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/phy.h b/drivers/net/wireless/rtlwifi/rtl8192se/phy.h
new file mode 100644
index 000000000000..37e504af6446
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/phy.h
@@ -0,0 +1,101 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2010 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29#ifndef __RTL92S_PHY_H__
30#define __RTL92S_PHY_H__
31
32#define MAX_TXPWR_IDX_NMODE_92S 63
33#define MAX_DOZE_WAITING_TIMES_9x 64
34
35/* Channel switch:The size of
36 * command tables for switch channel */
37#define MAX_PRECMD_CNT 16
38#define MAX_RFDEPENDCMD_CNT 16
39#define MAX_POSTCMD_CNT 16
40
41#define RF90_PATH_MAX 4
42
43enum version_8192s {
44 VERSION_8192S_ACUT,
45 VERSION_8192S_BCUT,
46 VERSION_8192S_CCUT
47};
48
49enum swchnlcmd_id {
50 CMDID_END,
51 CMDID_SET_TXPOWEROWER_LEVEL,
52 CMDID_BBREGWRITE10,
53 CMDID_WRITEPORT_ULONG,
54 CMDID_WRITEPORT_USHORT,
55 CMDID_WRITEPORT_UCHAR,
56 CMDID_RF_WRITEREG,
57};
58
59struct swchnlcmd {
60 enum swchnlcmd_id cmdid;
61 u32 para1;
62 u32 para2;
63 u32 msdelay;
64};
65
66enum baseband_config_type {
67 /* Radio Path A */
68 BASEBAND_CONFIG_PHY_REG = 0,
69 /* Radio Path B */
70 BASEBAND_CONFIG_AGC_TAB = 1,
71};
72
73#define hal_get_firmwareversion(rtlpriv) \
74 (((struct rt_firmware *)(rtlpriv->rtlhal.pfirmware))->firmwareversion)
75
76u32 rtl92s_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask);
77void rtl92s_phy_set_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask,
78 u32 data);
79void rtl92s_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation);
80u32 rtl92s_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
81 u32 regaddr, u32 bitmask);
82void rtl92s_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
83 u32 regaddr, u32 bitmask, u32 data);
84void rtl92s_phy_set_bw_mode(struct ieee80211_hw *hw,
85 enum nl80211_channel_type ch_type);
86u8 rtl92s_phy_sw_chnl(struct ieee80211_hw *hw);
87bool rtl92s_phy_set_rf_power_state(struct ieee80211_hw *hw,
88 enum rf_pwrstate rfpower_state);
89bool rtl92s_phy_mac_config(struct ieee80211_hw *hw);
90void rtl92s_phy_switch_ephy_parameter(struct ieee80211_hw *hw);
91bool rtl92s_phy_bb_config(struct ieee80211_hw *hw);
92bool rtl92s_phy_rf_config(struct ieee80211_hw *hw);
93void rtl92s_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw);
94void rtl92s_phy_set_txpower(struct ieee80211_hw *hw, u8 channel);
95bool rtl92s_phy_set_fw_cmd(struct ieee80211_hw *hw, enum fwcmd_iotype fwcmd_io);
96void rtl92s_phy_chk_fwcmd_iodone(struct ieee80211_hw *hw);
97void rtl92s_phy_set_beacon_hwreg(struct ieee80211_hw *hw, u16 beaconinterval);
98u8 rtl92s_phy_config_rf(struct ieee80211_hw *hw, enum radio_path rfpath) ;
99
100#endif
101
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/reg.h b/drivers/net/wireless/rtlwifi/rtl8192se/reg.h
new file mode 100644
index 000000000000..0116eaddbfac
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/reg.h
@@ -0,0 +1,1188 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2010 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29#ifndef __REALTEK_92S_REG_H__
30#define __REALTEK_92S_REG_H__
31
32/* 1. System Configuration Registers */
33#define REG_SYS_ISO_CTRL 0x0000
34#define REG_SYS_FUNC_EN 0x0002
35#define PMC_FSM 0x0004
36#define SYS_CLKR 0x0008
37#define EPROM_CMD 0x000A
38#define EE_VPD 0x000C
39#define AFE_MISC 0x0010
40#define SPS0_CTRL 0x0011
41#define SPS1_CTRL 0x0018
42#define RF_CTRL 0x001F
43#define LDOA15_CTRL 0x0020
44#define LDOV12D_CTRL 0x0021
45#define LDOHCI12_CTRL 0x0022
46#define LDO_USB_SDIO 0x0023
47#define LPLDO_CTRL 0x0024
48#define AFE_XTAL_CTRL 0x0026
49#define AFE_PLL_CTRL 0x0028
50#define REG_EFUSE_CTRL 0x0030
51#define REG_EFUSE_TEST 0x0034
52#define PWR_DATA 0x0038
53#define DBG_PORT 0x003A
54#define DPS_TIMER 0x003C
55#define RCLK_MON 0x003E
56
57/* 2. Command Control Registers */
58#define CMDR 0x0040
59#define TXPAUSE 0x0042
60#define LBKMD_SEL 0x0043
61#define TCR 0x0044
62#define RCR 0x0048
63#define MSR 0x004C
64#define SYSF_CFG 0x004D
65#define RX_PKY_LIMIT 0x004E
66#define MBIDCTRL 0x004F
67
68/* 3. MACID Setting Registers */
69#define MACIDR 0x0050
70#define MACIDR0 0x0050
71#define MACIDR4 0x0054
72#define BSSIDR 0x0058
73#define HWVID 0x005E
74#define MAR 0x0060
75#define MBIDCAMCONTENT 0x0068
76#define MBIDCAMCFG 0x0070
77#define BUILDTIME 0x0074
78#define BUILDUSER 0x0078
79
80#define IDR0 MACIDR0
81#define IDR4 MACIDR4
82
83/* 4. Timing Control Registers */
84#define TSFR 0x0080
85#define SLOT_TIME 0x0089
86#define USTIME 0x008A
87#define SIFS_CCK 0x008C
88#define SIFS_OFDM 0x008E
89#define PIFS_TIME 0x0090
90#define ACK_TIMEOUT 0x0091
91#define EIFSTR 0x0092
92#define BCN_INTERVAL 0x0094
93#define ATIMWND 0x0096
94#define BCN_DRV_EARLY_INT 0x0098
95#define BCN_DMATIME 0x009A
96#define BCN_ERR_THRESH 0x009C
97#define MLT 0x009D
98#define RSVD_MAC_TUNE_US 0x009E
99
100/* 5. FIFO Control Registers */
101#define RQPN 0x00A0
102#define RQPN1 0x00A0
103#define RQPN2 0x00A1
104#define RQPN3 0x00A2
105#define RQPN4 0x00A3
106#define RQPN5 0x00A4
107#define RQPN6 0x00A5
108#define RQPN7 0x00A6
109#define RQPN8 0x00A7
110#define RQPN9 0x00A8
111#define RQPN10 0x00A9
112#define LD_RQPN 0x00AB
113#define RXFF_BNDY 0x00AC
114#define RXRPT_BNDY 0x00B0
115#define TXPKTBUF_PGBNDY 0x00B4
116#define PBP 0x00B5
117#define RXDRVINFO_SZ 0x00B6
118#define TXFF_STATUS 0x00B7
119#define RXFF_STATUS 0x00B8
120#define TXFF_EMPTY_TH 0x00B9
121#define SDIO_RX_BLKSZ 0x00BC
122#define RXDMA 0x00BD
123#define RXPKT_NUM 0x00BE
124#define C2HCMD_UDT_SIZE 0x00C0
125#define C2HCMD_UDT_ADDR 0x00C2
126#define FIFOPAGE1 0x00C4
127#define FIFOPAGE2 0x00C8
128#define FIFOPAGE3 0x00CC
129#define FIFOPAGE4 0x00D0
130#define FIFOPAGE5 0x00D4
131#define FW_RSVD_PG_CRTL 0x00D8
132#define RXDMA_AGG_PG_TH 0x00D9
133#define TXDESC_MSK 0x00DC
134#define TXRPTFF_RDPTR 0x00E0
135#define TXRPTFF_WTPTR 0x00E4
136#define C2HFF_RDPTR 0x00E8
137#define C2HFF_WTPTR 0x00EC
138#define RXFF0_RDPTR 0x00F0
139#define RXFF0_WTPTR 0x00F4
140#define RXFF1_RDPTR 0x00F8
141#define RXFF1_WTPTR 0x00FC
142#define RXRPT0_RDPTR 0x0100
143#define RXRPT0_WTPTR 0x0104
144#define RXRPT1_RDPTR 0x0108
145#define RXRPT1_WTPTR 0x010C
146#define RX0_UDT_SIZE 0x0110
147#define RX1PKTNUM 0x0114
148#define RXFILTERMAP 0x0116
149#define RXFILTERMAP_GP1 0x0118
150#define RXFILTERMAP_GP2 0x011A
151#define RXFILTERMAP_GP3 0x011C
152#define BCNQ_CTRL 0x0120
153#define MGTQ_CTRL 0x0124
154#define HIQ_CTRL 0x0128
155#define VOTID7_CTRL 0x012c
156#define VOTID6_CTRL 0x0130
157#define VITID5_CTRL 0x0134
158#define VITID4_CTRL 0x0138
159#define BETID3_CTRL 0x013c
160#define BETID0_CTRL 0x0140
161#define BKTID2_CTRL 0x0144
162#define BKTID1_CTRL 0x0148
163#define CMDQ_CTRL 0x014c
164#define TXPKT_NUM_CTRL 0x0150
165#define TXQ_PGADD 0x0152
166#define TXFF_PG_NUM 0x0154
167#define TRXDMA_STATUS 0x0156
168
169/* 6. Adaptive Control Registers */
170#define INIMCS_SEL 0x0160
171#define TX_RATE_REG INIMCS_SEL
172#define INIRTSMCS_SEL 0x0180
173#define RRSR 0x0181
174#define ARFR0 0x0184
175#define ARFR1 0x0188
176#define ARFR2 0x018C
177#define ARFR3 0x0190
178#define ARFR4 0x0194
179#define ARFR5 0x0198
180#define ARFR6 0x019C
181#define ARFR7 0x01A0
182#define AGGLEN_LMT_H 0x01A7
183#define AGGLEN_LMT_L 0x01A8
184#define DARFRC 0x01B0
185#define RARFRC 0x01B8
186#define MCS_TXAGC 0x01C0
187#define CCK_TXAGC 0x01C8
188
189/* 7. EDCA Setting Registers */
190#define EDCAPARA_VO 0x01D0
191#define EDCAPARA_VI 0x01D4
192#define EDCAPARA_BE 0x01D8
193#define EDCAPARA_BK 0x01DC
194#define BCNTCFG 0x01E0
195#define CWRR 0x01E2
196#define ACMAVG 0x01E4
197#define AcmHwCtrl 0x01E7
198#define VO_ADMTM 0x01E8
199#define VI_ADMTM 0x01EC
200#define BE_ADMTM 0x01F0
201#define RETRY_LIMIT 0x01F4
202#define SG_RATE 0x01F6
203
204/* 8. WMAC, BA and CCX related Register. */
205#define NAV_CTRL 0x0200
206#define BW_OPMODE 0x0203
207#define BACAMCMD 0x0204
208#define BACAMCONTENT 0x0208
209
210/* the 0x2xx register WMAC definition */
211#define LBDLY 0x0210
212#define FWDLY 0x0211
213#define HWPC_RX_CTRL 0x0218
214#define MQIR 0x0220
215#define MAIR 0x0222
216#define MSIR 0x0224
217#define CLM_RESULT 0x0227
218#define NHM_RPI_CNT 0x0228
219#define RXERR_RPT 0x0230
220#define NAV_PROT_LEN 0x0234
221#define CFEND_TH 0x0236
222#define AMPDU_MIN_SPACE 0x0237
223#define TXOP_STALL_CTRL 0x0238
224
225/* 9. Security Control Registers */
226#define REG_RWCAM 0x0240
227#define REG_WCAMI 0x0244
228#define REG_RCAMO 0x0248
229#define REG_CAMDBG 0x024C
230#define REG_SECR 0x0250
231
232/* 10. Power Save Control Registers */
233#define WOW_CTRL 0x0260
234#define PSSTATUS 0x0261
235#define PSSWITCH 0x0262
236#define MIMOPS_WAIT_PERIOD 0x0263
237#define LPNAV_CTRL 0x0264
238#define WFM0 0x0270
239#define WFM1 0x0280
240#define WFM2 0x0290
241#define WFM3 0x02A0
242#define WFM4 0x02B0
243#define WFM5 0x02C0
244#define WFCRC 0x02D0
245#define FW_RPT_REG 0x02c4
246
247/* 11. General Purpose Registers */
248#define PSTIME 0x02E0
249#define TIMER0 0x02E4
250#define TIMER1 0x02E8
251#define GPIO_CTRL 0x02EC
252#define GPIO_IN 0x02EC
253#define GPIO_OUT 0x02ED
254#define GPIO_IO_SEL 0x02EE
255#define GPIO_MOD 0x02EF
256#define GPIO_INTCTRL 0x02F0
257#define MAC_PINMUX_CFG 0x02F1
258#define LEDCFG 0x02F2
259#define PHY_REG 0x02F3
260#define PHY_REG_DATA 0x02F4
261#define REG_EFUSE_CLK 0x02F8
262
263/* 12. Host Interrupt Status Registers */
264#define INTA_MASK 0x0300
265#define ISR 0x0308
266
267/* 13. Test Mode and Debug Control Registers */
268#define DBG_PORT_SWITCH 0x003A
269#define BIST 0x0310
270#define DBS 0x0314
271#define CPUINST 0x0318
272#define CPUCAUSE 0x031C
273#define LBUS_ERR_ADDR 0x0320
274#define LBUS_ERR_CMD 0x0324
275#define LBUS_ERR_DATA_L 0x0328
276#define LBUS_ERR_DATA_H 0x032C
277#define LX_EXCEPTION_ADDR 0x0330
278#define WDG_CTRL 0x0334
279#define INTMTU 0x0338
280#define INTM 0x033A
281#define FDLOCKTURN0 0x033C
282#define FDLOCKTURN1 0x033D
283#define TRXPKTBUF_DBG_DATA 0x0340
284#define TRXPKTBUF_DBG_CTRL 0x0348
285#define DPLL 0x034A
286#define CBUS_ERR_ADDR 0x0350
287#define CBUS_ERR_CMD 0x0354
288#define CBUS_ERR_DATA_L 0x0358
289#define CBUS_ERR_DATA_H 0x035C
290#define USB_SIE_INTF_ADDR 0x0360
291#define USB_SIE_INTF_WD 0x0361
292#define USB_SIE_INTF_RD 0x0362
293#define USB_SIE_INTF_CTRL 0x0363
294#define LBUS_MON_ADDR 0x0364
295#define LBUS_ADDR_MASK 0x0368
296
297/* Boundary is 0x37F */
298
299/* 14. PCIE config register */
300#define TP_POLL 0x0500
301#define PM_CTRL 0x0502
302#define PCIF 0x0503
303
304#define THPDA 0x0514
305#define TMDA 0x0518
306#define TCDA 0x051C
307#define HDA 0x0520
308#define TVODA 0x0524
309#define TVIDA 0x0528
310#define TBEDA 0x052C
311#define TBKDA 0x0530
312#define TBDA 0x0534
313#define RCDA 0x0538
314#define RDQDA 0x053C
315#define DBI_WDATA 0x0540
316#define DBI_RDATA 0x0544
317#define DBI_CTRL 0x0548
318#define MDIO_DATA 0x0550
319#define MDIO_CTRL 0x0554
320#define PCI_RPWM 0x0561
321#define PCI_CPWM 0x0563
322
323/* Config register (Offset 0x800-) */
324#define PHY_CCA 0x803
325
326/* Min Spacing related settings. */
327#define MAX_MSS_DENSITY_2T 0x13
328#define MAX_MSS_DENSITY_1T 0x0A
329
330/* Rx DMA Control related settings */
331#define RXDMA_AGG_EN BIT(7)
332
333#define RPWM PCI_RPWM
334
335/* Regsiter Bit and Content definition */
336
337#define ISO_MD2PP BIT(0)
338#define ISO_PA2PCIE BIT(3)
339#define ISO_PLL2MD BIT(4)
340#define ISO_PWC_DV2RP BIT(11)
341#define ISO_PWC_RV2RP BIT(12)
342
343
344#define FEN_MREGEN BIT(15)
345#define FEN_DCORE BIT(11)
346#define FEN_CPUEN BIT(10)
347
348#define PAD_HWPD_IDN BIT(22)
349
350#define SYS_CLKSEL_80M BIT(0)
351#define SYS_PS_CLKSEL BIT(1)
352#define SYS_CPU_CLKSEL BIT(2)
353#define SYS_MAC_CLK_EN BIT(11)
354#define SYS_SWHW_SEL BIT(14)
355#define SYS_FWHW_SEL BIT(15)
356
357#define CmdEEPROM_En BIT(5)
358#define CmdEERPOMSEL BIT(4)
359#define Cmd9346CR_9356SEL BIT(4)
360
361#define AFE_MBEN BIT(1)
362#define AFE_BGEN BIT(0)
363
364#define SPS1_SWEN BIT(1)
365#define SPS1_LDEN BIT(0)
366
367#define RF_EN BIT(0)
368#define RF_RSTB BIT(1)
369#define RF_SDMRSTB BIT(2)
370
371#define LDA15_EN BIT(0)
372
373#define LDV12_EN BIT(0)
374#define LDV12_SDBY BIT(1)
375
376#define XTAL_GATE_AFE BIT(10)
377
378#define APLL_EN BIT(0)
379
380#define AFR_CardBEn BIT(0)
381#define AFR_CLKRUN_SEL BIT(1)
382#define AFR_FuncRegEn BIT(2)
383
384#define APSDOFF_STATUS BIT(15)
385#define APSDOFF BIT(14)
386#define BBRSTN BIT(13)
387#define BB_GLB_RSTN BIT(12)
388#define SCHEDULE_EN BIT(10)
389#define MACRXEN BIT(9)
390#define MACTXEN BIT(8)
391#define DDMA_EN BIT(7)
392#define FW2HW_EN BIT(6)
393#define RXDMA_EN BIT(5)
394#define TXDMA_EN BIT(4)
395#define HCI_RXDMA_EN BIT(3)
396#define HCI_TXDMA_EN BIT(2)
397
398#define StopHCCA BIT(6)
399#define StopHigh BIT(5)
400#define StopMgt BIT(4)
401#define StopVO BIT(3)
402#define StopVI BIT(2)
403#define StopBE BIT(1)
404#define StopBK BIT(0)
405
406#define LBK_NORMAL 0x00
407#define LBK_MAC_LB (BIT(0) | BIT(1) | BIT(3))
408#define LBK_MAC_DLB (BIT(0) | BIT(1))
409#define LBK_DMA_LB (BIT(0) | BIT(1) | BIT(2))
410
411#define TCP_OFDL_EN BIT(25)
412#define HWPC_TX_EN BIT(24)
413#define TXDMAPRE2FULL BIT(23)
414#define DISCW BIT(20)
415#define TCRICV BIT(19)
416#define CfendForm BIT(17)
417#define TCRCRC BIT(16)
418#define FAKE_IMEM_EN BIT(15)
419#define TSFRST BIT(9)
420#define TSFEN BIT(8)
421#define FWALLRDY (BIT(0) | BIT(1) | BIT(2) | \
422 BIT(3) | BIT(4) | BIT(5) | \
423 BIT(6) | BIT(7))
424#define FWRDY BIT(7)
425#define BASECHG BIT(6)
426#define IMEM BIT(5)
427#define DMEM_CODE_DONE BIT(4)
428#define EXT_IMEM_CHK_RPT BIT(3)
429#define EXT_IMEM_CODE_DONE BIT(2)
430#define IMEM_CHK_RPT BIT(1)
431#define IMEM_CODE_DONE BIT(0)
432#define IMEM_CODE_DONE BIT(0)
433#define IMEM_CHK_RPT BIT(1)
434#define EMEM_CODE_DONE BIT(2)
435#define EMEM_CHK_RPT BIT(3)
436#define DMEM_CODE_DONE BIT(4)
437#define IMEM_RDY BIT(5)
438#define BASECHG BIT(6)
439#define FWRDY BIT(7)
440#define LOAD_FW_READY (IMEM_CODE_DONE | \
441 IMEM_CHK_RPT | \
442 EMEM_CODE_DONE | \
443 EMEM_CHK_RPT | \
444 DMEM_CODE_DONE | \
445 IMEM_RDY | \
446 BASECHG | \
447 FWRDY)
448#define TCR_TSFEN BIT(8)
449#define TCR_TSFRST BIT(9)
450#define TCR_FAKE_IMEM_EN BIT(15)
451#define TCR_CRC BIT(16)
452#define TCR_ICV BIT(19)
453#define TCR_DISCW BIT(20)
454#define TCR_HWPC_TX_EN BIT(24)
455#define TCR_TCP_OFDL_EN BIT(25)
456#define TXDMA_INIT_VALUE (IMEM_CHK_RPT | \
457 EXT_IMEM_CHK_RPT)
458
459#define RCR_APPFCS BIT(31)
460#define RCR_DIS_ENC_2BYTE BIT(30)
461#define RCR_DIS_AES_2BYTE BIT(29)
462#define RCR_HTC_LOC_CTRL BIT(28)
463#define RCR_ENMBID BIT(27)
464#define RCR_RX_TCPOFDL_EN BIT(26)
465#define RCR_APP_PHYST_RXFF BIT(25)
466#define RCR_APP_PHYST_STAFF BIT(24)
467#define RCR_CBSSID BIT(23)
468#define RCR_APWRMGT BIT(22)
469#define RCR_ADD3 BIT(21)
470#define RCR_AMF BIT(20)
471#define RCR_ACF BIT(19)
472#define RCR_ADF BIT(18)
473#define RCR_APP_MIC BIT(17)
474#define RCR_APP_ICV BIT(16)
475#define RCR_RXFTH BIT(13)
476#define RCR_AICV BIT(12)
477#define RCR_RXDESC_LK_EN BIT(11)
478#define RCR_APP_BA_SSN BIT(6)
479#define RCR_ACRC32 BIT(5)
480#define RCR_RXSHFT_EN BIT(4)
481#define RCR_AB BIT(3)
482#define RCR_AM BIT(2)
483#define RCR_APM BIT(1)
484#define RCR_AAP BIT(0)
485#define RCR_MXDMA_OFFSET 8
486#define RCR_FIFO_OFFSET 13
487
488
489#define MSR_LINK_MASK ((1 << 0) | (1 << 1))
490#define MSR_LINK_MANAGED 2
491#define MSR_LINK_NONE 0
492#define MSR_LINK_SHIFT 0
493#define MSR_LINK_ADHOC 1
494#define MSR_LINK_MASTER 3
495#define MSR_NOLINK 0x00
496#define MSR_ADHOC 0x01
497#define MSR_INFRA 0x02
498#define MSR_AP 0x03
499
500#define ENUART BIT(7)
501#define ENJTAG BIT(3)
502#define BTMODE (BIT(2) | BIT(1))
503#define ENBT BIT(0)
504
505#define ENMBID BIT(7)
506#define BCNUM (BIT(6) | BIT(5) | BIT(4))
507
508#define USTIME_EDCA 0xFF00
509#define USTIME_TSF 0x00FF
510
511#define SIFS_TRX 0xFF00
512#define SIFS_CTX 0x00FF
513
514#define ENSWBCN BIT(15)
515#define DRVERLY_TU 0x0FF0
516#define DRVERLY_US 0x000F
517#define BCN_TCFG_CW_SHIFT 8
518#define BCN_TCFG_IFS 0
519
520#define RRSR_RSC_OFFSET 21
521#define RRSR_SHORT_OFFSET 23
522#define RRSR_RSC_BW_40M 0x600000
523#define RRSR_RSC_UPSUBCHNL 0x400000
524#define RRSR_RSC_LOWSUBCHNL 0x200000
525#define RRSR_SHORT 0x800000
526#define RRSR_1M BIT(0)
527#define RRSR_2M BIT(1)
528#define RRSR_5_5M BIT(2)
529#define RRSR_11M BIT(3)
530#define RRSR_6M BIT(4)
531#define RRSR_9M BIT(5)
532#define RRSR_12M BIT(6)
533#define RRSR_18M BIT(7)
534#define RRSR_24M BIT(8)
535#define RRSR_36M BIT(9)
536#define RRSR_48M BIT(10)
537#define RRSR_54M BIT(11)
538#define RRSR_MCS0 BIT(12)
539#define RRSR_MCS1 BIT(13)
540#define RRSR_MCS2 BIT(14)
541#define RRSR_MCS3 BIT(15)
542#define RRSR_MCS4 BIT(16)
543#define RRSR_MCS5 BIT(17)
544#define RRSR_MCS6 BIT(18)
545#define RRSR_MCS7 BIT(19)
546#define BRSR_AckShortPmb BIT(23)
547
548#define RATR_1M 0x00000001
549#define RATR_2M 0x00000002
550#define RATR_55M 0x00000004
551#define RATR_11M 0x00000008
552#define RATR_6M 0x00000010
553#define RATR_9M 0x00000020
554#define RATR_12M 0x00000040
555#define RATR_18M 0x00000080
556#define RATR_24M 0x00000100
557#define RATR_36M 0x00000200
558#define RATR_48M 0x00000400
559#define RATR_54M 0x00000800
560#define RATR_MCS0 0x00001000
561#define RATR_MCS1 0x00002000
562#define RATR_MCS2 0x00004000
563#define RATR_MCS3 0x00008000
564#define RATR_MCS4 0x00010000
565#define RATR_MCS5 0x00020000
566#define RATR_MCS6 0x00040000
567#define RATR_MCS7 0x00080000
568#define RATR_MCS8 0x00100000
569#define RATR_MCS9 0x00200000
570#define RATR_MCS10 0x00400000
571#define RATR_MCS11 0x00800000
572#define RATR_MCS12 0x01000000
573#define RATR_MCS13 0x02000000
574#define RATR_MCS14 0x04000000
575#define RATR_MCS15 0x08000000
576
577#define RATE_ALL_CCK (RATR_1M | RATR_2M | \
578 RATR_55M | RATR_11M)
579#define RATE_ALL_OFDM_AG (RATR_6M | RATR_9M | \
580 RATR_12M | RATR_18M | \
581 RATR_24M | RATR_36M | \
582 RATR_48M | RATR_54M)
583#define RATE_ALL_OFDM_1SS (RATR_MCS0 | RATR_MCS1 | \
584 RATR_MCS2 | RATR_MCS3 | \
585 RATR_MCS4 | RATR_MCS5 | \
586 RATR_MCS6 | RATR_MCS7)
587#define RATE_ALL_OFDM_2SS (RATR_MCS8 | RATR_MCS9 | \
588 RATR_MCS10 | RATR_MCS11 | \
589 RATR_MCS12 | RATR_MCS13 | \
590 RATR_MCS14 | RATR_MCS15)
591
592#define AC_PARAM_TXOP_LIMIT_OFFSET 16
593#define AC_PARAM_ECW_MAX_OFFSET 12
594#define AC_PARAM_ECW_MIN_OFFSET 8
595#define AC_PARAM_AIFS_OFFSET 0
596
597#define AcmHw_HwEn BIT(0)
598#define AcmHw_BeqEn BIT(1)
599#define AcmHw_ViqEn BIT(2)
600#define AcmHw_VoqEn BIT(3)
601#define AcmHw_BeqStatus BIT(4)
602#define AcmHw_ViqStatus BIT(5)
603#define AcmHw_VoqStatus BIT(6)
604
605#define RETRY_LIMIT_SHORT_SHIFT 8
606#define RETRY_LIMIT_LONG_SHIFT 0
607
608#define NAV_UPPER_EN BIT(16)
609#define NAV_UPPER 0xFF00
610#define NAV_RTSRST 0xFF
611
612#define BW_OPMODE_20MHZ BIT(2)
613#define BW_OPMODE_5G BIT(1)
614#define BW_OPMODE_11J BIT(0)
615
616#define RXERR_RPT_RST BIT(27)
617#define RXERR_OFDM_PPDU 0
618#define RXERR_OFDM_FALSE_ALARM 1
619#define RXERR_OFDM_MPDU_OK 2
620#define RXERR_OFDM_MPDU_FAIL 3
621#define RXERR_CCK_PPDU 4
622#define RXERR_CCK_FALSE_ALARM 5
623#define RXERR_CCK_MPDU_OK 6
624#define RXERR_CCK_MPDU_FAIL 7
625#define RXERR_HT_PPDU 8
626#define RXERR_HT_FALSE_ALARM 9
627#define RXERR_HT_MPDU_TOTAL 10
628#define RXERR_HT_MPDU_OK 11
629#define RXERR_HT_MPDU_FAIL 12
630#define RXERR_RX_FULL_DROP 15
631
632#define SCR_TXUSEDK BIT(0)
633#define SCR_RXUSEDK BIT(1)
634#define SCR_TXENCENABLE BIT(2)
635#define SCR_RXENCENABLE BIT(3)
636#define SCR_SKBYA2 BIT(4)
637#define SCR_NOSKMC BIT(5)
638
639#define CAM_VALID BIT(15)
640#define CAM_NOTVALID 0x0000
641#define CAM_USEDK BIT(5)
642
643#define CAM_NONE 0x0
644#define CAM_WEP40 0x01
645#define CAM_TKIP 0x02
646#define CAM_AES 0x04
647#define CAM_WEP104 0x05
648
649#define TOTAL_CAM_ENTRY 32
650#define HALF_CAM_ENTRY 16
651
652#define CAM_WRITE BIT(16)
653#define CAM_READ 0x00000000
654#define CAM_POLLINIG BIT(31)
655
656#define WOW_PMEN BIT(0)
657#define WOW_WOMEN BIT(1)
658#define WOW_MAGIC BIT(2)
659#define WOW_UWF BIT(3)
660
661#define GPIOMUX_EN BIT(3)
662#define GPIOSEL_GPIO 0
663#define GPIOSEL_PHYDBG 1
664#define GPIOSEL_BT 2
665#define GPIOSEL_WLANDBG 3
666#define GPIOSEL_GPIO_MASK (~(BIT(0)|BIT(1)))
667
668#define HST_RDBUSY BIT(0)
669#define CPU_WTBUSY BIT(1)
670
671#define IMR8190_DISABLED 0x0
672#define IMR_CPUERR BIT(5)
673#define IMR_ATIMEND BIT(4)
674#define IMR_TBDOK BIT(3)
675#define IMR_TBDER BIT(2)
676#define IMR_BCNDMAINT8 BIT(1)
677#define IMR_BCNDMAINT7 BIT(0)
678#define IMR_BCNDMAINT6 BIT(31)
679#define IMR_BCNDMAINT5 BIT(30)
680#define IMR_BCNDMAINT4 BIT(29)
681#define IMR_BCNDMAINT3 BIT(28)
682#define IMR_BCNDMAINT2 BIT(27)
683#define IMR_BCNDMAINT1 BIT(26)
684#define IMR_BCNDOK8 BIT(25)
685#define IMR_BCNDOK7 BIT(24)
686#define IMR_BCNDOK6 BIT(23)
687#define IMR_BCNDOK5 BIT(22)
688#define IMR_BCNDOK4 BIT(21)
689#define IMR_BCNDOK3 BIT(20)
690#define IMR_BCNDOK2 BIT(19)
691#define IMR_BCNDOK1 BIT(18)
692#define IMR_TIMEOUT2 BIT(17)
693#define IMR_TIMEOUT1 BIT(16)
694#define IMR_TXFOVW BIT(15)
695#define IMR_PSTIMEOUT BIT(14)
696#define IMR_BCNINT BIT(13)
697#define IMR_RXFOVW BIT(12)
698#define IMR_RDU BIT(11)
699#define IMR_RXCMDOK BIT(10)
700#define IMR_BDOK BIT(9)
701#define IMR_HIGHDOK BIT(8)
702#define IMR_COMDOK BIT(7)
703#define IMR_MGNTDOK BIT(6)
704#define IMR_HCCADOK BIT(5)
705#define IMR_BKDOK BIT(4)
706#define IMR_BEDOK BIT(3)
707#define IMR_VIDOK BIT(2)
708#define IMR_VODOK BIT(1)
709#define IMR_ROK BIT(0)
710
711#define TPPOLL_BKQ BIT(0)
712#define TPPOLL_BEQ BIT(1)
713#define TPPOLL_VIQ BIT(2)
714#define TPPOLL_VOQ BIT(3)
715#define TPPOLL_BQ BIT(4)
716#define TPPOLL_CQ BIT(5)
717#define TPPOLL_MQ BIT(6)
718#define TPPOLL_HQ BIT(7)
719#define TPPOLL_HCCAQ BIT(8)
720#define TPPOLL_STOPBK BIT(9)
721#define TPPOLL_STOPBE BIT(10)
722#define TPPOLL_STOPVI BIT(11)
723#define TPPOLL_STOPVO BIT(12)
724#define TPPOLL_STOPMGT BIT(13)
725#define TPPOLL_STOPHIGH BIT(14)
726#define TPPOLL_STOPHCCA BIT(15)
727#define TPPOLL_SHIFT 8
728
729#define CCX_CMD_CLM_ENABLE BIT(0)
730#define CCX_CMD_NHM_ENABLE BIT(1)
731#define CCX_CMD_FUNCTION_ENABLE BIT(8)
732#define CCX_CMD_IGNORE_CCA BIT(9)
733#define CCX_CMD_IGNORE_TXON BIT(10)
734#define CCX_CLM_RESULT_READY BIT(16)
735#define CCX_NHM_RESULT_READY BIT(16)
736#define CCX_CMD_RESET 0x0
737
738
739#define HWSET_MAX_SIZE_92S 128
740#define EFUSE_MAX_SECTION 16
741#define EFUSE_REAL_CONTENT_LEN 512
742
743#define RTL8190_EEPROM_ID 0x8129
744#define EEPROM_HPON 0x02
745#define EEPROM_CLK 0x06
746#define EEPROM_TESTR 0x08
747
748#define EEPROM_VID 0x0A
749#define EEPROM_DID 0x0C
750#define EEPROM_SVID 0x0E
751#define EEPROM_SMID 0x10
752
753#define EEPROM_MAC_ADDR 0x12
754#define EEPROM_NODE_ADDRESS_BYTE_0 0x12
755
756#define EEPROM_PWDIFF 0x54
757
758#define EEPROM_TXPOWERBASE 0x50
759#define EEPROM_TX_PWR_INDEX_RANGE 28
760
761#define EEPROM_TX_PWR_HT20_DIFF 0x62
762#define DEFAULT_HT20_TXPWR_DIFF 2
763#define EEPROM_TX_PWR_OFDM_DIFF 0x65
764
765#define EEPROM_TXPWRGROUP 0x67
766#define EEPROM_REGULATORY 0x6D
767
768#define TX_PWR_SAFETY_CHK 0x6D
769#define EEPROM_TXPWINDEX_CCK_24G 0x5D
770#define EEPROM_TXPWINDEX_OFDM_24G 0x6B
771#define EEPROM_HT2T_CH1_A 0x6c
772#define EEPROM_HT2T_CH7_A 0x6d
773#define EEPROM_HT2T_CH13_A 0x6e
774#define EEPROM_HT2T_CH1_B 0x6f
775#define EEPROM_HT2T_CH7_B 0x70
776#define EEPROM_HT2T_CH13_B 0x71
777
778#define EEPROM_TSSI_A 0x74
779#define EEPROM_TSSI_B 0x75
780
781#define EEPROM_RFIND_POWERDIFF 0x76
782#define EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF 0x3
783
784#define EEPROM_THERMALMETER 0x77
785#define EEPROM_BLUETOOTH_COEXIST 0x78
786#define EEPROM_BLUETOOTH_TYPE 0x4f
787
788#define EEPROM_OPTIONAL 0x78
789#define EEPROM_WOWLAN 0x78
790
791#define EEPROM_CRYSTALCAP 0x79
792#define EEPROM_CHANNELPLAN 0x7B
793#define EEPROM_VERSION 0x7C
794#define EEPROM_CUSTOMID 0x7A
795#define EEPROM_BOARDTYPE 0x7E
796
797#define EEPROM_CHANNEL_PLAN_FCC 0x0
798#define EEPROM_CHANNEL_PLAN_IC 0x1
799#define EEPROM_CHANNEL_PLAN_ETSI 0x2
800#define EEPROM_CHANNEL_PLAN_SPAIN 0x3
801#define EEPROM_CHANNEL_PLAN_FRANCE 0x4
802#define EEPROM_CHANNEL_PLAN_MKK 0x5
803#define EEPROM_CHANNEL_PLAN_MKK1 0x6
804#define EEPROM_CHANNEL_PLAN_ISRAEL 0x7
805#define EEPROM_CHANNEL_PLAN_TELEC 0x8
806#define EEPROM_CHANNEL_PLAN_GLOBAL_DOMAIN 0x9
807#define EEPROM_CHANNEL_PLAN_WORLD_WIDE_13 0xA
808#define EEPROM_CHANNEL_PLAN_NCC 0xB
809#define EEPROM_CHANNEL_PLAN_BY_HW_MASK 0x80
810
811#define FW_DIG_DISABLE 0xfd00cc00
812#define FW_DIG_ENABLE 0xfd000000
813#define FW_DIG_HALT 0xfd000001
814#define FW_DIG_RESUME 0xfd000002
815#define FW_HIGH_PWR_DISABLE 0xfd000008
816#define FW_HIGH_PWR_ENABLE 0xfd000009
817#define FW_ADD_A2_ENTRY 0xfd000016
818#define FW_TXPWR_TRACK_ENABLE 0xfd000017
819#define FW_TXPWR_TRACK_DISABLE 0xfd000018
820#define FW_TXPWR_TRACK_THERMAL 0xfd000019
821#define FW_TXANT_SWITCH_ENABLE 0xfd000023
822#define FW_TXANT_SWITCH_DISABLE 0xfd000024
823#define FW_RA_INIT 0xfd000026
824#define FW_CTRL_DM_BY_DRIVER 0Xfd00002a
825#define FW_RA_IOT_BG_COMB 0xfd000030
826#define FW_RA_IOT_N_COMB 0xfd000031
827#define FW_RA_REFRESH 0xfd0000a0
828#define FW_RA_UPDATE_MASK 0xfd0000a2
829#define FW_RA_DISABLE 0xfd0000a4
830#define FW_RA_ACTIVE 0xfd0000a6
831#define FW_RA_DISABLE_RSSI_MASK 0xfd0000ac
832#define FW_RA_ENABLE_RSSI_MASK 0xfd0000ad
833#define FW_RA_RESET 0xfd0000af
834#define FW_DM_DISABLE 0xfd00aa00
835#define FW_IQK_ENABLE 0xf0000020
836#define FW_IQK_SUCCESS 0x0000dddd
837#define FW_IQK_FAIL 0x0000ffff
838#define FW_OP_FAILURE 0xffffffff
839#define FW_TX_FEEDBACK_NONE 0xfb000000
840#define FW_TX_FEEDBACK_DTM_ENABLE (FW_TX_FEEDBACK_NONE | 0x1)
841#define FW_TX_FEEDBACK_CCX_ENABL (FW_TX_FEEDBACK_NONE | 0x2)
842#define FW_BB_RESET_ENABLE 0xff00000d
843#define FW_BB_RESET_DISABLE 0xff00000e
844#define FW_CCA_CHK_ENABLE 0xff000011
845#define FW_CCK_RESET_CNT 0xff000013
846#define FW_LPS_ENTER 0xfe000010
847#define FW_LPS_LEAVE 0xfe000011
848#define FW_INDIRECT_READ 0xf2000000
849#define FW_INDIRECT_WRITE 0xf2000001
850#define FW_CHAN_SET 0xf3000001
851
852#define RFPC 0x5F
853#define RCR_9356SEL BIT(6)
854#define TCR_LRL_OFFSET 0
855#define TCR_SRL_OFFSET 8
856#define TCR_MXDMA_OFFSET 21
857#define TCR_SAT BIT(24)
858#define RCR_MXDMA_OFFSET 8
859#define RCR_FIFO_OFFSET 13
860#define RCR_OnlyErlPkt BIT(31)
861#define CWR 0xDC
862#define RETRYCTR 0xDE
863
864#define CPU_GEN_SYSTEM_RESET 0x00000001
865
866#define CCX_COMMAND_REG 0x890
867#define CLM_PERIOD_REG 0x894
868#define NHM_PERIOD_REG 0x896
869
870#define NHM_THRESHOLD0 0x898
871#define NHM_THRESHOLD1 0x899
872#define NHM_THRESHOLD2 0x89A
873#define NHM_THRESHOLD3 0x89B
874#define NHM_THRESHOLD4 0x89C
875#define NHM_THRESHOLD5 0x89D
876#define NHM_THRESHOLD6 0x89E
877#define CLM_RESULT_REG 0x8D0
878#define NHM_RESULT_REG 0x8D4
879#define NHM_RPI_COUNTER0 0x8D8
880#define NHM_RPI_COUNTER1 0x8D9
881#define NHM_RPI_COUNTER2 0x8DA
882#define NHM_RPI_COUNTER3 0x8DB
883#define NHM_RPI_COUNTER4 0x8DC
884#define NHM_RPI_COUNTER5 0x8DD
885#define NHM_RPI_COUNTER6 0x8DE
886#define NHM_RPI_COUNTER7 0x8DF
887
888#define HAL_8192S_HW_GPIO_OFF_BIT BIT(3)
889#define HAL_8192S_HW_GPIO_OFF_MASK 0xF7
890#define HAL_8192S_HW_GPIO_WPS_BIT BIT(4)
891
892#define RPMAC_RESET 0x100
893#define RPMAC_TXSTART 0x104
894#define RPMAC_TXLEGACYSIG 0x108
895#define RPMAC_TXHTSIG1 0x10c
896#define RPMAC_TXHTSIG2 0x110
897#define RPMAC_PHYDEBUG 0x114
898#define RPMAC_TXPACKETNNM 0x118
899#define RPMAC_TXIDLE 0x11c
900#define RPMAC_TXMACHEADER0 0x120
901#define RPMAC_TXMACHEADER1 0x124
902#define RPMAC_TXMACHEADER2 0x128
903#define RPMAC_TXMACHEADER3 0x12c
904#define RPMAC_TXMACHEADER4 0x130
905#define RPMAC_TXMACHEADER5 0x134
906#define RPMAC_TXDATATYPE 0x138
907#define RPMAC_TXRANDOMSEED 0x13c
908#define RPMAC_CCKPLCPPREAMBLE 0x140
909#define RPMAC_CCKPLCPHEADER 0x144
910#define RPMAC_CCKCRC16 0x148
911#define RPMAC_OFDMRXCRC32OK 0x170
912#define RPMAC_OFDMRXCRC32ER 0x174
913#define RPMAC_OFDMRXPARITYER 0x178
914#define RPMAC_OFDMRXCRC8ER 0x17c
915#define RPMAC_CCKCRXRC16ER 0x180
916#define RPMAC_CCKCRXRC32ER 0x184
917#define RPMAC_CCKCRXRC32OK 0x188
918#define RPMAC_TXSTATUS 0x18c
919
920#define RF_BB_CMD_ADDR 0x02c0
921#define RF_BB_CMD_DATA 0x02c4
922
923#define RFPGA0_RFMOD 0x800
924
925#define RFPGA0_TXINFO 0x804
926#define RFPGA0_PSDFUNCTION 0x808
927
928#define RFPGA0_TXGAINSTAGE 0x80c
929
930#define RFPGA0_RFTIMING1 0x810
931#define RFPGA0_RFTIMING2 0x814
932#define RFPGA0_XA_HSSIPARAMETER1 0x820
933#define RFPGA0_XA_HSSIPARAMETER2 0x824
934#define RFPGA0_XB_HSSIPARAMETER1 0x828
935#define RFPGA0_XB_HSSIPARAMETER2 0x82c
936#define RFPGA0_XC_HSSIPARAMETER1 0x830
937#define RFPGA0_XC_HSSIPARAMETER2 0x834
938#define RFPGA0_XD_HSSIPARAMETER1 0x838
939#define RFPGA0_XD_HSSIPARAMETER2 0x83c
940#define RFPGA0_XA_LSSIPARAMETER 0x840
941#define RFPGA0_XB_LSSIPARAMETER 0x844
942#define RFPGA0_XC_LSSIPARAMETER 0x848
943#define RFPGA0_XD_LSSIPARAMETER 0x84c
944
945#define RFPGA0_RFWAKEUP_PARAMETER 0x850
946#define RFPGA0_RFSLEEPUP_PARAMETER 0x854
947
948#define RFPGA0_XAB_SWITCHCONTROL 0x858
949#define RFPGA0_XCD_SWITCHCONTROL 0x85c
950
951#define RFPGA0_XA_RFINTERFACEOE 0x860
952#define RFPGA0_XB_RFINTERFACEOE 0x864
953#define RFPGA0_XC_RFINTERFACEOE 0x868
954#define RFPGA0_XD_RFINTERFACEOE 0x86c
955
956#define RFPGA0_XAB_RFINTERFACESW 0x870
957#define RFPGA0_XCD_RFINTERFACESW 0x874
958
959#define RFPGA0_XAB_RFPARAMETER 0x878
960#define RFPGA0_XCD_RFPARAMETER 0x87c
961
962#define RFPGA0_ANALOGPARAMETER1 0x880
963#define RFPGA0_ANALOGPARAMETER2 0x884
964#define RFPGA0_ANALOGPARAMETER3 0x888
965#define RFPGA0_ANALOGPARAMETER4 0x88c
966
967#define RFPGA0_XA_LSSIREADBACK 0x8a0
968#define RFPGA0_XB_LSSIREADBACK 0x8a4
969#define RFPGA0_XC_LSSIREADBACK 0x8a8
970#define RFPGA0_XD_LSSIREADBACK 0x8ac
971
972#define RFPGA0_PSDREPORT 0x8b4
973#define TRANSCEIVERA_HSPI_READBACK 0x8b8
974#define TRANSCEIVERB_HSPI_READBACK 0x8bc
975#define RFPGA0_XAB_RFINTERFACERB 0x8e0
976#define RFPGA0_XCD_RFINTERFACERB 0x8e4
977#define RFPGA1_RFMOD 0x900
978
979#define RFPGA1_TXBLOCK 0x904
980#define RFPGA1_DEBUGSELECT 0x908
981#define RFPGA1_TXINFO 0x90c
982
983#define RCCK0_SYSTEM 0xa00
984
985#define RCCK0_AFESETTING 0xa04
986#define RCCK0_CCA 0xa08
987
988#define RCCK0_RXAGC1 0xa0c
989#define RCCK0_RXAGC2 0xa10
990
991#define RCCK0_RXHP 0xa14
992
993#define RCCK0_DSPPARAMETER1 0xa18
994#define RCCK0_DSPPARAMETER2 0xa1c
995
996#define RCCK0_TXFILTER1 0xa20
997#define RCCK0_TXFILTER2 0xa24
998#define RCCK0_DEBUGPORT 0xa28
999#define RCCK0_FALSEALARMREPORT 0xa2c
1000#define RCCK0_TRSSIREPORT 0xa50
1001#define RCCK0_RXREPORT 0xa54
1002#define RCCK0_FACOUNTERLOWER 0xa5c
1003#define RCCK0_FACOUNTERUPPER 0xa58
1004
1005#define ROFDM0_LSTF 0xc00
1006
1007#define ROFDM0_TRXPATHENABLE 0xc04
1008#define ROFDM0_TRMUXPAR 0xc08
1009#define ROFDM0_TRSWISOLATION 0xc0c
1010
1011#define ROFDM0_XARXAFE 0xc10
1012#define ROFDM0_XARXIQIMBALANCE 0xc14
1013#define ROFDM0_XBRXAFE 0xc18
1014#define ROFDM0_XBRXIQIMBALANCE 0xc1c
1015#define ROFDM0_XCRXAFE 0xc20
1016#define ROFDM0_XCRXIQIMBALANCE 0xc24
1017#define ROFDM0_XDRXAFE 0xc28
1018#define ROFDM0_XDRXIQIMBALANCE 0xc2c
1019
1020#define ROFDM0_RXDETECTOR1 0xc30
1021#define ROFDM0_RXDETECTOR2 0xc34
1022#define ROFDM0_RXDETECTOR3 0xc38
1023#define ROFDM0_RXDETECTOR4 0xc3c
1024
1025#define ROFDM0_RXDSP 0xc40
1026#define ROFDM0_CFO_AND_DAGC 0xc44
1027#define ROFDM0_CCADROP_THRESHOLD 0xc48
1028#define ROFDM0_ECCA_THRESHOLD 0xc4c
1029
1030#define ROFDM0_XAAGCCORE1 0xc50
1031#define ROFDM0_XAAGCCORE2 0xc54
1032#define ROFDM0_XBAGCCORE1 0xc58
1033#define ROFDM0_XBAGCCORE2 0xc5c
1034#define ROFDM0_XCAGCCORE1 0xc60
1035#define ROFDM0_XCAGCCORE2 0xc64
1036#define ROFDM0_XDAGCCORE1 0xc68
1037#define ROFDM0_XDAGCCORE2 0xc6c
1038
1039#define ROFDM0_AGCPARAMETER1 0xc70
1040#define ROFDM0_AGCPARAMETER2 0xc74
1041#define ROFDM0_AGCRSSITABLE 0xc78
1042#define ROFDM0_HTSTFAGC 0xc7c
1043
1044#define ROFDM0_XATXIQIMBALANCE 0xc80
1045#define ROFDM0_XATXAFE 0xc84
1046#define ROFDM0_XBTXIQIMBALANCE 0xc88
1047#define ROFDM0_XBTXAFE 0xc8c
1048#define ROFDM0_XCTXIQIMBALANCE 0xc90
1049#define ROFDM0_XCTXAFE 0xc94
1050#define ROFDM0_XDTXIQIMBALANCE 0xc98
1051#define ROFDM0_XDTXAFE 0xc9c
1052
1053#define ROFDM0_RXHP_PARAMETER 0xce0
1054#define ROFDM0_TXPSEUDO_NOISE_WGT 0xce4
1055#define ROFDM0_FRAME_SYNC 0xcf0
1056#define ROFDM0_DFSREPORT 0xcf4
1057#define ROFDM0_TXCOEFF1 0xca4
1058#define ROFDM0_TXCOEFF2 0xca8
1059#define ROFDM0_TXCOEFF3 0xcac
1060#define ROFDM0_TXCOEFF4 0xcb0
1061#define ROFDM0_TXCOEFF5 0xcb4
1062#define ROFDM0_TXCOEFF6 0xcb8
1063
1064
1065#define ROFDM1_LSTF 0xd00
1066#define ROFDM1_TRXPATHENABLE 0xd04
1067
1068#define ROFDM1_CFO 0xd08
1069#define ROFDM1_CSI1 0xd10
1070#define ROFDM1_SBD 0xd14
1071#define ROFDM1_CSI2 0xd18
1072#define ROFDM1_CFOTRACKING 0xd2c
1073#define ROFDM1_TRXMESAURE1 0xd34
1074#define ROFDM1_INTF_DET 0xd3c
1075#define ROFDM1_PSEUDO_NOISESTATEAB 0xd50
1076#define ROFDM1_PSEUDO_NOISESTATECD 0xd54
1077#define ROFDM1_RX_PSEUDO_NOISE_WGT 0xd58
1078
1079#define ROFDM_PHYCOUNTER1 0xda0
1080#define ROFDM_PHYCOUNTER2 0xda4
1081#define ROFDM_PHYCOUNTER3 0xda8
1082
1083#define ROFDM_SHORT_CFOAB 0xdac
1084#define ROFDM_SHORT_CFOCD 0xdb0
1085#define ROFDM_LONG_CFOAB 0xdb4
1086#define ROFDM_LONG_CFOCD 0xdb8
1087#define ROFDM_TAIL_CFOAB 0xdbc
1088#define ROFDM_TAIL_CFOCD 0xdc0
1089#define ROFDM_PW_MEASURE1 0xdc4
1090#define ROFDM_PW_MEASURE2 0xdc8
1091#define ROFDM_BW_REPORT 0xdcc
1092#define ROFDM_AGC_REPORT 0xdd0
1093#define ROFDM_RXSNR 0xdd4
1094#define ROFDM_RXEVMCSI 0xdd8
1095#define ROFDM_SIG_REPORT 0xddc
1096
1097
1098#define RTXAGC_RATE18_06 0xe00
1099#define RTXAGC_RATE54_24 0xe04
1100#define RTXAGC_CCK_MCS32 0xe08
1101#define RTXAGC_MCS03_MCS00 0xe10
1102#define RTXAGC_MCS07_MCS04 0xe14
1103#define RTXAGC_MCS11_MCS08 0xe18
1104#define RTXAGC_MCS15_MCS12 0xe1c
1105
1106
1107#define RF_AC 0x00
1108#define RF_IQADJ_G1 0x01
1109#define RF_IQADJ_G2 0x02
1110#define RF_POW_TRSW 0x05
1111#define RF_GAIN_RX 0x06
1112#define RF_GAIN_TX 0x07
1113#define RF_TXM_IDAC 0x08
1114#define RF_BS_IQGEN 0x0F
1115
1116#define RF_MODE1 0x10
1117#define RF_MODE2 0x11
1118#define RF_RX_AGC_HP 0x12
1119#define RF_TX_AGC 0x13
1120#define RF_BIAS 0x14
1121#define RF_IPA 0x15
1122#define RF_POW_ABILITY 0x17
1123#define RF_MODE_AG 0x18
1124#define RF_CHANNEL 0x18
1125#define RF_CHNLBW 0x18
1126#define RF_TOP 0x19
1127#define RF_RX_G1 0x1A
1128#define RF_RX_G2 0x1B
1129#define RF_RX_BB2 0x1C
1130#define RF_RX_BB1 0x1D
1131#define RF_RCK1 0x1E
1132#define RF_RCK2 0x1F
1133
1134#define RF_TX_G1 0x20
1135#define RF_TX_G2 0x21
1136#define RF_TX_G3 0x22
1137#define RF_TX_BB1 0x23
1138#define RF_T_METER 0x24
1139#define RF_SYN_G1 0x25
1140#define RF_SYN_G2 0x26
1141#define RF_SYN_G3 0x27
1142#define RF_SYN_G4 0x28
1143#define RF_SYN_G5 0x29
1144#define RF_SYN_G6 0x2A
1145#define RF_SYN_G7 0x2B
1146#define RF_SYN_G8 0x2C
1147
1148#define RF_RCK_OS 0x30
1149#define RF_TXPA_G1 0x31
1150#define RF_TXPA_G2 0x32
1151#define RF_TXPA_G3 0x33
1152
1153#define BRFMOD 0x1
1154#define BCCKEN 0x1000000
1155#define BOFDMEN 0x2000000
1156
1157#define BXBTXAGC 0xf00
1158#define BXCTXAGC 0xf000
1159#define BXDTXAGC 0xf0000
1160
1161#define B3WIRE_DATALENGTH 0x800
1162#define B3WIRE_ADDRESSLENGTH 0x400
1163
1164#define BRFSI_RFENV 0x10
1165
1166#define BLSSI_READADDRESS 0x7f800000
1167#define BLSSI_READEDGE 0x80000000
1168#define BLSSI_READBACK_DATA 0xfffff
1169
1170#define BADCLKPHASE 0x4000000
1171
1172#define BCCK_SIDEBAND 0x10
1173
1174#define BTX_AGCRATECCK 0x7f00
1175
1176#define MASKBYTE0 0xff
1177#define MASKBYTE1 0xff00
1178#define MASKBYTE2 0xff0000
1179#define MASKBYTE3 0xff000000
1180#define MASKHWORD 0xffff0000
1181#define MASKLWORD 0x0000ffff
1182#define MASKDWORD 0xffffffff
1183
1184#define MAKS12BITS 0xfffff
1185#define MASK20BITS 0xfffff
1186#define RFREG_OFFSET_MASK 0xfffff
1187
1188#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/rf.c b/drivers/net/wireless/rtlwifi/rtl8192se/rf.c
new file mode 100644
index 000000000000..1d3a48330399
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/rf.c
@@ -0,0 +1,546 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2010 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#include "../wifi.h"
31#include "reg.h"
32#include "def.h"
33#include "phy.h"
34#include "rf.h"
35#include "dm.h"
36
37
38static void _rtl92s_get_powerbase(struct ieee80211_hw *hw, u8 *p_pwrlevel,
39 u8 chnl, u32 *ofdmbase, u32 *mcsbase,
40 u8 *p_final_pwridx)
41{
42 struct rtl_priv *rtlpriv = rtl_priv(hw);
43 struct rtl_phy *rtlphy = &(rtlpriv->phy);
44 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
45 u32 pwrbase0, pwrbase1;
46 u8 legacy_pwrdiff = 0, ht20_pwrdiff = 0;
47 u8 i, pwrlevel[4];
48
49 for (i = 0; i < 2; i++)
50 pwrlevel[i] = p_pwrlevel[i];
51
52 /* We only care about the path A for legacy. */
53 if (rtlefuse->eeprom_version < 2) {
54 pwrbase0 = pwrlevel[0] + (rtlefuse->legacy_httxpowerdiff & 0xf);
55 } else if (rtlefuse->eeprom_version >= 2) {
56 legacy_pwrdiff = rtlefuse->txpwr_legacyhtdiff
57 [RF90_PATH_A][chnl - 1];
58
59 /* For legacy OFDM, tx pwr always > HT OFDM pwr.
60 * We do not care Path B
61 * legacy OFDM pwr diff. NO BB register
62 * to notify HW. */
63 pwrbase0 = pwrlevel[0] + legacy_pwrdiff;
64 }
65
66 pwrbase0 = (pwrbase0 << 24) | (pwrbase0 << 16) | (pwrbase0 << 8) |
67 pwrbase0;
68 *ofdmbase = pwrbase0;
69
70 /* MCS rates */
71 if (rtlefuse->eeprom_version >= 2) {
72 /* Check HT20 to HT40 diff */
73 if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20) {
74 for (i = 0; i < 2; i++) {
75 /* rf-A, rf-B */
76 /* HT 20<->40 pwr diff */
77 ht20_pwrdiff = rtlefuse->txpwr_ht20diff
78 [i][chnl - 1];
79
80 if (ht20_pwrdiff < 8) /* 0~+7 */
81 pwrlevel[i] += ht20_pwrdiff;
82 else /* index8-15=-8~-1 */
83 pwrlevel[i] -= (16 - ht20_pwrdiff);
84 }
85 }
86 }
87
88 /* use index of rf-A */
89 pwrbase1 = pwrlevel[0];
90 pwrbase1 = (pwrbase1 << 24) | (pwrbase1 << 16) | (pwrbase1 << 8) |
91 pwrbase1;
92 *mcsbase = pwrbase1;
93
94 /* The following is for Antenna
95 * diff from Ant-B to Ant-A */
96 p_final_pwridx[0] = pwrlevel[0];
97 p_final_pwridx[1] = pwrlevel[1];
98
99 switch (rtlefuse->eeprom_regulatory) {
100 case 3:
101 /* The following is for calculation
102 * of the power diff for Ant-B to Ant-A. */
103 if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
104 p_final_pwridx[0] += rtlefuse->pwrgroup_ht40
105 [RF90_PATH_A][
106 chnl - 1];
107 p_final_pwridx[1] += rtlefuse->pwrgroup_ht40
108 [RF90_PATH_B][
109 chnl - 1];
110 } else {
111 p_final_pwridx[0] += rtlefuse->pwrgroup_ht20
112 [RF90_PATH_A][
113 chnl - 1];
114 p_final_pwridx[1] += rtlefuse->pwrgroup_ht20
115 [RF90_PATH_B][
116 chnl - 1];
117 }
118 break;
119 default:
120 break;
121 }
122
123 if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
124 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("40MHz finalpwr_idx "
125 "(A / B) = 0x%x / 0x%x\n", p_final_pwridx[0],
126 p_final_pwridx[1]));
127 } else {
128 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("20MHz finalpwr_idx "
129 "(A / B) = 0x%x / 0x%x\n", p_final_pwridx[0],
130 p_final_pwridx[1]));
131 }
132}
133
134static void _rtl92s_set_antennadiff(struct ieee80211_hw *hw,
135 u8 *p_final_pwridx)
136{
137 struct rtl_priv *rtlpriv = rtl_priv(hw);
138 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
139 struct rtl_phy *rtlphy = &(rtlpriv->phy);
140 char ant_pwr_diff = 0;
141 u32 u4reg_val = 0;
142
143 if (rtlphy->rf_type == RF_2T2R) {
144 ant_pwr_diff = p_final_pwridx[1] - p_final_pwridx[0];
145
146 /* range is from 7~-8,
147 * index = 0x0~0xf */
148 if (ant_pwr_diff > 7)
149 ant_pwr_diff = 7;
150 if (ant_pwr_diff < -8)
151 ant_pwr_diff = -8;
152
153 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
154 ("Antenna Diff from RF-B "
155 "to RF-A = %d (0x%x)\n", ant_pwr_diff,
156 ant_pwr_diff & 0xf));
157
158 ant_pwr_diff &= 0xf;
159 }
160
161 /* Antenna TX power difference */
162 rtlefuse->antenna_txpwdiff[2] = 0;/* RF-D, don't care */
163 rtlefuse->antenna_txpwdiff[1] = 0;/* RF-C, don't care */
164 rtlefuse->antenna_txpwdiff[0] = (u8)(ant_pwr_diff); /* RF-B */
165
166 u4reg_val = rtlefuse->antenna_txpwdiff[2] << 8 |
167 rtlefuse->antenna_txpwdiff[1] << 4 |
168 rtlefuse->antenna_txpwdiff[0];
169
170 rtl_set_bbreg(hw, RFPGA0_TXGAINSTAGE, (BXBTXAGC | BXCTXAGC | BXDTXAGC),
171 u4reg_val);
172
173 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
174 ("Write BCD-Diff(0x%x) = 0x%x\n",
175 RFPGA0_TXGAINSTAGE, u4reg_val));
176}
177
178static void _rtl92s_get_txpower_writeval_byregulatory(struct ieee80211_hw *hw,
179 u8 chnl, u8 index,
180 u32 pwrbase0,
181 u32 pwrbase1,
182 u32 *p_outwrite_val)
183{
184 struct rtl_priv *rtlpriv = rtl_priv(hw);
185 struct rtl_phy *rtlphy = &(rtlpriv->phy);
186 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
187 u8 i, chnlgroup, pwrdiff_limit[4];
188 u32 writeval, customer_limit;
189
190 /* Index 0 & 1= legacy OFDM, 2-5=HT_MCS rate */
191 switch (rtlefuse->eeprom_regulatory) {
192 case 0:
193 /* Realtek better performance increase power diff
194 * defined by Realtek for large power */
195 chnlgroup = 0;
196
197 writeval = rtlphy->mcs_txpwrlevel_origoffset
198 [chnlgroup][index] +
199 ((index < 2) ? pwrbase0 : pwrbase1);
200
201 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
202 ("RTK better performance, "
203 "writeval = 0x%x\n", writeval));
204 break;
205 case 1:
206 /* Realtek regulatory increase power diff defined
207 * by Realtek for regulatory */
208 if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
209 writeval = ((index < 2) ? pwrbase0 : pwrbase1);
210
211 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
212 ("Realtek regulatory, "
213 "40MHz, writeval = 0x%x\n", writeval));
214 } else {
215 if (rtlphy->pwrgroup_cnt == 1)
216 chnlgroup = 0;
217
218 if (rtlphy->pwrgroup_cnt >= 3) {
219 if (chnl <= 3)
220 chnlgroup = 0;
221 else if (chnl >= 4 && chnl <= 8)
222 chnlgroup = 1;
223 else if (chnl > 8)
224 chnlgroup = 2;
225 if (rtlphy->pwrgroup_cnt == 4)
226 chnlgroup++;
227 }
228
229 writeval = rtlphy->mcs_txpwrlevel_origoffset
230 [chnlgroup][index]
231 + ((index < 2) ?
232 pwrbase0 : pwrbase1);
233
234 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
235 ("Realtek regulatory, "
236 "20MHz, writeval = 0x%x\n", writeval));
237 }
238 break;
239 case 2:
240 /* Better regulatory don't increase any power diff */
241 writeval = ((index < 2) ? pwrbase0 : pwrbase1);
242 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
243 ("Better regulatory, "
244 "writeval = 0x%x\n", writeval));
245 break;
246 case 3:
247 /* Customer defined power diff. increase power diff
248 defined by customer. */
249 chnlgroup = 0;
250
251 if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
252 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
253 ("customer's limit, 40MHz = 0x%x\n",
254 rtlefuse->pwrgroup_ht40
255 [RF90_PATH_A][chnl - 1]));
256 } else {
257 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
258 ("customer's limit, 20MHz = 0x%x\n",
259 rtlefuse->pwrgroup_ht20
260 [RF90_PATH_A][chnl - 1]));
261 }
262
263 for (i = 0; i < 4; i++) {
264 pwrdiff_limit[i] =
265 (u8)((rtlphy->mcs_txpwrlevel_origoffset
266 [chnlgroup][index] & (0x7f << (i * 8)))
267 >> (i * 8));
268
269 if (rtlphy->current_chan_bw ==
270 HT_CHANNEL_WIDTH_20_40) {
271 if (pwrdiff_limit[i] >
272 rtlefuse->pwrgroup_ht40
273 [RF90_PATH_A][chnl - 1]) {
274 pwrdiff_limit[i] =
275 rtlefuse->pwrgroup_ht20
276 [RF90_PATH_A][chnl - 1];
277 }
278 } else {
279 if (pwrdiff_limit[i] >
280 rtlefuse->pwrgroup_ht20
281 [RF90_PATH_A][chnl - 1]) {
282 pwrdiff_limit[i] =
283 rtlefuse->pwrgroup_ht20
284 [RF90_PATH_A][chnl - 1];
285 }
286 }
287 }
288
289 customer_limit = (pwrdiff_limit[3] << 24) |
290 (pwrdiff_limit[2] << 16) |
291 (pwrdiff_limit[1] << 8) |
292 (pwrdiff_limit[0]);
293 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
294 ("Customer's limit = 0x%x\n",
295 customer_limit));
296
297 writeval = customer_limit + ((index < 2) ?
298 pwrbase0 : pwrbase1);
299 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
300 ("Customer, writeval = "
301 "0x%x\n", writeval));
302 break;
303 default:
304 chnlgroup = 0;
305 writeval = rtlphy->mcs_txpwrlevel_origoffset[chnlgroup][index] +
306 ((index < 2) ? pwrbase0 : pwrbase1);
307 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
308 ("RTK better performance, "
309 "writeval = 0x%x\n", writeval));
310 break;
311 }
312
313 if (rtlpriv->dm.dynamic_txhighpower_lvl == TX_HIGH_PWR_LEVEL_LEVEL1)
314 writeval = 0x10101010;
315 else if (rtlpriv->dm.dynamic_txhighpower_lvl ==
316 TX_HIGH_PWR_LEVEL_LEVEL2)
317 writeval = 0x0;
318
319 *p_outwrite_val = writeval;
320
321}
322
323static void _rtl92s_write_ofdm_powerreg(struct ieee80211_hw *hw,
324 u8 index, u32 val)
325{
326 struct rtl_priv *rtlpriv = rtl_priv(hw);
327 struct rtl_phy *rtlphy = &(rtlpriv->phy);
328 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
329 u16 regoffset[6] = {0xe00, 0xe04, 0xe10, 0xe14, 0xe18, 0xe1c};
330 u8 i, rfa_pwr[4];
331 u8 rfa_lower_bound = 0, rfa_upper_bound = 0, rf_pwr_diff = 0;
332 u32 writeval = val;
333
334 /* If path A and Path B coexist, we must limit Path A tx power.
335 * Protect Path B pwr over or under flow. We need to calculate
336 * upper and lower bound of path A tx power. */
337 if (rtlphy->rf_type == RF_2T2R) {
338 rf_pwr_diff = rtlefuse->antenna_txpwdiff[0];
339
340 /* Diff=-8~-1 */
341 if (rf_pwr_diff >= 8) {
342 /* Prevent underflow!! */
343 rfa_lower_bound = 0x10 - rf_pwr_diff;
344 /* if (rf_pwr_diff >= 0) Diff = 0-7 */
345 } else {
346 rfa_upper_bound = RF6052_MAX_TX_PWR - rf_pwr_diff;
347 }
348 }
349
350 for (i = 0; i < 4; i++) {
351 rfa_pwr[i] = (u8)((writeval & (0x7f << (i * 8))) >> (i * 8));
352 if (rfa_pwr[i] > RF6052_MAX_TX_PWR)
353 rfa_pwr[i] = RF6052_MAX_TX_PWR;
354
355 /* If path A and Path B coexist, we must limit Path A tx power.
356 * Protect Path B pwr over or under flow. We need to calculate
357 * upper and lower bound of path A tx power. */
358 if (rtlphy->rf_type == RF_2T2R) {
359 /* Diff=-8~-1 */
360 if (rf_pwr_diff >= 8) {
361 /* Prevent underflow!! */
362 if (rfa_pwr[i] < rfa_lower_bound)
363 rfa_pwr[i] = rfa_lower_bound;
364 /* Diff = 0-7 */
365 } else if (rf_pwr_diff >= 1) {
366 /* Prevent overflow */
367 if (rfa_pwr[i] > rfa_upper_bound)
368 rfa_pwr[i] = rfa_upper_bound;
369 }
370 }
371
372 }
373
374 writeval = (rfa_pwr[3] << 24) | (rfa_pwr[2] << 16) | (rfa_pwr[1] << 8) |
375 rfa_pwr[0];
376
377 rtl_set_bbreg(hw, regoffset[index], 0x7f7f7f7f, writeval);
378}
379
380void rtl92s_phy_rf6052_set_ofdmtxpower(struct ieee80211_hw *hw,
381 u8 *p_pwrlevel, u8 chnl)
382{
383 u32 writeval, pwrbase0, pwrbase1;
384 u8 index = 0;
385 u8 finalpwr_idx[4];
386
387 _rtl92s_get_powerbase(hw, p_pwrlevel, chnl, &pwrbase0, &pwrbase1,
388 &finalpwr_idx[0]);
389 _rtl92s_set_antennadiff(hw, &finalpwr_idx[0]);
390
391 for (index = 0; index < 6; index++) {
392 _rtl92s_get_txpower_writeval_byregulatory(hw, chnl, index,
393 pwrbase0, pwrbase1, &writeval);
394
395 _rtl92s_write_ofdm_powerreg(hw, index, writeval);
396 }
397}
398
399void rtl92s_phy_rf6052_set_ccktxpower(struct ieee80211_hw *hw, u8 pwrlevel)
400{
401 struct rtl_priv *rtlpriv = rtl_priv(hw);
402 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
403 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
404 u32 txagc = 0;
405 bool dont_inc_cck_or_turboscanoff = false;
406
407 if (((rtlefuse->eeprom_version >= 2) &&
408 (rtlefuse->txpwr_safetyflag == 1)) ||
409 ((rtlefuse->eeprom_version >= 2) &&
410 (rtlefuse->eeprom_regulatory != 0)))
411 dont_inc_cck_or_turboscanoff = true;
412
413 if (mac->act_scanning == true) {
414 txagc = 0x3f;
415 if (dont_inc_cck_or_turboscanoff)
416 txagc = pwrlevel;
417 } else {
418 txagc = pwrlevel;
419
420 if (rtlpriv->dm.dynamic_txhighpower_lvl ==
421 TX_HIGH_PWR_LEVEL_LEVEL1)
422 txagc = 0x10;
423 else if (rtlpriv->dm.dynamic_txhighpower_lvl ==
424 TX_HIGH_PWR_LEVEL_LEVEL2)
425 txagc = 0x0;
426 }
427
428 if (txagc > RF6052_MAX_TX_PWR)
429 txagc = RF6052_MAX_TX_PWR;
430
431 rtl_set_bbreg(hw, RTXAGC_CCK_MCS32, BTX_AGCRATECCK, txagc);
432
433}
434
435bool rtl92s_phy_rf6052_config(struct ieee80211_hw *hw)
436{
437 struct rtl_priv *rtlpriv = rtl_priv(hw);
438 struct rtl_phy *rtlphy = &(rtlpriv->phy);
439 u32 u4reg_val = 0;
440 u8 rfpath;
441 bool rtstatus = true;
442 struct bb_reg_def *pphyreg;
443
444 /* Initialize RF */
445 for (rfpath = 0; rfpath < rtlphy->num_total_rfpath; rfpath++) {
446
447 pphyreg = &rtlphy->phyreg_def[rfpath];
448
449 /* Store original RFENV control type */
450 switch (rfpath) {
451 case RF90_PATH_A:
452 case RF90_PATH_C:
453 u4reg_val = rtl92s_phy_query_bb_reg(hw,
454 pphyreg->rfintfs,
455 BRFSI_RFENV);
456 break;
457 case RF90_PATH_B:
458 case RF90_PATH_D:
459 u4reg_val = rtl92s_phy_query_bb_reg(hw,
460 pphyreg->rfintfs,
461 BRFSI_RFENV << 16);
462 break;
463 }
464
465 /* Set RF_ENV enable */
466 rtl92s_phy_set_bb_reg(hw, pphyreg->rfintfe,
467 BRFSI_RFENV << 16, 0x1);
468
469 /* Set RF_ENV output high */
470 rtl92s_phy_set_bb_reg(hw, pphyreg->rfintfo, BRFSI_RFENV, 0x1);
471
472 /* Set bit number of Address and Data for RF register */
473 rtl92s_phy_set_bb_reg(hw, pphyreg->rfhssi_para2,
474 B3WIRE_ADDRESSLENGTH, 0x0);
475 rtl92s_phy_set_bb_reg(hw, pphyreg->rfhssi_para2,
476 B3WIRE_DATALENGTH, 0x0);
477
478 /* Initialize RF fom connfiguration file */
479 switch (rfpath) {
480 case RF90_PATH_A:
481 rtstatus = rtl92s_phy_config_rf(hw,
482 (enum radio_path)rfpath);
483 break;
484 case RF90_PATH_B:
485 rtstatus = rtl92s_phy_config_rf(hw,
486 (enum radio_path)rfpath);
487 break;
488 case RF90_PATH_C:
489 break;
490 case RF90_PATH_D:
491 break;
492 }
493
494 /* Restore RFENV control type */
495 switch (rfpath) {
496 case RF90_PATH_A:
497 case RF90_PATH_C:
498 rtl92s_phy_set_bb_reg(hw, pphyreg->rfintfs, BRFSI_RFENV,
499 u4reg_val);
500 break;
501 case RF90_PATH_B:
502 case RF90_PATH_D:
503 rtl92s_phy_set_bb_reg(hw, pphyreg->rfintfs,
504 BRFSI_RFENV << 16,
505 u4reg_val);
506 break;
507 }
508
509 if (rtstatus != true) {
510 printk(KERN_ERR "Radio[%d] Fail!!", rfpath);
511 goto fail;
512 }
513
514 }
515
516 return rtstatus;
517
518fail:
519 return rtstatus;
520}
521
522void rtl92s_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth)
523{
524 struct rtl_priv *rtlpriv = rtl_priv(hw);
525 struct rtl_phy *rtlphy = &(rtlpriv->phy);
526
527 switch (bandwidth) {
528 case HT_CHANNEL_WIDTH_20:
529 rtlphy->rfreg_chnlval[0] = ((rtlphy->rfreg_chnlval[0] &
530 0xfffff3ff) | 0x0400);
531 rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK,
532 rtlphy->rfreg_chnlval[0]);
533 break;
534 case HT_CHANNEL_WIDTH_20_40:
535 rtlphy->rfreg_chnlval[0] = ((rtlphy->rfreg_chnlval[0] &
536 0xfffff3ff));
537 rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK,
538 rtlphy->rfreg_chnlval[0]);
539 break;
540 default:
541 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
542 ("unknown bandwidth: %#X\n",
543 bandwidth));
544 break;
545 }
546}
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/rf.h b/drivers/net/wireless/rtlwifi/rtl8192se/rf.h
new file mode 100644
index 000000000000..3843baa1a874
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/rf.h
@@ -0,0 +1,43 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2010 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29#ifndef __INC_RTL92S_RF_H
30#define __INC_RTL92S_RF_H
31
32#define RF6052_MAX_TX_PWR 0x3F
33
34void rtl92s_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw,
35 u8 bandwidth);
36bool rtl92s_phy_rf6052_config(struct ieee80211_hw *hw) ;
37void rtl92s_phy_rf6052_set_ccktxpower(struct ieee80211_hw *hw,
38 u8 powerlevel);
39void rtl92s_phy_rf6052_set_ofdmtxpower(struct ieee80211_hw *hw,
40 u8 *p_pwrlevel, u8 chnl);
41
42#endif
43
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/sw.c b/drivers/net/wireless/rtlwifi/rtl8192se/sw.c
new file mode 100644
index 000000000000..1c6cb1d7d660
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/sw.c
@@ -0,0 +1,423 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2010 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#include <linux/vmalloc.h>
31
32#include "../wifi.h"
33#include "../core.h"
34#include "../pci.h"
35#include "reg.h"
36#include "def.h"
37#include "phy.h"
38#include "dm.h"
39#include "fw.h"
40#include "hw.h"
41#include "sw.h"
42#include "trx.h"
43#include "led.h"
44
45static void rtl92s_init_aspm_vars(struct ieee80211_hw *hw)
46{
47 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
48
49 /*close ASPM for AMD defaultly */
50 rtlpci->const_amdpci_aspm = 0;
51
52 /*
53 * ASPM PS mode.
54 * 0 - Disable ASPM,
55 * 1 - Enable ASPM without Clock Req,
56 * 2 - Enable ASPM with Clock Req,
57 * 3 - Alwyas Enable ASPM with Clock Req,
58 * 4 - Always Enable ASPM without Clock Req.
59 * set defult to RTL8192CE:3 RTL8192E:2
60 * */
61 rtlpci->const_pci_aspm = 2;
62
63 /*Setting for PCI-E device */
64 rtlpci->const_devicepci_aspm_setting = 0x03;
65
66 /*Setting for PCI-E bridge */
67 rtlpci->const_hostpci_aspm_setting = 0x02;
68
69 /*
70 * In Hw/Sw Radio Off situation.
71 * 0 - Default,
72 * 1 - From ASPM setting without low Mac Pwr,
73 * 2 - From ASPM setting with low Mac Pwr,
74 * 3 - Bus D3
75 * set default to RTL8192CE:0 RTL8192SE:2
76 */
77 rtlpci->const_hwsw_rfoff_d3 = 2;
78
79 /*
80 * This setting works for those device with
81 * backdoor ASPM setting such as EPHY setting.
82 * 0 - Not support ASPM,
83 * 1 - Support ASPM,
84 * 2 - According to chipset.
85 */
86 rtlpci->const_support_pciaspm = 2;
87}
88
89static int rtl92s_init_sw_vars(struct ieee80211_hw *hw)
90{
91 struct rtl_priv *rtlpriv = rtl_priv(hw);
92 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
93 const struct firmware *firmware;
94 struct rt_firmware *pfirmware = NULL;
95 int err = 0;
96 u16 earlyrxthreshold = 7;
97
98 rtlpriv->dm.dm_initialgain_enable = 1;
99 rtlpriv->dm.dm_flag = 0;
100 rtlpriv->dm.disable_framebursting = 0;
101 rtlpriv->dm.thermalvalue = 0;
102 rtlpriv->dm.useramask = true;
103
104 /* compatible 5G band 91se just 2.4G band & smsp */
105 rtlpriv->rtlhal.current_bandtype = BAND_ON_2_4G;
106 rtlpriv->rtlhal.bandset = BAND_ON_2_4G;
107 rtlpriv->rtlhal.macphymode = SINGLEMAC_SINGLEPHY;
108
109 rtlpci->transmit_config = 0;
110
111 rtlpci->receive_config =
112 RCR_APPFCS |
113 RCR_APWRMGT |
114 /*RCR_ADD3 |*/
115 RCR_AMF |
116 RCR_ADF |
117 RCR_APP_MIC |
118 RCR_APP_ICV |
119 RCR_AICV |
120 /* Accept ICV error, CRC32 Error */
121 RCR_ACRC32 |
122 RCR_AB |
123 /* Accept Broadcast, Multicast */
124 RCR_AM |
125 /* Accept Physical match */
126 RCR_APM |
127 /* Accept Destination Address packets */
128 /*RCR_AAP |*/
129 RCR_APP_PHYST_STAFF |
130 /* Accept PHY status */
131 RCR_APP_PHYST_RXFF |
132 (earlyrxthreshold << RCR_FIFO_OFFSET);
133
134 rtlpci->irq_mask[0] = (u32)
135 (IMR_ROK |
136 IMR_VODOK |
137 IMR_VIDOK |
138 IMR_BEDOK |
139 IMR_BKDOK |
140 IMR_HCCADOK |
141 IMR_MGNTDOK |
142 IMR_COMDOK |
143 IMR_HIGHDOK |
144 IMR_BDOK |
145 IMR_RXCMDOK |
146 /*IMR_TIMEOUT0 |*/
147 IMR_RDU |
148 IMR_RXFOVW |
149 IMR_BCNINT
150 /*| IMR_TXFOVW*/
151 /*| IMR_TBDOK |
152 IMR_TBDER*/);
153
154 rtlpci->irq_mask[1] = (u32) 0;
155
156 rtlpci->shortretry_limit = 0x30;
157 rtlpci->longretry_limit = 0x30;
158
159 rtlpci->first_init = true;
160
161 /* for LPS & IPS */
162 rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps;
163 rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps;
164 rtlpriv->psc.fwctrl_lps = rtlpriv->cfg->mod_params->fwctrl_lps;
165 rtlpriv->psc.reg_fwctrl_lps = 3;
166 rtlpriv->psc.reg_max_lps_awakeintvl = 5;
167 /* for ASPM, you can close aspm through
168 * set const_support_pciaspm = 0 */
169 rtl92s_init_aspm_vars(hw);
170
171 if (rtlpriv->psc.reg_fwctrl_lps == 1)
172 rtlpriv->psc.fwctrl_psmode = FW_PS_MIN_MODE;
173 else if (rtlpriv->psc.reg_fwctrl_lps == 2)
174 rtlpriv->psc.fwctrl_psmode = FW_PS_MAX_MODE;
175 else if (rtlpriv->psc.reg_fwctrl_lps == 3)
176 rtlpriv->psc.fwctrl_psmode = FW_PS_DTIM_MODE;
177
178 /* for firmware buf */
179 rtlpriv->rtlhal.pfirmware = vzalloc(sizeof(struct rt_firmware));
180 if (!rtlpriv->rtlhal.pfirmware) {
181 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
182 ("Can't alloc buffer for fw.\n"));
183 return 1;
184 }
185
186 printk(KERN_INFO "rtl8192se: Driver for Realtek RTL8192SE/RTL8191SE\n"
187 " Loading firmware %s\n", rtlpriv->cfg->fw_name);
188 /* request fw */
189 err = request_firmware(&firmware, rtlpriv->cfg->fw_name,
190 rtlpriv->io.dev);
191 if (err) {
192 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
193 ("Failed to request firmware!\n"));
194 return 1;
195 }
196 if (firmware->size > sizeof(struct rt_firmware)) {
197 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
198 ("Firmware is too big!\n"));
199 release_firmware(firmware);
200 return 1;
201 }
202
203 pfirmware = (struct rt_firmware *)rtlpriv->rtlhal.pfirmware;
204 memcpy(pfirmware->sz_fw_tmpbuffer, firmware->data, firmware->size);
205 pfirmware->sz_fw_tmpbufferlen = firmware->size;
206 release_firmware(firmware);
207
208 return err;
209}
210
211static void rtl92s_deinit_sw_vars(struct ieee80211_hw *hw)
212{
213 struct rtl_priv *rtlpriv = rtl_priv(hw);
214
215 if (rtlpriv->rtlhal.pfirmware) {
216 vfree(rtlpriv->rtlhal.pfirmware);
217 rtlpriv->rtlhal.pfirmware = NULL;
218 }
219}
220
221static struct rtl_hal_ops rtl8192se_hal_ops = {
222 .init_sw_vars = rtl92s_init_sw_vars,
223 .deinit_sw_vars = rtl92s_deinit_sw_vars,
224 .read_eeprom_info = rtl92se_read_eeprom_info,
225 .interrupt_recognized = rtl92se_interrupt_recognized,
226 .hw_init = rtl92se_hw_init,
227 .hw_disable = rtl92se_card_disable,
228 .hw_suspend = rtl92se_suspend,
229 .hw_resume = rtl92se_resume,
230 .enable_interrupt = rtl92se_enable_interrupt,
231 .disable_interrupt = rtl92se_disable_interrupt,
232 .set_network_type = rtl92se_set_network_type,
233 .set_chk_bssid = rtl92se_set_check_bssid,
234 .set_qos = rtl92se_set_qos,
235 .set_bcn_reg = rtl92se_set_beacon_related_registers,
236 .set_bcn_intv = rtl92se_set_beacon_interval,
237 .update_interrupt_mask = rtl92se_update_interrupt_mask,
238 .get_hw_reg = rtl92se_get_hw_reg,
239 .set_hw_reg = rtl92se_set_hw_reg,
240 .update_rate_tbl = rtl92se_update_hal_rate_tbl,
241 .fill_tx_desc = rtl92se_tx_fill_desc,
242 .fill_tx_cmddesc = rtl92se_tx_fill_cmddesc,
243 .query_rx_desc = rtl92se_rx_query_desc,
244 .set_channel_access = rtl92se_update_channel_access_setting,
245 .radio_onoff_checking = rtl92se_gpio_radio_on_off_checking,
246 .set_bw_mode = rtl92s_phy_set_bw_mode,
247 .switch_channel = rtl92s_phy_sw_chnl,
248 .dm_watchdog = rtl92s_dm_watchdog,
249 .scan_operation_backup = rtl92s_phy_scan_operation_backup,
250 .set_rf_power_state = rtl92s_phy_set_rf_power_state,
251 .led_control = rtl92se_led_control,
252 .set_desc = rtl92se_set_desc,
253 .get_desc = rtl92se_get_desc,
254 .tx_polling = rtl92se_tx_polling,
255 .enable_hw_sec = rtl92se_enable_hw_security_config,
256 .set_key = rtl92se_set_key,
257 .init_sw_leds = rtl92se_init_sw_leds,
258 .get_bbreg = rtl92s_phy_query_bb_reg,
259 .set_bbreg = rtl92s_phy_set_bb_reg,
260 .get_rfreg = rtl92s_phy_query_rf_reg,
261 .set_rfreg = rtl92s_phy_set_rf_reg,
262};
263
264static struct rtl_mod_params rtl92se_mod_params = {
265 .sw_crypto = false,
266 .inactiveps = true,
267 .swctrl_lps = true,
268 .fwctrl_lps = false,
269};
270
271/* Because memory R/W bursting will cause system hang/crash
272 * for 92se, so we don't read back after every write action */
273static struct rtl_hal_cfg rtl92se_hal_cfg = {
274 .bar_id = 1,
275 .write_readback = false,
276 .name = "rtl92s_pci",
277 .fw_name = "rtlwifi/rtl8192sefw.bin",
278 .ops = &rtl8192se_hal_ops,
279 .mod_params = &rtl92se_mod_params,
280
281 .maps[SYS_ISO_CTRL] = REG_SYS_ISO_CTRL,
282 .maps[SYS_FUNC_EN] = REG_SYS_FUNC_EN,
283 .maps[SYS_CLK] = SYS_CLKR,
284 .maps[MAC_RCR_AM] = RCR_AM,
285 .maps[MAC_RCR_AB] = RCR_AB,
286 .maps[MAC_RCR_ACRC32] = RCR_ACRC32,
287 .maps[MAC_RCR_ACF] = RCR_ACF,
288 .maps[MAC_RCR_AAP] = RCR_AAP,
289
290 .maps[EFUSE_TEST] = REG_EFUSE_TEST,
291 .maps[EFUSE_CTRL] = REG_EFUSE_CTRL,
292 .maps[EFUSE_CLK] = REG_EFUSE_CLK,
293 .maps[EFUSE_CLK_CTRL] = REG_EFUSE_CTRL,
294 .maps[EFUSE_PWC_EV12V] = 0, /* nouse for 8192se */
295 .maps[EFUSE_FEN_ELDR] = 0, /* nouse for 8192se */
296 .maps[EFUSE_LOADER_CLK_EN] = 0,/* nouse for 8192se */
297 .maps[EFUSE_ANA8M] = EFUSE_ANA8M,
298 .maps[EFUSE_HWSET_MAX_SIZE] = HWSET_MAX_SIZE_92S,
299 .maps[EFUSE_MAX_SECTION_MAP] = EFUSE_MAX_SECTION,
300 .maps[EFUSE_REAL_CONTENT_SIZE] = EFUSE_REAL_CONTENT_LEN,
301
302 .maps[RWCAM] = REG_RWCAM,
303 .maps[WCAMI] = REG_WCAMI,
304 .maps[RCAMO] = REG_RCAMO,
305 .maps[CAMDBG] = REG_CAMDBG,
306 .maps[SECR] = REG_SECR,
307 .maps[SEC_CAM_NONE] = CAM_NONE,
308 .maps[SEC_CAM_WEP40] = CAM_WEP40,
309 .maps[SEC_CAM_TKIP] = CAM_TKIP,
310 .maps[SEC_CAM_AES] = CAM_AES,
311 .maps[SEC_CAM_WEP104] = CAM_WEP104,
312
313 .maps[RTL_IMR_BCNDMAINT6] = IMR_BCNDMAINT6,
314 .maps[RTL_IMR_BCNDMAINT5] = IMR_BCNDMAINT5,
315 .maps[RTL_IMR_BCNDMAINT4] = IMR_BCNDMAINT4,
316 .maps[RTL_IMR_BCNDMAINT3] = IMR_BCNDMAINT3,
317 .maps[RTL_IMR_BCNDMAINT2] = IMR_BCNDMAINT2,
318 .maps[RTL_IMR_BCNDMAINT1] = IMR_BCNDMAINT1,
319 .maps[RTL_IMR_BCNDOK8] = IMR_BCNDOK8,
320 .maps[RTL_IMR_BCNDOK7] = IMR_BCNDOK7,
321 .maps[RTL_IMR_BCNDOK6] = IMR_BCNDOK6,
322 .maps[RTL_IMR_BCNDOK5] = IMR_BCNDOK5,
323 .maps[RTL_IMR_BCNDOK4] = IMR_BCNDOK4,
324 .maps[RTL_IMR_BCNDOK3] = IMR_BCNDOK3,
325 .maps[RTL_IMR_BCNDOK2] = IMR_BCNDOK2,
326 .maps[RTL_IMR_BCNDOK1] = IMR_BCNDOK1,
327 .maps[RTL_IMR_TIMEOUT2] = IMR_TIMEOUT2,
328 .maps[RTL_IMR_TIMEOUT1] = IMR_TIMEOUT1,
329
330 .maps[RTL_IMR_TXFOVW] = IMR_TXFOVW,
331 .maps[RTL_IMR_PSTIMEOUT] = IMR_PSTIMEOUT,
332 .maps[RTL_IMR_BcnInt] = IMR_BCNINT,
333 .maps[RTL_IMR_RXFOVW] = IMR_RXFOVW,
334 .maps[RTL_IMR_RDU] = IMR_RDU,
335 .maps[RTL_IMR_ATIMEND] = IMR_ATIMEND,
336 .maps[RTL_IMR_BDOK] = IMR_BDOK,
337 .maps[RTL_IMR_MGNTDOK] = IMR_MGNTDOK,
338 .maps[RTL_IMR_TBDER] = IMR_TBDER,
339 .maps[RTL_IMR_HIGHDOK] = IMR_HIGHDOK,
340 .maps[RTL_IMR_COMDOK] = IMR_COMDOK,
341 .maps[RTL_IMR_TBDOK] = IMR_TBDOK,
342 .maps[RTL_IMR_BKDOK] = IMR_BKDOK,
343 .maps[RTL_IMR_BEDOK] = IMR_BEDOK,
344 .maps[RTL_IMR_VIDOK] = IMR_VIDOK,
345 .maps[RTL_IMR_VODOK] = IMR_VODOK,
346 .maps[RTL_IMR_ROK] = IMR_ROK,
347 .maps[RTL_IBSS_INT_MASKS] = (IMR_BCNINT | IMR_TBDOK | IMR_TBDER),
348
349 .maps[RTL_RC_CCK_RATE1M] = DESC92S_RATE1M,
350 .maps[RTL_RC_CCK_RATE2M] = DESC92S_RATE2M,
351 .maps[RTL_RC_CCK_RATE5_5M] = DESC92S_RATE5_5M,
352 .maps[RTL_RC_CCK_RATE11M] = DESC92S_RATE11M,
353 .maps[RTL_RC_OFDM_RATE6M] = DESC92S_RATE6M,
354 .maps[RTL_RC_OFDM_RATE9M] = DESC92S_RATE9M,
355 .maps[RTL_RC_OFDM_RATE12M] = DESC92S_RATE12M,
356 .maps[RTL_RC_OFDM_RATE18M] = DESC92S_RATE18M,
357 .maps[RTL_RC_OFDM_RATE24M] = DESC92S_RATE24M,
358 .maps[RTL_RC_OFDM_RATE36M] = DESC92S_RATE36M,
359 .maps[RTL_RC_OFDM_RATE48M] = DESC92S_RATE48M,
360 .maps[RTL_RC_OFDM_RATE54M] = DESC92S_RATE54M,
361
362 .maps[RTL_RC_HT_RATEMCS7] = DESC92S_RATEMCS7,
363 .maps[RTL_RC_HT_RATEMCS15] = DESC92S_RATEMCS15,
364};
365
366static struct pci_device_id rtl92se_pci_ids[] __devinitdata = {
367 {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8192, rtl92se_hal_cfg)},
368 {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8171, rtl92se_hal_cfg)},
369 {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8172, rtl92se_hal_cfg)},
370 {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8173, rtl92se_hal_cfg)},
371 {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8174, rtl92se_hal_cfg)},
372 {},
373};
374
375MODULE_DEVICE_TABLE(pci, rtl92se_pci_ids);
376
377MODULE_AUTHOR("lizhaoming <chaoming_li@realsil.com.cn>");
378MODULE_AUTHOR("Realtek WlanFAE <wlanfae@realtek.com>");
379MODULE_LICENSE("GPL");
380MODULE_DESCRIPTION("Realtek 8192S/8191S 802.11n PCI wireless");
381MODULE_FIRMWARE("rtlwifi/rtl8192sefw.bin");
382
383module_param_named(swenc, rtl92se_mod_params.sw_crypto, bool, 0444);
384module_param_named(ips, rtl92se_mod_params.inactiveps, bool, 0444);
385module_param_named(swlps, rtl92se_mod_params.swctrl_lps, bool, 0444);
386module_param_named(fwlps, rtl92se_mod_params.fwctrl_lps, bool, 0444);
387MODULE_PARM_DESC(swenc, "using hardware crypto (default 0 [hardware])\n");
388MODULE_PARM_DESC(ips, "using no link power save (default 1 is open)\n");
389MODULE_PARM_DESC(swlps, "using linked sw control power save (default 1 is "
390 "open)\n");
391
392
393static struct pci_driver rtl92se_driver = {
394 .name = KBUILD_MODNAME,
395 .id_table = rtl92se_pci_ids,
396 .probe = rtl_pci_probe,
397 .remove = rtl_pci_disconnect,
398
399#ifdef CONFIG_PM
400 .suspend = rtl_pci_suspend,
401 .resume = rtl_pci_resume,
402#endif
403
404};
405
406static int __init rtl92se_module_init(void)
407{
408 int ret = 0;
409
410 ret = pci_register_driver(&rtl92se_driver);
411 if (ret)
412 RT_ASSERT(false, (": No device found\n"));
413
414 return ret;
415}
416
417static void __exit rtl92se_module_exit(void)
418{
419 pci_unregister_driver(&rtl92se_driver);
420}
421
422module_init(rtl92se_module_init);
423module_exit(rtl92se_module_exit);
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/sw.h b/drivers/net/wireless/rtlwifi/rtl8192se/sw.h
new file mode 100644
index 000000000000..fc4eb285a0ac
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/sw.h
@@ -0,0 +1,36 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2010 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 *****************************************************************************/
27#ifndef __REALTEK_PCI92SE_SW_H__
28#define __REALTEK_PCI92SE_SW_H__
29
30#define EFUSE_MAX_SECTION 16
31
32int rtl92se_init_sw(struct ieee80211_hw *hw);
33void rtl92se_deinit_sw(struct ieee80211_hw *hw);
34void rtl92se_init_var_map(struct ieee80211_hw *hw);
35
36#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/table.c b/drivers/net/wireless/rtlwifi/rtl8192se/table.c
new file mode 100644
index 000000000000..154185b3969d
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/table.c
@@ -0,0 +1,634 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2010 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 * Created on 2010/ 5/18, 1:41
29 *****************************************************************************/
30
31#include "table.h"
32
33u32 rtl8192sephy_reg_2t2rarray[PHY_REG_2T2RARRAYLENGTH] = {
34 0x01c, 0x07000000,
35 0x800, 0x00040000,
36 0x804, 0x00008003,
37 0x808, 0x0000fc00,
38 0x80c, 0x0000000a,
39 0x810, 0x10005088,
40 0x814, 0x020c3d10,
41 0x818, 0x00200185,
42 0x81c, 0x00000000,
43 0x820, 0x01000000,
44 0x824, 0x00390004,
45 0x828, 0x01000000,
46 0x82c, 0x00390004,
47 0x830, 0x00000004,
48 0x834, 0x00690200,
49 0x838, 0x00000004,
50 0x83c, 0x00690200,
51 0x840, 0x00010000,
52 0x844, 0x00010000,
53 0x848, 0x00000000,
54 0x84c, 0x00000000,
55 0x850, 0x00000000,
56 0x854, 0x00000000,
57 0x858, 0x48484848,
58 0x85c, 0x65a965a9,
59 0x860, 0x0f7f0130,
60 0x864, 0x0f7f0130,
61 0x868, 0x0f7f0130,
62 0x86c, 0x0f7f0130,
63 0x870, 0x03000700,
64 0x874, 0x03000300,
65 0x878, 0x00020002,
66 0x87c, 0x004f0201,
67 0x880, 0xa8300ac1,
68 0x884, 0x00000058,
69 0x888, 0x00000008,
70 0x88c, 0x00000004,
71 0x890, 0x00000000,
72 0x894, 0xfffffffe,
73 0x898, 0x40302010,
74 0x89c, 0x00706050,
75 0x8b0, 0x00000000,
76 0x8e0, 0x00000000,
77 0x8e4, 0x00000000,
78 0xe00, 0x30333333,
79 0xe04, 0x2a2d2e2f,
80 0xe08, 0x00003232,
81 0xe10, 0x30333333,
82 0xe14, 0x2a2d2e2f,
83 0xe18, 0x30333333,
84 0xe1c, 0x2a2d2e2f,
85 0xe30, 0x01007c00,
86 0xe34, 0x01004800,
87 0xe38, 0x1000dc1f,
88 0xe3c, 0x10008c1f,
89 0xe40, 0x021400a0,
90 0xe44, 0x281600a0,
91 0xe48, 0xf8000001,
92 0xe4c, 0x00002910,
93 0xe50, 0x01007c00,
94 0xe54, 0x01004800,
95 0xe58, 0x1000dc1f,
96 0xe5c, 0x10008c1f,
97 0xe60, 0x021400a0,
98 0xe64, 0x281600a0,
99 0xe6c, 0x00002910,
100 0xe70, 0x31ed92fb,
101 0xe74, 0x361536fb,
102 0xe78, 0x361536fb,
103 0xe7c, 0x361536fb,
104 0xe80, 0x361536fb,
105 0xe84, 0x000d92fb,
106 0xe88, 0x000d92fb,
107 0xe8c, 0x31ed92fb,
108 0xed0, 0x31ed92fb,
109 0xed4, 0x31ed92fb,
110 0xed8, 0x000d92fb,
111 0xedc, 0x000d92fb,
112 0xee0, 0x000d92fb,
113 0xee4, 0x015e5448,
114 0xee8, 0x21555448,
115 0x900, 0x00000000,
116 0x904, 0x00000023,
117 0x908, 0x00000000,
118 0x90c, 0x01121313,
119 0xa00, 0x00d047c8,
120 0xa04, 0x80ff0008,
121 0xa08, 0x8ccd8300,
122 0xa0c, 0x2e62120f,
123 0xa10, 0x9500bb78,
124 0xa14, 0x11144028,
125 0xa18, 0x00881117,
126 0xa1c, 0x89140f00,
127 0xa20, 0x1a1b0000,
128 0xa24, 0x090e1317,
129 0xa28, 0x00000204,
130 0xa2c, 0x10d30000,
131 0xc00, 0x40071d40,
132 0xc04, 0x00a05633,
133 0xc08, 0x000000e4,
134 0xc0c, 0x6c6c6c6c,
135 0xc10, 0x08800000,
136 0xc14, 0x40000100,
137 0xc18, 0x08000000,
138 0xc1c, 0x40000100,
139 0xc20, 0x08000000,
140 0xc24, 0x40000100,
141 0xc28, 0x08000000,
142 0xc2c, 0x40000100,
143 0xc30, 0x6de9ac44,
144 0xc34, 0x469652cf,
145 0xc38, 0x49795994,
146 0xc3c, 0x0a979764,
147 0xc40, 0x1f7c403f,
148 0xc44, 0x000100b7,
149 0xc48, 0xec020000,
150 0xc4c, 0x007f037f,
151 0xc50, 0x69543420,
152 0xc54, 0x433c0094,
153 0xc58, 0x69543420,
154 0xc5c, 0x433c0094,
155 0xc60, 0x69543420,
156 0xc64, 0x433c0094,
157 0xc68, 0x69543420,
158 0xc6c, 0x433c0094,
159 0xc70, 0x2c7f000d,
160 0xc74, 0x0186155b,
161 0xc78, 0x0000001f,
162 0xc7c, 0x00b91612,
163 0xc80, 0x40000100,
164 0xc84, 0x20f60000,
165 0xc88, 0x20000080,
166 0xc8c, 0x20200000,
167 0xc90, 0x40000100,
168 0xc94, 0x00000000,
169 0xc98, 0x40000100,
170 0xc9c, 0x00000000,
171 0xca0, 0x00492492,
172 0xca4, 0x00000000,
173 0xca8, 0x00000000,
174 0xcac, 0x00000000,
175 0xcb0, 0x00000000,
176 0xcb4, 0x00000000,
177 0xcb8, 0x00000000,
178 0xcbc, 0x28000000,
179 0xcc0, 0x00000000,
180 0xcc4, 0x00000000,
181 0xcc8, 0x00000000,
182 0xccc, 0x00000000,
183 0xcd0, 0x00000000,
184 0xcd4, 0x00000000,
185 0xcd8, 0x64b22427,
186 0xcdc, 0x00766932,
187 0xce0, 0x00222222,
188 0xce4, 0x00000000,
189 0xce8, 0x37644302,
190 0xcec, 0x2f97d40c,
191 0xd00, 0x00000750,
192 0xd04, 0x00000403,
193 0xd08, 0x0000907f,
194 0xd0c, 0x00000001,
195 0xd10, 0xa0633333,
196 0xd14, 0x33333c63,
197 0xd18, 0x6a8f5b6b,
198 0xd1c, 0x00000000,
199 0xd20, 0x00000000,
200 0xd24, 0x00000000,
201 0xd28, 0x00000000,
202 0xd2c, 0xcc979975,
203 0xd30, 0x00000000,
204 0xd34, 0x00000000,
205 0xd38, 0x00000000,
206 0xd3c, 0x00027293,
207 0xd40, 0x00000000,
208 0xd44, 0x00000000,
209 0xd48, 0x00000000,
210 0xd50, 0x6437140a,
211 0xd54, 0x024dbd02,
212 0xd58, 0x00000000,
213 0xd5c, 0x30032064,
214 0xd60, 0x4653de68,
215 0xd64, 0x00518a3c,
216 0xd68, 0x00002101,
217 0xf14, 0x00000003,
218 0xf4c, 0x00000000,
219 0xf00, 0x00000300,
220};
221
222u32 rtl8192sephy_changeto_1t1rarray[PHY_CHANGETO_1T1RARRAYLENGTH] = {
223 0x844, 0xffffffff, 0x00010000,
224 0x804, 0x0000000f, 0x00000001,
225 0x824, 0x00f0000f, 0x00300004,
226 0x82c, 0x00f0000f, 0x00100002,
227 0x870, 0x04000000, 0x00000001,
228 0x864, 0x00000400, 0x00000000,
229 0x878, 0x000f000f, 0x00000002,
230 0xe74, 0x0f000000, 0x00000002,
231 0xe78, 0x0f000000, 0x00000002,
232 0xe7c, 0x0f000000, 0x00000002,
233 0xe80, 0x0f000000, 0x00000002,
234 0x90c, 0x000000ff, 0x00000011,
235 0xc04, 0x000000ff, 0x00000011,
236 0xd04, 0x0000000f, 0x00000001,
237 0x1f4, 0xffff0000, 0x00007777,
238 0x234, 0xf8000000, 0x0000000a,
239};
240
241u32 rtl8192sephy_changeto_1t2rarray[PHY_CHANGETO_1T2RARRAYLENGTH] = {
242 0x804, 0x0000000f, 0x00000003,
243 0x824, 0x00f0000f, 0x00300004,
244 0x82c, 0x00f0000f, 0x00300002,
245 0x870, 0x04000000, 0x00000001,
246 0x864, 0x00000400, 0x00000000,
247 0x878, 0x000f000f, 0x00000002,
248 0xe74, 0x0f000000, 0x00000002,
249 0xe78, 0x0f000000, 0x00000002,
250 0xe7c, 0x0f000000, 0x00000002,
251 0xe80, 0x0f000000, 0x00000002,
252 0x90c, 0x000000ff, 0x00000011,
253 0xc04, 0x000000ff, 0x00000033,
254 0xd04, 0x0000000f, 0x00000003,
255 0x1f4, 0xffff0000, 0x00007777,
256 0x234, 0xf8000000, 0x0000000a,
257};
258
259u32 rtl8192sephy_reg_array_pg[PHY_REG_ARRAY_PGLENGTH] = {
260 0xe00, 0xffffffff, 0x06090909,
261 0xe04, 0xffffffff, 0x00030406,
262 0xe08, 0x0000ff00, 0x00000000,
263 0xe10, 0xffffffff, 0x0a0c0d0e,
264 0xe14, 0xffffffff, 0x04070809,
265 0xe18, 0xffffffff, 0x0a0c0d0e,
266 0xe1c, 0xffffffff, 0x04070809,
267 0xe00, 0xffffffff, 0x04040404,
268 0xe04, 0xffffffff, 0x00020204,
269 0xe08, 0x0000ff00, 0x00000000,
270 0xe10, 0xffffffff, 0x02040404,
271 0xe14, 0xffffffff, 0x00000002,
272 0xe18, 0xffffffff, 0x02040404,
273 0xe1c, 0xffffffff, 0x00000002,
274 0xe00, 0xffffffff, 0x04040404,
275 0xe04, 0xffffffff, 0x00020204,
276 0xe08, 0x0000ff00, 0x00000000,
277 0xe10, 0xffffffff, 0x02040404,
278 0xe14, 0xffffffff, 0x00000002,
279 0xe18, 0xffffffff, 0x02040404,
280 0xe1c, 0xffffffff, 0x00000002,
281 0xe00, 0xffffffff, 0x02020202,
282 0xe04, 0xffffffff, 0x00020202,
283 0xe08, 0x0000ff00, 0x00000000,
284 0xe10, 0xffffffff, 0x02020202,
285 0xe14, 0xffffffff, 0x00000002,
286 0xe18, 0xffffffff, 0x02020202,
287 0xe1c, 0xffffffff, 0x00000002,
288};
289
290u32 rtl8192seradioa_1t_array[RADIOA_1T_ARRAYLENGTH] = {
291 0x000, 0x00030159,
292 0x001, 0x00030250,
293 0x002, 0x00010000,
294 0x010, 0x0008000f,
295 0x011, 0x000231fc,
296 0x010, 0x000c000f,
297 0x011, 0x0003f9f8,
298 0x010, 0x0002000f,
299 0x011, 0x00020101,
300 0x014, 0x0001093e,
301 0x014, 0x0009093e,
302 0x015, 0x0000f8f4,
303 0x017, 0x000f6500,
304 0x01a, 0x00013056,
305 0x01b, 0x00060000,
306 0x01c, 0x00000300,
307 0x01e, 0x00031059,
308 0x021, 0x00054000,
309 0x022, 0x0000083c,
310 0x023, 0x00001558,
311 0x024, 0x00000060,
312 0x025, 0x00022583,
313 0x026, 0x0000f200,
314 0x027, 0x000eacf1,
315 0x028, 0x0009bd54,
316 0x029, 0x00004582,
317 0x02a, 0x00000001,
318 0x02b, 0x00021334,
319 0x02a, 0x00000000,
320 0x02b, 0x0000000a,
321 0x02a, 0x00000001,
322 0x02b, 0x00000808,
323 0x02b, 0x00053333,
324 0x02c, 0x0000000c,
325 0x02a, 0x00000002,
326 0x02b, 0x00000808,
327 0x02b, 0x0005b333,
328 0x02c, 0x0000000d,
329 0x02a, 0x00000003,
330 0x02b, 0x00000808,
331 0x02b, 0x00063333,
332 0x02c, 0x0000000d,
333 0x02a, 0x00000004,
334 0x02b, 0x00000808,
335 0x02b, 0x0006b333,
336 0x02c, 0x0000000d,
337 0x02a, 0x00000005,
338 0x02b, 0x00000709,
339 0x02b, 0x00053333,
340 0x02c, 0x0000000d,
341 0x02a, 0x00000006,
342 0x02b, 0x00000709,
343 0x02b, 0x0005b333,
344 0x02c, 0x0000000d,
345 0x02a, 0x00000007,
346 0x02b, 0x00000709,
347 0x02b, 0x00063333,
348 0x02c, 0x0000000d,
349 0x02a, 0x00000008,
350 0x02b, 0x00000709,
351 0x02b, 0x0006b333,
352 0x02c, 0x0000000d,
353 0x02a, 0x00000009,
354 0x02b, 0x0000060a,
355 0x02b, 0x00053333,
356 0x02c, 0x0000000d,
357 0x02a, 0x0000000a,
358 0x02b, 0x0000060a,
359 0x02b, 0x0005b333,
360 0x02c, 0x0000000d,
361 0x02a, 0x0000000b,
362 0x02b, 0x0000060a,
363 0x02b, 0x00063333,
364 0x02c, 0x0000000d,
365 0x02a, 0x0000000c,
366 0x02b, 0x0000060a,
367 0x02b, 0x0006b333,
368 0x02c, 0x0000000d,
369 0x02a, 0x0000000d,
370 0x02b, 0x0000050b,
371 0x02b, 0x00053333,
372 0x02c, 0x0000000d,
373 0x02a, 0x0000000e,
374 0x02b, 0x0000050b,
375 0x02b, 0x00066623,
376 0x02c, 0x0000001a,
377 0x02a, 0x000e4000,
378 0x030, 0x00020000,
379 0x031, 0x000b9631,
380 0x032, 0x0000130d,
381 0x033, 0x00000187,
382 0x013, 0x00019e6c,
383 0x013, 0x00015e94,
384 0x000, 0x00010159,
385 0x018, 0x0000f401,
386 0x0fe, 0x00000000,
387 0x01e, 0x0003105b,
388 0x0fe, 0x00000000,
389 0x000, 0x00030159,
390 0x010, 0x0004000f,
391 0x011, 0x000203f9,
392};
393
394u32 rtl8192seradiob_array[RADIOB_ARRAYLENGTH] = {
395 0x000, 0x00030159,
396 0x001, 0x00001041,
397 0x002, 0x00011000,
398 0x005, 0x00080fc0,
399 0x007, 0x000fc803,
400 0x013, 0x00017cb0,
401 0x013, 0x00011cc0,
402 0x013, 0x0000dc60,
403 0x013, 0x00008c60,
404 0x013, 0x00004450,
405 0x013, 0x00000020,
406};
407
408u32 rtl8192seradiob_gm_array[RADIOB_GM_ARRAYLENGTH] = {
409 0x000, 0x00030159,
410 0x001, 0x00001041,
411 0x002, 0x00011000,
412 0x005, 0x00080fc0,
413 0x007, 0x000fc803,
414};
415
416u32 rtl8192semac_2t_array[MAC_2T_ARRAYLENGTH] = {
417 0x020, 0x00000035,
418 0x048, 0x0000000e,
419 0x049, 0x000000f0,
420 0x04a, 0x00000077,
421 0x04b, 0x00000083,
422 0x0b5, 0x00000021,
423 0x0dc, 0x000000ff,
424 0x0dd, 0x000000ff,
425 0x0de, 0x000000ff,
426 0x0df, 0x000000ff,
427 0x116, 0x00000000,
428 0x117, 0x00000000,
429 0x118, 0x00000000,
430 0x119, 0x00000000,
431 0x11a, 0x00000000,
432 0x11b, 0x00000000,
433 0x11c, 0x00000000,
434 0x11d, 0x00000000,
435 0x160, 0x0000000b,
436 0x161, 0x0000000b,
437 0x162, 0x0000000b,
438 0x163, 0x0000000b,
439 0x164, 0x0000000b,
440 0x165, 0x0000000b,
441 0x166, 0x0000000b,
442 0x167, 0x0000000b,
443 0x168, 0x0000000b,
444 0x169, 0x0000000b,
445 0x16a, 0x0000000b,
446 0x16b, 0x0000000b,
447 0x16c, 0x0000000b,
448 0x16d, 0x0000000b,
449 0x16e, 0x0000000b,
450 0x16f, 0x0000000b,
451 0x170, 0x0000000b,
452 0x171, 0x0000000b,
453 0x172, 0x0000000b,
454 0x173, 0x0000000b,
455 0x174, 0x0000000b,
456 0x175, 0x0000000b,
457 0x176, 0x0000000b,
458 0x177, 0x0000000b,
459 0x178, 0x0000000b,
460 0x179, 0x0000000b,
461 0x17a, 0x0000000b,
462 0x17b, 0x0000000b,
463 0x17c, 0x0000000b,
464 0x17d, 0x0000000b,
465 0x17e, 0x0000000b,
466 0x17f, 0x0000000b,
467 0x236, 0x0000000c,
468 0x503, 0x00000022,
469 0x560, 0x00000000,
470};
471
472u32 rtl8192seagctab_array[AGCTAB_ARRAYLENGTH] = {
473 0xc78, 0x7f000001,
474 0xc78, 0x7f010001,
475 0xc78, 0x7e020001,
476 0xc78, 0x7d030001,
477 0xc78, 0x7c040001,
478 0xc78, 0x7b050001,
479 0xc78, 0x7a060001,
480 0xc78, 0x79070001,
481 0xc78, 0x78080001,
482 0xc78, 0x77090001,
483 0xc78, 0x760a0001,
484 0xc78, 0x750b0001,
485 0xc78, 0x740c0001,
486 0xc78, 0x730d0001,
487 0xc78, 0x720e0001,
488 0xc78, 0x710f0001,
489 0xc78, 0x70100001,
490 0xc78, 0x6f110001,
491 0xc78, 0x6f120001,
492 0xc78, 0x6e130001,
493 0xc78, 0x6d140001,
494 0xc78, 0x6d150001,
495 0xc78, 0x6c160001,
496 0xc78, 0x6b170001,
497 0xc78, 0x6a180001,
498 0xc78, 0x6a190001,
499 0xc78, 0x691a0001,
500 0xc78, 0x681b0001,
501 0xc78, 0x671c0001,
502 0xc78, 0x661d0001,
503 0xc78, 0x651e0001,
504 0xc78, 0x641f0001,
505 0xc78, 0x63200001,
506 0xc78, 0x4c210001,
507 0xc78, 0x4b220001,
508 0xc78, 0x4a230001,
509 0xc78, 0x49240001,
510 0xc78, 0x48250001,
511 0xc78, 0x47260001,
512 0xc78, 0x46270001,
513 0xc78, 0x45280001,
514 0xc78, 0x44290001,
515 0xc78, 0x2c2a0001,
516 0xc78, 0x2b2b0001,
517 0xc78, 0x2a2c0001,
518 0xc78, 0x292d0001,
519 0xc78, 0x282e0001,
520 0xc78, 0x272f0001,
521 0xc78, 0x26300001,
522 0xc78, 0x25310001,
523 0xc78, 0x24320001,
524 0xc78, 0x23330001,
525 0xc78, 0x22340001,
526 0xc78, 0x09350001,
527 0xc78, 0x08360001,
528 0xc78, 0x07370001,
529 0xc78, 0x06380001,
530 0xc78, 0x05390001,
531 0xc78, 0x043a0001,
532 0xc78, 0x033b0001,
533 0xc78, 0x023c0001,
534 0xc78, 0x013d0001,
535 0xc78, 0x003e0001,
536 0xc78, 0x003f0001,
537 0xc78, 0x7f400001,
538 0xc78, 0x7f410001,
539 0xc78, 0x7e420001,
540 0xc78, 0x7d430001,
541 0xc78, 0x7c440001,
542 0xc78, 0x7b450001,
543 0xc78, 0x7a460001,
544 0xc78, 0x79470001,
545 0xc78, 0x78480001,
546 0xc78, 0x77490001,
547 0xc78, 0x764a0001,
548 0xc78, 0x754b0001,
549 0xc78, 0x744c0001,
550 0xc78, 0x734d0001,
551 0xc78, 0x724e0001,
552 0xc78, 0x714f0001,
553 0xc78, 0x70500001,
554 0xc78, 0x6f510001,
555 0xc78, 0x6f520001,
556 0xc78, 0x6e530001,
557 0xc78, 0x6d540001,
558 0xc78, 0x6d550001,
559 0xc78, 0x6c560001,
560 0xc78, 0x6b570001,
561 0xc78, 0x6a580001,
562 0xc78, 0x6a590001,
563 0xc78, 0x695a0001,
564 0xc78, 0x685b0001,
565 0xc78, 0x675c0001,
566 0xc78, 0x665d0001,
567 0xc78, 0x655e0001,
568 0xc78, 0x645f0001,
569 0xc78, 0x63600001,
570 0xc78, 0x4c610001,
571 0xc78, 0x4b620001,
572 0xc78, 0x4a630001,
573 0xc78, 0x49640001,
574 0xc78, 0x48650001,
575 0xc78, 0x47660001,
576 0xc78, 0x46670001,
577 0xc78, 0x45680001,
578 0xc78, 0x44690001,
579 0xc78, 0x2c6a0001,
580 0xc78, 0x2b6b0001,
581 0xc78, 0x2a6c0001,
582 0xc78, 0x296d0001,
583 0xc78, 0x286e0001,
584 0xc78, 0x276f0001,
585 0xc78, 0x26700001,
586 0xc78, 0x25710001,
587 0xc78, 0x24720001,
588 0xc78, 0x23730001,
589 0xc78, 0x22740001,
590 0xc78, 0x09750001,
591 0xc78, 0x08760001,
592 0xc78, 0x07770001,
593 0xc78, 0x06780001,
594 0xc78, 0x05790001,
595 0xc78, 0x047a0001,
596 0xc78, 0x037b0001,
597 0xc78, 0x027c0001,
598 0xc78, 0x017d0001,
599 0xc78, 0x007e0001,
600 0xc78, 0x007f0001,
601 0xc78, 0x3000001e,
602 0xc78, 0x3001001e,
603 0xc78, 0x3002001e,
604 0xc78, 0x3003001e,
605 0xc78, 0x3004001e,
606 0xc78, 0x3405001e,
607 0xc78, 0x3806001e,
608 0xc78, 0x3e07001e,
609 0xc78, 0x3e08001e,
610 0xc78, 0x4409001e,
611 0xc78, 0x460a001e,
612 0xc78, 0x480b001e,
613 0xc78, 0x480c001e,
614 0xc78, 0x4e0d001e,
615 0xc78, 0x560e001e,
616 0xc78, 0x5a0f001e,
617 0xc78, 0x5e10001e,
618 0xc78, 0x6211001e,
619 0xc78, 0x6c12001e,
620 0xc78, 0x7213001e,
621 0xc78, 0x7214001e,
622 0xc78, 0x7215001e,
623 0xc78, 0x7216001e,
624 0xc78, 0x7217001e,
625 0xc78, 0x7218001e,
626 0xc78, 0x7219001e,
627 0xc78, 0x721a001e,
628 0xc78, 0x721b001e,
629 0xc78, 0x721c001e,
630 0xc78, 0x721d001e,
631 0xc78, 0x721e001e,
632 0xc78, 0x721f001e,
633};
634
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/table.h b/drivers/net/wireless/rtlwifi/rtl8192se/table.h
new file mode 100644
index 000000000000..b4ed6d951ebb
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/table.h
@@ -0,0 +1,49 @@
1/******************************************************************************
2 * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
3 *
4 * This program is distributed in the hope that it will be useful, but WITHOUT
5 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
6 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
7 * more details.
8 *
9 * You should have received a copy of the GNU General Public License along with
10 * this program; if not, write to the Free Software Foundation, Inc.,
11 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
12 *
13 * The full GNU General Public License is included in this distribution in the
14 * file called LICENSE.
15 *
16 * Contact Information:
17 * wlanfae <wlanfae@realtek.com>
18 *
19 * Larry Finger <Larry.Finger@lwfinger.net>
20 *
21 ******************************************************************************/
22#ifndef __INC_HAL8192SE_FW_IMG_H
23#define __INC_HAL8192SE_FW_IMG_H
24
25#include <linux/types.h>
26
27/*Created on 2010/ 4/12, 5:56*/
28
29#define PHY_REG_2T2RARRAYLENGTH 372
30extern u32 rtl8192sephy_reg_2t2rarray[PHY_REG_2T2RARRAYLENGTH];
31#define PHY_CHANGETO_1T1RARRAYLENGTH 48
32extern u32 rtl8192sephy_changeto_1t1rarray[PHY_CHANGETO_1T1RARRAYLENGTH];
33#define PHY_CHANGETO_1T2RARRAYLENGTH 45
34extern u32 rtl8192sephy_changeto_1t2rarray[PHY_CHANGETO_1T2RARRAYLENGTH];
35#define PHY_REG_ARRAY_PGLENGTH 84
36extern u32 rtl8192sephy_reg_array_pg[PHY_REG_ARRAY_PGLENGTH];
37#define RADIOA_1T_ARRAYLENGTH 202
38extern u32 rtl8192seradioa_1t_array[RADIOA_1T_ARRAYLENGTH];
39#define RADIOB_ARRAYLENGTH 22
40extern u32 rtl8192seradiob_array[RADIOB_ARRAYLENGTH];
41#define RADIOB_GM_ARRAYLENGTH 10
42extern u32 rtl8192seradiob_gm_array[RADIOB_GM_ARRAYLENGTH];
43#define MAC_2T_ARRAYLENGTH 106
44extern u32 rtl8192semac_2t_array[MAC_2T_ARRAYLENGTH];
45#define AGCTAB_ARRAYLENGTH 320
46extern u32 rtl8192seagctab_array[AGCTAB_ARRAYLENGTH];
47
48#endif
49
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c
new file mode 100644
index 000000000000..5cf442373d46
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c
@@ -0,0 +1,976 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2010 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#include "../wifi.h"
31#include "../pci.h"
32#include "../base.h"
33#include "reg.h"
34#include "def.h"
35#include "phy.h"
36#include "fw.h"
37#include "trx.h"
38#include "led.h"
39
40static u8 _rtl92se_map_hwqueue_to_fwqueue(struct sk_buff *skb, u8 skb_queue)
41{
42 __le16 fc = rtl_get_fc(skb);
43
44 if (unlikely(ieee80211_is_beacon(fc)))
45 return QSLT_BEACON;
46 if (ieee80211_is_mgmt(fc))
47 return QSLT_MGNT;
48 if (ieee80211_is_nullfunc(fc))
49 return QSLT_HIGH;
50
51 return skb->priority;
52}
53
54static int _rtl92se_rate_mapping(bool isht, u8 desc_rate, bool first_ampdu)
55{
56 int rate_idx = 0;
57
58 if (first_ampdu) {
59 if (false == isht) {
60 switch (desc_rate) {
61 case DESC92S_RATE1M:
62 rate_idx = 0;
63 break;
64 case DESC92S_RATE2M:
65 rate_idx = 1;
66 break;
67 case DESC92S_RATE5_5M:
68 rate_idx = 2;
69 break;
70 case DESC92S_RATE11M:
71 rate_idx = 3;
72 break;
73 case DESC92S_RATE6M:
74 rate_idx = 4;
75 break;
76 case DESC92S_RATE9M:
77 rate_idx = 5;
78 break;
79 case DESC92S_RATE12M:
80 rate_idx = 6;
81 break;
82 case DESC92S_RATE18M:
83 rate_idx = 7;
84 break;
85 case DESC92S_RATE24M:
86 rate_idx = 8;
87 break;
88 case DESC92S_RATE36M:
89 rate_idx = 9;
90 break;
91 case DESC92S_RATE48M:
92 rate_idx = 10;
93 break;
94 case DESC92S_RATE54M:
95 rate_idx = 11;
96 break;
97 default:
98 rate_idx = 0;
99 break;
100 }
101 } else {
102 rate_idx = 11;
103 }
104
105 return rate_idx;
106 }
107
108 switch (desc_rate) {
109 case DESC92S_RATE1M:
110 rate_idx = 0;
111 break;
112 case DESC92S_RATE2M:
113 rate_idx = 1;
114 break;
115 case DESC92S_RATE5_5M:
116 rate_idx = 2;
117 break;
118 case DESC92S_RATE11M:
119 rate_idx = 3;
120 break;
121 case DESC92S_RATE6M:
122 rate_idx = 4;
123 break;
124 case DESC92S_RATE9M:
125 rate_idx = 5;
126 break;
127 case DESC92S_RATE12M:
128 rate_idx = 6;
129 break;
130 case DESC92S_RATE18M:
131 rate_idx = 7;
132 break;
133 case DESC92S_RATE24M:
134 rate_idx = 8;
135 break;
136 case DESC92S_RATE36M:
137 rate_idx = 9;
138 break;
139 case DESC92S_RATE48M:
140 rate_idx = 10;
141 break;
142 case DESC92S_RATE54M:
143 rate_idx = 11;
144 break;
145 default:
146 rate_idx = 11;
147 break;
148 }
149 return rate_idx;
150}
151
152static u8 _rtl92s_query_rxpwrpercentage(char antpower)
153{
154 if ((antpower <= -100) || (antpower >= 20))
155 return 0;
156 else if (antpower >= 0)
157 return 100;
158 else
159 return 100 + antpower;
160}
161
162static u8 _rtl92s_evm_db_to_percentage(char value)
163{
164 char ret_val;
165 ret_val = value;
166
167 if (ret_val >= 0)
168 ret_val = 0;
169
170 if (ret_val <= -33)
171 ret_val = -33;
172
173 ret_val = 0 - ret_val;
174 ret_val *= 3;
175
176 if (ret_val == 99)
177 ret_val = 100;
178
179 return ret_val;
180}
181
182static long _rtl92se_translate_todbm(struct ieee80211_hw *hw,
183 u8 signal_strength_index)
184{
185 long signal_power;
186
187 signal_power = (long)((signal_strength_index + 1) >> 1);
188 signal_power -= 95;
189 return signal_power;
190}
191
192static long _rtl92se_signal_scale_mapping(struct ieee80211_hw *hw,
193 long currsig)
194{
195 long retsig = 0;
196
197 /* Step 1. Scale mapping. */
198 if (currsig > 47)
199 retsig = 100;
200 else if (currsig > 14 && currsig <= 47)
201 retsig = 100 - ((47 - currsig) * 3) / 2;
202 else if (currsig > 2 && currsig <= 14)
203 retsig = 48 - ((14 - currsig) * 15) / 7;
204 else if (currsig >= 0)
205 retsig = currsig * 9 + 1;
206
207 return retsig;
208}
209
210
211static void _rtl92se_query_rxphystatus(struct ieee80211_hw *hw,
212 struct rtl_stats *pstats, u8 *pdesc,
213 struct rx_fwinfo *p_drvinfo,
214 bool packet_match_bssid,
215 bool packet_toself,
216 bool packet_beacon)
217{
218 struct rtl_priv *rtlpriv = rtl_priv(hw);
219 struct phy_sts_cck_8192s_t *cck_buf;
220 s8 rx_pwr_all = 0, rx_pwr[4];
221 u8 rf_rx_num = 0, evm, pwdb_all;
222 u8 i, max_spatial_stream;
223 u32 rssi, total_rssi = 0;
224 bool in_powersavemode = false;
225 bool is_cck_rate;
226
227 is_cck_rate = RX_HAL_IS_CCK_RATE(pdesc);
228 pstats->packet_matchbssid = packet_match_bssid;
229 pstats->packet_toself = packet_toself;
230 pstats->is_cck = is_cck_rate;
231 pstats->packet_beacon = packet_beacon;
232 pstats->is_cck = is_cck_rate;
233 pstats->rx_mimo_signalquality[0] = -1;
234 pstats->rx_mimo_signalquality[1] = -1;
235
236 if (is_cck_rate) {
237 u8 report, cck_highpwr;
238 cck_buf = (struct phy_sts_cck_8192s_t *)p_drvinfo;
239
240 if (!in_powersavemode)
241 cck_highpwr = (u8) rtl_get_bbreg(hw,
242 RFPGA0_XA_HSSIPARAMETER2,
243 0x200);
244 else
245 cck_highpwr = false;
246
247 if (!cck_highpwr) {
248 u8 cck_agc_rpt = cck_buf->cck_agc_rpt;
249 report = cck_buf->cck_agc_rpt & 0xc0;
250 report = report >> 6;
251 switch (report) {
252 case 0x3:
253 rx_pwr_all = -40 - (cck_agc_rpt & 0x3e);
254 break;
255 case 0x2:
256 rx_pwr_all = -20 - (cck_agc_rpt & 0x3e);
257 break;
258 case 0x1:
259 rx_pwr_all = -2 - (cck_agc_rpt & 0x3e);
260 break;
261 case 0x0:
262 rx_pwr_all = 14 - (cck_agc_rpt & 0x3e);
263 break;
264 }
265 } else {
266 u8 cck_agc_rpt = cck_buf->cck_agc_rpt;
267 report = p_drvinfo->cfosho[0] & 0x60;
268 report = report >> 5;
269 switch (report) {
270 case 0x3:
271 rx_pwr_all = -40 - ((cck_agc_rpt & 0x1f) << 1);
272 break;
273 case 0x2:
274 rx_pwr_all = -20 - ((cck_agc_rpt & 0x1f) << 1);
275 break;
276 case 0x1:
277 rx_pwr_all = -2 - ((cck_agc_rpt & 0x1f) << 1);
278 break;
279 case 0x0:
280 rx_pwr_all = 14 - ((cck_agc_rpt & 0x1f) << 1);
281 break;
282 }
283 }
284
285 pwdb_all = _rtl92s_query_rxpwrpercentage(rx_pwr_all);
286
287 /* CCK gain is smaller than OFDM/MCS gain, */
288 /* so we add gain diff by experiences, the val is 6 */
289 pwdb_all += 6;
290 if (pwdb_all > 100)
291 pwdb_all = 100;
292 /* modify the offset to make the same gain index with OFDM. */
293 if (pwdb_all > 34 && pwdb_all <= 42)
294 pwdb_all -= 2;
295 else if (pwdb_all > 26 && pwdb_all <= 34)
296 pwdb_all -= 6;
297 else if (pwdb_all > 14 && pwdb_all <= 26)
298 pwdb_all -= 8;
299 else if (pwdb_all > 4 && pwdb_all <= 14)
300 pwdb_all -= 4;
301
302 pstats->rx_pwdb_all = pwdb_all;
303 pstats->recvsignalpower = rx_pwr_all;
304
305 if (packet_match_bssid) {
306 u8 sq;
307 if (pstats->rx_pwdb_all > 40) {
308 sq = 100;
309 } else {
310 sq = cck_buf->sq_rpt;
311 if (sq > 64)
312 sq = 0;
313 else if (sq < 20)
314 sq = 100;
315 else
316 sq = ((64 - sq) * 100) / 44;
317 }
318
319 pstats->signalquality = sq;
320 pstats->rx_mimo_signalquality[0] = sq;
321 pstats->rx_mimo_signalquality[1] = -1;
322 }
323 } else {
324 rtlpriv->dm.rfpath_rxenable[0] =
325 rtlpriv->dm.rfpath_rxenable[1] = true;
326 for (i = RF90_PATH_A; i < RF90_PATH_MAX; i++) {
327 if (rtlpriv->dm.rfpath_rxenable[i])
328 rf_rx_num++;
329
330 rx_pwr[i] = ((p_drvinfo->gain_trsw[i] &
331 0x3f) * 2) - 110;
332 rssi = _rtl92s_query_rxpwrpercentage(rx_pwr[i]);
333 total_rssi += rssi;
334 rtlpriv->stats.rx_snr_db[i] =
335 (long)(p_drvinfo->rxsnr[i] / 2);
336
337 if (packet_match_bssid)
338 pstats->rx_mimo_signalstrength[i] = (u8) rssi;
339 }
340
341 rx_pwr_all = ((p_drvinfo->pwdb_all >> 1) & 0x7f) - 110;
342 pwdb_all = _rtl92s_query_rxpwrpercentage(rx_pwr_all);
343 pstats->rx_pwdb_all = pwdb_all;
344 pstats->rxpower = rx_pwr_all;
345 pstats->recvsignalpower = rx_pwr_all;
346
347 if (GET_RX_STATUS_DESC_RX_HT(pdesc) &&
348 GET_RX_STATUS_DESC_RX_MCS(pdesc) >= DESC92S_RATEMCS8 &&
349 GET_RX_STATUS_DESC_RX_MCS(pdesc) <= DESC92S_RATEMCS15)
350 max_spatial_stream = 2;
351 else
352 max_spatial_stream = 1;
353
354 for (i = 0; i < max_spatial_stream; i++) {
355 evm = _rtl92s_evm_db_to_percentage(p_drvinfo->rxevm[i]);
356
357 if (packet_match_bssid) {
358 if (i == 0)
359 pstats->signalquality = (u8)(evm &
360 0xff);
361 pstats->rx_mimo_signalquality[i] =
362 (u8) (evm & 0xff);
363 }
364 }
365 }
366
367 if (is_cck_rate)
368 pstats->signalstrength = (u8)(_rtl92se_signal_scale_mapping(hw,
369 pwdb_all));
370 else if (rf_rx_num != 0)
371 pstats->signalstrength = (u8) (_rtl92se_signal_scale_mapping(hw,
372 total_rssi /= rf_rx_num));
373}
374
375static void _rtl92se_process_ui_rssi(struct ieee80211_hw *hw,
376 struct rtl_stats *pstats)
377{
378 struct rtl_priv *rtlpriv = rtl_priv(hw);
379 struct rtl_phy *rtlphy = &(rtlpriv->phy);
380 u8 rfpath;
381 u32 last_rssi, tmpval;
382
383 if (pstats->packet_toself || pstats->packet_beacon) {
384 rtlpriv->stats.rssi_calculate_cnt++;
385
386 if (rtlpriv->stats.ui_rssi.total_num++ >=
387 PHY_RSSI_SLID_WIN_MAX) {
388 rtlpriv->stats.ui_rssi.total_num =
389 PHY_RSSI_SLID_WIN_MAX;
390 last_rssi = rtlpriv->stats.ui_rssi.elements[
391 rtlpriv->stats.ui_rssi.index];
392 rtlpriv->stats.ui_rssi.total_val -= last_rssi;
393 }
394
395 rtlpriv->stats.ui_rssi.total_val += pstats->signalstrength;
396 rtlpriv->stats.ui_rssi.elements[rtlpriv->stats.ui_rssi.index++]
397 = pstats->signalstrength;
398
399 if (rtlpriv->stats.ui_rssi.index >= PHY_RSSI_SLID_WIN_MAX)
400 rtlpriv->stats.ui_rssi.index = 0;
401
402 tmpval = rtlpriv->stats.ui_rssi.total_val /
403 rtlpriv->stats.ui_rssi.total_num;
404 rtlpriv->stats.signal_strength = _rtl92se_translate_todbm(hw,
405 (u8) tmpval);
406 pstats->rssi = rtlpriv->stats.signal_strength;
407 }
408
409 if (!pstats->is_cck && pstats->packet_toself) {
410 for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath;
411 rfpath++) {
412 if (rtlpriv->stats.rx_rssi_percentage[rfpath] == 0) {
413 rtlpriv->stats.rx_rssi_percentage[rfpath] =
414 pstats->rx_mimo_signalstrength[rfpath];
415
416 }
417
418 if (pstats->rx_mimo_signalstrength[rfpath] >
419 rtlpriv->stats.rx_rssi_percentage[rfpath]) {
420 rtlpriv->stats.rx_rssi_percentage[rfpath] =
421 ((rtlpriv->stats.rx_rssi_percentage[rfpath]
422 * (RX_SMOOTH_FACTOR - 1)) +
423 (pstats->rx_mimo_signalstrength[rfpath])) /
424 (RX_SMOOTH_FACTOR);
425
426 rtlpriv->stats.rx_rssi_percentage[rfpath] =
427 rtlpriv->stats.rx_rssi_percentage[rfpath]
428 + 1;
429 } else {
430 rtlpriv->stats.rx_rssi_percentage[rfpath] =
431 ((rtlpriv->stats.rx_rssi_percentage[rfpath]
432 * (RX_SMOOTH_FACTOR - 1)) +
433 (pstats->rx_mimo_signalstrength[rfpath])) /
434 (RX_SMOOTH_FACTOR);
435 }
436
437 }
438 }
439}
440
441static void _rtl92se_update_rxsignalstatistics(struct ieee80211_hw *hw,
442 struct rtl_stats *pstats)
443{
444 struct rtl_priv *rtlpriv = rtl_priv(hw);
445 int weighting = 0;
446
447 if (rtlpriv->stats.recv_signal_power == 0)
448 rtlpriv->stats.recv_signal_power = pstats->recvsignalpower;
449
450 if (pstats->recvsignalpower > rtlpriv->stats.recv_signal_power)
451 weighting = 5;
452 else if (pstats->recvsignalpower < rtlpriv->stats.recv_signal_power)
453 weighting = (-5);
454
455 rtlpriv->stats.recv_signal_power = (rtlpriv->stats.recv_signal_power * 5
456 + pstats->recvsignalpower +
457 weighting) / 6;
458}
459
460static void _rtl92se_process_pwdb(struct ieee80211_hw *hw,
461 struct rtl_stats *pstats)
462{
463 struct rtl_priv *rtlpriv = rtl_priv(hw);
464 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
465 long undec_sm_pwdb = 0;
466
467 if (mac->opmode == NL80211_IFTYPE_ADHOC) {
468 return;
469 } else {
470 undec_sm_pwdb =
471 rtlpriv->dm.undecorated_smoothed_pwdb;
472 }
473
474 if (pstats->packet_toself || pstats->packet_beacon) {
475 if (undec_sm_pwdb < 0)
476 undec_sm_pwdb = pstats->rx_pwdb_all;
477
478 if (pstats->rx_pwdb_all > (u32) undec_sm_pwdb) {
479 undec_sm_pwdb =
480 (((undec_sm_pwdb) *
481 (RX_SMOOTH_FACTOR - 1)) +
482 (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR);
483
484 undec_sm_pwdb = undec_sm_pwdb + 1;
485 } else {
486 undec_sm_pwdb = (((undec_sm_pwdb) *
487 (RX_SMOOTH_FACTOR - 1)) + (pstats->rx_pwdb_all)) /
488 (RX_SMOOTH_FACTOR);
489 }
490
491 rtlpriv->dm.undecorated_smoothed_pwdb = undec_sm_pwdb;
492 _rtl92se_update_rxsignalstatistics(hw, pstats);
493 }
494}
495
496static void rtl_92s_process_streams(struct ieee80211_hw *hw,
497 struct rtl_stats *pstats)
498{
499 struct rtl_priv *rtlpriv = rtl_priv(hw);
500 u32 stream;
501
502 for (stream = 0; stream < 2; stream++) {
503 if (pstats->rx_mimo_signalquality[stream] != -1) {
504 if (rtlpriv->stats.rx_evm_percentage[stream] == 0) {
505 rtlpriv->stats.rx_evm_percentage[stream] =
506 pstats->rx_mimo_signalquality[stream];
507 }
508
509 rtlpriv->stats.rx_evm_percentage[stream] =
510 ((rtlpriv->stats.rx_evm_percentage[stream] *
511 (RX_SMOOTH_FACTOR - 1)) +
512 (pstats->rx_mimo_signalquality[stream] *
513 1)) / (RX_SMOOTH_FACTOR);
514 }
515 }
516}
517
518static void _rtl92se_process_ui_link_quality(struct ieee80211_hw *hw,
519 struct rtl_stats *pstats)
520{
521 struct rtl_priv *rtlpriv = rtl_priv(hw);
522 u32 last_evm = 0, tmpval;
523
524 if (pstats->signalquality != 0) {
525 if (pstats->packet_toself || pstats->packet_beacon) {
526
527 if (rtlpriv->stats.ui_link_quality.total_num++ >=
528 PHY_LINKQUALITY_SLID_WIN_MAX) {
529 rtlpriv->stats.ui_link_quality.total_num =
530 PHY_LINKQUALITY_SLID_WIN_MAX;
531 last_evm =
532 rtlpriv->stats.ui_link_quality.elements[
533 rtlpriv->stats.ui_link_quality.index];
534 rtlpriv->stats.ui_link_quality.total_val -=
535 last_evm;
536 }
537
538 rtlpriv->stats.ui_link_quality.total_val +=
539 pstats->signalquality;
540 rtlpriv->stats.ui_link_quality.elements[
541 rtlpriv->stats.ui_link_quality.index++] =
542 pstats->signalquality;
543
544 if (rtlpriv->stats.ui_link_quality.index >=
545 PHY_LINKQUALITY_SLID_WIN_MAX)
546 rtlpriv->stats.ui_link_quality.index = 0;
547
548 tmpval = rtlpriv->stats.ui_link_quality.total_val /
549 rtlpriv->stats.ui_link_quality.total_num;
550 rtlpriv->stats.signal_quality = tmpval;
551
552 rtlpriv->stats.last_sigstrength_inpercent = tmpval;
553
554 rtl_92s_process_streams(hw, pstats);
555
556 }
557 }
558}
559
560static void _rtl92se_process_phyinfo(struct ieee80211_hw *hw,
561 u8 *buffer,
562 struct rtl_stats *pcurrent_stats)
563{
564
565 if (!pcurrent_stats->packet_matchbssid &&
566 !pcurrent_stats->packet_beacon)
567 return;
568
569 _rtl92se_process_ui_rssi(hw, pcurrent_stats);
570 _rtl92se_process_pwdb(hw, pcurrent_stats);
571 _rtl92se_process_ui_link_quality(hw, pcurrent_stats);
572}
573
574static void _rtl92se_translate_rx_signal_stuff(struct ieee80211_hw *hw,
575 struct sk_buff *skb, struct rtl_stats *pstats,
576 u8 *pdesc, struct rx_fwinfo *p_drvinfo)
577{
578 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
579 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
580
581 struct ieee80211_hdr *hdr;
582 u8 *tmp_buf;
583 u8 *praddr;
584 u8 *psaddr;
585 __le16 fc;
586 u16 type, cfc;
587 bool packet_matchbssid, packet_toself, packet_beacon;
588
589 tmp_buf = skb->data + pstats->rx_drvinfo_size + pstats->rx_bufshift;
590
591 hdr = (struct ieee80211_hdr *)tmp_buf;
592 fc = hdr->frame_control;
593 cfc = le16_to_cpu(fc);
594 type = WLAN_FC_GET_TYPE(fc);
595 praddr = hdr->addr1;
596 psaddr = hdr->addr2;
597
598 packet_matchbssid = ((IEEE80211_FTYPE_CTL != type) &&
599 (!compare_ether_addr(mac->bssid, (cfc & IEEE80211_FCTL_TODS) ?
600 hdr->addr1 : (cfc & IEEE80211_FCTL_FROMDS) ?
601 hdr->addr2 : hdr->addr3)) && (!pstats->hwerror) &&
602 (!pstats->crc) && (!pstats->icv));
603
604 packet_toself = packet_matchbssid &&
605 (!compare_ether_addr(praddr, rtlefuse->dev_addr));
606
607 if (ieee80211_is_beacon(fc))
608 packet_beacon = true;
609
610 _rtl92se_query_rxphystatus(hw, pstats, pdesc, p_drvinfo,
611 packet_matchbssid, packet_toself, packet_beacon);
612 _rtl92se_process_phyinfo(hw, tmp_buf, pstats);
613}
614
615bool rtl92se_rx_query_desc(struct ieee80211_hw *hw, struct rtl_stats *stats,
616 struct ieee80211_rx_status *rx_status, u8 *pdesc,
617 struct sk_buff *skb)
618{
619 struct rx_fwinfo *p_drvinfo;
620 u32 phystatus = (u32)GET_RX_STATUS_DESC_PHY_STATUS(pdesc);
621
622 stats->length = (u16)GET_RX_STATUS_DESC_PKT_LEN(pdesc);
623 stats->rx_drvinfo_size = (u8)GET_RX_STATUS_DESC_DRVINFO_SIZE(pdesc) * 8;
624 stats->rx_bufshift = (u8)(GET_RX_STATUS_DESC_SHIFT(pdesc) & 0x03);
625 stats->icv = (u16)GET_RX_STATUS_DESC_ICV(pdesc);
626 stats->crc = (u16)GET_RX_STATUS_DESC_CRC32(pdesc);
627 stats->hwerror = (u16)(stats->crc | stats->icv);
628 stats->decrypted = !GET_RX_STATUS_DESC_SWDEC(pdesc);
629
630 stats->rate = (u8)GET_RX_STATUS_DESC_RX_MCS(pdesc);
631 stats->shortpreamble = (u16)GET_RX_STATUS_DESC_SPLCP(pdesc);
632 stats->isampdu = (bool)(GET_RX_STATUS_DESC_PAGGR(pdesc) == 1);
633 stats->timestamp_low = GET_RX_STATUS_DESC_TSFL(pdesc);
634 stats->rx_is40Mhzpacket = (bool)GET_RX_STATUS_DESC_BW(pdesc);
635
636 if (stats->hwerror)
637 return false;
638
639 rx_status->freq = hw->conf.channel->center_freq;
640 rx_status->band = hw->conf.channel->band;
641
642 if (GET_RX_STATUS_DESC_CRC32(pdesc))
643 rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
644
645 if (!GET_RX_STATUS_DESC_SWDEC(pdesc))
646 rx_status->flag |= RX_FLAG_DECRYPTED;
647
648 if (GET_RX_STATUS_DESC_BW(pdesc))
649 rx_status->flag |= RX_FLAG_40MHZ;
650
651 if (GET_RX_STATUS_DESC_RX_HT(pdesc))
652 rx_status->flag |= RX_FLAG_HT;
653
654 rx_status->flag |= RX_FLAG_MACTIME_MPDU;
655
656 if (stats->decrypted)
657 rx_status->flag |= RX_FLAG_DECRYPTED;
658
659 rx_status->rate_idx = _rtl92se_rate_mapping((bool)
660 GET_RX_STATUS_DESC_RX_HT(pdesc),
661 (u8)GET_RX_STATUS_DESC_RX_MCS(pdesc),
662 (bool)GET_RX_STATUS_DESC_PAGGR(pdesc));
663
664
665 rx_status->mactime = GET_RX_STATUS_DESC_TSFL(pdesc);
666 if (phystatus == true) {
667 p_drvinfo = (struct rx_fwinfo *)(skb->data +
668 stats->rx_bufshift);
669 _rtl92se_translate_rx_signal_stuff(hw, skb, stats, pdesc,
670 p_drvinfo);
671 }
672
673 /*rx_status->qual = stats->signal; */
674 rx_status->signal = stats->rssi + 10;
675 /*rx_status->noise = -stats->noise; */
676
677 return true;
678}
679
680void rtl92se_tx_fill_desc(struct ieee80211_hw *hw,
681 struct ieee80211_hdr *hdr, u8 *pdesc_tx,
682 struct ieee80211_tx_info *info, struct sk_buff *skb,
683 u8 hw_queue, struct rtl_tcb_desc *ptcb_desc)
684{
685 struct rtl_priv *rtlpriv = rtl_priv(hw);
686 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
687 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
688 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
689 struct ieee80211_sta *sta = info->control.sta;
690 u8 *pdesc = (u8 *) pdesc_tx;
691 u16 seq_number;
692 __le16 fc = hdr->frame_control;
693 u8 reserved_macid = 0;
694 u8 fw_qsel = _rtl92se_map_hwqueue_to_fwqueue(skb, hw_queue);
695 bool firstseg = (!(hdr->seq_ctrl & cpu_to_le16(IEEE80211_SCTL_FRAG)));
696 bool lastseg = (!(hdr->frame_control &
697 cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)));
698 dma_addr_t mapping = pci_map_single(rtlpci->pdev, skb->data, skb->len,
699 PCI_DMA_TODEVICE);
700 u8 bw_40 = 0;
701
702 if (mac->opmode == NL80211_IFTYPE_STATION) {
703 bw_40 = mac->bw_40;
704 } else if (mac->opmode == NL80211_IFTYPE_AP ||
705 mac->opmode == NL80211_IFTYPE_ADHOC) {
706 if (sta)
707 bw_40 = sta->ht_cap.cap &
708 IEEE80211_HT_CAP_SUP_WIDTH_20_40;
709 }
710
711 seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4;
712
713 rtl_get_tcb_desc(hw, info, sta, skb, ptcb_desc);
714
715 CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_DESC_SIZE_RTL8192S);
716
717 if (firstseg) {
718 if (rtlpriv->dm.useramask) {
719 /* set txdesc macId */
720 if (ptcb_desc->mac_id < 32) {
721 SET_TX_DESC_MACID(pdesc, ptcb_desc->mac_id);
722 reserved_macid |= ptcb_desc->mac_id;
723 }
724 }
725 SET_TX_DESC_RSVD_MACID(pdesc, reserved_macid);
726
727 SET_TX_DESC_TXHT(pdesc, ((ptcb_desc->hw_rate >=
728 DESC92S_RATEMCS0) ? 1 : 0));
729
730 if (rtlhal->version == VERSION_8192S_ACUT) {
731 if (ptcb_desc->hw_rate == DESC92S_RATE1M ||
732 ptcb_desc->hw_rate == DESC92S_RATE2M ||
733 ptcb_desc->hw_rate == DESC92S_RATE5_5M ||
734 ptcb_desc->hw_rate == DESC92S_RATE11M) {
735 ptcb_desc->hw_rate = DESC92S_RATE12M;
736 }
737 }
738
739 SET_TX_DESC_TX_RATE(pdesc, ptcb_desc->hw_rate);
740
741 if (ptcb_desc->use_shortgi || ptcb_desc->use_shortpreamble)
742 SET_TX_DESC_TX_SHORT(pdesc, 0);
743
744 /* Aggregation related */
745 if (info->flags & IEEE80211_TX_CTL_AMPDU)
746 SET_TX_DESC_AGG_ENABLE(pdesc, 1);
747
748 /* For AMPDU, we must insert SSN into TX_DESC */
749 SET_TX_DESC_SEQ(pdesc, seq_number);
750
751 /* Protection mode related */
752 /* For 92S, if RTS/CTS are set, HW will execute RTS. */
753 /* We choose only one protection mode to execute */
754 SET_TX_DESC_RTS_ENABLE(pdesc, ((ptcb_desc->rts_enable &&
755 !ptcb_desc->cts_enable) ? 1 : 0));
756 SET_TX_DESC_CTS_ENABLE(pdesc, ((ptcb_desc->cts_enable) ?
757 1 : 0));
758 SET_TX_DESC_RTS_STBC(pdesc, ((ptcb_desc->rts_stbc) ? 1 : 0));
759
760 SET_TX_DESC_RTS_RATE(pdesc, ptcb_desc->rts_rate);
761 SET_TX_DESC_RTS_BANDWIDTH(pdesc, 0);
762 SET_TX_DESC_RTS_SUB_CARRIER(pdesc, ptcb_desc->rts_sc);
763 SET_TX_DESC_RTS_SHORT(pdesc, ((ptcb_desc->rts_rate <=
764 DESC92S_RATE54M) ?
765 (ptcb_desc->rts_use_shortpreamble ? 1 : 0)
766 : (ptcb_desc->rts_use_shortgi ? 1 : 0)));
767
768
769 /* Set Bandwidth and sub-channel settings. */
770 if (bw_40) {
771 if (ptcb_desc->packet_bw) {
772 SET_TX_DESC_TX_BANDWIDTH(pdesc, 1);
773 /* use duplicated mode */
774 SET_TX_DESC_TX_SUB_CARRIER(pdesc, 0);
775 } else {
776 SET_TX_DESC_TX_BANDWIDTH(pdesc, 0);
777 SET_TX_DESC_TX_SUB_CARRIER(pdesc,
778 mac->cur_40_prime_sc);
779 }
780 } else {
781 SET_TX_DESC_TX_BANDWIDTH(pdesc, 0);
782 SET_TX_DESC_TX_SUB_CARRIER(pdesc, 0);
783 }
784
785 /* 3 Fill necessary field in First Descriptor */
786 /*DWORD 0*/
787 SET_TX_DESC_LINIP(pdesc, 0);
788 SET_TX_DESC_OFFSET(pdesc, 32);
789 SET_TX_DESC_PKT_SIZE(pdesc, (u16) skb->len);
790
791 /*DWORD 1*/
792 SET_TX_DESC_RA_BRSR_ID(pdesc, ptcb_desc->ratr_index);
793
794 /* Fill security related */
795 if (info->control.hw_key) {
796 struct ieee80211_key_conf *keyconf;
797
798 keyconf = info->control.hw_key;
799 switch (keyconf->cipher) {
800 case WLAN_CIPHER_SUITE_WEP40:
801 case WLAN_CIPHER_SUITE_WEP104:
802 SET_TX_DESC_SEC_TYPE(pdesc, 0x1);
803 break;
804 case WLAN_CIPHER_SUITE_TKIP:
805 SET_TX_DESC_SEC_TYPE(pdesc, 0x2);
806 break;
807 case WLAN_CIPHER_SUITE_CCMP:
808 SET_TX_DESC_SEC_TYPE(pdesc, 0x3);
809 break;
810 default:
811 SET_TX_DESC_SEC_TYPE(pdesc, 0x0);
812 break;
813
814 }
815 }
816
817 /* Set Packet ID */
818 SET_TX_DESC_PACKET_ID(pdesc, 0);
819
820 /* We will assign magement queue to BK. */
821 SET_TX_DESC_QUEUE_SEL(pdesc, fw_qsel);
822
823 /* Alwasy enable all rate fallback range */
824 SET_TX_DESC_DATA_RATE_FB_LIMIT(pdesc, 0x1F);
825
826 /* Fix: I don't kown why hw use 6.5M to tx when set it */
827 SET_TX_DESC_USER_RATE(pdesc,
828 ptcb_desc->use_driver_rate ? 1 : 0);
829
830 /* Set NON_QOS bit. */
831 if (!ieee80211_is_data_qos(fc))
832 SET_TX_DESC_NON_QOS(pdesc, 1);
833
834 }
835
836 /* Fill fields that are required to be initialized
837 * in all of the descriptors */
838 /*DWORD 0 */
839 SET_TX_DESC_FIRST_SEG(pdesc, (firstseg ? 1 : 0));
840 SET_TX_DESC_LAST_SEG(pdesc, (lastseg ? 1 : 0));
841
842 /* DWORD 7 */
843 SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) skb->len);
844
845 /* DOWRD 8 */
846 SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, cpu_to_le32(mapping));
847
848 RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, ("\n"));
849}
850
851void rtl92se_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc,
852 bool firstseg, bool lastseg, struct sk_buff *skb)
853{
854 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
855 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
856 struct rtl_tcb_desc *tcb_desc = (struct rtl_tcb_desc *)(skb->cb);
857
858 dma_addr_t mapping = pci_map_single(rtlpci->pdev, skb->data, skb->len,
859 PCI_DMA_TODEVICE);
860
861 /* Clear all status */
862 CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_CMDDESC_SIZE_RTL8192S);
863
864 /* This bit indicate this packet is used for FW download. */
865 if (tcb_desc->cmd_or_init == DESC_PACKET_TYPE_INIT) {
866 /* For firmware downlaod we only need to set LINIP */
867 SET_TX_DESC_LINIP(pdesc, tcb_desc->last_inipkt);
868
869 /* 92SE must set as 1 for firmware download HW DMA error */
870 SET_TX_DESC_FIRST_SEG(pdesc, 1);
871 SET_TX_DESC_LAST_SEG(pdesc, 1);
872
873 /* 92SE need not to set TX packet size when firmware download */
874 SET_TX_DESC_PKT_SIZE(pdesc, (u16)(skb->len));
875 SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16)(skb->len));
876 SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, cpu_to_le32(mapping));
877
878 SET_TX_DESC_OWN(pdesc, 1);
879 } else { /* H2C Command Desc format (Host TXCMD) */
880 /* 92SE must set as 1 for firmware download HW DMA error */
881 SET_TX_DESC_FIRST_SEG(pdesc, 1);
882 SET_TX_DESC_LAST_SEG(pdesc, 1);
883
884 SET_TX_DESC_OFFSET(pdesc, 0x20);
885
886 /* Buffer size + command header */
887 SET_TX_DESC_PKT_SIZE(pdesc, (u16)(skb->len));
888 /* Fixed queue of H2C command */
889 SET_TX_DESC_QUEUE_SEL(pdesc, 0x13);
890
891 SET_BITS_TO_LE_4BYTE(skb->data, 24, 7, rtlhal->h2c_txcmd_seq);
892
893 SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16)(skb->len));
894 SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, cpu_to_le32(mapping));
895
896 SET_TX_DESC_OWN(pdesc, 1);
897
898 }
899}
900
901void rtl92se_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val)
902{
903 if (istx == true) {
904 switch (desc_name) {
905 case HW_DESC_OWN:
906 SET_TX_DESC_OWN(pdesc, 1);
907 break;
908 case HW_DESC_TX_NEXTDESC_ADDR:
909 SET_TX_DESC_NEXT_DESC_ADDRESS(pdesc, *(u32 *) val);
910 break;
911 default:
912 RT_ASSERT(false, ("ERR txdesc :%d not process\n",
913 desc_name));
914 break;
915 }
916 } else {
917 switch (desc_name) {
918 case HW_DESC_RXOWN:
919 SET_RX_STATUS_DESC_OWN(pdesc, 1);
920 break;
921 case HW_DESC_RXBUFF_ADDR:
922 SET_RX_STATUS__DESC_BUFF_ADDR(pdesc, *(u32 *) val);
923 break;
924 case HW_DESC_RXPKT_LEN:
925 SET_RX_STATUS_DESC_PKT_LEN(pdesc, *(u32 *) val);
926 break;
927 case HW_DESC_RXERO:
928 SET_RX_STATUS_DESC_EOR(pdesc, 1);
929 break;
930 default:
931 RT_ASSERT(false, ("ERR rxdesc :%d not process\n",
932 desc_name));
933 break;
934 }
935 }
936}
937
938u32 rtl92se_get_desc(u8 *desc, bool istx, u8 desc_name)
939{
940 u32 ret = 0;
941
942 if (istx == true) {
943 switch (desc_name) {
944 case HW_DESC_OWN:
945 ret = GET_TX_DESC_OWN(desc);
946 break;
947 case HW_DESC_TXBUFF_ADDR:
948 ret = GET_TX_DESC_TX_BUFFER_ADDRESS(desc);
949 break;
950 default:
951 RT_ASSERT(false, ("ERR txdesc :%d not process\n",
952 desc_name));
953 break;
954 }
955 } else {
956 switch (desc_name) {
957 case HW_DESC_OWN:
958 ret = GET_RX_STATUS_DESC_OWN(desc);
959 break;
960 case HW_DESC_RXPKT_LEN:
961 ret = GET_RX_STATUS_DESC_PKT_LEN(desc);
962 break;
963 default:
964 RT_ASSERT(false, ("ERR rxdesc :%d not process\n",
965 desc_name));
966 break;
967 }
968 }
969 return ret;
970}
971
972void rtl92se_tx_polling(struct ieee80211_hw *hw, u8 hw_queue)
973{
974 struct rtl_priv *rtlpriv = rtl_priv(hw);
975 rtl_write_word(rtlpriv, TP_POLL, BIT(0) << (hw_queue));
976}
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/trx.h b/drivers/net/wireless/rtlwifi/rtl8192se/trx.h
new file mode 100644
index 000000000000..05862c51b861
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/trx.h
@@ -0,0 +1,45 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2009-2010 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29#ifndef __REALTEK_PCI92SE_TRX_H__
30#define __REALTEK_PCI92SE_TRX_H__
31
32void rtl92se_tx_fill_desc(struct ieee80211_hw *hw, struct ieee80211_hdr *hdr,
33 u8 *pdesc, struct ieee80211_tx_info *info,
34 struct sk_buff *skb, u8 hw_queue,
35 struct rtl_tcb_desc *ptcb_desc);
36void rtl92se_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc, bool firstseg,
37 bool lastseg, struct sk_buff *skb);
38bool rtl92se_rx_query_desc(struct ieee80211_hw *hw, struct rtl_stats *stats,
39 struct ieee80211_rx_status *rx_status, u8 *pdesc,
40 struct sk_buff *skb);
41void rtl92se_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val);
42u32 rtl92se_get_desc(u8 *pdesc, bool istx, u8 desc_name);
43void rtl92se_tx_polling(struct ieee80211_hw *hw, u8 hw_queue);
44
45#endif
diff --git a/drivers/net/wireless/wl12xx/acx.c b/drivers/net/wireless/wl12xx/acx.c
index a5c9c0aff83f..c6ee530e5bf7 100644
--- a/drivers/net/wireless/wl12xx/acx.c
+++ b/drivers/net/wireless/wl12xx/acx.c
@@ -325,12 +325,19 @@ out:
325 return ret; 325 return ret;
326} 326}
327 327
328int wl1271_acx_rts_threshold(struct wl1271 *wl, u16 rts_threshold) 328int wl1271_acx_rts_threshold(struct wl1271 *wl, u32 rts_threshold)
329{ 329{
330 struct acx_rts_threshold *rts; 330 struct acx_rts_threshold *rts;
331 int ret; 331 int ret;
332 332
333 wl1271_debug(DEBUG_ACX, "acx rts threshold"); 333 /*
334 * If the RTS threshold is not configured or out of range, use the
335 * default value.
336 */
337 if (rts_threshold > IEEE80211_MAX_RTS_THRESHOLD)
338 rts_threshold = wl->conf.rx.rts_threshold;
339
340 wl1271_debug(DEBUG_ACX, "acx rts threshold: %d", rts_threshold);
334 341
335 rts = kzalloc(sizeof(*rts), GFP_KERNEL); 342 rts = kzalloc(sizeof(*rts), GFP_KERNEL);
336 if (!rts) { 343 if (!rts) {
@@ -338,7 +345,7 @@ int wl1271_acx_rts_threshold(struct wl1271 *wl, u16 rts_threshold)
338 goto out; 345 goto out;
339 } 346 }
340 347
341 rts->threshold = cpu_to_le16(rts_threshold); 348 rts->threshold = cpu_to_le16((u16)rts_threshold);
342 349
343 ret = wl1271_cmd_configure(wl, DOT11_RTS_THRESHOLD, rts, sizeof(*rts)); 350 ret = wl1271_cmd_configure(wl, DOT11_RTS_THRESHOLD, rts, sizeof(*rts));
344 if (ret < 0) { 351 if (ret < 0) {
@@ -540,13 +547,13 @@ out:
540 return ret; 547 return ret;
541} 548}
542 549
543int wl1271_acx_sg_cfg(struct wl1271 *wl) 550int wl1271_acx_sta_sg_cfg(struct wl1271 *wl)
544{ 551{
545 struct acx_bt_wlan_coex_param *param; 552 struct acx_sta_bt_wlan_coex_param *param;
546 struct conf_sg_settings *c = &wl->conf.sg; 553 struct conf_sg_settings *c = &wl->conf.sg;
547 int i, ret; 554 int i, ret;
548 555
549 wl1271_debug(DEBUG_ACX, "acx sg cfg"); 556 wl1271_debug(DEBUG_ACX, "acx sg sta cfg");
550 557
551 param = kzalloc(sizeof(*param), GFP_KERNEL); 558 param = kzalloc(sizeof(*param), GFP_KERNEL);
552 if (!param) { 559 if (!param) {
@@ -555,8 +562,38 @@ int wl1271_acx_sg_cfg(struct wl1271 *wl)
555 } 562 }
556 563
557 /* BT-WLAN coext parameters */ 564 /* BT-WLAN coext parameters */
558 for (i = 0; i < CONF_SG_PARAMS_MAX; i++) 565 for (i = 0; i < CONF_SG_STA_PARAMS_MAX; i++)
559 param->params[i] = cpu_to_le32(c->params[i]); 566 param->params[i] = cpu_to_le32(c->sta_params[i]);
567 param->param_idx = CONF_SG_PARAMS_ALL;
568
569 ret = wl1271_cmd_configure(wl, ACX_SG_CFG, param, sizeof(*param));
570 if (ret < 0) {
571 wl1271_warning("failed to set sg config: %d", ret);
572 goto out;
573 }
574
575out:
576 kfree(param);
577 return ret;
578}
579
580int wl1271_acx_ap_sg_cfg(struct wl1271 *wl)
581{
582 struct acx_ap_bt_wlan_coex_param *param;
583 struct conf_sg_settings *c = &wl->conf.sg;
584 int i, ret;
585
586 wl1271_debug(DEBUG_ACX, "acx sg ap cfg");
587
588 param = kzalloc(sizeof(*param), GFP_KERNEL);
589 if (!param) {
590 ret = -ENOMEM;
591 goto out;
592 }
593
594 /* BT-WLAN coext parameters */
595 for (i = 0; i < CONF_SG_AP_PARAMS_MAX; i++)
596 param->params[i] = cpu_to_le32(c->ap_params[i]);
560 param->param_idx = CONF_SG_PARAMS_ALL; 597 param->param_idx = CONF_SG_PARAMS_ALL;
561 598
562 ret = wl1271_cmd_configure(wl, ACX_SG_CFG, param, sizeof(*param)); 599 ret = wl1271_cmd_configure(wl, ACX_SG_CFG, param, sizeof(*param));
@@ -804,7 +841,8 @@ int wl1271_acx_ap_rate_policy(struct wl1271 *wl, struct conf_tx_rate_class *c,
804 struct acx_ap_rate_policy *acx; 841 struct acx_ap_rate_policy *acx;
805 int ret = 0; 842 int ret = 0;
806 843
807 wl1271_debug(DEBUG_ACX, "acx ap rate policy"); 844 wl1271_debug(DEBUG_ACX, "acx ap rate policy %d rates 0x%x",
845 idx, c->enabled_rates);
808 846
809 acx = kzalloc(sizeof(*acx), GFP_KERNEL); 847 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
810 if (!acx) { 848 if (!acx) {
@@ -898,12 +936,19 @@ out:
898 return ret; 936 return ret;
899} 937}
900 938
901int wl1271_acx_frag_threshold(struct wl1271 *wl, u16 frag_threshold) 939int wl1271_acx_frag_threshold(struct wl1271 *wl, u32 frag_threshold)
902{ 940{
903 struct acx_frag_threshold *acx; 941 struct acx_frag_threshold *acx;
904 int ret = 0; 942 int ret = 0;
905 943
906 wl1271_debug(DEBUG_ACX, "acx frag threshold"); 944 /*
945 * If the fragmentation is not configured or out of range, use the
946 * default value.
947 */
948 if (frag_threshold > IEEE80211_MAX_FRAG_THRESHOLD)
949 frag_threshold = wl->conf.tx.frag_threshold;
950
951 wl1271_debug(DEBUG_ACX, "acx frag threshold: %d", frag_threshold);
907 952
908 acx = kzalloc(sizeof(*acx), GFP_KERNEL); 953 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
909 954
@@ -912,7 +957,7 @@ int wl1271_acx_frag_threshold(struct wl1271 *wl, u16 frag_threshold)
912 goto out; 957 goto out;
913 } 958 }
914 959
915 acx->frag_threshold = cpu_to_le16(frag_threshold); 960 acx->frag_threshold = cpu_to_le16((u16)frag_threshold);
916 ret = wl1271_cmd_configure(wl, ACX_FRAG_CFG, acx, sizeof(*acx)); 961 ret = wl1271_cmd_configure(wl, ACX_FRAG_CFG, acx, sizeof(*acx));
917 if (ret < 0) { 962 if (ret < 0) {
918 wl1271_warning("Setting of frag threshold failed: %d", ret); 963 wl1271_warning("Setting of frag threshold failed: %d", ret);
@@ -954,6 +999,7 @@ out:
954int wl1271_acx_ap_mem_cfg(struct wl1271 *wl) 999int wl1271_acx_ap_mem_cfg(struct wl1271 *wl)
955{ 1000{
956 struct wl1271_acx_ap_config_memory *mem_conf; 1001 struct wl1271_acx_ap_config_memory *mem_conf;
1002 struct conf_memory_settings *mem;
957 int ret; 1003 int ret;
958 1004
959 wl1271_debug(DEBUG_ACX, "wl1271 mem cfg"); 1005 wl1271_debug(DEBUG_ACX, "wl1271 mem cfg");
@@ -964,14 +1010,21 @@ int wl1271_acx_ap_mem_cfg(struct wl1271 *wl)
964 goto out; 1010 goto out;
965 } 1011 }
966 1012
1013 if (wl->chip.id == CHIP_ID_1283_PG20)
1014 /*
1015 * FIXME: The 128x AP FW does not yet support dynamic memory.
1016 * Use the base memory configuration for 128x for now. This
1017 * should be fine tuned in the future.
1018 */
1019 mem = &wl->conf.mem_wl128x;
1020 else
1021 mem = &wl->conf.mem_wl127x;
1022
967 /* memory config */ 1023 /* memory config */
968 /* FIXME: for now we always use mem_wl127x for AP, because it 1024 mem_conf->num_stations = mem->num_stations;
969 * doesn't support dynamic memory and we don't have the 1025 mem_conf->rx_mem_block_num = mem->rx_block_num;
970 * optimal values for wl128x without dynamic memory yet */ 1026 mem_conf->tx_min_mem_block_num = mem->tx_min_block_num;
971 mem_conf->num_stations = wl->conf.mem_wl127x.num_stations; 1027 mem_conf->num_ssid_profiles = mem->ssid_profiles;
972 mem_conf->rx_mem_block_num = wl->conf.mem_wl127x.rx_block_num;
973 mem_conf->tx_min_mem_block_num = wl->conf.mem_wl127x.tx_min_block_num;
974 mem_conf->num_ssid_profiles = wl->conf.mem_wl127x.ssid_profiles;
975 mem_conf->total_tx_descriptors = cpu_to_le32(ACX_TX_DESCRIPTORS); 1028 mem_conf->total_tx_descriptors = cpu_to_le32(ACX_TX_DESCRIPTORS);
976 1029
977 ret = wl1271_cmd_configure(wl, ACX_MEM_CFG, mem_conf, 1030 ret = wl1271_cmd_configure(wl, ACX_MEM_CFG, mem_conf,
@@ -1524,46 +1577,22 @@ out:
1524 return ret; 1577 return ret;
1525} 1578}
1526 1579
1527int wl1271_acx_ap_max_tx_retry(struct wl1271 *wl) 1580int wl1271_acx_max_tx_retry(struct wl1271 *wl)
1528{ 1581{
1529 struct wl1271_acx_ap_max_tx_retry *acx = NULL; 1582 struct wl1271_acx_max_tx_retry *acx = NULL;
1530 int ret; 1583 int ret;
1531 1584
1532 wl1271_debug(DEBUG_ACX, "acx ap max tx retry"); 1585 wl1271_debug(DEBUG_ACX, "acx max tx retry");
1533 1586
1534 acx = kzalloc(sizeof(*acx), GFP_KERNEL); 1587 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1535 if (!acx) 1588 if (!acx)
1536 return -ENOMEM; 1589 return -ENOMEM;
1537 1590
1538 acx->max_tx_retry = cpu_to_le16(wl->conf.tx.max_tx_retries); 1591 acx->max_tx_retry = cpu_to_le16(wl->conf.tx.ap_max_tx_retries);
1539 1592
1540 ret = wl1271_cmd_configure(wl, ACX_MAX_TX_FAILURE, acx, sizeof(*acx)); 1593 ret = wl1271_cmd_configure(wl, ACX_MAX_TX_FAILURE, acx, sizeof(*acx));
1541 if (ret < 0) { 1594 if (ret < 0) {
1542 wl1271_warning("acx ap max tx retry failed: %d", ret); 1595 wl1271_warning("acx max tx retry failed: %d", ret);
1543 goto out;
1544 }
1545
1546out:
1547 kfree(acx);
1548 return ret;
1549}
1550
1551int wl1271_acx_sta_max_tx_retry(struct wl1271 *wl)
1552{
1553 struct wl1271_acx_sta_max_tx_retry *acx = NULL;
1554 int ret;
1555
1556 wl1271_debug(DEBUG_ACX, "acx sta max tx retry");
1557
1558 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1559 if (!acx)
1560 return -ENOMEM;
1561
1562 acx->max_tx_retry = wl->conf.tx.max_tx_retries;
1563
1564 ret = wl1271_cmd_configure(wl, ACX_CONS_TX_FAILURE, acx, sizeof(*acx));
1565 if (ret < 0) {
1566 wl1271_warning("acx sta max tx retry failed: %d", ret);
1567 goto out; 1596 goto out;
1568 } 1597 }
1569 1598
@@ -1626,3 +1655,68 @@ out:
1626 kfree(acx); 1655 kfree(acx);
1627 return ret; 1656 return ret;
1628} 1657}
1658
1659int wl1271_acx_set_ap_beacon_filter(struct wl1271 *wl, bool enable)
1660{
1661 struct acx_ap_beacon_filter *acx = NULL;
1662 int ret;
1663
1664 wl1271_debug(DEBUG_ACX, "acx set ap beacon filter: %d", enable);
1665
1666 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1667 if (!acx)
1668 return -ENOMEM;
1669
1670 acx->enable = enable ? 1 : 0;
1671
1672 ret = wl1271_cmd_configure(wl, ACX_AP_BEACON_FILTER_OPT,
1673 acx, sizeof(*acx));
1674 if (ret < 0) {
1675 wl1271_warning("acx set ap beacon filter failed: %d", ret);
1676 goto out;
1677 }
1678
1679out:
1680 kfree(acx);
1681 return ret;
1682}
1683
1684int wl1271_acx_fm_coex(struct wl1271 *wl)
1685{
1686 struct wl1271_acx_fm_coex *acx;
1687 int ret;
1688
1689 wl1271_debug(DEBUG_ACX, "acx fm coex setting");
1690
1691 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1692 if (!acx) {
1693 ret = -ENOMEM;
1694 goto out;
1695 }
1696
1697 acx->enable = wl->conf.fm_coex.enable;
1698 acx->swallow_period = wl->conf.fm_coex.swallow_period;
1699 acx->n_divider_fref_set_1 = wl->conf.fm_coex.n_divider_fref_set_1;
1700 acx->n_divider_fref_set_2 = wl->conf.fm_coex.n_divider_fref_set_2;
1701 acx->m_divider_fref_set_1 =
1702 cpu_to_le16(wl->conf.fm_coex.m_divider_fref_set_1);
1703 acx->m_divider_fref_set_2 =
1704 cpu_to_le16(wl->conf.fm_coex.m_divider_fref_set_2);
1705 acx->coex_pll_stabilization_time =
1706 cpu_to_le32(wl->conf.fm_coex.coex_pll_stabilization_time);
1707 acx->ldo_stabilization_time =
1708 cpu_to_le16(wl->conf.fm_coex.ldo_stabilization_time);
1709 acx->fm_disturbed_band_margin =
1710 wl->conf.fm_coex.fm_disturbed_band_margin;
1711 acx->swallow_clk_diff = wl->conf.fm_coex.swallow_clk_diff;
1712
1713 ret = wl1271_cmd_configure(wl, ACX_FM_COEX_CFG, acx, sizeof(*acx));
1714 if (ret < 0) {
1715 wl1271_warning("acx fm coex setting failed: %d", ret);
1716 goto out;
1717 }
1718
1719out:
1720 kfree(acx);
1721 return ret;
1722}
diff --git a/drivers/net/wireless/wl12xx/acx.h b/drivers/net/wireless/wl12xx/acx.h
index 942908cd53a3..9a895e3cc613 100644
--- a/drivers/net/wireless/wl12xx/acx.h
+++ b/drivers/net/wireless/wl12xx/acx.h
@@ -303,7 +303,6 @@ struct acx_beacon_filter_option {
303 struct acx_header header; 303 struct acx_header header;
304 304
305 u8 enable; 305 u8 enable;
306
307 /* 306 /*
308 * The number of beacons without the unicast TIM 307 * The number of beacons without the unicast TIM
309 * bit set that the firmware buffers before 308 * bit set that the firmware buffers before
@@ -370,14 +369,23 @@ struct acx_bt_wlan_coex {
370 u8 pad[3]; 369 u8 pad[3];
371} __packed; 370} __packed;
372 371
373struct acx_bt_wlan_coex_param { 372struct acx_sta_bt_wlan_coex_param {
374 struct acx_header header; 373 struct acx_header header;
375 374
376 __le32 params[CONF_SG_PARAMS_MAX]; 375 __le32 params[CONF_SG_STA_PARAMS_MAX];
377 u8 param_idx; 376 u8 param_idx;
378 u8 padding[3]; 377 u8 padding[3];
379} __packed; 378} __packed;
380 379
380struct acx_ap_bt_wlan_coex_param {
381 struct acx_header header;
382
383 __le32 params[CONF_SG_AP_PARAMS_MAX];
384 u8 param_idx;
385 u8 padding[3];
386} __packed;
387
388
381struct acx_dco_itrim_params { 389struct acx_dco_itrim_params {
382 struct acx_header header; 390 struct acx_header header;
383 391
@@ -1145,7 +1153,7 @@ struct wl1271_acx_fw_tsf_information {
1145 u8 padding[3]; 1153 u8 padding[3];
1146} __packed; 1154} __packed;
1147 1155
1148struct wl1271_acx_ap_max_tx_retry { 1156struct wl1271_acx_max_tx_retry {
1149 struct acx_header header; 1157 struct acx_header header;
1150 1158
1151 /* 1159 /*
@@ -1156,13 +1164,6 @@ struct wl1271_acx_ap_max_tx_retry {
1156 u8 padding_1[2]; 1164 u8 padding_1[2];
1157} __packed; 1165} __packed;
1158 1166
1159struct wl1271_acx_sta_max_tx_retry {
1160 struct acx_header header;
1161
1162 u8 max_tx_retry;
1163 u8 padding_1[3];
1164} __packed;
1165
1166struct wl1271_acx_config_ps { 1167struct wl1271_acx_config_ps {
1167 struct acx_header header; 1168 struct acx_header header;
1168 1169
@@ -1179,6 +1180,72 @@ struct wl1271_acx_inconnection_sta {
1179 u8 padding1[2]; 1180 u8 padding1[2];
1180} __packed; 1181} __packed;
1181 1182
1183struct acx_ap_beacon_filter {
1184 struct acx_header header;
1185
1186 u8 enable;
1187 u8 pad[3];
1188} __packed;
1189
1190/*
1191 * ACX_FM_COEX_CFG
1192 * set the FM co-existence parameters.
1193 */
1194struct wl1271_acx_fm_coex {
1195 struct acx_header header;
1196 /* enable(1) / disable(0) the FM Coex feature */
1197 u8 enable;
1198 /*
1199 * Swallow period used in COEX PLL swallowing mechanism.
1200 * 0xFF = use FW default
1201 */
1202 u8 swallow_period;
1203 /*
1204 * The N divider used in COEX PLL swallowing mechanism for Fref of
1205 * 38.4/19.2 Mhz. 0xFF = use FW default
1206 */
1207 u8 n_divider_fref_set_1;
1208 /*
1209 * The N divider used in COEX PLL swallowing mechanism for Fref of
1210 * 26/52 Mhz. 0xFF = use FW default
1211 */
1212 u8 n_divider_fref_set_2;
1213 /*
1214 * The M divider used in COEX PLL swallowing mechanism for Fref of
1215 * 38.4/19.2 Mhz. 0xFFFF = use FW default
1216 */
1217 __le16 m_divider_fref_set_1;
1218 /*
1219 * The M divider used in COEX PLL swallowing mechanism for Fref of
1220 * 26/52 Mhz. 0xFFFF = use FW default
1221 */
1222 __le16 m_divider_fref_set_2;
1223 /*
1224 * The time duration in uSec required for COEX PLL to stabilize.
1225 * 0xFFFFFFFF = use FW default
1226 */
1227 __le32 coex_pll_stabilization_time;
1228 /*
1229 * The time duration in uSec required for LDO to stabilize.
1230 * 0xFFFFFFFF = use FW default
1231 */
1232 __le16 ldo_stabilization_time;
1233 /*
1234 * The disturbed frequency band margin around the disturbed frequency
1235 * center (single sided).
1236 * For example, if 2 is configured, the following channels will be
1237 * considered disturbed channel:
1238 * 80 +- 0.1 MHz, 91 +- 0.1 MHz, 98 +- 0.1 MHz, 102 +- 0.1 MH
1239 * 0xFF = use FW default
1240 */
1241 u8 fm_disturbed_band_margin;
1242 /*
1243 * The swallow clock difference of the swallowing mechanism.
1244 * 0xFF = use FW default
1245 */
1246 u8 swallow_clk_diff;
1247} __packed;
1248
1182enum { 1249enum {
1183 ACX_WAKE_UP_CONDITIONS = 0x0002, 1250 ACX_WAKE_UP_CONDITIONS = 0x0002,
1184 ACX_MEM_CFG = 0x0003, 1251 ACX_MEM_CFG = 0x0003,
@@ -1197,6 +1264,7 @@ enum {
1197 ACX_TID_CFG = 0x001A, 1264 ACX_TID_CFG = 0x001A,
1198 ACX_PS_RX_STREAMING = 0x001B, 1265 ACX_PS_RX_STREAMING = 0x001B,
1199 ACX_BEACON_FILTER_OPT = 0x001F, 1266 ACX_BEACON_FILTER_OPT = 0x001F,
1267 ACX_AP_BEACON_FILTER_OPT = 0x0020,
1200 ACX_NOISE_HIST = 0x0021, 1268 ACX_NOISE_HIST = 0x0021,
1201 ACX_HDK_VERSION = 0x0022, /* ??? */ 1269 ACX_HDK_VERSION = 0x0022, /* ??? */
1202 ACX_PD_THRESHOLD = 0x0023, 1270 ACX_PD_THRESHOLD = 0x0023,
@@ -1208,6 +1276,7 @@ enum {
1208 ACX_BCN_DTIM_OPTIONS = 0x0031, 1276 ACX_BCN_DTIM_OPTIONS = 0x0031,
1209 ACX_SG_ENABLE = 0x0032, 1277 ACX_SG_ENABLE = 0x0032,
1210 ACX_SG_CFG = 0x0033, 1278 ACX_SG_CFG = 0x0033,
1279 ACX_FM_COEX_CFG = 0x0034,
1211 ACX_BEACON_FILTER_TABLE = 0x0038, 1280 ACX_BEACON_FILTER_TABLE = 0x0038,
1212 ACX_ARP_IP_FILTER = 0x0039, 1281 ACX_ARP_IP_FILTER = 0x0039,
1213 ACX_ROAMING_STATISTICS_TBL = 0x003B, 1282 ACX_ROAMING_STATISTICS_TBL = 0x003B,
@@ -1264,13 +1333,14 @@ int wl1271_acx_slot(struct wl1271 *wl, enum acx_slot_type slot_time);
1264int wl1271_acx_group_address_tbl(struct wl1271 *wl, bool enable, 1333int wl1271_acx_group_address_tbl(struct wl1271 *wl, bool enable,
1265 void *mc_list, u32 mc_list_len); 1334 void *mc_list, u32 mc_list_len);
1266int wl1271_acx_service_period_timeout(struct wl1271 *wl); 1335int wl1271_acx_service_period_timeout(struct wl1271 *wl);
1267int wl1271_acx_rts_threshold(struct wl1271 *wl, u16 rts_threshold); 1336int wl1271_acx_rts_threshold(struct wl1271 *wl, u32 rts_threshold);
1268int wl1271_acx_dco_itrim_params(struct wl1271 *wl); 1337int wl1271_acx_dco_itrim_params(struct wl1271 *wl);
1269int wl1271_acx_beacon_filter_opt(struct wl1271 *wl, bool enable_filter); 1338int wl1271_acx_beacon_filter_opt(struct wl1271 *wl, bool enable_filter);
1270int wl1271_acx_beacon_filter_table(struct wl1271 *wl); 1339int wl1271_acx_beacon_filter_table(struct wl1271 *wl);
1271int wl1271_acx_conn_monit_params(struct wl1271 *wl, bool enable); 1340int wl1271_acx_conn_monit_params(struct wl1271 *wl, bool enable);
1272int wl1271_acx_sg_enable(struct wl1271 *wl, bool enable); 1341int wl1271_acx_sg_enable(struct wl1271 *wl, bool enable);
1273int wl1271_acx_sg_cfg(struct wl1271 *wl); 1342int wl1271_acx_sta_sg_cfg(struct wl1271 *wl);
1343int wl1271_acx_ap_sg_cfg(struct wl1271 *wl);
1274int wl1271_acx_cca_threshold(struct wl1271 *wl); 1344int wl1271_acx_cca_threshold(struct wl1271 *wl);
1275int wl1271_acx_bcn_dtim_options(struct wl1271 *wl); 1345int wl1271_acx_bcn_dtim_options(struct wl1271 *wl);
1276int wl1271_acx_aid(struct wl1271 *wl, u16 aid); 1346int wl1271_acx_aid(struct wl1271 *wl, u16 aid);
@@ -1287,7 +1357,7 @@ int wl1271_acx_ac_cfg(struct wl1271 *wl, u8 ac, u8 cw_min, u16 cw_max,
1287int wl1271_acx_tid_cfg(struct wl1271 *wl, u8 queue_id, u8 channel_type, 1357int wl1271_acx_tid_cfg(struct wl1271 *wl, u8 queue_id, u8 channel_type,
1288 u8 tsid, u8 ps_scheme, u8 ack_policy, 1358 u8 tsid, u8 ps_scheme, u8 ack_policy,
1289 u32 apsd_conf0, u32 apsd_conf1); 1359 u32 apsd_conf0, u32 apsd_conf1);
1290int wl1271_acx_frag_threshold(struct wl1271 *wl, u16 frag_threshold); 1360int wl1271_acx_frag_threshold(struct wl1271 *wl, u32 frag_threshold);
1291int wl1271_acx_tx_config_options(struct wl1271 *wl); 1361int wl1271_acx_tx_config_options(struct wl1271 *wl);
1292int wl1271_acx_ap_mem_cfg(struct wl1271 *wl); 1362int wl1271_acx_ap_mem_cfg(struct wl1271 *wl);
1293int wl1271_acx_sta_mem_cfg(struct wl1271 *wl); 1363int wl1271_acx_sta_mem_cfg(struct wl1271 *wl);
@@ -1314,9 +1384,10 @@ int wl1271_acx_set_ba_session(struct wl1271 *wl,
1314int wl1271_acx_set_ba_receiver_session(struct wl1271 *wl, u8 tid_index, u16 ssn, 1384int wl1271_acx_set_ba_receiver_session(struct wl1271 *wl, u8 tid_index, u16 ssn,
1315 bool enable); 1385 bool enable);
1316int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime); 1386int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime);
1317int wl1271_acx_ap_max_tx_retry(struct wl1271 *wl); 1387int wl1271_acx_max_tx_retry(struct wl1271 *wl);
1318int wl1271_acx_sta_max_tx_retry(struct wl1271 *wl);
1319int wl1271_acx_config_ps(struct wl1271 *wl); 1388int wl1271_acx_config_ps(struct wl1271 *wl);
1320int wl1271_acx_set_inconnection_sta(struct wl1271 *wl, u8 *addr); 1389int wl1271_acx_set_inconnection_sta(struct wl1271 *wl, u8 *addr);
1390int wl1271_acx_set_ap_beacon_filter(struct wl1271 *wl, bool enable);
1391int wl1271_acx_fm_coex(struct wl1271 *wl);
1321 1392
1322#endif /* __WL1271_ACX_H__ */ 1393#endif /* __WL1271_ACX_H__ */
diff --git a/drivers/net/wireless/wl12xx/boot.c b/drivers/net/wireless/wl12xx/boot.c
index d263ebb6f974..b07f8b7e5f11 100644
--- a/drivers/net/wireless/wl12xx/boot.c
+++ b/drivers/net/wireless/wl12xx/boot.c
@@ -479,11 +479,11 @@ static int wl1271_boot_run_firmware(struct wl1271 *wl)
479 RSSI_SNR_TRIGGER_0_EVENT_ID | 479 RSSI_SNR_TRIGGER_0_EVENT_ID |
480 PSPOLL_DELIVERY_FAILURE_EVENT_ID | 480 PSPOLL_DELIVERY_FAILURE_EVENT_ID |
481 SOFT_GEMINI_SENSE_EVENT_ID | 481 SOFT_GEMINI_SENSE_EVENT_ID |
482 MAX_TX_RETRY_EVENT_ID; 482 PERIODIC_SCAN_REPORT_EVENT_ID |
483 PERIODIC_SCAN_COMPLETE_EVENT_ID;
483 484
484 if (wl->bss_type == BSS_TYPE_AP_BSS) 485 if (wl->bss_type == BSS_TYPE_AP_BSS)
485 wl->event_mask |= STA_REMOVE_COMPLETE_EVENT_ID | 486 wl->event_mask |= STA_REMOVE_COMPLETE_EVENT_ID;
486 INACTIVE_STA_EVENT_ID;
487 else 487 else
488 wl->event_mask |= DUMMY_PACKET_EVENT_ID; 488 wl->event_mask |= DUMMY_PACKET_EVENT_ID;
489 489
diff --git a/drivers/net/wireless/wl12xx/cmd.c b/drivers/net/wireless/wl12xx/cmd.c
index 69d24f35cd9a..42935ac72663 100644
--- a/drivers/net/wireless/wl12xx/cmd.c
+++ b/drivers/net/wireless/wl12xx/cmd.c
@@ -76,7 +76,7 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len,
76 if (time_after(jiffies, timeout)) { 76 if (time_after(jiffies, timeout)) {
77 wl1271_error("command complete timeout"); 77 wl1271_error("command complete timeout");
78 ret = -ETIMEDOUT; 78 ret = -ETIMEDOUT;
79 goto out; 79 goto fail;
80 } 80 }
81 81
82 poll_count++; 82 poll_count++;
@@ -96,14 +96,17 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len,
96 status = le16_to_cpu(cmd->status); 96 status = le16_to_cpu(cmd->status);
97 if (status != CMD_STATUS_SUCCESS) { 97 if (status != CMD_STATUS_SUCCESS) {
98 wl1271_error("command execute failure %d", status); 98 wl1271_error("command execute failure %d", status);
99 ieee80211_queue_work(wl->hw, &wl->recovery_work);
100 ret = -EIO; 99 ret = -EIO;
100 goto fail;
101 } 101 }
102 102
103 wl1271_write32(wl, ACX_REG_INTERRUPT_ACK, 103 wl1271_write32(wl, ACX_REG_INTERRUPT_ACK,
104 WL1271_ACX_INTR_CMD_COMPLETE); 104 WL1271_ACX_INTR_CMD_COMPLETE);
105 return 0;
105 106
106out: 107fail:
108 WARN_ON(1);
109 ieee80211_queue_work(wl->hw, &wl->recovery_work);
107 return ret; 110 return ret;
108} 111}
109 112
@@ -129,6 +132,9 @@ int wl1271_cmd_general_parms(struct wl1271 *wl)
129 if (gp->tx_bip_fem_auto_detect) 132 if (gp->tx_bip_fem_auto_detect)
130 answer = true; 133 answer = true;
131 134
135 /* Override the REF CLK from the NVS with the one from platform data */
136 gen_parms->general_params.ref_clock = wl->ref_clock;
137
132 ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), answer); 138 ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), answer);
133 if (ret < 0) { 139 if (ret < 0) {
134 wl1271_warning("CMD_INI_FILE_GENERAL_PARAM failed"); 140 wl1271_warning("CMD_INI_FILE_GENERAL_PARAM failed");
@@ -168,6 +174,10 @@ int wl128x_cmd_general_parms(struct wl1271 *wl)
168 if (gp->tx_bip_fem_auto_detect) 174 if (gp->tx_bip_fem_auto_detect)
169 answer = true; 175 answer = true;
170 176
177 /* Replace REF and TCXO CLKs with the ones from platform data */
178 gen_parms->general_params.ref_clock = wl->ref_clock;
179 gen_parms->general_params.tcxo_ref_clock = wl->tcxo_clock;
180
171 ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), answer); 181 ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), answer);
172 if (ret < 0) { 182 if (ret < 0) {
173 wl1271_warning("CMD_INI_FILE_GENERAL_PARAM failed"); 183 wl1271_warning("CMD_INI_FILE_GENERAL_PARAM failed");
@@ -1070,7 +1080,7 @@ int wl1271_cmd_start_bss(struct wl1271 *wl)
1070 1080
1071 memcpy(cmd->bssid, bss_conf->bssid, ETH_ALEN); 1081 memcpy(cmd->bssid, bss_conf->bssid, ETH_ALEN);
1072 1082
1073 cmd->aging_period = cpu_to_le16(wl->conf.tx.ap_aging_period); 1083 cmd->aging_period = cpu_to_le16(WL1271_AP_DEF_INACTIV_SEC);
1074 cmd->bss_index = WL1271_AP_BSS_INDEX; 1084 cmd->bss_index = WL1271_AP_BSS_INDEX;
1075 cmd->global_hlid = WL1271_AP_GLOBAL_HLID; 1085 cmd->global_hlid = WL1271_AP_GLOBAL_HLID;
1076 cmd->broadcast_hlid = WL1271_AP_BROADCAST_HLID; 1086 cmd->broadcast_hlid = WL1271_AP_BROADCAST_HLID;
diff --git a/drivers/net/wireless/wl12xx/conf.h b/drivers/net/wireless/wl12xx/conf.h
index e3de91528de8..1ab6c86aac40 100644
--- a/drivers/net/wireless/wl12xx/conf.h
+++ b/drivers/net/wireless/wl12xx/conf.h
@@ -396,12 +396,43 @@ enum {
396 CONF_SG_TEMP_PARAM_3, 396 CONF_SG_TEMP_PARAM_3,
397 CONF_SG_TEMP_PARAM_4, 397 CONF_SG_TEMP_PARAM_4,
398 CONF_SG_TEMP_PARAM_5, 398 CONF_SG_TEMP_PARAM_5,
399 CONF_SG_PARAMS_MAX, 399
400 /*
401 * AP beacon miss
402 *
403 * Range: 0 - 255
404 */
405 CONF_SG_AP_BEACON_MISS_TX,
406
407 /*
408 * AP RX window length
409 *
410 * Range: 0 - 50
411 */
412 CONF_SG_RX_WINDOW_LENGTH,
413
414 /*
415 * AP connection protection time
416 *
417 * Range: 0 - 5000
418 */
419 CONF_SG_AP_CONNECTION_PROTECTION_TIME,
420
421 CONF_SG_TEMP_PARAM_6,
422 CONF_SG_TEMP_PARAM_7,
423 CONF_SG_TEMP_PARAM_8,
424 CONF_SG_TEMP_PARAM_9,
425 CONF_SG_TEMP_PARAM_10,
426
427 CONF_SG_STA_PARAMS_MAX = CONF_SG_TEMP_PARAM_5 + 1,
428 CONF_SG_AP_PARAMS_MAX = CONF_SG_TEMP_PARAM_10 + 1,
429
400 CONF_SG_PARAMS_ALL = 0xff 430 CONF_SG_PARAMS_ALL = 0xff
401}; 431};
402 432
403struct conf_sg_settings { 433struct conf_sg_settings {
404 u32 params[CONF_SG_PARAMS_MAX]; 434 u32 sta_params[CONF_SG_STA_PARAMS_MAX];
435 u32 ap_params[CONF_SG_AP_PARAMS_MAX];
405 u8 state; 436 u8 state;
406}; 437};
407 438
@@ -509,6 +540,12 @@ struct conf_rx_settings {
509 CONF_HW_BIT_RATE_36MBPS | CONF_HW_BIT_RATE_48MBPS | \ 540 CONF_HW_BIT_RATE_36MBPS | CONF_HW_BIT_RATE_48MBPS | \
510 CONF_HW_BIT_RATE_54MBPS) 541 CONF_HW_BIT_RATE_54MBPS)
511 542
543#define CONF_TX_OFDM_RATES (CONF_HW_BIT_RATE_6MBPS | \
544 CONF_HW_BIT_RATE_12MBPS | CONF_HW_BIT_RATE_24MBPS | \
545 CONF_HW_BIT_RATE_36MBPS | CONF_HW_BIT_RATE_48MBPS | \
546 CONF_HW_BIT_RATE_54MBPS)
547
548
512/* 549/*
513 * Default rates for management traffic when operating in AP mode. This 550 * Default rates for management traffic when operating in AP mode. This
514 * should be configured according to the basic rate set of the AP 551 * should be configured according to the basic rate set of the AP
@@ -516,6 +553,13 @@ struct conf_rx_settings {
516#define CONF_TX_AP_DEFAULT_MGMT_RATES (CONF_HW_BIT_RATE_1MBPS | \ 553#define CONF_TX_AP_DEFAULT_MGMT_RATES (CONF_HW_BIT_RATE_1MBPS | \
517 CONF_HW_BIT_RATE_2MBPS | CONF_HW_BIT_RATE_5_5MBPS) 554 CONF_HW_BIT_RATE_2MBPS | CONF_HW_BIT_RATE_5_5MBPS)
518 555
556/*
557 * Default rates for working as IBSS. use 11b rates
558 */
559#define CONF_TX_IBSS_DEFAULT_RATES (CONF_HW_BIT_RATE_1MBPS | \
560 CONF_HW_BIT_RATE_2MBPS | CONF_HW_BIT_RATE_5_5MBPS | \
561 CONF_HW_BIT_RATE_11MBPS);
562
519struct conf_tx_rate_class { 563struct conf_tx_rate_class {
520 564
521 /* 565 /*
@@ -667,34 +711,10 @@ struct conf_tx_settings {
667 struct conf_tx_ac_category ac_conf[CONF_TX_MAX_AC_COUNT]; 711 struct conf_tx_ac_category ac_conf[CONF_TX_MAX_AC_COUNT];
668 712
669 /* 713 /*
670 * Configuration for rate classes in AP-mode. These rate classes 714 * AP-mode - allow this number of TX retries to a station before an
671 * are for the AC TX queues
672 */
673 struct conf_tx_rate_class ap_rc_conf[CONF_TX_MAX_AC_COUNT];
674
675 /*
676 * Management TX rate class for AP-mode.
677 */
678 struct conf_tx_rate_class ap_mgmt_conf;
679
680 /*
681 * Broadcast TX rate class for AP-mode.
682 */
683 struct conf_tx_rate_class ap_bcst_conf;
684
685 /*
686 * Allow this number of TX retries to a connected station/AP before an
687 * event is triggered from FW. 715 * event is triggered from FW.
688 * In AP-mode the hlids of unreachable stations are given in the
689 * "sta_tx_retry_exceeded" member in the event mailbox.
690 */
691 u8 max_tx_retries;
692
693 /*
694 * AP-mode - after this number of seconds a connected station is
695 * considered inactive.
696 */ 716 */
697 u16 ap_aging_period; 717 u16 ap_max_tx_retries;
698 718
699 /* 719 /*
700 * Configuration for TID parameters. 720 * Configuration for TID parameters.
@@ -1127,6 +1147,26 @@ struct conf_scan_settings {
1127 1147
1128}; 1148};
1129 1149
1150struct conf_sched_scan_settings {
1151 /* minimum time to wait on the channel for active scans (in TUs) */
1152 u16 min_dwell_time_active;
1153
1154 /* maximum time to wait on the channel for active scans (in TUs) */
1155 u16 max_dwell_time_active;
1156
1157 /* time to wait on the channel for passive scans (in TUs) */
1158 u32 dwell_time_passive;
1159
1160 /* number of probe requests to send on each channel in active scans */
1161 u8 num_probe_reqs;
1162
1163 /* RSSI threshold to be used for filtering */
1164 s8 rssi_threshold;
1165
1166 /* SNR threshold to be used for filtering */
1167 s8 snr_threshold;
1168};
1169
1130/* these are number of channels on the band divided by two, rounded up */ 1170/* these are number of channels on the band divided by two, rounded up */
1131#define CONF_TX_PWR_COMPENSATION_LEN_2 7 1171#define CONF_TX_PWR_COMPENSATION_LEN_2 7
1132#define CONF_TX_PWR_COMPENSATION_LEN_5 18 1172#define CONF_TX_PWR_COMPENSATION_LEN_5 18
@@ -1192,6 +1232,19 @@ struct conf_memory_settings {
1192 u8 tx_min; 1232 u8 tx_min;
1193}; 1233};
1194 1234
1235struct conf_fm_coex {
1236 u8 enable;
1237 u8 swallow_period;
1238 u8 n_divider_fref_set_1;
1239 u8 n_divider_fref_set_2;
1240 u16 m_divider_fref_set_1;
1241 u16 m_divider_fref_set_2;
1242 u32 coex_pll_stabilization_time;
1243 u16 ldo_stabilization_time;
1244 u8 fm_disturbed_band_margin;
1245 u8 swallow_clk_diff;
1246};
1247
1195struct conf_drv_settings { 1248struct conf_drv_settings {
1196 struct conf_sg_settings sg; 1249 struct conf_sg_settings sg;
1197 struct conf_rx_settings rx; 1250 struct conf_rx_settings rx;
@@ -1201,10 +1254,12 @@ struct conf_drv_settings {
1201 struct conf_pm_config_settings pm_config; 1254 struct conf_pm_config_settings pm_config;
1202 struct conf_roam_trigger_settings roam_trigger; 1255 struct conf_roam_trigger_settings roam_trigger;
1203 struct conf_scan_settings scan; 1256 struct conf_scan_settings scan;
1257 struct conf_sched_scan_settings sched_scan;
1204 struct conf_rf_settings rf; 1258 struct conf_rf_settings rf;
1205 struct conf_ht_setting ht; 1259 struct conf_ht_setting ht;
1206 struct conf_memory_settings mem_wl127x; 1260 struct conf_memory_settings mem_wl127x;
1207 struct conf_memory_settings mem_wl128x; 1261 struct conf_memory_settings mem_wl128x;
1262 struct conf_fm_coex fm_coex;
1208 u8 hci_io_ds; 1263 u8 hci_io_ds;
1209}; 1264};
1210 1265
diff --git a/drivers/net/wireless/wl12xx/debugfs.c b/drivers/net/wireless/wl12xx/debugfs.c
index 70ab1986788e..f1f8df9b6cd7 100644
--- a/drivers/net/wireless/wl12xx/debugfs.c
+++ b/drivers/net/wireless/wl12xx/debugfs.c
@@ -291,6 +291,242 @@ static const struct file_operations gpio_power_ops = {
291 .llseek = default_llseek, 291 .llseek = default_llseek,
292}; 292};
293 293
294static ssize_t start_recovery_write(struct file *file,
295 const char __user *user_buf,
296 size_t count, loff_t *ppos)
297{
298 struct wl1271 *wl = file->private_data;
299
300 mutex_lock(&wl->mutex);
301 ieee80211_queue_work(wl->hw, &wl->recovery_work);
302 mutex_unlock(&wl->mutex);
303
304 return count;
305}
306
307static const struct file_operations start_recovery_ops = {
308 .write = start_recovery_write,
309 .open = wl1271_open_file_generic,
310 .llseek = default_llseek,
311};
312
313static ssize_t driver_state_read(struct file *file, char __user *user_buf,
314 size_t count, loff_t *ppos)
315{
316 struct wl1271 *wl = file->private_data;
317 int res = 0;
318 char buf[1024];
319
320 mutex_lock(&wl->mutex);
321
322#define DRIVER_STATE_PRINT(x, fmt) \
323 (res += scnprintf(buf + res, sizeof(buf) - res,\
324 #x " = " fmt "\n", wl->x))
325
326#define DRIVER_STATE_PRINT_LONG(x) DRIVER_STATE_PRINT(x, "%ld")
327#define DRIVER_STATE_PRINT_INT(x) DRIVER_STATE_PRINT(x, "%d")
328#define DRIVER_STATE_PRINT_STR(x) DRIVER_STATE_PRINT(x, "%s")
329#define DRIVER_STATE_PRINT_LHEX(x) DRIVER_STATE_PRINT(x, "0x%lx")
330#define DRIVER_STATE_PRINT_HEX(x) DRIVER_STATE_PRINT(x, "0x%x")
331
332 DRIVER_STATE_PRINT_INT(tx_blocks_available);
333 DRIVER_STATE_PRINT_INT(tx_allocated_blocks);
334 DRIVER_STATE_PRINT_INT(tx_frames_cnt);
335 DRIVER_STATE_PRINT_LHEX(tx_frames_map[0]);
336 DRIVER_STATE_PRINT_INT(tx_queue_count);
337 DRIVER_STATE_PRINT_INT(tx_packets_count);
338 DRIVER_STATE_PRINT_INT(tx_results_count);
339 DRIVER_STATE_PRINT_LHEX(flags);
340 DRIVER_STATE_PRINT_INT(tx_blocks_freed[0]);
341 DRIVER_STATE_PRINT_INT(tx_blocks_freed[1]);
342 DRIVER_STATE_PRINT_INT(tx_blocks_freed[2]);
343 DRIVER_STATE_PRINT_INT(tx_blocks_freed[3]);
344 DRIVER_STATE_PRINT_INT(tx_security_last_seq);
345 DRIVER_STATE_PRINT_INT(rx_counter);
346 DRIVER_STATE_PRINT_INT(session_counter);
347 DRIVER_STATE_PRINT_INT(state);
348 DRIVER_STATE_PRINT_INT(bss_type);
349 DRIVER_STATE_PRINT_INT(channel);
350 DRIVER_STATE_PRINT_HEX(rate_set);
351 DRIVER_STATE_PRINT_HEX(basic_rate_set);
352 DRIVER_STATE_PRINT_HEX(basic_rate);
353 DRIVER_STATE_PRINT_INT(band);
354 DRIVER_STATE_PRINT_INT(beacon_int);
355 DRIVER_STATE_PRINT_INT(psm_entry_retry);
356 DRIVER_STATE_PRINT_INT(ps_poll_failures);
357 DRIVER_STATE_PRINT_HEX(filters);
358 DRIVER_STATE_PRINT_HEX(rx_config);
359 DRIVER_STATE_PRINT_HEX(rx_filter);
360 DRIVER_STATE_PRINT_INT(power_level);
361 DRIVER_STATE_PRINT_INT(rssi_thold);
362 DRIVER_STATE_PRINT_INT(last_rssi_event);
363 DRIVER_STATE_PRINT_INT(sg_enabled);
364 DRIVER_STATE_PRINT_INT(enable_11a);
365 DRIVER_STATE_PRINT_INT(noise);
366 DRIVER_STATE_PRINT_LHEX(ap_hlid_map[0]);
367 DRIVER_STATE_PRINT_INT(last_tx_hlid);
368 DRIVER_STATE_PRINT_INT(ba_support);
369 DRIVER_STATE_PRINT_HEX(ba_rx_bitmap);
370 DRIVER_STATE_PRINT_HEX(ap_fw_ps_map);
371 DRIVER_STATE_PRINT_LHEX(ap_ps_map);
372 DRIVER_STATE_PRINT_HEX(quirks);
373 DRIVER_STATE_PRINT_HEX(irq);
374 DRIVER_STATE_PRINT_HEX(ref_clock);
375 DRIVER_STATE_PRINT_HEX(tcxo_clock);
376 DRIVER_STATE_PRINT_HEX(hw_pg_ver);
377 DRIVER_STATE_PRINT_HEX(platform_quirks);
378 DRIVER_STATE_PRINT_HEX(chip.id);
379 DRIVER_STATE_PRINT_STR(chip.fw_ver_str);
380 DRIVER_STATE_PRINT_INT(sched_scanning);
381
382#undef DRIVER_STATE_PRINT_INT
383#undef DRIVER_STATE_PRINT_LONG
384#undef DRIVER_STATE_PRINT_HEX
385#undef DRIVER_STATE_PRINT_LHEX
386#undef DRIVER_STATE_PRINT_STR
387#undef DRIVER_STATE_PRINT
388
389 mutex_unlock(&wl->mutex);
390
391 return simple_read_from_buffer(user_buf, count, ppos, buf, res);
392}
393
394static const struct file_operations driver_state_ops = {
395 .read = driver_state_read,
396 .open = wl1271_open_file_generic,
397 .llseek = default_llseek,
398};
399
400static ssize_t dtim_interval_read(struct file *file, char __user *user_buf,
401 size_t count, loff_t *ppos)
402{
403 struct wl1271 *wl = file->private_data;
404 u8 value;
405
406 if (wl->conf.conn.wake_up_event == CONF_WAKE_UP_EVENT_DTIM ||
407 wl->conf.conn.wake_up_event == CONF_WAKE_UP_EVENT_N_DTIM)
408 value = wl->conf.conn.listen_interval;
409 else
410 value = 0;
411
412 return wl1271_format_buffer(user_buf, count, ppos, "%d\n", value);
413}
414
415static ssize_t dtim_interval_write(struct file *file,
416 const char __user *user_buf,
417 size_t count, loff_t *ppos)
418{
419 struct wl1271 *wl = file->private_data;
420 char buf[10];
421 size_t len;
422 unsigned long value;
423 int ret;
424
425 len = min(count, sizeof(buf) - 1);
426 if (copy_from_user(buf, user_buf, len))
427 return -EFAULT;
428 buf[len] = '\0';
429
430 ret = kstrtoul(buf, 0, &value);
431 if (ret < 0) {
432 wl1271_warning("illegal value for dtim_interval");
433 return -EINVAL;
434 }
435
436 if (value < 1 || value > 10) {
437 wl1271_warning("dtim value is not in valid range");
438 return -ERANGE;
439 }
440
441 mutex_lock(&wl->mutex);
442
443 wl->conf.conn.listen_interval = value;
444 /* for some reason there are different event types for 1 and >1 */
445 if (value == 1)
446 wl->conf.conn.wake_up_event = CONF_WAKE_UP_EVENT_DTIM;
447 else
448 wl->conf.conn.wake_up_event = CONF_WAKE_UP_EVENT_N_DTIM;
449
450 /*
451 * we don't reconfigure ACX_WAKE_UP_CONDITIONS now, so it will only
452 * take effect on the next time we enter psm.
453 */
454 mutex_unlock(&wl->mutex);
455 return count;
456}
457
458static const struct file_operations dtim_interval_ops = {
459 .read = dtim_interval_read,
460 .write = dtim_interval_write,
461 .open = wl1271_open_file_generic,
462 .llseek = default_llseek,
463};
464
465static ssize_t beacon_interval_read(struct file *file, char __user *user_buf,
466 size_t count, loff_t *ppos)
467{
468 struct wl1271 *wl = file->private_data;
469 u8 value;
470
471 if (wl->conf.conn.wake_up_event == CONF_WAKE_UP_EVENT_BEACON ||
472 wl->conf.conn.wake_up_event == CONF_WAKE_UP_EVENT_N_BEACONS)
473 value = wl->conf.conn.listen_interval;
474 else
475 value = 0;
476
477 return wl1271_format_buffer(user_buf, count, ppos, "%d\n", value);
478}
479
480static ssize_t beacon_interval_write(struct file *file,
481 const char __user *user_buf,
482 size_t count, loff_t *ppos)
483{
484 struct wl1271 *wl = file->private_data;
485 char buf[10];
486 size_t len;
487 unsigned long value;
488 int ret;
489
490 len = min(count, sizeof(buf) - 1);
491 if (copy_from_user(buf, user_buf, len))
492 return -EFAULT;
493 buf[len] = '\0';
494
495 ret = kstrtoul(buf, 0, &value);
496 if (ret < 0) {
497 wl1271_warning("illegal value for beacon_interval");
498 return -EINVAL;
499 }
500
501 if (value < 1 || value > 255) {
502 wl1271_warning("beacon interval value is not in valid range");
503 return -ERANGE;
504 }
505
506 mutex_lock(&wl->mutex);
507
508 wl->conf.conn.listen_interval = value;
509 /* for some reason there are different event types for 1 and >1 */
510 if (value == 1)
511 wl->conf.conn.wake_up_event = CONF_WAKE_UP_EVENT_BEACON;
512 else
513 wl->conf.conn.wake_up_event = CONF_WAKE_UP_EVENT_N_BEACONS;
514
515 /*
516 * we don't reconfigure ACX_WAKE_UP_CONDITIONS now, so it will only
517 * take effect on the next time we enter psm.
518 */
519 mutex_unlock(&wl->mutex);
520 return count;
521}
522
523static const struct file_operations beacon_interval_ops = {
524 .read = beacon_interval_read,
525 .write = beacon_interval_write,
526 .open = wl1271_open_file_generic,
527 .llseek = default_llseek,
528};
529
294static int wl1271_debugfs_add_files(struct wl1271 *wl, 530static int wl1271_debugfs_add_files(struct wl1271 *wl,
295 struct dentry *rootdir) 531 struct dentry *rootdir)
296{ 532{
@@ -399,6 +635,10 @@ static int wl1271_debugfs_add_files(struct wl1271 *wl,
399 DEBUGFS_ADD(excessive_retries, rootdir); 635 DEBUGFS_ADD(excessive_retries, rootdir);
400 636
401 DEBUGFS_ADD(gpio_power, rootdir); 637 DEBUGFS_ADD(gpio_power, rootdir);
638 DEBUGFS_ADD(start_recovery, rootdir);
639 DEBUGFS_ADD(driver_state, rootdir);
640 DEBUGFS_ADD(dtim_interval, rootdir);
641 DEBUGFS_ADD(beacon_interval, rootdir);
402 642
403 return 0; 643 return 0;
404 644
diff --git a/drivers/net/wireless/wl12xx/event.c b/drivers/net/wireless/wl12xx/event.c
index d7be3aec6fc3..c3c554cd6580 100644
--- a/drivers/net/wireless/wl12xx/event.c
+++ b/drivers/net/wireless/wl12xx/event.c
@@ -135,6 +135,13 @@ static int wl1271_event_ps_report(struct wl1271 *wl,
135 135
136 /* enable beacon early termination */ 136 /* enable beacon early termination */
137 ret = wl1271_acx_bet_enable(wl, true); 137 ret = wl1271_acx_bet_enable(wl, true);
138 if (ret < 0)
139 break;
140
141 if (wl->ps_compl) {
142 complete(wl->ps_compl);
143 wl->ps_compl = NULL;
144 }
138 break; 145 break;
139 default: 146 default:
140 break; 147 break;
@@ -174,8 +181,6 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox)
174 u32 vector; 181 u32 vector;
175 bool beacon_loss = false; 182 bool beacon_loss = false;
176 bool is_ap = (wl->bss_type == BSS_TYPE_AP_BSS); 183 bool is_ap = (wl->bss_type == BSS_TYPE_AP_BSS);
177 bool disconnect_sta = false;
178 unsigned long sta_bitmap = 0;
179 184
180 wl1271_event_mbox_dump(mbox); 185 wl1271_event_mbox_dump(mbox);
181 186
@@ -190,6 +195,22 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox)
190 wl1271_scan_stm(wl); 195 wl1271_scan_stm(wl);
191 } 196 }
192 197
198 if (vector & PERIODIC_SCAN_REPORT_EVENT_ID) {
199 wl1271_debug(DEBUG_EVENT, "PERIODIC_SCAN_REPORT_EVENT "
200 "(status 0x%0x)", mbox->scheduled_scan_status);
201
202 wl1271_scan_sched_scan_results(wl);
203 }
204
205 if (vector & PERIODIC_SCAN_COMPLETE_EVENT_ID) {
206 wl1271_debug(DEBUG_EVENT, "PERIODIC_SCAN_COMPLETE_EVENT "
207 "(status 0x%0x)", mbox->scheduled_scan_status);
208 if (wl->sched_scanning) {
209 wl1271_scan_sched_scan_stop(wl);
210 ieee80211_sched_scan_stopped(wl->hw);
211 }
212 }
213
193 /* disable dynamic PS when requested by the firmware */ 214 /* disable dynamic PS when requested by the firmware */
194 if (vector & SOFT_GEMINI_SENSE_EVENT_ID && 215 if (vector & SOFT_GEMINI_SENSE_EVENT_ID &&
195 wl->bss_type == BSS_TYPE_STA_BSS) { 216 wl->bss_type == BSS_TYPE_STA_BSS) {
@@ -237,54 +258,9 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox)
237 wl1271_tx_dummy_packet(wl); 258 wl1271_tx_dummy_packet(wl);
238 } 259 }
239 260
240 /*
241 * "TX retries exceeded" has a different meaning according to mode.
242 * In AP mode the offending station is disconnected. In STA mode we
243 * report connection loss.
244 */
245 if (vector & MAX_TX_RETRY_EVENT_ID) {
246 wl1271_debug(DEBUG_EVENT, "MAX_TX_RETRY_EVENT_ID");
247 if (is_ap) {
248 sta_bitmap |= le16_to_cpu(mbox->sta_tx_retry_exceeded);
249 disconnect_sta = true;
250 } else {
251 beacon_loss = true;
252 }
253 }
254
255 if ((vector & INACTIVE_STA_EVENT_ID) && is_ap) {
256 wl1271_debug(DEBUG_EVENT, "INACTIVE_STA_EVENT_ID");
257 sta_bitmap |= le16_to_cpu(mbox->sta_aging_status);
258 disconnect_sta = true;
259 }
260
261 if (wl->vif && beacon_loss) 261 if (wl->vif && beacon_loss)
262 ieee80211_connection_loss(wl->vif); 262 ieee80211_connection_loss(wl->vif);
263 263
264 if (is_ap && disconnect_sta) {
265 u32 num_packets = wl->conf.tx.max_tx_retries;
266 struct ieee80211_sta *sta;
267 const u8 *addr;
268 int h;
269
270 for (h = find_first_bit(&sta_bitmap, AP_MAX_LINKS);
271 h < AP_MAX_LINKS;
272 h = find_next_bit(&sta_bitmap, AP_MAX_LINKS, h+1)) {
273 if (!wl1271_is_active_sta(wl, h))
274 continue;
275
276 addr = wl->links[h].addr;
277
278 rcu_read_lock();
279 sta = ieee80211_find_sta(wl->vif, addr);
280 if (sta) {
281 wl1271_debug(DEBUG_EVENT, "remove sta %d", h);
282 ieee80211_report_low_ack(sta, num_packets);
283 }
284 rcu_read_unlock();
285 }
286 }
287
288 return 0; 264 return 0;
289} 265}
290 266
diff --git a/drivers/net/wireless/wl12xx/event.h b/drivers/net/wireless/wl12xx/event.h
index 7ae5a0821241..b6cf06e565a4 100644
--- a/drivers/net/wireless/wl12xx/event.h
+++ b/drivers/net/wireless/wl12xx/event.h
@@ -58,16 +58,13 @@ enum {
58 CHANNEL_SWITCH_COMPLETE_EVENT_ID = BIT(17), 58 CHANNEL_SWITCH_COMPLETE_EVENT_ID = BIT(17),
59 BSS_LOSE_EVENT_ID = BIT(18), 59 BSS_LOSE_EVENT_ID = BIT(18),
60 REGAINED_BSS_EVENT_ID = BIT(19), 60 REGAINED_BSS_EVENT_ID = BIT(19),
61 MAX_TX_RETRY_EVENT_ID = BIT(20), 61 ROAMING_TRIGGER_MAX_TX_RETRY_EVENT_ID = BIT(20),
62 /* STA: dummy paket for dynamic mem blocks */ 62 /* STA: dummy paket for dynamic mem blocks */
63 DUMMY_PACKET_EVENT_ID = BIT(21), 63 DUMMY_PACKET_EVENT_ID = BIT(21),
64 /* AP: STA remove complete */ 64 /* AP: STA remove complete */
65 STA_REMOVE_COMPLETE_EVENT_ID = BIT(21), 65 STA_REMOVE_COMPLETE_EVENT_ID = BIT(21),
66 SOFT_GEMINI_SENSE_EVENT_ID = BIT(22), 66 SOFT_GEMINI_SENSE_EVENT_ID = BIT(22),
67 /* STA: SG prediction */
68 SOFT_GEMINI_PREDICTION_EVENT_ID = BIT(23), 67 SOFT_GEMINI_PREDICTION_EVENT_ID = BIT(23),
69 /* AP: Inactive STA */
70 INACTIVE_STA_EVENT_ID = BIT(23),
71 SOFT_GEMINI_AVALANCHE_EVENT_ID = BIT(24), 68 SOFT_GEMINI_AVALANCHE_EVENT_ID = BIT(24),
72 PLT_RX_CALIBRATION_COMPLETE_EVENT_ID = BIT(25), 69 PLT_RX_CALIBRATION_COMPLETE_EVENT_ID = BIT(25),
73 DBG_EVENT_ID = BIT(26), 70 DBG_EVENT_ID = BIT(26),
@@ -122,11 +119,7 @@ struct event_mailbox {
122 119
123 /* AP FW only */ 120 /* AP FW only */
124 u8 hlid_removed; 121 u8 hlid_removed;
125
126 /* a bitmap of hlids for stations that have been inactive too long */
127 __le16 sta_aging_status; 122 __le16 sta_aging_status;
128
129 /* a bitmap of hlids for stations which didn't respond to TX */
130 __le16 sta_tx_retry_exceeded; 123 __le16 sta_tx_retry_exceeded;
131 124
132 u8 reserved_5[24]; 125 u8 reserved_5[24];
@@ -137,7 +130,4 @@ void wl1271_event_mbox_config(struct wl1271 *wl);
137int wl1271_event_handle(struct wl1271 *wl, u8 mbox); 130int wl1271_event_handle(struct wl1271 *wl, u8 mbox);
138void wl1271_pspoll_work(struct work_struct *work); 131void wl1271_pspoll_work(struct work_struct *work);
139 132
140/* Functions from main.c */
141bool wl1271_is_active_sta(struct wl1271 *wl, u8 hlid);
142
143#endif 133#endif
diff --git a/drivers/net/wireless/wl12xx/init.c b/drivers/net/wireless/wl12xx/init.c
index ab3b1e21de29..a8f4f156c055 100644
--- a/drivers/net/wireless/wl12xx/init.c
+++ b/drivers/net/wireless/wl12xx/init.c
@@ -258,7 +258,7 @@ int wl1271_init_phy_config(struct wl1271 *wl)
258 if (ret < 0) 258 if (ret < 0)
259 return ret; 259 return ret;
260 260
261 ret = wl1271_acx_rts_threshold(wl, wl->conf.rx.rts_threshold); 261 ret = wl1271_acx_rts_threshold(wl, wl->hw->wiphy->rts_threshold);
262 if (ret < 0) 262 if (ret < 0)
263 return ret; 263 return ret;
264 264
@@ -285,7 +285,10 @@ int wl1271_init_pta(struct wl1271 *wl)
285{ 285{
286 int ret; 286 int ret;
287 287
288 ret = wl1271_acx_sg_cfg(wl); 288 if (wl->bss_type == BSS_TYPE_AP_BSS)
289 ret = wl1271_acx_ap_sg_cfg(wl);
290 else
291 ret = wl1271_acx_sta_sg_cfg(wl);
289 if (ret < 0) 292 if (ret < 0)
290 return ret; 293 return ret;
291 294
@@ -351,8 +354,8 @@ static int wl1271_sta_hw_init(struct wl1271 *wl)
351 if (ret < 0) 354 if (ret < 0)
352 return ret; 355 return ret;
353 356
354 /* Bluetooth WLAN coexistence */ 357 /* FM WLAN coexistence */
355 ret = wl1271_init_pta(wl); 358 ret = wl1271_acx_fm_coex(wl);
356 if (ret < 0) 359 if (ret < 0)
357 return ret; 360 return ret;
358 361
@@ -375,10 +378,6 @@ static int wl1271_sta_hw_init(struct wl1271 *wl)
375 if (ret < 0) 378 if (ret < 0)
376 return ret; 379 return ret;
377 380
378 ret = wl1271_acx_sta_max_tx_retry(wl);
379 if (ret < 0)
380 return ret;
381
382 ret = wl1271_acx_sta_mem_cfg(wl); 381 ret = wl1271_acx_sta_mem_cfg(wl);
383 if (ret < 0) 382 if (ret < 0)
384 return ret; 383 return ret;
@@ -414,7 +413,7 @@ static int wl1271_sta_hw_init_post_mem(struct wl1271 *wl)
414 413
415static int wl1271_ap_hw_init(struct wl1271 *wl) 414static int wl1271_ap_hw_init(struct wl1271 *wl)
416{ 415{
417 int ret, i; 416 int ret;
418 417
419 ret = wl1271_ap_init_templates_config(wl); 418 ret = wl1271_ap_init_templates_config(wl);
420 if (ret < 0) 419 if (ret < 0)
@@ -425,27 +424,11 @@ static int wl1271_ap_hw_init(struct wl1271 *wl)
425 if (ret < 0) 424 if (ret < 0)
426 return ret; 425 return ret;
427 426
428 /* Configure initial TX rate classes */ 427 ret = wl1271_init_ap_rates(wl);
429 for (i = 0; i < wl->conf.tx.ac_conf_count; i++) {
430 ret = wl1271_acx_ap_rate_policy(wl,
431 &wl->conf.tx.ap_rc_conf[i], i);
432 if (ret < 0)
433 return ret;
434 }
435
436 ret = wl1271_acx_ap_rate_policy(wl,
437 &wl->conf.tx.ap_mgmt_conf,
438 ACX_TX_AP_MODE_MGMT_RATE);
439 if (ret < 0) 428 if (ret < 0)
440 return ret; 429 return ret;
441 430
442 ret = wl1271_acx_ap_rate_policy(wl, 431 ret = wl1271_acx_max_tx_retry(wl);
443 &wl->conf.tx.ap_bcst_conf,
444 ACX_TX_AP_MODE_BCST_RATE);
445 if (ret < 0)
446 return ret;
447
448 ret = wl1271_acx_ap_max_tx_retry(wl);
449 if (ret < 0) 432 if (ret < 0)
450 return ret; 433 return ret;
451 434
@@ -456,7 +439,7 @@ static int wl1271_ap_hw_init(struct wl1271 *wl)
456 return 0; 439 return 0;
457} 440}
458 441
459static int wl1271_ap_hw_init_post_mem(struct wl1271 *wl) 442int wl1271_ap_init_templates(struct wl1271 *wl)
460{ 443{
461 int ret; 444 int ret;
462 445
@@ -472,6 +455,70 @@ static int wl1271_ap_hw_init_post_mem(struct wl1271 *wl)
472 if (ret < 0) 455 if (ret < 0)
473 return ret; 456 return ret;
474 457
458 /*
459 * when operating as AP we want to receive external beacons for
460 * configuring ERP protection.
461 */
462 ret = wl1271_acx_set_ap_beacon_filter(wl, false);
463 if (ret < 0)
464 return ret;
465
466 return 0;
467}
468
469static int wl1271_ap_hw_init_post_mem(struct wl1271 *wl)
470{
471 return wl1271_ap_init_templates(wl);
472}
473
474int wl1271_init_ap_rates(struct wl1271 *wl)
475{
476 int i, ret;
477 struct conf_tx_rate_class rc;
478 u32 supported_rates;
479
480 wl1271_debug(DEBUG_AP, "AP basic rate set: 0x%x", wl->basic_rate_set);
481
482 if (wl->basic_rate_set == 0)
483 return -EINVAL;
484
485 rc.enabled_rates = wl->basic_rate_set;
486 rc.long_retry_limit = 10;
487 rc.short_retry_limit = 10;
488 rc.aflags = 0;
489 ret = wl1271_acx_ap_rate_policy(wl, &rc, ACX_TX_AP_MODE_MGMT_RATE);
490 if (ret < 0)
491 return ret;
492
493 /* use the min basic rate for AP broadcast/multicast */
494 rc.enabled_rates = wl1271_tx_min_rate_get(wl);
495 rc.short_retry_limit = 10;
496 rc.long_retry_limit = 10;
497 rc.aflags = 0;
498 ret = wl1271_acx_ap_rate_policy(wl, &rc, ACX_TX_AP_MODE_BCST_RATE);
499 if (ret < 0)
500 return ret;
501
502 /*
503 * If the basic rates contain OFDM rates, use OFDM only
504 * rates for unicast TX as well. Else use all supported rates.
505 */
506 if ((wl->basic_rate_set & CONF_TX_OFDM_RATES))
507 supported_rates = CONF_TX_OFDM_RATES;
508 else
509 supported_rates = CONF_TX_AP_ENABLED_RATES;
510
511 /* configure unicast TX rate classes */
512 for (i = 0; i < wl->conf.tx.ac_conf_count; i++) {
513 rc.enabled_rates = supported_rates;
514 rc.short_retry_limit = 10;
515 rc.long_retry_limit = 10;
516 rc.aflags = 0;
517 ret = wl1271_acx_ap_rate_policy(wl, &rc, i);
518 if (ret < 0)
519 return ret;
520 }
521
475 return 0; 522 return 0;
476} 523}
477 524
@@ -567,6 +614,11 @@ int wl1271_hw_init(struct wl1271 *wl)
567 if (ret < 0) 614 if (ret < 0)
568 return ret; 615 return ret;
569 616
617 /* Bluetooth WLAN coexistence */
618 ret = wl1271_init_pta(wl);
619 if (ret < 0)
620 return ret;
621
570 /* Default memory configuration */ 622 /* Default memory configuration */
571 ret = wl1271_acx_init_mem_config(wl); 623 ret = wl1271_acx_init_mem_config(wl);
572 if (ret < 0) 624 if (ret < 0)
@@ -606,7 +658,7 @@ int wl1271_hw_init(struct wl1271 *wl)
606 goto out_free_memmap; 658 goto out_free_memmap;
607 659
608 /* Default fragmentation threshold */ 660 /* Default fragmentation threshold */
609 ret = wl1271_acx_frag_threshold(wl, wl->conf.tx.frag_threshold); 661 ret = wl1271_acx_frag_threshold(wl, wl->hw->wiphy->frag_threshold);
610 if (ret < 0) 662 if (ret < 0)
611 goto out_free_memmap; 663 goto out_free_memmap;
612 664
diff --git a/drivers/net/wireless/wl12xx/init.h b/drivers/net/wireless/wl12xx/init.h
index 4975270a91ab..3a3c230fd292 100644
--- a/drivers/net/wireless/wl12xx/init.h
+++ b/drivers/net/wireless/wl12xx/init.h
@@ -33,5 +33,7 @@ int wl1271_init_pta(struct wl1271 *wl);
33int wl1271_init_energy_detection(struct wl1271 *wl); 33int wl1271_init_energy_detection(struct wl1271 *wl);
34int wl1271_chip_specific_init(struct wl1271 *wl); 34int wl1271_chip_specific_init(struct wl1271 *wl);
35int wl1271_hw_init(struct wl1271 *wl); 35int wl1271_hw_init(struct wl1271 *wl);
36int wl1271_init_ap_rates(struct wl1271 *wl);
37int wl1271_ap_init_templates(struct wl1271 *wl);
36 38
37#endif 39#endif
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
index 0c69e959d0de..610be03a198b 100644
--- a/drivers/net/wireless/wl12xx/main.c
+++ b/drivers/net/wireless/wl12xx/main.c
@@ -51,7 +51,7 @@
51 51
52static struct conf_drv_settings default_conf = { 52static struct conf_drv_settings default_conf = {
53 .sg = { 53 .sg = {
54 .params = { 54 .sta_params = {
55 [CONF_SG_BT_PER_THRESHOLD] = 7500, 55 [CONF_SG_BT_PER_THRESHOLD] = 7500,
56 [CONF_SG_HV3_MAX_OVERRIDE] = 0, 56 [CONF_SG_HV3_MAX_OVERRIDE] = 0,
57 [CONF_SG_BT_NFS_SAMPLE_INTERVAL] = 400, 57 [CONF_SG_BT_NFS_SAMPLE_INTERVAL] = 400,
@@ -101,6 +101,61 @@ static struct conf_drv_settings default_conf = {
101 [CONF_SG_DHCP_TIME] = 5000, 101 [CONF_SG_DHCP_TIME] = 5000,
102 [CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_A2DP] = 100, 102 [CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_A2DP] = 100,
103 }, 103 },
104 .ap_params = {
105 [CONF_SG_BT_PER_THRESHOLD] = 7500,
106 [CONF_SG_HV3_MAX_OVERRIDE] = 0,
107 [CONF_SG_BT_NFS_SAMPLE_INTERVAL] = 400,
108 [CONF_SG_BT_LOAD_RATIO] = 50,
109 [CONF_SG_AUTO_PS_MODE] = 1,
110 [CONF_SG_AUTO_SCAN_PROBE_REQ] = 170,
111 [CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_HV3] = 50,
112 [CONF_SG_ANTENNA_CONFIGURATION] = 0,
113 [CONF_SG_BEACON_MISS_PERCENT] = 60,
114 [CONF_SG_RATE_ADAPT_THRESH] = 64,
115 [CONF_SG_RATE_ADAPT_SNR] = 1,
116 [CONF_SG_WLAN_PS_BT_ACL_MASTER_MIN_BR] = 10,
117 [CONF_SG_WLAN_PS_BT_ACL_MASTER_MAX_BR] = 25,
118 [CONF_SG_WLAN_PS_MAX_BT_ACL_MASTER_BR] = 25,
119 [CONF_SG_WLAN_PS_BT_ACL_SLAVE_MIN_BR] = 20,
120 [CONF_SG_WLAN_PS_BT_ACL_SLAVE_MAX_BR] = 25,
121 [CONF_SG_WLAN_PS_MAX_BT_ACL_SLAVE_BR] = 25,
122 [CONF_SG_WLAN_PS_BT_ACL_MASTER_MIN_EDR] = 7,
123 [CONF_SG_WLAN_PS_BT_ACL_MASTER_MAX_EDR] = 25,
124 [CONF_SG_WLAN_PS_MAX_BT_ACL_MASTER_EDR] = 25,
125 [CONF_SG_WLAN_PS_BT_ACL_SLAVE_MIN_EDR] = 8,
126 [CONF_SG_WLAN_PS_BT_ACL_SLAVE_MAX_EDR] = 25,
127 [CONF_SG_WLAN_PS_MAX_BT_ACL_SLAVE_EDR] = 25,
128 [CONF_SG_RXT] = 1200,
129 [CONF_SG_TXT] = 1000,
130 [CONF_SG_ADAPTIVE_RXT_TXT] = 1,
131 [CONF_SG_PS_POLL_TIMEOUT] = 10,
132 [CONF_SG_UPSD_TIMEOUT] = 10,
133 [CONF_SG_WLAN_ACTIVE_BT_ACL_MASTER_MIN_EDR] = 7,
134 [CONF_SG_WLAN_ACTIVE_BT_ACL_MASTER_MAX_EDR] = 15,
135 [CONF_SG_WLAN_ACTIVE_MAX_BT_ACL_MASTER_EDR] = 15,
136 [CONF_SG_WLAN_ACTIVE_BT_ACL_SLAVE_MIN_EDR] = 8,
137 [CONF_SG_WLAN_ACTIVE_BT_ACL_SLAVE_MAX_EDR] = 20,
138 [CONF_SG_WLAN_ACTIVE_MAX_BT_ACL_SLAVE_EDR] = 15,
139 [CONF_SG_WLAN_ACTIVE_BT_ACL_MIN_BR] = 20,
140 [CONF_SG_WLAN_ACTIVE_BT_ACL_MAX_BR] = 50,
141 [CONF_SG_WLAN_ACTIVE_MAX_BT_ACL_BR] = 10,
142 [CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_HV3] = 200,
143 [CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_A2DP] = 800,
144 [CONF_SG_PASSIVE_SCAN_A2DP_BT_TIME] = 75,
145 [CONF_SG_PASSIVE_SCAN_A2DP_WLAN_TIME] = 15,
146 [CONF_SG_HV3_MAX_SERVED] = 6,
147 [CONF_SG_DHCP_TIME] = 5000,
148 [CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_A2DP] = 100,
149 [CONF_SG_TEMP_PARAM_1] = 0,
150 [CONF_SG_TEMP_PARAM_2] = 0,
151 [CONF_SG_TEMP_PARAM_3] = 0,
152 [CONF_SG_TEMP_PARAM_4] = 0,
153 [CONF_SG_TEMP_PARAM_5] = 0,
154 [CONF_SG_AP_BEACON_MISS_TX] = 3,
155 [CONF_SG_RX_WINDOW_LENGTH] = 6,
156 [CONF_SG_AP_CONNECTION_PROTECTION_TIME] = 50,
157 [CONF_SG_TEMP_PARAM_6] = 1,
158 },
104 .state = CONF_SG_PROTECTIVE, 159 .state = CONF_SG_PROTECTIVE,
105 }, 160 },
106 .rx = { 161 .rx = {
@@ -108,7 +163,7 @@ static struct conf_drv_settings default_conf = {
108 .packet_detection_threshold = 0, 163 .packet_detection_threshold = 0,
109 .ps_poll_timeout = 15, 164 .ps_poll_timeout = 15,
110 .upsd_timeout = 15, 165 .upsd_timeout = 15,
111 .rts_threshold = 2347, 166 .rts_threshold = IEEE80211_MAX_RTS_THRESHOLD,
112 .rx_cca_threshold = 0, 167 .rx_cca_threshold = 0,
113 .irq_blk_threshold = 0xFFFF, 168 .irq_blk_threshold = 0xFFFF,
114 .irq_pkt_threshold = 0, 169 .irq_pkt_threshold = 0,
@@ -154,46 +209,7 @@ static struct conf_drv_settings default_conf = {
154 .tx_op_limit = 1504, 209 .tx_op_limit = 1504,
155 }, 210 },
156 }, 211 },
157 .ap_rc_conf = { 212 .ap_max_tx_retries = 100,
158 [0] = {
159 .enabled_rates = CONF_TX_AP_ENABLED_RATES,
160 .short_retry_limit = 10,
161 .long_retry_limit = 10,
162 .aflags = 0,
163 },
164 [1] = {
165 .enabled_rates = CONF_TX_AP_ENABLED_RATES,
166 .short_retry_limit = 10,
167 .long_retry_limit = 10,
168 .aflags = 0,
169 },
170 [2] = {
171 .enabled_rates = CONF_TX_AP_ENABLED_RATES,
172 .short_retry_limit = 10,
173 .long_retry_limit = 10,
174 .aflags = 0,
175 },
176 [3] = {
177 .enabled_rates = CONF_TX_AP_ENABLED_RATES,
178 .short_retry_limit = 10,
179 .long_retry_limit = 10,
180 .aflags = 0,
181 },
182 },
183 .ap_mgmt_conf = {
184 .enabled_rates = CONF_TX_AP_DEFAULT_MGMT_RATES,
185 .short_retry_limit = 10,
186 .long_retry_limit = 10,
187 .aflags = 0,
188 },
189 .ap_bcst_conf = {
190 .enabled_rates = CONF_HW_BIT_RATE_1MBPS,
191 .short_retry_limit = 10,
192 .long_retry_limit = 10,
193 .aflags = 0,
194 },
195 .max_tx_retries = 100,
196 .ap_aging_period = 300,
197 .tid_conf_count = 4, 213 .tid_conf_count = 4,
198 .tid_conf = { 214 .tid_conf = {
199 [CONF_TX_AC_BE] = { 215 [CONF_TX_AC_BE] = {
@@ -241,12 +257,16 @@ static struct conf_drv_settings default_conf = {
241 .wake_up_event = CONF_WAKE_UP_EVENT_DTIM, 257 .wake_up_event = CONF_WAKE_UP_EVENT_DTIM,
242 .listen_interval = 1, 258 .listen_interval = 1,
243 .bcn_filt_mode = CONF_BCN_FILT_MODE_ENABLED, 259 .bcn_filt_mode = CONF_BCN_FILT_MODE_ENABLED,
244 .bcn_filt_ie_count = 1, 260 .bcn_filt_ie_count = 2,
245 .bcn_filt_ie = { 261 .bcn_filt_ie = {
246 [0] = { 262 [0] = {
247 .ie = WLAN_EID_CHANNEL_SWITCH, 263 .ie = WLAN_EID_CHANNEL_SWITCH,
248 .rule = CONF_BCN_RULE_PASS_ON_APPEARANCE, 264 .rule = CONF_BCN_RULE_PASS_ON_APPEARANCE,
249 } 265 },
266 [1] = {
267 .ie = WLAN_EID_HT_INFORMATION,
268 .rule = CONF_BCN_RULE_PASS_ON_CHANGE,
269 },
250 }, 270 },
251 .synch_fail_thold = 10, 271 .synch_fail_thold = 10,
252 .bss_lose_timeout = 100, 272 .bss_lose_timeout = 100,
@@ -258,7 +278,7 @@ static struct conf_drv_settings default_conf = {
258 .bet_enable = CONF_BET_MODE_ENABLE, 278 .bet_enable = CONF_BET_MODE_ENABLE,
259 .bet_max_consecutive = 50, 279 .bet_max_consecutive = 50,
260 .psm_entry_retries = 5, 280 .psm_entry_retries = 5,
261 .psm_exit_retries = 255, 281 .psm_exit_retries = 16,
262 .psm_entry_nullfunc_retries = 3, 282 .psm_entry_nullfunc_retries = 3,
263 .psm_entry_hangover_period = 1, 283 .psm_entry_hangover_period = 1,
264 .keep_alive_interval = 55000, 284 .keep_alive_interval = 55000,
@@ -286,6 +306,15 @@ static struct conf_drv_settings default_conf = {
286 .max_dwell_time_passive = 100000, 306 .max_dwell_time_passive = 100000,
287 .num_probe_reqs = 2, 307 .num_probe_reqs = 2,
288 }, 308 },
309 .sched_scan = {
310 /* sched_scan requires dwell times in TU instead of TU/1000 */
311 .min_dwell_time_active = 8,
312 .max_dwell_time_active = 30,
313 .dwell_time_passive = 100,
314 .num_probe_reqs = 2,
315 .rssi_threshold = -90,
316 .snr_threshold = 0,
317 },
289 .rf = { 318 .rf = {
290 .tx_per_channel_power_compensation_2 = { 319 .tx_per_channel_power_compensation_2 = {
291 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 320 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -305,7 +334,7 @@ static struct conf_drv_settings default_conf = {
305 .ssid_profiles = 1, 334 .ssid_profiles = 1,
306 .rx_block_num = 70, 335 .rx_block_num = 70,
307 .tx_min_block_num = 40, 336 .tx_min_block_num = 40,
308 .dynamic_memory = 0, 337 .dynamic_memory = 1,
309 .min_req_tx_blocks = 100, 338 .min_req_tx_blocks = 100,
310 .min_req_rx_blocks = 22, 339 .min_req_rx_blocks = 22,
311 .tx_min = 27, 340 .tx_min = 27,
@@ -320,10 +349,23 @@ static struct conf_drv_settings default_conf = {
320 .min_req_rx_blocks = 22, 349 .min_req_rx_blocks = 22,
321 .tx_min = 27, 350 .tx_min = 27,
322 }, 351 },
352 .fm_coex = {
353 .enable = true,
354 .swallow_period = 5,
355 .n_divider_fref_set_1 = 0xff, /* default */
356 .n_divider_fref_set_2 = 12,
357 .m_divider_fref_set_1 = 148,
358 .m_divider_fref_set_2 = 0xffff, /* default */
359 .coex_pll_stabilization_time = 0xffffffff, /* default */
360 .ldo_stabilization_time = 0xffff, /* default */
361 .fm_disturbed_band_margin = 0xff, /* default */
362 .swallow_clk_diff = 0xff, /* default */
363 },
323 .hci_io_ds = HCI_IO_DS_6MA, 364 .hci_io_ds = HCI_IO_DS_6MA,
324}; 365};
325 366
326static void __wl1271_op_remove_interface(struct wl1271 *wl); 367static void __wl1271_op_remove_interface(struct wl1271 *wl,
368 bool reset_tx_queues);
327static void wl1271_free_ap_keys(struct wl1271 *wl); 369static void wl1271_free_ap_keys(struct wl1271 *wl);
328 370
329 371
@@ -508,6 +550,11 @@ static int wl1271_plt_init(struct wl1271 *wl)
508 if (ret < 0) 550 if (ret < 0)
509 goto out_free_memmap; 551 goto out_free_memmap;
510 552
553 /* FM WLAN coexistence */
554 ret = wl1271_acx_fm_coex(wl);
555 if (ret < 0)
556 goto out_free_memmap;
557
511 /* Energy detection */ 558 /* Energy detection */
512 ret = wl1271_init_energy_detection(wl); 559 ret = wl1271_init_energy_detection(wl);
513 if (ret < 0) 560 if (ret < 0)
@@ -932,15 +979,30 @@ static void wl1271_recovery_work(struct work_struct *work)
932 if (wl->state != WL1271_STATE_ON) 979 if (wl->state != WL1271_STATE_ON)
933 goto out; 980 goto out;
934 981
935 wl1271_info("Hardware recovery in progress."); 982 wl1271_info("Hardware recovery in progress. FW ver: %s pc: 0x%x",
983 wl->chip.fw_ver_str, wl1271_read32(wl, SCR_PAD4));
936 984
937 if (test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) 985 if (test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags))
938 ieee80211_connection_loss(wl->vif); 986 ieee80211_connection_loss(wl->vif);
939 987
988 /* Prevent spurious TX during FW restart */
989 ieee80211_stop_queues(wl->hw);
990
991 if (wl->sched_scanning) {
992 ieee80211_sched_scan_stopped(wl->hw);
993 wl->sched_scanning = false;
994 }
995
940 /* reboot the chipset */ 996 /* reboot the chipset */
941 __wl1271_op_remove_interface(wl); 997 __wl1271_op_remove_interface(wl, false);
942 ieee80211_restart_hw(wl->hw); 998 ieee80211_restart_hw(wl->hw);
943 999
1000 /*
1001 * Its safe to enable TX now - the queues are stopped after a request
1002 * to restart the HW.
1003 */
1004 ieee80211_wake_queues(wl->hw);
1005
944out: 1006out:
945 mutex_unlock(&wl->mutex); 1007 mutex_unlock(&wl->mutex);
946} 1008}
@@ -1011,6 +1073,10 @@ static int wl1271_chip_wakeup(struct wl1271 *wl)
1011 wl1271_debug(DEBUG_BOOT, "chip id 0x%x (1271 PG20)", 1073 wl1271_debug(DEBUG_BOOT, "chip id 0x%x (1271 PG20)",
1012 wl->chip.id); 1074 wl->chip.id);
1013 1075
1076 /* end-of-transaction flag should be set in wl127x AP mode */
1077 if (wl->bss_type == BSS_TYPE_AP_BSS)
1078 wl->quirks |= WL12XX_QUIRK_END_OF_TRANSACTION;
1079
1014 ret = wl1271_setup(wl); 1080 ret = wl1271_setup(wl);
1015 if (ret < 0) 1081 if (ret < 0)
1016 goto out; 1082 goto out;
@@ -1273,7 +1339,7 @@ static struct sk_buff *wl12xx_alloc_dummy_packet(struct wl1271 *wl)
1273 skb->priority = WL1271_TID_MGMT; 1339 skb->priority = WL1271_TID_MGMT;
1274 1340
1275 /* Initialize all fields that might be used */ 1341 /* Initialize all fields that might be used */
1276 skb->queue_mapping = 0; 1342 skb_set_queue_mapping(skb, 0);
1277 memset(IEEE80211_SKB_CB(skb), 0, sizeof(struct ieee80211_tx_info)); 1343 memset(IEEE80211_SKB_CB(skb), 0, sizeof(struct ieee80211_tx_info));
1278 1344
1279 return skb; 1345 return skb;
@@ -1284,6 +1350,150 @@ static struct notifier_block wl1271_dev_notifier = {
1284 .notifier_call = wl1271_dev_notify, 1350 .notifier_call = wl1271_dev_notify,
1285}; 1351};
1286 1352
1353static int wl1271_configure_suspend(struct wl1271 *wl)
1354{
1355 int ret;
1356
1357 if (wl->bss_type != BSS_TYPE_STA_BSS)
1358 return 0;
1359
1360 mutex_lock(&wl->mutex);
1361
1362 ret = wl1271_ps_elp_wakeup(wl);
1363 if (ret < 0)
1364 goto out_unlock;
1365
1366 /* enter psm if needed*/
1367 if (!test_bit(WL1271_FLAG_PSM, &wl->flags)) {
1368 DECLARE_COMPLETION_ONSTACK(compl);
1369
1370 wl->ps_compl = &compl;
1371 ret = wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE,
1372 wl->basic_rate, true);
1373 if (ret < 0)
1374 goto out_sleep;
1375
1376 /* we must unlock here so we will be able to get events */
1377 wl1271_ps_elp_sleep(wl);
1378 mutex_unlock(&wl->mutex);
1379
1380 ret = wait_for_completion_timeout(
1381 &compl, msecs_to_jiffies(WL1271_PS_COMPLETE_TIMEOUT));
1382 if (ret <= 0) {
1383 wl1271_warning("couldn't enter ps mode!");
1384 ret = -EBUSY;
1385 goto out;
1386 }
1387
1388 /* take mutex again, and wakeup */
1389 mutex_lock(&wl->mutex);
1390
1391 ret = wl1271_ps_elp_wakeup(wl);
1392 if (ret < 0)
1393 goto out_unlock;
1394 }
1395out_sleep:
1396 wl1271_ps_elp_sleep(wl);
1397out_unlock:
1398 mutex_unlock(&wl->mutex);
1399out:
1400 return ret;
1401
1402}
1403
1404static void wl1271_configure_resume(struct wl1271 *wl)
1405{
1406 int ret;
1407
1408 if (wl->bss_type != BSS_TYPE_STA_BSS)
1409 return;
1410
1411 mutex_lock(&wl->mutex);
1412 ret = wl1271_ps_elp_wakeup(wl);
1413 if (ret < 0)
1414 goto out;
1415
1416 /* exit psm if it wasn't configured */
1417 if (!test_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags))
1418 wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE,
1419 wl->basic_rate, true);
1420
1421 wl1271_ps_elp_sleep(wl);
1422out:
1423 mutex_unlock(&wl->mutex);
1424}
1425
1426static int wl1271_op_suspend(struct ieee80211_hw *hw,
1427 struct cfg80211_wowlan *wow)
1428{
1429 struct wl1271 *wl = hw->priv;
1430 wl1271_debug(DEBUG_MAC80211, "mac80211 suspend wow=%d", !!wow);
1431 wl->wow_enabled = !!wow;
1432 if (wl->wow_enabled) {
1433 int ret;
1434 ret = wl1271_configure_suspend(wl);
1435 if (ret < 0) {
1436 wl1271_warning("couldn't prepare device to suspend");
1437 return ret;
1438 }
1439 /* flush any remaining work */
1440 wl1271_debug(DEBUG_MAC80211, "flushing remaining works");
1441 flush_delayed_work(&wl->scan_complete_work);
1442
1443 /*
1444 * disable and re-enable interrupts in order to flush
1445 * the threaded_irq
1446 */
1447 wl1271_disable_interrupts(wl);
1448
1449 /*
1450 * set suspended flag to avoid triggering a new threaded_irq
1451 * work. no need for spinlock as interrupts are disabled.
1452 */
1453 set_bit(WL1271_FLAG_SUSPENDED, &wl->flags);
1454
1455 wl1271_enable_interrupts(wl);
1456 flush_work(&wl->tx_work);
1457 flush_delayed_work(&wl->pspoll_work);
1458 flush_delayed_work(&wl->elp_work);
1459 }
1460 return 0;
1461}
1462
1463static int wl1271_op_resume(struct ieee80211_hw *hw)
1464{
1465 struct wl1271 *wl = hw->priv;
1466 wl1271_debug(DEBUG_MAC80211, "mac80211 resume wow=%d",
1467 wl->wow_enabled);
1468
1469 /*
1470 * re-enable irq_work enqueuing, and call irq_work directly if
1471 * there is a pending work.
1472 */
1473 if (wl->wow_enabled) {
1474 struct wl1271 *wl = hw->priv;
1475 unsigned long flags;
1476 bool run_irq_work = false;
1477
1478 spin_lock_irqsave(&wl->wl_lock, flags);
1479 clear_bit(WL1271_FLAG_SUSPENDED, &wl->flags);
1480 if (test_and_clear_bit(WL1271_FLAG_PENDING_WORK, &wl->flags))
1481 run_irq_work = true;
1482 spin_unlock_irqrestore(&wl->wl_lock, flags);
1483
1484 if (run_irq_work) {
1485 wl1271_debug(DEBUG_MAC80211,
1486 "run postponed irq_work directly");
1487 wl1271_irq(0, wl);
1488 wl1271_enable_interrupts(wl);
1489 }
1490
1491 wl1271_configure_resume(wl);
1492 }
1493
1494 return 0;
1495}
1496
1287static int wl1271_op_start(struct ieee80211_hw *hw) 1497static int wl1271_op_start(struct ieee80211_hw *hw)
1288{ 1498{
1289 wl1271_debug(DEBUG_MAC80211, "mac80211 start"); 1499 wl1271_debug(DEBUG_MAC80211, "mac80211 start");
@@ -1440,7 +1650,8 @@ out:
1440 return ret; 1650 return ret;
1441} 1651}
1442 1652
1443static void __wl1271_op_remove_interface(struct wl1271 *wl) 1653static void __wl1271_op_remove_interface(struct wl1271 *wl,
1654 bool reset_tx_queues)
1444{ 1655{
1445 int i; 1656 int i;
1446 1657
@@ -1486,7 +1697,7 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl)
1486 mutex_lock(&wl->mutex); 1697 mutex_lock(&wl->mutex);
1487 1698
1488 /* let's notify MAC80211 about the remaining pending TX frames */ 1699 /* let's notify MAC80211 about the remaining pending TX frames */
1489 wl1271_tx_reset(wl); 1700 wl1271_tx_reset(wl, reset_tx_queues);
1490 wl1271_power_off(wl); 1701 wl1271_power_off(wl);
1491 1702
1492 memset(wl->bssid, 0, ETH_ALEN); 1703 memset(wl->bssid, 0, ETH_ALEN);
@@ -1514,6 +1725,7 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl)
1514 memset(wl->ap_hlid_map, 0, sizeof(wl->ap_hlid_map)); 1725 memset(wl->ap_hlid_map, 0, sizeof(wl->ap_hlid_map));
1515 wl->ap_fw_ps_map = 0; 1726 wl->ap_fw_ps_map = 0;
1516 wl->ap_ps_map = 0; 1727 wl->ap_ps_map = 0;
1728 wl->sched_scanning = false;
1517 1729
1518 /* 1730 /*
1519 * this is performed after the cancel_work calls and the associated 1731 * this is performed after the cancel_work calls and the associated
@@ -1547,7 +1759,7 @@ static void wl1271_op_remove_interface(struct ieee80211_hw *hw,
1547 */ 1759 */
1548 if (wl->vif) { 1760 if (wl->vif) {
1549 WARN_ON(wl->vif != vif); 1761 WARN_ON(wl->vif != vif);
1550 __wl1271_op_remove_interface(wl); 1762 __wl1271_op_remove_interface(wl, true);
1551 } 1763 }
1552 1764
1553 mutex_unlock(&wl->mutex); 1765 mutex_unlock(&wl->mutex);
@@ -1716,6 +1928,13 @@ static int wl1271_sta_handle_idle(struct wl1271 *wl, bool idle)
1716 wl->session_counter++; 1928 wl->session_counter++;
1717 if (wl->session_counter >= SESSION_COUNTER_MAX) 1929 if (wl->session_counter >= SESSION_COUNTER_MAX)
1718 wl->session_counter = 0; 1930 wl->session_counter = 0;
1931
1932 /* The current firmware only supports sched_scan in idle */
1933 if (wl->sched_scanning) {
1934 wl1271_scan_sched_scan_stop(wl);
1935 ieee80211_sched_scan_stopped(wl->hw);
1936 }
1937
1719 ret = wl1271_dummy_join(wl); 1938 ret = wl1271_dummy_join(wl);
1720 if (ret < 0) 1939 if (ret < 0)
1721 goto out; 1940 goto out;
@@ -2268,6 +2487,60 @@ out:
2268 return ret; 2487 return ret;
2269} 2488}
2270 2489
2490static int wl1271_op_sched_scan_start(struct ieee80211_hw *hw,
2491 struct ieee80211_vif *vif,
2492 struct cfg80211_sched_scan_request *req,
2493 struct ieee80211_sched_scan_ies *ies)
2494{
2495 struct wl1271 *wl = hw->priv;
2496 int ret;
2497
2498 wl1271_debug(DEBUG_MAC80211, "wl1271_op_sched_scan_start");
2499
2500 mutex_lock(&wl->mutex);
2501
2502 ret = wl1271_ps_elp_wakeup(wl);
2503 if (ret < 0)
2504 goto out;
2505
2506 ret = wl1271_scan_sched_scan_config(wl, req, ies);
2507 if (ret < 0)
2508 goto out_sleep;
2509
2510 ret = wl1271_scan_sched_scan_start(wl);
2511 if (ret < 0)
2512 goto out_sleep;
2513
2514 wl->sched_scanning = true;
2515
2516out_sleep:
2517 wl1271_ps_elp_sleep(wl);
2518out:
2519 mutex_unlock(&wl->mutex);
2520 return ret;
2521}
2522
2523static void wl1271_op_sched_scan_stop(struct ieee80211_hw *hw,
2524 struct ieee80211_vif *vif)
2525{
2526 struct wl1271 *wl = hw->priv;
2527 int ret;
2528
2529 wl1271_debug(DEBUG_MAC80211, "wl1271_op_sched_scan_stop");
2530
2531 mutex_lock(&wl->mutex);
2532
2533 ret = wl1271_ps_elp_wakeup(wl);
2534 if (ret < 0)
2535 goto out;
2536
2537 wl1271_scan_sched_scan_stop(wl);
2538
2539 wl1271_ps_elp_sleep(wl);
2540out:
2541 mutex_unlock(&wl->mutex);
2542}
2543
2271static int wl1271_op_set_frag_threshold(struct ieee80211_hw *hw, u32 value) 2544static int wl1271_op_set_frag_threshold(struct ieee80211_hw *hw, u32 value)
2272{ 2545{
2273 struct wl1271 *wl = hw->priv; 2546 struct wl1271 *wl = hw->priv;
@@ -2284,7 +2557,7 @@ static int wl1271_op_set_frag_threshold(struct ieee80211_hw *hw, u32 value)
2284 if (ret < 0) 2557 if (ret < 0)
2285 goto out; 2558 goto out;
2286 2559
2287 ret = wl1271_acx_frag_threshold(wl, (u16)value); 2560 ret = wl1271_acx_frag_threshold(wl, value);
2288 if (ret < 0) 2561 if (ret < 0)
2289 wl1271_warning("wl1271_op_set_frag_threshold failed: %d", ret); 2562 wl1271_warning("wl1271_op_set_frag_threshold failed: %d", ret);
2290 2563
@@ -2312,7 +2585,7 @@ static int wl1271_op_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
2312 if (ret < 0) 2585 if (ret < 0)
2313 goto out; 2586 goto out;
2314 2587
2315 ret = wl1271_acx_rts_threshold(wl, (u16) value); 2588 ret = wl1271_acx_rts_threshold(wl, value);
2316 if (ret < 0) 2589 if (ret < 0)
2317 wl1271_warning("wl1271_op_set_rts_threshold failed: %d", ret); 2590 wl1271_warning("wl1271_op_set_rts_threshold failed: %d", ret);
2318 2591
@@ -2327,20 +2600,24 @@ out:
2327static int wl1271_ssid_set(struct wl1271 *wl, struct sk_buff *skb, 2600static int wl1271_ssid_set(struct wl1271 *wl, struct sk_buff *skb,
2328 int offset) 2601 int offset)
2329{ 2602{
2330 u8 *ptr = skb->data + offset; 2603 u8 ssid_len;
2604 const u8 *ptr = cfg80211_find_ie(WLAN_EID_SSID, skb->data + offset,
2605 skb->len - offset);
2331 2606
2332 /* find the location of the ssid in the beacon */ 2607 if (!ptr) {
2333 while (ptr < skb->data + skb->len) { 2608 wl1271_error("No SSID in IEs!");
2334 if (ptr[0] == WLAN_EID_SSID) { 2609 return -ENOENT;
2335 wl->ssid_len = ptr[1];
2336 memcpy(wl->ssid, ptr+2, wl->ssid_len);
2337 return 0;
2338 }
2339 ptr += (ptr[1] + 2);
2340 } 2610 }
2341 2611
2342 wl1271_error("No SSID in IEs!\n"); 2612 ssid_len = ptr[1];
2343 return -ENOENT; 2613 if (ssid_len > IEEE80211_MAX_SSID_LEN) {
2614 wl1271_error("SSID is too long!");
2615 return -EINVAL;
2616 }
2617
2618 wl->ssid_len = ssid_len;
2619 memcpy(wl->ssid, ptr+2, ssid_len);
2620 return 0;
2344} 2621}
2345 2622
2346static int wl1271_bss_erp_info_changed(struct wl1271 *wl, 2623static int wl1271_bss_erp_info_changed(struct wl1271 *wl,
@@ -2455,24 +2732,19 @@ static void wl1271_bss_info_changed_ap(struct wl1271 *wl,
2455 2732
2456 if ((changed & BSS_CHANGED_BASIC_RATES)) { 2733 if ((changed & BSS_CHANGED_BASIC_RATES)) {
2457 u32 rates = bss_conf->basic_rates; 2734 u32 rates = bss_conf->basic_rates;
2458 struct conf_tx_rate_class mgmt_rc;
2459 2735
2460 wl->basic_rate_set = wl1271_tx_enabled_rates_get(wl, rates); 2736 wl->basic_rate_set = wl1271_tx_enabled_rates_get(wl, rates);
2461 wl->basic_rate = wl1271_tx_min_rate_get(wl); 2737 wl->basic_rate = wl1271_tx_min_rate_get(wl);
2462 wl1271_debug(DEBUG_AP, "basic rates: 0x%x", 2738
2463 wl->basic_rate_set); 2739 ret = wl1271_init_ap_rates(wl);
2464
2465 /* update the AP management rate policy with the new rates */
2466 mgmt_rc.enabled_rates = wl->basic_rate_set;
2467 mgmt_rc.long_retry_limit = 10;
2468 mgmt_rc.short_retry_limit = 10;
2469 mgmt_rc.aflags = 0;
2470 ret = wl1271_acx_ap_rate_policy(wl, &mgmt_rc,
2471 ACX_TX_AP_MODE_MGMT_RATE);
2472 if (ret < 0) { 2740 if (ret < 0) {
2473 wl1271_error("AP mgmt policy change failed %d", ret); 2741 wl1271_error("AP rate policy change failed %d", ret);
2474 goto out; 2742 goto out;
2475 } 2743 }
2744
2745 ret = wl1271_ap_init_templates(wl);
2746 if (ret < 0)
2747 goto out;
2476 } 2748 }
2477 2749
2478 ret = wl1271_bss_beacon_info_changed(wl, vif, bss_conf, changed); 2750 ret = wl1271_bss_beacon_info_changed(wl, vif, bss_conf, changed);
@@ -2505,6 +2777,24 @@ static void wl1271_bss_info_changed_ap(struct wl1271 *wl,
2505 } 2777 }
2506 } 2778 }
2507 2779
2780 if (changed & BSS_CHANGED_IBSS) {
2781 wl1271_debug(DEBUG_ADHOC, "ibss_joined: %d",
2782 bss_conf->ibss_joined);
2783
2784 if (bss_conf->ibss_joined) {
2785 u32 rates = bss_conf->basic_rates;
2786 wl->basic_rate_set = wl1271_tx_enabled_rates_get(wl,
2787 rates);
2788 wl->basic_rate = wl1271_tx_min_rate_get(wl);
2789
2790 /* by default, use 11b rates */
2791 wl->rate_set = CONF_TX_IBSS_DEFAULT_RATES;
2792 ret = wl1271_acx_sta_rate_policies(wl);
2793 if (ret < 0)
2794 goto out;
2795 }
2796 }
2797
2508 ret = wl1271_bss_erp_info_changed(wl, bss_conf, changed); 2798 ret = wl1271_bss_erp_info_changed(wl, bss_conf, changed);
2509 if (ret < 0) 2799 if (ret < 0)
2510 goto out; 2800 goto out;
@@ -2694,8 +2984,10 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
2694 } 2984 }
2695 } else { 2985 } else {
2696 /* use defaults when not associated */ 2986 /* use defaults when not associated */
2987 bool was_assoc =
2988 !!test_and_clear_bit(WL1271_FLAG_STA_ASSOCIATED,
2989 &wl->flags);
2697 clear_bit(WL1271_FLAG_STA_STATE_SENT, &wl->flags); 2990 clear_bit(WL1271_FLAG_STA_STATE_SENT, &wl->flags);
2698 clear_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags);
2699 wl->aid = 0; 2991 wl->aid = 0;
2700 2992
2701 /* free probe-request template */ 2993 /* free probe-request template */
@@ -2721,8 +3013,10 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
2721 goto out; 3013 goto out;
2722 3014
2723 /* restore the bssid filter and go to dummy bssid */ 3015 /* restore the bssid filter and go to dummy bssid */
2724 wl1271_unjoin(wl); 3016 if (was_assoc) {
2725 wl1271_dummy_join(wl); 3017 wl1271_unjoin(wl);
3018 wl1271_dummy_join(wl);
3019 }
2726 } 3020 }
2727 } 3021 }
2728 3022
@@ -2954,12 +3248,6 @@ static void wl1271_free_sta(struct wl1271 *wl, u8 hlid)
2954 __clear_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map); 3248 __clear_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map);
2955} 3249}
2956 3250
2957bool wl1271_is_active_sta(struct wl1271 *wl, u8 hlid)
2958{
2959 int id = hlid - WL1271_AP_STA_HLID_START;
2960 return test_bit(id, wl->ap_hlid_map);
2961}
2962
2963static int wl1271_op_sta_add(struct ieee80211_hw *hw, 3251static int wl1271_op_sta_add(struct ieee80211_hw *hw,
2964 struct ieee80211_vif *vif, 3252 struct ieee80211_vif *vif,
2965 struct ieee80211_sta *sta) 3253 struct ieee80211_sta *sta)
@@ -3104,6 +3392,28 @@ out:
3104 return ret; 3392 return ret;
3105} 3393}
3106 3394
3395static bool wl1271_tx_frames_pending(struct ieee80211_hw *hw)
3396{
3397 struct wl1271 *wl = hw->priv;
3398 bool ret = false;
3399
3400 mutex_lock(&wl->mutex);
3401
3402 if (unlikely(wl->state == WL1271_STATE_OFF))
3403 goto out;
3404
3405 /* packets are considered pending if in the TX queue or the FW */
3406 ret = (wl->tx_queue_count > 0) || (wl->tx_frames_cnt > 0);
3407
3408 /* the above is appropriate for STA mode for PS purposes */
3409 WARN_ON(wl->bss_type != BSS_TYPE_STA_BSS);
3410
3411out:
3412 mutex_unlock(&wl->mutex);
3413
3414 return ret;
3415}
3416
3107/* can't be const, mac80211 writes to this */ 3417/* can't be const, mac80211 writes to this */
3108static struct ieee80211_rate wl1271_rates[] = { 3418static struct ieee80211_rate wl1271_rates[] = {
3109 { .bitrate = 10, 3419 { .bitrate = 10,
@@ -3340,12 +3650,16 @@ static const struct ieee80211_ops wl1271_ops = {
3340 .stop = wl1271_op_stop, 3650 .stop = wl1271_op_stop,
3341 .add_interface = wl1271_op_add_interface, 3651 .add_interface = wl1271_op_add_interface,
3342 .remove_interface = wl1271_op_remove_interface, 3652 .remove_interface = wl1271_op_remove_interface,
3653 .suspend = wl1271_op_suspend,
3654 .resume = wl1271_op_resume,
3343 .config = wl1271_op_config, 3655 .config = wl1271_op_config,
3344 .prepare_multicast = wl1271_op_prepare_multicast, 3656 .prepare_multicast = wl1271_op_prepare_multicast,
3345 .configure_filter = wl1271_op_configure_filter, 3657 .configure_filter = wl1271_op_configure_filter,
3346 .tx = wl1271_op_tx, 3658 .tx = wl1271_op_tx,
3347 .set_key = wl1271_op_set_key, 3659 .set_key = wl1271_op_set_key,
3348 .hw_scan = wl1271_op_hw_scan, 3660 .hw_scan = wl1271_op_hw_scan,
3661 .sched_scan_start = wl1271_op_sched_scan_start,
3662 .sched_scan_stop = wl1271_op_sched_scan_stop,
3349 .bss_info_changed = wl1271_op_bss_info_changed, 3663 .bss_info_changed = wl1271_op_bss_info_changed,
3350 .set_frag_threshold = wl1271_op_set_frag_threshold, 3664 .set_frag_threshold = wl1271_op_set_frag_threshold,
3351 .set_rts_threshold = wl1271_op_set_rts_threshold, 3665 .set_rts_threshold = wl1271_op_set_rts_threshold,
@@ -3355,6 +3669,7 @@ static const struct ieee80211_ops wl1271_ops = {
3355 .sta_add = wl1271_op_sta_add, 3669 .sta_add = wl1271_op_sta_add,
3356 .sta_remove = wl1271_op_sta_remove, 3670 .sta_remove = wl1271_op_sta_remove,
3357 .ampdu_action = wl1271_op_ampdu_action, 3671 .ampdu_action = wl1271_op_ampdu_action,
3672 .tx_frames_pending = wl1271_tx_frames_pending,
3358 CFG80211_TESTMODE_CMD(wl1271_tm_cmd) 3673 CFG80211_TESTMODE_CMD(wl1271_tm_cmd)
3359}; 3674};
3360 3675
@@ -3542,6 +3857,8 @@ int wl1271_init_ieee80211(struct wl1271 *wl)
3542 IEEE80211_HW_HAS_RATE_CONTROL | 3857 IEEE80211_HW_HAS_RATE_CONTROL |
3543 IEEE80211_HW_CONNECTION_MONITOR | 3858 IEEE80211_HW_CONNECTION_MONITOR |
3544 IEEE80211_HW_SUPPORTS_CQM_RSSI | 3859 IEEE80211_HW_SUPPORTS_CQM_RSSI |
3860 IEEE80211_HW_REPORTS_TX_ACK_STATUS |
3861 IEEE80211_HW_SPECTRUM_MGMT |
3545 IEEE80211_HW_AP_LINK_PS; 3862 IEEE80211_HW_AP_LINK_PS;
3546 3863
3547 wl->hw->wiphy->cipher_suites = cipher_suites; 3864 wl->hw->wiphy->cipher_suites = cipher_suites;
@@ -3663,6 +3980,7 @@ struct ieee80211_hw *wl1271_alloc_hw(void)
3663 wl->ap_fw_ps_map = 0; 3980 wl->ap_fw_ps_map = 0;
3664 wl->quirks = 0; 3981 wl->quirks = 0;
3665 wl->platform_quirks = 0; 3982 wl->platform_quirks = 0;
3983 wl->sched_scanning = false;
3666 3984
3667 memset(wl->tx_frames_map, 0, sizeof(wl->tx_frames_map)); 3985 memset(wl->tx_frames_map, 0, sizeof(wl->tx_frames_map));
3668 for (i = 0; i < ACX_TX_DESCRIPTORS; i++) 3986 for (i = 0; i < ACX_TX_DESCRIPTORS; i++)
diff --git a/drivers/net/wireless/wl12xx/ps.c b/drivers/net/wireless/wl12xx/ps.c
index b8deada5d020..b59b67711a17 100644
--- a/drivers/net/wireless/wl12xx/ps.c
+++ b/drivers/net/wireless/wl12xx/ps.c
@@ -43,6 +43,10 @@ void wl1271_elp_work(struct work_struct *work)
43 if (unlikely(wl->state == WL1271_STATE_OFF)) 43 if (unlikely(wl->state == WL1271_STATE_OFF))
44 goto out; 44 goto out;
45 45
46 /* our work might have been already cancelled */
47 if (unlikely(!test_bit(WL1271_FLAG_ELP_REQUESTED, &wl->flags)))
48 goto out;
49
46 if (test_bit(WL1271_FLAG_IN_ELP, &wl->flags) || 50 if (test_bit(WL1271_FLAG_IN_ELP, &wl->flags) ||
47 (!test_bit(WL1271_FLAG_PSM, &wl->flags) && 51 (!test_bit(WL1271_FLAG_PSM, &wl->flags) &&
48 !test_bit(WL1271_FLAG_IDLE, &wl->flags))) 52 !test_bit(WL1271_FLAG_IDLE, &wl->flags)))
@@ -61,12 +65,16 @@ out:
61/* Routines to toggle sleep mode while in ELP */ 65/* Routines to toggle sleep mode while in ELP */
62void wl1271_ps_elp_sleep(struct wl1271 *wl) 66void wl1271_ps_elp_sleep(struct wl1271 *wl)
63{ 67{
64 if (test_bit(WL1271_FLAG_PSM, &wl->flags) || 68 /* we shouldn't get consecutive sleep requests */
65 test_bit(WL1271_FLAG_IDLE, &wl->flags)) { 69 if (WARN_ON(test_and_set_bit(WL1271_FLAG_ELP_REQUESTED, &wl->flags)))
66 cancel_delayed_work(&wl->elp_work); 70 return;
67 ieee80211_queue_delayed_work(wl->hw, &wl->elp_work, 71
68 msecs_to_jiffies(ELP_ENTRY_DELAY)); 72 if (!test_bit(WL1271_FLAG_PSM, &wl->flags) &&
69 } 73 !test_bit(WL1271_FLAG_IDLE, &wl->flags))
74 return;
75
76 ieee80211_queue_delayed_work(wl->hw, &wl->elp_work,
77 msecs_to_jiffies(ELP_ENTRY_DELAY));
70} 78}
71 79
72int wl1271_ps_elp_wakeup(struct wl1271 *wl) 80int wl1271_ps_elp_wakeup(struct wl1271 *wl)
@@ -77,6 +85,16 @@ int wl1271_ps_elp_wakeup(struct wl1271 *wl)
77 u32 start_time = jiffies; 85 u32 start_time = jiffies;
78 bool pending = false; 86 bool pending = false;
79 87
88 /*
89 * we might try to wake up even if we didn't go to sleep
90 * before (e.g. on boot)
91 */
92 if (!test_and_clear_bit(WL1271_FLAG_ELP_REQUESTED, &wl->flags))
93 return 0;
94
95 /* don't cancel_sync as it might contend for a mutex and deadlock */
96 cancel_delayed_work(&wl->elp_work);
97
80 if (!test_bit(WL1271_FLAG_IN_ELP, &wl->flags)) 98 if (!test_bit(WL1271_FLAG_IN_ELP, &wl->flags))
81 return 0; 99 return 0;
82 100
diff --git a/drivers/net/wireless/wl12xx/ps.h b/drivers/net/wireless/wl12xx/ps.h
index c41bd0a711bc..25eb9bc9b628 100644
--- a/drivers/net/wireless/wl12xx/ps.h
+++ b/drivers/net/wireless/wl12xx/ps.h
@@ -35,4 +35,6 @@ void wl1271_elp_work(struct work_struct *work);
35void wl1271_ps_link_start(struct wl1271 *wl, u8 hlid, bool clean_queues); 35void wl1271_ps_link_start(struct wl1271 *wl, u8 hlid, bool clean_queues);
36void wl1271_ps_link_end(struct wl1271 *wl, u8 hlid); 36void wl1271_ps_link_end(struct wl1271 *wl, u8 hlid);
37 37
38#define WL1271_PS_COMPLETE_TIMEOUT 500
39
38#endif /* __WL1271_PS_H__ */ 40#endif /* __WL1271_PS_H__ */
diff --git a/drivers/net/wireless/wl12xx/rx.c b/drivers/net/wireless/wl12xx/rx.c
index 2a581495d5c9..70091035e019 100644
--- a/drivers/net/wireless/wl12xx/rx.c
+++ b/drivers/net/wireless/wl12xx/rx.c
@@ -76,12 +76,15 @@ static void wl1271_rx_status(struct wl1271 *wl,
76 status->band); 76 status->band);
77 77
78 if (desc->flags & WL1271_RX_DESC_ENCRYPT_MASK) { 78 if (desc->flags & WL1271_RX_DESC_ENCRYPT_MASK) {
79 status->flag |= RX_FLAG_IV_STRIPPED | RX_FLAG_MMIC_STRIPPED; 79 u8 desc_err_code = desc->status & WL1271_RX_DESC_STATUS_MASK;
80 80
81 if (likely(!(desc->status & WL1271_RX_DESC_DECRYPT_FAIL))) 81 status->flag |= RX_FLAG_IV_STRIPPED | RX_FLAG_MMIC_STRIPPED |
82 status->flag |= RX_FLAG_DECRYPTED; 82 RX_FLAG_DECRYPTED;
83 if (unlikely(desc->status & WL1271_RX_DESC_MIC_FAIL)) 83
84 if (unlikely(desc_err_code == WL1271_RX_DESC_MIC_FAIL)) {
84 status->flag |= RX_FLAG_MMIC_ERROR; 85 status->flag |= RX_FLAG_MMIC_ERROR;
86 wl1271_warning("Michael MIC error");
87 }
85 } 88 }
86} 89}
87 90
@@ -100,6 +103,25 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length)
100 if (unlikely(wl->state == WL1271_STATE_PLT)) 103 if (unlikely(wl->state == WL1271_STATE_PLT))
101 return -EINVAL; 104 return -EINVAL;
102 105
106 /* the data read starts with the descriptor */
107 desc = (struct wl1271_rx_descriptor *) data;
108
109 switch (desc->status & WL1271_RX_DESC_STATUS_MASK) {
110 /* discard corrupted packets */
111 case WL1271_RX_DESC_DRIVER_RX_Q_FAIL:
112 case WL1271_RX_DESC_DECRYPT_FAIL:
113 wl1271_warning("corrupted packet in RX with status: 0x%x",
114 desc->status & WL1271_RX_DESC_STATUS_MASK);
115 return -EINVAL;
116 case WL1271_RX_DESC_SUCCESS:
117 case WL1271_RX_DESC_MIC_FAIL:
118 break;
119 default:
120 wl1271_error("invalid RX descriptor status: 0x%x",
121 desc->status & WL1271_RX_DESC_STATUS_MASK);
122 return -EINVAL;
123 }
124
103 skb = __dev_alloc_skb(length, GFP_KERNEL); 125 skb = __dev_alloc_skb(length, GFP_KERNEL);
104 if (!skb) { 126 if (!skb) {
105 wl1271_error("Couldn't allocate RX frame"); 127 wl1271_error("Couldn't allocate RX frame");
@@ -109,9 +131,6 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length)
109 buf = skb_put(skb, length); 131 buf = skb_put(skb, length);
110 memcpy(buf, data, length); 132 memcpy(buf, data, length);
111 133
112 /* the data read starts with the descriptor */
113 desc = (struct wl1271_rx_descriptor *) buf;
114
115 /* now we pull the descriptor out of the buffer */ 134 /* now we pull the descriptor out of the buffer */
116 skb_pull(skb, sizeof(*desc)); 135 skb_pull(skb, sizeof(*desc));
117 136
@@ -121,7 +140,8 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length)
121 140
122 wl1271_rx_status(wl, desc, IEEE80211_SKB_RXCB(skb), beacon); 141 wl1271_rx_status(wl, desc, IEEE80211_SKB_RXCB(skb), beacon);
123 142
124 wl1271_debug(DEBUG_RX, "rx skb 0x%p: %d B %s", skb, skb->len, 143 wl1271_debug(DEBUG_RX, "rx skb 0x%p: %d B %s", skb,
144 skb->len - desc->pad_len,
125 beacon ? "beacon" : ""); 145 beacon ? "beacon" : "");
126 146
127 skb_trim(skb, skb->len - desc->pad_len); 147 skb_trim(skb, skb->len - desc->pad_len);
diff --git a/drivers/net/wireless/wl12xx/scan.c b/drivers/net/wireless/wl12xx/scan.c
index 5d0544c8f3f5..f37e5a391976 100644
--- a/drivers/net/wireless/wl12xx/scan.c
+++ b/drivers/net/wireless/wl12xx/scan.c
@@ -320,3 +320,246 @@ int wl1271_scan(struct wl1271 *wl, const u8 *ssid, size_t ssid_len,
320 320
321 return 0; 321 return 0;
322} 322}
323
324static int
325wl1271_scan_get_sched_scan_channels(struct wl1271 *wl,
326 struct cfg80211_sched_scan_request *req,
327 struct conn_scan_ch_params *channels,
328 u32 band, bool radar, bool passive,
329 int start)
330{
331 struct conf_sched_scan_settings *c = &wl->conf.sched_scan;
332 int i, j;
333 u32 flags;
334
335 for (i = 0, j = start;
336 i < req->n_channels && j < MAX_CHANNELS_ALL_BANDS;
337 i++) {
338 flags = req->channels[i]->flags;
339
340 if (!(flags & IEEE80211_CHAN_DISABLED) &&
341 ((flags & IEEE80211_CHAN_PASSIVE_SCAN) == passive) &&
342 ((flags & IEEE80211_CHAN_RADAR) == radar) &&
343 (req->channels[i]->band == band)) {
344 wl1271_debug(DEBUG_SCAN, "band %d, center_freq %d ",
345 req->channels[i]->band,
346 req->channels[i]->center_freq);
347 wl1271_debug(DEBUG_SCAN, "hw_value %d, flags %X",
348 req->channels[i]->hw_value,
349 req->channels[i]->flags);
350 wl1271_debug(DEBUG_SCAN, "max_power %d",
351 req->channels[i]->max_power);
352
353 if (flags & IEEE80211_CHAN_PASSIVE_SCAN) {
354 channels[j].passive_duration =
355 cpu_to_le16(c->dwell_time_passive);
356 } else {
357 channels[j].min_duration =
358 cpu_to_le16(c->min_dwell_time_active);
359 channels[j].max_duration =
360 cpu_to_le16(c->max_dwell_time_active);
361 }
362 channels[j].tx_power_att = req->channels[j]->max_power;
363 channels[j].channel = req->channels[i]->hw_value;
364
365 j++;
366 }
367 }
368
369 return j - start;
370}
371
372static int
373wl1271_scan_sched_scan_channels(struct wl1271 *wl,
374 struct cfg80211_sched_scan_request *req,
375 struct wl1271_cmd_sched_scan_config *cfg)
376{
377 int idx = 0;
378
379 cfg->passive[0] =
380 wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels,
381 IEEE80211_BAND_2GHZ,
382 false, true, idx);
383 idx += cfg->passive[0];
384
385 cfg->active[0] =
386 wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels,
387 IEEE80211_BAND_2GHZ,
388 false, false, idx);
389 idx += cfg->active[0];
390
391 cfg->passive[1] =
392 wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels,
393 IEEE80211_BAND_5GHZ,
394 false, true, idx);
395 idx += cfg->passive[1];
396
397 cfg->active[1] =
398 wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels,
399 IEEE80211_BAND_5GHZ,
400 false, false, 14);
401 idx += cfg->active[1];
402
403 cfg->dfs =
404 wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels,
405 IEEE80211_BAND_5GHZ,
406 true, false, idx);
407 idx += cfg->dfs;
408
409 wl1271_debug(DEBUG_SCAN, " 2.4GHz: active %d passive %d",
410 cfg->active[0], cfg->passive[0]);
411 wl1271_debug(DEBUG_SCAN, " 5GHz: active %d passive %d",
412 cfg->active[1], cfg->passive[1]);
413
414 return idx;
415}
416
417int wl1271_scan_sched_scan_config(struct wl1271 *wl,
418 struct cfg80211_sched_scan_request *req,
419 struct ieee80211_sched_scan_ies *ies)
420{
421 struct wl1271_cmd_sched_scan_config *cfg = NULL;
422 struct conf_sched_scan_settings *c = &wl->conf.sched_scan;
423 int i, total_channels, ret;
424
425 wl1271_debug(DEBUG_CMD, "cmd sched_scan scan config");
426
427 cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
428 if (!cfg)
429 return -ENOMEM;
430
431 cfg->rssi_threshold = c->rssi_threshold;
432 cfg->snr_threshold = c->snr_threshold;
433 cfg->n_probe_reqs = c->num_probe_reqs;
434 /* cycles set to 0 it means infinite (until manually stopped) */
435 cfg->cycles = 0;
436 /* report APs when at least 1 is found */
437 cfg->report_after = 1;
438 /* don't stop scanning automatically when something is found */
439 cfg->terminate = 0;
440 cfg->tag = WL1271_SCAN_DEFAULT_TAG;
441 /* don't filter on BSS type */
442 cfg->bss_type = SCAN_BSS_TYPE_ANY;
443 /* currently NL80211 supports only a single interval */
444 for (i = 0; i < SCAN_MAX_CYCLE_INTERVALS; i++)
445 cfg->intervals[i] = cpu_to_le32(req->interval);
446
447 if (req->ssids[0].ssid_len && req->ssids[0].ssid) {
448 cfg->filter_type = SCAN_SSID_FILTER_SPECIFIC;
449 cfg->ssid_len = req->ssids[0].ssid_len;
450 memcpy(cfg->ssid, req->ssids[0].ssid,
451 req->ssids[0].ssid_len);
452 } else {
453 cfg->filter_type = SCAN_SSID_FILTER_ANY;
454 cfg->ssid_len = 0;
455 }
456
457 total_channels = wl1271_scan_sched_scan_channels(wl, req, cfg);
458 if (total_channels == 0) {
459 wl1271_error("scan channel list is empty");
460 ret = -EINVAL;
461 goto out;
462 }
463
464 if (cfg->active[0]) {
465 ret = wl1271_cmd_build_probe_req(wl, req->ssids[0].ssid,
466 req->ssids[0].ssid_len,
467 ies->ie[IEEE80211_BAND_2GHZ],
468 ies->len[IEEE80211_BAND_2GHZ],
469 IEEE80211_BAND_2GHZ);
470 if (ret < 0) {
471 wl1271_error("2.4GHz PROBE request template failed");
472 goto out;
473 }
474 }
475
476 if (cfg->active[1]) {
477 ret = wl1271_cmd_build_probe_req(wl, req->ssids[0].ssid,
478 req->ssids[0].ssid_len,
479 ies->ie[IEEE80211_BAND_5GHZ],
480 ies->len[IEEE80211_BAND_5GHZ],
481 IEEE80211_BAND_5GHZ);
482 if (ret < 0) {
483 wl1271_error("5GHz PROBE request template failed");
484 goto out;
485 }
486 }
487
488 wl1271_dump(DEBUG_SCAN, "SCAN_CFG: ", cfg, sizeof(*cfg));
489
490 ret = wl1271_cmd_send(wl, CMD_CONNECTION_SCAN_CFG, cfg,
491 sizeof(*cfg), 0);
492 if (ret < 0) {
493 wl1271_error("SCAN configuration failed");
494 goto out;
495 }
496out:
497 kfree(cfg);
498 return ret;
499}
500
501int wl1271_scan_sched_scan_start(struct wl1271 *wl)
502{
503 struct wl1271_cmd_sched_scan_start *start;
504 int ret = 0;
505
506 wl1271_debug(DEBUG_CMD, "cmd periodic scan start");
507
508 if (wl->bss_type != BSS_TYPE_STA_BSS)
509 return -EOPNOTSUPP;
510
511 if (!test_bit(WL1271_FLAG_IDLE, &wl->flags))
512 return -EBUSY;
513
514 start = kzalloc(sizeof(*start), GFP_KERNEL);
515 if (!start)
516 return -ENOMEM;
517
518 start->tag = WL1271_SCAN_DEFAULT_TAG;
519
520 ret = wl1271_cmd_send(wl, CMD_START_PERIODIC_SCAN, start,
521 sizeof(*start), 0);
522 if (ret < 0) {
523 wl1271_error("failed to send scan start command");
524 goto out_free;
525 }
526
527out_free:
528 kfree(start);
529 return ret;
530}
531
532void wl1271_scan_sched_scan_results(struct wl1271 *wl)
533{
534 wl1271_debug(DEBUG_SCAN, "got periodic scan results");
535
536 ieee80211_sched_scan_results(wl->hw);
537}
538
539void wl1271_scan_sched_scan_stop(struct wl1271 *wl)
540{
541 struct wl1271_cmd_sched_scan_stop *stop;
542 int ret = 0;
543
544 wl1271_debug(DEBUG_CMD, "cmd periodic scan stop");
545
546 /* FIXME: what to do if alloc'ing to stop fails? */
547 stop = kzalloc(sizeof(*stop), GFP_KERNEL);
548 if (!stop) {
549 wl1271_error("failed to alloc memory to send sched scan stop");
550 return;
551 }
552
553 stop->tag = WL1271_SCAN_DEFAULT_TAG;
554
555 ret = wl1271_cmd_send(wl, CMD_STOP_PERIODIC_SCAN, stop,
556 sizeof(*stop), 0);
557 if (ret < 0) {
558 wl1271_error("failed to send sched scan stop command");
559 goto out_free;
560 }
561 wl->sched_scanning = false;
562
563out_free:
564 kfree(stop);
565}
diff --git a/drivers/net/wireless/wl12xx/scan.h b/drivers/net/wireless/wl12xx/scan.h
index 421a750add5a..c83319579ca3 100644
--- a/drivers/net/wireless/wl12xx/scan.h
+++ b/drivers/net/wireless/wl12xx/scan.h
@@ -33,6 +33,12 @@ int wl1271_scan_build_probe_req(struct wl1271 *wl,
33 const u8 *ie, size_t ie_len, u8 band); 33 const u8 *ie, size_t ie_len, u8 band);
34void wl1271_scan_stm(struct wl1271 *wl); 34void wl1271_scan_stm(struct wl1271 *wl);
35void wl1271_scan_complete_work(struct work_struct *work); 35void wl1271_scan_complete_work(struct work_struct *work);
36int wl1271_scan_sched_scan_config(struct wl1271 *wl,
37 struct cfg80211_sched_scan_request *req,
38 struct ieee80211_sched_scan_ies *ies);
39int wl1271_scan_sched_scan_start(struct wl1271 *wl);
40void wl1271_scan_sched_scan_stop(struct wl1271 *wl);
41void wl1271_scan_sched_scan_results(struct wl1271 *wl);
36 42
37#define WL1271_SCAN_MAX_CHANNELS 24 43#define WL1271_SCAN_MAX_CHANNELS 24
38#define WL1271_SCAN_DEFAULT_TAG 1 44#define WL1271_SCAN_DEFAULT_TAG 1
@@ -106,4 +112,112 @@ struct wl1271_cmd_trigger_scan_to {
106 __le32 timeout; 112 __le32 timeout;
107} __packed; 113} __packed;
108 114
115#define MAX_CHANNELS_ALL_BANDS 41
116#define SCAN_MAX_CYCLE_INTERVALS 16
117#define SCAN_MAX_BANDS 3
118
119enum {
120 SCAN_CHANNEL_TYPE_2GHZ_PASSIVE,
121 SCAN_CHANNEL_TYPE_2GHZ_ACTIVE,
122 SCAN_CHANNEL_TYPE_5GHZ_PASSIVE,
123 SCAN_CHANNEL_TYPE_5GHZ_ACTIVE,
124 SCAN_CHANNEL_TYPE_5GHZ_DFS,
125};
126
127enum {
128 SCAN_SSID_FILTER_ANY = 0,
129 SCAN_SSID_FILTER_SPECIFIC = 1,
130 SCAN_SSID_FILTER_LIST = 2,
131 SCAN_SSID_FILTER_DISABLED = 3
132};
133
134enum {
135 SCAN_BSS_TYPE_INDEPENDENT,
136 SCAN_BSS_TYPE_INFRASTRUCTURE,
137 SCAN_BSS_TYPE_ANY,
138};
139
140struct conn_scan_ch_params {
141 __le16 min_duration;
142 __le16 max_duration;
143 __le16 passive_duration;
144
145 u8 channel;
146 u8 tx_power_att;
147
148 /* bit 0: DFS channel; bit 1: DFS enabled */
149 u8 flags;
150
151 u8 padding[3];
152} __packed;
153
154struct wl1271_cmd_sched_scan_config {
155 struct wl1271_cmd_header header;
156
157 __le32 intervals[SCAN_MAX_CYCLE_INTERVALS];
158
159 s8 rssi_threshold; /* for filtering (in dBm) */
160 s8 snr_threshold; /* for filtering (in dB) */
161
162 u8 cycles; /* maximum number of scan cycles */
163 u8 report_after; /* report when this number of results are received */
164 u8 terminate; /* stop scanning after reporting */
165
166 u8 tag;
167 u8 bss_type; /* for filtering */
168 u8 filter_type;
169
170 u8 ssid_len; /* For SCAN_SSID_FILTER_SPECIFIC */
171 u8 ssid[IW_ESSID_MAX_SIZE];
172
173 u8 n_probe_reqs; /* Number of probes requests per channel */
174
175 u8 passive[SCAN_MAX_BANDS];
176 u8 active[SCAN_MAX_BANDS];
177
178 u8 dfs;
179
180 u8 padding[3];
181
182 struct conn_scan_ch_params channels[MAX_CHANNELS_ALL_BANDS];
183} __packed;
184
185
186#define SCHED_SCAN_MAX_SSIDS 8
187
188enum {
189 SCAN_SSID_TYPE_PUBLIC = 0,
190 SCAN_SSID_TYPE_HIDDEN = 1,
191};
192
193struct wl1271_ssid {
194 u8 type;
195 u8 len;
196 u8 ssid[IW_ESSID_MAX_SIZE];
197 /* u8 padding[2]; */
198} __packed;
199
200struct wl1271_cmd_sched_scan_ssid_list {
201 struct wl1271_cmd_header header;
202
203 u8 n_ssids;
204 struct wl1271_ssid ssids[SCHED_SCAN_MAX_SSIDS];
205 u8 padding[3];
206} __packed;
207
208struct wl1271_cmd_sched_scan_start {
209 struct wl1271_cmd_header header;
210
211 u8 tag;
212 u8 padding[3];
213} __packed;
214
215struct wl1271_cmd_sched_scan_stop {
216 struct wl1271_cmd_header header;
217
218 u8 tag;
219 u8 padding[3];
220} __packed;
221
222
109#endif /* __WL1271_SCAN_H__ */ 223#endif /* __WL1271_SCAN_H__ */
diff --git a/drivers/net/wireless/wl12xx/sdio.c b/drivers/net/wireless/wl12xx/sdio.c
index bcd4ad7ba90d..92d29a860fc0 100644
--- a/drivers/net/wireless/wl12xx/sdio.c
+++ b/drivers/net/wireless/wl12xx/sdio.c
@@ -82,6 +82,16 @@ static irqreturn_t wl1271_hardirq(int irq, void *cookie)
82 complete(wl->elp_compl); 82 complete(wl->elp_compl);
83 wl->elp_compl = NULL; 83 wl->elp_compl = NULL;
84 } 84 }
85
86 if (test_bit(WL1271_FLAG_SUSPENDED, &wl->flags)) {
87 /* don't enqueue a work right now. mark it as pending */
88 set_bit(WL1271_FLAG_PENDING_WORK, &wl->flags);
89 wl1271_debug(DEBUG_IRQ, "should not enqueue work");
90 disable_irq_nosync(wl->irq);
91 pm_wakeup_event(wl1271_sdio_wl_to_dev(wl), 0);
92 spin_unlock_irqrestore(&wl->wl_lock, flags);
93 return IRQ_HANDLED;
94 }
85 spin_unlock_irqrestore(&wl->wl_lock, flags); 95 spin_unlock_irqrestore(&wl->wl_lock, flags);
86 96
87 return IRQ_WAKE_THREAD; 97 return IRQ_WAKE_THREAD;
@@ -221,6 +231,7 @@ static int __devinit wl1271_probe(struct sdio_func *func,
221 const struct wl12xx_platform_data *wlan_data; 231 const struct wl12xx_platform_data *wlan_data;
222 struct wl1271 *wl; 232 struct wl1271 *wl;
223 unsigned long irqflags; 233 unsigned long irqflags;
234 mmc_pm_flag_t mmcflags;
224 int ret; 235 int ret;
225 236
226 /* We are only able to handle the wlan function */ 237 /* We are only able to handle the wlan function */
@@ -267,8 +278,18 @@ static int __devinit wl1271_probe(struct sdio_func *func,
267 goto out_free; 278 goto out_free;
268 } 279 }
269 280
281 enable_irq_wake(wl->irq);
282 device_init_wakeup(wl1271_sdio_wl_to_dev(wl), 1);
283
270 disable_irq(wl->irq); 284 disable_irq(wl->irq);
271 285
286 /* if sdio can keep power while host is suspended, enable wow */
287 mmcflags = sdio_get_host_pm_caps(func);
288 wl1271_debug(DEBUG_SDIO, "sdio PM caps = 0x%x", mmcflags);
289
290 if (mmcflags & MMC_PM_KEEP_POWER)
291 hw->wiphy->wowlan.flags = WIPHY_WOWLAN_ANY;
292
272 ret = wl1271_init_ieee80211(wl); 293 ret = wl1271_init_ieee80211(wl);
273 if (ret) 294 if (ret)
274 goto out_irq; 295 goto out_irq;
@@ -303,6 +324,8 @@ static void __devexit wl1271_remove(struct sdio_func *func)
303 pm_runtime_get_noresume(&func->dev); 324 pm_runtime_get_noresume(&func->dev);
304 325
305 wl1271_unregister_hw(wl); 326 wl1271_unregister_hw(wl);
327 device_init_wakeup(wl1271_sdio_wl_to_dev(wl), 0);
328 disable_irq_wake(wl->irq);
306 free_irq(wl->irq, wl); 329 free_irq(wl->irq, wl);
307 wl1271_free_hw(wl); 330 wl1271_free_hw(wl);
308} 331}
@@ -311,11 +334,50 @@ static int wl1271_suspend(struct device *dev)
311{ 334{
312 /* Tell MMC/SDIO core it's OK to power down the card 335 /* Tell MMC/SDIO core it's OK to power down the card
313 * (if it isn't already), but not to remove it completely */ 336 * (if it isn't already), but not to remove it completely */
314 return 0; 337 struct sdio_func *func = dev_to_sdio_func(dev);
338 struct wl1271 *wl = sdio_get_drvdata(func);
339 mmc_pm_flag_t sdio_flags;
340 int ret = 0;
341
342 wl1271_debug(DEBUG_MAC80211, "wl1271 suspend. wow_enabled: %d",
343 wl->wow_enabled);
344
345 /* check whether sdio should keep power */
346 if (wl->wow_enabled) {
347 sdio_flags = sdio_get_host_pm_caps(func);
348
349 if (!(sdio_flags & MMC_PM_KEEP_POWER)) {
350 wl1271_error("can't keep power while host "
351 "is suspended");
352 ret = -EINVAL;
353 goto out;
354 }
355
356 /* keep power while host suspended */
357 ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
358 if (ret) {
359 wl1271_error("error while trying to keep power");
360 goto out;
361 }
362
363 /* release host */
364 sdio_release_host(func);
365 }
366out:
367 return ret;
315} 368}
316 369
317static int wl1271_resume(struct device *dev) 370static int wl1271_resume(struct device *dev)
318{ 371{
372 struct sdio_func *func = dev_to_sdio_func(dev);
373 struct wl1271 *wl = sdio_get_drvdata(func);
374
375 wl1271_debug(DEBUG_MAC80211, "wl1271 resume");
376 if (wl->wow_enabled) {
377 /* claim back host */
378 sdio_claim_host(func);
379 }
380
319 return 0; 381 return 0;
320} 382}
321 383
diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c
index 7a3339fd3415..ca3ab1c1acef 100644
--- a/drivers/net/wireless/wl12xx/tx.c
+++ b/drivers/net/wireless/wl12xx/tx.c
@@ -65,6 +65,9 @@ static int wl1271_alloc_tx_id(struct wl1271 *wl, struct sk_buff *skb)
65static void wl1271_free_tx_id(struct wl1271 *wl, int id) 65static void wl1271_free_tx_id(struct wl1271 *wl, int id)
66{ 66{
67 if (__test_and_clear_bit(id, wl->tx_frames_map)) { 67 if (__test_and_clear_bit(id, wl->tx_frames_map)) {
68 if (unlikely(wl->tx_frames_cnt == ACX_TX_DESCRIPTORS))
69 clear_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags);
70
68 wl->tx_frames[id] = NULL; 71 wl->tx_frames[id] = NULL;
69 wl->tx_frames_cnt--; 72 wl->tx_frames_cnt--;
70 } 73 }
@@ -630,7 +633,7 @@ void wl1271_tx_work(struct work_struct *work)
630 633
631 wl1271_tx_work_locked(wl); 634 wl1271_tx_work_locked(wl);
632 635
633 wl1271_ps_elp_wakeup(wl); 636 wl1271_ps_elp_sleep(wl);
634out: 637out:
635 mutex_unlock(&wl->mutex); 638 mutex_unlock(&wl->mutex);
636} 639}
@@ -766,8 +769,8 @@ void wl1271_tx_reset_link_queues(struct wl1271 *wl, u8 hlid)
766 wl1271_handle_tx_low_watermark(wl); 769 wl1271_handle_tx_low_watermark(wl);
767} 770}
768 771
769/* caller must hold wl->mutex */ 772/* caller must hold wl->mutex and TX must be stopped */
770void wl1271_tx_reset(struct wl1271 *wl) 773void wl1271_tx_reset(struct wl1271 *wl, bool reset_tx_queues)
771{ 774{
772 int i; 775 int i;
773 struct sk_buff *skb; 776 struct sk_buff *skb;
@@ -803,8 +806,10 @@ void wl1271_tx_reset(struct wl1271 *wl)
803 /* 806 /*
804 * Make sure the driver is at a consistent state, in case this 807 * Make sure the driver is at a consistent state, in case this
805 * function is called from a context other than interface removal. 808 * function is called from a context other than interface removal.
809 * This call will always wake the TX queues.
806 */ 810 */
807 wl1271_handle_tx_low_watermark(wl); 811 if (reset_tx_queues)
812 wl1271_handle_tx_low_watermark(wl);
808 813
809 for (i = 0; i < ACX_TX_DESCRIPTORS; i++) { 814 for (i = 0; i < ACX_TX_DESCRIPTORS; i++) {
810 if (wl->tx_frames[i] == NULL) 815 if (wl->tx_frames[i] == NULL)
diff --git a/drivers/net/wireless/wl12xx/tx.h b/drivers/net/wireless/wl12xx/tx.h
index fc7835c4cf63..832f9258d675 100644
--- a/drivers/net/wireless/wl12xx/tx.h
+++ b/drivers/net/wireless/wl12xx/tx.h
@@ -185,7 +185,7 @@ static inline int wl1271_tx_get_queue(int queue)
185void wl1271_tx_work(struct work_struct *work); 185void wl1271_tx_work(struct work_struct *work);
186void wl1271_tx_work_locked(struct wl1271 *wl); 186void wl1271_tx_work_locked(struct wl1271 *wl);
187void wl1271_tx_complete(struct wl1271 *wl); 187void wl1271_tx_complete(struct wl1271 *wl);
188void wl1271_tx_reset(struct wl1271 *wl); 188void wl1271_tx_reset(struct wl1271 *wl, bool reset_tx_queues);
189void wl1271_tx_flush(struct wl1271 *wl); 189void wl1271_tx_flush(struct wl1271 *wl);
190u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band); 190u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band);
191u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set); 191u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set);
diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h
index 7c521af58e7d..fbe8f46d1232 100644
--- a/drivers/net/wireless/wl12xx/wl12xx.h
+++ b/drivers/net/wireless/wl12xx/wl12xx.h
@@ -172,6 +172,7 @@ extern u32 wl12xx_debug_level;
172#define WL1271_PS_STA_MAX_BLOCKS (2 * 9) 172#define WL1271_PS_STA_MAX_BLOCKS (2 * 9)
173 173
174#define WL1271_AP_BSS_INDEX 0 174#define WL1271_AP_BSS_INDEX 0
175#define WL1271_AP_DEF_INACTIV_SEC 300
175#define WL1271_AP_DEF_BEACON_EXP 20 176#define WL1271_AP_DEF_BEACON_EXP 20
176 177
177#define ACX_TX_DESCRIPTORS 32 178#define ACX_TX_DESCRIPTORS 32
@@ -345,17 +346,19 @@ enum wl12xx_flags {
345 WL1271_FLAG_TX_QUEUE_STOPPED, 346 WL1271_FLAG_TX_QUEUE_STOPPED,
346 WL1271_FLAG_TX_PENDING, 347 WL1271_FLAG_TX_PENDING,
347 WL1271_FLAG_IN_ELP, 348 WL1271_FLAG_IN_ELP,
349 WL1271_FLAG_ELP_REQUESTED,
348 WL1271_FLAG_PSM, 350 WL1271_FLAG_PSM,
349 WL1271_FLAG_PSM_REQUESTED, 351 WL1271_FLAG_PSM_REQUESTED,
350 WL1271_FLAG_IRQ_RUNNING, 352 WL1271_FLAG_IRQ_RUNNING,
351 WL1271_FLAG_IDLE, 353 WL1271_FLAG_IDLE,
352 WL1271_FLAG_IDLE_REQUESTED,
353 WL1271_FLAG_PSPOLL_FAILURE, 354 WL1271_FLAG_PSPOLL_FAILURE,
354 WL1271_FLAG_STA_STATE_SENT, 355 WL1271_FLAG_STA_STATE_SENT,
355 WL1271_FLAG_FW_TX_BUSY, 356 WL1271_FLAG_FW_TX_BUSY,
356 WL1271_FLAG_AP_STARTED, 357 WL1271_FLAG_AP_STARTED,
357 WL1271_FLAG_IF_INITIALIZED, 358 WL1271_FLAG_IF_INITIALIZED,
358 WL1271_FLAG_DUMMY_PACKET_PENDING, 359 WL1271_FLAG_DUMMY_PACKET_PENDING,
360 WL1271_FLAG_SUSPENDED,
361 WL1271_FLAG_PENDING_WORK,
359}; 362};
360 363
361struct wl1271_link { 364struct wl1271_link {
@@ -478,6 +481,8 @@ struct wl1271 {
478 struct wl1271_scan scan; 481 struct wl1271_scan scan;
479 struct delayed_work scan_complete_work; 482 struct delayed_work scan_complete_work;
480 483
484 bool sched_scanning;
485
481 /* probe-req template for the current AP */ 486 /* probe-req template for the current AP */
482 struct sk_buff *probereq; 487 struct sk_buff *probereq;
483 488
@@ -508,6 +513,7 @@ struct wl1271 {
508 unsigned int rx_filter; 513 unsigned int rx_filter;
509 514
510 struct completion *elp_compl; 515 struct completion *elp_compl;
516 struct completion *ps_compl;
511 struct delayed_work elp_work; 517 struct delayed_work elp_work;
512 struct delayed_work pspoll_work; 518 struct delayed_work pspoll_work;
513 519
@@ -562,6 +568,12 @@ struct wl1271 {
562 int tcxo_clock; 568 int tcxo_clock;
563 569
564 /* 570 /*
571 * wowlan trigger was configured during suspend.
572 * (currently, only "ANY" trigger is supported)
573 */
574 bool wow_enabled;
575
576 /*
565 * AP-mode - links indexed by HLID. The global and broadcast links 577 * AP-mode - links indexed by HLID. The global and broadcast links
566 * are always active. 578 * are always active.
567 */ 579 */
diff --git a/drivers/ssb/driver_pcicore.c b/drivers/ssb/driver_pcicore.c
index 8fde1220bc89..82feb348c8bb 100644
--- a/drivers/ssb/driver_pcicore.c
+++ b/drivers/ssb/driver_pcicore.c
@@ -21,8 +21,6 @@ static u16 ssb_pcie_mdio_read(struct ssb_pcicore *pc, u8 device, u8 address);
21static void ssb_pcie_mdio_write(struct ssb_pcicore *pc, u8 device, 21static void ssb_pcie_mdio_write(struct ssb_pcicore *pc, u8 device,
22 u8 address, u16 data); 22 u8 address, u16 data);
23 23
24static void ssb_commit_settings(struct ssb_bus *bus);
25
26static inline 24static inline
27u32 pcicore_read32(struct ssb_pcicore *pc, u16 offset) 25u32 pcicore_read32(struct ssb_pcicore *pc, u16 offset)
28{ 26{
@@ -659,30 +657,6 @@ static void ssb_pcie_mdio_write(struct ssb_pcicore *pc, u8 device,
659 pcicore_write32(pc, mdio_control, 0); 657 pcicore_write32(pc, mdio_control, 0);
660} 658}
661 659
662static void ssb_broadcast_value(struct ssb_device *dev,
663 u32 address, u32 data)
664{
665 /* This is used for both, PCI and ChipCommon core, so be careful. */
666 BUILD_BUG_ON(SSB_PCICORE_BCAST_ADDR != SSB_CHIPCO_BCAST_ADDR);
667 BUILD_BUG_ON(SSB_PCICORE_BCAST_DATA != SSB_CHIPCO_BCAST_DATA);
668
669 ssb_write32(dev, SSB_PCICORE_BCAST_ADDR, address);
670 ssb_read32(dev, SSB_PCICORE_BCAST_ADDR); /* flush */
671 ssb_write32(dev, SSB_PCICORE_BCAST_DATA, data);
672 ssb_read32(dev, SSB_PCICORE_BCAST_DATA); /* flush */
673}
674
675static void ssb_commit_settings(struct ssb_bus *bus)
676{
677 struct ssb_device *dev;
678
679 dev = bus->chipco.dev ? bus->chipco.dev : bus->pcicore.dev;
680 if (WARN_ON(!dev))
681 return;
682 /* This forces an update of the cached registers. */
683 ssb_broadcast_value(dev, 0xFD8, 0);
684}
685
686int ssb_pcicore_dev_irqvecs_enable(struct ssb_pcicore *pc, 660int ssb_pcicore_dev_irqvecs_enable(struct ssb_pcicore *pc,
687 struct ssb_device *dev) 661 struct ssb_device *dev)
688{ 662{
diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c
index ad3da93a428c..f8a13f863217 100644
--- a/drivers/ssb/main.c
+++ b/drivers/ssb/main.c
@@ -1329,6 +1329,37 @@ error:
1329} 1329}
1330EXPORT_SYMBOL(ssb_bus_powerup); 1330EXPORT_SYMBOL(ssb_bus_powerup);
1331 1331
1332static void ssb_broadcast_value(struct ssb_device *dev,
1333 u32 address, u32 data)
1334{
1335#ifdef CONFIG_SSB_DRIVER_PCICORE
1336 /* This is used for both, PCI and ChipCommon core, so be careful. */
1337 BUILD_BUG_ON(SSB_PCICORE_BCAST_ADDR != SSB_CHIPCO_BCAST_ADDR);
1338 BUILD_BUG_ON(SSB_PCICORE_BCAST_DATA != SSB_CHIPCO_BCAST_DATA);
1339#endif
1340
1341 ssb_write32(dev, SSB_CHIPCO_BCAST_ADDR, address);
1342 ssb_read32(dev, SSB_CHIPCO_BCAST_ADDR); /* flush */
1343 ssb_write32(dev, SSB_CHIPCO_BCAST_DATA, data);
1344 ssb_read32(dev, SSB_CHIPCO_BCAST_DATA); /* flush */
1345}
1346
1347void ssb_commit_settings(struct ssb_bus *bus)
1348{
1349 struct ssb_device *dev;
1350
1351#ifdef CONFIG_SSB_DRIVER_PCICORE
1352 dev = bus->chipco.dev ? bus->chipco.dev : bus->pcicore.dev;
1353#else
1354 dev = bus->chipco.dev;
1355#endif
1356 if (WARN_ON(!dev))
1357 return;
1358 /* This forces an update of the cached registers. */
1359 ssb_broadcast_value(dev, 0xFD8, 0);
1360}
1361EXPORT_SYMBOL(ssb_commit_settings);
1362
1332u32 ssb_admatch_base(u32 adm) 1363u32 ssb_admatch_base(u32 adm)
1333{ 1364{
1334 u32 base = 0; 1365 u32 base = 0;
diff --git a/drivers/ssb/scan.c b/drivers/ssb/scan.c
index 7dca719fbcfb..45e5babd3961 100644
--- a/drivers/ssb/scan.c
+++ b/drivers/ssb/scan.c
@@ -258,7 +258,10 @@ static int we_support_multiple_80211_cores(struct ssb_bus *bus)
258#ifdef CONFIG_SSB_PCIHOST 258#ifdef CONFIG_SSB_PCIHOST
259 if (bus->bustype == SSB_BUSTYPE_PCI) { 259 if (bus->bustype == SSB_BUSTYPE_PCI) {
260 if (bus->host_pci->vendor == PCI_VENDOR_ID_BROADCOM && 260 if (bus->host_pci->vendor == PCI_VENDOR_ID_BROADCOM &&
261 bus->host_pci->device == 0x4324) 261 ((bus->host_pci->device == 0x4313) ||
262 (bus->host_pci->device == 0x431A) ||
263 (bus->host_pci->device == 0x4321) ||
264 (bus->host_pci->device == 0x4324)))
262 return 1; 265 return 1;
263 } 266 }
264#endif /* CONFIG_SSB_PCIHOST */ 267#endif /* CONFIG_SSB_PCIHOST */
diff --git a/include/linux/bcma/bcma.h b/include/linux/bcma/bcma.h
new file mode 100644
index 000000000000..08763e4e848f
--- /dev/null
+++ b/include/linux/bcma/bcma.h
@@ -0,0 +1,224 @@
1#ifndef LINUX_BCMA_H_
2#define LINUX_BCMA_H_
3
4#include <linux/pci.h>
5#include <linux/mod_devicetable.h>
6
7#include <linux/bcma/bcma_driver_chipcommon.h>
8#include <linux/bcma/bcma_driver_pci.h>
9
10#include "bcma_regs.h"
11
12struct bcma_device;
13struct bcma_bus;
14
15enum bcma_hosttype {
16 BCMA_HOSTTYPE_NONE,
17 BCMA_HOSTTYPE_PCI,
18 BCMA_HOSTTYPE_SDIO,
19};
20
21struct bcma_chipinfo {
22 u16 id;
23 u8 rev;
24 u8 pkg;
25};
26
27struct bcma_host_ops {
28 u8 (*read8)(struct bcma_device *core, u16 offset);
29 u16 (*read16)(struct bcma_device *core, u16 offset);
30 u32 (*read32)(struct bcma_device *core, u16 offset);
31 void (*write8)(struct bcma_device *core, u16 offset, u8 value);
32 void (*write16)(struct bcma_device *core, u16 offset, u16 value);
33 void (*write32)(struct bcma_device *core, u16 offset, u32 value);
34 /* Agent ops */
35 u32 (*aread32)(struct bcma_device *core, u16 offset);
36 void (*awrite32)(struct bcma_device *core, u16 offset, u32 value);
37};
38
39/* Core manufacturers */
40#define BCMA_MANUF_ARM 0x43B
41#define BCMA_MANUF_MIPS 0x4A7
42#define BCMA_MANUF_BCM 0x4BF
43
44/* Core class values. */
45#define BCMA_CL_SIM 0x0
46#define BCMA_CL_EROM 0x1
47#define BCMA_CL_CORESIGHT 0x9
48#define BCMA_CL_VERIF 0xB
49#define BCMA_CL_OPTIMO 0xD
50#define BCMA_CL_GEN 0xE
51#define BCMA_CL_PRIMECELL 0xF
52
53/* Core-ID values. */
54#define BCMA_CORE_OOB_ROUTER 0x367 /* Out of band */
55#define BCMA_CORE_INVALID 0x700
56#define BCMA_CORE_CHIPCOMMON 0x800
57#define BCMA_CORE_ILINE20 0x801
58#define BCMA_CORE_SRAM 0x802
59#define BCMA_CORE_SDRAM 0x803
60#define BCMA_CORE_PCI 0x804
61#define BCMA_CORE_MIPS 0x805
62#define BCMA_CORE_ETHERNET 0x806
63#define BCMA_CORE_V90 0x807
64#define BCMA_CORE_USB11_HOSTDEV 0x808
65#define BCMA_CORE_ADSL 0x809
66#define BCMA_CORE_ILINE100 0x80A
67#define BCMA_CORE_IPSEC 0x80B
68#define BCMA_CORE_UTOPIA 0x80C
69#define BCMA_CORE_PCMCIA 0x80D
70#define BCMA_CORE_INTERNAL_MEM 0x80E
71#define BCMA_CORE_MEMC_SDRAM 0x80F
72#define BCMA_CORE_OFDM 0x810
73#define BCMA_CORE_EXTIF 0x811
74#define BCMA_CORE_80211 0x812
75#define BCMA_CORE_PHY_A 0x813
76#define BCMA_CORE_PHY_B 0x814
77#define BCMA_CORE_PHY_G 0x815
78#define BCMA_CORE_MIPS_3302 0x816
79#define BCMA_CORE_USB11_HOST 0x817
80#define BCMA_CORE_USB11_DEV 0x818
81#define BCMA_CORE_USB20_HOST 0x819
82#define BCMA_CORE_USB20_DEV 0x81A
83#define BCMA_CORE_SDIO_HOST 0x81B
84#define BCMA_CORE_ROBOSWITCH 0x81C
85#define BCMA_CORE_PARA_ATA 0x81D
86#define BCMA_CORE_SATA_XORDMA 0x81E
87#define BCMA_CORE_ETHERNET_GBIT 0x81F
88#define BCMA_CORE_PCIE 0x820
89#define BCMA_CORE_PHY_N 0x821
90#define BCMA_CORE_SRAM_CTL 0x822
91#define BCMA_CORE_MINI_MACPHY 0x823
92#define BCMA_CORE_ARM_1176 0x824
93#define BCMA_CORE_ARM_7TDMI 0x825
94#define BCMA_CORE_PHY_LP 0x826
95#define BCMA_CORE_PMU 0x827
96#define BCMA_CORE_PHY_SSN 0x828
97#define BCMA_CORE_SDIO_DEV 0x829
98#define BCMA_CORE_ARM_CM3 0x82A
99#define BCMA_CORE_PHY_HT 0x82B
100#define BCMA_CORE_MIPS_74K 0x82C
101#define BCMA_CORE_MAC_GBIT 0x82D
102#define BCMA_CORE_DDR12_MEM_CTL 0x82E
103#define BCMA_CORE_PCIE_RC 0x82F /* PCIe Root Complex */
104#define BCMA_CORE_OCP_OCP_BRIDGE 0x830
105#define BCMA_CORE_SHARED_COMMON 0x831
106#define BCMA_CORE_OCP_AHB_BRIDGE 0x832
107#define BCMA_CORE_SPI_HOST 0x833
108#define BCMA_CORE_I2S 0x834
109#define BCMA_CORE_SDR_DDR1_MEM_CTL 0x835 /* SDR/DDR1 memory controller core */
110#define BCMA_CORE_SHIM 0x837 /* SHIM component in ubus/6362 */
111#define BCMA_CORE_DEFAULT 0xFFF
112
113#define BCMA_MAX_NR_CORES 16
114
115struct bcma_device {
116 struct bcma_bus *bus;
117 struct bcma_device_id id;
118
119 struct device dev;
120 bool dev_registered;
121
122 u8 core_index;
123
124 u32 addr;
125 u32 wrap;
126
127 void *drvdata;
128 struct list_head list;
129};
130
131static inline void *bcma_get_drvdata(struct bcma_device *core)
132{
133 return core->drvdata;
134}
135static inline void bcma_set_drvdata(struct bcma_device *core, void *drvdata)
136{
137 core->drvdata = drvdata;
138}
139
140struct bcma_driver {
141 const char *name;
142 const struct bcma_device_id *id_table;
143
144 int (*probe)(struct bcma_device *dev);
145 void (*remove)(struct bcma_device *dev);
146 int (*suspend)(struct bcma_device *dev, pm_message_t state);
147 int (*resume)(struct bcma_device *dev);
148 void (*shutdown)(struct bcma_device *dev);
149
150 struct device_driver drv;
151};
152extern
153int __bcma_driver_register(struct bcma_driver *drv, struct module *owner);
154static inline int bcma_driver_register(struct bcma_driver *drv)
155{
156 return __bcma_driver_register(drv, THIS_MODULE);
157}
158extern void bcma_driver_unregister(struct bcma_driver *drv);
159
160struct bcma_bus {
161 /* The MMIO area. */
162 void __iomem *mmio;
163
164 const struct bcma_host_ops *ops;
165
166 enum bcma_hosttype hosttype;
167 union {
168 /* Pointer to the PCI bus (only for BCMA_HOSTTYPE_PCI) */
169 struct pci_dev *host_pci;
170 /* Pointer to the SDIO device (only for BCMA_HOSTTYPE_SDIO) */
171 struct sdio_func *host_sdio;
172 };
173
174 struct bcma_chipinfo chipinfo;
175
176 struct bcma_device *mapped_core;
177 struct list_head cores;
178 u8 nr_cores;
179
180 struct bcma_drv_cc drv_cc;
181 struct bcma_drv_pci drv_pci;
182};
183
184extern inline u32 bcma_read8(struct bcma_device *core, u16 offset)
185{
186 return core->bus->ops->read8(core, offset);
187}
188extern inline u32 bcma_read16(struct bcma_device *core, u16 offset)
189{
190 return core->bus->ops->read16(core, offset);
191}
192extern inline u32 bcma_read32(struct bcma_device *core, u16 offset)
193{
194 return core->bus->ops->read32(core, offset);
195}
196extern inline
197void bcma_write8(struct bcma_device *core, u16 offset, u32 value)
198{
199 core->bus->ops->write8(core, offset, value);
200}
201extern inline
202void bcma_write16(struct bcma_device *core, u16 offset, u32 value)
203{
204 core->bus->ops->write16(core, offset, value);
205}
206extern inline
207void bcma_write32(struct bcma_device *core, u16 offset, u32 value)
208{
209 core->bus->ops->write32(core, offset, value);
210}
211extern inline u32 bcma_aread32(struct bcma_device *core, u16 offset)
212{
213 return core->bus->ops->aread32(core, offset);
214}
215extern inline
216void bcma_awrite32(struct bcma_device *core, u16 offset, u32 value)
217{
218 core->bus->ops->awrite32(core, offset, value);
219}
220
221extern bool bcma_core_is_enabled(struct bcma_device *core);
222extern int bcma_core_enable(struct bcma_device *core, u32 flags);
223
224#endif /* LINUX_BCMA_H_ */
diff --git a/include/linux/bcma/bcma_driver_chipcommon.h b/include/linux/bcma/bcma_driver_chipcommon.h
new file mode 100644
index 000000000000..083c3b6cd5ce
--- /dev/null
+++ b/include/linux/bcma/bcma_driver_chipcommon.h
@@ -0,0 +1,302 @@
1#ifndef LINUX_BCMA_DRIVER_CC_H_
2#define LINUX_BCMA_DRIVER_CC_H_
3
4/** ChipCommon core registers. **/
5#define BCMA_CC_ID 0x0000
6#define BCMA_CC_ID_ID 0x0000FFFF
7#define BCMA_CC_ID_ID_SHIFT 0
8#define BCMA_CC_ID_REV 0x000F0000
9#define BCMA_CC_ID_REV_SHIFT 16
10#define BCMA_CC_ID_PKG 0x00F00000
11#define BCMA_CC_ID_PKG_SHIFT 20
12#define BCMA_CC_ID_NRCORES 0x0F000000
13#define BCMA_CC_ID_NRCORES_SHIFT 24
14#define BCMA_CC_ID_TYPE 0xF0000000
15#define BCMA_CC_ID_TYPE_SHIFT 28
16#define BCMA_CC_CAP 0x0004 /* Capabilities */
17#define BCMA_CC_CAP_NRUART 0x00000003 /* # of UARTs */
18#define BCMA_CC_CAP_MIPSEB 0x00000004 /* MIPS in BigEndian Mode */
19#define BCMA_CC_CAP_UARTCLK 0x00000018 /* UART clock select */
20#define BCMA_CC_CAP_UARTCLK_INT 0x00000008 /* UARTs are driven by internal divided clock */
21#define BCMA_CC_CAP_UARTGPIO 0x00000020 /* UARTs on GPIO 15-12 */
22#define BCMA_CC_CAP_EXTBUS 0x000000C0 /* External buses present */
23#define BCMA_CC_CAP_FLASHT 0x00000700 /* Flash Type */
24#define BCMA_CC_FLASHT_NONE 0x00000000 /* No flash */
25#define BCMA_CC_FLASHT_STSER 0x00000100 /* ST serial flash */
26#define BCMA_CC_FLASHT_ATSER 0x00000200 /* Atmel serial flash */
27#define BCMA_CC_FLASHT_PARA 0x00000700 /* Parallel flash */
28#define BCMA_CC_CAP_PLLT 0x00038000 /* PLL Type */
29#define BCMA_PLLTYPE_NONE 0x00000000
30#define BCMA_PLLTYPE_1 0x00010000 /* 48Mhz base, 3 dividers */
31#define BCMA_PLLTYPE_2 0x00020000 /* 48Mhz, 4 dividers */
32#define BCMA_PLLTYPE_3 0x00030000 /* 25Mhz, 2 dividers */
33#define BCMA_PLLTYPE_4 0x00008000 /* 48Mhz, 4 dividers */
34#define BCMA_PLLTYPE_5 0x00018000 /* 25Mhz, 4 dividers */
35#define BCMA_PLLTYPE_6 0x00028000 /* 100/200 or 120/240 only */
36#define BCMA_PLLTYPE_7 0x00038000 /* 25Mhz, 4 dividers */
37#define BCMA_CC_CAP_PCTL 0x00040000 /* Power Control */
38#define BCMA_CC_CAP_OTPS 0x00380000 /* OTP size */
39#define BCMA_CC_CAP_OTPS_SHIFT 19
40#define BCMA_CC_CAP_OTPS_BASE 5
41#define BCMA_CC_CAP_JTAGM 0x00400000 /* JTAG master present */
42#define BCMA_CC_CAP_BROM 0x00800000 /* Internal boot ROM active */
43#define BCMA_CC_CAP_64BIT 0x08000000 /* 64-bit Backplane */
44#define BCMA_CC_CAP_PMU 0x10000000 /* PMU available (rev >= 20) */
45#define BCMA_CC_CAP_ECI 0x20000000 /* ECI available (rev >= 20) */
46#define BCMA_CC_CAP_SPROM 0x40000000 /* SPROM present */
47#define BCMA_CC_CORECTL 0x0008
48#define BCMA_CC_CORECTL_UARTCLK0 0x00000001 /* Drive UART with internal clock */
49#define BCMA_CC_CORECTL_SE 0x00000002 /* sync clk out enable (corerev >= 3) */
50#define BCMA_CC_CORECTL_UARTCLKEN 0x00000008 /* UART clock enable (rev >= 21) */
51#define BCMA_CC_BIST 0x000C
52#define BCMA_CC_OTPS 0x0010 /* OTP status */
53#define BCMA_CC_OTPS_PROGFAIL 0x80000000
54#define BCMA_CC_OTPS_PROTECT 0x00000007
55#define BCMA_CC_OTPS_HW_PROTECT 0x00000001
56#define BCMA_CC_OTPS_SW_PROTECT 0x00000002
57#define BCMA_CC_OTPS_CID_PROTECT 0x00000004
58#define BCMA_CC_OTPC 0x0014 /* OTP control */
59#define BCMA_CC_OTPC_RECWAIT 0xFF000000
60#define BCMA_CC_OTPC_PROGWAIT 0x00FFFF00
61#define BCMA_CC_OTPC_PRW_SHIFT 8
62#define BCMA_CC_OTPC_MAXFAIL 0x00000038
63#define BCMA_CC_OTPC_VSEL 0x00000006
64#define BCMA_CC_OTPC_SELVL 0x00000001
65#define BCMA_CC_OTPP 0x0018 /* OTP prog */
66#define BCMA_CC_OTPP_COL 0x000000FF
67#define BCMA_CC_OTPP_ROW 0x0000FF00
68#define BCMA_CC_OTPP_ROW_SHIFT 8
69#define BCMA_CC_OTPP_READERR 0x10000000
70#define BCMA_CC_OTPP_VALUE 0x20000000
71#define BCMA_CC_OTPP_READ 0x40000000
72#define BCMA_CC_OTPP_START 0x80000000
73#define BCMA_CC_OTPP_BUSY 0x80000000
74#define BCMA_CC_IRQSTAT 0x0020
75#define BCMA_CC_IRQMASK 0x0024
76#define BCMA_CC_IRQ_GPIO 0x00000001 /* gpio intr */
77#define BCMA_CC_IRQ_EXT 0x00000002 /* ro: ext intr pin (corerev >= 3) */
78#define BCMA_CC_IRQ_WDRESET 0x80000000 /* watchdog reset occurred */
79#define BCMA_CC_CHIPCTL 0x0028 /* Rev >= 11 only */
80#define BCMA_CC_CHIPSTAT 0x002C /* Rev >= 11 only */
81#define BCMA_CC_JCMD 0x0030 /* Rev >= 10 only */
82#define BCMA_CC_JCMD_START 0x80000000
83#define BCMA_CC_JCMD_BUSY 0x80000000
84#define BCMA_CC_JCMD_PAUSE 0x40000000
85#define BCMA_CC_JCMD0_ACC_MASK 0x0000F000
86#define BCMA_CC_JCMD0_ACC_IRDR 0x00000000
87#define BCMA_CC_JCMD0_ACC_DR 0x00001000
88#define BCMA_CC_JCMD0_ACC_IR 0x00002000
89#define BCMA_CC_JCMD0_ACC_RESET 0x00003000
90#define BCMA_CC_JCMD0_ACC_IRPDR 0x00004000
91#define BCMA_CC_JCMD0_ACC_PDR 0x00005000
92#define BCMA_CC_JCMD0_IRW_MASK 0x00000F00
93#define BCMA_CC_JCMD_ACC_MASK 0x000F0000 /* Changes for corerev 11 */
94#define BCMA_CC_JCMD_ACC_IRDR 0x00000000
95#define BCMA_CC_JCMD_ACC_DR 0x00010000
96#define BCMA_CC_JCMD_ACC_IR 0x00020000
97#define BCMA_CC_JCMD_ACC_RESET 0x00030000
98#define BCMA_CC_JCMD_ACC_IRPDR 0x00040000
99#define BCMA_CC_JCMD_ACC_PDR 0x00050000
100#define BCMA_CC_JCMD_IRW_MASK 0x00001F00
101#define BCMA_CC_JCMD_IRW_SHIFT 8
102#define BCMA_CC_JCMD_DRW_MASK 0x0000003F
103#define BCMA_CC_JIR 0x0034 /* Rev >= 10 only */
104#define BCMA_CC_JDR 0x0038 /* Rev >= 10 only */
105#define BCMA_CC_JCTL 0x003C /* Rev >= 10 only */
106#define BCMA_CC_JCTL_FORCE_CLK 4 /* Force clock */
107#define BCMA_CC_JCTL_EXT_EN 2 /* Enable external targets */
108#define BCMA_CC_JCTL_EN 1 /* Enable Jtag master */
109#define BCMA_CC_FLASHCTL 0x0040
110#define BCMA_CC_FLASHCTL_START 0x80000000
111#define BCMA_CC_FLASHCTL_BUSY BCMA_CC_FLASHCTL_START
112#define BCMA_CC_FLASHADDR 0x0044
113#define BCMA_CC_FLASHDATA 0x0048
114#define BCMA_CC_BCAST_ADDR 0x0050
115#define BCMA_CC_BCAST_DATA 0x0054
116#define BCMA_CC_GPIOPULLUP 0x0058 /* Rev >= 20 only */
117#define BCMA_CC_GPIOPULLDOWN 0x005C /* Rev >= 20 only */
118#define BCMA_CC_GPIOIN 0x0060
119#define BCMA_CC_GPIOOUT 0x0064
120#define BCMA_CC_GPIOOUTEN 0x0068
121#define BCMA_CC_GPIOCTL 0x006C
122#define BCMA_CC_GPIOPOL 0x0070
123#define BCMA_CC_GPIOIRQ 0x0074
124#define BCMA_CC_WATCHDOG 0x0080
125#define BCMA_CC_GPIOTIMER 0x0088 /* LED powersave (corerev >= 16) */
126#define BCMA_CC_GPIOTIMER_OFFTIME 0x0000FFFF
127#define BCMA_CC_GPIOTIMER_OFFTIME_SHIFT 0
128#define BCMA_CC_GPIOTIMER_ONTIME 0xFFFF0000
129#define BCMA_CC_GPIOTIMER_ONTIME_SHIFT 16
130#define BCMA_CC_GPIOTOUTM 0x008C /* LED powersave (corerev >= 16) */
131#define BCMA_CC_CLOCK_N 0x0090
132#define BCMA_CC_CLOCK_SB 0x0094
133#define BCMA_CC_CLOCK_PCI 0x0098
134#define BCMA_CC_CLOCK_M2 0x009C
135#define BCMA_CC_CLOCK_MIPS 0x00A0
136#define BCMA_CC_CLKDIV 0x00A4 /* Rev >= 3 only */
137#define BCMA_CC_CLKDIV_SFLASH 0x0F000000
138#define BCMA_CC_CLKDIV_SFLASH_SHIFT 24
139#define BCMA_CC_CLKDIV_OTP 0x000F0000
140#define BCMA_CC_CLKDIV_OTP_SHIFT 16
141#define BCMA_CC_CLKDIV_JTAG 0x00000F00
142#define BCMA_CC_CLKDIV_JTAG_SHIFT 8
143#define BCMA_CC_CLKDIV_UART 0x000000FF
144#define BCMA_CC_CAP_EXT 0x00AC /* Capabilities */
145#define BCMA_CC_PLLONDELAY 0x00B0 /* Rev >= 4 only */
146#define BCMA_CC_FREFSELDELAY 0x00B4 /* Rev >= 4 only */
147#define BCMA_CC_SLOWCLKCTL 0x00B8 /* 6 <= Rev <= 9 only */
148#define BCMA_CC_SLOWCLKCTL_SRC 0x00000007 /* slow clock source mask */
149#define BCMA_CC_SLOWCLKCTL_SRC_LPO 0x00000000 /* source of slow clock is LPO */
150#define BCMA_CC_SLOWCLKCTL_SRC_XTAL 0x00000001 /* source of slow clock is crystal */
151#define BCMA_CC_SLOECLKCTL_SRC_PCI 0x00000002 /* source of slow clock is PCI */
152#define BCMA_CC_SLOWCLKCTL_LPOFREQ 0x00000200 /* LPOFreqSel, 1: 160Khz, 0: 32KHz */
153#define BCMA_CC_SLOWCLKCTL_LPOPD 0x00000400 /* LPOPowerDown, 1: LPO is disabled, 0: LPO is enabled */
154#define BCMA_CC_SLOWCLKCTL_FSLOW 0x00000800 /* ForceSlowClk, 1: sb/cores running on slow clock, 0: power logic control */
155#define BCMA_CC_SLOWCLKCTL_IPLL 0x00001000 /* IgnorePllOffReq, 1/0: power logic ignores/honors PLL clock disable requests from core */
156#define BCMA_CC_SLOWCLKCTL_ENXTAL 0x00002000 /* XtalControlEn, 1/0: power logic does/doesn't disable crystal when appropriate */
157#define BCMA_CC_SLOWCLKCTL_XTALPU 0x00004000 /* XtalPU (RO), 1/0: crystal running/disabled */
158#define BCMA_CC_SLOWCLKCTL_CLKDIV 0xFFFF0000 /* ClockDivider (SlowClk = 1/(4+divisor)) */
159#define BCMA_CC_SLOWCLKCTL_CLKDIV_SHIFT 16
160#define BCMA_CC_SYSCLKCTL 0x00C0 /* Rev >= 3 only */
161#define BCMA_CC_SYSCLKCTL_IDLPEN 0x00000001 /* ILPen: Enable Idle Low Power */
162#define BCMA_CC_SYSCLKCTL_ALPEN 0x00000002 /* ALPen: Enable Active Low Power */
163#define BCMA_CC_SYSCLKCTL_PLLEN 0x00000004 /* ForcePLLOn */
164#define BCMA_CC_SYSCLKCTL_FORCEALP 0x00000008 /* Force ALP (or HT if ALPen is not set */
165#define BCMA_CC_SYSCLKCTL_FORCEHT 0x00000010 /* Force HT */
166#define BCMA_CC_SYSCLKCTL_CLKDIV 0xFFFF0000 /* ClkDiv (ILP = 1/(4+divisor)) */
167#define BCMA_CC_SYSCLKCTL_CLKDIV_SHIFT 16
168#define BCMA_CC_CLKSTSTR 0x00C4 /* Rev >= 3 only */
169#define BCMA_CC_EROM 0x00FC
170#define BCMA_CC_PCMCIA_CFG 0x0100
171#define BCMA_CC_PCMCIA_MEMWAIT 0x0104
172#define BCMA_CC_PCMCIA_ATTRWAIT 0x0108
173#define BCMA_CC_PCMCIA_IOWAIT 0x010C
174#define BCMA_CC_IDE_CFG 0x0110
175#define BCMA_CC_IDE_MEMWAIT 0x0114
176#define BCMA_CC_IDE_ATTRWAIT 0x0118
177#define BCMA_CC_IDE_IOWAIT 0x011C
178#define BCMA_CC_PROG_CFG 0x0120
179#define BCMA_CC_PROG_WAITCNT 0x0124
180#define BCMA_CC_FLASH_CFG 0x0128
181#define BCMA_CC_FLASH_WAITCNT 0x012C
182#define BCMA_CC_CLKCTLST 0x01E0 /* Clock control and status (rev >= 20) */
183#define BCMA_CC_CLKCTLST_FORCEALP 0x00000001 /* Force ALP request */
184#define BCMA_CC_CLKCTLST_FORCEHT 0x00000002 /* Force HT request */
185#define BCMA_CC_CLKCTLST_FORCEILP 0x00000004 /* Force ILP request */
186#define BCMA_CC_CLKCTLST_HAVEALPREQ 0x00000008 /* ALP available request */
187#define BCMA_CC_CLKCTLST_HAVEHTREQ 0x00000010 /* HT available request */
188#define BCMA_CC_CLKCTLST_HWCROFF 0x00000020 /* Force HW clock request off */
189#define BCMA_CC_CLKCTLST_HAVEHT 0x00010000 /* HT available */
190#define BCMA_CC_CLKCTLST_HAVEALP 0x00020000 /* APL available */
191#define BCMA_CC_HW_WORKAROUND 0x01E4 /* Hardware workaround (rev >= 20) */
192#define BCMA_CC_UART0_DATA 0x0300
193#define BCMA_CC_UART0_IMR 0x0304
194#define BCMA_CC_UART0_FCR 0x0308
195#define BCMA_CC_UART0_LCR 0x030C
196#define BCMA_CC_UART0_MCR 0x0310
197#define BCMA_CC_UART0_LSR 0x0314
198#define BCMA_CC_UART0_MSR 0x0318
199#define BCMA_CC_UART0_SCRATCH 0x031C
200#define BCMA_CC_UART1_DATA 0x0400
201#define BCMA_CC_UART1_IMR 0x0404
202#define BCMA_CC_UART1_FCR 0x0408
203#define BCMA_CC_UART1_LCR 0x040C
204#define BCMA_CC_UART1_MCR 0x0410
205#define BCMA_CC_UART1_LSR 0x0414
206#define BCMA_CC_UART1_MSR 0x0418
207#define BCMA_CC_UART1_SCRATCH 0x041C
208/* PMU registers (rev >= 20) */
209#define BCMA_CC_PMU_CTL 0x0600 /* PMU control */
210#define BCMA_CC_PMU_CTL_ILP_DIV 0xFFFF0000 /* ILP div mask */
211#define BCMA_CC_PMU_CTL_ILP_DIV_SHIFT 16
212#define BCMA_CC_PMU_CTL_NOILPONW 0x00000200 /* No ILP on wait */
213#define BCMA_CC_PMU_CTL_HTREQEN 0x00000100 /* HT req enable */
214#define BCMA_CC_PMU_CTL_ALPREQEN 0x00000080 /* ALP req enable */
215#define BCMA_CC_PMU_CTL_XTALFREQ 0x0000007C /* Crystal freq */
216#define BCMA_CC_PMU_CTL_XTALFREQ_SHIFT 2
217#define BCMA_CC_PMU_CTL_ILPDIVEN 0x00000002 /* ILP div enable */
218#define BCMA_CC_PMU_CTL_LPOSEL 0x00000001 /* LPO sel */
219#define BCMA_CC_PMU_CAP 0x0604 /* PMU capabilities */
220#define BCMA_CC_PMU_CAP_REVISION 0x000000FF /* Revision mask */
221#define BCMA_CC_PMU_STAT 0x0608 /* PMU status */
222#define BCMA_CC_PMU_STAT_INTPEND 0x00000040 /* Interrupt pending */
223#define BCMA_CC_PMU_STAT_SBCLKST 0x00000030 /* Backplane clock status? */
224#define BCMA_CC_PMU_STAT_HAVEALP 0x00000008 /* ALP available */
225#define BCMA_CC_PMU_STAT_HAVEHT 0x00000004 /* HT available */
226#define BCMA_CC_PMU_STAT_RESINIT 0x00000003 /* Res init */
227#define BCMA_CC_PMU_RES_STAT 0x060C /* PMU res status */
228#define BCMA_CC_PMU_RES_PEND 0x0610 /* PMU res pending */
229#define BCMA_CC_PMU_TIMER 0x0614 /* PMU timer */
230#define BCMA_CC_PMU_MINRES_MSK 0x0618 /* PMU min res mask */
231#define BCMA_CC_PMU_MAXRES_MSK 0x061C /* PMU max res mask */
232#define BCMA_CC_PMU_RES_TABSEL 0x0620 /* PMU res table sel */
233#define BCMA_CC_PMU_RES_DEPMSK 0x0624 /* PMU res dep mask */
234#define BCMA_CC_PMU_RES_UPDNTM 0x0628 /* PMU res updown timer */
235#define BCMA_CC_PMU_RES_TIMER 0x062C /* PMU res timer */
236#define BCMA_CC_PMU_CLKSTRETCH 0x0630 /* PMU clockstretch */
237#define BCMA_CC_PMU_WATCHDOG 0x0634 /* PMU watchdog */
238#define BCMA_CC_PMU_RES_REQTS 0x0640 /* PMU res req timer sel */
239#define BCMA_CC_PMU_RES_REQT 0x0644 /* PMU res req timer */
240#define BCMA_CC_PMU_RES_REQM 0x0648 /* PMU res req mask */
241#define BCMA_CC_CHIPCTL_ADDR 0x0650
242#define BCMA_CC_CHIPCTL_DATA 0x0654
243#define BCMA_CC_REGCTL_ADDR 0x0658
244#define BCMA_CC_REGCTL_DATA 0x065C
245#define BCMA_CC_PLLCTL_ADDR 0x0660
246#define BCMA_CC_PLLCTL_DATA 0x0664
247
248/* Data for the PMU, if available.
249 * Check availability with ((struct bcma_chipcommon)->capabilities & BCMA_CC_CAP_PMU)
250 */
251struct bcma_chipcommon_pmu {
252 u8 rev; /* PMU revision */
253 u32 crystalfreq; /* The active crystal frequency (in kHz) */
254};
255
256struct bcma_drv_cc {
257 struct bcma_device *core;
258 u32 status;
259 u32 capabilities;
260 u32 capabilities_ext;
261 /* Fast Powerup Delay constant */
262 u16 fast_pwrup_delay;
263 struct bcma_chipcommon_pmu pmu;
264};
265
266/* Register access */
267#define bcma_cc_read32(cc, offset) \
268 bcma_read32((cc)->core, offset)
269#define bcma_cc_write32(cc, offset, val) \
270 bcma_write32((cc)->core, offset, val)
271
272#define bcma_cc_mask32(cc, offset, mask) \
273 bcma_cc_write32(cc, offset, bcma_cc_read32(cc, offset) & (mask))
274#define bcma_cc_set32(cc, offset, set) \
275 bcma_cc_write32(cc, offset, bcma_cc_read32(cc, offset) | (set))
276#define bcma_cc_maskset32(cc, offset, mask, set) \
277 bcma_cc_write32(cc, offset, (bcma_cc_read32(cc, offset) & (mask)) | (set))
278
279extern void bcma_core_chipcommon_init(struct bcma_drv_cc *cc);
280
281extern void bcma_chipco_suspend(struct bcma_drv_cc *cc);
282extern void bcma_chipco_resume(struct bcma_drv_cc *cc);
283
284extern void bcma_chipco_watchdog_timer_set(struct bcma_drv_cc *cc,
285 u32 ticks);
286
287void bcma_chipco_irq_mask(struct bcma_drv_cc *cc, u32 mask, u32 value);
288
289u32 bcma_chipco_irq_status(struct bcma_drv_cc *cc, u32 mask);
290
291/* Chipcommon GPIO pin access. */
292u32 bcma_chipco_gpio_in(struct bcma_drv_cc *cc, u32 mask);
293u32 bcma_chipco_gpio_out(struct bcma_drv_cc *cc, u32 mask, u32 value);
294u32 bcma_chipco_gpio_outen(struct bcma_drv_cc *cc, u32 mask, u32 value);
295u32 bcma_chipco_gpio_control(struct bcma_drv_cc *cc, u32 mask, u32 value);
296u32 bcma_chipco_gpio_intmask(struct bcma_drv_cc *cc, u32 mask, u32 value);
297u32 bcma_chipco_gpio_polarity(struct bcma_drv_cc *cc, u32 mask, u32 value);
298
299/* PMU support */
300extern void bcma_pmu_init(struct bcma_drv_cc *cc);
301
302#endif /* LINUX_BCMA_DRIVER_CC_H_ */
diff --git a/include/linux/bcma/bcma_driver_pci.h b/include/linux/bcma/bcma_driver_pci.h
new file mode 100644
index 000000000000..b7e191cf00ec
--- /dev/null
+++ b/include/linux/bcma/bcma_driver_pci.h
@@ -0,0 +1,89 @@
1#ifndef LINUX_BCMA_DRIVER_PCI_H_
2#define LINUX_BCMA_DRIVER_PCI_H_
3
4#include <linux/types.h>
5
6struct pci_dev;
7
8/** PCI core registers. **/
9#define BCMA_CORE_PCI_CTL 0x0000 /* PCI Control */
10#define BCMA_CORE_PCI_CTL_RST_OE 0x00000001 /* PCI_RESET Output Enable */
11#define BCMA_CORE_PCI_CTL_RST 0x00000002 /* PCI_RESET driven out to pin */
12#define BCMA_CORE_PCI_CTL_CLK_OE 0x00000004 /* Clock gate Output Enable */
13#define BCMA_CORE_PCI_CTL_CLK 0x00000008 /* Gate for clock driven out to pin */
14#define BCMA_CORE_PCI_ARBCTL 0x0010 /* PCI Arbiter Control */
15#define BCMA_CORE_PCI_ARBCTL_INTERN 0x00000001 /* Use internal arbiter */
16#define BCMA_CORE_PCI_ARBCTL_EXTERN 0x00000002 /* Use external arbiter */
17#define BCMA_CORE_PCI_ARBCTL_PARKID 0x00000006 /* Mask, selects which agent is parked on an idle bus */
18#define BCMA_CORE_PCI_ARBCTL_PARKID_LAST 0x00000000 /* Last requestor */
19#define BCMA_CORE_PCI_ARBCTL_PARKID_4710 0x00000002 /* 4710 */
20#define BCMA_CORE_PCI_ARBCTL_PARKID_EXT0 0x00000004 /* External requestor 0 */
21#define BCMA_CORE_PCI_ARBCTL_PARKID_EXT1 0x00000006 /* External requestor 1 */
22#define BCMA_CORE_PCI_ISTAT 0x0020 /* Interrupt status */
23#define BCMA_CORE_PCI_ISTAT_INTA 0x00000001 /* PCI INTA# */
24#define BCMA_CORE_PCI_ISTAT_INTB 0x00000002 /* PCI INTB# */
25#define BCMA_CORE_PCI_ISTAT_SERR 0x00000004 /* PCI SERR# (write to clear) */
26#define BCMA_CORE_PCI_ISTAT_PERR 0x00000008 /* PCI PERR# (write to clear) */
27#define BCMA_CORE_PCI_ISTAT_PME 0x00000010 /* PCI PME# */
28#define BCMA_CORE_PCI_IMASK 0x0024 /* Interrupt mask */
29#define BCMA_CORE_PCI_IMASK_INTA 0x00000001 /* PCI INTA# */
30#define BCMA_CORE_PCI_IMASK_INTB 0x00000002 /* PCI INTB# */
31#define BCMA_CORE_PCI_IMASK_SERR 0x00000004 /* PCI SERR# */
32#define BCMA_CORE_PCI_IMASK_PERR 0x00000008 /* PCI PERR# */
33#define BCMA_CORE_PCI_IMASK_PME 0x00000010 /* PCI PME# */
34#define BCMA_CORE_PCI_MBOX 0x0028 /* Backplane to PCI Mailbox */
35#define BCMA_CORE_PCI_MBOX_F0_0 0x00000100 /* PCI function 0, INT 0 */
36#define BCMA_CORE_PCI_MBOX_F0_1 0x00000200 /* PCI function 0, INT 1 */
37#define BCMA_CORE_PCI_MBOX_F1_0 0x00000400 /* PCI function 1, INT 0 */
38#define BCMA_CORE_PCI_MBOX_F1_1 0x00000800 /* PCI function 1, INT 1 */
39#define BCMA_CORE_PCI_MBOX_F2_0 0x00001000 /* PCI function 2, INT 0 */
40#define BCMA_CORE_PCI_MBOX_F2_1 0x00002000 /* PCI function 2, INT 1 */
41#define BCMA_CORE_PCI_MBOX_F3_0 0x00004000 /* PCI function 3, INT 0 */
42#define BCMA_CORE_PCI_MBOX_F3_1 0x00008000 /* PCI function 3, INT 1 */
43#define BCMA_CORE_PCI_BCAST_ADDR 0x0050 /* Backplane Broadcast Address */
44#define BCMA_CORE_PCI_BCAST_ADDR_MASK 0x000000FF
45#define BCMA_CORE_PCI_BCAST_DATA 0x0054 /* Backplane Broadcast Data */
46#define BCMA_CORE_PCI_GPIO_IN 0x0060 /* rev >= 2 only */
47#define BCMA_CORE_PCI_GPIO_OUT 0x0064 /* rev >= 2 only */
48#define BCMA_CORE_PCI_GPIO_ENABLE 0x0068 /* rev >= 2 only */
49#define BCMA_CORE_PCI_GPIO_CTL 0x006C /* rev >= 2 only */
50#define BCMA_CORE_PCI_SBTOPCI0 0x0100 /* Backplane to PCI translation 0 (sbtopci0) */
51#define BCMA_CORE_PCI_SBTOPCI0_MASK 0xFC000000
52#define BCMA_CORE_PCI_SBTOPCI1 0x0104 /* Backplane to PCI translation 1 (sbtopci1) */
53#define BCMA_CORE_PCI_SBTOPCI1_MASK 0xFC000000
54#define BCMA_CORE_PCI_SBTOPCI2 0x0108 /* Backplane to PCI translation 2 (sbtopci2) */
55#define BCMA_CORE_PCI_SBTOPCI2_MASK 0xC0000000
56#define BCMA_CORE_PCI_PCICFG0 0x0400 /* PCI config space 0 (rev >= 8) */
57#define BCMA_CORE_PCI_PCICFG1 0x0500 /* PCI config space 1 (rev >= 8) */
58#define BCMA_CORE_PCI_PCICFG2 0x0600 /* PCI config space 2 (rev >= 8) */
59#define BCMA_CORE_PCI_PCICFG3 0x0700 /* PCI config space 3 (rev >= 8) */
60#define BCMA_CORE_PCI_SPROM(wordoffset) (0x0800 + ((wordoffset) * 2)) /* SPROM shadow area (72 bytes) */
61
62/* SBtoPCIx */
63#define BCMA_CORE_PCI_SBTOPCI_MEM 0x00000000
64#define BCMA_CORE_PCI_SBTOPCI_IO 0x00000001
65#define BCMA_CORE_PCI_SBTOPCI_CFG0 0x00000002
66#define BCMA_CORE_PCI_SBTOPCI_CFG1 0x00000003
67#define BCMA_CORE_PCI_SBTOPCI_PREF 0x00000004 /* Prefetch enable */
68#define BCMA_CORE_PCI_SBTOPCI_BURST 0x00000008 /* Burst enable */
69#define BCMA_CORE_PCI_SBTOPCI_MRM 0x00000020 /* Memory Read Multiple */
70#define BCMA_CORE_PCI_SBTOPCI_RC 0x00000030 /* Read Command mask (rev >= 11) */
71#define BCMA_CORE_PCI_SBTOPCI_RC_READ 0x00000000 /* Memory read */
72#define BCMA_CORE_PCI_SBTOPCI_RC_READL 0x00000010 /* Memory read line */
73#define BCMA_CORE_PCI_SBTOPCI_RC_READM 0x00000020 /* Memory read multiple */
74
75/* PCIcore specific boardflags */
76#define BCMA_CORE_PCI_BFL_NOPCI 0x00000400 /* Board leaves PCI floating */
77
78struct bcma_drv_pci {
79 struct bcma_device *core;
80 u8 setup_done:1;
81};
82
83/* Register access */
84#define pcicore_read32(pc, offset) bcma_read32((pc)->core, offset)
85#define pcicore_write32(pc, offset, val) bcma_write32((pc)->core, offset, val)
86
87extern void bcma_core_pci_init(struct bcma_drv_pci *pc);
88
89#endif /* LINUX_BCMA_DRIVER_PCI_H_ */
diff --git a/include/linux/bcma/bcma_regs.h b/include/linux/bcma/bcma_regs.h
new file mode 100644
index 000000000000..f82d88a960ce
--- /dev/null
+++ b/include/linux/bcma/bcma_regs.h
@@ -0,0 +1,34 @@
1#ifndef LINUX_BCMA_REGS_H_
2#define LINUX_BCMA_REGS_H_
3
4/* Agent registers (common for every core) */
5#define BCMA_IOCTL 0x0408
6#define BCMA_IOCTL_CLK 0x0001
7#define BCMA_IOCTL_FGC 0x0002
8#define BCMA_IOCTL_CORE_BITS 0x3FFC
9#define BCMA_IOCTL_PME_EN 0x4000
10#define BCMA_IOCTL_BIST_EN 0x8000
11#define BCMA_RESET_CTL 0x0800
12#define BCMA_RESET_CTL_RESET 0x0001
13
14/* BCMA PCI config space registers. */
15#define BCMA_PCI_PMCSR 0x44
16#define BCMA_PCI_PE 0x100
17#define BCMA_PCI_BAR0_WIN 0x80 /* Backplane address space 0 */
18#define BCMA_PCI_BAR1_WIN 0x84 /* Backplane address space 1 */
19#define BCMA_PCI_SPROMCTL 0x88 /* SPROM control */
20#define BCMA_PCI_SPROMCTL_WE 0x10 /* SPROM write enable */
21#define BCMA_PCI_BAR1_CONTROL 0x8c /* Address space 1 burst control */
22#define BCMA_PCI_IRQS 0x90 /* PCI interrupts */
23#define BCMA_PCI_IRQMASK 0x94 /* PCI IRQ control and mask (pcirev >= 6 only) */
24#define BCMA_PCI_BACKPLANE_IRQS 0x98 /* Backplane Interrupts */
25#define BCMA_PCI_BAR0_WIN2 0xAC
26#define BCMA_PCI_GPIO_IN 0xB0 /* GPIO Input (pcirev >= 3 only) */
27#define BCMA_PCI_GPIO_OUT 0xB4 /* GPIO Output (pcirev >= 3 only) */
28#define BCMA_PCI_GPIO_OUT_ENABLE 0xB8 /* GPIO Output Enable/Disable (pcirev >= 3 only) */
29#define BCMA_PCI_GPIO_SCS 0x10 /* PCI config space bit 4 for 4306c0 slow clock source */
30#define BCMA_PCI_GPIO_HWRAD 0x20 /* PCI config space GPIO 13 for hw radio disable */
31#define BCMA_PCI_GPIO_XTAL 0x40 /* PCI config space GPIO 14 for Xtal powerup */
32#define BCMA_PCI_GPIO_PLL 0x80 /* PCI config space GPIO 15 for PLL powerdown */
33
34#endif /* LINUX_BCMA_REGS_H_ */
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 79690b710665..b2eee5879883 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -1002,6 +1002,11 @@ struct ieee80211_ht_info {
1002 1002
1003#define WLAN_CAPABILITY_ESS (1<<0) 1003#define WLAN_CAPABILITY_ESS (1<<0)
1004#define WLAN_CAPABILITY_IBSS (1<<1) 1004#define WLAN_CAPABILITY_IBSS (1<<1)
1005
1006/* A mesh STA sets the ESS and IBSS capability bits to zero */
1007#define WLAN_CAPABILITY_IS_MBSS(cap) \
1008 (!((cap) & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)))
1009
1005#define WLAN_CAPABILITY_CF_POLLABLE (1<<2) 1010#define WLAN_CAPABILITY_CF_POLLABLE (1<<2)
1006#define WLAN_CAPABILITY_CF_POLL_REQUEST (1<<3) 1011#define WLAN_CAPABILITY_CF_POLL_REQUEST (1<<3)
1007#define WLAN_CAPABILITY_PRIVACY (1<<4) 1012#define WLAN_CAPABILITY_PRIVACY (1<<4)
@@ -1261,9 +1266,8 @@ enum ieee80211_category {
1261 WLAN_CATEGORY_MULTIHOP_ACTION = 14, 1266 WLAN_CATEGORY_MULTIHOP_ACTION = 14,
1262 WLAN_CATEGORY_SELF_PROTECTED = 15, 1267 WLAN_CATEGORY_SELF_PROTECTED = 15,
1263 WLAN_CATEGORY_WMM = 17, 1268 WLAN_CATEGORY_WMM = 17,
1264 /* TODO: remove MESH_PLINK and MESH_PATH_SEL after */ 1269 /* TODO: remove MESH_PATH_SEL after mesh is updated
1265 /* mesh is updated to current 802.11s draft */ 1270 * to current 802.11s draft */
1266 WLAN_CATEGORY_MESH_PLINK = 30,
1267 WLAN_CATEGORY_MESH_PATH_SEL = 32, 1271 WLAN_CATEGORY_MESH_PATH_SEL = 32,
1268 WLAN_CATEGORY_VENDOR_SPECIFIC_PROTECTED = 126, 1272 WLAN_CATEGORY_VENDOR_SPECIFIC_PROTECTED = 126,
1269 WLAN_CATEGORY_VENDOR_SPECIFIC = 127, 1273 WLAN_CATEGORY_VENDOR_SPECIFIC = 127,
@@ -1516,6 +1520,7 @@ static inline bool ieee80211_is_robust_mgmt_frame(struct ieee80211_hdr *hdr)
1516 category = ((u8 *) hdr) + 24; 1520 category = ((u8 *) hdr) + 24;
1517 return *category != WLAN_CATEGORY_PUBLIC && 1521 return *category != WLAN_CATEGORY_PUBLIC &&
1518 *category != WLAN_CATEGORY_HT && 1522 *category != WLAN_CATEGORY_HT &&
1523 *category != WLAN_CATEGORY_SELF_PROTECTED &&
1519 *category != WLAN_CATEGORY_VENDOR_SPECIFIC; 1524 *category != WLAN_CATEGORY_VENDOR_SPECIFIC;
1520 } 1525 }
1521 1526
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index 48c007dae476..ae28e93fd072 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -382,6 +382,23 @@ struct ssb_device_id {
382#define SSB_ANY_ID 0xFFFF 382#define SSB_ANY_ID 0xFFFF
383#define SSB_ANY_REV 0xFF 383#define SSB_ANY_REV 0xFF
384 384
385/* Broadcom's specific AMBA core, see drivers/bcma/ */
386struct bcma_device_id {
387 __u16 manuf;
388 __u16 id;
389 __u8 rev;
390 __u8 class;
391};
392#define BCMA_CORE(_manuf, _id, _rev, _class) \
393 { .manuf = _manuf, .id = _id, .rev = _rev, .class = _class, }
394#define BCMA_CORETABLE_END \
395 { 0, },
396
397#define BCMA_ANY_MANUF 0xFFFF
398#define BCMA_ANY_ID 0xFFFF
399#define BCMA_ANY_REV 0xFF
400#define BCMA_ANY_CLASS 0xFF
401
385struct virtio_device_id { 402struct virtio_device_id {
386 __u32 device; 403 __u32 device;
387 __u32 vendor; 404 __u32 vendor;
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index 216b1d8a862f..c7ccaae15af6 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -77,6 +77,39 @@
77 */ 77 */
78 78
79/** 79/**
80 * DOC: Virtual interface / concurrency capabilities
81 *
82 * Some devices are able to operate with virtual MACs, they can have
83 * more than one virtual interface. The capability handling for this
84 * is a bit complex though, as there may be a number of restrictions
85 * on the types of concurrency that are supported.
86 *
87 * To start with, each device supports the interface types listed in
88 * the %NL80211_ATTR_SUPPORTED_IFTYPES attribute, but by listing the
89 * types there no concurrency is implied.
90 *
91 * Once concurrency is desired, more attributes must be observed:
92 * To start with, since some interface types are purely managed in
93 * software, like the AP-VLAN type in mac80211 for example, there's
94 * an additional list of these, they can be added at any time and
95 * are only restricted by some semantic restrictions (e.g. AP-VLAN
96 * cannot be added without a corresponding AP interface). This list
97 * is exported in the %NL80211_ATTR_SOFTWARE_IFTYPES attribute.
98 *
99 * Further, the list of supported combinations is exported. This is
100 * in the %NL80211_ATTR_INTERFACE_COMBINATIONS attribute. Basically,
101 * it exports a list of "groups", and at any point in time the
102 * interfaces that are currently active must fall into any one of
103 * the advertised groups. Within each group, there are restrictions
104 * on the number of interfaces of different types that are supported
105 * and also the number of different channels, along with potentially
106 * some other restrictions. See &enum nl80211_if_combination_attrs.
107 *
108 * All together, these attributes define the concurrency of virtual
109 * interfaces that a given device supports.
110 */
111
112/**
80 * enum nl80211_commands - supported nl80211 commands 113 * enum nl80211_commands - supported nl80211 commands
81 * 114 *
82 * @NL80211_CMD_UNSPEC: unspecified command to catch errors 115 * @NL80211_CMD_UNSPEC: unspecified command to catch errors
@@ -203,6 +236,28 @@
203 * @NL80211_CMD_SCAN_ABORTED: scan was aborted, for unspecified reasons, 236 * @NL80211_CMD_SCAN_ABORTED: scan was aborted, for unspecified reasons,
204 * partial scan results may be available 237 * partial scan results may be available
205 * 238 *
239 * @NL80211_CMD_START_SCHED_SCAN: start a scheduled scan at certain
240 * intervals, as specified by %NL80211_ATTR_SCHED_SCAN_INTERVAL.
241 * Like with normal scans, if SSIDs (%NL80211_ATTR_SCAN_SSIDS)
242 * are passed, they are used in the probe requests. For
243 * broadcast, a broadcast SSID must be passed (ie. an empty
244 * string). If no SSID is passed, no probe requests are sent and
245 * a passive scan is performed. %NL80211_ATTR_SCAN_FREQUENCIES,
246 * if passed, define which channels should be scanned; if not
247 * passed, all channels allowed for the current regulatory domain
248 * are used. Extra IEs can also be passed from the userspace by
249 * using the %NL80211_ATTR_IE attribute.
250 * @NL80211_CMD_STOP_SCHED_SCAN: stop a scheduled scan
251 * @NL80211_CMD_SCHED_SCAN_RESULTS: indicates that there are scheduled scan
252 * results available.
253 * @NL80211_CMD_SCHED_SCAN_STOPPED: indicates that the scheduled scan has
254 * stopped. The driver may issue this event at any time during a
255 * scheduled scan. One reason for stopping the scan is if the hardware
256 * does not support starting an association or a normal scan while running
257 * a scheduled scan. This event is also sent when the
258 * %NL80211_CMD_STOP_SCHED_SCAN command is received or when the interface
259 * is brought down while a scheduled scan was running.
260 *
206 * @NL80211_CMD_GET_SURVEY: get survey resuls, e.g. channel occupation 261 * @NL80211_CMD_GET_SURVEY: get survey resuls, e.g. channel occupation
207 * or noise level 262 * or noise level
208 * @NL80211_CMD_NEW_SURVEY_RESULTS: survey data notification (as a reply to 263 * @NL80211_CMD_NEW_SURVEY_RESULTS: survey data notification (as a reply to
@@ -420,6 +475,14 @@
420 * new station with the AUTHENTICATED flag unset and maybe change it later 475 * new station with the AUTHENTICATED flag unset and maybe change it later
421 * depending on the authentication result. 476 * depending on the authentication result.
422 * 477 *
478 * @NL80211_CMD_GET_WOWLAN: get Wake-on-Wireless-LAN (WoWLAN) settings.
479 * @NL80211_CMD_SET_WOWLAN: set Wake-on-Wireless-LAN (WoWLAN) settings.
480 * Since wireless is more complex than wired ethernet, it supports
481 * various triggers. These triggers can be configured through this
482 * command with the %NL80211_ATTR_WOWLAN_TRIGGERS attribute. For
483 * more background information, see
484 * http://wireless.kernel.org/en/users/Documentation/WoWLAN.
485 *
423 * @NL80211_CMD_MAX: highest used command number 486 * @NL80211_CMD_MAX: highest used command number
424 * @__NL80211_CMD_AFTER_LAST: internal use 487 * @__NL80211_CMD_AFTER_LAST: internal use
425 */ 488 */
@@ -534,6 +597,14 @@ enum nl80211_commands {
534 597
535 NL80211_CMD_NEW_PEER_CANDIDATE, 598 NL80211_CMD_NEW_PEER_CANDIDATE,
536 599
600 NL80211_CMD_GET_WOWLAN,
601 NL80211_CMD_SET_WOWLAN,
602
603 NL80211_CMD_START_SCHED_SCAN,
604 NL80211_CMD_STOP_SCHED_SCAN,
605 NL80211_CMD_SCHED_SCAN_RESULTS,
606 NL80211_CMD_SCHED_SCAN_STOPPED,
607
537 /* add new commands above here */ 608 /* add new commands above here */
538 609
539 /* used to define NL80211_CMD_MAX below */ 610 /* used to define NL80211_CMD_MAX below */
@@ -902,6 +973,28 @@ enum nl80211_commands {
902 * @NL80211_ATTR_SUPPORT_MESH_AUTH: Currently, this means the underlying driver 973 * @NL80211_ATTR_SUPPORT_MESH_AUTH: Currently, this means the underlying driver
903 * allows auth frames in a mesh to be passed to userspace for processing via 974 * allows auth frames in a mesh to be passed to userspace for processing via
904 * the @NL80211_MESH_SETUP_USERSPACE_AUTH flag. 975 * the @NL80211_MESH_SETUP_USERSPACE_AUTH flag.
976 * @NL80211_ATTR_STA_PLINK_STATE: The state of a mesh peer link as
977 * defined in &enum nl80211_plink_state. Used when userspace is
978 * driving the peer link management state machine.
979 * @NL80211_MESH_SETUP_USERSPACE_AMPE must be enabled.
980 *
981 * @NL80211_ATTR_WOWLAN_SUPPORTED: indicates, as part of the wiphy capabilities,
982 * the supported WoWLAN triggers
983 * @NL80211_ATTR_WOWLAN_TRIGGERS: used by %NL80211_CMD_SET_WOWLAN to
984 * indicate which WoW triggers should be enabled. This is also
985 * used by %NL80211_CMD_GET_WOWLAN to get the currently enabled WoWLAN
986 * triggers.
987
988 * @NL80211_ATTR_SCHED_SCAN_INTERVAL: Interval between scheduled scan
989 * cycles, in msecs.
990 *
991 * @NL80211_ATTR_INTERFACE_COMBINATIONS: Nested attribute listing the supported
992 * interface combinations. In each nested item, it contains attributes
993 * defined in &enum nl80211_if_combination_attrs.
994 * @NL80211_ATTR_SOFTWARE_IFTYPES: Nested attribute (just like
995 * %NL80211_ATTR_SUPPORTED_IFTYPES) containing the interface types that
996 * are managed in software: interfaces of these types aren't subject to
997 * any restrictions in their number or combinations.
905 * 998 *
906 * @NL80211_ATTR_MAX: highest attribute number currently defined 999 * @NL80211_ATTR_MAX: highest attribute number currently defined
907 * @__NL80211_ATTR_AFTER_LAST: internal use 1000 * @__NL80211_ATTR_AFTER_LAST: internal use
@@ -1091,6 +1184,15 @@ enum nl80211_attrs {
1091 NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX, 1184 NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX,
1092 1185
1093 NL80211_ATTR_SUPPORT_MESH_AUTH, 1186 NL80211_ATTR_SUPPORT_MESH_AUTH,
1187 NL80211_ATTR_STA_PLINK_STATE,
1188
1189 NL80211_ATTR_WOWLAN_TRIGGERS,
1190 NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED,
1191
1192 NL80211_ATTR_SCHED_SCAN_INTERVAL,
1193
1194 NL80211_ATTR_INTERFACE_COMBINATIONS,
1195 NL80211_ATTR_SOFTWARE_IFTYPES,
1094 1196
1095 /* add attributes here, update the policy in nl80211.c */ 1197 /* add attributes here, update the policy in nl80211.c */
1096 1198
@@ -1144,7 +1246,9 @@ enum nl80211_attrs {
1144 * @NL80211_IFTYPE_ADHOC: independent BSS member 1246 * @NL80211_IFTYPE_ADHOC: independent BSS member
1145 * @NL80211_IFTYPE_STATION: managed BSS member 1247 * @NL80211_IFTYPE_STATION: managed BSS member
1146 * @NL80211_IFTYPE_AP: access point 1248 * @NL80211_IFTYPE_AP: access point
1147 * @NL80211_IFTYPE_AP_VLAN: VLAN interface for access points 1249 * @NL80211_IFTYPE_AP_VLAN: VLAN interface for access points; VLAN interfaces
1250 * are a bit special in that they must always be tied to a pre-existing
1251 * AP type interface.
1148 * @NL80211_IFTYPE_WDS: wireless distribution interface 1252 * @NL80211_IFTYPE_WDS: wireless distribution interface
1149 * @NL80211_IFTYPE_MONITOR: monitor interface receiving all frames 1253 * @NL80211_IFTYPE_MONITOR: monitor interface receiving all frames
1150 * @NL80211_IFTYPE_MESH_POINT: mesh point 1254 * @NL80211_IFTYPE_MESH_POINT: mesh point
@@ -1293,6 +1397,7 @@ enum nl80211_sta_bss_param {
1293 * @NL80211_STA_INFO_LLID: the station's mesh LLID 1397 * @NL80211_STA_INFO_LLID: the station's mesh LLID
1294 * @NL80211_STA_INFO_PLID: the station's mesh PLID 1398 * @NL80211_STA_INFO_PLID: the station's mesh PLID
1295 * @NL80211_STA_INFO_PLINK_STATE: peer link state for the station 1399 * @NL80211_STA_INFO_PLINK_STATE: peer link state for the station
1400 * (see %enum nl80211_plink_state)
1296 * @NL80211_STA_INFO_RX_BITRATE: last unicast data frame rx rate, nested 1401 * @NL80211_STA_INFO_RX_BITRATE: last unicast data frame rx rate, nested
1297 * attribute, like NL80211_STA_INFO_TX_BITRATE. 1402 * attribute, like NL80211_STA_INFO_TX_BITRATE.
1298 * @NL80211_STA_INFO_BSS_PARAM: current station's view of BSS, nested attribute 1403 * @NL80211_STA_INFO_BSS_PARAM: current station's view of BSS, nested attribute
@@ -1748,6 +1853,15 @@ enum nl80211_meshconf_params {
1748 * @NL80211_MESH_SETUP_USERSPACE_AUTH: Enable this option if an authentication 1853 * @NL80211_MESH_SETUP_USERSPACE_AUTH: Enable this option if an authentication
1749 * daemon will be authenticating mesh candidates. 1854 * daemon will be authenticating mesh candidates.
1750 * 1855 *
1856 * @NL80211_MESH_SETUP_USERSPACE_AMPE: Enable this option if an authentication
1857 * daemon will be securing peer link frames. AMPE is a secured version of Mesh
1858 * Peering Management (MPM) and is implemented with the assistance of a
1859 * userspace daemon. When this flag is set, the kernel will send peer
1860 * management frames to a userspace daemon that will implement AMPE
1861 * functionality (security capabilities selection, key confirmation, and key
1862 * management). When the flag is unset (default), the kernel can autonomously
1863 * complete (unsecured) mesh peering without the need of a userspace daemon.
1864 *
1751 * @NL80211_MESH_SETUP_ATTR_MAX: highest possible mesh setup attribute number 1865 * @NL80211_MESH_SETUP_ATTR_MAX: highest possible mesh setup attribute number
1752 * @__NL80211_MESH_SETUP_ATTR_AFTER_LAST: Internal use 1866 * @__NL80211_MESH_SETUP_ATTR_AFTER_LAST: Internal use
1753 */ 1867 */
@@ -1757,6 +1871,7 @@ enum nl80211_mesh_setup_params {
1757 NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC, 1871 NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC,
1758 NL80211_MESH_SETUP_IE, 1872 NL80211_MESH_SETUP_IE,
1759 NL80211_MESH_SETUP_USERSPACE_AUTH, 1873 NL80211_MESH_SETUP_USERSPACE_AUTH,
1874 NL80211_MESH_SETUP_USERSPACE_AMPE,
1760 1875
1761 /* keep last */ 1876 /* keep last */
1762 __NL80211_MESH_SETUP_ATTR_AFTER_LAST, 1877 __NL80211_MESH_SETUP_ATTR_AFTER_LAST,
@@ -2061,4 +2176,189 @@ enum nl80211_tx_power_setting {
2061 NL80211_TX_POWER_FIXED, 2176 NL80211_TX_POWER_FIXED,
2062}; 2177};
2063 2178
2179/**
2180 * enum nl80211_wowlan_packet_pattern_attr - WoWLAN packet pattern attribute
2181 * @__NL80211_WOWLAN_PKTPAT_INVALID: invalid number for nested attribute
2182 * @NL80211_WOWLAN_PKTPAT_PATTERN: the pattern, values where the mask has
2183 * a zero bit are ignored
2184 * @NL80211_WOWLAN_PKTPAT_MASK: pattern mask, must be long enough to have
2185 * a bit for each byte in the pattern. The lowest-order bit corresponds
2186 * to the first byte of the pattern, but the bytes of the pattern are
2187 * in a little-endian-like format, i.e. the 9th byte of the pattern
2188 * corresponds to the lowest-order bit in the second byte of the mask.
2189 * For example: The match 00:xx:00:00:xx:00:00:00:00:xx:xx:xx (where
2190 * xx indicates "don't care") would be represented by a pattern of
2191 * twelve zero bytes, and a mask of "0xed,0x07".
2192 * Note that the pattern matching is done as though frames were not
2193 * 802.11 frames but 802.3 frames, i.e. the frame is fully unpacked
2194 * first (including SNAP header unpacking) and then matched.
2195 * @NUM_NL80211_WOWLAN_PKTPAT: number of attributes
2196 * @MAX_NL80211_WOWLAN_PKTPAT: max attribute number
2197 */
2198enum nl80211_wowlan_packet_pattern_attr {
2199 __NL80211_WOWLAN_PKTPAT_INVALID,
2200 NL80211_WOWLAN_PKTPAT_MASK,
2201 NL80211_WOWLAN_PKTPAT_PATTERN,
2202
2203 NUM_NL80211_WOWLAN_PKTPAT,
2204 MAX_NL80211_WOWLAN_PKTPAT = NUM_NL80211_WOWLAN_PKTPAT - 1,
2205};
2206
2207/**
2208 * struct nl80211_wowlan_pattern_support - pattern support information
2209 * @max_patterns: maximum number of patterns supported
2210 * @min_pattern_len: minimum length of each pattern
2211 * @max_pattern_len: maximum length of each pattern
2212 *
2213 * This struct is carried in %NL80211_WOWLAN_TRIG_PKT_PATTERN when
2214 * that is part of %NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED in the
2215 * capability information given by the kernel to userspace.
2216 */
2217struct nl80211_wowlan_pattern_support {
2218 __u32 max_patterns;
2219 __u32 min_pattern_len;
2220 __u32 max_pattern_len;
2221} __attribute__((packed));
2222
2223/**
2224 * enum nl80211_wowlan_triggers - WoWLAN trigger definitions
2225 * @__NL80211_WOWLAN_TRIG_INVALID: invalid number for nested attributes
2226 * @NL80211_WOWLAN_TRIG_ANY: wake up on any activity, do not really put
2227 * the chip into a special state -- works best with chips that have
2228 * support for low-power operation already (flag)
2229 * @NL80211_WOWLAN_TRIG_DISCONNECT: wake up on disconnect, the way disconnect
2230 * is detected is implementation-specific (flag)
2231 * @NL80211_WOWLAN_TRIG_MAGIC_PKT: wake up on magic packet (6x 0xff, followed
2232 * by 16 repetitions of MAC addr, anywhere in payload) (flag)
2233 * @NL80211_WOWLAN_TRIG_PKT_PATTERN: wake up on the specified packet patterns
2234 * which are passed in an array of nested attributes, each nested attribute
2235 * defining a with attributes from &struct nl80211_wowlan_trig_pkt_pattern.
2236 * Each pattern defines a wakeup packet. The matching is done on the MSDU,
2237 * i.e. as though the packet was an 802.3 packet, so the pattern matching
2238 * is done after the packet is converted to the MSDU.
2239 *
2240 * In %NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED, it is a binary attribute
2241 * carrying a &struct nl80211_wowlan_pattern_support.
2242 * @NUM_NL80211_WOWLAN_TRIG: number of wake on wireless triggers
2243 * @MAX_NL80211_WOWLAN_TRIG: highest wowlan trigger attribute number
2244 */
2245enum nl80211_wowlan_triggers {
2246 __NL80211_WOWLAN_TRIG_INVALID,
2247 NL80211_WOWLAN_TRIG_ANY,
2248 NL80211_WOWLAN_TRIG_DISCONNECT,
2249 NL80211_WOWLAN_TRIG_MAGIC_PKT,
2250 NL80211_WOWLAN_TRIG_PKT_PATTERN,
2251
2252 /* keep last */
2253 NUM_NL80211_WOWLAN_TRIG,
2254 MAX_NL80211_WOWLAN_TRIG = NUM_NL80211_WOWLAN_TRIG - 1
2255};
2256
2257/**
2258 * enum nl80211_iface_limit_attrs - limit attributes
2259 * @NL80211_IFACE_LIMIT_UNSPEC: (reserved)
2260 * @NL80211_IFACE_LIMIT_MAX: maximum number of interfaces that
2261 * can be chosen from this set of interface types (u32)
2262 * @NL80211_IFACE_LIMIT_TYPES: nested attribute containing a
2263 * flag attribute for each interface type in this set
2264 * @NUM_NL80211_IFACE_LIMIT: number of attributes
2265 * @MAX_NL80211_IFACE_LIMIT: highest attribute number
2266 */
2267enum nl80211_iface_limit_attrs {
2268 NL80211_IFACE_LIMIT_UNSPEC,
2269 NL80211_IFACE_LIMIT_MAX,
2270 NL80211_IFACE_LIMIT_TYPES,
2271
2272 /* keep last */
2273 NUM_NL80211_IFACE_LIMIT,
2274 MAX_NL80211_IFACE_LIMIT = NUM_NL80211_IFACE_LIMIT - 1
2275};
2276
2277/**
2278 * enum nl80211_if_combination_attrs -- interface combination attributes
2279 *
2280 * @NL80211_IFACE_COMB_UNSPEC: (reserved)
2281 * @NL80211_IFACE_COMB_LIMITS: Nested attributes containing the limits
2282 * for given interface types, see &enum nl80211_iface_limit_attrs.
2283 * @NL80211_IFACE_COMB_MAXNUM: u32 attribute giving the total number of
2284 * interfaces that can be created in this group. This number doesn't
2285 * apply to interfaces purely managed in software, which are listed
2286 * in a separate attribute %NL80211_ATTR_INTERFACES_SOFTWARE.
2287 * @NL80211_IFACE_COMB_STA_AP_BI_MATCH: flag attribute specifying that
2288 * beacon intervals within this group must be all the same even for
2289 * infrastructure and AP/GO combinations, i.e. the GO(s) must adopt
2290 * the infrastructure network's beacon interval.
2291 * @NL80211_IFACE_COMB_NUM_CHANNELS: u32 attribute specifying how many
2292 * different channels may be used within this group.
2293 * @NUM_NL80211_IFACE_COMB: number of attributes
2294 * @MAX_NL80211_IFACE_COMB: highest attribute number
2295 *
2296 * Examples:
2297 * limits = [ #{STA} <= 1, #{AP} <= 1 ], matching BI, channels = 1, max = 2
2298 * => allows an AP and a STA that must match BIs
2299 *
2300 * numbers = [ #{AP, P2P-GO} <= 8 ], channels = 1, max = 8
2301 * => allows 8 of AP/GO
2302 *
2303 * numbers = [ #{STA} <= 2 ], channels = 2, max = 2
2304 * => allows two STAs on different channels
2305 *
2306 * numbers = [ #{STA} <= 1, #{P2P-client,P2P-GO} <= 3 ], max = 4
2307 * => allows a STA plus three P2P interfaces
2308 *
2309 * The list of these four possiblities could completely be contained
2310 * within the %NL80211_ATTR_INTERFACE_COMBINATIONS attribute to indicate
2311 * that any of these groups must match.
2312 *
2313 * "Combinations" of just a single interface will not be listed here,
2314 * a single interface of any valid interface type is assumed to always
2315 * be possible by itself. This means that implicitly, for each valid
2316 * interface type, the following group always exists:
2317 * numbers = [ #{<type>} <= 1 ], channels = 1, max = 1
2318 */
2319enum nl80211_if_combination_attrs {
2320 NL80211_IFACE_COMB_UNSPEC,
2321 NL80211_IFACE_COMB_LIMITS,
2322 NL80211_IFACE_COMB_MAXNUM,
2323 NL80211_IFACE_COMB_STA_AP_BI_MATCH,
2324 NL80211_IFACE_COMB_NUM_CHANNELS,
2325
2326 /* keep last */
2327 NUM_NL80211_IFACE_COMB,
2328 MAX_NL80211_IFACE_COMB = NUM_NL80211_IFACE_COMB - 1
2329};
2330
2331
2332/**
2333 * enum nl80211_plink_state - state of a mesh peer link finite state machine
2334 *
2335 * @NL80211_PLINK_LISTEN: initial state, considered the implicit
2336 * state of non existant mesh peer links
2337 * @NL80211_PLINK_OPN_SNT: mesh plink open frame has been sent to
2338 * this mesh peer
2339 * @NL80211_PLINK_OPN_RCVD: mesh plink open frame has been received
2340 * from this mesh peer
2341 * @NL80211_PLINK_CNF_RCVD: mesh plink confirm frame has been
2342 * received from this mesh peer
2343 * @NL80211_PLINK_ESTAB: mesh peer link is established
2344 * @NL80211_PLINK_HOLDING: mesh peer link is being closed or cancelled
2345 * @NL80211_PLINK_BLOCKED: all frames transmitted from this mesh
2346 * plink are discarded
2347 * @NUM_NL80211_PLINK_STATES: number of peer link states
2348 * @MAX_NL80211_PLINK_STATES: highest numerical value of plink states
2349 */
2350enum nl80211_plink_state {
2351 NL80211_PLINK_LISTEN,
2352 NL80211_PLINK_OPN_SNT,
2353 NL80211_PLINK_OPN_RCVD,
2354 NL80211_PLINK_CNF_RCVD,
2355 NL80211_PLINK_ESTAB,
2356 NL80211_PLINK_HOLDING,
2357 NL80211_PLINK_BLOCKED,
2358
2359 /* keep last */
2360 NUM_NL80211_PLINK_STATES,
2361 MAX_NL80211_PLINK_STATES = NUM_NL80211_PLINK_STATES - 1
2362};
2363
2064#endif /* __LINUX_NL80211_H */ 2364#endif /* __LINUX_NL80211_H */
diff --git a/include/linux/ssb/ssb.h b/include/linux/ssb/ssb.h
index 7e99b348834c..f017b8900f78 100644
--- a/include/linux/ssb/ssb.h
+++ b/include/linux/ssb/ssb.h
@@ -518,6 +518,7 @@ extern int ssb_bus_may_powerdown(struct ssb_bus *bus);
518 * Otherwise static always-on powercontrol will be used. */ 518 * Otherwise static always-on powercontrol will be used. */
519extern int ssb_bus_powerup(struct ssb_bus *bus, bool dynamic_pctl); 519extern int ssb_bus_powerup(struct ssb_bus *bus, bool dynamic_pctl);
520 520
521extern void ssb_commit_settings(struct ssb_bus *bus);
521 522
522/* Various helper functions */ 523/* Various helper functions */
523extern u32 ssb_admatch_base(u32 adm); 524extern u32 ssb_admatch_base(u32 adm);
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 14cc3249c1eb..6c994c004d15 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -422,6 +422,7 @@ void hci_conn_check_pending(struct hci_dev *hdev);
422 422
423struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 sec_level, __u8 auth_type); 423struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 sec_level, __u8 auth_type);
424int hci_conn_check_link_mode(struct hci_conn *conn); 424int hci_conn_check_link_mode(struct hci_conn *conn);
425int hci_conn_check_secure(struct hci_conn *conn, __u8 sec_level);
425int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type); 426int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type);
426int hci_conn_change_link_key(struct hci_conn *conn); 427int hci_conn_change_link_key(struct hci_conn *conn);
427int hci_conn_switch_role(struct hci_conn *conn, __u8 role); 428int hci_conn_switch_role(struct hci_conn *conn, __u8 role);
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index c34b1c126363..d09c9b1118e3 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -350,6 +350,7 @@ struct l2cap_chan {
350 struct list_head srej_l; 350 struct list_head srej_l;
351 351
352 struct list_head list; 352 struct list_head list;
353 struct list_head global_l;
353}; 354};
354 355
355struct l2cap_conn { 356struct l2cap_conn {
@@ -441,7 +442,6 @@ static inline int l2cap_tx_window_full(struct l2cap_chan *ch)
441#define __is_sar_start(ctrl) (((ctrl) & L2CAP_CTRL_SAR) == L2CAP_SDU_START) 442#define __is_sar_start(ctrl) (((ctrl) & L2CAP_CTRL_SAR) == L2CAP_SDU_START)
442 443
443extern int disable_ertm; 444extern int disable_ertm;
444extern struct bt_sock_list l2cap_sk_list;
445 445
446int l2cap_init_sockets(void); 446int l2cap_init_sockets(void);
447void l2cap_cleanup_sockets(void); 447void l2cap_cleanup_sockets(void);
@@ -458,6 +458,9 @@ void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb);
458void l2cap_streaming_send(struct l2cap_chan *chan); 458void l2cap_streaming_send(struct l2cap_chan *chan);
459int l2cap_ertm_send(struct l2cap_chan *chan); 459int l2cap_ertm_send(struct l2cap_chan *chan);
460 460
461int l2cap_add_psm(struct l2cap_chan *chan, bdaddr_t *src, __le16 psm);
462int l2cap_add_scid(struct l2cap_chan *chan, __u16 scid);
463
461void l2cap_sock_set_timer(struct sock *sk, long timeout); 464void l2cap_sock_set_timer(struct sock *sk, long timeout);
462void l2cap_sock_clear_timer(struct sock *sk); 465void l2cap_sock_clear_timer(struct sock *sk);
463void __l2cap_sock_close(struct sock *sk, int reason); 466void __l2cap_sock_close(struct sock *sk, int reason);
@@ -466,9 +469,9 @@ void l2cap_sock_init(struct sock *sk, struct sock *parent);
466struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, 469struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock,
467 int proto, gfp_t prio); 470 int proto, gfp_t prio);
468void l2cap_send_disconn_req(struct l2cap_conn *conn, struct l2cap_chan *chan, int err); 471void l2cap_send_disconn_req(struct l2cap_conn *conn, struct l2cap_chan *chan, int err);
469struct l2cap_chan *l2cap_chan_alloc(struct sock *sk); 472struct l2cap_chan *l2cap_chan_create(struct sock *sk);
470void l2cap_chan_del(struct l2cap_chan *chan, int err); 473void l2cap_chan_del(struct l2cap_chan *chan, int err);
471void l2cap_chan_free(struct l2cap_chan *chan); 474void l2cap_chan_destroy(struct l2cap_chan *chan);
472int l2cap_chan_connect(struct l2cap_chan *chan); 475int l2cap_chan_connect(struct l2cap_chan *chan);
473 476
474#endif /* __L2CAP_H */ 477#endif /* __L2CAP_H */
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index d30eada7c6cd..bfd6557946be 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -387,6 +387,7 @@ enum plink_actions {
387 * @listen_interval: listen interval or -1 for no change 387 * @listen_interval: listen interval or -1 for no change
388 * @aid: AID or zero for no change 388 * @aid: AID or zero for no change
389 * @plink_action: plink action to take 389 * @plink_action: plink action to take
390 * @plink_state: set the peer link state for a station
390 * @ht_capa: HT capabilities of station 391 * @ht_capa: HT capabilities of station
391 */ 392 */
392struct station_parameters { 393struct station_parameters {
@@ -397,6 +398,7 @@ struct station_parameters {
397 u16 aid; 398 u16 aid;
398 u8 supported_rates_len; 399 u8 supported_rates_len;
399 u8 plink_action; 400 u8 plink_action;
401 u8 plink_state;
400 struct ieee80211_ht_cap *ht_capa; 402 struct ieee80211_ht_cap *ht_capa;
401}; 403};
402 404
@@ -695,7 +697,8 @@ struct mesh_config {
695 * @path_metric: which metric to use 697 * @path_metric: which metric to use
696 * @ie: vendor information elements (optional) 698 * @ie: vendor information elements (optional)
697 * @ie_len: length of vendor information elements 699 * @ie_len: length of vendor information elements
698 * @is_secure: or not 700 * @is_authenticated: this mesh requires authentication
701 * @is_secure: this mesh uses security
699 * 702 *
700 * These parameters are fixed when the mesh is created. 703 * These parameters are fixed when the mesh is created.
701 */ 704 */
@@ -706,6 +709,7 @@ struct mesh_setup {
706 u8 path_metric; 709 u8 path_metric;
707 const u8 *ie; 710 const u8 *ie;
708 u8 ie_len; 711 u8 ie_len;
712 bool is_authenticated;
709 bool is_secure; 713 bool is_secure;
710}; 714};
711 715
@@ -793,6 +797,35 @@ struct cfg80211_scan_request {
793}; 797};
794 798
795/** 799/**
800 * struct cfg80211_sched_scan_request - scheduled scan request description
801 *
802 * @ssids: SSIDs to scan for (passed in the probe_reqs in active scans)
803 * @n_ssids: number of SSIDs
804 * @n_channels: total number of channels to scan
805 * @interval: interval between each scheduled scan cycle
806 * @ie: optional information element(s) to add into Probe Request or %NULL
807 * @ie_len: length of ie in octets
808 * @wiphy: the wiphy this was for
809 * @dev: the interface
810 * @channels: channels to scan
811 */
812struct cfg80211_sched_scan_request {
813 struct cfg80211_ssid *ssids;
814 int n_ssids;
815 u32 n_channels;
816 u32 interval;
817 const u8 *ie;
818 size_t ie_len;
819
820 /* internal */
821 struct wiphy *wiphy;
822 struct net_device *dev;
823
824 /* keep last */
825 struct ieee80211_channel *channels[0];
826};
827
828/**
796 * enum cfg80211_signal_type - signal type 829 * enum cfg80211_signal_type - signal type
797 * 830 *
798 * @CFG80211_SIGNAL_TYPE_NONE: no signal strength information available 831 * @CFG80211_SIGNAL_TYPE_NONE: no signal strength information available
@@ -1088,6 +1121,38 @@ struct cfg80211_pmksa {
1088}; 1121};
1089 1122
1090/** 1123/**
1124 * struct cfg80211_wowlan_trig_pkt_pattern - packet pattern
1125 * @mask: bitmask where to match pattern and where to ignore bytes,
1126 * one bit per byte, in same format as nl80211
1127 * @pattern: bytes to match where bitmask is 1
1128 * @pattern_len: length of pattern (in bytes)
1129 *
1130 * Internal note: @mask and @pattern are allocated in one chunk of
1131 * memory, free @mask only!
1132 */
1133struct cfg80211_wowlan_trig_pkt_pattern {
1134 u8 *mask, *pattern;
1135 int pattern_len;
1136};
1137
1138/**
1139 * struct cfg80211_wowlan - Wake on Wireless-LAN support info
1140 *
1141 * This structure defines the enabled WoWLAN triggers for the device.
1142 * @any: wake up on any activity -- special trigger if device continues
1143 * operating as normal during suspend
1144 * @disconnect: wake up if getting disconnected
1145 * @magic_pkt: wake up on receiving magic packet
1146 * @patterns: wake up on receiving packet matching a pattern
1147 * @n_patterns: number of patterns
1148 */
1149struct cfg80211_wowlan {
1150 bool any, disconnect, magic_pkt;
1151 struct cfg80211_wowlan_trig_pkt_pattern *patterns;
1152 int n_patterns;
1153};
1154
1155/**
1091 * struct cfg80211_ops - backend description for wireless configuration 1156 * struct cfg80211_ops - backend description for wireless configuration
1092 * 1157 *
1093 * This struct is registered by fullmac card drivers and/or wireless stacks 1158 * This struct is registered by fullmac card drivers and/or wireless stacks
@@ -1100,7 +1165,9 @@ struct cfg80211_pmksa {
1100 * wireless extensions but this is subject to reevaluation as soon as this 1165 * wireless extensions but this is subject to reevaluation as soon as this
1101 * code is used more widely and we have a first user without wext. 1166 * code is used more widely and we have a first user without wext.
1102 * 1167 *
1103 * @suspend: wiphy device needs to be suspended 1168 * @suspend: wiphy device needs to be suspended. The variable @wow will
1169 * be %NULL or contain the enabled Wake-on-Wireless triggers that are
1170 * configured for the device.
1104 * @resume: wiphy device needs to be resumed 1171 * @resume: wiphy device needs to be resumed
1105 * 1172 *
1106 * @add_virtual_intf: create a new virtual interface with the given name, 1173 * @add_virtual_intf: create a new virtual interface with the given name,
@@ -1227,6 +1294,10 @@ struct cfg80211_pmksa {
1227 * @set_power_mgmt: Configure WLAN power management. A timeout value of -1 1294 * @set_power_mgmt: Configure WLAN power management. A timeout value of -1
1228 * allows the driver to adjust the dynamic ps timeout value. 1295 * allows the driver to adjust the dynamic ps timeout value.
1229 * @set_cqm_rssi_config: Configure connection quality monitor RSSI threshold. 1296 * @set_cqm_rssi_config: Configure connection quality monitor RSSI threshold.
1297 * @sched_scan_start: Tell the driver to start a scheduled scan.
1298 * @sched_scan_stop: Tell the driver to stop an ongoing scheduled
1299 * scan. The driver_initiated flag specifies whether the driver
1300 * itself has informed that the scan has stopped.
1230 * 1301 *
1231 * @mgmt_frame_register: Notify driver that a management frame type was 1302 * @mgmt_frame_register: Notify driver that a management frame type was
1232 * registered. Note that this callback may not sleep, and cannot run 1303 * registered. Note that this callback may not sleep, and cannot run
@@ -1244,7 +1315,7 @@ struct cfg80211_pmksa {
1244 * @get_ringparam: Get tx and rx ring current and maximum sizes. 1315 * @get_ringparam: Get tx and rx ring current and maximum sizes.
1245 */ 1316 */
1246struct cfg80211_ops { 1317struct cfg80211_ops {
1247 int (*suspend)(struct wiphy *wiphy); 1318 int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow);
1248 int (*resume)(struct wiphy *wiphy); 1319 int (*resume)(struct wiphy *wiphy);
1249 1320
1250 struct net_device * (*add_virtual_intf)(struct wiphy *wiphy, 1321 struct net_device * (*add_virtual_intf)(struct wiphy *wiphy,
@@ -1413,6 +1484,11 @@ struct cfg80211_ops {
1413 int (*set_ringparam)(struct wiphy *wiphy, u32 tx, u32 rx); 1484 int (*set_ringparam)(struct wiphy *wiphy, u32 tx, u32 rx);
1414 void (*get_ringparam)(struct wiphy *wiphy, 1485 void (*get_ringparam)(struct wiphy *wiphy,
1415 u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max); 1486 u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max);
1487
1488 int (*sched_scan_start)(struct wiphy *wiphy,
1489 struct net_device *dev,
1490 struct cfg80211_sched_scan_request *request);
1491 int (*sched_scan_stop)(struct wiphy *wiphy, struct net_device *dev);
1416}; 1492};
1417 1493
1418/* 1494/*
@@ -1444,6 +1520,10 @@ struct cfg80211_ops {
1444 * hints read the documenation for regulatory_hint_found_beacon() 1520 * hints read the documenation for regulatory_hint_found_beacon()
1445 * @WIPHY_FLAG_NETNS_OK: if not set, do not allow changing the netns of this 1521 * @WIPHY_FLAG_NETNS_OK: if not set, do not allow changing the netns of this
1446 * wiphy at all 1522 * wiphy at all
1523 * @WIPHY_FLAG_ENFORCE_COMBINATIONS: Set this flag to enforce interface
1524 * combinations for this device. This flag is used for backward
1525 * compatibility only until all drivers advertise combinations and
1526 * they will always be enforced.
1447 * @WIPHY_FLAG_PS_ON_BY_DEFAULT: if set to true, powersave will be enabled 1527 * @WIPHY_FLAG_PS_ON_BY_DEFAULT: if set to true, powersave will be enabled
1448 * by default -- this flag will be set depending on the kernel's default 1528 * by default -- this flag will be set depending on the kernel's default
1449 * on wiphy_new(), but can be changed by the driver if it has a good 1529 * on wiphy_new(), but can be changed by the driver if it has a good
@@ -1455,10 +1535,9 @@ struct cfg80211_ops {
1455 * control port protocol ethertype. The device also honours the 1535 * control port protocol ethertype. The device also honours the
1456 * control_port_no_encrypt flag. 1536 * control_port_no_encrypt flag.
1457 * @WIPHY_FLAG_IBSS_RSN: The device supports IBSS RSN. 1537 * @WIPHY_FLAG_IBSS_RSN: The device supports IBSS RSN.
1458 * @WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS: The device supports separate
1459 * unicast and multicast TX keys.
1460 * @WIPHY_FLAG_MESH_AUTH: The device supports mesh authentication by routing 1538 * @WIPHY_FLAG_MESH_AUTH: The device supports mesh authentication by routing
1461 * auth frames to userspace. See @NL80211_MESH_SETUP_USERSPACE_AUTH. 1539 * auth frames to userspace. See @NL80211_MESH_SETUP_USERSPACE_AUTH.
1540 * @WIPHY_FLAG_SCHED_SCAN: The device supports scheduled scans.
1462 */ 1541 */
1463enum wiphy_flags { 1542enum wiphy_flags {
1464 WIPHY_FLAG_CUSTOM_REGULATORY = BIT(0), 1543 WIPHY_FLAG_CUSTOM_REGULATORY = BIT(0),
@@ -1470,8 +1549,83 @@ enum wiphy_flags {
1470 WIPHY_FLAG_4ADDR_STATION = BIT(6), 1549 WIPHY_FLAG_4ADDR_STATION = BIT(6),
1471 WIPHY_FLAG_CONTROL_PORT_PROTOCOL = BIT(7), 1550 WIPHY_FLAG_CONTROL_PORT_PROTOCOL = BIT(7),
1472 WIPHY_FLAG_IBSS_RSN = BIT(8), 1551 WIPHY_FLAG_IBSS_RSN = BIT(8),
1473 WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS= BIT(9),
1474 WIPHY_FLAG_MESH_AUTH = BIT(10), 1552 WIPHY_FLAG_MESH_AUTH = BIT(10),
1553 WIPHY_FLAG_SUPPORTS_SCHED_SCAN = BIT(11),
1554 WIPHY_FLAG_ENFORCE_COMBINATIONS = BIT(12),
1555};
1556
1557/**
1558 * struct ieee80211_iface_limit - limit on certain interface types
1559 * @max: maximum number of interfaces of these types
1560 * @types: interface types (bits)
1561 */
1562struct ieee80211_iface_limit {
1563 u16 max;
1564 u16 types;
1565};
1566
1567/**
1568 * struct ieee80211_iface_combination - possible interface combination
1569 * @limits: limits for the given interface types
1570 * @n_limits: number of limitations
1571 * @num_different_channels: can use up to this many different channels
1572 * @max_interfaces: maximum number of interfaces in total allowed in this
1573 * group
1574 * @beacon_int_infra_match: In this combination, the beacon intervals
1575 * between infrastructure and AP types must match. This is required
1576 * only in special cases.
1577 *
1578 * These examples can be expressed as follows:
1579 *
1580 * Allow #STA <= 1, #AP <= 1, matching BI, channels = 1, 2 total:
1581 *
1582 * struct ieee80211_iface_limit limits1[] = {
1583 * { .max = 1, .types = BIT(NL80211_IFTYPE_STATION), },
1584 * { .max = 1, .types = BIT(NL80211_IFTYPE_AP}, },
1585 * };
1586 * struct ieee80211_iface_combination combination1 = {
1587 * .limits = limits1,
1588 * .n_limits = ARRAY_SIZE(limits1),
1589 * .max_interfaces = 2,
1590 * .beacon_int_infra_match = true,
1591 * };
1592 *
1593 *
1594 * Allow #{AP, P2P-GO} <= 8, channels = 1, 8 total:
1595 *
1596 * struct ieee80211_iface_limit limits2[] = {
1597 * { .max = 8, .types = BIT(NL80211_IFTYPE_AP) |
1598 * BIT(NL80211_IFTYPE_P2P_GO), },
1599 * };
1600 * struct ieee80211_iface_combination combination2 = {
1601 * .limits = limits2,
1602 * .n_limits = ARRAY_SIZE(limits2),
1603 * .max_interfaces = 8,
1604 * .num_different_channels = 1,
1605 * };
1606 *
1607 *
1608 * Allow #STA <= 1, #{P2P-client,P2P-GO} <= 3 on two channels, 4 total.
1609 * This allows for an infrastructure connection and three P2P connections.
1610 *
1611 * struct ieee80211_iface_limit limits3[] = {
1612 * { .max = 1, .types = BIT(NL80211_IFTYPE_STATION), },
1613 * { .max = 3, .types = BIT(NL80211_IFTYPE_P2P_GO) |
1614 * BIT(NL80211_IFTYPE_P2P_CLIENT), },
1615 * };
1616 * struct ieee80211_iface_combination combination3 = {
1617 * .limits = limits3,
1618 * .n_limits = ARRAY_SIZE(limits3),
1619 * .max_interfaces = 4,
1620 * .num_different_channels = 2,
1621 * };
1622 */
1623struct ieee80211_iface_combination {
1624 const struct ieee80211_iface_limit *limits;
1625 u32 num_different_channels;
1626 u16 max_interfaces;
1627 u8 n_limits;
1628 bool beacon_int_infra_match;
1475}; 1629};
1476 1630
1477struct mac_address { 1631struct mac_address {
@@ -1483,6 +1637,38 @@ struct ieee80211_txrx_stypes {
1483}; 1637};
1484 1638
1485/** 1639/**
1640 * enum wiphy_wowlan_support_flags - WoWLAN support flags
1641 * @WIPHY_WOWLAN_ANY: supports wakeup for the special "any"
1642 * trigger that keeps the device operating as-is and
1643 * wakes up the host on any activity, for example a
1644 * received packet that passed filtering; note that the
1645 * packet should be preserved in that case
1646 * @WIPHY_WOWLAN_MAGIC_PKT: supports wakeup on magic packet
1647 * (see nl80211.h)
1648 * @WIPHY_WOWLAN_DISCONNECT: supports wakeup on disconnect
1649 */
1650enum wiphy_wowlan_support_flags {
1651 WIPHY_WOWLAN_ANY = BIT(0),
1652 WIPHY_WOWLAN_MAGIC_PKT = BIT(1),
1653 WIPHY_WOWLAN_DISCONNECT = BIT(2),
1654};
1655
1656/**
1657 * struct wiphy_wowlan_support - WoWLAN support data
1658 * @flags: see &enum wiphy_wowlan_support_flags
1659 * @n_patterns: number of supported wakeup patterns
1660 * (see nl80211.h for the pattern definition)
1661 * @pattern_max_len: maximum length of each pattern
1662 * @pattern_min_len: minimum length of each pattern
1663 */
1664struct wiphy_wowlan_support {
1665 u32 flags;
1666 int n_patterns;
1667 int pattern_max_len;
1668 int pattern_min_len;
1669};
1670
1671/**
1486 * struct wiphy - wireless hardware description 1672 * struct wiphy - wireless hardware description
1487 * @reg_notifier: the driver's regulatory notification callback, 1673 * @reg_notifier: the driver's regulatory notification callback,
1488 * note that if your driver uses wiphy_apply_custom_regulatory() 1674 * note that if your driver uses wiphy_apply_custom_regulatory()
@@ -1519,6 +1705,11 @@ struct ieee80211_txrx_stypes {
1519 * @priv: driver private data (sized according to wiphy_new() parameter) 1705 * @priv: driver private data (sized according to wiphy_new() parameter)
1520 * @interface_modes: bitmask of interfaces types valid for this wiphy, 1706 * @interface_modes: bitmask of interfaces types valid for this wiphy,
1521 * must be set by driver 1707 * must be set by driver
1708 * @iface_combinations: Valid interface combinations array, should not
1709 * list single interface types.
1710 * @n_iface_combinations: number of entries in @iface_combinations array.
1711 * @software_iftypes: bitmask of software interface types, these are not
1712 * subject to any restrictions since they are purely managed in SW.
1522 * @flags: wiphy flags, see &enum wiphy_flags 1713 * @flags: wiphy flags, see &enum wiphy_flags
1523 * @bss_priv_size: each BSS struct has private data allocated with it, 1714 * @bss_priv_size: each BSS struct has private data allocated with it,
1524 * this variable determines its size 1715 * this variable determines its size
@@ -1549,6 +1740,8 @@ struct ieee80211_txrx_stypes {
1549 * 1740 *
1550 * @max_remain_on_channel_duration: Maximum time a remain-on-channel operation 1741 * @max_remain_on_channel_duration: Maximum time a remain-on-channel operation
1551 * may request, if implemented. 1742 * may request, if implemented.
1743 *
1744 * @wowlan: WoWLAN support information
1552 */ 1745 */
1553struct wiphy { 1746struct wiphy {
1554 /* assign these fields before you register the wiphy */ 1747 /* assign these fields before you register the wiphy */
@@ -1561,6 +1754,10 @@ struct wiphy {
1561 1754
1562 const struct ieee80211_txrx_stypes *mgmt_stypes; 1755 const struct ieee80211_txrx_stypes *mgmt_stypes;
1563 1756
1757 const struct ieee80211_iface_combination *iface_combinations;
1758 int n_iface_combinations;
1759 u16 software_iftypes;
1760
1564 u16 n_addresses; 1761 u16 n_addresses;
1565 1762
1566 /* Supported interface modes, OR together BIT(NL80211_IFTYPE_...) */ 1763 /* Supported interface modes, OR together BIT(NL80211_IFTYPE_...) */
@@ -1586,6 +1783,8 @@ struct wiphy {
1586 char fw_version[ETHTOOL_BUSINFO_LEN]; 1783 char fw_version[ETHTOOL_BUSINFO_LEN];
1587 u32 hw_version; 1784 u32 hw_version;
1588 1785
1786 struct wiphy_wowlan_support wowlan;
1787
1589 u16 max_remain_on_channel_duration; 1788 u16 max_remain_on_channel_duration;
1590 1789
1591 u8 max_num_pmkids; 1790 u8 max_num_pmkids;
@@ -1769,6 +1968,8 @@ struct cfg80211_cached_keys;
1769 * @mgmt_registrations_lock: lock for the list 1968 * @mgmt_registrations_lock: lock for the list
1770 * @mtx: mutex used to lock data in this struct 1969 * @mtx: mutex used to lock data in this struct
1771 * @cleanup_work: work struct used for cleanup that can't be done directly 1970 * @cleanup_work: work struct used for cleanup that can't be done directly
1971 * @beacon_interval: beacon interval used on this device for transmitting
1972 * beacons, 0 when not valid
1772 */ 1973 */
1773struct wireless_dev { 1974struct wireless_dev {
1774 struct wiphy *wiphy; 1975 struct wiphy *wiphy;
@@ -1809,6 +2010,8 @@ struct wireless_dev {
1809 bool ps; 2010 bool ps;
1810 int ps_timeout; 2011 int ps_timeout;
1811 2012
2013 int beacon_interval;
2014
1812#ifdef CONFIG_CFG80211_WEXT 2015#ifdef CONFIG_CFG80211_WEXT
1813 /* wext data */ 2016 /* wext data */
1814 struct { 2017 struct {
@@ -2034,10 +2237,12 @@ int ieee80211_data_from_8023(struct sk_buff *skb, const u8 *addr,
2034 * @addr: The device MAC address. 2237 * @addr: The device MAC address.
2035 * @iftype: The device interface type. 2238 * @iftype: The device interface type.
2036 * @extra_headroom: The hardware extra headroom for SKBs in the @list. 2239 * @extra_headroom: The hardware extra headroom for SKBs in the @list.
2240 * @has_80211_header: Set it true if SKB is with IEEE 802.11 header.
2037 */ 2241 */
2038void ieee80211_amsdu_to_8023s(struct sk_buff *skb, struct sk_buff_head *list, 2242void ieee80211_amsdu_to_8023s(struct sk_buff *skb, struct sk_buff_head *list,
2039 const u8 *addr, enum nl80211_iftype iftype, 2243 const u8 *addr, enum nl80211_iftype iftype,
2040 const unsigned int extra_headroom); 2244 const unsigned int extra_headroom,
2245 bool has_80211_header);
2041 2246
2042/** 2247/**
2043 * cfg80211_classify8021d - determine the 802.1p/1d tag for a data frame 2248 * cfg80211_classify8021d - determine the 802.1p/1d tag for a data frame
@@ -2257,6 +2462,24 @@ int cfg80211_wext_siwpmksa(struct net_device *dev,
2257void cfg80211_scan_done(struct cfg80211_scan_request *request, bool aborted); 2462void cfg80211_scan_done(struct cfg80211_scan_request *request, bool aborted);
2258 2463
2259/** 2464/**
2465 * cfg80211_sched_scan_results - notify that new scan results are available
2466 *
2467 * @wiphy: the wiphy which got scheduled scan results
2468 */
2469void cfg80211_sched_scan_results(struct wiphy *wiphy);
2470
2471/**
2472 * cfg80211_sched_scan_stopped - notify that the scheduled scan has stopped
2473 *
2474 * @wiphy: the wiphy on which the scheduled scan stopped
2475 *
2476 * The driver can call this function to inform cfg80211 that the
2477 * scheduled scan had to be stopped, for whatever reason. The driver
2478 * is then called back via the sched_scan_stop operation when done.
2479 */
2480void cfg80211_sched_scan_stopped(struct wiphy *wiphy);
2481
2482/**
2260 * cfg80211_inform_bss_frame - inform cfg80211 of a received BSS frame 2483 * cfg80211_inform_bss_frame - inform cfg80211 of a received BSS frame
2261 * 2484 *
2262 * @wiphy: the wiphy reporting the BSS 2485 * @wiphy: the wiphy reporting the BSS
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index db4b6b9f3977..8c7189c3f6ed 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -537,6 +537,21 @@ struct ieee80211_tx_info {
537 }; 537 };
538}; 538};
539 539
540/**
541 * ieee80211_sched_scan_ies - scheduled scan IEs
542 *
543 * This structure is used to pass the appropriate IEs to be used in scheduled
544 * scans for all bands. It contains both the IEs passed from the userspace
545 * and the ones generated by mac80211.
546 *
547 * @ie: array with the IEs for each supported band
548 * @len: array with the total length of the IEs for each band
549 */
550struct ieee80211_sched_scan_ies {
551 u8 *ie[IEEE80211_NUM_BANDS];
552 size_t len[IEEE80211_NUM_BANDS];
553};
554
540static inline struct ieee80211_tx_info *IEEE80211_SKB_CB(struct sk_buff *skb) 555static inline struct ieee80211_tx_info *IEEE80211_SKB_CB(struct sk_buff *skb)
541{ 556{
542 return (struct ieee80211_tx_info *)skb->cb; 557 return (struct ieee80211_tx_info *)skb->cb;
@@ -1606,6 +1621,18 @@ enum ieee80211_ampdu_mlme_action {
1606 * you should ensure to cancel it on this callback. 1621 * you should ensure to cancel it on this callback.
1607 * Must be implemented and can sleep. 1622 * Must be implemented and can sleep.
1608 * 1623 *
1624 * @suspend: Suspend the device; mac80211 itself will quiesce before and
1625 * stop transmitting and doing any other configuration, and then
1626 * ask the device to suspend. This is only invoked when WoWLAN is
1627 * configured, otherwise the device is deconfigured completely and
1628 * reconfigured at resume time.
1629 *
1630 * @resume: If WoWLAN was configured, this indicates that mac80211 is
1631 * now resuming its operation, after this the device must be fully
1632 * functional again. If this returns an error, the only way out is
1633 * to also unregister the device. If it returns 1, then mac80211
1634 * will also go through the regular complete restart on resume.
1635 *
1609 * @add_interface: Called when a netdevice attached to the hardware is 1636 * @add_interface: Called when a netdevice attached to the hardware is
1610 * enabled. Because it is not called for monitor mode devices, @start 1637 * enabled. Because it is not called for monitor mode devices, @start
1611 * and @stop must be implemented. 1638 * and @stop must be implemented.
@@ -1681,6 +1708,13 @@ enum ieee80211_ampdu_mlme_action {
1681 * any error unless this callback returned a negative error code. 1708 * any error unless this callback returned a negative error code.
1682 * The callback can sleep. 1709 * The callback can sleep.
1683 * 1710 *
1711 * @sched_scan_start: Ask the hardware to start scanning repeatedly at
1712 * specific intervals. The driver must call the
1713 * ieee80211_sched_scan_results() function whenever it finds results.
1714 * This process will continue until sched_scan_stop is called.
1715 *
1716 * @sched_scan_stop: Tell the hardware to stop an ongoing scheduled scan.
1717 *
1684 * @sw_scan_start: Notifier function that is called just before a software scan 1718 * @sw_scan_start: Notifier function that is called just before a software scan
1685 * is started. Can be NULL, if the driver doesn't need this notification. 1719 * is started. Can be NULL, if the driver doesn't need this notification.
1686 * The callback can sleep. 1720 * The callback can sleep.
@@ -1831,6 +1865,10 @@ struct ieee80211_ops {
1831 void (*tx)(struct ieee80211_hw *hw, struct sk_buff *skb); 1865 void (*tx)(struct ieee80211_hw *hw, struct sk_buff *skb);
1832 int (*start)(struct ieee80211_hw *hw); 1866 int (*start)(struct ieee80211_hw *hw);
1833 void (*stop)(struct ieee80211_hw *hw); 1867 void (*stop)(struct ieee80211_hw *hw);
1868#ifdef CONFIG_PM
1869 int (*suspend)(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan);
1870 int (*resume)(struct ieee80211_hw *hw);
1871#endif
1834 int (*add_interface)(struct ieee80211_hw *hw, 1872 int (*add_interface)(struct ieee80211_hw *hw,
1835 struct ieee80211_vif *vif); 1873 struct ieee80211_vif *vif);
1836 int (*change_interface)(struct ieee80211_hw *hw, 1874 int (*change_interface)(struct ieee80211_hw *hw,
@@ -1861,6 +1899,12 @@ struct ieee80211_ops {
1861 u32 iv32, u16 *phase1key); 1899 u32 iv32, u16 *phase1key);
1862 int (*hw_scan)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 1900 int (*hw_scan)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
1863 struct cfg80211_scan_request *req); 1901 struct cfg80211_scan_request *req);
1902 int (*sched_scan_start)(struct ieee80211_hw *hw,
1903 struct ieee80211_vif *vif,
1904 struct cfg80211_sched_scan_request *req,
1905 struct ieee80211_sched_scan_ies *ies);
1906 void (*sched_scan_stop)(struct ieee80211_hw *hw,
1907 struct ieee80211_vif *vif);
1864 void (*sw_scan_start)(struct ieee80211_hw *hw); 1908 void (*sw_scan_start)(struct ieee80211_hw *hw);
1865 void (*sw_scan_complete)(struct ieee80211_hw *hw); 1909 void (*sw_scan_complete)(struct ieee80211_hw *hw);
1866 int (*get_stats)(struct ieee80211_hw *hw, 1910 int (*get_stats)(struct ieee80211_hw *hw,
@@ -2578,6 +2622,28 @@ void ieee80211_wake_queues(struct ieee80211_hw *hw);
2578void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted); 2622void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted);
2579 2623
2580/** 2624/**
2625 * ieee80211_sched_scan_results - got results from scheduled scan
2626 *
2627 * When a scheduled scan is running, this function needs to be called by the
2628 * driver whenever there are new scan results available.
2629 *
2630 * @hw: the hardware that is performing scheduled scans
2631 */
2632void ieee80211_sched_scan_results(struct ieee80211_hw *hw);
2633
2634/**
2635 * ieee80211_sched_scan_stopped - inform that the scheduled scan has stopped
2636 *
2637 * When a scheduled scan is running, this function can be called by
2638 * the driver if it needs to stop the scan to perform another task.
2639 * Usual scenarios are drivers that cannot continue the scheduled scan
2640 * while associating, for instance.
2641 *
2642 * @hw: the hardware that is performing scheduled scans
2643 */
2644void ieee80211_sched_scan_stopped(struct ieee80211_hw *hw);
2645
2646/**
2581 * ieee80211_iterate_active_interfaces - iterate active interfaces 2647 * ieee80211_iterate_active_interfaces - iterate active interfaces
2582 * 2648 *
2583 * This function iterates over the interfaces associated with a given 2649 * This function iterates over the interfaces associated with a given
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 7f5ad8a2b22d..3163330cd4f1 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -623,6 +623,23 @@ encrypt:
623} 623}
624EXPORT_SYMBOL(hci_conn_security); 624EXPORT_SYMBOL(hci_conn_security);
625 625
626/* Check secure link requirement */
627int hci_conn_check_secure(struct hci_conn *conn, __u8 sec_level)
628{
629 BT_DBG("conn %p", conn);
630
631 if (sec_level != BT_SECURITY_HIGH)
632 return 1; /* Accept if non-secure is required */
633
634 if (conn->key_type == HCI_LK_AUTH_COMBINATION ||
635 (conn->key_type == HCI_LK_COMBINATION &&
636 conn->pin_length == 16))
637 return 1;
638
639 return 0; /* Reject not secure link */
640}
641EXPORT_SYMBOL(hci_conn_check_secure);
642
626/* Change link key */ 643/* Change link key */
627int hci_conn_change_link_key(struct hci_conn *conn) 644int hci_conn_change_link_key(struct hci_conn *conn)
628{ 645{
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index d5aa97ee6ffa..f13ddbf858ba 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -1440,7 +1440,7 @@ static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff
1440 1440
1441 conn->state = BT_CLOSED; 1441 conn->state = BT_CLOSED;
1442 1442
1443 if (conn->type == ACL_LINK) 1443 if (conn->type == ACL_LINK || conn->type == LE_LINK)
1444 mgmt_disconnected(hdev->id, &conn->dst); 1444 mgmt_disconnected(hdev->id, &conn->dst);
1445 1445
1446 hci_proto_disconn_cfm(conn, ev->reason); 1446 hci_proto_disconn_cfm(conn, ev->reason);
@@ -2659,12 +2659,15 @@ static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff
2659 } 2659 }
2660 2660
2661 if (ev->status) { 2661 if (ev->status) {
2662 mgmt_connect_failed(hdev->id, &ev->bdaddr, ev->status);
2662 hci_proto_connect_cfm(conn, ev->status); 2663 hci_proto_connect_cfm(conn, ev->status);
2663 conn->state = BT_CLOSED; 2664 conn->state = BT_CLOSED;
2664 hci_conn_del(conn); 2665 hci_conn_del(conn);
2665 goto unlock; 2666 goto unlock;
2666 } 2667 }
2667 2668
2669 mgmt_connected(hdev->id, &ev->bdaddr);
2670
2668 conn->handle = __le16_to_cpu(ev->handle); 2671 conn->handle = __le16_to_cpu(ev->handle);
2669 conn->state = BT_CONNECTED; 2672 conn->state = BT_CONNECTED;
2670 2673
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index a378acc491ec..4f3bc741183c 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -62,9 +62,8 @@ static u8 l2cap_fixed_chan[8] = { 0x02, };
62 62
63static struct workqueue_struct *_busy_wq; 63static struct workqueue_struct *_busy_wq;
64 64
65struct bt_sock_list l2cap_sk_list = { 65LIST_HEAD(chan_list);
66 .lock = __RW_LOCK_UNLOCKED(l2cap_sk_list.lock) 66DEFINE_RWLOCK(chan_list_lock);
67};
68 67
69static void l2cap_busy_work(struct work_struct *work); 68static void l2cap_busy_work(struct work_struct *work);
70 69
@@ -135,6 +134,64 @@ static inline struct l2cap_chan *l2cap_get_chan_by_ident(struct l2cap_conn *conn
135 return c; 134 return c;
136} 135}
137 136
137static struct l2cap_chan *__l2cap_global_chan_by_addr(__le16 psm, bdaddr_t *src)
138{
139 struct l2cap_chan *c;
140
141 list_for_each_entry(c, &chan_list, global_l) {
142 if (c->sport == psm && !bacmp(&bt_sk(c->sk)->src, src))
143 goto found;
144 }
145
146 c = NULL;
147found:
148 return c;
149}
150
151int l2cap_add_psm(struct l2cap_chan *chan, bdaddr_t *src, __le16 psm)
152{
153 int err;
154
155 write_lock_bh(&chan_list_lock);
156
157 if (psm && __l2cap_global_chan_by_addr(psm, src)) {
158 err = -EADDRINUSE;
159 goto done;
160 }
161
162 if (psm) {
163 chan->psm = psm;
164 chan->sport = psm;
165 err = 0;
166 } else {
167 u16 p;
168
169 err = -EINVAL;
170 for (p = 0x1001; p < 0x1100; p += 2)
171 if (!__l2cap_global_chan_by_addr(cpu_to_le16(p), src)) {
172 chan->psm = cpu_to_le16(p);
173 chan->sport = cpu_to_le16(p);
174 err = 0;
175 break;
176 }
177 }
178
179done:
180 write_unlock_bh(&chan_list_lock);
181 return err;
182}
183
184int l2cap_add_scid(struct l2cap_chan *chan, __u16 scid)
185{
186 write_lock_bh(&chan_list_lock);
187
188 chan->scid = scid;
189
190 write_unlock_bh(&chan_list_lock);
191
192 return 0;
193}
194
138static u16 l2cap_alloc_cid(struct l2cap_conn *conn) 195static u16 l2cap_alloc_cid(struct l2cap_conn *conn)
139{ 196{
140 u16 cid = L2CAP_CID_DYN_START; 197 u16 cid = L2CAP_CID_DYN_START;
@@ -147,7 +204,7 @@ static u16 l2cap_alloc_cid(struct l2cap_conn *conn)
147 return 0; 204 return 0;
148} 205}
149 206
150struct l2cap_chan *l2cap_chan_alloc(struct sock *sk) 207struct l2cap_chan *l2cap_chan_create(struct sock *sk)
151{ 208{
152 struct l2cap_chan *chan; 209 struct l2cap_chan *chan;
153 210
@@ -157,11 +214,19 @@ struct l2cap_chan *l2cap_chan_alloc(struct sock *sk)
157 214
158 chan->sk = sk; 215 chan->sk = sk;
159 216
217 write_lock_bh(&chan_list_lock);
218 list_add(&chan->global_l, &chan_list);
219 write_unlock_bh(&chan_list_lock);
220
160 return chan; 221 return chan;
161} 222}
162 223
163void l2cap_chan_free(struct l2cap_chan *chan) 224void l2cap_chan_destroy(struct l2cap_chan *chan)
164{ 225{
226 write_lock_bh(&chan_list_lock);
227 list_del(&chan->global_l);
228 write_unlock_bh(&chan_list_lock);
229
165 kfree(chan); 230 kfree(chan);
166} 231}
167 232
@@ -591,48 +656,51 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
591/* Find socket with cid and source bdaddr. 656/* Find socket with cid and source bdaddr.
592 * Returns closest match, locked. 657 * Returns closest match, locked.
593 */ 658 */
594static struct sock *l2cap_get_sock_by_scid(int state, __le16 cid, bdaddr_t *src) 659static struct l2cap_chan *l2cap_global_chan_by_scid(int state, __le16 cid, bdaddr_t *src)
595{ 660{
596 struct sock *sk = NULL, *sk1 = NULL; 661 struct l2cap_chan *c, *c1 = NULL;
597 struct hlist_node *node;
598 662
599 read_lock(&l2cap_sk_list.lock); 663 read_lock(&chan_list_lock);
600 664
601 sk_for_each(sk, node, &l2cap_sk_list.head) { 665 list_for_each_entry(c, &chan_list, global_l) {
602 struct l2cap_chan *chan = l2cap_pi(sk)->chan; 666 struct sock *sk = c->sk;
603 667
604 if (state && sk->sk_state != state) 668 if (state && sk->sk_state != state)
605 continue; 669 continue;
606 670
607 if (chan->scid == cid) { 671 if (c->scid == cid) {
608 /* Exact match. */ 672 /* Exact match. */
609 if (!bacmp(&bt_sk(sk)->src, src)) 673 if (!bacmp(&bt_sk(sk)->src, src)) {
610 break; 674 read_unlock(&chan_list_lock);
675 return c;
676 }
611 677
612 /* Closest match */ 678 /* Closest match */
613 if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) 679 if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY))
614 sk1 = sk; 680 c1 = c;
615 } 681 }
616 } 682 }
617 683
618 read_unlock(&l2cap_sk_list.lock); 684 read_unlock(&chan_list_lock);
619 685
620 return node ? sk : sk1; 686 return c1;
621} 687}
622 688
623static void l2cap_le_conn_ready(struct l2cap_conn *conn) 689static void l2cap_le_conn_ready(struct l2cap_conn *conn)
624{ 690{
625 struct sock *parent, *sk; 691 struct sock *parent, *sk;
626 struct l2cap_chan *chan; 692 struct l2cap_chan *chan, *pchan;
627 693
628 BT_DBG(""); 694 BT_DBG("");
629 695
630 /* Check if we have socket listening on cid */ 696 /* Check if we have socket listening on cid */
631 parent = l2cap_get_sock_by_scid(BT_LISTEN, L2CAP_CID_LE_DATA, 697 pchan = l2cap_global_chan_by_scid(BT_LISTEN, L2CAP_CID_LE_DATA,
632 conn->src); 698 conn->src);
633 if (!parent) 699 if (!pchan)
634 return; 700 return;
635 701
702 parent = pchan->sk;
703
636 bh_lock_sock(parent); 704 bh_lock_sock(parent);
637 705
638 /* Check for backlog size */ 706 /* Check for backlog size */
@@ -645,7 +713,7 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn)
645 if (!sk) 713 if (!sk)
646 goto clean; 714 goto clean;
647 715
648 chan = l2cap_chan_alloc(sk); 716 chan = l2cap_chan_create(sk);
649 if (!chan) { 717 if (!chan) {
650 l2cap_sock_kill(sk); 718 l2cap_sock_kill(sk);
651 goto clean; 719 goto clean;
@@ -823,33 +891,34 @@ static inline void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *ch
823/* Find socket with psm and source bdaddr. 891/* Find socket with psm and source bdaddr.
824 * Returns closest match. 892 * Returns closest match.
825 */ 893 */
826static struct sock *l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src) 894static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm, bdaddr_t *src)
827{ 895{
828 struct sock *sk = NULL, *sk1 = NULL; 896 struct l2cap_chan *c, *c1 = NULL;
829 struct hlist_node *node;
830 897
831 read_lock(&l2cap_sk_list.lock); 898 read_lock(&chan_list_lock);
832 899
833 sk_for_each(sk, node, &l2cap_sk_list.head) { 900 list_for_each_entry(c, &chan_list, global_l) {
834 struct l2cap_chan *chan = l2cap_pi(sk)->chan; 901 struct sock *sk = c->sk;
835 902
836 if (state && sk->sk_state != state) 903 if (state && sk->sk_state != state)
837 continue; 904 continue;
838 905
839 if (chan->psm == psm) { 906 if (c->psm == psm) {
840 /* Exact match. */ 907 /* Exact match. */
841 if (!bacmp(&bt_sk(sk)->src, src)) 908 if (!bacmp(&bt_sk(sk)->src, src)) {
842 break; 909 read_unlock_bh(&chan_list_lock);
910 return c;
911 }
843 912
844 /* Closest match */ 913 /* Closest match */
845 if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) 914 if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY))
846 sk1 = sk; 915 c1 = c;
847 } 916 }
848 } 917 }
849 918
850 read_unlock(&l2cap_sk_list.lock); 919 read_unlock(&chan_list_lock);
851 920
852 return node ? sk : sk1; 921 return c1;
853} 922}
854 923
855int l2cap_chan_connect(struct l2cap_chan *chan) 924int l2cap_chan_connect(struct l2cap_chan *chan)
@@ -2019,7 +2088,7 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd
2019{ 2088{
2020 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data; 2089 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
2021 struct l2cap_conn_rsp rsp; 2090 struct l2cap_conn_rsp rsp;
2022 struct l2cap_chan *chan = NULL; 2091 struct l2cap_chan *chan = NULL, *pchan;
2023 struct sock *parent, *sk = NULL; 2092 struct sock *parent, *sk = NULL;
2024 int result, status = L2CAP_CS_NO_INFO; 2093 int result, status = L2CAP_CS_NO_INFO;
2025 2094
@@ -2029,12 +2098,14 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd
2029 BT_DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid); 2098 BT_DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid);
2030 2099
2031 /* Check if we have socket listening on psm */ 2100 /* Check if we have socket listening on psm */
2032 parent = l2cap_get_sock_by_psm(BT_LISTEN, psm, conn->src); 2101 pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, conn->src);
2033 if (!parent) { 2102 if (!pchan) {
2034 result = L2CAP_CR_BAD_PSM; 2103 result = L2CAP_CR_BAD_PSM;
2035 goto sendresp; 2104 goto sendresp;
2036 } 2105 }
2037 2106
2107 parent = pchan->sk;
2108
2038 bh_lock_sock(parent); 2109 bh_lock_sock(parent);
2039 2110
2040 /* Check if the ACL is secure enough (if not SDP) */ 2111 /* Check if the ACL is secure enough (if not SDP) */
@@ -2057,7 +2128,7 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd
2057 if (!sk) 2128 if (!sk)
2058 goto response; 2129 goto response;
2059 2130
2060 chan = l2cap_chan_alloc(sk); 2131 chan = l2cap_chan_create(sk);
2061 if (!chan) { 2132 if (!chan) {
2062 l2cap_sock_kill(sk); 2133 l2cap_sock_kill(sk);
2063 goto response; 2134 goto response;
@@ -3685,11 +3756,14 @@ done:
3685static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, struct sk_buff *skb) 3756static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, struct sk_buff *skb)
3686{ 3757{
3687 struct sock *sk; 3758 struct sock *sk;
3759 struct l2cap_chan *chan;
3688 3760
3689 sk = l2cap_get_sock_by_psm(0, psm, conn->src); 3761 chan = l2cap_global_chan_by_psm(0, psm, conn->src);
3690 if (!sk) 3762 if (!chan)
3691 goto drop; 3763 goto drop;
3692 3764
3765 sk = chan->sk;
3766
3693 bh_lock_sock(sk); 3767 bh_lock_sock(sk);
3694 3768
3695 BT_DBG("sk %p, len %d", sk, skb->len); 3769 BT_DBG("sk %p, len %d", sk, skb->len);
@@ -3715,11 +3789,14 @@ done:
3715static inline int l2cap_att_channel(struct l2cap_conn *conn, __le16 cid, struct sk_buff *skb) 3789static inline int l2cap_att_channel(struct l2cap_conn *conn, __le16 cid, struct sk_buff *skb)
3716{ 3790{
3717 struct sock *sk; 3791 struct sock *sk;
3792 struct l2cap_chan *chan;
3718 3793
3719 sk = l2cap_get_sock_by_scid(0, cid, conn->src); 3794 chan = l2cap_global_chan_by_scid(0, cid, conn->src);
3720 if (!sk) 3795 if (!chan)
3721 goto drop; 3796 goto drop;
3722 3797
3798 sk = chan->sk;
3799
3723 bh_lock_sock(sk); 3800 bh_lock_sock(sk);
3724 3801
3725 BT_DBG("sk %p, len %d", sk, skb->len); 3802 BT_DBG("sk %p, len %d", sk, skb->len);
@@ -3786,8 +3863,7 @@ static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
3786static int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) 3863static int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
3787{ 3864{
3788 int exact = 0, lm1 = 0, lm2 = 0; 3865 int exact = 0, lm1 = 0, lm2 = 0;
3789 register struct sock *sk; 3866 struct l2cap_chan *c;
3790 struct hlist_node *node;
3791 3867
3792 if (type != ACL_LINK) 3868 if (type != ACL_LINK)
3793 return -EINVAL; 3869 return -EINVAL;
@@ -3795,25 +3871,25 @@ static int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type)
3795 BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr)); 3871 BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
3796 3872
3797 /* Find listening sockets and check their link_mode */ 3873 /* Find listening sockets and check their link_mode */
3798 read_lock(&l2cap_sk_list.lock); 3874 read_lock(&chan_list_lock);
3799 sk_for_each(sk, node, &l2cap_sk_list.head) { 3875 list_for_each_entry(c, &chan_list, global_l) {
3800 struct l2cap_chan *chan = l2cap_pi(sk)->chan; 3876 struct sock *sk = c->sk;
3801 3877
3802 if (sk->sk_state != BT_LISTEN) 3878 if (sk->sk_state != BT_LISTEN)
3803 continue; 3879 continue;
3804 3880
3805 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) { 3881 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) {
3806 lm1 |= HCI_LM_ACCEPT; 3882 lm1 |= HCI_LM_ACCEPT;
3807 if (chan->role_switch) 3883 if (c->role_switch)
3808 lm1 |= HCI_LM_MASTER; 3884 lm1 |= HCI_LM_MASTER;
3809 exact++; 3885 exact++;
3810 } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) { 3886 } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
3811 lm2 |= HCI_LM_ACCEPT; 3887 lm2 |= HCI_LM_ACCEPT;
3812 if (chan->role_switch) 3888 if (c->role_switch)
3813 lm2 |= HCI_LM_MASTER; 3889 lm2 |= HCI_LM_MASTER;
3814 } 3890 }
3815 } 3891 }
3816 read_unlock(&l2cap_sk_list.lock); 3892 read_unlock(&chan_list_lock);
3817 3893
3818 return exact ? lm1 : lm2; 3894 return exact ? lm1 : lm2;
3819} 3895}
@@ -4066,25 +4142,22 @@ drop:
4066 4142
4067static int l2cap_debugfs_show(struct seq_file *f, void *p) 4143static int l2cap_debugfs_show(struct seq_file *f, void *p)
4068{ 4144{
4069 struct sock *sk; 4145 struct l2cap_chan *c;
4070 struct hlist_node *node;
4071 4146
4072 read_lock_bh(&l2cap_sk_list.lock); 4147 read_lock_bh(&chan_list_lock);
4073 4148
4074 sk_for_each(sk, node, &l2cap_sk_list.head) { 4149 list_for_each_entry(c, &chan_list, global_l) {
4075 struct l2cap_pinfo *pi = l2cap_pi(sk); 4150 struct sock *sk = c->sk;
4076 struct l2cap_chan *chan = pi->chan;
4077 4151
4078 seq_printf(f, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d %d\n", 4152 seq_printf(f, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d %d\n",
4079 batostr(&bt_sk(sk)->src), 4153 batostr(&bt_sk(sk)->src),
4080 batostr(&bt_sk(sk)->dst), 4154 batostr(&bt_sk(sk)->dst),
4081 sk->sk_state, __le16_to_cpu(chan->psm), 4155 sk->sk_state, __le16_to_cpu(c->psm),
4082 chan->scid, chan->dcid, 4156 c->scid, c->dcid, c->imtu, c->omtu,
4083 chan->imtu, chan->omtu, chan->sec_level, 4157 c->sec_level, c->mode);
4084 chan->mode);
4085 } 4158 }
4086 4159
4087 read_unlock_bh(&l2cap_sk_list.lock); 4160 read_unlock_bh(&chan_list_lock);
4088 4161
4089 return 0; 4162 return 0;
4090} 4163}
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index 7c4a9ae9b3ce..18dc9888d8c2 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -78,22 +78,6 @@ void l2cap_sock_clear_timer(struct sock *sk)
78 sk_stop_timer(sk, &sk->sk_timer); 78 sk_stop_timer(sk, &sk->sk_timer);
79} 79}
80 80
81static struct sock *__l2cap_get_sock_by_addr(__le16 psm, bdaddr_t *src)
82{
83 struct sock *sk;
84 struct hlist_node *node;
85 sk_for_each(sk, node, &l2cap_sk_list.head) {
86 struct l2cap_chan *chan = l2cap_pi(sk)->chan;
87
88 if (chan->sport == psm && !bacmp(&bt_sk(sk)->src, src))
89 goto found;
90 }
91
92 sk = NULL;
93found:
94 return sk;
95}
96
97static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) 81static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
98{ 82{
99 struct sock *sk = sock->sk; 83 struct sock *sk = sock->sk;
@@ -136,26 +120,20 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
136 } 120 }
137 } 121 }
138 122
139 write_lock_bh(&l2cap_sk_list.lock); 123 if (la.l2_cid)
124 err = l2cap_add_scid(chan, la.l2_cid);
125 else
126 err = l2cap_add_psm(chan, &la.l2_bdaddr, la.l2_psm);
140 127
141 if (la.l2_psm && __l2cap_get_sock_by_addr(la.l2_psm, &la.l2_bdaddr)) { 128 if (err < 0)
142 err = -EADDRINUSE; 129 goto done;
143 } else {
144 /* Save source address */
145 bacpy(&bt_sk(sk)->src, &la.l2_bdaddr);
146 chan->psm = la.l2_psm;
147 chan->sport = la.l2_psm;
148 sk->sk_state = BT_BOUND;
149
150 if (__le16_to_cpu(la.l2_psm) == 0x0001 ||
151 __le16_to_cpu(la.l2_psm) == 0x0003)
152 chan->sec_level = BT_SECURITY_SDP;
153 }
154 130
155 if (la.l2_cid) 131 if (__le16_to_cpu(la.l2_psm) == 0x0001 ||
156 chan->scid = la.l2_cid; 132 __le16_to_cpu(la.l2_psm) == 0x0003)
133 chan->sec_level = BT_SECURITY_SDP;
157 134
158 write_unlock_bh(&l2cap_sk_list.lock); 135 bacpy(&bt_sk(sk)->src, &la.l2_bdaddr);
136 sk->sk_state = BT_BOUND;
159 137
160done: 138done:
161 release_sock(sk); 139 release_sock(sk);
@@ -278,28 +256,6 @@ static int l2cap_sock_listen(struct socket *sock, int backlog)
278 goto done; 256 goto done;
279 } 257 }
280 258
281 if (!chan->psm && !chan->scid) {
282 bdaddr_t *src = &bt_sk(sk)->src;
283 u16 psm;
284
285 err = -EINVAL;
286
287 write_lock_bh(&l2cap_sk_list.lock);
288
289 for (psm = 0x1001; psm < 0x1100; psm += 2)
290 if (!__l2cap_get_sock_by_addr(cpu_to_le16(psm), src)) {
291 chan->psm = cpu_to_le16(psm);
292 chan->sport = cpu_to_le16(psm);
293 err = 0;
294 break;
295 }
296
297 write_unlock_bh(&l2cap_sk_list.lock);
298
299 if (err < 0)
300 goto done;
301 }
302
303 sk->sk_max_ack_backlog = backlog; 259 sk->sk_max_ack_backlog = backlog;
304 sk->sk_ack_backlog = 0; 260 sk->sk_ack_backlog = 0;
305 sk->sk_state = BT_LISTEN; 261 sk->sk_state = BT_LISTEN;
@@ -852,8 +808,7 @@ void l2cap_sock_kill(struct sock *sk)
852 808
853 /* Kill poor orphan */ 809 /* Kill poor orphan */
854 810
855 l2cap_chan_free(l2cap_pi(sk)->chan); 811 l2cap_chan_destroy(l2cap_pi(sk)->chan);
856 bt_sock_unlink(&l2cap_sk_list, sk);
857 sock_set_flag(sk, SOCK_DEAD); 812 sock_set_flag(sk, SOCK_DEAD);
858 sock_put(sk); 813 sock_put(sk);
859} 814}
@@ -1069,7 +1024,6 @@ struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, g
1069 1024
1070 setup_timer(&sk->sk_timer, l2cap_sock_timeout, (unsigned long) sk); 1025 setup_timer(&sk->sk_timer, l2cap_sock_timeout, (unsigned long) sk);
1071 1026
1072 bt_sock_link(&l2cap_sk_list, sk);
1073 return sk; 1027 return sk;
1074} 1028}
1075 1029
@@ -1096,7 +1050,7 @@ static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol,
1096 if (!sk) 1050 if (!sk)
1097 return -ENOMEM; 1051 return -ENOMEM;
1098 1052
1099 chan = l2cap_chan_alloc(sk); 1053 chan = l2cap_chan_create(sk);
1100 if (!chan) { 1054 if (!chan) {
1101 l2cap_sock_kill(sk); 1055 l2cap_sock_kill(sk);
1102 return -ENOMEM; 1056 return -ENOMEM;
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 2481d257ed98..dae382ce7020 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -1033,6 +1033,9 @@ static int disconnect(struct sock *sk, u16 index, unsigned char *data, u16 len)
1033 } 1033 }
1034 1034
1035 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); 1035 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1036 if (!conn)
1037 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->bdaddr);
1038
1036 if (!conn) { 1039 if (!conn) {
1037 err = cmd_status(sk, index, MGMT_OP_DISCONNECT, ENOTCONN); 1040 err = cmd_status(sk, index, MGMT_OP_DISCONNECT, ENOTCONN);
1038 goto failed; 1041 goto failed;
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
index 121a5c13b989..5759bb7054f7 100644
--- a/net/bluetooth/rfcomm/core.c
+++ b/net/bluetooth/rfcomm/core.c
@@ -2096,7 +2096,7 @@ static void rfcomm_security_cfm(struct hci_conn *conn, u8 status, u8 encrypt)
2096 if (!test_and_clear_bit(RFCOMM_AUTH_PENDING, &d->flags)) 2096 if (!test_and_clear_bit(RFCOMM_AUTH_PENDING, &d->flags))
2097 continue; 2097 continue;
2098 2098
2099 if (!status) 2099 if (!status && hci_conn_check_secure(conn, d->sec_level))
2100 set_bit(RFCOMM_AUTH_ACCEPT, &d->flags); 2100 set_bit(RFCOMM_AUTH_ACCEPT, &d->flags);
2101 else 2101 else
2102 set_bit(RFCOMM_AUTH_REJECT, &d->flags); 2102 set_bit(RFCOMM_AUTH_REJECT, &d->flags);
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c
index 0c9d0c07eae6..9c0d76cdca92 100644
--- a/net/mac80211/agg-rx.c
+++ b/net/mac80211/agg-rx.c
@@ -63,7 +63,8 @@ void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
63 63
64 lockdep_assert_held(&sta->ampdu_mlme.mtx); 64 lockdep_assert_held(&sta->ampdu_mlme.mtx);
65 65
66 tid_rx = sta->ampdu_mlme.tid_rx[tid]; 66 tid_rx = rcu_dereference_protected(sta->ampdu_mlme.tid_rx[tid],
67 lockdep_is_held(&sta->ampdu_mlme.mtx));
67 68
68 if (!tid_rx) 69 if (!tid_rx)
69 return; 70 return;
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index 63d852cb4ca2..cd5125f77cc5 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -136,6 +136,14 @@ void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u1
136 ieee80211_tx_skb(sdata, skb); 136 ieee80211_tx_skb(sdata, skb);
137} 137}
138 138
139void ieee80211_assign_tid_tx(struct sta_info *sta, int tid,
140 struct tid_ampdu_tx *tid_tx)
141{
142 lockdep_assert_held(&sta->ampdu_mlme.mtx);
143 lockdep_assert_held(&sta->lock);
144 rcu_assign_pointer(sta->ampdu_mlme.tid_tx[tid], tid_tx);
145}
146
139static void kfree_tid_tx(struct rcu_head *rcu_head) 147static void kfree_tid_tx(struct rcu_head *rcu_head)
140{ 148{
141 struct tid_ampdu_tx *tid_tx = 149 struct tid_ampdu_tx *tid_tx =
@@ -149,19 +157,22 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
149 bool tx) 157 bool tx)
150{ 158{
151 struct ieee80211_local *local = sta->local; 159 struct ieee80211_local *local = sta->local;
152 struct tid_ampdu_tx *tid_tx = sta->ampdu_mlme.tid_tx[tid]; 160 struct tid_ampdu_tx *tid_tx;
153 int ret; 161 int ret;
154 162
155 lockdep_assert_held(&sta->ampdu_mlme.mtx); 163 lockdep_assert_held(&sta->ampdu_mlme.mtx);
156 164
157 if (!tid_tx)
158 return -ENOENT;
159
160 spin_lock_bh(&sta->lock); 165 spin_lock_bh(&sta->lock);
161 166
167 tid_tx = rcu_dereference_protected_tid_tx(sta, tid);
168 if (!tid_tx) {
169 spin_unlock_bh(&sta->lock);
170 return -ENOENT;
171 }
172
162 if (test_bit(HT_AGG_STATE_WANT_START, &tid_tx->state)) { 173 if (test_bit(HT_AGG_STATE_WANT_START, &tid_tx->state)) {
163 /* not even started yet! */ 174 /* not even started yet! */
164 rcu_assign_pointer(sta->ampdu_mlme.tid_tx[tid], NULL); 175 ieee80211_assign_tid_tx(sta, tid, NULL);
165 spin_unlock_bh(&sta->lock); 176 spin_unlock_bh(&sta->lock);
166 call_rcu(&tid_tx->rcu_head, kfree_tid_tx); 177 call_rcu(&tid_tx->rcu_head, kfree_tid_tx);
167 return 0; 178 return 0;
@@ -283,13 +294,13 @@ ieee80211_wake_queue_agg(struct ieee80211_local *local, int tid)
283 294
284void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid) 295void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid)
285{ 296{
286 struct tid_ampdu_tx *tid_tx = sta->ampdu_mlme.tid_tx[tid]; 297 struct tid_ampdu_tx *tid_tx;
287 struct ieee80211_local *local = sta->local; 298 struct ieee80211_local *local = sta->local;
288 struct ieee80211_sub_if_data *sdata = sta->sdata; 299 struct ieee80211_sub_if_data *sdata = sta->sdata;
289 u16 start_seq_num; 300 u16 start_seq_num;
290 int ret; 301 int ret;
291 302
292 lockdep_assert_held(&sta->ampdu_mlme.mtx); 303 tid_tx = rcu_dereference_protected_tid_tx(sta, tid);
293 304
294 /* 305 /*
295 * While we're asking the driver about the aggregation, 306 * While we're asking the driver about the aggregation,
@@ -318,7 +329,7 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid)
318 " tid %d\n", tid); 329 " tid %d\n", tid);
319#endif 330#endif
320 spin_lock_bh(&sta->lock); 331 spin_lock_bh(&sta->lock);
321 rcu_assign_pointer(sta->ampdu_mlme.tid_tx[tid], NULL); 332 ieee80211_assign_tid_tx(sta, tid, NULL);
322 spin_unlock_bh(&sta->lock); 333 spin_unlock_bh(&sta->lock);
323 334
324 ieee80211_wake_queue_agg(local, tid); 335 ieee80211_wake_queue_agg(local, tid);
@@ -396,9 +407,9 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid,
396 goto err_unlock_sta; 407 goto err_unlock_sta;
397 } 408 }
398 409
399 tid_tx = sta->ampdu_mlme.tid_tx[tid]; 410 tid_tx = rcu_dereference_protected_tid_tx(sta, tid);
400 /* check if the TID is not in aggregation flow already */ 411 /* check if the TID is not in aggregation flow already */
401 if (tid_tx) { 412 if (tid_tx || sta->ampdu_mlme.tid_start_tx[tid]) {
402#ifdef CONFIG_MAC80211_HT_DEBUG 413#ifdef CONFIG_MAC80211_HT_DEBUG
403 printk(KERN_DEBUG "BA request denied - session is not " 414 printk(KERN_DEBUG "BA request denied - session is not "
404 "idle on tid %u\n", tid); 415 "idle on tid %u\n", tid);
@@ -433,8 +444,11 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid,
433 sta->ampdu_mlme.dialog_token_allocator++; 444 sta->ampdu_mlme.dialog_token_allocator++;
434 tid_tx->dialog_token = sta->ampdu_mlme.dialog_token_allocator; 445 tid_tx->dialog_token = sta->ampdu_mlme.dialog_token_allocator;
435 446
436 /* finally, assign it to the array */ 447 /*
437 rcu_assign_pointer(sta->ampdu_mlme.tid_tx[tid], tid_tx); 448 * Finally, assign it to the start array; the work item will
449 * collect it and move it to the normal array.
450 */
451 sta->ampdu_mlme.tid_start_tx[tid] = tid_tx;
438 452
439 ieee80211_queue_work(&local->hw, &sta->ampdu_mlme.work); 453 ieee80211_queue_work(&local->hw, &sta->ampdu_mlme.work);
440 454
@@ -480,16 +494,19 @@ ieee80211_agg_splice_finish(struct ieee80211_local *local, u16 tid)
480static void ieee80211_agg_tx_operational(struct ieee80211_local *local, 494static void ieee80211_agg_tx_operational(struct ieee80211_local *local,
481 struct sta_info *sta, u16 tid) 495 struct sta_info *sta, u16 tid)
482{ 496{
497 struct tid_ampdu_tx *tid_tx;
498
483 lockdep_assert_held(&sta->ampdu_mlme.mtx); 499 lockdep_assert_held(&sta->ampdu_mlme.mtx);
484 500
501 tid_tx = rcu_dereference_protected_tid_tx(sta, tid);
502
485#ifdef CONFIG_MAC80211_HT_DEBUG 503#ifdef CONFIG_MAC80211_HT_DEBUG
486 printk(KERN_DEBUG "Aggregation is on for tid %d\n", tid); 504 printk(KERN_DEBUG "Aggregation is on for tid %d\n", tid);
487#endif 505#endif
488 506
489 drv_ampdu_action(local, sta->sdata, 507 drv_ampdu_action(local, sta->sdata,
490 IEEE80211_AMPDU_TX_OPERATIONAL, 508 IEEE80211_AMPDU_TX_OPERATIONAL,
491 &sta->sta, tid, NULL, 509 &sta->sta, tid, NULL, tid_tx->buf_size);
492 sta->ampdu_mlme.tid_tx[tid]->buf_size);
493 510
494 /* 511 /*
495 * synchronize with TX path, while splicing the TX path 512 * synchronize with TX path, while splicing the TX path
@@ -497,13 +514,13 @@ static void ieee80211_agg_tx_operational(struct ieee80211_local *local,
497 */ 514 */
498 spin_lock_bh(&sta->lock); 515 spin_lock_bh(&sta->lock);
499 516
500 ieee80211_agg_splice_packets(local, sta->ampdu_mlme.tid_tx[tid], tid); 517 ieee80211_agg_splice_packets(local, tid_tx, tid);
501 /* 518 /*
502 * Now mark as operational. This will be visible 519 * Now mark as operational. This will be visible
503 * in the TX path, and lets it go lock-free in 520 * in the TX path, and lets it go lock-free in
504 * the common case. 521 * the common case.
505 */ 522 */
506 set_bit(HT_AGG_STATE_OPERATIONAL, &sta->ampdu_mlme.tid_tx[tid]->state); 523 set_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state);
507 ieee80211_agg_splice_finish(local, tid); 524 ieee80211_agg_splice_finish(local, tid);
508 525
509 spin_unlock_bh(&sta->lock); 526 spin_unlock_bh(&sta->lock);
@@ -537,7 +554,7 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u16 tid)
537 } 554 }
538 555
539 mutex_lock(&sta->ampdu_mlme.mtx); 556 mutex_lock(&sta->ampdu_mlme.mtx);
540 tid_tx = sta->ampdu_mlme.tid_tx[tid]; 557 tid_tx = rcu_dereference_protected_tid_tx(sta, tid);
541 558
542 if (WARN_ON(!tid_tx)) { 559 if (WARN_ON(!tid_tx)) {
543#ifdef CONFIG_MAC80211_HT_DEBUG 560#ifdef CONFIG_MAC80211_HT_DEBUG
@@ -615,7 +632,7 @@ int ieee80211_stop_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid)
615 return -EINVAL; 632 return -EINVAL;
616 633
617 spin_lock_bh(&sta->lock); 634 spin_lock_bh(&sta->lock);
618 tid_tx = sta->ampdu_mlme.tid_tx[tid]; 635 tid_tx = rcu_dereference_protected_tid_tx(sta, tid);
619 636
620 if (!tid_tx) { 637 if (!tid_tx) {
621 ret = -ENOENT; 638 ret = -ENOENT;
@@ -671,7 +688,7 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid)
671 688
672 mutex_lock(&sta->ampdu_mlme.mtx); 689 mutex_lock(&sta->ampdu_mlme.mtx);
673 spin_lock_bh(&sta->lock); 690 spin_lock_bh(&sta->lock);
674 tid_tx = sta->ampdu_mlme.tid_tx[tid]; 691 tid_tx = rcu_dereference_protected_tid_tx(sta, tid);
675 692
676 if (!tid_tx || !test_bit(HT_AGG_STATE_STOPPING, &tid_tx->state)) { 693 if (!tid_tx || !test_bit(HT_AGG_STATE_STOPPING, &tid_tx->state)) {
677#ifdef CONFIG_MAC80211_HT_DEBUG 694#ifdef CONFIG_MAC80211_HT_DEBUG
@@ -697,7 +714,7 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid)
697 ieee80211_agg_splice_packets(local, tid_tx, tid); 714 ieee80211_agg_splice_packets(local, tid_tx, tid);
698 715
699 /* future packets must not find the tid_tx struct any more */ 716 /* future packets must not find the tid_tx struct any more */
700 rcu_assign_pointer(sta->ampdu_mlme.tid_tx[tid], NULL); 717 ieee80211_assign_tid_tx(sta, tid, NULL);
701 718
702 ieee80211_agg_splice_finish(local, tid); 719 ieee80211_agg_splice_finish(local, tid);
703 720
@@ -752,7 +769,7 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
752 769
753 mutex_lock(&sta->ampdu_mlme.mtx); 770 mutex_lock(&sta->ampdu_mlme.mtx);
754 771
755 tid_tx = sta->ampdu_mlme.tid_tx[tid]; 772 tid_tx = rcu_dereference_protected_tid_tx(sta, tid);
756 if (!tid_tx) 773 if (!tid_tx)
757 goto out; 774 goto out;
758 775
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 12d52cec9515..be70c70d3f5b 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -136,7 +136,10 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
136 mutex_lock(&sdata->local->sta_mtx); 136 mutex_lock(&sdata->local->sta_mtx);
137 137
138 if (mac_addr) { 138 if (mac_addr) {
139 sta = sta_info_get_bss(sdata, mac_addr); 139 if (ieee80211_vif_is_mesh(&sdata->vif))
140 sta = sta_info_get(sdata, mac_addr);
141 else
142 sta = sta_info_get_bss(sdata, mac_addr);
140 if (!sta) { 143 if (!sta) {
141 ieee80211_key_free(sdata->local, key); 144 ieee80211_key_free(sdata->local, key);
142 err = -ENOENT; 145 err = -ENOENT;
@@ -157,13 +160,14 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
157static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev, 160static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
158 u8 key_idx, bool pairwise, const u8 *mac_addr) 161 u8 key_idx, bool pairwise, const u8 *mac_addr)
159{ 162{
160 struct ieee80211_sub_if_data *sdata; 163 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
164 struct ieee80211_local *local = sdata->local;
161 struct sta_info *sta; 165 struct sta_info *sta;
166 struct ieee80211_key *key = NULL;
162 int ret; 167 int ret;
163 168
164 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 169 mutex_lock(&local->sta_mtx);
165 170 mutex_lock(&local->key_mtx);
166 mutex_lock(&sdata->local->sta_mtx);
167 171
168 if (mac_addr) { 172 if (mac_addr) {
169 ret = -ENOENT; 173 ret = -ENOENT;
@@ -172,33 +176,24 @@ static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
172 if (!sta) 176 if (!sta)
173 goto out_unlock; 177 goto out_unlock;
174 178
175 if (pairwise) { 179 if (pairwise)
176 if (sta->ptk) { 180 key = key_mtx_dereference(local, sta->ptk);
177 ieee80211_key_free(sdata->local, sta->ptk); 181 else
178 ret = 0; 182 key = key_mtx_dereference(local, sta->gtk[key_idx]);
179 } 183 } else
180 } else { 184 key = key_mtx_dereference(local, sdata->keys[key_idx]);
181 if (sta->gtk[key_idx]) {
182 ieee80211_key_free(sdata->local,
183 sta->gtk[key_idx]);
184 ret = 0;
185 }
186 }
187
188 goto out_unlock;
189 }
190 185
191 if (!sdata->keys[key_idx]) { 186 if (!key) {
192 ret = -ENOENT; 187 ret = -ENOENT;
193 goto out_unlock; 188 goto out_unlock;
194 } 189 }
195 190
196 ieee80211_key_free(sdata->local, sdata->keys[key_idx]); 191 __ieee80211_key_free(key);
197 WARN_ON(sdata->keys[key_idx]);
198 192
199 ret = 0; 193 ret = 0;
200 out_unlock: 194 out_unlock:
201 mutex_unlock(&sdata->local->sta_mtx); 195 mutex_unlock(&local->key_mtx);
196 mutex_unlock(&local->sta_mtx);
202 197
203 return ret; 198 return ret;
204} 199}
@@ -228,11 +223,11 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
228 goto out; 223 goto out;
229 224
230 if (pairwise) 225 if (pairwise)
231 key = sta->ptk; 226 key = rcu_dereference(sta->ptk);
232 else if (key_idx < NUM_DEFAULT_KEYS) 227 else if (key_idx < NUM_DEFAULT_KEYS)
233 key = sta->gtk[key_idx]; 228 key = rcu_dereference(sta->gtk[key_idx]);
234 } else 229 } else
235 key = sdata->keys[key_idx]; 230 key = rcu_dereference(sdata->keys[key_idx]);
236 231
237 if (!key) 232 if (!key)
238 goto out; 233 goto out;
@@ -468,7 +463,7 @@ static int ieee80211_config_beacon(struct ieee80211_sub_if_data *sdata,
468 int size; 463 int size;
469 int err = -EINVAL; 464 int err = -EINVAL;
470 465
471 old = sdata->u.ap.beacon; 466 old = rtnl_dereference(sdata->u.ap.beacon);
472 467
473 /* head must not be zero-length */ 468 /* head must not be zero-length */
474 if (params->head && !params->head_len) 469 if (params->head && !params->head_len)
@@ -563,8 +558,7 @@ static int ieee80211_add_beacon(struct wiphy *wiphy, struct net_device *dev,
563 558
564 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 559 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
565 560
566 old = sdata->u.ap.beacon; 561 old = rtnl_dereference(sdata->u.ap.beacon);
567
568 if (old) 562 if (old)
569 return -EALREADY; 563 return -EALREADY;
570 564
@@ -579,8 +573,7 @@ static int ieee80211_set_beacon(struct wiphy *wiphy, struct net_device *dev,
579 573
580 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 574 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
581 575
582 old = sdata->u.ap.beacon; 576 old = rtnl_dereference(sdata->u.ap.beacon);
583
584 if (!old) 577 if (!old)
585 return -ENOENT; 578 return -ENOENT;
586 579
@@ -594,8 +587,7 @@ static int ieee80211_del_beacon(struct wiphy *wiphy, struct net_device *dev)
594 587
595 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 588 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
596 589
597 old = sdata->u.ap.beacon; 590 old = rtnl_dereference(sdata->u.ap.beacon);
598
599 if (!old) 591 if (!old)
600 return -ENOENT; 592 return -ENOENT;
601 593
@@ -734,15 +726,29 @@ static void sta_apply_parameters(struct ieee80211_local *local,
734 params->ht_capa, 726 params->ht_capa,
735 &sta->sta.ht_cap); 727 &sta->sta.ht_cap);
736 728
737 if (ieee80211_vif_is_mesh(&sdata->vif) && params->plink_action) { 729 if (ieee80211_vif_is_mesh(&sdata->vif)) {
738 switch (params->plink_action) { 730#ifdef CONFIG_MAC80211_MESH
739 case PLINK_ACTION_OPEN: 731 if (sdata->u.mesh.security & IEEE80211_MESH_SEC_SECURED)
740 mesh_plink_open(sta); 732 switch (params->plink_state) {
741 break; 733 case NL80211_PLINK_LISTEN:
742 case PLINK_ACTION_BLOCK: 734 case NL80211_PLINK_ESTAB:
743 mesh_plink_block(sta); 735 case NL80211_PLINK_BLOCKED:
744 break; 736 sta->plink_state = params->plink_state;
745 } 737 break;
738 default:
739 /* nothing */
740 break;
741 }
742 else
743 switch (params->plink_action) {
744 case PLINK_ACTION_OPEN:
745 mesh_plink_open(sta);
746 break;
747 case PLINK_ACTION_BLOCK:
748 mesh_plink_block(sta);
749 break;
750 }
751#endif
746 } 752 }
747} 753}
748 754
@@ -943,8 +949,10 @@ static int ieee80211_change_mpath(struct wiphy *wiphy,
943static void mpath_set_pinfo(struct mesh_path *mpath, u8 *next_hop, 949static void mpath_set_pinfo(struct mesh_path *mpath, u8 *next_hop,
944 struct mpath_info *pinfo) 950 struct mpath_info *pinfo)
945{ 951{
946 if (mpath->next_hop) 952 struct sta_info *next_hop_sta = rcu_dereference(mpath->next_hop);
947 memcpy(next_hop, mpath->next_hop->sta.addr, ETH_ALEN); 953
954 if (next_hop_sta)
955 memcpy(next_hop, next_hop_sta->sta.addr, ETH_ALEN);
948 else 956 else
949 memset(next_hop, 0, ETH_ALEN); 957 memset(next_hop, 0, ETH_ALEN);
950 958
@@ -1064,7 +1072,11 @@ static int copy_mesh_setup(struct ieee80211_if_mesh *ifmsh,
1064 memcpy(ifmsh->mesh_id, setup->mesh_id, ifmsh->mesh_id_len); 1072 memcpy(ifmsh->mesh_id, setup->mesh_id, ifmsh->mesh_id_len);
1065 ifmsh->mesh_pp_id = setup->path_sel_proto; 1073 ifmsh->mesh_pp_id = setup->path_sel_proto;
1066 ifmsh->mesh_pm_id = setup->path_metric; 1074 ifmsh->mesh_pm_id = setup->path_metric;
1067 ifmsh->is_secure = setup->is_secure; 1075 ifmsh->security = IEEE80211_MESH_SEC_NONE;
1076 if (setup->is_authenticated)
1077 ifmsh->security |= IEEE80211_MESH_SEC_AUTHED;
1078 if (setup->is_secure)
1079 ifmsh->security |= IEEE80211_MESH_SEC_SECURED;
1068 1080
1069 return 0; 1081 return 0;
1070} 1082}
@@ -1297,9 +1309,10 @@ static int ieee80211_set_channel(struct wiphy *wiphy,
1297} 1309}
1298 1310
1299#ifdef CONFIG_PM 1311#ifdef CONFIG_PM
1300static int ieee80211_suspend(struct wiphy *wiphy) 1312static int ieee80211_suspend(struct wiphy *wiphy,
1313 struct cfg80211_wowlan *wowlan)
1301{ 1314{
1302 return __ieee80211_suspend(wiphy_priv(wiphy)); 1315 return __ieee80211_suspend(wiphy_priv(wiphy), wowlan);
1303} 1316}
1304 1317
1305static int ieee80211_resume(struct wiphy *wiphy) 1318static int ieee80211_resume(struct wiphy *wiphy)
@@ -1342,6 +1355,30 @@ static int ieee80211_scan(struct wiphy *wiphy,
1342 return ieee80211_request_scan(sdata, req); 1355 return ieee80211_request_scan(sdata, req);
1343} 1356}
1344 1357
1358static int
1359ieee80211_sched_scan_start(struct wiphy *wiphy,
1360 struct net_device *dev,
1361 struct cfg80211_sched_scan_request *req)
1362{
1363 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1364
1365 if (!sdata->local->ops->sched_scan_start)
1366 return -EOPNOTSUPP;
1367
1368 return ieee80211_request_sched_scan_start(sdata, req);
1369}
1370
1371static int
1372ieee80211_sched_scan_stop(struct wiphy *wiphy, struct net_device *dev)
1373{
1374 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1375
1376 if (!sdata->local->ops->sched_scan_stop)
1377 return -EOPNOTSUPP;
1378
1379 return ieee80211_request_sched_scan_stop(sdata);
1380}
1381
1345static int ieee80211_auth(struct wiphy *wiphy, struct net_device *dev, 1382static int ieee80211_auth(struct wiphy *wiphy, struct net_device *dev,
1346 struct cfg80211_auth_request *req) 1383 struct cfg80211_auth_request *req)
1347{ 1384{
@@ -2083,6 +2120,8 @@ struct cfg80211_ops mac80211_config_ops = {
2083 .suspend = ieee80211_suspend, 2120 .suspend = ieee80211_suspend,
2084 .resume = ieee80211_resume, 2121 .resume = ieee80211_resume,
2085 .scan = ieee80211_scan, 2122 .scan = ieee80211_scan,
2123 .sched_scan_start = ieee80211_sched_scan_start,
2124 .sched_scan_stop = ieee80211_sched_scan_stop,
2086 .auth = ieee80211_auth, 2125 .auth = ieee80211_auth,
2087 .assoc = ieee80211_assoc, 2126 .assoc = ieee80211_assoc,
2088 .deauth = ieee80211_deauth, 2127 .deauth = ieee80211_deauth,
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c
index 0a602dbfdb2b..186e02f7cc32 100644
--- a/net/mac80211/debugfs.c
+++ b/net/mac80211/debugfs.c
@@ -135,7 +135,7 @@ static ssize_t reset_write(struct file *file, const char __user *user_buf,
135 struct ieee80211_local *local = file->private_data; 135 struct ieee80211_local *local = file->private_data;
136 136
137 rtnl_lock(); 137 rtnl_lock();
138 __ieee80211_suspend(&local->hw); 138 __ieee80211_suspend(&local->hw, NULL);
139 __ieee80211_resume(&local->hw); 139 __ieee80211_resume(&local->hw);
140 rtnl_unlock(); 140 rtnl_unlock();
141 141
diff --git a/net/mac80211/debugfs_key.c b/net/mac80211/debugfs_key.c
index f7ef3477c24a..33c58b85c911 100644
--- a/net/mac80211/debugfs_key.c
+++ b/net/mac80211/debugfs_key.c
@@ -241,16 +241,12 @@ void ieee80211_debugfs_key_add(struct ieee80211_key *key)
241 if (!key->debugfs.dir) 241 if (!key->debugfs.dir)
242 return; 242 return;
243 243
244 rcu_read_lock(); 244 sta = key->sta;
245 sta = rcu_dereference(key->sta); 245 if (sta) {
246 if (sta)
247 sprintf(buf, "../../stations/%pM", sta->sta.addr); 246 sprintf(buf, "../../stations/%pM", sta->sta.addr);
248 rcu_read_unlock();
249
250 /* using sta as a boolean is fine outside RCU lock */
251 if (sta)
252 key->debugfs.stalink = 247 key->debugfs.stalink =
253 debugfs_create_symlink("station", key->debugfs.dir, buf); 248 debugfs_create_symlink("station", key->debugfs.dir, buf);
249 }
254 250
255 DEBUGFS_ADD(keylen); 251 DEBUGFS_ADD(keylen);
256 DEBUGFS_ADD(flags); 252 DEBUGFS_ADD(flags);
@@ -286,7 +282,8 @@ void ieee80211_debugfs_key_update_default(struct ieee80211_sub_if_data *sdata)
286 lockdep_assert_held(&sdata->local->key_mtx); 282 lockdep_assert_held(&sdata->local->key_mtx);
287 283
288 if (sdata->default_unicast_key) { 284 if (sdata->default_unicast_key) {
289 key = sdata->default_unicast_key; 285 key = key_mtx_dereference(sdata->local,
286 sdata->default_unicast_key);
290 sprintf(buf, "../keys/%d", key->debugfs.cnt); 287 sprintf(buf, "../keys/%d", key->debugfs.cnt);
291 sdata->debugfs.default_unicast_key = 288 sdata->debugfs.default_unicast_key =
292 debugfs_create_symlink("default_unicast_key", 289 debugfs_create_symlink("default_unicast_key",
@@ -297,7 +294,8 @@ void ieee80211_debugfs_key_update_default(struct ieee80211_sub_if_data *sdata)
297 } 294 }
298 295
299 if (sdata->default_multicast_key) { 296 if (sdata->default_multicast_key) {
300 key = sdata->default_multicast_key; 297 key = key_mtx_dereference(sdata->local,
298 sdata->default_multicast_key);
301 sprintf(buf, "../keys/%d", key->debugfs.cnt); 299 sprintf(buf, "../keys/%d", key->debugfs.cnt);
302 sdata->debugfs.default_multicast_key = 300 sdata->debugfs.default_multicast_key =
303 debugfs_create_symlink("default_multicast_key", 301 debugfs_create_symlink("default_multicast_key",
@@ -316,9 +314,8 @@ void ieee80211_debugfs_key_add_mgmt_default(struct ieee80211_sub_if_data *sdata)
316 if (!sdata->debugfs.dir) 314 if (!sdata->debugfs.dir)
317 return; 315 return;
318 316
319 /* this is running under the key lock */ 317 key = key_mtx_dereference(sdata->local,
320 318 sdata->default_mgmt_key);
321 key = sdata->default_mgmt_key;
322 if (key) { 319 if (key) {
323 sprintf(buf, "../keys/%d", key->debugfs.cnt); 320 sprintf(buf, "../keys/%d", key->debugfs.cnt);
324 sdata->debugfs.default_mgmt_key = 321 sdata->debugfs.default_mgmt_key =
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index 2ddb56e5b51f..eebf7a67daf7 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -41,6 +41,33 @@ static inline void drv_stop(struct ieee80211_local *local)
41 local->started = false; 41 local->started = false;
42} 42}
43 43
44#ifdef CONFIG_PM
45static inline int drv_suspend(struct ieee80211_local *local,
46 struct cfg80211_wowlan *wowlan)
47{
48 int ret;
49
50 might_sleep();
51
52 trace_drv_suspend(local);
53 ret = local->ops->suspend(&local->hw, wowlan);
54 trace_drv_return_int(local, ret);
55 return ret;
56}
57
58static inline int drv_resume(struct ieee80211_local *local)
59{
60 int ret;
61
62 might_sleep();
63
64 trace_drv_resume(local);
65 ret = local->ops->resume(&local->hw);
66 trace_drv_return_int(local, ret);
67 return ret;
68}
69#endif
70
44static inline int drv_add_interface(struct ieee80211_local *local, 71static inline int drv_add_interface(struct ieee80211_local *local,
45 struct ieee80211_vif *vif) 72 struct ieee80211_vif *vif)
46{ 73{
@@ -185,12 +212,39 @@ static inline int drv_hw_scan(struct ieee80211_local *local,
185 212
186 might_sleep(); 213 might_sleep();
187 214
188 trace_drv_hw_scan(local, sdata, req); 215 trace_drv_hw_scan(local, sdata);
189 ret = local->ops->hw_scan(&local->hw, &sdata->vif, req); 216 ret = local->ops->hw_scan(&local->hw, &sdata->vif, req);
190 trace_drv_return_int(local, ret); 217 trace_drv_return_int(local, ret);
191 return ret; 218 return ret;
192} 219}
193 220
221static inline int
222drv_sched_scan_start(struct ieee80211_local *local,
223 struct ieee80211_sub_if_data *sdata,
224 struct cfg80211_sched_scan_request *req,
225 struct ieee80211_sched_scan_ies *ies)
226{
227 int ret;
228
229 might_sleep();
230
231 trace_drv_sched_scan_start(local, sdata);
232 ret = local->ops->sched_scan_start(&local->hw, &sdata->vif,
233 req, ies);
234 trace_drv_return_int(local, ret);
235 return ret;
236}
237
238static inline void drv_sched_scan_stop(struct ieee80211_local *local,
239 struct ieee80211_sub_if_data *sdata)
240{
241 might_sleep();
242
243 trace_drv_sched_scan_stop(local, sdata);
244 local->ops->sched_scan_stop(&local->hw, &sdata->vif);
245 trace_drv_return_void(local);
246}
247
194static inline void drv_sw_scan_start(struct ieee80211_local *local) 248static inline void drv_sw_scan_start(struct ieee80211_local *local)
195{ 249{
196 might_sleep(); 250 might_sleep();
diff --git a/net/mac80211/driver-trace.h b/net/mac80211/driver-trace.h
index 191e834ec46b..ed9edcbd9aa5 100644
--- a/net/mac80211/driver-trace.h
+++ b/net/mac80211/driver-trace.h
@@ -55,6 +55,70 @@ DECLARE_EVENT_CLASS(local_only_evt,
55 TP_printk(LOCAL_PR_FMT, LOCAL_PR_ARG) 55 TP_printk(LOCAL_PR_FMT, LOCAL_PR_ARG)
56); 56);
57 57
58DECLARE_EVENT_CLASS(local_sdata_addr_evt,
59 TP_PROTO(struct ieee80211_local *local,
60 struct ieee80211_sub_if_data *sdata),
61 TP_ARGS(local, sdata),
62
63 TP_STRUCT__entry(
64 LOCAL_ENTRY
65 VIF_ENTRY
66 __array(char, addr, 6)
67 ),
68
69 TP_fast_assign(
70 LOCAL_ASSIGN;
71 VIF_ASSIGN;
72 memcpy(__entry->addr, sdata->vif.addr, 6);
73 ),
74
75 TP_printk(
76 LOCAL_PR_FMT VIF_PR_FMT " addr:%pM",
77 LOCAL_PR_ARG, VIF_PR_ARG, __entry->addr
78 )
79);
80
81DECLARE_EVENT_CLASS(local_u32_evt,
82 TP_PROTO(struct ieee80211_local *local, u32 value),
83 TP_ARGS(local, value),
84
85 TP_STRUCT__entry(
86 LOCAL_ENTRY
87 __field(u32, value)
88 ),
89
90 TP_fast_assign(
91 LOCAL_ASSIGN;
92 __entry->value = value;
93 ),
94
95 TP_printk(
96 LOCAL_PR_FMT " value:%d",
97 LOCAL_PR_ARG, __entry->value
98 )
99);
100
101DECLARE_EVENT_CLASS(local_sdata_evt,
102 TP_PROTO(struct ieee80211_local *local,
103 struct ieee80211_sub_if_data *sdata),
104 TP_ARGS(local, sdata),
105
106 TP_STRUCT__entry(
107 LOCAL_ENTRY
108 VIF_ENTRY
109 ),
110
111 TP_fast_assign(
112 LOCAL_ASSIGN;
113 VIF_ASSIGN;
114 ),
115
116 TP_printk(
117 LOCAL_PR_FMT VIF_PR_FMT,
118 LOCAL_PR_ARG, VIF_PR_ARG
119 )
120);
121
58DEFINE_EVENT(local_only_evt, drv_return_void, 122DEFINE_EVENT(local_only_evt, drv_return_void,
59 TP_PROTO(struct ieee80211_local *local), 123 TP_PROTO(struct ieee80211_local *local),
60 TP_ARGS(local) 124 TP_ARGS(local)
@@ -108,33 +172,25 @@ DEFINE_EVENT(local_only_evt, drv_start,
108 TP_ARGS(local) 172 TP_ARGS(local)
109); 173);
110 174
175DEFINE_EVENT(local_only_evt, drv_suspend,
176 TP_PROTO(struct ieee80211_local *local),
177 TP_ARGS(local)
178);
179
180DEFINE_EVENT(local_only_evt, drv_resume,
181 TP_PROTO(struct ieee80211_local *local),
182 TP_ARGS(local)
183);
184
111DEFINE_EVENT(local_only_evt, drv_stop, 185DEFINE_EVENT(local_only_evt, drv_stop,
112 TP_PROTO(struct ieee80211_local *local), 186 TP_PROTO(struct ieee80211_local *local),
113 TP_ARGS(local) 187 TP_ARGS(local)
114); 188);
115 189
116TRACE_EVENT(drv_add_interface, 190DEFINE_EVENT(local_sdata_addr_evt, drv_add_interface,
117 TP_PROTO(struct ieee80211_local *local, 191 TP_PROTO(struct ieee80211_local *local,
118 struct ieee80211_sub_if_data *sdata), 192 struct ieee80211_sub_if_data *sdata),
119 193 TP_ARGS(local, sdata)
120 TP_ARGS(local, sdata),
121
122 TP_STRUCT__entry(
123 LOCAL_ENTRY
124 VIF_ENTRY
125 __array(char, addr, 6)
126 ),
127
128 TP_fast_assign(
129 LOCAL_ASSIGN;
130 VIF_ASSIGN;
131 memcpy(__entry->addr, sdata->vif.addr, 6);
132 ),
133
134 TP_printk(
135 LOCAL_PR_FMT VIF_PR_FMT " addr:%pM",
136 LOCAL_PR_ARG, VIF_PR_ARG, __entry->addr
137 )
138); 194);
139 195
140TRACE_EVENT(drv_change_interface, 196TRACE_EVENT(drv_change_interface,
@@ -165,27 +221,10 @@ TRACE_EVENT(drv_change_interface,
165 ) 221 )
166); 222);
167 223
168TRACE_EVENT(drv_remove_interface, 224DEFINE_EVENT(local_sdata_addr_evt, drv_remove_interface,
169 TP_PROTO(struct ieee80211_local *local, struct ieee80211_sub_if_data *sdata), 225 TP_PROTO(struct ieee80211_local *local,
170 226 struct ieee80211_sub_if_data *sdata),
171 TP_ARGS(local, sdata), 227 TP_ARGS(local, sdata)
172
173 TP_STRUCT__entry(
174 LOCAL_ENTRY
175 VIF_ENTRY
176 __array(char, addr, 6)
177 ),
178
179 TP_fast_assign(
180 LOCAL_ASSIGN;
181 VIF_ASSIGN;
182 memcpy(__entry->addr, sdata->vif.addr, 6);
183 ),
184
185 TP_printk(
186 LOCAL_PR_FMT VIF_PR_FMT " addr:%pM",
187 LOCAL_PR_ARG, VIF_PR_ARG, __entry->addr
188 )
189); 228);
190 229
191TRACE_EVENT(drv_config, 230TRACE_EVENT(drv_config,
@@ -415,27 +454,22 @@ TRACE_EVENT(drv_update_tkip_key,
415 ) 454 )
416); 455);
417 456
418TRACE_EVENT(drv_hw_scan, 457DEFINE_EVENT(local_sdata_evt, drv_hw_scan,
419 TP_PROTO(struct ieee80211_local *local, 458 TP_PROTO(struct ieee80211_local *local,
420 struct ieee80211_sub_if_data *sdata, 459 struct ieee80211_sub_if_data *sdata),
421 struct cfg80211_scan_request *req), 460 TP_ARGS(local, sdata)
422 461);
423 TP_ARGS(local, sdata, req),
424
425 TP_STRUCT__entry(
426 LOCAL_ENTRY
427 VIF_ENTRY
428 ),
429 462
430 TP_fast_assign( 463DEFINE_EVENT(local_sdata_evt, drv_sched_scan_start,
431 LOCAL_ASSIGN; 464 TP_PROTO(struct ieee80211_local *local,
432 VIF_ASSIGN; 465 struct ieee80211_sub_if_data *sdata),
433 ), 466 TP_ARGS(local, sdata)
467);
434 468
435 TP_printk( 469DEFINE_EVENT(local_sdata_evt, drv_sched_scan_stop,
436 LOCAL_PR_FMT VIF_PR_FMT, 470 TP_PROTO(struct ieee80211_local *local,
437 LOCAL_PR_ARG,VIF_PR_ARG 471 struct ieee80211_sub_if_data *sdata),
438 ) 472 TP_ARGS(local, sdata)
439); 473);
440 474
441DEFINE_EVENT(local_only_evt, drv_sw_scan_start, 475DEFINE_EVENT(local_only_evt, drv_sw_scan_start,
@@ -504,46 +538,14 @@ TRACE_EVENT(drv_get_tkip_seq,
504 ) 538 )
505); 539);
506 540
507TRACE_EVENT(drv_set_frag_threshold, 541DEFINE_EVENT(local_u32_evt, drv_set_frag_threshold,
508 TP_PROTO(struct ieee80211_local *local, u32 value), 542 TP_PROTO(struct ieee80211_local *local, u32 value),
509 543 TP_ARGS(local, value)
510 TP_ARGS(local, value),
511
512 TP_STRUCT__entry(
513 LOCAL_ENTRY
514 __field(u32, value)
515 ),
516
517 TP_fast_assign(
518 LOCAL_ASSIGN;
519 __entry->value = value;
520 ),
521
522 TP_printk(
523 LOCAL_PR_FMT " value:%d",
524 LOCAL_PR_ARG, __entry->value
525 )
526); 544);
527 545
528TRACE_EVENT(drv_set_rts_threshold, 546DEFINE_EVENT(local_u32_evt, drv_set_rts_threshold,
529 TP_PROTO(struct ieee80211_local *local, u32 value), 547 TP_PROTO(struct ieee80211_local *local, u32 value),
530 548 TP_ARGS(local, value)
531 TP_ARGS(local, value),
532
533 TP_STRUCT__entry(
534 LOCAL_ENTRY
535 __field(u32, value)
536 ),
537
538 TP_fast_assign(
539 LOCAL_ASSIGN;
540 __entry->value = value;
541 ),
542
543 TP_printk(
544 LOCAL_PR_FMT " value:%d",
545 LOCAL_PR_ARG, __entry->value
546 )
547); 549);
548 550
549TRACE_EVENT(drv_set_coverage_class, 551TRACE_EVENT(drv_set_coverage_class,
@@ -1194,6 +1196,42 @@ TRACE_EVENT(api_scan_completed,
1194 ) 1196 )
1195); 1197);
1196 1198
1199TRACE_EVENT(api_sched_scan_results,
1200 TP_PROTO(struct ieee80211_local *local),
1201
1202 TP_ARGS(local),
1203
1204 TP_STRUCT__entry(
1205 LOCAL_ENTRY
1206 ),
1207
1208 TP_fast_assign(
1209 LOCAL_ASSIGN;
1210 ),
1211
1212 TP_printk(
1213 LOCAL_PR_FMT, LOCAL_PR_ARG
1214 )
1215);
1216
1217TRACE_EVENT(api_sched_scan_stopped,
1218 TP_PROTO(struct ieee80211_local *local),
1219
1220 TP_ARGS(local),
1221
1222 TP_STRUCT__entry(
1223 LOCAL_ENTRY
1224 ),
1225
1226 TP_fast_assign(
1227 LOCAL_ASSIGN;
1228 ),
1229
1230 TP_printk(
1231 LOCAL_PR_FMT, LOCAL_PR_ARG
1232 )
1233);
1234
1197TRACE_EVENT(api_sta_block_awake, 1235TRACE_EVENT(api_sta_block_awake,
1198 TP_PROTO(struct ieee80211_local *local, 1236 TP_PROTO(struct ieee80211_local *local,
1199 struct ieee80211_sta *sta, bool block), 1237 struct ieee80211_sta *sta, bool block),
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c
index b9e4b9bd2179..591add22bcc0 100644
--- a/net/mac80211/ht.c
+++ b/net/mac80211/ht.c
@@ -140,14 +140,29 @@ void ieee80211_ba_session_work(struct work_struct *work)
140 sta, tid, WLAN_BACK_RECIPIENT, 140 sta, tid, WLAN_BACK_RECIPIENT,
141 WLAN_REASON_QSTA_TIMEOUT, true); 141 WLAN_REASON_QSTA_TIMEOUT, true);
142 142
143 tid_tx = sta->ampdu_mlme.tid_tx[tid]; 143 tid_tx = sta->ampdu_mlme.tid_start_tx[tid];
144 if (!tid_tx) 144 if (tid_tx) {
145 continue; 145 /*
146 * Assign it over to the normal tid_tx array
147 * where it "goes live".
148 */
149 spin_lock_bh(&sta->lock);
150
151 sta->ampdu_mlme.tid_start_tx[tid] = NULL;
152 /* could there be a race? */
153 if (sta->ampdu_mlme.tid_tx[tid])
154 kfree(tid_tx);
155 else
156 ieee80211_assign_tid_tx(sta, tid, tid_tx);
157 spin_unlock_bh(&sta->lock);
146 158
147 if (test_bit(HT_AGG_STATE_WANT_START, &tid_tx->state))
148 ieee80211_tx_ba_session_handle_start(sta, tid); 159 ieee80211_tx_ba_session_handle_start(sta, tid);
149 else if (test_and_clear_bit(HT_AGG_STATE_WANT_STOP, 160 continue;
150 &tid_tx->state)) 161 }
162
163 tid_tx = rcu_dereference_protected_tid_tx(sta, tid);
164 if (tid_tx && test_and_clear_bit(HT_AGG_STATE_WANT_STOP,
165 &tid_tx->state))
151 ___ieee80211_stop_tx_ba_session(sta, tid, 166 ___ieee80211_stop_tx_ba_session(sta, tid,
152 WLAN_BACK_INITIATOR, 167 WLAN_BACK_INITIATOR,
153 true); 168 true);
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index b81860c94698..421eaa6b0c2b 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -662,12 +662,16 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata,
662 int tx_last_beacon, len = req->len; 662 int tx_last_beacon, len = req->len;
663 struct sk_buff *skb; 663 struct sk_buff *skb;
664 struct ieee80211_mgmt *resp; 664 struct ieee80211_mgmt *resp;
665 struct sk_buff *presp;
665 u8 *pos, *end; 666 u8 *pos, *end;
666 667
667 lockdep_assert_held(&ifibss->mtx); 668 lockdep_assert_held(&ifibss->mtx);
668 669
670 presp = rcu_dereference_protected(ifibss->presp,
671 lockdep_is_held(&ifibss->mtx));
672
669 if (ifibss->state != IEEE80211_IBSS_MLME_JOINED || 673 if (ifibss->state != IEEE80211_IBSS_MLME_JOINED ||
670 len < 24 + 2 || !ifibss->presp) 674 len < 24 + 2 || !presp)
671 return; 675 return;
672 676
673 tx_last_beacon = drv_tx_last_beacon(local); 677 tx_last_beacon = drv_tx_last_beacon(local);
@@ -705,7 +709,7 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata,
705 } 709 }
706 710
707 /* Reply with ProbeResp */ 711 /* Reply with ProbeResp */
708 skb = skb_copy(ifibss->presp, GFP_KERNEL); 712 skb = skb_copy(presp, GFP_KERNEL);
709 if (!skb) 713 if (!skb)
710 return; 714 return;
711 715
@@ -985,7 +989,8 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata)
985 989
986 /* remove beacon */ 990 /* remove beacon */
987 kfree(sdata->u.ibss.ie); 991 kfree(sdata->u.ibss.ie);
988 skb = sdata->u.ibss.presp; 992 skb = rcu_dereference_protected(sdata->u.ibss.presp,
993 lockdep_is_held(&sdata->u.ibss.mtx));
989 rcu_assign_pointer(sdata->u.ibss.presp, NULL); 994 rcu_assign_pointer(sdata->u.ibss.presp, NULL);
990 sdata->vif.bss_conf.ibss_joined = false; 995 sdata->vif.bss_conf.ibss_joined = false;
991 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED | 996 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 027c0467d7a3..2025af52b195 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -214,7 +214,7 @@ struct beacon_data {
214}; 214};
215 215
216struct ieee80211_if_ap { 216struct ieee80211_if_ap {
217 struct beacon_data *beacon; 217 struct beacon_data __rcu *beacon;
218 218
219 struct list_head vlans; 219 struct list_head vlans;
220 220
@@ -237,7 +237,7 @@ struct ieee80211_if_vlan {
237 struct list_head list; 237 struct list_head list;
238 238
239 /* used for all tx if the VLAN is configured to 4-addr mode */ 239 /* used for all tx if the VLAN is configured to 4-addr mode */
240 struct sta_info *sta; 240 struct sta_info __rcu *sta;
241}; 241};
242 242
243struct mesh_stats { 243struct mesh_stats {
@@ -442,7 +442,8 @@ struct ieee80211_if_ibss {
442 442
443 unsigned long ibss_join_req; 443 unsigned long ibss_join_req;
444 /* probe response/beacon for IBSS */ 444 /* probe response/beacon for IBSS */
445 struct sk_buff *presp, *skb; 445 struct sk_buff __rcu *presp;
446 struct sk_buff *skb;
446 447
447 enum { 448 enum {
448 IEEE80211_IBSS_MLME_SEARCH, 449 IEEE80211_IBSS_MLME_SEARCH,
@@ -490,7 +491,11 @@ struct ieee80211_if_mesh {
490 bool accepting_plinks; 491 bool accepting_plinks;
491 const u8 *ie; 492 const u8 *ie;
492 u8 ie_len; 493 u8 ie_len;
493 bool is_secure; 494 enum {
495 IEEE80211_MESH_SEC_NONE = 0x0,
496 IEEE80211_MESH_SEC_AUTHED = 0x1,
497 IEEE80211_MESH_SEC_SECURED = 0x2,
498 } security;
494}; 499};
495 500
496#ifdef CONFIG_MAC80211_MESH 501#ifdef CONFIG_MAC80211_MESH
@@ -563,9 +568,10 @@ struct ieee80211_sub_if_data {
563 struct ieee80211_fragment_entry fragments[IEEE80211_FRAGMENT_MAX]; 568 struct ieee80211_fragment_entry fragments[IEEE80211_FRAGMENT_MAX];
564 unsigned int fragment_next; 569 unsigned int fragment_next;
565 570
566 struct ieee80211_key *keys[NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS]; 571 struct ieee80211_key __rcu *keys[NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS];
567 struct ieee80211_key *default_unicast_key, *default_multicast_key; 572 struct ieee80211_key __rcu *default_unicast_key;
568 struct ieee80211_key *default_mgmt_key; 573 struct ieee80211_key __rcu *default_multicast_key;
574 struct ieee80211_key __rcu *default_mgmt_key;
569 575
570 u16 sequence_number; 576 u16 sequence_number;
571 __be16 control_port_protocol; 577 __be16 control_port_protocol;
@@ -764,6 +770,9 @@ struct ieee80211_local {
764 /* device is started */ 770 /* device is started */
765 bool started; 771 bool started;
766 772
773 /* wowlan is enabled -- don't reconfig on resume */
774 bool wowlan;
775
767 int tx_headroom; /* required headroom for hardware/radiotap */ 776 int tx_headroom; /* required headroom for hardware/radiotap */
768 777
769 /* count for keys needing tailroom space allocation */ 778 /* count for keys needing tailroom space allocation */
@@ -798,7 +807,7 @@ struct ieee80211_local {
798 spinlock_t sta_lock; 807 spinlock_t sta_lock;
799 unsigned long num_sta; 808 unsigned long num_sta;
800 struct list_head sta_list, sta_pending_list; 809 struct list_head sta_list, sta_pending_list;
801 struct sta_info *sta_hash[STA_HASH_SIZE]; 810 struct sta_info __rcu *sta_hash[STA_HASH_SIZE];
802 struct timer_list sta_cleanup; 811 struct timer_list sta_cleanup;
803 struct work_struct sta_finish_work; 812 struct work_struct sta_finish_work;
804 int sta_generation; 813 int sta_generation;
@@ -840,6 +849,10 @@ struct ieee80211_local {
840 int scan_channel_idx; 849 int scan_channel_idx;
841 int scan_ies_len; 850 int scan_ies_len;
842 851
852 bool sched_scanning;
853 struct ieee80211_sched_scan_ies sched_scan_ies;
854 struct work_struct sched_scan_stopped_work;
855
843 unsigned long leave_oper_channel_time; 856 unsigned long leave_oper_channel_time;
844 enum mac80211_scan_state next_scan_state; 857 enum mac80211_scan_state next_scan_state;
845 struct delayed_work scan_work; 858 struct delayed_work scan_work;
@@ -1147,6 +1160,12 @@ ieee80211_rx_bss_get(struct ieee80211_local *local, u8 *bssid, int freq,
1147void ieee80211_rx_bss_put(struct ieee80211_local *local, 1160void ieee80211_rx_bss_put(struct ieee80211_local *local,
1148 struct ieee80211_bss *bss); 1161 struct ieee80211_bss *bss);
1149 1162
1163/* scheduled scan handling */
1164int ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata,
1165 struct cfg80211_sched_scan_request *req);
1166int ieee80211_request_sched_scan_stop(struct ieee80211_sub_if_data *sdata);
1167void ieee80211_sched_scan_stopped_work(struct work_struct *work);
1168
1150/* off-channel helpers */ 1169/* off-channel helpers */
1151bool ieee80211_cfg_on_oper_channel(struct ieee80211_local *local); 1170bool ieee80211_cfg_on_oper_channel(struct ieee80211_local *local);
1152void ieee80211_offchannel_enable_all_ps(struct ieee80211_local *local, 1171void ieee80211_offchannel_enable_all_ps(struct ieee80211_local *local,
@@ -1250,7 +1269,8 @@ int ieee80211_reconfig(struct ieee80211_local *local);
1250void ieee80211_stop_device(struct ieee80211_local *local); 1269void ieee80211_stop_device(struct ieee80211_local *local);
1251 1270
1252#ifdef CONFIG_PM 1271#ifdef CONFIG_PM
1253int __ieee80211_suspend(struct ieee80211_hw *hw); 1272int __ieee80211_suspend(struct ieee80211_hw *hw,
1273 struct cfg80211_wowlan *wowlan);
1254 1274
1255static inline int __ieee80211_resume(struct ieee80211_hw *hw) 1275static inline int __ieee80211_resume(struct ieee80211_hw *hw)
1256{ 1276{
@@ -1263,7 +1283,8 @@ static inline int __ieee80211_resume(struct ieee80211_hw *hw)
1263 return ieee80211_reconfig(hw_to_local(hw)); 1283 return ieee80211_reconfig(hw_to_local(hw));
1264} 1284}
1265#else 1285#else
1266static inline int __ieee80211_suspend(struct ieee80211_hw *hw) 1286static inline int __ieee80211_suspend(struct ieee80211_hw *hw,
1287 struct cfg80211_wowlan *wowlan)
1267{ 1288{
1268 return 0; 1289 return 0;
1269} 1290}
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 80c29d626aa4..7dfbe71dc637 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -449,7 +449,8 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
449 /* APs need special treatment */ 449 /* APs need special treatment */
450 if (sdata->vif.type == NL80211_IFTYPE_AP) { 450 if (sdata->vif.type == NL80211_IFTYPE_AP) {
451 struct ieee80211_sub_if_data *vlan, *tmpsdata; 451 struct ieee80211_sub_if_data *vlan, *tmpsdata;
452 struct beacon_data *old_beacon = sdata->u.ap.beacon; 452 struct beacon_data *old_beacon =
453 rtnl_dereference(sdata->u.ap.beacon);
453 454
454 /* sdata_running will return false, so this will disable */ 455 /* sdata_running will return false, so this will disable */
455 ieee80211_bss_info_change_notify(sdata, 456 ieee80211_bss_info_change_notify(sdata,
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index b510721e3b3d..31afd712930d 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -195,7 +195,7 @@ static void __ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata,
195 assert_key_lock(sdata->local); 195 assert_key_lock(sdata->local);
196 196
197 if (idx >= 0 && idx < NUM_DEFAULT_KEYS) 197 if (idx >= 0 && idx < NUM_DEFAULT_KEYS)
198 key = sdata->keys[idx]; 198 key = key_mtx_dereference(sdata->local, sdata->keys[idx]);
199 199
200 if (uni) 200 if (uni)
201 rcu_assign_pointer(sdata->default_unicast_key, key); 201 rcu_assign_pointer(sdata->default_unicast_key, key);
@@ -222,7 +222,7 @@ __ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata, int idx)
222 222
223 if (idx >= NUM_DEFAULT_KEYS && 223 if (idx >= NUM_DEFAULT_KEYS &&
224 idx < NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS) 224 idx < NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS)
225 key = sdata->keys[idx]; 225 key = key_mtx_dereference(sdata->local, sdata->keys[idx]);
226 226
227 rcu_assign_pointer(sdata->default_mgmt_key, key); 227 rcu_assign_pointer(sdata->default_mgmt_key, key);
228 228
@@ -266,9 +266,15 @@ static void __ieee80211_key_replace(struct ieee80211_sub_if_data *sdata,
266 else 266 else
267 idx = new->conf.keyidx; 267 idx = new->conf.keyidx;
268 268
269 defunikey = old && sdata->default_unicast_key == old; 269 defunikey = old &&
270 defmultikey = old && sdata->default_multicast_key == old; 270 old == key_mtx_dereference(sdata->local,
271 defmgmtkey = old && sdata->default_mgmt_key == old; 271 sdata->default_unicast_key);
272 defmultikey = old &&
273 old == key_mtx_dereference(sdata->local,
274 sdata->default_multicast_key);
275 defmgmtkey = old &&
276 old == key_mtx_dereference(sdata->local,
277 sdata->default_mgmt_key);
272 278
273 if (defunikey && !new) 279 if (defunikey && !new)
274 __ieee80211_set_default_key(sdata, -1, true, false); 280 __ieee80211_set_default_key(sdata, -1, true, false);
@@ -451,11 +457,11 @@ int ieee80211_key_link(struct ieee80211_key *key,
451 mutex_lock(&sdata->local->key_mtx); 457 mutex_lock(&sdata->local->key_mtx);
452 458
453 if (sta && pairwise) 459 if (sta && pairwise)
454 old_key = sta->ptk; 460 old_key = key_mtx_dereference(sdata->local, sta->ptk);
455 else if (sta) 461 else if (sta)
456 old_key = sta->gtk[idx]; 462 old_key = key_mtx_dereference(sdata->local, sta->gtk[idx]);
457 else 463 else
458 old_key = sdata->keys[idx]; 464 old_key = key_mtx_dereference(sdata->local, sdata->keys[idx]);
459 465
460 __ieee80211_key_replace(sdata, sta, pairwise, old_key, key); 466 __ieee80211_key_replace(sdata, sta, pairwise, old_key, key);
461 __ieee80211_key_destroy(old_key); 467 __ieee80211_key_destroy(old_key);
@@ -471,8 +477,11 @@ int ieee80211_key_link(struct ieee80211_key *key,
471 return ret; 477 return ret;
472} 478}
473 479
474static void __ieee80211_key_free(struct ieee80211_key *key) 480void __ieee80211_key_free(struct ieee80211_key *key)
475{ 481{
482 if (!key)
483 return;
484
476 /* 485 /*
477 * Replace key with nothingness if it was ever used. 486 * Replace key with nothingness if it was ever used.
478 */ 487 */
@@ -486,9 +495,6 @@ static void __ieee80211_key_free(struct ieee80211_key *key)
486void ieee80211_key_free(struct ieee80211_local *local, 495void ieee80211_key_free(struct ieee80211_local *local,
487 struct ieee80211_key *key) 496 struct ieee80211_key *key)
488{ 497{
489 if (!key)
490 return;
491
492 mutex_lock(&local->key_mtx); 498 mutex_lock(&local->key_mtx);
493 __ieee80211_key_free(key); 499 __ieee80211_key_free(key);
494 mutex_unlock(&local->key_mtx); 500 mutex_unlock(&local->key_mtx);
diff --git a/net/mac80211/key.h b/net/mac80211/key.h
index 4ddbe27eb570..d801d5351336 100644
--- a/net/mac80211/key.h
+++ b/net/mac80211/key.h
@@ -135,6 +135,7 @@ struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len,
135int __must_check ieee80211_key_link(struct ieee80211_key *key, 135int __must_check ieee80211_key_link(struct ieee80211_key *key,
136 struct ieee80211_sub_if_data *sdata, 136 struct ieee80211_sub_if_data *sdata,
137 struct sta_info *sta); 137 struct sta_info *sta);
138void __ieee80211_key_free(struct ieee80211_key *key);
138void ieee80211_key_free(struct ieee80211_local *local, 139void ieee80211_key_free(struct ieee80211_local *local,
139 struct ieee80211_key *key); 140 struct ieee80211_key *key);
140void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx, 141void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx,
@@ -145,4 +146,7 @@ void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata);
145void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata); 146void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata);
146void ieee80211_disable_keys(struct ieee80211_sub_if_data *sdata); 147void ieee80211_disable_keys(struct ieee80211_sub_if_data *sdata);
147 148
149#define key_mtx_dereference(local, ref) \
150 rcu_dereference_protected(ref, lockdep_is_held(&((local)->key_mtx)))
151
148#endif /* IEEE80211_KEY_H */ 152#endif /* IEEE80211_KEY_H */
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 61877662e8f8..0d7b08db8e56 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -358,7 +358,8 @@ static void ieee80211_restart_work(struct work_struct *work)
358 flush_workqueue(local->workqueue); 358 flush_workqueue(local->workqueue);
359 359
360 mutex_lock(&local->mtx); 360 mutex_lock(&local->mtx);
361 WARN(test_bit(SCAN_HW_SCANNING, &local->scanning), 361 WARN(test_bit(SCAN_HW_SCANNING, &local->scanning) ||
362 local->sched_scanning,
362 "%s called with hardware scan in progress\n", __func__); 363 "%s called with hardware scan in progress\n", __func__);
363 mutex_unlock(&local->mtx); 364 mutex_unlock(&local->mtx);
364 365
@@ -580,8 +581,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
580 581
581 wiphy->flags |= WIPHY_FLAG_NETNS_OK | 582 wiphy->flags |= WIPHY_FLAG_NETNS_OK |
582 WIPHY_FLAG_4ADDR_AP | 583 WIPHY_FLAG_4ADDR_AP |
583 WIPHY_FLAG_4ADDR_STATION | 584 WIPHY_FLAG_4ADDR_STATION;
584 WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS;
585 585
586 if (!ops->set_key) 586 if (!ops->set_key)
587 wiphy->flags |= WIPHY_FLAG_IBSS_RSN; 587 wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
@@ -652,6 +652,9 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
652 setup_timer(&local->dynamic_ps_timer, 652 setup_timer(&local->dynamic_ps_timer,
653 ieee80211_dynamic_ps_timer, (unsigned long) local); 653 ieee80211_dynamic_ps_timer, (unsigned long) local);
654 654
655 INIT_WORK(&local->sched_scan_stopped_work,
656 ieee80211_sched_scan_stopped_work);
657
655 sta_info_init(local); 658 sta_info_init(local);
656 659
657 for (i = 0; i < IEEE80211_MAX_QUEUES; i++) { 660 for (i = 0; i < IEEE80211_MAX_QUEUES; i++) {
@@ -682,7 +685,7 @@ EXPORT_SYMBOL(ieee80211_alloc_hw);
682int ieee80211_register_hw(struct ieee80211_hw *hw) 685int ieee80211_register_hw(struct ieee80211_hw *hw)
683{ 686{
684 struct ieee80211_local *local = hw_to_local(hw); 687 struct ieee80211_local *local = hw_to_local(hw);
685 int result; 688 int result, i;
686 enum ieee80211_band band; 689 enum ieee80211_band band;
687 int channels, max_bitrates; 690 int channels, max_bitrates;
688 bool supp_ht; 691 bool supp_ht;
@@ -697,6 +700,13 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
697 WLAN_CIPHER_SUITE_AES_CMAC 700 WLAN_CIPHER_SUITE_AES_CMAC
698 }; 701 };
699 702
703 if ((hw->wiphy->wowlan.flags || hw->wiphy->wowlan.n_patterns)
704#ifdef CONFIG_PM
705 && (!local->ops->suspend || !local->ops->resume)
706#endif
707 )
708 return -EINVAL;
709
700 if (hw->max_report_rates == 0) 710 if (hw->max_report_rates == 0)
701 hw->max_report_rates = hw->max_rates; 711 hw->max_report_rates = hw->max_rates;
702 712
@@ -733,11 +743,19 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
733 return -ENOMEM; 743 return -ENOMEM;
734 744
735 /* if low-level driver supports AP, we also support VLAN */ 745 /* if low-level driver supports AP, we also support VLAN */
736 if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_AP)) 746 if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_AP)) {
737 local->hw.wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP_VLAN); 747 hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP_VLAN);
748 hw->wiphy->software_iftypes |= BIT(NL80211_IFTYPE_AP_VLAN);
749 }
738 750
739 /* mac80211 always supports monitor */ 751 /* mac80211 always supports monitor */
740 local->hw.wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR); 752 hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
753 hw->wiphy->software_iftypes |= BIT(NL80211_IFTYPE_MONITOR);
754
755 /* mac80211 doesn't support more than 1 channel */
756 for (i = 0; i < hw->wiphy->n_iface_combinations; i++)
757 if (hw->wiphy->iface_combinations[i].num_different_channels > 1)
758 return -EINVAL;
741 759
742#ifndef CONFIG_MAC80211_MESH 760#ifndef CONFIG_MAC80211_MESH
743 /* mesh depends on Kconfig, but drivers should set it if they want */ 761 /* mesh depends on Kconfig, but drivers should set it if they want */
@@ -827,6 +845,9 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
827 if (!local->ops->remain_on_channel) 845 if (!local->ops->remain_on_channel)
828 local->hw.wiphy->max_remain_on_channel_duration = 5000; 846 local->hw.wiphy->max_remain_on_channel_duration = 5000;
829 847
848 if (local->ops->sched_scan_start)
849 local->hw.wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
850
830 result = wiphy_register(local->hw.wiphy); 851 result = wiphy_register(local->hw.wiphy);
831 if (result < 0) 852 if (result < 0)
832 goto fail_wiphy_register; 853 goto fail_wiphy_register;
@@ -850,8 +871,10 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
850 * and we need some headroom for passing the frame to monitor 871 * and we need some headroom for passing the frame to monitor
851 * interfaces, but never both at the same time. 872 * interfaces, but never both at the same time.
852 */ 873 */
874#ifndef __CHECKER__
853 BUILD_BUG_ON(IEEE80211_TX_STATUS_HEADROOM != 875 BUILD_BUG_ON(IEEE80211_TX_STATUS_HEADROOM !=
854 sizeof(struct ieee80211_tx_status_rtap_hdr)); 876 sizeof(struct ieee80211_tx_status_rtap_hdr));
877#endif
855 local->tx_headroom = max_t(unsigned int , local->hw.extra_tx_headroom, 878 local->tx_headroom = max_t(unsigned int , local->hw.extra_tx_headroom,
856 sizeof(struct ieee80211_tx_status_rtap_hdr)); 879 sizeof(struct ieee80211_tx_status_rtap_hdr));
857 880
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index c1299e249541..29e9980c8e60 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -287,49 +287,6 @@ void mesh_mgmt_ies_add(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata)
287 } 287 }
288} 288}
289 289
290u32 mesh_table_hash(u8 *addr, struct ieee80211_sub_if_data *sdata, struct mesh_table *tbl)
291{
292 /* Use last four bytes of hw addr and interface index as hash index */
293 return jhash_2words(*(u32 *)(addr+2), sdata->dev->ifindex, tbl->hash_rnd)
294 & tbl->hash_mask;
295}
296
297struct mesh_table *mesh_table_alloc(int size_order)
298{
299 int i;
300 struct mesh_table *newtbl;
301
302 newtbl = kmalloc(sizeof(struct mesh_table), GFP_KERNEL);
303 if (!newtbl)
304 return NULL;
305
306 newtbl->hash_buckets = kzalloc(sizeof(struct hlist_head) *
307 (1 << size_order), GFP_KERNEL);
308
309 if (!newtbl->hash_buckets) {
310 kfree(newtbl);
311 return NULL;
312 }
313
314 newtbl->hashwlock = kmalloc(sizeof(spinlock_t) *
315 (1 << size_order), GFP_KERNEL);
316 if (!newtbl->hashwlock) {
317 kfree(newtbl->hash_buckets);
318 kfree(newtbl);
319 return NULL;
320 }
321
322 newtbl->size_order = size_order;
323 newtbl->hash_mask = (1 << size_order) - 1;
324 atomic_set(&newtbl->entries, 0);
325 get_random_bytes(&newtbl->hash_rnd,
326 sizeof(newtbl->hash_rnd));
327 for (i = 0; i <= newtbl->hash_mask; i++)
328 spin_lock_init(&newtbl->hashwlock[i]);
329
330 return newtbl;
331}
332
333 290
334static void ieee80211_mesh_path_timer(unsigned long data) 291static void ieee80211_mesh_path_timer(unsigned long data)
335{ 292{
@@ -574,7 +531,7 @@ static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
574 &elems); 531 &elems);
575 532
576 /* ignore beacons from secure mesh peers if our security is off */ 533 /* ignore beacons from secure mesh peers if our security is off */
577 if (elems.rsn_len && !sdata->u.mesh.is_secure) 534 if (elems.rsn_len && sdata->u.mesh.security == IEEE80211_MESH_SEC_NONE)
578 return; 535 return;
579 536
580 if (elems.ds_params && elems.ds_params_len == 1) 537 if (elems.ds_params && elems.ds_params_len == 1)
@@ -600,7 +557,7 @@ static void ieee80211_mesh_rx_mgmt_action(struct ieee80211_sub_if_data *sdata,
600 struct ieee80211_rx_status *rx_status) 557 struct ieee80211_rx_status *rx_status)
601{ 558{
602 switch (mgmt->u.action.category) { 559 switch (mgmt->u.action.category) {
603 case WLAN_CATEGORY_MESH_PLINK: 560 case WLAN_CATEGORY_MESH_ACTION:
604 mesh_rx_plink_frame(sdata, mgmt, len, rx_status); 561 mesh_rx_plink_frame(sdata, mgmt, len, rx_status);
605 break; 562 break;
606 case WLAN_CATEGORY_MESH_PATH_SEL: 563 case WLAN_CATEGORY_MESH_PATH_SEL:
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index 10acf1cc8082..e7c5fddb4804 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -92,7 +92,7 @@ struct mesh_path {
92 u8 dst[ETH_ALEN]; 92 u8 dst[ETH_ALEN];
93 u8 mpp[ETH_ALEN]; /* used for MPP or MAP */ 93 u8 mpp[ETH_ALEN]; /* used for MPP or MAP */
94 struct ieee80211_sub_if_data *sdata; 94 struct ieee80211_sub_if_data *sdata;
95 struct sta_info *next_hop; 95 struct sta_info __rcu *next_hop;
96 struct timer_list timer; 96 struct timer_list timer;
97 struct sk_buff_head frame_queue; 97 struct sk_buff_head frame_queue;
98 struct rcu_head rcu; 98 struct rcu_head rcu;
@@ -240,12 +240,8 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
240 240
241/* Private interfaces */ 241/* Private interfaces */
242/* Mesh tables */ 242/* Mesh tables */
243struct mesh_table *mesh_table_alloc(int size_order);
244void mesh_table_free(struct mesh_table *tbl, bool free_leafs);
245void mesh_mpath_table_grow(void); 243void mesh_mpath_table_grow(void);
246void mesh_mpp_table_grow(void); 244void mesh_mpp_table_grow(void);
247u32 mesh_table_hash(u8 *addr, struct ieee80211_sub_if_data *sdata,
248 struct mesh_table *tbl);
249/* Mesh paths */ 245/* Mesh paths */
250int mesh_path_error_tx(u8 ttl, u8 *target, __le32 target_sn, __le16 target_rcode, 246int mesh_path_error_tx(u8 ttl, u8 *target, __le32 target_sn, __le16 target_rcode,
251 const u8 *ra, struct ieee80211_sub_if_data *sdata); 247 const u8 *ra, struct ieee80211_sub_if_data *sdata);
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index e57f2e728cfe..2b18053070c1 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -391,7 +391,6 @@ static u32 hwmp_route_info_get(struct ieee80211_sub_if_data *sdata,
391 (mpath->flags & MESH_PATH_SN_VALID)) { 391 (mpath->flags & MESH_PATH_SN_VALID)) {
392 if (SN_GT(mpath->sn, orig_sn) || 392 if (SN_GT(mpath->sn, orig_sn) ||
393 (mpath->sn == orig_sn && 393 (mpath->sn == orig_sn &&
394 action == MPATH_PREQ &&
395 new_metric >= mpath->metric)) { 394 new_metric >= mpath->metric)) {
396 process = false; 395 process = false;
397 fresh_info = false; 396 fresh_info = false;
@@ -561,6 +560,14 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
561} 560}
562 561
563 562
563static inline struct sta_info *
564next_hop_deref_protected(struct mesh_path *mpath)
565{
566 return rcu_dereference_protected(mpath->next_hop,
567 lockdep_is_held(&mpath->state_lock));
568}
569
570
564static void hwmp_prep_frame_process(struct ieee80211_sub_if_data *sdata, 571static void hwmp_prep_frame_process(struct ieee80211_sub_if_data *sdata,
565 struct ieee80211_mgmt *mgmt, 572 struct ieee80211_mgmt *mgmt,
566 u8 *prep_elem, u32 metric) 573 u8 *prep_elem, u32 metric)
@@ -600,7 +607,7 @@ static void hwmp_prep_frame_process(struct ieee80211_sub_if_data *sdata,
600 spin_unlock_bh(&mpath->state_lock); 607 spin_unlock_bh(&mpath->state_lock);
601 goto fail; 608 goto fail;
602 } 609 }
603 memcpy(next_hop, mpath->next_hop->sta.addr, ETH_ALEN); 610 memcpy(next_hop, next_hop_deref_protected(mpath)->sta.addr, ETH_ALEN);
604 spin_unlock_bh(&mpath->state_lock); 611 spin_unlock_bh(&mpath->state_lock);
605 --ttl; 612 --ttl;
606 flags = PREP_IE_FLAGS(prep_elem); 613 flags = PREP_IE_FLAGS(prep_elem);
@@ -652,7 +659,8 @@ static void hwmp_perr_frame_process(struct ieee80211_sub_if_data *sdata,
652 if (mpath) { 659 if (mpath) {
653 spin_lock_bh(&mpath->state_lock); 660 spin_lock_bh(&mpath->state_lock);
654 if (mpath->flags & MESH_PATH_ACTIVE && 661 if (mpath->flags & MESH_PATH_ACTIVE &&
655 memcmp(ta, mpath->next_hop->sta.addr, ETH_ALEN) == 0 && 662 memcmp(ta, next_hop_deref_protected(mpath)->sta.addr,
663 ETH_ALEN) == 0 &&
656 (!(mpath->flags & MESH_PATH_SN_VALID) || 664 (!(mpath->flags & MESH_PATH_SN_VALID) ||
657 SN_GT(target_sn, mpath->sn))) { 665 SN_GT(target_sn, mpath->sn))) {
658 mpath->flags &= ~MESH_PATH_ACTIVE; 666 mpath->flags &= ~MESH_PATH_ACTIVE;
@@ -914,6 +922,7 @@ int mesh_nexthop_lookup(struct sk_buff *skb,
914{ 922{
915 struct sk_buff *skb_to_free = NULL; 923 struct sk_buff *skb_to_free = NULL;
916 struct mesh_path *mpath; 924 struct mesh_path *mpath;
925 struct sta_info *next_hop;
917 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 926 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
918 u8 *target_addr = hdr->addr3; 927 u8 *target_addr = hdr->addr3;
919 int err = 0; 928 int err = 0;
@@ -941,7 +950,11 @@ int mesh_nexthop_lookup(struct sk_buff *skb,
941 mesh_queue_preq(mpath, 950 mesh_queue_preq(mpath,
942 PREQ_Q_F_START | PREQ_Q_F_REFRESH); 951 PREQ_Q_F_START | PREQ_Q_F_REFRESH);
943 } 952 }
944 memcpy(hdr->addr1, mpath->next_hop->sta.addr, ETH_ALEN); 953 next_hop = rcu_dereference(mpath->next_hop);
954 if (next_hop)
955 memcpy(hdr->addr1, next_hop->sta.addr, ETH_ALEN);
956 else
957 err = -ENOENT;
945 } else { 958 } else {
946 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 959 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
947 if (!(mpath->flags & MESH_PATH_RESOLVING)) { 960 if (!(mpath->flags & MESH_PATH_RESOLVING)) {
@@ -967,20 +980,11 @@ endlookup:
967 980
968void mesh_path_timer(unsigned long data) 981void mesh_path_timer(unsigned long data)
969{ 982{
970 struct ieee80211_sub_if_data *sdata; 983 struct mesh_path *mpath = (void *) data;
971 struct mesh_path *mpath; 984 struct ieee80211_sub_if_data *sdata = mpath->sdata;
972
973 rcu_read_lock();
974 mpath = (struct mesh_path *) data;
975 mpath = rcu_dereference(mpath);
976 if (!mpath)
977 goto endmpathtimer;
978 sdata = mpath->sdata;
979 985
980 if (sdata->local->quiescing) { 986 if (sdata->local->quiescing)
981 rcu_read_unlock();
982 return; 987 return;
983 }
984 988
985 spin_lock_bh(&mpath->state_lock); 989 spin_lock_bh(&mpath->state_lock);
986 if (mpath->flags & MESH_PATH_RESOLVED || 990 if (mpath->flags & MESH_PATH_RESOLVED ||
@@ -997,8 +1001,6 @@ void mesh_path_timer(unsigned long data)
997 } 1001 }
998 1002
999 spin_unlock_bh(&mpath->state_lock); 1003 spin_unlock_bh(&mpath->state_lock);
1000endmpathtimer:
1001 rcu_read_unlock();
1002} 1004}
1003 1005
1004void 1006void
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c
index 35c715adaae2..83ce48e31913 100644
--- a/net/mac80211/mesh_pathtbl.c
+++ b/net/mac80211/mesh_pathtbl.c
@@ -40,6 +40,50 @@ static struct mesh_table *mesh_paths;
40static struct mesh_table *mpp_paths; /* Store paths for MPP&MAP */ 40static struct mesh_table *mpp_paths; /* Store paths for MPP&MAP */
41 41
42int mesh_paths_generation; 42int mesh_paths_generation;
43
44/* This lock will have the grow table function as writer and add / delete nodes
45 * as readers. When reading the table (i.e. doing lookups) we are well protected
46 * by RCU
47 */
48static DEFINE_RWLOCK(pathtbl_resize_lock);
49
50
51static struct mesh_table *mesh_table_alloc(int size_order)
52{
53 int i;
54 struct mesh_table *newtbl;
55
56 newtbl = kmalloc(sizeof(struct mesh_table), GFP_KERNEL);
57 if (!newtbl)
58 return NULL;
59
60 newtbl->hash_buckets = kzalloc(sizeof(struct hlist_head) *
61 (1 << size_order), GFP_KERNEL);
62
63 if (!newtbl->hash_buckets) {
64 kfree(newtbl);
65 return NULL;
66 }
67
68 newtbl->hashwlock = kmalloc(sizeof(spinlock_t) *
69 (1 << size_order), GFP_KERNEL);
70 if (!newtbl->hashwlock) {
71 kfree(newtbl->hash_buckets);
72 kfree(newtbl);
73 return NULL;
74 }
75
76 newtbl->size_order = size_order;
77 newtbl->hash_mask = (1 << size_order) - 1;
78 atomic_set(&newtbl->entries, 0);
79 get_random_bytes(&newtbl->hash_rnd,
80 sizeof(newtbl->hash_rnd));
81 for (i = 0; i <= newtbl->hash_mask; i++)
82 spin_lock_init(&newtbl->hashwlock[i]);
83
84 return newtbl;
85}
86
43static void __mesh_table_free(struct mesh_table *tbl) 87static void __mesh_table_free(struct mesh_table *tbl)
44{ 88{
45 kfree(tbl->hash_buckets); 89 kfree(tbl->hash_buckets);
@@ -47,7 +91,7 @@ static void __mesh_table_free(struct mesh_table *tbl)
47 kfree(tbl); 91 kfree(tbl);
48} 92}
49 93
50void mesh_table_free(struct mesh_table *tbl, bool free_leafs) 94static void mesh_table_free(struct mesh_table *tbl, bool free_leafs)
51{ 95{
52 struct hlist_head *mesh_hash; 96 struct hlist_head *mesh_hash;
53 struct hlist_node *p, *q; 97 struct hlist_node *p, *q;
@@ -55,18 +99,18 @@ void mesh_table_free(struct mesh_table *tbl, bool free_leafs)
55 99
56 mesh_hash = tbl->hash_buckets; 100 mesh_hash = tbl->hash_buckets;
57 for (i = 0; i <= tbl->hash_mask; i++) { 101 for (i = 0; i <= tbl->hash_mask; i++) {
58 spin_lock(&tbl->hashwlock[i]); 102 spin_lock_bh(&tbl->hashwlock[i]);
59 hlist_for_each_safe(p, q, &mesh_hash[i]) { 103 hlist_for_each_safe(p, q, &mesh_hash[i]) {
60 tbl->free_node(p, free_leafs); 104 tbl->free_node(p, free_leafs);
61 atomic_dec(&tbl->entries); 105 atomic_dec(&tbl->entries);
62 } 106 }
63 spin_unlock(&tbl->hashwlock[i]); 107 spin_unlock_bh(&tbl->hashwlock[i]);
64 } 108 }
65 __mesh_table_free(tbl); 109 __mesh_table_free(tbl);
66} 110}
67 111
68static int mesh_table_grow(struct mesh_table *oldtbl, 112static int mesh_table_grow(struct mesh_table *oldtbl,
69 struct mesh_table *newtbl) 113 struct mesh_table *newtbl)
70{ 114{
71 struct hlist_head *oldhash; 115 struct hlist_head *oldhash;
72 struct hlist_node *p, *q; 116 struct hlist_node *p, *q;
@@ -76,7 +120,6 @@ static int mesh_table_grow(struct mesh_table *oldtbl,
76 < oldtbl->mean_chain_len * (oldtbl->hash_mask + 1)) 120 < oldtbl->mean_chain_len * (oldtbl->hash_mask + 1))
77 return -EAGAIN; 121 return -EAGAIN;
78 122
79
80 newtbl->free_node = oldtbl->free_node; 123 newtbl->free_node = oldtbl->free_node;
81 newtbl->mean_chain_len = oldtbl->mean_chain_len; 124 newtbl->mean_chain_len = oldtbl->mean_chain_len;
82 newtbl->copy_node = oldtbl->copy_node; 125 newtbl->copy_node = oldtbl->copy_node;
@@ -98,12 +141,14 @@ errcopy:
98 return -ENOMEM; 141 return -ENOMEM;
99} 142}
100 143
144static u32 mesh_table_hash(u8 *addr, struct ieee80211_sub_if_data *sdata,
145 struct mesh_table *tbl)
146{
147 /* Use last four bytes of hw addr and interface index as hash index */
148 return jhash_2words(*(u32 *)(addr+2), sdata->dev->ifindex, tbl->hash_rnd)
149 & tbl->hash_mask;
150}
101 151
102/* This lock will have the grow table function as writer and add / delete nodes
103 * as readers. When reading the table (i.e. doing lookups) we are well protected
104 * by RCU
105 */
106static DEFINE_RWLOCK(pathtbl_resize_lock);
107 152
108/** 153/**
109 * 154 *
@@ -275,7 +320,7 @@ int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata)
275 if (!new_node) 320 if (!new_node)
276 goto err_node_alloc; 321 goto err_node_alloc;
277 322
278 read_lock(&pathtbl_resize_lock); 323 read_lock_bh(&pathtbl_resize_lock);
279 memcpy(new_mpath->dst, dst, ETH_ALEN); 324 memcpy(new_mpath->dst, dst, ETH_ALEN);
280 new_mpath->sdata = sdata; 325 new_mpath->sdata = sdata;
281 new_mpath->flags = 0; 326 new_mpath->flags = 0;
@@ -290,7 +335,7 @@ int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata)
290 hash_idx = mesh_table_hash(dst, sdata, mesh_paths); 335 hash_idx = mesh_table_hash(dst, sdata, mesh_paths);
291 bucket = &mesh_paths->hash_buckets[hash_idx]; 336 bucket = &mesh_paths->hash_buckets[hash_idx];
292 337
293 spin_lock(&mesh_paths->hashwlock[hash_idx]); 338 spin_lock_bh(&mesh_paths->hashwlock[hash_idx]);
294 339
295 err = -EEXIST; 340 err = -EEXIST;
296 hlist_for_each_entry(node, n, bucket, list) { 341 hlist_for_each_entry(node, n, bucket, list) {
@@ -306,8 +351,8 @@ int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata)
306 351
307 mesh_paths_generation++; 352 mesh_paths_generation++;
308 353
309 spin_unlock(&mesh_paths->hashwlock[hash_idx]); 354 spin_unlock_bh(&mesh_paths->hashwlock[hash_idx]);
310 read_unlock(&pathtbl_resize_lock); 355 read_unlock_bh(&pathtbl_resize_lock);
311 if (grow) { 356 if (grow) {
312 set_bit(MESH_WORK_GROW_MPATH_TABLE, &ifmsh->wrkq_flags); 357 set_bit(MESH_WORK_GROW_MPATH_TABLE, &ifmsh->wrkq_flags);
313 ieee80211_queue_work(&local->hw, &sdata->work); 358 ieee80211_queue_work(&local->hw, &sdata->work);
@@ -315,8 +360,8 @@ int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata)
315 return 0; 360 return 0;
316 361
317err_exists: 362err_exists:
318 spin_unlock(&mesh_paths->hashwlock[hash_idx]); 363 spin_unlock_bh(&mesh_paths->hashwlock[hash_idx]);
319 read_unlock(&pathtbl_resize_lock); 364 read_unlock_bh(&pathtbl_resize_lock);
320 kfree(new_node); 365 kfree(new_node);
321err_node_alloc: 366err_node_alloc:
322 kfree(new_mpath); 367 kfree(new_mpath);
@@ -329,18 +374,21 @@ void mesh_mpath_table_grow(void)
329{ 374{
330 struct mesh_table *oldtbl, *newtbl; 375 struct mesh_table *oldtbl, *newtbl;
331 376
332 newtbl = mesh_table_alloc(mesh_paths->size_order + 1); 377 rcu_read_lock();
378 newtbl = mesh_table_alloc(rcu_dereference(mesh_paths)->size_order + 1);
333 if (!newtbl) 379 if (!newtbl)
334 return; 380 return;
335 write_lock(&pathtbl_resize_lock); 381 write_lock_bh(&pathtbl_resize_lock);
336 oldtbl = mesh_paths; 382 oldtbl = mesh_paths;
337 if (mesh_table_grow(mesh_paths, newtbl) < 0) { 383 if (mesh_table_grow(mesh_paths, newtbl) < 0) {
384 rcu_read_unlock();
338 __mesh_table_free(newtbl); 385 __mesh_table_free(newtbl);
339 write_unlock(&pathtbl_resize_lock); 386 write_unlock_bh(&pathtbl_resize_lock);
340 return; 387 return;
341 } 388 }
389 rcu_read_unlock();
342 rcu_assign_pointer(mesh_paths, newtbl); 390 rcu_assign_pointer(mesh_paths, newtbl);
343 write_unlock(&pathtbl_resize_lock); 391 write_unlock_bh(&pathtbl_resize_lock);
344 392
345 synchronize_rcu(); 393 synchronize_rcu();
346 mesh_table_free(oldtbl, false); 394 mesh_table_free(oldtbl, false);
@@ -350,18 +398,21 @@ void mesh_mpp_table_grow(void)
350{ 398{
351 struct mesh_table *oldtbl, *newtbl; 399 struct mesh_table *oldtbl, *newtbl;
352 400
353 newtbl = mesh_table_alloc(mpp_paths->size_order + 1); 401 rcu_read_lock();
402 newtbl = mesh_table_alloc(rcu_dereference(mpp_paths)->size_order + 1);
354 if (!newtbl) 403 if (!newtbl)
355 return; 404 return;
356 write_lock(&pathtbl_resize_lock); 405 write_lock_bh(&pathtbl_resize_lock);
357 oldtbl = mpp_paths; 406 oldtbl = mpp_paths;
358 if (mesh_table_grow(mpp_paths, newtbl) < 0) { 407 if (mesh_table_grow(mpp_paths, newtbl) < 0) {
408 rcu_read_unlock();
359 __mesh_table_free(newtbl); 409 __mesh_table_free(newtbl);
360 write_unlock(&pathtbl_resize_lock); 410 write_unlock_bh(&pathtbl_resize_lock);
361 return; 411 return;
362 } 412 }
413 rcu_read_unlock();
363 rcu_assign_pointer(mpp_paths, newtbl); 414 rcu_assign_pointer(mpp_paths, newtbl);
364 write_unlock(&pathtbl_resize_lock); 415 write_unlock_bh(&pathtbl_resize_lock);
365 416
366 synchronize_rcu(); 417 synchronize_rcu();
367 mesh_table_free(oldtbl, false); 418 mesh_table_free(oldtbl, false);
@@ -395,7 +446,7 @@ int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata)
395 if (!new_node) 446 if (!new_node)
396 goto err_node_alloc; 447 goto err_node_alloc;
397 448
398 read_lock(&pathtbl_resize_lock); 449 read_lock_bh(&pathtbl_resize_lock);
399 memcpy(new_mpath->dst, dst, ETH_ALEN); 450 memcpy(new_mpath->dst, dst, ETH_ALEN);
400 memcpy(new_mpath->mpp, mpp, ETH_ALEN); 451 memcpy(new_mpath->mpp, mpp, ETH_ALEN);
401 new_mpath->sdata = sdata; 452 new_mpath->sdata = sdata;
@@ -408,7 +459,7 @@ int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata)
408 hash_idx = mesh_table_hash(dst, sdata, mpp_paths); 459 hash_idx = mesh_table_hash(dst, sdata, mpp_paths);
409 bucket = &mpp_paths->hash_buckets[hash_idx]; 460 bucket = &mpp_paths->hash_buckets[hash_idx];
410 461
411 spin_lock(&mpp_paths->hashwlock[hash_idx]); 462 spin_lock_bh(&mpp_paths->hashwlock[hash_idx]);
412 463
413 err = -EEXIST; 464 err = -EEXIST;
414 hlist_for_each_entry(node, n, bucket, list) { 465 hlist_for_each_entry(node, n, bucket, list) {
@@ -422,8 +473,8 @@ int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata)
422 mpp_paths->mean_chain_len * (mpp_paths->hash_mask + 1)) 473 mpp_paths->mean_chain_len * (mpp_paths->hash_mask + 1))
423 grow = 1; 474 grow = 1;
424 475
425 spin_unlock(&mpp_paths->hashwlock[hash_idx]); 476 spin_unlock_bh(&mpp_paths->hashwlock[hash_idx]);
426 read_unlock(&pathtbl_resize_lock); 477 read_unlock_bh(&pathtbl_resize_lock);
427 if (grow) { 478 if (grow) {
428 set_bit(MESH_WORK_GROW_MPP_TABLE, &ifmsh->wrkq_flags); 479 set_bit(MESH_WORK_GROW_MPP_TABLE, &ifmsh->wrkq_flags);
429 ieee80211_queue_work(&local->hw, &sdata->work); 480 ieee80211_queue_work(&local->hw, &sdata->work);
@@ -431,8 +482,8 @@ int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata)
431 return 0; 482 return 0;
432 483
433err_exists: 484err_exists:
434 spin_unlock(&mpp_paths->hashwlock[hash_idx]); 485 spin_unlock_bh(&mpp_paths->hashwlock[hash_idx]);
435 read_unlock(&pathtbl_resize_lock); 486 read_unlock_bh(&pathtbl_resize_lock);
436 kfree(new_node); 487 kfree(new_node);
437err_node_alloc: 488err_node_alloc:
438 kfree(new_mpath); 489 kfree(new_mpath);
@@ -545,11 +596,11 @@ int mesh_path_del(u8 *addr, struct ieee80211_sub_if_data *sdata)
545 int hash_idx; 596 int hash_idx;
546 int err = 0; 597 int err = 0;
547 598
548 read_lock(&pathtbl_resize_lock); 599 read_lock_bh(&pathtbl_resize_lock);
549 hash_idx = mesh_table_hash(addr, sdata, mesh_paths); 600 hash_idx = mesh_table_hash(addr, sdata, mesh_paths);
550 bucket = &mesh_paths->hash_buckets[hash_idx]; 601 bucket = &mesh_paths->hash_buckets[hash_idx];
551 602
552 spin_lock(&mesh_paths->hashwlock[hash_idx]); 603 spin_lock_bh(&mesh_paths->hashwlock[hash_idx]);
553 hlist_for_each_entry(node, n, bucket, list) { 604 hlist_for_each_entry(node, n, bucket, list) {
554 mpath = node->mpath; 605 mpath = node->mpath;
555 if (mpath->sdata == sdata && 606 if (mpath->sdata == sdata &&
@@ -567,8 +618,8 @@ int mesh_path_del(u8 *addr, struct ieee80211_sub_if_data *sdata)
567 err = -ENXIO; 618 err = -ENXIO;
568enddel: 619enddel:
569 mesh_paths_generation++; 620 mesh_paths_generation++;
570 spin_unlock(&mesh_paths->hashwlock[hash_idx]); 621 spin_unlock_bh(&mesh_paths->hashwlock[hash_idx]);
571 read_unlock(&pathtbl_resize_lock); 622 read_unlock_bh(&pathtbl_resize_lock);
572 return err; 623 return err;
573} 624}
574 625
@@ -720,7 +771,7 @@ void mesh_path_expire(struct ieee80211_sub_if_data *sdata)
720 struct hlist_node *p; 771 struct hlist_node *p;
721 int i; 772 int i;
722 773
723 read_lock(&pathtbl_resize_lock); 774 read_lock_bh(&pathtbl_resize_lock);
724 for_each_mesh_entry(mesh_paths, p, node, i) { 775 for_each_mesh_entry(mesh_paths, p, node, i) {
725 if (node->mpath->sdata != sdata) 776 if (node->mpath->sdata != sdata)
726 continue; 777 continue;
@@ -735,7 +786,7 @@ void mesh_path_expire(struct ieee80211_sub_if_data *sdata)
735 } else 786 } else
736 spin_unlock_bh(&mpath->state_lock); 787 spin_unlock_bh(&mpath->state_lock);
737 } 788 }
738 read_unlock(&pathtbl_resize_lock); 789 read_unlock_bh(&pathtbl_resize_lock);
739} 790}
740 791
741void mesh_pathtbl_unregister(void) 792void mesh_pathtbl_unregister(void)
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index 84e5b056af02..f4adc0917888 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -43,7 +43,7 @@
43#define dot11MeshMaxPeerLinks(s) (s->u.mesh.mshcfg.dot11MeshMaxPeerLinks) 43#define dot11MeshMaxPeerLinks(s) (s->u.mesh.mshcfg.dot11MeshMaxPeerLinks)
44 44
45enum plink_frame_type { 45enum plink_frame_type {
46 PLINK_OPEN = 0, 46 PLINK_OPEN = 1,
47 PLINK_CONFIRM, 47 PLINK_CONFIRM,
48 PLINK_CLOSE 48 PLINK_CLOSE
49}; 49};
@@ -83,7 +83,7 @@ void mesh_plink_dec_estab_count(struct ieee80211_sub_if_data *sdata)
83 */ 83 */
84static inline void mesh_plink_fsm_restart(struct sta_info *sta) 84static inline void mesh_plink_fsm_restart(struct sta_info *sta)
85{ 85{
86 sta->plink_state = PLINK_LISTEN; 86 sta->plink_state = NL80211_PLINK_LISTEN;
87 sta->llid = sta->plid = sta->reason = 0; 87 sta->llid = sta->plid = sta->reason = 0;
88 sta->plink_retries = 0; 88 sta->plink_retries = 0;
89} 89}
@@ -126,11 +126,11 @@ static bool __mesh_plink_deactivate(struct sta_info *sta)
126 struct ieee80211_sub_if_data *sdata = sta->sdata; 126 struct ieee80211_sub_if_data *sdata = sta->sdata;
127 bool deactivated = false; 127 bool deactivated = false;
128 128
129 if (sta->plink_state == PLINK_ESTAB) { 129 if (sta->plink_state == NL80211_PLINK_ESTAB) {
130 mesh_plink_dec_estab_count(sdata); 130 mesh_plink_dec_estab_count(sdata);
131 deactivated = true; 131 deactivated = true;
132 } 132 }
133 sta->plink_state = PLINK_BLOCKED; 133 sta->plink_state = NL80211_PLINK_BLOCKED;
134 mesh_path_flush_by_nexthop(sta); 134 mesh_path_flush_by_nexthop(sta);
135 135
136 return deactivated; 136 return deactivated;
@@ -181,8 +181,8 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
181 IEEE80211_STYPE_ACTION); 181 IEEE80211_STYPE_ACTION);
182 memcpy(mgmt->da, da, ETH_ALEN); 182 memcpy(mgmt->da, da, ETH_ALEN);
183 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); 183 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
184 /* BSSID is left zeroed, wildcard value */ 184 memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
185 mgmt->u.action.category = WLAN_CATEGORY_MESH_PLINK; 185 mgmt->u.action.category = WLAN_CATEGORY_MESH_ACTION;
186 mgmt->u.action.u.plink_action.action_code = action; 186 mgmt->u.action.u.plink_action.action_code = action;
187 187
188 if (action == PLINK_CLOSE) 188 if (action == PLINK_CLOSE)
@@ -251,7 +251,7 @@ void mesh_neighbour_update(u8 *hw_addr, u32 rates,
251 rcu_read_unlock(); 251 rcu_read_unlock();
252 /* Userspace handles peer allocation when security is enabled 252 /* Userspace handles peer allocation when security is enabled
253 * */ 253 * */
254 if (sdata->u.mesh.is_secure) 254 if (sdata->u.mesh.security & IEEE80211_MESH_SEC_AUTHED)
255 cfg80211_notify_new_peer_candidate(sdata->dev, hw_addr, 255 cfg80211_notify_new_peer_candidate(sdata->dev, hw_addr,
256 elems->ie_start, elems->total_len, 256 elems->ie_start, elems->total_len,
257 GFP_KERNEL); 257 GFP_KERNEL);
@@ -268,7 +268,7 @@ void mesh_neighbour_update(u8 *hw_addr, u32 rates,
268 sta->last_rx = jiffies; 268 sta->last_rx = jiffies;
269 sta->sta.supp_rates[local->hw.conf.channel->band] = rates; 269 sta->sta.supp_rates[local->hw.conf.channel->band] = rates;
270 if (mesh_peer_accepts_plinks(elems) && 270 if (mesh_peer_accepts_plinks(elems) &&
271 sta->plink_state == PLINK_LISTEN && 271 sta->plink_state == NL80211_PLINK_LISTEN &&
272 sdata->u.mesh.accepting_plinks && 272 sdata->u.mesh.accepting_plinks &&
273 sdata->u.mesh.mshcfg.auto_open_plinks) 273 sdata->u.mesh.mshcfg.auto_open_plinks)
274 mesh_plink_open(sta); 274 mesh_plink_open(sta);
@@ -308,8 +308,8 @@ static void mesh_plink_timer(unsigned long data)
308 sdata = sta->sdata; 308 sdata = sta->sdata;
309 309
310 switch (sta->plink_state) { 310 switch (sta->plink_state) {
311 case PLINK_OPN_RCVD: 311 case NL80211_PLINK_OPN_RCVD:
312 case PLINK_OPN_SNT: 312 case NL80211_PLINK_OPN_SNT:
313 /* retry timer */ 313 /* retry timer */
314 if (sta->plink_retries < dot11MeshMaxRetries(sdata)) { 314 if (sta->plink_retries < dot11MeshMaxRetries(sdata)) {
315 u32 rand; 315 u32 rand;
@@ -328,17 +328,17 @@ static void mesh_plink_timer(unsigned long data)
328 } 328 }
329 reason = cpu_to_le16(MESH_MAX_RETRIES); 329 reason = cpu_to_le16(MESH_MAX_RETRIES);
330 /* fall through on else */ 330 /* fall through on else */
331 case PLINK_CNF_RCVD: 331 case NL80211_PLINK_CNF_RCVD:
332 /* confirm timer */ 332 /* confirm timer */
333 if (!reason) 333 if (!reason)
334 reason = cpu_to_le16(MESH_CONFIRM_TIMEOUT); 334 reason = cpu_to_le16(MESH_CONFIRM_TIMEOUT);
335 sta->plink_state = PLINK_HOLDING; 335 sta->plink_state = NL80211_PLINK_HOLDING;
336 mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata)); 336 mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata));
337 spin_unlock_bh(&sta->lock); 337 spin_unlock_bh(&sta->lock);
338 mesh_plink_frame_tx(sdata, PLINK_CLOSE, sta->sta.addr, llid, plid, 338 mesh_plink_frame_tx(sdata, PLINK_CLOSE, sta->sta.addr, llid, plid,
339 reason); 339 reason);
340 break; 340 break;
341 case PLINK_HOLDING: 341 case NL80211_PLINK_HOLDING:
342 /* holding timer */ 342 /* holding timer */
343 del_timer(&sta->plink_timer); 343 del_timer(&sta->plink_timer);
344 mesh_plink_fsm_restart(sta); 344 mesh_plink_fsm_restart(sta);
@@ -386,11 +386,11 @@ int mesh_plink_open(struct sta_info *sta)
386 spin_lock_bh(&sta->lock); 386 spin_lock_bh(&sta->lock);
387 get_random_bytes(&llid, 2); 387 get_random_bytes(&llid, 2);
388 sta->llid = llid; 388 sta->llid = llid;
389 if (sta->plink_state != PLINK_LISTEN) { 389 if (sta->plink_state != NL80211_PLINK_LISTEN) {
390 spin_unlock_bh(&sta->lock); 390 spin_unlock_bh(&sta->lock);
391 return -EBUSY; 391 return -EBUSY;
392 } 392 }
393 sta->plink_state = PLINK_OPN_SNT; 393 sta->plink_state = NL80211_PLINK_OPN_SNT;
394 mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata)); 394 mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata));
395 spin_unlock_bh(&sta->lock); 395 spin_unlock_bh(&sta->lock);
396 mpl_dbg("Mesh plink: starting establishment with %pM\n", 396 mpl_dbg("Mesh plink: starting establishment with %pM\n",
@@ -407,7 +407,7 @@ void mesh_plink_block(struct sta_info *sta)
407 407
408 spin_lock_bh(&sta->lock); 408 spin_lock_bh(&sta->lock);
409 deactivated = __mesh_plink_deactivate(sta); 409 deactivated = __mesh_plink_deactivate(sta);
410 sta->plink_state = PLINK_BLOCKED; 410 sta->plink_state = NL80211_PLINK_BLOCKED;
411 spin_unlock_bh(&sta->lock); 411 spin_unlock_bh(&sta->lock);
412 412
413 if (deactivated) 413 if (deactivated)
@@ -430,13 +430,13 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
430 __le16 plid, llid, reason; 430 __le16 plid, llid, reason;
431#ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG 431#ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG
432 static const char *mplstates[] = { 432 static const char *mplstates[] = {
433 [PLINK_LISTEN] = "LISTEN", 433 [NL80211_PLINK_LISTEN] = "LISTEN",
434 [PLINK_OPN_SNT] = "OPN-SNT", 434 [NL80211_PLINK_OPN_SNT] = "OPN-SNT",
435 [PLINK_OPN_RCVD] = "OPN-RCVD", 435 [NL80211_PLINK_OPN_RCVD] = "OPN-RCVD",
436 [PLINK_CNF_RCVD] = "CNF_RCVD", 436 [NL80211_PLINK_CNF_RCVD] = "CNF_RCVD",
437 [PLINK_ESTAB] = "ESTAB", 437 [NL80211_PLINK_ESTAB] = "ESTAB",
438 [PLINK_HOLDING] = "HOLDING", 438 [NL80211_PLINK_HOLDING] = "HOLDING",
439 [PLINK_BLOCKED] = "BLOCKED" 439 [NL80211_PLINK_BLOCKED] = "BLOCKED"
440 }; 440 };
441#endif 441#endif
442 442
@@ -460,7 +460,8 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
460 mpl_dbg("Mesh plink: missing necessary peer link ie\n"); 460 mpl_dbg("Mesh plink: missing necessary peer link ie\n");
461 return; 461 return;
462 } 462 }
463 if (elems.rsn_len && !sdata->u.mesh.is_secure) { 463 if (elems.rsn_len &&
464 sdata->u.mesh.security == IEEE80211_MESH_SEC_NONE) {
464 mpl_dbg("Mesh plink: can't establish link with secure peer\n"); 465 mpl_dbg("Mesh plink: can't establish link with secure peer\n");
465 return; 466 return;
466 } 467 }
@@ -501,7 +502,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
501 return; 502 return;
502 } 503 }
503 504
504 if (sta && sta->plink_state == PLINK_BLOCKED) { 505 if (sta && sta->plink_state == NL80211_PLINK_BLOCKED) {
505 rcu_read_unlock(); 506 rcu_read_unlock();
506 return; 507 return;
507 } 508 }
@@ -571,7 +572,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
571 event = CNF_ACPT; 572 event = CNF_ACPT;
572 break; 573 break;
573 case PLINK_CLOSE: 574 case PLINK_CLOSE:
574 if (sta->plink_state == PLINK_ESTAB) 575 if (sta->plink_state == NL80211_PLINK_ESTAB)
575 /* Do not check for llid or plid. This does not 576 /* Do not check for llid or plid. This does not
576 * follow the standard but since multiple plinks 577 * follow the standard but since multiple plinks
577 * per sta are not supported, it is necessary in 578 * per sta are not supported, it is necessary in
@@ -606,14 +607,14 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
606 reason = 0; 607 reason = 0;
607 switch (sta->plink_state) { 608 switch (sta->plink_state) {
608 /* spin_unlock as soon as state is updated at each case */ 609 /* spin_unlock as soon as state is updated at each case */
609 case PLINK_LISTEN: 610 case NL80211_PLINK_LISTEN:
610 switch (event) { 611 switch (event) {
611 case CLS_ACPT: 612 case CLS_ACPT:
612 mesh_plink_fsm_restart(sta); 613 mesh_plink_fsm_restart(sta);
613 spin_unlock_bh(&sta->lock); 614 spin_unlock_bh(&sta->lock);
614 break; 615 break;
615 case OPN_ACPT: 616 case OPN_ACPT:
616 sta->plink_state = PLINK_OPN_RCVD; 617 sta->plink_state = NL80211_PLINK_OPN_RCVD;
617 sta->plid = plid; 618 sta->plid = plid;
618 get_random_bytes(&llid, 2); 619 get_random_bytes(&llid, 2);
619 sta->llid = llid; 620 sta->llid = llid;
@@ -630,7 +631,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
630 } 631 }
631 break; 632 break;
632 633
633 case PLINK_OPN_SNT: 634 case NL80211_PLINK_OPN_SNT:
634 switch (event) { 635 switch (event) {
635 case OPN_RJCT: 636 case OPN_RJCT:
636 case CNF_RJCT: 637 case CNF_RJCT:
@@ -639,7 +640,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
639 if (!reason) 640 if (!reason)
640 reason = cpu_to_le16(MESH_CLOSE_RCVD); 641 reason = cpu_to_le16(MESH_CLOSE_RCVD);
641 sta->reason = reason; 642 sta->reason = reason;
642 sta->plink_state = PLINK_HOLDING; 643 sta->plink_state = NL80211_PLINK_HOLDING;
643 if (!mod_plink_timer(sta, 644 if (!mod_plink_timer(sta,
644 dot11MeshHoldingTimeout(sdata))) 645 dot11MeshHoldingTimeout(sdata)))
645 sta->ignore_plink_timer = true; 646 sta->ignore_plink_timer = true;
@@ -651,7 +652,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
651 break; 652 break;
652 case OPN_ACPT: 653 case OPN_ACPT:
653 /* retry timer is left untouched */ 654 /* retry timer is left untouched */
654 sta->plink_state = PLINK_OPN_RCVD; 655 sta->plink_state = NL80211_PLINK_OPN_RCVD;
655 sta->plid = plid; 656 sta->plid = plid;
656 llid = sta->llid; 657 llid = sta->llid;
657 spin_unlock_bh(&sta->lock); 658 spin_unlock_bh(&sta->lock);
@@ -659,7 +660,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
659 plid, 0); 660 plid, 0);
660 break; 661 break;
661 case CNF_ACPT: 662 case CNF_ACPT:
662 sta->plink_state = PLINK_CNF_RCVD; 663 sta->plink_state = NL80211_PLINK_CNF_RCVD;
663 if (!mod_plink_timer(sta, 664 if (!mod_plink_timer(sta,
664 dot11MeshConfirmTimeout(sdata))) 665 dot11MeshConfirmTimeout(sdata)))
665 sta->ignore_plink_timer = true; 666 sta->ignore_plink_timer = true;
@@ -672,7 +673,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
672 } 673 }
673 break; 674 break;
674 675
675 case PLINK_OPN_RCVD: 676 case NL80211_PLINK_OPN_RCVD:
676 switch (event) { 677 switch (event) {
677 case OPN_RJCT: 678 case OPN_RJCT:
678 case CNF_RJCT: 679 case CNF_RJCT:
@@ -681,7 +682,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
681 if (!reason) 682 if (!reason)
682 reason = cpu_to_le16(MESH_CLOSE_RCVD); 683 reason = cpu_to_le16(MESH_CLOSE_RCVD);
683 sta->reason = reason; 684 sta->reason = reason;
684 sta->plink_state = PLINK_HOLDING; 685 sta->plink_state = NL80211_PLINK_HOLDING;
685 if (!mod_plink_timer(sta, 686 if (!mod_plink_timer(sta,
686 dot11MeshHoldingTimeout(sdata))) 687 dot11MeshHoldingTimeout(sdata)))
687 sta->ignore_plink_timer = true; 688 sta->ignore_plink_timer = true;
@@ -699,7 +700,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
699 break; 700 break;
700 case CNF_ACPT: 701 case CNF_ACPT:
701 del_timer(&sta->plink_timer); 702 del_timer(&sta->plink_timer);
702 sta->plink_state = PLINK_ESTAB; 703 sta->plink_state = NL80211_PLINK_ESTAB;
703 spin_unlock_bh(&sta->lock); 704 spin_unlock_bh(&sta->lock);
704 mesh_plink_inc_estab_count(sdata); 705 mesh_plink_inc_estab_count(sdata);
705 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON); 706 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON);
@@ -712,7 +713,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
712 } 713 }
713 break; 714 break;
714 715
715 case PLINK_CNF_RCVD: 716 case NL80211_PLINK_CNF_RCVD:
716 switch (event) { 717 switch (event) {
717 case OPN_RJCT: 718 case OPN_RJCT:
718 case CNF_RJCT: 719 case CNF_RJCT:
@@ -721,7 +722,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
721 if (!reason) 722 if (!reason)
722 reason = cpu_to_le16(MESH_CLOSE_RCVD); 723 reason = cpu_to_le16(MESH_CLOSE_RCVD);
723 sta->reason = reason; 724 sta->reason = reason;
724 sta->plink_state = PLINK_HOLDING; 725 sta->plink_state = NL80211_PLINK_HOLDING;
725 if (!mod_plink_timer(sta, 726 if (!mod_plink_timer(sta,
726 dot11MeshHoldingTimeout(sdata))) 727 dot11MeshHoldingTimeout(sdata)))
727 sta->ignore_plink_timer = true; 728 sta->ignore_plink_timer = true;
@@ -733,7 +734,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
733 break; 734 break;
734 case OPN_ACPT: 735 case OPN_ACPT:
735 del_timer(&sta->plink_timer); 736 del_timer(&sta->plink_timer);
736 sta->plink_state = PLINK_ESTAB; 737 sta->plink_state = NL80211_PLINK_ESTAB;
737 spin_unlock_bh(&sta->lock); 738 spin_unlock_bh(&sta->lock);
738 mesh_plink_inc_estab_count(sdata); 739 mesh_plink_inc_estab_count(sdata);
739 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON); 740 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON);
@@ -748,13 +749,13 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
748 } 749 }
749 break; 750 break;
750 751
751 case PLINK_ESTAB: 752 case NL80211_PLINK_ESTAB:
752 switch (event) { 753 switch (event) {
753 case CLS_ACPT: 754 case CLS_ACPT:
754 reason = cpu_to_le16(MESH_CLOSE_RCVD); 755 reason = cpu_to_le16(MESH_CLOSE_RCVD);
755 sta->reason = reason; 756 sta->reason = reason;
756 deactivated = __mesh_plink_deactivate(sta); 757 deactivated = __mesh_plink_deactivate(sta);
757 sta->plink_state = PLINK_HOLDING; 758 sta->plink_state = NL80211_PLINK_HOLDING;
758 llid = sta->llid; 759 llid = sta->llid;
759 mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata)); 760 mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata));
760 spin_unlock_bh(&sta->lock); 761 spin_unlock_bh(&sta->lock);
@@ -774,7 +775,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
774 break; 775 break;
775 } 776 }
776 break; 777 break;
777 case PLINK_HOLDING: 778 case NL80211_PLINK_HOLDING:
778 switch (event) { 779 switch (event) {
779 case CLS_ACPT: 780 case CLS_ACPT:
780 if (del_timer(&sta->plink_timer)) 781 if (del_timer(&sta->plink_timer))
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index a41f234bd486..4f6b2675e41d 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -750,6 +750,8 @@ void ieee80211_dynamic_ps_enable_work(struct work_struct *work)
750 dynamic_ps_enable_work); 750 dynamic_ps_enable_work);
751 struct ieee80211_sub_if_data *sdata = local->ps_sdata; 751 struct ieee80211_sub_if_data *sdata = local->ps_sdata;
752 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 752 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
753 unsigned long flags;
754 int q;
753 755
754 /* can only happen when PS was just disabled anyway */ 756 /* can only happen when PS was just disabled anyway */
755 if (!sdata) 757 if (!sdata)
@@ -758,6 +760,24 @@ void ieee80211_dynamic_ps_enable_work(struct work_struct *work)
758 if (local->hw.conf.flags & IEEE80211_CONF_PS) 760 if (local->hw.conf.flags & IEEE80211_CONF_PS)
759 return; 761 return;
760 762
763 /*
764 * transmission can be stopped by others which leads to
765 * dynamic_ps_timer expiry. Postpond the ps timer if it
766 * is not the actual idle state.
767 */
768 spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
769 for (q = 0; q < local->hw.queues; q++) {
770 if (local->queue_stop_reasons[q]) {
771 spin_unlock_irqrestore(&local->queue_stop_reason_lock,
772 flags);
773 mod_timer(&local->dynamic_ps_timer, jiffies +
774 msecs_to_jiffies(
775 local->hw.conf.dynamic_ps_timeout));
776 return;
777 }
778 }
779 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
780
761 if ((local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) && 781 if ((local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) &&
762 (!(ifmgd->flags & IEEE80211_STA_NULLFUNC_ACKED))) { 782 (!(ifmgd->flags & IEEE80211_STA_NULLFUNC_ACKED))) {
763 netif_tx_stop_all_queues(sdata->dev); 783 netif_tx_stop_all_queues(sdata->dev);
@@ -781,7 +801,7 @@ void ieee80211_dynamic_ps_enable_work(struct work_struct *work)
781 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); 801 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
782 } 802 }
783 803
784 netif_tx_start_all_queues(sdata->dev); 804 netif_tx_wake_all_queues(sdata->dev);
785} 805}
786 806
787void ieee80211_dynamic_ps_timer(unsigned long data) 807void ieee80211_dynamic_ps_timer(unsigned long data)
diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c
index 042461710880..730778a2c90c 100644
--- a/net/mac80211/pm.c
+++ b/net/mac80211/pm.c
@@ -6,7 +6,7 @@
6#include "driver-ops.h" 6#include "driver-ops.h"
7#include "led.h" 7#include "led.h"
8 8
9int __ieee80211_suspend(struct ieee80211_hw *hw) 9int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
10{ 10{
11 struct ieee80211_local *local = hw_to_local(hw); 11 struct ieee80211_local *local = hw_to_local(hw);
12 struct ieee80211_sub_if_data *sdata; 12 struct ieee80211_sub_if_data *sdata;
@@ -47,6 +47,16 @@ int __ieee80211_suspend(struct ieee80211_hw *hw)
47 cancel_work_sync(&local->dynamic_ps_enable_work); 47 cancel_work_sync(&local->dynamic_ps_enable_work);
48 del_timer_sync(&local->dynamic_ps_timer); 48 del_timer_sync(&local->dynamic_ps_timer);
49 49
50 local->wowlan = wowlan && local->open_count;
51 if (local->wowlan) {
52 int err = drv_suspend(local, wowlan);
53 if (err) {
54 local->quiescing = false;
55 return err;
56 }
57 goto suspend;
58 }
59
50 /* disable keys */ 60 /* disable keys */
51 list_for_each_entry(sdata, &local->interfaces, list) 61 list_for_each_entry(sdata, &local->interfaces, list)
52 ieee80211_disable_keys(sdata); 62 ieee80211_disable_keys(sdata);
@@ -104,6 +114,7 @@ int __ieee80211_suspend(struct ieee80211_hw *hw)
104 if (local->open_count) 114 if (local->open_count)
105 ieee80211_stop_device(local); 115 ieee80211_stop_device(local);
106 116
117 suspend:
107 local->suspended = true; 118 local->suspended = true;
108 /* need suspended to be visible before quiescing is false */ 119 /* need suspended to be visible before quiescing is false */
109 barrier(); 120 barrier();
diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c
index 778c604d7939..8adac67395f7 100644
--- a/net/mac80211/rc80211_minstrel.c
+++ b/net/mac80211/rc80211_minstrel.c
@@ -417,8 +417,8 @@ minstrel_rate_init(void *priv, struct ieee80211_supported_band *sband,
417 tx_time_single = mr->ack_time + mr->perfect_tx_time; 417 tx_time_single = mr->ack_time + mr->perfect_tx_time;
418 418
419 /* contention window */ 419 /* contention window */
420 tx_time_single += t_slot + min(cw, mp->cw_max); 420 tx_time_single += (t_slot * cw) >> 1;
421 cw = (cw << 1) | 1; 421 cw = min((cw << 1) | 1, mp->cw_max);
422 422
423 tx_time += tx_time_single; 423 tx_time += tx_time_single;
424 tx_time_cts += tx_time_single + mi->sp_ack_dur; 424 tx_time_cts += tx_time_single + mi->sp_ack_dur;
diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c
index c06aa3ac6b9d..333b5118be6d 100644
--- a/net/mac80211/rc80211_minstrel_ht.c
+++ b/net/mac80211/rc80211_minstrel_ht.c
@@ -464,6 +464,7 @@ minstrel_calc_retransmit(struct minstrel_priv *mp, struct minstrel_ht_sta *mi,
464 const struct mcs_group *group; 464 const struct mcs_group *group;
465 unsigned int tx_time, tx_time_rtscts, tx_time_data; 465 unsigned int tx_time, tx_time_rtscts, tx_time_data;
466 unsigned int cw = mp->cw_min; 466 unsigned int cw = mp->cw_min;
467 unsigned int ctime = 0;
467 unsigned int t_slot = 9; /* FIXME */ 468 unsigned int t_slot = 9; /* FIXME */
468 unsigned int ampdu_len = MINSTREL_TRUNC(mi->avg_ampdu_len); 469 unsigned int ampdu_len = MINSTREL_TRUNC(mi->avg_ampdu_len);
469 470
@@ -480,13 +481,27 @@ minstrel_calc_retransmit(struct minstrel_priv *mp, struct minstrel_ht_sta *mi,
480 481
481 group = &minstrel_mcs_groups[index / MCS_GROUP_RATES]; 482 group = &minstrel_mcs_groups[index / MCS_GROUP_RATES];
482 tx_time_data = group->duration[index % MCS_GROUP_RATES] * ampdu_len; 483 tx_time_data = group->duration[index % MCS_GROUP_RATES] * ampdu_len;
483 tx_time = 2 * (t_slot + mi->overhead + tx_time_data); 484
484 tx_time_rtscts = 2 * (t_slot + mi->overhead_rtscts + tx_time_data); 485 /* Contention time for first 2 tries */
486 ctime = (t_slot * cw) >> 1;
487 cw = min((cw << 1) | 1, mp->cw_max);
488 ctime += (t_slot * cw) >> 1;
489 cw = min((cw << 1) | 1, mp->cw_max);
490
491 /* Total TX time for data and Contention after first 2 tries */
492 tx_time = ctime + 2 * (mi->overhead + tx_time_data);
493 tx_time_rtscts = ctime + 2 * (mi->overhead_rtscts + tx_time_data);
494
495 /* See how many more tries we can fit inside segment size */
485 do { 496 do {
486 cw = (cw << 1) | 1; 497 /* Contention time for this try */
487 cw = min(cw, mp->cw_max); 498 ctime = (t_slot * cw) >> 1;
488 tx_time += cw + t_slot + mi->overhead; 499 cw = min((cw << 1) | 1, mp->cw_max);
489 tx_time_rtscts += cw + t_slot + mi->overhead_rtscts; 500
501 /* Total TX time after this try */
502 tx_time += ctime + mi->overhead + tx_time_data;
503 tx_time_rtscts += ctime + mi->overhead_rtscts + tx_time_data;
504
490 if (tx_time_rtscts < mp->segment_size) 505 if (tx_time_rtscts < mp->segment_size)
491 mr->retry_count_rtscts++; 506 mr->retry_count_rtscts++;
492 } while ((tx_time < mp->segment_size) && 507 } while ((tx_time < mp->segment_size) &&
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 13a6697651ad..7fa8c6be7bf0 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -404,11 +404,13 @@ ieee80211_rx_h_passive_scan(struct ieee80211_rx_data *rx)
404 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); 404 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
405 struct sk_buff *skb = rx->skb; 405 struct sk_buff *skb = rx->skb;
406 406
407 if (likely(!(status->rx_flags & IEEE80211_RX_IN_SCAN))) 407 if (likely(!(status->rx_flags & IEEE80211_RX_IN_SCAN) &&
408 !local->sched_scanning))
408 return RX_CONTINUE; 409 return RX_CONTINUE;
409 410
410 if (test_bit(SCAN_HW_SCANNING, &local->scanning) || 411 if (test_bit(SCAN_HW_SCANNING, &local->scanning) ||
411 test_bit(SCAN_SW_SCANNING, &local->scanning)) 412 test_bit(SCAN_SW_SCANNING, &local->scanning) ||
413 local->sched_scanning)
412 return ieee80211_scan_rx(rx->sdata, skb); 414 return ieee80211_scan_rx(rx->sdata, skb);
413 415
414 /* scanning finished during invoking of handlers */ 416 /* scanning finished during invoking of handlers */
@@ -488,15 +490,18 @@ ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx)
488 * establisment frame, beacon or probe, drop the frame. 490 * establisment frame, beacon or probe, drop the frame.
489 */ 491 */
490 492
491 if (!rx->sta || sta_plink_state(rx->sta) != PLINK_ESTAB) { 493 if (!rx->sta || sta_plink_state(rx->sta) != NL80211_PLINK_ESTAB) {
492 struct ieee80211_mgmt *mgmt; 494 struct ieee80211_mgmt *mgmt;
493 495
494 if (!ieee80211_is_mgmt(hdr->frame_control)) 496 if (!ieee80211_is_mgmt(hdr->frame_control))
495 return RX_DROP_MONITOR; 497 return RX_DROP_MONITOR;
496 498
497 if (ieee80211_is_action(hdr->frame_control)) { 499 if (ieee80211_is_action(hdr->frame_control)) {
500 u8 category;
498 mgmt = (struct ieee80211_mgmt *)hdr; 501 mgmt = (struct ieee80211_mgmt *)hdr;
499 if (mgmt->u.action.category != WLAN_CATEGORY_MESH_PLINK) 502 category = mgmt->u.action.category;
503 if (category != WLAN_CATEGORY_MESH_ACTION &&
504 category != WLAN_CATEGORY_SELF_PROTECTED)
500 return RX_DROP_MONITOR; 505 return RX_DROP_MONITOR;
501 return RX_CONTINUE; 506 return RX_CONTINUE;
502 } 507 }
@@ -1778,7 +1783,7 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx)
1778 1783
1779 ieee80211_amsdu_to_8023s(skb, &frame_list, dev->dev_addr, 1784 ieee80211_amsdu_to_8023s(skb, &frame_list, dev->dev_addr,
1780 rx->sdata->vif.type, 1785 rx->sdata->vif.type,
1781 rx->local->hw.extra_tx_headroom); 1786 rx->local->hw.extra_tx_headroom, true);
1782 1787
1783 while (!skb_queue_empty(&frame_list)) { 1788 while (!skb_queue_empty(&frame_list)) {
1784 rx->skb = __skb_dequeue(&frame_list); 1789 rx->skb = __skb_dequeue(&frame_list);
@@ -2205,7 +2210,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
2205 goto handled; 2210 goto handled;
2206 } 2211 }
2207 break; 2212 break;
2208 case WLAN_CATEGORY_MESH_PLINK: 2213 case WLAN_CATEGORY_MESH_ACTION:
2209 if (!ieee80211_vif_is_mesh(&sdata->vif)) 2214 if (!ieee80211_vif_is_mesh(&sdata->vif))
2210 break; 2215 break;
2211 goto queue; 2216 goto queue;
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 489b6ad200d4..d20046b5d8f4 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -15,6 +15,7 @@
15#include <linux/if_arp.h> 15#include <linux/if_arp.h>
16#include <linux/rtnetlink.h> 16#include <linux/rtnetlink.h>
17#include <linux/pm_qos_params.h> 17#include <linux/pm_qos_params.h>
18#include <linux/slab.h>
18#include <net/sch_generic.h> 19#include <net/sch_generic.h>
19#include <linux/slab.h> 20#include <linux/slab.h>
20#include <net/mac80211.h> 21#include <net/mac80211.h>
@@ -170,7 +171,7 @@ ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb)
170 return RX_CONTINUE; 171 return RX_CONTINUE;
171 172
172 if (skb->len < 24) 173 if (skb->len < 24)
173 return RX_DROP_MONITOR; 174 return RX_CONTINUE;
174 175
175 presp = ieee80211_is_probe_resp(fc); 176 presp = ieee80211_is_probe_resp(fc);
176 if (presp) { 177 if (presp) {
@@ -850,3 +851,122 @@ void ieee80211_scan_cancel(struct ieee80211_local *local)
850 } 851 }
851 mutex_unlock(&local->mtx); 852 mutex_unlock(&local->mtx);
852} 853}
854
855int ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata,
856 struct cfg80211_sched_scan_request *req)
857{
858 struct ieee80211_local *local = sdata->local;
859 int ret, i;
860
861 mutex_lock(&sdata->local->mtx);
862
863 if (local->sched_scanning) {
864 ret = -EBUSY;
865 goto out;
866 }
867
868 if (!local->ops->sched_scan_start) {
869 ret = -ENOTSUPP;
870 goto out;
871 }
872
873 for (i = 0; i < IEEE80211_NUM_BANDS; i++) {
874 local->sched_scan_ies.ie[i] = kzalloc(2 +
875 IEEE80211_MAX_SSID_LEN +
876 local->scan_ies_len,
877 GFP_KERNEL);
878 if (!local->sched_scan_ies.ie[i]) {
879 ret = -ENOMEM;
880 goto out_free;
881 }
882
883 local->sched_scan_ies.len[i] =
884 ieee80211_build_preq_ies(local,
885 local->sched_scan_ies.ie[i],
886 req->ie, req->ie_len, i,
887 (u32) -1, 0);
888 }
889
890 ret = drv_sched_scan_start(local, sdata, req,
891 &local->sched_scan_ies);
892 if (ret == 0) {
893 local->sched_scanning = true;
894 goto out;
895 }
896
897out_free:
898 while (i > 0)
899 kfree(local->sched_scan_ies.ie[--i]);
900out:
901 mutex_unlock(&sdata->local->mtx);
902 return ret;
903}
904
905int ieee80211_request_sched_scan_stop(struct ieee80211_sub_if_data *sdata)
906{
907 struct ieee80211_local *local = sdata->local;
908 int ret = 0, i;
909
910 mutex_lock(&sdata->local->mtx);
911
912 if (!local->ops->sched_scan_stop) {
913 ret = -ENOTSUPP;
914 goto out;
915 }
916
917 if (local->sched_scanning) {
918 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
919 kfree(local->sched_scan_ies.ie[i]);
920
921 drv_sched_scan_stop(local, sdata);
922 local->sched_scanning = false;
923 }
924out:
925 mutex_unlock(&sdata->local->mtx);
926
927 return ret;
928}
929
930void ieee80211_sched_scan_results(struct ieee80211_hw *hw)
931{
932 struct ieee80211_local *local = hw_to_local(hw);
933
934 trace_api_sched_scan_results(local);
935
936 cfg80211_sched_scan_results(hw->wiphy);
937}
938EXPORT_SYMBOL(ieee80211_sched_scan_results);
939
940void ieee80211_sched_scan_stopped_work(struct work_struct *work)
941{
942 struct ieee80211_local *local =
943 container_of(work, struct ieee80211_local,
944 sched_scan_stopped_work);
945 int i;
946
947 mutex_lock(&local->mtx);
948
949 if (!local->sched_scanning) {
950 mutex_unlock(&local->mtx);
951 return;
952 }
953
954 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
955 kfree(local->sched_scan_ies.ie[i]);
956
957 local->sched_scanning = false;
958
959 mutex_unlock(&local->mtx);
960
961 cfg80211_sched_scan_stopped(local->hw.wiphy);
962}
963
964void ieee80211_sched_scan_stopped(struct ieee80211_hw *hw)
965{
966 struct ieee80211_local *local = hw_to_local(hw);
967
968 trace_api_sched_scan_stopped(local);
969
970 ieee80211_queue_work(&local->hw, &local->sched_scan_stopped_work);
971}
972EXPORT_SYMBOL(ieee80211_sched_scan_stopped);
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index d9e6e81ff6b2..b83870bf60fa 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -67,7 +67,8 @@ static int sta_info_hash_del(struct ieee80211_local *local,
67{ 67{
68 struct sta_info *s; 68 struct sta_info *s;
69 69
70 s = local->sta_hash[STA_HASH(sta->sta.addr)]; 70 s = rcu_dereference_protected(local->sta_hash[STA_HASH(sta->sta.addr)],
71 lockdep_is_held(&local->sta_lock));
71 if (!s) 72 if (!s)
72 return -ENOENT; 73 return -ENOENT;
73 if (s == sta) { 74 if (s == sta) {
@@ -76,9 +77,11 @@ static int sta_info_hash_del(struct ieee80211_local *local,
76 return 0; 77 return 0;
77 } 78 }
78 79
79 while (s->hnext && s->hnext != sta) 80 while (rcu_access_pointer(s->hnext) &&
80 s = s->hnext; 81 rcu_access_pointer(s->hnext) != sta)
81 if (s->hnext) { 82 s = rcu_dereference_protected(s->hnext,
83 lockdep_is_held(&local->sta_lock));
84 if (rcu_access_pointer(s->hnext)) {
82 rcu_assign_pointer(s->hnext, sta->hnext); 85 rcu_assign_pointer(s->hnext, sta->hnext);
83 return 0; 86 return 0;
84 } 87 }
@@ -274,7 +277,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
274#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ 277#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */
275 278
276#ifdef CONFIG_MAC80211_MESH 279#ifdef CONFIG_MAC80211_MESH
277 sta->plink_state = PLINK_LISTEN; 280 sta->plink_state = NL80211_PLINK_LISTEN;
278 init_timer(&sta->plink_timer); 281 init_timer(&sta->plink_timer);
279#endif 282#endif
280 283
@@ -652,10 +655,12 @@ static int __must_check __sta_info_destroy(struct sta_info *sta)
652 if (ret) 655 if (ret)
653 return ret; 656 return ret;
654 657
658 mutex_lock(&local->key_mtx);
655 for (i = 0; i < NUM_DEFAULT_KEYS; i++) 659 for (i = 0; i < NUM_DEFAULT_KEYS; i++)
656 ieee80211_key_free(local, sta->gtk[i]); 660 __ieee80211_key_free(key_mtx_dereference(local, sta->gtk[i]));
657 if (sta->ptk) 661 if (sta->ptk)
658 ieee80211_key_free(local, sta->ptk); 662 __ieee80211_key_free(key_mtx_dereference(local, sta->ptk));
663 mutex_unlock(&local->key_mtx);
659 664
660 sta->dead = true; 665 sta->dead = true;
661 666
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index aa0adcbf3a93..c6ae8718bd57 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -152,6 +152,7 @@ struct tid_ampdu_rx {
152 * 152 *
153 * @tid_rx: aggregation info for Rx per TID -- RCU protected 153 * @tid_rx: aggregation info for Rx per TID -- RCU protected
154 * @tid_tx: aggregation info for Tx per TID 154 * @tid_tx: aggregation info for Tx per TID
155 * @tid_start_tx: sessions where start was requested
155 * @addba_req_num: number of times addBA request has been sent. 156 * @addba_req_num: number of times addBA request has been sent.
156 * @dialog_token_allocator: dialog token enumerator for each new session; 157 * @dialog_token_allocator: dialog token enumerator for each new session;
157 * @work: work struct for starting/stopping aggregation 158 * @work: work struct for starting/stopping aggregation
@@ -163,40 +164,18 @@ struct tid_ampdu_rx {
163struct sta_ampdu_mlme { 164struct sta_ampdu_mlme {
164 struct mutex mtx; 165 struct mutex mtx;
165 /* rx */ 166 /* rx */
166 struct tid_ampdu_rx *tid_rx[STA_TID_NUM]; 167 struct tid_ampdu_rx __rcu *tid_rx[STA_TID_NUM];
167 unsigned long tid_rx_timer_expired[BITS_TO_LONGS(STA_TID_NUM)]; 168 unsigned long tid_rx_timer_expired[BITS_TO_LONGS(STA_TID_NUM)];
168 /* tx */ 169 /* tx */
169 struct work_struct work; 170 struct work_struct work;
170 struct tid_ampdu_tx *tid_tx[STA_TID_NUM]; 171 struct tid_ampdu_tx __rcu *tid_tx[STA_TID_NUM];
172 struct tid_ampdu_tx *tid_start_tx[STA_TID_NUM];
171 u8 addba_req_num[STA_TID_NUM]; 173 u8 addba_req_num[STA_TID_NUM];
172 u8 dialog_token_allocator; 174 u8 dialog_token_allocator;
173}; 175};
174 176
175 177
176/** 178/**
177 * enum plink_state - state of a mesh peer link finite state machine
178 *
179 * @PLINK_LISTEN: initial state, considered the implicit state of non existent
180 * mesh peer links
181 * @PLINK_OPN_SNT: mesh plink open frame has been sent to this mesh peer
182 * @PLINK_OPN_RCVD: mesh plink open frame has been received from this mesh peer
183 * @PLINK_CNF_RCVD: mesh plink confirm frame has been received from this mesh
184 * peer
185 * @PLINK_ESTAB: mesh peer link is established
186 * @PLINK_HOLDING: mesh peer link is being closed or cancelled
187 * @PLINK_BLOCKED: all frames transmitted from this mesh plink are discarded
188 */
189enum plink_state {
190 PLINK_LISTEN,
191 PLINK_OPN_SNT,
192 PLINK_OPN_RCVD,
193 PLINK_CNF_RCVD,
194 PLINK_ESTAB,
195 PLINK_HOLDING,
196 PLINK_BLOCKED
197};
198
199/**
200 * struct sta_info - STA information 179 * struct sta_info - STA information
201 * 180 *
202 * This structure collects information about a station that 181 * This structure collects information about a station that
@@ -264,11 +243,11 @@ enum plink_state {
264struct sta_info { 243struct sta_info {
265 /* General information, mostly static */ 244 /* General information, mostly static */
266 struct list_head list; 245 struct list_head list;
267 struct sta_info *hnext; 246 struct sta_info __rcu *hnext;
268 struct ieee80211_local *local; 247 struct ieee80211_local *local;
269 struct ieee80211_sub_if_data *sdata; 248 struct ieee80211_sub_if_data *sdata;
270 struct ieee80211_key *gtk[NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS]; 249 struct ieee80211_key __rcu *gtk[NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS];
271 struct ieee80211_key *ptk; 250 struct ieee80211_key __rcu *ptk;
272 struct rate_control_ref *rate_ctrl; 251 struct rate_control_ref *rate_ctrl;
273 void *rate_ctrl_priv; 252 void *rate_ctrl_priv;
274 spinlock_t lock; 253 spinlock_t lock;
@@ -339,7 +318,7 @@ struct sta_info {
339 u8 plink_retries; 318 u8 plink_retries;
340 bool ignore_plink_timer; 319 bool ignore_plink_timer;
341 bool plink_timer_was_running; 320 bool plink_timer_was_running;
342 enum plink_state plink_state; 321 enum nl80211_plink_state plink_state;
343 u32 plink_timeout; 322 u32 plink_timeout;
344 struct timer_list plink_timer; 323 struct timer_list plink_timer;
345#endif 324#endif
@@ -357,12 +336,12 @@ struct sta_info {
357 struct ieee80211_sta sta; 336 struct ieee80211_sta sta;
358}; 337};
359 338
360static inline enum plink_state sta_plink_state(struct sta_info *sta) 339static inline enum nl80211_plink_state sta_plink_state(struct sta_info *sta)
361{ 340{
362#ifdef CONFIG_MAC80211_MESH 341#ifdef CONFIG_MAC80211_MESH
363 return sta->plink_state; 342 return sta->plink_state;
364#endif 343#endif
365 return PLINK_LISTEN; 344 return NL80211_PLINK_LISTEN;
366} 345}
367 346
368static inline void set_sta_flags(struct sta_info *sta, const u32 flags) 347static inline void set_sta_flags(struct sta_info *sta, const u32 flags)
@@ -421,7 +400,16 @@ static inline u32 get_sta_flags(struct sta_info *sta)
421 return ret; 400 return ret;
422} 401}
423 402
403void ieee80211_assign_tid_tx(struct sta_info *sta, int tid,
404 struct tid_ampdu_tx *tid_tx);
424 405
406static inline struct tid_ampdu_tx *
407rcu_dereference_protected_tid_tx(struct sta_info *sta, int tid)
408{
409 return rcu_dereference_protected(sta->ampdu_mlme.tid_tx[tid],
410 lockdep_is_held(&sta->lock) ||
411 lockdep_is_held(&sta->ampdu_mlme.mtx));
412}
425 413
426#define STA_HASH_SIZE 256 414#define STA_HASH_SIZE 256
427#define STA_HASH(sta) (sta[5]) 415#define STA_HASH(sta) (sta[5])
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index e3e3aa173af0..6eeaaa2bbafe 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1147,7 +1147,7 @@ static bool ieee80211_tx_prep_agg(struct ieee80211_tx_data *tx,
1147 * packet pass through because splicing the frames 1147 * packet pass through because splicing the frames
1148 * back is already done. 1148 * back is already done.
1149 */ 1149 */
1150 tid_tx = tx->sta->ampdu_mlme.tid_tx[tid]; 1150 tid_tx = rcu_dereference_protected_tid_tx(tx->sta, tid);
1151 1151
1152 if (!tid_tx) { 1152 if (!tid_tx) {
1153 /* do nothing, let packet pass through */ 1153 /* do nothing, let packet pass through */
@@ -1751,6 +1751,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1751 ret = NETDEV_TX_OK; 1751 ret = NETDEV_TX_OK;
1752 goto fail; 1752 goto fail;
1753 } 1753 }
1754 rcu_read_lock();
1754 if (!is_multicast_ether_addr(skb->data)) 1755 if (!is_multicast_ether_addr(skb->data))
1755 mppath = mpp_path_lookup(skb->data, sdata); 1756 mppath = mpp_path_lookup(skb->data, sdata);
1756 1757
@@ -1765,13 +1766,13 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1765 !(mppath && compare_ether_addr(mppath->mpp, skb->data))) { 1766 !(mppath && compare_ether_addr(mppath->mpp, skb->data))) {
1766 hdrlen = ieee80211_fill_mesh_addresses(&hdr, &fc, 1767 hdrlen = ieee80211_fill_mesh_addresses(&hdr, &fc,
1767 skb->data, skb->data + ETH_ALEN); 1768 skb->data, skb->data + ETH_ALEN);
1769 rcu_read_unlock();
1768 meshhdrlen = ieee80211_new_mesh_header(&mesh_hdr, 1770 meshhdrlen = ieee80211_new_mesh_header(&mesh_hdr,
1769 sdata, NULL, NULL); 1771 sdata, NULL, NULL);
1770 } else { 1772 } else {
1771 int is_mesh_mcast = 1; 1773 int is_mesh_mcast = 1;
1772 const u8 *mesh_da; 1774 const u8 *mesh_da;
1773 1775
1774 rcu_read_lock();
1775 if (is_multicast_ether_addr(skb->data)) 1776 if (is_multicast_ether_addr(skb->data))
1776 /* DA TA mSA AE:SA */ 1777 /* DA TA mSA AE:SA */
1777 mesh_da = skb->data; 1778 mesh_da = skb->data;
@@ -2534,8 +2535,9 @@ void ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb)
2534 skb_set_network_header(skb, 0); 2535 skb_set_network_header(skb, 0);
2535 skb_set_transport_header(skb, 0); 2536 skb_set_transport_header(skb, 0);
2536 2537
2537 /* send all internal mgmt frames on VO */ 2538 /* Send all internal mgmt frames on VO. Accordingly set TID to 7. */
2538 skb_set_queue_mapping(skb, 0); 2539 skb_set_queue_mapping(skb, IEEE80211_AC_VO);
2540 skb->priority = 7;
2539 2541
2540 /* 2542 /*
2541 * The other path calling ieee80211_xmit is from the tasklet, 2543 * The other path calling ieee80211_xmit is from the tasklet,
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index ef0560a2346a..d3fe2d237485 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1125,9 +1125,27 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1125 struct sta_info *sta; 1125 struct sta_info *sta;
1126 int res; 1126 int res;
1127 1127
1128#ifdef CONFIG_PM
1128 if (local->suspended) 1129 if (local->suspended)
1129 local->resuming = true; 1130 local->resuming = true;
1130 1131
1132 if (local->wowlan) {
1133 local->wowlan = false;
1134 res = drv_resume(local);
1135 if (res < 0) {
1136 local->resuming = false;
1137 return res;
1138 }
1139 if (res == 0)
1140 goto wake_up;
1141 WARN_ON(res > 1);
1142 /*
1143 * res is 1, which means the driver requested
1144 * to go through a regular reset on wakeup.
1145 */
1146 }
1147#endif
1148
1131 /* restart hardware */ 1149 /* restart hardware */
1132 if (local->open_count) { 1150 if (local->open_count) {
1133 /* 1151 /*
@@ -1258,6 +1276,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1258 if (ieee80211_sdata_running(sdata)) 1276 if (ieee80211_sdata_running(sdata))
1259 ieee80211_enable_keys(sdata); 1277 ieee80211_enable_keys(sdata);
1260 1278
1279 wake_up:
1261 ieee80211_wake_queues_by_reason(hw, 1280 ieee80211_wake_queues_by_reason(hw,
1262 IEEE80211_QUEUE_STOP_REASON_SUSPEND); 1281 IEEE80211_QUEUE_STOP_REASON_SUSPEND);
1263 1282
diff --git a/net/rfkill/core.c b/net/rfkill/core.c
index 0198191b756d..be90640a2774 100644
--- a/net/rfkill/core.c
+++ b/net/rfkill/core.c
@@ -1024,7 +1024,6 @@ static int rfkill_fop_open(struct inode *inode, struct file *file)
1024 * start getting events from elsewhere but hold mtx to get 1024 * start getting events from elsewhere but hold mtx to get
1025 * startup events added first 1025 * startup events added first
1026 */ 1026 */
1027 list_add(&data->list, &rfkill_fds);
1028 1027
1029 list_for_each_entry(rfkill, &rfkill_list, node) { 1028 list_for_each_entry(rfkill, &rfkill_list, node) {
1030 ev = kzalloc(sizeof(*ev), GFP_KERNEL); 1029 ev = kzalloc(sizeof(*ev), GFP_KERNEL);
@@ -1033,6 +1032,7 @@ static int rfkill_fop_open(struct inode *inode, struct file *file)
1033 rfkill_fill_event(&ev->ev, rfkill, RFKILL_OP_ADD); 1032 rfkill_fill_event(&ev->ev, rfkill, RFKILL_OP_ADD);
1034 list_add_tail(&ev->list, &data->events); 1033 list_add_tail(&ev->list, &data->events);
1035 } 1034 }
1035 list_add(&data->list, &rfkill_fds);
1036 mutex_unlock(&data->mtx); 1036 mutex_unlock(&data->mtx);
1037 mutex_unlock(&rfkill_global_mutex); 1037 mutex_unlock(&rfkill_global_mutex);
1038 1038
diff --git a/net/wireless/core.c b/net/wireless/core.c
index bbf1fa11107a..c22ef3492ee6 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -370,7 +370,7 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv)
370 spin_lock_init(&rdev->bss_lock); 370 spin_lock_init(&rdev->bss_lock);
371 INIT_LIST_HEAD(&rdev->bss_list); 371 INIT_LIST_HEAD(&rdev->bss_list);
372 INIT_WORK(&rdev->scan_done_wk, __cfg80211_scan_done); 372 INIT_WORK(&rdev->scan_done_wk, __cfg80211_scan_done);
373 373 INIT_WORK(&rdev->sched_scan_results_wk, __cfg80211_sched_scan_results);
374#ifdef CONFIG_CFG80211_WEXT 374#ifdef CONFIG_CFG80211_WEXT
375 rdev->wiphy.wext = &cfg80211_wext_handler; 375 rdev->wiphy.wext = &cfg80211_wext_handler;
376#endif 376#endif
@@ -416,6 +416,67 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv)
416} 416}
417EXPORT_SYMBOL(wiphy_new); 417EXPORT_SYMBOL(wiphy_new);
418 418
419static int wiphy_verify_combinations(struct wiphy *wiphy)
420{
421 const struct ieee80211_iface_combination *c;
422 int i, j;
423
424 /* If we have combinations enforce them */
425 if (wiphy->n_iface_combinations)
426 wiphy->flags |= WIPHY_FLAG_ENFORCE_COMBINATIONS;
427
428 for (i = 0; i < wiphy->n_iface_combinations; i++) {
429 u32 cnt = 0;
430 u16 all_iftypes = 0;
431
432 c = &wiphy->iface_combinations[i];
433
434 /* Combinations with just one interface aren't real */
435 if (WARN_ON(c->max_interfaces < 2))
436 return -EINVAL;
437
438 /* Need at least one channel */
439 if (WARN_ON(!c->num_different_channels))
440 return -EINVAL;
441
442 if (WARN_ON(!c->n_limits))
443 return -EINVAL;
444
445 for (j = 0; j < c->n_limits; j++) {
446 u16 types = c->limits[j].types;
447
448 /*
449 * interface types shouldn't overlap, this is
450 * used in cfg80211_can_change_interface()
451 */
452 if (WARN_ON(types & all_iftypes))
453 return -EINVAL;
454 all_iftypes |= types;
455
456 if (WARN_ON(!c->limits[j].max))
457 return -EINVAL;
458
459 /* Shouldn't list software iftypes in combinations! */
460 if (WARN_ON(wiphy->software_iftypes & types))
461 return -EINVAL;
462
463 cnt += c->limits[j].max;
464 /*
465 * Don't advertise an unsupported type
466 * in a combination.
467 */
468 if (WARN_ON((wiphy->interface_modes & types) != types))
469 return -EINVAL;
470 }
471
472 /* You can't even choose that many! */
473 if (WARN_ON(cnt < c->max_interfaces))
474 return -EINVAL;
475 }
476
477 return 0;
478}
479
419int wiphy_register(struct wiphy *wiphy) 480int wiphy_register(struct wiphy *wiphy)
420{ 481{
421 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 482 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
@@ -444,6 +505,10 @@ int wiphy_register(struct wiphy *wiphy)
444 if (WARN_ON(ifmodes != wiphy->interface_modes)) 505 if (WARN_ON(ifmodes != wiphy->interface_modes))
445 wiphy->interface_modes = ifmodes; 506 wiphy->interface_modes = ifmodes;
446 507
508 res = wiphy_verify_combinations(wiphy);
509 if (res)
510 return res;
511
447 /* sanity check supported bands/channels */ 512 /* sanity check supported bands/channels */
448 for (band = 0; band < IEEE80211_NUM_BANDS; band++) { 513 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
449 sband = wiphy->bands[band]; 514 sband = wiphy->bands[band];
@@ -493,6 +558,13 @@ int wiphy_register(struct wiphy *wiphy)
493 return -EINVAL; 558 return -EINVAL;
494 } 559 }
495 560
561 if (rdev->wiphy.wowlan.n_patterns) {
562 if (WARN_ON(!rdev->wiphy.wowlan.pattern_min_len ||
563 rdev->wiphy.wowlan.pattern_min_len >
564 rdev->wiphy.wowlan.pattern_max_len))
565 return -EINVAL;
566 }
567
496 /* check and set up bitrates */ 568 /* check and set up bitrates */
497 ieee80211_set_bitrate_flags(wiphy); 569 ieee80211_set_bitrate_flags(wiphy);
498 570
@@ -631,6 +703,7 @@ void cfg80211_dev_free(struct cfg80211_registered_device *rdev)
631 mutex_destroy(&rdev->devlist_mtx); 703 mutex_destroy(&rdev->devlist_mtx);
632 list_for_each_entry_safe(scan, tmp, &rdev->bss_list, list) 704 list_for_each_entry_safe(scan, tmp, &rdev->bss_list, list)
633 cfg80211_put_bss(&scan->pub); 705 cfg80211_put_bss(&scan->pub);
706 cfg80211_rdev_free_wowlan(rdev);
634 kfree(rdev); 707 kfree(rdev);
635} 708}
636 709
@@ -664,6 +737,11 @@ static void wdev_cleanup_work(struct work_struct *work)
664 ___cfg80211_scan_done(rdev, true); 737 ___cfg80211_scan_done(rdev, true);
665 } 738 }
666 739
740 if (WARN_ON(rdev->sched_scan_req &&
741 rdev->sched_scan_req->dev == wdev->netdev)) {
742 __cfg80211_stop_sched_scan(rdev, false);
743 }
744
667 cfg80211_unlock_rdev(rdev); 745 cfg80211_unlock_rdev(rdev);
668 746
669 mutex_lock(&rdev->devlist_mtx); 747 mutex_lock(&rdev->devlist_mtx);
@@ -685,6 +763,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
685 struct net_device *dev = ndev; 763 struct net_device *dev = ndev;
686 struct wireless_dev *wdev = dev->ieee80211_ptr; 764 struct wireless_dev *wdev = dev->ieee80211_ptr;
687 struct cfg80211_registered_device *rdev; 765 struct cfg80211_registered_device *rdev;
766 int ret;
688 767
689 if (!wdev) 768 if (!wdev)
690 return NOTIFY_DONE; 769 return NOTIFY_DONE;
@@ -751,6 +830,10 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
751 break; 830 break;
752 case NL80211_IFTYPE_P2P_CLIENT: 831 case NL80211_IFTYPE_P2P_CLIENT:
753 case NL80211_IFTYPE_STATION: 832 case NL80211_IFTYPE_STATION:
833 cfg80211_lock_rdev(rdev);
834 __cfg80211_stop_sched_scan(rdev, false);
835 cfg80211_unlock_rdev(rdev);
836
754 wdev_lock(wdev); 837 wdev_lock(wdev);
755#ifdef CONFIG_CFG80211_WEXT 838#ifdef CONFIG_CFG80211_WEXT
756 kfree(wdev->wext.ie); 839 kfree(wdev->wext.ie);
@@ -769,6 +852,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
769 default: 852 default:
770 break; 853 break;
771 } 854 }
855 wdev->beacon_interval = 0;
772 break; 856 break;
773 case NETDEV_DOWN: 857 case NETDEV_DOWN:
774 dev_hold(dev); 858 dev_hold(dev);
@@ -875,6 +959,9 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
875 return notifier_from_errno(-EOPNOTSUPP); 959 return notifier_from_errno(-EOPNOTSUPP);
876 if (rfkill_blocked(rdev->rfkill)) 960 if (rfkill_blocked(rdev->rfkill))
877 return notifier_from_errno(-ERFKILL); 961 return notifier_from_errno(-ERFKILL);
962 ret = cfg80211_can_add_interface(rdev, wdev->iftype);
963 if (ret)
964 return notifier_from_errno(ret);
878 break; 965 break;
879 } 966 }
880 967
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 26a0a084e16b..bf0fb40e3c8b 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -60,8 +60,10 @@ struct cfg80211_registered_device {
60 struct rb_root bss_tree; 60 struct rb_root bss_tree;
61 u32 bss_generation; 61 u32 bss_generation;
62 struct cfg80211_scan_request *scan_req; /* protected by RTNL */ 62 struct cfg80211_scan_request *scan_req; /* protected by RTNL */
63 struct cfg80211_sched_scan_request *sched_scan_req;
63 unsigned long suspend_at; 64 unsigned long suspend_at;
64 struct work_struct scan_done_wk; 65 struct work_struct scan_done_wk;
66 struct work_struct sched_scan_results_wk;
65 67
66#ifdef CONFIG_NL80211_TESTMODE 68#ifdef CONFIG_NL80211_TESTMODE
67 struct genl_info *testmode_info; 69 struct genl_info *testmode_info;
@@ -70,6 +72,8 @@ struct cfg80211_registered_device {
70 struct work_struct conn_work; 72 struct work_struct conn_work;
71 struct work_struct event_work; 73 struct work_struct event_work;
72 74
75 struct cfg80211_wowlan *wowlan;
76
73 /* must be last because of the way we do wiphy_priv(), 77 /* must be last because of the way we do wiphy_priv(),
74 * and it should at least be aligned to NETDEV_ALIGN */ 78 * and it should at least be aligned to NETDEV_ALIGN */
75 struct wiphy wiphy __attribute__((__aligned__(NETDEV_ALIGN))); 79 struct wiphy wiphy __attribute__((__aligned__(NETDEV_ALIGN)));
@@ -89,6 +93,18 @@ bool wiphy_idx_valid(int wiphy_idx)
89 return wiphy_idx >= 0; 93 return wiphy_idx >= 0;
90} 94}
91 95
96static inline void
97cfg80211_rdev_free_wowlan(struct cfg80211_registered_device *rdev)
98{
99 int i;
100
101 if (!rdev->wowlan)
102 return;
103 for (i = 0; i < rdev->wowlan->n_patterns; i++)
104 kfree(rdev->wowlan->patterns[i].mask);
105 kfree(rdev->wowlan->patterns);
106 kfree(rdev->wowlan);
107}
92 108
93extern struct workqueue_struct *cfg80211_wq; 109extern struct workqueue_struct *cfg80211_wq;
94extern struct mutex cfg80211_mutex; 110extern struct mutex cfg80211_mutex;
@@ -397,12 +413,26 @@ void cfg80211_sme_rx_auth(struct net_device *dev, const u8 *buf, size_t len);
397void cfg80211_sme_disassoc(struct net_device *dev, int idx); 413void cfg80211_sme_disassoc(struct net_device *dev, int idx);
398void __cfg80211_scan_done(struct work_struct *wk); 414void __cfg80211_scan_done(struct work_struct *wk);
399void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev, bool leak); 415void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev, bool leak);
416void __cfg80211_sched_scan_results(struct work_struct *wk);
417int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev,
418 bool driver_initiated);
400void cfg80211_upload_connect_keys(struct wireless_dev *wdev); 419void cfg80211_upload_connect_keys(struct wireless_dev *wdev);
401int cfg80211_change_iface(struct cfg80211_registered_device *rdev, 420int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
402 struct net_device *dev, enum nl80211_iftype ntype, 421 struct net_device *dev, enum nl80211_iftype ntype,
403 u32 *flags, struct vif_params *params); 422 u32 *flags, struct vif_params *params);
404void cfg80211_process_rdev_events(struct cfg80211_registered_device *rdev); 423void cfg80211_process_rdev_events(struct cfg80211_registered_device *rdev);
405 424
425int cfg80211_can_change_interface(struct cfg80211_registered_device *rdev,
426 struct wireless_dev *wdev,
427 enum nl80211_iftype iftype);
428
429static inline int
430cfg80211_can_add_interface(struct cfg80211_registered_device *rdev,
431 enum nl80211_iftype iftype)
432{
433 return cfg80211_can_change_interface(rdev, NULL, iftype);
434}
435
406struct ieee80211_channel * 436struct ieee80211_channel *
407rdev_freq_to_chan(struct cfg80211_registered_device *rdev, 437rdev_freq_to_chan(struct cfg80211_registered_device *rdev,
408 int freq, enum nl80211_channel_type channel_type); 438 int freq, enum nl80211_channel_type channel_type);
@@ -412,6 +442,9 @@ int cfg80211_set_freq(struct cfg80211_registered_device *rdev,
412 442
413u16 cfg80211_calculate_bitrate(struct rate_info *rate); 443u16 cfg80211_calculate_bitrate(struct rate_info *rate);
414 444
445int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev,
446 u32 beacon_int);
447
415#ifdef CONFIG_CFG80211_DEVELOPER_WARNINGS 448#ifdef CONFIG_CFG80211_DEVELOPER_WARNINGS
416#define CFG80211_DEV_WARN_ON(cond) WARN_ON(cond) 449#define CFG80211_DEV_WARN_ON(cond) WARN_ON(cond)
417#else 450#else
diff --git a/net/wireless/lib80211_crypt_wep.c b/net/wireless/lib80211_crypt_wep.c
index e2e88878ba35..2f265e033ae2 100644
--- a/net/wireless/lib80211_crypt_wep.c
+++ b/net/wireless/lib80211_crypt_wep.c
@@ -96,13 +96,12 @@ static int lib80211_wep_build_iv(struct sk_buff *skb, int hdr_len,
96 u8 *key, int keylen, void *priv) 96 u8 *key, int keylen, void *priv)
97{ 97{
98 struct lib80211_wep_data *wep = priv; 98 struct lib80211_wep_data *wep = priv;
99 u32 klen, len; 99 u32 klen;
100 u8 *pos; 100 u8 *pos;
101 101
102 if (skb_headroom(skb) < 4 || skb->len < hdr_len) 102 if (skb_headroom(skb) < 4 || skb->len < hdr_len)
103 return -1; 103 return -1;
104 104
105 len = skb->len - hdr_len;
106 pos = skb_push(skb, 4); 105 pos = skb_push(skb, 4);
107 memmove(pos, pos + 4, hdr_len); 106 memmove(pos, pos + 4, hdr_len);
108 pos += hdr_len; 107 pos += hdr_len;
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index 16881fea4ce6..493b939970cd 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -963,6 +963,16 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
963 if (memcmp(mgmt->bssid, dev->dev_addr, ETH_ALEN)) 963 if (memcmp(mgmt->bssid, dev->dev_addr, ETH_ALEN))
964 err = -EINVAL; 964 err = -EINVAL;
965 break; 965 break;
966 case NL80211_IFTYPE_MESH_POINT:
967 if (memcmp(mgmt->sa, mgmt->bssid, ETH_ALEN)) {
968 err = -EINVAL;
969 break;
970 }
971 /*
972 * check for mesh DA must be done by driver as
973 * cfg80211 doesn't track the stations
974 */
975 break;
966 default: 976 default:
967 err = -EOPNOTSUPP; 977 err = -EOPNOTSUPP;
968 break; 978 break;
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 0efa7fd01150..2222ce08ee91 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -173,6 +173,9 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
173 [NL80211_ATTR_MCAST_RATE] = { .type = NLA_U32 }, 173 [NL80211_ATTR_MCAST_RATE] = { .type = NLA_U32 },
174 [NL80211_ATTR_OFFCHANNEL_TX_OK] = { .type = NLA_FLAG }, 174 [NL80211_ATTR_OFFCHANNEL_TX_OK] = { .type = NLA_FLAG },
175 [NL80211_ATTR_KEY_DEFAULT_TYPES] = { .type = NLA_NESTED }, 175 [NL80211_ATTR_KEY_DEFAULT_TYPES] = { .type = NLA_NESTED },
176 [NL80211_ATTR_WOWLAN_TRIGGERS] = { .type = NLA_NESTED },
177 [NL80211_ATTR_STA_PLINK_STATE] = { .type = NLA_U8 },
178 [NL80211_ATTR_SCHED_SCAN_INTERVAL] = { .type = NLA_U32 },
176}; 179};
177 180
178/* policy for the key attributes */ 181/* policy for the key attributes */
@@ -194,6 +197,15 @@ nl80211_key_default_policy[NUM_NL80211_KEY_DEFAULT_TYPES] = {
194 [NL80211_KEY_DEFAULT_TYPE_MULTICAST] = { .type = NLA_FLAG }, 197 [NL80211_KEY_DEFAULT_TYPE_MULTICAST] = { .type = NLA_FLAG },
195}; 198};
196 199
200/* policy for WoWLAN attributes */
201static const struct nla_policy
202nl80211_wowlan_policy[NUM_NL80211_WOWLAN_TRIG] = {
203 [NL80211_WOWLAN_TRIG_ANY] = { .type = NLA_FLAG },
204 [NL80211_WOWLAN_TRIG_DISCONNECT] = { .type = NLA_FLAG },
205 [NL80211_WOWLAN_TRIG_MAGIC_PKT] = { .type = NLA_FLAG },
206 [NL80211_WOWLAN_TRIG_PKT_PATTERN] = { .type = NLA_NESTED },
207};
208
197/* ifidx get helper */ 209/* ifidx get helper */
198static int nl80211_get_ifidx(struct netlink_callback *cb) 210static int nl80211_get_ifidx(struct netlink_callback *cb)
199{ 211{
@@ -534,6 +546,7 @@ static int nl80211_key_allowed(struct wireless_dev *wdev)
534 case NL80211_IFTYPE_AP: 546 case NL80211_IFTYPE_AP:
535 case NL80211_IFTYPE_AP_VLAN: 547 case NL80211_IFTYPE_AP_VLAN:
536 case NL80211_IFTYPE_P2P_GO: 548 case NL80211_IFTYPE_P2P_GO:
549 case NL80211_IFTYPE_MESH_POINT:
537 break; 550 break;
538 case NL80211_IFTYPE_ADHOC: 551 case NL80211_IFTYPE_ADHOC:
539 if (!wdev->current_bss) 552 if (!wdev->current_bss)
@@ -551,6 +564,88 @@ static int nl80211_key_allowed(struct wireless_dev *wdev)
551 return 0; 564 return 0;
552} 565}
553 566
567static int nl80211_put_iftypes(struct sk_buff *msg, u32 attr, u16 ifmodes)
568{
569 struct nlattr *nl_modes = nla_nest_start(msg, attr);
570 int i;
571
572 if (!nl_modes)
573 goto nla_put_failure;
574
575 i = 0;
576 while (ifmodes) {
577 if (ifmodes & 1)
578 NLA_PUT_FLAG(msg, i);
579 ifmodes >>= 1;
580 i++;
581 }
582
583 nla_nest_end(msg, nl_modes);
584 return 0;
585
586nla_put_failure:
587 return -ENOBUFS;
588}
589
590static int nl80211_put_iface_combinations(struct wiphy *wiphy,
591 struct sk_buff *msg)
592{
593 struct nlattr *nl_combis;
594 int i, j;
595
596 nl_combis = nla_nest_start(msg,
597 NL80211_ATTR_INTERFACE_COMBINATIONS);
598 if (!nl_combis)
599 goto nla_put_failure;
600
601 for (i = 0; i < wiphy->n_iface_combinations; i++) {
602 const struct ieee80211_iface_combination *c;
603 struct nlattr *nl_combi, *nl_limits;
604
605 c = &wiphy->iface_combinations[i];
606
607 nl_combi = nla_nest_start(msg, i + 1);
608 if (!nl_combi)
609 goto nla_put_failure;
610
611 nl_limits = nla_nest_start(msg, NL80211_IFACE_COMB_LIMITS);
612 if (!nl_limits)
613 goto nla_put_failure;
614
615 for (j = 0; j < c->n_limits; j++) {
616 struct nlattr *nl_limit;
617
618 nl_limit = nla_nest_start(msg, j + 1);
619 if (!nl_limit)
620 goto nla_put_failure;
621 NLA_PUT_U32(msg, NL80211_IFACE_LIMIT_MAX,
622 c->limits[j].max);
623 if (nl80211_put_iftypes(msg, NL80211_IFACE_LIMIT_TYPES,
624 c->limits[j].types))
625 goto nla_put_failure;
626 nla_nest_end(msg, nl_limit);
627 }
628
629 nla_nest_end(msg, nl_limits);
630
631 if (c->beacon_int_infra_match)
632 NLA_PUT_FLAG(msg,
633 NL80211_IFACE_COMB_STA_AP_BI_MATCH);
634 NLA_PUT_U32(msg, NL80211_IFACE_COMB_NUM_CHANNELS,
635 c->num_different_channels);
636 NLA_PUT_U32(msg, NL80211_IFACE_COMB_MAXNUM,
637 c->max_interfaces);
638
639 nla_nest_end(msg, nl_combi);
640 }
641
642 nla_nest_end(msg, nl_combis);
643
644 return 0;
645nla_put_failure:
646 return -ENOBUFS;
647}
648
554static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, 649static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
555 struct cfg80211_registered_device *dev) 650 struct cfg80211_registered_device *dev)
556{ 651{
@@ -558,13 +653,11 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
558 struct nlattr *nl_bands, *nl_band; 653 struct nlattr *nl_bands, *nl_band;
559 struct nlattr *nl_freqs, *nl_freq; 654 struct nlattr *nl_freqs, *nl_freq;
560 struct nlattr *nl_rates, *nl_rate; 655 struct nlattr *nl_rates, *nl_rate;
561 struct nlattr *nl_modes;
562 struct nlattr *nl_cmds; 656 struct nlattr *nl_cmds;
563 enum ieee80211_band band; 657 enum ieee80211_band band;
564 struct ieee80211_channel *chan; 658 struct ieee80211_channel *chan;
565 struct ieee80211_rate *rate; 659 struct ieee80211_rate *rate;
566 int i; 660 int i;
567 u16 ifmodes = dev->wiphy.interface_modes;
568 const struct ieee80211_txrx_stypes *mgmt_stypes = 661 const struct ieee80211_txrx_stypes *mgmt_stypes =
569 dev->wiphy.mgmt_stypes; 662 dev->wiphy.mgmt_stypes;
570 663
@@ -624,20 +717,10 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
624 } 717 }
625 } 718 }
626 719
627 nl_modes = nla_nest_start(msg, NL80211_ATTR_SUPPORTED_IFTYPES); 720 if (nl80211_put_iftypes(msg, NL80211_ATTR_SUPPORTED_IFTYPES,
628 if (!nl_modes) 721 dev->wiphy.interface_modes))
629 goto nla_put_failure; 722 goto nla_put_failure;
630 723
631 i = 0;
632 while (ifmodes) {
633 if (ifmodes & 1)
634 NLA_PUT_FLAG(msg, i);
635 ifmodes >>= 1;
636 i++;
637 }
638
639 nla_nest_end(msg, nl_modes);
640
641 nl_bands = nla_nest_start(msg, NL80211_ATTR_WIPHY_BANDS); 724 nl_bands = nla_nest_start(msg, NL80211_ATTR_WIPHY_BANDS);
642 if (!nl_bands) 725 if (!nl_bands)
643 goto nla_put_failure; 726 goto nla_put_failure;
@@ -749,6 +832,8 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
749 } 832 }
750 CMD(set_channel, SET_CHANNEL); 833 CMD(set_channel, SET_CHANNEL);
751 CMD(set_wds_peer, SET_WDS_PEER); 834 CMD(set_wds_peer, SET_WDS_PEER);
835 if (dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN)
836 CMD(sched_scan_start, START_SCHED_SCAN);
752 837
753#undef CMD 838#undef CMD
754 839
@@ -821,6 +906,42 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
821 nla_nest_end(msg, nl_ifs); 906 nla_nest_end(msg, nl_ifs);
822 } 907 }
823 908
909 if (dev->wiphy.wowlan.flags || dev->wiphy.wowlan.n_patterns) {
910 struct nlattr *nl_wowlan;
911
912 nl_wowlan = nla_nest_start(msg,
913 NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED);
914 if (!nl_wowlan)
915 goto nla_put_failure;
916
917 if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_ANY)
918 NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_ANY);
919 if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_DISCONNECT)
920 NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_DISCONNECT);
921 if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_MAGIC_PKT)
922 NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT);
923 if (dev->wiphy.wowlan.n_patterns) {
924 struct nl80211_wowlan_pattern_support pat = {
925 .max_patterns = dev->wiphy.wowlan.n_patterns,
926 .min_pattern_len =
927 dev->wiphy.wowlan.pattern_min_len,
928 .max_pattern_len =
929 dev->wiphy.wowlan.pattern_max_len,
930 };
931 NLA_PUT(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN,
932 sizeof(pat), &pat);
933 }
934
935 nla_nest_end(msg, nl_wowlan);
936 }
937
938 if (nl80211_put_iftypes(msg, NL80211_ATTR_SOFTWARE_IFTYPES,
939 dev->wiphy.software_iftypes))
940 goto nla_put_failure;
941
942 if (nl80211_put_iface_combinations(&dev->wiphy, msg))
943 goto nla_put_failure;
944
824 return genlmsg_end(msg, hdr); 945 return genlmsg_end(msg, hdr);
825 946
826 nla_put_failure: 947 nla_put_failure:
@@ -1682,14 +1803,6 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
1682 if (err) 1803 if (err)
1683 goto out; 1804 goto out;
1684 1805
1685 if (!(rdev->wiphy.flags &
1686 WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS)) {
1687 if (!key.def_uni || !key.def_multi) {
1688 err = -EOPNOTSUPP;
1689 goto out;
1690 }
1691 }
1692
1693 err = rdev->ops->set_default_key(&rdev->wiphy, dev, key.idx, 1806 err = rdev->ops->set_default_key(&rdev->wiphy, dev, key.idx,
1694 key.def_uni, key.def_multi); 1807 key.def_uni, key.def_multi);
1695 1808
@@ -1840,8 +1953,9 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
1840 struct beacon_parameters *info); 1953 struct beacon_parameters *info);
1841 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 1954 struct cfg80211_registered_device *rdev = info->user_ptr[0];
1842 struct net_device *dev = info->user_ptr[1]; 1955 struct net_device *dev = info->user_ptr[1];
1956 struct wireless_dev *wdev = dev->ieee80211_ptr;
1843 struct beacon_parameters params; 1957 struct beacon_parameters params;
1844 int haveinfo = 0; 1958 int haveinfo = 0, err;
1845 1959
1846 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_BEACON_TAIL])) 1960 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_BEACON_TAIL]))
1847 return -EINVAL; 1961 return -EINVAL;
@@ -1850,6 +1964,8 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
1850 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) 1964 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
1851 return -EOPNOTSUPP; 1965 return -EOPNOTSUPP;
1852 1966
1967 memset(&params, 0, sizeof(params));
1968
1853 switch (info->genlhdr->cmd) { 1969 switch (info->genlhdr->cmd) {
1854 case NL80211_CMD_NEW_BEACON: 1970 case NL80211_CMD_NEW_BEACON:
1855 /* these are required for NEW_BEACON */ 1971 /* these are required for NEW_BEACON */
@@ -1858,6 +1974,15 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
1858 !info->attrs[NL80211_ATTR_BEACON_HEAD]) 1974 !info->attrs[NL80211_ATTR_BEACON_HEAD])
1859 return -EINVAL; 1975 return -EINVAL;
1860 1976
1977 params.interval =
1978 nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
1979 params.dtim_period =
1980 nla_get_u32(info->attrs[NL80211_ATTR_DTIM_PERIOD]);
1981
1982 err = cfg80211_validate_beacon_int(rdev, params.interval);
1983 if (err)
1984 return err;
1985
1861 call = rdev->ops->add_beacon; 1986 call = rdev->ops->add_beacon;
1862 break; 1987 break;
1863 case NL80211_CMD_SET_BEACON: 1988 case NL80211_CMD_SET_BEACON:
@@ -1871,20 +1996,6 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
1871 if (!call) 1996 if (!call)
1872 return -EOPNOTSUPP; 1997 return -EOPNOTSUPP;
1873 1998
1874 memset(&params, 0, sizeof(params));
1875
1876 if (info->attrs[NL80211_ATTR_BEACON_INTERVAL]) {
1877 params.interval =
1878 nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
1879 haveinfo = 1;
1880 }
1881
1882 if (info->attrs[NL80211_ATTR_DTIM_PERIOD]) {
1883 params.dtim_period =
1884 nla_get_u32(info->attrs[NL80211_ATTR_DTIM_PERIOD]);
1885 haveinfo = 1;
1886 }
1887
1888 if (info->attrs[NL80211_ATTR_BEACON_HEAD]) { 1999 if (info->attrs[NL80211_ATTR_BEACON_HEAD]) {
1889 params.head = nla_data(info->attrs[NL80211_ATTR_BEACON_HEAD]); 2000 params.head = nla_data(info->attrs[NL80211_ATTR_BEACON_HEAD]);
1890 params.head_len = 2001 params.head_len =
@@ -1902,13 +2013,18 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
1902 if (!haveinfo) 2013 if (!haveinfo)
1903 return -EINVAL; 2014 return -EINVAL;
1904 2015
1905 return call(&rdev->wiphy, dev, &params); 2016 err = call(&rdev->wiphy, dev, &params);
2017 if (!err && params.interval)
2018 wdev->beacon_interval = params.interval;
2019 return err;
1906} 2020}
1907 2021
1908static int nl80211_del_beacon(struct sk_buff *skb, struct genl_info *info) 2022static int nl80211_del_beacon(struct sk_buff *skb, struct genl_info *info)
1909{ 2023{
1910 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 2024 struct cfg80211_registered_device *rdev = info->user_ptr[0];
1911 struct net_device *dev = info->user_ptr[1]; 2025 struct net_device *dev = info->user_ptr[1];
2026 struct wireless_dev *wdev = dev->ieee80211_ptr;
2027 int err;
1912 2028
1913 if (!rdev->ops->del_beacon) 2029 if (!rdev->ops->del_beacon)
1914 return -EOPNOTSUPP; 2030 return -EOPNOTSUPP;
@@ -1917,7 +2033,10 @@ static int nl80211_del_beacon(struct sk_buff *skb, struct genl_info *info)
1917 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) 2033 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
1918 return -EOPNOTSUPP; 2034 return -EOPNOTSUPP;
1919 2035
1920 return rdev->ops->del_beacon(&rdev->wiphy, dev); 2036 err = rdev->ops->del_beacon(&rdev->wiphy, dev);
2037 if (!err)
2038 wdev->beacon_interval = 0;
2039 return err;
1921} 2040}
1922 2041
1923static const struct nla_policy sta_flags_policy[NL80211_STA_FLAG_MAX + 1] = { 2042static const struct nla_policy sta_flags_policy[NL80211_STA_FLAG_MAX + 1] = {
@@ -2216,6 +2335,7 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
2216 memset(&params, 0, sizeof(params)); 2335 memset(&params, 0, sizeof(params));
2217 2336
2218 params.listen_interval = -1; 2337 params.listen_interval = -1;
2338 params.plink_state = -1;
2219 2339
2220 if (info->attrs[NL80211_ATTR_STA_AID]) 2340 if (info->attrs[NL80211_ATTR_STA_AID])
2221 return -EINVAL; 2341 return -EINVAL;
@@ -2247,6 +2367,10 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
2247 params.plink_action = 2367 params.plink_action =
2248 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]); 2368 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]);
2249 2369
2370 if (info->attrs[NL80211_ATTR_STA_PLINK_STATE])
2371 params.plink_state =
2372 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_STATE]);
2373
2250 err = get_vlan(info, rdev, &params.vlan); 2374 err = get_vlan(info, rdev, &params.vlan);
2251 if (err) 2375 if (err)
2252 goto out; 2376 goto out;
@@ -2286,10 +2410,9 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
2286 err = -EINVAL; 2410 err = -EINVAL;
2287 if (params.listen_interval >= 0) 2411 if (params.listen_interval >= 0)
2288 err = -EINVAL; 2412 err = -EINVAL;
2289 if (params.supported_rates)
2290 err = -EINVAL;
2291 if (params.sta_flags_mask & 2413 if (params.sta_flags_mask &
2292 ~(BIT(NL80211_STA_FLAG_AUTHENTICATED) | 2414 ~(BIT(NL80211_STA_FLAG_AUTHENTICATED) |
2415 BIT(NL80211_STA_FLAG_MFP) |
2293 BIT(NL80211_STA_FLAG_AUTHORIZED))) 2416 BIT(NL80211_STA_FLAG_AUTHORIZED)))
2294 err = -EINVAL; 2417 err = -EINVAL;
2295 break; 2418 break;
@@ -2840,6 +2963,7 @@ static const struct nla_policy
2840 [NL80211_MESH_SETUP_USERSPACE_AUTH] = { .type = NLA_FLAG }, 2963 [NL80211_MESH_SETUP_USERSPACE_AUTH] = { .type = NLA_FLAG },
2841 [NL80211_MESH_SETUP_IE] = { .type = NLA_BINARY, 2964 [NL80211_MESH_SETUP_IE] = { .type = NLA_BINARY,
2842 .len = IEEE80211_MAX_DATA_LEN }, 2965 .len = IEEE80211_MAX_DATA_LEN },
2966 [NL80211_MESH_SETUP_USERSPACE_AMPE] = { .type = NLA_FLAG },
2843}; 2967};
2844 2968
2845static int nl80211_parse_mesh_config(struct genl_info *info, 2969static int nl80211_parse_mesh_config(struct genl_info *info,
@@ -2949,7 +3073,8 @@ static int nl80211_parse_mesh_setup(struct genl_info *info,
2949 setup->ie = nla_data(ieattr); 3073 setup->ie = nla_data(ieattr);
2950 setup->ie_len = nla_len(ieattr); 3074 setup->ie_len = nla_len(ieattr);
2951 } 3075 }
2952 setup->is_secure = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_AUTH]); 3076 setup->is_authenticated = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_AUTH]);
3077 setup->is_secure = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_AMPE]);
2953 3078
2954 return 0; 3079 return 0;
2955} 3080}
@@ -3318,6 +3443,188 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
3318 return err; 3443 return err;
3319} 3444}
3320 3445
3446static int nl80211_start_sched_scan(struct sk_buff *skb,
3447 struct genl_info *info)
3448{
3449 struct cfg80211_sched_scan_request *request;
3450 struct cfg80211_registered_device *rdev = info->user_ptr[0];
3451 struct net_device *dev = info->user_ptr[1];
3452 struct cfg80211_ssid *ssid;
3453 struct ieee80211_channel *channel;
3454 struct nlattr *attr;
3455 struct wiphy *wiphy;
3456 int err, tmp, n_ssids = 0, n_channels, i;
3457 u32 interval;
3458 enum ieee80211_band band;
3459 size_t ie_len;
3460
3461 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) ||
3462 !rdev->ops->sched_scan_start)
3463 return -EOPNOTSUPP;
3464
3465 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
3466 return -EINVAL;
3467
3468 if (rdev->sched_scan_req)
3469 return -EINPROGRESS;
3470
3471 if (!info->attrs[NL80211_ATTR_SCHED_SCAN_INTERVAL])
3472 return -EINVAL;
3473
3474 interval = nla_get_u32(info->attrs[NL80211_ATTR_SCHED_SCAN_INTERVAL]);
3475 if (interval == 0)
3476 return -EINVAL;
3477
3478 wiphy = &rdev->wiphy;
3479
3480 if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
3481 n_channels = validate_scan_freqs(
3482 info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]);
3483 if (!n_channels)
3484 return -EINVAL;
3485 } else {
3486 n_channels = 0;
3487
3488 for (band = 0; band < IEEE80211_NUM_BANDS; band++)
3489 if (wiphy->bands[band])
3490 n_channels += wiphy->bands[band]->n_channels;
3491 }
3492
3493 if (info->attrs[NL80211_ATTR_SCAN_SSIDS])
3494 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS],
3495 tmp)
3496 n_ssids++;
3497
3498 if (n_ssids > wiphy->max_scan_ssids)
3499 return -EINVAL;
3500
3501 if (info->attrs[NL80211_ATTR_IE])
3502 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
3503 else
3504 ie_len = 0;
3505
3506 if (ie_len > wiphy->max_scan_ie_len)
3507 return -EINVAL;
3508
3509 request = kzalloc(sizeof(*request)
3510 + sizeof(*ssid) * n_ssids
3511 + sizeof(channel) * n_channels
3512 + ie_len, GFP_KERNEL);
3513 if (!request)
3514 return -ENOMEM;
3515
3516 if (n_ssids)
3517 request->ssids = (void *)&request->channels[n_channels];
3518 request->n_ssids = n_ssids;
3519 if (ie_len) {
3520 if (request->ssids)
3521 request->ie = (void *)(request->ssids + n_ssids);
3522 else
3523 request->ie = (void *)(request->channels + n_channels);
3524 }
3525
3526 i = 0;
3527 if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
3528 /* user specified, bail out if channel not found */
3529 nla_for_each_nested(attr,
3530 info->attrs[NL80211_ATTR_SCAN_FREQUENCIES],
3531 tmp) {
3532 struct ieee80211_channel *chan;
3533
3534 chan = ieee80211_get_channel(wiphy, nla_get_u32(attr));
3535
3536 if (!chan) {
3537 err = -EINVAL;
3538 goto out_free;
3539 }
3540
3541 /* ignore disabled channels */
3542 if (chan->flags & IEEE80211_CHAN_DISABLED)
3543 continue;
3544
3545 request->channels[i] = chan;
3546 i++;
3547 }
3548 } else {
3549 /* all channels */
3550 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
3551 int j;
3552 if (!wiphy->bands[band])
3553 continue;
3554 for (j = 0; j < wiphy->bands[band]->n_channels; j++) {
3555 struct ieee80211_channel *chan;
3556
3557 chan = &wiphy->bands[band]->channels[j];
3558
3559 if (chan->flags & IEEE80211_CHAN_DISABLED)
3560 continue;
3561
3562 request->channels[i] = chan;
3563 i++;
3564 }
3565 }
3566 }
3567
3568 if (!i) {
3569 err = -EINVAL;
3570 goto out_free;
3571 }
3572
3573 request->n_channels = i;
3574
3575 i = 0;
3576 if (info->attrs[NL80211_ATTR_SCAN_SSIDS]) {
3577 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS],
3578 tmp) {
3579 if (request->ssids[i].ssid_len >
3580 IEEE80211_MAX_SSID_LEN) {
3581 err = -EINVAL;
3582 goto out_free;
3583 }
3584 memcpy(request->ssids[i].ssid, nla_data(attr),
3585 nla_len(attr));
3586 request->ssids[i].ssid_len = nla_len(attr);
3587 i++;
3588 }
3589 }
3590
3591 if (info->attrs[NL80211_ATTR_IE]) {
3592 request->ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
3593 memcpy((void *)request->ie,
3594 nla_data(info->attrs[NL80211_ATTR_IE]),
3595 request->ie_len);
3596 }
3597
3598 request->dev = dev;
3599 request->wiphy = &rdev->wiphy;
3600 request->interval = interval;
3601
3602 err = rdev->ops->sched_scan_start(&rdev->wiphy, dev, request);
3603 if (!err) {
3604 rdev->sched_scan_req = request;
3605 nl80211_send_sched_scan(rdev, dev,
3606 NL80211_CMD_START_SCHED_SCAN);
3607 goto out;
3608 }
3609
3610out_free:
3611 kfree(request);
3612out:
3613 return err;
3614}
3615
3616static int nl80211_stop_sched_scan(struct sk_buff *skb,
3617 struct genl_info *info)
3618{
3619 struct cfg80211_registered_device *rdev = info->user_ptr[0];
3620
3621 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) ||
3622 !rdev->ops->sched_scan_stop)
3623 return -EOPNOTSUPP;
3624
3625 return __cfg80211_stop_sched_scan(rdev, false);
3626}
3627
3321static int nl80211_send_bss(struct sk_buff *msg, u32 pid, u32 seq, int flags, 3628static int nl80211_send_bss(struct sk_buff *msg, u32 pid, u32 seq, int flags,
3322 struct cfg80211_registered_device *rdev, 3629 struct cfg80211_registered_device *rdev,
3323 struct wireless_dev *wdev, 3630 struct wireless_dev *wdev,
@@ -4816,6 +5123,194 @@ static int nl80211_leave_mesh(struct sk_buff *skb, struct genl_info *info)
4816 return cfg80211_leave_mesh(rdev, dev); 5123 return cfg80211_leave_mesh(rdev, dev);
4817} 5124}
4818 5125
5126static int nl80211_get_wowlan(struct sk_buff *skb, struct genl_info *info)
5127{
5128 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5129 struct sk_buff *msg;
5130 void *hdr;
5131
5132 if (!rdev->wiphy.wowlan.flags && !rdev->wiphy.wowlan.n_patterns)
5133 return -EOPNOTSUPP;
5134
5135 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
5136 if (!msg)
5137 return -ENOMEM;
5138
5139 hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
5140 NL80211_CMD_GET_WOWLAN);
5141 if (!hdr)
5142 goto nla_put_failure;
5143
5144 if (rdev->wowlan) {
5145 struct nlattr *nl_wowlan;
5146
5147 nl_wowlan = nla_nest_start(msg, NL80211_ATTR_WOWLAN_TRIGGERS);
5148 if (!nl_wowlan)
5149 goto nla_put_failure;
5150
5151 if (rdev->wowlan->any)
5152 NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_ANY);
5153 if (rdev->wowlan->disconnect)
5154 NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_DISCONNECT);
5155 if (rdev->wowlan->magic_pkt)
5156 NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT);
5157 if (rdev->wowlan->n_patterns) {
5158 struct nlattr *nl_pats, *nl_pat;
5159 int i, pat_len;
5160
5161 nl_pats = nla_nest_start(msg,
5162 NL80211_WOWLAN_TRIG_PKT_PATTERN);
5163 if (!nl_pats)
5164 goto nla_put_failure;
5165
5166 for (i = 0; i < rdev->wowlan->n_patterns; i++) {
5167 nl_pat = nla_nest_start(msg, i + 1);
5168 if (!nl_pat)
5169 goto nla_put_failure;
5170 pat_len = rdev->wowlan->patterns[i].pattern_len;
5171 NLA_PUT(msg, NL80211_WOWLAN_PKTPAT_MASK,
5172 DIV_ROUND_UP(pat_len, 8),
5173 rdev->wowlan->patterns[i].mask);
5174 NLA_PUT(msg, NL80211_WOWLAN_PKTPAT_PATTERN,
5175 pat_len,
5176 rdev->wowlan->patterns[i].pattern);
5177 nla_nest_end(msg, nl_pat);
5178 }
5179 nla_nest_end(msg, nl_pats);
5180 }
5181
5182 nla_nest_end(msg, nl_wowlan);
5183 }
5184
5185 genlmsg_end(msg, hdr);
5186 return genlmsg_reply(msg, info);
5187
5188nla_put_failure:
5189 nlmsg_free(msg);
5190 return -ENOBUFS;
5191}
5192
5193static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
5194{
5195 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5196 struct nlattr *tb[NUM_NL80211_WOWLAN_TRIG];
5197 struct cfg80211_wowlan no_triggers = {};
5198 struct cfg80211_wowlan new_triggers = {};
5199 struct wiphy_wowlan_support *wowlan = &rdev->wiphy.wowlan;
5200 int err, i;
5201
5202 if (!rdev->wiphy.wowlan.flags && !rdev->wiphy.wowlan.n_patterns)
5203 return -EOPNOTSUPP;
5204
5205 if (!info->attrs[NL80211_ATTR_WOWLAN_TRIGGERS])
5206 goto no_triggers;
5207
5208 err = nla_parse(tb, MAX_NL80211_WOWLAN_TRIG,
5209 nla_data(info->attrs[NL80211_ATTR_WOWLAN_TRIGGERS]),
5210 nla_len(info->attrs[NL80211_ATTR_WOWLAN_TRIGGERS]),
5211 nl80211_wowlan_policy);
5212 if (err)
5213 return err;
5214
5215 if (tb[NL80211_WOWLAN_TRIG_ANY]) {
5216 if (!(wowlan->flags & WIPHY_WOWLAN_ANY))
5217 return -EINVAL;
5218 new_triggers.any = true;
5219 }
5220
5221 if (tb[NL80211_WOWLAN_TRIG_DISCONNECT]) {
5222 if (!(wowlan->flags & WIPHY_WOWLAN_DISCONNECT))
5223 return -EINVAL;
5224 new_triggers.disconnect = true;
5225 }
5226
5227 if (tb[NL80211_WOWLAN_TRIG_MAGIC_PKT]) {
5228 if (!(wowlan->flags & WIPHY_WOWLAN_MAGIC_PKT))
5229 return -EINVAL;
5230 new_triggers.magic_pkt = true;
5231 }
5232
5233 if (tb[NL80211_WOWLAN_TRIG_PKT_PATTERN]) {
5234 struct nlattr *pat;
5235 int n_patterns = 0;
5236 int rem, pat_len, mask_len;
5237 struct nlattr *pat_tb[NUM_NL80211_WOWLAN_PKTPAT];
5238
5239 nla_for_each_nested(pat, tb[NL80211_WOWLAN_TRIG_PKT_PATTERN],
5240 rem)
5241 n_patterns++;
5242 if (n_patterns > wowlan->n_patterns)
5243 return -EINVAL;
5244
5245 new_triggers.patterns = kcalloc(n_patterns,
5246 sizeof(new_triggers.patterns[0]),
5247 GFP_KERNEL);
5248 if (!new_triggers.patterns)
5249 return -ENOMEM;
5250
5251 new_triggers.n_patterns = n_patterns;
5252 i = 0;
5253
5254 nla_for_each_nested(pat, tb[NL80211_WOWLAN_TRIG_PKT_PATTERN],
5255 rem) {
5256 nla_parse(pat_tb, MAX_NL80211_WOWLAN_PKTPAT,
5257 nla_data(pat), nla_len(pat), NULL);
5258 err = -EINVAL;
5259 if (!pat_tb[NL80211_WOWLAN_PKTPAT_MASK] ||
5260 !pat_tb[NL80211_WOWLAN_PKTPAT_PATTERN])
5261 goto error;
5262 pat_len = nla_len(pat_tb[NL80211_WOWLAN_PKTPAT_PATTERN]);
5263 mask_len = DIV_ROUND_UP(pat_len, 8);
5264 if (nla_len(pat_tb[NL80211_WOWLAN_PKTPAT_MASK]) !=
5265 mask_len)
5266 goto error;
5267 if (pat_len > wowlan->pattern_max_len ||
5268 pat_len < wowlan->pattern_min_len)
5269 goto error;
5270
5271 new_triggers.patterns[i].mask =
5272 kmalloc(mask_len + pat_len, GFP_KERNEL);
5273 if (!new_triggers.patterns[i].mask) {
5274 err = -ENOMEM;
5275 goto error;
5276 }
5277 new_triggers.patterns[i].pattern =
5278 new_triggers.patterns[i].mask + mask_len;
5279 memcpy(new_triggers.patterns[i].mask,
5280 nla_data(pat_tb[NL80211_WOWLAN_PKTPAT_MASK]),
5281 mask_len);
5282 new_triggers.patterns[i].pattern_len = pat_len;
5283 memcpy(new_triggers.patterns[i].pattern,
5284 nla_data(pat_tb[NL80211_WOWLAN_PKTPAT_PATTERN]),
5285 pat_len);
5286 i++;
5287 }
5288 }
5289
5290 if (memcmp(&new_triggers, &no_triggers, sizeof(new_triggers))) {
5291 struct cfg80211_wowlan *ntrig;
5292 ntrig = kmemdup(&new_triggers, sizeof(new_triggers),
5293 GFP_KERNEL);
5294 if (!ntrig) {
5295 err = -ENOMEM;
5296 goto error;
5297 }
5298 cfg80211_rdev_free_wowlan(rdev);
5299 rdev->wowlan = ntrig;
5300 } else {
5301 no_triggers:
5302 cfg80211_rdev_free_wowlan(rdev);
5303 rdev->wowlan = NULL;
5304 }
5305
5306 return 0;
5307 error:
5308 for (i = 0; i < new_triggers.n_patterns; i++)
5309 kfree(new_triggers.patterns[i].mask);
5310 kfree(new_triggers.patterns);
5311 return err;
5312}
5313
4819#define NL80211_FLAG_NEED_WIPHY 0x01 5314#define NL80211_FLAG_NEED_WIPHY 0x01
4820#define NL80211_FLAG_NEED_NETDEV 0x02 5315#define NL80211_FLAG_NEED_NETDEV 0x02
4821#define NL80211_FLAG_NEED_RTNL 0x04 5316#define NL80211_FLAG_NEED_RTNL 0x04
@@ -5100,6 +5595,22 @@ static struct genl_ops nl80211_ops[] = {
5100 .dumpit = nl80211_dump_scan, 5595 .dumpit = nl80211_dump_scan,
5101 }, 5596 },
5102 { 5597 {
5598 .cmd = NL80211_CMD_START_SCHED_SCAN,
5599 .doit = nl80211_start_sched_scan,
5600 .policy = nl80211_policy,
5601 .flags = GENL_ADMIN_PERM,
5602 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
5603 NL80211_FLAG_NEED_RTNL,
5604 },
5605 {
5606 .cmd = NL80211_CMD_STOP_SCHED_SCAN,
5607 .doit = nl80211_stop_sched_scan,
5608 .policy = nl80211_policy,
5609 .flags = GENL_ADMIN_PERM,
5610 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
5611 NL80211_FLAG_NEED_RTNL,
5612 },
5613 {
5103 .cmd = NL80211_CMD_AUTHENTICATE, 5614 .cmd = NL80211_CMD_AUTHENTICATE,
5104 .doit = nl80211_authenticate, 5615 .doit = nl80211_authenticate,
5105 .policy = nl80211_policy, 5616 .policy = nl80211_policy,
@@ -5314,6 +5825,22 @@ static struct genl_ops nl80211_ops[] = {
5314 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | 5825 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
5315 NL80211_FLAG_NEED_RTNL, 5826 NL80211_FLAG_NEED_RTNL,
5316 }, 5827 },
5828 {
5829 .cmd = NL80211_CMD_GET_WOWLAN,
5830 .doit = nl80211_get_wowlan,
5831 .policy = nl80211_policy,
5832 /* can be retrieved by unprivileged users */
5833 .internal_flags = NL80211_FLAG_NEED_WIPHY |
5834 NL80211_FLAG_NEED_RTNL,
5835 },
5836 {
5837 .cmd = NL80211_CMD_SET_WOWLAN,
5838 .doit = nl80211_set_wowlan,
5839 .policy = nl80211_policy,
5840 .flags = GENL_ADMIN_PERM,
5841 .internal_flags = NL80211_FLAG_NEED_WIPHY |
5842 NL80211_FLAG_NEED_RTNL,
5843 },
5317}; 5844};
5318 5845
5319static struct genl_multicast_group nl80211_mlme_mcgrp = { 5846static struct genl_multicast_group nl80211_mlme_mcgrp = {
@@ -5409,6 +5936,28 @@ static int nl80211_send_scan_msg(struct sk_buff *msg,
5409 return -EMSGSIZE; 5936 return -EMSGSIZE;
5410} 5937}
5411 5938
5939static int
5940nl80211_send_sched_scan_msg(struct sk_buff *msg,
5941 struct cfg80211_registered_device *rdev,
5942 struct net_device *netdev,
5943 u32 pid, u32 seq, int flags, u32 cmd)
5944{
5945 void *hdr;
5946
5947 hdr = nl80211hdr_put(msg, pid, seq, flags, cmd);
5948 if (!hdr)
5949 return -1;
5950
5951 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
5952 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
5953
5954 return genlmsg_end(msg, hdr);
5955
5956 nla_put_failure:
5957 genlmsg_cancel(msg, hdr);
5958 return -EMSGSIZE;
5959}
5960
5412void nl80211_send_scan_start(struct cfg80211_registered_device *rdev, 5961void nl80211_send_scan_start(struct cfg80211_registered_device *rdev,
5413 struct net_device *netdev) 5962 struct net_device *netdev)
5414{ 5963{
@@ -5466,6 +6015,43 @@ void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev,
5466 nl80211_scan_mcgrp.id, GFP_KERNEL); 6015 nl80211_scan_mcgrp.id, GFP_KERNEL);
5467} 6016}
5468 6017
6018void nl80211_send_sched_scan_results(struct cfg80211_registered_device *rdev,
6019 struct net_device *netdev)
6020{
6021 struct sk_buff *msg;
6022
6023 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
6024 if (!msg)
6025 return;
6026
6027 if (nl80211_send_sched_scan_msg(msg, rdev, netdev, 0, 0, 0,
6028 NL80211_CMD_SCHED_SCAN_RESULTS) < 0) {
6029 nlmsg_free(msg);
6030 return;
6031 }
6032
6033 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
6034 nl80211_scan_mcgrp.id, GFP_KERNEL);
6035}
6036
6037void nl80211_send_sched_scan(struct cfg80211_registered_device *rdev,
6038 struct net_device *netdev, u32 cmd)
6039{
6040 struct sk_buff *msg;
6041
6042 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
6043 if (!msg)
6044 return;
6045
6046 if (nl80211_send_sched_scan_msg(msg, rdev, netdev, 0, 0, 0, cmd) < 0) {
6047 nlmsg_free(msg);
6048 return;
6049 }
6050
6051 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
6052 nl80211_scan_mcgrp.id, GFP_KERNEL);
6053}
6054
5469/* 6055/*
5470 * This can happen on global regulatory changes or device specific settings 6056 * This can happen on global regulatory changes or device specific settings
5471 * based on custom world regulatory domains. 6057 * based on custom world regulatory domains.
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h
index f2af6955a665..2f1bfb87a651 100644
--- a/net/wireless/nl80211.h
+++ b/net/wireless/nl80211.h
@@ -12,6 +12,10 @@ void nl80211_send_scan_done(struct cfg80211_registered_device *rdev,
12 struct net_device *netdev); 12 struct net_device *netdev);
13void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev, 13void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev,
14 struct net_device *netdev); 14 struct net_device *netdev);
15void nl80211_send_sched_scan(struct cfg80211_registered_device *rdev,
16 struct net_device *netdev, u32 cmd);
17void nl80211_send_sched_scan_results(struct cfg80211_registered_device *rdev,
18 struct net_device *netdev);
15void nl80211_send_reg_change_event(struct regulatory_request *request); 19void nl80211_send_reg_change_event(struct regulatory_request *request);
16void nl80211_send_rx_auth(struct cfg80211_registered_device *rdev, 20void nl80211_send_rx_auth(struct cfg80211_registered_device *rdev,
17 struct net_device *netdev, 21 struct net_device *netdev,
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 1613080a96b9..1ad0f39fe091 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -672,11 +672,9 @@ static int freq_reg_info_regd(struct wiphy *wiphy,
672 for (i = 0; i < regd->n_reg_rules; i++) { 672 for (i = 0; i < regd->n_reg_rules; i++) {
673 const struct ieee80211_reg_rule *rr; 673 const struct ieee80211_reg_rule *rr;
674 const struct ieee80211_freq_range *fr = NULL; 674 const struct ieee80211_freq_range *fr = NULL;
675 const struct ieee80211_power_rule *pr = NULL;
676 675
677 rr = &regd->reg_rules[i]; 676 rr = &regd->reg_rules[i];
678 fr = &rr->freq_range; 677 fr = &rr->freq_range;
679 pr = &rr->power_rule;
680 678
681 /* 679 /*
682 * We only need to know if one frequency rule was 680 * We only need to know if one frequency rule was
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index fbf6f33ae4d0..73a441d237b5 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -93,6 +93,69 @@ void cfg80211_scan_done(struct cfg80211_scan_request *request, bool aborted)
93} 93}
94EXPORT_SYMBOL(cfg80211_scan_done); 94EXPORT_SYMBOL(cfg80211_scan_done);
95 95
96void __cfg80211_sched_scan_results(struct work_struct *wk)
97{
98 struct cfg80211_registered_device *rdev;
99
100 rdev = container_of(wk, struct cfg80211_registered_device,
101 sched_scan_results_wk);
102
103 cfg80211_lock_rdev(rdev);
104
105 /* we don't have sched_scan_req anymore if the scan is stopping */
106 if (rdev->sched_scan_req)
107 nl80211_send_sched_scan_results(rdev,
108 rdev->sched_scan_req->dev);
109
110 cfg80211_unlock_rdev(rdev);
111}
112
113void cfg80211_sched_scan_results(struct wiphy *wiphy)
114{
115 /* ignore if we're not scanning */
116 if (wiphy_to_dev(wiphy)->sched_scan_req)
117 queue_work(cfg80211_wq,
118 &wiphy_to_dev(wiphy)->sched_scan_results_wk);
119}
120EXPORT_SYMBOL(cfg80211_sched_scan_results);
121
122void cfg80211_sched_scan_stopped(struct wiphy *wiphy)
123{
124 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
125
126 cfg80211_lock_rdev(rdev);
127 __cfg80211_stop_sched_scan(rdev, true);
128 cfg80211_unlock_rdev(rdev);
129}
130EXPORT_SYMBOL(cfg80211_sched_scan_stopped);
131
132int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev,
133 bool driver_initiated)
134{
135 int err;
136 struct net_device *dev;
137
138 ASSERT_RDEV_LOCK(rdev);
139
140 if (!rdev->sched_scan_req)
141 return 0;
142
143 dev = rdev->sched_scan_req->dev;
144
145 if (!driver_initiated) {
146 err = rdev->ops->sched_scan_stop(&rdev->wiphy, dev);
147 if (err)
148 return err;
149 }
150
151 nl80211_send_sched_scan(rdev, dev, NL80211_CMD_SCHED_SCAN_STOPPED);
152
153 kfree(rdev->sched_scan_req);
154 rdev->sched_scan_req = NULL;
155
156 return err;
157}
158
96static void bss_release(struct kref *ref) 159static void bss_release(struct kref *ref)
97{ 160{
98 struct cfg80211_internal_bss *bss; 161 struct cfg80211_internal_bss *bss;
@@ -210,7 +273,7 @@ static bool is_mesh(struct cfg80211_bss *a,
210{ 273{
211 const u8 *ie; 274 const u8 *ie;
212 275
213 if (!is_zero_ether_addr(a->bssid)) 276 if (!WLAN_CAPABILITY_IS_MBSS(a->capability))
214 return false; 277 return false;
215 278
216 ie = cfg80211_find_ie(WLAN_EID_MESH_ID, 279 ie = cfg80211_find_ie(WLAN_EID_MESH_ID,
@@ -248,11 +311,7 @@ static int cmp_bss(struct cfg80211_bss *a,
248 if (a->channel != b->channel) 311 if (a->channel != b->channel)
249 return b->channel->center_freq - a->channel->center_freq; 312 return b->channel->center_freq - a->channel->center_freq;
250 313
251 r = memcmp(a->bssid, b->bssid, ETH_ALEN); 314 if (WLAN_CAPABILITY_IS_MBSS(a->capability | b->capability)) {
252 if (r)
253 return r;
254
255 if (is_zero_ether_addr(a->bssid)) {
256 r = cmp_ies(WLAN_EID_MESH_ID, 315 r = cmp_ies(WLAN_EID_MESH_ID,
257 a->information_elements, 316 a->information_elements,
258 a->len_information_elements, 317 a->len_information_elements,
@@ -267,6 +326,10 @@ static int cmp_bss(struct cfg80211_bss *a,
267 b->len_information_elements); 326 b->len_information_elements);
268 } 327 }
269 328
329 r = memcmp(a->bssid, b->bssid, ETH_ALEN);
330 if (r)
331 return r;
332
270 return cmp_ies(WLAN_EID_SSID, 333 return cmp_ies(WLAN_EID_SSID,
271 a->information_elements, 334 a->information_elements,
272 a->len_information_elements, 335 a->len_information_elements,
@@ -407,7 +470,7 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev,
407 470
408 res->ts = jiffies; 471 res->ts = jiffies;
409 472
410 if (is_zero_ether_addr(res->pub.bssid)) { 473 if (WLAN_CAPABILITY_IS_MBSS(res->pub.capability)) {
411 /* must be mesh, verify */ 474 /* must be mesh, verify */
412 meshid = cfg80211_find_ie(WLAN_EID_MESH_ID, 475 meshid = cfg80211_find_ie(WLAN_EID_MESH_ID,
413 res->pub.information_elements, 476 res->pub.information_elements,
diff --git a/net/wireless/sysfs.c b/net/wireless/sysfs.c
index 4294fa22bb2d..c6e4ca6a7d2e 100644
--- a/net/wireless/sysfs.c
+++ b/net/wireless/sysfs.c
@@ -93,7 +93,7 @@ static int wiphy_suspend(struct device *dev, pm_message_t state)
93 93
94 if (rdev->ops->suspend) { 94 if (rdev->ops->suspend) {
95 rtnl_lock(); 95 rtnl_lock();
96 ret = rdev->ops->suspend(&rdev->wiphy); 96 ret = rdev->ops->suspend(&rdev->wiphy, rdev->wowlan);
97 rtnl_unlock(); 97 rtnl_unlock();
98 } 98 }
99 99
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 6a750bc6bcfe..f0536d44d43c 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -544,7 +544,8 @@ EXPORT_SYMBOL(ieee80211_data_from_8023);
544 544
545void ieee80211_amsdu_to_8023s(struct sk_buff *skb, struct sk_buff_head *list, 545void ieee80211_amsdu_to_8023s(struct sk_buff *skb, struct sk_buff_head *list,
546 const u8 *addr, enum nl80211_iftype iftype, 546 const u8 *addr, enum nl80211_iftype iftype,
547 const unsigned int extra_headroom) 547 const unsigned int extra_headroom,
548 bool has_80211_header)
548{ 549{
549 struct sk_buff *frame = NULL; 550 struct sk_buff *frame = NULL;
550 u16 ethertype; 551 u16 ethertype;
@@ -553,14 +554,18 @@ void ieee80211_amsdu_to_8023s(struct sk_buff *skb, struct sk_buff_head *list,
553 int remaining, err; 554 int remaining, err;
554 u8 dst[ETH_ALEN], src[ETH_ALEN]; 555 u8 dst[ETH_ALEN], src[ETH_ALEN];
555 556
556 err = ieee80211_data_to_8023(skb, addr, iftype); 557 if (has_80211_header) {
557 if (err) 558 err = ieee80211_data_to_8023(skb, addr, iftype);
558 goto out; 559 if (err)
560 goto out;
559 561
560 /* skip the wrapping header */ 562 /* skip the wrapping header */
561 eth = (struct ethhdr *) skb_pull(skb, sizeof(struct ethhdr)); 563 eth = (struct ethhdr *) skb_pull(skb, sizeof(struct ethhdr));
562 if (!eth) 564 if (!eth)
563 goto out; 565 goto out;
566 } else {
567 eth = (struct ethhdr *) skb->data;
568 }
564 569
565 while (skb != frame) { 570 while (skb != frame) {
566 u8 padding; 571 u8 padding;
@@ -803,6 +808,11 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
803 return -EBUSY; 808 return -EBUSY;
804 809
805 if (ntype != otype) { 810 if (ntype != otype) {
811 err = cfg80211_can_change_interface(rdev, dev->ieee80211_ptr,
812 ntype);
813 if (err)
814 return err;
815
806 dev->ieee80211_ptr->use_4addr = false; 816 dev->ieee80211_ptr->use_4addr = false;
807 dev->ieee80211_ptr->mesh_id_up_len = 0; 817 dev->ieee80211_ptr->mesh_id_up_len = 0;
808 818
@@ -896,3 +906,103 @@ u16 cfg80211_calculate_bitrate(struct rate_info *rate)
896 /* do NOT round down here */ 906 /* do NOT round down here */
897 return (bitrate + 50000) / 100000; 907 return (bitrate + 50000) / 100000;
898} 908}
909
910int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev,
911 u32 beacon_int)
912{
913 struct wireless_dev *wdev;
914 int res = 0;
915
916 if (!beacon_int)
917 return -EINVAL;
918
919 mutex_lock(&rdev->devlist_mtx);
920
921 list_for_each_entry(wdev, &rdev->netdev_list, list) {
922 if (!wdev->beacon_interval)
923 continue;
924 if (wdev->beacon_interval != beacon_int) {
925 res = -EINVAL;
926 break;
927 }
928 }
929
930 mutex_unlock(&rdev->devlist_mtx);
931
932 return res;
933}
934
935int cfg80211_can_change_interface(struct cfg80211_registered_device *rdev,
936 struct wireless_dev *wdev,
937 enum nl80211_iftype iftype)
938{
939 struct wireless_dev *wdev_iter;
940 int num[NUM_NL80211_IFTYPES];
941 int total = 1;
942 int i, j;
943
944 ASSERT_RTNL();
945
946 /* Always allow software iftypes */
947 if (rdev->wiphy.software_iftypes & BIT(iftype))
948 return 0;
949
950 /*
951 * Drivers will gradually all set this flag, until all
952 * have it we only enforce for those that set it.
953 */
954 if (!(rdev->wiphy.flags & WIPHY_FLAG_ENFORCE_COMBINATIONS))
955 return 0;
956
957 memset(num, 0, sizeof(num));
958
959 num[iftype] = 1;
960
961 mutex_lock(&rdev->devlist_mtx);
962 list_for_each_entry(wdev_iter, &rdev->netdev_list, list) {
963 if (wdev_iter == wdev)
964 continue;
965 if (!netif_running(wdev_iter->netdev))
966 continue;
967
968 if (rdev->wiphy.software_iftypes & BIT(wdev_iter->iftype))
969 continue;
970
971 num[wdev_iter->iftype]++;
972 total++;
973 }
974 mutex_unlock(&rdev->devlist_mtx);
975
976 for (i = 0; i < rdev->wiphy.n_iface_combinations; i++) {
977 const struct ieee80211_iface_combination *c;
978 struct ieee80211_iface_limit *limits;
979
980 c = &rdev->wiphy.iface_combinations[i];
981
982 limits = kmemdup(c->limits, sizeof(limits[0]) * c->n_limits,
983 GFP_KERNEL);
984 if (!limits)
985 return -ENOMEM;
986 if (total > c->max_interfaces)
987 goto cont;
988
989 for (iftype = 0; iftype < NUM_NL80211_IFTYPES; iftype++) {
990 if (rdev->wiphy.software_iftypes & BIT(iftype))
991 continue;
992 for (j = 0; j < c->n_limits; j++) {
993 if (!(limits[j].types & iftype))
994 continue;
995 if (limits[j].max < num[iftype])
996 goto cont;
997 limits[j].max -= num[iftype];
998 }
999 }
1000 /* yay, it fits */
1001 kfree(limits);
1002 return 0;
1003 cont:
1004 kfree(limits);
1005 }
1006
1007 return -EBUSY;
1008}
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index 88f3f07205f8..e26e2fb462d4 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -702,6 +702,24 @@ static int do_ssb_entry(const char *filename,
702 return 1; 702 return 1;
703} 703}
704 704
705/* Looks like: bcma:mNidNrevNclN. */
706static int do_bcma_entry(const char *filename,
707 struct bcma_device_id *id, char *alias)
708{
709 id->manuf = TO_NATIVE(id->manuf);
710 id->id = TO_NATIVE(id->id);
711 id->rev = TO_NATIVE(id->rev);
712 id->class = TO_NATIVE(id->class);
713
714 strcpy(alias, "bcma:");
715 ADD(alias, "m", id->manuf != BCMA_ANY_MANUF, id->manuf);
716 ADD(alias, "id", id->id != BCMA_ANY_ID, id->id);
717 ADD(alias, "rev", id->rev != BCMA_ANY_REV, id->rev);
718 ADD(alias, "cl", id->class != BCMA_ANY_CLASS, id->class);
719 add_wildcard(alias);
720 return 1;
721}
722
705/* Looks like: virtio:dNvN */ 723/* Looks like: virtio:dNvN */
706static int do_virtio_entry(const char *filename, struct virtio_device_id *id, 724static int do_virtio_entry(const char *filename, struct virtio_device_id *id,
707 char *alias) 725 char *alias)
@@ -968,6 +986,10 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
968 do_table(symval, sym->st_size, 986 do_table(symval, sym->st_size,
969 sizeof(struct ssb_device_id), "ssb", 987 sizeof(struct ssb_device_id), "ssb",
970 do_ssb_entry, mod); 988 do_ssb_entry, mod);
989 else if (sym_is(symname, "__mod_bcma_device_table"))
990 do_table(symval, sym->st_size,
991 sizeof(struct bcma_device_id), "bcma",
992 do_bcma_entry, mod);
971 else if (sym_is(symname, "__mod_virtio_device_table")) 993 else if (sym_is(symname, "__mod_virtio_device_table"))
972 do_table(symval, sym->st_size, 994 do_table(symval, sym->st_size,
973 sizeof(struct virtio_device_id), "virtio", 995 sizeof(struct virtio_device_id), "virtio",