aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-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
152 files changed, 15866 insertions, 1533 deletions
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 */