aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2013-06-11 14:48:32 -0400
committerJohn W. Linville <linville@tuxdriver.com>2013-06-11 14:48:32 -0400
commit3899ba90a4ab2f3cab8e0f91a76c14ff131c8293 (patch)
treeae82b469f8a7ceb42547d11dd1fe5c73abc8635b
parent45203a3b380cee28f570475c0d28c169f908c209 (diff)
parent8b3e7be437a6b62118d0485ad971e724afe23fdf (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next into for-davem
Conflicts: drivers/net/wireless/ath/ath9k/debug.c net/mac80211/iface.c
-rw-r--r--Documentation/DocBook/80211.tmpl2
-rw-r--r--MAINTAINERS5
-rw-r--r--drivers/bcma/sprom.c71
-rw-r--r--drivers/net/wireless/Kconfig1
-rw-r--r--drivers/net/wireless/Makefile2
-rw-r--r--drivers/net/wireless/ath/ath9k/Kconfig8
-rw-r--r--drivers/net/wireless/ath/ath9k/ani.c57
-rw-r--r--drivers/net/wireless/ath/ath9k/ani.h12
-rw-r--r--drivers/net/wireless/ath/ath9k/ar5008_phy.c6
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_hw.c4
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_initvals.h14
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_mac.c5
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_paprd.c19
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.c6
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/beacon.c8
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c418
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.h59
-rw-r--r--drivers/net/wireless/ath/ath9k/htc.h7
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_beacon.c5
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_init.c7
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_main.c35
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_txrx.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c17
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h13
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c19
-rw-r--r--drivers/net/wireless/ath/ath9k/link.c9
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.c16
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.h4
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c47
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c9
-rw-r--r--drivers/net/wireless/ath/ath9k/wow.c168
-rw-r--r--drivers/net/wireless/ath/wil6210/Kconfig12
-rw-r--r--drivers/net/wireless/ath/wil6210/Makefile21
-rw-r--r--drivers/net/wireless/ath/wil6210/cfg80211.c4
-rw-r--r--drivers/net/wireless/ath/wil6210/debug.c69
-rw-r--r--drivers/net/wireless/ath/wil6210/debugfs.c8
-rw-r--r--drivers/net/wireless/ath/wil6210/interrupt.c29
-rw-r--r--drivers/net/wireless/ath/wil6210/main.c24
-rw-r--r--drivers/net/wireless/ath/wil6210/netdev.c54
-rw-r--r--drivers/net/wireless/ath/wil6210/trace.c20
-rw-r--r--drivers/net/wireless/ath/wil6210/trace.h235
-rw-r--r--drivers/net/wireless/ath/wil6210/txrx.c175
-rw-r--r--drivers/net/wireless/ath/wil6210/txrx.h32
-rw-r--r--drivers/net/wireless/ath/wil6210/wil6210.h27
-rw-r--r--drivers/net/wireless/ath/wil6210/wmi.c13
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c3
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/ampdu.c2
-rw-r--r--drivers/net/wireless/cw1200/Kconfig30
-rw-r--r--drivers/net/wireless/cw1200/Makefile21
-rw-r--r--drivers/net/wireless/cw1200/bh.c619
-rw-r--r--drivers/net/wireless/cw1200/bh.h28
-rw-r--r--drivers/net/wireless/cw1200/cw1200.h323
-rw-r--r--drivers/net/wireless/cw1200/cw1200_sdio.c425
-rw-r--r--drivers/net/wireless/cw1200/cw1200_spi.c463
-rw-r--r--drivers/net/wireless/cw1200/debug.c428
-rw-r--r--drivers/net/wireless/cw1200/debug.h93
-rw-r--r--drivers/net/wireless/cw1200/fwio.c520
-rw-r--r--drivers/net/wireless/cw1200/fwio.h39
-rw-r--r--drivers/net/wireless/cw1200/hwbus.h33
-rw-r--r--drivers/net/wireless/cw1200/hwio.c310
-rw-r--r--drivers/net/wireless/cw1200/hwio.h246
-rw-r--r--drivers/net/wireless/cw1200/main.c600
-rw-r--r--drivers/net/wireless/cw1200/pm.c367
-rw-r--r--drivers/net/wireless/cw1200/pm.h43
-rw-r--r--drivers/net/wireless/cw1200/queue.c583
-rw-r--r--drivers/net/wireless/cw1200/queue.h116
-rw-r--r--drivers/net/wireless/cw1200/scan.c461
-rw-r--r--drivers/net/wireless/cw1200/scan.h56
-rw-r--r--drivers/net/wireless/cw1200/sta.c2404
-rw-r--r--drivers/net/wireless/cw1200/sta.h123
-rw-r--r--drivers/net/wireless/cw1200/txrx.c1474
-rw-r--r--drivers/net/wireless/cw1200/txrx.h106
-rw-r--r--drivers/net/wireless/cw1200/wsm.c1823
-rw-r--r--drivers/net/wireless/cw1200/wsm.h1873
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2100.c2
-rw-r--r--drivers/net/wireless/iwlegacy/commands.h8
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/agn.h21
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/calib.c8
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/commands.h12
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/dev.h57
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/devices.c107
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/lib.c20
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/mac80211.c18
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/main.c45
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/power.c6
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/rs.c8
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/rx.c2
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/scan.c12
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/tt.c2
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/tx.c12
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/ucode.c10
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-1000.c3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-2000.c39
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c32
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-7000.c53
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-config.h49
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-csr.h19
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-drv.c3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c15
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fw.h7
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-modparams.h1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-nvm-parse.c20
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-nvm-parse.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-prph.h12
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans.h21
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/Makefile2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/bt-coex.c8
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/d3.c176
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/debugfs.c428
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h4
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h8
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-power.h93
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h1
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api.h233
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw.c37
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c36
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac80211.c262
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mvm.h200
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/nvm.c212
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/ops.c37
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c76
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/power.c196
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/quota.c25
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rs.c141
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rs.h17
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rx.c22
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/scan.c6
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/sta.c13
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/sta.h6
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/tt.c512
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/tx.c2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/utils.c41
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/drv.c50
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/trans.c51
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/tx.c17
-rw-r--r--drivers/net/wireless/mwifiex/Kconfig4
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.c77
-rw-r--r--drivers/net/wireless/mwifiex/cmdevt.c1
-rw-r--r--drivers/net/wireless/mwifiex/fw.h17
-rw-r--r--drivers/net/wireless/mwifiex/init.c53
-rw-r--r--drivers/net/wireless/mwifiex/join.c5
-rw-r--r--drivers/net/wireless/mwifiex/main.c14
-rw-r--r--drivers/net/wireless/mwifiex/main.h5
-rw-r--r--drivers/net/wireless/mwifiex/scan.c23
-rw-r--r--drivers/net/wireless/mwifiex/sdio.c463
-rw-r--r--drivers/net/wireless/mwifiex/sdio.h340
-rw-r--r--drivers/net/wireless/mwifiex/sta_cmd.c62
-rw-r--r--drivers/net/wireless/mwifiex/sta_cmdresp.c17
-rw-r--r--drivers/net/wireless/mwifiex/uap_cmd.c21
-rw-r--r--drivers/net/wireless/mwifiex/uap_event.c25
-rw-r--r--drivers/net/wireless/mwl8k.c11
-rw-r--r--drivers/net/wireless/p54/p54spi.c37
-rw-r--r--drivers/net/wireless/rt2x00/rt2800lib.c782
-rw-r--r--drivers/net/wireless/rt2x00/rt2800pci.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2800usb.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c36
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00pci.c9
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.c44
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192de/dm.c2
-rw-r--r--include/linux/ieee80211.h9
-rw-r--r--include/linux/platform_data/net-cw1200.h81
-rw-r--r--include/linux/ssb/ssb_regs.h1
-rw-r--r--include/net/cfg80211.h89
-rw-r--r--include/net/ieee80211_radiotap.h7
-rw-r--r--include/net/mac80211.h14
-rw-r--r--include/uapi/linux/nl80211.h24
-rw-r--r--net/mac80211/aes_ccm.c6
-rw-r--r--net/mac80211/cfg.c33
-rw-r--r--net/mac80211/debugfs_netdev.c15
-rw-r--r--net/mac80211/driver-ops.h3
-rw-r--r--net/mac80211/ht.c4
-rw-r--r--net/mac80211/ibss.c49
-rw-r--r--net/mac80211/ieee80211_i.h28
-rw-r--r--net/mac80211/iface.c29
-rw-r--r--net/mac80211/key.c24
-rw-r--r--net/mac80211/key.h15
-rw-r--r--net/mac80211/main.c4
-rw-r--r--net/mac80211/mesh.c38
-rw-r--r--net/mac80211/mesh_plink.c7
-rw-r--r--net/mac80211/mlme.c345
-rw-r--r--net/mac80211/rx.c30
-rw-r--r--net/mac80211/sta_info.c2
-rw-r--r--net/mac80211/sta_info.h5
-rw-r--r--net/mac80211/tx.c5
-rw-r--r--net/mac80211/util.c36
-rw-r--r--net/mac80211/wep.c48
-rw-r--r--net/mac80211/wpa.c68
-rw-r--r--net/wireless/core.c224
-rw-r--r--net/wireless/core.h93
-rw-r--r--net/wireless/debugfs.c4
-rw-r--r--net/wireless/ibss.c10
-rw-r--r--net/wireless/mesh.c3
-rw-r--r--net/wireless/mlme.c216
-rw-r--r--net/wireless/nl80211.c350
-rw-r--r--net/wireless/reg.c136
-rw-r--r--net/wireless/scan.c47
-rw-r--r--net/wireless/sme.c107
-rw-r--r--net/wireless/sysfs.c8
-rw-r--r--net/wireless/trace.h4
-rw-r--r--net/wireless/util.c39
-rw-r--r--net/wireless/wext-compat.c22
-rw-r--r--net/wireless/wext-sme.c41
206 files changed, 19923 insertions, 3391 deletions
diff --git a/Documentation/DocBook/80211.tmpl b/Documentation/DocBook/80211.tmpl
index 0f6a3edcd44b..ebe89694cf81 100644
--- a/Documentation/DocBook/80211.tmpl
+++ b/Documentation/DocBook/80211.tmpl
@@ -132,9 +132,7 @@
132!Finclude/net/cfg80211.h cfg80211_send_rx_assoc 132!Finclude/net/cfg80211.h cfg80211_send_rx_assoc
133!Finclude/net/cfg80211.h cfg80211_send_assoc_timeout 133!Finclude/net/cfg80211.h cfg80211_send_assoc_timeout
134!Finclude/net/cfg80211.h cfg80211_send_deauth 134!Finclude/net/cfg80211.h cfg80211_send_deauth
135!Finclude/net/cfg80211.h __cfg80211_send_deauth
136!Finclude/net/cfg80211.h cfg80211_send_disassoc 135!Finclude/net/cfg80211.h cfg80211_send_disassoc
137!Finclude/net/cfg80211.h __cfg80211_send_disassoc
138!Finclude/net/cfg80211.h cfg80211_ibss_joined 136!Finclude/net/cfg80211.h cfg80211_ibss_joined
139!Finclude/net/cfg80211.h cfg80211_connect_result 137!Finclude/net/cfg80211.h cfg80211_connect_result
140!Finclude/net/cfg80211.h cfg80211_roamed 138!Finclude/net/cfg80211.h cfg80211_roamed
diff --git a/MAINTAINERS b/MAINTAINERS
index f35a259a6564..0518ec49467b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2299,6 +2299,11 @@ M: Jaya Kumar <jayakumar.alsa@gmail.com>
2299S: Maintained 2299S: Maintained
2300F: sound/pci/cs5535audio/ 2300F: sound/pci/cs5535audio/
2301 2301
2302CW1200 WLAN driver
2303M: Solomon Peachy <pizza@shaftnet.org>
2304S: Maintained
2305F: drivers/net/wireless/cw1200/
2306
2302CX18 VIDEO4LINUX DRIVER 2307CX18 VIDEO4LINUX DRIVER
2303M: Andy Walls <awalls@md.metrocast.net> 2308M: Andy Walls <awalls@md.metrocast.net>
2304L: ivtv-devel@ivtvdriver.org (moderated for non-subscribers) 2309L: ivtv-devel@ivtvdriver.org (moderated for non-subscribers)
diff --git a/drivers/bcma/sprom.c b/drivers/bcma/sprom.c
index 8934298a638d..de15b4f4b237 100644
--- a/drivers/bcma/sprom.c
+++ b/drivers/bcma/sprom.c
@@ -72,12 +72,12 @@ fail:
72 * R/W ops. 72 * R/W ops.
73 **************************************************/ 73 **************************************************/
74 74
75static void bcma_sprom_read(struct bcma_bus *bus, u16 offset, u16 *sprom) 75static void bcma_sprom_read(struct bcma_bus *bus, u16 offset, u16 *sprom,
76 size_t words)
76{ 77{
77 int i; 78 int i;
78 for (i = 0; i < SSB_SPROMSIZE_WORDS_R4; i++) 79 for (i = 0; i < words; i++)
79 sprom[i] = bcma_read16(bus->drv_cc.core, 80 sprom[i] = bcma_read16(bus->drv_cc.core, offset + (i * 2));
80 offset + (i * 2));
81} 81}
82 82
83/************************************************** 83/**************************************************
@@ -124,29 +124,29 @@ static inline u8 bcma_crc8(u8 crc, u8 data)
124 return t[crc ^ data]; 124 return t[crc ^ data];
125} 125}
126 126
127static u8 bcma_sprom_crc(const u16 *sprom) 127static u8 bcma_sprom_crc(const u16 *sprom, size_t words)
128{ 128{
129 int word; 129 int word;
130 u8 crc = 0xFF; 130 u8 crc = 0xFF;
131 131
132 for (word = 0; word < SSB_SPROMSIZE_WORDS_R4 - 1; word++) { 132 for (word = 0; word < words - 1; word++) {
133 crc = bcma_crc8(crc, sprom[word] & 0x00FF); 133 crc = bcma_crc8(crc, sprom[word] & 0x00FF);
134 crc = bcma_crc8(crc, (sprom[word] & 0xFF00) >> 8); 134 crc = bcma_crc8(crc, (sprom[word] & 0xFF00) >> 8);
135 } 135 }
136 crc = bcma_crc8(crc, sprom[SSB_SPROMSIZE_WORDS_R4 - 1] & 0x00FF); 136 crc = bcma_crc8(crc, sprom[words - 1] & 0x00FF);
137 crc ^= 0xFF; 137 crc ^= 0xFF;
138 138
139 return crc; 139 return crc;
140} 140}
141 141
142static int bcma_sprom_check_crc(const u16 *sprom) 142static int bcma_sprom_check_crc(const u16 *sprom, size_t words)
143{ 143{
144 u8 crc; 144 u8 crc;
145 u8 expected_crc; 145 u8 expected_crc;
146 u16 tmp; 146 u16 tmp;
147 147
148 crc = bcma_sprom_crc(sprom); 148 crc = bcma_sprom_crc(sprom, words);
149 tmp = sprom[SSB_SPROMSIZE_WORDS_R4 - 1] & SSB_SPROM_REVISION_CRC; 149 tmp = sprom[words - 1] & SSB_SPROM_REVISION_CRC;
150 expected_crc = tmp >> SSB_SPROM_REVISION_CRC_SHIFT; 150 expected_crc = tmp >> SSB_SPROM_REVISION_CRC_SHIFT;
151 if (crc != expected_crc) 151 if (crc != expected_crc)
152 return -EPROTO; 152 return -EPROTO;
@@ -154,21 +154,25 @@ static int bcma_sprom_check_crc(const u16 *sprom)
154 return 0; 154 return 0;
155} 155}
156 156
157static int bcma_sprom_valid(const u16 *sprom) 157static int bcma_sprom_valid(struct bcma_bus *bus, const u16 *sprom,
158 size_t words)
158{ 159{
159 u16 revision; 160 u16 revision;
160 int err; 161 int err;
161 162
162 err = bcma_sprom_check_crc(sprom); 163 err = bcma_sprom_check_crc(sprom, words);
163 if (err) 164 if (err)
164 return err; 165 return err;
165 166
166 revision = sprom[SSB_SPROMSIZE_WORDS_R4 - 1] & SSB_SPROM_REVISION_REV; 167 revision = sprom[words - 1] & SSB_SPROM_REVISION_REV;
167 if (revision != 8 && revision != 9) { 168 if (revision != 8 && revision != 9 && revision != 10) {
168 pr_err("Unsupported SPROM revision: %d\n", revision); 169 pr_err("Unsupported SPROM revision: %d\n", revision);
169 return -ENOENT; 170 return -ENOENT;
170 } 171 }
171 172
173 bus->sprom.revision = revision;
174 bcma_debug(bus, "Found SPROM revision %d\n", revision);
175
172 return 0; 176 return 0;
173} 177}
174 178
@@ -208,9 +212,6 @@ static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom)
208 BUILD_BUG_ON(ARRAY_SIZE(pwr_info_offset) != 212 BUILD_BUG_ON(ARRAY_SIZE(pwr_info_offset) !=
209 ARRAY_SIZE(bus->sprom.core_pwr_info)); 213 ARRAY_SIZE(bus->sprom.core_pwr_info));
210 214
211 bus->sprom.revision = sprom[SSB_SPROMSIZE_WORDS_R4 - 1] &
212 SSB_SPROM_REVISION_REV;
213
214 for (i = 0; i < 3; i++) { 215 for (i = 0; i < 3; i++) {
215 v = sprom[SPOFF(SSB_SPROM8_IL0MAC) + i]; 216 v = sprom[SPOFF(SSB_SPROM8_IL0MAC) + i];
216 *(((__be16 *)bus->sprom.il0mac) + i) = cpu_to_be16(v); 217 *(((__be16 *)bus->sprom.il0mac) + i) = cpu_to_be16(v);
@@ -502,7 +503,6 @@ static bool bcma_sprom_onchip_available(struct bcma_bus *bus)
502 case BCMA_CHIP_ID_BCM4331: 503 case BCMA_CHIP_ID_BCM4331:
503 present = chip_status & BCMA_CC_CHIPST_4331_OTP_PRESENT; 504 present = chip_status & BCMA_CC_CHIPST_4331_OTP_PRESENT;
504 break; 505 break;
505
506 case BCMA_CHIP_ID_BCM43224: 506 case BCMA_CHIP_ID_BCM43224:
507 case BCMA_CHIP_ID_BCM43225: 507 case BCMA_CHIP_ID_BCM43225:
508 /* for these chips OTP is always available */ 508 /* for these chips OTP is always available */
@@ -550,7 +550,9 @@ int bcma_sprom_get(struct bcma_bus *bus)
550{ 550{
551 u16 offset = BCMA_CC_SPROM; 551 u16 offset = BCMA_CC_SPROM;
552 u16 *sprom; 552 u16 *sprom;
553 int err = 0; 553 size_t sprom_sizes[] = { SSB_SPROMSIZE_WORDS_R4,
554 SSB_SPROMSIZE_WORDS_R10, };
555 int i, err = 0;
554 556
555 if (!bus->drv_cc.core) 557 if (!bus->drv_cc.core)
556 return -EOPNOTSUPP; 558 return -EOPNOTSUPP;
@@ -579,32 +581,37 @@ int bcma_sprom_get(struct bcma_bus *bus)
579 } 581 }
580 } 582 }
581 583
582 sprom = kcalloc(SSB_SPROMSIZE_WORDS_R4, sizeof(u16),
583 GFP_KERNEL);
584 if (!sprom)
585 return -ENOMEM;
586
587 if (bus->chipinfo.id == BCMA_CHIP_ID_BCM4331 || 584 if (bus->chipinfo.id == BCMA_CHIP_ID_BCM4331 ||
588 bus->chipinfo.id == BCMA_CHIP_ID_BCM43431) 585 bus->chipinfo.id == BCMA_CHIP_ID_BCM43431)
589 bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, false); 586 bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, false);
590 587
591 bcma_debug(bus, "SPROM offset 0x%x\n", offset); 588 bcma_debug(bus, "SPROM offset 0x%x\n", offset);
592 bcma_sprom_read(bus, offset, sprom); 589 for (i = 0; i < ARRAY_SIZE(sprom_sizes); i++) {
590 size_t words = sprom_sizes[i];
591
592 sprom = kcalloc(words, sizeof(u16), GFP_KERNEL);
593 if (!sprom)
594 return -ENOMEM;
595
596 bcma_sprom_read(bus, offset, sprom, words);
597 err = bcma_sprom_valid(bus, sprom, words);
598 if (!err)
599 break;
600
601 kfree(sprom);
602 }
593 603
594 if (bus->chipinfo.id == BCMA_CHIP_ID_BCM4331 || 604 if (bus->chipinfo.id == BCMA_CHIP_ID_BCM4331 ||
595 bus->chipinfo.id == BCMA_CHIP_ID_BCM43431) 605 bus->chipinfo.id == BCMA_CHIP_ID_BCM43431)
596 bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, true); 606 bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, true);
597 607
598 err = bcma_sprom_valid(sprom);
599 if (err) { 608 if (err) {
600 bcma_warn(bus, "invalid sprom read from the PCIe card, try to use fallback sprom\n"); 609 bcma_warn(bus, "Invalid SPROM read from the PCIe card, trying to use fallback SPROM\n");
601 err = bcma_fill_sprom_with_fallback(bus, &bus->sprom); 610 err = bcma_fill_sprom_with_fallback(bus, &bus->sprom);
602 goto out; 611 } else {
612 bcma_sprom_extract_r8(bus, sprom);
613 kfree(sprom);
603 } 614 }
604 615
605 bcma_sprom_extract_r8(bus, sprom);
606
607out:
608 kfree(sprom);
609 return err; 616 return err;
610} 617}
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index f8f0156dff4e..200020eb3005 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -280,5 +280,6 @@ source "drivers/net/wireless/rtlwifi/Kconfig"
280source "drivers/net/wireless/ti/Kconfig" 280source "drivers/net/wireless/ti/Kconfig"
281source "drivers/net/wireless/zd1211rw/Kconfig" 281source "drivers/net/wireless/zd1211rw/Kconfig"
282source "drivers/net/wireless/mwifiex/Kconfig" 282source "drivers/net/wireless/mwifiex/Kconfig"
283source "drivers/net/wireless/cw1200/Kconfig"
283 284
284endif # WLAN 285endif # WLAN
diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile
index 67156efe14c4..0fab227025be 100644
--- a/drivers/net/wireless/Makefile
+++ b/drivers/net/wireless/Makefile
@@ -57,3 +57,5 @@ obj-$(CONFIG_MWIFIEX) += mwifiex/
57 57
58obj-$(CONFIG_BRCMFMAC) += brcm80211/ 58obj-$(CONFIG_BRCMFMAC) += brcm80211/
59obj-$(CONFIG_BRCMSMAC) += brcm80211/ 59obj-$(CONFIG_BRCMSMAC) += brcm80211/
60
61obj-$(CONFIG_CW1200) += cw1200/
diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig
index f3dc124c60c7..3b078515b422 100644
--- a/drivers/net/wireless/ath/ath9k/Kconfig
+++ b/drivers/net/wireless/ath/ath9k/Kconfig
@@ -84,14 +84,6 @@ config ATH9K_DFS_CERTIFIED
84 developed. At this point enabling this option won't do anything 84 developed. At this point enabling this option won't do anything
85 except increase code size. 85 except increase code size.
86 86
87config ATH9K_MAC_DEBUG
88 bool "Atheros MAC statistics"
89 depends on ATH9K_DEBUGFS
90 default y
91 ---help---
92 This option enables collection of statistics for Rx/Tx status
93 data and some other MAC related statistics
94
95config ATH9K_RATE_CONTROL 87config ATH9K_RATE_CONTROL
96 bool "Atheros ath9k rate control" 88 bool "Atheros ath9k rate control"
97 depends on ATH9K 89 depends on ATH9K
diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c
index 7ecd40f07a74..e91725bf401c 100644
--- a/drivers/net/wireless/ath/ath9k/ani.c
+++ b/drivers/net/wireless/ath/ath9k/ani.c
@@ -118,10 +118,10 @@ static void ath9k_ani_restart(struct ath_hw *ah)
118{ 118{
119 struct ar5416AniState *aniState; 119 struct ar5416AniState *aniState;
120 120
121 if (!DO_ANI(ah)) 121 if (!ah->curchan)
122 return; 122 return;
123 123
124 aniState = &ah->curchan->ani; 124 aniState = &ah->ani;
125 aniState->listenTime = 0; 125 aniState->listenTime = 0;
126 126
127 ENABLE_REGWRITE_BUFFER(ah); 127 ENABLE_REGWRITE_BUFFER(ah);
@@ -143,7 +143,7 @@ static void ath9k_ani_restart(struct ath_hw *ah)
143static void ath9k_hw_set_ofdm_nil(struct ath_hw *ah, u8 immunityLevel, 143static void ath9k_hw_set_ofdm_nil(struct ath_hw *ah, u8 immunityLevel,
144 bool scan) 144 bool scan)
145{ 145{
146 struct ar5416AniState *aniState = &ah->curchan->ani; 146 struct ar5416AniState *aniState = &ah->ani;
147 struct ath_common *common = ath9k_hw_common(ah); 147 struct ath_common *common = ath9k_hw_common(ah);
148 const struct ani_ofdm_level_entry *entry_ofdm; 148 const struct ani_ofdm_level_entry *entry_ofdm;
149 const struct ani_cck_level_entry *entry_cck; 149 const struct ani_cck_level_entry *entry_cck;
@@ -195,10 +195,10 @@ static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hw *ah)
195{ 195{
196 struct ar5416AniState *aniState; 196 struct ar5416AniState *aniState;
197 197
198 if (!DO_ANI(ah)) 198 if (!ah->curchan)
199 return; 199 return;
200 200
201 aniState = &ah->curchan->ani; 201 aniState = &ah->ani;
202 202
203 if (aniState->ofdmNoiseImmunityLevel < ATH9K_ANI_OFDM_MAX_LEVEL) 203 if (aniState->ofdmNoiseImmunityLevel < ATH9K_ANI_OFDM_MAX_LEVEL)
204 ath9k_hw_set_ofdm_nil(ah, aniState->ofdmNoiseImmunityLevel + 1, false); 204 ath9k_hw_set_ofdm_nil(ah, aniState->ofdmNoiseImmunityLevel + 1, false);
@@ -210,7 +210,7 @@ static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hw *ah)
210static void ath9k_hw_set_cck_nil(struct ath_hw *ah, u_int8_t immunityLevel, 210static void ath9k_hw_set_cck_nil(struct ath_hw *ah, u_int8_t immunityLevel,
211 bool scan) 211 bool scan)
212{ 212{
213 struct ar5416AniState *aniState = &ah->curchan->ani; 213 struct ar5416AniState *aniState = &ah->ani;
214 struct ath_common *common = ath9k_hw_common(ah); 214 struct ath_common *common = ath9k_hw_common(ah);
215 const struct ani_ofdm_level_entry *entry_ofdm; 215 const struct ani_ofdm_level_entry *entry_ofdm;
216 const struct ani_cck_level_entry *entry_cck; 216 const struct ani_cck_level_entry *entry_cck;
@@ -251,10 +251,10 @@ static void ath9k_hw_ani_cck_err_trigger(struct ath_hw *ah)
251{ 251{
252 struct ar5416AniState *aniState; 252 struct ar5416AniState *aniState;
253 253
254 if (!DO_ANI(ah)) 254 if (!ah->curchan)
255 return; 255 return;
256 256
257 aniState = &ah->curchan->ani; 257 aniState = &ah->ani;
258 258
259 if (aniState->cckNoiseImmunityLevel < ATH9K_ANI_CCK_MAX_LEVEL) 259 if (aniState->cckNoiseImmunityLevel < ATH9K_ANI_CCK_MAX_LEVEL)
260 ath9k_hw_set_cck_nil(ah, aniState->cckNoiseImmunityLevel + 1, 260 ath9k_hw_set_cck_nil(ah, aniState->cckNoiseImmunityLevel + 1,
@@ -269,7 +269,7 @@ static void ath9k_hw_ani_lower_immunity(struct ath_hw *ah)
269{ 269{
270 struct ar5416AniState *aniState; 270 struct ar5416AniState *aniState;
271 271
272 aniState = &ah->curchan->ani; 272 aniState = &ah->ani;
273 273
274 /* lower OFDM noise immunity */ 274 /* lower OFDM noise immunity */
275 if (aniState->ofdmNoiseImmunityLevel > 0 && 275 if (aniState->ofdmNoiseImmunityLevel > 0 &&
@@ -292,12 +292,12 @@ static void ath9k_hw_ani_lower_immunity(struct ath_hw *ah)
292 */ 292 */
293void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning) 293void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning)
294{ 294{
295 struct ar5416AniState *aniState = &ah->curchan->ani; 295 struct ar5416AniState *aniState = &ah->ani;
296 struct ath9k_channel *chan = ah->curchan; 296 struct ath9k_channel *chan = ah->curchan;
297 struct ath_common *common = ath9k_hw_common(ah); 297 struct ath_common *common = ath9k_hw_common(ah);
298 int ofdm_nil, cck_nil; 298 int ofdm_nil, cck_nil;
299 299
300 if (!DO_ANI(ah)) 300 if (!ah->curchan)
301 return; 301 return;
302 302
303 BUG_ON(aniState == NULL); 303 BUG_ON(aniState == NULL);
@@ -380,7 +380,7 @@ void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning)
380static bool ath9k_hw_ani_read_counters(struct ath_hw *ah) 380static bool ath9k_hw_ani_read_counters(struct ath_hw *ah)
381{ 381{
382 struct ath_common *common = ath9k_hw_common(ah); 382 struct ath_common *common = ath9k_hw_common(ah);
383 struct ar5416AniState *aniState = &ah->curchan->ani; 383 struct ar5416AniState *aniState = &ah->ani;
384 u32 phyCnt1, phyCnt2; 384 u32 phyCnt1, phyCnt2;
385 int32_t listenTime; 385 int32_t listenTime;
386 386
@@ -415,10 +415,10 @@ void ath9k_hw_ani_monitor(struct ath_hw *ah, struct ath9k_channel *chan)
415 struct ath_common *common = ath9k_hw_common(ah); 415 struct ath_common *common = ath9k_hw_common(ah);
416 u32 ofdmPhyErrRate, cckPhyErrRate; 416 u32 ofdmPhyErrRate, cckPhyErrRate;
417 417
418 if (!DO_ANI(ah)) 418 if (!ah->curchan)
419 return; 419 return;
420 420
421 aniState = &ah->curchan->ani; 421 aniState = &ah->ani;
422 if (!ath9k_hw_ani_read_counters(ah)) 422 if (!ath9k_hw_ani_read_counters(ah))
423 return; 423 return;
424 424
@@ -490,32 +490,22 @@ EXPORT_SYMBOL(ath9k_hw_disable_mib_counters);
490void ath9k_hw_ani_init(struct ath_hw *ah) 490void ath9k_hw_ani_init(struct ath_hw *ah)
491{ 491{
492 struct ath_common *common = ath9k_hw_common(ah); 492 struct ath_common *common = ath9k_hw_common(ah);
493 int i; 493 struct ar5416AniState *ani = &ah->ani;
494 494
495 ath_dbg(common, ANI, "Initialize ANI\n"); 495 ath_dbg(common, ANI, "Initialize ANI\n");
496 496
497 ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH; 497 ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH;
498 ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW; 498 ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW;
499
500 ah->config.cck_trig_high = ATH9K_ANI_CCK_TRIG_HIGH; 499 ah->config.cck_trig_high = ATH9K_ANI_CCK_TRIG_HIGH;
501 ah->config.cck_trig_low = ATH9K_ANI_CCK_TRIG_LOW; 500 ah->config.cck_trig_low = ATH9K_ANI_CCK_TRIG_LOW;
502 501
503 for (i = 0; i < ARRAY_SIZE(ah->channels); i++) { 502 ani->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL;
504 struct ath9k_channel *chan = &ah->channels[i]; 503 ani->firstepLevel = ATH9K_ANI_FIRSTEP_LVL;
505 struct ar5416AniState *ani = &chan->ani; 504 ani->mrcCCK = AR_SREV_9300_20_OR_LATER(ah) ? true : false;
506 505 ani->ofdmsTurn = true;
507 ani->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL; 506 ani->ofdmWeakSigDetect = true;
508 507 ani->cckNoiseImmunityLevel = ATH9K_ANI_CCK_DEF_LEVEL;
509 ani->firstepLevel = ATH9K_ANI_FIRSTEP_LVL; 508 ani->ofdmNoiseImmunityLevel = ATH9K_ANI_OFDM_DEF_LEVEL;
510
511 ani->mrcCCK = AR_SREV_9300_20_OR_LATER(ah) ? true : false;
512
513 ani->ofdmsTurn = true;
514
515 ani->ofdmWeakSigDetect = ATH9K_ANI_USE_OFDM_WEAK_SIG;
516 ani->cckNoiseImmunityLevel = ATH9K_ANI_CCK_DEF_LEVEL;
517 ani->ofdmNoiseImmunityLevel = ATH9K_ANI_OFDM_DEF_LEVEL;
518 }
519 509
520 /* 510 /*
521 * since we expect some ongoing maintenance on the tables, let's sanity 511 * since we expect some ongoing maintenance on the tables, let's sanity
@@ -524,9 +514,6 @@ void ath9k_hw_ani_init(struct ath_hw *ah)
524 ah->aniperiod = ATH9K_ANI_PERIOD; 514 ah->aniperiod = ATH9K_ANI_PERIOD;
525 ah->config.ani_poll_interval = ATH9K_ANI_POLLINTERVAL; 515 ah->config.ani_poll_interval = ATH9K_ANI_POLLINTERVAL;
526 516
527 if (ah->config.enable_ani)
528 ah->proc_phyerr |= HAL_PROCESS_ANI;
529
530 ath9k_ani_restart(ah); 517 ath9k_ani_restart(ah);
531 ath9k_enable_mib_counters(ah); 518 ath9k_enable_mib_counters(ah);
532} 519}
diff --git a/drivers/net/wireless/ath/ath9k/ani.h b/drivers/net/wireless/ath/ath9k/ani.h
index dddb1361039a..78b9fa9f6455 100644
--- a/drivers/net/wireless/ath/ath9k/ani.h
+++ b/drivers/net/wireless/ath/ath9k/ani.h
@@ -17,10 +17,6 @@
17#ifndef ANI_H 17#ifndef ANI_H
18#define ANI_H 18#define ANI_H
19 19
20#define HAL_PROCESS_ANI 0x00000001
21
22#define DO_ANI(ah) (((ah)->proc_phyerr & HAL_PROCESS_ANI) && ah->curchan)
23
24#define BEACON_RSSI(ahp) (ahp->stats.avgbrssi) 20#define BEACON_RSSI(ahp) (ahp->stats.avgbrssi)
25 21
26/* units are errors per second */ 22/* units are errors per second */
@@ -38,11 +34,7 @@
38#define ATH9K_ANI_CCK_TRIG_LOW 300 34#define ATH9K_ANI_CCK_TRIG_LOW 300
39 35
40#define ATH9K_ANI_NOISE_IMMUNE_LVL 4 36#define ATH9K_ANI_NOISE_IMMUNE_LVL 4
41#define ATH9K_ANI_USE_OFDM_WEAK_SIG true
42#define ATH9K_ANI_CCK_WEAK_SIG_THR false
43
44#define ATH9K_ANI_SPUR_IMMUNE_LVL 3 37#define ATH9K_ANI_SPUR_IMMUNE_LVL 3
45
46#define ATH9K_ANI_FIRSTEP_LVL 2 38#define ATH9K_ANI_FIRSTEP_LVL 2
47 39
48#define ATH9K_ANI_RSSI_THR_HIGH 40 40#define ATH9K_ANI_RSSI_THR_HIGH 40
@@ -111,7 +103,7 @@ struct ar5416AniState {
111 u8 mrcCCK; 103 u8 mrcCCK;
112 u8 spurImmunityLevel; 104 u8 spurImmunityLevel;
113 u8 firstepLevel; 105 u8 firstepLevel;
114 u8 ofdmWeakSigDetect; 106 bool ofdmWeakSigDetect;
115 u32 listenTime; 107 u32 listenTime;
116 u32 ofdmPhyErrCount; 108 u32 ofdmPhyErrCount;
117 u32 cckPhyErrCount; 109 u32 cckPhyErrCount;
@@ -119,8 +111,6 @@ struct ar5416AniState {
119}; 111};
120 112
121struct ar5416Stats { 113struct ar5416Stats {
122 u32 ast_ani_niup;
123 u32 ast_ani_nidown;
124 u32 ast_ani_spurup; 114 u32 ast_ani_spurup;
125 u32 ast_ani_spurdown; 115 u32 ast_ani_spurdown;
126 u32 ast_ani_ofdmon; 116 u32 ast_ani_ofdmon;
diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
index 391da5ad6a99..d1acfe98918a 100644
--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
@@ -931,7 +931,7 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah,
931{ 931{
932 struct ath_common *common = ath9k_hw_common(ah); 932 struct ath_common *common = ath9k_hw_common(ah);
933 struct ath9k_channel *chan = ah->curchan; 933 struct ath9k_channel *chan = ah->curchan;
934 struct ar5416AniState *aniState = &chan->ani; 934 struct ar5416AniState *aniState = &ah->ani;
935 s32 value, value2; 935 s32 value, value2;
936 936
937 switch (cmd & ah->ani_function) { 937 switch (cmd & ah->ani_function) {
@@ -1207,7 +1207,7 @@ static void ar5008_hw_ani_cache_ini_regs(struct ath_hw *ah)
1207{ 1207{
1208 struct ath_common *common = ath9k_hw_common(ah); 1208 struct ath_common *common = ath9k_hw_common(ah);
1209 struct ath9k_channel *chan = ah->curchan; 1209 struct ath9k_channel *chan = ah->curchan;
1210 struct ar5416AniState *aniState = &chan->ani; 1210 struct ar5416AniState *aniState = &ah->ani;
1211 struct ath9k_ani_default *iniDef; 1211 struct ath9k_ani_default *iniDef;
1212 u32 val; 1212 u32 val;
1213 1213
@@ -1251,7 +1251,7 @@ static void ar5008_hw_ani_cache_ini_regs(struct ath_hw *ah)
1251 /* these levels just got reset to defaults by the INI */ 1251 /* these levels just got reset to defaults by the INI */
1252 aniState->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL; 1252 aniState->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL;
1253 aniState->firstepLevel = ATH9K_ANI_FIRSTEP_LVL; 1253 aniState->firstepLevel = ATH9K_ANI_FIRSTEP_LVL;
1254 aniState->ofdmWeakSigDetect = ATH9K_ANI_USE_OFDM_WEAK_SIG; 1254 aniState->ofdmWeakSigDetect = true;
1255 aniState->mrcCCK = false; /* not available on pre AR9003 */ 1255 aniState->mrcCCK = false; /* not available on pre AR9003 */
1256} 1256}
1257 1257
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
index 830daa12feb6..8dc2d089cdef 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
@@ -38,10 +38,6 @@ static int ar9002_hw_init_mode_regs(struct ath_hw *ah)
38 else 38 else
39 INIT_INI_ARRAY(&ah->iniPcieSerdes, 39 INIT_INI_ARRAY(&ah->iniPcieSerdes,
40 ar9280PciePhy_clkreq_always_on_L1_9280); 40 ar9280PciePhy_clkreq_always_on_L1_9280);
41#ifdef CONFIG_PM_SLEEP
42 INIT_INI_ARRAY(&ah->iniPcieSerdesWow,
43 ar9280PciePhy_awow);
44#endif
45 41
46 if (AR_SREV_9287_11_OR_LATER(ah)) { 42 if (AR_SREV_9287_11_OR_LATER(ah)) {
47 INIT_INI_ARRAY(&ah->iniModes, ar9287Modes_9287_1_1); 43 INIT_INI_ARRAY(&ah->iniModes, ar9287Modes_9287_1_1);
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_initvals.h b/drivers/net/wireless/ath/ath9k/ar9002_initvals.h
index beb6162cf97c..4d18c66a6790 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar9002_initvals.h
@@ -925,20 +925,6 @@ static const u32 ar9280PciePhy_clkreq_always_on_L1_9280[][2] = {
925 {0x00004044, 0x00000000}, 925 {0x00004044, 0x00000000},
926}; 926};
927 927
928static const u32 ar9280PciePhy_awow[][2] = {
929 /* Addr allmodes */
930 {0x00004040, 0x9248fd00},
931 {0x00004040, 0x24924924},
932 {0x00004040, 0xa8000019},
933 {0x00004040, 0x13160820},
934 {0x00004040, 0xe5980560},
935 {0x00004040, 0xc01dcffd},
936 {0x00004040, 0x1aaabe41},
937 {0x00004040, 0xbe105554},
938 {0x00004040, 0x00043007},
939 {0x00004044, 0x00000000},
940};
941
942static const u32 ar9285Modes_9285_1_2[][5] = { 928static const u32 ar9285Modes_9285_1_2[][5] = {
943 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 929 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
944 {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160}, 930 {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160},
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
index 301bf72c53bf..5163abd3937c 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
@@ -469,6 +469,7 @@ int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah, struct ath_rx_status *rxs,
469 469
470 rxs->rs_status = 0; 470 rxs->rs_status = 0;
471 rxs->rs_flags = 0; 471 rxs->rs_flags = 0;
472 rxs->flag = 0;
472 473
473 rxs->rs_datalen = rxsp->status2 & AR_DataLen; 474 rxs->rs_datalen = rxsp->status2 & AR_DataLen;
474 rxs->rs_tstamp = rxsp->status3; 475 rxs->rs_tstamp = rxsp->status3;
@@ -493,8 +494,8 @@ int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah, struct ath_rx_status *rxs,
493 rxs->rs_isaggr = (rxsp->status11 & AR_RxAggr) ? 1 : 0; 494 rxs->rs_isaggr = (rxsp->status11 & AR_RxAggr) ? 1 : 0;
494 rxs->rs_moreaggr = (rxsp->status11 & AR_RxMoreAggr) ? 1 : 0; 495 rxs->rs_moreaggr = (rxsp->status11 & AR_RxMoreAggr) ? 1 : 0;
495 rxs->rs_antenna = (MS(rxsp->status4, AR_RxAntenna) & 0x7); 496 rxs->rs_antenna = (MS(rxsp->status4, AR_RxAntenna) & 0x7);
496 rxs->rs_flags = (rxsp->status4 & AR_GI) ? ATH9K_RX_GI : 0; 497 rxs->flag |= (rxsp->status4 & AR_GI) ? RX_FLAG_SHORT_GI : 0;
497 rxs->rs_flags |= (rxsp->status4 & AR_2040) ? ATH9K_RX_2040 : 0; 498 rxs->flag |= (rxsp->status4 & AR_2040) ? RX_FLAG_40MHZ : 0;
498 499
499 rxs->evm0 = rxsp->status6; 500 rxs->evm0 = rxsp->status6;
500 rxs->evm1 = rxsp->status7; 501 rxs->evm1 = rxsp->status7;
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
index 09c1f9da67a0..6343cc91953e 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
@@ -454,6 +454,8 @@ static bool create_pa_curve(u32 *data_L, u32 *data_U, u32 *pa_table, u16 *gain)
454 if (accum_cnt <= thresh_accum_cnt) 454 if (accum_cnt <= thresh_accum_cnt)
455 continue; 455 continue;
456 456
457 max_index++;
458
457 /* sum(tx amplitude) */ 459 /* sum(tx amplitude) */
458 accum_tx = ((data_L[i] >> 16) & 0xffff) | 460 accum_tx = ((data_L[i] >> 16) & 0xffff) |
459 ((data_U[i] & 0x7ff) << 16); 461 ((data_U[i] & 0x7ff) << 16);
@@ -468,20 +470,21 @@ static bool create_pa_curve(u32 *data_L, u32 *data_U, u32 *pa_table, u16 *gain)
468 470
469 accum_tx <<= scale_factor; 471 accum_tx <<= scale_factor;
470 accum_rx <<= scale_factor; 472 accum_rx <<= scale_factor;
471 x_est[i + 1] = (((accum_tx + accum_cnt) / accum_cnt) + 32) >> 473 x_est[max_index] =
472 scale_factor; 474 (((accum_tx + accum_cnt) / accum_cnt) + 32) >>
475 scale_factor;
473 476
474 Y[i + 1] = ((((accum_rx + accum_cnt) / accum_cnt) + 32) >> 477 Y[max_index] =
478 ((((accum_rx + accum_cnt) / accum_cnt) + 32) >>
475 scale_factor) + 479 scale_factor) +
476 (1 << scale_factor) * max_index + 16; 480 (1 << scale_factor) * i + 16;
477 481
478 if (accum_ang >= (1 << 26)) 482 if (accum_ang >= (1 << 26))
479 accum_ang -= 1 << 27; 483 accum_ang -= 1 << 27;
480 484
481 theta[i + 1] = ((accum_ang * (1 << scale_factor)) + accum_cnt) / 485 theta[max_index] =
482 accum_cnt; 486 ((accum_ang * (1 << scale_factor)) + accum_cnt) /
483 487 accum_cnt;
484 max_index++;
485 } 488 }
486 489
487 /* 490 /*
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index e1714d7c9eeb..83e03857c014 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -905,7 +905,7 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah,
905{ 905{
906 struct ath_common *common = ath9k_hw_common(ah); 906 struct ath_common *common = ath9k_hw_common(ah);
907 struct ath9k_channel *chan = ah->curchan; 907 struct ath9k_channel *chan = ah->curchan;
908 struct ar5416AniState *aniState = &chan->ani; 908 struct ar5416AniState *aniState = &ah->ani;
909 s32 value, value2; 909 s32 value, value2;
910 910
911 switch (cmd & ah->ani_function) { 911 switch (cmd & ah->ani_function) {
@@ -1173,7 +1173,7 @@ static void ar9003_hw_ani_cache_ini_regs(struct ath_hw *ah)
1173 struct ath9k_ani_default *iniDef; 1173 struct ath9k_ani_default *iniDef;
1174 u32 val; 1174 u32 val;
1175 1175
1176 aniState = &ah->curchan->ani; 1176 aniState = &ah->ani;
1177 iniDef = &aniState->iniDef; 1177 iniDef = &aniState->iniDef;
1178 1178
1179 ath_dbg(common, ANI, "ver %d.%d opmode %u chan %d Mhz/0x%x\n", 1179 ath_dbg(common, ANI, "ver %d.%d opmode %u chan %d Mhz/0x%x\n",
@@ -1214,7 +1214,7 @@ static void ar9003_hw_ani_cache_ini_regs(struct ath_hw *ah)
1214 /* these levels just got reset to defaults by the INI */ 1214 /* these levels just got reset to defaults by the INI */
1215 aniState->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL; 1215 aniState->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL;
1216 aniState->firstepLevel = ATH9K_ANI_FIRSTEP_LVL; 1216 aniState->firstepLevel = ATH9K_ANI_FIRSTEP_LVL;
1217 aniState->ofdmWeakSigDetect = ATH9K_ANI_USE_OFDM_WEAK_SIG; 1217 aniState->ofdmWeakSigDetect = true;
1218 aniState->mrcCCK = true; 1218 aniState->mrcCCK = true;
1219} 1219}
1220 1220
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 42b03dc39d14..18fcee4e9d68 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -642,6 +642,7 @@ enum sc_op_flags {
642 SC_OP_ANI_RUN, 642 SC_OP_ANI_RUN,
643 SC_OP_PRIM_STA_VIF, 643 SC_OP_PRIM_STA_VIF,
644 SC_OP_HW_RESET, 644 SC_OP_HW_RESET,
645 SC_OP_SCANNING,
645}; 646};
646 647
647/* Powersave flags */ 648/* Powersave flags */
@@ -755,7 +756,6 @@ struct ath_softc {
755 struct rchan *rfs_chan_spec_scan; 756 struct rchan *rfs_chan_spec_scan;
756 enum spectral_mode spectral_mode; 757 enum spectral_mode spectral_mode;
757 struct ath_spec_scan spec_config; 758 struct ath_spec_scan spec_config;
758 int scanning;
759 759
760#ifdef CONFIG_PM_SLEEP 760#ifdef CONFIG_PM_SLEEP
761 atomic_t wow_got_bmiss_intr; 761 atomic_t wow_got_bmiss_intr;
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c
index 2ff570f7f8ff..fd1eebab8647 100644
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -39,7 +39,8 @@ static void ath9k_beaconq_config(struct ath_softc *sc)
39 39
40 ath9k_hw_get_txq_props(ah, sc->beacon.beaconq, &qi); 40 ath9k_hw_get_txq_props(ah, sc->beacon.beaconq, &qi);
41 41
42 if (sc->sc_ah->opmode == NL80211_IFTYPE_AP) { 42 if (sc->sc_ah->opmode == NL80211_IFTYPE_AP ||
43 sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT) {
43 /* Always burst out beacon and CAB traffic. */ 44 /* Always burst out beacon and CAB traffic. */
44 qi.tqi_aifs = 1; 45 qi.tqi_aifs = 1;
45 qi.tqi_cwmin = 0; 46 qi.tqi_cwmin = 0;
@@ -273,7 +274,8 @@ static int ath9k_beacon_choose_slot(struct ath_softc *sc)
273 u64 tsf; 274 u64 tsf;
274 int slot; 275 int slot;
275 276
276 if (sc->sc_ah->opmode != NL80211_IFTYPE_AP) { 277 if (sc->sc_ah->opmode != NL80211_IFTYPE_AP &&
278 sc->sc_ah->opmode != NL80211_IFTYPE_MESH_POINT) {
277 ath_dbg(common, BEACON, "slot 0, tsf: %llu\n", 279 ath_dbg(common, BEACON, "slot 0, tsf: %llu\n",
278 ath9k_hw_gettsf64(sc->sc_ah)); 280 ath9k_hw_gettsf64(sc->sc_ah));
279 return 0; 281 return 0;
@@ -765,10 +767,10 @@ void ath9k_set_beacon(struct ath_softc *sc)
765 767
766 switch (sc->sc_ah->opmode) { 768 switch (sc->sc_ah->opmode) {
767 case NL80211_IFTYPE_AP: 769 case NL80211_IFTYPE_AP:
770 case NL80211_IFTYPE_MESH_POINT:
768 ath9k_beacon_config_ap(sc, cur_conf); 771 ath9k_beacon_config_ap(sc, cur_conf);
769 break; 772 break;
770 case NL80211_IFTYPE_ADHOC: 773 case NL80211_IFTYPE_ADHOC:
771 case NL80211_IFTYPE_MESH_POINT:
772 ath9k_beacon_config_adhoc(sc, cur_conf); 774 ath9k_beacon_config_adhoc(sc, cur_conf);
773 break; 775 break;
774 case NL80211_IFTYPE_STATION: 776 case NL80211_IFTYPE_STATION:
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index 51cc0fa5cd3e..87454f6c7b4f 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -173,25 +173,69 @@ static const struct file_operations fops_rx_chainmask = {
173 .llseek = default_llseek, 173 .llseek = default_llseek,
174}; 174};
175 175
176static ssize_t read_file_disable_ani(struct file *file, char __user *user_buf, 176static ssize_t read_file_ani(struct file *file, char __user *user_buf,
177 size_t count, loff_t *ppos) 177 size_t count, loff_t *ppos)
178{ 178{
179 struct ath_softc *sc = file->private_data; 179 struct ath_softc *sc = file->private_data;
180 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 180 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
181 char buf[32]; 181 struct ath_hw *ah = sc->sc_ah;
182 unsigned int len; 182 unsigned int len = 0, size = 1024;
183 ssize_t retval = 0;
184 char *buf;
183 185
184 len = sprintf(buf, "%d\n", common->disable_ani); 186 buf = kzalloc(size, GFP_KERNEL);
185 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 187 if (buf == NULL)
188 return -ENOMEM;
189
190 if (common->disable_ani) {
191 len += snprintf(buf + len, size - len, "%s: %s\n",
192 "ANI", "DISABLED");
193 goto exit;
194 }
195
196 len += snprintf(buf + len, size - len, "%15s: %s\n",
197 "ANI", "ENABLED");
198 len += snprintf(buf + len, size - len, "%15s: %u\n",
199 "ANI RESET", ah->stats.ast_ani_reset);
200 len += snprintf(buf + len, size - len, "%15s: %u\n",
201 "SPUR UP", ah->stats.ast_ani_spurup);
202 len += snprintf(buf + len, size - len, "%15s: %u\n",
203 "SPUR DOWN", ah->stats.ast_ani_spurup);
204 len += snprintf(buf + len, size - len, "%15s: %u\n",
205 "OFDM WS-DET ON", ah->stats.ast_ani_ofdmon);
206 len += snprintf(buf + len, size - len, "%15s: %u\n",
207 "OFDM WS-DET OFF", ah->stats.ast_ani_ofdmoff);
208 len += snprintf(buf + len, size - len, "%15s: %u\n",
209 "MRC-CCK ON", ah->stats.ast_ani_ccklow);
210 len += snprintf(buf + len, size - len, "%15s: %u\n",
211 "MRC-CCK OFF", ah->stats.ast_ani_cckhigh);
212 len += snprintf(buf + len, size - len, "%15s: %u\n",
213 "FIR-STEP UP", ah->stats.ast_ani_stepup);
214 len += snprintf(buf + len, size - len, "%15s: %u\n",
215 "FIR-STEP DOWN", ah->stats.ast_ani_stepdown);
216 len += snprintf(buf + len, size - len, "%15s: %u\n",
217 "INV LISTENTIME", ah->stats.ast_ani_lneg_or_lzero);
218 len += snprintf(buf + len, size - len, "%15s: %u\n",
219 "OFDM ERRORS", ah->stats.ast_ani_ofdmerrs);
220 len += snprintf(buf + len, size - len, "%15s: %u\n",
221 "CCK ERRORS", ah->stats.ast_ani_cckerrs);
222exit:
223 if (len > size)
224 len = size;
225
226 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
227 kfree(buf);
228
229 return retval;
186} 230}
187 231
188static ssize_t write_file_disable_ani(struct file *file, 232static ssize_t write_file_ani(struct file *file,
189 const char __user *user_buf, 233 const char __user *user_buf,
190 size_t count, loff_t *ppos) 234 size_t count, loff_t *ppos)
191{ 235{
192 struct ath_softc *sc = file->private_data; 236 struct ath_softc *sc = file->private_data;
193 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 237 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
194 unsigned long disable_ani; 238 unsigned long ani;
195 char buf[32]; 239 char buf[32];
196 ssize_t len; 240 ssize_t len;
197 241
@@ -200,12 +244,15 @@ static ssize_t write_file_disable_ani(struct file *file,
200 return -EFAULT; 244 return -EFAULT;
201 245
202 buf[len] = '\0'; 246 buf[len] = '\0';
203 if (kstrtoul(buf, 0, &disable_ani)) 247 if (kstrtoul(buf, 0, &ani))
204 return -EINVAL; 248 return -EINVAL;
205 249
206 common->disable_ani = !!disable_ani; 250 if (ani < 0 || ani > 1)
251 return -EINVAL;
252
253 common->disable_ani = !ani;
207 254
208 if (disable_ani) { 255 if (common->disable_ani) {
209 clear_bit(SC_OP_ANI_RUN, &sc->sc_flags); 256 clear_bit(SC_OP_ANI_RUN, &sc->sc_flags);
210 ath_stop_ani(sc); 257 ath_stop_ani(sc);
211 } else { 258 } else {
@@ -215,9 +262,9 @@ static ssize_t write_file_disable_ani(struct file *file,
215 return count; 262 return count;
216} 263}
217 264
218static const struct file_operations fops_disable_ani = { 265static const struct file_operations fops_ani = {
219 .read = read_file_disable_ani, 266 .read = read_file_ani,
220 .write = write_file_disable_ani, 267 .write = write_file_ani,
221 .open = simple_open, 268 .open = simple_open,
222 .owner = THIS_MODULE, 269 .owner = THIS_MODULE,
223 .llseek = default_llseek, 270 .llseek = default_llseek,
@@ -738,8 +785,6 @@ void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf,
738 struct ath_tx_status *ts, struct ath_txq *txq, 785 struct ath_tx_status *ts, struct ath_txq *txq,
739 unsigned int flags) 786 unsigned int flags)
740{ 787{
741#define TX_SAMP_DBG(c) (sc->debug.bb_mac_samp[sc->debug.sampidx].ts\
742 [sc->debug.tsidx].c)
743 int qnum = txq->axq_qnum; 788 int qnum = txq->axq_qnum;
744 789
745 TX_STAT_INC(qnum, tx_pkts_all); 790 TX_STAT_INC(qnum, tx_pkts_all);
@@ -771,37 +816,6 @@ void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf,
771 TX_STAT_INC(qnum, data_underrun); 816 TX_STAT_INC(qnum, data_underrun);
772 if (ts->ts_flags & ATH9K_TX_DELIM_UNDERRUN) 817 if (ts->ts_flags & ATH9K_TX_DELIM_UNDERRUN)
773 TX_STAT_INC(qnum, delim_underrun); 818 TX_STAT_INC(qnum, delim_underrun);
774
775#ifdef CONFIG_ATH9K_MAC_DEBUG
776 spin_lock(&sc->debug.samp_lock);
777 TX_SAMP_DBG(jiffies) = jiffies;
778 TX_SAMP_DBG(rssi_ctl0) = ts->ts_rssi_ctl0;
779 TX_SAMP_DBG(rssi_ctl1) = ts->ts_rssi_ctl1;
780 TX_SAMP_DBG(rssi_ctl2) = ts->ts_rssi_ctl2;
781 TX_SAMP_DBG(rssi_ext0) = ts->ts_rssi_ext0;
782 TX_SAMP_DBG(rssi_ext1) = ts->ts_rssi_ext1;
783 TX_SAMP_DBG(rssi_ext2) = ts->ts_rssi_ext2;
784 TX_SAMP_DBG(rateindex) = ts->ts_rateindex;
785 TX_SAMP_DBG(isok) = !!(ts->ts_status & ATH9K_TXERR_MASK);
786 TX_SAMP_DBG(rts_fail_cnt) = ts->ts_shortretry;
787 TX_SAMP_DBG(data_fail_cnt) = ts->ts_longretry;
788 TX_SAMP_DBG(rssi) = ts->ts_rssi;
789 TX_SAMP_DBG(tid) = ts->tid;
790 TX_SAMP_DBG(qid) = ts->qid;
791
792 if (ts->ts_flags & ATH9K_TX_BA) {
793 TX_SAMP_DBG(ba_low) = ts->ba_low;
794 TX_SAMP_DBG(ba_high) = ts->ba_high;
795 } else {
796 TX_SAMP_DBG(ba_low) = 0;
797 TX_SAMP_DBG(ba_high) = 0;
798 }
799
800 sc->debug.tsidx = (sc->debug.tsidx + 1) % ATH_DBG_MAX_SAMPLES;
801 spin_unlock(&sc->debug.samp_lock);
802#endif
803
804#undef TX_SAMP_DBG
805} 819}
806 820
807static const struct file_operations fops_xmit = { 821static const struct file_operations fops_xmit = {
@@ -915,8 +929,6 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf,
915void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs) 929void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs)
916{ 930{
917#define RX_PHY_ERR_INC(c) sc->debug.stats.rxstats.phy_err_stats[c]++ 931#define RX_PHY_ERR_INC(c) sc->debug.stats.rxstats.phy_err_stats[c]++
918#define RX_SAMP_DBG(c) (sc->debug.bb_mac_samp[sc->debug.sampidx].rs\
919 [sc->debug.rsidx].c)
920 932
921 RX_STAT_INC(rx_pkts_all); 933 RX_STAT_INC(rx_pkts_all);
922 sc->debug.stats.rxstats.rx_bytes_all += rs->rs_datalen; 934 sc->debug.stats.rxstats.rx_bytes_all += rs->rs_datalen;
@@ -940,27 +952,7 @@ void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs)
940 RX_PHY_ERR_INC(rs->rs_phyerr); 952 RX_PHY_ERR_INC(rs->rs_phyerr);
941 } 953 }
942 954
943#ifdef CONFIG_ATH9K_MAC_DEBUG
944 spin_lock(&sc->debug.samp_lock);
945 RX_SAMP_DBG(jiffies) = jiffies;
946 RX_SAMP_DBG(rssi_ctl0) = rs->rs_rssi_ctl0;
947 RX_SAMP_DBG(rssi_ctl1) = rs->rs_rssi_ctl1;
948 RX_SAMP_DBG(rssi_ctl2) = rs->rs_rssi_ctl2;
949 RX_SAMP_DBG(rssi_ext0) = rs->rs_rssi_ext0;
950 RX_SAMP_DBG(rssi_ext1) = rs->rs_rssi_ext1;
951 RX_SAMP_DBG(rssi_ext2) = rs->rs_rssi_ext2;
952 RX_SAMP_DBG(antenna) = rs->rs_antenna;
953 RX_SAMP_DBG(rssi) = rs->rs_rssi;
954 RX_SAMP_DBG(rate) = rs->rs_rate;
955 RX_SAMP_DBG(is_mybeacon) = rs->is_mybeacon;
956
957 sc->debug.rsidx = (sc->debug.rsidx + 1) % ATH_DBG_MAX_SAMPLES;
958 spin_unlock(&sc->debug.samp_lock);
959
960#endif
961
962#undef RX_PHY_ERR_INC 955#undef RX_PHY_ERR_INC
963#undef RX_SAMP_DBG
964} 956}
965 957
966static const struct file_operations fops_recv = { 958static const struct file_operations fops_recv = {
@@ -1485,283 +1477,6 @@ static const struct file_operations fops_modal_eeprom = {
1485 .llseek = default_llseek, 1477 .llseek = default_llseek,
1486}; 1478};
1487 1479
1488#ifdef CONFIG_ATH9K_MAC_DEBUG
1489
1490void ath9k_debug_samp_bb_mac(struct ath_softc *sc)
1491{
1492#define ATH_SAMP_DBG(c) (sc->debug.bb_mac_samp[sc->debug.sampidx].c)
1493 struct ath_hw *ah = sc->sc_ah;
1494 struct ath_common *common = ath9k_hw_common(ah);
1495 unsigned long flags;
1496 int i;
1497
1498 ath9k_ps_wakeup(sc);
1499
1500 spin_lock_bh(&sc->debug.samp_lock);
1501
1502 spin_lock_irqsave(&common->cc_lock, flags);
1503 ath_hw_cycle_counters_update(common);
1504
1505 ATH_SAMP_DBG(cc.cycles) = common->cc_ani.cycles;
1506 ATH_SAMP_DBG(cc.rx_busy) = common->cc_ani.rx_busy;
1507 ATH_SAMP_DBG(cc.rx_frame) = common->cc_ani.rx_frame;
1508 ATH_SAMP_DBG(cc.tx_frame) = common->cc_ani.tx_frame;
1509 spin_unlock_irqrestore(&common->cc_lock, flags);
1510
1511 ATH_SAMP_DBG(noise) = ah->noise;
1512
1513 REG_WRITE_D(ah, AR_MACMISC,
1514 ((AR_MACMISC_DMA_OBS_LINE_8 << AR_MACMISC_DMA_OBS_S) |
1515 (AR_MACMISC_MISC_OBS_BUS_1 <<
1516 AR_MACMISC_MISC_OBS_BUS_MSB_S)));
1517
1518 for (i = 0; i < ATH9K_NUM_DMA_DEBUG_REGS; i++)
1519 ATH_SAMP_DBG(dma_dbg_reg_vals[i]) = REG_READ_D(ah,
1520 AR_DMADBG_0 + (i * sizeof(u32)));
1521
1522 ATH_SAMP_DBG(pcu_obs) = REG_READ_D(ah, AR_OBS_BUS_1);
1523 ATH_SAMP_DBG(pcu_cr) = REG_READ_D(ah, AR_CR);
1524
1525 memcpy(ATH_SAMP_DBG(nfCalHist), sc->caldata.nfCalHist,
1526 sizeof(ATH_SAMP_DBG(nfCalHist)));
1527
1528 sc->debug.sampidx = (sc->debug.sampidx + 1) % ATH_DBG_MAX_SAMPLES;
1529 spin_unlock_bh(&sc->debug.samp_lock);
1530 ath9k_ps_restore(sc);
1531
1532#undef ATH_SAMP_DBG
1533}
1534
1535static int open_file_bb_mac_samps(struct inode *inode, struct file *file)
1536{
1537#define ATH_SAMP_DBG(c) bb_mac_samp[sampidx].c
1538 struct ath_softc *sc = inode->i_private;
1539 struct ath_hw *ah = sc->sc_ah;
1540 struct ath_common *common = ath9k_hw_common(ah);
1541 struct ieee80211_conf *conf = &common->hw->conf;
1542 struct ath_dbg_bb_mac_samp *bb_mac_samp;
1543 struct ath9k_nfcal_hist *h;
1544 int i, j, qcuOffset = 0, dcuOffset = 0;
1545 u32 *qcuBase, *dcuBase, size = 30000, len = 0;
1546 u32 sampidx = 0;
1547 u8 *buf;
1548 u8 chainmask = (ah->rxchainmask << 3) | ah->rxchainmask;
1549 u8 nread;
1550
1551 if (test_bit(SC_OP_INVALID, &sc->sc_flags))
1552 return -EAGAIN;
1553
1554 buf = vmalloc(size);
1555 if (!buf)
1556 return -ENOMEM;
1557 bb_mac_samp = vmalloc(sizeof(*bb_mac_samp) * ATH_DBG_MAX_SAMPLES);
1558 if (!bb_mac_samp) {
1559 vfree(buf);
1560 return -ENOMEM;
1561 }
1562 /* Account the current state too */
1563 ath9k_debug_samp_bb_mac(sc);
1564
1565 spin_lock_bh(&sc->debug.samp_lock);
1566 memcpy(bb_mac_samp, sc->debug.bb_mac_samp,
1567 sizeof(*bb_mac_samp) * ATH_DBG_MAX_SAMPLES);
1568 len += snprintf(buf + len, size - len,
1569 "Current Sample Index: %d\n", sc->debug.sampidx);
1570 spin_unlock_bh(&sc->debug.samp_lock);
1571
1572 len += snprintf(buf + len, size - len,
1573 "Raw DMA Debug Dump:\n");
1574 len += snprintf(buf + len, size - len, "Sample |\t");
1575 for (i = 0; i < ATH9K_NUM_DMA_DEBUG_REGS; i++)
1576 len += snprintf(buf + len, size - len, " DMA Reg%d |\t", i);
1577 len += snprintf(buf + len, size - len, "\n");
1578
1579 for (sampidx = 0; sampidx < ATH_DBG_MAX_SAMPLES; sampidx++) {
1580 len += snprintf(buf + len, size - len, "%d\t", sampidx);
1581
1582 for (i = 0; i < ATH9K_NUM_DMA_DEBUG_REGS; i++)
1583 len += snprintf(buf + len, size - len, " %08x\t",
1584 ATH_SAMP_DBG(dma_dbg_reg_vals[i]));
1585 len += snprintf(buf + len, size - len, "\n");
1586 }
1587 len += snprintf(buf + len, size - len, "\n");
1588
1589 len += snprintf(buf + len, size - len,
1590 "Sample Num QCU: chain_st fsp_ok fsp_st DCU: chain_st\n");
1591 for (sampidx = 0; sampidx < ATH_DBG_MAX_SAMPLES; sampidx++) {
1592 qcuBase = &ATH_SAMP_DBG(dma_dbg_reg_vals[0]);
1593 dcuBase = &ATH_SAMP_DBG(dma_dbg_reg_vals[4]);
1594
1595 for (i = 0; i < ATH9K_NUM_QUEUES; i++,
1596 qcuOffset += 4, dcuOffset += 5) {
1597 if (i == 8) {
1598 qcuOffset = 0;
1599 qcuBase++;
1600 }
1601
1602 if (i == 6) {
1603 dcuOffset = 0;
1604 dcuBase++;
1605 }
1606 if (!sc->debug.stats.txstats[i].queued)
1607 continue;
1608
1609 len += snprintf(buf + len, size - len,
1610 "%4d %7d %2x %1x %2x %2x\n",
1611 sampidx, i,
1612 (*qcuBase & (0x7 << qcuOffset)) >> qcuOffset,
1613 (*qcuBase & (0x8 << qcuOffset)) >>
1614 (qcuOffset + 3),
1615 ATH_SAMP_DBG(dma_dbg_reg_vals[2]) &
1616 (0x7 << (i * 3)) >> (i * 3),
1617 (*dcuBase & (0x1f << dcuOffset)) >> dcuOffset);
1618 }
1619 len += snprintf(buf + len, size - len, "\n");
1620 }
1621 len += snprintf(buf + len, size - len,
1622 "samp qcu_sh qcu_fh qcu_comp dcu_comp dcu_arb dcu_fp "
1623 "ch_idle_dur ch_idle_dur_val txfifo_val0 txfifo_val1 "
1624 "txfifo_dcu0 txfifo_dcu1 pcu_obs AR_CR\n");
1625
1626 for (sampidx = 0; sampidx < ATH_DBG_MAX_SAMPLES; sampidx++) {
1627 qcuBase = &ATH_SAMP_DBG(dma_dbg_reg_vals[0]);
1628 dcuBase = &ATH_SAMP_DBG(dma_dbg_reg_vals[4]);
1629
1630 len += snprintf(buf + len, size - len, "%4d %5x %5x ", sampidx,
1631 (ATH_SAMP_DBG(dma_dbg_reg_vals[3]) & 0x003c0000) >> 18,
1632 (ATH_SAMP_DBG(dma_dbg_reg_vals[3]) & 0x03c00000) >> 22);
1633 len += snprintf(buf + len, size - len, "%7x %8x ",
1634 (ATH_SAMP_DBG(dma_dbg_reg_vals[3]) & 0x1c000000) >> 26,
1635 (ATH_SAMP_DBG(dma_dbg_reg_vals[6]) & 0x3));
1636 len += snprintf(buf + len, size - len, "%7x %7x ",
1637 (ATH_SAMP_DBG(dma_dbg_reg_vals[5]) & 0x06000000) >> 25,
1638 (ATH_SAMP_DBG(dma_dbg_reg_vals[5]) & 0x38000000) >> 27);
1639 len += snprintf(buf + len, size - len, "%7d %12d ",
1640 (ATH_SAMP_DBG(dma_dbg_reg_vals[6]) & 0x000003fc) >> 2,
1641 (ATH_SAMP_DBG(dma_dbg_reg_vals[6]) & 0x00000400) >> 10);
1642 len += snprintf(buf + len, size - len, "%12d %12d ",
1643 (ATH_SAMP_DBG(dma_dbg_reg_vals[6]) & 0x00000800) >> 11,
1644 (ATH_SAMP_DBG(dma_dbg_reg_vals[6]) & 0x00001000) >> 12);
1645 len += snprintf(buf + len, size - len, "%12d %12d ",
1646 (ATH_SAMP_DBG(dma_dbg_reg_vals[6]) & 0x0001e000) >> 13,
1647 (ATH_SAMP_DBG(dma_dbg_reg_vals[6]) & 0x001e0000) >> 17);
1648 len += snprintf(buf + len, size - len, "0x%07x 0x%07x\n",
1649 ATH_SAMP_DBG(pcu_obs), ATH_SAMP_DBG(pcu_cr));
1650 }
1651
1652 len += snprintf(buf + len, size - len,
1653 "Sample ChNoise Chain privNF #Reading Readings\n");
1654 for (sampidx = 0; sampidx < ATH_DBG_MAX_SAMPLES; sampidx++) {
1655 h = ATH_SAMP_DBG(nfCalHist);
1656 if (!ATH_SAMP_DBG(noise))
1657 continue;
1658
1659 for (i = 0; i < NUM_NF_READINGS; i++) {
1660 if (!(chainmask & (1 << i)) ||
1661 ((i >= AR5416_MAX_CHAINS) && !conf_is_ht40(conf)))
1662 continue;
1663
1664 nread = AR_PHY_CCA_FILTERWINDOW_LENGTH -
1665 h[i].invalidNFcount;
1666 len += snprintf(buf + len, size - len,
1667 "%4d %5d %4d\t %d\t %d\t",
1668 sampidx, ATH_SAMP_DBG(noise),
1669 i, h[i].privNF, nread);
1670 for (j = 0; j < nread; j++)
1671 len += snprintf(buf + len, size - len,
1672 " %d", h[i].nfCalBuffer[j]);
1673 len += snprintf(buf + len, size - len, "\n");
1674 }
1675 }
1676 len += snprintf(buf + len, size - len, "\nCycle counters:\n"
1677 "Sample Total Rxbusy Rxframes Txframes\n");
1678 for (sampidx = 0; sampidx < ATH_DBG_MAX_SAMPLES; sampidx++) {
1679 if (!ATH_SAMP_DBG(cc.cycles))
1680 continue;
1681 len += snprintf(buf + len, size - len,
1682 "%4d %08x %08x %08x %08x\n",
1683 sampidx, ATH_SAMP_DBG(cc.cycles),
1684 ATH_SAMP_DBG(cc.rx_busy),
1685 ATH_SAMP_DBG(cc.rx_frame),
1686 ATH_SAMP_DBG(cc.tx_frame));
1687 }
1688
1689 len += snprintf(buf + len, size - len, "Tx status Dump :\n");
1690 len += snprintf(buf + len, size - len,
1691 "Sample rssi:- ctl0 ctl1 ctl2 ext0 ext1 ext2 comb "
1692 "isok rts_fail data_fail rate tid qid "
1693 "ba_low ba_high tx_before(ms)\n");
1694 for (sampidx = 0; sampidx < ATH_DBG_MAX_SAMPLES; sampidx++) {
1695 for (i = 0; i < ATH_DBG_MAX_SAMPLES; i++) {
1696 if (!ATH_SAMP_DBG(ts[i].jiffies))
1697 continue;
1698 len += snprintf(buf + len, size - len, "%-14d"
1699 "%-4d %-4d %-4d %-4d %-4d %-4d %-4d %-4d %-8d "
1700 "%-9d %-4d %-3d %-3d %08x %08x %-11d\n",
1701 sampidx,
1702 ATH_SAMP_DBG(ts[i].rssi_ctl0),
1703 ATH_SAMP_DBG(ts[i].rssi_ctl1),
1704 ATH_SAMP_DBG(ts[i].rssi_ctl2),
1705 ATH_SAMP_DBG(ts[i].rssi_ext0),
1706 ATH_SAMP_DBG(ts[i].rssi_ext1),
1707 ATH_SAMP_DBG(ts[i].rssi_ext2),
1708 ATH_SAMP_DBG(ts[i].rssi),
1709 ATH_SAMP_DBG(ts[i].isok),
1710 ATH_SAMP_DBG(ts[i].rts_fail_cnt),
1711 ATH_SAMP_DBG(ts[i].data_fail_cnt),
1712 ATH_SAMP_DBG(ts[i].rateindex),
1713 ATH_SAMP_DBG(ts[i].tid),
1714 ATH_SAMP_DBG(ts[i].qid),
1715 ATH_SAMP_DBG(ts[i].ba_low),
1716 ATH_SAMP_DBG(ts[i].ba_high),
1717 jiffies_to_msecs(jiffies -
1718 ATH_SAMP_DBG(ts[i].jiffies)));
1719 }
1720 }
1721
1722 len += snprintf(buf + len, size - len, "Rx status Dump :\n");
1723 len += snprintf(buf + len, size - len, "Sample rssi:- ctl0 ctl1 ctl2 "
1724 "ext0 ext1 ext2 comb beacon ant rate rx_before(ms)\n");
1725 for (sampidx = 0; sampidx < ATH_DBG_MAX_SAMPLES; sampidx++) {
1726 for (i = 0; i < ATH_DBG_MAX_SAMPLES; i++) {
1727 if (!ATH_SAMP_DBG(rs[i].jiffies))
1728 continue;
1729 len += snprintf(buf + len, size - len, "%-14d"
1730 "%-4d %-4d %-4d %-4d %-4d %-4d %-4d %-9s %-2d %02x %-13d\n",
1731 sampidx,
1732 ATH_SAMP_DBG(rs[i].rssi_ctl0),
1733 ATH_SAMP_DBG(rs[i].rssi_ctl1),
1734 ATH_SAMP_DBG(rs[i].rssi_ctl2),
1735 ATH_SAMP_DBG(rs[i].rssi_ext0),
1736 ATH_SAMP_DBG(rs[i].rssi_ext1),
1737 ATH_SAMP_DBG(rs[i].rssi_ext2),
1738 ATH_SAMP_DBG(rs[i].rssi),
1739 ATH_SAMP_DBG(rs[i].is_mybeacon) ?
1740 "True" : "False",
1741 ATH_SAMP_DBG(rs[i].antenna),
1742 ATH_SAMP_DBG(rs[i].rate),
1743 jiffies_to_msecs(jiffies -
1744 ATH_SAMP_DBG(rs[i].jiffies)));
1745 }
1746 }
1747
1748 vfree(bb_mac_samp);
1749 file->private_data = buf;
1750
1751 return 0;
1752#undef ATH_SAMP_DBG
1753}
1754
1755static const struct file_operations fops_samps = {
1756 .open = open_file_bb_mac_samps,
1757 .read = ath9k_debugfs_read_buf,
1758 .release = ath9k_debugfs_release_buf,
1759 .owner = THIS_MODULE,
1760 .llseek = default_llseek,
1761};
1762
1763#endif
1764
1765#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT 1480#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
1766static ssize_t read_file_btcoex(struct file *file, char __user *user_buf, 1481static ssize_t read_file_btcoex(struct file *file, char __user *user_buf,
1767 size_t count, loff_t *ppos) 1482 size_t count, loff_t *ppos)
@@ -2059,8 +1774,8 @@ int ath9k_init_debug(struct ath_hw *ah)
2059 sc->debug.debugfs_phy, sc, &fops_rx_chainmask); 1774 sc->debug.debugfs_phy, sc, &fops_rx_chainmask);
2060 debugfs_create_file("tx_chainmask", S_IRUSR | S_IWUSR, 1775 debugfs_create_file("tx_chainmask", S_IRUSR | S_IWUSR,
2061 sc->debug.debugfs_phy, sc, &fops_tx_chainmask); 1776 sc->debug.debugfs_phy, sc, &fops_tx_chainmask);
2062 debugfs_create_file("disable_ani", S_IRUSR | S_IWUSR, 1777 debugfs_create_file("ani", S_IRUSR | S_IWUSR,
2063 sc->debug.debugfs_phy, sc, &fops_disable_ani); 1778 sc->debug.debugfs_phy, sc, &fops_ani);
2064 debugfs_create_bool("paprd", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, 1779 debugfs_create_bool("paprd", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
2065 &sc->sc_ah->config.enable_paprd); 1780 &sc->sc_ah->config.enable_paprd);
2066 debugfs_create_file("regidx", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, 1781 debugfs_create_file("regidx", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
@@ -2095,11 +1810,6 @@ int ath9k_init_debug(struct ath_hw *ah)
2095 debugfs_create_file("spectral_fft_period", S_IRUSR | S_IWUSR, 1810 debugfs_create_file("spectral_fft_period", S_IRUSR | S_IWUSR,
2096 sc->debug.debugfs_phy, sc, 1811 sc->debug.debugfs_phy, sc,
2097 &fops_spectral_fft_period); 1812 &fops_spectral_fft_period);
2098
2099#ifdef CONFIG_ATH9K_MAC_DEBUG
2100 debugfs_create_file("samples", S_IRUSR, sc->debug.debugfs_phy, sc,
2101 &fops_samps);
2102#endif
2103 debugfs_create_u32("gpio_mask", S_IRUSR | S_IWUSR, 1813 debugfs_create_u32("gpio_mask", S_IRUSR | S_IWUSR,
2104 sc->debug.debugfs_phy, &sc->sc_ah->gpio_mask); 1814 sc->debug.debugfs_phy, &sc->sc_ah->gpio_mask);
2105 debugfs_create_u32("gpio_val", S_IRUSR | S_IWUSR, 1815 debugfs_create_u32("gpio_val", S_IRUSR | S_IWUSR,
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h
index 9d49aab8b989..fc679198a0f3 100644
--- a/drivers/net/wireless/ath/ath9k/debug.h
+++ b/drivers/net/wireless/ath/ath9k/debug.h
@@ -251,56 +251,10 @@ struct ath_stats {
251 u32 reset[__RESET_TYPE_MAX]; 251 u32 reset[__RESET_TYPE_MAX];
252}; 252};
253 253
254#define ATH_DBG_MAX_SAMPLES 10
255struct ath_dbg_bb_mac_samp {
256 u32 dma_dbg_reg_vals[ATH9K_NUM_DMA_DEBUG_REGS];
257 u32 pcu_obs, pcu_cr, noise;
258 struct {
259 u64 jiffies;
260 int8_t rssi_ctl0;
261 int8_t rssi_ctl1;
262 int8_t rssi_ctl2;
263 int8_t rssi_ext0;
264 int8_t rssi_ext1;
265 int8_t rssi_ext2;
266 int8_t rssi;
267 bool isok;
268 u8 rts_fail_cnt;
269 u8 data_fail_cnt;
270 u8 rateindex;
271 u8 qid;
272 u8 tid;
273 u32 ba_low;
274 u32 ba_high;
275 } ts[ATH_DBG_MAX_SAMPLES];
276 struct {
277 u64 jiffies;
278 int8_t rssi_ctl0;
279 int8_t rssi_ctl1;
280 int8_t rssi_ctl2;
281 int8_t rssi_ext0;
282 int8_t rssi_ext1;
283 int8_t rssi_ext2;
284 int8_t rssi;
285 bool is_mybeacon;
286 u8 antenna;
287 u8 rate;
288 } rs[ATH_DBG_MAX_SAMPLES];
289 struct ath_cycle_counters cc;
290 struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS];
291};
292
293struct ath9k_debug { 254struct ath9k_debug {
294 struct dentry *debugfs_phy; 255 struct dentry *debugfs_phy;
295 u32 regidx; 256 u32 regidx;
296 struct ath_stats stats; 257 struct ath_stats stats;
297#ifdef CONFIG_ATH9K_MAC_DEBUG
298 spinlock_t samp_lock;
299 struct ath_dbg_bb_mac_samp bb_mac_samp[ATH_DBG_MAX_SAMPLES];
300 u8 sampidx;
301 u8 tsidx;
302 u8 rsidx;
303#endif
304}; 258};
305 259
306int ath9k_init_debug(struct ath_hw *ah); 260int ath9k_init_debug(struct ath_hw *ah);
@@ -364,17 +318,4 @@ static inline void ath_debug_stat_rx(struct ath_softc *sc,
364 318
365#endif /* CONFIG_ATH9K_DEBUGFS */ 319#endif /* CONFIG_ATH9K_DEBUGFS */
366 320
367#ifdef CONFIG_ATH9K_MAC_DEBUG
368
369void ath9k_debug_samp_bb_mac(struct ath_softc *sc);
370
371#else
372
373static inline void ath9k_debug_samp_bb_mac(struct ath_softc *sc)
374{
375}
376
377#endif
378
379
380#endif /* DEBUG_H */ 321#endif /* DEBUG_H */
diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h
index d3b099d7898b..0085e643132f 100644
--- a/drivers/net/wireless/ath/ath9k/htc.h
+++ b/drivers/net/wireless/ath/ath9k/htc.h
@@ -208,6 +208,9 @@ struct ath9k_htc_target_rx_stats {
208 case NL80211_IFTYPE_AP: \ 208 case NL80211_IFTYPE_AP: \
209 _priv->num_ap_vif++; \ 209 _priv->num_ap_vif++; \
210 break; \ 210 break; \
211 case NL80211_IFTYPE_MESH_POINT: \
212 _priv->num_mbss_vif++; \
213 break; \
211 default: \ 214 default: \
212 break; \ 215 break; \
213 } \ 216 } \
@@ -224,6 +227,9 @@ struct ath9k_htc_target_rx_stats {
224 case NL80211_IFTYPE_AP: \ 227 case NL80211_IFTYPE_AP: \
225 _priv->num_ap_vif--; \ 228 _priv->num_ap_vif--; \
226 break; \ 229 break; \
230 case NL80211_IFTYPE_MESH_POINT: \
231 _priv->num_mbss_vif--; \
232 break; \
227 default: \ 233 default: \
228 break; \ 234 break; \
229 } \ 235 } \
@@ -450,6 +456,7 @@ struct ath9k_htc_priv {
450 u8 sta_slot; 456 u8 sta_slot;
451 u8 vif_sta_pos[ATH9K_HTC_MAX_VIF]; 457 u8 vif_sta_pos[ATH9K_HTC_MAX_VIF];
452 u8 num_ibss_vif; 458 u8 num_ibss_vif;
459 u8 num_mbss_vif;
453 u8 num_sta_vif; 460 u8 num_sta_vif;
454 u8 num_sta_assoc_vif; 461 u8 num_sta_assoc_vif;
455 u8 num_ap_vif; 462 u8 num_ap_vif;
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
index f13f458dd656..e0c03bd64182 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
@@ -28,7 +28,8 @@ void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv)
28 28
29 ath9k_hw_get_txq_props(ah, priv->beaconq, &qi); 29 ath9k_hw_get_txq_props(ah, priv->beaconq, &qi);
30 30
31 if (priv->ah->opmode == NL80211_IFTYPE_AP) { 31 if (priv->ah->opmode == NL80211_IFTYPE_AP ||
32 priv->ah->opmode == NL80211_IFTYPE_MESH_POINT) {
32 qi.tqi_aifs = 1; 33 qi.tqi_aifs = 1;
33 qi.tqi_cwmin = 0; 34 qi.tqi_cwmin = 0;
34 qi.tqi_cwmax = 0; 35 qi.tqi_cwmax = 0;
@@ -628,6 +629,7 @@ void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv,
628 case NL80211_IFTYPE_ADHOC: 629 case NL80211_IFTYPE_ADHOC:
629 ath9k_htc_beacon_config_adhoc(priv, cur_conf); 630 ath9k_htc_beacon_config_adhoc(priv, cur_conf);
630 break; 631 break;
632 case NL80211_IFTYPE_MESH_POINT:
631 case NL80211_IFTYPE_AP: 633 case NL80211_IFTYPE_AP:
632 ath9k_htc_beacon_config_ap(priv, cur_conf); 634 ath9k_htc_beacon_config_ap(priv, cur_conf);
633 break; 635 break;
@@ -649,6 +651,7 @@ void ath9k_htc_beacon_reconfig(struct ath9k_htc_priv *priv)
649 case NL80211_IFTYPE_ADHOC: 651 case NL80211_IFTYPE_ADHOC:
650 ath9k_htc_beacon_config_adhoc(priv, cur_conf); 652 ath9k_htc_beacon_config_adhoc(priv, cur_conf);
651 break; 653 break;
654 case NL80211_IFTYPE_MESH_POINT:
652 case NL80211_IFTYPE_AP: 655 case NL80211_IFTYPE_AP:
653 ath9k_htc_beacon_config_ap(priv, cur_conf); 656 ath9k_htc_beacon_config_ap(priv, cur_conf);
654 break; 657 break;
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
index a47f5e05fc04..59f64367e8ca 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
@@ -698,7 +698,8 @@ static const struct ieee80211_iface_limit if_limits[] = {
698 { .max = 2, .types = BIT(NL80211_IFTYPE_STATION) | 698 { .max = 2, .types = BIT(NL80211_IFTYPE_STATION) |
699 BIT(NL80211_IFTYPE_P2P_CLIENT) }, 699 BIT(NL80211_IFTYPE_P2P_CLIENT) },
700 { .max = 2, .types = BIT(NL80211_IFTYPE_AP) | 700 { .max = 2, .types = BIT(NL80211_IFTYPE_AP) |
701 BIT(NL80211_IFTYPE_P2P_GO) }, 701 BIT(NL80211_IFTYPE_P2P_GO) |
702 BIT(NL80211_IFTYPE_MESH_POINT) },
702}; 703};
703 704
704static const struct ieee80211_iface_combination if_comb = { 705static const struct ieee80211_iface_combination if_comb = {
@@ -721,6 +722,7 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv,
721 IEEE80211_HW_SUPPORTS_PS | 722 IEEE80211_HW_SUPPORTS_PS |
722 IEEE80211_HW_PS_NULLFUNC_STACK | 723 IEEE80211_HW_PS_NULLFUNC_STACK |
723 IEEE80211_HW_REPORTS_TX_ACK_STATUS | 724 IEEE80211_HW_REPORTS_TX_ACK_STATUS |
725 IEEE80211_HW_MFP_CAPABLE |
724 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING; 726 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING;
725 727
726 hw->wiphy->interface_modes = 728 hw->wiphy->interface_modes =
@@ -728,7 +730,8 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv,
728 BIT(NL80211_IFTYPE_ADHOC) | 730 BIT(NL80211_IFTYPE_ADHOC) |
729 BIT(NL80211_IFTYPE_AP) | 731 BIT(NL80211_IFTYPE_AP) |
730 BIT(NL80211_IFTYPE_P2P_GO) | 732 BIT(NL80211_IFTYPE_P2P_GO) |
731 BIT(NL80211_IFTYPE_P2P_CLIENT); 733 BIT(NL80211_IFTYPE_P2P_CLIENT) |
734 BIT(NL80211_IFTYPE_MESH_POINT);
732 735
733 hw->wiphy->iface_combinations = &if_comb; 736 hw->wiphy->iface_combinations = &if_comb;
734 hw->wiphy->n_iface_combinations = 1; 737 hw->wiphy->n_iface_combinations = 1;
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
index 0743a47cef8f..34869c2405aa 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -113,7 +113,9 @@ static void ath9k_htc_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
113 struct ath9k_htc_priv *priv = data; 113 struct ath9k_htc_priv *priv = data;
114 struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; 114 struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
115 115
116 if ((vif->type == NL80211_IFTYPE_AP) && bss_conf->enable_beacon) 116 if ((vif->type == NL80211_IFTYPE_AP ||
117 vif->type == NL80211_IFTYPE_MESH_POINT) &&
118 bss_conf->enable_beacon)
117 priv->reconfig_beacon = true; 119 priv->reconfig_beacon = true;
118 120
119 if (bss_conf->assoc) { 121 if (bss_conf->assoc) {
@@ -180,6 +182,8 @@ static void ath9k_htc_set_opmode(struct ath9k_htc_priv *priv)
180 priv->ah->opmode = NL80211_IFTYPE_ADHOC; 182 priv->ah->opmode = NL80211_IFTYPE_ADHOC;
181 else if (priv->num_ap_vif) 183 else if (priv->num_ap_vif)
182 priv->ah->opmode = NL80211_IFTYPE_AP; 184 priv->ah->opmode = NL80211_IFTYPE_AP;
185 else if (priv->num_mbss_vif)
186 priv->ah->opmode = NL80211_IFTYPE_MESH_POINT;
183 else 187 else
184 priv->ah->opmode = NL80211_IFTYPE_STATION; 188 priv->ah->opmode = NL80211_IFTYPE_STATION;
185 189
@@ -810,8 +814,7 @@ void ath9k_htc_ani_work(struct work_struct *work)
810 } 814 }
811 815
812 /* Verify whether we must check ANI */ 816 /* Verify whether we must check ANI */
813 if (ah->config.enable_ani && 817 if ((timestamp - common->ani.checkani_timer) >= ATH_ANI_POLLINTERVAL) {
814 (timestamp - common->ani.checkani_timer) >= ATH_ANI_POLLINTERVAL) {
815 aniflag = true; 818 aniflag = true;
816 common->ani.checkani_timer = timestamp; 819 common->ani.checkani_timer = timestamp;
817 } 820 }
@@ -841,8 +844,7 @@ set_timer:
841 * short calibration and long calibration. 844 * short calibration and long calibration.
842 */ 845 */
843 cal_interval = ATH_LONG_CALINTERVAL; 846 cal_interval = ATH_LONG_CALINTERVAL;
844 if (ah->config.enable_ani) 847 cal_interval = min(cal_interval, (u32)ATH_ANI_POLLINTERVAL);
845 cal_interval = min(cal_interval, (u32)ATH_ANI_POLLINTERVAL);
846 if (!common->ani.caldone) 848 if (!common->ani.caldone)
847 cal_interval = min(cal_interval, (u32)short_cal_interval); 849 cal_interval = min(cal_interval, (u32)short_cal_interval);
848 850
@@ -1052,6 +1054,9 @@ static int ath9k_htc_add_interface(struct ieee80211_hw *hw,
1052 case NL80211_IFTYPE_AP: 1054 case NL80211_IFTYPE_AP:
1053 hvif.opmode = HTC_M_HOSTAP; 1055 hvif.opmode = HTC_M_HOSTAP;
1054 break; 1056 break;
1057 case NL80211_IFTYPE_MESH_POINT:
1058 hvif.opmode = HTC_M_WDS; /* close enough */
1059 break;
1055 default: 1060 default:
1056 ath_err(common, 1061 ath_err(common,
1057 "Interface type %d not yet supported\n", vif->type); 1062 "Interface type %d not yet supported\n", vif->type);
@@ -1084,6 +1089,7 @@ static int ath9k_htc_add_interface(struct ieee80211_hw *hw,
1084 INC_VIF(priv, vif->type); 1089 INC_VIF(priv, vif->type);
1085 1090
1086 if ((vif->type == NL80211_IFTYPE_AP) || 1091 if ((vif->type == NL80211_IFTYPE_AP) ||
1092 (vif->type == NL80211_IFTYPE_MESH_POINT) ||
1087 (vif->type == NL80211_IFTYPE_ADHOC)) 1093 (vif->type == NL80211_IFTYPE_ADHOC))
1088 ath9k_htc_assign_bslot(priv, vif); 1094 ath9k_htc_assign_bslot(priv, vif);
1089 1095
@@ -1134,6 +1140,7 @@ static void ath9k_htc_remove_interface(struct ieee80211_hw *hw,
1134 DEC_VIF(priv, vif->type); 1140 DEC_VIF(priv, vif->type);
1135 1141
1136 if ((vif->type == NL80211_IFTYPE_AP) || 1142 if ((vif->type == NL80211_IFTYPE_AP) ||
1143 vif->type == NL80211_IFTYPE_MESH_POINT ||
1137 (vif->type == NL80211_IFTYPE_ADHOC)) 1144 (vif->type == NL80211_IFTYPE_ADHOC))
1138 ath9k_htc_remove_bslot(priv, vif); 1145 ath9k_htc_remove_bslot(priv, vif);
1139 1146
@@ -1525,9 +1532,10 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw,
1525 if ((changed & BSS_CHANGED_BEACON_ENABLED) && !bss_conf->enable_beacon) { 1532 if ((changed & BSS_CHANGED_BEACON_ENABLED) && !bss_conf->enable_beacon) {
1526 /* 1533 /*
1527 * Disable SWBA interrupt only if there are no 1534 * Disable SWBA interrupt only if there are no
1528 * AP/IBSS interfaces. 1535 * concurrent AP/mesh or IBSS interfaces.
1529 */ 1536 */
1530 if ((priv->num_ap_vif <= 1) || priv->num_ibss_vif) { 1537 if ((priv->num_ap_vif + priv->num_mbss_vif <= 1) ||
1538 priv->num_ibss_vif) {
1531 ath_dbg(common, CONFIG, 1539 ath_dbg(common, CONFIG,
1532 "Beacon disabled for BSS: %pM\n", 1540 "Beacon disabled for BSS: %pM\n",
1533 bss_conf->bssid); 1541 bss_conf->bssid);
@@ -1538,12 +1546,15 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw,
1538 1546
1539 if (changed & BSS_CHANGED_BEACON_INT) { 1547 if (changed & BSS_CHANGED_BEACON_INT) {
1540 /* 1548 /*
1541 * Reset the HW TSF for the first AP interface. 1549 * Reset the HW TSF for the first AP or mesh interface.
1542 */ 1550 */
1543 if ((priv->ah->opmode == NL80211_IFTYPE_AP) && 1551 if (priv->nvifs == 1 &&
1544 (priv->nvifs == 1) && 1552 ((priv->ah->opmode == NL80211_IFTYPE_AP &&
1545 (priv->num_ap_vif == 1) && 1553 vif->type == NL80211_IFTYPE_AP &&
1546 (vif->type == NL80211_IFTYPE_AP)) { 1554 priv->num_ap_vif == 1) ||
1555 (priv->ah->opmode == NL80211_IFTYPE_MESH_POINT &&
1556 vif->type == NL80211_IFTYPE_MESH_POINT &&
1557 priv->num_mbss_vif == 1))) {
1547 set_bit(OP_TSF_RESET, &priv->op_flags); 1558 set_bit(OP_TSF_RESET, &priv->op_flags);
1548 } 1559 }
1549 ath_dbg(common, CONFIG, 1560 ath_dbg(common, CONFIG,
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
index 6bd0e92ea2aa..e602c9519709 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
@@ -887,7 +887,7 @@ u32 ath9k_htc_calcrxfilter(struct ath9k_htc_priv *priv)
887 if (priv->rxfilter & FIF_PSPOLL) 887 if (priv->rxfilter & FIF_PSPOLL)
888 rfilt |= ATH9K_RX_FILTER_PSPOLL; 888 rfilt |= ATH9K_RX_FILTER_PSPOLL;
889 889
890 if (priv->nvifs > 1) 890 if (priv->nvifs > 1 || priv->rxfilter & FIF_OTHER_BSS)
891 rfilt |= ATH9K_RX_FILTER_MCAST_BCAST_ALL; 891 rfilt |= ATH9K_RX_FILTER_MCAST_BCAST_ALL;
892 892
893 return rfilt; 893 return rfilt;
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 15dfefcf2d0f..d813ab8104d6 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -452,7 +452,6 @@ static void ath9k_hw_init_config(struct ath_hw *ah)
452 ah->config.pcie_clock_req = 0; 452 ah->config.pcie_clock_req = 0;
453 ah->config.pcie_waen = 0; 453 ah->config.pcie_waen = 0;
454 ah->config.analog_shiftreg = 1; 454 ah->config.analog_shiftreg = 1;
455 ah->config.enable_ani = true;
456 455
457 for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) { 456 for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
458 ah->config.spurchans[i][0] = AR_NO_SPUR; 457 ah->config.spurchans[i][0] = AR_NO_SPUR;
@@ -549,8 +548,7 @@ static int ath9k_hw_post_init(struct ath_hw *ah)
549 ah->eep_ops->get_eeprom_ver(ah), 548 ah->eep_ops->get_eeprom_ver(ah),
550 ah->eep_ops->get_eeprom_rev(ah)); 549 ah->eep_ops->get_eeprom_rev(ah));
551 550
552 if (ah->config.enable_ani) 551 ath9k_hw_ani_init(ah);
553 ath9k_hw_ani_init(ah);
554 552
555 return 0; 553 return 0;
556} 554}
@@ -1250,10 +1248,10 @@ static void ath9k_hw_set_operating_mode(struct ath_hw *ah, int opmode)
1250 1248
1251 switch (opmode) { 1249 switch (opmode) {
1252 case NL80211_IFTYPE_ADHOC: 1250 case NL80211_IFTYPE_ADHOC:
1253 case NL80211_IFTYPE_MESH_POINT:
1254 set |= AR_STA_ID1_ADHOC; 1251 set |= AR_STA_ID1_ADHOC;
1255 REG_SET_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION); 1252 REG_SET_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION);
1256 break; 1253 break;
1254 case NL80211_IFTYPE_MESH_POINT:
1257 case NL80211_IFTYPE_AP: 1255 case NL80211_IFTYPE_AP:
1258 set |= AR_STA_ID1_STA_AP; 1256 set |= AR_STA_ID1_STA_AP;
1259 /* fall through */ 1257 /* fall through */
@@ -2255,12 +2253,12 @@ void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period)
2255 2253
2256 switch (ah->opmode) { 2254 switch (ah->opmode) {
2257 case NL80211_IFTYPE_ADHOC: 2255 case NL80211_IFTYPE_ADHOC:
2258 case NL80211_IFTYPE_MESH_POINT:
2259 REG_SET_BIT(ah, AR_TXCFG, 2256 REG_SET_BIT(ah, AR_TXCFG,
2260 AR_TXCFG_ADHOC_BEACON_ATIM_TX_POLICY); 2257 AR_TXCFG_ADHOC_BEACON_ATIM_TX_POLICY);
2261 REG_WRITE(ah, AR_NEXT_NDP_TIMER, next_beacon + 2258 REG_WRITE(ah, AR_NEXT_NDP_TIMER, next_beacon +
2262 TU_TO_USEC(ah->atim_window ? ah->atim_window : 1)); 2259 TU_TO_USEC(ah->atim_window ? ah->atim_window : 1));
2263 flags |= AR_NDP_TIMER_EN; 2260 flags |= AR_NDP_TIMER_EN;
2261 case NL80211_IFTYPE_MESH_POINT:
2264 case NL80211_IFTYPE_AP: 2262 case NL80211_IFTYPE_AP:
2265 REG_WRITE(ah, AR_NEXT_TBTT_TIMER, next_beacon); 2263 REG_WRITE(ah, AR_NEXT_TBTT_TIMER, next_beacon);
2266 REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, next_beacon - 2264 REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, next_beacon -
@@ -2604,13 +2602,8 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
2604 pCap->hw_caps |= ATH9K_HW_CAP_RTT; 2602 pCap->hw_caps |= ATH9K_HW_CAP_RTT;
2605 } 2603 }
2606 2604
2607 if (AR_SREV_9280_20_OR_LATER(ah)) { 2605 if (AR_SREV_9462(ah))
2608 pCap->hw_caps |= ATH9K_HW_WOW_DEVICE_CAPABLE | 2606 pCap->hw_caps |= ATH9K_HW_WOW_DEVICE_CAPABLE;
2609 ATH9K_HW_WOW_PATTERN_MATCH_EXACT;
2610
2611 if (AR_SREV_9280(ah))
2612 pCap->hw_caps |= ATH9K_HW_WOW_PATTERN_MATCH_DWORD;
2613 }
2614 2607
2615 if (AR_SREV_9300_20_OR_LATER(ah) && 2608 if (AR_SREV_9300_20_OR_LATER(ah) &&
2616 ah->eep_ops->get_eeprom(ah, EEP_PAPRD)) 2609 ah->eep_ops->get_eeprom(ah, EEP_PAPRD))
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index ae3034374bc4..7d259b7dc254 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -246,9 +246,7 @@ enum ath9k_hw_caps {
246 ATH9K_HW_CAP_MCI = BIT(15), 246 ATH9K_HW_CAP_MCI = BIT(15),
247 ATH9K_HW_CAP_DFS = BIT(16), 247 ATH9K_HW_CAP_DFS = BIT(16),
248 ATH9K_HW_WOW_DEVICE_CAPABLE = BIT(17), 248 ATH9K_HW_WOW_DEVICE_CAPABLE = BIT(17),
249 ATH9K_HW_WOW_PATTERN_MATCH_EXACT = BIT(18), 249 ATH9K_HW_CAP_PAPRD = BIT(18),
250 ATH9K_HW_WOW_PATTERN_MATCH_DWORD = BIT(19),
251 ATH9K_HW_CAP_PAPRD = BIT(20),
252}; 250};
253 251
254/* 252/*
@@ -291,7 +289,6 @@ struct ath9k_ops_config {
291 u32 ofdm_trig_high; 289 u32 ofdm_trig_high;
292 u32 cck_trig_high; 290 u32 cck_trig_high;
293 u32 cck_trig_low; 291 u32 cck_trig_low;
294 u32 enable_ani;
295 u32 enable_paprd; 292 u32 enable_paprd;
296 int serialize_regmode; 293 int serialize_regmode;
297 bool rx_intr_mitigation; 294 bool rx_intr_mitigation;
@@ -423,7 +420,6 @@ struct ath9k_hw_cal_data {
423 420
424struct ath9k_channel { 421struct ath9k_channel {
425 struct ieee80211_channel *chan; 422 struct ieee80211_channel *chan;
426 struct ar5416AniState ani;
427 u16 channel; 423 u16 channel;
428 u32 channelFlags; 424 u32 channelFlags;
429 u32 chanmode; 425 u32 chanmode;
@@ -854,10 +850,10 @@ struct ath_hw {
854 u32 globaltxtimeout; 850 u32 globaltxtimeout;
855 851
856 /* ANI */ 852 /* ANI */
857 u32 proc_phyerr;
858 u32 aniperiod; 853 u32 aniperiod;
859 enum ath9k_ani_cmd ani_function; 854 enum ath9k_ani_cmd ani_function;
860 u32 ani_skip_count; 855 u32 ani_skip_count;
856 struct ar5416AniState ani;
861 857
862#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT 858#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
863 struct ath_btcoex_hw btcoex_hw; 859 struct ath_btcoex_hw btcoex_hw;
@@ -882,9 +878,6 @@ struct ath_hw {
882 struct ar5416IniArray iniBank6; 878 struct ar5416IniArray iniBank6;
883 struct ar5416IniArray iniAddac; 879 struct ar5416IniArray iniAddac;
884 struct ar5416IniArray iniPcieSerdes; 880 struct ar5416IniArray iniPcieSerdes;
885#ifdef CONFIG_PM_SLEEP
886 struct ar5416IniArray iniPcieSerdesWow;
887#endif
888 struct ar5416IniArray iniPcieSerdesLowPower; 881 struct ar5416IniArray iniPcieSerdesLowPower;
889 struct ar5416IniArray iniModesFastClock; 882 struct ar5416IniArray iniModesFastClock;
890 struct ar5416IniArray iniAdditional; 883 struct ar5416IniArray iniAdditional;
@@ -1165,8 +1158,6 @@ static inline void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable)
1165} 1158}
1166#endif 1159#endif
1167 1160
1168
1169
1170#define ATH9K_CLOCK_RATE_CCK 22 1161#define ATH9K_CLOCK_RATE_CCK 22
1171#define ATH9K_CLOCK_RATE_5GHZ_OFDM 40 1162#define ATH9K_CLOCK_RATE_5GHZ_OFDM 40
1172#define ATH9K_CLOCK_RATE_2GHZ_OFDM 44 1163#define ATH9K_CLOCK_RATE_2GHZ_OFDM 44
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index aba415103f94..daba841808cf 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -21,6 +21,7 @@
21#include <linux/ath9k_platform.h> 21#include <linux/ath9k_platform.h>
22#include <linux/module.h> 22#include <linux/module.h>
23#include <linux/relay.h> 23#include <linux/relay.h>
24#include <net/ieee80211_radiotap.h>
24 25
25#include "ath9k.h" 26#include "ath9k.h"
26 27
@@ -613,9 +614,6 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
613 spin_lock_init(&sc->sc_serial_rw); 614 spin_lock_init(&sc->sc_serial_rw);
614 spin_lock_init(&sc->sc_pm_lock); 615 spin_lock_init(&sc->sc_pm_lock);
615 mutex_init(&sc->mutex); 616 mutex_init(&sc->mutex);
616#ifdef CONFIG_ATH9K_MAC_DEBUG
617 spin_lock_init(&sc->debug.samp_lock);
618#endif
619 tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc); 617 tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc);
620 tasklet_init(&sc->bcon_tasklet, ath9k_beacon_tasklet, 618 tasklet_init(&sc->bcon_tasklet, ath9k_beacon_tasklet,
621 (unsigned long)sc); 619 (unsigned long)sc);
@@ -769,12 +767,19 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
769 IEEE80211_HW_REPORTS_TX_ACK_STATUS | 767 IEEE80211_HW_REPORTS_TX_ACK_STATUS |
770 IEEE80211_HW_SUPPORTS_RC_TABLE; 768 IEEE80211_HW_SUPPORTS_RC_TABLE;
771 769
772 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) 770 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
773 hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION; 771 hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION;
772
773 if (AR_SREV_9280_20_OR_LATER(ah))
774 hw->radiotap_mcs_details |=
775 IEEE80211_RADIOTAP_MCS_HAVE_STBC;
776 }
774 777
775 if (AR_SREV_9160_10_OR_LATER(sc->sc_ah) || ath9k_modparam_nohwcrypt) 778 if (AR_SREV_9160_10_OR_LATER(sc->sc_ah) || ath9k_modparam_nohwcrypt)
776 hw->flags |= IEEE80211_HW_MFP_CAPABLE; 779 hw->flags |= IEEE80211_HW_MFP_CAPABLE;
777 780
781 hw->wiphy->features |= NL80211_FEATURE_ACTIVE_MONITOR;
782
778 hw->wiphy->interface_modes = 783 hw->wiphy->interface_modes =
779 BIT(NL80211_IFTYPE_P2P_GO) | 784 BIT(NL80211_IFTYPE_P2P_GO) |
780 BIT(NL80211_IFTYPE_P2P_CLIENT) | 785 BIT(NL80211_IFTYPE_P2P_CLIENT) |
@@ -795,21 +800,17 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
795 hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; 800 hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
796 801
797#ifdef CONFIG_PM_SLEEP 802#ifdef CONFIG_PM_SLEEP
798
799 if ((ah->caps.hw_caps & ATH9K_HW_WOW_DEVICE_CAPABLE) && 803 if ((ah->caps.hw_caps & ATH9K_HW_WOW_DEVICE_CAPABLE) &&
800 device_can_wakeup(sc->dev)) { 804 device_can_wakeup(sc->dev)) {
801
802 hw->wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT | 805 hw->wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT |
803 WIPHY_WOWLAN_DISCONNECT; 806 WIPHY_WOWLAN_DISCONNECT;
804 hw->wiphy->wowlan.n_patterns = MAX_NUM_USER_PATTERN; 807 hw->wiphy->wowlan.n_patterns = MAX_NUM_USER_PATTERN;
805 hw->wiphy->wowlan.pattern_min_len = 1; 808 hw->wiphy->wowlan.pattern_min_len = 1;
806 hw->wiphy->wowlan.pattern_max_len = MAX_PATTERN_SIZE; 809 hw->wiphy->wowlan.pattern_max_len = MAX_PATTERN_SIZE;
807
808 } 810 }
809 811
810 atomic_set(&sc->wow_sleep_proc_intr, -1); 812 atomic_set(&sc->wow_sleep_proc_intr, -1);
811 atomic_set(&sc->wow_got_bmiss_intr, -1); 813 atomic_set(&sc->wow_got_bmiss_intr, -1);
812
813#endif 814#endif
814 815
815 hw->queues = 4; 816 hw->queues = 4;
diff --git a/drivers/net/wireless/ath/ath9k/link.c b/drivers/net/wireless/ath/ath9k/link.c
index 849259b07370..fff5d3ccc663 100644
--- a/drivers/net/wireless/ath/ath9k/link.c
+++ b/drivers/net/wireless/ath/ath9k/link.c
@@ -390,9 +390,7 @@ void ath_ani_calibrate(unsigned long data)
390 } 390 }
391 391
392 /* Verify whether we must check ANI */ 392 /* Verify whether we must check ANI */
393 if (sc->sc_ah->config.enable_ani 393 if ((timestamp - common->ani.checkani_timer) >= ah->config.ani_poll_interval) {
394 && (timestamp - common->ani.checkani_timer) >=
395 ah->config.ani_poll_interval) {
396 aniflag = true; 394 aniflag = true;
397 common->ani.checkani_timer = timestamp; 395 common->ani.checkani_timer = timestamp;
398 } 396 }
@@ -418,7 +416,6 @@ void ath_ani_calibrate(unsigned long data)
418 longcal ? "long" : "", shortcal ? "short" : "", 416 longcal ? "long" : "", shortcal ? "short" : "",
419 aniflag ? "ani" : "", common->ani.caldone ? "true" : "false"); 417 aniflag ? "ani" : "", common->ani.caldone ? "true" : "false");
420 418
421 ath9k_debug_samp_bb_mac(sc);
422 ath9k_ps_restore(sc); 419 ath9k_ps_restore(sc);
423 420
424set_timer: 421set_timer:
@@ -428,9 +425,7 @@ set_timer:
428 * short calibration and long calibration. 425 * short calibration and long calibration.
429 */ 426 */
430 cal_interval = ATH_LONG_CALINTERVAL; 427 cal_interval = ATH_LONG_CALINTERVAL;
431 if (sc->sc_ah->config.enable_ani) 428 cal_interval = min(cal_interval, (u32)ah->config.ani_poll_interval);
432 cal_interval = min(cal_interval,
433 (u32)ah->config.ani_poll_interval);
434 if (!common->ani.caldone) 429 if (!common->ani.caldone)
435 cal_interval = min(cal_interval, (u32)short_cal_interval); 430 cal_interval = min(cal_interval, (u32)short_cal_interval);
436 431
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c
index 566109a40fb3..2ef05ebffbcf 100644
--- a/drivers/net/wireless/ath/ath9k/mac.c
+++ b/drivers/net/wireless/ath/ath9k/mac.c
@@ -547,6 +547,7 @@ int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
547 547
548 rs->rs_status = 0; 548 rs->rs_status = 0;
549 rs->rs_flags = 0; 549 rs->rs_flags = 0;
550 rs->flag = 0;
550 551
551 rs->rs_datalen = ads.ds_rxstatus1 & AR_DataLen; 552 rs->rs_datalen = ads.ds_rxstatus1 & AR_DataLen;
552 rs->rs_tstamp = ads.AR_RcvTimestamp; 553 rs->rs_tstamp = ads.AR_RcvTimestamp;
@@ -586,10 +587,17 @@ int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
586 rs->rs_moreaggr = 587 rs->rs_moreaggr =
587 (ads.ds_rxstatus8 & AR_RxMoreAggr) ? 1 : 0; 588 (ads.ds_rxstatus8 & AR_RxMoreAggr) ? 1 : 0;
588 rs->rs_antenna = MS(ads.ds_rxstatus3, AR_RxAntenna); 589 rs->rs_antenna = MS(ads.ds_rxstatus3, AR_RxAntenna);
589 rs->rs_flags = 590
590 (ads.ds_rxstatus3 & AR_GI) ? ATH9K_RX_GI : 0; 591 /* directly mapped flags for ieee80211_rx_status */
591 rs->rs_flags |= 592 rs->flag |=
592 (ads.ds_rxstatus3 & AR_2040) ? ATH9K_RX_2040 : 0; 593 (ads.ds_rxstatus3 & AR_GI) ? RX_FLAG_SHORT_GI : 0;
594 rs->flag |=
595 (ads.ds_rxstatus3 & AR_2040) ? RX_FLAG_40MHZ : 0;
596 if (AR_SREV_9280_20_OR_LATER(ah))
597 rs->flag |=
598 (ads.ds_rxstatus3 & AR_STBC) ?
599 /* we can only Nss=1 STBC */
600 (1 << RX_FLAG_STBC_SHIFT) : 0;
593 601
594 if (ads.ds_rxstatus8 & AR_PreDelimCRCErr) 602 if (ads.ds_rxstatus8 & AR_PreDelimCRCErr)
595 rs->rs_flags |= ATH9K_RX_DELIM_CRC_PRE; 603 rs->rs_flags |= ATH9K_RX_DELIM_CRC_PRE;
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h
index 5865f92998e1..b02dfce964b4 100644
--- a/drivers/net/wireless/ath/ath9k/mac.h
+++ b/drivers/net/wireless/ath/ath9k/mac.h
@@ -149,6 +149,7 @@ struct ath_rx_status {
149 u32 evm2; 149 u32 evm2;
150 u32 evm3; 150 u32 evm3;
151 u32 evm4; 151 u32 evm4;
152 u32 flag; /* see enum mac80211_rx_flags */
152}; 153};
153 154
154struct ath_htc_rx_status { 155struct ath_htc_rx_status {
@@ -533,7 +534,8 @@ struct ar5416_desc {
533#define AR_2040 0x00000002 534#define AR_2040 0x00000002
534#define AR_Parallel40 0x00000004 535#define AR_Parallel40 0x00000004
535#define AR_Parallel40_S 2 536#define AR_Parallel40_S 2
536#define AR_RxStatusRsvd30 0x000000f8 537#define AR_STBC 0x00000008 /* on ar9280 and later */
538#define AR_RxStatusRsvd30 0x000000f0
537#define AR_RxAntenna 0xffffff00 539#define AR_RxAntenna 0xffffff00
538#define AR_RxAntenna_S 8 540#define AR_RxAntenna_S 8
539 541
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 5092ecae7706..e5b186b04b29 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -193,7 +193,6 @@ static bool ath_prepare_reset(struct ath_softc *sc)
193 ath_stop_ani(sc); 193 ath_stop_ani(sc);
194 del_timer_sync(&sc->rx_poll_timer); 194 del_timer_sync(&sc->rx_poll_timer);
195 195
196 ath9k_debug_samp_bb_mac(sc);
197 ath9k_hw_disable_interrupts(ah); 196 ath9k_hw_disable_interrupts(ah);
198 197
199 if (!ath_drain_all_txq(sc)) 198 if (!ath_drain_all_txq(sc))
@@ -1273,7 +1272,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
1273 curchan->center_freq); 1272 curchan->center_freq);
1274 } else { 1273 } else {
1275 /* perform spectral scan if requested. */ 1274 /* perform spectral scan if requested. */
1276 if (sc->scanning && 1275 if (test_bit(SC_OP_SCANNING, &sc->sc_flags) &&
1277 sc->spectral_mode == SPECTRAL_CHANSCAN) 1276 sc->spectral_mode == SPECTRAL_CHANSCAN)
1278 ath9k_spectral_scan_trigger(hw); 1277 ath9k_spectral_scan_trigger(hw);
1279 } 1278 }
@@ -1690,7 +1689,7 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw,
1690 bool flush = false; 1689 bool flush = false;
1691 int ret = 0; 1690 int ret = 0;
1692 1691
1693 local_bh_disable(); 1692 mutex_lock(&sc->mutex);
1694 1693
1695 switch (action) { 1694 switch (action) {
1696 case IEEE80211_AMPDU_RX_START: 1695 case IEEE80211_AMPDU_RX_START:
@@ -1723,7 +1722,7 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw,
1723 ath_err(ath9k_hw_common(sc->sc_ah), "Unknown AMPDU action\n"); 1722 ath_err(ath9k_hw_common(sc->sc_ah), "Unknown AMPDU action\n");
1724 } 1723 }
1725 1724
1726 local_bh_enable(); 1725 mutex_unlock(&sc->mutex);
1727 1726
1728 return ret; 1727 return ret;
1729} 1728}
@@ -2007,7 +2006,6 @@ static void ath9k_wow_add_disassoc_deauth_pattern(struct ath_softc *sc)
2007{ 2006{
2008 struct ath_hw *ah = sc->sc_ah; 2007 struct ath_hw *ah = sc->sc_ah;
2009 struct ath_common *common = ath9k_hw_common(ah); 2008 struct ath_common *common = ath9k_hw_common(ah);
2010 struct ath9k_hw_capabilities *pcaps = &ah->caps;
2011 int pattern_count = 0; 2009 int pattern_count = 0;
2012 int i, byte_cnt; 2010 int i, byte_cnt;
2013 u8 dis_deauth_pattern[MAX_PATTERN_SIZE]; 2011 u8 dis_deauth_pattern[MAX_PATTERN_SIZE];
@@ -2077,36 +2075,9 @@ static void ath9k_wow_add_disassoc_deauth_pattern(struct ath_softc *sc)
2077 2075
2078 /* Create Disassociate pattern mask */ 2076 /* Create Disassociate pattern mask */
2079 2077
2080 if (pcaps->hw_caps & ATH9K_HW_WOW_PATTERN_MATCH_EXACT) { 2078 dis_deauth_mask[0] = 0xfe;
2081 2079 dis_deauth_mask[1] = 0x03;
2082 if (pcaps->hw_caps & ATH9K_HW_WOW_PATTERN_MATCH_DWORD) { 2080 dis_deauth_mask[2] = 0xc0;
2083 /*
2084 * for AR9280, because of hardware limitation, the
2085 * first 4 bytes have to be matched for all patterns.
2086 * the mask for disassociation and de-auth pattern
2087 * matching need to enable the first 4 bytes.
2088 * also the duration field needs to be filled.
2089 */
2090 dis_deauth_mask[0] = 0xf0;
2091
2092 /*
2093 * fill in duration field
2094 FIXME: what is the exact value ?
2095 */
2096 dis_deauth_pattern[2] = 0xff;
2097 dis_deauth_pattern[3] = 0xff;
2098 } else {
2099 dis_deauth_mask[0] = 0xfe;
2100 }
2101
2102 dis_deauth_mask[1] = 0x03;
2103 dis_deauth_mask[2] = 0xc0;
2104 } else {
2105 dis_deauth_mask[0] = 0xef;
2106 dis_deauth_mask[1] = 0x3f;
2107 dis_deauth_mask[2] = 0x00;
2108 dis_deauth_mask[3] = 0xfc;
2109 }
2110 2081
2111 ath_dbg(common, WOW, "Adding disassoc/deauth patterns for WoW\n"); 2082 ath_dbg(common, WOW, "Adding disassoc/deauth patterns for WoW\n");
2112 2083
@@ -2342,15 +2313,13 @@ static void ath9k_set_wakeup(struct ieee80211_hw *hw, bool enabled)
2342static void ath9k_sw_scan_start(struct ieee80211_hw *hw) 2313static void ath9k_sw_scan_start(struct ieee80211_hw *hw)
2343{ 2314{
2344 struct ath_softc *sc = hw->priv; 2315 struct ath_softc *sc = hw->priv;
2345 2316 set_bit(SC_OP_SCANNING, &sc->sc_flags);
2346 sc->scanning = 1;
2347} 2317}
2348 2318
2349static void ath9k_sw_scan_complete(struct ieee80211_hw *hw) 2319static void ath9k_sw_scan_complete(struct ieee80211_hw *hw)
2350{ 2320{
2351 struct ath_softc *sc = hw->priv; 2321 struct ath_softc *sc = hw->priv;
2352 2322 clear_bit(SC_OP_SCANNING, &sc->sc_flags);
2353 sc->scanning = 0;
2354} 2323}
2355 2324
2356struct ieee80211_ops ath9k_ops = { 2325struct ieee80211_ops ath9k_ops = {
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 8be2b5d8c155..865e043e8aa6 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -868,10 +868,7 @@ static int ath9k_process_rate(struct ath_common *common,
868 if (rx_stats->rs_rate & 0x80) { 868 if (rx_stats->rs_rate & 0x80) {
869 /* HT rate */ 869 /* HT rate */
870 rxs->flag |= RX_FLAG_HT; 870 rxs->flag |= RX_FLAG_HT;
871 if (rx_stats->rs_flags & ATH9K_RX_2040) 871 rxs->flag |= rx_stats->flag;
872 rxs->flag |= RX_FLAG_40MHZ;
873 if (rx_stats->rs_flags & ATH9K_RX_GI)
874 rxs->flag |= RX_FLAG_SHORT_GI;
875 rxs->rate_idx = rx_stats->rs_rate & 0x7f; 872 rxs->rate_idx = rx_stats->rs_rate & 0x7f;
876 return 0; 873 return 0;
877 } 874 }
@@ -958,11 +955,11 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc,
958 if (rx_stats->rs_more) 955 if (rx_stats->rs_more)
959 return 0; 956 return 0;
960 957
961 ath9k_process_rssi(common, hw, hdr, rx_stats);
962
963 if (ath9k_process_rate(common, hw, rx_stats, rx_status)) 958 if (ath9k_process_rate(common, hw, rx_stats, rx_status))
964 return -EINVAL; 959 return -EINVAL;
965 960
961 ath9k_process_rssi(common, hw, hdr, rx_stats);
962
966 rx_status->band = hw->conf.chandef.chan->band; 963 rx_status->band = hw->conf.chandef.chan->band;
967 rx_status->freq = hw->conf.chandef.chan->center_freq; 964 rx_status->freq = hw->conf.chandef.chan->center_freq;
968 rx_status->signal = ah->noise + rx_stats->rs_rssi; 965 rx_status->signal = ah->noise + rx_stats->rs_rssi;
diff --git a/drivers/net/wireless/ath/ath9k/wow.c b/drivers/net/wireless/ath/ath9k/wow.c
index 9f8563091bea..81c88dd606dc 100644
--- a/drivers/net/wireless/ath/ath9k/wow.c
+++ b/drivers/net/wireless/ath/ath9k/wow.c
@@ -34,17 +34,6 @@ const char *ath9k_hw_wow_event_to_string(u32 wow_event)
34} 34}
35EXPORT_SYMBOL(ath9k_hw_wow_event_to_string); 35EXPORT_SYMBOL(ath9k_hw_wow_event_to_string);
36 36
37static void ath9k_hw_config_serdes_wow_sleep(struct ath_hw *ah)
38{
39 int i;
40
41 for (i = 0; i < ah->iniPcieSerdesWow.ia_rows; i++)
42 REG_WRITE(ah, INI_RA(&ah->iniPcieSerdesWow, i, 0),
43 INI_RA(&ah->iniPcieSerdesWow, i, 1));
44
45 usleep_range(1000, 1500);
46}
47
48static void ath9k_hw_set_powermode_wow_sleep(struct ath_hw *ah) 37static void ath9k_hw_set_powermode_wow_sleep(struct ath_hw *ah)
49{ 38{
50 struct ath_common *common = ath9k_hw_common(ah); 39 struct ath_common *common = ath9k_hw_common(ah);
@@ -58,15 +47,8 @@ static void ath9k_hw_set_powermode_wow_sleep(struct ath_hw *ah)
58 ath_err(common, "Failed to stop Rx DMA in 10ms AR_CR=0x%08x AR_DIAG_SW=0x%08x\n", 47 ath_err(common, "Failed to stop Rx DMA in 10ms AR_CR=0x%08x AR_DIAG_SW=0x%08x\n",
59 REG_READ(ah, AR_CR), REG_READ(ah, AR_DIAG_SW)); 48 REG_READ(ah, AR_CR), REG_READ(ah, AR_DIAG_SW));
60 return; 49 return;
61 } else {
62 if (!AR_SREV_9300_20_OR_LATER(ah))
63 REG_WRITE(ah, AR_RXDP, 0x0);
64 } 50 }
65 51
66 /* AR9280 WoW has sleep issue, do not set it to sleep */
67 if (AR_SREV_9280_20(ah))
68 return;
69
70 REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_ON_INT); 52 REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_ON_INT);
71} 53}
72 54
@@ -84,27 +66,16 @@ static void ath9k_wow_create_keep_alive_pattern(struct ath_hw *ah)
84 66
85 /* set the transmit buffer */ 67 /* set the transmit buffer */
86 ctl[0] = (KAL_FRAME_LEN | (MAX_RATE_POWER << 16)); 68 ctl[0] = (KAL_FRAME_LEN | (MAX_RATE_POWER << 16));
87
88 if (!(AR_SREV_9300_20_OR_LATER(ah)))
89 ctl[0] += (KAL_ANTENNA_MODE << 25);
90
91 ctl[1] = 0; 69 ctl[1] = 0;
92 ctl[3] = 0xb; /* OFDM_6M hardware value for this rate */ 70 ctl[3] = 0xb; /* OFDM_6M hardware value for this rate */
93 ctl[4] = 0; 71 ctl[4] = 0;
94 ctl[7] = (ah->txchainmask) << 2; 72 ctl[7] = (ah->txchainmask) << 2;
95 73 ctl[2] = 0xf << 16; /* tx_tries 0 */
96 if (AR_SREV_9300_20_OR_LATER(ah))
97 ctl[2] = 0xf << 16; /* tx_tries 0 */
98 else
99 ctl[2] = 0x7 << 16; /* tx_tries 0 */
100
101 74
102 for (i = 0; i < KAL_NUM_DESC_WORDS; i++) 75 for (i = 0; i < KAL_NUM_DESC_WORDS; i++)
103 REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + i * 4), ctl[i]); 76 REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + i * 4), ctl[i]);
104 77
105 /* for AR9300 family 13 descriptor words */ 78 REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + i * 4), ctl[i]);
106 if (AR_SREV_9300_20_OR_LATER(ah))
107 REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + i * 4), ctl[i]);
108 79
109 data_word[0] = (KAL_FRAME_TYPE << 2) | (KAL_FRAME_SUB_TYPE << 4) | 80 data_word[0] = (KAL_FRAME_TYPE << 2) | (KAL_FRAME_SUB_TYPE << 4) |
110 (KAL_TO_DS << 8) | (KAL_DURATION_ID << 16); 81 (KAL_TO_DS << 8) | (KAL_DURATION_ID << 16);
@@ -183,9 +154,6 @@ void ath9k_hw_wow_apply_pattern(struct ath_hw *ah, u8 *user_pattern,
183 154
184 ah->wow_event_mask |= BIT(pattern_count + AR_WOW_PAT_FOUND_SHIFT); 155 ah->wow_event_mask |= BIT(pattern_count + AR_WOW_PAT_FOUND_SHIFT);
185 156
186 if (!AR_SREV_9285_12_OR_LATER(ah))
187 return;
188
189 if (pattern_count < 4) { 157 if (pattern_count < 4) {
190 /* Pattern 0-3 uses AR_WOW_LENGTH1 register */ 158 /* Pattern 0-3 uses AR_WOW_LENGTH1 register */
191 set = (pattern_len & AR_WOW_LENGTH_MAX) << 159 set = (pattern_len & AR_WOW_LENGTH_MAX) <<
@@ -207,6 +175,7 @@ u32 ath9k_hw_wow_wakeup(struct ath_hw *ah)
207{ 175{
208 u32 wow_status = 0; 176 u32 wow_status = 0;
209 u32 val = 0, rval; 177 u32 val = 0, rval;
178
210 /* 179 /*
211 * read the WoW status register to know 180 * read the WoW status register to know
212 * the wakeup reason 181 * the wakeup reason
@@ -223,19 +192,14 @@ u32 ath9k_hw_wow_wakeup(struct ath_hw *ah)
223 val &= ah->wow_event_mask; 192 val &= ah->wow_event_mask;
224 193
225 if (val) { 194 if (val) {
226
227 if (val & AR_WOW_MAGIC_PAT_FOUND) 195 if (val & AR_WOW_MAGIC_PAT_FOUND)
228 wow_status |= AH_WOW_MAGIC_PATTERN_EN; 196 wow_status |= AH_WOW_MAGIC_PATTERN_EN;
229
230 if (AR_WOW_PATTERN_FOUND(val)) 197 if (AR_WOW_PATTERN_FOUND(val))
231 wow_status |= AH_WOW_USER_PATTERN_EN; 198 wow_status |= AH_WOW_USER_PATTERN_EN;
232
233 if (val & AR_WOW_KEEP_ALIVE_FAIL) 199 if (val & AR_WOW_KEEP_ALIVE_FAIL)
234 wow_status |= AH_WOW_LINK_CHANGE; 200 wow_status |= AH_WOW_LINK_CHANGE;
235
236 if (val & AR_WOW_BEACON_FAIL) 201 if (val & AR_WOW_BEACON_FAIL)
237 wow_status |= AH_WOW_BEACON_MISS; 202 wow_status |= AH_WOW_BEACON_MISS;
238
239 } 203 }
240 204
241 /* 205 /*
@@ -255,17 +219,6 @@ u32 ath9k_hw_wow_wakeup(struct ath_hw *ah)
255 AR_WOW_CLEAR_EVENTS(REG_READ(ah, AR_WOW_PATTERN))); 219 AR_WOW_CLEAR_EVENTS(REG_READ(ah, AR_WOW_PATTERN)));
256 220
257 /* 221 /*
258 * tie reset register for AR9002 family of chipsets
259 * NB: not tieing it back might have some repurcussions.
260 */
261
262 if (!AR_SREV_9300_20_OR_LATER(ah)) {
263 REG_SET_BIT(ah, AR_WA, AR_WA_UNTIE_RESET_EN |
264 AR_WA_POR_SHORT | AR_WA_RESET_EN);
265 }
266
267
268 /*
269 * restore the beacon threshold to init value 222 * restore the beacon threshold to init value
270 */ 223 */
271 REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR); 224 REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR);
@@ -277,8 +230,7 @@ u32 ath9k_hw_wow_wakeup(struct ath_hw *ah)
277 * reset to our Chip's Power On Reset so that any PCI-E 230 * reset to our Chip's Power On Reset so that any PCI-E
278 * reset from the bus will not reset our chip 231 * reset from the bus will not reset our chip
279 */ 232 */
280 233 if (ah->is_pciexpress)
281 if (AR_SREV_9280_20_OR_LATER(ah) && ah->is_pciexpress)
282 ath9k_hw_configpcipowersave(ah, false); 234 ath9k_hw_configpcipowersave(ah, false);
283 235
284 ah->wow_event_mask = 0; 236 ah->wow_event_mask = 0;
@@ -298,7 +250,6 @@ void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable)
298 * are from the 'pattern_enable' in this function and 250 * are from the 'pattern_enable' in this function and
299 * 'pattern_count' of ath9k_hw_wow_apply_pattern() 251 * 'pattern_count' of ath9k_hw_wow_apply_pattern()
300 */ 252 */
301
302 wow_event_mask = ah->wow_event_mask; 253 wow_event_mask = ah->wow_event_mask;
303 254
304 /* 255 /*
@@ -306,50 +257,15 @@ void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable)
306 * WOW sleep, we do want the Reset from the PCI-E to disturb 257 * WOW sleep, we do want the Reset from the PCI-E to disturb
307 * our hw state 258 * our hw state
308 */ 259 */
309
310 if (ah->is_pciexpress) { 260 if (ah->is_pciexpress) {
311
312 /* 261 /*
313 * we need to untie the internal POR (power-on-reset) 262 * we need to untie the internal POR (power-on-reset)
314 * to the external PCI-E reset. We also need to tie 263 * to the external PCI-E reset. We also need to tie
315 * the PCI-E Phy reset to the PCI-E reset. 264 * the PCI-E Phy reset to the PCI-E reset.
316 */ 265 */
317 266 set = AR_WA_RESET_EN | AR_WA_POR_SHORT;
318 if (AR_SREV_9300_20_OR_LATER(ah)) { 267 clr = AR_WA_UNTIE_RESET_EN | AR_WA_D3_L1_DISABLE;
319 set = AR_WA_RESET_EN | AR_WA_POR_SHORT; 268 REG_RMW(ah, AR_WA, set, clr);
320 clr = AR_WA_UNTIE_RESET_EN | AR_WA_D3_L1_DISABLE;
321 REG_RMW(ah, AR_WA, set, clr);
322 } else {
323 if (AR_SREV_9285(ah) || AR_SREV_9287(ah))
324 set = AR9285_WA_DEFAULT;
325 else
326 set = AR9280_WA_DEFAULT;
327
328 /*
329 * In AR9280 and AR9285, bit 14 in WA register
330 * (disable L1) should only be set when device
331 * enters D3 state and be cleared when device
332 * comes back to D0
333 */
334
335 if (ah->config.pcie_waen & AR_WA_D3_L1_DISABLE)
336 set |= AR_WA_D3_L1_DISABLE;
337
338 clr = AR_WA_UNTIE_RESET_EN;
339 set |= AR_WA_RESET_EN | AR_WA_POR_SHORT;
340 REG_RMW(ah, AR_WA, set, clr);
341
342 /*
343 * for WoW sleep, we reprogram the SerDes so that the
344 * PLL and CLK REQ are both enabled. This uses more
345 * power but otherwise WoW sleep is unstable and the
346 * chip may disappear.
347 */
348
349 if (AR_SREV_9285_12_OR_LATER(ah))
350 ath9k_hw_config_serdes_wow_sleep(ah);
351
352 }
353 } 269 }
354 270
355 /* 271 /*
@@ -378,7 +294,6 @@ void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable)
378 * Program default values for pattern backoff, aifs/slot/KAL count, 294 * Program default values for pattern backoff, aifs/slot/KAL count,
379 * beacon miss timeout, KAL timeout, etc. 295 * beacon miss timeout, KAL timeout, etc.
380 */ 296 */
381
382 set = AR_WOW_BACK_OFF_SHIFT(AR_WOW_PAT_BACKOFF); 297 set = AR_WOW_BACK_OFF_SHIFT(AR_WOW_PAT_BACKOFF);
383 REG_SET_BIT(ah, AR_WOW_PATTERN, set); 298 REG_SET_BIT(ah, AR_WOW_PATTERN, set);
384 299
@@ -398,7 +313,7 @@ void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable)
398 /* 313 /*
399 * Keep alive timo in ms except AR9280 314 * Keep alive timo in ms except AR9280
400 */ 315 */
401 if (!pattern_enable || AR_SREV_9280(ah)) 316 if (!pattern_enable)
402 set = AR_WOW_KEEP_ALIVE_NEVER; 317 set = AR_WOW_KEEP_ALIVE_NEVER;
403 else 318 else
404 set = KAL_TIMEOUT * 32; 319 set = KAL_TIMEOUT * 32;
@@ -420,7 +335,6 @@ void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable)
420 /* 335 /*
421 * Configure MAC WoW Registers 336 * Configure MAC WoW Registers
422 */ 337 */
423
424 set = 0; 338 set = 0;
425 /* Send keep alive timeouts anyway */ 339 /* Send keep alive timeouts anyway */
426 clr = AR_WOW_KEEP_ALIVE_AUTO_DIS; 340 clr = AR_WOW_KEEP_ALIVE_AUTO_DIS;
@@ -430,16 +344,9 @@ void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable)
430 else 344 else
431 set = AR_WOW_KEEP_ALIVE_FAIL_DIS; 345 set = AR_WOW_KEEP_ALIVE_FAIL_DIS;
432 346
433 /*
434 * FIXME: For now disable keep alive frame
435 * failure. This seems to sometimes trigger
436 * unnecessary wake up with AR9485 chipsets.
437 */
438 set = AR_WOW_KEEP_ALIVE_FAIL_DIS; 347 set = AR_WOW_KEEP_ALIVE_FAIL_DIS;
439
440 REG_RMW(ah, AR_WOW_KEEP_ALIVE, set, clr); 348 REG_RMW(ah, AR_WOW_KEEP_ALIVE, set, clr);
441 349
442
443 /* 350 /*
444 * we are relying on a bmiss failure. ensure we have 351 * we are relying on a bmiss failure. ensure we have
445 * enough threshold to prevent false positives 352 * enough threshold to prevent false positives
@@ -473,14 +380,8 @@ void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable)
473 set |= AR_WOW_MAC_INTR_EN; 380 set |= AR_WOW_MAC_INTR_EN;
474 REG_RMW(ah, AR_WOW_PATTERN, set, clr); 381 REG_RMW(ah, AR_WOW_PATTERN, set, clr);
475 382
476 /* 383 REG_WRITE(ah, AR_WOW_PATTERN_MATCH_LT_256B,
477 * For AR9285 and later version of chipsets 384 AR_WOW_PATTERN_SUPPORTED);
478 * enable WoW pattern match for packets less
479 * than 256 bytes for all patterns
480 */
481 if (AR_SREV_9285_12_OR_LATER(ah))
482 REG_WRITE(ah, AR_WOW_PATTERN_MATCH_LT_256B,
483 AR_WOW_PATTERN_SUPPORTED);
484 385
485 /* 386 /*
486 * Set the power states appropriately and enable PME 387 * Set the power states appropriately and enable PME
@@ -488,43 +389,32 @@ void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable)
488 clr = 0; 389 clr = 0;
489 set = AR_PMCTRL_PWR_STATE_D1D3 | AR_PMCTRL_HOST_PME_EN | 390 set = AR_PMCTRL_PWR_STATE_D1D3 | AR_PMCTRL_HOST_PME_EN |
490 AR_PMCTRL_PWR_PM_CTRL_ENA; 391 AR_PMCTRL_PWR_PM_CTRL_ENA;
491 /*
492 * This is needed for AR9300 chipsets to wake-up
493 * the host.
494 */
495 if (AR_SREV_9300_20_OR_LATER(ah))
496 clr = AR_PCIE_PM_CTRL_ENA;
497 392
393 clr = AR_PCIE_PM_CTRL_ENA;
498 REG_RMW(ah, AR_PCIE_PM_CTRL, set, clr); 394 REG_RMW(ah, AR_PCIE_PM_CTRL, set, clr);
499 395
500 if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) { 396 /*
501 /* 397 * this is needed to prevent the chip waking up
502 * this is needed to prevent the chip waking up 398 * the host within 3-4 seconds with certain
503 * the host within 3-4 seconds with certain 399 * platform/BIOS. The fix is to enable
504 * platform/BIOS. The fix is to enable 400 * D1 & D3 to match original definition and
505 * D1 & D3 to match original definition and 401 * also match the OTP value. Anyway this
506 * also match the OTP value. Anyway this 402 * is more related to SW WOW.
507 * is more related to SW WOW. 403 */
508 */ 404 clr = AR_PMCTRL_PWR_STATE_D1D3;
509 clr = AR_PMCTRL_PWR_STATE_D1D3; 405 REG_CLR_BIT(ah, AR_PCIE_PM_CTRL, clr);
510 REG_CLR_BIT(ah, AR_PCIE_PM_CTRL, clr);
511
512 set = AR_PMCTRL_PWR_STATE_D1D3_REAL;
513 REG_SET_BIT(ah, AR_PCIE_PM_CTRL, set);
514 }
515
516 406
407 set = AR_PMCTRL_PWR_STATE_D1D3_REAL;
408 REG_SET_BIT(ah, AR_PCIE_PM_CTRL, set);
517 409
518 REG_CLR_BIT(ah, AR_STA_ID1, AR_STA_ID1_PRESERVE_SEQNUM); 410 REG_CLR_BIT(ah, AR_STA_ID1, AR_STA_ID1_PRESERVE_SEQNUM);
519 411
520 if (AR_SREV_9300_20_OR_LATER(ah)) { 412 /* to bring down WOW power low margin */
521 /* to bring down WOW power low margin */ 413 set = BIT(13);
522 set = BIT(13); 414 REG_SET_BIT(ah, AR_PCIE_PHY_REG3, set);
523 REG_SET_BIT(ah, AR_PCIE_PHY_REG3, set); 415 /* HW WoW */
524 /* HW WoW */ 416 clr = BIT(5);
525 clr = BIT(5); 417 REG_CLR_BIT(ah, AR_PCU_MISC_MODE3, clr);
526 REG_CLR_BIT(ah, AR_PCU_MISC_MODE3, clr);
527 }
528 418
529 ath9k_hw_set_powermode_wow_sleep(ah); 419 ath9k_hw_set_powermode_wow_sleep(ah);
530 ah->wow_event_mask = wow_event_mask; 420 ah->wow_event_mask = wow_event_mask;
diff --git a/drivers/net/wireless/ath/wil6210/Kconfig b/drivers/net/wireless/ath/wil6210/Kconfig
index bac3d98a0cfb..5644ac54facc 100644
--- a/drivers/net/wireless/ath/wil6210/Kconfig
+++ b/drivers/net/wireless/ath/wil6210/Kconfig
@@ -27,3 +27,15 @@ config WIL6210_ISR_COR
27 self-clear when accessed for debug purposes, it makes 27 self-clear when accessed for debug purposes, it makes
28 such monitoring impossible. 28 such monitoring impossible.
29 Say y unless you debug interrupts 29 Say y unless you debug interrupts
30
31config ATH6KL_TRACING
32 bool "wil6210 tracing support"
33 depends on WIL6210
34 depends on EVENT_TRACING
35 default y
36 ---help---
37 Say Y here to enable tracepoints for the wil6210 driver
38 using the kernel tracing infrastructure. Select this
39 option if you are interested in debugging the driver.
40
41 If unsure, say Y to make it easier to debug problems.
diff --git a/drivers/net/wireless/ath/wil6210/Makefile b/drivers/net/wireless/ath/wil6210/Makefile
index d288eea0a26a..f891d514d881 100644
--- a/drivers/net/wireless/ath/wil6210/Makefile
+++ b/drivers/net/wireless/ath/wil6210/Makefile
@@ -1,15 +1,20 @@
1obj-$(CONFIG_WIL6210) += wil6210.o 1obj-$(CONFIG_WIL6210) += wil6210.o
2 2
3wil6210-objs := main.o 3wil6210-y := main.o
4wil6210-objs += netdev.o 4wil6210-y += netdev.o
5wil6210-objs += cfg80211.o 5wil6210-y += cfg80211.o
6wil6210-objs += pcie_bus.o 6wil6210-y += pcie_bus.o
7wil6210-objs += debugfs.o 7wil6210-y += debugfs.o
8wil6210-objs += wmi.o 8wil6210-y += wmi.o
9wil6210-objs += interrupt.o 9wil6210-y += interrupt.o
10wil6210-objs += txrx.o 10wil6210-y += txrx.o
11wil6210-y += debug.o
12wil6210-$(CONFIG_WIL6210_TRACING) += trace.o
11 13
12ifeq (, $(findstring -W,$(EXTRA_CFLAGS))) 14ifeq (, $(findstring -W,$(EXTRA_CFLAGS)))
13 subdir-ccflags-y += -Werror 15 subdir-ccflags-y += -Werror
14endif 16endif
17# for tracing framework to find trace.h
18CFLAGS_trace.o := -I$(src)
19
15subdir-ccflags-y += -D__CHECK_ENDIAN__ 20subdir-ccflags-y += -D__CHECK_ENDIAN__
diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c
index c5d4a87abaaf..4eb05d0818c3 100644
--- a/drivers/net/wireless/ath/wil6210/cfg80211.c
+++ b/drivers/net/wireless/ath/wil6210/cfg80211.c
@@ -322,12 +322,16 @@ static int wil_cfg80211_connect(struct wiphy *wiphy,
322 * FW don't support scan after connection attempt 322 * FW don't support scan after connection attempt
323 */ 323 */
324 set_bit(wil_status_dontscan, &wil->status); 324 set_bit(wil_status_dontscan, &wil->status);
325 set_bit(wil_status_fwconnecting, &wil->status);
325 326
326 rc = wmi_send(wil, WMI_CONNECT_CMDID, &conn, sizeof(conn)); 327 rc = wmi_send(wil, WMI_CONNECT_CMDID, &conn, sizeof(conn));
327 if (rc == 0) { 328 if (rc == 0) {
328 /* Connect can take lots of time */ 329 /* Connect can take lots of time */
329 mod_timer(&wil->connect_timer, 330 mod_timer(&wil->connect_timer,
330 jiffies + msecs_to_jiffies(2000)); 331 jiffies + msecs_to_jiffies(2000));
332 } else {
333 clear_bit(wil_status_dontscan, &wil->status);
334 clear_bit(wil_status_fwconnecting, &wil->status);
331 } 335 }
332 336
333 out: 337 out:
diff --git a/drivers/net/wireless/ath/wil6210/debug.c b/drivers/net/wireless/ath/wil6210/debug.c
new file mode 100644
index 000000000000..9eeabf4a5879
--- /dev/null
+++ b/drivers/net/wireless/ath/wil6210/debug.c
@@ -0,0 +1,69 @@
1/*
2 * Copyright (c) 2013 Qualcomm Atheros, Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "wil6210.h"
18#include "trace.h"
19
20int wil_err(struct wil6210_priv *wil, const char *fmt, ...)
21{
22 struct net_device *ndev = wil_to_ndev(wil);
23 struct va_format vaf = {
24 .fmt = fmt,
25 };
26 va_list args;
27 int ret;
28
29 va_start(args, fmt);
30 vaf.va = &args;
31 ret = netdev_err(ndev, "%pV", &vaf);
32 trace_wil6210_log_err(&vaf);
33 va_end(args);
34
35 return ret;
36}
37
38int wil_info(struct wil6210_priv *wil, const char *fmt, ...)
39{
40 struct net_device *ndev = wil_to_ndev(wil);
41 struct va_format vaf = {
42 .fmt = fmt,
43 };
44 va_list args;
45 int ret;
46
47 va_start(args, fmt);
48 vaf.va = &args;
49 ret = netdev_info(ndev, "%pV", &vaf);
50 trace_wil6210_log_info(&vaf);
51 va_end(args);
52
53 return ret;
54}
55
56int wil_dbg_trace(struct wil6210_priv *wil, const char *fmt, ...)
57{
58 struct va_format vaf = {
59 .fmt = fmt,
60 };
61 va_list args;
62
63 va_start(args, fmt);
64 vaf.va = &args;
65 trace_wil6210_log_dbg(&vaf);
66 va_end(args);
67
68 return 0;
69}
diff --git a/drivers/net/wireless/ath/wil6210/debugfs.c b/drivers/net/wireless/ath/wil6210/debugfs.c
index 727b1f53e6ad..e8308ec30970 100644
--- a/drivers/net/wireless/ath/wil6210/debugfs.c
+++ b/drivers/net/wireless/ath/wil6210/debugfs.c
@@ -418,9 +418,15 @@ static int wil_txdesc_debugfs_show(struct seq_file *s, void *data)
418 if (skb) { 418 if (skb) {
419 unsigned char printbuf[16 * 3 + 2]; 419 unsigned char printbuf[16 * 3 + 2];
420 int i = 0; 420 int i = 0;
421 int len = skb_headlen(skb); 421 int len = le16_to_cpu(d->dma.length);
422 void *p = skb->data; 422 void *p = skb->data;
423 423
424 if (len != skb_headlen(skb)) {
425 seq_printf(s, "!!! len: desc = %d skb = %d\n",
426 len, skb_headlen(skb));
427 len = min_t(int, len, skb_headlen(skb));
428 }
429
424 seq_printf(s, " len = %d\n", len); 430 seq_printf(s, " len = %d\n", len);
425 431
426 while (i < len) { 432 while (i < len) {
diff --git a/drivers/net/wireless/ath/wil6210/interrupt.c b/drivers/net/wireless/ath/wil6210/interrupt.c
index e3c1e7684f9c..8205d3e4ab66 100644
--- a/drivers/net/wireless/ath/wil6210/interrupt.c
+++ b/drivers/net/wireless/ath/wil6210/interrupt.c
@@ -17,6 +17,7 @@
17#include <linux/interrupt.h> 17#include <linux/interrupt.h>
18 18
19#include "wil6210.h" 19#include "wil6210.h"
20#include "trace.h"
20 21
21/** 22/**
22 * Theory of operation: 23 * Theory of operation:
@@ -103,14 +104,14 @@ static void wil6210_mask_irq_pseudo(struct wil6210_priv *wil)
103 clear_bit(wil_status_irqen, &wil->status); 104 clear_bit(wil_status_irqen, &wil->status);
104} 105}
105 106
106static void wil6210_unmask_irq_tx(struct wil6210_priv *wil) 107void wil6210_unmask_irq_tx(struct wil6210_priv *wil)
107{ 108{
108 iowrite32(WIL6210_IMC_TX, wil->csr + 109 iowrite32(WIL6210_IMC_TX, wil->csr +
109 HOSTADDR(RGF_DMA_EP_TX_ICR) + 110 HOSTADDR(RGF_DMA_EP_TX_ICR) +
110 offsetof(struct RGF_ICR, IMC)); 111 offsetof(struct RGF_ICR, IMC));
111} 112}
112 113
113static void wil6210_unmask_irq_rx(struct wil6210_priv *wil) 114void wil6210_unmask_irq_rx(struct wil6210_priv *wil)
114{ 115{
115 iowrite32(WIL6210_IMC_RX, wil->csr + 116 iowrite32(WIL6210_IMC_RX, wil->csr +
116 HOSTADDR(RGF_DMA_EP_RX_ICR) + 117 HOSTADDR(RGF_DMA_EP_RX_ICR) +
@@ -168,6 +169,7 @@ static irqreturn_t wil6210_irq_rx(int irq, void *cookie)
168 HOSTADDR(RGF_DMA_EP_RX_ICR) + 169 HOSTADDR(RGF_DMA_EP_RX_ICR) +
169 offsetof(struct RGF_ICR, ICR)); 170 offsetof(struct RGF_ICR, ICR));
170 171
172 trace_wil6210_irq_rx(isr);
171 wil_dbg_irq(wil, "ISR RX 0x%08x\n", isr); 173 wil_dbg_irq(wil, "ISR RX 0x%08x\n", isr);
172 174
173 if (!isr) { 175 if (!isr) {
@@ -180,13 +182,14 @@ static irqreturn_t wil6210_irq_rx(int irq, void *cookie)
180 if (isr & BIT_DMA_EP_RX_ICR_RX_DONE) { 182 if (isr & BIT_DMA_EP_RX_ICR_RX_DONE) {
181 wil_dbg_irq(wil, "RX done\n"); 183 wil_dbg_irq(wil, "RX done\n");
182 isr &= ~BIT_DMA_EP_RX_ICR_RX_DONE; 184 isr &= ~BIT_DMA_EP_RX_ICR_RX_DONE;
183 wil_rx_handle(wil); 185 wil_dbg_txrx(wil, "NAPI schedule\n");
186 napi_schedule(&wil->napi_rx);
184 } 187 }
185 188
186 if (isr) 189 if (isr)
187 wil_err(wil, "un-handled RX ISR bits 0x%08x\n", isr); 190 wil_err(wil, "un-handled RX ISR bits 0x%08x\n", isr);
188 191
189 wil6210_unmask_irq_rx(wil); 192 /* Rx IRQ will be enabled when NAPI processing finished */
190 193
191 return IRQ_HANDLED; 194 return IRQ_HANDLED;
192} 195}
@@ -198,6 +201,7 @@ static irqreturn_t wil6210_irq_tx(int irq, void *cookie)
198 HOSTADDR(RGF_DMA_EP_TX_ICR) + 201 HOSTADDR(RGF_DMA_EP_TX_ICR) +
199 offsetof(struct RGF_ICR, ICR)); 202 offsetof(struct RGF_ICR, ICR));
200 203
204 trace_wil6210_irq_tx(isr);
201 wil_dbg_irq(wil, "ISR TX 0x%08x\n", isr); 205 wil_dbg_irq(wil, "ISR TX 0x%08x\n", isr);
202 206
203 if (!isr) { 207 if (!isr) {
@@ -208,23 +212,17 @@ static irqreturn_t wil6210_irq_tx(int irq, void *cookie)
208 wil6210_mask_irq_tx(wil); 212 wil6210_mask_irq_tx(wil);
209 213
210 if (isr & BIT_DMA_EP_TX_ICR_TX_DONE) { 214 if (isr & BIT_DMA_EP_TX_ICR_TX_DONE) {
211 uint i;
212 wil_dbg_irq(wil, "TX done\n"); 215 wil_dbg_irq(wil, "TX done\n");
216 napi_schedule(&wil->napi_tx);
213 isr &= ~BIT_DMA_EP_TX_ICR_TX_DONE; 217 isr &= ~BIT_DMA_EP_TX_ICR_TX_DONE;
214 for (i = 0; i < 24; i++) { 218 /* clear also all VRING interrupts */
215 u32 mask = BIT_DMA_EP_TX_ICR_TX_DONE_N(i); 219 isr &= ~(BIT(25) - 1UL);
216 if (isr & mask) {
217 isr &= ~mask;
218 wil_dbg_irq(wil, "TX done(%i)\n", i);
219 wil_tx_complete(wil, i);
220 }
221 }
222 } 220 }
223 221
224 if (isr) 222 if (isr)
225 wil_err(wil, "un-handled TX ISR bits 0x%08x\n", isr); 223 wil_err(wil, "un-handled TX ISR bits 0x%08x\n", isr);
226 224
227 wil6210_unmask_irq_tx(wil); 225 /* Tx IRQ will be enabled when NAPI processing finished */
228 226
229 return IRQ_HANDLED; 227 return IRQ_HANDLED;
230} 228}
@@ -256,6 +254,7 @@ static irqreturn_t wil6210_irq_misc(int irq, void *cookie)
256 HOSTADDR(RGF_DMA_EP_MISC_ICR) + 254 HOSTADDR(RGF_DMA_EP_MISC_ICR) +
257 offsetof(struct RGF_ICR, ICR)); 255 offsetof(struct RGF_ICR, ICR));
258 256
257 trace_wil6210_irq_misc(isr);
259 wil_dbg_irq(wil, "ISR MISC 0x%08x\n", isr); 258 wil_dbg_irq(wil, "ISR MISC 0x%08x\n", isr);
260 259
261 if (!isr) { 260 if (!isr) {
@@ -301,6 +300,7 @@ static irqreturn_t wil6210_irq_misc_thread(int irq, void *cookie)
301 struct wil6210_priv *wil = cookie; 300 struct wil6210_priv *wil = cookie;
302 u32 isr = wil->isr_misc; 301 u32 isr = wil->isr_misc;
303 302
303 trace_wil6210_irq_misc_thread(isr);
304 wil_dbg_irq(wil, "Thread ISR MISC 0x%08x\n", isr); 304 wil_dbg_irq(wil, "Thread ISR MISC 0x%08x\n", isr);
305 305
306 if (isr & ISR_MISC_FW_ERROR) { 306 if (isr & ISR_MISC_FW_ERROR) {
@@ -408,6 +408,7 @@ static irqreturn_t wil6210_hardirq(int irq, void *cookie)
408 if (wil6210_debug_irq_mask(wil, pseudo_cause)) 408 if (wil6210_debug_irq_mask(wil, pseudo_cause))
409 return IRQ_NONE; 409 return IRQ_NONE;
410 410
411 trace_wil6210_irq_pseudo(pseudo_cause);
411 wil_dbg_irq(wil, "Pseudo IRQ 0x%08x\n", pseudo_cause); 412 wil_dbg_irq(wil, "Pseudo IRQ 0x%08x\n", pseudo_cause);
412 413
413 wil6210_mask_irq_pseudo(wil); 414 wil6210_mask_irq_pseudo(wil);
diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c
index a0478e2f6868..c97b864667c5 100644
--- a/drivers/net/wireless/ath/wil6210/main.c
+++ b/drivers/net/wireless/ath/wil6210/main.c
@@ -56,27 +56,21 @@ static void _wil6210_disconnect(struct wil6210_priv *wil, void *bssid)
56{ 56{
57 uint i; 57 uint i;
58 struct net_device *ndev = wil_to_ndev(wil); 58 struct net_device *ndev = wil_to_ndev(wil);
59 struct wireless_dev *wdev = wil->wdev;
60 59
61 wil_dbg_misc(wil, "%s()\n", __func__); 60 wil_dbg_misc(wil, "%s()\n", __func__);
62 61
63 wil_link_off(wil); 62 wil_link_off(wil);
64 clear_bit(wil_status_fwconnected, &wil->status); 63 if (test_bit(wil_status_fwconnected, &wil->status)) {
65 64 clear_bit(wil_status_fwconnected, &wil->status);
66 switch (wdev->sme_state) { 65 cfg80211_disconnected(ndev,
67 case CFG80211_SME_CONNECTED: 66 WLAN_STATUS_UNSPECIFIED_FAILURE,
68 cfg80211_disconnected(ndev, WLAN_STATUS_UNSPECIFIED_FAILURE,
69 NULL, 0, GFP_KERNEL); 67 NULL, 0, GFP_KERNEL);
70 break; 68 } else if (test_bit(wil_status_fwconnecting, &wil->status)) {
71 case CFG80211_SME_CONNECTING:
72 cfg80211_connect_result(ndev, bssid, NULL, 0, NULL, 0, 69 cfg80211_connect_result(ndev, bssid, NULL, 0, NULL, 0,
73 WLAN_STATUS_UNSPECIFIED_FAILURE, 70 WLAN_STATUS_UNSPECIFIED_FAILURE,
74 GFP_KERNEL); 71 GFP_KERNEL);
75 break;
76 default:
77 break;
78 } 72 }
79 73 clear_bit(wil_status_fwconnecting, &wil->status);
80 for (i = 0; i < ARRAY_SIZE(wil->vring_tx); i++) 74 for (i = 0; i < ARRAY_SIZE(wil->vring_tx); i++)
81 wil_vring_fini_tx(wil, i); 75 wil_vring_fini_tx(wil, i);
82 76
@@ -365,6 +359,9 @@ static int __wil_up(struct wil6210_priv *wil)
365 /* Rx VRING. After MAC and beacon */ 359 /* Rx VRING. After MAC and beacon */
366 wil_rx_init(wil); 360 wil_rx_init(wil);
367 361
362 napi_enable(&wil->napi_rx);
363 napi_enable(&wil->napi_tx);
364
368 return 0; 365 return 0;
369} 366}
370 367
@@ -381,6 +378,9 @@ int wil_up(struct wil6210_priv *wil)
381 378
382static int __wil_down(struct wil6210_priv *wil) 379static int __wil_down(struct wil6210_priv *wil)
383{ 380{
381 napi_disable(&wil->napi_rx);
382 napi_disable(&wil->napi_tx);
383
384 if (wil->scan_request) { 384 if (wil->scan_request) {
385 cfg80211_scan_done(wil->scan_request, true); 385 cfg80211_scan_done(wil->scan_request, true);
386 wil->scan_request = NULL; 386 wil->scan_request = NULL;
diff --git a/drivers/net/wireless/ath/wil6210/netdev.c b/drivers/net/wireless/ath/wil6210/netdev.c
index 098a8ec6b841..29dd1e58cb17 100644
--- a/drivers/net/wireless/ath/wil6210/netdev.c
+++ b/drivers/net/wireless/ath/wil6210/netdev.c
@@ -40,6 +40,55 @@ static const struct net_device_ops wil_netdev_ops = {
40 .ndo_validate_addr = eth_validate_addr, 40 .ndo_validate_addr = eth_validate_addr,
41}; 41};
42 42
43static int wil6210_netdev_poll_rx(struct napi_struct *napi, int budget)
44{
45 struct wil6210_priv *wil = container_of(napi, struct wil6210_priv,
46 napi_rx);
47 int quota = budget;
48 int done;
49
50 wil_rx_handle(wil, &quota);
51 done = budget - quota;
52
53 if (done <= 1) { /* burst ends - only one packet processed */
54 napi_complete(napi);
55 wil6210_unmask_irq_rx(wil);
56 wil_dbg_txrx(wil, "NAPI RX complete\n");
57 }
58
59 wil_dbg_txrx(wil, "NAPI RX poll(%d) done %d\n", budget, done);
60
61 return done;
62}
63
64static int wil6210_netdev_poll_tx(struct napi_struct *napi, int budget)
65{
66 struct wil6210_priv *wil = container_of(napi, struct wil6210_priv,
67 napi_tx);
68 int tx_done = 0;
69 uint i;
70
71 /* always process ALL Tx complete, regardless budget - it is fast */
72 for (i = 0; i < WIL6210_MAX_TX_RINGS; i++) {
73 struct vring *vring = &wil->vring_tx[i];
74
75 if (!vring->va)
76 continue;
77
78 tx_done += wil_tx_complete(wil, i);
79 }
80
81 if (tx_done <= 1) { /* burst ends - only one packet processed */
82 napi_complete(napi);
83 wil6210_unmask_irq_tx(wil);
84 wil_dbg_txrx(wil, "NAPI TX complete\n");
85 }
86
87 wil_dbg_txrx(wil, "NAPI TX poll(%d) done %d\n", budget, tx_done);
88
89 return min(tx_done, budget);
90}
91
43void *wil_if_alloc(struct device *dev, void __iomem *csr) 92void *wil_if_alloc(struct device *dev, void __iomem *csr)
44{ 93{
45 struct net_device *ndev; 94 struct net_device *ndev;
@@ -81,6 +130,11 @@ void *wil_if_alloc(struct device *dev, void __iomem *csr)
81 SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy)); 130 SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
82 wdev->netdev = ndev; 131 wdev->netdev = ndev;
83 132
133 netif_napi_add(ndev, &wil->napi_rx, wil6210_netdev_poll_rx,
134 WIL6210_NAPI_BUDGET);
135 netif_napi_add(ndev, &wil->napi_tx, wil6210_netdev_poll_tx,
136 WIL6210_NAPI_BUDGET);
137
84 wil_link_off(wil); 138 wil_link_off(wil);
85 139
86 return wil; 140 return wil;
diff --git a/drivers/net/wireless/ath/wil6210/trace.c b/drivers/net/wireless/ath/wil6210/trace.c
new file mode 100644
index 000000000000..cd2534b9c5aa
--- /dev/null
+++ b/drivers/net/wireless/ath/wil6210/trace.c
@@ -0,0 +1,20 @@
1/*
2 * Copyright (c) 2013 Qualcomm Atheros, Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <linux/module.h>
18
19#define CREATE_TRACE_POINTS
20#include "trace.h"
diff --git a/drivers/net/wireless/ath/wil6210/trace.h b/drivers/net/wireless/ath/wil6210/trace.h
new file mode 100644
index 000000000000..eff1239be53a
--- /dev/null
+++ b/drivers/net/wireless/ath/wil6210/trace.h
@@ -0,0 +1,235 @@
1/*
2 * Copyright (c) 2013 Qualcomm Atheros, Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#undef TRACE_SYSTEM
18#define TRACE_SYSTEM wil6210
19#if !defined(WIL6210_TRACE_H) || defined(TRACE_HEADER_MULTI_READ)
20#define WIL6210_TRACE_H
21
22#include <linux/tracepoint.h>
23#include "wil6210.h"
24#include "txrx.h"
25
26/* create empty functions when tracing is disabled */
27#if !defined(CONFIG_WIL6210_TRACING) || defined(__CHECKER__)
28
29#undef TRACE_EVENT
30#define TRACE_EVENT(name, proto, ...) \
31static inline void trace_ ## name(proto) {}
32#undef DECLARE_EVENT_CLASS
33#define DECLARE_EVENT_CLASS(...)
34#undef DEFINE_EVENT
35#define DEFINE_EVENT(evt_class, name, proto, ...) \
36static inline void trace_ ## name(proto) {}
37#endif /* !CONFIG_WIL6210_TRACING || defined(__CHECKER__) */
38
39DECLARE_EVENT_CLASS(wil6210_wmi,
40 TP_PROTO(u16 id, void *buf, u16 buf_len),
41
42 TP_ARGS(id, buf, buf_len),
43
44 TP_STRUCT__entry(
45 __field(u16, id)
46 __field(u16, buf_len)
47 __dynamic_array(u8, buf, buf_len)
48 ),
49
50 TP_fast_assign(
51 __entry->id = id;
52 __entry->buf_len = buf_len;
53 memcpy(__get_dynamic_array(buf), buf, buf_len);
54 ),
55
56 TP_printk(
57 "id 0x%04x len %d",
58 __entry->id, __entry->buf_len
59 )
60);
61
62DEFINE_EVENT(wil6210_wmi, wil6210_wmi_cmd,
63 TP_PROTO(u16 id, void *buf, u16 buf_len),
64 TP_ARGS(id, buf, buf_len)
65);
66
67DEFINE_EVENT(wil6210_wmi, wil6210_wmi_event,
68 TP_PROTO(u16 id, void *buf, u16 buf_len),
69 TP_ARGS(id, buf, buf_len)
70);
71
72#define WIL6210_MSG_MAX (200)
73
74DECLARE_EVENT_CLASS(wil6210_log_event,
75 TP_PROTO(struct va_format *vaf),
76 TP_ARGS(vaf),
77 TP_STRUCT__entry(
78 __dynamic_array(char, msg, WIL6210_MSG_MAX)
79 ),
80 TP_fast_assign(
81 WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg),
82 WIL6210_MSG_MAX,
83 vaf->fmt,
84 *vaf->va) >= WIL6210_MSG_MAX);
85 ),
86 TP_printk("%s", __get_str(msg))
87);
88
89DEFINE_EVENT(wil6210_log_event, wil6210_log_err,
90 TP_PROTO(struct va_format *vaf),
91 TP_ARGS(vaf)
92);
93
94DEFINE_EVENT(wil6210_log_event, wil6210_log_info,
95 TP_PROTO(struct va_format *vaf),
96 TP_ARGS(vaf)
97);
98
99DEFINE_EVENT(wil6210_log_event, wil6210_log_dbg,
100 TP_PROTO(struct va_format *vaf),
101 TP_ARGS(vaf)
102);
103
104#define wil_pseudo_irq_cause(x) __print_flags(x, "|", \
105 {BIT_DMA_PSEUDO_CAUSE_RX, "Rx" }, \
106 {BIT_DMA_PSEUDO_CAUSE_TX, "Tx" }, \
107 {BIT_DMA_PSEUDO_CAUSE_MISC, "Misc" })
108
109TRACE_EVENT(wil6210_irq_pseudo,
110 TP_PROTO(u32 x),
111 TP_ARGS(x),
112 TP_STRUCT__entry(
113 __field(u32, x)
114 ),
115 TP_fast_assign(
116 __entry->x = x;
117 ),
118 TP_printk("cause 0x%08x : %s", __entry->x,
119 wil_pseudo_irq_cause(__entry->x))
120);
121
122DECLARE_EVENT_CLASS(wil6210_irq,
123 TP_PROTO(u32 x),
124 TP_ARGS(x),
125 TP_STRUCT__entry(
126 __field(u32, x)
127 ),
128 TP_fast_assign(
129 __entry->x = x;
130 ),
131 TP_printk("cause 0x%08x", __entry->x)
132);
133
134DEFINE_EVENT(wil6210_irq, wil6210_irq_rx,
135 TP_PROTO(u32 x),
136 TP_ARGS(x)
137);
138
139DEFINE_EVENT(wil6210_irq, wil6210_irq_tx,
140 TP_PROTO(u32 x),
141 TP_ARGS(x)
142);
143
144DEFINE_EVENT(wil6210_irq, wil6210_irq_misc,
145 TP_PROTO(u32 x),
146 TP_ARGS(x)
147);
148
149DEFINE_EVENT(wil6210_irq, wil6210_irq_misc_thread,
150 TP_PROTO(u32 x),
151 TP_ARGS(x)
152);
153
154TRACE_EVENT(wil6210_rx,
155 TP_PROTO(u16 index, struct vring_rx_desc *d),
156 TP_ARGS(index, d),
157 TP_STRUCT__entry(
158 __field(u16, index)
159 __field(unsigned int, len)
160 __field(u8, mid)
161 __field(u8, cid)
162 __field(u8, tid)
163 __field(u8, type)
164 __field(u8, subtype)
165 __field(u16, seq)
166 __field(u8, mcs)
167 ),
168 TP_fast_assign(
169 __entry->index = index;
170 __entry->len = d->dma.length;
171 __entry->mid = wil_rxdesc_mid(d);
172 __entry->cid = wil_rxdesc_cid(d);
173 __entry->tid = wil_rxdesc_tid(d);
174 __entry->type = wil_rxdesc_ftype(d);
175 __entry->subtype = wil_rxdesc_subtype(d);
176 __entry->seq = wil_rxdesc_seq(d);
177 __entry->mcs = wil_rxdesc_mcs(d);
178 ),
179 TP_printk("index %d len %d mid %d cid %d tid %d mcs %d seq 0x%03x"
180 " type 0x%1x subtype 0x%1x", __entry->index, __entry->len,
181 __entry->mid, __entry->cid, __entry->tid, __entry->mcs,
182 __entry->seq, __entry->type, __entry->subtype)
183);
184
185TRACE_EVENT(wil6210_tx,
186 TP_PROTO(u8 vring, u16 index, unsigned int len, u8 frags),
187 TP_ARGS(vring, index, len, frags),
188 TP_STRUCT__entry(
189 __field(u8, vring)
190 __field(u8, frags)
191 __field(u16, index)
192 __field(unsigned int, len)
193 ),
194 TP_fast_assign(
195 __entry->vring = vring;
196 __entry->frags = frags;
197 __entry->index = index;
198 __entry->len = len;
199 ),
200 TP_printk("vring %d index %d len %d frags %d",
201 __entry->vring, __entry->index, __entry->len, __entry->frags)
202);
203
204TRACE_EVENT(wil6210_tx_done,
205 TP_PROTO(u8 vring, u16 index, unsigned int len, u8 err),
206 TP_ARGS(vring, index, len, err),
207 TP_STRUCT__entry(
208 __field(u8, vring)
209 __field(u8, err)
210 __field(u16, index)
211 __field(unsigned int, len)
212 ),
213 TP_fast_assign(
214 __entry->vring = vring;
215 __entry->index = index;
216 __entry->len = len;
217 __entry->err = err;
218 ),
219 TP_printk("vring %d index %d len %d err 0x%02x",
220 __entry->vring, __entry->index, __entry->len,
221 __entry->err)
222);
223
224#endif /* WIL6210_TRACE_H || TRACE_HEADER_MULTI_READ*/
225
226#if defined(CONFIG_WIL6210_TRACING) && !defined(__CHECKER__)
227/* we don't want to use include/trace/events */
228#undef TRACE_INCLUDE_PATH
229#define TRACE_INCLUDE_PATH .
230#undef TRACE_INCLUDE_FILE
231#define TRACE_INCLUDE_FILE trace
232
233/* This part must be outside protection */
234#include <trace/define_trace.h>
235#endif /* defined(CONFIG_WIL6210_TRACING) && !defined(__CHECKER__) */
diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c
index 797024507c71..00dffeda983e 100644
--- a/drivers/net/wireless/ath/wil6210/txrx.c
+++ b/drivers/net/wireless/ath/wil6210/txrx.c
@@ -22,6 +22,7 @@
22#include "wil6210.h" 22#include "wil6210.h"
23#include "wmi.h" 23#include "wmi.h"
24#include "txrx.h" 24#include "txrx.h"
25#include "trace.h"
25 26
26static bool rtap_include_phy_info; 27static bool rtap_include_phy_info;
27module_param(rtap_include_phy_info, bool, S_IRUGO); 28module_param(rtap_include_phy_info, bool, S_IRUGO);
@@ -89,8 +90,8 @@ static int wil_vring_alloc(struct wil6210_priv *wil, struct vring *vring)
89 * we can use any 90 * we can use any
90 */ 91 */
91 for (i = 0; i < vring->size; i++) { 92 for (i = 0; i < vring->size; i++) {
92 volatile struct vring_tx_desc *d = &(vring->va[i].tx); 93 volatile struct vring_tx_desc *_d = &(vring->va[i].tx);
93 d->dma.status = TX_DMA_STATUS_DU; 94 _d->dma.status = TX_DMA_STATUS_DU;
94 } 95 }
95 96
96 wil_dbg_misc(wil, "vring[%d] 0x%p:0x%016llx 0x%p\n", vring->size, 97 wil_dbg_misc(wil, "vring[%d] 0x%p:0x%016llx 0x%p\n", vring->size,
@@ -106,30 +107,39 @@ static void wil_vring_free(struct wil6210_priv *wil, struct vring *vring,
106 size_t sz = vring->size * sizeof(vring->va[0]); 107 size_t sz = vring->size * sizeof(vring->va[0]);
107 108
108 while (!wil_vring_is_empty(vring)) { 109 while (!wil_vring_is_empty(vring)) {
110 dma_addr_t pa;
111 struct sk_buff *skb;
112 u16 dmalen;
113
109 if (tx) { 114 if (tx) {
110 volatile struct vring_tx_desc *d = 115 struct vring_tx_desc dd, *d = &dd;
116 volatile struct vring_tx_desc *_d =
111 &vring->va[vring->swtail].tx; 117 &vring->va[vring->swtail].tx;
112 dma_addr_t pa = d->dma.addr_low | 118
113 ((u64)d->dma.addr_high << 32); 119 *d = *_d;
114 struct sk_buff *skb = vring->ctx[vring->swtail]; 120 pa = wil_desc_addr(&d->dma.addr);
121 dmalen = le16_to_cpu(d->dma.length);
122 skb = vring->ctx[vring->swtail];
115 if (skb) { 123 if (skb) {
116 dma_unmap_single(dev, pa, d->dma.length, 124 dma_unmap_single(dev, pa, dmalen,
117 DMA_TO_DEVICE); 125 DMA_TO_DEVICE);
118 dev_kfree_skb_any(skb); 126 dev_kfree_skb_any(skb);
119 vring->ctx[vring->swtail] = NULL; 127 vring->ctx[vring->swtail] = NULL;
120 } else { 128 } else {
121 dma_unmap_page(dev, pa, d->dma.length, 129 dma_unmap_page(dev, pa, dmalen,
122 DMA_TO_DEVICE); 130 DMA_TO_DEVICE);
123 } 131 }
124 vring->swtail = wil_vring_next_tail(vring); 132 vring->swtail = wil_vring_next_tail(vring);
125 } else { /* rx */ 133 } else { /* rx */
126 volatile struct vring_rx_desc *d = 134 struct vring_rx_desc dd, *d = &dd;
135 volatile struct vring_rx_desc *_d =
127 &vring->va[vring->swtail].rx; 136 &vring->va[vring->swtail].rx;
128 dma_addr_t pa = d->dma.addr_low | 137
129 ((u64)d->dma.addr_high << 32); 138 *d = *_d;
130 struct sk_buff *skb = vring->ctx[vring->swhead]; 139 pa = wil_desc_addr(&d->dma.addr);
131 dma_unmap_single(dev, pa, d->dma.length, 140 dmalen = le16_to_cpu(d->dma.length);
132 DMA_FROM_DEVICE); 141 skb = vring->ctx[vring->swhead];
142 dma_unmap_single(dev, pa, dmalen, DMA_FROM_DEVICE);
133 kfree_skb(skb); 143 kfree_skb(skb);
134 wil_vring_advance_head(vring, 1); 144 wil_vring_advance_head(vring, 1);
135 } 145 }
@@ -151,7 +161,8 @@ static int wil_vring_alloc_skb(struct wil6210_priv *wil, struct vring *vring,
151{ 161{
152 struct device *dev = wil_to_dev(wil); 162 struct device *dev = wil_to_dev(wil);
153 unsigned int sz = RX_BUF_LEN; 163 unsigned int sz = RX_BUF_LEN;
154 volatile struct vring_rx_desc *d = &(vring->va[i].rx); 164 struct vring_rx_desc dd, *d = &dd;
165 volatile struct vring_rx_desc *_d = &(vring->va[i].rx);
155 dma_addr_t pa; 166 dma_addr_t pa;
156 167
157 /* TODO align */ 168 /* TODO align */
@@ -169,13 +180,13 @@ static int wil_vring_alloc_skb(struct wil6210_priv *wil, struct vring *vring,
169 } 180 }
170 181
171 d->dma.d0 = BIT(9) | RX_DMA_D0_CMD_DMA_IT; 182 d->dma.d0 = BIT(9) | RX_DMA_D0_CMD_DMA_IT;
172 d->dma.addr_low = lower_32_bits(pa); 183 wil_desc_addr_set(&d->dma.addr, pa);
173 d->dma.addr_high = (u16)upper_32_bits(pa);
174 /* ip_length don't care */ 184 /* ip_length don't care */
175 /* b11 don't care */ 185 /* b11 don't care */
176 /* error don't care */ 186 /* error don't care */
177 d->dma.status = 0; /* BIT(0) should be 0 for HW_OWNED */ 187 d->dma.status = 0; /* BIT(0) should be 0 for HW_OWNED */
178 d->dma.length = sz; 188 d->dma.length = cpu_to_le16(sz);
189 *_d = *d;
179 vring->ctx[i] = skb; 190 vring->ctx[i] = skb;
180 191
181 return 0; 192 return 0;
@@ -321,11 +332,12 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil,
321{ 332{
322 struct device *dev = wil_to_dev(wil); 333 struct device *dev = wil_to_dev(wil);
323 struct net_device *ndev = wil_to_ndev(wil); 334 struct net_device *ndev = wil_to_ndev(wil);
324 volatile struct vring_rx_desc *d; 335 volatile struct vring_rx_desc *_d;
325 struct vring_rx_desc *d1; 336 struct vring_rx_desc *d;
326 struct sk_buff *skb; 337 struct sk_buff *skb;
327 dma_addr_t pa; 338 dma_addr_t pa;
328 unsigned int sz = RX_BUF_LEN; 339 unsigned int sz = RX_BUF_LEN;
340 u16 dmalen;
329 u8 ftype; 341 u8 ftype;
330 u8 ds_bits; 342 u8 ds_bits;
331 343
@@ -334,32 +346,44 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil,
334 if (wil_vring_is_empty(vring)) 346 if (wil_vring_is_empty(vring))
335 return NULL; 347 return NULL;
336 348
337 d = &(vring->va[vring->swhead].rx); 349 _d = &(vring->va[vring->swhead].rx);
338 if (!(d->dma.status & RX_DMA_STATUS_DU)) { 350 if (!(_d->dma.status & RX_DMA_STATUS_DU)) {
339 /* it is not error, we just reached end of Rx done area */ 351 /* it is not error, we just reached end of Rx done area */
340 return NULL; 352 return NULL;
341 } 353 }
342 354
343 pa = d->dma.addr_low | ((u64)d->dma.addr_high << 32);
344 skb = vring->ctx[vring->swhead]; 355 skb = vring->ctx[vring->swhead];
356 d = wil_skb_rxdesc(skb);
357 *d = *_d;
358 pa = wil_desc_addr(&d->dma.addr);
359 vring->ctx[vring->swhead] = NULL;
360 wil_vring_advance_head(vring, 1);
361
345 dma_unmap_single(dev, pa, sz, DMA_FROM_DEVICE); 362 dma_unmap_single(dev, pa, sz, DMA_FROM_DEVICE);
346 skb_trim(skb, d->dma.length); 363 dmalen = le16_to_cpu(d->dma.length);
347 364
348 d1 = wil_skb_rxdesc(skb); 365 trace_wil6210_rx(vring->swhead, d);
349 *d1 = *d; 366 wil_dbg_txrx(wil, "Rx[%3d] : %d bytes\n", vring->swhead, dmalen);
367 wil_hex_dump_txrx("Rx ", DUMP_PREFIX_NONE, 32, 4,
368 (const void *)d, sizeof(*d), false);
350 369
351 wil->stats.last_mcs_rx = wil_rxdesc_mcs(d1); 370 if (dmalen > sz) {
371 wil_err(wil, "Rx size too large: %d bytes!\n", dmalen);
372 kfree_skb(skb);
373 return NULL;
374 }
375 skb_trim(skb, dmalen);
376
377 wil_hex_dump_txrx("Rx ", DUMP_PREFIX_OFFSET, 16, 1,
378 skb->data, skb_headlen(skb), false);
379
380
381 wil->stats.last_mcs_rx = wil_rxdesc_mcs(d);
352 382
353 /* use radiotap header only if required */ 383 /* use radiotap header only if required */
354 if (ndev->type == ARPHRD_IEEE80211_RADIOTAP) 384 if (ndev->type == ARPHRD_IEEE80211_RADIOTAP)
355 wil_rx_add_radiotap_header(wil, skb); 385 wil_rx_add_radiotap_header(wil, skb);
356 386
357 wil_dbg_txrx(wil, "Rx[%3d] : %d bytes\n", vring->swhead, d->dma.length);
358 wil_hex_dump_txrx("Rx ", DUMP_PREFIX_NONE, 32, 4,
359 (const void *)d, sizeof(*d), false);
360
361 wil_vring_advance_head(vring, 1);
362
363 /* no extra checks if in sniffer mode */ 387 /* no extra checks if in sniffer mode */
364 if (ndev->type != ARPHRD_ETHER) 388 if (ndev->type != ARPHRD_ETHER)
365 return skb; 389 return skb;
@@ -368,7 +392,7 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil,
368 * Driver should recognize it by frame type, that is found 392 * Driver should recognize it by frame type, that is found
369 * in Rx descriptor. If type is not data, it is 802.11 frame as is 393 * in Rx descriptor. If type is not data, it is 802.11 frame as is
370 */ 394 */
371 ftype = wil_rxdesc_ftype(d1) << 2; 395 ftype = wil_rxdesc_ftype(d) << 2;
372 if (ftype != IEEE80211_FTYPE_DATA) { 396 if (ftype != IEEE80211_FTYPE_DATA) {
373 wil_dbg_txrx(wil, "Non-data frame ftype 0x%08x\n", ftype); 397 wil_dbg_txrx(wil, "Non-data frame ftype 0x%08x\n", ftype);
374 /* TODO: process it */ 398 /* TODO: process it */
@@ -383,7 +407,7 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil,
383 return NULL; 407 return NULL;
384 } 408 }
385 409
386 ds_bits = wil_rxdesc_ds_bits(d1); 410 ds_bits = wil_rxdesc_ds_bits(d);
387 if (ds_bits == 1) { 411 if (ds_bits == 1) {
388 /* 412 /*
389 * HW bug - in ToDS mode, i.e. Rx on AP side, 413 * HW bug - in ToDS mode, i.e. Rx on AP side,
@@ -425,6 +449,7 @@ static int wil_rx_refill(struct wil6210_priv *wil, int count)
425 449
426/* 450/*
427 * Pass Rx packet to the netif. Update statistics. 451 * Pass Rx packet to the netif. Update statistics.
452 * Called in softirq context (NAPI poll).
428 */ 453 */
429static void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev) 454static void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev)
430{ 455{
@@ -433,10 +458,7 @@ static void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev)
433 458
434 skb_orphan(skb); 459 skb_orphan(skb);
435 460
436 if (in_interrupt()) 461 rc = netif_receive_skb(skb);
437 rc = netif_rx(skb);
438 else
439 rc = netif_rx_ni(skb);
440 462
441 if (likely(rc == NET_RX_SUCCESS)) { 463 if (likely(rc == NET_RX_SUCCESS)) {
442 ndev->stats.rx_packets++; 464 ndev->stats.rx_packets++;
@@ -450,9 +472,9 @@ static void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev)
450/** 472/**
451 * Proceed all completed skb's from Rx VRING 473 * Proceed all completed skb's from Rx VRING
452 * 474 *
453 * Safe to call from IRQ 475 * Safe to call from NAPI poll, i.e. softirq with interrupts enabled
454 */ 476 */
455void wil_rx_handle(struct wil6210_priv *wil) 477void wil_rx_handle(struct wil6210_priv *wil, int *quota)
456{ 478{
457 struct net_device *ndev = wil_to_ndev(wil); 479 struct net_device *ndev = wil_to_ndev(wil);
458 struct vring *v = &wil->vring_rx; 480 struct vring *v = &wil->vring_rx;
@@ -463,9 +485,8 @@ void wil_rx_handle(struct wil6210_priv *wil)
463 return; 485 return;
464 } 486 }
465 wil_dbg_txrx(wil, "%s()\n", __func__); 487 wil_dbg_txrx(wil, "%s()\n", __func__);
466 while (NULL != (skb = wil_vring_reap_rx(wil, v))) { 488 while ((*quota > 0) && (NULL != (skb = wil_vring_reap_rx(wil, v)))) {
467 wil_hex_dump_txrx("Rx ", DUMP_PREFIX_OFFSET, 16, 1, 489 (*quota)--;
468 skb->data, skb_headlen(skb), false);
469 490
470 if (wil->wdev->iftype == NL80211_IFTYPE_MONITOR) { 491 if (wil->wdev->iftype == NL80211_IFTYPE_MONITOR) {
471 skb->dev = ndev; 492 skb->dev = ndev;
@@ -600,17 +621,15 @@ static struct vring *wil_find_tx_vring(struct wil6210_priv *wil,
600 return NULL; 621 return NULL;
601} 622}
602 623
603static int wil_tx_desc_map(volatile struct vring_tx_desc *d, 624static int wil_tx_desc_map(struct vring_tx_desc *d, dma_addr_t pa, u32 len)
604 dma_addr_t pa, u32 len)
605{ 625{
606 d->dma.addr_low = lower_32_bits(pa); 626 wil_desc_addr_set(&d->dma.addr, pa);
607 d->dma.addr_high = (u16)upper_32_bits(pa);
608 d->dma.ip_length = 0; 627 d->dma.ip_length = 0;
609 /* 0..6: mac_length; 7:ip_version 0-IP6 1-IP4*/ 628 /* 0..6: mac_length; 7:ip_version 0-IP6 1-IP4*/
610 d->dma.b11 = 0/*14 | BIT(7)*/; 629 d->dma.b11 = 0/*14 | BIT(7)*/;
611 d->dma.error = 0; 630 d->dma.error = 0;
612 d->dma.status = 0; /* BIT(0) should be 0 for HW_OWNED */ 631 d->dma.status = 0; /* BIT(0) should be 0 for HW_OWNED */
613 d->dma.length = len; 632 d->dma.length = cpu_to_le16((u16)len);
614 d->dma.d0 = 0; 633 d->dma.d0 = 0;
615 d->mac.d[0] = 0; 634 d->mac.d[0] = 0;
616 d->mac.d[1] = 0; 635 d->mac.d[1] = 0;
@@ -630,7 +649,8 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
630 struct sk_buff *skb) 649 struct sk_buff *skb)
631{ 650{
632 struct device *dev = wil_to_dev(wil); 651 struct device *dev = wil_to_dev(wil);
633 volatile struct vring_tx_desc *d; 652 struct vring_tx_desc dd, *d = &dd;
653 volatile struct vring_tx_desc *_d;
634 u32 swhead = vring->swhead; 654 u32 swhead = vring->swhead;
635 int avail = wil_vring_avail_tx(vring); 655 int avail = wil_vring_avail_tx(vring);
636 int nr_frags = skb_shinfo(skb)->nr_frags; 656 int nr_frags = skb_shinfo(skb)->nr_frags;
@@ -648,7 +668,7 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
648 1 + nr_frags); 668 1 + nr_frags);
649 return -ENOMEM; 669 return -ENOMEM;
650 } 670 }
651 d = &(vring->va[i].tx); 671 _d = &(vring->va[i].tx);
652 672
653 /* FIXME FW can accept only unicast frames for the peer */ 673 /* FIXME FW can accept only unicast frames for the peer */
654 memcpy(skb->data, wil->dst_addr[vring_index], ETH_ALEN); 674 memcpy(skb->data, wil->dst_addr[vring_index], ETH_ALEN);
@@ -667,25 +687,30 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
667 wil_tx_desc_map(d, pa, skb_headlen(skb)); 687 wil_tx_desc_map(d, pa, skb_headlen(skb));
668 d->mac.d[2] |= ((nr_frags + 1) << 688 d->mac.d[2] |= ((nr_frags + 1) <<
669 MAC_CFG_DESC_TX_2_NUM_OF_DESCRIPTORS_POS); 689 MAC_CFG_DESC_TX_2_NUM_OF_DESCRIPTORS_POS);
690 if (nr_frags)
691 *_d = *d;
692
670 /* middle segments */ 693 /* middle segments */
671 for (f = 0; f < nr_frags; f++) { 694 for (f = 0; f < nr_frags; f++) {
672 const struct skb_frag_struct *frag = 695 const struct skb_frag_struct *frag =
673 &skb_shinfo(skb)->frags[f]; 696 &skb_shinfo(skb)->frags[f];
674 int len = skb_frag_size(frag); 697 int len = skb_frag_size(frag);
675 i = (swhead + f + 1) % vring->size; 698 i = (swhead + f + 1) % vring->size;
676 d = &(vring->va[i].tx); 699 _d = &(vring->va[i].tx);
677 pa = skb_frag_dma_map(dev, frag, 0, skb_frag_size(frag), 700 pa = skb_frag_dma_map(dev, frag, 0, skb_frag_size(frag),
678 DMA_TO_DEVICE); 701 DMA_TO_DEVICE);
679 if (unlikely(dma_mapping_error(dev, pa))) 702 if (unlikely(dma_mapping_error(dev, pa)))
680 goto dma_error; 703 goto dma_error;
681 wil_tx_desc_map(d, pa, len); 704 wil_tx_desc_map(d, pa, len);
682 vring->ctx[i] = NULL; 705 vring->ctx[i] = NULL;
706 *_d = *d;
683 } 707 }
684 /* for the last seg only */ 708 /* for the last seg only */
685 d->dma.d0 |= BIT(DMA_CFG_DESC_TX_0_CMD_EOP_POS); 709 d->dma.d0 |= BIT(DMA_CFG_DESC_TX_0_CMD_EOP_POS);
686 d->dma.d0 |= BIT(9); /* BUG: undocumented bit */ 710 d->dma.d0 |= BIT(9); /* BUG: undocumented bit */
687 d->dma.d0 |= BIT(DMA_CFG_DESC_TX_0_CMD_DMA_IT_POS); 711 d->dma.d0 |= BIT(DMA_CFG_DESC_TX_0_CMD_DMA_IT_POS);
688 d->dma.d0 |= (vring_index << DMA_CFG_DESC_TX_0_QID_POS); 712 d->dma.d0 |= (vring_index << DMA_CFG_DESC_TX_0_QID_POS);
713 *_d = *d;
689 714
690 wil_hex_dump_txrx("Tx ", DUMP_PREFIX_NONE, 32, 4, 715 wil_hex_dump_txrx("Tx ", DUMP_PREFIX_NONE, 32, 4,
691 (const void *)d, sizeof(*d), false); 716 (const void *)d, sizeof(*d), false);
@@ -693,6 +718,7 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
693 /* advance swhead */ 718 /* advance swhead */
694 wil_vring_advance_head(vring, nr_frags + 1); 719 wil_vring_advance_head(vring, nr_frags + 1);
695 wil_dbg_txrx(wil, "Tx swhead %d -> %d\n", swhead, vring->swhead); 720 wil_dbg_txrx(wil, "Tx swhead %d -> %d\n", swhead, vring->swhead);
721 trace_wil6210_tx(vring_index, swhead, skb->len, nr_frags);
696 iowrite32(vring->swhead, wil->csr + HOSTADDR(vring->hwtail)); 722 iowrite32(vring->swhead, wil->csr + HOSTADDR(vring->hwtail));
697 /* hold reference to skb 723 /* hold reference to skb
698 * to prevent skb release before accounting 724 * to prevent skb release before accounting
@@ -705,14 +731,18 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
705 /* unmap what we have mapped */ 731 /* unmap what we have mapped */
706 /* Note: increment @f to operate with positive index */ 732 /* Note: increment @f to operate with positive index */
707 for (f++; f > 0; f--) { 733 for (f++; f > 0; f--) {
734 u16 dmalen;
735
708 i = (swhead + f) % vring->size; 736 i = (swhead + f) % vring->size;
709 d = &(vring->va[i].tx); 737 _d = &(vring->va[i].tx);
710 d->dma.status = TX_DMA_STATUS_DU; 738 *d = *_d;
711 pa = d->dma.addr_low | ((u64)d->dma.addr_high << 32); 739 _d->dma.status = TX_DMA_STATUS_DU;
740 pa = wil_desc_addr(&d->dma.addr);
741 dmalen = le16_to_cpu(d->dma.length);
712 if (vring->ctx[i]) 742 if (vring->ctx[i])
713 dma_unmap_single(dev, pa, d->dma.length, DMA_TO_DEVICE); 743 dma_unmap_single(dev, pa, dmalen, DMA_TO_DEVICE);
714 else 744 else
715 dma_unmap_page(dev, pa, d->dma.length, DMA_TO_DEVICE); 745 dma_unmap_page(dev, pa, dmalen, DMA_TO_DEVICE);
716 } 746 }
717 747
718 return -EINVAL; 748 return -EINVAL;
@@ -761,7 +791,6 @@ netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev)
761 break; /* goto drop; */ 791 break; /* goto drop; */
762 } 792 }
763 drop: 793 drop:
764 netif_tx_stop_all_queues(ndev);
765 ndev->stats.tx_dropped++; 794 ndev->stats.tx_dropped++;
766 dev_kfree_skb_any(skb); 795 dev_kfree_skb_any(skb);
767 796
@@ -771,41 +800,48 @@ netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev)
771/** 800/**
772 * Clean up transmitted skb's from the Tx VRING 801 * Clean up transmitted skb's from the Tx VRING
773 * 802 *
803 * Return number of descriptors cleared
804 *
774 * Safe to call from IRQ 805 * Safe to call from IRQ
775 */ 806 */
776void wil_tx_complete(struct wil6210_priv *wil, int ringid) 807int wil_tx_complete(struct wil6210_priv *wil, int ringid)
777{ 808{
778 struct net_device *ndev = wil_to_ndev(wil); 809 struct net_device *ndev = wil_to_ndev(wil);
779 struct device *dev = wil_to_dev(wil); 810 struct device *dev = wil_to_dev(wil);
780 struct vring *vring = &wil->vring_tx[ringid]; 811 struct vring *vring = &wil->vring_tx[ringid];
812 int done = 0;
781 813
782 if (!vring->va) { 814 if (!vring->va) {
783 wil_err(wil, "Tx irq[%d]: vring not initialized\n", ringid); 815 wil_err(wil, "Tx irq[%d]: vring not initialized\n", ringid);
784 return; 816 return 0;
785 } 817 }
786 818
787 wil_dbg_txrx(wil, "%s(%d)\n", __func__, ringid); 819 wil_dbg_txrx(wil, "%s(%d)\n", __func__, ringid);
788 820
789 while (!wil_vring_is_empty(vring)) { 821 while (!wil_vring_is_empty(vring)) {
790 volatile struct vring_tx_desc *d1 = 822 volatile struct vring_tx_desc *_d =
791 &vring->va[vring->swtail].tx; 823 &vring->va[vring->swtail].tx;
792 struct vring_tx_desc dd, *d = &dd; 824 struct vring_tx_desc dd, *d = &dd;
793 dma_addr_t pa; 825 dma_addr_t pa;
794 struct sk_buff *skb; 826 struct sk_buff *skb;
827 u16 dmalen;
795 828
796 dd = *d1; 829 *d = *_d;
797 830
798 if (!(d->dma.status & TX_DMA_STATUS_DU)) 831 if (!(d->dma.status & TX_DMA_STATUS_DU))
799 break; 832 break;
800 833
834 dmalen = le16_to_cpu(d->dma.length);
835 trace_wil6210_tx_done(ringid, vring->swtail, dmalen,
836 d->dma.error);
801 wil_dbg_txrx(wil, 837 wil_dbg_txrx(wil,
802 "Tx[%3d] : %d bytes, status 0x%02x err 0x%02x\n", 838 "Tx[%3d] : %d bytes, status 0x%02x err 0x%02x\n",
803 vring->swtail, d->dma.length, d->dma.status, 839 vring->swtail, dmalen, d->dma.status,
804 d->dma.error); 840 d->dma.error);
805 wil_hex_dump_txrx("TxC ", DUMP_PREFIX_NONE, 32, 4, 841 wil_hex_dump_txrx("TxC ", DUMP_PREFIX_NONE, 32, 4,
806 (const void *)d, sizeof(*d), false); 842 (const void *)d, sizeof(*d), false);
807 843
808 pa = d->dma.addr_low | ((u64)d->dma.addr_high << 32); 844 pa = wil_desc_addr(&d->dma.addr);
809 skb = vring->ctx[vring->swtail]; 845 skb = vring->ctx[vring->swtail];
810 if (skb) { 846 if (skb) {
811 if (d->dma.error == 0) { 847 if (d->dma.error == 0) {
@@ -815,18 +851,21 @@ void wil_tx_complete(struct wil6210_priv *wil, int ringid)
815 ndev->stats.tx_errors++; 851 ndev->stats.tx_errors++;
816 } 852 }
817 853
818 dma_unmap_single(dev, pa, d->dma.length, DMA_TO_DEVICE); 854 dma_unmap_single(dev, pa, dmalen, DMA_TO_DEVICE);
819 dev_kfree_skb_any(skb); 855 dev_kfree_skb_any(skb);
820 vring->ctx[vring->swtail] = NULL; 856 vring->ctx[vring->swtail] = NULL;
821 } else { 857 } else {
822 dma_unmap_page(dev, pa, d->dma.length, DMA_TO_DEVICE); 858 dma_unmap_page(dev, pa, dmalen, DMA_TO_DEVICE);
823 } 859 }
824 d->dma.addr_low = 0; 860 d->dma.addr.addr_low = 0;
825 d->dma.addr_high = 0; 861 d->dma.addr.addr_high = 0;
826 d->dma.length = 0; 862 d->dma.length = 0;
827 d->dma.status = TX_DMA_STATUS_DU; 863 d->dma.status = TX_DMA_STATUS_DU;
828 vring->swtail = wil_vring_next_tail(vring); 864 vring->swtail = wil_vring_next_tail(vring);
865 done++;
829 } 866 }
830 if (wil_vring_avail_tx(vring) > vring->size/4) 867 if (wil_vring_avail_tx(vring) > vring->size/4)
831 netif_tx_wake_all_queues(wil_to_ndev(wil)); 868 netif_tx_wake_all_queues(wil_to_ndev(wil));
869
870 return done;
832} 871}
diff --git a/drivers/net/wireless/ath/wil6210/txrx.h b/drivers/net/wireless/ath/wil6210/txrx.h
index adef12fb2aee..23c0781cdb93 100644
--- a/drivers/net/wireless/ath/wil6210/txrx.h
+++ b/drivers/net/wireless/ath/wil6210/txrx.h
@@ -27,6 +27,28 @@
27#define WIL6210_RTAP_SIZE (128) 27#define WIL6210_RTAP_SIZE (128)
28 28
29/* Tx/Rx path */ 29/* Tx/Rx path */
30
31/*
32 * Common representation of physical address in Vring
33 */
34struct vring_dma_addr {
35 __le32 addr_low;
36 __le16 addr_high;
37} __packed;
38
39static inline dma_addr_t wil_desc_addr(struct vring_dma_addr *addr)
40{
41 return le32_to_cpu(addr->addr_low) |
42 ((u64)le16_to_cpu(addr->addr_high) << 32);
43}
44
45static inline void wil_desc_addr_set(struct vring_dma_addr *addr,
46 dma_addr_t pa)
47{
48 addr->addr_low = cpu_to_le32(lower_32_bits(pa));
49 addr->addr_high = cpu_to_le16((u16)upper_32_bits(pa));
50}
51
30/* 52/*
31 * Tx descriptor - MAC part 53 * Tx descriptor - MAC part
32 * [dword 0] 54 * [dword 0]
@@ -216,13 +238,12 @@ struct vring_tx_mac {
216 238
217struct vring_tx_dma { 239struct vring_tx_dma {
218 u32 d0; 240 u32 d0;
219 u32 addr_low; 241 struct vring_dma_addr addr;
220 u16 addr_high;
221 u8 ip_length; 242 u8 ip_length;
222 u8 b11; /* 0..6: mac_length; 7:ip_version */ 243 u8 b11; /* 0..6: mac_length; 7:ip_version */
223 u8 error; /* 0..2: err; 3..7: reserved; */ 244 u8 error; /* 0..2: err; 3..7: reserved; */
224 u8 status; /* 0: used; 1..7; reserved */ 245 u8 status; /* 0: used; 1..7; reserved */
225 u16 length; 246 __le16 length;
226} __packed; 247} __packed;
227 248
228/* 249/*
@@ -315,13 +336,12 @@ struct vring_rx_mac {
315 336
316struct vring_rx_dma { 337struct vring_rx_dma {
317 u32 d0; 338 u32 d0;
318 u32 addr_low; 339 struct vring_dma_addr addr;
319 u16 addr_high;
320 u8 ip_length; 340 u8 ip_length;
321 u8 b11; 341 u8 b11;
322 u8 error; 342 u8 error;
323 u8 status; 343 u8 status;
324 u16 length; 344 __le16 length;
325} __packed; 345} __packed;
326 346
327struct vring_tx_desc { 347struct vring_tx_desc {
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h
index 8f76ecd8a7e5..373cf656f5b0 100644
--- a/drivers/net/wireless/ath/wil6210/wil6210.h
+++ b/drivers/net/wireless/ath/wil6210/wil6210.h
@@ -34,9 +34,11 @@ static inline u32 WIL_GET_BITS(u32 x, int b0, int b1)
34 34
35#define WIL6210_MEM_SIZE (2*1024*1024UL) 35#define WIL6210_MEM_SIZE (2*1024*1024UL)
36 36
37#define WIL6210_RX_RING_SIZE (128) 37#define WIL6210_RX_RING_SIZE (128)
38#define WIL6210_TX_RING_SIZE (128) 38#define WIL6210_TX_RING_SIZE (128)
39#define WIL6210_MAX_TX_RINGS (24) 39#define WIL6210_MAX_TX_RINGS (24) /* HW limit */
40#define WIL6210_MAX_CID (8) /* HW limit */
41#define WIL6210_NAPI_BUDGET (16) /* arbitrary */
40 42
41/* Hardware definitions begin */ 43/* Hardware definitions begin */
42 44
@@ -184,6 +186,7 @@ struct vring {
184 186
185enum { /* for wil6210_priv.status */ 187enum { /* for wil6210_priv.status */
186 wil_status_fwready = 0, 188 wil_status_fwready = 0,
189 wil_status_fwconnecting,
187 wil_status_fwconnected, 190 wil_status_fwconnected,
188 wil_status_dontscan, 191 wil_status_dontscan,
189 wil_status_reset_done, 192 wil_status_reset_done,
@@ -239,6 +242,8 @@ struct wil6210_priv {
239 * - consumed in thread by wmi_event_worker 242 * - consumed in thread by wmi_event_worker
240 */ 243 */
241 spinlock_t wmi_ev_lock; 244 spinlock_t wmi_ev_lock;
245 struct napi_struct napi_rx;
246 struct napi_struct napi_tx;
242 /* DMA related */ 247 /* DMA related */
243 struct vring vring_rx; 248 struct vring vring_rx;
244 struct vring vring_tx[WIL6210_MAX_TX_RINGS]; 249 struct vring vring_tx[WIL6210_MAX_TX_RINGS];
@@ -267,9 +272,13 @@ struct wil6210_priv {
267#define wil_to_ndev(i) (wil_to_wdev(i)->netdev) 272#define wil_to_ndev(i) (wil_to_wdev(i)->netdev)
268#define ndev_to_wil(n) (wdev_to_wil(n->ieee80211_ptr)) 273#define ndev_to_wil(n) (wdev_to_wil(n->ieee80211_ptr))
269 274
270#define wil_dbg(wil, fmt, arg...) netdev_dbg(wil_to_ndev(wil), fmt, ##arg) 275int wil_dbg_trace(struct wil6210_priv *wil, const char *fmt, ...);
271#define wil_info(wil, fmt, arg...) netdev_info(wil_to_ndev(wil), fmt, ##arg) 276int wil_err(struct wil6210_priv *wil, const char *fmt, ...);
272#define wil_err(wil, fmt, arg...) netdev_err(wil_to_ndev(wil), fmt, ##arg) 277int wil_info(struct wil6210_priv *wil, const char *fmt, ...);
278#define wil_dbg(wil, fmt, arg...) do { \
279 netdev_dbg(wil_to_ndev(wil), fmt, ##arg); \
280 wil_dbg_trace(wil, fmt, ##arg); \
281} while (0)
273 282
274#define wil_dbg_irq(wil, fmt, arg...) wil_dbg(wil, "DBG[ IRQ]" fmt, ##arg) 283#define wil_dbg_irq(wil, fmt, arg...) wil_dbg(wil, "DBG[ IRQ]" fmt, ##arg)
275#define wil_dbg_txrx(wil, fmt, arg...) wil_dbg(wil, "DBG[TXRX]" fmt, ##arg) 284#define wil_dbg_txrx(wil, fmt, arg...) wil_dbg(wil, "DBG[TXRX]" fmt, ##arg)
@@ -356,10 +365,12 @@ int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size,
356void wil_vring_fini_tx(struct wil6210_priv *wil, int id); 365void wil_vring_fini_tx(struct wil6210_priv *wil, int id);
357 366
358netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev); 367netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev);
359void wil_tx_complete(struct wil6210_priv *wil, int ringid); 368int wil_tx_complete(struct wil6210_priv *wil, int ringid);
369void wil6210_unmask_irq_tx(struct wil6210_priv *wil);
360 370
361/* RX API */ 371/* RX API */
362void wil_rx_handle(struct wil6210_priv *wil); 372void wil_rx_handle(struct wil6210_priv *wil, int *quota);
373void wil6210_unmask_irq_rx(struct wil6210_priv *wil);
363 374
364int wil_iftype_nl2wmi(enum nl80211_iftype type); 375int wil_iftype_nl2wmi(enum nl80211_iftype type);
365 376
diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c
index 45b04e383f9a..527ffb543821 100644
--- a/drivers/net/wireless/ath/wil6210/wmi.c
+++ b/drivers/net/wireless/ath/wil6210/wmi.c
@@ -20,6 +20,7 @@
20#include "wil6210.h" 20#include "wil6210.h"
21#include "txrx.h" 21#include "txrx.h"
22#include "wmi.h" 22#include "wmi.h"
23#include "trace.h"
23 24
24/** 25/**
25 * WMI event receiving - theory of operations 26 * WMI event receiving - theory of operations
@@ -246,6 +247,8 @@ static int __wmi_send(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len)
246 iowrite32(r->head = next_head, wil->csr + HOST_MBOX + 247 iowrite32(r->head = next_head, wil->csr + HOST_MBOX +
247 offsetof(struct wil6210_mbox_ctl, tx.head)); 248 offsetof(struct wil6210_mbox_ctl, tx.head));
248 249
250 trace_wil6210_wmi_cmd(cmdid, buf, len);
251
249 /* interrupt to FW */ 252 /* interrupt to FW */
250 iowrite32(SW_INT_MBOX, wil->csr + HOST_SW_INT); 253 iowrite32(SW_INT_MBOX, wil->csr + HOST_SW_INT);
251 254
@@ -406,7 +409,7 @@ static void wmi_evt_connect(struct wil6210_priv *wil, int id, void *d, int len)
406 409
407 if ((wdev->iftype == NL80211_IFTYPE_STATION) || 410 if ((wdev->iftype == NL80211_IFTYPE_STATION) ||
408 (wdev->iftype == NL80211_IFTYPE_P2P_CLIENT)) { 411 (wdev->iftype == NL80211_IFTYPE_P2P_CLIENT)) {
409 if (wdev->sme_state != CFG80211_SME_CONNECTING) { 412 if (!test_bit(wil_status_fwconnecting, &wil->status)) {
410 wil_err(wil, "Not in connecting state\n"); 413 wil_err(wil, "Not in connecting state\n");
411 return; 414 return;
412 } 415 }
@@ -430,6 +433,7 @@ static void wmi_evt_connect(struct wil6210_priv *wil, int id, void *d, int len)
430 433
431 cfg80211_new_sta(ndev, evt->bssid, &sinfo, GFP_KERNEL); 434 cfg80211_new_sta(ndev, evt->bssid, &sinfo, GFP_KERNEL);
432 } 435 }
436 clear_bit(wil_status_fwconnecting, &wil->status);
433 set_bit(wil_status_fwconnected, &wil->status); 437 set_bit(wil_status_fwconnected, &wil->status);
434 438
435 /* FIXME FW can transmit only ucast frames to peer */ 439 /* FIXME FW can transmit only ucast frames to peer */
@@ -635,8 +639,9 @@ void wmi_recv_cmd(struct wil6210_priv *wil)
635 hdr.flags); 639 hdr.flags);
636 if ((hdr.type == WIL_MBOX_HDR_TYPE_WMI) && 640 if ((hdr.type == WIL_MBOX_HDR_TYPE_WMI) &&
637 (len >= sizeof(struct wil6210_mbox_hdr_wmi))) { 641 (len >= sizeof(struct wil6210_mbox_hdr_wmi))) {
638 wil_dbg_wmi(wil, "WMI event 0x%04x\n", 642 u16 id = le16_to_cpu(evt->event.wmi.id);
639 evt->event.wmi.id); 643 wil_dbg_wmi(wil, "WMI event 0x%04x\n", id);
644 trace_wil6210_wmi_event(id, &evt->event.wmi, len);
640 } 645 }
641 wil_hex_dump_wmi("evt ", DUMP_PREFIX_OFFSET, 16, 1, 646 wil_hex_dump_wmi("evt ", DUMP_PREFIX_OFFSET, 16, 1,
642 &evt->event.hdr, sizeof(hdr) + len, true); 647 &evt->event.hdr, sizeof(hdr) + len, true);
@@ -724,7 +729,7 @@ int wmi_pcp_start(struct wil6210_priv *wil, int bi, u8 wmi_nettype, u8 chan)
724 .bcon_interval = cpu_to_le16(bi), 729 .bcon_interval = cpu_to_le16(bi),
725 .network_type = wmi_nettype, 730 .network_type = wmi_nettype,
726 .disable_sec_offload = 1, 731 .disable_sec_offload = 1,
727 .channel = chan, 732 .channel = chan - 1,
728 }; 733 };
729 struct { 734 struct {
730 struct wil6210_mbox_hdr_wmi wmi; 735 struct wil6210_mbox_hdr_wmi wmi;
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
index 44fa0cdbf97b..11400b39cf0b 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
@@ -606,7 +606,8 @@ static int brcmf_sdio_pd_remove(struct platform_device *pdev)
606static struct platform_driver brcmf_sdio_pd = { 606static struct platform_driver brcmf_sdio_pd = {
607 .remove = brcmf_sdio_pd_remove, 607 .remove = brcmf_sdio_pd_remove,
608 .driver = { 608 .driver = {
609 .name = BRCMFMAC_SDIO_PDATA_NAME 609 .name = BRCMFMAC_SDIO_PDATA_NAME,
610 .owner = THIS_MODULE,
610 } 611 }
611}; 612};
612 613
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
index 1585cc5bf866..bd982856d385 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
@@ -900,7 +900,7 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb,
900 if (supr_status) { 900 if (supr_status) {
901 update_rate = false; 901 update_rate = false;
902 if (supr_status == TX_STATUS_SUPR_BADCH) { 902 if (supr_status == TX_STATUS_SUPR_BADCH) {
903 brcms_err(wlc->hw->d11core, 903 brcms_dbg_ht(wlc->hw->d11core,
904 "%s: Pkt tx suppressed, illegal channel possibly %d\n", 904 "%s: Pkt tx suppressed, illegal channel possibly %d\n",
905 __func__, CHSPEC_CHANNEL( 905 __func__, CHSPEC_CHANNEL(
906 wlc->default_bss->chanspec)); 906 wlc->default_bss->chanspec));
diff --git a/drivers/net/wireless/cw1200/Kconfig b/drivers/net/wireless/cw1200/Kconfig
new file mode 100644
index 000000000000..0880742eab17
--- /dev/null
+++ b/drivers/net/wireless/cw1200/Kconfig
@@ -0,0 +1,30 @@
1config CW1200
2 tristate "CW1200 WLAN support"
3 depends on MAC80211 && CFG80211
4 help
5 This is a driver for the ST-E CW1100 & CW1200 WLAN chipsets.
6 This option just enables the driver core, see below for
7 specific bus support.
8
9if CW1200
10
11config CW1200_WLAN_SDIO
12 tristate "Support SDIO platforms"
13 depends on CW1200 && MMC
14 help
15 Enable support for the CW1200 connected via an SDIO bus.
16 By default this driver only supports the Sagrad SG901-1091/1098 EVK
17 and similar designs that utilize a hardware reset circuit. To
18 support different CW1200 SDIO designs you will need to override
19 the default platform data by calling cw1200_sdio_set_platform_data()
20 in your board setup file.
21
22config CW1200_WLAN_SPI
23 tristate "Support SPI platforms"
24 depends on CW1200 && SPI
25 help
26 Enables support for the CW1200 connected via a SPI bus. You will
27 need to add appropriate platform data glue in your board setup
28 file.
29
30endif
diff --git a/drivers/net/wireless/cw1200/Makefile b/drivers/net/wireless/cw1200/Makefile
new file mode 100644
index 000000000000..b086aac6547a
--- /dev/null
+++ b/drivers/net/wireless/cw1200/Makefile
@@ -0,0 +1,21 @@
1cw1200_core-y := \
2 fwio.o \
3 txrx.o \
4 main.o \
5 queue.o \
6 hwio.o \
7 bh.o \
8 wsm.o \
9 sta.o \
10 scan.o \
11 debug.o
12cw1200_core-$(CONFIG_PM) += pm.o
13
14# CFLAGS_sta.o += -DDEBUG
15
16cw1200_wlan_sdio-y := cw1200_sdio.o
17cw1200_wlan_spi-y := cw1200_spi.o
18
19obj-$(CONFIG_CW1200) += cw1200_core.o
20obj-$(CONFIG_CW1200_WLAN_SDIO) += cw1200_wlan_sdio.o
21obj-$(CONFIG_CW1200_WLAN_SPI) += cw1200_wlan_spi.o
diff --git a/drivers/net/wireless/cw1200/bh.c b/drivers/net/wireless/cw1200/bh.c
new file mode 100644
index 000000000000..c1ec2a4dd8c0
--- /dev/null
+++ b/drivers/net/wireless/cw1200/bh.c
@@ -0,0 +1,619 @@
1/*
2 * Device handling thread implementation for mac80211 ST-Ericsson CW1200 drivers
3 *
4 * Copyright (c) 2010, ST-Ericsson
5 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6 *
7 * Based on:
8 * ST-Ericsson UMAC CW1200 driver, which is
9 * Copyright (c) 2010, ST-Ericsson
10 * Author: Ajitpal Singh <ajitpal.singh@stericsson.com>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 */
16
17#include <linux/module.h>
18#include <net/mac80211.h>
19#include <linux/kthread.h>
20#include <linux/timer.h>
21
22#include "cw1200.h"
23#include "bh.h"
24#include "hwio.h"
25#include "wsm.h"
26#include "hwbus.h"
27#include "debug.h"
28#include "fwio.h"
29
30static int cw1200_bh(void *arg);
31
32#define DOWNLOAD_BLOCK_SIZE_WR (0x1000 - 4)
33/* an SPI message cannot be bigger than (2"12-1)*2 bytes
34 * "*2" to cvt to bytes
35 */
36#define MAX_SZ_RD_WR_BUFFERS (DOWNLOAD_BLOCK_SIZE_WR*2)
37#define PIGGYBACK_CTRL_REG (2)
38#define EFFECTIVE_BUF_SIZE (MAX_SZ_RD_WR_BUFFERS - PIGGYBACK_CTRL_REG)
39
40/* Suspend state privates */
41enum cw1200_bh_pm_state {
42 CW1200_BH_RESUMED = 0,
43 CW1200_BH_SUSPEND,
44 CW1200_BH_SUSPENDED,
45 CW1200_BH_RESUME,
46};
47
48typedef int (*cw1200_wsm_handler)(struct cw1200_common *priv,
49 u8 *data, size_t size);
50
51static void cw1200_bh_work(struct work_struct *work)
52{
53 struct cw1200_common *priv =
54 container_of(work, struct cw1200_common, bh_work);
55 cw1200_bh(priv);
56}
57
58int cw1200_register_bh(struct cw1200_common *priv)
59{
60 int err = 0;
61 /* Realtime workqueue */
62 priv->bh_workqueue = alloc_workqueue("cw1200_bh",
63 WQ_MEM_RECLAIM | WQ_HIGHPRI
64 | WQ_CPU_INTENSIVE, 1);
65
66 if (!priv->bh_workqueue)
67 return -ENOMEM;
68
69 INIT_WORK(&priv->bh_work, cw1200_bh_work);
70
71 pr_debug("[BH] register.\n");
72
73 atomic_set(&priv->bh_rx, 0);
74 atomic_set(&priv->bh_tx, 0);
75 atomic_set(&priv->bh_term, 0);
76 atomic_set(&priv->bh_suspend, CW1200_BH_RESUMED);
77 priv->bh_error = 0;
78 priv->hw_bufs_used = 0;
79 priv->buf_id_tx = 0;
80 priv->buf_id_rx = 0;
81 init_waitqueue_head(&priv->bh_wq);
82 init_waitqueue_head(&priv->bh_evt_wq);
83
84 err = !queue_work(priv->bh_workqueue, &priv->bh_work);
85 WARN_ON(err);
86 return err;
87}
88
89void cw1200_unregister_bh(struct cw1200_common *priv)
90{
91 atomic_add(1, &priv->bh_term);
92 wake_up(&priv->bh_wq);
93
94 flush_workqueue(priv->bh_workqueue);
95
96 destroy_workqueue(priv->bh_workqueue);
97 priv->bh_workqueue = NULL;
98
99 pr_debug("[BH] unregistered.\n");
100}
101
102void cw1200_irq_handler(struct cw1200_common *priv)
103{
104 pr_debug("[BH] irq.\n");
105
106 /* Disable Interrupts! */
107 /* NOTE: hwbus_ops->lock already held */
108 __cw1200_irq_enable(priv, 0);
109
110 if (/* WARN_ON */(priv->bh_error))
111 return;
112
113 if (atomic_add_return(1, &priv->bh_rx) == 1)
114 wake_up(&priv->bh_wq);
115}
116EXPORT_SYMBOL_GPL(cw1200_irq_handler);
117
118void cw1200_bh_wakeup(struct cw1200_common *priv)
119{
120 pr_debug("[BH] wakeup.\n");
121 if (priv->bh_error) {
122 pr_err("[BH] wakeup failed (BH error)\n");
123 return;
124 }
125
126 if (atomic_add_return(1, &priv->bh_tx) == 1)
127 wake_up(&priv->bh_wq);
128}
129
130int cw1200_bh_suspend(struct cw1200_common *priv)
131{
132 pr_debug("[BH] suspend.\n");
133 if (priv->bh_error) {
134 wiphy_warn(priv->hw->wiphy, "BH error -- can't suspend\n");
135 return -EINVAL;
136 }
137
138 atomic_set(&priv->bh_suspend, CW1200_BH_SUSPEND);
139 wake_up(&priv->bh_wq);
140 return wait_event_timeout(priv->bh_evt_wq, priv->bh_error ||
141 (CW1200_BH_SUSPENDED == atomic_read(&priv->bh_suspend)),
142 1 * HZ) ? 0 : -ETIMEDOUT;
143}
144
145int cw1200_bh_resume(struct cw1200_common *priv)
146{
147 pr_debug("[BH] resume.\n");
148 if (priv->bh_error) {
149 wiphy_warn(priv->hw->wiphy, "BH error -- can't resume\n");
150 return -EINVAL;
151 }
152
153 atomic_set(&priv->bh_suspend, CW1200_BH_RESUME);
154 wake_up(&priv->bh_wq);
155 return wait_event_timeout(priv->bh_evt_wq, priv->bh_error ||
156 (CW1200_BH_RESUMED == atomic_read(&priv->bh_suspend)),
157 1 * HZ) ? 0 : -ETIMEDOUT;
158}
159
160static inline void wsm_alloc_tx_buffer(struct cw1200_common *priv)
161{
162 ++priv->hw_bufs_used;
163}
164
165int wsm_release_tx_buffer(struct cw1200_common *priv, int count)
166{
167 int ret = 0;
168 int hw_bufs_used = priv->hw_bufs_used;
169
170 priv->hw_bufs_used -= count;
171 if (WARN_ON(priv->hw_bufs_used < 0))
172 ret = -1;
173 else if (hw_bufs_used >= priv->wsm_caps.input_buffers)
174 ret = 1;
175 if (!priv->hw_bufs_used)
176 wake_up(&priv->bh_evt_wq);
177 return ret;
178}
179
180static int cw1200_bh_read_ctrl_reg(struct cw1200_common *priv,
181 u16 *ctrl_reg)
182{
183 int ret;
184
185 ret = cw1200_reg_read_16(priv,
186 ST90TDS_CONTROL_REG_ID, ctrl_reg);
187 if (ret) {
188 ret = cw1200_reg_read_16(priv,
189 ST90TDS_CONTROL_REG_ID, ctrl_reg);
190 if (ret)
191 pr_err("[BH] Failed to read control register.\n");
192 }
193
194 return ret;
195}
196
197static int cw1200_device_wakeup(struct cw1200_common *priv)
198{
199 u16 ctrl_reg;
200 int ret;
201
202 pr_debug("[BH] Device wakeup.\n");
203
204 /* First, set the dpll register */
205 ret = cw1200_reg_write_32(priv, ST90TDS_TSET_GEN_R_W_REG_ID,
206 cw1200_dpll_from_clk(priv->hw_refclk));
207 if (WARN_ON(ret))
208 return ret;
209
210 /* To force the device to be always-on, the host sets WLAN_UP to 1 */
211 ret = cw1200_reg_write_16(priv, ST90TDS_CONTROL_REG_ID,
212 ST90TDS_CONT_WUP_BIT);
213 if (WARN_ON(ret))
214 return ret;
215
216 ret = cw1200_bh_read_ctrl_reg(priv, &ctrl_reg);
217 if (WARN_ON(ret))
218 return ret;
219
220 /* If the device returns WLAN_RDY as 1, the device is active and will
221 * remain active.
222 */
223 if (ctrl_reg & ST90TDS_CONT_RDY_BIT) {
224 pr_debug("[BH] Device awake.\n");
225 return 1;
226 }
227
228 return 0;
229}
230
231/* Must be called from BH thraed. */
232void cw1200_enable_powersave(struct cw1200_common *priv,
233 bool enable)
234{
235 pr_debug("[BH] Powerave is %s.\n",
236 enable ? "enabled" : "disabled");
237 priv->powersave_enabled = enable;
238}
239
240static int cw1200_bh_rx_helper(struct cw1200_common *priv,
241 uint16_t *ctrl_reg,
242 int *tx)
243{
244 size_t read_len = 0;
245 struct sk_buff *skb_rx = NULL;
246 struct wsm_hdr *wsm;
247 size_t wsm_len;
248 u16 wsm_id;
249 u8 wsm_seq;
250 int rx_resync = 1;
251
252 size_t alloc_len;
253 u8 *data;
254
255 read_len = (*ctrl_reg & ST90TDS_CONT_NEXT_LEN_MASK) * 2;
256 if (!read_len)
257 return 0; /* No more work */
258
259 if (WARN_ON((read_len < sizeof(struct wsm_hdr)) ||
260 (read_len > EFFECTIVE_BUF_SIZE))) {
261 pr_debug("Invalid read len: %zu (%04x)",
262 read_len, *ctrl_reg);
263 goto err;
264 }
265
266 /* Add SIZE of PIGGYBACK reg (CONTROL Reg)
267 * to the NEXT Message length + 2 Bytes for SKB
268 */
269 read_len = read_len + 2;
270
271 alloc_len = priv->hwbus_ops->align_size(
272 priv->hwbus_priv, read_len);
273
274 /* Check if not exceeding CW1200 capabilities */
275 if (WARN_ON_ONCE(alloc_len > EFFECTIVE_BUF_SIZE)) {
276 pr_debug("Read aligned len: %zu\n",
277 alloc_len);
278 }
279
280 skb_rx = dev_alloc_skb(alloc_len);
281 if (WARN_ON(!skb_rx))
282 goto err;
283
284 skb_trim(skb_rx, 0);
285 skb_put(skb_rx, read_len);
286 data = skb_rx->data;
287 if (WARN_ON(!data))
288 goto err;
289
290 if (WARN_ON(cw1200_data_read(priv, data, alloc_len))) {
291 pr_err("rx blew up, len %zu\n", alloc_len);
292 goto err;
293 }
294
295 /* Piggyback */
296 *ctrl_reg = __le16_to_cpu(
297 ((__le16 *)data)[alloc_len / 2 - 1]);
298
299 wsm = (struct wsm_hdr *)data;
300 wsm_len = __le16_to_cpu(wsm->len);
301 if (WARN_ON(wsm_len > read_len))
302 goto err;
303
304 if (priv->wsm_enable_wsm_dumps)
305 print_hex_dump_bytes("<-- ",
306 DUMP_PREFIX_NONE,
307 data, wsm_len);
308
309 wsm_id = __le16_to_cpu(wsm->id) & 0xFFF;
310 wsm_seq = (__le16_to_cpu(wsm->id) >> 13) & 7;
311
312 skb_trim(skb_rx, wsm_len);
313
314 if (wsm_id == 0x0800) {
315 wsm_handle_exception(priv,
316 &data[sizeof(*wsm)],
317 wsm_len - sizeof(*wsm));
318 goto err;
319 } else if (!rx_resync) {
320 if (WARN_ON(wsm_seq != priv->wsm_rx_seq))
321 goto err;
322 }
323 priv->wsm_rx_seq = (wsm_seq + 1) & 7;
324 rx_resync = 0;
325
326 if (wsm_id & 0x0400) {
327 int rc = wsm_release_tx_buffer(priv, 1);
328 if (WARN_ON(rc < 0))
329 return rc;
330 else if (rc > 0)
331 *tx = 1;
332 }
333
334 /* cw1200_wsm_rx takes care on SKB livetime */
335 if (WARN_ON(wsm_handle_rx(priv, wsm_id, wsm, &skb_rx)))
336 goto err;
337
338 if (skb_rx) {
339 dev_kfree_skb(skb_rx);
340 skb_rx = NULL;
341 }
342
343 return 0;
344
345err:
346 if (skb_rx) {
347 dev_kfree_skb(skb_rx);
348 skb_rx = NULL;
349 }
350 return -1;
351}
352
353static int cw1200_bh_tx_helper(struct cw1200_common *priv,
354 int *pending_tx,
355 int *tx_burst)
356{
357 size_t tx_len;
358 u8 *data;
359 int ret;
360 struct wsm_hdr *wsm;
361
362 if (priv->device_can_sleep) {
363 ret = cw1200_device_wakeup(priv);
364 if (WARN_ON(ret < 0)) { /* Error in wakeup */
365 *pending_tx = 1;
366 return 0;
367 } else if (ret) { /* Woke up */
368 priv->device_can_sleep = false;
369 } else { /* Did not awake */
370 *pending_tx = 1;
371 return 0;
372 }
373 }
374
375 wsm_alloc_tx_buffer(priv);
376 ret = wsm_get_tx(priv, &data, &tx_len, tx_burst);
377 if (ret <= 0) {
378 wsm_release_tx_buffer(priv, 1);
379 if (WARN_ON(ret < 0))
380 return ret; /* Error */
381 return 0; /* No work */
382 }
383
384 wsm = (struct wsm_hdr *)data;
385 BUG_ON(tx_len < sizeof(*wsm));
386 BUG_ON(__le16_to_cpu(wsm->len) != tx_len);
387
388 atomic_add(1, &priv->bh_tx);
389
390 tx_len = priv->hwbus_ops->align_size(
391 priv->hwbus_priv, tx_len);
392
393 /* Check if not exceeding CW1200 capabilities */
394 if (WARN_ON_ONCE(tx_len > EFFECTIVE_BUF_SIZE))
395 pr_debug("Write aligned len: %zu\n", tx_len);
396
397 wsm->id &= __cpu_to_le16(0xffff ^ WSM_TX_SEQ(WSM_TX_SEQ_MAX));
398 wsm->id |= __cpu_to_le16(WSM_TX_SEQ(priv->wsm_tx_seq));
399
400 if (WARN_ON(cw1200_data_write(priv, data, tx_len))) {
401 pr_err("tx blew up, len %zu\n", tx_len);
402 wsm_release_tx_buffer(priv, 1);
403 return -1; /* Error */
404 }
405
406 if (priv->wsm_enable_wsm_dumps)
407 print_hex_dump_bytes("--> ",
408 DUMP_PREFIX_NONE,
409 data,
410 __le16_to_cpu(wsm->len));
411
412 wsm_txed(priv, data);
413 priv->wsm_tx_seq = (priv->wsm_tx_seq + 1) & WSM_TX_SEQ_MAX;
414
415 if (*tx_burst > 1) {
416 cw1200_debug_tx_burst(priv);
417 return 1; /* Work remains */
418 }
419
420 return 0;
421}
422
423static int cw1200_bh(void *arg)
424{
425 struct cw1200_common *priv = arg;
426 int rx, tx, term, suspend;
427 u16 ctrl_reg = 0;
428 int tx_allowed;
429 int pending_tx = 0;
430 int tx_burst;
431 long status;
432 u32 dummy;
433 int ret;
434
435 for (;;) {
436 if (!priv->hw_bufs_used &&
437 priv->powersave_enabled &&
438 !priv->device_can_sleep &&
439 !atomic_read(&priv->recent_scan)) {
440 status = 1 * HZ;
441 pr_debug("[BH] Device wakedown. No data.\n");
442 cw1200_reg_write_16(priv, ST90TDS_CONTROL_REG_ID, 0);
443 priv->device_can_sleep = true;
444 } else if (priv->hw_bufs_used) {
445 /* Interrupt loss detection */
446 status = 1 * HZ;
447 } else {
448 status = MAX_SCHEDULE_TIMEOUT;
449 }
450
451 /* Dummy Read for SDIO retry mechanism*/
452 if ((priv->hw_type != -1) &&
453 (atomic_read(&priv->bh_rx) == 0) &&
454 (atomic_read(&priv->bh_tx) == 0))
455 cw1200_reg_read(priv, ST90TDS_CONFIG_REG_ID,
456 &dummy, sizeof(dummy));
457
458 pr_debug("[BH] waiting ...\n");
459 status = wait_event_interruptible_timeout(priv->bh_wq, ({
460 rx = atomic_xchg(&priv->bh_rx, 0);
461 tx = atomic_xchg(&priv->bh_tx, 0);
462 term = atomic_xchg(&priv->bh_term, 0);
463 suspend = pending_tx ?
464 0 : atomic_read(&priv->bh_suspend);
465 (rx || tx || term || suspend || priv->bh_error);
466 }), status);
467
468 pr_debug("[BH] - rx: %d, tx: %d, term: %d, suspend: %d, status: %ld\n",
469 rx, tx, term, suspend, status);
470
471 /* Did an error occur? */
472 if ((status < 0 && status != -ERESTARTSYS) ||
473 term || priv->bh_error) {
474 break;
475 }
476 if (!status) { /* wait_event timed out */
477 unsigned long timestamp = jiffies;
478 long timeout;
479 int pending = 0;
480 int i;
481
482 /* Check to see if we have any outstanding frames */
483 if (priv->hw_bufs_used && (!rx || !tx)) {
484 wiphy_warn(priv->hw->wiphy,
485 "Missed interrupt? (%d frames outstanding)\n",
486 priv->hw_bufs_used);
487 rx = 1;
488
489 /* Get a timestamp of "oldest" frame */
490 for (i = 0; i < 4; ++i)
491 pending += cw1200_queue_get_xmit_timestamp(
492 &priv->tx_queue[i],
493 &timestamp,
494 priv->pending_frame_id);
495
496 /* Check if frame transmission is timed out.
497 * Add an extra second with respect to possible
498 * interrupt loss.
499 */
500 timeout = timestamp +
501 WSM_CMD_LAST_CHANCE_TIMEOUT +
502 1 * HZ -
503 jiffies;
504
505 /* And terminate BH thread if the frame is "stuck" */
506 if (pending && timeout < 0) {
507 wiphy_warn(priv->hw->wiphy,
508 "Timeout waiting for TX confirm (%d/%d pending, %ld vs %lu).\n",
509 priv->hw_bufs_used, pending,
510 timestamp, jiffies);
511 break;
512 }
513 } else if (!priv->device_can_sleep &&
514 !atomic_read(&priv->recent_scan)) {
515 pr_debug("[BH] Device wakedown. Timeout.\n");
516 cw1200_reg_write_16(priv,
517 ST90TDS_CONTROL_REG_ID, 0);
518 priv->device_can_sleep = true;
519 }
520 goto done;
521 } else if (suspend) {
522 pr_debug("[BH] Device suspend.\n");
523 if (priv->powersave_enabled) {
524 pr_debug("[BH] Device wakedown. Suspend.\n");
525 cw1200_reg_write_16(priv,
526 ST90TDS_CONTROL_REG_ID, 0);
527 priv->device_can_sleep = true;
528 }
529
530 atomic_set(&priv->bh_suspend, CW1200_BH_SUSPENDED);
531 wake_up(&priv->bh_evt_wq);
532 status = wait_event_interruptible(priv->bh_wq,
533 CW1200_BH_RESUME == atomic_read(&priv->bh_suspend));
534 if (status < 0) {
535 wiphy_err(priv->hw->wiphy,
536 "Failed to wait for resume: %ld.\n",
537 status);
538 break;
539 }
540 pr_debug("[BH] Device resume.\n");
541 atomic_set(&priv->bh_suspend, CW1200_BH_RESUMED);
542 wake_up(&priv->bh_evt_wq);
543 atomic_add(1, &priv->bh_rx);
544 goto done;
545 }
546
547 rx:
548 tx += pending_tx;
549 pending_tx = 0;
550
551 if (cw1200_bh_read_ctrl_reg(priv, &ctrl_reg))
552 break;
553
554 /* Don't bother trying to rx unless we have data to read */
555 if (ctrl_reg & ST90TDS_CONT_NEXT_LEN_MASK) {
556 ret = cw1200_bh_rx_helper(priv, &ctrl_reg, &tx);
557 if (ret < 0)
558 break;
559 /* Double up here if there's more data.. */
560 if (ctrl_reg & ST90TDS_CONT_NEXT_LEN_MASK) {
561 ret = cw1200_bh_rx_helper(priv, &ctrl_reg, &tx);
562 if (ret < 0)
563 break;
564 }
565 }
566
567 tx:
568 if (tx) {
569 tx = 0;
570
571 BUG_ON(priv->hw_bufs_used > priv->wsm_caps.input_buffers);
572 tx_burst = priv->wsm_caps.input_buffers - priv->hw_bufs_used;
573 tx_allowed = tx_burst > 0;
574
575 if (!tx_allowed) {
576 /* Buffers full. Ensure we process tx
577 * after we handle rx..
578 */
579 pending_tx = tx;
580 goto done_rx;
581 }
582 ret = cw1200_bh_tx_helper(priv, &pending_tx, &tx_burst);
583 if (ret < 0)
584 break;
585 if (ret > 0) /* More to transmit */
586 tx = ret;
587
588 /* Re-read ctrl reg */
589 if (cw1200_bh_read_ctrl_reg(priv, &ctrl_reg))
590 break;
591 }
592
593 done_rx:
594 if (priv->bh_error)
595 break;
596 if (ctrl_reg & ST90TDS_CONT_NEXT_LEN_MASK)
597 goto rx;
598 if (tx)
599 goto tx;
600
601 done:
602 /* Re-enable device interrupts */
603 priv->hwbus_ops->lock(priv->hwbus_priv);
604 __cw1200_irq_enable(priv, 1);
605 priv->hwbus_ops->unlock(priv->hwbus_priv);
606 }
607
608 /* Explicitly disable device interrupts */
609 priv->hwbus_ops->lock(priv->hwbus_priv);
610 __cw1200_irq_enable(priv, 0);
611 priv->hwbus_ops->unlock(priv->hwbus_priv);
612
613 if (!term) {
614 pr_err("[BH] Fatal error, exiting.\n");
615 priv->bh_error = 1;
616 /* TODO: schedule_work(recovery) */
617 }
618 return 0;
619}
diff --git a/drivers/net/wireless/cw1200/bh.h b/drivers/net/wireless/cw1200/bh.h
new file mode 100644
index 000000000000..af6a4853728f
--- /dev/null
+++ b/drivers/net/wireless/cw1200/bh.h
@@ -0,0 +1,28 @@
1/*
2 * Device handling thread interface for mac80211 ST-Ericsson CW1200 drivers
3 *
4 * Copyright (c) 2010, ST-Ericsson
5 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#ifndef CW1200_BH_H
13#define CW1200_BH_H
14
15/* extern */ struct cw1200_common;
16
17int cw1200_register_bh(struct cw1200_common *priv);
18void cw1200_unregister_bh(struct cw1200_common *priv);
19void cw1200_irq_handler(struct cw1200_common *priv);
20void cw1200_bh_wakeup(struct cw1200_common *priv);
21int cw1200_bh_suspend(struct cw1200_common *priv);
22int cw1200_bh_resume(struct cw1200_common *priv);
23/* Must be called from BH thread. */
24void cw1200_enable_powersave(struct cw1200_common *priv,
25 bool enable);
26int wsm_release_tx_buffer(struct cw1200_common *priv, int count);
27
28#endif /* CW1200_BH_H */
diff --git a/drivers/net/wireless/cw1200/cw1200.h b/drivers/net/wireless/cw1200/cw1200.h
new file mode 100644
index 000000000000..243e96353d13
--- /dev/null
+++ b/drivers/net/wireless/cw1200/cw1200.h
@@ -0,0 +1,323 @@
1/*
2 * Common private data for ST-Ericsson CW1200 drivers
3 *
4 * Copyright (c) 2010, ST-Ericsson
5 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6 *
7 * Based on the mac80211 Prism54 code, which is
8 * Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net>
9 *
10 * Based on the islsm (softmac prism54) driver, which is:
11 * Copyright 2004-2006 Jean-Baptiste Note <jbnote@gmail.com>, et al.
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2 as
15 * published by the Free Software Foundation.
16 */
17
18#ifndef CW1200_H
19#define CW1200_H
20
21#include <linux/wait.h>
22#include <linux/mutex.h>
23#include <linux/workqueue.h>
24#include <net/mac80211.h>
25
26#include "queue.h"
27#include "wsm.h"
28#include "scan.h"
29#include "txrx.h"
30#include "pm.h"
31
32/* Forward declarations */
33struct hwbus_ops;
34struct task_struct;
35struct cw1200_debug_priv;
36struct firmware;
37
38#define CW1200_MAX_CTRL_FRAME_LEN (0x1000)
39
40#define CW1200_MAX_STA_IN_AP_MODE (5)
41#define CW1200_LINK_ID_AFTER_DTIM (CW1200_MAX_STA_IN_AP_MODE + 1)
42#define CW1200_LINK_ID_UAPSD (CW1200_MAX_STA_IN_AP_MODE + 2)
43#define CW1200_LINK_ID_MAX (CW1200_MAX_STA_IN_AP_MODE + 3)
44#define CW1200_MAX_REQUEUE_ATTEMPTS (5)
45
46#define CW1200_MAX_TID (8)
47
48#define CW1200_BLOCK_ACK_CNT (30)
49#define CW1200_BLOCK_ACK_THLD (800)
50#define CW1200_BLOCK_ACK_HIST (3)
51#define CW1200_BLOCK_ACK_INTERVAL (1 * HZ / CW1200_BLOCK_ACK_HIST)
52
53#define CW1200_JOIN_TIMEOUT (1 * HZ)
54#define CW1200_AUTH_TIMEOUT (5 * HZ)
55
56struct cw1200_ht_info {
57 struct ieee80211_sta_ht_cap ht_cap;
58 enum nl80211_channel_type channel_type;
59 u16 operation_mode;
60};
61
62/* Please keep order */
63enum cw1200_join_status {
64 CW1200_JOIN_STATUS_PASSIVE = 0,
65 CW1200_JOIN_STATUS_MONITOR,
66 CW1200_JOIN_STATUS_JOINING,
67 CW1200_JOIN_STATUS_PRE_STA,
68 CW1200_JOIN_STATUS_STA,
69 CW1200_JOIN_STATUS_IBSS,
70 CW1200_JOIN_STATUS_AP,
71};
72
73enum cw1200_link_status {
74 CW1200_LINK_OFF,
75 CW1200_LINK_RESERVE,
76 CW1200_LINK_SOFT,
77 CW1200_LINK_HARD,
78 CW1200_LINK_RESET,
79 CW1200_LINK_RESET_REMAP,
80};
81
82extern int cw1200_power_mode;
83extern const char * const cw1200_fw_types[];
84
85struct cw1200_link_entry {
86 unsigned long timestamp;
87 enum cw1200_link_status status;
88 enum cw1200_link_status prev_status;
89 u8 mac[ETH_ALEN];
90 u8 buffered[CW1200_MAX_TID];
91 struct sk_buff_head rx_queue;
92};
93
94struct cw1200_common {
95 /* interfaces to the rest of the stack */
96 struct ieee80211_hw *hw;
97 struct ieee80211_vif *vif;
98 struct device *pdev;
99
100 /* Statistics */
101 struct ieee80211_low_level_stats stats;
102
103 /* Our macaddr */
104 u8 mac_addr[ETH_ALEN];
105
106 /* Hardware interface */
107 const struct hwbus_ops *hwbus_ops;
108 struct hwbus_priv *hwbus_priv;
109
110 /* Hardware information */
111 enum {
112 HIF_9000_SILICON_VERSATILE = 0,
113 HIF_8601_VERSATILE,
114 HIF_8601_SILICON,
115 } hw_type;
116 enum {
117 CW1200_HW_REV_CUT10 = 10,
118 CW1200_HW_REV_CUT11 = 11,
119 CW1200_HW_REV_CUT20 = 20,
120 CW1200_HW_REV_CUT22 = 22,
121 CW1X60_HW_REV = 40,
122 } hw_revision;
123 int hw_refclk;
124 bool hw_have_5ghz;
125 const struct firmware *sdd;
126 char *sdd_path;
127
128 struct cw1200_debug_priv *debug;
129
130 struct workqueue_struct *workqueue;
131 struct mutex conf_mutex;
132
133 struct cw1200_queue tx_queue[4];
134 struct cw1200_queue_stats tx_queue_stats;
135 int tx_burst_idx;
136
137 /* firmware/hardware info */
138 unsigned int tx_hdr_len;
139
140 /* Radio data */
141 int output_power;
142
143 /* BBP/MAC state */
144 struct ieee80211_rate *rates;
145 struct ieee80211_rate *mcs_rates;
146 struct ieee80211_channel *channel;
147 struct wsm_edca_params edca;
148 struct wsm_tx_queue_params tx_queue_params;
149 struct wsm_mib_association_mode association_mode;
150 struct wsm_set_bss_params bss_params;
151 struct cw1200_ht_info ht_info;
152 struct wsm_set_pm powersave_mode;
153 struct wsm_set_pm firmware_ps_mode;
154 int cqm_rssi_thold;
155 unsigned cqm_rssi_hyst;
156 bool cqm_use_rssi;
157 int cqm_beacon_loss_count;
158 int channel_switch_in_progress;
159 wait_queue_head_t channel_switch_done;
160 u8 long_frame_max_tx_count;
161 u8 short_frame_max_tx_count;
162 int mode;
163 bool enable_beacon;
164 int beacon_int;
165 bool listening;
166 struct wsm_rx_filter rx_filter;
167 struct wsm_mib_multicast_filter multicast_filter;
168 bool has_multicast_subscription;
169 bool disable_beacon_filter;
170 struct work_struct update_filtering_work;
171 struct work_struct set_beacon_wakeup_period_work;
172
173 u8 ba_rx_tid_mask;
174 u8 ba_tx_tid_mask;
175
176 struct cw1200_pm_state pm_state;
177
178 struct wsm_p2p_ps_modeinfo p2p_ps_modeinfo;
179 struct wsm_uapsd_info uapsd_info;
180 bool setbssparams_done;
181 bool bt_present;
182 u8 conf_listen_interval;
183 u32 listen_interval;
184 u32 erp_info;
185 u32 rts_threshold;
186
187 /* BH */
188 atomic_t bh_rx;
189 atomic_t bh_tx;
190 atomic_t bh_term;
191 atomic_t bh_suspend;
192
193 struct workqueue_struct *bh_workqueue;
194 struct work_struct bh_work;
195
196 int bh_error;
197 wait_queue_head_t bh_wq;
198 wait_queue_head_t bh_evt_wq;
199 u8 buf_id_tx;
200 u8 buf_id_rx;
201 u8 wsm_rx_seq;
202 u8 wsm_tx_seq;
203 int hw_bufs_used;
204 bool powersave_enabled;
205 bool device_can_sleep;
206
207 /* Scan status */
208 struct cw1200_scan scan;
209 /* Keep cw1200 awake (WUP = 1) 1 second after each scan to avoid
210 * FW issue with sleeping/waking up.
211 */
212 atomic_t recent_scan;
213 struct delayed_work clear_recent_scan_work;
214
215 /* WSM */
216 struct wsm_startup_ind wsm_caps;
217 struct mutex wsm_cmd_mux;
218 struct wsm_buf wsm_cmd_buf;
219 struct wsm_cmd wsm_cmd;
220 wait_queue_head_t wsm_cmd_wq;
221 wait_queue_head_t wsm_startup_done;
222 int firmware_ready;
223 atomic_t tx_lock;
224
225 /* WSM debug */
226 int wsm_enable_wsm_dumps;
227
228 /* WSM Join */
229 enum cw1200_join_status join_status;
230 u32 pending_frame_id;
231 bool join_pending;
232 struct delayed_work join_timeout;
233 struct work_struct unjoin_work;
234 struct work_struct join_complete_work;
235 int join_complete_status;
236 int join_dtim_period;
237 bool delayed_unjoin;
238
239 /* TX/RX and security */
240 s8 wep_default_key_id;
241 struct work_struct wep_key_work;
242 u32 key_map;
243 struct wsm_add_key keys[WSM_KEY_MAX_INDEX + 1];
244
245 /* AP powersave */
246 u32 link_id_map;
247 struct cw1200_link_entry link_id_db[CW1200_MAX_STA_IN_AP_MODE];
248 struct work_struct link_id_work;
249 struct delayed_work link_id_gc_work;
250 u32 sta_asleep_mask;
251 u32 pspoll_mask;
252 bool aid0_bit_set;
253 spinlock_t ps_state_lock; /* Protect power save state */
254 bool buffered_multicasts;
255 bool tx_multicast;
256 struct work_struct set_tim_work;
257 struct work_struct set_cts_work;
258 struct work_struct multicast_start_work;
259 struct work_struct multicast_stop_work;
260 struct timer_list mcast_timeout;
261
262 /* WSM events and CQM implementation */
263 spinlock_t event_queue_lock; /* Protect event queue */
264 struct list_head event_queue;
265 struct work_struct event_handler;
266
267 struct delayed_work bss_loss_work;
268 spinlock_t bss_loss_lock; /* Protect BSS loss state */
269 int bss_loss_state;
270 int bss_loss_confirm_id;
271 int delayed_link_loss;
272 struct work_struct bss_params_work;
273
274 /* TX rate policy cache */
275 struct tx_policy_cache tx_policy_cache;
276 struct work_struct tx_policy_upload_work;
277
278 /* legacy PS mode switch in suspend */
279 int ps_mode_switch_in_progress;
280 wait_queue_head_t ps_mode_switch_done;
281
282 /* Workaround for WFD testcase 6.1.10*/
283 struct work_struct linkid_reset_work;
284 u8 action_frame_sa[ETH_ALEN];
285 u8 action_linkid;
286};
287
288struct cw1200_sta_priv {
289 int link_id;
290};
291
292/* interfaces for the drivers */
293int cw1200_core_probe(const struct hwbus_ops *hwbus_ops,
294 struct hwbus_priv *hwbus,
295 struct device *pdev,
296 struct cw1200_common **pself,
297 int ref_clk, const u8 *macaddr,
298 const char *sdd_path, bool have_5ghz);
299void cw1200_core_release(struct cw1200_common *self);
300
301#define FWLOAD_BLOCK_SIZE (1024)
302
303static inline int cw1200_is_ht(const struct cw1200_ht_info *ht_info)
304{
305 return ht_info->channel_type != NL80211_CHAN_NO_HT;
306}
307
308static inline int cw1200_ht_greenfield(const struct cw1200_ht_info *ht_info)
309{
310 return cw1200_is_ht(ht_info) &&
311 (ht_info->ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD) &&
312 !(ht_info->operation_mode &
313 IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
314}
315
316static inline int cw1200_ht_ampdu_density(const struct cw1200_ht_info *ht_info)
317{
318 if (!cw1200_is_ht(ht_info))
319 return 0;
320 return ht_info->ht_cap.ampdu_density;
321}
322
323#endif /* CW1200_H */
diff --git a/drivers/net/wireless/cw1200/cw1200_sdio.c b/drivers/net/wireless/cw1200/cw1200_sdio.c
new file mode 100644
index 000000000000..ebdcdf44f155
--- /dev/null
+++ b/drivers/net/wireless/cw1200/cw1200_sdio.c
@@ -0,0 +1,425 @@
1/*
2 * Mac80211 SDIO driver for ST-Ericsson CW1200 device
3 *
4 * Copyright (c) 2010, ST-Ericsson
5 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/module.h>
13#include <linux/gpio.h>
14#include <linux/delay.h>
15#include <linux/mmc/host.h>
16#include <linux/mmc/sdio_func.h>
17#include <linux/mmc/card.h>
18#include <linux/mmc/sdio.h>
19#include <net/mac80211.h>
20
21#include "cw1200.h"
22#include "hwbus.h"
23#include <linux/platform_data/net-cw1200.h>
24#include "hwio.h"
25
26MODULE_AUTHOR("Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>");
27MODULE_DESCRIPTION("mac80211 ST-Ericsson CW1200 SDIO driver");
28MODULE_LICENSE("GPL");
29
30#define SDIO_BLOCK_SIZE (512)
31
32/* Default platform data for Sagrad modules */
33static struct cw1200_platform_data_sdio sagrad_109x_evk_platform_data = {
34 .ref_clk = 38400,
35 .have_5ghz = false,
36 .sdd_file = "sdd_sagrad_1091_1098.bin",
37};
38
39/* Allow platform data to be overridden */
40static struct cw1200_platform_data_sdio *global_plat_data = &sagrad_109x_evk_platform_data;
41
42void __init cw1200_sdio_set_platform_data(struct cw1200_platform_data_sdio *pdata)
43{
44 global_plat_data = pdata;
45}
46
47struct hwbus_priv {
48 struct sdio_func *func;
49 struct cw1200_common *core;
50 const struct cw1200_platform_data_sdio *pdata;
51};
52
53#ifndef SDIO_VENDOR_ID_STE
54#define SDIO_VENDOR_ID_STE 0x0020
55#endif
56
57#ifndef SDIO_DEVICE_ID_STE_CW1200
58#define SDIO_DEVICE_ID_STE_CW1200 0x2280
59#endif
60
61static const struct sdio_device_id cw1200_sdio_ids[] = {
62 { SDIO_DEVICE(SDIO_VENDOR_ID_STE, SDIO_DEVICE_ID_STE_CW1200) },
63 { /* end: all zeroes */ },
64};
65
66/* hwbus_ops implemetation */
67
68static int cw1200_sdio_memcpy_fromio(struct hwbus_priv *self,
69 unsigned int addr,
70 void *dst, int count)
71{
72 return sdio_memcpy_fromio(self->func, dst, addr, count);
73}
74
75static int cw1200_sdio_memcpy_toio(struct hwbus_priv *self,
76 unsigned int addr,
77 const void *src, int count)
78{
79 return sdio_memcpy_toio(self->func, addr, (void *)src, count);
80}
81
82static void cw1200_sdio_lock(struct hwbus_priv *self)
83{
84 sdio_claim_host(self->func);
85}
86
87static void cw1200_sdio_unlock(struct hwbus_priv *self)
88{
89 sdio_release_host(self->func);
90}
91
92static void cw1200_sdio_irq_handler(struct sdio_func *func)
93{
94 struct hwbus_priv *self = sdio_get_drvdata(func);
95
96 /* note: sdio_host already claimed here. */
97 if (self->core)
98 cw1200_irq_handler(self->core);
99}
100
101static irqreturn_t cw1200_gpio_hardirq(int irq, void *dev_id)
102{
103 return IRQ_WAKE_THREAD;
104}
105
106static irqreturn_t cw1200_gpio_irq(int irq, void *dev_id)
107{
108 struct hwbus_priv *self = dev_id;
109
110 if (self->core) {
111 sdio_claim_host(self->func);
112 cw1200_irq_handler(self->core);
113 sdio_release_host(self->func);
114 return IRQ_HANDLED;
115 } else {
116 return IRQ_NONE;
117 }
118}
119
120static int cw1200_request_irq(struct hwbus_priv *self)
121{
122 int ret;
123 u8 cccr;
124
125 cccr = sdio_f0_readb(self->func, SDIO_CCCR_IENx, &ret);
126 if (WARN_ON(ret))
127 goto err;
128
129 /* Master interrupt enable ... */
130 cccr |= BIT(0);
131
132 /* ... for our function */
133 cccr |= BIT(self->func->num);
134
135 sdio_f0_writeb(self->func, cccr, SDIO_CCCR_IENx, &ret);
136 if (WARN_ON(ret))
137 goto err;
138
139 ret = enable_irq_wake(self->pdata->irq);
140 if (WARN_ON(ret))
141 goto err;
142
143 /* Request the IRQ */
144 ret = request_threaded_irq(self->pdata->irq, cw1200_gpio_hardirq,
145 cw1200_gpio_irq,
146 IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
147 "cw1200_wlan_irq", self);
148 if (WARN_ON(ret))
149 goto err;
150
151 return 0;
152
153err:
154 return ret;
155}
156
157static int cw1200_sdio_irq_subscribe(struct hwbus_priv *self)
158{
159 int ret = 0;
160
161 pr_debug("SW IRQ subscribe\n");
162 sdio_claim_host(self->func);
163 if (self->pdata->irq)
164 ret = cw1200_request_irq(self);
165 else
166 ret = sdio_claim_irq(self->func, cw1200_sdio_irq_handler);
167
168 sdio_release_host(self->func);
169 return ret;
170}
171
172static int cw1200_sdio_irq_unsubscribe(struct hwbus_priv *self)
173{
174 int ret = 0;
175
176 pr_debug("SW IRQ unsubscribe\n");
177
178 if (self->pdata->irq) {
179 disable_irq_wake(self->pdata->irq);
180 free_irq(self->pdata->irq, self);
181 } else {
182 sdio_claim_host(self->func);
183 ret = sdio_release_irq(self->func);
184 sdio_release_host(self->func);
185 }
186 return ret;
187}
188
189static int cw1200_sdio_off(const struct cw1200_platform_data_sdio *pdata)
190{
191 if (pdata->reset) {
192 gpio_set_value(pdata->reset, 0);
193 msleep(30); /* Min is 2 * CLK32K cycles */
194 gpio_free(pdata->reset);
195 }
196
197 if (pdata->power_ctrl)
198 pdata->power_ctrl(pdata, false);
199 if (pdata->clk_ctrl)
200 pdata->clk_ctrl(pdata, false);
201
202 return 0;
203}
204
205static int cw1200_sdio_on(const struct cw1200_platform_data_sdio *pdata)
206{
207 /* Ensure I/Os are pulled low */
208 if (pdata->reset) {
209 gpio_request(pdata->reset, "cw1200_wlan_reset");
210 gpio_direction_output(pdata->reset, 0);
211 }
212 if (pdata->powerup) {
213 gpio_request(pdata->powerup, "cw1200_wlan_powerup");
214 gpio_direction_output(pdata->powerup, 0);
215 }
216 if (pdata->reset || pdata->powerup)
217 msleep(10); /* Settle time? */
218
219 /* Enable 3v3 and 1v8 to hardware */
220 if (pdata->power_ctrl) {
221 if (pdata->power_ctrl(pdata, true)) {
222 pr_err("power_ctrl() failed!\n");
223 return -1;
224 }
225 }
226
227 /* Enable CLK32K */
228 if (pdata->clk_ctrl) {
229 if (pdata->clk_ctrl(pdata, true)) {
230 pr_err("clk_ctrl() failed!\n");
231 return -1;
232 }
233 msleep(10); /* Delay until clock is stable for 2 cycles */
234 }
235
236 /* Enable POWERUP signal */
237 if (pdata->powerup) {
238 gpio_set_value(pdata->powerup, 1);
239 msleep(250); /* or more..? */
240 }
241 /* Enable RSTn signal */
242 if (pdata->reset) {
243 gpio_set_value(pdata->reset, 1);
244 msleep(50); /* Or more..? */
245 }
246 return 0;
247}
248
249static size_t cw1200_sdio_align_size(struct hwbus_priv *self, size_t size)
250{
251 if (self->pdata->no_nptb)
252 size = round_up(size, SDIO_BLOCK_SIZE);
253 else
254 size = sdio_align_size(self->func, size);
255
256 return size;
257}
258
259static int cw1200_sdio_pm(struct hwbus_priv *self, bool suspend)
260{
261 int ret = 0;
262
263 if (self->pdata->irq)
264 ret = irq_set_irq_wake(self->pdata->irq, suspend);
265 return ret;
266}
267
268static struct hwbus_ops cw1200_sdio_hwbus_ops = {
269 .hwbus_memcpy_fromio = cw1200_sdio_memcpy_fromio,
270 .hwbus_memcpy_toio = cw1200_sdio_memcpy_toio,
271 .lock = cw1200_sdio_lock,
272 .unlock = cw1200_sdio_unlock,
273 .align_size = cw1200_sdio_align_size,
274 .power_mgmt = cw1200_sdio_pm,
275};
276
277/* Probe Function to be called by SDIO stack when device is discovered */
278static int cw1200_sdio_probe(struct sdio_func *func,
279 const struct sdio_device_id *id)
280{
281 struct hwbus_priv *self;
282 int status;
283
284 pr_info("cw1200_wlan_sdio: Probe called\n");
285
286 /* We are only able to handle the wlan function */
287 if (func->num != 0x01)
288 return -ENODEV;
289
290 self = kzalloc(sizeof(*self), GFP_KERNEL);
291 if (!self) {
292 pr_err("Can't allocate SDIO hwbus_priv.\n");
293 return -ENOMEM;
294 }
295
296 func->card->quirks |= MMC_QUIRK_LENIENT_FN0;
297
298 self->pdata = global_plat_data; /* FIXME */
299 self->func = func;
300 sdio_set_drvdata(func, self);
301 sdio_claim_host(func);
302 sdio_enable_func(func);
303 sdio_release_host(func);
304
305 status = cw1200_sdio_irq_subscribe(self);
306
307 status = cw1200_core_probe(&cw1200_sdio_hwbus_ops,
308 self, &func->dev, &self->core,
309 self->pdata->ref_clk,
310 self->pdata->macaddr,
311 self->pdata->sdd_file,
312 self->pdata->have_5ghz);
313 if (status) {
314 cw1200_sdio_irq_unsubscribe(self);
315 sdio_claim_host(func);
316 sdio_disable_func(func);
317 sdio_release_host(func);
318 sdio_set_drvdata(func, NULL);
319 kfree(self);
320 }
321
322 return status;
323}
324
325/* Disconnect Function to be called by SDIO stack when
326 * device is disconnected
327 */
328static void cw1200_sdio_disconnect(struct sdio_func *func)
329{
330 struct hwbus_priv *self = sdio_get_drvdata(func);
331
332 if (self) {
333 cw1200_sdio_irq_unsubscribe(self);
334 if (self->core) {
335 cw1200_core_release(self->core);
336 self->core = NULL;
337 }
338 sdio_claim_host(func);
339 sdio_disable_func(func);
340 sdio_release_host(func);
341 sdio_set_drvdata(func, NULL);
342 kfree(self);
343 }
344}
345
346#ifdef CONFIG_PM
347static int cw1200_sdio_suspend(struct device *dev)
348{
349 int ret;
350 struct sdio_func *func = dev_to_sdio_func(dev);
351 struct hwbus_priv *self = sdio_get_drvdata(func);
352
353 if (!cw1200_can_suspend(self->core))
354 return -EAGAIN;
355
356 /* Notify SDIO that CW1200 will remain powered during suspend */
357 ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
358 if (ret)
359 pr_err("Error setting SDIO pm flags: %i\n", ret);
360
361 return ret;
362}
363
364static int cw1200_sdio_resume(struct device *dev)
365{
366 return 0;
367}
368
369static const struct dev_pm_ops cw1200_pm_ops = {
370 .suspend = cw1200_sdio_suspend,
371 .resume = cw1200_sdio_resume,
372};
373#endif
374
375static struct sdio_driver sdio_driver = {
376 .name = "cw1200_wlan_sdio",
377 .id_table = cw1200_sdio_ids,
378 .probe = cw1200_sdio_probe,
379 .remove = cw1200_sdio_disconnect,
380#ifdef CONFIG_PM
381 .drv = {
382 .pm = &cw1200_pm_ops,
383 }
384#endif
385};
386
387/* Init Module function -> Called by insmod */
388static int __init cw1200_sdio_init(void)
389{
390 const struct cw1200_platform_data_sdio *pdata;
391 int ret;
392
393 /* FIXME -- this won't support multiple devices */
394 pdata = global_plat_data;
395
396 if (cw1200_sdio_on(pdata)) {
397 ret = -1;
398 goto err;
399 }
400
401 ret = sdio_register_driver(&sdio_driver);
402 if (ret)
403 goto err;
404
405 return 0;
406
407err:
408 cw1200_sdio_off(pdata);
409 return ret;
410}
411
412/* Called at Driver Unloading */
413static void __exit cw1200_sdio_exit(void)
414{
415 const struct cw1200_platform_data_sdio *pdata;
416
417 /* FIXME -- this won't support multiple devices */
418 pdata = global_plat_data;
419 sdio_unregister_driver(&sdio_driver);
420 cw1200_sdio_off(pdata);
421}
422
423
424module_init(cw1200_sdio_init);
425module_exit(cw1200_sdio_exit);
diff --git a/drivers/net/wireless/cw1200/cw1200_spi.c b/drivers/net/wireless/cw1200/cw1200_spi.c
new file mode 100644
index 000000000000..953bd1904d3d
--- /dev/null
+++ b/drivers/net/wireless/cw1200/cw1200_spi.c
@@ -0,0 +1,463 @@
1/*
2 * Mac80211 SPI driver for ST-Ericsson CW1200 device
3 *
4 * Copyright (c) 2011, Sagrad Inc.
5 * Author: Solomon Peachy <speachy@sagrad.com>
6 *
7 * Based on cw1200_sdio.c
8 * Copyright (c) 2010, ST-Ericsson
9 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 */
15
16#include <linux/module.h>
17#include <linux/gpio.h>
18#include <linux/delay.h>
19#include <linux/spinlock.h>
20#include <linux/interrupt.h>
21#include <net/mac80211.h>
22
23#include <linux/spi/spi.h>
24#include <linux/device.h>
25
26#include "cw1200.h"
27#include "hwbus.h"
28#include <linux/platform_data/net-cw1200.h>
29#include "hwio.h"
30
31MODULE_AUTHOR("Solomon Peachy <speachy@sagrad.com>");
32MODULE_DESCRIPTION("mac80211 ST-Ericsson CW1200 SPI driver");
33MODULE_LICENSE("GPL");
34MODULE_ALIAS("spi:cw1200_wlan_spi");
35
36/* #define SPI_DEBUG */
37
38struct hwbus_priv {
39 struct spi_device *func;
40 struct cw1200_common *core;
41 const struct cw1200_platform_data_spi *pdata;
42 spinlock_t lock; /* Serialize all bus operations */
43 int claimed;
44};
45
46#define SDIO_TO_SPI_ADDR(addr) ((addr & 0x1f)>>2)
47#define SET_WRITE 0x7FFF /* usage: and operation */
48#define SET_READ 0x8000 /* usage: or operation */
49
50/* Notes on byte ordering:
51 LE: B0 B1 B2 B3
52 BE: B3 B2 B1 B0
53
54 Hardware expects 32-bit data to be written as 16-bit BE words:
55
56 B1 B0 B3 B2
57*/
58
59static int cw1200_spi_memcpy_fromio(struct hwbus_priv *self,
60 unsigned int addr,
61 void *dst, int count)
62{
63 int ret, i;
64 uint16_t regaddr;
65 struct spi_message m;
66
67 struct spi_transfer t_addr = {
68 .tx_buf = &regaddr,
69 .len = sizeof(regaddr),
70 };
71 struct spi_transfer t_msg = {
72 .rx_buf = dst,
73 .len = count,
74 };
75
76 regaddr = (SDIO_TO_SPI_ADDR(addr))<<12;
77 regaddr |= SET_READ;
78 regaddr |= (count>>1);
79 regaddr = cpu_to_le16(regaddr);
80
81#ifdef SPI_DEBUG
82 pr_info("READ : %04d from 0x%02x (%04x)\n", count, addr,
83 le16_to_cpu(regaddr));
84#endif
85
86#if defined(__LITTLE_ENDIAN)
87 /* We have to byteswap if the SPI bus is limited to 8b operation */
88 if (self->func->bits_per_word == 8)
89#endif
90 regaddr = swab16(regaddr);
91
92 spi_message_init(&m);
93 spi_message_add_tail(&t_addr, &m);
94 spi_message_add_tail(&t_msg, &m);
95 ret = spi_sync(self->func, &m);
96
97#ifdef SPI_DEBUG
98 pr_info("READ : ");
99 for (i = 0; i < t_addr.len; i++)
100 printk("%02x ", ((u8 *)t_addr.tx_buf)[i]);
101 printk(" : ");
102 for (i = 0; i < t_msg.len; i++)
103 printk("%02x ", ((u8 *)t_msg.rx_buf)[i]);
104 printk("\n");
105#endif
106
107#if defined(__LITTLE_ENDIAN)
108 /* We have to byteswap if the SPI bus is limited to 8b operation */
109 if (self->func->bits_per_word == 8)
110#endif
111 {
112 uint16_t *buf = (uint16_t *)dst;
113 for (i = 0; i < ((count + 1) >> 1); i++)
114 buf[i] = swab16(buf[i]);
115 }
116
117 return ret;
118}
119
120static int cw1200_spi_memcpy_toio(struct hwbus_priv *self,
121 unsigned int addr,
122 const void *src, int count)
123{
124 int rval, i;
125 uint16_t regaddr;
126 struct spi_transfer t_addr = {
127 .tx_buf = &regaddr,
128 .len = sizeof(regaddr),
129 };
130 struct spi_transfer t_msg = {
131 .tx_buf = src,
132 .len = count,
133 };
134 struct spi_message m;
135
136 regaddr = (SDIO_TO_SPI_ADDR(addr))<<12;
137 regaddr &= SET_WRITE;
138 regaddr |= (count>>1);
139 regaddr = cpu_to_le16(regaddr);
140
141#ifdef SPI_DEBUG
142 pr_info("WRITE: %04d to 0x%02x (%04x)\n", count, addr,
143 le16_to_cpu(regaddr));
144#endif
145
146#if defined(__LITTLE_ENDIAN)
147 /* We have to byteswap if the SPI bus is limited to 8b operation */
148 if (self->func->bits_per_word == 8)
149#endif
150 {
151 uint16_t *buf = (uint16_t *)src;
152 regaddr = swab16(regaddr);
153 for (i = 0; i < ((count + 1) >> 1); i++)
154 buf[i] = swab16(buf[i]);
155 }
156
157#ifdef SPI_DEBUG
158 pr_info("WRITE: ");
159 for (i = 0; i < t_addr.len; i++)
160 printk("%02x ", ((u8 *)t_addr.tx_buf)[i]);
161 printk(" : ");
162 for (i = 0; i < t_msg.len; i++)
163 printk("%02x ", ((u8 *)t_msg.tx_buf)[i]);
164 printk("\n");
165#endif
166
167 spi_message_init(&m);
168 spi_message_add_tail(&t_addr, &m);
169 spi_message_add_tail(&t_msg, &m);
170 rval = spi_sync(self->func, &m);
171
172#ifdef SPI_DEBUG
173 pr_info("WROTE: %d\n", m.actual_length);
174#endif
175
176#if defined(__LITTLE_ENDIAN)
177 /* We have to byteswap if the SPI bus is limited to 8b operation */
178 if (self->func->bits_per_word == 8)
179#endif
180 {
181 uint16_t *buf = (uint16_t *)src;
182 for (i = 0; i < ((count + 1) >> 1); i++)
183 buf[i] = swab16(buf[i]);
184 }
185 return rval;
186}
187
188static void cw1200_spi_lock(struct hwbus_priv *self)
189{
190 unsigned long flags;
191
192 might_sleep();
193
194 spin_lock_irqsave(&self->lock, flags);
195 while (1) {
196 set_current_state(TASK_UNINTERRUPTIBLE);
197 if (!self->claimed)
198 break;
199 spin_unlock_irqrestore(&self->lock, flags);
200 schedule();
201 spin_lock_irqsave(&self->lock, flags);
202 }
203 set_current_state(TASK_RUNNING);
204 self->claimed = 1;
205 spin_unlock_irqrestore(&self->lock, flags);
206
207 return;
208}
209
210static void cw1200_spi_unlock(struct hwbus_priv *self)
211{
212 unsigned long flags;
213
214 spin_lock_irqsave(&self->lock, flags);
215 self->claimed = 0;
216 spin_unlock_irqrestore(&self->lock, flags);
217 return;
218}
219
220static irqreturn_t cw1200_spi_irq_handler(int irq, void *dev_id)
221{
222 struct hwbus_priv *self = dev_id;
223
224 if (self->core) {
225 cw1200_irq_handler(self->core);
226 return IRQ_HANDLED;
227 } else {
228 return IRQ_NONE;
229 }
230}
231
232static int cw1200_spi_irq_subscribe(struct hwbus_priv *self)
233{
234 int ret;
235
236 pr_debug("SW IRQ subscribe\n");
237
238 ret = request_any_context_irq(self->func->irq, cw1200_spi_irq_handler,
239 IRQF_TRIGGER_HIGH,
240 "cw1200_wlan_irq", self);
241 if (WARN_ON(ret < 0))
242 goto exit;
243
244 ret = enable_irq_wake(self->func->irq);
245 if (WARN_ON(ret))
246 goto free_irq;
247
248 return 0;
249
250free_irq:
251 free_irq(self->func->irq, self);
252exit:
253 return ret;
254}
255
256static int cw1200_spi_irq_unsubscribe(struct hwbus_priv *self)
257{
258 int ret = 0;
259
260 pr_debug("SW IRQ unsubscribe\n");
261 disable_irq_wake(self->func->irq);
262 free_irq(self->func->irq, self);
263
264 return ret;
265}
266
267static int cw1200_spi_off(const struct cw1200_platform_data_spi *pdata)
268{
269 if (pdata->reset) {
270 gpio_set_value(pdata->reset, 0);
271 msleep(30); /* Min is 2 * CLK32K cycles */
272 gpio_free(pdata->reset);
273 }
274
275 if (pdata->power_ctrl)
276 pdata->power_ctrl(pdata, false);
277 if (pdata->clk_ctrl)
278 pdata->clk_ctrl(pdata, false);
279
280 return 0;
281}
282
283static int cw1200_spi_on(const struct cw1200_platform_data_spi *pdata)
284{
285 /* Ensure I/Os are pulled low */
286 if (pdata->reset) {
287 gpio_request(pdata->reset, "cw1200_wlan_reset");
288 gpio_direction_output(pdata->reset, 0);
289 }
290 if (pdata->powerup) {
291 gpio_request(pdata->powerup, "cw1200_wlan_powerup");
292 gpio_direction_output(pdata->powerup, 0);
293 }
294 if (pdata->reset || pdata->powerup)
295 msleep(10); /* Settle time? */
296
297 /* Enable 3v3 and 1v8 to hardware */
298 if (pdata->power_ctrl) {
299 if (pdata->power_ctrl(pdata, true)) {
300 pr_err("power_ctrl() failed!\n");
301 return -1;
302 }
303 }
304
305 /* Enable CLK32K */
306 if (pdata->clk_ctrl) {
307 if (pdata->clk_ctrl(pdata, true)) {
308 pr_err("clk_ctrl() failed!\n");
309 return -1;
310 }
311 msleep(10); /* Delay until clock is stable for 2 cycles */
312 }
313
314 /* Enable POWERUP signal */
315 if (pdata->powerup) {
316 gpio_set_value(pdata->powerup, 1);
317 msleep(250); /* or more..? */
318 }
319 /* Enable RSTn signal */
320 if (pdata->reset) {
321 gpio_set_value(pdata->reset, 1);
322 msleep(50); /* Or more..? */
323 }
324 return 0;
325}
326
327static size_t cw1200_spi_align_size(struct hwbus_priv *self, size_t size)
328{
329 return size & 1 ? size + 1 : size;
330}
331
332static int cw1200_spi_pm(struct hwbus_priv *self, bool suspend)
333{
334 return irq_set_irq_wake(self->func->irq, suspend);
335}
336
337static struct hwbus_ops cw1200_spi_hwbus_ops = {
338 .hwbus_memcpy_fromio = cw1200_spi_memcpy_fromio,
339 .hwbus_memcpy_toio = cw1200_spi_memcpy_toio,
340 .lock = cw1200_spi_lock,
341 .unlock = cw1200_spi_unlock,
342 .align_size = cw1200_spi_align_size,
343 .power_mgmt = cw1200_spi_pm,
344};
345
346/* Probe Function to be called by SPI stack when device is discovered */
347static int cw1200_spi_probe(struct spi_device *func)
348{
349 const struct cw1200_platform_data_spi *plat_data =
350 func->dev.platform_data;
351 struct hwbus_priv *self;
352 int status;
353
354 /* Sanity check speed */
355 if (func->max_speed_hz > 52000000)
356 func->max_speed_hz = 52000000;
357 if (func->max_speed_hz < 1000000)
358 func->max_speed_hz = 1000000;
359
360 /* Fix up transfer size */
361 if (plat_data->spi_bits_per_word)
362 func->bits_per_word = plat_data->spi_bits_per_word;
363 if (!func->bits_per_word)
364 func->bits_per_word = 16;
365
366 /* And finally.. */
367 func->mode = SPI_MODE_0;
368
369 pr_info("cw1200_wlan_spi: Probe called (CS %d M %d BPW %d CLK %d)\n",
370 func->chip_select, func->mode, func->bits_per_word,
371 func->max_speed_hz);
372
373 if (cw1200_spi_on(plat_data)) {
374 pr_err("spi_on() failed!\n");
375 return -1;
376 }
377
378 if (spi_setup(func)) {
379 pr_err("spi_setup() failed!\n");
380 return -1;
381 }
382
383 self = kzalloc(sizeof(*self), GFP_KERNEL);
384 if (!self) {
385 pr_err("Can't allocate SPI hwbus_priv.");
386 return -ENOMEM;
387 }
388
389 self->pdata = plat_data;
390 self->func = func;
391 spin_lock_init(&self->lock);
392
393 spi_set_drvdata(func, self);
394
395 status = cw1200_spi_irq_subscribe(self);
396
397 status = cw1200_core_probe(&cw1200_spi_hwbus_ops,
398 self, &func->dev, &self->core,
399 self->pdata->ref_clk,
400 self->pdata->macaddr,
401 self->pdata->sdd_file,
402 self->pdata->have_5ghz);
403
404 if (status) {
405 cw1200_spi_irq_unsubscribe(self);
406 cw1200_spi_off(plat_data);
407 kfree(self);
408 }
409
410 return status;
411}
412
413/* Disconnect Function to be called by SPI stack when device is disconnected */
414static int cw1200_spi_disconnect(struct spi_device *func)
415{
416 struct hwbus_priv *self = spi_get_drvdata(func);
417
418 if (self) {
419 cw1200_spi_irq_unsubscribe(self);
420 if (self->core) {
421 cw1200_core_release(self->core);
422 self->core = NULL;
423 }
424 kfree(self);
425 }
426 cw1200_spi_off(func->dev.platform_data);
427
428 return 0;
429}
430
431#ifdef CONFIG_PM
432static int cw1200_spi_suspend(struct device *dev, pm_message_t state)
433{
434 struct hwbus_priv *self = spi_get_drvdata(to_spi_device(dev));
435
436 if (!cw1200_can_suspend(self->core))
437 return -EAGAIN;
438
439 /* XXX notify host that we have to keep CW1200 powered on? */
440 return 0;
441}
442
443static int cw1200_spi_resume(struct device *dev)
444{
445 return 0;
446}
447#endif
448
449static struct spi_driver spi_driver = {
450 .probe = cw1200_spi_probe,
451 .remove = cw1200_spi_disconnect,
452 .driver = {
453 .name = "cw1200_wlan_spi",
454 .bus = &spi_bus_type,
455 .owner = THIS_MODULE,
456#ifdef CONFIG_PM
457 .suspend = cw1200_spi_suspend,
458 .resume = cw1200_spi_resume,
459#endif
460 },
461};
462
463module_spi_driver(spi_driver);
diff --git a/drivers/net/wireless/cw1200/debug.c b/drivers/net/wireless/cw1200/debug.c
new file mode 100644
index 000000000000..e323b4d54338
--- /dev/null
+++ b/drivers/net/wireless/cw1200/debug.c
@@ -0,0 +1,428 @@
1/*
2 * mac80211 glue code for mac80211 ST-Ericsson CW1200 drivers
3 * DebugFS code
4 *
5 * Copyright (c) 2010, ST-Ericsson
6 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/module.h>
14#include <linux/debugfs.h>
15#include <linux/seq_file.h>
16#include "cw1200.h"
17#include "debug.h"
18#include "fwio.h"
19
20/* join_status */
21static const char * const cw1200_debug_join_status[] = {
22 "passive",
23 "monitor",
24 "station (joining)",
25 "station (not authenticated yet)",
26 "station",
27 "adhoc",
28 "access point",
29};
30
31/* WSM_JOIN_PREAMBLE_... */
32static const char * const cw1200_debug_preamble[] = {
33 "long",
34 "short",
35 "long on 1 and 2 Mbps",
36};
37
38
39static const char * const cw1200_debug_link_id[] = {
40 "OFF",
41 "REQ",
42 "SOFT",
43 "HARD",
44};
45
46static const char *cw1200_debug_mode(int mode)
47{
48 switch (mode) {
49 case NL80211_IFTYPE_UNSPECIFIED:
50 return "unspecified";
51 case NL80211_IFTYPE_MONITOR:
52 return "monitor";
53 case NL80211_IFTYPE_STATION:
54 return "station";
55 case NL80211_IFTYPE_ADHOC:
56 return "adhoc";
57 case NL80211_IFTYPE_MESH_POINT:
58 return "mesh point";
59 case NL80211_IFTYPE_AP:
60 return "access point";
61 case NL80211_IFTYPE_P2P_CLIENT:
62 return "p2p client";
63 case NL80211_IFTYPE_P2P_GO:
64 return "p2p go";
65 default:
66 return "unsupported";
67 }
68}
69
70static void cw1200_queue_status_show(struct seq_file *seq,
71 struct cw1200_queue *q)
72{
73 int i;
74 seq_printf(seq, "Queue %d:\n", q->queue_id);
75 seq_printf(seq, " capacity: %zu\n", q->capacity);
76 seq_printf(seq, " queued: %zu\n", q->num_queued);
77 seq_printf(seq, " pending: %zu\n", q->num_pending);
78 seq_printf(seq, " sent: %zu\n", q->num_sent);
79 seq_printf(seq, " locked: %s\n", q->tx_locked_cnt ? "yes" : "no");
80 seq_printf(seq, " overfull: %s\n", q->overfull ? "yes" : "no");
81 seq_puts(seq, " link map: 0-> ");
82 for (i = 0; i < q->stats->map_capacity; ++i)
83 seq_printf(seq, "%.2d ", q->link_map_cache[i]);
84 seq_printf(seq, "<-%zu\n", q->stats->map_capacity);
85}
86
87static void cw1200_debug_print_map(struct seq_file *seq,
88 struct cw1200_common *priv,
89 const char *label,
90 u32 map)
91{
92 int i;
93 seq_printf(seq, "%s0-> ", label);
94 for (i = 0; i < priv->tx_queue_stats.map_capacity; ++i)
95 seq_printf(seq, "%s ", (map & BIT(i)) ? "**" : "..");
96 seq_printf(seq, "<-%zu\n", priv->tx_queue_stats.map_capacity - 1);
97}
98
99static int cw1200_status_show(struct seq_file *seq, void *v)
100{
101 int i;
102 struct list_head *item;
103 struct cw1200_common *priv = seq->private;
104 struct cw1200_debug_priv *d = priv->debug;
105
106 seq_puts(seq, "CW1200 Wireless LAN driver status\n");
107 seq_printf(seq, "Hardware: %d.%d\n",
108 priv->wsm_caps.hw_id,
109 priv->wsm_caps.hw_subid);
110 seq_printf(seq, "Firmware: %s %d.%d\n",
111 cw1200_fw_types[priv->wsm_caps.fw_type],
112 priv->wsm_caps.fw_ver,
113 priv->wsm_caps.fw_build);
114 seq_printf(seq, "FW API: %d\n",
115 priv->wsm_caps.fw_api);
116 seq_printf(seq, "FW caps: 0x%.4X\n",
117 priv->wsm_caps.fw_cap);
118 seq_printf(seq, "FW label: '%s'\n",
119 priv->wsm_caps.fw_label);
120 seq_printf(seq, "Mode: %s%s\n",
121 cw1200_debug_mode(priv->mode),
122 priv->listening ? " (listening)" : "");
123 seq_printf(seq, "Join state: %s\n",
124 cw1200_debug_join_status[priv->join_status]);
125 if (priv->channel)
126 seq_printf(seq, "Channel: %d%s\n",
127 priv->channel->hw_value,
128 priv->channel_switch_in_progress ?
129 " (switching)" : "");
130 if (priv->rx_filter.promiscuous)
131 seq_puts(seq, "Filter: promisc\n");
132 else if (priv->rx_filter.fcs)
133 seq_puts(seq, "Filter: fcs\n");
134 if (priv->rx_filter.bssid)
135 seq_puts(seq, "Filter: bssid\n");
136 if (!priv->disable_beacon_filter)
137 seq_puts(seq, "Filter: beacons\n");
138
139 if (priv->enable_beacon ||
140 priv->mode == NL80211_IFTYPE_AP ||
141 priv->mode == NL80211_IFTYPE_ADHOC ||
142 priv->mode == NL80211_IFTYPE_MESH_POINT ||
143 priv->mode == NL80211_IFTYPE_P2P_GO)
144 seq_printf(seq, "Beaconing: %s\n",
145 priv->enable_beacon ?
146 "enabled" : "disabled");
147
148 for (i = 0; i < 4; ++i)
149 seq_printf(seq, "EDCA(%d): %d, %d, %d, %d, %d\n", i,
150 priv->edca.params[i].cwmin,
151 priv->edca.params[i].cwmax,
152 priv->edca.params[i].aifns,
153 priv->edca.params[i].txop_limit,
154 priv->edca.params[i].max_rx_lifetime);
155
156 if (priv->join_status == CW1200_JOIN_STATUS_STA) {
157 static const char *pm_mode = "unknown";
158 switch (priv->powersave_mode.mode) {
159 case WSM_PSM_ACTIVE:
160 pm_mode = "off";
161 break;
162 case WSM_PSM_PS:
163 pm_mode = "on";
164 break;
165 case WSM_PSM_FAST_PS:
166 pm_mode = "dynamic";
167 break;
168 }
169 seq_printf(seq, "Preamble: %s\n",
170 cw1200_debug_preamble[priv->association_mode.preamble]);
171 seq_printf(seq, "AMPDU spcn: %d\n",
172 priv->association_mode.mpdu_start_spacing);
173 seq_printf(seq, "Basic rate: 0x%.8X\n",
174 le32_to_cpu(priv->association_mode.basic_rate_set));
175 seq_printf(seq, "Bss lost: %d beacons\n",
176 priv->bss_params.beacon_lost_count);
177 seq_printf(seq, "AID: %d\n",
178 priv->bss_params.aid);
179 seq_printf(seq, "Rates: 0x%.8X\n",
180 priv->bss_params.operational_rate_set);
181 seq_printf(seq, "Powersave: %s\n", pm_mode);
182 }
183 seq_printf(seq, "HT: %s\n",
184 cw1200_is_ht(&priv->ht_info) ? "on" : "off");
185 if (cw1200_is_ht(&priv->ht_info)) {
186 seq_printf(seq, "Greenfield: %s\n",
187 cw1200_ht_greenfield(&priv->ht_info) ? "yes" : "no");
188 seq_printf(seq, "AMPDU dens: %d\n",
189 cw1200_ht_ampdu_density(&priv->ht_info));
190 }
191 seq_printf(seq, "RSSI thold: %d\n",
192 priv->cqm_rssi_thold);
193 seq_printf(seq, "RSSI hyst: %d\n",
194 priv->cqm_rssi_hyst);
195 seq_printf(seq, "Long retr: %d\n",
196 priv->long_frame_max_tx_count);
197 seq_printf(seq, "Short retr: %d\n",
198 priv->short_frame_max_tx_count);
199 spin_lock_bh(&priv->tx_policy_cache.lock);
200 i = 0;
201 list_for_each(item, &priv->tx_policy_cache.used)
202 ++i;
203 spin_unlock_bh(&priv->tx_policy_cache.lock);
204 seq_printf(seq, "RC in use: %d\n", i);
205
206 seq_puts(seq, "\n");
207 for (i = 0; i < 4; ++i) {
208 cw1200_queue_status_show(seq, &priv->tx_queue[i]);
209 seq_puts(seq, "\n");
210 }
211
212 cw1200_debug_print_map(seq, priv, "Link map: ",
213 priv->link_id_map);
214 cw1200_debug_print_map(seq, priv, "Asleep map: ",
215 priv->sta_asleep_mask);
216 cw1200_debug_print_map(seq, priv, "PSPOLL map: ",
217 priv->pspoll_mask);
218
219 seq_puts(seq, "\n");
220
221 for (i = 0; i < CW1200_MAX_STA_IN_AP_MODE; ++i) {
222 if (priv->link_id_db[i].status) {
223 seq_printf(seq, "Link %d: %s, %pM\n",
224 i + 1,
225 cw1200_debug_link_id[priv->link_id_db[i].status],
226 priv->link_id_db[i].mac);
227 }
228 }
229
230 seq_puts(seq, "\n");
231
232 seq_printf(seq, "BH status: %s\n",
233 atomic_read(&priv->bh_term) ? "terminated" : "alive");
234 seq_printf(seq, "Pending RX: %d\n",
235 atomic_read(&priv->bh_rx));
236 seq_printf(seq, "Pending TX: %d\n",
237 atomic_read(&priv->bh_tx));
238 if (priv->bh_error)
239 seq_printf(seq, "BH errcode: %d\n",
240 priv->bh_error);
241 seq_printf(seq, "TX bufs: %d x %d bytes\n",
242 priv->wsm_caps.input_buffers,
243 priv->wsm_caps.input_buffer_size);
244 seq_printf(seq, "Used bufs: %d\n",
245 priv->hw_bufs_used);
246 seq_printf(seq, "Powermgmt: %s\n",
247 priv->powersave_enabled ? "on" : "off");
248 seq_printf(seq, "Device: %s\n",
249 priv->device_can_sleep ? "asleep" : "awake");
250
251 spin_lock(&priv->wsm_cmd.lock);
252 seq_printf(seq, "WSM status: %s\n",
253 priv->wsm_cmd.done ? "idle" : "active");
254 seq_printf(seq, "WSM cmd: 0x%.4X (%td bytes)\n",
255 priv->wsm_cmd.cmd, priv->wsm_cmd.len);
256 seq_printf(seq, "WSM retval: %d\n",
257 priv->wsm_cmd.ret);
258 spin_unlock(&priv->wsm_cmd.lock);
259
260 seq_printf(seq, "Datapath: %s\n",
261 atomic_read(&priv->tx_lock) ? "locked" : "unlocked");
262 if (atomic_read(&priv->tx_lock))
263 seq_printf(seq, "TXlock cnt: %d\n",
264 atomic_read(&priv->tx_lock));
265
266 seq_printf(seq, "TXed: %d\n",
267 d->tx);
268 seq_printf(seq, "AGG TXed: %d\n",
269 d->tx_agg);
270 seq_printf(seq, "MULTI TXed: %d (%d)\n",
271 d->tx_multi, d->tx_multi_frames);
272 seq_printf(seq, "RXed: %d\n",
273 d->rx);
274 seq_printf(seq, "AGG RXed: %d\n",
275 d->rx_agg);
276 seq_printf(seq, "TX miss: %d\n",
277 d->tx_cache_miss);
278 seq_printf(seq, "TX align: %d\n",
279 d->tx_align);
280 seq_printf(seq, "TX burst: %d\n",
281 d->tx_burst);
282 seq_printf(seq, "TX TTL: %d\n",
283 d->tx_ttl);
284 seq_printf(seq, "Scan: %s\n",
285 atomic_read(&priv->scan.in_progress) ? "active" : "idle");
286
287 return 0;
288}
289
290static int cw1200_status_open(struct inode *inode, struct file *file)
291{
292 return single_open(file, &cw1200_status_show,
293 inode->i_private);
294}
295
296static const struct file_operations fops_status = {
297 .open = cw1200_status_open,
298 .read = seq_read,
299 .llseek = seq_lseek,
300 .release = single_release,
301 .owner = THIS_MODULE,
302};
303
304static int cw1200_counters_show(struct seq_file *seq, void *v)
305{
306 int ret;
307 struct cw1200_common *priv = seq->private;
308 struct wsm_mib_counters_table counters;
309
310 ret = wsm_get_counters_table(priv, &counters);
311 if (ret)
312 return ret;
313
314#define PUT_COUNTER(tab, name) \
315 seq_printf(seq, "%s:" tab "%d\n", #name, \
316 __le32_to_cpu(counters.name))
317
318 PUT_COUNTER("\t\t", plcp_errors);
319 PUT_COUNTER("\t\t", fcs_errors);
320 PUT_COUNTER("\t\t", tx_packets);
321 PUT_COUNTER("\t\t", rx_packets);
322 PUT_COUNTER("\t\t", rx_packet_errors);
323 PUT_COUNTER("\t", rx_decryption_failures);
324 PUT_COUNTER("\t\t", rx_mic_failures);
325 PUT_COUNTER("\t", rx_no_key_failures);
326 PUT_COUNTER("\t", tx_multicast_frames);
327 PUT_COUNTER("\t", tx_frames_success);
328 PUT_COUNTER("\t", tx_frame_failures);
329 PUT_COUNTER("\t", tx_frames_retried);
330 PUT_COUNTER("\t", tx_frames_multi_retried);
331 PUT_COUNTER("\t", rx_frame_duplicates);
332 PUT_COUNTER("\t\t", rts_success);
333 PUT_COUNTER("\t\t", rts_failures);
334 PUT_COUNTER("\t\t", ack_failures);
335 PUT_COUNTER("\t", rx_multicast_frames);
336 PUT_COUNTER("\t", rx_frames_success);
337 PUT_COUNTER("\t", rx_cmac_icv_errors);
338 PUT_COUNTER("\t\t", rx_cmac_replays);
339 PUT_COUNTER("\t", rx_mgmt_ccmp_replays);
340
341#undef PUT_COUNTER
342
343 return 0;
344}
345
346static int cw1200_counters_open(struct inode *inode, struct file *file)
347{
348 return single_open(file, &cw1200_counters_show,
349 inode->i_private);
350}
351
352static const struct file_operations fops_counters = {
353 .open = cw1200_counters_open,
354 .read = seq_read,
355 .llseek = seq_lseek,
356 .release = single_release,
357 .owner = THIS_MODULE,
358};
359
360static ssize_t cw1200_wsm_dumps(struct file *file,
361 const char __user *user_buf, size_t count, loff_t *ppos)
362{
363 struct cw1200_common *priv = file->private_data;
364 char buf[1];
365
366 if (!count)
367 return -EINVAL;
368 if (copy_from_user(buf, user_buf, 1))
369 return -EFAULT;
370
371 if (buf[0] == '1')
372 priv->wsm_enable_wsm_dumps = 1;
373 else
374 priv->wsm_enable_wsm_dumps = 0;
375
376 return count;
377}
378
379static const struct file_operations fops_wsm_dumps = {
380 .open = simple_open,
381 .write = cw1200_wsm_dumps,
382 .llseek = default_llseek,
383};
384
385int cw1200_debug_init(struct cw1200_common *priv)
386{
387 int ret = -ENOMEM;
388 struct cw1200_debug_priv *d = kzalloc(sizeof(struct cw1200_debug_priv),
389 GFP_KERNEL);
390 priv->debug = d;
391 if (!d)
392 return ret;
393
394 d->debugfs_phy = debugfs_create_dir("cw1200",
395 priv->hw->wiphy->debugfsdir);
396 if (!d->debugfs_phy)
397 goto err;
398
399 if (!debugfs_create_file("status", S_IRUSR, d->debugfs_phy,
400 priv, &fops_status))
401 goto err;
402
403 if (!debugfs_create_file("counters", S_IRUSR, d->debugfs_phy,
404 priv, &fops_counters))
405 goto err;
406
407 if (!debugfs_create_file("wsm_dumps", S_IWUSR, d->debugfs_phy,
408 priv, &fops_wsm_dumps))
409 goto err;
410
411 return 0;
412
413err:
414 priv->debug = NULL;
415 debugfs_remove_recursive(d->debugfs_phy);
416 kfree(d);
417 return ret;
418}
419
420void cw1200_debug_release(struct cw1200_common *priv)
421{
422 struct cw1200_debug_priv *d = priv->debug;
423 if (d) {
424 debugfs_remove_recursive(d->debugfs_phy);
425 priv->debug = NULL;
426 kfree(d);
427 }
428}
diff --git a/drivers/net/wireless/cw1200/debug.h b/drivers/net/wireless/cw1200/debug.h
new file mode 100644
index 000000000000..b525aba53bfc
--- /dev/null
+++ b/drivers/net/wireless/cw1200/debug.h
@@ -0,0 +1,93 @@
1/*
2 * DebugFS code for ST-Ericsson CW1200 mac80211 driver
3 *
4 * Copyright (c) 2011, ST-Ericsson
5 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#ifndef CW1200_DEBUG_H_INCLUDED
13#define CW1200_DEBUG_H_INCLUDED
14
15struct cw1200_debug_priv {
16 struct dentry *debugfs_phy;
17 int tx;
18 int tx_agg;
19 int rx;
20 int rx_agg;
21 int tx_multi;
22 int tx_multi_frames;
23 int tx_cache_miss;
24 int tx_align;
25 int tx_ttl;
26 int tx_burst;
27 int ba_cnt;
28 int ba_acc;
29 int ba_cnt_rx;
30 int ba_acc_rx;
31};
32
33int cw1200_debug_init(struct cw1200_common *priv);
34void cw1200_debug_release(struct cw1200_common *priv);
35
36static inline void cw1200_debug_txed(struct cw1200_common *priv)
37{
38 ++priv->debug->tx;
39}
40
41static inline void cw1200_debug_txed_agg(struct cw1200_common *priv)
42{
43 ++priv->debug->tx_agg;
44}
45
46static inline void cw1200_debug_txed_multi(struct cw1200_common *priv,
47 int count)
48{
49 ++priv->debug->tx_multi;
50 priv->debug->tx_multi_frames += count;
51}
52
53static inline void cw1200_debug_rxed(struct cw1200_common *priv)
54{
55 ++priv->debug->rx;
56}
57
58static inline void cw1200_debug_rxed_agg(struct cw1200_common *priv)
59{
60 ++priv->debug->rx_agg;
61}
62
63static inline void cw1200_debug_tx_cache_miss(struct cw1200_common *priv)
64{
65 ++priv->debug->tx_cache_miss;
66}
67
68static inline void cw1200_debug_tx_align(struct cw1200_common *priv)
69{
70 ++priv->debug->tx_align;
71}
72
73static inline void cw1200_debug_tx_ttl(struct cw1200_common *priv)
74{
75 ++priv->debug->tx_ttl;
76}
77
78static inline void cw1200_debug_tx_burst(struct cw1200_common *priv)
79{
80 ++priv->debug->tx_burst;
81}
82
83static inline void cw1200_debug_ba(struct cw1200_common *priv,
84 int ba_cnt, int ba_acc,
85 int ba_cnt_rx, int ba_acc_rx)
86{
87 priv->debug->ba_cnt = ba_cnt;
88 priv->debug->ba_acc = ba_acc;
89 priv->debug->ba_cnt_rx = ba_cnt_rx;
90 priv->debug->ba_acc_rx = ba_acc_rx;
91}
92
93#endif /* CW1200_DEBUG_H_INCLUDED */
diff --git a/drivers/net/wireless/cw1200/fwio.c b/drivers/net/wireless/cw1200/fwio.c
new file mode 100644
index 000000000000..acdff0f7f952
--- /dev/null
+++ b/drivers/net/wireless/cw1200/fwio.c
@@ -0,0 +1,520 @@
1/*
2 * Firmware I/O code for mac80211 ST-Ericsson CW1200 drivers
3 *
4 * Copyright (c) 2010, ST-Ericsson
5 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6 *
7 * Based on:
8 * ST-Ericsson UMAC CW1200 driver which is
9 * Copyright (c) 2010, ST-Ericsson
10 * Author: Ajitpal Singh <ajitpal.singh@stericsson.com>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 */
16
17#include <linux/init.h>
18#include <linux/vmalloc.h>
19#include <linux/sched.h>
20#include <linux/firmware.h>
21
22#include "cw1200.h"
23#include "fwio.h"
24#include "hwio.h"
25#include "hwbus.h"
26#include "bh.h"
27
28static int cw1200_get_hw_type(u32 config_reg_val, int *major_revision)
29{
30 int hw_type = -1;
31 u32 silicon_type = (config_reg_val >> 24) & 0x7;
32 u32 silicon_vers = (config_reg_val >> 31) & 0x1;
33
34 switch (silicon_type) {
35 case 0x00:
36 *major_revision = 1;
37 hw_type = HIF_9000_SILICON_VERSATILE;
38 break;
39 case 0x01:
40 case 0x02: /* CW1x00 */
41 case 0x04: /* CW1x60 */
42 *major_revision = silicon_type;
43 if (silicon_vers)
44 hw_type = HIF_8601_VERSATILE;
45 else
46 hw_type = HIF_8601_SILICON;
47 break;
48 default:
49 break;
50 }
51
52 return hw_type;
53}
54
55static int cw1200_load_firmware_cw1200(struct cw1200_common *priv)
56{
57 int ret, block, num_blocks;
58 unsigned i;
59 u32 val32;
60 u32 put = 0, get = 0;
61 u8 *buf = NULL;
62 const char *fw_path;
63 const struct firmware *firmware = NULL;
64
65 /* Macroses are local. */
66#define APB_WRITE(reg, val) \
67 do { \
68 ret = cw1200_apb_write_32(priv, CW1200_APB(reg), (val)); \
69 if (ret < 0) \
70 goto error; \
71 } while (0)
72#define APB_READ(reg, val) \
73 do { \
74 ret = cw1200_apb_read_32(priv, CW1200_APB(reg), &(val)); \
75 if (ret < 0) \
76 goto error; \
77 } while (0)
78#define REG_WRITE(reg, val) \
79 do { \
80 ret = cw1200_reg_write_32(priv, (reg), (val)); \
81 if (ret < 0) \
82 goto error; \
83 } while (0)
84#define REG_READ(reg, val) \
85 do { \
86 ret = cw1200_reg_read_32(priv, (reg), &(val)); \
87 if (ret < 0) \
88 goto error; \
89 } while (0)
90
91 switch (priv->hw_revision) {
92 case CW1200_HW_REV_CUT10:
93 fw_path = FIRMWARE_CUT10;
94 if (!priv->sdd_path)
95 priv->sdd_path = SDD_FILE_10;
96 break;
97 case CW1200_HW_REV_CUT11:
98 fw_path = FIRMWARE_CUT11;
99 if (!priv->sdd_path)
100 priv->sdd_path = SDD_FILE_11;
101 break;
102 case CW1200_HW_REV_CUT20:
103 fw_path = FIRMWARE_CUT20;
104 if (!priv->sdd_path)
105 priv->sdd_path = SDD_FILE_20;
106 break;
107 case CW1200_HW_REV_CUT22:
108 fw_path = FIRMWARE_CUT22;
109 if (!priv->sdd_path)
110 priv->sdd_path = SDD_FILE_22;
111 break;
112 case CW1X60_HW_REV:
113 fw_path = FIRMWARE_CW1X60;
114 if (!priv->sdd_path)
115 priv->sdd_path = SDD_FILE_CW1X60;
116 break;
117 default:
118 pr_err("Invalid silicon revision %d.\n", priv->hw_revision);
119 return -EINVAL;
120 }
121
122 /* Initialize common registers */
123 APB_WRITE(DOWNLOAD_IMAGE_SIZE_REG, DOWNLOAD_ARE_YOU_HERE);
124 APB_WRITE(DOWNLOAD_PUT_REG, 0);
125 APB_WRITE(DOWNLOAD_GET_REG, 0);
126 APB_WRITE(DOWNLOAD_STATUS_REG, DOWNLOAD_PENDING);
127 APB_WRITE(DOWNLOAD_FLAGS_REG, 0);
128
129 /* Write the NOP Instruction */
130 REG_WRITE(ST90TDS_SRAM_BASE_ADDR_REG_ID, 0xFFF20000);
131 REG_WRITE(ST90TDS_AHB_DPORT_REG_ID, 0xEAFFFFFE);
132
133 /* Release CPU from RESET */
134 REG_READ(ST90TDS_CONFIG_REG_ID, val32);
135 val32 &= ~ST90TDS_CONFIG_CPU_RESET_BIT;
136 REG_WRITE(ST90TDS_CONFIG_REG_ID, val32);
137
138 /* Enable Clock */
139 val32 &= ~ST90TDS_CONFIG_CPU_CLK_DIS_BIT;
140 REG_WRITE(ST90TDS_CONFIG_REG_ID, val32);
141
142 /* Load a firmware file */
143 ret = request_firmware(&firmware, fw_path, priv->pdev);
144 if (ret) {
145 pr_err("Can't load firmware file %s.\n", fw_path);
146 goto error;
147 }
148
149 buf = kmalloc(DOWNLOAD_BLOCK_SIZE, GFP_KERNEL | GFP_DMA);
150 if (!buf) {
151 pr_err("Can't allocate firmware load buffer.\n");
152 ret = -ENOMEM;
153 goto error;
154 }
155
156 /* Check if the bootloader is ready */
157 for (i = 0; i < 100; i += 1 + i / 2) {
158 APB_READ(DOWNLOAD_IMAGE_SIZE_REG, val32);
159 if (val32 == DOWNLOAD_I_AM_HERE)
160 break;
161 mdelay(i);
162 } /* End of for loop */
163
164 if (val32 != DOWNLOAD_I_AM_HERE) {
165 pr_err("Bootloader is not ready.\n");
166 ret = -ETIMEDOUT;
167 goto error;
168 }
169
170 /* Calculcate number of download blocks */
171 num_blocks = (firmware->size - 1) / DOWNLOAD_BLOCK_SIZE + 1;
172
173 /* Updating the length in Download Ctrl Area */
174 val32 = firmware->size; /* Explicit cast from size_t to u32 */
175 APB_WRITE(DOWNLOAD_IMAGE_SIZE_REG, val32);
176
177 /* Firmware downloading loop */
178 for (block = 0; block < num_blocks; block++) {
179 size_t tx_size;
180 size_t block_size;
181
182 /* check the download status */
183 APB_READ(DOWNLOAD_STATUS_REG, val32);
184 if (val32 != DOWNLOAD_PENDING) {
185 pr_err("Bootloader reported error %d.\n", val32);
186 ret = -EIO;
187 goto error;
188 }
189
190 /* loop until put - get <= 24K */
191 for (i = 0; i < 100; i++) {
192 APB_READ(DOWNLOAD_GET_REG, get);
193 if ((put - get) <=
194 (DOWNLOAD_FIFO_SIZE - DOWNLOAD_BLOCK_SIZE))
195 break;
196 mdelay(i);
197 }
198
199 if ((put - get) > (DOWNLOAD_FIFO_SIZE - DOWNLOAD_BLOCK_SIZE)) {
200 pr_err("Timeout waiting for FIFO.\n");
201 ret = -ETIMEDOUT;
202 goto error;
203 }
204
205 /* calculate the block size */
206 tx_size = block_size = min((size_t)(firmware->size - put),
207 (size_t)DOWNLOAD_BLOCK_SIZE);
208
209 memcpy(buf, &firmware->data[put], block_size);
210 if (block_size < DOWNLOAD_BLOCK_SIZE) {
211 memset(&buf[block_size], 0,
212 DOWNLOAD_BLOCK_SIZE - block_size);
213 tx_size = DOWNLOAD_BLOCK_SIZE;
214 }
215
216 /* send the block to sram */
217 ret = cw1200_apb_write(priv,
218 CW1200_APB(DOWNLOAD_FIFO_OFFSET +
219 (put & (DOWNLOAD_FIFO_SIZE - 1))),
220 buf, tx_size);
221 if (ret < 0) {
222 pr_err("Can't write firmware block @ %d!\n",
223 put & (DOWNLOAD_FIFO_SIZE - 1));
224 goto error;
225 }
226
227 /* update the put register */
228 put += block_size;
229 APB_WRITE(DOWNLOAD_PUT_REG, put);
230 } /* End of firmware download loop */
231
232 /* Wait for the download completion */
233 for (i = 0; i < 300; i += 1 + i / 2) {
234 APB_READ(DOWNLOAD_STATUS_REG, val32);
235 if (val32 != DOWNLOAD_PENDING)
236 break;
237 mdelay(i);
238 }
239 if (val32 != DOWNLOAD_SUCCESS) {
240 pr_err("Wait for download completion failed: 0x%.8X\n", val32);
241 ret = -ETIMEDOUT;
242 goto error;
243 } else {
244 pr_info("Firmware download completed.\n");
245 ret = 0;
246 }
247
248error:
249 kfree(buf);
250 if (firmware)
251 release_firmware(firmware);
252 return ret;
253
254#undef APB_WRITE
255#undef APB_READ
256#undef REG_WRITE
257#undef REG_READ
258}
259
260
261static int config_reg_read(struct cw1200_common *priv, u32 *val)
262{
263 switch (priv->hw_type) {
264 case HIF_9000_SILICON_VERSATILE: {
265 u16 val16;
266 int ret = cw1200_reg_read_16(priv,
267 ST90TDS_CONFIG_REG_ID,
268 &val16);
269 if (ret < 0)
270 return ret;
271 *val = val16;
272 return 0;
273 }
274 case HIF_8601_VERSATILE:
275 case HIF_8601_SILICON:
276 default:
277 cw1200_reg_read_32(priv, ST90TDS_CONFIG_REG_ID, val);
278 break;
279 }
280 return 0;
281}
282
283static int config_reg_write(struct cw1200_common *priv, u32 val)
284{
285 switch (priv->hw_type) {
286 case HIF_9000_SILICON_VERSATILE:
287 return cw1200_reg_write_16(priv,
288 ST90TDS_CONFIG_REG_ID,
289 (u16)val);
290 case HIF_8601_VERSATILE:
291 case HIF_8601_SILICON:
292 default:
293 return cw1200_reg_write_32(priv, ST90TDS_CONFIG_REG_ID, val);
294 break;
295 }
296 return 0;
297}
298
299int cw1200_load_firmware(struct cw1200_common *priv)
300{
301 int ret;
302 int i;
303 u32 val32;
304 u16 val16;
305 int major_revision = -1;
306
307 /* Read CONFIG Register */
308 ret = cw1200_reg_read_32(priv, ST90TDS_CONFIG_REG_ID, &val32);
309 if (ret < 0) {
310 pr_err("Can't read config register.\n");
311 goto out;
312 }
313
314 if (val32 == 0 || val32 == 0xffffffff) {
315 pr_err("Bad config register value (0x%08x)\n", val32);
316 ret = -EIO;
317 goto out;
318 }
319
320 priv->hw_type = cw1200_get_hw_type(val32, &major_revision);
321 if (priv->hw_type < 0) {
322 pr_err("Can't deduce hardware type.\n");
323 ret = -ENOTSUPP;
324 goto out;
325 }
326
327 /* Set DPLL Reg value, and read back to confirm writes work */
328 ret = cw1200_reg_write_32(priv, ST90TDS_TSET_GEN_R_W_REG_ID,
329 cw1200_dpll_from_clk(priv->hw_refclk));
330 if (ret < 0) {
331 pr_err("Can't write DPLL register.\n");
332 goto out;
333 }
334
335 msleep(20);
336
337 ret = cw1200_reg_read_32(priv,
338 ST90TDS_TSET_GEN_R_W_REG_ID, &val32);
339 if (ret < 0) {
340 pr_err("Can't read DPLL register.\n");
341 goto out;
342 }
343
344 if (val32 != cw1200_dpll_from_clk(priv->hw_refclk)) {
345 pr_err("Unable to initialise DPLL register. Wrote 0x%.8X, Read 0x%.8X.\n",
346 cw1200_dpll_from_clk(priv->hw_refclk), val32);
347 ret = -EIO;
348 goto out;
349 }
350
351 /* Set wakeup bit in device */
352 ret = cw1200_reg_read_16(priv, ST90TDS_CONTROL_REG_ID, &val16);
353 if (ret < 0) {
354 pr_err("set_wakeup: can't read control register.\n");
355 goto out;
356 }
357
358 ret = cw1200_reg_write_16(priv, ST90TDS_CONTROL_REG_ID,
359 val16 | ST90TDS_CONT_WUP_BIT);
360 if (ret < 0) {
361 pr_err("set_wakeup: can't write control register.\n");
362 goto out;
363 }
364
365 /* Wait for wakeup */
366 for (i = 0; i < 300; i += (1 + i / 2)) {
367 ret = cw1200_reg_read_16(priv,
368 ST90TDS_CONTROL_REG_ID, &val16);
369 if (ret < 0) {
370 pr_err("wait_for_wakeup: can't read control register.\n");
371 goto out;
372 }
373
374 if (val16 & ST90TDS_CONT_RDY_BIT)
375 break;
376
377 msleep(i);
378 }
379
380 if ((val16 & ST90TDS_CONT_RDY_BIT) == 0) {
381 pr_err("wait_for_wakeup: device is not responding.\n");
382 ret = -ETIMEDOUT;
383 goto out;
384 }
385
386 switch (major_revision) {
387 case 1:
388 /* CW1200 Hardware detection logic : Check for CUT1.1 */
389 ret = cw1200_ahb_read_32(priv, CW1200_CUT_ID_ADDR, &val32);
390 if (ret) {
391 pr_err("HW detection: can't read CUT ID.\n");
392 goto out;
393 }
394
395 switch (val32) {
396 case CW1200_CUT_11_ID_STR:
397 pr_info("CW1x00 Cut 1.1 silicon detected.\n");
398 priv->hw_revision = CW1200_HW_REV_CUT11;
399 break;
400 default:
401 pr_info("CW1x00 Cut 1.0 silicon detected.\n");
402 priv->hw_revision = CW1200_HW_REV_CUT10;
403 break;
404 }
405
406 /* According to ST-E, CUT<2.0 has busted BA TID0-3.
407 Just disable it entirely...
408 */
409 priv->ba_rx_tid_mask = 0;
410 priv->ba_tx_tid_mask = 0;
411 break;
412 case 2: {
413 u32 ar1, ar2, ar3;
414 ret = cw1200_ahb_read_32(priv, CW1200_CUT2_ID_ADDR, &ar1);
415 if (ret) {
416 pr_err("(1) HW detection: can't read CUT ID\n");
417 goto out;
418 }
419 ret = cw1200_ahb_read_32(priv, CW1200_CUT2_ID_ADDR + 4, &ar2);
420 if (ret) {
421 pr_err("(2) HW detection: can't read CUT ID.\n");
422 goto out;
423 }
424
425 ret = cw1200_ahb_read_32(priv, CW1200_CUT2_ID_ADDR + 8, &ar3);
426 if (ret) {
427 pr_err("(3) HW detection: can't read CUT ID.\n");
428 goto out;
429 }
430
431 if (ar1 == CW1200_CUT_22_ID_STR1 &&
432 ar2 == CW1200_CUT_22_ID_STR2 &&
433 ar3 == CW1200_CUT_22_ID_STR3) {
434 pr_info("CW1x00 Cut 2.2 silicon detected.\n");
435 priv->hw_revision = CW1200_HW_REV_CUT22;
436 } else {
437 pr_info("CW1x00 Cut 2.0 silicon detected.\n");
438 priv->hw_revision = CW1200_HW_REV_CUT20;
439 }
440 break;
441 }
442 case 4:
443 pr_info("CW1x60 silicon detected.\n");
444 priv->hw_revision = CW1X60_HW_REV;
445 break;
446 default:
447 pr_err("Unsupported silicon major revision %d.\n",
448 major_revision);
449 ret = -ENOTSUPP;
450 goto out;
451 }
452
453 /* Checking for access mode */
454 ret = config_reg_read(priv, &val32);
455 if (ret < 0) {
456 pr_err("Can't read config register.\n");
457 goto out;
458 }
459
460 if (!(val32 & ST90TDS_CONFIG_ACCESS_MODE_BIT)) {
461 pr_err("Device is already in QUEUE mode!\n");
462 ret = -EINVAL;
463 goto out;
464 }
465
466 switch (priv->hw_type) {
467 case HIF_8601_SILICON:
468 if (priv->hw_revision == CW1X60_HW_REV) {
469 pr_err("Can't handle CW1160/1260 firmware load yet.\n");
470 ret = -ENOTSUPP;
471 goto out;
472 }
473 ret = cw1200_load_firmware_cw1200(priv);
474 break;
475 default:
476 pr_err("Can't perform firmware load for hw type %d.\n",
477 priv->hw_type);
478 ret = -ENOTSUPP;
479 goto out;
480 }
481 if (ret < 0) {
482 pr_err("Firmware load error.\n");
483 goto out;
484 }
485
486 /* Enable interrupt signalling */
487 priv->hwbus_ops->lock(priv->hwbus_priv);
488 ret = __cw1200_irq_enable(priv, 1);
489 priv->hwbus_ops->unlock(priv->hwbus_priv);
490 if (ret < 0)
491 goto unsubscribe;
492
493 /* Configure device for MESSSAGE MODE */
494 ret = config_reg_read(priv, &val32);
495 if (ret < 0) {
496 pr_err("Can't read config register.\n");
497 goto unsubscribe;
498 }
499 ret = config_reg_write(priv, val32 & ~ST90TDS_CONFIG_ACCESS_MODE_BIT);
500 if (ret < 0) {
501 pr_err("Can't write config register.\n");
502 goto unsubscribe;
503 }
504
505 /* Unless we read the CONFIG Register we are
506 * not able to get an interrupt
507 */
508 mdelay(10);
509 config_reg_read(priv, &val32);
510
511out:
512 return ret;
513
514unsubscribe:
515 /* Disable interrupt signalling */
516 priv->hwbus_ops->lock(priv->hwbus_priv);
517 ret = __cw1200_irq_enable(priv, 0);
518 priv->hwbus_ops->unlock(priv->hwbus_priv);
519 return ret;
520}
diff --git a/drivers/net/wireless/cw1200/fwio.h b/drivers/net/wireless/cw1200/fwio.h
new file mode 100644
index 000000000000..ea3099362cdf
--- /dev/null
+++ b/drivers/net/wireless/cw1200/fwio.h
@@ -0,0 +1,39 @@
1/*
2 * Firmware API for mac80211 ST-Ericsson CW1200 drivers
3 *
4 * Copyright (c) 2010, ST-Ericsson
5 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6 *
7 * Based on:
8 * ST-Ericsson UMAC CW1200 driver which is
9 * Copyright (c) 2010, ST-Ericsson
10 * Author: Ajitpal Singh <ajitpal.singh@stericsson.com>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 */
16
17#ifndef FWIO_H_INCLUDED
18#define FWIO_H_INCLUDED
19
20#define BOOTLOADER_CW1X60 "boot_cw1x60.bin"
21#define FIRMWARE_CW1X60 "wsm_cw1x60.bin"
22#define FIRMWARE_CUT22 "wsm_22.bin"
23#define FIRMWARE_CUT20 "wsm_20.bin"
24#define FIRMWARE_CUT11 "wsm_11.bin"
25#define FIRMWARE_CUT10 "wsm_10.bin"
26#define SDD_FILE_CW1X60 "sdd_cw1x60.bin"
27#define SDD_FILE_22 "sdd_22.bin"
28#define SDD_FILE_20 "sdd_20.bin"
29#define SDD_FILE_11 "sdd_11.bin"
30#define SDD_FILE_10 "sdd_10.bin"
31
32int cw1200_load_firmware(struct cw1200_common *priv);
33
34/* SDD definitions */
35#define SDD_PTA_CFG_ELT_ID 0xEB
36#define SDD_REFERENCE_FREQUENCY_ELT_ID 0xc5
37u32 cw1200_dpll_from_clk(u16 clk);
38
39#endif
diff --git a/drivers/net/wireless/cw1200/hwbus.h b/drivers/net/wireless/cw1200/hwbus.h
new file mode 100644
index 000000000000..8b2fc831c3de
--- /dev/null
+++ b/drivers/net/wireless/cw1200/hwbus.h
@@ -0,0 +1,33 @@
1/*
2 * Common hwbus abstraction layer interface for cw1200 wireless driver
3 *
4 * Copyright (c) 2010, ST-Ericsson
5 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#ifndef CW1200_HWBUS_H
13#define CW1200_HWBUS_H
14
15struct hwbus_priv;
16
17void cw1200_irq_handler(struct cw1200_common *priv);
18
19/* This MUST be wrapped with hwbus_ops->lock/unlock! */
20int __cw1200_irq_enable(struct cw1200_common *priv, int enable);
21
22struct hwbus_ops {
23 int (*hwbus_memcpy_fromio)(struct hwbus_priv *self, unsigned int addr,
24 void *dst, int count);
25 int (*hwbus_memcpy_toio)(struct hwbus_priv *self, unsigned int addr,
26 const void *src, int count);
27 void (*lock)(struct hwbus_priv *self);
28 void (*unlock)(struct hwbus_priv *self);
29 size_t (*align_size)(struct hwbus_priv *self, size_t size);
30 int (*power_mgmt)(struct hwbus_priv *self, bool suspend);
31};
32
33#endif /* CW1200_HWBUS_H */
diff --git a/drivers/net/wireless/cw1200/hwio.c b/drivers/net/wireless/cw1200/hwio.c
new file mode 100644
index 000000000000..dad3fb331818
--- /dev/null
+++ b/drivers/net/wireless/cw1200/hwio.c
@@ -0,0 +1,310 @@
1/*
2 * Low-level device IO routines for ST-Ericsson CW1200 drivers
3 *
4 * Copyright (c) 2010, ST-Ericsson
5 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6 *
7 * Based on:
8 * ST-Ericsson UMAC CW1200 driver, which is
9 * Copyright (c) 2010, ST-Ericsson
10 * Author: Ajitpal Singh <ajitpal.singh@lockless.no>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 */
16
17#include <linux/types.h>
18
19#include "cw1200.h"
20#include "hwio.h"
21#include "hwbus.h"
22
23 /* Sdio addr is 4*spi_addr */
24#define SPI_REG_ADDR_TO_SDIO(spi_reg_addr) ((spi_reg_addr) << 2)
25#define SDIO_ADDR17BIT(buf_id, mpf, rfu, reg_id_ofs) \
26 ((((buf_id) & 0x1F) << 7) \
27 | (((mpf) & 1) << 6) \
28 | (((rfu) & 1) << 5) \
29 | (((reg_id_ofs) & 0x1F) << 0))
30#define MAX_RETRY 3
31
32
33static int __cw1200_reg_read(struct cw1200_common *priv, u16 addr,
34 void *buf, size_t buf_len, int buf_id)
35{
36 u16 addr_sdio;
37 u32 sdio_reg_addr_17bit;
38
39 /* Check if buffer is aligned to 4 byte boundary */
40 if (WARN_ON(((unsigned long)buf & 3) && (buf_len > 4))) {
41 pr_err("buffer is not aligned.\n");
42 return -EINVAL;
43 }
44
45 /* Convert to SDIO Register Address */
46 addr_sdio = SPI_REG_ADDR_TO_SDIO(addr);
47 sdio_reg_addr_17bit = SDIO_ADDR17BIT(buf_id, 0, 0, addr_sdio);
48
49 return priv->hwbus_ops->hwbus_memcpy_fromio(priv->hwbus_priv,
50 sdio_reg_addr_17bit,
51 buf, buf_len);
52}
53
54static int __cw1200_reg_write(struct cw1200_common *priv, u16 addr,
55 const void *buf, size_t buf_len, int buf_id)
56{
57 u16 addr_sdio;
58 u32 sdio_reg_addr_17bit;
59
60 /* Convert to SDIO Register Address */
61 addr_sdio = SPI_REG_ADDR_TO_SDIO(addr);
62 sdio_reg_addr_17bit = SDIO_ADDR17BIT(buf_id, 0, 0, addr_sdio);
63
64 return priv->hwbus_ops->hwbus_memcpy_toio(priv->hwbus_priv,
65 sdio_reg_addr_17bit,
66 buf, buf_len);
67}
68
69static inline int __cw1200_reg_read_32(struct cw1200_common *priv,
70 u16 addr, u32 *val)
71{
72 int i = __cw1200_reg_read(priv, addr, val, sizeof(*val), 0);
73 *val = le32_to_cpu(*val);
74 return i;
75}
76
77static inline int __cw1200_reg_write_32(struct cw1200_common *priv,
78 u16 addr, u32 val)
79{
80 val = cpu_to_le32(val);
81 return __cw1200_reg_write(priv, addr, &val, sizeof(val), 0);
82}
83
84static inline int __cw1200_reg_read_16(struct cw1200_common *priv,
85 u16 addr, u16 *val)
86{
87 int i = __cw1200_reg_read(priv, addr, val, sizeof(*val), 0);
88 *val = le16_to_cpu(*val);
89 return i;
90}
91
92static inline int __cw1200_reg_write_16(struct cw1200_common *priv,
93 u16 addr, u16 val)
94{
95 val = cpu_to_le16(val);
96 return __cw1200_reg_write(priv, addr, &val, sizeof(val), 0);
97}
98
99int cw1200_reg_read(struct cw1200_common *priv, u16 addr, void *buf,
100 size_t buf_len)
101{
102 int ret;
103 priv->hwbus_ops->lock(priv->hwbus_priv);
104 ret = __cw1200_reg_read(priv, addr, buf, buf_len, 0);
105 priv->hwbus_ops->unlock(priv->hwbus_priv);
106 return ret;
107}
108
109int cw1200_reg_write(struct cw1200_common *priv, u16 addr, const void *buf,
110 size_t buf_len)
111{
112 int ret;
113 priv->hwbus_ops->lock(priv->hwbus_priv);
114 ret = __cw1200_reg_write(priv, addr, buf, buf_len, 0);
115 priv->hwbus_ops->unlock(priv->hwbus_priv);
116 return ret;
117}
118
119int cw1200_data_read(struct cw1200_common *priv, void *buf, size_t buf_len)
120{
121 int ret, retry = 1;
122 int buf_id_rx = priv->buf_id_rx;
123
124 priv->hwbus_ops->lock(priv->hwbus_priv);
125
126 while (retry <= MAX_RETRY) {
127 ret = __cw1200_reg_read(priv,
128 ST90TDS_IN_OUT_QUEUE_REG_ID, buf,
129 buf_len, buf_id_rx + 1);
130 if (!ret) {
131 buf_id_rx = (buf_id_rx + 1) & 3;
132 priv->buf_id_rx = buf_id_rx;
133 break;
134 } else {
135 retry++;
136 mdelay(1);
137 pr_err("error :[%d]\n", ret);
138 }
139 }
140
141 priv->hwbus_ops->unlock(priv->hwbus_priv);
142 return ret;
143}
144
145int cw1200_data_write(struct cw1200_common *priv, const void *buf,
146 size_t buf_len)
147{
148 int ret, retry = 1;
149 int buf_id_tx = priv->buf_id_tx;
150
151 priv->hwbus_ops->lock(priv->hwbus_priv);
152
153 while (retry <= MAX_RETRY) {
154 ret = __cw1200_reg_write(priv,
155 ST90TDS_IN_OUT_QUEUE_REG_ID, buf,
156 buf_len, buf_id_tx);
157 if (!ret) {
158 buf_id_tx = (buf_id_tx + 1) & 31;
159 priv->buf_id_tx = buf_id_tx;
160 break;
161 } else {
162 retry++;
163 mdelay(1);
164 pr_err("error :[%d]\n", ret);
165 }
166 }
167
168 priv->hwbus_ops->unlock(priv->hwbus_priv);
169 return ret;
170}
171
172int cw1200_indirect_read(struct cw1200_common *priv, u32 addr, void *buf,
173 size_t buf_len, u32 prefetch, u16 port_addr)
174{
175 u32 val32 = 0;
176 int i, ret;
177
178 if ((buf_len / 2) >= 0x1000) {
179 pr_err("Can't read more than 0xfff words.\n");
180 return -EINVAL;
181 }
182
183 priv->hwbus_ops->lock(priv->hwbus_priv);
184 /* Write address */
185 ret = __cw1200_reg_write_32(priv, ST90TDS_SRAM_BASE_ADDR_REG_ID, addr);
186 if (ret < 0) {
187 pr_err("Can't write address register.\n");
188 goto out;
189 }
190
191 /* Read CONFIG Register Value - We will read 32 bits */
192 ret = __cw1200_reg_read_32(priv, ST90TDS_CONFIG_REG_ID, &val32);
193 if (ret < 0) {
194 pr_err("Can't read config register.\n");
195 goto out;
196 }
197
198 /* Set PREFETCH bit */
199 ret = __cw1200_reg_write_32(priv, ST90TDS_CONFIG_REG_ID,
200 val32 | prefetch);
201 if (ret < 0) {
202 pr_err("Can't write prefetch bit.\n");
203 goto out;
204 }
205
206 /* Check for PRE-FETCH bit to be cleared */
207 for (i = 0; i < 20; i++) {
208 ret = __cw1200_reg_read_32(priv, ST90TDS_CONFIG_REG_ID, &val32);
209 if (ret < 0) {
210 pr_err("Can't check prefetch bit.\n");
211 goto out;
212 }
213 if (!(val32 & prefetch))
214 break;
215
216 mdelay(i);
217 }
218
219 if (val32 & prefetch) {
220 pr_err("Prefetch bit is not cleared.\n");
221 goto out;
222 }
223
224 /* Read data port */
225 ret = __cw1200_reg_read(priv, port_addr, buf, buf_len, 0);
226 if (ret < 0) {
227 pr_err("Can't read data port.\n");
228 goto out;
229 }
230
231out:
232 priv->hwbus_ops->unlock(priv->hwbus_priv);
233 return ret;
234}
235
236int cw1200_apb_write(struct cw1200_common *priv, u32 addr, const void *buf,
237 size_t buf_len)
238{
239 int ret;
240
241 if ((buf_len / 2) >= 0x1000) {
242 pr_err("Can't write more than 0xfff words.\n");
243 return -EINVAL;
244 }
245
246 priv->hwbus_ops->lock(priv->hwbus_priv);
247
248 /* Write address */
249 ret = __cw1200_reg_write_32(priv, ST90TDS_SRAM_BASE_ADDR_REG_ID, addr);
250 if (ret < 0) {
251 pr_err("Can't write address register.\n");
252 goto out;
253 }
254
255 /* Write data port */
256 ret = __cw1200_reg_write(priv, ST90TDS_SRAM_DPORT_REG_ID,
257 buf, buf_len, 0);
258 if (ret < 0) {
259 pr_err("Can't write data port.\n");
260 goto out;
261 }
262
263out:
264 priv->hwbus_ops->unlock(priv->hwbus_priv);
265 return ret;
266}
267
268int __cw1200_irq_enable(struct cw1200_common *priv, int enable)
269{
270 u32 val32;
271 u16 val16;
272 int ret;
273
274 if (HIF_8601_SILICON == priv->hw_type) {
275 ret = __cw1200_reg_read_32(priv, ST90TDS_CONFIG_REG_ID, &val32);
276 if (ret < 0) {
277 pr_err("Can't read config register.\n");
278 return ret;
279 }
280
281 if (enable)
282 val32 |= ST90TDS_CONF_IRQ_RDY_ENABLE;
283 else
284 val32 &= ~ST90TDS_CONF_IRQ_RDY_ENABLE;
285
286 ret = __cw1200_reg_write_32(priv, ST90TDS_CONFIG_REG_ID, val32);
287 if (ret < 0) {
288 pr_err("Can't write config register.\n");
289 return ret;
290 }
291 } else {
292 ret = __cw1200_reg_read_16(priv, ST90TDS_CONFIG_REG_ID, &val16);
293 if (ret < 0) {
294 pr_err("Can't read control register.\n");
295 return ret;
296 }
297
298 if (enable)
299 val16 |= ST90TDS_CONT_IRQ_RDY_ENABLE;
300 else
301 val16 &= ~ST90TDS_CONT_IRQ_RDY_ENABLE;
302
303 ret = __cw1200_reg_write_16(priv, ST90TDS_CONFIG_REG_ID, val16);
304 if (ret < 0) {
305 pr_err("Can't write control register.\n");
306 return ret;
307 }
308 }
309 return 0;
310}
diff --git a/drivers/net/wireless/cw1200/hwio.h b/drivers/net/wireless/cw1200/hwio.h
new file mode 100644
index 000000000000..563329cfead6
--- /dev/null
+++ b/drivers/net/wireless/cw1200/hwio.h
@@ -0,0 +1,246 @@
1/*
2 * Low-level API for mac80211 ST-Ericsson CW1200 drivers
3 *
4 * Copyright (c) 2010, ST-Ericsson
5 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6 *
7 * Based on:
8 * ST-Ericsson UMAC CW1200 driver which is
9 * Copyright (c) 2010, ST-Ericsson
10 * Author: Ajitpal Singh <ajitpal.singh@stericsson.com>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 */
16
17#ifndef CW1200_HWIO_H_INCLUDED
18#define CW1200_HWIO_H_INCLUDED
19
20/* extern */ struct cw1200_common;
21
22#define CW1200_CUT_11_ID_STR (0x302E3830)
23#define CW1200_CUT_22_ID_STR1 (0x302e3132)
24#define CW1200_CUT_22_ID_STR2 (0x32302e30)
25#define CW1200_CUT_22_ID_STR3 (0x3335)
26#define CW1200_CUT_ID_ADDR (0xFFF17F90)
27#define CW1200_CUT2_ID_ADDR (0xFFF1FF90)
28
29/* Download control area */
30/* boot loader start address in SRAM */
31#define DOWNLOAD_BOOT_LOADER_OFFSET (0x00000000)
32/* 32K, 0x4000 to 0xDFFF */
33#define DOWNLOAD_FIFO_OFFSET (0x00004000)
34/* 32K */
35#define DOWNLOAD_FIFO_SIZE (0x00008000)
36/* 128 bytes, 0xFF80 to 0xFFFF */
37#define DOWNLOAD_CTRL_OFFSET (0x0000FF80)
38#define DOWNLOAD_CTRL_DATA_DWORDS (32-6)
39
40struct download_cntl_t {
41 /* size of whole firmware file (including Cheksum), host init */
42 u32 image_size;
43 /* downloading flags */
44 u32 flags;
45 /* No. of bytes put into the download, init & updated by host */
46 u32 put;
47 /* last traced program counter, last ARM reg_pc */
48 u32 trace_pc;
49 /* No. of bytes read from the download, host init, device updates */
50 u32 get;
51 /* r0, boot losader status, host init to pending, device updates */
52 u32 status;
53 /* Extra debug info, r1 to r14 if status=r0=DOWNLOAD_EXCEPTION */
54 u32 debug_data[DOWNLOAD_CTRL_DATA_DWORDS];
55};
56
57#define DOWNLOAD_IMAGE_SIZE_REG \
58 (DOWNLOAD_CTRL_OFFSET + offsetof(struct download_cntl_t, image_size))
59#define DOWNLOAD_FLAGS_REG \
60 (DOWNLOAD_CTRL_OFFSET + offsetof(struct download_cntl_t, flags))
61#define DOWNLOAD_PUT_REG \
62 (DOWNLOAD_CTRL_OFFSET + offsetof(struct download_cntl_t, put))
63#define DOWNLOAD_TRACE_PC_REG \
64 (DOWNLOAD_CTRL_OFFSET + offsetof(struct download_cntl_t, trace_pc))
65#define DOWNLOAD_GET_REG \
66 (DOWNLOAD_CTRL_OFFSET + offsetof(struct download_cntl_t, get))
67#define DOWNLOAD_STATUS_REG \
68 (DOWNLOAD_CTRL_OFFSET + offsetof(struct download_cntl_t, status))
69#define DOWNLOAD_DEBUG_DATA_REG \
70 (DOWNLOAD_CTRL_OFFSET + offsetof(struct download_cntl_t, debug_data))
71#define DOWNLOAD_DEBUG_DATA_LEN (108)
72
73#define DOWNLOAD_BLOCK_SIZE (1024)
74
75/* For boot loader detection */
76#define DOWNLOAD_ARE_YOU_HERE (0x87654321)
77#define DOWNLOAD_I_AM_HERE (0x12345678)
78
79/* Download error code */
80#define DOWNLOAD_PENDING (0xFFFFFFFF)
81#define DOWNLOAD_SUCCESS (0)
82#define DOWNLOAD_EXCEPTION (1)
83#define DOWNLOAD_ERR_MEM_1 (2)
84#define DOWNLOAD_ERR_MEM_2 (3)
85#define DOWNLOAD_ERR_SOFTWARE (4)
86#define DOWNLOAD_ERR_FILE_SIZE (5)
87#define DOWNLOAD_ERR_CHECKSUM (6)
88#define DOWNLOAD_ERR_OVERFLOW (7)
89#define DOWNLOAD_ERR_IMAGE (8)
90#define DOWNLOAD_ERR_HOST (9)
91#define DOWNLOAD_ERR_ABORT (10)
92
93
94#define SYS_BASE_ADDR_SILICON (0)
95#define PAC_BASE_ADDRESS_SILICON (SYS_BASE_ADDR_SILICON + 0x09000000)
96#define PAC_SHARED_MEMORY_SILICON (PAC_BASE_ADDRESS_SILICON)
97
98#define CW1200_APB(addr) (PAC_SHARED_MEMORY_SILICON + (addr))
99
100/* Device register definitions */
101
102/* WBF - SPI Register Addresses */
103#define ST90TDS_ADDR_ID_BASE (0x0000)
104/* 16/32 bits */
105#define ST90TDS_CONFIG_REG_ID (0x0000)
106/* 16/32 bits */
107#define ST90TDS_CONTROL_REG_ID (0x0001)
108/* 16 bits, Q mode W/R */
109#define ST90TDS_IN_OUT_QUEUE_REG_ID (0x0002)
110/* 32 bits, AHB bus R/W */
111#define ST90TDS_AHB_DPORT_REG_ID (0x0003)
112/* 16/32 bits */
113#define ST90TDS_SRAM_BASE_ADDR_REG_ID (0x0004)
114/* 32 bits, APB bus R/W */
115#define ST90TDS_SRAM_DPORT_REG_ID (0x0005)
116/* 32 bits, t_settle/general */
117#define ST90TDS_TSET_GEN_R_W_REG_ID (0x0006)
118/* 16 bits, Q mode read, no length */
119#define ST90TDS_FRAME_OUT_REG_ID (0x0007)
120#define ST90TDS_ADDR_ID_MAX (ST90TDS_FRAME_OUT_REG_ID)
121
122/* WBF - Control register bit set */
123/* next o/p length, bit 11 to 0 */
124#define ST90TDS_CONT_NEXT_LEN_MASK (0x0FFF)
125#define ST90TDS_CONT_WUP_BIT (BIT(12))
126#define ST90TDS_CONT_RDY_BIT (BIT(13))
127#define ST90TDS_CONT_IRQ_ENABLE (BIT(14))
128#define ST90TDS_CONT_RDY_ENABLE (BIT(15))
129#define ST90TDS_CONT_IRQ_RDY_ENABLE (BIT(14)|BIT(15))
130
131/* SPI Config register bit set */
132#define ST90TDS_CONFIG_FRAME_BIT (BIT(2))
133#define ST90TDS_CONFIG_WORD_MODE_BITS (BIT(3)|BIT(4))
134#define ST90TDS_CONFIG_WORD_MODE_1 (BIT(3))
135#define ST90TDS_CONFIG_WORD_MODE_2 (BIT(4))
136#define ST90TDS_CONFIG_ERROR_0_BIT (BIT(5))
137#define ST90TDS_CONFIG_ERROR_1_BIT (BIT(6))
138#define ST90TDS_CONFIG_ERROR_2_BIT (BIT(7))
139/* TBD: Sure??? */
140#define ST90TDS_CONFIG_CSN_FRAME_BIT (BIT(7))
141#define ST90TDS_CONFIG_ERROR_3_BIT (BIT(8))
142#define ST90TDS_CONFIG_ERROR_4_BIT (BIT(9))
143/* QueueM */
144#define ST90TDS_CONFIG_ACCESS_MODE_BIT (BIT(10))
145/* AHB bus */
146#define ST90TDS_CONFIG_AHB_PRFETCH_BIT (BIT(11))
147#define ST90TDS_CONFIG_CPU_CLK_DIS_BIT (BIT(12))
148/* APB bus */
149#define ST90TDS_CONFIG_PRFETCH_BIT (BIT(13))
150/* cpu reset */
151#define ST90TDS_CONFIG_CPU_RESET_BIT (BIT(14))
152#define ST90TDS_CONFIG_CLEAR_INT_BIT (BIT(15))
153
154/* For CW1200 the IRQ Enable and Ready Bits are in CONFIG register */
155#define ST90TDS_CONF_IRQ_ENABLE (BIT(16))
156#define ST90TDS_CONF_RDY_ENABLE (BIT(17))
157#define ST90TDS_CONF_IRQ_RDY_ENABLE (BIT(16)|BIT(17))
158
159int cw1200_data_read(struct cw1200_common *priv,
160 void *buf, size_t buf_len);
161int cw1200_data_write(struct cw1200_common *priv,
162 const void *buf, size_t buf_len);
163
164int cw1200_reg_read(struct cw1200_common *priv, u16 addr,
165 void *buf, size_t buf_len);
166int cw1200_reg_write(struct cw1200_common *priv, u16 addr,
167 const void *buf, size_t buf_len);
168
169static inline int cw1200_reg_read_16(struct cw1200_common *priv,
170 u16 addr, u16 *val)
171{
172 u32 tmp;
173 int i;
174 i = cw1200_reg_read(priv, addr, &tmp, sizeof(tmp));
175 tmp = le32_to_cpu(tmp);
176 *val = tmp & 0xffff;
177 return i;
178}
179
180static inline int cw1200_reg_write_16(struct cw1200_common *priv,
181 u16 addr, u16 val)
182{
183 u32 tmp = val;
184 tmp = cpu_to_le32(tmp);
185 return cw1200_reg_write(priv, addr, &tmp, sizeof(tmp));
186}
187
188static inline int cw1200_reg_read_32(struct cw1200_common *priv,
189 u16 addr, u32 *val)
190{
191 int i = cw1200_reg_read(priv, addr, val, sizeof(*val));
192 *val = le32_to_cpu(*val);
193 return i;
194}
195
196static inline int cw1200_reg_write_32(struct cw1200_common *priv,
197 u16 addr, u32 val)
198{
199 val = cpu_to_le32(val);
200 return cw1200_reg_write(priv, addr, &val, sizeof(val));
201}
202
203int cw1200_indirect_read(struct cw1200_common *priv, u32 addr, void *buf,
204 size_t buf_len, u32 prefetch, u16 port_addr);
205int cw1200_apb_write(struct cw1200_common *priv, u32 addr, const void *buf,
206 size_t buf_len);
207
208static inline int cw1200_apb_read(struct cw1200_common *priv, u32 addr,
209 void *buf, size_t buf_len)
210{
211 return cw1200_indirect_read(priv, addr, buf, buf_len,
212 ST90TDS_CONFIG_PRFETCH_BIT,
213 ST90TDS_SRAM_DPORT_REG_ID);
214}
215
216static inline int cw1200_ahb_read(struct cw1200_common *priv, u32 addr,
217 void *buf, size_t buf_len)
218{
219 return cw1200_indirect_read(priv, addr, buf, buf_len,
220 ST90TDS_CONFIG_AHB_PRFETCH_BIT,
221 ST90TDS_AHB_DPORT_REG_ID);
222}
223
224static inline int cw1200_apb_read_32(struct cw1200_common *priv,
225 u32 addr, u32 *val)
226{
227 int i = cw1200_apb_read(priv, addr, val, sizeof(*val));
228 *val = le32_to_cpu(*val);
229 return i;
230}
231
232static inline int cw1200_apb_write_32(struct cw1200_common *priv,
233 u32 addr, u32 val)
234{
235 val = cpu_to_le32(val);
236 return cw1200_apb_write(priv, addr, &val, sizeof(val));
237}
238static inline int cw1200_ahb_read_32(struct cw1200_common *priv,
239 u32 addr, u32 *val)
240{
241 int i = cw1200_ahb_read(priv, addr, val, sizeof(*val));
242 *val = le32_to_cpu(*val);
243 return i;
244}
245
246#endif /* CW1200_HWIO_H_INCLUDED */
diff --git a/drivers/net/wireless/cw1200/main.c b/drivers/net/wireless/cw1200/main.c
new file mode 100644
index 000000000000..9f9adb4fbfb8
--- /dev/null
+++ b/drivers/net/wireless/cw1200/main.c
@@ -0,0 +1,600 @@
1/*
2 * mac80211 glue code for mac80211 ST-Ericsson CW1200 drivers
3 *
4 * Copyright (c) 2010, ST-Ericsson
5 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6 *
7 * Based on:
8 * Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net>
9 * Copyright (c) 2007-2009, Christian Lamparter <chunkeey@web.de>
10 * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
11 *
12 * Based on:
13 * - the islsm (softmac prism54) driver, which is:
14 * Copyright 2004-2006 Jean-Baptiste Note <jbnote@gmail.com>, et al.
15 * - stlc45xx driver
16 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
17 *
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License version 2 as
20 * published by the Free Software Foundation.
21 */
22
23#include <linux/module.h>
24#include <linux/init.h>
25#include <linux/firmware.h>
26#include <linux/etherdevice.h>
27#include <linux/vmalloc.h>
28#include <linux/random.h>
29#include <linux/sched.h>
30#include <net/mac80211.h>
31
32#include "cw1200.h"
33#include "txrx.h"
34#include "hwbus.h"
35#include "fwio.h"
36#include "hwio.h"
37#include "bh.h"
38#include "sta.h"
39#include "scan.h"
40#include "debug.h"
41#include "pm.h"
42
43MODULE_AUTHOR("Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>");
44MODULE_DESCRIPTION("Softmac ST-Ericsson CW1200 common code");
45MODULE_LICENSE("GPL");
46MODULE_ALIAS("cw1200_core");
47
48/* Accept MAC address of the form macaddr=0x00,0x80,0xE1,0x30,0x40,0x50 */
49static u8 cw1200_mac_template[ETH_ALEN] = {0x02, 0x80, 0xe1, 0x00, 0x00, 0x00};
50module_param_array_named(macaddr, cw1200_mac_template, byte, NULL, S_IRUGO);
51MODULE_PARM_DESC(macaddr, "Override platform_data MAC address");
52
53static char *cw1200_sdd_path;
54module_param(cw1200_sdd_path, charp, 0644);
55MODULE_PARM_DESC(cw1200_sdd_path, "Override platform_data SDD file");
56static int cw1200_refclk;
57module_param(cw1200_refclk, int, 0644);
58MODULE_PARM_DESC(cw1200_refclk, "Override platform_data reference clock");
59
60int cw1200_power_mode = wsm_power_mode_quiescent;
61module_param(cw1200_power_mode, int, 0644);
62MODULE_PARM_DESC(cw1200_power_mode, "WSM power mode. 0 == active, 1 == doze, 2 == quiescent (default)");
63
64#define RATETAB_ENT(_rate, _rateid, _flags) \
65 { \
66 .bitrate = (_rate), \
67 .hw_value = (_rateid), \
68 .flags = (_flags), \
69 }
70
71static struct ieee80211_rate cw1200_rates[] = {
72 RATETAB_ENT(10, 0, 0),
73 RATETAB_ENT(20, 1, 0),
74 RATETAB_ENT(55, 2, 0),
75 RATETAB_ENT(110, 3, 0),
76 RATETAB_ENT(60, 6, 0),
77 RATETAB_ENT(90, 7, 0),
78 RATETAB_ENT(120, 8, 0),
79 RATETAB_ENT(180, 9, 0),
80 RATETAB_ENT(240, 10, 0),
81 RATETAB_ENT(360, 11, 0),
82 RATETAB_ENT(480, 12, 0),
83 RATETAB_ENT(540, 13, 0),
84};
85
86static struct ieee80211_rate cw1200_mcs_rates[] = {
87 RATETAB_ENT(65, 14, IEEE80211_TX_RC_MCS),
88 RATETAB_ENT(130, 15, IEEE80211_TX_RC_MCS),
89 RATETAB_ENT(195, 16, IEEE80211_TX_RC_MCS),
90 RATETAB_ENT(260, 17, IEEE80211_TX_RC_MCS),
91 RATETAB_ENT(390, 18, IEEE80211_TX_RC_MCS),
92 RATETAB_ENT(520, 19, IEEE80211_TX_RC_MCS),
93 RATETAB_ENT(585, 20, IEEE80211_TX_RC_MCS),
94 RATETAB_ENT(650, 21, IEEE80211_TX_RC_MCS),
95};
96
97#define cw1200_a_rates (cw1200_rates + 4)
98#define cw1200_a_rates_size (ARRAY_SIZE(cw1200_rates) - 4)
99#define cw1200_g_rates (cw1200_rates + 0)
100#define cw1200_g_rates_size (ARRAY_SIZE(cw1200_rates))
101#define cw1200_n_rates (cw1200_mcs_rates)
102#define cw1200_n_rates_size (ARRAY_SIZE(cw1200_mcs_rates))
103
104
105#define CHAN2G(_channel, _freq, _flags) { \
106 .band = IEEE80211_BAND_2GHZ, \
107 .center_freq = (_freq), \
108 .hw_value = (_channel), \
109 .flags = (_flags), \
110 .max_antenna_gain = 0, \
111 .max_power = 30, \
112}
113
114#define CHAN5G(_channel, _flags) { \
115 .band = IEEE80211_BAND_5GHZ, \
116 .center_freq = 5000 + (5 * (_channel)), \
117 .hw_value = (_channel), \
118 .flags = (_flags), \
119 .max_antenna_gain = 0, \
120 .max_power = 30, \
121}
122
123static struct ieee80211_channel cw1200_2ghz_chantable[] = {
124 CHAN2G(1, 2412, 0),
125 CHAN2G(2, 2417, 0),
126 CHAN2G(3, 2422, 0),
127 CHAN2G(4, 2427, 0),
128 CHAN2G(5, 2432, 0),
129 CHAN2G(6, 2437, 0),
130 CHAN2G(7, 2442, 0),
131 CHAN2G(8, 2447, 0),
132 CHAN2G(9, 2452, 0),
133 CHAN2G(10, 2457, 0),
134 CHAN2G(11, 2462, 0),
135 CHAN2G(12, 2467, 0),
136 CHAN2G(13, 2472, 0),
137 CHAN2G(14, 2484, 0),
138};
139
140static struct ieee80211_channel cw1200_5ghz_chantable[] = {
141 CHAN5G(34, 0), CHAN5G(36, 0),
142 CHAN5G(38, 0), CHAN5G(40, 0),
143 CHAN5G(42, 0), CHAN5G(44, 0),
144 CHAN5G(46, 0), CHAN5G(48, 0),
145 CHAN5G(52, 0), CHAN5G(56, 0),
146 CHAN5G(60, 0), CHAN5G(64, 0),
147 CHAN5G(100, 0), CHAN5G(104, 0),
148 CHAN5G(108, 0), CHAN5G(112, 0),
149 CHAN5G(116, 0), CHAN5G(120, 0),
150 CHAN5G(124, 0), CHAN5G(128, 0),
151 CHAN5G(132, 0), CHAN5G(136, 0),
152 CHAN5G(140, 0), CHAN5G(149, 0),
153 CHAN5G(153, 0), CHAN5G(157, 0),
154 CHAN5G(161, 0), CHAN5G(165, 0),
155 CHAN5G(184, 0), CHAN5G(188, 0),
156 CHAN5G(192, 0), CHAN5G(196, 0),
157 CHAN5G(200, 0), CHAN5G(204, 0),
158 CHAN5G(208, 0), CHAN5G(212, 0),
159 CHAN5G(216, 0),
160};
161
162static struct ieee80211_supported_band cw1200_band_2ghz = {
163 .channels = cw1200_2ghz_chantable,
164 .n_channels = ARRAY_SIZE(cw1200_2ghz_chantable),
165 .bitrates = cw1200_g_rates,
166 .n_bitrates = cw1200_g_rates_size,
167 .ht_cap = {
168 .cap = IEEE80211_HT_CAP_GRN_FLD |
169 (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT) |
170 IEEE80211_HT_CAP_MAX_AMSDU,
171 .ht_supported = 1,
172 .ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K,
173 .ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE,
174 .mcs = {
175 .rx_mask[0] = 0xFF,
176 .rx_highest = __cpu_to_le16(0x41),
177 .tx_params = IEEE80211_HT_MCS_TX_DEFINED,
178 },
179 },
180};
181
182static struct ieee80211_supported_band cw1200_band_5ghz = {
183 .channels = cw1200_5ghz_chantable,
184 .n_channels = ARRAY_SIZE(cw1200_5ghz_chantable),
185 .bitrates = cw1200_a_rates,
186 .n_bitrates = cw1200_a_rates_size,
187 .ht_cap = {
188 .cap = IEEE80211_HT_CAP_GRN_FLD |
189 (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT) |
190 IEEE80211_HT_CAP_MAX_AMSDU,
191 .ht_supported = 1,
192 .ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K,
193 .ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE,
194 .mcs = {
195 .rx_mask[0] = 0xFF,
196 .rx_highest = __cpu_to_le16(0x41),
197 .tx_params = IEEE80211_HT_MCS_TX_DEFINED,
198 },
199 },
200};
201
202static const unsigned long cw1200_ttl[] = {
203 1 * HZ, /* VO */
204 2 * HZ, /* VI */
205 5 * HZ, /* BE */
206 10 * HZ /* BK */
207};
208
209static const struct ieee80211_ops cw1200_ops = {
210 .start = cw1200_start,
211 .stop = cw1200_stop,
212 .add_interface = cw1200_add_interface,
213 .remove_interface = cw1200_remove_interface,
214 .change_interface = cw1200_change_interface,
215 .tx = cw1200_tx,
216 .hw_scan = cw1200_hw_scan,
217 .set_tim = cw1200_set_tim,
218 .sta_notify = cw1200_sta_notify,
219 .sta_add = cw1200_sta_add,
220 .sta_remove = cw1200_sta_remove,
221 .set_key = cw1200_set_key,
222 .set_rts_threshold = cw1200_set_rts_threshold,
223 .config = cw1200_config,
224 .bss_info_changed = cw1200_bss_info_changed,
225 .prepare_multicast = cw1200_prepare_multicast,
226 .configure_filter = cw1200_configure_filter,
227 .conf_tx = cw1200_conf_tx,
228 .get_stats = cw1200_get_stats,
229 .ampdu_action = cw1200_ampdu_action,
230 .flush = cw1200_flush,
231#ifdef CONFIG_PM
232 .suspend = cw1200_wow_suspend,
233 .resume = cw1200_wow_resume,
234#endif
235 /* Intentionally not offloaded: */
236 /*.channel_switch = cw1200_channel_switch, */
237 /*.remain_on_channel = cw1200_remain_on_channel, */
238 /*.cancel_remain_on_channel = cw1200_cancel_remain_on_channel, */
239};
240
241int cw1200_ba_rx_tids = -1;
242int cw1200_ba_tx_tids = -1;
243module_param(cw1200_ba_rx_tids, int, 0644);
244module_param(cw1200_ba_tx_tids, int, 0644);
245MODULE_PARM_DESC(cw1200_ba_rx_tids, "Block ACK RX TIDs");
246MODULE_PARM_DESC(cw1200_ba_tx_tids, "Block ACK TX TIDs");
247
248static struct ieee80211_hw *cw1200_init_common(const u8 *macaddr,
249 const bool have_5ghz)
250{
251 int i, band;
252 struct ieee80211_hw *hw;
253 struct cw1200_common *priv;
254
255 hw = ieee80211_alloc_hw(sizeof(struct cw1200_common), &cw1200_ops);
256 if (!hw)
257 return NULL;
258
259 priv = hw->priv;
260 priv->hw = hw;
261 priv->hw_type = -1;
262 priv->mode = NL80211_IFTYPE_UNSPECIFIED;
263 priv->rates = cw1200_rates; /* TODO: fetch from FW */
264 priv->mcs_rates = cw1200_n_rates;
265 if (cw1200_ba_rx_tids != -1)
266 priv->ba_rx_tid_mask = cw1200_ba_rx_tids;
267 else
268 priv->ba_rx_tid_mask = 0xFF; /* Enable RX BLKACK for all TIDs */
269 if (cw1200_ba_tx_tids != -1)
270 priv->ba_tx_tid_mask = cw1200_ba_tx_tids;
271 else
272 priv->ba_tx_tid_mask = 0xff; /* Enable TX BLKACK for all TIDs */
273
274 hw->flags = IEEE80211_HW_SIGNAL_DBM |
275 IEEE80211_HW_SUPPORTS_PS |
276 IEEE80211_HW_SUPPORTS_DYNAMIC_PS |
277 IEEE80211_HW_REPORTS_TX_ACK_STATUS |
278 IEEE80211_HW_SUPPORTS_UAPSD |
279 IEEE80211_HW_CONNECTION_MONITOR |
280 IEEE80211_HW_AMPDU_AGGREGATION |
281 IEEE80211_HW_TX_AMPDU_SETUP_IN_HW |
282 IEEE80211_HW_NEED_DTIM_BEFORE_ASSOC;
283
284 hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
285 BIT(NL80211_IFTYPE_ADHOC) |
286 BIT(NL80211_IFTYPE_AP) |
287 BIT(NL80211_IFTYPE_MESH_POINT) |
288 BIT(NL80211_IFTYPE_P2P_CLIENT) |
289 BIT(NL80211_IFTYPE_P2P_GO);
290
291#ifdef CONFIG_PM
292 /* Support only for limited wowlan functionalities */
293 hw->wiphy->wowlan.flags = WIPHY_WOWLAN_ANY |
294 WIPHY_WOWLAN_DISCONNECT;
295 hw->wiphy->wowlan.n_patterns = 0;
296#endif
297
298 hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD;
299
300 hw->channel_change_time = 1000; /* TODO: find actual value */
301 hw->queues = 4;
302
303 priv->rts_threshold = -1;
304
305 hw->max_rates = 8;
306 hw->max_rate_tries = 15;
307 hw->extra_tx_headroom = WSM_TX_EXTRA_HEADROOM +
308 8; /* TKIP IV */
309
310 hw->sta_data_size = sizeof(struct cw1200_sta_priv);
311
312 hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &cw1200_band_2ghz;
313 if (have_5ghz)
314 hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &cw1200_band_5ghz;
315
316 /* Channel params have to be cleared before registering wiphy again */
317 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
318 struct ieee80211_supported_band *sband = hw->wiphy->bands[band];
319 if (!sband)
320 continue;
321 for (i = 0; i < sband->n_channels; i++) {
322 sband->channels[i].flags = 0;
323 sband->channels[i].max_antenna_gain = 0;
324 sband->channels[i].max_power = 30;
325 }
326 }
327
328 hw->wiphy->max_scan_ssids = 2;
329 hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN;
330
331 if (macaddr)
332 SET_IEEE80211_PERM_ADDR(hw, (u8 *)macaddr);
333 else
334 SET_IEEE80211_PERM_ADDR(hw, cw1200_mac_template);
335
336 /* Fix up mac address if necessary */
337 if (hw->wiphy->perm_addr[3] == 0 &&
338 hw->wiphy->perm_addr[4] == 0 &&
339 hw->wiphy->perm_addr[5] == 0) {
340 get_random_bytes(&hw->wiphy->perm_addr[3], 3);
341 }
342
343 mutex_init(&priv->wsm_cmd_mux);
344 mutex_init(&priv->conf_mutex);
345 priv->workqueue = create_singlethread_workqueue("cw1200_wq");
346 sema_init(&priv->scan.lock, 1);
347 INIT_WORK(&priv->scan.work, cw1200_scan_work);
348 INIT_DELAYED_WORK(&priv->scan.probe_work, cw1200_probe_work);
349 INIT_DELAYED_WORK(&priv->scan.timeout, cw1200_scan_timeout);
350 INIT_DELAYED_WORK(&priv->clear_recent_scan_work,
351 cw1200_clear_recent_scan_work);
352 INIT_DELAYED_WORK(&priv->join_timeout, cw1200_join_timeout);
353 INIT_WORK(&priv->unjoin_work, cw1200_unjoin_work);
354 INIT_WORK(&priv->join_complete_work, cw1200_join_complete_work);
355 INIT_WORK(&priv->wep_key_work, cw1200_wep_key_work);
356 INIT_WORK(&priv->tx_policy_upload_work, tx_policy_upload_work);
357 spin_lock_init(&priv->event_queue_lock);
358 INIT_LIST_HEAD(&priv->event_queue);
359 INIT_WORK(&priv->event_handler, cw1200_event_handler);
360 INIT_DELAYED_WORK(&priv->bss_loss_work, cw1200_bss_loss_work);
361 INIT_WORK(&priv->bss_params_work, cw1200_bss_params_work);
362 spin_lock_init(&priv->bss_loss_lock);
363 spin_lock_init(&priv->ps_state_lock);
364 INIT_WORK(&priv->set_cts_work, cw1200_set_cts_work);
365 INIT_WORK(&priv->set_tim_work, cw1200_set_tim_work);
366 INIT_WORK(&priv->multicast_start_work, cw1200_multicast_start_work);
367 INIT_WORK(&priv->multicast_stop_work, cw1200_multicast_stop_work);
368 INIT_WORK(&priv->link_id_work, cw1200_link_id_work);
369 INIT_DELAYED_WORK(&priv->link_id_gc_work, cw1200_link_id_gc_work);
370 INIT_WORK(&priv->linkid_reset_work, cw1200_link_id_reset);
371 INIT_WORK(&priv->update_filtering_work, cw1200_update_filtering_work);
372 INIT_WORK(&priv->set_beacon_wakeup_period_work,
373 cw1200_set_beacon_wakeup_period_work);
374 init_timer(&priv->mcast_timeout);
375 priv->mcast_timeout.data = (unsigned long)priv;
376 priv->mcast_timeout.function = cw1200_mcast_timeout;
377
378 if (cw1200_queue_stats_init(&priv->tx_queue_stats,
379 CW1200_LINK_ID_MAX,
380 cw1200_skb_dtor,
381 priv)) {
382 ieee80211_free_hw(hw);
383 return NULL;
384 }
385
386 for (i = 0; i < 4; ++i) {
387 if (cw1200_queue_init(&priv->tx_queue[i],
388 &priv->tx_queue_stats, i, 16,
389 cw1200_ttl[i])) {
390 for (; i > 0; i--)
391 cw1200_queue_deinit(&priv->tx_queue[i - 1]);
392 cw1200_queue_stats_deinit(&priv->tx_queue_stats);
393 ieee80211_free_hw(hw);
394 return NULL;
395 }
396 }
397
398 init_waitqueue_head(&priv->channel_switch_done);
399 init_waitqueue_head(&priv->wsm_cmd_wq);
400 init_waitqueue_head(&priv->wsm_startup_done);
401 init_waitqueue_head(&priv->ps_mode_switch_done);
402 wsm_buf_init(&priv->wsm_cmd_buf);
403 spin_lock_init(&priv->wsm_cmd.lock);
404 priv->wsm_cmd.done = 1;
405 tx_policy_init(priv);
406
407 return hw;
408}
409
410static int cw1200_register_common(struct ieee80211_hw *dev)
411{
412 struct cw1200_common *priv = dev->priv;
413 int err;
414
415#ifdef CONFIG_PM
416 err = cw1200_pm_init(&priv->pm_state, priv);
417 if (err) {
418 pr_err("Cannot init PM. (%d).\n",
419 err);
420 return err;
421 }
422#endif
423
424 err = ieee80211_register_hw(dev);
425 if (err) {
426 pr_err("Cannot register device (%d).\n",
427 err);
428#ifdef CONFIG_PM
429 cw1200_pm_deinit(&priv->pm_state);
430#endif
431 return err;
432 }
433
434 cw1200_debug_init(priv);
435
436 pr_info("Registered as '%s'\n", wiphy_name(dev->wiphy));
437 return 0;
438}
439
440static void cw1200_free_common(struct ieee80211_hw *dev)
441{
442 ieee80211_free_hw(dev);
443}
444
445static void cw1200_unregister_common(struct ieee80211_hw *dev)
446{
447 struct cw1200_common *priv = dev->priv;
448 int i;
449
450 ieee80211_unregister_hw(dev);
451
452 del_timer_sync(&priv->mcast_timeout);
453 cw1200_unregister_bh(priv);
454
455 cw1200_debug_release(priv);
456
457 mutex_destroy(&priv->conf_mutex);
458
459 wsm_buf_deinit(&priv->wsm_cmd_buf);
460
461 destroy_workqueue(priv->workqueue);
462 priv->workqueue = NULL;
463
464 if (priv->sdd) {
465 release_firmware(priv->sdd);
466 priv->sdd = NULL;
467 }
468
469 for (i = 0; i < 4; ++i)
470 cw1200_queue_deinit(&priv->tx_queue[i]);
471
472 cw1200_queue_stats_deinit(&priv->tx_queue_stats);
473#ifdef CONFIG_PM
474 cw1200_pm_deinit(&priv->pm_state);
475#endif
476}
477
478/* Clock is in KHz */
479u32 cw1200_dpll_from_clk(u16 clk_khz)
480{
481 switch (clk_khz) {
482 case 0x32C8: /* 13000 KHz */
483 return 0x1D89D241;
484 case 0x3E80: /* 16000 KHz */
485 return 0x000001E1;
486 case 0x41A0: /* 16800 KHz */
487 return 0x124931C1;
488 case 0x4B00: /* 19200 KHz */
489 return 0x00000191;
490 case 0x5DC0: /* 24000 KHz */
491 return 0x00000141;
492 case 0x6590: /* 26000 KHz */
493 return 0x0EC4F121;
494 case 0x8340: /* 33600 KHz */
495 return 0x092490E1;
496 case 0x9600: /* 38400 KHz */
497 return 0x100010C1;
498 case 0x9C40: /* 40000 KHz */
499 return 0x000000C1;
500 case 0xBB80: /* 48000 KHz */
501 return 0x000000A1;
502 case 0xCB20: /* 52000 KHz */
503 return 0x07627091;
504 default:
505 pr_err("Unknown Refclk freq (0x%04x), using 2600KHz\n",
506 clk_khz);
507 return 0x0EC4F121;
508 }
509}
510
511int cw1200_core_probe(const struct hwbus_ops *hwbus_ops,
512 struct hwbus_priv *hwbus,
513 struct device *pdev,
514 struct cw1200_common **core,
515 int ref_clk, const u8 *macaddr,
516 const char *sdd_path, bool have_5ghz)
517{
518 int err = -EINVAL;
519 struct ieee80211_hw *dev;
520 struct cw1200_common *priv;
521 struct wsm_operational_mode mode = {
522 .power_mode = cw1200_power_mode,
523 .disable_more_flag_usage = true,
524 };
525
526 dev = cw1200_init_common(macaddr, have_5ghz);
527 if (!dev)
528 goto err;
529
530 priv = dev->priv;
531 priv->hw_refclk = ref_clk;
532 if (cw1200_refclk)
533 priv->hw_refclk = cw1200_refclk;
534
535 priv->sdd_path = (char *)sdd_path;
536 if (cw1200_sdd_path)
537 priv->sdd_path = cw1200_sdd_path;
538
539 priv->hwbus_ops = hwbus_ops;
540 priv->hwbus_priv = hwbus;
541 priv->pdev = pdev;
542 SET_IEEE80211_DEV(priv->hw, pdev);
543
544 /* Pass struct cw1200_common back up */
545 *core = priv;
546
547 err = cw1200_register_bh(priv);
548 if (err)
549 goto err1;
550
551 err = cw1200_load_firmware(priv);
552 if (err)
553 goto err2;
554
555 if (wait_event_interruptible_timeout(priv->wsm_startup_done,
556 priv->firmware_ready,
557 3*HZ) <= 0) {
558 /* TODO: Need to find how to reset device
559 in QUEUE mode properly.
560 */
561 pr_err("Timeout waiting on device startup\n");
562 err = -ETIMEDOUT;
563 goto err2;
564 }
565
566 /* Set low-power mode. */
567 wsm_set_operational_mode(priv, &mode);
568
569 /* Enable multi-TX confirmation */
570 wsm_use_multi_tx_conf(priv, true);
571
572 err = cw1200_register_common(dev);
573 if (err)
574 goto err2;
575
576 return err;
577
578err2:
579 cw1200_unregister_bh(priv);
580err1:
581 cw1200_free_common(dev);
582err:
583 *core = NULL;
584 return err;
585}
586EXPORT_SYMBOL_GPL(cw1200_core_probe);
587
588void cw1200_core_release(struct cw1200_common *self)
589{
590 /* Disable device interrupts */
591 self->hwbus_ops->lock(self->hwbus_priv);
592 __cw1200_irq_enable(self, 0);
593 self->hwbus_ops->unlock(self->hwbus_priv);
594
595 /* And then clean up */
596 cw1200_unregister_common(self->hw);
597 cw1200_free_common(self->hw);
598 return;
599}
600EXPORT_SYMBOL_GPL(cw1200_core_release);
diff --git a/drivers/net/wireless/cw1200/pm.c b/drivers/net/wireless/cw1200/pm.c
new file mode 100644
index 000000000000..b37abb9f0453
--- /dev/null
+++ b/drivers/net/wireless/cw1200/pm.c
@@ -0,0 +1,367 @@
1/*
2 * Mac80211 power management API for ST-Ericsson CW1200 drivers
3 *
4 * Copyright (c) 2011, ST-Ericsson
5 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/module.h>
13#include <linux/if_ether.h>
14#include "cw1200.h"
15#include "pm.h"
16#include "sta.h"
17#include "bh.h"
18#include "hwbus.h"
19
20#define CW1200_BEACON_SKIPPING_MULTIPLIER 3
21
22struct cw1200_udp_port_filter {
23 struct wsm_udp_port_filter_hdr hdr;
24 /* Up to 4 filters are allowed. */
25 struct wsm_udp_port_filter filters[WSM_MAX_FILTER_ELEMENTS];
26} __packed;
27
28struct cw1200_ether_type_filter {
29 struct wsm_ether_type_filter_hdr hdr;
30 /* Up to 4 filters are allowed. */
31 struct wsm_ether_type_filter filters[WSM_MAX_FILTER_ELEMENTS];
32} __packed;
33
34static struct cw1200_udp_port_filter cw1200_udp_port_filter_on = {
35 .hdr.num = 2,
36 .filters = {
37 [0] = {
38 .action = WSM_FILTER_ACTION_FILTER_OUT,
39 .type = WSM_FILTER_PORT_TYPE_DST,
40 .port = __cpu_to_le16(67), /* DHCP Bootps */
41 },
42 [1] = {
43 .action = WSM_FILTER_ACTION_FILTER_OUT,
44 .type = WSM_FILTER_PORT_TYPE_DST,
45 .port = __cpu_to_le16(68), /* DHCP Bootpc */
46 },
47 }
48};
49
50static struct wsm_udp_port_filter_hdr cw1200_udp_port_filter_off = {
51 .num = 0,
52};
53
54#ifndef ETH_P_WAPI
55#define ETH_P_WAPI 0x88B4
56#endif
57
58static struct cw1200_ether_type_filter cw1200_ether_type_filter_on = {
59 .hdr.num = 4,
60 .filters = {
61 [0] = {
62 .action = WSM_FILTER_ACTION_FILTER_IN,
63 .type = __cpu_to_le16(ETH_P_IP),
64 },
65 [1] = {
66 .action = WSM_FILTER_ACTION_FILTER_IN,
67 .type = __cpu_to_le16(ETH_P_PAE),
68 },
69 [2] = {
70 .action = WSM_FILTER_ACTION_FILTER_IN,
71 .type = __cpu_to_le16(ETH_P_WAPI),
72 },
73 [3] = {
74 .action = WSM_FILTER_ACTION_FILTER_IN,
75 .type = __cpu_to_le16(ETH_P_ARP),
76 },
77 },
78};
79
80static struct wsm_ether_type_filter_hdr cw1200_ether_type_filter_off = {
81 .num = 0,
82};
83
84/* private */
85struct cw1200_suspend_state {
86 unsigned long bss_loss_tmo;
87 unsigned long join_tmo;
88 unsigned long direct_probe;
89 unsigned long link_id_gc;
90 bool beacon_skipping;
91 u8 prev_ps_mode;
92};
93
94static void cw1200_pm_stay_awake_tmo(unsigned long arg)
95{
96 /* XXX what's the point of this ? */
97}
98
99int cw1200_pm_init(struct cw1200_pm_state *pm,
100 struct cw1200_common *priv)
101{
102 spin_lock_init(&pm->lock);
103
104 init_timer(&pm->stay_awake);
105 pm->stay_awake.data = (unsigned long)pm;
106 pm->stay_awake.function = cw1200_pm_stay_awake_tmo;
107
108 return 0;
109}
110
111void cw1200_pm_deinit(struct cw1200_pm_state *pm)
112{
113 del_timer_sync(&pm->stay_awake);
114}
115
116void cw1200_pm_stay_awake(struct cw1200_pm_state *pm,
117 unsigned long tmo)
118{
119 long cur_tmo;
120 spin_lock_bh(&pm->lock);
121 cur_tmo = pm->stay_awake.expires - jiffies;
122 if (!timer_pending(&pm->stay_awake) || cur_tmo < (long)tmo)
123 mod_timer(&pm->stay_awake, jiffies + tmo);
124 spin_unlock_bh(&pm->lock);
125}
126
127static long cw1200_suspend_work(struct delayed_work *work)
128{
129 int ret = cancel_delayed_work(work);
130 long tmo;
131 if (ret > 0) {
132 /* Timer is pending */
133 tmo = work->timer.expires - jiffies;
134 if (tmo < 0)
135 tmo = 0;
136 } else {
137 tmo = -1;
138 }
139 return tmo;
140}
141
142static int cw1200_resume_work(struct cw1200_common *priv,
143 struct delayed_work *work,
144 unsigned long tmo)
145{
146 if ((long)tmo < 0)
147 return 1;
148
149 return queue_delayed_work(priv->workqueue, work, tmo);
150}
151
152int cw1200_can_suspend(struct cw1200_common *priv)
153{
154 if (atomic_read(&priv->bh_rx)) {
155 wiphy_dbg(priv->hw->wiphy, "Suspend interrupted.\n");
156 return 0;
157 }
158 return 1;
159}
160EXPORT_SYMBOL_GPL(cw1200_can_suspend);
161
162int cw1200_wow_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
163{
164 struct cw1200_common *priv = hw->priv;
165 struct cw1200_pm_state *pm_state = &priv->pm_state;
166 struct cw1200_suspend_state *state;
167 int ret;
168
169 spin_lock_bh(&pm_state->lock);
170 ret = timer_pending(&pm_state->stay_awake);
171 spin_unlock_bh(&pm_state->lock);
172 if (ret)
173 return -EAGAIN;
174
175 /* Do not suspend when datapath is not idle */
176 if (priv->tx_queue_stats.num_queued)
177 return -EBUSY;
178
179 /* Make sure there is no configuration requests in progress. */
180 if (!mutex_trylock(&priv->conf_mutex))
181 return -EBUSY;
182
183 /* Ensure pending operations are done.
184 * Note also that wow_suspend must return in ~2.5sec, before
185 * watchdog is triggered.
186 */
187 if (priv->channel_switch_in_progress)
188 goto revert1;
189
190 /* Do not suspend when join is pending */
191 if (priv->join_pending)
192 goto revert1;
193
194 /* Do not suspend when scanning */
195 if (down_trylock(&priv->scan.lock))
196 goto revert1;
197
198 /* Lock TX. */
199 wsm_lock_tx_async(priv);
200
201 /* Wait to avoid possible race with bh code.
202 * But do not wait too long...
203 */
204 if (wait_event_timeout(priv->bh_evt_wq,
205 !priv->hw_bufs_used, HZ / 10) <= 0)
206 goto revert2;
207
208 /* Set UDP filter */
209 wsm_set_udp_port_filter(priv, &cw1200_udp_port_filter_on.hdr);
210
211 /* Set ethernet frame type filter */
212 wsm_set_ether_type_filter(priv, &cw1200_ether_type_filter_on.hdr);
213
214 /* Allocate state */
215 state = kzalloc(sizeof(struct cw1200_suspend_state), GFP_KERNEL);
216 if (!state)
217 goto revert3;
218
219 /* Change to legacy PS while going to suspend */
220 if (!priv->vif->p2p &&
221 priv->join_status == CW1200_JOIN_STATUS_STA &&
222 priv->powersave_mode.mode != WSM_PSM_PS) {
223 state->prev_ps_mode = priv->powersave_mode.mode;
224 priv->powersave_mode.mode = WSM_PSM_PS;
225 cw1200_set_pm(priv, &priv->powersave_mode);
226 if (wait_event_interruptible_timeout(priv->ps_mode_switch_done,
227 !priv->ps_mode_switch_in_progress, 1*HZ) <= 0) {
228 goto revert3;
229 }
230 }
231
232 /* Store delayed work states. */
233 state->bss_loss_tmo =
234 cw1200_suspend_work(&priv->bss_loss_work);
235 state->join_tmo =
236 cw1200_suspend_work(&priv->join_timeout);
237 state->direct_probe =
238 cw1200_suspend_work(&priv->scan.probe_work);
239 state->link_id_gc =
240 cw1200_suspend_work(&priv->link_id_gc_work);
241
242 cancel_delayed_work_sync(&priv->clear_recent_scan_work);
243 atomic_set(&priv->recent_scan, 0);
244
245 /* Enable beacon skipping */
246 if (priv->join_status == CW1200_JOIN_STATUS_STA &&
247 priv->join_dtim_period &&
248 !priv->has_multicast_subscription) {
249 state->beacon_skipping = true;
250 wsm_set_beacon_wakeup_period(priv,
251 priv->join_dtim_period,
252 CW1200_BEACON_SKIPPING_MULTIPLIER * priv->join_dtim_period);
253 }
254
255 /* Stop serving thread */
256 if (cw1200_bh_suspend(priv))
257 goto revert4;
258
259 ret = timer_pending(&priv->mcast_timeout);
260 if (ret)
261 goto revert5;
262
263 /* Store suspend state */
264 pm_state->suspend_state = state;
265
266 /* Enable IRQ wake */
267 ret = priv->hwbus_ops->power_mgmt(priv->hwbus_priv, true);
268 if (ret) {
269 wiphy_err(priv->hw->wiphy,
270 "PM request failed: %d. WoW is disabled.\n", ret);
271 cw1200_wow_resume(hw);
272 return -EBUSY;
273 }
274
275 /* Force resume if event is coming from the device. */
276 if (atomic_read(&priv->bh_rx)) {
277 cw1200_wow_resume(hw);
278 return -EAGAIN;
279 }
280
281 return 0;
282
283revert5:
284 WARN_ON(cw1200_bh_resume(priv));
285revert4:
286 cw1200_resume_work(priv, &priv->bss_loss_work,
287 state->bss_loss_tmo);
288 cw1200_resume_work(priv, &priv->join_timeout,
289 state->join_tmo);
290 cw1200_resume_work(priv, &priv->scan.probe_work,
291 state->direct_probe);
292 cw1200_resume_work(priv, &priv->link_id_gc_work,
293 state->link_id_gc);
294 kfree(state);
295revert3:
296 wsm_set_udp_port_filter(priv, &cw1200_udp_port_filter_off);
297 wsm_set_ether_type_filter(priv, &cw1200_ether_type_filter_off);
298revert2:
299 wsm_unlock_tx(priv);
300 up(&priv->scan.lock);
301revert1:
302 mutex_unlock(&priv->conf_mutex);
303 return -EBUSY;
304}
305
306int cw1200_wow_resume(struct ieee80211_hw *hw)
307{
308 struct cw1200_common *priv = hw->priv;
309 struct cw1200_pm_state *pm_state = &priv->pm_state;
310 struct cw1200_suspend_state *state;
311
312 state = pm_state->suspend_state;
313 pm_state->suspend_state = NULL;
314
315 /* Disable IRQ wake */
316 priv->hwbus_ops->power_mgmt(priv->hwbus_priv, false);
317
318 /* Scan.lock must be released before BH is resumed other way
319 * in case when BSS_LOST command arrived the processing of the
320 * command will be delayed.
321 */
322 up(&priv->scan.lock);
323
324 /* Resume BH thread */
325 WARN_ON(cw1200_bh_resume(priv));
326
327 /* Restores previous PS mode */
328 if (!priv->vif->p2p && priv->join_status == CW1200_JOIN_STATUS_STA) {
329 priv->powersave_mode.mode = state->prev_ps_mode;
330 cw1200_set_pm(priv, &priv->powersave_mode);
331 }
332
333 if (state->beacon_skipping) {
334 wsm_set_beacon_wakeup_period(priv, priv->beacon_int *
335 priv->join_dtim_period >
336 MAX_BEACON_SKIP_TIME_MS ? 1 :
337 priv->join_dtim_period, 0);
338 state->beacon_skipping = false;
339 }
340
341 /* Resume delayed work */
342 cw1200_resume_work(priv, &priv->bss_loss_work,
343 state->bss_loss_tmo);
344 cw1200_resume_work(priv, &priv->join_timeout,
345 state->join_tmo);
346 cw1200_resume_work(priv, &priv->scan.probe_work,
347 state->direct_probe);
348 cw1200_resume_work(priv, &priv->link_id_gc_work,
349 state->link_id_gc);
350
351 /* Remove UDP port filter */
352 wsm_set_udp_port_filter(priv, &cw1200_udp_port_filter_off);
353
354 /* Remove ethernet frame type filter */
355 wsm_set_ether_type_filter(priv, &cw1200_ether_type_filter_off);
356
357 /* Unlock datapath */
358 wsm_unlock_tx(priv);
359
360 /* Unlock configuration mutex */
361 mutex_unlock(&priv->conf_mutex);
362
363 /* Free memory */
364 kfree(state);
365
366 return 0;
367}
diff --git a/drivers/net/wireless/cw1200/pm.h b/drivers/net/wireless/cw1200/pm.h
new file mode 100644
index 000000000000..3ed90ff22bb8
--- /dev/null
+++ b/drivers/net/wireless/cw1200/pm.h
@@ -0,0 +1,43 @@
1/*
2 * Mac80211 power management interface for ST-Ericsson CW1200 mac80211 drivers
3 *
4 * Copyright (c) 2011, ST-Ericsson
5 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#ifndef PM_H_INCLUDED
13#define PM_H_INCLUDED
14
15/* ******************************************************************** */
16/* mac80211 API */
17
18/* extern */ struct cw1200_common;
19/* private */ struct cw1200_suspend_state;
20
21struct cw1200_pm_state {
22 struct cw1200_suspend_state *suspend_state;
23 struct timer_list stay_awake;
24 struct platform_device *pm_dev;
25 spinlock_t lock; /* Protect access */
26};
27
28#ifdef CONFIG_PM
29int cw1200_pm_init(struct cw1200_pm_state *pm,
30 struct cw1200_common *priv);
31void cw1200_pm_deinit(struct cw1200_pm_state *pm);
32int cw1200_wow_suspend(struct ieee80211_hw *hw,
33 struct cfg80211_wowlan *wowlan);
34int cw1200_wow_resume(struct ieee80211_hw *hw);
35int cw1200_can_suspend(struct cw1200_common *priv);
36void cw1200_pm_stay_awake(struct cw1200_pm_state *pm,
37 unsigned long tmo);
38#else
39static inline void cw1200_pm_stay_awake(struct cw1200_pm_state *pm,
40 unsigned long tmo) {
41}
42#endif
43#endif
diff --git a/drivers/net/wireless/cw1200/queue.c b/drivers/net/wireless/cw1200/queue.c
new file mode 100644
index 000000000000..8510454d5db1
--- /dev/null
+++ b/drivers/net/wireless/cw1200/queue.c
@@ -0,0 +1,583 @@
1/*
2 * O(1) TX queue with built-in allocator for ST-Ericsson CW1200 drivers
3 *
4 * Copyright (c) 2010, ST-Ericsson
5 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <net/mac80211.h>
13#include <linux/sched.h>
14#include "queue.h"
15#include "cw1200.h"
16#include "debug.h"
17
18/* private */ struct cw1200_queue_item
19{
20 struct list_head head;
21 struct sk_buff *skb;
22 u32 packet_id;
23 unsigned long queue_timestamp;
24 unsigned long xmit_timestamp;
25 struct cw1200_txpriv txpriv;
26 u8 generation;
27};
28
29static inline void __cw1200_queue_lock(struct cw1200_queue *queue)
30{
31 struct cw1200_queue_stats *stats = queue->stats;
32 if (queue->tx_locked_cnt++ == 0) {
33 pr_debug("[TX] Queue %d is locked.\n",
34 queue->queue_id);
35 ieee80211_stop_queue(stats->priv->hw, queue->queue_id);
36 }
37}
38
39static inline void __cw1200_queue_unlock(struct cw1200_queue *queue)
40{
41 struct cw1200_queue_stats *stats = queue->stats;
42 BUG_ON(!queue->tx_locked_cnt);
43 if (--queue->tx_locked_cnt == 0) {
44 pr_debug("[TX] Queue %d is unlocked.\n",
45 queue->queue_id);
46 ieee80211_wake_queue(stats->priv->hw, queue->queue_id);
47 }
48}
49
50static inline void cw1200_queue_parse_id(u32 packet_id, u8 *queue_generation,
51 u8 *queue_id, u8 *item_generation,
52 u8 *item_id)
53{
54 *item_id = (packet_id >> 0) & 0xFF;
55 *item_generation = (packet_id >> 8) & 0xFF;
56 *queue_id = (packet_id >> 16) & 0xFF;
57 *queue_generation = (packet_id >> 24) & 0xFF;
58}
59
60static inline u32 cw1200_queue_mk_packet_id(u8 queue_generation, u8 queue_id,
61 u8 item_generation, u8 item_id)
62{
63 return ((u32)item_id << 0) |
64 ((u32)item_generation << 8) |
65 ((u32)queue_id << 16) |
66 ((u32)queue_generation << 24);
67}
68
69static void cw1200_queue_post_gc(struct cw1200_queue_stats *stats,
70 struct list_head *gc_list)
71{
72 struct cw1200_queue_item *item, *tmp;
73
74 list_for_each_entry_safe(item, tmp, gc_list, head) {
75 list_del(&item->head);
76 stats->skb_dtor(stats->priv, item->skb, &item->txpriv);
77 kfree(item);
78 }
79}
80
81static void cw1200_queue_register_post_gc(struct list_head *gc_list,
82 struct cw1200_queue_item *item)
83{
84 struct cw1200_queue_item *gc_item;
85 gc_item = kmalloc(sizeof(struct cw1200_queue_item),
86 GFP_ATOMIC);
87 BUG_ON(!gc_item);
88 memcpy(gc_item, item, sizeof(struct cw1200_queue_item));
89 list_add_tail(&gc_item->head, gc_list);
90}
91
92static void __cw1200_queue_gc(struct cw1200_queue *queue,
93 struct list_head *head,
94 bool unlock)
95{
96 struct cw1200_queue_stats *stats = queue->stats;
97 struct cw1200_queue_item *item = NULL, *tmp;
98 bool wakeup_stats = false;
99
100 list_for_each_entry_safe(item, tmp, &queue->queue, head) {
101 if (jiffies - item->queue_timestamp < queue->ttl)
102 break;
103 --queue->num_queued;
104 --queue->link_map_cache[item->txpriv.link_id];
105 spin_lock_bh(&stats->lock);
106 --stats->num_queued;
107 if (!--stats->link_map_cache[item->txpriv.link_id])
108 wakeup_stats = true;
109 spin_unlock_bh(&stats->lock);
110 cw1200_debug_tx_ttl(stats->priv);
111 cw1200_queue_register_post_gc(head, item);
112 item->skb = NULL;
113 list_move_tail(&item->head, &queue->free_pool);
114 }
115
116 if (wakeup_stats)
117 wake_up(&stats->wait_link_id_empty);
118
119 if (queue->overfull) {
120 if (queue->num_queued <= (queue->capacity >> 1)) {
121 queue->overfull = false;
122 if (unlock)
123 __cw1200_queue_unlock(queue);
124 } else if (item) {
125 unsigned long tmo = item->queue_timestamp + queue->ttl;
126 mod_timer(&queue->gc, tmo);
127 cw1200_pm_stay_awake(&stats->priv->pm_state,
128 tmo - jiffies);
129 }
130 }
131}
132
133static void cw1200_queue_gc(unsigned long arg)
134{
135 LIST_HEAD(list);
136 struct cw1200_queue *queue =
137 (struct cw1200_queue *)arg;
138
139 spin_lock_bh(&queue->lock);
140 __cw1200_queue_gc(queue, &list, true);
141 spin_unlock_bh(&queue->lock);
142 cw1200_queue_post_gc(queue->stats, &list);
143}
144
145int cw1200_queue_stats_init(struct cw1200_queue_stats *stats,
146 size_t map_capacity,
147 cw1200_queue_skb_dtor_t skb_dtor,
148 struct cw1200_common *priv)
149{
150 memset(stats, 0, sizeof(*stats));
151 stats->map_capacity = map_capacity;
152 stats->skb_dtor = skb_dtor;
153 stats->priv = priv;
154 spin_lock_init(&stats->lock);
155 init_waitqueue_head(&stats->wait_link_id_empty);
156
157 stats->link_map_cache = kzalloc(sizeof(int) * map_capacity,
158 GFP_KERNEL);
159 if (!stats->link_map_cache)
160 return -ENOMEM;
161
162 return 0;
163}
164
165int cw1200_queue_init(struct cw1200_queue *queue,
166 struct cw1200_queue_stats *stats,
167 u8 queue_id,
168 size_t capacity,
169 unsigned long ttl)
170{
171 size_t i;
172
173 memset(queue, 0, sizeof(*queue));
174 queue->stats = stats;
175 queue->capacity = capacity;
176 queue->queue_id = queue_id;
177 queue->ttl = ttl;
178 INIT_LIST_HEAD(&queue->queue);
179 INIT_LIST_HEAD(&queue->pending);
180 INIT_LIST_HEAD(&queue->free_pool);
181 spin_lock_init(&queue->lock);
182 init_timer(&queue->gc);
183 queue->gc.data = (unsigned long)queue;
184 queue->gc.function = cw1200_queue_gc;
185
186 queue->pool = kzalloc(sizeof(struct cw1200_queue_item) * capacity,
187 GFP_KERNEL);
188 if (!queue->pool)
189 return -ENOMEM;
190
191 queue->link_map_cache = kzalloc(sizeof(int) * stats->map_capacity,
192 GFP_KERNEL);
193 if (!queue->link_map_cache) {
194 kfree(queue->pool);
195 queue->pool = NULL;
196 return -ENOMEM;
197 }
198
199 for (i = 0; i < capacity; ++i)
200 list_add_tail(&queue->pool[i].head, &queue->free_pool);
201
202 return 0;
203}
204
205int cw1200_queue_clear(struct cw1200_queue *queue)
206{
207 int i;
208 LIST_HEAD(gc_list);
209 struct cw1200_queue_stats *stats = queue->stats;
210 struct cw1200_queue_item *item, *tmp;
211
212 spin_lock_bh(&queue->lock);
213 queue->generation++;
214 list_splice_tail_init(&queue->queue, &queue->pending);
215 list_for_each_entry_safe(item, tmp, &queue->pending, head) {
216 WARN_ON(!item->skb);
217 cw1200_queue_register_post_gc(&gc_list, item);
218 item->skb = NULL;
219 list_move_tail(&item->head, &queue->free_pool);
220 }
221 queue->num_queued = 0;
222 queue->num_pending = 0;
223
224 spin_lock_bh(&stats->lock);
225 for (i = 0; i < stats->map_capacity; ++i) {
226 stats->num_queued -= queue->link_map_cache[i];
227 stats->link_map_cache[i] -= queue->link_map_cache[i];
228 queue->link_map_cache[i] = 0;
229 }
230 spin_unlock_bh(&stats->lock);
231 if (queue->overfull) {
232 queue->overfull = false;
233 __cw1200_queue_unlock(queue);
234 }
235 spin_unlock_bh(&queue->lock);
236 wake_up(&stats->wait_link_id_empty);
237 cw1200_queue_post_gc(stats, &gc_list);
238 return 0;
239}
240
241void cw1200_queue_stats_deinit(struct cw1200_queue_stats *stats)
242{
243 kfree(stats->link_map_cache);
244 stats->link_map_cache = NULL;
245}
246
247void cw1200_queue_deinit(struct cw1200_queue *queue)
248{
249 cw1200_queue_clear(queue);
250 del_timer_sync(&queue->gc);
251 INIT_LIST_HEAD(&queue->free_pool);
252 kfree(queue->pool);
253 kfree(queue->link_map_cache);
254 queue->pool = NULL;
255 queue->link_map_cache = NULL;
256 queue->capacity = 0;
257}
258
259size_t cw1200_queue_get_num_queued(struct cw1200_queue *queue,
260 u32 link_id_map)
261{
262 size_t ret;
263 int i, bit;
264 size_t map_capacity = queue->stats->map_capacity;
265
266 if (!link_id_map)
267 return 0;
268
269 spin_lock_bh(&queue->lock);
270 if (link_id_map == (u32)-1) {
271 ret = queue->num_queued - queue->num_pending;
272 } else {
273 ret = 0;
274 for (i = 0, bit = 1; i < map_capacity; ++i, bit <<= 1) {
275 if (link_id_map & bit)
276 ret += queue->link_map_cache[i];
277 }
278 }
279 spin_unlock_bh(&queue->lock);
280 return ret;
281}
282
283int cw1200_queue_put(struct cw1200_queue *queue,
284 struct sk_buff *skb,
285 struct cw1200_txpriv *txpriv)
286{
287 int ret = 0;
288 LIST_HEAD(gc_list);
289 struct cw1200_queue_stats *stats = queue->stats;
290
291 if (txpriv->link_id >= queue->stats->map_capacity)
292 return -EINVAL;
293
294 spin_lock_bh(&queue->lock);
295 if (!WARN_ON(list_empty(&queue->free_pool))) {
296 struct cw1200_queue_item *item = list_first_entry(
297 &queue->free_pool, struct cw1200_queue_item, head);
298 BUG_ON(item->skb);
299
300 list_move_tail(&item->head, &queue->queue);
301 item->skb = skb;
302 item->txpriv = *txpriv;
303 item->generation = 0;
304 item->packet_id = cw1200_queue_mk_packet_id(queue->generation,
305 queue->queue_id,
306 item->generation,
307 item - queue->pool);
308 item->queue_timestamp = jiffies;
309
310 ++queue->num_queued;
311 ++queue->link_map_cache[txpriv->link_id];
312
313 spin_lock_bh(&stats->lock);
314 ++stats->num_queued;
315 ++stats->link_map_cache[txpriv->link_id];
316 spin_unlock_bh(&stats->lock);
317
318 /* TX may happen in parallel sometimes.
319 * Leave extra queue slots so we don't overflow.
320 */
321 if (queue->overfull == false &&
322 queue->num_queued >=
323 (queue->capacity - (num_present_cpus() - 1))) {
324 queue->overfull = true;
325 __cw1200_queue_lock(queue);
326 mod_timer(&queue->gc, jiffies);
327 }
328 } else {
329 ret = -ENOENT;
330 }
331 spin_unlock_bh(&queue->lock);
332 return ret;
333}
334
335int cw1200_queue_get(struct cw1200_queue *queue,
336 u32 link_id_map,
337 struct wsm_tx **tx,
338 struct ieee80211_tx_info **tx_info,
339 const struct cw1200_txpriv **txpriv)
340{
341 int ret = -ENOENT;
342 struct cw1200_queue_item *item;
343 struct cw1200_queue_stats *stats = queue->stats;
344 bool wakeup_stats = false;
345
346 spin_lock_bh(&queue->lock);
347 list_for_each_entry(item, &queue->queue, head) {
348 if (link_id_map & BIT(item->txpriv.link_id)) {
349 ret = 0;
350 break;
351 }
352 }
353
354 if (!WARN_ON(ret)) {
355 *tx = (struct wsm_tx *)item->skb->data;
356 *tx_info = IEEE80211_SKB_CB(item->skb);
357 *txpriv = &item->txpriv;
358 (*tx)->packet_id = __cpu_to_le32(item->packet_id);
359 list_move_tail(&item->head, &queue->pending);
360 ++queue->num_pending;
361 --queue->link_map_cache[item->txpriv.link_id];
362 item->xmit_timestamp = jiffies;
363
364 spin_lock_bh(&stats->lock);
365 --stats->num_queued;
366 if (!--stats->link_map_cache[item->txpriv.link_id])
367 wakeup_stats = true;
368 spin_unlock_bh(&stats->lock);
369 }
370 spin_unlock_bh(&queue->lock);
371 if (wakeup_stats)
372 wake_up(&stats->wait_link_id_empty);
373 return ret;
374}
375
376int cw1200_queue_requeue(struct cw1200_queue *queue, u32 packet_id)
377{
378 int ret = 0;
379 u8 queue_generation, queue_id, item_generation, item_id;
380 struct cw1200_queue_item *item;
381 struct cw1200_queue_stats *stats = queue->stats;
382
383 cw1200_queue_parse_id(packet_id, &queue_generation, &queue_id,
384 &item_generation, &item_id);
385
386 item = &queue->pool[item_id];
387
388 spin_lock_bh(&queue->lock);
389 BUG_ON(queue_id != queue->queue_id);
390 if (queue_generation != queue->generation) {
391 ret = -ENOENT;
392 } else if (item_id >= (unsigned) queue->capacity) {
393 WARN_ON(1);
394 ret = -EINVAL;
395 } else if (item->generation != item_generation) {
396 WARN_ON(1);
397 ret = -ENOENT;
398 } else {
399 --queue->num_pending;
400 ++queue->link_map_cache[item->txpriv.link_id];
401
402 spin_lock_bh(&stats->lock);
403 ++stats->num_queued;
404 ++stats->link_map_cache[item->txpriv.link_id];
405 spin_unlock_bh(&stats->lock);
406
407 item->generation = ++item_generation;
408 item->packet_id = cw1200_queue_mk_packet_id(queue_generation,
409 queue_id,
410 item_generation,
411 item_id);
412 list_move(&item->head, &queue->queue);
413 }
414 spin_unlock_bh(&queue->lock);
415 return ret;
416}
417
418int cw1200_queue_requeue_all(struct cw1200_queue *queue)
419{
420 struct cw1200_queue_item *item, *tmp;
421 struct cw1200_queue_stats *stats = queue->stats;
422 spin_lock_bh(&queue->lock);
423
424 list_for_each_entry_safe_reverse(item, tmp, &queue->pending, head) {
425 --queue->num_pending;
426 ++queue->link_map_cache[item->txpriv.link_id];
427
428 spin_lock_bh(&stats->lock);
429 ++stats->num_queued;
430 ++stats->link_map_cache[item->txpriv.link_id];
431 spin_unlock_bh(&stats->lock);
432
433 ++item->generation;
434 item->packet_id = cw1200_queue_mk_packet_id(queue->generation,
435 queue->queue_id,
436 item->generation,
437 item - queue->pool);
438 list_move(&item->head, &queue->queue);
439 }
440 spin_unlock_bh(&queue->lock);
441
442 return 0;
443}
444
445int cw1200_queue_remove(struct cw1200_queue *queue, u32 packet_id)
446{
447 int ret = 0;
448 u8 queue_generation, queue_id, item_generation, item_id;
449 struct cw1200_queue_item *item;
450 struct cw1200_queue_stats *stats = queue->stats;
451 struct sk_buff *gc_skb = NULL;
452 struct cw1200_txpriv gc_txpriv;
453
454 cw1200_queue_parse_id(packet_id, &queue_generation, &queue_id,
455 &item_generation, &item_id);
456
457 item = &queue->pool[item_id];
458
459 spin_lock_bh(&queue->lock);
460 BUG_ON(queue_id != queue->queue_id);
461 if (queue_generation != queue->generation) {
462 ret = -ENOENT;
463 } else if (item_id >= (unsigned) queue->capacity) {
464 WARN_ON(1);
465 ret = -EINVAL;
466 } else if (item->generation != item_generation) {
467 WARN_ON(1);
468 ret = -ENOENT;
469 } else {
470 gc_txpriv = item->txpriv;
471 gc_skb = item->skb;
472 item->skb = NULL;
473 --queue->num_pending;
474 --queue->num_queued;
475 ++queue->num_sent;
476 ++item->generation;
477 /* Do not use list_move_tail here, but list_move:
478 * try to utilize cache row.
479 */
480 list_move(&item->head, &queue->free_pool);
481
482 if (queue->overfull &&
483 (queue->num_queued <= (queue->capacity >> 1))) {
484 queue->overfull = false;
485 __cw1200_queue_unlock(queue);
486 }
487 }
488 spin_unlock_bh(&queue->lock);
489
490 if (gc_skb)
491 stats->skb_dtor(stats->priv, gc_skb, &gc_txpriv);
492
493 return ret;
494}
495
496int cw1200_queue_get_skb(struct cw1200_queue *queue, u32 packet_id,
497 struct sk_buff **skb,
498 const struct cw1200_txpriv **txpriv)
499{
500 int ret = 0;
501 u8 queue_generation, queue_id, item_generation, item_id;
502 struct cw1200_queue_item *item;
503 cw1200_queue_parse_id(packet_id, &queue_generation, &queue_id,
504 &item_generation, &item_id);
505
506 item = &queue->pool[item_id];
507
508 spin_lock_bh(&queue->lock);
509 BUG_ON(queue_id != queue->queue_id);
510 if (queue_generation != queue->generation) {
511 ret = -ENOENT;
512 } else if (item_id >= (unsigned) queue->capacity) {
513 WARN_ON(1);
514 ret = -EINVAL;
515 } else if (item->generation != item_generation) {
516 WARN_ON(1);
517 ret = -ENOENT;
518 } else {
519 *skb = item->skb;
520 *txpriv = &item->txpriv;
521 }
522 spin_unlock_bh(&queue->lock);
523 return ret;
524}
525
526void cw1200_queue_lock(struct cw1200_queue *queue)
527{
528 spin_lock_bh(&queue->lock);
529 __cw1200_queue_lock(queue);
530 spin_unlock_bh(&queue->lock);
531}
532
533void cw1200_queue_unlock(struct cw1200_queue *queue)
534{
535 spin_lock_bh(&queue->lock);
536 __cw1200_queue_unlock(queue);
537 spin_unlock_bh(&queue->lock);
538}
539
540bool cw1200_queue_get_xmit_timestamp(struct cw1200_queue *queue,
541 unsigned long *timestamp,
542 u32 pending_frame_id)
543{
544 struct cw1200_queue_item *item;
545 bool ret;
546
547 spin_lock_bh(&queue->lock);
548 ret = !list_empty(&queue->pending);
549 if (ret) {
550 list_for_each_entry(item, &queue->pending, head) {
551 if (item->packet_id != pending_frame_id)
552 if (time_before(item->xmit_timestamp,
553 *timestamp))
554 *timestamp = item->xmit_timestamp;
555 }
556 }
557 spin_unlock_bh(&queue->lock);
558 return ret;
559}
560
561bool cw1200_queue_stats_is_empty(struct cw1200_queue_stats *stats,
562 u32 link_id_map)
563{
564 bool empty = true;
565
566 spin_lock_bh(&stats->lock);
567 if (link_id_map == (u32)-1) {
568 empty = stats->num_queued == 0;
569 } else {
570 int i;
571 for (i = 0; i < stats->map_capacity; ++i) {
572 if (link_id_map & BIT(i)) {
573 if (stats->link_map_cache[i]) {
574 empty = false;
575 break;
576 }
577 }
578 }
579 }
580 spin_unlock_bh(&stats->lock);
581
582 return empty;
583}
diff --git a/drivers/net/wireless/cw1200/queue.h b/drivers/net/wireless/cw1200/queue.h
new file mode 100644
index 000000000000..119f9c79c14e
--- /dev/null
+++ b/drivers/net/wireless/cw1200/queue.h
@@ -0,0 +1,116 @@
1/*
2 * O(1) TX queue with built-in allocator for ST-Ericsson CW1200 drivers
3 *
4 * Copyright (c) 2010, ST-Ericsson
5 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#ifndef CW1200_QUEUE_H_INCLUDED
13#define CW1200_QUEUE_H_INCLUDED
14
15/* private */ struct cw1200_queue_item;
16
17/* extern */ struct sk_buff;
18/* extern */ struct wsm_tx;
19/* extern */ struct cw1200_common;
20/* extern */ struct ieee80211_tx_queue_stats;
21/* extern */ struct cw1200_txpriv;
22
23/* forward */ struct cw1200_queue_stats;
24
25typedef void (*cw1200_queue_skb_dtor_t)(struct cw1200_common *priv,
26 struct sk_buff *skb,
27 const struct cw1200_txpriv *txpriv);
28
29struct cw1200_queue {
30 struct cw1200_queue_stats *stats;
31 size_t capacity;
32 size_t num_queued;
33 size_t num_pending;
34 size_t num_sent;
35 struct cw1200_queue_item *pool;
36 struct list_head queue;
37 struct list_head free_pool;
38 struct list_head pending;
39 int tx_locked_cnt;
40 int *link_map_cache;
41 bool overfull;
42 spinlock_t lock; /* Protect queue entry */
43 u8 queue_id;
44 u8 generation;
45 struct timer_list gc;
46 unsigned long ttl;
47};
48
49struct cw1200_queue_stats {
50 spinlock_t lock; /* Protect stats entry */
51 int *link_map_cache;
52 int num_queued;
53 size_t map_capacity;
54 wait_queue_head_t wait_link_id_empty;
55 cw1200_queue_skb_dtor_t skb_dtor;
56 struct cw1200_common *priv;
57};
58
59struct cw1200_txpriv {
60 u8 link_id;
61 u8 raw_link_id;
62 u8 tid;
63 u8 rate_id;
64 u8 offset;
65};
66
67int cw1200_queue_stats_init(struct cw1200_queue_stats *stats,
68 size_t map_capacity,
69 cw1200_queue_skb_dtor_t skb_dtor,
70 struct cw1200_common *priv);
71int cw1200_queue_init(struct cw1200_queue *queue,
72 struct cw1200_queue_stats *stats,
73 u8 queue_id,
74 size_t capacity,
75 unsigned long ttl);
76int cw1200_queue_clear(struct cw1200_queue *queue);
77void cw1200_queue_stats_deinit(struct cw1200_queue_stats *stats);
78void cw1200_queue_deinit(struct cw1200_queue *queue);
79
80size_t cw1200_queue_get_num_queued(struct cw1200_queue *queue,
81 u32 link_id_map);
82int cw1200_queue_put(struct cw1200_queue *queue,
83 struct sk_buff *skb,
84 struct cw1200_txpriv *txpriv);
85int cw1200_queue_get(struct cw1200_queue *queue,
86 u32 link_id_map,
87 struct wsm_tx **tx,
88 struct ieee80211_tx_info **tx_info,
89 const struct cw1200_txpriv **txpriv);
90int cw1200_queue_requeue(struct cw1200_queue *queue, u32 packet_id);
91int cw1200_queue_requeue_all(struct cw1200_queue *queue);
92int cw1200_queue_remove(struct cw1200_queue *queue,
93 u32 packet_id);
94int cw1200_queue_get_skb(struct cw1200_queue *queue, u32 packet_id,
95 struct sk_buff **skb,
96 const struct cw1200_txpriv **txpriv);
97void cw1200_queue_lock(struct cw1200_queue *queue);
98void cw1200_queue_unlock(struct cw1200_queue *queue);
99bool cw1200_queue_get_xmit_timestamp(struct cw1200_queue *queue,
100 unsigned long *timestamp,
101 u32 pending_frame_id);
102
103bool cw1200_queue_stats_is_empty(struct cw1200_queue_stats *stats,
104 u32 link_id_map);
105
106static inline u8 cw1200_queue_get_queue_id(u32 packet_id)
107{
108 return (packet_id >> 16) & 0xFF;
109}
110
111static inline u8 cw1200_queue_get_generation(u32 packet_id)
112{
113 return (packet_id >> 8) & 0xFF;
114}
115
116#endif /* CW1200_QUEUE_H_INCLUDED */
diff --git a/drivers/net/wireless/cw1200/scan.c b/drivers/net/wireless/cw1200/scan.c
new file mode 100644
index 000000000000..ee3c19037aac
--- /dev/null
+++ b/drivers/net/wireless/cw1200/scan.c
@@ -0,0 +1,461 @@
1/*
2 * Scan implementation for ST-Ericsson CW1200 mac80211 drivers
3 *
4 * Copyright (c) 2010, ST-Ericsson
5 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/sched.h>
13#include "cw1200.h"
14#include "scan.h"
15#include "sta.h"
16#include "pm.h"
17
18static void cw1200_scan_restart_delayed(struct cw1200_common *priv);
19
20static int cw1200_scan_start(struct cw1200_common *priv, struct wsm_scan *scan)
21{
22 int ret, i;
23 int tmo = 2000;
24
25 switch (priv->join_status) {
26 case CW1200_JOIN_STATUS_PRE_STA:
27 case CW1200_JOIN_STATUS_JOINING:
28 return -EBUSY;
29 default:
30 break;
31 }
32
33 wiphy_dbg(priv->hw->wiphy, "[SCAN] hw req, type %d, %d channels, flags: 0x%x.\n",
34 scan->type, scan->num_channels, scan->flags);
35
36 for (i = 0; i < scan->num_channels; ++i)
37 tmo += scan->ch[i].max_chan_time + 10;
38
39 cancel_delayed_work_sync(&priv->clear_recent_scan_work);
40 atomic_set(&priv->scan.in_progress, 1);
41 atomic_set(&priv->recent_scan, 1);
42 cw1200_pm_stay_awake(&priv->pm_state, tmo * HZ / 1000);
43 queue_delayed_work(priv->workqueue, &priv->scan.timeout,
44 tmo * HZ / 1000);
45 ret = wsm_scan(priv, scan);
46 if (ret) {
47 atomic_set(&priv->scan.in_progress, 0);
48 cancel_delayed_work_sync(&priv->scan.timeout);
49 cw1200_scan_restart_delayed(priv);
50 }
51 return ret;
52}
53
54int cw1200_hw_scan(struct ieee80211_hw *hw,
55 struct ieee80211_vif *vif,
56 struct cfg80211_scan_request *req)
57{
58 struct cw1200_common *priv = hw->priv;
59 struct wsm_template_frame frame = {
60 .frame_type = WSM_FRAME_TYPE_PROBE_REQUEST,
61 };
62 int i, ret;
63
64 if (!priv->vif)
65 return -EINVAL;
66
67 /* Scan when P2P_GO corrupt firmware MiniAP mode */
68 if (priv->join_status == CW1200_JOIN_STATUS_AP)
69 return -EOPNOTSUPP;
70
71 if (req->n_ssids == 1 && !req->ssids[0].ssid_len)
72 req->n_ssids = 0;
73
74 wiphy_dbg(hw->wiphy, "[SCAN] Scan request for %d SSIDs.\n",
75 req->n_ssids);
76
77 if (req->n_ssids > WSM_SCAN_MAX_NUM_OF_SSIDS)
78 return -EINVAL;
79
80 frame.skb = ieee80211_probereq_get(hw, priv->vif, NULL, 0,
81 req->ie_len);
82 if (!frame.skb)
83 return -ENOMEM;
84
85 if (req->ie_len)
86 memcpy(skb_put(frame.skb, req->ie_len), req->ie, req->ie_len);
87
88 /* will be unlocked in cw1200_scan_work() */
89 down(&priv->scan.lock);
90 mutex_lock(&priv->conf_mutex);
91
92 ret = wsm_set_template_frame(priv, &frame);
93 if (!ret) {
94 /* Host want to be the probe responder. */
95 ret = wsm_set_probe_responder(priv, true);
96 }
97 if (ret) {
98 mutex_unlock(&priv->conf_mutex);
99 up(&priv->scan.lock);
100 dev_kfree_skb(frame.skb);
101 return ret;
102 }
103
104 wsm_lock_tx(priv);
105
106 BUG_ON(priv->scan.req);
107 priv->scan.req = req;
108 priv->scan.n_ssids = 0;
109 priv->scan.status = 0;
110 priv->scan.begin = &req->channels[0];
111 priv->scan.curr = priv->scan.begin;
112 priv->scan.end = &req->channels[req->n_channels];
113 priv->scan.output_power = priv->output_power;
114
115 for (i = 0; i < req->n_ssids; ++i) {
116 struct wsm_ssid *dst = &priv->scan.ssids[priv->scan.n_ssids];
117 memcpy(&dst->ssid[0], req->ssids[i].ssid, sizeof(dst->ssid));
118 dst->length = req->ssids[i].ssid_len;
119 ++priv->scan.n_ssids;
120 }
121
122 mutex_unlock(&priv->conf_mutex);
123
124 if (frame.skb)
125 dev_kfree_skb(frame.skb);
126 queue_work(priv->workqueue, &priv->scan.work);
127 return 0;
128}
129
130void cw1200_scan_work(struct work_struct *work)
131{
132 struct cw1200_common *priv = container_of(work, struct cw1200_common,
133 scan.work);
134 struct ieee80211_channel **it;
135 struct wsm_scan scan = {
136 .type = WSM_SCAN_TYPE_FOREGROUND,
137 .flags = WSM_SCAN_FLAG_SPLIT_METHOD,
138 };
139 bool first_run = (priv->scan.begin == priv->scan.curr &&
140 priv->scan.begin != priv->scan.end);
141 int i;
142
143 if (first_run) {
144 /* Firmware gets crazy if scan request is sent
145 * when STA is joined but not yet associated.
146 * Force unjoin in this case.
147 */
148 if (cancel_delayed_work_sync(&priv->join_timeout) > 0)
149 cw1200_join_timeout(&priv->join_timeout.work);
150 }
151
152 mutex_lock(&priv->conf_mutex);
153
154 if (first_run) {
155 if (priv->join_status == CW1200_JOIN_STATUS_STA &&
156 !(priv->powersave_mode.mode & WSM_PSM_PS)) {
157 struct wsm_set_pm pm = priv->powersave_mode;
158 pm.mode = WSM_PSM_PS;
159 cw1200_set_pm(priv, &pm);
160 } else if (priv->join_status == CW1200_JOIN_STATUS_MONITOR) {
161 /* FW bug: driver has to restart p2p-dev mode
162 * after scan
163 */
164 cw1200_disable_listening(priv);
165 }
166 }
167
168 if (!priv->scan.req || (priv->scan.curr == priv->scan.end)) {
169 if (priv->scan.output_power != priv->output_power)
170 wsm_set_output_power(priv, priv->output_power * 10);
171 if (priv->join_status == CW1200_JOIN_STATUS_STA &&
172 !(priv->powersave_mode.mode & WSM_PSM_PS))
173 cw1200_set_pm(priv, &priv->powersave_mode);
174
175 if (priv->scan.status < 0)
176 wiphy_dbg(priv->hw->wiphy, "[SCAN] Scan failed (%d).\n",
177 priv->scan.status);
178 else if (priv->scan.req)
179 wiphy_dbg(priv->hw->wiphy,
180 "[SCAN] Scan completed.\n");
181 else
182 wiphy_dbg(priv->hw->wiphy,
183 "[SCAN] Scan canceled.\n");
184
185 priv->scan.req = NULL;
186 cw1200_scan_restart_delayed(priv);
187 wsm_unlock_tx(priv);
188 mutex_unlock(&priv->conf_mutex);
189 ieee80211_scan_completed(priv->hw, priv->scan.status ? 1 : 0);
190 up(&priv->scan.lock);
191 return;
192 } else {
193 struct ieee80211_channel *first = *priv->scan.curr;
194 for (it = priv->scan.curr + 1, i = 1;
195 it != priv->scan.end && i < WSM_SCAN_MAX_NUM_OF_CHANNELS;
196 ++it, ++i) {
197 if ((*it)->band != first->band)
198 break;
199 if (((*it)->flags ^ first->flags) &
200 IEEE80211_CHAN_PASSIVE_SCAN)
201 break;
202 if (!(first->flags & IEEE80211_CHAN_PASSIVE_SCAN) &&
203 (*it)->max_power != first->max_power)
204 break;
205 }
206 scan.band = first->band;
207
208 if (priv->scan.req->no_cck)
209 scan.max_tx_rate = WSM_TRANSMIT_RATE_6;
210 else
211 scan.max_tx_rate = WSM_TRANSMIT_RATE_1;
212 scan.num_probes =
213 (first->flags & IEEE80211_CHAN_PASSIVE_SCAN) ? 0 : 2;
214 scan.num_ssids = priv->scan.n_ssids;
215 scan.ssids = &priv->scan.ssids[0];
216 scan.num_channels = it - priv->scan.curr;
217 /* TODO: Is it optimal? */
218 scan.probe_delay = 100;
219 /* It is not stated in WSM specification, however
220 * FW team says that driver may not use FG scan
221 * when joined.
222 */
223 if (priv->join_status == CW1200_JOIN_STATUS_STA) {
224 scan.type = WSM_SCAN_TYPE_BACKGROUND;
225 scan.flags = WSM_SCAN_FLAG_FORCE_BACKGROUND;
226 }
227 scan.ch = kzalloc(
228 sizeof(struct wsm_scan_ch) * (it - priv->scan.curr),
229 GFP_KERNEL);
230 if (!scan.ch) {
231 priv->scan.status = -ENOMEM;
232 goto fail;
233 }
234 for (i = 0; i < scan.num_channels; ++i) {
235 scan.ch[i].number = priv->scan.curr[i]->hw_value;
236 if (priv->scan.curr[i]->flags & IEEE80211_CHAN_PASSIVE_SCAN) {
237 scan.ch[i].min_chan_time = 50;
238 scan.ch[i].max_chan_time = 100;
239 } else {
240 scan.ch[i].min_chan_time = 10;
241 scan.ch[i].max_chan_time = 25;
242 }
243 }
244 if (!(first->flags & IEEE80211_CHAN_PASSIVE_SCAN) &&
245 priv->scan.output_power != first->max_power) {
246 priv->scan.output_power = first->max_power;
247 wsm_set_output_power(priv,
248 priv->scan.output_power * 10);
249 }
250 priv->scan.status = cw1200_scan_start(priv, &scan);
251 kfree(scan.ch);
252 if (priv->scan.status)
253 goto fail;
254 priv->scan.curr = it;
255 }
256 mutex_unlock(&priv->conf_mutex);
257 return;
258
259fail:
260 priv->scan.curr = priv->scan.end;
261 mutex_unlock(&priv->conf_mutex);
262 queue_work(priv->workqueue, &priv->scan.work);
263 return;
264}
265
266static void cw1200_scan_restart_delayed(struct cw1200_common *priv)
267{
268 /* FW bug: driver has to restart p2p-dev mode after scan. */
269 if (priv->join_status == CW1200_JOIN_STATUS_MONITOR) {
270 cw1200_enable_listening(priv);
271 cw1200_update_filtering(priv);
272 }
273
274 if (priv->delayed_unjoin) {
275 priv->delayed_unjoin = false;
276 if (queue_work(priv->workqueue, &priv->unjoin_work) <= 0)
277 wsm_unlock_tx(priv);
278 } else if (priv->delayed_link_loss) {
279 wiphy_dbg(priv->hw->wiphy, "[CQM] Requeue BSS loss.\n");
280 priv->delayed_link_loss = 0;
281 cw1200_cqm_bssloss_sm(priv, 1, 0, 0);
282 }
283}
284
285static void cw1200_scan_complete(struct cw1200_common *priv)
286{
287 queue_delayed_work(priv->workqueue, &priv->clear_recent_scan_work, HZ);
288 if (priv->scan.direct_probe) {
289 wiphy_dbg(priv->hw->wiphy, "[SCAN] Direct probe complete.\n");
290 cw1200_scan_restart_delayed(priv);
291 priv->scan.direct_probe = 0;
292 up(&priv->scan.lock);
293 wsm_unlock_tx(priv);
294 } else {
295 cw1200_scan_work(&priv->scan.work);
296 }
297}
298
299void cw1200_scan_failed_cb(struct cw1200_common *priv)
300{
301 if (priv->mode == NL80211_IFTYPE_UNSPECIFIED)
302 /* STA is stopped. */
303 return;
304
305 if (cancel_delayed_work_sync(&priv->scan.timeout) > 0) {
306 priv->scan.status = -EIO;
307 queue_delayed_work(priv->workqueue, &priv->scan.timeout, 0);
308 }
309}
310
311
312void cw1200_scan_complete_cb(struct cw1200_common *priv,
313 struct wsm_scan_complete *arg)
314{
315 if (priv->mode == NL80211_IFTYPE_UNSPECIFIED)
316 /* STA is stopped. */
317 return;
318
319 if (cancel_delayed_work_sync(&priv->scan.timeout) > 0) {
320 priv->scan.status = 1;
321 queue_delayed_work(priv->workqueue, &priv->scan.timeout, 0);
322 }
323}
324
325void cw1200_clear_recent_scan_work(struct work_struct *work)
326{
327 struct cw1200_common *priv =
328 container_of(work, struct cw1200_common,
329 clear_recent_scan_work.work);
330 atomic_xchg(&priv->recent_scan, 0);
331}
332
333void cw1200_scan_timeout(struct work_struct *work)
334{
335 struct cw1200_common *priv =
336 container_of(work, struct cw1200_common, scan.timeout.work);
337 if (atomic_xchg(&priv->scan.in_progress, 0)) {
338 if (priv->scan.status > 0) {
339 priv->scan.status = 0;
340 } else if (!priv->scan.status) {
341 wiphy_warn(priv->hw->wiphy,
342 "Timeout waiting for scan complete notification.\n");
343 priv->scan.status = -ETIMEDOUT;
344 priv->scan.curr = priv->scan.end;
345 wsm_stop_scan(priv);
346 }
347 cw1200_scan_complete(priv);
348 }
349}
350
351void cw1200_probe_work(struct work_struct *work)
352{
353 struct cw1200_common *priv =
354 container_of(work, struct cw1200_common, scan.probe_work.work);
355 u8 queue_id = cw1200_queue_get_queue_id(priv->pending_frame_id);
356 struct cw1200_queue *queue = &priv->tx_queue[queue_id];
357 const struct cw1200_txpriv *txpriv;
358 struct wsm_tx *wsm;
359 struct wsm_template_frame frame = {
360 .frame_type = WSM_FRAME_TYPE_PROBE_REQUEST,
361 };
362 struct wsm_ssid ssids[1] = {{
363 .length = 0,
364 } };
365 struct wsm_scan_ch ch[1] = {{
366 .min_chan_time = 0,
367 .max_chan_time = 10,
368 } };
369 struct wsm_scan scan = {
370 .type = WSM_SCAN_TYPE_FOREGROUND,
371 .num_probes = 1,
372 .probe_delay = 0,
373 .num_channels = 1,
374 .ssids = ssids,
375 .ch = ch,
376 };
377 u8 *ies;
378 size_t ies_len;
379 int ret;
380
381 wiphy_dbg(priv->hw->wiphy, "[SCAN] Direct probe work.\n");
382
383 mutex_lock(&priv->conf_mutex);
384 if (down_trylock(&priv->scan.lock)) {
385 /* Scan is already in progress. Requeue self. */
386 schedule();
387 queue_delayed_work(priv->workqueue,
388 &priv->scan.probe_work, HZ / 10);
389 mutex_unlock(&priv->conf_mutex);
390 return;
391 }
392
393 /* Make sure we still have a pending probe req */
394 if (cw1200_queue_get_skb(queue, priv->pending_frame_id,
395 &frame.skb, &txpriv)) {
396 up(&priv->scan.lock);
397 mutex_unlock(&priv->conf_mutex);
398 wsm_unlock_tx(priv);
399 return;
400 }
401 wsm = (struct wsm_tx *)frame.skb->data;
402 scan.max_tx_rate = wsm->max_tx_rate;
403 scan.band = (priv->channel->band == IEEE80211_BAND_5GHZ) ?
404 WSM_PHY_BAND_5G : WSM_PHY_BAND_2_4G;
405 if (priv->join_status == CW1200_JOIN_STATUS_STA ||
406 priv->join_status == CW1200_JOIN_STATUS_IBSS) {
407 scan.type = WSM_SCAN_TYPE_BACKGROUND;
408 scan.flags = WSM_SCAN_FLAG_FORCE_BACKGROUND;
409 }
410 ch[0].number = priv->channel->hw_value;
411
412 skb_pull(frame.skb, txpriv->offset);
413
414 ies = &frame.skb->data[sizeof(struct ieee80211_hdr_3addr)];
415 ies_len = frame.skb->len - sizeof(struct ieee80211_hdr_3addr);
416
417 if (ies_len) {
418 u8 *ssidie =
419 (u8 *)cfg80211_find_ie(WLAN_EID_SSID, ies, ies_len);
420 if (ssidie && ssidie[1] && ssidie[1] <= sizeof(ssids[0].ssid)) {
421 u8 *nextie = &ssidie[2 + ssidie[1]];
422 /* Remove SSID from the IE list. It has to be provided
423 * as a separate argument in cw1200_scan_start call
424 */
425
426 /* Store SSID localy */
427 ssids[0].length = ssidie[1];
428 memcpy(ssids[0].ssid, &ssidie[2], ssids[0].length);
429 scan.num_ssids = 1;
430
431 /* Remove SSID from IE list */
432 ssidie[1] = 0;
433 memmove(&ssidie[2], nextie, &ies[ies_len] - nextie);
434 skb_trim(frame.skb, frame.skb->len - ssids[0].length);
435 }
436 }
437
438 /* FW bug: driver has to restart p2p-dev mode after scan */
439 if (priv->join_status == CW1200_JOIN_STATUS_MONITOR)
440 cw1200_disable_listening(priv);
441 ret = wsm_set_template_frame(priv, &frame);
442 priv->scan.direct_probe = 1;
443 if (!ret) {
444 wsm_flush_tx(priv);
445 ret = cw1200_scan_start(priv, &scan);
446 }
447 mutex_unlock(&priv->conf_mutex);
448
449 skb_push(frame.skb, txpriv->offset);
450 if (!ret)
451 IEEE80211_SKB_CB(frame.skb)->flags |= IEEE80211_TX_STAT_ACK;
452 BUG_ON(cw1200_queue_remove(queue, priv->pending_frame_id));
453
454 if (ret) {
455 priv->scan.direct_probe = 0;
456 up(&priv->scan.lock);
457 wsm_unlock_tx(priv);
458 }
459
460 return;
461}
diff --git a/drivers/net/wireless/cw1200/scan.h b/drivers/net/wireless/cw1200/scan.h
new file mode 100644
index 000000000000..5a8296ccfa82
--- /dev/null
+++ b/drivers/net/wireless/cw1200/scan.h
@@ -0,0 +1,56 @@
1/*
2 * Scan interface for ST-Ericsson CW1200 mac80211 drivers
3 *
4 * Copyright (c) 2010, ST-Ericsson
5 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#ifndef SCAN_H_INCLUDED
13#define SCAN_H_INCLUDED
14
15#include <linux/semaphore.h>
16#include "wsm.h"
17
18/* external */ struct sk_buff;
19/* external */ struct cfg80211_scan_request;
20/* external */ struct ieee80211_channel;
21/* external */ struct ieee80211_hw;
22/* external */ struct work_struct;
23
24struct cw1200_scan {
25 struct semaphore lock;
26 struct work_struct work;
27 struct delayed_work timeout;
28 struct cfg80211_scan_request *req;
29 struct ieee80211_channel **begin;
30 struct ieee80211_channel **curr;
31 struct ieee80211_channel **end;
32 struct wsm_ssid ssids[WSM_SCAN_MAX_NUM_OF_SSIDS];
33 int output_power;
34 int n_ssids;
35 int status;
36 atomic_t in_progress;
37 /* Direct probe requests workaround */
38 struct delayed_work probe_work;
39 int direct_probe;
40};
41
42int cw1200_hw_scan(struct ieee80211_hw *hw,
43 struct ieee80211_vif *vif,
44 struct cfg80211_scan_request *req);
45void cw1200_scan_work(struct work_struct *work);
46void cw1200_scan_timeout(struct work_struct *work);
47void cw1200_clear_recent_scan_work(struct work_struct *work);
48void cw1200_scan_complete_cb(struct cw1200_common *priv,
49 struct wsm_scan_complete *arg);
50void cw1200_scan_failed_cb(struct cw1200_common *priv);
51
52/* ******************************************************************** */
53/* Raw probe requests TX workaround */
54void cw1200_probe_work(struct work_struct *work);
55
56#endif
diff --git a/drivers/net/wireless/cw1200/sta.c b/drivers/net/wireless/cw1200/sta.c
new file mode 100644
index 000000000000..4cd0352b508d
--- /dev/null
+++ b/drivers/net/wireless/cw1200/sta.c
@@ -0,0 +1,2404 @@
1/*
2 * Mac80211 STA API for ST-Ericsson CW1200 drivers
3 *
4 * Copyright (c) 2010, ST-Ericsson
5 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/vmalloc.h>
13#include <linux/sched.h>
14#include <linux/firmware.h>
15#include <linux/module.h>
16
17#include "cw1200.h"
18#include "sta.h"
19#include "fwio.h"
20#include "bh.h"
21#include "debug.h"
22
23#ifndef ERP_INFO_BYTE_OFFSET
24#define ERP_INFO_BYTE_OFFSET 2
25#endif
26
27static void cw1200_do_join(struct cw1200_common *priv);
28static void cw1200_do_unjoin(struct cw1200_common *priv);
29
30static int cw1200_upload_beacon(struct cw1200_common *priv);
31static int cw1200_upload_pspoll(struct cw1200_common *priv);
32static int cw1200_upload_null(struct cw1200_common *priv);
33static int cw1200_upload_qosnull(struct cw1200_common *priv);
34static int cw1200_start_ap(struct cw1200_common *priv);
35static int cw1200_update_beaconing(struct cw1200_common *priv);
36static int cw1200_enable_beaconing(struct cw1200_common *priv,
37 bool enable);
38static void __cw1200_sta_notify(struct ieee80211_hw *dev,
39 struct ieee80211_vif *vif,
40 enum sta_notify_cmd notify_cmd,
41 int link_id);
42static int __cw1200_flush(struct cw1200_common *priv, bool drop);
43
44static inline void __cw1200_free_event_queue(struct list_head *list)
45{
46 struct cw1200_wsm_event *event, *tmp;
47 list_for_each_entry_safe(event, tmp, list, link) {
48 list_del(&event->link);
49 kfree(event);
50 }
51}
52
53/* ******************************************************************** */
54/* STA API */
55
56int cw1200_start(struct ieee80211_hw *dev)
57{
58 struct cw1200_common *priv = dev->priv;
59 int ret = 0;
60
61 cw1200_pm_stay_awake(&priv->pm_state, HZ);
62
63 mutex_lock(&priv->conf_mutex);
64
65 /* default EDCA */
66 WSM_EDCA_SET(&priv->edca, 0, 0x0002, 0x0003, 0x0007, 47, 0xc8, false);
67 WSM_EDCA_SET(&priv->edca, 1, 0x0002, 0x0007, 0x000f, 94, 0xc8, false);
68 WSM_EDCA_SET(&priv->edca, 2, 0x0003, 0x000f, 0x03ff, 0, 0xc8, false);
69 WSM_EDCA_SET(&priv->edca, 3, 0x0007, 0x000f, 0x03ff, 0, 0xc8, false);
70 ret = wsm_set_edca_params(priv, &priv->edca);
71 if (ret)
72 goto out;
73
74 ret = cw1200_set_uapsd_param(priv, &priv->edca);
75 if (ret)
76 goto out;
77
78 priv->setbssparams_done = false;
79
80 memcpy(priv->mac_addr, dev->wiphy->perm_addr, ETH_ALEN);
81 priv->mode = NL80211_IFTYPE_MONITOR;
82 priv->wep_default_key_id = -1;
83
84 priv->cqm_beacon_loss_count = 10;
85
86 ret = cw1200_setup_mac(priv);
87 if (ret)
88 goto out;
89
90out:
91 mutex_unlock(&priv->conf_mutex);
92 return ret;
93}
94
95void cw1200_stop(struct ieee80211_hw *dev)
96{
97 struct cw1200_common *priv = dev->priv;
98 LIST_HEAD(list);
99 int i;
100
101 wsm_lock_tx(priv);
102
103 while (down_trylock(&priv->scan.lock)) {
104 /* Scan is in progress. Force it to stop. */
105 priv->scan.req = NULL;
106 schedule();
107 }
108 up(&priv->scan.lock);
109
110 cancel_delayed_work_sync(&priv->scan.probe_work);
111 cancel_delayed_work_sync(&priv->scan.timeout);
112 cancel_delayed_work_sync(&priv->clear_recent_scan_work);
113 cancel_delayed_work_sync(&priv->join_timeout);
114 cw1200_cqm_bssloss_sm(priv, 0, 0, 0);
115 cancel_work_sync(&priv->unjoin_work);
116 cancel_delayed_work_sync(&priv->link_id_gc_work);
117 flush_workqueue(priv->workqueue);
118 del_timer_sync(&priv->mcast_timeout);
119 mutex_lock(&priv->conf_mutex);
120 priv->mode = NL80211_IFTYPE_UNSPECIFIED;
121 priv->listening = false;
122
123 spin_lock(&priv->event_queue_lock);
124 list_splice_init(&priv->event_queue, &list);
125 spin_unlock(&priv->event_queue_lock);
126 __cw1200_free_event_queue(&list);
127
128
129 priv->join_status = CW1200_JOIN_STATUS_PASSIVE;
130 priv->join_pending = false;
131
132 for (i = 0; i < 4; i++)
133 cw1200_queue_clear(&priv->tx_queue[i]);
134 mutex_unlock(&priv->conf_mutex);
135 tx_policy_clean(priv);
136
137 /* HACK! */
138 if (atomic_xchg(&priv->tx_lock, 1) != 1)
139 pr_debug("[STA] TX is force-unlocked due to stop request.\n");
140
141 wsm_unlock_tx(priv);
142 atomic_xchg(&priv->tx_lock, 0); /* for recovery to work */
143}
144
145static int cw1200_bssloss_mitigation = 1;
146module_param(cw1200_bssloss_mitigation, int, 0644);
147MODULE_PARM_DESC(cw1200_bssloss_mitigation, "BSS Loss mitigation. 0 == disabled, 1 == enabled (default)");
148
149
150void __cw1200_cqm_bssloss_sm(struct cw1200_common *priv,
151 int init, int good, int bad)
152{
153 int tx = 0;
154
155 priv->delayed_link_loss = 0;
156 cancel_work_sync(&priv->bss_params_work);
157
158 pr_debug("[STA] CQM BSSLOSS_SM: state: %d init %d good %d bad: %d txlock: %d uj: %d\n",
159 priv->bss_loss_state,
160 init, good, bad,
161 atomic_read(&priv->tx_lock),
162 priv->delayed_unjoin);
163
164 /* If we have a pending unjoin */
165 if (priv->delayed_unjoin)
166 return;
167
168 if (init) {
169 queue_delayed_work(priv->workqueue,
170 &priv->bss_loss_work,
171 HZ);
172 priv->bss_loss_state = 0;
173
174 /* Skip the confimration procedure in P2P case */
175 if (!priv->vif->p2p && !atomic_read(&priv->tx_lock))
176 tx = 1;
177 } else if (good) {
178 cancel_delayed_work_sync(&priv->bss_loss_work);
179 priv->bss_loss_state = 0;
180 queue_work(priv->workqueue, &priv->bss_params_work);
181 } else if (bad) {
182 /* XXX Should we just keep going until we time out? */
183 if (priv->bss_loss_state < 3)
184 tx = 1;
185 } else {
186 cancel_delayed_work_sync(&priv->bss_loss_work);
187 priv->bss_loss_state = 0;
188 }
189
190 /* Bypass mitigation if it's disabled */
191 if (!cw1200_bssloss_mitigation)
192 tx = 0;
193
194 /* Spit out a NULL packet to our AP if necessary */
195 if (tx) {
196 struct sk_buff *skb;
197
198 priv->bss_loss_state++;
199
200 skb = ieee80211_nullfunc_get(priv->hw, priv->vif);
201 WARN_ON(!skb);
202 if (skb)
203 cw1200_tx(priv->hw, NULL, skb);
204 }
205}
206
207int cw1200_add_interface(struct ieee80211_hw *dev,
208 struct ieee80211_vif *vif)
209{
210 int ret;
211 struct cw1200_common *priv = dev->priv;
212 /* __le32 auto_calibration_mode = __cpu_to_le32(1); */
213
214 vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER |
215 IEEE80211_VIF_SUPPORTS_CQM_RSSI;
216
217 mutex_lock(&priv->conf_mutex);
218
219 if (priv->mode != NL80211_IFTYPE_MONITOR) {
220 mutex_unlock(&priv->conf_mutex);
221 return -EOPNOTSUPP;
222 }
223
224 switch (vif->type) {
225 case NL80211_IFTYPE_STATION:
226 case NL80211_IFTYPE_ADHOC:
227 case NL80211_IFTYPE_MESH_POINT:
228 case NL80211_IFTYPE_AP:
229 priv->mode = vif->type;
230 break;
231 default:
232 mutex_unlock(&priv->conf_mutex);
233 return -EOPNOTSUPP;
234 }
235
236 priv->vif = vif;
237 memcpy(priv->mac_addr, vif->addr, ETH_ALEN);
238 ret = cw1200_setup_mac(priv);
239 /* Enable auto-calibration */
240 /* Exception in subsequent channel switch; disabled.
241 * wsm_write_mib(priv, WSM_MIB_ID_SET_AUTO_CALIBRATION_MODE,
242 * &auto_calibration_mode, sizeof(auto_calibration_mode));
243 */
244
245 mutex_unlock(&priv->conf_mutex);
246 return ret;
247}
248
249void cw1200_remove_interface(struct ieee80211_hw *dev,
250 struct ieee80211_vif *vif)
251{
252 struct cw1200_common *priv = dev->priv;
253 struct wsm_reset reset = {
254 .reset_statistics = true,
255 };
256 int i;
257
258 mutex_lock(&priv->conf_mutex);
259 switch (priv->join_status) {
260 case CW1200_JOIN_STATUS_JOINING:
261 case CW1200_JOIN_STATUS_PRE_STA:
262 case CW1200_JOIN_STATUS_STA:
263 case CW1200_JOIN_STATUS_IBSS:
264 wsm_lock_tx(priv);
265 if (queue_work(priv->workqueue, &priv->unjoin_work) <= 0)
266 wsm_unlock_tx(priv);
267 break;
268 case CW1200_JOIN_STATUS_AP:
269 for (i = 0; priv->link_id_map; ++i) {
270 if (priv->link_id_map & BIT(i)) {
271 reset.link_id = i;
272 wsm_reset(priv, &reset);
273 priv->link_id_map &= ~BIT(i);
274 }
275 }
276 memset(priv->link_id_db, 0, sizeof(priv->link_id_db));
277 priv->sta_asleep_mask = 0;
278 priv->enable_beacon = false;
279 priv->tx_multicast = false;
280 priv->aid0_bit_set = false;
281 priv->buffered_multicasts = false;
282 priv->pspoll_mask = 0;
283 reset.link_id = 0;
284 wsm_reset(priv, &reset);
285 break;
286 case CW1200_JOIN_STATUS_MONITOR:
287 cw1200_update_listening(priv, false);
288 break;
289 default:
290 break;
291 }
292 priv->vif = NULL;
293 priv->mode = NL80211_IFTYPE_MONITOR;
294 memset(priv->mac_addr, 0, ETH_ALEN);
295 memset(&priv->p2p_ps_modeinfo, 0, sizeof(priv->p2p_ps_modeinfo));
296 cw1200_free_keys(priv);
297 cw1200_setup_mac(priv);
298 priv->listening = false;
299 priv->join_status = CW1200_JOIN_STATUS_PASSIVE;
300 if (!__cw1200_flush(priv, true))
301 wsm_unlock_tx(priv);
302
303 mutex_unlock(&priv->conf_mutex);
304}
305
306int cw1200_change_interface(struct ieee80211_hw *dev,
307 struct ieee80211_vif *vif,
308 enum nl80211_iftype new_type,
309 bool p2p)
310{
311 int ret = 0;
312 pr_debug("change_interface new: %d (%d), old: %d (%d)\n", new_type,
313 p2p, vif->type, vif->p2p);
314
315 if (new_type != vif->type || vif->p2p != p2p) {
316 cw1200_remove_interface(dev, vif);
317 vif->type = new_type;
318 vif->p2p = p2p;
319 ret = cw1200_add_interface(dev, vif);
320 }
321
322 return ret;
323}
324
325int cw1200_config(struct ieee80211_hw *dev, u32 changed)
326{
327 int ret = 0;
328 struct cw1200_common *priv = dev->priv;
329 struct ieee80211_conf *conf = &dev->conf;
330
331 pr_debug("CONFIG CHANGED: %08x\n", changed);
332
333 down(&priv->scan.lock);
334 mutex_lock(&priv->conf_mutex);
335 /* TODO: IEEE80211_CONF_CHANGE_QOS */
336 /* TODO: IEEE80211_CONF_CHANGE_LISTEN_INTERVAL */
337
338 if (changed & IEEE80211_CONF_CHANGE_POWER) {
339 priv->output_power = conf->power_level;
340 pr_debug("[STA] TX power: %d\n", priv->output_power);
341 wsm_set_output_power(priv, priv->output_power * 10);
342 }
343
344 if ((changed & IEEE80211_CONF_CHANGE_CHANNEL) &&
345 (priv->channel != conf->chandef.chan)) {
346 struct ieee80211_channel *ch = conf->chandef.chan;
347 struct wsm_switch_channel channel = {
348 .channel_number = ch->hw_value,
349 };
350 pr_debug("[STA] Freq %d (wsm ch: %d).\n",
351 ch->center_freq, ch->hw_value);
352
353 /* __cw1200_flush() implicitly locks tx, if successful */
354 if (!__cw1200_flush(priv, false)) {
355 if (!wsm_switch_channel(priv, &channel)) {
356 ret = wait_event_timeout(priv->channel_switch_done,
357 !priv->channel_switch_in_progress,
358 3 * HZ);
359 if (ret) {
360 /* Already unlocks if successful */
361 priv->channel = ch;
362 ret = 0;
363 } else {
364 ret = -ETIMEDOUT;
365 }
366 } else {
367 /* Unlock if switch channel fails */
368 wsm_unlock_tx(priv);
369 }
370 }
371 }
372
373 if (changed & IEEE80211_CONF_CHANGE_PS) {
374 if (!(conf->flags & IEEE80211_CONF_PS))
375 priv->powersave_mode.mode = WSM_PSM_ACTIVE;
376 else if (conf->dynamic_ps_timeout <= 0)
377 priv->powersave_mode.mode = WSM_PSM_PS;
378 else
379 priv->powersave_mode.mode = WSM_PSM_FAST_PS;
380
381 /* Firmware requires that value for this 1-byte field must
382 * be specified in units of 500us. Values above the 128ms
383 * threshold are not supported.
384 */
385 if (conf->dynamic_ps_timeout >= 0x80)
386 priv->powersave_mode.fast_psm_idle_period = 0xFF;
387 else
388 priv->powersave_mode.fast_psm_idle_period =
389 conf->dynamic_ps_timeout << 1;
390
391 if (priv->join_status == CW1200_JOIN_STATUS_STA &&
392 priv->bss_params.aid)
393 cw1200_set_pm(priv, &priv->powersave_mode);
394 }
395
396 if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
397 /* TBD: It looks like it's transparent
398 * there's a monitor interface present -- use this
399 * to determine for example whether to calculate
400 * timestamps for packets or not, do not use instead
401 * of filter flags!
402 */
403 }
404
405 if (changed & IEEE80211_CONF_CHANGE_IDLE) {
406 struct wsm_operational_mode mode = {
407 .power_mode = cw1200_power_mode,
408 .disable_more_flag_usage = true,
409 };
410
411 wsm_lock_tx(priv);
412 /* Disable p2p-dev mode forced by TX request */
413 if ((priv->join_status == CW1200_JOIN_STATUS_MONITOR) &&
414 (conf->flags & IEEE80211_CONF_IDLE) &&
415 !priv->listening) {
416 cw1200_disable_listening(priv);
417 priv->join_status = CW1200_JOIN_STATUS_PASSIVE;
418 }
419 wsm_set_operational_mode(priv, &mode);
420 wsm_unlock_tx(priv);
421 }
422
423 if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) {
424 pr_debug("[STA] Retry limits: %d (long), %d (short).\n",
425 conf->long_frame_max_tx_count,
426 conf->short_frame_max_tx_count);
427 spin_lock_bh(&priv->tx_policy_cache.lock);
428 priv->long_frame_max_tx_count = conf->long_frame_max_tx_count;
429 priv->short_frame_max_tx_count =
430 (conf->short_frame_max_tx_count < 0x0F) ?
431 conf->short_frame_max_tx_count : 0x0F;
432 priv->hw->max_rate_tries = priv->short_frame_max_tx_count;
433 spin_unlock_bh(&priv->tx_policy_cache.lock);
434 }
435 mutex_unlock(&priv->conf_mutex);
436 up(&priv->scan.lock);
437 return ret;
438}
439
440void cw1200_update_filtering(struct cw1200_common *priv)
441{
442 int ret;
443 bool bssid_filtering = !priv->rx_filter.bssid;
444 bool is_p2p = priv->vif && priv->vif->p2p;
445 bool is_sta = priv->vif && NL80211_IFTYPE_STATION == priv->vif->type;
446
447 static struct wsm_beacon_filter_control bf_ctrl;
448 static struct wsm_mib_beacon_filter_table bf_tbl = {
449 .entry[0].ie_id = WLAN_EID_VENDOR_SPECIFIC,
450 .entry[0].flags = WSM_BEACON_FILTER_IE_HAS_CHANGED |
451 WSM_BEACON_FILTER_IE_NO_LONGER_PRESENT |
452 WSM_BEACON_FILTER_IE_HAS_APPEARED,
453 .entry[0].oui[0] = 0x50,
454 .entry[0].oui[1] = 0x6F,
455 .entry[0].oui[2] = 0x9A,
456 .entry[1].ie_id = WLAN_EID_HT_OPERATION,
457 .entry[1].flags = WSM_BEACON_FILTER_IE_HAS_CHANGED |
458 WSM_BEACON_FILTER_IE_NO_LONGER_PRESENT |
459 WSM_BEACON_FILTER_IE_HAS_APPEARED,
460 .entry[2].ie_id = WLAN_EID_ERP_INFO,
461 .entry[2].flags = WSM_BEACON_FILTER_IE_HAS_CHANGED |
462 WSM_BEACON_FILTER_IE_NO_LONGER_PRESENT |
463 WSM_BEACON_FILTER_IE_HAS_APPEARED,
464 };
465
466 if (priv->join_status == CW1200_JOIN_STATUS_PASSIVE)
467 return;
468 else if (priv->join_status == CW1200_JOIN_STATUS_MONITOR)
469 bssid_filtering = false;
470
471 if (priv->disable_beacon_filter) {
472 bf_ctrl.enabled = 0;
473 bf_ctrl.bcn_count = 1;
474 bf_tbl.num = __cpu_to_le32(0);
475 } else if (is_p2p || !is_sta) {
476 bf_ctrl.enabled = WSM_BEACON_FILTER_ENABLE |
477 WSM_BEACON_FILTER_AUTO_ERP;
478 bf_ctrl.bcn_count = 0;
479 bf_tbl.num = __cpu_to_le32(2);
480 } else {
481 bf_ctrl.enabled = WSM_BEACON_FILTER_ENABLE;
482 bf_ctrl.bcn_count = 0;
483 bf_tbl.num = __cpu_to_le32(3);
484 }
485
486 /* When acting as p2p client being connected to p2p GO, in order to
487 * receive frames from a different p2p device, turn off bssid filter.
488 *
489 * WARNING: FW dependency!
490 * This can only be used with FW WSM371 and its successors.
491 * In that FW version even with bssid filter turned off,
492 * device will block most of the unwanted frames.
493 */
494 if (is_p2p)
495 bssid_filtering = false;
496
497 ret = wsm_set_rx_filter(priv, &priv->rx_filter);
498 if (!ret)
499 ret = wsm_set_beacon_filter_table(priv, &bf_tbl);
500 if (!ret)
501 ret = wsm_beacon_filter_control(priv, &bf_ctrl);
502 if (!ret)
503 ret = wsm_set_bssid_filtering(priv, bssid_filtering);
504 if (!ret)
505 ret = wsm_set_multicast_filter(priv, &priv->multicast_filter);
506 if (ret)
507 wiphy_err(priv->hw->wiphy,
508 "Update filtering failed: %d.\n", ret);
509 return;
510}
511
512void cw1200_update_filtering_work(struct work_struct *work)
513{
514 struct cw1200_common *priv =
515 container_of(work, struct cw1200_common,
516 update_filtering_work);
517
518 cw1200_update_filtering(priv);
519}
520
521void cw1200_set_beacon_wakeup_period_work(struct work_struct *work)
522{
523 struct cw1200_common *priv =
524 container_of(work, struct cw1200_common,
525 set_beacon_wakeup_period_work);
526
527 wsm_set_beacon_wakeup_period(priv,
528 priv->beacon_int * priv->join_dtim_period >
529 MAX_BEACON_SKIP_TIME_MS ? 1 :
530 priv->join_dtim_period, 0);
531}
532
533u64 cw1200_prepare_multicast(struct ieee80211_hw *hw,
534 struct netdev_hw_addr_list *mc_list)
535{
536 static u8 broadcast_ipv6[ETH_ALEN] = {
537 0x33, 0x33, 0x00, 0x00, 0x00, 0x01
538 };
539 static u8 broadcast_ipv4[ETH_ALEN] = {
540 0x01, 0x00, 0x5e, 0x00, 0x00, 0x01
541 };
542 struct cw1200_common *priv = hw->priv;
543 struct netdev_hw_addr *ha;
544 int count = 0;
545
546 /* Disable multicast filtering */
547 priv->has_multicast_subscription = false;
548 memset(&priv->multicast_filter, 0x00, sizeof(priv->multicast_filter));
549
550 if (netdev_hw_addr_list_count(mc_list) > WSM_MAX_GRP_ADDRTABLE_ENTRIES)
551 return 0;
552
553 /* Enable if requested */
554 netdev_hw_addr_list_for_each(ha, mc_list) {
555 pr_debug("[STA] multicast: %pM\n", ha->addr);
556 memcpy(&priv->multicast_filter.macaddrs[count],
557 ha->addr, ETH_ALEN);
558 if (memcmp(ha->addr, broadcast_ipv4, ETH_ALEN) &&
559 memcmp(ha->addr, broadcast_ipv6, ETH_ALEN))
560 priv->has_multicast_subscription = true;
561 count++;
562 }
563
564 if (count) {
565 priv->multicast_filter.enable = __cpu_to_le32(1);
566 priv->multicast_filter.num_addrs = __cpu_to_le32(count);
567 }
568
569 return netdev_hw_addr_list_count(mc_list);
570}
571
572void cw1200_configure_filter(struct ieee80211_hw *dev,
573 unsigned int changed_flags,
574 unsigned int *total_flags,
575 u64 multicast)
576{
577 struct cw1200_common *priv = dev->priv;
578 bool listening = !!(*total_flags &
579 (FIF_PROMISC_IN_BSS |
580 FIF_OTHER_BSS |
581 FIF_BCN_PRBRESP_PROMISC |
582 FIF_PROBE_REQ));
583
584 *total_flags &= FIF_PROMISC_IN_BSS |
585 FIF_OTHER_BSS |
586 FIF_FCSFAIL |
587 FIF_BCN_PRBRESP_PROMISC |
588 FIF_PROBE_REQ;
589
590 down(&priv->scan.lock);
591 mutex_lock(&priv->conf_mutex);
592
593 priv->rx_filter.promiscuous = (*total_flags & FIF_PROMISC_IN_BSS)
594 ? 1 : 0;
595 priv->rx_filter.bssid = (*total_flags & (FIF_OTHER_BSS |
596 FIF_PROBE_REQ)) ? 1 : 0;
597 priv->rx_filter.fcs = (*total_flags & FIF_FCSFAIL) ? 1 : 0;
598 priv->disable_beacon_filter = !(*total_flags &
599 (FIF_BCN_PRBRESP_PROMISC |
600 FIF_PROMISC_IN_BSS |
601 FIF_PROBE_REQ));
602 if (priv->listening != listening) {
603 priv->listening = listening;
604 wsm_lock_tx(priv);
605 cw1200_update_listening(priv, listening);
606 wsm_unlock_tx(priv);
607 }
608 cw1200_update_filtering(priv);
609 mutex_unlock(&priv->conf_mutex);
610 up(&priv->scan.lock);
611}
612
613int cw1200_conf_tx(struct ieee80211_hw *dev, struct ieee80211_vif *vif,
614 u16 queue, const struct ieee80211_tx_queue_params *params)
615{
616 struct cw1200_common *priv = dev->priv;
617 int ret = 0;
618 /* To prevent re-applying PM request OID again and again*/
619 bool old_uapsd_flags;
620
621 mutex_lock(&priv->conf_mutex);
622
623 if (queue < dev->queues) {
624 old_uapsd_flags = priv->uapsd_info.uapsd_flags;
625
626 WSM_TX_QUEUE_SET(&priv->tx_queue_params, queue, 0, 0, 0);
627 ret = wsm_set_tx_queue_params(priv,
628 &priv->tx_queue_params.params[queue], queue);
629 if (ret) {
630 ret = -EINVAL;
631 goto out;
632 }
633
634 WSM_EDCA_SET(&priv->edca, queue, params->aifs,
635 params->cw_min, params->cw_max,
636 params->txop, 0xc8,
637 params->uapsd);
638 ret = wsm_set_edca_params(priv, &priv->edca);
639 if (ret) {
640 ret = -EINVAL;
641 goto out;
642 }
643
644 if (priv->mode == NL80211_IFTYPE_STATION) {
645 ret = cw1200_set_uapsd_param(priv, &priv->edca);
646 if (!ret && priv->setbssparams_done &&
647 (priv->join_status == CW1200_JOIN_STATUS_STA) &&
648 (old_uapsd_flags != priv->uapsd_info.uapsd_flags))
649 ret = cw1200_set_pm(priv, &priv->powersave_mode);
650 }
651 } else {
652 ret = -EINVAL;
653 }
654
655out:
656 mutex_unlock(&priv->conf_mutex);
657 return ret;
658}
659
660int cw1200_get_stats(struct ieee80211_hw *dev,
661 struct ieee80211_low_level_stats *stats)
662{
663 struct cw1200_common *priv = dev->priv;
664
665 memcpy(stats, &priv->stats, sizeof(*stats));
666 return 0;
667}
668
669int cw1200_set_pm(struct cw1200_common *priv, const struct wsm_set_pm *arg)
670{
671 struct wsm_set_pm pm = *arg;
672
673 if (priv->uapsd_info.uapsd_flags != 0)
674 pm.mode &= ~WSM_PSM_FAST_PS_FLAG;
675
676 if (memcmp(&pm, &priv->firmware_ps_mode,
677 sizeof(struct wsm_set_pm))) {
678 priv->firmware_ps_mode = pm;
679 return wsm_set_pm(priv, &pm);
680 } else {
681 return 0;
682 }
683}
684
685int cw1200_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd,
686 struct ieee80211_vif *vif, struct ieee80211_sta *sta,
687 struct ieee80211_key_conf *key)
688{
689 int ret = -EOPNOTSUPP;
690 struct cw1200_common *priv = dev->priv;
691 struct ieee80211_key_seq seq;
692
693 mutex_lock(&priv->conf_mutex);
694
695 if (cmd == SET_KEY) {
696 u8 *peer_addr = NULL;
697 int pairwise = (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) ?
698 1 : 0;
699 int idx = cw1200_alloc_key(priv);
700 struct wsm_add_key *wsm_key = &priv->keys[idx];
701
702 if (idx < 0) {
703 ret = -EINVAL;
704 goto finally;
705 }
706
707 if (sta)
708 peer_addr = sta->addr;
709
710 key->flags |= IEEE80211_KEY_FLAG_PUT_IV_SPACE;
711
712 switch (key->cipher) {
713 case WLAN_CIPHER_SUITE_WEP40:
714 case WLAN_CIPHER_SUITE_WEP104:
715 if (key->keylen > 16) {
716 cw1200_free_key(priv, idx);
717 ret = -EINVAL;
718 goto finally;
719 }
720
721 if (pairwise) {
722 wsm_key->type = WSM_KEY_TYPE_WEP_PAIRWISE;
723 memcpy(wsm_key->wep_pairwise.peer,
724 peer_addr, ETH_ALEN);
725 memcpy(wsm_key->wep_pairwise.keydata,
726 &key->key[0], key->keylen);
727 wsm_key->wep_pairwise.keylen = key->keylen;
728 } else {
729 wsm_key->type = WSM_KEY_TYPE_WEP_DEFAULT;
730 memcpy(wsm_key->wep_group.keydata,
731 &key->key[0], key->keylen);
732 wsm_key->wep_group.keylen = key->keylen;
733 wsm_key->wep_group.keyid = key->keyidx;
734 }
735 break;
736 case WLAN_CIPHER_SUITE_TKIP:
737 ieee80211_get_key_rx_seq(key, 0, &seq);
738 if (pairwise) {
739 wsm_key->type = WSM_KEY_TYPE_TKIP_PAIRWISE;
740 memcpy(wsm_key->tkip_pairwise.peer,
741 peer_addr, ETH_ALEN);
742 memcpy(wsm_key->tkip_pairwise.keydata,
743 &key->key[0], 16);
744 memcpy(wsm_key->tkip_pairwise.tx_mic_key,
745 &key->key[16], 8);
746 memcpy(wsm_key->tkip_pairwise.rx_mic_key,
747 &key->key[24], 8);
748 } else {
749 size_t mic_offset =
750 (priv->mode == NL80211_IFTYPE_AP) ?
751 16 : 24;
752 wsm_key->type = WSM_KEY_TYPE_TKIP_GROUP;
753 memcpy(wsm_key->tkip_group.keydata,
754 &key->key[0], 16);
755 memcpy(wsm_key->tkip_group.rx_mic_key,
756 &key->key[mic_offset], 8);
757
758 wsm_key->tkip_group.rx_seqnum[0] = seq.tkip.iv16 & 0xff;
759 wsm_key->tkip_group.rx_seqnum[1] = (seq.tkip.iv16 >> 8) & 0xff;
760 wsm_key->tkip_group.rx_seqnum[2] = seq.tkip.iv32 & 0xff;
761 wsm_key->tkip_group.rx_seqnum[3] = (seq.tkip.iv32 >> 8) & 0xff;
762 wsm_key->tkip_group.rx_seqnum[4] = (seq.tkip.iv32 >> 16) & 0xff;
763 wsm_key->tkip_group.rx_seqnum[5] = (seq.tkip.iv32 >> 24) & 0xff;
764 wsm_key->tkip_group.rx_seqnum[6] = 0;
765 wsm_key->tkip_group.rx_seqnum[7] = 0;
766
767 wsm_key->tkip_group.keyid = key->keyidx;
768 }
769 break;
770 case WLAN_CIPHER_SUITE_CCMP:
771 ieee80211_get_key_rx_seq(key, 0, &seq);
772 if (pairwise) {
773 wsm_key->type = WSM_KEY_TYPE_AES_PAIRWISE;
774 memcpy(wsm_key->aes_pairwise.peer,
775 peer_addr, ETH_ALEN);
776 memcpy(wsm_key->aes_pairwise.keydata,
777 &key->key[0], 16);
778 } else {
779 wsm_key->type = WSM_KEY_TYPE_AES_GROUP;
780 memcpy(wsm_key->aes_group.keydata,
781 &key->key[0], 16);
782
783 wsm_key->aes_group.rx_seqnum[0] = seq.ccmp.pn[5];
784 wsm_key->aes_group.rx_seqnum[1] = seq.ccmp.pn[4];
785 wsm_key->aes_group.rx_seqnum[2] = seq.ccmp.pn[3];
786 wsm_key->aes_group.rx_seqnum[3] = seq.ccmp.pn[2];
787 wsm_key->aes_group.rx_seqnum[4] = seq.ccmp.pn[1];
788 wsm_key->aes_group.rx_seqnum[5] = seq.ccmp.pn[0];
789 wsm_key->aes_group.rx_seqnum[6] = 0;
790 wsm_key->aes_group.rx_seqnum[7] = 0;
791 wsm_key->aes_group.keyid = key->keyidx;
792 }
793 break;
794 case WLAN_CIPHER_SUITE_SMS4:
795 if (pairwise) {
796 wsm_key->type = WSM_KEY_TYPE_WAPI_PAIRWISE;
797 memcpy(wsm_key->wapi_pairwise.peer,
798 peer_addr, ETH_ALEN);
799 memcpy(wsm_key->wapi_pairwise.keydata,
800 &key->key[0], 16);
801 memcpy(wsm_key->wapi_pairwise.mic_key,
802 &key->key[16], 16);
803 wsm_key->wapi_pairwise.keyid = key->keyidx;
804 } else {
805 wsm_key->type = WSM_KEY_TYPE_WAPI_GROUP;
806 memcpy(wsm_key->wapi_group.keydata,
807 &key->key[0], 16);
808 memcpy(wsm_key->wapi_group.mic_key,
809 &key->key[16], 16);
810 wsm_key->wapi_group.keyid = key->keyidx;
811 }
812 break;
813 default:
814 pr_warn("Unhandled key type %d\n", key->cipher);
815 cw1200_free_key(priv, idx);
816 ret = -EOPNOTSUPP;
817 goto finally;
818 }
819 ret = wsm_add_key(priv, wsm_key);
820 if (!ret)
821 key->hw_key_idx = idx;
822 else
823 cw1200_free_key(priv, idx);
824 } else if (cmd == DISABLE_KEY) {
825 struct wsm_remove_key wsm_key = {
826 .index = key->hw_key_idx,
827 };
828
829 if (wsm_key.index > WSM_KEY_MAX_INDEX) {
830 ret = -EINVAL;
831 goto finally;
832 }
833
834 cw1200_free_key(priv, wsm_key.index);
835 ret = wsm_remove_key(priv, &wsm_key);
836 } else {
837 pr_warn("Unhandled key command %d\n", cmd);
838 }
839
840finally:
841 mutex_unlock(&priv->conf_mutex);
842 return ret;
843}
844
845void cw1200_wep_key_work(struct work_struct *work)
846{
847 struct cw1200_common *priv =
848 container_of(work, struct cw1200_common, wep_key_work);
849 u8 queue_id = cw1200_queue_get_queue_id(priv->pending_frame_id);
850 struct cw1200_queue *queue = &priv->tx_queue[queue_id];
851 __le32 wep_default_key_id = __cpu_to_le32(
852 priv->wep_default_key_id);
853
854 pr_debug("[STA] Setting default WEP key: %d\n",
855 priv->wep_default_key_id);
856 wsm_flush_tx(priv);
857 wsm_write_mib(priv, WSM_MIB_ID_DOT11_WEP_DEFAULT_KEY_ID,
858 &wep_default_key_id, sizeof(wep_default_key_id));
859 cw1200_queue_requeue(queue, priv->pending_frame_id);
860 wsm_unlock_tx(priv);
861}
862
863int cw1200_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
864{
865 int ret = 0;
866 __le32 val32;
867 struct cw1200_common *priv = hw->priv;
868
869 if (priv->mode == NL80211_IFTYPE_UNSPECIFIED)
870 return 0;
871
872 if (value != (u32) -1)
873 val32 = __cpu_to_le32(value);
874 else
875 val32 = 0; /* disabled */
876
877 if (priv->mode == NL80211_IFTYPE_UNSPECIFIED) {
878 /* device is down, can _not_ set threshold */
879 ret = -ENODEV;
880 goto out;
881 }
882
883 if (priv->rts_threshold == value)
884 goto out;
885
886 pr_debug("[STA] Setting RTS threshold: %d\n",
887 priv->rts_threshold);
888
889 /* mutex_lock(&priv->conf_mutex); */
890 ret = wsm_write_mib(priv, WSM_MIB_ID_DOT11_RTS_THRESHOLD,
891 &val32, sizeof(val32));
892 if (!ret)
893 priv->rts_threshold = value;
894 /* mutex_unlock(&priv->conf_mutex); */
895
896out:
897 return ret;
898}
899
900/* If successful, LOCKS the TX queue! */
901static int __cw1200_flush(struct cw1200_common *priv, bool drop)
902{
903 int i, ret;
904
905 for (;;) {
906 /* TODO: correct flush handling is required when dev_stop.
907 * Temporary workaround: 2s
908 */
909 if (drop) {
910 for (i = 0; i < 4; ++i)
911 cw1200_queue_clear(&priv->tx_queue[i]);
912 } else {
913 ret = wait_event_timeout(
914 priv->tx_queue_stats.wait_link_id_empty,
915 cw1200_queue_stats_is_empty(
916 &priv->tx_queue_stats, -1),
917 2 * HZ);
918 }
919
920 if (!drop && ret <= 0) {
921 ret = -ETIMEDOUT;
922 break;
923 } else {
924 ret = 0;
925 }
926
927 wsm_lock_tx(priv);
928 if (!cw1200_queue_stats_is_empty(&priv->tx_queue_stats, -1)) {
929 /* Highly unlikely: WSM requeued frames. */
930 wsm_unlock_tx(priv);
931 continue;
932 }
933 break;
934 }
935 return ret;
936}
937
938void cw1200_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
939{
940 struct cw1200_common *priv = hw->priv;
941
942 switch (priv->mode) {
943 case NL80211_IFTYPE_MONITOR:
944 drop = true;
945 break;
946 case NL80211_IFTYPE_AP:
947 if (!priv->enable_beacon)
948 drop = true;
949 break;
950 }
951
952 if (!__cw1200_flush(priv, drop))
953 wsm_unlock_tx(priv);
954
955 return;
956}
957
958/* ******************************************************************** */
959/* WSM callbacks */
960
961void cw1200_free_event_queue(struct cw1200_common *priv)
962{
963 LIST_HEAD(list);
964
965 spin_lock(&priv->event_queue_lock);
966 list_splice_init(&priv->event_queue, &list);
967 spin_unlock(&priv->event_queue_lock);
968
969 __cw1200_free_event_queue(&list);
970}
971
972void cw1200_event_handler(struct work_struct *work)
973{
974 struct cw1200_common *priv =
975 container_of(work, struct cw1200_common, event_handler);
976 struct cw1200_wsm_event *event;
977 LIST_HEAD(list);
978
979 spin_lock(&priv->event_queue_lock);
980 list_splice_init(&priv->event_queue, &list);
981 spin_unlock(&priv->event_queue_lock);
982
983 list_for_each_entry(event, &list, link) {
984 switch (event->evt.id) {
985 case WSM_EVENT_ERROR:
986 pr_err("Unhandled WSM Error from LMAC\n");
987 break;
988 case WSM_EVENT_BSS_LOST:
989 pr_debug("[CQM] BSS lost.\n");
990 cancel_work_sync(&priv->unjoin_work);
991 if (!down_trylock(&priv->scan.lock)) {
992 cw1200_cqm_bssloss_sm(priv, 1, 0, 0);
993 up(&priv->scan.lock);
994 } else {
995 /* Scan is in progress. Delay reporting.
996 * Scan complete will trigger bss_loss_work
997 */
998 priv->delayed_link_loss = 1;
999 /* Also start a watchdog. */
1000 queue_delayed_work(priv->workqueue,
1001 &priv->bss_loss_work, 5*HZ);
1002 }
1003 break;
1004 case WSM_EVENT_BSS_REGAINED:
1005 pr_debug("[CQM] BSS regained.\n");
1006 cw1200_cqm_bssloss_sm(priv, 0, 0, 0);
1007 cancel_work_sync(&priv->unjoin_work);
1008 break;
1009 case WSM_EVENT_RADAR_DETECTED:
1010 wiphy_info(priv->hw->wiphy, "radar pulse detected\n");
1011 break;
1012 case WSM_EVENT_RCPI_RSSI:
1013 {
1014 /* RSSI: signed Q8.0, RCPI: unsigned Q7.1
1015 * RSSI = RCPI / 2 - 110
1016 */
1017 int rcpi_rssi = (int)(event->evt.data & 0xFF);
1018 int cqm_evt;
1019 if (priv->cqm_use_rssi)
1020 rcpi_rssi = (s8)rcpi_rssi;
1021 else
1022 rcpi_rssi = rcpi_rssi / 2 - 110;
1023
1024 cqm_evt = (rcpi_rssi <= priv->cqm_rssi_thold) ?
1025 NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW :
1026 NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH;
1027 pr_debug("[CQM] RSSI event: %d.\n", rcpi_rssi);
1028 ieee80211_cqm_rssi_notify(priv->vif, cqm_evt,
1029 GFP_KERNEL);
1030 break;
1031 }
1032 case WSM_EVENT_BT_INACTIVE:
1033 pr_warn("Unhandled BT INACTIVE from LMAC\n");
1034 break;
1035 case WSM_EVENT_BT_ACTIVE:
1036 pr_warn("Unhandled BT ACTIVE from LMAC\n");
1037 break;
1038 }
1039 }
1040 __cw1200_free_event_queue(&list);
1041}
1042
1043void cw1200_bss_loss_work(struct work_struct *work)
1044{
1045 struct cw1200_common *priv =
1046 container_of(work, struct cw1200_common, bss_loss_work.work);
1047
1048 pr_debug("[CQM] Reporting connection loss.\n");
1049 wsm_lock_tx(priv);
1050 if (queue_work(priv->workqueue, &priv->unjoin_work) <= 0)
1051 wsm_unlock_tx(priv);
1052}
1053
1054void cw1200_bss_params_work(struct work_struct *work)
1055{
1056 struct cw1200_common *priv =
1057 container_of(work, struct cw1200_common, bss_params_work);
1058 mutex_lock(&priv->conf_mutex);
1059
1060 priv->bss_params.reset_beacon_loss = 1;
1061 wsm_set_bss_params(priv, &priv->bss_params);
1062 priv->bss_params.reset_beacon_loss = 0;
1063
1064 mutex_unlock(&priv->conf_mutex);
1065}
1066
1067/* ******************************************************************** */
1068/* Internal API */
1069
1070/* This function is called to Parse the SDD file
1071 * to extract listen_interval and PTA related information
1072 * sdd is a TLV: u8 id, u8 len, u8 data[]
1073 */
1074static int cw1200_parse_sdd_file(struct cw1200_common *priv)
1075{
1076 const u8 *p = priv->sdd->data;
1077 int ret = 0;
1078
1079 while (p + 2 <= priv->sdd->data + priv->sdd->size) {
1080 if (p + p[1] + 2 > priv->sdd->data + priv->sdd->size) {
1081 pr_warn("Malformed sdd structure\n");
1082 return -1;
1083 }
1084 switch (p[0]) {
1085 case SDD_PTA_CFG_ELT_ID: {
1086 u16 v;
1087 if (p[1] < 4) {
1088 pr_warn("SDD_PTA_CFG_ELT_ID malformed\n");
1089 ret = -1;
1090 break;
1091 }
1092 v = le16_to_cpu(*((u16 *)(p + 2)));
1093 if (!v) /* non-zero means this is enabled */
1094 break;
1095
1096 v = le16_to_cpu(*((u16 *)(p + 4)));
1097 priv->conf_listen_interval = (v >> 7) & 0x1F;
1098 pr_debug("PTA found; Listen Interval %d\n",
1099 priv->conf_listen_interval);
1100 break;
1101 }
1102 case SDD_REFERENCE_FREQUENCY_ELT_ID: {
1103 u16 clk = le16_to_cpu(*((u16 *)(p + 2)));
1104 if (clk != priv->hw_refclk)
1105 pr_warn("SDD file doesn't match configured refclk (%d vs %d)\n",
1106 clk, priv->hw_refclk);
1107 break;
1108 }
1109 default:
1110 break;
1111 }
1112 p += p[1] + 2;
1113 }
1114
1115 if (!priv->bt_present) {
1116 pr_debug("PTA element NOT found.\n");
1117 priv->conf_listen_interval = 0;
1118 }
1119 return ret;
1120}
1121
1122int cw1200_setup_mac(struct cw1200_common *priv)
1123{
1124 int ret = 0;
1125
1126 /* NOTE: There is a bug in FW: it reports signal
1127 * as RSSI if RSSI subscription is enabled.
1128 * It's not enough to set WSM_RCPI_RSSI_USE_RSSI.
1129 *
1130 * NOTE2: RSSI based reports have been switched to RCPI, since
1131 * FW has a bug and RSSI reported values are not stable,
1132 * what can leads to signal level oscilations in user-end applications
1133 */
1134 struct wsm_rcpi_rssi_threshold threshold = {
1135 .rssiRcpiMode = WSM_RCPI_RSSI_THRESHOLD_ENABLE |
1136 WSM_RCPI_RSSI_DONT_USE_UPPER |
1137 WSM_RCPI_RSSI_DONT_USE_LOWER,
1138 .rollingAverageCount = 16,
1139 };
1140
1141 struct wsm_configuration cfg = {
1142 .dot11StationId = &priv->mac_addr[0],
1143 };
1144
1145 /* Remember the decission here to make sure, we will handle
1146 * the RCPI/RSSI value correctly on WSM_EVENT_RCPI_RSS
1147 */
1148 if (threshold.rssiRcpiMode & WSM_RCPI_RSSI_USE_RSSI)
1149 priv->cqm_use_rssi = true;
1150
1151 if (!priv->sdd) {
1152 ret = request_firmware(&priv->sdd, priv->sdd_path, priv->pdev);
1153 if (ret) {
1154 pr_err("Can't load sdd file %s.\n", priv->sdd_path);
1155 return ret;
1156 }
1157 cw1200_parse_sdd_file(priv);
1158 }
1159
1160 cfg.dpdData = priv->sdd->data;
1161 cfg.dpdData_size = priv->sdd->size;
1162 ret = wsm_configuration(priv, &cfg);
1163 if (ret)
1164 return ret;
1165
1166 /* Configure RSSI/SCPI reporting as RSSI. */
1167 wsm_set_rcpi_rssi_threshold(priv, &threshold);
1168
1169 return 0;
1170}
1171
1172static void cw1200_join_complete(struct cw1200_common *priv)
1173{
1174 pr_debug("[STA] Join complete (%d)\n", priv->join_complete_status);
1175
1176 priv->join_pending = false;
1177 if (priv->join_complete_status) {
1178 priv->join_status = CW1200_JOIN_STATUS_PASSIVE;
1179 cw1200_update_listening(priv, priv->listening);
1180 cw1200_do_unjoin(priv);
1181 ieee80211_connection_loss(priv->vif);
1182 } else {
1183 if (priv->mode == NL80211_IFTYPE_ADHOC)
1184 priv->join_status = CW1200_JOIN_STATUS_IBSS;
1185 else
1186 priv->join_status = CW1200_JOIN_STATUS_PRE_STA;
1187 }
1188 wsm_unlock_tx(priv); /* Clearing the lock held before do_join() */
1189}
1190
1191void cw1200_join_complete_work(struct work_struct *work)
1192{
1193 struct cw1200_common *priv =
1194 container_of(work, struct cw1200_common, join_complete_work);
1195 mutex_lock(&priv->conf_mutex);
1196 cw1200_join_complete(priv);
1197 mutex_unlock(&priv->conf_mutex);
1198}
1199
1200void cw1200_join_complete_cb(struct cw1200_common *priv,
1201 struct wsm_join_complete *arg)
1202{
1203 pr_debug("[STA] cw1200_join_complete_cb called, status=%d.\n",
1204 arg->status);
1205
1206 if (cancel_delayed_work(&priv->join_timeout)) {
1207 priv->join_complete_status = arg->status;
1208 queue_work(priv->workqueue, &priv->join_complete_work);
1209 }
1210}
1211
1212/* MUST be called with tx_lock held! It will be unlocked for us. */
1213static void cw1200_do_join(struct cw1200_common *priv)
1214{
1215 const u8 *bssid;
1216 struct ieee80211_bss_conf *conf = &priv->vif->bss_conf;
1217 struct cfg80211_bss *bss = NULL;
1218 struct wsm_protected_mgmt_policy mgmt_policy;
1219 struct wsm_join join = {
1220 .mode = conf->ibss_joined ?
1221 WSM_JOIN_MODE_IBSS : WSM_JOIN_MODE_BSS,
1222 .preamble_type = WSM_JOIN_PREAMBLE_LONG,
1223 .probe_for_join = 1,
1224 .atim_window = 0,
1225 .basic_rate_set = cw1200_rate_mask_to_wsm(priv,
1226 conf->basic_rates),
1227 };
1228 if (delayed_work_pending(&priv->join_timeout)) {
1229 pr_warn("[STA] - Join request already pending, skipping..\n");
1230 wsm_unlock_tx(priv);
1231 return;
1232 }
1233
1234 if (priv->join_status)
1235 cw1200_do_unjoin(priv);
1236
1237 bssid = priv->vif->bss_conf.bssid;
1238
1239 bss = cfg80211_get_bss(priv->hw->wiphy, priv->channel,
1240 bssid, NULL, 0, 0, 0);
1241
1242 if (!bss && !conf->ibss_joined) {
1243 wsm_unlock_tx(priv);
1244 return;
1245 }
1246
1247 mutex_lock(&priv->conf_mutex);
1248
1249 /* Under the conf lock: check scan status and
1250 * bail out if it is in progress.
1251 */
1252 if (atomic_read(&priv->scan.in_progress)) {
1253 wsm_unlock_tx(priv);
1254 goto done_put;
1255 }
1256
1257 priv->join_pending = true;
1258
1259 /* Sanity check basic rates */
1260 if (!join.basic_rate_set)
1261 join.basic_rate_set = 7;
1262
1263 /* Sanity check beacon interval */
1264 if (!priv->beacon_int)
1265 priv->beacon_int = 1;
1266
1267 join.beacon_interval = priv->beacon_int;
1268
1269 /* BT Coex related changes */
1270 if (priv->bt_present) {
1271 if (((priv->conf_listen_interval * 100) %
1272 priv->beacon_int) == 0)
1273 priv->listen_interval =
1274 ((priv->conf_listen_interval * 100) /
1275 priv->beacon_int);
1276 else
1277 priv->listen_interval =
1278 ((priv->conf_listen_interval * 100) /
1279 priv->beacon_int + 1);
1280 }
1281
1282 if (priv->hw->conf.ps_dtim_period)
1283 priv->join_dtim_period = priv->hw->conf.ps_dtim_period;
1284 join.dtim_period = priv->join_dtim_period;
1285
1286 join.channel_number = priv->channel->hw_value;
1287 join.band = (priv->channel->band == IEEE80211_BAND_5GHZ) ?
1288 WSM_PHY_BAND_5G : WSM_PHY_BAND_2_4G;
1289
1290 memcpy(join.bssid, bssid, sizeof(join.bssid));
1291
1292 pr_debug("[STA] Join BSSID: %pM DTIM: %d, interval: %d\n",
1293 join.bssid,
1294 join.dtim_period, priv->beacon_int);
1295
1296 if (!conf->ibss_joined) {
1297 const u8 *ssidie;
1298 rcu_read_lock();
1299 ssidie = ieee80211_bss_get_ie(bss, WLAN_EID_SSID);
1300 if (ssidie) {
1301 join.ssid_len = ssidie[1];
1302 memcpy(join.ssid, &ssidie[2], join.ssid_len);
1303 }
1304 rcu_read_unlock();
1305 }
1306
1307 if (priv->vif->p2p) {
1308 join.flags |= WSM_JOIN_FLAGS_P2P_GO;
1309 join.basic_rate_set =
1310 cw1200_rate_mask_to_wsm(priv, 0xFF0);
1311 }
1312
1313 /* Enable asynchronous join calls */
1314 if (!conf->ibss_joined) {
1315 join.flags |= WSM_JOIN_FLAGS_FORCE;
1316 join.flags |= WSM_JOIN_FLAGS_FORCE_WITH_COMPLETE_IND;
1317 }
1318
1319 wsm_flush_tx(priv);
1320
1321 /* Stay Awake for Join and Auth Timeouts and a bit more */
1322 cw1200_pm_stay_awake(&priv->pm_state,
1323 CW1200_JOIN_TIMEOUT + CW1200_AUTH_TIMEOUT);
1324
1325 cw1200_update_listening(priv, false);
1326
1327 /* Turn on Block ACKs */
1328 wsm_set_block_ack_policy(priv, priv->ba_tx_tid_mask,
1329 priv->ba_rx_tid_mask);
1330
1331 /* Set up timeout */
1332 if (join.flags & WSM_JOIN_FLAGS_FORCE_WITH_COMPLETE_IND) {
1333 priv->join_status = CW1200_JOIN_STATUS_JOINING;
1334 queue_delayed_work(priv->workqueue,
1335 &priv->join_timeout,
1336 CW1200_JOIN_TIMEOUT);
1337 }
1338
1339 /* 802.11w protected mgmt frames */
1340 mgmt_policy.protectedMgmtEnable = 0;
1341 mgmt_policy.unprotectedMgmtFramesAllowed = 1;
1342 mgmt_policy.encryptionForAuthFrame = 1;
1343 wsm_set_protected_mgmt_policy(priv, &mgmt_policy);
1344
1345 /* Perform actual join */
1346 if (wsm_join(priv, &join)) {
1347 pr_err("[STA] cw1200_join_work: wsm_join failed!\n");
1348 cancel_delayed_work_sync(&priv->join_timeout);
1349 cw1200_update_listening(priv, priv->listening);
1350 /* Tx lock still held, unjoin will clear it. */
1351 if (queue_work(priv->workqueue, &priv->unjoin_work) <= 0)
1352 wsm_unlock_tx(priv);
1353 } else {
1354 if (!(join.flags & WSM_JOIN_FLAGS_FORCE_WITH_COMPLETE_IND))
1355 cw1200_join_complete(priv); /* Will clear tx_lock */
1356
1357 /* Upload keys */
1358 cw1200_upload_keys(priv);
1359
1360 /* Due to beacon filtering it is possible that the
1361 * AP's beacon is not known for the mac80211 stack.
1362 * Disable filtering temporary to make sure the stack
1363 * receives at least one
1364 */
1365 priv->disable_beacon_filter = true;
1366 }
1367 cw1200_update_filtering(priv);
1368
1369done_put:
1370 mutex_unlock(&priv->conf_mutex);
1371 if (bss)
1372 cfg80211_put_bss(priv->hw->wiphy, bss);
1373}
1374
1375void cw1200_join_timeout(struct work_struct *work)
1376{
1377 struct cw1200_common *priv =
1378 container_of(work, struct cw1200_common, join_timeout.work);
1379 pr_debug("[WSM] Join timed out.\n");
1380 wsm_lock_tx(priv);
1381 if (queue_work(priv->workqueue, &priv->unjoin_work) <= 0)
1382 wsm_unlock_tx(priv);
1383}
1384
1385static void cw1200_do_unjoin(struct cw1200_common *priv)
1386{
1387 struct wsm_reset reset = {
1388 .reset_statistics = true,
1389 };
1390
1391 cancel_delayed_work_sync(&priv->join_timeout);
1392
1393 mutex_lock(&priv->conf_mutex);
1394 priv->join_pending = false;
1395
1396 if (atomic_read(&priv->scan.in_progress)) {
1397 if (priv->delayed_unjoin)
1398 wiphy_dbg(priv->hw->wiphy, "Delayed unjoin is already scheduled.\n");
1399 else
1400 priv->delayed_unjoin = true;
1401 goto done;
1402 }
1403
1404 priv->delayed_link_loss = false;
1405
1406 if (!priv->join_status)
1407 goto done;
1408
1409 if (priv->join_status > CW1200_JOIN_STATUS_IBSS) {
1410 wiphy_err(priv->hw->wiphy, "Unexpected: join status: %d\n",
1411 priv->join_status);
1412 BUG_ON(1);
1413 }
1414
1415 cancel_work_sync(&priv->update_filtering_work);
1416 cancel_work_sync(&priv->set_beacon_wakeup_period_work);
1417 priv->join_status = CW1200_JOIN_STATUS_PASSIVE;
1418
1419 /* Unjoin is a reset. */
1420 wsm_flush_tx(priv);
1421 wsm_keep_alive_period(priv, 0);
1422 wsm_reset(priv, &reset);
1423 wsm_set_output_power(priv, priv->output_power * 10);
1424 priv->join_dtim_period = 0;
1425 cw1200_setup_mac(priv);
1426 cw1200_free_event_queue(priv);
1427 cancel_work_sync(&priv->event_handler);
1428 cw1200_update_listening(priv, priv->listening);
1429 cw1200_cqm_bssloss_sm(priv, 0, 0, 0);
1430
1431 /* Disable Block ACKs */
1432 wsm_set_block_ack_policy(priv, 0, 0);
1433
1434 priv->disable_beacon_filter = false;
1435 cw1200_update_filtering(priv);
1436 memset(&priv->association_mode, 0,
1437 sizeof(priv->association_mode));
1438 memset(&priv->bss_params, 0, sizeof(priv->bss_params));
1439 priv->setbssparams_done = false;
1440 memset(&priv->firmware_ps_mode, 0,
1441 sizeof(priv->firmware_ps_mode));
1442
1443 pr_debug("[STA] Unjoin completed.\n");
1444
1445done:
1446 mutex_unlock(&priv->conf_mutex);
1447}
1448
1449void cw1200_unjoin_work(struct work_struct *work)
1450{
1451 struct cw1200_common *priv =
1452 container_of(work, struct cw1200_common, unjoin_work);
1453
1454 cw1200_do_unjoin(priv);
1455
1456 /* Tell the stack we're dead */
1457 ieee80211_connection_loss(priv->vif);
1458
1459 wsm_unlock_tx(priv);
1460}
1461
1462int cw1200_enable_listening(struct cw1200_common *priv)
1463{
1464 struct wsm_start start = {
1465 .mode = WSM_START_MODE_P2P_DEV,
1466 .band = WSM_PHY_BAND_2_4G,
1467 .beacon_interval = 100,
1468 .dtim_period = 1,
1469 .probe_delay = 0,
1470 .basic_rate_set = 0x0F,
1471 };
1472
1473 if (priv->channel) {
1474 start.band = priv->channel->band == IEEE80211_BAND_5GHZ ?
1475 WSM_PHY_BAND_5G : WSM_PHY_BAND_2_4G;
1476 start.channel_number = priv->channel->hw_value;
1477 } else {
1478 start.band = WSM_PHY_BAND_2_4G;
1479 start.channel_number = 1;
1480 }
1481
1482 return wsm_start(priv, &start);
1483}
1484
1485int cw1200_disable_listening(struct cw1200_common *priv)
1486{
1487 int ret;
1488 struct wsm_reset reset = {
1489 .reset_statistics = true,
1490 };
1491 ret = wsm_reset(priv, &reset);
1492 return ret;
1493}
1494
1495void cw1200_update_listening(struct cw1200_common *priv, bool enabled)
1496{
1497 if (enabled) {
1498 if (priv->join_status == CW1200_JOIN_STATUS_PASSIVE) {
1499 if (!cw1200_enable_listening(priv))
1500 priv->join_status = CW1200_JOIN_STATUS_MONITOR;
1501 wsm_set_probe_responder(priv, true);
1502 }
1503 } else {
1504 if (priv->join_status == CW1200_JOIN_STATUS_MONITOR) {
1505 if (!cw1200_disable_listening(priv))
1506 priv->join_status = CW1200_JOIN_STATUS_PASSIVE;
1507 wsm_set_probe_responder(priv, false);
1508 }
1509 }
1510}
1511
1512int cw1200_set_uapsd_param(struct cw1200_common *priv,
1513 const struct wsm_edca_params *arg)
1514{
1515 int ret;
1516 u16 uapsd_flags = 0;
1517
1518 /* Here's the mapping AC [queue, bit]
1519 * VO [0,3], VI [1, 2], BE [2, 1], BK [3, 0]
1520 */
1521
1522 if (arg->uapsd_enable[0])
1523 uapsd_flags |= 1 << 3;
1524
1525 if (arg->uapsd_enable[1])
1526 uapsd_flags |= 1 << 2;
1527
1528 if (arg->uapsd_enable[2])
1529 uapsd_flags |= 1 << 1;
1530
1531 if (arg->uapsd_enable[3])
1532 uapsd_flags |= 1;
1533
1534 /* Currently pseudo U-APSD operation is not supported, so setting
1535 * MinAutoTriggerInterval, MaxAutoTriggerInterval and
1536 * AutoTriggerStep to 0
1537 */
1538
1539 priv->uapsd_info.uapsd_flags = cpu_to_le16(uapsd_flags);
1540 priv->uapsd_info.min_auto_trigger_interval = 0;
1541 priv->uapsd_info.max_auto_trigger_interval = 0;
1542 priv->uapsd_info.auto_trigger_step = 0;
1543
1544 ret = wsm_set_uapsd_info(priv, &priv->uapsd_info);
1545 return ret;
1546}
1547
1548/* ******************************************************************** */
1549/* AP API */
1550
1551int cw1200_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
1552 struct ieee80211_sta *sta)
1553{
1554 struct cw1200_common *priv = hw->priv;
1555 struct cw1200_sta_priv *sta_priv =
1556 (struct cw1200_sta_priv *)&sta->drv_priv;
1557 struct cw1200_link_entry *entry;
1558 struct sk_buff *skb;
1559
1560 if (priv->mode != NL80211_IFTYPE_AP)
1561 return 0;
1562
1563 sta_priv->link_id = cw1200_find_link_id(priv, sta->addr);
1564 if (WARN_ON(!sta_priv->link_id)) {
1565 wiphy_info(priv->hw->wiphy,
1566 "[AP] No more link IDs available.\n");
1567 return -ENOENT;
1568 }
1569
1570 entry = &priv->link_id_db[sta_priv->link_id - 1];
1571 spin_lock_bh(&priv->ps_state_lock);
1572 if ((sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK) ==
1573 IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK)
1574 priv->sta_asleep_mask |= BIT(sta_priv->link_id);
1575 entry->status = CW1200_LINK_HARD;
1576 while ((skb = skb_dequeue(&entry->rx_queue)))
1577 ieee80211_rx_irqsafe(priv->hw, skb);
1578 spin_unlock_bh(&priv->ps_state_lock);
1579 return 0;
1580}
1581
1582int cw1200_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
1583 struct ieee80211_sta *sta)
1584{
1585 struct cw1200_common *priv = hw->priv;
1586 struct cw1200_sta_priv *sta_priv =
1587 (struct cw1200_sta_priv *)&sta->drv_priv;
1588 struct cw1200_link_entry *entry;
1589
1590 if (priv->mode != NL80211_IFTYPE_AP || !sta_priv->link_id)
1591 return 0;
1592
1593 entry = &priv->link_id_db[sta_priv->link_id - 1];
1594 spin_lock_bh(&priv->ps_state_lock);
1595 entry->status = CW1200_LINK_RESERVE;
1596 entry->timestamp = jiffies;
1597 wsm_lock_tx_async(priv);
1598 if (queue_work(priv->workqueue, &priv->link_id_work) <= 0)
1599 wsm_unlock_tx(priv);
1600 spin_unlock_bh(&priv->ps_state_lock);
1601 flush_workqueue(priv->workqueue);
1602 return 0;
1603}
1604
1605static void __cw1200_sta_notify(struct ieee80211_hw *dev,
1606 struct ieee80211_vif *vif,
1607 enum sta_notify_cmd notify_cmd,
1608 int link_id)
1609{
1610 struct cw1200_common *priv = dev->priv;
1611 u32 bit, prev;
1612
1613 /* Zero link id means "for all link IDs" */
1614 if (link_id)
1615 bit = BIT(link_id);
1616 else if (WARN_ON_ONCE(notify_cmd != STA_NOTIFY_AWAKE))
1617 bit = 0;
1618 else
1619 bit = priv->link_id_map;
1620 prev = priv->sta_asleep_mask & bit;
1621
1622 switch (notify_cmd) {
1623 case STA_NOTIFY_SLEEP:
1624 if (!prev) {
1625 if (priv->buffered_multicasts &&
1626 !priv->sta_asleep_mask)
1627 queue_work(priv->workqueue,
1628 &priv->multicast_start_work);
1629 priv->sta_asleep_mask |= bit;
1630 }
1631 break;
1632 case STA_NOTIFY_AWAKE:
1633 if (prev) {
1634 priv->sta_asleep_mask &= ~bit;
1635 priv->pspoll_mask &= ~bit;
1636 if (priv->tx_multicast && link_id &&
1637 !priv->sta_asleep_mask)
1638 queue_work(priv->workqueue,
1639 &priv->multicast_stop_work);
1640 cw1200_bh_wakeup(priv);
1641 }
1642 break;
1643 }
1644}
1645
1646void cw1200_sta_notify(struct ieee80211_hw *dev,
1647 struct ieee80211_vif *vif,
1648 enum sta_notify_cmd notify_cmd,
1649 struct ieee80211_sta *sta)
1650{
1651 struct cw1200_common *priv = dev->priv;
1652 struct cw1200_sta_priv *sta_priv =
1653 (struct cw1200_sta_priv *)&sta->drv_priv;
1654
1655 spin_lock_bh(&priv->ps_state_lock);
1656 __cw1200_sta_notify(dev, vif, notify_cmd, sta_priv->link_id);
1657 spin_unlock_bh(&priv->ps_state_lock);
1658}
1659
1660static void cw1200_ps_notify(struct cw1200_common *priv,
1661 int link_id, bool ps)
1662{
1663 if (link_id > CW1200_MAX_STA_IN_AP_MODE)
1664 return;
1665
1666 pr_debug("%s for LinkId: %d. STAs asleep: %.8X\n",
1667 ps ? "Stop" : "Start",
1668 link_id, priv->sta_asleep_mask);
1669
1670 __cw1200_sta_notify(priv->hw, priv->vif,
1671 ps ? STA_NOTIFY_SLEEP : STA_NOTIFY_AWAKE, link_id);
1672}
1673
1674static int cw1200_set_tim_impl(struct cw1200_common *priv, bool aid0_bit_set)
1675{
1676 struct sk_buff *skb;
1677 struct wsm_update_ie update_ie = {
1678 .what = WSM_UPDATE_IE_BEACON,
1679 .count = 1,
1680 };
1681 u16 tim_offset, tim_length;
1682
1683 pr_debug("[AP] mcast: %s.\n", aid0_bit_set ? "ena" : "dis");
1684
1685 skb = ieee80211_beacon_get_tim(priv->hw, priv->vif,
1686 &tim_offset, &tim_length);
1687 if (!skb) {
1688 if (!__cw1200_flush(priv, true))
1689 wsm_unlock_tx(priv);
1690 return -ENOENT;
1691 }
1692
1693 if (tim_offset && tim_length >= 6) {
1694 /* Ignore DTIM count from mac80211:
1695 * firmware handles DTIM internally.
1696 */
1697 skb->data[tim_offset + 2] = 0;
1698
1699 /* Set/reset aid0 bit */
1700 if (aid0_bit_set)
1701 skb->data[tim_offset + 4] |= 1;
1702 else
1703 skb->data[tim_offset + 4] &= ~1;
1704 }
1705
1706 update_ie.ies = &skb->data[tim_offset];
1707 update_ie.length = tim_length;
1708 wsm_update_ie(priv, &update_ie);
1709
1710 dev_kfree_skb(skb);
1711
1712 return 0;
1713}
1714
1715void cw1200_set_tim_work(struct work_struct *work)
1716{
1717 struct cw1200_common *priv =
1718 container_of(work, struct cw1200_common, set_tim_work);
1719 (void)cw1200_set_tim_impl(priv, priv->aid0_bit_set);
1720}
1721
1722int cw1200_set_tim(struct ieee80211_hw *dev, struct ieee80211_sta *sta,
1723 bool set)
1724{
1725 struct cw1200_common *priv = dev->priv;
1726 queue_work(priv->workqueue, &priv->set_tim_work);
1727 return 0;
1728}
1729
1730void cw1200_set_cts_work(struct work_struct *work)
1731{
1732 struct cw1200_common *priv =
1733 container_of(work, struct cw1200_common, set_cts_work);
1734
1735 u8 erp_ie[3] = {WLAN_EID_ERP_INFO, 0x1, 0};
1736 struct wsm_update_ie update_ie = {
1737 .what = WSM_UPDATE_IE_BEACON,
1738 .count = 1,
1739 .ies = erp_ie,
1740 .length = 3,
1741 };
1742 u32 erp_info;
1743 __le32 use_cts_prot;
1744 mutex_lock(&priv->conf_mutex);
1745 erp_info = priv->erp_info;
1746 mutex_unlock(&priv->conf_mutex);
1747 use_cts_prot =
1748 erp_info & WLAN_ERP_USE_PROTECTION ?
1749 __cpu_to_le32(1) : 0;
1750
1751 erp_ie[ERP_INFO_BYTE_OFFSET] = erp_info;
1752
1753 pr_debug("[STA] ERP information 0x%x\n", erp_info);
1754
1755 wsm_write_mib(priv, WSM_MIB_ID_NON_ERP_PROTECTION,
1756 &use_cts_prot, sizeof(use_cts_prot));
1757 wsm_update_ie(priv, &update_ie);
1758
1759 return;
1760}
1761
1762static int cw1200_set_btcoexinfo(struct cw1200_common *priv)
1763{
1764 struct wsm_override_internal_txrate arg;
1765 int ret = 0;
1766
1767 if (priv->mode == NL80211_IFTYPE_STATION) {
1768 /* Plumb PSPOLL and NULL template */
1769 cw1200_upload_pspoll(priv);
1770 cw1200_upload_null(priv);
1771 cw1200_upload_qosnull(priv);
1772 } else {
1773 return 0;
1774 }
1775
1776 memset(&arg, 0, sizeof(struct wsm_override_internal_txrate));
1777
1778 if (!priv->vif->p2p) {
1779 /* STATION mode */
1780 if (priv->bss_params.operational_rate_set & ~0xF) {
1781 pr_debug("[STA] STA has ERP rates\n");
1782 /* G or BG mode */
1783 arg.internalTxRate = (__ffs(
1784 priv->bss_params.operational_rate_set & ~0xF));
1785 } else {
1786 pr_debug("[STA] STA has non ERP rates\n");
1787 /* B only mode */
1788 arg.internalTxRate = (__ffs(priv->association_mode.basic_rate_set));
1789 }
1790 arg.nonErpInternalTxRate = (__ffs(priv->association_mode.basic_rate_set));
1791 } else {
1792 /* P2P mode */
1793 arg.internalTxRate = (__ffs(priv->bss_params.operational_rate_set & ~0xF));
1794 arg.nonErpInternalTxRate = (__ffs(priv->bss_params.operational_rate_set & ~0xF));
1795 }
1796
1797 pr_debug("[STA] BTCOEX_INFO MODE %d, internalTxRate : %x, nonErpInternalTxRate: %x\n",
1798 priv->mode,
1799 arg.internalTxRate,
1800 arg.nonErpInternalTxRate);
1801
1802 ret = wsm_write_mib(priv, WSM_MIB_ID_OVERRIDE_INTERNAL_TX_RATE,
1803 &arg, sizeof(arg));
1804
1805 return ret;
1806}
1807
1808void cw1200_bss_info_changed(struct ieee80211_hw *dev,
1809 struct ieee80211_vif *vif,
1810 struct ieee80211_bss_conf *info,
1811 u32 changed)
1812{
1813 struct cw1200_common *priv = dev->priv;
1814 bool do_join = false;
1815
1816 mutex_lock(&priv->conf_mutex);
1817
1818 pr_debug("BSS CHANGED: %08x\n", changed);
1819
1820 /* TODO: BSS_CHANGED_QOS */
1821 /* TODO: BSS_CHANGED_TXPOWER */
1822
1823 if (changed & BSS_CHANGED_ARP_FILTER) {
1824 struct wsm_mib_arp_ipv4_filter filter = {0};
1825 int i;
1826
1827 pr_debug("[STA] BSS_CHANGED_ARP_FILTER cnt: %d\n",
1828 info->arp_addr_cnt);
1829
1830 /* Currently only one IP address is supported by firmware.
1831 * In case of more IPs arp filtering will be disabled.
1832 */
1833 if (info->arp_addr_cnt > 0 &&
1834 info->arp_addr_cnt <= WSM_MAX_ARP_IP_ADDRTABLE_ENTRIES) {
1835 for (i = 0; i < info->arp_addr_cnt; i++) {
1836 filter.ipv4addrs[i] = info->arp_addr_list[i];
1837 pr_debug("[STA] addr[%d]: 0x%X\n",
1838 i, filter.ipv4addrs[i]);
1839 }
1840 filter.enable = __cpu_to_le32(1);
1841 }
1842
1843 pr_debug("[STA] arp ip filter enable: %d\n",
1844 __le32_to_cpu(filter.enable));
1845
1846 wsm_set_arp_ipv4_filter(priv, &filter);
1847 }
1848
1849 if (changed &
1850 (BSS_CHANGED_BEACON |
1851 BSS_CHANGED_AP_PROBE_RESP |
1852 BSS_CHANGED_BSSID |
1853 BSS_CHANGED_SSID |
1854 BSS_CHANGED_IBSS)) {
1855 pr_debug("BSS_CHANGED_BEACON\n");
1856 priv->beacon_int = info->beacon_int;
1857 cw1200_update_beaconing(priv);
1858 cw1200_upload_beacon(priv);
1859 }
1860
1861 if (changed & BSS_CHANGED_BEACON_ENABLED) {
1862 pr_debug("BSS_CHANGED_BEACON_ENABLED (%d)\n", info->enable_beacon);
1863
1864 if (priv->enable_beacon != info->enable_beacon) {
1865 cw1200_enable_beaconing(priv, info->enable_beacon);
1866 priv->enable_beacon = info->enable_beacon;
1867 }
1868 }
1869
1870 if (changed & BSS_CHANGED_BEACON_INT) {
1871 pr_debug("CHANGED_BEACON_INT\n");
1872 if (info->ibss_joined)
1873 do_join = true;
1874 else if (priv->join_status == CW1200_JOIN_STATUS_AP)
1875 cw1200_update_beaconing(priv);
1876 }
1877
1878 /* assoc/disassoc, or maybe AID changed */
1879 if (changed & BSS_CHANGED_ASSOC) {
1880 wsm_lock_tx(priv);
1881 priv->wep_default_key_id = -1;
1882 wsm_unlock_tx(priv);
1883 }
1884
1885 if (changed & BSS_CHANGED_BSSID) {
1886 pr_debug("BSS_CHANGED_BSSID\n");
1887 do_join = true;
1888 }
1889
1890 if (changed &
1891 (BSS_CHANGED_ASSOC |
1892 BSS_CHANGED_BSSID |
1893 BSS_CHANGED_IBSS |
1894 BSS_CHANGED_BASIC_RATES |
1895 BSS_CHANGED_HT)) {
1896 pr_debug("BSS_CHANGED_ASSOC\n");
1897 if (info->assoc) {
1898 if (priv->join_status < CW1200_JOIN_STATUS_PRE_STA) {
1899 ieee80211_connection_loss(vif);
1900 mutex_unlock(&priv->conf_mutex);
1901 return;
1902 } else if (priv->join_status == CW1200_JOIN_STATUS_PRE_STA) {
1903 priv->join_status = CW1200_JOIN_STATUS_STA;
1904 }
1905 } else {
1906 do_join = true;
1907 }
1908
1909 if (info->assoc || info->ibss_joined) {
1910 struct ieee80211_sta *sta = NULL;
1911 u32 val = 0;
1912
1913 if (info->dtim_period)
1914 priv->join_dtim_period = info->dtim_period;
1915 priv->beacon_int = info->beacon_int;
1916
1917 rcu_read_lock();
1918
1919 if (info->bssid && !info->ibss_joined)
1920 sta = ieee80211_find_sta(vif, info->bssid);
1921 if (sta) {
1922 priv->ht_info.ht_cap = sta->ht_cap;
1923 priv->bss_params.operational_rate_set =
1924 cw1200_rate_mask_to_wsm(priv,
1925 sta->supp_rates[priv->channel->band]);
1926 priv->ht_info.channel_type = cfg80211_get_chandef_type(&dev->conf.chandef);
1927 priv->ht_info.operation_mode = info->ht_operation_mode;
1928 } else {
1929 memset(&priv->ht_info, 0,
1930 sizeof(priv->ht_info));
1931 priv->bss_params.operational_rate_set = -1;
1932 }
1933 rcu_read_unlock();
1934
1935 /* Non Greenfield stations present */
1936 if (priv->ht_info.operation_mode &
1937 IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT)
1938 val |= WSM_NON_GREENFIELD_STA_PRESENT;
1939
1940 /* Set HT protection method */
1941 val |= (priv->ht_info.operation_mode & IEEE80211_HT_OP_MODE_PROTECTION) << 2;
1942
1943 /* TODO:
1944 * STBC_param.dual_cts
1945 * STBC_param.LSIG_TXOP_FILL
1946 */
1947
1948 val = cpu_to_le32(val);
1949 wsm_write_mib(priv, WSM_MIB_ID_SET_HT_PROTECTION,
1950 &val, sizeof(val));
1951
1952 priv->association_mode.greenfield =
1953 cw1200_ht_greenfield(&priv->ht_info);
1954 priv->association_mode.flags =
1955 WSM_ASSOCIATION_MODE_SNOOP_ASSOC_FRAMES |
1956 WSM_ASSOCIATION_MODE_USE_PREAMBLE_TYPE |
1957 WSM_ASSOCIATION_MODE_USE_HT_MODE |
1958 WSM_ASSOCIATION_MODE_USE_BASIC_RATE_SET |
1959 WSM_ASSOCIATION_MODE_USE_MPDU_START_SPACING;
1960 priv->association_mode.preamble =
1961 info->use_short_preamble ?
1962 WSM_JOIN_PREAMBLE_SHORT :
1963 WSM_JOIN_PREAMBLE_LONG;
1964 priv->association_mode.basic_rate_set = __cpu_to_le32(
1965 cw1200_rate_mask_to_wsm(priv,
1966 info->basic_rates));
1967 priv->association_mode.mpdu_start_spacing =
1968 cw1200_ht_ampdu_density(&priv->ht_info);
1969
1970 cw1200_cqm_bssloss_sm(priv, 0, 0, 0);
1971 cancel_work_sync(&priv->unjoin_work);
1972
1973 priv->bss_params.beacon_lost_count = priv->cqm_beacon_loss_count;
1974 priv->bss_params.aid = info->aid;
1975
1976 if (priv->join_dtim_period < 1)
1977 priv->join_dtim_period = 1;
1978
1979 pr_debug("[STA] DTIM %d, interval: %d\n",
1980 priv->join_dtim_period, priv->beacon_int);
1981 pr_debug("[STA] Preamble: %d, Greenfield: %d, Aid: %d, Rates: 0x%.8X, Basic: 0x%.8X\n",
1982 priv->association_mode.preamble,
1983 priv->association_mode.greenfield,
1984 priv->bss_params.aid,
1985 priv->bss_params.operational_rate_set,
1986 priv->association_mode.basic_rate_set);
1987 wsm_set_association_mode(priv, &priv->association_mode);
1988
1989 if (!info->ibss_joined) {
1990 wsm_keep_alive_period(priv, 30 /* sec */);
1991 wsm_set_bss_params(priv, &priv->bss_params);
1992 priv->setbssparams_done = true;
1993 cw1200_set_beacon_wakeup_period_work(&priv->set_beacon_wakeup_period_work);
1994 cw1200_set_pm(priv, &priv->powersave_mode);
1995 }
1996 if (priv->vif->p2p) {
1997 pr_debug("[STA] Setting p2p powersave configuration.\n");
1998 wsm_set_p2p_ps_modeinfo(priv,
1999 &priv->p2p_ps_modeinfo);
2000 }
2001 if (priv->bt_present)
2002 cw1200_set_btcoexinfo(priv);
2003 } else {
2004 memset(&priv->association_mode, 0,
2005 sizeof(priv->association_mode));
2006 memset(&priv->bss_params, 0, sizeof(priv->bss_params));
2007 }
2008 }
2009
2010 /* ERP Protection */
2011 if (changed & (BSS_CHANGED_ASSOC |
2012 BSS_CHANGED_ERP_CTS_PROT |
2013 BSS_CHANGED_ERP_PREAMBLE)) {
2014 u32 prev_erp_info = priv->erp_info;
2015 if (info->use_cts_prot)
2016 priv->erp_info |= WLAN_ERP_USE_PROTECTION;
2017 else if (!(prev_erp_info & WLAN_ERP_NON_ERP_PRESENT))
2018 priv->erp_info &= ~WLAN_ERP_USE_PROTECTION;
2019
2020 if (info->use_short_preamble)
2021 priv->erp_info |= WLAN_ERP_BARKER_PREAMBLE;
2022 else
2023 priv->erp_info &= ~WLAN_ERP_BARKER_PREAMBLE;
2024
2025 pr_debug("[STA] ERP Protection: %x\n", priv->erp_info);
2026
2027 if (prev_erp_info != priv->erp_info)
2028 queue_work(priv->workqueue, &priv->set_cts_work);
2029 }
2030
2031 /* ERP Slottime */
2032 if (changed & (BSS_CHANGED_ASSOC | BSS_CHANGED_ERP_SLOT)) {
2033 __le32 slot_time = info->use_short_slot ?
2034 __cpu_to_le32(9) : __cpu_to_le32(20);
2035 pr_debug("[STA] Slot time: %d us.\n",
2036 __le32_to_cpu(slot_time));
2037 wsm_write_mib(priv, WSM_MIB_ID_DOT11_SLOT_TIME,
2038 &slot_time, sizeof(slot_time));
2039 }
2040
2041 if (changed & (BSS_CHANGED_ASSOC | BSS_CHANGED_CQM)) {
2042 struct wsm_rcpi_rssi_threshold threshold = {
2043 .rollingAverageCount = 8,
2044 };
2045 pr_debug("[CQM] RSSI threshold subscribe: %d +- %d\n",
2046 info->cqm_rssi_thold, info->cqm_rssi_hyst);
2047 priv->cqm_rssi_thold = info->cqm_rssi_thold;
2048 priv->cqm_rssi_hyst = info->cqm_rssi_hyst;
2049
2050 if (info->cqm_rssi_thold || info->cqm_rssi_hyst) {
2051 /* RSSI subscription enabled */
2052 /* TODO: It's not a correct way of setting threshold.
2053 * Upper and lower must be set equal here and adjusted
2054 * in callback. However current implementation is much
2055 * more relaible and stable.
2056 */
2057
2058 /* RSSI: signed Q8.0, RCPI: unsigned Q7.1
2059 * RSSI = RCPI / 2 - 110
2060 */
2061 if (priv->cqm_use_rssi) {
2062 threshold.upperThreshold =
2063 info->cqm_rssi_thold + info->cqm_rssi_hyst;
2064 threshold.lowerThreshold =
2065 info->cqm_rssi_thold;
2066 threshold.rssiRcpiMode |= WSM_RCPI_RSSI_USE_RSSI;
2067 } else {
2068 threshold.upperThreshold = (info->cqm_rssi_thold + info->cqm_rssi_hyst + 110) * 2;
2069 threshold.lowerThreshold = (info->cqm_rssi_thold + 110) * 2;
2070 }
2071 threshold.rssiRcpiMode |= WSM_RCPI_RSSI_THRESHOLD_ENABLE;
2072 } else {
2073 /* There is a bug in FW, see sta.c. We have to enable
2074 * dummy subscription to get correct RSSI values.
2075 */
2076 threshold.rssiRcpiMode |=
2077 WSM_RCPI_RSSI_THRESHOLD_ENABLE |
2078 WSM_RCPI_RSSI_DONT_USE_UPPER |
2079 WSM_RCPI_RSSI_DONT_USE_LOWER;
2080 if (priv->cqm_use_rssi)
2081 threshold.rssiRcpiMode |= WSM_RCPI_RSSI_USE_RSSI;
2082 }
2083 wsm_set_rcpi_rssi_threshold(priv, &threshold);
2084 }
2085 mutex_unlock(&priv->conf_mutex);
2086
2087 if (do_join) {
2088 wsm_lock_tx(priv);
2089 cw1200_do_join(priv); /* Will unlock it for us */
2090 }
2091}
2092
2093void cw1200_multicast_start_work(struct work_struct *work)
2094{
2095 struct cw1200_common *priv =
2096 container_of(work, struct cw1200_common, multicast_start_work);
2097 long tmo = priv->join_dtim_period *
2098 (priv->beacon_int + 20) * HZ / 1024;
2099
2100 cancel_work_sync(&priv->multicast_stop_work);
2101
2102 if (!priv->aid0_bit_set) {
2103 wsm_lock_tx(priv);
2104 cw1200_set_tim_impl(priv, true);
2105 priv->aid0_bit_set = true;
2106 mod_timer(&priv->mcast_timeout, jiffies + tmo);
2107 wsm_unlock_tx(priv);
2108 }
2109}
2110
2111void cw1200_multicast_stop_work(struct work_struct *work)
2112{
2113 struct cw1200_common *priv =
2114 container_of(work, struct cw1200_common, multicast_stop_work);
2115
2116 if (priv->aid0_bit_set) {
2117 del_timer_sync(&priv->mcast_timeout);
2118 wsm_lock_tx(priv);
2119 priv->aid0_bit_set = false;
2120 cw1200_set_tim_impl(priv, false);
2121 wsm_unlock_tx(priv);
2122 }
2123}
2124
2125void cw1200_mcast_timeout(unsigned long arg)
2126{
2127 struct cw1200_common *priv =
2128 (struct cw1200_common *)arg;
2129
2130 wiphy_warn(priv->hw->wiphy,
2131 "Multicast delivery timeout.\n");
2132 spin_lock_bh(&priv->ps_state_lock);
2133 priv->tx_multicast = priv->aid0_bit_set &&
2134 priv->buffered_multicasts;
2135 if (priv->tx_multicast)
2136 cw1200_bh_wakeup(priv);
2137 spin_unlock_bh(&priv->ps_state_lock);
2138}
2139
2140int cw1200_ampdu_action(struct ieee80211_hw *hw,
2141 struct ieee80211_vif *vif,
2142 enum ieee80211_ampdu_mlme_action action,
2143 struct ieee80211_sta *sta, u16 tid, u16 *ssn,
2144 u8 buf_size)
2145{
2146 /* Aggregation is implemented fully in firmware,
2147 * including block ack negotiation. Do not allow
2148 * mac80211 stack to do anything: it interferes with
2149 * the firmware.
2150 */
2151
2152 /* Note that we still need this function stubbed. */
2153 return -ENOTSUPP;
2154}
2155
2156/* ******************************************************************** */
2157/* WSM callback */
2158void cw1200_suspend_resume(struct cw1200_common *priv,
2159 struct wsm_suspend_resume *arg)
2160{
2161 pr_debug("[AP] %s: %s\n",
2162 arg->stop ? "stop" : "start",
2163 arg->multicast ? "broadcast" : "unicast");
2164
2165 if (arg->multicast) {
2166 bool cancel_tmo = false;
2167 spin_lock_bh(&priv->ps_state_lock);
2168 if (arg->stop) {
2169 priv->tx_multicast = false;
2170 } else {
2171 /* Firmware sends this indication every DTIM if there
2172 * is a STA in powersave connected. There is no reason
2173 * to suspend, following wakeup will consume much more
2174 * power than it could be saved.
2175 */
2176 cw1200_pm_stay_awake(&priv->pm_state,
2177 priv->join_dtim_period *
2178 (priv->beacon_int + 20) * HZ / 1024);
2179 priv->tx_multicast = (priv->aid0_bit_set &&
2180 priv->buffered_multicasts);
2181 if (priv->tx_multicast) {
2182 cancel_tmo = true;
2183 cw1200_bh_wakeup(priv);
2184 }
2185 }
2186 spin_unlock_bh(&priv->ps_state_lock);
2187 if (cancel_tmo)
2188 del_timer_sync(&priv->mcast_timeout);
2189 } else {
2190 spin_lock_bh(&priv->ps_state_lock);
2191 cw1200_ps_notify(priv, arg->link_id, arg->stop);
2192 spin_unlock_bh(&priv->ps_state_lock);
2193 if (!arg->stop)
2194 cw1200_bh_wakeup(priv);
2195 }
2196 return;
2197}
2198
2199/* ******************************************************************** */
2200/* AP privates */
2201
2202static int cw1200_upload_beacon(struct cw1200_common *priv)
2203{
2204 int ret = 0;
2205 struct ieee80211_mgmt *mgmt;
2206 struct wsm_template_frame frame = {
2207 .frame_type = WSM_FRAME_TYPE_BEACON,
2208 };
2209
2210 u16 tim_offset;
2211 u16 tim_len;
2212
2213 if (priv->mode == NL80211_IFTYPE_STATION ||
2214 priv->mode == NL80211_IFTYPE_MONITOR ||
2215 priv->mode == NL80211_IFTYPE_UNSPECIFIED)
2216 goto done;
2217
2218 if (priv->vif->p2p)
2219 frame.rate = WSM_TRANSMIT_RATE_6;
2220
2221 frame.skb = ieee80211_beacon_get_tim(priv->hw, priv->vif,
2222 &tim_offset, &tim_len);
2223 if (!frame.skb)
2224 return -ENOMEM;
2225
2226 ret = wsm_set_template_frame(priv, &frame);
2227
2228 if (ret)
2229 goto done;
2230
2231 /* TODO: Distill probe resp; remove TIM
2232 * and any other beacon-specific IEs
2233 */
2234 mgmt = (void *)frame.skb->data;
2235 mgmt->frame_control =
2236 __cpu_to_le16(IEEE80211_FTYPE_MGMT |
2237 IEEE80211_STYPE_PROBE_RESP);
2238
2239 frame.frame_type = WSM_FRAME_TYPE_PROBE_RESPONSE;
2240 if (priv->vif->p2p) {
2241 ret = wsm_set_probe_responder(priv, true);
2242 } else {
2243 ret = wsm_set_template_frame(priv, &frame);
2244 wsm_set_probe_responder(priv, false);
2245 }
2246
2247done:
2248 dev_kfree_skb(frame.skb);
2249
2250 return ret;
2251}
2252
2253static int cw1200_upload_pspoll(struct cw1200_common *priv)
2254{
2255 int ret = 0;
2256 struct wsm_template_frame frame = {
2257 .frame_type = WSM_FRAME_TYPE_PS_POLL,
2258 .rate = 0xFF,
2259 };
2260
2261
2262 frame.skb = ieee80211_pspoll_get(priv->hw, priv->vif);
2263 if (!frame.skb)
2264 return -ENOMEM;
2265
2266 ret = wsm_set_template_frame(priv, &frame);
2267
2268 dev_kfree_skb(frame.skb);
2269
2270 return ret;
2271}
2272
2273static int cw1200_upload_null(struct cw1200_common *priv)
2274{
2275 int ret = 0;
2276 struct wsm_template_frame frame = {
2277 .frame_type = WSM_FRAME_TYPE_NULL,
2278 .rate = 0xFF,
2279 };
2280
2281 frame.skb = ieee80211_nullfunc_get(priv->hw, priv->vif);
2282 if (!frame.skb)
2283 return -ENOMEM;
2284
2285 ret = wsm_set_template_frame(priv, &frame);
2286
2287 dev_kfree_skb(frame.skb);
2288
2289 return ret;
2290}
2291
2292static int cw1200_upload_qosnull(struct cw1200_common *priv)
2293{
2294 int ret = 0;
2295 /* TODO: This needs to be implemented
2296
2297 struct wsm_template_frame frame = {
2298 .frame_type = WSM_FRAME_TYPE_QOS_NULL,
2299 .rate = 0xFF,
2300 };
2301
2302 frame.skb = ieee80211_qosnullfunc_get(priv->hw, priv->vif);
2303 if (!frame.skb)
2304 return -ENOMEM;
2305
2306 ret = wsm_set_template_frame(priv, &frame);
2307
2308 dev_kfree_skb(frame.skb);
2309
2310 */
2311 return ret;
2312}
2313
2314static int cw1200_enable_beaconing(struct cw1200_common *priv,
2315 bool enable)
2316{
2317 struct wsm_beacon_transmit transmit = {
2318 .enable_beaconing = enable,
2319 };
2320
2321 return wsm_beacon_transmit(priv, &transmit);
2322}
2323
2324static int cw1200_start_ap(struct cw1200_common *priv)
2325{
2326 int ret;
2327 struct ieee80211_bss_conf *conf = &priv->vif->bss_conf;
2328 struct wsm_start start = {
2329 .mode = priv->vif->p2p ?
2330 WSM_START_MODE_P2P_GO : WSM_START_MODE_AP,
2331 .band = (priv->channel->band == IEEE80211_BAND_5GHZ) ?
2332 WSM_PHY_BAND_5G : WSM_PHY_BAND_2_4G,
2333 .channel_number = priv->channel->hw_value,
2334 .beacon_interval = conf->beacon_int,
2335 .dtim_period = conf->dtim_period,
2336 .preamble = conf->use_short_preamble ?
2337 WSM_JOIN_PREAMBLE_SHORT :
2338 WSM_JOIN_PREAMBLE_LONG,
2339 .probe_delay = 100,
2340 .basic_rate_set = cw1200_rate_mask_to_wsm(priv,
2341 conf->basic_rates),
2342 };
2343 struct wsm_operational_mode mode = {
2344 .power_mode = cw1200_power_mode,
2345 .disable_more_flag_usage = true,
2346 };
2347
2348 memset(start.ssid, 0, sizeof(start.ssid));
2349 if (!conf->hidden_ssid) {
2350 start.ssid_len = conf->ssid_len;
2351 memcpy(start.ssid, conf->ssid, start.ssid_len);
2352 }
2353
2354 priv->beacon_int = conf->beacon_int;
2355 priv->join_dtim_period = conf->dtim_period;
2356
2357 memset(&priv->link_id_db, 0, sizeof(priv->link_id_db));
2358
2359 pr_debug("[AP] ch: %d(%d), bcn: %d(%d), brt: 0x%.8X, ssid: %.*s.\n",
2360 start.channel_number, start.band,
2361 start.beacon_interval, start.dtim_period,
2362 start.basic_rate_set,
2363 start.ssid_len, start.ssid);
2364 ret = wsm_start(priv, &start);
2365 if (!ret)
2366 ret = cw1200_upload_keys(priv);
2367 if (!ret && priv->vif->p2p) {
2368 pr_debug("[AP] Setting p2p powersave configuration.\n");
2369 wsm_set_p2p_ps_modeinfo(priv, &priv->p2p_ps_modeinfo);
2370 }
2371 if (!ret) {
2372 wsm_set_block_ack_policy(priv, 0, 0);
2373 priv->join_status = CW1200_JOIN_STATUS_AP;
2374 cw1200_update_filtering(priv);
2375 }
2376 wsm_set_operational_mode(priv, &mode);
2377 return ret;
2378}
2379
2380static int cw1200_update_beaconing(struct cw1200_common *priv)
2381{
2382 struct ieee80211_bss_conf *conf = &priv->vif->bss_conf;
2383 struct wsm_reset reset = {
2384 .link_id = 0,
2385 .reset_statistics = true,
2386 };
2387
2388 if (priv->mode == NL80211_IFTYPE_AP) {
2389 /* TODO: check if changed channel, band */
2390 if (priv->join_status != CW1200_JOIN_STATUS_AP ||
2391 priv->beacon_int != conf->beacon_int) {
2392 pr_debug("ap restarting\n");
2393 wsm_lock_tx(priv);
2394 if (priv->join_status != CW1200_JOIN_STATUS_PASSIVE)
2395 wsm_reset(priv, &reset);
2396 priv->join_status = CW1200_JOIN_STATUS_PASSIVE;
2397 cw1200_start_ap(priv);
2398 wsm_unlock_tx(priv);
2399 } else
2400 pr_debug("ap started join_status: %d\n",
2401 priv->join_status);
2402 }
2403 return 0;
2404}
diff --git a/drivers/net/wireless/cw1200/sta.h b/drivers/net/wireless/cw1200/sta.h
new file mode 100644
index 000000000000..35babb62cc6a
--- /dev/null
+++ b/drivers/net/wireless/cw1200/sta.h
@@ -0,0 +1,123 @@
1/*
2 * Mac80211 STA interface for ST-Ericsson CW1200 mac80211 drivers
3 *
4 * Copyright (c) 2010, ST-Ericsson
5 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#ifndef STA_H_INCLUDED
13#define STA_H_INCLUDED
14
15/* ******************************************************************** */
16/* mac80211 API */
17
18int cw1200_start(struct ieee80211_hw *dev);
19void cw1200_stop(struct ieee80211_hw *dev);
20int cw1200_add_interface(struct ieee80211_hw *dev,
21 struct ieee80211_vif *vif);
22void cw1200_remove_interface(struct ieee80211_hw *dev,
23 struct ieee80211_vif *vif);
24int cw1200_change_interface(struct ieee80211_hw *dev,
25 struct ieee80211_vif *vif,
26 enum nl80211_iftype new_type,
27 bool p2p);
28int cw1200_config(struct ieee80211_hw *dev, u32 changed);
29void cw1200_configure_filter(struct ieee80211_hw *dev,
30 unsigned int changed_flags,
31 unsigned int *total_flags,
32 u64 multicast);
33int cw1200_conf_tx(struct ieee80211_hw *dev, struct ieee80211_vif *vif,
34 u16 queue, const struct ieee80211_tx_queue_params *params);
35int cw1200_get_stats(struct ieee80211_hw *dev,
36 struct ieee80211_low_level_stats *stats);
37int cw1200_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd,
38 struct ieee80211_vif *vif, struct ieee80211_sta *sta,
39 struct ieee80211_key_conf *key);
40
41int cw1200_set_rts_threshold(struct ieee80211_hw *hw, u32 value);
42
43void cw1200_flush(struct ieee80211_hw *hw, u32 queues, bool drop);
44
45u64 cw1200_prepare_multicast(struct ieee80211_hw *hw,
46 struct netdev_hw_addr_list *mc_list);
47
48int cw1200_set_pm(struct cw1200_common *priv, const struct wsm_set_pm *arg);
49
50/* ******************************************************************** */
51/* WSM callbacks */
52
53void cw1200_join_complete_cb(struct cw1200_common *priv,
54 struct wsm_join_complete *arg);
55
56/* ******************************************************************** */
57/* WSM events */
58
59void cw1200_free_event_queue(struct cw1200_common *priv);
60void cw1200_event_handler(struct work_struct *work);
61void cw1200_bss_loss_work(struct work_struct *work);
62void cw1200_bss_params_work(struct work_struct *work);
63void cw1200_keep_alive_work(struct work_struct *work);
64void cw1200_tx_failure_work(struct work_struct *work);
65
66void __cw1200_cqm_bssloss_sm(struct cw1200_common *priv, int init, int good,
67 int bad);
68static inline void cw1200_cqm_bssloss_sm(struct cw1200_common *priv,
69 int init, int good, int bad)
70{
71 spin_lock(&priv->bss_loss_lock);
72 __cw1200_cqm_bssloss_sm(priv, init, good, bad);
73 spin_unlock(&priv->bss_loss_lock);
74}
75
76/* ******************************************************************** */
77/* Internal API */
78
79int cw1200_setup_mac(struct cw1200_common *priv);
80void cw1200_join_timeout(struct work_struct *work);
81void cw1200_unjoin_work(struct work_struct *work);
82void cw1200_join_complete_work(struct work_struct *work);
83void cw1200_wep_key_work(struct work_struct *work);
84void cw1200_update_listening(struct cw1200_common *priv, bool enabled);
85void cw1200_update_filtering(struct cw1200_common *priv);
86void cw1200_update_filtering_work(struct work_struct *work);
87void cw1200_set_beacon_wakeup_period_work(struct work_struct *work);
88int cw1200_enable_listening(struct cw1200_common *priv);
89int cw1200_disable_listening(struct cw1200_common *priv);
90int cw1200_set_uapsd_param(struct cw1200_common *priv,
91 const struct wsm_edca_params *arg);
92void cw1200_ba_work(struct work_struct *work);
93void cw1200_ba_timer(unsigned long arg);
94
95/* AP stuffs */
96int cw1200_set_tim(struct ieee80211_hw *dev, struct ieee80211_sta *sta,
97 bool set);
98int cw1200_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
99 struct ieee80211_sta *sta);
100int cw1200_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
101 struct ieee80211_sta *sta);
102void cw1200_sta_notify(struct ieee80211_hw *dev, struct ieee80211_vif *vif,
103 enum sta_notify_cmd notify_cmd,
104 struct ieee80211_sta *sta);
105void cw1200_bss_info_changed(struct ieee80211_hw *dev,
106 struct ieee80211_vif *vif,
107 struct ieee80211_bss_conf *info,
108 u32 changed);
109int cw1200_ampdu_action(struct ieee80211_hw *hw,
110 struct ieee80211_vif *vif,
111 enum ieee80211_ampdu_mlme_action action,
112 struct ieee80211_sta *sta, u16 tid, u16 *ssn,
113 u8 buf_size);
114
115void cw1200_suspend_resume(struct cw1200_common *priv,
116 struct wsm_suspend_resume *arg);
117void cw1200_set_tim_work(struct work_struct *work);
118void cw1200_set_cts_work(struct work_struct *work);
119void cw1200_multicast_start_work(struct work_struct *work);
120void cw1200_multicast_stop_work(struct work_struct *work);
121void cw1200_mcast_timeout(unsigned long arg);
122
123#endif
diff --git a/drivers/net/wireless/cw1200/txrx.c b/drivers/net/wireless/cw1200/txrx.c
new file mode 100644
index 000000000000..44ca10cb0d39
--- /dev/null
+++ b/drivers/net/wireless/cw1200/txrx.c
@@ -0,0 +1,1474 @@
1/*
2 * Datapath implementation for ST-Ericsson CW1200 mac80211 drivers
3 *
4 * Copyright (c) 2010, ST-Ericsson
5 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <net/mac80211.h>
13#include <linux/etherdevice.h>
14#include <linux/skbuff.h>
15
16#include "cw1200.h"
17#include "wsm.h"
18#include "bh.h"
19#include "sta.h"
20#include "debug.h"
21
22#define CW1200_INVALID_RATE_ID (0xFF)
23
24static int cw1200_handle_action_rx(struct cw1200_common *priv,
25 struct sk_buff *skb);
26static const struct ieee80211_rate *
27cw1200_get_tx_rate(const struct cw1200_common *priv,
28 const struct ieee80211_tx_rate *rate);
29
30/* ******************************************************************** */
31/* TX queue lock / unlock */
32
33static inline void cw1200_tx_queues_lock(struct cw1200_common *priv)
34{
35 int i;
36 for (i = 0; i < 4; ++i)
37 cw1200_queue_lock(&priv->tx_queue[i]);
38}
39
40static inline void cw1200_tx_queues_unlock(struct cw1200_common *priv)
41{
42 int i;
43 for (i = 0; i < 4; ++i)
44 cw1200_queue_unlock(&priv->tx_queue[i]);
45}
46
47/* ******************************************************************** */
48/* TX policy cache implementation */
49
50static void tx_policy_dump(struct tx_policy *policy)
51{
52 pr_debug("[TX policy] %.1X%.1X%.1X%.1X%.1X%.1X%.1X%.1X %.1X%.1X%.1X%.1X%.1X%.1X%.1X%.1X %.1X%.1X%.1X%.1X%.1X%.1X%.1X%.1X: %d\n",
53 policy->raw[0] & 0x0F, policy->raw[0] >> 4,
54 policy->raw[1] & 0x0F, policy->raw[1] >> 4,
55 policy->raw[2] & 0x0F, policy->raw[2] >> 4,
56 policy->raw[3] & 0x0F, policy->raw[3] >> 4,
57 policy->raw[4] & 0x0F, policy->raw[4] >> 4,
58 policy->raw[5] & 0x0F, policy->raw[5] >> 4,
59 policy->raw[6] & 0x0F, policy->raw[6] >> 4,
60 policy->raw[7] & 0x0F, policy->raw[7] >> 4,
61 policy->raw[8] & 0x0F, policy->raw[8] >> 4,
62 policy->raw[9] & 0x0F, policy->raw[9] >> 4,
63 policy->raw[10] & 0x0F, policy->raw[10] >> 4,
64 policy->raw[11] & 0x0F, policy->raw[11] >> 4,
65 policy->defined);
66}
67
68static void tx_policy_build(const struct cw1200_common *priv,
69 /* [out] */ struct tx_policy *policy,
70 struct ieee80211_tx_rate *rates, size_t count)
71{
72 int i, j;
73 unsigned limit = priv->short_frame_max_tx_count;
74 unsigned total = 0;
75 BUG_ON(rates[0].idx < 0);
76 memset(policy, 0, sizeof(*policy));
77
78 /* Sort rates in descending order. */
79 for (i = 1; i < count; ++i) {
80 if (rates[i].idx < 0) {
81 count = i;
82 break;
83 }
84 if (rates[i].idx > rates[i - 1].idx) {
85 struct ieee80211_tx_rate tmp = rates[i - 1];
86 rates[i - 1] = rates[i];
87 rates[i] = tmp;
88 }
89 }
90
91 /* Eliminate duplicates. */
92 total = rates[0].count;
93 for (i = 0, j = 1; j < count; ++j) {
94 if (rates[j].idx == rates[i].idx) {
95 rates[i].count += rates[j].count;
96 } else if (rates[j].idx > rates[i].idx) {
97 break;
98 } else {
99 ++i;
100 if (i != j)
101 rates[i] = rates[j];
102 }
103 total += rates[j].count;
104 }
105 count = i + 1;
106
107 /* Re-fill policy trying to keep every requested rate and with
108 * respect to the global max tx retransmission count.
109 */
110 if (limit < count)
111 limit = count;
112 if (total > limit) {
113 for (i = 0; i < count; ++i) {
114 int left = count - i - 1;
115 if (rates[i].count > limit - left)
116 rates[i].count = limit - left;
117 limit -= rates[i].count;
118 }
119 }
120
121 /* HACK!!! Device has problems (at least) switching from
122 * 54Mbps CTS to 1Mbps. This switch takes enormous amount
123 * of time (100-200 ms), leading to valuable throughput drop.
124 * As a workaround, additional g-rates are injected to the
125 * policy.
126 */
127 if (count == 2 && !(rates[0].flags & IEEE80211_TX_RC_MCS) &&
128 rates[0].idx > 4 && rates[0].count > 2 &&
129 rates[1].idx < 2) {
130 int mid_rate = (rates[0].idx + 4) >> 1;
131
132 /* Decrease number of retries for the initial rate */
133 rates[0].count -= 2;
134
135 if (mid_rate != 4) {
136 /* Keep fallback rate at 1Mbps. */
137 rates[3] = rates[1];
138
139 /* Inject 1 transmission on lowest g-rate */
140 rates[2].idx = 4;
141 rates[2].count = 1;
142 rates[2].flags = rates[1].flags;
143
144 /* Inject 1 transmission on mid-rate */
145 rates[1].idx = mid_rate;
146 rates[1].count = 1;
147
148 /* Fallback to 1 Mbps is a really bad thing,
149 * so let's try to increase probability of
150 * successful transmission on the lowest g rate
151 * even more
152 */
153 if (rates[0].count >= 3) {
154 --rates[0].count;
155 ++rates[2].count;
156 }
157
158 /* Adjust amount of rates defined */
159 count += 2;
160 } else {
161 /* Keep fallback rate at 1Mbps. */
162 rates[2] = rates[1];
163
164 /* Inject 2 transmissions on lowest g-rate */
165 rates[1].idx = 4;
166 rates[1].count = 2;
167
168 /* Adjust amount of rates defined */
169 count += 1;
170 }
171 }
172
173 policy->defined = cw1200_get_tx_rate(priv, &rates[0])->hw_value + 1;
174
175 for (i = 0; i < count; ++i) {
176 register unsigned rateid, off, shift, retries;
177
178 rateid = cw1200_get_tx_rate(priv, &rates[i])->hw_value;
179 off = rateid >> 3; /* eq. rateid / 8 */
180 shift = (rateid & 0x07) << 2; /* eq. (rateid % 8) * 4 */
181
182 retries = rates[i].count;
183 if (retries > 0x0F) {
184 rates[i].count = 0x0f;
185 retries = 0x0F;
186 }
187 policy->tbl[off] |= __cpu_to_le32(retries << shift);
188 policy->retry_count += retries;
189 }
190
191 pr_debug("[TX policy] Policy (%zu): %d:%d, %d:%d, %d:%d, %d:%d\n",
192 count,
193 rates[0].idx, rates[0].count,
194 rates[1].idx, rates[1].count,
195 rates[2].idx, rates[2].count,
196 rates[3].idx, rates[3].count);
197}
198
199static inline bool tx_policy_is_equal(const struct tx_policy *wanted,
200 const struct tx_policy *cached)
201{
202 size_t count = wanted->defined >> 1;
203 if (wanted->defined > cached->defined)
204 return false;
205 if (count) {
206 if (memcmp(wanted->raw, cached->raw, count))
207 return false;
208 }
209 if (wanted->defined & 1) {
210 if ((wanted->raw[count] & 0x0F) != (cached->raw[count] & 0x0F))
211 return false;
212 }
213 return true;
214}
215
216static int tx_policy_find(struct tx_policy_cache *cache,
217 const struct tx_policy *wanted)
218{
219 /* O(n) complexity. Not so good, but there's only 8 entries in
220 * the cache.
221 * Also lru helps to reduce search time.
222 */
223 struct tx_policy_cache_entry *it;
224 /* First search for policy in "used" list */
225 list_for_each_entry(it, &cache->used, link) {
226 if (tx_policy_is_equal(wanted, &it->policy))
227 return it - cache->cache;
228 }
229 /* Then - in "free list" */
230 list_for_each_entry(it, &cache->free, link) {
231 if (tx_policy_is_equal(wanted, &it->policy))
232 return it - cache->cache;
233 }
234 return -1;
235}
236
237static inline void tx_policy_use(struct tx_policy_cache *cache,
238 struct tx_policy_cache_entry *entry)
239{
240 ++entry->policy.usage_count;
241 list_move(&entry->link, &cache->used);
242}
243
244static inline int tx_policy_release(struct tx_policy_cache *cache,
245 struct tx_policy_cache_entry *entry)
246{
247 int ret = --entry->policy.usage_count;
248 if (!ret)
249 list_move(&entry->link, &cache->free);
250 return ret;
251}
252
253void tx_policy_clean(struct cw1200_common *priv)
254{
255 int idx, locked;
256 struct tx_policy_cache *cache = &priv->tx_policy_cache;
257 struct tx_policy_cache_entry *entry;
258
259 cw1200_tx_queues_lock(priv);
260 spin_lock_bh(&cache->lock);
261 locked = list_empty(&cache->free);
262
263 for (idx = 0; idx < TX_POLICY_CACHE_SIZE; idx++) {
264 entry = &cache->cache[idx];
265 /* Policy usage count should be 0 at this time as all queues
266 should be empty
267 */
268 if (WARN_ON(entry->policy.usage_count)) {
269 entry->policy.usage_count = 0;
270 list_move(&entry->link, &cache->free);
271 }
272 memset(&entry->policy, 0, sizeof(entry->policy));
273 }
274 if (locked)
275 cw1200_tx_queues_unlock(priv);
276
277 cw1200_tx_queues_unlock(priv);
278 spin_unlock_bh(&cache->lock);
279}
280
281/* ******************************************************************** */
282/* External TX policy cache API */
283
284void tx_policy_init(struct cw1200_common *priv)
285{
286 struct tx_policy_cache *cache = &priv->tx_policy_cache;
287 int i;
288
289 memset(cache, 0, sizeof(*cache));
290
291 spin_lock_init(&cache->lock);
292 INIT_LIST_HEAD(&cache->used);
293 INIT_LIST_HEAD(&cache->free);
294
295 for (i = 0; i < TX_POLICY_CACHE_SIZE; ++i)
296 list_add(&cache->cache[i].link, &cache->free);
297}
298
299static int tx_policy_get(struct cw1200_common *priv,
300 struct ieee80211_tx_rate *rates,
301 size_t count, bool *renew)
302{
303 int idx;
304 struct tx_policy_cache *cache = &priv->tx_policy_cache;
305 struct tx_policy wanted;
306
307 tx_policy_build(priv, &wanted, rates, count);
308
309 spin_lock_bh(&cache->lock);
310 if (WARN_ON_ONCE(list_empty(&cache->free))) {
311 spin_unlock_bh(&cache->lock);
312 return CW1200_INVALID_RATE_ID;
313 }
314 idx = tx_policy_find(cache, &wanted);
315 if (idx >= 0) {
316 pr_debug("[TX policy] Used TX policy: %d\n", idx);
317 *renew = false;
318 } else {
319 struct tx_policy_cache_entry *entry;
320 *renew = true;
321 /* If policy is not found create a new one
322 * using the oldest entry in "free" list
323 */
324 entry = list_entry(cache->free.prev,
325 struct tx_policy_cache_entry, link);
326 entry->policy = wanted;
327 idx = entry - cache->cache;
328 pr_debug("[TX policy] New TX policy: %d\n", idx);
329 tx_policy_dump(&entry->policy);
330 }
331 tx_policy_use(cache, &cache->cache[idx]);
332 if (list_empty(&cache->free)) {
333 /* Lock TX queues. */
334 cw1200_tx_queues_lock(priv);
335 }
336 spin_unlock_bh(&cache->lock);
337 return idx;
338}
339
340static void tx_policy_put(struct cw1200_common *priv, int idx)
341{
342 int usage, locked;
343 struct tx_policy_cache *cache = &priv->tx_policy_cache;
344
345 spin_lock_bh(&cache->lock);
346 locked = list_empty(&cache->free);
347 usage = tx_policy_release(cache, &cache->cache[idx]);
348 if (locked && !usage) {
349 /* Unlock TX queues. */
350 cw1200_tx_queues_unlock(priv);
351 }
352 spin_unlock_bh(&cache->lock);
353}
354
355static int tx_policy_upload(struct cw1200_common *priv)
356{
357 struct tx_policy_cache *cache = &priv->tx_policy_cache;
358 int i;
359 struct wsm_set_tx_rate_retry_policy arg = {
360 .num = 0,
361 };
362 spin_lock_bh(&cache->lock);
363
364 /* Upload only modified entries. */
365 for (i = 0; i < TX_POLICY_CACHE_SIZE; ++i) {
366 struct tx_policy *src = &cache->cache[i].policy;
367 if (src->retry_count && !src->uploaded) {
368 struct wsm_tx_rate_retry_policy *dst =
369 &arg.tbl[arg.num];
370 dst->index = i;
371 dst->short_retries = priv->short_frame_max_tx_count;
372 dst->long_retries = priv->long_frame_max_tx_count;
373
374 dst->flags = WSM_TX_RATE_POLICY_FLAG_TERMINATE_WHEN_FINISHED |
375 WSM_TX_RATE_POLICY_FLAG_COUNT_INITIAL_TRANSMIT;
376 memcpy(dst->rate_count_indices, src->tbl,
377 sizeof(dst->rate_count_indices));
378 src->uploaded = 1;
379 ++arg.num;
380 }
381 }
382 spin_unlock_bh(&cache->lock);
383 cw1200_debug_tx_cache_miss(priv);
384 pr_debug("[TX policy] Upload %d policies\n", arg.num);
385 return wsm_set_tx_rate_retry_policy(priv, &arg);
386}
387
388void tx_policy_upload_work(struct work_struct *work)
389{
390 struct cw1200_common *priv =
391 container_of(work, struct cw1200_common, tx_policy_upload_work);
392
393 pr_debug("[TX] TX policy upload.\n");
394 tx_policy_upload(priv);
395
396 wsm_unlock_tx(priv);
397 cw1200_tx_queues_unlock(priv);
398}
399
400/* ******************************************************************** */
401/* cw1200 TX implementation */
402
403struct cw1200_txinfo {
404 struct sk_buff *skb;
405 unsigned queue;
406 struct ieee80211_tx_info *tx_info;
407 const struct ieee80211_rate *rate;
408 struct ieee80211_hdr *hdr;
409 size_t hdrlen;
410 const u8 *da;
411 struct cw1200_sta_priv *sta_priv;
412 struct ieee80211_sta *sta;
413 struct cw1200_txpriv txpriv;
414};
415
416u32 cw1200_rate_mask_to_wsm(struct cw1200_common *priv, u32 rates)
417{
418 u32 ret = 0;
419 int i;
420 for (i = 0; i < 32; ++i) {
421 if (rates & BIT(i))
422 ret |= BIT(priv->rates[i].hw_value);
423 }
424 return ret;
425}
426
427static const struct ieee80211_rate *
428cw1200_get_tx_rate(const struct cw1200_common *priv,
429 const struct ieee80211_tx_rate *rate)
430{
431 if (rate->idx < 0)
432 return NULL;
433 if (rate->flags & IEEE80211_TX_RC_MCS)
434 return &priv->mcs_rates[rate->idx];
435 return &priv->hw->wiphy->bands[priv->channel->band]->
436 bitrates[rate->idx];
437}
438
439static int
440cw1200_tx_h_calc_link_ids(struct cw1200_common *priv,
441 struct cw1200_txinfo *t)
442{
443 if (t->sta && t->sta_priv->link_id)
444 t->txpriv.raw_link_id =
445 t->txpriv.link_id =
446 t->sta_priv->link_id;
447 else if (priv->mode != NL80211_IFTYPE_AP)
448 t->txpriv.raw_link_id =
449 t->txpriv.link_id = 0;
450 else if (is_multicast_ether_addr(t->da)) {
451 if (priv->enable_beacon) {
452 t->txpriv.raw_link_id = 0;
453 t->txpriv.link_id = CW1200_LINK_ID_AFTER_DTIM;
454 } else {
455 t->txpriv.raw_link_id = 0;
456 t->txpriv.link_id = 0;
457 }
458 } else {
459 t->txpriv.link_id = cw1200_find_link_id(priv, t->da);
460 if (!t->txpriv.link_id)
461 t->txpriv.link_id = cw1200_alloc_link_id(priv, t->da);
462 if (!t->txpriv.link_id) {
463 wiphy_err(priv->hw->wiphy,
464 "No more link IDs available.\n");
465 return -ENOENT;
466 }
467 t->txpriv.raw_link_id = t->txpriv.link_id;
468 }
469 if (t->txpriv.raw_link_id)
470 priv->link_id_db[t->txpriv.raw_link_id - 1].timestamp =
471 jiffies;
472 if (t->sta && (t->sta->uapsd_queues & BIT(t->queue)))
473 t->txpriv.link_id = CW1200_LINK_ID_UAPSD;
474 return 0;
475}
476
477static void
478cw1200_tx_h_pm(struct cw1200_common *priv,
479 struct cw1200_txinfo *t)
480{
481 if (ieee80211_is_auth(t->hdr->frame_control)) {
482 u32 mask = ~BIT(t->txpriv.raw_link_id);
483 spin_lock_bh(&priv->ps_state_lock);
484 priv->sta_asleep_mask &= mask;
485 priv->pspoll_mask &= mask;
486 spin_unlock_bh(&priv->ps_state_lock);
487 }
488}
489
490static void
491cw1200_tx_h_calc_tid(struct cw1200_common *priv,
492 struct cw1200_txinfo *t)
493{
494 if (ieee80211_is_data_qos(t->hdr->frame_control)) {
495 u8 *qos = ieee80211_get_qos_ctl(t->hdr);
496 t->txpriv.tid = qos[0] & IEEE80211_QOS_CTL_TID_MASK;
497 } else if (ieee80211_is_data(t->hdr->frame_control)) {
498 t->txpriv.tid = 0;
499 }
500}
501
502static int
503cw1200_tx_h_crypt(struct cw1200_common *priv,
504 struct cw1200_txinfo *t)
505{
506 if (!t->tx_info->control.hw_key ||
507 !ieee80211_has_protected(t->hdr->frame_control))
508 return 0;
509
510 t->hdrlen += t->tx_info->control.hw_key->iv_len;
511 skb_put(t->skb, t->tx_info->control.hw_key->icv_len);
512
513 if (t->tx_info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP)
514 skb_put(t->skb, 8); /* MIC space */
515
516 return 0;
517}
518
519static int
520cw1200_tx_h_align(struct cw1200_common *priv,
521 struct cw1200_txinfo *t,
522 u8 *flags)
523{
524 size_t offset = (size_t)t->skb->data & 3;
525
526 if (!offset)
527 return 0;
528
529 if (offset & 1) {
530 wiphy_err(priv->hw->wiphy,
531 "Bug: attempt to transmit a frame with wrong alignment: %zu\n",
532 offset);
533 return -EINVAL;
534 }
535
536 if (skb_headroom(t->skb) < offset) {
537 wiphy_err(priv->hw->wiphy,
538 "Bug: no space allocated for DMA alignment. headroom: %d\n",
539 skb_headroom(t->skb));
540 return -ENOMEM;
541 }
542 skb_push(t->skb, offset);
543 t->hdrlen += offset;
544 t->txpriv.offset += offset;
545 *flags |= WSM_TX_2BYTES_SHIFT;
546 cw1200_debug_tx_align(priv);
547 return 0;
548}
549
550static int
551cw1200_tx_h_action(struct cw1200_common *priv,
552 struct cw1200_txinfo *t)
553{
554 struct ieee80211_mgmt *mgmt =
555 (struct ieee80211_mgmt *)t->hdr;
556 if (ieee80211_is_action(t->hdr->frame_control) &&
557 mgmt->u.action.category == WLAN_CATEGORY_BACK)
558 return 1;
559 else
560 return 0;
561}
562
563/* Add WSM header */
564static struct wsm_tx *
565cw1200_tx_h_wsm(struct cw1200_common *priv,
566 struct cw1200_txinfo *t)
567{
568 struct wsm_tx *wsm;
569
570 if (skb_headroom(t->skb) < sizeof(struct wsm_tx)) {
571 wiphy_err(priv->hw->wiphy,
572 "Bug: no space allocated for WSM header. headroom: %d\n",
573 skb_headroom(t->skb));
574 return NULL;
575 }
576
577 wsm = (struct wsm_tx *)skb_push(t->skb, sizeof(struct wsm_tx));
578 t->txpriv.offset += sizeof(struct wsm_tx);
579 memset(wsm, 0, sizeof(*wsm));
580 wsm->hdr.len = __cpu_to_le16(t->skb->len);
581 wsm->hdr.id = __cpu_to_le16(0x0004);
582 wsm->queue_id = wsm_queue_id_to_wsm(t->queue);
583 return wsm;
584}
585
586/* BT Coex specific handling */
587static void
588cw1200_tx_h_bt(struct cw1200_common *priv,
589 struct cw1200_txinfo *t,
590 struct wsm_tx *wsm)
591{
592 u8 priority = 0;
593
594 if (!priv->bt_present)
595 return;
596
597 if (ieee80211_is_nullfunc(t->hdr->frame_control)) {
598 priority = WSM_EPTA_PRIORITY_MGT;
599 } else if (ieee80211_is_data(t->hdr->frame_control)) {
600 /* Skip LLC SNAP header (+6) */
601 u8 *payload = &t->skb->data[t->hdrlen];
602 u16 *ethertype = (u16 *)&payload[6];
603 if (*ethertype == __be16_to_cpu(ETH_P_PAE))
604 priority = WSM_EPTA_PRIORITY_EAPOL;
605 } else if (ieee80211_is_assoc_req(t->hdr->frame_control) ||
606 ieee80211_is_reassoc_req(t->hdr->frame_control)) {
607 struct ieee80211_mgmt *mgt_frame =
608 (struct ieee80211_mgmt *)t->hdr;
609
610 if (mgt_frame->u.assoc_req.listen_interval <
611 priv->listen_interval) {
612 pr_debug("Modified Listen Interval to %d from %d\n",
613 priv->listen_interval,
614 mgt_frame->u.assoc_req.listen_interval);
615 /* Replace listen interval derieved from
616 * the one read from SDD
617 */
618 mgt_frame->u.assoc_req.listen_interval =
619 priv->listen_interval;
620 }
621 }
622
623 if (!priority) {
624 if (ieee80211_is_action(t->hdr->frame_control))
625 priority = WSM_EPTA_PRIORITY_ACTION;
626 else if (ieee80211_is_mgmt(t->hdr->frame_control))
627 priority = WSM_EPTA_PRIORITY_MGT;
628 else if ((wsm->queue_id == WSM_QUEUE_VOICE))
629 priority = WSM_EPTA_PRIORITY_VOICE;
630 else if ((wsm->queue_id == WSM_QUEUE_VIDEO))
631 priority = WSM_EPTA_PRIORITY_VIDEO;
632 else
633 priority = WSM_EPTA_PRIORITY_DATA;
634 }
635
636 pr_debug("[TX] EPTA priority %d.\n", priority);
637
638 wsm->flags |= priority << 1;
639}
640
641static int
642cw1200_tx_h_rate_policy(struct cw1200_common *priv,
643 struct cw1200_txinfo *t,
644 struct wsm_tx *wsm)
645{
646 bool tx_policy_renew = false;
647
648 t->txpriv.rate_id = tx_policy_get(priv,
649 t->tx_info->control.rates, IEEE80211_TX_MAX_RATES,
650 &tx_policy_renew);
651 if (t->txpriv.rate_id == CW1200_INVALID_RATE_ID)
652 return -EFAULT;
653
654 wsm->flags |= t->txpriv.rate_id << 4;
655
656 t->rate = cw1200_get_tx_rate(priv,
657 &t->tx_info->control.rates[0]),
658 wsm->max_tx_rate = t->rate->hw_value;
659 if (t->rate->flags & IEEE80211_TX_RC_MCS) {
660 if (cw1200_ht_greenfield(&priv->ht_info))
661 wsm->ht_tx_parameters |=
662 __cpu_to_le32(WSM_HT_TX_GREENFIELD);
663 else
664 wsm->ht_tx_parameters |=
665 __cpu_to_le32(WSM_HT_TX_MIXED);
666 }
667
668 if (tx_policy_renew) {
669 pr_debug("[TX] TX policy renew.\n");
670 /* It's not so optimal to stop TX queues every now and then.
671 * Better to reimplement task scheduling with
672 * a counter. TODO.
673 */
674 wsm_lock_tx_async(priv);
675 cw1200_tx_queues_lock(priv);
676 if (queue_work(priv->workqueue,
677 &priv->tx_policy_upload_work) <= 0) {
678 cw1200_tx_queues_unlock(priv);
679 wsm_unlock_tx(priv);
680 }
681 }
682 return 0;
683}
684
685static bool
686cw1200_tx_h_pm_state(struct cw1200_common *priv,
687 struct cw1200_txinfo *t)
688{
689 int was_buffered = 1;
690
691 if (t->txpriv.link_id == CW1200_LINK_ID_AFTER_DTIM &&
692 !priv->buffered_multicasts) {
693 priv->buffered_multicasts = true;
694 if (priv->sta_asleep_mask)
695 queue_work(priv->workqueue,
696 &priv->multicast_start_work);
697 }
698
699 if (t->txpriv.raw_link_id && t->txpriv.tid < CW1200_MAX_TID)
700 was_buffered = priv->link_id_db[t->txpriv.raw_link_id - 1].buffered[t->txpriv.tid]++;
701
702 return !was_buffered;
703}
704
705/* ******************************************************************** */
706
707void cw1200_tx(struct ieee80211_hw *dev,
708 struct ieee80211_tx_control *control,
709 struct sk_buff *skb)
710{
711 struct cw1200_common *priv = dev->priv;
712 struct cw1200_txinfo t = {
713 .skb = skb,
714 .queue = skb_get_queue_mapping(skb),
715 .tx_info = IEEE80211_SKB_CB(skb),
716 .hdr = (struct ieee80211_hdr *)skb->data,
717 .txpriv.tid = CW1200_MAX_TID,
718 .txpriv.rate_id = CW1200_INVALID_RATE_ID,
719 };
720 struct ieee80211_sta *sta;
721 struct wsm_tx *wsm;
722 bool tid_update = 0;
723 u8 flags = 0;
724 int ret;
725
726 if (priv->bh_error)
727 goto drop;
728
729 t.hdrlen = ieee80211_hdrlen(t.hdr->frame_control);
730 t.da = ieee80211_get_DA(t.hdr);
731 if (control) {
732 t.sta = control->sta;
733 t.sta_priv = (struct cw1200_sta_priv *)&t.sta->drv_priv;
734 }
735
736 if (WARN_ON(t.queue >= 4))
737 goto drop;
738
739 ret = cw1200_tx_h_calc_link_ids(priv, &t);
740 if (ret)
741 goto drop;
742
743 pr_debug("[TX] TX %d bytes (queue: %d, link_id: %d (%d)).\n",
744 skb->len, t.queue, t.txpriv.link_id,
745 t.txpriv.raw_link_id);
746
747 cw1200_tx_h_pm(priv, &t);
748 cw1200_tx_h_calc_tid(priv, &t);
749 ret = cw1200_tx_h_crypt(priv, &t);
750 if (ret)
751 goto drop;
752 ret = cw1200_tx_h_align(priv, &t, &flags);
753 if (ret)
754 goto drop;
755 ret = cw1200_tx_h_action(priv, &t);
756 if (ret)
757 goto drop;
758 wsm = cw1200_tx_h_wsm(priv, &t);
759 if (!wsm) {
760 ret = -ENOMEM;
761 goto drop;
762 }
763 wsm->flags |= flags;
764 cw1200_tx_h_bt(priv, &t, wsm);
765 ret = cw1200_tx_h_rate_policy(priv, &t, wsm);
766 if (ret)
767 goto drop;
768
769 rcu_read_lock();
770 sta = rcu_dereference(t.sta);
771
772 spin_lock_bh(&priv->ps_state_lock);
773 {
774 tid_update = cw1200_tx_h_pm_state(priv, &t);
775 BUG_ON(cw1200_queue_put(&priv->tx_queue[t.queue],
776 t.skb, &t.txpriv));
777 }
778 spin_unlock_bh(&priv->ps_state_lock);
779
780 if (tid_update && sta)
781 ieee80211_sta_set_buffered(sta, t.txpriv.tid, true);
782
783 rcu_read_unlock();
784
785 cw1200_bh_wakeup(priv);
786
787 return;
788
789drop:
790 cw1200_skb_dtor(priv, skb, &t.txpriv);
791 return;
792}
793
794/* ******************************************************************** */
795
796static int cw1200_handle_action_rx(struct cw1200_common *priv,
797 struct sk_buff *skb)
798{
799 struct ieee80211_mgmt *mgmt = (void *)skb->data;
800
801 /* Filter block ACK negotiation: fully controlled by firmware */
802 if (mgmt->u.action.category == WLAN_CATEGORY_BACK)
803 return 1;
804
805 return 0;
806}
807
808static int cw1200_handle_pspoll(struct cw1200_common *priv,
809 struct sk_buff *skb)
810{
811 struct ieee80211_sta *sta;
812 struct ieee80211_pspoll *pspoll = (struct ieee80211_pspoll *)skb->data;
813 int link_id = 0;
814 u32 pspoll_mask = 0;
815 int drop = 1;
816 int i;
817
818 if (priv->join_status != CW1200_JOIN_STATUS_AP)
819 goto done;
820 if (memcmp(priv->vif->addr, pspoll->bssid, ETH_ALEN))
821 goto done;
822
823 rcu_read_lock();
824 sta = ieee80211_find_sta(priv->vif, pspoll->ta);
825 if (sta) {
826 struct cw1200_sta_priv *sta_priv;
827 sta_priv = (struct cw1200_sta_priv *)&sta->drv_priv;
828 link_id = sta_priv->link_id;
829 pspoll_mask = BIT(sta_priv->link_id);
830 }
831 rcu_read_unlock();
832 if (!link_id)
833 goto done;
834
835 priv->pspoll_mask |= pspoll_mask;
836 drop = 0;
837
838 /* Do not report pspols if data for given link id is queued already. */
839 for (i = 0; i < 4; ++i) {
840 if (cw1200_queue_get_num_queued(&priv->tx_queue[i],
841 pspoll_mask)) {
842 cw1200_bh_wakeup(priv);
843 drop = 1;
844 break;
845 }
846 }
847 pr_debug("[RX] PSPOLL: %s\n", drop ? "local" : "fwd");
848done:
849 return drop;
850}
851
852/* ******************************************************************** */
853
854void cw1200_tx_confirm_cb(struct cw1200_common *priv,
855 int link_id,
856 struct wsm_tx_confirm *arg)
857{
858 u8 queue_id = cw1200_queue_get_queue_id(arg->packet_id);
859 struct cw1200_queue *queue = &priv->tx_queue[queue_id];
860 struct sk_buff *skb;
861 const struct cw1200_txpriv *txpriv;
862
863 pr_debug("[TX] TX confirm: %d, %d.\n",
864 arg->status, arg->ack_failures);
865
866 if (priv->mode == NL80211_IFTYPE_UNSPECIFIED) {
867 /* STA is stopped. */
868 return;
869 }
870
871 if (WARN_ON(queue_id >= 4))
872 return;
873
874 if (arg->status)
875 pr_debug("TX failed: %d.\n", arg->status);
876
877 if ((arg->status == WSM_REQUEUE) &&
878 (arg->flags & WSM_TX_STATUS_REQUEUE)) {
879 /* "Requeue" means "implicit suspend" */
880 struct wsm_suspend_resume suspend = {
881 .link_id = link_id,
882 .stop = 1,
883 .multicast = !link_id,
884 };
885 cw1200_suspend_resume(priv, &suspend);
886 wiphy_warn(priv->hw->wiphy, "Requeue for link_id %d (try %d). STAs asleep: 0x%.8X\n",
887 link_id,
888 cw1200_queue_get_generation(arg->packet_id) + 1,
889 priv->sta_asleep_mask);
890 cw1200_queue_requeue(queue, arg->packet_id);
891 spin_lock_bh(&priv->ps_state_lock);
892 if (!link_id) {
893 priv->buffered_multicasts = true;
894 if (priv->sta_asleep_mask) {
895 queue_work(priv->workqueue,
896 &priv->multicast_start_work);
897 }
898 }
899 spin_unlock_bh(&priv->ps_state_lock);
900 } else if (!cw1200_queue_get_skb(queue, arg->packet_id,
901 &skb, &txpriv)) {
902 struct ieee80211_tx_info *tx = IEEE80211_SKB_CB(skb);
903 int tx_count = arg->ack_failures;
904 u8 ht_flags = 0;
905 int i;
906
907 if (cw1200_ht_greenfield(&priv->ht_info))
908 ht_flags |= IEEE80211_TX_RC_GREEN_FIELD;
909
910 spin_lock(&priv->bss_loss_lock);
911 if (priv->bss_loss_state &&
912 arg->packet_id == priv->bss_loss_confirm_id) {
913 if (arg->status) {
914 /* Recovery failed */
915 __cw1200_cqm_bssloss_sm(priv, 0, 0, 1);
916 } else {
917 /* Recovery succeeded */
918 __cw1200_cqm_bssloss_sm(priv, 0, 1, 0);
919 }
920 }
921 spin_unlock(&priv->bss_loss_lock);
922
923 if (!arg->status) {
924 tx->flags |= IEEE80211_TX_STAT_ACK;
925 ++tx_count;
926 cw1200_debug_txed(priv);
927 if (arg->flags & WSM_TX_STATUS_AGGREGATION) {
928 /* Do not report aggregation to mac80211:
929 * it confuses minstrel a lot.
930 */
931 /* tx->flags |= IEEE80211_TX_STAT_AMPDU; */
932 cw1200_debug_txed_agg(priv);
933 }
934 } else {
935 if (tx_count)
936 ++tx_count;
937 }
938
939 for (i = 0; i < IEEE80211_TX_MAX_RATES; ++i) {
940 if (tx->status.rates[i].count >= tx_count) {
941 tx->status.rates[i].count = tx_count;
942 break;
943 }
944 tx_count -= tx->status.rates[i].count;
945 if (tx->status.rates[i].flags & IEEE80211_TX_RC_MCS)
946 tx->status.rates[i].flags |= ht_flags;
947 }
948
949 for (++i; i < IEEE80211_TX_MAX_RATES; ++i) {
950 tx->status.rates[i].count = 0;
951 tx->status.rates[i].idx = -1;
952 }
953
954 /* Pull off any crypto trailers that we added on */
955 if (tx->control.hw_key) {
956 skb_trim(skb, skb->len - tx->control.hw_key->icv_len);
957 if (tx->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP)
958 skb_trim(skb, skb->len - 8); /* MIC space */
959 }
960 cw1200_queue_remove(queue, arg->packet_id);
961 }
962 /* XXX TODO: Only wake if there are pending transmits.. */
963 cw1200_bh_wakeup(priv);
964}
965
966static void cw1200_notify_buffered_tx(struct cw1200_common *priv,
967 struct sk_buff *skb, int link_id, int tid)
968{
969 struct ieee80211_sta *sta;
970 struct ieee80211_hdr *hdr;
971 u8 *buffered;
972 u8 still_buffered = 0;
973
974 if (link_id && tid < CW1200_MAX_TID) {
975 buffered = priv->link_id_db
976 [link_id - 1].buffered;
977
978 spin_lock_bh(&priv->ps_state_lock);
979 if (!WARN_ON(!buffered[tid]))
980 still_buffered = --buffered[tid];
981 spin_unlock_bh(&priv->ps_state_lock);
982
983 if (!still_buffered && tid < CW1200_MAX_TID) {
984 hdr = (struct ieee80211_hdr *)skb->data;
985 rcu_read_lock();
986 sta = ieee80211_find_sta(priv->vif, hdr->addr1);
987 if (sta)
988 ieee80211_sta_set_buffered(sta, tid, false);
989 rcu_read_unlock();
990 }
991 }
992}
993
994void cw1200_skb_dtor(struct cw1200_common *priv,
995 struct sk_buff *skb,
996 const struct cw1200_txpriv *txpriv)
997{
998 skb_pull(skb, txpriv->offset);
999 if (txpriv->rate_id != CW1200_INVALID_RATE_ID) {
1000 cw1200_notify_buffered_tx(priv, skb,
1001 txpriv->raw_link_id, txpriv->tid);
1002 tx_policy_put(priv, txpriv->rate_id);
1003 }
1004 ieee80211_tx_status(priv->hw, skb);
1005}
1006
1007void cw1200_rx_cb(struct cw1200_common *priv,
1008 struct wsm_rx *arg,
1009 int link_id,
1010 struct sk_buff **skb_p)
1011{
1012 struct sk_buff *skb = *skb_p;
1013 struct ieee80211_rx_status *hdr = IEEE80211_SKB_RXCB(skb);
1014 struct ieee80211_hdr *frame = (struct ieee80211_hdr *)skb->data;
1015 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
1016 struct cw1200_link_entry *entry = NULL;
1017 unsigned long grace_period;
1018
1019 bool early_data = false;
1020 bool p2p = priv->vif && priv->vif->p2p;
1021 size_t hdrlen;
1022 hdr->flag = 0;
1023
1024 if (priv->mode == NL80211_IFTYPE_UNSPECIFIED) {
1025 /* STA is stopped. */
1026 goto drop;
1027 }
1028
1029 if (link_id && link_id <= CW1200_MAX_STA_IN_AP_MODE) {
1030 entry = &priv->link_id_db[link_id - 1];
1031 if (entry->status == CW1200_LINK_SOFT &&
1032 ieee80211_is_data(frame->frame_control))
1033 early_data = true;
1034 entry->timestamp = jiffies;
1035 } else if (p2p &&
1036 ieee80211_is_action(frame->frame_control) &&
1037 (mgmt->u.action.category == WLAN_CATEGORY_PUBLIC)) {
1038 pr_debug("[RX] Going to MAP&RESET link ID\n");
1039 WARN_ON(work_pending(&priv->linkid_reset_work));
1040 memcpy(&priv->action_frame_sa[0],
1041 ieee80211_get_SA(frame), ETH_ALEN);
1042 priv->action_linkid = 0;
1043 schedule_work(&priv->linkid_reset_work);
1044 }
1045
1046 if (link_id && p2p &&
1047 ieee80211_is_action(frame->frame_control) &&
1048 (mgmt->u.action.category == WLAN_CATEGORY_PUBLIC)) {
1049 /* Link ID already exists for the ACTION frame.
1050 * Reset and Remap
1051 */
1052 WARN_ON(work_pending(&priv->linkid_reset_work));
1053 memcpy(&priv->action_frame_sa[0],
1054 ieee80211_get_SA(frame), ETH_ALEN);
1055 priv->action_linkid = link_id;
1056 schedule_work(&priv->linkid_reset_work);
1057 }
1058 if (arg->status) {
1059 if (arg->status == WSM_STATUS_MICFAILURE) {
1060 pr_debug("[RX] MIC failure.\n");
1061 hdr->flag |= RX_FLAG_MMIC_ERROR;
1062 } else if (arg->status == WSM_STATUS_NO_KEY_FOUND) {
1063 pr_debug("[RX] No key found.\n");
1064 goto drop;
1065 } else {
1066 pr_debug("[RX] Receive failure: %d.\n",
1067 arg->status);
1068 goto drop;
1069 }
1070 }
1071
1072 if (skb->len < sizeof(struct ieee80211_pspoll)) {
1073 wiphy_warn(priv->hw->wiphy, "Mailformed SDU rx'ed. Size is lesser than IEEE header.\n");
1074 goto drop;
1075 }
1076
1077 if (ieee80211_is_pspoll(frame->frame_control))
1078 if (cw1200_handle_pspoll(priv, skb))
1079 goto drop;
1080
1081 hdr->band = ((arg->channel_number & 0xff00) ||
1082 (arg->channel_number > 14)) ?
1083 IEEE80211_BAND_5GHZ : IEEE80211_BAND_2GHZ;
1084 hdr->freq = ieee80211_channel_to_frequency(
1085 arg->channel_number,
1086 hdr->band);
1087
1088 if (arg->rx_rate >= 14) {
1089 hdr->flag |= RX_FLAG_HT;
1090 hdr->rate_idx = arg->rx_rate - 14;
1091 } else if (arg->rx_rate >= 4) {
1092 hdr->rate_idx = arg->rx_rate - 2;
1093 } else {
1094 hdr->rate_idx = arg->rx_rate;
1095 }
1096
1097 hdr->signal = (s8)arg->rcpi_rssi;
1098 hdr->antenna = 0;
1099
1100 hdrlen = ieee80211_hdrlen(frame->frame_control);
1101
1102 if (WSM_RX_STATUS_ENCRYPTION(arg->flags)) {
1103 size_t iv_len = 0, icv_len = 0;
1104
1105 hdr->flag |= RX_FLAG_DECRYPTED | RX_FLAG_IV_STRIPPED;
1106
1107 /* Oops... There is no fast way to ask mac80211 about
1108 * IV/ICV lengths. Even defineas are not exposed.
1109 */
1110 switch (WSM_RX_STATUS_ENCRYPTION(arg->flags)) {
1111 case WSM_RX_STATUS_WEP:
1112 iv_len = 4 /* WEP_IV_LEN */;
1113 icv_len = 4 /* WEP_ICV_LEN */;
1114 break;
1115 case WSM_RX_STATUS_TKIP:
1116 iv_len = 8 /* TKIP_IV_LEN */;
1117 icv_len = 4 /* TKIP_ICV_LEN */
1118 + 8 /*MICHAEL_MIC_LEN*/;
1119 hdr->flag |= RX_FLAG_MMIC_STRIPPED;
1120 break;
1121 case WSM_RX_STATUS_AES:
1122 iv_len = 8 /* CCMP_HDR_LEN */;
1123 icv_len = 8 /* CCMP_MIC_LEN */;
1124 break;
1125 case WSM_RX_STATUS_WAPI:
1126 iv_len = 18 /* WAPI_HDR_LEN */;
1127 icv_len = 16 /* WAPI_MIC_LEN */;
1128 break;
1129 default:
1130 pr_warn("Unknown encryption type %d\n",
1131 WSM_RX_STATUS_ENCRYPTION(arg->flags));
1132 goto drop;
1133 }
1134
1135 /* Firmware strips ICV in case of MIC failure. */
1136 if (arg->status == WSM_STATUS_MICFAILURE)
1137 icv_len = 0;
1138
1139 if (skb->len < hdrlen + iv_len + icv_len) {
1140 wiphy_warn(priv->hw->wiphy, "Malformed SDU rx'ed. Size is lesser than crypto headers.\n");
1141 goto drop;
1142 }
1143
1144 /* Remove IV, ICV and MIC */
1145 skb_trim(skb, skb->len - icv_len);
1146 memmove(skb->data + iv_len, skb->data, hdrlen);
1147 skb_pull(skb, iv_len);
1148 }
1149
1150 /* Remove TSF from the end of frame */
1151 if (arg->flags & WSM_RX_STATUS_TSF_INCLUDED) {
1152 memcpy(&hdr->mactime, skb->data + skb->len - 8, 8);
1153 hdr->mactime = le64_to_cpu(hdr->mactime);
1154 if (skb->len >= 8)
1155 skb_trim(skb, skb->len - 8);
1156 } else {
1157 hdr->mactime = 0;
1158 }
1159
1160 cw1200_debug_rxed(priv);
1161 if (arg->flags & WSM_RX_STATUS_AGGREGATE)
1162 cw1200_debug_rxed_agg(priv);
1163
1164 if (ieee80211_is_action(frame->frame_control) &&
1165 (arg->flags & WSM_RX_STATUS_ADDRESS1)) {
1166 if (cw1200_handle_action_rx(priv, skb))
1167 return;
1168 } else if (ieee80211_is_beacon(frame->frame_control) &&
1169 !arg->status &&
1170 !memcmp(ieee80211_get_SA(frame), priv->vif->bss_conf.bssid,
1171 ETH_ALEN)) {
1172 const u8 *tim_ie;
1173 u8 *ies = ((struct ieee80211_mgmt *)
1174 (skb->data))->u.beacon.variable;
1175 size_t ies_len = skb->len - (ies - (u8 *)(skb->data));
1176
1177 tim_ie = cfg80211_find_ie(WLAN_EID_TIM, ies, ies_len);
1178 if (tim_ie) {
1179 struct ieee80211_tim_ie *tim =
1180 (struct ieee80211_tim_ie *)&tim_ie[2];
1181
1182 if (priv->join_dtim_period != tim->dtim_period) {
1183 priv->join_dtim_period = tim->dtim_period;
1184 queue_work(priv->workqueue,
1185 &priv->set_beacon_wakeup_period_work);
1186 }
1187 }
1188
1189 /* Disable beacon filter once we're associated... */
1190 if (priv->disable_beacon_filter &&
1191 (priv->vif->bss_conf.assoc ||
1192 priv->vif->bss_conf.ibss_joined)) {
1193 priv->disable_beacon_filter = false;
1194 queue_work(priv->workqueue,
1195 &priv->update_filtering_work);
1196 }
1197 }
1198
1199 /* Stay awake after frame is received to give
1200 * userspace chance to react and acquire appropriate
1201 * wakelock.
1202 */
1203 if (ieee80211_is_auth(frame->frame_control))
1204 grace_period = 5 * HZ;
1205 else if (ieee80211_is_deauth(frame->frame_control))
1206 grace_period = 5 * HZ;
1207 else
1208 grace_period = 1 * HZ;
1209 cw1200_pm_stay_awake(&priv->pm_state, grace_period);
1210
1211 if (early_data) {
1212 spin_lock_bh(&priv->ps_state_lock);
1213 /* Double-check status with lock held */
1214 if (entry->status == CW1200_LINK_SOFT)
1215 skb_queue_tail(&entry->rx_queue, skb);
1216 else
1217 ieee80211_rx_irqsafe(priv->hw, skb);
1218 spin_unlock_bh(&priv->ps_state_lock);
1219 } else {
1220 ieee80211_rx_irqsafe(priv->hw, skb);
1221 }
1222 *skb_p = NULL;
1223
1224 return;
1225
1226drop:
1227 /* TODO: update failure counters */
1228 return;
1229}
1230
1231/* ******************************************************************** */
1232/* Security */
1233
1234int cw1200_alloc_key(struct cw1200_common *priv)
1235{
1236 int idx;
1237
1238 idx = ffs(~priv->key_map) - 1;
1239 if (idx < 0 || idx > WSM_KEY_MAX_INDEX)
1240 return -1;
1241
1242 priv->key_map |= BIT(idx);
1243 priv->keys[idx].index = idx;
1244 return idx;
1245}
1246
1247void cw1200_free_key(struct cw1200_common *priv, int idx)
1248{
1249 BUG_ON(!(priv->key_map & BIT(idx)));
1250 memset(&priv->keys[idx], 0, sizeof(priv->keys[idx]));
1251 priv->key_map &= ~BIT(idx);
1252}
1253
1254void cw1200_free_keys(struct cw1200_common *priv)
1255{
1256 memset(&priv->keys, 0, sizeof(priv->keys));
1257 priv->key_map = 0;
1258}
1259
1260int cw1200_upload_keys(struct cw1200_common *priv)
1261{
1262 int idx, ret = 0;
1263 for (idx = 0; idx <= WSM_KEY_MAX_INDEX; ++idx)
1264 if (priv->key_map & BIT(idx)) {
1265 ret = wsm_add_key(priv, &priv->keys[idx]);
1266 if (ret < 0)
1267 break;
1268 }
1269 return ret;
1270}
1271
1272/* Workaround for WFD test case 6.1.10 */
1273void cw1200_link_id_reset(struct work_struct *work)
1274{
1275 struct cw1200_common *priv =
1276 container_of(work, struct cw1200_common, linkid_reset_work);
1277 int temp_linkid;
1278
1279 if (!priv->action_linkid) {
1280 /* In GO mode we can receive ACTION frames without a linkID */
1281 temp_linkid = cw1200_alloc_link_id(priv,
1282 &priv->action_frame_sa[0]);
1283 WARN_ON(!temp_linkid);
1284 if (temp_linkid) {
1285 /* Make sure we execute the WQ */
1286 flush_workqueue(priv->workqueue);
1287 /* Release the link ID */
1288 spin_lock_bh(&priv->ps_state_lock);
1289 priv->link_id_db[temp_linkid - 1].prev_status =
1290 priv->link_id_db[temp_linkid - 1].status;
1291 priv->link_id_db[temp_linkid - 1].status =
1292 CW1200_LINK_RESET;
1293 spin_unlock_bh(&priv->ps_state_lock);
1294 wsm_lock_tx_async(priv);
1295 if (queue_work(priv->workqueue,
1296 &priv->link_id_work) <= 0)
1297 wsm_unlock_tx(priv);
1298 }
1299 } else {
1300 spin_lock_bh(&priv->ps_state_lock);
1301 priv->link_id_db[priv->action_linkid - 1].prev_status =
1302 priv->link_id_db[priv->action_linkid - 1].status;
1303 priv->link_id_db[priv->action_linkid - 1].status =
1304 CW1200_LINK_RESET_REMAP;
1305 spin_unlock_bh(&priv->ps_state_lock);
1306 wsm_lock_tx_async(priv);
1307 if (queue_work(priv->workqueue, &priv->link_id_work) <= 0)
1308 wsm_unlock_tx(priv);
1309 flush_workqueue(priv->workqueue);
1310 }
1311}
1312
1313int cw1200_find_link_id(struct cw1200_common *priv, const u8 *mac)
1314{
1315 int i, ret = 0;
1316 spin_lock_bh(&priv->ps_state_lock);
1317 for (i = 0; i < CW1200_MAX_STA_IN_AP_MODE; ++i) {
1318 if (!memcmp(mac, priv->link_id_db[i].mac, ETH_ALEN) &&
1319 priv->link_id_db[i].status) {
1320 priv->link_id_db[i].timestamp = jiffies;
1321 ret = i + 1;
1322 break;
1323 }
1324 }
1325 spin_unlock_bh(&priv->ps_state_lock);
1326 return ret;
1327}
1328
1329int cw1200_alloc_link_id(struct cw1200_common *priv, const u8 *mac)
1330{
1331 int i, ret = 0;
1332 unsigned long max_inactivity = 0;
1333 unsigned long now = jiffies;
1334
1335 spin_lock_bh(&priv->ps_state_lock);
1336 for (i = 0; i < CW1200_MAX_STA_IN_AP_MODE; ++i) {
1337 if (!priv->link_id_db[i].status) {
1338 ret = i + 1;
1339 break;
1340 } else if (priv->link_id_db[i].status != CW1200_LINK_HARD &&
1341 !priv->tx_queue_stats.link_map_cache[i + 1]) {
1342 unsigned long inactivity =
1343 now - priv->link_id_db[i].timestamp;
1344 if (inactivity < max_inactivity)
1345 continue;
1346 max_inactivity = inactivity;
1347 ret = i + 1;
1348 }
1349 }
1350 if (ret) {
1351 struct cw1200_link_entry *entry = &priv->link_id_db[ret - 1];
1352 pr_debug("[AP] STA added, link_id: %d\n", ret);
1353 entry->status = CW1200_LINK_RESERVE;
1354 memcpy(&entry->mac, mac, ETH_ALEN);
1355 memset(&entry->buffered, 0, CW1200_MAX_TID);
1356 skb_queue_head_init(&entry->rx_queue);
1357 wsm_lock_tx_async(priv);
1358 if (queue_work(priv->workqueue, &priv->link_id_work) <= 0)
1359 wsm_unlock_tx(priv);
1360 } else {
1361 wiphy_info(priv->hw->wiphy,
1362 "[AP] Early: no more link IDs available.\n");
1363 }
1364
1365 spin_unlock_bh(&priv->ps_state_lock);
1366 return ret;
1367}
1368
1369void cw1200_link_id_work(struct work_struct *work)
1370{
1371 struct cw1200_common *priv =
1372 container_of(work, struct cw1200_common, link_id_work);
1373 wsm_flush_tx(priv);
1374 cw1200_link_id_gc_work(&priv->link_id_gc_work.work);
1375 wsm_unlock_tx(priv);
1376}
1377
1378void cw1200_link_id_gc_work(struct work_struct *work)
1379{
1380 struct cw1200_common *priv =
1381 container_of(work, struct cw1200_common, link_id_gc_work.work);
1382 struct wsm_reset reset = {
1383 .reset_statistics = false,
1384 };
1385 struct wsm_map_link map_link = {
1386 .link_id = 0,
1387 };
1388 unsigned long now = jiffies;
1389 unsigned long next_gc = -1;
1390 long ttl;
1391 bool need_reset;
1392 u32 mask;
1393 int i;
1394
1395 if (priv->join_status != CW1200_JOIN_STATUS_AP)
1396 return;
1397
1398 wsm_lock_tx(priv);
1399 spin_lock_bh(&priv->ps_state_lock);
1400 for (i = 0; i < CW1200_MAX_STA_IN_AP_MODE; ++i) {
1401 need_reset = false;
1402 mask = BIT(i + 1);
1403 if (priv->link_id_db[i].status == CW1200_LINK_RESERVE ||
1404 (priv->link_id_db[i].status == CW1200_LINK_HARD &&
1405 !(priv->link_id_map & mask))) {
1406 if (priv->link_id_map & mask) {
1407 priv->sta_asleep_mask &= ~mask;
1408 priv->pspoll_mask &= ~mask;
1409 need_reset = true;
1410 }
1411 priv->link_id_map |= mask;
1412 if (priv->link_id_db[i].status != CW1200_LINK_HARD)
1413 priv->link_id_db[i].status = CW1200_LINK_SOFT;
1414 memcpy(map_link.mac_addr, priv->link_id_db[i].mac,
1415 ETH_ALEN);
1416 spin_unlock_bh(&priv->ps_state_lock);
1417 if (need_reset) {
1418 reset.link_id = i + 1;
1419 wsm_reset(priv, &reset);
1420 }
1421 map_link.link_id = i + 1;
1422 wsm_map_link(priv, &map_link);
1423 next_gc = min(next_gc, CW1200_LINK_ID_GC_TIMEOUT);
1424 spin_lock_bh(&priv->ps_state_lock);
1425 } else if (priv->link_id_db[i].status == CW1200_LINK_SOFT) {
1426 ttl = priv->link_id_db[i].timestamp - now +
1427 CW1200_LINK_ID_GC_TIMEOUT;
1428 if (ttl <= 0) {
1429 need_reset = true;
1430 priv->link_id_db[i].status = CW1200_LINK_OFF;
1431 priv->link_id_map &= ~mask;
1432 priv->sta_asleep_mask &= ~mask;
1433 priv->pspoll_mask &= ~mask;
1434 memset(map_link.mac_addr, 0, ETH_ALEN);
1435 spin_unlock_bh(&priv->ps_state_lock);
1436 reset.link_id = i + 1;
1437 wsm_reset(priv, &reset);
1438 spin_lock_bh(&priv->ps_state_lock);
1439 } else {
1440 next_gc = min_t(unsigned long, next_gc, ttl);
1441 }
1442 } else if (priv->link_id_db[i].status == CW1200_LINK_RESET ||
1443 priv->link_id_db[i].status ==
1444 CW1200_LINK_RESET_REMAP) {
1445 int status = priv->link_id_db[i].status;
1446 priv->link_id_db[i].status =
1447 priv->link_id_db[i].prev_status;
1448 priv->link_id_db[i].timestamp = now;
1449 reset.link_id = i + 1;
1450 spin_unlock_bh(&priv->ps_state_lock);
1451 wsm_reset(priv, &reset);
1452 if (status == CW1200_LINK_RESET_REMAP) {
1453 memcpy(map_link.mac_addr,
1454 priv->link_id_db[i].mac,
1455 ETH_ALEN);
1456 map_link.link_id = i + 1;
1457 wsm_map_link(priv, &map_link);
1458 next_gc = min(next_gc,
1459 CW1200_LINK_ID_GC_TIMEOUT);
1460 }
1461 spin_lock_bh(&priv->ps_state_lock);
1462 }
1463 if (need_reset) {
1464 skb_queue_purge(&priv->link_id_db[i].rx_queue);
1465 pr_debug("[AP] STA removed, link_id: %d\n",
1466 reset.link_id);
1467 }
1468 }
1469 spin_unlock_bh(&priv->ps_state_lock);
1470 if (next_gc != -1)
1471 queue_delayed_work(priv->workqueue,
1472 &priv->link_id_gc_work, next_gc);
1473 wsm_unlock_tx(priv);
1474}
diff --git a/drivers/net/wireless/cw1200/txrx.h b/drivers/net/wireless/cw1200/txrx.h
new file mode 100644
index 000000000000..492a4e14213b
--- /dev/null
+++ b/drivers/net/wireless/cw1200/txrx.h
@@ -0,0 +1,106 @@
1/*
2 * Datapath interface for ST-Ericsson CW1200 mac80211 drivers
3 *
4 * Copyright (c) 2010, ST-Ericsson
5 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#ifndef CW1200_TXRX_H
13#define CW1200_TXRX_H
14
15#include <linux/list.h>
16
17/* extern */ struct ieee80211_hw;
18/* extern */ struct sk_buff;
19/* extern */ struct wsm_tx;
20/* extern */ struct wsm_rx;
21/* extern */ struct wsm_tx_confirm;
22/* extern */ struct cw1200_txpriv;
23
24struct tx_policy {
25 union {
26 __le32 tbl[3];
27 u8 raw[12];
28 };
29 u8 defined;
30 u8 usage_count;
31 u8 retry_count;
32 u8 uploaded;
33};
34
35struct tx_policy_cache_entry {
36 struct tx_policy policy;
37 struct list_head link;
38};
39
40#define TX_POLICY_CACHE_SIZE (8)
41struct tx_policy_cache {
42 struct tx_policy_cache_entry cache[TX_POLICY_CACHE_SIZE];
43 struct list_head used;
44 struct list_head free;
45 spinlock_t lock; /* Protect policy cache */
46};
47
48/* ******************************************************************** */
49/* TX policy cache */
50/* Intention of TX policy cache is an overcomplicated WSM API.
51 * Device does not accept per-PDU tx retry sequence.
52 * It uses "tx retry policy id" instead, so driver code has to sync
53 * linux tx retry sequences with a retry policy table in the device.
54 */
55void tx_policy_init(struct cw1200_common *priv);
56void tx_policy_upload_work(struct work_struct *work);
57void tx_policy_clean(struct cw1200_common *priv);
58
59/* ******************************************************************** */
60/* TX implementation */
61
62u32 cw1200_rate_mask_to_wsm(struct cw1200_common *priv,
63 u32 rates);
64void cw1200_tx(struct ieee80211_hw *dev,
65 struct ieee80211_tx_control *control,
66 struct sk_buff *skb);
67void cw1200_skb_dtor(struct cw1200_common *priv,
68 struct sk_buff *skb,
69 const struct cw1200_txpriv *txpriv);
70
71/* ******************************************************************** */
72/* WSM callbacks */
73
74void cw1200_tx_confirm_cb(struct cw1200_common *priv,
75 int link_id,
76 struct wsm_tx_confirm *arg);
77void cw1200_rx_cb(struct cw1200_common *priv,
78 struct wsm_rx *arg,
79 int link_id,
80 struct sk_buff **skb_p);
81
82/* ******************************************************************** */
83/* Timeout */
84
85void cw1200_tx_timeout(struct work_struct *work);
86
87/* ******************************************************************** */
88/* Security */
89int cw1200_alloc_key(struct cw1200_common *priv);
90void cw1200_free_key(struct cw1200_common *priv, int idx);
91void cw1200_free_keys(struct cw1200_common *priv);
92int cw1200_upload_keys(struct cw1200_common *priv);
93
94/* ******************************************************************** */
95/* Workaround for WFD test case 6.1.10 */
96void cw1200_link_id_reset(struct work_struct *work);
97
98#define CW1200_LINK_ID_GC_TIMEOUT ((unsigned long)(10 * HZ))
99
100int cw1200_find_link_id(struct cw1200_common *priv, const u8 *mac);
101int cw1200_alloc_link_id(struct cw1200_common *priv, const u8 *mac);
102void cw1200_link_id_work(struct work_struct *work);
103void cw1200_link_id_gc_work(struct work_struct *work);
104
105
106#endif /* CW1200_TXRX_H */
diff --git a/drivers/net/wireless/cw1200/wsm.c b/drivers/net/wireless/cw1200/wsm.c
new file mode 100644
index 000000000000..d95094fdcc50
--- /dev/null
+++ b/drivers/net/wireless/cw1200/wsm.c
@@ -0,0 +1,1823 @@
1/*
2 * WSM host interface (HI) implementation for
3 * ST-Ericsson CW1200 mac80211 drivers.
4 *
5 * Copyright (c) 2010, ST-Ericsson
6 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/skbuff.h>
14#include <linux/wait.h>
15#include <linux/delay.h>
16#include <linux/sched.h>
17#include <linux/random.h>
18
19#include "cw1200.h"
20#include "wsm.h"
21#include "bh.h"
22#include "sta.h"
23#include "debug.h"
24
25#define WSM_CMD_TIMEOUT (2 * HZ) /* With respect to interrupt loss */
26#define WSM_CMD_START_TIMEOUT (7 * HZ)
27#define WSM_CMD_RESET_TIMEOUT (3 * HZ) /* 2 sec. timeout was observed. */
28#define WSM_CMD_MAX_TIMEOUT (3 * HZ)
29
30#define WSM_SKIP(buf, size) \
31 do { \
32 if ((buf)->data + size > (buf)->end) \
33 goto underflow; \
34 (buf)->data += size; \
35 } while (0)
36
37#define WSM_GET(buf, ptr, size) \
38 do { \
39 if ((buf)->data + size > (buf)->end) \
40 goto underflow; \
41 memcpy(ptr, (buf)->data, size); \
42 (buf)->data += size; \
43 } while (0)
44
45#define __WSM_GET(buf, type, cvt) \
46 ({ \
47 type val; \
48 if ((buf)->data + sizeof(type) > (buf)->end) \
49 goto underflow; \
50 val = cvt(*(type *)(buf)->data); \
51 (buf)->data += sizeof(type); \
52 val; \
53 })
54
55#define WSM_GET8(buf) __WSM_GET(buf, u8, (u8))
56#define WSM_GET16(buf) __WSM_GET(buf, u16, __le16_to_cpu)
57#define WSM_GET32(buf) __WSM_GET(buf, u32, __le32_to_cpu)
58
59#define WSM_PUT(buf, ptr, size) \
60 do { \
61 if ((buf)->data + size > (buf)->end) \
62 if (wsm_buf_reserve((buf), size)) \
63 goto nomem; \
64 memcpy((buf)->data, ptr, size); \
65 (buf)->data += size; \
66 } while (0)
67
68#define __WSM_PUT(buf, val, type, cvt) \
69 do { \
70 if ((buf)->data + sizeof(type) > (buf)->end) \
71 if (wsm_buf_reserve((buf), sizeof(type))) \
72 goto nomem; \
73 *(type *)(buf)->data = cvt(val); \
74 (buf)->data += sizeof(type); \
75 } while (0)
76
77#define WSM_PUT8(buf, val) __WSM_PUT(buf, val, u8, (u8))
78#define WSM_PUT16(buf, val) __WSM_PUT(buf, val, u16, __cpu_to_le16)
79#define WSM_PUT32(buf, val) __WSM_PUT(buf, val, u32, __cpu_to_le32)
80
81static void wsm_buf_reset(struct wsm_buf *buf);
82static int wsm_buf_reserve(struct wsm_buf *buf, size_t extra_size);
83
84static int wsm_cmd_send(struct cw1200_common *priv,
85 struct wsm_buf *buf,
86 void *arg, u16 cmd, long tmo);
87
88#define wsm_cmd_lock(__priv) mutex_lock(&((__priv)->wsm_cmd_mux))
89#define wsm_cmd_unlock(__priv) mutex_unlock(&((__priv)->wsm_cmd_mux))
90
91/* ******************************************************************** */
92/* WSM API implementation */
93
94static int wsm_generic_confirm(struct cw1200_common *priv,
95 void *arg,
96 struct wsm_buf *buf)
97{
98 u32 status = WSM_GET32(buf);
99 if (status != WSM_STATUS_SUCCESS)
100 return -EINVAL;
101 return 0;
102
103underflow:
104 WARN_ON(1);
105 return -EINVAL;
106}
107
108int wsm_configuration(struct cw1200_common *priv, struct wsm_configuration *arg)
109{
110 int ret;
111 struct wsm_buf *buf = &priv->wsm_cmd_buf;
112
113 wsm_cmd_lock(priv);
114
115 WSM_PUT32(buf, arg->dot11MaxTransmitMsduLifeTime);
116 WSM_PUT32(buf, arg->dot11MaxReceiveLifeTime);
117 WSM_PUT32(buf, arg->dot11RtsThreshold);
118
119 /* DPD block. */
120 WSM_PUT16(buf, arg->dpdData_size + 12);
121 WSM_PUT16(buf, 1); /* DPD version */
122 WSM_PUT(buf, arg->dot11StationId, ETH_ALEN);
123 WSM_PUT16(buf, 5); /* DPD flags */
124 WSM_PUT(buf, arg->dpdData, arg->dpdData_size);
125
126 ret = wsm_cmd_send(priv, buf, arg,
127 WSM_CONFIGURATION_REQ_ID, WSM_CMD_TIMEOUT);
128
129 wsm_cmd_unlock(priv);
130 return ret;
131
132nomem:
133 wsm_cmd_unlock(priv);
134 return -ENOMEM;
135}
136
137static int wsm_configuration_confirm(struct cw1200_common *priv,
138 struct wsm_configuration *arg,
139 struct wsm_buf *buf)
140{
141 int i;
142 int status;
143
144 status = WSM_GET32(buf);
145 if (WARN_ON(status != WSM_STATUS_SUCCESS))
146 return -EINVAL;
147
148 WSM_GET(buf, arg->dot11StationId, ETH_ALEN);
149 arg->dot11FrequencyBandsSupported = WSM_GET8(buf);
150 WSM_SKIP(buf, 1);
151 arg->supportedRateMask = WSM_GET32(buf);
152 for (i = 0; i < 2; ++i) {
153 arg->txPowerRange[i].min_power_level = WSM_GET32(buf);
154 arg->txPowerRange[i].max_power_level = WSM_GET32(buf);
155 arg->txPowerRange[i].stepping = WSM_GET32(buf);
156 }
157 return 0;
158
159underflow:
160 WARN_ON(1);
161 return -EINVAL;
162}
163
164/* ******************************************************************** */
165
166int wsm_reset(struct cw1200_common *priv, const struct wsm_reset *arg)
167{
168 int ret;
169 struct wsm_buf *buf = &priv->wsm_cmd_buf;
170 u16 cmd = WSM_RESET_REQ_ID | WSM_TX_LINK_ID(arg->link_id);
171
172 wsm_cmd_lock(priv);
173
174 WSM_PUT32(buf, arg->reset_statistics ? 0 : 1);
175 ret = wsm_cmd_send(priv, buf, NULL, cmd, WSM_CMD_RESET_TIMEOUT);
176 wsm_cmd_unlock(priv);
177 return ret;
178
179nomem:
180 wsm_cmd_unlock(priv);
181 return -ENOMEM;
182}
183
184/* ******************************************************************** */
185
186struct wsm_mib {
187 u16 mib_id;
188 void *buf;
189 size_t buf_size;
190};
191
192int wsm_read_mib(struct cw1200_common *priv, u16 mib_id, void *_buf,
193 size_t buf_size)
194{
195 int ret;
196 struct wsm_buf *buf = &priv->wsm_cmd_buf;
197 struct wsm_mib mib_buf = {
198 .mib_id = mib_id,
199 .buf = _buf,
200 .buf_size = buf_size,
201 };
202 wsm_cmd_lock(priv);
203
204 WSM_PUT16(buf, mib_id);
205 WSM_PUT16(buf, 0);
206
207 ret = wsm_cmd_send(priv, buf, &mib_buf,
208 WSM_READ_MIB_REQ_ID, WSM_CMD_TIMEOUT);
209 wsm_cmd_unlock(priv);
210 return ret;
211
212nomem:
213 wsm_cmd_unlock(priv);
214 return -ENOMEM;
215}
216
217static int wsm_read_mib_confirm(struct cw1200_common *priv,
218 struct wsm_mib *arg,
219 struct wsm_buf *buf)
220{
221 u16 size;
222 if (WARN_ON(WSM_GET32(buf) != WSM_STATUS_SUCCESS))
223 return -EINVAL;
224
225 if (WARN_ON(WSM_GET16(buf) != arg->mib_id))
226 return -EINVAL;
227
228 size = WSM_GET16(buf);
229 if (size > arg->buf_size)
230 size = arg->buf_size;
231
232 WSM_GET(buf, arg->buf, size);
233 arg->buf_size = size;
234 return 0;
235
236underflow:
237 WARN_ON(1);
238 return -EINVAL;
239}
240
241/* ******************************************************************** */
242
243int wsm_write_mib(struct cw1200_common *priv, u16 mib_id, void *_buf,
244 size_t buf_size)
245{
246 int ret;
247 struct wsm_buf *buf = &priv->wsm_cmd_buf;
248 struct wsm_mib mib_buf = {
249 .mib_id = mib_id,
250 .buf = _buf,
251 .buf_size = buf_size,
252 };
253
254 wsm_cmd_lock(priv);
255
256 WSM_PUT16(buf, mib_id);
257 WSM_PUT16(buf, buf_size);
258 WSM_PUT(buf, _buf, buf_size);
259
260 ret = wsm_cmd_send(priv, buf, &mib_buf,
261 WSM_WRITE_MIB_REQ_ID, WSM_CMD_TIMEOUT);
262 wsm_cmd_unlock(priv);
263 return ret;
264
265nomem:
266 wsm_cmd_unlock(priv);
267 return -ENOMEM;
268}
269
270static int wsm_write_mib_confirm(struct cw1200_common *priv,
271 struct wsm_mib *arg,
272 struct wsm_buf *buf)
273{
274 int ret;
275
276 ret = wsm_generic_confirm(priv, arg, buf);
277 if (ret)
278 return ret;
279
280 if (arg->mib_id == WSM_MIB_ID_OPERATIONAL_POWER_MODE) {
281 /* OperationalMode: update PM status. */
282 const char *p = arg->buf;
283 cw1200_enable_powersave(priv, (p[0] & 0x0F) ? true : false);
284 }
285 return 0;
286}
287
288/* ******************************************************************** */
289
290int wsm_scan(struct cw1200_common *priv, const struct wsm_scan *arg)
291{
292 int i;
293 int ret;
294 struct wsm_buf *buf = &priv->wsm_cmd_buf;
295
296 if (arg->num_channels > 48)
297 return -EINVAL;
298
299 if (arg->num_ssids > 2)
300 return -EINVAL;
301
302 if (arg->band > 1)
303 return -EINVAL;
304
305 wsm_cmd_lock(priv);
306
307 WSM_PUT8(buf, arg->band);
308 WSM_PUT8(buf, arg->type);
309 WSM_PUT8(buf, arg->flags);
310 WSM_PUT8(buf, arg->max_tx_rate);
311 WSM_PUT32(buf, arg->auto_scan_interval);
312 WSM_PUT8(buf, arg->num_probes);
313 WSM_PUT8(buf, arg->num_channels);
314 WSM_PUT8(buf, arg->num_ssids);
315 WSM_PUT8(buf, arg->probe_delay);
316
317 for (i = 0; i < arg->num_channels; ++i) {
318 WSM_PUT16(buf, arg->ch[i].number);
319 WSM_PUT16(buf, 0);
320 WSM_PUT32(buf, arg->ch[i].min_chan_time);
321 WSM_PUT32(buf, arg->ch[i].max_chan_time);
322 WSM_PUT32(buf, 0);
323 }
324
325 for (i = 0; i < arg->num_ssids; ++i) {
326 WSM_PUT32(buf, arg->ssids[i].length);
327 WSM_PUT(buf, &arg->ssids[i].ssid[0],
328 sizeof(arg->ssids[i].ssid));
329 }
330
331 ret = wsm_cmd_send(priv, buf, NULL,
332 WSM_START_SCAN_REQ_ID, WSM_CMD_TIMEOUT);
333 wsm_cmd_unlock(priv);
334 return ret;
335
336nomem:
337 wsm_cmd_unlock(priv);
338 return -ENOMEM;
339}
340
341/* ******************************************************************** */
342
343int wsm_stop_scan(struct cw1200_common *priv)
344{
345 int ret;
346 struct wsm_buf *buf = &priv->wsm_cmd_buf;
347 wsm_cmd_lock(priv);
348 ret = wsm_cmd_send(priv, buf, NULL,
349 WSM_STOP_SCAN_REQ_ID, WSM_CMD_TIMEOUT);
350 wsm_cmd_unlock(priv);
351 return ret;
352}
353
354
355static int wsm_tx_confirm(struct cw1200_common *priv,
356 struct wsm_buf *buf,
357 int link_id)
358{
359 struct wsm_tx_confirm tx_confirm;
360
361 tx_confirm.packet_id = WSM_GET32(buf);
362 tx_confirm.status = WSM_GET32(buf);
363 tx_confirm.tx_rate = WSM_GET8(buf);
364 tx_confirm.ack_failures = WSM_GET8(buf);
365 tx_confirm.flags = WSM_GET16(buf);
366 tx_confirm.media_delay = WSM_GET32(buf);
367 tx_confirm.tx_queue_delay = WSM_GET32(buf);
368
369 cw1200_tx_confirm_cb(priv, link_id, &tx_confirm);
370 return 0;
371
372underflow:
373 WARN_ON(1);
374 return -EINVAL;
375}
376
377static int wsm_multi_tx_confirm(struct cw1200_common *priv,
378 struct wsm_buf *buf, int link_id)
379{
380 int ret;
381 int count;
382 int i;
383
384 count = WSM_GET32(buf);
385 if (WARN_ON(count <= 0))
386 return -EINVAL;
387
388 if (count > 1) {
389 /* We already released one buffer, now for the rest */
390 ret = wsm_release_tx_buffer(priv, count - 1);
391 if (ret < 0)
392 return ret;
393 else if (ret > 0)
394 cw1200_bh_wakeup(priv);
395 }
396
397 cw1200_debug_txed_multi(priv, count);
398 for (i = 0; i < count; ++i) {
399 ret = wsm_tx_confirm(priv, buf, link_id);
400 if (ret)
401 return ret;
402 }
403 return ret;
404
405underflow:
406 WARN_ON(1);
407 return -EINVAL;
408}
409
410/* ******************************************************************** */
411
412static int wsm_join_confirm(struct cw1200_common *priv,
413 struct wsm_join_cnf *arg,
414 struct wsm_buf *buf)
415{
416 arg->status = WSM_GET32(buf);
417 if (WARN_ON(arg->status) != WSM_STATUS_SUCCESS)
418 return -EINVAL;
419
420 arg->min_power_level = WSM_GET32(buf);
421 arg->max_power_level = WSM_GET32(buf);
422
423 return 0;
424
425underflow:
426 WARN_ON(1);
427 return -EINVAL;
428}
429
430int wsm_join(struct cw1200_common *priv, struct wsm_join *arg)
431{
432 int ret;
433 struct wsm_buf *buf = &priv->wsm_cmd_buf;
434 struct wsm_join_cnf resp;
435 wsm_cmd_lock(priv);
436
437 WSM_PUT8(buf, arg->mode);
438 WSM_PUT8(buf, arg->band);
439 WSM_PUT16(buf, arg->channel_number);
440 WSM_PUT(buf, &arg->bssid[0], sizeof(arg->bssid));
441 WSM_PUT16(buf, arg->atim_window);
442 WSM_PUT8(buf, arg->preamble_type);
443 WSM_PUT8(buf, arg->probe_for_join);
444 WSM_PUT8(buf, arg->dtim_period);
445 WSM_PUT8(buf, arg->flags);
446 WSM_PUT32(buf, arg->ssid_len);
447 WSM_PUT(buf, &arg->ssid[0], sizeof(arg->ssid));
448 WSM_PUT32(buf, arg->beacon_interval);
449 WSM_PUT32(buf, arg->basic_rate_set);
450
451 priv->tx_burst_idx = -1;
452 ret = wsm_cmd_send(priv, buf, &resp,
453 WSM_JOIN_REQ_ID, WSM_CMD_TIMEOUT);
454 /* TODO: Update state based on resp.min|max_power_level */
455
456 priv->join_complete_status = resp.status;
457
458 wsm_cmd_unlock(priv);
459 return ret;
460
461nomem:
462 wsm_cmd_unlock(priv);
463 return -ENOMEM;
464}
465
466/* ******************************************************************** */
467
468int wsm_set_bss_params(struct cw1200_common *priv,
469 const struct wsm_set_bss_params *arg)
470{
471 int ret;
472 struct wsm_buf *buf = &priv->wsm_cmd_buf;
473
474 wsm_cmd_lock(priv);
475
476 WSM_PUT8(buf, (arg->reset_beacon_loss ? 0x1 : 0));
477 WSM_PUT8(buf, arg->beacon_lost_count);
478 WSM_PUT16(buf, arg->aid);
479 WSM_PUT32(buf, arg->operational_rate_set);
480
481 ret = wsm_cmd_send(priv, buf, NULL,
482 WSM_SET_BSS_PARAMS_REQ_ID, WSM_CMD_TIMEOUT);
483
484 wsm_cmd_unlock(priv);
485 return ret;
486
487nomem:
488 wsm_cmd_unlock(priv);
489 return -ENOMEM;
490}
491
492/* ******************************************************************** */
493
494int wsm_add_key(struct cw1200_common *priv, const struct wsm_add_key *arg)
495{
496 int ret;
497 struct wsm_buf *buf = &priv->wsm_cmd_buf;
498
499 wsm_cmd_lock(priv);
500
501 WSM_PUT(buf, arg, sizeof(*arg));
502
503 ret = wsm_cmd_send(priv, buf, NULL,
504 WSM_ADD_KEY_REQ_ID, WSM_CMD_TIMEOUT);
505
506 wsm_cmd_unlock(priv);
507 return ret;
508
509nomem:
510 wsm_cmd_unlock(priv);
511 return -ENOMEM;
512}
513
514/* ******************************************************************** */
515
516int wsm_remove_key(struct cw1200_common *priv, const struct wsm_remove_key *arg)
517{
518 int ret;
519 struct wsm_buf *buf = &priv->wsm_cmd_buf;
520
521 wsm_cmd_lock(priv);
522
523 WSM_PUT8(buf, arg->index);
524 WSM_PUT8(buf, 0);
525 WSM_PUT16(buf, 0);
526
527 ret = wsm_cmd_send(priv, buf, NULL,
528 WSM_REMOVE_KEY_REQ_ID, WSM_CMD_TIMEOUT);
529
530 wsm_cmd_unlock(priv);
531 return ret;
532
533nomem:
534 wsm_cmd_unlock(priv);
535 return -ENOMEM;
536}
537
538/* ******************************************************************** */
539
540int wsm_set_tx_queue_params(struct cw1200_common *priv,
541 const struct wsm_set_tx_queue_params *arg, u8 id)
542{
543 int ret;
544 struct wsm_buf *buf = &priv->wsm_cmd_buf;
545 u8 queue_id_to_wmm_aci[] = {3, 2, 0, 1};
546
547 wsm_cmd_lock(priv);
548
549 WSM_PUT8(buf, queue_id_to_wmm_aci[id]);
550 WSM_PUT8(buf, 0);
551 WSM_PUT8(buf, arg->ackPolicy);
552 WSM_PUT8(buf, 0);
553 WSM_PUT32(buf, arg->maxTransmitLifetime);
554 WSM_PUT16(buf, arg->allowedMediumTime);
555 WSM_PUT16(buf, 0);
556
557 ret = wsm_cmd_send(priv, buf, NULL, 0x0012, WSM_CMD_TIMEOUT);
558
559 wsm_cmd_unlock(priv);
560 return ret;
561
562nomem:
563 wsm_cmd_unlock(priv);
564 return -ENOMEM;
565}
566
567/* ******************************************************************** */
568
569int wsm_set_edca_params(struct cw1200_common *priv,
570 const struct wsm_edca_params *arg)
571{
572 int ret;
573 struct wsm_buf *buf = &priv->wsm_cmd_buf;
574
575 wsm_cmd_lock(priv);
576
577 /* Implemented according to specification. */
578
579 WSM_PUT16(buf, arg->params[3].cwmin);
580 WSM_PUT16(buf, arg->params[2].cwmin);
581 WSM_PUT16(buf, arg->params[1].cwmin);
582 WSM_PUT16(buf, arg->params[0].cwmin);
583
584 WSM_PUT16(buf, arg->params[3].cwmax);
585 WSM_PUT16(buf, arg->params[2].cwmax);
586 WSM_PUT16(buf, arg->params[1].cwmax);
587 WSM_PUT16(buf, arg->params[0].cwmax);
588
589 WSM_PUT8(buf, arg->params[3].aifns);
590 WSM_PUT8(buf, arg->params[2].aifns);
591 WSM_PUT8(buf, arg->params[1].aifns);
592 WSM_PUT8(buf, arg->params[0].aifns);
593
594 WSM_PUT16(buf, arg->params[3].txop_limit);
595 WSM_PUT16(buf, arg->params[2].txop_limit);
596 WSM_PUT16(buf, arg->params[1].txop_limit);
597 WSM_PUT16(buf, arg->params[0].txop_limit);
598
599 WSM_PUT32(buf, arg->params[3].max_rx_lifetime);
600 WSM_PUT32(buf, arg->params[2].max_rx_lifetime);
601 WSM_PUT32(buf, arg->params[1].max_rx_lifetime);
602 WSM_PUT32(buf, arg->params[0].max_rx_lifetime);
603
604 ret = wsm_cmd_send(priv, buf, NULL,
605 WSM_EDCA_PARAMS_REQ_ID, WSM_CMD_TIMEOUT);
606 wsm_cmd_unlock(priv);
607 return ret;
608
609nomem:
610 wsm_cmd_unlock(priv);
611 return -ENOMEM;
612}
613
614/* ******************************************************************** */
615
616int wsm_switch_channel(struct cw1200_common *priv,
617 const struct wsm_switch_channel *arg)
618{
619 int ret;
620 struct wsm_buf *buf = &priv->wsm_cmd_buf;
621
622 wsm_cmd_lock(priv);
623
624 WSM_PUT8(buf, arg->mode);
625 WSM_PUT8(buf, arg->switch_count);
626 WSM_PUT16(buf, arg->channel_number);
627
628 priv->channel_switch_in_progress = 1;
629
630 ret = wsm_cmd_send(priv, buf, NULL,
631 WSM_SWITCH_CHANNEL_REQ_ID, WSM_CMD_TIMEOUT);
632 if (ret)
633 priv->channel_switch_in_progress = 0;
634
635 wsm_cmd_unlock(priv);
636 return ret;
637
638nomem:
639 wsm_cmd_unlock(priv);
640 return -ENOMEM;
641}
642
643/* ******************************************************************** */
644
645int wsm_set_pm(struct cw1200_common *priv, const struct wsm_set_pm *arg)
646{
647 int ret;
648 struct wsm_buf *buf = &priv->wsm_cmd_buf;
649 priv->ps_mode_switch_in_progress = 1;
650
651 wsm_cmd_lock(priv);
652
653 WSM_PUT8(buf, arg->mode);
654 WSM_PUT8(buf, arg->fast_psm_idle_period);
655 WSM_PUT8(buf, arg->ap_psm_change_period);
656 WSM_PUT8(buf, arg->min_auto_pspoll_period);
657
658 ret = wsm_cmd_send(priv, buf, NULL,
659 WSM_SET_PM_REQ_ID, WSM_CMD_TIMEOUT);
660
661 wsm_cmd_unlock(priv);
662 return ret;
663
664nomem:
665 wsm_cmd_unlock(priv);
666 return -ENOMEM;
667}
668
669/* ******************************************************************** */
670
671int wsm_start(struct cw1200_common *priv, const struct wsm_start *arg)
672{
673 int ret;
674 struct wsm_buf *buf = &priv->wsm_cmd_buf;
675
676 wsm_cmd_lock(priv);
677
678 WSM_PUT8(buf, arg->mode);
679 WSM_PUT8(buf, arg->band);
680 WSM_PUT16(buf, arg->channel_number);
681 WSM_PUT32(buf, arg->ct_window);
682 WSM_PUT32(buf, arg->beacon_interval);
683 WSM_PUT8(buf, arg->dtim_period);
684 WSM_PUT8(buf, arg->preamble);
685 WSM_PUT8(buf, arg->probe_delay);
686 WSM_PUT8(buf, arg->ssid_len);
687 WSM_PUT(buf, arg->ssid, sizeof(arg->ssid));
688 WSM_PUT32(buf, arg->basic_rate_set);
689
690 priv->tx_burst_idx = -1;
691 ret = wsm_cmd_send(priv, buf, NULL,
692 WSM_START_REQ_ID, WSM_CMD_START_TIMEOUT);
693
694 wsm_cmd_unlock(priv);
695 return ret;
696
697nomem:
698 wsm_cmd_unlock(priv);
699 return -ENOMEM;
700}
701
702/* ******************************************************************** */
703
704int wsm_beacon_transmit(struct cw1200_common *priv,
705 const struct wsm_beacon_transmit *arg)
706{
707 int ret;
708 struct wsm_buf *buf = &priv->wsm_cmd_buf;
709
710 wsm_cmd_lock(priv);
711
712 WSM_PUT32(buf, arg->enable_beaconing ? 1 : 0);
713
714 ret = wsm_cmd_send(priv, buf, NULL,
715 WSM_BEACON_TRANSMIT_REQ_ID, WSM_CMD_TIMEOUT);
716
717 wsm_cmd_unlock(priv);
718 return ret;
719
720nomem:
721 wsm_cmd_unlock(priv);
722 return -ENOMEM;
723}
724
725/* ******************************************************************** */
726
727int wsm_start_find(struct cw1200_common *priv)
728{
729 int ret;
730 struct wsm_buf *buf = &priv->wsm_cmd_buf;
731
732 wsm_cmd_lock(priv);
733 ret = wsm_cmd_send(priv, buf, NULL, 0x0019, WSM_CMD_TIMEOUT);
734 wsm_cmd_unlock(priv);
735 return ret;
736}
737
738/* ******************************************************************** */
739
740int wsm_stop_find(struct cw1200_common *priv)
741{
742 int ret;
743 struct wsm_buf *buf = &priv->wsm_cmd_buf;
744
745 wsm_cmd_lock(priv);
746 ret = wsm_cmd_send(priv, buf, NULL, 0x001A, WSM_CMD_TIMEOUT);
747 wsm_cmd_unlock(priv);
748 return ret;
749}
750
751/* ******************************************************************** */
752
753int wsm_map_link(struct cw1200_common *priv, const struct wsm_map_link *arg)
754{
755 int ret;
756 struct wsm_buf *buf = &priv->wsm_cmd_buf;
757 u16 cmd = 0x001C | WSM_TX_LINK_ID(arg->link_id);
758
759 wsm_cmd_lock(priv);
760
761 WSM_PUT(buf, &arg->mac_addr[0], sizeof(arg->mac_addr));
762 WSM_PUT16(buf, 0);
763
764 ret = wsm_cmd_send(priv, buf, NULL, cmd, WSM_CMD_TIMEOUT);
765
766 wsm_cmd_unlock(priv);
767 return ret;
768
769nomem:
770 wsm_cmd_unlock(priv);
771 return -ENOMEM;
772}
773
774/* ******************************************************************** */
775
776int wsm_update_ie(struct cw1200_common *priv,
777 const struct wsm_update_ie *arg)
778{
779 int ret;
780 struct wsm_buf *buf = &priv->wsm_cmd_buf;
781
782 wsm_cmd_lock(priv);
783
784 WSM_PUT16(buf, arg->what);
785 WSM_PUT16(buf, arg->count);
786 WSM_PUT(buf, arg->ies, arg->length);
787
788 ret = wsm_cmd_send(priv, buf, NULL, 0x001B, WSM_CMD_TIMEOUT);
789
790 wsm_cmd_unlock(priv);
791 return ret;
792
793nomem:
794 wsm_cmd_unlock(priv);
795 return -ENOMEM;
796}
797
798/* ******************************************************************** */
799int wsm_set_probe_responder(struct cw1200_common *priv, bool enable)
800{
801 priv->rx_filter.probeResponder = enable;
802 return wsm_set_rx_filter(priv, &priv->rx_filter);
803}
804
805/* ******************************************************************** */
806/* WSM indication events implementation */
807const char * const cw1200_fw_types[] = {
808 "ETF",
809 "WFM",
810 "WSM",
811 "HI test",
812 "Platform test"
813};
814
815static int wsm_startup_indication(struct cw1200_common *priv,
816 struct wsm_buf *buf)
817{
818 priv->wsm_caps.input_buffers = WSM_GET16(buf);
819 priv->wsm_caps.input_buffer_size = WSM_GET16(buf);
820 priv->wsm_caps.hw_id = WSM_GET16(buf);
821 priv->wsm_caps.hw_subid = WSM_GET16(buf);
822 priv->wsm_caps.status = WSM_GET16(buf);
823 priv->wsm_caps.fw_cap = WSM_GET16(buf);
824 priv->wsm_caps.fw_type = WSM_GET16(buf);
825 priv->wsm_caps.fw_api = WSM_GET16(buf);
826 priv->wsm_caps.fw_build = WSM_GET16(buf);
827 priv->wsm_caps.fw_ver = WSM_GET16(buf);
828 WSM_GET(buf, priv->wsm_caps.fw_label, sizeof(priv->wsm_caps.fw_label));
829 priv->wsm_caps.fw_label[sizeof(priv->wsm_caps.fw_label) - 1] = 0; /* Do not trust FW too much... */
830
831 if (WARN_ON(priv->wsm_caps.status))
832 return -EINVAL;
833
834 if (WARN_ON(priv->wsm_caps.fw_type > 4))
835 return -EINVAL;
836
837 pr_info("CW1200 WSM init done.\n"
838 " Input buffers: %d x %d bytes\n"
839 " Hardware: %d.%d\n"
840 " %s firmware [%s], ver: %d, build: %d,"
841 " api: %d, cap: 0x%.4X\n",
842 priv->wsm_caps.input_buffers,
843 priv->wsm_caps.input_buffer_size,
844 priv->wsm_caps.hw_id, priv->wsm_caps.hw_subid,
845 cw1200_fw_types[priv->wsm_caps.fw_type],
846 priv->wsm_caps.fw_label, priv->wsm_caps.fw_ver,
847 priv->wsm_caps.fw_build,
848 priv->wsm_caps.fw_api, priv->wsm_caps.fw_cap);
849
850 /* Disable unsupported frequency bands */
851 if (!(priv->wsm_caps.fw_cap & 0x1))
852 priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = NULL;
853 if (!(priv->wsm_caps.fw_cap & 0x2))
854 priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = NULL;
855
856 priv->firmware_ready = 1;
857 wake_up(&priv->wsm_startup_done);
858 return 0;
859
860underflow:
861 WARN_ON(1);
862 return -EINVAL;
863}
864
865static int wsm_receive_indication(struct cw1200_common *priv,
866 int link_id,
867 struct wsm_buf *buf,
868 struct sk_buff **skb_p)
869{
870 struct wsm_rx rx;
871 struct ieee80211_hdr *hdr;
872 size_t hdr_len;
873 __le16 fctl;
874
875 rx.status = WSM_GET32(buf);
876 rx.channel_number = WSM_GET16(buf);
877 rx.rx_rate = WSM_GET8(buf);
878 rx.rcpi_rssi = WSM_GET8(buf);
879 rx.flags = WSM_GET32(buf);
880
881 /* FW Workaround: Drop probe resp or
882 beacon when RSSI is 0
883 */
884 hdr = (struct ieee80211_hdr *)(*skb_p)->data;
885
886 if (!rx.rcpi_rssi &&
887 (ieee80211_is_probe_resp(hdr->frame_control) ||
888 ieee80211_is_beacon(hdr->frame_control)))
889 return 0;
890
891 /* If no RSSI subscription has been made,
892 * convert RCPI to RSSI here
893 */
894 if (!priv->cqm_use_rssi)
895 rx.rcpi_rssi = rx.rcpi_rssi / 2 - 110;
896
897 fctl = *(__le16 *)buf->data;
898 hdr_len = buf->data - buf->begin;
899 skb_pull(*skb_p, hdr_len);
900 if (!rx.status && ieee80211_is_deauth(fctl)) {
901 if (priv->join_status == CW1200_JOIN_STATUS_STA) {
902 /* Shedule unjoin work */
903 pr_debug("[WSM] Issue unjoin command (RX).\n");
904 wsm_lock_tx_async(priv);
905 if (queue_work(priv->workqueue,
906 &priv->unjoin_work) <= 0)
907 wsm_unlock_tx(priv);
908 }
909 }
910 cw1200_rx_cb(priv, &rx, link_id, skb_p);
911 if (*skb_p)
912 skb_push(*skb_p, hdr_len);
913
914 return 0;
915
916underflow:
917 return -EINVAL;
918}
919
920static int wsm_event_indication(struct cw1200_common *priv, struct wsm_buf *buf)
921{
922 int first;
923 struct cw1200_wsm_event *event;
924
925 if (priv->mode == NL80211_IFTYPE_UNSPECIFIED) {
926 /* STA is stopped. */
927 return 0;
928 }
929
930 event = kzalloc(sizeof(struct cw1200_wsm_event), GFP_KERNEL);
931 if (!event)
932 return -ENOMEM;
933
934 event->evt.id = __le32_to_cpu(WSM_GET32(buf));
935 event->evt.data = __le32_to_cpu(WSM_GET32(buf));
936
937 pr_debug("[WSM] Event: %d(%d)\n",
938 event->evt.id, event->evt.data);
939
940 spin_lock(&priv->event_queue_lock);
941 first = list_empty(&priv->event_queue);
942 list_add_tail(&event->link, &priv->event_queue);
943 spin_unlock(&priv->event_queue_lock);
944
945 if (first)
946 queue_work(priv->workqueue, &priv->event_handler);
947
948 return 0;
949
950underflow:
951 kfree(event);
952 return -EINVAL;
953}
954
955static int wsm_channel_switch_indication(struct cw1200_common *priv,
956 struct wsm_buf *buf)
957{
958 WARN_ON(WSM_GET32(buf));
959
960 priv->channel_switch_in_progress = 0;
961 wake_up(&priv->channel_switch_done);
962
963 wsm_unlock_tx(priv);
964
965 return 0;
966
967underflow:
968 return -EINVAL;
969}
970
971static int wsm_set_pm_indication(struct cw1200_common *priv,
972 struct wsm_buf *buf)
973{
974 /* TODO: Check buf (struct wsm_set_pm_complete) for validity */
975 if (priv->ps_mode_switch_in_progress) {
976 priv->ps_mode_switch_in_progress = 0;
977 wake_up(&priv->ps_mode_switch_done);
978 }
979 return 0;
980}
981
982static int wsm_scan_started(struct cw1200_common *priv, void *arg,
983 struct wsm_buf *buf)
984{
985 u32 status = WSM_GET32(buf);
986 if (status != WSM_STATUS_SUCCESS) {
987 cw1200_scan_failed_cb(priv);
988 return -EINVAL;
989 }
990 return 0;
991
992underflow:
993 WARN_ON(1);
994 return -EINVAL;
995}
996
997static int wsm_scan_complete_indication(struct cw1200_common *priv,
998 struct wsm_buf *buf)
999{
1000 struct wsm_scan_complete arg;
1001 arg.status = WSM_GET32(buf);
1002 arg.psm = WSM_GET8(buf);
1003 arg.num_channels = WSM_GET8(buf);
1004 cw1200_scan_complete_cb(priv, &arg);
1005
1006 return 0;
1007
1008underflow:
1009 return -EINVAL;
1010}
1011
1012static int wsm_join_complete_indication(struct cw1200_common *priv,
1013 struct wsm_buf *buf)
1014{
1015 struct wsm_join_complete arg;
1016 arg.status = WSM_GET32(buf);
1017 pr_debug("[WSM] Join complete indication, status: %d\n", arg.status);
1018 cw1200_join_complete_cb(priv, &arg);
1019
1020 return 0;
1021
1022underflow:
1023 return -EINVAL;
1024}
1025
1026static int wsm_find_complete_indication(struct cw1200_common *priv,
1027 struct wsm_buf *buf)
1028{
1029 pr_warn("Implement find_complete_indication\n");
1030 return 0;
1031}
1032
1033static int wsm_ba_timeout_indication(struct cw1200_common *priv,
1034 struct wsm_buf *buf)
1035{
1036 u32 dummy;
1037 u8 tid;
1038 u8 dummy2;
1039 u8 addr[ETH_ALEN];
1040
1041 dummy = WSM_GET32(buf);
1042 tid = WSM_GET8(buf);
1043 dummy2 = WSM_GET8(buf);
1044 WSM_GET(buf, addr, ETH_ALEN);
1045
1046 pr_info("BlockACK timeout, tid %d, addr %pM\n",
1047 tid, addr);
1048
1049 return 0;
1050
1051underflow:
1052 return -EINVAL;
1053}
1054
1055static int wsm_suspend_resume_indication(struct cw1200_common *priv,
1056 int link_id, struct wsm_buf *buf)
1057{
1058 u32 flags;
1059 struct wsm_suspend_resume arg;
1060
1061 flags = WSM_GET32(buf);
1062 arg.link_id = link_id;
1063 arg.stop = !(flags & 1);
1064 arg.multicast = !!(flags & 8);
1065 arg.queue = (flags >> 1) & 3;
1066
1067 cw1200_suspend_resume(priv, &arg);
1068
1069 return 0;
1070
1071underflow:
1072 return -EINVAL;
1073}
1074
1075
1076/* ******************************************************************** */
1077/* WSM TX */
1078
1079static int wsm_cmd_send(struct cw1200_common *priv,
1080 struct wsm_buf *buf,
1081 void *arg, u16 cmd, long tmo)
1082{
1083 size_t buf_len = buf->data - buf->begin;
1084 int ret;
1085
1086 /* Don't bother if we're dead. */
1087 if (priv->bh_error) {
1088 ret = 0;
1089 goto done;
1090 }
1091
1092 /* Block until the cmd buffer is completed. Tortuous. */
1093 spin_lock(&priv->wsm_cmd.lock);
1094 while (!priv->wsm_cmd.done) {
1095 spin_unlock(&priv->wsm_cmd.lock);
1096 spin_lock(&priv->wsm_cmd.lock);
1097 }
1098 priv->wsm_cmd.done = 0;
1099 spin_unlock(&priv->wsm_cmd.lock);
1100
1101 if (cmd == WSM_WRITE_MIB_REQ_ID ||
1102 cmd == WSM_READ_MIB_REQ_ID)
1103 pr_debug("[WSM] >>> 0x%.4X [MIB: 0x%.4X] (%zu)\n",
1104 cmd, __le16_to_cpu(((__le16 *)buf->begin)[2]),
1105 buf_len);
1106 else
1107 pr_debug("[WSM] >>> 0x%.4X (%zu)\n", cmd, buf_len);
1108
1109 /* Due to buggy SPI on CW1200, we need to
1110 * pad the message by a few bytes to ensure
1111 * that it's completely received.
1112 */
1113 buf_len += 4;
1114
1115 /* Fill HI message header */
1116 /* BH will add sequence number */
1117 ((__le16 *)buf->begin)[0] = __cpu_to_le16(buf_len);
1118 ((__le16 *)buf->begin)[1] = __cpu_to_le16(cmd);
1119
1120 spin_lock(&priv->wsm_cmd.lock);
1121 BUG_ON(priv->wsm_cmd.ptr);
1122 priv->wsm_cmd.ptr = buf->begin;
1123 priv->wsm_cmd.len = buf_len;
1124 priv->wsm_cmd.arg = arg;
1125 priv->wsm_cmd.cmd = cmd;
1126 spin_unlock(&priv->wsm_cmd.lock);
1127
1128 cw1200_bh_wakeup(priv);
1129
1130 /* Wait for command completion */
1131 ret = wait_event_timeout(priv->wsm_cmd_wq,
1132 priv->wsm_cmd.done, tmo);
1133
1134 if (!ret && !priv->wsm_cmd.done) {
1135 spin_lock(&priv->wsm_cmd.lock);
1136 priv->wsm_cmd.done = 1;
1137 priv->wsm_cmd.ptr = NULL;
1138 spin_unlock(&priv->wsm_cmd.lock);
1139 if (priv->bh_error) {
1140 /* Return ok to help system cleanup */
1141 ret = 0;
1142 } else {
1143 pr_err("CMD req (0x%04x) stuck in firmware, killing BH\n", priv->wsm_cmd.cmd);
1144 print_hex_dump_bytes("REQDUMP: ", DUMP_PREFIX_NONE,
1145 buf->begin, buf_len);
1146 pr_err("Outstanding outgoing frames: %d\n", priv->hw_bufs_used);
1147
1148 /* Kill BH thread to report the error to the top layer. */
1149 atomic_add(1, &priv->bh_term);
1150 wake_up(&priv->bh_wq);
1151 ret = -ETIMEDOUT;
1152 }
1153 } else {
1154 spin_lock(&priv->wsm_cmd.lock);
1155 BUG_ON(!priv->wsm_cmd.done);
1156 ret = priv->wsm_cmd.ret;
1157 spin_unlock(&priv->wsm_cmd.lock);
1158 }
1159done:
1160 wsm_buf_reset(buf);
1161 return ret;
1162}
1163
1164/* ******************************************************************** */
1165/* WSM TX port control */
1166
1167void wsm_lock_tx(struct cw1200_common *priv)
1168{
1169 wsm_cmd_lock(priv);
1170 if (atomic_add_return(1, &priv->tx_lock) == 1) {
1171 if (wsm_flush_tx(priv))
1172 pr_debug("[WSM] TX is locked.\n");
1173 }
1174 wsm_cmd_unlock(priv);
1175}
1176
1177void wsm_lock_tx_async(struct cw1200_common *priv)
1178{
1179 if (atomic_add_return(1, &priv->tx_lock) == 1)
1180 pr_debug("[WSM] TX is locked (async).\n");
1181}
1182
1183bool wsm_flush_tx(struct cw1200_common *priv)
1184{
1185 unsigned long timestamp = jiffies;
1186 bool pending = false;
1187 long timeout;
1188 int i;
1189
1190 /* Flush must be called with TX lock held. */
1191 BUG_ON(!atomic_read(&priv->tx_lock));
1192
1193 /* First check if we really need to do something.
1194 * It is safe to use unprotected access, as hw_bufs_used
1195 * can only decrements.
1196 */
1197 if (!priv->hw_bufs_used)
1198 return true;
1199
1200 if (priv->bh_error) {
1201 /* In case of failure do not wait for magic. */
1202 pr_err("[WSM] Fatal error occured, will not flush TX.\n");
1203 return false;
1204 } else {
1205 /* Get a timestamp of "oldest" frame */
1206 for (i = 0; i < 4; ++i)
1207 pending |= cw1200_queue_get_xmit_timestamp(
1208 &priv->tx_queue[i],
1209 &timestamp, 0xffffffff);
1210 /* If there's nothing pending, we're good */
1211 if (!pending)
1212 return true;
1213
1214 timeout = timestamp + WSM_CMD_LAST_CHANCE_TIMEOUT - jiffies;
1215 if (timeout < 0 || wait_event_timeout(priv->bh_evt_wq,
1216 !priv->hw_bufs_used,
1217 timeout) <= 0) {
1218 /* Hmmm... Not good. Frame had stuck in firmware. */
1219 priv->bh_error = 1;
1220 wiphy_err(priv->hw->wiphy, "[WSM] TX Frames (%d) stuck in firmware, killing BH\n", priv->hw_bufs_used);
1221 wake_up(&priv->bh_wq);
1222 return false;
1223 }
1224
1225 /* Ok, everything is flushed. */
1226 return true;
1227 }
1228}
1229
1230void wsm_unlock_tx(struct cw1200_common *priv)
1231{
1232 int tx_lock;
1233 tx_lock = atomic_sub_return(1, &priv->tx_lock);
1234 BUG_ON(tx_lock < 0);
1235
1236 if (tx_lock == 0) {
1237 if (!priv->bh_error)
1238 cw1200_bh_wakeup(priv);
1239 pr_debug("[WSM] TX is unlocked.\n");
1240 }
1241}
1242
1243/* ******************************************************************** */
1244/* WSM RX */
1245
1246int wsm_handle_exception(struct cw1200_common *priv, u8 *data, size_t len)
1247{
1248 struct wsm_buf buf;
1249 u32 reason;
1250 u32 reg[18];
1251 char fname[48];
1252 unsigned int i;
1253
1254 static const char * const reason_str[] = {
1255 "undefined instruction",
1256 "prefetch abort",
1257 "data abort",
1258 "unknown error",
1259 };
1260
1261 buf.begin = buf.data = data;
1262 buf.end = &buf.begin[len];
1263
1264 reason = WSM_GET32(&buf);
1265 for (i = 0; i < ARRAY_SIZE(reg); ++i)
1266 reg[i] = WSM_GET32(&buf);
1267 WSM_GET(&buf, fname, sizeof(fname));
1268
1269 if (reason < 4)
1270 wiphy_err(priv->hw->wiphy,
1271 "Firmware exception: %s.\n",
1272 reason_str[reason]);
1273 else
1274 wiphy_err(priv->hw->wiphy,
1275 "Firmware assert at %.*s, line %d\n",
1276 (int) sizeof(fname), fname, reg[1]);
1277
1278 for (i = 0; i < 12; i += 4)
1279 wiphy_err(priv->hw->wiphy,
1280 "R%d: 0x%.8X, R%d: 0x%.8X, R%d: 0x%.8X, R%d: 0x%.8X,\n",
1281 i + 0, reg[i + 0], i + 1, reg[i + 1],
1282 i + 2, reg[i + 2], i + 3, reg[i + 3]);
1283 wiphy_err(priv->hw->wiphy,
1284 "R12: 0x%.8X, SP: 0x%.8X, LR: 0x%.8X, PC: 0x%.8X,\n",
1285 reg[i + 0], reg[i + 1], reg[i + 2], reg[i + 3]);
1286 i += 4;
1287 wiphy_err(priv->hw->wiphy,
1288 "CPSR: 0x%.8X, SPSR: 0x%.8X\n",
1289 reg[i + 0], reg[i + 1]);
1290
1291 print_hex_dump_bytes("R1: ", DUMP_PREFIX_NONE,
1292 fname, sizeof(fname));
1293 return 0;
1294
1295underflow:
1296 wiphy_err(priv->hw->wiphy, "Firmware exception.\n");
1297 print_hex_dump_bytes("Exception: ", DUMP_PREFIX_NONE,
1298 data, len);
1299 return -EINVAL;
1300}
1301
1302int wsm_handle_rx(struct cw1200_common *priv, u16 id,
1303 struct wsm_hdr *wsm, struct sk_buff **skb_p)
1304{
1305 int ret = 0;
1306 struct wsm_buf wsm_buf;
1307 int link_id = (id >> 6) & 0x0F;
1308
1309 /* Strip link id. */
1310 id &= ~WSM_TX_LINK_ID(WSM_TX_LINK_ID_MAX);
1311
1312 wsm_buf.begin = (u8 *)&wsm[0];
1313 wsm_buf.data = (u8 *)&wsm[1];
1314 wsm_buf.end = &wsm_buf.begin[__le32_to_cpu(wsm->len)];
1315
1316 pr_debug("[WSM] <<< 0x%.4X (%td)\n", id,
1317 wsm_buf.end - wsm_buf.begin);
1318
1319 if (id == WSM_TX_CONFIRM_IND_ID) {
1320 ret = wsm_tx_confirm(priv, &wsm_buf, link_id);
1321 } else if (id == WSM_MULTI_TX_CONFIRM_ID) {
1322 ret = wsm_multi_tx_confirm(priv, &wsm_buf, link_id);
1323 } else if (id & 0x0400) {
1324 void *wsm_arg;
1325 u16 wsm_cmd;
1326
1327 /* Do not trust FW too much. Protection against repeated
1328 * response and race condition removal (see above).
1329 */
1330 spin_lock(&priv->wsm_cmd.lock);
1331 wsm_arg = priv->wsm_cmd.arg;
1332 wsm_cmd = priv->wsm_cmd.cmd &
1333 ~WSM_TX_LINK_ID(WSM_TX_LINK_ID_MAX);
1334 priv->wsm_cmd.cmd = 0xFFFF;
1335 spin_unlock(&priv->wsm_cmd.lock);
1336
1337 if (WARN_ON((id & ~0x0400) != wsm_cmd)) {
1338 /* Note that any non-zero is a fatal retcode. */
1339 ret = -EINVAL;
1340 goto out;
1341 }
1342
1343 /* Note that wsm_arg can be NULL in case of timeout in
1344 * wsm_cmd_send().
1345 */
1346
1347 switch (id) {
1348 case WSM_READ_MIB_RESP_ID:
1349 if (wsm_arg)
1350 ret = wsm_read_mib_confirm(priv, wsm_arg,
1351 &wsm_buf);
1352 break;
1353 case WSM_WRITE_MIB_RESP_ID:
1354 if (wsm_arg)
1355 ret = wsm_write_mib_confirm(priv, wsm_arg,
1356 &wsm_buf);
1357 break;
1358 case WSM_START_SCAN_RESP_ID:
1359 if (wsm_arg)
1360 ret = wsm_scan_started(priv, wsm_arg, &wsm_buf);
1361 break;
1362 case WSM_CONFIGURATION_RESP_ID:
1363 if (wsm_arg)
1364 ret = wsm_configuration_confirm(priv, wsm_arg,
1365 &wsm_buf);
1366 break;
1367 case WSM_JOIN_RESP_ID:
1368 if (wsm_arg)
1369 ret = wsm_join_confirm(priv, wsm_arg, &wsm_buf);
1370 break;
1371 case WSM_STOP_SCAN_RESP_ID:
1372 case WSM_RESET_RESP_ID:
1373 case WSM_ADD_KEY_RESP_ID:
1374 case WSM_REMOVE_KEY_RESP_ID:
1375 case WSM_SET_PM_RESP_ID:
1376 case WSM_SET_BSS_PARAMS_RESP_ID:
1377 case 0x0412: /* set_tx_queue_params */
1378 case WSM_EDCA_PARAMS_RESP_ID:
1379 case WSM_SWITCH_CHANNEL_RESP_ID:
1380 case WSM_START_RESP_ID:
1381 case WSM_BEACON_TRANSMIT_RESP_ID:
1382 case 0x0419: /* start_find */
1383 case 0x041A: /* stop_find */
1384 case 0x041B: /* update_ie */
1385 case 0x041C: /* map_link */
1386 WARN_ON(wsm_arg != NULL);
1387 ret = wsm_generic_confirm(priv, wsm_arg, &wsm_buf);
1388 if (ret) {
1389 wiphy_warn(priv->hw->wiphy,
1390 "wsm_generic_confirm failed for request 0x%04x.\n",
1391 id & ~0x0400);
1392
1393 /* often 0x407 and 0x410 occur, this means we're dead.. */
1394 if (priv->join_status >= CW1200_JOIN_STATUS_JOINING) {
1395 wsm_lock_tx(priv);
1396 if (queue_work(priv->workqueue, &priv->unjoin_work) <= 0)
1397 wsm_unlock_tx(priv);
1398 }
1399 }
1400 break;
1401 default:
1402 wiphy_warn(priv->hw->wiphy,
1403 "Unrecognized confirmation 0x%04x\n",
1404 id & ~0x0400);
1405 }
1406
1407 spin_lock(&priv->wsm_cmd.lock);
1408 priv->wsm_cmd.ret = ret;
1409 priv->wsm_cmd.done = 1;
1410 spin_unlock(&priv->wsm_cmd.lock);
1411
1412 ret = 0; /* Error response from device should ne stop BH. */
1413
1414 wake_up(&priv->wsm_cmd_wq);
1415 } else if (id & 0x0800) {
1416 switch (id) {
1417 case WSM_STARTUP_IND_ID:
1418 ret = wsm_startup_indication(priv, &wsm_buf);
1419 break;
1420 case WSM_RECEIVE_IND_ID:
1421 ret = wsm_receive_indication(priv, link_id,
1422 &wsm_buf, skb_p);
1423 break;
1424 case 0x0805:
1425 ret = wsm_event_indication(priv, &wsm_buf);
1426 break;
1427 case WSM_SCAN_COMPLETE_IND_ID:
1428 ret = wsm_scan_complete_indication(priv, &wsm_buf);
1429 break;
1430 case 0x0808:
1431 ret = wsm_ba_timeout_indication(priv, &wsm_buf);
1432 break;
1433 case 0x0809:
1434 ret = wsm_set_pm_indication(priv, &wsm_buf);
1435 break;
1436 case 0x080A:
1437 ret = wsm_channel_switch_indication(priv, &wsm_buf);
1438 break;
1439 case 0x080B:
1440 ret = wsm_find_complete_indication(priv, &wsm_buf);
1441 break;
1442 case 0x080C:
1443 ret = wsm_suspend_resume_indication(priv,
1444 link_id, &wsm_buf);
1445 break;
1446 case 0x080F:
1447 ret = wsm_join_complete_indication(priv, &wsm_buf);
1448 break;
1449 default:
1450 pr_warn("Unrecognised WSM ID %04x\n", id);
1451 }
1452 } else {
1453 WARN_ON(1);
1454 ret = -EINVAL;
1455 }
1456out:
1457 return ret;
1458}
1459
1460static bool wsm_handle_tx_data(struct cw1200_common *priv,
1461 struct wsm_tx *wsm,
1462 const struct ieee80211_tx_info *tx_info,
1463 const struct cw1200_txpriv *txpriv,
1464 struct cw1200_queue *queue)
1465{
1466 bool handled = false;
1467 const struct ieee80211_hdr *frame =
1468 (struct ieee80211_hdr *)&((u8 *)wsm)[txpriv->offset];
1469 __le16 fctl = frame->frame_control;
1470 enum {
1471 do_probe,
1472 do_drop,
1473 do_wep,
1474 do_tx,
1475 } action = do_tx;
1476
1477 switch (priv->mode) {
1478 case NL80211_IFTYPE_STATION:
1479 if (priv->join_status == CW1200_JOIN_STATUS_MONITOR)
1480 action = do_tx;
1481 else if (priv->join_status < CW1200_JOIN_STATUS_PRE_STA)
1482 action = do_drop;
1483 break;
1484 case NL80211_IFTYPE_AP:
1485 if (!priv->join_status) {
1486 action = do_drop;
1487 } else if (!(BIT(txpriv->raw_link_id) &
1488 (BIT(0) | priv->link_id_map))) {
1489 wiphy_warn(priv->hw->wiphy,
1490 "A frame with expired link id is dropped.\n");
1491 action = do_drop;
1492 }
1493 if (cw1200_queue_get_generation(wsm->packet_id) >
1494 CW1200_MAX_REQUEUE_ATTEMPTS) {
1495 /* HACK!!! WSM324 firmware has tendency to requeue
1496 * multicast frames in a loop, causing performance
1497 * drop and high power consumption of the driver.
1498 * In this situation it is better just to drop
1499 * the problematic frame.
1500 */
1501 wiphy_warn(priv->hw->wiphy,
1502 "Too many attempts to requeue a frame; dropped.\n");
1503 action = do_drop;
1504 }
1505 break;
1506 case NL80211_IFTYPE_ADHOC:
1507 if (priv->join_status != CW1200_JOIN_STATUS_IBSS)
1508 action = do_drop;
1509 break;
1510 case NL80211_IFTYPE_MESH_POINT:
1511 action = do_tx; /* TODO: Test me! */
1512 break;
1513 case NL80211_IFTYPE_MONITOR:
1514 default:
1515 action = do_drop;
1516 break;
1517 }
1518
1519 if (action == do_tx) {
1520 if (ieee80211_is_nullfunc(fctl)) {
1521 spin_lock(&priv->bss_loss_lock);
1522 if (priv->bss_loss_state) {
1523 priv->bss_loss_confirm_id = wsm->packet_id;
1524 wsm->queue_id = WSM_QUEUE_VOICE;
1525 }
1526 spin_unlock(&priv->bss_loss_lock);
1527 } else if (ieee80211_is_probe_req(fctl)) {
1528 action = do_probe;
1529 } else if (ieee80211_is_deauth(fctl) &&
1530 priv->mode != NL80211_IFTYPE_AP) {
1531 pr_debug("[WSM] Issue unjoin command due to tx deauth.\n");
1532 wsm_lock_tx_async(priv);
1533 if (queue_work(priv->workqueue,
1534 &priv->unjoin_work) <= 0)
1535 wsm_unlock_tx(priv);
1536 } else if (ieee80211_has_protected(fctl) &&
1537 tx_info->control.hw_key &&
1538 tx_info->control.hw_key->keyidx != priv->wep_default_key_id &&
1539 (tx_info->control.hw_key->cipher == WLAN_CIPHER_SUITE_WEP40 ||
1540 tx_info->control.hw_key->cipher == WLAN_CIPHER_SUITE_WEP104)) {
1541 action = do_wep;
1542 }
1543 }
1544
1545 switch (action) {
1546 case do_probe:
1547 /* An interesting FW "feature". Device filters probe responses.
1548 * The easiest way to get it back is to convert
1549 * probe request into WSM start_scan command.
1550 */
1551 pr_debug("[WSM] Convert probe request to scan.\n");
1552 wsm_lock_tx_async(priv);
1553 priv->pending_frame_id = __le32_to_cpu(wsm->packet_id);
1554 if (queue_delayed_work(priv->workqueue,
1555 &priv->scan.probe_work, 0) <= 0)
1556 wsm_unlock_tx(priv);
1557 handled = true;
1558 break;
1559 case do_drop:
1560 pr_debug("[WSM] Drop frame (0x%.4X).\n", fctl);
1561 BUG_ON(cw1200_queue_remove(queue,
1562 __le32_to_cpu(wsm->packet_id)));
1563 handled = true;
1564 break;
1565 case do_wep:
1566 pr_debug("[WSM] Issue set_default_wep_key.\n");
1567 wsm_lock_tx_async(priv);
1568 priv->wep_default_key_id = tx_info->control.hw_key->keyidx;
1569 priv->pending_frame_id = __le32_to_cpu(wsm->packet_id);
1570 if (queue_work(priv->workqueue, &priv->wep_key_work) <= 0)
1571 wsm_unlock_tx(priv);
1572 handled = true;
1573 break;
1574 case do_tx:
1575 pr_debug("[WSM] Transmit frame.\n");
1576 break;
1577 default:
1578 /* Do nothing */
1579 break;
1580 }
1581 return handled;
1582}
1583
1584static int cw1200_get_prio_queue(struct cw1200_common *priv,
1585 u32 link_id_map, int *total)
1586{
1587 static const int urgent = BIT(CW1200_LINK_ID_AFTER_DTIM) |
1588 BIT(CW1200_LINK_ID_UAPSD);
1589 struct wsm_edca_queue_params *edca;
1590 unsigned score, best = -1;
1591 int winner = -1;
1592 int queued;
1593 int i;
1594
1595 /* search for a winner using edca params */
1596 for (i = 0; i < 4; ++i) {
1597 queued = cw1200_queue_get_num_queued(&priv->tx_queue[i],
1598 link_id_map);
1599 if (!queued)
1600 continue;
1601 *total += queued;
1602 edca = &priv->edca.params[i];
1603 score = ((edca->aifns + edca->cwmin) << 16) +
1604 ((edca->cwmax - edca->cwmin) *
1605 (get_random_int() & 0xFFFF));
1606 if (score < best && (winner < 0 || i != 3)) {
1607 best = score;
1608 winner = i;
1609 }
1610 }
1611
1612 /* override winner if bursting */
1613 if (winner >= 0 && priv->tx_burst_idx >= 0 &&
1614 winner != priv->tx_burst_idx &&
1615 !cw1200_queue_get_num_queued(
1616 &priv->tx_queue[winner],
1617 link_id_map & urgent) &&
1618 cw1200_queue_get_num_queued(
1619 &priv->tx_queue[priv->tx_burst_idx],
1620 link_id_map))
1621 winner = priv->tx_burst_idx;
1622
1623 return winner;
1624}
1625
1626static int wsm_get_tx_queue_and_mask(struct cw1200_common *priv,
1627 struct cw1200_queue **queue_p,
1628 u32 *tx_allowed_mask_p,
1629 bool *more)
1630{
1631 int idx;
1632 u32 tx_allowed_mask;
1633 int total = 0;
1634
1635 /* Search for a queue with multicast frames buffered */
1636 if (priv->tx_multicast) {
1637 tx_allowed_mask = BIT(CW1200_LINK_ID_AFTER_DTIM);
1638 idx = cw1200_get_prio_queue(priv,
1639 tx_allowed_mask, &total);
1640 if (idx >= 0) {
1641 *more = total > 1;
1642 goto found;
1643 }
1644 }
1645
1646 /* Search for unicast traffic */
1647 tx_allowed_mask = ~priv->sta_asleep_mask;
1648 tx_allowed_mask |= BIT(CW1200_LINK_ID_UAPSD);
1649 if (priv->sta_asleep_mask) {
1650 tx_allowed_mask |= priv->pspoll_mask;
1651 tx_allowed_mask &= ~BIT(CW1200_LINK_ID_AFTER_DTIM);
1652 } else {
1653 tx_allowed_mask |= BIT(CW1200_LINK_ID_AFTER_DTIM);
1654 }
1655 idx = cw1200_get_prio_queue(priv,
1656 tx_allowed_mask, &total);
1657 if (idx < 0)
1658 return -ENOENT;
1659
1660found:
1661 *queue_p = &priv->tx_queue[idx];
1662 *tx_allowed_mask_p = tx_allowed_mask;
1663 return 0;
1664}
1665
1666int wsm_get_tx(struct cw1200_common *priv, u8 **data,
1667 size_t *tx_len, int *burst)
1668{
1669 struct wsm_tx *wsm = NULL;
1670 struct ieee80211_tx_info *tx_info;
1671 struct cw1200_queue *queue = NULL;
1672 int queue_num;
1673 u32 tx_allowed_mask = 0;
1674 const struct cw1200_txpriv *txpriv = NULL;
1675 int count = 0;
1676
1677 /* More is used only for broadcasts. */
1678 bool more = false;
1679
1680 if (priv->wsm_cmd.ptr) { /* CMD request */
1681 ++count;
1682 spin_lock(&priv->wsm_cmd.lock);
1683 BUG_ON(!priv->wsm_cmd.ptr);
1684 *data = priv->wsm_cmd.ptr;
1685 *tx_len = priv->wsm_cmd.len;
1686 *burst = 1;
1687 spin_unlock(&priv->wsm_cmd.lock);
1688 } else {
1689 for (;;) {
1690 int ret;
1691
1692 if (atomic_add_return(0, &priv->tx_lock))
1693 break;
1694
1695 spin_lock_bh(&priv->ps_state_lock);
1696
1697 ret = wsm_get_tx_queue_and_mask(priv, &queue,
1698 &tx_allowed_mask, &more);
1699 queue_num = queue - priv->tx_queue;
1700
1701 if (priv->buffered_multicasts &&
1702 (ret || !more) &&
1703 (priv->tx_multicast || !priv->sta_asleep_mask)) {
1704 priv->buffered_multicasts = false;
1705 if (priv->tx_multicast) {
1706 priv->tx_multicast = false;
1707 queue_work(priv->workqueue,
1708 &priv->multicast_stop_work);
1709 }
1710 }
1711
1712 spin_unlock_bh(&priv->ps_state_lock);
1713
1714 if (ret)
1715 break;
1716
1717 if (cw1200_queue_get(queue,
1718 tx_allowed_mask,
1719 &wsm, &tx_info, &txpriv))
1720 continue;
1721
1722 if (wsm_handle_tx_data(priv, wsm,
1723 tx_info, txpriv, queue))
1724 continue; /* Handled by WSM */
1725
1726 wsm->hdr.id &= __cpu_to_le16(
1727 ~WSM_TX_LINK_ID(WSM_TX_LINK_ID_MAX));
1728 wsm->hdr.id |= cpu_to_le16(
1729 WSM_TX_LINK_ID(txpriv->raw_link_id));
1730 priv->pspoll_mask &= ~BIT(txpriv->raw_link_id);
1731
1732 *data = (u8 *)wsm;
1733 *tx_len = __le16_to_cpu(wsm->hdr.len);
1734
1735 /* allow bursting if txop is set */
1736 if (priv->edca.params[queue_num].txop_limit)
1737 *burst = min(*burst,
1738 (int)cw1200_queue_get_num_queued(queue, tx_allowed_mask) + 1);
1739 else
1740 *burst = 1;
1741
1742 /* store index of bursting queue */
1743 if (*burst > 1)
1744 priv->tx_burst_idx = queue_num;
1745 else
1746 priv->tx_burst_idx = -1;
1747
1748 if (more) {
1749 struct ieee80211_hdr *hdr =
1750 (struct ieee80211_hdr *)
1751 &((u8 *)wsm)[txpriv->offset];
1752 /* more buffered multicast/broadcast frames
1753 * ==> set MoreData flag in IEEE 802.11 header
1754 * to inform PS STAs
1755 */
1756 hdr->frame_control |=
1757 cpu_to_le16(IEEE80211_FCTL_MOREDATA);
1758 }
1759
1760 pr_debug("[WSM] >>> 0x%.4X (%zu) %p %c\n",
1761 0x0004, *tx_len, *data,
1762 wsm->more ? 'M' : ' ');
1763 ++count;
1764 break;
1765 }
1766 }
1767
1768 return count;
1769}
1770
1771void wsm_txed(struct cw1200_common *priv, u8 *data)
1772{
1773 if (data == priv->wsm_cmd.ptr) {
1774 spin_lock(&priv->wsm_cmd.lock);
1775 priv->wsm_cmd.ptr = NULL;
1776 spin_unlock(&priv->wsm_cmd.lock);
1777 }
1778}
1779
1780/* ******************************************************************** */
1781/* WSM buffer */
1782
1783void wsm_buf_init(struct wsm_buf *buf)
1784{
1785 BUG_ON(buf->begin);
1786 buf->begin = kmalloc(FWLOAD_BLOCK_SIZE, GFP_KERNEL | GFP_DMA);
1787 buf->end = buf->begin ? &buf->begin[FWLOAD_BLOCK_SIZE] : buf->begin;
1788 wsm_buf_reset(buf);
1789}
1790
1791void wsm_buf_deinit(struct wsm_buf *buf)
1792{
1793 kfree(buf->begin);
1794 buf->begin = buf->data = buf->end = NULL;
1795}
1796
1797static void wsm_buf_reset(struct wsm_buf *buf)
1798{
1799 if (buf->begin) {
1800 buf->data = &buf->begin[4];
1801 *(u32 *)buf->begin = 0;
1802 } else {
1803 buf->data = buf->begin;
1804 }
1805}
1806
1807static int wsm_buf_reserve(struct wsm_buf *buf, size_t extra_size)
1808{
1809 size_t pos = buf->data - buf->begin;
1810 size_t size = pos + extra_size;
1811
1812 size = round_up(size, FWLOAD_BLOCK_SIZE);
1813
1814 buf->begin = krealloc(buf->begin, size, GFP_KERNEL | GFP_DMA);
1815 if (buf->begin) {
1816 buf->data = &buf->begin[pos];
1817 buf->end = &buf->begin[size];
1818 return 0;
1819 } else {
1820 buf->end = buf->data = buf->begin;
1821 return -ENOMEM;
1822 }
1823}
diff --git a/drivers/net/wireless/cw1200/wsm.h b/drivers/net/wireless/cw1200/wsm.h
new file mode 100644
index 000000000000..2816171f7a1d
--- /dev/null
+++ b/drivers/net/wireless/cw1200/wsm.h
@@ -0,0 +1,1873 @@
1/*
2 * WSM host interface (HI) interface for ST-Ericsson CW1200 mac80211 drivers
3 *
4 * Copyright (c) 2010, ST-Ericsson
5 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
6 *
7 * Based on CW1200 UMAC WSM API, which is
8 * Copyright (C) ST-Ericsson SA 2010
9 * Author: Stewart Mathers <stewart.mathers@stericsson.com>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 */
15
16#ifndef CW1200_WSM_H_INCLUDED
17#define CW1200_WSM_H_INCLUDED
18
19#include <linux/spinlock.h>
20
21struct cw1200_common;
22
23/* Bands */
24/* Radio band 2.412 -2.484 GHz. */
25#define WSM_PHY_BAND_2_4G (0)
26
27/* Radio band 4.9375-5.8250 GHz. */
28#define WSM_PHY_BAND_5G (1)
29
30/* Transmit rates */
31/* 1 Mbps ERP-DSSS */
32#define WSM_TRANSMIT_RATE_1 (0)
33
34/* 2 Mbps ERP-DSSS */
35#define WSM_TRANSMIT_RATE_2 (1)
36
37/* 5.5 Mbps ERP-CCK */
38#define WSM_TRANSMIT_RATE_5 (2)
39
40/* 11 Mbps ERP-CCK */
41#define WSM_TRANSMIT_RATE_11 (3)
42
43/* 22 Mbps ERP-PBCC (Not supported) */
44/* #define WSM_TRANSMIT_RATE_22 (4) */
45
46/* 33 Mbps ERP-PBCC (Not supported) */
47/* #define WSM_TRANSMIT_RATE_33 (5) */
48
49/* 6 Mbps (3 Mbps) ERP-OFDM, BPSK coding rate 1/2 */
50#define WSM_TRANSMIT_RATE_6 (6)
51
52/* 9 Mbps (4.5 Mbps) ERP-OFDM, BPSK coding rate 3/4 */
53#define WSM_TRANSMIT_RATE_9 (7)
54
55/* 12 Mbps (6 Mbps) ERP-OFDM, QPSK coding rate 1/2 */
56#define WSM_TRANSMIT_RATE_12 (8)
57
58/* 18 Mbps (9 Mbps) ERP-OFDM, QPSK coding rate 3/4 */
59#define WSM_TRANSMIT_RATE_18 (9)
60
61/* 24 Mbps (12 Mbps) ERP-OFDM, 16QAM coding rate 1/2 */
62#define WSM_TRANSMIT_RATE_24 (10)
63
64/* 36 Mbps (18 Mbps) ERP-OFDM, 16QAM coding rate 3/4 */
65#define WSM_TRANSMIT_RATE_36 (11)
66
67/* 48 Mbps (24 Mbps) ERP-OFDM, 64QAM coding rate 1/2 */
68#define WSM_TRANSMIT_RATE_48 (12)
69
70/* 54 Mbps (27 Mbps) ERP-OFDM, 64QAM coding rate 3/4 */
71#define WSM_TRANSMIT_RATE_54 (13)
72
73/* 6.5 Mbps HT-OFDM, BPSK coding rate 1/2 */
74#define WSM_TRANSMIT_RATE_HT_6 (14)
75
76/* 13 Mbps HT-OFDM, QPSK coding rate 1/2 */
77#define WSM_TRANSMIT_RATE_HT_13 (15)
78
79/* 19.5 Mbps HT-OFDM, QPSK coding rate 3/4 */
80#define WSM_TRANSMIT_RATE_HT_19 (16)
81
82/* 26 Mbps HT-OFDM, 16QAM coding rate 1/2 */
83#define WSM_TRANSMIT_RATE_HT_26 (17)
84
85/* 39 Mbps HT-OFDM, 16QAM coding rate 3/4 */
86#define WSM_TRANSMIT_RATE_HT_39 (18)
87
88/* 52 Mbps HT-OFDM, 64QAM coding rate 2/3 */
89#define WSM_TRANSMIT_RATE_HT_52 (19)
90
91/* 58.5 Mbps HT-OFDM, 64QAM coding rate 3/4 */
92#define WSM_TRANSMIT_RATE_HT_58 (20)
93
94/* 65 Mbps HT-OFDM, 64QAM coding rate 5/6 */
95#define WSM_TRANSMIT_RATE_HT_65 (21)
96
97/* Scan types */
98/* Foreground scan */
99#define WSM_SCAN_TYPE_FOREGROUND (0)
100
101/* Background scan */
102#define WSM_SCAN_TYPE_BACKGROUND (1)
103
104/* Auto scan */
105#define WSM_SCAN_TYPE_AUTO (2)
106
107/* Scan flags */
108/* Forced background scan means if the station cannot */
109/* enter the power-save mode, it shall force to perform a */
110/* background scan. Only valid when ScanType is */
111/* background scan. */
112#define WSM_SCAN_FLAG_FORCE_BACKGROUND (BIT(0))
113
114/* The WLAN device scans one channel at a time so */
115/* that disturbance to the data traffic is minimized. */
116#define WSM_SCAN_FLAG_SPLIT_METHOD (BIT(1))
117
118/* Preamble Type. Long if not set. */
119#define WSM_SCAN_FLAG_SHORT_PREAMBLE (BIT(2))
120
121/* 11n Tx Mode. Mixed if not set. */
122#define WSM_SCAN_FLAG_11N_GREENFIELD (BIT(3))
123
124/* Scan constraints */
125/* Maximum number of channels to be scanned. */
126#define WSM_SCAN_MAX_NUM_OF_CHANNELS (48)
127
128/* The maximum number of SSIDs that the device can scan for. */
129#define WSM_SCAN_MAX_NUM_OF_SSIDS (2)
130
131/* Power management modes */
132/* 802.11 Active mode */
133#define WSM_PSM_ACTIVE (0)
134
135/* 802.11 PS mode */
136#define WSM_PSM_PS BIT(0)
137
138/* Fast Power Save bit */
139#define WSM_PSM_FAST_PS_FLAG BIT(7)
140
141/* Dynamic aka Fast power save */
142#define WSM_PSM_FAST_PS (BIT(0) | BIT(7))
143
144/* Undetermined */
145/* Note : Undetermined status is reported when the */
146/* NULL data frame used to advertise the PM mode to */
147/* the AP at Pre or Post Background Scan is not Acknowledged */
148#define WSM_PSM_UNKNOWN BIT(1)
149
150/* Queue IDs */
151/* best effort/legacy */
152#define WSM_QUEUE_BEST_EFFORT (0)
153
154/* background */
155#define WSM_QUEUE_BACKGROUND (1)
156
157/* video */
158#define WSM_QUEUE_VIDEO (2)
159
160/* voice */
161#define WSM_QUEUE_VOICE (3)
162
163/* HT TX parameters */
164/* Non-HT */
165#define WSM_HT_TX_NON_HT (0)
166
167/* Mixed format */
168#define WSM_HT_TX_MIXED (1)
169
170/* Greenfield format */
171#define WSM_HT_TX_GREENFIELD (2)
172
173/* STBC allowed */
174#define WSM_HT_TX_STBC (BIT(7))
175
176/* EPTA prioirty flags for BT Coex */
177/* default epta priority */
178#define WSM_EPTA_PRIORITY_DEFAULT 4
179/* use for normal data */
180#define WSM_EPTA_PRIORITY_DATA 4
181/* use for connect/disconnect/roaming*/
182#define WSM_EPTA_PRIORITY_MGT 5
183/* use for action frames */
184#define WSM_EPTA_PRIORITY_ACTION 5
185/* use for AC_VI data */
186#define WSM_EPTA_PRIORITY_VIDEO 5
187/* use for AC_VO data */
188#define WSM_EPTA_PRIORITY_VOICE 6
189/* use for EAPOL exchange */
190#define WSM_EPTA_PRIORITY_EAPOL 7
191
192/* TX status */
193/* Frame was sent aggregated */
194/* Only valid for WSM_SUCCESS status. */
195#define WSM_TX_STATUS_AGGREGATION (BIT(0))
196
197/* Host should requeue this frame later. */
198/* Valid only when status is WSM_REQUEUE. */
199#define WSM_TX_STATUS_REQUEUE (BIT(1))
200
201/* Normal Ack */
202#define WSM_TX_STATUS_NORMAL_ACK (0<<2)
203
204/* No Ack */
205#define WSM_TX_STATUS_NO_ACK (1<<2)
206
207/* No explicit acknowledgement */
208#define WSM_TX_STATUS_NO_EXPLICIT_ACK (2<<2)
209
210/* Block Ack */
211/* Only valid for WSM_SUCCESS status. */
212#define WSM_TX_STATUS_BLOCK_ACK (3<<2)
213
214/* RX status */
215/* Unencrypted */
216#define WSM_RX_STATUS_UNENCRYPTED (0<<0)
217
218/* WEP */
219#define WSM_RX_STATUS_WEP (1<<0)
220
221/* TKIP */
222#define WSM_RX_STATUS_TKIP (2<<0)
223
224/* AES */
225#define WSM_RX_STATUS_AES (3<<0)
226
227/* WAPI */
228#define WSM_RX_STATUS_WAPI (4<<0)
229
230/* Macro to fetch encryption subfield. */
231#define WSM_RX_STATUS_ENCRYPTION(status) ((status) & 0x07)
232
233/* Frame was part of an aggregation */
234#define WSM_RX_STATUS_AGGREGATE (BIT(3))
235
236/* Frame was first in the aggregation */
237#define WSM_RX_STATUS_AGGREGATE_FIRST (BIT(4))
238
239/* Frame was last in the aggregation */
240#define WSM_RX_STATUS_AGGREGATE_LAST (BIT(5))
241
242/* Indicates a defragmented frame */
243#define WSM_RX_STATUS_DEFRAGMENTED (BIT(6))
244
245/* Indicates a Beacon frame */
246#define WSM_RX_STATUS_BEACON (BIT(7))
247
248/* Indicates STA bit beacon TIM field */
249#define WSM_RX_STATUS_TIM (BIT(8))
250
251/* Indicates Beacon frame's virtual bitmap contains multicast bit */
252#define WSM_RX_STATUS_MULTICAST (BIT(9))
253
254/* Indicates frame contains a matching SSID */
255#define WSM_RX_STATUS_MATCHING_SSID (BIT(10))
256
257/* Indicates frame contains a matching BSSI */
258#define WSM_RX_STATUS_MATCHING_BSSI (BIT(11))
259
260/* Indicates More bit set in Framectl field */
261#define WSM_RX_STATUS_MORE_DATA (BIT(12))
262
263/* Indicates frame received during a measurement process */
264#define WSM_RX_STATUS_MEASUREMENT (BIT(13))
265
266/* Indicates frame received as an HT packet */
267#define WSM_RX_STATUS_HT (BIT(14))
268
269/* Indicates frame received with STBC */
270#define WSM_RX_STATUS_STBC (BIT(15))
271
272/* Indicates Address 1 field matches dot11StationId */
273#define WSM_RX_STATUS_ADDRESS1 (BIT(16))
274
275/* Indicates Group address present in the Address 1 field */
276#define WSM_RX_STATUS_GROUP (BIT(17))
277
278/* Indicates Broadcast address present in the Address 1 field */
279#define WSM_RX_STATUS_BROADCAST (BIT(18))
280
281/* Indicates group key used with encrypted frames */
282#define WSM_RX_STATUS_GROUP_KEY (BIT(19))
283
284/* Macro to fetch encryption key index. */
285#define WSM_RX_STATUS_KEY_IDX(status) (((status >> 20)) & 0x0F)
286
287/* Indicates TSF inclusion after 802.11 frame body */
288#define WSM_RX_STATUS_TSF_INCLUDED (BIT(24))
289
290/* Frame Control field starts at Frame offset + 2 */
291#define WSM_TX_2BYTES_SHIFT (BIT(7))
292
293/* Join mode */
294/* IBSS */
295#define WSM_JOIN_MODE_IBSS (0)
296
297/* BSS */
298#define WSM_JOIN_MODE_BSS (1)
299
300/* PLCP preamble type */
301/* For long preamble */
302#define WSM_JOIN_PREAMBLE_LONG (0)
303
304/* For short preamble (Long for 1Mbps) */
305#define WSM_JOIN_PREAMBLE_SHORT (1)
306
307/* For short preamble (Long for 1 and 2Mbps) */
308#define WSM_JOIN_PREAMBLE_SHORT_2 (2)
309
310/* Join flags */
311/* Unsynchronized */
312#define WSM_JOIN_FLAGS_UNSYNCRONIZED BIT(0)
313/* The BSS owner is a P2P GO */
314#define WSM_JOIN_FLAGS_P2P_GO BIT(1)
315/* Force to join BSS with the BSSID and the
316 * SSID specified without waiting for beacons. The
317 * ProbeForJoin parameter is ignored.
318 */
319#define WSM_JOIN_FLAGS_FORCE BIT(2)
320/* Give probe request/response higher
321 * priority over the BT traffic
322 */
323#define WSM_JOIN_FLAGS_PRIO BIT(3)
324/* Issue immediate join confirmation and use
325 * join complete to notify about completion
326 */
327#define WSM_JOIN_FLAGS_FORCE_WITH_COMPLETE_IND BIT(5)
328
329/* Key types */
330#define WSM_KEY_TYPE_WEP_DEFAULT (0)
331#define WSM_KEY_TYPE_WEP_PAIRWISE (1)
332#define WSM_KEY_TYPE_TKIP_GROUP (2)
333#define WSM_KEY_TYPE_TKIP_PAIRWISE (3)
334#define WSM_KEY_TYPE_AES_GROUP (4)
335#define WSM_KEY_TYPE_AES_PAIRWISE (5)
336#define WSM_KEY_TYPE_WAPI_GROUP (6)
337#define WSM_KEY_TYPE_WAPI_PAIRWISE (7)
338
339/* Key indexes */
340#define WSM_KEY_MAX_INDEX (10)
341
342/* ACK policy */
343#define WSM_ACK_POLICY_NORMAL (0)
344#define WSM_ACK_POLICY_NO_ACK (1)
345
346/* Start modes */
347#define WSM_START_MODE_AP (0) /* Mini AP */
348#define WSM_START_MODE_P2P_GO (1) /* P2P GO */
349#define WSM_START_MODE_P2P_DEV (2) /* P2P device */
350
351/* SetAssociationMode MIB flags */
352#define WSM_ASSOCIATION_MODE_USE_PREAMBLE_TYPE (BIT(0))
353#define WSM_ASSOCIATION_MODE_USE_HT_MODE (BIT(1))
354#define WSM_ASSOCIATION_MODE_USE_BASIC_RATE_SET (BIT(2))
355#define WSM_ASSOCIATION_MODE_USE_MPDU_START_SPACING (BIT(3))
356#define WSM_ASSOCIATION_MODE_SNOOP_ASSOC_FRAMES (BIT(4))
357
358/* RcpiRssiThreshold MIB flags */
359#define WSM_RCPI_RSSI_THRESHOLD_ENABLE (BIT(0))
360#define WSM_RCPI_RSSI_USE_RSSI (BIT(1))
361#define WSM_RCPI_RSSI_DONT_USE_UPPER (BIT(2))
362#define WSM_RCPI_RSSI_DONT_USE_LOWER (BIT(3))
363
364/* Update-ie constants */
365#define WSM_UPDATE_IE_BEACON (BIT(0))
366#define WSM_UPDATE_IE_PROBE_RESP (BIT(1))
367#define WSM_UPDATE_IE_PROBE_REQ (BIT(2))
368
369/* WSM events */
370/* Error */
371#define WSM_EVENT_ERROR (0)
372
373/* BSS lost */
374#define WSM_EVENT_BSS_LOST (1)
375
376/* BSS regained */
377#define WSM_EVENT_BSS_REGAINED (2)
378
379/* Radar detected */
380#define WSM_EVENT_RADAR_DETECTED (3)
381
382/* RCPI or RSSI threshold triggered */
383#define WSM_EVENT_RCPI_RSSI (4)
384
385/* BT inactive */
386#define WSM_EVENT_BT_INACTIVE (5)
387
388/* BT active */
389#define WSM_EVENT_BT_ACTIVE (6)
390
391/* MIB IDs */
392/* 4.1 dot11StationId */
393#define WSM_MIB_ID_DOT11_STATION_ID 0x0000
394
395/* 4.2 dot11MaxtransmitMsduLifeTime */
396#define WSM_MIB_ID_DOT11_MAX_TRANSMIT_LIFTIME 0x0001
397
398/* 4.3 dot11MaxReceiveLifeTime */
399#define WSM_MIB_ID_DOT11_MAX_RECEIVE_LIFETIME 0x0002
400
401/* 4.4 dot11SlotTime */
402#define WSM_MIB_ID_DOT11_SLOT_TIME 0x0003
403
404/* 4.5 dot11GroupAddressesTable */
405#define WSM_MIB_ID_DOT11_GROUP_ADDRESSES_TABLE 0x0004
406#define WSM_MAX_GRP_ADDRTABLE_ENTRIES 8
407
408/* 4.6 dot11WepDefaultKeyId */
409#define WSM_MIB_ID_DOT11_WEP_DEFAULT_KEY_ID 0x0005
410
411/* 4.7 dot11CurrentTxPowerLevel */
412#define WSM_MIB_ID_DOT11_CURRENT_TX_POWER_LEVEL 0x0006
413
414/* 4.8 dot11RTSThreshold */
415#define WSM_MIB_ID_DOT11_RTS_THRESHOLD 0x0007
416
417/* 4.9 NonErpProtection */
418#define WSM_MIB_ID_NON_ERP_PROTECTION 0x1000
419
420/* 4.10 ArpIpAddressesTable */
421#define WSM_MIB_ID_ARP_IP_ADDRESSES_TABLE 0x1001
422#define WSM_MAX_ARP_IP_ADDRTABLE_ENTRIES 1
423
424/* 4.11 TemplateFrame */
425#define WSM_MIB_ID_TEMPLATE_FRAME 0x1002
426
427/* 4.12 RxFilter */
428#define WSM_MIB_ID_RX_FILTER 0x1003
429
430/* 4.13 BeaconFilterTable */
431#define WSM_MIB_ID_BEACON_FILTER_TABLE 0x1004
432
433/* 4.14 BeaconFilterEnable */
434#define WSM_MIB_ID_BEACON_FILTER_ENABLE 0x1005
435
436/* 4.15 OperationalPowerMode */
437#define WSM_MIB_ID_OPERATIONAL_POWER_MODE 0x1006
438
439/* 4.16 BeaconWakeUpPeriod */
440#define WSM_MIB_ID_BEACON_WAKEUP_PERIOD 0x1007
441
442/* 4.17 RcpiRssiThreshold */
443#define WSM_MIB_ID_RCPI_RSSI_THRESHOLD 0x1009
444
445/* 4.18 StatisticsTable */
446#define WSM_MIB_ID_STATISTICS_TABLE 0x100A
447
448/* 4.19 IbssPsConfig */
449#define WSM_MIB_ID_IBSS_PS_CONFIG 0x100B
450
451/* 4.20 CountersTable */
452#define WSM_MIB_ID_COUNTERS_TABLE 0x100C
453
454/* 4.21 BlockAckPolicy */
455#define WSM_MIB_ID_BLOCK_ACK_POLICY 0x100E
456
457/* 4.22 OverrideInternalTxRate */
458#define WSM_MIB_ID_OVERRIDE_INTERNAL_TX_RATE 0x100F
459
460/* 4.23 SetAssociationMode */
461#define WSM_MIB_ID_SET_ASSOCIATION_MODE 0x1010
462
463/* 4.24 UpdateEptaConfigData */
464#define WSM_MIB_ID_UPDATE_EPTA_CONFIG_DATA 0x1011
465
466/* 4.25 SelectCcaMethod */
467#define WSM_MIB_ID_SELECT_CCA_METHOD 0x1012
468
469/* 4.26 SetUpasdInformation */
470#define WSM_MIB_ID_SET_UAPSD_INFORMATION 0x1013
471
472/* 4.27 SetAutoCalibrationMode WBF00004073 */
473#define WSM_MIB_ID_SET_AUTO_CALIBRATION_MODE 0x1015
474
475/* 4.28 SetTxRateRetryPolicy */
476#define WSM_MIB_ID_SET_TX_RATE_RETRY_POLICY 0x1016
477
478/* 4.29 SetHostMessageTypeFilter */
479#define WSM_MIB_ID_SET_HOST_MSG_TYPE_FILTER 0x1017
480
481/* 4.30 P2PFindInfo */
482#define WSM_MIB_ID_P2P_FIND_INFO 0x1018
483
484/* 4.31 P2PPsModeInfo */
485#define WSM_MIB_ID_P2P_PS_MODE_INFO 0x1019
486
487/* 4.32 SetEtherTypeDataFrameFilter */
488#define WSM_MIB_ID_SET_ETHERTYPE_DATAFRAME_FILTER 0x101A
489
490/* 4.33 SetUDPPortDataFrameFilter */
491#define WSM_MIB_ID_SET_UDPPORT_DATAFRAME_FILTER 0x101B
492
493/* 4.34 SetMagicDataFrameFilter */
494#define WSM_MIB_ID_SET_MAGIC_DATAFRAME_FILTER 0x101C
495
496/* 4.35 P2PDeviceInfo */
497#define WSM_MIB_ID_P2P_DEVICE_INFO 0x101D
498
499/* 4.36 SetWCDMABand */
500#define WSM_MIB_ID_SET_WCDMA_BAND 0x101E
501
502/* 4.37 GroupTxSequenceCounter */
503#define WSM_MIB_ID_GRP_SEQ_COUNTER 0x101F
504
505/* 4.38 ProtectedMgmtPolicy */
506#define WSM_MIB_ID_PROTECTED_MGMT_POLICY 0x1020
507
508/* 4.39 SetHtProtection */
509#define WSM_MIB_ID_SET_HT_PROTECTION 0x1021
510
511/* 4.40 GPIO Command */
512#define WSM_MIB_ID_GPIO_COMMAND 0x1022
513
514/* 4.41 TSF Counter Value */
515#define WSM_MIB_ID_TSF_COUNTER 0x1023
516
517/* Test Purposes Only */
518#define WSM_MIB_ID_BLOCK_ACK_INFO 0x100D
519
520/* 4.42 UseMultiTxConfMessage */
521#define WSM_MIB_USE_MULTI_TX_CONF 0x1024
522
523/* 4.43 Keep-alive period */
524#define WSM_MIB_ID_KEEP_ALIVE_PERIOD 0x1025
525
526/* 4.44 Disable BSSID filter */
527#define WSM_MIB_ID_DISABLE_BSSID_FILTER 0x1026
528
529/* Frame template types */
530#define WSM_FRAME_TYPE_PROBE_REQUEST (0)
531#define WSM_FRAME_TYPE_BEACON (1)
532#define WSM_FRAME_TYPE_NULL (2)
533#define WSM_FRAME_TYPE_QOS_NULL (3)
534#define WSM_FRAME_TYPE_PS_POLL (4)
535#define WSM_FRAME_TYPE_PROBE_RESPONSE (5)
536
537#define WSM_FRAME_GREENFIELD (0x80) /* See 4.11 */
538
539/* Status */
540/* The WSM firmware has completed a request */
541/* successfully. */
542#define WSM_STATUS_SUCCESS (0)
543
544/* This is a generic failure code if other error codes do */
545/* not apply. */
546#define WSM_STATUS_FAILURE (1)
547
548/* A request contains one or more invalid parameters. */
549#define WSM_INVALID_PARAMETER (2)
550
551/* The request cannot perform because the device is in */
552/* an inappropriate mode. */
553#define WSM_ACCESS_DENIED (3)
554
555/* The frame received includes a decryption error. */
556#define WSM_STATUS_DECRYPTFAILURE (4)
557
558/* A MIC failure is detected in the received packets. */
559#define WSM_STATUS_MICFAILURE (5)
560
561/* The transmit request failed due to retry limit being */
562/* exceeded. */
563#define WSM_STATUS_RETRY_EXCEEDED (6)
564
565/* The transmit request failed due to MSDU life time */
566/* being exceeded. */
567#define WSM_STATUS_TX_LIFETIME_EXCEEDED (7)
568
569/* The link to the AP is lost. */
570#define WSM_STATUS_LINK_LOST (8)
571
572/* No key was found for the encrypted frame */
573#define WSM_STATUS_NO_KEY_FOUND (9)
574
575/* Jammer was detected when transmitting this frame */
576#define WSM_STATUS_JAMMER_DETECTED (10)
577
578/* The message should be requeued later. */
579/* This is applicable only to Transmit */
580#define WSM_REQUEUE (11)
581
582/* Advanced filtering options */
583#define WSM_MAX_FILTER_ELEMENTS (4)
584
585#define WSM_FILTER_ACTION_IGNORE (0)
586#define WSM_FILTER_ACTION_FILTER_IN (1)
587#define WSM_FILTER_ACTION_FILTER_OUT (2)
588
589#define WSM_FILTER_PORT_TYPE_DST (0)
590#define WSM_FILTER_PORT_TYPE_SRC (1)
591
592/* Actual header of WSM messages */
593struct wsm_hdr {
594 __le16 len;
595 __le16 id;
596};
597
598#define WSM_TX_SEQ_MAX (7)
599#define WSM_TX_SEQ(seq) \
600 ((seq & WSM_TX_SEQ_MAX) << 13)
601#define WSM_TX_LINK_ID_MAX (0x0F)
602#define WSM_TX_LINK_ID(link_id) \
603 ((link_id & WSM_TX_LINK_ID_MAX) << 6)
604
605#define MAX_BEACON_SKIP_TIME_MS 1000
606
607#define WSM_CMD_LAST_CHANCE_TIMEOUT (HZ * 3 / 2)
608
609/* ******************************************************************** */
610/* WSM capability */
611
612#define WSM_STARTUP_IND_ID 0x0801
613
614struct wsm_startup_ind {
615 u16 input_buffers;
616 u16 input_buffer_size;
617 u16 status;
618 u16 hw_id;
619 u16 hw_subid;
620 u16 fw_cap;
621 u16 fw_type;
622 u16 fw_api;
623 u16 fw_build;
624 u16 fw_ver;
625 char fw_label[128];
626 u32 config[4];
627};
628
629/* ******************************************************************** */
630/* WSM commands */
631
632/* 3.1 */
633#define WSM_CONFIGURATION_REQ_ID 0x0009
634#define WSM_CONFIGURATION_RESP_ID 0x0409
635
636struct wsm_tx_power_range {
637 int min_power_level;
638 int max_power_level;
639 u32 stepping;
640};
641
642struct wsm_configuration {
643 /* [in] */ u32 dot11MaxTransmitMsduLifeTime;
644 /* [in] */ u32 dot11MaxReceiveLifeTime;
645 /* [in] */ u32 dot11RtsThreshold;
646 /* [in, out] */ u8 *dot11StationId;
647 /* [in] */ const void *dpdData;
648 /* [in] */ size_t dpdData_size;
649 /* [out] */ u8 dot11FrequencyBandsSupported;
650 /* [out] */ u32 supportedRateMask;
651 /* [out] */ struct wsm_tx_power_range txPowerRange[2];
652};
653
654int wsm_configuration(struct cw1200_common *priv,
655 struct wsm_configuration *arg);
656
657/* 3.3 */
658#define WSM_RESET_REQ_ID 0x000A
659#define WSM_RESET_RESP_ID 0x040A
660struct wsm_reset {
661 /* [in] */ int link_id;
662 /* [in] */ bool reset_statistics;
663};
664
665int wsm_reset(struct cw1200_common *priv, const struct wsm_reset *arg);
666
667/* 3.5 */
668#define WSM_READ_MIB_REQ_ID 0x0005
669#define WSM_READ_MIB_RESP_ID 0x0405
670int wsm_read_mib(struct cw1200_common *priv, u16 mib_id, void *buf,
671 size_t buf_size);
672
673/* 3.7 */
674#define WSM_WRITE_MIB_REQ_ID 0x0006
675#define WSM_WRITE_MIB_RESP_ID 0x0406
676int wsm_write_mib(struct cw1200_common *priv, u16 mib_id, void *buf,
677 size_t buf_size);
678
679/* 3.9 */
680#define WSM_START_SCAN_REQ_ID 0x0007
681#define WSM_START_SCAN_RESP_ID 0x0407
682
683struct wsm_ssid {
684 u8 ssid[32];
685 u32 length;
686};
687
688struct wsm_scan_ch {
689 u16 number;
690 u32 min_chan_time;
691 u32 max_chan_time;
692 u32 tx_power_level;
693};
694
695struct wsm_scan {
696 /* WSM_PHY_BAND_... */
697 u8 band;
698
699 /* WSM_SCAN_TYPE_... */
700 u8 type;
701
702 /* WSM_SCAN_FLAG_... */
703 u8 flags;
704
705 /* WSM_TRANSMIT_RATE_... */
706 u8 max_tx_rate;
707
708 /* Interval period in TUs that the device shall the re- */
709 /* execute the requested scan. Max value supported by the device */
710 /* is 256s. */
711 u32 auto_scan_interval;
712
713 /* Number of probe requests (per SSID) sent to one (1) */
714 /* channel. Zero (0) means that none is send, which */
715 /* means that a passive scan is to be done. Value */
716 /* greater than zero (0) means that an active scan is to */
717 /* be done. */
718 u32 num_probes;
719
720 /* Number of channels to be scanned. */
721 /* Maximum value is WSM_SCAN_MAX_NUM_OF_CHANNELS. */
722 u8 num_channels;
723
724 /* Number of SSID provided in the scan command (this */
725 /* is zero (0) in broadcast scan) */
726 /* The maximum number of SSIDs is WSM_SCAN_MAX_NUM_OF_SSIDS. */
727 u8 num_ssids;
728
729 /* The delay time (in microseconds) period */
730 /* before sending a probe-request. */
731 u8 probe_delay;
732
733 /* SSIDs to be scanned [numOfSSIDs]; */
734 struct wsm_ssid *ssids;
735
736 /* Channels to be scanned [numOfChannels]; */
737 struct wsm_scan_ch *ch;
738};
739
740int wsm_scan(struct cw1200_common *priv, const struct wsm_scan *arg);
741
742/* 3.11 */
743#define WSM_STOP_SCAN_REQ_ID 0x0008
744#define WSM_STOP_SCAN_RESP_ID 0x0408
745int wsm_stop_scan(struct cw1200_common *priv);
746
747/* 3.13 */
748#define WSM_SCAN_COMPLETE_IND_ID 0x0806
749struct wsm_scan_complete {
750 /* WSM_STATUS_... */
751 u32 status;
752
753 /* WSM_PSM_... */
754 u8 psm;
755
756 /* Number of channels that the scan operation completed. */
757 u8 num_channels;
758};
759
760/* 3.14 */
761#define WSM_TX_CONFIRM_IND_ID 0x0404
762#define WSM_MULTI_TX_CONFIRM_ID 0x041E
763
764struct wsm_tx_confirm {
765 /* Packet identifier used in wsm_tx. */
766 u32 packet_id;
767
768 /* WSM_STATUS_... */
769 u32 status;
770
771 /* WSM_TRANSMIT_RATE_... */
772 u8 tx_rate;
773
774 /* The number of times the frame was transmitted */
775 /* without receiving an acknowledgement. */
776 u8 ack_failures;
777
778 /* WSM_TX_STATUS_... */
779 u16 flags;
780
781 /* The total time in microseconds that the frame spent in */
782 /* the WLAN device before transmission as completed. */
783 u32 media_delay;
784
785 /* The total time in microseconds that the frame spent in */
786 /* the WLAN device before transmission was started. */
787 u32 tx_queue_delay;
788};
789
790/* 3.15 */
791typedef void (*wsm_tx_confirm_cb) (struct cw1200_common *priv,
792 struct wsm_tx_confirm *arg);
793
794/* Note that ideology of wsm_tx struct is different against the rest of
795 * WSM API. wsm_hdr is /not/ a caller-adapted struct to be used as an input
796 * argument for WSM call, but a prepared bytestream to be sent to firmware.
797 * It is filled partly in cw1200_tx, partly in low-level WSM code.
798 * Please pay attention once again: ideology is different.
799 *
800 * Legend:
801 * - [in]: cw1200_tx must fill this field.
802 * - [wsm]: the field is filled by low-level WSM.
803 */
804struct wsm_tx {
805 /* common WSM header */
806 struct wsm_hdr hdr;
807
808 /* Packet identifier that meant to be used in completion. */
809 __le32 packet_id;
810
811 /* WSM_TRANSMIT_RATE_... */
812 u8 max_tx_rate;
813
814 /* WSM_QUEUE_... */
815 u8 queue_id;
816
817 /* True: another packet is pending on the host for transmission. */
818 u8 more;
819
820 /* Bit 0 = 0 - Start expiry time from first Tx attempt (default) */
821 /* Bit 0 = 1 - Start expiry time from receipt of Tx Request */
822 /* Bits 3:1 - PTA Priority */
823 /* Bits 6:4 - Tx Rate Retry Policy */
824 /* Bit 7 - Reserved */
825 u8 flags;
826
827 /* Should be 0. */
828 __le32 reserved;
829
830 /* The elapsed time in TUs, after the initial transmission */
831 /* of an MSDU, after which further attempts to transmit */
832 /* the MSDU shall be terminated. Overrides the global */
833 /* dot11MaxTransmitMsduLifeTime setting [optional] */
834 /* Device will set the default value if this is 0. */
835 __le32 expire_time;
836
837 /* WSM_HT_TX_... */
838 __le32 ht_tx_parameters;
839};
840
841/* = sizeof(generic hi hdr) + sizeof(wsm hdr) + sizeof(alignment) */
842#define WSM_TX_EXTRA_HEADROOM (28)
843
844/* 3.16 */
845#define WSM_RECEIVE_IND_ID 0x0804
846
847struct wsm_rx {
848 /* WSM_STATUS_... */
849 __le32 status;
850
851 /* Specifies the channel of the received packet. */
852 __le16 channel_number;
853
854 /* WSM_TRANSMIT_RATE_... */
855 u8 rx_rate;
856
857 /* This value is expressed in signed Q8.0 format for */
858 /* RSSI and unsigned Q7.1 format for RCPI. */
859 u8 rcpi_rssi;
860
861 /* WSM_RX_STATUS_... */
862 __le32 flags;
863
864 /* Payload */
865 u8 data[0];
866} __packed;
867
868/* = sizeof(generic hi hdr) + sizeof(wsm hdr) */
869#define WSM_RX_EXTRA_HEADROOM (16)
870
871typedef void (*wsm_rx_cb) (struct cw1200_common *priv, struct wsm_rx *arg,
872 struct sk_buff **skb_p);
873
874/* 3.17 */
875struct wsm_event {
876 /* WSM_STATUS_... */
877 /* [out] */ u32 id;
878
879 /* Indication parameters. */
880 /* For error indication, this shall be a 32-bit WSM status. */
881 /* For RCPI or RSSI indication, this should be an 8-bit */
882 /* RCPI or RSSI value. */
883 /* [out] */ u32 data;
884};
885
886struct cw1200_wsm_event {
887 struct list_head link;
888 struct wsm_event evt;
889};
890
891/* 3.18 - 3.22 */
892/* Measurement. Skipped for now. Irrelevent. */
893
894typedef void (*wsm_event_cb) (struct cw1200_common *priv,
895 struct wsm_event *arg);
896
897/* 3.23 */
898#define WSM_JOIN_REQ_ID 0x000B
899#define WSM_JOIN_RESP_ID 0x040B
900
901struct wsm_join {
902 /* WSM_JOIN_MODE_... */
903 u8 mode;
904
905 /* WSM_PHY_BAND_... */
906 u8 band;
907
908 /* Specifies the channel number to join. The channel */
909 /* number will be mapped to an actual frequency */
910 /* according to the band */
911 u16 channel_number;
912
913 /* Specifies the BSSID of the BSS or IBSS to be joined */
914 /* or the IBSS to be started. */
915 u8 bssid[6];
916
917 /* ATIM window of IBSS */
918 /* When ATIM window is zero the initiated IBSS does */
919 /* not support power saving. */
920 u16 atim_window;
921
922 /* WSM_JOIN_PREAMBLE_... */
923 u8 preamble_type;
924
925 /* Specifies if a probe request should be send with the */
926 /* specified SSID when joining to the network. */
927 u8 probe_for_join;
928
929 /* DTIM Period (In multiples of beacon interval) */
930 u8 dtim_period;
931
932 /* WSM_JOIN_FLAGS_... */
933 u8 flags;
934
935 /* Length of the SSID */
936 u32 ssid_len;
937
938 /* Specifies the SSID of the IBSS to join or start */
939 u8 ssid[32];
940
941 /* Specifies the time between TBTTs in TUs */
942 u32 beacon_interval;
943
944 /* A bit mask that defines the BSS basic rate set. */
945 u32 basic_rate_set;
946};
947
948struct wsm_join_cnf {
949 u32 status;
950
951 /* Minimum transmission power level in units of 0.1dBm */
952 u32 min_power_level;
953
954 /* Maximum transmission power level in units of 0.1dBm */
955 u32 max_power_level;
956};
957
958int wsm_join(struct cw1200_common *priv, struct wsm_join *arg);
959
960/* 3.24 */
961struct wsm_join_complete {
962 /* WSM_STATUS_... */
963 u32 status;
964};
965
966/* 3.25 */
967#define WSM_SET_PM_REQ_ID 0x0010
968#define WSM_SET_PM_RESP_ID 0x0410
969struct wsm_set_pm {
970 /* WSM_PSM_... */
971 u8 mode;
972
973 /* in unit of 500us; 0 to use default */
974 u8 fast_psm_idle_period;
975
976 /* in unit of 500us; 0 to use default */
977 u8 ap_psm_change_period;
978
979 /* in unit of 500us; 0 to disable auto-pspoll */
980 u8 min_auto_pspoll_period;
981};
982
983int wsm_set_pm(struct cw1200_common *priv, const struct wsm_set_pm *arg);
984
985/* 3.27 */
986struct wsm_set_pm_complete {
987 u8 psm; /* WSM_PSM_... */
988};
989
990/* 3.28 */
991#define WSM_SET_BSS_PARAMS_REQ_ID 0x0011
992#define WSM_SET_BSS_PARAMS_RESP_ID 0x0411
993struct wsm_set_bss_params {
994 /* This resets the beacon loss counters only */
995 u8 reset_beacon_loss;
996
997 /* The number of lost consecutive beacons after which */
998 /* the WLAN device should indicate the BSS-Lost event */
999 /* to the WLAN host driver. */
1000 u8 beacon_lost_count;
1001
1002 /* The AID received during the association process. */
1003 u16 aid;
1004
1005 /* The operational rate set mask */
1006 u32 operational_rate_set;
1007};
1008
1009int wsm_set_bss_params(struct cw1200_common *priv,
1010 const struct wsm_set_bss_params *arg);
1011
1012/* 3.30 */
1013#define WSM_ADD_KEY_REQ_ID 0x000C
1014#define WSM_ADD_KEY_RESP_ID 0x040C
1015struct wsm_add_key {
1016 u8 type; /* WSM_KEY_TYPE_... */
1017 u8 index; /* Key entry index: 0 -- WSM_KEY_MAX_INDEX */
1018 u16 reserved;
1019 union {
1020 struct {
1021 u8 peer[6]; /* MAC address of the peer station */
1022 u8 reserved;
1023 u8 keylen; /* Key length in bytes */
1024 u8 keydata[16]; /* Key data */
1025 } __packed wep_pairwise;
1026 struct {
1027 u8 keyid; /* Unique per key identifier (0..3) */
1028 u8 keylen; /* Key length in bytes */
1029 u16 reserved;
1030 u8 keydata[16]; /* Key data */
1031 } __packed wep_group;
1032 struct {
1033 u8 peer[6]; /* MAC address of the peer station */
1034 u16 reserved;
1035 u8 keydata[16]; /* TKIP key data */
1036 u8 rx_mic_key[8]; /* Rx MIC key */
1037 u8 tx_mic_key[8]; /* Tx MIC key */
1038 } __packed tkip_pairwise;
1039 struct {
1040 u8 keydata[16]; /* TKIP key data */
1041 u8 rx_mic_key[8]; /* Rx MIC key */
1042 u8 keyid; /* Key ID */
1043 u8 reserved[3];
1044 u8 rx_seqnum[8]; /* Receive Sequence Counter */
1045 } __packed tkip_group;
1046 struct {
1047 u8 peer[6]; /* MAC address of the peer station */
1048 u16 reserved;
1049 u8 keydata[16]; /* AES key data */
1050 } __packed aes_pairwise;
1051 struct {
1052 u8 keydata[16]; /* AES key data */
1053 u8 keyid; /* Key ID */
1054 u8 reserved[3];
1055 u8 rx_seqnum[8]; /* Receive Sequence Counter */
1056 } __packed aes_group;
1057 struct {
1058 u8 peer[6]; /* MAC address of the peer station */
1059 u8 keyid; /* Key ID */
1060 u8 reserved;
1061 u8 keydata[16]; /* WAPI key data */
1062 u8 mic_key[16]; /* MIC key data */
1063 } __packed wapi_pairwise;
1064 struct {
1065 u8 keydata[16]; /* WAPI key data */
1066 u8 mic_key[16]; /* MIC key data */
1067 u8 keyid; /* Key ID */
1068 u8 reserved[3];
1069 } __packed wapi_group;
1070 } __packed;
1071} __packed;
1072
1073int wsm_add_key(struct cw1200_common *priv, const struct wsm_add_key *arg);
1074
1075/* 3.32 */
1076#define WSM_REMOVE_KEY_REQ_ID 0x000D
1077#define WSM_REMOVE_KEY_RESP_ID 0x040D
1078struct wsm_remove_key {
1079 u8 index; /* Key entry index : 0-10 */
1080};
1081
1082int wsm_remove_key(struct cw1200_common *priv,
1083 const struct wsm_remove_key *arg);
1084
1085/* 3.34 */
1086struct wsm_set_tx_queue_params {
1087 /* WSM_ACK_POLICY_... */
1088 u8 ackPolicy;
1089
1090 /* Medium Time of TSPEC (in 32us units) allowed per */
1091 /* One Second Averaging Period for this queue. */
1092 u16 allowedMediumTime;
1093
1094 /* dot11MaxTransmitMsduLifetime to be used for the */
1095 /* specified queue. */
1096 u32 maxTransmitLifetime;
1097};
1098
1099struct wsm_tx_queue_params {
1100 /* NOTE: index is a linux queue id. */
1101 struct wsm_set_tx_queue_params params[4];
1102};
1103
1104
1105#define WSM_TX_QUEUE_SET(queue_params, queue, ack_policy, allowed_time,\
1106 max_life_time) \
1107do { \
1108 struct wsm_set_tx_queue_params *p = &(queue_params)->params[queue]; \
1109 p->ackPolicy = (ack_policy); \
1110 p->allowedMediumTime = (allowed_time); \
1111 p->maxTransmitLifetime = (max_life_time); \
1112} while (0)
1113
1114int wsm_set_tx_queue_params(struct cw1200_common *priv,
1115 const struct wsm_set_tx_queue_params *arg, u8 id);
1116
1117/* 3.36 */
1118#define WSM_EDCA_PARAMS_REQ_ID 0x0013
1119#define WSM_EDCA_PARAMS_RESP_ID 0x0413
1120struct wsm_edca_queue_params {
1121 /* CWmin (in slots) for the access class. */
1122 __le16 cwmin;
1123
1124 /* CWmax (in slots) for the access class. */
1125 __le16 cwmax;
1126
1127 /* AIFS (in slots) for the access class. */
1128 __le16 aifns;
1129
1130 /* TX OP Limit (in microseconds) for the access class. */
1131 __le16 txop_limit;
1132
1133 /* dot11MaxReceiveLifetime to be used for the specified */
1134 /* the access class. Overrides the global */
1135 /* dot11MaxReceiveLifetime value */
1136 __le32 max_rx_lifetime;
1137} __packed;
1138
1139struct wsm_edca_params {
1140 /* NOTE: index is a linux queue id. */
1141 struct wsm_edca_queue_params params[4];
1142 bool uapsd_enable[4];
1143};
1144
1145#define TXOP_UNIT 32
1146#define WSM_EDCA_SET(__edca, __queue, __aifs, __cw_min, __cw_max, __txop, __lifetime,\
1147 __uapsd) \
1148 do { \
1149 struct wsm_edca_queue_params *p = &(__edca)->params[__queue]; \
1150 p->cwmin = (__cw_min); \
1151 p->cwmax = (__cw_max); \
1152 p->aifns = (__aifs); \
1153 p->txop_limit = ((__txop) * TXOP_UNIT); \
1154 p->max_rx_lifetime = (__lifetime); \
1155 (__edca)->uapsd_enable[__queue] = (__uapsd); \
1156 } while (0)
1157
1158int wsm_set_edca_params(struct cw1200_common *priv,
1159 const struct wsm_edca_params *arg);
1160
1161int wsm_set_uapsd_param(struct cw1200_common *priv,
1162 const struct wsm_edca_params *arg);
1163
1164/* 3.38 */
1165/* Set-System info. Skipped for now. Irrelevent. */
1166
1167/* 3.40 */
1168#define WSM_SWITCH_CHANNEL_REQ_ID 0x0016
1169#define WSM_SWITCH_CHANNEL_RESP_ID 0x0416
1170
1171struct wsm_switch_channel {
1172 /* 1 - means the STA shall not transmit any further */
1173 /* frames until the channel switch has completed */
1174 u8 mode;
1175
1176 /* Number of TBTTs until channel switch occurs. */
1177 /* 0 - indicates switch shall occur at any time */
1178 /* 1 - occurs immediately before the next TBTT */
1179 u8 switch_count;
1180
1181 /* The new channel number to switch to. */
1182 /* Note this is defined as per section 2.7. */
1183 u16 channel_number;
1184};
1185
1186int wsm_switch_channel(struct cw1200_common *priv,
1187 const struct wsm_switch_channel *arg);
1188
1189typedef void (*wsm_channel_switch_cb) (struct cw1200_common *priv);
1190
1191#define WSM_START_REQ_ID 0x0017
1192#define WSM_START_RESP_ID 0x0417
1193
1194struct wsm_start {
1195 /* WSM_START_MODE_... */
1196 /* [in] */ u8 mode;
1197
1198 /* WSM_PHY_BAND_... */
1199 /* [in] */ u8 band;
1200
1201 /* Channel number */
1202 /* [in] */ u16 channel_number;
1203
1204 /* Client Traffic window in units of TU */
1205 /* Valid only when mode == ..._P2P */
1206 /* [in] */ u32 ct_window;
1207
1208 /* Interval between two consecutive */
1209 /* beacon transmissions in TU. */
1210 /* [in] */ u32 beacon_interval;
1211
1212 /* DTIM period in terms of beacon intervals */
1213 /* [in] */ u8 dtim_period;
1214
1215 /* WSM_JOIN_PREAMBLE_... */
1216 /* [in] */ u8 preamble;
1217
1218 /* The delay time (in microseconds) period */
1219 /* before sending a probe-request. */
1220 /* [in] */ u8 probe_delay;
1221
1222 /* Length of the SSID */
1223 /* [in] */ u8 ssid_len;
1224
1225 /* SSID of the BSS or P2P_GO to be started now. */
1226 /* [in] */ u8 ssid[32];
1227
1228 /* The basic supported rates for the MiniAP. */
1229 /* [in] */ u32 basic_rate_set;
1230};
1231
1232int wsm_start(struct cw1200_common *priv, const struct wsm_start *arg);
1233
1234#define WSM_BEACON_TRANSMIT_REQ_ID 0x0018
1235#define WSM_BEACON_TRANSMIT_RESP_ID 0x0418
1236
1237struct wsm_beacon_transmit {
1238 /* 1: enable; 0: disable */
1239 /* [in] */ u8 enable_beaconing;
1240};
1241
1242int wsm_beacon_transmit(struct cw1200_common *priv,
1243 const struct wsm_beacon_transmit *arg);
1244
1245int wsm_start_find(struct cw1200_common *priv);
1246
1247int wsm_stop_find(struct cw1200_common *priv);
1248
1249typedef void (*wsm_find_complete_cb) (struct cw1200_common *priv, u32 status);
1250
1251struct wsm_suspend_resume {
1252 /* See 3.52 */
1253 /* Link ID */
1254 /* [out] */ int link_id;
1255 /* Stop sending further Tx requests down to device for this link */
1256 /* [out] */ bool stop;
1257 /* Transmit multicast Frames */
1258 /* [out] */ bool multicast;
1259 /* The AC on which Tx to be suspended /resumed. */
1260 /* This is applicable only for U-APSD */
1261 /* WSM_QUEUE_... */
1262 /* [out] */ int queue;
1263};
1264
1265typedef void (*wsm_suspend_resume_cb) (struct cw1200_common *priv,
1266 struct wsm_suspend_resume *arg);
1267
1268/* 3.54 Update-IE request. */
1269struct wsm_update_ie {
1270 /* WSM_UPDATE_IE_... */
1271 /* [in] */ u16 what;
1272 /* [in] */ u16 count;
1273 /* [in] */ u8 *ies;
1274 /* [in] */ size_t length;
1275};
1276
1277int wsm_update_ie(struct cw1200_common *priv,
1278 const struct wsm_update_ie *arg);
1279
1280/* 3.56 */
1281struct wsm_map_link {
1282 /* MAC address of the remote device */
1283 /* [in] */ u8 mac_addr[6];
1284 /* [in] */ u8 link_id;
1285};
1286
1287int wsm_map_link(struct cw1200_common *priv, const struct wsm_map_link *arg);
1288
1289/* ******************************************************************** */
1290/* MIB shortcats */
1291
1292static inline int wsm_set_output_power(struct cw1200_common *priv,
1293 int power_level)
1294{
1295 __le32 val = __cpu_to_le32(power_level);
1296 return wsm_write_mib(priv, WSM_MIB_ID_DOT11_CURRENT_TX_POWER_LEVEL,
1297 &val, sizeof(val));
1298}
1299
1300static inline int wsm_set_beacon_wakeup_period(struct cw1200_common *priv,
1301 unsigned dtim_interval,
1302 unsigned listen_interval)
1303{
1304 struct {
1305 u8 numBeaconPeriods;
1306 u8 reserved;
1307 __le16 listenInterval;
1308 } val = {
1309 dtim_interval, 0, __cpu_to_le16(listen_interval)
1310 };
1311
1312 if (dtim_interval > 0xFF || listen_interval > 0xFFFF)
1313 return -EINVAL;
1314 else
1315 return wsm_write_mib(priv, WSM_MIB_ID_BEACON_WAKEUP_PERIOD,
1316 &val, sizeof(val));
1317}
1318
1319struct wsm_rcpi_rssi_threshold {
1320 u8 rssiRcpiMode; /* WSM_RCPI_RSSI_... */
1321 u8 lowerThreshold;
1322 u8 upperThreshold;
1323 u8 rollingAverageCount;
1324};
1325
1326static inline int wsm_set_rcpi_rssi_threshold(struct cw1200_common *priv,
1327 struct wsm_rcpi_rssi_threshold *arg)
1328{
1329 return wsm_write_mib(priv, WSM_MIB_ID_RCPI_RSSI_THRESHOLD, arg,
1330 sizeof(*arg));
1331}
1332
1333struct wsm_mib_counters_table {
1334 __le32 plcp_errors;
1335 __le32 fcs_errors;
1336 __le32 tx_packets;
1337 __le32 rx_packets;
1338 __le32 rx_packet_errors;
1339 __le32 rx_decryption_failures;
1340 __le32 rx_mic_failures;
1341 __le32 rx_no_key_failures;
1342 __le32 tx_multicast_frames;
1343 __le32 tx_frames_success;
1344 __le32 tx_frame_failures;
1345 __le32 tx_frames_retried;
1346 __le32 tx_frames_multi_retried;
1347 __le32 rx_frame_duplicates;
1348 __le32 rts_success;
1349 __le32 rts_failures;
1350 __le32 ack_failures;
1351 __le32 rx_multicast_frames;
1352 __le32 rx_frames_success;
1353 __le32 rx_cmac_icv_errors;
1354 __le32 rx_cmac_replays;
1355 __le32 rx_mgmt_ccmp_replays;
1356} __packed;
1357
1358static inline int wsm_get_counters_table(struct cw1200_common *priv,
1359 struct wsm_mib_counters_table *arg)
1360{
1361 return wsm_read_mib(priv, WSM_MIB_ID_COUNTERS_TABLE,
1362 arg, sizeof(*arg));
1363}
1364
1365static inline int wsm_get_station_id(struct cw1200_common *priv, u8 *mac)
1366{
1367 return wsm_read_mib(priv, WSM_MIB_ID_DOT11_STATION_ID, mac, ETH_ALEN);
1368}
1369
1370struct wsm_rx_filter {
1371 bool promiscuous;
1372 bool bssid;
1373 bool fcs;
1374 bool probeResponder;
1375};
1376
1377static inline int wsm_set_rx_filter(struct cw1200_common *priv,
1378 const struct wsm_rx_filter *arg)
1379{
1380 __le32 val = 0;
1381 if (arg->promiscuous)
1382 val |= __cpu_to_le32(BIT(0));
1383 if (arg->bssid)
1384 val |= __cpu_to_le32(BIT(1));
1385 if (arg->fcs)
1386 val |= __cpu_to_le32(BIT(2));
1387 if (arg->probeResponder)
1388 val |= __cpu_to_le32(BIT(3));
1389 return wsm_write_mib(priv, WSM_MIB_ID_RX_FILTER, &val, sizeof(val));
1390}
1391
1392int wsm_set_probe_responder(struct cw1200_common *priv, bool enable);
1393
1394#define WSM_BEACON_FILTER_IE_HAS_CHANGED BIT(0)
1395#define WSM_BEACON_FILTER_IE_NO_LONGER_PRESENT BIT(1)
1396#define WSM_BEACON_FILTER_IE_HAS_APPEARED BIT(2)
1397
1398struct wsm_beacon_filter_table_entry {
1399 u8 ie_id;
1400 u8 flags;
1401 u8 oui[3];
1402 u8 match_data[3];
1403} __packed;
1404
1405struct wsm_mib_beacon_filter_table {
1406 __le32 num;
1407 struct wsm_beacon_filter_table_entry entry[10];
1408} __packed;
1409
1410static inline int wsm_set_beacon_filter_table(struct cw1200_common *priv,
1411 struct wsm_mib_beacon_filter_table *ft)
1412{
1413 size_t size = __le32_to_cpu(ft->num) *
1414 sizeof(struct wsm_beacon_filter_table_entry) +
1415 sizeof(__le32);
1416
1417 return wsm_write_mib(priv, WSM_MIB_ID_BEACON_FILTER_TABLE, ft, size);
1418}
1419
1420#define WSM_BEACON_FILTER_ENABLE BIT(0) /* Enable/disable beacon filtering */
1421#define WSM_BEACON_FILTER_AUTO_ERP BIT(1) /* If 1 FW will handle ERP IE changes internally */
1422
1423struct wsm_beacon_filter_control {
1424 int enabled;
1425 int bcn_count;
1426};
1427
1428static inline int wsm_beacon_filter_control(struct cw1200_common *priv,
1429 struct wsm_beacon_filter_control *arg)
1430{
1431 struct {
1432 __le32 enabled;
1433 __le32 bcn_count;
1434 } val;
1435 val.enabled = __cpu_to_le32(arg->enabled);
1436 val.bcn_count = __cpu_to_le32(arg->bcn_count);
1437 return wsm_write_mib(priv, WSM_MIB_ID_BEACON_FILTER_ENABLE, &val,
1438 sizeof(val));
1439}
1440
1441enum wsm_power_mode {
1442 wsm_power_mode_active = 0,
1443 wsm_power_mode_doze = 1,
1444 wsm_power_mode_quiescent = 2,
1445};
1446
1447struct wsm_operational_mode {
1448 enum wsm_power_mode power_mode;
1449 int disable_more_flag_usage;
1450 int perform_ant_diversity;
1451};
1452
1453static inline int wsm_set_operational_mode(struct cw1200_common *priv,
1454 const struct wsm_operational_mode *arg)
1455{
1456 u8 val = arg->power_mode;
1457 if (arg->disable_more_flag_usage)
1458 val |= BIT(4);
1459 if (arg->perform_ant_diversity)
1460 val |= BIT(5);
1461 return wsm_write_mib(priv, WSM_MIB_ID_OPERATIONAL_POWER_MODE, &val,
1462 sizeof(val));
1463}
1464
1465struct wsm_template_frame {
1466 u8 frame_type;
1467 u8 rate;
1468 struct sk_buff *skb;
1469};
1470
1471static inline int wsm_set_template_frame(struct cw1200_common *priv,
1472 struct wsm_template_frame *arg)
1473{
1474 int ret;
1475 u8 *p = skb_push(arg->skb, 4);
1476 p[0] = arg->frame_type;
1477 p[1] = arg->rate;
1478 ((u16 *)p)[1] = __cpu_to_le16(arg->skb->len - 4);
1479 ret = wsm_write_mib(priv, WSM_MIB_ID_TEMPLATE_FRAME, p, arg->skb->len);
1480 skb_pull(arg->skb, 4);
1481 return ret;
1482}
1483
1484
1485struct wsm_protected_mgmt_policy {
1486 bool protectedMgmtEnable;
1487 bool unprotectedMgmtFramesAllowed;
1488 bool encryptionForAuthFrame;
1489};
1490
1491static inline int wsm_set_protected_mgmt_policy(struct cw1200_common *priv,
1492 struct wsm_protected_mgmt_policy *arg)
1493{
1494 __le32 val = 0;
1495 int ret;
1496 if (arg->protectedMgmtEnable)
1497 val |= __cpu_to_le32(BIT(0));
1498 if (arg->unprotectedMgmtFramesAllowed)
1499 val |= __cpu_to_le32(BIT(1));
1500 if (arg->encryptionForAuthFrame)
1501 val |= __cpu_to_le32(BIT(2));
1502 ret = wsm_write_mib(priv, WSM_MIB_ID_PROTECTED_MGMT_POLICY,
1503 &val, sizeof(val));
1504 return ret;
1505}
1506
1507struct wsm_mib_block_ack_policy {
1508 u8 tx_tid;
1509 u8 reserved1;
1510 u8 rx_tid;
1511 u8 reserved2;
1512} __packed;
1513
1514static inline int wsm_set_block_ack_policy(struct cw1200_common *priv,
1515 u8 tx_tid_policy,
1516 u8 rx_tid_policy)
1517{
1518 struct wsm_mib_block_ack_policy val = {
1519 .tx_tid = tx_tid_policy,
1520 .rx_tid = rx_tid_policy,
1521 };
1522 return wsm_write_mib(priv, WSM_MIB_ID_BLOCK_ACK_POLICY, &val,
1523 sizeof(val));
1524}
1525
1526struct wsm_mib_association_mode {
1527 u8 flags; /* WSM_ASSOCIATION_MODE_... */
1528 u8 preamble; /* WSM_JOIN_PREAMBLE_... */
1529 u8 greenfield; /* 1 for greenfield */
1530 u8 mpdu_start_spacing;
1531 __le32 basic_rate_set;
1532} __packed;
1533
1534static inline int wsm_set_association_mode(struct cw1200_common *priv,
1535 struct wsm_mib_association_mode *arg)
1536{
1537 return wsm_write_mib(priv, WSM_MIB_ID_SET_ASSOCIATION_MODE, arg,
1538 sizeof(*arg));
1539}
1540
1541#define WSM_TX_RATE_POLICY_FLAG_TERMINATE_WHEN_FINISHED BIT(2)
1542#define WSM_TX_RATE_POLICY_FLAG_COUNT_INITIAL_TRANSMIT BIT(3)
1543struct wsm_tx_rate_retry_policy {
1544 u8 index;
1545 u8 short_retries;
1546 u8 long_retries;
1547 /* BIT(2) - Terminate retries when Tx rate retry policy
1548 * finishes.
1549 * BIT(3) - Count initial frame transmission as part of
1550 * rate retry counting but not as a retry
1551 * attempt
1552 */
1553 u8 flags;
1554 u8 rate_recoveries;
1555 u8 reserved[3];
1556 __le32 rate_count_indices[3];
1557} __packed;
1558
1559struct wsm_set_tx_rate_retry_policy {
1560 u8 num;
1561 u8 reserved[3];
1562 struct wsm_tx_rate_retry_policy tbl[8];
1563} __packed;
1564
1565static inline int wsm_set_tx_rate_retry_policy(struct cw1200_common *priv,
1566 struct wsm_set_tx_rate_retry_policy *arg)
1567{
1568 size_t size = 4 + arg->num * sizeof(struct wsm_tx_rate_retry_policy);
1569 return wsm_write_mib(priv, WSM_MIB_ID_SET_TX_RATE_RETRY_POLICY, arg,
1570 size);
1571}
1572
1573/* 4.32 SetEtherTypeDataFrameFilter */
1574struct wsm_ether_type_filter_hdr {
1575 u8 num; /* Up to WSM_MAX_FILTER_ELEMENTS */
1576 u8 reserved[3];
1577} __packed;
1578
1579struct wsm_ether_type_filter {
1580 u8 action; /* WSM_FILTER_ACTION_XXX */
1581 u8 reserved;
1582 __le16 type; /* Type of ethernet frame */
1583} __packed;
1584
1585static inline int wsm_set_ether_type_filter(struct cw1200_common *priv,
1586 struct wsm_ether_type_filter_hdr *arg)
1587{
1588 size_t size = sizeof(struct wsm_ether_type_filter_hdr) +
1589 arg->num * sizeof(struct wsm_ether_type_filter);
1590 return wsm_write_mib(priv, WSM_MIB_ID_SET_ETHERTYPE_DATAFRAME_FILTER,
1591 arg, size);
1592}
1593
1594/* 4.33 SetUDPPortDataFrameFilter */
1595struct wsm_udp_port_filter_hdr {
1596 u8 num; /* Up to WSM_MAX_FILTER_ELEMENTS */
1597 u8 reserved[3];
1598} __packed;
1599
1600struct wsm_udp_port_filter {
1601 u8 action; /* WSM_FILTER_ACTION_XXX */
1602 u8 type; /* WSM_FILTER_PORT_TYPE_XXX */
1603 __le16 port; /* Port number */
1604} __packed;
1605
1606static inline int wsm_set_udp_port_filter(struct cw1200_common *priv,
1607 struct wsm_udp_port_filter_hdr *arg)
1608{
1609 size_t size = sizeof(struct wsm_udp_port_filter_hdr) +
1610 arg->num * sizeof(struct wsm_udp_port_filter);
1611 return wsm_write_mib(priv, WSM_MIB_ID_SET_UDPPORT_DATAFRAME_FILTER,
1612 arg, size);
1613}
1614
1615/* Undocumented MIBs: */
1616/* 4.35 P2PDeviceInfo */
1617#define D11_MAX_SSID_LEN (32)
1618
1619struct wsm_p2p_device_type {
1620 __le16 category_id;
1621 u8 oui[4];
1622 __le16 subcategory_id;
1623} __packed;
1624
1625struct wsm_p2p_device_info {
1626 struct wsm_p2p_device_type primaryDevice;
1627 u8 reserved1[3];
1628 u8 devname_size;
1629 u8 local_devname[D11_MAX_SSID_LEN];
1630 u8 reserved2[3];
1631 u8 num_secdev_supported;
1632 struct wsm_p2p_device_type secdevs[0];
1633} __packed;
1634
1635/* 4.36 SetWCDMABand - WO */
1636struct wsm_cdma_band {
1637 u8 wcdma_band;
1638 u8 reserved[3];
1639} __packed;
1640
1641/* 4.37 GroupTxSequenceCounter - RO */
1642struct wsm_group_tx_seq {
1643 __le32 bits_47_16;
1644 __le16 bits_15_00;
1645 __le16 reserved;
1646} __packed;
1647
1648/* 4.39 SetHtProtection - WO */
1649#define WSM_DUAL_CTS_PROT_ENB (1 << 0)
1650#define WSM_NON_GREENFIELD_STA_PRESENT (1 << 1)
1651#define WSM_HT_PROT_MODE__NO_PROT (0 << 2)
1652#define WSM_HT_PROT_MODE__NON_MEMBER (1 << 2)
1653#define WSM_HT_PROT_MODE__20_MHZ (2 << 2)
1654#define WSM_HT_PROT_MODE__NON_HT_MIXED (3 << 2)
1655#define WSM_LSIG_TXOP_PROT_FULL (1 << 4)
1656#define WSM_LARGE_L_LENGTH_PROT (1 << 5)
1657
1658struct wsm_ht_protection {
1659 __le32 flags;
1660} __packed;
1661
1662/* 4.40 GPIO Command - R/W */
1663#define WSM_GPIO_COMMAND_SETUP 0
1664#define WSM_GPIO_COMMAND_READ 1
1665#define WSM_GPIO_COMMAND_WRITE 2
1666#define WSM_GPIO_COMMAND_RESET 3
1667#define WSM_GPIO_ALL_PINS 0xFF
1668
1669struct wsm_gpio_command {
1670 u8 command;
1671 u8 pin;
1672 __le16 config;
1673} __packed;
1674
1675/* 4.41 TSFCounter - RO */
1676struct wsm_tsf_counter {
1677 __le64 tsf_counter;
1678} __packed;
1679
1680/* 4.43 Keep alive period */
1681struct wsm_keep_alive_period {
1682 __le16 period;
1683 u8 reserved[2];
1684} __packed;
1685
1686static inline int wsm_keep_alive_period(struct cw1200_common *priv,
1687 int period)
1688{
1689 struct wsm_keep_alive_period arg = {
1690 .period = __cpu_to_le16(period),
1691 };
1692 return wsm_write_mib(priv, WSM_MIB_ID_KEEP_ALIVE_PERIOD,
1693 &arg, sizeof(arg));
1694};
1695
1696/* BSSID filtering */
1697struct wsm_set_bssid_filtering {
1698 u8 filter;
1699 u8 reserved[3];
1700} __packed;
1701
1702static inline int wsm_set_bssid_filtering(struct cw1200_common *priv,
1703 bool enabled)
1704{
1705 struct wsm_set_bssid_filtering arg = {
1706 .filter = !enabled,
1707 };
1708 return wsm_write_mib(priv, WSM_MIB_ID_DISABLE_BSSID_FILTER,
1709 &arg, sizeof(arg));
1710}
1711
1712/* Multicast filtering - 4.5 */
1713struct wsm_mib_multicast_filter {
1714 __le32 enable;
1715 __le32 num_addrs;
1716 u8 macaddrs[WSM_MAX_GRP_ADDRTABLE_ENTRIES][ETH_ALEN];
1717} __packed;
1718
1719static inline int wsm_set_multicast_filter(struct cw1200_common *priv,
1720 struct wsm_mib_multicast_filter *fp)
1721{
1722 return wsm_write_mib(priv, WSM_MIB_ID_DOT11_GROUP_ADDRESSES_TABLE,
1723 fp, sizeof(*fp));
1724}
1725
1726/* ARP IPv4 filtering - 4.10 */
1727struct wsm_mib_arp_ipv4_filter {
1728 __le32 enable;
1729 __be32 ipv4addrs[WSM_MAX_ARP_IP_ADDRTABLE_ENTRIES];
1730} __packed;
1731
1732static inline int wsm_set_arp_ipv4_filter(struct cw1200_common *priv,
1733 struct wsm_mib_arp_ipv4_filter *fp)
1734{
1735 return wsm_write_mib(priv, WSM_MIB_ID_ARP_IP_ADDRESSES_TABLE,
1736 fp, sizeof(*fp));
1737}
1738
1739/* P2P Power Save Mode Info - 4.31 */
1740struct wsm_p2p_ps_modeinfo {
1741 u8 opp_ps_ct_window;
1742 u8 count;
1743 u8 reserved;
1744 u8 dtim_count;
1745 __le32 duration;
1746 __le32 interval;
1747 __le32 start_time;
1748} __packed;
1749
1750static inline int wsm_set_p2p_ps_modeinfo(struct cw1200_common *priv,
1751 struct wsm_p2p_ps_modeinfo *mi)
1752{
1753 return wsm_write_mib(priv, WSM_MIB_ID_P2P_PS_MODE_INFO,
1754 mi, sizeof(*mi));
1755}
1756
1757static inline int wsm_get_p2p_ps_modeinfo(struct cw1200_common *priv,
1758 struct wsm_p2p_ps_modeinfo *mi)
1759{
1760 return wsm_read_mib(priv, WSM_MIB_ID_P2P_PS_MODE_INFO,
1761 mi, sizeof(*mi));
1762}
1763
1764/* UseMultiTxConfMessage */
1765
1766static inline int wsm_use_multi_tx_conf(struct cw1200_common *priv,
1767 bool enabled)
1768{
1769 __le32 arg = enabled ? __cpu_to_le32(1) : 0;
1770
1771 return wsm_write_mib(priv, WSM_MIB_USE_MULTI_TX_CONF,
1772 &arg, sizeof(arg));
1773}
1774
1775
1776/* 4.26 SetUpasdInformation */
1777struct wsm_uapsd_info {
1778 __le16 uapsd_flags;
1779 __le16 min_auto_trigger_interval;
1780 __le16 max_auto_trigger_interval;
1781 __le16 auto_trigger_step;
1782};
1783
1784static inline int wsm_set_uapsd_info(struct cw1200_common *priv,
1785 struct wsm_uapsd_info *arg)
1786{
1787 return wsm_write_mib(priv, WSM_MIB_ID_SET_UAPSD_INFORMATION,
1788 arg, sizeof(*arg));
1789}
1790
1791/* 4.22 OverrideInternalTxRate */
1792struct wsm_override_internal_txrate {
1793 u8 internalTxRate;
1794 u8 nonErpInternalTxRate;
1795 u8 reserved[2];
1796} __packed;
1797
1798static inline int wsm_set_override_internal_txrate(struct cw1200_common *priv,
1799 struct wsm_override_internal_txrate *arg)
1800{
1801 return wsm_write_mib(priv, WSM_MIB_ID_OVERRIDE_INTERNAL_TX_RATE,
1802 arg, sizeof(*arg));
1803}
1804
1805/* ******************************************************************** */
1806/* WSM TX port control */
1807
1808void wsm_lock_tx(struct cw1200_common *priv);
1809void wsm_lock_tx_async(struct cw1200_common *priv);
1810bool wsm_flush_tx(struct cw1200_common *priv);
1811void wsm_unlock_tx(struct cw1200_common *priv);
1812
1813/* ******************************************************************** */
1814/* WSM / BH API */
1815
1816int wsm_handle_exception(struct cw1200_common *priv, u8 *data, size_t len);
1817int wsm_handle_rx(struct cw1200_common *priv, u16 id, struct wsm_hdr *wsm,
1818 struct sk_buff **skb_p);
1819
1820/* ******************************************************************** */
1821/* wsm_buf API */
1822
1823struct wsm_buf {
1824 u8 *begin;
1825 u8 *data;
1826 u8 *end;
1827};
1828
1829void wsm_buf_init(struct wsm_buf *buf);
1830void wsm_buf_deinit(struct wsm_buf *buf);
1831
1832/* ******************************************************************** */
1833/* wsm_cmd API */
1834
1835struct wsm_cmd {
1836 spinlock_t lock; /* Protect structure from multiple access */
1837 int done;
1838 u8 *ptr;
1839 size_t len;
1840 void *arg;
1841 int ret;
1842 u16 cmd;
1843};
1844
1845/* ******************************************************************** */
1846/* WSM TX buffer access */
1847
1848int wsm_get_tx(struct cw1200_common *priv, u8 **data,
1849 size_t *tx_len, int *burst);
1850void wsm_txed(struct cw1200_common *priv, u8 *data);
1851
1852/* ******************************************************************** */
1853/* Queue mapping: WSM <---> linux */
1854/* Linux: VO VI BE BK */
1855/* WSM: BE BK VI VO */
1856
1857static inline u8 wsm_queue_id_to_linux(u8 queue_id)
1858{
1859 static const u8 queue_mapping[] = {
1860 2, 3, 1, 0
1861 };
1862 return queue_mapping[queue_id];
1863}
1864
1865static inline u8 wsm_queue_id_to_wsm(u8 queue_id)
1866{
1867 static const u8 queue_mapping[] = {
1868 3, 2, 0, 1
1869 };
1870 return queue_mapping[queue_id];
1871}
1872
1873#endif /* CW1200_HWIO_H_INCLUDED */
diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c
index 15920aaa5dd6..f8ab193009cd 100644
--- a/drivers/net/wireless/ipw2x00/ipw2100.c
+++ b/drivers/net/wireless/ipw2x00/ipw2100.c
@@ -6242,8 +6242,6 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
6242 if ((val & 0x0000ff00) != 0) 6242 if ((val & 0x0000ff00) != 0)
6243 pci_write_config_dword(pci_dev, 0x40, val & 0xffff00ff); 6243 pci_write_config_dword(pci_dev, 0x40, val & 0xffff00ff);
6244 6244
6245 pci_set_power_state(pci_dev, PCI_D0);
6246
6247 if (!ipw2100_hw_is_adapter_in_system(dev)) { 6245 if (!ipw2100_hw_is_adapter_in_system(dev)) {
6248 printk(KERN_WARNING DRV_NAME 6246 printk(KERN_WARNING DRV_NAME
6249 "Device not found via register read.\n"); 6247 "Device not found via register read.\n");
diff --git a/drivers/net/wireless/iwlegacy/commands.h b/drivers/net/wireless/iwlegacy/commands.h
index 3b6c99400892..048421511988 100644
--- a/drivers/net/wireless/iwlegacy/commands.h
+++ b/drivers/net/wireless/iwlegacy/commands.h
@@ -1348,14 +1348,6 @@ struct il_rx_mpdu_res_start {
1348#define TX_CMD_SEC_KEY128 0x08 1348#define TX_CMD_SEC_KEY128 0x08
1349 1349
1350/* 1350/*
1351 * security overhead sizes
1352 */
1353#define WEP_IV_LEN 4
1354#define WEP_ICV_LEN 4
1355#define CCMP_MIC_LEN 8
1356#define TKIP_ICV_LEN 4
1357
1358/*
1359 * C_TX = 0x1c (command) 1351 * C_TX = 0x1c (command)
1360 */ 1352 */
1361 1353
diff --git a/drivers/net/wireless/iwlwifi/dvm/agn.h b/drivers/net/wireless/iwlwifi/dvm/agn.h
index 48545ab00311..de2c9514bef6 100644
--- a/drivers/net/wireless/iwlwifi/dvm/agn.h
+++ b/drivers/net/wireless/iwlwifi/dvm/agn.h
@@ -76,13 +76,16 @@
76#define IWL_INVALID_STATION 255 76#define IWL_INVALID_STATION 255
77 77
78/* device operations */ 78/* device operations */
79extern struct iwl_lib_ops iwl1000_lib; 79extern const struct iwl_dvm_cfg iwl_dvm_1000_cfg;
80extern struct iwl_lib_ops iwl2000_lib; 80extern const struct iwl_dvm_cfg iwl_dvm_2000_cfg;
81extern struct iwl_lib_ops iwl2030_lib; 81extern const struct iwl_dvm_cfg iwl_dvm_105_cfg;
82extern struct iwl_lib_ops iwl5000_lib; 82extern const struct iwl_dvm_cfg iwl_dvm_2030_cfg;
83extern struct iwl_lib_ops iwl5150_lib; 83extern const struct iwl_dvm_cfg iwl_dvm_5000_cfg;
84extern struct iwl_lib_ops iwl6000_lib; 84extern const struct iwl_dvm_cfg iwl_dvm_5150_cfg;
85extern struct iwl_lib_ops iwl6030_lib; 85extern const struct iwl_dvm_cfg iwl_dvm_6000_cfg;
86extern const struct iwl_dvm_cfg iwl_dvm_6005_cfg;
87extern const struct iwl_dvm_cfg iwl_dvm_6050_cfg;
88extern const struct iwl_dvm_cfg iwl_dvm_6030_cfg;
86 89
87 90
88#define TIME_UNIT 1024 91#define TIME_UNIT 1024
@@ -291,8 +294,8 @@ void iwlagn_bt_adjust_rssi_monitor(struct iwl_priv *priv, bool rssi_ena);
291 294
292static inline bool iwl_advanced_bt_coexist(struct iwl_priv *priv) 295static inline bool iwl_advanced_bt_coexist(struct iwl_priv *priv)
293{ 296{
294 return priv->cfg->bt_params && 297 return priv->lib->bt_params &&
295 priv->cfg->bt_params->advanced_bt_coexist; 298 priv->lib->bt_params->advanced_bt_coexist;
296} 299}
297 300
298#ifdef CONFIG_IWLWIFI_DEBUG 301#ifdef CONFIG_IWLWIFI_DEBUG
diff --git a/drivers/net/wireless/iwlwifi/dvm/calib.c b/drivers/net/wireless/iwlwifi/dvm/calib.c
index d6c4cf2ad7c5..1b0f0d502568 100644
--- a/drivers/net/wireless/iwlwifi/dvm/calib.c
+++ b/drivers/net/wireless/iwlwifi/dvm/calib.c
@@ -521,7 +521,7 @@ static int iwl_enhance_sensitivity_write(struct iwl_priv *priv)
521 521
522 iwl_prepare_legacy_sensitivity_tbl(priv, data, &cmd.enhance_table[0]); 522 iwl_prepare_legacy_sensitivity_tbl(priv, data, &cmd.enhance_table[0]);
523 523
524 if (priv->cfg->base_params->hd_v2) { 524 if (priv->lib->hd_v2) {
525 cmd.enhance_table[HD_INA_NON_SQUARE_DET_OFDM_INDEX] = 525 cmd.enhance_table[HD_INA_NON_SQUARE_DET_OFDM_INDEX] =
526 HD_INA_NON_SQUARE_DET_OFDM_DATA_V2; 526 HD_INA_NON_SQUARE_DET_OFDM_DATA_V2;
527 cmd.enhance_table[HD_INA_NON_SQUARE_DET_CCK_INDEX] = 527 cmd.enhance_table[HD_INA_NON_SQUARE_DET_CCK_INDEX] =
@@ -895,7 +895,7 @@ static void iwlagn_gain_computation(struct iwl_priv *priv,
895 continue; 895 continue;
896 } 896 }
897 897
898 delta_g = (priv->cfg->base_params->chain_noise_scale * 898 delta_g = (priv->lib->chain_noise_scale *
899 ((s32)average_noise[default_chain] - 899 ((s32)average_noise[default_chain] -
900 (s32)average_noise[i])) / 1500; 900 (s32)average_noise[i])) / 1500;
901 901
@@ -1051,8 +1051,8 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv)
1051 return; 1051 return;
1052 1052
1053 /* Analyze signal for disconnected antenna */ 1053 /* Analyze signal for disconnected antenna */
1054 if (priv->cfg->bt_params && 1054 if (priv->lib->bt_params &&
1055 priv->cfg->bt_params->advanced_bt_coexist) { 1055 priv->lib->bt_params->advanced_bt_coexist) {
1056 /* Disable disconnected antenna algorithm for advanced 1056 /* Disable disconnected antenna algorithm for advanced
1057 bt coex, assuming valid antennas are connected */ 1057 bt coex, assuming valid antennas are connected */
1058 data->active_chains = priv->nvm_data->valid_rx_ant; 1058 data->active_chains = priv->nvm_data->valid_rx_ant;
diff --git a/drivers/net/wireless/iwlwifi/dvm/commands.h b/drivers/net/wireless/iwlwifi/dvm/commands.h
index 95ca026ecc9d..ebdac909f0cd 100644
--- a/drivers/net/wireless/iwlwifi/dvm/commands.h
+++ b/drivers/net/wireless/iwlwifi/dvm/commands.h
@@ -838,10 +838,6 @@ struct iwl_qosparam_cmd {
838#define STA_MODIFY_DELBA_TID_MSK 0x10 838#define STA_MODIFY_DELBA_TID_MSK 0x10
839#define STA_MODIFY_SLEEP_TX_COUNT_MSK 0x20 839#define STA_MODIFY_SLEEP_TX_COUNT_MSK 0x20
840 840
841/* Receiver address (actually, Rx station's index into station table),
842 * combined with Traffic ID (QOS priority), in format used by Tx Scheduler */
843#define BUILD_RAxTID(sta_id, tid) (((sta_id) << 4) + (tid))
844
845/* agn */ 841/* agn */
846struct iwl_keyinfo { 842struct iwl_keyinfo {
847 __le16 key_flags; 843 __le16 key_flags;
@@ -1225,14 +1221,6 @@ struct iwl_rx_mpdu_res_start {
1225#define TX_CMD_SEC_KEY128 0x08 1221#define TX_CMD_SEC_KEY128 0x08
1226 1222
1227/* 1223/*
1228 * security overhead sizes
1229 */
1230#define WEP_IV_LEN 4
1231#define WEP_ICV_LEN 4
1232#define CCMP_MIC_LEN 8
1233#define TKIP_ICV_LEN 4
1234
1235/*
1236 * REPLY_TX = 0x1c (command) 1224 * REPLY_TX = 0x1c (command)
1237 */ 1225 */
1238 1226
diff --git a/drivers/net/wireless/iwlwifi/dvm/dev.h b/drivers/net/wireless/iwlwifi/dvm/dev.h
index 71ea77576d22..f1b8df16dbba 100644
--- a/drivers/net/wireless/iwlwifi/dvm/dev.h
+++ b/drivers/net/wireless/iwlwifi/dvm/dev.h
@@ -568,16 +568,61 @@ struct iwl_hw_params {
568 const struct iwl_sensitivity_ranges *sens; 568 const struct iwl_sensitivity_ranges *sens;
569}; 569};
570 570
571struct iwl_lib_ops { 571/**
572 /* set hw dependent parameters */ 572 * struct iwl_dvm_bt_params - DVM specific BT (coex) parameters
573 * @advanced_bt_coexist: support advanced bt coexist
574 * @bt_init_traffic_load: specify initial bt traffic load
575 * @bt_prio_boost: default bt priority boost value
576 * @agg_time_limit: maximum number of uSec in aggregation
577 * @bt_sco_disable: uCode should not response to BT in SCO/ESCO mode
578 */
579struct iwl_dvm_bt_params {
580 bool advanced_bt_coexist;
581 u8 bt_init_traffic_load;
582 u32 bt_prio_boost;
583 u16 agg_time_limit;
584 bool bt_sco_disable;
585 bool bt_session_2;
586};
587
588/**
589 * struct iwl_dvm_cfg - DVM firmware specific device configuration
590 * @set_hw_params: set hardware parameters
591 * @set_channel_switch: send channel switch command
592 * @nic_config: apply device specific configuration
593 * @temperature: read temperature
594 * @adv_thermal_throttle: support advance thermal throttle
595 * @support_ct_kill_exit: support ct kill exit condition
596 * @plcp_delta_threshold: plcp error rate threshold used to trigger
597 * radio tuning when there is a high receiving plcp error rate
598 * @chain_noise_scale: default chain noise scale used for gain computation
599 * @hd_v2: v2 of enhanced sensitivity value, used for 2000 series and up
600 * @no_idle_support: do not support idle mode
601 * @bt_params: pointer to BT parameters
602 * @need_temp_offset_calib: need to perform temperature offset calibration
603 * @no_xtal_calib: some devices do not need crystal calibration data,
604 * don't send it to those
605 * @temp_offset_v2: support v2 of temperature offset calibration
606 * @adv_pm: advanced power management
607 */
608struct iwl_dvm_cfg {
573 void (*set_hw_params)(struct iwl_priv *priv); 609 void (*set_hw_params)(struct iwl_priv *priv);
574 int (*set_channel_switch)(struct iwl_priv *priv, 610 int (*set_channel_switch)(struct iwl_priv *priv,
575 struct ieee80211_channel_switch *ch_switch); 611 struct ieee80211_channel_switch *ch_switch);
576 /* device specific configuration */
577 void (*nic_config)(struct iwl_priv *priv); 612 void (*nic_config)(struct iwl_priv *priv);
578
579 /* temperature */
580 void (*temperature)(struct iwl_priv *priv); 613 void (*temperature)(struct iwl_priv *priv);
614
615 const struct iwl_dvm_bt_params *bt_params;
616 s32 chain_noise_scale;
617 u8 plcp_delta_threshold;
618 bool adv_thermal_throttle;
619 bool support_ct_kill_exit;
620 bool hd_v2;
621 bool no_idle_support;
622 bool need_temp_offset_calib;
623 bool no_xtal_calib;
624 bool temp_offset_v2;
625 bool adv_pm;
581}; 626};
582 627
583struct iwl_wipan_noa_data { 628struct iwl_wipan_noa_data {
@@ -610,7 +655,7 @@ struct iwl_priv {
610 struct device *dev; /* for debug prints only */ 655 struct device *dev; /* for debug prints only */
611 const struct iwl_cfg *cfg; 656 const struct iwl_cfg *cfg;
612 const struct iwl_fw *fw; 657 const struct iwl_fw *fw;
613 const struct iwl_lib_ops *lib; 658 const struct iwl_dvm_cfg *lib;
614 unsigned long status; 659 unsigned long status;
615 660
616 spinlock_t sta_lock; 661 spinlock_t sta_lock;
diff --git a/drivers/net/wireless/iwlwifi/dvm/devices.c b/drivers/net/wireless/iwlwifi/dvm/devices.c
index c48907c8ab43..352c6cb7b4f1 100644
--- a/drivers/net/wireless/iwlwifi/dvm/devices.c
+++ b/drivers/net/wireless/iwlwifi/dvm/devices.c
@@ -174,10 +174,13 @@ static void iwl1000_hw_set_hw_params(struct iwl_priv *priv)
174 priv->hw_params.sens = &iwl1000_sensitivity; 174 priv->hw_params.sens = &iwl1000_sensitivity;
175} 175}
176 176
177struct iwl_lib_ops iwl1000_lib = { 177const struct iwl_dvm_cfg iwl_dvm_1000_cfg = {
178 .set_hw_params = iwl1000_hw_set_hw_params, 178 .set_hw_params = iwl1000_hw_set_hw_params,
179 .nic_config = iwl1000_nic_config, 179 .nic_config = iwl1000_nic_config,
180 .temperature = iwlagn_temperature, 180 .temperature = iwlagn_temperature,
181 .support_ct_kill_exit = true,
182 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF,
183 .chain_noise_scale = 1000,
181}; 184};
182 185
183 186
@@ -232,16 +235,56 @@ static void iwl2000_hw_set_hw_params(struct iwl_priv *priv)
232 priv->hw_params.sens = &iwl2000_sensitivity; 235 priv->hw_params.sens = &iwl2000_sensitivity;
233} 236}
234 237
235struct iwl_lib_ops iwl2000_lib = { 238const struct iwl_dvm_cfg iwl_dvm_2000_cfg = {
236 .set_hw_params = iwl2000_hw_set_hw_params, 239 .set_hw_params = iwl2000_hw_set_hw_params,
237 .nic_config = iwl2000_nic_config, 240 .nic_config = iwl2000_nic_config,
238 .temperature = iwlagn_temperature, 241 .temperature = iwlagn_temperature,
242 .adv_thermal_throttle = true,
243 .support_ct_kill_exit = true,
244 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
245 .chain_noise_scale = 1000,
246 .hd_v2 = true,
247 .need_temp_offset_calib = true,
248 .temp_offset_v2 = true,
239}; 249};
240 250
241struct iwl_lib_ops iwl2030_lib = { 251const struct iwl_dvm_cfg iwl_dvm_105_cfg = {
242 .set_hw_params = iwl2000_hw_set_hw_params, 252 .set_hw_params = iwl2000_hw_set_hw_params,
243 .nic_config = iwl2000_nic_config, 253 .nic_config = iwl2000_nic_config,
244 .temperature = iwlagn_temperature, 254 .temperature = iwlagn_temperature,
255 .adv_thermal_throttle = true,
256 .support_ct_kill_exit = true,
257 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
258 .chain_noise_scale = 1000,
259 .hd_v2 = true,
260 .need_temp_offset_calib = true,
261 .temp_offset_v2 = true,
262 .adv_pm = true,
263};
264
265static const struct iwl_dvm_bt_params iwl2030_bt_params = {
266 /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
267 .advanced_bt_coexist = true,
268 .agg_time_limit = BT_AGG_THRESHOLD_DEF,
269 .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE,
270 .bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT32,
271 .bt_sco_disable = true,
272 .bt_session_2 = true,
273};
274
275const struct iwl_dvm_cfg iwl_dvm_2030_cfg = {
276 .set_hw_params = iwl2000_hw_set_hw_params,
277 .nic_config = iwl2000_nic_config,
278 .temperature = iwlagn_temperature,
279 .adv_thermal_throttle = true,
280 .support_ct_kill_exit = true,
281 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
282 .chain_noise_scale = 1000,
283 .hd_v2 = true,
284 .bt_params = &iwl2030_bt_params,
285 .need_temp_offset_calib = true,
286 .temp_offset_v2 = true,
287 .adv_pm = true,
245}; 288};
246 289
247/* 290/*
@@ -420,16 +463,23 @@ static int iwl5000_hw_channel_switch(struct iwl_priv *priv,
420 return iwl_dvm_send_cmd(priv, &hcmd); 463 return iwl_dvm_send_cmd(priv, &hcmd);
421} 464}
422 465
423struct iwl_lib_ops iwl5000_lib = { 466const struct iwl_dvm_cfg iwl_dvm_5000_cfg = {
424 .set_hw_params = iwl5000_hw_set_hw_params, 467 .set_hw_params = iwl5000_hw_set_hw_params,
425 .set_channel_switch = iwl5000_hw_channel_switch, 468 .set_channel_switch = iwl5000_hw_channel_switch,
426 .temperature = iwlagn_temperature, 469 .temperature = iwlagn_temperature,
470 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
471 .chain_noise_scale = 1000,
472 .no_idle_support = true,
427}; 473};
428 474
429struct iwl_lib_ops iwl5150_lib = { 475const struct iwl_dvm_cfg iwl_dvm_5150_cfg = {
430 .set_hw_params = iwl5150_hw_set_hw_params, 476 .set_hw_params = iwl5150_hw_set_hw_params,
431 .set_channel_switch = iwl5000_hw_channel_switch, 477 .set_channel_switch = iwl5000_hw_channel_switch,
432 .temperature = iwl5150_temperature, 478 .temperature = iwl5150_temperature,
479 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
480 .chain_noise_scale = 1000,
481 .no_idle_support = true,
482 .no_xtal_calib = true,
433}; 483};
434 484
435 485
@@ -584,16 +634,59 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv,
584 return err; 634 return err;
585} 635}
586 636
587struct iwl_lib_ops iwl6000_lib = { 637const struct iwl_dvm_cfg iwl_dvm_6000_cfg = {
588 .set_hw_params = iwl6000_hw_set_hw_params, 638 .set_hw_params = iwl6000_hw_set_hw_params,
589 .set_channel_switch = iwl6000_hw_channel_switch, 639 .set_channel_switch = iwl6000_hw_channel_switch,
590 .nic_config = iwl6000_nic_config, 640 .nic_config = iwl6000_nic_config,
591 .temperature = iwlagn_temperature, 641 .temperature = iwlagn_temperature,
642 .adv_thermal_throttle = true,
643 .support_ct_kill_exit = true,
644 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
645 .chain_noise_scale = 1000,
646};
647
648const struct iwl_dvm_cfg iwl_dvm_6005_cfg = {
649 .set_hw_params = iwl6000_hw_set_hw_params,
650 .set_channel_switch = iwl6000_hw_channel_switch,
651 .nic_config = iwl6000_nic_config,
652 .temperature = iwlagn_temperature,
653 .adv_thermal_throttle = true,
654 .support_ct_kill_exit = true,
655 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
656 .chain_noise_scale = 1000,
657 .need_temp_offset_calib = true,
658};
659
660const struct iwl_dvm_cfg iwl_dvm_6050_cfg = {
661 .set_hw_params = iwl6000_hw_set_hw_params,
662 .set_channel_switch = iwl6000_hw_channel_switch,
663 .nic_config = iwl6000_nic_config,
664 .temperature = iwlagn_temperature,
665 .adv_thermal_throttle = true,
666 .support_ct_kill_exit = true,
667 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
668 .chain_noise_scale = 1500,
669};
670
671static const struct iwl_dvm_bt_params iwl6000_bt_params = {
672 /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
673 .advanced_bt_coexist = true,
674 .agg_time_limit = BT_AGG_THRESHOLD_DEF,
675 .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE,
676 .bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT,
677 .bt_sco_disable = true,
592}; 678};
593 679
594struct iwl_lib_ops iwl6030_lib = { 680const struct iwl_dvm_cfg iwl_dvm_6030_cfg = {
595 .set_hw_params = iwl6000_hw_set_hw_params, 681 .set_hw_params = iwl6000_hw_set_hw_params,
596 .set_channel_switch = iwl6000_hw_channel_switch, 682 .set_channel_switch = iwl6000_hw_channel_switch,
597 .nic_config = iwl6000_nic_config, 683 .nic_config = iwl6000_nic_config,
598 .temperature = iwlagn_temperature, 684 .temperature = iwlagn_temperature,
685 .adv_thermal_throttle = true,
686 .support_ct_kill_exit = true,
687 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
688 .chain_noise_scale = 1000,
689 .bt_params = &iwl6000_bt_params,
690 .need_temp_offset_calib = true,
691 .adv_pm = true,
599}; 692};
diff --git a/drivers/net/wireless/iwlwifi/dvm/lib.c b/drivers/net/wireless/iwlwifi/dvm/lib.c
index 54f553380aa8..9879550a0fea 100644
--- a/drivers/net/wireless/iwlwifi/dvm/lib.c
+++ b/drivers/net/wireless/iwlwifi/dvm/lib.c
@@ -254,23 +254,23 @@ void iwlagn_send_advance_bt_config(struct iwl_priv *priv)
254 BUILD_BUG_ON(sizeof(iwlagn_def_3w_lookup) != 254 BUILD_BUG_ON(sizeof(iwlagn_def_3w_lookup) !=
255 sizeof(basic.bt3_lookup_table)); 255 sizeof(basic.bt3_lookup_table));
256 256
257 if (priv->cfg->bt_params) { 257 if (priv->lib->bt_params) {
258 /* 258 /*
259 * newer generation of devices (2000 series and newer) 259 * newer generation of devices (2000 series and newer)
260 * use the version 2 of the bt command 260 * use the version 2 of the bt command
261 * we need to make sure sending the host command 261 * we need to make sure sending the host command
262 * with correct data structure to avoid uCode assert 262 * with correct data structure to avoid uCode assert
263 */ 263 */
264 if (priv->cfg->bt_params->bt_session_2) { 264 if (priv->lib->bt_params->bt_session_2) {
265 bt_cmd_v2.prio_boost = cpu_to_le32( 265 bt_cmd_v2.prio_boost = cpu_to_le32(
266 priv->cfg->bt_params->bt_prio_boost); 266 priv->lib->bt_params->bt_prio_boost);
267 bt_cmd_v2.tx_prio_boost = 0; 267 bt_cmd_v2.tx_prio_boost = 0;
268 bt_cmd_v2.rx_prio_boost = 0; 268 bt_cmd_v2.rx_prio_boost = 0;
269 } else { 269 } else {
270 /* older version only has 8 bits */ 270 /* older version only has 8 bits */
271 WARN_ON(priv->cfg->bt_params->bt_prio_boost & ~0xFF); 271 WARN_ON(priv->lib->bt_params->bt_prio_boost & ~0xFF);
272 bt_cmd_v1.prio_boost = 272 bt_cmd_v1.prio_boost =
273 priv->cfg->bt_params->bt_prio_boost; 273 priv->lib->bt_params->bt_prio_boost;
274 bt_cmd_v1.tx_prio_boost = 0; 274 bt_cmd_v1.tx_prio_boost = 0;
275 bt_cmd_v1.rx_prio_boost = 0; 275 bt_cmd_v1.rx_prio_boost = 0;
276 } 276 }
@@ -330,7 +330,7 @@ void iwlagn_send_advance_bt_config(struct iwl_priv *priv)
330 priv->bt_full_concurrent ? 330 priv->bt_full_concurrent ?
331 "full concurrency" : "3-wire"); 331 "full concurrency" : "3-wire");
332 332
333 if (priv->cfg->bt_params->bt_session_2) { 333 if (priv->lib->bt_params->bt_session_2) {
334 memcpy(&bt_cmd_v2.basic, &basic, 334 memcpy(&bt_cmd_v2.basic, &basic,
335 sizeof(basic)); 335 sizeof(basic));
336 ret = iwl_dvm_send_cmd_pdu(priv, REPLY_BT_CONFIG, 336 ret = iwl_dvm_send_cmd_pdu(priv, REPLY_BT_CONFIG,
@@ -758,8 +758,8 @@ static bool is_single_rx_stream(struct iwl_priv *priv)
758 */ 758 */
759static int iwl_get_active_rx_chain_count(struct iwl_priv *priv) 759static int iwl_get_active_rx_chain_count(struct iwl_priv *priv)
760{ 760{
761 if (priv->cfg->bt_params && 761 if (priv->lib->bt_params &&
762 priv->cfg->bt_params->advanced_bt_coexist && 762 priv->lib->bt_params->advanced_bt_coexist &&
763 (priv->bt_full_concurrent || 763 (priv->bt_full_concurrent ||
764 priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)) { 764 priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)) {
765 /* 765 /*
@@ -830,8 +830,8 @@ void iwlagn_set_rxon_chain(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
830 else 830 else
831 active_chains = priv->nvm_data->valid_rx_ant; 831 active_chains = priv->nvm_data->valid_rx_ant;
832 832
833 if (priv->cfg->bt_params && 833 if (priv->lib->bt_params &&
834 priv->cfg->bt_params->advanced_bt_coexist && 834 priv->lib->bt_params->advanced_bt_coexist &&
835 (priv->bt_full_concurrent || 835 (priv->bt_full_concurrent ||
836 priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)) { 836 priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)) {
837 /* 837 /*
diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
index cab23af0be9e..c0039a992909 100644
--- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
@@ -426,7 +426,11 @@ static int iwlagn_mac_suspend(struct ieee80211_hw *hw,
426 if (ret) 426 if (ret)
427 goto error; 427 goto error;
428 428
429 iwl_trans_d3_suspend(priv->trans); 429 /* let the ucode operate on its own */
430 iwl_write32(priv->trans, CSR_UCODE_DRV_GP1_SET,
431 CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE);
432
433 iwl_trans_d3_suspend(priv->trans, false);
430 434
431 goto out; 435 goto out;
432 436
@@ -500,7 +504,7 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw)
500 /* we'll clear ctx->vif during iwlagn_prepare_restart() */ 504 /* we'll clear ctx->vif during iwlagn_prepare_restart() */
501 vif = ctx->vif; 505 vif = ctx->vif;
502 506
503 ret = iwl_trans_d3_resume(priv->trans, &d3_status); 507 ret = iwl_trans_d3_resume(priv->trans, &d3_status, false);
504 if (ret) 508 if (ret)
505 goto out_unlock; 509 goto out_unlock;
506 510
@@ -509,6 +513,10 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw)
509 goto out_unlock; 513 goto out_unlock;
510 } 514 }
511 515
516 /* uCode is no longer operating by itself */
517 iwl_write32(priv->trans, CSR_UCODE_DRV_GP1_CLR,
518 CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE);
519
512 base = priv->device_pointers.error_event_table; 520 base = priv->device_pointers.error_event_table;
513 if (!iwlagn_hw_valid_rtc_data_addr(base)) { 521 if (!iwlagn_hw_valid_rtc_data_addr(base)) {
514 IWL_WARN(priv, "Invalid error table during resume!\n"); 522 IWL_WARN(priv, "Invalid error table during resume!\n");
@@ -1276,8 +1284,8 @@ static void iwlagn_mac_rssi_callback(struct ieee80211_hw *hw,
1276 IWL_DEBUG_MAC80211(priv, "enter\n"); 1284 IWL_DEBUG_MAC80211(priv, "enter\n");
1277 mutex_lock(&priv->mutex); 1285 mutex_lock(&priv->mutex);
1278 1286
1279 if (priv->cfg->bt_params && 1287 if (priv->lib->bt_params &&
1280 priv->cfg->bt_params->advanced_bt_coexist) { 1288 priv->lib->bt_params->advanced_bt_coexist) {
1281 if (rssi_event == RSSI_EVENT_LOW) 1289 if (rssi_event == RSSI_EVENT_LOW)
1282 priv->bt_enable_pspoll = true; 1290 priv->bt_enable_pspoll = true;
1283 else if (rssi_event == RSSI_EVENT_HIGH) 1291 else if (rssi_event == RSSI_EVENT_HIGH)
@@ -1387,7 +1395,7 @@ static int iwl_setup_interface(struct iwl_priv *priv,
1387 return err; 1395 return err;
1388 } 1396 }
1389 1397
1390 if (priv->cfg->bt_params && priv->cfg->bt_params->advanced_bt_coexist && 1398 if (priv->lib->bt_params && priv->lib->bt_params->advanced_bt_coexist &&
1391 vif->type == NL80211_IFTYPE_ADHOC) { 1399 vif->type == NL80211_IFTYPE_ADHOC) {
1392 /* 1400 /*
1393 * pretend to have high BT traffic as long as we 1401 * pretend to have high BT traffic as long as we
diff --git a/drivers/net/wireless/iwlwifi/dvm/main.c b/drivers/net/wireless/iwlwifi/dvm/main.c
index 74d7572e7091..68f754659570 100644
--- a/drivers/net/wireless/iwlwifi/dvm/main.c
+++ b/drivers/net/wireless/iwlwifi/dvm/main.c
@@ -615,7 +615,7 @@ static void iwl_rf_kill_ct_config(struct iwl_priv *priv)
615 615
616 priv->thermal_throttle.ct_kill_toggle = false; 616 priv->thermal_throttle.ct_kill_toggle = false;
617 617
618 if (priv->cfg->base_params->support_ct_kill_exit) { 618 if (priv->lib->support_ct_kill_exit) {
619 adv_cmd.critical_temperature_enter = 619 adv_cmd.critical_temperature_enter =
620 cpu_to_le32(priv->hw_params.ct_kill_threshold); 620 cpu_to_le32(priv->hw_params.ct_kill_threshold);
621 adv_cmd.critical_temperature_exit = 621 adv_cmd.critical_temperature_exit =
@@ -732,10 +732,10 @@ int iwl_alive_start(struct iwl_priv *priv)
732 } 732 }
733 733
734 /* download priority table before any calibration request */ 734 /* download priority table before any calibration request */
735 if (priv->cfg->bt_params && 735 if (priv->lib->bt_params &&
736 priv->cfg->bt_params->advanced_bt_coexist) { 736 priv->lib->bt_params->advanced_bt_coexist) {
737 /* Configure Bluetooth device coexistence support */ 737 /* Configure Bluetooth device coexistence support */
738 if (priv->cfg->bt_params->bt_sco_disable) 738 if (priv->lib->bt_params->bt_sco_disable)
739 priv->bt_enable_pspoll = false; 739 priv->bt_enable_pspoll = false;
740 else 740 else
741 priv->bt_enable_pspoll = true; 741 priv->bt_enable_pspoll = true;
@@ -873,9 +873,9 @@ void iwl_down(struct iwl_priv *priv)
873 priv->bt_status = 0; 873 priv->bt_status = 0;
874 priv->cur_rssi_ctx = NULL; 874 priv->cur_rssi_ctx = NULL;
875 priv->bt_is_sco = 0; 875 priv->bt_is_sco = 0;
876 if (priv->cfg->bt_params) 876 if (priv->lib->bt_params)
877 priv->bt_traffic_load = 877 priv->bt_traffic_load =
878 priv->cfg->bt_params->bt_init_traffic_load; 878 priv->lib->bt_params->bt_init_traffic_load;
879 else 879 else
880 priv->bt_traffic_load = 0; 880 priv->bt_traffic_load = 0;
881 priv->bt_full_concurrent = false; 881 priv->bt_full_concurrent = false;
@@ -1058,7 +1058,7 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
1058 1058
1059 iwl_setup_scan_deferred_work(priv); 1059 iwl_setup_scan_deferred_work(priv);
1060 1060
1061 if (priv->cfg->bt_params) 1061 if (priv->lib->bt_params)
1062 iwlagn_bt_setup_deferred_work(priv); 1062 iwlagn_bt_setup_deferred_work(priv);
1063 1063
1064 init_timer(&priv->statistics_periodic); 1064 init_timer(&priv->statistics_periodic);
@@ -1072,7 +1072,7 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
1072 1072
1073void iwl_cancel_deferred_work(struct iwl_priv *priv) 1073void iwl_cancel_deferred_work(struct iwl_priv *priv)
1074{ 1074{
1075 if (priv->cfg->bt_params) 1075 if (priv->lib->bt_params)
1076 iwlagn_bt_cancel_deferred_work(priv); 1076 iwlagn_bt_cancel_deferred_work(priv);
1077 1077
1078 cancel_work_sync(&priv->run_time_calib_work); 1078 cancel_work_sync(&priv->run_time_calib_work);
@@ -1098,8 +1098,7 @@ static int iwl_init_drv(struct iwl_priv *priv)
1098 1098
1099 priv->band = IEEE80211_BAND_2GHZ; 1099 priv->band = IEEE80211_BAND_2GHZ;
1100 1100
1101 priv->plcp_delta_threshold = 1101 priv->plcp_delta_threshold = priv->lib->plcp_delta_threshold;
1102 priv->cfg->base_params->plcp_delta_threshold;
1103 1102
1104 priv->iw_mode = NL80211_IFTYPE_STATION; 1103 priv->iw_mode = NL80211_IFTYPE_STATION;
1105 priv->current_ht_config.smps = IEEE80211_SMPS_STATIC; 1104 priv->current_ht_config.smps = IEEE80211_SMPS_STATIC;
@@ -1116,8 +1115,8 @@ static int iwl_init_drv(struct iwl_priv *priv)
1116 iwl_init_scan_params(priv); 1115 iwl_init_scan_params(priv);
1117 1116
1118 /* init bt coex */ 1117 /* init bt coex */
1119 if (priv->cfg->bt_params && 1118 if (priv->lib->bt_params &&
1120 priv->cfg->bt_params->advanced_bt_coexist) { 1119 priv->lib->bt_params->advanced_bt_coexist) {
1121 priv->kill_ack_mask = IWLAGN_BT_KILL_ACK_MASK_DEFAULT; 1120 priv->kill_ack_mask = IWLAGN_BT_KILL_ACK_MASK_DEFAULT;
1122 priv->kill_cts_mask = IWLAGN_BT_KILL_CTS_MASK_DEFAULT; 1121 priv->kill_cts_mask = IWLAGN_BT_KILL_CTS_MASK_DEFAULT;
1123 priv->bt_valid = IWLAGN_BT_ALL_VALID_MSK; 1122 priv->bt_valid = IWLAGN_BT_ALL_VALID_MSK;
@@ -1264,31 +1263,37 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
1264 switch (priv->cfg->device_family) { 1263 switch (priv->cfg->device_family) {
1265 case IWL_DEVICE_FAMILY_1000: 1264 case IWL_DEVICE_FAMILY_1000:
1266 case IWL_DEVICE_FAMILY_100: 1265 case IWL_DEVICE_FAMILY_100:
1267 priv->lib = &iwl1000_lib; 1266 priv->lib = &iwl_dvm_1000_cfg;
1268 break; 1267 break;
1269 case IWL_DEVICE_FAMILY_2000: 1268 case IWL_DEVICE_FAMILY_2000:
1269 priv->lib = &iwl_dvm_2000_cfg;
1270 break;
1270 case IWL_DEVICE_FAMILY_105: 1271 case IWL_DEVICE_FAMILY_105:
1271 priv->lib = &iwl2000_lib; 1272 priv->lib = &iwl_dvm_105_cfg;
1272 break; 1273 break;
1273 case IWL_DEVICE_FAMILY_2030: 1274 case IWL_DEVICE_FAMILY_2030:
1274 case IWL_DEVICE_FAMILY_135: 1275 case IWL_DEVICE_FAMILY_135:
1275 priv->lib = &iwl2030_lib; 1276 priv->lib = &iwl_dvm_2030_cfg;
1276 break; 1277 break;
1277 case IWL_DEVICE_FAMILY_5000: 1278 case IWL_DEVICE_FAMILY_5000:
1278 priv->lib = &iwl5000_lib; 1279 priv->lib = &iwl_dvm_5000_cfg;
1279 break; 1280 break;
1280 case IWL_DEVICE_FAMILY_5150: 1281 case IWL_DEVICE_FAMILY_5150:
1281 priv->lib = &iwl5150_lib; 1282 priv->lib = &iwl_dvm_5150_cfg;
1282 break; 1283 break;
1283 case IWL_DEVICE_FAMILY_6000: 1284 case IWL_DEVICE_FAMILY_6000:
1284 case IWL_DEVICE_FAMILY_6005:
1285 case IWL_DEVICE_FAMILY_6000i: 1285 case IWL_DEVICE_FAMILY_6000i:
1286 priv->lib = &iwl_dvm_6000_cfg;
1287 break;
1288 case IWL_DEVICE_FAMILY_6005:
1289 priv->lib = &iwl_dvm_6005_cfg;
1290 break;
1286 case IWL_DEVICE_FAMILY_6050: 1291 case IWL_DEVICE_FAMILY_6050:
1287 case IWL_DEVICE_FAMILY_6150: 1292 case IWL_DEVICE_FAMILY_6150:
1288 priv->lib = &iwl6000_lib; 1293 priv->lib = &iwl_dvm_6050_cfg;
1289 break; 1294 break;
1290 case IWL_DEVICE_FAMILY_6030: 1295 case IWL_DEVICE_FAMILY_6030:
1291 priv->lib = &iwl6030_lib; 1296 priv->lib = &iwl_dvm_6030_cfg;
1292 break; 1297 break;
1293 default: 1298 default:
1294 break; 1299 break;
diff --git a/drivers/net/wireless/iwlwifi/dvm/power.c b/drivers/net/wireless/iwlwifi/dvm/power.c
index bd69018d07a9..77cb59712235 100644
--- a/drivers/net/wireless/iwlwifi/dvm/power.c
+++ b/drivers/net/wireless/iwlwifi/dvm/power.c
@@ -163,7 +163,7 @@ static void iwl_static_sleep_cmd(struct iwl_priv *priv,
163 u8 skip; 163 u8 skip;
164 u32 slp_itrvl; 164 u32 slp_itrvl;
165 165
166 if (priv->cfg->adv_pm) { 166 if (priv->lib->adv_pm) {
167 table = apm_range_2; 167 table = apm_range_2;
168 if (period <= IWL_DTIM_RANGE_1_MAX) 168 if (period <= IWL_DTIM_RANGE_1_MAX)
169 table = apm_range_1; 169 table = apm_range_1;
@@ -217,7 +217,7 @@ static void iwl_static_sleep_cmd(struct iwl_priv *priv,
217 cmd->flags &= ~IWL_POWER_SHADOW_REG_ENA; 217 cmd->flags &= ~IWL_POWER_SHADOW_REG_ENA;
218 218
219 if (iwl_advanced_bt_coexist(priv)) { 219 if (iwl_advanced_bt_coexist(priv)) {
220 if (!priv->cfg->bt_params->bt_sco_disable) 220 if (!priv->lib->bt_params->bt_sco_disable)
221 cmd->flags |= IWL_POWER_BT_SCO_ENA; 221 cmd->flags |= IWL_POWER_BT_SCO_ENA;
222 else 222 else
223 cmd->flags &= ~IWL_POWER_BT_SCO_ENA; 223 cmd->flags &= ~IWL_POWER_BT_SCO_ENA;
@@ -293,7 +293,7 @@ static void iwl_power_build_cmd(struct iwl_priv *priv,
293 293
294 if (priv->wowlan) 294 if (priv->wowlan)
295 iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_5, dtimper); 295 iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_5, dtimper);
296 else if (!priv->cfg->base_params->no_idle_support && 296 else if (!priv->lib->no_idle_support &&
297 priv->hw->conf.flags & IEEE80211_CONF_IDLE) 297 priv->hw->conf.flags & IEEE80211_CONF_IDLE)
298 iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_5, 20); 298 iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_5, 20);
299 else if (iwl_tt_is_low_power_state(priv)) { 299 else if (iwl_tt_is_low_power_state(priv)) {
diff --git a/drivers/net/wireless/iwlwifi/dvm/rs.c b/drivers/net/wireless/iwlwifi/dvm/rs.c
index 907bd6e50aad..94314a8e1029 100644
--- a/drivers/net/wireless/iwlwifi/dvm/rs.c
+++ b/drivers/net/wireless/iwlwifi/dvm/rs.c
@@ -1088,7 +1088,7 @@ done:
1088 (priv->tm_fixed_rate != lq_sta->dbg_fixed_rate)) 1088 (priv->tm_fixed_rate != lq_sta->dbg_fixed_rate))
1089 rs_program_fix_rate(priv, lq_sta); 1089 rs_program_fix_rate(priv, lq_sta);
1090#endif 1090#endif
1091 if (priv->cfg->bt_params && priv->cfg->bt_params->advanced_bt_coexist) 1091 if (priv->lib->bt_params && priv->lib->bt_params->advanced_bt_coexist)
1092 rs_bt_update_lq(priv, ctx, lq_sta); 1092 rs_bt_update_lq(priv, ctx, lq_sta);
1093} 1093}
1094 1094
@@ -3064,11 +3064,11 @@ static void rs_fill_link_cmd(struct iwl_priv *priv,
3064 * overwrite if needed, pass aggregation time limit 3064 * overwrite if needed, pass aggregation time limit
3065 * to uCode in uSec 3065 * to uCode in uSec
3066 */ 3066 */
3067 if (priv && priv->cfg->bt_params && 3067 if (priv && priv->lib->bt_params &&
3068 priv->cfg->bt_params->agg_time_limit && 3068 priv->lib->bt_params->agg_time_limit &&
3069 priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH) 3069 priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)
3070 lq_cmd->agg_params.agg_time_limit = 3070 lq_cmd->agg_params.agg_time_limit =
3071 cpu_to_le16(priv->cfg->bt_params->agg_time_limit); 3071 cpu_to_le16(priv->lib->bt_params->agg_time_limit);
3072} 3072}
3073 3073
3074static void *rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) 3074static void *rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
diff --git a/drivers/net/wireless/iwlwifi/dvm/rx.c b/drivers/net/wireless/iwlwifi/dvm/rx.c
index a4eed2055fdb..2f3fd160ab44 100644
--- a/drivers/net/wireless/iwlwifi/dvm/rx.c
+++ b/drivers/net/wireless/iwlwifi/dvm/rx.c
@@ -1102,7 +1102,7 @@ void iwl_setup_rx_handlers(struct iwl_priv *priv)
1102 iwl_notification_wait_init(&priv->notif_wait); 1102 iwl_notification_wait_init(&priv->notif_wait);
1103 1103
1104 /* Set up BT Rx handlers */ 1104 /* Set up BT Rx handlers */
1105 if (priv->cfg->bt_params) 1105 if (priv->lib->bt_params)
1106 iwlagn_bt_rx_handler_setup(priv); 1106 iwlagn_bt_rx_handler_setup(priv);
1107} 1107}
1108 1108
diff --git a/drivers/net/wireless/iwlwifi/dvm/scan.c b/drivers/net/wireless/iwlwifi/dvm/scan.c
index d69b55866714..8c686a5b90ac 100644
--- a/drivers/net/wireless/iwlwifi/dvm/scan.c
+++ b/drivers/net/wireless/iwlwifi/dvm/scan.c
@@ -801,8 +801,8 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
801 * Internal scans are passive, so we can indiscriminately set 801 * Internal scans are passive, so we can indiscriminately set
802 * the BT ignore flag on 2.4 GHz since it applies to TX only. 802 * the BT ignore flag on 2.4 GHz since it applies to TX only.
803 */ 803 */
804 if (priv->cfg->bt_params && 804 if (priv->lib->bt_params &&
805 priv->cfg->bt_params->advanced_bt_coexist) 805 priv->lib->bt_params->advanced_bt_coexist)
806 scan->tx_cmd.tx_flags |= TX_CMD_FLG_IGNORE_BT; 806 scan->tx_cmd.tx_flags |= TX_CMD_FLG_IGNORE_BT;
807 break; 807 break;
808 case IEEE80211_BAND_5GHZ: 808 case IEEE80211_BAND_5GHZ:
@@ -844,8 +844,8 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
844 band = priv->scan_band; 844 band = priv->scan_band;
845 845
846 if (band == IEEE80211_BAND_2GHZ && 846 if (band == IEEE80211_BAND_2GHZ &&
847 priv->cfg->bt_params && 847 priv->lib->bt_params &&
848 priv->cfg->bt_params->advanced_bt_coexist) { 848 priv->lib->bt_params->advanced_bt_coexist) {
849 /* transmit 2.4 GHz probes only on first antenna */ 849 /* transmit 2.4 GHz probes only on first antenna */
850 scan_tx_antennas = first_antenna(scan_tx_antennas); 850 scan_tx_antennas = first_antenna(scan_tx_antennas);
851 } 851 }
@@ -873,8 +873,8 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
873 873
874 rx_ant = first_antenna(active_chains); 874 rx_ant = first_antenna(active_chains);
875 } 875 }
876 if (priv->cfg->bt_params && 876 if (priv->lib->bt_params &&
877 priv->cfg->bt_params->advanced_bt_coexist && 877 priv->lib->bt_params->advanced_bt_coexist &&
878 priv->bt_full_concurrent) { 878 priv->bt_full_concurrent) {
879 /* operated as 1x1 in full concurrency mode */ 879 /* operated as 1x1 in full concurrency mode */
880 rx_ant = first_antenna(rx_ant); 880 rx_ant = first_antenna(rx_ant);
diff --git a/drivers/net/wireless/iwlwifi/dvm/tt.c b/drivers/net/wireless/iwlwifi/dvm/tt.c
index 03f9bc01c0cc..fbeee081ee2f 100644
--- a/drivers/net/wireless/iwlwifi/dvm/tt.c
+++ b/drivers/net/wireless/iwlwifi/dvm/tt.c
@@ -627,7 +627,7 @@ void iwl_tt_initialize(struct iwl_priv *priv)
627 INIT_WORK(&priv->ct_enter, iwl_bg_ct_enter); 627 INIT_WORK(&priv->ct_enter, iwl_bg_ct_enter);
628 INIT_WORK(&priv->ct_exit, iwl_bg_ct_exit); 628 INIT_WORK(&priv->ct_exit, iwl_bg_ct_exit);
629 629
630 if (priv->cfg->base_params->adv_thermal_throttle) { 630 if (priv->lib->adv_thermal_throttle) {
631 IWL_DEBUG_TEMP(priv, "Advanced Thermal Throttling\n"); 631 IWL_DEBUG_TEMP(priv, "Advanced Thermal Throttling\n");
632 tt->restriction = kcalloc(IWL_TI_STATE_MAX, 632 tt->restriction = kcalloc(IWL_TI_STATE_MAX,
633 sizeof(struct iwl_tt_restriction), 633 sizeof(struct iwl_tt_restriction),
diff --git a/drivers/net/wireless/iwlwifi/dvm/tx.c b/drivers/net/wireless/iwlwifi/dvm/tx.c
index a900aaf47790..353a053b4eb1 100644
--- a/drivers/net/wireless/iwlwifi/dvm/tx.c
+++ b/drivers/net/wireless/iwlwifi/dvm/tx.c
@@ -83,8 +83,8 @@ static void iwlagn_tx_cmd_build_basic(struct iwl_priv *priv,
83 else if (ieee80211_is_back_req(fc)) 83 else if (ieee80211_is_back_req(fc))
84 tx_flags |= TX_CMD_FLG_ACK_MSK | TX_CMD_FLG_IMM_BA_RSP_MASK; 84 tx_flags |= TX_CMD_FLG_ACK_MSK | TX_CMD_FLG_IMM_BA_RSP_MASK;
85 else if (info->band == IEEE80211_BAND_2GHZ && 85 else if (info->band == IEEE80211_BAND_2GHZ &&
86 priv->cfg->bt_params && 86 priv->lib->bt_params &&
87 priv->cfg->bt_params->advanced_bt_coexist && 87 priv->lib->bt_params->advanced_bt_coexist &&
88 (ieee80211_is_auth(fc) || ieee80211_is_assoc_req(fc) || 88 (ieee80211_is_auth(fc) || ieee80211_is_assoc_req(fc) ||
89 ieee80211_is_reassoc_req(fc) || 89 ieee80211_is_reassoc_req(fc) ||
90 skb->protocol == cpu_to_be16(ETH_P_PAE))) 90 skb->protocol == cpu_to_be16(ETH_P_PAE)))
@@ -202,8 +202,8 @@ static void iwlagn_tx_cmd_build_rate(struct iwl_priv *priv,
202 rate_flags |= RATE_MCS_CCK_MSK; 202 rate_flags |= RATE_MCS_CCK_MSK;
203 203
204 /* Set up antennas */ 204 /* Set up antennas */
205 if (priv->cfg->bt_params && 205 if (priv->lib->bt_params &&
206 priv->cfg->bt_params->advanced_bt_coexist && 206 priv->lib->bt_params->advanced_bt_coexist &&
207 priv->bt_full_concurrent) { 207 priv->bt_full_concurrent) {
208 /* operated as 1x1 in full concurrency mode */ 208 /* operated as 1x1 in full concurrency mode */
209 priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant, 209 priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant,
@@ -986,8 +986,8 @@ static void iwl_rx_reply_tx_agg(struct iwl_priv *priv,
986 * notification again. 986 * notification again.
987 */ 987 */
988 if (tx_resp->bt_kill_count && tx_resp->frame_count == 1 && 988 if (tx_resp->bt_kill_count && tx_resp->frame_count == 1 &&
989 priv->cfg->bt_params && 989 priv->lib->bt_params &&
990 priv->cfg->bt_params->advanced_bt_coexist) { 990 priv->lib->bt_params->advanced_bt_coexist) {
991 IWL_DEBUG_COEX(priv, "receive reply tx w/ bt_kill\n"); 991 IWL_DEBUG_COEX(priv, "receive reply tx w/ bt_kill\n");
992 } 992 }
993 993
diff --git a/drivers/net/wireless/iwlwifi/dvm/ucode.c b/drivers/net/wireless/iwlwifi/dvm/ucode.c
index 0a1cdc5e856b..86270b69cd02 100644
--- a/drivers/net/wireless/iwlwifi/dvm/ucode.c
+++ b/drivers/net/wireless/iwlwifi/dvm/ucode.c
@@ -132,8 +132,8 @@ int iwl_init_alive_start(struct iwl_priv *priv)
132{ 132{
133 int ret; 133 int ret;
134 134
135 if (priv->cfg->bt_params && 135 if (priv->lib->bt_params &&
136 priv->cfg->bt_params->advanced_bt_coexist) { 136 priv->lib->bt_params->advanced_bt_coexist) {
137 /* 137 /*
138 * Tell uCode we are ready to perform calibration 138 * Tell uCode we are ready to perform calibration
139 * need to perform this before any calibration 139 * need to perform this before any calibration
@@ -155,8 +155,8 @@ int iwl_init_alive_start(struct iwl_priv *priv)
155 * temperature offset calibration is only needed for runtime ucode, 155 * temperature offset calibration is only needed for runtime ucode,
156 * so prepare the value now. 156 * so prepare the value now.
157 */ 157 */
158 if (priv->cfg->need_temp_offset_calib) { 158 if (priv->lib->need_temp_offset_calib) {
159 if (priv->cfg->temp_offset_v2) 159 if (priv->lib->temp_offset_v2)
160 return iwl_set_temperature_offset_calib_v2(priv); 160 return iwl_set_temperature_offset_calib_v2(priv);
161 else 161 else
162 return iwl_set_temperature_offset_calib(priv); 162 return iwl_set_temperature_offset_calib(priv);
@@ -277,7 +277,7 @@ static int iwl_alive_notify(struct iwl_priv *priv)
277 if (ret) 277 if (ret)
278 return ret; 278 return ret;
279 279
280 if (!priv->cfg->no_xtal_calib) { 280 if (!priv->lib->no_xtal_calib) {
281 ret = iwl_set_Xtal_calib(priv); 281 ret = iwl_set_Xtal_calib(priv);
282 if (ret) 282 if (ret)
283 return ret; 283 return ret;
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index c080ae3070b2..0d2afe098afc 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -60,9 +60,6 @@ static const struct iwl_base_params iwl1000_base_params = {
60 .max_ll_items = OTP_MAX_LL_ITEMS_1000, 60 .max_ll_items = OTP_MAX_LL_ITEMS_1000,
61 .shadow_ram_support = false, 61 .shadow_ram_support = false,
62 .led_compensation = 51, 62 .led_compensation = 51,
63 .support_ct_kill_exit = true,
64 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF,
65 .chain_noise_scale = 1000,
66 .wd_timeout = IWL_WATCHDOG_DISABLED, 63 .wd_timeout = IWL_WATCHDOG_DISABLED,
67 .max_event_log_size = 128, 64 .max_event_log_size = 128,
68}; 65};
diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c
index a6ddd2f9fba0..c727ec7c90a6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-2000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-2000.c
@@ -72,14 +72,9 @@ static const struct iwl_base_params iwl2000_base_params = {
72 .max_ll_items = OTP_MAX_LL_ITEMS_2x00, 72 .max_ll_items = OTP_MAX_LL_ITEMS_2x00,
73 .shadow_ram_support = true, 73 .shadow_ram_support = true,
74 .led_compensation = 51, 74 .led_compensation = 51,
75 .adv_thermal_throttle = true,
76 .support_ct_kill_exit = true,
77 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
78 .chain_noise_scale = 1000,
79 .wd_timeout = IWL_DEF_WD_TIMEOUT, 75 .wd_timeout = IWL_DEF_WD_TIMEOUT,
80 .max_event_log_size = 512, 76 .max_event_log_size = 512,
81 .shadow_reg_enable = false, /* TODO: fix bugs using this feature */ 77 .shadow_reg_enable = false, /* TODO: fix bugs using this feature */
82 .hd_v2 = true,
83}; 78};
84 79
85 80
@@ -90,14 +85,9 @@ static const struct iwl_base_params iwl2030_base_params = {
90 .max_ll_items = OTP_MAX_LL_ITEMS_2x00, 85 .max_ll_items = OTP_MAX_LL_ITEMS_2x00,
91 .shadow_ram_support = true, 86 .shadow_ram_support = true,
92 .led_compensation = 57, 87 .led_compensation = 57,
93 .adv_thermal_throttle = true,
94 .support_ct_kill_exit = true,
95 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
96 .chain_noise_scale = 1000,
97 .wd_timeout = IWL_LONG_WD_TIMEOUT, 88 .wd_timeout = IWL_LONG_WD_TIMEOUT,
98 .max_event_log_size = 512, 89 .max_event_log_size = 512,
99 .shadow_reg_enable = false, /* TODO: fix bugs using this feature */ 90 .shadow_reg_enable = false, /* TODO: fix bugs using this feature */
100 .hd_v2 = true,
101}; 91};
102 92
103static const struct iwl_ht_params iwl2000_ht_params = { 93static const struct iwl_ht_params iwl2000_ht_params = {
@@ -106,16 +96,6 @@ static const struct iwl_ht_params iwl2000_ht_params = {
106 .ht40_bands = BIT(IEEE80211_BAND_2GHZ), 96 .ht40_bands = BIT(IEEE80211_BAND_2GHZ),
107}; 97};
108 98
109static const struct iwl_bt_params iwl2030_bt_params = {
110 /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
111 .advanced_bt_coexist = true,
112 .agg_time_limit = BT_AGG_THRESHOLD_DEF,
113 .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE,
114 .bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT32,
115 .bt_sco_disable = true,
116 .bt_session_2 = true,
117};
118
119static const struct iwl_eeprom_params iwl20x0_eeprom_params = { 99static const struct iwl_eeprom_params iwl20x0_eeprom_params = {
120 .regulatory_bands = { 100 .regulatory_bands = {
121 EEPROM_REG_BAND_1_CHANNELS, 101 EEPROM_REG_BAND_1_CHANNELS,
@@ -137,12 +117,10 @@ static const struct iwl_eeprom_params iwl20x0_eeprom_params = {
137 .device_family = IWL_DEVICE_FAMILY_2000, \ 117 .device_family = IWL_DEVICE_FAMILY_2000, \
138 .max_inst_size = IWL60_RTC_INST_SIZE, \ 118 .max_inst_size = IWL60_RTC_INST_SIZE, \
139 .max_data_size = IWL60_RTC_DATA_SIZE, \ 119 .max_data_size = IWL60_RTC_DATA_SIZE, \
140 .nvm_ver = EEPROM_2000_EEPROM_VERSION, \ 120 .nvm_ver = EEPROM_2000_EEPROM_VERSION, \
141 .nvm_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ 121 .nvm_calib_ver = EEPROM_2000_TX_POWER_VERSION, \
142 .base_params = &iwl2000_base_params, \ 122 .base_params = &iwl2000_base_params, \
143 .eeprom_params = &iwl20x0_eeprom_params, \ 123 .eeprom_params = &iwl20x0_eeprom_params, \
144 .need_temp_offset_calib = true, \
145 .temp_offset_v2 = true, \
146 .led_mode = IWL_LED_RF_STATE 124 .led_mode = IWL_LED_RF_STATE
147 125
148const struct iwl_cfg iwl2000_2bgn_cfg = { 126const struct iwl_cfg iwl2000_2bgn_cfg = {
@@ -168,12 +146,8 @@ const struct iwl_cfg iwl2000_2bgn_d_cfg = {
168 .nvm_ver = EEPROM_2000_EEPROM_VERSION, \ 146 .nvm_ver = EEPROM_2000_EEPROM_VERSION, \
169 .nvm_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ 147 .nvm_calib_ver = EEPROM_2000_TX_POWER_VERSION, \
170 .base_params = &iwl2030_base_params, \ 148 .base_params = &iwl2030_base_params, \
171 .bt_params = &iwl2030_bt_params, \
172 .eeprom_params = &iwl20x0_eeprom_params, \ 149 .eeprom_params = &iwl20x0_eeprom_params, \
173 .need_temp_offset_calib = true, \ 150 .led_mode = IWL_LED_RF_STATE
174 .temp_offset_v2 = true, \
175 .led_mode = IWL_LED_RF_STATE, \
176 .adv_pm = true
177 151
178const struct iwl_cfg iwl2030_2bgn_cfg = { 152const struct iwl_cfg iwl2030_2bgn_cfg = {
179 .name = "Intel(R) Centrino(R) Wireless-N 2230 BGN", 153 .name = "Intel(R) Centrino(R) Wireless-N 2230 BGN",
@@ -193,10 +167,7 @@ const struct iwl_cfg iwl2030_2bgn_cfg = {
193 .nvm_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ 167 .nvm_calib_ver = EEPROM_2000_TX_POWER_VERSION, \
194 .base_params = &iwl2000_base_params, \ 168 .base_params = &iwl2000_base_params, \
195 .eeprom_params = &iwl20x0_eeprom_params, \ 169 .eeprom_params = &iwl20x0_eeprom_params, \
196 .need_temp_offset_calib = true, \
197 .temp_offset_v2 = true, \
198 .led_mode = IWL_LED_RF_STATE, \ 170 .led_mode = IWL_LED_RF_STATE, \
199 .adv_pm = true, \
200 .rx_with_siso_diversity = true 171 .rx_with_siso_diversity = true
201 172
202const struct iwl_cfg iwl105_bgn_cfg = { 173const struct iwl_cfg iwl105_bgn_cfg = {
@@ -222,12 +193,8 @@ const struct iwl_cfg iwl105_bgn_d_cfg = {
222 .nvm_ver = EEPROM_2000_EEPROM_VERSION, \ 193 .nvm_ver = EEPROM_2000_EEPROM_VERSION, \
223 .nvm_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ 194 .nvm_calib_ver = EEPROM_2000_TX_POWER_VERSION, \
224 .base_params = &iwl2030_base_params, \ 195 .base_params = &iwl2030_base_params, \
225 .bt_params = &iwl2030_bt_params, \
226 .eeprom_params = &iwl20x0_eeprom_params, \ 196 .eeprom_params = &iwl20x0_eeprom_params, \
227 .need_temp_offset_calib = true, \
228 .temp_offset_v2 = true, \
229 .led_mode = IWL_LED_RF_STATE, \ 197 .led_mode = IWL_LED_RF_STATE, \
230 .adv_pm = true, \
231 .rx_with_siso_diversity = true 198 .rx_with_siso_diversity = true
232 199
233const struct iwl_cfg iwl135_bgn_cfg = { 200const struct iwl_cfg iwl135_bgn_cfg = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index 403f3f224bf6..ecc01e1a61a1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -59,11 +59,8 @@ static const struct iwl_base_params iwl5000_base_params = {
59 .num_of_queues = IWLAGN_NUM_QUEUES, 59 .num_of_queues = IWLAGN_NUM_QUEUES,
60 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, 60 .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
61 .led_compensation = 51, 61 .led_compensation = 51,
62 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
63 .chain_noise_scale = 1000,
64 .wd_timeout = IWL_WATCHDOG_DISABLED, 62 .wd_timeout = IWL_WATCHDOG_DISABLED,
65 .max_event_log_size = 512, 63 .max_event_log_size = 512,
66 .no_idle_support = true,
67}; 64};
68 65
69static const struct iwl_ht_params iwl5000_ht_params = { 66static const struct iwl_ht_params iwl5000_ht_params = {
@@ -159,7 +156,6 @@ const struct iwl_cfg iwl5350_agn_cfg = {
159 .nvm_calib_ver = EEPROM_5050_TX_POWER_VERSION, \ 156 .nvm_calib_ver = EEPROM_5050_TX_POWER_VERSION, \
160 .base_params = &iwl5000_base_params, \ 157 .base_params = &iwl5000_base_params, \
161 .eeprom_params = &iwl5000_eeprom_params, \ 158 .eeprom_params = &iwl5000_eeprom_params, \
162 .no_xtal_calib = true, \
163 .led_mode = IWL_LED_BLINK, \ 159 .led_mode = IWL_LED_BLINK, \
164 .internal_wimax_coex = true 160 .internal_wimax_coex = true
165 161
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index b5ab8d1bcac0..30d45e2fc193 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -82,10 +82,6 @@ static const struct iwl_base_params iwl6000_base_params = {
82 .max_ll_items = OTP_MAX_LL_ITEMS_6x00, 82 .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
83 .shadow_ram_support = true, 83 .shadow_ram_support = true,
84 .led_compensation = 51, 84 .led_compensation = 51,
85 .adv_thermal_throttle = true,
86 .support_ct_kill_exit = true,
87 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
88 .chain_noise_scale = 1000,
89 .wd_timeout = IWL_DEF_WD_TIMEOUT, 85 .wd_timeout = IWL_DEF_WD_TIMEOUT,
90 .max_event_log_size = 512, 86 .max_event_log_size = 512,
91 .shadow_reg_enable = false, /* TODO: fix bugs using this feature */ 87 .shadow_reg_enable = false, /* TODO: fix bugs using this feature */
@@ -98,10 +94,6 @@ static const struct iwl_base_params iwl6050_base_params = {
98 .max_ll_items = OTP_MAX_LL_ITEMS_6x50, 94 .max_ll_items = OTP_MAX_LL_ITEMS_6x50,
99 .shadow_ram_support = true, 95 .shadow_ram_support = true,
100 .led_compensation = 51, 96 .led_compensation = 51,
101 .adv_thermal_throttle = true,
102 .support_ct_kill_exit = true,
103 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
104 .chain_noise_scale = 1500,
105 .wd_timeout = IWL_DEF_WD_TIMEOUT, 97 .wd_timeout = IWL_DEF_WD_TIMEOUT,
106 .max_event_log_size = 1024, 98 .max_event_log_size = 1024,
107 .shadow_reg_enable = false, /* TODO: fix bugs using this feature */ 99 .shadow_reg_enable = false, /* TODO: fix bugs using this feature */
@@ -114,10 +106,6 @@ static const struct iwl_base_params iwl6000_g2_base_params = {
114 .max_ll_items = OTP_MAX_LL_ITEMS_6x00, 106 .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
115 .shadow_ram_support = true, 107 .shadow_ram_support = true,
116 .led_compensation = 57, 108 .led_compensation = 57,
117 .adv_thermal_throttle = true,
118 .support_ct_kill_exit = true,
119 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
120 .chain_noise_scale = 1000,
121 .wd_timeout = IWL_LONG_WD_TIMEOUT, 109 .wd_timeout = IWL_LONG_WD_TIMEOUT,
122 .max_event_log_size = 512, 110 .max_event_log_size = 512,
123 .shadow_reg_enable = false, /* TODO: fix bugs using this feature */ 111 .shadow_reg_enable = false, /* TODO: fix bugs using this feature */
@@ -129,15 +117,6 @@ static const struct iwl_ht_params iwl6000_ht_params = {
129 .ht40_bands = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ), 117 .ht40_bands = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ),
130}; 118};
131 119
132static const struct iwl_bt_params iwl6000_bt_params = {
133 /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
134 .advanced_bt_coexist = true,
135 .agg_time_limit = BT_AGG_THRESHOLD_DEF,
136 .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE,
137 .bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT,
138 .bt_sco_disable = true,
139};
140
141static const struct iwl_eeprom_params iwl6000_eeprom_params = { 120static const struct iwl_eeprom_params iwl6000_eeprom_params = {
142 .regulatory_bands = { 121 .regulatory_bands = {
143 EEPROM_REG_BAND_1_CHANNELS, 122 EEPROM_REG_BAND_1_CHANNELS,
@@ -163,7 +142,6 @@ static const struct iwl_eeprom_params iwl6000_eeprom_params = {
163 .nvm_calib_ver = EEPROM_6005_TX_POWER_VERSION, \ 142 .nvm_calib_ver = EEPROM_6005_TX_POWER_VERSION, \
164 .base_params = &iwl6000_g2_base_params, \ 143 .base_params = &iwl6000_g2_base_params, \
165 .eeprom_params = &iwl6000_eeprom_params, \ 144 .eeprom_params = &iwl6000_eeprom_params, \
166 .need_temp_offset_calib = true, \
167 .led_mode = IWL_LED_RF_STATE 145 .led_mode = IWL_LED_RF_STATE
168 146
169const struct iwl_cfg iwl6005_2agn_cfg = { 147const struct iwl_cfg iwl6005_2agn_cfg = {
@@ -217,11 +195,8 @@ const struct iwl_cfg iwl6005_2agn_mow2_cfg = {
217 .nvm_ver = EEPROM_6030_EEPROM_VERSION, \ 195 .nvm_ver = EEPROM_6030_EEPROM_VERSION, \
218 .nvm_calib_ver = EEPROM_6030_TX_POWER_VERSION, \ 196 .nvm_calib_ver = EEPROM_6030_TX_POWER_VERSION, \
219 .base_params = &iwl6000_g2_base_params, \ 197 .base_params = &iwl6000_g2_base_params, \
220 .bt_params = &iwl6000_bt_params, \
221 .eeprom_params = &iwl6000_eeprom_params, \ 198 .eeprom_params = &iwl6000_eeprom_params, \
222 .need_temp_offset_calib = true, \ 199 .led_mode = IWL_LED_RF_STATE
223 .led_mode = IWL_LED_RF_STATE, \
224 .adv_pm = true \
225 200
226const struct iwl_cfg iwl6030_2agn_cfg = { 201const struct iwl_cfg iwl6030_2agn_cfg = {
227 .name = "Intel(R) Centrino(R) Advanced-N 6230 AGN", 202 .name = "Intel(R) Centrino(R) Advanced-N 6230 AGN",
@@ -256,11 +231,8 @@ const struct iwl_cfg iwl6030_2bg_cfg = {
256 .nvm_ver = EEPROM_6030_EEPROM_VERSION, \ 231 .nvm_ver = EEPROM_6030_EEPROM_VERSION, \
257 .nvm_calib_ver = EEPROM_6030_TX_POWER_VERSION, \ 232 .nvm_calib_ver = EEPROM_6030_TX_POWER_VERSION, \
258 .base_params = &iwl6000_g2_base_params, \ 233 .base_params = &iwl6000_g2_base_params, \
259 .bt_params = &iwl6000_bt_params, \
260 .eeprom_params = &iwl6000_eeprom_params, \ 234 .eeprom_params = &iwl6000_eeprom_params, \
261 .need_temp_offset_calib = true, \ 235 .led_mode = IWL_LED_RF_STATE
262 .led_mode = IWL_LED_RF_STATE, \
263 .adv_pm = true
264 236
265const struct iwl_cfg iwl6035_2agn_cfg = { 237const struct iwl_cfg iwl6035_2agn_cfg = {
266 .name = "Intel(R) Centrino(R) Advanced-N 6235 AGN", 238 .name = "Intel(R) Centrino(R) Advanced-N 6235 AGN",
diff --git a/drivers/net/wireless/iwlwifi/iwl-7000.c b/drivers/net/wireless/iwlwifi/iwl-7000.c
index 50263e87fe15..d4f3b4864ab1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-7000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-7000.c
@@ -96,13 +96,9 @@ static const struct iwl_base_params iwl7000_base_params = {
96 .pll_cfg_val = 0, 96 .pll_cfg_val = 0,
97 .shadow_ram_support = true, 97 .shadow_ram_support = true,
98 .led_compensation = 57, 98 .led_compensation = 57,
99 .adv_thermal_throttle = true,
100 .support_ct_kill_exit = true,
101 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
102 .chain_noise_scale = 1000,
103 .wd_timeout = IWL_LONG_WD_TIMEOUT, 99 .wd_timeout = IWL_LONG_WD_TIMEOUT,
104 .max_event_log_size = 512, 100 .max_event_log_size = 512,
105 .shadow_reg_enable = false, /* TODO: fix bugs using this feature */ 101 .shadow_reg_enable = true,
106}; 102};
107 103
108static const struct iwl_ht_params iwl7000_ht_params = { 104static const struct iwl_ht_params iwl7000_ht_params = {
@@ -118,14 +114,11 @@ static const struct iwl_ht_params iwl7000_ht_params = {
118 .max_inst_size = IWL60_RTC_INST_SIZE, \ 114 .max_inst_size = IWL60_RTC_INST_SIZE, \
119 .max_data_size = IWL60_RTC_DATA_SIZE, \ 115 .max_data_size = IWL60_RTC_DATA_SIZE, \
120 .base_params = &iwl7000_base_params, \ 116 .base_params = &iwl7000_base_params, \
121 /* TODO: .bt_params? */ \ 117 .led_mode = IWL_LED_RF_STATE
122 .need_temp_offset_calib = true, \
123 .led_mode = IWL_LED_RF_STATE, \
124 .adv_pm = true \
125 118
126 119
127const struct iwl_cfg iwl7260_2ac_cfg = { 120const struct iwl_cfg iwl7260_2ac_cfg = {
128 .name = "Intel(R) Dual Band Wireless AC7260", 121 .name = "Intel(R) Dual Band Wireless AC 7260",
129 .fw_name_pre = IWL7260_FW_PRE, 122 .fw_name_pre = IWL7260_FW_PRE,
130 IWL_DEVICE_7000, 123 IWL_DEVICE_7000,
131 .ht_params = &iwl7000_ht_params, 124 .ht_params = &iwl7000_ht_params,
@@ -133,8 +126,44 @@ const struct iwl_cfg iwl7260_2ac_cfg = {
133 .nvm_calib_ver = IWL7260_TX_POWER_VERSION, 126 .nvm_calib_ver = IWL7260_TX_POWER_VERSION,
134}; 127};
135 128
136const struct iwl_cfg iwl3160_ac_cfg = { 129const struct iwl_cfg iwl7260_2n_cfg = {
137 .name = "Intel(R) Dual Band Wireless AC3160", 130 .name = "Intel(R) Dual Band Wireless N 7260",
131 .fw_name_pre = IWL7260_FW_PRE,
132 IWL_DEVICE_7000,
133 .ht_params = &iwl7000_ht_params,
134 .nvm_ver = IWL7260_NVM_VERSION,
135 .nvm_calib_ver = IWL7260_TX_POWER_VERSION,
136};
137
138const struct iwl_cfg iwl7260_n_cfg = {
139 .name = "Intel(R) Wireless N 7260",
140 .fw_name_pre = IWL7260_FW_PRE,
141 IWL_DEVICE_7000,
142 .ht_params = &iwl7000_ht_params,
143 .nvm_ver = IWL7260_NVM_VERSION,
144 .nvm_calib_ver = IWL7260_TX_POWER_VERSION,
145};
146
147const struct iwl_cfg iwl3160_2ac_cfg = {
148 .name = "Intel(R) Dual Band Wireless AC 3160",
149 .fw_name_pre = IWL3160_FW_PRE,
150 IWL_DEVICE_7000,
151 .ht_params = &iwl7000_ht_params,
152 .nvm_ver = IWL3160_NVM_VERSION,
153 .nvm_calib_ver = IWL3160_TX_POWER_VERSION,
154};
155
156const struct iwl_cfg iwl3160_2n_cfg = {
157 .name = "Intel(R) Dual Band Wireless N 3160",
158 .fw_name_pre = IWL3160_FW_PRE,
159 IWL_DEVICE_7000,
160 .ht_params = &iwl7000_ht_params,
161 .nvm_ver = IWL3160_NVM_VERSION,
162 .nvm_calib_ver = IWL3160_TX_POWER_VERSION,
163};
164
165const struct iwl_cfg iwl3160_n_cfg = {
166 .name = "Intel(R) Wireless N 3160",
138 .fw_name_pre = IWL3160_FW_PRE, 167 .fw_name_pre = IWL3160_FW_PRE,
139 IWL_DEVICE_7000, 168 IWL_DEVICE_7000,
140 .ht_params = &iwl7000_ht_params, 169 .ht_params = &iwl7000_ht_params,
diff --git a/drivers/net/wireless/iwlwifi/iwl-config.h b/drivers/net/wireless/iwlwifi/iwl-config.h
index c38aa8f77554..a193832fc790 100644
--- a/drivers/net/wireless/iwlwifi/iwl-config.h
+++ b/drivers/net/wireless/iwlwifi/iwl-config.h
@@ -136,17 +136,9 @@ enum iwl_led_mode {
136 * @led_compensation: compensate on the led on/off time per HW according 136 * @led_compensation: compensate on the led on/off time per HW according
137 * to the deviation to achieve the desired led frequency. 137 * to the deviation to achieve the desired led frequency.
138 * The detail algorithm is described in iwl-led.c 138 * The detail algorithm is described in iwl-led.c
139 * @chain_noise_num_beacons: number of beacons used to compute chain noise
140 * @adv_thermal_throttle: support advance thermal throttle
141 * @support_ct_kill_exit: support ct kill exit condition
142 * @plcp_delta_threshold: plcp error rate threshold used to trigger
143 * radio tuning when there is a high receiving plcp error rate
144 * @chain_noise_scale: default chain noise scale used for gain computation
145 * @wd_timeout: TX queues watchdog timeout 139 * @wd_timeout: TX queues watchdog timeout
146 * @max_event_log_size: size of event log buffer size for ucode event logging 140 * @max_event_log_size: size of event log buffer size for ucode event logging
147 * @shadow_reg_enable: HW shadow register support 141 * @shadow_reg_enable: HW shadow register support
148 * @hd_v2: v2 of enhanced sensitivity value, used for 2000 series and up
149 * @no_idle_support: do not support idle mode
150 */ 142 */
151struct iwl_base_params { 143struct iwl_base_params {
152 int eeprom_size; 144 int eeprom_size;
@@ -157,31 +149,9 @@ struct iwl_base_params {
157 const u16 max_ll_items; 149 const u16 max_ll_items;
158 const bool shadow_ram_support; 150 const bool shadow_ram_support;
159 u16 led_compensation; 151 u16 led_compensation;
160 bool adv_thermal_throttle;
161 bool support_ct_kill_exit;
162 u8 plcp_delta_threshold;
163 s32 chain_noise_scale;
164 unsigned int wd_timeout; 152 unsigned int wd_timeout;
165 u32 max_event_log_size; 153 u32 max_event_log_size;
166 const bool shadow_reg_enable; 154 const bool shadow_reg_enable;
167 const bool hd_v2;
168 const bool no_idle_support;
169};
170
171/*
172 * @advanced_bt_coexist: support advanced bt coexist
173 * @bt_init_traffic_load: specify initial bt traffic load
174 * @bt_prio_boost: default bt priority boost value
175 * @agg_time_limit: maximum number of uSec in aggregation
176 * @bt_sco_disable: uCode should not response to BT in SCO/ESCO mode
177 */
178struct iwl_bt_params {
179 bool advanced_bt_coexist;
180 u8 bt_init_traffic_load;
181 u32 bt_prio_boost;
182 u16 agg_time_limit;
183 bool bt_sco_disable;
184 bool bt_session_2;
185}; 155};
186 156
187/* 157/*
@@ -231,16 +201,10 @@ struct iwl_eeprom_params {
231 * @nvm_calib_ver: NVM calibration version 201 * @nvm_calib_ver: NVM calibration version
232 * @lib: pointer to the lib ops 202 * @lib: pointer to the lib ops
233 * @base_params: pointer to basic parameters 203 * @base_params: pointer to basic parameters
234 * @ht_params: point to ht patameters 204 * @ht_params: point to ht parameters
235 * @bt_params: pointer to bt parameters
236 * @need_temp_offset_calib: need to perform temperature offset calibration
237 * @no_xtal_calib: some devices do not need crystal calibration data,
238 * don't send it to those
239 * @led_mode: 0=blinking, 1=On(RF On)/Off(RF Off) 205 * @led_mode: 0=blinking, 1=On(RF On)/Off(RF Off)
240 * @adv_pm: advance power management
241 * @rx_with_siso_diversity: 1x1 device with rx antenna diversity 206 * @rx_with_siso_diversity: 1x1 device with rx antenna diversity
242 * @internal_wimax_coex: internal wifi/wimax combo device 207 * @internal_wimax_coex: internal wifi/wimax combo device
243 * @temp_offset_v2: support v2 of temperature offset calibration
244 * 208 *
245 * We enable the driver to be backward compatible wrt. hardware features. 209 * We enable the driver to be backward compatible wrt. hardware features.
246 * API differences in uCode shouldn't be handled here but through TLVs 210 * API differences in uCode shouldn't be handled here but through TLVs
@@ -264,15 +228,10 @@ struct iwl_cfg {
264 const struct iwl_base_params *base_params; 228 const struct iwl_base_params *base_params;
265 /* params likely to change within a device family */ 229 /* params likely to change within a device family */
266 const struct iwl_ht_params *ht_params; 230 const struct iwl_ht_params *ht_params;
267 const struct iwl_bt_params *bt_params;
268 const struct iwl_eeprom_params *eeprom_params; 231 const struct iwl_eeprom_params *eeprom_params;
269 const bool need_temp_offset_calib; /* if used set to true */
270 const bool no_xtal_calib;
271 enum iwl_led_mode led_mode; 232 enum iwl_led_mode led_mode;
272 const bool adv_pm;
273 const bool rx_with_siso_diversity; 233 const bool rx_with_siso_diversity;
274 const bool internal_wimax_coex; 234 const bool internal_wimax_coex;
275 const bool temp_offset_v2;
276}; 235};
277 236
278/* 237/*
@@ -320,6 +279,10 @@ extern const struct iwl_cfg iwl105_bgn_cfg;
320extern const struct iwl_cfg iwl105_bgn_d_cfg; 279extern const struct iwl_cfg iwl105_bgn_d_cfg;
321extern const struct iwl_cfg iwl135_bgn_cfg; 280extern const struct iwl_cfg iwl135_bgn_cfg;
322extern const struct iwl_cfg iwl7260_2ac_cfg; 281extern const struct iwl_cfg iwl7260_2ac_cfg;
323extern const struct iwl_cfg iwl3160_ac_cfg; 282extern const struct iwl_cfg iwl7260_2n_cfg;
283extern const struct iwl_cfg iwl7260_n_cfg;
284extern const struct iwl_cfg iwl3160_2ac_cfg;
285extern const struct iwl_cfg iwl3160_2n_cfg;
286extern const struct iwl_cfg iwl3160_n_cfg;
324 287
325#endif /* __IWL_CONFIG_H__ */ 288#endif /* __IWL_CONFIG_H__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h
index 20e845d4da04..a276af476e2d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-csr.h
+++ b/drivers/net/wireless/iwlwifi/iwl-csr.h
@@ -472,4 +472,23 @@
472#define IWL_HOST_INT_CALIB_TIMEOUT_DEF (0x10) 472#define IWL_HOST_INT_CALIB_TIMEOUT_DEF (0x10)
473#define IWL_HOST_INT_CALIB_TIMEOUT_MIN (0x0) 473#define IWL_HOST_INT_CALIB_TIMEOUT_MIN (0x0)
474 474
475/*****************************************************************************
476 * 7000/3000 series SHR DTS addresses *
477 *****************************************************************************/
478
479/* Diode Results Register Structure: */
480enum dtd_diode_reg {
481 DTS_DIODE_REG_DIG_VAL = 0x000000FF, /* bits [7:0] */
482 DTS_DIODE_REG_VREF_LOW = 0x0000FF00, /* bits [15:8] */
483 DTS_DIODE_REG_VREF_HIGH = 0x00FF0000, /* bits [23:16] */
484 DTS_DIODE_REG_VREF_ID = 0x03000000, /* bits [25:24] */
485 DTS_DIODE_REG_PASS_ONCE = 0x80000000, /* bits [31:31] */
486 DTS_DIODE_REG_FLAGS_MSK = 0xFF000000, /* bits [31:24] */
487/* Those are the masks INSIDE the flags bit-field: */
488 DTS_DIODE_REG_FLAGS_VREFS_ID_POS = 0,
489 DTS_DIODE_REG_FLAGS_VREFS_ID = 0x00000003, /* bits [1:0] */
490 DTS_DIODE_REG_FLAGS_PASS_ONCE_POS = 7,
491 DTS_DIODE_REG_FLAGS_PASS_ONCE = 0x00000080, /* bits [7:7] */
492};
493
475#endif /* !__iwl_csr_h__ */ 494#endif /* !__iwl_csr_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c
index 39aad9893e0b..4f886133639a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-drv.c
+++ b/drivers/net/wireless/iwlwifi/iwl-drv.c
@@ -1234,6 +1234,9 @@ MODULE_PARM_DESC(wd_disable,
1234 "Disable stuck queue watchdog timer 0=system default, " 1234 "Disable stuck queue watchdog timer 0=system default, "
1235 "1=disable, 2=enable (default: 0)"); 1235 "1=disable, 2=enable (default: 0)");
1236 1236
1237module_param_named(nvm_file, iwlwifi_mod_params.nvm_file, charp, S_IRUGO);
1238MODULE_PARM_DESC(nvm_file, "NVM file name");
1239
1237/* 1240/*
1238 * set bt_coex_active to true, uCode will do kill/defer 1241 * set bt_coex_active to true, uCode will do kill/defer
1239 * every time the priority line is asserted (BT is sending signals on the 1242 * every time the priority line is asserted (BT is sending signals on the
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c
index 600c9fdd7f71..4c887f365908 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c
@@ -732,17 +732,16 @@ int iwl_init_sband_channels(struct iwl_nvm_data *data,
732void iwl_init_ht_hw_capab(const struct iwl_cfg *cfg, 732void iwl_init_ht_hw_capab(const struct iwl_cfg *cfg,
733 struct iwl_nvm_data *data, 733 struct iwl_nvm_data *data,
734 struct ieee80211_sta_ht_cap *ht_info, 734 struct ieee80211_sta_ht_cap *ht_info,
735 enum ieee80211_band band) 735 enum ieee80211_band band,
736 u8 tx_chains, u8 rx_chains)
736{ 737{
737 int max_bit_rate = 0; 738 int max_bit_rate = 0;
738 u8 rx_chains;
739 u8 tx_chains;
740 739
741 tx_chains = hweight8(data->valid_tx_ant); 740 tx_chains = hweight8(tx_chains);
742 if (cfg->rx_with_siso_diversity) 741 if (cfg->rx_with_siso_diversity)
743 rx_chains = 1; 742 rx_chains = 1;
744 else 743 else
745 rx_chains = hweight8(data->valid_rx_ant); 744 rx_chains = hweight8(rx_chains);
746 745
747 if (!(data->sku_cap_11n_enable) || !cfg->ht_params) { 746 if (!(data->sku_cap_11n_enable) || !cfg->ht_params) {
748 ht_info->ht_supported = false; 747 ht_info->ht_supported = false;
@@ -806,7 +805,8 @@ static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
806 sband->n_bitrates = N_RATES_24; 805 sband->n_bitrates = N_RATES_24;
807 n_used += iwl_init_sband_channels(data, sband, n_channels, 806 n_used += iwl_init_sband_channels(data, sband, n_channels,
808 IEEE80211_BAND_2GHZ); 807 IEEE80211_BAND_2GHZ);
809 iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, IEEE80211_BAND_2GHZ); 808 iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, IEEE80211_BAND_2GHZ,
809 data->valid_tx_ant, data->valid_rx_ant);
810 810
811 sband = &data->bands[IEEE80211_BAND_5GHZ]; 811 sband = &data->bands[IEEE80211_BAND_5GHZ];
812 sband->band = IEEE80211_BAND_5GHZ; 812 sband->band = IEEE80211_BAND_5GHZ;
@@ -814,7 +814,8 @@ static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
814 sband->n_bitrates = N_RATES_52; 814 sband->n_bitrates = N_RATES_52;
815 n_used += iwl_init_sband_channels(data, sband, n_channels, 815 n_used += iwl_init_sband_channels(data, sband, n_channels,
816 IEEE80211_BAND_5GHZ); 816 IEEE80211_BAND_5GHZ);
817 iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, IEEE80211_BAND_5GHZ); 817 iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, IEEE80211_BAND_5GHZ,
818 data->valid_tx_ant, data->valid_rx_ant);
818 819
819 if (n_channels != n_used) 820 if (n_channels != n_used)
820 IWL_ERR_DEV(dev, "EEPROM: used only %d of %d channels\n", 821 IWL_ERR_DEV(dev, "EEPROM: used only %d of %d channels\n",
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h
index 37f115390b19..d73304a23ec2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h
@@ -133,6 +133,7 @@ int iwl_init_sband_channels(struct iwl_nvm_data *data,
133void iwl_init_ht_hw_capab(const struct iwl_cfg *cfg, 133void iwl_init_ht_hw_capab(const struct iwl_cfg *cfg,
134 struct iwl_nvm_data *data, 134 struct iwl_nvm_data *data,
135 struct ieee80211_sta_ht_cap *ht_info, 135 struct ieee80211_sta_ht_cap *ht_info,
136 enum ieee80211_band band); 136 enum ieee80211_band band,
137 u8 tx_chains, u8 rx_chains);
137 138
138#endif /* __iwl_eeprom_parse_h__ */ 139#endif /* __iwl_eeprom_parse_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw.h b/drivers/net/wireless/iwlwifi/iwl-fw.h
index c4c446d41eb0..f844d5c748c0 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fw.h
@@ -106,11 +106,14 @@ enum iwl_ucode_type {
106 106
107/* 107/*
108 * enumeration of ucode section. 108 * enumeration of ucode section.
109 * This enumeration is used for legacy tlv style (before 16.0 uCode). 109 * This enumeration is used directly for older firmware (before 16.0).
110 * For new firmware, there can be up to 4 sections (see below) but the
111 * first one packaged into the firmware file is the DATA section and
112 * some debugging code accesses that.
110 */ 113 */
111enum iwl_ucode_sec { 114enum iwl_ucode_sec {
112 IWL_UCODE_SECTION_INST,
113 IWL_UCODE_SECTION_DATA, 115 IWL_UCODE_SECTION_DATA,
116 IWL_UCODE_SECTION_INST,
114}; 117};
115/* 118/*
116 * For 16.0 uCode and above, there is no differentiation between sections, 119 * For 16.0 uCode and above, there is no differentiation between sections,
diff --git a/drivers/net/wireless/iwlwifi/iwl-modparams.h b/drivers/net/wireless/iwlwifi/iwl-modparams.h
index d6f6c37c09fd..36dfe0919f6b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-modparams.h
+++ b/drivers/net/wireless/iwlwifi/iwl-modparams.h
@@ -119,6 +119,7 @@ struct iwl_mod_params {
119 int ant_coupling; 119 int ant_coupling;
120 bool bt_ch_announce; 120 bool bt_ch_announce;
121 bool auto_agg; 121 bool auto_agg;
122 char *nvm_file;
122}; 123};
123 124
124#endif /* #__iwl_modparams_h__ */ 125#endif /* #__iwl_modparams_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
index 6199a0a597a6..acd2665afb8c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
+++ b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
@@ -89,6 +89,7 @@ enum nvm_sku_bits {
89 NVM_SKU_CAP_BAND_24GHZ = BIT(0), 89 NVM_SKU_CAP_BAND_24GHZ = BIT(0),
90 NVM_SKU_CAP_BAND_52GHZ = BIT(1), 90 NVM_SKU_CAP_BAND_52GHZ = BIT(1),
91 NVM_SKU_CAP_11N_ENABLE = BIT(2), 91 NVM_SKU_CAP_11N_ENABLE = BIT(2),
92 NVM_SKU_CAP_11AC_ENABLE = BIT(3),
92}; 93};
93 94
94/* radio config bits (actual values from NVM definition) */ 95/* radio config bits (actual values from NVM definition) */
@@ -258,8 +259,6 @@ static void iwl_init_vht_hw_capab(const struct iwl_cfg *cfg,
258 struct iwl_nvm_data *data, 259 struct iwl_nvm_data *data,
259 struct ieee80211_sta_vht_cap *vht_cap) 260 struct ieee80211_sta_vht_cap *vht_cap)
260{ 261{
261 /* For now, assume new devices with NVM are VHT capable */
262
263 vht_cap->vht_supported = true; 262 vht_cap->vht_supported = true;
264 263
265 vht_cap->cap = IEEE80211_VHT_CAP_SHORT_GI_80 | 264 vht_cap->cap = IEEE80211_VHT_CAP_SHORT_GI_80 |
@@ -292,7 +291,8 @@ static void iwl_init_vht_hw_capab(const struct iwl_cfg *cfg,
292} 291}
293 292
294static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg, 293static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
295 struct iwl_nvm_data *data, const __le16 *nvm_sw) 294 struct iwl_nvm_data *data, const __le16 *nvm_sw,
295 bool enable_vht, u8 tx_chains, u8 rx_chains)
296{ 296{
297 int n_channels = iwl_init_channel_map(dev, cfg, data, 297 int n_channels = iwl_init_channel_map(dev, cfg, data,
298 &nvm_sw[NVM_CHANNELS]); 298 &nvm_sw[NVM_CHANNELS]);
@@ -305,7 +305,8 @@ static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
305 sband->n_bitrates = N_RATES_24; 305 sband->n_bitrates = N_RATES_24;
306 n_used += iwl_init_sband_channels(data, sband, n_channels, 306 n_used += iwl_init_sband_channels(data, sband, n_channels,
307 IEEE80211_BAND_2GHZ); 307 IEEE80211_BAND_2GHZ);
308 iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, IEEE80211_BAND_2GHZ); 308 iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, IEEE80211_BAND_2GHZ,
309 tx_chains, rx_chains);
309 310
310 sband = &data->bands[IEEE80211_BAND_5GHZ]; 311 sband = &data->bands[IEEE80211_BAND_5GHZ];
311 sband->band = IEEE80211_BAND_5GHZ; 312 sband->band = IEEE80211_BAND_5GHZ;
@@ -313,8 +314,10 @@ static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
313 sband->n_bitrates = N_RATES_52; 314 sband->n_bitrates = N_RATES_52;
314 n_used += iwl_init_sband_channels(data, sband, n_channels, 315 n_used += iwl_init_sband_channels(data, sband, n_channels,
315 IEEE80211_BAND_5GHZ); 316 IEEE80211_BAND_5GHZ);
316 iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, IEEE80211_BAND_5GHZ); 317 iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, IEEE80211_BAND_5GHZ,
317 iwl_init_vht_hw_capab(cfg, data, &sband->vht_cap); 318 tx_chains, rx_chains);
319 if (enable_vht)
320 iwl_init_vht_hw_capab(cfg, data, &sband->vht_cap);
318 321
319 if (n_channels != n_used) 322 if (n_channels != n_used)
320 IWL_ERR_DEV(dev, "NVM: used only %d of %d channels\n", 323 IWL_ERR_DEV(dev, "NVM: used only %d of %d channels\n",
@@ -324,7 +327,7 @@ static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
324struct iwl_nvm_data * 327struct iwl_nvm_data *
325iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg, 328iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg,
326 const __le16 *nvm_hw, const __le16 *nvm_sw, 329 const __le16 *nvm_hw, const __le16 *nvm_sw,
327 const __le16 *nvm_calib) 330 const __le16 *nvm_calib, u8 tx_chains, u8 rx_chains)
328{ 331{
329 struct iwl_nvm_data *data; 332 struct iwl_nvm_data *data;
330 u8 hw_addr[ETH_ALEN]; 333 u8 hw_addr[ETH_ALEN];
@@ -380,7 +383,8 @@ iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg,
380 data->hw_addr[4] = hw_addr[5]; 383 data->hw_addr[4] = hw_addr[5];
381 data->hw_addr[5] = hw_addr[4]; 384 data->hw_addr[5] = hw_addr[4];
382 385
383 iwl_init_sbands(dev, cfg, data, nvm_sw); 386 iwl_init_sbands(dev, cfg, data, nvm_sw, sku & NVM_SKU_CAP_11AC_ENABLE,
387 tx_chains, rx_chains);
384 388
385 data->calib_version = 255; /* TODO: 389 data->calib_version = 255; /* TODO:
386 this value will prevent some checks from 390 this value will prevent some checks from
diff --git a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h
index e57fb989661e..3325059c52d4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h
+++ b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h
@@ -75,6 +75,6 @@
75struct iwl_nvm_data * 75struct iwl_nvm_data *
76iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg, 76iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg,
77 const __le16 *nvm_hw, const __le16 *nvm_sw, 77 const __le16 *nvm_hw, const __le16 *nvm_sw,
78 const __le16 *nvm_calib); 78 const __le16 *nvm_calib, u8 tx_chains, u8 rx_chains);
79 79
80#endif /* __iwl_nvm_parse_h__ */ 80#endif /* __iwl_nvm_parse_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h
index 386f2a7c87cb..ff8cc75c189d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-prph.h
+++ b/drivers/net/wireless/iwlwifi/iwl-prph.h
@@ -100,6 +100,18 @@
100/* Device system time */ 100/* Device system time */
101#define DEVICE_SYSTEM_TIME_REG 0xA0206C 101#define DEVICE_SYSTEM_TIME_REG 0xA0206C
102 102
103/*****************************************************************************
104 * 7000/3000 series SHR DTS addresses *
105 *****************************************************************************/
106
107#define SHR_MISC_WFM_DTS_EN (0x00a10024)
108#define DTSC_CFG_MODE (0x00a10604)
109#define DTSC_VREF_AVG (0x00a10648)
110#define DTSC_VREF5_AVG (0x00a1064c)
111#define DTSC_CFG_MODE_PERIODIC (0x2)
112#define DTSC_PTAT_AVG (0x00a10650)
113
114
103/** 115/**
104 * Tx Scheduler 116 * Tx Scheduler
105 * 117 *
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h
index 7a13790b5bfe..be4b2ac3dbbf 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/iwlwifi/iwl-trans.h
@@ -189,7 +189,8 @@ enum CMD_MODE {
189 CMD_SYNC = 0, 189 CMD_SYNC = 0,
190 CMD_ASYNC = BIT(0), 190 CMD_ASYNC = BIT(0),
191 CMD_WANT_SKB = BIT(1), 191 CMD_WANT_SKB = BIT(1),
192 CMD_ON_DEMAND = BIT(2), 192 CMD_SEND_IN_RFKILL = BIT(2),
193 CMD_ON_DEMAND = BIT(3),
193}; 194};
194 195
195#define DEF_CMD_PAYLOAD_SIZE 320 196#define DEF_CMD_PAYLOAD_SIZE 320
@@ -427,8 +428,9 @@ struct iwl_trans_ops {
427 void (*fw_alive)(struct iwl_trans *trans, u32 scd_addr); 428 void (*fw_alive)(struct iwl_trans *trans, u32 scd_addr);
428 void (*stop_device)(struct iwl_trans *trans); 429 void (*stop_device)(struct iwl_trans *trans);
429 430
430 void (*d3_suspend)(struct iwl_trans *trans); 431 void (*d3_suspend)(struct iwl_trans *trans, bool test);
431 int (*d3_resume)(struct iwl_trans *trans, enum iwl_d3_status *status); 432 int (*d3_resume)(struct iwl_trans *trans, enum iwl_d3_status *status,
433 bool test);
432 434
433 int (*send_cmd)(struct iwl_trans *trans, struct iwl_host_cmd *cmd); 435 int (*send_cmd)(struct iwl_trans *trans, struct iwl_host_cmd *cmd);
434 436
@@ -455,7 +457,7 @@ struct iwl_trans_ops {
455 int (*read_mem)(struct iwl_trans *trans, u32 addr, 457 int (*read_mem)(struct iwl_trans *trans, u32 addr,
456 void *buf, int dwords); 458 void *buf, int dwords);
457 int (*write_mem)(struct iwl_trans *trans, u32 addr, 459 int (*write_mem)(struct iwl_trans *trans, u32 addr,
458 void *buf, int dwords); 460 const void *buf, int dwords);
459 void (*configure)(struct iwl_trans *trans, 461 void (*configure)(struct iwl_trans *trans,
460 const struct iwl_trans_config *trans_cfg); 462 const struct iwl_trans_config *trans_cfg);
461 void (*set_pmi)(struct iwl_trans *trans, bool state); 463 void (*set_pmi)(struct iwl_trans *trans, bool state);
@@ -587,17 +589,18 @@ static inline void iwl_trans_stop_device(struct iwl_trans *trans)
587 trans->state = IWL_TRANS_NO_FW; 589 trans->state = IWL_TRANS_NO_FW;
588} 590}
589 591
590static inline void iwl_trans_d3_suspend(struct iwl_trans *trans) 592static inline void iwl_trans_d3_suspend(struct iwl_trans *trans, bool test)
591{ 593{
592 might_sleep(); 594 might_sleep();
593 trans->ops->d3_suspend(trans); 595 trans->ops->d3_suspend(trans, test);
594} 596}
595 597
596static inline int iwl_trans_d3_resume(struct iwl_trans *trans, 598static inline int iwl_trans_d3_resume(struct iwl_trans *trans,
597 enum iwl_d3_status *status) 599 enum iwl_d3_status *status,
600 bool test)
598{ 601{
599 might_sleep(); 602 might_sleep();
600 return trans->ops->d3_resume(trans, status); 603 return trans->ops->d3_resume(trans, status, test);
601} 604}
602 605
603static inline int iwl_trans_send_cmd(struct iwl_trans *trans, 606static inline int iwl_trans_send_cmd(struct iwl_trans *trans,
@@ -761,7 +764,7 @@ static inline u32 iwl_trans_read_mem32(struct iwl_trans *trans, u32 addr)
761} 764}
762 765
763static inline int iwl_trans_write_mem(struct iwl_trans *trans, u32 addr, 766static inline int iwl_trans_write_mem(struct iwl_trans *trans, u32 addr,
764 void *buf, int dwords) 767 const void *buf, int dwords)
765{ 768{
766 return trans->ops->write_mem(trans, addr, buf, dwords); 769 return trans->ops->write_mem(trans, addr, buf, dwords);
767} 770}
diff --git a/drivers/net/wireless/iwlwifi/mvm/Makefile b/drivers/net/wireless/iwlwifi/mvm/Makefile
index 2acc44b40986..ff856e543ae8 100644
--- a/drivers/net/wireless/iwlwifi/mvm/Makefile
+++ b/drivers/net/wireless/iwlwifi/mvm/Makefile
@@ -3,7 +3,7 @@ iwlmvm-y += fw.o mac80211.o nvm.o ops.o phy-ctxt.o mac-ctxt.o
3iwlmvm-y += utils.o rx.o tx.o binding.o quota.o sta.o 3iwlmvm-y += utils.o rx.o tx.o binding.o quota.o sta.o
4iwlmvm-y += scan.o time-event.o rs.o 4iwlmvm-y += scan.o time-event.o rs.o
5iwlmvm-y += power.o bt-coex.o 5iwlmvm-y += power.o bt-coex.o
6iwlmvm-y += led.o 6iwlmvm-y += led.o tt.o
7iwlmvm-$(CONFIG_IWLWIFI_DEBUGFS) += debugfs.o 7iwlmvm-$(CONFIG_IWLWIFI_DEBUGFS) += debugfs.o
8iwlmvm-$(CONFIG_PM_SLEEP) += d3.o 8iwlmvm-$(CONFIG_PM_SLEEP) += d3.o
9 9
diff --git a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c
index 810bfa5f6de0..9a4d94a1f90d 100644
--- a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c
+++ b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c
@@ -174,7 +174,7 @@ static const __le32 iwl_tight_lookup[BT_COEX_LUT_SIZE] = {
174static const __le32 iwl_loose_lookup[BT_COEX_LUT_SIZE] = { 174static const __le32 iwl_loose_lookup[BT_COEX_LUT_SIZE] = {
175 cpu_to_le32(0xaaaaaaaa), 175 cpu_to_le32(0xaaaaaaaa),
176 cpu_to_le32(0xaaaaaaaa), 176 cpu_to_le32(0xaaaaaaaa),
177 cpu_to_le32(0xaeaaaaaa), 177 cpu_to_le32(0xaaaaaaaa),
178 cpu_to_le32(0xaaaaaaaa), 178 cpu_to_le32(0xaaaaaaaa),
179 cpu_to_le32(0xcc00ff28), 179 cpu_to_le32(0xcc00ff28),
180 cpu_to_le32(0x0000aaaa), 180 cpu_to_le32(0x0000aaaa),
@@ -351,6 +351,7 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac,
351 enum ieee80211_band band; 351 enum ieee80211_band band;
352 int ave_rssi; 352 int ave_rssi;
353 353
354 lockdep_assert_held(&mvm->mutex);
354 if (vif->type != NL80211_IFTYPE_STATION) 355 if (vif->type != NL80211_IFTYPE_STATION)
355 return; 356 return;
356 357
@@ -365,7 +366,8 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac,
365 smps_mode = IEEE80211_SMPS_AUTOMATIC; 366 smps_mode = IEEE80211_SMPS_AUTOMATIC;
366 367
367 if (band != IEEE80211_BAND_2GHZ) { 368 if (band != IEEE80211_BAND_2GHZ) {
368 ieee80211_request_smps(vif, smps_mode); 369 iwl_mvm_update_smps(mvm, vif, IWL_MVM_SMPS_REQ_BT_COEX,
370 smps_mode);
369 return; 371 return;
370 } 372 }
371 373
@@ -380,7 +382,7 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac,
380 mvmvif->id, data->notif->bt_status, 382 mvmvif->id, data->notif->bt_status,
381 data->notif->bt_traffic_load, smps_mode); 383 data->notif->bt_traffic_load, smps_mode);
382 384
383 ieee80211_request_smps(vif, smps_mode); 385 iwl_mvm_update_smps(mvm, vif, IWL_MVM_SMPS_REQ_BT_COEX, smps_mode);
384 386
385 /* don't reduce the Tx power if in loose scheme */ 387 /* don't reduce the Tx power if in loose scheme */
386 if (is_loose_coex()) 388 if (is_loose_coex())
diff --git a/drivers/net/wireless/iwlwifi/mvm/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c
index 16bbdcc8627a..7a2ef3f013fd 100644
--- a/drivers/net/wireless/iwlwifi/mvm/d3.c
+++ b/drivers/net/wireless/iwlwifi/mvm/d3.c
@@ -63,6 +63,7 @@
63 63
64#include <linux/etherdevice.h> 64#include <linux/etherdevice.h>
65#include <linux/ip.h> 65#include <linux/ip.h>
66#include <linux/fs.h>
66#include <net/cfg80211.h> 67#include <net/cfg80211.h>
67#include <net/ipv6.h> 68#include <net/ipv6.h>
68#include <net/tcp.h> 69#include <net/tcp.h>
@@ -756,7 +757,9 @@ static int iwl_mvm_d3_reprogram(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
756 return 0; 757 return 0;
757} 758}
758 759
759int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) 760static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
761 struct cfg80211_wowlan *wowlan,
762 bool test)
760{ 763{
761 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 764 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
762 struct iwl_d3_iter_data suspend_iter_data = { 765 struct iwl_d3_iter_data suspend_iter_data = {
@@ -769,7 +772,7 @@ int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
769 struct iwl_wowlan_config_cmd wowlan_config_cmd = {}; 772 struct iwl_wowlan_config_cmd wowlan_config_cmd = {};
770 struct iwl_wowlan_kek_kck_material_cmd kek_kck_cmd = {}; 773 struct iwl_wowlan_kek_kck_material_cmd kek_kck_cmd = {};
771 struct iwl_wowlan_tkip_params_cmd tkip_cmd = {}; 774 struct iwl_wowlan_tkip_params_cmd tkip_cmd = {};
772 struct iwl_d3_manager_config d3_cfg_cmd = { 775 struct iwl_d3_manager_config d3_cfg_cmd_data = {
773 /* 776 /*
774 * Program the minimum sleep time to 10 seconds, as many 777 * Program the minimum sleep time to 10 seconds, as many
775 * platforms have issues processing a wakeup signal while 778 * platforms have issues processing a wakeup signal while
@@ -777,17 +780,30 @@ int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
777 */ 780 */
778 .min_sleep_time = cpu_to_le32(10 * 1000 * 1000), 781 .min_sleep_time = cpu_to_le32(10 * 1000 * 1000),
779 }; 782 };
783 struct iwl_host_cmd d3_cfg_cmd = {
784 .id = D3_CONFIG_CMD,
785 .flags = CMD_SYNC | CMD_WANT_SKB,
786 .data[0] = &d3_cfg_cmd_data,
787 .len[0] = sizeof(d3_cfg_cmd_data),
788 };
780 struct wowlan_key_data key_data = { 789 struct wowlan_key_data key_data = {
781 .use_rsc_tsc = false, 790 .use_rsc_tsc = false,
782 .tkip = &tkip_cmd, 791 .tkip = &tkip_cmd,
783 .use_tkip = false, 792 .use_tkip = false,
784 }; 793 };
785 int ret, i; 794 int ret, i;
795 int len __maybe_unused;
786 u16 seq; 796 u16 seq;
787 u8 old_aux_sta_id, old_ap_sta_id = IWL_MVM_STATION_COUNT; 797 u8 old_aux_sta_id, old_ap_sta_id = IWL_MVM_STATION_COUNT;
788 798
789 if (WARN_ON(!wowlan)) 799 if (!wowlan) {
800 /*
801 * mac80211 shouldn't get here, but for D3 test
802 * it doesn't warrant a warning
803 */
804 WARN_ON(!test);
790 return -EINVAL; 805 return -EINVAL;
806 }
791 807
792 key_data.rsc_tsc = kzalloc(sizeof(*key_data.rsc_tsc), GFP_KERNEL); 808 key_data.rsc_tsc = kzalloc(sizeof(*key_data.rsc_tsc), GFP_KERNEL);
793 if (!key_data.rsc_tsc) 809 if (!key_data.rsc_tsc)
@@ -1007,15 +1023,31 @@ int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
1007 if (ret) 1023 if (ret)
1008 goto out; 1024 goto out;
1009 1025
1026 ret = iwl_mvm_power_update_mode(mvm, vif);
1027 if (ret)
1028 goto out;
1029
1010 /* must be last -- this switches firmware state */ 1030 /* must be last -- this switches firmware state */
1011 ret = iwl_mvm_send_cmd_pdu(mvm, D3_CONFIG_CMD, CMD_SYNC, 1031 ret = iwl_mvm_send_cmd(mvm, &d3_cfg_cmd);
1012 sizeof(d3_cfg_cmd), &d3_cfg_cmd);
1013 if (ret) 1032 if (ret)
1014 goto out; 1033 goto out;
1034#ifdef CONFIG_IWLWIFI_DEBUGFS
1035 len = le32_to_cpu(d3_cfg_cmd.resp_pkt->len_n_flags) &
1036 FH_RSCSR_FRAME_SIZE_MSK;
1037 if (len >= sizeof(u32) * 2) {
1038 mvm->d3_test_pme_ptr =
1039 le32_to_cpup((__le32 *)d3_cfg_cmd.resp_pkt->data);
1040 } else if (test) {
1041 /* in test mode we require the pointer */
1042 ret = -EIO;
1043 goto out;
1044 }
1045#endif
1046 iwl_free_resp(&d3_cfg_cmd);
1015 1047
1016 clear_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status); 1048 clear_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status);
1017 1049
1018 iwl_trans_d3_suspend(mvm->trans); 1050 iwl_trans_d3_suspend(mvm->trans, test);
1019 out: 1051 out:
1020 mvm->aux_sta.sta_id = old_aux_sta_id; 1052 mvm->aux_sta.sta_id = old_aux_sta_id;
1021 mvm_ap_sta->sta_id = old_ap_sta_id; 1053 mvm_ap_sta->sta_id = old_ap_sta_id;
@@ -1030,6 +1062,11 @@ int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
1030 return ret; 1062 return ret;
1031} 1063}
1032 1064
1065int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
1066{
1067 return __iwl_mvm_suspend(hw, wowlan, false);
1068}
1069
1033static void iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm, 1070static void iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm,
1034 struct ieee80211_vif *vif) 1071 struct ieee80211_vif *vif)
1035{ 1072{
@@ -1214,9 +1251,28 @@ static void iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm,
1214 iwl_free_resp(&cmd); 1251 iwl_free_resp(&cmd);
1215} 1252}
1216 1253
1217int iwl_mvm_resume(struct ieee80211_hw *hw) 1254static void iwl_mvm_read_d3_sram(struct iwl_mvm *mvm)
1255{
1256#ifdef CONFIG_IWLWIFI_DEBUGFS
1257 const struct fw_img *img = &mvm->fw->img[IWL_UCODE_WOWLAN];
1258 u32 len = img->sec[IWL_UCODE_SECTION_DATA].len;
1259 u32 offs = img->sec[IWL_UCODE_SECTION_DATA].offset;
1260
1261 if (!mvm->store_d3_resume_sram)
1262 return;
1263
1264 if (!mvm->d3_resume_sram) {
1265 mvm->d3_resume_sram = kzalloc(len, GFP_KERNEL);
1266 if (!mvm->d3_resume_sram)
1267 return;
1268 }
1269
1270 iwl_trans_read_mem_bytes(mvm->trans, offs, mvm->d3_resume_sram, len);
1271#endif
1272}
1273
1274static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test)
1218{ 1275{
1219 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1220 struct iwl_d3_iter_data resume_iter_data = { 1276 struct iwl_d3_iter_data resume_iter_data = {
1221 .mvm = mvm, 1277 .mvm = mvm,
1222 }; 1278 };
@@ -1236,7 +1292,7 @@ int iwl_mvm_resume(struct ieee80211_hw *hw)
1236 1292
1237 vif = resume_iter_data.vif; 1293 vif = resume_iter_data.vif;
1238 1294
1239 ret = iwl_trans_d3_resume(mvm->trans, &d3_status); 1295 ret = iwl_trans_d3_resume(mvm->trans, &d3_status, test);
1240 if (ret) 1296 if (ret)
1241 goto out_unlock; 1297 goto out_unlock;
1242 1298
@@ -1245,12 +1301,15 @@ int iwl_mvm_resume(struct ieee80211_hw *hw)
1245 goto out_unlock; 1301 goto out_unlock;
1246 } 1302 }
1247 1303
1304 /* query SRAM first in case we want event logging */
1305 iwl_mvm_read_d3_sram(mvm);
1306
1248 iwl_mvm_query_wakeup_reasons(mvm, vif); 1307 iwl_mvm_query_wakeup_reasons(mvm, vif);
1249 1308
1250 out_unlock: 1309 out_unlock:
1251 mutex_unlock(&mvm->mutex); 1310 mutex_unlock(&mvm->mutex);
1252 1311
1253 if (vif) 1312 if (!test && vif)
1254 ieee80211_resume_disconnect(vif); 1313 ieee80211_resume_disconnect(vif);
1255 1314
1256 /* return 1 to reconfigure the device */ 1315 /* return 1 to reconfigure the device */
@@ -1258,9 +1317,106 @@ int iwl_mvm_resume(struct ieee80211_hw *hw)
1258 return 1; 1317 return 1;
1259} 1318}
1260 1319
1320int iwl_mvm_resume(struct ieee80211_hw *hw)
1321{
1322 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1323
1324 return __iwl_mvm_resume(mvm, false);
1325}
1326
1261void iwl_mvm_set_wakeup(struct ieee80211_hw *hw, bool enabled) 1327void iwl_mvm_set_wakeup(struct ieee80211_hw *hw, bool enabled)
1262{ 1328{
1263 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 1329 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1264 1330
1265 device_set_wakeup_enable(mvm->trans->dev, enabled); 1331 device_set_wakeup_enable(mvm->trans->dev, enabled);
1266} 1332}
1333
1334#ifdef CONFIG_IWLWIFI_DEBUGFS
1335static int iwl_mvm_d3_test_open(struct inode *inode, struct file *file)
1336{
1337 struct iwl_mvm *mvm = inode->i_private;
1338 int err;
1339
1340 if (mvm->d3_test_active)
1341 return -EBUSY;
1342
1343 file->private_data = inode->i_private;
1344
1345 ieee80211_stop_queues(mvm->hw);
1346 synchronize_net();
1347
1348 /* start pseudo D3 */
1349 rtnl_lock();
1350 err = __iwl_mvm_suspend(mvm->hw, mvm->hw->wiphy->wowlan_config, true);
1351 rtnl_unlock();
1352 if (err > 0)
1353 err = -EINVAL;
1354 if (err) {
1355 ieee80211_wake_queues(mvm->hw);
1356 return err;
1357 }
1358 mvm->d3_test_active = true;
1359 return 0;
1360}
1361
1362static ssize_t iwl_mvm_d3_test_read(struct file *file, char __user *user_buf,
1363 size_t count, loff_t *ppos)
1364{
1365 struct iwl_mvm *mvm = file->private_data;
1366 u32 pme_asserted;
1367
1368 while (true) {
1369 pme_asserted = iwl_trans_read_mem32(mvm->trans,
1370 mvm->d3_test_pme_ptr);
1371 if (pme_asserted)
1372 break;
1373 if (msleep_interruptible(100))
1374 break;
1375 }
1376
1377 return 0;
1378}
1379
1380static void iwl_mvm_d3_test_disconn_work_iter(void *_data, u8 *mac,
1381 struct ieee80211_vif *vif)
1382{
1383 if (vif->type == NL80211_IFTYPE_STATION)
1384 ieee80211_connection_loss(vif);
1385}
1386
1387static int iwl_mvm_d3_test_release(struct inode *inode, struct file *file)
1388{
1389 struct iwl_mvm *mvm = inode->i_private;
1390 int remaining_time = 10;
1391
1392 mvm->d3_test_active = false;
1393 __iwl_mvm_resume(mvm, true);
1394 iwl_abort_notification_waits(&mvm->notif_wait);
1395 ieee80211_restart_hw(mvm->hw);
1396
1397 /* wait for restart and disconnect all interfaces */
1398 while (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status) &&
1399 remaining_time > 0) {
1400 remaining_time--;
1401 msleep(1000);
1402 }
1403
1404 if (remaining_time == 0)
1405 IWL_ERR(mvm, "Timed out waiting for HW restart to finish!\n");
1406
1407 ieee80211_iterate_active_interfaces_atomic(
1408 mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
1409 iwl_mvm_d3_test_disconn_work_iter, NULL);
1410
1411 ieee80211_wake_queues(mvm->hw);
1412
1413 return 0;
1414}
1415
1416const struct file_operations iwl_dbgfs_d3_test_ops = {
1417 .llseek = no_llseek,
1418 .open = iwl_mvm_d3_test_open,
1419 .read = iwl_mvm_d3_test_read,
1420 .release = iwl_mvm_d3_test_release,
1421};
1422#endif
diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
index 2053dccefcd6..b7643c16201f 100644
--- a/drivers/net/wireless/iwlwifi/mvm/debugfs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
@@ -145,15 +145,18 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file, char __user *user_buf,
145 char *buf; 145 char *buf;
146 u8 *ptr; 146 u8 *ptr;
147 147
148 if (!mvm->ucode_loaded)
149 return -EINVAL;
150
148 /* default is to dump the entire data segment */ 151 /* default is to dump the entire data segment */
149 if (!mvm->dbgfs_sram_offset && !mvm->dbgfs_sram_len) { 152 if (!mvm->dbgfs_sram_offset && !mvm->dbgfs_sram_len) {
150 mvm->dbgfs_sram_offset = 0x800000;
151 if (!mvm->ucode_loaded)
152 return -EINVAL;
153 img = &mvm->fw->img[mvm->cur_ucode]; 153 img = &mvm->fw->img[mvm->cur_ucode];
154 mvm->dbgfs_sram_len = img->sec[IWL_UCODE_SECTION_DATA].len; 154 ofs = img->sec[IWL_UCODE_SECTION_DATA].offset;
155 len = img->sec[IWL_UCODE_SECTION_DATA].len;
156 } else {
157 ofs = mvm->dbgfs_sram_offset;
158 len = mvm->dbgfs_sram_len;
155 } 159 }
156 len = mvm->dbgfs_sram_len;
157 160
158 bufsz = len * 4 + 256; 161 bufsz = len * 4 + 256;
159 buf = kzalloc(bufsz, GFP_KERNEL); 162 buf = kzalloc(bufsz, GFP_KERNEL);
@@ -167,12 +170,9 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file, char __user *user_buf,
167 } 170 }
168 171
169 pos += scnprintf(buf + pos, bufsz - pos, "sram_len: 0x%x\n", len); 172 pos += scnprintf(buf + pos, bufsz - pos, "sram_len: 0x%x\n", len);
170 pos += scnprintf(buf + pos, bufsz - pos, "sram_offset: 0x%x\n", 173 pos += scnprintf(buf + pos, bufsz - pos, "sram_offset: 0x%x\n", ofs);
171 mvm->dbgfs_sram_offset);
172 174
173 iwl_trans_read_mem_bytes(mvm->trans, 175 iwl_trans_read_mem_bytes(mvm->trans, ofs, ptr, len);
174 mvm->dbgfs_sram_offset,
175 ptr, len);
176 for (ofs = 0; ofs < len; ofs += 16) { 176 for (ofs = 0; ofs < len; ofs += 16) {
177 pos += scnprintf(buf + pos, bufsz - pos, "0x%.4x ", ofs); 177 pos += scnprintf(buf + pos, bufsz - pos, "0x%.4x ", ofs);
178 hex_dump_to_buffer(ptr + ofs, 16, 16, 1, buf + pos, 178 hex_dump_to_buffer(ptr + ofs, 16, 16, 1, buf + pos,
@@ -300,6 +300,146 @@ static ssize_t iwl_dbgfs_power_down_d3_allow_write(struct file *file,
300 return count; 300 return count;
301} 301}
302 302
303static void iwl_dbgfs_update_pm(struct iwl_mvm *mvm,
304 struct ieee80211_vif *vif,
305 enum iwl_dbgfs_pm_mask param, int val)
306{
307 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
308 struct iwl_dbgfs_pm *dbgfs_pm = &mvmvif->dbgfs_pm;
309
310 dbgfs_pm->mask |= param;
311
312 switch (param) {
313 case MVM_DEBUGFS_PM_KEEP_ALIVE: {
314 struct ieee80211_hw *hw = mvm->hw;
315 int dtimper = hw->conf.ps_dtim_period ?: 1;
316 int dtimper_msec = dtimper * vif->bss_conf.beacon_int;
317
318 IWL_DEBUG_POWER(mvm, "debugfs: set keep_alive= %d sec\n", val);
319 if (val * MSEC_PER_SEC < 3 * dtimper_msec) {
320 IWL_WARN(mvm,
321 "debugfs: keep alive period (%ld msec) is less than minimum required (%d msec)\n",
322 val * MSEC_PER_SEC, 3 * dtimper_msec);
323 }
324 dbgfs_pm->keep_alive_seconds = val;
325 break;
326 }
327 case MVM_DEBUGFS_PM_SKIP_OVER_DTIM:
328 IWL_DEBUG_POWER(mvm, "skip_over_dtim %s\n",
329 val ? "enabled" : "disabled");
330 dbgfs_pm->skip_over_dtim = val;
331 break;
332 case MVM_DEBUGFS_PM_SKIP_DTIM_PERIODS:
333 IWL_DEBUG_POWER(mvm, "skip_dtim_periods=%d\n", val);
334 dbgfs_pm->skip_dtim_periods = val;
335 break;
336 case MVM_DEBUGFS_PM_RX_DATA_TIMEOUT:
337 IWL_DEBUG_POWER(mvm, "rx_data_timeout=%d\n", val);
338 dbgfs_pm->rx_data_timeout = val;
339 break;
340 case MVM_DEBUGFS_PM_TX_DATA_TIMEOUT:
341 IWL_DEBUG_POWER(mvm, "tx_data_timeout=%d\n", val);
342 dbgfs_pm->tx_data_timeout = val;
343 break;
344 case MVM_DEBUGFS_PM_DISABLE_POWER_OFF:
345 IWL_DEBUG_POWER(mvm, "disable_power_off=%d\n", val);
346 dbgfs_pm->disable_power_off = val;
347 break;
348 }
349}
350
351static ssize_t iwl_dbgfs_pm_params_write(struct file *file,
352 const char __user *user_buf,
353 size_t count, loff_t *ppos)
354{
355 struct ieee80211_vif *vif = file->private_data;
356 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
357 struct iwl_mvm *mvm = mvmvif->dbgfs_data;
358 enum iwl_dbgfs_pm_mask param;
359 char buf[32] = {};
360 int val;
361 int ret;
362
363 if (copy_from_user(buf, user_buf, sizeof(buf)))
364 return -EFAULT;
365
366 if (!strncmp("keep_alive=", buf, 11)) {
367 if (sscanf(buf + 11, "%d", &val) != 1)
368 return -EINVAL;
369 param = MVM_DEBUGFS_PM_KEEP_ALIVE;
370 } else if (!strncmp("skip_over_dtim=", buf, 15)) {
371 if (sscanf(buf + 15, "%d", &val) != 1)
372 return -EINVAL;
373 param = MVM_DEBUGFS_PM_SKIP_OVER_DTIM;
374 } else if (!strncmp("skip_dtim_periods=", buf, 18)) {
375 if (sscanf(buf + 18, "%d", &val) != 1)
376 return -EINVAL;
377 param = MVM_DEBUGFS_PM_SKIP_DTIM_PERIODS;
378 } else if (!strncmp("rx_data_timeout=", buf, 16)) {
379 if (sscanf(buf + 16, "%d", &val) != 1)
380 return -EINVAL;
381 param = MVM_DEBUGFS_PM_RX_DATA_TIMEOUT;
382 } else if (!strncmp("tx_data_timeout=", buf, 16)) {
383 if (sscanf(buf + 16, "%d", &val) != 1)
384 return -EINVAL;
385 param = MVM_DEBUGFS_PM_TX_DATA_TIMEOUT;
386 } else if (!strncmp("disable_power_off=", buf, 18)) {
387 if (sscanf(buf + 18, "%d", &val) != 1)
388 return -EINVAL;
389 param = MVM_DEBUGFS_PM_DISABLE_POWER_OFF;
390 } else {
391 return -EINVAL;
392 }
393
394 mutex_lock(&mvm->mutex);
395 iwl_dbgfs_update_pm(mvm, vif, param, val);
396 ret = iwl_mvm_power_update_mode(mvm, vif);
397 mutex_unlock(&mvm->mutex);
398
399 return ret ?: count;
400}
401
402static ssize_t iwl_dbgfs_pm_params_read(struct file *file,
403 char __user *user_buf,
404 size_t count, loff_t *ppos)
405{
406 struct ieee80211_vif *vif = file->private_data;
407 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
408 struct iwl_mvm *mvm = mvmvif->dbgfs_data;
409 struct iwl_powertable_cmd cmd = {};
410 char buf[256];
411 int bufsz = sizeof(buf);
412 int pos = 0;
413
414 iwl_mvm_power_build_cmd(mvm, vif, &cmd);
415
416 pos += scnprintf(buf+pos, bufsz-pos, "disable_power_off = %d\n",
417 (cmd.flags &
418 cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK)) ?
419 0 : 1);
420 pos += scnprintf(buf+pos, bufsz-pos, "skip_dtim_periods = %d\n",
421 le32_to_cpu(cmd.skip_dtim_periods));
422 pos += scnprintf(buf+pos, bufsz-pos, "power_scheme = %d\n",
423 iwlmvm_mod_params.power_scheme);
424 pos += scnprintf(buf+pos, bufsz-pos, "flags = %d\n",
425 le16_to_cpu(cmd.flags));
426 pos += scnprintf(buf+pos, bufsz-pos, "keep_alive = %d\n",
427 cmd.keep_alive_seconds);
428
429 if (cmd.flags & cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK)) {
430 pos += scnprintf(buf+pos, bufsz-pos, "skip_over_dtim = %d\n",
431 (cmd.flags &
432 cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK)) ?
433 1 : 0);
434 pos += scnprintf(buf+pos, bufsz-pos, "rx_data_timeout = %d\n",
435 le32_to_cpu(cmd.rx_data_timeout));
436 pos += scnprintf(buf+pos, bufsz-pos, "tx_data_timeout = %d\n",
437 le32_to_cpu(cmd.tx_data_timeout));
438 }
439
440 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
441}
442
303static ssize_t iwl_dbgfs_mac_params_read(struct file *file, 443static ssize_t iwl_dbgfs_mac_params_read(struct file *file,
304 char __user *user_buf, 444 char __user *user_buf,
305 size_t count, loff_t *ppos) 445 size_t count, loff_t *ppos)
@@ -481,6 +621,255 @@ static ssize_t iwl_dbgfs_fw_restart_write(struct file *file,
481 return count; 621 return count;
482} 622}
483 623
624static void iwl_dbgfs_update_bf(struct ieee80211_vif *vif,
625 enum iwl_dbgfs_bf_mask param, int value)
626{
627 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
628 struct iwl_dbgfs_bf *dbgfs_bf = &mvmvif->dbgfs_bf;
629
630 dbgfs_bf->mask |= param;
631
632 switch (param) {
633 case MVM_DEBUGFS_BF_ENERGY_DELTA:
634 dbgfs_bf->bf_energy_delta = value;
635 break;
636 case MVM_DEBUGFS_BF_ROAMING_ENERGY_DELTA:
637 dbgfs_bf->bf_roaming_energy_delta = value;
638 break;
639 case MVM_DEBUGFS_BF_ROAMING_STATE:
640 dbgfs_bf->bf_roaming_state = value;
641 break;
642 case MVM_DEBUGFS_BF_TEMPERATURE_DELTA:
643 dbgfs_bf->bf_temperature_delta = value;
644 break;
645 case MVM_DEBUGFS_BF_ENABLE_BEACON_FILTER:
646 dbgfs_bf->bf_enable_beacon_filter = value;
647 break;
648 case MVM_DEBUGFS_BF_DEBUG_FLAG:
649 dbgfs_bf->bf_debug_flag = value;
650 break;
651 case MVM_DEBUGFS_BF_ESCAPE_TIMER:
652 dbgfs_bf->bf_escape_timer = value;
653 break;
654 case MVM_DEBUGFS_BA_ENABLE_BEACON_ABORT:
655 dbgfs_bf->ba_enable_beacon_abort = value;
656 break;
657 case MVM_DEBUGFS_BA_ESCAPE_TIMER:
658 dbgfs_bf->ba_escape_timer = value;
659 break;
660 }
661}
662
663static ssize_t iwl_dbgfs_bf_params_write(struct file *file,
664 const char __user *user_buf,
665 size_t count, loff_t *ppos)
666{
667 struct ieee80211_vif *vif = file->private_data;
668 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
669 struct iwl_mvm *mvm = mvmvif->dbgfs_data;
670 enum iwl_dbgfs_bf_mask param;
671 char buf[256];
672 int buf_size;
673 int value;
674 int ret = 0;
675
676 memset(buf, 0, sizeof(buf));
677 buf_size = min(count, sizeof(buf) - 1);
678 if (copy_from_user(buf, user_buf, buf_size))
679 return -EFAULT;
680
681 if (!strncmp("bf_energy_delta=", buf, 16)) {
682 if (sscanf(buf+16, "%d", &value) != 1)
683 return -EINVAL;
684 if (value < IWL_BF_ENERGY_DELTA_MIN ||
685 value > IWL_BF_ENERGY_DELTA_MAX)
686 return -EINVAL;
687 param = MVM_DEBUGFS_BF_ENERGY_DELTA;
688 } else if (!strncmp("bf_roaming_energy_delta=", buf, 24)) {
689 if (sscanf(buf+24, "%d", &value) != 1)
690 return -EINVAL;
691 if (value < IWL_BF_ROAMING_ENERGY_DELTA_MIN ||
692 value > IWL_BF_ROAMING_ENERGY_DELTA_MAX)
693 return -EINVAL;
694 param = MVM_DEBUGFS_BF_ROAMING_ENERGY_DELTA;
695 } else if (!strncmp("bf_roaming_state=", buf, 17)) {
696 if (sscanf(buf+17, "%d", &value) != 1)
697 return -EINVAL;
698 if (value < IWL_BF_ROAMING_STATE_MIN ||
699 value > IWL_BF_ROAMING_STATE_MAX)
700 return -EINVAL;
701 param = MVM_DEBUGFS_BF_ROAMING_STATE;
702 } else if (!strncmp("bf_temperature_delta=", buf, 21)) {
703 if (sscanf(buf+21, "%d", &value) != 1)
704 return -EINVAL;
705 if (value < IWL_BF_TEMPERATURE_DELTA_MIN ||
706 value > IWL_BF_TEMPERATURE_DELTA_MAX)
707 return -EINVAL;
708 param = MVM_DEBUGFS_BF_TEMPERATURE_DELTA;
709 } else if (!strncmp("bf_enable_beacon_filter=", buf, 24)) {
710 if (sscanf(buf+24, "%d", &value) != 1)
711 return -EINVAL;
712 if (value < 0 || value > 1)
713 return -EINVAL;
714 param = MVM_DEBUGFS_BF_ENABLE_BEACON_FILTER;
715 } else if (!strncmp("bf_debug_flag=", buf, 14)) {
716 if (sscanf(buf+14, "%d", &value) != 1)
717 return -EINVAL;
718 if (value < 0 || value > 1)
719 return -EINVAL;
720 param = MVM_DEBUGFS_BF_DEBUG_FLAG;
721 } else if (!strncmp("bf_escape_timer=", buf, 16)) {
722 if (sscanf(buf+16, "%d", &value) != 1)
723 return -EINVAL;
724 if (value < IWL_BF_ESCAPE_TIMER_MIN ||
725 value > IWL_BF_ESCAPE_TIMER_MAX)
726 return -EINVAL;
727 param = MVM_DEBUGFS_BF_ESCAPE_TIMER;
728 } else if (!strncmp("ba_escape_timer=", buf, 16)) {
729 if (sscanf(buf+16, "%d", &value) != 1)
730 return -EINVAL;
731 if (value < IWL_BA_ESCAPE_TIMER_MIN ||
732 value > IWL_BA_ESCAPE_TIMER_MAX)
733 return -EINVAL;
734 param = MVM_DEBUGFS_BA_ESCAPE_TIMER;
735 } else if (!strncmp("ba_enable_beacon_abort=", buf, 23)) {
736 if (sscanf(buf+23, "%d", &value) != 1)
737 return -EINVAL;
738 if (value < 0 || value > 1)
739 return -EINVAL;
740 param = MVM_DEBUGFS_BA_ENABLE_BEACON_ABORT;
741 } else {
742 return -EINVAL;
743 }
744
745 mutex_lock(&mvm->mutex);
746 iwl_dbgfs_update_bf(vif, param, value);
747 if (param == MVM_DEBUGFS_BF_ENABLE_BEACON_FILTER && !value) {
748 ret = iwl_mvm_disable_beacon_filter(mvm, vif);
749 } else {
750 if (mvmvif->bf_enabled)
751 ret = iwl_mvm_enable_beacon_filter(mvm, vif);
752 else
753 ret = iwl_mvm_disable_beacon_filter(mvm, vif);
754 }
755 mutex_unlock(&mvm->mutex);
756
757 return ret ?: count;
758}
759
760static ssize_t iwl_dbgfs_bf_params_read(struct file *file,
761 char __user *user_buf,
762 size_t count, loff_t *ppos)
763{
764 struct ieee80211_vif *vif = file->private_data;
765 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
766 char buf[256];
767 int pos = 0;
768 const size_t bufsz = sizeof(buf);
769 struct iwl_beacon_filter_cmd cmd = {
770 .bf_energy_delta = IWL_BF_ENERGY_DELTA_DEFAULT,
771 .bf_roaming_energy_delta = IWL_BF_ROAMING_ENERGY_DELTA_DEFAULT,
772 .bf_roaming_state = IWL_BF_ROAMING_STATE_DEFAULT,
773 .bf_temperature_delta = IWL_BF_TEMPERATURE_DELTA_DEFAULT,
774 .bf_enable_beacon_filter = IWL_BF_ENABLE_BEACON_FILTER_DEFAULT,
775 .bf_debug_flag = IWL_BF_DEBUG_FLAG_DEFAULT,
776 .bf_escape_timer = cpu_to_le32(IWL_BF_ESCAPE_TIMER_DEFAULT),
777 .ba_escape_timer = cpu_to_le32(IWL_BA_ESCAPE_TIMER_DEFAULT),
778 .ba_enable_beacon_abort = IWL_BA_ENABLE_BEACON_ABORT_DEFAULT,
779 };
780
781 iwl_mvm_beacon_filter_debugfs_parameters(vif, &cmd);
782 if (mvmvif->bf_enabled)
783 cmd.bf_enable_beacon_filter = 1;
784 else
785 cmd.bf_enable_beacon_filter = 0;
786
787 pos += scnprintf(buf+pos, bufsz-pos, "bf_energy_delta = %d\n",
788 cmd.bf_energy_delta);
789 pos += scnprintf(buf+pos, bufsz-pos, "bf_roaming_energy_delta = %d\n",
790 cmd.bf_roaming_energy_delta);
791 pos += scnprintf(buf+pos, bufsz-pos, "bf_roaming_state = %d\n",
792 cmd.bf_roaming_state);
793 pos += scnprintf(buf+pos, bufsz-pos, "bf_temperature_delta = %d\n",
794 cmd.bf_temperature_delta);
795 pos += scnprintf(buf+pos, bufsz-pos, "bf_enable_beacon_filter = %d\n",
796 cmd.bf_enable_beacon_filter);
797 pos += scnprintf(buf+pos, bufsz-pos, "bf_debug_flag = %d\n",
798 cmd.bf_debug_flag);
799 pos += scnprintf(buf+pos, bufsz-pos, "bf_escape_timer = %d\n",
800 cmd.bf_escape_timer);
801 pos += scnprintf(buf+pos, bufsz-pos, "ba_escape_timer = %d\n",
802 cmd.ba_escape_timer);
803 pos += scnprintf(buf+pos, bufsz-pos, "ba_enable_beacon_abort = %d\n",
804 cmd.ba_enable_beacon_abort);
805
806 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
807}
808
809#ifdef CONFIG_PM_SLEEP
810static ssize_t iwl_dbgfs_d3_sram_write(struct file *file,
811 const char __user *user_buf,
812 size_t count, loff_t *ppos)
813{
814 struct iwl_mvm *mvm = file->private_data;
815 char buf[8] = {};
816 int store;
817
818 if (copy_from_user(buf, user_buf, sizeof(buf)))
819 return -EFAULT;
820
821 if (sscanf(buf, "%d", &store) != 1)
822 return -EINVAL;
823
824 mvm->store_d3_resume_sram = store;
825
826 return count;
827}
828
829static ssize_t iwl_dbgfs_d3_sram_read(struct file *file, char __user *user_buf,
830 size_t count, loff_t *ppos)
831{
832 struct iwl_mvm *mvm = file->private_data;
833 const struct fw_img *img;
834 int ofs, len, pos = 0;
835 size_t bufsz, ret;
836 char *buf;
837 u8 *ptr = mvm->d3_resume_sram;
838
839 img = &mvm->fw->img[IWL_UCODE_WOWLAN];
840 len = img->sec[IWL_UCODE_SECTION_DATA].len;
841
842 bufsz = len * 4 + 256;
843 buf = kzalloc(bufsz, GFP_KERNEL);
844 if (!buf)
845 return -ENOMEM;
846
847 pos += scnprintf(buf, bufsz, "D3 SRAM capture: %sabled\n",
848 mvm->store_d3_resume_sram ? "en" : "dis");
849
850 if (ptr) {
851 for (ofs = 0; ofs < len; ofs += 16) {
852 pos += scnprintf(buf + pos, bufsz - pos,
853 "0x%.4x ", ofs);
854 hex_dump_to_buffer(ptr + ofs, 16, 16, 1, buf + pos,
855 bufsz - pos, false);
856 pos += strlen(buf + pos);
857 if (bufsz - pos > 0)
858 buf[pos++] = '\n';
859 }
860 } else {
861 pos += scnprintf(buf + pos, bufsz - pos,
862 "(no data captured)\n");
863 }
864
865 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
866
867 kfree(buf);
868
869 return ret;
870}
871#endif
872
484#define MVM_DEBUGFS_READ_FILE_OPS(name) \ 873#define MVM_DEBUGFS_READ_FILE_OPS(name) \
485static const struct file_operations iwl_dbgfs_##name##_ops = { \ 874static const struct file_operations iwl_dbgfs_##name##_ops = { \
486 .read = iwl_dbgfs_##name##_read, \ 875 .read = iwl_dbgfs_##name##_read, \
@@ -524,9 +913,14 @@ MVM_DEBUGFS_READ_FILE_OPS(bt_notif);
524MVM_DEBUGFS_WRITE_FILE_OPS(power_down_allow); 913MVM_DEBUGFS_WRITE_FILE_OPS(power_down_allow);
525MVM_DEBUGFS_WRITE_FILE_OPS(power_down_d3_allow); 914MVM_DEBUGFS_WRITE_FILE_OPS(power_down_d3_allow);
526MVM_DEBUGFS_WRITE_FILE_OPS(fw_restart); 915MVM_DEBUGFS_WRITE_FILE_OPS(fw_restart);
916#ifdef CONFIG_PM_SLEEP
917MVM_DEBUGFS_READ_WRITE_FILE_OPS(d3_sram);
918#endif
527 919
528/* Interface specific debugfs entries */ 920/* Interface specific debugfs entries */
529MVM_DEBUGFS_READ_FILE_OPS(mac_params); 921MVM_DEBUGFS_READ_FILE_OPS(mac_params);
922MVM_DEBUGFS_READ_WRITE_FILE_OPS(pm_params);
923MVM_DEBUGFS_READ_WRITE_FILE_OPS(bf_params);
530 924
531int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir) 925int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
532{ 926{
@@ -542,6 +936,10 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
542 MVM_DEBUGFS_ADD_FILE(power_down_allow, mvm->debugfs_dir, S_IWUSR); 936 MVM_DEBUGFS_ADD_FILE(power_down_allow, mvm->debugfs_dir, S_IWUSR);
543 MVM_DEBUGFS_ADD_FILE(power_down_d3_allow, mvm->debugfs_dir, S_IWUSR); 937 MVM_DEBUGFS_ADD_FILE(power_down_d3_allow, mvm->debugfs_dir, S_IWUSR);
544 MVM_DEBUGFS_ADD_FILE(fw_restart, mvm->debugfs_dir, S_IWUSR); 938 MVM_DEBUGFS_ADD_FILE(fw_restart, mvm->debugfs_dir, S_IWUSR);
939#ifdef CONFIG_PM_SLEEP
940 MVM_DEBUGFS_ADD_FILE(d3_sram, mvm->debugfs_dir, S_IRUSR | S_IWUSR);
941 MVM_DEBUGFS_ADD_FILE(d3_test, mvm->debugfs_dir, S_IRUSR);
942#endif
545 943
546 /* 944 /*
547 * Create a symlink with mac80211. It will be removed when mac80211 945 * Create a symlink with mac80211. It will be removed when mac80211
@@ -577,9 +975,19 @@ void iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
577 return; 975 return;
578 } 976 }
579 977
978 if (iwlmvm_mod_params.power_scheme != IWL_POWER_SCHEME_CAM &&
979 vif->type == NL80211_IFTYPE_STATION && !vif->p2p)
980 MVM_DEBUGFS_ADD_FILE_VIF(pm_params, mvmvif->dbgfs_dir, S_IWUSR |
981 S_IRUSR);
982
580 MVM_DEBUGFS_ADD_FILE_VIF(mac_params, mvmvif->dbgfs_dir, 983 MVM_DEBUGFS_ADD_FILE_VIF(mac_params, mvmvif->dbgfs_dir,
581 S_IRUSR); 984 S_IRUSR);
582 985
986 if (vif->type == NL80211_IFTYPE_STATION && !vif->p2p &&
987 mvmvif == mvm->bf_allowed_vif)
988 MVM_DEBUGFS_ADD_FILE_VIF(bf_params, mvmvif->dbgfs_dir,
989 S_IRUSR | S_IWUSR);
990
583 /* 991 /*
584 * Create symlink for convenience pointing to interface specific 992 * Create symlink for convenience pointing to interface specific
585 * debugfs entries for the driver. For example, under 993 * debugfs entries for the driver. For example, under
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h
index 51e015d1dfb2..6f8b2c16ae17 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h
@@ -75,13 +75,15 @@ enum iwl_d3_wakeup_flags {
75 * struct iwl_d3_manager_config - D3 manager configuration command 75 * struct iwl_d3_manager_config - D3 manager configuration command
76 * @min_sleep_time: minimum sleep time (in usec) 76 * @min_sleep_time: minimum sleep time (in usec)
77 * @wakeup_flags: wakeup flags, see &enum iwl_d3_wakeup_flags 77 * @wakeup_flags: wakeup flags, see &enum iwl_d3_wakeup_flags
78 * @wakeup_host_timer: force wakeup after this many seconds
78 * 79 *
79 * The structure is used for the D3_CONFIG_CMD command. 80 * The structure is used for the D3_CONFIG_CMD command.
80 */ 81 */
81struct iwl_d3_manager_config { 82struct iwl_d3_manager_config {
82 __le32 min_sleep_time; 83 __le32 min_sleep_time;
83 __le32 wakeup_flags; 84 __le32 wakeup_flags;
84} __packed; /* D3_MANAGER_CONFIG_CMD_S_VER_3 */ 85 __le32 wakeup_host_timer;
86} __packed; /* D3_MANAGER_CONFIG_CMD_S_VER_4 */
85 87
86 88
87/* TODO: OFFLOADS_QUERY_API_S_VER_1 */ 89/* TODO: OFFLOADS_QUERY_API_S_VER_1 */
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h
index d68640ea41d4..98b1feb43d38 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h
@@ -71,7 +71,13 @@
71#define MAC_INDEX_MIN_DRIVER 0 71#define MAC_INDEX_MIN_DRIVER 0
72#define NUM_MAC_INDEX_DRIVER MAC_INDEX_AUX 72#define NUM_MAC_INDEX_DRIVER MAC_INDEX_AUX
73 73
74#define AC_NUM 4 /* Number of access categories */ 74enum iwl_ac {
75 AC_BK,
76 AC_BE,
77 AC_VI,
78 AC_VO,
79 AC_NUM,
80};
75 81
76/** 82/**
77 * enum iwl_mac_protection_flags - MAC context flags 83 * enum iwl_mac_protection_flags - MAC context flags
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
index 81fe45f46be7..d8e19290b0f3 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
@@ -101,20 +101,107 @@ enum iwl_power_flags {
101 * @tx_data_timeout: Minimum time (usec) from last Tx packet for AM to 101 * @tx_data_timeout: Minimum time (usec) from last Tx packet for AM to
102 * PSM transition - legacy PM 102 * PSM transition - legacy PM
103 * @sleep_interval: not in use 103 * @sleep_interval: not in use
104 * @keep_alive_beacons: not in use 104 * @skip_dtim_periods: Number of DTIM periods to skip if Skip over DTIM flag
105 * is set. For example, if it is required to skip over
106 * one DTIM, this value need to be set to 2 (DTIM periods).
105 * @lprx_rssi_threshold: Signal strength up to which LP RX can be enabled. 107 * @lprx_rssi_threshold: Signal strength up to which LP RX can be enabled.
106 * Default: 80dbm 108 * Default: 80dbm
107 */ 109 */
108struct iwl_powertable_cmd { 110struct iwl_powertable_cmd {
109 /* PM_POWER_TABLE_CMD_API_S_VER_5 */ 111 /* PM_POWER_TABLE_CMD_API_S_VER_6 */
110 __le16 flags; 112 __le16 flags;
111 u8 keep_alive_seconds; 113 u8 keep_alive_seconds;
112 u8 debug_flags; 114 u8 debug_flags;
113 __le32 rx_data_timeout; 115 __le32 rx_data_timeout;
114 __le32 tx_data_timeout; 116 __le32 tx_data_timeout;
115 __le32 sleep_interval[IWL_POWER_VEC_SIZE]; 117 __le32 sleep_interval[IWL_POWER_VEC_SIZE];
116 __le32 keep_alive_beacons; 118 __le32 skip_dtim_periods;
117 __le32 lprx_rssi_threshold; 119 __le32 lprx_rssi_threshold;
118} __packed; 120} __packed;
119 121
122/**
123 * struct iwl_beacon_filter_cmd
124 * REPLY_BEACON_FILTERING_CMD = 0xd2 (command)
125 * @id_and_color: MAC contex identifier
126 * @bf_energy_delta: Used for RSSI filtering, if in 'normal' state. Send beacon
127 * to driver if delta in Energy values calculated for this and last
128 * passed beacon is greater than this threshold. Zero value means that
129 * the Energy change is ignored for beacon filtering, and beacon will
130 * not be forced to be sent to driver regardless of this delta. Typical
131 * energy delta 5dB.
132 * @bf_roaming_energy_delta: Used for RSSI filtering, if in 'roaming' state.
133 * Send beacon to driver if delta in Energy values calculated for this
134 * and last passed beacon is greater than this threshold. Zero value
135 * means that the Energy change is ignored for beacon filtering while in
136 * Roaming state, typical energy delta 1dB.
137 * @bf_roaming_state: Used for RSSI filtering. If absolute Energy values
138 * calculated for current beacon is less than the threshold, use
139 * Roaming Energy Delta Threshold, otherwise use normal Energy Delta
140 * Threshold. Typical energy threshold is -72dBm.
141 * @bf_temperature_delta: Send Beacon to driver if delta in temperature values
142 * calculated for this and the last passed beacon is greater than this
143 * threshold. Zero value means that the temperature changeis ignored for
144 * beacon filtering; beacons will not be forced to be sent to driver
145 * regardless of whether its temerature has been changed.
146 * @bf_enable_beacon_filter: 1, beacon filtering is enabled; 0, disabled.
147 * @bf_filter_escape_timer: Send beacons to to driver if no beacons were passed
148 * for a specific period of time. Units: Beacons.
149 * @ba_escape_timer: Fully receive and parse beacon if no beacons were passed
150 * for a longer period of time then this escape-timeout. Units: Beacons.
151 * @ba_enable_beacon_abort: 1, beacon abort is enabled; 0, disabled.
152 */
153struct iwl_beacon_filter_cmd {
154 u8 bf_energy_delta;
155 u8 bf_roaming_energy_delta;
156 u8 bf_roaming_state;
157 u8 bf_temperature_delta;
158 u8 bf_enable_beacon_filter;
159 u8 bf_debug_flag;
160 __le16 reserved1;
161 __le32 bf_escape_timer;
162 __le32 ba_escape_timer;
163 u8 ba_enable_beacon_abort;
164 u8 reserved2[3];
165} __packed;
166
167/* Beacon filtering and beacon abort */
168#define IWL_BF_ENERGY_DELTA_DEFAULT 5
169#define IWL_BF_ENERGY_DELTA_MAX 255
170#define IWL_BF_ENERGY_DELTA_MIN 0
171
172#define IWL_BF_ROAMING_ENERGY_DELTA_DEFAULT 1
173#define IWL_BF_ROAMING_ENERGY_DELTA_MAX 255
174#define IWL_BF_ROAMING_ENERGY_DELTA_MIN 0
175
176#define IWL_BF_ROAMING_STATE_DEFAULT 72
177#define IWL_BF_ROAMING_STATE_MAX 255
178#define IWL_BF_ROAMING_STATE_MIN 0
179
180#define IWL_BF_TEMPERATURE_DELTA_DEFAULT 5
181#define IWL_BF_TEMPERATURE_DELTA_MAX 255
182#define IWL_BF_TEMPERATURE_DELTA_MIN 0
183
184#define IWL_BF_ENABLE_BEACON_FILTER_DEFAULT 1
185
186#define IWL_BF_DEBUG_FLAG_DEFAULT 0
187
188#define IWL_BF_ESCAPE_TIMER_DEFAULT 50
189#define IWL_BF_ESCAPE_TIMER_MAX 1024
190#define IWL_BF_ESCAPE_TIMER_MIN 0
191
192#define IWL_BA_ESCAPE_TIMER_DEFAULT 3
193#define IWL_BA_ESCAPE_TIMER_MAX 1024
194#define IWL_BA_ESCAPE_TIMER_MIN 0
195
196#define IWL_BA_ENABLE_BEACON_ABORT_DEFAULT 1
197
198#define IWL_BF_CMD_CONFIG_DEFAULTS \
199 .bf_energy_delta = IWL_BF_ENERGY_DELTA_DEFAULT, \
200 .bf_roaming_energy_delta = IWL_BF_ROAMING_ENERGY_DELTA_DEFAULT, \
201 .bf_roaming_state = IWL_BF_ROAMING_STATE_DEFAULT, \
202 .bf_temperature_delta = IWL_BF_TEMPERATURE_DELTA_DEFAULT, \
203 .bf_debug_flag = IWL_BF_DEBUG_FLAG_DEFAULT, \
204 .bf_escape_timer = cpu_to_le32(IWL_BF_ESCAPE_TIMER_DEFAULT), \
205 .ba_escape_timer = cpu_to_le32(IWL_BA_ESCAPE_TIMER_DEFAULT)
206
120#endif 207#endif
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h
index 007a93b25bd7..6994232f5726 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h
@@ -134,6 +134,7 @@ enum iwl_tx_flags {
134#define TX_CMD_SEC_WEP 0x01 134#define TX_CMD_SEC_WEP 0x01
135#define TX_CMD_SEC_CCM 0x02 135#define TX_CMD_SEC_CCM 0x02
136#define TX_CMD_SEC_TKIP 0x03 136#define TX_CMD_SEC_TKIP 0x03
137#define TX_CMD_SEC_MSK 0x07
137#define TX_CMD_SEC_WEP_KEY_IDX_POS 6 138#define TX_CMD_SEC_WEP_KEY_IDX_POS 6
138#define TX_CMD_SEC_WEP_KEY_IDX_MSK 0xc0 139#define TX_CMD_SEC_WEP_KEY_IDX_MSK 0xc0
139#define TX_CMD_SEC_KEY128 0x08 140#define TX_CMD_SEC_KEY128 0x08
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
index c6384555aab4..cbfb3beae783 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
@@ -139,6 +139,9 @@ enum {
139 /* Power */ 139 /* Power */
140 POWER_TABLE_CMD = 0x77, 140 POWER_TABLE_CMD = 0x77,
141 141
142 /* Thermal Throttling*/
143 REPLY_THERMAL_MNG_BACKOFF = 0x7e,
144
142 /* Scanning */ 145 /* Scanning */
143 SCAN_REQUEST_CMD = 0x80, 146 SCAN_REQUEST_CMD = 0x80,
144 SCAN_ABORT_CMD = 0x81, 147 SCAN_ABORT_CMD = 0x81,
@@ -161,6 +164,8 @@ enum {
161 CARD_STATE_CMD = 0xa0, 164 CARD_STATE_CMD = 0xa0,
162 CARD_STATE_NOTIFICATION = 0xa1, 165 CARD_STATE_NOTIFICATION = 0xa1,
163 166
167 MISSED_BEACONS_NOTIFICATION = 0xa2,
168
164 REPLY_RX_PHY_CMD = 0xc0, 169 REPLY_RX_PHY_CMD = 0xc0,
165 REPLY_RX_MPDU_CMD = 0xc1, 170 REPLY_RX_MPDU_CMD = 0xc1,
166 BA_NOTIF = 0xc5, 171 BA_NOTIF = 0xc5,
@@ -170,6 +175,8 @@ enum {
170 BT_COEX_PROT_ENV = 0xcd, 175 BT_COEX_PROT_ENV = 0xcd,
171 BT_PROFILE_NOTIFICATION = 0xce, 176 BT_PROFILE_NOTIFICATION = 0xce,
172 177
178 REPLY_BEACON_FILTERING_CMD = 0xd2,
179
173 REPLY_DEBUG_CMD = 0xf0, 180 REPLY_DEBUG_CMD = 0xf0,
174 DEBUG_LOG_MSG = 0xf7, 181 DEBUG_LOG_MSG = 0xf7,
175 182
@@ -938,6 +945,24 @@ struct iwl_card_state_notif {
938} __packed; /* CARD_STATE_NTFY_API_S_VER_1 */ 945} __packed; /* CARD_STATE_NTFY_API_S_VER_1 */
939 946
940/** 947/**
948 * struct iwl_missed_beacons_notif - information on missed beacons
949 * ( MISSED_BEACONS_NOTIFICATION = 0xa2 )
950 * @mac_id: interface ID
951 * @consec_missed_beacons_since_last_rx: number of consecutive missed
952 * beacons since last RX.
953 * @consec_missed_beacons: number of consecutive missed beacons
954 * @num_expected_beacons:
955 * @num_recvd_beacons:
956 */
957struct iwl_missed_beacons_notif {
958 __le32 mac_id;
959 __le32 consec_missed_beacons_since_last_rx;
960 __le32 consec_missed_beacons;
961 __le32 num_expected_beacons;
962 __le32 num_recvd_beacons;
963} __packed; /* MISSED_BEACON_NTFY_API_S_VER_3 */
964
965/**
941 * struct iwl_set_calib_default_cmd - set default value for calibration. 966 * struct iwl_set_calib_default_cmd - set default value for calibration.
942 * ( SET_CALIB_DEFAULT_CMD = 0x8e ) 967 * ( SET_CALIB_DEFAULT_CMD = 0x8e )
943 * @calib_index: the calibration to set value for 968 * @calib_index: the calibration to set value for
@@ -975,4 +1000,212 @@ struct iwl_mcast_filter_cmd {
975 u8 addr_list[0]; 1000 u8 addr_list[0];
976} __packed; /* MCAST_FILTERING_CMD_API_S_VER_1 */ 1001} __packed; /* MCAST_FILTERING_CMD_API_S_VER_1 */
977 1002
1003struct mvm_statistics_dbg {
1004 __le32 burst_check;
1005 __le32 burst_count;
1006 __le32 wait_for_silence_timeout_cnt;
1007 __le32 reserved[3];
1008} __packed; /* STATISTICS_DEBUG_API_S_VER_2 */
1009
1010struct mvm_statistics_div {
1011 __le32 tx_on_a;
1012 __le32 tx_on_b;
1013 __le32 exec_time;
1014 __le32 probe_time;
1015 __le32 rssi_ant;
1016 __le32 reserved2;
1017} __packed; /* STATISTICS_SLOW_DIV_API_S_VER_2 */
1018
1019struct mvm_statistics_general_common {
1020 __le32 temperature; /* radio temperature */
1021 __le32 temperature_m; /* radio voltage */
1022 struct mvm_statistics_dbg dbg;
1023 __le32 sleep_time;
1024 __le32 slots_out;
1025 __le32 slots_idle;
1026 __le32 ttl_timestamp;
1027 struct mvm_statistics_div div;
1028 __le32 rx_enable_counter;
1029 /*
1030 * num_of_sos_states:
1031 * count the number of times we have to re-tune
1032 * in order to get out of bad PHY status
1033 */
1034 __le32 num_of_sos_states;
1035} __packed; /* STATISTICS_GENERAL_API_S_VER_5 */
1036
1037struct mvm_statistics_rx_non_phy {
1038 __le32 bogus_cts; /* CTS received when not expecting CTS */
1039 __le32 bogus_ack; /* ACK received when not expecting ACK */
1040 __le32 non_bssid_frames; /* number of frames with BSSID that
1041 * doesn't belong to the STA BSSID */
1042 __le32 filtered_frames; /* count frames that were dumped in the
1043 * filtering process */
1044 __le32 non_channel_beacons; /* beacons with our bss id but not on
1045 * our serving channel */
1046 __le32 channel_beacons; /* beacons with our bss id and in our
1047 * serving channel */
1048 __le32 num_missed_bcon; /* number of missed beacons */
1049 __le32 adc_rx_saturation_time; /* count in 0.8us units the time the
1050 * ADC was in saturation */
1051 __le32 ina_detection_search_time;/* total time (in 0.8us) searched
1052 * for INA */
1053 __le32 beacon_silence_rssi_a; /* RSSI silence after beacon frame */
1054 __le32 beacon_silence_rssi_b; /* RSSI silence after beacon frame */
1055 __le32 beacon_silence_rssi_c; /* RSSI silence after beacon frame */
1056 __le32 interference_data_flag; /* flag for interference data
1057 * availability. 1 when data is
1058 * available. */
1059 __le32 channel_load; /* counts RX Enable time in uSec */
1060 __le32 dsp_false_alarms; /* DSP false alarm (both OFDM
1061 * and CCK) counter */
1062 __le32 beacon_rssi_a;
1063 __le32 beacon_rssi_b;
1064 __le32 beacon_rssi_c;
1065 __le32 beacon_energy_a;
1066 __le32 beacon_energy_b;
1067 __le32 beacon_energy_c;
1068 __le32 num_bt_kills;
1069 __le32 mac_id;
1070 __le32 directed_data_mpdu;
1071} __packed; /* STATISTICS_RX_NON_PHY_API_S_VER_3 */
1072
1073struct mvm_statistics_rx_phy {
1074 __le32 ina_cnt;
1075 __le32 fina_cnt;
1076 __le32 plcp_err;
1077 __le32 crc32_err;
1078 __le32 overrun_err;
1079 __le32 early_overrun_err;
1080 __le32 crc32_good;
1081 __le32 false_alarm_cnt;
1082 __le32 fina_sync_err_cnt;
1083 __le32 sfd_timeout;
1084 __le32 fina_timeout;
1085 __le32 unresponded_rts;
1086 __le32 rxe_frame_limit_overrun;
1087 __le32 sent_ack_cnt;
1088 __le32 sent_cts_cnt;
1089 __le32 sent_ba_rsp_cnt;
1090 __le32 dsp_self_kill;
1091 __le32 mh_format_err;
1092 __le32 re_acq_main_rssi_sum;
1093 __le32 reserved;
1094} __packed; /* STATISTICS_RX_PHY_API_S_VER_2 */
1095
1096struct mvm_statistics_rx_ht_phy {
1097 __le32 plcp_err;
1098 __le32 overrun_err;
1099 __le32 early_overrun_err;
1100 __le32 crc32_good;
1101 __le32 crc32_err;
1102 __le32 mh_format_err;
1103 __le32 agg_crc32_good;
1104 __le32 agg_mpdu_cnt;
1105 __le32 agg_cnt;
1106 __le32 unsupport_mcs;
1107} __packed; /* STATISTICS_HT_RX_PHY_API_S_VER_1 */
1108
1109#define MAX_CHAINS 3
1110
1111struct mvm_statistics_tx_non_phy_agg {
1112 __le32 ba_timeout;
1113 __le32 ba_reschedule_frames;
1114 __le32 scd_query_agg_frame_cnt;
1115 __le32 scd_query_no_agg;
1116 __le32 scd_query_agg;
1117 __le32 scd_query_mismatch;
1118 __le32 frame_not_ready;
1119 __le32 underrun;
1120 __le32 bt_prio_kill;
1121 __le32 rx_ba_rsp_cnt;
1122 __s8 txpower[MAX_CHAINS];
1123 __s8 reserved;
1124 __le32 reserved2;
1125} __packed; /* STATISTICS_TX_NON_PHY_AGG_API_S_VER_1 */
1126
1127struct mvm_statistics_tx_channel_width {
1128 __le32 ext_cca_narrow_ch20[1];
1129 __le32 ext_cca_narrow_ch40[2];
1130 __le32 ext_cca_narrow_ch80[3];
1131 __le32 ext_cca_narrow_ch160[4];
1132 __le32 last_tx_ch_width_indx;
1133 __le32 rx_detected_per_ch_width[4];
1134 __le32 success_per_ch_width[4];
1135 __le32 fail_per_ch_width[4];
1136}; /* STATISTICS_TX_CHANNEL_WIDTH_API_S_VER_1 */
1137
1138struct mvm_statistics_tx {
1139 __le32 preamble_cnt;
1140 __le32 rx_detected_cnt;
1141 __le32 bt_prio_defer_cnt;
1142 __le32 bt_prio_kill_cnt;
1143 __le32 few_bytes_cnt;
1144 __le32 cts_timeout;
1145 __le32 ack_timeout;
1146 __le32 expected_ack_cnt;
1147 __le32 actual_ack_cnt;
1148 __le32 dump_msdu_cnt;
1149 __le32 burst_abort_next_frame_mismatch_cnt;
1150 __le32 burst_abort_missing_next_frame_cnt;
1151 __le32 cts_timeout_collision;
1152 __le32 ack_or_ba_timeout_collision;
1153 struct mvm_statistics_tx_non_phy_agg agg;
1154 struct mvm_statistics_tx_channel_width channel_width;
1155} __packed; /* STATISTICS_TX_API_S_VER_4 */
1156
1157
1158struct mvm_statistics_bt_activity {
1159 __le32 hi_priority_tx_req_cnt;
1160 __le32 hi_priority_tx_denied_cnt;
1161 __le32 lo_priority_tx_req_cnt;
1162 __le32 lo_priority_tx_denied_cnt;
1163 __le32 hi_priority_rx_req_cnt;
1164 __le32 hi_priority_rx_denied_cnt;
1165 __le32 lo_priority_rx_req_cnt;
1166 __le32 lo_priority_rx_denied_cnt;
1167} __packed; /* STATISTICS_BT_ACTIVITY_API_S_VER_1 */
1168
1169struct mvm_statistics_general {
1170 struct mvm_statistics_general_common common;
1171 __le32 beacon_filtered;
1172 __le32 missed_beacons;
1173 __s8 beacon_filter_everage_energy;
1174 __s8 beacon_filter_reason;
1175 __s8 beacon_filter_current_energy;
1176 __s8 beacon_filter_reserved;
1177 __le32 beacon_filter_delta_time;
1178 struct mvm_statistics_bt_activity bt_activity;
1179} __packed; /* STATISTICS_GENERAL_API_S_VER_5 */
1180
1181struct mvm_statistics_rx {
1182 struct mvm_statistics_rx_phy ofdm;
1183 struct mvm_statistics_rx_phy cck;
1184 struct mvm_statistics_rx_non_phy general;
1185 struct mvm_statistics_rx_ht_phy ofdm_ht;
1186} __packed; /* STATISTICS_RX_API_S_VER_3 */
1187
1188/*
1189 * STATISTICS_NOTIFICATION = 0x9d (notification only, not a command)
1190 *
1191 * By default, uCode issues this notification after receiving a beacon
1192 * while associated. To disable this behavior, set DISABLE_NOTIF flag in the
1193 * REPLY_STATISTICS_CMD 0x9c, above.
1194 *
1195 * Statistics counters continue to increment beacon after beacon, but are
1196 * cleared when changing channels or when driver issues REPLY_STATISTICS_CMD
1197 * 0x9c with CLEAR_STATS bit set (see above).
1198 *
1199 * uCode also issues this notification during scans. uCode clears statistics
1200 * appropriately so that each notification contains statistics for only the
1201 * one channel that has just been scanned.
1202 */
1203
1204struct iwl_notif_statistics { /* STATISTICS_NTFY_API_S_VER_8 */
1205 __le32 flag;
1206 struct mvm_statistics_rx rx;
1207 struct mvm_statistics_tx tx;
1208 struct mvm_statistics_general general;
1209} __packed;
1210
978#endif /* __fw_api_h__ */ 1211#endif /* __fw_api_h__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw.c b/drivers/net/wireless/iwlwifi/mvm/fw.c
index e18c92dd60ec..cd7c0032cc58 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/iwlwifi/mvm/fw.c
@@ -326,6 +326,17 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
326 ret = iwl_nvm_check_version(mvm->nvm_data, mvm->trans); 326 ret = iwl_nvm_check_version(mvm->nvm_data, mvm->trans);
327 WARN_ON(ret); 327 WARN_ON(ret);
328 328
329 /*
330 * abort after reading the nvm in case RF Kill is on, we will complete
331 * the init seq later when RF kill will switch to off
332 */
333 if (iwl_mvm_is_radio_killed(mvm)) {
334 IWL_DEBUG_RF_KILL(mvm,
335 "jump over all phy activities due to RF kill\n");
336 iwl_remove_notification(&mvm->notif_wait, &calib_wait);
337 return 1;
338 }
339
329 /* Send TX valid antennas before triggering calibrations */ 340 /* Send TX valid antennas before triggering calibrations */
330 ret = iwl_send_tx_ant_cfg(mvm, iwl_fw_valid_tx_ant(mvm->fw)); 341 ret = iwl_send_tx_ant_cfg(mvm, iwl_fw_valid_tx_ant(mvm->fw));
331 if (ret) 342 if (ret)
@@ -388,6 +399,8 @@ out:
388int iwl_mvm_up(struct iwl_mvm *mvm) 399int iwl_mvm_up(struct iwl_mvm *mvm)
389{ 400{
390 int ret, i; 401 int ret, i;
402 struct ieee80211_channel *chan;
403 struct cfg80211_chan_def chandef;
391 404
392 lockdep_assert_held(&mvm->mutex); 405 lockdep_assert_held(&mvm->mutex);
393 406
@@ -400,8 +413,16 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
400 ret = iwl_run_init_mvm_ucode(mvm, false); 413 ret = iwl_run_init_mvm_ucode(mvm, false);
401 if (ret && !iwlmvm_mod_params.init_dbg) { 414 if (ret && !iwlmvm_mod_params.init_dbg) {
402 IWL_ERR(mvm, "Failed to run INIT ucode: %d\n", ret); 415 IWL_ERR(mvm, "Failed to run INIT ucode: %d\n", ret);
416 /* this can't happen */
417 if (WARN_ON(ret > 0))
418 ret = -ERFKILL;
403 goto error; 419 goto error;
404 } 420 }
421 /* should stop & start HW since that INIT image just loaded */
422 iwl_trans_stop_hw(mvm->trans, false);
423 ret = iwl_trans_start_hw(mvm->trans);
424 if (ret)
425 return ret;
405 } 426 }
406 427
407 if (iwlmvm_mod_params.init_dbg) 428 if (iwlmvm_mod_params.init_dbg)
@@ -443,8 +464,22 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
443 if (ret) 464 if (ret)
444 goto error; 465 goto error;
445 466
446 IWL_DEBUG_INFO(mvm, "RT uCode started.\n"); 467 /* Add all the PHY contexts */
468 chan = &mvm->hw->wiphy->bands[IEEE80211_BAND_2GHZ]->channels[0];
469 cfg80211_chandef_create(&chandef, chan, NL80211_CHAN_NO_HT);
470 for (i = 0; i < NUM_PHY_CTX; i++) {
471 /*
472 * The channel used here isn't relevant as it's
473 * going to be overwritten in the other flows.
474 * For now use the first channel we have.
475 */
476 ret = iwl_mvm_phy_ctxt_add(mvm, &mvm->phy_ctxts[i],
477 &chandef, 1, 1);
478 if (ret)
479 goto error;
480 }
447 481
482 IWL_DEBUG_INFO(mvm, "RT uCode started.\n");
448 return 0; 483 return 0;
449 error: 484 error:
450 iwl_trans_stop_device(mvm->trans); 485 iwl_trans_stop_device(mvm->trans);
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
index b2cc3d98e0f7..46c7c0507c25 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
@@ -227,7 +227,7 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm,
227 .found_vif = false, 227 .found_vif = false,
228 }; 228 };
229 u32 ac; 229 u32 ac;
230 int ret; 230 int ret, i;
231 231
232 /* 232 /*
233 * Allocate a MAC ID and a TSF for this MAC, along with the queues 233 * Allocate a MAC ID and a TSF for this MAC, along with the queues
@@ -335,6 +335,9 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm,
335 mvmvif->bcast_sta.sta_id = IWL_MVM_STATION_COUNT; 335 mvmvif->bcast_sta.sta_id = IWL_MVM_STATION_COUNT;
336 mvmvif->ap_sta_id = IWL_MVM_STATION_COUNT; 336 mvmvif->ap_sta_id = IWL_MVM_STATION_COUNT;
337 337
338 for (i = 0; i < NUM_IWL_MVM_SMPS_REQ; i++)
339 mvmvif->smps_requests[i] = IEEE80211_SMPS_AUTOMATIC;
340
338 return 0; 341 return 0;
339 342
340exit_fail: 343exit_fail:
@@ -362,7 +365,7 @@ int iwl_mvm_mac_ctxt_init(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
362 break; 365 break;
363 case NL80211_IFTYPE_AP: 366 case NL80211_IFTYPE_AP:
364 iwl_trans_ac_txq_enable(mvm->trans, vif->cab_queue, 367 iwl_trans_ac_txq_enable(mvm->trans, vif->cab_queue,
365 IWL_MVM_TX_FIFO_VO); 368 IWL_MVM_TX_FIFO_MCAST);
366 /* fall through */ 369 /* fall through */
367 default: 370 default:
368 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) 371 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
@@ -550,6 +553,10 @@ static void iwl_mvm_mac_ctxt_cmd_common(struct iwl_mvm *mvm,
550 cmd->ac[i].fifos_mask = BIT(iwl_mvm_ac_to_tx_fifo[i]); 553 cmd->ac[i].fifos_mask = BIT(iwl_mvm_ac_to_tx_fifo[i]);
551 } 554 }
552 555
556 /* in AP mode, the MCAST FIFO takes the EDCA params from VO */
557 if (vif->type == NL80211_IFTYPE_AP)
558 cmd->ac[AC_VO].fifos_mask |= BIT(IWL_MVM_TX_FIFO_MCAST);
559
553 if (vif->bss_conf.qos) 560 if (vif->bss_conf.qos)
554 cmd->qos_flags |= cpu_to_le32(MAC_QOS_FLG_UPDATE_EDCA); 561 cmd->qos_flags |= cpu_to_le32(MAC_QOS_FLG_UPDATE_EDCA);
555 562
@@ -1047,3 +1054,28 @@ int iwl_mvm_rx_beacon_notif(struct iwl_mvm *mvm,
1047 rate); 1054 rate);
1048 return 0; 1055 return 0;
1049} 1056}
1057
1058static void iwl_mvm_beacon_loss_iterator(void *_data, u8 *mac,
1059 struct ieee80211_vif *vif)
1060{
1061 u16 *id = _data;
1062 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1063
1064 if (mvmvif->id == *id)
1065 ieee80211_beacon_loss(vif);
1066}
1067
1068int iwl_mvm_rx_missed_beacons_notif(struct iwl_mvm *mvm,
1069 struct iwl_rx_cmd_buffer *rxb,
1070 struct iwl_device_cmd *cmd)
1071{
1072 struct iwl_rx_packet *pkt = rxb_addr(rxb);
1073 struct iwl_missed_beacons_notif *missed_beacons = (void *)pkt->data;
1074 u16 id = (u16)le32_to_cpu(missed_beacons->mac_id);
1075
1076 ieee80211_iterate_active_interfaces_atomic(mvm->hw,
1077 IEEE80211_IFACE_ITER_NORMAL,
1078 iwl_mvm_beacon_loss_iterator,
1079 &id);
1080 return 0;
1081}
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
index a5eb8c82f16a..2ed296caeb28 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
@@ -127,6 +127,17 @@ static const struct wiphy_wowlan_tcp_support iwl_mvm_wowlan_tcp_support = {
127}; 127};
128#endif 128#endif
129 129
130static void iwl_mvm_reset_phy_ctxts(struct iwl_mvm *mvm)
131{
132 int i;
133
134 memset(mvm->phy_ctxts, 0, sizeof(mvm->phy_ctxts));
135 for (i = 0; i < NUM_PHY_CTX; i++) {
136 mvm->phy_ctxts[i].id = i;
137 mvm->phy_ctxts[i].ref = 0;
138 }
139}
140
130int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) 141int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
131{ 142{
132 struct ieee80211_hw *hw = mvm->hw; 143 struct ieee80211_hw *hw = mvm->hw;
@@ -141,7 +152,8 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
141 IEEE80211_HW_SUPPORTS_PS | 152 IEEE80211_HW_SUPPORTS_PS |
142 IEEE80211_HW_SUPPORTS_DYNAMIC_PS | 153 IEEE80211_HW_SUPPORTS_DYNAMIC_PS |
143 IEEE80211_HW_AMPDU_AGGREGATION | 154 IEEE80211_HW_AMPDU_AGGREGATION |
144 IEEE80211_HW_TIMING_BEACON_ONLY; 155 IEEE80211_HW_TIMING_BEACON_ONLY |
156 IEEE80211_HW_CONNECTION_MONITOR;
145 157
146 hw->queues = IWL_MVM_FIRST_AGG_QUEUE; 158 hw->queues = IWL_MVM_FIRST_AGG_QUEUE;
147 hw->offchannel_tx_hw_queue = IWL_MVM_OFFCHANNEL_QUEUE; 159 hw->offchannel_tx_hw_queue = IWL_MVM_OFFCHANNEL_QUEUE;
@@ -158,7 +170,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
158 170
159 hw->sta_data_size = sizeof(struct iwl_mvm_sta); 171 hw->sta_data_size = sizeof(struct iwl_mvm_sta);
160 hw->vif_data_size = sizeof(struct iwl_mvm_vif); 172 hw->vif_data_size = sizeof(struct iwl_mvm_vif);
161 hw->chanctx_data_size = sizeof(struct iwl_mvm_phy_ctxt); 173 hw->chanctx_data_size = sizeof(u16);
162 174
163 hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | 175 hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
164 BIT(NL80211_IFTYPE_P2P_CLIENT) | 176 BIT(NL80211_IFTYPE_P2P_CLIENT) |
@@ -193,6 +205,8 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
193 hw->wiphy->n_addresses++; 205 hw->wiphy->n_addresses++;
194 } 206 }
195 207
208 iwl_mvm_reset_phy_ctxts(mvm);
209
196 /* we create the 802.11 header and a max-length SSID element */ 210 /* we create the 802.11 header and a max-length SSID element */
197 hw->wiphy->max_scan_ie_len = 211 hw->wiphy->max_scan_ie_len =
198 mvm->fw->ucode_capa.max_probe_length - 24 - 34; 212 mvm->fw->ucode_capa.max_probe_length - 24 - 34;
@@ -252,8 +266,8 @@ static void iwl_mvm_mac_tx(struct ieee80211_hw *hw,
252{ 266{
253 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 267 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
254 268
255 if (test_bit(IWL_MVM_STATUS_HW_RFKILL, &mvm->status)) { 269 if (iwl_mvm_is_radio_killed(mvm)) {
256 IWL_DEBUG_DROP(mvm, "Dropping - RF KILL\n"); 270 IWL_DEBUG_DROP(mvm, "Dropping - RF/CT KILL\n");
257 goto drop; 271 goto drop;
258 } 272 }
259 273
@@ -345,8 +359,7 @@ static void iwl_mvm_cleanup_iterator(void *data, u8 *mac,
345 iwl_mvm_te_clear_data(mvm, &mvmvif->time_event_data); 359 iwl_mvm_te_clear_data(mvm, &mvmvif->time_event_data);
346 spin_unlock_bh(&mvm->time_event_lock); 360 spin_unlock_bh(&mvm->time_event_lock);
347 361
348 if (vif->type != NL80211_IFTYPE_P2P_DEVICE) 362 mvmvif->phy_ctxt = NULL;
349 mvmvif->phy_ctxt = NULL;
350} 363}
351 364
352static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm) 365static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm)
@@ -363,6 +376,9 @@ static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm)
363 mvm->hw, IEEE80211_IFACE_ITER_RESUME_ALL, 376 mvm->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
364 iwl_mvm_cleanup_iterator, mvm); 377 iwl_mvm_cleanup_iterator, mvm);
365 378
379 mvm->p2p_device_vif = NULL;
380
381 iwl_mvm_reset_phy_ctxts(mvm);
366 memset(mvm->fw_key_table, 0, sizeof(mvm->fw_key_table)); 382 memset(mvm->fw_key_table, 0, sizeof(mvm->fw_key_table));
367 memset(mvm->sta_drained, 0, sizeof(mvm->sta_drained)); 383 memset(mvm->sta_drained, 0, sizeof(mvm->sta_drained));
368 384
@@ -456,6 +472,20 @@ static void iwl_mvm_power_update_iterator(void *data, u8 *mac,
456 iwl_mvm_power_update_mode(mvm, vif); 472 iwl_mvm_power_update_mode(mvm, vif);
457} 473}
458 474
475static struct iwl_mvm_phy_ctxt *iwl_mvm_get_free_phy_ctxt(struct iwl_mvm *mvm)
476{
477 u16 i;
478
479 lockdep_assert_held(&mvm->mutex);
480
481 for (i = 0; i < NUM_PHY_CTX; i++)
482 if (!mvm->phy_ctxts[i].ref)
483 return &mvm->phy_ctxts[i];
484
485 IWL_ERR(mvm, "No available PHY context\n");
486 return NULL;
487}
488
459static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw, 489static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
460 struct ieee80211_vif *vif) 490 struct ieee80211_vif *vif)
461{ 491{
@@ -530,32 +560,34 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
530 */ 560 */
531 iwl_mvm_power_update_mode(mvm, vif); 561 iwl_mvm_power_update_mode(mvm, vif);
532 562
563 /* beacon filtering */
564 if (!mvm->bf_allowed_vif &&
565 vif->type == NL80211_IFTYPE_STATION && !vif->p2p){
566 mvm->bf_allowed_vif = mvmvif;
567 vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER;
568 }
569
570 ret = iwl_mvm_disable_beacon_filter(mvm, vif);
571 if (ret)
572 goto out_release;
573
533 /* 574 /*
534 * P2P_DEVICE interface does not have a channel context assigned to it, 575 * P2P_DEVICE interface does not have a channel context assigned to it,
535 * so a dedicated PHY context is allocated to it and the corresponding 576 * so a dedicated PHY context is allocated to it and the corresponding
536 * MAC context is bound to it at this stage. 577 * MAC context is bound to it at this stage.
537 */ 578 */
538 if (vif->type == NL80211_IFTYPE_P2P_DEVICE) { 579 if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
539 struct ieee80211_channel *chan;
540 struct cfg80211_chan_def chandef;
541 580
542 mvmvif->phy_ctxt = &mvm->phy_ctxt_roc; 581 mvmvif->phy_ctxt = iwl_mvm_get_free_phy_ctxt(mvm);
543 582 if (!mvmvif->phy_ctxt) {
544 /* 583 ret = -ENOSPC;
545 * The channel used here isn't relevant as it's
546 * going to be overwritten as part of the ROC flow.
547 * For now use the first channel we have.
548 */
549 chan = &mvm->hw->wiphy->bands[IEEE80211_BAND_2GHZ]->channels[0];
550 cfg80211_chandef_create(&chandef, chan, NL80211_CHAN_NO_HT);
551 ret = iwl_mvm_phy_ctxt_add(mvm, mvmvif->phy_ctxt,
552 &chandef, 1, 1);
553 if (ret)
554 goto out_remove_mac; 584 goto out_remove_mac;
585 }
555 586
587 iwl_mvm_phy_ctxt_ref(mvm, mvmvif->phy_ctxt);
556 ret = iwl_mvm_binding_add_vif(mvm, vif); 588 ret = iwl_mvm_binding_add_vif(mvm, vif);
557 if (ret) 589 if (ret)
558 goto out_remove_phy; 590 goto out_unref_phy;
559 591
560 ret = iwl_mvm_add_bcast_sta(mvm, vif, &mvmvif->bcast_sta); 592 ret = iwl_mvm_add_bcast_sta(mvm, vif, &mvmvif->bcast_sta);
561 if (ret) 593 if (ret)
@@ -571,27 +603,17 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
571 603
572 out_unbind: 604 out_unbind:
573 iwl_mvm_binding_remove_vif(mvm, vif); 605 iwl_mvm_binding_remove_vif(mvm, vif);
574 out_remove_phy: 606 out_unref_phy:
575 iwl_mvm_phy_ctxt_remove(mvm, mvmvif->phy_ctxt); 607 iwl_mvm_phy_ctxt_unref(mvm, mvmvif->phy_ctxt);
576 out_remove_mac: 608 out_remove_mac:
577 mvmvif->phy_ctxt = NULL; 609 mvmvif->phy_ctxt = NULL;
578 iwl_mvm_mac_ctxt_remove(mvm, vif); 610 iwl_mvm_mac_ctxt_remove(mvm, vif);
579 out_release: 611 out_release:
580 /*
581 * TODO: remove this temporary code.
582 * Currently MVM FW supports power management only on single MAC.
583 * Check if only one additional interface remains after releasing
584 * current one. Update power mode on the remaining interface.
585 */
586 if (vif->type != NL80211_IFTYPE_P2P_DEVICE) 612 if (vif->type != NL80211_IFTYPE_P2P_DEVICE)
587 mvm->vif_count--; 613 mvm->vif_count--;
588 IWL_DEBUG_MAC80211(mvm, "Currently %d interfaces active\n", 614 ieee80211_iterate_active_interfaces(
589 mvm->vif_count); 615 mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
590 if (mvm->vif_count == 1) { 616 iwl_mvm_power_update_iterator, mvm);
591 ieee80211_iterate_active_interfaces(
592 mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
593 iwl_mvm_power_update_iterator, mvm);
594 }
595 iwl_mvm_mac_ctxt_release(mvm, vif); 617 iwl_mvm_mac_ctxt_release(mvm, vif);
596 out_unlock: 618 out_unlock:
597 mutex_unlock(&mvm->mutex); 619 mutex_unlock(&mvm->mutex);
@@ -646,6 +668,11 @@ static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw,
646 668
647 mutex_lock(&mvm->mutex); 669 mutex_lock(&mvm->mutex);
648 670
671 if (mvm->bf_allowed_vif == mvmvif) {
672 mvm->bf_allowed_vif = NULL;
673 vif->driver_flags &= ~IEEE80211_VIF_BEACON_FILTER;
674 }
675
649 iwl_mvm_vif_dbgfs_clean(mvm, vif); 676 iwl_mvm_vif_dbgfs_clean(mvm, vif);
650 677
651 /* 678 /*
@@ -661,7 +688,7 @@ static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw,
661 mvm->p2p_device_vif = NULL; 688 mvm->p2p_device_vif = NULL;
662 iwl_mvm_rm_bcast_sta(mvm, &mvmvif->bcast_sta); 689 iwl_mvm_rm_bcast_sta(mvm, &mvmvif->bcast_sta);
663 iwl_mvm_binding_remove_vif(mvm, vif); 690 iwl_mvm_binding_remove_vif(mvm, vif);
664 iwl_mvm_phy_ctxt_remove(mvm, mvmvif->phy_ctxt); 691 iwl_mvm_phy_ctxt_unref(mvm, mvmvif->phy_ctxt);
665 mvmvif->phy_ctxt = NULL; 692 mvmvif->phy_ctxt = NULL;
666 } 693 }
667 694
@@ -748,6 +775,9 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
748 if (ret) 775 if (ret)
749 IWL_ERR(mvm, "failed to update quotas\n"); 776 IWL_ERR(mvm, "failed to update quotas\n");
750 } 777 }
778 ret = iwl_mvm_power_update_mode(mvm, vif);
779 if (ret)
780 IWL_ERR(mvm, "failed to update power mode\n");
751 } else if (changes & BSS_CHANGED_DTIM_PERIOD) { 781 } else if (changes & BSS_CHANGED_DTIM_PERIOD) {
752 /* 782 /*
753 * We received a beacon _after_ association so 783 * We received a beacon _after_ association so
@@ -756,19 +786,9 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
756 iwl_mvm_remove_time_event(mvm, mvmvif, 786 iwl_mvm_remove_time_event(mvm, mvmvif,
757 &mvmvif->time_event_data); 787 &mvmvif->time_event_data);
758 } else if (changes & BSS_CHANGED_PS) { 788 } else if (changes & BSS_CHANGED_PS) {
759 /* 789 ret = iwl_mvm_power_update_mode(mvm, vif);
760 * TODO: remove this temporary code. 790 if (ret)
761 * Currently MVM FW supports power management only on single 791 IWL_ERR(mvm, "failed to update power mode\n");
762 * MAC. Avoid power mode update if more than one interface
763 * is active.
764 */
765 IWL_DEBUG_MAC80211(mvm, "Currently %d interfaces active\n",
766 mvm->vif_count);
767 if (mvm->vif_count == 1) {
768 ret = iwl_mvm_power_update_mode(mvm, vif);
769 if (ret)
770 IWL_ERR(mvm, "failed to update power mode\n");
771 }
772 } 792 }
773} 793}
774 794
@@ -999,9 +1019,13 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
999 mvmvif->phy_ctxt->channel->band); 1019 mvmvif->phy_ctxt->channel->band);
1000 } else if (old_state == IEEE80211_STA_ASSOC && 1020 } else if (old_state == IEEE80211_STA_ASSOC &&
1001 new_state == IEEE80211_STA_AUTHORIZED) { 1021 new_state == IEEE80211_STA_AUTHORIZED) {
1022 /* enable beacon filtering */
1023 WARN_ON(iwl_mvm_enable_beacon_filter(mvm, vif));
1002 ret = 0; 1024 ret = 0;
1003 } else if (old_state == IEEE80211_STA_AUTHORIZED && 1025 } else if (old_state == IEEE80211_STA_AUTHORIZED &&
1004 new_state == IEEE80211_STA_ASSOC) { 1026 new_state == IEEE80211_STA_ASSOC) {
1027 /* disable beacon filtering */
1028 WARN_ON(iwl_mvm_disable_beacon_filter(mvm, vif));
1005 ret = 0; 1029 ret = 0;
1006 } else if (old_state == IEEE80211_STA_ASSOC && 1030 } else if (old_state == IEEE80211_STA_ASSOC &&
1007 new_state == IEEE80211_STA_AUTH) { 1031 new_state == IEEE80211_STA_AUTH) {
@@ -1167,29 +1191,107 @@ static int iwl_mvm_roc(struct ieee80211_hw *hw,
1167 enum ieee80211_roc_type type) 1191 enum ieee80211_roc_type type)
1168{ 1192{
1169 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 1193 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1194 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1170 struct cfg80211_chan_def chandef; 1195 struct cfg80211_chan_def chandef;
1171 int ret; 1196 struct iwl_mvm_phy_ctxt *phy_ctxt;
1197 int ret, i;
1198
1199 IWL_DEBUG_MAC80211(mvm, "enter (%d, %d, %d)\n", channel->hw_value,
1200 duration, type);
1172 1201
1173 if (vif->type != NL80211_IFTYPE_P2P_DEVICE) { 1202 if (vif->type != NL80211_IFTYPE_P2P_DEVICE) {
1174 IWL_ERR(mvm, "vif isn't a P2P_DEVICE: %d\n", vif->type); 1203 IWL_ERR(mvm, "vif isn't a P2P_DEVICE: %d\n", vif->type);
1175 return -EINVAL; 1204 return -EINVAL;
1176 } 1205 }
1177 1206
1178 IWL_DEBUG_MAC80211(mvm, "enter (%d, %d, %d)\n", channel->hw_value,
1179 duration, type);
1180
1181 mutex_lock(&mvm->mutex); 1207 mutex_lock(&mvm->mutex);
1182 1208
1209 for (i = 0; i < NUM_PHY_CTX; i++) {
1210 phy_ctxt = &mvm->phy_ctxts[i];
1211 if (phy_ctxt->ref == 0 || mvmvif->phy_ctxt == phy_ctxt)
1212 continue;
1213
1214 if (phy_ctxt->ref && channel == phy_ctxt->channel) {
1215 /*
1216 * Unbind the P2P_DEVICE from the current PHY context,
1217 * and if the PHY context is not used remove it.
1218 */
1219 ret = iwl_mvm_binding_remove_vif(mvm, vif);
1220 if (WARN(ret, "Failed unbinding P2P_DEVICE\n"))
1221 goto out_unlock;
1222
1223 iwl_mvm_phy_ctxt_unref(mvm, mvmvif->phy_ctxt);
1224
1225 /* Bind the P2P_DEVICE to the current PHY Context */
1226 mvmvif->phy_ctxt = phy_ctxt;
1227
1228 ret = iwl_mvm_binding_add_vif(mvm, vif);
1229 if (WARN(ret, "Failed binding P2P_DEVICE\n"))
1230 goto out_unlock;
1231
1232 iwl_mvm_phy_ctxt_ref(mvm, mvmvif->phy_ctxt);
1233 goto schedule_time_event;
1234 }
1235 }
1236
1237 /* Need to update the PHY context only if the ROC channel changed */
1238 if (channel == mvmvif->phy_ctxt->channel)
1239 goto schedule_time_event;
1240
1183 cfg80211_chandef_create(&chandef, channel, NL80211_CHAN_NO_HT); 1241 cfg80211_chandef_create(&chandef, channel, NL80211_CHAN_NO_HT);
1184 ret = iwl_mvm_phy_ctxt_changed(mvm, &mvm->phy_ctxt_roc,
1185 &chandef, 1, 1);
1186 1242
1243 /*
1244 * Change the PHY context configuration as it is currently referenced
1245 * only by the P2P Device MAC
1246 */
1247 if (mvmvif->phy_ctxt->ref == 1) {
1248 ret = iwl_mvm_phy_ctxt_changed(mvm, mvmvif->phy_ctxt,
1249 &chandef, 1, 1);
1250 if (ret)
1251 goto out_unlock;
1252 } else {
1253 /*
1254 * The PHY context is shared with other MACs. Need to remove the
1255 * P2P Device from the binding, allocate an new PHY context and
1256 * create a new binding
1257 */
1258 phy_ctxt = iwl_mvm_get_free_phy_ctxt(mvm);
1259 if (!phy_ctxt) {
1260 ret = -ENOSPC;
1261 goto out_unlock;
1262 }
1263
1264 ret = iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, &chandef,
1265 1, 1);
1266 if (ret) {
1267 IWL_ERR(mvm, "Failed to change PHY context\n");
1268 goto out_unlock;
1269 }
1270
1271 /* Unbind the P2P_DEVICE from the current PHY context */
1272 ret = iwl_mvm_binding_remove_vif(mvm, vif);
1273 if (WARN(ret, "Failed unbinding P2P_DEVICE\n"))
1274 goto out_unlock;
1275
1276 iwl_mvm_phy_ctxt_unref(mvm, mvmvif->phy_ctxt);
1277
1278 /* Bind the P2P_DEVICE to the new allocated PHY context */
1279 mvmvif->phy_ctxt = phy_ctxt;
1280
1281 ret = iwl_mvm_binding_add_vif(mvm, vif);
1282 if (WARN(ret, "Failed binding P2P_DEVICE\n"))
1283 goto out_unlock;
1284
1285 iwl_mvm_phy_ctxt_ref(mvm, mvmvif->phy_ctxt);
1286 }
1287
1288schedule_time_event:
1187 /* Schedule the time events */ 1289 /* Schedule the time events */
1188 ret = iwl_mvm_start_p2p_roc(mvm, vif, duration, type); 1290 ret = iwl_mvm_start_p2p_roc(mvm, vif, duration, type);
1189 1291
1292out_unlock:
1190 mutex_unlock(&mvm->mutex); 1293 mutex_unlock(&mvm->mutex);
1191 IWL_DEBUG_MAC80211(mvm, "leave\n"); 1294 IWL_DEBUG_MAC80211(mvm, "leave\n");
1192
1193 return ret; 1295 return ret;
1194} 1296}
1195 1297
@@ -1211,15 +1313,30 @@ static int iwl_mvm_add_chanctx(struct ieee80211_hw *hw,
1211 struct ieee80211_chanctx_conf *ctx) 1313 struct ieee80211_chanctx_conf *ctx)
1212{ 1314{
1213 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 1315 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1214 struct iwl_mvm_phy_ctxt *phy_ctxt = (void *)ctx->drv_priv; 1316 u16 *phy_ctxt_id = (u16 *)ctx->drv_priv;
1317 struct iwl_mvm_phy_ctxt *phy_ctxt;
1215 int ret; 1318 int ret;
1216 1319
1320 IWL_DEBUG_MAC80211(mvm, "Add channel context\n");
1321
1217 mutex_lock(&mvm->mutex); 1322 mutex_lock(&mvm->mutex);
1323 phy_ctxt = iwl_mvm_get_free_phy_ctxt(mvm);
1324 if (!phy_ctxt) {
1325 ret = -ENOSPC;
1326 goto out;
1327 }
1218 1328
1219 IWL_DEBUG_MAC80211(mvm, "Add PHY context\n"); 1329 ret = iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, &ctx->def,
1220 ret = iwl_mvm_phy_ctxt_add(mvm, phy_ctxt, &ctx->def, 1330 ctx->rx_chains_static,
1221 ctx->rx_chains_static, 1331 ctx->rx_chains_dynamic);
1222 ctx->rx_chains_dynamic); 1332 if (ret) {
1333 IWL_ERR(mvm, "Failed to add PHY context\n");
1334 goto out;
1335 }
1336
1337 iwl_mvm_phy_ctxt_ref(mvm, phy_ctxt);
1338 *phy_ctxt_id = phy_ctxt->id;
1339out:
1223 mutex_unlock(&mvm->mutex); 1340 mutex_unlock(&mvm->mutex);
1224 return ret; 1341 return ret;
1225} 1342}
@@ -1228,10 +1345,11 @@ static void iwl_mvm_remove_chanctx(struct ieee80211_hw *hw,
1228 struct ieee80211_chanctx_conf *ctx) 1345 struct ieee80211_chanctx_conf *ctx)
1229{ 1346{
1230 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 1347 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1231 struct iwl_mvm_phy_ctxt *phy_ctxt = (void *)ctx->drv_priv; 1348 u16 *phy_ctxt_id = (u16 *)ctx->drv_priv;
1349 struct iwl_mvm_phy_ctxt *phy_ctxt = &mvm->phy_ctxts[*phy_ctxt_id];
1232 1350
1233 mutex_lock(&mvm->mutex); 1351 mutex_lock(&mvm->mutex);
1234 iwl_mvm_phy_ctxt_remove(mvm, phy_ctxt); 1352 iwl_mvm_phy_ctxt_unref(mvm, phy_ctxt);
1235 mutex_unlock(&mvm->mutex); 1353 mutex_unlock(&mvm->mutex);
1236} 1354}
1237 1355
@@ -1240,7 +1358,16 @@ static void iwl_mvm_change_chanctx(struct ieee80211_hw *hw,
1240 u32 changed) 1358 u32 changed)
1241{ 1359{
1242 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 1360 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1243 struct iwl_mvm_phy_ctxt *phy_ctxt = (void *)ctx->drv_priv; 1361 u16 *phy_ctxt_id = (u16 *)ctx->drv_priv;
1362 struct iwl_mvm_phy_ctxt *phy_ctxt = &mvm->phy_ctxts[*phy_ctxt_id];
1363
1364 if (WARN_ONCE((phy_ctxt->ref > 1) &&
1365 (changed & ~(IEEE80211_CHANCTX_CHANGE_WIDTH |
1366 IEEE80211_CHANCTX_CHANGE_RX_CHAINS |
1367 IEEE80211_CHANCTX_CHANGE_RADAR)),
1368 "Cannot change PHY. Ref=%d, changed=0x%X\n",
1369 phy_ctxt->ref, changed))
1370 return;
1244 1371
1245 mutex_lock(&mvm->mutex); 1372 mutex_lock(&mvm->mutex);
1246 iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, &ctx->def, 1373 iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, &ctx->def,
@@ -1254,13 +1381,14 @@ static int iwl_mvm_assign_vif_chanctx(struct ieee80211_hw *hw,
1254 struct ieee80211_chanctx_conf *ctx) 1381 struct ieee80211_chanctx_conf *ctx)
1255{ 1382{
1256 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 1383 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1257 struct iwl_mvm_phy_ctxt *phyctx = (void *)ctx->drv_priv; 1384 u16 *phy_ctxt_id = (u16 *)ctx->drv_priv;
1385 struct iwl_mvm_phy_ctxt *phy_ctxt = &mvm->phy_ctxts[*phy_ctxt_id];
1258 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 1386 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1259 int ret; 1387 int ret;
1260 1388
1261 mutex_lock(&mvm->mutex); 1389 mutex_lock(&mvm->mutex);
1262 1390
1263 mvmvif->phy_ctxt = phyctx; 1391 mvmvif->phy_ctxt = phy_ctxt;
1264 1392
1265 switch (vif->type) { 1393 switch (vif->type) {
1266 case NL80211_IFTYPE_AP: 1394 case NL80211_IFTYPE_AP:
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h
index 9f46b23801bc..4e10aae71038 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h
@@ -88,6 +88,7 @@ enum iwl_mvm_tx_fifo {
88 IWL_MVM_TX_FIFO_BE, 88 IWL_MVM_TX_FIFO_BE,
89 IWL_MVM_TX_FIFO_VI, 89 IWL_MVM_TX_FIFO_VI,
90 IWL_MVM_TX_FIFO_VO, 90 IWL_MVM_TX_FIFO_VO,
91 IWL_MVM_TX_FIFO_MCAST = 5,
91}; 92};
92 93
93extern struct ieee80211_ops iwl_mvm_hw_ops; 94extern struct ieee80211_ops iwl_mvm_hw_ops;
@@ -109,6 +110,7 @@ extern struct iwl_mvm_mod_params iwlmvm_mod_params;
109struct iwl_mvm_phy_ctxt { 110struct iwl_mvm_phy_ctxt {
110 u16 id; 111 u16 id;
111 u16 color; 112 u16 color;
113 u32 ref;
112 114
113 /* 115 /*
114 * TODO: This should probably be removed. Currently here only for rate 116 * TODO: This should probably be removed. Currently here only for rate
@@ -149,6 +151,60 @@ enum iwl_power_scheme {
149 151
150#define IWL_CONN_MAX_LISTEN_INTERVAL 70 152#define IWL_CONN_MAX_LISTEN_INTERVAL 70
151 153
154#ifdef CONFIG_IWLWIFI_DEBUGFS
155enum iwl_dbgfs_pm_mask {
156 MVM_DEBUGFS_PM_KEEP_ALIVE = BIT(0),
157 MVM_DEBUGFS_PM_SKIP_OVER_DTIM = BIT(1),
158 MVM_DEBUGFS_PM_SKIP_DTIM_PERIODS = BIT(2),
159 MVM_DEBUGFS_PM_RX_DATA_TIMEOUT = BIT(3),
160 MVM_DEBUGFS_PM_TX_DATA_TIMEOUT = BIT(4),
161 MVM_DEBUGFS_PM_DISABLE_POWER_OFF = BIT(5),
162};
163
164struct iwl_dbgfs_pm {
165 u8 keep_alive_seconds;
166 u32 rx_data_timeout;
167 u32 tx_data_timeout;
168 bool skip_over_dtim;
169 u8 skip_dtim_periods;
170 bool disable_power_off;
171 int mask;
172};
173
174/* beacon filtering */
175
176enum iwl_dbgfs_bf_mask {
177 MVM_DEBUGFS_BF_ENERGY_DELTA = BIT(0),
178 MVM_DEBUGFS_BF_ROAMING_ENERGY_DELTA = BIT(1),
179 MVM_DEBUGFS_BF_ROAMING_STATE = BIT(2),
180 MVM_DEBUGFS_BF_TEMPERATURE_DELTA = BIT(3),
181 MVM_DEBUGFS_BF_ENABLE_BEACON_FILTER = BIT(4),
182 MVM_DEBUGFS_BF_DEBUG_FLAG = BIT(5),
183 MVM_DEBUGFS_BF_ESCAPE_TIMER = BIT(6),
184 MVM_DEBUGFS_BA_ESCAPE_TIMER = BIT(7),
185 MVM_DEBUGFS_BA_ENABLE_BEACON_ABORT = BIT(8),
186};
187
188struct iwl_dbgfs_bf {
189 u8 bf_energy_delta;
190 u8 bf_roaming_energy_delta;
191 u8 bf_roaming_state;
192 u8 bf_temperature_delta;
193 u8 bf_enable_beacon_filter;
194 u8 bf_debug_flag;
195 u32 bf_escape_timer;
196 u32 ba_escape_timer;
197 u8 ba_enable_beacon_abort;
198 int mask;
199};
200#endif
201
202enum iwl_mvm_smps_type_request {
203 IWL_MVM_SMPS_REQ_BT_COEX,
204 IWL_MVM_SMPS_REQ_TT,
205 NUM_IWL_MVM_SMPS_REQ,
206};
207
152/** 208/**
153 * struct iwl_mvm_vif - data per Virtual Interface, it is a MAC context 209 * struct iwl_mvm_vif - data per Virtual Interface, it is a MAC context
154 * @id: between 0 and 3 210 * @id: between 0 and 3
@@ -163,6 +219,8 @@ enum iwl_power_scheme {
163 * @bcast_sta: station used for broadcast packets. Used by the following 219 * @bcast_sta: station used for broadcast packets. Used by the following
164 * vifs: P2P_DEVICE, GO and AP. 220 * vifs: P2P_DEVICE, GO and AP.
165 * @beacon_skb: the skb used to hold the AP/GO beacon template 221 * @beacon_skb: the skb used to hold the AP/GO beacon template
222 * @smps_requests: the requests of of differents parts of the driver, regard
223 the desired smps mode.
166 */ 224 */
167struct iwl_mvm_vif { 225struct iwl_mvm_vif {
168 u16 id; 226 u16 id;
@@ -172,6 +230,8 @@ struct iwl_mvm_vif {
172 bool uploaded; 230 bool uploaded;
173 bool ap_active; 231 bool ap_active;
174 bool monitor_active; 232 bool monitor_active;
233 /* indicate whether beacon filtering is enabled */
234 bool bf_enabled;
175 235
176 u32 ap_beacon_time; 236 u32 ap_beacon_time;
177 237
@@ -214,7 +274,11 @@ struct iwl_mvm_vif {
214 struct dentry *dbgfs_dir; 274 struct dentry *dbgfs_dir;
215 struct dentry *dbgfs_slink; 275 struct dentry *dbgfs_slink;
216 void *dbgfs_data; 276 void *dbgfs_data;
277 struct iwl_dbgfs_pm dbgfs_pm;
278 struct iwl_dbgfs_bf dbgfs_bf;
217#endif 279#endif
280
281 enum ieee80211_smps_mode smps_requests[NUM_IWL_MVM_SMPS_REQ];
218}; 282};
219 283
220static inline struct iwl_mvm_vif * 284static inline struct iwl_mvm_vif *
@@ -223,12 +287,6 @@ iwl_mvm_vif_from_mac80211(struct ieee80211_vif *vif)
223 return (void *)vif->drv_priv; 287 return (void *)vif->drv_priv;
224} 288}
225 289
226enum iwl_mvm_status {
227 IWL_MVM_STATUS_HW_RFKILL,
228 IWL_MVM_STATUS_ROC_RUNNING,
229 IWL_MVM_STATUS_IN_HW_RESTART,
230};
231
232enum iwl_scan_status { 290enum iwl_scan_status {
233 IWL_MVM_SCAN_NONE, 291 IWL_MVM_SCAN_NONE,
234 IWL_MVM_SCAN_OS, 292 IWL_MVM_SCAN_OS,
@@ -246,6 +304,63 @@ struct iwl_nvm_section {
246 const u8 *data; 304 const u8 *data;
247}; 305};
248 306
307/*
308 * Tx-backoff threshold
309 * @temperature: The threshold in Celsius
310 * @backoff: The tx-backoff in uSec
311 */
312struct iwl_tt_tx_backoff {
313 s32 temperature;
314 u32 backoff;
315};
316
317#define TT_TX_BACKOFF_SIZE 6
318
319/**
320 * struct iwl_tt_params - thermal throttling parameters
321 * @ct_kill_entry: CT Kill entry threshold
322 * @ct_kill_exit: CT Kill exit threshold
323 * @ct_kill_duration: The time intervals (in uSec) in which the driver needs
324 * to checks whether to exit CT Kill.
325 * @dynamic_smps_entry: Dynamic SMPS entry threshold
326 * @dynamic_smps_exit: Dynamic SMPS exit threshold
327 * @tx_protection_entry: TX protection entry threshold
328 * @tx_protection_exit: TX protection exit threshold
329 * @tx_backoff: Array of thresholds for tx-backoff , in ascending order.
330 * @support_ct_kill: Support CT Kill?
331 * @support_dynamic_smps: Support dynamic SMPS?
332 * @support_tx_protection: Support tx protection?
333 * @support_tx_backoff: Support tx-backoff?
334 */
335struct iwl_tt_params {
336 s32 ct_kill_entry;
337 s32 ct_kill_exit;
338 u32 ct_kill_duration;
339 s32 dynamic_smps_entry;
340 s32 dynamic_smps_exit;
341 s32 tx_protection_entry;
342 s32 tx_protection_exit;
343 struct iwl_tt_tx_backoff tx_backoff[TT_TX_BACKOFF_SIZE];
344 bool support_ct_kill;
345 bool support_dynamic_smps;
346 bool support_tx_protection;
347 bool support_tx_backoff;
348};
349
350/**
351 * struct iwl_mvm_tt_mgnt - Thermal Throttling Management structure
352 * @ct_kill_exit: worker to exit thermal kill
353 * @dynamic_smps: Is thermal throttling enabled dynamic_smps?
354 * @tx_backoff: The current thremal throttling tx backoff in uSec.
355 * @params: Parameters to configure the thermal throttling algorithm.
356 */
357struct iwl_mvm_tt_mgmt {
358 struct delayed_work ct_kill_exit;
359 bool dynamic_smps;
360 u32 tx_backoff;
361 const struct iwl_tt_params *params;
362};
363
249struct iwl_mvm { 364struct iwl_mvm {
250 /* for logger access */ 365 /* for logger access */
251 struct device *dev; 366 struct device *dev;
@@ -266,6 +381,12 @@ struct iwl_mvm {
266 381
267 unsigned long status; 382 unsigned long status;
268 383
384 /*
385 * for beacon filtering -
386 * currently only one interface can be supported
387 */
388 struct iwl_mvm_vif *bf_allowed_vif;
389
269 enum iwl_ucode_type cur_ucode; 390 enum iwl_ucode_type cur_ucode;
270 bool ucode_loaded; 391 bool ucode_loaded;
271 bool init_ucode_run; 392 bool init_ucode_run;
@@ -313,7 +434,7 @@ struct iwl_mvm {
313 bool prevent_power_down_d3; 434 bool prevent_power_down_d3;
314#endif 435#endif
315 436
316 struct iwl_mvm_phy_ctxt phy_ctxt_roc; 437 struct iwl_mvm_phy_ctxt phy_ctxts[NUM_PHY_CTX];
317 438
318 struct list_head time_event_list; 439 struct list_head time_event_list;
319 spinlock_t time_event_lock; 440 spinlock_t time_event_lock;
@@ -338,11 +459,21 @@ struct iwl_mvm {
338 459
339#ifdef CONFIG_PM_SLEEP 460#ifdef CONFIG_PM_SLEEP
340 int gtk_ivlen, gtk_icvlen, ptk_ivlen, ptk_icvlen; 461 int gtk_ivlen, gtk_icvlen, ptk_ivlen, ptk_icvlen;
462#ifdef CONFIG_IWLWIFI_DEBUGFS
463 bool d3_test_active;
464 bool store_d3_resume_sram;
465 void *d3_resume_sram;
466 u32 d3_test_pme_ptr;
467#endif
341#endif 468#endif
342 469
343 /* BT-Coex */ 470 /* BT-Coex */
344 u8 bt_kill_msk; 471 u8 bt_kill_msk;
345 struct iwl_bt_coex_profile_notif last_bt_notif; 472 struct iwl_bt_coex_profile_notif last_bt_notif;
473
474 /* Thermal Throttling and CTkill */
475 struct iwl_mvm_tt_mgmt thermal_throttle;
476 s32 temperature; /* Celsius */
346}; 477};
347 478
348/* Extract MVM priv from op_mode and _hw */ 479/* Extract MVM priv from op_mode and _hw */
@@ -352,6 +483,19 @@ struct iwl_mvm {
352#define IWL_MAC80211_GET_MVM(_hw) \ 483#define IWL_MAC80211_GET_MVM(_hw) \
353 IWL_OP_MODE_GET_MVM((struct iwl_op_mode *)((_hw)->priv)) 484 IWL_OP_MODE_GET_MVM((struct iwl_op_mode *)((_hw)->priv))
354 485
486enum iwl_mvm_status {
487 IWL_MVM_STATUS_HW_RFKILL,
488 IWL_MVM_STATUS_HW_CTKILL,
489 IWL_MVM_STATUS_ROC_RUNNING,
490 IWL_MVM_STATUS_IN_HW_RESTART,
491};
492
493static inline bool iwl_mvm_is_radio_killed(struct iwl_mvm *mvm)
494{
495 return test_bit(IWL_MVM_STATUS_HW_RFKILL, &mvm->status) ||
496 test_bit(IWL_MVM_STATUS_HW_CTKILL, &mvm->status);
497}
498
355extern const u8 iwl_mvm_ac_to_tx_fifo[]; 499extern const u8 iwl_mvm_ac_to_tx_fifo[];
356 500
357struct iwl_rate_info { 501struct iwl_rate_info {
@@ -443,8 +587,10 @@ int iwl_mvm_phy_ctxt_add(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt,
443int iwl_mvm_phy_ctxt_changed(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt, 587int iwl_mvm_phy_ctxt_changed(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt,
444 struct cfg80211_chan_def *chandef, 588 struct cfg80211_chan_def *chandef,
445 u8 chains_static, u8 chains_dynamic); 589 u8 chains_static, u8 chains_dynamic);
446void iwl_mvm_phy_ctxt_remove(struct iwl_mvm *mvm, 590void iwl_mvm_phy_ctxt_ref(struct iwl_mvm *mvm,
447 struct iwl_mvm_phy_ctxt *ctxt); 591 struct iwl_mvm_phy_ctxt *ctxt);
592void iwl_mvm_phy_ctxt_unref(struct iwl_mvm *mvm,
593 struct iwl_mvm_phy_ctxt *ctxt);
448 594
449/* MAC (virtual interface) programming */ 595/* MAC (virtual interface) programming */
450int iwl_mvm_mac_ctxt_init(struct iwl_mvm *mvm, struct ieee80211_vif *vif); 596int iwl_mvm_mac_ctxt_init(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
@@ -459,6 +605,9 @@ int iwl_mvm_mac_ctxt_beacon_changed(struct iwl_mvm *mvm,
459int iwl_mvm_rx_beacon_notif(struct iwl_mvm *mvm, 605int iwl_mvm_rx_beacon_notif(struct iwl_mvm *mvm,
460 struct iwl_rx_cmd_buffer *rxb, 606 struct iwl_rx_cmd_buffer *rxb,
461 struct iwl_device_cmd *cmd); 607 struct iwl_device_cmd *cmd);
608int iwl_mvm_rx_missed_beacons_notif(struct iwl_mvm *mvm,
609 struct iwl_rx_cmd_buffer *rxb,
610 struct iwl_device_cmd *cmd);
462 611
463/* Bindings */ 612/* Bindings */
464int iwl_mvm_binding_add_vif(struct iwl_mvm *mvm, struct ieee80211_vif *vif); 613int iwl_mvm_binding_add_vif(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
@@ -523,6 +672,7 @@ void iwl_mvm_ipv6_addr_change(struct ieee80211_hw *hw,
523 struct inet6_dev *idev); 672 struct inet6_dev *idev);
524void iwl_mvm_set_default_unicast_key(struct ieee80211_hw *hw, 673void iwl_mvm_set_default_unicast_key(struct ieee80211_hw *hw,
525 struct ieee80211_vif *vif, int idx); 674 struct ieee80211_vif *vif, int idx);
675extern const struct file_operations iwl_dbgfs_d3_test_ops;
526 676
527/* BT Coex */ 677/* BT Coex */
528int iwl_send_bt_prio_tbl(struct iwl_mvm *mvm); 678int iwl_send_bt_prio_tbl(struct iwl_mvm *mvm);
@@ -534,4 +684,36 @@ void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
534 enum ieee80211_rssi_event rssi_event); 684 enum ieee80211_rssi_event rssi_event);
535void iwl_mvm_bt_coex_vif_assoc(struct iwl_mvm *mvm, struct ieee80211_vif *vif); 685void iwl_mvm_bt_coex_vif_assoc(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
536 686
687/* beacon filtering */
688#ifdef CONFIG_IWLWIFI_DEBUGFS
689void
690iwl_mvm_beacon_filter_debugfs_parameters(struct ieee80211_vif *vif,
691 struct iwl_beacon_filter_cmd *cmd);
692int iwl_mvm_dbgfs_set_fw_dbg_log(struct iwl_mvm *mvm);
693#else
694static inline void
695iwl_mvm_beacon_filter_debugfs_parameters(struct ieee80211_vif *vif,
696 struct iwl_beacon_filter_cmd *cmd)
697{}
698static inline int iwl_mvm_dbgfs_set_fw_dbg_log(struct iwl_mvm *mvm)
699{
700 return 0;
701}
702#endif
703int iwl_mvm_enable_beacon_filter(struct iwl_mvm *mvm,
704 struct ieee80211_vif *vif);
705int iwl_mvm_disable_beacon_filter(struct iwl_mvm *mvm,
706 struct ieee80211_vif *vif);
707
708/* SMPS */
709void iwl_mvm_update_smps(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
710 enum iwl_mvm_smps_type_request req_type,
711 enum ieee80211_smps_mode smps_request);
712
713/* Thermal management and CT-kill */
714void iwl_mvm_tt_handler(struct iwl_mvm *mvm);
715void iwl_mvm_tt_initialize(struct iwl_mvm *mvm);
716void iwl_mvm_tt_exit(struct iwl_mvm *mvm);
717void iwl_mvm_set_hw_ctkill_state(struct iwl_mvm *mvm, bool state);
718
537#endif /* __IWL_MVM_H__ */ 719#endif /* __IWL_MVM_H__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/nvm.c b/drivers/net/wireless/iwlwifi/mvm/nvm.c
index b8ec02f89acc..edb94ea31654 100644
--- a/drivers/net/wireless/iwlwifi/mvm/nvm.c
+++ b/drivers/net/wireless/iwlwifi/mvm/nvm.c
@@ -60,6 +60,7 @@
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 * 61 *
62 *****************************************************************************/ 62 *****************************************************************************/
63#include <linux/firmware.h>
63#include "iwl-trans.h" 64#include "iwl-trans.h"
64#include "mvm.h" 65#include "mvm.h"
65#include "iwl-eeprom-parse.h" 66#include "iwl-eeprom-parse.h"
@@ -75,31 +76,56 @@ static const int nvm_to_read[] = {
75}; 76};
76 77
77/* Default NVM size to read */ 78/* Default NVM size to read */
78#define IWL_NVM_DEFAULT_CHUNK_SIZE (2*1024); 79#define IWL_NVM_DEFAULT_CHUNK_SIZE (2*1024)
80#define IWL_MAX_NVM_SECTION_SIZE 6000
79 81
80static inline void iwl_nvm_fill_read(struct iwl_nvm_access_cmd *cmd, 82#define NVM_WRITE_OPCODE 1
81 u16 offset, u16 length, u16 section) 83#define NVM_READ_OPCODE 0
84
85/*
86 * prepare the NVM host command w/ the pointers to the nvm buffer
87 * and send it to fw
88 */
89static int iwl_nvm_write_chunk(struct iwl_mvm *mvm, u16 section,
90 u16 offset, u16 length, const u8 *data)
82{ 91{
83 cmd->offset = cpu_to_le16(offset); 92 struct iwl_nvm_access_cmd nvm_access_cmd = {
84 cmd->length = cpu_to_le16(length); 93 .offset = cpu_to_le16(offset),
85 cmd->type = cpu_to_le16(section); 94 .length = cpu_to_le16(length),
95 .type = cpu_to_le16(section),
96 .op_code = NVM_WRITE_OPCODE,
97 };
98 struct iwl_host_cmd cmd = {
99 .id = NVM_ACCESS_CMD,
100 .len = { sizeof(struct iwl_nvm_access_cmd), length },
101 .flags = CMD_SYNC | CMD_SEND_IN_RFKILL,
102 .data = { &nvm_access_cmd, data },
103 /* data may come from vmalloc, so use _DUP */
104 .dataflags = { 0, IWL_HCMD_DFL_DUP },
105 };
106
107 return iwl_mvm_send_cmd(mvm, &cmd);
86} 108}
87 109
88static int iwl_nvm_read_chunk(struct iwl_mvm *mvm, u16 section, 110static int iwl_nvm_read_chunk(struct iwl_mvm *mvm, u16 section,
89 u16 offset, u16 length, u8 *data) 111 u16 offset, u16 length, u8 *data)
90{ 112{
91 struct iwl_nvm_access_cmd nvm_access_cmd = {}; 113 struct iwl_nvm_access_cmd nvm_access_cmd = {
114 .offset = cpu_to_le16(offset),
115 .length = cpu_to_le16(length),
116 .type = cpu_to_le16(section),
117 .op_code = NVM_READ_OPCODE,
118 };
92 struct iwl_nvm_access_resp *nvm_resp; 119 struct iwl_nvm_access_resp *nvm_resp;
93 struct iwl_rx_packet *pkt; 120 struct iwl_rx_packet *pkt;
94 struct iwl_host_cmd cmd = { 121 struct iwl_host_cmd cmd = {
95 .id = NVM_ACCESS_CMD, 122 .id = NVM_ACCESS_CMD,
96 .flags = CMD_SYNC | CMD_WANT_SKB, 123 .flags = CMD_SYNC | CMD_WANT_SKB | CMD_SEND_IN_RFKILL,
97 .data = { &nvm_access_cmd, }, 124 .data = { &nvm_access_cmd, },
98 }; 125 };
99 int ret, bytes_read, offset_read; 126 int ret, bytes_read, offset_read;
100 u8 *resp_data; 127 u8 *resp_data;
101 128
102 iwl_nvm_fill_read(&nvm_access_cmd, offset, length, section);
103 cmd.len[0] = sizeof(struct iwl_nvm_access_cmd); 129 cmd.len[0] = sizeof(struct iwl_nvm_access_cmd);
104 130
105 ret = iwl_mvm_send_cmd(mvm, &cmd); 131 ret = iwl_mvm_send_cmd(mvm, &cmd);
@@ -144,6 +170,30 @@ exit:
144 return ret; 170 return ret;
145} 171}
146 172
173static int iwl_nvm_write_section(struct iwl_mvm *mvm, u16 section,
174 const u8 *data, u16 length)
175{
176 int offset = 0;
177
178 /* copy data in chunks of 2k (and remainder if any) */
179
180 while (offset < length) {
181 int chunk_size, ret;
182
183 chunk_size = min(IWL_NVM_DEFAULT_CHUNK_SIZE,
184 length - offset);
185
186 ret = iwl_nvm_write_chunk(mvm, section, offset,
187 chunk_size, data + offset);
188 if (ret < 0)
189 return ret;
190
191 offset += chunk_size;
192 }
193
194 return 0;
195}
196
147/* 197/*
148 * Reads an NVM section completely. 198 * Reads an NVM section completely.
149 * NICs prior to 7000 family doesn't have a real NVM, but just read 199 * NICs prior to 7000 family doesn't have a real NVM, but just read
@@ -177,7 +227,8 @@ static int iwl_nvm_read_section(struct iwl_mvm *mvm, u16 section,
177 offset += ret; 227 offset += ret;
178 } 228 }
179 229
180 IWL_INFO(mvm, "NVM section %d read completed\n", section); 230 IWL_DEBUG_EEPROM(mvm->trans->dev,
231 "NVM section %d read completed\n", section);
181 return offset; 232 return offset;
182} 233}
183 234
@@ -200,7 +251,130 @@ iwl_parse_nvm_sections(struct iwl_mvm *mvm)
200 hw = (const __le16 *)sections[NVM_SECTION_TYPE_HW].data; 251 hw = (const __le16 *)sections[NVM_SECTION_TYPE_HW].data;
201 sw = (const __le16 *)sections[NVM_SECTION_TYPE_SW].data; 252 sw = (const __le16 *)sections[NVM_SECTION_TYPE_SW].data;
202 calib = (const __le16 *)sections[NVM_SECTION_TYPE_CALIBRATION].data; 253 calib = (const __le16 *)sections[NVM_SECTION_TYPE_CALIBRATION].data;
203 return iwl_parse_nvm_data(mvm->trans->dev, mvm->cfg, hw, sw, calib); 254 return iwl_parse_nvm_data(mvm->trans->dev, mvm->cfg, hw, sw, calib,
255 iwl_fw_valid_tx_ant(mvm->fw),
256 iwl_fw_valid_rx_ant(mvm->fw));
257}
258
259#define MAX_NVM_FILE_LEN 16384
260
261/*
262 * HOW TO CREATE THE NVM FILE FORMAT:
263 * ------------------------------
264 * 1. create hex file, format:
265 * 3800 -> header
266 * 0000 -> header
267 * 5a40 -> data
268 *
269 * rev - 6 bit (word1)
270 * len - 10 bit (word1)
271 * id - 4 bit (word2)
272 * rsv - 12 bit (word2)
273 *
274 * 2. flip 8bits with 8 bits per line to get the right NVM file format
275 *
276 * 3. create binary file from the hex file
277 *
278 * 4. save as "iNVM_xxx.bin" under /lib/firmware
279 */
280static int iwl_mvm_load_external_nvm(struct iwl_mvm *mvm)
281{
282 int ret, section_id, section_size;
283 const struct firmware *fw_entry;
284 const struct {
285 __le16 word1;
286 __le16 word2;
287 u8 data[];
288 } *file_sec;
289 const u8 *eof;
290
291#define NVM_WORD1_LEN(x) (8 * (x & 0x03FF))
292#define NVM_WORD2_ID(x) (x >> 12)
293
294 /*
295 * Obtain NVM image via request_firmware. Since we already used
296 * request_firmware_nowait() for the firmware binary load and only
297 * get here after that we assume the NVM request can be satisfied
298 * synchronously.
299 */
300 ret = request_firmware(&fw_entry, iwlwifi_mod_params.nvm_file,
301 mvm->trans->dev);
302 if (ret) {
303 IWL_ERR(mvm, "ERROR: %s isn't available %d\n",
304 iwlwifi_mod_params.nvm_file, ret);
305 return ret;
306 }
307
308 IWL_INFO(mvm, "Loaded NVM file %s (%zu bytes)\n",
309 iwlwifi_mod_params.nvm_file, fw_entry->size);
310
311 if (fw_entry->size < sizeof(*file_sec)) {
312 IWL_ERR(mvm, "NVM file too small\n");
313 ret = -EINVAL;
314 goto out;
315 }
316
317 if (fw_entry->size > MAX_NVM_FILE_LEN) {
318 IWL_ERR(mvm, "NVM file too large\n");
319 ret = -EINVAL;
320 goto out;
321 }
322
323 eof = fw_entry->data + fw_entry->size;
324
325 file_sec = (void *)fw_entry->data;
326
327 while (true) {
328 if (file_sec->data > eof) {
329 IWL_ERR(mvm,
330 "ERROR - NVM file too short for section header\n");
331 ret = -EINVAL;
332 break;
333 }
334
335 /* check for EOF marker */
336 if (!file_sec->word1 && !file_sec->word2) {
337 ret = 0;
338 break;
339 }
340
341 section_size = 2 * NVM_WORD1_LEN(le16_to_cpu(file_sec->word1));
342 section_id = NVM_WORD2_ID(le16_to_cpu(file_sec->word2));
343
344 if (section_size > IWL_MAX_NVM_SECTION_SIZE) {
345 IWL_ERR(mvm, "ERROR - section too large (%d)\n",
346 section_size);
347 ret = -EINVAL;
348 break;
349 }
350
351 if (!section_size) {
352 IWL_ERR(mvm, "ERROR - section empty\n");
353 ret = -EINVAL;
354 break;
355 }
356
357 if (file_sec->data + section_size > eof) {
358 IWL_ERR(mvm,
359 "ERROR - NVM file too short for section (%d bytes)\n",
360 section_size);
361 ret = -EINVAL;
362 break;
363 }
364
365 ret = iwl_nvm_write_section(mvm, section_id, file_sec->data,
366 section_size);
367 if (ret < 0) {
368 IWL_ERR(mvm, "iwl_mvm_send_cmd failed: %d\n", ret);
369 break;
370 }
371
372 /* advance to the next section */
373 file_sec = (void *)(file_sec->data + section_size);
374 }
375out:
376 release_firmware(fw_entry);
377 return ret;
204} 378}
205 379
206int iwl_nvm_init(struct iwl_mvm *mvm) 380int iwl_nvm_init(struct iwl_mvm *mvm)
@@ -208,6 +382,17 @@ int iwl_nvm_init(struct iwl_mvm *mvm)
208 int ret, i, section; 382 int ret, i, section;
209 u8 *nvm_buffer, *temp; 383 u8 *nvm_buffer, *temp;
210 384
385 /* load external NVM if configured */
386 if (iwlwifi_mod_params.nvm_file) {
387 /* move to External NVM flow */
388 ret = iwl_mvm_load_external_nvm(mvm);
389 if (ret)
390 return ret;
391 }
392
393 /* Read From FW NVM */
394 IWL_DEBUG_EEPROM(mvm->trans->dev, "Read from NVM\n");
395
211 /* TODO: find correct NVM max size for a section */ 396 /* TODO: find correct NVM max size for a section */
212 nvm_buffer = kmalloc(mvm->cfg->base_params->eeprom_size, 397 nvm_buffer = kmalloc(mvm->cfg->base_params->eeprom_size,
213 GFP_KERNEL); 398 GFP_KERNEL);
@@ -231,8 +416,9 @@ int iwl_nvm_init(struct iwl_mvm *mvm)
231 if (ret < 0) 416 if (ret < 0)
232 return ret; 417 return ret;
233 418
234 ret = 0;
235 mvm->nvm_data = iwl_parse_nvm_sections(mvm); 419 mvm->nvm_data = iwl_parse_nvm_sections(mvm);
420 if (!mvm->nvm_data)
421 return -ENODATA;
236 422
237 return ret; 423 return 0;
238} 424}
diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c
index b29c31a41594..af79a14063a9 100644
--- a/drivers/net/wireless/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/iwlwifi/mvm/ops.c
@@ -215,17 +215,22 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = {
215 RX_HANDLER(REPLY_RX_PHY_CMD, iwl_mvm_rx_rx_phy_cmd, false), 215 RX_HANDLER(REPLY_RX_PHY_CMD, iwl_mvm_rx_rx_phy_cmd, false),
216 RX_HANDLER(TX_CMD, iwl_mvm_rx_tx_cmd, false), 216 RX_HANDLER(TX_CMD, iwl_mvm_rx_tx_cmd, false),
217 RX_HANDLER(BA_NOTIF, iwl_mvm_rx_ba_notif, false), 217 RX_HANDLER(BA_NOTIF, iwl_mvm_rx_ba_notif, false),
218
219 RX_HANDLER(BT_PROFILE_NOTIFICATION, iwl_mvm_rx_bt_coex_notif, true),
220 RX_HANDLER(BEACON_NOTIFICATION, iwl_mvm_rx_beacon_notif, false),
221 RX_HANDLER(STATISTICS_NOTIFICATION, iwl_mvm_rx_statistics, true),
222
218 RX_HANDLER(TIME_EVENT_NOTIFICATION, iwl_mvm_rx_time_event_notif, false), 223 RX_HANDLER(TIME_EVENT_NOTIFICATION, iwl_mvm_rx_time_event_notif, false),
219 224
220 RX_HANDLER(SCAN_REQUEST_CMD, iwl_mvm_rx_scan_response, false), 225 RX_HANDLER(SCAN_REQUEST_CMD, iwl_mvm_rx_scan_response, false),
221 RX_HANDLER(SCAN_COMPLETE_NOTIFICATION, iwl_mvm_rx_scan_complete, false), 226 RX_HANDLER(SCAN_COMPLETE_NOTIFICATION, iwl_mvm_rx_scan_complete, false),
222 227
223 RX_HANDLER(BT_PROFILE_NOTIFICATION, iwl_mvm_rx_bt_coex_notif, true),
224 RX_HANDLER(BEACON_NOTIFICATION, iwl_mvm_rx_beacon_notif, false),
225
226 RX_HANDLER(RADIO_VERSION_NOTIFICATION, iwl_mvm_rx_radio_ver, false), 228 RX_HANDLER(RADIO_VERSION_NOTIFICATION, iwl_mvm_rx_radio_ver, false),
227 RX_HANDLER(CARD_STATE_NOTIFICATION, iwl_mvm_rx_card_state_notif, false), 229 RX_HANDLER(CARD_STATE_NOTIFICATION, iwl_mvm_rx_card_state_notif, false),
228 230
231 RX_HANDLER(MISSED_BEACONS_NOTIFICATION, iwl_mvm_rx_missed_beacons_notif,
232 false),
233
229 RX_HANDLER(REPLY_ERROR, iwl_mvm_rx_fw_error, false), 234 RX_HANDLER(REPLY_ERROR, iwl_mvm_rx_fw_error, false),
230}; 235};
231#undef RX_HANDLER 236#undef RX_HANDLER
@@ -288,11 +293,14 @@ static const char *iwl_mvm_cmd_strings[REPLY_MAX] = {
288 CMD(NET_DETECT_HOTSPOTS_CMD), 293 CMD(NET_DETECT_HOTSPOTS_CMD),
289 CMD(NET_DETECT_HOTSPOTS_QUERY_CMD), 294 CMD(NET_DETECT_HOTSPOTS_QUERY_CMD),
290 CMD(CARD_STATE_NOTIFICATION), 295 CMD(CARD_STATE_NOTIFICATION),
296 CMD(MISSED_BEACONS_NOTIFICATION),
291 CMD(BT_COEX_PRIO_TABLE), 297 CMD(BT_COEX_PRIO_TABLE),
292 CMD(BT_COEX_PROT_ENV), 298 CMD(BT_COEX_PROT_ENV),
293 CMD(BT_PROFILE_NOTIFICATION), 299 CMD(BT_PROFILE_NOTIFICATION),
294 CMD(BT_CONFIG), 300 CMD(BT_CONFIG),
295 CMD(MCAST_FILTER_CMD), 301 CMD(MCAST_FILTER_CMD),
302 CMD(REPLY_BEACON_FILTERING_CMD),
303 CMD(REPLY_THERMAL_MNG_BACKOFF),
296}; 304};
297#undef CMD 305#undef CMD
298 306
@@ -393,10 +401,13 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
393 if (err) 401 if (err)
394 goto out_free; 402 goto out_free;
395 403
404 iwl_mvm_tt_initialize(mvm);
405
396 mutex_lock(&mvm->mutex); 406 mutex_lock(&mvm->mutex);
397 err = iwl_run_init_mvm_ucode(mvm, true); 407 err = iwl_run_init_mvm_ucode(mvm, true);
398 mutex_unlock(&mvm->mutex); 408 mutex_unlock(&mvm->mutex);
399 if (err && !iwlmvm_mod_params.init_dbg) { 409 /* returns 0 if successful, 1 if success but in rfkill */
410 if (err < 0 && !iwlmvm_mod_params.init_dbg) {
400 IWL_ERR(mvm, "Failed to run INIT ucode: %d\n", err); 411 IWL_ERR(mvm, "Failed to run INIT ucode: %d\n", err);
401 goto out_free; 412 goto out_free;
402 } 413 }
@@ -439,10 +450,16 @@ static void iwl_op_mode_mvm_stop(struct iwl_op_mode *op_mode)
439 450
440 iwl_mvm_leds_exit(mvm); 451 iwl_mvm_leds_exit(mvm);
441 452
453 iwl_mvm_tt_exit(mvm);
454
442 ieee80211_unregister_hw(mvm->hw); 455 ieee80211_unregister_hw(mvm->hw);
443 456
444 kfree(mvm->scan_cmd); 457 kfree(mvm->scan_cmd);
445 458
459#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_IWLWIFI_DEBUGFS)
460 kfree(mvm->d3_resume_sram);
461#endif
462
446 iwl_trans_stop_hw(mvm->trans, true); 463 iwl_trans_stop_hw(mvm->trans, true);
447 464
448 iwl_phy_db_free(mvm->phy_db); 465 iwl_phy_db_free(mvm->phy_db);
@@ -589,6 +606,16 @@ static void iwl_mvm_wake_sw_queue(struct iwl_op_mode *op_mode, int queue)
589 ieee80211_wake_queue(mvm->hw, mq); 606 ieee80211_wake_queue(mvm->hw, mq);
590} 607}
591 608
609void iwl_mvm_set_hw_ctkill_state(struct iwl_mvm *mvm, bool state)
610{
611 if (state)
612 set_bit(IWL_MVM_STATUS_HW_CTKILL, &mvm->status);
613 else
614 clear_bit(IWL_MVM_STATUS_HW_CTKILL, &mvm->status);
615
616 wiphy_rfkill_set_hw_state(mvm->hw->wiphy, iwl_mvm_is_radio_killed(mvm));
617}
618
592static void iwl_mvm_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state) 619static void iwl_mvm_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state)
593{ 620{
594 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode); 621 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
@@ -598,7 +625,7 @@ static void iwl_mvm_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state)
598 else 625 else
599 clear_bit(IWL_MVM_STATUS_HW_RFKILL, &mvm->status); 626 clear_bit(IWL_MVM_STATUS_HW_RFKILL, &mvm->status);
600 627
601 wiphy_rfkill_set_hw_state(mvm->hw->wiphy, state); 628 wiphy_rfkill_set_hw_state(mvm->hw->wiphy, iwl_mvm_is_radio_killed(mvm));
602} 629}
603 630
604static void iwl_mvm_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb) 631static void iwl_mvm_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb)
diff --git a/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c
index a28a1d1f23eb..a8652ddd6bed 100644
--- a/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c
+++ b/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c
@@ -195,21 +195,6 @@ static int iwl_mvm_phy_ctxt_apply(struct iwl_mvm *mvm,
195 return ret; 195 return ret;
196} 196}
197 197
198
199struct phy_ctx_used_data {
200 unsigned long used[BITS_TO_LONGS(NUM_PHY_CTX)];
201};
202
203static void iwl_mvm_phy_ctx_used_iter(struct ieee80211_hw *hw,
204 struct ieee80211_chanctx_conf *ctx,
205 void *_data)
206{
207 struct phy_ctx_used_data *data = _data;
208 struct iwl_mvm_phy_ctxt *phy_ctxt = (void *)ctx->drv_priv;
209
210 __set_bit(phy_ctxt->id, data->used);
211}
212
213/* 198/*
214 * Send a command to add a PHY context based on the current HW configuration. 199 * Send a command to add a PHY context based on the current HW configuration.
215 */ 200 */
@@ -217,34 +202,28 @@ int iwl_mvm_phy_ctxt_add(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt,
217 struct cfg80211_chan_def *chandef, 202 struct cfg80211_chan_def *chandef,
218 u8 chains_static, u8 chains_dynamic) 203 u8 chains_static, u8 chains_dynamic)
219{ 204{
220 struct phy_ctx_used_data data = { 205 int ret;
221 .used = { },
222 };
223
224 /*
225 * If this is a regular PHY context (not the ROC one)
226 * skip the ROC PHY context's ID.
227 */
228 if (ctxt != &mvm->phy_ctxt_roc)
229 __set_bit(mvm->phy_ctxt_roc.id, data.used);
230 206
207 WARN_ON(!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status) &&
208 ctxt->ref);
231 lockdep_assert_held(&mvm->mutex); 209 lockdep_assert_held(&mvm->mutex);
232 ctxt->color++;
233 210
234 if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) { 211 ctxt->channel = chandef->chan;
235 ieee80211_iter_chan_contexts_atomic( 212 ret = iwl_mvm_phy_ctxt_apply(mvm, ctxt, chandef,
236 mvm->hw, iwl_mvm_phy_ctx_used_iter, &data); 213 chains_static, chains_dynamic,
214 FW_CTXT_ACTION_ADD, 0);
237 215
238 ctxt->id = find_first_zero_bit(data.used, NUM_PHY_CTX); 216 return ret;
239 if (WARN_ONCE(ctxt->id == NUM_PHY_CTX, 217}
240 "Failed to init PHY context - no free ID!\n"))
241 return -EIO;
242 }
243 218
244 ctxt->channel = chandef->chan; 219/*
245 return iwl_mvm_phy_ctxt_apply(mvm, ctxt, chandef, 220 * Update the number of references to the given PHY context. This is valid only
246 chains_static, chains_dynamic, 221 * in case the PHY context was already created, i.e., its reference count > 0.
247 FW_CTXT_ACTION_ADD, 0); 222 */
223void iwl_mvm_phy_ctxt_ref(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt)
224{
225 lockdep_assert_held(&mvm->mutex);
226 ctxt->ref++;
248} 227}
249 228
250/* 229/*
@@ -264,23 +243,12 @@ int iwl_mvm_phy_ctxt_changed(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt,
264 FW_CTXT_ACTION_MODIFY, 0); 243 FW_CTXT_ACTION_MODIFY, 0);
265} 244}
266 245
267/* 246void iwl_mvm_phy_ctxt_unref(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt)
268 * Send a command to the FW to remove the given phy context.
269 * Once the command is sent, regardless of success or failure, the context is
270 * marked as invalid
271 */
272void iwl_mvm_phy_ctxt_remove(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt)
273{ 247{
274 struct iwl_phy_context_cmd cmd;
275 int ret;
276
277 lockdep_assert_held(&mvm->mutex); 248 lockdep_assert_held(&mvm->mutex);
278 249
279 iwl_mvm_phy_ctxt_cmd_hdr(ctxt, &cmd, FW_CTXT_ACTION_REMOVE, 0); 250 if (WARN_ON_ONCE(!ctxt))
280 ret = iwl_mvm_send_cmd_pdu(mvm, PHY_CONTEXT_CMD, CMD_SYNC, 251 return;
281 sizeof(struct iwl_phy_context_cmd), 252
282 &cmd); 253 ctxt->ref--;
283 if (ret)
284 IWL_ERR(mvm, "Failed to send PHY remove: ctxt id=%d\n",
285 ctxt->id);
286} 254}
diff --git a/drivers/net/wireless/iwlwifi/mvm/power.c b/drivers/net/wireless/iwlwifi/mvm/power.c
index ed77e437aac4..3760a33ca3a4 100644
--- a/drivers/net/wireless/iwlwifi/mvm/power.c
+++ b/drivers/net/wireless/iwlwifi/mvm/power.c
@@ -75,6 +75,54 @@
75 75
76#define POWER_KEEP_ALIVE_PERIOD_SEC 25 76#define POWER_KEEP_ALIVE_PERIOD_SEC 25
77 77
78static int iwl_mvm_beacon_filter_send_cmd(struct iwl_mvm *mvm,
79 struct iwl_beacon_filter_cmd *cmd)
80{
81 int ret;
82
83 ret = iwl_mvm_send_cmd_pdu(mvm, REPLY_BEACON_FILTERING_CMD, CMD_SYNC,
84 sizeof(struct iwl_beacon_filter_cmd), cmd);
85
86 if (!ret) {
87 IWL_DEBUG_POWER(mvm, "ba_enable_beacon_abort is: %d\n",
88 cmd->ba_enable_beacon_abort);
89 IWL_DEBUG_POWER(mvm, "ba_escape_timer is: %d\n",
90 cmd->ba_escape_timer);
91 IWL_DEBUG_POWER(mvm, "bf_debug_flag is: %d\n",
92 cmd->bf_debug_flag);
93 IWL_DEBUG_POWER(mvm, "bf_enable_beacon_filter is: %d\n",
94 cmd->bf_enable_beacon_filter);
95 IWL_DEBUG_POWER(mvm, "bf_energy_delta is: %d\n",
96 cmd->bf_energy_delta);
97 IWL_DEBUG_POWER(mvm, "bf_escape_timer is: %d\n",
98 cmd->bf_escape_timer);
99 IWL_DEBUG_POWER(mvm, "bf_roaming_energy_delta is: %d\n",
100 cmd->bf_roaming_energy_delta);
101 IWL_DEBUG_POWER(mvm, "bf_roaming_state is: %d\n",
102 cmd->bf_roaming_state);
103 IWL_DEBUG_POWER(mvm, "bf_temperature_delta is: %d\n",
104 cmd->bf_temperature_delta);
105 }
106 return ret;
107}
108
109static int iwl_mvm_update_beacon_abort(struct iwl_mvm *mvm,
110 struct ieee80211_vif *vif, bool enable)
111{
112 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
113 struct iwl_beacon_filter_cmd cmd = {
114 IWL_BF_CMD_CONFIG_DEFAULTS,
115 .bf_enable_beacon_filter = 1,
116 .ba_enable_beacon_abort = enable,
117 };
118
119 if (!mvmvif->bf_enabled)
120 return 0;
121
122 iwl_mvm_beacon_filter_debugfs_parameters(vif, &cmd);
123 return iwl_mvm_beacon_filter_send_cmd(mvm, &cmd);
124}
125
78static void iwl_mvm_power_log(struct iwl_mvm *mvm, 126static void iwl_mvm_power_log(struct iwl_mvm *mvm,
79 struct iwl_powertable_cmd *cmd) 127 struct iwl_powertable_cmd *cmd)
80{ 128{
@@ -91,6 +139,9 @@ static void iwl_mvm_power_log(struct iwl_mvm *mvm,
91 le32_to_cpu(cmd->tx_data_timeout)); 139 le32_to_cpu(cmd->tx_data_timeout));
92 IWL_DEBUG_POWER(mvm, "LP RX RSSI threshold = %u\n", 140 IWL_DEBUG_POWER(mvm, "LP RX RSSI threshold = %u\n",
93 cmd->lprx_rssi_threshold); 141 cmd->lprx_rssi_threshold);
142 if (cmd->flags & cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK))
143 IWL_DEBUG_POWER(mvm, "DTIM periods to skip = %u\n",
144 le32_to_cpu(cmd->skip_dtim_periods));
94 } 145 }
95} 146}
96 147
@@ -103,6 +154,8 @@ void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
103 int dtimper, dtimper_msec; 154 int dtimper, dtimper_msec;
104 int keep_alive; 155 int keep_alive;
105 bool radar_detect = false; 156 bool radar_detect = false;
157 struct iwl_mvm_vif *mvmvif __maybe_unused =
158 iwl_mvm_vif_from_mac80211(vif);
106 159
107 /* 160 /*
108 * Regardless of power management state the driver must set 161 * Regardless of power management state the driver must set
@@ -115,7 +168,14 @@ void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
115 return; 168 return;
116 169
117 cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK); 170 cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK);
171 if (!vif->bss_conf.assoc)
172 cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK);
118 173
174#ifdef CONFIG_IWLWIFI_DEBUGFS
175 if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_DISABLE_POWER_OFF &&
176 mvmvif->dbgfs_pm.disable_power_off)
177 cmd->flags &= cpu_to_le16(~POWER_FLAGS_POWER_SAVE_ENA_MSK);
178#endif
119 if (!vif->bss_conf.ps) 179 if (!vif->bss_conf.ps)
120 return; 180 return;
121 181
@@ -135,8 +195,11 @@ void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
135 195
136 /* Check skip over DTIM conditions */ 196 /* Check skip over DTIM conditions */
137 if (!radar_detect && (dtimper <= 10) && 197 if (!radar_detect && (dtimper <= 10) &&
138 (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_LP)) 198 (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_LP ||
199 mvm->cur_ucode == IWL_UCODE_WOWLAN)) {
139 cmd->flags |= cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK); 200 cmd->flags |= cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK);
201 cmd->skip_dtim_periods = cpu_to_le32(3);
202 }
140 203
141 /* Check that keep alive period is at least 3 * DTIM */ 204 /* Check that keep alive period is at least 3 * DTIM */
142 dtimper_msec = dtimper * vif->bss_conf.beacon_int; 205 dtimper_msec = dtimper * vif->bss_conf.beacon_int;
@@ -145,27 +208,76 @@ void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
145 keep_alive = DIV_ROUND_UP(keep_alive, MSEC_PER_SEC); 208 keep_alive = DIV_ROUND_UP(keep_alive, MSEC_PER_SEC);
146 cmd->keep_alive_seconds = keep_alive; 209 cmd->keep_alive_seconds = keep_alive;
147 210
148 cmd->rx_data_timeout = cpu_to_le32(100 * USEC_PER_MSEC); 211 if (mvm->cur_ucode != IWL_UCODE_WOWLAN) {
149 cmd->tx_data_timeout = cpu_to_le32(100 * USEC_PER_MSEC); 212 cmd->rx_data_timeout = cpu_to_le32(100 * USEC_PER_MSEC);
213 cmd->tx_data_timeout = cpu_to_le32(100 * USEC_PER_MSEC);
214 } else {
215 cmd->rx_data_timeout = cpu_to_le32(10 * USEC_PER_MSEC);
216 cmd->tx_data_timeout = cpu_to_le32(10 * USEC_PER_MSEC);
217 }
218
219#ifdef CONFIG_IWLWIFI_DEBUGFS
220 if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_KEEP_ALIVE)
221 cmd->keep_alive_seconds = mvmvif->dbgfs_pm.keep_alive_seconds;
222 if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_SKIP_OVER_DTIM) {
223 if (mvmvif->dbgfs_pm.skip_over_dtim)
224 cmd->flags |=
225 cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK);
226 else
227 cmd->flags &=
228 cpu_to_le16(~POWER_FLAGS_SKIP_OVER_DTIM_MSK);
229 }
230 if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_RX_DATA_TIMEOUT)
231 cmd->rx_data_timeout =
232 cpu_to_le32(mvmvif->dbgfs_pm.rx_data_timeout);
233 if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_TX_DATA_TIMEOUT)
234 cmd->tx_data_timeout =
235 cpu_to_le32(mvmvif->dbgfs_pm.tx_data_timeout);
236 if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_SKIP_DTIM_PERIODS)
237 cmd->skip_dtim_periods =
238 cpu_to_le32(mvmvif->dbgfs_pm.skip_dtim_periods);
239#endif /* CONFIG_IWLWIFI_DEBUGFS */
150} 240}
151 241
152int iwl_mvm_power_update_mode(struct iwl_mvm *mvm, struct ieee80211_vif *vif) 242int iwl_mvm_power_update_mode(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
153{ 243{
244 int ret;
245 bool ba_enable;
154 struct iwl_powertable_cmd cmd = {}; 246 struct iwl_powertable_cmd cmd = {};
155 247
156 if (vif->type != NL80211_IFTYPE_STATION || vif->p2p) 248 if (vif->type != NL80211_IFTYPE_STATION || vif->p2p)
157 return 0; 249 return 0;
158 250
251 /*
252 * TODO: The following vif_count verification is temporary condition.
253 * Avoid power mode update if more than one interface is currently
254 * active. Remove this condition when FW will support power management
255 * on multiple MACs.
256 */
257 IWL_DEBUG_POWER(mvm, "Currently %d interfaces active\n",
258 mvm->vif_count);
259 if (mvm->vif_count > 1)
260 return 0;
261
159 iwl_mvm_power_build_cmd(mvm, vif, &cmd); 262 iwl_mvm_power_build_cmd(mvm, vif, &cmd);
160 iwl_mvm_power_log(mvm, &cmd); 263 iwl_mvm_power_log(mvm, &cmd);
161 264
162 return iwl_mvm_send_cmd_pdu(mvm, POWER_TABLE_CMD, CMD_SYNC, 265 ret = iwl_mvm_send_cmd_pdu(mvm, POWER_TABLE_CMD, CMD_SYNC,
163 sizeof(cmd), &cmd); 266 sizeof(cmd), &cmd);
267 if (ret)
268 return ret;
269
270 ba_enable = !!(cmd.flags &
271 cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK));
272
273 return iwl_mvm_update_beacon_abort(mvm, vif, ba_enable);
164} 274}
165 275
166int iwl_mvm_power_disable(struct iwl_mvm *mvm, struct ieee80211_vif *vif) 276int iwl_mvm_power_disable(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
167{ 277{
168 struct iwl_powertable_cmd cmd = {}; 278 struct iwl_powertable_cmd cmd = {};
279 struct iwl_mvm_vif *mvmvif __maybe_unused =
280 iwl_mvm_vif_from_mac80211(vif);
169 281
170 if (vif->type != NL80211_IFTYPE_STATION || vif->p2p) 282 if (vif->type != NL80211_IFTYPE_STATION || vif->p2p)
171 return 0; 283 return 0;
@@ -173,8 +285,82 @@ int iwl_mvm_power_disable(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
173 if (iwlmvm_mod_params.power_scheme != IWL_POWER_SCHEME_CAM) 285 if (iwlmvm_mod_params.power_scheme != IWL_POWER_SCHEME_CAM)
174 cmd.flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK); 286 cmd.flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK);
175 287
288#ifdef CONFIG_IWLWIFI_DEBUGFS
289 if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_DISABLE_POWER_OFF &&
290 mvmvif->dbgfs_pm.disable_power_off)
291 cmd.flags &= cpu_to_le16(~POWER_FLAGS_POWER_SAVE_ENA_MSK);
292#endif
176 iwl_mvm_power_log(mvm, &cmd); 293 iwl_mvm_power_log(mvm, &cmd);
177 294
178 return iwl_mvm_send_cmd_pdu(mvm, POWER_TABLE_CMD, CMD_ASYNC, 295 return iwl_mvm_send_cmd_pdu(mvm, POWER_TABLE_CMD, CMD_ASYNC,
179 sizeof(cmd), &cmd); 296 sizeof(cmd), &cmd);
180} 297}
298
299#ifdef CONFIG_IWLWIFI_DEBUGFS
300void
301iwl_mvm_beacon_filter_debugfs_parameters(struct ieee80211_vif *vif,
302 struct iwl_beacon_filter_cmd *cmd)
303{
304 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
305 struct iwl_dbgfs_bf *dbgfs_bf = &mvmvif->dbgfs_bf;
306
307 if (dbgfs_bf->mask & MVM_DEBUGFS_BF_ENERGY_DELTA)
308 cmd->bf_energy_delta = dbgfs_bf->bf_energy_delta;
309 if (dbgfs_bf->mask & MVM_DEBUGFS_BF_ROAMING_ENERGY_DELTA)
310 cmd->bf_roaming_energy_delta =
311 dbgfs_bf->bf_roaming_energy_delta;
312 if (dbgfs_bf->mask & MVM_DEBUGFS_BF_ROAMING_STATE)
313 cmd->bf_roaming_state = dbgfs_bf->bf_roaming_state;
314 if (dbgfs_bf->mask & MVM_DEBUGFS_BF_TEMPERATURE_DELTA)
315 cmd->bf_temperature_delta = dbgfs_bf->bf_temperature_delta;
316 if (dbgfs_bf->mask & MVM_DEBUGFS_BF_DEBUG_FLAG)
317 cmd->bf_debug_flag = dbgfs_bf->bf_debug_flag;
318 if (dbgfs_bf->mask & MVM_DEBUGFS_BF_ESCAPE_TIMER)
319 cmd->bf_escape_timer = cpu_to_le32(dbgfs_bf->bf_escape_timer);
320 if (dbgfs_bf->mask & MVM_DEBUGFS_BA_ESCAPE_TIMER)
321 cmd->ba_escape_timer = cpu_to_le32(dbgfs_bf->ba_escape_timer);
322 if (dbgfs_bf->mask & MVM_DEBUGFS_BA_ENABLE_BEACON_ABORT)
323 cmd->ba_enable_beacon_abort = dbgfs_bf->ba_enable_beacon_abort;
324}
325#endif
326
327int iwl_mvm_enable_beacon_filter(struct iwl_mvm *mvm,
328 struct ieee80211_vif *vif)
329{
330 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
331 struct iwl_beacon_filter_cmd cmd = {
332 IWL_BF_CMD_CONFIG_DEFAULTS,
333 .bf_enable_beacon_filter = 1,
334 };
335 int ret;
336
337 if (mvmvif != mvm->bf_allowed_vif ||
338 vif->type != NL80211_IFTYPE_STATION || vif->p2p)
339 return 0;
340
341 iwl_mvm_beacon_filter_debugfs_parameters(vif, &cmd);
342 ret = iwl_mvm_beacon_filter_send_cmd(mvm, &cmd);
343
344 if (!ret)
345 mvmvif->bf_enabled = true;
346
347 return ret;
348}
349
350int iwl_mvm_disable_beacon_filter(struct iwl_mvm *mvm,
351 struct ieee80211_vif *vif)
352{
353 struct iwl_beacon_filter_cmd cmd = {};
354 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
355 int ret;
356
357 if (vif->type != NL80211_IFTYPE_STATION || vif->p2p)
358 return 0;
359
360 ret = iwl_mvm_beacon_filter_send_cmd(mvm, &cmd);
361
362 if (!ret)
363 mvmvif->bf_enabled = false;
364
365 return ret;
366}
diff --git a/drivers/net/wireless/iwlwifi/mvm/quota.c b/drivers/net/wireless/iwlwifi/mvm/quota.c
index a1e3e923ea3e..29d49cf0fdb2 100644
--- a/drivers/net/wireless/iwlwifi/mvm/quota.c
+++ b/drivers/net/wireless/iwlwifi/mvm/quota.c
@@ -169,27 +169,34 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm, struct ieee80211_vif *newvif)
169 num_active_bindings++; 169 num_active_bindings++;
170 } 170 }
171 171
172 if (!num_active_bindings) 172 quota = 0;
173 goto send_cmd; 173 quota_rem = 0;
174 174 if (num_active_bindings) {
175 quota = IWL_MVM_MAX_QUOTA / num_active_bindings; 175 quota = IWL_MVM_MAX_QUOTA / num_active_bindings;
176 quota_rem = IWL_MVM_MAX_QUOTA % num_active_bindings; 176 quota_rem = IWL_MVM_MAX_QUOTA % num_active_bindings;
177 }
177 178
178 for (idx = 0, i = 0; i < MAX_BINDINGS; i++) { 179 for (idx = 0, i = 0; i < MAX_BINDINGS; i++) {
179 if (data.n_interfaces[i] <= 0) 180 if (data.colors[i] < 0)
180 continue; 181 continue;
181 182
182 cmd.quotas[idx].id_and_color = 183 cmd.quotas[idx].id_and_color =
183 cpu_to_le32(FW_CMD_ID_AND_COLOR(i, data.colors[i])); 184 cpu_to_le32(FW_CMD_ID_AND_COLOR(i, data.colors[i]));
184 cmd.quotas[idx].quota = cpu_to_le32(quota); 185
185 cmd.quotas[idx].max_duration = cpu_to_le32(IWL_MVM_MAX_QUOTA); 186 if (data.n_interfaces[i] <= 0) {
187 cmd.quotas[idx].quota = cpu_to_le32(0);
188 cmd.quotas[idx].max_duration = cpu_to_le32(0);
189 } else {
190 cmd.quotas[idx].quota = cpu_to_le32(quota);
191 cmd.quotas[idx].max_duration =
192 cpu_to_le32(IWL_MVM_MAX_QUOTA);
193 }
186 idx++; 194 idx++;
187 } 195 }
188 196
189 /* Give the remainder of the session to the first binding */ 197 /* Give the remainder of the session to the first binding */
190 le32_add_cpu(&cmd.quotas[0].quota, quota_rem); 198 le32_add_cpu(&cmd.quotas[0].quota, quota_rem);
191 199
192send_cmd:
193 ret = iwl_mvm_send_cmd_pdu(mvm, TIME_QUOTA_CMD, CMD_SYNC, 200 ret = iwl_mvm_send_cmd_pdu(mvm, TIME_QUOTA_CMD, CMD_SYNC,
194 sizeof(cmd), &cmd); 201 sizeof(cmd), &cmd);
195 if (ret) 202 if (ret)
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c
index 55334d542e26..d6beec765d65 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/rs.c
@@ -401,6 +401,17 @@ static int rs_tl_turn_on_agg_for_tid(struct iwl_mvm *mvm,
401 401
402 load = rs_tl_get_load(lq_data, tid); 402 load = rs_tl_get_load(lq_data, tid);
403 403
404 /*
405 * Don't create TX aggregation sessions when in high
406 * BT traffic, as they would just be disrupted by BT.
407 */
408 if (BT_MBOX_MSG(&mvm->last_bt_notif, 3, TRAFFIC_LOAD) >= 2) {
409 IWL_DEBUG_COEX(mvm, "BT traffic (%d), no aggregation allowed\n",
410 BT_MBOX_MSG(&mvm->last_bt_notif,
411 3, TRAFFIC_LOAD));
412 return ret;
413 }
414
404 if ((iwlwifi_mod_params.auto_agg) || (load > IWL_AGG_LOAD_THRESHOLD)) { 415 if ((iwlwifi_mod_params.auto_agg) || (load > IWL_AGG_LOAD_THRESHOLD)) {
405 IWL_DEBUG_HT(mvm, "Starting Tx agg: STA: %pM tid: %d\n", 416 IWL_DEBUG_HT(mvm, "Starting Tx agg: STA: %pM tid: %d\n",
406 sta->addr, tid); 417 sta->addr, tid);
@@ -1519,6 +1530,29 @@ static int rs_move_siso_to_other(struct iwl_mvm *mvm,
1519 u8 update_search_tbl_counter = 0; 1530 u8 update_search_tbl_counter = 0;
1520 int ret; 1531 int ret;
1521 1532
1533 switch (BT_MBOX_MSG(&mvm->last_bt_notif, 3, TRAFFIC_LOAD)) {
1534 case IWL_BT_COEX_TRAFFIC_LOAD_NONE:
1535 /* nothing */
1536 break;
1537 case IWL_BT_COEX_TRAFFIC_LOAD_LOW:
1538 /* avoid antenna B unless MIMO */
1539 if (tbl->action == IWL_SISO_SWITCH_ANTENNA2)
1540 tbl->action = IWL_SISO_SWITCH_MIMO2_AB;
1541 break;
1542 case IWL_BT_COEX_TRAFFIC_LOAD_HIGH:
1543 case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS:
1544 /* avoid antenna B and MIMO */
1545 valid_tx_ant =
1546 first_antenna(iwl_fw_valid_tx_ant(mvm->fw));
1547 if (tbl->action != IWL_SISO_SWITCH_ANTENNA1)
1548 tbl->action = IWL_SISO_SWITCH_ANTENNA1;
1549 break;
1550 default:
1551 IWL_ERR(mvm, "Invalid BT load %d",
1552 BT_MBOX_MSG(&mvm->last_bt_notif, 3, TRAFFIC_LOAD));
1553 break;
1554 }
1555
1522 start_action = tbl->action; 1556 start_action = tbl->action;
1523 while (1) { 1557 while (1) {
1524 lq_sta->action_counter++; 1558 lq_sta->action_counter++;
@@ -1532,7 +1566,9 @@ static int rs_move_siso_to_other(struct iwl_mvm *mvm,
1532 tx_chains_num <= 2)) 1566 tx_chains_num <= 2))
1533 break; 1567 break;
1534 1568
1535 if (window->success_ratio >= IWL_RS_GOOD_RATIO) 1569 if (window->success_ratio >= IWL_RS_GOOD_RATIO &&
1570 BT_MBOX_MSG(&mvm->last_bt_notif, 3,
1571 TRAFFIC_LOAD) == 0)
1536 break; 1572 break;
1537 1573
1538 memcpy(search_tbl, tbl, sz); 1574 memcpy(search_tbl, tbl, sz);
@@ -1654,6 +1690,28 @@ static int rs_move_mimo2_to_other(struct iwl_mvm *mvm,
1654 u8 update_search_tbl_counter = 0; 1690 u8 update_search_tbl_counter = 0;
1655 int ret; 1691 int ret;
1656 1692
1693 switch (BT_MBOX_MSG(&mvm->last_bt_notif, 3, TRAFFIC_LOAD)) {
1694 case IWL_BT_COEX_TRAFFIC_LOAD_NONE:
1695 /* nothing */
1696 break;
1697 case IWL_BT_COEX_TRAFFIC_LOAD_HIGH:
1698 case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS:
1699 /* avoid antenna B and MIMO */
1700 if (tbl->action != IWL_MIMO2_SWITCH_SISO_A)
1701 tbl->action = IWL_MIMO2_SWITCH_SISO_A;
1702 break;
1703 case IWL_BT_COEX_TRAFFIC_LOAD_LOW:
1704 /* avoid antenna B unless MIMO */
1705 if (tbl->action == IWL_MIMO2_SWITCH_SISO_B ||
1706 tbl->action == IWL_MIMO2_SWITCH_SISO_C)
1707 tbl->action = IWL_MIMO2_SWITCH_SISO_A;
1708 break;
1709 default:
1710 IWL_ERR(mvm, "Invalid BT load %d",
1711 BT_MBOX_MSG(&mvm->last_bt_notif, 3, TRAFFIC_LOAD));
1712 break;
1713 }
1714
1657 start_action = tbl->action; 1715 start_action = tbl->action;
1658 while (1) { 1716 while (1) {
1659 lq_sta->action_counter++; 1717 lq_sta->action_counter++;
@@ -1791,6 +1849,28 @@ static int rs_move_mimo3_to_other(struct iwl_mvm *mvm,
1791 int ret; 1849 int ret;
1792 u8 update_search_tbl_counter = 0; 1850 u8 update_search_tbl_counter = 0;
1793 1851
1852 switch (BT_MBOX_MSG(&mvm->last_bt_notif, 3, TRAFFIC_LOAD)) {
1853 case IWL_BT_COEX_TRAFFIC_LOAD_NONE:
1854 /* nothing */
1855 break;
1856 case IWL_BT_COEX_TRAFFIC_LOAD_HIGH:
1857 case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS:
1858 /* avoid antenna B and MIMO */
1859 if (tbl->action != IWL_MIMO3_SWITCH_SISO_A)
1860 tbl->action = IWL_MIMO3_SWITCH_SISO_A;
1861 break;
1862 case IWL_BT_COEX_TRAFFIC_LOAD_LOW:
1863 /* avoid antenna B unless MIMO */
1864 if (tbl->action == IWL_MIMO3_SWITCH_SISO_B ||
1865 tbl->action == IWL_MIMO3_SWITCH_SISO_C)
1866 tbl->action = IWL_MIMO3_SWITCH_SISO_A;
1867 break;
1868 default:
1869 IWL_ERR(mvm, "Invalid BT load %d",
1870 BT_MBOX_MSG(&mvm->last_bt_notif, 3, TRAFFIC_LOAD));
1871 break;
1872 }
1873
1794 start_action = tbl->action; 1874 start_action = tbl->action;
1795 while (1) { 1875 while (1) {
1796 lq_sta->action_counter++; 1876 lq_sta->action_counter++;
@@ -2302,6 +2382,32 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
2302 (current_tpt > (100 * tbl->expected_tpt[low])))) 2382 (current_tpt > (100 * tbl->expected_tpt[low]))))
2303 scale_action = 0; 2383 scale_action = 0;
2304 2384
2385 if ((BT_MBOX_MSG(&mvm->last_bt_notif, 3, TRAFFIC_LOAD) >=
2386 IWL_BT_COEX_TRAFFIC_LOAD_HIGH) &&
2387 (is_mimo2(tbl->lq_type) || is_mimo3(tbl->lq_type))) {
2388 if (lq_sta->last_bt_traffic >
2389 BT_MBOX_MSG(&mvm->last_bt_notif, 3, TRAFFIC_LOAD)) {
2390 /*
2391 * don't set scale_action, don't want to scale up if
2392 * the rate scale doesn't otherwise think that is a
2393 * good idea.
2394 */
2395 } else if (lq_sta->last_bt_traffic <=
2396 BT_MBOX_MSG(&mvm->last_bt_notif, 3, TRAFFIC_LOAD)) {
2397 scale_action = -1;
2398 }
2399 }
2400 lq_sta->last_bt_traffic =
2401 BT_MBOX_MSG(&mvm->last_bt_notif, 3, TRAFFIC_LOAD);
2402
2403 if ((BT_MBOX_MSG(&mvm->last_bt_notif, 3, TRAFFIC_LOAD) >=
2404 IWL_BT_COEX_TRAFFIC_LOAD_HIGH) &&
2405 (is_mimo2(tbl->lq_type) || is_mimo3(tbl->lq_type))) {
2406 /* search for a new modulation */
2407 rs_stay_in_table(lq_sta, true);
2408 goto lq_update;
2409 }
2410
2305 switch (scale_action) { 2411 switch (scale_action) {
2306 case -1: 2412 case -1:
2307 /* Decrease starting rate, update uCode's rate table */ 2413 /* Decrease starting rate, update uCode's rate table */
@@ -2782,6 +2888,13 @@ static void rs_fill_link_cmd(struct iwl_mvm *mvm,
2782 2888
2783 lq_cmd->agg_time_limit = 2889 lq_cmd->agg_time_limit =
2784 cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF); 2890 cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF);
2891
2892 /*
2893 * overwrite if needed, pass aggregation time limit
2894 * to uCode in uSec - This is racy - but heh, at least it helps...
2895 */
2896 if (mvm && BT_MBOX_MSG(&mvm->last_bt_notif, 3, TRAFFIC_LOAD) >= 2)
2897 lq_cmd->agg_time_limit = cpu_to_le16(1200);
2785} 2898}
2786 2899
2787static void *rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) 2900static void *rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
@@ -3080,3 +3193,29 @@ void iwl_mvm_rate_control_unregister(void)
3080{ 3193{
3081 ieee80211_rate_control_unregister(&rs_mvm_ops); 3194 ieee80211_rate_control_unregister(&rs_mvm_ops);
3082} 3195}
3196
3197/**
3198 * iwl_mvm_tx_protection - Gets LQ command, change it to enable/disable
3199 * Tx protection, according to this rquest and previous requests,
3200 * and send the LQ command.
3201 * @lq: The LQ command
3202 * @mvmsta: The station
3203 * @enable: Enable Tx protection?
3204 */
3205int iwl_mvm_tx_protection(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq,
3206 struct iwl_mvm_sta *mvmsta, bool enable)
3207{
3208 lockdep_assert_held(&mvm->mutex);
3209
3210 if (enable) {
3211 if (mvmsta->tx_protection == 0)
3212 lq->flags |= LQ_FLAG_SET_STA_TLC_RTS_MSK;
3213 mvmsta->tx_protection++;
3214 } else {
3215 mvmsta->tx_protection--;
3216 if (mvmsta->tx_protection == 0)
3217 lq->flags &= ~LQ_FLAG_SET_STA_TLC_RTS_MSK;
3218 }
3219
3220 return iwl_mvm_send_lq_cmd(mvm, lq, CMD_ASYNC, false);
3221}
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.h b/drivers/net/wireless/iwlwifi/mvm/rs.h
index 219c6857cc0f..cff4f6da7733 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rs.h
+++ b/drivers/net/wireless/iwlwifi/mvm/rs.h
@@ -358,6 +358,18 @@ struct iwl_lq_sta {
358 u8 last_bt_traffic; 358 u8 last_bt_traffic;
359}; 359};
360 360
361enum iwl_bt_coex_profile_traffic_load {
362 IWL_BT_COEX_TRAFFIC_LOAD_NONE = 0,
363 IWL_BT_COEX_TRAFFIC_LOAD_LOW = 1,
364 IWL_BT_COEX_TRAFFIC_LOAD_HIGH = 2,
365 IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS = 3,
366/*
367 * There are no more even though below is a u8, the
368 * indication from the BT device only has two bits.
369 */
370};
371
372
361static inline u8 num_of_ant(u8 mask) 373static inline u8 num_of_ant(u8 mask)
362{ 374{
363 return !!((mask) & ANT_A) + 375 return !!((mask) & ANT_A) +
@@ -390,4 +402,9 @@ extern int iwl_mvm_rate_control_register(void);
390 */ 402 */
391extern void iwl_mvm_rate_control_unregister(void); 403extern void iwl_mvm_rate_control_unregister(void);
392 404
405struct iwl_mvm_sta;
406
407int iwl_mvm_tx_protection(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq,
408 struct iwl_mvm_sta *mvmsta, bool enable);
409
393#endif /* __rs__ */ 410#endif /* __rs__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/rx.c b/drivers/net/wireless/iwlwifi/mvm/rx.c
index 4dfc21a3e83e..e4930d5027d2 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rx.c
+++ b/drivers/net/wireless/iwlwifi/mvm/rx.c
@@ -363,3 +363,25 @@ int iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
363 rxb, &rx_status); 363 rxb, &rx_status);
364 return 0; 364 return 0;
365} 365}
366
367/*
368 * iwl_mvm_rx_statistics - STATISTICS_NOTIFICATION handler
369 *
370 * TODO: This handler is implemented partially.
371 * It only gets the NIC's temperature.
372 */
373int iwl_mvm_rx_statistics(struct iwl_mvm *mvm,
374 struct iwl_rx_cmd_buffer *rxb,
375 struct iwl_device_cmd *cmd)
376{
377 struct iwl_rx_packet *pkt = rxb_addr(rxb);
378 struct iwl_notif_statistics *stats = (void *)&pkt->data;
379 struct mvm_statistics_general_common *common = &stats->general.common;
380
381 if (mvm->temperature != le32_to_cpu(common->temperature)) {
382 mvm->temperature = le32_to_cpu(common->temperature);
383 iwl_mvm_tt_handler(mvm);
384 }
385
386 return 0;
387}
diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c
index 2476e43799d5..2157b0f8ced5 100644
--- a/drivers/net/wireless/iwlwifi/mvm/scan.c
+++ b/drivers/net/wireless/iwlwifi/mvm/scan.c
@@ -298,12 +298,6 @@ int iwl_mvm_scan_request(struct iwl_mvm *mvm,
298 else 298 else
299 cmd->type = cpu_to_le32(SCAN_TYPE_FORCED); 299 cmd->type = cpu_to_le32(SCAN_TYPE_FORCED);
300 300
301 /*
302 * TODO: This is a WA due to a bug in the FW AUX framework that does not
303 * properly handle time events that fail to be scheduled
304 */
305 cmd->type = cpu_to_le32(SCAN_TYPE_FORCED);
306
307 cmd->repeats = cpu_to_le32(1); 301 cmd->repeats = cpu_to_le32(1);
308 302
309 /* 303 /*
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c
index 5c664ed54400..2278858d5658 100644
--- a/drivers/net/wireless/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/iwlwifi/mvm/sta.c
@@ -64,6 +64,7 @@
64 64
65#include "mvm.h" 65#include "mvm.h"
66#include "sta.h" 66#include "sta.h"
67#include "rs.h"
67 68
68static int iwl_mvm_find_free_sta_id(struct iwl_mvm *mvm) 69static int iwl_mvm_find_free_sta_id(struct iwl_mvm *mvm)
69{ 70{
@@ -217,6 +218,8 @@ int iwl_mvm_add_sta(struct iwl_mvm *mvm,
217 mvmvif->color); 218 mvmvif->color);
218 mvm_sta->vif = vif; 219 mvm_sta->vif = vif;
219 mvm_sta->max_agg_bufsize = LINK_QUAL_AGG_FRAME_LIMIT_DEF; 220 mvm_sta->max_agg_bufsize = LINK_QUAL_AGG_FRAME_LIMIT_DEF;
221 mvm_sta->tx_protection = 0;
222 mvm_sta->tt_tx_protection = false;
220 223
221 /* HW restart, don't assume the memory has been zeroed */ 224 /* HW restart, don't assume the memory has been zeroed */
222 atomic_set(&mvm->pending_frames[sta_id], 0); 225 atomic_set(&mvm->pending_frames[sta_id], 0);
@@ -798,21 +801,23 @@ int iwl_mvm_sta_tx_agg_oper(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
798 min(mvmsta->max_agg_bufsize, buf_size); 801 min(mvmsta->max_agg_bufsize, buf_size);
799 mvmsta->lq_sta.lq.agg_frame_cnt_limit = mvmsta->max_agg_bufsize; 802 mvmsta->lq_sta.lq.agg_frame_cnt_limit = mvmsta->max_agg_bufsize;
800 803
804 IWL_DEBUG_HT(mvm, "Tx aggregation enabled on ra = %pM tid = %d\n",
805 sta->addr, tid);
806
801 if (mvm->cfg->ht_params->use_rts_for_aggregation) { 807 if (mvm->cfg->ht_params->use_rts_for_aggregation) {
802 /* 808 /*
803 * switch to RTS/CTS if it is the prefer protection 809 * switch to RTS/CTS if it is the prefer protection
804 * method for HT traffic 810 * method for HT traffic
811 * this function also sends the LQ command
805 */ 812 */
806 mvmsta->lq_sta.lq.flags |= LQ_FLAG_SET_STA_TLC_RTS_MSK; 813 return iwl_mvm_tx_protection(mvm, &mvmsta->lq_sta.lq,
814 mvmsta, true);
807 /* 815 /*
808 * TODO: remove the TLC_RTS flag when we tear down the last 816 * TODO: remove the TLC_RTS flag when we tear down the last
809 * AGG session (agg_tids_count in DVM) 817 * AGG session (agg_tids_count in DVM)
810 */ 818 */
811 } 819 }
812 820
813 IWL_DEBUG_HT(mvm, "Tx aggregation enabled on ra = %pM tid = %d\n",
814 sta->addr, tid);
815
816 return iwl_mvm_send_lq_cmd(mvm, &mvmsta->lq_sta.lq, CMD_ASYNC, false); 821 return iwl_mvm_send_lq_cmd(mvm, &mvmsta->lq_sta.lq, CMD_ASYNC, false);
817} 822}
818 823
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.h b/drivers/net/wireless/iwlwifi/mvm/sta.h
index a4ddce77aaae..3efa0a0cc987 100644
--- a/drivers/net/wireless/iwlwifi/mvm/sta.h
+++ b/drivers/net/wireless/iwlwifi/mvm/sta.h
@@ -275,6 +275,8 @@ struct iwl_mvm_tid_data {
275 * @lock: lock to protect the whole struct. Since %tid_data is access from Tx 275 * @lock: lock to protect the whole struct. Since %tid_data is access from Tx
276 * and from Tx response flow, it needs a spinlock. 276 * and from Tx response flow, it needs a spinlock.
277 * @tid_data: per tid data. Look at %iwl_mvm_tid_data. 277 * @tid_data: per tid data. Look at %iwl_mvm_tid_data.
278 * @tx_protection: reference counter for controlling the Tx protection.
279 * @tt_tx_protection: is thermal throttling enable Tx protection?
278 * 280 *
279 * When mac80211 creates a station it reserves some space (hw->sta_data_size) 281 * When mac80211 creates a station it reserves some space (hw->sta_data_size)
280 * in the structure for use by driver. This structure is placed in that 282 * in the structure for use by driver. This structure is placed in that
@@ -296,6 +298,10 @@ struct iwl_mvm_sta {
296#ifdef CONFIG_PM_SLEEP 298#ifdef CONFIG_PM_SLEEP
297 u16 last_seq_ctl; 299 u16 last_seq_ctl;
298#endif 300#endif
301
302 /* Temporary, until the new TLC will control the Tx protection */
303 s8 tx_protection;
304 bool tt_tx_protection;
299}; 305};
300 306
301/** 307/**
diff --git a/drivers/net/wireless/iwlwifi/mvm/tt.c b/drivers/net/wireless/iwlwifi/mvm/tt.c
new file mode 100644
index 000000000000..a7e3b8ddf22b
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/tt.c
@@ -0,0 +1,512 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2013 Intel Corporation. All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called COPYING.
26 *
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *
62 *****************************************************************************/
63
64#include "mvm.h"
65#include "iwl-config.h"
66#include "iwl-io.h"
67#include "iwl-csr.h"
68#include "iwl-prph.h"
69
70#define OTP_DTS_DIODE_DEVIATION 96 /*in words*/
71/* VBG - Voltage Band Gap error data (temperature offset) */
72#define OTP_WP_DTS_VBG (OTP_DTS_DIODE_DEVIATION + 2)
73#define MEAS_VBG_MIN_VAL 2300
74#define MEAS_VBG_MAX_VAL 3000
75#define MEAS_VBG_DEFAULT_VAL 2700
76#define DTS_DIODE_VALID(flags) (flags & DTS_DIODE_REG_FLAGS_PASS_ONCE)
77#define MIN_TEMPERATURE 0
78#define MAX_TEMPERATURE 125
79#define TEMPERATURE_ERROR (MAX_TEMPERATURE + 1)
80#define PTAT_DIGITAL_VALUE_MIN_VALUE 0
81#define PTAT_DIGITAL_VALUE_MAX_VALUE 0xFF
82#define DTS_VREFS_NUM 5
83static inline u32 DTS_DIODE_GET_VREFS_ID(u32 flags)
84{
85 return (flags & DTS_DIODE_REG_FLAGS_VREFS_ID) >>
86 DTS_DIODE_REG_FLAGS_VREFS_ID_POS;
87}
88
89#define CALC_VREFS_MIN_DIFF 43
90#define CALC_VREFS_MAX_DIFF 51
91#define CALC_LUT_SIZE (1 + CALC_VREFS_MAX_DIFF - CALC_VREFS_MIN_DIFF)
92#define CALC_LUT_INDEX_OFFSET CALC_VREFS_MIN_DIFF
93#define CALC_TEMPERATURE_RESULT_SHIFT_OFFSET 23
94
95/*
96 * @digital_value: The diode's digital-value sampled (temperature/voltage)
97 * @vref_low: The lower voltage-reference (the vref just below the diode's
98 * sampled digital-value)
99 * @vref_high: The higher voltage-reference (the vref just above the diode's
100 * sampled digital-value)
101 * @flags: bits[1:0]: The ID of the Vrefs pair (lowVref,highVref)
102 * bits[6:2]: Reserved.
103 * bits[7:7]: Indicates completion of at least 1 successful sample
104 * since last DTS reset.
105 */
106struct iwl_mvm_dts_diode_bits {
107 u8 digital_value;
108 u8 vref_low;
109 u8 vref_high;
110 u8 flags;
111} __packed;
112
113union dts_diode_results {
114 u32 reg_value;
115 struct iwl_mvm_dts_diode_bits bits;
116} __packed;
117
118static s16 iwl_mvm_dts_get_volt_band_gap(struct iwl_mvm *mvm)
119{
120 struct iwl_nvm_section calib_sec;
121 const __le16 *calib;
122 u16 vbg;
123
124 /* TODO: move parsing to NVM code */
125 calib_sec = mvm->nvm_sections[NVM_SECTION_TYPE_CALIBRATION];
126 calib = (__le16 *)calib_sec.data;
127
128 vbg = le16_to_cpu(calib[OTP_WP_DTS_VBG]);
129
130 if (vbg < MEAS_VBG_MIN_VAL || vbg > MEAS_VBG_MAX_VAL)
131 vbg = MEAS_VBG_DEFAULT_VAL;
132
133 return vbg;
134}
135
136static u16 iwl_mvm_dts_get_ptat_deviation_offset(struct iwl_mvm *mvm)
137{
138 const u8 *calib;
139 u8 ptat, pa1, pa2, median;
140
141 /* TODO: move parsing to NVM code */
142 calib = mvm->nvm_sections[NVM_SECTION_TYPE_CALIBRATION].data;
143 ptat = calib[OTP_DTS_DIODE_DEVIATION];
144 pa1 = calib[OTP_DTS_DIODE_DEVIATION + 1];
145 pa2 = calib[OTP_DTS_DIODE_DEVIATION + 2];
146
147 /* get the median: */
148 if (ptat > pa1) {
149 if (ptat > pa2)
150 median = (pa1 > pa2) ? pa1 : pa2;
151 else
152 median = ptat;
153 } else {
154 if (pa1 > pa2)
155 median = (ptat > pa2) ? ptat : pa2;
156 else
157 median = pa1;
158 }
159
160 return ptat - median;
161}
162
163static u8 iwl_mvm_dts_calibrate_ptat_deviation(struct iwl_mvm *mvm, u8 value)
164{
165 /* Calibrate the PTAT digital value, based on PTAT deviation data: */
166 s16 new_val = value - iwl_mvm_dts_get_ptat_deviation_offset(mvm);
167
168 if (new_val > PTAT_DIGITAL_VALUE_MAX_VALUE)
169 new_val = PTAT_DIGITAL_VALUE_MAX_VALUE;
170 else if (new_val < PTAT_DIGITAL_VALUE_MIN_VALUE)
171 new_val = PTAT_DIGITAL_VALUE_MIN_VALUE;
172
173 return new_val;
174}
175
176static bool dts_get_adjacent_vrefs(struct iwl_mvm *mvm,
177 union dts_diode_results *avg_ptat)
178{
179 u8 vrefs_results[DTS_VREFS_NUM];
180 u8 low_vref_index = 0, flags;
181 u32 reg;
182
183 reg = iwl_read_prph(mvm->trans, DTSC_VREF_AVG);
184 memcpy(vrefs_results, &reg, sizeof(reg));
185 reg = iwl_read_prph(mvm->trans, DTSC_VREF5_AVG);
186 vrefs_results[4] = reg & 0xff;
187
188 if (avg_ptat->bits.digital_value < vrefs_results[0] ||
189 avg_ptat->bits.digital_value > vrefs_results[4])
190 return false;
191
192 if (avg_ptat->bits.digital_value > vrefs_results[3])
193 low_vref_index = 3;
194 else if (avg_ptat->bits.digital_value > vrefs_results[2])
195 low_vref_index = 2;
196 else if (avg_ptat->bits.digital_value > vrefs_results[1])
197 low_vref_index = 1;
198
199 avg_ptat->bits.vref_low = vrefs_results[low_vref_index];
200 avg_ptat->bits.vref_high = vrefs_results[low_vref_index + 1];
201 flags = avg_ptat->bits.flags;
202 avg_ptat->bits.flags =
203 (flags & ~DTS_DIODE_REG_FLAGS_VREFS_ID) |
204 (low_vref_index & DTS_DIODE_REG_FLAGS_VREFS_ID);
205 return true;
206}
207
208/*
209 * return true it the results are valid, and false otherwise.
210 */
211static bool dts_read_ptat_avg_results(struct iwl_mvm *mvm,
212 union dts_diode_results *avg_ptat)
213{
214 u32 reg;
215 u8 tmp;
216
217 /* fill the diode value and pass_once with avg-reg results */
218 reg = iwl_read_prph(mvm->trans, DTSC_PTAT_AVG);
219 reg &= DTS_DIODE_REG_DIG_VAL | DTS_DIODE_REG_PASS_ONCE;
220 avg_ptat->reg_value = reg;
221
222 /* calibrate the PTAT digital value */
223 tmp = avg_ptat->bits.digital_value;
224 tmp = iwl_mvm_dts_calibrate_ptat_deviation(mvm, tmp);
225 avg_ptat->bits.digital_value = tmp;
226
227 /*
228 * fill vrefs fields, based on the avgVrefs results
229 * and the diode value
230 */
231 return dts_get_adjacent_vrefs(mvm, avg_ptat) &&
232 DTS_DIODE_VALID(avg_ptat->bits.flags);
233}
234
235static s32 calculate_nic_temperature(union dts_diode_results avg_ptat,
236 u16 volt_band_gap)
237{
238 u32 tmp_result;
239 u8 vrefs_diff;
240 /*
241 * For temperature calculation (at the end, shift right by 23)
242 * LUT[(D2-D1)] = ROUND{ 2^23 / ((D2-D1)*9*10) }
243 * (D2-D1) == 43 44 45 46 47 48 49 50 51
244 */
245 static const u16 calc_lut[CALC_LUT_SIZE] = {
246 2168, 2118, 2071, 2026, 1983, 1942, 1902, 1864, 1828,
247 };
248
249 /*
250 * The diff between the high and low voltage-references is assumed
251 * to be strictly be in range of [60,68]
252 */
253 vrefs_diff = avg_ptat.bits.vref_high - avg_ptat.bits.vref_low;
254
255 if (vrefs_diff < CALC_VREFS_MIN_DIFF ||
256 vrefs_diff > CALC_VREFS_MAX_DIFF)
257 return TEMPERATURE_ERROR;
258
259 /* calculate the result: */
260 tmp_result =
261 vrefs_diff * (DTS_DIODE_GET_VREFS_ID(avg_ptat.bits.flags) + 9);
262 tmp_result += avg_ptat.bits.digital_value;
263 tmp_result -= avg_ptat.bits.vref_high;
264
265 /* multiply by the LUT value (based on the diff) */
266 tmp_result *= calc_lut[vrefs_diff - CALC_LUT_INDEX_OFFSET];
267
268 /*
269 * Get the BandGap (the voltage refereces source) error data
270 * (temperature offset)
271 */
272 tmp_result *= volt_band_gap;
273
274 /*
275 * here, tmp_result value can be up to 32-bits. We want to right-shift
276 * it *without* sign-extend.
277 */
278 tmp_result = tmp_result >> CALC_TEMPERATURE_RESULT_SHIFT_OFFSET;
279
280 /*
281 * at this point, tmp_result should be in the range:
282 * 200 <= tmp_result <= 365
283 */
284 return (s16)tmp_result - 240;
285}
286
287static s32 check_nic_temperature(struct iwl_mvm *mvm)
288{
289 u16 volt_band_gap;
290 union dts_diode_results avg_ptat;
291
292 volt_band_gap = iwl_mvm_dts_get_volt_band_gap(mvm);
293
294 /* disable DTS */
295 iwl_write_prph(mvm->trans, SHR_MISC_WFM_DTS_EN, 0);
296
297 /* SV initialization */
298 iwl_write_prph(mvm->trans, SHR_MISC_WFM_DTS_EN, 1);
299 iwl_write_prph(mvm->trans, DTSC_CFG_MODE,
300 DTSC_CFG_MODE_PERIODIC);
301
302 /* wait for results */
303 msleep(100);
304 if (!dts_read_ptat_avg_results(mvm, &avg_ptat))
305 return TEMPERATURE_ERROR;
306
307 /* disable DTS */
308 iwl_write_prph(mvm->trans, SHR_MISC_WFM_DTS_EN, 0);
309
310 return calculate_nic_temperature(avg_ptat, volt_band_gap);
311}
312
313static void iwl_mvm_enter_ctkill(struct iwl_mvm *mvm)
314{
315 u32 duration = mvm->thermal_throttle.params->ct_kill_duration;
316
317 IWL_ERR(mvm, "Enter CT Kill\n");
318 iwl_mvm_set_hw_ctkill_state(mvm, true);
319 schedule_delayed_work(&mvm->thermal_throttle.ct_kill_exit,
320 round_jiffies_relative(duration * HZ));
321}
322
323static void iwl_mvm_exit_ctkill(struct iwl_mvm *mvm)
324{
325 IWL_ERR(mvm, "Exit CT Kill\n");
326 iwl_mvm_set_hw_ctkill_state(mvm, false);
327}
328
329static void check_exit_ctkill(struct work_struct *work)
330{
331 struct iwl_mvm_tt_mgmt *tt;
332 struct iwl_mvm *mvm;
333 u32 duration;
334 s32 temp;
335
336 tt = container_of(work, struct iwl_mvm_tt_mgmt, ct_kill_exit.work);
337 mvm = container_of(tt, struct iwl_mvm, thermal_throttle);
338
339 duration = tt->params->ct_kill_duration;
340
341 iwl_trans_start_hw(mvm->trans);
342 temp = check_nic_temperature(mvm);
343 iwl_trans_stop_hw(mvm->trans, false);
344
345 if (temp < MIN_TEMPERATURE || temp > MAX_TEMPERATURE) {
346 IWL_DEBUG_TEMP(mvm, "Failed to measure NIC temperature\n");
347 goto reschedule;
348 }
349 IWL_DEBUG_TEMP(mvm, "NIC temperature: %d\n", temp);
350
351 if (temp <= tt->params->ct_kill_exit) {
352 iwl_mvm_exit_ctkill(mvm);
353 return;
354 }
355
356reschedule:
357 schedule_delayed_work(&mvm->thermal_throttle.ct_kill_exit,
358 round_jiffies(duration * HZ));
359}
360
361static void iwl_mvm_tt_smps_iterator(void *_data, u8 *mac,
362 struct ieee80211_vif *vif)
363{
364 struct iwl_mvm *mvm = _data;
365 enum ieee80211_smps_mode smps_mode;
366
367 lockdep_assert_held(&mvm->mutex);
368
369 if (mvm->thermal_throttle.dynamic_smps)
370 smps_mode = IEEE80211_SMPS_DYNAMIC;
371 else
372 smps_mode = IEEE80211_SMPS_AUTOMATIC;
373
374 if (vif->type != NL80211_IFTYPE_STATION)
375 return;
376
377 iwl_mvm_update_smps(mvm, vif, IWL_MVM_SMPS_REQ_TT, smps_mode);
378}
379
380static void iwl_mvm_tt_tx_protection(struct iwl_mvm *mvm, bool enable)
381{
382 struct ieee80211_sta *sta;
383 struct iwl_mvm_sta *mvmsta;
384 int i, err;
385
386 for (i = 0; i < IWL_MVM_STATION_COUNT; i++) {
387 sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[i],
388 lockdep_is_held(&mvm->mutex));
389 if (IS_ERR_OR_NULL(sta))
390 continue;
391 mvmsta = (void *)sta->drv_priv;
392 if (enable == mvmsta->tt_tx_protection)
393 continue;
394 err = iwl_mvm_tx_protection(mvm, &mvmsta->lq_sta.lq,
395 mvmsta, enable);
396 if (err) {
397 IWL_ERR(mvm, "Failed to %s Tx protection\n",
398 enable ? "enable" : "disable");
399 } else {
400 IWL_DEBUG_TEMP(mvm, "%s Tx protection\n",
401 enable ? "Enable" : "Disable");
402 mvmsta->tt_tx_protection = enable;
403 }
404 }
405}
406
407static void iwl_mvm_tt_tx_backoff(struct iwl_mvm *mvm, u32 backoff)
408{
409 struct iwl_host_cmd cmd = {
410 .id = REPLY_THERMAL_MNG_BACKOFF,
411 .len = { sizeof(u32), },
412 .data = { &backoff, },
413 .flags = CMD_SYNC,
414 };
415
416 if (iwl_mvm_send_cmd(mvm, &cmd) == 0) {
417 IWL_DEBUG_TEMP(mvm, "Set Thermal Tx backoff to: %u\n",
418 backoff);
419 mvm->thermal_throttle.tx_backoff = backoff;
420 } else {
421 IWL_ERR(mvm, "Failed to change Thermal Tx backoff\n");
422 }
423}
424
425void iwl_mvm_tt_handler(struct iwl_mvm *mvm)
426{
427 const struct iwl_tt_params *params = mvm->thermal_throttle.params;
428 struct iwl_mvm_tt_mgmt *tt = &mvm->thermal_throttle;
429 s32 temperature = mvm->temperature;
430 int i;
431 u32 tx_backoff;
432
433 IWL_DEBUG_TEMP(mvm, "NIC temperature: %d\n", mvm->temperature);
434
435 if (params->support_ct_kill && temperature >= params->ct_kill_entry) {
436 iwl_mvm_enter_ctkill(mvm);
437 return;
438 }
439
440 if (params->support_dynamic_smps) {
441 if (!tt->dynamic_smps &&
442 temperature >= params->dynamic_smps_entry) {
443 IWL_DEBUG_TEMP(mvm, "Enable dynamic SMPS\n");
444 tt->dynamic_smps = true;
445 ieee80211_iterate_active_interfaces_atomic(
446 mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
447 iwl_mvm_tt_smps_iterator, mvm);
448 } else if (tt->dynamic_smps &&
449 temperature <= params->dynamic_smps_exit) {
450 IWL_DEBUG_TEMP(mvm, "Disable dynamic SMPS\n");
451 tt->dynamic_smps = false;
452 ieee80211_iterate_active_interfaces_atomic(
453 mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
454 iwl_mvm_tt_smps_iterator, mvm);
455 }
456 }
457
458 if (params->support_tx_protection) {
459 if (temperature >= params->tx_protection_entry)
460 iwl_mvm_tt_tx_protection(mvm, true);
461 else if (temperature <= params->tx_protection_exit)
462 iwl_mvm_tt_tx_protection(mvm, false);
463 }
464
465 if (params->support_tx_backoff) {
466 tx_backoff = 0;
467 for (i = 0; i < TT_TX_BACKOFF_SIZE; i++) {
468 if (temperature < params->tx_backoff[i].temperature)
469 break;
470 tx_backoff = params->tx_backoff[i].backoff;
471 }
472 if (tt->tx_backoff != tx_backoff)
473 iwl_mvm_tt_tx_backoff(mvm, tx_backoff);
474 }
475}
476
477static const struct iwl_tt_params iwl7000_tt_params = {
478 .ct_kill_entry = 118,
479 .ct_kill_exit = 96,
480 .ct_kill_duration = 5,
481 .dynamic_smps_entry = 114,
482 .dynamic_smps_exit = 110,
483 .tx_protection_entry = 114,
484 .tx_protection_exit = 108,
485 .tx_backoff = {
486 {.temperature = 112, .backoff = 200},
487 {.temperature = 113, .backoff = 600},
488 {.temperature = 114, .backoff = 1200},
489 {.temperature = 115, .backoff = 2000},
490 {.temperature = 116, .backoff = 4000},
491 {.temperature = 117, .backoff = 10000},
492 },
493 .support_ct_kill = true,
494 .support_dynamic_smps = true,
495 .support_tx_protection = true,
496 .support_tx_backoff = true,
497};
498
499void iwl_mvm_tt_initialize(struct iwl_mvm *mvm)
500{
501 struct iwl_mvm_tt_mgmt *tt = &mvm->thermal_throttle;
502
503 IWL_DEBUG_TEMP(mvm, "Initialize Thermal Throttling\n");
504 tt->params = &iwl7000_tt_params;
505 INIT_DELAYED_WORK(&tt->ct_kill_exit, check_exit_ctkill);
506}
507
508void iwl_mvm_tt_exit(struct iwl_mvm *mvm)
509{
510 cancel_delayed_work_sync(&mvm->thermal_throttle.ct_kill_exit);
511 IWL_DEBUG_TEMP(mvm, "Exit Thermal Throttling\n");
512}
diff --git a/drivers/net/wireless/iwlwifi/mvm/tx.c b/drivers/net/wireless/iwlwifi/mvm/tx.c
index f212f16502ff..a830eb6cc411 100644
--- a/drivers/net/wireless/iwlwifi/mvm/tx.c
+++ b/drivers/net/wireless/iwlwifi/mvm/tx.c
@@ -175,7 +175,7 @@ static void iwl_mvm_set_tx_cmd_rate(struct iwl_mvm *mvm,
175 * table is controlled by LINK_QUALITY commands 175 * table is controlled by LINK_QUALITY commands
176 */ 176 */
177 177
178 if (ieee80211_is_data(fc)) { 178 if (ieee80211_is_data(fc) && sta) {
179 tx_cmd->initial_rate_index = 0; 179 tx_cmd->initial_rate_index = 0;
180 tx_cmd->tx_flags |= cpu_to_le32(TX_CMD_FLG_STA_RATE); 180 tx_cmd->tx_flags |= cpu_to_le32(TX_CMD_FLG_STA_RATE);
181 return; 181 return;
diff --git a/drivers/net/wireless/iwlwifi/mvm/utils.c b/drivers/net/wireless/iwlwifi/mvm/utils.c
index 687b34e387ac..1e1332839e4a 100644
--- a/drivers/net/wireless/iwlwifi/mvm/utils.c
+++ b/drivers/net/wireless/iwlwifi/mvm/utils.c
@@ -76,6 +76,11 @@ int iwl_mvm_send_cmd(struct iwl_mvm *mvm, struct iwl_host_cmd *cmd)
76{ 76{
77 int ret; 77 int ret;
78 78
79#if defined(CONFIG_IWLWIFI_DEBUGFS) && defined(CONFIG_PM_SLEEP)
80 if (WARN_ON(mvm->d3_test_active))
81 return -EIO;
82#endif
83
79 /* 84 /*
80 * Synchronous commands from this op-mode must hold 85 * Synchronous commands from this op-mode must hold
81 * the mutex, this ensures we don't try to send two 86 * the mutex, this ensures we don't try to send two
@@ -125,6 +130,11 @@ int iwl_mvm_send_cmd_status(struct iwl_mvm *mvm, struct iwl_host_cmd *cmd,
125 130
126 lockdep_assert_held(&mvm->mutex); 131 lockdep_assert_held(&mvm->mutex);
127 132
133#if defined(CONFIG_IWLWIFI_DEBUGFS) && defined(CONFIG_PM_SLEEP)
134 if (WARN_ON(mvm->d3_test_active))
135 return -EIO;
136#endif
137
128 /* 138 /*
129 * Only synchronous commands can wait for status, 139 * Only synchronous commands can wait for status,
130 * we use WANT_SKB so the caller can't. 140 * we use WANT_SKB so the caller can't.
@@ -471,3 +481,34 @@ int iwl_mvm_send_lq_cmd(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq,
471 481
472 return iwl_mvm_send_cmd(mvm, &cmd); 482 return iwl_mvm_send_cmd(mvm, &cmd);
473} 483}
484
485/**
486 * iwl_mvm_update_smps - Get a requst to change the SMPS mode
487 * @req_type: The part of the driver who call for a change.
488 * @smps_requests: The request to change the SMPS mode.
489 *
490 * Get a requst to change the SMPS mode,
491 * and change it according to all other requests in the driver.
492 */
493void iwl_mvm_update_smps(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
494 enum iwl_mvm_smps_type_request req_type,
495 enum ieee80211_smps_mode smps_request)
496{
497 struct iwl_mvm_vif *mvmvif;
498 enum ieee80211_smps_mode smps_mode = IEEE80211_SMPS_AUTOMATIC;
499 int i;
500
501 lockdep_assert_held(&mvm->mutex);
502 mvmvif = iwl_mvm_vif_from_mac80211(vif);
503 mvmvif->smps_requests[req_type] = smps_request;
504 for (i = 0; i < NUM_IWL_MVM_SMPS_REQ; i++) {
505 if (mvmvif->smps_requests[i] == IEEE80211_SMPS_STATIC) {
506 smps_mode = IEEE80211_SMPS_STATIC;
507 break;
508 }
509 if (mvmvif->smps_requests[i] == IEEE80211_SMPS_DYNAMIC)
510 smps_mode = IEEE80211_SMPS_DYNAMIC;
511 }
512
513 ieee80211_request_smps(vif, smps_mode);
514}
diff --git a/drivers/net/wireless/iwlwifi/pcie/drv.c b/drivers/net/wireless/iwlwifi/pcie/drv.c
index 8cb53ec2b77b..db7bdd35a9c5 100644
--- a/drivers/net/wireless/iwlwifi/pcie/drv.c
+++ b/drivers/net/wireless/iwlwifi/pcie/drv.c
@@ -256,10 +256,54 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
256 256
257/* 7000 Series */ 257/* 7000 Series */
258 {IWL_PCI_DEVICE(0x08B1, 0x4070, iwl7260_2ac_cfg)}, 258 {IWL_PCI_DEVICE(0x08B1, 0x4070, iwl7260_2ac_cfg)},
259 {IWL_PCI_DEVICE(0x08B1, 0x4062, iwl7260_2ac_cfg)}, 259 {IWL_PCI_DEVICE(0x08B1, 0x4170, iwl7260_2ac_cfg)},
260 {IWL_PCI_DEVICE(0x08B1, 0x4060, iwl7260_2n_cfg)},
261 {IWL_PCI_DEVICE(0x08B1, 0x4160, iwl7260_2n_cfg)},
262 {IWL_PCI_DEVICE(0x08B1, 0x4062, iwl7260_n_cfg)},
263 {IWL_PCI_DEVICE(0x08B1, 0x4162, iwl7260_n_cfg)},
264 {IWL_PCI_DEVICE(0x08B2, 0x4270, iwl7260_2ac_cfg)},
265 {IWL_PCI_DEVICE(0x08B2, 0x4260, iwl7260_2n_cfg)},
266 {IWL_PCI_DEVICE(0x08B2, 0x4262, iwl7260_n_cfg)},
267 {IWL_PCI_DEVICE(0x08B1, 0x4470, iwl7260_2ac_cfg)},
268 {IWL_PCI_DEVICE(0x08B1, 0x4460, iwl7260_2n_cfg)},
269 {IWL_PCI_DEVICE(0x08B1, 0x4462, iwl7260_n_cfg)},
270 {IWL_PCI_DEVICE(0x08B1, 0x4870, iwl7260_2ac_cfg)},
271 {IWL_PCI_DEVICE(0x08B1, 0x486E, iwl7260_2ac_cfg)},
272 {IWL_PCI_DEVICE(0x08B1, 0x4A70, iwl7260_2ac_cfg)},
273 {IWL_PCI_DEVICE(0x08B1, 0x4A6E, iwl7260_2ac_cfg)},
274 {IWL_PCI_DEVICE(0x08B1, 0x4A6C, iwl7260_2ac_cfg)},
275 {IWL_PCI_DEVICE(0x08B1, 0x4020, iwl7260_2n_cfg)},
276 {IWL_PCI_DEVICE(0x08B2, 0x4220, iwl7260_2n_cfg)},
277 {IWL_PCI_DEVICE(0x08B1, 0x4420, iwl7260_2n_cfg)},
260 {IWL_PCI_DEVICE(0x08B1, 0xC070, iwl7260_2ac_cfg)}, 278 {IWL_PCI_DEVICE(0x08B1, 0xC070, iwl7260_2ac_cfg)},
261 {IWL_PCI_DEVICE(0x08B3, 0x0070, iwl3160_ac_cfg)}, 279 {IWL_PCI_DEVICE(0x08B1, 0xC170, iwl7260_2ac_cfg)},
262 {IWL_PCI_DEVICE(0x08B3, 0x8070, iwl3160_ac_cfg)}, 280 {IWL_PCI_DEVICE(0x08B1, 0xC060, iwl7260_2n_cfg)},
281 {IWL_PCI_DEVICE(0x08B1, 0xC160, iwl7260_2n_cfg)},
282 {IWL_PCI_DEVICE(0x08B1, 0xC062, iwl7260_n_cfg)},
283 {IWL_PCI_DEVICE(0x08B1, 0xC162, iwl7260_n_cfg)},
284 {IWL_PCI_DEVICE(0x08B2, 0xC270, iwl7260_2ac_cfg)},
285 {IWL_PCI_DEVICE(0x08B2, 0xC260, iwl7260_2n_cfg)},
286 {IWL_PCI_DEVICE(0x08B2, 0xC262, iwl7260_n_cfg)},
287 {IWL_PCI_DEVICE(0x08B1, 0xC470, iwl7260_2ac_cfg)},
288 {IWL_PCI_DEVICE(0x08B1, 0xC460, iwl7260_2n_cfg)},
289 {IWL_PCI_DEVICE(0x08B1, 0xC462, iwl7260_n_cfg)},
290 {IWL_PCI_DEVICE(0x08B1, 0xC020, iwl7260_2n_cfg)},
291 {IWL_PCI_DEVICE(0x08B2, 0xC220, iwl7260_2n_cfg)},
292 {IWL_PCI_DEVICE(0x08B1, 0xC420, iwl7260_2n_cfg)},
293
294/* 3160 Series */
295 {IWL_PCI_DEVICE(0x08B3, 0x0070, iwl3160_2ac_cfg)},
296 {IWL_PCI_DEVICE(0x08B3, 0x0170, iwl3160_2ac_cfg)},
297 {IWL_PCI_DEVICE(0x08B3, 0x0060, iwl3160_2n_cfg)},
298 {IWL_PCI_DEVICE(0x08B3, 0x0062, iwl3160_n_cfg)},
299 {IWL_PCI_DEVICE(0x08B4, 0x0270, iwl3160_2ac_cfg)},
300 {IWL_PCI_DEVICE(0x08B3, 0x0470, iwl3160_2ac_cfg)},
301 {IWL_PCI_DEVICE(0x08B3, 0x8070, iwl3160_2ac_cfg)},
302 {IWL_PCI_DEVICE(0x08B3, 0x8170, iwl3160_2ac_cfg)},
303 {IWL_PCI_DEVICE(0x08B3, 0x8060, iwl3160_2n_cfg)},
304 {IWL_PCI_DEVICE(0x08B3, 0x8062, iwl3160_n_cfg)},
305 {IWL_PCI_DEVICE(0x08B4, 0x8270, iwl3160_2ac_cfg)},
306 {IWL_PCI_DEVICE(0x08B3, 0x8470, iwl3160_2ac_cfg)},
263 307
264 {0} 308 {0}
265}; 309};
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c
index 50ba0a468f94..197dbe0a868c 100644
--- a/drivers/net/wireless/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/iwlwifi/pcie/trans.c
@@ -405,20 +405,27 @@ static int iwl_pcie_load_section(struct iwl_trans *trans, u8 section_num,
405{ 405{
406 u8 *v_addr; 406 u8 *v_addr;
407 dma_addr_t p_addr; 407 dma_addr_t p_addr;
408 u32 offset; 408 u32 offset, chunk_sz = section->len;
409 int ret = 0; 409 int ret = 0;
410 410
411 IWL_DEBUG_FW(trans, "[%d] uCode section being loaded...\n", 411 IWL_DEBUG_FW(trans, "[%d] uCode section being loaded...\n",
412 section_num); 412 section_num);
413 413
414 v_addr = dma_alloc_coherent(trans->dev, PAGE_SIZE, &p_addr, GFP_KERNEL); 414 v_addr = dma_alloc_coherent(trans->dev, chunk_sz, &p_addr,
415 if (!v_addr) 415 GFP_KERNEL | __GFP_NOWARN);
416 return -ENOMEM; 416 if (!v_addr) {
417 IWL_DEBUG_INFO(trans, "Falling back to small chunks of DMA\n");
418 chunk_sz = PAGE_SIZE;
419 v_addr = dma_alloc_coherent(trans->dev, chunk_sz,
420 &p_addr, GFP_KERNEL);
421 if (!v_addr)
422 return -ENOMEM;
423 }
417 424
418 for (offset = 0; offset < section->len; offset += PAGE_SIZE) { 425 for (offset = 0; offset < section->len; offset += chunk_sz) {
419 u32 copy_size; 426 u32 copy_size;
420 427
421 copy_size = min_t(u32, PAGE_SIZE, section->len - offset); 428 copy_size = min_t(u32, chunk_sz, section->len - offset);
422 429
423 memcpy(v_addr, (u8 *)section->data + offset, copy_size); 430 memcpy(v_addr, (u8 *)section->data + offset, copy_size);
424 ret = iwl_pcie_load_firmware_chunk(trans, 431 ret = iwl_pcie_load_firmware_chunk(trans,
@@ -432,7 +439,7 @@ static int iwl_pcie_load_section(struct iwl_trans *trans, u8 section_num,
432 } 439 }
433 } 440 }
434 441
435 dma_free_coherent(trans->dev, PAGE_SIZE, v_addr, p_addr); 442 dma_free_coherent(trans->dev, chunk_sz, v_addr, p_addr);
436 return ret; 443 return ret;
437} 444}
438 445
@@ -571,13 +578,17 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans)
571 clear_bit(STATUS_RFKILL, &trans_pcie->status); 578 clear_bit(STATUS_RFKILL, &trans_pcie->status);
572} 579}
573 580
574static void iwl_trans_pcie_d3_suspend(struct iwl_trans *trans) 581static void iwl_trans_pcie_d3_suspend(struct iwl_trans *trans, bool test)
575{ 582{
576 /* let the ucode operate on its own */
577 iwl_write32(trans, CSR_UCODE_DRV_GP1_SET,
578 CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE);
579
580 iwl_disable_interrupts(trans); 583 iwl_disable_interrupts(trans);
584
585 /*
586 * in testing mode, the host stays awake and the
587 * hardware won't be reset (not even partially)
588 */
589 if (test)
590 return;
591
581 iwl_pcie_disable_ict(trans); 592 iwl_pcie_disable_ict(trans);
582 593
583 iwl_clear_bit(trans, CSR_GP_CNTRL, 594 iwl_clear_bit(trans, CSR_GP_CNTRL,
@@ -596,11 +607,18 @@ static void iwl_trans_pcie_d3_suspend(struct iwl_trans *trans)
596} 607}
597 608
598static int iwl_trans_pcie_d3_resume(struct iwl_trans *trans, 609static int iwl_trans_pcie_d3_resume(struct iwl_trans *trans,
599 enum iwl_d3_status *status) 610 enum iwl_d3_status *status,
611 bool test)
600{ 612{
601 u32 val; 613 u32 val;
602 int ret; 614 int ret;
603 615
616 if (test) {
617 iwl_enable_interrupts(trans);
618 *status = IWL_D3_STATUS_ALIVE;
619 return 0;
620 }
621
604 iwl_pcie_set_pwr(trans, false); 622 iwl_pcie_set_pwr(trans, false);
605 623
606 val = iwl_read32(trans, CSR_RESET); 624 val = iwl_read32(trans, CSR_RESET);
@@ -636,9 +654,6 @@ static int iwl_trans_pcie_d3_resume(struct iwl_trans *trans,
636 return ret; 654 return ret;
637 } 655 }
638 656
639 iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR,
640 CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE);
641
642 *status = IWL_D3_STATUS_ALIVE; 657 *status = IWL_D3_STATUS_ALIVE;
643 return 0; 658 return 0;
644} 659}
@@ -917,11 +932,11 @@ static int iwl_trans_pcie_read_mem(struct iwl_trans *trans, u32 addr,
917} 932}
918 933
919static int iwl_trans_pcie_write_mem(struct iwl_trans *trans, u32 addr, 934static int iwl_trans_pcie_write_mem(struct iwl_trans *trans, u32 addr,
920 void *buf, int dwords) 935 const void *buf, int dwords)
921{ 936{
922 unsigned long flags; 937 unsigned long flags;
923 int offs, ret = 0; 938 int offs, ret = 0;
924 u32 *vals = buf; 939 const u32 *vals = buf;
925 940
926 if (iwl_trans_grab_nic_access(trans, false, &flags)) { 941 if (iwl_trans_grab_nic_access(trans, false, &flags)) {
927 iwl_write32(trans, HBUS_TARG_MEM_WADDR, addr); 942 iwl_write32(trans, HBUS_TARG_MEM_WADDR, addr);
diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c
index c5e30294c5ac..f65da1984d91 100644
--- a/drivers/net/wireless/iwlwifi/pcie/tx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/tx.c
@@ -224,13 +224,13 @@ static void iwl_pcie_txq_update_byte_cnt_tbl(struct iwl_trans *trans,
224 224
225 switch (sec_ctl & TX_CMD_SEC_MSK) { 225 switch (sec_ctl & TX_CMD_SEC_MSK) {
226 case TX_CMD_SEC_CCM: 226 case TX_CMD_SEC_CCM:
227 len += CCMP_MIC_LEN; 227 len += IEEE80211_CCMP_MIC_LEN;
228 break; 228 break;
229 case TX_CMD_SEC_TKIP: 229 case TX_CMD_SEC_TKIP:
230 len += TKIP_ICV_LEN; 230 len += IEEE80211_TKIP_ICV_LEN;
231 break; 231 break;
232 case TX_CMD_SEC_WEP: 232 case TX_CMD_SEC_WEP:
233 len += WEP_IV_LEN + WEP_ICV_LEN; 233 len += IEEE80211_WEP_IV_LEN + IEEE80211_WEP_ICV_LEN;
234 break; 234 break;
235 } 235 }
236 236
@@ -1045,6 +1045,10 @@ static inline void iwl_pcie_txq_set_inactive(struct iwl_trans *trans,
1045 (1 << SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN)); 1045 (1 << SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN));
1046} 1046}
1047 1047
1048/* Receiver address (actually, Rx station's index into station table),
1049 * combined with Traffic ID (QOS priority), in format used by Tx Scheduler */
1050#define BUILD_RAxTID(sta_id, tid) (((sta_id) << 4) + (tid))
1051
1048void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo, 1052void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo,
1049 int sta_id, int tid, int frame_limit, u16 ssn) 1053 int sta_id, int tid, int frame_limit, u16 ssn)
1050{ 1054{
@@ -1518,11 +1522,13 @@ static int iwl_pcie_send_hcmd_sync(struct iwl_trans *trans,
1518 if (test_bit(STATUS_FW_ERROR, &trans_pcie->status)) { 1522 if (test_bit(STATUS_FW_ERROR, &trans_pcie->status)) {
1519 IWL_ERR(trans, "FW error in SYNC CMD %s\n", 1523 IWL_ERR(trans, "FW error in SYNC CMD %s\n",
1520 get_cmd_string(trans_pcie, cmd->id)); 1524 get_cmd_string(trans_pcie, cmd->id));
1525 dump_stack();
1521 ret = -EIO; 1526 ret = -EIO;
1522 goto cancel; 1527 goto cancel;
1523 } 1528 }
1524 1529
1525 if (test_bit(STATUS_RFKILL, &trans_pcie->status)) { 1530 if (!(cmd->flags & CMD_SEND_IN_RFKILL) &&
1531 test_bit(STATUS_RFKILL, &trans_pcie->status)) {
1526 IWL_DEBUG_RF_KILL(trans, "RFKILL in SYNC CMD... no rsp\n"); 1532 IWL_DEBUG_RF_KILL(trans, "RFKILL in SYNC CMD... no rsp\n");
1527 ret = -ERFKILL; 1533 ret = -ERFKILL;
1528 goto cancel; 1534 goto cancel;
@@ -1564,7 +1570,8 @@ int iwl_trans_pcie_send_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
1564 if (test_bit(STATUS_FW_ERROR, &trans_pcie->status)) 1570 if (test_bit(STATUS_FW_ERROR, &trans_pcie->status))
1565 return -EIO; 1571 return -EIO;
1566 1572
1567 if (test_bit(STATUS_RFKILL, &trans_pcie->status)) { 1573 if (!(cmd->flags & CMD_SEND_IN_RFKILL) &&
1574 test_bit(STATUS_RFKILL, &trans_pcie->status)) {
1568 IWL_DEBUG_RF_KILL(trans, "Dropping CMD 0x%x: RF KILL\n", 1575 IWL_DEBUG_RF_KILL(trans, "Dropping CMD 0x%x: RF KILL\n",
1569 cmd->id); 1576 cmd->id);
1570 return -ERFKILL; 1577 return -ERFKILL;
diff --git a/drivers/net/wireless/mwifiex/Kconfig b/drivers/net/wireless/mwifiex/Kconfig
index 4f614aad9ded..f7ff4725506a 100644
--- a/drivers/net/wireless/mwifiex/Kconfig
+++ b/drivers/net/wireless/mwifiex/Kconfig
@@ -3,13 +3,13 @@ config MWIFIEX
3 depends on CFG80211 3 depends on CFG80211
4 ---help--- 4 ---help---
5 This adds support for wireless adapters based on Marvell 5 This adds support for wireless adapters based on Marvell
6 802.11n chipsets. 6 802.11n/ac chipsets.
7 7
8 If you choose to build it as a module, it will be called 8 If you choose to build it as a module, it will be called
9 mwifiex. 9 mwifiex.
10 10
11config MWIFIEX_SDIO 11config MWIFIEX_SDIO
12 tristate "Marvell WiFi-Ex Driver for SD8786/SD8787/SD8797" 12 tristate "Marvell WiFi-Ex Driver for SD8786/SD8787/SD8797/SD8897"
13 depends on MWIFIEX && MMC 13 depends on MWIFIEX && MMC
14 select FW_LOADER 14 select FW_LOADER
15 ---help--- 15 ---help---
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index e42b266a023a..00a82817eb6b 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -1231,6 +1231,51 @@ static int mwifiex_cfg80211_change_beacon(struct wiphy *wiphy,
1231 return 0; 1231 return 0;
1232} 1232}
1233 1233
1234/* cfg80211 operation handler for del_station.
1235 * Function deauthenticates station which value is provided in mac parameter.
1236 * If mac is NULL/broadcast, all stations in associated station list are
1237 * deauthenticated. If bss is not started or there are no stations in
1238 * associated stations list, no action is taken.
1239 */
1240static int
1241mwifiex_cfg80211_del_station(struct wiphy *wiphy, struct net_device *dev,
1242 u8 *mac)
1243{
1244 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
1245 struct mwifiex_sta_node *sta_node;
1246 unsigned long flags;
1247
1248 if (list_empty(&priv->sta_list) || !priv->bss_started)
1249 return 0;
1250
1251 if (!mac || is_broadcast_ether_addr(mac)) {
1252 wiphy_dbg(wiphy, "%s: NULL/broadcast mac address\n", __func__);
1253 list_for_each_entry(sta_node, &priv->sta_list, list) {
1254 if (mwifiex_send_cmd_sync(priv,
1255 HostCmd_CMD_UAP_STA_DEAUTH,
1256 HostCmd_ACT_GEN_SET, 0,
1257 sta_node->mac_addr))
1258 return -1;
1259 mwifiex_uap_del_sta_data(priv, sta_node);
1260 }
1261 } else {
1262 wiphy_dbg(wiphy, "%s: mac address %pM\n", __func__, mac);
1263 spin_lock_irqsave(&priv->sta_list_spinlock, flags);
1264 sta_node = mwifiex_get_sta_entry(priv, mac);
1265 spin_unlock_irqrestore(&priv->sta_list_spinlock, flags);
1266 if (sta_node) {
1267 if (mwifiex_send_cmd_sync(priv,
1268 HostCmd_CMD_UAP_STA_DEAUTH,
1269 HostCmd_ACT_GEN_SET, 0,
1270 sta_node->mac_addr))
1271 return -1;
1272 mwifiex_uap_del_sta_data(priv, sta_node);
1273 }
1274 }
1275
1276 return 0;
1277}
1278
1234static int 1279static int
1235mwifiex_cfg80211_set_antenna(struct wiphy *wiphy, u32 tx_ant, u32 rx_ant) 1280mwifiex_cfg80211_set_antenna(struct wiphy *wiphy, u32 tx_ant, u32 rx_ant)
1236{ 1281{
@@ -1859,6 +1904,7 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy,
1859 int i, offset, ret; 1904 int i, offset, ret;
1860 struct ieee80211_channel *chan; 1905 struct ieee80211_channel *chan;
1861 struct ieee_types_header *ie; 1906 struct ieee_types_header *ie;
1907 struct mwifiex_user_scan_cfg *user_scan_cfg;
1862 1908
1863 wiphy_dbg(wiphy, "info: received scan request on %s\n", dev->name); 1909 wiphy_dbg(wiphy, "info: received scan request on %s\n", dev->name);
1864 1910
@@ -1869,20 +1915,22 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy,
1869 return -EBUSY; 1915 return -EBUSY;
1870 } 1916 }
1871 1917
1872 if (priv->user_scan_cfg) { 1918 /* Block scan request if scan operation or scan cleanup when interface
1919 * is disabled is in process
1920 */
1921 if (priv->scan_request || priv->scan_aborting) {
1873 dev_err(priv->adapter->dev, "cmd: Scan already in process..\n"); 1922 dev_err(priv->adapter->dev, "cmd: Scan already in process..\n");
1874 return -EBUSY; 1923 return -EBUSY;
1875 } 1924 }
1876 1925
1877 priv->user_scan_cfg = kzalloc(sizeof(struct mwifiex_user_scan_cfg), 1926 user_scan_cfg = kzalloc(sizeof(*user_scan_cfg), GFP_KERNEL);
1878 GFP_KERNEL); 1927 if (!user_scan_cfg)
1879 if (!priv->user_scan_cfg)
1880 return -ENOMEM; 1928 return -ENOMEM;
1881 1929
1882 priv->scan_request = request; 1930 priv->scan_request = request;
1883 1931
1884 priv->user_scan_cfg->num_ssids = request->n_ssids; 1932 user_scan_cfg->num_ssids = request->n_ssids;
1885 priv->user_scan_cfg->ssid_list = request->ssids; 1933 user_scan_cfg->ssid_list = request->ssids;
1886 1934
1887 if (request->ie && request->ie_len) { 1935 if (request->ie && request->ie_len) {
1888 offset = 0; 1936 offset = 0;
@@ -1902,25 +1950,25 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy,
1902 for (i = 0; i < min_t(u32, request->n_channels, 1950 for (i = 0; i < min_t(u32, request->n_channels,
1903 MWIFIEX_USER_SCAN_CHAN_MAX); i++) { 1951 MWIFIEX_USER_SCAN_CHAN_MAX); i++) {
1904 chan = request->channels[i]; 1952 chan = request->channels[i];
1905 priv->user_scan_cfg->chan_list[i].chan_number = chan->hw_value; 1953 user_scan_cfg->chan_list[i].chan_number = chan->hw_value;
1906 priv->user_scan_cfg->chan_list[i].radio_type = chan->band; 1954 user_scan_cfg->chan_list[i].radio_type = chan->band;
1907 1955
1908 if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN) 1956 if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN)
1909 priv->user_scan_cfg->chan_list[i].scan_type = 1957 user_scan_cfg->chan_list[i].scan_type =
1910 MWIFIEX_SCAN_TYPE_PASSIVE; 1958 MWIFIEX_SCAN_TYPE_PASSIVE;
1911 else 1959 else
1912 priv->user_scan_cfg->chan_list[i].scan_type = 1960 user_scan_cfg->chan_list[i].scan_type =
1913 MWIFIEX_SCAN_TYPE_ACTIVE; 1961 MWIFIEX_SCAN_TYPE_ACTIVE;
1914 1962
1915 priv->user_scan_cfg->chan_list[i].scan_time = 0; 1963 user_scan_cfg->chan_list[i].scan_time = 0;
1916 } 1964 }
1917 1965
1918 ret = mwifiex_scan_networks(priv, priv->user_scan_cfg); 1966 ret = mwifiex_scan_networks(priv, user_scan_cfg);
1967 kfree(user_scan_cfg);
1919 if (ret) { 1968 if (ret) {
1920 dev_err(priv->adapter->dev, "scan failed: %d\n", ret); 1969 dev_err(priv->adapter->dev, "scan failed: %d\n", ret);
1970 priv->scan_aborting = false;
1921 priv->scan_request = NULL; 1971 priv->scan_request = NULL;
1922 kfree(priv->user_scan_cfg);
1923 priv->user_scan_cfg = NULL;
1924 return ret; 1972 return ret;
1925 } 1973 }
1926 1974
@@ -2419,6 +2467,7 @@ static struct cfg80211_ops mwifiex_cfg80211_ops = {
2419 .change_beacon = mwifiex_cfg80211_change_beacon, 2467 .change_beacon = mwifiex_cfg80211_change_beacon,
2420 .set_cqm_rssi_config = mwifiex_cfg80211_set_cqm_rssi_config, 2468 .set_cqm_rssi_config = mwifiex_cfg80211_set_cqm_rssi_config,
2421 .set_antenna = mwifiex_cfg80211_set_antenna, 2469 .set_antenna = mwifiex_cfg80211_set_antenna,
2470 .del_station = mwifiex_cfg80211_del_station,
2422#ifdef CONFIG_PM 2471#ifdef CONFIG_PM
2423 .suspend = mwifiex_cfg80211_suspend, 2472 .suspend = mwifiex_cfg80211_suspend,
2424 .resume = mwifiex_cfg80211_resume, 2473 .resume = mwifiex_cfg80211_resume,
diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c
index 26755d9acb55..2d761477d15e 100644
--- a/drivers/net/wireless/mwifiex/cmdevt.c
+++ b/drivers/net/wireless/mwifiex/cmdevt.c
@@ -570,6 +570,7 @@ int mwifiex_send_cmd_async(struct mwifiex_private *priv, uint16_t cmd_no,
570 case HostCmd_CMD_UAP_SYS_CONFIG: 570 case HostCmd_CMD_UAP_SYS_CONFIG:
571 case HostCmd_CMD_UAP_BSS_START: 571 case HostCmd_CMD_UAP_BSS_START:
572 case HostCmd_CMD_UAP_BSS_STOP: 572 case HostCmd_CMD_UAP_BSS_STOP:
573 case HostCmd_CMD_UAP_STA_DEAUTH:
573 ret = mwifiex_uap_prepare_cmd(priv, cmd_no, cmd_action, 574 ret = mwifiex_uap_prepare_cmd(priv, cmd_no, cmd_action,
574 cmd_oid, data_buf, 575 cmd_oid, data_buf,
575 cmd_ptr); 576 cmd_ptr);
diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h
index 1f7578d553ec..d6ada7354c14 100644
--- a/drivers/net/wireless/mwifiex/fw.h
+++ b/drivers/net/wireless/mwifiex/fw.h
@@ -271,6 +271,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
271#define HostCmd_CMD_802_11_SUBSCRIBE_EVENT 0x0075 271#define HostCmd_CMD_802_11_SUBSCRIBE_EVENT 0x0075
272#define HostCmd_CMD_802_11_TX_RATE_QUERY 0x007f 272#define HostCmd_CMD_802_11_TX_RATE_QUERY 0x007f
273#define HostCmd_CMD_802_11_IBSS_COALESCING_STATUS 0x0083 273#define HostCmd_CMD_802_11_IBSS_COALESCING_STATUS 0x0083
274#define HostCmd_CMD_CFG_DATA 0x008f
274#define HostCmd_CMD_VERSION_EXT 0x0097 275#define HostCmd_CMD_VERSION_EXT 0x0097
275#define HostCmd_CMD_MEF_CFG 0x009a 276#define HostCmd_CMD_MEF_CFG 0x009a
276#define HostCmd_CMD_RSSI_INFO 0x00a4 277#define HostCmd_CMD_RSSI_INFO 0x00a4
@@ -279,6 +280,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
279#define HostCmd_CMD_UAP_SYS_CONFIG 0x00b0 280#define HostCmd_CMD_UAP_SYS_CONFIG 0x00b0
280#define HostCmd_CMD_UAP_BSS_START 0x00b1 281#define HostCmd_CMD_UAP_BSS_START 0x00b1
281#define HostCmd_CMD_UAP_BSS_STOP 0x00b2 282#define HostCmd_CMD_UAP_BSS_STOP 0x00b2
283#define HostCmd_CMD_UAP_STA_DEAUTH 0x00b5
282#define HostCmd_CMD_11N_CFG 0x00cd 284#define HostCmd_CMD_11N_CFG 0x00cd
283#define HostCmd_CMD_11N_ADDBA_REQ 0x00ce 285#define HostCmd_CMD_11N_ADDBA_REQ 0x00ce
284#define HostCmd_CMD_11N_ADDBA_RSP 0x00cf 286#define HostCmd_CMD_11N_ADDBA_RSP 0x00cf
@@ -464,6 +466,8 @@ enum P2P_MODES {
464#define MWIFIEX_CRITERIA_UNICAST BIT(1) 466#define MWIFIEX_CRITERIA_UNICAST BIT(1)
465#define MWIFIEX_CRITERIA_MULTICAST BIT(3) 467#define MWIFIEX_CRITERIA_MULTICAST BIT(3)
466 468
469#define CFG_DATA_TYPE_CAL 2
470
467struct mwifiex_ie_types_header { 471struct mwifiex_ie_types_header {
468 __le16 type; 472 __le16 type;
469 __le16 len; 473 __le16 len;
@@ -1197,6 +1201,11 @@ struct host_cmd_ds_amsdu_aggr_ctrl {
1197 __le16 curr_buf_size; 1201 __le16 curr_buf_size;
1198} __packed; 1202} __packed;
1199 1203
1204struct host_cmd_ds_sta_deauth {
1205 u8 mac[ETH_ALEN];
1206 __le16 reason;
1207} __packed;
1208
1200struct mwifiex_ie_types_wmm_param_set { 1209struct mwifiex_ie_types_wmm_param_set {
1201 struct mwifiex_ie_types_header header; 1210 struct mwifiex_ie_types_header header;
1202 u8 wmm_ie[1]; 1211 u8 wmm_ie[1];
@@ -1573,6 +1582,12 @@ struct mwifiex_ie_list {
1573 struct mwifiex_ie ie_list[MAX_MGMT_IE_INDEX]; 1582 struct mwifiex_ie ie_list[MAX_MGMT_IE_INDEX];
1574} __packed; 1583} __packed;
1575 1584
1585struct host_cmd_ds_802_11_cfg_data {
1586 __le16 action;
1587 __le16 type;
1588 __le16 data_len;
1589} __packed;
1590
1576struct host_cmd_ds_command { 1591struct host_cmd_ds_command {
1577 __le16 command; 1592 __le16 command;
1578 __le16 size; 1593 __le16 size;
@@ -1630,7 +1645,9 @@ struct host_cmd_ds_command {
1630 struct host_cmd_ds_802_11_eeprom_access eeprom; 1645 struct host_cmd_ds_802_11_eeprom_access eeprom;
1631 struct host_cmd_ds_802_11_subsc_evt subsc_evt; 1646 struct host_cmd_ds_802_11_subsc_evt subsc_evt;
1632 struct host_cmd_ds_sys_config uap_sys_config; 1647 struct host_cmd_ds_sys_config uap_sys_config;
1648 struct host_cmd_ds_sta_deauth sta_deauth;
1633 struct host_cmd_11ac_vht_cfg vht_cfg; 1649 struct host_cmd_11ac_vht_cfg vht_cfg;
1650 struct host_cmd_ds_802_11_cfg_data cfg_data;
1634 } params; 1651 } params;
1635} __packed; 1652} __packed;
1636 1653
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c
index 9f44fda19db9..c7f11c0c3bb7 100644
--- a/drivers/net/wireless/mwifiex/init.c
+++ b/drivers/net/wireless/mwifiex/init.c
@@ -59,6 +59,9 @@ static void scan_delay_timer_fn(unsigned long data)
59 struct cmd_ctrl_node *cmd_node, *tmp_node; 59 struct cmd_ctrl_node *cmd_node, *tmp_node;
60 unsigned long flags; 60 unsigned long flags;
61 61
62 if (adapter->surprise_removed)
63 return;
64
62 if (adapter->scan_delay_cnt == MWIFIEX_MAX_SCAN_DELAY_CNT) { 65 if (adapter->scan_delay_cnt == MWIFIEX_MAX_SCAN_DELAY_CNT) {
63 /* 66 /*
64 * Abort scan operation by cancelling all pending scan 67 * Abort scan operation by cancelling all pending scan
@@ -78,19 +81,13 @@ static void scan_delay_timer_fn(unsigned long data)
78 adapter->empty_tx_q_cnt = 0; 81 adapter->empty_tx_q_cnt = 0;
79 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags); 82 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
80 83
81 if (priv->user_scan_cfg) { 84 if (priv->scan_request) {
82 if (priv->scan_request) { 85 dev_dbg(adapter->dev, "info: aborting scan\n");
83 dev_dbg(priv->adapter->dev, 86 cfg80211_scan_done(priv->scan_request, 1);
84 "info: aborting scan\n"); 87 priv->scan_request = NULL;
85 cfg80211_scan_done(priv->scan_request, 1); 88 } else {
86 priv->scan_request = NULL; 89 priv->scan_aborting = false;
87 } else { 90 dev_dbg(adapter->dev, "info: scan already aborted\n");
88 dev_dbg(priv->adapter->dev,
89 "info: scan already aborted\n");
90 }
91
92 kfree(priv->user_scan_cfg);
93 priv->user_scan_cfg = NULL;
94 } 91 }
95 goto done; 92 goto done;
96 } 93 }
@@ -447,23 +444,29 @@ static void mwifiex_free_lock_list(struct mwifiex_adapter *adapter)
447} 444}
448 445
449/* 446/*
450 * This function frees the adapter structure. 447 * This function performs cleanup for adapter structure.
451 * 448 *
452 * The freeing operation is done recursively, by canceling all 449 * The cleanup is done recursively, by canceling all pending
453 * pending commands, freeing the member buffers previously 450 * commands, freeing the member buffers previously allocated
454 * allocated (command buffers, scan table buffer, sleep confirm 451 * (command buffers, scan table buffer, sleep confirm command
455 * command buffer), stopping the timers and calling the cleanup 452 * buffer), stopping the timers and calling the cleanup routines
456 * routines for every interface, before the actual adapter 453 * for every interface.
457 * structure is freed.
458 */ 454 */
459static void 455static void
460mwifiex_free_adapter(struct mwifiex_adapter *adapter) 456mwifiex_adapter_cleanup(struct mwifiex_adapter *adapter)
461{ 457{
458 int i;
459
462 if (!adapter) { 460 if (!adapter) {
463 pr_err("%s: adapter is NULL\n", __func__); 461 pr_err("%s: adapter is NULL\n", __func__);
464 return; 462 return;
465 } 463 }
466 464
465 for (i = 0; i < adapter->priv_num; i++) {
466 if (adapter->priv[i])
467 del_timer_sync(&adapter->priv[i]->scan_delay_timer);
468 }
469
467 mwifiex_cancel_all_pending_cmd(adapter); 470 mwifiex_cancel_all_pending_cmd(adapter);
468 471
469 /* Free lock variables */ 472 /* Free lock variables */
@@ -684,7 +687,6 @@ mwifiex_shutdown_drv(struct mwifiex_adapter *adapter)
684 int ret = -EINPROGRESS; 687 int ret = -EINPROGRESS;
685 struct mwifiex_private *priv; 688 struct mwifiex_private *priv;
686 s32 i; 689 s32 i;
687 unsigned long flags;
688 struct sk_buff *skb; 690 struct sk_buff *skb;
689 691
690 /* mwifiex already shutdown */ 692 /* mwifiex already shutdown */
@@ -719,7 +721,7 @@ mwifiex_shutdown_drv(struct mwifiex_adapter *adapter)
719 } 721 }
720 } 722 }
721 723
722 spin_lock_irqsave(&adapter->mwifiex_lock, flags); 724 spin_lock(&adapter->mwifiex_lock);
723 725
724 if (adapter->if_ops.data_complete) { 726 if (adapter->if_ops.data_complete) {
725 while ((skb = skb_dequeue(&adapter->usb_rx_data_q))) { 727 while ((skb = skb_dequeue(&adapter->usb_rx_data_q))) {
@@ -733,10 +735,9 @@ mwifiex_shutdown_drv(struct mwifiex_adapter *adapter)
733 } 735 }
734 } 736 }
735 737
736 /* Free adapter structure */ 738 mwifiex_adapter_cleanup(adapter);
737 mwifiex_free_adapter(adapter);
738 739
739 spin_unlock_irqrestore(&adapter->mwifiex_lock, flags); 740 spin_unlock(&adapter->mwifiex_lock);
740 741
741 /* Notify completion */ 742 /* Notify completion */
742 ret = mwifiex_shutdown_fw_complete(adapter); 743 ret = mwifiex_shutdown_fw_complete(adapter);
diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c
index 6bcb66e6e97c..122175af18c6 100644
--- a/drivers/net/wireless/mwifiex/join.c
+++ b/drivers/net/wireless/mwifiex/join.c
@@ -919,9 +919,8 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv,
919 memcpy(&priv->curr_bss_params.data_rates, 919 memcpy(&priv->curr_bss_params.data_rates,
920 &adhoc_start->data_rate, priv->curr_bss_params.num_of_rates); 920 &adhoc_start->data_rate, priv->curr_bss_params.num_of_rates);
921 921
922 dev_dbg(adapter->dev, "info: ADHOC_S_CMD: rates=%02x %02x %02x %02x\n", 922 dev_dbg(adapter->dev, "info: ADHOC_S_CMD: rates=%4ph\n",
923 adhoc_start->data_rate[0], adhoc_start->data_rate[1], 923 adhoc_start->data_rate);
924 adhoc_start->data_rate[2], adhoc_start->data_rate[3]);
925 924
926 dev_dbg(adapter->dev, "info: ADHOC_S_CMD: AD-HOC Start command is ready\n"); 925 dev_dbg(adapter->dev, "info: ADHOC_S_CMD: AD-HOC Start command is ready\n");
927 926
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
index 2eb88ea9acf7..5bc7ef8d04d6 100644
--- a/drivers/net/wireless/mwifiex/main.c
+++ b/drivers/net/wireless/mwifiex/main.c
@@ -25,6 +25,8 @@
25#define VERSION "1.0" 25#define VERSION "1.0"
26 26
27const char driver_version[] = "mwifiex " VERSION " (%s) "; 27const char driver_version[] = "mwifiex " VERSION " (%s) ";
28static char *cal_data_cfg;
29module_param(cal_data_cfg, charp, 0);
28 30
29/* 31/*
30 * This function registers the device and performs all the necessary 32 * This function registers the device and performs all the necessary
@@ -336,6 +338,13 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context)
336 338
337 dev_notice(adapter->dev, "WLAN FW is active\n"); 339 dev_notice(adapter->dev, "WLAN FW is active\n");
338 340
341 if (cal_data_cfg) {
342 if ((request_firmware(&adapter->cal_data, cal_data_cfg,
343 adapter->dev)) < 0)
344 dev_err(adapter->dev,
345 "Cal data request_firmware() failed\n");
346 }
347
339 adapter->init_wait_q_woken = false; 348 adapter->init_wait_q_woken = false;
340 ret = mwifiex_init_fw(adapter); 349 ret = mwifiex_init_fw(adapter);
341 if (ret == -1) { 350 if (ret == -1) {
@@ -390,6 +399,10 @@ err_init_fw:
390 pr_debug("info: %s: unregister device\n", __func__); 399 pr_debug("info: %s: unregister device\n", __func__);
391 adapter->if_ops.unregister_dev(adapter); 400 adapter->if_ops.unregister_dev(adapter);
392done: 401done:
402 if (adapter->cal_data) {
403 release_firmware(adapter->cal_data);
404 adapter->cal_data = NULL;
405 }
393 release_firmware(adapter->firmware); 406 release_firmware(adapter->firmware);
394 complete(&adapter->fw_load); 407 complete(&adapter->fw_load);
395 return; 408 return;
@@ -436,6 +449,7 @@ mwifiex_close(struct net_device *dev)
436 dev_dbg(priv->adapter->dev, "aborting scan on ndo_stop\n"); 449 dev_dbg(priv->adapter->dev, "aborting scan on ndo_stop\n");
437 cfg80211_scan_done(priv->scan_request, 1); 450 cfg80211_scan_done(priv->scan_request, 1);
438 priv->scan_request = NULL; 451 priv->scan_request = NULL;
452 priv->scan_aborting = true;
439 } 453 }
440 454
441 return 0; 455 return 0;
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index 4ef67fca06d3..0832c2437daf 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -492,7 +492,6 @@ struct mwifiex_private {
492 struct semaphore async_sem; 492 struct semaphore async_sem;
493 u8 report_scan_result; 493 u8 report_scan_result;
494 struct cfg80211_scan_request *scan_request; 494 struct cfg80211_scan_request *scan_request;
495 struct mwifiex_user_scan_cfg *user_scan_cfg;
496 u8 cfg_bssid[6]; 495 u8 cfg_bssid[6];
497 struct wps wps; 496 struct wps wps;
498 u8 scan_block; 497 u8 scan_block;
@@ -510,6 +509,7 @@ struct mwifiex_private {
510 u8 ap_11ac_enabled; 509 u8 ap_11ac_enabled;
511 u32 mgmt_frame_mask; 510 u32 mgmt_frame_mask;
512 struct mwifiex_roc_cfg roc_cfg; 511 struct mwifiex_roc_cfg roc_cfg;
512 bool scan_aborting;
513}; 513};
514 514
515enum mwifiex_ba_status { 515enum mwifiex_ba_status {
@@ -730,6 +730,7 @@ struct mwifiex_adapter {
730 u16 max_mgmt_ie_index; 730 u16 max_mgmt_ie_index;
731 u8 scan_delay_cnt; 731 u8 scan_delay_cnt;
732 u8 empty_tx_q_cnt; 732 u8 empty_tx_q_cnt;
733 const struct firmware *cal_data;
733 734
734 /* 11AC */ 735 /* 11AC */
735 u32 is_hw_11ac_capable; 736 u32 is_hw_11ac_capable;
@@ -1115,6 +1116,8 @@ int mwifiex_set_mgmt_ies(struct mwifiex_private *priv,
1115 struct cfg80211_beacon_data *data); 1116 struct cfg80211_beacon_data *data);
1116int mwifiex_del_mgmt_ies(struct mwifiex_private *priv); 1117int mwifiex_del_mgmt_ies(struct mwifiex_private *priv);
1117u8 *mwifiex_11d_code_2_region(u8 code); 1118u8 *mwifiex_11d_code_2_region(u8 code);
1119void mwifiex_uap_del_sta_data(struct mwifiex_private *priv,
1120 struct mwifiex_sta_node *node);
1118 1121
1119extern const struct ethtool_ops mwifiex_ethtool_ops; 1122extern const struct ethtool_ops mwifiex_ethtool_ops;
1120 1123
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c
index 9cf5d8f07df8..801b6b728379 100644
--- a/drivers/net/wireless/mwifiex/scan.c
+++ b/drivers/net/wireless/mwifiex/scan.c
@@ -1784,22 +1784,17 @@ check_next_scan:
1784 if (priv->report_scan_result) 1784 if (priv->report_scan_result)
1785 priv->report_scan_result = false; 1785 priv->report_scan_result = false;
1786 1786
1787 if (priv->user_scan_cfg) { 1787 if (priv->scan_request) {
1788 if (priv->scan_request) { 1788 dev_dbg(adapter->dev, "info: notifying scan done\n");
1789 dev_dbg(priv->adapter->dev, 1789 cfg80211_scan_done(priv->scan_request, 0);
1790 "info: notifying scan done\n"); 1790 priv->scan_request = NULL;
1791 cfg80211_scan_done(priv->scan_request, 0); 1791 } else {
1792 priv->scan_request = NULL; 1792 priv->scan_aborting = false;
1793 } else { 1793 dev_dbg(adapter->dev, "info: scan already aborted\n");
1794 dev_dbg(priv->adapter->dev,
1795 "info: scan already aborted\n");
1796 }
1797
1798 kfree(priv->user_scan_cfg);
1799 priv->user_scan_cfg = NULL;
1800 } 1794 }
1801 } else { 1795 } else {
1802 if (priv->user_scan_cfg && !priv->scan_request) { 1796 if ((priv->scan_aborting && !priv->scan_request) ||
1797 priv->scan_block) {
1803 spin_unlock_irqrestore(&adapter->scan_pending_q_lock, 1798 spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
1804 flags); 1799 flags);
1805 adapter->scan_delay_cnt = MWIFIEX_MAX_SCAN_DELAY_CNT; 1800 adapter->scan_delay_cnt = MWIFIEX_MAX_SCAN_DELAY_CNT;
diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c
index 363ba31b58bf..5ee5ed02eccd 100644
--- a/drivers/net/wireless/mwifiex/sdio.c
+++ b/drivers/net/wireless/mwifiex/sdio.c
@@ -77,6 +77,17 @@ mwifiex_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id)
77 77
78 func->card->quirks |= MMC_QUIRK_BLKSZ_FOR_BYTE_MODE; 78 func->card->quirks |= MMC_QUIRK_BLKSZ_FOR_BYTE_MODE;
79 79
80 if (id->driver_data) {
81 struct mwifiex_sdio_device *data = (void *)id->driver_data;
82
83 card->firmware = data->firmware;
84 card->reg = data->reg;
85 card->max_ports = data->max_ports;
86 card->mp_agg_pkt_limit = data->mp_agg_pkt_limit;
87 card->supports_sdio_new_mode = data->supports_sdio_new_mode;
88 card->has_control_mask = data->has_control_mask;
89 }
90
80 sdio_claim_host(func); 91 sdio_claim_host(func);
81 ret = sdio_enable_func(func); 92 ret = sdio_enable_func(func);
82 sdio_release_host(func); 93 sdio_release_host(func);
@@ -251,12 +262,19 @@ static int mwifiex_sdio_resume(struct device *dev)
251#define SDIO_DEVICE_ID_MARVELL_8787 (0x9119) 262#define SDIO_DEVICE_ID_MARVELL_8787 (0x9119)
252/* Device ID for SD8797 */ 263/* Device ID for SD8797 */
253#define SDIO_DEVICE_ID_MARVELL_8797 (0x9129) 264#define SDIO_DEVICE_ID_MARVELL_8797 (0x9129)
265/* Device ID for SD8897 */
266#define SDIO_DEVICE_ID_MARVELL_8897 (0x912d)
254 267
255/* WLAN IDs */ 268/* WLAN IDs */
256static const struct sdio_device_id mwifiex_ids[] = { 269static const struct sdio_device_id mwifiex_ids[] = {
257 {SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8786)}, 270 {SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8786),
258 {SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8787)}, 271 .driver_data = (unsigned long) &mwifiex_sdio_sd8786},
259 {SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8797)}, 272 {SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8787),
273 .driver_data = (unsigned long) &mwifiex_sdio_sd8787},
274 {SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8797),
275 .driver_data = (unsigned long) &mwifiex_sdio_sd8797},
276 {SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8897),
277 .driver_data = (unsigned long) &mwifiex_sdio_sd8897},
260 {}, 278 {},
261}; 279};
262 280
@@ -282,13 +300,13 @@ static struct sdio_driver mwifiex_sdio = {
282 * This function writes data into SDIO card register. 300 * This function writes data into SDIO card register.
283 */ 301 */
284static int 302static int
285mwifiex_write_reg(struct mwifiex_adapter *adapter, u32 reg, u32 data) 303mwifiex_write_reg(struct mwifiex_adapter *adapter, u32 reg, u8 data)
286{ 304{
287 struct sdio_mmc_card *card = adapter->card; 305 struct sdio_mmc_card *card = adapter->card;
288 int ret = -1; 306 int ret = -1;
289 307
290 sdio_claim_host(card->func); 308 sdio_claim_host(card->func);
291 sdio_writeb(card->func, (u8) data, reg, &ret); 309 sdio_writeb(card->func, data, reg, &ret);
292 sdio_release_host(card->func); 310 sdio_release_host(card->func);
293 311
294 return ret; 312 return ret;
@@ -298,7 +316,7 @@ mwifiex_write_reg(struct mwifiex_adapter *adapter, u32 reg, u32 data)
298 * This function reads data from SDIO card register. 316 * This function reads data from SDIO card register.
299 */ 317 */
300static int 318static int
301mwifiex_read_reg(struct mwifiex_adapter *adapter, u32 reg, u32 *data) 319mwifiex_read_reg(struct mwifiex_adapter *adapter, u32 reg, u8 *data)
302{ 320{
303 struct sdio_mmc_card *card = adapter->card; 321 struct sdio_mmc_card *card = adapter->card;
304 int ret = -1; 322 int ret = -1;
@@ -400,7 +418,40 @@ static int mwifiex_pm_wakeup_card_complete(struct mwifiex_adapter *adapter)
400} 418}
401 419
402/* 420/*
403 * This function initializes the IO ports. 421 * This function is used to initialize IO ports for the
422 * chipsets supporting SDIO new mode eg SD8897.
423 */
424static int mwifiex_init_sdio_new_mode(struct mwifiex_adapter *adapter)
425{
426 u8 reg;
427
428 adapter->ioport = MEM_PORT;
429
430 /* enable sdio new mode */
431 if (mwifiex_read_reg(adapter, CARD_CONFIG_2_1_REG, &reg))
432 return -1;
433 if (mwifiex_write_reg(adapter, CARD_CONFIG_2_1_REG,
434 reg | CMD53_NEW_MODE))
435 return -1;
436
437 /* Configure cmd port and enable reading rx length from the register */
438 if (mwifiex_read_reg(adapter, CMD_CONFIG_0, &reg))
439 return -1;
440 if (mwifiex_write_reg(adapter, CMD_CONFIG_0, reg | CMD_PORT_RD_LEN_EN))
441 return -1;
442
443 /* Enable Dnld/Upld ready auto reset for cmd port after cmd53 is
444 * completed
445 */
446 if (mwifiex_read_reg(adapter, CMD_CONFIG_1, &reg))
447 return -1;
448 if (mwifiex_write_reg(adapter, CMD_CONFIG_1, reg | CMD_PORT_AUTO_EN))
449 return -1;
450
451 return 0;
452}
453
454/* This function initializes the IO ports.
404 * 455 *
405 * The following operations are performed - 456 * The following operations are performed -
406 * - Read the IO ports (0, 1 and 2) 457 * - Read the IO ports (0, 1 and 2)
@@ -409,10 +460,17 @@ static int mwifiex_pm_wakeup_card_complete(struct mwifiex_adapter *adapter)
409 */ 460 */
410static int mwifiex_init_sdio_ioport(struct mwifiex_adapter *adapter) 461static int mwifiex_init_sdio_ioport(struct mwifiex_adapter *adapter)
411{ 462{
412 u32 reg; 463 u8 reg;
464 struct sdio_mmc_card *card = adapter->card;
413 465
414 adapter->ioport = 0; 466 adapter->ioport = 0;
415 467
468 if (card->supports_sdio_new_mode) {
469 if (mwifiex_init_sdio_new_mode(adapter))
470 return -1;
471 goto cont;
472 }
473
416 /* Read the IO port */ 474 /* Read the IO port */
417 if (!mwifiex_read_reg(adapter, IO_PORT_0_REG, &reg)) 475 if (!mwifiex_read_reg(adapter, IO_PORT_0_REG, &reg))
418 adapter->ioport |= (reg & 0xff); 476 adapter->ioport |= (reg & 0xff);
@@ -428,19 +486,19 @@ static int mwifiex_init_sdio_ioport(struct mwifiex_adapter *adapter)
428 adapter->ioport |= ((reg & 0xff) << 16); 486 adapter->ioport |= ((reg & 0xff) << 16);
429 else 487 else
430 return -1; 488 return -1;
431 489cont:
432 pr_debug("info: SDIO FUNC1 IO port: %#x\n", adapter->ioport); 490 pr_debug("info: SDIO FUNC1 IO port: %#x\n", adapter->ioport);
433 491
434 /* Set Host interrupt reset to read to clear */ 492 /* Set Host interrupt reset to read to clear */
435 if (!mwifiex_read_reg(adapter, HOST_INT_RSR_REG, &reg)) 493 if (!mwifiex_read_reg(adapter, HOST_INT_RSR_REG, &reg))
436 mwifiex_write_reg(adapter, HOST_INT_RSR_REG, 494 mwifiex_write_reg(adapter, HOST_INT_RSR_REG,
437 reg | SDIO_INT_MASK); 495 reg | card->reg->sdio_int_mask);
438 else 496 else
439 return -1; 497 return -1;
440 498
441 /* Dnld/Upld ready set to auto reset */ 499 /* Dnld/Upld ready set to auto reset */
442 if (!mwifiex_read_reg(adapter, CARD_MISC_CFG_REG, &reg)) 500 if (!mwifiex_read_reg(adapter, card->reg->card_misc_cfg_reg, &reg))
443 mwifiex_write_reg(adapter, CARD_MISC_CFG_REG, 501 mwifiex_write_reg(adapter, card->reg->card_misc_cfg_reg,
444 reg | AUTO_RE_ENABLE_INT); 502 reg | AUTO_RE_ENABLE_INT);
445 else 503 else
446 return -1; 504 return -1;
@@ -486,34 +544,42 @@ static int mwifiex_write_data_to_card(struct mwifiex_adapter *adapter,
486static int mwifiex_get_rd_port(struct mwifiex_adapter *adapter, u8 *port) 544static int mwifiex_get_rd_port(struct mwifiex_adapter *adapter, u8 *port)
487{ 545{
488 struct sdio_mmc_card *card = adapter->card; 546 struct sdio_mmc_card *card = adapter->card;
489 u16 rd_bitmap = card->mp_rd_bitmap; 547 const struct mwifiex_sdio_card_reg *reg = card->reg;
548 u32 rd_bitmap = card->mp_rd_bitmap;
490 549
491 dev_dbg(adapter->dev, "data: mp_rd_bitmap=0x%04x\n", rd_bitmap); 550 dev_dbg(adapter->dev, "data: mp_rd_bitmap=0x%08x\n", rd_bitmap);
492 551
493 if (!(rd_bitmap & (CTRL_PORT_MASK | DATA_PORT_MASK))) 552 if (card->supports_sdio_new_mode) {
494 return -1; 553 if (!(rd_bitmap & reg->data_port_mask))
554 return -1;
555 } else {
556 if (!(rd_bitmap & (CTRL_PORT_MASK | reg->data_port_mask)))
557 return -1;
558 }
495 559
496 if (card->mp_rd_bitmap & CTRL_PORT_MASK) { 560 if ((card->has_control_mask) &&
497 card->mp_rd_bitmap &= (u16) (~CTRL_PORT_MASK); 561 (card->mp_rd_bitmap & CTRL_PORT_MASK)) {
562 card->mp_rd_bitmap &= (u32) (~CTRL_PORT_MASK);
498 *port = CTRL_PORT; 563 *port = CTRL_PORT;
499 dev_dbg(adapter->dev, "data: port=%d mp_rd_bitmap=0x%04x\n", 564 dev_dbg(adapter->dev, "data: port=%d mp_rd_bitmap=0x%08x\n",
500 *port, card->mp_rd_bitmap); 565 *port, card->mp_rd_bitmap);
501 } else { 566 return 0;
502 if (card->mp_rd_bitmap & (1 << card->curr_rd_port)) { 567 }
503 card->mp_rd_bitmap &= (u16)
504 (~(1 << card->curr_rd_port));
505 *port = card->curr_rd_port;
506 568
507 if (++card->curr_rd_port == MAX_PORT) 569 if (!(card->mp_rd_bitmap & (1 << card->curr_rd_port)))
508 card->curr_rd_port = 1; 570 return -1;
509 } else { 571
510 return -1; 572 /* We are now handling the SDIO data ports */
511 } 573 card->mp_rd_bitmap &= (u32)(~(1 << card->curr_rd_port));
574 *port = card->curr_rd_port;
575
576 if (++card->curr_rd_port == card->max_ports)
577 card->curr_rd_port = reg->start_rd_port;
578
579 dev_dbg(adapter->dev,
580 "data: port=%d mp_rd_bitmap=0x%08x -> 0x%08x\n",
581 *port, rd_bitmap, card->mp_rd_bitmap);
512 582
513 dev_dbg(adapter->dev,
514 "data: port=%d mp_rd_bitmap=0x%04x -> 0x%04x\n",
515 *port, rd_bitmap, card->mp_rd_bitmap);
516 }
517 return 0; 583 return 0;
518} 584}
519 585
@@ -524,35 +590,45 @@ static int mwifiex_get_rd_port(struct mwifiex_adapter *adapter, u8 *port)
524 * increased (provided it does not reach the maximum limit, in which 590 * increased (provided it does not reach the maximum limit, in which
525 * case it is reset to 1) 591 * case it is reset to 1)
526 */ 592 */
527static int mwifiex_get_wr_port_data(struct mwifiex_adapter *adapter, u8 *port) 593static int mwifiex_get_wr_port_data(struct mwifiex_adapter *adapter, u32 *port)
528{ 594{
529 struct sdio_mmc_card *card = adapter->card; 595 struct sdio_mmc_card *card = adapter->card;
530 u16 wr_bitmap = card->mp_wr_bitmap; 596 const struct mwifiex_sdio_card_reg *reg = card->reg;
597 u32 wr_bitmap = card->mp_wr_bitmap;
531 598
532 dev_dbg(adapter->dev, "data: mp_wr_bitmap=0x%04x\n", wr_bitmap); 599 dev_dbg(adapter->dev, "data: mp_wr_bitmap=0x%08x\n", wr_bitmap);
533 600
534 if (!(wr_bitmap & card->mp_data_port_mask)) 601 if (card->supports_sdio_new_mode &&
602 !(wr_bitmap & reg->data_port_mask)) {
603 adapter->data_sent = true;
604 return -EBUSY;
605 } else if (!card->supports_sdio_new_mode &&
606 !(wr_bitmap & card->mp_data_port_mask)) {
535 return -1; 607 return -1;
608 }
536 609
537 if (card->mp_wr_bitmap & (1 << card->curr_wr_port)) { 610 if (card->mp_wr_bitmap & (1 << card->curr_wr_port)) {
538 card->mp_wr_bitmap &= (u16) (~(1 << card->curr_wr_port)); 611 card->mp_wr_bitmap &= (u32) (~(1 << card->curr_wr_port));
539 *port = card->curr_wr_port; 612 *port = card->curr_wr_port;
540 if (++card->curr_wr_port == card->mp_end_port) 613 if (((card->supports_sdio_new_mode) &&
541 card->curr_wr_port = 1; 614 (++card->curr_wr_port == card->max_ports)) ||
615 ((!card->supports_sdio_new_mode) &&
616 (++card->curr_wr_port == card->mp_end_port)))
617 card->curr_wr_port = reg->start_wr_port;
542 } else { 618 } else {
543 adapter->data_sent = true; 619 adapter->data_sent = true;
544 return -EBUSY; 620 return -EBUSY;
545 } 621 }
546 622
547 if (*port == CTRL_PORT) { 623 if ((card->has_control_mask) && (*port == CTRL_PORT)) {
548 dev_err(adapter->dev, "invalid data port=%d cur port=%d" 624 dev_err(adapter->dev,
549 " mp_wr_bitmap=0x%04x -> 0x%04x\n", 625 "invalid data port=%d cur port=%d mp_wr_bitmap=0x%08x -> 0x%08x\n",
550 *port, card->curr_wr_port, wr_bitmap, 626 *port, card->curr_wr_port, wr_bitmap,
551 card->mp_wr_bitmap); 627 card->mp_wr_bitmap);
552 return -1; 628 return -1;
553 } 629 }
554 630
555 dev_dbg(adapter->dev, "data: port=%d mp_wr_bitmap=0x%04x -> 0x%04x\n", 631 dev_dbg(adapter->dev, "data: port=%d mp_wr_bitmap=0x%08x -> 0x%08x\n",
556 *port, wr_bitmap, card->mp_wr_bitmap); 632 *port, wr_bitmap, card->mp_wr_bitmap);
557 633
558 return 0; 634 return 0;
@@ -564,11 +640,12 @@ static int mwifiex_get_wr_port_data(struct mwifiex_adapter *adapter, u8 *port)
564static int 640static int
565mwifiex_sdio_poll_card_status(struct mwifiex_adapter *adapter, u8 bits) 641mwifiex_sdio_poll_card_status(struct mwifiex_adapter *adapter, u8 bits)
566{ 642{
643 struct sdio_mmc_card *card = adapter->card;
567 u32 tries; 644 u32 tries;
568 u32 cs; 645 u8 cs;
569 646
570 for (tries = 0; tries < MAX_POLL_TRIES; tries++) { 647 for (tries = 0; tries < MAX_POLL_TRIES; tries++) {
571 if (mwifiex_read_reg(adapter, CARD_STATUS_REG, &cs)) 648 if (mwifiex_read_reg(adapter, card->reg->poll_reg, &cs))
572 break; 649 break;
573 else if ((cs & bits) == bits) 650 else if ((cs & bits) == bits)
574 return 0; 651 return 0;
@@ -587,12 +664,14 @@ mwifiex_sdio_poll_card_status(struct mwifiex_adapter *adapter, u8 bits)
587static int 664static int
588mwifiex_sdio_read_fw_status(struct mwifiex_adapter *adapter, u16 *dat) 665mwifiex_sdio_read_fw_status(struct mwifiex_adapter *adapter, u16 *dat)
589{ 666{
590 u32 fws0, fws1; 667 struct sdio_mmc_card *card = adapter->card;
668 const struct mwifiex_sdio_card_reg *reg = card->reg;
669 u8 fws0, fws1;
591 670
592 if (mwifiex_read_reg(adapter, CARD_FW_STATUS0_REG, &fws0)) 671 if (mwifiex_read_reg(adapter, reg->status_reg_0, &fws0))
593 return -1; 672 return -1;
594 673
595 if (mwifiex_read_reg(adapter, CARD_FW_STATUS1_REG, &fws1)) 674 if (mwifiex_read_reg(adapter, reg->status_reg_1, &fws1))
596 return -1; 675 return -1;
597 676
598 *dat = (u16) ((fws1 << 8) | fws0); 677 *dat = (u16) ((fws1 << 8) | fws0);
@@ -608,14 +687,14 @@ mwifiex_sdio_read_fw_status(struct mwifiex_adapter *adapter, u16 *dat)
608 */ 687 */
609static int mwifiex_sdio_disable_host_int(struct mwifiex_adapter *adapter) 688static int mwifiex_sdio_disable_host_int(struct mwifiex_adapter *adapter)
610{ 689{
611 u32 host_int_mask; 690 u8 host_int_mask, host_int_disable = HOST_INT_DISABLE;
612 691
613 /* Read back the host_int_mask register */ 692 /* Read back the host_int_mask register */
614 if (mwifiex_read_reg(adapter, HOST_INT_MASK_REG, &host_int_mask)) 693 if (mwifiex_read_reg(adapter, HOST_INT_MASK_REG, &host_int_mask))
615 return -1; 694 return -1;
616 695
617 /* Update with the mask and write back to the register */ 696 /* Update with the mask and write back to the register */
618 host_int_mask &= ~HOST_INT_DISABLE; 697 host_int_mask &= ~host_int_disable;
619 698
620 if (mwifiex_write_reg(adapter, HOST_INT_MASK_REG, host_int_mask)) { 699 if (mwifiex_write_reg(adapter, HOST_INT_MASK_REG, host_int_mask)) {
621 dev_err(adapter->dev, "disable host interrupt failed\n"); 700 dev_err(adapter->dev, "disable host interrupt failed\n");
@@ -633,8 +712,11 @@ static int mwifiex_sdio_disable_host_int(struct mwifiex_adapter *adapter)
633 */ 712 */
634static int mwifiex_sdio_enable_host_int(struct mwifiex_adapter *adapter) 713static int mwifiex_sdio_enable_host_int(struct mwifiex_adapter *adapter)
635{ 714{
715 struct sdio_mmc_card *card = adapter->card;
716
636 /* Simply write the mask to the register */ 717 /* Simply write the mask to the register */
637 if (mwifiex_write_reg(adapter, HOST_INT_MASK_REG, HOST_INT_ENABLE)) { 718 if (mwifiex_write_reg(adapter, HOST_INT_MASK_REG,
719 card->reg->host_int_enable)) {
638 dev_err(adapter->dev, "enable host interrupt failed\n"); 720 dev_err(adapter->dev, "enable host interrupt failed\n");
639 return -1; 721 return -1;
640 } 722 }
@@ -686,11 +768,13 @@ static int mwifiex_sdio_card_to_host(struct mwifiex_adapter *adapter,
686static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, 768static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
687 struct mwifiex_fw_image *fw) 769 struct mwifiex_fw_image *fw)
688{ 770{
771 struct sdio_mmc_card *card = adapter->card;
772 const struct mwifiex_sdio_card_reg *reg = card->reg;
689 int ret; 773 int ret;
690 u8 *firmware = fw->fw_buf; 774 u8 *firmware = fw->fw_buf;
691 u32 firmware_len = fw->fw_len; 775 u32 firmware_len = fw->fw_len;
692 u32 offset = 0; 776 u32 offset = 0;
693 u32 base0, base1; 777 u8 base0, base1;
694 u8 *fwbuf; 778 u8 *fwbuf;
695 u16 len = 0; 779 u16 len = 0;
696 u32 txlen, tx_blocks = 0, tries; 780 u32 txlen, tx_blocks = 0, tries;
@@ -727,7 +811,7 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
727 break; 811 break;
728 812
729 for (tries = 0; tries < MAX_POLL_TRIES; tries++) { 813 for (tries = 0; tries < MAX_POLL_TRIES; tries++) {
730 ret = mwifiex_read_reg(adapter, HOST_F1_RD_BASE_0, 814 ret = mwifiex_read_reg(adapter, reg->base_0_reg,
731 &base0); 815 &base0);
732 if (ret) { 816 if (ret) {
733 dev_err(adapter->dev, 817 dev_err(adapter->dev,
@@ -736,7 +820,7 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
736 base0, base0); 820 base0, base0);
737 goto done; 821 goto done;
738 } 822 }
739 ret = mwifiex_read_reg(adapter, HOST_F1_RD_BASE_1, 823 ret = mwifiex_read_reg(adapter, reg->base_1_reg,
740 &base1); 824 &base1);
741 if (ret) { 825 if (ret) {
742 dev_err(adapter->dev, 826 dev_err(adapter->dev,
@@ -828,10 +912,11 @@ done:
828static int mwifiex_check_fw_status(struct mwifiex_adapter *adapter, 912static int mwifiex_check_fw_status(struct mwifiex_adapter *adapter,
829 u32 poll_num) 913 u32 poll_num)
830{ 914{
915 struct sdio_mmc_card *card = adapter->card;
831 int ret = 0; 916 int ret = 0;
832 u16 firmware_stat; 917 u16 firmware_stat;
833 u32 tries; 918 u32 tries;
834 u32 winner_status; 919 u8 winner_status;
835 920
836 /* Wait for firmware initialization event */ 921 /* Wait for firmware initialization event */
837 for (tries = 0; tries < poll_num; tries++) { 922 for (tries = 0; tries < poll_num; tries++) {
@@ -849,7 +934,7 @@ static int mwifiex_check_fw_status(struct mwifiex_adapter *adapter,
849 934
850 if (ret) { 935 if (ret) {
851 if (mwifiex_read_reg 936 if (mwifiex_read_reg
852 (adapter, CARD_FW_STATUS0_REG, &winner_status)) 937 (adapter, card->reg->status_reg_0, &winner_status))
853 winner_status = 0; 938 winner_status = 0;
854 939
855 if (winner_status) 940 if (winner_status)
@@ -866,12 +951,12 @@ static int mwifiex_check_fw_status(struct mwifiex_adapter *adapter,
866static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter) 951static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter)
867{ 952{
868 struct sdio_mmc_card *card = adapter->card; 953 struct sdio_mmc_card *card = adapter->card;
869 u32 sdio_ireg; 954 u8 sdio_ireg;
870 unsigned long flags; 955 unsigned long flags;
871 956
872 if (mwifiex_read_data_sync(adapter, card->mp_regs, MAX_MP_REGS, 957 if (mwifiex_read_data_sync(adapter, card->mp_regs,
873 REG_PORT | MWIFIEX_SDIO_BYTE_MODE_MASK, 958 card->reg->max_mp_regs,
874 0)) { 959 REG_PORT | MWIFIEX_SDIO_BYTE_MODE_MASK, 0)) {
875 dev_err(adapter->dev, "read mp_regs failed\n"); 960 dev_err(adapter->dev, "read mp_regs failed\n");
876 return; 961 return;
877 } 962 }
@@ -880,6 +965,9 @@ static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter)
880 if (sdio_ireg) { 965 if (sdio_ireg) {
881 /* 966 /*
882 * DN_LD_HOST_INT_STATUS and/or UP_LD_HOST_INT_STATUS 967 * DN_LD_HOST_INT_STATUS and/or UP_LD_HOST_INT_STATUS
968 * For SDIO new mode CMD port interrupts
969 * DN_LD_CMD_PORT_HOST_INT_STATUS and/or
970 * UP_LD_CMD_PORT_HOST_INT_STATUS
883 * Clear the interrupt status register 971 * Clear the interrupt status register
884 */ 972 */
885 dev_dbg(adapter->dev, "int: sdio_ireg = %#x\n", sdio_ireg); 973 dev_dbg(adapter->dev, "int: sdio_ireg = %#x\n", sdio_ireg);
@@ -1003,11 +1091,11 @@ static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter,
1003 s32 f_aggr_cur = 0; 1091 s32 f_aggr_cur = 0;
1004 struct sk_buff *skb_deaggr; 1092 struct sk_buff *skb_deaggr;
1005 u32 pind; 1093 u32 pind;
1006 u32 pkt_len, pkt_type = 0; 1094 u32 pkt_len, pkt_type, mport;
1007 u8 *curr_ptr; 1095 u8 *curr_ptr;
1008 u32 rx_len = skb->len; 1096 u32 rx_len = skb->len;
1009 1097
1010 if (port == CTRL_PORT) { 1098 if ((card->has_control_mask) && (port == CTRL_PORT)) {
1011 /* Read the command Resp without aggr */ 1099 /* Read the command Resp without aggr */
1012 dev_dbg(adapter->dev, "info: %s: no aggregation for cmd " 1100 dev_dbg(adapter->dev, "info: %s: no aggregation for cmd "
1013 "response\n", __func__); 1101 "response\n", __func__);
@@ -1024,7 +1112,10 @@ static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter,
1024 goto rx_curr_single; 1112 goto rx_curr_single;
1025 } 1113 }
1026 1114
1027 if (card->mp_rd_bitmap & (~((u16) CTRL_PORT_MASK))) { 1115 if ((!card->has_control_mask && (card->mp_rd_bitmap &
1116 card->reg->data_port_mask)) ||
1117 (card->has_control_mask && (card->mp_rd_bitmap &
1118 (~((u32) CTRL_PORT_MASK))))) {
1028 /* Some more data RX pending */ 1119 /* Some more data RX pending */
1029 dev_dbg(adapter->dev, "info: %s: not last packet\n", __func__); 1120 dev_dbg(adapter->dev, "info: %s: not last packet\n", __func__);
1030 1121
@@ -1060,10 +1151,10 @@ static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter,
1060 if (f_aggr_cur) { 1151 if (f_aggr_cur) {
1061 dev_dbg(adapter->dev, "info: current packet aggregation\n"); 1152 dev_dbg(adapter->dev, "info: current packet aggregation\n");
1062 /* Curr pkt can be aggregated */ 1153 /* Curr pkt can be aggregated */
1063 MP_RX_AGGR_SETUP(card, skb, port); 1154 mp_rx_aggr_setup(card, skb, port);
1064 1155
1065 if (MP_RX_AGGR_PKT_LIMIT_REACHED(card) || 1156 if (MP_RX_AGGR_PKT_LIMIT_REACHED(card) ||
1066 MP_RX_AGGR_PORT_LIMIT_REACHED(card)) { 1157 mp_rx_aggr_port_limit_reached(card)) {
1067 dev_dbg(adapter->dev, "info: %s: aggregated packet " 1158 dev_dbg(adapter->dev, "info: %s: aggregated packet "
1068 "limit reached\n", __func__); 1159 "limit reached\n", __func__);
1069 /* No more pkts allowed in Aggr buf, rx it */ 1160 /* No more pkts allowed in Aggr buf, rx it */
@@ -1076,11 +1167,28 @@ static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter,
1076 dev_dbg(adapter->dev, "info: do_rx_aggr: num of packets: %d\n", 1167 dev_dbg(adapter->dev, "info: do_rx_aggr: num of packets: %d\n",
1077 card->mpa_rx.pkt_cnt); 1168 card->mpa_rx.pkt_cnt);
1078 1169
1170 if (card->supports_sdio_new_mode) {
1171 int i;
1172 u32 port_count;
1173
1174 for (i = 0, port_count = 0; i < card->max_ports; i++)
1175 if (card->mpa_rx.ports & BIT(i))
1176 port_count++;
1177
1178 /* Reading data from "start_port + 0" to "start_port +
1179 * port_count -1", so decrease the count by 1
1180 */
1181 port_count--;
1182 mport = (adapter->ioport | SDIO_MPA_ADDR_BASE |
1183 (port_count << 8)) + card->mpa_rx.start_port;
1184 } else {
1185 mport = (adapter->ioport | SDIO_MPA_ADDR_BASE |
1186 (card->mpa_rx.ports << 4)) +
1187 card->mpa_rx.start_port;
1188 }
1189
1079 if (mwifiex_read_data_sync(adapter, card->mpa_rx.buf, 1190 if (mwifiex_read_data_sync(adapter, card->mpa_rx.buf,
1080 card->mpa_rx.buf_len, 1191 card->mpa_rx.buf_len, mport, 1))
1081 (adapter->ioport | 0x1000 |
1082 (card->mpa_rx.ports << 4)) +
1083 card->mpa_rx.start_port, 1))
1084 goto error; 1192 goto error;
1085 1193
1086 curr_ptr = card->mpa_rx.buf; 1194 curr_ptr = card->mpa_rx.buf;
@@ -1167,6 +1275,7 @@ error:
1167static int mwifiex_process_int_status(struct mwifiex_adapter *adapter) 1275static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
1168{ 1276{
1169 struct sdio_mmc_card *card = adapter->card; 1277 struct sdio_mmc_card *card = adapter->card;
1278 const struct mwifiex_sdio_card_reg *reg = card->reg;
1170 int ret = 0; 1279 int ret = 0;
1171 u8 sdio_ireg; 1280 u8 sdio_ireg;
1172 struct sk_buff *skb; 1281 struct sk_buff *skb;
@@ -1175,6 +1284,8 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
1175 u32 rx_blocks; 1284 u32 rx_blocks;
1176 u16 rx_len; 1285 u16 rx_len;
1177 unsigned long flags; 1286 unsigned long flags;
1287 u32 bitmap;
1288 u8 cr;
1178 1289
1179 spin_lock_irqsave(&adapter->int_lock, flags); 1290 spin_lock_irqsave(&adapter->int_lock, flags);
1180 sdio_ireg = adapter->int_status; 1291 sdio_ireg = adapter->int_status;
@@ -1184,10 +1295,60 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
1184 if (!sdio_ireg) 1295 if (!sdio_ireg)
1185 return ret; 1296 return ret;
1186 1297
1298 /* Following interrupt is only for SDIO new mode */
1299 if (sdio_ireg & DN_LD_CMD_PORT_HOST_INT_STATUS && adapter->cmd_sent)
1300 adapter->cmd_sent = false;
1301
1302 /* Following interrupt is only for SDIO new mode */
1303 if (sdio_ireg & UP_LD_CMD_PORT_HOST_INT_STATUS) {
1304 u32 pkt_type;
1305
1306 /* read the len of control packet */
1307 rx_len = card->mp_regs[CMD_RD_LEN_1] << 8;
1308 rx_len |= (u16) card->mp_regs[CMD_RD_LEN_0];
1309 rx_blocks = DIV_ROUND_UP(rx_len, MWIFIEX_SDIO_BLOCK_SIZE);
1310 if (rx_len <= INTF_HEADER_LEN ||
1311 (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE) >
1312 MWIFIEX_RX_DATA_BUF_SIZE)
1313 return -1;
1314 rx_len = (u16) (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE);
1315
1316 skb = dev_alloc_skb(rx_len);
1317 if (!skb)
1318 return -1;
1319
1320 skb_put(skb, rx_len);
1321
1322 if (mwifiex_sdio_card_to_host(adapter, &pkt_type, skb->data,
1323 skb->len, adapter->ioport |
1324 CMD_PORT_SLCT)) {
1325 dev_err(adapter->dev,
1326 "%s: failed to card_to_host", __func__);
1327 dev_kfree_skb_any(skb);
1328 goto term_cmd;
1329 }
1330
1331 if ((pkt_type != MWIFIEX_TYPE_CMD) &&
1332 (pkt_type != MWIFIEX_TYPE_EVENT))
1333 dev_err(adapter->dev,
1334 "%s:Received wrong packet on cmd port",
1335 __func__);
1336
1337 mwifiex_decode_rx_packet(adapter, skb, pkt_type);
1338 }
1339
1187 if (sdio_ireg & DN_LD_HOST_INT_STATUS) { 1340 if (sdio_ireg & DN_LD_HOST_INT_STATUS) {
1188 card->mp_wr_bitmap = ((u16) card->mp_regs[WR_BITMAP_U]) << 8; 1341 bitmap = (u32) card->mp_regs[reg->wr_bitmap_l];
1189 card->mp_wr_bitmap |= (u16) card->mp_regs[WR_BITMAP_L]; 1342 bitmap |= ((u32) card->mp_regs[reg->wr_bitmap_u]) << 8;
1190 dev_dbg(adapter->dev, "int: DNLD: wr_bitmap=0x%04x\n", 1343 if (card->supports_sdio_new_mode) {
1344 bitmap |=
1345 ((u32) card->mp_regs[reg->wr_bitmap_1l]) << 16;
1346 bitmap |=
1347 ((u32) card->mp_regs[reg->wr_bitmap_1u]) << 24;
1348 }
1349 card->mp_wr_bitmap = bitmap;
1350
1351 dev_dbg(adapter->dev, "int: DNLD: wr_bitmap=0x%x\n",
1191 card->mp_wr_bitmap); 1352 card->mp_wr_bitmap);
1192 if (adapter->data_sent && 1353 if (adapter->data_sent &&
1193 (card->mp_wr_bitmap & card->mp_data_port_mask)) { 1354 (card->mp_wr_bitmap & card->mp_data_port_mask)) {
@@ -1200,11 +1361,11 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
1200 /* As firmware will not generate download ready interrupt if the port 1361 /* As firmware will not generate download ready interrupt if the port
1201 updated is command port only, cmd_sent should be done for any SDIO 1362 updated is command port only, cmd_sent should be done for any SDIO
1202 interrupt. */ 1363 interrupt. */
1203 if (adapter->cmd_sent) { 1364 if (card->has_control_mask && adapter->cmd_sent) {
1204 /* Check if firmware has attach buffer at command port and 1365 /* Check if firmware has attach buffer at command port and
1205 update just that in wr_bit_map. */ 1366 update just that in wr_bit_map. */
1206 card->mp_wr_bitmap |= 1367 card->mp_wr_bitmap |=
1207 (u16) card->mp_regs[WR_BITMAP_L] & CTRL_PORT_MASK; 1368 (u32) card->mp_regs[reg->wr_bitmap_l] & CTRL_PORT_MASK;
1208 if (card->mp_wr_bitmap & CTRL_PORT_MASK) 1369 if (card->mp_wr_bitmap & CTRL_PORT_MASK)
1209 adapter->cmd_sent = false; 1370 adapter->cmd_sent = false;
1210 } 1371 }
@@ -1212,9 +1373,16 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
1212 dev_dbg(adapter->dev, "info: cmd_sent=%d data_sent=%d\n", 1373 dev_dbg(adapter->dev, "info: cmd_sent=%d data_sent=%d\n",
1213 adapter->cmd_sent, adapter->data_sent); 1374 adapter->cmd_sent, adapter->data_sent);
1214 if (sdio_ireg & UP_LD_HOST_INT_STATUS) { 1375 if (sdio_ireg & UP_LD_HOST_INT_STATUS) {
1215 card->mp_rd_bitmap = ((u16) card->mp_regs[RD_BITMAP_U]) << 8; 1376 bitmap = (u32) card->mp_regs[reg->rd_bitmap_l];
1216 card->mp_rd_bitmap |= (u16) card->mp_regs[RD_BITMAP_L]; 1377 bitmap |= ((u32) card->mp_regs[reg->rd_bitmap_u]) << 8;
1217 dev_dbg(adapter->dev, "int: UPLD: rd_bitmap=0x%04x\n", 1378 if (card->supports_sdio_new_mode) {
1379 bitmap |=
1380 ((u32) card->mp_regs[reg->rd_bitmap_1l]) << 16;
1381 bitmap |=
1382 ((u32) card->mp_regs[reg->rd_bitmap_1u]) << 24;
1383 }
1384 card->mp_rd_bitmap = bitmap;
1385 dev_dbg(adapter->dev, "int: UPLD: rd_bitmap=0x%x\n",
1218 card->mp_rd_bitmap); 1386 card->mp_rd_bitmap);
1219 1387
1220 while (true) { 1388 while (true) {
@@ -1224,8 +1392,8 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
1224 "info: no more rd_port available\n"); 1392 "info: no more rd_port available\n");
1225 break; 1393 break;
1226 } 1394 }
1227 len_reg_l = RD_LEN_P0_L + (port << 1); 1395 len_reg_l = reg->rd_len_p0_l + (port << 1);
1228 len_reg_u = RD_LEN_P0_U + (port << 1); 1396 len_reg_u = reg->rd_len_p0_u + (port << 1);
1229 rx_len = ((u16) card->mp_regs[len_reg_u]) << 8; 1397 rx_len = ((u16) card->mp_regs[len_reg_u]) << 8;
1230 rx_len |= (u16) card->mp_regs[len_reg_l]; 1398 rx_len |= (u16) card->mp_regs[len_reg_l];
1231 dev_dbg(adapter->dev, "info: RX: port=%d rx_len=%u\n", 1399 dev_dbg(adapter->dev, "info: RX: port=%d rx_len=%u\n",
@@ -1257,37 +1425,33 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
1257 1425
1258 if (mwifiex_sdio_card_to_host_mp_aggr(adapter, skb, 1426 if (mwifiex_sdio_card_to_host_mp_aggr(adapter, skb,
1259 port)) { 1427 port)) {
1260 u32 cr = 0;
1261
1262 dev_err(adapter->dev, "card_to_host_mpa failed:" 1428 dev_err(adapter->dev, "card_to_host_mpa failed:"
1263 " int status=%#x\n", sdio_ireg); 1429 " int status=%#x\n", sdio_ireg);
1264 if (mwifiex_read_reg(adapter, 1430 goto term_cmd;
1265 CONFIGURATION_REG, &cr))
1266 dev_err(adapter->dev,
1267 "read CFG reg failed\n");
1268
1269 dev_dbg(adapter->dev,
1270 "info: CFG reg val = %d\n", cr);
1271 if (mwifiex_write_reg(adapter,
1272 CONFIGURATION_REG,
1273 (cr | 0x04)))
1274 dev_err(adapter->dev,
1275 "write CFG reg failed\n");
1276
1277 dev_dbg(adapter->dev, "info: write success\n");
1278 if (mwifiex_read_reg(adapter,
1279 CONFIGURATION_REG, &cr))
1280 dev_err(adapter->dev,
1281 "read CFG reg failed\n");
1282
1283 dev_dbg(adapter->dev,
1284 "info: CFG reg val =%x\n", cr);
1285 return -1;
1286 } 1431 }
1287 } 1432 }
1288 } 1433 }
1289 1434
1290 return 0; 1435 return 0;
1436
1437term_cmd:
1438 /* terminate cmd */
1439 if (mwifiex_read_reg(adapter, CONFIGURATION_REG, &cr))
1440 dev_err(adapter->dev, "read CFG reg failed\n");
1441 else
1442 dev_dbg(adapter->dev, "info: CFG reg val = %d\n", cr);
1443
1444 if (mwifiex_write_reg(adapter, CONFIGURATION_REG, (cr | 0x04)))
1445 dev_err(adapter->dev, "write CFG reg failed\n");
1446 else
1447 dev_dbg(adapter->dev, "info: write success\n");
1448
1449 if (mwifiex_read_reg(adapter, CONFIGURATION_REG, &cr))
1450 dev_err(adapter->dev, "read CFG reg failed\n");
1451 else
1452 dev_dbg(adapter->dev, "info: CFG reg val =%x\n", cr);
1453
1454 return -1;
1291} 1455}
1292 1456
1293/* 1457/*
@@ -1305,7 +1469,7 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
1305 * and return. 1469 * and return.
1306 */ 1470 */
1307static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter, 1471static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter,
1308 u8 *payload, u32 pkt_len, u8 port, 1472 u8 *payload, u32 pkt_len, u32 port,
1309 u32 next_pkt_len) 1473 u32 next_pkt_len)
1310{ 1474{
1311 struct sdio_mmc_card *card = adapter->card; 1475 struct sdio_mmc_card *card = adapter->card;
@@ -1314,8 +1478,11 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter,
1314 s32 f_send_cur_buf = 0; 1478 s32 f_send_cur_buf = 0;
1315 s32 f_precopy_cur_buf = 0; 1479 s32 f_precopy_cur_buf = 0;
1316 s32 f_postcopy_cur_buf = 0; 1480 s32 f_postcopy_cur_buf = 0;
1481 u32 mport;
1317 1482
1318 if ((!card->mpa_tx.enabled) || (port == CTRL_PORT)) { 1483 if (!card->mpa_tx.enabled ||
1484 (card->has_control_mask && (port == CTRL_PORT)) ||
1485 (card->supports_sdio_new_mode && (port == CMD_PORT_SLCT))) {
1319 dev_dbg(adapter->dev, "info: %s: tx aggregation disabled\n", 1486 dev_dbg(adapter->dev, "info: %s: tx aggregation disabled\n",
1320 __func__); 1487 __func__);
1321 1488
@@ -1329,7 +1496,7 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter,
1329 __func__); 1496 __func__);
1330 1497
1331 if (MP_TX_AGGR_IN_PROGRESS(card)) { 1498 if (MP_TX_AGGR_IN_PROGRESS(card)) {
1332 if (!MP_TX_AGGR_PORT_LIMIT_REACHED(card) && 1499 if (!mp_tx_aggr_port_limit_reached(card) &&
1333 MP_TX_AGGR_BUF_HAS_ROOM(card, pkt_len)) { 1500 MP_TX_AGGR_BUF_HAS_ROOM(card, pkt_len)) {
1334 f_precopy_cur_buf = 1; 1501 f_precopy_cur_buf = 1;
1335 1502
@@ -1342,7 +1509,7 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter,
1342 /* No room in Aggr buf, send it */ 1509 /* No room in Aggr buf, send it */
1343 f_send_aggr_buf = 1; 1510 f_send_aggr_buf = 1;
1344 1511
1345 if (MP_TX_AGGR_PORT_LIMIT_REACHED(card) || 1512 if (mp_tx_aggr_port_limit_reached(card) ||
1346 !(card->mp_wr_bitmap & 1513 !(card->mp_wr_bitmap &
1347 (1 << card->curr_wr_port))) 1514 (1 << card->curr_wr_port)))
1348 f_send_cur_buf = 1; 1515 f_send_cur_buf = 1;
@@ -1381,7 +1548,7 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter,
1381 MP_TX_AGGR_BUF_PUT(card, payload, pkt_len, port); 1548 MP_TX_AGGR_BUF_PUT(card, payload, pkt_len, port);
1382 1549
1383 if (MP_TX_AGGR_PKT_LIMIT_REACHED(card) || 1550 if (MP_TX_AGGR_PKT_LIMIT_REACHED(card) ||
1384 MP_TX_AGGR_PORT_LIMIT_REACHED(card)) 1551 mp_tx_aggr_port_limit_reached(card))
1385 /* No more pkts allowed in Aggr buf, send it */ 1552 /* No more pkts allowed in Aggr buf, send it */
1386 f_send_aggr_buf = 1; 1553 f_send_aggr_buf = 1;
1387 } 1554 }
@@ -1390,11 +1557,28 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter,
1390 dev_dbg(adapter->dev, "data: %s: send aggr buffer: %d %d\n", 1557 dev_dbg(adapter->dev, "data: %s: send aggr buffer: %d %d\n",
1391 __func__, 1558 __func__,
1392 card->mpa_tx.start_port, card->mpa_tx.ports); 1559 card->mpa_tx.start_port, card->mpa_tx.ports);
1560 if (card->supports_sdio_new_mode) {
1561 u32 port_count;
1562 int i;
1563
1564 for (i = 0, port_count = 0; i < card->max_ports; i++)
1565 if (card->mpa_tx.ports & BIT(i))
1566 port_count++;
1567
1568 /* Writing data from "start_port + 0" to "start_port +
1569 * port_count -1", so decrease the count by 1
1570 */
1571 port_count--;
1572 mport = (adapter->ioport | SDIO_MPA_ADDR_BASE |
1573 (port_count << 8)) + card->mpa_tx.start_port;
1574 } else {
1575 mport = (adapter->ioport | SDIO_MPA_ADDR_BASE |
1576 (card->mpa_tx.ports << 4)) +
1577 card->mpa_tx.start_port;
1578 }
1579
1393 ret = mwifiex_write_data_to_card(adapter, card->mpa_tx.buf, 1580 ret = mwifiex_write_data_to_card(adapter, card->mpa_tx.buf,
1394 card->mpa_tx.buf_len, 1581 card->mpa_tx.buf_len, mport);
1395 (adapter->ioport | 0x1000 |
1396 (card->mpa_tx.ports << 4)) +
1397 card->mpa_tx.start_port);
1398 1582
1399 MP_TX_AGGR_BUF_RESET(card); 1583 MP_TX_AGGR_BUF_RESET(card);
1400 } 1584 }
@@ -1434,7 +1618,7 @@ static int mwifiex_sdio_host_to_card(struct mwifiex_adapter *adapter,
1434 int ret; 1618 int ret;
1435 u32 buf_block_len; 1619 u32 buf_block_len;
1436 u32 blk_size; 1620 u32 blk_size;
1437 u8 port = CTRL_PORT; 1621 u32 port = CTRL_PORT;
1438 u8 *payload = (u8 *)skb->data; 1622 u8 *payload = (u8 *)skb->data;
1439 u32 pkt_len = skb->len; 1623 u32 pkt_len = skb->len;
1440 1624
@@ -1465,6 +1649,9 @@ static int mwifiex_sdio_host_to_card(struct mwifiex_adapter *adapter,
1465 pkt_len > MWIFIEX_UPLD_SIZE) 1649 pkt_len > MWIFIEX_UPLD_SIZE)
1466 dev_err(adapter->dev, "%s: payload=%p, nb=%d\n", 1650 dev_err(adapter->dev, "%s: payload=%p, nb=%d\n",
1467 __func__, payload, pkt_len); 1651 __func__, payload, pkt_len);
1652
1653 if (card->supports_sdio_new_mode)
1654 port = CMD_PORT_SLCT;
1468 } 1655 }
1469 1656
1470 /* Transfer data to card */ 1657 /* Transfer data to card */
@@ -1586,18 +1773,7 @@ static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
1586 1773
1587 adapter->dev = &func->dev; 1774 adapter->dev = &func->dev;
1588 1775
1589 switch (func->device) { 1776 strcpy(adapter->fw_name, card->firmware);
1590 case SDIO_DEVICE_ID_MARVELL_8786:
1591 strcpy(adapter->fw_name, SD8786_DEFAULT_FW_NAME);
1592 break;
1593 case SDIO_DEVICE_ID_MARVELL_8797:
1594 strcpy(adapter->fw_name, SD8797_DEFAULT_FW_NAME);
1595 break;
1596 case SDIO_DEVICE_ID_MARVELL_8787:
1597 default:
1598 strcpy(adapter->fw_name, SD8787_DEFAULT_FW_NAME);
1599 break;
1600 }
1601 1777
1602 return 0; 1778 return 0;
1603 1779
@@ -1626,8 +1802,9 @@ disable_func:
1626static int mwifiex_init_sdio(struct mwifiex_adapter *adapter) 1802static int mwifiex_init_sdio(struct mwifiex_adapter *adapter)
1627{ 1803{
1628 struct sdio_mmc_card *card = adapter->card; 1804 struct sdio_mmc_card *card = adapter->card;
1805 const struct mwifiex_sdio_card_reg *reg = card->reg;
1629 int ret; 1806 int ret;
1630 u32 sdio_ireg; 1807 u8 sdio_ireg;
1631 1808
1632 /* 1809 /*
1633 * Read the HOST_INT_STATUS_REG for ACK the first interrupt got 1810 * Read the HOST_INT_STATUS_REG for ACK the first interrupt got
@@ -1645,30 +1822,35 @@ static int mwifiex_init_sdio(struct mwifiex_adapter *adapter)
1645 /* Initialize SDIO variables in card */ 1822 /* Initialize SDIO variables in card */
1646 card->mp_rd_bitmap = 0; 1823 card->mp_rd_bitmap = 0;
1647 card->mp_wr_bitmap = 0; 1824 card->mp_wr_bitmap = 0;
1648 card->curr_rd_port = 1; 1825 card->curr_rd_port = reg->start_rd_port;
1649 card->curr_wr_port = 1; 1826 card->curr_wr_port = reg->start_wr_port;
1650 1827
1651 card->mp_data_port_mask = DATA_PORT_MASK; 1828 card->mp_data_port_mask = reg->data_port_mask;
1652 1829
1653 card->mpa_tx.buf_len = 0; 1830 card->mpa_tx.buf_len = 0;
1654 card->mpa_tx.pkt_cnt = 0; 1831 card->mpa_tx.pkt_cnt = 0;
1655 card->mpa_tx.start_port = 0; 1832 card->mpa_tx.start_port = 0;
1656 1833
1657 card->mpa_tx.enabled = 1; 1834 card->mpa_tx.enabled = 1;
1658 card->mpa_tx.pkt_aggr_limit = SDIO_MP_AGGR_DEF_PKT_LIMIT; 1835 card->mpa_tx.pkt_aggr_limit = card->mp_agg_pkt_limit;
1659 1836
1660 card->mpa_rx.buf_len = 0; 1837 card->mpa_rx.buf_len = 0;
1661 card->mpa_rx.pkt_cnt = 0; 1838 card->mpa_rx.pkt_cnt = 0;
1662 card->mpa_rx.start_port = 0; 1839 card->mpa_rx.start_port = 0;
1663 1840
1664 card->mpa_rx.enabled = 1; 1841 card->mpa_rx.enabled = 1;
1665 card->mpa_rx.pkt_aggr_limit = SDIO_MP_AGGR_DEF_PKT_LIMIT; 1842 card->mpa_rx.pkt_aggr_limit = card->mp_agg_pkt_limit;
1666 1843
1667 /* Allocate buffers for SDIO MP-A */ 1844 /* Allocate buffers for SDIO MP-A */
1668 card->mp_regs = kzalloc(MAX_MP_REGS, GFP_KERNEL); 1845 card->mp_regs = kzalloc(reg->max_mp_regs, GFP_KERNEL);
1669 if (!card->mp_regs) 1846 if (!card->mp_regs)
1670 return -ENOMEM; 1847 return -ENOMEM;
1671 1848
1849 /* Allocate skb pointer buffers */
1850 card->mpa_rx.skb_arr = kzalloc((sizeof(void *)) *
1851 card->mp_agg_pkt_limit, GFP_KERNEL);
1852 card->mpa_rx.len_arr = kzalloc(sizeof(*card->mpa_rx.len_arr) *
1853 card->mp_agg_pkt_limit, GFP_KERNEL);
1672 ret = mwifiex_alloc_sdio_mpa_buffers(adapter, 1854 ret = mwifiex_alloc_sdio_mpa_buffers(adapter,
1673 SDIO_MP_TX_AGGR_DEF_BUF_SIZE, 1855 SDIO_MP_TX_AGGR_DEF_BUF_SIZE,
1674 SDIO_MP_RX_AGGR_DEF_BUF_SIZE); 1856 SDIO_MP_RX_AGGR_DEF_BUF_SIZE);
@@ -1705,6 +1887,8 @@ static void mwifiex_cleanup_sdio(struct mwifiex_adapter *adapter)
1705 struct sdio_mmc_card *card = adapter->card; 1887 struct sdio_mmc_card *card = adapter->card;
1706 1888
1707 kfree(card->mp_regs); 1889 kfree(card->mp_regs);
1890 kfree(card->mpa_rx.skb_arr);
1891 kfree(card->mpa_rx.len_arr);
1708 kfree(card->mpa_tx.buf); 1892 kfree(card->mpa_tx.buf);
1709 kfree(card->mpa_rx.buf); 1893 kfree(card->mpa_rx.buf);
1710} 1894}
@@ -1716,16 +1900,20 @@ static void
1716mwifiex_update_mp_end_port(struct mwifiex_adapter *adapter, u16 port) 1900mwifiex_update_mp_end_port(struct mwifiex_adapter *adapter, u16 port)
1717{ 1901{
1718 struct sdio_mmc_card *card = adapter->card; 1902 struct sdio_mmc_card *card = adapter->card;
1903 const struct mwifiex_sdio_card_reg *reg = card->reg;
1719 int i; 1904 int i;
1720 1905
1721 card->mp_end_port = port; 1906 card->mp_end_port = port;
1722 1907
1723 card->mp_data_port_mask = DATA_PORT_MASK; 1908 card->mp_data_port_mask = reg->data_port_mask;
1724 1909
1725 for (i = 1; i <= MAX_PORT - card->mp_end_port; i++) 1910 if (reg->start_wr_port) {
1726 card->mp_data_port_mask &= ~(1 << (MAX_PORT - i)); 1911 for (i = 1; i <= card->max_ports - card->mp_end_port; i++)
1912 card->mp_data_port_mask &=
1913 ~(1 << (card->max_ports - i));
1914 }
1727 1915
1728 card->curr_wr_port = 1; 1916 card->curr_wr_port = reg->start_wr_port;
1729 1917
1730 dev_dbg(adapter->dev, "cmd: mp_end_port %d, data port mask 0x%x\n", 1918 dev_dbg(adapter->dev, "cmd: mp_end_port %d, data port mask 0x%x\n",
1731 port, card->mp_data_port_mask); 1919 port, card->mp_data_port_mask);
@@ -1831,3 +2019,4 @@ MODULE_LICENSE("GPL v2");
1831MODULE_FIRMWARE(SD8786_DEFAULT_FW_NAME); 2019MODULE_FIRMWARE(SD8786_DEFAULT_FW_NAME);
1832MODULE_FIRMWARE(SD8787_DEFAULT_FW_NAME); 2020MODULE_FIRMWARE(SD8787_DEFAULT_FW_NAME);
1833MODULE_FIRMWARE(SD8797_DEFAULT_FW_NAME); 2021MODULE_FIRMWARE(SD8797_DEFAULT_FW_NAME);
2022MODULE_FIRMWARE(SD8897_DEFAULT_FW_NAME);
diff --git a/drivers/net/wireless/mwifiex/sdio.h b/drivers/net/wireless/mwifiex/sdio.h
index 8cc5468654b4..6d51dfdd8251 100644
--- a/drivers/net/wireless/mwifiex/sdio.h
+++ b/drivers/net/wireless/mwifiex/sdio.h
@@ -32,30 +32,37 @@
32#define SD8786_DEFAULT_FW_NAME "mrvl/sd8786_uapsta.bin" 32#define SD8786_DEFAULT_FW_NAME "mrvl/sd8786_uapsta.bin"
33#define SD8787_DEFAULT_FW_NAME "mrvl/sd8787_uapsta.bin" 33#define SD8787_DEFAULT_FW_NAME "mrvl/sd8787_uapsta.bin"
34#define SD8797_DEFAULT_FW_NAME "mrvl/sd8797_uapsta.bin" 34#define SD8797_DEFAULT_FW_NAME "mrvl/sd8797_uapsta.bin"
35#define SD8897_DEFAULT_FW_NAME "mrvl/sd8897_uapsta.bin"
35 36
36#define BLOCK_MODE 1 37#define BLOCK_MODE 1
37#define BYTE_MODE 0 38#define BYTE_MODE 0
38 39
39#define REG_PORT 0 40#define REG_PORT 0
40#define RD_BITMAP_L 0x04
41#define RD_BITMAP_U 0x05
42#define WR_BITMAP_L 0x06
43#define WR_BITMAP_U 0x07
44#define RD_LEN_P0_L 0x08
45#define RD_LEN_P0_U 0x09
46 41
47#define MWIFIEX_SDIO_IO_PORT_MASK 0xfffff 42#define MWIFIEX_SDIO_IO_PORT_MASK 0xfffff
48 43
49#define MWIFIEX_SDIO_BYTE_MODE_MASK 0x80000000 44#define MWIFIEX_SDIO_BYTE_MODE_MASK 0x80000000
50 45
46#define SDIO_MPA_ADDR_BASE 0x1000
51#define CTRL_PORT 0 47#define CTRL_PORT 0
52#define CTRL_PORT_MASK 0x0001 48#define CTRL_PORT_MASK 0x0001
53#define DATA_PORT_MASK 0xfffe
54 49
55#define MAX_MP_REGS 64 50#define CMD_PORT_UPLD_INT_MASK (0x1U<<6)
56#define MAX_PORT 16 51#define CMD_PORT_DNLD_INT_MASK (0x1U<<7)
57 52#define HOST_TERM_CMD53 (0x1U << 2)
58#define SDIO_MP_AGGR_DEF_PKT_LIMIT 8 53#define REG_PORT 0
54#define MEM_PORT 0x10000
55#define CMD_RD_LEN_0 0xB4
56#define CMD_RD_LEN_1 0xB5
57#define CARD_CONFIG_2_1_REG 0xCD
58#define CMD53_NEW_MODE (0x1U << 0)
59#define CMD_CONFIG_0 0xB8
60#define CMD_PORT_RD_LEN_EN (0x1U << 2)
61#define CMD_CONFIG_1 0xB9
62#define CMD_PORT_AUTO_EN (0x1U << 0)
63#define CMD_PORT_SLCT 0x8000
64#define UP_LD_CMD_PORT_HOST_INT_STATUS (0x40U)
65#define DN_LD_CMD_PORT_HOST_INT_STATUS (0x80U)
59 66
60#define SDIO_MP_TX_AGGR_DEF_BUF_SIZE (8192) /* 8K */ 67#define SDIO_MP_TX_AGGR_DEF_BUF_SIZE (8192) /* 8K */
61 68
@@ -75,14 +82,8 @@
75 82
76/* Host Control Registers : Configuration */ 83/* Host Control Registers : Configuration */
77#define CONFIGURATION_REG 0x00 84#define CONFIGURATION_REG 0x00
78/* Host Control Registers : Host without Command 53 finish host*/
79#define HOST_TO_CARD_EVENT (0x1U << 3)
80/* Host Control Registers : Host without Command 53 finish host */
81#define HOST_WO_CMD53_FINISH_HOST (0x1U << 2)
82/* Host Control Registers : Host power up */ 85/* Host Control Registers : Host power up */
83#define HOST_POWER_UP (0x1U << 1) 86#define HOST_POWER_UP (0x1U << 1)
84/* Host Control Registers : Host power down */
85#define HOST_POWER_DOWN (0x1U << 0)
86 87
87/* Host Control Registers : Host interrupt mask */ 88/* Host Control Registers : Host interrupt mask */
88#define HOST_INT_MASK_REG 0x02 89#define HOST_INT_MASK_REG 0x02
@@ -90,8 +91,7 @@
90#define UP_LD_HOST_INT_MASK (0x1U) 91#define UP_LD_HOST_INT_MASK (0x1U)
91/* Host Control Registers : Download host interrupt mask */ 92/* Host Control Registers : Download host interrupt mask */
92#define DN_LD_HOST_INT_MASK (0x2U) 93#define DN_LD_HOST_INT_MASK (0x2U)
93/* Enable Host interrupt mask */ 94
94#define HOST_INT_ENABLE (UP_LD_HOST_INT_MASK | DN_LD_HOST_INT_MASK)
95/* Disable Host interrupt mask */ 95/* Disable Host interrupt mask */
96#define HOST_INT_DISABLE 0xff 96#define HOST_INT_DISABLE 0xff
97 97
@@ -104,74 +104,15 @@
104 104
105/* Host Control Registers : Host interrupt RSR */ 105/* Host Control Registers : Host interrupt RSR */
106#define HOST_INT_RSR_REG 0x01 106#define HOST_INT_RSR_REG 0x01
107/* Host Control Registers : Upload host interrupt RSR */
108#define UP_LD_HOST_INT_RSR (0x1U)
109#define SDIO_INT_MASK 0x3F
110 107
111/* Host Control Registers : Host interrupt status */ 108/* Host Control Registers : Host interrupt status */
112#define HOST_INT_STATUS_REG 0x28 109#define HOST_INT_STATUS_REG 0x28
113/* Host Control Registers : Upload CRC error */ 110
114#define UP_LD_CRC_ERR (0x1U << 2)
115/* Host Control Registers : Upload restart */
116#define UP_LD_RESTART (0x1U << 1)
117/* Host Control Registers : Download restart */
118#define DN_LD_RESTART (0x1U << 0)
119
120/* Card Control Registers : Card status register */
121#define CARD_STATUS_REG 0x30
122/* Card Control Registers : Card I/O ready */ 111/* Card Control Registers : Card I/O ready */
123#define CARD_IO_READY (0x1U << 3) 112#define CARD_IO_READY (0x1U << 3)
124/* Card Control Registers : CIS card ready */
125#define CIS_CARD_RDY (0x1U << 2)
126/* Card Control Registers : Upload card ready */
127#define UP_LD_CARD_RDY (0x1U << 1)
128/* Card Control Registers : Download card ready */ 113/* Card Control Registers : Download card ready */
129#define DN_LD_CARD_RDY (0x1U << 0) 114#define DN_LD_CARD_RDY (0x1U << 0)
130 115
131/* Card Control Registers : Host interrupt mask register */
132#define HOST_INTERRUPT_MASK_REG 0x34
133/* Card Control Registers : Host power interrupt mask */
134#define HOST_POWER_INT_MASK (0x1U << 3)
135/* Card Control Registers : Abort card interrupt mask */
136#define ABORT_CARD_INT_MASK (0x1U << 2)
137/* Card Control Registers : Upload card interrupt mask */
138#define UP_LD_CARD_INT_MASK (0x1U << 1)
139/* Card Control Registers : Download card interrupt mask */
140#define DN_LD_CARD_INT_MASK (0x1U << 0)
141
142/* Card Control Registers : Card interrupt status register */
143#define CARD_INTERRUPT_STATUS_REG 0x38
144/* Card Control Registers : Power up interrupt */
145#define POWER_UP_INT (0x1U << 4)
146/* Card Control Registers : Power down interrupt */
147#define POWER_DOWN_INT (0x1U << 3)
148
149/* Card Control Registers : Card interrupt RSR register */
150#define CARD_INTERRUPT_RSR_REG 0x3c
151/* Card Control Registers : Power up RSR */
152#define POWER_UP_RSR (0x1U << 4)
153/* Card Control Registers : Power down RSR */
154#define POWER_DOWN_RSR (0x1U << 3)
155
156/* Card Control Registers : Miscellaneous Configuration Register */
157#define CARD_MISC_CFG_REG 0x6C
158
159/* Host F1 read base 0 */
160#define HOST_F1_RD_BASE_0 0x0040
161/* Host F1 read base 1 */
162#define HOST_F1_RD_BASE_1 0x0041
163/* Host F1 card ready */
164#define HOST_F1_CARD_RDY 0x0020
165
166/* Firmware status 0 register */
167#define CARD_FW_STATUS0_REG 0x60
168/* Firmware status 1 register */
169#define CARD_FW_STATUS1_REG 0x61
170/* Rx length register */
171#define CARD_RX_LEN_REG 0x62
172/* Rx unit register */
173#define CARD_RX_UNIT_REG 0x63
174
175/* Max retry number of CMD53 write */ 116/* Max retry number of CMD53 write */
176#define MAX_WRITE_IOMEM_RETRY 2 117#define MAX_WRITE_IOMEM_RETRY 2
177 118
@@ -192,7 +133,8 @@
192 if (a->mpa_tx.start_port <= port) \ 133 if (a->mpa_tx.start_port <= port) \
193 a->mpa_tx.ports |= (1<<(a->mpa_tx.pkt_cnt)); \ 134 a->mpa_tx.ports |= (1<<(a->mpa_tx.pkt_cnt)); \
194 else \ 135 else \
195 a->mpa_tx.ports |= (1<<(a->mpa_tx.pkt_cnt+1+(MAX_PORT - \ 136 a->mpa_tx.ports |= (1<<(a->mpa_tx.pkt_cnt+1+ \
137 (a->max_ports - \
196 a->mp_end_port))); \ 138 a->mp_end_port))); \
197 a->mpa_tx.pkt_cnt++; \ 139 a->mpa_tx.pkt_cnt++; \
198} while (0) 140} while (0)
@@ -201,12 +143,6 @@
201#define MP_TX_AGGR_PKT_LIMIT_REACHED(a) \ 143#define MP_TX_AGGR_PKT_LIMIT_REACHED(a) \
202 (a->mpa_tx.pkt_cnt == a->mpa_tx.pkt_aggr_limit) 144 (a->mpa_tx.pkt_cnt == a->mpa_tx.pkt_aggr_limit)
203 145
204/* SDIO Tx aggregation port limit ? */
205#define MP_TX_AGGR_PORT_LIMIT_REACHED(a) ((a->curr_wr_port < \
206 a->mpa_tx.start_port) && (((MAX_PORT - \
207 a->mpa_tx.start_port) + a->curr_wr_port) >= \
208 SDIO_MP_AGGR_DEF_PKT_LIMIT))
209
210/* Reset SDIO Tx aggregation buffer parameters */ 146/* Reset SDIO Tx aggregation buffer parameters */
211#define MP_TX_AGGR_BUF_RESET(a) do { \ 147#define MP_TX_AGGR_BUF_RESET(a) do { \
212 a->mpa_tx.pkt_cnt = 0; \ 148 a->mpa_tx.pkt_cnt = 0; \
@@ -219,12 +155,6 @@
219#define MP_RX_AGGR_PKT_LIMIT_REACHED(a) \ 155#define MP_RX_AGGR_PKT_LIMIT_REACHED(a) \
220 (a->mpa_rx.pkt_cnt == a->mpa_rx.pkt_aggr_limit) 156 (a->mpa_rx.pkt_cnt == a->mpa_rx.pkt_aggr_limit)
221 157
222/* SDIO Tx aggregation port limit ? */
223#define MP_RX_AGGR_PORT_LIMIT_REACHED(a) ((a->curr_rd_port < \
224 a->mpa_rx.start_port) && (((MAX_PORT - \
225 a->mpa_rx.start_port) + a->curr_rd_port) >= \
226 SDIO_MP_AGGR_DEF_PKT_LIMIT))
227
228/* SDIO Rx aggregation in progress ? */ 158/* SDIO Rx aggregation in progress ? */
229#define MP_RX_AGGR_IN_PROGRESS(a) (a->mpa_rx.pkt_cnt > 0) 159#define MP_RX_AGGR_IN_PROGRESS(a) (a->mpa_rx.pkt_cnt > 0)
230 160
@@ -232,20 +162,6 @@
232#define MP_RX_AGGR_BUF_HAS_ROOM(a, rx_len) \ 162#define MP_RX_AGGR_BUF_HAS_ROOM(a, rx_len) \
233 ((a->mpa_rx.buf_len+rx_len) <= a->mpa_rx.buf_size) 163 ((a->mpa_rx.buf_len+rx_len) <= a->mpa_rx.buf_size)
234 164
235/* Prepare to copy current packet from card to SDIO Rx aggregation buffer */
236#define MP_RX_AGGR_SETUP(a, skb, port) do { \
237 a->mpa_rx.buf_len += skb->len; \
238 if (!a->mpa_rx.pkt_cnt) \
239 a->mpa_rx.start_port = port; \
240 if (a->mpa_rx.start_port <= port) \
241 a->mpa_rx.ports |= (1<<(a->mpa_rx.pkt_cnt)); \
242 else \
243 a->mpa_rx.ports |= (1<<(a->mpa_rx.pkt_cnt+1)); \
244 a->mpa_rx.skb_arr[a->mpa_rx.pkt_cnt] = skb; \
245 a->mpa_rx.len_arr[a->mpa_rx.pkt_cnt] = skb->len; \
246 a->mpa_rx.pkt_cnt++; \
247} while (0)
248
249/* Reset SDIO Rx aggregation buffer parameters */ 165/* Reset SDIO Rx aggregation buffer parameters */
250#define MP_RX_AGGR_BUF_RESET(a) do { \ 166#define MP_RX_AGGR_BUF_RESET(a) do { \
251 a->mpa_rx.pkt_cnt = 0; \ 167 a->mpa_rx.pkt_cnt = 0; \
@@ -254,14 +170,13 @@
254 a->mpa_rx.start_port = 0; \ 170 a->mpa_rx.start_port = 0; \
255} while (0) 171} while (0)
256 172
257
258/* data structure for SDIO MPA TX */ 173/* data structure for SDIO MPA TX */
259struct mwifiex_sdio_mpa_tx { 174struct mwifiex_sdio_mpa_tx {
260 /* multiport tx aggregation buffer pointer */ 175 /* multiport tx aggregation buffer pointer */
261 u8 *buf; 176 u8 *buf;
262 u32 buf_len; 177 u32 buf_len;
263 u32 pkt_cnt; 178 u32 pkt_cnt;
264 u16 ports; 179 u32 ports;
265 u16 start_port; 180 u16 start_port;
266 u8 enabled; 181 u8 enabled;
267 u32 buf_size; 182 u32 buf_size;
@@ -272,11 +187,11 @@ struct mwifiex_sdio_mpa_rx {
272 u8 *buf; 187 u8 *buf;
273 u32 buf_len; 188 u32 buf_len;
274 u32 pkt_cnt; 189 u32 pkt_cnt;
275 u16 ports; 190 u32 ports;
276 u16 start_port; 191 u16 start_port;
277 192
278 struct sk_buff *skb_arr[SDIO_MP_AGGR_DEF_PKT_LIMIT]; 193 struct sk_buff **skb_arr;
279 u32 len_arr[SDIO_MP_AGGR_DEF_PKT_LIMIT]; 194 u32 *len_arr;
280 195
281 u8 enabled; 196 u8 enabled;
282 u32 buf_size; 197 u32 buf_size;
@@ -286,15 +201,47 @@ struct mwifiex_sdio_mpa_rx {
286int mwifiex_bus_register(void); 201int mwifiex_bus_register(void);
287void mwifiex_bus_unregister(void); 202void mwifiex_bus_unregister(void);
288 203
204struct mwifiex_sdio_card_reg {
205 u8 start_rd_port;
206 u8 start_wr_port;
207 u8 base_0_reg;
208 u8 base_1_reg;
209 u8 poll_reg;
210 u8 host_int_enable;
211 u8 status_reg_0;
212 u8 status_reg_1;
213 u8 sdio_int_mask;
214 u32 data_port_mask;
215 u8 max_mp_regs;
216 u8 rd_bitmap_l;
217 u8 rd_bitmap_u;
218 u8 rd_bitmap_1l;
219 u8 rd_bitmap_1u;
220 u8 wr_bitmap_l;
221 u8 wr_bitmap_u;
222 u8 wr_bitmap_1l;
223 u8 wr_bitmap_1u;
224 u8 rd_len_p0_l;
225 u8 rd_len_p0_u;
226 u8 card_misc_cfg_reg;
227};
228
289struct sdio_mmc_card { 229struct sdio_mmc_card {
290 struct sdio_func *func; 230 struct sdio_func *func;
291 struct mwifiex_adapter *adapter; 231 struct mwifiex_adapter *adapter;
292 232
293 u16 mp_rd_bitmap; 233 const char *firmware;
294 u16 mp_wr_bitmap; 234 const struct mwifiex_sdio_card_reg *reg;
235 u8 max_ports;
236 u8 mp_agg_pkt_limit;
237 bool supports_sdio_new_mode;
238 bool has_control_mask;
239
240 u32 mp_rd_bitmap;
241 u32 mp_wr_bitmap;
295 242
296 u16 mp_end_port; 243 u16 mp_end_port;
297 u16 mp_data_port_mask; 244 u32 mp_data_port_mask;
298 245
299 u8 curr_rd_port; 246 u8 curr_rd_port;
300 u8 curr_wr_port; 247 u8 curr_wr_port;
@@ -305,6 +252,98 @@ struct sdio_mmc_card {
305 struct mwifiex_sdio_mpa_rx mpa_rx; 252 struct mwifiex_sdio_mpa_rx mpa_rx;
306}; 253};
307 254
255struct mwifiex_sdio_device {
256 const char *firmware;
257 const struct mwifiex_sdio_card_reg *reg;
258 u8 max_ports;
259 u8 mp_agg_pkt_limit;
260 bool supports_sdio_new_mode;
261 bool has_control_mask;
262};
263
264static const struct mwifiex_sdio_card_reg mwifiex_reg_sd87xx = {
265 .start_rd_port = 1,
266 .start_wr_port = 1,
267 .base_0_reg = 0x0040,
268 .base_1_reg = 0x0041,
269 .poll_reg = 0x30,
270 .host_int_enable = UP_LD_HOST_INT_MASK | DN_LD_HOST_INT_MASK,
271 .status_reg_0 = 0x60,
272 .status_reg_1 = 0x61,
273 .sdio_int_mask = 0x3f,
274 .data_port_mask = 0x0000fffe,
275 .max_mp_regs = 64,
276 .rd_bitmap_l = 0x04,
277 .rd_bitmap_u = 0x05,
278 .wr_bitmap_l = 0x06,
279 .wr_bitmap_u = 0x07,
280 .rd_len_p0_l = 0x08,
281 .rd_len_p0_u = 0x09,
282 .card_misc_cfg_reg = 0x6c,
283};
284
285static const struct mwifiex_sdio_card_reg mwifiex_reg_sd8897 = {
286 .start_rd_port = 0,
287 .start_wr_port = 0,
288 .base_0_reg = 0x60,
289 .base_1_reg = 0x61,
290 .poll_reg = 0x50,
291 .host_int_enable = UP_LD_HOST_INT_MASK | DN_LD_HOST_INT_MASK |
292 CMD_PORT_UPLD_INT_MASK | CMD_PORT_DNLD_INT_MASK,
293 .status_reg_0 = 0xc0,
294 .status_reg_1 = 0xc1,
295 .sdio_int_mask = 0xff,
296 .data_port_mask = 0xffffffff,
297 .max_mp_regs = 184,
298 .rd_bitmap_l = 0x04,
299 .rd_bitmap_u = 0x05,
300 .rd_bitmap_1l = 0x06,
301 .rd_bitmap_1u = 0x07,
302 .wr_bitmap_l = 0x08,
303 .wr_bitmap_u = 0x09,
304 .wr_bitmap_1l = 0x0a,
305 .wr_bitmap_1u = 0x0b,
306 .rd_len_p0_l = 0x0c,
307 .rd_len_p0_u = 0x0d,
308 .card_misc_cfg_reg = 0xcc,
309};
310
311static const struct mwifiex_sdio_device mwifiex_sdio_sd8786 = {
312 .firmware = SD8786_DEFAULT_FW_NAME,
313 .reg = &mwifiex_reg_sd87xx,
314 .max_ports = 16,
315 .mp_agg_pkt_limit = 8,
316 .supports_sdio_new_mode = false,
317 .has_control_mask = true,
318};
319
320static const struct mwifiex_sdio_device mwifiex_sdio_sd8787 = {
321 .firmware = SD8787_DEFAULT_FW_NAME,
322 .reg = &mwifiex_reg_sd87xx,
323 .max_ports = 16,
324 .mp_agg_pkt_limit = 8,
325 .supports_sdio_new_mode = false,
326 .has_control_mask = true,
327};
328
329static const struct mwifiex_sdio_device mwifiex_sdio_sd8797 = {
330 .firmware = SD8797_DEFAULT_FW_NAME,
331 .reg = &mwifiex_reg_sd87xx,
332 .max_ports = 16,
333 .mp_agg_pkt_limit = 8,
334 .supports_sdio_new_mode = false,
335 .has_control_mask = true,
336};
337
338static const struct mwifiex_sdio_device mwifiex_sdio_sd8897 = {
339 .firmware = SD8897_DEFAULT_FW_NAME,
340 .reg = &mwifiex_reg_sd8897,
341 .max_ports = 32,
342 .mp_agg_pkt_limit = 16,
343 .supports_sdio_new_mode = true,
344 .has_control_mask = false,
345};
346
308/* 347/*
309 * .cmdrsp_complete handler 348 * .cmdrsp_complete handler
310 */ 349 */
@@ -325,4 +364,77 @@ static inline int mwifiex_sdio_event_complete(struct mwifiex_adapter *adapter,
325 return 0; 364 return 0;
326} 365}
327 366
367static inline bool
368mp_rx_aggr_port_limit_reached(struct sdio_mmc_card *card)
369{
370 u8 tmp;
371
372 if (card->curr_rd_port < card->mpa_rx.start_port) {
373 if (card->supports_sdio_new_mode)
374 tmp = card->mp_end_port >> 1;
375 else
376 tmp = card->mp_agg_pkt_limit;
377
378 if (((card->max_ports - card->mpa_rx.start_port) +
379 card->curr_rd_port) >= tmp)
380 return true;
381 }
382
383 if (!card->supports_sdio_new_mode)
384 return false;
385
386 if ((card->curr_rd_port - card->mpa_rx.start_port) >=
387 (card->mp_end_port >> 1))
388 return true;
389
390 return false;
391}
392
393static inline bool
394mp_tx_aggr_port_limit_reached(struct sdio_mmc_card *card)
395{
396 u16 tmp;
397
398 if (card->curr_wr_port < card->mpa_tx.start_port) {
399 if (card->supports_sdio_new_mode)
400 tmp = card->mp_end_port >> 1;
401 else
402 tmp = card->mp_agg_pkt_limit;
403
404 if (((card->max_ports - card->mpa_tx.start_port) +
405 card->curr_wr_port) >= tmp)
406 return true;
407 }
408
409 if (!card->supports_sdio_new_mode)
410 return false;
411
412 if ((card->curr_wr_port - card->mpa_tx.start_port) >=
413 (card->mp_end_port >> 1))
414 return true;
415
416 return false;
417}
418
419/* Prepare to copy current packet from card to SDIO Rx aggregation buffer */
420static inline void mp_rx_aggr_setup(struct sdio_mmc_card *card,
421 struct sk_buff *skb, u8 port)
422{
423 card->mpa_rx.buf_len += skb->len;
424
425 if (!card->mpa_rx.pkt_cnt)
426 card->mpa_rx.start_port = port;
427
428 if (card->supports_sdio_new_mode) {
429 card->mpa_rx.ports |= (1 << port);
430 } else {
431 if (card->mpa_rx.start_port <= port)
432 card->mpa_rx.ports |= 1 << (card->mpa_rx.pkt_cnt);
433 else
434 card->mpa_rx.ports |= 1 << (card->mpa_rx.pkt_cnt + 1);
435 }
436 card->mpa_rx.skb_arr[card->mpa_rx.pkt_cnt] = skb;
437 card->mpa_rx.len_arr[card->mpa_rx.pkt_cnt] = skb->len;
438 card->mpa_rx.pkt_cnt++;
439}
328#endif /* _MWIFIEX_SDIO_H */ 440#endif /* _MWIFIEX_SDIO_H */
diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c
index b193e25977d2..8ece48580642 100644
--- a/drivers/net/wireless/mwifiex/sta_cmd.c
+++ b/drivers/net/wireless/mwifiex/sta_cmd.c
@@ -1134,6 +1134,55 @@ mwifiex_cmd_mef_cfg(struct mwifiex_private *priv,
1134 return 0; 1134 return 0;
1135} 1135}
1136 1136
1137/* This function parse cal data from ASCII to hex */
1138static u32 mwifiex_parse_cal_cfg(u8 *src, size_t len, u8 *dst)
1139{
1140 u8 *s = src, *d = dst;
1141
1142 while (s - src < len) {
1143 if (*s && (isspace(*s) || *s == '\t')) {
1144 s++;
1145 continue;
1146 }
1147 if (isxdigit(*s)) {
1148 *d++ = simple_strtol(s, NULL, 16);
1149 s += 2;
1150 } else {
1151 s++;
1152 }
1153 }
1154
1155 return d - dst;
1156}
1157
1158/* This function prepares command of set_cfg_data. */
1159static int mwifiex_cmd_cfg_data(struct mwifiex_private *priv,
1160 struct host_cmd_ds_command *cmd,
1161 u16 cmd_action)
1162{
1163 struct host_cmd_ds_802_11_cfg_data *cfg_data = &cmd->params.cfg_data;
1164 struct mwifiex_adapter *adapter = priv->adapter;
1165 u32 len, cal_data_offset;
1166 u8 *tmp_cmd = (u8 *)cmd;
1167
1168 cal_data_offset = S_DS_GEN + sizeof(*cfg_data);
1169 if ((adapter->cal_data->data) && (adapter->cal_data->size > 0))
1170 len = mwifiex_parse_cal_cfg((u8 *)adapter->cal_data->data,
1171 adapter->cal_data->size,
1172 (u8 *)(tmp_cmd + cal_data_offset));
1173 else
1174 return -1;
1175
1176 cfg_data->action = cpu_to_le16(cmd_action);
1177 cfg_data->type = cpu_to_le16(CFG_DATA_TYPE_CAL);
1178 cfg_data->data_len = cpu_to_le16(len);
1179
1180 cmd->command = cpu_to_le16(HostCmd_CMD_CFG_DATA);
1181 cmd->size = cpu_to_le16(S_DS_GEN + sizeof(*cfg_data) + len);
1182
1183 return 0;
1184}
1185
1137/* 1186/*
1138 * This function prepares the commands before sending them to the firmware. 1187 * This function prepares the commands before sending them to the firmware.
1139 * 1188 *
@@ -1152,6 +1201,9 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no,
1152 case HostCmd_CMD_GET_HW_SPEC: 1201 case HostCmd_CMD_GET_HW_SPEC:
1153 ret = mwifiex_cmd_get_hw_spec(priv, cmd_ptr); 1202 ret = mwifiex_cmd_get_hw_spec(priv, cmd_ptr);
1154 break; 1203 break;
1204 case HostCmd_CMD_CFG_DATA:
1205 ret = mwifiex_cmd_cfg_data(priv, cmd_ptr, cmd_action);
1206 break;
1155 case HostCmd_CMD_MAC_CONTROL: 1207 case HostCmd_CMD_MAC_CONTROL:
1156 ret = mwifiex_cmd_mac_control(priv, cmd_ptr, cmd_action, 1208 ret = mwifiex_cmd_mac_control(priv, cmd_ptr, cmd_action,
1157 data_buf); 1209 data_buf);
@@ -1384,6 +1436,7 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no,
1384 */ 1436 */
1385int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta) 1437int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta)
1386{ 1438{
1439 struct mwifiex_adapter *adapter = priv->adapter;
1387 int ret; 1440 int ret;
1388 u16 enable = true; 1441 u16 enable = true;
1389 struct mwifiex_ds_11n_amsdu_aggr_ctrl amsdu_aggr_ctrl; 1442 struct mwifiex_ds_11n_amsdu_aggr_ctrl amsdu_aggr_ctrl;
@@ -1404,6 +1457,15 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta)
1404 HostCmd_ACT_GEN_SET, 0, NULL); 1457 HostCmd_ACT_GEN_SET, 0, NULL);
1405 if (ret) 1458 if (ret)
1406 return -1; 1459 return -1;
1460
1461 /* Download calibration data to firmware */
1462 if (adapter->cal_data) {
1463 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_CFG_DATA,
1464 HostCmd_ACT_GEN_SET, 0, NULL);
1465 if (ret)
1466 return -1;
1467 }
1468
1407 /* Read MAC address from HW */ 1469 /* Read MAC address from HW */
1408 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_GET_HW_SPEC, 1470 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_GET_HW_SPEC,
1409 HostCmd_ACT_GEN_GET, 0, NULL); 1471 HostCmd_ACT_GEN_GET, 0, NULL);
diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c
index 9f990e14966e..d85df158cc6c 100644
--- a/drivers/net/wireless/mwifiex/sta_cmdresp.c
+++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c
@@ -818,6 +818,18 @@ static int mwifiex_ret_subsc_evt(struct mwifiex_private *priv,
818 return 0; 818 return 0;
819} 819}
820 820
821/* This function handles the command response of set_cfg_data */
822static int mwifiex_ret_cfg_data(struct mwifiex_private *priv,
823 struct host_cmd_ds_command *resp)
824{
825 if (resp->result != HostCmd_RESULT_OK) {
826 dev_err(priv->adapter->dev, "Cal data cmd resp failed\n");
827 return -1;
828 }
829
830 return 0;
831}
832
821/* 833/*
822 * This function handles the command responses. 834 * This function handles the command responses.
823 * 835 *
@@ -841,6 +853,9 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no,
841 case HostCmd_CMD_GET_HW_SPEC: 853 case HostCmd_CMD_GET_HW_SPEC:
842 ret = mwifiex_ret_get_hw_spec(priv, resp); 854 ret = mwifiex_ret_get_hw_spec(priv, resp);
843 break; 855 break;
856 case HostCmd_CMD_CFG_DATA:
857 ret = mwifiex_ret_cfg_data(priv, resp);
858 break;
844 case HostCmd_CMD_MAC_CONTROL: 859 case HostCmd_CMD_MAC_CONTROL:
845 break; 860 break;
846 case HostCmd_CMD_802_11_MAC_ADDRESS: 861 case HostCmd_CMD_802_11_MAC_ADDRESS:
@@ -978,6 +993,8 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no,
978 case HostCmd_CMD_UAP_BSS_STOP: 993 case HostCmd_CMD_UAP_BSS_STOP:
979 priv->bss_started = 0; 994 priv->bss_started = 0;
980 break; 995 break;
996 case HostCmd_CMD_UAP_STA_DEAUTH:
997 break;
981 case HostCmd_CMD_MEF_CFG: 998 case HostCmd_CMD_MEF_CFG:
982 break; 999 break;
983 default: 1000 default:
diff --git a/drivers/net/wireless/mwifiex/uap_cmd.c b/drivers/net/wireless/mwifiex/uap_cmd.c
index b04b1db29100..2de882dead0f 100644
--- a/drivers/net/wireless/mwifiex/uap_cmd.c
+++ b/drivers/net/wireless/mwifiex/uap_cmd.c
@@ -689,6 +689,23 @@ mwifiex_cmd_uap_sys_config(struct host_cmd_ds_command *cmd, u16 cmd_action,
689 return 0; 689 return 0;
690} 690}
691 691
692/* This function prepares AP specific deauth command with mac supplied in
693 * function parameter.
694 */
695static int mwifiex_cmd_uap_sta_deauth(struct mwifiex_private *priv,
696 struct host_cmd_ds_command *cmd, u8 *mac)
697{
698 struct host_cmd_ds_sta_deauth *sta_deauth = &cmd->params.sta_deauth;
699
700 cmd->command = cpu_to_le16(HostCmd_CMD_UAP_STA_DEAUTH);
701 memcpy(sta_deauth->mac, mac, ETH_ALEN);
702 sta_deauth->reason = cpu_to_le16(WLAN_REASON_DEAUTH_LEAVING);
703
704 cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_sta_deauth) +
705 S_DS_GEN);
706 return 0;
707}
708
692/* This function prepares the AP specific commands before sending them 709/* This function prepares the AP specific commands before sending them
693 * to the firmware. 710 * to the firmware.
694 * This is a generic function which calls specific command preparation 711 * This is a generic function which calls specific command preparation
@@ -710,6 +727,10 @@ int mwifiex_uap_prepare_cmd(struct mwifiex_private *priv, u16 cmd_no,
710 cmd->command = cpu_to_le16(cmd_no); 727 cmd->command = cpu_to_le16(cmd_no);
711 cmd->size = cpu_to_le16(S_DS_GEN); 728 cmd->size = cpu_to_le16(S_DS_GEN);
712 break; 729 break;
730 case HostCmd_CMD_UAP_STA_DEAUTH:
731 if (mwifiex_cmd_uap_sta_deauth(priv, cmd, data_buf))
732 return -1;
733 break;
713 default: 734 default:
714 dev_err(priv->adapter->dev, 735 dev_err(priv->adapter->dev,
715 "PREP_CMD: unknown cmd %#x\n", cmd_no); 736 "PREP_CMD: unknown cmd %#x\n", cmd_no);
diff --git a/drivers/net/wireless/mwifiex/uap_event.c b/drivers/net/wireless/mwifiex/uap_event.c
index 21c640d3b579..718066577c6c 100644
--- a/drivers/net/wireless/mwifiex/uap_event.c
+++ b/drivers/net/wireless/mwifiex/uap_event.c
@@ -107,18 +107,15 @@ mwifiex_set_sta_ht_cap(struct mwifiex_private *priv, const u8 *ies,
107 */ 107 */
108static void mwifiex_del_sta_entry(struct mwifiex_private *priv, u8 *mac) 108static void mwifiex_del_sta_entry(struct mwifiex_private *priv, u8 *mac)
109{ 109{
110 struct mwifiex_sta_node *node, *tmp; 110 struct mwifiex_sta_node *node;
111 unsigned long flags; 111 unsigned long flags;
112 112
113 spin_lock_irqsave(&priv->sta_list_spinlock, flags); 113 spin_lock_irqsave(&priv->sta_list_spinlock, flags);
114 114
115 node = mwifiex_get_sta_entry(priv, mac); 115 node = mwifiex_get_sta_entry(priv, mac);
116 if (node) { 116 if (node) {
117 list_for_each_entry_safe(node, tmp, &priv->sta_list, 117 list_del(&node->list);
118 list) { 118 kfree(node);
119 list_del(&node->list);
120 kfree(node);
121 }
122 } 119 }
123 120
124 spin_unlock_irqrestore(&priv->sta_list_spinlock, flags); 121 spin_unlock_irqrestore(&priv->sta_list_spinlock, flags);
@@ -295,3 +292,19 @@ int mwifiex_process_uap_event(struct mwifiex_private *priv)
295 292
296 return 0; 293 return 0;
297} 294}
295
296/* This function deletes station entry from associated station list.
297 * Also if both AP and STA are 11n enabled, RxReorder tables and TxBA stream
298 * tables created for this station are deleted.
299 */
300void mwifiex_uap_del_sta_data(struct mwifiex_private *priv,
301 struct mwifiex_sta_node *node)
302{
303 if (priv->ap_11n_enabled && node->is_11n_enabled) {
304 mwifiex_11n_del_rx_reorder_tbl_by_ta(priv, node->mac_addr);
305 mwifiex_del_tx_ba_stream_tbl_by_ra(priv, node->mac_addr);
306 }
307 mwifiex_del_sta_entry(priv, node->mac_addr);
308
309 return;
310}
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index 6820fce4016b..a3707fd4ef62 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -1548,7 +1548,7 @@ static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw)
1548 if (!priv->pending_tx_pkts) 1548 if (!priv->pending_tx_pkts)
1549 return 0; 1549 return 0;
1550 1550
1551 retry = 0; 1551 retry = 1;
1552 rc = 0; 1552 rc = 0;
1553 1553
1554 spin_lock_bh(&priv->tx_lock); 1554 spin_lock_bh(&priv->tx_lock);
@@ -1572,13 +1572,19 @@ static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw)
1572 1572
1573 spin_lock_bh(&priv->tx_lock); 1573 spin_lock_bh(&priv->tx_lock);
1574 1574
1575 if (timeout) { 1575 if (timeout || !priv->pending_tx_pkts) {
1576 WARN_ON(priv->pending_tx_pkts); 1576 WARN_ON(priv->pending_tx_pkts);
1577 if (retry) 1577 if (retry)
1578 wiphy_notice(hw->wiphy, "tx rings drained\n"); 1578 wiphy_notice(hw->wiphy, "tx rings drained\n");
1579 break; 1579 break;
1580 } 1580 }
1581 1581
1582 if (retry) {
1583 mwl8k_tx_start(priv);
1584 retry = 0;
1585 continue;
1586 }
1587
1582 if (priv->pending_tx_pkts < oldcount) { 1588 if (priv->pending_tx_pkts < oldcount) {
1583 wiphy_notice(hw->wiphy, 1589 wiphy_notice(hw->wiphy,
1584 "waiting for tx rings to drain (%d -> %d pkts)\n", 1590 "waiting for tx rings to drain (%d -> %d pkts)\n",
@@ -2055,6 +2061,7 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw,
2055 mwl8k_remove_stream(hw, stream); 2061 mwl8k_remove_stream(hw, stream);
2056 spin_unlock(&priv->stream_lock); 2062 spin_unlock(&priv->stream_lock);
2057 } 2063 }
2064 mwl8k_tx_start(priv);
2058 spin_unlock_bh(&priv->tx_lock); 2065 spin_unlock_bh(&priv->tx_lock);
2059 pci_unmap_single(priv->pdev, dma, skb->len, 2066 pci_unmap_single(priv->pdev, dma, skb->len,
2060 PCI_DMA_TODEVICE); 2067 PCI_DMA_TODEVICE);
diff --git a/drivers/net/wireless/p54/p54spi.c b/drivers/net/wireless/p54/p54spi.c
index 978e7eb26567..7fc46f26cf2b 100644
--- a/drivers/net/wireless/p54/p54spi.c
+++ b/drivers/net/wireless/p54/p54spi.c
@@ -42,8 +42,7 @@
42 42
43MODULE_FIRMWARE("3826.arm"); 43MODULE_FIRMWARE("3826.arm");
44 44
45/* 45/* gpios should be handled in board files and provided via platform data,
46 * gpios should be handled in board files and provided via platform data,
47 * but because it's currently impossible for p54spi to have a header file 46 * but because it's currently impossible for p54spi to have a header file
48 * in include/linux, let's use module paramaters for now 47 * in include/linux, let's use module paramaters for now
49 */ 48 */
@@ -191,8 +190,7 @@ static int p54spi_request_eeprom(struct ieee80211_hw *dev)
191 const struct firmware *eeprom; 190 const struct firmware *eeprom;
192 int ret; 191 int ret;
193 192
194 /* 193 /* allow users to customize their eeprom.
195 * allow users to customize their eeprom.
196 */ 194 */
197 195
198 ret = request_firmware(&eeprom, "3826.eeprom", &priv->spi->dev); 196 ret = request_firmware(&eeprom, "3826.eeprom", &priv->spi->dev);
@@ -285,8 +283,7 @@ static void p54spi_power_on(struct p54s_priv *priv)
285 gpio_set_value(p54spi_gpio_power, 1); 283 gpio_set_value(p54spi_gpio_power, 1);
286 enable_irq(gpio_to_irq(p54spi_gpio_irq)); 284 enable_irq(gpio_to_irq(p54spi_gpio_irq));
287 285
288 /* 286 /* need to wait a while before device can be accessed, the length
289 * need to wait a while before device can be accessed, the length
290 * is just a guess 287 * is just a guess
291 */ 288 */
292 msleep(10); 289 msleep(10);
@@ -365,7 +362,8 @@ static int p54spi_rx(struct p54s_priv *priv)
365 /* Firmware may insert up to 4 padding bytes after the lmac header, 362 /* Firmware may insert up to 4 padding bytes after the lmac header,
366 * but it does not amend the size of SPI data transfer. 363 * but it does not amend the size of SPI data transfer.
367 * Such packets has correct data size in header, thus referencing 364 * Such packets has correct data size in header, thus referencing
368 * past the end of allocated skb. Reserve extra 4 bytes for this case */ 365 * past the end of allocated skb. Reserve extra 4 bytes for this case
366 */
369 skb = dev_alloc_skb(len + 4); 367 skb = dev_alloc_skb(len + 4);
370 if (!skb) { 368 if (!skb) {
371 p54spi_sleep(priv); 369 p54spi_sleep(priv);
@@ -383,7 +381,8 @@ static int p54spi_rx(struct p54s_priv *priv)
383 } 381 }
384 p54spi_sleep(priv); 382 p54spi_sleep(priv);
385 /* Put additional bytes to compensate for the possible 383 /* Put additional bytes to compensate for the possible
386 * alignment-caused truncation */ 384 * alignment-caused truncation
385 */
387 skb_put(skb, 4); 386 skb_put(skb, 4);
388 387
389 if (p54_rx(priv->hw, skb) == 0) 388 if (p54_rx(priv->hw, skb) == 0)
@@ -713,27 +712,7 @@ static struct spi_driver p54spi_driver = {
713 .remove = p54spi_remove, 712 .remove = p54spi_remove,
714}; 713};
715 714
716static int __init p54spi_init(void) 715module_spi_driver(p54spi_driver);
717{
718 int ret;
719
720 ret = spi_register_driver(&p54spi_driver);
721 if (ret < 0) {
722 printk(KERN_ERR "failed to register SPI driver: %d", ret);
723 goto out;
724 }
725
726out:
727 return ret;
728}
729
730static void __exit p54spi_exit(void)
731{
732 spi_unregister_driver(&p54spi_driver);
733}
734
735module_init(p54spi_init);
736module_exit(p54spi_exit);
737 716
738MODULE_LICENSE("GPL"); 717MODULE_LICENSE("GPL");
739MODULE_AUTHOR("Christian Lamparter <chunkeey@web.de>"); 718MODULE_AUTHOR("Christian Lamparter <chunkeey@web.de>");
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index b52d70c75e1a..ead3a3e746a2 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -840,7 +840,7 @@ static inline void rt2800_clear_beacon_register(struct rt2x00_dev *rt2x00dev,
840 unsigned int beacon_base) 840 unsigned int beacon_base)
841{ 841{
842 int i; 842 int i;
843 const int txwi_desc_size = rt2x00dev->ops->bcn->winfo_size; 843 const int txwi_desc_size = rt2x00dev->bcn->winfo_size;
844 844
845 /* 845 /*
846 * For the Beacon base registers we only need to clear 846 * For the Beacon base registers we only need to clear
@@ -3953,379 +3953,577 @@ static void rt2800_init_bbp_early(struct rt2x00_dev *rt2x00dev)
3953 rt2800_bbp_write(rt2x00dev, 106, 0x35); 3953 rt2800_bbp_write(rt2x00dev, 106, 0x35);
3954} 3954}
3955 3955
3956static void rt2800_init_bbp_5592(struct rt2x00_dev *rt2x00dev) 3956static void rt2800_disable_unused_dac_adc(struct rt2x00_dev *rt2x00dev)
3957{ 3957{
3958 int ant, div_mode;
3959 u16 eeprom; 3958 u16 eeprom;
3960 u8 value; 3959 u8 value;
3961 3960
3962 rt2800_init_bbp_early(rt2x00dev); 3961 rt2800_bbp_read(rt2x00dev, 138, &value);
3962 rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom);
3963 if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_TXPATH) == 1)
3964 value |= 0x20;
3965 if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH) == 1)
3966 value &= ~0x02;
3967 rt2800_bbp_write(rt2x00dev, 138, value);
3968}
3963 3969
3964 rt2800_bbp_read(rt2x00dev, 105, &value); 3970static void rt2800_init_bbp_305x_soc(struct rt2x00_dev *rt2x00dev)
3965 rt2x00_set_field8(&value, BBP105_MLD, 3971{
3966 rt2x00dev->default_ant.rx_chain_num == 2); 3972 rt2800_bbp_write(rt2x00dev, 31, 0x08);
3967 rt2800_bbp_write(rt2x00dev, 105, value); 3973
3974 rt2800_bbp_write(rt2x00dev, 65, 0x2c);
3975 rt2800_bbp_write(rt2x00dev, 66, 0x38);
3976
3977 rt2800_bbp_write(rt2x00dev, 69, 0x12);
3978 rt2800_bbp_write(rt2x00dev, 73, 0x10);
3979
3980 rt2800_bbp_write(rt2x00dev, 70, 0x0a);
3981
3982 rt2800_bbp_write(rt2x00dev, 78, 0x0e);
3983 rt2800_bbp_write(rt2x00dev, 80, 0x08);
3984
3985 rt2800_bbp_write(rt2x00dev, 82, 0x62);
3986
3987 rt2800_bbp_write(rt2x00dev, 83, 0x6a);
3988
3989 rt2800_bbp_write(rt2x00dev, 84, 0x99);
3990
3991 rt2800_bbp_write(rt2x00dev, 86, 0x00);
3992
3993 rt2800_bbp_write(rt2x00dev, 91, 0x04);
3994
3995 rt2800_bbp_write(rt2x00dev, 92, 0x00);
3996
3997 rt2800_bbp_write(rt2x00dev, 103, 0xc0);
3998
3999 rt2800_bbp_write(rt2x00dev, 105, 0x01);
4000
4001 rt2800_bbp_write(rt2x00dev, 106, 0x35);
4002}
4003
4004static void rt2800_init_bbp_28xx(struct rt2x00_dev *rt2x00dev)
4005{
4006 rt2800_bbp_write(rt2x00dev, 65, 0x2c);
4007 rt2800_bbp_write(rt2x00dev, 66, 0x38);
4008
4009 if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860C)) {
4010 rt2800_bbp_write(rt2x00dev, 69, 0x16);
4011 rt2800_bbp_write(rt2x00dev, 73, 0x12);
4012 } else {
4013 rt2800_bbp_write(rt2x00dev, 69, 0x12);
4014 rt2800_bbp_write(rt2x00dev, 73, 0x10);
4015 }
4016
4017 rt2800_bbp_write(rt2x00dev, 70, 0x0a);
4018
4019 rt2800_bbp_write(rt2x00dev, 81, 0x37);
4020
4021 rt2800_bbp_write(rt2x00dev, 82, 0x62);
4022
4023 rt2800_bbp_write(rt2x00dev, 83, 0x6a);
4024
4025 if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860D))
4026 rt2800_bbp_write(rt2x00dev, 84, 0x19);
4027 else
4028 rt2800_bbp_write(rt2x00dev, 84, 0x99);
4029
4030 rt2800_bbp_write(rt2x00dev, 86, 0x00);
4031
4032 rt2800_bbp_write(rt2x00dev, 91, 0x04);
4033
4034 rt2800_bbp_write(rt2x00dev, 92, 0x00);
4035
4036 rt2800_bbp_write(rt2x00dev, 103, 0x00);
4037
4038 rt2800_bbp_write(rt2x00dev, 105, 0x05);
4039
4040 rt2800_bbp_write(rt2x00dev, 106, 0x35);
4041}
4042
4043static void rt2800_init_bbp_30xx(struct rt2x00_dev *rt2x00dev)
4044{
4045 rt2800_bbp_write(rt2x00dev, 65, 0x2c);
4046 rt2800_bbp_write(rt2x00dev, 66, 0x38);
4047
4048 rt2800_bbp_write(rt2x00dev, 69, 0x12);
4049 rt2800_bbp_write(rt2x00dev, 73, 0x10);
4050
4051 rt2800_bbp_write(rt2x00dev, 70, 0x0a);
4052
4053 rt2800_bbp_write(rt2x00dev, 79, 0x13);
4054 rt2800_bbp_write(rt2x00dev, 80, 0x05);
4055 rt2800_bbp_write(rt2x00dev, 81, 0x33);
4056
4057 rt2800_bbp_write(rt2x00dev, 82, 0x62);
4058
4059 rt2800_bbp_write(rt2x00dev, 83, 0x6a);
4060
4061 rt2800_bbp_write(rt2x00dev, 84, 0x99);
4062
4063 rt2800_bbp_write(rt2x00dev, 86, 0x00);
4064
4065 rt2800_bbp_write(rt2x00dev, 91, 0x04);
4066
4067 rt2800_bbp_write(rt2x00dev, 92, 0x00);
4068
4069 if (rt2x00_rt_rev_gte(rt2x00dev, RT3070, REV_RT3070F) ||
4070 rt2x00_rt_rev_gte(rt2x00dev, RT3071, REV_RT3071E) ||
4071 rt2x00_rt_rev_gte(rt2x00dev, RT3090, REV_RT3090E))
4072 rt2800_bbp_write(rt2x00dev, 103, 0xc0);
4073 else
4074 rt2800_bbp_write(rt2x00dev, 103, 0x00);
4075
4076 rt2800_bbp_write(rt2x00dev, 105, 0x05);
4077
4078 rt2800_bbp_write(rt2x00dev, 106, 0x35);
4079
4080 if (rt2x00_rt(rt2x00dev, RT3071) ||
4081 rt2x00_rt(rt2x00dev, RT3090))
4082 rt2800_disable_unused_dac_adc(rt2x00dev);
4083}
4084
4085static void rt2800_init_bbp_3290(struct rt2x00_dev *rt2x00dev)
4086{
4087 u8 value;
3968 4088
3969 rt2800_bbp4_mac_if_ctrl(rt2x00dev); 4089 rt2800_bbp4_mac_if_ctrl(rt2x00dev);
3970 4090
3971 rt2800_bbp_write(rt2x00dev, 20, 0x06);
3972 rt2800_bbp_write(rt2x00dev, 31, 0x08); 4091 rt2800_bbp_write(rt2x00dev, 31, 0x08);
3973 rt2800_bbp_write(rt2x00dev, 65, 0x2C); 4092
3974 rt2800_bbp_write(rt2x00dev, 68, 0xDD); 4093 rt2800_bbp_write(rt2x00dev, 65, 0x2c);
3975 rt2800_bbp_write(rt2x00dev, 69, 0x1A); 4094 rt2800_bbp_write(rt2x00dev, 66, 0x38);
3976 rt2800_bbp_write(rt2x00dev, 70, 0x05); 4095
4096 rt2800_bbp_write(rt2x00dev, 68, 0x0b);
4097
4098 rt2800_bbp_write(rt2x00dev, 69, 0x12);
3977 rt2800_bbp_write(rt2x00dev, 73, 0x13); 4099 rt2800_bbp_write(rt2x00dev, 73, 0x13);
3978 rt2800_bbp_write(rt2x00dev, 74, 0x0F); 4100 rt2800_bbp_write(rt2x00dev, 75, 0x46);
3979 rt2800_bbp_write(rt2x00dev, 75, 0x4F);
3980 rt2800_bbp_write(rt2x00dev, 76, 0x28); 4101 rt2800_bbp_write(rt2x00dev, 76, 0x28);
4102
4103 rt2800_bbp_write(rt2x00dev, 77, 0x58);
4104
4105 rt2800_bbp_write(rt2x00dev, 70, 0x0a);
4106
4107 rt2800_bbp_write(rt2x00dev, 74, 0x0b);
4108 rt2800_bbp_write(rt2x00dev, 79, 0x18);
4109 rt2800_bbp_write(rt2x00dev, 80, 0x09);
4110 rt2800_bbp_write(rt2x00dev, 81, 0x33);
4111
4112 rt2800_bbp_write(rt2x00dev, 82, 0x62);
4113
4114 rt2800_bbp_write(rt2x00dev, 83, 0x7a);
4115
4116 rt2800_bbp_write(rt2x00dev, 84, 0x9a);
4117
4118 rt2800_bbp_write(rt2x00dev, 86, 0x38);
4119
4120 rt2800_bbp_write(rt2x00dev, 91, 0x04);
4121
4122 rt2800_bbp_write(rt2x00dev, 92, 0x02);
4123
4124 rt2800_bbp_write(rt2x00dev, 103, 0xc0);
4125
4126 rt2800_bbp_write(rt2x00dev, 104, 0x92);
4127
4128 rt2800_bbp_write(rt2x00dev, 105, 0x1c);
4129
4130 rt2800_bbp_write(rt2x00dev, 106, 0x03);
4131
4132 rt2800_bbp_write(rt2x00dev, 128, 0x12);
4133
4134 rt2800_bbp_write(rt2x00dev, 67, 0x24);
4135 rt2800_bbp_write(rt2x00dev, 143, 0x04);
4136 rt2800_bbp_write(rt2x00dev, 142, 0x99);
4137 rt2800_bbp_write(rt2x00dev, 150, 0x30);
4138 rt2800_bbp_write(rt2x00dev, 151, 0x2e);
4139 rt2800_bbp_write(rt2x00dev, 152, 0x20);
4140 rt2800_bbp_write(rt2x00dev, 153, 0x34);
4141 rt2800_bbp_write(rt2x00dev, 154, 0x40);
4142 rt2800_bbp_write(rt2x00dev, 155, 0x3b);
4143 rt2800_bbp_write(rt2x00dev, 253, 0x04);
4144
4145 rt2800_bbp_read(rt2x00dev, 47, &value);
4146 rt2x00_set_field8(&value, BBP47_TSSI_ADC6, 1);
4147 rt2800_bbp_write(rt2x00dev, 47, value);
4148
4149 /* Use 5-bit ADC for Acquisition and 8-bit ADC for data */
4150 rt2800_bbp_read(rt2x00dev, 3, &value);
4151 rt2x00_set_field8(&value, BBP3_ADC_MODE_SWITCH, 1);
4152 rt2x00_set_field8(&value, BBP3_ADC_INIT_MODE, 1);
4153 rt2800_bbp_write(rt2x00dev, 3, value);
4154}
4155
4156static void rt2800_init_bbp_3352(struct rt2x00_dev *rt2x00dev)
4157{
4158 rt2800_bbp_write(rt2x00dev, 3, 0x00);
4159 rt2800_bbp_write(rt2x00dev, 4, 0x50);
4160
4161 rt2800_bbp_write(rt2x00dev, 31, 0x08);
4162
4163 rt2800_bbp_write(rt2x00dev, 47, 0x48);
4164
4165 rt2800_bbp_write(rt2x00dev, 65, 0x2c);
4166 rt2800_bbp_write(rt2x00dev, 66, 0x38);
4167
4168 rt2800_bbp_write(rt2x00dev, 68, 0x0b);
4169
4170 rt2800_bbp_write(rt2x00dev, 69, 0x12);
4171 rt2800_bbp_write(rt2x00dev, 73, 0x13);
4172 rt2800_bbp_write(rt2x00dev, 75, 0x46);
4173 rt2800_bbp_write(rt2x00dev, 76, 0x28);
4174
3981 rt2800_bbp_write(rt2x00dev, 77, 0x59); 4175 rt2800_bbp_write(rt2x00dev, 77, 0x59);
3982 rt2800_bbp_write(rt2x00dev, 84, 0x9A); 4176
4177 rt2800_bbp_write(rt2x00dev, 70, 0x0a);
4178
4179 rt2800_bbp_write(rt2x00dev, 78, 0x0e);
4180 rt2800_bbp_write(rt2x00dev, 80, 0x08);
4181 rt2800_bbp_write(rt2x00dev, 81, 0x37);
4182
4183 rt2800_bbp_write(rt2x00dev, 82, 0x62);
4184
4185 rt2800_bbp_write(rt2x00dev, 83, 0x6a);
4186
4187 rt2800_bbp_write(rt2x00dev, 84, 0x99);
4188
3983 rt2800_bbp_write(rt2x00dev, 86, 0x38); 4189 rt2800_bbp_write(rt2x00dev, 86, 0x38);
4190
3984 rt2800_bbp_write(rt2x00dev, 88, 0x90); 4191 rt2800_bbp_write(rt2x00dev, 88, 0x90);
4192
3985 rt2800_bbp_write(rt2x00dev, 91, 0x04); 4193 rt2800_bbp_write(rt2x00dev, 91, 0x04);
4194
3986 rt2800_bbp_write(rt2x00dev, 92, 0x02); 4195 rt2800_bbp_write(rt2x00dev, 92, 0x02);
3987 rt2800_bbp_write(rt2x00dev, 95, 0x9a); 4196
3988 rt2800_bbp_write(rt2x00dev, 98, 0x12); 4197 rt2800_bbp_write(rt2x00dev, 103, 0xc0);
3989 rt2800_bbp_write(rt2x00dev, 103, 0xC0); 4198
3990 rt2800_bbp_write(rt2x00dev, 104, 0x92); 4199 rt2800_bbp_write(rt2x00dev, 104, 0x92);
3991 /* FIXME BBP105 owerwrite */
3992 rt2800_bbp_write(rt2x00dev, 105, 0x3C);
3993 rt2800_bbp_write(rt2x00dev, 106, 0x35);
3994 rt2800_bbp_write(rt2x00dev, 128, 0x12);
3995 rt2800_bbp_write(rt2x00dev, 134, 0xD0);
3996 rt2800_bbp_write(rt2x00dev, 135, 0xF6);
3997 rt2800_bbp_write(rt2x00dev, 137, 0x0F);
3998 4200
3999 /* Initialize GLRT (Generalized Likehood Radio Test) */ 4201 rt2800_bbp_write(rt2x00dev, 105, 0x34);
4000 rt2800_init_bbp_5592_glrt(rt2x00dev); 4202
4203 rt2800_bbp_write(rt2x00dev, 106, 0x05);
4204
4205 rt2800_bbp_write(rt2x00dev, 120, 0x50);
4206
4207 rt2800_bbp_write(rt2x00dev, 137, 0x0f);
4208
4209 rt2800_bbp_write(rt2x00dev, 163, 0xbd);
4210 /* Set ITxBF timeout to 0x9c40=1000msec */
4211 rt2800_bbp_write(rt2x00dev, 179, 0x02);
4212 rt2800_bbp_write(rt2x00dev, 180, 0x00);
4213 rt2800_bbp_write(rt2x00dev, 182, 0x40);
4214 rt2800_bbp_write(rt2x00dev, 180, 0x01);
4215 rt2800_bbp_write(rt2x00dev, 182, 0x9c);
4216 rt2800_bbp_write(rt2x00dev, 179, 0x00);
4217 /* Reprogram the inband interface to put right values in RXWI */
4218 rt2800_bbp_write(rt2x00dev, 142, 0x04);
4219 rt2800_bbp_write(rt2x00dev, 143, 0x3b);
4220 rt2800_bbp_write(rt2x00dev, 142, 0x06);
4221 rt2800_bbp_write(rt2x00dev, 143, 0xa0);
4222 rt2800_bbp_write(rt2x00dev, 142, 0x07);
4223 rt2800_bbp_write(rt2x00dev, 143, 0xa1);
4224 rt2800_bbp_write(rt2x00dev, 142, 0x08);
4225 rt2800_bbp_write(rt2x00dev, 143, 0xa2);
4226
4227 rt2800_bbp_write(rt2x00dev, 148, 0xc8);
4228}
4001 4229
4002 rt2800_bbp4_mac_if_ctrl(rt2x00dev); 4230static void rt2800_init_bbp_3390(struct rt2x00_dev *rt2x00dev)
4231{
4232 rt2800_bbp_write(rt2x00dev, 65, 0x2c);
4233 rt2800_bbp_write(rt2x00dev, 66, 0x38);
4003 4234
4004 rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom); 4235 rt2800_bbp_write(rt2x00dev, 69, 0x12);
4005 div_mode = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_ANT_DIVERSITY); 4236 rt2800_bbp_write(rt2x00dev, 73, 0x10);
4006 ant = (div_mode == 3) ? 1 : 0;
4007 rt2800_bbp_read(rt2x00dev, 152, &value);
4008 if (ant == 0) {
4009 /* Main antenna */
4010 rt2x00_set_field8(&value, BBP152_RX_DEFAULT_ANT, 1);
4011 } else {
4012 /* Auxiliary antenna */
4013 rt2x00_set_field8(&value, BBP152_RX_DEFAULT_ANT, 0);
4014 }
4015 rt2800_bbp_write(rt2x00dev, 152, value);
4016 4237
4017 if (rt2x00_rt_rev_gte(rt2x00dev, RT5592, REV_RT5592C)) { 4238 rt2800_bbp_write(rt2x00dev, 70, 0x0a);
4018 rt2800_bbp_read(rt2x00dev, 254, &value);
4019 rt2x00_set_field8(&value, BBP254_BIT7, 1);
4020 rt2800_bbp_write(rt2x00dev, 254, value);
4021 }
4022 4239
4023 rt2800_init_freq_calibration(rt2x00dev); 4240 rt2800_bbp_write(rt2x00dev, 79, 0x13);
4241 rt2800_bbp_write(rt2x00dev, 80, 0x05);
4242 rt2800_bbp_write(rt2x00dev, 81, 0x33);
4024 4243
4025 rt2800_bbp_write(rt2x00dev, 84, 0x19); 4244 rt2800_bbp_write(rt2x00dev, 82, 0x62);
4026 if (rt2x00_rt_rev_gte(rt2x00dev, RT5592, REV_RT5592C)) 4245
4246 rt2800_bbp_write(rt2x00dev, 83, 0x6a);
4247
4248 rt2800_bbp_write(rt2x00dev, 84, 0x99);
4249
4250 rt2800_bbp_write(rt2x00dev, 86, 0x00);
4251
4252 rt2800_bbp_write(rt2x00dev, 91, 0x04);
4253
4254 rt2800_bbp_write(rt2x00dev, 92, 0x00);
4255
4256 if (rt2x00_rt_rev_gte(rt2x00dev, RT3390, REV_RT3390E))
4027 rt2800_bbp_write(rt2x00dev, 103, 0xc0); 4257 rt2800_bbp_write(rt2x00dev, 103, 0xc0);
4258 else
4259 rt2800_bbp_write(rt2x00dev, 103, 0x00);
4260
4261 rt2800_bbp_write(rt2x00dev, 105, 0x05);
4262
4263 rt2800_bbp_write(rt2x00dev, 106, 0x35);
4264
4265 rt2800_disable_unused_dac_adc(rt2x00dev);
4028} 4266}
4029 4267
4030static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) 4268static void rt2800_init_bbp_3572(struct rt2x00_dev *rt2x00dev)
4031{ 4269{
4032 unsigned int i; 4270 rt2800_bbp_write(rt2x00dev, 31, 0x08);
4033 u16 eeprom;
4034 u8 reg_id;
4035 u8 value;
4036 4271
4037 if (unlikely(rt2800_wait_bbp_rf_ready(rt2x00dev) || 4272 rt2800_bbp_write(rt2x00dev, 65, 0x2c);
4038 rt2800_wait_bbp_ready(rt2x00dev))) 4273 rt2800_bbp_write(rt2x00dev, 66, 0x38);
4039 return -EACCES;
4040 4274
4041 if (rt2x00_rt(rt2x00dev, RT5592)) { 4275 rt2800_bbp_write(rt2x00dev, 69, 0x12);
4042 rt2800_init_bbp_5592(rt2x00dev); 4276 rt2800_bbp_write(rt2x00dev, 73, 0x10);
4043 return 0;
4044 }
4045 4277
4046 if (rt2x00_rt(rt2x00dev, RT3352)) { 4278 rt2800_bbp_write(rt2x00dev, 70, 0x0a);
4047 rt2800_bbp_write(rt2x00dev, 3, 0x00);
4048 rt2800_bbp_write(rt2x00dev, 4, 0x50);
4049 }
4050 4279
4051 if (rt2x00_rt(rt2x00dev, RT3290) || 4280 rt2800_bbp_write(rt2x00dev, 79, 0x13);
4052 rt2x00_rt(rt2x00dev, RT5390) || 4281 rt2800_bbp_write(rt2x00dev, 80, 0x05);
4053 rt2x00_rt(rt2x00dev, RT5392)) 4282 rt2800_bbp_write(rt2x00dev, 81, 0x33);
4054 rt2800_bbp4_mac_if_ctrl(rt2x00dev);
4055 4283
4056 if (rt2800_is_305x_soc(rt2x00dev) || 4284 rt2800_bbp_write(rt2x00dev, 82, 0x62);
4057 rt2x00_rt(rt2x00dev, RT3290) ||
4058 rt2x00_rt(rt2x00dev, RT3352) ||
4059 rt2x00_rt(rt2x00dev, RT3572) ||
4060 rt2x00_rt(rt2x00dev, RT5390) ||
4061 rt2x00_rt(rt2x00dev, RT5392))
4062 rt2800_bbp_write(rt2x00dev, 31, 0x08);
4063 4285
4064 if (rt2x00_rt(rt2x00dev, RT3352)) 4286 rt2800_bbp_write(rt2x00dev, 83, 0x6a);
4065 rt2800_bbp_write(rt2x00dev, 47, 0x48); 4287
4288 rt2800_bbp_write(rt2x00dev, 84, 0x99);
4289
4290 rt2800_bbp_write(rt2x00dev, 86, 0x00);
4291
4292 rt2800_bbp_write(rt2x00dev, 91, 0x04);
4293
4294 rt2800_bbp_write(rt2x00dev, 92, 0x00);
4295
4296 rt2800_bbp_write(rt2x00dev, 103, 0xc0);
4297
4298 rt2800_bbp_write(rt2x00dev, 105, 0x05);
4299
4300 rt2800_bbp_write(rt2x00dev, 106, 0x35);
4301
4302 rt2800_disable_unused_dac_adc(rt2x00dev);
4303}
4304
4305static void rt2800_init_bbp_53xx(struct rt2x00_dev *rt2x00dev)
4306{
4307 int ant, div_mode;
4308 u16 eeprom;
4309 u8 value;
4310
4311 rt2800_bbp4_mac_if_ctrl(rt2x00dev);
4312
4313 rt2800_bbp_write(rt2x00dev, 31, 0x08);
4066 4314
4067 rt2800_bbp_write(rt2x00dev, 65, 0x2c); 4315 rt2800_bbp_write(rt2x00dev, 65, 0x2c);
4068 rt2800_bbp_write(rt2x00dev, 66, 0x38); 4316 rt2800_bbp_write(rt2x00dev, 66, 0x38);
4069 4317
4070 if (rt2x00_rt(rt2x00dev, RT3290) || 4318 rt2800_bbp_write(rt2x00dev, 68, 0x0b);
4071 rt2x00_rt(rt2x00dev, RT3352) ||
4072 rt2x00_rt(rt2x00dev, RT5390) ||
4073 rt2x00_rt(rt2x00dev, RT5392))
4074 rt2800_bbp_write(rt2x00dev, 68, 0x0b);
4075 4319
4076 if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860C)) { 4320 rt2800_bbp_write(rt2x00dev, 69, 0x12);
4077 rt2800_bbp_write(rt2x00dev, 69, 0x16); 4321 rt2800_bbp_write(rt2x00dev, 73, 0x13);
4078 rt2800_bbp_write(rt2x00dev, 73, 0x12); 4322 rt2800_bbp_write(rt2x00dev, 75, 0x46);
4079 } else if (rt2x00_rt(rt2x00dev, RT3290) || 4323 rt2800_bbp_write(rt2x00dev, 76, 0x28);
4080 rt2x00_rt(rt2x00dev, RT3352) ||
4081 rt2x00_rt(rt2x00dev, RT5390) ||
4082 rt2x00_rt(rt2x00dev, RT5392)) {
4083 rt2800_bbp_write(rt2x00dev, 69, 0x12);
4084 rt2800_bbp_write(rt2x00dev, 73, 0x13);
4085 rt2800_bbp_write(rt2x00dev, 75, 0x46);
4086 rt2800_bbp_write(rt2x00dev, 76, 0x28);
4087 4324
4088 if (rt2x00_rt(rt2x00dev, RT3290)) 4325 rt2800_bbp_write(rt2x00dev, 77, 0x59);
4089 rt2800_bbp_write(rt2x00dev, 77, 0x58);
4090 else
4091 rt2800_bbp_write(rt2x00dev, 77, 0x59);
4092 } else {
4093 rt2800_bbp_write(rt2x00dev, 69, 0x12);
4094 rt2800_bbp_write(rt2x00dev, 73, 0x10);
4095 }
4096 4326
4097 rt2800_bbp_write(rt2x00dev, 70, 0x0a); 4327 rt2800_bbp_write(rt2x00dev, 70, 0x0a);
4098 4328
4099 if (rt2x00_rt(rt2x00dev, RT3070) || 4329 rt2800_bbp_write(rt2x00dev, 79, 0x13);
4100 rt2x00_rt(rt2x00dev, RT3071) || 4330 rt2800_bbp_write(rt2x00dev, 80, 0x05);
4101 rt2x00_rt(rt2x00dev, RT3090) || 4331 rt2800_bbp_write(rt2x00dev, 81, 0x33);
4102 rt2x00_rt(rt2x00dev, RT3390) ||
4103 rt2x00_rt(rt2x00dev, RT3572) ||
4104 rt2x00_rt(rt2x00dev, RT5390) ||
4105 rt2x00_rt(rt2x00dev, RT5392)) {
4106 rt2800_bbp_write(rt2x00dev, 79, 0x13);
4107 rt2800_bbp_write(rt2x00dev, 80, 0x05);
4108 rt2800_bbp_write(rt2x00dev, 81, 0x33);
4109 } else if (rt2800_is_305x_soc(rt2x00dev)) {
4110 rt2800_bbp_write(rt2x00dev, 78, 0x0e);
4111 rt2800_bbp_write(rt2x00dev, 80, 0x08);
4112 } else if (rt2x00_rt(rt2x00dev, RT3290)) {
4113 rt2800_bbp_write(rt2x00dev, 74, 0x0b);
4114 rt2800_bbp_write(rt2x00dev, 79, 0x18);
4115 rt2800_bbp_write(rt2x00dev, 80, 0x09);
4116 rt2800_bbp_write(rt2x00dev, 81, 0x33);
4117 } else if (rt2x00_rt(rt2x00dev, RT3352)) {
4118 rt2800_bbp_write(rt2x00dev, 78, 0x0e);
4119 rt2800_bbp_write(rt2x00dev, 80, 0x08);
4120 rt2800_bbp_write(rt2x00dev, 81, 0x37);
4121 } else {
4122 rt2800_bbp_write(rt2x00dev, 81, 0x37);
4123 }
4124 4332
4125 rt2800_bbp_write(rt2x00dev, 82, 0x62); 4333 rt2800_bbp_write(rt2x00dev, 82, 0x62);
4126 if (rt2x00_rt(rt2x00dev, RT3290) ||
4127 rt2x00_rt(rt2x00dev, RT5390) ||
4128 rt2x00_rt(rt2x00dev, RT5392))
4129 rt2800_bbp_write(rt2x00dev, 83, 0x7a);
4130 else
4131 rt2800_bbp_write(rt2x00dev, 83, 0x6a);
4132 4334
4133 if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860D)) 4335 rt2800_bbp_write(rt2x00dev, 83, 0x7a);
4134 rt2800_bbp_write(rt2x00dev, 84, 0x19);
4135 else if (rt2x00_rt(rt2x00dev, RT3290) ||
4136 rt2x00_rt(rt2x00dev, RT5390) ||
4137 rt2x00_rt(rt2x00dev, RT5392))
4138 rt2800_bbp_write(rt2x00dev, 84, 0x9a);
4139 else
4140 rt2800_bbp_write(rt2x00dev, 84, 0x99);
4141 4336
4142 if (rt2x00_rt(rt2x00dev, RT3290) || 4337 rt2800_bbp_write(rt2x00dev, 84, 0x9a);
4143 rt2x00_rt(rt2x00dev, RT3352) ||
4144 rt2x00_rt(rt2x00dev, RT5390) ||
4145 rt2x00_rt(rt2x00dev, RT5392))
4146 rt2800_bbp_write(rt2x00dev, 86, 0x38);
4147 else
4148 rt2800_bbp_write(rt2x00dev, 86, 0x00);
4149 4338
4150 if (rt2x00_rt(rt2x00dev, RT3352) || 4339 rt2800_bbp_write(rt2x00dev, 86, 0x38);
4151 rt2x00_rt(rt2x00dev, RT5392)) 4340
4341 if (rt2x00_rt(rt2x00dev, RT5392))
4152 rt2800_bbp_write(rt2x00dev, 88, 0x90); 4342 rt2800_bbp_write(rt2x00dev, 88, 0x90);
4153 4343
4154 rt2800_bbp_write(rt2x00dev, 91, 0x04); 4344 rt2800_bbp_write(rt2x00dev, 91, 0x04);
4155 4345
4156 if (rt2x00_rt(rt2x00dev, RT3290) || 4346 rt2800_bbp_write(rt2x00dev, 92, 0x02);
4157 rt2x00_rt(rt2x00dev, RT3352) ||
4158 rt2x00_rt(rt2x00dev, RT5390) ||
4159 rt2x00_rt(rt2x00dev, RT5392))
4160 rt2800_bbp_write(rt2x00dev, 92, 0x02);
4161 else
4162 rt2800_bbp_write(rt2x00dev, 92, 0x00);
4163 4347
4164 if (rt2x00_rt(rt2x00dev, RT5392)) { 4348 if (rt2x00_rt(rt2x00dev, RT5392)) {
4165 rt2800_bbp_write(rt2x00dev, 95, 0x9a); 4349 rt2800_bbp_write(rt2x00dev, 95, 0x9a);
4166 rt2800_bbp_write(rt2x00dev, 98, 0x12); 4350 rt2800_bbp_write(rt2x00dev, 98, 0x12);
4167 } 4351 }
4168 4352
4169 if (rt2x00_rt_rev_gte(rt2x00dev, RT3070, REV_RT3070F) || 4353 rt2800_bbp_write(rt2x00dev, 103, 0xc0);
4170 rt2x00_rt_rev_gte(rt2x00dev, RT3071, REV_RT3071E) ||
4171 rt2x00_rt_rev_gte(rt2x00dev, RT3090, REV_RT3090E) ||
4172 rt2x00_rt_rev_gte(rt2x00dev, RT3390, REV_RT3390E) ||
4173 rt2x00_rt(rt2x00dev, RT3290) ||
4174 rt2x00_rt(rt2x00dev, RT3352) ||
4175 rt2x00_rt(rt2x00dev, RT3572) ||
4176 rt2x00_rt(rt2x00dev, RT5390) ||
4177 rt2x00_rt(rt2x00dev, RT5392) ||
4178 rt2800_is_305x_soc(rt2x00dev))
4179 rt2800_bbp_write(rt2x00dev, 103, 0xc0);
4180 else
4181 rt2800_bbp_write(rt2x00dev, 103, 0x00);
4182 4354
4183 if (rt2x00_rt(rt2x00dev, RT3290) || 4355 rt2800_bbp_write(rt2x00dev, 104, 0x92);
4184 rt2x00_rt(rt2x00dev, RT3352) ||
4185 rt2x00_rt(rt2x00dev, RT5390) ||
4186 rt2x00_rt(rt2x00dev, RT5392))
4187 rt2800_bbp_write(rt2x00dev, 104, 0x92);
4188 4356
4189 if (rt2800_is_305x_soc(rt2x00dev)) 4357 rt2800_bbp_write(rt2x00dev, 105, 0x3c);
4190 rt2800_bbp_write(rt2x00dev, 105, 0x01);
4191 else if (rt2x00_rt(rt2x00dev, RT3290))
4192 rt2800_bbp_write(rt2x00dev, 105, 0x1c);
4193 else if (rt2x00_rt(rt2x00dev, RT3352))
4194 rt2800_bbp_write(rt2x00dev, 105, 0x34);
4195 else if (rt2x00_rt(rt2x00dev, RT5390) ||
4196 rt2x00_rt(rt2x00dev, RT5392))
4197 rt2800_bbp_write(rt2x00dev, 105, 0x3c);
4198 else
4199 rt2800_bbp_write(rt2x00dev, 105, 0x05);
4200 4358
4201 if (rt2x00_rt(rt2x00dev, RT3290) || 4359 if (rt2x00_rt(rt2x00dev, RT5390))
4202 rt2x00_rt(rt2x00dev, RT5390))
4203 rt2800_bbp_write(rt2x00dev, 106, 0x03); 4360 rt2800_bbp_write(rt2x00dev, 106, 0x03);
4204 else if (rt2x00_rt(rt2x00dev, RT3352))
4205 rt2800_bbp_write(rt2x00dev, 106, 0x05);
4206 else if (rt2x00_rt(rt2x00dev, RT5392)) 4361 else if (rt2x00_rt(rt2x00dev, RT5392))
4207 rt2800_bbp_write(rt2x00dev, 106, 0x12); 4362 rt2800_bbp_write(rt2x00dev, 106, 0x12);
4208 else 4363 else
4209 rt2800_bbp_write(rt2x00dev, 106, 0x35); 4364 WARN_ON(1);
4210
4211 if (rt2x00_rt(rt2x00dev, RT3352))
4212 rt2800_bbp_write(rt2x00dev, 120, 0x50);
4213 4365
4214 if (rt2x00_rt(rt2x00dev, RT3290) || 4366 rt2800_bbp_write(rt2x00dev, 128, 0x12);
4215 rt2x00_rt(rt2x00dev, RT5390) ||
4216 rt2x00_rt(rt2x00dev, RT5392))
4217 rt2800_bbp_write(rt2x00dev, 128, 0x12);
4218 4367
4219 if (rt2x00_rt(rt2x00dev, RT5392)) { 4368 if (rt2x00_rt(rt2x00dev, RT5392)) {
4220 rt2800_bbp_write(rt2x00dev, 134, 0xd0); 4369 rt2800_bbp_write(rt2x00dev, 134, 0xd0);
4221 rt2800_bbp_write(rt2x00dev, 135, 0xf6); 4370 rt2800_bbp_write(rt2x00dev, 135, 0xf6);
4222 } 4371 }
4223 4372
4224 if (rt2x00_rt(rt2x00dev, RT3352)) 4373 rt2800_disable_unused_dac_adc(rt2x00dev);
4225 rt2800_bbp_write(rt2x00dev, 137, 0x0f);
4226 4374
4227 if (rt2x00_rt(rt2x00dev, RT3071) || 4375 rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
4228 rt2x00_rt(rt2x00dev, RT3090) || 4376 div_mode = rt2x00_get_field16(eeprom,
4229 rt2x00_rt(rt2x00dev, RT3390) || 4377 EEPROM_NIC_CONF1_ANT_DIVERSITY);
4230 rt2x00_rt(rt2x00dev, RT3572) || 4378 ant = (div_mode == 3) ? 1 : 0;
4231 rt2x00_rt(rt2x00dev, RT5390) ||
4232 rt2x00_rt(rt2x00dev, RT5392)) {
4233 rt2800_bbp_read(rt2x00dev, 138, &value);
4234 4379
4235 rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom); 4380 /* check if this is a Bluetooth combo card */
4236 if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_TXPATH) == 1) 4381 if (test_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags)) {
4237 value |= 0x20; 4382 u32 reg;
4238 if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH) == 1)
4239 value &= ~0x02;
4240 4383
4241 rt2800_bbp_write(rt2x00dev, 138, value); 4384 rt2800_register_read(rt2x00dev, GPIO_CTRL, &reg);
4385 rt2x00_set_field32(&reg, GPIO_CTRL_DIR3, 0);
4386 rt2x00_set_field32(&reg, GPIO_CTRL_DIR6, 0);
4387 rt2x00_set_field32(&reg, GPIO_CTRL_VAL3, 0);
4388 rt2x00_set_field32(&reg, GPIO_CTRL_VAL6, 0);
4389 if (ant == 0)
4390 rt2x00_set_field32(&reg, GPIO_CTRL_VAL3, 1);
4391 else if (ant == 1)
4392 rt2x00_set_field32(&reg, GPIO_CTRL_VAL6, 1);
4393 rt2800_register_write(rt2x00dev, GPIO_CTRL, reg);
4242 } 4394 }
4243 4395
4244 if (rt2x00_rt(rt2x00dev, RT3290)) { 4396 /* This chip has hardware antenna diversity*/
4245 rt2800_bbp_write(rt2x00dev, 67, 0x24); 4397 if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390R)) {
4246 rt2800_bbp_write(rt2x00dev, 143, 0x04); 4398 rt2800_bbp_write(rt2x00dev, 150, 0); /* Disable Antenna Software OFDM */
4247 rt2800_bbp_write(rt2x00dev, 142, 0x99); 4399 rt2800_bbp_write(rt2x00dev, 151, 0); /* Disable Antenna Software CCK */
4248 rt2800_bbp_write(rt2x00dev, 150, 0x30); 4400 rt2800_bbp_write(rt2x00dev, 154, 0); /* Clear previously selected antenna */
4249 rt2800_bbp_write(rt2x00dev, 151, 0x2e);
4250 rt2800_bbp_write(rt2x00dev, 152, 0x20);
4251 rt2800_bbp_write(rt2x00dev, 153, 0x34);
4252 rt2800_bbp_write(rt2x00dev, 154, 0x40);
4253 rt2800_bbp_write(rt2x00dev, 155, 0x3b);
4254 rt2800_bbp_write(rt2x00dev, 253, 0x04);
4255
4256 rt2800_bbp_read(rt2x00dev, 47, &value);
4257 rt2x00_set_field8(&value, BBP47_TSSI_ADC6, 1);
4258 rt2800_bbp_write(rt2x00dev, 47, value);
4259
4260 /* Use 5-bit ADC for Acquisition and 8-bit ADC for data */
4261 rt2800_bbp_read(rt2x00dev, 3, &value);
4262 rt2x00_set_field8(&value, BBP3_ADC_MODE_SWITCH, 1);
4263 rt2x00_set_field8(&value, BBP3_ADC_INIT_MODE, 1);
4264 rt2800_bbp_write(rt2x00dev, 3, value);
4265 } 4401 }
4266 4402
4267 if (rt2x00_rt(rt2x00dev, RT3352)) { 4403 rt2800_bbp_read(rt2x00dev, 152, &value);
4268 rt2800_bbp_write(rt2x00dev, 163, 0xbd); 4404 if (ant == 0)
4269 /* Set ITxBF timeout to 0x9c40=1000msec */ 4405 rt2x00_set_field8(&value, BBP152_RX_DEFAULT_ANT, 1);
4270 rt2800_bbp_write(rt2x00dev, 179, 0x02); 4406 else
4271 rt2800_bbp_write(rt2x00dev, 180, 0x00); 4407 rt2x00_set_field8(&value, BBP152_RX_DEFAULT_ANT, 0);
4272 rt2800_bbp_write(rt2x00dev, 182, 0x40); 4408 rt2800_bbp_write(rt2x00dev, 152, value);
4273 rt2800_bbp_write(rt2x00dev, 180, 0x01); 4409
4274 rt2800_bbp_write(rt2x00dev, 182, 0x9c); 4410 rt2800_init_freq_calibration(rt2x00dev);
4275 rt2800_bbp_write(rt2x00dev, 179, 0x00); 4411}
4276 /* Reprogram the inband interface to put right values in RXWI */ 4412
4277 rt2800_bbp_write(rt2x00dev, 142, 0x04); 4413static void rt2800_init_bbp_5592(struct rt2x00_dev *rt2x00dev)
4278 rt2800_bbp_write(rt2x00dev, 143, 0x3b); 4414{
4279 rt2800_bbp_write(rt2x00dev, 142, 0x06); 4415 int ant, div_mode;
4280 rt2800_bbp_write(rt2x00dev, 143, 0xa0); 4416 u16 eeprom;
4281 rt2800_bbp_write(rt2x00dev, 142, 0x07); 4417 u8 value;
4282 rt2800_bbp_write(rt2x00dev, 143, 0xa1); 4418
4283 rt2800_bbp_write(rt2x00dev, 142, 0x08); 4419 rt2800_init_bbp_early(rt2x00dev);
4284 rt2800_bbp_write(rt2x00dev, 143, 0xa2); 4420
4285 4421 rt2800_bbp_read(rt2x00dev, 105, &value);
4286 rt2800_bbp_write(rt2x00dev, 148, 0xc8); 4422 rt2x00_set_field8(&value, BBP105_MLD,
4423 rt2x00dev->default_ant.rx_chain_num == 2);
4424 rt2800_bbp_write(rt2x00dev, 105, value);
4425
4426 rt2800_bbp4_mac_if_ctrl(rt2x00dev);
4427
4428 rt2800_bbp_write(rt2x00dev, 20, 0x06);
4429 rt2800_bbp_write(rt2x00dev, 31, 0x08);
4430 rt2800_bbp_write(rt2x00dev, 65, 0x2C);
4431 rt2800_bbp_write(rt2x00dev, 68, 0xDD);
4432 rt2800_bbp_write(rt2x00dev, 69, 0x1A);
4433 rt2800_bbp_write(rt2x00dev, 70, 0x05);
4434 rt2800_bbp_write(rt2x00dev, 73, 0x13);
4435 rt2800_bbp_write(rt2x00dev, 74, 0x0F);
4436 rt2800_bbp_write(rt2x00dev, 75, 0x4F);
4437 rt2800_bbp_write(rt2x00dev, 76, 0x28);
4438 rt2800_bbp_write(rt2x00dev, 77, 0x59);
4439 rt2800_bbp_write(rt2x00dev, 84, 0x9A);
4440 rt2800_bbp_write(rt2x00dev, 86, 0x38);
4441 rt2800_bbp_write(rt2x00dev, 88, 0x90);
4442 rt2800_bbp_write(rt2x00dev, 91, 0x04);
4443 rt2800_bbp_write(rt2x00dev, 92, 0x02);
4444 rt2800_bbp_write(rt2x00dev, 95, 0x9a);
4445 rt2800_bbp_write(rt2x00dev, 98, 0x12);
4446 rt2800_bbp_write(rt2x00dev, 103, 0xC0);
4447 rt2800_bbp_write(rt2x00dev, 104, 0x92);
4448 /* FIXME BBP105 owerwrite */
4449 rt2800_bbp_write(rt2x00dev, 105, 0x3C);
4450 rt2800_bbp_write(rt2x00dev, 106, 0x35);
4451 rt2800_bbp_write(rt2x00dev, 128, 0x12);
4452 rt2800_bbp_write(rt2x00dev, 134, 0xD0);
4453 rt2800_bbp_write(rt2x00dev, 135, 0xF6);
4454 rt2800_bbp_write(rt2x00dev, 137, 0x0F);
4455
4456 /* Initialize GLRT (Generalized Likehood Radio Test) */
4457 rt2800_init_bbp_5592_glrt(rt2x00dev);
4458
4459 rt2800_bbp4_mac_if_ctrl(rt2x00dev);
4460
4461 rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
4462 div_mode = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_ANT_DIVERSITY);
4463 ant = (div_mode == 3) ? 1 : 0;
4464 rt2800_bbp_read(rt2x00dev, 152, &value);
4465 if (ant == 0) {
4466 /* Main antenna */
4467 rt2x00_set_field8(&value, BBP152_RX_DEFAULT_ANT, 1);
4468 } else {
4469 /* Auxiliary antenna */
4470 rt2x00_set_field8(&value, BBP152_RX_DEFAULT_ANT, 0);
4287 } 4471 }
4472 rt2800_bbp_write(rt2x00dev, 152, value);
4288 4473
4289 if (rt2x00_rt(rt2x00dev, RT5390) || 4474 if (rt2x00_rt_rev_gte(rt2x00dev, RT5592, REV_RT5592C)) {
4290 rt2x00_rt(rt2x00dev, RT5392)) { 4475 rt2800_bbp_read(rt2x00dev, 254, &value);
4291 int ant, div_mode; 4476 rt2x00_set_field8(&value, BBP254_BIT7, 1);
4477 rt2800_bbp_write(rt2x00dev, 254, value);
4478 }
4292 4479
4293 rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom); 4480 rt2800_init_freq_calibration(rt2x00dev);
4294 div_mode = rt2x00_get_field16(eeprom,
4295 EEPROM_NIC_CONF1_ANT_DIVERSITY);
4296 ant = (div_mode == 3) ? 1 : 0;
4297 4481
4298 /* check if this is a Bluetooth combo card */ 4482 rt2800_bbp_write(rt2x00dev, 84, 0x19);
4299 if (test_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags)) { 4483 if (rt2x00_rt_rev_gte(rt2x00dev, RT5592, REV_RT5592C))
4300 u32 reg; 4484 rt2800_bbp_write(rt2x00dev, 103, 0xc0);
4301 4485}
4302 rt2800_register_read(rt2x00dev, GPIO_CTRL, &reg);
4303 rt2x00_set_field32(&reg, GPIO_CTRL_DIR3, 0);
4304 rt2x00_set_field32(&reg, GPIO_CTRL_DIR6, 0);
4305 rt2x00_set_field32(&reg, GPIO_CTRL_VAL3, 0);
4306 rt2x00_set_field32(&reg, GPIO_CTRL_VAL6, 0);
4307 if (ant == 0)
4308 rt2x00_set_field32(&reg, GPIO_CTRL_VAL3, 1);
4309 else if (ant == 1)
4310 rt2x00_set_field32(&reg, GPIO_CTRL_VAL6, 1);
4311 rt2800_register_write(rt2x00dev, GPIO_CTRL, reg);
4312 }
4313 4486
4314 /* This chip has hardware antenna diversity*/ 4487static void rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
4315 if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390R)) { 4488{
4316 rt2800_bbp_write(rt2x00dev, 150, 0); /* Disable Antenna Software OFDM */ 4489 unsigned int i;
4317 rt2800_bbp_write(rt2x00dev, 151, 0); /* Disable Antenna Software CCK */ 4490 u16 eeprom;
4318 rt2800_bbp_write(rt2x00dev, 154, 0); /* Clear previously selected antenna */ 4491 u8 reg_id;
4319 } 4492 u8 value;
4320 4493
4321 rt2800_bbp_read(rt2x00dev, 152, &value); 4494 if (rt2800_is_305x_soc(rt2x00dev))
4322 if (ant == 0) 4495 rt2800_init_bbp_305x_soc(rt2x00dev);
4323 rt2x00_set_field8(&value, BBP152_RX_DEFAULT_ANT, 1);
4324 else
4325 rt2x00_set_field8(&value, BBP152_RX_DEFAULT_ANT, 0);
4326 rt2800_bbp_write(rt2x00dev, 152, value);
4327 4496
4328 rt2800_init_freq_calibration(rt2x00dev); 4497 switch (rt2x00dev->chip.rt) {
4498 case RT2860:
4499 case RT2872:
4500 case RT2883:
4501 rt2800_init_bbp_28xx(rt2x00dev);
4502 break;
4503 case RT3070:
4504 case RT3071:
4505 case RT3090:
4506 rt2800_init_bbp_30xx(rt2x00dev);
4507 break;
4508 case RT3290:
4509 rt2800_init_bbp_3290(rt2x00dev);
4510 break;
4511 case RT3352:
4512 rt2800_init_bbp_3352(rt2x00dev);
4513 break;
4514 case RT3390:
4515 rt2800_init_bbp_3390(rt2x00dev);
4516 break;
4517 case RT3572:
4518 rt2800_init_bbp_3572(rt2x00dev);
4519 break;
4520 case RT5390:
4521 case RT5392:
4522 rt2800_init_bbp_53xx(rt2x00dev);
4523 break;
4524 case RT5592:
4525 rt2800_init_bbp_5592(rt2x00dev);
4526 return;
4329 } 4527 }
4330 4528
4331 for (i = 0; i < EEPROM_BBP_SIZE; i++) { 4529 for (i = 0; i < EEPROM_BBP_SIZE; i++) {
@@ -4337,8 +4535,6 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
4337 rt2800_bbp_write(rt2x00dev, reg_id, value); 4535 rt2800_bbp_write(rt2x00dev, reg_id, value);
4338 } 4536 }
4339 } 4537 }
4340
4341 return 0;
4342} 4538}
4343 4539
4344static void rt2800_led_open_drain_enable(struct rt2x00_dev *rt2x00dev) 4540static void rt2800_led_open_drain_enable(struct rt2x00_dev *rt2x00dev)
@@ -5189,9 +5385,11 @@ int rt2800_enable_radio(struct rt2x00_dev *rt2x00dev)
5189 } 5385 }
5190 msleep(1); 5386 msleep(1);
5191 5387
5192 if (unlikely(rt2800_init_bbp(rt2x00dev))) 5388 if (unlikely(rt2800_wait_bbp_rf_ready(rt2x00dev) ||
5389 rt2800_wait_bbp_ready(rt2x00dev)))
5193 return -EIO; 5390 return -EIO;
5194 5391
5392 rt2800_init_bbp(rt2x00dev);
5195 rt2800_init_rfcsr(rt2x00dev); 5393 rt2800_init_rfcsr(rt2x00dev);
5196 5394
5197 if (rt2x00_is_usb(rt2x00dev) && 5395 if (rt2x00_is_usb(rt2x00dev) &&
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index 6f4a861af336..330f1d25726d 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -1014,7 +1014,7 @@ static void rt2800pci_txstatus_interrupt(struct rt2x00_dev *rt2x00dev)
1014 * Since we have only one producer and one consumer we don't 1014 * Since we have only one producer and one consumer we don't
1015 * need to lock the kfifo. 1015 * need to lock the kfifo.
1016 */ 1016 */
1017 for (i = 0; i < rt2x00dev->ops->tx->entry_num; i++) { 1017 for (i = 0; i < rt2x00dev->tx->limit; i++) {
1018 rt2x00mmio_register_read(rt2x00dev, TX_STA_FIFO, &status); 1018 rt2x00mmio_register_read(rt2x00dev, TX_STA_FIFO, &status);
1019 1019
1020 if (!rt2x00_get_field32(status, TX_STA_FIFO_VALID)) 1020 if (!rt2x00_get_field32(status, TX_STA_FIFO_VALID))
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index ac854d75bd6c..c71a48da9a31 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -327,7 +327,7 @@ static int rt2800usb_enable_radio(struct rt2x00_dev *rt2x00dev)
327 * this limit so reduce the number to prevent errors. 327 * this limit so reduce the number to prevent errors.
328 */ 328 */
329 rt2x00_set_field32(&reg, USB_DMA_CFG_RX_BULK_AGG_LIMIT, 329 rt2x00_set_field32(&reg, USB_DMA_CFG_RX_BULK_AGG_LIMIT,
330 ((rt2x00dev->ops->rx->entry_num * DATA_FRAME_SIZE) 330 ((rt2x00dev->rx->limit * DATA_FRAME_SIZE)
331 / 1024) - 3); 331 / 1024) - 3);
332 rt2x00_set_field32(&reg, USB_DMA_CFG_RX_BULK_EN, 1); 332 rt2x00_set_field32(&reg, USB_DMA_CFG_RX_BULK_EN, 1);
333 rt2x00_set_field32(&reg, USB_DMA_CFG_TX_BULK_EN, 1); 333 rt2x00_set_field32(&reg, USB_DMA_CFG_TX_BULK_EN, 1);
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 90dc14336980..6a201725bc50 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -1077,7 +1077,7 @@ static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev)
1077 */ 1077 */
1078 int kfifo_size = 1078 int kfifo_size =
1079 roundup_pow_of_two(rt2x00dev->ops->tx_queues * 1079 roundup_pow_of_two(rt2x00dev->ops->tx_queues *
1080 rt2x00dev->ops->tx->entry_num * 1080 rt2x00dev->tx->limit *
1081 sizeof(u32)); 1081 sizeof(u32));
1082 1082
1083 status = kfifo_alloc(&rt2x00dev->txstatus_fifo, kfifo_size, 1083 status = kfifo_alloc(&rt2x00dev->txstatus_fifo, kfifo_size,
@@ -1301,23 +1301,6 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
1301 (rt2x00dev->ops->max_ap_intf - 1); 1301 (rt2x00dev->ops->max_ap_intf - 1);
1302 1302
1303 /* 1303 /*
1304 * Determine which operating modes are supported, all modes
1305 * which require beaconing, depend on the availability of
1306 * beacon entries.
1307 */
1308 rt2x00dev->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
1309 if (rt2x00dev->ops->bcn->entry_num > 0)
1310 rt2x00dev->hw->wiphy->interface_modes |=
1311 BIT(NL80211_IFTYPE_ADHOC) |
1312 BIT(NL80211_IFTYPE_AP) |
1313#ifdef CONFIG_MAC80211_MESH
1314 BIT(NL80211_IFTYPE_MESH_POINT) |
1315#endif
1316 BIT(NL80211_IFTYPE_WDS);
1317
1318 rt2x00dev->hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
1319
1320 /*
1321 * Initialize work. 1304 * Initialize work.
1322 */ 1305 */
1323 rt2x00dev->workqueue = 1306 rt2x00dev->workqueue =
@@ -1348,6 +1331,23 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
1348 goto exit; 1331 goto exit;
1349 1332
1350 /* 1333 /*
1334 * Determine which operating modes are supported, all modes
1335 * which require beaconing, depend on the availability of
1336 * beacon entries.
1337 */
1338 rt2x00dev->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
1339 if (rt2x00dev->ops->bcn->entry_num > 0)
1340 rt2x00dev->hw->wiphy->interface_modes |=
1341 BIT(NL80211_IFTYPE_ADHOC) |
1342 BIT(NL80211_IFTYPE_AP) |
1343#ifdef CONFIG_MAC80211_MESH
1344 BIT(NL80211_IFTYPE_MESH_POINT) |
1345#endif
1346 BIT(NL80211_IFTYPE_WDS);
1347
1348 rt2x00dev->hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
1349
1350 /*
1351 * Initialize ieee80211 structure. 1351 * Initialize ieee80211 structure.
1352 */ 1352 */
1353 retval = rt2x00lib_probe_hw(rt2x00dev); 1353 retval = rt2x00lib_probe_hw(rt2x00dev);
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c
index dc49e525ae5e..76d95deb274b 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.c
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
@@ -105,11 +105,13 @@ int rt2x00pci_probe(struct pci_dev *pci_dev, const struct rt2x00_ops *ops)
105 goto exit_release_regions; 105 goto exit_release_regions;
106 } 106 }
107 107
108 pci_enable_msi(pci_dev);
109
108 hw = ieee80211_alloc_hw(sizeof(struct rt2x00_dev), ops->hw); 110 hw = ieee80211_alloc_hw(sizeof(struct rt2x00_dev), ops->hw);
109 if (!hw) { 111 if (!hw) {
110 rt2x00_probe_err("Failed to allocate hardware\n"); 112 rt2x00_probe_err("Failed to allocate hardware\n");
111 retval = -ENOMEM; 113 retval = -ENOMEM;
112 goto exit_release_regions; 114 goto exit_disable_msi;
113 } 115 }
114 116
115 pci_set_drvdata(pci_dev, hw); 117 pci_set_drvdata(pci_dev, hw);
@@ -150,6 +152,9 @@ exit_free_reg:
150exit_free_device: 152exit_free_device:
151 ieee80211_free_hw(hw); 153 ieee80211_free_hw(hw);
152 154
155exit_disable_msi:
156 pci_disable_msi(pci_dev);
157
153exit_release_regions: 158exit_release_regions:
154 pci_release_regions(pci_dev); 159 pci_release_regions(pci_dev);
155 160
@@ -174,6 +179,8 @@ void rt2x00pci_remove(struct pci_dev *pci_dev)
174 rt2x00pci_free_reg(rt2x00dev); 179 rt2x00pci_free_reg(rt2x00dev);
175 ieee80211_free_hw(hw); 180 ieee80211_free_hw(hw);
176 181
182 pci_disable_msi(pci_dev);
183
177 /* 184 /*
178 * Free the PCI device data. 185 * Free the PCI device data.
179 */ 186 */
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index 2c12311467a9..5efbbbdca701 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -1170,12 +1170,6 @@ static int rt2x00queue_alloc_entries(struct data_queue *queue,
1170 1170
1171 rt2x00queue_reset(queue); 1171 rt2x00queue_reset(queue);
1172 1172
1173 queue->limit = qdesc->entry_num;
1174 queue->threshold = DIV_ROUND_UP(qdesc->entry_num, 10);
1175 queue->data_size = qdesc->data_size;
1176 queue->desc_size = qdesc->desc_size;
1177 queue->winfo_size = qdesc->winfo_size;
1178
1179 /* 1173 /*
1180 * Allocate all queue entries. 1174 * Allocate all queue entries.
1181 */ 1175 */
@@ -1284,9 +1278,38 @@ void rt2x00queue_uninitialize(struct rt2x00_dev *rt2x00dev)
1284 } 1278 }
1285} 1279}
1286 1280
1281static const struct data_queue_desc *
1282rt2x00queue_get_qdesc_by_qid(struct rt2x00_dev *rt2x00dev,
1283 enum data_queue_qid qid)
1284{
1285 switch (qid) {
1286 case QID_RX:
1287 return rt2x00dev->ops->rx;
1288
1289 case QID_AC_BE:
1290 case QID_AC_BK:
1291 case QID_AC_VO:
1292 case QID_AC_VI:
1293 return rt2x00dev->ops->tx;
1294
1295 case QID_BEACON:
1296 return rt2x00dev->ops->bcn;
1297
1298 case QID_ATIM:
1299 return rt2x00dev->ops->atim;
1300
1301 default:
1302 break;
1303 }
1304
1305 return NULL;
1306}
1307
1287static void rt2x00queue_init(struct rt2x00_dev *rt2x00dev, 1308static void rt2x00queue_init(struct rt2x00_dev *rt2x00dev,
1288 struct data_queue *queue, enum data_queue_qid qid) 1309 struct data_queue *queue, enum data_queue_qid qid)
1289{ 1310{
1311 const struct data_queue_desc *qdesc;
1312
1290 mutex_init(&queue->status_lock); 1313 mutex_init(&queue->status_lock);
1291 spin_lock_init(&queue->tx_lock); 1314 spin_lock_init(&queue->tx_lock);
1292 spin_lock_init(&queue->index_lock); 1315 spin_lock_init(&queue->index_lock);
@@ -1297,6 +1320,15 @@ static void rt2x00queue_init(struct rt2x00_dev *rt2x00dev,
1297 queue->aifs = 2; 1320 queue->aifs = 2;
1298 queue->cw_min = 5; 1321 queue->cw_min = 5;
1299 queue->cw_max = 10; 1322 queue->cw_max = 10;
1323
1324 qdesc = rt2x00queue_get_qdesc_by_qid(rt2x00dev, qid);
1325 BUG_ON(!qdesc);
1326
1327 queue->limit = qdesc->entry_num;
1328 queue->threshold = DIV_ROUND_UP(qdesc->entry_num, 10);
1329 queue->data_size = qdesc->data_size;
1330 queue->desc_size = qdesc->desc_size;
1331 queue->winfo_size = qdesc->winfo_size;
1300} 1332}
1301 1333
1302int rt2x00queue_allocate(struct rt2x00_dev *rt2x00dev) 1334int rt2x00queue_allocate(struct rt2x00_dev *rt2x00dev)
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index 0dc8180e251b..7e1759b3e49a 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -2175,7 +2175,7 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev)
2175 * that the TX_STA_FIFO stack has a size of 16. We stick to our 2175 * that the TX_STA_FIFO stack has a size of 16. We stick to our
2176 * tx ring size for now. 2176 * tx ring size for now.
2177 */ 2177 */
2178 for (i = 0; i < rt2x00dev->ops->tx->entry_num; i++) { 2178 for (i = 0; i < rt2x00dev->tx->limit; i++) {
2179 rt2x00mmio_register_read(rt2x00dev, STA_CSR4, &reg); 2179 rt2x00mmio_register_read(rt2x00dev, STA_CSR4, &reg);
2180 if (!rt2x00_get_field32(reg, STA_CSR4_VALID)) 2180 if (!rt2x00_get_field32(reg, STA_CSR4_VALID))
2181 break; 2181 break;
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/dm.c b/drivers/net/wireless/rtlwifi/rtl8192de/dm.c
index 19a765532603..47875ba09ff8 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/dm.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/dm.c
@@ -842,7 +842,7 @@ static void rtl92d_dm_txpower_tracking_callback_thermalmeter(
842 long val_y, ele_c = 0; 842 long val_y, ele_c = 0;
843 u8 ofdm_index[2]; 843 u8 ofdm_index[2];
844 s8 cck_index = 0; 844 s8 cck_index = 0;
845 u8 ofdm_index_old[2]; 845 u8 ofdm_index_old[2] = {0, 0};
846 s8 cck_index_old = 0; 846 s8 cck_index_old = 0;
847 u8 index; 847 u8 index;
848 int i; 848 int i;
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 06b0ed0154a4..d826e5a84af0 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -1829,6 +1829,15 @@ enum ieee80211_key_len {
1829 WLAN_KEY_LEN_AES_CMAC = 16, 1829 WLAN_KEY_LEN_AES_CMAC = 16,
1830}; 1830};
1831 1831
1832#define IEEE80211_WEP_IV_LEN 4
1833#define IEEE80211_WEP_ICV_LEN 4
1834#define IEEE80211_CCMP_HDR_LEN 8
1835#define IEEE80211_CCMP_MIC_LEN 8
1836#define IEEE80211_CCMP_PN_LEN 6
1837#define IEEE80211_TKIP_IV_LEN 8
1838#define IEEE80211_TKIP_ICV_LEN 4
1839#define IEEE80211_CMAC_PN_LEN 6
1840
1832/* Public action codes */ 1841/* Public action codes */
1833enum ieee80211_pub_actioncode { 1842enum ieee80211_pub_actioncode {
1834 WLAN_PUB_ACTION_EXT_CHANSW_ANN = 4, 1843 WLAN_PUB_ACTION_EXT_CHANSW_ANN = 4,
diff --git a/include/linux/platform_data/net-cw1200.h b/include/linux/platform_data/net-cw1200.h
new file mode 100644
index 000000000000..c6fbc3ce4ab0
--- /dev/null
+++ b/include/linux/platform_data/net-cw1200.h
@@ -0,0 +1,81 @@
1/*
2 * Copyright (C) ST-Ericsson SA 2011
3 *
4 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@stericsson.com>
5 * License terms: GNU General Public License (GPL) version 2
6 */
7
8#ifndef CW1200_PLAT_H_INCLUDED
9#define CW1200_PLAT_H_INCLUDED
10
11struct cw1200_platform_data_spi {
12 u8 spi_bits_per_word; /* REQUIRED */
13 u16 ref_clk; /* REQUIRED (in KHz) */
14
15 /* All others are optional */
16 bool have_5ghz;
17 int reset; /* GPIO to RSTn signal (0 disables) */
18 int powerup; /* GPIO to POWERUP signal (0 disables) */
19 int (*power_ctrl)(const struct cw1200_platform_data_spi *pdata,
20 bool enable); /* Control 3v3 / 1v8 supply */
21 int (*clk_ctrl)(const struct cw1200_platform_data_spi *pdata,
22 bool enable); /* Control CLK32K */
23 const u8 *macaddr; /* if NULL, use cw1200_mac_template module parameter */
24 const char *sdd_file; /* if NULL, will use default for detected hw type */
25};
26
27struct cw1200_platform_data_sdio {
28 u16 ref_clk; /* REQUIRED (in KHz) */
29
30 /* All others are optional */
31 bool have_5ghz;
32 bool no_nptb; /* SDIO hardware does not support non-power-of-2-blocksizes */
33 int reset; /* GPIO to RSTn signal (0 disables) */
34 int powerup; /* GPIO to POWERUP signal (0 disables) */
35 int irq; /* IRQ line or 0 to use SDIO IRQ */
36 int (*power_ctrl)(const struct cw1200_platform_data_sdio *pdata,
37 bool enable); /* Control 3v3 / 1v8 supply */
38 int (*clk_ctrl)(const struct cw1200_platform_data_sdio *pdata,
39 bool enable); /* Control CLK32K */
40 const u8 *macaddr; /* if NULL, use cw1200_mac_template module parameter */
41 const char *sdd_file; /* if NULL, will use default for detected hw type */
42};
43
44
45/* An example of SPI support in your board setup file:
46
47 static struct cw1200_platform_data_spi cw1200_platform_data = {
48 .ref_clk = 38400,
49 .spi_bits_per_word = 16,
50 .reset = GPIO_RF_RESET,
51 .powerup = GPIO_RF_POWERUP,
52 .macaddr = wifi_mac_addr,
53 .sdd_file = "sdd_sagrad_1091_1098.bin",
54 };
55 static struct spi_board_info myboard_spi_devices[] __initdata = {
56 {
57 .modalias = "cw1200_wlan_spi",
58 .max_speed_hz = 52000000,
59 .bus_num = 0,
60 .irq = WIFI_IRQ,
61 .platform_data = &cw1200_platform_data,
62 .chip_select = 0,
63 },
64 };
65
66 */
67
68/* An example of SDIO support in your board setup file:
69
70 static struct cw1200_platform_data_sdio my_cw1200_platform_data = {
71 .ref_clk = 38400,
72 .have_5ghz = false,
73 .sdd_file = "sdd_myplatform.bin",
74 };
75 cw1200_sdio_set_platform_data(&my_cw1200_platform_data);
76
77 */
78
79void __init cw1200_sdio_set_platform_data(struct cw1200_platform_data_sdio *pdata);
80
81#endif /* CW1200_PLAT_H_INCLUDED */
diff --git a/include/linux/ssb/ssb_regs.h b/include/linux/ssb/ssb_regs.h
index 3a7256955b10..f9f931c89e3e 100644
--- a/include/linux/ssb/ssb_regs.h
+++ b/include/linux/ssb/ssb_regs.h
@@ -172,6 +172,7 @@
172#define SSB_SPROMSIZE_WORDS_R4 220 172#define SSB_SPROMSIZE_WORDS_R4 220
173#define SSB_SPROMSIZE_BYTES_R123 (SSB_SPROMSIZE_WORDS_R123 * sizeof(u16)) 173#define SSB_SPROMSIZE_BYTES_R123 (SSB_SPROMSIZE_WORDS_R123 * sizeof(u16))
174#define SSB_SPROMSIZE_BYTES_R4 (SSB_SPROMSIZE_WORDS_R4 * sizeof(u16)) 174#define SSB_SPROMSIZE_BYTES_R4 (SSB_SPROMSIZE_WORDS_R4 * sizeof(u16))
175#define SSB_SPROMSIZE_WORDS_R10 230
175#define SSB_SPROM_BASE1 0x1000 176#define SSB_SPROM_BASE1 0x1000
176#define SSB_SPROM_BASE31 0x0800 177#define SSB_SPROM_BASE31 0x0800
177#define SSB_SPROM_REVISION 0x007E 178#define SSB_SPROM_REVISION 0x007E
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 26b5b692c22b..6dd19593e333 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -753,6 +753,8 @@ int cfg80211_check_station_change(struct wiphy *wiphy,
753 * @STATION_INFO_LOCAL_PM: @local_pm filled 753 * @STATION_INFO_LOCAL_PM: @local_pm filled
754 * @STATION_INFO_PEER_PM: @peer_pm filled 754 * @STATION_INFO_PEER_PM: @peer_pm filled
755 * @STATION_INFO_NONPEER_PM: @nonpeer_pm filled 755 * @STATION_INFO_NONPEER_PM: @nonpeer_pm filled
756 * @STATION_INFO_CHAIN_SIGNAL: @chain_signal filled
757 * @STATION_INFO_CHAIN_SIGNAL_AVG: @chain_signal_avg filled
756 */ 758 */
757enum station_info_flags { 759enum station_info_flags {
758 STATION_INFO_INACTIVE_TIME = 1<<0, 760 STATION_INFO_INACTIVE_TIME = 1<<0,
@@ -781,6 +783,8 @@ enum station_info_flags {
781 STATION_INFO_NONPEER_PM = 1<<23, 783 STATION_INFO_NONPEER_PM = 1<<23,
782 STATION_INFO_RX_BYTES64 = 1<<24, 784 STATION_INFO_RX_BYTES64 = 1<<24,
783 STATION_INFO_TX_BYTES64 = 1<<25, 785 STATION_INFO_TX_BYTES64 = 1<<25,
786 STATION_INFO_CHAIN_SIGNAL = 1<<26,
787 STATION_INFO_CHAIN_SIGNAL_AVG = 1<<27,
784}; 788};
785 789
786/** 790/**
@@ -857,6 +861,8 @@ struct sta_bss_parameters {
857 u16 beacon_interval; 861 u16 beacon_interval;
858}; 862};
859 863
864#define IEEE80211_MAX_CHAINS 4
865
860/** 866/**
861 * struct station_info - station information 867 * struct station_info - station information
862 * 868 *
@@ -874,6 +880,9 @@ struct sta_bss_parameters {
874 * For CFG80211_SIGNAL_TYPE_MBM, value is expressed in _dBm_. 880 * For CFG80211_SIGNAL_TYPE_MBM, value is expressed in _dBm_.
875 * @signal_avg: Average signal strength, type depends on the wiphy's signal_type. 881 * @signal_avg: Average signal strength, type depends on the wiphy's signal_type.
876 * For CFG80211_SIGNAL_TYPE_MBM, value is expressed in _dBm_. 882 * For CFG80211_SIGNAL_TYPE_MBM, value is expressed in _dBm_.
883 * @chains: bitmask for filled values in @chain_signal, @chain_signal_avg
884 * @chain_signal: per-chain signal strength of last received packet in dBm
885 * @chain_signal_avg: per-chain signal strength average in dBm
877 * @txrate: current unicast bitrate from this station 886 * @txrate: current unicast bitrate from this station
878 * @rxrate: current unicast bitrate to this station 887 * @rxrate: current unicast bitrate to this station
879 * @rx_packets: packets received from this station 888 * @rx_packets: packets received from this station
@@ -909,6 +918,11 @@ struct station_info {
909 u8 plink_state; 918 u8 plink_state;
910 s8 signal; 919 s8 signal;
911 s8 signal_avg; 920 s8 signal_avg;
921
922 u8 chains;
923 s8 chain_signal[IEEE80211_MAX_CHAINS];
924 s8 chain_signal_avg[IEEE80211_MAX_CHAINS];
925
912 struct rate_info txrate; 926 struct rate_info txrate;
913 struct rate_info rxrate; 927 struct rate_info rxrate;
914 u32 rx_packets; 928 u32 rx_packets;
@@ -947,6 +961,7 @@ struct station_info {
947 * @MONITOR_FLAG_CONTROL: pass control frames 961 * @MONITOR_FLAG_CONTROL: pass control frames
948 * @MONITOR_FLAG_OTHER_BSS: disable BSSID filtering 962 * @MONITOR_FLAG_OTHER_BSS: disable BSSID filtering
949 * @MONITOR_FLAG_COOK_FRAMES: report frames after processing 963 * @MONITOR_FLAG_COOK_FRAMES: report frames after processing
964 * @MONITOR_FLAG_ACTIVE: active monitor, ACKs frames on its MAC address
950 */ 965 */
951enum monitor_flags { 966enum monitor_flags {
952 MONITOR_FLAG_FCSFAIL = 1<<NL80211_MNTR_FLAG_FCSFAIL, 967 MONITOR_FLAG_FCSFAIL = 1<<NL80211_MNTR_FLAG_FCSFAIL,
@@ -954,6 +969,7 @@ enum monitor_flags {
954 MONITOR_FLAG_CONTROL = 1<<NL80211_MNTR_FLAG_CONTROL, 969 MONITOR_FLAG_CONTROL = 1<<NL80211_MNTR_FLAG_CONTROL,
955 MONITOR_FLAG_OTHER_BSS = 1<<NL80211_MNTR_FLAG_OTHER_BSS, 970 MONITOR_FLAG_OTHER_BSS = 1<<NL80211_MNTR_FLAG_OTHER_BSS,
956 MONITOR_FLAG_COOK_FRAMES = 1<<NL80211_MNTR_FLAG_COOK_FRAMES, 971 MONITOR_FLAG_COOK_FRAMES = 1<<NL80211_MNTR_FLAG_COOK_FRAMES,
972 MONITOR_FLAG_ACTIVE = 1<<NL80211_MNTR_FLAG_ACTIVE,
957}; 973};
958 974
959/** 975/**
@@ -1147,6 +1163,7 @@ struct mesh_config {
1147 * @sync_method: which synchronization method to use 1163 * @sync_method: which synchronization method to use
1148 * @path_sel_proto: which path selection protocol to use 1164 * @path_sel_proto: which path selection protocol to use
1149 * @path_metric: which metric to use 1165 * @path_metric: which metric to use
1166 * @auth_id: which authentication method this mesh is using
1150 * @ie: vendor information elements (optional) 1167 * @ie: vendor information elements (optional)
1151 * @ie_len: length of vendor information elements 1168 * @ie_len: length of vendor information elements
1152 * @is_authenticated: this mesh requires authentication 1169 * @is_authenticated: this mesh requires authentication
@@ -1165,6 +1182,7 @@ struct mesh_setup {
1165 u8 sync_method; 1182 u8 sync_method;
1166 u8 path_sel_proto; 1183 u8 path_sel_proto;
1167 u8 path_metric; 1184 u8 path_metric;
1185 u8 auth_id;
1168 const u8 *ie; 1186 const u8 *ie;
1169 u8 ie_len; 1187 u8 ie_len;
1170 bool is_authenticated; 1188 bool is_authenticated;
@@ -1241,6 +1259,7 @@ struct cfg80211_ssid {
1241 * @scan_start: time (in jiffies) when the scan started 1259 * @scan_start: time (in jiffies) when the scan started
1242 * @wdev: the wireless device to scan for 1260 * @wdev: the wireless device to scan for
1243 * @aborted: (internal) scan request was notified as aborted 1261 * @aborted: (internal) scan request was notified as aborted
1262 * @notified: (internal) scan request was notified as done or aborted
1244 * @no_cck: used to send probe requests at non CCK rate in 2GHz band 1263 * @no_cck: used to send probe requests at non CCK rate in 2GHz band
1245 */ 1264 */
1246struct cfg80211_scan_request { 1265struct cfg80211_scan_request {
@@ -1258,7 +1277,7 @@ struct cfg80211_scan_request {
1258 /* internal */ 1277 /* internal */
1259 struct wiphy *wiphy; 1278 struct wiphy *wiphy;
1260 unsigned long scan_start; 1279 unsigned long scan_start;
1261 bool aborted; 1280 bool aborted, notified;
1262 bool no_cck; 1281 bool no_cck;
1263 1282
1264 /* keep last */ 1283 /* keep last */
@@ -1850,7 +1869,9 @@ struct cfg80211_update_ft_ies_params {
1850 * @get_mpath: get a mesh path for the given parameters 1869 * @get_mpath: get a mesh path for the given parameters
1851 * @dump_mpath: dump mesh path callback -- resume dump at index @idx 1870 * @dump_mpath: dump mesh path callback -- resume dump at index @idx
1852 * @join_mesh: join the mesh network with the specified parameters 1871 * @join_mesh: join the mesh network with the specified parameters
1872 * (invoked with the wireless_dev mutex held)
1853 * @leave_mesh: leave the current mesh network 1873 * @leave_mesh: leave the current mesh network
1874 * (invoked with the wireless_dev mutex held)
1854 * 1875 *
1855 * @get_mesh_config: Get the current mesh configuration 1876 * @get_mesh_config: Get the current mesh configuration
1856 * 1877 *
@@ -1877,20 +1898,28 @@ struct cfg80211_update_ft_ies_params {
1877 * the scan/scan_done bracket too. 1898 * the scan/scan_done bracket too.
1878 * 1899 *
1879 * @auth: Request to authenticate with the specified peer 1900 * @auth: Request to authenticate with the specified peer
1901 * (invoked with the wireless_dev mutex held)
1880 * @assoc: Request to (re)associate with the specified peer 1902 * @assoc: Request to (re)associate with the specified peer
1903 * (invoked with the wireless_dev mutex held)
1881 * @deauth: Request to deauthenticate from the specified peer 1904 * @deauth: Request to deauthenticate from the specified peer
1905 * (invoked with the wireless_dev mutex held)
1882 * @disassoc: Request to disassociate from the specified peer 1906 * @disassoc: Request to disassociate from the specified peer
1907 * (invoked with the wireless_dev mutex held)
1883 * 1908 *
1884 * @connect: Connect to the ESS with the specified parameters. When connected, 1909 * @connect: Connect to the ESS with the specified parameters. When connected,
1885 * call cfg80211_connect_result() with status code %WLAN_STATUS_SUCCESS. 1910 * call cfg80211_connect_result() with status code %WLAN_STATUS_SUCCESS.
1886 * If the connection fails for some reason, call cfg80211_connect_result() 1911 * If the connection fails for some reason, call cfg80211_connect_result()
1887 * with the status from the AP. 1912 * with the status from the AP.
1913 * (invoked with the wireless_dev mutex held)
1888 * @disconnect: Disconnect from the BSS/ESS. 1914 * @disconnect: Disconnect from the BSS/ESS.
1915 * (invoked with the wireless_dev mutex held)
1889 * 1916 *
1890 * @join_ibss: Join the specified IBSS (or create if necessary). Once done, call 1917 * @join_ibss: Join the specified IBSS (or create if necessary). Once done, call
1891 * cfg80211_ibss_joined(), also call that function when changing BSSID due 1918 * cfg80211_ibss_joined(), also call that function when changing BSSID due
1892 * to a merge. 1919 * to a merge.
1920 * (invoked with the wireless_dev mutex held)
1893 * @leave_ibss: Leave the IBSS. 1921 * @leave_ibss: Leave the IBSS.
1922 * (invoked with the wireless_dev mutex held)
1894 * 1923 *
1895 * @set_mcast_rate: Set the specified multicast rate (only if vif is in ADHOC or 1924 * @set_mcast_rate: Set the specified multicast rate (only if vif is in ADHOC or
1896 * MESH mode) 1925 * MESH mode)
@@ -2556,6 +2585,9 @@ struct wiphy_wowlan_support {
2556 * may request, if implemented. 2585 * may request, if implemented.
2557 * 2586 *
2558 * @wowlan: WoWLAN support information 2587 * @wowlan: WoWLAN support information
2588 * @wowlan_config: current WoWLAN configuration; this should usually not be
2589 * used since access to it is necessarily racy, use the parameter passed
2590 * to the suspend() operation instead.
2559 * 2591 *
2560 * @ap_sme_capa: AP SME capabilities, flags from &enum nl80211_ap_sme_features. 2592 * @ap_sme_capa: AP SME capabilities, flags from &enum nl80211_ap_sme_features.
2561 * @ht_capa_mod_mask: Specify what ht_cap values can be over-ridden. 2593 * @ht_capa_mod_mask: Specify what ht_cap values can be over-ridden.
@@ -2623,6 +2655,7 @@ struct wiphy {
2623 2655
2624#ifdef CONFIG_PM 2656#ifdef CONFIG_PM
2625 struct wiphy_wowlan_support wowlan; 2657 struct wiphy_wowlan_support wowlan;
2658 struct cfg80211_wowlan *wowlan_config;
2626#endif 2659#endif
2627 2660
2628 u16 max_remain_on_channel_duration; 2661 u16 max_remain_on_channel_duration;
@@ -2834,8 +2867,8 @@ struct cfg80211_cached_keys;
2834 * by cfg80211 on change_interface 2867 * by cfg80211 on change_interface
2835 * @mgmt_registrations: list of registrations for management frames 2868 * @mgmt_registrations: list of registrations for management frames
2836 * @mgmt_registrations_lock: lock for the list 2869 * @mgmt_registrations_lock: lock for the list
2837 * @mtx: mutex used to lock data in this struct 2870 * @mtx: mutex used to lock data in this struct, may be used by drivers
2838 * @cleanup_work: work struct used for cleanup that can't be done directly 2871 * and some API functions require it held
2839 * @beacon_interval: beacon interval used on this device for transmitting 2872 * @beacon_interval: beacon interval used on this device for transmitting
2840 * beacons, 0 when not valid 2873 * beacons, 0 when not valid
2841 * @address: The address for this device, valid only if @netdev is %NULL 2874 * @address: The address for this device, valid only if @netdev is %NULL
@@ -2858,8 +2891,6 @@ struct wireless_dev {
2858 2891
2859 struct mutex mtx; 2892 struct mutex mtx;
2860 2893
2861 struct work_struct cleanup_work;
2862
2863 bool use_4addr, p2p_started; 2894 bool use_4addr, p2p_started;
2864 2895
2865 u8 address[ETH_ALEN] __aligned(sizeof(u16)); 2896 u8 address[ETH_ALEN] __aligned(sizeof(u16));
@@ -2989,6 +3020,15 @@ struct ieee80211_rate *
2989ieee80211_get_response_rate(struct ieee80211_supported_band *sband, 3020ieee80211_get_response_rate(struct ieee80211_supported_band *sband,
2990 u32 basic_rates, int bitrate); 3021 u32 basic_rates, int bitrate);
2991 3022
3023/**
3024 * ieee80211_mandatory_rates - get mandatory rates for a given band
3025 * @sband: the band to look for rates in
3026 *
3027 * This function returns a bitmap of the mandatory rates for the given
3028 * band, bits are set according to the rate position in the bitrates array.
3029 */
3030u32 ieee80211_mandatory_rates(struct ieee80211_supported_band *sband);
3031
2992/* 3032/*
2993 * Radiotap parsing functions -- for controlled injection support 3033 * Radiotap parsing functions -- for controlled injection support
2994 * 3034 *
@@ -3400,7 +3440,8 @@ void cfg80211_unlink_bss(struct wiphy *wiphy, struct cfg80211_bss *bss);
3400 * This function is called whenever an authentication has been processed in 3440 * This function is called whenever an authentication has been processed in
3401 * station mode. The driver is required to call either this function or 3441 * station mode. The driver is required to call either this function or
3402 * cfg80211_send_auth_timeout() to indicate the result of cfg80211_ops::auth() 3442 * cfg80211_send_auth_timeout() to indicate the result of cfg80211_ops::auth()
3403 * call. This function may sleep. 3443 * call. This function may sleep. The caller must hold the corresponding wdev's
3444 * mutex.
3404 */ 3445 */
3405void cfg80211_send_rx_auth(struct net_device *dev, const u8 *buf, size_t len); 3446void cfg80211_send_rx_auth(struct net_device *dev, const u8 *buf, size_t len);
3406 3447
@@ -3409,7 +3450,8 @@ void cfg80211_send_rx_auth(struct net_device *dev, const u8 *buf, size_t len);
3409 * @dev: network device 3450 * @dev: network device
3410 * @addr: The MAC address of the device with which the authentication timed out 3451 * @addr: The MAC address of the device with which the authentication timed out
3411 * 3452 *
3412 * This function may sleep. 3453 * This function may sleep. The caller must hold the corresponding wdev's
3454 * mutex.
3413 */ 3455 */
3414void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr); 3456void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr);
3415 3457
@@ -3424,7 +3466,8 @@ void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr);
3424 * This function is called whenever a (re)association response has been 3466 * This function is called whenever a (re)association response has been
3425 * processed in station mode. The driver is required to call either this 3467 * processed in station mode. The driver is required to call either this
3426 * function or cfg80211_send_assoc_timeout() to indicate the result of 3468 * function or cfg80211_send_assoc_timeout() to indicate the result of
3427 * cfg80211_ops::assoc() call. This function may sleep. 3469 * cfg80211_ops::assoc() call. This function may sleep. The caller must hold
3470 * the corresponding wdev's mutex.
3428 */ 3471 */
3429void cfg80211_send_rx_assoc(struct net_device *dev, struct cfg80211_bss *bss, 3472void cfg80211_send_rx_assoc(struct net_device *dev, struct cfg80211_bss *bss,
3430 const u8 *buf, size_t len); 3473 const u8 *buf, size_t len);
@@ -3434,7 +3477,7 @@ void cfg80211_send_rx_assoc(struct net_device *dev, struct cfg80211_bss *bss,
3434 * @dev: network device 3477 * @dev: network device
3435 * @addr: The MAC address of the device with which the association timed out 3478 * @addr: The MAC address of the device with which the association timed out
3436 * 3479 *
3437 * This function may sleep. 3480 * This function may sleep. The caller must hold the corresponding wdev's mutex.
3438 */ 3481 */
3439void cfg80211_send_assoc_timeout(struct net_device *dev, const u8 *addr); 3482void cfg80211_send_assoc_timeout(struct net_device *dev, const u8 *addr);
3440 3483
@@ -3446,21 +3489,12 @@ void cfg80211_send_assoc_timeout(struct net_device *dev, const u8 *addr);
3446 * 3489 *
3447 * This function is called whenever deauthentication has been processed in 3490 * This function is called whenever deauthentication has been processed in
3448 * station mode. This includes both received deauthentication frames and 3491 * station mode. This includes both received deauthentication frames and
3449 * locally generated ones. This function may sleep. 3492 * locally generated ones. This function may sleep. The caller must hold the
3493 * corresponding wdev's mutex.
3450 */ 3494 */
3451void cfg80211_send_deauth(struct net_device *dev, const u8 *buf, size_t len); 3495void cfg80211_send_deauth(struct net_device *dev, const u8 *buf, size_t len);
3452 3496
3453/** 3497/**
3454 * __cfg80211_send_deauth - notification of processed deauthentication
3455 * @dev: network device
3456 * @buf: deauthentication frame (header + body)
3457 * @len: length of the frame data
3458 *
3459 * Like cfg80211_send_deauth(), but doesn't take the wdev lock.
3460 */
3461void __cfg80211_send_deauth(struct net_device *dev, const u8 *buf, size_t len);
3462
3463/**
3464 * cfg80211_send_disassoc - notification of processed disassociation 3498 * cfg80211_send_disassoc - notification of processed disassociation
3465 * @dev: network device 3499 * @dev: network device
3466 * @buf: disassociation response frame (header + body) 3500 * @buf: disassociation response frame (header + body)
@@ -3468,22 +3502,12 @@ void __cfg80211_send_deauth(struct net_device *dev, const u8 *buf, size_t len);
3468 * 3502 *
3469 * This function is called whenever disassociation has been processed in 3503 * This function is called whenever disassociation has been processed in
3470 * station mode. This includes both received disassociation frames and locally 3504 * station mode. This includes both received disassociation frames and locally
3471 * generated ones. This function may sleep. 3505 * generated ones. This function may sleep. The caller must hold the
3506 * corresponding wdev's mutex.
3472 */ 3507 */
3473void cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, size_t len); 3508void cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, size_t len);
3474 3509
3475/** 3510/**
3476 * __cfg80211_send_disassoc - notification of processed disassociation
3477 * @dev: network device
3478 * @buf: disassociation response frame (header + body)
3479 * @len: length of the frame data
3480 *
3481 * Like cfg80211_send_disassoc(), but doesn't take the wdev lock.
3482 */
3483void __cfg80211_send_disassoc(struct net_device *dev, const u8 *buf,
3484 size_t len);
3485
3486/**
3487 * cfg80211_send_unprot_deauth - notification of unprotected deauthentication 3511 * cfg80211_send_unprot_deauth - notification of unprotected deauthentication
3488 * @dev: network device 3512 * @dev: network device
3489 * @buf: deauthentication frame (header + body) 3513 * @buf: deauthentication frame (header + body)
@@ -4153,6 +4177,7 @@ void cfg80211_report_wowlan_wakeup(struct wireless_dev *wdev,
4153 * cfg80211_crit_proto_stopped() - indicate critical protocol stopped by driver. 4177 * cfg80211_crit_proto_stopped() - indicate critical protocol stopped by driver.
4154 * 4178 *
4155 * @wdev: the wireless device for which critical protocol is stopped. 4179 * @wdev: the wireless device for which critical protocol is stopped.
4180 * @gfp: allocation flags
4156 * 4181 *
4157 * This function can be called by the driver to indicate it has reverted 4182 * This function can be called by the driver to indicate it has reverted
4158 * operation back to normal. One reason could be that the duration given 4183 * operation back to normal. One reason could be that the duration given
diff --git a/include/net/ieee80211_radiotap.h b/include/net/ieee80211_radiotap.h
index c3999632e616..c6d07cb074bc 100644
--- a/include/net/ieee80211_radiotap.h
+++ b/include/net/ieee80211_radiotap.h
@@ -269,6 +269,7 @@ enum ieee80211_radiotap_type {
269#define IEEE80211_RADIOTAP_MCS_HAVE_GI 0x04 269#define IEEE80211_RADIOTAP_MCS_HAVE_GI 0x04
270#define IEEE80211_RADIOTAP_MCS_HAVE_FMT 0x08 270#define IEEE80211_RADIOTAP_MCS_HAVE_FMT 0x08
271#define IEEE80211_RADIOTAP_MCS_HAVE_FEC 0x10 271#define IEEE80211_RADIOTAP_MCS_HAVE_FEC 0x10
272#define IEEE80211_RADIOTAP_MCS_HAVE_STBC 0x20
272 273
273#define IEEE80211_RADIOTAP_MCS_BW_MASK 0x03 274#define IEEE80211_RADIOTAP_MCS_BW_MASK 0x03
274#define IEEE80211_RADIOTAP_MCS_BW_20 0 275#define IEEE80211_RADIOTAP_MCS_BW_20 0
@@ -278,6 +279,12 @@ enum ieee80211_radiotap_type {
278#define IEEE80211_RADIOTAP_MCS_SGI 0x04 279#define IEEE80211_RADIOTAP_MCS_SGI 0x04
279#define IEEE80211_RADIOTAP_MCS_FMT_GF 0x08 280#define IEEE80211_RADIOTAP_MCS_FMT_GF 0x08
280#define IEEE80211_RADIOTAP_MCS_FEC_LDPC 0x10 281#define IEEE80211_RADIOTAP_MCS_FEC_LDPC 0x10
282#define IEEE80211_RADIOTAP_MCS_STBC_MASK 0x60
283#define IEEE80211_RADIOTAP_MCS_STBC_1 1
284#define IEEE80211_RADIOTAP_MCS_STBC_2 2
285#define IEEE80211_RADIOTAP_MCS_STBC_3 3
286
287#define IEEE80211_RADIOTAP_MCS_STBC_SHIFT 5
281 288
282/* For IEEE80211_RADIOTAP_AMPDU_STATUS */ 289/* For IEEE80211_RADIOTAP_AMPDU_STATUS */
283#define IEEE80211_RADIOTAP_AMPDU_REPORT_ZEROLEN 0x0001 290#define IEEE80211_RADIOTAP_AMPDU_REPORT_ZEROLEN 0x0001
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 885898a40d13..1f0014bd4d87 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -805,6 +805,7 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info)
805 * on this subframe 805 * on this subframe
806 * @RX_FLAG_AMPDU_DELIM_CRC_KNOWN: The delimiter CRC field is known (the CRC 806 * @RX_FLAG_AMPDU_DELIM_CRC_KNOWN: The delimiter CRC field is known (the CRC
807 * is stored in the @ampdu_delimiter_crc field) 807 * is stored in the @ampdu_delimiter_crc field)
808 * @RX_FLAG_STBC_MASK: STBC 2 bit bitmask. 1 - Nss=1, 2 - Nss=2, 3 - Nss=3
808 */ 809 */
809enum mac80211_rx_flags { 810enum mac80211_rx_flags {
810 RX_FLAG_MMIC_ERROR = BIT(0), 811 RX_FLAG_MMIC_ERROR = BIT(0),
@@ -832,8 +833,11 @@ enum mac80211_rx_flags {
832 RX_FLAG_80MHZ = BIT(23), 833 RX_FLAG_80MHZ = BIT(23),
833 RX_FLAG_80P80MHZ = BIT(24), 834 RX_FLAG_80P80MHZ = BIT(24),
834 RX_FLAG_160MHZ = BIT(25), 835 RX_FLAG_160MHZ = BIT(25),
836 RX_FLAG_STBC_MASK = BIT(26) | BIT(27),
835}; 837};
836 838
839#define RX_FLAG_STBC_SHIFT 26
840
837/** 841/**
838 * struct ieee80211_rx_status - receive status 842 * struct ieee80211_rx_status - receive status
839 * 843 *
@@ -850,6 +854,10 @@ enum mac80211_rx_flags {
850 * @signal: signal strength when receiving this frame, either in dBm, in dB or 854 * @signal: signal strength when receiving this frame, either in dBm, in dB or
851 * unspecified depending on the hardware capabilities flags 855 * unspecified depending on the hardware capabilities flags
852 * @IEEE80211_HW_SIGNAL_* 856 * @IEEE80211_HW_SIGNAL_*
857 * @chains: bitmask of receive chains for which separate signal strength
858 * values were filled.
859 * @chain_signal: per-chain signal strength, in dBm (unlike @signal, doesn't
860 * support dB or unspecified units)
853 * @antenna: antenna used 861 * @antenna: antenna used
854 * @rate_idx: index of data rate into band's supported rates or MCS index if 862 * @rate_idx: index of data rate into band's supported rates or MCS index if
855 * HT or VHT is used (%RX_FLAG_HT/%RX_FLAG_VHT) 863 * HT or VHT is used (%RX_FLAG_HT/%RX_FLAG_VHT)
@@ -881,6 +889,8 @@ struct ieee80211_rx_status {
881 u8 band; 889 u8 band;
882 u8 antenna; 890 u8 antenna;
883 s8 signal; 891 s8 signal;
892 u8 chains;
893 s8 chain_signal[IEEE80211_MAX_CHAINS];
884 u8 ampdu_delimiter_crc; 894 u8 ampdu_delimiter_crc;
885 u8 vendor_radiotap_align; 895 u8 vendor_radiotap_align;
886 u8 vendor_radiotap_oui[3]; 896 u8 vendor_radiotap_oui[3];
@@ -1235,7 +1245,7 @@ enum ieee80211_sta_rx_bandwidth {
1235 * struct ieee80211_sta_rates - station rate selection table 1245 * struct ieee80211_sta_rates - station rate selection table
1236 * 1246 *
1237 * @rcu_head: RCU head used for freeing the table on update 1247 * @rcu_head: RCU head used for freeing the table on update
1238 * @rates: transmit rates/flags to be used by default. 1248 * @rate: transmit rates/flags to be used by default.
1239 * Overriding entries per-packet is possible by using cb tx control. 1249 * Overriding entries per-packet is possible by using cb tx control.
1240 */ 1250 */
1241struct ieee80211_sta_rates { 1251struct ieee80211_sta_rates {
@@ -1276,7 +1286,7 @@ struct ieee80211_sta_rates {
1276 * notifications and capabilities. The value is only valid after 1286 * notifications and capabilities. The value is only valid after
1277 * the station moves to associated state. 1287 * the station moves to associated state.
1278 * @smps_mode: current SMPS mode (off, static or dynamic) 1288 * @smps_mode: current SMPS mode (off, static or dynamic)
1279 * @tx_rates: rate control selection table 1289 * @rates: rate control selection table
1280 */ 1290 */
1281struct ieee80211_sta { 1291struct ieee80211_sta {
1282 u32 supp_rates[IEEE80211_NUM_BANDS]; 1292 u32 supp_rates[IEEE80211_NUM_BANDS];
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index d1e48b5e348f..5920715278c2 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -27,6 +27,8 @@
27 27
28#include <linux/types.h> 28#include <linux/types.h>
29 29
30#define NL80211_GENL_NAME "nl80211"
31
30/** 32/**
31 * DOC: Station handling 33 * DOC: Station handling
32 * 34 *
@@ -1429,6 +1431,11 @@ enum nl80211_commands {
1429 * @NL80211_ATTR_MAX_CRIT_PROT_DURATION: duration in milliseconds in which 1431 * @NL80211_ATTR_MAX_CRIT_PROT_DURATION: duration in milliseconds in which
1430 * the connection should have increased reliability (u16). 1432 * the connection should have increased reliability (u16).
1431 * 1433 *
1434 * @NL80211_ATTR_PEER_AID: Association ID for the peer TDLS station (u16).
1435 * This is similar to @NL80211_ATTR_STA_AID but with a difference of being
1436 * allowed to be used with the first @NL80211_CMD_SET_STATION command to
1437 * update a TDLS peer STA entry.
1438 *
1432 * @NL80211_ATTR_MAX: highest attribute number currently defined 1439 * @NL80211_ATTR_MAX: highest attribute number currently defined
1433 * @__NL80211_ATTR_AFTER_LAST: internal use 1440 * @__NL80211_ATTR_AFTER_LAST: internal use
1434 */ 1441 */
@@ -1727,6 +1734,8 @@ enum nl80211_attrs {
1727 NL80211_ATTR_CRIT_PROT_ID, 1734 NL80211_ATTR_CRIT_PROT_ID,
1728 NL80211_ATTR_MAX_CRIT_PROT_DURATION, 1735 NL80211_ATTR_MAX_CRIT_PROT_DURATION,
1729 1736
1737 NL80211_ATTR_PEER_AID,
1738
1730 /* add attributes here, update the policy in nl80211.c */ 1739 /* add attributes here, update the policy in nl80211.c */
1731 1740
1732 __NL80211_ATTR_AFTER_LAST, 1741 __NL80211_ATTR_AFTER_LAST,
@@ -1991,6 +2000,10 @@ enum nl80211_sta_bss_param {
1991 * @NL80211_STA_INFO_PEER_PM: peer mesh STA link-specific power mode 2000 * @NL80211_STA_INFO_PEER_PM: peer mesh STA link-specific power mode
1992 * @NL80211_STA_INFO_NONPEER_PM: neighbor mesh STA power save mode towards 2001 * @NL80211_STA_INFO_NONPEER_PM: neighbor mesh STA power save mode towards
1993 * non-peer STA 2002 * non-peer STA
2003 * @NL80211_STA_INFO_CHAIN_SIGNAL: per-chain signal strength of last PPDU
2004 * Contains a nested array of signal strength attributes (u8, dBm)
2005 * @NL80211_STA_INFO_CHAIN_SIGNAL_AVG: per-chain signal strength average
2006 * Same format as NL80211_STA_INFO_CHAIN_SIGNAL.
1994 * @__NL80211_STA_INFO_AFTER_LAST: internal 2007 * @__NL80211_STA_INFO_AFTER_LAST: internal
1995 * @NL80211_STA_INFO_MAX: highest possible station info attribute 2008 * @NL80211_STA_INFO_MAX: highest possible station info attribute
1996 */ 2009 */
@@ -2020,6 +2033,8 @@ enum nl80211_sta_info {
2020 NL80211_STA_INFO_NONPEER_PM, 2033 NL80211_STA_INFO_NONPEER_PM,
2021 NL80211_STA_INFO_RX_BYTES64, 2034 NL80211_STA_INFO_RX_BYTES64,
2022 NL80211_STA_INFO_TX_BYTES64, 2035 NL80211_STA_INFO_TX_BYTES64,
2036 NL80211_STA_INFO_CHAIN_SIGNAL,
2037 NL80211_STA_INFO_CHAIN_SIGNAL_AVG,
2023 2038
2024 /* keep last */ 2039 /* keep last */
2025 __NL80211_STA_INFO_AFTER_LAST, 2040 __NL80211_STA_INFO_AFTER_LAST,
@@ -2413,6 +2428,8 @@ enum nl80211_survey_info {
2413 * @NL80211_MNTR_FLAG_OTHER_BSS: disable BSSID filtering 2428 * @NL80211_MNTR_FLAG_OTHER_BSS: disable BSSID filtering
2414 * @NL80211_MNTR_FLAG_COOK_FRAMES: report frames after processing. 2429 * @NL80211_MNTR_FLAG_COOK_FRAMES: report frames after processing.
2415 * overrides all other flags. 2430 * overrides all other flags.
2431 * @NL80211_MNTR_FLAG_ACTIVE: use the configured MAC address
2432 * and ACK incoming unicast packets.
2416 * 2433 *
2417 * @__NL80211_MNTR_FLAG_AFTER_LAST: internal use 2434 * @__NL80211_MNTR_FLAG_AFTER_LAST: internal use
2418 * @NL80211_MNTR_FLAG_MAX: highest possible monitor flag 2435 * @NL80211_MNTR_FLAG_MAX: highest possible monitor flag
@@ -2424,6 +2441,7 @@ enum nl80211_mntr_flags {
2424 NL80211_MNTR_FLAG_CONTROL, 2441 NL80211_MNTR_FLAG_CONTROL,
2425 NL80211_MNTR_FLAG_OTHER_BSS, 2442 NL80211_MNTR_FLAG_OTHER_BSS,
2426 NL80211_MNTR_FLAG_COOK_FRAMES, 2443 NL80211_MNTR_FLAG_COOK_FRAMES,
2444 NL80211_MNTR_FLAG_ACTIVE,
2427 2445
2428 /* keep last */ 2446 /* keep last */
2429 __NL80211_MNTR_FLAG_AFTER_LAST, 2447 __NL80211_MNTR_FLAG_AFTER_LAST,
@@ -2637,6 +2655,10 @@ enum nl80211_meshconf_params {
2637 * @NL80211_MESH_SETUP_USERSPACE_MPM: Enable this option if userspace will 2655 * @NL80211_MESH_SETUP_USERSPACE_MPM: Enable this option if userspace will
2638 * implement an MPM which handles peer allocation and state. 2656 * implement an MPM which handles peer allocation and state.
2639 * 2657 *
2658 * @NL80211_MESH_SETUP_AUTH_PROTOCOL: Inform the kernel of the authentication
2659 * method (u8, as defined in IEEE 8.4.2.100.6, e.g. 0x1 for SAE).
2660 * Default is no authentication method required.
2661 *
2640 * @NL80211_MESH_SETUP_ATTR_MAX: highest possible mesh setup attribute number 2662 * @NL80211_MESH_SETUP_ATTR_MAX: highest possible mesh setup attribute number
2641 * 2663 *
2642 * @__NL80211_MESH_SETUP_ATTR_AFTER_LAST: Internal use 2664 * @__NL80211_MESH_SETUP_ATTR_AFTER_LAST: Internal use
@@ -2650,6 +2672,7 @@ enum nl80211_mesh_setup_params {
2650 NL80211_MESH_SETUP_USERSPACE_AMPE, 2672 NL80211_MESH_SETUP_USERSPACE_AMPE,
2651 NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC, 2673 NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC,
2652 NL80211_MESH_SETUP_USERSPACE_MPM, 2674 NL80211_MESH_SETUP_USERSPACE_MPM,
2675 NL80211_MESH_SETUP_AUTH_PROTOCOL,
2653 2676
2654 /* keep last */ 2677 /* keep last */
2655 __NL80211_MESH_SETUP_ATTR_AFTER_LAST, 2678 __NL80211_MESH_SETUP_ATTR_AFTER_LAST,
@@ -3575,6 +3598,7 @@ enum nl80211_feature_flags {
3575 NL80211_FEATURE_ADVERTISE_CHAN_LIMITS = 1 << 14, 3598 NL80211_FEATURE_ADVERTISE_CHAN_LIMITS = 1 << 14,
3576 NL80211_FEATURE_FULL_AP_CLIENT_STATE = 1 << 15, 3599 NL80211_FEATURE_FULL_AP_CLIENT_STATE = 1 << 15,
3577 NL80211_FEATURE_USERSPACE_MPM = 1 << 16, 3600 NL80211_FEATURE_USERSPACE_MPM = 1 << 16,
3601 NL80211_FEATURE_ACTIVE_MONITOR = 1 << 17,
3578}; 3602};
3579 3603
3580/** 3604/**
diff --git a/net/mac80211/aes_ccm.c b/net/mac80211/aes_ccm.c
index 0785e95c9924..be7614b9ed27 100644
--- a/net/mac80211/aes_ccm.c
+++ b/net/mac80211/aes_ccm.c
@@ -85,7 +85,7 @@ void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *scratch,
85 *cpos++ = *pos++ ^ e[i]; 85 *cpos++ = *pos++ ^ e[i];
86 } 86 }
87 87
88 for (i = 0; i < CCMP_MIC_LEN; i++) 88 for (i = 0; i < IEEE80211_CCMP_MIC_LEN; i++)
89 mic[i] = b[i] ^ s_0[i]; 89 mic[i] = b[i] ^ s_0[i];
90} 90}
91 91
@@ -123,7 +123,7 @@ int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *scratch,
123 crypto_cipher_encrypt_one(tfm, a, a); 123 crypto_cipher_encrypt_one(tfm, a, a);
124 } 124 }
125 125
126 for (i = 0; i < CCMP_MIC_LEN; i++) { 126 for (i = 0; i < IEEE80211_CCMP_MIC_LEN; i++) {
127 if ((mic[i] ^ s_0[i]) != a[i]) 127 if ((mic[i] ^ s_0[i]) != a[i])
128 return -1; 128 return -1;
129 } 129 }
@@ -138,7 +138,7 @@ struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[])
138 138
139 tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC); 139 tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC);
140 if (!IS_ERR(tfm)) 140 if (!IS_ERR(tfm))
141 crypto_cipher_setkey(tfm, key, ALG_CCMP_KEY_LEN); 141 crypto_cipher_setkey(tfm, key, WLAN_KEY_LEN_CCMP);
142 142
143 return tfm; 143 return tfm;
144} 144}
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 1a89c80e6407..30622101d3b5 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -73,16 +73,19 @@ static int ieee80211_change_iface(struct wiphy *wiphy,
73 struct ieee80211_local *local = sdata->local; 73 struct ieee80211_local *local = sdata->local;
74 74
75 if (ieee80211_sdata_running(sdata)) { 75 if (ieee80211_sdata_running(sdata)) {
76 u32 mask = MONITOR_FLAG_COOK_FRAMES |
77 MONITOR_FLAG_ACTIVE;
78
76 /* 79 /*
77 * Prohibit MONITOR_FLAG_COOK_FRAMES to be 80 * Prohibit MONITOR_FLAG_COOK_FRAMES and
78 * changed while the interface is up. 81 * MONITOR_FLAG_ACTIVE to be changed while the
82 * interface is up.
79 * Else we would need to add a lot of cruft 83 * Else we would need to add a lot of cruft
80 * to update everything: 84 * to update everything:
81 * cooked_mntrs, monitor and all fif_* counters 85 * cooked_mntrs, monitor and all fif_* counters
82 * reconfigure hardware 86 * reconfigure hardware
83 */ 87 */
84 if ((*flags & MONITOR_FLAG_COOK_FRAMES) != 88 if ((*flags & mask) != (sdata->u.mntr_flags & mask))
85 (sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES))
86 return -EBUSY; 89 return -EBUSY;
87 90
88 ieee80211_adjust_monitor_flags(sdata, -1); 91 ieee80211_adjust_monitor_flags(sdata, -1);
@@ -444,7 +447,7 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
444 struct ieee80211_local *local = sdata->local; 447 struct ieee80211_local *local = sdata->local;
445 struct timespec uptime; 448 struct timespec uptime;
446 u64 packets = 0; 449 u64 packets = 0;
447 int ac; 450 int i, ac;
448 451
449 sinfo->generation = sdata->local->sta_generation; 452 sinfo->generation = sdata->local->sta_generation;
450 453
@@ -488,6 +491,17 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
488 sinfo->signal = (s8)sta->last_signal; 491 sinfo->signal = (s8)sta->last_signal;
489 sinfo->signal_avg = (s8) -ewma_read(&sta->avg_signal); 492 sinfo->signal_avg = (s8) -ewma_read(&sta->avg_signal);
490 } 493 }
494 if (sta->chains) {
495 sinfo->filled |= STATION_INFO_CHAIN_SIGNAL |
496 STATION_INFO_CHAIN_SIGNAL_AVG;
497
498 sinfo->chains = sta->chains;
499 for (i = 0; i < ARRAY_SIZE(sinfo->chain_signal); i++) {
500 sinfo->chain_signal[i] = sta->chain_signal_last[i];
501 sinfo->chain_signal_avg[i] =
502 (s8) -ewma_read(&sta->chain_signal_avg[i]);
503 }
504 }
491 505
492 sta_set_rate_info_tx(sta, &sta->last_tx_rate, &sinfo->txrate); 506 sta_set_rate_info_tx(sta, &sta->last_tx_rate, &sinfo->txrate);
493 sta_set_rate_info_rx(sta, &sinfo->rxrate); 507 sta_set_rate_info_rx(sta, &sinfo->rxrate);
@@ -728,7 +742,7 @@ static void ieee80211_get_et_strings(struct wiphy *wiphy,
728 742
729 if (sset == ETH_SS_STATS) { 743 if (sset == ETH_SS_STATS) {
730 sz_sta_stats = sizeof(ieee80211_gstrings_sta_stats); 744 sz_sta_stats = sizeof(ieee80211_gstrings_sta_stats);
731 memcpy(data, *ieee80211_gstrings_sta_stats, sz_sta_stats); 745 memcpy(data, ieee80211_gstrings_sta_stats, sz_sta_stats);
732 } 746 }
733 drv_get_et_strings(sdata, sset, &(data[sz_sta_stats])); 747 drv_get_et_strings(sdata, sset, &(data[sz_sta_stats]));
734} 748}
@@ -1735,6 +1749,7 @@ static int copy_mesh_setup(struct ieee80211_if_mesh *ifmsh,
1735 ifmsh->mesh_pp_id = setup->path_sel_proto; 1749 ifmsh->mesh_pp_id = setup->path_sel_proto;
1736 ifmsh->mesh_pm_id = setup->path_metric; 1750 ifmsh->mesh_pm_id = setup->path_metric;
1737 ifmsh->user_mpm = setup->user_mpm; 1751 ifmsh->user_mpm = setup->user_mpm;
1752 ifmsh->mesh_auth_id = setup->auth_id;
1738 ifmsh->security = IEEE80211_MESH_SEC_NONE; 1753 ifmsh->security = IEEE80211_MESH_SEC_NONE;
1739 if (setup->is_authenticated) 1754 if (setup->is_authenticated)
1740 ifmsh->security |= IEEE80211_MESH_SEC_AUTHED; 1755 ifmsh->security |= IEEE80211_MESH_SEC_AUTHED;
@@ -2306,7 +2321,7 @@ int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata,
2306 enum ieee80211_smps_mode old_req; 2321 enum ieee80211_smps_mode old_req;
2307 int err; 2322 int err;
2308 2323
2309 lockdep_assert_held(&sdata->u.mgd.mtx); 2324 lockdep_assert_held(&sdata->wdev.mtx);
2310 2325
2311 old_req = sdata->u.mgd.req_smps; 2326 old_req = sdata->u.mgd.req_smps;
2312 sdata->u.mgd.req_smps = smps_mode; 2327 sdata->u.mgd.req_smps = smps_mode;
@@ -2363,9 +2378,9 @@ static int ieee80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
2363 local->dynamic_ps_forced_timeout = timeout; 2378 local->dynamic_ps_forced_timeout = timeout;
2364 2379
2365 /* no change, but if automatic follow powersave */ 2380 /* no change, but if automatic follow powersave */
2366 mutex_lock(&sdata->u.mgd.mtx); 2381 sdata_lock(sdata);
2367 __ieee80211_request_smps(sdata, sdata->u.mgd.req_smps); 2382 __ieee80211_request_smps(sdata, sdata->u.mgd.req_smps);
2368 mutex_unlock(&sdata->u.mgd.mtx); 2383 sdata_unlock(sdata);
2369 2384
2370 if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS) 2385 if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS)
2371 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); 2386 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c
index 14abcf44f974..cafe614ef93d 100644
--- a/net/mac80211/debugfs_netdev.c
+++ b/net/mac80211/debugfs_netdev.c
@@ -228,9 +228,9 @@ static int ieee80211_set_smps(struct ieee80211_sub_if_data *sdata,
228 if (sdata->vif.type != NL80211_IFTYPE_STATION) 228 if (sdata->vif.type != NL80211_IFTYPE_STATION)
229 return -EOPNOTSUPP; 229 return -EOPNOTSUPP;
230 230
231 mutex_lock(&sdata->u.mgd.mtx); 231 sdata_lock(sdata);
232 err = __ieee80211_request_smps(sdata, smps_mode); 232 err = __ieee80211_request_smps(sdata, smps_mode);
233 mutex_unlock(&sdata->u.mgd.mtx); 233 sdata_unlock(sdata);
234 234
235 return err; 235 return err;
236} 236}
@@ -313,16 +313,16 @@ static ssize_t ieee80211_if_parse_tkip_mic_test(
313 case NL80211_IFTYPE_STATION: 313 case NL80211_IFTYPE_STATION:
314 fc |= cpu_to_le16(IEEE80211_FCTL_TODS); 314 fc |= cpu_to_le16(IEEE80211_FCTL_TODS);
315 /* BSSID SA DA */ 315 /* BSSID SA DA */
316 mutex_lock(&sdata->u.mgd.mtx); 316 sdata_lock(sdata);
317 if (!sdata->u.mgd.associated) { 317 if (!sdata->u.mgd.associated) {
318 mutex_unlock(&sdata->u.mgd.mtx); 318 sdata_unlock(sdata);
319 dev_kfree_skb(skb); 319 dev_kfree_skb(skb);
320 return -ENOTCONN; 320 return -ENOTCONN;
321 } 321 }
322 memcpy(hdr->addr1, sdata->u.mgd.associated->bssid, ETH_ALEN); 322 memcpy(hdr->addr1, sdata->u.mgd.associated->bssid, ETH_ALEN);
323 memcpy(hdr->addr2, sdata->vif.addr, ETH_ALEN); 323 memcpy(hdr->addr2, sdata->vif.addr, ETH_ALEN);
324 memcpy(hdr->addr3, addr, ETH_ALEN); 324 memcpy(hdr->addr3, addr, ETH_ALEN);
325 mutex_unlock(&sdata->u.mgd.mtx); 325 sdata_unlock(sdata);
326 break; 326 break;
327 default: 327 default:
328 dev_kfree_skb(skb); 328 dev_kfree_skb(skb);
@@ -471,6 +471,8 @@ __IEEE80211_IF_FILE_W(tsf);
471IEEE80211_IF_FILE(peer, u.wds.remote_addr, MAC); 471IEEE80211_IF_FILE(peer, u.wds.remote_addr, MAC);
472 472
473#ifdef CONFIG_MAC80211_MESH 473#ifdef CONFIG_MAC80211_MESH
474IEEE80211_IF_FILE(estab_plinks, u.mesh.estab_plinks, ATOMIC);
475
474/* Mesh stats attributes */ 476/* Mesh stats attributes */
475IEEE80211_IF_FILE(fwded_mcast, u.mesh.mshstats.fwded_mcast, DEC); 477IEEE80211_IF_FILE(fwded_mcast, u.mesh.mshstats.fwded_mcast, DEC);
476IEEE80211_IF_FILE(fwded_unicast, u.mesh.mshstats.fwded_unicast, DEC); 478IEEE80211_IF_FILE(fwded_unicast, u.mesh.mshstats.fwded_unicast, DEC);
@@ -480,7 +482,6 @@ IEEE80211_IF_FILE(dropped_frames_congestion,
480 u.mesh.mshstats.dropped_frames_congestion, DEC); 482 u.mesh.mshstats.dropped_frames_congestion, DEC);
481IEEE80211_IF_FILE(dropped_frames_no_route, 483IEEE80211_IF_FILE(dropped_frames_no_route,
482 u.mesh.mshstats.dropped_frames_no_route, DEC); 484 u.mesh.mshstats.dropped_frames_no_route, DEC);
483IEEE80211_IF_FILE(estab_plinks, u.mesh.estab_plinks, ATOMIC);
484 485
485/* Mesh parameters */ 486/* Mesh parameters */
486IEEE80211_IF_FILE(dot11MeshMaxRetries, 487IEEE80211_IF_FILE(dot11MeshMaxRetries,
@@ -583,6 +584,7 @@ static void add_wds_files(struct ieee80211_sub_if_data *sdata)
583static void add_mesh_files(struct ieee80211_sub_if_data *sdata) 584static void add_mesh_files(struct ieee80211_sub_if_data *sdata)
584{ 585{
585 DEBUGFS_ADD_MODE(tsf, 0600); 586 DEBUGFS_ADD_MODE(tsf, 0600);
587 DEBUGFS_ADD_MODE(estab_plinks, 0400);
586} 588}
587 589
588static void add_mesh_stats(struct ieee80211_sub_if_data *sdata) 590static void add_mesh_stats(struct ieee80211_sub_if_data *sdata)
@@ -598,7 +600,6 @@ static void add_mesh_stats(struct ieee80211_sub_if_data *sdata)
598 MESHSTATS_ADD(dropped_frames_ttl); 600 MESHSTATS_ADD(dropped_frames_ttl);
599 MESHSTATS_ADD(dropped_frames_no_route); 601 MESHSTATS_ADD(dropped_frames_no_route);
600 MESHSTATS_ADD(dropped_frames_congestion); 602 MESHSTATS_ADD(dropped_frames_congestion);
601 MESHSTATS_ADD(estab_plinks);
602#undef MESHSTATS_ADD 603#undef MESHSTATS_ADD
603} 604}
604 605
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index 169664c122e2..b931c96a596f 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -146,7 +146,8 @@ static inline int drv_add_interface(struct ieee80211_local *local,
146 146
147 if (WARN_ON(sdata->vif.type == NL80211_IFTYPE_AP_VLAN || 147 if (WARN_ON(sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
148 (sdata->vif.type == NL80211_IFTYPE_MONITOR && 148 (sdata->vif.type == NL80211_IFTYPE_MONITOR &&
149 !(local->hw.flags & IEEE80211_HW_WANT_MONITOR_VIF)))) 149 !(local->hw.flags & IEEE80211_HW_WANT_MONITOR_VIF) &&
150 !(sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE))))
150 return -EINVAL; 151 return -EINVAL;
151 152
152 trace_drv_add_interface(local, sdata); 153 trace_drv_add_interface(local, sdata);
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c
index af8cee06e4f3..75dff338f581 100644
--- a/net/mac80211/ht.c
+++ b/net/mac80211/ht.c
@@ -429,9 +429,9 @@ void ieee80211_request_smps_work(struct work_struct *work)
429 container_of(work, struct ieee80211_sub_if_data, 429 container_of(work, struct ieee80211_sub_if_data,
430 u.mgd.request_smps_work); 430 u.mgd.request_smps_work);
431 431
432 mutex_lock(&sdata->u.mgd.mtx); 432 sdata_lock(sdata);
433 __ieee80211_request_smps(sdata, sdata->u.mgd.driver_smps_mode); 433 __ieee80211_request_smps(sdata, sdata->u.mgd.driver_smps_mode);
434 mutex_unlock(&sdata->u.mgd.mtx); 434 sdata_unlock(sdata);
435} 435}
436 436
437void ieee80211_request_smps(struct ieee80211_vif *vif, 437void ieee80211_request_smps(struct ieee80211_vif *vif,
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 170f9a7fa319..caa4b4f7f6e4 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -54,7 +54,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
54 struct beacon_data *presp; 54 struct beacon_data *presp;
55 int frame_len; 55 int frame_len;
56 56
57 lockdep_assert_held(&ifibss->mtx); 57 sdata_assert_lock(sdata);
58 58
59 /* Reset own TSF to allow time synchronization work. */ 59 /* Reset own TSF to allow time synchronization work. */
60 drv_reset_tsf(local, sdata); 60 drv_reset_tsf(local, sdata);
@@ -74,7 +74,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
74 } 74 }
75 75
76 presp = rcu_dereference_protected(ifibss->presp, 76 presp = rcu_dereference_protected(ifibss->presp,
77 lockdep_is_held(&ifibss->mtx)); 77 lockdep_is_held(&sdata->wdev.mtx));
78 rcu_assign_pointer(ifibss->presp, NULL); 78 rcu_assign_pointer(ifibss->presp, NULL);
79 if (presp) 79 if (presp)
80 kfree_rcu(presp, rcu_head); 80 kfree_rcu(presp, rcu_head);
@@ -263,7 +263,7 @@ static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
263 const struct cfg80211_bss_ies *ies; 263 const struct cfg80211_bss_ies *ies;
264 u64 tsf; 264 u64 tsf;
265 265
266 lockdep_assert_held(&sdata->u.ibss.mtx); 266 sdata_assert_lock(sdata);
267 267
268 if (beacon_int < 10) 268 if (beacon_int < 10)
269 beacon_int = 10; 269 beacon_int = 10;
@@ -341,6 +341,7 @@ ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
341 struct ieee80211_local *local = sdata->local; 341 struct ieee80211_local *local = sdata->local;
342 struct sta_info *sta; 342 struct sta_info *sta;
343 struct ieee80211_chanctx_conf *chanctx_conf; 343 struct ieee80211_chanctx_conf *chanctx_conf;
344 struct ieee80211_supported_band *sband;
344 int band; 345 int band;
345 346
346 /* 347 /*
@@ -380,8 +381,9 @@ ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
380 sta->last_rx = jiffies; 381 sta->last_rx = jiffies;
381 382
382 /* make sure mandatory rates are always added */ 383 /* make sure mandatory rates are always added */
384 sband = local->hw.wiphy->bands[band];
383 sta->sta.supp_rates[band] = supp_rates | 385 sta->sta.supp_rates[band] = supp_rates |
384 ieee80211_mandatory_rates(local, band); 386 ieee80211_mandatory_rates(sband);
385 387
386 return ieee80211_ibss_finish_sta(sta, auth); 388 return ieee80211_ibss_finish_sta(sta, auth);
387} 389}
@@ -408,7 +410,7 @@ static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata,
408 struct sta_info *sta; 410 struct sta_info *sta;
409 u8 deauth_frame_buf[IEEE80211_DEAUTH_FRAME_LEN]; 411 u8 deauth_frame_buf[IEEE80211_DEAUTH_FRAME_LEN];
410 412
411 lockdep_assert_held(&sdata->u.ibss.mtx); 413 sdata_assert_lock(sdata);
412 414
413 if (len < 24 + 6) 415 if (len < 24 + 6)
414 return; 416 return;
@@ -492,7 +494,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
492 prev_rates = sta->sta.supp_rates[band]; 494 prev_rates = sta->sta.supp_rates[band];
493 /* make sure mandatory rates are always added */ 495 /* make sure mandatory rates are always added */
494 sta->sta.supp_rates[band] = supp_rates | 496 sta->sta.supp_rates[band] = supp_rates |
495 ieee80211_mandatory_rates(local, band); 497 ieee80211_mandatory_rates(sband);
496 498
497 if (sta->sta.supp_rates[band] != prev_rates) { 499 if (sta->sta.supp_rates[band] != prev_rates) {
498 ibss_dbg(sdata, 500 ibss_dbg(sdata,
@@ -624,6 +626,7 @@ void ieee80211_ibss_rx_no_sta(struct ieee80211_sub_if_data *sdata,
624 struct ieee80211_local *local = sdata->local; 626 struct ieee80211_local *local = sdata->local;
625 struct sta_info *sta; 627 struct sta_info *sta;
626 struct ieee80211_chanctx_conf *chanctx_conf; 628 struct ieee80211_chanctx_conf *chanctx_conf;
629 struct ieee80211_supported_band *sband;
627 int band; 630 int band;
628 631
629 /* 632 /*
@@ -658,8 +661,9 @@ void ieee80211_ibss_rx_no_sta(struct ieee80211_sub_if_data *sdata,
658 sta->last_rx = jiffies; 661 sta->last_rx = jiffies;
659 662
660 /* make sure mandatory rates are always added */ 663 /* make sure mandatory rates are always added */
664 sband = local->hw.wiphy->bands[band];
661 sta->sta.supp_rates[band] = supp_rates | 665 sta->sta.supp_rates[band] = supp_rates |
662 ieee80211_mandatory_rates(local, band); 666 ieee80211_mandatory_rates(sband);
663 667
664 spin_lock(&ifibss->incomplete_lock); 668 spin_lock(&ifibss->incomplete_lock);
665 list_add(&sta->list, &ifibss->incomplete_stations); 669 list_add(&sta->list, &ifibss->incomplete_stations);
@@ -673,7 +677,7 @@ static int ieee80211_sta_active_ibss(struct ieee80211_sub_if_data *sdata)
673 int active = 0; 677 int active = 0;
674 struct sta_info *sta; 678 struct sta_info *sta;
675 679
676 lockdep_assert_held(&sdata->u.ibss.mtx); 680 sdata_assert_lock(sdata);
677 681
678 rcu_read_lock(); 682 rcu_read_lock();
679 683
@@ -699,7 +703,7 @@ static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata)
699{ 703{
700 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; 704 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
701 705
702 lockdep_assert_held(&ifibss->mtx); 706 sdata_assert_lock(sdata);
703 707
704 mod_timer(&ifibss->timer, 708 mod_timer(&ifibss->timer,
705 round_jiffies(jiffies + IEEE80211_IBSS_MERGE_INTERVAL)); 709 round_jiffies(jiffies + IEEE80211_IBSS_MERGE_INTERVAL));
@@ -730,7 +734,7 @@ static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
730 u16 capability; 734 u16 capability;
731 int i; 735 int i;
732 736
733 lockdep_assert_held(&ifibss->mtx); 737 sdata_assert_lock(sdata);
734 738
735 if (ifibss->fixed_bssid) { 739 if (ifibss->fixed_bssid) {
736 memcpy(bssid, ifibss->bssid, ETH_ALEN); 740 memcpy(bssid, ifibss->bssid, ETH_ALEN);
@@ -773,7 +777,7 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
773 int active_ibss; 777 int active_ibss;
774 u16 capability; 778 u16 capability;
775 779
776 lockdep_assert_held(&ifibss->mtx); 780 sdata_assert_lock(sdata);
777 781
778 active_ibss = ieee80211_sta_active_ibss(sdata); 782 active_ibss = ieee80211_sta_active_ibss(sdata);
779 ibss_dbg(sdata, "sta_find_ibss (active_ibss=%d)\n", active_ibss); 783 ibss_dbg(sdata, "sta_find_ibss (active_ibss=%d)\n", active_ibss);
@@ -843,10 +847,10 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata,
843 struct beacon_data *presp; 847 struct beacon_data *presp;
844 u8 *pos, *end; 848 u8 *pos, *end;
845 849
846 lockdep_assert_held(&ifibss->mtx); 850 sdata_assert_lock(sdata);
847 851
848 presp = rcu_dereference_protected(ifibss->presp, 852 presp = rcu_dereference_protected(ifibss->presp,
849 lockdep_is_held(&ifibss->mtx)); 853 lockdep_is_held(&sdata->wdev.mtx));
850 854
851 if (ifibss->state != IEEE80211_IBSS_MLME_JOINED || 855 if (ifibss->state != IEEE80211_IBSS_MLME_JOINED ||
852 len < 24 + 2 || !presp) 856 len < 24 + 2 || !presp)
@@ -930,7 +934,7 @@ void ieee80211_ibss_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
930 mgmt = (struct ieee80211_mgmt *) skb->data; 934 mgmt = (struct ieee80211_mgmt *) skb->data;
931 fc = le16_to_cpu(mgmt->frame_control); 935 fc = le16_to_cpu(mgmt->frame_control);
932 936
933 mutex_lock(&sdata->u.ibss.mtx); 937 sdata_lock(sdata);
934 938
935 if (!sdata->u.ibss.ssid_len) 939 if (!sdata->u.ibss.ssid_len)
936 goto mgmt_out; /* not ready to merge yet */ 940 goto mgmt_out; /* not ready to merge yet */
@@ -953,7 +957,7 @@ void ieee80211_ibss_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
953 } 957 }
954 958
955 mgmt_out: 959 mgmt_out:
956 mutex_unlock(&sdata->u.ibss.mtx); 960 sdata_unlock(sdata);
957} 961}
958 962
959void ieee80211_ibss_work(struct ieee80211_sub_if_data *sdata) 963void ieee80211_ibss_work(struct ieee80211_sub_if_data *sdata)
@@ -961,7 +965,7 @@ void ieee80211_ibss_work(struct ieee80211_sub_if_data *sdata)
961 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; 965 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
962 struct sta_info *sta; 966 struct sta_info *sta;
963 967
964 mutex_lock(&ifibss->mtx); 968 sdata_lock(sdata);
965 969
966 /* 970 /*
967 * Work could be scheduled after scan or similar 971 * Work could be scheduled after scan or similar
@@ -997,7 +1001,7 @@ void ieee80211_ibss_work(struct ieee80211_sub_if_data *sdata)
997 } 1001 }
998 1002
999 out: 1003 out:
1000 mutex_unlock(&ifibss->mtx); 1004 sdata_unlock(sdata);
1001} 1005}
1002 1006
1003static void ieee80211_ibss_timer(unsigned long data) 1007static void ieee80211_ibss_timer(unsigned long data)
@@ -1014,7 +1018,6 @@ void ieee80211_ibss_setup_sdata(struct ieee80211_sub_if_data *sdata)
1014 1018
1015 setup_timer(&ifibss->timer, ieee80211_ibss_timer, 1019 setup_timer(&ifibss->timer, ieee80211_ibss_timer,
1016 (unsigned long) sdata); 1020 (unsigned long) sdata);
1017 mutex_init(&ifibss->mtx);
1018 INIT_LIST_HEAD(&ifibss->incomplete_stations); 1021 INIT_LIST_HEAD(&ifibss->incomplete_stations);
1019 spin_lock_init(&ifibss->incomplete_lock); 1022 spin_lock_init(&ifibss->incomplete_lock);
1020} 1023}
@@ -1041,8 +1044,6 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
1041{ 1044{
1042 u32 changed = 0; 1045 u32 changed = 0;
1043 1046
1044 mutex_lock(&sdata->u.ibss.mtx);
1045
1046 if (params->bssid) { 1047 if (params->bssid) {
1047 memcpy(sdata->u.ibss.bssid, params->bssid, ETH_ALEN); 1048 memcpy(sdata->u.ibss.bssid, params->bssid, ETH_ALEN);
1048 sdata->u.ibss.fixed_bssid = true; 1049 sdata->u.ibss.fixed_bssid = true;
@@ -1075,8 +1076,6 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
1075 memcpy(sdata->u.ibss.ssid, params->ssid, params->ssid_len); 1076 memcpy(sdata->u.ibss.ssid, params->ssid, params->ssid_len);
1076 sdata->u.ibss.ssid_len = params->ssid_len; 1077 sdata->u.ibss.ssid_len = params->ssid_len;
1077 1078
1078 mutex_unlock(&sdata->u.ibss.mtx);
1079
1080 /* 1079 /*
1081 * 802.11n-2009 9.13.3.1: In an IBSS, the HT Protection field is 1080 * 802.11n-2009 9.13.3.1: In an IBSS, the HT Protection field is
1082 * reserved, but an HT STA shall protect HT transmissions as though 1081 * reserved, but an HT STA shall protect HT transmissions as though
@@ -1112,8 +1111,6 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata)
1112 struct sta_info *sta; 1111 struct sta_info *sta;
1113 struct beacon_data *presp; 1112 struct beacon_data *presp;
1114 1113
1115 mutex_lock(&sdata->u.ibss.mtx);
1116
1117 active_ibss = ieee80211_sta_active_ibss(sdata); 1114 active_ibss = ieee80211_sta_active_ibss(sdata);
1118 1115
1119 if (!active_ibss && !is_zero_ether_addr(ifibss->bssid)) { 1116 if (!active_ibss && !is_zero_ether_addr(ifibss->bssid)) {
@@ -1157,7 +1154,7 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata)
1157 /* remove beacon */ 1154 /* remove beacon */
1158 kfree(sdata->u.ibss.ie); 1155 kfree(sdata->u.ibss.ie);
1159 presp = rcu_dereference_protected(ifibss->presp, 1156 presp = rcu_dereference_protected(ifibss->presp,
1160 lockdep_is_held(&sdata->u.ibss.mtx)); 1157 lockdep_is_held(&sdata->wdev.mtx));
1161 RCU_INIT_POINTER(sdata->u.ibss.presp, NULL); 1158 RCU_INIT_POINTER(sdata->u.ibss.presp, NULL);
1162 sdata->vif.bss_conf.ibss_joined = false; 1159 sdata->vif.bss_conf.ibss_joined = false;
1163 sdata->vif.bss_conf.ibss_creator = false; 1160 sdata->vif.bss_conf.ibss_creator = false;
@@ -1173,7 +1170,5 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata)
1173 1170
1174 del_timer_sync(&sdata->u.ibss.timer); 1171 del_timer_sync(&sdata->u.ibss.timer);
1175 1172
1176 mutex_unlock(&sdata->u.ibss.mtx);
1177
1178 return 0; 1173 return 0;
1179} 1174}
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 44be28cfc6c4..9eed6f1d1614 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -394,7 +394,6 @@ struct ieee80211_if_managed {
394 bool nullfunc_failed; 394 bool nullfunc_failed;
395 bool connection_loss; 395 bool connection_loss;
396 396
397 struct mutex mtx;
398 struct cfg80211_bss *associated; 397 struct cfg80211_bss *associated;
399 struct ieee80211_mgd_auth_data *auth_data; 398 struct ieee80211_mgd_auth_data *auth_data;
400 struct ieee80211_mgd_assoc_data *assoc_data; 399 struct ieee80211_mgd_assoc_data *assoc_data;
@@ -488,8 +487,6 @@ struct ieee80211_if_managed {
488struct ieee80211_if_ibss { 487struct ieee80211_if_ibss {
489 struct timer_list timer; 488 struct timer_list timer;
490 489
491 struct mutex mtx;
492
493 unsigned long last_scan_completed; 490 unsigned long last_scan_completed;
494 491
495 u32 basic_rates; 492 u32 basic_rates;
@@ -580,8 +577,6 @@ struct ieee80211_if_mesh {
580 bool accepting_plinks; 577 bool accepting_plinks;
581 int num_gates; 578 int num_gates;
582 struct beacon_data __rcu *beacon; 579 struct beacon_data __rcu *beacon;
583 /* just protects beacon updates for now */
584 struct mutex mtx;
585 const u8 *ie; 580 const u8 *ie;
586 u8 ie_len; 581 u8 ie_len;
587 enum { 582 enum {
@@ -778,6 +773,26 @@ struct ieee80211_sub_if_data *vif_to_sdata(struct ieee80211_vif *p)
778 return container_of(p, struct ieee80211_sub_if_data, vif); 773 return container_of(p, struct ieee80211_sub_if_data, vif);
779} 774}
780 775
776static inline void sdata_lock(struct ieee80211_sub_if_data *sdata)
777 __acquires(&sdata->wdev.mtx)
778{
779 mutex_lock(&sdata->wdev.mtx);
780 __acquire(&sdata->wdev.mtx);
781}
782
783static inline void sdata_unlock(struct ieee80211_sub_if_data *sdata)
784 __releases(&sdata->wdev.mtx)
785{
786 mutex_unlock(&sdata->wdev.mtx);
787 __release(&sdata->wdev.mtx);
788}
789
790static inline void
791sdata_assert_lock(struct ieee80211_sub_if_data *sdata)
792{
793 lockdep_assert_held(&sdata->wdev.mtx);
794}
795
781static inline enum ieee80211_band 796static inline enum ieee80211_band
782ieee80211_get_sdata_band(struct ieee80211_sub_if_data *sdata) 797ieee80211_get_sdata_band(struct ieee80211_sub_if_data *sdata)
783{ 798{
@@ -1506,9 +1521,6 @@ static inline void ieee802_11_parse_elems(u8 *start, size_t len, bool action,
1506 ieee802_11_parse_elems_crc(start, len, action, elems, 0, 0); 1521 ieee802_11_parse_elems_crc(start, len, action, elems, 0, 0);
1507} 1522}
1508 1523
1509u32 ieee80211_mandatory_rates(struct ieee80211_local *local,
1510 enum ieee80211_band band);
1511
1512void ieee80211_dynamic_ps_enable_work(struct work_struct *work); 1524void ieee80211_dynamic_ps_enable_work(struct work_struct *work);
1513void ieee80211_dynamic_ps_disable_work(struct work_struct *work); 1525void ieee80211_dynamic_ps_disable_work(struct work_struct *work);
1514void ieee80211_dynamic_ps_timer(unsigned long data); 1526void ieee80211_dynamic_ps_timer(unsigned long data);
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 7c3ba8628d4e..cc117591f678 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -159,7 +159,8 @@ static int ieee80211_change_mtu(struct net_device *dev, int new_mtu)
159 return 0; 159 return 0;
160} 160}
161 161
162static int ieee80211_verify_mac(struct ieee80211_sub_if_data *sdata, u8 *addr) 162static int ieee80211_verify_mac(struct ieee80211_sub_if_data *sdata, u8 *addr,
163 bool check_dup)
163{ 164{
164 struct ieee80211_local *local = sdata->local; 165 struct ieee80211_local *local = sdata->local;
165 struct ieee80211_sub_if_data *iter; 166 struct ieee80211_sub_if_data *iter;
@@ -180,13 +181,16 @@ static int ieee80211_verify_mac(struct ieee80211_sub_if_data *sdata, u8 *addr)
180 ((u64)m[2] << 3*8) | ((u64)m[3] << 2*8) | 181 ((u64)m[2] << 3*8) | ((u64)m[3] << 2*8) |
181 ((u64)m[4] << 1*8) | ((u64)m[5] << 0*8); 182 ((u64)m[4] << 1*8) | ((u64)m[5] << 0*8);
182 183
184 if (!check_dup)
185 return ret;
183 186
184 mutex_lock(&local->iflist_mtx); 187 mutex_lock(&local->iflist_mtx);
185 list_for_each_entry(iter, &local->interfaces, list) { 188 list_for_each_entry(iter, &local->interfaces, list) {
186 if (iter == sdata) 189 if (iter == sdata)
187 continue; 190 continue;
188 191
189 if (iter->vif.type == NL80211_IFTYPE_MONITOR) 192 if (iter->vif.type == NL80211_IFTYPE_MONITOR &&
193 !(iter->u.mntr_flags & MONITOR_FLAG_ACTIVE))
190 continue; 194 continue;
191 195
192 m = iter->vif.addr; 196 m = iter->vif.addr;
@@ -208,12 +212,17 @@ static int ieee80211_change_mac(struct net_device *dev, void *addr)
208{ 212{
209 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 213 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
210 struct sockaddr *sa = addr; 214 struct sockaddr *sa = addr;
215 bool check_dup = true;
211 int ret; 216 int ret;
212 217
213 if (ieee80211_sdata_running(sdata)) 218 if (ieee80211_sdata_running(sdata))
214 return -EBUSY; 219 return -EBUSY;
215 220
216 ret = ieee80211_verify_mac(sdata, sa->sa_data); 221 if (sdata->vif.type == NL80211_IFTYPE_MONITOR &&
222 !(sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE))
223 check_dup = false;
224
225 ret = ieee80211_verify_mac(sdata, sa->sa_data, check_dup);
217 if (ret) 226 if (ret)
218 return ret; 227 return ret;
219 228
@@ -545,7 +554,11 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
545 break; 554 break;
546 } 555 }
547 556
548 if (local->monitors == 0 && local->open_count == 0) { 557 if (sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE) {
558 res = drv_add_interface(local, sdata);
559 if (res)
560 goto err_stop;
561 } else if (local->monitors == 0 && local->open_count == 0) {
549 res = ieee80211_add_virtual_monitor(local); 562 res = ieee80211_add_virtual_monitor(local);
550 if (res) 563 if (res)
551 goto err_stop; 564 goto err_stop;
@@ -923,7 +936,11 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
923 mutex_lock(&local->mtx); 936 mutex_lock(&local->mtx);
924 ieee80211_recalc_idle(local); 937 ieee80211_recalc_idle(local);
925 mutex_unlock(&local->mtx); 938 mutex_unlock(&local->mtx);
926 break; 939
940 if (!(sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE))
941 break;
942
943 /* fall through */
927 default: 944 default:
928 if (going_down) 945 if (going_down)
929 drv_remove_interface(local, sdata); 946 drv_remove_interface(local, sdata);
@@ -1072,7 +1089,7 @@ static const struct net_device_ops ieee80211_monitorif_ops = {
1072 .ndo_start_xmit = ieee80211_monitor_start_xmit, 1089 .ndo_start_xmit = ieee80211_monitor_start_xmit,
1073 .ndo_set_rx_mode = ieee80211_set_multicast_list, 1090 .ndo_set_rx_mode = ieee80211_set_multicast_list,
1074 .ndo_change_mtu = ieee80211_change_mtu, 1091 .ndo_change_mtu = ieee80211_change_mtu,
1075 .ndo_set_mac_address = eth_mac_addr, 1092 .ndo_set_mac_address = ieee80211_change_mac,
1076 .ndo_select_queue = ieee80211_monitor_select_queue, 1093 .ndo_select_queue = ieee80211_monitor_select_queue,
1077}; 1094};
1078 1095
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index 67059b88fea5..e39cc91d0cf1 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -335,12 +335,12 @@ struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len,
335 switch (cipher) { 335 switch (cipher) {
336 case WLAN_CIPHER_SUITE_WEP40: 336 case WLAN_CIPHER_SUITE_WEP40:
337 case WLAN_CIPHER_SUITE_WEP104: 337 case WLAN_CIPHER_SUITE_WEP104:
338 key->conf.iv_len = WEP_IV_LEN; 338 key->conf.iv_len = IEEE80211_WEP_IV_LEN;
339 key->conf.icv_len = WEP_ICV_LEN; 339 key->conf.icv_len = IEEE80211_WEP_ICV_LEN;
340 break; 340 break;
341 case WLAN_CIPHER_SUITE_TKIP: 341 case WLAN_CIPHER_SUITE_TKIP:
342 key->conf.iv_len = TKIP_IV_LEN; 342 key->conf.iv_len = IEEE80211_TKIP_IV_LEN;
343 key->conf.icv_len = TKIP_ICV_LEN; 343 key->conf.icv_len = IEEE80211_TKIP_ICV_LEN;
344 if (seq) { 344 if (seq) {
345 for (i = 0; i < IEEE80211_NUM_TIDS; i++) { 345 for (i = 0; i < IEEE80211_NUM_TIDS; i++) {
346 key->u.tkip.rx[i].iv32 = 346 key->u.tkip.rx[i].iv32 =
@@ -352,13 +352,13 @@ struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len,
352 spin_lock_init(&key->u.tkip.txlock); 352 spin_lock_init(&key->u.tkip.txlock);
353 break; 353 break;
354 case WLAN_CIPHER_SUITE_CCMP: 354 case WLAN_CIPHER_SUITE_CCMP:
355 key->conf.iv_len = CCMP_HDR_LEN; 355 key->conf.iv_len = IEEE80211_CCMP_HDR_LEN;
356 key->conf.icv_len = CCMP_MIC_LEN; 356 key->conf.icv_len = IEEE80211_CCMP_MIC_LEN;
357 if (seq) { 357 if (seq) {
358 for (i = 0; i < IEEE80211_NUM_TIDS + 1; i++) 358 for (i = 0; i < IEEE80211_NUM_TIDS + 1; i++)
359 for (j = 0; j < CCMP_PN_LEN; j++) 359 for (j = 0; j < IEEE80211_CCMP_PN_LEN; j++)
360 key->u.ccmp.rx_pn[i][j] = 360 key->u.ccmp.rx_pn[i][j] =
361 seq[CCMP_PN_LEN - j - 1]; 361 seq[IEEE80211_CCMP_PN_LEN - j - 1];
362 } 362 }
363 /* 363 /*
364 * Initialize AES key state here as an optimization so that 364 * Initialize AES key state here as an optimization so that
@@ -375,9 +375,9 @@ struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len,
375 key->conf.iv_len = 0; 375 key->conf.iv_len = 0;
376 key->conf.icv_len = sizeof(struct ieee80211_mmie); 376 key->conf.icv_len = sizeof(struct ieee80211_mmie);
377 if (seq) 377 if (seq)
378 for (j = 0; j < CMAC_PN_LEN; j++) 378 for (j = 0; j < IEEE80211_CMAC_PN_LEN; j++)
379 key->u.aes_cmac.rx_pn[j] = 379 key->u.aes_cmac.rx_pn[j] =
380 seq[CMAC_PN_LEN - j - 1]; 380 seq[IEEE80211_CMAC_PN_LEN - j - 1];
381 /* 381 /*
382 * Initialize AES key state here as an optimization so that 382 * Initialize AES key state here as an optimization so that
383 * it does not need to be initialized for every packet. 383 * it does not need to be initialized for every packet.
@@ -740,13 +740,13 @@ void ieee80211_get_key_rx_seq(struct ieee80211_key_conf *keyconf,
740 pn = key->u.ccmp.rx_pn[IEEE80211_NUM_TIDS]; 740 pn = key->u.ccmp.rx_pn[IEEE80211_NUM_TIDS];
741 else 741 else
742 pn = key->u.ccmp.rx_pn[tid]; 742 pn = key->u.ccmp.rx_pn[tid];
743 memcpy(seq->ccmp.pn, pn, CCMP_PN_LEN); 743 memcpy(seq->ccmp.pn, pn, IEEE80211_CCMP_PN_LEN);
744 break; 744 break;
745 case WLAN_CIPHER_SUITE_AES_CMAC: 745 case WLAN_CIPHER_SUITE_AES_CMAC:
746 if (WARN_ON(tid != 0)) 746 if (WARN_ON(tid != 0))
747 return; 747 return;
748 pn = key->u.aes_cmac.rx_pn; 748 pn = key->u.aes_cmac.rx_pn;
749 memcpy(seq->aes_cmac.pn, pn, CMAC_PN_LEN); 749 memcpy(seq->aes_cmac.pn, pn, IEEE80211_CMAC_PN_LEN);
750 break; 750 break;
751 } 751 }
752} 752}
diff --git a/net/mac80211/key.h b/net/mac80211/key.h
index e8de3e6d7804..036d57e76a5e 100644
--- a/net/mac80211/key.h
+++ b/net/mac80211/key.h
@@ -19,17 +19,6 @@
19#define NUM_DEFAULT_KEYS 4 19#define NUM_DEFAULT_KEYS 4
20#define NUM_DEFAULT_MGMT_KEYS 2 20#define NUM_DEFAULT_MGMT_KEYS 2
21 21
22#define WEP_IV_LEN 4
23#define WEP_ICV_LEN 4
24#define ALG_CCMP_KEY_LEN 16
25#define CCMP_HDR_LEN 8
26#define CCMP_MIC_LEN 8
27#define CCMP_TK_LEN 16
28#define CCMP_PN_LEN 6
29#define TKIP_IV_LEN 8
30#define TKIP_ICV_LEN 4
31#define CMAC_PN_LEN 6
32
33struct ieee80211_local; 22struct ieee80211_local;
34struct ieee80211_sub_if_data; 23struct ieee80211_sub_if_data;
35struct sta_info; 24struct sta_info;
@@ -93,13 +82,13 @@ struct ieee80211_key {
93 * frames and the last counter is used with Robust 82 * frames and the last counter is used with Robust
94 * Management frames. 83 * Management frames.
95 */ 84 */
96 u8 rx_pn[IEEE80211_NUM_TIDS + 1][CCMP_PN_LEN]; 85 u8 rx_pn[IEEE80211_NUM_TIDS + 1][IEEE80211_CCMP_PN_LEN];
97 struct crypto_cipher *tfm; 86 struct crypto_cipher *tfm;
98 u32 replays; /* dot11RSNAStatsCCMPReplays */ 87 u32 replays; /* dot11RSNAStatsCCMPReplays */
99 } ccmp; 88 } ccmp;
100 struct { 89 struct {
101 atomic64_t tx_pn; 90 atomic64_t tx_pn;
102 u8 rx_pn[CMAC_PN_LEN]; 91 u8 rx_pn[IEEE80211_CMAC_PN_LEN];
103 struct crypto_cipher *tfm; 92 struct crypto_cipher *tfm;
104 u32 replays; /* dot11RSNAStatsCMACReplays */ 93 u32 replays; /* dot11RSNAStatsCMACReplays */
105 u32 icverrors; /* dot11RSNAStatsCMACICVErrors */ 94 u32 icverrors; /* dot11RSNAStatsCMACICVErrors */
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 8a7bfc47d577..1998f1475267 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -331,7 +331,7 @@ static int ieee80211_ifa_changed(struct notifier_block *nb,
331 return NOTIFY_DONE; 331 return NOTIFY_DONE;
332 332
333 ifmgd = &sdata->u.mgd; 333 ifmgd = &sdata->u.mgd;
334 mutex_lock(&ifmgd->mtx); 334 sdata_lock(sdata);
335 335
336 /* Copy the addresses to the bss_conf list */ 336 /* Copy the addresses to the bss_conf list */
337 ifa = idev->ifa_list; 337 ifa = idev->ifa_list;
@@ -349,7 +349,7 @@ static int ieee80211_ifa_changed(struct notifier_block *nb,
349 ieee80211_bss_info_change_notify(sdata, 349 ieee80211_bss_info_change_notify(sdata,
350 BSS_CHANGED_ARP_FILTER); 350 BSS_CHANGED_ARP_FILTER);
351 351
352 mutex_unlock(&ifmgd->mtx); 352 sdata_unlock(sdata);
353 353
354 return NOTIFY_DONE; 354 return NOTIFY_DONE;
355} 355}
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 6952760881c8..b3d1fdd46368 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -161,8 +161,11 @@ void mesh_sta_cleanup(struct sta_info *sta)
161 del_timer_sync(&sta->plink_timer); 161 del_timer_sync(&sta->plink_timer);
162 } 162 }
163 163
164 if (changed) 164 if (changed) {
165 sdata_lock(sdata);
165 ieee80211_mbss_info_change_notify(sdata, changed); 166 ieee80211_mbss_info_change_notify(sdata, changed);
167 sdata_unlock(sdata);
168 }
166} 169}
167 170
168int mesh_rmc_init(struct ieee80211_sub_if_data *sdata) 171int mesh_rmc_init(struct ieee80211_sub_if_data *sdata)
@@ -577,7 +580,9 @@ static void ieee80211_mesh_housekeeping(struct ieee80211_sub_if_data *sdata)
577 mesh_path_expire(sdata); 580 mesh_path_expire(sdata);
578 581
579 changed = mesh_accept_plinks_update(sdata); 582 changed = mesh_accept_plinks_update(sdata);
583 sdata_lock(sdata);
580 ieee80211_mbss_info_change_notify(sdata, changed); 584 ieee80211_mbss_info_change_notify(sdata, changed);
585 sdata_unlock(sdata);
581 586
582 mod_timer(&ifmsh->housekeeping_timer, 587 mod_timer(&ifmsh->housekeeping_timer,
583 round_jiffies(jiffies + 588 round_jiffies(jiffies +
@@ -697,25 +702,21 @@ out_free:
697} 702}
698 703
699static int 704static int
700ieee80211_mesh_rebuild_beacon(struct ieee80211_if_mesh *ifmsh) 705ieee80211_mesh_rebuild_beacon(struct ieee80211_sub_if_data *sdata)
701{ 706{
702 struct beacon_data *old_bcn; 707 struct beacon_data *old_bcn;
703 int ret; 708 int ret;
704 709
705 mutex_lock(&ifmsh->mtx); 710 old_bcn = rcu_dereference_protected(sdata->u.mesh.beacon,
706 711 lockdep_is_held(&sdata->wdev.mtx));
707 old_bcn = rcu_dereference_protected(ifmsh->beacon, 712 ret = ieee80211_mesh_build_beacon(&sdata->u.mesh);
708 lockdep_is_held(&ifmsh->mtx));
709 ret = ieee80211_mesh_build_beacon(ifmsh);
710 if (ret) 713 if (ret)
711 /* just reuse old beacon */ 714 /* just reuse old beacon */
712 goto out; 715 return ret;
713 716
714 if (old_bcn) 717 if (old_bcn)
715 kfree_rcu(old_bcn, rcu_head); 718 kfree_rcu(old_bcn, rcu_head);
716out: 719 return 0;
717 mutex_unlock(&ifmsh->mtx);
718 return ret;
719} 720}
720 721
721void ieee80211_mbss_info_change_notify(struct ieee80211_sub_if_data *sdata, 722void ieee80211_mbss_info_change_notify(struct ieee80211_sub_if_data *sdata,
@@ -726,7 +727,7 @@ void ieee80211_mbss_info_change_notify(struct ieee80211_sub_if_data *sdata,
726 BSS_CHANGED_HT | 727 BSS_CHANGED_HT |
727 BSS_CHANGED_BASIC_RATES | 728 BSS_CHANGED_BASIC_RATES |
728 BSS_CHANGED_BEACON_INT))) 729 BSS_CHANGED_BEACON_INT)))
729 if (ieee80211_mesh_rebuild_beacon(&sdata->u.mesh)) 730 if (ieee80211_mesh_rebuild_beacon(sdata))
730 return; 731 return;
731 ieee80211_bss_info_change_notify(sdata, changed); 732 ieee80211_bss_info_change_notify(sdata, changed);
732} 733}
@@ -741,6 +742,8 @@ int ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)
741 BSS_CHANGED_BASIC_RATES | 742 BSS_CHANGED_BASIC_RATES |
742 BSS_CHANGED_BEACON_INT; 743 BSS_CHANGED_BEACON_INT;
743 enum ieee80211_band band = ieee80211_get_sdata_band(sdata); 744 enum ieee80211_band band = ieee80211_get_sdata_band(sdata);
745 struct ieee80211_supported_band *sband =
746 sdata->local->hw.wiphy->bands[band];
744 747
745 local->fif_other_bss++; 748 local->fif_other_bss++;
746 /* mesh ifaces must set allmulti to forward mcast traffic */ 749 /* mesh ifaces must set allmulti to forward mcast traffic */
@@ -748,7 +751,6 @@ int ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)
748 ieee80211_configure_filter(local); 751 ieee80211_configure_filter(local);
749 752
750 ifmsh->mesh_cc_id = 0; /* Disabled */ 753 ifmsh->mesh_cc_id = 0; /* Disabled */
751 ifmsh->mesh_auth_id = 0; /* Disabled */
752 /* register sync ops from extensible synchronization framework */ 754 /* register sync ops from extensible synchronization framework */
753 ifmsh->sync_ops = ieee80211_mesh_sync_ops_get(ifmsh->mesh_sp_id); 755 ifmsh->sync_ops = ieee80211_mesh_sync_ops_get(ifmsh->mesh_sp_id);
754 ifmsh->adjusting_tbtt = false; 756 ifmsh->adjusting_tbtt = false;
@@ -759,8 +761,7 @@ int ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)
759 sdata->vif.bss_conf.ht_operation_mode = 761 sdata->vif.bss_conf.ht_operation_mode =
760 ifmsh->mshcfg.ht_opmode; 762 ifmsh->mshcfg.ht_opmode;
761 sdata->vif.bss_conf.enable_beacon = true; 763 sdata->vif.bss_conf.enable_beacon = true;
762 sdata->vif.bss_conf.basic_rates = 764 sdata->vif.bss_conf.basic_rates = ieee80211_mandatory_rates(sband);
763 ieee80211_mandatory_rates(local, band);
764 765
765 changed |= ieee80211_mps_local_status_update(sdata); 766 changed |= ieee80211_mps_local_status_update(sdata);
766 767
@@ -788,12 +789,12 @@ void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata)
788 sdata->vif.bss_conf.enable_beacon = false; 789 sdata->vif.bss_conf.enable_beacon = false;
789 clear_bit(SDATA_STATE_OFFCHANNEL_BEACON_STOPPED, &sdata->state); 790 clear_bit(SDATA_STATE_OFFCHANNEL_BEACON_STOPPED, &sdata->state);
790 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED); 791 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED);
791 mutex_lock(&ifmsh->mtx); 792 sdata_lock(sdata);
792 bcn = rcu_dereference_protected(ifmsh->beacon, 793 bcn = rcu_dereference_protected(ifmsh->beacon,
793 lockdep_is_held(&ifmsh->mtx)); 794 lockdep_is_held(&sdata->wdev.mtx));
794 rcu_assign_pointer(ifmsh->beacon, NULL); 795 rcu_assign_pointer(ifmsh->beacon, NULL);
795 kfree_rcu(bcn, rcu_head); 796 kfree_rcu(bcn, rcu_head);
796 mutex_unlock(&ifmsh->mtx); 797 sdata_unlock(sdata);
797 798
798 /* flush STAs and mpaths on this iface */ 799 /* flush STAs and mpaths on this iface */
799 sta_info_flush(sdata); 800 sta_info_flush(sdata);
@@ -1041,7 +1042,6 @@ void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata)
1041 spin_lock_init(&ifmsh->mesh_preq_queue_lock); 1042 spin_lock_init(&ifmsh->mesh_preq_queue_lock);
1042 spin_lock_init(&ifmsh->sync_offset_lock); 1043 spin_lock_init(&ifmsh->sync_offset_lock);
1043 RCU_INIT_POINTER(ifmsh->beacon, NULL); 1044 RCU_INIT_POINTER(ifmsh->beacon, NULL);
1044 mutex_init(&ifmsh->mtx);
1045 1045
1046 sdata->vif.bss_conf.bssid = zero_addr; 1046 sdata->vif.bss_conf.bssid = zero_addr;
1047} 1047}
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index 09bebed99416..6c4da99bc4fb 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -517,7 +517,9 @@ void mesh_neighbour_update(struct ieee80211_sub_if_data *sdata,
517 ieee80211_mps_frame_release(sta, elems); 517 ieee80211_mps_frame_release(sta, elems);
518out: 518out:
519 rcu_read_unlock(); 519 rcu_read_unlock();
520 sdata_lock(sdata);
520 ieee80211_mbss_info_change_notify(sdata, changed); 521 ieee80211_mbss_info_change_notify(sdata, changed);
522 sdata_unlock(sdata);
521} 523}
522 524
523static void mesh_plink_timer(unsigned long data) 525static void mesh_plink_timer(unsigned long data)
@@ -1068,6 +1070,9 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
1068 1070
1069 rcu_read_unlock(); 1071 rcu_read_unlock();
1070 1072
1071 if (changed) 1073 if (changed) {
1074 sdata_lock(sdata);
1072 ieee80211_mbss_info_change_notify(sdata, changed); 1075 ieee80211_mbss_info_change_notify(sdata, changed);
1076 sdata_unlock(sdata);
1077 }
1073} 1078}
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index a8c2130c8ba4..f44f4caa69ee 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -91,41 +91,6 @@ MODULE_PARM_DESC(probe_wait_ms,
91#define IEEE80211_SIGNAL_AVE_MIN_COUNT 4 91#define IEEE80211_SIGNAL_AVE_MIN_COUNT 4
92 92
93/* 93/*
94 * All cfg80211 functions have to be called outside a locked
95 * section so that they can acquire a lock themselves... This
96 * is much simpler than queuing up things in cfg80211, but we
97 * do need some indirection for that here.
98 */
99enum rx_mgmt_action {
100 /* no action required */
101 RX_MGMT_NONE,
102
103 /* caller must call cfg80211_send_deauth() */
104 RX_MGMT_CFG80211_DEAUTH,
105
106 /* caller must call cfg80211_send_disassoc() */
107 RX_MGMT_CFG80211_DISASSOC,
108
109 /* caller must call cfg80211_send_rx_auth() */
110 RX_MGMT_CFG80211_RX_AUTH,
111
112 /* caller must call cfg80211_send_rx_assoc() */
113 RX_MGMT_CFG80211_RX_ASSOC,
114
115 /* caller must call cfg80211_send_assoc_timeout() */
116 RX_MGMT_CFG80211_ASSOC_TIMEOUT,
117
118 /* used when a processed beacon causes a deauth */
119 RX_MGMT_CFG80211_TX_DEAUTH,
120};
121
122/* utils */
123static inline void ASSERT_MGD_MTX(struct ieee80211_if_managed *ifmgd)
124{
125 lockdep_assert_held(&ifmgd->mtx);
126}
127
128/*
129 * We can have multiple work items (and connection probing) 94 * We can have multiple work items (and connection probing)
130 * scheduling this timer, but we need to take care to only 95 * scheduling this timer, but we need to take care to only
131 * reschedule it when it should fire _earlier_ than it was 96 * reschedule it when it should fire _earlier_ than it was
@@ -135,13 +100,14 @@ static inline void ASSERT_MGD_MTX(struct ieee80211_if_managed *ifmgd)
135 * has happened -- the work that runs from this timer will 100 * has happened -- the work that runs from this timer will
136 * do that. 101 * do that.
137 */ 102 */
138static void run_again(struct ieee80211_if_managed *ifmgd, unsigned long timeout) 103static void run_again(struct ieee80211_sub_if_data *sdata,
104 unsigned long timeout)
139{ 105{
140 ASSERT_MGD_MTX(ifmgd); 106 sdata_assert_lock(sdata);
141 107
142 if (!timer_pending(&ifmgd->timer) || 108 if (!timer_pending(&sdata->u.mgd.timer) ||
143 time_before(timeout, ifmgd->timer.expires)) 109 time_before(timeout, sdata->u.mgd.timer.expires))
144 mod_timer(&ifmgd->timer, timeout); 110 mod_timer(&sdata->u.mgd.timer, timeout);
145} 111}
146 112
147void ieee80211_sta_reset_beacon_monitor(struct ieee80211_sub_if_data *sdata) 113void ieee80211_sta_reset_beacon_monitor(struct ieee80211_sub_if_data *sdata)
@@ -652,7 +618,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
652 struct ieee80211_channel *chan; 618 struct ieee80211_channel *chan;
653 u32 rates = 0; 619 u32 rates = 0;
654 620
655 lockdep_assert_held(&ifmgd->mtx); 621 sdata_assert_lock(sdata);
656 622
657 rcu_read_lock(); 623 rcu_read_lock();
658 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); 624 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
@@ -962,7 +928,7 @@ static void ieee80211_chswitch_work(struct work_struct *work)
962 if (!ieee80211_sdata_running(sdata)) 928 if (!ieee80211_sdata_running(sdata))
963 return; 929 return;
964 930
965 mutex_lock(&ifmgd->mtx); 931 sdata_lock(sdata);
966 if (!ifmgd->associated) 932 if (!ifmgd->associated)
967 goto out; 933 goto out;
968 934
@@ -985,7 +951,7 @@ static void ieee80211_chswitch_work(struct work_struct *work)
985 IEEE80211_QUEUE_STOP_REASON_CSA); 951 IEEE80211_QUEUE_STOP_REASON_CSA);
986 out: 952 out:
987 ifmgd->flags &= ~IEEE80211_STA_CSA_RECEIVED; 953 ifmgd->flags &= ~IEEE80211_STA_CSA_RECEIVED;
988 mutex_unlock(&ifmgd->mtx); 954 sdata_unlock(sdata);
989} 955}
990 956
991void ieee80211_chswitch_done(struct ieee80211_vif *vif, bool success) 957void ieee80211_chswitch_done(struct ieee80211_vif *vif, bool success)
@@ -1036,7 +1002,7 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
1036 const struct ieee80211_ht_operation *ht_oper; 1002 const struct ieee80211_ht_operation *ht_oper;
1037 int secondary_channel_offset = -1; 1003 int secondary_channel_offset = -1;
1038 1004
1039 ASSERT_MGD_MTX(ifmgd); 1005 sdata_assert_lock(sdata);
1040 1006
1041 if (!cbss) 1007 if (!cbss)
1042 return; 1008 return;
@@ -1390,6 +1356,9 @@ static bool ieee80211_powersave_allowed(struct ieee80211_sub_if_data *sdata)
1390 IEEE80211_STA_CONNECTION_POLL)) 1356 IEEE80211_STA_CONNECTION_POLL))
1391 return false; 1357 return false;
1392 1358
1359 if (!sdata->vif.bss_conf.dtim_period)
1360 return false;
1361
1393 rcu_read_lock(); 1362 rcu_read_lock();
1394 sta = sta_info_get(sdata, mgd->bssid); 1363 sta = sta_info_get(sdata, mgd->bssid);
1395 if (sta) 1364 if (sta)
@@ -1842,7 +1811,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
1842 struct ieee80211_local *local = sdata->local; 1811 struct ieee80211_local *local = sdata->local;
1843 u32 changed = 0; 1812 u32 changed = 0;
1844 1813
1845 ASSERT_MGD_MTX(ifmgd); 1814 sdata_assert_lock(sdata);
1846 1815
1847 if (WARN_ON_ONCE(tx && !frame_buf)) 1816 if (WARN_ON_ONCE(tx && !frame_buf))
1848 return; 1817 return;
@@ -2051,7 +2020,7 @@ static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata)
2051 } 2020 }
2052 2021
2053 ifmgd->probe_timeout = jiffies + msecs_to_jiffies(probe_wait_ms); 2022 ifmgd->probe_timeout = jiffies + msecs_to_jiffies(probe_wait_ms);
2054 run_again(ifmgd, ifmgd->probe_timeout); 2023 run_again(sdata, ifmgd->probe_timeout);
2055 if (sdata->local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) 2024 if (sdata->local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)
2056 ieee80211_flush_queues(sdata->local, sdata); 2025 ieee80211_flush_queues(sdata->local, sdata);
2057} 2026}
@@ -2065,7 +2034,7 @@ static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata,
2065 if (!ieee80211_sdata_running(sdata)) 2034 if (!ieee80211_sdata_running(sdata))
2066 return; 2035 return;
2067 2036
2068 mutex_lock(&ifmgd->mtx); 2037 sdata_lock(sdata);
2069 2038
2070 if (!ifmgd->associated) 2039 if (!ifmgd->associated)
2071 goto out; 2040 goto out;
@@ -2119,7 +2088,7 @@ static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata,
2119 ifmgd->probe_send_count = 0; 2088 ifmgd->probe_send_count = 0;
2120 ieee80211_mgd_probe_ap_send(sdata); 2089 ieee80211_mgd_probe_ap_send(sdata);
2121 out: 2090 out:
2122 mutex_unlock(&ifmgd->mtx); 2091 sdata_unlock(sdata);
2123} 2092}
2124 2093
2125struct sk_buff *ieee80211_ap_probereq_get(struct ieee80211_hw *hw, 2094struct sk_buff *ieee80211_ap_probereq_get(struct ieee80211_hw *hw,
@@ -2135,7 +2104,7 @@ struct sk_buff *ieee80211_ap_probereq_get(struct ieee80211_hw *hw,
2135 if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION)) 2104 if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION))
2136 return NULL; 2105 return NULL;
2137 2106
2138 ASSERT_MGD_MTX(ifmgd); 2107 sdata_assert_lock(sdata);
2139 2108
2140 if (ifmgd->associated) 2109 if (ifmgd->associated)
2141 cbss = ifmgd->associated; 2110 cbss = ifmgd->associated;
@@ -2168,9 +2137,9 @@ static void __ieee80211_disconnect(struct ieee80211_sub_if_data *sdata)
2168 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 2137 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
2169 u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN]; 2138 u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN];
2170 2139
2171 mutex_lock(&ifmgd->mtx); 2140 sdata_lock(sdata);
2172 if (!ifmgd->associated) { 2141 if (!ifmgd->associated) {
2173 mutex_unlock(&ifmgd->mtx); 2142 sdata_unlock(sdata);
2174 return; 2143 return;
2175 } 2144 }
2176 2145
@@ -2181,13 +2150,9 @@ static void __ieee80211_disconnect(struct ieee80211_sub_if_data *sdata)
2181 ieee80211_wake_queues_by_reason(&sdata->local->hw, 2150 ieee80211_wake_queues_by_reason(&sdata->local->hw,
2182 IEEE80211_MAX_QUEUE_MAP, 2151 IEEE80211_MAX_QUEUE_MAP,
2183 IEEE80211_QUEUE_STOP_REASON_CSA); 2152 IEEE80211_QUEUE_STOP_REASON_CSA);
2184 mutex_unlock(&ifmgd->mtx);
2185 2153
2186 /*
2187 * must be outside lock due to cfg80211,
2188 * but that's not a problem.
2189 */
2190 cfg80211_send_deauth(sdata->dev, frame_buf, IEEE80211_DEAUTH_FRAME_LEN); 2154 cfg80211_send_deauth(sdata->dev, frame_buf, IEEE80211_DEAUTH_FRAME_LEN);
2155 sdata_unlock(sdata);
2191} 2156}
2192 2157
2193static void ieee80211_beacon_connection_loss_work(struct work_struct *work) 2158static void ieee80211_beacon_connection_loss_work(struct work_struct *work)
@@ -2254,7 +2219,7 @@ static void ieee80211_destroy_auth_data(struct ieee80211_sub_if_data *sdata,
2254{ 2219{
2255 struct ieee80211_mgd_auth_data *auth_data = sdata->u.mgd.auth_data; 2220 struct ieee80211_mgd_auth_data *auth_data = sdata->u.mgd.auth_data;
2256 2221
2257 lockdep_assert_held(&sdata->u.mgd.mtx); 2222 sdata_assert_lock(sdata);
2258 2223
2259 if (!assoc) { 2224 if (!assoc) {
2260 sta_info_destroy_addr(sdata, auth_data->bss->bssid); 2225 sta_info_destroy_addr(sdata, auth_data->bss->bssid);
@@ -2295,27 +2260,26 @@ static void ieee80211_auth_challenge(struct ieee80211_sub_if_data *sdata,
2295 auth_data->key_idx, tx_flags); 2260 auth_data->key_idx, tx_flags);
2296} 2261}
2297 2262
2298static enum rx_mgmt_action __must_check 2263static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
2299ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata, 2264 struct ieee80211_mgmt *mgmt, size_t len)
2300 struct ieee80211_mgmt *mgmt, size_t len)
2301{ 2265{
2302 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 2266 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
2303 u8 bssid[ETH_ALEN]; 2267 u8 bssid[ETH_ALEN];
2304 u16 auth_alg, auth_transaction, status_code; 2268 u16 auth_alg, auth_transaction, status_code;
2305 struct sta_info *sta; 2269 struct sta_info *sta;
2306 2270
2307 lockdep_assert_held(&ifmgd->mtx); 2271 sdata_assert_lock(sdata);
2308 2272
2309 if (len < 24 + 6) 2273 if (len < 24 + 6)
2310 return RX_MGMT_NONE; 2274 return;
2311 2275
2312 if (!ifmgd->auth_data || ifmgd->auth_data->done) 2276 if (!ifmgd->auth_data || ifmgd->auth_data->done)
2313 return RX_MGMT_NONE; 2277 return;
2314 2278
2315 memcpy(bssid, ifmgd->auth_data->bss->bssid, ETH_ALEN); 2279 memcpy(bssid, ifmgd->auth_data->bss->bssid, ETH_ALEN);
2316 2280
2317 if (!ether_addr_equal(bssid, mgmt->bssid)) 2281 if (!ether_addr_equal(bssid, mgmt->bssid))
2318 return RX_MGMT_NONE; 2282 return;
2319 2283
2320 auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg); 2284 auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg);
2321 auth_transaction = le16_to_cpu(mgmt->u.auth.auth_transaction); 2285 auth_transaction = le16_to_cpu(mgmt->u.auth.auth_transaction);
@@ -2327,14 +2291,15 @@ ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
2327 mgmt->sa, auth_alg, ifmgd->auth_data->algorithm, 2291 mgmt->sa, auth_alg, ifmgd->auth_data->algorithm,
2328 auth_transaction, 2292 auth_transaction,
2329 ifmgd->auth_data->expected_transaction); 2293 ifmgd->auth_data->expected_transaction);
2330 return RX_MGMT_NONE; 2294 return;
2331 } 2295 }
2332 2296
2333 if (status_code != WLAN_STATUS_SUCCESS) { 2297 if (status_code != WLAN_STATUS_SUCCESS) {
2334 sdata_info(sdata, "%pM denied authentication (status %d)\n", 2298 sdata_info(sdata, "%pM denied authentication (status %d)\n",
2335 mgmt->sa, status_code); 2299 mgmt->sa, status_code);
2336 ieee80211_destroy_auth_data(sdata, false); 2300 ieee80211_destroy_auth_data(sdata, false);
2337 return RX_MGMT_CFG80211_RX_AUTH; 2301 cfg80211_send_rx_auth(sdata->dev, (u8 *)mgmt, len);
2302 return;
2338 } 2303 }
2339 2304
2340 switch (ifmgd->auth_data->algorithm) { 2305 switch (ifmgd->auth_data->algorithm) {
@@ -2347,20 +2312,20 @@ ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
2347 if (ifmgd->auth_data->expected_transaction != 4) { 2312 if (ifmgd->auth_data->expected_transaction != 4) {
2348 ieee80211_auth_challenge(sdata, mgmt, len); 2313 ieee80211_auth_challenge(sdata, mgmt, len);
2349 /* need another frame */ 2314 /* need another frame */
2350 return RX_MGMT_NONE; 2315 return;
2351 } 2316 }
2352 break; 2317 break;
2353 default: 2318 default:
2354 WARN_ONCE(1, "invalid auth alg %d", 2319 WARN_ONCE(1, "invalid auth alg %d",
2355 ifmgd->auth_data->algorithm); 2320 ifmgd->auth_data->algorithm);
2356 return RX_MGMT_NONE; 2321 return;
2357 } 2322 }
2358 2323
2359 sdata_info(sdata, "authenticated\n"); 2324 sdata_info(sdata, "authenticated\n");
2360 ifmgd->auth_data->done = true; 2325 ifmgd->auth_data->done = true;
2361 ifmgd->auth_data->timeout = jiffies + IEEE80211_AUTH_WAIT_ASSOC; 2326 ifmgd->auth_data->timeout = jiffies + IEEE80211_AUTH_WAIT_ASSOC;
2362 ifmgd->auth_data->timeout_started = true; 2327 ifmgd->auth_data->timeout_started = true;
2363 run_again(ifmgd, ifmgd->auth_data->timeout); 2328 run_again(sdata, ifmgd->auth_data->timeout);
2364 2329
2365 if (ifmgd->auth_data->algorithm == WLAN_AUTH_SAE && 2330 if (ifmgd->auth_data->algorithm == WLAN_AUTH_SAE &&
2366 ifmgd->auth_data->expected_transaction != 2) { 2331 ifmgd->auth_data->expected_transaction != 2) {
@@ -2368,7 +2333,8 @@ ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
2368 * Report auth frame to user space for processing since another 2333 * Report auth frame to user space for processing since another
2369 * round of Authentication frames is still needed. 2334 * round of Authentication frames is still needed.
2370 */ 2335 */
2371 return RX_MGMT_CFG80211_RX_AUTH; 2336 cfg80211_send_rx_auth(sdata->dev, (u8 *)mgmt, len);
2337 return;
2372 } 2338 }
2373 2339
2374 /* move station state to auth */ 2340 /* move station state to auth */
@@ -2384,30 +2350,29 @@ ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
2384 } 2350 }
2385 mutex_unlock(&sdata->local->sta_mtx); 2351 mutex_unlock(&sdata->local->sta_mtx);
2386 2352
2387 return RX_MGMT_CFG80211_RX_AUTH; 2353 cfg80211_send_rx_auth(sdata->dev, (u8 *)mgmt, len);
2354 return;
2388 out_err: 2355 out_err:
2389 mutex_unlock(&sdata->local->sta_mtx); 2356 mutex_unlock(&sdata->local->sta_mtx);
2390 /* ignore frame -- wait for timeout */ 2357 /* ignore frame -- wait for timeout */
2391 return RX_MGMT_NONE;
2392} 2358}
2393 2359
2394 2360
2395static enum rx_mgmt_action __must_check 2361static void ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
2396ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata, 2362 struct ieee80211_mgmt *mgmt, size_t len)
2397 struct ieee80211_mgmt *mgmt, size_t len)
2398{ 2363{
2399 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 2364 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
2400 const u8 *bssid = NULL; 2365 const u8 *bssid = NULL;
2401 u16 reason_code; 2366 u16 reason_code;
2402 2367
2403 lockdep_assert_held(&ifmgd->mtx); 2368 sdata_assert_lock(sdata);
2404 2369
2405 if (len < 24 + 2) 2370 if (len < 24 + 2)
2406 return RX_MGMT_NONE; 2371 return;
2407 2372
2408 if (!ifmgd->associated || 2373 if (!ifmgd->associated ||
2409 !ether_addr_equal(mgmt->bssid, ifmgd->associated->bssid)) 2374 !ether_addr_equal(mgmt->bssid, ifmgd->associated->bssid))
2410 return RX_MGMT_NONE; 2375 return;
2411 2376
2412 bssid = ifmgd->associated->bssid; 2377 bssid = ifmgd->associated->bssid;
2413 2378
@@ -2418,25 +2383,24 @@ ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
2418 2383
2419 ieee80211_set_disassoc(sdata, 0, 0, false, NULL); 2384 ieee80211_set_disassoc(sdata, 0, 0, false, NULL);
2420 2385
2421 return RX_MGMT_CFG80211_DEAUTH; 2386 cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, len);
2422} 2387}
2423 2388
2424 2389
2425static enum rx_mgmt_action __must_check 2390static void ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata,
2426ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata, 2391 struct ieee80211_mgmt *mgmt, size_t len)
2427 struct ieee80211_mgmt *mgmt, size_t len)
2428{ 2392{
2429 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 2393 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
2430 u16 reason_code; 2394 u16 reason_code;
2431 2395
2432 lockdep_assert_held(&ifmgd->mtx); 2396 sdata_assert_lock(sdata);
2433 2397
2434 if (len < 24 + 2) 2398 if (len < 24 + 2)
2435 return RX_MGMT_NONE; 2399 return;
2436 2400
2437 if (!ifmgd->associated || 2401 if (!ifmgd->associated ||
2438 !ether_addr_equal(mgmt->bssid, ifmgd->associated->bssid)) 2402 !ether_addr_equal(mgmt->bssid, ifmgd->associated->bssid))
2439 return RX_MGMT_NONE; 2403 return;
2440 2404
2441 reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code); 2405 reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code);
2442 2406
@@ -2445,7 +2409,7 @@ ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata,
2445 2409
2446 ieee80211_set_disassoc(sdata, 0, 0, false, NULL); 2410 ieee80211_set_disassoc(sdata, 0, 0, false, NULL);
2447 2411
2448 return RX_MGMT_CFG80211_DISASSOC; 2412 cfg80211_send_disassoc(sdata->dev, (u8 *)mgmt, len);
2449} 2413}
2450 2414
2451static void ieee80211_get_rates(struct ieee80211_supported_band *sband, 2415static void ieee80211_get_rates(struct ieee80211_supported_band *sband,
@@ -2495,7 +2459,7 @@ static void ieee80211_destroy_assoc_data(struct ieee80211_sub_if_data *sdata,
2495{ 2459{
2496 struct ieee80211_mgd_assoc_data *assoc_data = sdata->u.mgd.assoc_data; 2460 struct ieee80211_mgd_assoc_data *assoc_data = sdata->u.mgd.assoc_data;
2497 2461
2498 lockdep_assert_held(&sdata->u.mgd.mtx); 2462 sdata_assert_lock(sdata);
2499 2463
2500 if (!assoc) { 2464 if (!assoc) {
2501 sta_info_destroy_addr(sdata, assoc_data->bss->bssid); 2465 sta_info_destroy_addr(sdata, assoc_data->bss->bssid);
@@ -2676,10 +2640,9 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
2676 return true; 2640 return true;
2677} 2641}
2678 2642
2679static enum rx_mgmt_action __must_check 2643static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
2680ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, 2644 struct ieee80211_mgmt *mgmt,
2681 struct ieee80211_mgmt *mgmt, size_t len, 2645 size_t len)
2682 struct cfg80211_bss **bss)
2683{ 2646{
2684 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 2647 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
2685 struct ieee80211_mgd_assoc_data *assoc_data = ifmgd->assoc_data; 2648 struct ieee80211_mgd_assoc_data *assoc_data = ifmgd->assoc_data;
@@ -2687,13 +2650,14 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
2687 struct ieee802_11_elems elems; 2650 struct ieee802_11_elems elems;
2688 u8 *pos; 2651 u8 *pos;
2689 bool reassoc; 2652 bool reassoc;
2653 struct cfg80211_bss *bss;
2690 2654
2691 lockdep_assert_held(&ifmgd->mtx); 2655 sdata_assert_lock(sdata);
2692 2656
2693 if (!assoc_data) 2657 if (!assoc_data)
2694 return RX_MGMT_NONE; 2658 return;
2695 if (!ether_addr_equal(assoc_data->bss->bssid, mgmt->bssid)) 2659 if (!ether_addr_equal(assoc_data->bss->bssid, mgmt->bssid))
2696 return RX_MGMT_NONE; 2660 return;
2697 2661
2698 /* 2662 /*
2699 * AssocResp and ReassocResp have identical structure, so process both 2663 * AssocResp and ReassocResp have identical structure, so process both
@@ -2701,7 +2665,7 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
2701 */ 2665 */
2702 2666
2703 if (len < 24 + 6) 2667 if (len < 24 + 6)
2704 return RX_MGMT_NONE; 2668 return;
2705 2669
2706 reassoc = ieee80211_is_reassoc_req(mgmt->frame_control); 2670 reassoc = ieee80211_is_reassoc_req(mgmt->frame_control);
2707 capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info); 2671 capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info);
@@ -2728,22 +2692,23 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
2728 assoc_data->timeout = jiffies + msecs_to_jiffies(ms); 2692 assoc_data->timeout = jiffies + msecs_to_jiffies(ms);
2729 assoc_data->timeout_started = true; 2693 assoc_data->timeout_started = true;
2730 if (ms > IEEE80211_ASSOC_TIMEOUT) 2694 if (ms > IEEE80211_ASSOC_TIMEOUT)
2731 run_again(ifmgd, assoc_data->timeout); 2695 run_again(sdata, assoc_data->timeout);
2732 return RX_MGMT_NONE; 2696 return;
2733 } 2697 }
2734 2698
2735 *bss = assoc_data->bss; 2699 bss = assoc_data->bss;
2736 2700
2737 if (status_code != WLAN_STATUS_SUCCESS) { 2701 if (status_code != WLAN_STATUS_SUCCESS) {
2738 sdata_info(sdata, "%pM denied association (code=%d)\n", 2702 sdata_info(sdata, "%pM denied association (code=%d)\n",
2739 mgmt->sa, status_code); 2703 mgmt->sa, status_code);
2740 ieee80211_destroy_assoc_data(sdata, false); 2704 ieee80211_destroy_assoc_data(sdata, false);
2741 } else { 2705 } else {
2742 if (!ieee80211_assoc_success(sdata, *bss, mgmt, len)) { 2706 if (!ieee80211_assoc_success(sdata, bss, mgmt, len)) {
2743 /* oops -- internal error -- send timeout for now */ 2707 /* oops -- internal error -- send timeout for now */
2744 ieee80211_destroy_assoc_data(sdata, false); 2708 ieee80211_destroy_assoc_data(sdata, false);
2745 cfg80211_put_bss(sdata->local->hw.wiphy, *bss); 2709 cfg80211_put_bss(sdata->local->hw.wiphy, bss);
2746 return RX_MGMT_CFG80211_ASSOC_TIMEOUT; 2710 cfg80211_send_assoc_timeout(sdata->dev, mgmt->bssid);
2711 return;
2747 } 2712 }
2748 sdata_info(sdata, "associated\n"); 2713 sdata_info(sdata, "associated\n");
2749 2714
@@ -2755,7 +2720,7 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
2755 ieee80211_destroy_assoc_data(sdata, true); 2720 ieee80211_destroy_assoc_data(sdata, true);
2756 } 2721 }
2757 2722
2758 return RX_MGMT_CFG80211_RX_ASSOC; 2723 cfg80211_send_rx_assoc(sdata->dev, bss, (u8 *)mgmt, len);
2759} 2724}
2760 2725
2761static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, 2726static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
@@ -2769,7 +2734,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
2769 struct ieee80211_channel *channel; 2734 struct ieee80211_channel *channel;
2770 bool need_ps = false; 2735 bool need_ps = false;
2771 2736
2772 lockdep_assert_held(&sdata->u.mgd.mtx); 2737 sdata_assert_lock(sdata);
2773 2738
2774 if ((sdata->u.mgd.associated && 2739 if ((sdata->u.mgd.associated &&
2775 ether_addr_equal(mgmt->bssid, sdata->u.mgd.associated->bssid)) || 2740 ether_addr_equal(mgmt->bssid, sdata->u.mgd.associated->bssid)) ||
@@ -2828,7 +2793,7 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata,
2828 2793
2829 ifmgd = &sdata->u.mgd; 2794 ifmgd = &sdata->u.mgd;
2830 2795
2831 ASSERT_MGD_MTX(ifmgd); 2796 sdata_assert_lock(sdata);
2832 2797
2833 if (!ether_addr_equal(mgmt->da, sdata->vif.addr)) 2798 if (!ether_addr_equal(mgmt->da, sdata->vif.addr))
2834 return; /* ignore ProbeResp to foreign address */ 2799 return; /* ignore ProbeResp to foreign address */
@@ -2853,7 +2818,7 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata,
2853 ifmgd->auth_data->tries = 0; 2818 ifmgd->auth_data->tries = 0;
2854 ifmgd->auth_data->timeout = jiffies; 2819 ifmgd->auth_data->timeout = jiffies;
2855 ifmgd->auth_data->timeout_started = true; 2820 ifmgd->auth_data->timeout_started = true;
2856 run_again(ifmgd, ifmgd->auth_data->timeout); 2821 run_again(sdata, ifmgd->auth_data->timeout);
2857 } 2822 }
2858} 2823}
2859 2824
@@ -2878,10 +2843,9 @@ static const u64 care_about_ies =
2878 (1ULL << WLAN_EID_HT_CAPABILITY) | 2843 (1ULL << WLAN_EID_HT_CAPABILITY) |
2879 (1ULL << WLAN_EID_HT_OPERATION); 2844 (1ULL << WLAN_EID_HT_OPERATION);
2880 2845
2881static enum rx_mgmt_action 2846static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
2882ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, 2847 struct ieee80211_mgmt *mgmt, size_t len,
2883 struct ieee80211_mgmt *mgmt, size_t len, 2848 struct ieee80211_rx_status *rx_status)
2884 u8 *deauth_buf, struct ieee80211_rx_status *rx_status)
2885{ 2849{
2886 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 2850 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
2887 struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf; 2851 struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf;
@@ -2896,24 +2860,25 @@ ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
2896 u8 erp_value = 0; 2860 u8 erp_value = 0;
2897 u32 ncrc; 2861 u32 ncrc;
2898 u8 *bssid; 2862 u8 *bssid;
2863 u8 deauth_buf[IEEE80211_DEAUTH_FRAME_LEN];
2899 2864
2900 lockdep_assert_held(&ifmgd->mtx); 2865 sdata_assert_lock(sdata);
2901 2866
2902 /* Process beacon from the current BSS */ 2867 /* Process beacon from the current BSS */
2903 baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt; 2868 baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt;
2904 if (baselen > len) 2869 if (baselen > len)
2905 return RX_MGMT_NONE; 2870 return;
2906 2871
2907 rcu_read_lock(); 2872 rcu_read_lock();
2908 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); 2873 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
2909 if (!chanctx_conf) { 2874 if (!chanctx_conf) {
2910 rcu_read_unlock(); 2875 rcu_read_unlock();
2911 return RX_MGMT_NONE; 2876 return;
2912 } 2877 }
2913 2878
2914 if (rx_status->freq != chanctx_conf->def.chan->center_freq) { 2879 if (rx_status->freq != chanctx_conf->def.chan->center_freq) {
2915 rcu_read_unlock(); 2880 rcu_read_unlock();
2916 return RX_MGMT_NONE; 2881 return;
2917 } 2882 }
2918 chan = chanctx_conf->def.chan; 2883 chan = chanctx_conf->def.chan;
2919 rcu_read_unlock(); 2884 rcu_read_unlock();
@@ -2940,13 +2905,13 @@ ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
2940 /* continue assoc process */ 2905 /* continue assoc process */
2941 ifmgd->assoc_data->timeout = jiffies; 2906 ifmgd->assoc_data->timeout = jiffies;
2942 ifmgd->assoc_data->timeout_started = true; 2907 ifmgd->assoc_data->timeout_started = true;
2943 run_again(ifmgd, ifmgd->assoc_data->timeout); 2908 run_again(sdata, ifmgd->assoc_data->timeout);
2944 return RX_MGMT_NONE; 2909 return;
2945 } 2910 }
2946 2911
2947 if (!ifmgd->associated || 2912 if (!ifmgd->associated ||
2948 !ether_addr_equal(mgmt->bssid, ifmgd->associated->bssid)) 2913 !ether_addr_equal(mgmt->bssid, ifmgd->associated->bssid))
2949 return RX_MGMT_NONE; 2914 return;
2950 bssid = ifmgd->associated->bssid; 2915 bssid = ifmgd->associated->bssid;
2951 2916
2952 /* Track average RSSI from the Beacon frames of the current AP */ 2917 /* Track average RSSI from the Beacon frames of the current AP */
@@ -3092,7 +3057,7 @@ ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
3092 } 3057 }
3093 3058
3094 if (ncrc == ifmgd->beacon_crc && ifmgd->beacon_crc_valid) 3059 if (ncrc == ifmgd->beacon_crc && ifmgd->beacon_crc_valid)
3095 return RX_MGMT_NONE; 3060 return;
3096 ifmgd->beacon_crc = ncrc; 3061 ifmgd->beacon_crc = ncrc;
3097 ifmgd->beacon_crc_valid = true; 3062 ifmgd->beacon_crc_valid = true;
3098 3063
@@ -3126,6 +3091,7 @@ ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
3126 } 3091 }
3127 3092
3128 changed |= BSS_CHANGED_DTIM_PERIOD; 3093 changed |= BSS_CHANGED_DTIM_PERIOD;
3094 ieee80211_recalc_ps_vif(sdata);
3129 } 3095 }
3130 3096
3131 if (elems.erp_info) { 3097 if (elems.erp_info) {
@@ -3147,7 +3113,9 @@ ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
3147 ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, 3113 ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH,
3148 WLAN_REASON_DEAUTH_LEAVING, 3114 WLAN_REASON_DEAUTH_LEAVING,
3149 true, deauth_buf); 3115 true, deauth_buf);
3150 return RX_MGMT_CFG80211_TX_DEAUTH; 3116 cfg80211_send_deauth(sdata->dev, deauth_buf,
3117 sizeof(deauth_buf));
3118 return;
3151 } 3119 }
3152 3120
3153 if (sta && elems.opmode_notif) 3121 if (sta && elems.opmode_notif)
@@ -3164,19 +3132,13 @@ ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
3164 elems.pwr_constr_elem); 3132 elems.pwr_constr_elem);
3165 3133
3166 ieee80211_bss_info_change_notify(sdata, changed); 3134 ieee80211_bss_info_change_notify(sdata, changed);
3167
3168 return RX_MGMT_NONE;
3169} 3135}
3170 3136
3171void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, 3137void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
3172 struct sk_buff *skb) 3138 struct sk_buff *skb)
3173{ 3139{
3174 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
3175 struct ieee80211_rx_status *rx_status; 3140 struct ieee80211_rx_status *rx_status;
3176 struct ieee80211_mgmt *mgmt; 3141 struct ieee80211_mgmt *mgmt;
3177 struct cfg80211_bss *bss = NULL;
3178 enum rx_mgmt_action rma = RX_MGMT_NONE;
3179 u8 deauth_buf[IEEE80211_DEAUTH_FRAME_LEN];
3180 u16 fc; 3142 u16 fc;
3181 struct ieee802_11_elems elems; 3143 struct ieee802_11_elems elems;
3182 int ies_len; 3144 int ies_len;
@@ -3185,28 +3147,27 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
3185 mgmt = (struct ieee80211_mgmt *) skb->data; 3147 mgmt = (struct ieee80211_mgmt *) skb->data;
3186 fc = le16_to_cpu(mgmt->frame_control); 3148 fc = le16_to_cpu(mgmt->frame_control);
3187 3149
3188 mutex_lock(&ifmgd->mtx); 3150 sdata_lock(sdata);
3189 3151
3190 switch (fc & IEEE80211_FCTL_STYPE) { 3152 switch (fc & IEEE80211_FCTL_STYPE) {
3191 case IEEE80211_STYPE_BEACON: 3153 case IEEE80211_STYPE_BEACON:
3192 rma = ieee80211_rx_mgmt_beacon(sdata, mgmt, skb->len, 3154 ieee80211_rx_mgmt_beacon(sdata, mgmt, skb->len, rx_status);
3193 deauth_buf, rx_status);
3194 break; 3155 break;
3195 case IEEE80211_STYPE_PROBE_RESP: 3156 case IEEE80211_STYPE_PROBE_RESP:
3196 ieee80211_rx_mgmt_probe_resp(sdata, skb); 3157 ieee80211_rx_mgmt_probe_resp(sdata, skb);
3197 break; 3158 break;
3198 case IEEE80211_STYPE_AUTH: 3159 case IEEE80211_STYPE_AUTH:
3199 rma = ieee80211_rx_mgmt_auth(sdata, mgmt, skb->len); 3160 ieee80211_rx_mgmt_auth(sdata, mgmt, skb->len);
3200 break; 3161 break;
3201 case IEEE80211_STYPE_DEAUTH: 3162 case IEEE80211_STYPE_DEAUTH:
3202 rma = ieee80211_rx_mgmt_deauth(sdata, mgmt, skb->len); 3163 ieee80211_rx_mgmt_deauth(sdata, mgmt, skb->len);
3203 break; 3164 break;
3204 case IEEE80211_STYPE_DISASSOC: 3165 case IEEE80211_STYPE_DISASSOC:
3205 rma = ieee80211_rx_mgmt_disassoc(sdata, mgmt, skb->len); 3166 ieee80211_rx_mgmt_disassoc(sdata, mgmt, skb->len);
3206 break; 3167 break;
3207 case IEEE80211_STYPE_ASSOC_RESP: 3168 case IEEE80211_STYPE_ASSOC_RESP:
3208 case IEEE80211_STYPE_REASSOC_RESP: 3169 case IEEE80211_STYPE_REASSOC_RESP:
3209 rma = ieee80211_rx_mgmt_assoc_resp(sdata, mgmt, skb->len, &bss); 3170 ieee80211_rx_mgmt_assoc_resp(sdata, mgmt, skb->len);
3210 break; 3171 break;
3211 case IEEE80211_STYPE_ACTION: 3172 case IEEE80211_STYPE_ACTION:
3212 if (mgmt->u.action.category == WLAN_CATEGORY_SPECTRUM_MGMT) { 3173 if (mgmt->u.action.category == WLAN_CATEGORY_SPECTRUM_MGMT) {
@@ -3252,34 +3213,7 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
3252 } 3213 }
3253 break; 3214 break;
3254 } 3215 }
3255 mutex_unlock(&ifmgd->mtx); 3216 sdata_unlock(sdata);
3256
3257 switch (rma) {
3258 case RX_MGMT_NONE:
3259 /* no action */
3260 break;
3261 case RX_MGMT_CFG80211_DEAUTH:
3262 cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len);
3263 break;
3264 case RX_MGMT_CFG80211_DISASSOC:
3265 cfg80211_send_disassoc(sdata->dev, (u8 *)mgmt, skb->len);
3266 break;
3267 case RX_MGMT_CFG80211_RX_AUTH:
3268 cfg80211_send_rx_auth(sdata->dev, (u8 *)mgmt, skb->len);
3269 break;
3270 case RX_MGMT_CFG80211_RX_ASSOC:
3271 cfg80211_send_rx_assoc(sdata->dev, bss, (u8 *)mgmt, skb->len);
3272 break;
3273 case RX_MGMT_CFG80211_ASSOC_TIMEOUT:
3274 cfg80211_send_assoc_timeout(sdata->dev, mgmt->bssid);
3275 break;
3276 case RX_MGMT_CFG80211_TX_DEAUTH:
3277 cfg80211_send_deauth(sdata->dev, deauth_buf,
3278 sizeof(deauth_buf));
3279 break;
3280 default:
3281 WARN(1, "unexpected: %d", rma);
3282 }
3283} 3217}
3284 3218
3285static void ieee80211_sta_timer(unsigned long data) 3219static void ieee80211_sta_timer(unsigned long data)
@@ -3293,20 +3227,12 @@ static void ieee80211_sta_timer(unsigned long data)
3293static void ieee80211_sta_connection_lost(struct ieee80211_sub_if_data *sdata, 3227static void ieee80211_sta_connection_lost(struct ieee80211_sub_if_data *sdata,
3294 u8 *bssid, u8 reason, bool tx) 3228 u8 *bssid, u8 reason, bool tx)
3295{ 3229{
3296 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
3297 u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN]; 3230 u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN];
3298 3231
3299 ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, reason, 3232 ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, reason,
3300 tx, frame_buf); 3233 tx, frame_buf);
3301 mutex_unlock(&ifmgd->mtx);
3302 3234
3303 /*
3304 * must be outside lock due to cfg80211,
3305 * but that's not a problem.
3306 */
3307 cfg80211_send_deauth(sdata->dev, frame_buf, IEEE80211_DEAUTH_FRAME_LEN); 3235 cfg80211_send_deauth(sdata->dev, frame_buf, IEEE80211_DEAUTH_FRAME_LEN);
3308
3309 mutex_lock(&ifmgd->mtx);
3310} 3236}
3311 3237
3312static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata) 3238static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata)
@@ -3316,7 +3242,7 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata)
3316 struct ieee80211_mgd_auth_data *auth_data = ifmgd->auth_data; 3242 struct ieee80211_mgd_auth_data *auth_data = ifmgd->auth_data;
3317 u32 tx_flags = 0; 3243 u32 tx_flags = 0;
3318 3244
3319 lockdep_assert_held(&ifmgd->mtx); 3245 sdata_assert_lock(sdata);
3320 3246
3321 if (WARN_ON_ONCE(!auth_data)) 3247 if (WARN_ON_ONCE(!auth_data))
3322 return -EINVAL; 3248 return -EINVAL;
@@ -3389,7 +3315,7 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata)
3389 if (tx_flags == 0) { 3315 if (tx_flags == 0) {
3390 auth_data->timeout = jiffies + IEEE80211_AUTH_TIMEOUT; 3316 auth_data->timeout = jiffies + IEEE80211_AUTH_TIMEOUT;
3391 ifmgd->auth_data->timeout_started = true; 3317 ifmgd->auth_data->timeout_started = true;
3392 run_again(ifmgd, auth_data->timeout); 3318 run_again(sdata, auth_data->timeout);
3393 } else { 3319 } else {
3394 auth_data->timeout_started = false; 3320 auth_data->timeout_started = false;
3395 } 3321 }
@@ -3402,7 +3328,7 @@ static int ieee80211_do_assoc(struct ieee80211_sub_if_data *sdata)
3402 struct ieee80211_mgd_assoc_data *assoc_data = sdata->u.mgd.assoc_data; 3328 struct ieee80211_mgd_assoc_data *assoc_data = sdata->u.mgd.assoc_data;
3403 struct ieee80211_local *local = sdata->local; 3329 struct ieee80211_local *local = sdata->local;
3404 3330
3405 lockdep_assert_held(&sdata->u.mgd.mtx); 3331 sdata_assert_lock(sdata);
3406 3332
3407 assoc_data->tries++; 3333 assoc_data->tries++;
3408 if (assoc_data->tries > IEEE80211_ASSOC_MAX_TRIES) { 3334 if (assoc_data->tries > IEEE80211_ASSOC_MAX_TRIES) {
@@ -3426,7 +3352,7 @@ static int ieee80211_do_assoc(struct ieee80211_sub_if_data *sdata)
3426 if (!(local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)) { 3352 if (!(local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)) {
3427 assoc_data->timeout = jiffies + IEEE80211_ASSOC_TIMEOUT; 3353 assoc_data->timeout = jiffies + IEEE80211_ASSOC_TIMEOUT;
3428 assoc_data->timeout_started = true; 3354 assoc_data->timeout_started = true;
3429 run_again(&sdata->u.mgd, assoc_data->timeout); 3355 run_again(sdata, assoc_data->timeout);
3430 } else { 3356 } else {
3431 assoc_data->timeout_started = false; 3357 assoc_data->timeout_started = false;
3432 } 3358 }
@@ -3451,7 +3377,7 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
3451 struct ieee80211_local *local = sdata->local; 3377 struct ieee80211_local *local = sdata->local;
3452 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 3378 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
3453 3379
3454 mutex_lock(&ifmgd->mtx); 3380 sdata_lock(sdata);
3455 3381
3456 if (ifmgd->status_received) { 3382 if (ifmgd->status_received) {
3457 __le16 fc = ifmgd->status_fc; 3383 __le16 fc = ifmgd->status_fc;
@@ -3463,7 +3389,7 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
3463 if (status_acked) { 3389 if (status_acked) {
3464 ifmgd->auth_data->timeout = 3390 ifmgd->auth_data->timeout =
3465 jiffies + IEEE80211_AUTH_TIMEOUT_SHORT; 3391 jiffies + IEEE80211_AUTH_TIMEOUT_SHORT;
3466 run_again(ifmgd, ifmgd->auth_data->timeout); 3392 run_again(sdata, ifmgd->auth_data->timeout);
3467 } else { 3393 } else {
3468 ifmgd->auth_data->timeout = jiffies - 1; 3394 ifmgd->auth_data->timeout = jiffies - 1;
3469 } 3395 }
@@ -3474,7 +3400,7 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
3474 if (status_acked) { 3400 if (status_acked) {
3475 ifmgd->assoc_data->timeout = 3401 ifmgd->assoc_data->timeout =
3476 jiffies + IEEE80211_ASSOC_TIMEOUT_SHORT; 3402 jiffies + IEEE80211_ASSOC_TIMEOUT_SHORT;
3477 run_again(ifmgd, ifmgd->assoc_data->timeout); 3403 run_again(sdata, ifmgd->assoc_data->timeout);
3478 } else { 3404 } else {
3479 ifmgd->assoc_data->timeout = jiffies - 1; 3405 ifmgd->assoc_data->timeout = jiffies - 1;
3480 } 3406 }
@@ -3497,12 +3423,10 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
3497 3423
3498 ieee80211_destroy_auth_data(sdata, false); 3424 ieee80211_destroy_auth_data(sdata, false);
3499 3425
3500 mutex_unlock(&ifmgd->mtx);
3501 cfg80211_send_auth_timeout(sdata->dev, bssid); 3426 cfg80211_send_auth_timeout(sdata->dev, bssid);
3502 mutex_lock(&ifmgd->mtx);
3503 } 3427 }
3504 } else if (ifmgd->auth_data && ifmgd->auth_data->timeout_started) 3428 } else if (ifmgd->auth_data && ifmgd->auth_data->timeout_started)
3505 run_again(ifmgd, ifmgd->auth_data->timeout); 3429 run_again(sdata, ifmgd->auth_data->timeout);
3506 3430
3507 if (ifmgd->assoc_data && ifmgd->assoc_data->timeout_started && 3431 if (ifmgd->assoc_data && ifmgd->assoc_data->timeout_started &&
3508 time_after(jiffies, ifmgd->assoc_data->timeout)) { 3432 time_after(jiffies, ifmgd->assoc_data->timeout)) {
@@ -3515,12 +3439,10 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
3515 3439
3516 ieee80211_destroy_assoc_data(sdata, false); 3440 ieee80211_destroy_assoc_data(sdata, false);
3517 3441
3518 mutex_unlock(&ifmgd->mtx);
3519 cfg80211_send_assoc_timeout(sdata->dev, bssid); 3442 cfg80211_send_assoc_timeout(sdata->dev, bssid);
3520 mutex_lock(&ifmgd->mtx);
3521 } 3443 }
3522 } else if (ifmgd->assoc_data && ifmgd->assoc_data->timeout_started) 3444 } else if (ifmgd->assoc_data && ifmgd->assoc_data->timeout_started)
3523 run_again(ifmgd, ifmgd->assoc_data->timeout); 3445 run_again(sdata, ifmgd->assoc_data->timeout);
3524 3446
3525 if (ifmgd->flags & (IEEE80211_STA_BEACON_POLL | 3447 if (ifmgd->flags & (IEEE80211_STA_BEACON_POLL |
3526 IEEE80211_STA_CONNECTION_POLL) && 3448 IEEE80211_STA_CONNECTION_POLL) &&
@@ -3554,7 +3476,7 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
3554 false); 3476 false);
3555 } 3477 }
3556 } else if (time_is_after_jiffies(ifmgd->probe_timeout)) 3478 } else if (time_is_after_jiffies(ifmgd->probe_timeout))
3557 run_again(ifmgd, ifmgd->probe_timeout); 3479 run_again(sdata, ifmgd->probe_timeout);
3558 else if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) { 3480 else if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) {
3559 mlme_dbg(sdata, 3481 mlme_dbg(sdata,
3560 "Failed to send nullfunc to AP %pM after %dms, disconnecting\n", 3482 "Failed to send nullfunc to AP %pM after %dms, disconnecting\n",
@@ -3583,7 +3505,7 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
3583 } 3505 }
3584 } 3506 }
3585 3507
3586 mutex_unlock(&ifmgd->mtx); 3508 sdata_unlock(sdata);
3587} 3509}
3588 3510
3589static void ieee80211_sta_bcn_mon_timer(unsigned long data) 3511static void ieee80211_sta_bcn_mon_timer(unsigned long data)
@@ -3644,9 +3566,9 @@ void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata)
3644{ 3566{
3645 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 3567 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
3646 3568
3647 mutex_lock(&ifmgd->mtx); 3569 sdata_lock(sdata);
3648 if (!ifmgd->associated) { 3570 if (!ifmgd->associated) {
3649 mutex_unlock(&ifmgd->mtx); 3571 sdata_unlock(sdata);
3650 return; 3572 return;
3651 } 3573 }
3652 3574
@@ -3657,10 +3579,10 @@ void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata)
3657 ifmgd->associated->bssid, 3579 ifmgd->associated->bssid,
3658 WLAN_REASON_UNSPECIFIED, 3580 WLAN_REASON_UNSPECIFIED,
3659 true); 3581 true);
3660 mutex_unlock(&ifmgd->mtx); 3582 sdata_unlock(sdata);
3661 return; 3583 return;
3662 } 3584 }
3663 mutex_unlock(&ifmgd->mtx); 3585 sdata_unlock(sdata);
3664} 3586}
3665#endif 3587#endif
3666 3588
@@ -3692,8 +3614,6 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata)
3692 ifmgd->uapsd_max_sp_len = sdata->local->hw.uapsd_max_sp_len; 3614 ifmgd->uapsd_max_sp_len = sdata->local->hw.uapsd_max_sp_len;
3693 ifmgd->p2p_noa_index = -1; 3615 ifmgd->p2p_noa_index = -1;
3694 3616
3695 mutex_init(&ifmgd->mtx);
3696
3697 if (sdata->local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS) 3617 if (sdata->local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS)
3698 ifmgd->req_smps = IEEE80211_SMPS_AUTOMATIC; 3618 ifmgd->req_smps = IEEE80211_SMPS_AUTOMATIC;
3699 else 3619 else
@@ -4049,8 +3969,6 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
4049 3969
4050 /* try to authenticate/probe */ 3970 /* try to authenticate/probe */
4051 3971
4052 mutex_lock(&ifmgd->mtx);
4053
4054 if ((ifmgd->auth_data && !ifmgd->auth_data->done) || 3972 if ((ifmgd->auth_data && !ifmgd->auth_data->done) ||
4055 ifmgd->assoc_data) { 3973 ifmgd->assoc_data) {
4056 err = -EBUSY; 3974 err = -EBUSY;
@@ -4070,8 +3988,8 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
4070 WLAN_REASON_UNSPECIFIED, 3988 WLAN_REASON_UNSPECIFIED,
4071 false, frame_buf); 3989 false, frame_buf);
4072 3990
4073 __cfg80211_send_deauth(sdata->dev, frame_buf, 3991 cfg80211_send_deauth(sdata->dev, frame_buf,
4074 sizeof(frame_buf)); 3992 sizeof(frame_buf));
4075 } 3993 }
4076 3994
4077 sdata_info(sdata, "authenticate with %pM\n", req->bss->bssid); 3995 sdata_info(sdata, "authenticate with %pM\n", req->bss->bssid);
@@ -4088,8 +4006,7 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
4088 4006
4089 /* hold our own reference */ 4007 /* hold our own reference */
4090 cfg80211_ref_bss(local->hw.wiphy, auth_data->bss); 4008 cfg80211_ref_bss(local->hw.wiphy, auth_data->bss);
4091 err = 0; 4009 return 0;
4092 goto out_unlock;
4093 4010
4094 err_clear: 4011 err_clear:
4095 memset(ifmgd->bssid, 0, ETH_ALEN); 4012 memset(ifmgd->bssid, 0, ETH_ALEN);
@@ -4097,9 +4014,6 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
4097 ifmgd->auth_data = NULL; 4014 ifmgd->auth_data = NULL;
4098 err_free: 4015 err_free:
4099 kfree(auth_data); 4016 kfree(auth_data);
4100 out_unlock:
4101 mutex_unlock(&ifmgd->mtx);
4102
4103 return err; 4017 return err;
4104} 4018}
4105 4019
@@ -4130,8 +4044,6 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
4130 assoc_data->ssid_len = ssidie[1]; 4044 assoc_data->ssid_len = ssidie[1];
4131 rcu_read_unlock(); 4045 rcu_read_unlock();
4132 4046
4133 mutex_lock(&ifmgd->mtx);
4134
4135 if (ifmgd->associated) { 4047 if (ifmgd->associated) {
4136 u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN]; 4048 u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN];
4137 4049
@@ -4139,8 +4051,8 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
4139 WLAN_REASON_UNSPECIFIED, 4051 WLAN_REASON_UNSPECIFIED,
4140 false, frame_buf); 4052 false, frame_buf);
4141 4053
4142 __cfg80211_send_deauth(sdata->dev, frame_buf, 4054 cfg80211_send_deauth(sdata->dev, frame_buf,
4143 sizeof(frame_buf)); 4055 sizeof(frame_buf));
4144 } 4056 }
4145 4057
4146 if (ifmgd->auth_data && !ifmgd->auth_data->done) { 4058 if (ifmgd->auth_data && !ifmgd->auth_data->done) {
@@ -4334,7 +4246,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
4334 } 4246 }
4335 rcu_read_unlock(); 4247 rcu_read_unlock();
4336 4248
4337 run_again(ifmgd, assoc_data->timeout); 4249 run_again(sdata, assoc_data->timeout);
4338 4250
4339 if (bss->corrupt_data) { 4251 if (bss->corrupt_data) {
4340 char *corrupt_type = "data"; 4252 char *corrupt_type = "data";
@@ -4350,17 +4262,13 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
4350 corrupt_type); 4262 corrupt_type);
4351 } 4263 }
4352 4264
4353 err = 0; 4265 return 0;
4354 goto out;
4355 err_clear: 4266 err_clear:
4356 memset(ifmgd->bssid, 0, ETH_ALEN); 4267 memset(ifmgd->bssid, 0, ETH_ALEN);
4357 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID); 4268 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID);
4358 ifmgd->assoc_data = NULL; 4269 ifmgd->assoc_data = NULL;
4359 err_free: 4270 err_free:
4360 kfree(assoc_data); 4271 kfree(assoc_data);
4361 out:
4362 mutex_unlock(&ifmgd->mtx);
4363
4364 return err; 4272 return err;
4365} 4273}
4366 4274
@@ -4372,8 +4280,6 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
4372 bool tx = !req->local_state_change; 4280 bool tx = !req->local_state_change;
4373 bool report_frame = false; 4281 bool report_frame = false;
4374 4282
4375 mutex_lock(&ifmgd->mtx);
4376
4377 sdata_info(sdata, 4283 sdata_info(sdata,
4378 "deauthenticating from %pM by local choice (reason=%d)\n", 4284 "deauthenticating from %pM by local choice (reason=%d)\n",
4379 req->bssid, req->reason_code); 4285 req->bssid, req->reason_code);
@@ -4385,7 +4291,6 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
4385 req->reason_code, tx, 4291 req->reason_code, tx,
4386 frame_buf); 4292 frame_buf);
4387 ieee80211_destroy_auth_data(sdata, false); 4293 ieee80211_destroy_auth_data(sdata, false);
4388 mutex_unlock(&ifmgd->mtx);
4389 4294
4390 report_frame = true; 4295 report_frame = true;
4391 goto out; 4296 goto out;
@@ -4397,12 +4302,11 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
4397 req->reason_code, tx, frame_buf); 4302 req->reason_code, tx, frame_buf);
4398 report_frame = true; 4303 report_frame = true;
4399 } 4304 }
4400 mutex_unlock(&ifmgd->mtx);
4401 4305
4402 out: 4306 out:
4403 if (report_frame) 4307 if (report_frame)
4404 __cfg80211_send_deauth(sdata->dev, frame_buf, 4308 cfg80211_send_deauth(sdata->dev, frame_buf,
4405 IEEE80211_DEAUTH_FRAME_LEN); 4309 IEEE80211_DEAUTH_FRAME_LEN);
4406 4310
4407 return 0; 4311 return 0;
4408} 4312}
@@ -4414,18 +4318,14 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
4414 u8 bssid[ETH_ALEN]; 4318 u8 bssid[ETH_ALEN];
4415 u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN]; 4319 u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN];
4416 4320
4417 mutex_lock(&ifmgd->mtx);
4418
4419 /* 4321 /*
4420 * cfg80211 should catch this ... but it's racy since 4322 * cfg80211 should catch this ... but it's racy since
4421 * we can receive a disassoc frame, process it, hand it 4323 * we can receive a disassoc frame, process it, hand it
4422 * to cfg80211 while that's in a locked section already 4324 * to cfg80211 while that's in a locked section already
4423 * trying to tell us that the user wants to disconnect. 4325 * trying to tell us that the user wants to disconnect.
4424 */ 4326 */
4425 if (ifmgd->associated != req->bss) { 4327 if (ifmgd->associated != req->bss)
4426 mutex_unlock(&ifmgd->mtx);
4427 return -ENOLINK; 4328 return -ENOLINK;
4428 }
4429 4329
4430 sdata_info(sdata, 4330 sdata_info(sdata,
4431 "disassociating from %pM by local choice (reason=%d)\n", 4331 "disassociating from %pM by local choice (reason=%d)\n",
@@ -4435,10 +4335,9 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
4435 ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DISASSOC, 4335 ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DISASSOC,
4436 req->reason_code, !req->local_state_change, 4336 req->reason_code, !req->local_state_change,
4437 frame_buf); 4337 frame_buf);
4438 mutex_unlock(&ifmgd->mtx);
4439 4338
4440 __cfg80211_send_disassoc(sdata->dev, frame_buf, 4339 cfg80211_send_disassoc(sdata->dev, frame_buf,
4441 IEEE80211_DEAUTH_FRAME_LEN); 4340 IEEE80211_DEAUTH_FRAME_LEN);
4442 4341
4443 return 0; 4342 return 0;
4444} 4343}
@@ -4458,13 +4357,13 @@ void ieee80211_mgd_stop(struct ieee80211_sub_if_data *sdata)
4458 cancel_work_sync(&ifmgd->csa_connection_drop_work); 4357 cancel_work_sync(&ifmgd->csa_connection_drop_work);
4459 cancel_work_sync(&ifmgd->chswitch_work); 4358 cancel_work_sync(&ifmgd->chswitch_work);
4460 4359
4461 mutex_lock(&ifmgd->mtx); 4360 sdata_lock(sdata);
4462 if (ifmgd->assoc_data) 4361 if (ifmgd->assoc_data)
4463 ieee80211_destroy_assoc_data(sdata, false); 4362 ieee80211_destroy_assoc_data(sdata, false);
4464 if (ifmgd->auth_data) 4363 if (ifmgd->auth_data)
4465 ieee80211_destroy_auth_data(sdata, false); 4364 ieee80211_destroy_auth_data(sdata, false);
4466 del_timer_sync(&ifmgd->timer); 4365 del_timer_sync(&ifmgd->timer);
4467 mutex_unlock(&ifmgd->mtx); 4366 sdata_unlock(sdata);
4468} 4367}
4469 4368
4470void ieee80211_cqm_rssi_notify(struct ieee80211_vif *vif, 4369void ieee80211_cqm_rssi_notify(struct ieee80211_vif *vif,
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 8e2952620256..bdd7b4a719e9 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -258,6 +258,8 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
258 pos += 2; 258 pos += 2;
259 259
260 if (status->flag & RX_FLAG_HT) { 260 if (status->flag & RX_FLAG_HT) {
261 unsigned int stbc;
262
261 rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_MCS); 263 rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_MCS);
262 *pos++ = local->hw.radiotap_mcs_details; 264 *pos++ = local->hw.radiotap_mcs_details;
263 *pos = 0; 265 *pos = 0;
@@ -267,6 +269,8 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
267 *pos |= IEEE80211_RADIOTAP_MCS_BW_40; 269 *pos |= IEEE80211_RADIOTAP_MCS_BW_40;
268 if (status->flag & RX_FLAG_HT_GF) 270 if (status->flag & RX_FLAG_HT_GF)
269 *pos |= IEEE80211_RADIOTAP_MCS_FMT_GF; 271 *pos |= IEEE80211_RADIOTAP_MCS_FMT_GF;
272 stbc = (status->flag & RX_FLAG_STBC_MASK) >> RX_FLAG_STBC_SHIFT;
273 *pos |= stbc << IEEE80211_RADIOTAP_MCS_STBC_SHIFT;
270 pos++; 274 pos++;
271 *pos++ = status->rate_idx; 275 *pos++ = status->rate_idx;
272 } 276 }
@@ -1372,6 +1376,7 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
1372 struct sk_buff *skb = rx->skb; 1376 struct sk_buff *skb = rx->skb;
1373 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); 1377 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
1374 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 1378 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
1379 int i;
1375 1380
1376 if (!sta) 1381 if (!sta)
1377 return RX_CONTINUE; 1382 return RX_CONTINUE;
@@ -1422,6 +1427,19 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
1422 ewma_add(&sta->avg_signal, -status->signal); 1427 ewma_add(&sta->avg_signal, -status->signal);
1423 } 1428 }
1424 1429
1430 if (status->chains) {
1431 sta->chains = status->chains;
1432 for (i = 0; i < ARRAY_SIZE(status->chain_signal); i++) {
1433 int signal = status->chain_signal[i];
1434
1435 if (!(status->chains & BIT(i)))
1436 continue;
1437
1438 sta->chain_signal_last[i] = signal;
1439 ewma_add(&sta->chain_signal_avg[i], -signal);
1440 }
1441 }
1442
1425 /* 1443 /*
1426 * Change STA power saving mode only at the end of a frame 1444 * Change STA power saving mode only at the end of a frame
1427 * exchange sequence. 1445 * exchange sequence.
@@ -1608,7 +1626,7 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
1608 entry->ccmp = 1; 1626 entry->ccmp = 1;
1609 memcpy(entry->last_pn, 1627 memcpy(entry->last_pn,
1610 rx->key->u.ccmp.rx_pn[queue], 1628 rx->key->u.ccmp.rx_pn[queue],
1611 CCMP_PN_LEN); 1629 IEEE80211_CCMP_PN_LEN);
1612 } 1630 }
1613 return RX_QUEUED; 1631 return RX_QUEUED;
1614 } 1632 }
@@ -1627,21 +1645,21 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
1627 * (IEEE 802.11i, 8.3.3.4.5) */ 1645 * (IEEE 802.11i, 8.3.3.4.5) */
1628 if (entry->ccmp) { 1646 if (entry->ccmp) {
1629 int i; 1647 int i;
1630 u8 pn[CCMP_PN_LEN], *rpn; 1648 u8 pn[IEEE80211_CCMP_PN_LEN], *rpn;
1631 int queue; 1649 int queue;
1632 if (!rx->key || rx->key->conf.cipher != WLAN_CIPHER_SUITE_CCMP) 1650 if (!rx->key || rx->key->conf.cipher != WLAN_CIPHER_SUITE_CCMP)
1633 return RX_DROP_UNUSABLE; 1651 return RX_DROP_UNUSABLE;
1634 memcpy(pn, entry->last_pn, CCMP_PN_LEN); 1652 memcpy(pn, entry->last_pn, IEEE80211_CCMP_PN_LEN);
1635 for (i = CCMP_PN_LEN - 1; i >= 0; i--) { 1653 for (i = IEEE80211_CCMP_PN_LEN - 1; i >= 0; i--) {
1636 pn[i]++; 1654 pn[i]++;
1637 if (pn[i]) 1655 if (pn[i])
1638 break; 1656 break;
1639 } 1657 }
1640 queue = rx->security_idx; 1658 queue = rx->security_idx;
1641 rpn = rx->key->u.ccmp.rx_pn[queue]; 1659 rpn = rx->key->u.ccmp.rx_pn[queue];
1642 if (memcmp(pn, rpn, CCMP_PN_LEN)) 1660 if (memcmp(pn, rpn, IEEE80211_CCMP_PN_LEN))
1643 return RX_DROP_UNUSABLE; 1661 return RX_DROP_UNUSABLE;
1644 memcpy(entry->last_pn, pn, CCMP_PN_LEN); 1662 memcpy(entry->last_pn, pn, IEEE80211_CCMP_PN_LEN);
1645 } 1663 }
1646 1664
1647 skb_pull(rx->skb, ieee80211_hdrlen(fc)); 1665 skb_pull(rx->skb, ieee80211_hdrlen(fc));
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 11216bc13b27..a04c5671d7fd 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -358,6 +358,8 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
358 do_posix_clock_monotonic_gettime(&uptime); 358 do_posix_clock_monotonic_gettime(&uptime);
359 sta->last_connected = uptime.tv_sec; 359 sta->last_connected = uptime.tv_sec;
360 ewma_init(&sta->avg_signal, 1024, 8); 360 ewma_init(&sta->avg_signal, 1024, 8);
361 for (i = 0; i < ARRAY_SIZE(sta->chain_signal_avg); i++)
362 ewma_init(&sta->chain_signal_avg[i], 1024, 8);
361 363
362 if (sta_prepare_rate_control(local, sta, gfp)) { 364 if (sta_prepare_rate_control(local, sta, gfp)) {
363 kfree(sta); 365 kfree(sta);
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index adc30045f99e..41c28b977f7c 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -344,6 +344,11 @@ struct sta_info {
344 int last_signal; 344 int last_signal;
345 struct ewma avg_signal; 345 struct ewma avg_signal;
346 int last_ack_signal; 346 int last_ack_signal;
347
348 u8 chains;
349 s8 chain_signal_last[IEEE80211_MAX_CHAINS];
350 struct ewma chain_signal_avg[IEEE80211_MAX_CHAINS];
351
347 /* Plus 1 for non-QoS frames */ 352 /* Plus 1 for non-QoS frames */
348 __le16 last_seq_ctrl[IEEE80211_NUM_TIDS + 1]; 353 __le16 last_seq_ctrl[IEEE80211_NUM_TIDS + 1];
349 354
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 9972e07a2f96..34be9336b5d1 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -398,13 +398,14 @@ ieee80211_tx_h_multicast_ps_buf(struct ieee80211_tx_data *tx)
398 if (ieee80211_has_order(hdr->frame_control)) 398 if (ieee80211_has_order(hdr->frame_control))
399 return TX_CONTINUE; 399 return TX_CONTINUE;
400 400
401 if (tx->local->hw.flags & IEEE80211_HW_QUEUE_CONTROL)
402 info->hw_queue = tx->sdata->vif.cab_queue;
403
401 /* no stations in PS mode */ 404 /* no stations in PS mode */
402 if (!atomic_read(&ps->num_sta_ps)) 405 if (!atomic_read(&ps->num_sta_ps))
403 return TX_CONTINUE; 406 return TX_CONTINUE;
404 407
405 info->flags |= IEEE80211_TX_CTL_SEND_AFTER_DTIM; 408 info->flags |= IEEE80211_TX_CTL_SEND_AFTER_DTIM;
406 if (tx->local->hw.flags & IEEE80211_HW_QUEUE_CONTROL)
407 info->hw_queue = tx->sdata->vif.cab_queue;
408 409
409 /* device releases frame after DTIM beacon */ 410 /* device releases frame after DTIM beacon */
410 if (!(tx->local->hw.flags & IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING)) 411 if (!(tx->local->hw.flags & IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING))
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 27e07150eb46..89a83770d152 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -560,6 +560,9 @@ void ieee80211_iterate_active_interfaces(
560 list_for_each_entry(sdata, &local->interfaces, list) { 560 list_for_each_entry(sdata, &local->interfaces, list) {
561 switch (sdata->vif.type) { 561 switch (sdata->vif.type) {
562 case NL80211_IFTYPE_MONITOR: 562 case NL80211_IFTYPE_MONITOR:
563 if (!(sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE))
564 continue;
565 break;
563 case NL80211_IFTYPE_AP_VLAN: 566 case NL80211_IFTYPE_AP_VLAN:
564 continue; 567 continue;
565 default: 568 default:
@@ -598,6 +601,9 @@ void ieee80211_iterate_active_interfaces_atomic(
598 list_for_each_entry_rcu(sdata, &local->interfaces, list) { 601 list_for_each_entry_rcu(sdata, &local->interfaces, list) {
599 switch (sdata->vif.type) { 602 switch (sdata->vif.type) {
600 case NL80211_IFTYPE_MONITOR: 603 case NL80211_IFTYPE_MONITOR:
604 if (!(sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE))
605 continue;
606 break;
601 case NL80211_IFTYPE_AP_VLAN: 607 case NL80211_IFTYPE_AP_VLAN:
602 continue; 608 continue;
603 default: 609 default:
@@ -1072,32 +1078,6 @@ void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata,
1072 ieee80211_set_wmm_default(sdata, true); 1078 ieee80211_set_wmm_default(sdata, true);
1073} 1079}
1074 1080
1075u32 ieee80211_mandatory_rates(struct ieee80211_local *local,
1076 enum ieee80211_band band)
1077{
1078 struct ieee80211_supported_band *sband;
1079 struct ieee80211_rate *bitrates;
1080 u32 mandatory_rates;
1081 enum ieee80211_rate_flags mandatory_flag;
1082 int i;
1083
1084 sband = local->hw.wiphy->bands[band];
1085 if (WARN_ON(!sband))
1086 return 1;
1087
1088 if (band == IEEE80211_BAND_2GHZ)
1089 mandatory_flag = IEEE80211_RATE_MANDATORY_B;
1090 else
1091 mandatory_flag = IEEE80211_RATE_MANDATORY_A;
1092
1093 bitrates = sband->bitrates;
1094 mandatory_rates = 0;
1095 for (i = 0; i < sband->n_bitrates; i++)
1096 if (bitrates[i].flags & mandatory_flag)
1097 mandatory_rates |= BIT(i);
1098 return mandatory_rates;
1099}
1100
1101void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, 1081void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
1102 u16 transaction, u16 auth_alg, u16 status, 1082 u16 transaction, u16 auth_alg, u16 status,
1103 const u8 *extra, size_t extra_len, const u8 *da, 1083 const u8 *extra, size_t extra_len, const u8 *da,
@@ -1607,9 +1587,9 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1607 if (sdata->u.mgd.dtim_period) 1587 if (sdata->u.mgd.dtim_period)
1608 changed |= BSS_CHANGED_DTIM_PERIOD; 1588 changed |= BSS_CHANGED_DTIM_PERIOD;
1609 1589
1610 mutex_lock(&sdata->u.mgd.mtx); 1590 sdata_lock(sdata);
1611 ieee80211_bss_info_change_notify(sdata, changed); 1591 ieee80211_bss_info_change_notify(sdata, changed);
1612 mutex_unlock(&sdata->u.mgd.mtx); 1592 sdata_unlock(sdata);
1613 break; 1593 break;
1614 case NL80211_IFTYPE_ADHOC: 1594 case NL80211_IFTYPE_ADHOC:
1615 changed |= BSS_CHANGED_IBSS; 1595 changed |= BSS_CHANGED_IBSS;
diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c
index c04d401dae92..6ee2b5863572 100644
--- a/net/mac80211/wep.c
+++ b/net/mac80211/wep.c
@@ -28,7 +28,7 @@
28int ieee80211_wep_init(struct ieee80211_local *local) 28int ieee80211_wep_init(struct ieee80211_local *local)
29{ 29{
30 /* start WEP IV from a random value */ 30 /* start WEP IV from a random value */
31 get_random_bytes(&local->wep_iv, WEP_IV_LEN); 31 get_random_bytes(&local->wep_iv, IEEE80211_WEP_IV_LEN);
32 32
33 local->wep_tx_tfm = crypto_alloc_cipher("arc4", 0, CRYPTO_ALG_ASYNC); 33 local->wep_tx_tfm = crypto_alloc_cipher("arc4", 0, CRYPTO_ALG_ASYNC);
34 if (IS_ERR(local->wep_tx_tfm)) { 34 if (IS_ERR(local->wep_tx_tfm)) {
@@ -98,20 +98,21 @@ static u8 *ieee80211_wep_add_iv(struct ieee80211_local *local,
98 98
99 hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED); 99 hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
100 100
101 if (WARN_ON(skb_tailroom(skb) < WEP_ICV_LEN || 101 if (WARN_ON(skb_tailroom(skb) < IEEE80211_WEP_ICV_LEN ||
102 skb_headroom(skb) < WEP_IV_LEN)) 102 skb_headroom(skb) < IEEE80211_WEP_IV_LEN))
103 return NULL; 103 return NULL;
104 104
105 hdrlen = ieee80211_hdrlen(hdr->frame_control); 105 hdrlen = ieee80211_hdrlen(hdr->frame_control);
106 newhdr = skb_push(skb, WEP_IV_LEN); 106 newhdr = skb_push(skb, IEEE80211_WEP_IV_LEN);
107 memmove(newhdr, newhdr + WEP_IV_LEN, hdrlen); 107 memmove(newhdr, newhdr + IEEE80211_WEP_IV_LEN, hdrlen);
108 108
109 /* the HW only needs room for the IV, but not the actual IV */ 109 /* the HW only needs room for the IV, but not the actual IV */
110 if (info->control.hw_key && 110 if (info->control.hw_key &&
111 (info->control.hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)) 111 (info->control.hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE))
112 return newhdr + hdrlen; 112 return newhdr + hdrlen;
113 113
114 skb_set_network_header(skb, skb_network_offset(skb) + WEP_IV_LEN); 114 skb_set_network_header(skb, skb_network_offset(skb) +
115 IEEE80211_WEP_IV_LEN);
115 ieee80211_wep_get_iv(local, keylen, keyidx, newhdr + hdrlen); 116 ieee80211_wep_get_iv(local, keylen, keyidx, newhdr + hdrlen);
116 return newhdr + hdrlen; 117 return newhdr + hdrlen;
117} 118}
@@ -125,8 +126,8 @@ static void ieee80211_wep_remove_iv(struct ieee80211_local *local,
125 unsigned int hdrlen; 126 unsigned int hdrlen;
126 127
127 hdrlen = ieee80211_hdrlen(hdr->frame_control); 128 hdrlen = ieee80211_hdrlen(hdr->frame_control);
128 memmove(skb->data + WEP_IV_LEN, skb->data, hdrlen); 129 memmove(skb->data + IEEE80211_WEP_IV_LEN, skb->data, hdrlen);
129 skb_pull(skb, WEP_IV_LEN); 130 skb_pull(skb, IEEE80211_WEP_IV_LEN);
130} 131}
131 132
132 133
@@ -146,7 +147,7 @@ int ieee80211_wep_encrypt_data(struct crypto_cipher *tfm, u8 *rc4key,
146 put_unaligned(icv, (__le32 *)(data + data_len)); 147 put_unaligned(icv, (__le32 *)(data + data_len));
147 148
148 crypto_cipher_setkey(tfm, rc4key, klen); 149 crypto_cipher_setkey(tfm, rc4key, klen);
149 for (i = 0; i < data_len + WEP_ICV_LEN; i++) 150 for (i = 0; i < data_len + IEEE80211_WEP_ICV_LEN; i++)
150 crypto_cipher_encrypt_one(tfm, data + i, data + i); 151 crypto_cipher_encrypt_one(tfm, data + i, data + i);
151 152
152 return 0; 153 return 0;
@@ -172,7 +173,7 @@ int ieee80211_wep_encrypt(struct ieee80211_local *local,
172 if (!iv) 173 if (!iv)
173 return -1; 174 return -1;
174 175
175 len = skb->len - (iv + WEP_IV_LEN - skb->data); 176 len = skb->len - (iv + IEEE80211_WEP_IV_LEN - skb->data);
176 177
177 /* Prepend 24-bit IV to RC4 key */ 178 /* Prepend 24-bit IV to RC4 key */
178 memcpy(rc4key, iv, 3); 179 memcpy(rc4key, iv, 3);
@@ -181,10 +182,10 @@ int ieee80211_wep_encrypt(struct ieee80211_local *local,
181 memcpy(rc4key + 3, key, keylen); 182 memcpy(rc4key + 3, key, keylen);
182 183
183 /* Add room for ICV */ 184 /* Add room for ICV */
184 skb_put(skb, WEP_ICV_LEN); 185 skb_put(skb, IEEE80211_WEP_ICV_LEN);
185 186
186 return ieee80211_wep_encrypt_data(local->wep_tx_tfm, rc4key, keylen + 3, 187 return ieee80211_wep_encrypt_data(local->wep_tx_tfm, rc4key, keylen + 3,
187 iv + WEP_IV_LEN, len); 188 iv + IEEE80211_WEP_IV_LEN, len);
188} 189}
189 190
190 191
@@ -201,11 +202,11 @@ int ieee80211_wep_decrypt_data(struct crypto_cipher *tfm, u8 *rc4key,
201 return -1; 202 return -1;
202 203
203 crypto_cipher_setkey(tfm, rc4key, klen); 204 crypto_cipher_setkey(tfm, rc4key, klen);
204 for (i = 0; i < data_len + WEP_ICV_LEN; i++) 205 for (i = 0; i < data_len + IEEE80211_WEP_ICV_LEN; i++)
205 crypto_cipher_decrypt_one(tfm, data + i, data + i); 206 crypto_cipher_decrypt_one(tfm, data + i, data + i);
206 207
207 crc = cpu_to_le32(~crc32_le(~0, data, data_len)); 208 crc = cpu_to_le32(~crc32_le(~0, data, data_len));
208 if (memcmp(&crc, data + data_len, WEP_ICV_LEN) != 0) 209 if (memcmp(&crc, data + data_len, IEEE80211_WEP_ICV_LEN) != 0)
209 /* ICV mismatch */ 210 /* ICV mismatch */
210 return -1; 211 return -1;
211 212
@@ -237,10 +238,10 @@ static int ieee80211_wep_decrypt(struct ieee80211_local *local,
237 return -1; 238 return -1;
238 239
239 hdrlen = ieee80211_hdrlen(hdr->frame_control); 240 hdrlen = ieee80211_hdrlen(hdr->frame_control);
240 if (skb->len < hdrlen + WEP_IV_LEN + WEP_ICV_LEN) 241 if (skb->len < hdrlen + IEEE80211_WEP_IV_LEN + IEEE80211_WEP_ICV_LEN)
241 return -1; 242 return -1;
242 243
243 len = skb->len - hdrlen - WEP_IV_LEN - WEP_ICV_LEN; 244 len = skb->len - hdrlen - IEEE80211_WEP_IV_LEN - IEEE80211_WEP_ICV_LEN;
244 245
245 keyidx = skb->data[hdrlen + 3] >> 6; 246 keyidx = skb->data[hdrlen + 3] >> 6;
246 247
@@ -256,16 +257,16 @@ static int ieee80211_wep_decrypt(struct ieee80211_local *local,
256 memcpy(rc4key + 3, key->conf.key, key->conf.keylen); 257 memcpy(rc4key + 3, key->conf.key, key->conf.keylen);
257 258
258 if (ieee80211_wep_decrypt_data(local->wep_rx_tfm, rc4key, klen, 259 if (ieee80211_wep_decrypt_data(local->wep_rx_tfm, rc4key, klen,
259 skb->data + hdrlen + WEP_IV_LEN, 260 skb->data + hdrlen +
260 len)) 261 IEEE80211_WEP_IV_LEN, len))
261 ret = -1; 262 ret = -1;
262 263
263 /* Trim ICV */ 264 /* Trim ICV */
264 skb_trim(skb, skb->len - WEP_ICV_LEN); 265 skb_trim(skb, skb->len - IEEE80211_WEP_ICV_LEN);
265 266
266 /* Remove IV */ 267 /* Remove IV */
267 memmove(skb->data + WEP_IV_LEN, skb->data, hdrlen); 268 memmove(skb->data + IEEE80211_WEP_IV_LEN, skb->data, hdrlen);
268 skb_pull(skb, WEP_IV_LEN); 269 skb_pull(skb, IEEE80211_WEP_IV_LEN);
269 270
270 return ret; 271 return ret;
271} 272}
@@ -305,13 +306,14 @@ ieee80211_crypto_wep_decrypt(struct ieee80211_rx_data *rx)
305 if (ieee80211_wep_decrypt(rx->local, rx->skb, rx->key)) 306 if (ieee80211_wep_decrypt(rx->local, rx->skb, rx->key))
306 return RX_DROP_UNUSABLE; 307 return RX_DROP_UNUSABLE;
307 } else if (!(status->flag & RX_FLAG_IV_STRIPPED)) { 308 } else if (!(status->flag & RX_FLAG_IV_STRIPPED)) {
308 if (!pskb_may_pull(rx->skb, ieee80211_hdrlen(fc) + WEP_IV_LEN)) 309 if (!pskb_may_pull(rx->skb, ieee80211_hdrlen(fc) +
310 IEEE80211_WEP_IV_LEN))
309 return RX_DROP_UNUSABLE; 311 return RX_DROP_UNUSABLE;
310 if (rx->sta && ieee80211_wep_is_weak_iv(rx->skb, rx->key)) 312 if (rx->sta && ieee80211_wep_is_weak_iv(rx->skb, rx->key))
311 rx->sta->wep_weak_iv_count++; 313 rx->sta->wep_weak_iv_count++;
312 ieee80211_wep_remove_iv(rx->local, rx->skb, rx->key); 314 ieee80211_wep_remove_iv(rx->local, rx->skb, rx->key);
313 /* remove ICV */ 315 /* remove ICV */
314 if (pskb_trim(rx->skb, rx->skb->len - WEP_ICV_LEN)) 316 if (pskb_trim(rx->skb, rx->skb->len - IEEE80211_WEP_ICV_LEN))
315 return RX_DROP_UNUSABLE; 317 return RX_DROP_UNUSABLE;
316 } 318 }
317 319
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c
index c7c6d644486f..c9edfcb7a13b 100644
--- a/net/mac80211/wpa.c
+++ b/net/mac80211/wpa.c
@@ -62,10 +62,10 @@ ieee80211_tx_h_michael_mic_add(struct ieee80211_tx_data *tx)
62 62
63 tail = MICHAEL_MIC_LEN; 63 tail = MICHAEL_MIC_LEN;
64 if (!info->control.hw_key) 64 if (!info->control.hw_key)
65 tail += TKIP_ICV_LEN; 65 tail += IEEE80211_TKIP_ICV_LEN;
66 66
67 if (WARN_ON(skb_tailroom(skb) < tail || 67 if (WARN_ON(skb_tailroom(skb) < tail ||
68 skb_headroom(skb) < TKIP_IV_LEN)) 68 skb_headroom(skb) < IEEE80211_TKIP_IV_LEN))
69 return TX_DROP; 69 return TX_DROP;
70 70
71 key = &tx->key->conf.key[NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY]; 71 key = &tx->key->conf.key[NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY];
@@ -198,15 +198,16 @@ static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
198 if (info->control.hw_key) 198 if (info->control.hw_key)
199 tail = 0; 199 tail = 0;
200 else 200 else
201 tail = TKIP_ICV_LEN; 201 tail = IEEE80211_TKIP_ICV_LEN;
202 202
203 if (WARN_ON(skb_tailroom(skb) < tail || 203 if (WARN_ON(skb_tailroom(skb) < tail ||
204 skb_headroom(skb) < TKIP_IV_LEN)) 204 skb_headroom(skb) < IEEE80211_TKIP_IV_LEN))
205 return -1; 205 return -1;
206 206
207 pos = skb_push(skb, TKIP_IV_LEN); 207 pos = skb_push(skb, IEEE80211_TKIP_IV_LEN);
208 memmove(pos, pos + TKIP_IV_LEN, hdrlen); 208 memmove(pos, pos + IEEE80211_TKIP_IV_LEN, hdrlen);
209 skb_set_network_header(skb, skb_network_offset(skb) + TKIP_IV_LEN); 209 skb_set_network_header(skb, skb_network_offset(skb) +
210 IEEE80211_TKIP_IV_LEN);
210 pos += hdrlen; 211 pos += hdrlen;
211 212
212 /* the HW only needs room for the IV, but not the actual IV */ 213 /* the HW only needs room for the IV, but not the actual IV */
@@ -227,7 +228,7 @@ static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
227 return 0; 228 return 0;
228 229
229 /* Add room for ICV */ 230 /* Add room for ICV */
230 skb_put(skb, TKIP_ICV_LEN); 231 skb_put(skb, IEEE80211_TKIP_ICV_LEN);
231 232
232 return ieee80211_tkip_encrypt_data(tx->local->wep_tx_tfm, 233 return ieee80211_tkip_encrypt_data(tx->local->wep_tx_tfm,
233 key, skb, pos, len); 234 key, skb, pos, len);
@@ -290,11 +291,11 @@ ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx)
290 return RX_DROP_UNUSABLE; 291 return RX_DROP_UNUSABLE;
291 292
292 /* Trim ICV */ 293 /* Trim ICV */
293 skb_trim(skb, skb->len - TKIP_ICV_LEN); 294 skb_trim(skb, skb->len - IEEE80211_TKIP_ICV_LEN);
294 295
295 /* Remove IV */ 296 /* Remove IV */
296 memmove(skb->data + TKIP_IV_LEN, skb->data, hdrlen); 297 memmove(skb->data + IEEE80211_TKIP_IV_LEN, skb->data, hdrlen);
297 skb_pull(skb, TKIP_IV_LEN); 298 skb_pull(skb, IEEE80211_TKIP_IV_LEN);
298 299
299 return RX_CONTINUE; 300 return RX_CONTINUE;
300} 301}
@@ -337,9 +338,9 @@ static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *scratch,
337 else 338 else
338 qos_tid = 0; 339 qos_tid = 0;
339 340
340 data_len = skb->len - hdrlen - CCMP_HDR_LEN; 341 data_len = skb->len - hdrlen - IEEE80211_CCMP_HDR_LEN;
341 if (encrypted) 342 if (encrypted)
342 data_len -= CCMP_MIC_LEN; 343 data_len -= IEEE80211_CCMP_MIC_LEN;
343 344
344 /* First block, b_0 */ 345 /* First block, b_0 */
345 b_0[0] = 0x59; /* flags: Adata: 1, M: 011, L: 001 */ 346 b_0[0] = 0x59; /* flags: Adata: 1, M: 011, L: 001 */
@@ -348,7 +349,7 @@ static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *scratch,
348 */ 349 */
349 b_0[1] = qos_tid | (mgmt << 4); 350 b_0[1] = qos_tid | (mgmt << 4);
350 memcpy(&b_0[2], hdr->addr2, ETH_ALEN); 351 memcpy(&b_0[2], hdr->addr2, ETH_ALEN);
351 memcpy(&b_0[8], pn, CCMP_PN_LEN); 352 memcpy(&b_0[8], pn, IEEE80211_CCMP_PN_LEN);
352 /* l(m) */ 353 /* l(m) */
353 put_unaligned_be16(data_len, &b_0[14]); 354 put_unaligned_be16(data_len, &b_0[14]);
354 355
@@ -424,15 +425,16 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
424 if (info->control.hw_key) 425 if (info->control.hw_key)
425 tail = 0; 426 tail = 0;
426 else 427 else
427 tail = CCMP_MIC_LEN; 428 tail = IEEE80211_CCMP_MIC_LEN;
428 429
429 if (WARN_ON(skb_tailroom(skb) < tail || 430 if (WARN_ON(skb_tailroom(skb) < tail ||
430 skb_headroom(skb) < CCMP_HDR_LEN)) 431 skb_headroom(skb) < IEEE80211_CCMP_HDR_LEN))
431 return -1; 432 return -1;
432 433
433 pos = skb_push(skb, CCMP_HDR_LEN); 434 pos = skb_push(skb, IEEE80211_CCMP_HDR_LEN);
434 memmove(pos, pos + CCMP_HDR_LEN, hdrlen); 435 memmove(pos, pos + IEEE80211_CCMP_HDR_LEN, hdrlen);
435 skb_set_network_header(skb, skb_network_offset(skb) + CCMP_HDR_LEN); 436 skb_set_network_header(skb, skb_network_offset(skb) +
437 IEEE80211_CCMP_HDR_LEN);
436 438
437 /* the HW only needs room for the IV, but not the actual IV */ 439 /* the HW only needs room for the IV, but not the actual IV */
438 if (info->control.hw_key && 440 if (info->control.hw_key &&
@@ -457,10 +459,10 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
457 if (info->control.hw_key) 459 if (info->control.hw_key)
458 return 0; 460 return 0;
459 461
460 pos += CCMP_HDR_LEN; 462 pos += IEEE80211_CCMP_HDR_LEN;
461 ccmp_special_blocks(skb, pn, scratch, 0); 463 ccmp_special_blocks(skb, pn, scratch, 0);
462 ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, scratch, pos, len, 464 ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, scratch, pos, len,
463 pos, skb_put(skb, CCMP_MIC_LEN)); 465 pos, skb_put(skb, IEEE80211_CCMP_MIC_LEN));
464 466
465 return 0; 467 return 0;
466} 468}
@@ -490,7 +492,7 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx)
490 struct ieee80211_key *key = rx->key; 492 struct ieee80211_key *key = rx->key;
491 struct sk_buff *skb = rx->skb; 493 struct sk_buff *skb = rx->skb;
492 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); 494 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
493 u8 pn[CCMP_PN_LEN]; 495 u8 pn[IEEE80211_CCMP_PN_LEN];
494 int data_len; 496 int data_len;
495 int queue; 497 int queue;
496 498
@@ -500,12 +502,13 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx)
500 !ieee80211_is_robust_mgmt_frame(hdr)) 502 !ieee80211_is_robust_mgmt_frame(hdr))
501 return RX_CONTINUE; 503 return RX_CONTINUE;
502 504
503 data_len = skb->len - hdrlen - CCMP_HDR_LEN - CCMP_MIC_LEN; 505 data_len = skb->len - hdrlen - IEEE80211_CCMP_HDR_LEN -
506 IEEE80211_CCMP_MIC_LEN;
504 if (!rx->sta || data_len < 0) 507 if (!rx->sta || data_len < 0)
505 return RX_DROP_UNUSABLE; 508 return RX_DROP_UNUSABLE;
506 509
507 if (status->flag & RX_FLAG_DECRYPTED) { 510 if (status->flag & RX_FLAG_DECRYPTED) {
508 if (!pskb_may_pull(rx->skb, hdrlen + CCMP_HDR_LEN)) 511 if (!pskb_may_pull(rx->skb, hdrlen + IEEE80211_CCMP_HDR_LEN))
509 return RX_DROP_UNUSABLE; 512 return RX_DROP_UNUSABLE;
510 } else { 513 } else {
511 if (skb_linearize(rx->skb)) 514 if (skb_linearize(rx->skb))
@@ -516,7 +519,7 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx)
516 519
517 queue = rx->security_idx; 520 queue = rx->security_idx;
518 521
519 if (memcmp(pn, key->u.ccmp.rx_pn[queue], CCMP_PN_LEN) <= 0) { 522 if (memcmp(pn, key->u.ccmp.rx_pn[queue], IEEE80211_CCMP_PN_LEN) <= 0) {
520 key->u.ccmp.replays++; 523 key->u.ccmp.replays++;
521 return RX_DROP_UNUSABLE; 524 return RX_DROP_UNUSABLE;
522 } 525 }
@@ -528,19 +531,20 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx)
528 531
529 if (ieee80211_aes_ccm_decrypt( 532 if (ieee80211_aes_ccm_decrypt(
530 key->u.ccmp.tfm, scratch, 533 key->u.ccmp.tfm, scratch,
531 skb->data + hdrlen + CCMP_HDR_LEN, data_len, 534 skb->data + hdrlen + IEEE80211_CCMP_HDR_LEN,
532 skb->data + skb->len - CCMP_MIC_LEN, 535 data_len,
533 skb->data + hdrlen + CCMP_HDR_LEN)) 536 skb->data + skb->len - IEEE80211_CCMP_MIC_LEN,
537 skb->data + hdrlen + IEEE80211_CCMP_HDR_LEN))
534 return RX_DROP_UNUSABLE; 538 return RX_DROP_UNUSABLE;
535 } 539 }
536 540
537 memcpy(key->u.ccmp.rx_pn[queue], pn, CCMP_PN_LEN); 541 memcpy(key->u.ccmp.rx_pn[queue], pn, IEEE80211_CCMP_PN_LEN);
538 542
539 /* Remove CCMP header and MIC */ 543 /* Remove CCMP header and MIC */
540 if (pskb_trim(skb, skb->len - CCMP_MIC_LEN)) 544 if (pskb_trim(skb, skb->len - IEEE80211_CCMP_MIC_LEN))
541 return RX_DROP_UNUSABLE; 545 return RX_DROP_UNUSABLE;
542 memmove(skb->data + CCMP_HDR_LEN, skb->data, hdrlen); 546 memmove(skb->data + IEEE80211_CCMP_HDR_LEN, skb->data, hdrlen);
543 skb_pull(skb, CCMP_HDR_LEN); 547 skb_pull(skb, IEEE80211_CCMP_HDR_LEN);
544 548
545 return RX_CONTINUE; 549 return RX_CONTINUE;
546} 550}
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 01e41191f1bf..e4df77490229 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -34,13 +34,12 @@
34MODULE_AUTHOR("Johannes Berg"); 34MODULE_AUTHOR("Johannes Berg");
35MODULE_LICENSE("GPL"); 35MODULE_LICENSE("GPL");
36MODULE_DESCRIPTION("wireless configuration support"); 36MODULE_DESCRIPTION("wireless configuration support");
37MODULE_ALIAS_GENL_FAMILY(NL80211_GENL_NAME);
37 38
38/* RCU-protected (and cfg80211_mutex for writers) */ 39/* RCU-protected (and RTNL for writers) */
39LIST_HEAD(cfg80211_rdev_list); 40LIST_HEAD(cfg80211_rdev_list);
40int cfg80211_rdev_list_generation; 41int cfg80211_rdev_list_generation;
41 42
42DEFINE_MUTEX(cfg80211_mutex);
43
44/* for debugfs */ 43/* for debugfs */
45static struct dentry *ieee80211_debugfs_dir; 44static struct dentry *ieee80211_debugfs_dir;
46 45
@@ -52,12 +51,11 @@ module_param(cfg80211_disable_40mhz_24ghz, bool, 0644);
52MODULE_PARM_DESC(cfg80211_disable_40mhz_24ghz, 51MODULE_PARM_DESC(cfg80211_disable_40mhz_24ghz,
53 "Disable 40MHz support in the 2.4GHz band"); 52 "Disable 40MHz support in the 2.4GHz band");
54 53
55/* requires cfg80211_mutex to be held! */
56struct cfg80211_registered_device *cfg80211_rdev_by_wiphy_idx(int wiphy_idx) 54struct cfg80211_registered_device *cfg80211_rdev_by_wiphy_idx(int wiphy_idx)
57{ 55{
58 struct cfg80211_registered_device *result = NULL, *rdev; 56 struct cfg80211_registered_device *result = NULL, *rdev;
59 57
60 assert_cfg80211_lock(); 58 ASSERT_RTNL();
61 59
62 list_for_each_entry(rdev, &cfg80211_rdev_list, list) { 60 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
63 if (rdev->wiphy_idx == wiphy_idx) { 61 if (rdev->wiphy_idx == wiphy_idx) {
@@ -76,12 +74,11 @@ int get_wiphy_idx(struct wiphy *wiphy)
76 return rdev->wiphy_idx; 74 return rdev->wiphy_idx;
77} 75}
78 76
79/* requires cfg80211_rdev_mutex to be held! */
80struct wiphy *wiphy_idx_to_wiphy(int wiphy_idx) 77struct wiphy *wiphy_idx_to_wiphy(int wiphy_idx)
81{ 78{
82 struct cfg80211_registered_device *rdev; 79 struct cfg80211_registered_device *rdev;
83 80
84 assert_cfg80211_lock(); 81 ASSERT_RTNL();
85 82
86 rdev = cfg80211_rdev_by_wiphy_idx(wiphy_idx); 83 rdev = cfg80211_rdev_by_wiphy_idx(wiphy_idx);
87 if (!rdev) 84 if (!rdev)
@@ -89,35 +86,13 @@ struct wiphy *wiphy_idx_to_wiphy(int wiphy_idx)
89 return &rdev->wiphy; 86 return &rdev->wiphy;
90} 87}
91 88
92struct cfg80211_registered_device *
93cfg80211_get_dev_from_ifindex(struct net *net, int ifindex)
94{
95 struct cfg80211_registered_device *rdev = ERR_PTR(-ENODEV);
96 struct net_device *dev;
97
98 mutex_lock(&cfg80211_mutex);
99 dev = dev_get_by_index(net, ifindex);
100 if (!dev)
101 goto out;
102 if (dev->ieee80211_ptr) {
103 rdev = wiphy_to_dev(dev->ieee80211_ptr->wiphy);
104 mutex_lock(&rdev->mtx);
105 } else
106 rdev = ERR_PTR(-ENODEV);
107 dev_put(dev);
108 out:
109 mutex_unlock(&cfg80211_mutex);
110 return rdev;
111}
112
113/* requires cfg80211_mutex to be held */
114int cfg80211_dev_rename(struct cfg80211_registered_device *rdev, 89int cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
115 char *newname) 90 char *newname)
116{ 91{
117 struct cfg80211_registered_device *rdev2; 92 struct cfg80211_registered_device *rdev2;
118 int wiphy_idx, taken = -1, result, digits; 93 int wiphy_idx, taken = -1, result, digits;
119 94
120 assert_cfg80211_lock(); 95 ASSERT_RTNL();
121 96
122 /* prohibit calling the thing phy%d when %d is not its number */ 97 /* prohibit calling the thing phy%d when %d is not its number */
123 sscanf(newname, PHY_NAME "%d%n", &wiphy_idx, &taken); 98 sscanf(newname, PHY_NAME "%d%n", &wiphy_idx, &taken);
@@ -215,8 +190,7 @@ static void cfg80211_rfkill_poll(struct rfkill *rfkill, void *data)
215void cfg80211_stop_p2p_device(struct cfg80211_registered_device *rdev, 190void cfg80211_stop_p2p_device(struct cfg80211_registered_device *rdev,
216 struct wireless_dev *wdev) 191 struct wireless_dev *wdev)
217{ 192{
218 lockdep_assert_held(&rdev->devlist_mtx); 193 ASSERT_RTNL();
219 lockdep_assert_held(&rdev->sched_scan_mtx);
220 194
221 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_P2P_DEVICE)) 195 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_P2P_DEVICE))
222 return; 196 return;
@@ -230,18 +204,15 @@ void cfg80211_stop_p2p_device(struct cfg80211_registered_device *rdev,
230 rdev->opencount--; 204 rdev->opencount--;
231 205
232 if (rdev->scan_req && rdev->scan_req->wdev == wdev) { 206 if (rdev->scan_req && rdev->scan_req->wdev == wdev) {
233 bool busy = work_busy(&rdev->scan_done_wk);
234
235 /* 207 /*
236 * If the work isn't pending or running (in which case it would 208 * If the scan request wasn't notified as done, set it
237 * be waiting for the lock we hold) the driver didn't properly 209 * to aborted and leak it after a warning. The driver
238 * cancel the scan when the interface was removed. In this case 210 * should have notified us that it ended at the latest
239 * warn and leak the scan request object to not crash later. 211 * during rdev_stop_p2p_device().
240 */ 212 */
241 WARN_ON(!busy); 213 if (WARN_ON(!rdev->scan_req->notified))
242 214 rdev->scan_req->aborted = true;
243 rdev->scan_req->aborted = true; 215 ___cfg80211_scan_done(rdev, !rdev->scan_req->notified);
244 ___cfg80211_scan_done(rdev, !busy);
245 } 216 }
246} 217}
247 218
@@ -255,8 +226,6 @@ static int cfg80211_rfkill_set_block(void *data, bool blocked)
255 226
256 rtnl_lock(); 227 rtnl_lock();
257 228
258 /* read-only iteration need not hold the devlist_mtx */
259
260 list_for_each_entry(wdev, &rdev->wdev_list, list) { 229 list_for_each_entry(wdev, &rdev->wdev_list, list) {
261 if (wdev->netdev) { 230 if (wdev->netdev) {
262 dev_close(wdev->netdev); 231 dev_close(wdev->netdev);
@@ -265,12 +234,7 @@ static int cfg80211_rfkill_set_block(void *data, bool blocked)
265 /* otherwise, check iftype */ 234 /* otherwise, check iftype */
266 switch (wdev->iftype) { 235 switch (wdev->iftype) {
267 case NL80211_IFTYPE_P2P_DEVICE: 236 case NL80211_IFTYPE_P2P_DEVICE:
268 /* but this requires it */
269 mutex_lock(&rdev->devlist_mtx);
270 mutex_lock(&rdev->sched_scan_mtx);
271 cfg80211_stop_p2p_device(rdev, wdev); 237 cfg80211_stop_p2p_device(rdev, wdev);
272 mutex_unlock(&rdev->sched_scan_mtx);
273 mutex_unlock(&rdev->devlist_mtx);
274 break; 238 break;
275 default: 239 default:
276 break; 240 break;
@@ -298,10 +262,7 @@ static void cfg80211_event_work(struct work_struct *work)
298 event_work); 262 event_work);
299 263
300 rtnl_lock(); 264 rtnl_lock();
301 cfg80211_lock_rdev(rdev);
302
303 cfg80211_process_rdev_events(rdev); 265 cfg80211_process_rdev_events(rdev);
304 cfg80211_unlock_rdev(rdev);
305 rtnl_unlock(); 266 rtnl_unlock();
306} 267}
307 268
@@ -309,7 +270,7 @@ static void cfg80211_event_work(struct work_struct *work)
309 270
310struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv) 271struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv)
311{ 272{
312 static int wiphy_counter; 273 static atomic_t wiphy_counter = ATOMIC_INIT(0);
313 274
314 struct cfg80211_registered_device *rdev; 275 struct cfg80211_registered_device *rdev;
315 int alloc_size; 276 int alloc_size;
@@ -331,26 +292,18 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv)
331 292
332 rdev->ops = ops; 293 rdev->ops = ops;
333 294
334 mutex_lock(&cfg80211_mutex); 295 rdev->wiphy_idx = atomic_inc_return(&wiphy_counter);
335
336 rdev->wiphy_idx = wiphy_counter++;
337 296
338 if (unlikely(rdev->wiphy_idx < 0)) { 297 if (unlikely(rdev->wiphy_idx < 0)) {
339 wiphy_counter--;
340 mutex_unlock(&cfg80211_mutex);
341 /* ugh, wrapped! */ 298 /* ugh, wrapped! */
299 atomic_dec(&wiphy_counter);
342 kfree(rdev); 300 kfree(rdev);
343 return NULL; 301 return NULL;
344 } 302 }
345 303
346 mutex_unlock(&cfg80211_mutex);
347
348 /* give it a proper name */ 304 /* give it a proper name */
349 dev_set_name(&rdev->wiphy.dev, PHY_NAME "%d", rdev->wiphy_idx); 305 dev_set_name(&rdev->wiphy.dev, PHY_NAME "%d", rdev->wiphy_idx);
350 306
351 mutex_init(&rdev->mtx);
352 mutex_init(&rdev->devlist_mtx);
353 mutex_init(&rdev->sched_scan_mtx);
354 INIT_LIST_HEAD(&rdev->wdev_list); 307 INIT_LIST_HEAD(&rdev->wdev_list);
355 INIT_LIST_HEAD(&rdev->beacon_registrations); 308 INIT_LIST_HEAD(&rdev->beacon_registrations);
356 spin_lock_init(&rdev->beacon_registrations_lock); 309 spin_lock_init(&rdev->beacon_registrations_lock);
@@ -598,11 +551,11 @@ int wiphy_register(struct wiphy *wiphy)
598 /* check and set up bitrates */ 551 /* check and set up bitrates */
599 ieee80211_set_bitrate_flags(wiphy); 552 ieee80211_set_bitrate_flags(wiphy);
600 553
601 mutex_lock(&cfg80211_mutex); 554 rtnl_lock();
602 555
603 res = device_add(&rdev->wiphy.dev); 556 res = device_add(&rdev->wiphy.dev);
604 if (res) { 557 if (res) {
605 mutex_unlock(&cfg80211_mutex); 558 rtnl_unlock();
606 return res; 559 return res;
607 } 560 }
608 561
@@ -631,25 +584,18 @@ int wiphy_register(struct wiphy *wiphy)
631 } 584 }
632 585
633 cfg80211_debugfs_rdev_add(rdev); 586 cfg80211_debugfs_rdev_add(rdev);
634 mutex_unlock(&cfg80211_mutex);
635 587
636 /*
637 * due to a locking dependency this has to be outside of the
638 * cfg80211_mutex lock
639 */
640 res = rfkill_register(rdev->rfkill); 588 res = rfkill_register(rdev->rfkill);
641 if (res) { 589 if (res) {
642 device_del(&rdev->wiphy.dev); 590 device_del(&rdev->wiphy.dev);
643 591
644 mutex_lock(&cfg80211_mutex);
645 debugfs_remove_recursive(rdev->wiphy.debugfsdir); 592 debugfs_remove_recursive(rdev->wiphy.debugfsdir);
646 list_del_rcu(&rdev->list); 593 list_del_rcu(&rdev->list);
647 wiphy_regulatory_deregister(wiphy); 594 wiphy_regulatory_deregister(wiphy);
648 mutex_unlock(&cfg80211_mutex); 595 rtnl_unlock();
649 return res; 596 return res;
650 } 597 }
651 598
652 rtnl_lock();
653 rdev->wiphy.registered = true; 599 rdev->wiphy.registered = true;
654 rtnl_unlock(); 600 rtnl_unlock();
655 return 0; 601 return 0;
@@ -679,25 +625,19 @@ void wiphy_unregister(struct wiphy *wiphy)
679{ 625{
680 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 626 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
681 627
682 rtnl_lock();
683 rdev->wiphy.registered = false;
684 rtnl_unlock();
685
686 rfkill_unregister(rdev->rfkill);
687
688 /* protect the device list */
689 mutex_lock(&cfg80211_mutex);
690
691 wait_event(rdev->dev_wait, ({ 628 wait_event(rdev->dev_wait, ({
692 int __count; 629 int __count;
693 mutex_lock(&rdev->devlist_mtx); 630 rtnl_lock();
694 __count = rdev->opencount; 631 __count = rdev->opencount;
695 mutex_unlock(&rdev->devlist_mtx); 632 rtnl_unlock();
696 __count == 0; })); 633 __count == 0; }));
697 634
698 mutex_lock(&rdev->devlist_mtx); 635 rtnl_lock();
636 rdev->wiphy.registered = false;
637
638 rfkill_unregister(rdev->rfkill);
639
699 BUG_ON(!list_empty(&rdev->wdev_list)); 640 BUG_ON(!list_empty(&rdev->wdev_list));
700 mutex_unlock(&rdev->devlist_mtx);
701 641
702 /* 642 /*
703 * First remove the hardware from everywhere, this makes 643 * First remove the hardware from everywhere, this makes
@@ -708,20 +648,6 @@ void wiphy_unregister(struct wiphy *wiphy)
708 synchronize_rcu(); 648 synchronize_rcu();
709 649
710 /* 650 /*
711 * Try to grab rdev->mtx. If a command is still in progress,
712 * hopefully the driver will refuse it since it's tearing
713 * down the device already. We wait for this command to complete
714 * before unlinking the item from the list.
715 * Note: as codified by the BUG_ON above we cannot get here if
716 * a virtual interface is still present. Hence, we can only get
717 * to lock contention here if userspace issues a command that
718 * identified the hardware by wiphy index.
719 */
720 cfg80211_lock_rdev(rdev);
721 /* nothing */
722 cfg80211_unlock_rdev(rdev);
723
724 /*
725 * If this device got a regulatory hint tell core its 651 * If this device got a regulatory hint tell core its
726 * free to listen now to a new shiny device regulatory hint 652 * free to listen now to a new shiny device regulatory hint
727 */ 653 */
@@ -730,15 +656,17 @@ void wiphy_unregister(struct wiphy *wiphy)
730 cfg80211_rdev_list_generation++; 656 cfg80211_rdev_list_generation++;
731 device_del(&rdev->wiphy.dev); 657 device_del(&rdev->wiphy.dev);
732 658
733 mutex_unlock(&cfg80211_mutex); 659 rtnl_unlock();
734 660
735 flush_work(&rdev->scan_done_wk); 661 flush_work(&rdev->scan_done_wk);
736 cancel_work_sync(&rdev->conn_work); 662 cancel_work_sync(&rdev->conn_work);
737 flush_work(&rdev->event_work); 663 flush_work(&rdev->event_work);
738 cancel_delayed_work_sync(&rdev->dfs_update_channels_wk); 664 cancel_delayed_work_sync(&rdev->dfs_update_channels_wk);
739 665
740 if (rdev->wowlan && rdev->ops->set_wakeup) 666#ifdef CONFIG_PM
667 if (rdev->wiphy.wowlan_config && rdev->ops->set_wakeup)
741 rdev_set_wakeup(rdev, false); 668 rdev_set_wakeup(rdev, false);
669#endif
742 cfg80211_rdev_free_wowlan(rdev); 670 cfg80211_rdev_free_wowlan(rdev);
743} 671}
744EXPORT_SYMBOL(wiphy_unregister); 672EXPORT_SYMBOL(wiphy_unregister);
@@ -748,9 +676,6 @@ void cfg80211_dev_free(struct cfg80211_registered_device *rdev)
748 struct cfg80211_internal_bss *scan, *tmp; 676 struct cfg80211_internal_bss *scan, *tmp;
749 struct cfg80211_beacon_registration *reg, *treg; 677 struct cfg80211_beacon_registration *reg, *treg;
750 rfkill_destroy(rdev->rfkill); 678 rfkill_destroy(rdev->rfkill);
751 mutex_destroy(&rdev->mtx);
752 mutex_destroy(&rdev->devlist_mtx);
753 mutex_destroy(&rdev->sched_scan_mtx);
754 list_for_each_entry_safe(reg, treg, &rdev->beacon_registrations, list) { 679 list_for_each_entry_safe(reg, treg, &rdev->beacon_registrations, list) {
755 list_del(&reg->list); 680 list_del(&reg->list);
756 kfree(reg); 681 kfree(reg);
@@ -775,36 +700,6 @@ void wiphy_rfkill_set_hw_state(struct wiphy *wiphy, bool blocked)
775} 700}
776EXPORT_SYMBOL(wiphy_rfkill_set_hw_state); 701EXPORT_SYMBOL(wiphy_rfkill_set_hw_state);
777 702
778static void wdev_cleanup_work(struct work_struct *work)
779{
780 struct wireless_dev *wdev;
781 struct cfg80211_registered_device *rdev;
782
783 wdev = container_of(work, struct wireless_dev, cleanup_work);
784 rdev = wiphy_to_dev(wdev->wiphy);
785
786 mutex_lock(&rdev->sched_scan_mtx);
787
788 if (WARN_ON(rdev->scan_req && rdev->scan_req->wdev == wdev)) {
789 rdev->scan_req->aborted = true;
790 ___cfg80211_scan_done(rdev, true);
791 }
792
793 if (WARN_ON(rdev->sched_scan_req &&
794 rdev->sched_scan_req->dev == wdev->netdev)) {
795 __cfg80211_stop_sched_scan(rdev, false);
796 }
797
798 mutex_unlock(&rdev->sched_scan_mtx);
799
800 mutex_lock(&rdev->devlist_mtx);
801 rdev->opencount--;
802 mutex_unlock(&rdev->devlist_mtx);
803 wake_up(&rdev->dev_wait);
804
805 dev_put(wdev->netdev);
806}
807
808void cfg80211_unregister_wdev(struct wireless_dev *wdev) 703void cfg80211_unregister_wdev(struct wireless_dev *wdev)
809{ 704{
810 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 705 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
@@ -814,8 +709,6 @@ void cfg80211_unregister_wdev(struct wireless_dev *wdev)
814 if (WARN_ON(wdev->netdev)) 709 if (WARN_ON(wdev->netdev))
815 return; 710 return;
816 711
817 mutex_lock(&rdev->devlist_mtx);
818 mutex_lock(&rdev->sched_scan_mtx);
819 list_del_rcu(&wdev->list); 712 list_del_rcu(&wdev->list);
820 rdev->devlist_generation++; 713 rdev->devlist_generation++;
821 714
@@ -827,8 +720,6 @@ void cfg80211_unregister_wdev(struct wireless_dev *wdev)
827 WARN_ON_ONCE(1); 720 WARN_ON_ONCE(1);
828 break; 721 break;
829 } 722 }
830 mutex_unlock(&rdev->sched_scan_mtx);
831 mutex_unlock(&rdev->devlist_mtx);
832} 723}
833EXPORT_SYMBOL(cfg80211_unregister_wdev); 724EXPORT_SYMBOL(cfg80211_unregister_wdev);
834 725
@@ -847,7 +738,7 @@ void cfg80211_update_iface_num(struct cfg80211_registered_device *rdev,
847} 738}
848 739
849void cfg80211_leave(struct cfg80211_registered_device *rdev, 740void cfg80211_leave(struct cfg80211_registered_device *rdev,
850 struct wireless_dev *wdev) 741 struct wireless_dev *wdev)
851{ 742{
852 struct net_device *dev = wdev->netdev; 743 struct net_device *dev = wdev->netdev;
853 744
@@ -857,9 +748,7 @@ void cfg80211_leave(struct cfg80211_registered_device *rdev,
857 break; 748 break;
858 case NL80211_IFTYPE_P2P_CLIENT: 749 case NL80211_IFTYPE_P2P_CLIENT:
859 case NL80211_IFTYPE_STATION: 750 case NL80211_IFTYPE_STATION:
860 mutex_lock(&rdev->sched_scan_mtx);
861 __cfg80211_stop_sched_scan(rdev, false); 751 __cfg80211_stop_sched_scan(rdev, false);
862 mutex_unlock(&rdev->sched_scan_mtx);
863 752
864 wdev_lock(wdev); 753 wdev_lock(wdev);
865#ifdef CONFIG_CFG80211_WEXT 754#ifdef CONFIG_CFG80211_WEXT
@@ -868,8 +757,8 @@ void cfg80211_leave(struct cfg80211_registered_device *rdev,
868 wdev->wext.ie_len = 0; 757 wdev->wext.ie_len = 0;
869 wdev->wext.connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC; 758 wdev->wext.connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
870#endif 759#endif
871 __cfg80211_disconnect(rdev, dev, 760 cfg80211_disconnect(rdev, dev,
872 WLAN_REASON_DEAUTH_LEAVING, true); 761 WLAN_REASON_DEAUTH_LEAVING, true);
873 wdev_unlock(wdev); 762 wdev_unlock(wdev);
874 break; 763 break;
875 case NL80211_IFTYPE_MESH_POINT: 764 case NL80211_IFTYPE_MESH_POINT:
@@ -911,13 +800,11 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
911 * are added with nl80211. 800 * are added with nl80211.
912 */ 801 */
913 mutex_init(&wdev->mtx); 802 mutex_init(&wdev->mtx);
914 INIT_WORK(&wdev->cleanup_work, wdev_cleanup_work);
915 INIT_LIST_HEAD(&wdev->event_list); 803 INIT_LIST_HEAD(&wdev->event_list);
916 spin_lock_init(&wdev->event_lock); 804 spin_lock_init(&wdev->event_lock);
917 INIT_LIST_HEAD(&wdev->mgmt_registrations); 805 INIT_LIST_HEAD(&wdev->mgmt_registrations);
918 spin_lock_init(&wdev->mgmt_registrations_lock); 806 spin_lock_init(&wdev->mgmt_registrations_lock);
919 807
920 mutex_lock(&rdev->devlist_mtx);
921 wdev->identifier = ++rdev->wdev_id; 808 wdev->identifier = ++rdev->wdev_id;
922 list_add_rcu(&wdev->list, &rdev->wdev_list); 809 list_add_rcu(&wdev->list, &rdev->wdev_list);
923 rdev->devlist_generation++; 810 rdev->devlist_generation++;
@@ -930,7 +817,6 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
930 } 817 }
931 wdev->netdev = dev; 818 wdev->netdev = dev;
932 wdev->sme_state = CFG80211_SME_IDLE; 819 wdev->sme_state = CFG80211_SME_IDLE;
933 mutex_unlock(&rdev->devlist_mtx);
934#ifdef CONFIG_CFG80211_WEXT 820#ifdef CONFIG_CFG80211_WEXT
935 wdev->wext.default_key = -1; 821 wdev->wext.default_key = -1;
936 wdev->wext.default_mgmt_key = -1; 822 wdev->wext.default_mgmt_key = -1;
@@ -956,26 +842,22 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
956 break; 842 break;
957 case NETDEV_DOWN: 843 case NETDEV_DOWN:
958 cfg80211_update_iface_num(rdev, wdev->iftype, -1); 844 cfg80211_update_iface_num(rdev, wdev->iftype, -1);
959 dev_hold(dev); 845 if (rdev->scan_req && rdev->scan_req->wdev == wdev) {
960 queue_work(cfg80211_wq, &wdev->cleanup_work); 846 if (WARN_ON(!rdev->scan_req->notified))
847 rdev->scan_req->aborted = true;
848 ___cfg80211_scan_done(rdev, true);
849 }
850
851 if (WARN_ON(rdev->sched_scan_req &&
852 rdev->sched_scan_req->dev == wdev->netdev)) {
853 __cfg80211_stop_sched_scan(rdev, false);
854 }
855
856 rdev->opencount--;
857 wake_up(&rdev->dev_wait);
961 break; 858 break;
962 case NETDEV_UP: 859 case NETDEV_UP:
963 /*
964 * If we have a really quick DOWN/UP succession we may
965 * have this work still pending ... cancel it and see
966 * if it was pending, in which case we need to account
967 * for some of the work it would have done.
968 */
969 if (cancel_work_sync(&wdev->cleanup_work)) {
970 mutex_lock(&rdev->devlist_mtx);
971 rdev->opencount--;
972 mutex_unlock(&rdev->devlist_mtx);
973 dev_put(dev);
974 }
975 cfg80211_update_iface_num(rdev, wdev->iftype, 1); 860 cfg80211_update_iface_num(rdev, wdev->iftype, 1);
976 cfg80211_lock_rdev(rdev);
977 mutex_lock(&rdev->devlist_mtx);
978 mutex_lock(&rdev->sched_scan_mtx);
979 wdev_lock(wdev); 861 wdev_lock(wdev);
980 switch (wdev->iftype) { 862 switch (wdev->iftype) {
981#ifdef CONFIG_CFG80211_WEXT 863#ifdef CONFIG_CFG80211_WEXT
@@ -1007,10 +889,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
1007 break; 889 break;
1008 } 890 }
1009 wdev_unlock(wdev); 891 wdev_unlock(wdev);
1010 mutex_unlock(&rdev->sched_scan_mtx);
1011 rdev->opencount++; 892 rdev->opencount++;
1012 mutex_unlock(&rdev->devlist_mtx);
1013 cfg80211_unlock_rdev(rdev);
1014 893
1015 /* 894 /*
1016 * Configure power management to the driver here so that its 895 * Configure power management to the driver here so that its
@@ -1027,12 +906,6 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
1027 break; 906 break;
1028 case NETDEV_UNREGISTER: 907 case NETDEV_UNREGISTER:
1029 /* 908 /*
1030 * NB: cannot take rdev->mtx here because this may be
1031 * called within code protected by it when interfaces
1032 * are removed with nl80211.
1033 */
1034 mutex_lock(&rdev->devlist_mtx);
1035 /*
1036 * It is possible to get NETDEV_UNREGISTER 909 * It is possible to get NETDEV_UNREGISTER
1037 * multiple times. To detect that, check 910 * multiple times. To detect that, check
1038 * that the interface is still on the list 911 * that the interface is still on the list
@@ -1048,7 +921,6 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
1048 kfree(wdev->wext.keys); 921 kfree(wdev->wext.keys);
1049#endif 922#endif
1050 } 923 }
1051 mutex_unlock(&rdev->devlist_mtx);
1052 /* 924 /*
1053 * synchronise (so that we won't find this netdev 925 * synchronise (so that we won't find this netdev
1054 * from other code any more) and then clear the list 926 * from other code any more) and then clear the list
@@ -1068,9 +940,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
1068 return notifier_from_errno(-EOPNOTSUPP); 940 return notifier_from_errno(-EOPNOTSUPP);
1069 if (rfkill_blocked(rdev->rfkill)) 941 if (rfkill_blocked(rdev->rfkill))
1070 return notifier_from_errno(-ERFKILL); 942 return notifier_from_errno(-ERFKILL);
1071 mutex_lock(&rdev->devlist_mtx);
1072 ret = cfg80211_can_add_interface(rdev, wdev->iftype); 943 ret = cfg80211_can_add_interface(rdev, wdev->iftype);
1073 mutex_unlock(&rdev->devlist_mtx);
1074 if (ret) 944 if (ret)
1075 return notifier_from_errno(ret); 945 return notifier_from_errno(ret);
1076 break; 946 break;
@@ -1088,12 +958,10 @@ static void __net_exit cfg80211_pernet_exit(struct net *net)
1088 struct cfg80211_registered_device *rdev; 958 struct cfg80211_registered_device *rdev;
1089 959
1090 rtnl_lock(); 960 rtnl_lock();
1091 mutex_lock(&cfg80211_mutex);
1092 list_for_each_entry(rdev, &cfg80211_rdev_list, list) { 961 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
1093 if (net_eq(wiphy_net(&rdev->wiphy), net)) 962 if (net_eq(wiphy_net(&rdev->wiphy), net))
1094 WARN_ON(cfg80211_switch_netns(rdev, &init_net)); 963 WARN_ON(cfg80211_switch_netns(rdev, &init_net));
1095 } 964 }
1096 mutex_unlock(&cfg80211_mutex);
1097 rtnl_unlock(); 965 rtnl_unlock();
1098} 966}
1099 967
diff --git a/net/wireless/core.h b/net/wireless/core.h
index fd35dae547c4..a65eaf8a84c1 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -5,7 +5,6 @@
5 */ 5 */
6#ifndef __NET_WIRELESS_CORE_H 6#ifndef __NET_WIRELESS_CORE_H
7#define __NET_WIRELESS_CORE_H 7#define __NET_WIRELESS_CORE_H
8#include <linux/mutex.h>
9#include <linux/list.h> 8#include <linux/list.h>
10#include <linux/netdevice.h> 9#include <linux/netdevice.h>
11#include <linux/rbtree.h> 10#include <linux/rbtree.h>
@@ -23,11 +22,6 @@
23struct cfg80211_registered_device { 22struct cfg80211_registered_device {
24 const struct cfg80211_ops *ops; 23 const struct cfg80211_ops *ops;
25 struct list_head list; 24 struct list_head list;
26 /* we hold this mutex during any call so that
27 * we cannot do multiple calls at once, and also
28 * to avoid the deregister call to proceed while
29 * any call is in progress */
30 struct mutex mtx;
31 25
32 /* rfkill support */ 26 /* rfkill support */
33 struct rfkill_ops rfkill_ops; 27 struct rfkill_ops rfkill_ops;
@@ -49,9 +43,7 @@ struct cfg80211_registered_device {
49 /* wiphy index, internal only */ 43 /* wiphy index, internal only */
50 int wiphy_idx; 44 int wiphy_idx;
51 45
52 /* associated wireless interfaces */ 46 /* associated wireless interfaces, protected by rtnl or RCU */
53 struct mutex devlist_mtx;
54 /* protected by devlist_mtx or RCU */
55 struct list_head wdev_list; 47 struct list_head wdev_list;
56 int devlist_generation, wdev_id; 48 int devlist_generation, wdev_id;
57 int opencount; /* also protected by devlist_mtx */ 49 int opencount; /* also protected by devlist_mtx */
@@ -75,8 +67,6 @@ struct cfg80211_registered_device {
75 struct work_struct scan_done_wk; 67 struct work_struct scan_done_wk;
76 struct work_struct sched_scan_results_wk; 68 struct work_struct sched_scan_results_wk;
77 69
78 struct mutex sched_scan_mtx;
79
80#ifdef CONFIG_NL80211_TESTMODE 70#ifdef CONFIG_NL80211_TESTMODE
81 struct genl_info *testmode_info; 71 struct genl_info *testmode_info;
82#endif 72#endif
@@ -84,8 +74,6 @@ struct cfg80211_registered_device {
84 struct work_struct conn_work; 74 struct work_struct conn_work;
85 struct work_struct event_work; 75 struct work_struct event_work;
86 76
87 struct cfg80211_wowlan *wowlan;
88
89 struct delayed_work dfs_update_channels_wk; 77 struct delayed_work dfs_update_channels_wk;
90 78
91 /* netlink port which started critical protocol (0 means not started) */ 79 /* netlink port which started critical protocol (0 means not started) */
@@ -106,29 +94,26 @@ struct cfg80211_registered_device *wiphy_to_dev(struct wiphy *wiphy)
106static inline void 94static inline void
107cfg80211_rdev_free_wowlan(struct cfg80211_registered_device *rdev) 95cfg80211_rdev_free_wowlan(struct cfg80211_registered_device *rdev)
108{ 96{
97#ifdef CONFIG_PM
109 int i; 98 int i;
110 99
111 if (!rdev->wowlan) 100 if (!rdev->wiphy.wowlan_config)
112 return; 101 return;
113 for (i = 0; i < rdev->wowlan->n_patterns; i++) 102 for (i = 0; i < rdev->wiphy.wowlan_config->n_patterns; i++)
114 kfree(rdev->wowlan->patterns[i].mask); 103 kfree(rdev->wiphy.wowlan_config->patterns[i].mask);
115 kfree(rdev->wowlan->patterns); 104 kfree(rdev->wiphy.wowlan_config->patterns);
116 if (rdev->wowlan->tcp && rdev->wowlan->tcp->sock) 105 if (rdev->wiphy.wowlan_config->tcp &&
117 sock_release(rdev->wowlan->tcp->sock); 106 rdev->wiphy.wowlan_config->tcp->sock)
118 kfree(rdev->wowlan->tcp); 107 sock_release(rdev->wiphy.wowlan_config->tcp->sock);
119 kfree(rdev->wowlan); 108 kfree(rdev->wiphy.wowlan_config->tcp);
109 kfree(rdev->wiphy.wowlan_config);
110#endif
120} 111}
121 112
122extern struct workqueue_struct *cfg80211_wq; 113extern struct workqueue_struct *cfg80211_wq;
123extern struct mutex cfg80211_mutex;
124extern struct list_head cfg80211_rdev_list; 114extern struct list_head cfg80211_rdev_list;
125extern int cfg80211_rdev_list_generation; 115extern int cfg80211_rdev_list_generation;
126 116
127static inline void assert_cfg80211_lock(void)
128{
129 lockdep_assert_held(&cfg80211_mutex);
130}
131
132struct cfg80211_internal_bss { 117struct cfg80211_internal_bss {
133 struct list_head list; 118 struct list_head list;
134 struct list_head hidden_list; 119 struct list_head hidden_list;
@@ -161,27 +146,11 @@ static inline void cfg80211_unhold_bss(struct cfg80211_internal_bss *bss)
161struct cfg80211_registered_device *cfg80211_rdev_by_wiphy_idx(int wiphy_idx); 146struct cfg80211_registered_device *cfg80211_rdev_by_wiphy_idx(int wiphy_idx);
162int get_wiphy_idx(struct wiphy *wiphy); 147int get_wiphy_idx(struct wiphy *wiphy);
163 148
164/* requires cfg80211_rdev_mutex to be held! */
165struct wiphy *wiphy_idx_to_wiphy(int wiphy_idx); 149struct wiphy *wiphy_idx_to_wiphy(int wiphy_idx);
166 150
167/* identical to cfg80211_get_dev_from_info but only operate on ifindex */
168extern struct cfg80211_registered_device *
169cfg80211_get_dev_from_ifindex(struct net *net, int ifindex);
170
171int cfg80211_switch_netns(struct cfg80211_registered_device *rdev, 151int cfg80211_switch_netns(struct cfg80211_registered_device *rdev,
172 struct net *net); 152 struct net *net);
173 153
174static inline void cfg80211_lock_rdev(struct cfg80211_registered_device *rdev)
175{
176 mutex_lock(&rdev->mtx);
177}
178
179static inline void cfg80211_unlock_rdev(struct cfg80211_registered_device *rdev)
180{
181 BUG_ON(IS_ERR(rdev) || !rdev);
182 mutex_unlock(&rdev->mtx);
183}
184
185static inline void wdev_lock(struct wireless_dev *wdev) 154static inline void wdev_lock(struct wireless_dev *wdev)
186 __acquires(wdev) 155 __acquires(wdev)
187{ 156{
@@ -196,7 +165,7 @@ static inline void wdev_unlock(struct wireless_dev *wdev)
196 mutex_unlock(&wdev->mtx); 165 mutex_unlock(&wdev->mtx);
197} 166}
198 167
199#define ASSERT_RDEV_LOCK(rdev) lockdep_assert_held(&(rdev)->mtx) 168#define ASSERT_RDEV_LOCK(rdev) ASSERT_RTNL()
200#define ASSERT_WDEV_LOCK(wdev) lockdep_assert_held(&(wdev)->mtx) 169#define ASSERT_WDEV_LOCK(wdev) lockdep_assert_held(&(wdev)->mtx)
201 170
202static inline bool cfg80211_has_monitors_only(struct cfg80211_registered_device *rdev) 171static inline bool cfg80211_has_monitors_only(struct cfg80211_registered_device *rdev)
@@ -314,38 +283,21 @@ int cfg80211_stop_ap(struct cfg80211_registered_device *rdev,
314 struct net_device *dev); 283 struct net_device *dev);
315 284
316/* MLME */ 285/* MLME */
317int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
318 struct net_device *dev,
319 struct ieee80211_channel *chan,
320 enum nl80211_auth_type auth_type,
321 const u8 *bssid,
322 const u8 *ssid, int ssid_len,
323 const u8 *ie, int ie_len,
324 const u8 *key, int key_len, int key_idx,
325 const u8 *sae_data, int sae_data_len);
326int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev, 286int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
327 struct net_device *dev, struct ieee80211_channel *chan, 287 struct net_device *dev,
328 enum nl80211_auth_type auth_type, const u8 *bssid, 288 struct ieee80211_channel *chan,
289 enum nl80211_auth_type auth_type,
290 const u8 *bssid,
329 const u8 *ssid, int ssid_len, 291 const u8 *ssid, int ssid_len,
330 const u8 *ie, int ie_len, 292 const u8 *ie, int ie_len,
331 const u8 *key, int key_len, int key_idx, 293 const u8 *key, int key_len, int key_idx,
332 const u8 *sae_data, int sae_data_len); 294 const u8 *sae_data, int sae_data_len);
333int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
334 struct net_device *dev,
335 struct ieee80211_channel *chan,
336 const u8 *bssid,
337 const u8 *ssid, int ssid_len,
338 struct cfg80211_assoc_request *req);
339int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev, 295int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
340 struct net_device *dev, 296 struct net_device *dev,
341 struct ieee80211_channel *chan, 297 struct ieee80211_channel *chan,
342 const u8 *bssid, 298 const u8 *bssid,
343 const u8 *ssid, int ssid_len, 299 const u8 *ssid, int ssid_len,
344 struct cfg80211_assoc_request *req); 300 struct cfg80211_assoc_request *req);
345int __cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,
346 struct net_device *dev, const u8 *bssid,
347 const u8 *ie, int ie_len, u16 reason,
348 bool local_state_change);
349int cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev, 301int cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,
350 struct net_device *dev, const u8 *bssid, 302 struct net_device *dev, const u8 *bssid,
351 const u8 *ie, int ie_len, u16 reason, 303 const u8 *ie, int ie_len, u16 reason,
@@ -377,18 +329,11 @@ void cfg80211_oper_and_vht_capa(struct ieee80211_vht_cap *vht_capa,
377 const struct ieee80211_vht_cap *vht_capa_mask); 329 const struct ieee80211_vht_cap *vht_capa_mask);
378 330
379/* SME */ 331/* SME */
380int __cfg80211_connect(struct cfg80211_registered_device *rdev,
381 struct net_device *dev,
382 struct cfg80211_connect_params *connect,
383 struct cfg80211_cached_keys *connkeys,
384 const u8 *prev_bssid);
385int cfg80211_connect(struct cfg80211_registered_device *rdev, 332int cfg80211_connect(struct cfg80211_registered_device *rdev,
386 struct net_device *dev, 333 struct net_device *dev,
387 struct cfg80211_connect_params *connect, 334 struct cfg80211_connect_params *connect,
388 struct cfg80211_cached_keys *connkeys); 335 struct cfg80211_cached_keys *connkeys,
389int __cfg80211_disconnect(struct cfg80211_registered_device *rdev, 336 const u8 *prev_bssid);
390 struct net_device *dev, u16 reason,
391 bool wextev);
392int cfg80211_disconnect(struct cfg80211_registered_device *rdev, 337int cfg80211_disconnect(struct cfg80211_registered_device *rdev,
393 struct net_device *dev, u16 reason, 338 struct net_device *dev, u16 reason,
394 bool wextev); 339 bool wextev);
diff --git a/net/wireless/debugfs.c b/net/wireless/debugfs.c
index 920cabe0461b..90d050036624 100644
--- a/net/wireless/debugfs.c
+++ b/net/wireless/debugfs.c
@@ -74,7 +74,7 @@ static ssize_t ht40allow_map_read(struct file *file,
74 if (!buf) 74 if (!buf)
75 return -ENOMEM; 75 return -ENOMEM;
76 76
77 mutex_lock(&cfg80211_mutex); 77 rtnl_lock();
78 78
79 for (band = 0; band < IEEE80211_NUM_BANDS; band++) { 79 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
80 sband = wiphy->bands[band]; 80 sband = wiphy->bands[band];
@@ -85,7 +85,7 @@ static ssize_t ht40allow_map_read(struct file *file,
85 buf, buf_size, offset); 85 buf, buf_size, offset);
86 } 86 }
87 87
88 mutex_unlock(&cfg80211_mutex); 88 rtnl_unlock();
89 89
90 r = simple_read_from_buffer(user_buf, count, ppos, buf, offset); 90 r = simple_read_from_buffer(user_buf, count, ppos, buf, offset);
91 91
diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c
index d80e47194d49..5449c5a6de84 100644
--- a/net/wireless/ibss.c
+++ b/net/wireless/ibss.c
@@ -152,11 +152,11 @@ int cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
152 struct wireless_dev *wdev = dev->ieee80211_ptr; 152 struct wireless_dev *wdev = dev->ieee80211_ptr;
153 int err; 153 int err;
154 154
155 mutex_lock(&rdev->devlist_mtx); 155 ASSERT_RTNL();
156
156 wdev_lock(wdev); 157 wdev_lock(wdev);
157 err = __cfg80211_join_ibss(rdev, dev, params, connkeys); 158 err = __cfg80211_join_ibss(rdev, dev, params, connkeys);
158 wdev_unlock(wdev); 159 wdev_unlock(wdev);
159 mutex_unlock(&rdev->devlist_mtx);
160 160
161 return err; 161 return err;
162} 162}
@@ -359,11 +359,9 @@ int cfg80211_ibss_wext_siwfreq(struct net_device *dev,
359 wdev->wext.ibss.channel_fixed = false; 359 wdev->wext.ibss.channel_fixed = false;
360 } 360 }
361 361
362 mutex_lock(&rdev->devlist_mtx);
363 wdev_lock(wdev); 362 wdev_lock(wdev);
364 err = cfg80211_ibss_wext_join(rdev, wdev); 363 err = cfg80211_ibss_wext_join(rdev, wdev);
365 wdev_unlock(wdev); 364 wdev_unlock(wdev);
366 mutex_unlock(&rdev->devlist_mtx);
367 365
368 return err; 366 return err;
369} 367}
@@ -429,11 +427,9 @@ int cfg80211_ibss_wext_siwessid(struct net_device *dev,
429 memcpy(wdev->wext.ibss.ssid, ssid, len); 427 memcpy(wdev->wext.ibss.ssid, ssid, len);
430 wdev->wext.ibss.ssid_len = len; 428 wdev->wext.ibss.ssid_len = len;
431 429
432 mutex_lock(&rdev->devlist_mtx);
433 wdev_lock(wdev); 430 wdev_lock(wdev);
434 err = cfg80211_ibss_wext_join(rdev, wdev); 431 err = cfg80211_ibss_wext_join(rdev, wdev);
435 wdev_unlock(wdev); 432 wdev_unlock(wdev);
436 mutex_unlock(&rdev->devlist_mtx);
437 433
438 return err; 434 return err;
439} 435}
@@ -512,11 +508,9 @@ int cfg80211_ibss_wext_siwap(struct net_device *dev,
512 } else 508 } else
513 wdev->wext.ibss.bssid = NULL; 509 wdev->wext.ibss.bssid = NULL;
514 510
515 mutex_lock(&rdev->devlist_mtx);
516 wdev_lock(wdev); 511 wdev_lock(wdev);
517 err = cfg80211_ibss_wext_join(rdev, wdev); 512 err = cfg80211_ibss_wext_join(rdev, wdev);
518 wdev_unlock(wdev); 513 wdev_unlock(wdev);
519 mutex_unlock(&rdev->devlist_mtx);
520 514
521 return err; 515 return err;
522} 516}
diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c
index 0bb93f3061a4..5dfb289ab761 100644
--- a/net/wireless/mesh.c
+++ b/net/wireless/mesh.c
@@ -82,6 +82,7 @@ const struct mesh_setup default_mesh_setup = {
82 .sync_method = IEEE80211_SYNC_METHOD_NEIGHBOR_OFFSET, 82 .sync_method = IEEE80211_SYNC_METHOD_NEIGHBOR_OFFSET,
83 .path_sel_proto = IEEE80211_PATH_PROTOCOL_HWMP, 83 .path_sel_proto = IEEE80211_PATH_PROTOCOL_HWMP,
84 .path_metric = IEEE80211_PATH_METRIC_AIRTIME, 84 .path_metric = IEEE80211_PATH_METRIC_AIRTIME,
85 .auth_id = 0, /* open */
85 .ie = NULL, 86 .ie = NULL,
86 .ie_len = 0, 87 .ie_len = 0,
87 .is_secure = false, 88 .is_secure = false,
@@ -185,11 +186,9 @@ int cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
185 struct wireless_dev *wdev = dev->ieee80211_ptr; 186 struct wireless_dev *wdev = dev->ieee80211_ptr;
186 int err; 187 int err;
187 188
188 mutex_lock(&rdev->devlist_mtx);
189 wdev_lock(wdev); 189 wdev_lock(wdev);
190 err = __cfg80211_join_mesh(rdev, dev, setup, conf); 190 err = __cfg80211_join_mesh(rdev, dev, setup, conf);
191 wdev_unlock(wdev); 191 wdev_unlock(wdev);
192 mutex_unlock(&rdev->devlist_mtx);
193 192
194 return err; 193 return err;
195} 194}
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index 0c7b7dd855f6..7bde5d9c0003 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -25,12 +25,9 @@ void cfg80211_send_rx_auth(struct net_device *dev, const u8 *buf, size_t len)
25 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 25 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
26 26
27 trace_cfg80211_send_rx_auth(dev); 27 trace_cfg80211_send_rx_auth(dev);
28 wdev_lock(wdev);
29 28
30 nl80211_send_rx_auth(rdev, dev, buf, len, GFP_KERNEL); 29 nl80211_send_rx_auth(rdev, dev, buf, len, GFP_KERNEL);
31 cfg80211_sme_rx_auth(dev, buf, len); 30 cfg80211_sme_rx_auth(dev, buf, len);
32
33 wdev_unlock(wdev);
34} 31}
35EXPORT_SYMBOL(cfg80211_send_rx_auth); 32EXPORT_SYMBOL(cfg80211_send_rx_auth);
36 33
@@ -46,7 +43,6 @@ void cfg80211_send_rx_assoc(struct net_device *dev, struct cfg80211_bss *bss,
46 int ieoffs = offsetof(struct ieee80211_mgmt, u.assoc_resp.variable); 43 int ieoffs = offsetof(struct ieee80211_mgmt, u.assoc_resp.variable);
47 44
48 trace_cfg80211_send_rx_assoc(dev, bss); 45 trace_cfg80211_send_rx_assoc(dev, bss);
49 wdev_lock(wdev);
50 46
51 status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code); 47 status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code);
52 48
@@ -59,7 +55,7 @@ void cfg80211_send_rx_assoc(struct net_device *dev, struct cfg80211_bss *bss,
59 if (status_code != WLAN_STATUS_SUCCESS && wdev->conn && 55 if (status_code != WLAN_STATUS_SUCCESS && wdev->conn &&
60 cfg80211_sme_failed_reassoc(wdev)) { 56 cfg80211_sme_failed_reassoc(wdev)) {
61 cfg80211_put_bss(wiphy, bss); 57 cfg80211_put_bss(wiphy, bss);
62 goto out; 58 return;
63 } 59 }
64 60
65 nl80211_send_rx_assoc(rdev, dev, buf, len, GFP_KERNEL); 61 nl80211_send_rx_assoc(rdev, dev, buf, len, GFP_KERNEL);
@@ -71,7 +67,7 @@ void cfg80211_send_rx_assoc(struct net_device *dev, struct cfg80211_bss *bss,
71 * sme will schedule work that does it later. 67 * sme will schedule work that does it later.
72 */ 68 */
73 cfg80211_put_bss(wiphy, bss); 69 cfg80211_put_bss(wiphy, bss);
74 goto out; 70 return;
75 } 71 }
76 72
77 if (!wdev->conn && wdev->sme_state == CFG80211_SME_IDLE) { 73 if (!wdev->conn && wdev->sme_state == CFG80211_SME_IDLE) {
@@ -87,13 +83,11 @@ void cfg80211_send_rx_assoc(struct net_device *dev, struct cfg80211_bss *bss,
87 __cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, ie, len - ieoffs, 83 __cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, ie, len - ieoffs,
88 status_code, 84 status_code,
89 status_code == WLAN_STATUS_SUCCESS, bss); 85 status_code == WLAN_STATUS_SUCCESS, bss);
90 out:
91 wdev_unlock(wdev);
92} 86}
93EXPORT_SYMBOL(cfg80211_send_rx_assoc); 87EXPORT_SYMBOL(cfg80211_send_rx_assoc);
94 88
95void __cfg80211_send_deauth(struct net_device *dev, 89void cfg80211_send_deauth(struct net_device *dev,
96 const u8 *buf, size_t len) 90 const u8 *buf, size_t len)
97{ 91{
98 struct wireless_dev *wdev = dev->ieee80211_ptr; 92 struct wireless_dev *wdev = dev->ieee80211_ptr;
99 struct wiphy *wiphy = wdev->wiphy; 93 struct wiphy *wiphy = wdev->wiphy;
@@ -102,7 +96,7 @@ void __cfg80211_send_deauth(struct net_device *dev,
102 const u8 *bssid = mgmt->bssid; 96 const u8 *bssid = mgmt->bssid;
103 bool was_current = false; 97 bool was_current = false;
104 98
105 trace___cfg80211_send_deauth(dev); 99 trace_cfg80211_send_deauth(dev);
106 ASSERT_WDEV_LOCK(wdev); 100 ASSERT_WDEV_LOCK(wdev);
107 101
108 if (wdev->current_bss && 102 if (wdev->current_bss &&
@@ -129,20 +123,10 @@ void __cfg80211_send_deauth(struct net_device *dev,
129 false, NULL); 123 false, NULL);
130 } 124 }
131} 125}
132EXPORT_SYMBOL(__cfg80211_send_deauth);
133
134void cfg80211_send_deauth(struct net_device *dev, const u8 *buf, size_t len)
135{
136 struct wireless_dev *wdev = dev->ieee80211_ptr;
137
138 wdev_lock(wdev);
139 __cfg80211_send_deauth(dev, buf, len);
140 wdev_unlock(wdev);
141}
142EXPORT_SYMBOL(cfg80211_send_deauth); 126EXPORT_SYMBOL(cfg80211_send_deauth);
143 127
144void __cfg80211_send_disassoc(struct net_device *dev, 128void cfg80211_send_disassoc(struct net_device *dev,
145 const u8 *buf, size_t len) 129 const u8 *buf, size_t len)
146{ 130{
147 struct wireless_dev *wdev = dev->ieee80211_ptr; 131 struct wireless_dev *wdev = dev->ieee80211_ptr;
148 struct wiphy *wiphy = wdev->wiphy; 132 struct wiphy *wiphy = wdev->wiphy;
@@ -152,7 +136,7 @@ void __cfg80211_send_disassoc(struct net_device *dev,
152 u16 reason_code; 136 u16 reason_code;
153 bool from_ap; 137 bool from_ap;
154 138
155 trace___cfg80211_send_disassoc(dev); 139 trace_cfg80211_send_disassoc(dev);
156 ASSERT_WDEV_LOCK(wdev); 140 ASSERT_WDEV_LOCK(wdev);
157 141
158 nl80211_send_disassoc(rdev, dev, buf, len, GFP_KERNEL); 142 nl80211_send_disassoc(rdev, dev, buf, len, GFP_KERNEL);
@@ -175,16 +159,6 @@ void __cfg80211_send_disassoc(struct net_device *dev,
175 from_ap = !ether_addr_equal(mgmt->sa, dev->dev_addr); 159 from_ap = !ether_addr_equal(mgmt->sa, dev->dev_addr);
176 __cfg80211_disconnected(dev, NULL, 0, reason_code, from_ap); 160 __cfg80211_disconnected(dev, NULL, 0, reason_code, from_ap);
177} 161}
178EXPORT_SYMBOL(__cfg80211_send_disassoc);
179
180void cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, size_t len)
181{
182 struct wireless_dev *wdev = dev->ieee80211_ptr;
183
184 wdev_lock(wdev);
185 __cfg80211_send_disassoc(dev, buf, len);
186 wdev_unlock(wdev);
187}
188EXPORT_SYMBOL(cfg80211_send_disassoc); 162EXPORT_SYMBOL(cfg80211_send_disassoc);
189 163
190void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr) 164void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr)
@@ -194,15 +168,12 @@ void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr)
194 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 168 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
195 169
196 trace_cfg80211_send_auth_timeout(dev, addr); 170 trace_cfg80211_send_auth_timeout(dev, addr);
197 wdev_lock(wdev);
198 171
199 nl80211_send_auth_timeout(rdev, dev, addr, GFP_KERNEL); 172 nl80211_send_auth_timeout(rdev, dev, addr, GFP_KERNEL);
200 if (wdev->sme_state == CFG80211_SME_CONNECTING) 173 if (wdev->sme_state == CFG80211_SME_CONNECTING)
201 __cfg80211_connect_result(dev, addr, NULL, 0, NULL, 0, 174 __cfg80211_connect_result(dev, addr, NULL, 0, NULL, 0,
202 WLAN_STATUS_UNSPECIFIED_FAILURE, 175 WLAN_STATUS_UNSPECIFIED_FAILURE,
203 false, NULL); 176 false, NULL);
204
205 wdev_unlock(wdev);
206} 177}
207EXPORT_SYMBOL(cfg80211_send_auth_timeout); 178EXPORT_SYMBOL(cfg80211_send_auth_timeout);
208 179
@@ -213,15 +184,12 @@ void cfg80211_send_assoc_timeout(struct net_device *dev, const u8 *addr)
213 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 184 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
214 185
215 trace_cfg80211_send_assoc_timeout(dev, addr); 186 trace_cfg80211_send_assoc_timeout(dev, addr);
216 wdev_lock(wdev);
217 187
218 nl80211_send_assoc_timeout(rdev, dev, addr, GFP_KERNEL); 188 nl80211_send_assoc_timeout(rdev, dev, addr, GFP_KERNEL);
219 if (wdev->sme_state == CFG80211_SME_CONNECTING) 189 if (wdev->sme_state == CFG80211_SME_CONNECTING)
220 __cfg80211_connect_result(dev, addr, NULL, 0, NULL, 0, 190 __cfg80211_connect_result(dev, addr, NULL, 0, NULL, 0,
221 WLAN_STATUS_UNSPECIFIED_FAILURE, 191 WLAN_STATUS_UNSPECIFIED_FAILURE,
222 false, NULL); 192 false, NULL);
223
224 wdev_unlock(wdev);
225} 193}
226EXPORT_SYMBOL(cfg80211_send_assoc_timeout); 194EXPORT_SYMBOL(cfg80211_send_assoc_timeout);
227 195
@@ -253,18 +221,27 @@ void cfg80211_michael_mic_failure(struct net_device *dev, const u8 *addr,
253EXPORT_SYMBOL(cfg80211_michael_mic_failure); 221EXPORT_SYMBOL(cfg80211_michael_mic_failure);
254 222
255/* some MLME handling for userspace SME */ 223/* some MLME handling for userspace SME */
256int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev, 224int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
257 struct net_device *dev, 225 struct net_device *dev,
258 struct ieee80211_channel *chan, 226 struct ieee80211_channel *chan,
259 enum nl80211_auth_type auth_type, 227 enum nl80211_auth_type auth_type,
260 const u8 *bssid, 228 const u8 *bssid,
261 const u8 *ssid, int ssid_len, 229 const u8 *ssid, int ssid_len,
262 const u8 *ie, int ie_len, 230 const u8 *ie, int ie_len,
263 const u8 *key, int key_len, int key_idx, 231 const u8 *key, int key_len, int key_idx,
264 const u8 *sae_data, int sae_data_len) 232 const u8 *sae_data, int sae_data_len)
265{ 233{
266 struct wireless_dev *wdev = dev->ieee80211_ptr; 234 struct wireless_dev *wdev = dev->ieee80211_ptr;
267 struct cfg80211_auth_request req; 235 struct cfg80211_auth_request req = {
236 .ie = ie,
237 .ie_len = ie_len,
238 .sae_data = sae_data,
239 .sae_data_len = sae_data_len,
240 .auth_type = auth_type,
241 .key = key,
242 .key_len = key_len,
243 .key_idx = key_idx,
244 };
268 int err; 245 int err;
269 246
270 ASSERT_WDEV_LOCK(wdev); 247 ASSERT_WDEV_LOCK(wdev);
@@ -277,18 +254,8 @@ int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
277 ether_addr_equal(bssid, wdev->current_bss->pub.bssid)) 254 ether_addr_equal(bssid, wdev->current_bss->pub.bssid))
278 return -EALREADY; 255 return -EALREADY;
279 256
280 memset(&req, 0, sizeof(req));
281
282 req.ie = ie;
283 req.ie_len = ie_len;
284 req.sae_data = sae_data;
285 req.sae_data_len = sae_data_len;
286 req.auth_type = auth_type;
287 req.bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len, 257 req.bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len,
288 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); 258 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
289 req.key = key;
290 req.key_len = key_len;
291 req.key_idx = key_idx;
292 if (!req.bss) 259 if (!req.bss)
293 return -ENOENT; 260 return -ENOENT;
294 261
@@ -304,28 +271,6 @@ out:
304 return err; 271 return err;
305} 272}
306 273
307int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
308 struct net_device *dev, struct ieee80211_channel *chan,
309 enum nl80211_auth_type auth_type, const u8 *bssid,
310 const u8 *ssid, int ssid_len,
311 const u8 *ie, int ie_len,
312 const u8 *key, int key_len, int key_idx,
313 const u8 *sae_data, int sae_data_len)
314{
315 int err;
316
317 mutex_lock(&rdev->devlist_mtx);
318 wdev_lock(dev->ieee80211_ptr);
319 err = __cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid,
320 ssid, ssid_len, ie, ie_len,
321 key, key_len, key_idx,
322 sae_data, sae_data_len);
323 wdev_unlock(dev->ieee80211_ptr);
324 mutex_unlock(&rdev->devlist_mtx);
325
326 return err;
327}
328
329/* Do a logical ht_capa &= ht_capa_mask. */ 274/* Do a logical ht_capa &= ht_capa_mask. */
330void cfg80211_oper_and_ht_capa(struct ieee80211_ht_cap *ht_capa, 275void cfg80211_oper_and_ht_capa(struct ieee80211_ht_cap *ht_capa,
331 const struct ieee80211_ht_cap *ht_capa_mask) 276 const struct ieee80211_ht_cap *ht_capa_mask)
@@ -360,12 +305,12 @@ void cfg80211_oper_and_vht_capa(struct ieee80211_vht_cap *vht_capa,
360 p1[i] &= p2[i]; 305 p1[i] &= p2[i];
361} 306}
362 307
363int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev, 308int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
364 struct net_device *dev, 309 struct net_device *dev,
365 struct ieee80211_channel *chan, 310 struct ieee80211_channel *chan,
366 const u8 *bssid, 311 const u8 *bssid,
367 const u8 *ssid, int ssid_len, 312 const u8 *ssid, int ssid_len,
368 struct cfg80211_assoc_request *req) 313 struct cfg80211_assoc_request *req)
369{ 314{
370 struct wireless_dev *wdev = dev->ieee80211_ptr; 315 struct wireless_dev *wdev = dev->ieee80211_ptr;
371 int err; 316 int err;
@@ -415,30 +360,10 @@ out:
415 return err; 360 return err;
416} 361}
417 362
418int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev, 363int cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,
419 struct net_device *dev, 364 struct net_device *dev, const u8 *bssid,
420 struct ieee80211_channel *chan, 365 const u8 *ie, int ie_len, u16 reason,
421 const u8 *bssid, 366 bool local_state_change)
422 const u8 *ssid, int ssid_len,
423 struct cfg80211_assoc_request *req)
424{
425 struct wireless_dev *wdev = dev->ieee80211_ptr;
426 int err;
427
428 mutex_lock(&rdev->devlist_mtx);
429 wdev_lock(wdev);
430 err = __cfg80211_mlme_assoc(rdev, dev, chan, bssid,
431 ssid, ssid_len, req);
432 wdev_unlock(wdev);
433 mutex_unlock(&rdev->devlist_mtx);
434
435 return err;
436}
437
438int __cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,
439 struct net_device *dev, const u8 *bssid,
440 const u8 *ie, int ie_len, u16 reason,
441 bool local_state_change)
442{ 367{
443 struct wireless_dev *wdev = dev->ieee80211_ptr; 368 struct wireless_dev *wdev = dev->ieee80211_ptr;
444 struct cfg80211_deauth_request req = { 369 struct cfg80211_deauth_request req = {
@@ -458,29 +383,18 @@ int __cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,
458 return rdev_deauth(rdev, dev, &req); 383 return rdev_deauth(rdev, dev, &req);
459} 384}
460 385
461int cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev, 386int cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev,
462 struct net_device *dev, const u8 *bssid, 387 struct net_device *dev, const u8 *bssid,
463 const u8 *ie, int ie_len, u16 reason, 388 const u8 *ie, int ie_len, u16 reason,
464 bool local_state_change) 389 bool local_state_change)
465{
466 struct wireless_dev *wdev = dev->ieee80211_ptr;
467 int err;
468
469 wdev_lock(wdev);
470 err = __cfg80211_mlme_deauth(rdev, dev, bssid, ie, ie_len, reason,
471 local_state_change);
472 wdev_unlock(wdev);
473
474 return err;
475}
476
477static int __cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev,
478 struct net_device *dev, const u8 *bssid,
479 const u8 *ie, int ie_len, u16 reason,
480 bool local_state_change)
481{ 390{
482 struct wireless_dev *wdev = dev->ieee80211_ptr; 391 struct wireless_dev *wdev = dev->ieee80211_ptr;
483 struct cfg80211_disassoc_request req; 392 struct cfg80211_disassoc_request req = {
393 .reason_code = reason,
394 .local_state_change = local_state_change,
395 .ie = ie,
396 .ie_len = ie_len,
397 };
484 398
485 ASSERT_WDEV_LOCK(wdev); 399 ASSERT_WDEV_LOCK(wdev);
486 400
@@ -490,11 +404,6 @@ static int __cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev,
490 if (WARN(!wdev->current_bss, "sme_state=%d\n", wdev->sme_state)) 404 if (WARN(!wdev->current_bss, "sme_state=%d\n", wdev->sme_state))
491 return -ENOTCONN; 405 return -ENOTCONN;
492 406
493 memset(&req, 0, sizeof(req));
494 req.reason_code = reason;
495 req.local_state_change = local_state_change;
496 req.ie = ie;
497 req.ie_len = ie_len;
498 if (ether_addr_equal(wdev->current_bss->pub.bssid, bssid)) 407 if (ether_addr_equal(wdev->current_bss->pub.bssid, bssid))
499 req.bss = &wdev->current_bss->pub; 408 req.bss = &wdev->current_bss->pub;
500 else 409 else
@@ -503,44 +412,25 @@ static int __cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev,
503 return rdev_disassoc(rdev, dev, &req); 412 return rdev_disassoc(rdev, dev, &req);
504} 413}
505 414
506int cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev,
507 struct net_device *dev, const u8 *bssid,
508 const u8 *ie, int ie_len, u16 reason,
509 bool local_state_change)
510{
511 struct wireless_dev *wdev = dev->ieee80211_ptr;
512 int err;
513
514 wdev_lock(wdev);
515 err = __cfg80211_mlme_disassoc(rdev, dev, bssid, ie, ie_len, reason,
516 local_state_change);
517 wdev_unlock(wdev);
518
519 return err;
520}
521
522void cfg80211_mlme_down(struct cfg80211_registered_device *rdev, 415void cfg80211_mlme_down(struct cfg80211_registered_device *rdev,
523 struct net_device *dev) 416 struct net_device *dev)
524{ 417{
525 struct wireless_dev *wdev = dev->ieee80211_ptr; 418 struct wireless_dev *wdev = dev->ieee80211_ptr;
526 struct cfg80211_deauth_request req;
527 u8 bssid[ETH_ALEN]; 419 u8 bssid[ETH_ALEN];
420 struct cfg80211_deauth_request req = {
421 .reason_code = WLAN_REASON_DEAUTH_LEAVING,
422 .bssid = bssid,
423 };
528 424
529 ASSERT_WDEV_LOCK(wdev); 425 ASSERT_WDEV_LOCK(wdev);
530 426
531 if (!rdev->ops->deauth) 427 if (!rdev->ops->deauth)
532 return; 428 return;
533 429
534 memset(&req, 0, sizeof(req));
535 req.reason_code = WLAN_REASON_DEAUTH_LEAVING;
536 req.ie = NULL;
537 req.ie_len = 0;
538
539 if (!wdev->current_bss) 430 if (!wdev->current_bss)
540 return; 431 return;
541 432
542 memcpy(bssid, wdev->current_bss->pub.bssid, ETH_ALEN); 433 memcpy(bssid, wdev->current_bss->pub.bssid, ETH_ALEN);
543 req.bssid = bssid;
544 rdev_deauth(rdev, dev, &req); 434 rdev_deauth(rdev, dev, &req);
545 435
546 if (wdev->current_bss) { 436 if (wdev->current_bss) {
@@ -848,7 +738,7 @@ void cfg80211_dfs_channels_update_work(struct work_struct *work)
848 dfs_update_channels_wk); 738 dfs_update_channels_wk);
849 wiphy = &rdev->wiphy; 739 wiphy = &rdev->wiphy;
850 740
851 mutex_lock(&cfg80211_mutex); 741 rtnl_lock();
852 for (bandid = 0; bandid < IEEE80211_NUM_BANDS; bandid++) { 742 for (bandid = 0; bandid < IEEE80211_NUM_BANDS; bandid++) {
853 sband = wiphy->bands[bandid]; 743 sband = wiphy->bands[bandid];
854 if (!sband) 744 if (!sband)
@@ -881,7 +771,7 @@ void cfg80211_dfs_channels_update_work(struct work_struct *work)
881 check_again = true; 771 check_again = true;
882 } 772 }
883 } 773 }
884 mutex_unlock(&cfg80211_mutex); 774 rtnl_unlock();
885 775
886 /* reschedule if there are other channels waiting to be cleared again */ 776 /* reschedule if there are other channels waiting to be cleared again */
887 if (check_again) 777 if (check_again)
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index d5aed3bb3945..31d265f36d2c 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -37,10 +37,10 @@ static void nl80211_post_doit(struct genl_ops *ops, struct sk_buff *skb,
37 37
38/* the netlink family */ 38/* the netlink family */
39static struct genl_family nl80211_fam = { 39static struct genl_family nl80211_fam = {
40 .id = GENL_ID_GENERATE, /* don't bother with a hardcoded ID */ 40 .id = GENL_ID_GENERATE, /* don't bother with a hardcoded ID */
41 .name = "nl80211", /* have users key off the name instead */ 41 .name = NL80211_GENL_NAME, /* have users key off the name instead */
42 .hdrsize = 0, /* no private header */ 42 .hdrsize = 0, /* no private header */
43 .version = 1, /* no particular meaning now */ 43 .version = 1, /* no particular meaning now */
44 .maxattr = NL80211_ATTR_MAX, 44 .maxattr = NL80211_ATTR_MAX,
45 .netnsok = true, 45 .netnsok = true,
46 .pre_doit = nl80211_pre_doit, 46 .pre_doit = nl80211_pre_doit,
@@ -59,7 +59,7 @@ __cfg80211_wdev_from_attrs(struct net *netns, struct nlattr **attrs)
59 int wiphy_idx = -1; 59 int wiphy_idx = -1;
60 int ifidx = -1; 60 int ifidx = -1;
61 61
62 assert_cfg80211_lock(); 62 ASSERT_RTNL();
63 63
64 if (!have_ifidx && !have_wdev_id) 64 if (!have_ifidx && !have_wdev_id)
65 return ERR_PTR(-EINVAL); 65 return ERR_PTR(-EINVAL);
@@ -80,7 +80,6 @@ __cfg80211_wdev_from_attrs(struct net *netns, struct nlattr **attrs)
80 if (have_wdev_id && rdev->wiphy_idx != wiphy_idx) 80 if (have_wdev_id && rdev->wiphy_idx != wiphy_idx)
81 continue; 81 continue;
82 82
83 mutex_lock(&rdev->devlist_mtx);
84 list_for_each_entry(wdev, &rdev->wdev_list, list) { 83 list_for_each_entry(wdev, &rdev->wdev_list, list) {
85 if (have_ifidx && wdev->netdev && 84 if (have_ifidx && wdev->netdev &&
86 wdev->netdev->ifindex == ifidx) { 85 wdev->netdev->ifindex == ifidx) {
@@ -92,7 +91,6 @@ __cfg80211_wdev_from_attrs(struct net *netns, struct nlattr **attrs)
92 break; 91 break;
93 } 92 }
94 } 93 }
95 mutex_unlock(&rdev->devlist_mtx);
96 94
97 if (result) 95 if (result)
98 break; 96 break;
@@ -109,7 +107,7 @@ __cfg80211_rdev_from_attrs(struct net *netns, struct nlattr **attrs)
109 struct cfg80211_registered_device *rdev = NULL, *tmp; 107 struct cfg80211_registered_device *rdev = NULL, *tmp;
110 struct net_device *netdev; 108 struct net_device *netdev;
111 109
112 assert_cfg80211_lock(); 110 ASSERT_RTNL();
113 111
114 if (!attrs[NL80211_ATTR_WIPHY] && 112 if (!attrs[NL80211_ATTR_WIPHY] &&
115 !attrs[NL80211_ATTR_IFINDEX] && 113 !attrs[NL80211_ATTR_IFINDEX] &&
@@ -128,14 +126,12 @@ __cfg80211_rdev_from_attrs(struct net *netns, struct nlattr **attrs)
128 tmp = cfg80211_rdev_by_wiphy_idx(wdev_id >> 32); 126 tmp = cfg80211_rdev_by_wiphy_idx(wdev_id >> 32);
129 if (tmp) { 127 if (tmp) {
130 /* make sure wdev exists */ 128 /* make sure wdev exists */
131 mutex_lock(&tmp->devlist_mtx);
132 list_for_each_entry(wdev, &tmp->wdev_list, list) { 129 list_for_each_entry(wdev, &tmp->wdev_list, list) {
133 if (wdev->identifier != (u32)wdev_id) 130 if (wdev->identifier != (u32)wdev_id)
134 continue; 131 continue;
135 found = true; 132 found = true;
136 break; 133 break;
137 } 134 }
138 mutex_unlock(&tmp->devlist_mtx);
139 135
140 if (!found) 136 if (!found)
141 tmp = NULL; 137 tmp = NULL;
@@ -182,19 +178,6 @@ __cfg80211_rdev_from_attrs(struct net *netns, struct nlattr **attrs)
182/* 178/*
183 * This function returns a pointer to the driver 179 * This function returns a pointer to the driver
184 * that the genl_info item that is passed refers to. 180 * that the genl_info item that is passed refers to.
185 * If successful, it returns non-NULL and also locks
186 * the driver's mutex!
187 *
188 * This means that you need to call cfg80211_unlock_rdev()
189 * before being allowed to acquire &cfg80211_mutex!
190 *
191 * This is necessary because we need to lock the global
192 * mutex to get an item off the list safely, and then
193 * we lock the rdev mutex so it doesn't go away under us.
194 *
195 * We don't want to keep cfg80211_mutex locked
196 * for all the time in order to allow requests on
197 * other interfaces to go through at the same time.
198 * 181 *
199 * The result of this can be a PTR_ERR and hence must 182 * The result of this can be a PTR_ERR and hence must
200 * be checked with IS_ERR() for errors. 183 * be checked with IS_ERR() for errors.
@@ -202,20 +185,7 @@ __cfg80211_rdev_from_attrs(struct net *netns, struct nlattr **attrs)
202static struct cfg80211_registered_device * 185static struct cfg80211_registered_device *
203cfg80211_get_dev_from_info(struct net *netns, struct genl_info *info) 186cfg80211_get_dev_from_info(struct net *netns, struct genl_info *info)
204{ 187{
205 struct cfg80211_registered_device *rdev; 188 return __cfg80211_rdev_from_attrs(netns, info->attrs);
206
207 mutex_lock(&cfg80211_mutex);
208 rdev = __cfg80211_rdev_from_attrs(netns, info->attrs);
209
210 /* if it is not an error we grab the lock on
211 * it to assure it won't be going away while
212 * we operate on it */
213 if (!IS_ERR(rdev))
214 mutex_lock(&rdev->mtx);
215
216 mutex_unlock(&cfg80211_mutex);
217
218 return rdev;
219} 189}
220 190
221/* policy for the attributes */ 191/* policy for the attributes */
@@ -378,6 +348,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
378 [NL80211_ATTR_MDID] = { .type = NLA_U16 }, 348 [NL80211_ATTR_MDID] = { .type = NLA_U16 },
379 [NL80211_ATTR_IE_RIC] = { .type = NLA_BINARY, 349 [NL80211_ATTR_IE_RIC] = { .type = NLA_BINARY,
380 .len = IEEE80211_MAX_DATA_LEN }, 350 .len = IEEE80211_MAX_DATA_LEN },
351 [NL80211_ATTR_PEER_AID] = { .type = NLA_U16 },
381}; 352};
382 353
383/* policy for the key attributes */ 354/* policy for the key attributes */
@@ -455,7 +426,6 @@ static int nl80211_prepare_wdev_dump(struct sk_buff *skb,
455 int err; 426 int err;
456 427
457 rtnl_lock(); 428 rtnl_lock();
458 mutex_lock(&cfg80211_mutex);
459 429
460 if (!cb->args[0]) { 430 if (!cb->args[0]) {
461 err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize, 431 err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize,
@@ -484,14 +454,12 @@ static int nl80211_prepare_wdev_dump(struct sk_buff *skb,
484 *rdev = wiphy_to_dev(wiphy); 454 *rdev = wiphy_to_dev(wiphy);
485 *wdev = NULL; 455 *wdev = NULL;
486 456
487 mutex_lock(&(*rdev)->devlist_mtx);
488 list_for_each_entry(tmp, &(*rdev)->wdev_list, list) { 457 list_for_each_entry(tmp, &(*rdev)->wdev_list, list) {
489 if (tmp->identifier == cb->args[1]) { 458 if (tmp->identifier == cb->args[1]) {
490 *wdev = tmp; 459 *wdev = tmp;
491 break; 460 break;
492 } 461 }
493 } 462 }
494 mutex_unlock(&(*rdev)->devlist_mtx);
495 463
496 if (!*wdev) { 464 if (!*wdev) {
497 err = -ENODEV; 465 err = -ENODEV;
@@ -499,19 +467,14 @@ static int nl80211_prepare_wdev_dump(struct sk_buff *skb,
499 } 467 }
500 } 468 }
501 469
502 cfg80211_lock_rdev(*rdev);
503
504 mutex_unlock(&cfg80211_mutex);
505 return 0; 470 return 0;
506 out_unlock: 471 out_unlock:
507 mutex_unlock(&cfg80211_mutex);
508 rtnl_unlock(); 472 rtnl_unlock();
509 return err; 473 return err;
510} 474}
511 475
512static void nl80211_finish_wdev_dump(struct cfg80211_registered_device *rdev) 476static void nl80211_finish_wdev_dump(struct cfg80211_registered_device *rdev)
513{ 477{
514 cfg80211_unlock_rdev(rdev);
515 rtnl_unlock(); 478 rtnl_unlock();
516} 479}
517 480
@@ -1567,7 +1530,7 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
1567 struct nlattr **tb = nl80211_fam.attrbuf; 1530 struct nlattr **tb = nl80211_fam.attrbuf;
1568 int res; 1531 int res;
1569 1532
1570 mutex_lock(&cfg80211_mutex); 1533 rtnl_lock();
1571 res = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize, 1534 res = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize,
1572 tb, nl80211_fam.maxattr, nl80211_policy); 1535 tb, nl80211_fam.maxattr, nl80211_policy);
1573 if (res == 0) { 1536 if (res == 0) {
@@ -1581,10 +1544,8 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
1581 int ifidx = nla_get_u32(tb[NL80211_ATTR_IFINDEX]); 1544 int ifidx = nla_get_u32(tb[NL80211_ATTR_IFINDEX]);
1582 1545
1583 netdev = dev_get_by_index(sock_net(skb->sk), ifidx); 1546 netdev = dev_get_by_index(sock_net(skb->sk), ifidx);
1584 if (!netdev) { 1547 if (!netdev)
1585 mutex_unlock(&cfg80211_mutex);
1586 return -ENODEV; 1548 return -ENODEV;
1587 }
1588 if (netdev->ieee80211_ptr) { 1549 if (netdev->ieee80211_ptr) {
1589 dev = wiphy_to_dev( 1550 dev = wiphy_to_dev(
1590 netdev->ieee80211_ptr->wiphy); 1551 netdev->ieee80211_ptr->wiphy);
@@ -1628,7 +1589,6 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
1628 !skb->len && 1589 !skb->len &&
1629 cb->min_dump_alloc < 4096) { 1590 cb->min_dump_alloc < 4096) {
1630 cb->min_dump_alloc = 4096; 1591 cb->min_dump_alloc = 4096;
1631 mutex_unlock(&cfg80211_mutex);
1632 return 1; 1592 return 1;
1633 } 1593 }
1634 idx--; 1594 idx--;
@@ -1637,7 +1597,7 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
1637 } while (cb->args[1] > 0); 1597 } while (cb->args[1] > 0);
1638 break; 1598 break;
1639 } 1599 }
1640 mutex_unlock(&cfg80211_mutex); 1600 rtnl_unlock();
1641 1601
1642 cb->args[0] = idx; 1602 cb->args[0] = idx;
1643 1603
@@ -1792,7 +1752,6 @@ static int __nl80211_set_channel(struct cfg80211_registered_device *rdev,
1792 if (result) 1752 if (result)
1793 return result; 1753 return result;
1794 1754
1795 mutex_lock(&rdev->devlist_mtx);
1796 switch (iftype) { 1755 switch (iftype) {
1797 case NL80211_IFTYPE_AP: 1756 case NL80211_IFTYPE_AP:
1798 case NL80211_IFTYPE_P2P_GO: 1757 case NL80211_IFTYPE_P2P_GO:
@@ -1816,7 +1775,6 @@ static int __nl80211_set_channel(struct cfg80211_registered_device *rdev,
1816 default: 1775 default:
1817 result = -EINVAL; 1776 result = -EINVAL;
1818 } 1777 }
1819 mutex_unlock(&rdev->devlist_mtx);
1820 1778
1821 return result; 1779 return result;
1822} 1780}
@@ -1865,6 +1823,8 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
1865 u32 frag_threshold = 0, rts_threshold = 0; 1823 u32 frag_threshold = 0, rts_threshold = 0;
1866 u8 coverage_class = 0; 1824 u8 coverage_class = 0;
1867 1825
1826 ASSERT_RTNL();
1827
1868 /* 1828 /*
1869 * Try to find the wiphy and netdev. Normally this 1829 * Try to find the wiphy and netdev. Normally this
1870 * function shouldn't need the netdev, but this is 1830 * function shouldn't need the netdev, but this is
@@ -1874,31 +1834,25 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
1874 * also passed a netdev to set_wiphy, so that it is 1834 * also passed a netdev to set_wiphy, so that it is
1875 * possible to let that go to the right netdev! 1835 * possible to let that go to the right netdev!
1876 */ 1836 */
1877 mutex_lock(&cfg80211_mutex);
1878 1837
1879 if (info->attrs[NL80211_ATTR_IFINDEX]) { 1838 if (info->attrs[NL80211_ATTR_IFINDEX]) {
1880 int ifindex = nla_get_u32(info->attrs[NL80211_ATTR_IFINDEX]); 1839 int ifindex = nla_get_u32(info->attrs[NL80211_ATTR_IFINDEX]);
1881 1840
1882 netdev = dev_get_by_index(genl_info_net(info), ifindex); 1841 netdev = dev_get_by_index(genl_info_net(info), ifindex);
1883 if (netdev && netdev->ieee80211_ptr) { 1842 if (netdev && netdev->ieee80211_ptr)
1884 rdev = wiphy_to_dev(netdev->ieee80211_ptr->wiphy); 1843 rdev = wiphy_to_dev(netdev->ieee80211_ptr->wiphy);
1885 mutex_lock(&rdev->mtx); 1844 else
1886 } else
1887 netdev = NULL; 1845 netdev = NULL;
1888 } 1846 }
1889 1847
1890 if (!netdev) { 1848 if (!netdev) {
1891 rdev = __cfg80211_rdev_from_attrs(genl_info_net(info), 1849 rdev = __cfg80211_rdev_from_attrs(genl_info_net(info),
1892 info->attrs); 1850 info->attrs);
1893 if (IS_ERR(rdev)) { 1851 if (IS_ERR(rdev))
1894 mutex_unlock(&cfg80211_mutex);
1895 return PTR_ERR(rdev); 1852 return PTR_ERR(rdev);
1896 }
1897 wdev = NULL; 1853 wdev = NULL;
1898 netdev = NULL; 1854 netdev = NULL;
1899 result = 0; 1855 result = 0;
1900
1901 mutex_lock(&rdev->mtx);
1902 } else 1856 } else
1903 wdev = netdev->ieee80211_ptr; 1857 wdev = netdev->ieee80211_ptr;
1904 1858
@@ -1911,8 +1865,6 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
1911 result = cfg80211_dev_rename( 1865 result = cfg80211_dev_rename(
1912 rdev, nla_data(info->attrs[NL80211_ATTR_WIPHY_NAME])); 1866 rdev, nla_data(info->attrs[NL80211_ATTR_WIPHY_NAME]));
1913 1867
1914 mutex_unlock(&cfg80211_mutex);
1915
1916 if (result) 1868 if (result)
1917 goto bad_res; 1869 goto bad_res;
1918 1870
@@ -2119,7 +2071,6 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
2119 } 2071 }
2120 2072
2121 bad_res: 2073 bad_res:
2122 mutex_unlock(&rdev->mtx);
2123 if (netdev) 2074 if (netdev)
2124 dev_put(netdev); 2075 dev_put(netdev);
2125 return result; 2076 return result;
@@ -2217,7 +2168,7 @@ static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *
2217 struct cfg80211_registered_device *rdev; 2168 struct cfg80211_registered_device *rdev;
2218 struct wireless_dev *wdev; 2169 struct wireless_dev *wdev;
2219 2170
2220 mutex_lock(&cfg80211_mutex); 2171 rtnl_lock();
2221 list_for_each_entry(rdev, &cfg80211_rdev_list, list) { 2172 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
2222 if (!net_eq(wiphy_net(&rdev->wiphy), sock_net(skb->sk))) 2173 if (!net_eq(wiphy_net(&rdev->wiphy), sock_net(skb->sk)))
2223 continue; 2174 continue;
@@ -2227,7 +2178,6 @@ static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *
2227 } 2178 }
2228 if_idx = 0; 2179 if_idx = 0;
2229 2180
2230 mutex_lock(&rdev->devlist_mtx);
2231 list_for_each_entry(wdev, &rdev->wdev_list, list) { 2181 list_for_each_entry(wdev, &rdev->wdev_list, list) {
2232 if (if_idx < if_start) { 2182 if (if_idx < if_start) {
2233 if_idx++; 2183 if_idx++;
@@ -2236,17 +2186,15 @@ static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *
2236 if (nl80211_send_iface(skb, NETLINK_CB(cb->skb).portid, 2186 if (nl80211_send_iface(skb, NETLINK_CB(cb->skb).portid,
2237 cb->nlh->nlmsg_seq, NLM_F_MULTI, 2187 cb->nlh->nlmsg_seq, NLM_F_MULTI,
2238 rdev, wdev) < 0) { 2188 rdev, wdev) < 0) {
2239 mutex_unlock(&rdev->devlist_mtx);
2240 goto out; 2189 goto out;
2241 } 2190 }
2242 if_idx++; 2191 if_idx++;
2243 } 2192 }
2244 mutex_unlock(&rdev->devlist_mtx);
2245 2193
2246 wp_idx++; 2194 wp_idx++;
2247 } 2195 }
2248 out: 2196 out:
2249 mutex_unlock(&cfg80211_mutex); 2197 rtnl_unlock();
2250 2198
2251 cb->args[0] = wp_idx; 2199 cb->args[0] = wp_idx;
2252 cb->args[1] = if_idx; 2200 cb->args[1] = if_idx;
@@ -2279,6 +2227,7 @@ static const struct nla_policy mntr_flags_policy[NL80211_MNTR_FLAG_MAX + 1] = {
2279 [NL80211_MNTR_FLAG_CONTROL] = { .type = NLA_FLAG }, 2227 [NL80211_MNTR_FLAG_CONTROL] = { .type = NLA_FLAG },
2280 [NL80211_MNTR_FLAG_OTHER_BSS] = { .type = NLA_FLAG }, 2228 [NL80211_MNTR_FLAG_OTHER_BSS] = { .type = NLA_FLAG },
2281 [NL80211_MNTR_FLAG_COOK_FRAMES] = { .type = NLA_FLAG }, 2229 [NL80211_MNTR_FLAG_COOK_FRAMES] = { .type = NLA_FLAG },
2230 [NL80211_MNTR_FLAG_ACTIVE] = { .type = NLA_FLAG },
2282}; 2231};
2283 2232
2284static int parse_monitor_flags(struct nlattr *nla, u32 *mntrflags) 2233static int parse_monitor_flags(struct nlattr *nla, u32 *mntrflags)
@@ -2390,6 +2339,10 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
2390 change = true; 2339 change = true;
2391 } 2340 }
2392 2341
2342 if (flags && (*flags & NL80211_MNTR_FLAG_ACTIVE) &&
2343 !(rdev->wiphy.features & NL80211_FEATURE_ACTIVE_MONITOR))
2344 return -EOPNOTSUPP;
2345
2393 if (change) 2346 if (change)
2394 err = cfg80211_change_iface(rdev, dev, ntype, flags, &params); 2347 err = cfg80211_change_iface(rdev, dev, ntype, flags, &params);
2395 else 2348 else
@@ -2447,6 +2400,11 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
2447 err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ? 2400 err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ?
2448 info->attrs[NL80211_ATTR_MNTR_FLAGS] : NULL, 2401 info->attrs[NL80211_ATTR_MNTR_FLAGS] : NULL,
2449 &flags); 2402 &flags);
2403
2404 if (!err && (flags & NL80211_MNTR_FLAG_ACTIVE) &&
2405 !(rdev->wiphy.features & NL80211_FEATURE_ACTIVE_MONITOR))
2406 return -EOPNOTSUPP;
2407
2450 wdev = rdev_add_virtual_intf(rdev, 2408 wdev = rdev_add_virtual_intf(rdev,
2451 nla_data(info->attrs[NL80211_ATTR_IFNAME]), 2409 nla_data(info->attrs[NL80211_ATTR_IFNAME]),
2452 type, err ? NULL : &flags, &params); 2410 type, err ? NULL : &flags, &params);
@@ -2479,11 +2437,9 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
2479 INIT_LIST_HEAD(&wdev->mgmt_registrations); 2437 INIT_LIST_HEAD(&wdev->mgmt_registrations);
2480 spin_lock_init(&wdev->mgmt_registrations_lock); 2438 spin_lock_init(&wdev->mgmt_registrations_lock);
2481 2439
2482 mutex_lock(&rdev->devlist_mtx);
2483 wdev->identifier = ++rdev->wdev_id; 2440 wdev->identifier = ++rdev->wdev_id;
2484 list_add_rcu(&wdev->list, &rdev->wdev_list); 2441 list_add_rcu(&wdev->list, &rdev->wdev_list);
2485 rdev->devlist_generation++; 2442 rdev->devlist_generation++;
2486 mutex_unlock(&rdev->devlist_mtx);
2487 break; 2443 break;
2488 default: 2444 default:
2489 break; 2445 break;
@@ -2992,8 +2948,6 @@ static bool nl80211_get_ap_channel(struct cfg80211_registered_device *rdev,
2992 struct wireless_dev *wdev; 2948 struct wireless_dev *wdev;
2993 bool ret = false; 2949 bool ret = false;
2994 2950
2995 mutex_lock(&rdev->devlist_mtx);
2996
2997 list_for_each_entry(wdev, &rdev->wdev_list, list) { 2951 list_for_each_entry(wdev, &rdev->wdev_list, list) {
2998 if (wdev->iftype != NL80211_IFTYPE_AP && 2952 if (wdev->iftype != NL80211_IFTYPE_AP &&
2999 wdev->iftype != NL80211_IFTYPE_P2P_GO) 2953 wdev->iftype != NL80211_IFTYPE_P2P_GO)
@@ -3007,8 +2961,6 @@ static bool nl80211_get_ap_channel(struct cfg80211_registered_device *rdev,
3007 break; 2961 break;
3008 } 2962 }
3009 2963
3010 mutex_unlock(&rdev->devlist_mtx);
3011
3012 return ret; 2964 return ret;
3013} 2965}
3014 2966
@@ -3170,13 +3122,10 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
3170 params.radar_required = true; 3122 params.radar_required = true;
3171 } 3123 }
3172 3124
3173 mutex_lock(&rdev->devlist_mtx);
3174 err = cfg80211_can_use_iftype_chan(rdev, wdev, wdev->iftype, 3125 err = cfg80211_can_use_iftype_chan(rdev, wdev, wdev->iftype,
3175 params.chandef.chan, 3126 params.chandef.chan,
3176 CHAN_MODE_SHARED, 3127 CHAN_MODE_SHARED,
3177 radar_detect_width); 3128 radar_detect_width);
3178 mutex_unlock(&rdev->devlist_mtx);
3179
3180 if (err) 3129 if (err)
3181 return err; 3130 return err;
3182 3131
@@ -3376,6 +3325,32 @@ static bool nl80211_put_sta_rate(struct sk_buff *msg, struct rate_info *info,
3376 return true; 3325 return true;
3377} 3326}
3378 3327
3328static bool nl80211_put_signal(struct sk_buff *msg, u8 mask, s8 *signal,
3329 int id)
3330{
3331 void *attr;
3332 int i = 0;
3333
3334 if (!mask)
3335 return true;
3336
3337 attr = nla_nest_start(msg, id);
3338 if (!attr)
3339 return false;
3340
3341 for (i = 0; i < IEEE80211_MAX_CHAINS; i++) {
3342 if (!(mask & BIT(i)))
3343 continue;
3344
3345 if (nla_put_u8(msg, i, signal[i]))
3346 return false;
3347 }
3348
3349 nla_nest_end(msg, attr);
3350
3351 return true;
3352}
3353
3379static int nl80211_send_station(struct sk_buff *msg, u32 portid, u32 seq, 3354static int nl80211_send_station(struct sk_buff *msg, u32 portid, u32 seq,
3380 int flags, 3355 int flags,
3381 struct cfg80211_registered_device *rdev, 3356 struct cfg80211_registered_device *rdev,
@@ -3447,6 +3422,18 @@ static int nl80211_send_station(struct sk_buff *msg, u32 portid, u32 seq,
3447 default: 3422 default:
3448 break; 3423 break;
3449 } 3424 }
3425 if (sinfo->filled & STATION_INFO_CHAIN_SIGNAL) {
3426 if (!nl80211_put_signal(msg, sinfo->chains,
3427 sinfo->chain_signal,
3428 NL80211_STA_INFO_CHAIN_SIGNAL))
3429 goto nla_put_failure;
3430 }
3431 if (sinfo->filled & STATION_INFO_CHAIN_SIGNAL_AVG) {
3432 if (!nl80211_put_signal(msg, sinfo->chains,
3433 sinfo->chain_signal_avg,
3434 NL80211_STA_INFO_CHAIN_SIGNAL_AVG))
3435 goto nla_put_failure;
3436 }
3450 if (sinfo->filled & STATION_INFO_TX_BITRATE) { 3437 if (sinfo->filled & STATION_INFO_TX_BITRATE) {
3451 if (!nl80211_put_sta_rate(msg, &sinfo->txrate, 3438 if (!nl80211_put_sta_rate(msg, &sinfo->txrate,
3452 NL80211_STA_INFO_TX_BITRATE)) 3439 NL80211_STA_INFO_TX_BITRATE))
@@ -3834,6 +3821,8 @@ static int nl80211_set_station_tdls(struct genl_info *info,
3834 struct station_parameters *params) 3821 struct station_parameters *params)
3835{ 3822{
3836 /* Dummy STA entry gets updated once the peer capabilities are known */ 3823 /* Dummy STA entry gets updated once the peer capabilities are known */
3824 if (info->attrs[NL80211_ATTR_PEER_AID])
3825 params->aid = nla_get_u16(info->attrs[NL80211_ATTR_PEER_AID]);
3837 if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) 3826 if (info->attrs[NL80211_ATTR_HT_CAPABILITY])
3838 params->ht_capa = 3827 params->ht_capa =
3839 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]); 3828 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
@@ -3974,7 +3963,8 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
3974 if (!info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]) 3963 if (!info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES])
3975 return -EINVAL; 3964 return -EINVAL;
3976 3965
3977 if (!info->attrs[NL80211_ATTR_STA_AID]) 3966 if (!info->attrs[NL80211_ATTR_STA_AID] &&
3967 !info->attrs[NL80211_ATTR_PEER_AID])
3978 return -EINVAL; 3968 return -EINVAL;
3979 3969
3980 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); 3970 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
@@ -3985,7 +3975,10 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
3985 params.listen_interval = 3975 params.listen_interval =
3986 nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]); 3976 nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
3987 3977
3988 params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]); 3978 if (info->attrs[NL80211_ATTR_STA_AID])
3979 params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]);
3980 else
3981 params.aid = nla_get_u16(info->attrs[NL80211_ATTR_PEER_AID]);
3989 if (!params.aid || params.aid > IEEE80211_MAX_AID) 3982 if (!params.aid || params.aid > IEEE80211_MAX_AID)
3990 return -EINVAL; 3983 return -EINVAL;
3991 3984
@@ -4634,6 +4627,7 @@ static const struct nla_policy
4634 [NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL] = { .type = NLA_U8 }, 4627 [NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL] = { .type = NLA_U8 },
4635 [NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC] = { .type = NLA_U8 }, 4628 [NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC] = { .type = NLA_U8 },
4636 [NL80211_MESH_SETUP_USERSPACE_AUTH] = { .type = NLA_FLAG }, 4629 [NL80211_MESH_SETUP_USERSPACE_AUTH] = { .type = NLA_FLAG },
4630 [NL80211_MESH_SETUP_AUTH_PROTOCOL] = { .type = NLA_U8 },
4637 [NL80211_MESH_SETUP_USERSPACE_MPM] = { .type = NLA_FLAG }, 4631 [NL80211_MESH_SETUP_USERSPACE_MPM] = { .type = NLA_FLAG },
4638 [NL80211_MESH_SETUP_IE] = { .type = NLA_BINARY, 4632 [NL80211_MESH_SETUP_IE] = { .type = NLA_BINARY,
4639 .len = IEEE80211_MAX_DATA_LEN }, 4633 .len = IEEE80211_MAX_DATA_LEN },
@@ -4819,6 +4813,13 @@ static int nl80211_parse_mesh_setup(struct genl_info *info,
4819 if (setup->is_secure) 4813 if (setup->is_secure)
4820 setup->user_mpm = true; 4814 setup->user_mpm = true;
4821 4815
4816 if (tb[NL80211_MESH_SETUP_AUTH_PROTOCOL]) {
4817 if (!setup->user_mpm)
4818 return -EINVAL;
4819 setup->auth_id =
4820 nla_get_u8(tb[NL80211_MESH_SETUP_AUTH_PROTOCOL]);
4821 }
4822
4822 return 0; 4823 return 0;
4823} 4824}
4824 4825
@@ -4861,18 +4862,13 @@ static int nl80211_get_reg(struct sk_buff *skb, struct genl_info *info)
4861 void *hdr = NULL; 4862 void *hdr = NULL;
4862 struct nlattr *nl_reg_rules; 4863 struct nlattr *nl_reg_rules;
4863 unsigned int i; 4864 unsigned int i;
4864 int err = -EINVAL;
4865
4866 mutex_lock(&cfg80211_mutex);
4867 4865
4868 if (!cfg80211_regdomain) 4866 if (!cfg80211_regdomain)
4869 goto out; 4867 return -EINVAL;
4870 4868
4871 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 4869 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4872 if (!msg) { 4870 if (!msg)
4873 err = -ENOBUFS; 4871 return -ENOBUFS;
4874 goto out;
4875 }
4876 4872
4877 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0, 4873 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
4878 NL80211_CMD_GET_REG); 4874 NL80211_CMD_GET_REG);
@@ -4931,8 +4927,7 @@ static int nl80211_get_reg(struct sk_buff *skb, struct genl_info *info)
4931 nla_nest_end(msg, nl_reg_rules); 4927 nla_nest_end(msg, nl_reg_rules);
4932 4928
4933 genlmsg_end(msg, hdr); 4929 genlmsg_end(msg, hdr);
4934 err = genlmsg_reply(msg, info); 4930 return genlmsg_reply(msg, info);
4935 goto out;
4936 4931
4937nla_put_failure_rcu: 4932nla_put_failure_rcu:
4938 rcu_read_unlock(); 4933 rcu_read_unlock();
@@ -4940,10 +4935,7 @@ nla_put_failure:
4940 genlmsg_cancel(msg, hdr); 4935 genlmsg_cancel(msg, hdr);
4941put_failure: 4936put_failure:
4942 nlmsg_free(msg); 4937 nlmsg_free(msg);
4943 err = -EMSGSIZE; 4938 return -EMSGSIZE;
4944out:
4945 mutex_unlock(&cfg80211_mutex);
4946 return err;
4947} 4939}
4948 4940
4949static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info) 4941static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
@@ -5009,12 +5001,9 @@ static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
5009 } 5001 }
5010 } 5002 }
5011 5003
5012 mutex_lock(&cfg80211_mutex);
5013
5014 r = set_regdom(rd); 5004 r = set_regdom(rd);
5015 /* set_regdom took ownership */ 5005 /* set_regdom took ownership */
5016 rd = NULL; 5006 rd = NULL;
5017 mutex_unlock(&cfg80211_mutex);
5018 5007
5019 bad_reg: 5008 bad_reg:
5020 kfree(rd); 5009 kfree(rd);
@@ -5064,7 +5053,6 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
5064 if (!rdev->ops->scan) 5053 if (!rdev->ops->scan)
5065 return -EOPNOTSUPP; 5054 return -EOPNOTSUPP;
5066 5055
5067 mutex_lock(&rdev->sched_scan_mtx);
5068 if (rdev->scan_req) { 5056 if (rdev->scan_req) {
5069 err = -EBUSY; 5057 err = -EBUSY;
5070 goto unlock; 5058 goto unlock;
@@ -5250,7 +5238,6 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
5250 } 5238 }
5251 5239
5252 unlock: 5240 unlock:
5253 mutex_unlock(&rdev->sched_scan_mtx);
5254 return err; 5241 return err;
5255} 5242}
5256 5243
@@ -5322,8 +5309,6 @@ static int nl80211_start_sched_scan(struct sk_buff *skb,
5322 if (ie_len > wiphy->max_sched_scan_ie_len) 5309 if (ie_len > wiphy->max_sched_scan_ie_len)
5323 return -EINVAL; 5310 return -EINVAL;
5324 5311
5325 mutex_lock(&rdev->sched_scan_mtx);
5326
5327 if (rdev->sched_scan_req) { 5312 if (rdev->sched_scan_req) {
5328 err = -EINPROGRESS; 5313 err = -EINPROGRESS;
5329 goto out; 5314 goto out;
@@ -5491,7 +5476,6 @@ static int nl80211_start_sched_scan(struct sk_buff *skb,
5491out_free: 5476out_free:
5492 kfree(request); 5477 kfree(request);
5493out: 5478out:
5494 mutex_unlock(&rdev->sched_scan_mtx);
5495 return err; 5479 return err;
5496} 5480}
5497 5481
@@ -5499,17 +5483,12 @@ static int nl80211_stop_sched_scan(struct sk_buff *skb,
5499 struct genl_info *info) 5483 struct genl_info *info)
5500{ 5484{
5501 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 5485 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5502 int err;
5503 5486
5504 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) || 5487 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) ||
5505 !rdev->ops->sched_scan_stop) 5488 !rdev->ops->sched_scan_stop)
5506 return -EOPNOTSUPP; 5489 return -EOPNOTSUPP;
5507 5490
5508 mutex_lock(&rdev->sched_scan_mtx); 5491 return __cfg80211_stop_sched_scan(rdev, false);
5509 err = __cfg80211_stop_sched_scan(rdev, false);
5510 mutex_unlock(&rdev->sched_scan_mtx);
5511
5512 return err;
5513} 5492}
5514 5493
5515static int nl80211_start_radar_detection(struct sk_buff *skb, 5494static int nl80211_start_radar_detection(struct sk_buff *skb,
@@ -5541,12 +5520,11 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
5541 if (!rdev->ops->start_radar_detection) 5520 if (!rdev->ops->start_radar_detection)
5542 return -EOPNOTSUPP; 5521 return -EOPNOTSUPP;
5543 5522
5544 mutex_lock(&rdev->devlist_mtx);
5545 err = cfg80211_can_use_iftype_chan(rdev, wdev, wdev->iftype, 5523 err = cfg80211_can_use_iftype_chan(rdev, wdev, wdev->iftype,
5546 chandef.chan, CHAN_MODE_SHARED, 5524 chandef.chan, CHAN_MODE_SHARED,
5547 BIT(chandef.width)); 5525 BIT(chandef.width));
5548 if (err) 5526 if (err)
5549 goto err_locked; 5527 return err;
5550 5528
5551 err = rdev->ops->start_radar_detection(&rdev->wiphy, dev, &chandef); 5529 err = rdev->ops->start_radar_detection(&rdev->wiphy, dev, &chandef);
5552 if (!err) { 5530 if (!err) {
@@ -5554,9 +5532,6 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
5554 wdev->cac_started = true; 5532 wdev->cac_started = true;
5555 wdev->cac_start_time = jiffies; 5533 wdev->cac_start_time = jiffies;
5556 } 5534 }
5557err_locked:
5558 mutex_unlock(&rdev->devlist_mtx);
5559
5560 return err; 5535 return err;
5561} 5536}
5562 5537
@@ -5939,10 +5914,13 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
5939 if (local_state_change) 5914 if (local_state_change)
5940 return 0; 5915 return 0;
5941 5916
5942 return cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid, 5917 wdev_lock(dev->ieee80211_ptr);
5943 ssid, ssid_len, ie, ie_len, 5918 err = cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid,
5944 key.p.key, key.p.key_len, key.idx, 5919 ssid, ssid_len, ie, ie_len,
5945 sae_data, sae_data_len); 5920 key.p.key, key.p.key_len, key.idx,
5921 sae_data, sae_data_len);
5922 wdev_unlock(dev->ieee80211_ptr);
5923 return err;
5946} 5924}
5947 5925
5948static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev, 5926static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev,
@@ -6109,9 +6087,12 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
6109 } 6087 }
6110 6088
6111 err = nl80211_crypto_settings(rdev, info, &req.crypto, 1); 6089 err = nl80211_crypto_settings(rdev, info, &req.crypto, 1);
6112 if (!err) 6090 if (!err) {
6091 wdev_lock(dev->ieee80211_ptr);
6113 err = cfg80211_mlme_assoc(rdev, dev, chan, bssid, 6092 err = cfg80211_mlme_assoc(rdev, dev, chan, bssid,
6114 ssid, ssid_len, &req); 6093 ssid, ssid_len, &req);
6094 wdev_unlock(dev->ieee80211_ptr);
6095 }
6115 6096
6116 return err; 6097 return err;
6117} 6098}
@@ -6121,7 +6102,7 @@ static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info)
6121 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 6102 struct cfg80211_registered_device *rdev = info->user_ptr[0];
6122 struct net_device *dev = info->user_ptr[1]; 6103 struct net_device *dev = info->user_ptr[1];
6123 const u8 *ie = NULL, *bssid; 6104 const u8 *ie = NULL, *bssid;
6124 int ie_len = 0; 6105 int ie_len = 0, err;
6125 u16 reason_code; 6106 u16 reason_code;
6126 bool local_state_change; 6107 bool local_state_change;
6127 6108
@@ -6156,8 +6137,11 @@ static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info)
6156 6137
6157 local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE]; 6138 local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE];
6158 6139
6159 return cfg80211_mlme_deauth(rdev, dev, bssid, ie, ie_len, reason_code, 6140 wdev_lock(dev->ieee80211_ptr);
6160 local_state_change); 6141 err = cfg80211_mlme_deauth(rdev, dev, bssid, ie, ie_len, reason_code,
6142 local_state_change);
6143 wdev_unlock(dev->ieee80211_ptr);
6144 return err;
6161} 6145}
6162 6146
6163static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info) 6147static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info)
@@ -6165,7 +6149,7 @@ static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info)
6165 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 6149 struct cfg80211_registered_device *rdev = info->user_ptr[0];
6166 struct net_device *dev = info->user_ptr[1]; 6150 struct net_device *dev = info->user_ptr[1];
6167 const u8 *ie = NULL, *bssid; 6151 const u8 *ie = NULL, *bssid;
6168 int ie_len = 0; 6152 int ie_len = 0, err;
6169 u16 reason_code; 6153 u16 reason_code;
6170 bool local_state_change; 6154 bool local_state_change;
6171 6155
@@ -6200,8 +6184,11 @@ static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info)
6200 6184
6201 local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE]; 6185 local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE];
6202 6186
6203 return cfg80211_mlme_disassoc(rdev, dev, bssid, ie, ie_len, reason_code, 6187 wdev_lock(dev->ieee80211_ptr);
6204 local_state_change); 6188 err = cfg80211_mlme_disassoc(rdev, dev, bssid, ie, ie_len, reason_code,
6189 local_state_change);
6190 wdev_unlock(dev->ieee80211_ptr);
6191 return err;
6205} 6192}
6206 6193
6207static bool 6194static bool
@@ -6419,6 +6406,8 @@ static int nl80211_testmode_dump(struct sk_buff *skb,
6419 void *data = NULL; 6406 void *data = NULL;
6420 int data_len = 0; 6407 int data_len = 0;
6421 6408
6409 rtnl_lock();
6410
6422 if (cb->args[0]) { 6411 if (cb->args[0]) {
6423 /* 6412 /*
6424 * 0 is a valid index, but not valid for args[0], 6413 * 0 is a valid index, but not valid for args[0],
@@ -6430,18 +6419,16 @@ static int nl80211_testmode_dump(struct sk_buff *skb,
6430 nl80211_fam.attrbuf, nl80211_fam.maxattr, 6419 nl80211_fam.attrbuf, nl80211_fam.maxattr,
6431 nl80211_policy); 6420 nl80211_policy);
6432 if (err) 6421 if (err)
6433 return err; 6422 goto out_err;
6434 6423
6435 mutex_lock(&cfg80211_mutex);
6436 rdev = __cfg80211_rdev_from_attrs(sock_net(skb->sk), 6424 rdev = __cfg80211_rdev_from_attrs(sock_net(skb->sk),
6437 nl80211_fam.attrbuf); 6425 nl80211_fam.attrbuf);
6438 if (IS_ERR(rdev)) { 6426 if (IS_ERR(rdev)) {
6439 mutex_unlock(&cfg80211_mutex); 6427 err = PTR_ERR(rdev);
6440 return PTR_ERR(rdev); 6428 goto out_err;
6441 } 6429 }
6442 phy_idx = rdev->wiphy_idx; 6430 phy_idx = rdev->wiphy_idx;
6443 rdev = NULL; 6431 rdev = NULL;
6444 mutex_unlock(&cfg80211_mutex);
6445 6432
6446 if (nl80211_fam.attrbuf[NL80211_ATTR_TESTDATA]) 6433 if (nl80211_fam.attrbuf[NL80211_ATTR_TESTDATA])
6447 cb->args[1] = 6434 cb->args[1] =
@@ -6453,14 +6440,11 @@ static int nl80211_testmode_dump(struct sk_buff *skb,
6453 data_len = nla_len((void *)cb->args[1]); 6440 data_len = nla_len((void *)cb->args[1]);
6454 } 6441 }
6455 6442
6456 mutex_lock(&cfg80211_mutex);
6457 rdev = cfg80211_rdev_by_wiphy_idx(phy_idx); 6443 rdev = cfg80211_rdev_by_wiphy_idx(phy_idx);
6458 if (!rdev) { 6444 if (!rdev) {
6459 mutex_unlock(&cfg80211_mutex); 6445 err = -ENOENT;
6460 return -ENOENT; 6446 goto out_err;
6461 } 6447 }
6462 cfg80211_lock_rdev(rdev);
6463 mutex_unlock(&cfg80211_mutex);
6464 6448
6465 if (!rdev->ops->testmode_dump) { 6449 if (!rdev->ops->testmode_dump) {
6466 err = -EOPNOTSUPP; 6450 err = -EOPNOTSUPP;
@@ -6501,7 +6485,7 @@ static int nl80211_testmode_dump(struct sk_buff *skb,
6501 /* see above */ 6485 /* see above */
6502 cb->args[0] = phy_idx + 1; 6486 cb->args[0] = phy_idx + 1;
6503 out_err: 6487 out_err:
6504 cfg80211_unlock_rdev(rdev); 6488 rtnl_unlock();
6505 return err; 6489 return err;
6506} 6490}
6507 6491
@@ -6709,7 +6693,9 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
6709 sizeof(connect.vht_capa)); 6693 sizeof(connect.vht_capa));
6710 } 6694 }
6711 6695
6712 err = cfg80211_connect(rdev, dev, &connect, connkeys); 6696 wdev_lock(dev->ieee80211_ptr);
6697 err = cfg80211_connect(rdev, dev, &connect, connkeys, NULL);
6698 wdev_unlock(dev->ieee80211_ptr);
6713 if (err) 6699 if (err)
6714 kfree(connkeys); 6700 kfree(connkeys);
6715 return err; 6701 return err;
@@ -6720,6 +6706,7 @@ static int nl80211_disconnect(struct sk_buff *skb, struct genl_info *info)
6720 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 6706 struct cfg80211_registered_device *rdev = info->user_ptr[0];
6721 struct net_device *dev = info->user_ptr[1]; 6707 struct net_device *dev = info->user_ptr[1];
6722 u16 reason; 6708 u16 reason;
6709 int ret;
6723 6710
6724 if (!info->attrs[NL80211_ATTR_REASON_CODE]) 6711 if (!info->attrs[NL80211_ATTR_REASON_CODE])
6725 reason = WLAN_REASON_DEAUTH_LEAVING; 6712 reason = WLAN_REASON_DEAUTH_LEAVING;
@@ -6733,7 +6720,10 @@ static int nl80211_disconnect(struct sk_buff *skb, struct genl_info *info)
6733 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) 6720 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
6734 return -EOPNOTSUPP; 6721 return -EOPNOTSUPP;
6735 6722
6736 return cfg80211_disconnect(rdev, dev, reason, true); 6723 wdev_lock(dev->ieee80211_ptr);
6724 ret = cfg80211_disconnect(rdev, dev, reason, true);
6725 wdev_unlock(dev->ieee80211_ptr);
6726 return ret;
6737} 6727}
6738 6728
6739static int nl80211_wiphy_netns(struct sk_buff *skb, struct genl_info *info) 6729static int nl80211_wiphy_netns(struct sk_buff *skb, struct genl_info *info)
@@ -7509,28 +7499,29 @@ static int nl80211_leave_mesh(struct sk_buff *skb, struct genl_info *info)
7509static int nl80211_send_wowlan_patterns(struct sk_buff *msg, 7499static int nl80211_send_wowlan_patterns(struct sk_buff *msg,
7510 struct cfg80211_registered_device *rdev) 7500 struct cfg80211_registered_device *rdev)
7511{ 7501{
7502 struct cfg80211_wowlan *wowlan = rdev->wiphy.wowlan_config;
7512 struct nlattr *nl_pats, *nl_pat; 7503 struct nlattr *nl_pats, *nl_pat;
7513 int i, pat_len; 7504 int i, pat_len;
7514 7505
7515 if (!rdev->wowlan->n_patterns) 7506 if (!wowlan->n_patterns)
7516 return 0; 7507 return 0;
7517 7508
7518 nl_pats = nla_nest_start(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN); 7509 nl_pats = nla_nest_start(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN);
7519 if (!nl_pats) 7510 if (!nl_pats)
7520 return -ENOBUFS; 7511 return -ENOBUFS;
7521 7512
7522 for (i = 0; i < rdev->wowlan->n_patterns; i++) { 7513 for (i = 0; i < wowlan->n_patterns; i++) {
7523 nl_pat = nla_nest_start(msg, i + 1); 7514 nl_pat = nla_nest_start(msg, i + 1);
7524 if (!nl_pat) 7515 if (!nl_pat)
7525 return -ENOBUFS; 7516 return -ENOBUFS;
7526 pat_len = rdev->wowlan->patterns[i].pattern_len; 7517 pat_len = wowlan->patterns[i].pattern_len;
7527 if (nla_put(msg, NL80211_WOWLAN_PKTPAT_MASK, 7518 if (nla_put(msg, NL80211_WOWLAN_PKTPAT_MASK,
7528 DIV_ROUND_UP(pat_len, 8), 7519 DIV_ROUND_UP(pat_len, 8),
7529 rdev->wowlan->patterns[i].mask) || 7520 wowlan->patterns[i].mask) ||
7530 nla_put(msg, NL80211_WOWLAN_PKTPAT_PATTERN, 7521 nla_put(msg, NL80211_WOWLAN_PKTPAT_PATTERN,
7531 pat_len, rdev->wowlan->patterns[i].pattern) || 7522 pat_len, wowlan->patterns[i].pattern) ||
7532 nla_put_u32(msg, NL80211_WOWLAN_PKTPAT_OFFSET, 7523 nla_put_u32(msg, NL80211_WOWLAN_PKTPAT_OFFSET,
7533 rdev->wowlan->patterns[i].pkt_offset)) 7524 wowlan->patterns[i].pkt_offset))
7534 return -ENOBUFS; 7525 return -ENOBUFS;
7535 nla_nest_end(msg, nl_pat); 7526 nla_nest_end(msg, nl_pat);
7536 } 7527 }
@@ -7593,12 +7584,12 @@ static int nl80211_get_wowlan(struct sk_buff *skb, struct genl_info *info)
7593 !rdev->wiphy.wowlan.tcp) 7584 !rdev->wiphy.wowlan.tcp)
7594 return -EOPNOTSUPP; 7585 return -EOPNOTSUPP;
7595 7586
7596 if (rdev->wowlan && rdev->wowlan->tcp) { 7587 if (rdev->wiphy.wowlan_config && rdev->wiphy.wowlan_config->tcp) {
7597 /* adjust size to have room for all the data */ 7588 /* adjust size to have room for all the data */
7598 size += rdev->wowlan->tcp->tokens_size + 7589 size += rdev->wiphy.wowlan_config->tcp->tokens_size +
7599 rdev->wowlan->tcp->payload_len + 7590 rdev->wiphy.wowlan_config->tcp->payload_len +
7600 rdev->wowlan->tcp->wake_len + 7591 rdev->wiphy.wowlan_config->tcp->wake_len +
7601 rdev->wowlan->tcp->wake_len / 8; 7592 rdev->wiphy.wowlan_config->tcp->wake_len / 8;
7602 } 7593 }
7603 7594
7604 msg = nlmsg_new(size, GFP_KERNEL); 7595 msg = nlmsg_new(size, GFP_KERNEL);
@@ -7610,33 +7601,34 @@ static int nl80211_get_wowlan(struct sk_buff *skb, struct genl_info *info)
7610 if (!hdr) 7601 if (!hdr)
7611 goto nla_put_failure; 7602 goto nla_put_failure;
7612 7603
7613 if (rdev->wowlan) { 7604 if (rdev->wiphy.wowlan_config) {
7614 struct nlattr *nl_wowlan; 7605 struct nlattr *nl_wowlan;
7615 7606
7616 nl_wowlan = nla_nest_start(msg, NL80211_ATTR_WOWLAN_TRIGGERS); 7607 nl_wowlan = nla_nest_start(msg, NL80211_ATTR_WOWLAN_TRIGGERS);
7617 if (!nl_wowlan) 7608 if (!nl_wowlan)
7618 goto nla_put_failure; 7609 goto nla_put_failure;
7619 7610
7620 if ((rdev->wowlan->any && 7611 if ((rdev->wiphy.wowlan_config->any &&
7621 nla_put_flag(msg, NL80211_WOWLAN_TRIG_ANY)) || 7612 nla_put_flag(msg, NL80211_WOWLAN_TRIG_ANY)) ||
7622 (rdev->wowlan->disconnect && 7613 (rdev->wiphy.wowlan_config->disconnect &&
7623 nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT)) || 7614 nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT)) ||
7624 (rdev->wowlan->magic_pkt && 7615 (rdev->wiphy.wowlan_config->magic_pkt &&
7625 nla_put_flag(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT)) || 7616 nla_put_flag(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT)) ||
7626 (rdev->wowlan->gtk_rekey_failure && 7617 (rdev->wiphy.wowlan_config->gtk_rekey_failure &&
7627 nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE)) || 7618 nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE)) ||
7628 (rdev->wowlan->eap_identity_req && 7619 (rdev->wiphy.wowlan_config->eap_identity_req &&
7629 nla_put_flag(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST)) || 7620 nla_put_flag(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST)) ||
7630 (rdev->wowlan->four_way_handshake && 7621 (rdev->wiphy.wowlan_config->four_way_handshake &&
7631 nla_put_flag(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE)) || 7622 nla_put_flag(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE)) ||
7632 (rdev->wowlan->rfkill_release && 7623 (rdev->wiphy.wowlan_config->rfkill_release &&
7633 nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE))) 7624 nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE)))
7634 goto nla_put_failure; 7625 goto nla_put_failure;
7635 7626
7636 if (nl80211_send_wowlan_patterns(msg, rdev)) 7627 if (nl80211_send_wowlan_patterns(msg, rdev))
7637 goto nla_put_failure; 7628 goto nla_put_failure;
7638 7629
7639 if (nl80211_send_wowlan_tcp(msg, rdev->wowlan->tcp)) 7630 if (nl80211_send_wowlan_tcp(msg,
7631 rdev->wiphy.wowlan_config->tcp))
7640 goto nla_put_failure; 7632 goto nla_put_failure;
7641 7633
7642 nla_nest_end(msg, nl_wowlan); 7634 nla_nest_end(msg, nl_wowlan);
@@ -7803,7 +7795,7 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
7803 struct cfg80211_wowlan *ntrig; 7795 struct cfg80211_wowlan *ntrig;
7804 struct wiphy_wowlan_support *wowlan = &rdev->wiphy.wowlan; 7796 struct wiphy_wowlan_support *wowlan = &rdev->wiphy.wowlan;
7805 int err, i; 7797 int err, i;
7806 bool prev_enabled = rdev->wowlan; 7798 bool prev_enabled = rdev->wiphy.wowlan_config;
7807 7799
7808 if (!rdev->wiphy.wowlan.flags && !rdev->wiphy.wowlan.n_patterns && 7800 if (!rdev->wiphy.wowlan.flags && !rdev->wiphy.wowlan.n_patterns &&
7809 !rdev->wiphy.wowlan.tcp) 7801 !rdev->wiphy.wowlan.tcp)
@@ -7811,7 +7803,7 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
7811 7803
7812 if (!info->attrs[NL80211_ATTR_WOWLAN_TRIGGERS]) { 7804 if (!info->attrs[NL80211_ATTR_WOWLAN_TRIGGERS]) {
7813 cfg80211_rdev_free_wowlan(rdev); 7805 cfg80211_rdev_free_wowlan(rdev);
7814 rdev->wowlan = NULL; 7806 rdev->wiphy.wowlan_config = NULL;
7815 goto set_wakeup; 7807 goto set_wakeup;
7816 } 7808 }
7817 7809
@@ -7947,11 +7939,12 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
7947 goto error; 7939 goto error;
7948 } 7940 }
7949 cfg80211_rdev_free_wowlan(rdev); 7941 cfg80211_rdev_free_wowlan(rdev);
7950 rdev->wowlan = ntrig; 7942 rdev->wiphy.wowlan_config = ntrig;
7951 7943
7952 set_wakeup: 7944 set_wakeup:
7953 if (rdev->ops->set_wakeup && prev_enabled != !!rdev->wowlan) 7945 if (rdev->ops->set_wakeup &&
7954 rdev_set_wakeup(rdev, rdev->wowlan); 7946 prev_enabled != !!rdev->wiphy.wowlan_config)
7947 rdev_set_wakeup(rdev, rdev->wiphy.wowlan_config);
7955 7948
7956 return 0; 7949 return 0;
7957 error: 7950 error:
@@ -8136,9 +8129,7 @@ static int nl80211_start_p2p_device(struct sk_buff *skb, struct genl_info *info)
8136 if (wdev->p2p_started) 8129 if (wdev->p2p_started)
8137 return 0; 8130 return 0;
8138 8131
8139 mutex_lock(&rdev->devlist_mtx);
8140 err = cfg80211_can_add_interface(rdev, wdev->iftype); 8132 err = cfg80211_can_add_interface(rdev, wdev->iftype);
8141 mutex_unlock(&rdev->devlist_mtx);
8142 if (err) 8133 if (err)
8143 return err; 8134 return err;
8144 8135
@@ -8147,9 +8138,7 @@ static int nl80211_start_p2p_device(struct sk_buff *skb, struct genl_info *info)
8147 return err; 8138 return err;
8148 8139
8149 wdev->p2p_started = true; 8140 wdev->p2p_started = true;
8150 mutex_lock(&rdev->devlist_mtx);
8151 rdev->opencount++; 8141 rdev->opencount++;
8152 mutex_unlock(&rdev->devlist_mtx);
8153 8142
8154 return 0; 8143 return 0;
8155} 8144}
@@ -8165,11 +8154,7 @@ static int nl80211_stop_p2p_device(struct sk_buff *skb, struct genl_info *info)
8165 if (!rdev->ops->stop_p2p_device) 8154 if (!rdev->ops->stop_p2p_device)
8166 return -EOPNOTSUPP; 8155 return -EOPNOTSUPP;
8167 8156
8168 mutex_lock(&rdev->devlist_mtx);
8169 mutex_lock(&rdev->sched_scan_mtx);
8170 cfg80211_stop_p2p_device(rdev, wdev); 8157 cfg80211_stop_p2p_device(rdev, wdev);
8171 mutex_unlock(&rdev->sched_scan_mtx);
8172 mutex_unlock(&rdev->devlist_mtx);
8173 8158
8174 return 0; 8159 return 0;
8175} 8160}
@@ -8312,11 +8297,11 @@ static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb,
8312 info->user_ptr[0] = rdev; 8297 info->user_ptr[0] = rdev;
8313 } else if (ops->internal_flags & NL80211_FLAG_NEED_NETDEV || 8298 } else if (ops->internal_flags & NL80211_FLAG_NEED_NETDEV ||
8314 ops->internal_flags & NL80211_FLAG_NEED_WDEV) { 8299 ops->internal_flags & NL80211_FLAG_NEED_WDEV) {
8315 mutex_lock(&cfg80211_mutex); 8300 ASSERT_RTNL();
8301
8316 wdev = __cfg80211_wdev_from_attrs(genl_info_net(info), 8302 wdev = __cfg80211_wdev_from_attrs(genl_info_net(info),
8317 info->attrs); 8303 info->attrs);
8318 if (IS_ERR(wdev)) { 8304 if (IS_ERR(wdev)) {
8319 mutex_unlock(&cfg80211_mutex);
8320 if (rtnl) 8305 if (rtnl)
8321 rtnl_unlock(); 8306 rtnl_unlock();
8322 return PTR_ERR(wdev); 8307 return PTR_ERR(wdev);
@@ -8327,7 +8312,6 @@ static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb,
8327 8312
8328 if (ops->internal_flags & NL80211_FLAG_NEED_NETDEV) { 8313 if (ops->internal_flags & NL80211_FLAG_NEED_NETDEV) {
8329 if (!dev) { 8314 if (!dev) {
8330 mutex_unlock(&cfg80211_mutex);
8331 if (rtnl) 8315 if (rtnl)
8332 rtnl_unlock(); 8316 rtnl_unlock();
8333 return -EINVAL; 8317 return -EINVAL;
@@ -8341,7 +8325,6 @@ static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb,
8341 if (dev) { 8325 if (dev) {
8342 if (ops->internal_flags & NL80211_FLAG_CHECK_NETDEV_UP && 8326 if (ops->internal_flags & NL80211_FLAG_CHECK_NETDEV_UP &&
8343 !netif_running(dev)) { 8327 !netif_running(dev)) {
8344 mutex_unlock(&cfg80211_mutex);
8345 if (rtnl) 8328 if (rtnl)
8346 rtnl_unlock(); 8329 rtnl_unlock();
8347 return -ENETDOWN; 8330 return -ENETDOWN;
@@ -8350,17 +8333,12 @@ static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb,
8350 dev_hold(dev); 8333 dev_hold(dev);
8351 } else if (ops->internal_flags & NL80211_FLAG_CHECK_NETDEV_UP) { 8334 } else if (ops->internal_flags & NL80211_FLAG_CHECK_NETDEV_UP) {
8352 if (!wdev->p2p_started) { 8335 if (!wdev->p2p_started) {
8353 mutex_unlock(&cfg80211_mutex);
8354 if (rtnl) 8336 if (rtnl)
8355 rtnl_unlock(); 8337 rtnl_unlock();
8356 return -ENETDOWN; 8338 return -ENETDOWN;
8357 } 8339 }
8358 } 8340 }
8359 8341
8360 cfg80211_lock_rdev(rdev);
8361
8362 mutex_unlock(&cfg80211_mutex);
8363
8364 info->user_ptr[0] = rdev; 8342 info->user_ptr[0] = rdev;
8365 } 8343 }
8366 8344
@@ -8370,8 +8348,6 @@ static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb,
8370static void nl80211_post_doit(struct genl_ops *ops, struct sk_buff *skb, 8348static void nl80211_post_doit(struct genl_ops *ops, struct sk_buff *skb,
8371 struct genl_info *info) 8349 struct genl_info *info)
8372{ 8350{
8373 if (info->user_ptr[0])
8374 cfg80211_unlock_rdev(info->user_ptr[0]);
8375 if (info->user_ptr[1]) { 8351 if (info->user_ptr[1]) {
8376 if (ops->internal_flags & NL80211_FLAG_NEED_WDEV) { 8352 if (ops->internal_flags & NL80211_FLAG_NEED_WDEV) {
8377 struct wireless_dev *wdev = info->user_ptr[1]; 8353 struct wireless_dev *wdev = info->user_ptr[1];
@@ -8393,7 +8369,8 @@ static struct genl_ops nl80211_ops[] = {
8393 .dumpit = nl80211_dump_wiphy, 8369 .dumpit = nl80211_dump_wiphy,
8394 .policy = nl80211_policy, 8370 .policy = nl80211_policy,
8395 /* can be retrieved by unprivileged users */ 8371 /* can be retrieved by unprivileged users */
8396 .internal_flags = NL80211_FLAG_NEED_WIPHY, 8372 .internal_flags = NL80211_FLAG_NEED_WIPHY |
8373 NL80211_FLAG_NEED_RTNL,
8397 }, 8374 },
8398 { 8375 {
8399 .cmd = NL80211_CMD_SET_WIPHY, 8376 .cmd = NL80211_CMD_SET_WIPHY,
@@ -8408,7 +8385,8 @@ static struct genl_ops nl80211_ops[] = {
8408 .dumpit = nl80211_dump_interface, 8385 .dumpit = nl80211_dump_interface,
8409 .policy = nl80211_policy, 8386 .policy = nl80211_policy,
8410 /* can be retrieved by unprivileged users */ 8387 /* can be retrieved by unprivileged users */
8411 .internal_flags = NL80211_FLAG_NEED_WDEV, 8388 .internal_flags = NL80211_FLAG_NEED_WDEV |
8389 NL80211_FLAG_NEED_RTNL,
8412 }, 8390 },
8413 { 8391 {
8414 .cmd = NL80211_CMD_SET_INTERFACE, 8392 .cmd = NL80211_CMD_SET_INTERFACE,
@@ -8567,6 +8545,7 @@ static struct genl_ops nl80211_ops[] = {
8567 .cmd = NL80211_CMD_GET_REG, 8545 .cmd = NL80211_CMD_GET_REG,
8568 .doit = nl80211_get_reg, 8546 .doit = nl80211_get_reg,
8569 .policy = nl80211_policy, 8547 .policy = nl80211_policy,
8548 .internal_flags = NL80211_FLAG_NEED_RTNL,
8570 /* can be retrieved by unprivileged users */ 8549 /* can be retrieved by unprivileged users */
8571 }, 8550 },
8572 { 8551 {
@@ -8574,6 +8553,7 @@ static struct genl_ops nl80211_ops[] = {
8574 .doit = nl80211_set_reg, 8553 .doit = nl80211_set_reg,
8575 .policy = nl80211_policy, 8554 .policy = nl80211_policy,
8576 .flags = GENL_ADMIN_PERM, 8555 .flags = GENL_ADMIN_PERM,
8556 .internal_flags = NL80211_FLAG_NEED_RTNL,
8577 }, 8557 },
8578 { 8558 {
8579 .cmd = NL80211_CMD_REQ_SET_REG, 8559 .cmd = NL80211_CMD_REQ_SET_REG,
@@ -9029,8 +9009,6 @@ static int nl80211_add_scan_req(struct sk_buff *msg,
9029 struct nlattr *nest; 9009 struct nlattr *nest;
9030 int i; 9010 int i;
9031 9011
9032 lockdep_assert_held(&rdev->sched_scan_mtx);
9033
9034 if (WARN_ON(!req)) 9012 if (WARN_ON(!req))
9035 return 0; 9013 return 0;
9036 9014
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index cc35fbaa4578..e1d6749234c6 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -81,7 +81,10 @@ static struct regulatory_request core_request_world = {
81 .country_ie_env = ENVIRON_ANY, 81 .country_ie_env = ENVIRON_ANY,
82}; 82};
83 83
84/* Receipt of information from last regulatory request */ 84/*
85 * Receipt of information from last regulatory request,
86 * protected by RTNL (and can be accessed with RCU protection)
87 */
85static struct regulatory_request __rcu *last_request = 88static struct regulatory_request __rcu *last_request =
86 (void __rcu *)&core_request_world; 89 (void __rcu *)&core_request_world;
87 90
@@ -96,39 +99,25 @@ static struct device_type reg_device_type = {
96 * Central wireless core regulatory domains, we only need two, 99 * Central wireless core regulatory domains, we only need two,
97 * the current one and a world regulatory domain in case we have no 100 * the current one and a world regulatory domain in case we have no
98 * information to give us an alpha2. 101 * information to give us an alpha2.
102 * (protected by RTNL, can be read under RCU)
99 */ 103 */
100const struct ieee80211_regdomain __rcu *cfg80211_regdomain; 104const struct ieee80211_regdomain __rcu *cfg80211_regdomain;
101 105
102/* 106/*
103 * Protects static reg.c components:
104 * - cfg80211_regdomain (if not used with RCU)
105 * - cfg80211_world_regdom
106 * - last_request (if not used with RCU)
107 * - reg_num_devs_support_basehint
108 */
109static DEFINE_MUTEX(reg_mutex);
110
111/*
112 * Number of devices that registered to the core 107 * Number of devices that registered to the core
113 * that support cellular base station regulatory hints 108 * that support cellular base station regulatory hints
109 * (protected by RTNL)
114 */ 110 */
115static int reg_num_devs_support_basehint; 111static int reg_num_devs_support_basehint;
116 112
117static inline void assert_reg_lock(void)
118{
119 lockdep_assert_held(&reg_mutex);
120}
121
122static const struct ieee80211_regdomain *get_cfg80211_regdom(void) 113static const struct ieee80211_regdomain *get_cfg80211_regdom(void)
123{ 114{
124 return rcu_dereference_protected(cfg80211_regdomain, 115 return rtnl_dereference(cfg80211_regdomain);
125 lockdep_is_held(&reg_mutex));
126} 116}
127 117
128static const struct ieee80211_regdomain *get_wiphy_regdom(struct wiphy *wiphy) 118static const struct ieee80211_regdomain *get_wiphy_regdom(struct wiphy *wiphy)
129{ 119{
130 return rcu_dereference_protected(wiphy->regd, 120 return rtnl_dereference(wiphy->regd);
131 lockdep_is_held(&reg_mutex));
132} 121}
133 122
134static void rcu_free_regdom(const struct ieee80211_regdomain *r) 123static void rcu_free_regdom(const struct ieee80211_regdomain *r)
@@ -140,8 +129,7 @@ static void rcu_free_regdom(const struct ieee80211_regdomain *r)
140 129
141static struct regulatory_request *get_last_request(void) 130static struct regulatory_request *get_last_request(void)
142{ 131{
143 return rcu_dereference_check(last_request, 132 return rcu_dereference_rtnl(last_request);
144 lockdep_is_held(&reg_mutex));
145} 133}
146 134
147/* Used to queue up regulatory hints */ 135/* Used to queue up regulatory hints */
@@ -200,6 +188,7 @@ static const struct ieee80211_regdomain world_regdom = {
200 } 188 }
201}; 189};
202 190
191/* protected by RTNL */
203static const struct ieee80211_regdomain *cfg80211_world_regdom = 192static const struct ieee80211_regdomain *cfg80211_world_regdom =
204 &world_regdom; 193 &world_regdom;
205 194
@@ -215,7 +204,7 @@ static void reset_regdomains(bool full_reset,
215 const struct ieee80211_regdomain *r; 204 const struct ieee80211_regdomain *r;
216 struct regulatory_request *lr; 205 struct regulatory_request *lr;
217 206
218 assert_reg_lock(); 207 ASSERT_RTNL();
219 208
220 r = get_cfg80211_regdom(); 209 r = get_cfg80211_regdom();
221 210
@@ -377,7 +366,7 @@ static void reg_regdb_search(struct work_struct *work)
377 const struct ieee80211_regdomain *curdom, *regdom = NULL; 366 const struct ieee80211_regdomain *curdom, *regdom = NULL;
378 int i; 367 int i;
379 368
380 mutex_lock(&cfg80211_mutex); 369 rtnl_lock();
381 370
382 mutex_lock(&reg_regdb_search_mutex); 371 mutex_lock(&reg_regdb_search_mutex);
383 while (!list_empty(&reg_regdb_search_list)) { 372 while (!list_empty(&reg_regdb_search_list)) {
@@ -402,7 +391,7 @@ static void reg_regdb_search(struct work_struct *work)
402 if (!IS_ERR_OR_NULL(regdom)) 391 if (!IS_ERR_OR_NULL(regdom))
403 set_regdom(regdom); 392 set_regdom(regdom);
404 393
405 mutex_unlock(&cfg80211_mutex); 394 rtnl_unlock();
406} 395}
407 396
408static DECLARE_WORK(reg_regdb_work, reg_regdb_search); 397static DECLARE_WORK(reg_regdb_work, reg_regdb_search);
@@ -936,13 +925,7 @@ static bool reg_request_cell_base(struct regulatory_request *request)
936 925
937bool reg_last_request_cell_base(void) 926bool reg_last_request_cell_base(void)
938{ 927{
939 bool val; 928 return reg_request_cell_base(get_last_request());
940
941 mutex_lock(&reg_mutex);
942 val = reg_request_cell_base(get_last_request());
943 mutex_unlock(&reg_mutex);
944
945 return val;
946} 929}
947 930
948#ifdef CONFIG_CFG80211_CERTIFICATION_ONUS 931#ifdef CONFIG_CFG80211_CERTIFICATION_ONUS
@@ -1225,7 +1208,7 @@ static void update_all_wiphy_regulatory(enum nl80211_reg_initiator initiator)
1225 struct cfg80211_registered_device *rdev; 1208 struct cfg80211_registered_device *rdev;
1226 struct wiphy *wiphy; 1209 struct wiphy *wiphy;
1227 1210
1228 assert_cfg80211_lock(); 1211 ASSERT_RTNL();
1229 1212
1230 list_for_each_entry(rdev, &cfg80211_rdev_list, list) { 1213 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
1231 wiphy = &rdev->wiphy; 1214 wiphy = &rdev->wiphy;
@@ -1444,8 +1427,6 @@ static void reg_set_request_processed(void)
1444 * what it believes should be the current regulatory domain. 1427 * what it believes should be the current regulatory domain.
1445 * 1428 *
1446 * Returns one of the different reg request treatment values. 1429 * Returns one of the different reg request treatment values.
1447 *
1448 * Caller must hold &reg_mutex
1449 */ 1430 */
1450static enum reg_request_treatment 1431static enum reg_request_treatment
1451__regulatory_hint(struct wiphy *wiphy, 1432__regulatory_hint(struct wiphy *wiphy,
@@ -1570,21 +1551,19 @@ static void reg_process_pending_hints(void)
1570{ 1551{
1571 struct regulatory_request *reg_request, *lr; 1552 struct regulatory_request *reg_request, *lr;
1572 1553
1573 mutex_lock(&cfg80211_mutex);
1574 mutex_lock(&reg_mutex);
1575 lr = get_last_request(); 1554 lr = get_last_request();
1576 1555
1577 /* When last_request->processed becomes true this will be rescheduled */ 1556 /* When last_request->processed becomes true this will be rescheduled */
1578 if (lr && !lr->processed) { 1557 if (lr && !lr->processed) {
1579 REG_DBG_PRINT("Pending regulatory request, waiting for it to be processed...\n"); 1558 REG_DBG_PRINT("Pending regulatory request, waiting for it to be processed...\n");
1580 goto out; 1559 return;
1581 } 1560 }
1582 1561
1583 spin_lock(&reg_requests_lock); 1562 spin_lock(&reg_requests_lock);
1584 1563
1585 if (list_empty(&reg_requests_list)) { 1564 if (list_empty(&reg_requests_list)) {
1586 spin_unlock(&reg_requests_lock); 1565 spin_unlock(&reg_requests_lock);
1587 goto out; 1566 return;
1588 } 1567 }
1589 1568
1590 reg_request = list_first_entry(&reg_requests_list, 1569 reg_request = list_first_entry(&reg_requests_list,
@@ -1595,10 +1574,6 @@ static void reg_process_pending_hints(void)
1595 spin_unlock(&reg_requests_lock); 1574 spin_unlock(&reg_requests_lock);
1596 1575
1597 reg_process_hint(reg_request, reg_request->initiator); 1576 reg_process_hint(reg_request, reg_request->initiator);
1598
1599out:
1600 mutex_unlock(&reg_mutex);
1601 mutex_unlock(&cfg80211_mutex);
1602} 1577}
1603 1578
1604/* Processes beacon hints -- this has nothing to do with country IEs */ 1579/* Processes beacon hints -- this has nothing to do with country IEs */
@@ -1607,9 +1582,6 @@ static void reg_process_pending_beacon_hints(void)
1607 struct cfg80211_registered_device *rdev; 1582 struct cfg80211_registered_device *rdev;
1608 struct reg_beacon *pending_beacon, *tmp; 1583 struct reg_beacon *pending_beacon, *tmp;
1609 1584
1610 mutex_lock(&cfg80211_mutex);
1611 mutex_lock(&reg_mutex);
1612
1613 /* This goes through the _pending_ beacon list */ 1585 /* This goes through the _pending_ beacon list */
1614 spin_lock_bh(&reg_pending_beacons_lock); 1586 spin_lock_bh(&reg_pending_beacons_lock);
1615 1587
@@ -1626,14 +1598,14 @@ static void reg_process_pending_beacon_hints(void)
1626 } 1598 }
1627 1599
1628 spin_unlock_bh(&reg_pending_beacons_lock); 1600 spin_unlock_bh(&reg_pending_beacons_lock);
1629 mutex_unlock(&reg_mutex);
1630 mutex_unlock(&cfg80211_mutex);
1631} 1601}
1632 1602
1633static void reg_todo(struct work_struct *work) 1603static void reg_todo(struct work_struct *work)
1634{ 1604{
1605 rtnl_lock();
1635 reg_process_pending_hints(); 1606 reg_process_pending_hints();
1636 reg_process_pending_beacon_hints(); 1607 reg_process_pending_beacon_hints();
1608 rtnl_unlock();
1637} 1609}
1638 1610
1639static void queue_regulatory_request(struct regulatory_request *request) 1611static void queue_regulatory_request(struct regulatory_request *request)
@@ -1717,29 +1689,23 @@ int regulatory_hint(struct wiphy *wiphy, const char *alpha2)
1717} 1689}
1718EXPORT_SYMBOL(regulatory_hint); 1690EXPORT_SYMBOL(regulatory_hint);
1719 1691
1720/*
1721 * We hold wdev_lock() here so we cannot hold cfg80211_mutex() and
1722 * therefore cannot iterate over the rdev list here.
1723 */
1724void regulatory_hint_11d(struct wiphy *wiphy, enum ieee80211_band band, 1692void regulatory_hint_11d(struct wiphy *wiphy, enum ieee80211_band band,
1725 const u8 *country_ie, u8 country_ie_len) 1693 const u8 *country_ie, u8 country_ie_len)
1726{ 1694{
1727 char alpha2[2]; 1695 char alpha2[2];
1728 enum environment_cap env = ENVIRON_ANY; 1696 enum environment_cap env = ENVIRON_ANY;
1729 struct regulatory_request *request, *lr; 1697 struct regulatory_request *request = NULL, *lr;
1730
1731 mutex_lock(&reg_mutex);
1732 lr = get_last_request();
1733
1734 if (unlikely(!lr))
1735 goto out;
1736 1698
1737 /* IE len must be evenly divisible by 2 */ 1699 /* IE len must be evenly divisible by 2 */
1738 if (country_ie_len & 0x01) 1700 if (country_ie_len & 0x01)
1739 goto out; 1701 return;
1740 1702
1741 if (country_ie_len < IEEE80211_COUNTRY_IE_MIN_LEN) 1703 if (country_ie_len < IEEE80211_COUNTRY_IE_MIN_LEN)
1742 goto out; 1704 return;
1705
1706 request = kzalloc(sizeof(*request), GFP_KERNEL);
1707 if (!request)
1708 return;
1743 1709
1744 alpha2[0] = country_ie[0]; 1710 alpha2[0] = country_ie[0];
1745 alpha2[1] = country_ie[1]; 1711 alpha2[1] = country_ie[1];
@@ -1749,19 +1715,21 @@ void regulatory_hint_11d(struct wiphy *wiphy, enum ieee80211_band band,
1749 else if (country_ie[2] == 'O') 1715 else if (country_ie[2] == 'O')
1750 env = ENVIRON_OUTDOOR; 1716 env = ENVIRON_OUTDOOR;
1751 1717
1718 rcu_read_lock();
1719 lr = get_last_request();
1720
1721 if (unlikely(!lr))
1722 goto out;
1723
1752 /* 1724 /*
1753 * We will run this only upon a successful connection on cfg80211. 1725 * We will run this only upon a successful connection on cfg80211.
1754 * We leave conflict resolution to the workqueue, where can hold 1726 * We leave conflict resolution to the workqueue, where can hold
1755 * cfg80211_mutex. 1727 * the RTNL.
1756 */ 1728 */
1757 if (lr->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE && 1729 if (lr->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE &&
1758 lr->wiphy_idx != WIPHY_IDX_INVALID) 1730 lr->wiphy_idx != WIPHY_IDX_INVALID)
1759 goto out; 1731 goto out;
1760 1732
1761 request = kzalloc(sizeof(struct regulatory_request), GFP_KERNEL);
1762 if (!request)
1763 goto out;
1764
1765 request->wiphy_idx = get_wiphy_idx(wiphy); 1733 request->wiphy_idx = get_wiphy_idx(wiphy);
1766 request->alpha2[0] = alpha2[0]; 1734 request->alpha2[0] = alpha2[0];
1767 request->alpha2[1] = alpha2[1]; 1735 request->alpha2[1] = alpha2[1];
@@ -1769,8 +1737,10 @@ void regulatory_hint_11d(struct wiphy *wiphy, enum ieee80211_band band,
1769 request->country_ie_env = env; 1737 request->country_ie_env = env;
1770 1738
1771 queue_regulatory_request(request); 1739 queue_regulatory_request(request);
1740 request = NULL;
1772out: 1741out:
1773 mutex_unlock(&reg_mutex); 1742 kfree(request);
1743 rcu_read_unlock();
1774} 1744}
1775 1745
1776static void restore_alpha2(char *alpha2, bool reset_user) 1746static void restore_alpha2(char *alpha2, bool reset_user)
@@ -1858,8 +1828,7 @@ static void restore_regulatory_settings(bool reset_user)
1858 LIST_HEAD(tmp_reg_req_list); 1828 LIST_HEAD(tmp_reg_req_list);
1859 struct cfg80211_registered_device *rdev; 1829 struct cfg80211_registered_device *rdev;
1860 1830
1861 mutex_lock(&cfg80211_mutex); 1831 ASSERT_RTNL();
1862 mutex_lock(&reg_mutex);
1863 1832
1864 reset_regdomains(true, &world_regdom); 1833 reset_regdomains(true, &world_regdom);
1865 restore_alpha2(alpha2, reset_user); 1834 restore_alpha2(alpha2, reset_user);
@@ -1914,9 +1883,6 @@ static void restore_regulatory_settings(bool reset_user)
1914 list_splice_tail_init(&tmp_reg_req_list, &reg_requests_list); 1883 list_splice_tail_init(&tmp_reg_req_list, &reg_requests_list);
1915 spin_unlock(&reg_requests_lock); 1884 spin_unlock(&reg_requests_lock);
1916 1885
1917 mutex_unlock(&reg_mutex);
1918 mutex_unlock(&cfg80211_mutex);
1919
1920 REG_DBG_PRINT("Kicking the queue\n"); 1886 REG_DBG_PRINT("Kicking the queue\n");
1921 1887
1922 schedule_work(&reg_work); 1888 schedule_work(&reg_work);
@@ -2231,7 +2197,6 @@ int set_regdom(const struct ieee80211_regdomain *rd)
2231 struct regulatory_request *lr; 2197 struct regulatory_request *lr;
2232 int r; 2198 int r;
2233 2199
2234 mutex_lock(&reg_mutex);
2235 lr = get_last_request(); 2200 lr = get_last_request();
2236 2201
2237 /* Note that this doesn't update the wiphys, this is done below */ 2202 /* Note that this doesn't update the wiphys, this is done below */
@@ -2241,14 +2206,12 @@ int set_regdom(const struct ieee80211_regdomain *rd)
2241 reg_set_request_processed(); 2206 reg_set_request_processed();
2242 2207
2243 kfree(rd); 2208 kfree(rd);
2244 goto out; 2209 return r;
2245 } 2210 }
2246 2211
2247 /* This would make this whole thing pointless */ 2212 /* This would make this whole thing pointless */
2248 if (WARN_ON(!lr->intersect && rd != get_cfg80211_regdom())) { 2213 if (WARN_ON(!lr->intersect && rd != get_cfg80211_regdom()))
2249 r = -EINVAL; 2214 return -EINVAL;
2250 goto out;
2251 }
2252 2215
2253 /* update all wiphys now with the new established regulatory domain */ 2216 /* update all wiphys now with the new established regulatory domain */
2254 update_all_wiphy_regulatory(lr->initiator); 2217 update_all_wiphy_regulatory(lr->initiator);
@@ -2259,10 +2222,7 @@ int set_regdom(const struct ieee80211_regdomain *rd)
2259 2222
2260 reg_set_request_processed(); 2223 reg_set_request_processed();
2261 2224
2262 out: 2225 return 0;
2263 mutex_unlock(&reg_mutex);
2264
2265 return r;
2266} 2226}
2267 2227
2268int reg_device_uevent(struct device *dev, struct kobj_uevent_env *env) 2228int reg_device_uevent(struct device *dev, struct kobj_uevent_env *env)
@@ -2287,23 +2247,17 @@ int reg_device_uevent(struct device *dev, struct kobj_uevent_env *env)
2287 2247
2288void wiphy_regulatory_register(struct wiphy *wiphy) 2248void wiphy_regulatory_register(struct wiphy *wiphy)
2289{ 2249{
2290 mutex_lock(&reg_mutex);
2291
2292 if (!reg_dev_ignore_cell_hint(wiphy)) 2250 if (!reg_dev_ignore_cell_hint(wiphy))
2293 reg_num_devs_support_basehint++; 2251 reg_num_devs_support_basehint++;
2294 2252
2295 wiphy_update_regulatory(wiphy, NL80211_REGDOM_SET_BY_CORE); 2253 wiphy_update_regulatory(wiphy, NL80211_REGDOM_SET_BY_CORE);
2296
2297 mutex_unlock(&reg_mutex);
2298} 2254}
2299 2255
2300/* Caller must hold cfg80211_mutex */
2301void wiphy_regulatory_deregister(struct wiphy *wiphy) 2256void wiphy_regulatory_deregister(struct wiphy *wiphy)
2302{ 2257{
2303 struct wiphy *request_wiphy = NULL; 2258 struct wiphy *request_wiphy = NULL;
2304 struct regulatory_request *lr; 2259 struct regulatory_request *lr;
2305 2260
2306 mutex_lock(&reg_mutex);
2307 lr = get_last_request(); 2261 lr = get_last_request();
2308 2262
2309 if (!reg_dev_ignore_cell_hint(wiphy)) 2263 if (!reg_dev_ignore_cell_hint(wiphy))
@@ -2316,12 +2270,10 @@ void wiphy_regulatory_deregister(struct wiphy *wiphy)
2316 request_wiphy = wiphy_idx_to_wiphy(lr->wiphy_idx); 2270 request_wiphy = wiphy_idx_to_wiphy(lr->wiphy_idx);
2317 2271
2318 if (!request_wiphy || request_wiphy != wiphy) 2272 if (!request_wiphy || request_wiphy != wiphy)
2319 goto out; 2273 return;
2320 2274
2321 lr->wiphy_idx = WIPHY_IDX_INVALID; 2275 lr->wiphy_idx = WIPHY_IDX_INVALID;
2322 lr->country_ie_env = ENVIRON_ANY; 2276 lr->country_ie_env = ENVIRON_ANY;
2323out:
2324 mutex_unlock(&reg_mutex);
2325} 2277}
2326 2278
2327static void reg_timeout_work(struct work_struct *work) 2279static void reg_timeout_work(struct work_struct *work)
@@ -2385,9 +2337,9 @@ void regulatory_exit(void)
2385 cancel_delayed_work_sync(&reg_timeout); 2337 cancel_delayed_work_sync(&reg_timeout);
2386 2338
2387 /* Lock to suppress warnings */ 2339 /* Lock to suppress warnings */
2388 mutex_lock(&reg_mutex); 2340 rtnl_lock();
2389 reset_regdomains(true, NULL); 2341 reset_regdomains(true, NULL);
2390 mutex_unlock(&reg_mutex); 2342 rtnl_unlock();
2391 2343
2392 dev_set_uevent_suppress(&reg_pdev->dev, true); 2344 dev_set_uevent_suppress(&reg_pdev->dev, true);
2393 2345
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index fd99ea495b7e..dd01b58fa78c 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -169,7 +169,7 @@ void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev, bool leak)
169 union iwreq_data wrqu; 169 union iwreq_data wrqu;
170#endif 170#endif
171 171
172 lockdep_assert_held(&rdev->sched_scan_mtx); 172 ASSERT_RTNL();
173 173
174 request = rdev->scan_req; 174 request = rdev->scan_req;
175 175
@@ -230,9 +230,9 @@ void __cfg80211_scan_done(struct work_struct *wk)
230 rdev = container_of(wk, struct cfg80211_registered_device, 230 rdev = container_of(wk, struct cfg80211_registered_device,
231 scan_done_wk); 231 scan_done_wk);
232 232
233 mutex_lock(&rdev->sched_scan_mtx); 233 rtnl_lock();
234 ___cfg80211_scan_done(rdev, false); 234 ___cfg80211_scan_done(rdev, false);
235 mutex_unlock(&rdev->sched_scan_mtx); 235 rtnl_unlock();
236} 236}
237 237
238void cfg80211_scan_done(struct cfg80211_scan_request *request, bool aborted) 238void cfg80211_scan_done(struct cfg80211_scan_request *request, bool aborted)
@@ -241,6 +241,7 @@ void cfg80211_scan_done(struct cfg80211_scan_request *request, bool aborted)
241 WARN_ON(request != wiphy_to_dev(request->wiphy)->scan_req); 241 WARN_ON(request != wiphy_to_dev(request->wiphy)->scan_req);
242 242
243 request->aborted = aborted; 243 request->aborted = aborted;
244 request->notified = true;
244 queue_work(cfg80211_wq, &wiphy_to_dev(request->wiphy)->scan_done_wk); 245 queue_work(cfg80211_wq, &wiphy_to_dev(request->wiphy)->scan_done_wk);
245} 246}
246EXPORT_SYMBOL(cfg80211_scan_done); 247EXPORT_SYMBOL(cfg80211_scan_done);
@@ -255,7 +256,7 @@ void __cfg80211_sched_scan_results(struct work_struct *wk)
255 256
256 request = rdev->sched_scan_req; 257 request = rdev->sched_scan_req;
257 258
258 mutex_lock(&rdev->sched_scan_mtx); 259 rtnl_lock();
259 260
260 /* we don't have sched_scan_req anymore if the scan is stopping */ 261 /* we don't have sched_scan_req anymore if the scan is stopping */
261 if (request) { 262 if (request) {
@@ -270,7 +271,7 @@ void __cfg80211_sched_scan_results(struct work_struct *wk)
270 nl80211_send_sched_scan_results(rdev, request->dev); 271 nl80211_send_sched_scan_results(rdev, request->dev);
271 } 272 }
272 273
273 mutex_unlock(&rdev->sched_scan_mtx); 274 rtnl_unlock();
274} 275}
275 276
276void cfg80211_sched_scan_results(struct wiphy *wiphy) 277void cfg80211_sched_scan_results(struct wiphy *wiphy)
@@ -289,9 +290,9 @@ void cfg80211_sched_scan_stopped(struct wiphy *wiphy)
289 290
290 trace_cfg80211_sched_scan_stopped(wiphy); 291 trace_cfg80211_sched_scan_stopped(wiphy);
291 292
292 mutex_lock(&rdev->sched_scan_mtx); 293 rtnl_lock();
293 __cfg80211_stop_sched_scan(rdev, true); 294 __cfg80211_stop_sched_scan(rdev, true);
294 mutex_unlock(&rdev->sched_scan_mtx); 295 rtnl_unlock();
295} 296}
296EXPORT_SYMBOL(cfg80211_sched_scan_stopped); 297EXPORT_SYMBOL(cfg80211_sched_scan_stopped);
297 298
@@ -300,7 +301,7 @@ int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev,
300{ 301{
301 struct net_device *dev; 302 struct net_device *dev;
302 303
303 lockdep_assert_held(&rdev->sched_scan_mtx); 304 ASSERT_RTNL();
304 305
305 if (!rdev->sched_scan_req) 306 if (!rdev->sched_scan_req)
306 return -ENOENT; 307 return -ENOENT;
@@ -1040,6 +1041,25 @@ void cfg80211_unlink_bss(struct wiphy *wiphy, struct cfg80211_bss *pub)
1040EXPORT_SYMBOL(cfg80211_unlink_bss); 1041EXPORT_SYMBOL(cfg80211_unlink_bss);
1041 1042
1042#ifdef CONFIG_CFG80211_WEXT 1043#ifdef CONFIG_CFG80211_WEXT
1044static struct cfg80211_registered_device *
1045cfg80211_get_dev_from_ifindex(struct net *net, int ifindex)
1046{
1047 struct cfg80211_registered_device *rdev;
1048 struct net_device *dev;
1049
1050 ASSERT_RTNL();
1051
1052 dev = dev_get_by_index(net, ifindex);
1053 if (!dev)
1054 return ERR_PTR(-ENODEV);
1055 if (dev->ieee80211_ptr)
1056 rdev = wiphy_to_dev(dev->ieee80211_ptr->wiphy);
1057 else
1058 rdev = ERR_PTR(-ENODEV);
1059 dev_put(dev);
1060 return rdev;
1061}
1062
1043int cfg80211_wext_siwscan(struct net_device *dev, 1063int cfg80211_wext_siwscan(struct net_device *dev,
1044 struct iw_request_info *info, 1064 struct iw_request_info *info,
1045 union iwreq_data *wrqu, char *extra) 1065 union iwreq_data *wrqu, char *extra)
@@ -1062,7 +1082,6 @@ int cfg80211_wext_siwscan(struct net_device *dev,
1062 if (IS_ERR(rdev)) 1082 if (IS_ERR(rdev))
1063 return PTR_ERR(rdev); 1083 return PTR_ERR(rdev);
1064 1084
1065 mutex_lock(&rdev->sched_scan_mtx);
1066 if (rdev->scan_req) { 1085 if (rdev->scan_req) {
1067 err = -EBUSY; 1086 err = -EBUSY;
1068 goto out; 1087 goto out;
@@ -1169,9 +1188,7 @@ int cfg80211_wext_siwscan(struct net_device *dev,
1169 dev_hold(dev); 1188 dev_hold(dev);
1170 } 1189 }
1171 out: 1190 out:
1172 mutex_unlock(&rdev->sched_scan_mtx);
1173 kfree(creq); 1191 kfree(creq);
1174 cfg80211_unlock_rdev(rdev);
1175 return err; 1192 return err;
1176} 1193}
1177EXPORT_SYMBOL_GPL(cfg80211_wext_siwscan); 1194EXPORT_SYMBOL_GPL(cfg80211_wext_siwscan);
@@ -1470,10 +1487,8 @@ int cfg80211_wext_giwscan(struct net_device *dev,
1470 if (IS_ERR(rdev)) 1487 if (IS_ERR(rdev))
1471 return PTR_ERR(rdev); 1488 return PTR_ERR(rdev);
1472 1489
1473 if (rdev->scan_req) { 1490 if (rdev->scan_req)
1474 res = -EAGAIN; 1491 return -EAGAIN;
1475 goto out;
1476 }
1477 1492
1478 res = ieee80211_scan_results(rdev, info, extra, data->length); 1493 res = ieee80211_scan_results(rdev, info, extra, data->length);
1479 data->length = 0; 1494 data->length = 0;
@@ -1482,8 +1497,6 @@ int cfg80211_wext_giwscan(struct net_device *dev,
1482 res = 0; 1497 res = 0;
1483 } 1498 }
1484 1499
1485 out:
1486 cfg80211_unlock_rdev(rdev);
1487 return res; 1500 return res;
1488} 1501}
1489EXPORT_SYMBOL_GPL(cfg80211_wext_giwscan); 1502EXPORT_SYMBOL_GPL(cfg80211_wext_giwscan);
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index 3ed35c345cae..81be95f3be74 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -43,35 +43,29 @@ static bool cfg80211_is_all_idle(void)
43 struct wireless_dev *wdev; 43 struct wireless_dev *wdev;
44 bool is_all_idle = true; 44 bool is_all_idle = true;
45 45
46 mutex_lock(&cfg80211_mutex);
47
48 /* 46 /*
49 * All devices must be idle as otherwise if you are actively 47 * All devices must be idle as otherwise if you are actively
50 * scanning some new beacon hints could be learned and would 48 * scanning some new beacon hints could be learned and would
51 * count as new regulatory hints. 49 * count as new regulatory hints.
52 */ 50 */
53 list_for_each_entry(rdev, &cfg80211_rdev_list, list) { 51 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
54 cfg80211_lock_rdev(rdev);
55 list_for_each_entry(wdev, &rdev->wdev_list, list) { 52 list_for_each_entry(wdev, &rdev->wdev_list, list) {
56 wdev_lock(wdev); 53 wdev_lock(wdev);
57 if (wdev->sme_state != CFG80211_SME_IDLE) 54 if (wdev->sme_state != CFG80211_SME_IDLE)
58 is_all_idle = false; 55 is_all_idle = false;
59 wdev_unlock(wdev); 56 wdev_unlock(wdev);
60 } 57 }
61 cfg80211_unlock_rdev(rdev);
62 } 58 }
63 59
64 mutex_unlock(&cfg80211_mutex);
65
66 return is_all_idle; 60 return is_all_idle;
67} 61}
68 62
69static void disconnect_work(struct work_struct *work) 63static void disconnect_work(struct work_struct *work)
70{ 64{
71 if (!cfg80211_is_all_idle()) 65 rtnl_lock();
72 return; 66 if (cfg80211_is_all_idle())
73 67 regulatory_hint_disconnect();
74 regulatory_hint_disconnect(); 68 rtnl_unlock();
75} 69}
76 70
77static DECLARE_WORK(cfg80211_disconnect_work, disconnect_work); 71static DECLARE_WORK(cfg80211_disconnect_work, disconnect_work);
@@ -85,7 +79,6 @@ static int cfg80211_conn_scan(struct wireless_dev *wdev)
85 ASSERT_RTNL(); 79 ASSERT_RTNL();
86 ASSERT_RDEV_LOCK(rdev); 80 ASSERT_RDEV_LOCK(rdev);
87 ASSERT_WDEV_LOCK(wdev); 81 ASSERT_WDEV_LOCK(wdev);
88 lockdep_assert_held(&rdev->sched_scan_mtx);
89 82
90 if (rdev->scan_req) 83 if (rdev->scan_req)
91 return -EBUSY; 84 return -EBUSY;
@@ -176,13 +169,13 @@ static int cfg80211_conn_do_work(struct wireless_dev *wdev)
176 case CFG80211_CONN_AUTHENTICATE_NEXT: 169 case CFG80211_CONN_AUTHENTICATE_NEXT:
177 BUG_ON(!rdev->ops->auth); 170 BUG_ON(!rdev->ops->auth);
178 wdev->conn->state = CFG80211_CONN_AUTHENTICATING; 171 wdev->conn->state = CFG80211_CONN_AUTHENTICATING;
179 return __cfg80211_mlme_auth(rdev, wdev->netdev, 172 return cfg80211_mlme_auth(rdev, wdev->netdev,
180 params->channel, params->auth_type, 173 params->channel, params->auth_type,
181 params->bssid, 174 params->bssid,
182 params->ssid, params->ssid_len, 175 params->ssid, params->ssid_len,
183 NULL, 0, 176 NULL, 0,
184 params->key, params->key_len, 177 params->key, params->key_len,
185 params->key_idx, NULL, 0); 178 params->key_idx, NULL, 0);
186 case CFG80211_CONN_ASSOCIATE_NEXT: 179 case CFG80211_CONN_ASSOCIATE_NEXT:
187 BUG_ON(!rdev->ops->assoc); 180 BUG_ON(!rdev->ops->assoc);
188 wdev->conn->state = CFG80211_CONN_ASSOCIATING; 181 wdev->conn->state = CFG80211_CONN_ASSOCIATING;
@@ -198,19 +191,19 @@ static int cfg80211_conn_do_work(struct wireless_dev *wdev)
198 req.vht_capa = params->vht_capa; 191 req.vht_capa = params->vht_capa;
199 req.vht_capa_mask = params->vht_capa_mask; 192 req.vht_capa_mask = params->vht_capa_mask;
200 193
201 err = __cfg80211_mlme_assoc(rdev, wdev->netdev, params->channel, 194 err = cfg80211_mlme_assoc(rdev, wdev->netdev, params->channel,
202 params->bssid, params->ssid, 195 params->bssid, params->ssid,
203 params->ssid_len, &req); 196 params->ssid_len, &req);
204 if (err) 197 if (err)
205 __cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid, 198 cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid,
206 NULL, 0, 199 NULL, 0,
207 WLAN_REASON_DEAUTH_LEAVING, 200 WLAN_REASON_DEAUTH_LEAVING,
208 false); 201 false);
209 return err; 202 return err;
210 case CFG80211_CONN_DEAUTH_ASSOC_FAIL: 203 case CFG80211_CONN_DEAUTH_ASSOC_FAIL:
211 __cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid, 204 cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid,
212 NULL, 0, 205 NULL, 0,
213 WLAN_REASON_DEAUTH_LEAVING, false); 206 WLAN_REASON_DEAUTH_LEAVING, false);
214 /* return an error so that we call __cfg80211_connect_result() */ 207 /* return an error so that we call __cfg80211_connect_result() */
215 return -EINVAL; 208 return -EINVAL;
216 default: 209 default:
@@ -226,9 +219,6 @@ void cfg80211_conn_work(struct work_struct *work)
226 u8 bssid_buf[ETH_ALEN], *bssid = NULL; 219 u8 bssid_buf[ETH_ALEN], *bssid = NULL;
227 220
228 rtnl_lock(); 221 rtnl_lock();
229 cfg80211_lock_rdev(rdev);
230 mutex_lock(&rdev->devlist_mtx);
231 mutex_lock(&rdev->sched_scan_mtx);
232 222
233 list_for_each_entry(wdev, &rdev->wdev_list, list) { 223 list_for_each_entry(wdev, &rdev->wdev_list, list) {
234 if (!wdev->netdev) 224 if (!wdev->netdev)
@@ -256,9 +246,6 @@ void cfg80211_conn_work(struct work_struct *work)
256 wdev_unlock(wdev); 246 wdev_unlock(wdev);
257 } 247 }
258 248
259 mutex_unlock(&rdev->sched_scan_mtx);
260 mutex_unlock(&rdev->devlist_mtx);
261 cfg80211_unlock_rdev(rdev);
262 rtnl_unlock(); 249 rtnl_unlock();
263} 250}
264 251
@@ -773,11 +760,11 @@ void cfg80211_disconnected(struct net_device *dev, u16 reason,
773} 760}
774EXPORT_SYMBOL(cfg80211_disconnected); 761EXPORT_SYMBOL(cfg80211_disconnected);
775 762
776int __cfg80211_connect(struct cfg80211_registered_device *rdev, 763int cfg80211_connect(struct cfg80211_registered_device *rdev,
777 struct net_device *dev, 764 struct net_device *dev,
778 struct cfg80211_connect_params *connect, 765 struct cfg80211_connect_params *connect,
779 struct cfg80211_cached_keys *connkeys, 766 struct cfg80211_cached_keys *connkeys,
780 const u8 *prev_bssid) 767 const u8 *prev_bssid)
781{ 768{
782 struct wireless_dev *wdev = dev->ieee80211_ptr; 769 struct wireless_dev *wdev = dev->ieee80211_ptr;
783 struct cfg80211_bss *bss = NULL; 770 struct cfg80211_bss *bss = NULL;
@@ -924,27 +911,8 @@ int __cfg80211_connect(struct cfg80211_registered_device *rdev,
924 } 911 }
925} 912}
926 913
927int cfg80211_connect(struct cfg80211_registered_device *rdev, 914int cfg80211_disconnect(struct cfg80211_registered_device *rdev,
928 struct net_device *dev, 915 struct net_device *dev, u16 reason, bool wextev)
929 struct cfg80211_connect_params *connect,
930 struct cfg80211_cached_keys *connkeys)
931{
932 int err;
933
934 mutex_lock(&rdev->devlist_mtx);
935 /* might request scan - scan_mtx -> wdev_mtx dependency */
936 mutex_lock(&rdev->sched_scan_mtx);
937 wdev_lock(dev->ieee80211_ptr);
938 err = __cfg80211_connect(rdev, dev, connect, connkeys, NULL);
939 wdev_unlock(dev->ieee80211_ptr);
940 mutex_unlock(&rdev->sched_scan_mtx);
941 mutex_unlock(&rdev->devlist_mtx);
942
943 return err;
944}
945
946int __cfg80211_disconnect(struct cfg80211_registered_device *rdev,
947 struct net_device *dev, u16 reason, bool wextev)
948{ 916{
949 struct wireless_dev *wdev = dev->ieee80211_ptr; 917 struct wireless_dev *wdev = dev->ieee80211_ptr;
950 int err; 918 int err;
@@ -979,7 +947,7 @@ int __cfg80211_disconnect(struct cfg80211_registered_device *rdev,
979 } 947 }
980 948
981 /* wdev->conn->params.bssid must be set if > SCANNING */ 949 /* wdev->conn->params.bssid must be set if > SCANNING */
982 err = __cfg80211_mlme_deauth(rdev, dev, 950 err = cfg80211_mlme_deauth(rdev, dev,
983 wdev->conn->params.bssid, 951 wdev->conn->params.bssid,
984 NULL, 0, reason, false); 952 NULL, 0, reason, false);
985 if (err) 953 if (err)
@@ -1001,19 +969,6 @@ int __cfg80211_disconnect(struct cfg80211_registered_device *rdev,
1001 return 0; 969 return 0;
1002} 970}
1003 971
1004int cfg80211_disconnect(struct cfg80211_registered_device *rdev,
1005 struct net_device *dev,
1006 u16 reason, bool wextev)
1007{
1008 int err;
1009
1010 wdev_lock(dev->ieee80211_ptr);
1011 err = __cfg80211_disconnect(rdev, dev, reason, wextev);
1012 wdev_unlock(dev->ieee80211_ptr);
1013
1014 return err;
1015}
1016
1017void cfg80211_sme_disassoc(struct net_device *dev, 972void cfg80211_sme_disassoc(struct net_device *dev,
1018 struct cfg80211_internal_bss *bss) 973 struct cfg80211_internal_bss *bss)
1019{ 974{
@@ -1036,6 +991,6 @@ void cfg80211_sme_disassoc(struct net_device *dev,
1036 991
1037 memcpy(bssid, bss->pub.bssid, ETH_ALEN); 992 memcpy(bssid, bss->pub.bssid, ETH_ALEN);
1038 993
1039 __cfg80211_mlme_deauth(rdev, dev, bssid, NULL, 0, 994 cfg80211_mlme_deauth(rdev, dev, bssid, NULL, 0,
1040 WLAN_REASON_DEAUTH_LEAVING, false); 995 WLAN_REASON_DEAUTH_LEAVING, false);
1041} 996}
diff --git a/net/wireless/sysfs.c b/net/wireless/sysfs.c
index 8f28b9f798d8..360a42c6f694 100644
--- a/net/wireless/sysfs.c
+++ b/net/wireless/sysfs.c
@@ -91,6 +91,7 @@ static void cfg80211_leave_all(struct cfg80211_registered_device *rdev)
91 cfg80211_leave(rdev, wdev); 91 cfg80211_leave(rdev, wdev);
92} 92}
93 93
94#ifdef CONFIG_PM
94static int wiphy_suspend(struct device *dev, pm_message_t state) 95static int wiphy_suspend(struct device *dev, pm_message_t state)
95{ 96{
96 struct cfg80211_registered_device *rdev = dev_to_rdev(dev); 97 struct cfg80211_registered_device *rdev = dev_to_rdev(dev);
@@ -100,10 +101,10 @@ static int wiphy_suspend(struct device *dev, pm_message_t state)
100 101
101 rtnl_lock(); 102 rtnl_lock();
102 if (rdev->wiphy.registered) { 103 if (rdev->wiphy.registered) {
103 if (!rdev->wowlan) 104 if (!rdev->wiphy.wowlan_config)
104 cfg80211_leave_all(rdev); 105 cfg80211_leave_all(rdev);
105 if (rdev->ops->suspend) 106 if (rdev->ops->suspend)
106 ret = rdev_suspend(rdev, rdev->wowlan); 107 ret = rdev_suspend(rdev, rdev->wiphy.wowlan_config);
107 if (ret == 1) { 108 if (ret == 1) {
108 /* Driver refuse to configure wowlan */ 109 /* Driver refuse to configure wowlan */
109 cfg80211_leave_all(rdev); 110 cfg80211_leave_all(rdev);
@@ -132,6 +133,7 @@ static int wiphy_resume(struct device *dev)
132 133
133 return ret; 134 return ret;
134} 135}
136#endif
135 137
136static const void *wiphy_namespace(struct device *d) 138static const void *wiphy_namespace(struct device *d)
137{ 139{
@@ -146,8 +148,10 @@ struct class ieee80211_class = {
146 .dev_release = wiphy_dev_release, 148 .dev_release = wiphy_dev_release,
147 .dev_attrs = ieee80211_dev_attrs, 149 .dev_attrs = ieee80211_dev_attrs,
148 .dev_uevent = wiphy_uevent, 150 .dev_uevent = wiphy_uevent,
151#ifdef CONFIG_PM
149 .suspend = wiphy_suspend, 152 .suspend = wiphy_suspend,
150 .resume = wiphy_resume, 153 .resume = wiphy_resume,
154#endif
151 .ns_type = &net_ns_type_operations, 155 .ns_type = &net_ns_type_operations,
152 .namespace = wiphy_namespace, 156 .namespace = wiphy_namespace,
153}; 157};
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index 5755bc14abbd..23fafeae8a10 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -1911,12 +1911,12 @@ TRACE_EVENT(cfg80211_send_rx_assoc,
1911 NETDEV_PR_ARG, MAC_PR_ARG(bssid), CHAN_PR_ARG) 1911 NETDEV_PR_ARG, MAC_PR_ARG(bssid), CHAN_PR_ARG)
1912); 1912);
1913 1913
1914DEFINE_EVENT(netdev_evt_only, __cfg80211_send_deauth, 1914DEFINE_EVENT(netdev_evt_only, cfg80211_send_deauth,
1915 TP_PROTO(struct net_device *netdev), 1915 TP_PROTO(struct net_device *netdev),
1916 TP_ARGS(netdev) 1916 TP_ARGS(netdev)
1917); 1917);
1918 1918
1919DEFINE_EVENT(netdev_evt_only, __cfg80211_send_disassoc, 1919DEFINE_EVENT(netdev_evt_only, cfg80211_send_disassoc,
1920 TP_PROTO(struct net_device *netdev), 1920 TP_PROTO(struct net_device *netdev),
1921 TP_ARGS(netdev) 1921 TP_ARGS(netdev)
1922); 1922);
diff --git a/net/wireless/util.c b/net/wireless/util.c
index f5ad4d94ba88..74458b7f61eb 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -33,6 +33,29 @@ ieee80211_get_response_rate(struct ieee80211_supported_band *sband,
33} 33}
34EXPORT_SYMBOL(ieee80211_get_response_rate); 34EXPORT_SYMBOL(ieee80211_get_response_rate);
35 35
36u32 ieee80211_mandatory_rates(struct ieee80211_supported_band *sband)
37{
38 struct ieee80211_rate *bitrates;
39 u32 mandatory_rates = 0;
40 enum ieee80211_rate_flags mandatory_flag;
41 int i;
42
43 if (WARN_ON(!sband))
44 return 1;
45
46 if (sband->band == IEEE80211_BAND_2GHZ)
47 mandatory_flag = IEEE80211_RATE_MANDATORY_B;
48 else
49 mandatory_flag = IEEE80211_RATE_MANDATORY_A;
50
51 bitrates = sband->bitrates;
52 for (i = 0; i < sband->n_bitrates; i++)
53 if (bitrates[i].flags & mandatory_flag)
54 mandatory_rates |= BIT(i);
55 return mandatory_rates;
56}
57EXPORT_SYMBOL(ieee80211_mandatory_rates);
58
36int ieee80211_channel_to_frequency(int chan, enum ieee80211_band band) 59int ieee80211_channel_to_frequency(int chan, enum ieee80211_band band)
37{ 60{
38 /* see 802.11 17.3.8.3.2 and Annex J 61 /* see 802.11 17.3.8.3.2 and Annex J
@@ -785,12 +808,8 @@ void cfg80211_process_rdev_events(struct cfg80211_registered_device *rdev)
785 ASSERT_RTNL(); 808 ASSERT_RTNL();
786 ASSERT_RDEV_LOCK(rdev); 809 ASSERT_RDEV_LOCK(rdev);
787 810
788 mutex_lock(&rdev->devlist_mtx);
789
790 list_for_each_entry(wdev, &rdev->wdev_list, list) 811 list_for_each_entry(wdev, &rdev->wdev_list, list)
791 cfg80211_process_wdev_events(wdev); 812 cfg80211_process_wdev_events(wdev);
792
793 mutex_unlock(&rdev->devlist_mtx);
794} 813}
795 814
796int cfg80211_change_iface(struct cfg80211_registered_device *rdev, 815int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
@@ -822,10 +841,8 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
822 return -EBUSY; 841 return -EBUSY;
823 842
824 if (ntype != otype && netif_running(dev)) { 843 if (ntype != otype && netif_running(dev)) {
825 mutex_lock(&rdev->devlist_mtx);
826 err = cfg80211_can_change_interface(rdev, dev->ieee80211_ptr, 844 err = cfg80211_can_change_interface(rdev, dev->ieee80211_ptr,
827 ntype); 845 ntype);
828 mutex_unlock(&rdev->devlist_mtx);
829 if (err) 846 if (err)
830 return err; 847 return err;
831 848
@@ -841,8 +858,10 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
841 break; 858 break;
842 case NL80211_IFTYPE_STATION: 859 case NL80211_IFTYPE_STATION:
843 case NL80211_IFTYPE_P2P_CLIENT: 860 case NL80211_IFTYPE_P2P_CLIENT:
861 wdev_lock(dev->ieee80211_ptr);
844 cfg80211_disconnect(rdev, dev, 862 cfg80211_disconnect(rdev, dev,
845 WLAN_REASON_DEAUTH_LEAVING, true); 863 WLAN_REASON_DEAUTH_LEAVING, true);
864 wdev_unlock(dev->ieee80211_ptr);
846 break; 865 break;
847 case NL80211_IFTYPE_MESH_POINT: 866 case NL80211_IFTYPE_MESH_POINT:
848 /* mesh should be handled? */ 867 /* mesh should be handled? */
@@ -1169,6 +1188,9 @@ bool ieee80211_operating_class_to_band(u8 operating_class,
1169 case 84: 1188 case 84:
1170 *band = IEEE80211_BAND_2GHZ; 1189 *band = IEEE80211_BAND_2GHZ;
1171 return true; 1190 return true;
1191 case 180:
1192 *band = IEEE80211_BAND_60GHZ;
1193 return true;
1172 } 1194 }
1173 1195
1174 return false; 1196 return false;
@@ -1184,8 +1206,6 @@ int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev,
1184 if (!beacon_int) 1206 if (!beacon_int)
1185 return -EINVAL; 1207 return -EINVAL;
1186 1208
1187 mutex_lock(&rdev->devlist_mtx);
1188
1189 list_for_each_entry(wdev, &rdev->wdev_list, list) { 1209 list_for_each_entry(wdev, &rdev->wdev_list, list) {
1190 if (!wdev->beacon_interval) 1210 if (!wdev->beacon_interval)
1191 continue; 1211 continue;
@@ -1195,8 +1215,6 @@ int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev,
1195 } 1215 }
1196 } 1216 }
1197 1217
1198 mutex_unlock(&rdev->devlist_mtx);
1199
1200 return res; 1218 return res;
1201} 1219}
1202 1220
@@ -1220,7 +1238,6 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev,
1220 int i, j; 1238 int i, j;
1221 1239
1222 ASSERT_RTNL(); 1240 ASSERT_RTNL();
1223 lockdep_assert_held(&rdev->devlist_mtx);
1224 1241
1225 if (WARN_ON(hweight32(radar_detect) > 1)) 1242 if (WARN_ON(hweight32(radar_detect) > 1))
1226 return -EINVAL; 1243 return -EINVAL;
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c
index d997d0f0c54a..e7c6e862580d 100644
--- a/net/wireless/wext-compat.c
+++ b/net/wireless/wext-compat.c
@@ -72,7 +72,6 @@ int cfg80211_wext_siwmode(struct net_device *dev, struct iw_request_info *info,
72 struct cfg80211_registered_device *rdev; 72 struct cfg80211_registered_device *rdev;
73 struct vif_params vifparams; 73 struct vif_params vifparams;
74 enum nl80211_iftype type; 74 enum nl80211_iftype type;
75 int ret;
76 75
77 rdev = wiphy_to_dev(wdev->wiphy); 76 rdev = wiphy_to_dev(wdev->wiphy);
78 77
@@ -98,11 +97,7 @@ int cfg80211_wext_siwmode(struct net_device *dev, struct iw_request_info *info,
98 97
99 memset(&vifparams, 0, sizeof(vifparams)); 98 memset(&vifparams, 0, sizeof(vifparams));
100 99
101 cfg80211_lock_rdev(rdev); 100 return cfg80211_change_iface(rdev, dev, type, NULL, &vifparams);
102 ret = cfg80211_change_iface(rdev, dev, type, NULL, &vifparams);
103 cfg80211_unlock_rdev(rdev);
104
105 return ret;
106} 101}
107EXPORT_SYMBOL_GPL(cfg80211_wext_siwmode); 102EXPORT_SYMBOL_GPL(cfg80211_wext_siwmode);
108 103
@@ -579,13 +574,10 @@ static int cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
579{ 574{
580 int err; 575 int err;
581 576
582 /* devlist mutex needed for possible IBSS re-join */
583 mutex_lock(&rdev->devlist_mtx);
584 wdev_lock(dev->ieee80211_ptr); 577 wdev_lock(dev->ieee80211_ptr);
585 err = __cfg80211_set_encryption(rdev, dev, pairwise, addr, 578 err = __cfg80211_set_encryption(rdev, dev, pairwise, addr,
586 remove, tx_key, idx, params); 579 remove, tx_key, idx, params);
587 wdev_unlock(dev->ieee80211_ptr); 580 wdev_unlock(dev->ieee80211_ptr);
588 mutex_unlock(&rdev->devlist_mtx);
589 581
590 return err; 582 return err;
591} 583}
@@ -787,7 +779,7 @@ static int cfg80211_wext_siwfreq(struct net_device *dev,
787 struct cfg80211_chan_def chandef = { 779 struct cfg80211_chan_def chandef = {
788 .width = NL80211_CHAN_WIDTH_20_NOHT, 780 .width = NL80211_CHAN_WIDTH_20_NOHT,
789 }; 781 };
790 int freq, err; 782 int freq;
791 783
792 switch (wdev->iftype) { 784 switch (wdev->iftype) {
793 case NL80211_IFTYPE_STATION: 785 case NL80211_IFTYPE_STATION:
@@ -804,10 +796,7 @@ static int cfg80211_wext_siwfreq(struct net_device *dev,
804 chandef.chan = ieee80211_get_channel(&rdev->wiphy, freq); 796 chandef.chan = ieee80211_get_channel(&rdev->wiphy, freq);
805 if (!chandef.chan) 797 if (!chandef.chan)
806 return -EINVAL; 798 return -EINVAL;
807 mutex_lock(&rdev->devlist_mtx); 799 return cfg80211_set_monitor_channel(rdev, &chandef);
808 err = cfg80211_set_monitor_channel(rdev, &chandef);
809 mutex_unlock(&rdev->devlist_mtx);
810 return err;
811 case NL80211_IFTYPE_MESH_POINT: 800 case NL80211_IFTYPE_MESH_POINT:
812 freq = cfg80211_wext_freq(wdev->wiphy, wextfreq); 801 freq = cfg80211_wext_freq(wdev->wiphy, wextfreq);
813 if (freq < 0) 802 if (freq < 0)
@@ -818,10 +807,7 @@ static int cfg80211_wext_siwfreq(struct net_device *dev,
818 chandef.chan = ieee80211_get_channel(&rdev->wiphy, freq); 807 chandef.chan = ieee80211_get_channel(&rdev->wiphy, freq);
819 if (!chandef.chan) 808 if (!chandef.chan)
820 return -EINVAL; 809 return -EINVAL;
821 mutex_lock(&rdev->devlist_mtx); 810 return cfg80211_set_mesh_channel(rdev, wdev, &chandef);
822 err = cfg80211_set_mesh_channel(rdev, wdev, &chandef);
823 mutex_unlock(&rdev->devlist_mtx);
824 return err;
825 default: 811 default:
826 return -EOPNOTSUPP; 812 return -EOPNOTSUPP;
827 } 813 }
diff --git a/net/wireless/wext-sme.c b/net/wireless/wext-sme.c
index e79cb5c0655a..a53f8404f451 100644
--- a/net/wireless/wext-sme.c
+++ b/net/wireless/wext-sme.c
@@ -54,8 +54,8 @@ int cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev,
54 if (wdev->wext.prev_bssid_valid) 54 if (wdev->wext.prev_bssid_valid)
55 prev_bssid = wdev->wext.prev_bssid; 55 prev_bssid = wdev->wext.prev_bssid;
56 56
57 err = __cfg80211_connect(rdev, wdev->netdev, 57 err = cfg80211_connect(rdev, wdev->netdev,
58 &wdev->wext.connect, ck, prev_bssid); 58 &wdev->wext.connect, ck, prev_bssid);
59 if (err) 59 if (err)
60 kfree(ck); 60 kfree(ck);
61 61
@@ -87,9 +87,6 @@ int cfg80211_mgd_wext_siwfreq(struct net_device *dev,
87 return -EINVAL; 87 return -EINVAL;
88 } 88 }
89 89
90 cfg80211_lock_rdev(rdev);
91 mutex_lock(&rdev->devlist_mtx);
92 mutex_lock(&rdev->sched_scan_mtx);
93 wdev_lock(wdev); 90 wdev_lock(wdev);
94 91
95 if (wdev->sme_state != CFG80211_SME_IDLE) { 92 if (wdev->sme_state != CFG80211_SME_IDLE) {
@@ -103,8 +100,8 @@ int cfg80211_mgd_wext_siwfreq(struct net_device *dev,
103 /* if SSID set, we'll try right again, avoid event */ 100 /* if SSID set, we'll try right again, avoid event */
104 if (wdev->wext.connect.ssid_len) 101 if (wdev->wext.connect.ssid_len)
105 event = false; 102 event = false;
106 err = __cfg80211_disconnect(rdev, dev, 103 err = cfg80211_disconnect(rdev, dev,
107 WLAN_REASON_DEAUTH_LEAVING, event); 104 WLAN_REASON_DEAUTH_LEAVING, event);
108 if (err) 105 if (err)
109 goto out; 106 goto out;
110 } 107 }
@@ -136,9 +133,6 @@ int cfg80211_mgd_wext_siwfreq(struct net_device *dev,
136 err = cfg80211_mgd_wext_connect(rdev, wdev); 133 err = cfg80211_mgd_wext_connect(rdev, wdev);
137 out: 134 out:
138 wdev_unlock(wdev); 135 wdev_unlock(wdev);
139 mutex_unlock(&rdev->sched_scan_mtx);
140 mutex_unlock(&rdev->devlist_mtx);
141 cfg80211_unlock_rdev(rdev);
142 return err; 136 return err;
143} 137}
144 138
@@ -190,9 +184,6 @@ int cfg80211_mgd_wext_siwessid(struct net_device *dev,
190 if (len > 0 && ssid[len - 1] == '\0') 184 if (len > 0 && ssid[len - 1] == '\0')
191 len--; 185 len--;
192 186
193 cfg80211_lock_rdev(rdev);
194 mutex_lock(&rdev->devlist_mtx);
195 mutex_lock(&rdev->sched_scan_mtx);
196 wdev_lock(wdev); 187 wdev_lock(wdev);
197 188
198 err = 0; 189 err = 0;
@@ -208,8 +199,8 @@ int cfg80211_mgd_wext_siwessid(struct net_device *dev,
208 /* if SSID set now, we'll try to connect, avoid event */ 199 /* if SSID set now, we'll try to connect, avoid event */
209 if (len) 200 if (len)
210 event = false; 201 event = false;
211 err = __cfg80211_disconnect(rdev, dev, 202 err = cfg80211_disconnect(rdev, dev,
212 WLAN_REASON_DEAUTH_LEAVING, event); 203 WLAN_REASON_DEAUTH_LEAVING, event);
213 if (err) 204 if (err)
214 goto out; 205 goto out;
215 } 206 }
@@ -226,9 +217,6 @@ int cfg80211_mgd_wext_siwessid(struct net_device *dev,
226 err = cfg80211_mgd_wext_connect(rdev, wdev); 217 err = cfg80211_mgd_wext_connect(rdev, wdev);
227 out: 218 out:
228 wdev_unlock(wdev); 219 wdev_unlock(wdev);
229 mutex_unlock(&rdev->sched_scan_mtx);
230 mutex_unlock(&rdev->devlist_mtx);
231 cfg80211_unlock_rdev(rdev);
232 return err; 220 return err;
233} 221}
234 222
@@ -287,9 +275,6 @@ int cfg80211_mgd_wext_siwap(struct net_device *dev,
287 if (is_zero_ether_addr(bssid) || is_broadcast_ether_addr(bssid)) 275 if (is_zero_ether_addr(bssid) || is_broadcast_ether_addr(bssid))
288 bssid = NULL; 276 bssid = NULL;
289 277
290 cfg80211_lock_rdev(rdev);
291 mutex_lock(&rdev->devlist_mtx);
292 mutex_lock(&rdev->sched_scan_mtx);
293 wdev_lock(wdev); 278 wdev_lock(wdev);
294 279
295 if (wdev->sme_state != CFG80211_SME_IDLE) { 280 if (wdev->sme_state != CFG80211_SME_IDLE) {
@@ -303,8 +288,8 @@ int cfg80211_mgd_wext_siwap(struct net_device *dev,
303 ether_addr_equal(bssid, wdev->wext.connect.bssid)) 288 ether_addr_equal(bssid, wdev->wext.connect.bssid))
304 goto out; 289 goto out;
305 290
306 err = __cfg80211_disconnect(rdev, dev, 291 err = cfg80211_disconnect(rdev, dev,
307 WLAN_REASON_DEAUTH_LEAVING, false); 292 WLAN_REASON_DEAUTH_LEAVING, false);
308 if (err) 293 if (err)
309 goto out; 294 goto out;
310 } 295 }
@@ -318,9 +303,6 @@ int cfg80211_mgd_wext_siwap(struct net_device *dev,
318 err = cfg80211_mgd_wext_connect(rdev, wdev); 303 err = cfg80211_mgd_wext_connect(rdev, wdev);
319 out: 304 out:
320 wdev_unlock(wdev); 305 wdev_unlock(wdev);
321 mutex_unlock(&rdev->sched_scan_mtx);
322 mutex_unlock(&rdev->devlist_mtx);
323 cfg80211_unlock_rdev(rdev);
324 return err; 306 return err;
325} 307}
326 308
@@ -383,8 +365,8 @@ int cfg80211_wext_siwgenie(struct net_device *dev,
383 wdev->wext.ie_len = ie_len; 365 wdev->wext.ie_len = ie_len;
384 366
385 if (wdev->sme_state != CFG80211_SME_IDLE) { 367 if (wdev->sme_state != CFG80211_SME_IDLE) {
386 err = __cfg80211_disconnect(rdev, dev, 368 err = cfg80211_disconnect(rdev, dev,
387 WLAN_REASON_DEAUTH_LEAVING, false); 369 WLAN_REASON_DEAUTH_LEAVING, false);
388 if (err) 370 if (err)
389 goto out; 371 goto out;
390 } 372 }
@@ -420,8 +402,7 @@ int cfg80211_wext_siwmlme(struct net_device *dev,
420 switch (mlme->cmd) { 402 switch (mlme->cmd) {
421 case IW_MLME_DEAUTH: 403 case IW_MLME_DEAUTH:
422 case IW_MLME_DISASSOC: 404 case IW_MLME_DISASSOC:
423 err = __cfg80211_disconnect(rdev, dev, mlme->reason_code, 405 err = cfg80211_disconnect(rdev, dev, mlme->reason_code, true);
424 true);
425 break; 406 break;
426 default: 407 default:
427 err = -EOPNOTSUPP; 408 err = -EOPNOTSUPP;