aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/Kconfig3
-rw-r--r--drivers/net/wireless/Makefile4
-rw-r--r--drivers/net/wireless/ti/Kconfig14
-rw-r--r--drivers/net/wireless/ti/Makefile4
-rw-r--r--drivers/net/wireless/ti/wl1251/Kconfig (renamed from drivers/net/wireless/wl1251/Kconfig)0
-rw-r--r--drivers/net/wireless/ti/wl1251/Makefile (renamed from drivers/net/wireless/wl1251/Makefile)0
-rw-r--r--drivers/net/wireless/ti/wl1251/acx.c (renamed from drivers/net/wireless/wl1251/acx.c)0
-rw-r--r--drivers/net/wireless/ti/wl1251/acx.h (renamed from drivers/net/wireless/wl1251/acx.h)0
-rw-r--r--drivers/net/wireless/ti/wl1251/boot.c (renamed from drivers/net/wireless/wl1251/boot.c)0
-rw-r--r--drivers/net/wireless/ti/wl1251/boot.h (renamed from drivers/net/wireless/wl1251/boot.h)0
-rw-r--r--drivers/net/wireless/ti/wl1251/cmd.c (renamed from drivers/net/wireless/wl1251/cmd.c)0
-rw-r--r--drivers/net/wireless/ti/wl1251/cmd.h (renamed from drivers/net/wireless/wl1251/cmd.h)0
-rw-r--r--drivers/net/wireless/ti/wl1251/debugfs.c (renamed from drivers/net/wireless/wl1251/debugfs.c)0
-rw-r--r--drivers/net/wireless/ti/wl1251/debugfs.h (renamed from drivers/net/wireless/wl1251/debugfs.h)0
-rw-r--r--drivers/net/wireless/ti/wl1251/event.c (renamed from drivers/net/wireless/wl1251/event.c)0
-rw-r--r--drivers/net/wireless/ti/wl1251/event.h (renamed from drivers/net/wireless/wl1251/event.h)0
-rw-r--r--drivers/net/wireless/ti/wl1251/init.c (renamed from drivers/net/wireless/wl1251/init.c)0
-rw-r--r--drivers/net/wireless/ti/wl1251/init.h (renamed from drivers/net/wireless/wl1251/init.h)0
-rw-r--r--drivers/net/wireless/ti/wl1251/io.c (renamed from drivers/net/wireless/wl1251/io.c)0
-rw-r--r--drivers/net/wireless/ti/wl1251/io.h (renamed from drivers/net/wireless/wl1251/io.h)0
-rw-r--r--drivers/net/wireless/ti/wl1251/main.c (renamed from drivers/net/wireless/wl1251/main.c)0
-rw-r--r--drivers/net/wireless/ti/wl1251/ps.c (renamed from drivers/net/wireless/wl1251/ps.c)0
-rw-r--r--drivers/net/wireless/ti/wl1251/ps.h (renamed from drivers/net/wireless/wl1251/ps.h)0
-rw-r--r--drivers/net/wireless/ti/wl1251/reg.h (renamed from drivers/net/wireless/wl1251/reg.h)0
-rw-r--r--drivers/net/wireless/ti/wl1251/rx.c (renamed from drivers/net/wireless/wl1251/rx.c)0
-rw-r--r--drivers/net/wireless/ti/wl1251/rx.h (renamed from drivers/net/wireless/wl1251/rx.h)0
-rw-r--r--drivers/net/wireless/ti/wl1251/sdio.c (renamed from drivers/net/wireless/wl1251/sdio.c)0
-rw-r--r--drivers/net/wireless/ti/wl1251/spi.c (renamed from drivers/net/wireless/wl1251/spi.c)0
-rw-r--r--drivers/net/wireless/ti/wl1251/spi.h (renamed from drivers/net/wireless/wl1251/spi.h)0
-rw-r--r--drivers/net/wireless/ti/wl1251/tx.c (renamed from drivers/net/wireless/wl1251/tx.c)0
-rw-r--r--drivers/net/wireless/ti/wl1251/tx.h (renamed from drivers/net/wireless/wl1251/tx.h)0
-rw-r--r--drivers/net/wireless/ti/wl1251/wl1251.h (renamed from drivers/net/wireless/wl1251/wl1251.h)0
-rw-r--r--drivers/net/wireless/ti/wl1251/wl12xx_80211.h (renamed from drivers/net/wireless/wl1251/wl12xx_80211.h)0
-rw-r--r--drivers/net/wireless/ti/wl12xx/Kconfig8
-rw-r--r--drivers/net/wireless/ti/wl12xx/Makefile3
-rw-r--r--drivers/net/wireless/ti/wl12xx/acx.c53
-rw-r--r--drivers/net/wireless/ti/wl12xx/acx.h36
-rw-r--r--drivers/net/wireless/ti/wl12xx/cmd.c254
-rw-r--r--drivers/net/wireless/ti/wl12xx/cmd.h112
-rw-r--r--drivers/net/wireless/ti/wl12xx/conf.h50
-rw-r--r--drivers/net/wireless/ti/wl12xx/main.c1388
-rw-r--r--drivers/net/wireless/ti/wl12xx/reg.h (renamed from drivers/net/wireless/wl12xx/reg.h)315
-rw-r--r--drivers/net/wireless/ti/wl12xx/wl12xx.h31
-rw-r--r--drivers/net/wireless/ti/wlcore/Kconfig41
-rw-r--r--drivers/net/wireless/ti/wlcore/Makefile15
-rw-r--r--drivers/net/wireless/ti/wlcore/acx.c (renamed from drivers/net/wireless/wl12xx/acx.c)42
-rw-r--r--drivers/net/wireless/ti/wlcore/acx.h (renamed from drivers/net/wireless/wl12xx/acx.h)10
-rw-r--r--drivers/net/wireless/ti/wlcore/boot.c443
-rw-r--r--drivers/net/wireless/ti/wlcore/boot.h54
-rw-r--r--drivers/net/wireless/ti/wlcore/cmd.c (renamed from drivers/net/wireless/wl12xx/cmd.c)285
-rw-r--r--drivers/net/wireless/ti/wlcore/cmd.h (renamed from drivers/net/wireless/wl12xx/cmd.h)98
-rw-r--r--drivers/net/wireless/ti/wlcore/conf.h (renamed from drivers/net/wireless/wl12xx/conf.h)85
-rw-r--r--drivers/net/wireless/ti/wlcore/debug.h (renamed from drivers/net/wireless/wl12xx/debug.h)1
-rw-r--r--drivers/net/wireless/ti/wlcore/debugfs.c (renamed from drivers/net/wireless/wl12xx/debugfs.c)3
-rw-r--r--drivers/net/wireless/ti/wlcore/debugfs.h (renamed from drivers/net/wireless/wl12xx/debugfs.h)2
-rw-r--r--drivers/net/wireless/ti/wlcore/event.c (renamed from drivers/net/wireless/wl12xx/event.c)31
-rw-r--r--drivers/net/wireless/ti/wlcore/event.h (renamed from drivers/net/wireless/wl12xx/event.h)3
-rw-r--r--drivers/net/wireless/ti/wlcore/hw_ops.h122
-rw-r--r--drivers/net/wireless/ti/wlcore/ini.h (renamed from drivers/net/wireless/wl12xx/ini.h)0
-rw-r--r--drivers/net/wireless/ti/wlcore/init.c (renamed from drivers/net/wireless/wl12xx/init.c)66
-rw-r--r--drivers/net/wireless/ti/wlcore/init.h (renamed from drivers/net/wireless/wl12xx/init.h)2
-rw-r--r--drivers/net/wireless/ti/wlcore/io.c (renamed from drivers/net/wireless/wl12xx/io.c)191
-rw-r--r--drivers/net/wireless/ti/wlcore/io.h (renamed from drivers/net/wireless/wl12xx/io.h)88
-rw-r--r--drivers/net/wireless/ti/wlcore/main.c (renamed from drivers/net/wireless/wl12xx/main.c)821
-rw-r--r--drivers/net/wireless/ti/wlcore/ps.c (renamed from drivers/net/wireless/wl12xx/ps.c)8
-rw-r--r--drivers/net/wireless/ti/wlcore/ps.h (renamed from drivers/net/wireless/wl12xx/ps.h)2
-rw-r--r--drivers/net/wireless/ti/wlcore/rx.c (renamed from drivers/net/wireless/wl12xx/rx.c)130
-rw-r--r--drivers/net/wireless/ti/wlcore/rx.h (renamed from drivers/net/wireless/wl12xx/rx.h)12
-rw-r--r--drivers/net/wireless/ti/wlcore/scan.c (renamed from drivers/net/wireless/wl12xx/scan.c)30
-rw-r--r--drivers/net/wireless/ti/wlcore/scan.h (renamed from drivers/net/wireless/wl12xx/scan.h)4
-rw-r--r--drivers/net/wireless/ti/wlcore/sdio.c (renamed from drivers/net/wireless/wl12xx/sdio.c)6
-rw-r--r--drivers/net/wireless/ti/wlcore/spi.c (renamed from drivers/net/wireless/wl12xx/spi.c)4
-rw-r--r--drivers/net/wireless/ti/wlcore/testmode.c (renamed from drivers/net/wireless/wl12xx/testmode.c)3
-rw-r--r--drivers/net/wireless/ti/wlcore/testmode.h (renamed from drivers/net/wireless/wl12xx/testmode.h)0
-rw-r--r--drivers/net/wireless/ti/wlcore/tx.c (renamed from drivers/net/wireless/wl12xx/tx.c)125
-rw-r--r--drivers/net/wireless/ti/wlcore/tx.h (renamed from drivers/net/wireless/wl12xx/tx.h)7
-rw-r--r--drivers/net/wireless/ti/wlcore/wl12xx.h (renamed from drivers/net/wireless/wl12xx/wl12xx.h)271
-rw-r--r--drivers/net/wireless/ti/wlcore/wl12xx_80211.h (renamed from drivers/net/wireless/wl12xx/wl12xx_80211.h)0
-rw-r--r--drivers/net/wireless/ti/wlcore/wl12xx_platform_data.c (renamed from drivers/net/wireless/wl12xx/wl12xx_platform_data.c)0
-rw-r--r--drivers/net/wireless/ti/wlcore/wlcore.h448
-rw-r--r--drivers/net/wireless/wl12xx/Kconfig48
-rw-r--r--drivers/net/wireless/wl12xx/Makefile15
-rw-r--r--drivers/net/wireless/wl12xx/boot.c786
-rw-r--r--drivers/net/wireless/wl12xx/boot.h120
84 files changed, 3790 insertions, 2907 deletions
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index abd3b71cd4ab..5f58fa53238c 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -282,8 +282,7 @@ source "drivers/net/wireless/orinoco/Kconfig"
282source "drivers/net/wireless/p54/Kconfig" 282source "drivers/net/wireless/p54/Kconfig"
283source "drivers/net/wireless/rt2x00/Kconfig" 283source "drivers/net/wireless/rt2x00/Kconfig"
284source "drivers/net/wireless/rtlwifi/Kconfig" 284source "drivers/net/wireless/rtlwifi/Kconfig"
285source "drivers/net/wireless/wl1251/Kconfig" 285source "drivers/net/wireless/ti/Kconfig"
286source "drivers/net/wireless/wl12xx/Kconfig"
287source "drivers/net/wireless/zd1211rw/Kconfig" 286source "drivers/net/wireless/zd1211rw/Kconfig"
288source "drivers/net/wireless/mwifiex/Kconfig" 287source "drivers/net/wireless/mwifiex/Kconfig"
289 288
diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile
index 98db76196b59..0ce218b931d4 100644
--- a/drivers/net/wireless/Makefile
+++ b/drivers/net/wireless/Makefile
@@ -51,9 +51,7 @@ obj-$(CONFIG_ATH_COMMON) += ath/
51 51
52obj-$(CONFIG_MAC80211_HWSIM) += mac80211_hwsim.o 52obj-$(CONFIG_MAC80211_HWSIM) += mac80211_hwsim.o
53 53
54obj-$(CONFIG_WL1251) += wl1251/ 54obj-$(CONFIG_WL_TI) += ti/
55obj-$(CONFIG_WL12XX) += wl12xx/
56obj-$(CONFIG_WL12XX_PLATFORM_DATA) += wl12xx/
57 55
58obj-$(CONFIG_IWM) += iwmc3200wifi/ 56obj-$(CONFIG_IWM) += iwmc3200wifi/
59 57
diff --git a/drivers/net/wireless/ti/Kconfig b/drivers/net/wireless/ti/Kconfig
new file mode 100644
index 000000000000..1a72932e2213
--- /dev/null
+++ b/drivers/net/wireless/ti/Kconfig
@@ -0,0 +1,14 @@
1menuconfig WL_TI
2 bool "TI Wireless LAN support"
3 ---help---
4 This section contains support for all the wireless drivers
5 for Texas Instruments WLAN chips, such as wl1251 and the wl12xx
6 family.
7
8if WL_TI
9source "drivers/net/wireless/ti/wl1251/Kconfig"
10source "drivers/net/wireless/ti/wl12xx/Kconfig"
11
12# keep last for automatic dependencies
13source "drivers/net/wireless/ti/wlcore/Kconfig"
14endif # WL_TI
diff --git a/drivers/net/wireless/ti/Makefile b/drivers/net/wireless/ti/Makefile
new file mode 100644
index 000000000000..0a565622d4a4
--- /dev/null
+++ b/drivers/net/wireless/ti/Makefile
@@ -0,0 +1,4 @@
1obj-$(CONFIG_WLCORE) += wlcore/
2obj-$(CONFIG_WL12XX) += wl12xx/
3obj-$(CONFIG_WL12XX_PLATFORM_DATA) += wlcore/
4obj-$(CONFIG_WL1251) += wl1251/
diff --git a/drivers/net/wireless/wl1251/Kconfig b/drivers/net/wireless/ti/wl1251/Kconfig
index 1fb65849414f..1fb65849414f 100644
--- a/drivers/net/wireless/wl1251/Kconfig
+++ b/drivers/net/wireless/ti/wl1251/Kconfig
diff --git a/drivers/net/wireless/wl1251/Makefile b/drivers/net/wireless/ti/wl1251/Makefile
index a5c6328b5f72..a5c6328b5f72 100644
--- a/drivers/net/wireless/wl1251/Makefile
+++ b/drivers/net/wireless/ti/wl1251/Makefile
diff --git a/drivers/net/wireless/wl1251/acx.c b/drivers/net/wireless/ti/wl1251/acx.c
index ad87a1ac6462..ad87a1ac6462 100644
--- a/drivers/net/wireless/wl1251/acx.c
+++ b/drivers/net/wireless/ti/wl1251/acx.c
diff --git a/drivers/net/wireless/wl1251/acx.h b/drivers/net/wireless/ti/wl1251/acx.h
index c2ba100f9b1a..c2ba100f9b1a 100644
--- a/drivers/net/wireless/wl1251/acx.h
+++ b/drivers/net/wireless/ti/wl1251/acx.h
diff --git a/drivers/net/wireless/wl1251/boot.c b/drivers/net/wireless/ti/wl1251/boot.c
index a2e5241382da..a2e5241382da 100644
--- a/drivers/net/wireless/wl1251/boot.c
+++ b/drivers/net/wireless/ti/wl1251/boot.c
diff --git a/drivers/net/wireless/wl1251/boot.h b/drivers/net/wireless/ti/wl1251/boot.h
index 7661bc5e4662..7661bc5e4662 100644
--- a/drivers/net/wireless/wl1251/boot.h
+++ b/drivers/net/wireless/ti/wl1251/boot.h
diff --git a/drivers/net/wireless/wl1251/cmd.c b/drivers/net/wireless/ti/wl1251/cmd.c
index d14d69d733a0..d14d69d733a0 100644
--- a/drivers/net/wireless/wl1251/cmd.c
+++ b/drivers/net/wireless/ti/wl1251/cmd.c
diff --git a/drivers/net/wireless/wl1251/cmd.h b/drivers/net/wireless/ti/wl1251/cmd.h
index ee4f2b391822..ee4f2b391822 100644
--- a/drivers/net/wireless/wl1251/cmd.h
+++ b/drivers/net/wireless/ti/wl1251/cmd.h
diff --git a/drivers/net/wireless/wl1251/debugfs.c b/drivers/net/wireless/ti/wl1251/debugfs.c
index 6c274007d200..6c274007d200 100644
--- a/drivers/net/wireless/wl1251/debugfs.c
+++ b/drivers/net/wireless/ti/wl1251/debugfs.c
diff --git a/drivers/net/wireless/wl1251/debugfs.h b/drivers/net/wireless/ti/wl1251/debugfs.h
index b3417c02a218..b3417c02a218 100644
--- a/drivers/net/wireless/wl1251/debugfs.h
+++ b/drivers/net/wireless/ti/wl1251/debugfs.h
diff --git a/drivers/net/wireless/wl1251/event.c b/drivers/net/wireless/ti/wl1251/event.c
index 9f15ccaf8f05..9f15ccaf8f05 100644
--- a/drivers/net/wireless/wl1251/event.c
+++ b/drivers/net/wireless/ti/wl1251/event.c
diff --git a/drivers/net/wireless/wl1251/event.h b/drivers/net/wireless/ti/wl1251/event.h
index 30eb5d150bf7..30eb5d150bf7 100644
--- a/drivers/net/wireless/wl1251/event.h
+++ b/drivers/net/wireless/ti/wl1251/event.h
diff --git a/drivers/net/wireless/wl1251/init.c b/drivers/net/wireless/ti/wl1251/init.c
index 89b43d35473c..89b43d35473c 100644
--- a/drivers/net/wireless/wl1251/init.c
+++ b/drivers/net/wireless/ti/wl1251/init.c
diff --git a/drivers/net/wireless/wl1251/init.h b/drivers/net/wireless/ti/wl1251/init.h
index 543f17582ead..543f17582ead 100644
--- a/drivers/net/wireless/wl1251/init.h
+++ b/drivers/net/wireless/ti/wl1251/init.h
diff --git a/drivers/net/wireless/wl1251/io.c b/drivers/net/wireless/ti/wl1251/io.c
index cdcadbf6ac2c..cdcadbf6ac2c 100644
--- a/drivers/net/wireless/wl1251/io.c
+++ b/drivers/net/wireless/ti/wl1251/io.c
diff --git a/drivers/net/wireless/wl1251/io.h b/drivers/net/wireless/ti/wl1251/io.h
index d382877c34cc..d382877c34cc 100644
--- a/drivers/net/wireless/wl1251/io.h
+++ b/drivers/net/wireless/ti/wl1251/io.h
diff --git a/drivers/net/wireless/wl1251/main.c b/drivers/net/wireless/ti/wl1251/main.c
index 41302c7b1ad0..41302c7b1ad0 100644
--- a/drivers/net/wireless/wl1251/main.c
+++ b/drivers/net/wireless/ti/wl1251/main.c
diff --git a/drivers/net/wireless/wl1251/ps.c b/drivers/net/wireless/ti/wl1251/ps.c
index db719f7d2692..db719f7d2692 100644
--- a/drivers/net/wireless/wl1251/ps.c
+++ b/drivers/net/wireless/ti/wl1251/ps.c
diff --git a/drivers/net/wireless/wl1251/ps.h b/drivers/net/wireless/ti/wl1251/ps.h
index 75efad246d67..75efad246d67 100644
--- a/drivers/net/wireless/wl1251/ps.h
+++ b/drivers/net/wireless/ti/wl1251/ps.h
diff --git a/drivers/net/wireless/wl1251/reg.h b/drivers/net/wireless/ti/wl1251/reg.h
index a5809019c5c1..a5809019c5c1 100644
--- a/drivers/net/wireless/wl1251/reg.h
+++ b/drivers/net/wireless/ti/wl1251/reg.h
diff --git a/drivers/net/wireless/wl1251/rx.c b/drivers/net/wireless/ti/wl1251/rx.c
index 6af35265c900..6af35265c900 100644
--- a/drivers/net/wireless/wl1251/rx.c
+++ b/drivers/net/wireless/ti/wl1251/rx.c
diff --git a/drivers/net/wireless/wl1251/rx.h b/drivers/net/wireless/ti/wl1251/rx.h
index 4448f635a4d8..4448f635a4d8 100644
--- a/drivers/net/wireless/wl1251/rx.h
+++ b/drivers/net/wireless/ti/wl1251/rx.h
diff --git a/drivers/net/wireless/wl1251/sdio.c b/drivers/net/wireless/ti/wl1251/sdio.c
index f78694295c39..f78694295c39 100644
--- a/drivers/net/wireless/wl1251/sdio.c
+++ b/drivers/net/wireless/ti/wl1251/sdio.c
diff --git a/drivers/net/wireless/wl1251/spi.c b/drivers/net/wireless/ti/wl1251/spi.c
index 6248c354fc5c..6248c354fc5c 100644
--- a/drivers/net/wireless/wl1251/spi.c
+++ b/drivers/net/wireless/ti/wl1251/spi.c
diff --git a/drivers/net/wireless/wl1251/spi.h b/drivers/net/wireless/ti/wl1251/spi.h
index 16d506955cc0..16d506955cc0 100644
--- a/drivers/net/wireless/wl1251/spi.h
+++ b/drivers/net/wireless/ti/wl1251/spi.h
diff --git a/drivers/net/wireless/wl1251/tx.c b/drivers/net/wireless/ti/wl1251/tx.c
index 28121c590a2b..28121c590a2b 100644
--- a/drivers/net/wireless/wl1251/tx.c
+++ b/drivers/net/wireless/ti/wl1251/tx.c
diff --git a/drivers/net/wireless/wl1251/tx.h b/drivers/net/wireless/ti/wl1251/tx.h
index 81338d39b43e..81338d39b43e 100644
--- a/drivers/net/wireless/wl1251/tx.h
+++ b/drivers/net/wireless/ti/wl1251/tx.h
diff --git a/drivers/net/wireless/wl1251/wl1251.h b/drivers/net/wireless/ti/wl1251/wl1251.h
index 9d8f5816c6f9..9d8f5816c6f9 100644
--- a/drivers/net/wireless/wl1251/wl1251.h
+++ b/drivers/net/wireless/ti/wl1251/wl1251.h
diff --git a/drivers/net/wireless/wl1251/wl12xx_80211.h b/drivers/net/wireless/ti/wl1251/wl12xx_80211.h
index 04ed51495772..04ed51495772 100644
--- a/drivers/net/wireless/wl1251/wl12xx_80211.h
+++ b/drivers/net/wireless/ti/wl1251/wl12xx_80211.h
diff --git a/drivers/net/wireless/ti/wl12xx/Kconfig b/drivers/net/wireless/ti/wl12xx/Kconfig
new file mode 100644
index 000000000000..5b92329122c4
--- /dev/null
+++ b/drivers/net/wireless/ti/wl12xx/Kconfig
@@ -0,0 +1,8 @@
1config WL12XX
2 tristate "TI wl12xx support"
3 select WLCORE
4 ---help---
5 This module adds support for wireless adapters based on TI wl1271,
6 wl1273, wl1281 and wl1283 chipsets. This module does *not* include
7 support for wl1251. For wl1251 support, use the separate homonymous
8 driver instead.
diff --git a/drivers/net/wireless/ti/wl12xx/Makefile b/drivers/net/wireless/ti/wl12xx/Makefile
new file mode 100644
index 000000000000..87f64b14db35
--- /dev/null
+++ b/drivers/net/wireless/ti/wl12xx/Makefile
@@ -0,0 +1,3 @@
1wl12xx-objs = main.o cmd.o acx.o
2
3obj-$(CONFIG_WL12XX) += wl12xx.o
diff --git a/drivers/net/wireless/ti/wl12xx/acx.c b/drivers/net/wireless/ti/wl12xx/acx.c
new file mode 100644
index 000000000000..bea06b2d7bf4
--- /dev/null
+++ b/drivers/net/wireless/ti/wl12xx/acx.c
@@ -0,0 +1,53 @@
1/*
2 * This file is part of wl12xx
3 *
4 * Copyright (C) 2008-2009 Nokia Corporation
5 * Copyright (C) 2011 Texas Instruments Inc.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * version 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
19 * 02110-1301 USA
20 *
21 */
22
23#include "../wlcore/cmd.h"
24#include "../wlcore/debug.h"
25#include "../wlcore/acx.h"
26
27#include "acx.h"
28
29int wl1271_acx_host_if_cfg_bitmap(struct wl1271 *wl, u32 host_cfg_bitmap)
30{
31 struct wl1271_acx_host_config_bitmap *bitmap_conf;
32 int ret;
33
34 bitmap_conf = kzalloc(sizeof(*bitmap_conf), GFP_KERNEL);
35 if (!bitmap_conf) {
36 ret = -ENOMEM;
37 goto out;
38 }
39
40 bitmap_conf->host_cfg_bitmap = cpu_to_le32(host_cfg_bitmap);
41
42 ret = wl1271_cmd_configure(wl, ACX_HOST_IF_CFG_BITMAP,
43 bitmap_conf, sizeof(*bitmap_conf));
44 if (ret < 0) {
45 wl1271_warning("wl1271 bitmap config opt failed: %d", ret);
46 goto out;
47 }
48
49out:
50 kfree(bitmap_conf);
51
52 return ret;
53}
diff --git a/drivers/net/wireless/ti/wl12xx/acx.h b/drivers/net/wireless/ti/wl12xx/acx.h
new file mode 100644
index 000000000000..d1f5aba0afce
--- /dev/null
+++ b/drivers/net/wireless/ti/wl12xx/acx.h
@@ -0,0 +1,36 @@
1/*
2 * This file is part of wl12xx
3 *
4 * Copyright (C) 1998-2009, 2011 Texas Instruments. All rights reserved.
5 * Copyright (C) 2008-2010 Nokia Corporation
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * version 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
19 * 02110-1301 USA
20 *
21 */
22
23#ifndef __WL12XX_ACX_H__
24#define __WL12XX_ACX_H__
25
26#include "../wlcore/wlcore.h"
27
28struct wl1271_acx_host_config_bitmap {
29 struct acx_header header;
30
31 __le32 host_cfg_bitmap;
32} __packed;
33
34int wl1271_acx_host_if_cfg_bitmap(struct wl1271 *wl, u32 host_cfg_bitmap);
35
36#endif /* __WL12XX_ACX_H__ */
diff --git a/drivers/net/wireless/ti/wl12xx/cmd.c b/drivers/net/wireless/ti/wl12xx/cmd.c
new file mode 100644
index 000000000000..8ffaeb5f2147
--- /dev/null
+++ b/drivers/net/wireless/ti/wl12xx/cmd.c
@@ -0,0 +1,254 @@
1/*
2 * This file is part of wl12xx
3 *
4 * Copyright (C) 2009-2010 Nokia Corporation
5 * Copyright (C) 2011 Texas Instruments Inc.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * version 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
19 * 02110-1301 USA
20 *
21 */
22
23#include "../wlcore/cmd.h"
24#include "../wlcore/debug.h"
25
26#include "wl12xx.h"
27#include "cmd.h"
28
29int wl1271_cmd_ext_radio_parms(struct wl1271 *wl)
30{
31 struct wl1271_ext_radio_parms_cmd *ext_radio_parms;
32 struct wl12xx_priv *priv = wl->priv;
33 struct wl12xx_conf_rf *rf = &priv->conf.rf;
34 int ret;
35
36 if (!wl->nvs)
37 return -ENODEV;
38
39 ext_radio_parms = kzalloc(sizeof(*ext_radio_parms), GFP_KERNEL);
40 if (!ext_radio_parms)
41 return -ENOMEM;
42
43 ext_radio_parms->test.id = TEST_CMD_INI_FILE_RF_EXTENDED_PARAM;
44
45 memcpy(ext_radio_parms->tx_per_channel_power_compensation_2,
46 rf->tx_per_channel_power_compensation_2,
47 CONF_TX_PWR_COMPENSATION_LEN_2);
48 memcpy(ext_radio_parms->tx_per_channel_power_compensation_5,
49 rf->tx_per_channel_power_compensation_5,
50 CONF_TX_PWR_COMPENSATION_LEN_5);
51
52 wl1271_dump(DEBUG_CMD, "TEST_CMD_INI_FILE_EXT_RADIO_PARAM: ",
53 ext_radio_parms, sizeof(*ext_radio_parms));
54
55 ret = wl1271_cmd_test(wl, ext_radio_parms, sizeof(*ext_radio_parms), 0);
56 if (ret < 0)
57 wl1271_warning("TEST_CMD_INI_FILE_RF_EXTENDED_PARAM failed");
58
59 kfree(ext_radio_parms);
60 return ret;
61}
62
63int wl1271_cmd_general_parms(struct wl1271 *wl)
64{
65 struct wl1271_general_parms_cmd *gen_parms;
66 struct wl1271_ini_general_params *gp =
67 &((struct wl1271_nvs_file *)wl->nvs)->general_params;
68 bool answer = false;
69 int ret;
70
71 if (!wl->nvs)
72 return -ENODEV;
73
74 if (gp->tx_bip_fem_manufacturer >= WL1271_INI_FEM_MODULE_COUNT) {
75 wl1271_warning("FEM index from INI out of bounds");
76 return -EINVAL;
77 }
78
79 gen_parms = kzalloc(sizeof(*gen_parms), GFP_KERNEL);
80 if (!gen_parms)
81 return -ENOMEM;
82
83 gen_parms->test.id = TEST_CMD_INI_FILE_GENERAL_PARAM;
84
85 memcpy(&gen_parms->general_params, gp, sizeof(*gp));
86
87 if (gp->tx_bip_fem_auto_detect)
88 answer = true;
89
90 /* Override the REF CLK from the NVS with the one from platform data */
91 gen_parms->general_params.ref_clock = wl->ref_clock;
92
93 ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), answer);
94 if (ret < 0) {
95 wl1271_warning("CMD_INI_FILE_GENERAL_PARAM failed");
96 goto out;
97 }
98
99 gp->tx_bip_fem_manufacturer =
100 gen_parms->general_params.tx_bip_fem_manufacturer;
101
102 if (gp->tx_bip_fem_manufacturer >= WL1271_INI_FEM_MODULE_COUNT) {
103 wl1271_warning("FEM index from FW out of bounds");
104 ret = -EINVAL;
105 goto out;
106 }
107
108 wl1271_debug(DEBUG_CMD, "FEM autodetect: %s, manufacturer: %d\n",
109 answer ? "auto" : "manual", gp->tx_bip_fem_manufacturer);
110
111out:
112 kfree(gen_parms);
113 return ret;
114}
115
116int wl128x_cmd_general_parms(struct wl1271 *wl)
117{
118 struct wl128x_general_parms_cmd *gen_parms;
119 struct wl128x_ini_general_params *gp =
120 &((struct wl128x_nvs_file *)wl->nvs)->general_params;
121 bool answer = false;
122 int ret;
123
124 if (!wl->nvs)
125 return -ENODEV;
126
127 if (gp->tx_bip_fem_manufacturer >= WL1271_INI_FEM_MODULE_COUNT) {
128 wl1271_warning("FEM index from ini out of bounds");
129 return -EINVAL;
130 }
131
132 gen_parms = kzalloc(sizeof(*gen_parms), GFP_KERNEL);
133 if (!gen_parms)
134 return -ENOMEM;
135
136 gen_parms->test.id = TEST_CMD_INI_FILE_GENERAL_PARAM;
137
138 memcpy(&gen_parms->general_params, gp, sizeof(*gp));
139
140 if (gp->tx_bip_fem_auto_detect)
141 answer = true;
142
143 /* Replace REF and TCXO CLKs with the ones from platform data */
144 gen_parms->general_params.ref_clock = wl->ref_clock;
145 gen_parms->general_params.tcxo_ref_clock = wl->tcxo_clock;
146
147 ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), answer);
148 if (ret < 0) {
149 wl1271_warning("CMD_INI_FILE_GENERAL_PARAM failed");
150 goto out;
151 }
152
153 gp->tx_bip_fem_manufacturer =
154 gen_parms->general_params.tx_bip_fem_manufacturer;
155
156 if (gp->tx_bip_fem_manufacturer >= WL1271_INI_FEM_MODULE_COUNT) {
157 wl1271_warning("FEM index from FW out of bounds");
158 ret = -EINVAL;
159 goto out;
160 }
161
162 wl1271_debug(DEBUG_CMD, "FEM autodetect: %s, manufacturer: %d\n",
163 answer ? "auto" : "manual", gp->tx_bip_fem_manufacturer);
164
165out:
166 kfree(gen_parms);
167 return ret;
168}
169
170int wl1271_cmd_radio_parms(struct wl1271 *wl)
171{
172 struct wl1271_nvs_file *nvs = (struct wl1271_nvs_file *)wl->nvs;
173 struct wl1271_radio_parms_cmd *radio_parms;
174 struct wl1271_ini_general_params *gp = &nvs->general_params;
175 int ret;
176
177 if (!wl->nvs)
178 return -ENODEV;
179
180 radio_parms = kzalloc(sizeof(*radio_parms), GFP_KERNEL);
181 if (!radio_parms)
182 return -ENOMEM;
183
184 radio_parms->test.id = TEST_CMD_INI_FILE_RADIO_PARAM;
185
186 /* 2.4GHz parameters */
187 memcpy(&radio_parms->static_params_2, &nvs->stat_radio_params_2,
188 sizeof(struct wl1271_ini_band_params_2));
189 memcpy(&radio_parms->dyn_params_2,
190 &nvs->dyn_radio_params_2[gp->tx_bip_fem_manufacturer].params,
191 sizeof(struct wl1271_ini_fem_params_2));
192
193 /* 5GHz parameters */
194 memcpy(&radio_parms->static_params_5,
195 &nvs->stat_radio_params_5,
196 sizeof(struct wl1271_ini_band_params_5));
197 memcpy(&radio_parms->dyn_params_5,
198 &nvs->dyn_radio_params_5[gp->tx_bip_fem_manufacturer].params,
199 sizeof(struct wl1271_ini_fem_params_5));
200
201 wl1271_dump(DEBUG_CMD, "TEST_CMD_INI_FILE_RADIO_PARAM: ",
202 radio_parms, sizeof(*radio_parms));
203
204 ret = wl1271_cmd_test(wl, radio_parms, sizeof(*radio_parms), 0);
205 if (ret < 0)
206 wl1271_warning("CMD_INI_FILE_RADIO_PARAM failed");
207
208 kfree(radio_parms);
209 return ret;
210}
211
212int wl128x_cmd_radio_parms(struct wl1271 *wl)
213{
214 struct wl128x_nvs_file *nvs = (struct wl128x_nvs_file *)wl->nvs;
215 struct wl128x_radio_parms_cmd *radio_parms;
216 struct wl128x_ini_general_params *gp = &nvs->general_params;
217 int ret;
218
219 if (!wl->nvs)
220 return -ENODEV;
221
222 radio_parms = kzalloc(sizeof(*radio_parms), GFP_KERNEL);
223 if (!radio_parms)
224 return -ENOMEM;
225
226 radio_parms->test.id = TEST_CMD_INI_FILE_RADIO_PARAM;
227
228 /* 2.4GHz parameters */
229 memcpy(&radio_parms->static_params_2, &nvs->stat_radio_params_2,
230 sizeof(struct wl128x_ini_band_params_2));
231 memcpy(&radio_parms->dyn_params_2,
232 &nvs->dyn_radio_params_2[gp->tx_bip_fem_manufacturer].params,
233 sizeof(struct wl128x_ini_fem_params_2));
234
235 /* 5GHz parameters */
236 memcpy(&radio_parms->static_params_5,
237 &nvs->stat_radio_params_5,
238 sizeof(struct wl128x_ini_band_params_5));
239 memcpy(&radio_parms->dyn_params_5,
240 &nvs->dyn_radio_params_5[gp->tx_bip_fem_manufacturer].params,
241 sizeof(struct wl128x_ini_fem_params_5));
242
243 radio_parms->fem_vendor_and_options = nvs->fem_vendor_and_options;
244
245 wl1271_dump(DEBUG_CMD, "TEST_CMD_INI_FILE_RADIO_PARAM: ",
246 radio_parms, sizeof(*radio_parms));
247
248 ret = wl1271_cmd_test(wl, radio_parms, sizeof(*radio_parms), 0);
249 if (ret < 0)
250 wl1271_warning("CMD_INI_FILE_RADIO_PARAM failed");
251
252 kfree(radio_parms);
253 return ret;
254}
diff --git a/drivers/net/wireless/ti/wl12xx/cmd.h b/drivers/net/wireless/ti/wl12xx/cmd.h
new file mode 100644
index 000000000000..140a0e8829d5
--- /dev/null
+++ b/drivers/net/wireless/ti/wl12xx/cmd.h
@@ -0,0 +1,112 @@
1/*
2 * This file is part of wl12xx
3 *
4 * Copyright (C) 1998-2009, 2011 Texas Instruments. All rights reserved.
5 * Copyright (C) 2009 Nokia Corporation
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * version 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
19 * 02110-1301 USA
20 *
21 */
22
23#ifndef __WL12XX_CMD_H__
24#define __WL12XX_CMD_H__
25
26#include "conf.h"
27
28#define TEST_CMD_INI_FILE_RADIO_PARAM 0x19
29#define TEST_CMD_INI_FILE_GENERAL_PARAM 0x1E
30
31struct wl1271_general_parms_cmd {
32 struct wl1271_cmd_header header;
33
34 struct wl1271_cmd_test_header test;
35
36 struct wl1271_ini_general_params general_params;
37
38 u8 sr_debug_table[WL1271_INI_MAX_SMART_REFLEX_PARAM];
39 u8 sr_sen_n_p;
40 u8 sr_sen_n_p_gain;
41 u8 sr_sen_nrn;
42 u8 sr_sen_prn;
43 u8 padding[3];
44} __packed;
45
46struct wl128x_general_parms_cmd {
47 struct wl1271_cmd_header header;
48
49 struct wl1271_cmd_test_header test;
50
51 struct wl128x_ini_general_params general_params;
52
53 u8 sr_debug_table[WL1271_INI_MAX_SMART_REFLEX_PARAM];
54 u8 sr_sen_n_p;
55 u8 sr_sen_n_p_gain;
56 u8 sr_sen_nrn;
57 u8 sr_sen_prn;
58 u8 padding[3];
59} __packed;
60
61struct wl1271_radio_parms_cmd {
62 struct wl1271_cmd_header header;
63
64 struct wl1271_cmd_test_header test;
65
66 /* Static radio parameters */
67 struct wl1271_ini_band_params_2 static_params_2;
68 struct wl1271_ini_band_params_5 static_params_5;
69
70 /* Dynamic radio parameters */
71 struct wl1271_ini_fem_params_2 dyn_params_2;
72 u8 padding2;
73 struct wl1271_ini_fem_params_5 dyn_params_5;
74 u8 padding3[2];
75} __packed;
76
77struct wl128x_radio_parms_cmd {
78 struct wl1271_cmd_header header;
79
80 struct wl1271_cmd_test_header test;
81
82 /* Static radio parameters */
83 struct wl128x_ini_band_params_2 static_params_2;
84 struct wl128x_ini_band_params_5 static_params_5;
85
86 u8 fem_vendor_and_options;
87
88 /* Dynamic radio parameters */
89 struct wl128x_ini_fem_params_2 dyn_params_2;
90 u8 padding2;
91 struct wl128x_ini_fem_params_5 dyn_params_5;
92} __packed;
93
94#define TEST_CMD_INI_FILE_RF_EXTENDED_PARAM 0x26
95
96struct wl1271_ext_radio_parms_cmd {
97 struct wl1271_cmd_header header;
98
99 struct wl1271_cmd_test_header test;
100
101 u8 tx_per_channel_power_compensation_2[CONF_TX_PWR_COMPENSATION_LEN_2];
102 u8 tx_per_channel_power_compensation_5[CONF_TX_PWR_COMPENSATION_LEN_5];
103 u8 padding[3];
104} __packed;
105
106int wl1271_cmd_general_parms(struct wl1271 *wl);
107int wl128x_cmd_general_parms(struct wl1271 *wl);
108int wl1271_cmd_radio_parms(struct wl1271 *wl);
109int wl128x_cmd_radio_parms(struct wl1271 *wl);
110int wl1271_cmd_ext_radio_parms(struct wl1271 *wl);
111
112#endif /* __WL12XX_CMD_H__ */
diff --git a/drivers/net/wireless/ti/wl12xx/conf.h b/drivers/net/wireless/ti/wl12xx/conf.h
new file mode 100644
index 000000000000..75e29897a0f5
--- /dev/null
+++ b/drivers/net/wireless/ti/wl12xx/conf.h
@@ -0,0 +1,50 @@
1/*
2 * This file is part of wl12xx
3 *
4 * Copyright (C) 2011 Texas Instruments Inc.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18 * 02110-1301 USA
19 *
20 */
21
22#ifndef __WL12XX_CONF_H__
23#define __WL12XX_CONF_H__
24
25/* these are number of channels on the band divided by two, rounded up */
26#define CONF_TX_PWR_COMPENSATION_LEN_2 7
27#define CONF_TX_PWR_COMPENSATION_LEN_5 18
28
29struct wl12xx_conf_rf {
30 /*
31 * Per channel power compensation for 2.4GHz
32 *
33 * Range: s8
34 */
35 u8 tx_per_channel_power_compensation_2[CONF_TX_PWR_COMPENSATION_LEN_2];
36
37 /*
38 * Per channel power compensation for 5GHz
39 *
40 * Range: s8
41 */
42 u8 tx_per_channel_power_compensation_5[CONF_TX_PWR_COMPENSATION_LEN_5];
43};
44
45struct wl12xx_priv_conf {
46 struct wl12xx_conf_rf rf;
47 struct conf_memory_settings mem_wl127x;
48};
49
50#endif /* __WL12XX_CONF_H__ */
diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c
new file mode 100644
index 000000000000..d7dd3def07b5
--- /dev/null
+++ b/drivers/net/wireless/ti/wl12xx/main.c
@@ -0,0 +1,1388 @@
1/*
2 * This file is part of wl1271
3 *
4 * Copyright (C) 2008-2010 Nokia Corporation
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18 * 02110-1301 USA
19 *
20 */
21
22#include <linux/module.h>
23#include <linux/platform_device.h>
24
25#include <linux/err.h>
26
27#include <linux/wl12xx.h>
28
29#include "../wlcore/wlcore.h"
30#include "../wlcore/debug.h"
31#include "../wlcore/io.h"
32#include "../wlcore/acx.h"
33#include "../wlcore/tx.h"
34#include "../wlcore/rx.h"
35#include "../wlcore/io.h"
36#include "../wlcore/boot.h"
37
38#include "wl12xx.h"
39#include "reg.h"
40#include "cmd.h"
41#include "acx.h"
42
43static struct wlcore_conf wl12xx_conf = {
44 .sg = {
45 .params = {
46 [CONF_SG_ACL_BT_MASTER_MIN_BR] = 10,
47 [CONF_SG_ACL_BT_MASTER_MAX_BR] = 180,
48 [CONF_SG_ACL_BT_SLAVE_MIN_BR] = 10,
49 [CONF_SG_ACL_BT_SLAVE_MAX_BR] = 180,
50 [CONF_SG_ACL_BT_MASTER_MIN_EDR] = 10,
51 [CONF_SG_ACL_BT_MASTER_MAX_EDR] = 80,
52 [CONF_SG_ACL_BT_SLAVE_MIN_EDR] = 10,
53 [CONF_SG_ACL_BT_SLAVE_MAX_EDR] = 80,
54 [CONF_SG_ACL_WLAN_PS_MASTER_BR] = 8,
55 [CONF_SG_ACL_WLAN_PS_SLAVE_BR] = 8,
56 [CONF_SG_ACL_WLAN_PS_MASTER_EDR] = 20,
57 [CONF_SG_ACL_WLAN_PS_SLAVE_EDR] = 20,
58 [CONF_SG_ACL_WLAN_ACTIVE_MASTER_MIN_BR] = 20,
59 [CONF_SG_ACL_WLAN_ACTIVE_MASTER_MAX_BR] = 35,
60 [CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MIN_BR] = 16,
61 [CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MAX_BR] = 35,
62 [CONF_SG_ACL_WLAN_ACTIVE_MASTER_MIN_EDR] = 32,
63 [CONF_SG_ACL_WLAN_ACTIVE_MASTER_MAX_EDR] = 50,
64 [CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MIN_EDR] = 28,
65 [CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MAX_EDR] = 50,
66 [CONF_SG_ACL_ACTIVE_SCAN_WLAN_BR] = 10,
67 [CONF_SG_ACL_ACTIVE_SCAN_WLAN_EDR] = 20,
68 [CONF_SG_ACL_PASSIVE_SCAN_BT_BR] = 75,
69 [CONF_SG_ACL_PASSIVE_SCAN_WLAN_BR] = 15,
70 [CONF_SG_ACL_PASSIVE_SCAN_BT_EDR] = 27,
71 [CONF_SG_ACL_PASSIVE_SCAN_WLAN_EDR] = 17,
72 /* active scan params */
73 [CONF_SG_AUTO_SCAN_PROBE_REQ] = 170,
74 [CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_HV3] = 50,
75 [CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_A2DP] = 100,
76 /* passive scan params */
77 [CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_A2DP_BR] = 800,
78 [CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_A2DP_EDR] = 200,
79 [CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_HV3] = 200,
80 /* passive scan in dual antenna params */
81 [CONF_SG_CONSECUTIVE_HV3_IN_PASSIVE_SCAN] = 0,
82 [CONF_SG_BCN_HV3_COLLISION_THRESH_IN_PASSIVE_SCAN] = 0,
83 [CONF_SG_TX_RX_PROTECTION_BWIDTH_IN_PASSIVE_SCAN] = 0,
84 /* general params */
85 [CONF_SG_STA_FORCE_PS_IN_BT_SCO] = 1,
86 [CONF_SG_ANTENNA_CONFIGURATION] = 0,
87 [CONF_SG_BEACON_MISS_PERCENT] = 60,
88 [CONF_SG_DHCP_TIME] = 5000,
89 [CONF_SG_RXT] = 1200,
90 [CONF_SG_TXT] = 1000,
91 [CONF_SG_ADAPTIVE_RXT_TXT] = 1,
92 [CONF_SG_GENERAL_USAGE_BIT_MAP] = 3,
93 [CONF_SG_HV3_MAX_SERVED] = 6,
94 [CONF_SG_PS_POLL_TIMEOUT] = 10,
95 [CONF_SG_UPSD_TIMEOUT] = 10,
96 [CONF_SG_CONSECUTIVE_CTS_THRESHOLD] = 2,
97 [CONF_SG_STA_RX_WINDOW_AFTER_DTIM] = 5,
98 [CONF_SG_STA_CONNECTION_PROTECTION_TIME] = 30,
99 /* AP params */
100 [CONF_AP_BEACON_MISS_TX] = 3,
101 [CONF_AP_RX_WINDOW_AFTER_BEACON] = 10,
102 [CONF_AP_BEACON_WINDOW_INTERVAL] = 2,
103 [CONF_AP_CONNECTION_PROTECTION_TIME] = 0,
104 [CONF_AP_BT_ACL_VAL_BT_SERVE_TIME] = 25,
105 [CONF_AP_BT_ACL_VAL_WL_SERVE_TIME] = 25,
106 /* CTS Diluting params */
107 [CONF_SG_CTS_DILUTED_BAD_RX_PACKETS_TH] = 0,
108 [CONF_SG_CTS_CHOP_IN_DUAL_ANT_SCO_MASTER] = 0,
109 },
110 .state = CONF_SG_PROTECTIVE,
111 },
112 .rx = {
113 .rx_msdu_life_time = 512000,
114 .packet_detection_threshold = 0,
115 .ps_poll_timeout = 15,
116 .upsd_timeout = 15,
117 .rts_threshold = IEEE80211_MAX_RTS_THRESHOLD,
118 .rx_cca_threshold = 0,
119 .irq_blk_threshold = 0xFFFF,
120 .irq_pkt_threshold = 0,
121 .irq_timeout = 600,
122 .queue_type = CONF_RX_QUEUE_TYPE_LOW_PRIORITY,
123 },
124 .tx = {
125 .tx_energy_detection = 0,
126 .sta_rc_conf = {
127 .enabled_rates = 0,
128 .short_retry_limit = 10,
129 .long_retry_limit = 10,
130 .aflags = 0,
131 },
132 .ac_conf_count = 4,
133 .ac_conf = {
134 [CONF_TX_AC_BE] = {
135 .ac = CONF_TX_AC_BE,
136 .cw_min = 15,
137 .cw_max = 63,
138 .aifsn = 3,
139 .tx_op_limit = 0,
140 },
141 [CONF_TX_AC_BK] = {
142 .ac = CONF_TX_AC_BK,
143 .cw_min = 15,
144 .cw_max = 63,
145 .aifsn = 7,
146 .tx_op_limit = 0,
147 },
148 [CONF_TX_AC_VI] = {
149 .ac = CONF_TX_AC_VI,
150 .cw_min = 15,
151 .cw_max = 63,
152 .aifsn = CONF_TX_AIFS_PIFS,
153 .tx_op_limit = 3008,
154 },
155 [CONF_TX_AC_VO] = {
156 .ac = CONF_TX_AC_VO,
157 .cw_min = 15,
158 .cw_max = 63,
159 .aifsn = CONF_TX_AIFS_PIFS,
160 .tx_op_limit = 1504,
161 },
162 },
163 .max_tx_retries = 100,
164 .ap_aging_period = 300,
165 .tid_conf_count = 4,
166 .tid_conf = {
167 [CONF_TX_AC_BE] = {
168 .queue_id = CONF_TX_AC_BE,
169 .channel_type = CONF_CHANNEL_TYPE_EDCF,
170 .tsid = CONF_TX_AC_BE,
171 .ps_scheme = CONF_PS_SCHEME_LEGACY,
172 .ack_policy = CONF_ACK_POLICY_LEGACY,
173 .apsd_conf = {0, 0},
174 },
175 [CONF_TX_AC_BK] = {
176 .queue_id = CONF_TX_AC_BK,
177 .channel_type = CONF_CHANNEL_TYPE_EDCF,
178 .tsid = CONF_TX_AC_BK,
179 .ps_scheme = CONF_PS_SCHEME_LEGACY,
180 .ack_policy = CONF_ACK_POLICY_LEGACY,
181 .apsd_conf = {0, 0},
182 },
183 [CONF_TX_AC_VI] = {
184 .queue_id = CONF_TX_AC_VI,
185 .channel_type = CONF_CHANNEL_TYPE_EDCF,
186 .tsid = CONF_TX_AC_VI,
187 .ps_scheme = CONF_PS_SCHEME_LEGACY,
188 .ack_policy = CONF_ACK_POLICY_LEGACY,
189 .apsd_conf = {0, 0},
190 },
191 [CONF_TX_AC_VO] = {
192 .queue_id = CONF_TX_AC_VO,
193 .channel_type = CONF_CHANNEL_TYPE_EDCF,
194 .tsid = CONF_TX_AC_VO,
195 .ps_scheme = CONF_PS_SCHEME_LEGACY,
196 .ack_policy = CONF_ACK_POLICY_LEGACY,
197 .apsd_conf = {0, 0},
198 },
199 },
200 .frag_threshold = IEEE80211_MAX_FRAG_THRESHOLD,
201 .tx_compl_timeout = 700,
202 .tx_compl_threshold = 4,
203 .basic_rate = CONF_HW_BIT_RATE_1MBPS,
204 .basic_rate_5 = CONF_HW_BIT_RATE_6MBPS,
205 .tmpl_short_retry_limit = 10,
206 .tmpl_long_retry_limit = 10,
207 .tx_watchdog_timeout = 5000,
208 },
209 .conn = {
210 .wake_up_event = CONF_WAKE_UP_EVENT_DTIM,
211 .listen_interval = 1,
212 .suspend_wake_up_event = CONF_WAKE_UP_EVENT_N_DTIM,
213 .suspend_listen_interval = 3,
214 .bcn_filt_mode = CONF_BCN_FILT_MODE_ENABLED,
215 .bcn_filt_ie_count = 2,
216 .bcn_filt_ie = {
217 [0] = {
218 .ie = WLAN_EID_CHANNEL_SWITCH,
219 .rule = CONF_BCN_RULE_PASS_ON_APPEARANCE,
220 },
221 [1] = {
222 .ie = WLAN_EID_HT_OPERATION,
223 .rule = CONF_BCN_RULE_PASS_ON_CHANGE,
224 },
225 },
226 .synch_fail_thold = 10,
227 .bss_lose_timeout = 100,
228 .beacon_rx_timeout = 10000,
229 .broadcast_timeout = 20000,
230 .rx_broadcast_in_ps = 1,
231 .ps_poll_threshold = 10,
232 .bet_enable = CONF_BET_MODE_ENABLE,
233 .bet_max_consecutive = 50,
234 .psm_entry_retries = 8,
235 .psm_exit_retries = 16,
236 .psm_entry_nullfunc_retries = 3,
237 .dynamic_ps_timeout = 40,
238 .forced_ps = false,
239 .keep_alive_interval = 55000,
240 .max_listen_interval = 20,
241 },
242 .itrim = {
243 .enable = false,
244 .timeout = 50000,
245 },
246 .pm_config = {
247 .host_clk_settling_time = 5000,
248 .host_fast_wakeup_support = false
249 },
250 .roam_trigger = {
251 .trigger_pacing = 1,
252 .avg_weight_rssi_beacon = 20,
253 .avg_weight_rssi_data = 10,
254 .avg_weight_snr_beacon = 20,
255 .avg_weight_snr_data = 10,
256 },
257 .scan = {
258 .min_dwell_time_active = 7500,
259 .max_dwell_time_active = 30000,
260 .min_dwell_time_passive = 100000,
261 .max_dwell_time_passive = 100000,
262 .num_probe_reqs = 2,
263 .split_scan_timeout = 50000,
264 },
265 .sched_scan = {
266 /*
267 * Values are in TU/1000 but since sched scan FW command
268 * params are in TUs rounding up may occur.
269 */
270 .base_dwell_time = 7500,
271 .max_dwell_time_delta = 22500,
272 /* based on 250bits per probe @1Mbps */
273 .dwell_time_delta_per_probe = 2000,
274 /* based on 250bits per probe @6Mbps (plus a bit more) */
275 .dwell_time_delta_per_probe_5 = 350,
276 .dwell_time_passive = 100000,
277 .dwell_time_dfs = 150000,
278 .num_probe_reqs = 2,
279 .rssi_threshold = -90,
280 .snr_threshold = 0,
281 },
282 .ht = {
283 .rx_ba_win_size = 8,
284 .tx_ba_win_size = 64,
285 .inactivity_timeout = 10000,
286 .tx_ba_tid_bitmap = CONF_TX_BA_ENABLED_TID_BITMAP,
287 },
288 /*
289 * Memory config for wl127x chips is given in the
290 * wl12xx_default_priv_conf struct. The below configuration is
291 * for wl128x chips.
292 */
293 .mem = {
294 .num_stations = 1,
295 .ssid_profiles = 1,
296 .rx_block_num = 40,
297 .tx_min_block_num = 40,
298 .dynamic_memory = 1,
299 .min_req_tx_blocks = 45,
300 .min_req_rx_blocks = 22,
301 .tx_min = 27,
302 },
303 .fm_coex = {
304 .enable = true,
305 .swallow_period = 5,
306 .n_divider_fref_set_1 = 0xff, /* default */
307 .n_divider_fref_set_2 = 12,
308 .m_divider_fref_set_1 = 148,
309 .m_divider_fref_set_2 = 0xffff, /* default */
310 .coex_pll_stabilization_time = 0xffffffff, /* default */
311 .ldo_stabilization_time = 0xffff, /* default */
312 .fm_disturbed_band_margin = 0xff, /* default */
313 .swallow_clk_diff = 0xff, /* default */
314 },
315 .rx_streaming = {
316 .duration = 150,
317 .queues = 0x1,
318 .interval = 20,
319 .always = 0,
320 },
321 .fwlog = {
322 .mode = WL12XX_FWLOG_ON_DEMAND,
323 .mem_blocks = 2,
324 .severity = 0,
325 .timestamp = WL12XX_FWLOG_TIMESTAMP_DISABLED,
326 .output = WL12XX_FWLOG_OUTPUT_HOST,
327 .threshold = 0,
328 },
329 .rate = {
330 .rate_retry_score = 32000,
331 .per_add = 8192,
332 .per_th1 = 2048,
333 .per_th2 = 4096,
334 .max_per = 8100,
335 .inverse_curiosity_factor = 5,
336 .tx_fail_low_th = 4,
337 .tx_fail_high_th = 10,
338 .per_alpha_shift = 4,
339 .per_add_shift = 13,
340 .per_beta1_shift = 10,
341 .per_beta2_shift = 8,
342 .rate_check_up = 2,
343 .rate_check_down = 12,
344 .rate_retry_policy = {
345 0x00, 0x00, 0x00, 0x00, 0x00,
346 0x00, 0x00, 0x00, 0x00, 0x00,
347 0x00, 0x00, 0x00,
348 },
349 },
350 .hangover = {
351 .recover_time = 0,
352 .hangover_period = 20,
353 .dynamic_mode = 1,
354 .early_termination_mode = 1,
355 .max_period = 20,
356 .min_period = 1,
357 .increase_delta = 1,
358 .decrease_delta = 2,
359 .quiet_time = 4,
360 .increase_time = 1,
361 .window_size = 16,
362 },
363};
364
365static struct wl12xx_priv_conf wl12xx_default_priv_conf = {
366 .rf = {
367 .tx_per_channel_power_compensation_2 = {
368 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
369 },
370 .tx_per_channel_power_compensation_5 = {
371 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
372 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
373 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
374 },
375 },
376 .mem_wl127x = {
377 .num_stations = 1,
378 .ssid_profiles = 1,
379 .rx_block_num = 70,
380 .tx_min_block_num = 40,
381 .dynamic_memory = 1,
382 .min_req_tx_blocks = 100,
383 .min_req_rx_blocks = 22,
384 .tx_min = 27,
385 },
386
387};
388
389#define WL12XX_TX_HW_BLOCK_SPARE_DEFAULT 1
390#define WL12XX_TX_HW_BLOCK_GEM_SPARE 2
391#define WL12XX_TX_HW_BLOCK_SIZE 252
392
393static const u8 wl12xx_rate_to_idx_2ghz[] = {
394 /* MCS rates are used only with 11n */
395 7, /* WL12XX_CONF_HW_RXTX_RATE_MCS7_SGI */
396 7, /* WL12XX_CONF_HW_RXTX_RATE_MCS7 */
397 6, /* WL12XX_CONF_HW_RXTX_RATE_MCS6 */
398 5, /* WL12XX_CONF_HW_RXTX_RATE_MCS5 */
399 4, /* WL12XX_CONF_HW_RXTX_RATE_MCS4 */
400 3, /* WL12XX_CONF_HW_RXTX_RATE_MCS3 */
401 2, /* WL12XX_CONF_HW_RXTX_RATE_MCS2 */
402 1, /* WL12XX_CONF_HW_RXTX_RATE_MCS1 */
403 0, /* WL12XX_CONF_HW_RXTX_RATE_MCS0 */
404
405 11, /* WL12XX_CONF_HW_RXTX_RATE_54 */
406 10, /* WL12XX_CONF_HW_RXTX_RATE_48 */
407 9, /* WL12XX_CONF_HW_RXTX_RATE_36 */
408 8, /* WL12XX_CONF_HW_RXTX_RATE_24 */
409
410 /* TI-specific rate */
411 CONF_HW_RXTX_RATE_UNSUPPORTED, /* WL12XX_CONF_HW_RXTX_RATE_22 */
412
413 7, /* WL12XX_CONF_HW_RXTX_RATE_18 */
414 6, /* WL12XX_CONF_HW_RXTX_RATE_12 */
415 3, /* WL12XX_CONF_HW_RXTX_RATE_11 */
416 5, /* WL12XX_CONF_HW_RXTX_RATE_9 */
417 4, /* WL12XX_CONF_HW_RXTX_RATE_6 */
418 2, /* WL12XX_CONF_HW_RXTX_RATE_5_5 */
419 1, /* WL12XX_CONF_HW_RXTX_RATE_2 */
420 0 /* WL12XX_CONF_HW_RXTX_RATE_1 */
421};
422
423static const u8 wl12xx_rate_to_idx_5ghz[] = {
424 /* MCS rates are used only with 11n */
425 7, /* WL12XX_CONF_HW_RXTX_RATE_MCS7_SGI */
426 7, /* WL12XX_CONF_HW_RXTX_RATE_MCS7 */
427 6, /* WL12XX_CONF_HW_RXTX_RATE_MCS6 */
428 5, /* WL12XX_CONF_HW_RXTX_RATE_MCS5 */
429 4, /* WL12XX_CONF_HW_RXTX_RATE_MCS4 */
430 3, /* WL12XX_CONF_HW_RXTX_RATE_MCS3 */
431 2, /* WL12XX_CONF_HW_RXTX_RATE_MCS2 */
432 1, /* WL12XX_CONF_HW_RXTX_RATE_MCS1 */
433 0, /* WL12XX_CONF_HW_RXTX_RATE_MCS0 */
434
435 7, /* WL12XX_CONF_HW_RXTX_RATE_54 */
436 6, /* WL12XX_CONF_HW_RXTX_RATE_48 */
437 5, /* WL12XX_CONF_HW_RXTX_RATE_36 */
438 4, /* WL12XX_CONF_HW_RXTX_RATE_24 */
439
440 /* TI-specific rate */
441 CONF_HW_RXTX_RATE_UNSUPPORTED, /* WL12XX_CONF_HW_RXTX_RATE_22 */
442
443 3, /* WL12XX_CONF_HW_RXTX_RATE_18 */
444 2, /* WL12XX_CONF_HW_RXTX_RATE_12 */
445 CONF_HW_RXTX_RATE_UNSUPPORTED, /* WL12XX_CONF_HW_RXTX_RATE_11 */
446 1, /* WL12XX_CONF_HW_RXTX_RATE_9 */
447 0, /* WL12XX_CONF_HW_RXTX_RATE_6 */
448 CONF_HW_RXTX_RATE_UNSUPPORTED, /* WL12XX_CONF_HW_RXTX_RATE_5_5 */
449 CONF_HW_RXTX_RATE_UNSUPPORTED, /* WL12XX_CONF_HW_RXTX_RATE_2 */
450 CONF_HW_RXTX_RATE_UNSUPPORTED /* WL12XX_CONF_HW_RXTX_RATE_1 */
451};
452
453static const u8 *wl12xx_band_rate_to_idx[] = {
454 [IEEE80211_BAND_2GHZ] = wl12xx_rate_to_idx_2ghz,
455 [IEEE80211_BAND_5GHZ] = wl12xx_rate_to_idx_5ghz
456};
457
458enum wl12xx_hw_rates {
459 WL12XX_CONF_HW_RXTX_RATE_MCS7_SGI = 0,
460 WL12XX_CONF_HW_RXTX_RATE_MCS7,
461 WL12XX_CONF_HW_RXTX_RATE_MCS6,
462 WL12XX_CONF_HW_RXTX_RATE_MCS5,
463 WL12XX_CONF_HW_RXTX_RATE_MCS4,
464 WL12XX_CONF_HW_RXTX_RATE_MCS3,
465 WL12XX_CONF_HW_RXTX_RATE_MCS2,
466 WL12XX_CONF_HW_RXTX_RATE_MCS1,
467 WL12XX_CONF_HW_RXTX_RATE_MCS0,
468 WL12XX_CONF_HW_RXTX_RATE_54,
469 WL12XX_CONF_HW_RXTX_RATE_48,
470 WL12XX_CONF_HW_RXTX_RATE_36,
471 WL12XX_CONF_HW_RXTX_RATE_24,
472 WL12XX_CONF_HW_RXTX_RATE_22,
473 WL12XX_CONF_HW_RXTX_RATE_18,
474 WL12XX_CONF_HW_RXTX_RATE_12,
475 WL12XX_CONF_HW_RXTX_RATE_11,
476 WL12XX_CONF_HW_RXTX_RATE_9,
477 WL12XX_CONF_HW_RXTX_RATE_6,
478 WL12XX_CONF_HW_RXTX_RATE_5_5,
479 WL12XX_CONF_HW_RXTX_RATE_2,
480 WL12XX_CONF_HW_RXTX_RATE_1,
481 WL12XX_CONF_HW_RXTX_RATE_MAX,
482};
483
484static struct wlcore_partition_set wl12xx_ptable[PART_TABLE_LEN] = {
485 [PART_DOWN] = {
486 .mem = {
487 .start = 0x00000000,
488 .size = 0x000177c0
489 },
490 .reg = {
491 .start = REGISTERS_BASE,
492 .size = 0x00008800
493 },
494 .mem2 = {
495 .start = 0x00000000,
496 .size = 0x00000000
497 },
498 .mem3 = {
499 .start = 0x00000000,
500 .size = 0x00000000
501 },
502 },
503
504 [PART_BOOT] = { /* in wl12xx we can use a mix of work and down
505 * partition here */
506 .mem = {
507 .start = 0x00040000,
508 .size = 0x00014fc0
509 },
510 .reg = {
511 .start = REGISTERS_BASE,
512 .size = 0x00008800
513 },
514 .mem2 = {
515 .start = 0x00000000,
516 .size = 0x00000000
517 },
518 .mem3 = {
519 .start = 0x00000000,
520 .size = 0x00000000
521 },
522 },
523
524 [PART_WORK] = {
525 .mem = {
526 .start = 0x00040000,
527 .size = 0x00014fc0
528 },
529 .reg = {
530 .start = REGISTERS_BASE,
531 .size = 0x0000a000
532 },
533 .mem2 = {
534 .start = 0x003004f8,
535 .size = 0x00000004
536 },
537 .mem3 = {
538 .start = 0x00040404,
539 .size = 0x00000000
540 },
541 },
542
543 [PART_DRPW] = {
544 .mem = {
545 .start = 0x00040000,
546 .size = 0x00014fc0
547 },
548 .reg = {
549 .start = DRPW_BASE,
550 .size = 0x00006000
551 },
552 .mem2 = {
553 .start = 0x00000000,
554 .size = 0x00000000
555 },
556 .mem3 = {
557 .start = 0x00000000,
558 .size = 0x00000000
559 }
560 }
561};
562
563static const int wl12xx_rtable[REG_TABLE_LEN] = {
564 [REG_ECPU_CONTROL] = WL12XX_REG_ECPU_CONTROL,
565 [REG_INTERRUPT_NO_CLEAR] = WL12XX_REG_INTERRUPT_NO_CLEAR,
566 [REG_INTERRUPT_ACK] = WL12XX_REG_INTERRUPT_ACK,
567 [REG_COMMAND_MAILBOX_PTR] = WL12XX_REG_COMMAND_MAILBOX_PTR,
568 [REG_EVENT_MAILBOX_PTR] = WL12XX_REG_EVENT_MAILBOX_PTR,
569 [REG_INTERRUPT_TRIG] = WL12XX_REG_INTERRUPT_TRIG,
570 [REG_INTERRUPT_MASK] = WL12XX_REG_INTERRUPT_MASK,
571 [REG_PC_ON_RECOVERY] = WL12XX_SCR_PAD4,
572 [REG_CHIP_ID_B] = WL12XX_CHIP_ID_B,
573 [REG_CMD_MBOX_ADDRESS] = WL12XX_CMD_MBOX_ADDRESS,
574
575 /* data access memory addresses, used with partition translation */
576 [REG_SLV_MEM_DATA] = WL1271_SLV_MEM_DATA,
577 [REG_SLV_REG_DATA] = WL1271_SLV_REG_DATA,
578
579 /* raw data access memory addresses */
580 [REG_RAW_FW_STATUS_ADDR] = FW_STATUS_ADDR,
581};
582
583/* TODO: maybe move to a new header file? */
584#define WL127X_FW_NAME_MULTI "ti-connectivity/wl127x-fw-4-mr.bin"
585#define WL127X_FW_NAME_SINGLE "ti-connectivity/wl127x-fw-4-sr.bin"
586#define WL127X_PLT_FW_NAME "ti-connectivity/wl127x-fw-4-plt.bin"
587
588#define WL128X_FW_NAME_MULTI "ti-connectivity/wl128x-fw-4-mr.bin"
589#define WL128X_FW_NAME_SINGLE "ti-connectivity/wl128x-fw-4-sr.bin"
590#define WL128X_PLT_FW_NAME "ti-connectivity/wl128x-fw-4-plt.bin"
591
592static void wl127x_prepare_read(struct wl1271 *wl, u32 rx_desc, u32 len)
593{
594 if (wl->chip.id != CHIP_ID_1283_PG20) {
595 struct wl1271_acx_mem_map *wl_mem_map = wl->target_mem_map;
596 struct wl1271_rx_mem_pool_addr rx_mem_addr;
597
598 /*
599 * Choose the block we want to read
600 * For aggregated packets, only the first memory block
601 * should be retrieved. The FW takes care of the rest.
602 */
603 u32 mem_block = rx_desc & RX_MEM_BLOCK_MASK;
604
605 rx_mem_addr.addr = (mem_block << 8) +
606 le32_to_cpu(wl_mem_map->packet_memory_pool_start);
607
608 rx_mem_addr.addr_extra = rx_mem_addr.addr + 4;
609
610 wl1271_write(wl, WL1271_SLV_REG_DATA,
611 &rx_mem_addr, sizeof(rx_mem_addr), false);
612 }
613}
614
615static int wl12xx_identify_chip(struct wl1271 *wl)
616{
617 int ret = 0;
618
619 switch (wl->chip.id) {
620 case CHIP_ID_1271_PG10:
621 wl1271_warning("chip id 0x%x (1271 PG10) support is obsolete",
622 wl->chip.id);
623
624 /* clear the alignment quirk, since we don't support it */
625 wl->quirks &= ~WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN;
626
627 wl->quirks |= WLCORE_QUIRK_LEGACY_NVS;
628 wl->sr_fw_name = WL127X_FW_NAME_SINGLE;
629 wl->mr_fw_name = WL127X_FW_NAME_MULTI;
630 memcpy(&wl->conf.mem, &wl12xx_default_priv_conf.mem_wl127x,
631 sizeof(wl->conf.mem));
632
633 /* read data preparation is only needed by wl127x */
634 wl->ops->prepare_read = wl127x_prepare_read;
635
636 break;
637
638 case CHIP_ID_1271_PG20:
639 wl1271_debug(DEBUG_BOOT, "chip id 0x%x (1271 PG20)",
640 wl->chip.id);
641
642 /* clear the alignment quirk, since we don't support it */
643 wl->quirks &= ~WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN;
644
645 wl->quirks |= WLCORE_QUIRK_LEGACY_NVS;
646 wl->plt_fw_name = WL127X_PLT_FW_NAME;
647 wl->sr_fw_name = WL127X_FW_NAME_SINGLE;
648 wl->mr_fw_name = WL127X_FW_NAME_MULTI;
649 memcpy(&wl->conf.mem, &wl12xx_default_priv_conf.mem_wl127x,
650 sizeof(wl->conf.mem));
651
652 /* read data preparation is only needed by wl127x */
653 wl->ops->prepare_read = wl127x_prepare_read;
654
655 break;
656
657 case CHIP_ID_1283_PG20:
658 wl1271_debug(DEBUG_BOOT, "chip id 0x%x (1283 PG20)",
659 wl->chip.id);
660 wl->plt_fw_name = WL128X_PLT_FW_NAME;
661 wl->sr_fw_name = WL128X_FW_NAME_SINGLE;
662 wl->mr_fw_name = WL128X_FW_NAME_MULTI;
663 break;
664 case CHIP_ID_1283_PG10:
665 default:
666 wl1271_warning("unsupported chip id: 0x%x", wl->chip.id);
667 ret = -ENODEV;
668 goto out;
669 }
670
671out:
672 return ret;
673}
674
675static void wl12xx_top_reg_write(struct wl1271 *wl, int addr, u16 val)
676{
677 /* write address >> 1 + 0x30000 to OCP_POR_CTR */
678 addr = (addr >> 1) + 0x30000;
679 wl1271_write32(wl, WL12XX_OCP_POR_CTR, addr);
680
681 /* write value to OCP_POR_WDATA */
682 wl1271_write32(wl, WL12XX_OCP_DATA_WRITE, val);
683
684 /* write 1 to OCP_CMD */
685 wl1271_write32(wl, WL12XX_OCP_CMD, OCP_CMD_WRITE);
686}
687
688static u16 wl12xx_top_reg_read(struct wl1271 *wl, int addr)
689{
690 u32 val;
691 int timeout = OCP_CMD_LOOP;
692
693 /* write address >> 1 + 0x30000 to OCP_POR_CTR */
694 addr = (addr >> 1) + 0x30000;
695 wl1271_write32(wl, WL12XX_OCP_POR_CTR, addr);
696
697 /* write 2 to OCP_CMD */
698 wl1271_write32(wl, WL12XX_OCP_CMD, OCP_CMD_READ);
699
700 /* poll for data ready */
701 do {
702 val = wl1271_read32(wl, WL12XX_OCP_DATA_READ);
703 } while (!(val & OCP_READY_MASK) && --timeout);
704
705 if (!timeout) {
706 wl1271_warning("Top register access timed out.");
707 return 0xffff;
708 }
709
710 /* check data status and return if OK */
711 if ((val & OCP_STATUS_MASK) == OCP_STATUS_OK)
712 return val & 0xffff;
713 else {
714 wl1271_warning("Top register access returned error.");
715 return 0xffff;
716 }
717}
718
719static int wl128x_switch_tcxo_to_fref(struct wl1271 *wl)
720{
721 u16 spare_reg;
722
723 /* Mask bits [2] & [8:4] in the sys_clk_cfg register */
724 spare_reg = wl12xx_top_reg_read(wl, WL_SPARE_REG);
725 if (spare_reg == 0xFFFF)
726 return -EFAULT;
727 spare_reg |= (BIT(3) | BIT(5) | BIT(6));
728 wl12xx_top_reg_write(wl, WL_SPARE_REG, spare_reg);
729
730 /* Enable FREF_CLK_REQ & mux MCS and coex PLLs to FREF */
731 wl12xx_top_reg_write(wl, SYS_CLK_CFG_REG,
732 WL_CLK_REQ_TYPE_PG2 | MCS_PLL_CLK_SEL_FREF);
733
734 /* Delay execution for 15msec, to let the HW settle */
735 mdelay(15);
736
737 return 0;
738}
739
740static bool wl128x_is_tcxo_valid(struct wl1271 *wl)
741{
742 u16 tcxo_detection;
743
744 tcxo_detection = wl12xx_top_reg_read(wl, TCXO_CLK_DETECT_REG);
745 if (tcxo_detection & TCXO_DET_FAILED)
746 return false;
747
748 return true;
749}
750
751static bool wl128x_is_fref_valid(struct wl1271 *wl)
752{
753 u16 fref_detection;
754
755 fref_detection = wl12xx_top_reg_read(wl, FREF_CLK_DETECT_REG);
756 if (fref_detection & FREF_CLK_DETECT_FAIL)
757 return false;
758
759 return true;
760}
761
762static int wl128x_manually_configure_mcs_pll(struct wl1271 *wl)
763{
764 wl12xx_top_reg_write(wl, MCS_PLL_M_REG, MCS_PLL_M_REG_VAL);
765 wl12xx_top_reg_write(wl, MCS_PLL_N_REG, MCS_PLL_N_REG_VAL);
766 wl12xx_top_reg_write(wl, MCS_PLL_CONFIG_REG, MCS_PLL_CONFIG_REG_VAL);
767
768 return 0;
769}
770
771static int wl128x_configure_mcs_pll(struct wl1271 *wl, int clk)
772{
773 u16 spare_reg;
774 u16 pll_config;
775 u8 input_freq;
776
777 /* Mask bits [3:1] in the sys_clk_cfg register */
778 spare_reg = wl12xx_top_reg_read(wl, WL_SPARE_REG);
779 if (spare_reg == 0xFFFF)
780 return -EFAULT;
781 spare_reg |= BIT(2);
782 wl12xx_top_reg_write(wl, WL_SPARE_REG, spare_reg);
783
784 /* Handle special cases of the TCXO clock */
785 if (wl->tcxo_clock == WL12XX_TCXOCLOCK_16_8 ||
786 wl->tcxo_clock == WL12XX_TCXOCLOCK_33_6)
787 return wl128x_manually_configure_mcs_pll(wl);
788
789 /* Set the input frequency according to the selected clock source */
790 input_freq = (clk & 1) + 1;
791
792 pll_config = wl12xx_top_reg_read(wl, MCS_PLL_CONFIG_REG);
793 if (pll_config == 0xFFFF)
794 return -EFAULT;
795 pll_config |= (input_freq << MCS_SEL_IN_FREQ_SHIFT);
796 pll_config |= MCS_PLL_ENABLE_HP;
797 wl12xx_top_reg_write(wl, MCS_PLL_CONFIG_REG, pll_config);
798
799 return 0;
800}
801
802/*
803 * WL128x has two clocks input - TCXO and FREF.
804 * TCXO is the main clock of the device, while FREF is used to sync
805 * between the GPS and the cellular modem.
806 * In cases where TCXO is 32.736MHz or 16.368MHz, the FREF will be used
807 * as the WLAN/BT main clock.
808 */
809static int wl128x_boot_clk(struct wl1271 *wl, int *selected_clock)
810{
811 u16 sys_clk_cfg;
812
813 /* For XTAL-only modes, FREF will be used after switching from TCXO */
814 if (wl->ref_clock == WL12XX_REFCLOCK_26_XTAL ||
815 wl->ref_clock == WL12XX_REFCLOCK_38_XTAL) {
816 if (!wl128x_switch_tcxo_to_fref(wl))
817 return -EINVAL;
818 goto fref_clk;
819 }
820
821 /* Query the HW, to determine which clock source we should use */
822 sys_clk_cfg = wl12xx_top_reg_read(wl, SYS_CLK_CFG_REG);
823 if (sys_clk_cfg == 0xFFFF)
824 return -EINVAL;
825 if (sys_clk_cfg & PRCM_CM_EN_MUX_WLAN_FREF)
826 goto fref_clk;
827
828 /* If TCXO is either 32.736MHz or 16.368MHz, switch to FREF */
829 if (wl->tcxo_clock == WL12XX_TCXOCLOCK_16_368 ||
830 wl->tcxo_clock == WL12XX_TCXOCLOCK_32_736) {
831 if (!wl128x_switch_tcxo_to_fref(wl))
832 return -EINVAL;
833 goto fref_clk;
834 }
835
836 /* TCXO clock is selected */
837 if (!wl128x_is_tcxo_valid(wl))
838 return -EINVAL;
839 *selected_clock = wl->tcxo_clock;
840 goto config_mcs_pll;
841
842fref_clk:
843 /* FREF clock is selected */
844 if (!wl128x_is_fref_valid(wl))
845 return -EINVAL;
846 *selected_clock = wl->ref_clock;
847
848config_mcs_pll:
849 return wl128x_configure_mcs_pll(wl, *selected_clock);
850}
851
852static int wl127x_boot_clk(struct wl1271 *wl)
853{
854 u32 pause;
855 u32 clk;
856
857 if (WL127X_PG_GET_MAJOR(wl->hw_pg_ver) < 3)
858 wl->quirks |= WLCORE_QUIRK_END_OF_TRANSACTION;
859
860 if (wl->ref_clock == CONF_REF_CLK_19_2_E ||
861 wl->ref_clock == CONF_REF_CLK_38_4_E ||
862 wl->ref_clock == CONF_REF_CLK_38_4_M_XTAL)
863 /* ref clk: 19.2/38.4/38.4-XTAL */
864 clk = 0x3;
865 else if (wl->ref_clock == CONF_REF_CLK_26_E ||
866 wl->ref_clock == CONF_REF_CLK_52_E)
867 /* ref clk: 26/52 */
868 clk = 0x5;
869 else
870 return -EINVAL;
871
872 if (wl->ref_clock != CONF_REF_CLK_19_2_E) {
873 u16 val;
874 /* Set clock type (open drain) */
875 val = wl12xx_top_reg_read(wl, OCP_REG_CLK_TYPE);
876 val &= FREF_CLK_TYPE_BITS;
877 wl12xx_top_reg_write(wl, OCP_REG_CLK_TYPE, val);
878
879 /* Set clock pull mode (no pull) */
880 val = wl12xx_top_reg_read(wl, OCP_REG_CLK_PULL);
881 val |= NO_PULL;
882 wl12xx_top_reg_write(wl, OCP_REG_CLK_PULL, val);
883 } else {
884 u16 val;
885 /* Set clock polarity */
886 val = wl12xx_top_reg_read(wl, OCP_REG_CLK_POLARITY);
887 val &= FREF_CLK_POLARITY_BITS;
888 val |= CLK_REQ_OUTN_SEL;
889 wl12xx_top_reg_write(wl, OCP_REG_CLK_POLARITY, val);
890 }
891
892 wl1271_write32(wl, WL12XX_PLL_PARAMETERS, clk);
893
894 pause = wl1271_read32(wl, WL12XX_PLL_PARAMETERS);
895
896 wl1271_debug(DEBUG_BOOT, "pause1 0x%x", pause);
897
898 pause &= ~(WU_COUNTER_PAUSE_VAL);
899 pause |= WU_COUNTER_PAUSE_VAL;
900 wl1271_write32(wl, WL12XX_WU_COUNTER_PAUSE, pause);
901
902 return 0;
903}
904
905static int wl1271_boot_soft_reset(struct wl1271 *wl)
906{
907 unsigned long timeout;
908 u32 boot_data;
909
910 /* perform soft reset */
911 wl1271_write32(wl, WL12XX_SLV_SOFT_RESET, ACX_SLV_SOFT_RESET_BIT);
912
913 /* SOFT_RESET is self clearing */
914 timeout = jiffies + usecs_to_jiffies(SOFT_RESET_MAX_TIME);
915 while (1) {
916 boot_data = wl1271_read32(wl, WL12XX_SLV_SOFT_RESET);
917 wl1271_debug(DEBUG_BOOT, "soft reset bootdata 0x%x", boot_data);
918 if ((boot_data & ACX_SLV_SOFT_RESET_BIT) == 0)
919 break;
920
921 if (time_after(jiffies, timeout)) {
922 /* 1.2 check pWhalBus->uSelfClearTime if the
923 * timeout was reached */
924 wl1271_error("soft reset timeout");
925 return -1;
926 }
927
928 udelay(SOFT_RESET_STALL_TIME);
929 }
930
931 /* disable Rx/Tx */
932 wl1271_write32(wl, WL12XX_ENABLE, 0x0);
933
934 /* disable auto calibration on start*/
935 wl1271_write32(wl, WL12XX_SPARE_A2, 0xffff);
936
937 return 0;
938}
939
940static int wl12xx_pre_boot(struct wl1271 *wl)
941{
942 int ret = 0;
943 u32 clk;
944 int selected_clock = -1;
945
946 if (wl->chip.id == CHIP_ID_1283_PG20) {
947 ret = wl128x_boot_clk(wl, &selected_clock);
948 if (ret < 0)
949 goto out;
950 } else {
951 ret = wl127x_boot_clk(wl);
952 if (ret < 0)
953 goto out;
954 }
955
956 /* Continue the ELP wake up sequence */
957 wl1271_write32(wl, WL12XX_WELP_ARM_COMMAND, WELP_ARM_COMMAND_VAL);
958 udelay(500);
959
960 wlcore_set_partition(wl, &wl->ptable[PART_DRPW]);
961
962 /* Read-modify-write DRPW_SCRATCH_START register (see next state)
963 to be used by DRPw FW. The RTRIM value will be added by the FW
964 before taking DRPw out of reset */
965
966 clk = wl1271_read32(wl, WL12XX_DRPW_SCRATCH_START);
967
968 wl1271_debug(DEBUG_BOOT, "clk2 0x%x", clk);
969
970 if (wl->chip.id == CHIP_ID_1283_PG20)
971 clk |= ((selected_clock & 0x3) << 1) << 4;
972 else
973 clk |= (wl->ref_clock << 1) << 4;
974
975 wl1271_write32(wl, WL12XX_DRPW_SCRATCH_START, clk);
976
977 wlcore_set_partition(wl, &wl->ptable[PART_WORK]);
978
979 /* Disable interrupts */
980 wlcore_write_reg(wl, REG_INTERRUPT_MASK, WL1271_ACX_INTR_ALL);
981
982 ret = wl1271_boot_soft_reset(wl);
983 if (ret < 0)
984 goto out;
985
986out:
987 return ret;
988}
989
990static void wl12xx_pre_upload(struct wl1271 *wl)
991{
992 u32 tmp;
993
994 /* write firmware's last address (ie. it's length) to
995 * ACX_EEPROMLESS_IND_REG */
996 wl1271_debug(DEBUG_BOOT, "ACX_EEPROMLESS_IND_REG");
997
998 wl1271_write32(wl, WL12XX_EEPROMLESS_IND, WL12XX_EEPROMLESS_IND);
999
1000 tmp = wlcore_read_reg(wl, REG_CHIP_ID_B);
1001
1002 wl1271_debug(DEBUG_BOOT, "chip id 0x%x", tmp);
1003
1004 /* 6. read the EEPROM parameters */
1005 tmp = wl1271_read32(wl, WL12XX_SCR_PAD2);
1006
1007 /* WL1271: The reference driver skips steps 7 to 10 (jumps directly
1008 * to upload_fw) */
1009
1010 if (wl->chip.id == CHIP_ID_1283_PG20)
1011 wl12xx_top_reg_write(wl, SDIO_IO_DS, HCI_IO_DS_6MA);
1012}
1013
1014static void wl12xx_enable_interrupts(struct wl1271 *wl)
1015{
1016 u32 polarity;
1017
1018 polarity = wl12xx_top_reg_read(wl, OCP_REG_POLARITY);
1019
1020 /* We use HIGH polarity, so unset the LOW bit */
1021 polarity &= ~POLARITY_LOW;
1022 wl12xx_top_reg_write(wl, OCP_REG_POLARITY, polarity);
1023
1024 wlcore_write_reg(wl, REG_INTERRUPT_MASK, WL1271_ACX_ALL_EVENTS_VECTOR);
1025
1026 wlcore_enable_interrupts(wl);
1027 wlcore_write_reg(wl, REG_INTERRUPT_MASK,
1028 WL1271_ACX_INTR_ALL & ~(WL1271_INTR_MASK));
1029
1030 wl1271_write32(wl, WL12XX_HI_CFG, HI_CFG_DEF_VAL);
1031}
1032
1033static int wl12xx_boot(struct wl1271 *wl)
1034{
1035 int ret;
1036
1037 ret = wl12xx_pre_boot(wl);
1038 if (ret < 0)
1039 goto out;
1040
1041 ret = wlcore_boot_upload_nvs(wl);
1042 if (ret < 0)
1043 goto out;
1044
1045 wl12xx_pre_upload(wl);
1046
1047 ret = wlcore_boot_upload_firmware(wl);
1048 if (ret < 0)
1049 goto out;
1050
1051 ret = wlcore_boot_run_firmware(wl);
1052 if (ret < 0)
1053 goto out;
1054
1055 wl12xx_enable_interrupts(wl);
1056
1057out:
1058 return ret;
1059}
1060
1061static void wl12xx_trigger_cmd(struct wl1271 *wl, int cmd_box_addr,
1062 void *buf, size_t len)
1063{
1064 wl1271_write(wl, cmd_box_addr, buf, len, false);
1065 wlcore_write_reg(wl, REG_INTERRUPT_TRIG, WL12XX_INTR_TRIG_CMD);
1066}
1067
1068static void wl12xx_ack_event(struct wl1271 *wl)
1069{
1070 wlcore_write_reg(wl, REG_INTERRUPT_TRIG, WL12XX_INTR_TRIG_EVENT_ACK);
1071}
1072
1073static u32 wl12xx_calc_tx_blocks(struct wl1271 *wl, u32 len, u32 spare_blks)
1074{
1075 u32 blk_size = WL12XX_TX_HW_BLOCK_SIZE;
1076 u32 align_len = wlcore_calc_packet_alignment(wl, len);
1077
1078 return (align_len + blk_size - 1) / blk_size + spare_blks;
1079}
1080
1081static void
1082wl12xx_set_tx_desc_blocks(struct wl1271 *wl, struct wl1271_tx_hw_descr *desc,
1083 u32 blks, u32 spare_blks)
1084{
1085 if (wl->chip.id == CHIP_ID_1283_PG20) {
1086 desc->wl128x_mem.total_mem_blocks = blks;
1087 } else {
1088 desc->wl127x_mem.extra_blocks = spare_blks;
1089 desc->wl127x_mem.total_mem_blocks = blks;
1090 }
1091}
1092
1093static void
1094wl12xx_set_tx_desc_data_len(struct wl1271 *wl, struct wl1271_tx_hw_descr *desc,
1095 struct sk_buff *skb)
1096{
1097 u32 aligned_len = wlcore_calc_packet_alignment(wl, skb->len);
1098
1099 if (wl->chip.id == CHIP_ID_1283_PG20) {
1100 desc->wl128x_mem.extra_bytes = aligned_len - skb->len;
1101 desc->length = cpu_to_le16(aligned_len >> 2);
1102
1103 wl1271_debug(DEBUG_TX,
1104 "tx_fill_hdr: hlid: %d len: %d life: %d mem: %d extra: %d",
1105 desc->hlid,
1106 le16_to_cpu(desc->length),
1107 le16_to_cpu(desc->life_time),
1108 desc->wl128x_mem.total_mem_blocks,
1109 desc->wl128x_mem.extra_bytes);
1110 } else {
1111 /* calculate number of padding bytes */
1112 int pad = aligned_len - skb->len;
1113 desc->tx_attr |=
1114 cpu_to_le16(pad << TX_HW_ATTR_OFST_LAST_WORD_PAD);
1115
1116 /* Store the aligned length in terms of words */
1117 desc->length = cpu_to_le16(aligned_len >> 2);
1118
1119 wl1271_debug(DEBUG_TX,
1120 "tx_fill_hdr: pad: %d hlid: %d len: %d life: %d mem: %d",
1121 pad, desc->hlid,
1122 le16_to_cpu(desc->length),
1123 le16_to_cpu(desc->life_time),
1124 desc->wl127x_mem.total_mem_blocks);
1125 }
1126}
1127
1128static enum wl_rx_buf_align
1129wl12xx_get_rx_buf_align(struct wl1271 *wl, u32 rx_desc)
1130{
1131 if (rx_desc & RX_BUF_UNALIGNED_PAYLOAD)
1132 return WLCORE_RX_BUF_UNALIGNED;
1133
1134 return WLCORE_RX_BUF_ALIGNED;
1135}
1136
1137static u32 wl12xx_get_rx_packet_len(struct wl1271 *wl, void *rx_data,
1138 u32 data_len)
1139{
1140 struct wl1271_rx_descriptor *desc = rx_data;
1141
1142 /* invalid packet */
1143 if (data_len < sizeof(*desc) ||
1144 data_len < sizeof(*desc) + desc->pad_len)
1145 return 0;
1146
1147 return data_len - sizeof(*desc) - desc->pad_len;
1148}
1149
1150static void wl12xx_tx_delayed_compl(struct wl1271 *wl)
1151{
1152 if (wl->fw_status->tx_results_counter == (wl->tx_results_count & 0xff))
1153 return;
1154
1155 wl1271_tx_complete(wl);
1156}
1157
1158static int wl12xx_hw_init(struct wl1271 *wl)
1159{
1160 int ret;
1161
1162 if (wl->chip.id == CHIP_ID_1283_PG20) {
1163 u32 host_cfg_bitmap = HOST_IF_CFG_RX_FIFO_ENABLE;
1164
1165 ret = wl128x_cmd_general_parms(wl);
1166 if (ret < 0)
1167 goto out;
1168 ret = wl128x_cmd_radio_parms(wl);
1169 if (ret < 0)
1170 goto out;
1171
1172 if (wl->quirks & WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN)
1173 /* Enable SDIO padding */
1174 host_cfg_bitmap |= HOST_IF_CFG_TX_PAD_TO_SDIO_BLK;
1175
1176 /* Must be before wl1271_acx_init_mem_config() */
1177 ret = wl1271_acx_host_if_cfg_bitmap(wl, host_cfg_bitmap);
1178 if (ret < 0)
1179 goto out;
1180 } else {
1181 ret = wl1271_cmd_general_parms(wl);
1182 if (ret < 0)
1183 goto out;
1184 ret = wl1271_cmd_radio_parms(wl);
1185 if (ret < 0)
1186 goto out;
1187 ret = wl1271_cmd_ext_radio_parms(wl);
1188 if (ret < 0)
1189 goto out;
1190 }
1191out:
1192 return ret;
1193}
1194
1195static u32 wl12xx_sta_get_ap_rate_mask(struct wl1271 *wl,
1196 struct wl12xx_vif *wlvif)
1197{
1198 return wlvif->rate_set;
1199}
1200
1201static int wl12xx_identify_fw(struct wl1271 *wl)
1202{
1203 unsigned int *fw_ver = wl->chip.fw_ver;
1204
1205 /* Only new station firmwares support routing fw logs to the host */
1206 if ((fw_ver[FW_VER_IF_TYPE] == FW_VER_IF_TYPE_STA) &&
1207 (fw_ver[FW_VER_MINOR] < FW_VER_MINOR_FWLOG_STA_MIN))
1208 wl->quirks |= WLCORE_QUIRK_FWLOG_NOT_IMPLEMENTED;
1209
1210 /* This feature is not yet supported for AP mode */
1211 if (fw_ver[FW_VER_IF_TYPE] == FW_VER_IF_TYPE_AP)
1212 wl->quirks |= WLCORE_QUIRK_FWLOG_NOT_IMPLEMENTED;
1213
1214 return 0;
1215}
1216
1217static void wl12xx_conf_init(struct wl1271 *wl)
1218{
1219 struct wl12xx_priv *priv = wl->priv;
1220
1221 /* apply driver default configuration */
1222 memcpy(&wl->conf, &wl12xx_conf, sizeof(wl12xx_conf));
1223
1224 /* apply default private configuration */
1225 memcpy(&priv->conf, &wl12xx_default_priv_conf, sizeof(priv->conf));
1226}
1227
1228static bool wl12xx_mac_in_fuse(struct wl1271 *wl)
1229{
1230 bool supported = false;
1231 u8 major, minor;
1232
1233 if (wl->chip.id == CHIP_ID_1283_PG20) {
1234 major = WL128X_PG_GET_MAJOR(wl->hw_pg_ver);
1235 minor = WL128X_PG_GET_MINOR(wl->hw_pg_ver);
1236
1237 /* in wl128x we have the MAC address if the PG is >= (2, 1) */
1238 if (major > 2 || (major == 2 && minor >= 1))
1239 supported = true;
1240 } else {
1241 major = WL127X_PG_GET_MAJOR(wl->hw_pg_ver);
1242 minor = WL127X_PG_GET_MINOR(wl->hw_pg_ver);
1243
1244 /* in wl127x we have the MAC address if the PG is >= (3, 1) */
1245 if (major == 3 && minor >= 1)
1246 supported = true;
1247 }
1248
1249 wl1271_debug(DEBUG_PROBE,
1250 "PG Ver major = %d minor = %d, MAC %s present",
1251 major, minor, supported ? "is" : "is not");
1252
1253 return supported;
1254}
1255
1256static void wl12xx_get_fuse_mac(struct wl1271 *wl)
1257{
1258 u32 mac1, mac2;
1259
1260 wlcore_set_partition(wl, &wl->ptable[PART_DRPW]);
1261
1262 mac1 = wl1271_read32(wl, WL12XX_REG_FUSE_BD_ADDR_1);
1263 mac2 = wl1271_read32(wl, WL12XX_REG_FUSE_BD_ADDR_2);
1264
1265 /* these are the two parts of the BD_ADDR */
1266 wl->fuse_oui_addr = ((mac2 & 0xffff) << 8) +
1267 ((mac1 & 0xff000000) >> 24);
1268 wl->fuse_nic_addr = mac1 & 0xffffff;
1269
1270 wlcore_set_partition(wl, &wl->ptable[PART_DOWN]);
1271}
1272
1273static s8 wl12xx_get_pg_ver(struct wl1271 *wl)
1274{
1275 u32 die_info;
1276
1277 if (wl->chip.id == CHIP_ID_1283_PG20)
1278 die_info = wl12xx_top_reg_read(wl, WL128X_REG_FUSE_DATA_2_1);
1279 else
1280 die_info = wl12xx_top_reg_read(wl, WL127X_REG_FUSE_DATA_2_1);
1281
1282 return (s8) (die_info & PG_VER_MASK) >> PG_VER_OFFSET;
1283}
1284
1285static void wl12xx_get_mac(struct wl1271 *wl)
1286{
1287 if (wl12xx_mac_in_fuse(wl))
1288 wl12xx_get_fuse_mac(wl);
1289}
1290
1291static struct wlcore_ops wl12xx_ops = {
1292 .identify_chip = wl12xx_identify_chip,
1293 .identify_fw = wl12xx_identify_fw,
1294 .boot = wl12xx_boot,
1295 .trigger_cmd = wl12xx_trigger_cmd,
1296 .ack_event = wl12xx_ack_event,
1297 .calc_tx_blocks = wl12xx_calc_tx_blocks,
1298 .set_tx_desc_blocks = wl12xx_set_tx_desc_blocks,
1299 .set_tx_desc_data_len = wl12xx_set_tx_desc_data_len,
1300 .get_rx_buf_align = wl12xx_get_rx_buf_align,
1301 .get_rx_packet_len = wl12xx_get_rx_packet_len,
1302 .tx_immediate_compl = NULL,
1303 .tx_delayed_compl = wl12xx_tx_delayed_compl,
1304 .hw_init = wl12xx_hw_init,
1305 .init_vif = NULL,
1306 .sta_get_ap_rate_mask = wl12xx_sta_get_ap_rate_mask,
1307 .get_pg_ver = wl12xx_get_pg_ver,
1308 .get_mac = wl12xx_get_mac,
1309};
1310
1311static struct ieee80211_sta_ht_cap wl12xx_ht_cap = {
1312 .cap = IEEE80211_HT_CAP_GRN_FLD | IEEE80211_HT_CAP_SGI_20 |
1313 (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT),
1314 .ht_supported = true,
1315 .ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K,
1316 .ampdu_density = IEEE80211_HT_MPDU_DENSITY_8,
1317 .mcs = {
1318 .rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
1319 .rx_highest = cpu_to_le16(72),
1320 .tx_params = IEEE80211_HT_MCS_TX_DEFINED,
1321 },
1322};
1323
1324static int __devinit wl12xx_probe(struct platform_device *pdev)
1325{
1326 struct wl1271 *wl;
1327 struct ieee80211_hw *hw;
1328 struct wl12xx_priv *priv;
1329
1330 hw = wlcore_alloc_hw(sizeof(*priv));
1331 if (IS_ERR(hw)) {
1332 wl1271_error("can't allocate hw");
1333 return PTR_ERR(hw);
1334 }
1335
1336 wl = hw->priv;
1337 wl->ops = &wl12xx_ops;
1338 wl->ptable = wl12xx_ptable;
1339 wl->rtable = wl12xx_rtable;
1340 wl->num_tx_desc = 16;
1341 wl->normal_tx_spare = WL12XX_TX_HW_BLOCK_SPARE_DEFAULT;
1342 wl->gem_tx_spare = WL12XX_TX_HW_BLOCK_GEM_SPARE;
1343 wl->band_rate_to_idx = wl12xx_band_rate_to_idx;
1344 wl->hw_tx_rate_tbl_size = WL12XX_CONF_HW_RXTX_RATE_MAX;
1345 wl->hw_min_ht_rate = WL12XX_CONF_HW_RXTX_RATE_MCS0;
1346 wl->fw_status_priv_len = 0;
1347 memcpy(&wl->ht_cap, &wl12xx_ht_cap, sizeof(wl12xx_ht_cap));
1348 wl12xx_conf_init(wl);
1349
1350 return wlcore_probe(wl, pdev);
1351}
1352
1353static const struct platform_device_id wl12xx_id_table[] __devinitconst = {
1354 { "wl12xx", 0 },
1355 { } /* Terminating Entry */
1356};
1357MODULE_DEVICE_TABLE(platform, wl12xx_id_table);
1358
1359static struct platform_driver wl12xx_driver = {
1360 .probe = wl12xx_probe,
1361 .remove = __devexit_p(wlcore_remove),
1362 .id_table = wl12xx_id_table,
1363 .driver = {
1364 .name = "wl12xx_driver",
1365 .owner = THIS_MODULE,
1366 }
1367};
1368
1369static int __init wl12xx_init(void)
1370{
1371 return platform_driver_register(&wl12xx_driver);
1372}
1373module_init(wl12xx_init);
1374
1375static void __exit wl12xx_exit(void)
1376{
1377 platform_driver_unregister(&wl12xx_driver);
1378}
1379module_exit(wl12xx_exit);
1380
1381MODULE_LICENSE("GPL v2");
1382MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>");
1383MODULE_FIRMWARE(WL127X_FW_NAME_SINGLE);
1384MODULE_FIRMWARE(WL127X_FW_NAME_MULTI);
1385MODULE_FIRMWARE(WL127X_PLT_FW_NAME);
1386MODULE_FIRMWARE(WL128X_FW_NAME_SINGLE);
1387MODULE_FIRMWARE(WL128X_FW_NAME_MULTI);
1388MODULE_FIRMWARE(WL128X_PLT_FW_NAME);
diff --git a/drivers/net/wireless/wl12xx/reg.h b/drivers/net/wireless/ti/wl12xx/reg.h
index 340db324bc26..79ede02e2587 100644
--- a/drivers/net/wireless/wl12xx/reg.h
+++ b/drivers/net/wireless/ti/wl12xx/reg.h
@@ -33,16 +33,8 @@
33#define REGISTERS_DOWN_SIZE 0x00008800 33#define REGISTERS_DOWN_SIZE 0x00008800
34#define REGISTERS_WORK_SIZE 0x0000b000 34#define REGISTERS_WORK_SIZE 0x0000b000
35 35
36#define HW_ACCESS_ELP_CTRL_REG_ADDR 0x1FFFC
37#define FW_STATUS_ADDR (0x14FC0 + 0xA000) 36#define FW_STATUS_ADDR (0x14FC0 + 0xA000)
38 37
39/* ELP register commands */
40#define ELPCTRL_WAKE_UP 0x1
41#define ELPCTRL_WAKE_UP_WLAN_READY 0x5
42#define ELPCTRL_SLEEP 0x0
43/* ELP WLAN_READY bit */
44#define ELPCTRL_WLAN_READY 0x2
45
46/*=============================================== 38/*===============================================
47 Host Software Reset - 32bit RW 39 Host Software Reset - 32bit RW
48 ------------------------------------------ 40 ------------------------------------------
@@ -57,14 +49,14 @@
57 (not self-clearing), the Wlan hardware 49 (not self-clearing), the Wlan hardware
58 exits the software reset state. 50 exits the software reset state.
59===============================================*/ 51===============================================*/
60#define ACX_REG_SLV_SOFT_RESET (REGISTERS_BASE + 0x0000) 52#define WL12XX_SLV_SOFT_RESET (REGISTERS_BASE + 0x0000)
61 53
62#define WL1271_SLV_REG_DATA (REGISTERS_BASE + 0x0008) 54#define WL1271_SLV_REG_DATA (REGISTERS_BASE + 0x0008)
63#define WL1271_SLV_REG_ADATA (REGISTERS_BASE + 0x000c) 55#define WL1271_SLV_REG_ADATA (REGISTERS_BASE + 0x000c)
64#define WL1271_SLV_MEM_DATA (REGISTERS_BASE + 0x0018) 56#define WL1271_SLV_MEM_DATA (REGISTERS_BASE + 0x0018)
65 57
66#define ACX_REG_INTERRUPT_TRIG (REGISTERS_BASE + 0x0474) 58#define WL12XX_REG_INTERRUPT_TRIG (REGISTERS_BASE + 0x0474)
67#define ACX_REG_INTERRUPT_TRIG_H (REGISTERS_BASE + 0x0478) 59#define WL12XX_REG_INTERRUPT_TRIG_H (REGISTERS_BASE + 0x0478)
68 60
69/*============================================= 61/*=============================================
70 Host Interrupt Mask Register - 32bit (RW) 62 Host Interrupt Mask Register - 32bit (RW)
@@ -94,7 +86,7 @@
94 21- - 86 21- -
95 Default: 0x0001 87 Default: 0x0001
96*==============================================*/ 88*==============================================*/
97#define ACX_REG_INTERRUPT_MASK (REGISTERS_BASE + 0x04DC) 89#define WL12XX_REG_INTERRUPT_MASK (REGISTERS_BASE + 0x04DC)
98 90
99/*============================================= 91/*=============================================
100 Host Interrupt Mask Set 16bit, (Write only) 92 Host Interrupt Mask Set 16bit, (Write only)
@@ -125,7 +117,7 @@
125 Reading this register doesn't 117 Reading this register doesn't
126 effect its content. 118 effect its content.
127=============================================*/ 119=============================================*/
128#define ACX_REG_INTERRUPT_NO_CLEAR (REGISTERS_BASE + 0x04E8) 120#define WL12XX_REG_INTERRUPT_NO_CLEAR (REGISTERS_BASE + 0x04E8)
129 121
130/*============================================= 122/*=============================================
131 Host Interrupt Status Clear on Read Register 123 Host Interrupt Status Clear on Read Register
@@ -148,9 +140,9 @@
148 HINT_STS_ND registers, thus making the 140 HINT_STS_ND registers, thus making the
149 assotiated interrupt inactive. (0-no effect) 141 assotiated interrupt inactive. (0-no effect)
150==============================================*/ 142==============================================*/
151#define ACX_REG_INTERRUPT_ACK (REGISTERS_BASE + 0x04F0) 143#define WL12XX_REG_INTERRUPT_ACK (REGISTERS_BASE + 0x04F0)
152 144
153#define RX_DRIVER_COUNTER_ADDRESS (REGISTERS_BASE + 0x0538) 145#define WL12XX_REG_RX_DRIVER_COUNTER (REGISTERS_BASE + 0x0538)
154 146
155/* Device Configuration registers*/ 147/* Device Configuration registers*/
156#define SOR_CFG (REGISTERS_BASE + 0x0800) 148#define SOR_CFG (REGISTERS_BASE + 0x0800)
@@ -175,9 +167,9 @@
175 1 halt eCPU 167 1 halt eCPU
176 0 enable eCPU 168 0 enable eCPU
177 ===============================================*/ 169 ===============================================*/
178#define ACX_REG_ECPU_CONTROL (REGISTERS_BASE + 0x0804) 170#define WL12XX_REG_ECPU_CONTROL (REGISTERS_BASE + 0x0804)
179 171
180#define HI_CFG (REGISTERS_BASE + 0x0808) 172#define WL12XX_HI_CFG (REGISTERS_BASE + 0x0808)
181 173
182/*=============================================== 174/*===============================================
183 EEPROM Burst Read Start - 32bit RW 175 EEPROM Burst Read Start - 32bit RW
@@ -196,72 +188,67 @@
196*================================================*/ 188*================================================*/
197#define ACX_REG_EE_START (REGISTERS_BASE + 0x080C) 189#define ACX_REG_EE_START (REGISTERS_BASE + 0x080C)
198 190
199#define OCP_POR_CTR (REGISTERS_BASE + 0x09B4) 191#define WL12XX_OCP_POR_CTR (REGISTERS_BASE + 0x09B4)
200#define OCP_DATA_WRITE (REGISTERS_BASE + 0x09B8) 192#define WL12XX_OCP_DATA_WRITE (REGISTERS_BASE + 0x09B8)
201#define OCP_DATA_READ (REGISTERS_BASE + 0x09BC) 193#define WL12XX_OCP_DATA_READ (REGISTERS_BASE + 0x09BC)
202#define OCP_CMD (REGISTERS_BASE + 0x09C0) 194#define WL12XX_OCP_CMD (REGISTERS_BASE + 0x09C0)
203
204#define WL1271_HOST_WR_ACCESS (REGISTERS_BASE + 0x09F8)
205 195
206#define CHIP_ID_B (REGISTERS_BASE + 0x5674) 196#define WL12XX_HOST_WR_ACCESS (REGISTERS_BASE + 0x09F8)
207 197
208#define CHIP_ID_1271_PG10 (0x4030101) 198#define WL12XX_CHIP_ID_B (REGISTERS_BASE + 0x5674)
209#define CHIP_ID_1271_PG20 (0x4030111)
210#define CHIP_ID_1283_PG10 (0x05030101)
211#define CHIP_ID_1283_PG20 (0x05030111)
212 199
213#define ENABLE (REGISTERS_BASE + 0x5450) 200#define WL12XX_ENABLE (REGISTERS_BASE + 0x5450)
214 201
215/* Power Management registers */ 202/* Power Management registers */
216#define ELP_CFG_MODE (REGISTERS_BASE + 0x5804) 203#define WL12XX_ELP_CFG_MODE (REGISTERS_BASE + 0x5804)
217#define ELP_CMD (REGISTERS_BASE + 0x5808) 204#define WL12XX_ELP_CMD (REGISTERS_BASE + 0x5808)
218#define PLL_CAL_TIME (REGISTERS_BASE + 0x5810) 205#define WL12XX_PLL_CAL_TIME (REGISTERS_BASE + 0x5810)
219#define CLK_REQ_TIME (REGISTERS_BASE + 0x5814) 206#define WL12XX_CLK_REQ_TIME (REGISTERS_BASE + 0x5814)
220#define CLK_BUF_TIME (REGISTERS_BASE + 0x5818) 207#define WL12XX_CLK_BUF_TIME (REGISTERS_BASE + 0x5818)
221 208
222#define CFG_PLL_SYNC_CNT (REGISTERS_BASE + 0x5820) 209#define WL12XX_CFG_PLL_SYNC_CNT (REGISTERS_BASE + 0x5820)
223 210
224/* Scratch Pad registers*/ 211/* Scratch Pad registers*/
225#define SCR_PAD0 (REGISTERS_BASE + 0x5608) 212#define WL12XX_SCR_PAD0 (REGISTERS_BASE + 0x5608)
226#define SCR_PAD1 (REGISTERS_BASE + 0x560C) 213#define WL12XX_SCR_PAD1 (REGISTERS_BASE + 0x560C)
227#define SCR_PAD2 (REGISTERS_BASE + 0x5610) 214#define WL12XX_SCR_PAD2 (REGISTERS_BASE + 0x5610)
228#define SCR_PAD3 (REGISTERS_BASE + 0x5614) 215#define WL12XX_SCR_PAD3 (REGISTERS_BASE + 0x5614)
229#define SCR_PAD4 (REGISTERS_BASE + 0x5618) 216#define WL12XX_SCR_PAD4 (REGISTERS_BASE + 0x5618)
230#define SCR_PAD4_SET (REGISTERS_BASE + 0x561C) 217#define WL12XX_SCR_PAD4_SET (REGISTERS_BASE + 0x561C)
231#define SCR_PAD4_CLR (REGISTERS_BASE + 0x5620) 218#define WL12XX_SCR_PAD4_CLR (REGISTERS_BASE + 0x5620)
232#define SCR_PAD5 (REGISTERS_BASE + 0x5624) 219#define WL12XX_SCR_PAD5 (REGISTERS_BASE + 0x5624)
233#define SCR_PAD5_SET (REGISTERS_BASE + 0x5628) 220#define WL12XX_SCR_PAD5_SET (REGISTERS_BASE + 0x5628)
234#define SCR_PAD5_CLR (REGISTERS_BASE + 0x562C) 221#define WL12XX_SCR_PAD5_CLR (REGISTERS_BASE + 0x562C)
235#define SCR_PAD6 (REGISTERS_BASE + 0x5630) 222#define WL12XX_SCR_PAD6 (REGISTERS_BASE + 0x5630)
236#define SCR_PAD7 (REGISTERS_BASE + 0x5634) 223#define WL12XX_SCR_PAD7 (REGISTERS_BASE + 0x5634)
237#define SCR_PAD8 (REGISTERS_BASE + 0x5638) 224#define WL12XX_SCR_PAD8 (REGISTERS_BASE + 0x5638)
238#define SCR_PAD9 (REGISTERS_BASE + 0x563C) 225#define WL12XX_SCR_PAD9 (REGISTERS_BASE + 0x563C)
239 226
240/* Spare registers*/ 227/* Spare registers*/
241#define SPARE_A1 (REGISTERS_BASE + 0x0994) 228#define WL12XX_SPARE_A1 (REGISTERS_BASE + 0x0994)
242#define SPARE_A2 (REGISTERS_BASE + 0x0998) 229#define WL12XX_SPARE_A2 (REGISTERS_BASE + 0x0998)
243#define SPARE_A3 (REGISTERS_BASE + 0x099C) 230#define WL12XX_SPARE_A3 (REGISTERS_BASE + 0x099C)
244#define SPARE_A4 (REGISTERS_BASE + 0x09A0) 231#define WL12XX_SPARE_A4 (REGISTERS_BASE + 0x09A0)
245#define SPARE_A5 (REGISTERS_BASE + 0x09A4) 232#define WL12XX_SPARE_A5 (REGISTERS_BASE + 0x09A4)
246#define SPARE_A6 (REGISTERS_BASE + 0x09A8) 233#define WL12XX_SPARE_A6 (REGISTERS_BASE + 0x09A8)
247#define SPARE_A7 (REGISTERS_BASE + 0x09AC) 234#define WL12XX_SPARE_A7 (REGISTERS_BASE + 0x09AC)
248#define SPARE_A8 (REGISTERS_BASE + 0x09B0) 235#define WL12XX_SPARE_A8 (REGISTERS_BASE + 0x09B0)
249#define SPARE_B1 (REGISTERS_BASE + 0x5420) 236#define WL12XX_SPARE_B1 (REGISTERS_BASE + 0x5420)
250#define SPARE_B2 (REGISTERS_BASE + 0x5424) 237#define WL12XX_SPARE_B2 (REGISTERS_BASE + 0x5424)
251#define SPARE_B3 (REGISTERS_BASE + 0x5428) 238#define WL12XX_SPARE_B3 (REGISTERS_BASE + 0x5428)
252#define SPARE_B4 (REGISTERS_BASE + 0x542C) 239#define WL12XX_SPARE_B4 (REGISTERS_BASE + 0x542C)
253#define SPARE_B5 (REGISTERS_BASE + 0x5430) 240#define WL12XX_SPARE_B5 (REGISTERS_BASE + 0x5430)
254#define SPARE_B6 (REGISTERS_BASE + 0x5434) 241#define WL12XX_SPARE_B6 (REGISTERS_BASE + 0x5434)
255#define SPARE_B7 (REGISTERS_BASE + 0x5438) 242#define WL12XX_SPARE_B7 (REGISTERS_BASE + 0x5438)
256#define SPARE_B8 (REGISTERS_BASE + 0x543C) 243#define WL12XX_SPARE_B8 (REGISTERS_BASE + 0x543C)
257 244
258#define PLL_PARAMETERS (REGISTERS_BASE + 0x6040) 245#define WL12XX_PLL_PARAMETERS (REGISTERS_BASE + 0x6040)
259#define WU_COUNTER_PAUSE (REGISTERS_BASE + 0x6008) 246#define WL12XX_WU_COUNTER_PAUSE (REGISTERS_BASE + 0x6008)
260#define WELP_ARM_COMMAND (REGISTERS_BASE + 0x6100) 247#define WL12XX_WELP_ARM_COMMAND (REGISTERS_BASE + 0x6100)
261#define DRPW_SCRATCH_START (DRPW_BASE + 0x002C) 248#define WL12XX_DRPW_SCRATCH_START (DRPW_BASE + 0x002C)
262 249
263 250#define WL12XX_CMD_MBOX_ADDRESS 0x407B4
264#define ACX_SLV_SOFT_RESET_BIT BIT(1) 251
265#define ACX_REG_EEPROM_START_BIT BIT(1) 252#define ACX_REG_EEPROM_START_BIT BIT(1)
266 253
267/* Command/Information Mailbox Pointers */ 254/* Command/Information Mailbox Pointers */
@@ -279,7 +266,7 @@
279 the host receives the Init Complete interrupt from 266 the host receives the Init Complete interrupt from
280 the Wlan hardware. 267 the Wlan hardware.
281 ===============================================*/ 268 ===============================================*/
282#define REG_COMMAND_MAILBOX_PTR (SCR_PAD0) 269#define WL12XX_REG_COMMAND_MAILBOX_PTR (WL12XX_SCR_PAD0)
283 270
284/*=============================================== 271/*===============================================
285 Information Mailbox Pointer - 32bit RW 272 Information Mailbox Pointer - 32bit RW
@@ -294,7 +281,7 @@
294 until after the host receives the Init Complete interrupt from 281 until after the host receives the Init Complete interrupt from
295 the Wlan hardware. 282 the Wlan hardware.
296 ===============================================*/ 283 ===============================================*/
297#define REG_EVENT_MAILBOX_PTR (SCR_PAD1) 284#define WL12XX_REG_EVENT_MAILBOX_PTR (WL12XX_SCR_PAD1)
298 285
299/*=============================================== 286/*===============================================
300 EEPROM Read/Write Request 32bit RW 287 EEPROM Read/Write Request 32bit RW
@@ -365,26 +352,6 @@
365#define ACX_CONT_WIND_MIN_MASK 0x0000007f 352#define ACX_CONT_WIND_MIN_MASK 0x0000007f
366#define ACX_CONT_WIND_MAX 0x03ff0000 353#define ACX_CONT_WIND_MAX 0x03ff0000
367 354
368/*===============================================
369 HI_CFG Interface Configuration Register Values
370 ------------------------------------------
371 ===============================================*/
372#define HI_CFG_UART_ENABLE 0x00000004
373#define HI_CFG_RST232_ENABLE 0x00000008
374#define HI_CFG_CLOCK_REQ_SELECT 0x00000010
375#define HI_CFG_HOST_INT_ENABLE 0x00000020
376#define HI_CFG_VLYNQ_OUTPUT_ENABLE 0x00000040
377#define HI_CFG_HOST_INT_ACTIVE_LOW 0x00000080
378#define HI_CFG_UART_TX_OUT_GPIO_15 0x00000100
379#define HI_CFG_UART_TX_OUT_GPIO_14 0x00000200
380#define HI_CFG_UART_TX_OUT_GPIO_7 0x00000400
381
382#define HI_CFG_DEF_VAL \
383 (HI_CFG_UART_ENABLE | \
384 HI_CFG_RST232_ENABLE | \
385 HI_CFG_CLOCK_REQ_SELECT | \
386 HI_CFG_HOST_INT_ENABLE)
387
388#define REF_FREQ_19_2 0 355#define REF_FREQ_19_2 0
389#define REF_FREQ_26_0 1 356#define REF_FREQ_26_0 1
390#define REF_FREQ_38_4 2 357#define REF_FREQ_38_4 2
@@ -400,38 +367,19 @@
400#define LUT_PARAM_BB_PLL_LOOP_FILTER 5 367#define LUT_PARAM_BB_PLL_LOOP_FILTER 5
401#define LUT_PARAM_NUM 6 368#define LUT_PARAM_NUM 6
402 369
403#define ACX_EEPROMLESS_IND_REG (SCR_PAD4) 370#define WL12XX_EEPROMLESS_IND (WL12XX_SCR_PAD4)
404#define USE_EEPROM 0 371#define USE_EEPROM 0
405#define SOFT_RESET_MAX_TIME 1000000
406#define SOFT_RESET_STALL_TIME 1000
407#define NVS_DATA_BUNDARY_ALIGNMENT 4 372#define NVS_DATA_BUNDARY_ALIGNMENT 4
408 373
409
410/* Firmware image load chunk size */
411#define CHUNK_SIZE 16384
412
413/* Firmware image header size */ 374/* Firmware image header size */
414#define FW_HDR_SIZE 8 375#define FW_HDR_SIZE 8
415 376
416#define ECPU_CONTROL_HALT 0x00000101
417
418
419/****************************************************************************** 377/******************************************************************************
420 378
421 CHANNELS, BAND & REG DOMAINS definitions 379 CHANNELS, BAND & REG DOMAINS definitions
422 380
423******************************************************************************/ 381******************************************************************************/
424 382
425
426enum {
427 RADIO_BAND_2_4GHZ = 0, /* 2.4 Ghz band */
428 RADIO_BAND_5GHZ = 1, /* 5 Ghz band */
429 RADIO_BAND_JAPAN_4_9_GHZ = 2,
430 DEFAULT_BAND = RADIO_BAND_2_4GHZ,
431 INVALID_BAND = 0xFE,
432 MAX_RADIO_BANDS = 0xFF
433};
434
435#define SHORT_PREAMBLE_BIT BIT(0) /* CCK or Barker depending on the rate */ 383#define SHORT_PREAMBLE_BIT BIT(0) /* CCK or Barker depending on the rate */
436#define OFDM_RATE_BIT BIT(6) 384#define OFDM_RATE_BIT BIT(6)
437#define PBCC_RATE_BIT BIT(7) 385#define PBCC_RATE_BIT BIT(7)
@@ -465,14 +413,82 @@ b12-b0 - Supported Rate indicator bits as defined below.
465 413
466******************************************************************************/ 414******************************************************************************/
467 415
416#define OCP_CMD_LOOP 32
417#define OCP_CMD_WRITE 0x1
418#define OCP_CMD_READ 0x2
419#define OCP_READY_MASK BIT(18)
420#define OCP_STATUS_MASK (BIT(16) | BIT(17))
421#define OCP_STATUS_NO_RESP 0x00000
422#define OCP_STATUS_OK 0x10000
423#define OCP_STATUS_REQ_FAILED 0x20000
424#define OCP_STATUS_RESP_ERROR 0x30000
425
426#define OCP_REG_POLARITY 0x0064
427#define OCP_REG_CLK_TYPE 0x0448
428#define OCP_REG_CLK_POLARITY 0x0cb2
429#define OCP_REG_CLK_PULL 0x0cb4
430
431#define POLARITY_LOW BIT(1)
432#define NO_PULL (BIT(14) | BIT(15))
433
434#define FREF_CLK_TYPE_BITS 0xfffffe7f
435#define CLK_REQ_PRCM 0x100
436#define FREF_CLK_POLARITY_BITS 0xfffff8ff
437#define CLK_REQ_OUTN_SEL 0x700
438
439#define WU_COUNTER_PAUSE_VAL 0x3FF
440
441/* PLL configuration algorithm for wl128x */
442#define SYS_CLK_CFG_REG 0x2200
443/* Bit[0] - 0-TCXO, 1-FREF */
444#define MCS_PLL_CLK_SEL_FREF BIT(0)
445/* Bit[3:2] - 01-TCXO, 10-FREF */
446#define WL_CLK_REQ_TYPE_FREF BIT(3)
447#define WL_CLK_REQ_TYPE_PG2 (BIT(3) | BIT(2))
448/* Bit[4] - 0-TCXO, 1-FREF */
449#define PRCM_CM_EN_MUX_WLAN_FREF BIT(4)
450
451#define TCXO_ILOAD_INT_REG 0x2264
452#define TCXO_CLK_DETECT_REG 0x2266
453
454#define TCXO_DET_FAILED BIT(4)
455
456#define FREF_ILOAD_INT_REG 0x2084
457#define FREF_CLK_DETECT_REG 0x2086
458#define FREF_CLK_DETECT_FAIL BIT(4)
459
460/* Use this reg for masking during driver access */
461#define WL_SPARE_REG 0x2320
462#define WL_SPARE_VAL BIT(2)
463/* Bit[6:5:3] - mask wl write SYS_CLK_CFG[8:5:2:4] */
464#define WL_SPARE_MASK_8526 (BIT(6) | BIT(5) | BIT(3))
465
466#define PLL_LOCK_COUNTERS_REG 0xD8C
467#define PLL_LOCK_COUNTERS_COEX 0x0F
468#define PLL_LOCK_COUNTERS_MCS 0xF0
469#define MCS_PLL_OVERRIDE_REG 0xD90
470#define MCS_PLL_CONFIG_REG 0xD92
471#define MCS_SEL_IN_FREQ_MASK 0x0070
472#define MCS_SEL_IN_FREQ_SHIFT 4
473#define MCS_PLL_CONFIG_REG_VAL 0x73
474#define MCS_PLL_ENABLE_HP (BIT(0) | BIT(1))
475
476#define MCS_PLL_M_REG 0xD94
477#define MCS_PLL_N_REG 0xD96
478#define MCS_PLL_M_REG_VAL 0xC8
479#define MCS_PLL_N_REG_VAL 0x07
480
481#define SDIO_IO_DS 0xd14
482
483/* SDIO/wSPI DS configuration values */
484enum {
485 HCI_IO_DS_8MA = 0,
486 HCI_IO_DS_4MA = 1, /* default */
487 HCI_IO_DS_6MA = 2,
488 HCI_IO_DS_2MA = 3,
489};
468 490
469/************************************************************************* 491/* end PLL configuration algorithm for wl128x */
470
471 Interrupt Trigger Register (Host -> WiLink)
472
473**************************************************************************/
474
475/* Hardware to Embedded CPU Interrupts - first 32-bit register set */
476 492
477/* 493/*
478 * Host Command Interrupt. Setting this bit masks 494 * Host Command Interrupt. Setting this bit masks
@@ -480,7 +496,7 @@ b12-b0 - Supported Rate indicator bits as defined below.
480 * the FW that it has sent a command 496 * the FW that it has sent a command
481 * to the Wlan hardware Command Mailbox. 497 * to the Wlan hardware Command Mailbox.
482 */ 498 */
483#define INTR_TRIG_CMD BIT(0) 499#define WL12XX_INTR_TRIG_CMD BIT(0)
484 500
485/* 501/*
486 * Host Event Acknowlegde Interrupt. The host 502 * Host Event Acknowlegde Interrupt. The host
@@ -488,42 +504,27 @@ b12-b0 - Supported Rate indicator bits as defined below.
488 * the unsolicited information from the event 504 * the unsolicited information from the event
489 * mailbox. 505 * mailbox.
490 */ 506 */
491#define INTR_TRIG_EVENT_ACK BIT(1) 507#define WL12XX_INTR_TRIG_EVENT_ACK BIT(1)
492
493/*
494 * The host sets this bit to inform the Wlan
495 * FW that a TX packet is in the XFER
496 * Buffer #0.
497 */
498#define INTR_TRIG_TX_PROC0 BIT(2)
499
500/*
501 * The host sets this bit to inform the FW
502 * that it read a packet from RX XFER
503 * Buffer #0.
504 */
505#define INTR_TRIG_RX_PROC0 BIT(3)
506
507#define INTR_TRIG_DEBUG_ACK BIT(4)
508 508
509#define INTR_TRIG_STATE_CHANGED BIT(5) 509/*===============================================
510 510 HI_CFG Interface Configuration Register Values
511 511 ------------------------------------------
512/* Hardware to Embedded CPU Interrupts - second 32-bit register set */ 512 ===============================================*/
513 513#define HI_CFG_UART_ENABLE 0x00000004
514/* 514#define HI_CFG_RST232_ENABLE 0x00000008
515 * The host sets this bit to inform the FW 515#define HI_CFG_CLOCK_REQ_SELECT 0x00000010
516 * that it read a packet from RX XFER 516#define HI_CFG_HOST_INT_ENABLE 0x00000020
517 * Buffer #1. 517#define HI_CFG_VLYNQ_OUTPUT_ENABLE 0x00000040
518 */ 518#define HI_CFG_HOST_INT_ACTIVE_LOW 0x00000080
519#define INTR_TRIG_RX_PROC1 BIT(17) 519#define HI_CFG_UART_TX_OUT_GPIO_15 0x00000100
520#define HI_CFG_UART_TX_OUT_GPIO_14 0x00000200
521#define HI_CFG_UART_TX_OUT_GPIO_7 0x00000400
520 522
521/* 523#define HI_CFG_DEF_VAL \
522 * The host sets this bit to inform the Wlan 524 (HI_CFG_UART_ENABLE | \
523 * hardware that a TX packet is in the XFER 525 HI_CFG_RST232_ENABLE | \
524 * Buffer #1. 526 HI_CFG_CLOCK_REQ_SELECT | \
525 */ 527 HI_CFG_HOST_INT_ENABLE)
526#define INTR_TRIG_TX_PROC1 BIT(18)
527 528
528#define WL127X_REG_FUSE_DATA_2_1 0x050a 529#define WL127X_REG_FUSE_DATA_2_1 0x050a
529#define WL128X_REG_FUSE_DATA_2_1 0x2152 530#define WL128X_REG_FUSE_DATA_2_1 0x2152
diff --git a/drivers/net/wireless/ti/wl12xx/wl12xx.h b/drivers/net/wireless/ti/wl12xx/wl12xx.h
new file mode 100644
index 000000000000..74cd332e23ef
--- /dev/null
+++ b/drivers/net/wireless/ti/wl12xx/wl12xx.h
@@ -0,0 +1,31 @@
1/*
2 * This file is part of wl12xx
3 *
4 * Copyright (C) 2011 Texas Instruments Inc.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18 * 02110-1301 USA
19 *
20 */
21
22#ifndef __WL12XX_PRIV_H__
23#define __WL12XX_PRIV_H__
24
25#include "conf.h"
26
27struct wl12xx_priv {
28 struct wl12xx_priv_conf conf;
29};
30
31#endif /* __WL12XX_PRIV_H__ */
diff --git a/drivers/net/wireless/ti/wlcore/Kconfig b/drivers/net/wireless/ti/wlcore/Kconfig
new file mode 100644
index 000000000000..9d04c38938bc
--- /dev/null
+++ b/drivers/net/wireless/ti/wlcore/Kconfig
@@ -0,0 +1,41 @@
1config WLCORE
2 tristate "TI wlcore support"
3 depends on WL_TI && GENERIC_HARDIRQS
4 depends on INET
5 select FW_LOADER
6 ---help---
7 This module contains the main code for TI WLAN chips. It abstracts
8 hardware-specific differences among different chipset families.
9 Each chipset family needs to implement its own lower-level module
10 that will depend on this module for the common code.
11
12 If you choose to build a module, it will be called wlcore. Say N if
13 unsure.
14
15config WLCORE_SPI
16 tristate "TI wlcore SPI support"
17 depends on WLCORE && SPI_MASTER
18 select CRC7
19 ---help---
20 This module adds support for the SPI interface of adapters using
21 TI WLAN chipsets. Select this if your platform is using
22 the SPI bus.
23
24 If you choose to build a module, it'll be called wlcore_spi.
25 Say N if unsure.
26
27config WLCORE_SDIO
28 tristate "TI wlcore SDIO support"
29 depends on WLCORE && MMC
30 ---help---
31 This module adds support for the SDIO interface of adapters using
32 TI WLAN chipsets. Select this if your platform is using
33 the SDIO bus.
34
35 If you choose to build a module, it'll be called wlcore_sdio.
36 Say N if unsure.
37
38config WL12XX_PLATFORM_DATA
39 bool
40 depends on WLCORE_SDIO != n || WL1251_SDIO != n
41 default y
diff --git a/drivers/net/wireless/ti/wlcore/Makefile b/drivers/net/wireless/ti/wlcore/Makefile
new file mode 100644
index 000000000000..d9fba9e32130
--- /dev/null
+++ b/drivers/net/wireless/ti/wlcore/Makefile
@@ -0,0 +1,15 @@
1wlcore-objs = main.o cmd.o io.o event.o tx.o rx.o ps.o acx.o \
2 boot.o init.o debugfs.o scan.o
3
4wlcore_spi-objs = spi.o
5wlcore_sdio-objs = sdio.o
6
7wlcore-$(CONFIG_NL80211_TESTMODE) += testmode.o
8obj-$(CONFIG_WLCORE) += wlcore.o
9obj-$(CONFIG_WLCORE_SPI) += wlcore_spi.o
10obj-$(CONFIG_WLCORE_SDIO) += wlcore_sdio.o
11
12# small builtin driver bit
13obj-$(CONFIG_WL12XX_PLATFORM_DATA) += wl12xx_platform_data.o
14
15ccflags-y += -D__CHECK_ENDIAN__
diff --git a/drivers/net/wireless/wl12xx/acx.c b/drivers/net/wireless/ti/wlcore/acx.c
index bc96db0683a5..5912541a925e 100644
--- a/drivers/net/wireless/wl12xx/acx.c
+++ b/drivers/net/wireless/ti/wlcore/acx.c
@@ -28,11 +28,11 @@
28#include <linux/spi/spi.h> 28#include <linux/spi/spi.h>
29#include <linux/slab.h> 29#include <linux/slab.h>
30 30
31#include "wl12xx.h" 31#include "wlcore.h"
32#include "debug.h" 32#include "debug.h"
33#include "wl12xx_80211.h" 33#include "wl12xx_80211.h"
34#include "reg.h"
35#include "ps.h" 34#include "ps.h"
35#include "hw_ops.h"
36 36
37int wl1271_acx_wake_up_conditions(struct wl1271 *wl, struct wl12xx_vif *wlvif, 37int wl1271_acx_wake_up_conditions(struct wl1271 *wl, struct wl12xx_vif *wlvif,
38 u8 wake_up_event, u8 listen_interval) 38 u8 wake_up_event, u8 listen_interval)
@@ -757,7 +757,10 @@ int wl1271_acx_sta_rate_policies(struct wl1271 *wl, struct wl12xx_vif *wlvif)
757 757
758 /* configure one AP supported rate class */ 758 /* configure one AP supported rate class */
759 acx->rate_policy_idx = cpu_to_le32(wlvif->sta.ap_rate_idx); 759 acx->rate_policy_idx = cpu_to_le32(wlvif->sta.ap_rate_idx);
760 acx->rate_policy.enabled_rates = cpu_to_le32(wlvif->rate_set); 760
761 /* the AP policy is HW specific */
762 acx->rate_policy.enabled_rates =
763 cpu_to_le32(wlcore_hw_sta_get_ap_rate_mask(wl, wlvif));
761 acx->rate_policy.short_retry_limit = c->short_retry_limit; 764 acx->rate_policy.short_retry_limit = c->short_retry_limit;
762 acx->rate_policy.long_retry_limit = c->long_retry_limit; 765 acx->rate_policy.long_retry_limit = c->long_retry_limit;
763 acx->rate_policy.aflags = c->aflags; 766 acx->rate_policy.aflags = c->aflags;
@@ -969,17 +972,14 @@ int wl12xx_acx_mem_cfg(struct wl1271 *wl)
969 goto out; 972 goto out;
970 } 973 }
971 974
972 if (wl->chip.id == CHIP_ID_1283_PG20) 975 mem = &wl->conf.mem;
973 mem = &wl->conf.mem_wl128x;
974 else
975 mem = &wl->conf.mem_wl127x;
976 976
977 /* memory config */ 977 /* memory config */
978 mem_conf->num_stations = mem->num_stations; 978 mem_conf->num_stations = mem->num_stations;
979 mem_conf->rx_mem_block_num = mem->rx_block_num; 979 mem_conf->rx_mem_block_num = mem->rx_block_num;
980 mem_conf->tx_min_mem_block_num = mem->tx_min_block_num; 980 mem_conf->tx_min_mem_block_num = mem->tx_min_block_num;
981 mem_conf->num_ssid_profiles = mem->ssid_profiles; 981 mem_conf->num_ssid_profiles = mem->ssid_profiles;
982 mem_conf->total_tx_descriptors = cpu_to_le32(ACX_TX_DESCRIPTORS); 982 mem_conf->total_tx_descriptors = cpu_to_le32(wl->num_tx_desc);
983 mem_conf->dyn_mem_enable = mem->dynamic_memory; 983 mem_conf->dyn_mem_enable = mem->dynamic_memory;
984 mem_conf->tx_free_req = mem->min_req_tx_blocks; 984 mem_conf->tx_free_req = mem->min_req_tx_blocks;
985 mem_conf->rx_free_req = mem->min_req_rx_blocks; 985 mem_conf->rx_free_req = mem->min_req_rx_blocks;
@@ -998,32 +998,6 @@ out:
998 return ret; 998 return ret;
999} 999}
1000 1000
1001int wl1271_acx_host_if_cfg_bitmap(struct wl1271 *wl, u32 host_cfg_bitmap)
1002{
1003 struct wl1271_acx_host_config_bitmap *bitmap_conf;
1004 int ret;
1005
1006 bitmap_conf = kzalloc(sizeof(*bitmap_conf), GFP_KERNEL);
1007 if (!bitmap_conf) {
1008 ret = -ENOMEM;
1009 goto out;
1010 }
1011
1012 bitmap_conf->host_cfg_bitmap = cpu_to_le32(host_cfg_bitmap);
1013
1014 ret = wl1271_cmd_configure(wl, ACX_HOST_IF_CFG_BITMAP,
1015 bitmap_conf, sizeof(*bitmap_conf));
1016 if (ret < 0) {
1017 wl1271_warning("wl1271 bitmap config opt failed: %d", ret);
1018 goto out;
1019 }
1020
1021out:
1022 kfree(bitmap_conf);
1023
1024 return ret;
1025}
1026
1027int wl1271_acx_init_mem_config(struct wl1271 *wl) 1001int wl1271_acx_init_mem_config(struct wl1271 *wl)
1028{ 1002{
1029 int ret; 1003 int ret;
diff --git a/drivers/net/wireless/wl12xx/acx.h b/drivers/net/wireless/ti/wlcore/acx.h
index a28fc044034c..b2f88831b7a9 100644
--- a/drivers/net/wireless/wl12xx/acx.h
+++ b/drivers/net/wireless/ti/wlcore/acx.h
@@ -25,7 +25,7 @@
25#ifndef __ACX_H__ 25#ifndef __ACX_H__
26#define __ACX_H__ 26#define __ACX_H__
27 27
28#include "wl12xx.h" 28#include "wlcore.h"
29#include "cmd.h" 29#include "cmd.h"
30 30
31/************************************************************************* 31/*************************************************************************
@@ -824,16 +824,11 @@ struct wl1271_acx_keep_alive_config {
824 __le32 period; 824 __le32 period;
825} __packed; 825} __packed;
826 826
827/* TODO: maybe this needs to be moved somewhere else? */
827#define HOST_IF_CFG_RX_FIFO_ENABLE BIT(0) 828#define HOST_IF_CFG_RX_FIFO_ENABLE BIT(0)
828#define HOST_IF_CFG_TX_EXTRA_BLKS_SWAP BIT(1) 829#define HOST_IF_CFG_TX_EXTRA_BLKS_SWAP BIT(1)
829#define HOST_IF_CFG_TX_PAD_TO_SDIO_BLK BIT(3) 830#define HOST_IF_CFG_TX_PAD_TO_SDIO_BLK BIT(3)
830 831
831struct wl1271_acx_host_config_bitmap {
832 struct acx_header header;
833
834 __le32 host_cfg_bitmap;
835} __packed;
836
837enum { 832enum {
838 WL1271_ACX_TRIG_TYPE_LEVEL = 0, 833 WL1271_ACX_TRIG_TYPE_LEVEL = 0,
839 WL1271_ACX_TRIG_TYPE_EDGE, 834 WL1271_ACX_TRIG_TYPE_EDGE,
@@ -1274,7 +1269,6 @@ int wl1271_acx_frag_threshold(struct wl1271 *wl, u32 frag_threshold);
1274int wl1271_acx_tx_config_options(struct wl1271 *wl); 1269int wl1271_acx_tx_config_options(struct wl1271 *wl);
1275int wl12xx_acx_mem_cfg(struct wl1271 *wl); 1270int wl12xx_acx_mem_cfg(struct wl1271 *wl);
1276int wl1271_acx_init_mem_config(struct wl1271 *wl); 1271int wl1271_acx_init_mem_config(struct wl1271 *wl);
1277int wl1271_acx_host_if_cfg_bitmap(struct wl1271 *wl, u32 host_cfg_bitmap);
1278int wl1271_acx_init_rx_interrupt(struct wl1271 *wl); 1272int wl1271_acx_init_rx_interrupt(struct wl1271 *wl);
1279int wl1271_acx_smart_reflex(struct wl1271 *wl); 1273int wl1271_acx_smart_reflex(struct wl1271 *wl);
1280int wl1271_acx_bet_enable(struct wl1271 *wl, struct wl12xx_vif *wlvif, 1274int wl1271_acx_bet_enable(struct wl1271 *wl, struct wl12xx_vif *wlvif,
diff --git a/drivers/net/wireless/ti/wlcore/boot.c b/drivers/net/wireless/ti/wlcore/boot.c
new file mode 100644
index 000000000000..3a2207db5405
--- /dev/null
+++ b/drivers/net/wireless/ti/wlcore/boot.c
@@ -0,0 +1,443 @@
1/*
2 * This file is part of wl1271
3 *
4 * Copyright (C) 2008-2010 Nokia Corporation
5 *
6 * Contact: Luciano Coelho <luciano.coelho@nokia.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 */
23
24#include <linux/slab.h>
25#include <linux/wl12xx.h>
26#include <linux/export.h>
27
28#include "debug.h"
29#include "acx.h"
30#include "boot.h"
31#include "io.h"
32#include "event.h"
33#include "rx.h"
34#include "hw_ops.h"
35
36static void wl1271_boot_set_ecpu_ctrl(struct wl1271 *wl, u32 flag)
37{
38 u32 cpu_ctrl;
39
40 /* 10.5.0 run the firmware (I) */
41 cpu_ctrl = wlcore_read_reg(wl, REG_ECPU_CONTROL);
42
43 /* 10.5.1 run the firmware (II) */
44 cpu_ctrl |= flag;
45 wlcore_write_reg(wl, REG_ECPU_CONTROL, cpu_ctrl);
46}
47
48static int wlcore_parse_fw_ver(struct wl1271 *wl)
49{
50 int ret;
51
52 ret = sscanf(wl->chip.fw_ver_str + 4, "%u.%u.%u.%u.%u",
53 &wl->chip.fw_ver[0], &wl->chip.fw_ver[1],
54 &wl->chip.fw_ver[2], &wl->chip.fw_ver[3],
55 &wl->chip.fw_ver[4]);
56
57 if (ret != 5) {
58 wl1271_warning("fw version incorrect value");
59 memset(wl->chip.fw_ver, 0, sizeof(wl->chip.fw_ver));
60 return -EINVAL;
61 }
62
63 ret = wlcore_identify_fw(wl);
64 if (ret < 0)
65 return ret;
66
67 return 0;
68}
69
70static int wlcore_boot_fw_version(struct wl1271 *wl)
71{
72 struct wl1271_static_data *static_data;
73 int ret;
74
75 static_data = kmalloc(sizeof(*static_data), GFP_DMA);
76 if (!static_data) {
77 wl1271_error("Couldn't allocate memory for static data!");
78 return -ENOMEM;
79 }
80
81 wl1271_read(wl, wl->cmd_box_addr, static_data, sizeof(*static_data),
82 false);
83
84 strncpy(wl->chip.fw_ver_str, static_data->fw_version,
85 sizeof(wl->chip.fw_ver_str));
86
87 kfree(static_data);
88
89 /* make sure the string is NULL-terminated */
90 wl->chip.fw_ver_str[sizeof(wl->chip.fw_ver_str) - 1] = '\0';
91
92 ret = wlcore_parse_fw_ver(wl);
93 if (ret < 0)
94 return ret;
95
96 return 0;
97}
98
99static int wl1271_boot_upload_firmware_chunk(struct wl1271 *wl, void *buf,
100 size_t fw_data_len, u32 dest)
101{
102 struct wlcore_partition_set partition;
103 int addr, chunk_num, partition_limit;
104 u8 *p, *chunk;
105
106 /* whal_FwCtrl_LoadFwImageSm() */
107
108 wl1271_debug(DEBUG_BOOT, "starting firmware upload");
109
110 wl1271_debug(DEBUG_BOOT, "fw_data_len %zd chunk_size %d",
111 fw_data_len, CHUNK_SIZE);
112
113 if ((fw_data_len % 4) != 0) {
114 wl1271_error("firmware length not multiple of four");
115 return -EIO;
116 }
117
118 chunk = kmalloc(CHUNK_SIZE, GFP_KERNEL);
119 if (!chunk) {
120 wl1271_error("allocation for firmware upload chunk failed");
121 return -ENOMEM;
122 }
123
124 memcpy(&partition, &wl->ptable[PART_DOWN], sizeof(partition));
125 partition.mem.start = dest;
126 wlcore_set_partition(wl, &partition);
127
128 /* 10.1 set partition limit and chunk num */
129 chunk_num = 0;
130 partition_limit = wl->ptable[PART_DOWN].mem.size;
131
132 while (chunk_num < fw_data_len / CHUNK_SIZE) {
133 /* 10.2 update partition, if needed */
134 addr = dest + (chunk_num + 2) * CHUNK_SIZE;
135 if (addr > partition_limit) {
136 addr = dest + chunk_num * CHUNK_SIZE;
137 partition_limit = chunk_num * CHUNK_SIZE +
138 wl->ptable[PART_DOWN].mem.size;
139 partition.mem.start = addr;
140 wlcore_set_partition(wl, &partition);
141 }
142
143 /* 10.3 upload the chunk */
144 addr = dest + chunk_num * CHUNK_SIZE;
145 p = buf + chunk_num * CHUNK_SIZE;
146 memcpy(chunk, p, CHUNK_SIZE);
147 wl1271_debug(DEBUG_BOOT, "uploading fw chunk 0x%p to 0x%x",
148 p, addr);
149 wl1271_write(wl, addr, chunk, CHUNK_SIZE, false);
150
151 chunk_num++;
152 }
153
154 /* 10.4 upload the last chunk */
155 addr = dest + chunk_num * CHUNK_SIZE;
156 p = buf + chunk_num * CHUNK_SIZE;
157 memcpy(chunk, p, fw_data_len % CHUNK_SIZE);
158 wl1271_debug(DEBUG_BOOT, "uploading fw last chunk (%zd B) 0x%p to 0x%x",
159 fw_data_len % CHUNK_SIZE, p, addr);
160 wl1271_write(wl, addr, chunk, fw_data_len % CHUNK_SIZE, false);
161
162 kfree(chunk);
163 return 0;
164}
165
166int wlcore_boot_upload_firmware(struct wl1271 *wl)
167{
168 u32 chunks, addr, len;
169 int ret = 0;
170 u8 *fw;
171
172 fw = wl->fw;
173 chunks = be32_to_cpup((__be32 *) fw);
174 fw += sizeof(u32);
175
176 wl1271_debug(DEBUG_BOOT, "firmware chunks to be uploaded: %u", chunks);
177
178 while (chunks--) {
179 addr = be32_to_cpup((__be32 *) fw);
180 fw += sizeof(u32);
181 len = be32_to_cpup((__be32 *) fw);
182 fw += sizeof(u32);
183
184 if (len > 300000) {
185 wl1271_info("firmware chunk too long: %u", len);
186 return -EINVAL;
187 }
188 wl1271_debug(DEBUG_BOOT, "chunk %d addr 0x%x len %u",
189 chunks, addr, len);
190 ret = wl1271_boot_upload_firmware_chunk(wl, fw, len, addr);
191 if (ret != 0)
192 break;
193 fw += len;
194 }
195
196 return ret;
197}
198EXPORT_SYMBOL_GPL(wlcore_boot_upload_firmware);
199
200int wlcore_boot_upload_nvs(struct wl1271 *wl)
201{
202 size_t nvs_len, burst_len;
203 int i;
204 u32 dest_addr, val;
205 u8 *nvs_ptr, *nvs_aligned;
206
207 if (wl->nvs == NULL)
208 return -ENODEV;
209
210 if (wl->quirks & WLCORE_QUIRK_LEGACY_NVS) {
211 struct wl1271_nvs_file *nvs =
212 (struct wl1271_nvs_file *)wl->nvs;
213 /*
214 * FIXME: the LEGACY NVS image support (NVS's missing the 5GHz
215 * band configurations) can be removed when those NVS files stop
216 * floating around.
217 */
218 if (wl->nvs_len == sizeof(struct wl1271_nvs_file) ||
219 wl->nvs_len == WL1271_INI_LEGACY_NVS_FILE_SIZE) {
220 if (nvs->general_params.dual_mode_select)
221 wl->enable_11a = true;
222 }
223
224 if (wl->nvs_len != sizeof(struct wl1271_nvs_file) &&
225 (wl->nvs_len != WL1271_INI_LEGACY_NVS_FILE_SIZE ||
226 wl->enable_11a)) {
227 wl1271_error("nvs size is not as expected: %zu != %zu",
228 wl->nvs_len, sizeof(struct wl1271_nvs_file));
229 kfree(wl->nvs);
230 wl->nvs = NULL;
231 wl->nvs_len = 0;
232 return -EILSEQ;
233 }
234
235 /* only the first part of the NVS needs to be uploaded */
236 nvs_len = sizeof(nvs->nvs);
237 nvs_ptr = (u8 *) nvs->nvs;
238 } else {
239 struct wl128x_nvs_file *nvs = (struct wl128x_nvs_file *)wl->nvs;
240
241 if (wl->nvs_len == sizeof(struct wl128x_nvs_file)) {
242 if (nvs->general_params.dual_mode_select)
243 wl->enable_11a = true;
244 } else {
245 wl1271_error("nvs size is not as expected: %zu != %zu",
246 wl->nvs_len,
247 sizeof(struct wl128x_nvs_file));
248 kfree(wl->nvs);
249 wl->nvs = NULL;
250 wl->nvs_len = 0;
251 return -EILSEQ;
252 }
253
254 /* only the first part of the NVS needs to be uploaded */
255 nvs_len = sizeof(nvs->nvs);
256 nvs_ptr = (u8 *)nvs->nvs;
257 }
258
259 /* update current MAC address to NVS */
260 nvs_ptr[11] = wl->addresses[0].addr[0];
261 nvs_ptr[10] = wl->addresses[0].addr[1];
262 nvs_ptr[6] = wl->addresses[0].addr[2];
263 nvs_ptr[5] = wl->addresses[0].addr[3];
264 nvs_ptr[4] = wl->addresses[0].addr[4];
265 nvs_ptr[3] = wl->addresses[0].addr[5];
266
267 /*
268 * Layout before the actual NVS tables:
269 * 1 byte : burst length.
270 * 2 bytes: destination address.
271 * n bytes: data to burst copy.
272 *
273 * This is ended by a 0 length, then the NVS tables.
274 */
275
276 /* FIXME: Do we need to check here whether the LSB is 1? */
277 while (nvs_ptr[0]) {
278 burst_len = nvs_ptr[0];
279 dest_addr = (nvs_ptr[1] & 0xfe) | ((u32)(nvs_ptr[2] << 8));
280
281 /*
282 * Due to our new wl1271_translate_reg_addr function,
283 * we need to add the register partition start address
284 * to the destination
285 */
286 dest_addr += wl->curr_part.reg.start;
287
288 /* We move our pointer to the data */
289 nvs_ptr += 3;
290
291 for (i = 0; i < burst_len; i++) {
292 if (nvs_ptr + 3 >= (u8 *) wl->nvs + nvs_len)
293 goto out_badnvs;
294
295 val = (nvs_ptr[0] | (nvs_ptr[1] << 8)
296 | (nvs_ptr[2] << 16) | (nvs_ptr[3] << 24));
297
298 wl1271_debug(DEBUG_BOOT,
299 "nvs burst write 0x%x: 0x%x",
300 dest_addr, val);
301 wl1271_write32(wl, dest_addr, val);
302
303 nvs_ptr += 4;
304 dest_addr += 4;
305 }
306
307 if (nvs_ptr >= (u8 *) wl->nvs + nvs_len)
308 goto out_badnvs;
309 }
310
311 /*
312 * We've reached the first zero length, the first NVS table
313 * is located at an aligned offset which is at least 7 bytes further.
314 * NOTE: The wl->nvs->nvs element must be first, in order to
315 * simplify the casting, we assume it is at the beginning of
316 * the wl->nvs structure.
317 */
318 nvs_ptr = (u8 *)wl->nvs +
319 ALIGN(nvs_ptr - (u8 *)wl->nvs + 7, 4);
320
321 if (nvs_ptr >= (u8 *) wl->nvs + nvs_len)
322 goto out_badnvs;
323
324 nvs_len -= nvs_ptr - (u8 *)wl->nvs;
325
326 /* Now we must set the partition correctly */
327 wlcore_set_partition(wl, &wl->ptable[PART_WORK]);
328
329 /* Copy the NVS tables to a new block to ensure alignment */
330 nvs_aligned = kmemdup(nvs_ptr, nvs_len, GFP_KERNEL);
331 if (!nvs_aligned)
332 return -ENOMEM;
333
334 /* And finally we upload the NVS tables */
335 wlcore_write_data(wl, REG_CMD_MBOX_ADDRESS,
336 nvs_aligned, nvs_len, false);
337
338 kfree(nvs_aligned);
339 return 0;
340
341out_badnvs:
342 wl1271_error("nvs data is malformed");
343 return -EILSEQ;
344}
345EXPORT_SYMBOL_GPL(wlcore_boot_upload_nvs);
346
347int wlcore_boot_run_firmware(struct wl1271 *wl)
348{
349 int loop, ret;
350 u32 chip_id, intr;
351
352 /* Make sure we have the boot partition */
353 wlcore_set_partition(wl, &wl->ptable[PART_BOOT]);
354
355 wl1271_boot_set_ecpu_ctrl(wl, ECPU_CONTROL_HALT);
356
357 chip_id = wlcore_read_reg(wl, REG_CHIP_ID_B);
358
359 wl1271_debug(DEBUG_BOOT, "chip id after firmware boot: 0x%x", chip_id);
360
361 if (chip_id != wl->chip.id) {
362 wl1271_error("chip id doesn't match after firmware boot");
363 return -EIO;
364 }
365
366 /* wait for init to complete */
367 loop = 0;
368 while (loop++ < INIT_LOOP) {
369 udelay(INIT_LOOP_DELAY);
370 intr = wlcore_read_reg(wl, REG_INTERRUPT_NO_CLEAR);
371
372 if (intr == 0xffffffff) {
373 wl1271_error("error reading hardware complete "
374 "init indication");
375 return -EIO;
376 }
377 /* check that ACX_INTR_INIT_COMPLETE is enabled */
378 else if (intr & WL1271_ACX_INTR_INIT_COMPLETE) {
379 wlcore_write_reg(wl, REG_INTERRUPT_ACK,
380 WL1271_ACX_INTR_INIT_COMPLETE);
381 break;
382 }
383 }
384
385 if (loop > INIT_LOOP) {
386 wl1271_error("timeout waiting for the hardware to "
387 "complete initialization");
388 return -EIO;
389 }
390
391 /* get hardware config command mail box */
392 wl->cmd_box_addr = wlcore_read_reg(wl, REG_COMMAND_MAILBOX_PTR);
393
394 wl1271_debug(DEBUG_MAILBOX, "cmd_box_addr 0x%x", wl->cmd_box_addr);
395
396 /* get hardware config event mail box */
397 wl->mbox_ptr[0] = wlcore_read_reg(wl, REG_EVENT_MAILBOX_PTR);
398 wl->mbox_ptr[1] = wl->mbox_ptr[0] + sizeof(struct event_mailbox);
399
400 wl1271_debug(DEBUG_MAILBOX, "MBOX ptrs: 0x%x 0x%x",
401 wl->mbox_ptr[0], wl->mbox_ptr[1]);
402
403 ret = wlcore_boot_fw_version(wl);
404 if (ret < 0) {
405 wl1271_error("couldn't boot firmware");
406 return ret;
407 }
408
409 /*
410 * in case of full asynchronous mode the firmware event must be
411 * ready to receive event from the command mailbox
412 */
413
414 /* unmask required mbox events */
415 wl->event_mask = BSS_LOSE_EVENT_ID |
416 SCAN_COMPLETE_EVENT_ID |
417 ROLE_STOP_COMPLETE_EVENT_ID |
418 RSSI_SNR_TRIGGER_0_EVENT_ID |
419 PSPOLL_DELIVERY_FAILURE_EVENT_ID |
420 SOFT_GEMINI_SENSE_EVENT_ID |
421 PERIODIC_SCAN_REPORT_EVENT_ID |
422 PERIODIC_SCAN_COMPLETE_EVENT_ID |
423 DUMMY_PACKET_EVENT_ID |
424 PEER_REMOVE_COMPLETE_EVENT_ID |
425 BA_SESSION_RX_CONSTRAINT_EVENT_ID |
426 REMAIN_ON_CHANNEL_COMPLETE_EVENT_ID |
427 INACTIVE_STA_EVENT_ID |
428 MAX_TX_RETRY_EVENT_ID |
429 CHANNEL_SWITCH_COMPLETE_EVENT_ID;
430
431 ret = wl1271_event_unmask(wl);
432 if (ret < 0) {
433 wl1271_error("EVENT mask setting failed");
434 return ret;
435 }
436
437 /* set the working partition to its "running" mode offset */
438 wlcore_set_partition(wl, &wl->ptable[PART_WORK]);
439
440 /* firmware startup completed */
441 return 0;
442}
443EXPORT_SYMBOL_GPL(wlcore_boot_run_firmware);
diff --git a/drivers/net/wireless/ti/wlcore/boot.h b/drivers/net/wireless/ti/wlcore/boot.h
new file mode 100644
index 000000000000..094981dd2227
--- /dev/null
+++ b/drivers/net/wireless/ti/wlcore/boot.h
@@ -0,0 +1,54 @@
1/*
2 * This file is part of wl1271
3 *
4 * Copyright (C) 2008-2009 Nokia Corporation
5 *
6 * Contact: Luciano Coelho <luciano.coelho@nokia.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 */
23
24#ifndef __BOOT_H__
25#define __BOOT_H__
26
27#include "wlcore.h"
28
29int wlcore_boot_upload_firmware(struct wl1271 *wl);
30int wlcore_boot_upload_nvs(struct wl1271 *wl);
31int wlcore_boot_run_firmware(struct wl1271 *wl);
32
33#define WL1271_NO_SUBBANDS 8
34#define WL1271_NO_POWER_LEVELS 4
35#define WL1271_FW_VERSION_MAX_LEN 20
36
37struct wl1271_static_data {
38 u8 mac_address[ETH_ALEN];
39 u8 padding[2];
40 u8 fw_version[WL1271_FW_VERSION_MAX_LEN];
41 u32 hw_version;
42 u8 tx_power_table[WL1271_NO_SUBBANDS][WL1271_NO_POWER_LEVELS];
43};
44
45/* number of times we try to read the INIT interrupt */
46#define INIT_LOOP 20000
47
48/* delay between retries */
49#define INIT_LOOP_DELAY 50
50
51#define WU_COUNTER_PAUSE_VAL 0x3FF
52#define WELP_ARM_COMMAND_VAL 0x4
53
54#endif
diff --git a/drivers/net/wireless/wl12xx/cmd.c b/drivers/net/wireless/ti/wlcore/cmd.c
index 3414fc11e9ba..5c4716c6f040 100644
--- a/drivers/net/wireless/wl12xx/cmd.c
+++ b/drivers/net/wireless/ti/wlcore/cmd.c
@@ -28,9 +28,8 @@
28#include <linux/ieee80211.h> 28#include <linux/ieee80211.h>
29#include <linux/slab.h> 29#include <linux/slab.h>
30 30
31#include "wl12xx.h" 31#include "wlcore.h"
32#include "debug.h" 32#include "debug.h"
33#include "reg.h"
34#include "io.h" 33#include "io.h"
35#include "acx.h" 34#include "acx.h"
36#include "wl12xx_80211.h" 35#include "wl12xx_80211.h"
@@ -67,11 +66,15 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len,
67 66
68 wl1271_write(wl, wl->cmd_box_addr, buf, len, false); 67 wl1271_write(wl, wl->cmd_box_addr, buf, len, false);
69 68
70 wl1271_write32(wl, ACX_REG_INTERRUPT_TRIG, INTR_TRIG_CMD); 69 /*
70 * TODO: we just need this because one bit is in a different
71 * place. Is there any better way?
72 */
73 wl->ops->trigger_cmd(wl, wl->cmd_box_addr, buf, len);
71 74
72 timeout = jiffies + msecs_to_jiffies(WL1271_COMMAND_TIMEOUT); 75 timeout = jiffies + msecs_to_jiffies(WL1271_COMMAND_TIMEOUT);
73 76
74 intr = wl1271_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR); 77 intr = wlcore_read_reg(wl, REG_INTERRUPT_NO_CLEAR);
75 while (!(intr & WL1271_ACX_INTR_CMD_COMPLETE)) { 78 while (!(intr & WL1271_ACX_INTR_CMD_COMPLETE)) {
76 if (time_after(jiffies, timeout)) { 79 if (time_after(jiffies, timeout)) {
77 wl1271_error("command complete timeout"); 80 wl1271_error("command complete timeout");
@@ -85,7 +88,7 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len,
85 else 88 else
86 msleep(1); 89 msleep(1);
87 90
88 intr = wl1271_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR); 91 intr = wlcore_read_reg(wl, REG_INTERRUPT_NO_CLEAR);
89 } 92 }
90 93
91 /* read back the status code of the command */ 94 /* read back the status code of the command */
@@ -100,8 +103,7 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len,
100 goto fail; 103 goto fail;
101 } 104 }
102 105
103 wl1271_write32(wl, ACX_REG_INTERRUPT_ACK, 106 wlcore_write_reg(wl, REG_INTERRUPT_ACK, WL1271_ACX_INTR_CMD_COMPLETE);
104 WL1271_ACX_INTR_CMD_COMPLETE);
105 return 0; 107 return 0;
106 108
107fail: 109fail:
@@ -110,240 +112,18 @@ fail:
110 return ret; 112 return ret;
111} 113}
112 114
113int wl1271_cmd_general_parms(struct wl1271 *wl)
114{
115 struct wl1271_general_parms_cmd *gen_parms;
116 struct wl1271_ini_general_params *gp =
117 &((struct wl1271_nvs_file *)wl->nvs)->general_params;
118 bool answer = false;
119 int ret;
120
121 if (!wl->nvs)
122 return -ENODEV;
123
124 if (gp->tx_bip_fem_manufacturer >= WL1271_INI_FEM_MODULE_COUNT) {
125 wl1271_warning("FEM index from INI out of bounds");
126 return -EINVAL;
127 }
128
129 gen_parms = kzalloc(sizeof(*gen_parms), GFP_KERNEL);
130 if (!gen_parms)
131 return -ENOMEM;
132
133 gen_parms->test.id = TEST_CMD_INI_FILE_GENERAL_PARAM;
134
135 memcpy(&gen_parms->general_params, gp, sizeof(*gp));
136
137 if (gp->tx_bip_fem_auto_detect)
138 answer = true;
139
140 /* Override the REF CLK from the NVS with the one from platform data */
141 gen_parms->general_params.ref_clock = wl->ref_clock;
142
143 ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), answer);
144 if (ret < 0) {
145 wl1271_warning("CMD_INI_FILE_GENERAL_PARAM failed");
146 goto out;
147 }
148
149 gp->tx_bip_fem_manufacturer =
150 gen_parms->general_params.tx_bip_fem_manufacturer;
151
152 if (gp->tx_bip_fem_manufacturer >= WL1271_INI_FEM_MODULE_COUNT) {
153 wl1271_warning("FEM index from FW out of bounds");
154 ret = -EINVAL;
155 goto out;
156 }
157
158 wl1271_debug(DEBUG_CMD, "FEM autodetect: %s, manufacturer: %d\n",
159 answer ? "auto" : "manual", gp->tx_bip_fem_manufacturer);
160
161out:
162 kfree(gen_parms);
163 return ret;
164}
165
166int wl128x_cmd_general_parms(struct wl1271 *wl)
167{
168 struct wl128x_general_parms_cmd *gen_parms;
169 struct wl128x_ini_general_params *gp =
170 &((struct wl128x_nvs_file *)wl->nvs)->general_params;
171 bool answer = false;
172 int ret;
173
174 if (!wl->nvs)
175 return -ENODEV;
176
177 if (gp->tx_bip_fem_manufacturer >= WL1271_INI_FEM_MODULE_COUNT) {
178 wl1271_warning("FEM index from ini out of bounds");
179 return -EINVAL;
180 }
181
182 gen_parms = kzalloc(sizeof(*gen_parms), GFP_KERNEL);
183 if (!gen_parms)
184 return -ENOMEM;
185
186 gen_parms->test.id = TEST_CMD_INI_FILE_GENERAL_PARAM;
187
188 memcpy(&gen_parms->general_params, gp, sizeof(*gp));
189
190 if (gp->tx_bip_fem_auto_detect)
191 answer = true;
192
193 /* Replace REF and TCXO CLKs with the ones from platform data */
194 gen_parms->general_params.ref_clock = wl->ref_clock;
195 gen_parms->general_params.tcxo_ref_clock = wl->tcxo_clock;
196
197 ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), answer);
198 if (ret < 0) {
199 wl1271_warning("CMD_INI_FILE_GENERAL_PARAM failed");
200 goto out;
201 }
202
203 gp->tx_bip_fem_manufacturer =
204 gen_parms->general_params.tx_bip_fem_manufacturer;
205
206 if (gp->tx_bip_fem_manufacturer >= WL1271_INI_FEM_MODULE_COUNT) {
207 wl1271_warning("FEM index from FW out of bounds");
208 ret = -EINVAL;
209 goto out;
210 }
211
212 wl1271_debug(DEBUG_CMD, "FEM autodetect: %s, manufacturer: %d\n",
213 answer ? "auto" : "manual", gp->tx_bip_fem_manufacturer);
214
215out:
216 kfree(gen_parms);
217 return ret;
218}
219
220int wl1271_cmd_radio_parms(struct wl1271 *wl)
221{
222 struct wl1271_nvs_file *nvs = (struct wl1271_nvs_file *)wl->nvs;
223 struct wl1271_radio_parms_cmd *radio_parms;
224 struct wl1271_ini_general_params *gp = &nvs->general_params;
225 int ret;
226
227 if (!wl->nvs)
228 return -ENODEV;
229
230 radio_parms = kzalloc(sizeof(*radio_parms), GFP_KERNEL);
231 if (!radio_parms)
232 return -ENOMEM;
233
234 radio_parms->test.id = TEST_CMD_INI_FILE_RADIO_PARAM;
235
236 /* 2.4GHz parameters */
237 memcpy(&radio_parms->static_params_2, &nvs->stat_radio_params_2,
238 sizeof(struct wl1271_ini_band_params_2));
239 memcpy(&radio_parms->dyn_params_2,
240 &nvs->dyn_radio_params_2[gp->tx_bip_fem_manufacturer].params,
241 sizeof(struct wl1271_ini_fem_params_2));
242
243 /* 5GHz parameters */
244 memcpy(&radio_parms->static_params_5,
245 &nvs->stat_radio_params_5,
246 sizeof(struct wl1271_ini_band_params_5));
247 memcpy(&radio_parms->dyn_params_5,
248 &nvs->dyn_radio_params_5[gp->tx_bip_fem_manufacturer].params,
249 sizeof(struct wl1271_ini_fem_params_5));
250
251 wl1271_dump(DEBUG_CMD, "TEST_CMD_INI_FILE_RADIO_PARAM: ",
252 radio_parms, sizeof(*radio_parms));
253
254 ret = wl1271_cmd_test(wl, radio_parms, sizeof(*radio_parms), 0);
255 if (ret < 0)
256 wl1271_warning("CMD_INI_FILE_RADIO_PARAM failed");
257
258 kfree(radio_parms);
259 return ret;
260}
261
262int wl128x_cmd_radio_parms(struct wl1271 *wl)
263{
264 struct wl128x_nvs_file *nvs = (struct wl128x_nvs_file *)wl->nvs;
265 struct wl128x_radio_parms_cmd *radio_parms;
266 struct wl128x_ini_general_params *gp = &nvs->general_params;
267 int ret;
268
269 if (!wl->nvs)
270 return -ENODEV;
271
272 radio_parms = kzalloc(sizeof(*radio_parms), GFP_KERNEL);
273 if (!radio_parms)
274 return -ENOMEM;
275
276 radio_parms->test.id = TEST_CMD_INI_FILE_RADIO_PARAM;
277
278 /* 2.4GHz parameters */
279 memcpy(&radio_parms->static_params_2, &nvs->stat_radio_params_2,
280 sizeof(struct wl128x_ini_band_params_2));
281 memcpy(&radio_parms->dyn_params_2,
282 &nvs->dyn_radio_params_2[gp->tx_bip_fem_manufacturer].params,
283 sizeof(struct wl128x_ini_fem_params_2));
284
285 /* 5GHz parameters */
286 memcpy(&radio_parms->static_params_5,
287 &nvs->stat_radio_params_5,
288 sizeof(struct wl128x_ini_band_params_5));
289 memcpy(&radio_parms->dyn_params_5,
290 &nvs->dyn_radio_params_5[gp->tx_bip_fem_manufacturer].params,
291 sizeof(struct wl128x_ini_fem_params_5));
292
293 radio_parms->fem_vendor_and_options = nvs->fem_vendor_and_options;
294
295 wl1271_dump(DEBUG_CMD, "TEST_CMD_INI_FILE_RADIO_PARAM: ",
296 radio_parms, sizeof(*radio_parms));
297
298 ret = wl1271_cmd_test(wl, radio_parms, sizeof(*radio_parms), 0);
299 if (ret < 0)
300 wl1271_warning("CMD_INI_FILE_RADIO_PARAM failed");
301
302 kfree(radio_parms);
303 return ret;
304}
305
306int wl1271_cmd_ext_radio_parms(struct wl1271 *wl)
307{
308 struct wl1271_ext_radio_parms_cmd *ext_radio_parms;
309 struct conf_rf_settings *rf = &wl->conf.rf;
310 int ret;
311
312 if (!wl->nvs)
313 return -ENODEV;
314
315 ext_radio_parms = kzalloc(sizeof(*ext_radio_parms), GFP_KERNEL);
316 if (!ext_radio_parms)
317 return -ENOMEM;
318
319 ext_radio_parms->test.id = TEST_CMD_INI_FILE_RF_EXTENDED_PARAM;
320
321 memcpy(ext_radio_parms->tx_per_channel_power_compensation_2,
322 rf->tx_per_channel_power_compensation_2,
323 CONF_TX_PWR_COMPENSATION_LEN_2);
324 memcpy(ext_radio_parms->tx_per_channel_power_compensation_5,
325 rf->tx_per_channel_power_compensation_5,
326 CONF_TX_PWR_COMPENSATION_LEN_5);
327
328 wl1271_dump(DEBUG_CMD, "TEST_CMD_INI_FILE_EXT_RADIO_PARAM: ",
329 ext_radio_parms, sizeof(*ext_radio_parms));
330
331 ret = wl1271_cmd_test(wl, ext_radio_parms, sizeof(*ext_radio_parms), 0);
332 if (ret < 0)
333 wl1271_warning("TEST_CMD_INI_FILE_RF_EXTENDED_PARAM failed");
334
335 kfree(ext_radio_parms);
336 return ret;
337}
338
339/* 115/*
340 * Poll the mailbox event field until any of the bits in the mask is set or a 116 * Poll the mailbox event field until any of the bits in the mask is set or a
341 * timeout occurs (WL1271_EVENT_TIMEOUT in msecs) 117 * timeout occurs (WL1271_EVENT_TIMEOUT in msecs)
342 */ 118 */
343static int wl1271_cmd_wait_for_event_or_timeout(struct wl1271 *wl, u32 mask) 119static int wl1271_cmd_wait_for_event_or_timeout(struct wl1271 *wl, u32 mask)
344{ 120{
345 u32 events_vector, event; 121 u32 *events_vector;
122 u32 event;
346 unsigned long timeout; 123 unsigned long timeout;
124 int ret = 0;
125
126 events_vector = kmalloc(sizeof(*events_vector), GFP_DMA);
347 127
348 timeout = jiffies + msecs_to_jiffies(WL1271_EVENT_TIMEOUT); 128 timeout = jiffies + msecs_to_jiffies(WL1271_EVENT_TIMEOUT);
349 129
@@ -351,21 +131,24 @@ static int wl1271_cmd_wait_for_event_or_timeout(struct wl1271 *wl, u32 mask)
351 if (time_after(jiffies, timeout)) { 131 if (time_after(jiffies, timeout)) {
352 wl1271_debug(DEBUG_CMD, "timeout waiting for event %d", 132 wl1271_debug(DEBUG_CMD, "timeout waiting for event %d",
353 (int)mask); 133 (int)mask);
354 return -ETIMEDOUT; 134 ret = -ETIMEDOUT;
135 goto out;
355 } 136 }
356 137
357 msleep(1); 138 msleep(1);
358 139
359 /* read from both event fields */ 140 /* read from both event fields */
360 wl1271_read(wl, wl->mbox_ptr[0], &events_vector, 141 wl1271_read(wl, wl->mbox_ptr[0], events_vector,
361 sizeof(events_vector), false); 142 sizeof(*events_vector), false);
362 event = events_vector & mask; 143 event = *events_vector & mask;
363 wl1271_read(wl, wl->mbox_ptr[1], &events_vector, 144 wl1271_read(wl, wl->mbox_ptr[1], events_vector,
364 sizeof(events_vector), false); 145 sizeof(*events_vector), false);
365 event |= events_vector & mask; 146 event |= *events_vector & mask;
366 } while (!event); 147 } while (!event);
367 148
368 return 0; 149out:
150 kfree(events_vector);
151 return ret;
369} 152}
370 153
371static int wl1271_cmd_wait_for_event(struct wl1271 *wl, u32 mask) 154static int wl1271_cmd_wait_for_event(struct wl1271 *wl, u32 mask)
@@ -522,7 +305,7 @@ static int wl12xx_cmd_role_start_dev(struct wl1271 *wl,
522 305
523 cmd->role_id = wlvif->dev_role_id; 306 cmd->role_id = wlvif->dev_role_id;
524 if (wlvif->band == IEEE80211_BAND_5GHZ) 307 if (wlvif->band == IEEE80211_BAND_5GHZ)
525 cmd->band = WL12XX_BAND_5GHZ; 308 cmd->band = WLCORE_BAND_5GHZ;
526 cmd->channel = wlvif->channel; 309 cmd->channel = wlvif->channel;
527 310
528 if (wlvif->dev_hlid == WL12XX_INVALID_LINK_ID) { 311 if (wlvif->dev_hlid == WL12XX_INVALID_LINK_ID) {
@@ -613,7 +396,7 @@ int wl12xx_cmd_role_start_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif)
613 396
614 cmd->role_id = wlvif->role_id; 397 cmd->role_id = wlvif->role_id;
615 if (wlvif->band == IEEE80211_BAND_5GHZ) 398 if (wlvif->band == IEEE80211_BAND_5GHZ)
616 cmd->band = WL12XX_BAND_5GHZ; 399 cmd->band = WLCORE_BAND_5GHZ;
617 cmd->channel = wlvif->channel; 400 cmd->channel = wlvif->channel;
618 cmd->sta.basic_rate_set = cpu_to_le32(wlvif->basic_rate_set); 401 cmd->sta.basic_rate_set = cpu_to_le32(wlvif->basic_rate_set);
619 cmd->sta.beacon_interval = cpu_to_le16(wlvif->beacon_int); 402 cmd->sta.beacon_interval = cpu_to_le16(wlvif->beacon_int);
@@ -750,14 +533,14 @@ int wl12xx_cmd_role_start_ap(struct wl1271 *wl, struct wl12xx_vif *wlvif)
750 533
751 switch (wlvif->band) { 534 switch (wlvif->band) {
752 case IEEE80211_BAND_2GHZ: 535 case IEEE80211_BAND_2GHZ:
753 cmd->band = RADIO_BAND_2_4GHZ; 536 cmd->band = WLCORE_BAND_2_4GHZ;
754 break; 537 break;
755 case IEEE80211_BAND_5GHZ: 538 case IEEE80211_BAND_5GHZ:
756 cmd->band = RADIO_BAND_5GHZ; 539 cmd->band = WLCORE_BAND_5GHZ;
757 break; 540 break;
758 default: 541 default:
759 wl1271_warning("ap start - unknown band: %d", (int)wlvif->band); 542 wl1271_warning("ap start - unknown band: %d", (int)wlvif->band);
760 cmd->band = RADIO_BAND_2_4GHZ; 543 cmd->band = WLCORE_BAND_2_4GHZ;
761 break; 544 break;
762 } 545 }
763 546
@@ -830,7 +613,7 @@ int wl12xx_cmd_role_start_ibss(struct wl1271 *wl, struct wl12xx_vif *wlvif)
830 613
831 cmd->role_id = wlvif->role_id; 614 cmd->role_id = wlvif->role_id;
832 if (wlvif->band == IEEE80211_BAND_5GHZ) 615 if (wlvif->band == IEEE80211_BAND_5GHZ)
833 cmd->band = WL12XX_BAND_5GHZ; 616 cmd->band = WLCORE_BAND_5GHZ;
834 cmd->channel = wlvif->channel; 617 cmd->channel = wlvif->channel;
835 cmd->ibss.basic_rate_set = cpu_to_le32(wlvif->basic_rate_set); 618 cmd->ibss.basic_rate_set = cpu_to_le32(wlvif->basic_rate_set);
836 cmd->ibss.beacon_interval = cpu_to_le16(wlvif->beacon_int); 619 cmd->ibss.beacon_interval = cpu_to_le16(wlvif->beacon_int);
@@ -904,6 +687,7 @@ int wl1271_cmd_test(struct wl1271 *wl, void *buf, size_t buf_len, u8 answer)
904 687
905 return ret; 688 return ret;
906} 689}
690EXPORT_SYMBOL_GPL(wl1271_cmd_test);
907 691
908/** 692/**
909 * read acx from firmware 693 * read acx from firmware
@@ -960,6 +744,7 @@ int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len)
960 744
961 return 0; 745 return 0;
962} 746}
747EXPORT_SYMBOL_GPL(wl1271_cmd_configure);
963 748
964int wl1271_cmd_data_path(struct wl1271 *wl, bool enable) 749int wl1271_cmd_data_path(struct wl1271 *wl, bool enable)
965{ 750{
@@ -1730,10 +1515,10 @@ static int wl12xx_cmd_roc(struct wl1271 *wl, struct wl12xx_vif *wlvif,
1730 cmd->channel = wlvif->channel; 1515 cmd->channel = wlvif->channel;
1731 switch (wlvif->band) { 1516 switch (wlvif->band) {
1732 case IEEE80211_BAND_2GHZ: 1517 case IEEE80211_BAND_2GHZ:
1733 cmd->band = RADIO_BAND_2_4GHZ; 1518 cmd->band = WLCORE_BAND_2_4GHZ;
1734 break; 1519 break;
1735 case IEEE80211_BAND_5GHZ: 1520 case IEEE80211_BAND_5GHZ:
1736 cmd->band = RADIO_BAND_5GHZ; 1521 cmd->band = WLCORE_BAND_5GHZ;
1737 break; 1522 break;
1738 default: 1523 default:
1739 wl1271_error("roc - unknown band: %d", (int)wlvif->band); 1524 wl1271_error("roc - unknown band: %d", (int)wlvif->band);
diff --git a/drivers/net/wireless/wl12xx/cmd.h b/drivers/net/wireless/ti/wlcore/cmd.h
index de217d92516b..a46ae07cb77e 100644
--- a/drivers/net/wireless/wl12xx/cmd.h
+++ b/drivers/net/wireless/ti/wlcore/cmd.h
@@ -25,17 +25,12 @@
25#ifndef __CMD_H__ 25#ifndef __CMD_H__
26#define __CMD_H__ 26#define __CMD_H__
27 27
28#include "wl12xx.h" 28#include "wlcore.h"
29 29
30struct acx_header; 30struct acx_header;
31 31
32int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len, 32int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len,
33 size_t res_len); 33 size_t res_len);
34int wl1271_cmd_general_parms(struct wl1271 *wl);
35int wl128x_cmd_general_parms(struct wl1271 *wl);
36int wl1271_cmd_radio_parms(struct wl1271 *wl);
37int wl128x_cmd_radio_parms(struct wl1271 *wl);
38int wl1271_cmd_ext_radio_parms(struct wl1271 *wl);
39int wl12xx_cmd_role_enable(struct wl1271 *wl, u8 *addr, u8 role_type, 34int wl12xx_cmd_role_enable(struct wl1271 *wl, u8 *addr, u8 role_type,
40 u8 *role_id); 35 u8 *role_id);
41int wl12xx_cmd_role_disable(struct wl1271 *wl, u8 *role_id); 36int wl12xx_cmd_role_disable(struct wl1271 *wl, u8 *role_id);
@@ -262,13 +257,13 @@ struct wl12xx_cmd_role_disable {
262 u8 padding[3]; 257 u8 padding[3];
263} __packed; 258} __packed;
264 259
265enum wl12xx_band { 260enum wlcore_band {
266 WL12XX_BAND_2_4GHZ = 0, 261 WLCORE_BAND_2_4GHZ = 0,
267 WL12XX_BAND_5GHZ = 1, 262 WLCORE_BAND_5GHZ = 1,
268 WL12XX_BAND_JAPAN_4_9_GHZ = 2, 263 WLCORE_BAND_JAPAN_4_9_GHZ = 2,
269 WL12XX_BAND_DEFAULT = WL12XX_BAND_2_4GHZ, 264 WLCORE_BAND_DEFAULT = WLCORE_BAND_2_4GHZ,
270 WL12XX_BAND_INVALID = 0x7E, 265 WLCORE_BAND_INVALID = 0x7E,
271 WL12XX_BAND_MAX_RADIO = 0x7F, 266 WLCORE_BAND_MAX_RADIO = 0x7F,
272}; 267};
273 268
274struct wl12xx_cmd_role_start { 269struct wl12xx_cmd_role_start {
@@ -494,83 +489,6 @@ enum wl1271_channel_tune_bands {
494 489
495#define WL1271_PD_REFERENCE_POINT_BAND_B_G 0 490#define WL1271_PD_REFERENCE_POINT_BAND_B_G 0
496 491
497#define TEST_CMD_INI_FILE_RADIO_PARAM 0x19
498#define TEST_CMD_INI_FILE_GENERAL_PARAM 0x1E
499#define TEST_CMD_INI_FILE_RF_EXTENDED_PARAM 0x26
500
501struct wl1271_general_parms_cmd {
502 struct wl1271_cmd_header header;
503
504 struct wl1271_cmd_test_header test;
505
506 struct wl1271_ini_general_params general_params;
507
508 u8 sr_debug_table[WL1271_INI_MAX_SMART_REFLEX_PARAM];
509 u8 sr_sen_n_p;
510 u8 sr_sen_n_p_gain;
511 u8 sr_sen_nrn;
512 u8 sr_sen_prn;
513 u8 padding[3];
514} __packed;
515
516struct wl128x_general_parms_cmd {
517 struct wl1271_cmd_header header;
518
519 struct wl1271_cmd_test_header test;
520
521 struct wl128x_ini_general_params general_params;
522
523 u8 sr_debug_table[WL1271_INI_MAX_SMART_REFLEX_PARAM];
524 u8 sr_sen_n_p;
525 u8 sr_sen_n_p_gain;
526 u8 sr_sen_nrn;
527 u8 sr_sen_prn;
528 u8 padding[3];
529} __packed;
530
531struct wl1271_radio_parms_cmd {
532 struct wl1271_cmd_header header;
533
534 struct wl1271_cmd_test_header test;
535
536 /* Static radio parameters */
537 struct wl1271_ini_band_params_2 static_params_2;
538 struct wl1271_ini_band_params_5 static_params_5;
539
540 /* Dynamic radio parameters */
541 struct wl1271_ini_fem_params_2 dyn_params_2;
542 u8 padding2;
543 struct wl1271_ini_fem_params_5 dyn_params_5;
544 u8 padding3[2];
545} __packed;
546
547struct wl128x_radio_parms_cmd {
548 struct wl1271_cmd_header header;
549
550 struct wl1271_cmd_test_header test;
551
552 /* Static radio parameters */
553 struct wl128x_ini_band_params_2 static_params_2;
554 struct wl128x_ini_band_params_5 static_params_5;
555
556 u8 fem_vendor_and_options;
557
558 /* Dynamic radio parameters */
559 struct wl128x_ini_fem_params_2 dyn_params_2;
560 u8 padding2;
561 struct wl128x_ini_fem_params_5 dyn_params_5;
562} __packed;
563
564struct wl1271_ext_radio_parms_cmd {
565 struct wl1271_cmd_header header;
566
567 struct wl1271_cmd_test_header test;
568
569 u8 tx_per_channel_power_compensation_2[CONF_TX_PWR_COMPENSATION_LEN_2];
570 u8 tx_per_channel_power_compensation_5[CONF_TX_PWR_COMPENSATION_LEN_5];
571 u8 padding[3];
572} __packed;
573
574/* 492/*
575 * There are three types of disconnections: 493 * There are three types of disconnections:
576 * 494 *
diff --git a/drivers/net/wireless/wl12xx/conf.h b/drivers/net/wireless/ti/wlcore/conf.h
index 3e581e19424c..fef0db4213bc 100644
--- a/drivers/net/wireless/wl12xx/conf.h
+++ b/drivers/net/wireless/ti/wlcore/conf.h
@@ -65,36 +65,7 @@ enum {
65 CONF_HW_RATE_INDEX_MAX = CONF_HW_RATE_INDEX_54MBPS, 65 CONF_HW_RATE_INDEX_MAX = CONF_HW_RATE_INDEX_54MBPS,
66}; 66};
67 67
68enum { 68#define CONF_HW_RXTX_RATE_UNSUPPORTED 0xff
69 CONF_HW_RXTX_RATE_MCS7_SGI = 0,
70 CONF_HW_RXTX_RATE_MCS7,
71 CONF_HW_RXTX_RATE_MCS6,
72 CONF_HW_RXTX_RATE_MCS5,
73 CONF_HW_RXTX_RATE_MCS4,
74 CONF_HW_RXTX_RATE_MCS3,
75 CONF_HW_RXTX_RATE_MCS2,
76 CONF_HW_RXTX_RATE_MCS1,
77 CONF_HW_RXTX_RATE_MCS0,
78 CONF_HW_RXTX_RATE_54,
79 CONF_HW_RXTX_RATE_48,
80 CONF_HW_RXTX_RATE_36,
81 CONF_HW_RXTX_RATE_24,
82 CONF_HW_RXTX_RATE_22,
83 CONF_HW_RXTX_RATE_18,
84 CONF_HW_RXTX_RATE_12,
85 CONF_HW_RXTX_RATE_11,
86 CONF_HW_RXTX_RATE_9,
87 CONF_HW_RXTX_RATE_6,
88 CONF_HW_RXTX_RATE_5_5,
89 CONF_HW_RXTX_RATE_2,
90 CONF_HW_RXTX_RATE_1,
91 CONF_HW_RXTX_RATE_MAX,
92 CONF_HW_RXTX_RATE_UNSUPPORTED = 0xff
93};
94
95/* Rates between and including these are MCS rates */
96#define CONF_HW_RXTX_RATE_MCS_MIN CONF_HW_RXTX_RATE_MCS7_SGI
97#define CONF_HW_RXTX_RATE_MCS_MAX CONF_HW_RXTX_RATE_MCS0
98 69
99enum { 70enum {
100 CONF_SG_DISABLE = 0, 71 CONF_SG_DISABLE = 0,
@@ -1096,16 +1067,31 @@ struct conf_scan_settings {
1096}; 1067};
1097 1068
1098struct conf_sched_scan_settings { 1069struct conf_sched_scan_settings {
1099 /* minimum time to wait on the channel for active scans (in TUs) */ 1070 /*
1100 u16 min_dwell_time_active; 1071 * The base time to wait on the channel for active scans (in TU/1000).
1072 * The minimum dwell time is calculated according to this:
1073 * min_dwell_time = base + num_of_probes_to_be_sent * delta_per_probe
1074 * The maximum dwell time is calculated according to this:
1075 * max_dwell_time = min_dwell_time + max_dwell_time_delta
1076 */
1077 u32 base_dwell_time;
1101 1078
1102 /* maximum time to wait on the channel for active scans (in TUs) */ 1079 /* The delta between the min dwell time and max dwell time for
1103 u16 max_dwell_time_active; 1080 * active scans (in TU/1000s). The max dwell time is used by the FW once
1081 * traffic is detected on the channel.
1082 */
1083 u32 max_dwell_time_delta;
1084
1085 /* Delta added to min dwell time per each probe in 2.4 GHz (TU/1000) */
1086 u32 dwell_time_delta_per_probe;
1104 1087
1105 /* time to wait on the channel for passive scans (in TUs) */ 1088 /* Delta added to min dwell time per each probe in 5 GHz (TU/1000) */
1089 u32 dwell_time_delta_per_probe_5;
1090
1091 /* time to wait on the channel for passive scans (in TU/1000) */
1106 u32 dwell_time_passive; 1092 u32 dwell_time_passive;
1107 1093
1108 /* time to wait on the channel for DFS scans (in TUs) */ 1094 /* time to wait on the channel for DFS scans (in TU/1000) */
1109 u32 dwell_time_dfs; 1095 u32 dwell_time_dfs;
1110 1096
1111 /* number of probe requests to send on each channel in active scans */ 1097 /* number of probe requests to send on each channel in active scans */
@@ -1118,26 +1104,6 @@ struct conf_sched_scan_settings {
1118 s8 snr_threshold; 1104 s8 snr_threshold;
1119}; 1105};
1120 1106
1121/* these are number of channels on the band divided by two, rounded up */
1122#define CONF_TX_PWR_COMPENSATION_LEN_2 7
1123#define CONF_TX_PWR_COMPENSATION_LEN_5 18
1124
1125struct conf_rf_settings {
1126 /*
1127 * Per channel power compensation for 2.4GHz
1128 *
1129 * Range: s8
1130 */
1131 u8 tx_per_channel_power_compensation_2[CONF_TX_PWR_COMPENSATION_LEN_2];
1132
1133 /*
1134 * Per channel power compensation for 5GHz
1135 *
1136 * Range: s8
1137 */
1138 u8 tx_per_channel_power_compensation_5[CONF_TX_PWR_COMPENSATION_LEN_5];
1139};
1140
1141struct conf_ht_setting { 1107struct conf_ht_setting {
1142 u8 rx_ba_win_size; 1108 u8 rx_ba_win_size;
1143 u8 tx_ba_win_size; 1109 u8 tx_ba_win_size;
@@ -1286,7 +1252,7 @@ struct conf_hangover_settings {
1286 u8 window_size; 1252 u8 window_size;
1287}; 1253};
1288 1254
1289struct conf_drv_settings { 1255struct wlcore_conf {
1290 struct conf_sg_settings sg; 1256 struct conf_sg_settings sg;
1291 struct conf_rx_settings rx; 1257 struct conf_rx_settings rx;
1292 struct conf_tx_settings tx; 1258 struct conf_tx_settings tx;
@@ -1296,16 +1262,13 @@ struct conf_drv_settings {
1296 struct conf_roam_trigger_settings roam_trigger; 1262 struct conf_roam_trigger_settings roam_trigger;
1297 struct conf_scan_settings scan; 1263 struct conf_scan_settings scan;
1298 struct conf_sched_scan_settings sched_scan; 1264 struct conf_sched_scan_settings sched_scan;
1299 struct conf_rf_settings rf;
1300 struct conf_ht_setting ht; 1265 struct conf_ht_setting ht;
1301 struct conf_memory_settings mem_wl127x; 1266 struct conf_memory_settings mem;
1302 struct conf_memory_settings mem_wl128x;
1303 struct conf_fm_coex fm_coex; 1267 struct conf_fm_coex fm_coex;
1304 struct conf_rx_streaming_settings rx_streaming; 1268 struct conf_rx_streaming_settings rx_streaming;
1305 struct conf_fwlog fwlog; 1269 struct conf_fwlog fwlog;
1306 struct conf_rate_policy_settings rate; 1270 struct conf_rate_policy_settings rate;
1307 struct conf_hangover_settings hangover; 1271 struct conf_hangover_settings hangover;
1308 u8 hci_io_ds;
1309}; 1272};
1310 1273
1311#endif 1274#endif
diff --git a/drivers/net/wireless/wl12xx/debug.h b/drivers/net/wireless/ti/wlcore/debug.h
index ec0fdc25b280..6b800b3cbea5 100644
--- a/drivers/net/wireless/wl12xx/debug.h
+++ b/drivers/net/wireless/ti/wlcore/debug.h
@@ -52,6 +52,7 @@ enum {
52 DEBUG_ADHOC = BIT(16), 52 DEBUG_ADHOC = BIT(16),
53 DEBUG_AP = BIT(17), 53 DEBUG_AP = BIT(17),
54 DEBUG_PROBE = BIT(18), 54 DEBUG_PROBE = BIT(18),
55 DEBUG_IO = BIT(19),
55 DEBUG_MASTER = (DEBUG_ADHOC | DEBUG_AP), 56 DEBUG_MASTER = (DEBUG_ADHOC | DEBUG_AP),
56 DEBUG_ALL = ~0, 57 DEBUG_ALL = ~0,
57}; 58};
diff --git a/drivers/net/wireless/wl12xx/debugfs.c b/drivers/net/wireless/ti/wlcore/debugfs.c
index e1cf72765965..0b775e35b5df 100644
--- a/drivers/net/wireless/wl12xx/debugfs.c
+++ b/drivers/net/wireless/ti/wlcore/debugfs.c
@@ -26,7 +26,7 @@
26#include <linux/skbuff.h> 26#include <linux/skbuff.h>
27#include <linux/slab.h> 27#include <linux/slab.h>
28 28
29#include "wl12xx.h" 29#include "wlcore.h"
30#include "debug.h" 30#include "debug.h"
31#include "acx.h" 31#include "acx.h"
32#include "ps.h" 32#include "ps.h"
@@ -653,6 +653,7 @@ static ssize_t vifs_state_read(struct file *file, char __user *user_buf,
653 VIF_STATE_PRINT_INT(last_rssi_event); 653 VIF_STATE_PRINT_INT(last_rssi_event);
654 VIF_STATE_PRINT_INT(ba_support); 654 VIF_STATE_PRINT_INT(ba_support);
655 VIF_STATE_PRINT_INT(ba_allowed); 655 VIF_STATE_PRINT_INT(ba_allowed);
656 VIF_STATE_PRINT_INT(is_gem);
656 VIF_STATE_PRINT_LLHEX(tx_security_seq); 657 VIF_STATE_PRINT_LLHEX(tx_security_seq);
657 VIF_STATE_PRINT_INT(tx_security_last_seq_lsb); 658 VIF_STATE_PRINT_INT(tx_security_last_seq_lsb);
658 } 659 }
diff --git a/drivers/net/wireless/wl12xx/debugfs.h b/drivers/net/wireless/ti/wlcore/debugfs.h
index 254c5b292cf6..a8d3aef011ff 100644
--- a/drivers/net/wireless/wl12xx/debugfs.h
+++ b/drivers/net/wireless/ti/wlcore/debugfs.h
@@ -24,7 +24,7 @@
24#ifndef __DEBUGFS_H__ 24#ifndef __DEBUGFS_H__
25#define __DEBUGFS_H__ 25#define __DEBUGFS_H__
26 26
27#include "wl12xx.h" 27#include "wlcore.h"
28 28
29int wl1271_debugfs_init(struct wl1271 *wl); 29int wl1271_debugfs_init(struct wl1271 *wl);
30void wl1271_debugfs_exit(struct wl1271 *wl); 30void wl1271_debugfs_exit(struct wl1271 *wl);
diff --git a/drivers/net/wireless/wl12xx/event.c b/drivers/net/wireless/ti/wlcore/event.c
index c953717f38eb..292632ddf890 100644
--- a/drivers/net/wireless/wl12xx/event.c
+++ b/drivers/net/wireless/ti/wlcore/event.c
@@ -21,9 +21,8 @@
21 * 21 *
22 */ 22 */
23 23
24#include "wl12xx.h" 24#include "wlcore.h"
25#include "debug.h" 25#include "debug.h"
26#include "reg.h"
27#include "io.h" 26#include "io.h"
28#include "event.h" 27#include "event.h"
29#include "ps.h" 28#include "ps.h"
@@ -98,8 +97,9 @@ static void wl1271_event_mbox_dump(struct event_mailbox *mbox)
98 wl1271_debug(DEBUG_EVENT, "\tmask: 0x%x", mbox->events_mask); 97 wl1271_debug(DEBUG_EVENT, "\tmask: 0x%x", mbox->events_mask);
99} 98}
100 99
101static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox) 100static int wl1271_event_process(struct wl1271 *wl)
102{ 101{
102 struct event_mailbox *mbox = wl->mbox;
103 struct ieee80211_vif *vif; 103 struct ieee80211_vif *vif;
104 struct wl12xx_vif *wlvif; 104 struct wl12xx_vif *wlvif;
105 u32 vector; 105 u32 vector;
@@ -196,7 +196,7 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox)
196 bool success; 196 bool success;
197 197
198 if (!test_and_clear_bit(WLVIF_FLAG_CS_PROGRESS, 198 if (!test_and_clear_bit(WLVIF_FLAG_CS_PROGRESS,
199 &wl->flags)) 199 &wlvif->flags))
200 continue; 200 continue;
201 201
202 success = mbox->channel_switch_status ? false : true; 202 success = mbox->channel_switch_status ? false : true;
@@ -278,18 +278,8 @@ int wl1271_event_unmask(struct wl1271 *wl)
278 return 0; 278 return 0;
279} 279}
280 280
281void wl1271_event_mbox_config(struct wl1271 *wl)
282{
283 wl->mbox_ptr[0] = wl1271_read32(wl, REG_EVENT_MAILBOX_PTR);
284 wl->mbox_ptr[1] = wl->mbox_ptr[0] + sizeof(struct event_mailbox);
285
286 wl1271_debug(DEBUG_EVENT, "MBOX ptrs: 0x%x 0x%x",
287 wl->mbox_ptr[0], wl->mbox_ptr[1]);
288}
289
290int wl1271_event_handle(struct wl1271 *wl, u8 mbox_num) 281int wl1271_event_handle(struct wl1271 *wl, u8 mbox_num)
291{ 282{
292 struct event_mailbox mbox;
293 int ret; 283 int ret;
294 284
295 wl1271_debug(DEBUG_EVENT, "EVENT on mbox %d", mbox_num); 285 wl1271_debug(DEBUG_EVENT, "EVENT on mbox %d", mbox_num);
@@ -298,16 +288,19 @@ int wl1271_event_handle(struct wl1271 *wl, u8 mbox_num)
298 return -EINVAL; 288 return -EINVAL;
299 289
300 /* first we read the mbox descriptor */ 290 /* first we read the mbox descriptor */
301 wl1271_read(wl, wl->mbox_ptr[mbox_num], &mbox, 291 wl1271_read(wl, wl->mbox_ptr[mbox_num], wl->mbox,
302 sizeof(struct event_mailbox), false); 292 sizeof(*wl->mbox), false);
303 293
304 /* process the descriptor */ 294 /* process the descriptor */
305 ret = wl1271_event_process(wl, &mbox); 295 ret = wl1271_event_process(wl);
306 if (ret < 0) 296 if (ret < 0)
307 return ret; 297 return ret;
308 298
309 /* then we let the firmware know it can go on...*/ 299 /*
310 wl1271_write32(wl, ACX_REG_INTERRUPT_TRIG, INTR_TRIG_EVENT_ACK); 300 * TODO: we just need this because one bit is in a different
301 * place. Is there any better way?
302 */
303 wl->ops->ack_event(wl);
311 304
312 return 0; 305 return 0;
313} 306}
diff --git a/drivers/net/wireless/wl12xx/event.h b/drivers/net/wireless/ti/wlcore/event.h
index 057d193d3525..8adf18d6c58f 100644
--- a/drivers/net/wireless/wl12xx/event.h
+++ b/drivers/net/wireless/ti/wlcore/event.h
@@ -132,8 +132,9 @@ struct event_mailbox {
132 u8 reserved_8[9]; 132 u8 reserved_8[9];
133} __packed; 133} __packed;
134 134
135struct wl1271;
136
135int wl1271_event_unmask(struct wl1271 *wl); 137int wl1271_event_unmask(struct wl1271 *wl);
136void wl1271_event_mbox_config(struct wl1271 *wl);
137int wl1271_event_handle(struct wl1271 *wl, u8 mbox); 138int wl1271_event_handle(struct wl1271 *wl, u8 mbox);
138 139
139#endif 140#endif
diff --git a/drivers/net/wireless/ti/wlcore/hw_ops.h b/drivers/net/wireless/ti/wlcore/hw_ops.h
new file mode 100644
index 000000000000..9384b4d56c24
--- /dev/null
+++ b/drivers/net/wireless/ti/wlcore/hw_ops.h
@@ -0,0 +1,122 @@
1/*
2 * This file is part of wlcore
3 *
4 * Copyright (C) 2011 Texas Instruments Inc.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18 * 02110-1301 USA
19 *
20 */
21
22#ifndef __WLCORE_HW_OPS_H__
23#define __WLCORE_HW_OPS_H__
24
25#include "wlcore.h"
26#include "rx.h"
27
28static inline u32
29wlcore_hw_calc_tx_blocks(struct wl1271 *wl, u32 len, u32 spare_blks)
30{
31 if (!wl->ops->calc_tx_blocks)
32 BUG_ON(1);
33
34 return wl->ops->calc_tx_blocks(wl, len, spare_blks);
35}
36
37static inline void
38wlcore_hw_set_tx_desc_blocks(struct wl1271 *wl, struct wl1271_tx_hw_descr *desc,
39 u32 blks, u32 spare_blks)
40{
41 if (!wl->ops->set_tx_desc_blocks)
42 BUG_ON(1);
43
44 return wl->ops->set_tx_desc_blocks(wl, desc, blks, spare_blks);
45}
46
47static inline void
48wlcore_hw_set_tx_desc_data_len(struct wl1271 *wl,
49 struct wl1271_tx_hw_descr *desc,
50 struct sk_buff *skb)
51{
52 if (!wl->ops->set_tx_desc_data_len)
53 BUG_ON(1);
54
55 wl->ops->set_tx_desc_data_len(wl, desc, skb);
56}
57
58static inline enum wl_rx_buf_align
59wlcore_hw_get_rx_buf_align(struct wl1271 *wl, u32 rx_desc)
60{
61
62 if (!wl->ops->get_rx_buf_align)
63 BUG_ON(1);
64
65 return wl->ops->get_rx_buf_align(wl, rx_desc);
66}
67
68static inline void
69wlcore_hw_prepare_read(struct wl1271 *wl, u32 rx_desc, u32 len)
70{
71 if (wl->ops->prepare_read)
72 wl->ops->prepare_read(wl, rx_desc, len);
73}
74
75static inline u32
76wlcore_hw_get_rx_packet_len(struct wl1271 *wl, void *rx_data, u32 data_len)
77{
78 if (!wl->ops->get_rx_packet_len)
79 BUG_ON(1);
80
81 return wl->ops->get_rx_packet_len(wl, rx_data, data_len);
82}
83
84static inline void wlcore_hw_tx_delayed_compl(struct wl1271 *wl)
85{
86 if (wl->ops->tx_delayed_compl)
87 wl->ops->tx_delayed_compl(wl);
88}
89
90static inline void wlcore_hw_tx_immediate_compl(struct wl1271 *wl)
91{
92 if (wl->ops->tx_immediate_compl)
93 wl->ops->tx_immediate_compl(wl);
94}
95
96static inline int
97wlcore_hw_init_vif(struct wl1271 *wl, struct wl12xx_vif *wlvif)
98{
99 if (wl->ops->init_vif)
100 return wl->ops->init_vif(wl, wlvif);
101
102 return 0;
103}
104
105static inline u32
106wlcore_hw_sta_get_ap_rate_mask(struct wl1271 *wl, struct wl12xx_vif *wlvif)
107{
108 if (!wl->ops->sta_get_ap_rate_mask)
109 BUG_ON(1);
110
111 return wl->ops->sta_get_ap_rate_mask(wl, wlvif);
112}
113
114static inline int wlcore_identify_fw(struct wl1271 *wl)
115{
116 if (wl->ops->identify_fw)
117 return wl->ops->identify_fw(wl);
118
119 return 0;
120}
121
122#endif
diff --git a/drivers/net/wireless/wl12xx/ini.h b/drivers/net/wireless/ti/wlcore/ini.h
index 4cf9ecc56212..4cf9ecc56212 100644
--- a/drivers/net/wireless/wl12xx/ini.h
+++ b/drivers/net/wireless/ti/wlcore/ini.h
diff --git a/drivers/net/wireless/wl12xx/init.c b/drivers/net/wireless/ti/wlcore/init.c
index 203fbebf09eb..9f89255eb6e6 100644
--- a/drivers/net/wireless/wl12xx/init.c
+++ b/drivers/net/wireless/ti/wlcore/init.c
@@ -30,9 +30,9 @@
30#include "wl12xx_80211.h" 30#include "wl12xx_80211.h"
31#include "acx.h" 31#include "acx.h"
32#include "cmd.h" 32#include "cmd.h"
33#include "reg.h"
34#include "tx.h" 33#include "tx.h"
35#include "io.h" 34#include "io.h"
35#include "hw_ops.h"
36 36
37int wl1271_init_templates_config(struct wl1271 *wl) 37int wl1271_init_templates_config(struct wl1271 *wl)
38{ 38{
@@ -319,7 +319,7 @@ static int wl12xx_init_fwlog(struct wl1271 *wl)
319{ 319{
320 int ret; 320 int ret;
321 321
322 if (wl->quirks & WL12XX_QUIRK_FWLOG_NOT_IMPLEMENTED) 322 if (wl->quirks & WLCORE_QUIRK_FWLOG_NOT_IMPLEMENTED)
323 return 0; 323 return 0;
324 324
325 ret = wl12xx_cmd_config_fwlog(wl); 325 ret = wl12xx_cmd_config_fwlog(wl);
@@ -494,26 +494,6 @@ static int wl1271_set_ba_policies(struct wl1271 *wl, struct wl12xx_vif *wlvif)
494 return wl12xx_acx_set_ba_initiator_policy(wl, wlvif); 494 return wl12xx_acx_set_ba_initiator_policy(wl, wlvif);
495} 495}
496 496
497int wl1271_chip_specific_init(struct wl1271 *wl)
498{
499 int ret = 0;
500
501 if (wl->chip.id == CHIP_ID_1283_PG20) {
502 u32 host_cfg_bitmap = HOST_IF_CFG_RX_FIFO_ENABLE;
503
504 if (!(wl->quirks & WL12XX_QUIRK_NO_BLOCKSIZE_ALIGNMENT))
505 /* Enable SDIO padding */
506 host_cfg_bitmap |= HOST_IF_CFG_TX_PAD_TO_SDIO_BLK;
507
508 /* Must be before wl1271_acx_init_mem_config() */
509 ret = wl1271_acx_host_if_cfg_bitmap(wl, host_cfg_bitmap);
510 if (ret < 0)
511 goto out;
512 }
513out:
514 return ret;
515}
516
517/* vif-specifc initialization */ 497/* vif-specifc initialization */
518static int wl12xx_init_sta_role(struct wl1271 *wl, struct wl12xx_vif *wlvif) 498static int wl12xx_init_sta_role(struct wl1271 *wl, struct wl12xx_vif *wlvif)
519{ 499{
@@ -582,10 +562,17 @@ int wl1271_init_vif_specific(struct wl1271 *wl, struct ieee80211_vif *vif)
582 if (ret < 0) 562 if (ret < 0)
583 return ret; 563 return ret;
584 } else if (!wl->sta_count) { 564 } else if (!wl->sta_count) {
585 /* Configure for ELP power saving */ 565 if (wl->quirks & WLCORE_QUIRK_NO_ELP) {
586 ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_ELP); 566 /* Configure for power always on */
587 if (ret < 0) 567 ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_CAM);
588 return ret; 568 if (ret < 0)
569 return ret;
570 } else {
571 /* Configure for ELP power saving */
572 ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_ELP);
573 if (ret < 0)
574 return ret;
575 }
589 } 576 }
590 } 577 }
591 578
@@ -652,6 +639,10 @@ int wl1271_init_vif_specific(struct wl1271 *wl, struct ieee80211_vif *vif)
652 if (ret < 0) 639 if (ret < 0)
653 return ret; 640 return ret;
654 641
642 ret = wlcore_hw_init_vif(wl, wlvif);
643 if (ret < 0)
644 return ret;
645
655 return 0; 646 return 0;
656} 647}
657 648
@@ -659,27 +650,8 @@ int wl1271_hw_init(struct wl1271 *wl)
659{ 650{
660 int ret; 651 int ret;
661 652
662 if (wl->chip.id == CHIP_ID_1283_PG20) { 653 /* Chip-specific hw init */
663 ret = wl128x_cmd_general_parms(wl); 654 ret = wl->ops->hw_init(wl);
664 if (ret < 0)
665 return ret;
666 ret = wl128x_cmd_radio_parms(wl);
667 if (ret < 0)
668 return ret;
669 } else {
670 ret = wl1271_cmd_general_parms(wl);
671 if (ret < 0)
672 return ret;
673 ret = wl1271_cmd_radio_parms(wl);
674 if (ret < 0)
675 return ret;
676 ret = wl1271_cmd_ext_radio_parms(wl);
677 if (ret < 0)
678 return ret;
679 }
680
681 /* Chip-specific init */
682 ret = wl1271_chip_specific_init(wl);
683 if (ret < 0) 655 if (ret < 0)
684 return ret; 656 return ret;
685 657
diff --git a/drivers/net/wireless/wl12xx/init.h b/drivers/net/wireless/ti/wlcore/init.h
index 2da0f404ef6e..a45fbfddec19 100644
--- a/drivers/net/wireless/wl12xx/init.h
+++ b/drivers/net/wireless/ti/wlcore/init.h
@@ -24,7 +24,7 @@
24#ifndef __INIT_H__ 24#ifndef __INIT_H__
25#define __INIT_H__ 25#define __INIT_H__
26 26
27#include "wl12xx.h" 27#include "wlcore.h"
28 28
29int wl1271_hw_init_power_auth(struct wl1271 *wl); 29int wl1271_hw_init_power_auth(struct wl1271 *wl);
30int wl1271_init_templates_config(struct wl1271 *wl); 30int wl1271_init_templates_config(struct wl1271 *wl);
diff --git a/drivers/net/wireless/wl12xx/io.c b/drivers/net/wireless/ti/wlcore/io.c
index c574a3b31e31..7cd0081aede5 100644
--- a/drivers/net/wireless/wl12xx/io.c
+++ b/drivers/net/wireless/ti/wlcore/io.c
@@ -26,84 +26,12 @@
26#include <linux/spi/spi.h> 26#include <linux/spi/spi.h>
27#include <linux/interrupt.h> 27#include <linux/interrupt.h>
28 28
29#include "wl12xx.h" 29#include "wlcore.h"
30#include "debug.h" 30#include "debug.h"
31#include "wl12xx_80211.h" 31#include "wl12xx_80211.h"
32#include "io.h" 32#include "io.h"
33#include "tx.h" 33#include "tx.h"
34 34
35#define OCP_CMD_LOOP 32
36
37#define OCP_CMD_WRITE 0x1
38#define OCP_CMD_READ 0x2
39
40#define OCP_READY_MASK BIT(18)
41#define OCP_STATUS_MASK (BIT(16) | BIT(17))
42
43#define OCP_STATUS_NO_RESP 0x00000
44#define OCP_STATUS_OK 0x10000
45#define OCP_STATUS_REQ_FAILED 0x20000
46#define OCP_STATUS_RESP_ERROR 0x30000
47
48struct wl1271_partition_set wl12xx_part_table[PART_TABLE_LEN] = {
49 [PART_DOWN] = {
50 .mem = {
51 .start = 0x00000000,
52 .size = 0x000177c0
53 },
54 .reg = {
55 .start = REGISTERS_BASE,
56 .size = 0x00008800
57 },
58 .mem2 = {
59 .start = 0x00000000,
60 .size = 0x00000000
61 },
62 .mem3 = {
63 .start = 0x00000000,
64 .size = 0x00000000
65 },
66 },
67
68 [PART_WORK] = {
69 .mem = {
70 .start = 0x00040000,
71 .size = 0x00014fc0
72 },
73 .reg = {
74 .start = REGISTERS_BASE,
75 .size = 0x0000a000
76 },
77 .mem2 = {
78 .start = 0x003004f8,
79 .size = 0x00000004
80 },
81 .mem3 = {
82 .start = 0x00040404,
83 .size = 0x00000000
84 },
85 },
86
87 [PART_DRPW] = {
88 .mem = {
89 .start = 0x00040000,
90 .size = 0x00014fc0
91 },
92 .reg = {
93 .start = DRPW_BASE,
94 .size = 0x00006000
95 },
96 .mem2 = {
97 .start = 0x00000000,
98 .size = 0x00000000
99 },
100 .mem3 = {
101 .start = 0x00000000,
102 .size = 0x00000000
103 }
104 }
105};
106
107bool wl1271_set_block_size(struct wl1271 *wl) 35bool wl1271_set_block_size(struct wl1271 *wl)
108{ 36{
109 if (wl->if_ops->set_block_size) { 37 if (wl->if_ops->set_block_size) {
@@ -114,17 +42,53 @@ bool wl1271_set_block_size(struct wl1271 *wl)
114 return false; 42 return false;
115} 43}
116 44
117void wl1271_disable_interrupts(struct wl1271 *wl) 45void wlcore_disable_interrupts(struct wl1271 *wl)
118{ 46{
119 disable_irq(wl->irq); 47 disable_irq(wl->irq);
120} 48}
49EXPORT_SYMBOL_GPL(wlcore_disable_interrupts);
121 50
122void wl1271_enable_interrupts(struct wl1271 *wl) 51void wlcore_enable_interrupts(struct wl1271 *wl)
123{ 52{
124 enable_irq(wl->irq); 53 enable_irq(wl->irq);
125} 54}
55EXPORT_SYMBOL_GPL(wlcore_enable_interrupts);
126 56
127/* Set the SPI partitions to access the chip addresses 57int wlcore_translate_addr(struct wl1271 *wl, int addr)
58{
59 struct wlcore_partition_set *part = &wl->curr_part;
60
61 /*
62 * To translate, first check to which window of addresses the
63 * particular address belongs. Then subtract the starting address
64 * of that window from the address. Then, add offset of the
65 * translated region.
66 *
67 * The translated regions occur next to each other in physical device
68 * memory, so just add the sizes of the preceding address regions to
69 * get the offset to the new region.
70 */
71 if ((addr >= part->mem.start) &&
72 (addr < part->mem.start + part->mem.size))
73 return addr - part->mem.start;
74 else if ((addr >= part->reg.start) &&
75 (addr < part->reg.start + part->reg.size))
76 return addr - part->reg.start + part->mem.size;
77 else if ((addr >= part->mem2.start) &&
78 (addr < part->mem2.start + part->mem2.size))
79 return addr - part->mem2.start + part->mem.size +
80 part->reg.size;
81 else if ((addr >= part->mem3.start) &&
82 (addr < part->mem3.start + part->mem3.size))
83 return addr - part->mem3.start + part->mem.size +
84 part->reg.size + part->mem2.size;
85
86 WARN(1, "HW address 0x%x out of range", addr);
87 return 0;
88}
89EXPORT_SYMBOL_GPL(wlcore_translate_addr);
90
91/* Set the partitions to access the chip addresses
128 * 92 *
129 * To simplify driver code, a fixed (virtual) memory map is defined for 93 * To simplify driver code, a fixed (virtual) memory map is defined for
130 * register and memory addresses. Because in the chipset, in different stages 94 * register and memory addresses. Because in the chipset, in different stages
@@ -158,33 +122,43 @@ void wl1271_enable_interrupts(struct wl1271 *wl)
158 * | | 122 * | |
159 * 123 *
160 */ 124 */
161int wl1271_set_partition(struct wl1271 *wl, 125void wlcore_set_partition(struct wl1271 *wl,
162 struct wl1271_partition_set *p) 126 const struct wlcore_partition_set *p)
163{ 127{
164 /* copy partition info */ 128 /* copy partition info */
165 memcpy(&wl->part, p, sizeof(*p)); 129 memcpy(&wl->curr_part, p, sizeof(*p));
166 130
167 wl1271_debug(DEBUG_SPI, "mem_start %08X mem_size %08X", 131 wl1271_debug(DEBUG_IO, "mem_start %08X mem_size %08X",
168 p->mem.start, p->mem.size); 132 p->mem.start, p->mem.size);
169 wl1271_debug(DEBUG_SPI, "reg_start %08X reg_size %08X", 133 wl1271_debug(DEBUG_IO, "reg_start %08X reg_size %08X",
170 p->reg.start, p->reg.size); 134 p->reg.start, p->reg.size);
171 wl1271_debug(DEBUG_SPI, "mem2_start %08X mem2_size %08X", 135 wl1271_debug(DEBUG_IO, "mem2_start %08X mem2_size %08X",
172 p->mem2.start, p->mem2.size); 136 p->mem2.start, p->mem2.size);
173 wl1271_debug(DEBUG_SPI, "mem3_start %08X mem3_size %08X", 137 wl1271_debug(DEBUG_IO, "mem3_start %08X mem3_size %08X",
174 p->mem3.start, p->mem3.size); 138 p->mem3.start, p->mem3.size);
175 139
176 /* write partition info to the chipset */
177 wl1271_raw_write32(wl, HW_PART0_START_ADDR, p->mem.start); 140 wl1271_raw_write32(wl, HW_PART0_START_ADDR, p->mem.start);
178 wl1271_raw_write32(wl, HW_PART0_SIZE_ADDR, p->mem.size); 141 wl1271_raw_write32(wl, HW_PART0_SIZE_ADDR, p->mem.size);
179 wl1271_raw_write32(wl, HW_PART1_START_ADDR, p->reg.start); 142 wl1271_raw_write32(wl, HW_PART1_START_ADDR, p->reg.start);
180 wl1271_raw_write32(wl, HW_PART1_SIZE_ADDR, p->reg.size); 143 wl1271_raw_write32(wl, HW_PART1_SIZE_ADDR, p->reg.size);
181 wl1271_raw_write32(wl, HW_PART2_START_ADDR, p->mem2.start); 144 wl1271_raw_write32(wl, HW_PART2_START_ADDR, p->mem2.start);
182 wl1271_raw_write32(wl, HW_PART2_SIZE_ADDR, p->mem2.size); 145 wl1271_raw_write32(wl, HW_PART2_SIZE_ADDR, p->mem2.size);
146 /*
147 * We don't need the size of the last partition, as it is
148 * automatically calculated based on the total memory size and
149 * the sizes of the previous partitions.
150 */
183 wl1271_raw_write32(wl, HW_PART3_START_ADDR, p->mem3.start); 151 wl1271_raw_write32(wl, HW_PART3_START_ADDR, p->mem3.start);
152}
153EXPORT_SYMBOL_GPL(wlcore_set_partition);
184 154
185 return 0; 155void wlcore_select_partition(struct wl1271 *wl, u8 part)
156{
157 wl1271_debug(DEBUG_IO, "setting partition %d", part);
158
159 wlcore_set_partition(wl, &wl->ptable[part]);
186} 160}
187EXPORT_SYMBOL_GPL(wl1271_set_partition); 161EXPORT_SYMBOL_GPL(wlcore_select_partition);
188 162
189void wl1271_io_reset(struct wl1271 *wl) 163void wl1271_io_reset(struct wl1271 *wl)
190{ 164{
@@ -197,48 +171,3 @@ void wl1271_io_init(struct wl1271 *wl)
197 if (wl->if_ops->init) 171 if (wl->if_ops->init)
198 wl->if_ops->init(wl->dev); 172 wl->if_ops->init(wl->dev);
199} 173}
200
201void wl1271_top_reg_write(struct wl1271 *wl, int addr, u16 val)
202{
203 /* write address >> 1 + 0x30000 to OCP_POR_CTR */
204 addr = (addr >> 1) + 0x30000;
205 wl1271_write32(wl, OCP_POR_CTR, addr);
206
207 /* write value to OCP_POR_WDATA */
208 wl1271_write32(wl, OCP_DATA_WRITE, val);
209
210 /* write 1 to OCP_CMD */
211 wl1271_write32(wl, OCP_CMD, OCP_CMD_WRITE);
212}
213
214u16 wl1271_top_reg_read(struct wl1271 *wl, int addr)
215{
216 u32 val;
217 int timeout = OCP_CMD_LOOP;
218
219 /* write address >> 1 + 0x30000 to OCP_POR_CTR */
220 addr = (addr >> 1) + 0x30000;
221 wl1271_write32(wl, OCP_POR_CTR, addr);
222
223 /* write 2 to OCP_CMD */
224 wl1271_write32(wl, OCP_CMD, OCP_CMD_READ);
225
226 /* poll for data ready */
227 do {
228 val = wl1271_read32(wl, OCP_DATA_READ);
229 } while (!(val & OCP_READY_MASK) && --timeout);
230
231 if (!timeout) {
232 wl1271_warning("Top register access timed out.");
233 return 0xffff;
234 }
235
236 /* check data status and return if OK */
237 if ((val & OCP_STATUS_MASK) == OCP_STATUS_OK)
238 return val & 0xffff;
239 else {
240 wl1271_warning("Top register access returned error.");
241 return 0xffff;
242 }
243}
244
diff --git a/drivers/net/wireless/wl12xx/io.h b/drivers/net/wireless/ti/wlcore/io.h
index 4fb3dab8c3b2..8942954b56a0 100644
--- a/drivers/net/wireless/wl12xx/io.h
+++ b/drivers/net/wireless/ti/wlcore/io.h
@@ -26,7 +26,6 @@
26#define __IO_H__ 26#define __IO_H__
27 27
28#include <linux/irqreturn.h> 28#include <linux/irqreturn.h>
29#include "reg.h"
30 29
31#define HW_ACCESS_MEMORY_MAX_RANGE 0x1FFC0 30#define HW_ACCESS_MEMORY_MAX_RANGE 0x1FFC0
32 31
@@ -43,15 +42,14 @@
43 42
44#define HW_ACCESS_PRAM_MAX_RANGE 0x3c000 43#define HW_ACCESS_PRAM_MAX_RANGE 0x3c000
45 44
46extern struct wl1271_partition_set wl12xx_part_table[PART_TABLE_LEN];
47
48struct wl1271; 45struct wl1271;
49 46
50void wl1271_disable_interrupts(struct wl1271 *wl); 47void wlcore_disable_interrupts(struct wl1271 *wl);
51void wl1271_enable_interrupts(struct wl1271 *wl); 48void wlcore_enable_interrupts(struct wl1271 *wl);
52 49
53void wl1271_io_reset(struct wl1271 *wl); 50void wl1271_io_reset(struct wl1271 *wl);
54void wl1271_io_init(struct wl1271 *wl); 51void wl1271_io_init(struct wl1271 *wl);
52int wlcore_translate_addr(struct wl1271 *wl, int addr);
55 53
56/* Raw target IO, address is not translated */ 54/* Raw target IO, address is not translated */
57static inline void wl1271_raw_write(struct wl1271 *wl, int addr, void *buf, 55static inline void wl1271_raw_write(struct wl1271 *wl, int addr, void *buf,
@@ -66,6 +64,18 @@ static inline void wl1271_raw_read(struct wl1271 *wl, int addr, void *buf,
66 wl->if_ops->read(wl->dev, addr, buf, len, fixed); 64 wl->if_ops->read(wl->dev, addr, buf, len, fixed);
67} 65}
68 66
67static inline void wlcore_raw_read_data(struct wl1271 *wl, int reg, void *buf,
68 size_t len, bool fixed)
69{
70 wl1271_raw_read(wl, wl->rtable[reg], buf, len, fixed);
71}
72
73static inline void wlcore_raw_write_data(struct wl1271 *wl, int reg, void *buf,
74 size_t len, bool fixed)
75{
76 wl1271_raw_write(wl, wl->rtable[reg], buf, len, fixed);
77}
78
69static inline u32 wl1271_raw_read32(struct wl1271 *wl, int addr) 79static inline u32 wl1271_raw_read32(struct wl1271 *wl, int addr)
70{ 80{
71 wl1271_raw_read(wl, addr, &wl->buffer_32, 81 wl1271_raw_read(wl, addr, &wl->buffer_32,
@@ -81,36 +91,12 @@ static inline void wl1271_raw_write32(struct wl1271 *wl, int addr, u32 val)
81 sizeof(wl->buffer_32), false); 91 sizeof(wl->buffer_32), false);
82} 92}
83 93
84/* Translated target IO */
85static inline int wl1271_translate_addr(struct wl1271 *wl, int addr)
86{
87 /*
88 * To translate, first check to which window of addresses the
89 * particular address belongs. Then subtract the starting address
90 * of that window from the address. Then, add offset of the
91 * translated region.
92 *
93 * The translated regions occur next to each other in physical device
94 * memory, so just add the sizes of the preceding address regions to
95 * get the offset to the new region.
96 *
97 * Currently, only the two first regions are addressed, and the
98 * assumption is that all addresses will fall into either of those
99 * two.
100 */
101 if ((addr >= wl->part.reg.start) &&
102 (addr < wl->part.reg.start + wl->part.reg.size))
103 return addr - wl->part.reg.start + wl->part.mem.size;
104 else
105 return addr - wl->part.mem.start;
106}
107
108static inline void wl1271_read(struct wl1271 *wl, int addr, void *buf, 94static inline void wl1271_read(struct wl1271 *wl, int addr, void *buf,
109 size_t len, bool fixed) 95 size_t len, bool fixed)
110{ 96{
111 int physical; 97 int physical;
112 98
113 physical = wl1271_translate_addr(wl, addr); 99 physical = wlcore_translate_addr(wl, addr);
114 100
115 wl1271_raw_read(wl, physical, buf, len, fixed); 101 wl1271_raw_read(wl, physical, buf, len, fixed);
116} 102}
@@ -120,11 +106,23 @@ static inline void wl1271_write(struct wl1271 *wl, int addr, void *buf,
120{ 106{
121 int physical; 107 int physical;
122 108
123 physical = wl1271_translate_addr(wl, addr); 109 physical = wlcore_translate_addr(wl, addr);
124 110
125 wl1271_raw_write(wl, physical, buf, len, fixed); 111 wl1271_raw_write(wl, physical, buf, len, fixed);
126} 112}
127 113
114static inline void wlcore_write_data(struct wl1271 *wl, int reg, void *buf,
115 size_t len, bool fixed)
116{
117 wl1271_write(wl, wl->rtable[reg], buf, len, fixed);
118}
119
120static inline void wlcore_read_data(struct wl1271 *wl, int reg, void *buf,
121 size_t len, bool fixed)
122{
123 wl1271_read(wl, wl->rtable[reg], buf, len, fixed);
124}
125
128static inline void wl1271_read_hwaddr(struct wl1271 *wl, int hwaddr, 126static inline void wl1271_read_hwaddr(struct wl1271 *wl, int hwaddr,
129 void *buf, size_t len, bool fixed) 127 void *buf, size_t len, bool fixed)
130{ 128{
@@ -134,19 +132,30 @@ static inline void wl1271_read_hwaddr(struct wl1271 *wl, int hwaddr,
134 /* Addresses are stored internally as addresses to 32 bytes blocks */ 132 /* Addresses are stored internally as addresses to 32 bytes blocks */
135 addr = hwaddr << 5; 133 addr = hwaddr << 5;
136 134
137 physical = wl1271_translate_addr(wl, addr); 135 physical = wlcore_translate_addr(wl, addr);
138 136
139 wl1271_raw_read(wl, physical, buf, len, fixed); 137 wl1271_raw_read(wl, physical, buf, len, fixed);
140} 138}
141 139
142static inline u32 wl1271_read32(struct wl1271 *wl, int addr) 140static inline u32 wl1271_read32(struct wl1271 *wl, int addr)
143{ 141{
144 return wl1271_raw_read32(wl, wl1271_translate_addr(wl, addr)); 142 return wl1271_raw_read32(wl, wlcore_translate_addr(wl, addr));
145} 143}
146 144
147static inline void wl1271_write32(struct wl1271 *wl, int addr, u32 val) 145static inline void wl1271_write32(struct wl1271 *wl, int addr, u32 val)
148{ 146{
149 wl1271_raw_write32(wl, wl1271_translate_addr(wl, addr), val); 147 wl1271_raw_write32(wl, wlcore_translate_addr(wl, addr), val);
148}
149
150static inline u32 wlcore_read_reg(struct wl1271 *wl, int reg)
151{
152 return wl1271_raw_read32(wl,
153 wlcore_translate_addr(wl, wl->rtable[reg]));
154}
155
156static inline void wlcore_write_reg(struct wl1271 *wl, int reg, u32 val)
157{
158 wl1271_raw_write32(wl, wlcore_translate_addr(wl, wl->rtable[reg]), val);
150} 159}
151 160
152static inline void wl1271_power_off(struct wl1271 *wl) 161static inline void wl1271_power_off(struct wl1271 *wl)
@@ -164,13 +173,8 @@ static inline int wl1271_power_on(struct wl1271 *wl)
164 return ret; 173 return ret;
165} 174}
166 175
167 176void wlcore_set_partition(struct wl1271 *wl,
168/* Top Register IO */ 177 const struct wlcore_partition_set *p);
169void wl1271_top_reg_write(struct wl1271 *wl, int addr, u16 val);
170u16 wl1271_top_reg_read(struct wl1271 *wl, int addr);
171
172int wl1271_set_partition(struct wl1271 *wl,
173 struct wl1271_partition_set *p);
174 178
175bool wl1271_set_block_size(struct wl1271 *wl); 179bool wl1271_set_block_size(struct wl1271 *wl);
176 180
@@ -178,4 +182,6 @@ bool wl1271_set_block_size(struct wl1271 *wl);
178 182
179int wl1271_tx_dummy_packet(struct wl1271 *wl); 183int wl1271_tx_dummy_packet(struct wl1271 *wl);
180 184
185void wlcore_select_partition(struct wl1271 *wl, u8 part);
186
181#endif 187#endif
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/ti/wlcore/main.c
index 362ff1a7067e..2b0f987660c6 100644
--- a/drivers/net/wireless/wl12xx/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -35,10 +35,9 @@
35#include <linux/sched.h> 35#include <linux/sched.h>
36#include <linux/interrupt.h> 36#include <linux/interrupt.h>
37 37
38#include "wl12xx.h" 38#include "wlcore.h"
39#include "debug.h" 39#include "debug.h"
40#include "wl12xx_80211.h" 40#include "wl12xx_80211.h"
41#include "reg.h"
42#include "io.h" 41#include "io.h"
43#include "event.h" 42#include "event.h"
44#include "tx.h" 43#include "tx.h"
@@ -50,342 +49,15 @@
50#include "boot.h" 49#include "boot.h"
51#include "testmode.h" 50#include "testmode.h"
52#include "scan.h" 51#include "scan.h"
52#include "hw_ops.h"
53 53
54#define WL1271_BOOT_RETRIES 3 54#define WL1271_BOOT_RETRIES 3
55 55
56static struct conf_drv_settings default_conf = { 56#define WL1271_BOOT_RETRIES 3
57 .sg = {
58 .params = {
59 [CONF_SG_ACL_BT_MASTER_MIN_BR] = 10,
60 [CONF_SG_ACL_BT_MASTER_MAX_BR] = 180,
61 [CONF_SG_ACL_BT_SLAVE_MIN_BR] = 10,
62 [CONF_SG_ACL_BT_SLAVE_MAX_BR] = 180,
63 [CONF_SG_ACL_BT_MASTER_MIN_EDR] = 10,
64 [CONF_SG_ACL_BT_MASTER_MAX_EDR] = 80,
65 [CONF_SG_ACL_BT_SLAVE_MIN_EDR] = 10,
66 [CONF_SG_ACL_BT_SLAVE_MAX_EDR] = 80,
67 [CONF_SG_ACL_WLAN_PS_MASTER_BR] = 8,
68 [CONF_SG_ACL_WLAN_PS_SLAVE_BR] = 8,
69 [CONF_SG_ACL_WLAN_PS_MASTER_EDR] = 20,
70 [CONF_SG_ACL_WLAN_PS_SLAVE_EDR] = 20,
71 [CONF_SG_ACL_WLAN_ACTIVE_MASTER_MIN_BR] = 20,
72 [CONF_SG_ACL_WLAN_ACTIVE_MASTER_MAX_BR] = 35,
73 [CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MIN_BR] = 16,
74 [CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MAX_BR] = 35,
75 [CONF_SG_ACL_WLAN_ACTIVE_MASTER_MIN_EDR] = 32,
76 [CONF_SG_ACL_WLAN_ACTIVE_MASTER_MAX_EDR] = 50,
77 [CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MIN_EDR] = 28,
78 [CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MAX_EDR] = 50,
79 [CONF_SG_ACL_ACTIVE_SCAN_WLAN_BR] = 10,
80 [CONF_SG_ACL_ACTIVE_SCAN_WLAN_EDR] = 20,
81 [CONF_SG_ACL_PASSIVE_SCAN_BT_BR] = 75,
82 [CONF_SG_ACL_PASSIVE_SCAN_WLAN_BR] = 15,
83 [CONF_SG_ACL_PASSIVE_SCAN_BT_EDR] = 27,
84 [CONF_SG_ACL_PASSIVE_SCAN_WLAN_EDR] = 17,
85 /* active scan params */
86 [CONF_SG_AUTO_SCAN_PROBE_REQ] = 170,
87 [CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_HV3] = 50,
88 [CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_A2DP] = 100,
89 /* passive scan params */
90 [CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_A2DP_BR] = 800,
91 [CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_A2DP_EDR] = 200,
92 [CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_HV3] = 200,
93 /* passive scan in dual antenna params */
94 [CONF_SG_CONSECUTIVE_HV3_IN_PASSIVE_SCAN] = 0,
95 [CONF_SG_BCN_HV3_COLLISION_THRESH_IN_PASSIVE_SCAN] = 0,
96 [CONF_SG_TX_RX_PROTECTION_BWIDTH_IN_PASSIVE_SCAN] = 0,
97 /* general params */
98 [CONF_SG_STA_FORCE_PS_IN_BT_SCO] = 1,
99 [CONF_SG_ANTENNA_CONFIGURATION] = 0,
100 [CONF_SG_BEACON_MISS_PERCENT] = 60,
101 [CONF_SG_DHCP_TIME] = 5000,
102 [CONF_SG_RXT] = 1200,
103 [CONF_SG_TXT] = 1000,
104 [CONF_SG_ADAPTIVE_RXT_TXT] = 1,
105 [CONF_SG_GENERAL_USAGE_BIT_MAP] = 3,
106 [CONF_SG_HV3_MAX_SERVED] = 6,
107 [CONF_SG_PS_POLL_TIMEOUT] = 10,
108 [CONF_SG_UPSD_TIMEOUT] = 10,
109 [CONF_SG_CONSECUTIVE_CTS_THRESHOLD] = 2,
110 [CONF_SG_STA_RX_WINDOW_AFTER_DTIM] = 5,
111 [CONF_SG_STA_CONNECTION_PROTECTION_TIME] = 30,
112 /* AP params */
113 [CONF_AP_BEACON_MISS_TX] = 3,
114 [CONF_AP_RX_WINDOW_AFTER_BEACON] = 10,
115 [CONF_AP_BEACON_WINDOW_INTERVAL] = 2,
116 [CONF_AP_CONNECTION_PROTECTION_TIME] = 0,
117 [CONF_AP_BT_ACL_VAL_BT_SERVE_TIME] = 25,
118 [CONF_AP_BT_ACL_VAL_WL_SERVE_TIME] = 25,
119 /* CTS Diluting params */
120 [CONF_SG_CTS_DILUTED_BAD_RX_PACKETS_TH] = 0,
121 [CONF_SG_CTS_CHOP_IN_DUAL_ANT_SCO_MASTER] = 0,
122 },
123 .state = CONF_SG_PROTECTIVE,
124 },
125 .rx = {
126 .rx_msdu_life_time = 512000,
127 .packet_detection_threshold = 0,
128 .ps_poll_timeout = 15,
129 .upsd_timeout = 15,
130 .rts_threshold = IEEE80211_MAX_RTS_THRESHOLD,
131 .rx_cca_threshold = 0,
132 .irq_blk_threshold = 0xFFFF,
133 .irq_pkt_threshold = 0,
134 .irq_timeout = 600,
135 .queue_type = CONF_RX_QUEUE_TYPE_LOW_PRIORITY,
136 },
137 .tx = {
138 .tx_energy_detection = 0,
139 .sta_rc_conf = {
140 .enabled_rates = 0,
141 .short_retry_limit = 10,
142 .long_retry_limit = 10,
143 .aflags = 0,
144 },
145 .ac_conf_count = 4,
146 .ac_conf = {
147 [CONF_TX_AC_BE] = {
148 .ac = CONF_TX_AC_BE,
149 .cw_min = 15,
150 .cw_max = 63,
151 .aifsn = 3,
152 .tx_op_limit = 0,
153 },
154 [CONF_TX_AC_BK] = {
155 .ac = CONF_TX_AC_BK,
156 .cw_min = 15,
157 .cw_max = 63,
158 .aifsn = 7,
159 .tx_op_limit = 0,
160 },
161 [CONF_TX_AC_VI] = {
162 .ac = CONF_TX_AC_VI,
163 .cw_min = 15,
164 .cw_max = 63,
165 .aifsn = CONF_TX_AIFS_PIFS,
166 .tx_op_limit = 3008,
167 },
168 [CONF_TX_AC_VO] = {
169 .ac = CONF_TX_AC_VO,
170 .cw_min = 15,
171 .cw_max = 63,
172 .aifsn = CONF_TX_AIFS_PIFS,
173 .tx_op_limit = 1504,
174 },
175 },
176 .max_tx_retries = 100,
177 .ap_aging_period = 300,
178 .tid_conf_count = 4,
179 .tid_conf = {
180 [CONF_TX_AC_BE] = {
181 .queue_id = CONF_TX_AC_BE,
182 .channel_type = CONF_CHANNEL_TYPE_EDCF,
183 .tsid = CONF_TX_AC_BE,
184 .ps_scheme = CONF_PS_SCHEME_LEGACY,
185 .ack_policy = CONF_ACK_POLICY_LEGACY,
186 .apsd_conf = {0, 0},
187 },
188 [CONF_TX_AC_BK] = {
189 .queue_id = CONF_TX_AC_BK,
190 .channel_type = CONF_CHANNEL_TYPE_EDCF,
191 .tsid = CONF_TX_AC_BK,
192 .ps_scheme = CONF_PS_SCHEME_LEGACY,
193 .ack_policy = CONF_ACK_POLICY_LEGACY,
194 .apsd_conf = {0, 0},
195 },
196 [CONF_TX_AC_VI] = {
197 .queue_id = CONF_TX_AC_VI,
198 .channel_type = CONF_CHANNEL_TYPE_EDCF,
199 .tsid = CONF_TX_AC_VI,
200 .ps_scheme = CONF_PS_SCHEME_LEGACY,
201 .ack_policy = CONF_ACK_POLICY_LEGACY,
202 .apsd_conf = {0, 0},
203 },
204 [CONF_TX_AC_VO] = {
205 .queue_id = CONF_TX_AC_VO,
206 .channel_type = CONF_CHANNEL_TYPE_EDCF,
207 .tsid = CONF_TX_AC_VO,
208 .ps_scheme = CONF_PS_SCHEME_LEGACY,
209 .ack_policy = CONF_ACK_POLICY_LEGACY,
210 .apsd_conf = {0, 0},
211 },
212 },
213 .frag_threshold = IEEE80211_MAX_FRAG_THRESHOLD,
214 .tx_compl_timeout = 700,
215 .tx_compl_threshold = 4,
216 .basic_rate = CONF_HW_BIT_RATE_1MBPS,
217 .basic_rate_5 = CONF_HW_BIT_RATE_6MBPS,
218 .tmpl_short_retry_limit = 10,
219 .tmpl_long_retry_limit = 10,
220 .tx_watchdog_timeout = 5000,
221 },
222 .conn = {
223 .wake_up_event = CONF_WAKE_UP_EVENT_DTIM,
224 .listen_interval = 1,
225 .suspend_wake_up_event = CONF_WAKE_UP_EVENT_N_DTIM,
226 .suspend_listen_interval = 3,
227 .bcn_filt_mode = CONF_BCN_FILT_MODE_ENABLED,
228 .bcn_filt_ie_count = 2,
229 .bcn_filt_ie = {
230 [0] = {
231 .ie = WLAN_EID_CHANNEL_SWITCH,
232 .rule = CONF_BCN_RULE_PASS_ON_APPEARANCE,
233 },
234 [1] = {
235 .ie = WLAN_EID_HT_OPERATION,
236 .rule = CONF_BCN_RULE_PASS_ON_CHANGE,
237 },
238 },
239 .synch_fail_thold = 10,
240 .bss_lose_timeout = 100,
241 .beacon_rx_timeout = 10000,
242 .broadcast_timeout = 20000,
243 .rx_broadcast_in_ps = 1,
244 .ps_poll_threshold = 10,
245 .bet_enable = CONF_BET_MODE_ENABLE,
246 .bet_max_consecutive = 50,
247 .psm_entry_retries = 8,
248 .psm_exit_retries = 16,
249 .psm_entry_nullfunc_retries = 3,
250 .dynamic_ps_timeout = 200,
251 .forced_ps = false,
252 .keep_alive_interval = 55000,
253 .max_listen_interval = 20,
254 },
255 .itrim = {
256 .enable = false,
257 .timeout = 50000,
258 },
259 .pm_config = {
260 .host_clk_settling_time = 5000,
261 .host_fast_wakeup_support = false
262 },
263 .roam_trigger = {
264 .trigger_pacing = 1,
265 .avg_weight_rssi_beacon = 20,
266 .avg_weight_rssi_data = 10,
267 .avg_weight_snr_beacon = 20,
268 .avg_weight_snr_data = 10,
269 },
270 .scan = {
271 .min_dwell_time_active = 7500,
272 .max_dwell_time_active = 30000,
273 .min_dwell_time_passive = 100000,
274 .max_dwell_time_passive = 100000,
275 .num_probe_reqs = 2,
276 .split_scan_timeout = 50000,
277 },
278 .sched_scan = {
279 /* sched_scan requires dwell times in TU instead of TU/1000 */
280 .min_dwell_time_active = 30,
281 .max_dwell_time_active = 60,
282 .dwell_time_passive = 100,
283 .dwell_time_dfs = 150,
284 .num_probe_reqs = 2,
285 .rssi_threshold = -90,
286 .snr_threshold = 0,
287 },
288 .rf = {
289 .tx_per_channel_power_compensation_2 = {
290 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
291 },
292 .tx_per_channel_power_compensation_5 = {
293 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
294 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
295 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
296 },
297 },
298 .ht = {
299 .rx_ba_win_size = 8,
300 .tx_ba_win_size = 64,
301 .inactivity_timeout = 10000,
302 .tx_ba_tid_bitmap = CONF_TX_BA_ENABLED_TID_BITMAP,
303 },
304 .mem_wl127x = {
305 .num_stations = 1,
306 .ssid_profiles = 1,
307 .rx_block_num = 70,
308 .tx_min_block_num = 40,
309 .dynamic_memory = 1,
310 .min_req_tx_blocks = 100,
311 .min_req_rx_blocks = 22,
312 .tx_min = 27,
313 },
314 .mem_wl128x = {
315 .num_stations = 1,
316 .ssid_profiles = 1,
317 .rx_block_num = 40,
318 .tx_min_block_num = 40,
319 .dynamic_memory = 1,
320 .min_req_tx_blocks = 45,
321 .min_req_rx_blocks = 22,
322 .tx_min = 27,
323 },
324 .fm_coex = {
325 .enable = true,
326 .swallow_period = 5,
327 .n_divider_fref_set_1 = 0xff, /* default */
328 .n_divider_fref_set_2 = 12,
329 .m_divider_fref_set_1 = 148,
330 .m_divider_fref_set_2 = 0xffff, /* default */
331 .coex_pll_stabilization_time = 0xffffffff, /* default */
332 .ldo_stabilization_time = 0xffff, /* default */
333 .fm_disturbed_band_margin = 0xff, /* default */
334 .swallow_clk_diff = 0xff, /* default */
335 },
336 .rx_streaming = {
337 .duration = 150,
338 .queues = 0x1,
339 .interval = 20,
340 .always = 0,
341 },
342 .fwlog = {
343 .mode = WL12XX_FWLOG_ON_DEMAND,
344 .mem_blocks = 2,
345 .severity = 0,
346 .timestamp = WL12XX_FWLOG_TIMESTAMP_DISABLED,
347 .output = WL12XX_FWLOG_OUTPUT_HOST,
348 .threshold = 0,
349 },
350 .hci_io_ds = HCI_IO_DS_6MA,
351 .rate = {
352 .rate_retry_score = 32000,
353 .per_add = 8192,
354 .per_th1 = 2048,
355 .per_th2 = 4096,
356 .max_per = 8100,
357 .inverse_curiosity_factor = 5,
358 .tx_fail_low_th = 4,
359 .tx_fail_high_th = 10,
360 .per_alpha_shift = 4,
361 .per_add_shift = 13,
362 .per_beta1_shift = 10,
363 .per_beta2_shift = 8,
364 .rate_check_up = 2,
365 .rate_check_down = 12,
366 .rate_retry_policy = {
367 0x00, 0x00, 0x00, 0x00, 0x00,
368 0x00, 0x00, 0x00, 0x00, 0x00,
369 0x00, 0x00, 0x00,
370 },
371 },
372 .hangover = {
373 .recover_time = 0,
374 .hangover_period = 20,
375 .dynamic_mode = 1,
376 .early_termination_mode = 1,
377 .max_period = 20,
378 .min_period = 1,
379 .increase_delta = 1,
380 .decrease_delta = 2,
381 .quiet_time = 4,
382 .increase_time = 1,
383 .window_size = 16,
384 },
385};
386 57
387static char *fwlog_param; 58static char *fwlog_param;
388static bool bug_on_recovery; 59static bool bug_on_recovery;
60static bool no_recovery;
389 61
390static void __wl1271_op_remove_interface(struct wl1271 *wl, 62static void __wl1271_op_remove_interface(struct wl1271 *wl,
391 struct ieee80211_vif *vif, 63 struct ieee80211_vif *vif,
@@ -628,22 +300,8 @@ out:
628 mutex_unlock(&wl->mutex); 300 mutex_unlock(&wl->mutex);
629} 301}
630 302
631static void wl1271_conf_init(struct wl1271 *wl) 303static void wlcore_adjust_conf(struct wl1271 *wl)
632{ 304{
633
634 /*
635 * This function applies the default configuration to the driver. This
636 * function is invoked upon driver load (spi probe.)
637 *
638 * The configuration is stored in a run-time structure in order to
639 * facilitate for run-time adjustment of any of the parameters. Making
640 * changes to the configuration structure will apply the new values on
641 * the next interface up (wl1271_op_start.)
642 */
643
644 /* apply driver default configuration */
645 memcpy(&wl->conf, &default_conf, sizeof(default_conf));
646
647 /* Adjust settings according to optional module parameters */ 305 /* Adjust settings according to optional module parameters */
648 if (fwlog_param) { 306 if (fwlog_param) {
649 if (!strcmp(fwlog_param, "continuous")) { 307 if (!strcmp(fwlog_param, "continuous")) {
@@ -666,28 +324,7 @@ static int wl1271_plt_init(struct wl1271 *wl)
666{ 324{
667 int ret; 325 int ret;
668 326
669 if (wl->chip.id == CHIP_ID_1283_PG20) 327 ret = wl->ops->hw_init(wl);
670 ret = wl128x_cmd_general_parms(wl);
671 else
672 ret = wl1271_cmd_general_parms(wl);
673 if (ret < 0)
674 return ret;
675
676 if (wl->chip.id == CHIP_ID_1283_PG20)
677 ret = wl128x_cmd_radio_parms(wl);
678 else
679 ret = wl1271_cmd_radio_parms(wl);
680 if (ret < 0)
681 return ret;
682
683 if (wl->chip.id != CHIP_ID_1283_PG20) {
684 ret = wl1271_cmd_ext_radio_parms(wl);
685 if (ret < 0)
686 return ret;
687 }
688
689 /* Chip-specific initializations */
690 ret = wl1271_chip_specific_init(wl);
691 if (ret < 0) 328 if (ret < 0)
692 return ret; 329 return ret;
693 330
@@ -750,7 +387,7 @@ static void wl12xx_irq_ps_regulate_link(struct wl1271 *wl,
750 387
751static void wl12xx_irq_update_links_status(struct wl1271 *wl, 388static void wl12xx_irq_update_links_status(struct wl1271 *wl,
752 struct wl12xx_vif *wlvif, 389 struct wl12xx_vif *wlvif,
753 struct wl12xx_fw_status *status) 390 struct wl_fw_status *status)
754{ 391{
755 struct wl1271_link *lnk; 392 struct wl1271_link *lnk;
756 u32 cur_fw_ps_map; 393 u32 cur_fw_ps_map;
@@ -770,9 +407,10 @@ static void wl12xx_irq_update_links_status(struct wl1271 *wl,
770 407
771 for_each_set_bit(hlid, wlvif->ap.sta_hlid_map, WL12XX_MAX_LINKS) { 408 for_each_set_bit(hlid, wlvif->ap.sta_hlid_map, WL12XX_MAX_LINKS) {
772 lnk = &wl->links[hlid]; 409 lnk = &wl->links[hlid];
773 cnt = status->tx_lnk_free_pkts[hlid] - lnk->prev_freed_pkts; 410 cnt = status->counters.tx_lnk_free_pkts[hlid] -
411 lnk->prev_freed_pkts;
774 412
775 lnk->prev_freed_pkts = status->tx_lnk_free_pkts[hlid]; 413 lnk->prev_freed_pkts = status->counters.tx_lnk_free_pkts[hlid];
776 lnk->allocated_pkts -= cnt; 414 lnk->allocated_pkts -= cnt;
777 415
778 wl12xx_irq_ps_regulate_link(wl, wlvif, hlid, 416 wl12xx_irq_ps_regulate_link(wl, wlvif, hlid,
@@ -781,15 +419,19 @@ static void wl12xx_irq_update_links_status(struct wl1271 *wl,
781} 419}
782 420
783static void wl12xx_fw_status(struct wl1271 *wl, 421static void wl12xx_fw_status(struct wl1271 *wl,
784 struct wl12xx_fw_status *status) 422 struct wl_fw_status *status)
785{ 423{
786 struct wl12xx_vif *wlvif; 424 struct wl12xx_vif *wlvif;
787 struct timespec ts; 425 struct timespec ts;
788 u32 old_tx_blk_count = wl->tx_blocks_available; 426 u32 old_tx_blk_count = wl->tx_blocks_available;
789 int avail, freed_blocks; 427 int avail, freed_blocks;
790 int i; 428 int i;
429 size_t status_len;
430
431 status_len = sizeof(*status) + wl->fw_status_priv_len;
791 432
792 wl1271_raw_read(wl, FW_STATUS_ADDR, status, sizeof(*status), false); 433 wlcore_raw_read_data(wl, REG_RAW_FW_STATUS_ADDR, status,
434 status_len, false);
793 435
794 wl1271_debug(DEBUG_IRQ, "intr: 0x%x (fw_rx_counter = %d, " 436 wl1271_debug(DEBUG_IRQ, "intr: 0x%x (fw_rx_counter = %d, "
795 "drv_rx_counter = %d, tx_results_counter = %d)", 437 "drv_rx_counter = %d, tx_results_counter = %d)",
@@ -801,10 +443,10 @@ static void wl12xx_fw_status(struct wl1271 *wl,
801 for (i = 0; i < NUM_TX_QUEUES; i++) { 443 for (i = 0; i < NUM_TX_QUEUES; i++) {
802 /* prevent wrap-around in freed-packets counter */ 444 /* prevent wrap-around in freed-packets counter */
803 wl->tx_allocated_pkts[i] -= 445 wl->tx_allocated_pkts[i] -=
804 (status->tx_released_pkts[i] - 446 (status->counters.tx_released_pkts[i] -
805 wl->tx_pkts_freed[i]) & 0xff; 447 wl->tx_pkts_freed[i]) & 0xff;
806 448
807 wl->tx_pkts_freed[i] = status->tx_released_pkts[i]; 449 wl->tx_pkts_freed[i] = status->counters.tx_released_pkts[i];
808 } 450 }
809 451
810 /* prevent wrap-around in total blocks counter */ 452 /* prevent wrap-around in total blocks counter */
@@ -927,6 +569,9 @@ static irqreturn_t wl1271_irq(int irq, void *cookie)
927 smp_mb__after_clear_bit(); 569 smp_mb__after_clear_bit();
928 570
929 wl12xx_fw_status(wl, wl->fw_status); 571 wl12xx_fw_status(wl, wl->fw_status);
572
573 wlcore_hw_tx_immediate_compl(wl);
574
930 intr = le32_to_cpu(wl->fw_status->intr); 575 intr = le32_to_cpu(wl->fw_status->intr);
931 intr &= WL1271_INTR_MASK; 576 intr &= WL1271_INTR_MASK;
932 if (!intr) { 577 if (!intr) {
@@ -963,9 +608,7 @@ static irqreturn_t wl1271_irq(int irq, void *cookie)
963 } 608 }
964 609
965 /* check for tx results */ 610 /* check for tx results */
966 if (wl->fw_status->tx_results_counter != 611 wlcore_hw_tx_delayed_compl(wl);
967 (wl->tx_results_count & 0xff))
968 wl1271_tx_complete(wl);
969 612
970 /* Make sure the deferred queues don't get too long */ 613 /* Make sure the deferred queues don't get too long */
971 defer_count = skb_queue_len(&wl->deferred_tx_queue) + 614 defer_count = skb_queue_len(&wl->deferred_tx_queue) +
@@ -1046,10 +689,7 @@ static int wl12xx_fetch_firmware(struct wl1271 *wl, bool plt)
1046 689
1047 if (plt) { 690 if (plt) {
1048 fw_type = WL12XX_FW_TYPE_PLT; 691 fw_type = WL12XX_FW_TYPE_PLT;
1049 if (wl->chip.id == CHIP_ID_1283_PG20) 692 fw_name = wl->plt_fw_name;
1050 fw_name = WL128X_PLT_FW_NAME;
1051 else
1052 fw_name = WL127X_PLT_FW_NAME;
1053 } else { 693 } else {
1054 /* 694 /*
1055 * we can't call wl12xx_get_vif_count() here because 695 * we can't call wl12xx_get_vif_count() here because
@@ -1057,16 +697,10 @@ static int wl12xx_fetch_firmware(struct wl1271 *wl, bool plt)
1057 */ 697 */
1058 if (wl->last_vif_count > 1) { 698 if (wl->last_vif_count > 1) {
1059 fw_type = WL12XX_FW_TYPE_MULTI; 699 fw_type = WL12XX_FW_TYPE_MULTI;
1060 if (wl->chip.id == CHIP_ID_1283_PG20) 700 fw_name = wl->mr_fw_name;
1061 fw_name = WL128X_FW_NAME_MULTI;
1062 else
1063 fw_name = WL127X_FW_NAME_MULTI;
1064 } else { 701 } else {
1065 fw_type = WL12XX_FW_TYPE_NORMAL; 702 fw_type = WL12XX_FW_TYPE_NORMAL;
1066 if (wl->chip.id == CHIP_ID_1283_PG20) 703 fw_name = wl->sr_fw_name;
1067 fw_name = WL128X_FW_NAME_SINGLE;
1068 else
1069 fw_name = WL127X_FW_NAME_SINGLE;
1070 } 704 }
1071 } 705 }
1072 706
@@ -1173,7 +807,7 @@ static void wl12xx_read_fwlog_panic(struct wl1271 *wl)
1173 u32 first_addr; 807 u32 first_addr;
1174 u8 *block; 808 u8 *block;
1175 809
1176 if ((wl->quirks & WL12XX_QUIRK_FWLOG_NOT_IMPLEMENTED) || 810 if ((wl->quirks & WLCORE_QUIRK_FWLOG_NOT_IMPLEMENTED) ||
1177 (wl->conf.fwlog.mode != WL12XX_FWLOG_ON_DEMAND) || 811 (wl->conf.fwlog.mode != WL12XX_FWLOG_ON_DEMAND) ||
1178 (wl->conf.fwlog.mem_blocks == 0)) 812 (wl->conf.fwlog.mem_blocks == 0))
1179 return; 813 return;
@@ -1239,11 +873,20 @@ static void wl1271_recovery_work(struct work_struct *work)
1239 wl12xx_read_fwlog_panic(wl); 873 wl12xx_read_fwlog_panic(wl);
1240 874
1241 wl1271_info("Hardware recovery in progress. FW ver: %s pc: 0x%x", 875 wl1271_info("Hardware recovery in progress. FW ver: %s pc: 0x%x",
1242 wl->chip.fw_ver_str, wl1271_read32(wl, SCR_PAD4)); 876 wl->chip.fw_ver_str,
877 wlcore_read_reg(wl, REG_PC_ON_RECOVERY));
1243 878
1244 BUG_ON(bug_on_recovery && 879 BUG_ON(bug_on_recovery &&
1245 !test_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags)); 880 !test_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags));
1246 881
882 if (no_recovery) {
883 wl1271_info("No recovery (chosen on module load). Fw will remain stuck.");
884 clear_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags);
885 goto out_unlock;
886 }
887
888 BUG_ON(bug_on_recovery);
889
1247 /* 890 /*
1248 * Advance security sequence number to overcome potential progress 891 * Advance security sequence number to overcome potential progress
1249 * in the firmware during recovery. This doens't hurt if the network is 892 * in the firmware during recovery. This doens't hurt if the network is
@@ -1290,10 +933,7 @@ out_unlock:
1290 933
1291static void wl1271_fw_wakeup(struct wl1271 *wl) 934static void wl1271_fw_wakeup(struct wl1271 *wl)
1292{ 935{
1293 u32 elp_reg; 936 wl1271_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG, ELPCTRL_WAKE_UP);
1294
1295 elp_reg = ELPCTRL_WAKE_UP;
1296 wl1271_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, elp_reg);
1297} 937}
1298 938
1299static int wl1271_setup(struct wl1271 *wl) 939static int wl1271_setup(struct wl1271 *wl)
@@ -1323,7 +963,7 @@ static int wl12xx_set_power_on(struct wl1271 *wl)
1323 wl1271_io_reset(wl); 963 wl1271_io_reset(wl);
1324 wl1271_io_init(wl); 964 wl1271_io_init(wl);
1325 965
1326 wl1271_set_partition(wl, &wl12xx_part_table[PART_DOWN]); 966 wlcore_set_partition(wl, &wl->ptable[PART_BOOT]);
1327 967
1328 /* ELP module wake up */ 968 /* ELP module wake up */
1329 wl1271_fw_wakeup(wl); 969 wl1271_fw_wakeup(wl);
@@ -1348,44 +988,18 @@ static int wl12xx_chip_wakeup(struct wl1271 *wl, bool plt)
1348 * negligible, we use the same block size for all different 988 * negligible, we use the same block size for all different
1349 * chip types. 989 * chip types.
1350 */ 990 */
1351 if (!wl1271_set_block_size(wl)) 991 if (wl1271_set_block_size(wl))
1352 wl->quirks |= WL12XX_QUIRK_NO_BLOCKSIZE_ALIGNMENT; 992 wl->quirks |= WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN;
1353
1354 switch (wl->chip.id) {
1355 case CHIP_ID_1271_PG10:
1356 wl1271_warning("chip id 0x%x (1271 PG10) support is obsolete",
1357 wl->chip.id);
1358 993
1359 ret = wl1271_setup(wl); 994 ret = wl->ops->identify_chip(wl);
1360 if (ret < 0) 995 if (ret < 0)
1361 goto out; 996 goto out;
1362 wl->quirks |= WL12XX_QUIRK_NO_BLOCKSIZE_ALIGNMENT;
1363 break;
1364
1365 case CHIP_ID_1271_PG20:
1366 wl1271_debug(DEBUG_BOOT, "chip id 0x%x (1271 PG20)",
1367 wl->chip.id);
1368
1369 ret = wl1271_setup(wl);
1370 if (ret < 0)
1371 goto out;
1372 wl->quirks |= WL12XX_QUIRK_NO_BLOCKSIZE_ALIGNMENT;
1373 break;
1374 997
1375 case CHIP_ID_1283_PG20: 998 /* TODO: make sure the lower driver has set things up correctly */
1376 wl1271_debug(DEBUG_BOOT, "chip id 0x%x (1283 PG20)",
1377 wl->chip.id);
1378 999
1379 ret = wl1271_setup(wl); 1000 ret = wl1271_setup(wl);
1380 if (ret < 0) 1001 if (ret < 0)
1381 goto out;
1382 break;
1383 case CHIP_ID_1283_PG10:
1384 default:
1385 wl1271_warning("unsupported chip id: 0x%x", wl->chip.id);
1386 ret = -ENODEV;
1387 goto out; 1002 goto out;
1388 }
1389 1003
1390 ret = wl12xx_fetch_firmware(wl, plt); 1004 ret = wl12xx_fetch_firmware(wl, plt);
1391 if (ret < 0) 1005 if (ret < 0)
@@ -1425,7 +1039,7 @@ int wl1271_plt_start(struct wl1271 *wl)
1425 if (ret < 0) 1039 if (ret < 0)
1426 goto power_off; 1040 goto power_off;
1427 1041
1428 ret = wl1271_boot(wl); 1042 ret = wl->ops->boot(wl);
1429 if (ret < 0) 1043 if (ret < 0)
1430 goto power_off; 1044 goto power_off;
1431 1045
@@ -1454,7 +1068,7 @@ irq_disable:
1454 work function will not do anything.) Also, any other 1068 work function will not do anything.) Also, any other
1455 possible concurrent operations will fail due to the 1069 possible concurrent operations will fail due to the
1456 current state, hence the wl1271 struct should be safe. */ 1070 current state, hence the wl1271 struct should be safe. */
1457 wl1271_disable_interrupts(wl); 1071 wlcore_disable_interrupts(wl);
1458 wl1271_flush_deferred_work(wl); 1072 wl1271_flush_deferred_work(wl);
1459 cancel_work_sync(&wl->netstack_work); 1073 cancel_work_sync(&wl->netstack_work);
1460 mutex_lock(&wl->mutex); 1074 mutex_lock(&wl->mutex);
@@ -1481,7 +1095,7 @@ int wl1271_plt_stop(struct wl1271 *wl)
1481 * Otherwise, the interrupt handler might be called and exit without 1095 * Otherwise, the interrupt handler might be called and exit without
1482 * reading the interrupt status. 1096 * reading the interrupt status.
1483 */ 1097 */
1484 wl1271_disable_interrupts(wl); 1098 wlcore_disable_interrupts(wl);
1485 mutex_lock(&wl->mutex); 1099 mutex_lock(&wl->mutex);
1486 if (!wl->plt) { 1100 if (!wl->plt) {
1487 mutex_unlock(&wl->mutex); 1101 mutex_unlock(&wl->mutex);
@@ -1491,7 +1105,7 @@ int wl1271_plt_stop(struct wl1271 *wl)
1491 * may have been disabled when op_stop was called. It will, 1105 * may have been disabled when op_stop was called. It will,
1492 * however, balance the above call to disable_interrupts(). 1106 * however, balance the above call to disable_interrupts().
1493 */ 1107 */
1494 wl1271_enable_interrupts(wl); 1108 wlcore_enable_interrupts(wl);
1495 1109
1496 wl1271_error("cannot power down because not in PLT " 1110 wl1271_error("cannot power down because not in PLT "
1497 "state: %d", wl->state); 1111 "state: %d", wl->state);
@@ -1652,14 +1266,12 @@ static int wl1271_configure_suspend_sta(struct wl1271 *wl,
1652{ 1266{
1653 int ret = 0; 1267 int ret = 0;
1654 1268
1655 mutex_lock(&wl->mutex);
1656
1657 if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) 1269 if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
1658 goto out_unlock; 1270 goto out;
1659 1271
1660 ret = wl1271_ps_elp_wakeup(wl); 1272 ret = wl1271_ps_elp_wakeup(wl);
1661 if (ret < 0) 1273 if (ret < 0)
1662 goto out_unlock; 1274 goto out;
1663 1275
1664 ret = wl1271_acx_wake_up_conditions(wl, wlvif, 1276 ret = wl1271_acx_wake_up_conditions(wl, wlvif,
1665 wl->conf.conn.suspend_wake_up_event, 1277 wl->conf.conn.suspend_wake_up_event,
@@ -1668,11 +1280,9 @@ static int wl1271_configure_suspend_sta(struct wl1271 *wl,
1668 if (ret < 0) 1280 if (ret < 0)
1669 wl1271_error("suspend: set wake up conditions failed: %d", ret); 1281 wl1271_error("suspend: set wake up conditions failed: %d", ret);
1670 1282
1671
1672 wl1271_ps_elp_sleep(wl); 1283 wl1271_ps_elp_sleep(wl);
1673 1284
1674out_unlock: 1285out:
1675 mutex_unlock(&wl->mutex);
1676 return ret; 1286 return ret;
1677 1287
1678} 1288}
@@ -1682,20 +1292,17 @@ static int wl1271_configure_suspend_ap(struct wl1271 *wl,
1682{ 1292{
1683 int ret = 0; 1293 int ret = 0;
1684 1294
1685 mutex_lock(&wl->mutex);
1686
1687 if (!test_bit(WLVIF_FLAG_AP_STARTED, &wlvif->flags)) 1295 if (!test_bit(WLVIF_FLAG_AP_STARTED, &wlvif->flags))
1688 goto out_unlock; 1296 goto out;
1689 1297
1690 ret = wl1271_ps_elp_wakeup(wl); 1298 ret = wl1271_ps_elp_wakeup(wl);
1691 if (ret < 0) 1299 if (ret < 0)
1692 goto out_unlock; 1300 goto out;
1693 1301
1694 ret = wl1271_acx_beacon_filter_opt(wl, wlvif, true); 1302 ret = wl1271_acx_beacon_filter_opt(wl, wlvif, true);
1695 1303
1696 wl1271_ps_elp_sleep(wl); 1304 wl1271_ps_elp_sleep(wl);
1697out_unlock: 1305out:
1698 mutex_unlock(&wl->mutex);
1699 return ret; 1306 return ret;
1700 1307
1701} 1308}
@@ -1720,10 +1327,9 @@ static void wl1271_configure_resume(struct wl1271 *wl,
1720 if ((!is_ap) && (!is_sta)) 1327 if ((!is_ap) && (!is_sta))
1721 return; 1328 return;
1722 1329
1723 mutex_lock(&wl->mutex);
1724 ret = wl1271_ps_elp_wakeup(wl); 1330 ret = wl1271_ps_elp_wakeup(wl);
1725 if (ret < 0) 1331 if (ret < 0)
1726 goto out; 1332 return;
1727 1333
1728 if (is_sta) { 1334 if (is_sta) {
1729 ret = wl1271_acx_wake_up_conditions(wl, wlvif, 1335 ret = wl1271_acx_wake_up_conditions(wl, wlvif,
@@ -1739,8 +1345,6 @@ static void wl1271_configure_resume(struct wl1271 *wl,
1739 } 1345 }
1740 1346
1741 wl1271_ps_elp_sleep(wl); 1347 wl1271_ps_elp_sleep(wl);
1742out:
1743 mutex_unlock(&wl->mutex);
1744} 1348}
1745 1349
1746static int wl1271_op_suspend(struct ieee80211_hw *hw, 1350static int wl1271_op_suspend(struct ieee80211_hw *hw,
@@ -1755,6 +1359,7 @@ static int wl1271_op_suspend(struct ieee80211_hw *hw,
1755 1359
1756 wl1271_tx_flush(wl); 1360 wl1271_tx_flush(wl);
1757 1361
1362 mutex_lock(&wl->mutex);
1758 wl->wow_enabled = true; 1363 wl->wow_enabled = true;
1759 wl12xx_for_each_wlvif(wl, wlvif) { 1364 wl12xx_for_each_wlvif(wl, wlvif) {
1760 ret = wl1271_configure_suspend(wl, wlvif); 1365 ret = wl1271_configure_suspend(wl, wlvif);
@@ -1763,6 +1368,7 @@ static int wl1271_op_suspend(struct ieee80211_hw *hw,
1763 return ret; 1368 return ret;
1764 } 1369 }
1765 } 1370 }
1371 mutex_unlock(&wl->mutex);
1766 /* flush any remaining work */ 1372 /* flush any remaining work */
1767 wl1271_debug(DEBUG_MAC80211, "flushing remaining works"); 1373 wl1271_debug(DEBUG_MAC80211, "flushing remaining works");
1768 1374
@@ -1770,7 +1376,7 @@ static int wl1271_op_suspend(struct ieee80211_hw *hw,
1770 * disable and re-enable interrupts in order to flush 1376 * disable and re-enable interrupts in order to flush
1771 * the threaded_irq 1377 * the threaded_irq
1772 */ 1378 */
1773 wl1271_disable_interrupts(wl); 1379 wlcore_disable_interrupts(wl);
1774 1380
1775 /* 1381 /*
1776 * set suspended flag to avoid triggering a new threaded_irq 1382 * set suspended flag to avoid triggering a new threaded_irq
@@ -1778,7 +1384,7 @@ static int wl1271_op_suspend(struct ieee80211_hw *hw,
1778 */ 1384 */
1779 set_bit(WL1271_FLAG_SUSPENDED, &wl->flags); 1385 set_bit(WL1271_FLAG_SUSPENDED, &wl->flags);
1780 1386
1781 wl1271_enable_interrupts(wl); 1387 wlcore_enable_interrupts(wl);
1782 flush_work(&wl->tx_work); 1388 flush_work(&wl->tx_work);
1783 flush_delayed_work(&wl->elp_work); 1389 flush_delayed_work(&wl->elp_work);
1784 1390
@@ -1810,12 +1416,15 @@ static int wl1271_op_resume(struct ieee80211_hw *hw)
1810 wl1271_debug(DEBUG_MAC80211, 1416 wl1271_debug(DEBUG_MAC80211,
1811 "run postponed irq_work directly"); 1417 "run postponed irq_work directly");
1812 wl1271_irq(0, wl); 1418 wl1271_irq(0, wl);
1813 wl1271_enable_interrupts(wl); 1419 wlcore_enable_interrupts(wl);
1814 } 1420 }
1421
1422 mutex_lock(&wl->mutex);
1815 wl12xx_for_each_wlvif(wl, wlvif) { 1423 wl12xx_for_each_wlvif(wl, wlvif) {
1816 wl1271_configure_resume(wl, wlvif); 1424 wl1271_configure_resume(wl, wlvif);
1817 } 1425 }
1818 wl->wow_enabled = false; 1426 wl->wow_enabled = false;
1427 mutex_unlock(&wl->mutex);
1819 1428
1820 return 0; 1429 return 0;
1821} 1430}
@@ -1851,7 +1460,7 @@ static void wl1271_op_stop(struct ieee80211_hw *hw)
1851 * Otherwise, the interrupt handler might be called and exit without 1460 * Otherwise, the interrupt handler might be called and exit without
1852 * reading the interrupt status. 1461 * reading the interrupt status.
1853 */ 1462 */
1854 wl1271_disable_interrupts(wl); 1463 wlcore_disable_interrupts(wl);
1855 mutex_lock(&wl->mutex); 1464 mutex_lock(&wl->mutex);
1856 if (wl->state == WL1271_STATE_OFF) { 1465 if (wl->state == WL1271_STATE_OFF) {
1857 mutex_unlock(&wl->mutex); 1466 mutex_unlock(&wl->mutex);
@@ -1861,7 +1470,7 @@ static void wl1271_op_stop(struct ieee80211_hw *hw)
1861 * may have been disabled when op_stop was called. It will, 1470 * may have been disabled when op_stop was called. It will,
1862 * however, balance the above call to disable_interrupts(). 1471 * however, balance the above call to disable_interrupts().
1863 */ 1472 */
1864 wl1271_enable_interrupts(wl); 1473 wlcore_enable_interrupts(wl);
1865 return; 1474 return;
1866 } 1475 }
1867 1476
@@ -1894,7 +1503,6 @@ static void wl1271_op_stop(struct ieee80211_hw *hw)
1894 wl->tx_results_count = 0; 1503 wl->tx_results_count = 0;
1895 wl->tx_packets_count = 0; 1504 wl->tx_packets_count = 0;
1896 wl->time_offset = 0; 1505 wl->time_offset = 0;
1897 wl->tx_spare_blocks = TX_HW_BLOCK_SPARE_DEFAULT;
1898 wl->ap_fw_ps_map = 0; 1506 wl->ap_fw_ps_map = 0;
1899 wl->ap_ps_map = 0; 1507 wl->ap_ps_map = 0;
1900 wl->sched_scanning = false; 1508 wl->sched_scanning = false;
@@ -2067,7 +1675,7 @@ static bool wl12xx_init_fw(struct wl1271 *wl)
2067 if (ret < 0) 1675 if (ret < 0)
2068 goto power_off; 1676 goto power_off;
2069 1677
2070 ret = wl1271_boot(wl); 1678 ret = wl->ops->boot(wl);
2071 if (ret < 0) 1679 if (ret < 0)
2072 goto power_off; 1680 goto power_off;
2073 1681
@@ -2087,7 +1695,7 @@ irq_disable:
2087 work function will not do anything.) Also, any other 1695 work function will not do anything.) Also, any other
2088 possible concurrent operations will fail due to the 1696 possible concurrent operations will fail due to the
2089 current state, hence the wl1271 struct should be safe. */ 1697 current state, hence the wl1271 struct should be safe. */
2090 wl1271_disable_interrupts(wl); 1698 wlcore_disable_interrupts(wl);
2091 wl1271_flush_deferred_work(wl); 1699 wl1271_flush_deferred_work(wl);
2092 cancel_work_sync(&wl->netstack_work); 1700 cancel_work_sync(&wl->netstack_work);
2093 mutex_lock(&wl->mutex); 1701 mutex_lock(&wl->mutex);
@@ -2360,10 +1968,12 @@ deinit:
2360 for (i = 0; i < CONF_TX_MAX_AC_COUNT; i++) 1968 for (i = 0; i < CONF_TX_MAX_AC_COUNT; i++)
2361 wl12xx_free_rate_policy(wl, 1969 wl12xx_free_rate_policy(wl,
2362 &wlvif->ap.ucast_rate_idx[i]); 1970 &wlvif->ap.ucast_rate_idx[i]);
1971 wl1271_free_ap_keys(wl, wlvif);
2363 } 1972 }
2364 1973
1974 dev_kfree_skb(wlvif->probereq);
1975 wlvif->probereq = NULL;
2365 wl12xx_tx_reset_wlvif(wl, wlvif); 1976 wl12xx_tx_reset_wlvif(wl, wlvif);
2366 wl1271_free_ap_keys(wl, wlvif);
2367 if (wl->last_wlvif == wlvif) 1977 if (wl->last_wlvif == wlvif)
2368 wl->last_wlvif = NULL; 1978 wl->last_wlvif = NULL;
2369 list_del(&wlvif->list); 1979 list_del(&wlvif->list);
@@ -2946,6 +2556,17 @@ static int wl1271_set_key(struct wl1271 *wl, struct wl12xx_vif *wlvif,
2946 int ret; 2556 int ret;
2947 bool is_ap = (wlvif->bss_type == BSS_TYPE_AP_BSS); 2557 bool is_ap = (wlvif->bss_type == BSS_TYPE_AP_BSS);
2948 2558
2559 /*
2560 * A role set to GEM cipher requires different Tx settings (namely
2561 * spare blocks). Note when we are in this mode so the HW can adjust.
2562 */
2563 if (key_type == KEY_GEM) {
2564 if (action == KEY_ADD_OR_REPLACE)
2565 wlvif->is_gem = true;
2566 else if (action == KEY_REMOVE)
2567 wlvif->is_gem = false;
2568 }
2569
2949 if (is_ap) { 2570 if (is_ap) {
2950 struct wl1271_station *wl_sta; 2571 struct wl1271_station *wl_sta;
2951 u8 hlid; 2572 u8 hlid;
@@ -2984,17 +2605,6 @@ static int wl1271_set_key(struct wl1271 *wl, struct wl12xx_vif *wlvif,
2984 0xff, 0xff, 0xff, 0xff, 0xff, 0xff 2605 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
2985 }; 2606 };
2986 2607
2987 /*
2988 * A STA set to GEM cipher requires 2 tx spare blocks.
2989 * Return to default value when GEM cipher key is removed
2990 */
2991 if (key_type == KEY_GEM) {
2992 if (action == KEY_ADD_OR_REPLACE)
2993 wl->tx_spare_blocks = 2;
2994 else if (action == KEY_REMOVE)
2995 wl->tx_spare_blocks = TX_HW_BLOCK_SPARE_DEFAULT;
2996 }
2997
2998 addr = sta ? sta->addr : bcast_addr; 2608 addr = sta ? sta->addr : bcast_addr;
2999 2609
3000 if (is_zero_ether_addr(addr)) { 2610 if (is_zero_ether_addr(addr)) {
@@ -3791,8 +3401,7 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
3791 wlvif->rssi_thold = bss_conf->cqm_rssi_thold; 3401 wlvif->rssi_thold = bss_conf->cqm_rssi_thold;
3792 } 3402 }
3793 3403
3794 if (changed & BSS_CHANGED_BSSID && 3404 if (changed & BSS_CHANGED_BSSID)
3795 (is_ibss || bss_conf->assoc))
3796 if (!is_zero_ether_addr(bss_conf->bssid)) { 3405 if (!is_zero_ether_addr(bss_conf->bssid)) {
3797 ret = wl12xx_cmd_build_null_data(wl, wlvif); 3406 ret = wl12xx_cmd_build_null_data(wl, wlvif);
3798 if (ret < 0) 3407 if (ret < 0)
@@ -3801,9 +3410,6 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
3801 ret = wl1271_build_qos_null_data(wl, vif); 3410 ret = wl1271_build_qos_null_data(wl, vif);
3802 if (ret < 0) 3411 if (ret < 0)
3803 goto out; 3412 goto out;
3804
3805 /* Need to update the BSSID (for filtering etc) */
3806 do_join = true;
3807 } 3413 }
3808 3414
3809 if (changed & (BSS_CHANGED_ASSOC | BSS_CHANGED_HT)) { 3415 if (changed & (BSS_CHANGED_ASSOC | BSS_CHANGED_HT)) {
@@ -3830,6 +3436,7 @@ sta_not_found:
3830 int ieoffset; 3436 int ieoffset;
3831 wlvif->aid = bss_conf->aid; 3437 wlvif->aid = bss_conf->aid;
3832 wlvif->beacon_int = bss_conf->beacon_int; 3438 wlvif->beacon_int = bss_conf->beacon_int;
3439 do_join = true;
3833 set_assoc = true; 3440 set_assoc = true;
3834 3441
3835 /* 3442 /*
@@ -4662,60 +4269,12 @@ static struct ieee80211_channel wl1271_channels[] = {
4662 { .hw_value = 14, .center_freq = 2484, .max_power = 25 }, 4269 { .hw_value = 14, .center_freq = 2484, .max_power = 25 },
4663}; 4270};
4664 4271
4665/* mapping to indexes for wl1271_rates */
4666static const u8 wl1271_rate_to_idx_2ghz[] = {
4667 /* MCS rates are used only with 11n */
4668 7, /* CONF_HW_RXTX_RATE_MCS7_SGI */
4669 7, /* CONF_HW_RXTX_RATE_MCS7 */
4670 6, /* CONF_HW_RXTX_RATE_MCS6 */
4671 5, /* CONF_HW_RXTX_RATE_MCS5 */
4672 4, /* CONF_HW_RXTX_RATE_MCS4 */
4673 3, /* CONF_HW_RXTX_RATE_MCS3 */
4674 2, /* CONF_HW_RXTX_RATE_MCS2 */
4675 1, /* CONF_HW_RXTX_RATE_MCS1 */
4676 0, /* CONF_HW_RXTX_RATE_MCS0 */
4677
4678 11, /* CONF_HW_RXTX_RATE_54 */
4679 10, /* CONF_HW_RXTX_RATE_48 */
4680 9, /* CONF_HW_RXTX_RATE_36 */
4681 8, /* CONF_HW_RXTX_RATE_24 */
4682
4683 /* TI-specific rate */
4684 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_22 */
4685
4686 7, /* CONF_HW_RXTX_RATE_18 */
4687 6, /* CONF_HW_RXTX_RATE_12 */
4688 3, /* CONF_HW_RXTX_RATE_11 */
4689 5, /* CONF_HW_RXTX_RATE_9 */
4690 4, /* CONF_HW_RXTX_RATE_6 */
4691 2, /* CONF_HW_RXTX_RATE_5_5 */
4692 1, /* CONF_HW_RXTX_RATE_2 */
4693 0 /* CONF_HW_RXTX_RATE_1 */
4694};
4695
4696/* 11n STA capabilities */
4697#define HW_RX_HIGHEST_RATE 72
4698
4699#define WL12XX_HT_CAP { \
4700 .cap = IEEE80211_HT_CAP_GRN_FLD | IEEE80211_HT_CAP_SGI_20 | \
4701 (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT), \
4702 .ht_supported = true, \
4703 .ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K, \
4704 .ampdu_density = IEEE80211_HT_MPDU_DENSITY_8, \
4705 .mcs = { \
4706 .rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, \
4707 .rx_highest = cpu_to_le16(HW_RX_HIGHEST_RATE), \
4708 .tx_params = IEEE80211_HT_MCS_TX_DEFINED, \
4709 }, \
4710}
4711
4712/* can't be const, mac80211 writes to this */ 4272/* can't be const, mac80211 writes to this */
4713static struct ieee80211_supported_band wl1271_band_2ghz = { 4273static struct ieee80211_supported_band wl1271_band_2ghz = {
4714 .channels = wl1271_channels, 4274 .channels = wl1271_channels,
4715 .n_channels = ARRAY_SIZE(wl1271_channels), 4275 .n_channels = ARRAY_SIZE(wl1271_channels),
4716 .bitrates = wl1271_rates, 4276 .bitrates = wl1271_rates,
4717 .n_bitrates = ARRAY_SIZE(wl1271_rates), 4277 .n_bitrates = ARRAY_SIZE(wl1271_rates),
4718 .ht_cap = WL12XX_HT_CAP,
4719}; 4278};
4720 4279
4721/* 5 GHz data rates for WL1273 */ 4280/* 5 GHz data rates for WL1273 */
@@ -4784,48 +4343,11 @@ static struct ieee80211_channel wl1271_channels_5ghz[] = {
4784 { .hw_value = 165, .center_freq = 5825, .max_power = 25 }, 4343 { .hw_value = 165, .center_freq = 5825, .max_power = 25 },
4785}; 4344};
4786 4345
4787/* mapping to indexes for wl1271_rates_5ghz */
4788static const u8 wl1271_rate_to_idx_5ghz[] = {
4789 /* MCS rates are used only with 11n */
4790 7, /* CONF_HW_RXTX_RATE_MCS7_SGI */
4791 7, /* CONF_HW_RXTX_RATE_MCS7 */
4792 6, /* CONF_HW_RXTX_RATE_MCS6 */
4793 5, /* CONF_HW_RXTX_RATE_MCS5 */
4794 4, /* CONF_HW_RXTX_RATE_MCS4 */
4795 3, /* CONF_HW_RXTX_RATE_MCS3 */
4796 2, /* CONF_HW_RXTX_RATE_MCS2 */
4797 1, /* CONF_HW_RXTX_RATE_MCS1 */
4798 0, /* CONF_HW_RXTX_RATE_MCS0 */
4799
4800 7, /* CONF_HW_RXTX_RATE_54 */
4801 6, /* CONF_HW_RXTX_RATE_48 */
4802 5, /* CONF_HW_RXTX_RATE_36 */
4803 4, /* CONF_HW_RXTX_RATE_24 */
4804
4805 /* TI-specific rate */
4806 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_22 */
4807
4808 3, /* CONF_HW_RXTX_RATE_18 */
4809 2, /* CONF_HW_RXTX_RATE_12 */
4810 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_11 */
4811 1, /* CONF_HW_RXTX_RATE_9 */
4812 0, /* CONF_HW_RXTX_RATE_6 */
4813 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_5_5 */
4814 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_2 */
4815 CONF_HW_RXTX_RATE_UNSUPPORTED /* CONF_HW_RXTX_RATE_1 */
4816};
4817
4818static struct ieee80211_supported_band wl1271_band_5ghz = { 4346static struct ieee80211_supported_band wl1271_band_5ghz = {
4819 .channels = wl1271_channels_5ghz, 4347 .channels = wl1271_channels_5ghz,
4820 .n_channels = ARRAY_SIZE(wl1271_channels_5ghz), 4348 .n_channels = ARRAY_SIZE(wl1271_channels_5ghz),
4821 .bitrates = wl1271_rates_5ghz, 4349 .bitrates = wl1271_rates_5ghz,
4822 .n_bitrates = ARRAY_SIZE(wl1271_rates_5ghz), 4350 .n_bitrates = ARRAY_SIZE(wl1271_rates_5ghz),
4823 .ht_cap = WL12XX_HT_CAP,
4824};
4825
4826static const u8 *wl1271_band_rate_to_idx[] = {
4827 [IEEE80211_BAND_2GHZ] = wl1271_rate_to_idx_2ghz,
4828 [IEEE80211_BAND_5GHZ] = wl1271_rate_to_idx_5ghz
4829}; 4351};
4830 4352
4831static const struct ieee80211_ops wl1271_ops = { 4353static const struct ieee80211_ops wl1271_ops = {
@@ -4862,18 +4384,18 @@ static const struct ieee80211_ops wl1271_ops = {
4862}; 4384};
4863 4385
4864 4386
4865u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band) 4387u8 wlcore_rate_to_idx(struct wl1271 *wl, u8 rate, enum ieee80211_band band)
4866{ 4388{
4867 u8 idx; 4389 u8 idx;
4868 4390
4869 BUG_ON(band >= sizeof(wl1271_band_rate_to_idx)/sizeof(u8 *)); 4391 BUG_ON(band >= 2);
4870 4392
4871 if (unlikely(rate >= CONF_HW_RXTX_RATE_MAX)) { 4393 if (unlikely(rate >= wl->hw_tx_rate_tbl_size)) {
4872 wl1271_error("Illegal RX rate from HW: %d", rate); 4394 wl1271_error("Illegal RX rate from HW: %d", rate);
4873 return 0; 4395 return 0;
4874 } 4396 }
4875 4397
4876 idx = wl1271_band_rate_to_idx[band][rate]; 4398 idx = wl->band_rate_to_idx[band][rate];
4877 if (unlikely(idx == CONF_HW_RXTX_RATE_UNSUPPORTED)) { 4399 if (unlikely(idx == CONF_HW_RXTX_RATE_UNSUPPORTED)) {
4878 wl1271_error("Unsupported RX rate from HW: %d", rate); 4400 wl1271_error("Unsupported RX rate from HW: %d", rate);
4879 return 0; 4401 return 0;
@@ -5027,34 +4549,6 @@ static struct bin_attribute fwlog_attr = {
5027 .read = wl1271_sysfs_read_fwlog, 4549 .read = wl1271_sysfs_read_fwlog,
5028}; 4550};
5029 4551
5030static bool wl12xx_mac_in_fuse(struct wl1271 *wl)
5031{
5032 bool supported = false;
5033 u8 major, minor;
5034
5035 if (wl->chip.id == CHIP_ID_1283_PG20) {
5036 major = WL128X_PG_GET_MAJOR(wl->hw_pg_ver);
5037 minor = WL128X_PG_GET_MINOR(wl->hw_pg_ver);
5038
5039 /* in wl128x we have the MAC address if the PG is >= (2, 1) */
5040 if (major > 2 || (major == 2 && minor >= 1))
5041 supported = true;
5042 } else {
5043 major = WL127X_PG_GET_MAJOR(wl->hw_pg_ver);
5044 minor = WL127X_PG_GET_MINOR(wl->hw_pg_ver);
5045
5046 /* in wl127x we have the MAC address if the PG is >= (3, 1) */
5047 if (major == 3 && minor >= 1)
5048 supported = true;
5049 }
5050
5051 wl1271_debug(DEBUG_PROBE,
5052 "PG Ver major = %d minor = %d, MAC %s present",
5053 major, minor, supported ? "is" : "is not");
5054
5055 return supported;
5056}
5057
5058static void wl12xx_derive_mac_addresses(struct wl1271 *wl, 4552static void wl12xx_derive_mac_addresses(struct wl1271 *wl,
5059 u32 oui, u32 nic, int n) 4553 u32 oui, u32 nic, int n)
5060{ 4554{
@@ -5080,47 +4574,23 @@ static void wl12xx_derive_mac_addresses(struct wl1271 *wl,
5080 wl->hw->wiphy->addresses = wl->addresses; 4574 wl->hw->wiphy->addresses = wl->addresses;
5081} 4575}
5082 4576
5083static void wl12xx_get_fuse_mac(struct wl1271 *wl)
5084{
5085 u32 mac1, mac2;
5086
5087 wl1271_set_partition(wl, &wl12xx_part_table[PART_DRPW]);
5088
5089 mac1 = wl1271_read32(wl, WL12XX_REG_FUSE_BD_ADDR_1);
5090 mac2 = wl1271_read32(wl, WL12XX_REG_FUSE_BD_ADDR_2);
5091
5092 /* these are the two parts of the BD_ADDR */
5093 wl->fuse_oui_addr = ((mac2 & 0xffff) << 8) +
5094 ((mac1 & 0xff000000) >> 24);
5095 wl->fuse_nic_addr = mac1 & 0xffffff;
5096
5097 wl1271_set_partition(wl, &wl12xx_part_table[PART_DOWN]);
5098}
5099
5100static int wl12xx_get_hw_info(struct wl1271 *wl) 4577static int wl12xx_get_hw_info(struct wl1271 *wl)
5101{ 4578{
5102 int ret; 4579 int ret;
5103 u32 die_info;
5104 4580
5105 ret = wl12xx_set_power_on(wl); 4581 ret = wl12xx_set_power_on(wl);
5106 if (ret < 0) 4582 if (ret < 0)
5107 goto out; 4583 goto out;
5108 4584
5109 wl->chip.id = wl1271_read32(wl, CHIP_ID_B); 4585 wl->chip.id = wlcore_read_reg(wl, REG_CHIP_ID_B);
5110 4586
5111 if (wl->chip.id == CHIP_ID_1283_PG20) 4587 wl->fuse_oui_addr = 0;
5112 die_info = wl1271_top_reg_read(wl, WL128X_REG_FUSE_DATA_2_1); 4588 wl->fuse_nic_addr = 0;
5113 else
5114 die_info = wl1271_top_reg_read(wl, WL127X_REG_FUSE_DATA_2_1);
5115 4589
5116 wl->hw_pg_ver = (s8) (die_info & PG_VER_MASK) >> PG_VER_OFFSET; 4590 wl->hw_pg_ver = wl->ops->get_pg_ver(wl);
5117 4591
5118 if (!wl12xx_mac_in_fuse(wl)) { 4592 if (wl->ops->get_mac)
5119 wl->fuse_oui_addr = 0; 4593 wl->ops->get_mac(wl);
5120 wl->fuse_nic_addr = 0;
5121 } else {
5122 wl12xx_get_fuse_mac(wl);
5123 }
5124 4594
5125 wl1271_power_off(wl); 4595 wl1271_power_off(wl);
5126out: 4596out:
@@ -5255,8 +4725,12 @@ static int wl1271_init_ieee80211(struct wl1271 *wl)
5255 */ 4725 */
5256 memcpy(&wl->bands[IEEE80211_BAND_2GHZ], &wl1271_band_2ghz, 4726 memcpy(&wl->bands[IEEE80211_BAND_2GHZ], &wl1271_band_2ghz,
5257 sizeof(wl1271_band_2ghz)); 4727 sizeof(wl1271_band_2ghz));
4728 memcpy(&wl->bands[IEEE80211_BAND_2GHZ].ht_cap, &wl->ht_cap,
4729 sizeof(wl->ht_cap));
5258 memcpy(&wl->bands[IEEE80211_BAND_5GHZ], &wl1271_band_5ghz, 4730 memcpy(&wl->bands[IEEE80211_BAND_5GHZ], &wl1271_band_5ghz,
5259 sizeof(wl1271_band_5ghz)); 4731 sizeof(wl1271_band_5ghz));
4732 memcpy(&wl->bands[IEEE80211_BAND_5GHZ].ht_cap, &wl->ht_cap,
4733 sizeof(wl->ht_cap));
5260 4734
5261 wl->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = 4735 wl->hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
5262 &wl->bands[IEEE80211_BAND_2GHZ]; 4736 &wl->bands[IEEE80211_BAND_2GHZ];
@@ -5280,14 +4754,14 @@ static int wl1271_init_ieee80211(struct wl1271 *wl)
5280 wl->hw->sta_data_size = sizeof(struct wl1271_station); 4754 wl->hw->sta_data_size = sizeof(struct wl1271_station);
5281 wl->hw->vif_data_size = sizeof(struct wl12xx_vif); 4755 wl->hw->vif_data_size = sizeof(struct wl12xx_vif);
5282 4756
5283 wl->hw->max_rx_aggregation_subframes = 8; 4757 wl->hw->max_rx_aggregation_subframes = wl->conf.ht.rx_ba_win_size;
5284 4758
5285 return 0; 4759 return 0;
5286} 4760}
5287 4761
5288#define WL1271_DEFAULT_CHANNEL 0 4762#define WL1271_DEFAULT_CHANNEL 0
5289 4763
5290static struct ieee80211_hw *wl1271_alloc_hw(void) 4764struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size)
5291{ 4765{
5292 struct ieee80211_hw *hw; 4766 struct ieee80211_hw *hw;
5293 struct wl1271 *wl; 4767 struct wl1271 *wl;
@@ -5306,6 +4780,13 @@ static struct ieee80211_hw *wl1271_alloc_hw(void)
5306 wl = hw->priv; 4780 wl = hw->priv;
5307 memset(wl, 0, sizeof(*wl)); 4781 memset(wl, 0, sizeof(*wl));
5308 4782
4783 wl->priv = kzalloc(priv_size, GFP_KERNEL);
4784 if (!wl->priv) {
4785 wl1271_error("could not alloc wl priv");
4786 ret = -ENOMEM;
4787 goto err_priv_alloc;
4788 }
4789
5309 INIT_LIST_HEAD(&wl->wlvif_list); 4790 INIT_LIST_HEAD(&wl->wlvif_list);
5310 4791
5311 wl->hw = hw; 4792 wl->hw = hw;
@@ -5342,7 +4823,6 @@ static struct ieee80211_hw *wl1271_alloc_hw(void)
5342 wl->quirks = 0; 4823 wl->quirks = 0;
5343 wl->platform_quirks = 0; 4824 wl->platform_quirks = 0;
5344 wl->sched_scanning = false; 4825 wl->sched_scanning = false;
5345 wl->tx_spare_blocks = TX_HW_BLOCK_SPARE_DEFAULT;
5346 wl->system_hlid = WL12XX_SYSTEM_HLID; 4826 wl->system_hlid = WL12XX_SYSTEM_HLID;
5347 wl->active_sta_count = 0; 4827 wl->active_sta_count = 0;
5348 wl->fwlog_size = 0; 4828 wl->fwlog_size = 0;
@@ -5352,7 +4832,7 @@ static struct ieee80211_hw *wl1271_alloc_hw(void)
5352 __set_bit(WL12XX_SYSTEM_HLID, wl->links_map); 4832 __set_bit(WL12XX_SYSTEM_HLID, wl->links_map);
5353 4833
5354 memset(wl->tx_frames_map, 0, sizeof(wl->tx_frames_map)); 4834 memset(wl->tx_frames_map, 0, sizeof(wl->tx_frames_map));
5355 for (i = 0; i < ACX_TX_DESCRIPTORS; i++) 4835 for (i = 0; i < wl->num_tx_desc; i++)
5356 wl->tx_frames[i] = NULL; 4836 wl->tx_frames[i] = NULL;
5357 4837
5358 spin_lock_init(&wl->wl_lock); 4838 spin_lock_init(&wl->wl_lock);
@@ -5361,9 +4841,6 @@ static struct ieee80211_hw *wl1271_alloc_hw(void)
5361 wl->fw_type = WL12XX_FW_TYPE_NONE; 4841 wl->fw_type = WL12XX_FW_TYPE_NONE;
5362 mutex_init(&wl->mutex); 4842 mutex_init(&wl->mutex);
5363 4843
5364 /* Apply default driver configuration. */
5365 wl1271_conf_init(wl);
5366
5367 order = get_order(WL1271_AGGR_BUFFER_SIZE); 4844 order = get_order(WL1271_AGGR_BUFFER_SIZE);
5368 wl->aggr_buf = (u8 *)__get_free_pages(GFP_KERNEL, order); 4845 wl->aggr_buf = (u8 *)__get_free_pages(GFP_KERNEL, order);
5369 if (!wl->aggr_buf) { 4846 if (!wl->aggr_buf) {
@@ -5384,8 +4861,17 @@ static struct ieee80211_hw *wl1271_alloc_hw(void)
5384 goto err_dummy_packet; 4861 goto err_dummy_packet;
5385 } 4862 }
5386 4863
4864 wl->mbox = kmalloc(sizeof(*wl->mbox), GFP_DMA);
4865 if (!wl->mbox) {
4866 ret = -ENOMEM;
4867 goto err_fwlog;
4868 }
4869
5387 return hw; 4870 return hw;
5388 4871
4872err_fwlog:
4873 free_page((unsigned long)wl->fwlog);
4874
5389err_dummy_packet: 4875err_dummy_packet:
5390 dev_kfree_skb(wl->dummy_packet); 4876 dev_kfree_skb(wl->dummy_packet);
5391 4877
@@ -5397,14 +4883,18 @@ err_wq:
5397 4883
5398err_hw: 4884err_hw:
5399 wl1271_debugfs_exit(wl); 4885 wl1271_debugfs_exit(wl);
4886 kfree(wl->priv);
4887
4888err_priv_alloc:
5400 ieee80211_free_hw(hw); 4889 ieee80211_free_hw(hw);
5401 4890
5402err_hw_alloc: 4891err_hw_alloc:
5403 4892
5404 return ERR_PTR(ret); 4893 return ERR_PTR(ret);
5405} 4894}
4895EXPORT_SYMBOL_GPL(wlcore_alloc_hw);
5406 4896
5407static int wl1271_free_hw(struct wl1271 *wl) 4897int wlcore_free_hw(struct wl1271 *wl)
5408{ 4898{
5409 /* Unblock any fwlog readers */ 4899 /* Unblock any fwlog readers */
5410 mutex_lock(&wl->mutex); 4900 mutex_lock(&wl->mutex);
@@ -5434,10 +4924,12 @@ static int wl1271_free_hw(struct wl1271 *wl)
5434 kfree(wl->tx_res_if); 4924 kfree(wl->tx_res_if);
5435 destroy_workqueue(wl->freezable_wq); 4925 destroy_workqueue(wl->freezable_wq);
5436 4926
4927 kfree(wl->priv);
5437 ieee80211_free_hw(wl->hw); 4928 ieee80211_free_hw(wl->hw);
5438 4929
5439 return 0; 4930 return 0;
5440} 4931}
4932EXPORT_SYMBOL_GPL(wlcore_free_hw);
5441 4933
5442static irqreturn_t wl12xx_hardirq(int irq, void *cookie) 4934static irqreturn_t wl12xx_hardirq(int irq, void *cookie)
5443{ 4935{
@@ -5468,22 +4960,22 @@ static irqreturn_t wl12xx_hardirq(int irq, void *cookie)
5468 return IRQ_WAKE_THREAD; 4960 return IRQ_WAKE_THREAD;
5469} 4961}
5470 4962
5471static int __devinit wl12xx_probe(struct platform_device *pdev) 4963int __devinit wlcore_probe(struct wl1271 *wl, struct platform_device *pdev)
5472{ 4964{
5473 struct wl12xx_platform_data *pdata = pdev->dev.platform_data; 4965 struct wl12xx_platform_data *pdata = pdev->dev.platform_data;
5474 struct ieee80211_hw *hw;
5475 struct wl1271 *wl;
5476 unsigned long irqflags; 4966 unsigned long irqflags;
5477 int ret = -ENODEV; 4967 int ret;
5478 4968
5479 hw = wl1271_alloc_hw(); 4969 if (!wl->ops || !wl->ptable) {
5480 if (IS_ERR(hw)) { 4970 ret = -EINVAL;
5481 wl1271_error("can't allocate hw"); 4971 goto out_free_hw;
5482 ret = PTR_ERR(hw);
5483 goto out;
5484 } 4972 }
5485 4973
5486 wl = hw->priv; 4974 BUG_ON(wl->num_tx_desc > WLCORE_MAX_TX_DESCRIPTORS);
4975
4976 /* adjust some runtime configuration parameters */
4977 wlcore_adjust_conf(wl);
4978
5487 wl->irq = platform_get_irq(pdev, 0); 4979 wl->irq = platform_get_irq(pdev, 0);
5488 wl->ref_clock = pdata->board_ref_clock; 4980 wl->ref_clock = pdata->board_ref_clock;
5489 wl->tcxo_clock = pdata->board_tcxo_clock; 4981 wl->tcxo_clock = pdata->board_tcxo_clock;
@@ -5512,7 +5004,7 @@ static int __devinit wl12xx_probe(struct platform_device *pdev)
5512 wl->irq_wake_enabled = true; 5004 wl->irq_wake_enabled = true;
5513 device_init_wakeup(wl->dev, 1); 5005 device_init_wakeup(wl->dev, 1);
5514 if (pdata->pwr_in_suspend) 5006 if (pdata->pwr_in_suspend)
5515 hw->wiphy->wowlan.flags = WIPHY_WOWLAN_ANY; 5007 wl->hw->wiphy->wowlan.flags = WIPHY_WOWLAN_ANY;
5516 5008
5517 } 5009 }
5518 disable_irq(wl->irq); 5010 disable_irq(wl->irq);
@@ -5546,7 +5038,7 @@ static int __devinit wl12xx_probe(struct platform_device *pdev)
5546 goto out_hw_pg_ver; 5038 goto out_hw_pg_ver;
5547 } 5039 }
5548 5040
5549 return 0; 5041 goto out;
5550 5042
5551out_hw_pg_ver: 5043out_hw_pg_ver:
5552 device_remove_file(wl->dev, &dev_attr_hw_pg_ver); 5044 device_remove_file(wl->dev, &dev_attr_hw_pg_ver);
@@ -5558,13 +5050,14 @@ out_irq:
5558 free_irq(wl->irq, wl); 5050 free_irq(wl->irq, wl);
5559 5051
5560out_free_hw: 5052out_free_hw:
5561 wl1271_free_hw(wl); 5053 wlcore_free_hw(wl);
5562 5054
5563out: 5055out:
5564 return ret; 5056 return ret;
5565} 5057}
5058EXPORT_SYMBOL_GPL(wlcore_probe);
5566 5059
5567static int __devexit wl12xx_remove(struct platform_device *pdev) 5060int __devexit wlcore_remove(struct platform_device *pdev)
5568{ 5061{
5569 struct wl1271 *wl = platform_get_drvdata(pdev); 5062 struct wl1271 *wl = platform_get_drvdata(pdev);
5570 5063
@@ -5574,38 +5067,11 @@ static int __devexit wl12xx_remove(struct platform_device *pdev)
5574 } 5067 }
5575 wl1271_unregister_hw(wl); 5068 wl1271_unregister_hw(wl);
5576 free_irq(wl->irq, wl); 5069 free_irq(wl->irq, wl);
5577 wl1271_free_hw(wl); 5070 wlcore_free_hw(wl);
5578 5071
5579 return 0; 5072 return 0;
5580} 5073}
5581 5074EXPORT_SYMBOL_GPL(wlcore_remove);
5582static const struct platform_device_id wl12xx_id_table[] __devinitconst = {
5583 { "wl12xx", 0 },
5584 { } /* Terminating Entry */
5585};
5586MODULE_DEVICE_TABLE(platform, wl12xx_id_table);
5587
5588static struct platform_driver wl12xx_driver = {
5589 .probe = wl12xx_probe,
5590 .remove = __devexit_p(wl12xx_remove),
5591 .id_table = wl12xx_id_table,
5592 .driver = {
5593 .name = "wl12xx_driver",
5594 .owner = THIS_MODULE,
5595 }
5596};
5597
5598static int __init wl12xx_init(void)
5599{
5600 return platform_driver_register(&wl12xx_driver);
5601}
5602module_init(wl12xx_init);
5603
5604static void __exit wl12xx_exit(void)
5605{
5606 platform_driver_unregister(&wl12xx_driver);
5607}
5608module_exit(wl12xx_exit);
5609 5075
5610u32 wl12xx_debug_level = DEBUG_NONE; 5076u32 wl12xx_debug_level = DEBUG_NONE;
5611EXPORT_SYMBOL_GPL(wl12xx_debug_level); 5077EXPORT_SYMBOL_GPL(wl12xx_debug_level);
@@ -5619,6 +5085,9 @@ MODULE_PARM_DESC(fwlog,
5619module_param(bug_on_recovery, bool, S_IRUSR | S_IWUSR); 5085module_param(bug_on_recovery, bool, S_IRUSR | S_IWUSR);
5620MODULE_PARM_DESC(bug_on_recovery, "BUG() on fw recovery"); 5086MODULE_PARM_DESC(bug_on_recovery, "BUG() on fw recovery");
5621 5087
5088module_param(no_recovery, bool, S_IRUSR | S_IWUSR);
5089MODULE_PARM_DESC(no_recovery, "Prevent HW recovery. FW will remain stuck.");
5090
5622MODULE_LICENSE("GPL"); 5091MODULE_LICENSE("GPL");
5623MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>"); 5092MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>");
5624MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>"); 5093MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>");
diff --git a/drivers/net/wireless/wl12xx/ps.c b/drivers/net/wireless/ti/wlcore/ps.c
index 78f598b4f97b..756eee2257b4 100644
--- a/drivers/net/wireless/wl12xx/ps.c
+++ b/drivers/net/wireless/ti/wlcore/ps.c
@@ -21,7 +21,6 @@
21 * 21 *
22 */ 22 */
23 23
24#include "reg.h"
25#include "ps.h" 24#include "ps.h"
26#include "io.h" 25#include "io.h"
27#include "tx.h" 26#include "tx.h"
@@ -62,7 +61,7 @@ void wl1271_elp_work(struct work_struct *work)
62 } 61 }
63 62
64 wl1271_debug(DEBUG_PSM, "chip to elp"); 63 wl1271_debug(DEBUG_PSM, "chip to elp");
65 wl1271_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_SLEEP); 64 wl1271_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG, ELPCTRL_SLEEP);
66 set_bit(WL1271_FLAG_IN_ELP, &wl->flags); 65 set_bit(WL1271_FLAG_IN_ELP, &wl->flags);
67 66
68out: 67out:
@@ -74,6 +73,9 @@ void wl1271_ps_elp_sleep(struct wl1271 *wl)
74{ 73{
75 struct wl12xx_vif *wlvif; 74 struct wl12xx_vif *wlvif;
76 75
76 if (wl->quirks & WLCORE_QUIRK_NO_ELP)
77 return;
78
77 /* we shouldn't get consecutive sleep requests */ 79 /* we shouldn't get consecutive sleep requests */
78 if (WARN_ON(test_and_set_bit(WL1271_FLAG_ELP_REQUESTED, &wl->flags))) 80 if (WARN_ON(test_and_set_bit(WL1271_FLAG_ELP_REQUESTED, &wl->flags)))
79 return; 81 return;
@@ -125,7 +127,7 @@ int wl1271_ps_elp_wakeup(struct wl1271 *wl)
125 wl->elp_compl = &compl; 127 wl->elp_compl = &compl;
126 spin_unlock_irqrestore(&wl->wl_lock, flags); 128 spin_unlock_irqrestore(&wl->wl_lock, flags);
127 129
128 wl1271_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_WAKE_UP); 130 wl1271_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG, ELPCTRL_WAKE_UP);
129 131
130 if (!pending) { 132 if (!pending) {
131 ret = wait_for_completion_timeout( 133 ret = wait_for_completion_timeout(
diff --git a/drivers/net/wireless/wl12xx/ps.h b/drivers/net/wireless/ti/wlcore/ps.h
index 5f19d4fbbf27..de4f9da8ed26 100644
--- a/drivers/net/wireless/wl12xx/ps.h
+++ b/drivers/net/wireless/ti/wlcore/ps.h
@@ -24,7 +24,7 @@
24#ifndef __PS_H__ 24#ifndef __PS_H__
25#define __PS_H__ 25#define __PS_H__
26 26
27#include "wl12xx.h" 27#include "wlcore.h"
28#include "acx.h" 28#include "acx.h"
29 29
30int wl1271_ps_set_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif, 30int wl1271_ps_set_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif,
diff --git a/drivers/net/wireless/wl12xx/rx.c b/drivers/net/wireless/ti/wlcore/rx.c
index cfa6071704c5..89bd9385e90b 100644
--- a/drivers/net/wireless/wl12xx/rx.c
+++ b/drivers/net/wireless/ti/wlcore/rx.c
@@ -24,34 +24,36 @@
24#include <linux/gfp.h> 24#include <linux/gfp.h>
25#include <linux/sched.h> 25#include <linux/sched.h>
26 26
27#include "wl12xx.h" 27#include "wlcore.h"
28#include "debug.h" 28#include "debug.h"
29#include "acx.h" 29#include "acx.h"
30#include "reg.h"
31#include "rx.h" 30#include "rx.h"
32#include "tx.h" 31#include "tx.h"
33#include "io.h" 32#include "io.h"
33#include "hw_ops.h"
34 34
35static u8 wl12xx_rx_get_mem_block(struct wl12xx_fw_status *status, 35/*
36 u32 drv_rx_counter) 36 * TODO: this is here just for now, it must be removed when the data
37{ 37 * operations are in place.
38 return le32_to_cpu(status->rx_pkt_descs[drv_rx_counter]) & 38 */
39 RX_MEM_BLOCK_MASK; 39#include "../wl12xx/reg.h"
40}
41 40
42static u32 wl12xx_rx_get_buf_size(struct wl12xx_fw_status *status, 41static u32 wlcore_rx_get_buf_size(struct wl1271 *wl,
43 u32 drv_rx_counter) 42 u32 rx_pkt_desc)
44{ 43{
45 return (le32_to_cpu(status->rx_pkt_descs[drv_rx_counter]) & 44 if (wl->quirks & WLCORE_QUIRK_RX_BLOCKSIZE_ALIGN)
46 RX_BUF_SIZE_MASK) >> RX_BUF_SIZE_SHIFT_DIV; 45 return (rx_pkt_desc & ALIGNED_RX_BUF_SIZE_MASK) >>
46 ALIGNED_RX_BUF_SIZE_SHIFT;
47
48 return (rx_pkt_desc & RX_BUF_SIZE_MASK) >> RX_BUF_SIZE_SHIFT_DIV;
47} 49}
48 50
49static bool wl12xx_rx_get_unaligned(struct wl12xx_fw_status *status, 51static u32 wlcore_rx_get_align_buf_size(struct wl1271 *wl, u32 pkt_len)
50 u32 drv_rx_counter)
51{ 52{
52 /* Convert the value to bool */ 53 if (wl->quirks & WLCORE_QUIRK_RX_BLOCKSIZE_ALIGN)
53 return !!(le32_to_cpu(status->rx_pkt_descs[drv_rx_counter]) & 54 return ALIGN(pkt_len, WL12XX_BUS_BLOCK_SIZE);
54 RX_BUF_UNALIGNED_PAYLOAD); 55
56 return pkt_len;
55} 57}
56 58
57static void wl1271_rx_status(struct wl1271 *wl, 59static void wl1271_rx_status(struct wl1271 *wl,
@@ -66,10 +68,10 @@ static void wl1271_rx_status(struct wl1271 *wl,
66 else 68 else
67 status->band = IEEE80211_BAND_5GHZ; 69 status->band = IEEE80211_BAND_5GHZ;
68 70
69 status->rate_idx = wl1271_rate_to_idx(desc->rate, status->band); 71 status->rate_idx = wlcore_rate_to_idx(wl, desc->rate, status->band);
70 72
71 /* 11n support */ 73 /* 11n support */
72 if (desc->rate <= CONF_HW_RXTX_RATE_MCS0) 74 if (desc->rate <= wl->hw_min_ht_rate)
73 status->flag |= RX_FLAG_HT; 75 status->flag |= RX_FLAG_HT;
74 76
75 status->signal = desc->rssi; 77 status->signal = desc->rssi;
@@ -98,7 +100,7 @@ static void wl1271_rx_status(struct wl1271 *wl,
98} 100}
99 101
100static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length, 102static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length,
101 bool unaligned, u8 *hlid) 103 enum wl_rx_buf_align rx_align, u8 *hlid)
102{ 104{
103 struct wl1271_rx_descriptor *desc; 105 struct wl1271_rx_descriptor *desc;
104 struct sk_buff *skb; 106 struct sk_buff *skb;
@@ -106,8 +108,9 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length,
106 u8 *buf; 108 u8 *buf;
107 u8 beacon = 0; 109 u8 beacon = 0;
108 u8 is_data = 0; 110 u8 is_data = 0;
109 u8 reserved = unaligned ? NET_IP_ALIGN : 0; 111 u8 reserved = 0;
110 u16 seq_num; 112 u16 seq_num;
113 u32 pkt_data_len;
111 114
112 /* 115 /*
113 * In PLT mode we seem to get frames and mac80211 warns about them, 116 * In PLT mode we seem to get frames and mac80211 warns about them,
@@ -116,6 +119,16 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length,
116 if (unlikely(wl->plt)) 119 if (unlikely(wl->plt))
117 return -EINVAL; 120 return -EINVAL;
118 121
122 pkt_data_len = wlcore_hw_get_rx_packet_len(wl, data, length);
123 if (!pkt_data_len) {
124 wl1271_error("Invalid packet arrived from HW. length %d",
125 length);
126 return -EINVAL;
127 }
128
129 if (rx_align == WLCORE_RX_BUF_UNALIGNED)
130 reserved = NET_IP_ALIGN;
131
119 /* the data read starts with the descriptor */ 132 /* the data read starts with the descriptor */
120 desc = (struct wl1271_rx_descriptor *) data; 133 desc = (struct wl1271_rx_descriptor *) data;
121 134
@@ -142,8 +155,8 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length,
142 return -EINVAL; 155 return -EINVAL;
143 } 156 }
144 157
145 /* skb length not included rx descriptor */ 158 /* skb length not including rx descriptor */
146 skb = __dev_alloc_skb(length + reserved - sizeof(*desc), GFP_KERNEL); 159 skb = __dev_alloc_skb(pkt_data_len + reserved, GFP_KERNEL);
147 if (!skb) { 160 if (!skb) {
148 wl1271_error("Couldn't allocate RX frame"); 161 wl1271_error("Couldn't allocate RX frame");
149 return -ENOMEM; 162 return -ENOMEM;
@@ -152,7 +165,7 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length,
152 /* reserve the unaligned payload(if any) */ 165 /* reserve the unaligned payload(if any) */
153 skb_reserve(skb, reserved); 166 skb_reserve(skb, reserved);
154 167
155 buf = skb_put(skb, length - sizeof(*desc)); 168 buf = skb_put(skb, pkt_data_len);
156 169
157 /* 170 /*
158 * Copy packets from aggregation buffer to the skbs without rx 171 * Copy packets from aggregation buffer to the skbs without rx
@@ -160,7 +173,10 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length,
160 * packets copy the packets in offset of 2 bytes guarantee IP header 173 * packets copy the packets in offset of 2 bytes guarantee IP header
161 * payload aligned to 4 bytes. 174 * payload aligned to 4 bytes.
162 */ 175 */
163 memcpy(buf, data + sizeof(*desc), length - sizeof(*desc)); 176 memcpy(buf, data + sizeof(*desc), pkt_data_len);
177 if (rx_align == WLCORE_RX_BUF_PADDED)
178 skb_pull(skb, NET_IP_ALIGN);
179
164 *hlid = desc->hlid; 180 *hlid = desc->hlid;
165 181
166 hdr = (struct ieee80211_hdr *)skb->data; 182 hdr = (struct ieee80211_hdr *)skb->data;
@@ -177,36 +193,35 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length,
177 beacon ? "beacon" : "", 193 beacon ? "beacon" : "",
178 seq_num, *hlid); 194 seq_num, *hlid);
179 195
180 skb_trim(skb, skb->len - desc->pad_len);
181
182 skb_queue_tail(&wl->deferred_rx_queue, skb); 196 skb_queue_tail(&wl->deferred_rx_queue, skb);
183 queue_work(wl->freezable_wq, &wl->netstack_work); 197 queue_work(wl->freezable_wq, &wl->netstack_work);
184 198
185 return is_data; 199 return is_data;
186} 200}
187 201
188void wl12xx_rx(struct wl1271 *wl, struct wl12xx_fw_status *status) 202void wl12xx_rx(struct wl1271 *wl, struct wl_fw_status *status)
189{ 203{
190 struct wl1271_acx_mem_map *wl_mem_map = wl->target_mem_map;
191 unsigned long active_hlids[BITS_TO_LONGS(WL12XX_MAX_LINKS)] = {0}; 204 unsigned long active_hlids[BITS_TO_LONGS(WL12XX_MAX_LINKS)] = {0};
192 u32 buf_size; 205 u32 buf_size;
193 u32 fw_rx_counter = status->fw_rx_counter & NUM_RX_PKT_DESC_MOD_MASK; 206 u32 fw_rx_counter = status->fw_rx_counter & NUM_RX_PKT_DESC_MOD_MASK;
194 u32 drv_rx_counter = wl->rx_counter & NUM_RX_PKT_DESC_MOD_MASK; 207 u32 drv_rx_counter = wl->rx_counter & NUM_RX_PKT_DESC_MOD_MASK;
195 u32 rx_counter; 208 u32 rx_counter;
196 u32 mem_block; 209 u32 pkt_len, align_pkt_len;
197 u32 pkt_length; 210 u32 pkt_offset, des;
198 u32 pkt_offset;
199 u8 hlid; 211 u8 hlid;
200 bool unaligned = false; 212 enum wl_rx_buf_align rx_align;
201 213
202 while (drv_rx_counter != fw_rx_counter) { 214 while (drv_rx_counter != fw_rx_counter) {
203 buf_size = 0; 215 buf_size = 0;
204 rx_counter = drv_rx_counter; 216 rx_counter = drv_rx_counter;
205 while (rx_counter != fw_rx_counter) { 217 while (rx_counter != fw_rx_counter) {
206 pkt_length = wl12xx_rx_get_buf_size(status, rx_counter); 218 des = le32_to_cpu(status->rx_pkt_descs[rx_counter]);
207 if (buf_size + pkt_length > WL1271_AGGR_BUFFER_SIZE) 219 pkt_len = wlcore_rx_get_buf_size(wl, des);
220 align_pkt_len = wlcore_rx_get_align_buf_size(wl,
221 pkt_len);
222 if (buf_size + align_pkt_len > WL1271_AGGR_BUFFER_SIZE)
208 break; 223 break;
209 buf_size += pkt_length; 224 buf_size += align_pkt_len;
210 rx_counter++; 225 rx_counter++;
211 rx_counter &= NUM_RX_PKT_DESC_MOD_MASK; 226 rx_counter &= NUM_RX_PKT_DESC_MOD_MASK;
212 } 227 }
@@ -216,38 +231,18 @@ void wl12xx_rx(struct wl1271 *wl, struct wl12xx_fw_status *status)
216 break; 231 break;
217 } 232 }
218 233
219 if (wl->chip.id != CHIP_ID_1283_PG20) {
220 /*
221 * Choose the block we want to read
222 * For aggregated packets, only the first memory block
223 * should be retrieved. The FW takes care of the rest.
224 */
225 mem_block = wl12xx_rx_get_mem_block(status,
226 drv_rx_counter);
227
228 wl->rx_mem_pool_addr.addr = (mem_block << 8) +
229 le32_to_cpu(wl_mem_map->packet_memory_pool_start);
230
231 wl->rx_mem_pool_addr.addr_extra =
232 wl->rx_mem_pool_addr.addr + 4;
233
234 wl1271_write(wl, WL1271_SLV_REG_DATA,
235 &wl->rx_mem_pool_addr,
236 sizeof(wl->rx_mem_pool_addr), false);
237 }
238
239 /* Read all available packets at once */ 234 /* Read all available packets at once */
240 wl1271_read(wl, WL1271_SLV_MEM_DATA, wl->aggr_buf, 235 des = le32_to_cpu(status->rx_pkt_descs[drv_rx_counter]);
241 buf_size, true); 236 wlcore_hw_prepare_read(wl, des, buf_size);
237 wlcore_read_data(wl, REG_SLV_MEM_DATA, wl->aggr_buf,
238 buf_size, true);
242 239
243 /* Split data into separate packets */ 240 /* Split data into separate packets */
244 pkt_offset = 0; 241 pkt_offset = 0;
245 while (pkt_offset < buf_size) { 242 while (pkt_offset < buf_size) {
246 pkt_length = wl12xx_rx_get_buf_size(status, 243 des = le32_to_cpu(status->rx_pkt_descs[drv_rx_counter]);
247 drv_rx_counter); 244 pkt_len = wlcore_rx_get_buf_size(wl, des);
248 245 rx_align = wlcore_hw_get_rx_buf_align(wl, des);
249 unaligned = wl12xx_rx_get_unaligned(status,
250 drv_rx_counter);
251 246
252 /* 247 /*
253 * the handle data call can only fail in memory-outage 248 * the handle data call can only fail in memory-outage
@@ -256,7 +251,7 @@ void wl12xx_rx(struct wl1271 *wl, struct wl12xx_fw_status *status)
256 */ 251 */
257 if (wl1271_rx_handle_data(wl, 252 if (wl1271_rx_handle_data(wl,
258 wl->aggr_buf + pkt_offset, 253 wl->aggr_buf + pkt_offset,
259 pkt_length, unaligned, 254 pkt_len, rx_align,
260 &hlid) == 1) { 255 &hlid) == 1) {
261 if (hlid < WL12XX_MAX_LINKS) 256 if (hlid < WL12XX_MAX_LINKS)
262 __set_bit(hlid, active_hlids); 257 __set_bit(hlid, active_hlids);
@@ -269,7 +264,7 @@ void wl12xx_rx(struct wl1271 *wl, struct wl12xx_fw_status *status)
269 wl->rx_counter++; 264 wl->rx_counter++;
270 drv_rx_counter++; 265 drv_rx_counter++;
271 drv_rx_counter &= NUM_RX_PKT_DESC_MOD_MASK; 266 drv_rx_counter &= NUM_RX_PKT_DESC_MOD_MASK;
272 pkt_offset += pkt_length; 267 pkt_offset += wlcore_rx_get_align_buf_size(wl, pkt_len);
273 } 268 }
274 } 269 }
275 270
@@ -277,8 +272,9 @@ void wl12xx_rx(struct wl1271 *wl, struct wl12xx_fw_status *status)
277 * Write the driver's packet counter to the FW. This is only required 272 * Write the driver's packet counter to the FW. This is only required
278 * for older hardware revisions 273 * for older hardware revisions
279 */ 274 */
280 if (wl->quirks & WL12XX_QUIRK_END_OF_TRANSACTION) 275 if (wl->quirks & WLCORE_QUIRK_END_OF_TRANSACTION)
281 wl1271_write32(wl, RX_DRIVER_COUNTER_ADDRESS, wl->rx_counter); 276 wl1271_write32(wl, WL12XX_REG_RX_DRIVER_COUNTER,
277 wl->rx_counter);
282 278
283 wl12xx_rearm_rx_streaming(wl, active_hlids); 279 wl12xx_rearm_rx_streaming(wl, active_hlids);
284} 280}
diff --git a/drivers/net/wireless/wl12xx/rx.h b/drivers/net/wireless/ti/wlcore/rx.h
index 86ba6b1d0cdc..6e129e2a8546 100644
--- a/drivers/net/wireless/wl12xx/rx.h
+++ b/drivers/net/wireless/ti/wlcore/rx.h
@@ -96,9 +96,19 @@
96#define RX_MEM_BLOCK_MASK 0xFF 96#define RX_MEM_BLOCK_MASK 0xFF
97#define RX_BUF_SIZE_MASK 0xFFF00 97#define RX_BUF_SIZE_MASK 0xFFF00
98#define RX_BUF_SIZE_SHIFT_DIV 6 98#define RX_BUF_SIZE_SHIFT_DIV 6
99#define ALIGNED_RX_BUF_SIZE_MASK 0xFFFF00
100#define ALIGNED_RX_BUF_SIZE_SHIFT 8
101
99/* If set, the start of IP payload is not 4 bytes aligned */ 102/* If set, the start of IP payload is not 4 bytes aligned */
100#define RX_BUF_UNALIGNED_PAYLOAD BIT(20) 103#define RX_BUF_UNALIGNED_PAYLOAD BIT(20)
101 104
105/* Describes the alignment state of a Rx buffer */
106enum wl_rx_buf_align {
107 WLCORE_RX_BUF_ALIGNED,
108 WLCORE_RX_BUF_UNALIGNED,
109 WLCORE_RX_BUF_PADDED,
110};
111
102enum { 112enum {
103 WL12XX_RX_CLASS_UNKNOWN, 113 WL12XX_RX_CLASS_UNKNOWN,
104 WL12XX_RX_CLASS_MANAGEMENT, 114 WL12XX_RX_CLASS_MANAGEMENT,
@@ -126,7 +136,7 @@ struct wl1271_rx_descriptor {
126 u8 reserved; 136 u8 reserved;
127} __packed; 137} __packed;
128 138
129void wl12xx_rx(struct wl1271 *wl, struct wl12xx_fw_status *status); 139void wl12xx_rx(struct wl1271 *wl, struct wl_fw_status *status);
130u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band); 140u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band);
131 141
132#endif 142#endif
diff --git a/drivers/net/wireless/wl12xx/scan.c b/drivers/net/wireless/ti/wlcore/scan.c
index fcba055ef196..ade21a011c45 100644
--- a/drivers/net/wireless/wl12xx/scan.c
+++ b/drivers/net/wireless/ti/wlcore/scan.c
@@ -23,7 +23,7 @@
23 23
24#include <linux/ieee80211.h> 24#include <linux/ieee80211.h>
25 25
26#include "wl12xx.h" 26#include "wlcore.h"
27#include "debug.h" 27#include "debug.h"
28#include "cmd.h" 28#include "cmd.h"
29#include "scan.h" 29#include "scan.h"
@@ -417,6 +417,23 @@ wl1271_scan_get_sched_scan_channels(struct wl1271 *wl,
417 int i, j; 417 int i, j;
418 u32 flags; 418 u32 flags;
419 bool force_passive = !req->n_ssids; 419 bool force_passive = !req->n_ssids;
420 u32 min_dwell_time_active, max_dwell_time_active, delta_per_probe;
421 u32 dwell_time_passive, dwell_time_dfs;
422
423 if (band == IEEE80211_BAND_5GHZ)
424 delta_per_probe = c->dwell_time_delta_per_probe_5;
425 else
426 delta_per_probe = c->dwell_time_delta_per_probe;
427
428 min_dwell_time_active = c->base_dwell_time +
429 req->n_ssids * c->num_probe_reqs * delta_per_probe;
430
431 max_dwell_time_active = min_dwell_time_active + c->max_dwell_time_delta;
432
433 min_dwell_time_active = DIV_ROUND_UP(min_dwell_time_active, 1000);
434 max_dwell_time_active = DIV_ROUND_UP(max_dwell_time_active, 1000);
435 dwell_time_passive = DIV_ROUND_UP(c->dwell_time_passive, 1000);
436 dwell_time_dfs = DIV_ROUND_UP(c->dwell_time_dfs, 1000);
420 437
421 for (i = 0, j = start; 438 for (i = 0, j = start;
422 i < req->n_channels && j < max_channels; 439 i < req->n_channels && j < max_channels;
@@ -440,21 +457,24 @@ wl1271_scan_get_sched_scan_channels(struct wl1271 *wl,
440 req->channels[i]->flags); 457 req->channels[i]->flags);
441 wl1271_debug(DEBUG_SCAN, "max_power %d", 458 wl1271_debug(DEBUG_SCAN, "max_power %d",
442 req->channels[i]->max_power); 459 req->channels[i]->max_power);
460 wl1271_debug(DEBUG_SCAN, "min_dwell_time %d max dwell time %d",
461 min_dwell_time_active,
462 max_dwell_time_active);
443 463
444 if (flags & IEEE80211_CHAN_RADAR) { 464 if (flags & IEEE80211_CHAN_RADAR) {
445 channels[j].flags |= SCAN_CHANNEL_FLAGS_DFS; 465 channels[j].flags |= SCAN_CHANNEL_FLAGS_DFS;
446 466
447 channels[j].passive_duration = 467 channels[j].passive_duration =
448 cpu_to_le16(c->dwell_time_dfs); 468 cpu_to_le16(dwell_time_dfs);
449 } else { 469 } else {
450 channels[j].passive_duration = 470 channels[j].passive_duration =
451 cpu_to_le16(c->dwell_time_passive); 471 cpu_to_le16(dwell_time_passive);
452 } 472 }
453 473
454 channels[j].min_duration = 474 channels[j].min_duration =
455 cpu_to_le16(c->min_dwell_time_active); 475 cpu_to_le16(min_dwell_time_active);
456 channels[j].max_duration = 476 channels[j].max_duration =
457 cpu_to_le16(c->max_dwell_time_active); 477 cpu_to_le16(max_dwell_time_active);
458 478
459 channels[j].tx_power_att = req->channels[i]->max_power; 479 channels[j].tx_power_att = req->channels[i]->max_power;
460 channels[j].channel = req->channels[i]->hw_value; 480 channels[j].channel = req->channels[i]->hw_value;
diff --git a/drivers/net/wireless/wl12xx/scan.h b/drivers/net/wireless/ti/wlcore/scan.h
index 96ff457a3a0b..81ee36ac2078 100644
--- a/drivers/net/wireless/wl12xx/scan.h
+++ b/drivers/net/wireless/ti/wlcore/scan.h
@@ -24,7 +24,7 @@
24#ifndef __SCAN_H__ 24#ifndef __SCAN_H__
25#define __SCAN_H__ 25#define __SCAN_H__
26 26
27#include "wl12xx.h" 27#include "wlcore.h"
28 28
29int wl1271_scan(struct wl1271 *wl, struct ieee80211_vif *vif, 29int wl1271_scan(struct wl1271 *wl, struct ieee80211_vif *vif,
30 const u8 *ssid, size_t ssid_len, 30 const u8 *ssid, size_t ssid_len,
@@ -55,7 +55,7 @@ void wl1271_scan_sched_scan_results(struct wl1271 *wl);
55#define WL1271_SCAN_BAND_2_4_GHZ 0 55#define WL1271_SCAN_BAND_2_4_GHZ 0
56#define WL1271_SCAN_BAND_5_GHZ 1 56#define WL1271_SCAN_BAND_5_GHZ 1
57 57
58#define WL1271_SCAN_TIMEOUT 10000 /* msec */ 58#define WL1271_SCAN_TIMEOUT 30000 /* msec */
59 59
60enum { 60enum {
61 WL1271_SCAN_STATE_IDLE, 61 WL1271_SCAN_STATE_IDLE,
diff --git a/drivers/net/wireless/wl12xx/sdio.c b/drivers/net/wireless/ti/wlcore/sdio.c
index 4b3c32774bae..0a72347cfc4c 100644
--- a/drivers/net/wireless/wl12xx/sdio.c
+++ b/drivers/net/wireless/ti/wlcore/sdio.c
@@ -33,7 +33,7 @@
33#include <linux/wl12xx.h> 33#include <linux/wl12xx.h>
34#include <linux/pm_runtime.h> 34#include <linux/pm_runtime.h>
35 35
36#include "wl12xx.h" 36#include "wlcore.h"
37#include "wl12xx_80211.h" 37#include "wl12xx_80211.h"
38#include "io.h" 38#include "io.h"
39 39
@@ -76,7 +76,7 @@ static void wl12xx_sdio_raw_read(struct device *child, int addr, void *buf,
76 76
77 sdio_claim_host(func); 77 sdio_claim_host(func);
78 78
79 if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) { 79 if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG)) {
80 ((u8 *)buf)[0] = sdio_f0_readb(func, addr, &ret); 80 ((u8 *)buf)[0] = sdio_f0_readb(func, addr, &ret);
81 dev_dbg(child->parent, "sdio read 52 addr 0x%x, byte 0x%02x\n", 81 dev_dbg(child->parent, "sdio read 52 addr 0x%x, byte 0x%02x\n",
82 addr, ((u8 *)buf)[0]); 82 addr, ((u8 *)buf)[0]);
@@ -105,7 +105,7 @@ static void wl12xx_sdio_raw_write(struct device *child, int addr, void *buf,
105 105
106 sdio_claim_host(func); 106 sdio_claim_host(func);
107 107
108 if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) { 108 if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG)) {
109 sdio_f0_writeb(func, ((u8 *)buf)[0], addr, &ret); 109 sdio_f0_writeb(func, ((u8 *)buf)[0], addr, &ret);
110 dev_dbg(child->parent, "sdio write 52 addr 0x%x, byte 0x%02x\n", 110 dev_dbg(child->parent, "sdio write 52 addr 0x%x, byte 0x%02x\n",
111 addr, ((u8 *)buf)[0]); 111 addr, ((u8 *)buf)[0]);
diff --git a/drivers/net/wireless/wl12xx/spi.c b/drivers/net/wireless/ti/wlcore/spi.c
index 2fc18a8dcce8..553cd3cbb98c 100644
--- a/drivers/net/wireless/wl12xx/spi.c
+++ b/drivers/net/wireless/ti/wlcore/spi.c
@@ -30,12 +30,10 @@
30#include <linux/platform_device.h> 30#include <linux/platform_device.h>
31#include <linux/slab.h> 31#include <linux/slab.h>
32 32
33#include "wl12xx.h" 33#include "wlcore.h"
34#include "wl12xx_80211.h" 34#include "wl12xx_80211.h"
35#include "io.h" 35#include "io.h"
36 36
37#include "reg.h"
38
39#define WSPI_CMD_READ 0x40000000 37#define WSPI_CMD_READ 0x40000000
40#define WSPI_CMD_WRITE 0x00000000 38#define WSPI_CMD_WRITE 0x00000000
41#define WSPI_CMD_FIXED 0x20000000 39#define WSPI_CMD_FIXED 0x20000000
diff --git a/drivers/net/wireless/wl12xx/testmode.c b/drivers/net/wireless/ti/wlcore/testmode.c
index 1e93bb9c0246..9cda706e4e3f 100644
--- a/drivers/net/wireless/wl12xx/testmode.c
+++ b/drivers/net/wireless/ti/wlcore/testmode.c
@@ -25,10 +25,9 @@
25#include <linux/slab.h> 25#include <linux/slab.h>
26#include <net/genetlink.h> 26#include <net/genetlink.h>
27 27
28#include "wl12xx.h" 28#include "wlcore.h"
29#include "debug.h" 29#include "debug.h"
30#include "acx.h" 30#include "acx.h"
31#include "reg.h"
32#include "ps.h" 31#include "ps.h"
33#include "io.h" 32#include "io.h"
34 33
diff --git a/drivers/net/wireless/wl12xx/testmode.h b/drivers/net/wireless/ti/wlcore/testmode.h
index 8071654259ea..8071654259ea 100644
--- a/drivers/net/wireless/wl12xx/testmode.h
+++ b/drivers/net/wireless/ti/wlcore/testmode.h
diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/ti/wlcore/tx.c
index 43ae49143d68..6893bc207994 100644
--- a/drivers/net/wireless/wl12xx/tx.c
+++ b/drivers/net/wireless/ti/wlcore/tx.c
@@ -25,13 +25,19 @@
25#include <linux/module.h> 25#include <linux/module.h>
26#include <linux/etherdevice.h> 26#include <linux/etherdevice.h>
27 27
28#include "wl12xx.h" 28#include "wlcore.h"
29#include "debug.h" 29#include "debug.h"
30#include "io.h" 30#include "io.h"
31#include "reg.h"
32#include "ps.h" 31#include "ps.h"
33#include "tx.h" 32#include "tx.h"
34#include "event.h" 33#include "event.h"
34#include "hw_ops.h"
35
36/*
37 * TODO: this is here just for now, it must be removed when the data
38 * operations are in place.
39 */
40#include "../wl12xx/reg.h"
35 41
36static int wl1271_set_default_wep_key(struct wl1271 *wl, 42static int wl1271_set_default_wep_key(struct wl1271 *wl,
37 struct wl12xx_vif *wlvif, u8 id) 43 struct wl12xx_vif *wlvif, u8 id)
@@ -56,8 +62,8 @@ static int wl1271_alloc_tx_id(struct wl1271 *wl, struct sk_buff *skb)
56{ 62{
57 int id; 63 int id;
58 64
59 id = find_first_zero_bit(wl->tx_frames_map, ACX_TX_DESCRIPTORS); 65 id = find_first_zero_bit(wl->tx_frames_map, wl->num_tx_desc);
60 if (id >= ACX_TX_DESCRIPTORS) 66 if (id >= wl->num_tx_desc)
61 return -EBUSY; 67 return -EBUSY;
62 68
63 __set_bit(id, wl->tx_frames_map); 69 __set_bit(id, wl->tx_frames_map);
@@ -69,7 +75,7 @@ static int wl1271_alloc_tx_id(struct wl1271 *wl, struct sk_buff *skb)
69static void wl1271_free_tx_id(struct wl1271 *wl, int id) 75static void wl1271_free_tx_id(struct wl1271 *wl, int id)
70{ 76{
71 if (__test_and_clear_bit(id, wl->tx_frames_map)) { 77 if (__test_and_clear_bit(id, wl->tx_frames_map)) {
72 if (unlikely(wl->tx_frames_cnt == ACX_TX_DESCRIPTORS)) 78 if (unlikely(wl->tx_frames_cnt == wl->num_tx_desc))
73 clear_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags); 79 clear_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags);
74 80
75 wl->tx_frames[id] = NULL; 81 wl->tx_frames[id] = NULL;
@@ -167,14 +173,15 @@ u8 wl12xx_tx_get_hlid(struct wl1271 *wl, struct wl12xx_vif *wlvif,
167 return wlvif->dev_hlid; 173 return wlvif->dev_hlid;
168} 174}
169 175
170static unsigned int wl12xx_calc_packet_alignment(struct wl1271 *wl, 176unsigned int wlcore_calc_packet_alignment(struct wl1271 *wl,
171 unsigned int packet_length) 177 unsigned int packet_length)
172{ 178{
173 if (wl->quirks & WL12XX_QUIRK_NO_BLOCKSIZE_ALIGNMENT) 179 if (wl->quirks & WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN)
174 return ALIGN(packet_length, WL1271_TX_ALIGN_TO);
175 else
176 return ALIGN(packet_length, WL12XX_BUS_BLOCK_SIZE); 180 return ALIGN(packet_length, WL12XX_BUS_BLOCK_SIZE);
181 else
182 return ALIGN(packet_length, WL1271_TX_ALIGN_TO);
177} 183}
184EXPORT_SYMBOL(wlcore_calc_packet_alignment);
178 185
179static int wl1271_tx_allocate(struct wl1271 *wl, struct wl12xx_vif *wlvif, 186static int wl1271_tx_allocate(struct wl1271 *wl, struct wl12xx_vif *wlvif,
180 struct sk_buff *skb, u32 extra, u32 buf_offset, 187 struct sk_buff *skb, u32 extra, u32 buf_offset,
@@ -182,10 +189,9 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct wl12xx_vif *wlvif,
182{ 189{
183 struct wl1271_tx_hw_descr *desc; 190 struct wl1271_tx_hw_descr *desc;
184 u32 total_len = skb->len + sizeof(struct wl1271_tx_hw_descr) + extra; 191 u32 total_len = skb->len + sizeof(struct wl1271_tx_hw_descr) + extra;
185 u32 len;
186 u32 total_blocks; 192 u32 total_blocks;
187 int id, ret = -EBUSY, ac; 193 int id, ret = -EBUSY, ac;
188 u32 spare_blocks = wl->tx_spare_blocks; 194 u32 spare_blocks = wl->normal_tx_spare;
189 bool is_dummy = false; 195 bool is_dummy = false;
190 196
191 if (buf_offset + total_len > WL1271_AGGR_BUFFER_SIZE) 197 if (buf_offset + total_len > WL1271_AGGR_BUFFER_SIZE)
@@ -196,30 +202,19 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct wl12xx_vif *wlvif,
196 if (id < 0) 202 if (id < 0)
197 return id; 203 return id;
198 204
199 /* approximate the number of blocks required for this packet 205 if (unlikely(wl12xx_is_dummy_packet(wl, skb)))
200 in the firmware */
201 len = wl12xx_calc_packet_alignment(wl, total_len);
202
203 /* in case of a dummy packet, use default amount of spare mem blocks */
204 if (unlikely(wl12xx_is_dummy_packet(wl, skb))) {
205 is_dummy = true; 206 is_dummy = true;
206 spare_blocks = TX_HW_BLOCK_SPARE_DEFAULT; 207 else if (wlvif->is_gem)
207 } 208 spare_blocks = wl->gem_tx_spare;
208 209
209 total_blocks = (len + TX_HW_BLOCK_SIZE - 1) / TX_HW_BLOCK_SIZE + 210 total_blocks = wlcore_hw_calc_tx_blocks(wl, total_len, spare_blocks);
210 spare_blocks;
211 211
212 if (total_blocks <= wl->tx_blocks_available) { 212 if (total_blocks <= wl->tx_blocks_available) {
213 desc = (struct wl1271_tx_hw_descr *)skb_push( 213 desc = (struct wl1271_tx_hw_descr *)skb_push(
214 skb, total_len - skb->len); 214 skb, total_len - skb->len);
215 215
216 /* HW descriptor fields change between wl127x and wl128x */ 216 wlcore_hw_set_tx_desc_blocks(wl, desc, total_blocks,
217 if (wl->chip.id == CHIP_ID_1283_PG20) { 217 spare_blocks);
218 desc->wl128x_mem.total_mem_blocks = total_blocks;
219 } else {
220 desc->wl127x_mem.extra_blocks = spare_blocks;
221 desc->wl127x_mem.total_mem_blocks = total_blocks;
222 }
223 218
224 desc->id = id; 219 desc->id = id;
225 220
@@ -256,7 +251,7 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct wl12xx_vif *wlvif,
256{ 251{
257 struct timespec ts; 252 struct timespec ts;
258 struct wl1271_tx_hw_descr *desc; 253 struct wl1271_tx_hw_descr *desc;
259 int aligned_len, ac, rate_idx; 254 int ac, rate_idx;
260 s64 hosttime; 255 s64 hosttime;
261 u16 tx_attr = 0; 256 u16 tx_attr = 0;
262 __le16 frame_control; 257 __le16 frame_control;
@@ -329,44 +324,16 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct wl12xx_vif *wlvif,
329 } 324 }
330 325
331 tx_attr |= rate_idx << TX_HW_ATTR_OFST_RATE_POLICY; 326 tx_attr |= rate_idx << TX_HW_ATTR_OFST_RATE_POLICY;
332 desc->reserved = 0;
333
334 aligned_len = wl12xx_calc_packet_alignment(wl, skb->len);
335
336 if (wl->chip.id == CHIP_ID_1283_PG20) {
337 desc->wl128x_mem.extra_bytes = aligned_len - skb->len;
338 desc->length = cpu_to_le16(aligned_len >> 2);
339
340 wl1271_debug(DEBUG_TX, "tx_fill_hdr: hlid: %d "
341 "tx_attr: 0x%x len: %d life: %d mem: %d",
342 desc->hlid, tx_attr,
343 le16_to_cpu(desc->length),
344 le16_to_cpu(desc->life_time),
345 desc->wl128x_mem.total_mem_blocks);
346 } else {
347 int pad;
348
349 /* Store the aligned length in terms of words */
350 desc->length = cpu_to_le16(aligned_len >> 2);
351
352 /* calculate number of padding bytes */
353 pad = aligned_len - skb->len;
354 tx_attr |= pad << TX_HW_ATTR_OFST_LAST_WORD_PAD;
355
356 wl1271_debug(DEBUG_TX, "tx_fill_hdr: pad: %d hlid: %d "
357 "tx_attr: 0x%x len: %d life: %d mem: %d", pad,
358 desc->hlid, tx_attr,
359 le16_to_cpu(desc->length),
360 le16_to_cpu(desc->life_time),
361 desc->wl127x_mem.total_mem_blocks);
362 }
363 327
364 /* for WEP shared auth - no fw encryption is needed */ 328 /* for WEP shared auth - no fw encryption is needed */
365 if (ieee80211_is_auth(frame_control) && 329 if (ieee80211_is_auth(frame_control) &&
366 ieee80211_has_protected(frame_control)) 330 ieee80211_has_protected(frame_control))
367 tx_attr |= TX_HW_ATTR_HOST_ENCRYPT; 331 tx_attr |= TX_HW_ATTR_HOST_ENCRYPT;
368 332
333 desc->reserved = 0;
369 desc->tx_attr = cpu_to_le16(tx_attr); 334 desc->tx_attr = cpu_to_le16(tx_attr);
335
336 wlcore_hw_set_tx_desc_data_len(wl, desc, skb);
370} 337}
371 338
372/* caller must hold wl->mutex */ 339/* caller must hold wl->mutex */
@@ -432,7 +399,7 @@ static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct wl12xx_vif *wlvif,
432 * In special cases, we want to align to a specific block size 399 * In special cases, we want to align to a specific block size
433 * (eg. for wl128x with SDIO we align to 256). 400 * (eg. for wl128x with SDIO we align to 256).
434 */ 401 */
435 total_len = wl12xx_calc_packet_alignment(wl, skb->len); 402 total_len = wlcore_calc_packet_alignment(wl, skb->len);
436 403
437 memcpy(wl->aggr_buf + buf_offset, skb->data, skb->len); 404 memcpy(wl->aggr_buf + buf_offset, skb->data, skb->len);
438 memset(wl->aggr_buf + buf_offset + skb->len, 0, total_len - skb->len); 405 memset(wl->aggr_buf + buf_offset + skb->len, 0, total_len - skb->len);
@@ -718,8 +685,8 @@ void wl1271_tx_work_locked(struct wl1271 *wl)
718 * Flush buffer and try again. 685 * Flush buffer and try again.
719 */ 686 */
720 wl1271_skb_queue_head(wl, wlvif, skb); 687 wl1271_skb_queue_head(wl, wlvif, skb);
721 wl1271_write(wl, WL1271_SLV_MEM_DATA, wl->aggr_buf, 688 wlcore_write_data(wl, REG_SLV_MEM_DATA, wl->aggr_buf,
722 buf_offset, true); 689 buf_offset, true);
723 sent_packets = true; 690 sent_packets = true;
724 buf_offset = 0; 691 buf_offset = 0;
725 continue; 692 continue;
@@ -753,8 +720,8 @@ void wl1271_tx_work_locked(struct wl1271 *wl)
753 720
754out_ack: 721out_ack:
755 if (buf_offset) { 722 if (buf_offset) {
756 wl1271_write(wl, WL1271_SLV_MEM_DATA, wl->aggr_buf, 723 wlcore_write_data(wl, REG_SLV_MEM_DATA, wl->aggr_buf,
757 buf_offset, true); 724 buf_offset, true);
758 sent_packets = true; 725 sent_packets = true;
759 } 726 }
760 if (sent_packets) { 727 if (sent_packets) {
@@ -762,8 +729,8 @@ out_ack:
762 * Interrupt the firmware with the new packets. This is only 729 * Interrupt the firmware with the new packets. This is only
763 * required for older hardware revisions 730 * required for older hardware revisions
764 */ 731 */
765 if (wl->quirks & WL12XX_QUIRK_END_OF_TRANSACTION) 732 if (wl->quirks & WLCORE_QUIRK_END_OF_TRANSACTION)
766 wl1271_write32(wl, WL1271_HOST_WR_ACCESS, 733 wl1271_write32(wl, WL12XX_HOST_WR_ACCESS,
767 wl->tx_packets_count); 734 wl->tx_packets_count);
768 735
769 wl1271_handle_tx_low_watermark(wl); 736 wl1271_handle_tx_low_watermark(wl);
@@ -792,11 +759,20 @@ static u8 wl1271_tx_get_rate_flags(u8 rate_class_index)
792{ 759{
793 u8 flags = 0; 760 u8 flags = 0;
794 761
795 if (rate_class_index >= CONF_HW_RXTX_RATE_MCS_MIN && 762 /*
796 rate_class_index <= CONF_HW_RXTX_RATE_MCS_MAX) 763 * TODO: use wl12xx constants when this code is moved to wl12xx, as
764 * only it uses Tx-completion.
765 */
766 if (rate_class_index <= 8)
797 flags |= IEEE80211_TX_RC_MCS; 767 flags |= IEEE80211_TX_RC_MCS;
798 if (rate_class_index == CONF_HW_RXTX_RATE_MCS7_SGI) 768
769 /*
770 * TODO: use wl12xx constants when this code is moved to wl12xx, as
771 * only it uses Tx-completion.
772 */
773 if (rate_class_index == 0)
799 flags |= IEEE80211_TX_RC_SHORT_GI; 774 flags |= IEEE80211_TX_RC_SHORT_GI;
775
800 return flags; 776 return flags;
801} 777}
802 778
@@ -813,7 +789,7 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl,
813 u8 retries = 0; 789 u8 retries = 0;
814 790
815 /* check for id legality */ 791 /* check for id legality */
816 if (unlikely(id >= ACX_TX_DESCRIPTORS || wl->tx_frames[id] == NULL)) { 792 if (unlikely(id >= wl->num_tx_desc || wl->tx_frames[id] == NULL)) {
817 wl1271_warning("TX result illegal id: %d", id); 793 wl1271_warning("TX result illegal id: %d", id);
818 return; 794 return;
819 } 795 }
@@ -834,7 +810,7 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl,
834 if (result->status == TX_SUCCESS) { 810 if (result->status == TX_SUCCESS) {
835 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) 811 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
836 info->flags |= IEEE80211_TX_STAT_ACK; 812 info->flags |= IEEE80211_TX_STAT_ACK;
837 rate = wl1271_rate_to_idx(result->rate_class_index, 813 rate = wlcore_rate_to_idx(wl, result->rate_class_index,
838 wlvif->band); 814 wlvif->band);
839 rate_flags = wl1271_tx_get_rate_flags(result->rate_class_index); 815 rate_flags = wl1271_tx_get_rate_flags(result->rate_class_index);
840 retries = result->ack_failures; 816 retries = result->ack_failures;
@@ -929,6 +905,7 @@ void wl1271_tx_complete(struct wl1271 *wl)
929 wl->tx_results_count++; 905 wl->tx_results_count++;
930 } 906 }
931} 907}
908EXPORT_SYMBOL(wl1271_tx_complete);
932 909
933void wl1271_tx_reset_link_queues(struct wl1271 *wl, u8 hlid) 910void wl1271_tx_reset_link_queues(struct wl1271 *wl, u8 hlid)
934{ 911{
@@ -1006,7 +983,7 @@ void wl12xx_tx_reset(struct wl1271 *wl, bool reset_tx_queues)
1006 if (reset_tx_queues) 983 if (reset_tx_queues)
1007 wl1271_handle_tx_low_watermark(wl); 984 wl1271_handle_tx_low_watermark(wl);
1008 985
1009 for (i = 0; i < ACX_TX_DESCRIPTORS; i++) { 986 for (i = 0; i < wl->num_tx_desc; i++) {
1010 if (wl->tx_frames[i] == NULL) 987 if (wl->tx_frames[i] == NULL)
1011 continue; 988 continue;
1012 989
diff --git a/drivers/net/wireless/wl12xx/tx.h b/drivers/net/wireless/ti/wlcore/tx.h
index 5cf8c32d40d1..2fd6e5dc6f75 100644
--- a/drivers/net/wireless/wl12xx/tx.h
+++ b/drivers/net/wireless/ti/wlcore/tx.h
@@ -25,9 +25,6 @@
25#ifndef __TX_H__ 25#ifndef __TX_H__
26#define __TX_H__ 26#define __TX_H__
27 27
28#define TX_HW_BLOCK_SPARE_DEFAULT 1
29#define TX_HW_BLOCK_SIZE 252
30
31#define TX_HW_MGMT_PKT_LIFETIME_TU 2000 28#define TX_HW_MGMT_PKT_LIFETIME_TU 2000
32#define TX_HW_AP_MODE_PKT_LIFETIME_TU 8000 29#define TX_HW_AP_MODE_PKT_LIFETIME_TU 8000
33 30
@@ -212,7 +209,7 @@ void wl1271_tx_complete(struct wl1271 *wl);
212void wl12xx_tx_reset_wlvif(struct wl1271 *wl, struct wl12xx_vif *wlvif); 209void wl12xx_tx_reset_wlvif(struct wl1271 *wl, struct wl12xx_vif *wlvif);
213void wl12xx_tx_reset(struct wl1271 *wl, bool reset_tx_queues); 210void wl12xx_tx_reset(struct wl1271 *wl, bool reset_tx_queues);
214void wl1271_tx_flush(struct wl1271 *wl); 211void wl1271_tx_flush(struct wl1271 *wl);
215u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band); 212u8 wlcore_rate_to_idx(struct wl1271 *wl, u8 rate, enum ieee80211_band band);
216u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set, 213u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set,
217 enum ieee80211_band rate_band); 214 enum ieee80211_band rate_band);
218u32 wl1271_tx_min_rate_get(struct wl1271 *wl, u32 rate_set); 215u32 wl1271_tx_min_rate_get(struct wl1271 *wl, u32 rate_set);
@@ -224,6 +221,8 @@ void wl1271_tx_reset_link_queues(struct wl1271 *wl, u8 hlid);
224void wl1271_handle_tx_low_watermark(struct wl1271 *wl); 221void wl1271_handle_tx_low_watermark(struct wl1271 *wl);
225bool wl12xx_is_dummy_packet(struct wl1271 *wl, struct sk_buff *skb); 222bool wl12xx_is_dummy_packet(struct wl1271 *wl, struct sk_buff *skb);
226void wl12xx_rearm_rx_streaming(struct wl1271 *wl, unsigned long *active_hlids); 223void wl12xx_rearm_rx_streaming(struct wl1271 *wl, unsigned long *active_hlids);
224unsigned int wlcore_calc_packet_alignment(struct wl1271 *wl,
225 unsigned int packet_length);
227 226
228/* from main.c */ 227/* from main.c */
229void wl1271_free_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 hlid); 228void wl1271_free_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 hlid);
diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/ti/wlcore/wl12xx.h
index 749a15a75d38..a9b220c43e54 100644
--- a/drivers/net/wireless/wl12xx/wl12xx.h
+++ b/drivers/net/wireless/ti/wlcore/wl12xx.h
@@ -89,8 +89,6 @@
89#define WL1271_AP_BSS_INDEX 0 89#define WL1271_AP_BSS_INDEX 0
90#define WL1271_AP_DEF_BEACON_EXP 20 90#define WL1271_AP_DEF_BEACON_EXP 20
91 91
92#define ACX_TX_DESCRIPTORS 16
93
94#define WL1271_AGGR_BUFFER_SIZE (4 * PAGE_SIZE) 92#define WL1271_AGGR_BUFFER_SIZE (4 * PAGE_SIZE)
95 93
96enum wl1271_state { 94enum wl1271_state {
@@ -105,26 +103,6 @@ enum wl12xx_fw_type {
105 WL12XX_FW_TYPE_PLT, 103 WL12XX_FW_TYPE_PLT,
106}; 104};
107 105
108enum wl1271_partition_type {
109 PART_DOWN,
110 PART_WORK,
111 PART_DRPW,
112
113 PART_TABLE_LEN
114};
115
116struct wl1271_partition {
117 u32 size;
118 u32 start;
119};
120
121struct wl1271_partition_set {
122 struct wl1271_partition mem;
123 struct wl1271_partition reg;
124 struct wl1271_partition mem2;
125 struct wl1271_partition mem3;
126};
127
128struct wl1271; 106struct wl1271;
129 107
130enum { 108enum {
@@ -167,8 +145,21 @@ struct wl1271_stats {
167 145
168#define AP_MAX_STATIONS 8 146#define AP_MAX_STATIONS 8
169 147
148struct wl_fw_packet_counters {
149 /* Cumulative counter of released packets per AC */
150 u8 tx_released_pkts[NUM_TX_QUEUES];
151
152 /* Cumulative counter of freed packets per HLID */
153 u8 tx_lnk_free_pkts[WL12XX_MAX_LINKS];
154
155 /* Cumulative counter of released Voice memory blocks */
156 u8 tx_voice_released_blks;
157
158 u8 padding[3];
159} __packed;
160
170/* FW status registers */ 161/* FW status registers */
171struct wl12xx_fw_status { 162struct wl_fw_status {
172 __le32 intr; 163 __le32 intr;
173 u8 fw_rx_counter; 164 u8 fw_rx_counter;
174 u8 drv_rx_counter; 165 u8 drv_rx_counter;
@@ -195,16 +186,12 @@ struct wl12xx_fw_status {
195 /* Size (in Memory Blocks) of TX pool */ 186 /* Size (in Memory Blocks) of TX pool */
196 __le32 tx_total; 187 __le32 tx_total;
197 188
198 /* Cumulative counter of released packets per AC */ 189 struct wl_fw_packet_counters counters;
199 u8 tx_released_pkts[NUM_TX_QUEUES];
200 190
201 /* Cumulative counter of freed packets per HLID */
202 u8 tx_lnk_free_pkts[WL12XX_MAX_LINKS];
203
204 /* Cumulative counter of released Voice memory blocks */
205 u8 tx_voice_released_blks;
206 u8 padding_1[3];
207 __le32 log_start_addr; 191 __le32 log_start_addr;
192
193 /* Private status to be used by the lower drivers */
194 u8 priv[0];
208} __packed; 195} __packed;
209 196
210struct wl1271_rx_mem_pool_addr { 197struct wl1271_rx_mem_pool_addr {
@@ -292,214 +279,6 @@ struct wl1271_link {
292 u8 ba_bitmap; 279 u8 ba_bitmap;
293}; 280};
294 281
295struct wl1271 {
296 struct ieee80211_hw *hw;
297 bool mac80211_registered;
298
299 struct device *dev;
300
301 void *if_priv;
302
303 struct wl1271_if_operations *if_ops;
304
305 void (*set_power)(bool enable);
306 int irq;
307 int ref_clock;
308
309 spinlock_t wl_lock;
310
311 enum wl1271_state state;
312 enum wl12xx_fw_type fw_type;
313 bool plt;
314 u8 last_vif_count;
315 struct mutex mutex;
316
317 unsigned long flags;
318
319 struct wl1271_partition_set part;
320
321 struct wl1271_chip chip;
322
323 int cmd_box_addr;
324 int event_box_addr;
325
326 u8 *fw;
327 size_t fw_len;
328 void *nvs;
329 size_t nvs_len;
330
331 s8 hw_pg_ver;
332
333 /* address read from the fuse ROM */
334 u32 fuse_oui_addr;
335 u32 fuse_nic_addr;
336
337 /* we have up to 2 MAC addresses */
338 struct mac_address addresses[2];
339 int channel;
340 u8 system_hlid;
341
342 unsigned long links_map[BITS_TO_LONGS(WL12XX_MAX_LINKS)];
343 unsigned long roles_map[BITS_TO_LONGS(WL12XX_MAX_ROLES)];
344 unsigned long roc_map[BITS_TO_LONGS(WL12XX_MAX_ROLES)];
345 unsigned long rate_policies_map[
346 BITS_TO_LONGS(WL12XX_MAX_RATE_POLICIES)];
347
348 struct list_head wlvif_list;
349
350 u8 sta_count;
351 u8 ap_count;
352
353 struct wl1271_acx_mem_map *target_mem_map;
354
355 /* Accounting for allocated / available TX blocks on HW */
356 u32 tx_blocks_freed;
357 u32 tx_blocks_available;
358 u32 tx_allocated_blocks;
359 u32 tx_results_count;
360
361 /* amount of spare TX blocks to use */
362 u32 tx_spare_blocks;
363
364 /* Accounting for allocated / available Tx packets in HW */
365 u32 tx_pkts_freed[NUM_TX_QUEUES];
366 u32 tx_allocated_pkts[NUM_TX_QUEUES];
367
368 /* Transmitted TX packets counter for chipset interface */
369 u32 tx_packets_count;
370
371 /* Time-offset between host and chipset clocks */
372 s64 time_offset;
373
374 /* Frames scheduled for transmission, not handled yet */
375 int tx_queue_count[NUM_TX_QUEUES];
376 long stopped_queues_map;
377
378 /* Frames received, not handled yet by mac80211 */
379 struct sk_buff_head deferred_rx_queue;
380
381 /* Frames sent, not returned yet to mac80211 */
382 struct sk_buff_head deferred_tx_queue;
383
384 struct work_struct tx_work;
385 struct workqueue_struct *freezable_wq;
386
387 /* Pending TX frames */
388 unsigned long tx_frames_map[BITS_TO_LONGS(ACX_TX_DESCRIPTORS)];
389 struct sk_buff *tx_frames[ACX_TX_DESCRIPTORS];
390 int tx_frames_cnt;
391
392 /* FW Rx counter */
393 u32 rx_counter;
394
395 /* Rx memory pool address */
396 struct wl1271_rx_mem_pool_addr rx_mem_pool_addr;
397
398 /* Intermediate buffer, used for packet aggregation */
399 u8 *aggr_buf;
400
401 /* Reusable dummy packet template */
402 struct sk_buff *dummy_packet;
403
404 /* Network stack work */
405 struct work_struct netstack_work;
406
407 /* FW log buffer */
408 u8 *fwlog;
409
410 /* Number of valid bytes in the FW log buffer */
411 ssize_t fwlog_size;
412
413 /* Sysfs FW log entry readers wait queue */
414 wait_queue_head_t fwlog_waitq;
415
416 /* Hardware recovery work */
417 struct work_struct recovery_work;
418
419 /* The mbox event mask */
420 u32 event_mask;
421
422 /* Mailbox pointers */
423 u32 mbox_ptr[2];
424
425 /* Are we currently scanning */
426 struct ieee80211_vif *scan_vif;
427 struct wl1271_scan scan;
428 struct delayed_work scan_complete_work;
429
430 bool sched_scanning;
431
432 /* The current band */
433 enum ieee80211_band band;
434
435 struct completion *elp_compl;
436 struct delayed_work elp_work;
437
438 /* in dBm */
439 int power_level;
440
441 struct wl1271_stats stats;
442
443 __le32 buffer_32;
444 u32 buffer_cmd;
445 u32 buffer_busyword[WL1271_BUSY_WORD_CNT];
446
447 struct wl12xx_fw_status *fw_status;
448 struct wl1271_tx_hw_res_if *tx_res_if;
449
450 /* Current chipset configuration */
451 struct conf_drv_settings conf;
452
453 bool sg_enabled;
454
455 bool enable_11a;
456
457 /* Most recently reported noise in dBm */
458 s8 noise;
459
460 /* bands supported by this instance of wl12xx */
461 struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS];
462
463 int tcxo_clock;
464
465 /*
466 * wowlan trigger was configured during suspend.
467 * (currently, only "ANY" trigger is supported)
468 */
469 bool wow_enabled;
470 bool irq_wake_enabled;
471
472 /*
473 * AP-mode - links indexed by HLID. The global and broadcast links
474 * are always active.
475 */
476 struct wl1271_link links[WL12XX_MAX_LINKS];
477
478 /* AP-mode - a bitmap of links currently in PS mode according to FW */
479 u32 ap_fw_ps_map;
480
481 /* AP-mode - a bitmap of links currently in PS mode in mac80211 */
482 unsigned long ap_ps_map;
483
484 /* Quirks of specific hardware revisions */
485 unsigned int quirks;
486
487 /* Platform limitations */
488 unsigned int platform_quirks;
489
490 /* number of currently active RX BA sessions */
491 int ba_rx_session_count;
492
493 /* AP-mode - number of currently connected stations */
494 int active_sta_count;
495
496 /* last wlvif we transmitted from */
497 struct wl12xx_vif *last_wlvif;
498
499 /* work to fire when Tx is stuck */
500 struct delayed_work tx_watchdog_work;
501};
502
503struct wl1271_station { 282struct wl1271_station {
504 u8 hlid; 283 u8 hlid;
505}; 284};
@@ -605,6 +384,9 @@ struct wl12xx_vif {
605 struct work_struct rx_streaming_disable_work; 384 struct work_struct rx_streaming_disable_work;
606 struct timer_list rx_streaming_timer; 385 struct timer_list rx_streaming_timer;
607 386
387 /* does the current role use GEM for encryption (AP or STA) */
388 bool is_gem;
389
608 /* 390 /*
609 * This struct must be last! 391 * This struct must be last!
610 * data that has to be saved acrossed reconfigs (e.g. recovery) 392 * data that has to be saved acrossed reconfigs (e.g. recovery)
@@ -679,17 +461,6 @@ size_t wl12xx_copy_fwlog(struct wl1271 *wl, u8 *memblock, size_t maxlen);
679#define HW_BG_RATES_MASK 0xffff 461#define HW_BG_RATES_MASK 0xffff
680#define HW_HT_RATES_OFFSET 16 462#define HW_HT_RATES_OFFSET 16
681 463
682/* Quirks */
683
684/* Each RX/TX transaction requires an end-of-transaction transfer */
685#define WL12XX_QUIRK_END_OF_TRANSACTION BIT(0)
686
687/* wl127x and SPI don't support SDIO block size alignment */
688#define WL12XX_QUIRK_NO_BLOCKSIZE_ALIGNMENT BIT(2)
689
690/* Older firmwares did not implement the FW logger over bus feature */
691#define WL12XX_QUIRK_FWLOG_NOT_IMPLEMENTED BIT(4)
692
693#define WL12XX_HW_BLOCK_SIZE 256 464#define WL12XX_HW_BLOCK_SIZE 256
694 465
695#endif 466#endif
diff --git a/drivers/net/wireless/wl12xx/wl12xx_80211.h b/drivers/net/wireless/ti/wlcore/wl12xx_80211.h
index 22b0bc98d7b5..22b0bc98d7b5 100644
--- a/drivers/net/wireless/wl12xx/wl12xx_80211.h
+++ b/drivers/net/wireless/ti/wlcore/wl12xx_80211.h
diff --git a/drivers/net/wireless/wl12xx/wl12xx_platform_data.c b/drivers/net/wireless/ti/wlcore/wl12xx_platform_data.c
index 998e95895f9d..998e95895f9d 100644
--- a/drivers/net/wireless/wl12xx/wl12xx_platform_data.c
+++ b/drivers/net/wireless/ti/wlcore/wl12xx_platform_data.c
diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h
new file mode 100644
index 000000000000..39f9fadfebd9
--- /dev/null
+++ b/drivers/net/wireless/ti/wlcore/wlcore.h
@@ -0,0 +1,448 @@
1/*
2 * This file is part of wlcore
3 *
4 * Copyright (C) 2011 Texas Instruments Inc.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18 * 02110-1301 USA
19 *
20 */
21
22#ifndef __WLCORE_H__
23#define __WLCORE_H__
24
25#include <linux/platform_device.h>
26
27#include "wl12xx.h"
28#include "event.h"
29
30/* The maximum number of Tx descriptors in all chip families */
31#define WLCORE_MAX_TX_DESCRIPTORS 32
32
33/* forward declaration */
34struct wl1271_tx_hw_descr;
35enum wl_rx_buf_align;
36
37struct wlcore_ops {
38 int (*identify_chip)(struct wl1271 *wl);
39 int (*identify_fw)(struct wl1271 *wl);
40 int (*boot)(struct wl1271 *wl);
41 void (*trigger_cmd)(struct wl1271 *wl, int cmd_box_addr,
42 void *buf, size_t len);
43 void (*ack_event)(struct wl1271 *wl);
44 u32 (*calc_tx_blocks)(struct wl1271 *wl, u32 len, u32 spare_blks);
45 void (*set_tx_desc_blocks)(struct wl1271 *wl,
46 struct wl1271_tx_hw_descr *desc,
47 u32 blks, u32 spare_blks);
48 void (*set_tx_desc_data_len)(struct wl1271 *wl,
49 struct wl1271_tx_hw_descr *desc,
50 struct sk_buff *skb);
51 enum wl_rx_buf_align (*get_rx_buf_align)(struct wl1271 *wl,
52 u32 rx_desc);
53 void (*prepare_read)(struct wl1271 *wl, u32 rx_desc, u32 len);
54 u32 (*get_rx_packet_len)(struct wl1271 *wl, void *rx_data,
55 u32 data_len);
56 void (*tx_delayed_compl)(struct wl1271 *wl);
57 void (*tx_immediate_compl)(struct wl1271 *wl);
58 int (*hw_init)(struct wl1271 *wl);
59 int (*init_vif)(struct wl1271 *wl, struct wl12xx_vif *wlvif);
60 u32 (*sta_get_ap_rate_mask)(struct wl1271 *wl,
61 struct wl12xx_vif *wlvif);
62 s8 (*get_pg_ver)(struct wl1271 *wl);
63 void (*get_mac)(struct wl1271 *wl);
64};
65
66enum wlcore_partitions {
67 PART_DOWN,
68 PART_WORK,
69 PART_BOOT,
70 PART_DRPW,
71 PART_TOP_PRCM_ELP_SOC,
72 PART_PHY_INIT,
73
74 PART_TABLE_LEN,
75};
76
77struct wlcore_partition {
78 u32 size;
79 u32 start;
80};
81
82struct wlcore_partition_set {
83 struct wlcore_partition mem;
84 struct wlcore_partition reg;
85 struct wlcore_partition mem2;
86 struct wlcore_partition mem3;
87};
88
89enum wlcore_registers {
90 /* register addresses, used with partition translation */
91 REG_ECPU_CONTROL,
92 REG_INTERRUPT_NO_CLEAR,
93 REG_INTERRUPT_ACK,
94 REG_COMMAND_MAILBOX_PTR,
95 REG_EVENT_MAILBOX_PTR,
96 REG_INTERRUPT_TRIG,
97 REG_INTERRUPT_MASK,
98 REG_PC_ON_RECOVERY,
99 REG_CHIP_ID_B,
100 REG_CMD_MBOX_ADDRESS,
101
102 /* data access memory addresses, used with partition translation */
103 REG_SLV_MEM_DATA,
104 REG_SLV_REG_DATA,
105
106 /* raw data access memory addresses */
107 REG_RAW_FW_STATUS_ADDR,
108
109 REG_TABLE_LEN,
110};
111
112struct wl1271 {
113 struct ieee80211_hw *hw;
114 bool mac80211_registered;
115
116 struct device *dev;
117
118 void *if_priv;
119
120 struct wl1271_if_operations *if_ops;
121
122 void (*set_power)(bool enable);
123 int irq;
124 int ref_clock;
125
126 spinlock_t wl_lock;
127
128 enum wl1271_state state;
129 enum wl12xx_fw_type fw_type;
130 bool plt;
131 u8 last_vif_count;
132 struct mutex mutex;
133
134 unsigned long flags;
135
136 struct wlcore_partition_set curr_part;
137
138 struct wl1271_chip chip;
139
140 int cmd_box_addr;
141
142 u8 *fw;
143 size_t fw_len;
144 void *nvs;
145 size_t nvs_len;
146
147 s8 hw_pg_ver;
148
149 /* address read from the fuse ROM */
150 u32 fuse_oui_addr;
151 u32 fuse_nic_addr;
152
153 /* we have up to 2 MAC addresses */
154 struct mac_address addresses[2];
155 int channel;
156 u8 system_hlid;
157
158 unsigned long links_map[BITS_TO_LONGS(WL12XX_MAX_LINKS)];
159 unsigned long roles_map[BITS_TO_LONGS(WL12XX_MAX_ROLES)];
160 unsigned long roc_map[BITS_TO_LONGS(WL12XX_MAX_ROLES)];
161 unsigned long rate_policies_map[
162 BITS_TO_LONGS(WL12XX_MAX_RATE_POLICIES)];
163
164 struct list_head wlvif_list;
165
166 u8 sta_count;
167 u8 ap_count;
168
169 struct wl1271_acx_mem_map *target_mem_map;
170
171 /* Accounting for allocated / available TX blocks on HW */
172 u32 tx_blocks_freed;
173 u32 tx_blocks_available;
174 u32 tx_allocated_blocks;
175 u32 tx_results_count;
176
177 /* Accounting for allocated / available Tx packets in HW */
178 u32 tx_pkts_freed[NUM_TX_QUEUES];
179 u32 tx_allocated_pkts[NUM_TX_QUEUES];
180
181 /* Transmitted TX packets counter for chipset interface */
182 u32 tx_packets_count;
183
184 /* Time-offset between host and chipset clocks */
185 s64 time_offset;
186
187 /* Frames scheduled for transmission, not handled yet */
188 int tx_queue_count[NUM_TX_QUEUES];
189 long stopped_queues_map;
190
191 /* Frames received, not handled yet by mac80211 */
192 struct sk_buff_head deferred_rx_queue;
193
194 /* Frames sent, not returned yet to mac80211 */
195 struct sk_buff_head deferred_tx_queue;
196
197 struct work_struct tx_work;
198 struct workqueue_struct *freezable_wq;
199
200 /* Pending TX frames */
201 unsigned long tx_frames_map[BITS_TO_LONGS(WLCORE_MAX_TX_DESCRIPTORS)];
202 struct sk_buff *tx_frames[WLCORE_MAX_TX_DESCRIPTORS];
203 int tx_frames_cnt;
204
205 /* FW Rx counter */
206 u32 rx_counter;
207
208 /* Rx memory pool address */
209 struct wl1271_rx_mem_pool_addr rx_mem_pool_addr;
210
211 /* Intermediate buffer, used for packet aggregation */
212 u8 *aggr_buf;
213
214 /* Reusable dummy packet template */
215 struct sk_buff *dummy_packet;
216
217 /* Network stack work */
218 struct work_struct netstack_work;
219
220 /* FW log buffer */
221 u8 *fwlog;
222
223 /* Number of valid bytes in the FW log buffer */
224 ssize_t fwlog_size;
225
226 /* Sysfs FW log entry readers wait queue */
227 wait_queue_head_t fwlog_waitq;
228
229 /* Hardware recovery work */
230 struct work_struct recovery_work;
231
232 /* Pointer that holds DMA-friendly block for the mailbox */
233 struct event_mailbox *mbox;
234
235 /* The mbox event mask */
236 u32 event_mask;
237
238 /* Mailbox pointers */
239 u32 mbox_ptr[2];
240
241 /* Are we currently scanning */
242 struct ieee80211_vif *scan_vif;
243 struct wl1271_scan scan;
244 struct delayed_work scan_complete_work;
245
246 bool sched_scanning;
247
248 /* The current band */
249 enum ieee80211_band band;
250
251 struct completion *elp_compl;
252 struct delayed_work elp_work;
253
254 /* in dBm */
255 int power_level;
256
257 struct wl1271_stats stats;
258
259 __le32 buffer_32;
260 u32 buffer_cmd;
261 u32 buffer_busyword[WL1271_BUSY_WORD_CNT];
262
263 struct wl_fw_status *fw_status;
264 struct wl1271_tx_hw_res_if *tx_res_if;
265
266 /* Current chipset configuration */
267 struct wlcore_conf conf;
268
269 bool sg_enabled;
270
271 bool enable_11a;
272
273 /* Most recently reported noise in dBm */
274 s8 noise;
275
276 /* bands supported by this instance of wl12xx */
277 struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS];
278
279 int tcxo_clock;
280
281 /*
282 * wowlan trigger was configured during suspend.
283 * (currently, only "ANY" trigger is supported)
284 */
285 bool wow_enabled;
286 bool irq_wake_enabled;
287
288 /*
289 * AP-mode - links indexed by HLID. The global and broadcast links
290 * are always active.
291 */
292 struct wl1271_link links[WL12XX_MAX_LINKS];
293
294 /* AP-mode - a bitmap of links currently in PS mode according to FW */
295 u32 ap_fw_ps_map;
296
297 /* AP-mode - a bitmap of links currently in PS mode in mac80211 */
298 unsigned long ap_ps_map;
299
300 /* Quirks of specific hardware revisions */
301 unsigned int quirks;
302
303 /* Platform limitations */
304 unsigned int platform_quirks;
305
306 /* number of currently active RX BA sessions */
307 int ba_rx_session_count;
308
309 /* AP-mode - number of currently connected stations */
310 int active_sta_count;
311
312 /* last wlvif we transmitted from */
313 struct wl12xx_vif *last_wlvif;
314
315 /* work to fire when Tx is stuck */
316 struct delayed_work tx_watchdog_work;
317
318 struct wlcore_ops *ops;
319 /* pointer to the lower driver partition table */
320 const struct wlcore_partition_set *ptable;
321 /* pointer to the lower driver register table */
322 const int *rtable;
323 /* name of the firmwares to load - for PLT, single role, multi-role */
324 const char *plt_fw_name;
325 const char *sr_fw_name;
326 const char *mr_fw_name;
327
328 /* per-chip-family private structure */
329 void *priv;
330
331 /* number of TX descriptors the HW supports. */
332 u32 num_tx_desc;
333
334 /* spare Tx blocks for normal/GEM operating modes */
335 u32 normal_tx_spare;
336 u32 gem_tx_spare;
337
338 /* translate HW Tx rates to standard rate-indices */
339 const u8 **band_rate_to_idx;
340
341 /* size of table for HW rates that can be received from chip */
342 u8 hw_tx_rate_tbl_size;
343
344 /* this HW rate and below are considered HT rates for this chip */
345 u8 hw_min_ht_rate;
346
347 /* HW HT (11n) capabilities */
348 struct ieee80211_sta_ht_cap ht_cap;
349
350 /* size of the private FW status data */
351 size_t fw_status_priv_len;
352};
353
354int __devinit wlcore_probe(struct wl1271 *wl, struct platform_device *pdev);
355int __devexit wlcore_remove(struct platform_device *pdev);
356struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size);
357int wlcore_free_hw(struct wl1271 *wl);
358
359/* Firmware image load chunk size */
360#define CHUNK_SIZE 16384
361
362/* Quirks */
363
364/* Each RX/TX transaction requires an end-of-transaction transfer */
365#define WLCORE_QUIRK_END_OF_TRANSACTION BIT(0)
366
367/* wl127x and SPI don't support SDIO block size alignment */
368#define WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN BIT(2)
369
370/* means aggregated Rx packets are aligned to a SDIO block */
371#define WLCORE_QUIRK_RX_BLOCKSIZE_ALIGN BIT(3)
372
373/* Older firmwares did not implement the FW logger over bus feature */
374#define WLCORE_QUIRK_FWLOG_NOT_IMPLEMENTED BIT(4)
375
376/* Older firmwares use an old NVS format */
377#define WLCORE_QUIRK_LEGACY_NVS BIT(5)
378
379/* Some firmwares may not support ELP */
380#define WLCORE_QUIRK_NO_ELP BIT(6)
381
382/* TODO: move to the lower drivers when all usages are abstracted */
383#define CHIP_ID_1271_PG10 (0x4030101)
384#define CHIP_ID_1271_PG20 (0x4030111)
385#define CHIP_ID_1283_PG10 (0x05030101)
386#define CHIP_ID_1283_PG20 (0x05030111)
387
388/* TODO: move all these common registers and values elsewhere */
389#define HW_ACCESS_ELP_CTRL_REG 0x1FFFC
390
391/* ELP register commands */
392#define ELPCTRL_WAKE_UP 0x1
393#define ELPCTRL_WAKE_UP_WLAN_READY 0x5
394#define ELPCTRL_SLEEP 0x0
395/* ELP WLAN_READY bit */
396#define ELPCTRL_WLAN_READY 0x2
397
398/*************************************************************************
399
400 Interrupt Trigger Register (Host -> WiLink)
401
402**************************************************************************/
403
404/* Hardware to Embedded CPU Interrupts - first 32-bit register set */
405
406/*
407 * The host sets this bit to inform the Wlan
408 * FW that a TX packet is in the XFER
409 * Buffer #0.
410 */
411#define INTR_TRIG_TX_PROC0 BIT(2)
412
413/*
414 * The host sets this bit to inform the FW
415 * that it read a packet from RX XFER
416 * Buffer #0.
417 */
418#define INTR_TRIG_RX_PROC0 BIT(3)
419
420#define INTR_TRIG_DEBUG_ACK BIT(4)
421
422#define INTR_TRIG_STATE_CHANGED BIT(5)
423
424/* Hardware to Embedded CPU Interrupts - second 32-bit register set */
425
426/*
427 * The host sets this bit to inform the FW
428 * that it read a packet from RX XFER
429 * Buffer #1.
430 */
431#define INTR_TRIG_RX_PROC1 BIT(17)
432
433/*
434 * The host sets this bit to inform the Wlan
435 * hardware that a TX packet is in the XFER
436 * Buffer #1.
437 */
438#define INTR_TRIG_TX_PROC1 BIT(18)
439
440#define ACX_SLV_SOFT_RESET_BIT BIT(1)
441#define SOFT_RESET_MAX_TIME 1000000
442#define SOFT_RESET_STALL_TIME 1000
443
444#define ECPU_CONTROL_HALT 0x00000101
445
446#define WELP_ARM_COMMAND_VAL 0x4
447
448#endif /* __WLCORE_H__ */
diff --git a/drivers/net/wireless/wl12xx/Kconfig b/drivers/net/wireless/wl12xx/Kconfig
deleted file mode 100644
index af08c8609c63..000000000000
--- a/drivers/net/wireless/wl12xx/Kconfig
+++ /dev/null
@@ -1,48 +0,0 @@
1menuconfig WL12XX_MENU
2 tristate "TI wl12xx driver support"
3 depends on MAC80211 && EXPERIMENTAL
4 ---help---
5 This will enable TI wl12xx driver support for the following chips:
6 wl1271, wl1273, wl1281 and wl1283.
7 The drivers make use of the mac80211 stack.
8
9config WL12XX
10 tristate "TI wl12xx support"
11 depends on WL12XX_MENU && GENERIC_HARDIRQS
12 depends on INET
13 select FW_LOADER
14 ---help---
15 This module adds support for wireless adapters based on TI wl1271 and
16 TI wl1273 chipsets. This module does *not* include support for wl1251.
17 For wl1251 support, use the separate homonymous driver instead.
18
19 If you choose to build a module, it will be called wl12xx. Say N if
20 unsure.
21
22config WL12XX_SPI
23 tristate "TI wl12xx SPI support"
24 depends on WL12XX && SPI_MASTER
25 select CRC7
26 ---help---
27 This module adds support for the SPI interface of adapters using
28 TI wl12xx chipsets. Select this if your platform is using
29 the SPI bus.
30
31 If you choose to build a module, it'll be called wl12xx_spi.
32 Say N if unsure.
33
34config WL12XX_SDIO
35 tristate "TI wl12xx SDIO support"
36 depends on WL12XX && MMC
37 ---help---
38 This module adds support for the SDIO interface of adapters using
39 TI wl12xx chipsets. Select this if your platform is using
40 the SDIO bus.
41
42 If you choose to build a module, it'll be called wl12xx_sdio.
43 Say N if unsure.
44
45config WL12XX_PLATFORM_DATA
46 bool
47 depends on WL12XX_SDIO != n || WL1251_SDIO != n
48 default y
diff --git a/drivers/net/wireless/wl12xx/Makefile b/drivers/net/wireless/wl12xx/Makefile
deleted file mode 100644
index 98f289c907a9..000000000000
--- a/drivers/net/wireless/wl12xx/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
1wl12xx-objs = main.o cmd.o io.o event.o tx.o rx.o ps.o acx.o \
2 boot.o init.o debugfs.o scan.o
3
4wl12xx_spi-objs = spi.o
5wl12xx_sdio-objs = sdio.o
6
7wl12xx-$(CONFIG_NL80211_TESTMODE) += testmode.o
8obj-$(CONFIG_WL12XX) += wl12xx.o
9obj-$(CONFIG_WL12XX_SPI) += wl12xx_spi.o
10obj-$(CONFIG_WL12XX_SDIO) += wl12xx_sdio.o
11
12# small builtin driver bit
13obj-$(CONFIG_WL12XX_PLATFORM_DATA) += wl12xx_platform_data.o
14
15ccflags-y += -D__CHECK_ENDIAN__
diff --git a/drivers/net/wireless/wl12xx/boot.c b/drivers/net/wireless/wl12xx/boot.c
deleted file mode 100644
index 954101d03f06..000000000000
--- a/drivers/net/wireless/wl12xx/boot.c
+++ /dev/null
@@ -1,786 +0,0 @@
1/*
2 * This file is part of wl1271
3 *
4 * Copyright (C) 2008-2010 Nokia Corporation
5 *
6 * Contact: Luciano Coelho <luciano.coelho@nokia.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 */
23
24#include <linux/slab.h>
25#include <linux/wl12xx.h>
26#include <linux/export.h>
27
28#include "debug.h"
29#include "acx.h"
30#include "reg.h"
31#include "boot.h"
32#include "io.h"
33#include "event.h"
34#include "rx.h"
35
36static void wl1271_boot_set_ecpu_ctrl(struct wl1271 *wl, u32 flag)
37{
38 u32 cpu_ctrl;
39
40 /* 10.5.0 run the firmware (I) */
41 cpu_ctrl = wl1271_read32(wl, ACX_REG_ECPU_CONTROL);
42
43 /* 10.5.1 run the firmware (II) */
44 cpu_ctrl |= flag;
45 wl1271_write32(wl, ACX_REG_ECPU_CONTROL, cpu_ctrl);
46}
47
48static unsigned int wl12xx_get_fw_ver_quirks(struct wl1271 *wl)
49{
50 unsigned int quirks = 0;
51 unsigned int *fw_ver = wl->chip.fw_ver;
52
53 /* Only new station firmwares support routing fw logs to the host */
54 if ((fw_ver[FW_VER_IF_TYPE] == FW_VER_IF_TYPE_STA) &&
55 (fw_ver[FW_VER_MINOR] < FW_VER_MINOR_FWLOG_STA_MIN))
56 quirks |= WL12XX_QUIRK_FWLOG_NOT_IMPLEMENTED;
57
58 /* This feature is not yet supported for AP mode */
59 if (fw_ver[FW_VER_IF_TYPE] == FW_VER_IF_TYPE_AP)
60 quirks |= WL12XX_QUIRK_FWLOG_NOT_IMPLEMENTED;
61
62 return quirks;
63}
64
65static void wl1271_parse_fw_ver(struct wl1271 *wl)
66{
67 int ret;
68
69 ret = sscanf(wl->chip.fw_ver_str + 4, "%u.%u.%u.%u.%u",
70 &wl->chip.fw_ver[0], &wl->chip.fw_ver[1],
71 &wl->chip.fw_ver[2], &wl->chip.fw_ver[3],
72 &wl->chip.fw_ver[4]);
73
74 if (ret != 5) {
75 wl1271_warning("fw version incorrect value");
76 memset(wl->chip.fw_ver, 0, sizeof(wl->chip.fw_ver));
77 return;
78 }
79
80 /* Check if any quirks are needed with older fw versions */
81 wl->quirks |= wl12xx_get_fw_ver_quirks(wl);
82}
83
84static void wl1271_boot_fw_version(struct wl1271 *wl)
85{
86 struct wl1271_static_data static_data;
87
88 wl1271_read(wl, wl->cmd_box_addr, &static_data, sizeof(static_data),
89 false);
90
91 strncpy(wl->chip.fw_ver_str, static_data.fw_version,
92 sizeof(wl->chip.fw_ver_str));
93
94 /* make sure the string is NULL-terminated */
95 wl->chip.fw_ver_str[sizeof(wl->chip.fw_ver_str) - 1] = '\0';
96
97 wl1271_parse_fw_ver(wl);
98}
99
100static int wl1271_boot_upload_firmware_chunk(struct wl1271 *wl, void *buf,
101 size_t fw_data_len, u32 dest)
102{
103 struct wl1271_partition_set partition;
104 int addr, chunk_num, partition_limit;
105 u8 *p, *chunk;
106
107 /* whal_FwCtrl_LoadFwImageSm() */
108
109 wl1271_debug(DEBUG_BOOT, "starting firmware upload");
110
111 wl1271_debug(DEBUG_BOOT, "fw_data_len %zd chunk_size %d",
112 fw_data_len, CHUNK_SIZE);
113
114 if ((fw_data_len % 4) != 0) {
115 wl1271_error("firmware length not multiple of four");
116 return -EIO;
117 }
118
119 chunk = kmalloc(CHUNK_SIZE, GFP_KERNEL);
120 if (!chunk) {
121 wl1271_error("allocation for firmware upload chunk failed");
122 return -ENOMEM;
123 }
124
125 memcpy(&partition, &wl12xx_part_table[PART_DOWN], sizeof(partition));
126 partition.mem.start = dest;
127 wl1271_set_partition(wl, &partition);
128
129 /* 10.1 set partition limit and chunk num */
130 chunk_num = 0;
131 partition_limit = wl12xx_part_table[PART_DOWN].mem.size;
132
133 while (chunk_num < fw_data_len / CHUNK_SIZE) {
134 /* 10.2 update partition, if needed */
135 addr = dest + (chunk_num + 2) * CHUNK_SIZE;
136 if (addr > partition_limit) {
137 addr = dest + chunk_num * CHUNK_SIZE;
138 partition_limit = chunk_num * CHUNK_SIZE +
139 wl12xx_part_table[PART_DOWN].mem.size;
140 partition.mem.start = addr;
141 wl1271_set_partition(wl, &partition);
142 }
143
144 /* 10.3 upload the chunk */
145 addr = dest + chunk_num * CHUNK_SIZE;
146 p = buf + chunk_num * CHUNK_SIZE;
147 memcpy(chunk, p, CHUNK_SIZE);
148 wl1271_debug(DEBUG_BOOT, "uploading fw chunk 0x%p to 0x%x",
149 p, addr);
150 wl1271_write(wl, addr, chunk, CHUNK_SIZE, false);
151
152 chunk_num++;
153 }
154
155 /* 10.4 upload the last chunk */
156 addr = dest + chunk_num * CHUNK_SIZE;
157 p = buf + chunk_num * CHUNK_SIZE;
158 memcpy(chunk, p, fw_data_len % CHUNK_SIZE);
159 wl1271_debug(DEBUG_BOOT, "uploading fw last chunk (%zd B) 0x%p to 0x%x",
160 fw_data_len % CHUNK_SIZE, p, addr);
161 wl1271_write(wl, addr, chunk, fw_data_len % CHUNK_SIZE, false);
162
163 kfree(chunk);
164 return 0;
165}
166
167static int wl1271_boot_upload_firmware(struct wl1271 *wl)
168{
169 u32 chunks, addr, len;
170 int ret = 0;
171 u8 *fw;
172
173 fw = wl->fw;
174 chunks = be32_to_cpup((__be32 *) fw);
175 fw += sizeof(u32);
176
177 wl1271_debug(DEBUG_BOOT, "firmware chunks to be uploaded: %u", chunks);
178
179 while (chunks--) {
180 addr = be32_to_cpup((__be32 *) fw);
181 fw += sizeof(u32);
182 len = be32_to_cpup((__be32 *) fw);
183 fw += sizeof(u32);
184
185 if (len > 300000) {
186 wl1271_info("firmware chunk too long: %u", len);
187 return -EINVAL;
188 }
189 wl1271_debug(DEBUG_BOOT, "chunk %d addr 0x%x len %u",
190 chunks, addr, len);
191 ret = wl1271_boot_upload_firmware_chunk(wl, fw, len, addr);
192 if (ret != 0)
193 break;
194 fw += len;
195 }
196
197 return ret;
198}
199
200static int wl1271_boot_upload_nvs(struct wl1271 *wl)
201{
202 size_t nvs_len, burst_len;
203 int i;
204 u32 dest_addr, val;
205 u8 *nvs_ptr, *nvs_aligned;
206
207 if (wl->nvs == NULL)
208 return -ENODEV;
209
210 if (wl->chip.id == CHIP_ID_1283_PG20) {
211 struct wl128x_nvs_file *nvs = (struct wl128x_nvs_file *)wl->nvs;
212
213 if (wl->nvs_len == sizeof(struct wl128x_nvs_file)) {
214 if (nvs->general_params.dual_mode_select)
215 wl->enable_11a = true;
216 } else {
217 wl1271_error("nvs size is not as expected: %zu != %zu",
218 wl->nvs_len,
219 sizeof(struct wl128x_nvs_file));
220 kfree(wl->nvs);
221 wl->nvs = NULL;
222 wl->nvs_len = 0;
223 return -EILSEQ;
224 }
225
226 /* only the first part of the NVS needs to be uploaded */
227 nvs_len = sizeof(nvs->nvs);
228 nvs_ptr = (u8 *)nvs->nvs;
229
230 } else {
231 struct wl1271_nvs_file *nvs =
232 (struct wl1271_nvs_file *)wl->nvs;
233 /*
234 * FIXME: the LEGACY NVS image support (NVS's missing the 5GHz
235 * band configurations) can be removed when those NVS files stop
236 * floating around.
237 */
238 if (wl->nvs_len == sizeof(struct wl1271_nvs_file) ||
239 wl->nvs_len == WL1271_INI_LEGACY_NVS_FILE_SIZE) {
240 if (nvs->general_params.dual_mode_select)
241 wl->enable_11a = true;
242 }
243
244 if (wl->nvs_len != sizeof(struct wl1271_nvs_file) &&
245 (wl->nvs_len != WL1271_INI_LEGACY_NVS_FILE_SIZE ||
246 wl->enable_11a)) {
247 wl1271_error("nvs size is not as expected: %zu != %zu",
248 wl->nvs_len, sizeof(struct wl1271_nvs_file));
249 kfree(wl->nvs);
250 wl->nvs = NULL;
251 wl->nvs_len = 0;
252 return -EILSEQ;
253 }
254
255 /* only the first part of the NVS needs to be uploaded */
256 nvs_len = sizeof(nvs->nvs);
257 nvs_ptr = (u8 *) nvs->nvs;
258 }
259
260 /* update current MAC address to NVS */
261 nvs_ptr[11] = wl->addresses[0].addr[0];
262 nvs_ptr[10] = wl->addresses[0].addr[1];
263 nvs_ptr[6] = wl->addresses[0].addr[2];
264 nvs_ptr[5] = wl->addresses[0].addr[3];
265 nvs_ptr[4] = wl->addresses[0].addr[4];
266 nvs_ptr[3] = wl->addresses[0].addr[5];
267
268 /*
269 * Layout before the actual NVS tables:
270 * 1 byte : burst length.
271 * 2 bytes: destination address.
272 * n bytes: data to burst copy.
273 *
274 * This is ended by a 0 length, then the NVS tables.
275 */
276
277 /* FIXME: Do we need to check here whether the LSB is 1? */
278 while (nvs_ptr[0]) {
279 burst_len = nvs_ptr[0];
280 dest_addr = (nvs_ptr[1] & 0xfe) | ((u32)(nvs_ptr[2] << 8));
281
282 /*
283 * Due to our new wl1271_translate_reg_addr function,
284 * we need to add the REGISTER_BASE to the destination
285 */
286 dest_addr += REGISTERS_BASE;
287
288 /* We move our pointer to the data */
289 nvs_ptr += 3;
290
291 for (i = 0; i < burst_len; i++) {
292 if (nvs_ptr + 3 >= (u8 *) wl->nvs + nvs_len)
293 goto out_badnvs;
294
295 val = (nvs_ptr[0] | (nvs_ptr[1] << 8)
296 | (nvs_ptr[2] << 16) | (nvs_ptr[3] << 24));
297
298 wl1271_debug(DEBUG_BOOT,
299 "nvs burst write 0x%x: 0x%x",
300 dest_addr, val);
301 wl1271_write32(wl, dest_addr, val);
302
303 nvs_ptr += 4;
304 dest_addr += 4;
305 }
306
307 if (nvs_ptr >= (u8 *) wl->nvs + nvs_len)
308 goto out_badnvs;
309 }
310
311 /*
312 * We've reached the first zero length, the first NVS table
313 * is located at an aligned offset which is at least 7 bytes further.
314 * NOTE: The wl->nvs->nvs element must be first, in order to
315 * simplify the casting, we assume it is at the beginning of
316 * the wl->nvs structure.
317 */
318 nvs_ptr = (u8 *)wl->nvs +
319 ALIGN(nvs_ptr - (u8 *)wl->nvs + 7, 4);
320
321 if (nvs_ptr >= (u8 *) wl->nvs + nvs_len)
322 goto out_badnvs;
323
324 nvs_len -= nvs_ptr - (u8 *)wl->nvs;
325
326 /* Now we must set the partition correctly */
327 wl1271_set_partition(wl, &wl12xx_part_table[PART_WORK]);
328
329 /* Copy the NVS tables to a new block to ensure alignment */
330 nvs_aligned = kmemdup(nvs_ptr, nvs_len, GFP_KERNEL);
331 if (!nvs_aligned)
332 return -ENOMEM;
333
334 /* And finally we upload the NVS tables */
335 wl1271_write(wl, CMD_MBOX_ADDRESS, nvs_aligned, nvs_len, false);
336
337 kfree(nvs_aligned);
338 return 0;
339
340out_badnvs:
341 wl1271_error("nvs data is malformed");
342 return -EILSEQ;
343}
344
345static void wl1271_boot_enable_interrupts(struct wl1271 *wl)
346{
347 wl1271_enable_interrupts(wl);
348 wl1271_write32(wl, ACX_REG_INTERRUPT_MASK,
349 WL1271_ACX_INTR_ALL & ~(WL1271_INTR_MASK));
350 wl1271_write32(wl, HI_CFG, HI_CFG_DEF_VAL);
351}
352
353static int wl1271_boot_soft_reset(struct wl1271 *wl)
354{
355 unsigned long timeout;
356 u32 boot_data;
357
358 /* perform soft reset */
359 wl1271_write32(wl, ACX_REG_SLV_SOFT_RESET, ACX_SLV_SOFT_RESET_BIT);
360
361 /* SOFT_RESET is self clearing */
362 timeout = jiffies + usecs_to_jiffies(SOFT_RESET_MAX_TIME);
363 while (1) {
364 boot_data = wl1271_read32(wl, ACX_REG_SLV_SOFT_RESET);
365 wl1271_debug(DEBUG_BOOT, "soft reset bootdata 0x%x", boot_data);
366 if ((boot_data & ACX_SLV_SOFT_RESET_BIT) == 0)
367 break;
368
369 if (time_after(jiffies, timeout)) {
370 /* 1.2 check pWhalBus->uSelfClearTime if the
371 * timeout was reached */
372 wl1271_error("soft reset timeout");
373 return -1;
374 }
375
376 udelay(SOFT_RESET_STALL_TIME);
377 }
378
379 /* disable Rx/Tx */
380 wl1271_write32(wl, ENABLE, 0x0);
381
382 /* disable auto calibration on start*/
383 wl1271_write32(wl, SPARE_A2, 0xffff);
384
385 return 0;
386}
387
388static int wl1271_boot_run_firmware(struct wl1271 *wl)
389{
390 int loop, ret;
391 u32 chip_id, intr;
392
393 wl1271_boot_set_ecpu_ctrl(wl, ECPU_CONTROL_HALT);
394
395 chip_id = wl1271_read32(wl, CHIP_ID_B);
396
397 wl1271_debug(DEBUG_BOOT, "chip id after firmware boot: 0x%x", chip_id);
398
399 if (chip_id != wl->chip.id) {
400 wl1271_error("chip id doesn't match after firmware boot");
401 return -EIO;
402 }
403
404 /* wait for init to complete */
405 loop = 0;
406 while (loop++ < INIT_LOOP) {
407 udelay(INIT_LOOP_DELAY);
408 intr = wl1271_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR);
409
410 if (intr == 0xffffffff) {
411 wl1271_error("error reading hardware complete "
412 "init indication");
413 return -EIO;
414 }
415 /* check that ACX_INTR_INIT_COMPLETE is enabled */
416 else if (intr & WL1271_ACX_INTR_INIT_COMPLETE) {
417 wl1271_write32(wl, ACX_REG_INTERRUPT_ACK,
418 WL1271_ACX_INTR_INIT_COMPLETE);
419 break;
420 }
421 }
422
423 if (loop > INIT_LOOP) {
424 wl1271_error("timeout waiting for the hardware to "
425 "complete initialization");
426 return -EIO;
427 }
428
429 /* get hardware config command mail box */
430 wl->cmd_box_addr = wl1271_read32(wl, REG_COMMAND_MAILBOX_PTR);
431
432 /* get hardware config event mail box */
433 wl->event_box_addr = wl1271_read32(wl, REG_EVENT_MAILBOX_PTR);
434
435 /* set the working partition to its "running" mode offset */
436 wl1271_set_partition(wl, &wl12xx_part_table[PART_WORK]);
437
438 wl1271_debug(DEBUG_MAILBOX, "cmd_box_addr 0x%x event_box_addr 0x%x",
439 wl->cmd_box_addr, wl->event_box_addr);
440
441 wl1271_boot_fw_version(wl);
442
443 /*
444 * in case of full asynchronous mode the firmware event must be
445 * ready to receive event from the command mailbox
446 */
447
448 /* unmask required mbox events */
449 wl->event_mask = BSS_LOSE_EVENT_ID |
450 SCAN_COMPLETE_EVENT_ID |
451 ROLE_STOP_COMPLETE_EVENT_ID |
452 RSSI_SNR_TRIGGER_0_EVENT_ID |
453 PSPOLL_DELIVERY_FAILURE_EVENT_ID |
454 SOFT_GEMINI_SENSE_EVENT_ID |
455 PERIODIC_SCAN_REPORT_EVENT_ID |
456 PERIODIC_SCAN_COMPLETE_EVENT_ID |
457 DUMMY_PACKET_EVENT_ID |
458 PEER_REMOVE_COMPLETE_EVENT_ID |
459 BA_SESSION_RX_CONSTRAINT_EVENT_ID |
460 REMAIN_ON_CHANNEL_COMPLETE_EVENT_ID |
461 INACTIVE_STA_EVENT_ID |
462 MAX_TX_RETRY_EVENT_ID |
463 CHANNEL_SWITCH_COMPLETE_EVENT_ID;
464
465 ret = wl1271_event_unmask(wl);
466 if (ret < 0) {
467 wl1271_error("EVENT mask setting failed");
468 return ret;
469 }
470
471 wl1271_event_mbox_config(wl);
472
473 /* firmware startup completed */
474 return 0;
475}
476
477static int wl1271_boot_write_irq_polarity(struct wl1271 *wl)
478{
479 u32 polarity;
480
481 polarity = wl1271_top_reg_read(wl, OCP_REG_POLARITY);
482
483 /* We use HIGH polarity, so unset the LOW bit */
484 polarity &= ~POLARITY_LOW;
485 wl1271_top_reg_write(wl, OCP_REG_POLARITY, polarity);
486
487 return 0;
488}
489
490static int wl128x_switch_tcxo_to_fref(struct wl1271 *wl)
491{
492 u16 spare_reg;
493
494 /* Mask bits [2] & [8:4] in the sys_clk_cfg register */
495 spare_reg = wl1271_top_reg_read(wl, WL_SPARE_REG);
496 if (spare_reg == 0xFFFF)
497 return -EFAULT;
498 spare_reg |= (BIT(3) | BIT(5) | BIT(6));
499 wl1271_top_reg_write(wl, WL_SPARE_REG, spare_reg);
500
501 /* Enable FREF_CLK_REQ & mux MCS and coex PLLs to FREF */
502 wl1271_top_reg_write(wl, SYS_CLK_CFG_REG,
503 WL_CLK_REQ_TYPE_PG2 | MCS_PLL_CLK_SEL_FREF);
504
505 /* Delay execution for 15msec, to let the HW settle */
506 mdelay(15);
507
508 return 0;
509}
510
511static bool wl128x_is_tcxo_valid(struct wl1271 *wl)
512{
513 u16 tcxo_detection;
514
515 tcxo_detection = wl1271_top_reg_read(wl, TCXO_CLK_DETECT_REG);
516 if (tcxo_detection & TCXO_DET_FAILED)
517 return false;
518
519 return true;
520}
521
522static bool wl128x_is_fref_valid(struct wl1271 *wl)
523{
524 u16 fref_detection;
525
526 fref_detection = wl1271_top_reg_read(wl, FREF_CLK_DETECT_REG);
527 if (fref_detection & FREF_CLK_DETECT_FAIL)
528 return false;
529
530 return true;
531}
532
533static int wl128x_manually_configure_mcs_pll(struct wl1271 *wl)
534{
535 wl1271_top_reg_write(wl, MCS_PLL_M_REG, MCS_PLL_M_REG_VAL);
536 wl1271_top_reg_write(wl, MCS_PLL_N_REG, MCS_PLL_N_REG_VAL);
537 wl1271_top_reg_write(wl, MCS_PLL_CONFIG_REG, MCS_PLL_CONFIG_REG_VAL);
538
539 return 0;
540}
541
542static int wl128x_configure_mcs_pll(struct wl1271 *wl, int clk)
543{
544 u16 spare_reg;
545 u16 pll_config;
546 u8 input_freq;
547
548 /* Mask bits [3:1] in the sys_clk_cfg register */
549 spare_reg = wl1271_top_reg_read(wl, WL_SPARE_REG);
550 if (spare_reg == 0xFFFF)
551 return -EFAULT;
552 spare_reg |= BIT(2);
553 wl1271_top_reg_write(wl, WL_SPARE_REG, spare_reg);
554
555 /* Handle special cases of the TCXO clock */
556 if (wl->tcxo_clock == WL12XX_TCXOCLOCK_16_8 ||
557 wl->tcxo_clock == WL12XX_TCXOCLOCK_33_6)
558 return wl128x_manually_configure_mcs_pll(wl);
559
560 /* Set the input frequency according to the selected clock source */
561 input_freq = (clk & 1) + 1;
562
563 pll_config = wl1271_top_reg_read(wl, MCS_PLL_CONFIG_REG);
564 if (pll_config == 0xFFFF)
565 return -EFAULT;
566 pll_config |= (input_freq << MCS_SEL_IN_FREQ_SHIFT);
567 pll_config |= MCS_PLL_ENABLE_HP;
568 wl1271_top_reg_write(wl, MCS_PLL_CONFIG_REG, pll_config);
569
570 return 0;
571}
572
573/*
574 * WL128x has two clocks input - TCXO and FREF.
575 * TCXO is the main clock of the device, while FREF is used to sync
576 * between the GPS and the cellular modem.
577 * In cases where TCXO is 32.736MHz or 16.368MHz, the FREF will be used
578 * as the WLAN/BT main clock.
579 */
580static int wl128x_boot_clk(struct wl1271 *wl, int *selected_clock)
581{
582 u16 sys_clk_cfg;
583
584 /* For XTAL-only modes, FREF will be used after switching from TCXO */
585 if (wl->ref_clock == WL12XX_REFCLOCK_26_XTAL ||
586 wl->ref_clock == WL12XX_REFCLOCK_38_XTAL) {
587 if (!wl128x_switch_tcxo_to_fref(wl))
588 return -EINVAL;
589 goto fref_clk;
590 }
591
592 /* Query the HW, to determine which clock source we should use */
593 sys_clk_cfg = wl1271_top_reg_read(wl, SYS_CLK_CFG_REG);
594 if (sys_clk_cfg == 0xFFFF)
595 return -EINVAL;
596 if (sys_clk_cfg & PRCM_CM_EN_MUX_WLAN_FREF)
597 goto fref_clk;
598
599 /* If TCXO is either 32.736MHz or 16.368MHz, switch to FREF */
600 if (wl->tcxo_clock == WL12XX_TCXOCLOCK_16_368 ||
601 wl->tcxo_clock == WL12XX_TCXOCLOCK_32_736) {
602 if (!wl128x_switch_tcxo_to_fref(wl))
603 return -EINVAL;
604 goto fref_clk;
605 }
606
607 /* TCXO clock is selected */
608 if (!wl128x_is_tcxo_valid(wl))
609 return -EINVAL;
610 *selected_clock = wl->tcxo_clock;
611 goto config_mcs_pll;
612
613fref_clk:
614 /* FREF clock is selected */
615 if (!wl128x_is_fref_valid(wl))
616 return -EINVAL;
617 *selected_clock = wl->ref_clock;
618
619config_mcs_pll:
620 return wl128x_configure_mcs_pll(wl, *selected_clock);
621}
622
623static int wl127x_boot_clk(struct wl1271 *wl)
624{
625 u32 pause;
626 u32 clk;
627
628 if (WL127X_PG_GET_MAJOR(wl->hw_pg_ver) < 3)
629 wl->quirks |= WL12XX_QUIRK_END_OF_TRANSACTION;
630
631 if (wl->ref_clock == CONF_REF_CLK_19_2_E ||
632 wl->ref_clock == CONF_REF_CLK_38_4_E ||
633 wl->ref_clock == CONF_REF_CLK_38_4_M_XTAL)
634 /* ref clk: 19.2/38.4/38.4-XTAL */
635 clk = 0x3;
636 else if (wl->ref_clock == CONF_REF_CLK_26_E ||
637 wl->ref_clock == CONF_REF_CLK_52_E)
638 /* ref clk: 26/52 */
639 clk = 0x5;
640 else
641 return -EINVAL;
642
643 if (wl->ref_clock != CONF_REF_CLK_19_2_E) {
644 u16 val;
645 /* Set clock type (open drain) */
646 val = wl1271_top_reg_read(wl, OCP_REG_CLK_TYPE);
647 val &= FREF_CLK_TYPE_BITS;
648 wl1271_top_reg_write(wl, OCP_REG_CLK_TYPE, val);
649
650 /* Set clock pull mode (no pull) */
651 val = wl1271_top_reg_read(wl, OCP_REG_CLK_PULL);
652 val |= NO_PULL;
653 wl1271_top_reg_write(wl, OCP_REG_CLK_PULL, val);
654 } else {
655 u16 val;
656 /* Set clock polarity */
657 val = wl1271_top_reg_read(wl, OCP_REG_CLK_POLARITY);
658 val &= FREF_CLK_POLARITY_BITS;
659 val |= CLK_REQ_OUTN_SEL;
660 wl1271_top_reg_write(wl, OCP_REG_CLK_POLARITY, val);
661 }
662
663 wl1271_write32(wl, PLL_PARAMETERS, clk);
664
665 pause = wl1271_read32(wl, PLL_PARAMETERS);
666
667 wl1271_debug(DEBUG_BOOT, "pause1 0x%x", pause);
668
669 pause &= ~(WU_COUNTER_PAUSE_VAL);
670 pause |= WU_COUNTER_PAUSE_VAL;
671 wl1271_write32(wl, WU_COUNTER_PAUSE, pause);
672
673 return 0;
674}
675
676/* uploads NVS and firmware */
677int wl1271_load_firmware(struct wl1271 *wl)
678{
679 int ret = 0;
680 u32 tmp, clk;
681 int selected_clock = -1;
682
683 if (wl->chip.id == CHIP_ID_1283_PG20) {
684 ret = wl128x_boot_clk(wl, &selected_clock);
685 if (ret < 0)
686 goto out;
687 } else {
688 ret = wl127x_boot_clk(wl);
689 if (ret < 0)
690 goto out;
691 }
692
693 /* Continue the ELP wake up sequence */
694 wl1271_write32(wl, WELP_ARM_COMMAND, WELP_ARM_COMMAND_VAL);
695 udelay(500);
696
697 wl1271_set_partition(wl, &wl12xx_part_table[PART_DRPW]);
698
699 /* Read-modify-write DRPW_SCRATCH_START register (see next state)
700 to be used by DRPw FW. The RTRIM value will be added by the FW
701 before taking DRPw out of reset */
702
703 wl1271_debug(DEBUG_BOOT, "DRPW_SCRATCH_START %08x", DRPW_SCRATCH_START);
704 clk = wl1271_read32(wl, DRPW_SCRATCH_START);
705
706 wl1271_debug(DEBUG_BOOT, "clk2 0x%x", clk);
707
708 if (wl->chip.id == CHIP_ID_1283_PG20) {
709 clk |= ((selected_clock & 0x3) << 1) << 4;
710 } else {
711 clk |= (wl->ref_clock << 1) << 4;
712 }
713
714 wl1271_write32(wl, DRPW_SCRATCH_START, clk);
715
716 wl1271_set_partition(wl, &wl12xx_part_table[PART_WORK]);
717
718 /* Disable interrupts */
719 wl1271_write32(wl, ACX_REG_INTERRUPT_MASK, WL1271_ACX_INTR_ALL);
720
721 ret = wl1271_boot_soft_reset(wl);
722 if (ret < 0)
723 goto out;
724
725 /* 2. start processing NVS file */
726 ret = wl1271_boot_upload_nvs(wl);
727 if (ret < 0)
728 goto out;
729
730 /* write firmware's last address (ie. it's length) to
731 * ACX_EEPROMLESS_IND_REG */
732 wl1271_debug(DEBUG_BOOT, "ACX_EEPROMLESS_IND_REG");
733
734 wl1271_write32(wl, ACX_EEPROMLESS_IND_REG, ACX_EEPROMLESS_IND_REG);
735
736 tmp = wl1271_read32(wl, CHIP_ID_B);
737
738 wl1271_debug(DEBUG_BOOT, "chip id 0x%x", tmp);
739
740 /* 6. read the EEPROM parameters */
741 tmp = wl1271_read32(wl, SCR_PAD2);
742
743 /* WL1271: The reference driver skips steps 7 to 10 (jumps directly
744 * to upload_fw) */
745
746 if (wl->chip.id == CHIP_ID_1283_PG20)
747 wl1271_top_reg_write(wl, SDIO_IO_DS, wl->conf.hci_io_ds);
748
749 ret = wl1271_boot_upload_firmware(wl);
750 if (ret < 0)
751 goto out;
752
753out:
754 return ret;
755}
756EXPORT_SYMBOL_GPL(wl1271_load_firmware);
757
758int wl1271_boot(struct wl1271 *wl)
759{
760 int ret;
761
762 /* upload NVS and firmware */
763 ret = wl1271_load_firmware(wl);
764 if (ret)
765 return ret;
766
767 /* 10.5 start firmware */
768 ret = wl1271_boot_run_firmware(wl);
769 if (ret < 0)
770 goto out;
771
772 ret = wl1271_boot_write_irq_polarity(wl);
773 if (ret < 0)
774 goto out;
775
776 wl1271_write32(wl, ACX_REG_INTERRUPT_MASK,
777 WL1271_ACX_ALL_EVENTS_VECTOR);
778
779 /* Enable firmware interrupts now */
780 wl1271_boot_enable_interrupts(wl);
781
782 wl1271_event_mbox_config(wl);
783
784out:
785 return ret;
786}
diff --git a/drivers/net/wireless/wl12xx/boot.h b/drivers/net/wireless/wl12xx/boot.h
deleted file mode 100644
index c3adc09f403d..000000000000
--- a/drivers/net/wireless/wl12xx/boot.h
+++ /dev/null
@@ -1,120 +0,0 @@
1/*
2 * This file is part of wl1271
3 *
4 * Copyright (C) 2008-2009 Nokia Corporation
5 *
6 * Contact: Luciano Coelho <luciano.coelho@nokia.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 */
23
24#ifndef __BOOT_H__
25#define __BOOT_H__
26
27#include "wl12xx.h"
28
29int wl1271_boot(struct wl1271 *wl);
30int wl1271_load_firmware(struct wl1271 *wl);
31
32#define WL1271_NO_SUBBANDS 8
33#define WL1271_NO_POWER_LEVELS 4
34#define WL1271_FW_VERSION_MAX_LEN 20
35
36struct wl1271_static_data {
37 u8 mac_address[ETH_ALEN];
38 u8 padding[2];
39 u8 fw_version[WL1271_FW_VERSION_MAX_LEN];
40 u32 hw_version;
41 u8 tx_power_table[WL1271_NO_SUBBANDS][WL1271_NO_POWER_LEVELS];
42};
43
44/* number of times we try to read the INIT interrupt */
45#define INIT_LOOP 20000
46
47/* delay between retries */
48#define INIT_LOOP_DELAY 50
49
50#define WU_COUNTER_PAUSE_VAL 0x3FF
51#define WELP_ARM_COMMAND_VAL 0x4
52
53#define OCP_REG_POLARITY 0x0064
54#define OCP_REG_CLK_TYPE 0x0448
55#define OCP_REG_CLK_POLARITY 0x0cb2
56#define OCP_REG_CLK_PULL 0x0cb4
57
58#define CMD_MBOX_ADDRESS 0x407B4
59
60#define POLARITY_LOW BIT(1)
61#define NO_PULL (BIT(14) | BIT(15))
62
63#define FREF_CLK_TYPE_BITS 0xfffffe7f
64#define CLK_REQ_PRCM 0x100
65#define FREF_CLK_POLARITY_BITS 0xfffff8ff
66#define CLK_REQ_OUTN_SEL 0x700
67
68/* PLL configuration algorithm for wl128x */
69#define SYS_CLK_CFG_REG 0x2200
70/* Bit[0] - 0-TCXO, 1-FREF */
71#define MCS_PLL_CLK_SEL_FREF BIT(0)
72/* Bit[3:2] - 01-TCXO, 10-FREF */
73#define WL_CLK_REQ_TYPE_FREF BIT(3)
74#define WL_CLK_REQ_TYPE_PG2 (BIT(3) | BIT(2))
75/* Bit[4] - 0-TCXO, 1-FREF */
76#define PRCM_CM_EN_MUX_WLAN_FREF BIT(4)
77
78#define TCXO_ILOAD_INT_REG 0x2264
79#define TCXO_CLK_DETECT_REG 0x2266
80
81#define TCXO_DET_FAILED BIT(4)
82
83#define FREF_ILOAD_INT_REG 0x2084
84#define FREF_CLK_DETECT_REG 0x2086
85#define FREF_CLK_DETECT_FAIL BIT(4)
86
87/* Use this reg for masking during driver access */
88#define WL_SPARE_REG 0x2320
89#define WL_SPARE_VAL BIT(2)
90/* Bit[6:5:3] - mask wl write SYS_CLK_CFG[8:5:2:4] */
91#define WL_SPARE_MASK_8526 (BIT(6) | BIT(5) | BIT(3))
92
93#define PLL_LOCK_COUNTERS_REG 0xD8C
94#define PLL_LOCK_COUNTERS_COEX 0x0F
95#define PLL_LOCK_COUNTERS_MCS 0xF0
96#define MCS_PLL_OVERRIDE_REG 0xD90
97#define MCS_PLL_CONFIG_REG 0xD92
98#define MCS_SEL_IN_FREQ_MASK 0x0070
99#define MCS_SEL_IN_FREQ_SHIFT 4
100#define MCS_PLL_CONFIG_REG_VAL 0x73
101#define MCS_PLL_ENABLE_HP (BIT(0) | BIT(1))
102
103#define MCS_PLL_M_REG 0xD94
104#define MCS_PLL_N_REG 0xD96
105#define MCS_PLL_M_REG_VAL 0xC8
106#define MCS_PLL_N_REG_VAL 0x07
107
108#define SDIO_IO_DS 0xd14
109
110/* SDIO/wSPI DS configuration values */
111enum {
112 HCI_IO_DS_8MA = 0,
113 HCI_IO_DS_4MA = 1, /* default */
114 HCI_IO_DS_6MA = 2,
115 HCI_IO_DS_2MA = 3,
116};
117
118/* end PLL configuration algorithm for wl128x */
119
120#endif