diff options
author | Luciano Coelho <coelho@ti.com> | 2012-04-12 08:32:53 -0400 |
---|---|---|
committer | Luciano Coelho <coelho@ti.com> | 2012-04-12 08:32:53 -0400 |
commit | 916ef361ce70a56601654e44c91855153e557051 (patch) | |
tree | ea2812e64d17e2bf93a65e5a1933d54ff0e07255 /drivers/net | |
parent | e66a8ddff72e85605f2212a0ebc666c7e9116641 (diff) | |
parent | 6bac40a63aae9d0942496c9f350dbb7a6c88e3fa (diff) |
Merge branch 'wl12xx-next' into for-linville
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/wireless/Kconfig | 3 | ||||
-rw-r--r-- | drivers/net/wireless/Makefile | 4 | ||||
-rw-r--r-- | drivers/net/wireless/ti/Kconfig | 14 | ||||
-rw-r--r-- | drivers/net/wireless/ti/Makefile | 4 | ||||
-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/Kconfig | 8 | ||||
-rw-r--r-- | drivers/net/wireless/ti/wl12xx/Makefile | 3 | ||||
-rw-r--r-- | drivers/net/wireless/ti/wl12xx/acx.c | 53 | ||||
-rw-r--r-- | drivers/net/wireless/ti/wl12xx/acx.h | 36 | ||||
-rw-r--r-- | drivers/net/wireless/ti/wl12xx/cmd.c | 254 | ||||
-rw-r--r-- | drivers/net/wireless/ti/wl12xx/cmd.h | 112 | ||||
-rw-r--r-- | drivers/net/wireless/ti/wl12xx/conf.h | 50 | ||||
-rw-r--r-- | drivers/net/wireless/ti/wl12xx/main.c | 1388 | ||||
-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.h | 31 | ||||
-rw-r--r-- | drivers/net/wireless/ti/wlcore/Kconfig | 41 | ||||
-rw-r--r-- | drivers/net/wireless/ti/wlcore/Makefile | 15 | ||||
-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.c | 443 | ||||
-rw-r--r-- | drivers/net/wireless/ti/wlcore/boot.h | 54 | ||||
-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.h | 122 | ||||
-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.h | 448 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/Kconfig | 48 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/Makefile | 15 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/boot.c | 786 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/boot.h | 120 |
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" | |||
282 | source "drivers/net/wireless/p54/Kconfig" | 282 | source "drivers/net/wireless/p54/Kconfig" |
283 | source "drivers/net/wireless/rt2x00/Kconfig" | 283 | source "drivers/net/wireless/rt2x00/Kconfig" |
284 | source "drivers/net/wireless/rtlwifi/Kconfig" | 284 | source "drivers/net/wireless/rtlwifi/Kconfig" |
285 | source "drivers/net/wireless/wl1251/Kconfig" | 285 | source "drivers/net/wireless/ti/Kconfig" |
286 | source "drivers/net/wireless/wl12xx/Kconfig" | ||
287 | source "drivers/net/wireless/zd1211rw/Kconfig" | 286 | source "drivers/net/wireless/zd1211rw/Kconfig" |
288 | source "drivers/net/wireless/mwifiex/Kconfig" | 287 | source "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 | ||
52 | obj-$(CONFIG_MAC80211_HWSIM) += mac80211_hwsim.o | 52 | obj-$(CONFIG_MAC80211_HWSIM) += mac80211_hwsim.o |
53 | 53 | ||
54 | obj-$(CONFIG_WL1251) += wl1251/ | 54 | obj-$(CONFIG_WL_TI) += ti/ |
55 | obj-$(CONFIG_WL12XX) += wl12xx/ | ||
56 | obj-$(CONFIG_WL12XX_PLATFORM_DATA) += wl12xx/ | ||
57 | 55 | ||
58 | obj-$(CONFIG_IWM) += iwmc3200wifi/ | 56 | obj-$(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 @@ | |||
1 | menuconfig 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 | |||
8 | if WL_TI | ||
9 | source "drivers/net/wireless/ti/wl1251/Kconfig" | ||
10 | source "drivers/net/wireless/ti/wl12xx/Kconfig" | ||
11 | |||
12 | # keep last for automatic dependencies | ||
13 | source "drivers/net/wireless/ti/wlcore/Kconfig" | ||
14 | endif # 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 @@ | |||
1 | obj-$(CONFIG_WLCORE) += wlcore/ | ||
2 | obj-$(CONFIG_WL12XX) += wl12xx/ | ||
3 | obj-$(CONFIG_WL12XX_PLATFORM_DATA) += wlcore/ | ||
4 | obj-$(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 @@ | |||
1 | config 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 @@ | |||
1 | wl12xx-objs = main.o cmd.o acx.o | ||
2 | |||
3 | obj-$(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 | |||
29 | int 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 | |||
49 | out: | ||
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 | |||
28 | struct wl1271_acx_host_config_bitmap { | ||
29 | struct acx_header header; | ||
30 | |||
31 | __le32 host_cfg_bitmap; | ||
32 | } __packed; | ||
33 | |||
34 | int 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 | |||
29 | int 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 | |||
63 | int 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 | |||
111 | out: | ||
112 | kfree(gen_parms); | ||
113 | return ret; | ||
114 | } | ||
115 | |||
116 | int 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 | |||
165 | out: | ||
166 | kfree(gen_parms); | ||
167 | return ret; | ||
168 | } | ||
169 | |||
170 | int 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 | |||
212 | int 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 | |||
31 | struct 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 | |||
46 | struct 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 | |||
61 | struct 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 | |||
77 | struct 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 | |||
96 | struct 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 | |||
106 | int wl1271_cmd_general_parms(struct wl1271 *wl); | ||
107 | int wl128x_cmd_general_parms(struct wl1271 *wl); | ||
108 | int wl1271_cmd_radio_parms(struct wl1271 *wl); | ||
109 | int wl128x_cmd_radio_parms(struct wl1271 *wl); | ||
110 | int 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 | |||
29 | struct 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 | |||
45 | struct 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 | |||
43 | static 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 | |||
365 | static 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 | |||
393 | static 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 | |||
423 | static 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 | |||
453 | static 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 | |||
458 | enum 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 | |||
484 | static 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 | |||
563 | static 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 | |||
592 | static 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 | |||
615 | static 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 | |||
671 | out: | ||
672 | return ret; | ||
673 | } | ||
674 | |||
675 | static 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 | |||
688 | static 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 | |||
719 | static 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 | |||
740 | static 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 | |||
751 | static 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 | |||
762 | static 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 | |||
771 | static 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 | */ | ||
809 | static 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 | |||
842 | fref_clk: | ||
843 | /* FREF clock is selected */ | ||
844 | if (!wl128x_is_fref_valid(wl)) | ||
845 | return -EINVAL; | ||
846 | *selected_clock = wl->ref_clock; | ||
847 | |||
848 | config_mcs_pll: | ||
849 | return wl128x_configure_mcs_pll(wl, *selected_clock); | ||
850 | } | ||
851 | |||
852 | static 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 | |||
905 | static 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 | |||
940 | static 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 | |||
986 | out: | ||
987 | return ret; | ||
988 | } | ||
989 | |||
990 | static 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 | |||
1014 | static 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 | |||
1033 | static 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 | |||
1057 | out: | ||
1058 | return ret; | ||
1059 | } | ||
1060 | |||
1061 | static 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 | |||
1068 | static void wl12xx_ack_event(struct wl1271 *wl) | ||
1069 | { | ||
1070 | wlcore_write_reg(wl, REG_INTERRUPT_TRIG, WL12XX_INTR_TRIG_EVENT_ACK); | ||
1071 | } | ||
1072 | |||
1073 | static 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 | |||
1081 | static void | ||
1082 | wl12xx_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 | |||
1093 | static void | ||
1094 | wl12xx_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 | |||
1128 | static enum wl_rx_buf_align | ||
1129 | wl12xx_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 | |||
1137 | static 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 | |||
1150 | static 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 | |||
1158 | static 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 | } | ||
1191 | out: | ||
1192 | return ret; | ||
1193 | } | ||
1194 | |||
1195 | static u32 wl12xx_sta_get_ap_rate_mask(struct wl1271 *wl, | ||
1196 | struct wl12xx_vif *wlvif) | ||
1197 | { | ||
1198 | return wlvif->rate_set; | ||
1199 | } | ||
1200 | |||
1201 | static 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 | |||
1217 | static 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 | |||
1228 | static 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 | |||
1256 | static 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 | |||
1273 | static 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 | |||
1285 | static void wl12xx_get_mac(struct wl1271 *wl) | ||
1286 | { | ||
1287 | if (wl12xx_mac_in_fuse(wl)) | ||
1288 | wl12xx_get_fuse_mac(wl); | ||
1289 | } | ||
1290 | |||
1291 | static 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 | |||
1311 | static 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 | |||
1324 | static 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 | |||
1353 | static const struct platform_device_id wl12xx_id_table[] __devinitconst = { | ||
1354 | { "wl12xx", 0 }, | ||
1355 | { } /* Terminating Entry */ | ||
1356 | }; | ||
1357 | MODULE_DEVICE_TABLE(platform, wl12xx_id_table); | ||
1358 | |||
1359 | static 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 | |||
1369 | static int __init wl12xx_init(void) | ||
1370 | { | ||
1371 | return platform_driver_register(&wl12xx_driver); | ||
1372 | } | ||
1373 | module_init(wl12xx_init); | ||
1374 | |||
1375 | static void __exit wl12xx_exit(void) | ||
1376 | { | ||
1377 | platform_driver_unregister(&wl12xx_driver); | ||
1378 | } | ||
1379 | module_exit(wl12xx_exit); | ||
1380 | |||
1381 | MODULE_LICENSE("GPL v2"); | ||
1382 | MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>"); | ||
1383 | MODULE_FIRMWARE(WL127X_FW_NAME_SINGLE); | ||
1384 | MODULE_FIRMWARE(WL127X_FW_NAME_MULTI); | ||
1385 | MODULE_FIRMWARE(WL127X_PLT_FW_NAME); | ||
1386 | MODULE_FIRMWARE(WL128X_FW_NAME_SINGLE); | ||
1387 | MODULE_FIRMWARE(WL128X_FW_NAME_MULTI); | ||
1388 | MODULE_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 | |||
426 | enum { | ||
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 */ | ||
484 | enum { | ||
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 | |||
27 | struct 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 @@ | |||
1 | config 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 | |||
15 | config 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 | |||
27 | config 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 | |||
38 | config 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 @@ | |||
1 | wlcore-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 | |||
4 | wlcore_spi-objs = spi.o | ||
5 | wlcore_sdio-objs = sdio.o | ||
6 | |||
7 | wlcore-$(CONFIG_NL80211_TESTMODE) += testmode.o | ||
8 | obj-$(CONFIG_WLCORE) += wlcore.o | ||
9 | obj-$(CONFIG_WLCORE_SPI) += wlcore_spi.o | ||
10 | obj-$(CONFIG_WLCORE_SDIO) += wlcore_sdio.o | ||
11 | |||
12 | # small builtin driver bit | ||
13 | obj-$(CONFIG_WL12XX_PLATFORM_DATA) += wl12xx_platform_data.o | ||
14 | |||
15 | ccflags-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 | ||
37 | int wl1271_acx_wake_up_conditions(struct wl1271 *wl, struct wl12xx_vif *wlvif, | 37 | int 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 | ||
1001 | int 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 | |||
1021 | out: | ||
1022 | kfree(bitmap_conf); | ||
1023 | |||
1024 | return ret; | ||
1025 | } | ||
1026 | |||
1027 | int wl1271_acx_init_mem_config(struct wl1271 *wl) | 1001 | int 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 | ||
831 | struct wl1271_acx_host_config_bitmap { | ||
832 | struct acx_header header; | ||
833 | |||
834 | __le32 host_cfg_bitmap; | ||
835 | } __packed; | ||
836 | |||
837 | enum { | 832 | enum { |
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); | |||
1274 | int wl1271_acx_tx_config_options(struct wl1271 *wl); | 1269 | int wl1271_acx_tx_config_options(struct wl1271 *wl); |
1275 | int wl12xx_acx_mem_cfg(struct wl1271 *wl); | 1270 | int wl12xx_acx_mem_cfg(struct wl1271 *wl); |
1276 | int wl1271_acx_init_mem_config(struct wl1271 *wl); | 1271 | int wl1271_acx_init_mem_config(struct wl1271 *wl); |
1277 | int wl1271_acx_host_if_cfg_bitmap(struct wl1271 *wl, u32 host_cfg_bitmap); | ||
1278 | int wl1271_acx_init_rx_interrupt(struct wl1271 *wl); | 1272 | int wl1271_acx_init_rx_interrupt(struct wl1271 *wl); |
1279 | int wl1271_acx_smart_reflex(struct wl1271 *wl); | 1273 | int wl1271_acx_smart_reflex(struct wl1271 *wl); |
1280 | int wl1271_acx_bet_enable(struct wl1271 *wl, struct wl12xx_vif *wlvif, | 1274 | int 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 | |||
36 | static 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 | |||
48 | static 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 | |||
70 | static 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 | |||
99 | static 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 | |||
166 | int 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 | } | ||
198 | EXPORT_SYMBOL_GPL(wlcore_boot_upload_firmware); | ||
199 | |||
200 | int 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 | |||
341 | out_badnvs: | ||
342 | wl1271_error("nvs data is malformed"); | ||
343 | return -EILSEQ; | ||
344 | } | ||
345 | EXPORT_SYMBOL_GPL(wlcore_boot_upload_nvs); | ||
346 | |||
347 | int 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 | } | ||
443 | EXPORT_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 | |||
29 | int wlcore_boot_upload_firmware(struct wl1271 *wl); | ||
30 | int wlcore_boot_upload_nvs(struct wl1271 *wl); | ||
31 | int 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 | |||
37 | struct 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 | ||
107 | fail: | 109 | fail: |
@@ -110,240 +112,18 @@ fail: | |||
110 | return ret; | 112 | return ret; |
111 | } | 113 | } |
112 | 114 | ||
113 | int 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 | |||
161 | out: | ||
162 | kfree(gen_parms); | ||
163 | return ret; | ||
164 | } | ||
165 | |||
166 | int 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 | |||
215 | out: | ||
216 | kfree(gen_parms); | ||
217 | return ret; | ||
218 | } | ||
219 | |||
220 | int 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 | |||
262 | int 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 | |||
306 | int 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 | */ |
343 | static int wl1271_cmd_wait_for_event_or_timeout(struct wl1271 *wl, u32 mask) | 119 | static 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; | 149 | out: |
150 | kfree(events_vector); | ||
151 | return ret; | ||
369 | } | 152 | } |
370 | 153 | ||
371 | static int wl1271_cmd_wait_for_event(struct wl1271 *wl, u32 mask) | 154 | static 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 | } |
690 | EXPORT_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 | } |
747 | EXPORT_SYMBOL_GPL(wl1271_cmd_configure); | ||
963 | 748 | ||
964 | int wl1271_cmd_data_path(struct wl1271 *wl, bool enable) | 749 | int 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 | ||
30 | struct acx_header; | 30 | struct acx_header; |
31 | 31 | ||
32 | int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len, | 32 | int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len, |
33 | size_t res_len); | 33 | size_t res_len); |
34 | int wl1271_cmd_general_parms(struct wl1271 *wl); | ||
35 | int wl128x_cmd_general_parms(struct wl1271 *wl); | ||
36 | int wl1271_cmd_radio_parms(struct wl1271 *wl); | ||
37 | int wl128x_cmd_radio_parms(struct wl1271 *wl); | ||
38 | int wl1271_cmd_ext_radio_parms(struct wl1271 *wl); | ||
39 | int wl12xx_cmd_role_enable(struct wl1271 *wl, u8 *addr, u8 role_type, | 34 | int wl12xx_cmd_role_enable(struct wl1271 *wl, u8 *addr, u8 role_type, |
40 | u8 *role_id); | 35 | u8 *role_id); |
41 | int wl12xx_cmd_role_disable(struct wl1271 *wl, u8 *role_id); | 36 | int 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 | ||
265 | enum wl12xx_band { | 260 | enum 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 | ||
274 | struct wl12xx_cmd_role_start { | 269 | struct 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 | |||
501 | struct 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 | |||
516 | struct 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 | |||
531 | struct 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 | |||
547 | struct 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 | |||
564 | struct 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 | ||
68 | enum { | 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 | ||
99 | enum { | 70 | enum { |
100 | CONF_SG_DISABLE = 0, | 71 | CONF_SG_DISABLE = 0, |
@@ -1096,16 +1067,31 @@ struct conf_scan_settings { | |||
1096 | }; | 1067 | }; |
1097 | 1068 | ||
1098 | struct conf_sched_scan_settings { | 1069 | struct 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 | |||
1125 | struct 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 | |||
1141 | struct conf_ht_setting { | 1107 | struct 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 | ||
1289 | struct conf_drv_settings { | 1255 | struct 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 | ||
29 | int wl1271_debugfs_init(struct wl1271 *wl); | 29 | int wl1271_debugfs_init(struct wl1271 *wl); |
30 | void wl1271_debugfs_exit(struct wl1271 *wl); | 30 | void 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 | ||
101 | static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox) | 100 | static 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 | ||
281 | void 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 | |||
290 | int wl1271_event_handle(struct wl1271 *wl, u8 mbox_num) | 281 | int 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 | ||
135 | struct wl1271; | ||
136 | |||
135 | int wl1271_event_unmask(struct wl1271 *wl); | 137 | int wl1271_event_unmask(struct wl1271 *wl); |
136 | void wl1271_event_mbox_config(struct wl1271 *wl); | ||
137 | int wl1271_event_handle(struct wl1271 *wl, u8 mbox); | 138 | int 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 | |||
28 | static inline u32 | ||
29 | wlcore_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 | |||
37 | static inline void | ||
38 | wlcore_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 | |||
47 | static inline void | ||
48 | wlcore_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 | |||
58 | static inline enum wl_rx_buf_align | ||
59 | wlcore_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 | |||
68 | static inline void | ||
69 | wlcore_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 | |||
75 | static inline u32 | ||
76 | wlcore_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 | |||
84 | static 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 | |||
90 | static 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 | |||
96 | static inline int | ||
97 | wlcore_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 | |||
105 | static inline u32 | ||
106 | wlcore_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 | |||
114 | static 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 | ||
37 | int wl1271_init_templates_config(struct wl1271 *wl) | 37 | int 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 | ||
497 | int 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 | } | ||
513 | out: | ||
514 | return ret; | ||
515 | } | ||
516 | |||
517 | /* vif-specifc initialization */ | 497 | /* vif-specifc initialization */ |
518 | static int wl12xx_init_sta_role(struct wl1271 *wl, struct wl12xx_vif *wlvif) | 498 | static 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 | ||
29 | int wl1271_hw_init_power_auth(struct wl1271 *wl); | 29 | int wl1271_hw_init_power_auth(struct wl1271 *wl); |
30 | int wl1271_init_templates_config(struct wl1271 *wl); | 30 | int 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 | |||
48 | struct 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 | |||
107 | bool wl1271_set_block_size(struct wl1271 *wl) | 35 | bool 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 | ||
117 | void wl1271_disable_interrupts(struct wl1271 *wl) | 45 | void wlcore_disable_interrupts(struct wl1271 *wl) |
118 | { | 46 | { |
119 | disable_irq(wl->irq); | 47 | disable_irq(wl->irq); |
120 | } | 48 | } |
49 | EXPORT_SYMBOL_GPL(wlcore_disable_interrupts); | ||
121 | 50 | ||
122 | void wl1271_enable_interrupts(struct wl1271 *wl) | 51 | void wlcore_enable_interrupts(struct wl1271 *wl) |
123 | { | 52 | { |
124 | enable_irq(wl->irq); | 53 | enable_irq(wl->irq); |
125 | } | 54 | } |
55 | EXPORT_SYMBOL_GPL(wlcore_enable_interrupts); | ||
126 | 56 | ||
127 | /* Set the SPI partitions to access the chip addresses | 57 | int 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 | } | ||
89 | EXPORT_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 | */ |
161 | int wl1271_set_partition(struct wl1271 *wl, | 125 | void 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 | } | ||
153 | EXPORT_SYMBOL_GPL(wlcore_set_partition); | ||
184 | 154 | ||
185 | return 0; | 155 | void 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 | } |
187 | EXPORT_SYMBOL_GPL(wl1271_set_partition); | 161 | EXPORT_SYMBOL_GPL(wlcore_select_partition); |
188 | 162 | ||
189 | void wl1271_io_reset(struct wl1271 *wl) | 163 | void 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 | |||
201 | void 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 | |||
214 | u16 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 | ||
46 | extern struct wl1271_partition_set wl12xx_part_table[PART_TABLE_LEN]; | ||
47 | |||
48 | struct wl1271; | 45 | struct wl1271; |
49 | 46 | ||
50 | void wl1271_disable_interrupts(struct wl1271 *wl); | 47 | void wlcore_disable_interrupts(struct wl1271 *wl); |
51 | void wl1271_enable_interrupts(struct wl1271 *wl); | 48 | void wlcore_enable_interrupts(struct wl1271 *wl); |
52 | 49 | ||
53 | void wl1271_io_reset(struct wl1271 *wl); | 50 | void wl1271_io_reset(struct wl1271 *wl); |
54 | void wl1271_io_init(struct wl1271 *wl); | 51 | void wl1271_io_init(struct wl1271 *wl); |
52 | int 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 */ |
57 | static inline void wl1271_raw_write(struct wl1271 *wl, int addr, void *buf, | 55 | static 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 | ||
67 | static 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 | |||
73 | static 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 | |||
69 | static inline u32 wl1271_raw_read32(struct wl1271 *wl, int addr) | 79 | static 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 */ | ||
85 | static 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 | |||
108 | static inline void wl1271_read(struct wl1271 *wl, int addr, void *buf, | 94 | static 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 | ||
114 | static 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 | |||
120 | static 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 | |||
128 | static inline void wl1271_read_hwaddr(struct wl1271 *wl, int hwaddr, | 126 | static 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 | ||
142 | static inline u32 wl1271_read32(struct wl1271 *wl, int addr) | 140 | static 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 | ||
147 | static inline void wl1271_write32(struct wl1271 *wl, int addr, u32 val) | 145 | static 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 | |||
150 | static 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 | |||
156 | static 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 | ||
152 | static inline void wl1271_power_off(struct wl1271 *wl) | 161 | static 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 | 176 | void wlcore_set_partition(struct wl1271 *wl, | |
168 | /* Top Register IO */ | 177 | const struct wlcore_partition_set *p); |
169 | void wl1271_top_reg_write(struct wl1271 *wl, int addr, u16 val); | ||
170 | u16 wl1271_top_reg_read(struct wl1271 *wl, int addr); | ||
171 | |||
172 | int wl1271_set_partition(struct wl1271 *wl, | ||
173 | struct wl1271_partition_set *p); | ||
174 | 178 | ||
175 | bool wl1271_set_block_size(struct wl1271 *wl); | 179 | bool wl1271_set_block_size(struct wl1271 *wl); |
176 | 180 | ||
@@ -178,4 +182,6 @@ bool wl1271_set_block_size(struct wl1271 *wl); | |||
178 | 182 | ||
179 | int wl1271_tx_dummy_packet(struct wl1271 *wl); | 183 | int wl1271_tx_dummy_packet(struct wl1271 *wl); |
180 | 184 | ||
185 | void 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 | ||
56 | static 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 | ||
387 | static char *fwlog_param; | 58 | static char *fwlog_param; |
388 | static bool bug_on_recovery; | 59 | static bool bug_on_recovery; |
60 | static bool no_recovery; | ||
389 | 61 | ||
390 | static void __wl1271_op_remove_interface(struct wl1271 *wl, | 62 | static 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 | ||
631 | static void wl1271_conf_init(struct wl1271 *wl) | 303 | static 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 | ||
751 | static void wl12xx_irq_update_links_status(struct wl1271 *wl, | 388 | static 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 | ||
783 | static void wl12xx_fw_status(struct wl1271 *wl, | 421 | static 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 | ||
1291 | static void wl1271_fw_wakeup(struct wl1271 *wl) | 934 | static 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 | ||
1299 | static int wl1271_setup(struct wl1271 *wl) | 939 | static 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 | ||
1674 | out_unlock: | 1285 | out: |
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); |
1697 | out_unlock: | 1305 | out: |
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); |
1742 | out: | ||
1743 | mutex_unlock(&wl->mutex); | ||
1744 | } | 1348 | } |
1745 | 1349 | ||
1746 | static int wl1271_op_suspend(struct ieee80211_hw *hw, | 1350 | static 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 */ | ||
4666 | static 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 */ |
4713 | static struct ieee80211_supported_band wl1271_band_2ghz = { | 4273 | static 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 */ | ||
4788 | static 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 | |||
4818 | static struct ieee80211_supported_band wl1271_band_5ghz = { | 4346 | static 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 | |||
4826 | static 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 | ||
4831 | static const struct ieee80211_ops wl1271_ops = { | 4353 | static const struct ieee80211_ops wl1271_ops = { |
@@ -4862,18 +4384,18 @@ static const struct ieee80211_ops wl1271_ops = { | |||
4862 | }; | 4384 | }; |
4863 | 4385 | ||
4864 | 4386 | ||
4865 | u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band) | 4387 | u8 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 | ||
5030 | static 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 | |||
5058 | static void wl12xx_derive_mac_addresses(struct wl1271 *wl, | 4552 | static 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 | ||
5083 | static 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 | |||
5100 | static int wl12xx_get_hw_info(struct wl1271 *wl) | 4577 | static 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); |
5126 | out: | 4596 | out: |
@@ -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 | ||
5290 | static struct ieee80211_hw *wl1271_alloc_hw(void) | 4764 | struct 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 | ||
4872 | err_fwlog: | ||
4873 | free_page((unsigned long)wl->fwlog); | ||
4874 | |||
5389 | err_dummy_packet: | 4875 | err_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 | ||
5398 | err_hw: | 4884 | err_hw: |
5399 | wl1271_debugfs_exit(wl); | 4885 | wl1271_debugfs_exit(wl); |
4886 | kfree(wl->priv); | ||
4887 | |||
4888 | err_priv_alloc: | ||
5400 | ieee80211_free_hw(hw); | 4889 | ieee80211_free_hw(hw); |
5401 | 4890 | ||
5402 | err_hw_alloc: | 4891 | err_hw_alloc: |
5403 | 4892 | ||
5404 | return ERR_PTR(ret); | 4893 | return ERR_PTR(ret); |
5405 | } | 4894 | } |
4895 | EXPORT_SYMBOL_GPL(wlcore_alloc_hw); | ||
5406 | 4896 | ||
5407 | static int wl1271_free_hw(struct wl1271 *wl) | 4897 | int 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 | } |
4932 | EXPORT_SYMBOL_GPL(wlcore_free_hw); | ||
5441 | 4933 | ||
5442 | static irqreturn_t wl12xx_hardirq(int irq, void *cookie) | 4934 | static 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 | ||
5471 | static int __devinit wl12xx_probe(struct platform_device *pdev) | 4963 | int __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 | ||
5551 | out_hw_pg_ver: | 5043 | out_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 | ||
5560 | out_free_hw: | 5052 | out_free_hw: |
5561 | wl1271_free_hw(wl); | 5053 | wlcore_free_hw(wl); |
5562 | 5054 | ||
5563 | out: | 5055 | out: |
5564 | return ret; | 5056 | return ret; |
5565 | } | 5057 | } |
5058 | EXPORT_SYMBOL_GPL(wlcore_probe); | ||
5566 | 5059 | ||
5567 | static int __devexit wl12xx_remove(struct platform_device *pdev) | 5060 | int __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 | 5074 | EXPORT_SYMBOL_GPL(wlcore_remove); | |
5582 | static const struct platform_device_id wl12xx_id_table[] __devinitconst = { | ||
5583 | { "wl12xx", 0 }, | ||
5584 | { } /* Terminating Entry */ | ||
5585 | }; | ||
5586 | MODULE_DEVICE_TABLE(platform, wl12xx_id_table); | ||
5587 | |||
5588 | static 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 | |||
5598 | static int __init wl12xx_init(void) | ||
5599 | { | ||
5600 | return platform_driver_register(&wl12xx_driver); | ||
5601 | } | ||
5602 | module_init(wl12xx_init); | ||
5603 | |||
5604 | static void __exit wl12xx_exit(void) | ||
5605 | { | ||
5606 | platform_driver_unregister(&wl12xx_driver); | ||
5607 | } | ||
5608 | module_exit(wl12xx_exit); | ||
5609 | 5075 | ||
5610 | u32 wl12xx_debug_level = DEBUG_NONE; | 5076 | u32 wl12xx_debug_level = DEBUG_NONE; |
5611 | EXPORT_SYMBOL_GPL(wl12xx_debug_level); | 5077 | EXPORT_SYMBOL_GPL(wl12xx_debug_level); |
@@ -5619,6 +5085,9 @@ MODULE_PARM_DESC(fwlog, | |||
5619 | module_param(bug_on_recovery, bool, S_IRUSR | S_IWUSR); | 5085 | module_param(bug_on_recovery, bool, S_IRUSR | S_IWUSR); |
5620 | MODULE_PARM_DESC(bug_on_recovery, "BUG() on fw recovery"); | 5086 | MODULE_PARM_DESC(bug_on_recovery, "BUG() on fw recovery"); |
5621 | 5087 | ||
5088 | module_param(no_recovery, bool, S_IRUSR | S_IWUSR); | ||
5089 | MODULE_PARM_DESC(no_recovery, "Prevent HW recovery. FW will remain stuck."); | ||
5090 | |||
5622 | MODULE_LICENSE("GPL"); | 5091 | MODULE_LICENSE("GPL"); |
5623 | MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>"); | 5092 | MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>"); |
5624 | MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>"); | 5093 | MODULE_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 | ||
68 | out: | 67 | out: |
@@ -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 | ||
30 | int wl1271_ps_set_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif, | 30 | int 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 | ||
35 | static 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 | ||
42 | static u32 wl12xx_rx_get_buf_size(struct wl12xx_fw_status *status, | 41 | static 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 | ||
49 | static bool wl12xx_rx_get_unaligned(struct wl12xx_fw_status *status, | 51 | static 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 | ||
57 | static void wl1271_rx_status(struct wl1271 *wl, | 59 | static 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 | ||
100 | static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length, | 102 | static 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 | ||
188 | void wl12xx_rx(struct wl1271 *wl, struct wl12xx_fw_status *status) | 202 | void 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 */ | ||
106 | enum wl_rx_buf_align { | ||
107 | WLCORE_RX_BUF_ALIGNED, | ||
108 | WLCORE_RX_BUF_UNALIGNED, | ||
109 | WLCORE_RX_BUF_PADDED, | ||
110 | }; | ||
111 | |||
102 | enum { | 112 | enum { |
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 | ||
129 | void wl12xx_rx(struct wl1271 *wl, struct wl12xx_fw_status *status); | 139 | void wl12xx_rx(struct wl1271 *wl, struct wl_fw_status *status); |
130 | u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band); | 140 | u8 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 | ||
29 | int wl1271_scan(struct wl1271 *wl, struct ieee80211_vif *vif, | 29 | int 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 | ||
60 | enum { | 60 | enum { |
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 | ||
36 | static int wl1271_set_default_wep_key(struct wl1271 *wl, | 42 | static 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) | |||
69 | static void wl1271_free_tx_id(struct wl1271 *wl, int id) | 75 | static 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 | ||
170 | static unsigned int wl12xx_calc_packet_alignment(struct wl1271 *wl, | 176 | unsigned 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 | } |
184 | EXPORT_SYMBOL(wlcore_calc_packet_alignment); | ||
178 | 185 | ||
179 | static int wl1271_tx_allocate(struct wl1271 *wl, struct wl12xx_vif *wlvif, | 186 | static 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 | ||
754 | out_ack: | 721 | out_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 | } |
908 | EXPORT_SYMBOL(wl1271_tx_complete); | ||
932 | 909 | ||
933 | void wl1271_tx_reset_link_queues(struct wl1271 *wl, u8 hlid) | 910 | void 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); | |||
212 | void wl12xx_tx_reset_wlvif(struct wl1271 *wl, struct wl12xx_vif *wlvif); | 209 | void wl12xx_tx_reset_wlvif(struct wl1271 *wl, struct wl12xx_vif *wlvif); |
213 | void wl12xx_tx_reset(struct wl1271 *wl, bool reset_tx_queues); | 210 | void wl12xx_tx_reset(struct wl1271 *wl, bool reset_tx_queues); |
214 | void wl1271_tx_flush(struct wl1271 *wl); | 211 | void wl1271_tx_flush(struct wl1271 *wl); |
215 | u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band); | 212 | u8 wlcore_rate_to_idx(struct wl1271 *wl, u8 rate, enum ieee80211_band band); |
216 | u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set, | 213 | u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set, |
217 | enum ieee80211_band rate_band); | 214 | enum ieee80211_band rate_band); |
218 | u32 wl1271_tx_min_rate_get(struct wl1271 *wl, u32 rate_set); | 215 | u32 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); | |||
224 | void wl1271_handle_tx_low_watermark(struct wl1271 *wl); | 221 | void wl1271_handle_tx_low_watermark(struct wl1271 *wl); |
225 | bool wl12xx_is_dummy_packet(struct wl1271 *wl, struct sk_buff *skb); | 222 | bool wl12xx_is_dummy_packet(struct wl1271 *wl, struct sk_buff *skb); |
226 | void wl12xx_rearm_rx_streaming(struct wl1271 *wl, unsigned long *active_hlids); | 223 | void wl12xx_rearm_rx_streaming(struct wl1271 *wl, unsigned long *active_hlids); |
224 | unsigned int wlcore_calc_packet_alignment(struct wl1271 *wl, | ||
225 | unsigned int packet_length); | ||
227 | 226 | ||
228 | /* from main.c */ | 227 | /* from main.c */ |
229 | void wl1271_free_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 hlid); | 228 | void 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 | ||
96 | enum wl1271_state { | 94 | enum wl1271_state { |
@@ -105,26 +103,6 @@ enum wl12xx_fw_type { | |||
105 | WL12XX_FW_TYPE_PLT, | 103 | WL12XX_FW_TYPE_PLT, |
106 | }; | 104 | }; |
107 | 105 | ||
108 | enum wl1271_partition_type { | ||
109 | PART_DOWN, | ||
110 | PART_WORK, | ||
111 | PART_DRPW, | ||
112 | |||
113 | PART_TABLE_LEN | ||
114 | }; | ||
115 | |||
116 | struct wl1271_partition { | ||
117 | u32 size; | ||
118 | u32 start; | ||
119 | }; | ||
120 | |||
121 | struct 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 | |||
128 | struct wl1271; | 106 | struct wl1271; |
129 | 107 | ||
130 | enum { | 108 | enum { |
@@ -167,8 +145,21 @@ struct wl1271_stats { | |||
167 | 145 | ||
168 | #define AP_MAX_STATIONS 8 | 146 | #define AP_MAX_STATIONS 8 |
169 | 147 | ||
148 | struct 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 */ |
171 | struct wl12xx_fw_status { | 162 | struct 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 | ||
210 | struct wl1271_rx_mem_pool_addr { | 197 | struct wl1271_rx_mem_pool_addr { |
@@ -292,214 +279,6 @@ struct wl1271_link { | |||
292 | u8 ba_bitmap; | 279 | u8 ba_bitmap; |
293 | }; | 280 | }; |
294 | 281 | ||
295 | struct 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 | |||
503 | struct wl1271_station { | 282 | struct 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 */ | ||
34 | struct wl1271_tx_hw_descr; | ||
35 | enum wl_rx_buf_align; | ||
36 | |||
37 | struct 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 | |||
66 | enum 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 | |||
77 | struct wlcore_partition { | ||
78 | u32 size; | ||
79 | u32 start; | ||
80 | }; | ||
81 | |||
82 | struct 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 | |||
89 | enum 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 | |||
112 | struct 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 | |||
354 | int __devinit wlcore_probe(struct wl1271 *wl, struct platform_device *pdev); | ||
355 | int __devexit wlcore_remove(struct platform_device *pdev); | ||
356 | struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size); | ||
357 | int 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 @@ | |||
1 | menuconfig 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 | |||
9 | config 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 | |||
22 | config 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 | |||
34 | config 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 | |||
45 | config 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 @@ | |||
1 | wl12xx-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 | |||
4 | wl12xx_spi-objs = spi.o | ||
5 | wl12xx_sdio-objs = sdio.o | ||
6 | |||
7 | wl12xx-$(CONFIG_NL80211_TESTMODE) += testmode.o | ||
8 | obj-$(CONFIG_WL12XX) += wl12xx.o | ||
9 | obj-$(CONFIG_WL12XX_SPI) += wl12xx_spi.o | ||
10 | obj-$(CONFIG_WL12XX_SDIO) += wl12xx_sdio.o | ||
11 | |||
12 | # small builtin driver bit | ||
13 | obj-$(CONFIG_WL12XX_PLATFORM_DATA) += wl12xx_platform_data.o | ||
14 | |||
15 | ccflags-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 | |||
36 | static 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 | |||
48 | static 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 | |||
65 | static 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 | |||
84 | static 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 | |||
100 | static 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 | |||
167 | static 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 | |||
200 | static 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 | |||
340 | out_badnvs: | ||
341 | wl1271_error("nvs data is malformed"); | ||
342 | return -EILSEQ; | ||
343 | } | ||
344 | |||
345 | static 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 | |||
353 | static 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 | |||
388 | static 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 | |||
477 | static 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 | |||
490 | static 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 | |||
511 | static 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 | |||
522 | static 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 | |||
533 | static 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 | |||
542 | static 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 | */ | ||
580 | static 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 | |||
613 | fref_clk: | ||
614 | /* FREF clock is selected */ | ||
615 | if (!wl128x_is_fref_valid(wl)) | ||
616 | return -EINVAL; | ||
617 | *selected_clock = wl->ref_clock; | ||
618 | |||
619 | config_mcs_pll: | ||
620 | return wl128x_configure_mcs_pll(wl, *selected_clock); | ||
621 | } | ||
622 | |||
623 | static 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 */ | ||
677 | int 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 | |||
753 | out: | ||
754 | return ret; | ||
755 | } | ||
756 | EXPORT_SYMBOL_GPL(wl1271_load_firmware); | ||
757 | |||
758 | int 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 | |||
784 | out: | ||
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 | |||
29 | int wl1271_boot(struct wl1271 *wl); | ||
30 | int 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 | |||
36 | struct 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 */ | ||
111 | enum { | ||
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 | ||