aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2008-11-21 20:05:11 -0500
committerDavid S. Miller <davem@davemloft.net>2008-11-21 20:05:11 -0500
commit6c0bce37ffc8f000a516fadf6dee84579c4c8f9b (patch)
tree273af34d6f777b1ecb0fce7b2685e868064e6cf9 /drivers/net
parente243455d345ef62751723671bc2605a2f6032ceb (diff)
parenta1eb5fe319beb9e181aa52c8adf75ad9aab56a89 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/Kconfig145
-rw-r--r--drivers/net/wireless/Makefile13
-rw-r--r--drivers/net/wireless/ath5k/base.c10
-rw-r--r--drivers/net/wireless/ath5k/phy.c4
-rw-r--r--drivers/net/wireless/ath5k/reset.c4
-rw-r--r--drivers/net/wireless/ath9k/hw.c3
-rw-r--r--drivers/net/wireless/ath9k/main.c74
-rw-r--r--drivers/net/wireless/ath9k/rc.c6
-rw-r--r--drivers/net/wireless/ath9k/recv.c5
-rw-r--r--drivers/net/wireless/b43/xmit.c4
-rw-r--r--drivers/net/wireless/b43legacy/b43legacy.h5
-rw-r--r--drivers/net/wireless/b43legacy/main.c111
-rw-r--r--drivers/net/wireless/hostap/Kconfig6
-rw-r--r--drivers/net/wireless/hostap/hostap.h2
-rw-r--r--drivers/net/wireless/hostap/hostap_80211.h2
-rw-r--r--drivers/net/wireless/hostap/hostap_80211_rx.c10
-rw-r--r--drivers/net/wireless/hostap/hostap_80211_tx.c8
-rw-r--r--drivers/net/wireless/hostap/hostap_ap.c12
-rw-r--r--drivers/net/wireless/hostap/hostap_ap.h8
-rw-r--r--drivers/net/wireless/hostap/hostap_hw.c61
-rw-r--r--drivers/net/wireless/hostap/hostap_ioctl.c141
-rw-r--r--drivers/net/wireless/hostap/hostap_main.c19
-rw-r--r--drivers/net/wireless/hostap/hostap_proc.c20
-rw-r--r--drivers/net/wireless/hostap/hostap_wlan.h6
-rw-r--r--drivers/net/wireless/ipw2x00/Kconfig191
-rw-r--r--drivers/net/wireless/ipw2x00/Makefile14
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2100.c (renamed from drivers/net/wireless/ipw2100.c)12
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2100.h (renamed from drivers/net/wireless/ipw2100.h)0
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2200.c (renamed from drivers/net/wireless/ipw2200.c)15
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2200.h (renamed from drivers/net/wireless/ipw2200.h)0
-rw-r--r--drivers/net/wireless/ipw2x00/libipw_geo.c195
-rw-r--r--drivers/net/wireless/ipw2x00/libipw_module.c293
-rw-r--r--drivers/net/wireless/ipw2x00/libipw_rx.c1799
-rw-r--r--drivers/net/wireless/ipw2x00/libipw_tx.c546
-rw-r--r--drivers/net/wireless/ipw2x00/libipw_wx.c760
-rw-r--r--drivers/net/wireless/iwlwifi/Makefile1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965-hw.h117
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c44
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000-hw.h37
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c54
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c260
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-commands.h12
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c49
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h16
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debug.h10
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h43
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fh.h83
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-power.c17
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rx.c22
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-spectrum.c198
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-spectrum.h1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c55
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c49
-rw-r--r--drivers/net/wireless/libertas/cmd.c18
-rw-r--r--drivers/net/wireless/libertas/cmd.h3
-rw-r--r--drivers/net/wireless/libertas/defs.h12
-rw-r--r--drivers/net/wireless/libertas/ethtool.c2
-rw-r--r--drivers/net/wireless/libertas/host.h8
-rw-r--r--drivers/net/wireless/libertas/hostcmd.h26
-rw-r--r--drivers/net/wireless/libertas/if_usb.c3
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c6
-rw-r--r--drivers/net/wireless/orinoco/orinoco.c4
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.c108
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.c102
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.c25
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h57
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00config.c39
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c45
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00leds.c94
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00lib.h15
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mac.c17
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00pci.c13
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00pci.h11
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.c32
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.c42
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.h5
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c113
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c24
-rw-r--r--drivers/net/wireless/rtl818x/Makefile7
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180.h (renamed from drivers/net/wireless/rtl8180.h)0
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180_dev.c (renamed from drivers/net/wireless/rtl8180_dev.c)12
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180_grf5101.c (renamed from drivers/net/wireless/rtl8180_grf5101.c)0
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180_grf5101.h (renamed from drivers/net/wireless/rtl8180_grf5101.h)0
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180_max2820.c (renamed from drivers/net/wireless/rtl8180_max2820.c)0
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180_max2820.h (renamed from drivers/net/wireless/rtl8180_max2820.h)0
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180_rtl8225.c (renamed from drivers/net/wireless/rtl8180_rtl8225.c)14
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180_rtl8225.h (renamed from drivers/net/wireless/rtl8180_rtl8225.h)0
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180_sa2400.c (renamed from drivers/net/wireless/rtl8180_sa2400.c)0
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180_sa2400.h (renamed from drivers/net/wireless/rtl8180_sa2400.h)0
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187.h (renamed from drivers/net/wireless/rtl8187.h)0
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187_dev.c (renamed from drivers/net/wireless/rtl8187_dev.c)8
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187_rtl8225.c (renamed from drivers/net/wireless/rtl8187_rtl8225.c)0
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187_rtl8225.h (renamed from drivers/net/wireless/rtl8187_rtl8225.h)0
-rw-r--r--drivers/net/wireless/rtl818x/rtl818x.h (renamed from drivers/net/wireless/rtl818x.h)1
-rw-r--r--drivers/net/wireless/zd1201.c115
95 files changed, 5155 insertions, 1398 deletions
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index 42afaedbb219..84b49c83ae67 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -123,150 +123,6 @@ config PCMCIA_RAYCS
123 To compile this driver as a module, choose M here: the module will be 123 To compile this driver as a module, choose M here: the module will be
124 called ray_cs. If unsure, say N. 124 called ray_cs. If unsure, say N.
125 125
126config IPW2100
127 tristate "Intel PRO/Wireless 2100 Network Connection"
128 depends on PCI && WLAN_80211
129 select WIRELESS_EXT
130 select FW_LOADER
131 select IEEE80211
132 ---help---
133 A driver for the Intel PRO/Wireless 2100 Network
134 Connection 802.11b wireless network adapter.
135
136 See <file:Documentation/networking/README.ipw2100> for information on
137 the capabilities currently enabled in this driver and for tips
138 for debugging issues and problems.
139
140 In order to use this driver, you will need a firmware image for it.
141 You can obtain the firmware from
142 <http://ipw2100.sf.net/>. Once you have the firmware image, you
143 will need to place it in /lib/firmware.
144
145 You will also very likely need the Wireless Tools in order to
146 configure your card:
147
148 <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>.
149
150 It is recommended that you compile this driver as a module (M)
151 rather than built-in (Y). This driver requires firmware at device
152 initialization time, and when built-in this typically happens
153 before the filesystem is accessible (hence firmware will be
154 unavailable and initialization will fail). If you do choose to build
155 this driver into your kernel image, you can avoid this problem by
156 including the firmware and a firmware loader in an initramfs.
157
158config IPW2100_MONITOR
159 bool "Enable promiscuous mode"
160 depends on IPW2100
161 ---help---
162 Enables promiscuous/monitor mode support for the ipw2100 driver.
163 With this feature compiled into the driver, you can switch to
164 promiscuous mode via the Wireless Tool's Monitor mode. While in this
165 mode, no packets can be sent.
166
167config IPW2100_DEBUG
168 bool "Enable full debugging output in IPW2100 module."
169 depends on IPW2100
170 ---help---
171 This option will enable debug tracing output for the IPW2100.
172
173 This will result in the kernel module being ~60k larger. You can
174 control which debug output is sent to the kernel log by setting the
175 value in
176
177 /sys/bus/pci/drivers/ipw2100/debug_level
178
179 This entry will only exist if this option is enabled.
180
181 If you are not trying to debug or develop the IPW2100 driver, you
182 most likely want to say N here.
183
184config IPW2200
185 tristate "Intel PRO/Wireless 2200BG and 2915ABG Network Connection"
186 depends on PCI && WLAN_80211
187 select WIRELESS_EXT
188 select FW_LOADER
189 select IEEE80211
190 ---help---
191 A driver for the Intel PRO/Wireless 2200BG and 2915ABG Network
192 Connection adapters.
193
194 See <file:Documentation/networking/README.ipw2200> for
195 information on the capabilities currently enabled in this
196 driver and for tips for debugging issues and problems.
197
198 In order to use this driver, you will need a firmware image for it.
199 You can obtain the firmware from
200 <http://ipw2200.sf.net/>. See the above referenced README.ipw2200
201 for information on where to install the firmware images.
202
203 You will also very likely need the Wireless Tools in order to
204 configure your card:
205
206 <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>.
207
208 It is recommended that you compile this driver as a module (M)
209 rather than built-in (Y). This driver requires firmware at device
210 initialization time, and when built-in this typically happens
211 before the filesystem is accessible (hence firmware will be
212 unavailable and initialization will fail). If you do choose to build
213 this driver into your kernel image, you can avoid this problem by
214 including the firmware and a firmware loader in an initramfs.
215
216config IPW2200_MONITOR
217 bool "Enable promiscuous mode"
218 depends on IPW2200
219 ---help---
220 Enables promiscuous/monitor mode support for the ipw2200 driver.
221 With this feature compiled into the driver, you can switch to
222 promiscuous mode via the Wireless Tool's Monitor mode. While in this
223 mode, no packets can be sent.
224
225config IPW2200_RADIOTAP
226 bool "Enable radiotap format 802.11 raw packet support"
227 depends on IPW2200_MONITOR
228
229config IPW2200_PROMISCUOUS
230 bool "Enable creation of a RF radiotap promiscuous interface"
231 depends on IPW2200_MONITOR
232 select IPW2200_RADIOTAP
233 ---help---
234 Enables the creation of a second interface prefixed 'rtap'.
235 This second interface will provide every received in radiotap
236 format.
237
238 This is useful for performing wireless network analysis while
239 maintaining an active association.
240
241 Example usage:
242
243 % modprobe ipw2200 rtap_iface=1
244 % ifconfig rtap0 up
245 % tethereal -i rtap0
246
247 If you do not specify 'rtap_iface=1' as a module parameter then
248 the rtap interface will not be created and you will need to turn
249 it on via sysfs:
250
251 % echo 1 > /sys/bus/pci/drivers/ipw2200/*/rtap_iface
252
253config IPW2200_QOS
254 bool "Enable QoS support"
255 depends on IPW2200 && EXPERIMENTAL
256
257config IPW2200_DEBUG
258 bool "Enable full debugging output in IPW2200 module."
259 depends on IPW2200
260 ---help---
261 This option will enable low level debug tracing output for IPW2200.
262
263 Note, normal debug code is already compiled in. This low level
264 debug option enables debug on hot paths (e.g Tx, Rx, ISR) and
265 will result in the kernel module being ~70 larger. Most users
266 will typically not need this high verbosity debug information.
267
268 If you are not sure, say N here.
269
270config LIBERTAS 126config LIBERTAS
271 tristate "Marvell 8xxx Libertas WLAN driver support" 127 tristate "Marvell 8xxx Libertas WLAN driver support"
272 depends on WLAN_80211 128 depends on WLAN_80211
@@ -712,6 +568,7 @@ config MAC80211_HWSIM
712source "drivers/net/wireless/p54/Kconfig" 568source "drivers/net/wireless/p54/Kconfig"
713source "drivers/net/wireless/ath5k/Kconfig" 569source "drivers/net/wireless/ath5k/Kconfig"
714source "drivers/net/wireless/ath9k/Kconfig" 570source "drivers/net/wireless/ath9k/Kconfig"
571source "drivers/net/wireless/ipw2x00/Kconfig"
715source "drivers/net/wireless/iwlwifi/Kconfig" 572source "drivers/net/wireless/iwlwifi/Kconfig"
716source "drivers/net/wireless/hostap/Kconfig" 573source "drivers/net/wireless/hostap/Kconfig"
717source "drivers/net/wireless/b43/Kconfig" 574source "drivers/net/wireless/b43/Kconfig"
diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile
index 78820840fe21..ac590e1ca8be 100644
--- a/drivers/net/wireless/Makefile
+++ b/drivers/net/wireless/Makefile
@@ -2,9 +2,8 @@
2# Makefile for the Linux Wireless network device drivers. 2# Makefile for the Linux Wireless network device drivers.
3# 3#
4 4
5obj-$(CONFIG_IPW2100) += ipw2100.o 5obj-$(CONFIG_IPW2100) += ipw2x00/
6 6obj-$(CONFIG_IPW2200) += ipw2x00/
7obj-$(CONFIG_IPW2200) += ipw2200.o
8 7
9obj-$(CONFIG_STRIP) += strip.o 8obj-$(CONFIG_STRIP) += strip.o
10obj-$(CONFIG_ARLAN) += arlan.o 9obj-$(CONFIG_ARLAN) += arlan.o
@@ -31,6 +30,8 @@ obj-$(CONFIG_HOSTAP) += hostap/
31obj-$(CONFIG_B43) += b43/ 30obj-$(CONFIG_B43) += b43/
32obj-$(CONFIG_B43LEGACY) += b43legacy/ 31obj-$(CONFIG_B43LEGACY) += b43legacy/
33obj-$(CONFIG_ZD1211RW) += zd1211rw/ 32obj-$(CONFIG_ZD1211RW) += zd1211rw/
33obj-$(CONFIG_RTL8180) += rtl818x/
34obj-$(CONFIG_RTL8187) += rtl818x/
34 35
35# 16-bit wireless PCMCIA client drivers 36# 16-bit wireless PCMCIA client drivers
36obj-$(CONFIG_PCMCIA_RAYCS) += ray_cs.o 37obj-$(CONFIG_PCMCIA_RAYCS) += ray_cs.o
@@ -43,12 +44,6 @@ obj-$(CONFIG_LIBERTAS) += libertas/
43 44
44obj-$(CONFIG_LIBERTAS_THINFIRM) += libertas_tf/ 45obj-$(CONFIG_LIBERTAS_THINFIRM) += libertas_tf/
45 46
46rtl8180-objs := rtl8180_dev.o rtl8180_rtl8225.o rtl8180_sa2400.o rtl8180_max2820.o rtl8180_grf5101.o
47rtl8187-objs := rtl8187_dev.o rtl8187_rtl8225.o
48
49obj-$(CONFIG_RTL8180) += rtl8180.o
50obj-$(CONFIG_RTL8187) += rtl8187.o
51
52obj-$(CONFIG_ADM8211) += adm8211.o 47obj-$(CONFIG_ADM8211) += adm8211.o
53 48
54obj-$(CONFIG_IWLWIFI) += iwlwifi/ 49obj-$(CONFIG_IWLWIFI) += iwlwifi/
diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c
index c7ffcbb9062d..34cd1a4a297f 100644
--- a/drivers/net/wireless/ath5k/base.c
+++ b/drivers/net/wireless/ath5k/base.c
@@ -2219,9 +2219,9 @@ ath5k_init(struct ath5k_softc *sc, bool is_resume)
2219 */ 2219 */
2220 sc->curchan = sc->hw->conf.channel; 2220 sc->curchan = sc->hw->conf.channel;
2221 sc->curband = &sc->sbands[sc->curchan->band]; 2221 sc->curband = &sc->sbands[sc->curchan->band];
2222 sc->imask = AR5K_INT_RXOK | AR5K_INT_TXOK | AR5K_INT_RXEOL | 2222 sc->imask = AR5K_INT_RXOK | AR5K_INT_RXERR | AR5K_INT_RXEOL |
2223 AR5K_INT_RXORN | AR5K_INT_FATAL | AR5K_INT_GLOBAL | 2223 AR5K_INT_RXORN | AR5K_INT_TXDESC | AR5K_INT_TXEOL |
2224 AR5K_INT_MIB; 2224 AR5K_INT_FATAL | AR5K_INT_GLOBAL | AR5K_INT_MIB;
2225 ret = ath5k_reset(sc, false, false); 2225 ret = ath5k_reset(sc, false, false);
2226 if (ret) 2226 if (ret)
2227 goto done; 2227 goto done;
@@ -2953,9 +2953,9 @@ static void ath5k_configure_filter(struct ieee80211_hw *hw,
2953 test_bit(ATH_STAT_PROMISC, sc->status)) 2953 test_bit(ATH_STAT_PROMISC, sc->status))
2954 rfilt |= AR5K_RX_FILTER_PROM; 2954 rfilt |= AR5K_RX_FILTER_PROM;
2955 if (sc->opmode == NL80211_IFTYPE_STATION || 2955 if (sc->opmode == NL80211_IFTYPE_STATION ||
2956 sc->opmode == NL80211_IFTYPE_ADHOC) { 2956 sc->opmode == NL80211_IFTYPE_ADHOC ||
2957 sc->opmode == NL80211_IFTYPE_AP)
2957 rfilt |= AR5K_RX_FILTER_BEACON; 2958 rfilt |= AR5K_RX_FILTER_BEACON;
2958 }
2959 if (sc->opmode == NL80211_IFTYPE_MESH_POINT) 2959 if (sc->opmode == NL80211_IFTYPE_MESH_POINT)
2960 rfilt |= AR5K_RX_FILTER_CONTROL | AR5K_RX_FILTER_BEACON | 2960 rfilt |= AR5K_RX_FILTER_CONTROL | AR5K_RX_FILTER_BEACON |
2961 AR5K_RX_FILTER_PROBEREQ | AR5K_RX_FILTER_PROM; 2961 AR5K_RX_FILTER_PROBEREQ | AR5K_RX_FILTER_PROM;
diff --git a/drivers/net/wireless/ath5k/phy.c b/drivers/net/wireless/ath5k/phy.c
index 69625bf4d11c..7ba18e09463b 100644
--- a/drivers/net/wireless/ath5k/phy.c
+++ b/drivers/net/wireless/ath5k/phy.c
@@ -2196,9 +2196,7 @@ static int ath5k_hw_rf5110_calibrate(struct ath5k_hw *ah,
2196 return ret; 2196 return ret;
2197 } 2197 }
2198 2198
2199 ret = ath5k_hw_noise_floor_calibration(ah, channel->center_freq); 2199 ath5k_hw_noise_floor_calibration(ah, channel->center_freq);
2200 if (ret)
2201 return ret;
2202 2200
2203 /* 2201 /*
2204 * Re-enable RX/TX and beacons 2202 * Re-enable RX/TX and beacons
diff --git a/drivers/net/wireless/ath5k/reset.c b/drivers/net/wireless/ath5k/reset.c
index b51bc030da02..5003263c9ea4 100644
--- a/drivers/net/wireless/ath5k/reset.c
+++ b/drivers/net/wireless/ath5k/reset.c
@@ -842,9 +842,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
842 * 842 *
843 * XXX: Find an interval that's OK for all cards... 843 * XXX: Find an interval that's OK for all cards...
844 */ 844 */
845 ret = ath5k_hw_noise_floor_calibration(ah, channel->center_freq); 845 ath5k_hw_noise_floor_calibration(ah, channel->center_freq);
846 if (ret)
847 return ret;
848 846
849 /* 847 /*
850 * Reset queues and start beacon timers at the end of the reset routine 848 * Reset queues and start beacon timers at the end of the reset routine
diff --git a/drivers/net/wireless/ath9k/hw.c b/drivers/net/wireless/ath9k/hw.c
index e05c9ef55e47..ff6457e0cb00 100644
--- a/drivers/net/wireless/ath9k/hw.c
+++ b/drivers/net/wireless/ath9k/hw.c
@@ -382,8 +382,9 @@ static const char *ath9k_hw_devname(u16 devid)
382{ 382{
383 switch (devid) { 383 switch (devid) {
384 case AR5416_DEVID_PCI: 384 case AR5416_DEVID_PCI:
385 case AR5416_DEVID_PCIE:
386 return "Atheros 5416"; 385 return "Atheros 5416";
386 case AR5416_DEVID_PCIE:
387 return "Atheros 5418";
387 case AR9160_DEVID_PCI: 388 case AR9160_DEVID_PCI:
388 return "Atheros 9160"; 389 return "Atheros 9160";
389 case AR9280_DEVID_PCI: 390 case AR9280_DEVID_PCI:
diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c
index f830fe1e4adc..fbb2dd2373c8 100644
--- a/drivers/net/wireless/ath9k/main.c
+++ b/drivers/net/wireless/ath9k/main.c
@@ -18,6 +18,7 @@
18 18
19#include <linux/nl80211.h> 19#include <linux/nl80211.h>
20#include "core.h" 20#include "core.h"
21#include "reg.h"
21 22
22#define ATH_PCI_VERSION "0.1" 23#define ATH_PCI_VERSION "0.1"
23 24
@@ -1519,15 +1520,74 @@ static struct ieee80211_ops ath9k_ops = {
1519 .set_frag_threshold = ath9k_no_fragmentation, 1520 .set_frag_threshold = ath9k_no_fragmentation,
1520}; 1521};
1521 1522
1523static struct {
1524 u32 version;
1525 const char * name;
1526} ath_mac_bb_names[] = {
1527 { AR_SREV_VERSION_5416_PCI, "5416" },
1528 { AR_SREV_VERSION_5416_PCIE, "5418" },
1529 { AR_SREV_VERSION_9100, "9100" },
1530 { AR_SREV_VERSION_9160, "9160" },
1531 { AR_SREV_VERSION_9280, "9280" },
1532 { AR_SREV_VERSION_9285, "9285" }
1533};
1534
1535static struct {
1536 u16 version;
1537 const char * name;
1538} ath_rf_names[] = {
1539 { 0, "5133" },
1540 { AR_RAD5133_SREV_MAJOR, "5133" },
1541 { AR_RAD5122_SREV_MAJOR, "5122" },
1542 { AR_RAD2133_SREV_MAJOR, "2133" },
1543 { AR_RAD2122_SREV_MAJOR, "2122" }
1544};
1545
1546/*
1547 * Return the MAC/BB name. "????" is returned if the MAC/BB is unknown.
1548 */
1549
1550static const char *
1551ath_mac_bb_name(u32 mac_bb_version)
1552{
1553 int i;
1554
1555 for (i=0; i<ARRAY_SIZE(ath_mac_bb_names); i++) {
1556 if (ath_mac_bb_names[i].version == mac_bb_version) {
1557 return ath_mac_bb_names[i].name;
1558 }
1559 }
1560
1561 return "????";
1562}
1563
1564/*
1565 * Return the RF name. "????" is returned if the RF is unknown.
1566 */
1567
1568static const char *
1569ath_rf_name(u16 rf_version)
1570{
1571 int i;
1572
1573 for (i=0; i<ARRAY_SIZE(ath_rf_names); i++) {
1574 if (ath_rf_names[i].version == rf_version) {
1575 return ath_rf_names[i].name;
1576 }
1577 }
1578
1579 return "????";
1580}
1581
1522static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) 1582static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1523{ 1583{
1524 void __iomem *mem; 1584 void __iomem *mem;
1525 struct ath_softc *sc; 1585 struct ath_softc *sc;
1526 struct ieee80211_hw *hw; 1586 struct ieee80211_hw *hw;
1527 const char *athname;
1528 u8 csz; 1587 u8 csz;
1529 u32 val; 1588 u32 val;
1530 int ret = 0; 1589 int ret = 0;
1590 struct ath_hal *ah;
1531 1591
1532 if (pci_enable_device(pdev)) 1592 if (pci_enable_device(pdev))
1533 return -EIO; 1593 return -EIO;
@@ -1614,11 +1674,15 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1614 goto bad4; 1674 goto bad4;
1615 } 1675 }
1616 1676
1617 athname = ath9k_hw_probe(id->vendor, id->device); 1677 ah = sc->sc_ah;
1618 1678 printk(KERN_INFO
1619 printk(KERN_INFO "%s: %s: mem=0x%lx, irq=%d\n", 1679 "%s: Atheros AR%s MAC/BB Rev:%x "
1680 "AR%s RF Rev:%x: mem=0x%lx, irq=%d\n",
1620 wiphy_name(hw->wiphy), 1681 wiphy_name(hw->wiphy),
1621 athname ? athname : "Atheros ???", 1682 ath_mac_bb_name(ah->ah_macVersion),
1683 ah->ah_macRev,
1684 ath_rf_name((ah->ah_analog5GhzRev & AR_RADIO_SREV_MAJOR)),
1685 ah->ah_phyRev,
1622 (unsigned long)mem, pdev->irq); 1686 (unsigned long)mem, pdev->irq);
1623 1687
1624 return 0; 1688 return 0;
diff --git a/drivers/net/wireless/ath9k/rc.c b/drivers/net/wireless/ath9k/rc.c
index aa6bfd717c20..517992d14808 100644
--- a/drivers/net/wireless/ath9k/rc.c
+++ b/drivers/net/wireless/ath9k/rc.c
@@ -1272,8 +1272,7 @@ static void ath_rc_update_ht(struct ath_softc *sc,
1272 rate_ctrl->state[tx_rate].per = 100; 1272 rate_ctrl->state[tx_rate].per = 100;
1273 } else { 1273 } else {
1274 /* xretries == 2 */ 1274 /* xretries == 2 */
1275 count = sizeof(nretry_to_per_lookup) / 1275 count = ARRAY_SIZE(nretry_to_per_lookup);
1276 sizeof(nretry_to_per_lookup[0]);
1277 if (retries >= count) 1276 if (retries >= count)
1278 retries = count - 1; 1277 retries = count - 1;
1279 /* new_PER = 7/8*old_PER + 1/8*(currentPER) */ 1278 /* new_PER = 7/8*old_PER + 1/8*(currentPER) */
@@ -1291,8 +1290,7 @@ static void ath_rc_update_ht(struct ath_softc *sc,
1291 } else { /* xretries == 0 */ 1290 } else { /* xretries == 0 */
1292 /* Update the PER. */ 1291 /* Update the PER. */
1293 /* Make sure it doesn't index out of array's bounds. */ 1292 /* Make sure it doesn't index out of array's bounds. */
1294 count = sizeof(nretry_to_per_lookup) / 1293 count = ARRAY_SIZE(nretry_to_per_lookup);
1295 sizeof(nretry_to_per_lookup[0]);
1296 if (retries >= count) 1294 if (retries >= count)
1297 retries = count - 1; 1295 retries = count - 1;
1298 if (info_priv->n_bad_frames) { 1296 if (info_priv->n_bad_frames) {
diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c
index 2ecb0a010ce2..2d72ac19fada 100644
--- a/drivers/net/wireless/ath9k/recv.c
+++ b/drivers/net/wireless/ath9k/recv.c
@@ -296,9 +296,8 @@ u32 ath_calcrxfilter(struct ath_softc *sc)
296 rfilt &= ~ATH9K_RX_FILTER_UCAST; 296 rfilt &= ~ATH9K_RX_FILTER_UCAST;
297 } 297 }
298 298
299 if (((sc->sc_ah->ah_opmode == ATH9K_M_STA) && 299 if (sc->sc_ah->ah_opmode == ATH9K_M_STA ||
300 (sc->rx_filter & FIF_BCN_PRBRESP_PROMISC)) || 300 sc->sc_ah->ah_opmode == ATH9K_M_IBSS)
301 (sc->sc_ah->ah_opmode == ATH9K_M_IBSS))
302 rfilt |= ATH9K_RX_FILTER_BEACON; 301 rfilt |= ATH9K_RX_FILTER_BEACON;
303 302
304 /* If in HOSTAP mode, want to enable reception of PSPOLL frames 303 /* If in HOSTAP mode, want to enable reception of PSPOLL frames
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c
index adba89b816d4..eae9b8052658 100644
--- a/drivers/net/wireless/b43/xmit.c
+++ b/drivers/net/wireless/b43/xmit.c
@@ -46,7 +46,6 @@ static int b43_plcp_get_bitrate_idx_cck(struct b43_plcp_hdr6 *plcp)
46 case 0x6E: 46 case 0x6E:
47 return 3; 47 return 3;
48 } 48 }
49 B43_WARN_ON(1);
50 return -1; 49 return -1;
51} 50}
52 51
@@ -73,7 +72,6 @@ static u8 b43_plcp_get_bitrate_idx_ofdm(struct b43_plcp_hdr6 *plcp, bool aphy)
73 case 0xC: 72 case 0xC:
74 return base + 7; 73 return base + 7;
75 } 74 }
76 B43_WARN_ON(1);
77 return -1; 75 return -1;
78} 76}
79 77
@@ -608,6 +606,8 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
608 phytype == B43_PHYTYPE_A); 606 phytype == B43_PHYTYPE_A);
609 else 607 else
610 status.rate_idx = b43_plcp_get_bitrate_idx_cck(plcp); 608 status.rate_idx = b43_plcp_get_bitrate_idx_cck(plcp);
609 if (unlikely(status.rate_idx == -1))
610 goto drop;
611 status.antenna = !!(phystat0 & B43_RX_PHYST0_ANT); 611 status.antenna = !!(phystat0 & B43_RX_PHYST0_ANT);
612 612
613 /* 613 /*
diff --git a/drivers/net/wireless/b43legacy/b43legacy.h b/drivers/net/wireless/b43legacy/b43legacy.h
index c40078e1fff9..97b0e06dfe21 100644
--- a/drivers/net/wireless/b43legacy/b43legacy.h
+++ b/drivers/net/wireless/b43legacy/b43legacy.h
@@ -145,6 +145,10 @@
145#define B43legacy_SHM_SH_PRMAXTIME 0x0074 /* Probe Response max time */ 145#define B43legacy_SHM_SH_PRMAXTIME 0x0074 /* Probe Response max time */
146#define B43legacy_SHM_SH_PRPHYCTL 0x0188 /* Probe Resp PHY TX control */ 146#define B43legacy_SHM_SH_PRPHYCTL 0x0188 /* Probe Resp PHY TX control */
147/* SHM_SHARED rate tables */ 147/* SHM_SHARED rate tables */
148#define B43legacy_SHM_SH_OFDMDIRECT 0x0480 /* Pointer to OFDM direct map */
149#define B43legacy_SHM_SH_OFDMBASIC 0x04A0 /* Pointer to OFDM basic rate map */
150#define B43legacy_SHM_SH_CCKDIRECT 0x04C0 /* Pointer to CCK direct map */
151#define B43legacy_SHM_SH_CCKBASIC 0x04E0 /* Pointer to CCK basic rate map */
148/* SHM_SHARED microcode soft registers */ 152/* SHM_SHARED microcode soft registers */
149#define B43legacy_SHM_SH_UCODEREV 0x0000 /* Microcode revision */ 153#define B43legacy_SHM_SH_UCODEREV 0x0000 /* Microcode revision */
150#define B43legacy_SHM_SH_UCODEPATCH 0x0002 /* Microcode patchlevel */ 154#define B43legacy_SHM_SH_UCODEPATCH 0x0002 /* Microcode patchlevel */
@@ -663,7 +667,6 @@ struct b43legacy_wldev {
663 bool bad_frames_preempt;/* Use "Bad Frames Preemption". */ 667 bool bad_frames_preempt;/* Use "Bad Frames Preemption". */
664 bool dfq_valid; /* Directed frame queue valid (IBSS PS mode, ATIM). */ 668 bool dfq_valid; /* Directed frame queue valid (IBSS PS mode, ATIM). */
665 bool short_preamble; /* TRUE if using short preamble. */ 669 bool short_preamble; /* TRUE if using short preamble. */
666 bool short_slot; /* TRUE if using short slot timing. */
667 bool radio_hw_enable; /* State of radio hardware enable bit. */ 670 bool radio_hw_enable; /* State of radio hardware enable bit. */
668 671
669 /* PHY/Radio device. */ 672 /* PHY/Radio device. */
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c
index 6c8eb4d2519a..c1324e31d2f6 100644
--- a/drivers/net/wireless/b43legacy/main.c
+++ b/drivers/net/wireless/b43legacy/main.c
@@ -576,13 +576,11 @@ static void b43legacy_set_slot_time(struct b43legacy_wldev *dev,
576static void b43legacy_short_slot_timing_enable(struct b43legacy_wldev *dev) 576static void b43legacy_short_slot_timing_enable(struct b43legacy_wldev *dev)
577{ 577{
578 b43legacy_set_slot_time(dev, 9); 578 b43legacy_set_slot_time(dev, 9);
579 dev->short_slot = 1;
580} 579}
581 580
582static void b43legacy_short_slot_timing_disable(struct b43legacy_wldev *dev) 581static void b43legacy_short_slot_timing_disable(struct b43legacy_wldev *dev)
583{ 582{
584 b43legacy_set_slot_time(dev, 20); 583 b43legacy_set_slot_time(dev, 20);
585 dev->short_slot = 0;
586} 584}
587 585
588/* Enable a Generic IRQ. "mask" is the mask of which IRQs to enable. 586/* Enable a Generic IRQ. "mask" is the mask of which IRQs to enable.
@@ -2608,16 +2606,6 @@ static int b43legacy_op_dev_config(struct ieee80211_hw *hw,
2608 if (conf->channel->hw_value != phy->channel) 2606 if (conf->channel->hw_value != phy->channel)
2609 b43legacy_radio_selectchannel(dev, conf->channel->hw_value, 0); 2607 b43legacy_radio_selectchannel(dev, conf->channel->hw_value, 0);
2610 2608
2611 /* Enable/Disable ShortSlot timing. */
2612 if ((!!(conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME))
2613 != dev->short_slot) {
2614 B43legacy_WARN_ON(phy->type != B43legacy_PHYTYPE_G);
2615 if (conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME)
2616 b43legacy_short_slot_timing_enable(dev);
2617 else
2618 b43legacy_short_slot_timing_disable(dev);
2619 }
2620
2621 dev->wl->radiotap_enabled = !!(conf->flags & IEEE80211_CONF_RADIOTAP); 2609 dev->wl->radiotap_enabled = !!(conf->flags & IEEE80211_CONF_RADIOTAP);
2622 2610
2623 /* Adjust the desired TX power level. */ 2611 /* Adjust the desired TX power level. */
@@ -2662,6 +2650,104 @@ out_unlock_mutex:
2662 return err; 2650 return err;
2663} 2651}
2664 2652
2653static void b43legacy_update_basic_rates(struct b43legacy_wldev *dev, u64 brates)
2654{
2655 struct ieee80211_supported_band *sband =
2656 dev->wl->hw->wiphy->bands[IEEE80211_BAND_2GHZ];
2657 struct ieee80211_rate *rate;
2658 int i;
2659 u16 basic, direct, offset, basic_offset, rateptr;
2660
2661 for (i = 0; i < sband->n_bitrates; i++) {
2662 rate = &sband->bitrates[i];
2663
2664 if (b43legacy_is_cck_rate(rate->hw_value)) {
2665 direct = B43legacy_SHM_SH_CCKDIRECT;
2666 basic = B43legacy_SHM_SH_CCKBASIC;
2667 offset = b43legacy_plcp_get_ratecode_cck(rate->hw_value);
2668 offset &= 0xF;
2669 } else {
2670 direct = B43legacy_SHM_SH_OFDMDIRECT;
2671 basic = B43legacy_SHM_SH_OFDMBASIC;
2672 offset = b43legacy_plcp_get_ratecode_ofdm(rate->hw_value);
2673 offset &= 0xF;
2674 }
2675
2676 rate = ieee80211_get_response_rate(sband, brates, rate->bitrate);
2677
2678 if (b43legacy_is_cck_rate(rate->hw_value)) {
2679 basic_offset = b43legacy_plcp_get_ratecode_cck(rate->hw_value);
2680 basic_offset &= 0xF;
2681 } else {
2682 basic_offset = b43legacy_plcp_get_ratecode_ofdm(rate->hw_value);
2683 basic_offset &= 0xF;
2684 }
2685
2686 /*
2687 * Get the pointer that we need to point to
2688 * from the direct map
2689 */
2690 rateptr = b43legacy_shm_read16(dev, B43legacy_SHM_SHARED,
2691 direct + 2 * basic_offset);
2692 /* and write it to the basic map */
2693 b43legacy_shm_write16(dev, B43legacy_SHM_SHARED,
2694 basic + 2 * offset, rateptr);
2695 }
2696}
2697
2698static void b43legacy_op_bss_info_changed(struct ieee80211_hw *hw,
2699 struct ieee80211_vif *vif,
2700 struct ieee80211_bss_conf *conf,
2701 u32 changed)
2702{
2703 struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
2704 struct b43legacy_wldev *dev;
2705 struct b43legacy_phy *phy;
2706 unsigned long flags;
2707 u32 savedirqs;
2708
2709 mutex_lock(&wl->mutex);
2710
2711 dev = wl->current_dev;
2712 phy = &dev->phy;
2713
2714 /* Disable IRQs while reconfiguring the device.
2715 * This makes it possible to drop the spinlock throughout
2716 * the reconfiguration process. */
2717 spin_lock_irqsave(&wl->irq_lock, flags);
2718 if (b43legacy_status(dev) < B43legacy_STAT_STARTED) {
2719 spin_unlock_irqrestore(&wl->irq_lock, flags);
2720 goto out_unlock_mutex;
2721 }
2722 savedirqs = b43legacy_interrupt_disable(dev, B43legacy_IRQ_ALL);
2723 spin_unlock_irqrestore(&wl->irq_lock, flags);
2724 b43legacy_synchronize_irq(dev);
2725
2726 b43legacy_mac_suspend(dev);
2727
2728 if (changed & BSS_CHANGED_BASIC_RATES)
2729 b43legacy_update_basic_rates(dev, conf->basic_rates);
2730
2731 if (changed & BSS_CHANGED_ERP_SLOT) {
2732 if (conf->use_short_slot)
2733 b43legacy_short_slot_timing_enable(dev);
2734 else
2735 b43legacy_short_slot_timing_disable(dev);
2736 }
2737
2738 b43legacy_mac_enable(dev);
2739
2740 spin_lock_irqsave(&wl->irq_lock, flags);
2741 b43legacy_interrupt_enable(dev, savedirqs);
2742 /* XXX: why? */
2743 mmiowb();
2744 spin_unlock_irqrestore(&wl->irq_lock, flags);
2745 out_unlock_mutex:
2746 mutex_unlock(&wl->mutex);
2747
2748 return;
2749}
2750
2665static void b43legacy_op_configure_filter(struct ieee80211_hw *hw, 2751static void b43legacy_op_configure_filter(struct ieee80211_hw *hw,
2666 unsigned int changed, 2752 unsigned int changed,
2667 unsigned int *fflags, 2753 unsigned int *fflags,
@@ -3370,6 +3456,7 @@ static const struct ieee80211_ops b43legacy_hw_ops = {
3370 .add_interface = b43legacy_op_add_interface, 3456 .add_interface = b43legacy_op_add_interface,
3371 .remove_interface = b43legacy_op_remove_interface, 3457 .remove_interface = b43legacy_op_remove_interface,
3372 .config = b43legacy_op_dev_config, 3458 .config = b43legacy_op_dev_config,
3459 .bss_info_changed = b43legacy_op_bss_info_changed,
3373 .config_interface = b43legacy_op_config_interface, 3460 .config_interface = b43legacy_op_config_interface,
3374 .configure_filter = b43legacy_op_configure_filter, 3461 .configure_filter = b43legacy_op_configure_filter,
3375 .get_stats = b43legacy_op_get_stats, 3462 .get_stats = b43legacy_op_get_stats,
diff --git a/drivers/net/wireless/hostap/Kconfig b/drivers/net/wireless/hostap/Kconfig
index 1fef33169fdd..87bbd4db4bad 100644
--- a/drivers/net/wireless/hostap/Kconfig
+++ b/drivers/net/wireless/hostap/Kconfig
@@ -2,8 +2,10 @@ config HOSTAP
2 tristate "IEEE 802.11 for Host AP (Prism2/2.5/3 and WEP/TKIP/CCMP)" 2 tristate "IEEE 802.11 for Host AP (Prism2/2.5/3 and WEP/TKIP/CCMP)"
3 depends on WLAN_80211 3 depends on WLAN_80211
4 select WIRELESS_EXT 4 select WIRELESS_EXT
5 select IEEE80211 5 select LIB80211
6 select IEEE80211_CRYPT_WEP 6 select LIB80211_CRYPT_WEP
7 select LIB80211_CRYPT_TKIP
8 select LIB80211_CRYPT_CCMP
7 ---help--- 9 ---help---
8 Shared driver code for IEEE 802.11b wireless cards based on 10 Shared driver code for IEEE 802.11b wireless cards based on
9 Intersil Prism2/2.5/3 chipset. This driver supports so called 11 Intersil Prism2/2.5/3 chipset. This driver supports so called
diff --git a/drivers/net/wireless/hostap/hostap.h b/drivers/net/wireless/hostap/hostap.h
index 3a386a636cca..2453deaa3e00 100644
--- a/drivers/net/wireless/hostap/hostap.h
+++ b/drivers/net/wireless/hostap/hostap.h
@@ -63,7 +63,7 @@ void ap_control_flush_macs(struct mac_restrictions *mac_restrictions);
63int ap_control_kick_mac(struct ap_data *ap, struct net_device *dev, u8 *mac); 63int ap_control_kick_mac(struct ap_data *ap, struct net_device *dev, u8 *mac);
64void ap_control_kickall(struct ap_data *ap); 64void ap_control_kickall(struct ap_data *ap);
65void * ap_crypt_get_ptrs(struct ap_data *ap, u8 *addr, int permanent, 65void * ap_crypt_get_ptrs(struct ap_data *ap, u8 *addr, int permanent,
66 struct ieee80211_crypt_data ***crypt); 66 struct lib80211_crypt_data ***crypt);
67int prism2_ap_get_sta_qual(local_info_t *local, struct sockaddr addr[], 67int prism2_ap_get_sta_qual(local_info_t *local, struct sockaddr addr[],
68 struct iw_quality qual[], int buf_size, 68 struct iw_quality qual[], int buf_size,
69 int aplist); 69 int aplist);
diff --git a/drivers/net/wireless/hostap/hostap_80211.h b/drivers/net/wireless/hostap/hostap_80211.h
index 3694b1eba521..3a9474d9a907 100644
--- a/drivers/net/wireless/hostap/hostap_80211.h
+++ b/drivers/net/wireless/hostap/hostap_80211.h
@@ -2,7 +2,7 @@
2#define HOSTAP_80211_H 2#define HOSTAP_80211_H
3 3
4#include <linux/types.h> 4#include <linux/types.h>
5#include <net/ieee80211_crypt.h> 5#include <net/ieee80211.h>
6 6
7struct hostap_ieee80211_mgmt { 7struct hostap_ieee80211_mgmt {
8 __le16 frame_control; 8 __le16 frame_control;
diff --git a/drivers/net/wireless/hostap/hostap_80211_rx.c b/drivers/net/wireless/hostap/hostap_80211_rx.c
index 5f64461aa54e..19b1bf0478bd 100644
--- a/drivers/net/wireless/hostap/hostap_80211_rx.c
+++ b/drivers/net/wireless/hostap/hostap_80211_rx.c
@@ -1,5 +1,5 @@
1#include <linux/etherdevice.h> 1#include <linux/etherdevice.h>
2#include <net/ieee80211_crypt.h> 2#include <net/lib80211.h>
3 3
4#include "hostap_80211.h" 4#include "hostap_80211.h"
5#include "hostap.h" 5#include "hostap.h"
@@ -649,7 +649,7 @@ static int hostap_is_eapol_frame(local_info_t *local, struct sk_buff *skb)
649/* Called only as a tasklet (software IRQ) */ 649/* Called only as a tasklet (software IRQ) */
650static int 650static int
651hostap_rx_frame_decrypt(local_info_t *local, struct sk_buff *skb, 651hostap_rx_frame_decrypt(local_info_t *local, struct sk_buff *skb,
652 struct ieee80211_crypt_data *crypt) 652 struct lib80211_crypt_data *crypt)
653{ 653{
654 struct ieee80211_hdr_4addr *hdr; 654 struct ieee80211_hdr_4addr *hdr;
655 int res, hdrlen; 655 int res, hdrlen;
@@ -687,7 +687,7 @@ hostap_rx_frame_decrypt(local_info_t *local, struct sk_buff *skb,
687/* Called only as a tasklet (software IRQ) */ 687/* Called only as a tasklet (software IRQ) */
688static int 688static int
689hostap_rx_frame_decrypt_msdu(local_info_t *local, struct sk_buff *skb, 689hostap_rx_frame_decrypt_msdu(local_info_t *local, struct sk_buff *skb,
690 int keyidx, struct ieee80211_crypt_data *crypt) 690 int keyidx, struct lib80211_crypt_data *crypt)
691{ 691{
692 struct ieee80211_hdr_4addr *hdr; 692 struct ieee80211_hdr_4addr *hdr;
693 int res, hdrlen; 693 int res, hdrlen;
@@ -733,7 +733,7 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
733 int from_assoc_ap = 0; 733 int from_assoc_ap = 0;
734 u8 dst[ETH_ALEN]; 734 u8 dst[ETH_ALEN];
735 u8 src[ETH_ALEN]; 735 u8 src[ETH_ALEN];
736 struct ieee80211_crypt_data *crypt = NULL; 736 struct lib80211_crypt_data *crypt = NULL;
737 void *sta = NULL; 737 void *sta = NULL;
738 int keyidx = 0; 738 int keyidx = 0;
739 739
@@ -785,7 +785,7 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
785 int idx = 0; 785 int idx = 0;
786 if (skb->len >= hdrlen + 3) 786 if (skb->len >= hdrlen + 3)
787 idx = skb->data[hdrlen + 3] >> 6; 787 idx = skb->data[hdrlen + 3] >> 6;
788 crypt = local->crypt[idx]; 788 crypt = local->crypt_info.crypt[idx];
789 sta = NULL; 789 sta = NULL;
790 790
791 /* Use station specific key to override default keys if the 791 /* Use station specific key to override default keys if the
diff --git a/drivers/net/wireless/hostap/hostap_80211_tx.c b/drivers/net/wireless/hostap/hostap_80211_tx.c
index 075247188e64..078a010f39a0 100644
--- a/drivers/net/wireless/hostap/hostap_80211_tx.c
+++ b/drivers/net/wireless/hostap/hostap_80211_tx.c
@@ -306,7 +306,7 @@ int hostap_mgmt_start_xmit(struct sk_buff *skb, struct net_device *dev)
306 306
307/* Called only from software IRQ */ 307/* Called only from software IRQ */
308static struct sk_buff * hostap_tx_encrypt(struct sk_buff *skb, 308static struct sk_buff * hostap_tx_encrypt(struct sk_buff *skb,
309 struct ieee80211_crypt_data *crypt) 309 struct lib80211_crypt_data *crypt)
310{ 310{
311 struct hostap_interface *iface; 311 struct hostap_interface *iface;
312 local_info_t *local; 312 local_info_t *local;
@@ -405,7 +405,7 @@ int hostap_master_start_xmit(struct sk_buff *skb, struct net_device *dev)
405 if (local->host_encrypt) { 405 if (local->host_encrypt) {
406 /* Set crypt to default algorithm and key; will be replaced in 406 /* Set crypt to default algorithm and key; will be replaced in
407 * AP code if STA has own alg/key */ 407 * AP code if STA has own alg/key */
408 tx.crypt = local->crypt[local->tx_keyidx]; 408 tx.crypt = local->crypt_info.crypt[local->crypt_info.tx_keyidx];
409 tx.host_encrypt = 1; 409 tx.host_encrypt = 1;
410 } else { 410 } else {
411 tx.crypt = NULL; 411 tx.crypt = NULL;
@@ -487,7 +487,9 @@ int hostap_master_start_xmit(struct sk_buff *skb, struct net_device *dev)
487 487
488 if (tx.crypt && (!tx.crypt->ops || !tx.crypt->ops->encrypt_mpdu)) 488 if (tx.crypt && (!tx.crypt->ops || !tx.crypt->ops->encrypt_mpdu))
489 tx.crypt = NULL; 489 tx.crypt = NULL;
490 else if ((tx.crypt || local->crypt[local->tx_keyidx]) && !no_encrypt) { 490 else if ((tx.crypt ||
491 local->crypt_info.crypt[local->crypt_info.tx_keyidx]) &&
492 !no_encrypt) {
491 /* Add ISWEP flag both for firmware and host based encryption 493 /* Add ISWEP flag both for firmware and host based encryption
492 */ 494 */
493 fc |= IEEE80211_FCTL_PROTECTED; 495 fc |= IEEE80211_FCTL_PROTECTED;
diff --git a/drivers/net/wireless/hostap/hostap_ap.c b/drivers/net/wireless/hostap/hostap_ap.c
index dec3dbe1bf8f..0903db786d5f 100644
--- a/drivers/net/wireless/hostap/hostap_ap.c
+++ b/drivers/net/wireless/hostap/hostap_ap.c
@@ -1206,7 +1206,7 @@ static void prism2_check_tx_rates(struct sta_info *sta)
1206 1206
1207static void ap_crypt_init(struct ap_data *ap) 1207static void ap_crypt_init(struct ap_data *ap)
1208{ 1208{
1209 ap->crypt = ieee80211_get_crypto_ops("WEP"); 1209 ap->crypt = lib80211_get_crypto_ops("WEP");
1210 1210
1211 if (ap->crypt) { 1211 if (ap->crypt) {
1212 if (ap->crypt->init) { 1212 if (ap->crypt->init) {
@@ -1224,7 +1224,7 @@ static void ap_crypt_init(struct ap_data *ap)
1224 1224
1225 if (ap->crypt == NULL) { 1225 if (ap->crypt == NULL) {
1226 printk(KERN_WARNING "AP could not initialize WEP: load module " 1226 printk(KERN_WARNING "AP could not initialize WEP: load module "
1227 "ieee80211_crypt_wep.ko\n"); 1227 "lib80211_crypt_wep.ko\n");
1228 } 1228 }
1229} 1229}
1230 1230
@@ -1293,7 +1293,7 @@ static void handle_authen(local_info_t *local, struct sk_buff *skb,
1293 __le16 *pos; 1293 __le16 *pos;
1294 u16 resp = WLAN_STATUS_SUCCESS, fc; 1294 u16 resp = WLAN_STATUS_SUCCESS, fc;
1295 struct sta_info *sta = NULL; 1295 struct sta_info *sta = NULL;
1296 struct ieee80211_crypt_data *crypt; 1296 struct lib80211_crypt_data *crypt;
1297 char *txt = ""; 1297 char *txt = "";
1298 1298
1299 len = skb->len - IEEE80211_MGMT_HDR_LEN; 1299 len = skb->len - IEEE80211_MGMT_HDR_LEN;
@@ -1319,7 +1319,7 @@ static void handle_authen(local_info_t *local, struct sk_buff *skb,
1319 int idx = 0; 1319 int idx = 0;
1320 if (skb->len >= hdrlen + 3) 1320 if (skb->len >= hdrlen + 3)
1321 idx = skb->data[hdrlen + 3] >> 6; 1321 idx = skb->data[hdrlen + 3] >> 6;
1322 crypt = local->crypt[idx]; 1322 crypt = local->crypt_info.crypt[idx];
1323 } 1323 }
1324 1324
1325 pos = (__le16 *) (skb->data + IEEE80211_MGMT_HDR_LEN); 1325 pos = (__le16 *) (skb->data + IEEE80211_MGMT_HDR_LEN);
@@ -3065,7 +3065,7 @@ ap_rx_ret hostap_handle_sta_rx(local_info_t *local, struct net_device *dev,
3065/* Called only as a tasklet (software IRQ) */ 3065/* Called only as a tasklet (software IRQ) */
3066int hostap_handle_sta_crypto(local_info_t *local, 3066int hostap_handle_sta_crypto(local_info_t *local,
3067 struct ieee80211_hdr_4addr *hdr, 3067 struct ieee80211_hdr_4addr *hdr,
3068 struct ieee80211_crypt_data **crypt, 3068 struct lib80211_crypt_data **crypt,
3069 void **sta_ptr) 3069 void **sta_ptr)
3070{ 3070{
3071 struct sta_info *sta; 3071 struct sta_info *sta;
@@ -3213,7 +3213,7 @@ void hostap_update_rates(local_info_t *local)
3213 3213
3214 3214
3215void * ap_crypt_get_ptrs(struct ap_data *ap, u8 *addr, int permanent, 3215void * ap_crypt_get_ptrs(struct ap_data *ap, u8 *addr, int permanent,
3216 struct ieee80211_crypt_data ***crypt) 3216 struct lib80211_crypt_data ***crypt)
3217{ 3217{
3218 struct sta_info *sta; 3218 struct sta_info *sta;
3219 3219
diff --git a/drivers/net/wireless/hostap/hostap_ap.h b/drivers/net/wireless/hostap/hostap_ap.h
index 2fa2452b6b07..d36e4b175336 100644
--- a/drivers/net/wireless/hostap/hostap_ap.h
+++ b/drivers/net/wireless/hostap/hostap_ap.h
@@ -74,7 +74,7 @@ struct sta_info {
74 u32 tx_since_last_failure; 74 u32 tx_since_last_failure;
75 u32 tx_consecutive_exc; 75 u32 tx_consecutive_exc;
76 76
77 struct ieee80211_crypt_data *crypt; 77 struct lib80211_crypt_data *crypt;
78 78
79 int ap; /* whether this station is an AP */ 79 int ap; /* whether this station is an AP */
80 80
@@ -209,7 +209,7 @@ struct ap_data {
209 209
210 /* WEP operations for generating challenges to be used with shared key 210 /* WEP operations for generating challenges to be used with shared key
211 * authentication */ 211 * authentication */
212 struct ieee80211_crypto_ops *crypt; 212 struct lib80211_crypto_ops *crypt;
213 void *crypt_priv; 213 void *crypt_priv;
214#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */ 214#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
215}; 215};
@@ -229,7 +229,7 @@ typedef enum {
229struct hostap_tx_data { 229struct hostap_tx_data {
230 struct sk_buff *skb; 230 struct sk_buff *skb;
231 int host_encrypt; 231 int host_encrypt;
232 struct ieee80211_crypt_data *crypt; 232 struct lib80211_crypt_data *crypt;
233 void *sta_ptr; 233 void *sta_ptr;
234}; 234};
235ap_tx_ret hostap_handle_sta_tx(local_info_t *local, struct hostap_tx_data *tx); 235ap_tx_ret hostap_handle_sta_tx(local_info_t *local, struct hostap_tx_data *tx);
@@ -244,7 +244,7 @@ ap_rx_ret hostap_handle_sta_rx(local_info_t *local, struct net_device *dev,
244 struct hostap_80211_rx_status *rx_stats, 244 struct hostap_80211_rx_status *rx_stats,
245 int wds); 245 int wds);
246int hostap_handle_sta_crypto(local_info_t *local, struct ieee80211_hdr_4addr *hdr, 246int hostap_handle_sta_crypto(local_info_t *local, struct ieee80211_hdr_4addr *hdr,
247 struct ieee80211_crypt_data **crypt, 247 struct lib80211_crypt_data **crypt,
248 void **sta_ptr); 248 void **sta_ptr);
249int hostap_is_sta_assoc(struct ap_data *ap, u8 *sta_addr); 249int hostap_is_sta_assoc(struct ap_data *ap, u8 *sta_addr);
250int hostap_is_sta_authorized(struct ap_data *ap, u8 *sta_addr); 250int hostap_is_sta_authorized(struct ap_data *ap, u8 *sta_addr);
diff --git a/drivers/net/wireless/hostap/hostap_hw.c b/drivers/net/wireless/hostap/hostap_hw.c
index fd7f7ceeac46..0f27059bbe85 100644
--- a/drivers/net/wireless/hostap/hostap_hw.c
+++ b/drivers/net/wireless/hostap/hostap_hw.c
@@ -47,7 +47,7 @@
47#include <linux/wireless.h> 47#include <linux/wireless.h>
48#include <net/iw_handler.h> 48#include <net/iw_handler.h>
49#include <net/ieee80211.h> 49#include <net/ieee80211.h>
50#include <net/ieee80211_crypt.h> 50#include <net/lib80211.h>
51#include <asm/irq.h> 51#include <asm/irq.h>
52 52
53#include "hostap_80211.h" 53#include "hostap_80211.h"
@@ -2788,45 +2788,6 @@ static void prism2_check_sta_fw_version(local_info_t *local)
2788} 2788}
2789 2789
2790 2790
2791static void prism2_crypt_deinit_entries(local_info_t *local, int force)
2792{
2793 struct list_head *ptr, *n;
2794 struct ieee80211_crypt_data *entry;
2795
2796 for (ptr = local->crypt_deinit_list.next, n = ptr->next;
2797 ptr != &local->crypt_deinit_list; ptr = n, n = ptr->next) {
2798 entry = list_entry(ptr, struct ieee80211_crypt_data, list);
2799
2800 if (atomic_read(&entry->refcnt) != 0 && !force)
2801 continue;
2802
2803 list_del(ptr);
2804
2805 if (entry->ops)
2806 entry->ops->deinit(entry->priv);
2807 kfree(entry);
2808 }
2809}
2810
2811
2812static void prism2_crypt_deinit_handler(unsigned long data)
2813{
2814 local_info_t *local = (local_info_t *) data;
2815 unsigned long flags;
2816
2817 spin_lock_irqsave(&local->lock, flags);
2818 prism2_crypt_deinit_entries(local, 0);
2819 if (!list_empty(&local->crypt_deinit_list)) {
2820 printk(KERN_DEBUG "%s: entries remaining in delayed crypt "
2821 "deletion list\n", local->dev->name);
2822 local->crypt_deinit_timer.expires = jiffies + HZ;
2823 add_timer(&local->crypt_deinit_timer);
2824 }
2825 spin_unlock_irqrestore(&local->lock, flags);
2826
2827}
2828
2829
2830static void hostap_passive_scan(unsigned long data) 2791static void hostap_passive_scan(unsigned long data)
2831{ 2792{
2832 local_info_t *local = (local_info_t *) data; 2793 local_info_t *local = (local_info_t *) data;
@@ -3250,10 +3211,8 @@ while (0)
3250 3211
3251 INIT_LIST_HEAD(&local->cmd_queue); 3212 INIT_LIST_HEAD(&local->cmd_queue);
3252 init_waitqueue_head(&local->hostscan_wq); 3213 init_waitqueue_head(&local->hostscan_wq);
3253 INIT_LIST_HEAD(&local->crypt_deinit_list); 3214
3254 init_timer(&local->crypt_deinit_timer); 3215 lib80211_crypt_info_init(&local->crypt_info, dev->name, &local->lock);
3255 local->crypt_deinit_timer.data = (unsigned long) local;
3256 local->crypt_deinit_timer.function = prism2_crypt_deinit_handler;
3257 3216
3258 init_timer(&local->passive_scan_timer); 3217 init_timer(&local->passive_scan_timer);
3259 local->passive_scan_timer.data = (unsigned long) local; 3218 local->passive_scan_timer.data = (unsigned long) local;
@@ -3354,9 +3313,7 @@ static void prism2_free_local_data(struct net_device *dev)
3354 3313
3355 flush_scheduled_work(); 3314 flush_scheduled_work();
3356 3315
3357 if (timer_pending(&local->crypt_deinit_timer)) 3316 lib80211_crypt_info_free(&local->crypt_info);
3358 del_timer(&local->crypt_deinit_timer);
3359 prism2_crypt_deinit_entries(local, 1);
3360 3317
3361 if (timer_pending(&local->passive_scan_timer)) 3318 if (timer_pending(&local->passive_scan_timer))
3362 del_timer(&local->passive_scan_timer); 3319 del_timer(&local->passive_scan_timer);
@@ -3373,16 +3330,6 @@ static void prism2_free_local_data(struct net_device *dev)
3373 if (local->dev_enabled) 3330 if (local->dev_enabled)
3374 prism2_callback(local, PRISM2_CALLBACK_DISABLE); 3331 prism2_callback(local, PRISM2_CALLBACK_DISABLE);
3375 3332
3376 for (i = 0; i < WEP_KEYS; i++) {
3377 struct ieee80211_crypt_data *crypt = local->crypt[i];
3378 if (crypt) {
3379 if (crypt->ops)
3380 crypt->ops->deinit(crypt->priv);
3381 kfree(crypt);
3382 local->crypt[i] = NULL;
3383 }
3384 }
3385
3386 if (local->ap != NULL) 3333 if (local->ap != NULL)
3387 hostap_free_data(local->ap); 3334 hostap_free_data(local->ap);
3388 3335
diff --git a/drivers/net/wireless/hostap/hostap_ioctl.c b/drivers/net/wireless/hostap/hostap_ioctl.c
index 2318c5df7a08..c40fdf4c79de 100644
--- a/drivers/net/wireless/hostap/hostap_ioctl.c
+++ b/drivers/net/wireless/hostap/hostap_ioctl.c
@@ -2,7 +2,7 @@
2 2
3#include <linux/types.h> 3#include <linux/types.h>
4#include <linux/ethtool.h> 4#include <linux/ethtool.h>
5#include <net/ieee80211_crypt.h> 5#include <net/lib80211.h>
6 6
7#include "hostap_wlan.h" 7#include "hostap_wlan.h"
8#include "hostap.h" 8#include "hostap.h"
@@ -116,32 +116,6 @@ static int prism2_get_name(struct net_device *dev,
116} 116}
117 117
118 118
119static void prism2_crypt_delayed_deinit(local_info_t *local,
120 struct ieee80211_crypt_data **crypt)
121{
122 struct ieee80211_crypt_data *tmp;
123 unsigned long flags;
124
125 tmp = *crypt;
126 *crypt = NULL;
127
128 if (tmp == NULL)
129 return;
130
131 /* must not run ops->deinit() while there may be pending encrypt or
132 * decrypt operations. Use a list of delayed deinits to avoid needing
133 * locking. */
134
135 spin_lock_irqsave(&local->lock, flags);
136 list_add(&tmp->list, &local->crypt_deinit_list);
137 if (!timer_pending(&local->crypt_deinit_timer)) {
138 local->crypt_deinit_timer.expires = jiffies + HZ;
139 add_timer(&local->crypt_deinit_timer);
140 }
141 spin_unlock_irqrestore(&local->lock, flags);
142}
143
144
145static int prism2_ioctl_siwencode(struct net_device *dev, 119static int prism2_ioctl_siwencode(struct net_device *dev,
146 struct iw_request_info *info, 120 struct iw_request_info *info,
147 struct iw_point *erq, char *keybuf) 121 struct iw_point *erq, char *keybuf)
@@ -149,47 +123,47 @@ static int prism2_ioctl_siwencode(struct net_device *dev,
149 struct hostap_interface *iface; 123 struct hostap_interface *iface;
150 local_info_t *local; 124 local_info_t *local;
151 int i; 125 int i;
152 struct ieee80211_crypt_data **crypt; 126 struct lib80211_crypt_data **crypt;
153 127
154 iface = netdev_priv(dev); 128 iface = netdev_priv(dev);
155 local = iface->local; 129 local = iface->local;
156 130
157 i = erq->flags & IW_ENCODE_INDEX; 131 i = erq->flags & IW_ENCODE_INDEX;
158 if (i < 1 || i > 4) 132 if (i < 1 || i > 4)
159 i = local->tx_keyidx; 133 i = local->crypt_info.tx_keyidx;
160 else 134 else
161 i--; 135 i--;
162 if (i < 0 || i >= WEP_KEYS) 136 if (i < 0 || i >= WEP_KEYS)
163 return -EINVAL; 137 return -EINVAL;
164 138
165 crypt = &local->crypt[i]; 139 crypt = &local->crypt_info.crypt[i];
166 140
167 if (erq->flags & IW_ENCODE_DISABLED) { 141 if (erq->flags & IW_ENCODE_DISABLED) {
168 if (*crypt) 142 if (*crypt)
169 prism2_crypt_delayed_deinit(local, crypt); 143 lib80211_crypt_delayed_deinit(&local->crypt_info, crypt);
170 goto done; 144 goto done;
171 } 145 }
172 146
173 if (*crypt != NULL && (*crypt)->ops != NULL && 147 if (*crypt != NULL && (*crypt)->ops != NULL &&
174 strcmp((*crypt)->ops->name, "WEP") != 0) { 148 strcmp((*crypt)->ops->name, "WEP") != 0) {
175 /* changing to use WEP; deinit previously used algorithm */ 149 /* changing to use WEP; deinit previously used algorithm */
176 prism2_crypt_delayed_deinit(local, crypt); 150 lib80211_crypt_delayed_deinit(&local->crypt_info, crypt);
177 } 151 }
178 152
179 if (*crypt == NULL) { 153 if (*crypt == NULL) {
180 struct ieee80211_crypt_data *new_crypt; 154 struct lib80211_crypt_data *new_crypt;
181 155
182 /* take WEP into use */ 156 /* take WEP into use */
183 new_crypt = kzalloc(sizeof(struct ieee80211_crypt_data), 157 new_crypt = kzalloc(sizeof(struct lib80211_crypt_data),
184 GFP_KERNEL); 158 GFP_KERNEL);
185 if (new_crypt == NULL) 159 if (new_crypt == NULL)
186 return -ENOMEM; 160 return -ENOMEM;
187 new_crypt->ops = ieee80211_get_crypto_ops("WEP"); 161 new_crypt->ops = lib80211_get_crypto_ops("WEP");
188 if (!new_crypt->ops) { 162 if (!new_crypt->ops) {
189 request_module("ieee80211_crypt_wep"); 163 request_module("lib80211_crypt_wep");
190 new_crypt->ops = ieee80211_get_crypto_ops("WEP"); 164 new_crypt->ops = lib80211_get_crypto_ops("WEP");
191 } 165 }
192 if (new_crypt->ops) 166 if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
193 new_crypt->priv = new_crypt->ops->init(i); 167 new_crypt->priv = new_crypt->ops->init(i);
194 if (!new_crypt->ops || !new_crypt->priv) { 168 if (!new_crypt->ops || !new_crypt->priv) {
195 kfree(new_crypt); 169 kfree(new_crypt);
@@ -210,16 +184,16 @@ static int prism2_ioctl_siwencode(struct net_device *dev,
210 memset(keybuf + erq->length, 0, len - erq->length); 184 memset(keybuf + erq->length, 0, len - erq->length);
211 (*crypt)->ops->set_key(keybuf, len, NULL, (*crypt)->priv); 185 (*crypt)->ops->set_key(keybuf, len, NULL, (*crypt)->priv);
212 for (j = 0; j < WEP_KEYS; j++) { 186 for (j = 0; j < WEP_KEYS; j++) {
213 if (j != i && local->crypt[j]) { 187 if (j != i && local->crypt_info.crypt[j]) {
214 first = 0; 188 first = 0;
215 break; 189 break;
216 } 190 }
217 } 191 }
218 if (first) 192 if (first)
219 local->tx_keyidx = i; 193 local->crypt_info.tx_keyidx = i;
220 } else { 194 } else {
221 /* No key data - just set the default TX key index */ 195 /* No key data - just set the default TX key index */
222 local->tx_keyidx = i; 196 local->crypt_info.tx_keyidx = i;
223 } 197 }
224 198
225 done: 199 done:
@@ -252,20 +226,20 @@ static int prism2_ioctl_giwencode(struct net_device *dev,
252 local_info_t *local; 226 local_info_t *local;
253 int i, len; 227 int i, len;
254 u16 val; 228 u16 val;
255 struct ieee80211_crypt_data *crypt; 229 struct lib80211_crypt_data *crypt;
256 230
257 iface = netdev_priv(dev); 231 iface = netdev_priv(dev);
258 local = iface->local; 232 local = iface->local;
259 233
260 i = erq->flags & IW_ENCODE_INDEX; 234 i = erq->flags & IW_ENCODE_INDEX;
261 if (i < 1 || i > 4) 235 if (i < 1 || i > 4)
262 i = local->tx_keyidx; 236 i = local->crypt_info.tx_keyidx;
263 else 237 else
264 i--; 238 i--;
265 if (i < 0 || i >= WEP_KEYS) 239 if (i < 0 || i >= WEP_KEYS)
266 return -EINVAL; 240 return -EINVAL;
267 241
268 crypt = local->crypt[i]; 242 crypt = local->crypt_info.crypt[i];
269 erq->flags = i + 1; 243 erq->flags = i + 1;
270 244
271 if (crypt == NULL || crypt->ops == NULL) { 245 if (crypt == NULL || crypt->ops == NULL) {
@@ -3227,8 +3201,8 @@ static int prism2_ioctl_siwencodeext(struct net_device *dev,
3227 local_info_t *local = iface->local; 3201 local_info_t *local = iface->local;
3228 struct iw_encode_ext *ext = (struct iw_encode_ext *) extra; 3202 struct iw_encode_ext *ext = (struct iw_encode_ext *) extra;
3229 int i, ret = 0; 3203 int i, ret = 0;
3230 struct ieee80211_crypto_ops *ops; 3204 struct lib80211_crypto_ops *ops;
3231 struct ieee80211_crypt_data **crypt; 3205 struct lib80211_crypt_data **crypt;
3232 void *sta_ptr; 3206 void *sta_ptr;
3233 u8 *addr; 3207 u8 *addr;
3234 const char *alg, *module; 3208 const char *alg, *module;
@@ -3237,7 +3211,7 @@ static int prism2_ioctl_siwencodeext(struct net_device *dev,
3237 if (i > WEP_KEYS) 3211 if (i > WEP_KEYS)
3238 return -EINVAL; 3212 return -EINVAL;
3239 if (i < 1 || i > WEP_KEYS) 3213 if (i < 1 || i > WEP_KEYS)
3240 i = local->tx_keyidx; 3214 i = local->crypt_info.tx_keyidx;
3241 else 3215 else
3242 i--; 3216 i--;
3243 if (i < 0 || i >= WEP_KEYS) 3217 if (i < 0 || i >= WEP_KEYS)
@@ -3247,7 +3221,7 @@ static int prism2_ioctl_siwencodeext(struct net_device *dev,
3247 if (addr[0] == 0xff && addr[1] == 0xff && addr[2] == 0xff && 3221 if (addr[0] == 0xff && addr[1] == 0xff && addr[2] == 0xff &&
3248 addr[3] == 0xff && addr[4] == 0xff && addr[5] == 0xff) { 3222 addr[3] == 0xff && addr[4] == 0xff && addr[5] == 0xff) {
3249 sta_ptr = NULL; 3223 sta_ptr = NULL;
3250 crypt = &local->crypt[i]; 3224 crypt = &local->crypt_info.crypt[i];
3251 } else { 3225 } else {
3252 if (i != 0) 3226 if (i != 0)
3253 return -EINVAL; 3227 return -EINVAL;
@@ -3260,7 +3234,7 @@ static int prism2_ioctl_siwencodeext(struct net_device *dev,
3260 * is emulated by using default key idx 0. 3234 * is emulated by using default key idx 0.
3261 */ 3235 */
3262 i = 0; 3236 i = 0;
3263 crypt = &local->crypt[i]; 3237 crypt = &local->crypt_info.crypt[i];
3264 } else 3238 } else
3265 return -EINVAL; 3239 return -EINVAL;
3266 } 3240 }
@@ -3269,22 +3243,22 @@ static int prism2_ioctl_siwencodeext(struct net_device *dev,
3269 if ((erq->flags & IW_ENCODE_DISABLED) || 3243 if ((erq->flags & IW_ENCODE_DISABLED) ||
3270 ext->alg == IW_ENCODE_ALG_NONE) { 3244 ext->alg == IW_ENCODE_ALG_NONE) {
3271 if (*crypt) 3245 if (*crypt)
3272 prism2_crypt_delayed_deinit(local, crypt); 3246 lib80211_crypt_delayed_deinit(&local->crypt_info, crypt);
3273 goto done; 3247 goto done;
3274 } 3248 }
3275 3249
3276 switch (ext->alg) { 3250 switch (ext->alg) {
3277 case IW_ENCODE_ALG_WEP: 3251 case IW_ENCODE_ALG_WEP:
3278 alg = "WEP"; 3252 alg = "WEP";
3279 module = "ieee80211_crypt_wep"; 3253 module = "lib80211_crypt_wep";
3280 break; 3254 break;
3281 case IW_ENCODE_ALG_TKIP: 3255 case IW_ENCODE_ALG_TKIP:
3282 alg = "TKIP"; 3256 alg = "TKIP";
3283 module = "ieee80211_crypt_tkip"; 3257 module = "lib80211_crypt_tkip";
3284 break; 3258 break;
3285 case IW_ENCODE_ALG_CCMP: 3259 case IW_ENCODE_ALG_CCMP:
3286 alg = "CCMP"; 3260 alg = "CCMP";
3287 module = "ieee80211_crypt_ccmp"; 3261 module = "lib80211_crypt_ccmp";
3288 break; 3262 break;
3289 default: 3263 default:
3290 printk(KERN_DEBUG "%s: unsupported algorithm %d\n", 3264 printk(KERN_DEBUG "%s: unsupported algorithm %d\n",
@@ -3293,10 +3267,10 @@ static int prism2_ioctl_siwencodeext(struct net_device *dev,
3293 goto done; 3267 goto done;
3294 } 3268 }
3295 3269
3296 ops = ieee80211_get_crypto_ops(alg); 3270 ops = lib80211_get_crypto_ops(alg);
3297 if (ops == NULL) { 3271 if (ops == NULL) {
3298 request_module(module); 3272 request_module(module);
3299 ops = ieee80211_get_crypto_ops(alg); 3273 ops = lib80211_get_crypto_ops(alg);
3300 } 3274 }
3301 if (ops == NULL) { 3275 if (ops == NULL) {
3302 printk(KERN_DEBUG "%s: unknown crypto alg '%s'\n", 3276 printk(KERN_DEBUG "%s: unknown crypto alg '%s'\n",
@@ -3315,18 +3289,19 @@ static int prism2_ioctl_siwencodeext(struct net_device *dev,
3315 } 3289 }
3316 3290
3317 if (*crypt == NULL || (*crypt)->ops != ops) { 3291 if (*crypt == NULL || (*crypt)->ops != ops) {
3318 struct ieee80211_crypt_data *new_crypt; 3292 struct lib80211_crypt_data *new_crypt;
3319 3293
3320 prism2_crypt_delayed_deinit(local, crypt); 3294 lib80211_crypt_delayed_deinit(&local->crypt_info, crypt);
3321 3295
3322 new_crypt = kzalloc(sizeof(struct ieee80211_crypt_data), 3296 new_crypt = kzalloc(sizeof(struct lib80211_crypt_data),
3323 GFP_KERNEL); 3297 GFP_KERNEL);
3324 if (new_crypt == NULL) { 3298 if (new_crypt == NULL) {
3325 ret = -ENOMEM; 3299 ret = -ENOMEM;
3326 goto done; 3300 goto done;
3327 } 3301 }
3328 new_crypt->ops = ops; 3302 new_crypt->ops = ops;
3329 new_crypt->priv = new_crypt->ops->init(i); 3303 if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
3304 new_crypt->priv = new_crypt->ops->init(i);
3330 if (new_crypt->priv == NULL) { 3305 if (new_crypt->priv == NULL) {
3331 kfree(new_crypt); 3306 kfree(new_crypt);
3332 ret = -EINVAL; 3307 ret = -EINVAL;
@@ -3354,20 +3329,20 @@ static int prism2_ioctl_siwencodeext(struct net_device *dev,
3354 3329
3355 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) { 3330 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
3356 if (!sta_ptr) 3331 if (!sta_ptr)
3357 local->tx_keyidx = i; 3332 local->crypt_info.tx_keyidx = i;
3358 } 3333 }
3359 3334
3360 3335
3361 if (sta_ptr == NULL && ext->key_len > 0) { 3336 if (sta_ptr == NULL && ext->key_len > 0) {
3362 int first = 1, j; 3337 int first = 1, j;
3363 for (j = 0; j < WEP_KEYS; j++) { 3338 for (j = 0; j < WEP_KEYS; j++) {
3364 if (j != i && local->crypt[j]) { 3339 if (j != i && local->crypt_info.crypt[j]) {
3365 first = 0; 3340 first = 0;
3366 break; 3341 break;
3367 } 3342 }
3368 } 3343 }
3369 if (first) 3344 if (first)
3370 local->tx_keyidx = i; 3345 local->crypt_info.tx_keyidx = i;
3371 } 3346 }
3372 3347
3373 done: 3348 done:
@@ -3399,7 +3374,7 @@ static int prism2_ioctl_giwencodeext(struct net_device *dev,
3399{ 3374{
3400 struct hostap_interface *iface = netdev_priv(dev); 3375 struct hostap_interface *iface = netdev_priv(dev);
3401 local_info_t *local = iface->local; 3376 local_info_t *local = iface->local;
3402 struct ieee80211_crypt_data **crypt; 3377 struct lib80211_crypt_data **crypt;
3403 void *sta_ptr; 3378 void *sta_ptr;
3404 int max_key_len, i; 3379 int max_key_len, i;
3405 struct iw_encode_ext *ext = (struct iw_encode_ext *) extra; 3380 struct iw_encode_ext *ext = (struct iw_encode_ext *) extra;
@@ -3411,7 +3386,7 @@ static int prism2_ioctl_giwencodeext(struct net_device *dev,
3411 3386
3412 i = erq->flags & IW_ENCODE_INDEX; 3387 i = erq->flags & IW_ENCODE_INDEX;
3413 if (i < 1 || i > WEP_KEYS) 3388 if (i < 1 || i > WEP_KEYS)
3414 i = local->tx_keyidx; 3389 i = local->crypt_info.tx_keyidx;
3415 else 3390 else
3416 i--; 3391 i--;
3417 3392
@@ -3419,7 +3394,7 @@ static int prism2_ioctl_giwencodeext(struct net_device *dev,
3419 if (addr[0] == 0xff && addr[1] == 0xff && addr[2] == 0xff && 3394 if (addr[0] == 0xff && addr[1] == 0xff && addr[2] == 0xff &&
3420 addr[3] == 0xff && addr[4] == 0xff && addr[5] == 0xff) { 3395 addr[3] == 0xff && addr[4] == 0xff && addr[5] == 0xff) {
3421 sta_ptr = NULL; 3396 sta_ptr = NULL;
3422 crypt = &local->crypt[i]; 3397 crypt = &local->crypt_info.crypt[i];
3423 } else { 3398 } else {
3424 i = 0; 3399 i = 0;
3425 sta_ptr = ap_crypt_get_ptrs(local->ap, addr, 0, &crypt); 3400 sta_ptr = ap_crypt_get_ptrs(local->ap, addr, 0, &crypt);
@@ -3468,8 +3443,8 @@ static int prism2_ioctl_set_encryption(local_info_t *local,
3468 int param_len) 3443 int param_len)
3469{ 3444{
3470 int ret = 0; 3445 int ret = 0;
3471 struct ieee80211_crypto_ops *ops; 3446 struct lib80211_crypto_ops *ops;
3472 struct ieee80211_crypt_data **crypt; 3447 struct lib80211_crypt_data **crypt;
3473 void *sta_ptr; 3448 void *sta_ptr;
3474 3449
3475 param->u.crypt.err = 0; 3450 param->u.crypt.err = 0;
@@ -3486,7 +3461,7 @@ static int prism2_ioctl_set_encryption(local_info_t *local,
3486 if (param->u.crypt.idx >= WEP_KEYS) 3461 if (param->u.crypt.idx >= WEP_KEYS)
3487 return -EINVAL; 3462 return -EINVAL;
3488 sta_ptr = NULL; 3463 sta_ptr = NULL;
3489 crypt = &local->crypt[param->u.crypt.idx]; 3464 crypt = &local->crypt_info.crypt[param->u.crypt.idx];
3490 } else { 3465 } else {
3491 if (param->u.crypt.idx) 3466 if (param->u.crypt.idx)
3492 return -EINVAL; 3467 return -EINVAL;
@@ -3503,20 +3478,20 @@ static int prism2_ioctl_set_encryption(local_info_t *local,
3503 3478
3504 if (strcmp(param->u.crypt.alg, "none") == 0) { 3479 if (strcmp(param->u.crypt.alg, "none") == 0) {
3505 if (crypt) 3480 if (crypt)
3506 prism2_crypt_delayed_deinit(local, crypt); 3481 lib80211_crypt_delayed_deinit(&local->crypt_info, crypt);
3507 goto done; 3482 goto done;
3508 } 3483 }
3509 3484
3510 ops = ieee80211_get_crypto_ops(param->u.crypt.alg); 3485 ops = lib80211_get_crypto_ops(param->u.crypt.alg);
3511 if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) { 3486 if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) {
3512 request_module("ieee80211_crypt_wep"); 3487 request_module("lib80211_crypt_wep");
3513 ops = ieee80211_get_crypto_ops(param->u.crypt.alg); 3488 ops = lib80211_get_crypto_ops(param->u.crypt.alg);
3514 } else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) { 3489 } else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) {
3515 request_module("ieee80211_crypt_tkip"); 3490 request_module("lib80211_crypt_tkip");
3516 ops = ieee80211_get_crypto_ops(param->u.crypt.alg); 3491 ops = lib80211_get_crypto_ops(param->u.crypt.alg);
3517 } else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) { 3492 } else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) {
3518 request_module("ieee80211_crypt_ccmp"); 3493 request_module("lib80211_crypt_ccmp");
3519 ops = ieee80211_get_crypto_ops(param->u.crypt.alg); 3494 ops = lib80211_get_crypto_ops(param->u.crypt.alg);
3520 } 3495 }
3521 if (ops == NULL) { 3496 if (ops == NULL) {
3522 printk(KERN_DEBUG "%s: unknown crypto alg '%s'\n", 3497 printk(KERN_DEBUG "%s: unknown crypto alg '%s'\n",
@@ -3531,11 +3506,11 @@ static int prism2_ioctl_set_encryption(local_info_t *local,
3531 local->host_decrypt = local->host_encrypt = 1; 3506 local->host_decrypt = local->host_encrypt = 1;
3532 3507
3533 if (*crypt == NULL || (*crypt)->ops != ops) { 3508 if (*crypt == NULL || (*crypt)->ops != ops) {
3534 struct ieee80211_crypt_data *new_crypt; 3509 struct lib80211_crypt_data *new_crypt;
3535 3510
3536 prism2_crypt_delayed_deinit(local, crypt); 3511 lib80211_crypt_delayed_deinit(&local->crypt_info, crypt);
3537 3512
3538 new_crypt = kzalloc(sizeof(struct ieee80211_crypt_data), 3513 new_crypt = kzalloc(sizeof(struct lib80211_crypt_data),
3539 GFP_KERNEL); 3514 GFP_KERNEL);
3540 if (new_crypt == NULL) { 3515 if (new_crypt == NULL) {
3541 ret = -ENOMEM; 3516 ret = -ENOMEM;
@@ -3568,7 +3543,7 @@ static int prism2_ioctl_set_encryption(local_info_t *local,
3568 3543
3569 if (param->u.crypt.flags & HOSTAP_CRYPT_FLAG_SET_TX_KEY) { 3544 if (param->u.crypt.flags & HOSTAP_CRYPT_FLAG_SET_TX_KEY) {
3570 if (!sta_ptr) 3545 if (!sta_ptr)
3571 local->tx_keyidx = param->u.crypt.idx; 3546 local->crypt_info.tx_keyidx = param->u.crypt.idx;
3572 else if (param->u.crypt.idx) { 3547 else if (param->u.crypt.idx) {
3573 printk(KERN_DEBUG "%s: TX key idx setting failed\n", 3548 printk(KERN_DEBUG "%s: TX key idx setting failed\n",
3574 local->dev->name); 3549 local->dev->name);
@@ -3604,7 +3579,7 @@ static int prism2_ioctl_get_encryption(local_info_t *local,
3604 struct prism2_hostapd_param *param, 3579 struct prism2_hostapd_param *param,
3605 int param_len) 3580 int param_len)
3606{ 3581{
3607 struct ieee80211_crypt_data **crypt; 3582 struct lib80211_crypt_data **crypt;
3608 void *sta_ptr; 3583 void *sta_ptr;
3609 int max_key_len; 3584 int max_key_len;
3610 3585
@@ -3620,8 +3595,8 @@ static int prism2_ioctl_get_encryption(local_info_t *local,
3620 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) { 3595 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
3621 sta_ptr = NULL; 3596 sta_ptr = NULL;
3622 if (param->u.crypt.idx >= WEP_KEYS) 3597 if (param->u.crypt.idx >= WEP_KEYS)
3623 param->u.crypt.idx = local->tx_keyidx; 3598 param->u.crypt.idx = local->crypt_info.tx_keyidx;
3624 crypt = &local->crypt[param->u.crypt.idx]; 3599 crypt = &local->crypt_info.crypt[param->u.crypt.idx];
3625 } else { 3600 } else {
3626 param->u.crypt.idx = 0; 3601 param->u.crypt.idx = 0;
3627 sta_ptr = ap_crypt_get_ptrs(local->ap, param->sta_addr, 0, 3602 sta_ptr = ap_crypt_get_ptrs(local->ap, param->sta_addr, 0,
diff --git a/drivers/net/wireless/hostap/hostap_main.c b/drivers/net/wireless/hostap/hostap_main.c
index 4c36eb2fafd1..02a312ca8607 100644
--- a/drivers/net/wireless/hostap/hostap_main.c
+++ b/drivers/net/wireless/hostap/hostap_main.c
@@ -27,7 +27,7 @@
27#include <net/net_namespace.h> 27#include <net/net_namespace.h>
28#include <net/iw_handler.h> 28#include <net/iw_handler.h>
29#include <net/ieee80211.h> 29#include <net/ieee80211.h>
30#include <net/ieee80211_crypt.h> 30#include <net/lib80211.h>
31#include <asm/uaccess.h> 31#include <asm/uaccess.h>
32 32
33#include "hostap_wlan.h" 33#include "hostap_wlan.h"
@@ -343,10 +343,11 @@ int hostap_set_encryption(local_info_t *local)
343 char keybuf[WEP_KEY_LEN + 1]; 343 char keybuf[WEP_KEY_LEN + 1];
344 enum { NONE, WEP, OTHER } encrypt_type; 344 enum { NONE, WEP, OTHER } encrypt_type;
345 345
346 idx = local->tx_keyidx; 346 idx = local->crypt_info.tx_keyidx;
347 if (local->crypt[idx] == NULL || local->crypt[idx]->ops == NULL) 347 if (local->crypt_info.crypt[idx] == NULL ||
348 local->crypt_info.crypt[idx]->ops == NULL)
348 encrypt_type = NONE; 349 encrypt_type = NONE;
349 else if (strcmp(local->crypt[idx]->ops->name, "WEP") == 0) 350 else if (strcmp(local->crypt_info.crypt[idx]->ops->name, "WEP") == 0)
350 encrypt_type = WEP; 351 encrypt_type = WEP;
351 else 352 else
352 encrypt_type = OTHER; 353 encrypt_type = OTHER;
@@ -394,17 +395,17 @@ int hostap_set_encryption(local_info_t *local)
394 /* 104-bit support seems to require that all the keys are set to the 395 /* 104-bit support seems to require that all the keys are set to the
395 * same keylen */ 396 * same keylen */
396 keylen = 6; /* first 5 octets */ 397 keylen = 6; /* first 5 octets */
397 len = local->crypt[idx]->ops->get_key(keybuf, sizeof(keybuf), 398 len = local->crypt_info.crypt[idx]->ops->get_key(keybuf, sizeof(keybuf), NULL,
398 NULL, local->crypt[idx]->priv); 399 local->crypt_info.crypt[idx]->priv);
399 if (idx >= 0 && idx < WEP_KEYS && len > 5) 400 if (idx >= 0 && idx < WEP_KEYS && len > 5)
400 keylen = WEP_KEY_LEN + 1; /* first 13 octets */ 401 keylen = WEP_KEY_LEN + 1; /* first 13 octets */
401 402
402 for (i = 0; i < WEP_KEYS; i++) { 403 for (i = 0; i < WEP_KEYS; i++) {
403 memset(keybuf, 0, sizeof(keybuf)); 404 memset(keybuf, 0, sizeof(keybuf));
404 if (local->crypt[i]) { 405 if (local->crypt_info.crypt[i]) {
405 (void) local->crypt[i]->ops->get_key( 406 (void) local->crypt_info.crypt[i]->ops->get_key(
406 keybuf, sizeof(keybuf), 407 keybuf, sizeof(keybuf),
407 NULL, local->crypt[i]->priv); 408 NULL, local->crypt_info.crypt[i]->priv);
408 } 409 }
409 if (local->func->set_rid(local->dev, 410 if (local->func->set_rid(local->dev,
410 HFA384X_RID_CNFDEFAULTKEY0 + i, 411 HFA384X_RID_CNFDEFAULTKEY0 + i,
diff --git a/drivers/net/wireless/hostap/hostap_proc.c b/drivers/net/wireless/hostap/hostap_proc.c
index ae7d3caf3dae..005ff25a405f 100644
--- a/drivers/net/wireless/hostap/hostap_proc.c
+++ b/drivers/net/wireless/hostap/hostap_proc.c
@@ -2,7 +2,7 @@
2 2
3#include <linux/types.h> 3#include <linux/types.h>
4#include <linux/proc_fs.h> 4#include <linux/proc_fs.h>
5#include <net/ieee80211_crypt.h> 5#include <net/lib80211.h>
6 6
7#include "hostap_wlan.h" 7#include "hostap_wlan.h"
8#include "hostap.h" 8#include "hostap.h"
@@ -36,9 +36,10 @@ static int prism2_debug_proc_read(char *page, char **start, off_t off,
36 p += sprintf(p, "dev_enabled=%d\n", local->dev_enabled); 36 p += sprintf(p, "dev_enabled=%d\n", local->dev_enabled);
37 p += sprintf(p, "sw_tick_stuck=%d\n", local->sw_tick_stuck); 37 p += sprintf(p, "sw_tick_stuck=%d\n", local->sw_tick_stuck);
38 for (i = 0; i < WEP_KEYS; i++) { 38 for (i = 0; i < WEP_KEYS; i++) {
39 if (local->crypt[i] && local->crypt[i]->ops) { 39 if (local->crypt_info.crypt[i] &&
40 p += sprintf(p, "crypt[%d]=%s\n", 40 local->crypt_info.crypt[i]->ops) {
41 i, local->crypt[i]->ops->name); 41 p += sprintf(p, "crypt[%d]=%s\n", i,
42 local->crypt_info.crypt[i]->ops->name);
42 } 43 }
43 } 44 }
44 p += sprintf(p, "pri_only=%d\n", local->pri_only); 45 p += sprintf(p, "pri_only=%d\n", local->pri_only);
@@ -206,12 +207,13 @@ static int prism2_crypt_proc_read(char *page, char **start, off_t off,
206 return 0; 207 return 0;
207 } 208 }
208 209
209 p += sprintf(p, "tx_keyidx=%d\n", local->tx_keyidx); 210 p += sprintf(p, "tx_keyidx=%d\n", local->crypt_info.tx_keyidx);
210 for (i = 0; i < WEP_KEYS; i++) { 211 for (i = 0; i < WEP_KEYS; i++) {
211 if (local->crypt[i] && local->crypt[i]->ops && 212 if (local->crypt_info.crypt[i] &&
212 local->crypt[i]->ops->print_stats) { 213 local->crypt_info.crypt[i]->ops &&
213 p = local->crypt[i]->ops->print_stats( 214 local->crypt_info.crypt[i]->ops->print_stats) {
214 p, local->crypt[i]->priv); 215 p = local->crypt_info.crypt[i]->ops->print_stats(
216 p, local->crypt_info.crypt[i]->priv);
215 } 217 }
216 } 218 }
217 219
diff --git a/drivers/net/wireless/hostap/hostap_wlan.h b/drivers/net/wireless/hostap/hostap_wlan.h
index d2c7a56b8b59..4d8d51a353cd 100644
--- a/drivers/net/wireless/hostap/hostap_wlan.h
+++ b/drivers/net/wireless/hostap/hostap_wlan.h
@@ -6,6 +6,7 @@
6#include <linux/mutex.h> 6#include <linux/mutex.h>
7#include <net/iw_handler.h> 7#include <net/iw_handler.h>
8#include <net/ieee80211_radiotap.h> 8#include <net/ieee80211_radiotap.h>
9#include <net/lib80211.h>
9 10
10#include "hostap_config.h" 11#include "hostap_config.h"
11#include "hostap_common.h" 12#include "hostap_common.h"
@@ -763,10 +764,7 @@ struct local_info {
763 764
764#define WEP_KEYS 4 765#define WEP_KEYS 4
765#define WEP_KEY_LEN 13 766#define WEP_KEY_LEN 13
766 struct ieee80211_crypt_data *crypt[WEP_KEYS]; 767 struct lib80211_crypt_info crypt_info;
767 int tx_keyidx; /* default TX key index (crypt[tx_keyidx]) */
768 struct timer_list crypt_deinit_timer;
769 struct list_head crypt_deinit_list;
770 768
771 int open_wep; /* allow unencrypted frames */ 769 int open_wep; /* allow unencrypted frames */
772 int host_encrypt; 770 int host_encrypt;
diff --git a/drivers/net/wireless/ipw2x00/Kconfig b/drivers/net/wireless/ipw2x00/Kconfig
new file mode 100644
index 000000000000..3d5cc4463d4d
--- /dev/null
+++ b/drivers/net/wireless/ipw2x00/Kconfig
@@ -0,0 +1,191 @@
1#
2# Intel Centrino wireless drivers
3#
4
5config IPW2100
6 tristate "Intel PRO/Wireless 2100 Network Connection"
7 depends on PCI && WLAN_80211
8 select WIRELESS_EXT
9 select FW_LOADER
10 select LIB80211
11 select LIBIPW
12 ---help---
13 A driver for the Intel PRO/Wireless 2100 Network
14 Connection 802.11b wireless network adapter.
15
16 See <file:Documentation/networking/README.ipw2100> for information on
17 the capabilities currently enabled in this driver and for tips
18 for debugging issues and problems.
19
20 In order to use this driver, you will need a firmware image for it.
21 You can obtain the firmware from
22 <http://ipw2100.sf.net/>. Once you have the firmware image, you
23 will need to place it in /lib/firmware.
24
25 You will also very likely need the Wireless Tools in order to
26 configure your card:
27
28 <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>.
29
30 It is recommended that you compile this driver as a module (M)
31 rather than built-in (Y). This driver requires firmware at device
32 initialization time, and when built-in this typically happens
33 before the filesystem is accessible (hence firmware will be
34 unavailable and initialization will fail). If you do choose to build
35 this driver into your kernel image, you can avoid this problem by
36 including the firmware and a firmware loader in an initramfs.
37
38config IPW2100_MONITOR
39 bool "Enable promiscuous mode"
40 depends on IPW2100
41 ---help---
42 Enables promiscuous/monitor mode support for the ipw2100 driver.
43 With this feature compiled into the driver, you can switch to
44 promiscuous mode via the Wireless Tool's Monitor mode. While in this
45 mode, no packets can be sent.
46
47config IPW2100_DEBUG
48 bool "Enable full debugging output in IPW2100 module."
49 depends on IPW2100
50 ---help---
51 This option will enable debug tracing output for the IPW2100.
52
53 This will result in the kernel module being ~60k larger. You can
54 control which debug output is sent to the kernel log by setting the
55 value in
56
57 /sys/bus/pci/drivers/ipw2100/debug_level
58
59 This entry will only exist if this option is enabled.
60
61 If you are not trying to debug or develop the IPW2100 driver, you
62 most likely want to say N here.
63
64config IPW2200
65 tristate "Intel PRO/Wireless 2200BG and 2915ABG Network Connection"
66 depends on PCI && WLAN_80211
67 select WIRELESS_EXT
68 select FW_LOADER
69 select LIB80211
70 select LIBIPW
71 ---help---
72 A driver for the Intel PRO/Wireless 2200BG and 2915ABG Network
73 Connection adapters.
74
75 See <file:Documentation/networking/README.ipw2200> for
76 information on the capabilities currently enabled in this
77 driver and for tips for debugging issues and problems.
78
79 In order to use this driver, you will need a firmware image for it.
80 You can obtain the firmware from
81 <http://ipw2200.sf.net/>. See the above referenced README.ipw2200
82 for information on where to install the firmware images.
83
84 You will also very likely need the Wireless Tools in order to
85 configure your card:
86
87 <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>.
88
89 It is recommended that you compile this driver as a module (M)
90 rather than built-in (Y). This driver requires firmware at device
91 initialization time, and when built-in this typically happens
92 before the filesystem is accessible (hence firmware will be
93 unavailable and initialization will fail). If you do choose to build
94 this driver into your kernel image, you can avoid this problem by
95 including the firmware and a firmware loader in an initramfs.
96
97config IPW2200_MONITOR
98 bool "Enable promiscuous mode"
99 depends on IPW2200
100 ---help---
101 Enables promiscuous/monitor mode support for the ipw2200 driver.
102 With this feature compiled into the driver, you can switch to
103 promiscuous mode via the Wireless Tool's Monitor mode. While in this
104 mode, no packets can be sent.
105
106config IPW2200_RADIOTAP
107 bool "Enable radiotap format 802.11 raw packet support"
108 depends on IPW2200_MONITOR
109
110config IPW2200_PROMISCUOUS
111 bool "Enable creation of a RF radiotap promiscuous interface"
112 depends on IPW2200_MONITOR
113 select IPW2200_RADIOTAP
114 ---help---
115 Enables the creation of a second interface prefixed 'rtap'.
116 This second interface will provide every received in radiotap
117 format.
118
119 This is useful for performing wireless network analysis while
120 maintaining an active association.
121
122 Example usage:
123
124 % modprobe ipw2200 rtap_iface=1
125 % ifconfig rtap0 up
126 % tethereal -i rtap0
127
128 If you do not specify 'rtap_iface=1' as a module parameter then
129 the rtap interface will not be created and you will need to turn
130 it on via sysfs:
131
132 % echo 1 > /sys/bus/pci/drivers/ipw2200/*/rtap_iface
133
134config IPW2200_QOS
135 bool "Enable QoS support"
136 depends on IPW2200 && EXPERIMENTAL
137
138config IPW2200_DEBUG
139 bool "Enable full debugging output in IPW2200 module."
140 depends on IPW2200
141 ---help---
142 This option will enable low level debug tracing output for IPW2200.
143
144 Note, normal debug code is already compiled in. This low level
145 debug option enables debug on hot paths (e.g Tx, Rx, ISR) and
146 will result in the kernel module being ~70 larger. Most users
147 will typically not need this high verbosity debug information.
148
149 If you are not sure, say N here.
150
151config LIBIPW
152 tristate
153 select WIRELESS_EXT
154 select CRYPTO
155 select CRYPTO_ARC4
156 select CRYPTO_ECB
157 select CRYPTO_AES
158 select CRYPTO_MICHAEL_MIC
159 select CRYPTO_ECB
160 select CRC32
161 select LIB80211
162 select LIB80211_CRYPT_WEP
163 select LIB80211_CRYPT_TKIP
164 select LIB80211_CRYPT_CCMP
165 ---help---
166 This option enables the hardware independent IEEE 802.11
167 networking stack. This component is deprecated in favor of the
168 mac80211 component.
169
170config LIBIPW_DEBUG
171 bool "Full debugging output for the LIBIPW component"
172 depends on LIBIPW
173 ---help---
174 This option will enable debug tracing output for the
175 libipw component.
176
177 This will result in the kernel module being ~70k larger. You
178 can control which debug output is sent to the kernel log by
179 setting the value in
180
181 /proc/net/ieee80211/debug_level
182
183 For example:
184
185 % echo 0x00000FFO > /proc/net/ieee80211/debug_level
186
187 For a list of values you can assign to debug_level, you
188 can look at the bit mask values in <net/ieee80211.h>
189
190 If you are not trying to debug or develop the libipw
191 component, you most likely want to say N here.
diff --git a/drivers/net/wireless/ipw2x00/Makefile b/drivers/net/wireless/ipw2x00/Makefile
new file mode 100644
index 000000000000..aecd2cff462b
--- /dev/null
+++ b/drivers/net/wireless/ipw2x00/Makefile
@@ -0,0 +1,14 @@
1#
2# Makefile for the Intel Centrino wireless drivers
3#
4
5obj-$(CONFIG_IPW2100) += ipw2100.o
6obj-$(CONFIG_IPW2200) += ipw2200.o
7
8obj-$(CONFIG_LIBIPW) += libipw.o
9libipw-objs := \
10 libipw_module.o \
11 libipw_tx.o \
12 libipw_rx.o \
13 libipw_wx.o \
14 libipw_geo.o
diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c
index 062c9f280304..2d2044d3d1c9 100644
--- a/drivers/net/wireless/ipw2100.c
+++ b/drivers/net/wireless/ipw2x00/ipw2100.c
@@ -4010,7 +4010,7 @@ static ssize_t show_internals(struct device *d, struct device_attribute *attr,
4010 else 4010 else
4011 len += sprintf(buf + len, "not connected\n"); 4011 len += sprintf(buf + len, "not connected\n");
4012 4012
4013 DUMP_VAR(ieee->crypt[priv->ieee->tx_keyidx], "p"); 4013 DUMP_VAR(ieee->crypt_info.crypt[priv->ieee->crypt_info.tx_keyidx], "p");
4014 DUMP_VAR(status, "08lx"); 4014 DUMP_VAR(status, "08lx");
4015 DUMP_VAR(config, "08lx"); 4015 DUMP_VAR(config, "08lx");
4016 DUMP_VAR(capability, "08lx"); 4016 DUMP_VAR(capability, "08lx");
@@ -5514,7 +5514,7 @@ static int ipw2100_configure_security(struct ipw2100_priv *priv, int batch_mode)
5514 } 5514 }
5515 } 5515 }
5516 5516
5517 ipw2100_set_key_index(priv, priv->ieee->tx_keyidx, 1); 5517 ipw2100_set_key_index(priv, priv->ieee->crypt_info.tx_keyidx, 1);
5518 } 5518 }
5519 5519
5520 /* Always enable privacy so the Host can filter WEP packets if 5520 /* Always enable privacy so the Host can filter WEP packets if
@@ -7620,7 +7620,7 @@ static int ipw2100_wx_set_auth(struct net_device *dev,
7620 struct ipw2100_priv *priv = ieee80211_priv(dev); 7620 struct ipw2100_priv *priv = ieee80211_priv(dev);
7621 struct ieee80211_device *ieee = priv->ieee; 7621 struct ieee80211_device *ieee = priv->ieee;
7622 struct iw_param *param = &wrqu->param; 7622 struct iw_param *param = &wrqu->param;
7623 struct ieee80211_crypt_data *crypt; 7623 struct lib80211_crypt_data *crypt;
7624 unsigned long flags; 7624 unsigned long flags;
7625 int ret = 0; 7625 int ret = 0;
7626 7626
@@ -7635,7 +7635,7 @@ static int ipw2100_wx_set_auth(struct net_device *dev,
7635 break; 7635 break;
7636 7636
7637 case IW_AUTH_TKIP_COUNTERMEASURES: 7637 case IW_AUTH_TKIP_COUNTERMEASURES:
7638 crypt = priv->ieee->crypt[priv->ieee->tx_keyidx]; 7638 crypt = priv->ieee->crypt_info.crypt[priv->ieee->crypt_info.tx_keyidx];
7639 if (!crypt || !crypt->ops->set_flags || !crypt->ops->get_flags) 7639 if (!crypt || !crypt->ops->set_flags || !crypt->ops->get_flags)
7640 break; 7640 break;
7641 7641
@@ -7712,7 +7712,7 @@ static int ipw2100_wx_get_auth(struct net_device *dev,
7712{ 7712{
7713 struct ipw2100_priv *priv = ieee80211_priv(dev); 7713 struct ipw2100_priv *priv = ieee80211_priv(dev);
7714 struct ieee80211_device *ieee = priv->ieee; 7714 struct ieee80211_device *ieee = priv->ieee;
7715 struct ieee80211_crypt_data *crypt; 7715 struct lib80211_crypt_data *crypt;
7716 struct iw_param *param = &wrqu->param; 7716 struct iw_param *param = &wrqu->param;
7717 int ret = 0; 7717 int ret = 0;
7718 7718
@@ -7728,7 +7728,7 @@ static int ipw2100_wx_get_auth(struct net_device *dev,
7728 break; 7728 break;
7729 7729
7730 case IW_AUTH_TKIP_COUNTERMEASURES: 7730 case IW_AUTH_TKIP_COUNTERMEASURES:
7731 crypt = priv->ieee->crypt[priv->ieee->tx_keyidx]; 7731 crypt = priv->ieee->crypt_info.crypt[priv->ieee->crypt_info.tx_keyidx];
7732 if (!crypt || !crypt->ops->get_flags) { 7732 if (!crypt || !crypt->ops->get_flags) {
7733 IPW_DEBUG_WARNING("Can't get TKIP countermeasures: " 7733 IPW_DEBUG_WARNING("Can't get TKIP countermeasures: "
7734 "crypt not set!\n"); 7734 "crypt not set!\n");
diff --git a/drivers/net/wireless/ipw2100.h b/drivers/net/wireless/ipw2x00/ipw2100.h
index bbf1ddcafba8..bbf1ddcafba8 100644
--- a/drivers/net/wireless/ipw2100.h
+++ b/drivers/net/wireless/ipw2x00/ipw2100.h
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c
index 051ae92d8b65..d2a2b7586d08 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2x00/ipw2200.c
@@ -6600,7 +6600,7 @@ static int ipw_wx_set_auth(struct net_device *dev,
6600 struct ipw_priv *priv = ieee80211_priv(dev); 6600 struct ipw_priv *priv = ieee80211_priv(dev);
6601 struct ieee80211_device *ieee = priv->ieee; 6601 struct ieee80211_device *ieee = priv->ieee;
6602 struct iw_param *param = &wrqu->param; 6602 struct iw_param *param = &wrqu->param;
6603 struct ieee80211_crypt_data *crypt; 6603 struct lib80211_crypt_data *crypt;
6604 unsigned long flags; 6604 unsigned long flags;
6605 int ret = 0; 6605 int ret = 0;
6606 6606
@@ -6622,7 +6622,7 @@ static int ipw_wx_set_auth(struct net_device *dev,
6622 break; 6622 break;
6623 6623
6624 case IW_AUTH_TKIP_COUNTERMEASURES: 6624 case IW_AUTH_TKIP_COUNTERMEASURES:
6625 crypt = priv->ieee->crypt[priv->ieee->tx_keyidx]; 6625 crypt = priv->ieee->crypt_info.crypt[priv->ieee->crypt_info.tx_keyidx];
6626 if (!crypt || !crypt->ops->set_flags || !crypt->ops->get_flags) 6626 if (!crypt || !crypt->ops->set_flags || !crypt->ops->get_flags)
6627 break; 6627 break;
6628 6628
@@ -6699,7 +6699,7 @@ static int ipw_wx_get_auth(struct net_device *dev,
6699{ 6699{
6700 struct ipw_priv *priv = ieee80211_priv(dev); 6700 struct ipw_priv *priv = ieee80211_priv(dev);
6701 struct ieee80211_device *ieee = priv->ieee; 6701 struct ieee80211_device *ieee = priv->ieee;
6702 struct ieee80211_crypt_data *crypt; 6702 struct lib80211_crypt_data *crypt;
6703 struct iw_param *param = &wrqu->param; 6703 struct iw_param *param = &wrqu->param;
6704 int ret = 0; 6704 int ret = 0;
6705 6705
@@ -6715,7 +6715,7 @@ static int ipw_wx_get_auth(struct net_device *dev,
6715 break; 6715 break;
6716 6716
6717 case IW_AUTH_TKIP_COUNTERMEASURES: 6717 case IW_AUTH_TKIP_COUNTERMEASURES:
6718 crypt = priv->ieee->crypt[priv->ieee->tx_keyidx]; 6718 crypt = priv->ieee->crypt_info.crypt[priv->ieee->crypt_info.tx_keyidx];
6719 if (!crypt || !crypt->ops->get_flags) 6719 if (!crypt || !crypt->ops->get_flags)
6720 break; 6720 break;
6721 6721
@@ -7575,8 +7575,7 @@ static int ipw_associate(void *data)
7575 } 7575 }
7576 7576
7577 if (!(priv->config & CFG_ASSOCIATE) && 7577 if (!(priv->config & CFG_ASSOCIATE) &&
7578 !(priv->config & (CFG_STATIC_ESSID | 7578 !(priv->config & (CFG_STATIC_ESSID | CFG_STATIC_BSSID))) {
7579 CFG_STATIC_CHANNEL | CFG_STATIC_BSSID))) {
7580 IPW_DEBUG_ASSOC("Not attempting association (associate=0)\n"); 7579 IPW_DEBUG_ASSOC("Not attempting association (associate=0)\n");
7581 return 0; 7580 return 0;
7582 } 7581 }
@@ -10252,8 +10251,8 @@ static int ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb,
10252 case SEC_LEVEL_1: 10251 case SEC_LEVEL_1:
10253 tfd->u.data.tfd.tfd_24.mchdr.frame_ctl |= 10252 tfd->u.data.tfd.tfd_24.mchdr.frame_ctl |=
10254 cpu_to_le16(IEEE80211_FCTL_PROTECTED); 10253 cpu_to_le16(IEEE80211_FCTL_PROTECTED);
10255 tfd->u.data.key_index = priv->ieee->tx_keyidx; 10254 tfd->u.data.key_index = priv->ieee->crypt_info.tx_keyidx;
10256 if (priv->ieee->sec.key_sizes[priv->ieee->tx_keyidx] <= 10255 if (priv->ieee->sec.key_sizes[priv->ieee->crypt_info.tx_keyidx] <=
10257 40) 10256 40)
10258 tfd->u.data.key_index |= DCT_WEP_KEY_64Bit; 10257 tfd->u.data.key_index |= DCT_WEP_KEY_64Bit;
10259 else 10258 else
diff --git a/drivers/net/wireless/ipw2200.h b/drivers/net/wireless/ipw2x00/ipw2200.h
index 0a84d52147bd..0a84d52147bd 100644
--- a/drivers/net/wireless/ipw2200.h
+++ b/drivers/net/wireless/ipw2x00/ipw2200.h
diff --git a/drivers/net/wireless/ipw2x00/libipw_geo.c b/drivers/net/wireless/ipw2x00/libipw_geo.c
new file mode 100644
index 000000000000..960ad13f5e9f
--- /dev/null
+++ b/drivers/net/wireless/ipw2x00/libipw_geo.c
@@ -0,0 +1,195 @@
1/******************************************************************************
2
3 Copyright(c) 2005 Intel Corporation. All rights reserved.
4
5 This program is free software; you can redistribute it and/or modify it
6 under the terms of version 2 of the GNU General Public License as
7 published by the Free Software Foundation.
8
9 This program is distributed in the hope that it will be useful, but WITHOUT
10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 more details.
13
14 You should have received a copy of the GNU General Public License along with
15 this program; if not, write to the Free Software Foundation, Inc., 59
16 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18 The full GNU General Public License is included in this distribution in the
19 file called LICENSE.
20
21 Contact Information:
22 James P. Ketrenos <ipw2100-admin@linux.intel.com>
23 Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
24
25******************************************************************************/
26#include <linux/compiler.h>
27#include <linux/errno.h>
28#include <linux/if_arp.h>
29#include <linux/in6.h>
30#include <linux/in.h>
31#include <linux/ip.h>
32#include <linux/kernel.h>
33#include <linux/module.h>
34#include <linux/netdevice.h>
35#include <linux/proc_fs.h>
36#include <linux/skbuff.h>
37#include <linux/slab.h>
38#include <linux/tcp.h>
39#include <linux/types.h>
40#include <linux/wireless.h>
41#include <linux/etherdevice.h>
42#include <asm/uaccess.h>
43
44#include <net/ieee80211.h>
45
46int ieee80211_is_valid_channel(struct ieee80211_device *ieee, u8 channel)
47{
48 int i;
49
50 /* Driver needs to initialize the geography map before using
51 * these helper functions */
52 if (ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0)
53 return 0;
54
55 if (ieee->freq_band & IEEE80211_24GHZ_BAND)
56 for (i = 0; i < ieee->geo.bg_channels; i++)
57 /* NOTE: If G mode is currently supported but
58 * this is a B only channel, we don't see it
59 * as valid. */
60 if ((ieee->geo.bg[i].channel == channel) &&
61 !(ieee->geo.bg[i].flags & IEEE80211_CH_INVALID) &&
62 (!(ieee->mode & IEEE_G) ||
63 !(ieee->geo.bg[i].flags & IEEE80211_CH_B_ONLY)))
64 return IEEE80211_24GHZ_BAND;
65
66 if (ieee->freq_band & IEEE80211_52GHZ_BAND)
67 for (i = 0; i < ieee->geo.a_channels; i++)
68 if ((ieee->geo.a[i].channel == channel) &&
69 !(ieee->geo.a[i].flags & IEEE80211_CH_INVALID))
70 return IEEE80211_52GHZ_BAND;
71
72 return 0;
73}
74
75int ieee80211_channel_to_index(struct ieee80211_device *ieee, u8 channel)
76{
77 int i;
78
79 /* Driver needs to initialize the geography map before using
80 * these helper functions */
81 if (ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0)
82 return -1;
83
84 if (ieee->freq_band & IEEE80211_24GHZ_BAND)
85 for (i = 0; i < ieee->geo.bg_channels; i++)
86 if (ieee->geo.bg[i].channel == channel)
87 return i;
88
89 if (ieee->freq_band & IEEE80211_52GHZ_BAND)
90 for (i = 0; i < ieee->geo.a_channels; i++)
91 if (ieee->geo.a[i].channel == channel)
92 return i;
93
94 return -1;
95}
96
97u32 ieee80211_channel_to_freq(struct ieee80211_device * ieee, u8 channel)
98{
99 const struct ieee80211_channel * ch;
100
101 /* Driver needs to initialize the geography map before using
102 * these helper functions */
103 if (ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0)
104 return 0;
105
106 ch = ieee80211_get_channel(ieee, channel);
107 if (!ch->channel)
108 return 0;
109 return ch->freq;
110}
111
112u8 ieee80211_freq_to_channel(struct ieee80211_device * ieee, u32 freq)
113{
114 int i;
115
116 /* Driver needs to initialize the geography map before using
117 * these helper functions */
118 if (ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0)
119 return 0;
120
121 freq /= 100000;
122
123 if (ieee->freq_band & IEEE80211_24GHZ_BAND)
124 for (i = 0; i < ieee->geo.bg_channels; i++)
125 if (ieee->geo.bg[i].freq == freq)
126 return ieee->geo.bg[i].channel;
127
128 if (ieee->freq_band & IEEE80211_52GHZ_BAND)
129 for (i = 0; i < ieee->geo.a_channels; i++)
130 if (ieee->geo.a[i].freq == freq)
131 return ieee->geo.a[i].channel;
132
133 return 0;
134}
135
136int ieee80211_set_geo(struct ieee80211_device *ieee,
137 const struct ieee80211_geo *geo)
138{
139 memcpy(ieee->geo.name, geo->name, 3);
140 ieee->geo.name[3] = '\0';
141 ieee->geo.bg_channels = geo->bg_channels;
142 ieee->geo.a_channels = geo->a_channels;
143 memcpy(ieee->geo.bg, geo->bg, geo->bg_channels *
144 sizeof(struct ieee80211_channel));
145 memcpy(ieee->geo.a, geo->a, ieee->geo.a_channels *
146 sizeof(struct ieee80211_channel));
147 return 0;
148}
149
150const struct ieee80211_geo *ieee80211_get_geo(struct ieee80211_device *ieee)
151{
152 return &ieee->geo;
153}
154
155u8 ieee80211_get_channel_flags(struct ieee80211_device * ieee, u8 channel)
156{
157 int index = ieee80211_channel_to_index(ieee, channel);
158
159 if (index == -1)
160 return IEEE80211_CH_INVALID;
161
162 if (channel <= IEEE80211_24GHZ_CHANNELS)
163 return ieee->geo.bg[index].flags;
164
165 return ieee->geo.a[index].flags;
166}
167
168static const struct ieee80211_channel bad_channel = {
169 .channel = 0,
170 .flags = IEEE80211_CH_INVALID,
171 .max_power = 0,
172};
173
174const struct ieee80211_channel *ieee80211_get_channel(struct ieee80211_device
175 *ieee, u8 channel)
176{
177 int index = ieee80211_channel_to_index(ieee, channel);
178
179 if (index == -1)
180 return &bad_channel;
181
182 if (channel <= IEEE80211_24GHZ_CHANNELS)
183 return &ieee->geo.bg[index];
184
185 return &ieee->geo.a[index];
186}
187
188EXPORT_SYMBOL(ieee80211_get_channel);
189EXPORT_SYMBOL(ieee80211_get_channel_flags);
190EXPORT_SYMBOL(ieee80211_is_valid_channel);
191EXPORT_SYMBOL(ieee80211_freq_to_channel);
192EXPORT_SYMBOL(ieee80211_channel_to_freq);
193EXPORT_SYMBOL(ieee80211_channel_to_index);
194EXPORT_SYMBOL(ieee80211_set_geo);
195EXPORT_SYMBOL(ieee80211_get_geo);
diff --git a/drivers/net/wireless/ipw2x00/libipw_module.c b/drivers/net/wireless/ipw2x00/libipw_module.c
new file mode 100644
index 000000000000..a2f5616d5b09
--- /dev/null
+++ b/drivers/net/wireless/ipw2x00/libipw_module.c
@@ -0,0 +1,293 @@
1/*******************************************************************************
2
3 Copyright(c) 2004-2005 Intel Corporation. All rights reserved.
4
5 Portions of this file are based on the WEP enablement code provided by the
6 Host AP project hostap-drivers v0.1.3
7 Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
8 <j@w1.fi>
9 Copyright (c) 2002-2003, Jouni Malinen <j@w1.fi>
10
11 This program is free software; you can redistribute it and/or modify it
12 under the terms of version 2 of the GNU General Public License as
13 published by the Free Software Foundation.
14
15 This program is distributed in the hope that it will be useful, but WITHOUT
16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
18 more details.
19
20 You should have received a copy of the GNU General Public License along with
21 this program; if not, write to the Free Software Foundation, Inc., 59
22 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23
24 The full GNU General Public License is included in this distribution in the
25 file called LICENSE.
26
27 Contact Information:
28 James P. Ketrenos <ipw2100-admin@linux.intel.com>
29 Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30
31*******************************************************************************/
32
33#include <linux/compiler.h>
34#include <linux/errno.h>
35#include <linux/if_arp.h>
36#include <linux/in6.h>
37#include <linux/in.h>
38#include <linux/ip.h>
39#include <linux/kernel.h>
40#include <linux/module.h>
41#include <linux/netdevice.h>
42#include <linux/proc_fs.h>
43#include <linux/skbuff.h>
44#include <linux/slab.h>
45#include <linux/tcp.h>
46#include <linux/types.h>
47#include <linux/wireless.h>
48#include <linux/etherdevice.h>
49#include <asm/uaccess.h>
50#include <net/net_namespace.h>
51#include <net/arp.h>
52
53#include <net/ieee80211.h>
54
55#define DRV_DESCRIPTION "802.11 data/management/control stack"
56#define DRV_NAME "ieee80211"
57#define DRV_VERSION IEEE80211_VERSION
58#define DRV_COPYRIGHT "Copyright (C) 2004-2005 Intel Corporation <jketreno@linux.intel.com>"
59
60MODULE_VERSION(DRV_VERSION);
61MODULE_DESCRIPTION(DRV_DESCRIPTION);
62MODULE_AUTHOR(DRV_COPYRIGHT);
63MODULE_LICENSE("GPL");
64
65static int ieee80211_networks_allocate(struct ieee80211_device *ieee)
66{
67 if (ieee->networks)
68 return 0;
69
70 ieee->networks =
71 kzalloc(MAX_NETWORK_COUNT * sizeof(struct ieee80211_network),
72 GFP_KERNEL);
73 if (!ieee->networks) {
74 printk(KERN_WARNING "%s: Out of memory allocating beacons\n",
75 ieee->dev->name);
76 return -ENOMEM;
77 }
78
79 return 0;
80}
81
82void ieee80211_network_reset(struct ieee80211_network *network)
83{
84 if (!network)
85 return;
86
87 if (network->ibss_dfs) {
88 kfree(network->ibss_dfs);
89 network->ibss_dfs = NULL;
90 }
91}
92
93static inline void ieee80211_networks_free(struct ieee80211_device *ieee)
94{
95 int i;
96
97 if (!ieee->networks)
98 return;
99
100 for (i = 0; i < MAX_NETWORK_COUNT; i++)
101 if (ieee->networks[i].ibss_dfs)
102 kfree(ieee->networks[i].ibss_dfs);
103
104 kfree(ieee->networks);
105 ieee->networks = NULL;
106}
107
108static void ieee80211_networks_initialize(struct ieee80211_device *ieee)
109{
110 int i;
111
112 INIT_LIST_HEAD(&ieee->network_free_list);
113 INIT_LIST_HEAD(&ieee->network_list);
114 for (i = 0; i < MAX_NETWORK_COUNT; i++)
115 list_add_tail(&ieee->networks[i].list,
116 &ieee->network_free_list);
117}
118
119static int ieee80211_change_mtu(struct net_device *dev, int new_mtu)
120{
121 if ((new_mtu < 68) || (new_mtu > IEEE80211_DATA_LEN))
122 return -EINVAL;
123 dev->mtu = new_mtu;
124 return 0;
125}
126
127static struct net_device_stats *ieee80211_generic_get_stats(
128 struct net_device *dev)
129{
130 struct ieee80211_device *ieee = netdev_priv(dev);
131 return &ieee->stats;
132}
133
134struct net_device *alloc_ieee80211(int sizeof_priv)
135{
136 struct ieee80211_device *ieee;
137 struct net_device *dev;
138 int err;
139
140 IEEE80211_DEBUG_INFO("Initializing...\n");
141
142 dev = alloc_etherdev(sizeof(struct ieee80211_device) + sizeof_priv);
143 if (!dev) {
144 IEEE80211_ERROR("Unable to allocate network device.\n");
145 goto failed;
146 }
147 ieee = netdev_priv(dev);
148 dev->hard_start_xmit = ieee80211_xmit;
149 dev->change_mtu = ieee80211_change_mtu;
150
151 /* Drivers are free to override this if the generic implementation
152 * does not meet their needs. */
153 dev->get_stats = ieee80211_generic_get_stats;
154
155 ieee->dev = dev;
156
157 err = ieee80211_networks_allocate(ieee);
158 if (err) {
159 IEEE80211_ERROR("Unable to allocate beacon storage: %d\n", err);
160 goto failed_free_netdev;
161 }
162 ieee80211_networks_initialize(ieee);
163
164 /* Default fragmentation threshold is maximum payload size */
165 ieee->fts = DEFAULT_FTS;
166 ieee->rts = DEFAULT_FTS;
167 ieee->scan_age = DEFAULT_MAX_SCAN_AGE;
168 ieee->open_wep = 1;
169
170 /* Default to enabling full open WEP with host based encrypt/decrypt */
171 ieee->host_encrypt = 1;
172 ieee->host_decrypt = 1;
173 ieee->host_mc_decrypt = 1;
174
175 /* Host fragementation in Open mode. Default is enabled.
176 * Note: host fragmentation is always enabled if host encryption
177 * is enabled. For cards can do hardware encryption, they must do
178 * hardware fragmentation as well. So we don't need a variable
179 * like host_enc_frag. */
180 ieee->host_open_frag = 1;
181 ieee->ieee802_1x = 1; /* Default to supporting 802.1x */
182
183 spin_lock_init(&ieee->lock);
184
185 lib80211_crypt_info_init(&ieee->crypt_info, dev->name, &ieee->lock);
186
187 ieee->wpa_enabled = 0;
188 ieee->drop_unencrypted = 0;
189 ieee->privacy_invoked = 0;
190
191 return dev;
192
193failed_free_netdev:
194 free_netdev(dev);
195failed:
196 return NULL;
197}
198
199void free_ieee80211(struct net_device *dev)
200{
201 struct ieee80211_device *ieee = netdev_priv(dev);
202
203 lib80211_crypt_info_free(&ieee->crypt_info);
204
205 ieee80211_networks_free(ieee);
206 free_netdev(dev);
207}
208
209#ifdef CONFIG_IEEE80211_DEBUG
210
211static int debug = 0;
212u32 ieee80211_debug_level = 0;
213EXPORT_SYMBOL_GPL(ieee80211_debug_level);
214static struct proc_dir_entry *ieee80211_proc = NULL;
215
216static int show_debug_level(char *page, char **start, off_t offset,
217 int count, int *eof, void *data)
218{
219 return snprintf(page, count, "0x%08X\n", ieee80211_debug_level);
220}
221
222static int store_debug_level(struct file *file, const char __user * buffer,
223 unsigned long count, void *data)
224{
225 char buf[] = "0x00000000\n";
226 unsigned long len = min((unsigned long)sizeof(buf) - 1, count);
227 unsigned long val;
228
229 if (copy_from_user(buf, buffer, len))
230 return count;
231 buf[len] = 0;
232 if (sscanf(buf, "%li", &val) != 1)
233 printk(KERN_INFO DRV_NAME
234 ": %s is not in hex or decimal form.\n", buf);
235 else
236 ieee80211_debug_level = val;
237
238 return strnlen(buf, len);
239}
240#endif /* CONFIG_IEEE80211_DEBUG */
241
242static int __init ieee80211_init(void)
243{
244#ifdef CONFIG_IEEE80211_DEBUG
245 struct proc_dir_entry *e;
246
247 ieee80211_debug_level = debug;
248 ieee80211_proc = proc_mkdir(DRV_NAME, init_net.proc_net);
249 if (ieee80211_proc == NULL) {
250 IEEE80211_ERROR("Unable to create " DRV_NAME
251 " proc directory\n");
252 return -EIO;
253 }
254 e = create_proc_entry("debug_level", S_IFREG | S_IRUGO | S_IWUSR,
255 ieee80211_proc);
256 if (!e) {
257 remove_proc_entry(DRV_NAME, init_net.proc_net);
258 ieee80211_proc = NULL;
259 return -EIO;
260 }
261 e->read_proc = show_debug_level;
262 e->write_proc = store_debug_level;
263 e->data = NULL;
264#endif /* CONFIG_IEEE80211_DEBUG */
265
266 printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION ", " DRV_VERSION "\n");
267 printk(KERN_INFO DRV_NAME ": " DRV_COPYRIGHT "\n");
268
269 return 0;
270}
271
272static void __exit ieee80211_exit(void)
273{
274#ifdef CONFIG_IEEE80211_DEBUG
275 if (ieee80211_proc) {
276 remove_proc_entry("debug_level", ieee80211_proc);
277 remove_proc_entry(DRV_NAME, init_net.proc_net);
278 ieee80211_proc = NULL;
279 }
280#endif /* CONFIG_IEEE80211_DEBUG */
281}
282
283#ifdef CONFIG_IEEE80211_DEBUG
284#include <linux/moduleparam.h>
285module_param(debug, int, 0444);
286MODULE_PARM_DESC(debug, "debug output mask");
287#endif /* CONFIG_IEEE80211_DEBUG */
288
289module_exit(ieee80211_exit);
290module_init(ieee80211_init);
291
292EXPORT_SYMBOL(alloc_ieee80211);
293EXPORT_SYMBOL(free_ieee80211);
diff --git a/drivers/net/wireless/ipw2x00/libipw_rx.c b/drivers/net/wireless/ipw2x00/libipw_rx.c
new file mode 100644
index 000000000000..9c67dfae4320
--- /dev/null
+++ b/drivers/net/wireless/ipw2x00/libipw_rx.c
@@ -0,0 +1,1799 @@
1/*
2 * Original code based Host AP (software wireless LAN access point) driver
3 * for Intersil Prism2/2.5/3 - hostap.o module, common routines
4 *
5 * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
6 * <j@w1.fi>
7 * Copyright (c) 2002-2003, Jouni Malinen <j@w1.fi>
8 * Copyright (c) 2004-2005, Intel Corporation
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation. See README and COPYING for
13 * more details.
14 */
15
16#include <linux/compiler.h>
17#include <linux/errno.h>
18#include <linux/if_arp.h>
19#include <linux/in6.h>
20#include <linux/in.h>
21#include <linux/ip.h>
22#include <linux/kernel.h>
23#include <linux/module.h>
24#include <linux/netdevice.h>
25#include <linux/proc_fs.h>
26#include <linux/skbuff.h>
27#include <linux/slab.h>
28#include <linux/tcp.h>
29#include <linux/types.h>
30#include <linux/wireless.h>
31#include <linux/etherdevice.h>
32#include <asm/uaccess.h>
33#include <linux/ctype.h>
34
35#include <net/lib80211.h>
36#include <net/ieee80211.h>
37
38static void ieee80211_monitor_rx(struct ieee80211_device *ieee,
39 struct sk_buff *skb,
40 struct ieee80211_rx_stats *rx_stats)
41{
42 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
43 u16 fc = le16_to_cpu(hdr->frame_control);
44
45 skb->dev = ieee->dev;
46 skb_reset_mac_header(skb);
47 skb_pull(skb, ieee80211_get_hdrlen(fc));
48 skb->pkt_type = PACKET_OTHERHOST;
49 skb->protocol = htons(ETH_P_80211_RAW);
50 memset(skb->cb, 0, sizeof(skb->cb));
51 netif_rx(skb);
52}
53
54/* Called only as a tasklet (software IRQ) */
55static struct ieee80211_frag_entry *ieee80211_frag_cache_find(struct
56 ieee80211_device
57 *ieee,
58 unsigned int seq,
59 unsigned int frag,
60 u8 * src,
61 u8 * dst)
62{
63 struct ieee80211_frag_entry *entry;
64 int i;
65
66 for (i = 0; i < IEEE80211_FRAG_CACHE_LEN; i++) {
67 entry = &ieee->frag_cache[i];
68 if (entry->skb != NULL &&
69 time_after(jiffies, entry->first_frag_time + 2 * HZ)) {
70 IEEE80211_DEBUG_FRAG("expiring fragment cache entry "
71 "seq=%u last_frag=%u\n",
72 entry->seq, entry->last_frag);
73 dev_kfree_skb_any(entry->skb);
74 entry->skb = NULL;
75 }
76
77 if (entry->skb != NULL && entry->seq == seq &&
78 (entry->last_frag + 1 == frag || frag == -1) &&
79 !compare_ether_addr(entry->src_addr, src) &&
80 !compare_ether_addr(entry->dst_addr, dst))
81 return entry;
82 }
83
84 return NULL;
85}
86
87/* Called only as a tasklet (software IRQ) */
88static struct sk_buff *ieee80211_frag_cache_get(struct ieee80211_device *ieee,
89 struct ieee80211_hdr_4addr *hdr)
90{
91 struct sk_buff *skb = NULL;
92 u16 sc;
93 unsigned int frag, seq;
94 struct ieee80211_frag_entry *entry;
95
96 sc = le16_to_cpu(hdr->seq_ctl);
97 frag = WLAN_GET_SEQ_FRAG(sc);
98 seq = WLAN_GET_SEQ_SEQ(sc);
99
100 if (frag == 0) {
101 /* Reserve enough space to fit maximum frame length */
102 skb = dev_alloc_skb(ieee->dev->mtu +
103 sizeof(struct ieee80211_hdr_4addr) +
104 8 /* LLC */ +
105 2 /* alignment */ +
106 8 /* WEP */ + ETH_ALEN /* WDS */ );
107 if (skb == NULL)
108 return NULL;
109
110 entry = &ieee->frag_cache[ieee->frag_next_idx];
111 ieee->frag_next_idx++;
112 if (ieee->frag_next_idx >= IEEE80211_FRAG_CACHE_LEN)
113 ieee->frag_next_idx = 0;
114
115 if (entry->skb != NULL)
116 dev_kfree_skb_any(entry->skb);
117
118 entry->first_frag_time = jiffies;
119 entry->seq = seq;
120 entry->last_frag = frag;
121 entry->skb = skb;
122 memcpy(entry->src_addr, hdr->addr2, ETH_ALEN);
123 memcpy(entry->dst_addr, hdr->addr1, ETH_ALEN);
124 } else {
125 /* received a fragment of a frame for which the head fragment
126 * should have already been received */
127 entry = ieee80211_frag_cache_find(ieee, seq, frag, hdr->addr2,
128 hdr->addr1);
129 if (entry != NULL) {
130 entry->last_frag = frag;
131 skb = entry->skb;
132 }
133 }
134
135 return skb;
136}
137
138/* Called only as a tasklet (software IRQ) */
139static int ieee80211_frag_cache_invalidate(struct ieee80211_device *ieee,
140 struct ieee80211_hdr_4addr *hdr)
141{
142 u16 sc;
143 unsigned int seq;
144 struct ieee80211_frag_entry *entry;
145
146 sc = le16_to_cpu(hdr->seq_ctl);
147 seq = WLAN_GET_SEQ_SEQ(sc);
148
149 entry = ieee80211_frag_cache_find(ieee, seq, -1, hdr->addr2,
150 hdr->addr1);
151
152 if (entry == NULL) {
153 IEEE80211_DEBUG_FRAG("could not invalidate fragment cache "
154 "entry (seq=%u)\n", seq);
155 return -1;
156 }
157
158 entry->skb = NULL;
159 return 0;
160}
161
162#ifdef NOT_YET
163/* ieee80211_rx_frame_mgtmt
164 *
165 * Responsible for handling management control frames
166 *
167 * Called by ieee80211_rx */
168static int
169ieee80211_rx_frame_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb,
170 struct ieee80211_rx_stats *rx_stats, u16 type,
171 u16 stype)
172{
173 if (ieee->iw_mode == IW_MODE_MASTER) {
174 printk(KERN_DEBUG "%s: Master mode not yet suppported.\n",
175 ieee->dev->name);
176 return 0;
177/*
178 hostap_update_sta_ps(ieee, (struct hostap_ieee80211_hdr_4addr *)
179 skb->data);*/
180 }
181
182 if (ieee->hostapd && type == WLAN_FC_TYPE_MGMT) {
183 if (stype == WLAN_FC_STYPE_BEACON &&
184 ieee->iw_mode == IW_MODE_MASTER) {
185 struct sk_buff *skb2;
186 /* Process beacon frames also in kernel driver to
187 * update STA(AP) table statistics */
188 skb2 = skb_clone(skb, GFP_ATOMIC);
189 if (skb2)
190 hostap_rx(skb2->dev, skb2, rx_stats);
191 }
192
193 /* send management frames to the user space daemon for
194 * processing */
195 ieee->apdevstats.rx_packets++;
196 ieee->apdevstats.rx_bytes += skb->len;
197 prism2_rx_80211(ieee->apdev, skb, rx_stats, PRISM2_RX_MGMT);
198 return 0;
199 }
200
201 if (ieee->iw_mode == IW_MODE_MASTER) {
202 if (type != WLAN_FC_TYPE_MGMT && type != WLAN_FC_TYPE_CTRL) {
203 printk(KERN_DEBUG "%s: unknown management frame "
204 "(type=0x%02x, stype=0x%02x) dropped\n",
205 skb->dev->name, type, stype);
206 return -1;
207 }
208
209 hostap_rx(skb->dev, skb, rx_stats);
210 return 0;
211 }
212
213 printk(KERN_DEBUG "%s: hostap_rx_frame_mgmt: management frame "
214 "received in non-Host AP mode\n", skb->dev->name);
215 return -1;
216}
217#endif
218
219/* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */
220/* Ethernet-II snap header (RFC1042 for most EtherTypes) */
221static unsigned char rfc1042_header[] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
222
223/* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */
224static unsigned char bridge_tunnel_header[] =
225 { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
226/* No encapsulation header if EtherType < 0x600 (=length) */
227
228/* Called by ieee80211_rx_frame_decrypt */
229static int ieee80211_is_eapol_frame(struct ieee80211_device *ieee,
230 struct sk_buff *skb)
231{
232 struct net_device *dev = ieee->dev;
233 u16 fc, ethertype;
234 struct ieee80211_hdr_3addr *hdr;
235 u8 *pos;
236
237 if (skb->len < 24)
238 return 0;
239
240 hdr = (struct ieee80211_hdr_3addr *)skb->data;
241 fc = le16_to_cpu(hdr->frame_ctl);
242
243 /* check that the frame is unicast frame to us */
244 if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
245 IEEE80211_FCTL_TODS &&
246 !compare_ether_addr(hdr->addr1, dev->dev_addr) &&
247 !compare_ether_addr(hdr->addr3, dev->dev_addr)) {
248 /* ToDS frame with own addr BSSID and DA */
249 } else if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
250 IEEE80211_FCTL_FROMDS &&
251 !compare_ether_addr(hdr->addr1, dev->dev_addr)) {
252 /* FromDS frame with own addr as DA */
253 } else
254 return 0;
255
256 if (skb->len < 24 + 8)
257 return 0;
258
259 /* check for port access entity Ethernet type */
260 pos = skb->data + 24;
261 ethertype = (pos[6] << 8) | pos[7];
262 if (ethertype == ETH_P_PAE)
263 return 1;
264
265 return 0;
266}
267
268/* Called only as a tasklet (software IRQ), by ieee80211_rx */
269static int
270ieee80211_rx_frame_decrypt(struct ieee80211_device *ieee, struct sk_buff *skb,
271 struct lib80211_crypt_data *crypt)
272{
273 struct ieee80211_hdr_3addr *hdr;
274 int res, hdrlen;
275
276 if (crypt == NULL || crypt->ops->decrypt_mpdu == NULL)
277 return 0;
278
279 hdr = (struct ieee80211_hdr_3addr *)skb->data;
280 hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
281
282 atomic_inc(&crypt->refcnt);
283 res = crypt->ops->decrypt_mpdu(skb, hdrlen, crypt->priv);
284 atomic_dec(&crypt->refcnt);
285 if (res < 0) {
286 IEEE80211_DEBUG_DROP("decryption failed (SA=%pM) res=%d\n",
287 hdr->addr2, res);
288 if (res == -2)
289 IEEE80211_DEBUG_DROP("Decryption failed ICV "
290 "mismatch (key %d)\n",
291 skb->data[hdrlen + 3] >> 6);
292 ieee->ieee_stats.rx_discards_undecryptable++;
293 return -1;
294 }
295
296 return res;
297}
298
299/* Called only as a tasklet (software IRQ), by ieee80211_rx */
300static int
301ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device *ieee,
302 struct sk_buff *skb, int keyidx,
303 struct lib80211_crypt_data *crypt)
304{
305 struct ieee80211_hdr_3addr *hdr;
306 int res, hdrlen;
307
308 if (crypt == NULL || crypt->ops->decrypt_msdu == NULL)
309 return 0;
310
311 hdr = (struct ieee80211_hdr_3addr *)skb->data;
312 hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
313
314 atomic_inc(&crypt->refcnt);
315 res = crypt->ops->decrypt_msdu(skb, keyidx, hdrlen, crypt->priv);
316 atomic_dec(&crypt->refcnt);
317 if (res < 0) {
318 printk(KERN_DEBUG "%s: MSDU decryption/MIC verification failed"
319 " (SA=%pM keyidx=%d)\n", ieee->dev->name, hdr->addr2,
320 keyidx);
321 return -1;
322 }
323
324 return 0;
325}
326
327/* All received frames are sent to this function. @skb contains the frame in
328 * IEEE 802.11 format, i.e., in the format it was sent over air.
329 * This function is called only as a tasklet (software IRQ). */
330int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
331 struct ieee80211_rx_stats *rx_stats)
332{
333 struct net_device *dev = ieee->dev;
334 struct ieee80211_hdr_4addr *hdr;
335 size_t hdrlen;
336 u16 fc, type, stype, sc;
337 struct net_device_stats *stats;
338 unsigned int frag;
339 u8 *payload;
340 u16 ethertype;
341#ifdef NOT_YET
342 struct net_device *wds = NULL;
343 struct sk_buff *skb2 = NULL;
344 struct net_device *wds = NULL;
345 int frame_authorized = 0;
346 int from_assoc_ap = 0;
347 void *sta = NULL;
348#endif
349 u8 dst[ETH_ALEN];
350 u8 src[ETH_ALEN];
351 struct lib80211_crypt_data *crypt = NULL;
352 int keyidx = 0;
353 int can_be_decrypted = 0;
354
355 hdr = (struct ieee80211_hdr_4addr *)skb->data;
356 stats = &ieee->stats;
357
358 if (skb->len < 10) {
359 printk(KERN_INFO "%s: SKB length < 10\n", dev->name);
360 goto rx_dropped;
361 }
362
363 fc = le16_to_cpu(hdr->frame_ctl);
364 type = WLAN_FC_GET_TYPE(fc);
365 stype = WLAN_FC_GET_STYPE(fc);
366 sc = le16_to_cpu(hdr->seq_ctl);
367 frag = WLAN_GET_SEQ_FRAG(sc);
368 hdrlen = ieee80211_get_hdrlen(fc);
369
370 if (skb->len < hdrlen) {
371 printk(KERN_INFO "%s: invalid SKB length %d\n",
372 dev->name, skb->len);
373 goto rx_dropped;
374 }
375
376 /* Put this code here so that we avoid duplicating it in all
377 * Rx paths. - Jean II */
378#ifdef CONFIG_WIRELESS_EXT
379#ifdef IW_WIRELESS_SPY /* defined in iw_handler.h */
380 /* If spy monitoring on */
381 if (ieee->spy_data.spy_number > 0) {
382 struct iw_quality wstats;
383
384 wstats.updated = 0;
385 if (rx_stats->mask & IEEE80211_STATMASK_RSSI) {
386 wstats.level = rx_stats->signal;
387 wstats.updated |= IW_QUAL_LEVEL_UPDATED;
388 } else
389 wstats.updated |= IW_QUAL_LEVEL_INVALID;
390
391 if (rx_stats->mask & IEEE80211_STATMASK_NOISE) {
392 wstats.noise = rx_stats->noise;
393 wstats.updated |= IW_QUAL_NOISE_UPDATED;
394 } else
395 wstats.updated |= IW_QUAL_NOISE_INVALID;
396
397 if (rx_stats->mask & IEEE80211_STATMASK_SIGNAL) {
398 wstats.qual = rx_stats->signal;
399 wstats.updated |= IW_QUAL_QUAL_UPDATED;
400 } else
401 wstats.updated |= IW_QUAL_QUAL_INVALID;
402
403 /* Update spy records */
404 wireless_spy_update(ieee->dev, hdr->addr2, &wstats);
405 }
406#endif /* IW_WIRELESS_SPY */
407#endif /* CONFIG_WIRELESS_EXT */
408
409#ifdef NOT_YET
410 hostap_update_rx_stats(local->ap, hdr, rx_stats);
411#endif
412
413 if (ieee->iw_mode == IW_MODE_MONITOR) {
414 stats->rx_packets++;
415 stats->rx_bytes += skb->len;
416 ieee80211_monitor_rx(ieee, skb, rx_stats);
417 return 1;
418 }
419
420 can_be_decrypted = (is_multicast_ether_addr(hdr->addr1) ||
421 is_broadcast_ether_addr(hdr->addr2)) ?
422 ieee->host_mc_decrypt : ieee->host_decrypt;
423
424 if (can_be_decrypted) {
425 if (skb->len >= hdrlen + 3) {
426 /* Top two-bits of byte 3 are the key index */
427 keyidx = skb->data[hdrlen + 3] >> 6;
428 }
429
430 /* ieee->crypt[] is WEP_KEY (4) in length. Given that keyidx
431 * is only allowed 2-bits of storage, no value of keyidx can
432 * be provided via above code that would result in keyidx
433 * being out of range */
434 crypt = ieee->crypt_info.crypt[keyidx];
435
436#ifdef NOT_YET
437 sta = NULL;
438
439 /* Use station specific key to override default keys if the
440 * receiver address is a unicast address ("individual RA"). If
441 * bcrx_sta_key parameter is set, station specific key is used
442 * even with broad/multicast targets (this is against IEEE
443 * 802.11, but makes it easier to use different keys with
444 * stations that do not support WEP key mapping). */
445
446 if (!(hdr->addr1[0] & 0x01) || local->bcrx_sta_key)
447 (void)hostap_handle_sta_crypto(local, hdr, &crypt,
448 &sta);
449#endif
450
451 /* allow NULL decrypt to indicate an station specific override
452 * for default encryption */
453 if (crypt && (crypt->ops == NULL ||
454 crypt->ops->decrypt_mpdu == NULL))
455 crypt = NULL;
456
457 if (!crypt && (fc & IEEE80211_FCTL_PROTECTED)) {
458 /* This seems to be triggered by some (multicast?)
459 * frames from other than current BSS, so just drop the
460 * frames silently instead of filling system log with
461 * these reports. */
462 IEEE80211_DEBUG_DROP("Decryption failed (not set)"
463 " (SA=%pM)\n", hdr->addr2);
464 ieee->ieee_stats.rx_discards_undecryptable++;
465 goto rx_dropped;
466 }
467 }
468#ifdef NOT_YET
469 if (type != WLAN_FC_TYPE_DATA) {
470 if (type == WLAN_FC_TYPE_MGMT && stype == WLAN_FC_STYPE_AUTH &&
471 fc & IEEE80211_FCTL_PROTECTED && ieee->host_decrypt &&
472 (keyidx = hostap_rx_frame_decrypt(ieee, skb, crypt)) < 0) {
473 printk(KERN_DEBUG "%s: failed to decrypt mgmt::auth "
474 "from %pM\n", dev->name, hdr->addr2);
475 /* TODO: could inform hostapd about this so that it
476 * could send auth failure report */
477 goto rx_dropped;
478 }
479
480 if (ieee80211_rx_frame_mgmt(ieee, skb, rx_stats, type, stype))
481 goto rx_dropped;
482 else
483 goto rx_exit;
484 }
485#endif
486 /* drop duplicate 802.11 retransmissions (IEEE 802.11 Chap. 9.29) */
487 if (sc == ieee->prev_seq_ctl)
488 goto rx_dropped;
489 else
490 ieee->prev_seq_ctl = sc;
491
492 /* Data frame - extract src/dst addresses */
493 if (skb->len < IEEE80211_3ADDR_LEN)
494 goto rx_dropped;
495
496 switch (fc & (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
497 case IEEE80211_FCTL_FROMDS:
498 memcpy(dst, hdr->addr1, ETH_ALEN);
499 memcpy(src, hdr->addr3, ETH_ALEN);
500 break;
501 case IEEE80211_FCTL_TODS:
502 memcpy(dst, hdr->addr3, ETH_ALEN);
503 memcpy(src, hdr->addr2, ETH_ALEN);
504 break;
505 case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS:
506 if (skb->len < IEEE80211_4ADDR_LEN)
507 goto rx_dropped;
508 memcpy(dst, hdr->addr3, ETH_ALEN);
509 memcpy(src, hdr->addr4, ETH_ALEN);
510 break;
511 case 0:
512 memcpy(dst, hdr->addr1, ETH_ALEN);
513 memcpy(src, hdr->addr2, ETH_ALEN);
514 break;
515 }
516
517#ifdef NOT_YET
518 if (hostap_rx_frame_wds(ieee, hdr, fc, &wds))
519 goto rx_dropped;
520 if (wds) {
521 skb->dev = dev = wds;
522 stats = hostap_get_stats(dev);
523 }
524
525 if (ieee->iw_mode == IW_MODE_MASTER && !wds &&
526 (fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
527 IEEE80211_FCTL_FROMDS && ieee->stadev
528 && !compare_ether_addr(hdr->addr2, ieee->assoc_ap_addr)) {
529 /* Frame from BSSID of the AP for which we are a client */
530 skb->dev = dev = ieee->stadev;
531 stats = hostap_get_stats(dev);
532 from_assoc_ap = 1;
533 }
534#endif
535
536#ifdef NOT_YET
537 if ((ieee->iw_mode == IW_MODE_MASTER ||
538 ieee->iw_mode == IW_MODE_REPEAT) && !from_assoc_ap) {
539 switch (hostap_handle_sta_rx(ieee, dev, skb, rx_stats,
540 wds != NULL)) {
541 case AP_RX_CONTINUE_NOT_AUTHORIZED:
542 frame_authorized = 0;
543 break;
544 case AP_RX_CONTINUE:
545 frame_authorized = 1;
546 break;
547 case AP_RX_DROP:
548 goto rx_dropped;
549 case AP_RX_EXIT:
550 goto rx_exit;
551 }
552 }
553#endif
554
555 /* Nullfunc frames may have PS-bit set, so they must be passed to
556 * hostap_handle_sta_rx() before being dropped here. */
557
558 stype &= ~IEEE80211_STYPE_QOS_DATA;
559
560 if (stype != IEEE80211_STYPE_DATA &&
561 stype != IEEE80211_STYPE_DATA_CFACK &&
562 stype != IEEE80211_STYPE_DATA_CFPOLL &&
563 stype != IEEE80211_STYPE_DATA_CFACKPOLL) {
564 if (stype != IEEE80211_STYPE_NULLFUNC)
565 IEEE80211_DEBUG_DROP("RX: dropped data frame "
566 "with no data (type=0x%02x, "
567 "subtype=0x%02x, len=%d)\n",
568 type, stype, skb->len);
569 goto rx_dropped;
570 }
571
572 /* skb: hdr + (possibly fragmented, possibly encrypted) payload */
573
574 if ((fc & IEEE80211_FCTL_PROTECTED) && can_be_decrypted &&
575 (keyidx = ieee80211_rx_frame_decrypt(ieee, skb, crypt)) < 0)
576 goto rx_dropped;
577
578 hdr = (struct ieee80211_hdr_4addr *)skb->data;
579
580 /* skb: hdr + (possibly fragmented) plaintext payload */
581 // PR: FIXME: hostap has additional conditions in the "if" below:
582 // ieee->host_decrypt && (fc & IEEE80211_FCTL_PROTECTED) &&
583 if ((frag != 0) || (fc & IEEE80211_FCTL_MOREFRAGS)) {
584 int flen;
585 struct sk_buff *frag_skb = ieee80211_frag_cache_get(ieee, hdr);
586 IEEE80211_DEBUG_FRAG("Rx Fragment received (%u)\n", frag);
587
588 if (!frag_skb) {
589 IEEE80211_DEBUG(IEEE80211_DL_RX | IEEE80211_DL_FRAG,
590 "Rx cannot get skb from fragment "
591 "cache (morefrag=%d seq=%u frag=%u)\n",
592 (fc & IEEE80211_FCTL_MOREFRAGS) != 0,
593 WLAN_GET_SEQ_SEQ(sc), frag);
594 goto rx_dropped;
595 }
596
597 flen = skb->len;
598 if (frag != 0)
599 flen -= hdrlen;
600
601 if (frag_skb->tail + flen > frag_skb->end) {
602 printk(KERN_WARNING "%s: host decrypted and "
603 "reassembled frame did not fit skb\n",
604 dev->name);
605 ieee80211_frag_cache_invalidate(ieee, hdr);
606 goto rx_dropped;
607 }
608
609 if (frag == 0) {
610 /* copy first fragment (including full headers) into
611 * beginning of the fragment cache skb */
612 skb_copy_from_linear_data(skb, skb_put(frag_skb, flen), flen);
613 } else {
614 /* append frame payload to the end of the fragment
615 * cache skb */
616 skb_copy_from_linear_data_offset(skb, hdrlen,
617 skb_put(frag_skb, flen), flen);
618 }
619 dev_kfree_skb_any(skb);
620 skb = NULL;
621
622 if (fc & IEEE80211_FCTL_MOREFRAGS) {
623 /* more fragments expected - leave the skb in fragment
624 * cache for now; it will be delivered to upper layers
625 * after all fragments have been received */
626 goto rx_exit;
627 }
628
629 /* this was the last fragment and the frame will be
630 * delivered, so remove skb from fragment cache */
631 skb = frag_skb;
632 hdr = (struct ieee80211_hdr_4addr *)skb->data;
633 ieee80211_frag_cache_invalidate(ieee, hdr);
634 }
635
636 /* skb: hdr + (possible reassembled) full MSDU payload; possibly still
637 * encrypted/authenticated */
638 if ((fc & IEEE80211_FCTL_PROTECTED) && can_be_decrypted &&
639 ieee80211_rx_frame_decrypt_msdu(ieee, skb, keyidx, crypt))
640 goto rx_dropped;
641
642 hdr = (struct ieee80211_hdr_4addr *)skb->data;
643 if (crypt && !(fc & IEEE80211_FCTL_PROTECTED) && !ieee->open_wep) {
644 if ( /*ieee->ieee802_1x && */
645 ieee80211_is_eapol_frame(ieee, skb)) {
646 /* pass unencrypted EAPOL frames even if encryption is
647 * configured */
648 } else {
649 IEEE80211_DEBUG_DROP("encryption configured, but RX "
650 "frame not encrypted (SA=%pM)\n",
651 hdr->addr2);
652 goto rx_dropped;
653 }
654 }
655
656 if (crypt && !(fc & IEEE80211_FCTL_PROTECTED) && !ieee->open_wep &&
657 !ieee80211_is_eapol_frame(ieee, skb)) {
658 IEEE80211_DEBUG_DROP("dropped unencrypted RX data "
659 "frame from %pM (drop_unencrypted=1)\n",
660 hdr->addr2);
661 goto rx_dropped;
662 }
663
664 /* If the frame was decrypted in hardware, we may need to strip off
665 * any security data (IV, ICV, etc) that was left behind */
666 if (!can_be_decrypted && (fc & IEEE80211_FCTL_PROTECTED) &&
667 ieee->host_strip_iv_icv) {
668 int trimlen = 0;
669
670 /* Top two-bits of byte 3 are the key index */
671 if (skb->len >= hdrlen + 3)
672 keyidx = skb->data[hdrlen + 3] >> 6;
673
674 /* To strip off any security data which appears before the
675 * payload, we simply increase hdrlen (as the header gets
676 * chopped off immediately below). For the security data which
677 * appears after the payload, we use skb_trim. */
678
679 switch (ieee->sec.encode_alg[keyidx]) {
680 case SEC_ALG_WEP:
681 /* 4 byte IV */
682 hdrlen += 4;
683 /* 4 byte ICV */
684 trimlen = 4;
685 break;
686 case SEC_ALG_TKIP:
687 /* 4 byte IV, 4 byte ExtIV */
688 hdrlen += 8;
689 /* 8 byte MIC, 4 byte ICV */
690 trimlen = 12;
691 break;
692 case SEC_ALG_CCMP:
693 /* 8 byte CCMP header */
694 hdrlen += 8;
695 /* 8 byte MIC */
696 trimlen = 8;
697 break;
698 }
699
700 if (skb->len < trimlen)
701 goto rx_dropped;
702
703 __skb_trim(skb, skb->len - trimlen);
704
705 if (skb->len < hdrlen)
706 goto rx_dropped;
707 }
708
709 /* skb: hdr + (possible reassembled) full plaintext payload */
710
711 payload = skb->data + hdrlen;
712 ethertype = (payload[6] << 8) | payload[7];
713
714#ifdef NOT_YET
715 /* If IEEE 802.1X is used, check whether the port is authorized to send
716 * the received frame. */
717 if (ieee->ieee802_1x && ieee->iw_mode == IW_MODE_MASTER) {
718 if (ethertype == ETH_P_PAE) {
719 printk(KERN_DEBUG "%s: RX: IEEE 802.1X frame\n",
720 dev->name);
721 if (ieee->hostapd && ieee->apdev) {
722 /* Send IEEE 802.1X frames to the user
723 * space daemon for processing */
724 prism2_rx_80211(ieee->apdev, skb, rx_stats,
725 PRISM2_RX_MGMT);
726 ieee->apdevstats.rx_packets++;
727 ieee->apdevstats.rx_bytes += skb->len;
728 goto rx_exit;
729 }
730 } else if (!frame_authorized) {
731 printk(KERN_DEBUG "%s: dropped frame from "
732 "unauthorized port (IEEE 802.1X): "
733 "ethertype=0x%04x\n", dev->name, ethertype);
734 goto rx_dropped;
735 }
736 }
737#endif
738
739 /* convert hdr + possible LLC headers into Ethernet header */
740 if (skb->len - hdrlen >= 8 &&
741 ((memcmp(payload, rfc1042_header, SNAP_SIZE) == 0 &&
742 ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) ||
743 memcmp(payload, bridge_tunnel_header, SNAP_SIZE) == 0)) {
744 /* remove RFC1042 or Bridge-Tunnel encapsulation and
745 * replace EtherType */
746 skb_pull(skb, hdrlen + SNAP_SIZE);
747 memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN);
748 memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN);
749 } else {
750 __be16 len;
751 /* Leave Ethernet header part of hdr and full payload */
752 skb_pull(skb, hdrlen);
753 len = htons(skb->len);
754 memcpy(skb_push(skb, 2), &len, 2);
755 memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN);
756 memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN);
757 }
758
759#ifdef NOT_YET
760 if (wds && ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
761 IEEE80211_FCTL_TODS) && skb->len >= ETH_HLEN + ETH_ALEN) {
762 /* Non-standard frame: get addr4 from its bogus location after
763 * the payload */
764 skb_copy_to_linear_data_offset(skb, ETH_ALEN,
765 skb->data + skb->len - ETH_ALEN,
766 ETH_ALEN);
767 skb_trim(skb, skb->len - ETH_ALEN);
768 }
769#endif
770
771 stats->rx_packets++;
772 stats->rx_bytes += skb->len;
773
774#ifdef NOT_YET
775 if (ieee->iw_mode == IW_MODE_MASTER && !wds && ieee->ap->bridge_packets) {
776 if (dst[0] & 0x01) {
777 /* copy multicast frame both to the higher layers and
778 * to the wireless media */
779 ieee->ap->bridged_multicast++;
780 skb2 = skb_clone(skb, GFP_ATOMIC);
781 if (skb2 == NULL)
782 printk(KERN_DEBUG "%s: skb_clone failed for "
783 "multicast frame\n", dev->name);
784 } else if (hostap_is_sta_assoc(ieee->ap, dst)) {
785 /* send frame directly to the associated STA using
786 * wireless media and not passing to higher layers */
787 ieee->ap->bridged_unicast++;
788 skb2 = skb;
789 skb = NULL;
790 }
791 }
792
793 if (skb2 != NULL) {
794 /* send to wireless media */
795 skb2->dev = dev;
796 skb2->protocol = htons(ETH_P_802_3);
797 skb_reset_mac_header(skb2);
798 skb_reset_network_header(skb2);
799 /* skb2->network_header += ETH_HLEN; */
800 dev_queue_xmit(skb2);
801 }
802#endif
803
804 if (skb) {
805 skb->protocol = eth_type_trans(skb, dev);
806 memset(skb->cb, 0, sizeof(skb->cb));
807 skb->ip_summed = CHECKSUM_NONE; /* 802.11 crc not sufficient */
808 if (netif_rx(skb) == NET_RX_DROP) {
809 /* netif_rx always succeeds, but it might drop
810 * the packet. If it drops the packet, we log that
811 * in our stats. */
812 IEEE80211_DEBUG_DROP
813 ("RX: netif_rx dropped the packet\n");
814 stats->rx_dropped++;
815 }
816 }
817
818 rx_exit:
819#ifdef NOT_YET
820 if (sta)
821 hostap_handle_sta_release(sta);
822#endif
823 return 1;
824
825 rx_dropped:
826 stats->rx_dropped++;
827
828 /* Returning 0 indicates to caller that we have not handled the SKB--
829 * so it is still allocated and can be used again by underlying
830 * hardware as a DMA target */
831 return 0;
832}
833
834/* Filter out unrelated packets, call ieee80211_rx[_mgt]
835 * This function takes over the skb, it should not be used again after calling
836 * this function. */
837void ieee80211_rx_any(struct ieee80211_device *ieee,
838 struct sk_buff *skb, struct ieee80211_rx_stats *stats)
839{
840 struct ieee80211_hdr_4addr *hdr;
841 int is_packet_for_us;
842 u16 fc;
843
844 if (ieee->iw_mode == IW_MODE_MONITOR) {
845 if (!ieee80211_rx(ieee, skb, stats))
846 dev_kfree_skb_irq(skb);
847 return;
848 }
849
850 if (skb->len < sizeof(struct ieee80211_hdr))
851 goto drop_free;
852
853 hdr = (struct ieee80211_hdr_4addr *)skb->data;
854 fc = le16_to_cpu(hdr->frame_ctl);
855
856 if ((fc & IEEE80211_FCTL_VERS) != 0)
857 goto drop_free;
858
859 switch (fc & IEEE80211_FCTL_FTYPE) {
860 case IEEE80211_FTYPE_MGMT:
861 if (skb->len < sizeof(struct ieee80211_hdr_3addr))
862 goto drop_free;
863 ieee80211_rx_mgt(ieee, hdr, stats);
864 dev_kfree_skb_irq(skb);
865 return;
866 case IEEE80211_FTYPE_DATA:
867 break;
868 case IEEE80211_FTYPE_CTL:
869 return;
870 default:
871 return;
872 }
873
874 is_packet_for_us = 0;
875 switch (ieee->iw_mode) {
876 case IW_MODE_ADHOC:
877 /* our BSS and not from/to DS */
878 if (memcmp(hdr->addr3, ieee->bssid, ETH_ALEN) == 0)
879 if ((fc & (IEEE80211_FCTL_TODS+IEEE80211_FCTL_FROMDS)) == 0) {
880 /* promisc: get all */
881 if (ieee->dev->flags & IFF_PROMISC)
882 is_packet_for_us = 1;
883 /* to us */
884 else if (memcmp(hdr->addr1, ieee->dev->dev_addr, ETH_ALEN) == 0)
885 is_packet_for_us = 1;
886 /* mcast */
887 else if (is_multicast_ether_addr(hdr->addr1))
888 is_packet_for_us = 1;
889 }
890 break;
891 case IW_MODE_INFRA:
892 /* our BSS (== from our AP) and from DS */
893 if (memcmp(hdr->addr2, ieee->bssid, ETH_ALEN) == 0)
894 if ((fc & (IEEE80211_FCTL_TODS+IEEE80211_FCTL_FROMDS)) == IEEE80211_FCTL_FROMDS) {
895 /* promisc: get all */
896 if (ieee->dev->flags & IFF_PROMISC)
897 is_packet_for_us = 1;
898 /* to us */
899 else if (memcmp(hdr->addr1, ieee->dev->dev_addr, ETH_ALEN) == 0)
900 is_packet_for_us = 1;
901 /* mcast */
902 else if (is_multicast_ether_addr(hdr->addr1)) {
903 /* not our own packet bcasted from AP */
904 if (memcmp(hdr->addr3, ieee->dev->dev_addr, ETH_ALEN))
905 is_packet_for_us = 1;
906 }
907 }
908 break;
909 default:
910 /* ? */
911 break;
912 }
913
914 if (is_packet_for_us)
915 if (!ieee80211_rx(ieee, skb, stats))
916 dev_kfree_skb_irq(skb);
917 return;
918
919drop_free:
920 dev_kfree_skb_irq(skb);
921 ieee->stats.rx_dropped++;
922 return;
923}
924
925#define MGMT_FRAME_FIXED_PART_LENGTH 0x24
926
927static u8 qos_oui[QOS_OUI_LEN] = { 0x00, 0x50, 0xF2 };
928
929/*
930* Make ther structure we read from the beacon packet has
931* the right values
932*/
933static int ieee80211_verify_qos_info(struct ieee80211_qos_information_element
934 *info_element, int sub_type)
935{
936
937 if (info_element->qui_subtype != sub_type)
938 return -1;
939 if (memcmp(info_element->qui, qos_oui, QOS_OUI_LEN))
940 return -1;
941 if (info_element->qui_type != QOS_OUI_TYPE)
942 return -1;
943 if (info_element->version != QOS_VERSION_1)
944 return -1;
945
946 return 0;
947}
948
949/*
950 * Parse a QoS parameter element
951 */
952static int ieee80211_read_qos_param_element(struct ieee80211_qos_parameter_info
953 *element_param, struct ieee80211_info_element
954 *info_element)
955{
956 int ret = 0;
957 u16 size = sizeof(struct ieee80211_qos_parameter_info) - 2;
958
959 if ((info_element == NULL) || (element_param == NULL))
960 return -1;
961
962 if (info_element->id == QOS_ELEMENT_ID && info_element->len == size) {
963 memcpy(element_param->info_element.qui, info_element->data,
964 info_element->len);
965 element_param->info_element.elementID = info_element->id;
966 element_param->info_element.length = info_element->len;
967 } else
968 ret = -1;
969 if (ret == 0)
970 ret = ieee80211_verify_qos_info(&element_param->info_element,
971 QOS_OUI_PARAM_SUB_TYPE);
972 return ret;
973}
974
975/*
976 * Parse a QoS information element
977 */
978static int ieee80211_read_qos_info_element(struct
979 ieee80211_qos_information_element
980 *element_info, struct ieee80211_info_element
981 *info_element)
982{
983 int ret = 0;
984 u16 size = sizeof(struct ieee80211_qos_information_element) - 2;
985
986 if (element_info == NULL)
987 return -1;
988 if (info_element == NULL)
989 return -1;
990
991 if ((info_element->id == QOS_ELEMENT_ID) && (info_element->len == size)) {
992 memcpy(element_info->qui, info_element->data,
993 info_element->len);
994 element_info->elementID = info_element->id;
995 element_info->length = info_element->len;
996 } else
997 ret = -1;
998
999 if (ret == 0)
1000 ret = ieee80211_verify_qos_info(element_info,
1001 QOS_OUI_INFO_SUB_TYPE);
1002 return ret;
1003}
1004
1005/*
1006 * Write QoS parameters from the ac parameters.
1007 */
1008static int ieee80211_qos_convert_ac_to_parameters(struct
1009 ieee80211_qos_parameter_info
1010 *param_elm, struct
1011 ieee80211_qos_parameters
1012 *qos_param)
1013{
1014 int rc = 0;
1015 int i;
1016 struct ieee80211_qos_ac_parameter *ac_params;
1017 u32 txop;
1018 u8 cw_min;
1019 u8 cw_max;
1020
1021 for (i = 0; i < QOS_QUEUE_NUM; i++) {
1022 ac_params = &(param_elm->ac_params_record[i]);
1023
1024 qos_param->aifs[i] = (ac_params->aci_aifsn) & 0x0F;
1025 qos_param->aifs[i] -= (qos_param->aifs[i] < 2) ? 0 : 2;
1026
1027 cw_min = ac_params->ecw_min_max & 0x0F;
1028 qos_param->cw_min[i] = cpu_to_le16((1 << cw_min) - 1);
1029
1030 cw_max = (ac_params->ecw_min_max & 0xF0) >> 4;
1031 qos_param->cw_max[i] = cpu_to_le16((1 << cw_max) - 1);
1032
1033 qos_param->flag[i] =
1034 (ac_params->aci_aifsn & 0x10) ? 0x01 : 0x00;
1035
1036 txop = le16_to_cpu(ac_params->tx_op_limit) * 32;
1037 qos_param->tx_op_limit[i] = cpu_to_le16(txop);
1038 }
1039 return rc;
1040}
1041
1042/*
1043 * we have a generic data element which it may contain QoS information or
1044 * parameters element. check the information element length to decide
1045 * which type to read
1046 */
1047static int ieee80211_parse_qos_info_param_IE(struct ieee80211_info_element
1048 *info_element,
1049 struct ieee80211_network *network)
1050{
1051 int rc = 0;
1052 struct ieee80211_qos_parameters *qos_param = NULL;
1053 struct ieee80211_qos_information_element qos_info_element;
1054
1055 rc = ieee80211_read_qos_info_element(&qos_info_element, info_element);
1056
1057 if (rc == 0) {
1058 network->qos_data.param_count = qos_info_element.ac_info & 0x0F;
1059 network->flags |= NETWORK_HAS_QOS_INFORMATION;
1060 } else {
1061 struct ieee80211_qos_parameter_info param_element;
1062
1063 rc = ieee80211_read_qos_param_element(&param_element,
1064 info_element);
1065 if (rc == 0) {
1066 qos_param = &(network->qos_data.parameters);
1067 ieee80211_qos_convert_ac_to_parameters(&param_element,
1068 qos_param);
1069 network->flags |= NETWORK_HAS_QOS_PARAMETERS;
1070 network->qos_data.param_count =
1071 param_element.info_element.ac_info & 0x0F;
1072 }
1073 }
1074
1075 if (rc == 0) {
1076 IEEE80211_DEBUG_QOS("QoS is supported\n");
1077 network->qos_data.supported = 1;
1078 }
1079 return rc;
1080}
1081
1082#ifdef CONFIG_IEEE80211_DEBUG
1083#define MFIE_STRING(x) case MFIE_TYPE_ ##x: return #x
1084
1085static const char *get_info_element_string(u16 id)
1086{
1087 switch (id) {
1088 MFIE_STRING(SSID);
1089 MFIE_STRING(RATES);
1090 MFIE_STRING(FH_SET);
1091 MFIE_STRING(DS_SET);
1092 MFIE_STRING(CF_SET);
1093 MFIE_STRING(TIM);
1094 MFIE_STRING(IBSS_SET);
1095 MFIE_STRING(COUNTRY);
1096 MFIE_STRING(HOP_PARAMS);
1097 MFIE_STRING(HOP_TABLE);
1098 MFIE_STRING(REQUEST);
1099 MFIE_STRING(CHALLENGE);
1100 MFIE_STRING(POWER_CONSTRAINT);
1101 MFIE_STRING(POWER_CAPABILITY);
1102 MFIE_STRING(TPC_REQUEST);
1103 MFIE_STRING(TPC_REPORT);
1104 MFIE_STRING(SUPP_CHANNELS);
1105 MFIE_STRING(CSA);
1106 MFIE_STRING(MEASURE_REQUEST);
1107 MFIE_STRING(MEASURE_REPORT);
1108 MFIE_STRING(QUIET);
1109 MFIE_STRING(IBSS_DFS);
1110 MFIE_STRING(ERP_INFO);
1111 MFIE_STRING(RSN);
1112 MFIE_STRING(RATES_EX);
1113 MFIE_STRING(GENERIC);
1114 MFIE_STRING(QOS_PARAMETER);
1115 default:
1116 return "UNKNOWN";
1117 }
1118}
1119#endif
1120
1121static int ieee80211_parse_info_param(struct ieee80211_info_element
1122 *info_element, u16 length,
1123 struct ieee80211_network *network)
1124{
1125 DECLARE_SSID_BUF(ssid);
1126 u8 i;
1127#ifdef CONFIG_IEEE80211_DEBUG
1128 char rates_str[64];
1129 char *p;
1130#endif
1131
1132 while (length >= sizeof(*info_element)) {
1133 if (sizeof(*info_element) + info_element->len > length) {
1134 IEEE80211_DEBUG_MGMT("Info elem: parse failed: "
1135 "info_element->len + 2 > left : "
1136 "info_element->len+2=%zd left=%d, id=%d.\n",
1137 info_element->len +
1138 sizeof(*info_element),
1139 length, info_element->id);
1140 /* We stop processing but don't return an error here
1141 * because some misbehaviour APs break this rule. ie.
1142 * Orinoco AP1000. */
1143 break;
1144 }
1145
1146 switch (info_element->id) {
1147 case MFIE_TYPE_SSID:
1148 network->ssid_len = min(info_element->len,
1149 (u8) IW_ESSID_MAX_SIZE);
1150 memcpy(network->ssid, info_element->data,
1151 network->ssid_len);
1152 if (network->ssid_len < IW_ESSID_MAX_SIZE)
1153 memset(network->ssid + network->ssid_len, 0,
1154 IW_ESSID_MAX_SIZE - network->ssid_len);
1155
1156 IEEE80211_DEBUG_MGMT("MFIE_TYPE_SSID: '%s' len=%d.\n",
1157 print_ssid(ssid, network->ssid,
1158 network->ssid_len),
1159 network->ssid_len);
1160 break;
1161
1162 case MFIE_TYPE_RATES:
1163#ifdef CONFIG_IEEE80211_DEBUG
1164 p = rates_str;
1165#endif
1166 network->rates_len = min(info_element->len,
1167 MAX_RATES_LENGTH);
1168 for (i = 0; i < network->rates_len; i++) {
1169 network->rates[i] = info_element->data[i];
1170#ifdef CONFIG_IEEE80211_DEBUG
1171 p += snprintf(p, sizeof(rates_str) -
1172 (p - rates_str), "%02X ",
1173 network->rates[i]);
1174#endif
1175 if (ieee80211_is_ofdm_rate
1176 (info_element->data[i])) {
1177 network->flags |= NETWORK_HAS_OFDM;
1178 if (info_element->data[i] &
1179 IEEE80211_BASIC_RATE_MASK)
1180 network->flags &=
1181 ~NETWORK_HAS_CCK;
1182 }
1183 }
1184
1185 IEEE80211_DEBUG_MGMT("MFIE_TYPE_RATES: '%s' (%d)\n",
1186 rates_str, network->rates_len);
1187 break;
1188
1189 case MFIE_TYPE_RATES_EX:
1190#ifdef CONFIG_IEEE80211_DEBUG
1191 p = rates_str;
1192#endif
1193 network->rates_ex_len = min(info_element->len,
1194 MAX_RATES_EX_LENGTH);
1195 for (i = 0; i < network->rates_ex_len; i++) {
1196 network->rates_ex[i] = info_element->data[i];
1197#ifdef CONFIG_IEEE80211_DEBUG
1198 p += snprintf(p, sizeof(rates_str) -
1199 (p - rates_str), "%02X ",
1200 network->rates[i]);
1201#endif
1202 if (ieee80211_is_ofdm_rate
1203 (info_element->data[i])) {
1204 network->flags |= NETWORK_HAS_OFDM;
1205 if (info_element->data[i] &
1206 IEEE80211_BASIC_RATE_MASK)
1207 network->flags &=
1208 ~NETWORK_HAS_CCK;
1209 }
1210 }
1211
1212 IEEE80211_DEBUG_MGMT("MFIE_TYPE_RATES_EX: '%s' (%d)\n",
1213 rates_str, network->rates_ex_len);
1214 break;
1215
1216 case MFIE_TYPE_DS_SET:
1217 IEEE80211_DEBUG_MGMT("MFIE_TYPE_DS_SET: %d\n",
1218 info_element->data[0]);
1219 network->channel = info_element->data[0];
1220 break;
1221
1222 case MFIE_TYPE_FH_SET:
1223 IEEE80211_DEBUG_MGMT("MFIE_TYPE_FH_SET: ignored\n");
1224 break;
1225
1226 case MFIE_TYPE_CF_SET:
1227 IEEE80211_DEBUG_MGMT("MFIE_TYPE_CF_SET: ignored\n");
1228 break;
1229
1230 case MFIE_TYPE_TIM:
1231 network->tim.tim_count = info_element->data[0];
1232 network->tim.tim_period = info_element->data[1];
1233 IEEE80211_DEBUG_MGMT("MFIE_TYPE_TIM: partially ignored\n");
1234 break;
1235
1236 case MFIE_TYPE_ERP_INFO:
1237 network->erp_value = info_element->data[0];
1238 network->flags |= NETWORK_HAS_ERP_VALUE;
1239 IEEE80211_DEBUG_MGMT("MFIE_TYPE_ERP_SET: %d\n",
1240 network->erp_value);
1241 break;
1242
1243 case MFIE_TYPE_IBSS_SET:
1244 network->atim_window = info_element->data[0];
1245 IEEE80211_DEBUG_MGMT("MFIE_TYPE_IBSS_SET: %d\n",
1246 network->atim_window);
1247 break;
1248
1249 case MFIE_TYPE_CHALLENGE:
1250 IEEE80211_DEBUG_MGMT("MFIE_TYPE_CHALLENGE: ignored\n");
1251 break;
1252
1253 case MFIE_TYPE_GENERIC:
1254 IEEE80211_DEBUG_MGMT("MFIE_TYPE_GENERIC: %d bytes\n",
1255 info_element->len);
1256 if (!ieee80211_parse_qos_info_param_IE(info_element,
1257 network))
1258 break;
1259
1260 if (info_element->len >= 4 &&
1261 info_element->data[0] == 0x00 &&
1262 info_element->data[1] == 0x50 &&
1263 info_element->data[2] == 0xf2 &&
1264 info_element->data[3] == 0x01) {
1265 network->wpa_ie_len = min(info_element->len + 2,
1266 MAX_WPA_IE_LEN);
1267 memcpy(network->wpa_ie, info_element,
1268 network->wpa_ie_len);
1269 }
1270 break;
1271
1272 case MFIE_TYPE_RSN:
1273 IEEE80211_DEBUG_MGMT("MFIE_TYPE_RSN: %d bytes\n",
1274 info_element->len);
1275 network->rsn_ie_len = min(info_element->len + 2,
1276 MAX_WPA_IE_LEN);
1277 memcpy(network->rsn_ie, info_element,
1278 network->rsn_ie_len);
1279 break;
1280
1281 case MFIE_TYPE_QOS_PARAMETER:
1282 printk(KERN_ERR
1283 "QoS Error need to parse QOS_PARAMETER IE\n");
1284 break;
1285 /* 802.11h */
1286 case MFIE_TYPE_POWER_CONSTRAINT:
1287 network->power_constraint = info_element->data[0];
1288 network->flags |= NETWORK_HAS_POWER_CONSTRAINT;
1289 break;
1290
1291 case MFIE_TYPE_CSA:
1292 network->power_constraint = info_element->data[0];
1293 network->flags |= NETWORK_HAS_CSA;
1294 break;
1295
1296 case MFIE_TYPE_QUIET:
1297 network->quiet.count = info_element->data[0];
1298 network->quiet.period = info_element->data[1];
1299 network->quiet.duration = info_element->data[2];
1300 network->quiet.offset = info_element->data[3];
1301 network->flags |= NETWORK_HAS_QUIET;
1302 break;
1303
1304 case MFIE_TYPE_IBSS_DFS:
1305 if (network->ibss_dfs)
1306 break;
1307 network->ibss_dfs = kmemdup(info_element->data,
1308 info_element->len,
1309 GFP_ATOMIC);
1310 if (!network->ibss_dfs)
1311 return 1;
1312 network->flags |= NETWORK_HAS_IBSS_DFS;
1313 break;
1314
1315 case MFIE_TYPE_TPC_REPORT:
1316 network->tpc_report.transmit_power =
1317 info_element->data[0];
1318 network->tpc_report.link_margin = info_element->data[1];
1319 network->flags |= NETWORK_HAS_TPC_REPORT;
1320 break;
1321
1322 default:
1323 IEEE80211_DEBUG_MGMT
1324 ("Unsupported info element: %s (%d)\n",
1325 get_info_element_string(info_element->id),
1326 info_element->id);
1327 break;
1328 }
1329
1330 length -= sizeof(*info_element) + info_element->len;
1331 info_element =
1332 (struct ieee80211_info_element *)&info_element->
1333 data[info_element->len];
1334 }
1335
1336 return 0;
1337}
1338
1339static int ieee80211_handle_assoc_resp(struct ieee80211_device *ieee, struct ieee80211_assoc_response
1340 *frame, struct ieee80211_rx_stats *stats)
1341{
1342 struct ieee80211_network network_resp = {
1343 .ibss_dfs = NULL,
1344 };
1345 struct ieee80211_network *network = &network_resp;
1346 struct net_device *dev = ieee->dev;
1347
1348 network->flags = 0;
1349 network->qos_data.active = 0;
1350 network->qos_data.supported = 0;
1351 network->qos_data.param_count = 0;
1352 network->qos_data.old_param_count = 0;
1353
1354 //network->atim_window = le16_to_cpu(frame->aid) & (0x3FFF);
1355 network->atim_window = le16_to_cpu(frame->aid);
1356 network->listen_interval = le16_to_cpu(frame->status);
1357 memcpy(network->bssid, frame->header.addr3, ETH_ALEN);
1358 network->capability = le16_to_cpu(frame->capability);
1359 network->last_scanned = jiffies;
1360 network->rates_len = network->rates_ex_len = 0;
1361 network->last_associate = 0;
1362 network->ssid_len = 0;
1363 network->erp_value =
1364 (network->capability & WLAN_CAPABILITY_IBSS) ? 0x3 : 0x0;
1365
1366 if (stats->freq == IEEE80211_52GHZ_BAND) {
1367 /* for A band (No DS info) */
1368 network->channel = stats->received_channel;
1369 } else
1370 network->flags |= NETWORK_HAS_CCK;
1371
1372 network->wpa_ie_len = 0;
1373 network->rsn_ie_len = 0;
1374
1375 if (ieee80211_parse_info_param
1376 (frame->info_element, stats->len - sizeof(*frame), network))
1377 return 1;
1378
1379 network->mode = 0;
1380 if (stats->freq == IEEE80211_52GHZ_BAND)
1381 network->mode = IEEE_A;
1382 else {
1383 if (network->flags & NETWORK_HAS_OFDM)
1384 network->mode |= IEEE_G;
1385 if (network->flags & NETWORK_HAS_CCK)
1386 network->mode |= IEEE_B;
1387 }
1388
1389 memcpy(&network->stats, stats, sizeof(network->stats));
1390
1391 if (ieee->handle_assoc_response != NULL)
1392 ieee->handle_assoc_response(dev, frame, network);
1393
1394 return 0;
1395}
1396
1397/***************************************************/
1398
1399static int ieee80211_network_init(struct ieee80211_device *ieee, struct ieee80211_probe_response
1400 *beacon,
1401 struct ieee80211_network *network,
1402 struct ieee80211_rx_stats *stats)
1403{
1404 DECLARE_SSID_BUF(ssid);
1405
1406 network->qos_data.active = 0;
1407 network->qos_data.supported = 0;
1408 network->qos_data.param_count = 0;
1409 network->qos_data.old_param_count = 0;
1410
1411 /* Pull out fixed field data */
1412 memcpy(network->bssid, beacon->header.addr3, ETH_ALEN);
1413 network->capability = le16_to_cpu(beacon->capability);
1414 network->last_scanned = jiffies;
1415 network->time_stamp[0] = le32_to_cpu(beacon->time_stamp[0]);
1416 network->time_stamp[1] = le32_to_cpu(beacon->time_stamp[1]);
1417 network->beacon_interval = le16_to_cpu(beacon->beacon_interval);
1418 /* Where to pull this? beacon->listen_interval; */
1419 network->listen_interval = 0x0A;
1420 network->rates_len = network->rates_ex_len = 0;
1421 network->last_associate = 0;
1422 network->ssid_len = 0;
1423 network->flags = 0;
1424 network->atim_window = 0;
1425 network->erp_value = (network->capability & WLAN_CAPABILITY_IBSS) ?
1426 0x3 : 0x0;
1427
1428 if (stats->freq == IEEE80211_52GHZ_BAND) {
1429 /* for A band (No DS info) */
1430 network->channel = stats->received_channel;
1431 } else
1432 network->flags |= NETWORK_HAS_CCK;
1433
1434 network->wpa_ie_len = 0;
1435 network->rsn_ie_len = 0;
1436
1437 if (ieee80211_parse_info_param
1438 (beacon->info_element, stats->len - sizeof(*beacon), network))
1439 return 1;
1440
1441 network->mode = 0;
1442 if (stats->freq == IEEE80211_52GHZ_BAND)
1443 network->mode = IEEE_A;
1444 else {
1445 if (network->flags & NETWORK_HAS_OFDM)
1446 network->mode |= IEEE_G;
1447 if (network->flags & NETWORK_HAS_CCK)
1448 network->mode |= IEEE_B;
1449 }
1450
1451 if (network->mode == 0) {
1452 IEEE80211_DEBUG_SCAN("Filtered out '%s (%pM)' "
1453 "network.\n",
1454 print_ssid(ssid, network->ssid,
1455 network->ssid_len),
1456 network->bssid);
1457 return 1;
1458 }
1459
1460 memcpy(&network->stats, stats, sizeof(network->stats));
1461
1462 return 0;
1463}
1464
1465static inline int is_same_network(struct ieee80211_network *src,
1466 struct ieee80211_network *dst)
1467{
1468 /* A network is only a duplicate if the channel, BSSID, and ESSID
1469 * all match. We treat all <hidden> with the same BSSID and channel
1470 * as one network */
1471 return ((src->ssid_len == dst->ssid_len) &&
1472 (src->channel == dst->channel) &&
1473 !compare_ether_addr(src->bssid, dst->bssid) &&
1474 !memcmp(src->ssid, dst->ssid, src->ssid_len));
1475}
1476
1477static void update_network(struct ieee80211_network *dst,
1478 struct ieee80211_network *src)
1479{
1480 int qos_active;
1481 u8 old_param;
1482
1483 ieee80211_network_reset(dst);
1484 dst->ibss_dfs = src->ibss_dfs;
1485
1486 /* We only update the statistics if they were created by receiving
1487 * the network information on the actual channel the network is on.
1488 *
1489 * This keeps beacons received on neighbor channels from bringing
1490 * down the signal level of an AP. */
1491 if (dst->channel == src->stats.received_channel)
1492 memcpy(&dst->stats, &src->stats,
1493 sizeof(struct ieee80211_rx_stats));
1494 else
1495 IEEE80211_DEBUG_SCAN("Network %pM info received "
1496 "off channel (%d vs. %d)\n", src->bssid,
1497 dst->channel, src->stats.received_channel);
1498
1499 dst->capability = src->capability;
1500 memcpy(dst->rates, src->rates, src->rates_len);
1501 dst->rates_len = src->rates_len;
1502 memcpy(dst->rates_ex, src->rates_ex, src->rates_ex_len);
1503 dst->rates_ex_len = src->rates_ex_len;
1504
1505 dst->mode = src->mode;
1506 dst->flags = src->flags;
1507 dst->time_stamp[0] = src->time_stamp[0];
1508 dst->time_stamp[1] = src->time_stamp[1];
1509
1510 dst->beacon_interval = src->beacon_interval;
1511 dst->listen_interval = src->listen_interval;
1512 dst->atim_window = src->atim_window;
1513 dst->erp_value = src->erp_value;
1514 dst->tim = src->tim;
1515
1516 memcpy(dst->wpa_ie, src->wpa_ie, src->wpa_ie_len);
1517 dst->wpa_ie_len = src->wpa_ie_len;
1518 memcpy(dst->rsn_ie, src->rsn_ie, src->rsn_ie_len);
1519 dst->rsn_ie_len = src->rsn_ie_len;
1520
1521 dst->last_scanned = jiffies;
1522 qos_active = src->qos_data.active;
1523 old_param = dst->qos_data.old_param_count;
1524 if (dst->flags & NETWORK_HAS_QOS_MASK)
1525 memcpy(&dst->qos_data, &src->qos_data,
1526 sizeof(struct ieee80211_qos_data));
1527 else {
1528 dst->qos_data.supported = src->qos_data.supported;
1529 dst->qos_data.param_count = src->qos_data.param_count;
1530 }
1531
1532 if (dst->qos_data.supported == 1) {
1533 if (dst->ssid_len)
1534 IEEE80211_DEBUG_QOS
1535 ("QoS the network %s is QoS supported\n",
1536 dst->ssid);
1537 else
1538 IEEE80211_DEBUG_QOS
1539 ("QoS the network is QoS supported\n");
1540 }
1541 dst->qos_data.active = qos_active;
1542 dst->qos_data.old_param_count = old_param;
1543
1544 /* dst->last_associate is not overwritten */
1545}
1546
1547static inline int is_beacon(__le16 fc)
1548{
1549 return (WLAN_FC_GET_STYPE(le16_to_cpu(fc)) == IEEE80211_STYPE_BEACON);
1550}
1551
1552static void ieee80211_process_probe_response(struct ieee80211_device
1553 *ieee, struct
1554 ieee80211_probe_response
1555 *beacon, struct ieee80211_rx_stats
1556 *stats)
1557{
1558 struct net_device *dev = ieee->dev;
1559 struct ieee80211_network network = {
1560 .ibss_dfs = NULL,
1561 };
1562 struct ieee80211_network *target;
1563 struct ieee80211_network *oldest = NULL;
1564#ifdef CONFIG_IEEE80211_DEBUG
1565 struct ieee80211_info_element *info_element = beacon->info_element;
1566#endif
1567 unsigned long flags;
1568 DECLARE_SSID_BUF(ssid);
1569
1570 IEEE80211_DEBUG_SCAN("'%s' (%pM"
1571 "): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n",
1572 print_ssid(ssid, info_element->data, info_element->len),
1573 beacon->header.addr3,
1574 (beacon->capability & cpu_to_le16(1 << 0xf)) ? '1' : '0',
1575 (beacon->capability & cpu_to_le16(1 << 0xe)) ? '1' : '0',
1576 (beacon->capability & cpu_to_le16(1 << 0xd)) ? '1' : '0',
1577 (beacon->capability & cpu_to_le16(1 << 0xc)) ? '1' : '0',
1578 (beacon->capability & cpu_to_le16(1 << 0xb)) ? '1' : '0',
1579 (beacon->capability & cpu_to_le16(1 << 0xa)) ? '1' : '0',
1580 (beacon->capability & cpu_to_le16(1 << 0x9)) ? '1' : '0',
1581 (beacon->capability & cpu_to_le16(1 << 0x8)) ? '1' : '0',
1582 (beacon->capability & cpu_to_le16(1 << 0x7)) ? '1' : '0',
1583 (beacon->capability & cpu_to_le16(1 << 0x6)) ? '1' : '0',
1584 (beacon->capability & cpu_to_le16(1 << 0x5)) ? '1' : '0',
1585 (beacon->capability & cpu_to_le16(1 << 0x4)) ? '1' : '0',
1586 (beacon->capability & cpu_to_le16(1 << 0x3)) ? '1' : '0',
1587 (beacon->capability & cpu_to_le16(1 << 0x2)) ? '1' : '0',
1588 (beacon->capability & cpu_to_le16(1 << 0x1)) ? '1' : '0',
1589 (beacon->capability & cpu_to_le16(1 << 0x0)) ? '1' : '0');
1590
1591 if (ieee80211_network_init(ieee, beacon, &network, stats)) {
1592 IEEE80211_DEBUG_SCAN("Dropped '%s' (%pM) via %s.\n",
1593 print_ssid(ssid, info_element->data,
1594 info_element->len),
1595 beacon->header.addr3,
1596 is_beacon(beacon->header.frame_ctl) ?
1597 "BEACON" : "PROBE RESPONSE");
1598 return;
1599 }
1600
1601 /* The network parsed correctly -- so now we scan our known networks
1602 * to see if we can find it in our list.
1603 *
1604 * NOTE: This search is definitely not optimized. Once its doing
1605 * the "right thing" we'll optimize it for efficiency if
1606 * necessary */
1607
1608 /* Search for this entry in the list and update it if it is
1609 * already there. */
1610
1611 spin_lock_irqsave(&ieee->lock, flags);
1612
1613 list_for_each_entry(target, &ieee->network_list, list) {
1614 if (is_same_network(target, &network))
1615 break;
1616
1617 if ((oldest == NULL) ||
1618 (target->last_scanned < oldest->last_scanned))
1619 oldest = target;
1620 }
1621
1622 /* If we didn't find a match, then get a new network slot to initialize
1623 * with this beacon's information */
1624 if (&target->list == &ieee->network_list) {
1625 if (list_empty(&ieee->network_free_list)) {
1626 /* If there are no more slots, expire the oldest */
1627 list_del(&oldest->list);
1628 target = oldest;
1629 IEEE80211_DEBUG_SCAN("Expired '%s' (%pM) from "
1630 "network list.\n",
1631 print_ssid(ssid, target->ssid,
1632 target->ssid_len),
1633 target->bssid);
1634 ieee80211_network_reset(target);
1635 } else {
1636 /* Otherwise just pull from the free list */
1637 target = list_entry(ieee->network_free_list.next,
1638 struct ieee80211_network, list);
1639 list_del(ieee->network_free_list.next);
1640 }
1641
1642#ifdef CONFIG_IEEE80211_DEBUG
1643 IEEE80211_DEBUG_SCAN("Adding '%s' (%pM) via %s.\n",
1644 print_ssid(ssid, network.ssid,
1645 network.ssid_len),
1646 network.bssid,
1647 is_beacon(beacon->header.frame_ctl) ?
1648 "BEACON" : "PROBE RESPONSE");
1649#endif
1650 memcpy(target, &network, sizeof(*target));
1651 network.ibss_dfs = NULL;
1652 list_add_tail(&target->list, &ieee->network_list);
1653 } else {
1654 IEEE80211_DEBUG_SCAN("Updating '%s' (%pM) via %s.\n",
1655 print_ssid(ssid, target->ssid,
1656 target->ssid_len),
1657 target->bssid,
1658 is_beacon(beacon->header.frame_ctl) ?
1659 "BEACON" : "PROBE RESPONSE");
1660 update_network(target, &network);
1661 network.ibss_dfs = NULL;
1662 }
1663
1664 spin_unlock_irqrestore(&ieee->lock, flags);
1665
1666 if (is_beacon(beacon->header.frame_ctl)) {
1667 if (ieee->handle_beacon != NULL)
1668 ieee->handle_beacon(dev, beacon, target);
1669 } else {
1670 if (ieee->handle_probe_response != NULL)
1671 ieee->handle_probe_response(dev, beacon, target);
1672 }
1673}
1674
1675void ieee80211_rx_mgt(struct ieee80211_device *ieee,
1676 struct ieee80211_hdr_4addr *header,
1677 struct ieee80211_rx_stats *stats)
1678{
1679 switch (WLAN_FC_GET_STYPE(le16_to_cpu(header->frame_ctl))) {
1680 case IEEE80211_STYPE_ASSOC_RESP:
1681 IEEE80211_DEBUG_MGMT("received ASSOCIATION RESPONSE (%d)\n",
1682 WLAN_FC_GET_STYPE(le16_to_cpu
1683 (header->frame_ctl)));
1684 ieee80211_handle_assoc_resp(ieee,
1685 (struct ieee80211_assoc_response *)
1686 header, stats);
1687 break;
1688
1689 case IEEE80211_STYPE_REASSOC_RESP:
1690 IEEE80211_DEBUG_MGMT("received REASSOCIATION RESPONSE (%d)\n",
1691 WLAN_FC_GET_STYPE(le16_to_cpu
1692 (header->frame_ctl)));
1693 break;
1694
1695 case IEEE80211_STYPE_PROBE_REQ:
1696 IEEE80211_DEBUG_MGMT("received auth (%d)\n",
1697 WLAN_FC_GET_STYPE(le16_to_cpu
1698 (header->frame_ctl)));
1699
1700 if (ieee->handle_probe_request != NULL)
1701 ieee->handle_probe_request(ieee->dev,
1702 (struct
1703 ieee80211_probe_request *)
1704 header, stats);
1705 break;
1706
1707 case IEEE80211_STYPE_PROBE_RESP:
1708 IEEE80211_DEBUG_MGMT("received PROBE RESPONSE (%d)\n",
1709 WLAN_FC_GET_STYPE(le16_to_cpu
1710 (header->frame_ctl)));
1711 IEEE80211_DEBUG_SCAN("Probe response\n");
1712 ieee80211_process_probe_response(ieee,
1713 (struct
1714 ieee80211_probe_response *)
1715 header, stats);
1716 break;
1717
1718 case IEEE80211_STYPE_BEACON:
1719 IEEE80211_DEBUG_MGMT("received BEACON (%d)\n",
1720 WLAN_FC_GET_STYPE(le16_to_cpu
1721 (header->frame_ctl)));
1722 IEEE80211_DEBUG_SCAN("Beacon\n");
1723 ieee80211_process_probe_response(ieee,
1724 (struct
1725 ieee80211_probe_response *)
1726 header, stats);
1727 break;
1728 case IEEE80211_STYPE_AUTH:
1729
1730 IEEE80211_DEBUG_MGMT("received auth (%d)\n",
1731 WLAN_FC_GET_STYPE(le16_to_cpu
1732 (header->frame_ctl)));
1733
1734 if (ieee->handle_auth != NULL)
1735 ieee->handle_auth(ieee->dev,
1736 (struct ieee80211_auth *)header);
1737 break;
1738
1739 case IEEE80211_STYPE_DISASSOC:
1740 if (ieee->handle_disassoc != NULL)
1741 ieee->handle_disassoc(ieee->dev,
1742 (struct ieee80211_disassoc *)
1743 header);
1744 break;
1745
1746 case IEEE80211_STYPE_ACTION:
1747 IEEE80211_DEBUG_MGMT("ACTION\n");
1748 if (ieee->handle_action)
1749 ieee->handle_action(ieee->dev,
1750 (struct ieee80211_action *)
1751 header, stats);
1752 break;
1753
1754 case IEEE80211_STYPE_REASSOC_REQ:
1755 IEEE80211_DEBUG_MGMT("received reassoc (%d)\n",
1756 WLAN_FC_GET_STYPE(le16_to_cpu
1757 (header->frame_ctl)));
1758
1759 IEEE80211_DEBUG_MGMT("%s: IEEE80211_REASSOC_REQ received\n",
1760 ieee->dev->name);
1761 if (ieee->handle_reassoc_request != NULL)
1762 ieee->handle_reassoc_request(ieee->dev,
1763 (struct ieee80211_reassoc_request *)
1764 header);
1765 break;
1766
1767 case IEEE80211_STYPE_ASSOC_REQ:
1768 IEEE80211_DEBUG_MGMT("received assoc (%d)\n",
1769 WLAN_FC_GET_STYPE(le16_to_cpu
1770 (header->frame_ctl)));
1771
1772 IEEE80211_DEBUG_MGMT("%s: IEEE80211_ASSOC_REQ received\n",
1773 ieee->dev->name);
1774 if (ieee->handle_assoc_request != NULL)
1775 ieee->handle_assoc_request(ieee->dev);
1776 break;
1777
1778 case IEEE80211_STYPE_DEAUTH:
1779 IEEE80211_DEBUG_MGMT("DEAUTH\n");
1780 if (ieee->handle_deauth != NULL)
1781 ieee->handle_deauth(ieee->dev,
1782 (struct ieee80211_deauth *)
1783 header);
1784 break;
1785 default:
1786 IEEE80211_DEBUG_MGMT("received UNKNOWN (%d)\n",
1787 WLAN_FC_GET_STYPE(le16_to_cpu
1788 (header->frame_ctl)));
1789 IEEE80211_DEBUG_MGMT("%s: Unknown management packet: %d\n",
1790 ieee->dev->name,
1791 WLAN_FC_GET_STYPE(le16_to_cpu
1792 (header->frame_ctl)));
1793 break;
1794 }
1795}
1796
1797EXPORT_SYMBOL_GPL(ieee80211_rx_any);
1798EXPORT_SYMBOL(ieee80211_rx_mgt);
1799EXPORT_SYMBOL(ieee80211_rx);
diff --git a/drivers/net/wireless/ipw2x00/libipw_tx.c b/drivers/net/wireless/ipw2x00/libipw_tx.c
new file mode 100644
index 000000000000..f78f57e8844a
--- /dev/null
+++ b/drivers/net/wireless/ipw2x00/libipw_tx.c
@@ -0,0 +1,546 @@
1/******************************************************************************
2
3 Copyright(c) 2003 - 2005 Intel Corporation. All rights reserved.
4
5 This program is free software; you can redistribute it and/or modify it
6 under the terms of version 2 of the GNU General Public License as
7 published by the Free Software Foundation.
8
9 This program is distributed in the hope that it will be useful, but WITHOUT
10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 more details.
13
14 You should have received a copy of the GNU General Public License along with
15 this program; if not, write to the Free Software Foundation, Inc., 59
16 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18 The full GNU General Public License is included in this distribution in the
19 file called LICENSE.
20
21 Contact Information:
22 James P. Ketrenos <ipw2100-admin@linux.intel.com>
23 Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
24
25******************************************************************************/
26#include <linux/compiler.h>
27#include <linux/errno.h>
28#include <linux/if_arp.h>
29#include <linux/in6.h>
30#include <linux/in.h>
31#include <linux/ip.h>
32#include <linux/kernel.h>
33#include <linux/module.h>
34#include <linux/netdevice.h>
35#include <linux/proc_fs.h>
36#include <linux/skbuff.h>
37#include <linux/slab.h>
38#include <linux/tcp.h>
39#include <linux/types.h>
40#include <linux/wireless.h>
41#include <linux/etherdevice.h>
42#include <asm/uaccess.h>
43
44#include <net/ieee80211.h>
45
46/*
47
48802.11 Data Frame
49
50 ,-------------------------------------------------------------------.
51Bytes | 2 | 2 | 6 | 6 | 6 | 2 | 0..2312 | 4 |
52 |------|------|---------|---------|---------|------|---------|------|
53Desc. | ctrl | dura | DA/RA | TA | SA | Sequ | Frame | fcs |
54 | | tion | (BSSID) | | | ence | data | |
55 `--------------------------------------------------| |------'
56Total: 28 non-data bytes `----.----'
57 |
58 .- 'Frame data' expands, if WEP enabled, to <----------'
59 |
60 V
61 ,-----------------------.
62Bytes | 4 | 0-2296 | 4 |
63 |-----|-----------|-----|
64Desc. | IV | Encrypted | ICV |
65 | | Packet | |
66 `-----| |-----'
67 `-----.-----'
68 |
69 .- 'Encrypted Packet' expands to
70 |
71 V
72 ,---------------------------------------------------.
73Bytes | 1 | 1 | 1 | 3 | 2 | 0-2304 |
74 |------|------|---------|----------|------|---------|
75Desc. | SNAP | SNAP | Control |Eth Tunnel| Type | IP |
76 | DSAP | SSAP | | | | Packet |
77 | 0xAA | 0xAA |0x03 (UI)|0x00-00-F8| | |
78 `----------------------------------------------------
79Total: 8 non-data bytes
80
81802.3 Ethernet Data Frame
82
83 ,-----------------------------------------.
84Bytes | 6 | 6 | 2 | Variable | 4 |
85 |-------|-------|------|-----------|------|
86Desc. | Dest. | Source| Type | IP Packet | fcs |
87 | MAC | MAC | | | |
88 `-----------------------------------------'
89Total: 18 non-data bytes
90
91In the event that fragmentation is required, the incoming payload is split into
92N parts of size ieee->fts. The first fragment contains the SNAP header and the
93remaining packets are just data.
94
95If encryption is enabled, each fragment payload size is reduced by enough space
96to add the prefix and postfix (IV and ICV totalling 8 bytes in the case of WEP)
97So if you have 1500 bytes of payload with ieee->fts set to 500 without
98encryption it will take 3 frames. With WEP it will take 4 frames as the
99payload of each frame is reduced to 492 bytes.
100
101* SKB visualization
102*
103* ,- skb->data
104* |
105* | ETHERNET HEADER ,-<-- PAYLOAD
106* | | 14 bytes from skb->data
107* | 2 bytes for Type --> ,T. | (sizeof ethhdr)
108* | | | |
109* |,-Dest.--. ,--Src.---. | | |
110* | 6 bytes| | 6 bytes | | | |
111* v | | | | | |
112* 0 | v 1 | v | v 2
113* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
114* ^ | ^ | ^ |
115* | | | | | |
116* | | | | `T' <---- 2 bytes for Type
117* | | | |
118* | | '---SNAP--' <-------- 6 bytes for SNAP
119* | |
120* `-IV--' <-------------------- 4 bytes for IV (WEP)
121*
122* SNAP HEADER
123*
124*/
125
126static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 };
127static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 };
128
129static int ieee80211_copy_snap(u8 * data, __be16 h_proto)
130{
131 struct ieee80211_snap_hdr *snap;
132 u8 *oui;
133
134 snap = (struct ieee80211_snap_hdr *)data;
135 snap->dsap = 0xaa;
136 snap->ssap = 0xaa;
137 snap->ctrl = 0x03;
138
139 if (h_proto == htons(ETH_P_AARP) || h_proto == htons(ETH_P_IPX))
140 oui = P802_1H_OUI;
141 else
142 oui = RFC1042_OUI;
143 snap->oui[0] = oui[0];
144 snap->oui[1] = oui[1];
145 snap->oui[2] = oui[2];
146
147 memcpy(data + SNAP_SIZE, &h_proto, sizeof(u16));
148
149 return SNAP_SIZE + sizeof(u16);
150}
151
152static int ieee80211_encrypt_fragment(struct ieee80211_device *ieee,
153 struct sk_buff *frag, int hdr_len)
154{
155 struct lib80211_crypt_data *crypt =
156 ieee->crypt_info.crypt[ieee->crypt_info.tx_keyidx];
157 int res;
158
159 if (crypt == NULL)
160 return -1;
161
162 /* To encrypt, frame format is:
163 * IV (4 bytes), clear payload (including SNAP), ICV (4 bytes) */
164 atomic_inc(&crypt->refcnt);
165 res = 0;
166 if (crypt->ops && crypt->ops->encrypt_mpdu)
167 res = crypt->ops->encrypt_mpdu(frag, hdr_len, crypt->priv);
168
169 atomic_dec(&crypt->refcnt);
170 if (res < 0) {
171 printk(KERN_INFO "%s: Encryption failed: len=%d.\n",
172 ieee->dev->name, frag->len);
173 ieee->ieee_stats.tx_discards++;
174 return -1;
175 }
176
177 return 0;
178}
179
180void ieee80211_txb_free(struct ieee80211_txb *txb)
181{
182 int i;
183 if (unlikely(!txb))
184 return;
185 for (i = 0; i < txb->nr_frags; i++)
186 if (txb->fragments[i])
187 dev_kfree_skb_any(txb->fragments[i]);
188 kfree(txb);
189}
190
191static struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size,
192 int headroom, gfp_t gfp_mask)
193{
194 struct ieee80211_txb *txb;
195 int i;
196 txb = kmalloc(sizeof(struct ieee80211_txb) + (sizeof(u8 *) * nr_frags),
197 gfp_mask);
198 if (!txb)
199 return NULL;
200
201 memset(txb, 0, sizeof(struct ieee80211_txb));
202 txb->nr_frags = nr_frags;
203 txb->frag_size = txb_size;
204
205 for (i = 0; i < nr_frags; i++) {
206 txb->fragments[i] = __dev_alloc_skb(txb_size + headroom,
207 gfp_mask);
208 if (unlikely(!txb->fragments[i])) {
209 i--;
210 break;
211 }
212 skb_reserve(txb->fragments[i], headroom);
213 }
214 if (unlikely(i != nr_frags)) {
215 while (i >= 0)
216 dev_kfree_skb_any(txb->fragments[i--]);
217 kfree(txb);
218 return NULL;
219 }
220 return txb;
221}
222
223static int ieee80211_classify(struct sk_buff *skb)
224{
225 struct ethhdr *eth;
226 struct iphdr *ip;
227
228 eth = (struct ethhdr *)skb->data;
229 if (eth->h_proto != htons(ETH_P_IP))
230 return 0;
231
232 ip = ip_hdr(skb);
233 switch (ip->tos & 0xfc) {
234 case 0x20:
235 return 2;
236 case 0x40:
237 return 1;
238 case 0x60:
239 return 3;
240 case 0x80:
241 return 4;
242 case 0xa0:
243 return 5;
244 case 0xc0:
245 return 6;
246 case 0xe0:
247 return 7;
248 default:
249 return 0;
250 }
251}
252
253/* Incoming skb is converted to a txb which consists of
254 * a block of 802.11 fragment packets (stored as skbs) */
255int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
256{
257 struct ieee80211_device *ieee = netdev_priv(dev);
258 struct ieee80211_txb *txb = NULL;
259 struct ieee80211_hdr_3addrqos *frag_hdr;
260 int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size,
261 rts_required;
262 unsigned long flags;
263 struct net_device_stats *stats = &ieee->stats;
264 int encrypt, host_encrypt, host_encrypt_msdu, host_build_iv;
265 __be16 ether_type;
266 int bytes, fc, hdr_len;
267 struct sk_buff *skb_frag;
268 struct ieee80211_hdr_3addrqos header = {/* Ensure zero initialized */
269 .duration_id = 0,
270 .seq_ctl = 0,
271 .qos_ctl = 0
272 };
273 u8 dest[ETH_ALEN], src[ETH_ALEN];
274 struct lib80211_crypt_data *crypt;
275 int priority = skb->priority;
276 int snapped = 0;
277
278 if (ieee->is_queue_full && (*ieee->is_queue_full) (dev, priority))
279 return NETDEV_TX_BUSY;
280
281 spin_lock_irqsave(&ieee->lock, flags);
282
283 /* If there is no driver handler to take the TXB, dont' bother
284 * creating it... */
285 if (!ieee->hard_start_xmit) {
286 printk(KERN_WARNING "%s: No xmit handler.\n", ieee->dev->name);
287 goto success;
288 }
289
290 if (unlikely(skb->len < SNAP_SIZE + sizeof(u16))) {
291 printk(KERN_WARNING "%s: skb too small (%d).\n",
292 ieee->dev->name, skb->len);
293 goto success;
294 }
295
296 ether_type = ((struct ethhdr *)skb->data)->h_proto;
297
298 crypt = ieee->crypt_info.crypt[ieee->crypt_info.tx_keyidx];
299
300 encrypt = !(ether_type == htons(ETH_P_PAE) && ieee->ieee802_1x) &&
301 ieee->sec.encrypt;
302
303 host_encrypt = ieee->host_encrypt && encrypt && crypt;
304 host_encrypt_msdu = ieee->host_encrypt_msdu && encrypt && crypt;
305 host_build_iv = ieee->host_build_iv && encrypt && crypt;
306
307 if (!encrypt && ieee->ieee802_1x &&
308 ieee->drop_unencrypted && ether_type != htons(ETH_P_PAE)) {
309 stats->tx_dropped++;
310 goto success;
311 }
312
313 /* Save source and destination addresses */
314 skb_copy_from_linear_data(skb, dest, ETH_ALEN);
315 skb_copy_from_linear_data_offset(skb, ETH_ALEN, src, ETH_ALEN);
316
317 if (host_encrypt || host_build_iv)
318 fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA |
319 IEEE80211_FCTL_PROTECTED;
320 else
321 fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA;
322
323 if (ieee->iw_mode == IW_MODE_INFRA) {
324 fc |= IEEE80211_FCTL_TODS;
325 /* To DS: Addr1 = BSSID, Addr2 = SA, Addr3 = DA */
326 memcpy(header.addr1, ieee->bssid, ETH_ALEN);
327 memcpy(header.addr2, src, ETH_ALEN);
328 memcpy(header.addr3, dest, ETH_ALEN);
329 } else if (ieee->iw_mode == IW_MODE_ADHOC) {
330 /* not From/To DS: Addr1 = DA, Addr2 = SA, Addr3 = BSSID */
331 memcpy(header.addr1, dest, ETH_ALEN);
332 memcpy(header.addr2, src, ETH_ALEN);
333 memcpy(header.addr3, ieee->bssid, ETH_ALEN);
334 }
335 hdr_len = IEEE80211_3ADDR_LEN;
336
337 if (ieee->is_qos_active && ieee->is_qos_active(dev, skb)) {
338 fc |= IEEE80211_STYPE_QOS_DATA;
339 hdr_len += 2;
340
341 skb->priority = ieee80211_classify(skb);
342 header.qos_ctl |= cpu_to_le16(skb->priority & IEEE80211_QCTL_TID);
343 }
344 header.frame_ctl = cpu_to_le16(fc);
345
346 /* Advance the SKB to the start of the payload */
347 skb_pull(skb, sizeof(struct ethhdr));
348
349 /* Determine total amount of storage required for TXB packets */
350 bytes = skb->len + SNAP_SIZE + sizeof(u16);
351
352 /* Encrypt msdu first on the whole data packet. */
353 if ((host_encrypt || host_encrypt_msdu) &&
354 crypt && crypt->ops && crypt->ops->encrypt_msdu) {
355 int res = 0;
356 int len = bytes + hdr_len + crypt->ops->extra_msdu_prefix_len +
357 crypt->ops->extra_msdu_postfix_len;
358 struct sk_buff *skb_new = dev_alloc_skb(len);
359
360 if (unlikely(!skb_new))
361 goto failed;
362
363 skb_reserve(skb_new, crypt->ops->extra_msdu_prefix_len);
364 memcpy(skb_put(skb_new, hdr_len), &header, hdr_len);
365 snapped = 1;
366 ieee80211_copy_snap(skb_put(skb_new, SNAP_SIZE + sizeof(u16)),
367 ether_type);
368 skb_copy_from_linear_data(skb, skb_put(skb_new, skb->len), skb->len);
369 res = crypt->ops->encrypt_msdu(skb_new, hdr_len, crypt->priv);
370 if (res < 0) {
371 IEEE80211_ERROR("msdu encryption failed\n");
372 dev_kfree_skb_any(skb_new);
373 goto failed;
374 }
375 dev_kfree_skb_any(skb);
376 skb = skb_new;
377 bytes += crypt->ops->extra_msdu_prefix_len +
378 crypt->ops->extra_msdu_postfix_len;
379 skb_pull(skb, hdr_len);
380 }
381
382 if (host_encrypt || ieee->host_open_frag) {
383 /* Determine fragmentation size based on destination (multicast
384 * and broadcast are not fragmented) */
385 if (is_multicast_ether_addr(dest) ||
386 is_broadcast_ether_addr(dest))
387 frag_size = MAX_FRAG_THRESHOLD;
388 else
389 frag_size = ieee->fts;
390
391 /* Determine amount of payload per fragment. Regardless of if
392 * this stack is providing the full 802.11 header, one will
393 * eventually be affixed to this fragment -- so we must account
394 * for it when determining the amount of payload space. */
395 bytes_per_frag = frag_size - hdr_len;
396 if (ieee->config &
397 (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
398 bytes_per_frag -= IEEE80211_FCS_LEN;
399
400 /* Each fragment may need to have room for encryptiong
401 * pre/postfix */
402 if (host_encrypt)
403 bytes_per_frag -= crypt->ops->extra_mpdu_prefix_len +
404 crypt->ops->extra_mpdu_postfix_len;
405
406 /* Number of fragments is the total
407 * bytes_per_frag / payload_per_fragment */
408 nr_frags = bytes / bytes_per_frag;
409 bytes_last_frag = bytes % bytes_per_frag;
410 if (bytes_last_frag)
411 nr_frags++;
412 else
413 bytes_last_frag = bytes_per_frag;
414 } else {
415 nr_frags = 1;
416 bytes_per_frag = bytes_last_frag = bytes;
417 frag_size = bytes + hdr_len;
418 }
419
420 rts_required = (frag_size > ieee->rts
421 && ieee->config & CFG_IEEE80211_RTS);
422 if (rts_required)
423 nr_frags++;
424
425 /* When we allocate the TXB we allocate enough space for the reserve
426 * and full fragment bytes (bytes_per_frag doesn't include prefix,
427 * postfix, header, FCS, etc.) */
428 txb = ieee80211_alloc_txb(nr_frags, frag_size,
429 ieee->tx_headroom, GFP_ATOMIC);
430 if (unlikely(!txb)) {
431 printk(KERN_WARNING "%s: Could not allocate TXB\n",
432 ieee->dev->name);
433 goto failed;
434 }
435 txb->encrypted = encrypt;
436 if (host_encrypt)
437 txb->payload_size = frag_size * (nr_frags - 1) +
438 bytes_last_frag;
439 else
440 txb->payload_size = bytes;
441
442 if (rts_required) {
443 skb_frag = txb->fragments[0];
444 frag_hdr =
445 (struct ieee80211_hdr_3addrqos *)skb_put(skb_frag, hdr_len);
446
447 /*
448 * Set header frame_ctl to the RTS.
449 */
450 header.frame_ctl =
451 cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS);
452 memcpy(frag_hdr, &header, hdr_len);
453
454 /*
455 * Restore header frame_ctl to the original data setting.
456 */
457 header.frame_ctl = cpu_to_le16(fc);
458
459 if (ieee->config &
460 (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
461 skb_put(skb_frag, 4);
462
463 txb->rts_included = 1;
464 i = 1;
465 } else
466 i = 0;
467
468 for (; i < nr_frags; i++) {
469 skb_frag = txb->fragments[i];
470
471 if (host_encrypt || host_build_iv)
472 skb_reserve(skb_frag,
473 crypt->ops->extra_mpdu_prefix_len);
474
475 frag_hdr =
476 (struct ieee80211_hdr_3addrqos *)skb_put(skb_frag, hdr_len);
477 memcpy(frag_hdr, &header, hdr_len);
478
479 /* If this is not the last fragment, then add the MOREFRAGS
480 * bit to the frame control */
481 if (i != nr_frags - 1) {
482 frag_hdr->frame_ctl =
483 cpu_to_le16(fc | IEEE80211_FCTL_MOREFRAGS);
484 bytes = bytes_per_frag;
485 } else {
486 /* The last fragment takes the remaining length */
487 bytes = bytes_last_frag;
488 }
489
490 if (i == 0 && !snapped) {
491 ieee80211_copy_snap(skb_put
492 (skb_frag, SNAP_SIZE + sizeof(u16)),
493 ether_type);
494 bytes -= SNAP_SIZE + sizeof(u16);
495 }
496
497 skb_copy_from_linear_data(skb, skb_put(skb_frag, bytes), bytes);
498
499 /* Advance the SKB... */
500 skb_pull(skb, bytes);
501
502 /* Encryption routine will move the header forward in order
503 * to insert the IV between the header and the payload */
504 if (host_encrypt)
505 ieee80211_encrypt_fragment(ieee, skb_frag, hdr_len);
506 else if (host_build_iv) {
507 atomic_inc(&crypt->refcnt);
508 if (crypt->ops->build_iv)
509 crypt->ops->build_iv(skb_frag, hdr_len,
510 ieee->sec.keys[ieee->sec.active_key],
511 ieee->sec.key_sizes[ieee->sec.active_key],
512 crypt->priv);
513 atomic_dec(&crypt->refcnt);
514 }
515
516 if (ieee->config &
517 (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
518 skb_put(skb_frag, 4);
519 }
520
521 success:
522 spin_unlock_irqrestore(&ieee->lock, flags);
523
524 dev_kfree_skb_any(skb);
525
526 if (txb) {
527 int ret = (*ieee->hard_start_xmit) (txb, dev, priority);
528 if (ret == 0) {
529 stats->tx_packets++;
530 stats->tx_bytes += txb->payload_size;
531 return 0;
532 }
533
534 ieee80211_txb_free(txb);
535 }
536
537 return 0;
538
539 failed:
540 spin_unlock_irqrestore(&ieee->lock, flags);
541 netif_stop_queue(dev);
542 stats->tx_errors++;
543 return 1;
544}
545
546EXPORT_SYMBOL(ieee80211_txb_free);
diff --git a/drivers/net/wireless/ipw2x00/libipw_wx.c b/drivers/net/wireless/ipw2x00/libipw_wx.c
new file mode 100644
index 000000000000..31ea3abfc327
--- /dev/null
+++ b/drivers/net/wireless/ipw2x00/libipw_wx.c
@@ -0,0 +1,760 @@
1/******************************************************************************
2
3 Copyright(c) 2004-2005 Intel Corporation. All rights reserved.
4
5 Portions of this file are based on the WEP enablement code provided by the
6 Host AP project hostap-drivers v0.1.3
7 Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
8 <j@w1.fi>
9 Copyright (c) 2002-2003, Jouni Malinen <j@w1.fi>
10
11 This program is free software; you can redistribute it and/or modify it
12 under the terms of version 2 of the GNU General Public License as
13 published by the Free Software Foundation.
14
15 This program is distributed in the hope that it will be useful, but WITHOUT
16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
18 more details.
19
20 You should have received a copy of the GNU General Public License along with
21 this program; if not, write to the Free Software Foundation, Inc., 59
22 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23
24 The full GNU General Public License is included in this distribution in the
25 file called LICENSE.
26
27 Contact Information:
28 James P. Ketrenos <ipw2100-admin@linux.intel.com>
29 Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30
31******************************************************************************/
32
33#include <linux/kmod.h>
34#include <linux/module.h>
35#include <linux/jiffies.h>
36
37#include <net/lib80211.h>
38#include <net/ieee80211.h>
39#include <linux/wireless.h>
40
41static const char *ieee80211_modes[] = {
42 "?", "a", "b", "ab", "g", "ag", "bg", "abg"
43};
44
45#define MAX_CUSTOM_LEN 64
46static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
47 char *start, char *stop,
48 struct ieee80211_network *network,
49 struct iw_request_info *info)
50{
51 char custom[MAX_CUSTOM_LEN];
52 char *p;
53 struct iw_event iwe;
54 int i, j;
55 char *current_val; /* For rates */
56 u8 rate;
57
58 /* First entry *MUST* be the AP MAC address */
59 iwe.cmd = SIOCGIWAP;
60 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
61 memcpy(iwe.u.ap_addr.sa_data, network->bssid, ETH_ALEN);
62 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_ADDR_LEN);
63
64 /* Remaining entries will be displayed in the order we provide them */
65
66 /* Add the ESSID */
67 iwe.cmd = SIOCGIWESSID;
68 iwe.u.data.flags = 1;
69 iwe.u.data.length = min(network->ssid_len, (u8) 32);
70 start = iwe_stream_add_point(info, start, stop,
71 &iwe, network->ssid);
72
73 /* Add the protocol name */
74 iwe.cmd = SIOCGIWNAME;
75 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11%s",
76 ieee80211_modes[network->mode]);
77 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_CHAR_LEN);
78
79 /* Add mode */
80 iwe.cmd = SIOCGIWMODE;
81 if (network->capability & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)) {
82 if (network->capability & WLAN_CAPABILITY_ESS)
83 iwe.u.mode = IW_MODE_MASTER;
84 else
85 iwe.u.mode = IW_MODE_ADHOC;
86
87 start = iwe_stream_add_event(info, start, stop,
88 &iwe, IW_EV_UINT_LEN);
89 }
90
91 /* Add channel and frequency */
92 /* Note : userspace automatically computes channel using iwrange */
93 iwe.cmd = SIOCGIWFREQ;
94 iwe.u.freq.m = ieee80211_channel_to_freq(ieee, network->channel);
95 iwe.u.freq.e = 6;
96 iwe.u.freq.i = 0;
97 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_FREQ_LEN);
98
99 /* Add encryption capability */
100 iwe.cmd = SIOCGIWENCODE;
101 if (network->capability & WLAN_CAPABILITY_PRIVACY)
102 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
103 else
104 iwe.u.data.flags = IW_ENCODE_DISABLED;
105 iwe.u.data.length = 0;
106 start = iwe_stream_add_point(info, start, stop,
107 &iwe, network->ssid);
108
109 /* Add basic and extended rates */
110 /* Rate : stuffing multiple values in a single event require a bit
111 * more of magic - Jean II */
112 current_val = start + iwe_stream_lcp_len(info);
113 iwe.cmd = SIOCGIWRATE;
114 /* Those two flags are ignored... */
115 iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
116
117 for (i = 0, j = 0; i < network->rates_len;) {
118 if (j < network->rates_ex_len &&
119 ((network->rates_ex[j] & 0x7F) <
120 (network->rates[i] & 0x7F)))
121 rate = network->rates_ex[j++] & 0x7F;
122 else
123 rate = network->rates[i++] & 0x7F;
124 /* Bit rate given in 500 kb/s units (+ 0x80) */
125 iwe.u.bitrate.value = ((rate & 0x7f) * 500000);
126 /* Add new value to event */
127 current_val = iwe_stream_add_value(info, start, current_val,
128 stop, &iwe, IW_EV_PARAM_LEN);
129 }
130 for (; j < network->rates_ex_len; j++) {
131 rate = network->rates_ex[j] & 0x7F;
132 /* Bit rate given in 500 kb/s units (+ 0x80) */
133 iwe.u.bitrate.value = ((rate & 0x7f) * 500000);
134 /* Add new value to event */
135 current_val = iwe_stream_add_value(info, start, current_val,
136 stop, &iwe, IW_EV_PARAM_LEN);
137 }
138 /* Check if we added any rate */
139 if ((current_val - start) > iwe_stream_lcp_len(info))
140 start = current_val;
141
142 /* Add quality statistics */
143 iwe.cmd = IWEVQUAL;
144 iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED |
145 IW_QUAL_NOISE_UPDATED;
146
147 if (!(network->stats.mask & IEEE80211_STATMASK_RSSI)) {
148 iwe.u.qual.updated |= IW_QUAL_QUAL_INVALID |
149 IW_QUAL_LEVEL_INVALID;
150 iwe.u.qual.qual = 0;
151 } else {
152 if (ieee->perfect_rssi == ieee->worst_rssi)
153 iwe.u.qual.qual = 100;
154 else
155 iwe.u.qual.qual =
156 (100 *
157 (ieee->perfect_rssi - ieee->worst_rssi) *
158 (ieee->perfect_rssi - ieee->worst_rssi) -
159 (ieee->perfect_rssi - network->stats.rssi) *
160 (15 * (ieee->perfect_rssi - ieee->worst_rssi) +
161 62 * (ieee->perfect_rssi -
162 network->stats.rssi))) /
163 ((ieee->perfect_rssi -
164 ieee->worst_rssi) * (ieee->perfect_rssi -
165 ieee->worst_rssi));
166 if (iwe.u.qual.qual > 100)
167 iwe.u.qual.qual = 100;
168 else if (iwe.u.qual.qual < 1)
169 iwe.u.qual.qual = 0;
170 }
171
172 if (!(network->stats.mask & IEEE80211_STATMASK_NOISE)) {
173 iwe.u.qual.updated |= IW_QUAL_NOISE_INVALID;
174 iwe.u.qual.noise = 0;
175 } else {
176 iwe.u.qual.noise = network->stats.noise;
177 }
178
179 if (!(network->stats.mask & IEEE80211_STATMASK_SIGNAL)) {
180 iwe.u.qual.updated |= IW_QUAL_LEVEL_INVALID;
181 iwe.u.qual.level = 0;
182 } else {
183 iwe.u.qual.level = network->stats.signal;
184 }
185
186 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN);
187
188 iwe.cmd = IWEVCUSTOM;
189 p = custom;
190
191 iwe.u.data.length = p - custom;
192 if (iwe.u.data.length)
193 start = iwe_stream_add_point(info, start, stop, &iwe, custom);
194
195 memset(&iwe, 0, sizeof(iwe));
196 if (network->wpa_ie_len) {
197 char buf[MAX_WPA_IE_LEN];
198 memcpy(buf, network->wpa_ie, network->wpa_ie_len);
199 iwe.cmd = IWEVGENIE;
200 iwe.u.data.length = network->wpa_ie_len;
201 start = iwe_stream_add_point(info, start, stop, &iwe, buf);
202 }
203
204 memset(&iwe, 0, sizeof(iwe));
205 if (network->rsn_ie_len) {
206 char buf[MAX_WPA_IE_LEN];
207 memcpy(buf, network->rsn_ie, network->rsn_ie_len);
208 iwe.cmd = IWEVGENIE;
209 iwe.u.data.length = network->rsn_ie_len;
210 start = iwe_stream_add_point(info, start, stop, &iwe, buf);
211 }
212
213 /* Add EXTRA: Age to display seconds since last beacon/probe response
214 * for given network. */
215 iwe.cmd = IWEVCUSTOM;
216 p = custom;
217 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
218 " Last beacon: %dms ago",
219 jiffies_to_msecs(jiffies - network->last_scanned));
220 iwe.u.data.length = p - custom;
221 if (iwe.u.data.length)
222 start = iwe_stream_add_point(info, start, stop, &iwe, custom);
223
224 /* Add spectrum management information */
225 iwe.cmd = -1;
226 p = custom;
227 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), " Channel flags: ");
228
229 if (ieee80211_get_channel_flags(ieee, network->channel) &
230 IEEE80211_CH_INVALID) {
231 iwe.cmd = IWEVCUSTOM;
232 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), "INVALID ");
233 }
234
235 if (ieee80211_get_channel_flags(ieee, network->channel) &
236 IEEE80211_CH_RADAR_DETECT) {
237 iwe.cmd = IWEVCUSTOM;
238 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), "DFS ");
239 }
240
241 if (iwe.cmd == IWEVCUSTOM) {
242 iwe.u.data.length = p - custom;
243 start = iwe_stream_add_point(info, start, stop, &iwe, custom);
244 }
245
246 return start;
247}
248
249#define SCAN_ITEM_SIZE 128
250
251int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
252 struct iw_request_info *info,
253 union iwreq_data *wrqu, char *extra)
254{
255 struct ieee80211_network *network;
256 unsigned long flags;
257 int err = 0;
258
259 char *ev = extra;
260 char *stop = ev + wrqu->data.length;
261 int i = 0;
262 DECLARE_SSID_BUF(ssid);
263
264 IEEE80211_DEBUG_WX("Getting scan\n");
265
266 spin_lock_irqsave(&ieee->lock, flags);
267
268 list_for_each_entry(network, &ieee->network_list, list) {
269 i++;
270 if (stop - ev < SCAN_ITEM_SIZE) {
271 err = -E2BIG;
272 break;
273 }
274
275 if (ieee->scan_age == 0 ||
276 time_after(network->last_scanned + ieee->scan_age, jiffies))
277 ev = ieee80211_translate_scan(ieee, ev, stop, network,
278 info);
279 else
280 IEEE80211_DEBUG_SCAN("Not showing network '%s ("
281 "%pM)' due to age (%dms).\n",
282 print_ssid(ssid, network->ssid,
283 network->ssid_len),
284 network->bssid,
285 jiffies_to_msecs(jiffies -
286 network->
287 last_scanned));
288 }
289
290 spin_unlock_irqrestore(&ieee->lock, flags);
291
292 wrqu->data.length = ev - extra;
293 wrqu->data.flags = 0;
294
295 IEEE80211_DEBUG_WX("exit: %d networks returned.\n", i);
296
297 return err;
298}
299
300int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
301 struct iw_request_info *info,
302 union iwreq_data *wrqu, char *keybuf)
303{
304 struct iw_point *erq = &(wrqu->encoding);
305 struct net_device *dev = ieee->dev;
306 struct ieee80211_security sec = {
307 .flags = 0
308 };
309 int i, key, key_provided, len;
310 struct lib80211_crypt_data **crypt;
311 int host_crypto = ieee->host_encrypt || ieee->host_decrypt || ieee->host_build_iv;
312 DECLARE_SSID_BUF(ssid);
313
314 IEEE80211_DEBUG_WX("SET_ENCODE\n");
315
316 key = erq->flags & IW_ENCODE_INDEX;
317 if (key) {
318 if (key > WEP_KEYS)
319 return -EINVAL;
320 key--;
321 key_provided = 1;
322 } else {
323 key_provided = 0;
324 key = ieee->crypt_info.tx_keyidx;
325 }
326
327 IEEE80211_DEBUG_WX("Key: %d [%s]\n", key, key_provided ?
328 "provided" : "default");
329
330 crypt = &ieee->crypt_info.crypt[key];
331
332 if (erq->flags & IW_ENCODE_DISABLED) {
333 if (key_provided && *crypt) {
334 IEEE80211_DEBUG_WX("Disabling encryption on key %d.\n",
335 key);
336 lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt);
337 } else
338 IEEE80211_DEBUG_WX("Disabling encryption.\n");
339
340 /* Check all the keys to see if any are still configured,
341 * and if no key index was provided, de-init them all */
342 for (i = 0; i < WEP_KEYS; i++) {
343 if (ieee->crypt_info.crypt[i] != NULL) {
344 if (key_provided)
345 break;
346 lib80211_crypt_delayed_deinit(&ieee->crypt_info,
347 &ieee->crypt_info.crypt[i]);
348 }
349 }
350
351 if (i == WEP_KEYS) {
352 sec.enabled = 0;
353 sec.encrypt = 0;
354 sec.level = SEC_LEVEL_0;
355 sec.flags |= SEC_ENABLED | SEC_LEVEL | SEC_ENCRYPT;
356 }
357
358 goto done;
359 }
360
361 sec.enabled = 1;
362 sec.encrypt = 1;
363 sec.flags |= SEC_ENABLED | SEC_ENCRYPT;
364
365 if (*crypt != NULL && (*crypt)->ops != NULL &&
366 strcmp((*crypt)->ops->name, "WEP") != 0) {
367 /* changing to use WEP; deinit previously used algorithm
368 * on this key */
369 lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt);
370 }
371
372 if (*crypt == NULL && host_crypto) {
373 struct lib80211_crypt_data *new_crypt;
374
375 /* take WEP into use */
376 new_crypt = kzalloc(sizeof(struct lib80211_crypt_data),
377 GFP_KERNEL);
378 if (new_crypt == NULL)
379 return -ENOMEM;
380 new_crypt->ops = lib80211_get_crypto_ops("WEP");
381 if (!new_crypt->ops) {
382 request_module("lib80211_crypt_wep");
383 new_crypt->ops = lib80211_get_crypto_ops("WEP");
384 }
385
386 if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
387 new_crypt->priv = new_crypt->ops->init(key);
388
389 if (!new_crypt->ops || !new_crypt->priv) {
390 kfree(new_crypt);
391 new_crypt = NULL;
392
393 printk(KERN_WARNING "%s: could not initialize WEP: "
394 "load module lib80211_crypt_wep\n", dev->name);
395 return -EOPNOTSUPP;
396 }
397 *crypt = new_crypt;
398 }
399
400 /* If a new key was provided, set it up */
401 if (erq->length > 0) {
402#ifdef CONFIG_IEEE80211_DEBUG
403 DECLARE_SSID_BUF(ssid);
404#endif
405
406 len = erq->length <= 5 ? 5 : 13;
407 memcpy(sec.keys[key], keybuf, erq->length);
408 if (len > erq->length)
409 memset(sec.keys[key] + erq->length, 0,
410 len - erq->length);
411 IEEE80211_DEBUG_WX("Setting key %d to '%s' (%d:%d bytes)\n",
412 key, print_ssid(ssid, sec.keys[key], len),
413 erq->length, len);
414 sec.key_sizes[key] = len;
415 if (*crypt)
416 (*crypt)->ops->set_key(sec.keys[key], len, NULL,
417 (*crypt)->priv);
418 sec.flags |= (1 << key);
419 /* This ensures a key will be activated if no key is
420 * explicitly set */
421 if (key == sec.active_key)
422 sec.flags |= SEC_ACTIVE_KEY;
423
424 } else {
425 if (host_crypto) {
426 len = (*crypt)->ops->get_key(sec.keys[key], WEP_KEY_LEN,
427 NULL, (*crypt)->priv);
428 if (len == 0) {
429 /* Set a default key of all 0 */
430 IEEE80211_DEBUG_WX("Setting key %d to all "
431 "zero.\n", key);
432 memset(sec.keys[key], 0, 13);
433 (*crypt)->ops->set_key(sec.keys[key], 13, NULL,
434 (*crypt)->priv);
435 sec.key_sizes[key] = 13;
436 sec.flags |= (1 << key);
437 }
438 }
439 /* No key data - just set the default TX key index */
440 if (key_provided) {
441 IEEE80211_DEBUG_WX("Setting key %d to default Tx "
442 "key.\n", key);
443 ieee->crypt_info.tx_keyidx = key;
444 sec.active_key = key;
445 sec.flags |= SEC_ACTIVE_KEY;
446 }
447 }
448 if (erq->flags & (IW_ENCODE_OPEN | IW_ENCODE_RESTRICTED)) {
449 ieee->open_wep = !(erq->flags & IW_ENCODE_RESTRICTED);
450 sec.auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN :
451 WLAN_AUTH_SHARED_KEY;
452 sec.flags |= SEC_AUTH_MODE;
453 IEEE80211_DEBUG_WX("Auth: %s\n",
454 sec.auth_mode == WLAN_AUTH_OPEN ?
455 "OPEN" : "SHARED KEY");
456 }
457
458 /* For now we just support WEP, so only set that security level...
459 * TODO: When WPA is added this is one place that needs to change */
460 sec.flags |= SEC_LEVEL;
461 sec.level = SEC_LEVEL_1; /* 40 and 104 bit WEP */
462 sec.encode_alg[key] = SEC_ALG_WEP;
463
464 done:
465 if (ieee->set_security)
466 ieee->set_security(dev, &sec);
467
468 /* Do not reset port if card is in Managed mode since resetting will
469 * generate new IEEE 802.11 authentication which may end up in looping
470 * with IEEE 802.1X. If your hardware requires a reset after WEP
471 * configuration (for example... Prism2), implement the reset_port in
472 * the callbacks structures used to initialize the 802.11 stack. */
473 if (ieee->reset_on_keychange &&
474 ieee->iw_mode != IW_MODE_INFRA &&
475 ieee->reset_port && ieee->reset_port(dev)) {
476 printk(KERN_DEBUG "%s: reset_port failed\n", dev->name);
477 return -EINVAL;
478 }
479 return 0;
480}
481
482int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
483 struct iw_request_info *info,
484 union iwreq_data *wrqu, char *keybuf)
485{
486 struct iw_point *erq = &(wrqu->encoding);
487 int len, key;
488 struct lib80211_crypt_data *crypt;
489 struct ieee80211_security *sec = &ieee->sec;
490
491 IEEE80211_DEBUG_WX("GET_ENCODE\n");
492
493 key = erq->flags & IW_ENCODE_INDEX;
494 if (key) {
495 if (key > WEP_KEYS)
496 return -EINVAL;
497 key--;
498 } else
499 key = ieee->crypt_info.tx_keyidx;
500
501 crypt = ieee->crypt_info.crypt[key];
502 erq->flags = key + 1;
503
504 if (!sec->enabled) {
505 erq->length = 0;
506 erq->flags |= IW_ENCODE_DISABLED;
507 return 0;
508 }
509
510 len = sec->key_sizes[key];
511 memcpy(keybuf, sec->keys[key], len);
512
513 erq->length = len;
514 erq->flags |= IW_ENCODE_ENABLED;
515
516 if (ieee->open_wep)
517 erq->flags |= IW_ENCODE_OPEN;
518 else
519 erq->flags |= IW_ENCODE_RESTRICTED;
520
521 return 0;
522}
523
524int ieee80211_wx_set_encodeext(struct ieee80211_device *ieee,
525 struct iw_request_info *info,
526 union iwreq_data *wrqu, char *extra)
527{
528 struct net_device *dev = ieee->dev;
529 struct iw_point *encoding = &wrqu->encoding;
530 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
531 int i, idx, ret = 0;
532 int group_key = 0;
533 const char *alg, *module;
534 struct lib80211_crypto_ops *ops;
535 struct lib80211_crypt_data **crypt;
536
537 struct ieee80211_security sec = {
538 .flags = 0,
539 };
540
541 idx = encoding->flags & IW_ENCODE_INDEX;
542 if (idx) {
543 if (idx < 1 || idx > WEP_KEYS)
544 return -EINVAL;
545 idx--;
546 } else
547 idx = ieee->crypt_info.tx_keyidx;
548
549 if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
550 crypt = &ieee->crypt_info.crypt[idx];
551 group_key = 1;
552 } else {
553 /* some Cisco APs use idx>0 for unicast in dynamic WEP */
554 if (idx != 0 && ext->alg != IW_ENCODE_ALG_WEP)
555 return -EINVAL;
556 if (ieee->iw_mode == IW_MODE_INFRA)
557 crypt = &ieee->crypt_info.crypt[idx];
558 else
559 return -EINVAL;
560 }
561
562 sec.flags |= SEC_ENABLED | SEC_ENCRYPT;
563 if ((encoding->flags & IW_ENCODE_DISABLED) ||
564 ext->alg == IW_ENCODE_ALG_NONE) {
565 if (*crypt)
566 lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt);
567
568 for (i = 0; i < WEP_KEYS; i++)
569 if (ieee->crypt_info.crypt[i] != NULL)
570 break;
571
572 if (i == WEP_KEYS) {
573 sec.enabled = 0;
574 sec.encrypt = 0;
575 sec.level = SEC_LEVEL_0;
576 sec.flags |= SEC_LEVEL;
577 }
578 goto done;
579 }
580
581 sec.enabled = 1;
582 sec.encrypt = 1;
583
584 if (group_key ? !ieee->host_mc_decrypt :
585 !(ieee->host_encrypt || ieee->host_decrypt ||
586 ieee->host_encrypt_msdu))
587 goto skip_host_crypt;
588
589 switch (ext->alg) {
590 case IW_ENCODE_ALG_WEP:
591 alg = "WEP";
592 module = "lib80211_crypt_wep";
593 break;
594 case IW_ENCODE_ALG_TKIP:
595 alg = "TKIP";
596 module = "lib80211_crypt_tkip";
597 break;
598 case IW_ENCODE_ALG_CCMP:
599 alg = "CCMP";
600 module = "lib80211_crypt_ccmp";
601 break;
602 default:
603 IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
604 dev->name, ext->alg);
605 ret = -EINVAL;
606 goto done;
607 }
608
609 ops = lib80211_get_crypto_ops(alg);
610 if (ops == NULL) {
611 request_module(module);
612 ops = lib80211_get_crypto_ops(alg);
613 }
614 if (ops == NULL) {
615 IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
616 dev->name, ext->alg);
617 ret = -EINVAL;
618 goto done;
619 }
620
621 if (*crypt == NULL || (*crypt)->ops != ops) {
622 struct lib80211_crypt_data *new_crypt;
623
624 lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt);
625
626 new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL);
627 if (new_crypt == NULL) {
628 ret = -ENOMEM;
629 goto done;
630 }
631 new_crypt->ops = ops;
632 if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
633 new_crypt->priv = new_crypt->ops->init(idx);
634 if (new_crypt->priv == NULL) {
635 kfree(new_crypt);
636 ret = -EINVAL;
637 goto done;
638 }
639 *crypt = new_crypt;
640 }
641
642 if (ext->key_len > 0 && (*crypt)->ops->set_key &&
643 (*crypt)->ops->set_key(ext->key, ext->key_len, ext->rx_seq,
644 (*crypt)->priv) < 0) {
645 IEEE80211_DEBUG_WX("%s: key setting failed\n", dev->name);
646 ret = -EINVAL;
647 goto done;
648 }
649
650 skip_host_crypt:
651 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
652 ieee->crypt_info.tx_keyidx = idx;
653 sec.active_key = idx;
654 sec.flags |= SEC_ACTIVE_KEY;
655 }
656
657 if (ext->alg != IW_ENCODE_ALG_NONE) {
658 memcpy(sec.keys[idx], ext->key, ext->key_len);
659 sec.key_sizes[idx] = ext->key_len;
660 sec.flags |= (1 << idx);
661 if (ext->alg == IW_ENCODE_ALG_WEP) {
662 sec.encode_alg[idx] = SEC_ALG_WEP;
663 sec.flags |= SEC_LEVEL;
664 sec.level = SEC_LEVEL_1;
665 } else if (ext->alg == IW_ENCODE_ALG_TKIP) {
666 sec.encode_alg[idx] = SEC_ALG_TKIP;
667 sec.flags |= SEC_LEVEL;
668 sec.level = SEC_LEVEL_2;
669 } else if (ext->alg == IW_ENCODE_ALG_CCMP) {
670 sec.encode_alg[idx] = SEC_ALG_CCMP;
671 sec.flags |= SEC_LEVEL;
672 sec.level = SEC_LEVEL_3;
673 }
674 /* Don't set sec level for group keys. */
675 if (group_key)
676 sec.flags &= ~SEC_LEVEL;
677 }
678 done:
679 if (ieee->set_security)
680 ieee->set_security(ieee->dev, &sec);
681
682 /*
683 * Do not reset port if card is in Managed mode since resetting will
684 * generate new IEEE 802.11 authentication which may end up in looping
685 * with IEEE 802.1X. If your hardware requires a reset after WEP
686 * configuration (for example... Prism2), implement the reset_port in
687 * the callbacks structures used to initialize the 802.11 stack.
688 */
689 if (ieee->reset_on_keychange &&
690 ieee->iw_mode != IW_MODE_INFRA &&
691 ieee->reset_port && ieee->reset_port(dev)) {
692 IEEE80211_DEBUG_WX("%s: reset_port failed\n", dev->name);
693 return -EINVAL;
694 }
695
696 return ret;
697}
698
699int ieee80211_wx_get_encodeext(struct ieee80211_device *ieee,
700 struct iw_request_info *info,
701 union iwreq_data *wrqu, char *extra)
702{
703 struct iw_point *encoding = &wrqu->encoding;
704 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
705 struct ieee80211_security *sec = &ieee->sec;
706 int idx, max_key_len;
707
708 max_key_len = encoding->length - sizeof(*ext);
709 if (max_key_len < 0)
710 return -EINVAL;
711
712 idx = encoding->flags & IW_ENCODE_INDEX;
713 if (idx) {
714 if (idx < 1 || idx > WEP_KEYS)
715 return -EINVAL;
716 idx--;
717 } else
718 idx = ieee->crypt_info.tx_keyidx;
719
720 if (!(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) &&
721 ext->alg != IW_ENCODE_ALG_WEP)
722 if (idx != 0 || ieee->iw_mode != IW_MODE_INFRA)
723 return -EINVAL;
724
725 encoding->flags = idx + 1;
726 memset(ext, 0, sizeof(*ext));
727
728 if (!sec->enabled) {
729 ext->alg = IW_ENCODE_ALG_NONE;
730 ext->key_len = 0;
731 encoding->flags |= IW_ENCODE_DISABLED;
732 } else {
733 if (sec->encode_alg[idx] == SEC_ALG_WEP)
734 ext->alg = IW_ENCODE_ALG_WEP;
735 else if (sec->encode_alg[idx] == SEC_ALG_TKIP)
736 ext->alg = IW_ENCODE_ALG_TKIP;
737 else if (sec->encode_alg[idx] == SEC_ALG_CCMP)
738 ext->alg = IW_ENCODE_ALG_CCMP;
739 else
740 return -EINVAL;
741
742 ext->key_len = sec->key_sizes[idx];
743 memcpy(ext->key, sec->keys[idx], ext->key_len);
744 encoding->flags |= IW_ENCODE_ENABLED;
745 if (ext->key_len &&
746 (ext->alg == IW_ENCODE_ALG_TKIP ||
747 ext->alg == IW_ENCODE_ALG_CCMP))
748 ext->ext_flags |= IW_ENCODE_EXT_TX_SEQ_VALID;
749
750 }
751
752 return 0;
753}
754
755EXPORT_SYMBOL(ieee80211_wx_set_encodeext);
756EXPORT_SYMBOL(ieee80211_wx_get_encodeext);
757
758EXPORT_SYMBOL(ieee80211_wx_get_scan);
759EXPORT_SYMBOL(ieee80211_wx_set_encode);
760EXPORT_SYMBOL(ieee80211_wx_get_encode);
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile
index 47aa28f6a513..8b45b30e6d5c 100644
--- a/drivers/net/wireless/iwlwifi/Makefile
+++ b/drivers/net/wireless/iwlwifi/Makefile
@@ -5,6 +5,7 @@ iwlcore-objs += iwl-scan.o
5iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o 5iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o
6iwlcore-$(CONFIG_IWLWIFI_LEDS) += iwl-led.o 6iwlcore-$(CONFIG_IWLWIFI_LEDS) += iwl-led.o
7iwlcore-$(CONFIG_IWLWIFI_RFKILL) += iwl-rfkill.o 7iwlcore-$(CONFIG_IWLWIFI_RFKILL) += iwl-rfkill.o
8iwlcore-$(CONFIG_IWLAGN_SPECTRUM_MEASUREMENT) += iwl-spectrum.o
8 9
9obj-$(CONFIG_IWLAGN) += iwlagn.o 10obj-$(CONFIG_IWLAGN) += iwlagn.o
10iwlagn-objs := iwl-agn.o iwl-agn-rs.o 11iwlagn-objs := iwl-agn.o iwl-agn-rs.o
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
index 9da7c7bea752..fb0fd773960f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
@@ -819,64 +819,6 @@ enum {
819#define IWL49_NUM_QUEUES 16 819#define IWL49_NUM_QUEUES 16
820#define IWL49_NUM_AMPDU_QUEUES 8 820#define IWL49_NUM_AMPDU_QUEUES 8
821 821
822#define IWL_TX_DMA_MASK (DMA_BIT_MASK(36) & ~0x3)
823#define IWL_NUM_OF_TBS 20
824
825static inline u8 iwl_get_dma_hi_addr(dma_addr_t addr)
826{
827 return (sizeof(addr) > sizeof(u32) ? (addr >> 16) >> 16 : 0) & 0xF;
828}
829/**
830 * struct iwl_tfd_tb transmit buffer descriptor within transmit frame descriptor
831 *
832 * This structure contains dma address and length of transmission address
833 *
834 * @lo: low [31:0] portion of the dma address of TX buffer
835 * every even is unaligned on 16 bit boundary
836 * @hi_n_len 0-3 [35:32] portion of dma
837 * 4-16 length of the tx buffer
838 */
839struct iwl_tfd_tb {
840 __le32 lo;
841 __le16 hi_n_len;
842} __attribute__((packed));
843
844/**
845 * struct iwl_tfd
846 *
847 * Transmit Frame Descriptor (TFD)
848 *
849 * @ __reserved1[3] reserved
850 * @ num_tbs 0-5 number of active tbs
851 * 6-7 padding (not used)
852 * @ tbs[20] transmit frame buffer descriptors
853 * @ __pad padding
854 *
855 * Each Tx queue uses a circular buffer of 256 TFDs stored in host DRAM.
856 * Both driver and device share these circular buffers, each of which must be
857 * contiguous 256 TFDs x 128 bytes-per-TFD = 32 KBytes
858 *
859 * Driver must indicate the physical address of the base of each
860 * circular buffer via the FH_MEM_CBBC_QUEUE registers.
861 *
862 * Each TFD contains pointer/size information for up to 20 data buffers
863 * in host DRAM. These buffers collectively contain the (one) frame described
864 * by the TFD. Each buffer must be a single contiguous block of memory within
865 * itself, but buffers may be scattered in host DRAM. Each buffer has max size
866 * of (4K - 4). The concatenates all of a TFD's buffers into a single
867 * Tx frame, up to 8 KBytes in size.
868 *
869 * A maximum of 255 (not 256!) TFDs may be on a queue waiting for Tx.
870 *
871 * Bit fields in the control dword (val0):
872 */
873struct iwl_tfd {
874 u8 __reserved1[3];
875 u8 num_tbs;
876 struct iwl_tfd_tb tbs[IWL_NUM_OF_TBS];
877 __le32 __pad;
878} __attribute__ ((packed));
879
880 822
881/** 823/**
882 * struct iwl4965_schedq_bc_tbl 824 * struct iwl4965_schedq_bc_tbl
@@ -896,64 +838,9 @@ struct iwl_tfd {
896 * padding puts each byte count table on a 1024-byte boundary; 838 * padding puts each byte count table on a 1024-byte boundary;
897 * 4965 assumes tables are separated by 1024 bytes. 839 * 4965 assumes tables are separated by 1024 bytes.
898 */ 840 */
899struct iwl4965_schedq_bc_tbl { 841struct iwl4965_scd_bc_tbl {
900 __le16 tfd_offset[TFD_QUEUE_BC_SIZE]; 842 __le16 tfd_offset[TFD_QUEUE_BC_SIZE];
901 u8 pad[1024 - (TFD_QUEUE_BC_SIZE) * sizeof(__le16)]; 843 u8 pad[1024 - (TFD_QUEUE_BC_SIZE) * sizeof(__le16)];
902} __attribute__ ((packed)); 844} __attribute__ ((packed));
903 845
904 846#endif /* !__iwl_4965_hw_h__ */
905/**
906 * struct iwl4965_shared - handshake area for Tx and Rx
907 *
908 * For convenience in allocating memory, this structure combines 2 areas of
909 * DRAM which must be shared between driver and 4965. These do not need to
910 * be combined, if better allocation would result from keeping them separate:
911 *
912 * 1) The Tx byte count tables occupy 1024 bytes each (16 KBytes total for
913 * 16 queues). Driver uses SCD_DRAM_BASE_ADDR to tell 4965 where to find
914 * the first of these tables. 4965 assumes tables are 1024 bytes apart.
915 *
916 * 2) The Rx status (val0 and val1) occupies only 8 bytes. Driver uses
917 * FH_RSCSR_CHNL0_STTS_WPTR_REG to tell 4965 where to find this area.
918 * Driver reads val0 to determine the latest Receive Buffer Descriptor (RBD)
919 * that has been filled by the 4965.
920 *
921 * Bit fields val0:
922 * 31-12: Not used
923 * 11- 0: Index of last filled Rx buffer descriptor (4965 writes, driver reads)
924 *
925 * Bit fields val1:
926 * 31- 0: Not used
927 */
928struct iwl4965_shared {
929 struct iwl4965_schedq_bc_tbl queues_bc_tbls[IWL49_NUM_QUEUES];
930 __le32 rb_closed;
931
932 /* __le32 rb_closed_stts_rb_num:12; */
933#define IWL_rb_closed_stts_rb_num_POS 0
934#define IWL_rb_closed_stts_rb_num_LEN 12
935#define IWL_rb_closed_stts_rb_num_SYM rb_closed
936 /* __le32 rsrv1:4; */
937 /* __le32 rb_closed_stts_rx_frame_num:12; */
938#define IWL_rb_closed_stts_rx_frame_num_POS 16
939#define IWL_rb_closed_stts_rx_frame_num_LEN 12
940#define IWL_rb_closed_stts_rx_frame_num_SYM rb_closed
941 /* __le32 rsrv2:4; */
942
943 __le32 frm_finished;
944 /* __le32 frame_finished_stts_rb_num:12; */
945#define IWL_frame_finished_stts_rb_num_POS 0
946#define IWL_frame_finished_stts_rb_num_LEN 12
947#define IWL_frame_finished_stts_rb_num_SYM frm_finished
948 /* __le32 rsrv3:4; */
949 /* __le32 frame_finished_stts_rx_frame_num:12; */
950#define IWL_frame_finished_stts_rx_frame_num_POS 16
951#define IWL_frame_finished_stts_rx_frame_num_LEN 12
952#define IWL_frame_finished_stts_rx_frame_num_SYM frm_finished
953 /* __le32 rsrv4:4; */
954
955 __le32 padding1; /* so that allocation will be aligned to 16B */
956 __le32 padding2;
957} __attribute__ ((packed));
958
959#endif /* __iwl4965_4965_hw_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 157cad4e9da0..c43cf2f072cd 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -715,8 +715,7 @@ static int iwl4965_alive_notify(struct iwl_priv *priv)
715 715
716 /* Tel 4965 where to find Tx byte count tables */ 716 /* Tel 4965 where to find Tx byte count tables */
717 iwl_write_prph(priv, IWL49_SCD_DRAM_BASE_ADDR, 717 iwl_write_prph(priv, IWL49_SCD_DRAM_BASE_ADDR,
718 (priv->shared_phys + 718 priv->scd_bc_tbls.dma >> 10);
719 offsetof(struct iwl4965_shared, queues_bc_tbls)) >> 10);
720 719
721 /* Disable chain mode for all queues */ 720 /* Disable chain mode for all queues */
722 iwl_write_prph(priv, IWL49_SCD_QUEUECHAIN_SEL, 0); 721 iwl_write_prph(priv, IWL49_SCD_QUEUECHAIN_SEL, 0);
@@ -804,6 +803,8 @@ static int iwl4965_hw_set_hw_params(struct iwl_priv *priv)
804 } 803 }
805 804
806 priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues; 805 priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues;
806 priv->hw_params.scd_bc_tbls_size =
807 IWL49_NUM_QUEUES * sizeof(struct iwl4965_scd_bc_tbl);
807 priv->hw_params.max_stations = IWL4965_STATION_COUNT; 808 priv->hw_params.max_stations = IWL4965_STATION_COUNT;
808 priv->hw_params.bcast_sta_id = IWL4965_BROADCAST_ID; 809 priv->hw_params.bcast_sta_id = IWL4965_BROADCAST_ID;
809 priv->hw_params.max_data_size = IWL49_RTC_DATA_SIZE; 810 priv->hw_params.max_data_size = IWL49_RTC_DATA_SIZE;
@@ -1631,36 +1632,6 @@ static int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channel)
1631} 1632}
1632#endif 1633#endif
1633 1634
1634static int iwl4965_shared_mem_rx_idx(struct iwl_priv *priv)
1635{
1636 struct iwl4965_shared *s = priv->shared_virt;
1637 return le32_to_cpu(s->rb_closed) & 0xFFF;
1638}
1639
1640static int iwl4965_alloc_shared_mem(struct iwl_priv *priv)
1641{
1642 priv->shared_virt = pci_alloc_consistent(priv->pci_dev,
1643 sizeof(struct iwl4965_shared),
1644 &priv->shared_phys);
1645 if (!priv->shared_virt)
1646 return -ENOMEM;
1647
1648 memset(priv->shared_virt, 0, sizeof(struct iwl4965_shared));
1649
1650 priv->rb_closed_offset = offsetof(struct iwl4965_shared, rb_closed);
1651
1652 return 0;
1653}
1654
1655static void iwl4965_free_shared_mem(struct iwl_priv *priv)
1656{
1657 if (priv->shared_virt)
1658 pci_free_consistent(priv->pci_dev,
1659 sizeof(struct iwl4965_shared),
1660 priv->shared_virt,
1661 priv->shared_phys);
1662}
1663
1664/** 1635/**
1665 * iwl4965_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array 1636 * iwl4965_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array
1666 */ 1637 */
@@ -1668,7 +1639,7 @@ static void iwl4965_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
1668 struct iwl_tx_queue *txq, 1639 struct iwl_tx_queue *txq,
1669 u16 byte_cnt) 1640 u16 byte_cnt)
1670{ 1641{
1671 struct iwl4965_shared *shared_data = priv->shared_virt; 1642 struct iwl4965_scd_bc_tbl *scd_bc_tbl = priv->scd_bc_tbls.addr;
1672 int txq_id = txq->q.id; 1643 int txq_id = txq->q.id;
1673 int write_ptr = txq->q.write_ptr; 1644 int write_ptr = txq->q.write_ptr;
1674 int len = byte_cnt + IWL_TX_CRC_SIZE + IWL_TX_DELIMITER_SIZE; 1645 int len = byte_cnt + IWL_TX_CRC_SIZE + IWL_TX_DELIMITER_SIZE;
@@ -1678,11 +1649,11 @@ static void iwl4965_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
1678 1649
1679 bc_ent = cpu_to_le16(len & 0xFFF); 1650 bc_ent = cpu_to_le16(len & 0xFFF);
1680 /* Set up byte count within first 256 entries */ 1651 /* Set up byte count within first 256 entries */
1681 shared_data->queues_bc_tbls[txq_id].tfd_offset[write_ptr] = bc_ent; 1652 scd_bc_tbl[txq_id].tfd_offset[write_ptr] = bc_ent;
1682 1653
1683 /* If within first 64 entries, duplicate at end */ 1654 /* If within first 64 entries, duplicate at end */
1684 if (write_ptr < TFD_QUEUE_SIZE_BC_DUP) 1655 if (write_ptr < TFD_QUEUE_SIZE_BC_DUP)
1685 shared_data->queues_bc_tbls[txq_id]. 1656 scd_bc_tbl[txq_id].
1686 tfd_offset[TFD_QUEUE_SIZE_MAX + write_ptr] = bc_ent; 1657 tfd_offset[TFD_QUEUE_SIZE_MAX + write_ptr] = bc_ent;
1687} 1658}
1688 1659
@@ -2304,9 +2275,6 @@ static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = {
2304 2275
2305static struct iwl_lib_ops iwl4965_lib = { 2276static struct iwl_lib_ops iwl4965_lib = {
2306 .set_hw_params = iwl4965_hw_set_hw_params, 2277 .set_hw_params = iwl4965_hw_set_hw_params,
2307 .alloc_shared_mem = iwl4965_alloc_shared_mem,
2308 .free_shared_mem = iwl4965_free_shared_mem,
2309 .shared_mem_rx_idx = iwl4965_shared_mem_rx_idx,
2310 .txq_update_byte_cnt_tbl = iwl4965_txq_update_byte_cnt_tbl, 2278 .txq_update_byte_cnt_tbl = iwl4965_txq_update_byte_cnt_tbl,
2311 .txq_set_sched = iwl4965_txq_set_sched, 2279 .txq_set_sched = iwl4965_txq_set_sched,
2312 .txq_agg_enable = iwl4965_txq_agg_enable, 2280 .txq_agg_enable = iwl4965_txq_agg_enable,
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
index 12c74048a396..c6595e8b4405 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
@@ -90,45 +90,10 @@
90 * @tfd_offset 0-12 - tx command byte count 90 * @tfd_offset 0-12 - tx command byte count
91 * 12-16 - station index 91 * 12-16 - station index
92 */ 92 */
93struct iwl5000_schedq_bc_tbl { 93struct iwl5000_scd_bc_tbl {
94 __le16 tfd_offset[TFD_QUEUE_BC_SIZE]; 94 __le16 tfd_offset[TFD_QUEUE_BC_SIZE];
95} __attribute__ ((packed)); 95} __attribute__ ((packed));
96 96
97/**
98 * struct iwl5000_shared
99 * @rb_closed
100 * address is provided to FH_RSCSR_CHNL0_STTS_WPTR_REG
101 */
102struct iwl5000_shared {
103 struct iwl5000_schedq_bc_tbl queues_bc_tbls[IWL50_NUM_QUEUES];
104 __le32 rb_closed;
105
106 /* __le32 rb_closed_stts_rb_num:12; */
107#define IWL_rb_closed_stts_rb_num_POS 0
108#define IWL_rb_closed_stts_rb_num_LEN 12
109#define IWL_rb_closed_stts_rb_num_SYM rb_closed
110 /* __le32 rsrv1:4; */
111 /* __le32 rb_closed_stts_rx_frame_num:12; */
112#define IWL_rb_closed_stts_rx_frame_num_POS 16
113#define IWL_rb_closed_stts_rx_frame_num_LEN 12
114#define IWL_rb_closed_stts_rx_frame_num_SYM rb_closed
115 /* __le32 rsrv2:4; */
116
117 __le32 frm_finished;
118 /* __le32 frame_finished_stts_rb_num:12; */
119#define IWL_frame_finished_stts_rb_num_POS 0
120#define IWL_frame_finished_stts_rb_num_LEN 12
121#define IWL_frame_finished_stts_rb_num_SYM frm_finished
122 /* __le32 rsrv3:4; */
123 /* __le32 frame_finished_stts_rx_frame_num:12; */
124#define IWL_frame_finished_stts_rx_frame_num_POS 16
125#define IWL_frame_finished_stts_rx_frame_num_LEN 12
126#define IWL_frame_finished_stts_rx_frame_num_SYM frm_finished
127 /* __le32 rsrv4:4; */
128
129 __le32 padding1; /* so that allocation will be aligned to 16B */
130 __le32 padding2;
131} __attribute__ ((packed));
132 97
133#endif /* __iwl_5000_hw_h__ */ 98#endif /* __iwl_5000_hw_h__ */
134 99
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index 31e62a838ad4..ee3613db3132 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -721,11 +721,9 @@ static int iwl5000_alive_notify(struct iwl_priv *priv)
721 iwl_write_targ_mem(priv, a, 0); 721 iwl_write_targ_mem(priv, a, 0);
722 722
723 iwl_write_prph(priv, IWL50_SCD_DRAM_BASE_ADDR, 723 iwl_write_prph(priv, IWL50_SCD_DRAM_BASE_ADDR,
724 (priv->shared_phys + 724 priv->scd_bc_tbls.dma >> 10);
725 offsetof(struct iwl5000_shared, queues_bc_tbls)) >> 10);
726 iwl_write_prph(priv, IWL50_SCD_QUEUECHAIN_SEL, 725 iwl_write_prph(priv, IWL50_SCD_QUEUECHAIN_SEL,
727 IWL50_SCD_QUEUECHAIN_SEL_ALL( 726 IWL50_SCD_QUEUECHAIN_SEL_ALL(priv->hw_params.max_txq_num));
728 priv->hw_params.max_txq_num));
729 iwl_write_prph(priv, IWL50_SCD_AGGR_SEL, 0); 727 iwl_write_prph(priv, IWL50_SCD_AGGR_SEL, 0);
730 728
731 /* initiate the queues */ 729 /* initiate the queues */
@@ -788,6 +786,8 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
788 } 786 }
789 787
790 priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues; 788 priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues;
789 priv->hw_params.scd_bc_tbls_size =
790 IWL50_NUM_QUEUES * sizeof(struct iwl5000_scd_bc_tbl);
791 priv->hw_params.max_stations = IWL5000_STATION_COUNT; 791 priv->hw_params.max_stations = IWL5000_STATION_COUNT;
792 priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID; 792 priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID;
793 priv->hw_params.max_data_size = IWL50_RTC_DATA_SIZE; 793 priv->hw_params.max_data_size = IWL50_RTC_DATA_SIZE;
@@ -853,36 +853,6 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
853 return 0; 853 return 0;
854} 854}
855 855
856static int iwl5000_alloc_shared_mem(struct iwl_priv *priv)
857{
858 priv->shared_virt = pci_alloc_consistent(priv->pci_dev,
859 sizeof(struct iwl5000_shared),
860 &priv->shared_phys);
861 if (!priv->shared_virt)
862 return -ENOMEM;
863
864 memset(priv->shared_virt, 0, sizeof(struct iwl5000_shared));
865
866 priv->rb_closed_offset = offsetof(struct iwl5000_shared, rb_closed);
867
868 return 0;
869}
870
871static void iwl5000_free_shared_mem(struct iwl_priv *priv)
872{
873 if (priv->shared_virt)
874 pci_free_consistent(priv->pci_dev,
875 sizeof(struct iwl5000_shared),
876 priv->shared_virt,
877 priv->shared_phys);
878}
879
880static int iwl5000_shared_mem_rx_idx(struct iwl_priv *priv)
881{
882 struct iwl5000_shared *s = priv->shared_virt;
883 return le32_to_cpu(s->rb_closed) & 0xFFF;
884}
885
886/** 856/**
887 * iwl5000_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array 857 * iwl5000_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array
888 */ 858 */
@@ -890,7 +860,7 @@ static void iwl5000_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
890 struct iwl_tx_queue *txq, 860 struct iwl_tx_queue *txq,
891 u16 byte_cnt) 861 u16 byte_cnt)
892{ 862{
893 struct iwl5000_shared *shared_data = priv->shared_virt; 863 struct iwl5000_scd_bc_tbl *scd_bc_tbl = priv->scd_bc_tbls.addr;
894 int write_ptr = txq->q.write_ptr; 864 int write_ptr = txq->q.write_ptr;
895 int txq_id = txq->q.id; 865 int txq_id = txq->q.id;
896 u8 sec_ctl = 0; 866 u8 sec_ctl = 0;
@@ -919,17 +889,17 @@ static void iwl5000_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
919 889
920 bc_ent = cpu_to_le16((len & 0xFFF) | (sta_id << 12)); 890 bc_ent = cpu_to_le16((len & 0xFFF) | (sta_id << 12));
921 891
922 shared_data->queues_bc_tbls[txq_id].tfd_offset[write_ptr] = bc_ent; 892 scd_bc_tbl[txq_id].tfd_offset[write_ptr] = bc_ent;
923 893
924 if (txq->q.write_ptr < TFD_QUEUE_SIZE_BC_DUP) 894 if (txq->q.write_ptr < TFD_QUEUE_SIZE_BC_DUP)
925 shared_data->queues_bc_tbls[txq_id]. 895 scd_bc_tbl[txq_id].
926 tfd_offset[TFD_QUEUE_SIZE_MAX + write_ptr] = bc_ent; 896 tfd_offset[TFD_QUEUE_SIZE_MAX + write_ptr] = bc_ent;
927} 897}
928 898
929static void iwl5000_txq_inval_byte_cnt_tbl(struct iwl_priv *priv, 899static void iwl5000_txq_inval_byte_cnt_tbl(struct iwl_priv *priv,
930 struct iwl_tx_queue *txq) 900 struct iwl_tx_queue *txq)
931{ 901{
932 struct iwl5000_shared *shared_data = priv->shared_virt; 902 struct iwl5000_scd_bc_tbl *scd_bc_tbl = priv->scd_bc_tbls.addr;
933 int txq_id = txq->q.id; 903 int txq_id = txq->q.id;
934 int read_ptr = txq->q.read_ptr; 904 int read_ptr = txq->q.read_ptr;
935 u8 sta_id = 0; 905 u8 sta_id = 0;
@@ -941,11 +911,10 @@ static void iwl5000_txq_inval_byte_cnt_tbl(struct iwl_priv *priv,
941 sta_id = txq->cmd[read_ptr]->cmd.tx.sta_id; 911 sta_id = txq->cmd[read_ptr]->cmd.tx.sta_id;
942 912
943 bc_ent = cpu_to_le16(1 | (sta_id << 12)); 913 bc_ent = cpu_to_le16(1 | (sta_id << 12));
944 shared_data->queues_bc_tbls[txq_id]. 914 scd_bc_tbl[txq_id].tfd_offset[read_ptr] = bc_ent;
945 tfd_offset[read_ptr] = bc_ent;
946 915
947 if (txq->q.write_ptr < TFD_QUEUE_SIZE_BC_DUP) 916 if (txq->q.write_ptr < TFD_QUEUE_SIZE_BC_DUP)
948 shared_data->queues_bc_tbls[txq_id]. 917 scd_bc_tbl[txq_id].
949 tfd_offset[TFD_QUEUE_SIZE_MAX + read_ptr] = bc_ent; 918 tfd_offset[TFD_QUEUE_SIZE_MAX + read_ptr] = bc_ent;
950} 919}
951 920
@@ -1458,9 +1427,6 @@ static struct iwl_hcmd_utils_ops iwl5000_hcmd_utils = {
1458 1427
1459static struct iwl_lib_ops iwl5000_lib = { 1428static struct iwl_lib_ops iwl5000_lib = {
1460 .set_hw_params = iwl5000_hw_set_hw_params, 1429 .set_hw_params = iwl5000_hw_set_hw_params,
1461 .alloc_shared_mem = iwl5000_alloc_shared_mem,
1462 .free_shared_mem = iwl5000_free_shared_mem,
1463 .shared_mem_rx_idx = iwl5000_shared_mem_rx_idx,
1464 .txq_update_byte_cnt_tbl = iwl5000_txq_update_byte_cnt_tbl, 1430 .txq_update_byte_cnt_tbl = iwl5000_txq_update_byte_cnt_tbl,
1465 .txq_inval_byte_cnt_tbl = iwl5000_txq_inval_byte_cnt_tbl, 1431 .txq_inval_byte_cnt_tbl = iwl5000_txq_inval_byte_cnt_tbl,
1466 .txq_set_sched = iwl5000_txq_set_sched, 1432 .txq_set_sched = iwl5000_txq_set_sched,
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 35cfa1524c35..8fa4f7a2dc1a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -871,138 +871,6 @@ static void iwl_set_rate(struct iwl_priv *priv)
871 (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF; 871 (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
872} 872}
873 873
874#ifdef CONFIG_IWLAGN_SPECTRUM_MEASUREMENT
875
876#include "iwl-spectrum.h"
877
878#define BEACON_TIME_MASK_LOW 0x00FFFFFF
879#define BEACON_TIME_MASK_HIGH 0xFF000000
880#define TIME_UNIT 1024
881
882/*
883 * extended beacon time format
884 * time in usec will be changed into a 32-bit value in 8:24 format
885 * the high 1 byte is the beacon counts
886 * the lower 3 bytes is the time in usec within one beacon interval
887 */
888
889static u32 iwl_usecs_to_beacons(u32 usec, u32 beacon_interval)
890{
891 u32 quot;
892 u32 rem;
893 u32 interval = beacon_interval * 1024;
894
895 if (!interval || !usec)
896 return 0;
897
898 quot = (usec / interval) & (BEACON_TIME_MASK_HIGH >> 24);
899 rem = (usec % interval) & BEACON_TIME_MASK_LOW;
900
901 return (quot << 24) + rem;
902}
903
904/* base is usually what we get from ucode with each received frame,
905 * the same as HW timer counter counting down
906 */
907
908static __le32 iwl_add_beacon_time(u32 base, u32 addon, u32 beacon_interval)
909{
910 u32 base_low = base & BEACON_TIME_MASK_LOW;
911 u32 addon_low = addon & BEACON_TIME_MASK_LOW;
912 u32 interval = beacon_interval * TIME_UNIT;
913 u32 res = (base & BEACON_TIME_MASK_HIGH) +
914 (addon & BEACON_TIME_MASK_HIGH);
915
916 if (base_low > addon_low)
917 res += base_low - addon_low;
918 else if (base_low < addon_low) {
919 res += interval + base_low - addon_low;
920 res += (1 << 24);
921 } else
922 res += (1 << 24);
923
924 return cpu_to_le32(res);
925}
926
927static int iwl_get_measurement(struct iwl_priv *priv,
928 struct ieee80211_measurement_params *params,
929 u8 type)
930{
931 struct iwl4965_spectrum_cmd spectrum;
932 struct iwl_rx_packet *res;
933 struct iwl_host_cmd cmd = {
934 .id = REPLY_SPECTRUM_MEASUREMENT_CMD,
935 .data = (void *)&spectrum,
936 .meta.flags = CMD_WANT_SKB,
937 };
938 u32 add_time = le64_to_cpu(params->start_time);
939 int rc;
940 int spectrum_resp_status;
941 int duration = le16_to_cpu(params->duration);
942
943 if (iwl_is_associated(priv))
944 add_time =
945 iwl_usecs_to_beacons(
946 le64_to_cpu(params->start_time) - priv->last_tsf,
947 le16_to_cpu(priv->rxon_timing.beacon_interval));
948
949 memset(&spectrum, 0, sizeof(spectrum));
950
951 spectrum.channel_count = cpu_to_le16(1);
952 spectrum.flags =
953 RXON_FLG_TSF2HOST_MSK | RXON_FLG_ANT_A_MSK | RXON_FLG_DIS_DIV_MSK;
954 spectrum.filter_flags = MEASUREMENT_FILTER_FLAG;
955 cmd.len = sizeof(spectrum);
956 spectrum.len = cpu_to_le16(cmd.len - sizeof(spectrum.len));
957
958 if (iwl_is_associated(priv))
959 spectrum.start_time =
960 iwl_add_beacon_time(priv->last_beacon_time,
961 add_time,
962 le16_to_cpu(priv->rxon_timing.beacon_interval));
963 else
964 spectrum.start_time = 0;
965
966 spectrum.channels[0].duration = cpu_to_le32(duration * TIME_UNIT);
967 spectrum.channels[0].channel = params->channel;
968 spectrum.channels[0].type = type;
969 if (priv->active_rxon.flags & RXON_FLG_BAND_24G_MSK)
970 spectrum.flags |= RXON_FLG_BAND_24G_MSK |
971 RXON_FLG_AUTO_DETECT_MSK | RXON_FLG_TGG_PROTECT_MSK;
972
973 rc = iwl_send_cmd_sync(priv, &cmd);
974 if (rc)
975 return rc;
976
977 res = (struct iwl_rx_packet *)cmd.meta.u.skb->data;
978 if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
979 IWL_ERROR("Bad return from REPLY_RX_ON_ASSOC command\n");
980 rc = -EIO;
981 }
982
983 spectrum_resp_status = le16_to_cpu(res->u.spectrum.status);
984 switch (spectrum_resp_status) {
985 case 0: /* Command will be handled */
986 if (res->u.spectrum.id != 0xff) {
987 IWL_DEBUG_INFO
988 ("Replaced existing measurement: %d\n",
989 res->u.spectrum.id);
990 priv->measurement_status &= ~MEASUREMENT_READY;
991 }
992 priv->measurement_status |= MEASUREMENT_ACTIVE;
993 rc = 0;
994 break;
995
996 case 1: /* Command will not be handled */
997 rc = -EAGAIN;
998 break;
999 }
1000
1001 dev_kfree_skb_any(cmd.meta.u.skb);
1002
1003 return rc;
1004}
1005#endif
1006 874
1007/****************************************************************************** 875/******************************************************************************
1008 * 876 *
@@ -1072,24 +940,6 @@ static void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
1072 priv->staging_rxon.channel = csa->channel; 940 priv->staging_rxon.channel = csa->channel;
1073} 941}
1074 942
1075static void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv,
1076 struct iwl_rx_mem_buffer *rxb)
1077{
1078#ifdef CONFIG_IWLAGN_SPECTRUM_MEASUREMENT
1079 struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
1080 struct iwl4965_spectrum_notification *report = &(pkt->u.spectrum_notif);
1081
1082 if (!report->state) {
1083 IWL_DEBUG(IWL_DL_11H,
1084 "Spectrum Measure Notification: Start\n");
1085 return;
1086 }
1087
1088 memcpy(&priv->measure_report, report, sizeof(*report));
1089 priv->measurement_status |= MEASUREMENT_READY;
1090#endif
1091}
1092
1093static void iwl_rx_pm_sleep_notif(struct iwl_priv *priv, 943static void iwl_rx_pm_sleep_notif(struct iwl_priv *priv,
1094 struct iwl_rx_mem_buffer *rxb) 944 struct iwl_rx_mem_buffer *rxb)
1095{ 945{
@@ -1298,8 +1148,6 @@ static void iwl_setup_rx_handlers(struct iwl_priv *priv)
1298 priv->rx_handlers[REPLY_ALIVE] = iwl_rx_reply_alive; 1148 priv->rx_handlers[REPLY_ALIVE] = iwl_rx_reply_alive;
1299 priv->rx_handlers[REPLY_ERROR] = iwl_rx_reply_error; 1149 priv->rx_handlers[REPLY_ERROR] = iwl_rx_reply_error;
1300 priv->rx_handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl_rx_csa; 1150 priv->rx_handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl_rx_csa;
1301 priv->rx_handlers[SPECTRUM_MEASURE_NOTIFICATION] =
1302 iwl_rx_spectrum_measure_notif;
1303 priv->rx_handlers[PM_SLEEP_NOTIFICATION] = iwl_rx_pm_sleep_notif; 1151 priv->rx_handlers[PM_SLEEP_NOTIFICATION] = iwl_rx_pm_sleep_notif;
1304 priv->rx_handlers[PM_DEBUG_STATISTIC_NOTIFIC] = 1152 priv->rx_handlers[PM_DEBUG_STATISTIC_NOTIFIC] =
1305 iwl_rx_pm_debug_statistics_notif; 1153 iwl_rx_pm_debug_statistics_notif;
@@ -1313,6 +1161,7 @@ static void iwl_setup_rx_handlers(struct iwl_priv *priv)
1313 priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl_rx_statistics; 1161 priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl_rx_statistics;
1314 priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl_rx_statistics; 1162 priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl_rx_statistics;
1315 1163
1164 iwl_setup_spectrum_handlers(priv);
1316 iwl_setup_rx_scan_handlers(priv); 1165 iwl_setup_rx_scan_handlers(priv);
1317 1166
1318 /* status change handler */ 1167 /* status change handler */
@@ -1359,7 +1208,7 @@ void iwl_rx_handle(struct iwl_priv *priv)
1359 1208
1360 /* uCode's read index (stored in shared DRAM) indicates the last Rx 1209 /* uCode's read index (stored in shared DRAM) indicates the last Rx
1361 * buffer that the driver may process (last buffer filled by ucode). */ 1210 * buffer that the driver may process (last buffer filled by ucode). */
1362 r = priv->cfg->ops->lib->shared_mem_rx_idx(priv); 1211 r = le16_to_cpu(rxq->rb_stts->closed_rb_num) & 0x0FFF;
1363 i = rxq->read; 1212 i = rxq->read;
1364 1213
1365 /* Rx interrupt, but nothing sent from uCode */ 1214 /* Rx interrupt, but nothing sent from uCode */
@@ -2002,6 +1851,10 @@ static int iwl_read_ucode(struct iwl_priv *priv)
2002 return ret; 1851 return ret;
2003} 1852}
2004 1853
1854/* temporary */
1855static int iwl_mac_beacon_update(struct ieee80211_hw *hw,
1856 struct sk_buff *skb);
1857
2005/** 1858/**
2006 * iwl_alive_start - called after REPLY_ALIVE notification received 1859 * iwl_alive_start - called after REPLY_ALIVE notification received
2007 * from protocol/runtime uCode (initialization uCode's 1860 * from protocol/runtime uCode (initialization uCode's
@@ -2084,6 +1937,15 @@ static void iwl_alive_start(struct iwl_priv *priv)
2084 1937
2085 iwl_power_update_mode(priv, 1); 1938 iwl_power_update_mode(priv, 1);
2086 1939
1940 /* reassociate for ADHOC mode */
1941 if (priv->vif && (priv->iw_mode == NL80211_IFTYPE_ADHOC)) {
1942 struct sk_buff *beacon = ieee80211_beacon_get(priv->hw,
1943 priv->vif);
1944 if (beacon)
1945 iwl_mac_beacon_update(priv->hw, beacon);
1946 }
1947
1948
2087 if (test_and_clear_bit(STATUS_MODE_PENDING, &priv->status)) 1949 if (test_and_clear_bit(STATUS_MODE_PENDING, &priv->status))
2088 iwl_set_mode(priv, priv->iw_mode); 1950 iwl_set_mode(priv, priv->iw_mode);
2089 1951
@@ -2183,8 +2045,6 @@ static void __iwl_down(struct iwl_priv *priv)
2183 priv->cfg->ops->lib->apm_ops.stop(priv); 2045 priv->cfg->ops->lib->apm_ops.stop(priv);
2184 else 2046 else
2185 priv->cfg->ops->lib->apm_ops.reset(priv); 2047 priv->cfg->ops->lib->apm_ops.reset(priv);
2186 priv->cfg->ops->lib->free_shared_mem(priv);
2187
2188 exit: 2048 exit:
2189 memset(&priv->card_alive, 0, sizeof(struct iwl_alive_resp)); 2049 memset(&priv->card_alive, 0, sizeof(struct iwl_alive_resp));
2190 2050
@@ -2237,12 +2097,6 @@ static int __iwl_up(struct iwl_priv *priv)
2237 2097
2238 iwl_write32(priv, CSR_INT, 0xFFFFFFFF); 2098 iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
2239 2099
2240 ret = priv->cfg->ops->lib->alloc_shared_mem(priv);
2241 if (ret) {
2242 IWL_ERROR("Unable to allocate shared memory\n");
2243 return ret;
2244 }
2245
2246 ret = iwl_hw_nic_init(priv); 2100 ret = iwl_hw_nic_init(priv);
2247 if (ret) { 2101 if (ret) {
2248 IWL_ERROR("Unable to init nic\n"); 2102 IWL_ERROR("Unable to init nic\n");
@@ -2930,8 +2784,6 @@ static void iwl_config_ap(struct iwl_priv *priv)
2930 * clear sta table, add BCAST sta... */ 2784 * clear sta table, add BCAST sta... */
2931} 2785}
2932 2786
2933/* temporary */
2934static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb);
2935 2787
2936static int iwl_mac_config_interface(struct ieee80211_hw *hw, 2788static int iwl_mac_config_interface(struct ieee80211_hw *hw,
2937 struct ieee80211_vif *vif, 2789 struct ieee80211_vif *vif,
@@ -2953,7 +2805,9 @@ static int iwl_mac_config_interface(struct ieee80211_hw *hw,
2953 struct sk_buff *beacon = ieee80211_beacon_get(hw, vif); 2805 struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
2954 if (!beacon) 2806 if (!beacon)
2955 return -ENOMEM; 2807 return -ENOMEM;
2808 mutex_lock(&priv->mutex);
2956 rc = iwl_mac_beacon_update(hw, beacon); 2809 rc = iwl_mac_beacon_update(hw, beacon);
2810 mutex_unlock(&priv->mutex);
2957 if (rc) 2811 if (rc)
2958 return rc; 2812 return rc;
2959 } 2813 }
@@ -3529,18 +3383,15 @@ static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
3529 unsigned long flags; 3383 unsigned long flags;
3530 __le64 timestamp; 3384 __le64 timestamp;
3531 3385
3532 mutex_lock(&priv->mutex);
3533 IWL_DEBUG_MAC80211("enter\n"); 3386 IWL_DEBUG_MAC80211("enter\n");
3534 3387
3535 if (!iwl_is_ready_rf(priv)) { 3388 if (!iwl_is_ready_rf(priv)) {
3536 IWL_DEBUG_MAC80211("leave - RF not ready\n"); 3389 IWL_DEBUG_MAC80211("leave - RF not ready\n");
3537 mutex_unlock(&priv->mutex);
3538 return -EIO; 3390 return -EIO;
3539 } 3391 }
3540 3392
3541 if (priv->iw_mode != NL80211_IFTYPE_ADHOC) { 3393 if (priv->iw_mode != NL80211_IFTYPE_ADHOC) {
3542 IWL_DEBUG_MAC80211("leave - not IBSS\n"); 3394 IWL_DEBUG_MAC80211("leave - not IBSS\n");
3543 mutex_unlock(&priv->mutex);
3544 return -EIO; 3395 return -EIO;
3545 } 3396 }
3546 3397
@@ -3562,7 +3413,6 @@ static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
3562 3413
3563 iwl_post_associate(priv); 3414 iwl_post_associate(priv);
3564 3415
3565 mutex_unlock(&priv->mutex);
3566 3416
3567 return 0; 3417 return 0;
3568} 3418}
@@ -3766,79 +3616,6 @@ static ssize_t store_filter_flags(struct device *d,
3766static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, show_filter_flags, 3616static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, show_filter_flags,
3767 store_filter_flags); 3617 store_filter_flags);
3768 3618
3769#ifdef CONFIG_IWLAGN_SPECTRUM_MEASUREMENT
3770
3771static ssize_t show_measurement(struct device *d,
3772 struct device_attribute *attr, char *buf)
3773{
3774 struct iwl_priv *priv = dev_get_drvdata(d);
3775 struct iwl4965_spectrum_notification measure_report;
3776 u32 size = sizeof(measure_report), len = 0, ofs = 0;
3777 u8 *data = (u8 *)&measure_report;
3778 unsigned long flags;
3779
3780 spin_lock_irqsave(&priv->lock, flags);
3781 if (!(priv->measurement_status & MEASUREMENT_READY)) {
3782 spin_unlock_irqrestore(&priv->lock, flags);
3783 return 0;
3784 }
3785 memcpy(&measure_report, &priv->measure_report, size);
3786 priv->measurement_status = 0;
3787 spin_unlock_irqrestore(&priv->lock, flags);
3788
3789 while (size && (PAGE_SIZE - len)) {
3790 hex_dump_to_buffer(data + ofs, size, 16, 1, buf + len,
3791 PAGE_SIZE - len, 1);
3792 len = strlen(buf);
3793 if (PAGE_SIZE - len)
3794 buf[len++] = '\n';
3795
3796 ofs += 16;
3797 size -= min(size, 16U);
3798 }
3799
3800 return len;
3801}
3802
3803static ssize_t store_measurement(struct device *d,
3804 struct device_attribute *attr,
3805 const char *buf, size_t count)
3806{
3807 struct iwl_priv *priv = dev_get_drvdata(d);
3808 struct ieee80211_measurement_params params = {
3809 .channel = le16_to_cpu(priv->active_rxon.channel),
3810 .start_time = cpu_to_le64(priv->last_tsf),
3811 .duration = cpu_to_le16(1),
3812 };
3813 u8 type = IWL_MEASURE_BASIC;
3814 u8 buffer[32];
3815 u8 channel;
3816
3817 if (count) {
3818 char *p = buffer;
3819 strncpy(buffer, buf, min(sizeof(buffer), count));
3820 channel = simple_strtoul(p, NULL, 0);
3821 if (channel)
3822 params.channel = channel;
3823
3824 p = buffer;
3825 while (*p && *p != ' ')
3826 p++;
3827 if (*p)
3828 type = simple_strtoul(p + 1, NULL, 0);
3829 }
3830
3831 IWL_DEBUG_INFO("Invoking measurement of type %d on "
3832 "channel %d (for '%s')\n", type, params.channel, buf);
3833 iwl_get_measurement(priv, &params, type);
3834
3835 return count;
3836}
3837
3838static DEVICE_ATTR(measurement, S_IRUSR | S_IWUSR,
3839 show_measurement, store_measurement);
3840#endif /* CONFIG_IWLAGN_SPECTRUM_MEASUREMENT */
3841
3842static ssize_t store_retry_rate(struct device *d, 3619static ssize_t store_retry_rate(struct device *d,
3843 struct device_attribute *attr, 3620 struct device_attribute *attr,
3844 const char *buf, size_t count) 3621 const char *buf, size_t count)
@@ -4091,9 +3868,6 @@ static struct attribute *iwl_sysfs_entries[] = {
4091 &dev_attr_channels.attr, 3868 &dev_attr_channels.attr,
4092 &dev_attr_flags.attr, 3869 &dev_attr_flags.attr,
4093 &dev_attr_filter_flags.attr, 3870 &dev_attr_filter_flags.attr,
4094#ifdef CONFIG_IWLAGN_SPECTRUM_MEASUREMENT
4095 &dev_attr_measurement.attr,
4096#endif
4097 &dev_attr_power_level.attr, 3871 &dev_attr_power_level.attr,
4098 &dev_attr_retry_rate.attr, 3872 &dev_attr_retry_rate.attr,
4099 &dev_attr_statistics.attr, 3873 &dev_attr_statistics.attr,
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index 8aade00e165a..1fe83d45443a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -213,10 +213,11 @@ struct iwl_cmd_header {
213} __attribute__ ((packed)); 213} __attribute__ ((packed));
214 214
215/** 215/**
216 * 4965 rate_n_flags bit fields 216 * iwlagn rate_n_flags bit fields
217 * 217 *
218 * rate_n_flags format is used in following 4965 commands: 218 * rate_n_flags format is used in following iwlagn commands:
219 * REPLY_RX (response only) 219 * REPLY_RX (response only)
220 * REPLY_RX_MPDU (response only)
220 * REPLY_TX (both command and response) 221 * REPLY_TX (both command and response)
221 * REPLY_TX_LINK_QUALITY_CMD 222 * REPLY_TX_LINK_QUALITY_CMD
222 * 223 *
@@ -230,8 +231,9 @@ struct iwl_cmd_header {
230 * 6) 54 Mbps 231 * 6) 54 Mbps
231 * 7) 60 Mbps 232 * 7) 60 Mbps
232 * 233 *
233 * 3: 0) Single stream (SISO) 234 * 4-3: 0) Single stream (SISO)
234 * 1) Dual stream (MIMO) 235 * 1) Dual stream (MIMO)
236 * 2) Triple stream (MIMO)
235 * 237 *
236 * 5: Value of 0x20 in bits 7:0 indicates 6 Mbps FAT duplicate data 238 * 5: Value of 0x20 in bits 7:0 indicates 6 Mbps FAT duplicate data
237 * 239 *
@@ -252,8 +254,8 @@ struct iwl_cmd_header {
252 * 110) 11 Mbps 254 * 110) 11 Mbps
253 */ 255 */
254#define RATE_MCS_CODE_MSK 0x7 256#define RATE_MCS_CODE_MSK 0x7
255#define RATE_MCS_MIMO_POS 3 257#define RATE_MCS_SPATIAL_POS 3
256#define RATE_MCS_MIMO_MSK 0x8 258#define RATE_MCS_SPATIAL_MSK 0x18
257#define RATE_MCS_HT_DUP_POS 5 259#define RATE_MCS_HT_DUP_POS 5
258#define RATE_MCS_HT_DUP_MSK 0x20 260#define RATE_MCS_HT_DUP_MSK 0x20
259 261
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 8eb02031e797..8bd4d087d4e2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -30,10 +30,9 @@
30#include <linux/module.h> 30#include <linux/module.h>
31#include <net/mac80211.h> 31#include <net/mac80211.h>
32 32
33struct iwl_priv; /* FIXME: remove */
34#include "iwl-debug.h"
35#include "iwl-eeprom.h" 33#include "iwl-eeprom.h"
36#include "iwl-dev.h" /* FIXME: remove */ 34#include "iwl-dev.h" /* FIXME: remove */
35#include "iwl-debug.h"
37#include "iwl-core.h" 36#include "iwl-core.h"
38#include "iwl-io.h" 37#include "iwl-io.h"
39#include "iwl-rfkill.h" 38#include "iwl-rfkill.h"
@@ -190,52 +189,6 @@ void iwl_hw_detect(struct iwl_priv *priv)
190} 189}
191EXPORT_SYMBOL(iwl_hw_detect); 190EXPORT_SYMBOL(iwl_hw_detect);
192 191
193/* Tell nic where to find the "keep warm" buffer */
194int iwl_kw_init(struct iwl_priv *priv)
195{
196 unsigned long flags;
197 int ret;
198
199 spin_lock_irqsave(&priv->lock, flags);
200 ret = iwl_grab_nic_access(priv);
201 if (ret)
202 goto out;
203
204 iwl_write_direct32(priv, FH_KW_MEM_ADDR_REG,
205 priv->kw.dma_addr >> 4);
206 iwl_release_nic_access(priv);
207out:
208 spin_unlock_irqrestore(&priv->lock, flags);
209 return ret;
210}
211
212int iwl_kw_alloc(struct iwl_priv *priv)
213{
214 struct pci_dev *dev = priv->pci_dev;
215 struct iwl_kw *kw = &priv->kw;
216
217 kw->size = IWL_KW_SIZE;
218 kw->v_addr = pci_alloc_consistent(dev, kw->size, &kw->dma_addr);
219 if (!kw->v_addr)
220 return -ENOMEM;
221
222 return 0;
223}
224
225/**
226 * iwl_kw_free - Free the "keep warm" buffer
227 */
228void iwl_kw_free(struct iwl_priv *priv)
229{
230 struct pci_dev *dev = priv->pci_dev;
231 struct iwl_kw *kw = &priv->kw;
232
233 if (kw->v_addr) {
234 pci_free_consistent(dev, kw->size, kw->v_addr, kw->dma_addr);
235 memset(kw, 0, sizeof(*kw));
236 }
237}
238
239int iwl_hw_nic_init(struct iwl_priv *priv) 192int iwl_hw_nic_init(struct iwl_priv *priv)
240{ 193{
241 unsigned long flags; 194 unsigned long flags;
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 10f07f6e1737..ff966b8a0c6d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -102,10 +102,6 @@ struct iwl_hcmd_utils_ops {
102struct iwl_lib_ops { 102struct iwl_lib_ops {
103 /* set hw dependent parameters */ 103 /* set hw dependent parameters */
104 int (*set_hw_params)(struct iwl_priv *priv); 104 int (*set_hw_params)(struct iwl_priv *priv);
105 /* ucode shared memory */
106 int (*alloc_shared_mem)(struct iwl_priv *priv);
107 void (*free_shared_mem)(struct iwl_priv *priv);
108 int (*shared_mem_rx_idx)(struct iwl_priv *priv);
109 /* Handling TX */ 105 /* Handling TX */
110 void (*txq_update_byte_cnt_tbl)(struct iwl_priv *priv, 106 void (*txq_update_byte_cnt_tbl)(struct iwl_priv *priv,
111 struct iwl_tx_queue *txq, 107 struct iwl_tx_queue *txq,
@@ -198,10 +194,6 @@ int iwl_setup_mac(struct iwl_priv *priv);
198int iwl_set_hw_params(struct iwl_priv *priv); 194int iwl_set_hw_params(struct iwl_priv *priv);
199int iwl_init_drv(struct iwl_priv *priv); 195int iwl_init_drv(struct iwl_priv *priv);
200void iwl_uninit_drv(struct iwl_priv *priv); 196void iwl_uninit_drv(struct iwl_priv *priv);
201/* "keep warm" functions */
202int iwl_kw_init(struct iwl_priv *priv);
203int iwl_kw_alloc(struct iwl_priv *priv);
204void iwl_kw_free(struct iwl_priv *priv);
205 197
206/***************************************************** 198/*****************************************************
207* RX 199* RX
@@ -297,6 +289,14 @@ int iwl_send_calib_results(struct iwl_priv *priv);
297int iwl_calib_set(struct iwl_calib_result *res, const u8 *buf, int len); 289int iwl_calib_set(struct iwl_calib_result *res, const u8 *buf, int len);
298void iwl_calib_free_results(struct iwl_priv *priv); 290void iwl_calib_free_results(struct iwl_priv *priv);
299 291
292/*******************************************************************************
293 * Spectrum Measureemtns in iwl-spectrum.c
294 ******************************************************************************/
295#ifdef CONFIG_IWLAGN_SPECTRUM_MEASUREMENT
296void iwl_setup_spectrum_handlers(struct iwl_priv *priv);
297#else
298static inline void iwl_setup_spectrum_handlers(struct iwl_priv *priv) {}
299#endif
300/***************************************************** 300/*****************************************************
301 * S e n d i n g H o s t C o m m a n d s * 301 * S e n d i n g H o s t C o m m a n d s *
302 *****************************************************/ 302 *****************************************************/
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h
index 84b7772809e3..0e79a6ab4c81 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debug.h
+++ b/drivers/net/wireless/iwlwifi/iwl-debug.h
@@ -40,6 +40,13 @@ do { if ((priv->debug_level & (level)) && net_ratelimit()) \
40 dev_printk(KERN_ERR, &(priv->hw->wiphy->dev), "%c %s " fmt, \ 40 dev_printk(KERN_ERR, &(priv->hw->wiphy->dev), "%c %s " fmt, \
41 in_interrupt() ? 'I' : 'U', __func__ , ## args); } while (0) 41 in_interrupt() ? 'I' : 'U', __func__ , ## args); } while (0)
42 42
43#define iwl_print_hex_dump(priv, level, p, len) \
44do { \
45 if (priv->debug_level & level) \
46 print_hex_dump(KERN_DEBUG, "iwl data: ", \
47 DUMP_PREFIX_OFFSET, 16, 1, p, len, 1); \
48} while (0)
49
43#ifdef CONFIG_IWLWIFI_DEBUGFS 50#ifdef CONFIG_IWLWIFI_DEBUGFS
44struct iwl_debugfs { 51struct iwl_debugfs {
45 const char *name; 52 const char *name;
@@ -70,6 +77,9 @@ void iwl_dbgfs_unregister(struct iwl_priv *priv);
70#else 77#else
71#define IWL_DEBUG(level, fmt, args...) 78#define IWL_DEBUG(level, fmt, args...)
72#define IWL_DEBUG_LIMIT(level, fmt, args...) 79#define IWL_DEBUG_LIMIT(level, fmt, args...)
80static inline void iwl_print_hex_dump(struct iwl_priv *priv, int level,
81 void *p, u32 len)
82{}
73#endif /* CONFIG_IWLWIFI_DEBUG */ 83#endif /* CONFIG_IWLWIFI_DEBUG */
74 84
75 85
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index d509aed5567a..bd3df55e4953 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -301,7 +301,6 @@ struct iwl_host_cmd {
301 301
302/** 302/**
303 * struct iwl_rx_queue - Rx queue 303 * struct iwl_rx_queue - Rx queue
304 * @processed: Internal index to last handled Rx packet
305 * @read: Shared index to newest available Rx buffer 304 * @read: Shared index to newest available Rx buffer
306 * @write: Shared index to oldest written Rx packet 305 * @write: Shared index to oldest written Rx packet
307 * @free_count: Number of pre-allocated buffers in rx_free 306 * @free_count: Number of pre-allocated buffers in rx_free
@@ -316,13 +315,14 @@ struct iwl_rx_queue {
316 dma_addr_t dma_addr; 315 dma_addr_t dma_addr;
317 struct iwl_rx_mem_buffer pool[RX_QUEUE_SIZE + RX_FREE_BUFFERS]; 316 struct iwl_rx_mem_buffer pool[RX_QUEUE_SIZE + RX_FREE_BUFFERS];
318 struct iwl_rx_mem_buffer *queue[RX_QUEUE_SIZE]; 317 struct iwl_rx_mem_buffer *queue[RX_QUEUE_SIZE];
319 u32 processed;
320 u32 read; 318 u32 read;
321 u32 write; 319 u32 write;
322 u32 free_count; 320 u32 free_count;
323 struct list_head rx_free; 321 struct list_head rx_free;
324 struct list_head rx_used; 322 struct list_head rx_used;
325 int need_update; 323 int need_update;
324 struct iwl_rb_status *rb_stts;
325 dma_addr_t rb_stts_dma;
326 spinlock_t lock; 326 spinlock_t lock;
327}; 327};
328 328
@@ -507,6 +507,7 @@ struct iwl_sensitivity_ranges {
507/** 507/**
508 * struct iwl_hw_params 508 * struct iwl_hw_params
509 * @max_txq_num: Max # Tx queues supported 509 * @max_txq_num: Max # Tx queues supported
510 * @scd_bc_tbls_size: size of scheduler byte count tables
510 * @tx/rx_chains_num: Number of TX/RX chains 511 * @tx/rx_chains_num: Number of TX/RX chains
511 * @valid_tx/rx_ant: usable antennas 512 * @valid_tx/rx_ant: usable antennas
512 * @max_rxq_size: Max # Rx frames in Rx queue (must be power-of-2) 513 * @max_rxq_size: Max # Rx frames in Rx queue (must be power-of-2)
@@ -524,6 +525,7 @@ struct iwl_sensitivity_ranges {
524 */ 525 */
525struct iwl_hw_params { 526struct iwl_hw_params {
526 u16 max_txq_num; 527 u16 max_txq_num;
528 u16 scd_bc_tbls_size;
527 u8 tx_chains_num; 529 u8 tx_chains_num;
528 u8 rx_chains_num; 530 u8 rx_chains_num;
529 u8 valid_tx_ant; 531 u8 valid_tx_ant;
@@ -605,13 +607,9 @@ static inline u8 get_cmd_index(struct iwl_queue *q, u32 index, int is_huge)
605struct iwl_priv; 607struct iwl_priv;
606 608
607 609
608/* Structures, enum, and defines specific to the 4965 */ 610struct iwl_dma_ptr {
609 611 dma_addr_t dma;
610#define IWL_KW_SIZE 0x1000 /*4k */ 612 void *addr;
611
612struct iwl_kw {
613 dma_addr_t dma_addr;
614 void *v_addr;
615 size_t size; 613 size_t size;
616}; 614};
617 615
@@ -907,7 +905,9 @@ struct iwl_priv {
907 struct iwl_rx_queue rxq; 905 struct iwl_rx_queue rxq;
908 struct iwl_tx_queue txq[IWL_MAX_NUM_QUEUES]; 906 struct iwl_tx_queue txq[IWL_MAX_NUM_QUEUES];
909 unsigned long txq_ctx_active_msk; 907 unsigned long txq_ctx_active_msk;
910 struct iwl_kw kw; /* keep warm address */ 908 struct iwl_dma_ptr kw; /* keep warm address */
909 struct iwl_dma_ptr scd_bc_tbls;
910
911 u32 scd_base_addr; /* scheduler sram base address */ 911 u32 scd_base_addr; /* scheduler sram base address */
912 912
913 unsigned long status; 913 unsigned long status;
@@ -967,11 +967,7 @@ struct iwl_priv {
967 struct ieee80211_vif *vif; 967 struct ieee80211_vif *vif;
968 968
969 struct iwl_hw_params hw_params; 969 struct iwl_hw_params hw_params;
970 /* driver/uCode shared Tx Byte Counts and Rx status */ 970
971 void *shared_virt;
972 int rb_closed_offset;
973 /* Physical Pointer to Tx Byte Counts and Rx status */
974 dma_addr_t shared_phys;
975 971
976 /* Current association information needed to configure the 972 /* Current association information needed to configure the
977 * hardware */ 973 * hardware */
@@ -1093,23 +1089,6 @@ static inline int is_channel_ibss(const struct iwl_channel_info *ch)
1093 return ((ch->flags & EEPROM_CHANNEL_IBSS)) ? 1 : 0; 1089 return ((ch->flags & EEPROM_CHANNEL_IBSS)) ? 1 : 0;
1094} 1090}
1095 1091
1096#ifdef CONFIG_IWLWIFI_DEBUG
1097static inline void iwl_print_hex_dump(struct iwl_priv *priv, int level,
1098 void *p, u32 len)
1099{
1100 if (!(priv->debug_level & level))
1101 return;
1102
1103 print_hex_dump(KERN_DEBUG, "iwl data: ", DUMP_PREFIX_OFFSET, 16, 1,
1104 p, len, 1);
1105}
1106#else
1107static inline void iwl_print_hex_dump(struct iwl_priv *priv, int level,
1108 void *p, u32 len)
1109{
1110}
1111#endif
1112
1113extern const struct iwl_channel_info *iwl_get_channel_info( 1092extern const struct iwl_channel_info *iwl_get_channel_info(
1114 const struct iwl_priv *priv, enum ieee80211_band band, u16 channel); 1093 const struct iwl_priv *priv, enum ieee80211_band band, u16 channel);
1115 1094
diff --git a/drivers/net/wireless/iwlwifi/iwl-fh.h b/drivers/net/wireless/iwlwifi/iwl-fh.h
index 97e2cf41258d..e46300c28a8f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fh.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fh.h
@@ -266,6 +266,8 @@
266#define FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_NO_INT_VAL (0x00000000) 266#define FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_NO_INT_VAL (0x00000000)
267#define FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL (0x00001000) 267#define FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL (0x00001000)
268 268
269#define FH_RCSR_CHNL0_RX_CONFIG_SINGLE_FRAME (0x00008000)
270
269 271
270/** 272/**
271 * Rx Shared Status Registers (RSSR) 273 * Rx Shared Status Registers (RSSR)
@@ -403,5 +405,86 @@
403#define TFD_QUEUE_SIZE_BC_DUP (64) 405#define TFD_QUEUE_SIZE_BC_DUP (64)
404#define TFD_QUEUE_BC_SIZE (TFD_QUEUE_SIZE_MAX + TFD_QUEUE_SIZE_BC_DUP) 406#define TFD_QUEUE_BC_SIZE (TFD_QUEUE_SIZE_MAX + TFD_QUEUE_SIZE_BC_DUP)
405 407
408/**
409 * struct iwl_rb_status - reseve buffer status
410 * host memory mapped FH registers
411 * @closed_rb_num [0:11] - Indicates the index of the RB which was closed
412 * @closed_fr_num [0:11] - Indicates the index of the RX Frame which was closed
413 * @finished_rb_num [0:11] - Indicates the index of the current RB
414 * in which the last frame was written to
415 * @finished_fr_num [0:11] - Indicates the index of the RX Frame
416 * which was transfered
417 */
418struct iwl_rb_status {
419 __le16 closed_rb_num;
420 __le16 closed_fr_num;
421 __le16 finished_rb_num;
422 __le16 finished_fr_nam;
423} __attribute__ ((packed));
424
425
426
427#define IWL_TX_DMA_MASK DMA_BIT_MASK(36)
428
429#define IWL_NUM_OF_TBS 20
430
431static inline u8 iwl_get_dma_hi_addr(dma_addr_t addr)
432{
433 return (sizeof(addr) > sizeof(u32) ? (addr >> 16) >> 16 : 0) & 0xF;
434}
435/**
436 * struct iwl_tfd_tb transmit buffer descriptor within transmit frame descriptor
437 *
438 * This structure contains dma address and length of transmission address
439 *
440 * @lo: low [31:0] portion of the dma address of TX buffer
441 * every even is unaligned on 16 bit boundary
442 * @hi_n_len 0-3 [35:32] portion of dma
443 * 4-16 length of the tx buffer
444 */
445struct iwl_tfd_tb {
446 __le32 lo;
447 __le16 hi_n_len;
448} __attribute__((packed));
449
450/**
451 * struct iwl_tfd
452 *
453 * Transmit Frame Descriptor (TFD)
454 *
455 * @ __reserved1[3] reserved
456 * @ num_tbs 0-5 number of active tbs
457 * 6-7 padding (not used)
458 * @ tbs[20] transmit frame buffer descriptors
459 * @ __pad padding
460 *
461 * Each Tx queue uses a circular buffer of 256 TFDs stored in host DRAM.
462 * Both driver and device share these circular buffers, each of which must be
463 * contiguous 256 TFDs x 128 bytes-per-TFD = 32 KBytes
464 *
465 * Driver must indicate the physical address of the base of each
466 * circular buffer via the FH_MEM_CBBC_QUEUE registers.
467 *
468 * Each TFD contains pointer/size information for up to 20 data buffers
469 * in host DRAM. These buffers collectively contain the (one) frame described
470 * by the TFD. Each buffer must be a single contiguous block of memory within
471 * itself, but buffers may be scattered in host DRAM. Each buffer has max size
472 * of (4K - 4). The concatenates all of a TFD's buffers into a single
473 * Tx frame, up to 8 KBytes in size.
474 *
475 * A maximum of 255 (not 256!) TFDs may be on a queue waiting for Tx.
476 *
477 * Bit fields in the control dword (val0):
478 */
479struct iwl_tfd {
480 u8 __reserved1[3];
481 u8 num_tbs;
482 struct iwl_tfd_tb tbs[IWL_NUM_OF_TBS];
483 __le32 __pad;
484} __attribute__ ((packed));
485
486
487/* Keep Warm Size */
488#define IWL_KW_SIZE 0x1000 /*4k */
406 489
407#endif /* !__iwl_fh_h__ */ 490#endif /* !__iwl_fh_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c
index 07a5f60e9229..b429daa5a2bc 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.c
+++ b/drivers/net/wireless/iwlwifi/iwl-power.c
@@ -257,15 +257,11 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force)
257 struct iwl_power_mgr *setting = &(priv->power_data); 257 struct iwl_power_mgr *setting = &(priv->power_data);
258 int ret = 0; 258 int ret = 0;
259 u16 uninitialized_var(final_mode); 259 u16 uninitialized_var(final_mode);
260 bool update_chains;
260 261
261 /* Don't update the RX chain when chain noise calibration is running */ 262 /* Don't update the RX chain when chain noise calibration is running */
262 if (priv->chain_noise_data.state != IWL_CHAIN_NOISE_DONE && 263 update_chains = priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE ||
263 priv->chain_noise_data.state != IWL_CHAIN_NOISE_ALIVE) { 264 priv->chain_noise_data.state == IWL_CHAIN_NOISE_ALIVE;
264 IWL_DEBUG_POWER("Cannot update the power, chain noise "
265 "calibration running: %d\n",
266 priv->chain_noise_data.state);
267 return -EAGAIN;
268 }
269 265
270 /* If on battery, set to 3, 266 /* If on battery, set to 3,
271 * if plugged into AC power, set to CAM ("continuously aware mode"), 267 * if plugged into AC power, set to CAM ("continuously aware mode"),
@@ -313,9 +309,12 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force)
313 else 309 else
314 set_bit(STATUS_POWER_PMI, &priv->status); 310 set_bit(STATUS_POWER_PMI, &priv->status);
315 311
316 if (priv->cfg->ops->lib->update_chain_flags) 312 if (priv->cfg->ops->lib->update_chain_flags && update_chains)
317 priv->cfg->ops->lib->update_chain_flags(priv); 313 priv->cfg->ops->lib->update_chain_flags(priv);
318 314 else
315 IWL_DEBUG_POWER("Cannot update the power, chain noise "
316 "calibration running: %d\n",
317 priv->chain_noise_data.state);
319 if (!ret) 318 if (!ret)
320 setting->power_mode = final_mode; 319 setting->power_mode = final_mode;
321 } 320 }
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index b3c35c64d042..876afd4cab9e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -218,8 +218,7 @@ int iwl_rx_queue_restock(struct iwl_priv *priv)
218 218
219 /* If we've added more space for the firmware to place data, tell it. 219 /* If we've added more space for the firmware to place data, tell it.
220 * Increment device's write pointer in multiples of 8. */ 220 * Increment device's write pointer in multiples of 8. */
221 if ((write != (rxq->write & ~0x7)) 221 if (write != (rxq->write & ~0x7)) {
222 || (abs(rxq->write - rxq->read) > 7)) {
223 spin_lock_irqsave(&rxq->lock, flags); 222 spin_lock_irqsave(&rxq->lock, flags);
224 rxq->need_update = 1; 223 rxq->need_update = 1;
225 spin_unlock_irqrestore(&rxq->lock, flags); 224 spin_unlock_irqrestore(&rxq->lock, flags);
@@ -317,7 +316,10 @@ void iwl_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
317 316
318 pci_free_consistent(priv->pci_dev, 4 * RX_QUEUE_SIZE, rxq->bd, 317 pci_free_consistent(priv->pci_dev, 4 * RX_QUEUE_SIZE, rxq->bd,
319 rxq->dma_addr); 318 rxq->dma_addr);
319 pci_free_consistent(priv->pci_dev, sizeof(struct iwl_rb_status),
320 rxq->rb_stts, rxq->rb_stts_dma);
320 rxq->bd = NULL; 321 rxq->bd = NULL;
322 rxq->rb_stts = NULL;
321} 323}
322EXPORT_SYMBOL(iwl_rx_queue_free); 324EXPORT_SYMBOL(iwl_rx_queue_free);
323 325
@@ -334,7 +336,12 @@ int iwl_rx_queue_alloc(struct iwl_priv *priv)
334 /* Alloc the circular buffer of Read Buffer Descriptors (RBDs) */ 336 /* Alloc the circular buffer of Read Buffer Descriptors (RBDs) */
335 rxq->bd = pci_alloc_consistent(dev, 4 * RX_QUEUE_SIZE, &rxq->dma_addr); 337 rxq->bd = pci_alloc_consistent(dev, 4 * RX_QUEUE_SIZE, &rxq->dma_addr);
336 if (!rxq->bd) 338 if (!rxq->bd)
337 return -ENOMEM; 339 goto err_bd;
340
341 rxq->rb_stts = pci_alloc_consistent(dev, sizeof(struct iwl_rb_status),
342 &rxq->rb_stts_dma);
343 if (!rxq->rb_stts)
344 goto err_rb;
338 345
339 /* Fill the rx_used queue with _all_ of the Rx buffers */ 346 /* Fill the rx_used queue with _all_ of the Rx buffers */
340 for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) 347 for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++)
@@ -346,6 +353,12 @@ int iwl_rx_queue_alloc(struct iwl_priv *priv)
346 rxq->free_count = 0; 353 rxq->free_count = 0;
347 rxq->need_update = 0; 354 rxq->need_update = 0;
348 return 0; 355 return 0;
356
357err_rb:
358 pci_free_consistent(priv->pci_dev, 4 * RX_QUEUE_SIZE, rxq->bd,
359 rxq->dma_addr);
360err_bd:
361 return -ENOMEM;
349} 362}
350EXPORT_SYMBOL(iwl_rx_queue_alloc); 363EXPORT_SYMBOL(iwl_rx_queue_alloc);
351 364
@@ -412,7 +425,7 @@ int iwl_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
412 425
413 /* Tell device where in DRAM to update its Rx status */ 426 /* Tell device where in DRAM to update its Rx status */
414 iwl_write_direct32(priv, FH_RSCSR_CHNL0_STTS_WPTR_REG, 427 iwl_write_direct32(priv, FH_RSCSR_CHNL0_STTS_WPTR_REG,
415 (priv->shared_phys + priv->rb_closed_offset) >> 4); 428 rxq->rb_stts_dma >> 4);
416 429
417 /* Enable Rx DMA 430 /* Enable Rx DMA
418 * FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY is set because of HW bug in 431 * FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY is set because of HW bug in
@@ -426,6 +439,7 @@ int iwl_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
426 FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL | 439 FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL |
427 FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY | 440 FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY |
428 FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL | 441 FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL |
442 FH_RCSR_CHNL0_RX_CONFIG_SINGLE_FRAME |
429 rb_size| 443 rb_size|
430 (rb_timeout << FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_POS)| 444 (rb_timeout << FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_POS)|
431 (rfdnlog << FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS)); 445 (rfdnlog << FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS));
diff --git a/drivers/net/wireless/iwlwifi/iwl-spectrum.c b/drivers/net/wireless/iwlwifi/iwl-spectrum.c
new file mode 100644
index 000000000000..ad319a178a90
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-spectrum.c
@@ -0,0 +1,198 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
4 *
5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of version 2 of the GNU General Public License as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
16 *
17 * You should have received a copy of the GNU General Public License along with
18 * this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
20 *
21 * The full GNU General Public License is included in this distribution in the
22 * file called LICENSE.
23 *
24 * Contact Information:
25 * Intel Linux Wireless <ilw@linux.intel.com>
26 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
27 *
28 *****************************************************************************/
29
30#include <linux/kernel.h>
31#include <linux/module.h>
32#include <linux/init.h>
33#include <linux/pci.h>
34#include <linux/delay.h>
35#include <linux/skbuff.h>
36#include <linux/netdevice.h>
37#include <linux/wireless.h>
38
39#include <net/mac80211.h>
40
41#include "iwl-eeprom.h"
42#include "iwl-dev.h"
43#include "iwl-core.h"
44#include "iwl-io.h"
45#include "iwl-spectrum.h"
46
47#define BEACON_TIME_MASK_LOW 0x00FFFFFF
48#define BEACON_TIME_MASK_HIGH 0xFF000000
49#define TIME_UNIT 1024
50
51/*
52 * extended beacon time format
53 * time in usec will be changed into a 32-bit value in 8:24 format
54 * the high 1 byte is the beacon counts
55 * the lower 3 bytes is the time in usec within one beacon interval
56 */
57
58/* TOOD: was used in sysfs debug interface need to add to mac */
59#if 0
60static u32 iwl_usecs_to_beacons(u32 usec, u32 beacon_interval)
61{
62 u32 quot;
63 u32 rem;
64 u32 interval = beacon_interval * 1024;
65
66 if (!interval || !usec)
67 return 0;
68
69 quot = (usec / interval) & (BEACON_TIME_MASK_HIGH >> 24);
70 rem = (usec % interval) & BEACON_TIME_MASK_LOW;
71
72 return (quot << 24) + rem;
73}
74
75/* base is usually what we get from ucode with each received frame,
76 * the same as HW timer counter counting down
77 */
78
79static __le32 iwl_add_beacon_time(u32 base, u32 addon, u32 beacon_interval)
80{
81 u32 base_low = base & BEACON_TIME_MASK_LOW;
82 u32 addon_low = addon & BEACON_TIME_MASK_LOW;
83 u32 interval = beacon_interval * TIME_UNIT;
84 u32 res = (base & BEACON_TIME_MASK_HIGH) +
85 (addon & BEACON_TIME_MASK_HIGH);
86
87 if (base_low > addon_low)
88 res += base_low - addon_low;
89 else if (base_low < addon_low) {
90 res += interval + base_low - addon_low;
91 res += (1 << 24);
92 } else
93 res += (1 << 24);
94
95 return cpu_to_le32(res);
96}
97static int iwl_get_measurement(struct iwl_priv *priv,
98 struct ieee80211_measurement_params *params,
99 u8 type)
100{
101 struct iwl4965_spectrum_cmd spectrum;
102 struct iwl_rx_packet *res;
103 struct iwl_host_cmd cmd = {
104 .id = REPLY_SPECTRUM_MEASUREMENT_CMD,
105 .data = (void *)&spectrum,
106 .meta.flags = CMD_WANT_SKB,
107 };
108 u32 add_time = le64_to_cpu(params->start_time);
109 int rc;
110 int spectrum_resp_status;
111 int duration = le16_to_cpu(params->duration);
112
113 if (iwl_is_associated(priv))
114 add_time =
115 iwl_usecs_to_beacons(
116 le64_to_cpu(params->start_time) - priv->last_tsf,
117 le16_to_cpu(priv->rxon_timing.beacon_interval));
118
119 memset(&spectrum, 0, sizeof(spectrum));
120
121 spectrum.channel_count = cpu_to_le16(1);
122 spectrum.flags =
123 RXON_FLG_TSF2HOST_MSK | RXON_FLG_ANT_A_MSK | RXON_FLG_DIS_DIV_MSK;
124 spectrum.filter_flags = MEASUREMENT_FILTER_FLAG;
125 cmd.len = sizeof(spectrum);
126 spectrum.len = cpu_to_le16(cmd.len - sizeof(spectrum.len));
127
128 if (iwl_is_associated(priv))
129 spectrum.start_time =
130 iwl_add_beacon_time(priv->last_beacon_time,
131 add_time,
132 le16_to_cpu(priv->rxon_timing.beacon_interval));
133 else
134 spectrum.start_time = 0;
135
136 spectrum.channels[0].duration = cpu_to_le32(duration * TIME_UNIT);
137 spectrum.channels[0].channel = params->channel;
138 spectrum.channels[0].type = type;
139 if (priv->active_rxon.flags & RXON_FLG_BAND_24G_MSK)
140 spectrum.flags |= RXON_FLG_BAND_24G_MSK |
141 RXON_FLG_AUTO_DETECT_MSK | RXON_FLG_TGG_PROTECT_MSK;
142
143 rc = iwl_send_cmd_sync(priv, &cmd);
144 if (rc)
145 return rc;
146
147 res = (struct iwl_rx_packet *)cmd.meta.u.skb->data;
148 if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
149 IWL_ERROR("Bad return from REPLY_RX_ON_ASSOC command\n");
150 rc = -EIO;
151 }
152
153 spectrum_resp_status = le16_to_cpu(res->u.spectrum.status);
154 switch (spectrum_resp_status) {
155 case 0: /* Command will be handled */
156 if (res->u.spectrum.id != 0xff) {
157 IWL_DEBUG_INFO
158 ("Replaced existing measurement: %d\n",
159 res->u.spectrum.id);
160 priv->measurement_status &= ~MEASUREMENT_READY;
161 }
162 priv->measurement_status |= MEASUREMENT_ACTIVE;
163 rc = 0;
164 break;
165
166 case 1: /* Command will not be handled */
167 rc = -EAGAIN;
168 break;
169 }
170
171 dev_kfree_skb_any(cmd.meta.u.skb);
172
173 return rc;
174}
175#endif
176
177static void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv,
178 struct iwl_rx_mem_buffer *rxb)
179{
180 struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
181 struct iwl4965_spectrum_notification *report = &(pkt->u.spectrum_notif);
182
183 if (!report->state) {
184 IWL_DEBUG(IWL_DL_11H,
185 "Spectrum Measure Notification: Start\n");
186 return;
187 }
188
189 memcpy(&priv->measure_report, report, sizeof(*report));
190 priv->measurement_status |= MEASUREMENT_READY;
191}
192
193void iwl_setup_spectrum_handlers(struct iwl_priv *priv)
194{
195 priv->rx_handlers[SPECTRUM_MEASURE_NOTIFICATION] =
196 iwl_rx_spectrum_measure_notif;
197}
198EXPORT_SYMBOL(iwl_setup_spectrum_handlers);
diff --git a/drivers/net/wireless/iwlwifi/iwl-spectrum.h b/drivers/net/wireless/iwlwifi/iwl-spectrum.h
index a40a2174df98..fa990a102515 100644
--- a/drivers/net/wireless/iwlwifi/iwl-spectrum.h
+++ b/drivers/net/wireless/iwlwifi/iwl-spectrum.h
@@ -88,4 +88,5 @@ struct ieee80211_measurement_report {
88 struct ieee80211_basic_report basic[0]; 88 struct ieee80211_basic_report basic[0];
89 } u; 89 } u;
90} __attribute__ ((packed)); 90} __attribute__ ((packed));
91
91#endif 92#endif
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index 7d8b4e2d5094..166f0001e01d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -56,6 +56,26 @@ static const u16 default_tid_to_tx_fifo[] = {
56 IWL_TX_FIFO_AC3 56 IWL_TX_FIFO_AC3
57}; 57};
58 58
59static inline int iwl_alloc_dma_ptr(struct iwl_priv *priv,
60 struct iwl_dma_ptr *ptr, size_t size)
61{
62 ptr->addr = pci_alloc_consistent(priv->pci_dev, size, &ptr->dma);
63 if (!ptr->addr)
64 return -ENOMEM;
65 ptr->size = size;
66 return 0;
67}
68
69static inline void iwl_free_dma_ptr(struct iwl_priv *priv,
70 struct iwl_dma_ptr *ptr)
71{
72 if (unlikely(!ptr->addr))
73 return;
74
75 pci_free_consistent(priv->pci_dev, ptr->size, ptr->addr, ptr->dma);
76 memset(ptr, 0, sizeof(*ptr));
77}
78
59static inline dma_addr_t iwl_tfd_tb_get_addr(struct iwl_tfd *tfd, u8 idx) 79static inline dma_addr_t iwl_tfd_tb_get_addr(struct iwl_tfd *tfd, u8 idx)
60{ 80{
61 struct iwl_tfd_tb *tb = &tfd->tbs[idx]; 81 struct iwl_tfd_tb *tb = &tfd->tbs[idx];
@@ -517,8 +537,9 @@ void iwl_hw_txq_ctx_free(struct iwl_priv *priv)
517 else 537 else
518 iwl_tx_queue_free(priv, txq_id); 538 iwl_tx_queue_free(priv, txq_id);
519 539
520 /* Keep-warm buffer */ 540 iwl_free_dma_ptr(priv, &priv->kw);
521 iwl_kw_free(priv); 541
542 iwl_free_dma_ptr(priv, &priv->scd_bc_tbls);
522} 543}
523EXPORT_SYMBOL(iwl_hw_txq_ctx_free); 544EXPORT_SYMBOL(iwl_hw_txq_ctx_free);
524 545
@@ -535,13 +556,17 @@ int iwl_txq_ctx_reset(struct iwl_priv *priv)
535 int txq_id, slots_num; 556 int txq_id, slots_num;
536 unsigned long flags; 557 unsigned long flags;
537 558
538 iwl_kw_free(priv);
539
540 /* Free all tx/cmd queues and keep-warm buffer */ 559 /* Free all tx/cmd queues and keep-warm buffer */
541 iwl_hw_txq_ctx_free(priv); 560 iwl_hw_txq_ctx_free(priv);
542 561
562 ret = iwl_alloc_dma_ptr(priv, &priv->scd_bc_tbls,
563 priv->hw_params.scd_bc_tbls_size);
564 if (ret) {
565 IWL_ERROR("Scheduler BC Table allocation failed\n");
566 goto error_bc_tbls;
567 }
543 /* Alloc keep-warm buffer */ 568 /* Alloc keep-warm buffer */
544 ret = iwl_kw_alloc(priv); 569 ret = iwl_alloc_dma_ptr(priv, &priv->kw, IWL_KW_SIZE);
545 if (ret) { 570 if (ret) {
546 IWL_ERROR("Keep Warm allocation failed\n"); 571 IWL_ERROR("Keep Warm allocation failed\n");
547 goto error_kw; 572 goto error_kw;
@@ -556,16 +581,13 @@ int iwl_txq_ctx_reset(struct iwl_priv *priv)
556 /* Turn off all Tx DMA fifos */ 581 /* Turn off all Tx DMA fifos */
557 priv->cfg->ops->lib->txq_set_sched(priv, 0); 582 priv->cfg->ops->lib->txq_set_sched(priv, 0);
558 583
584 /* Tell NIC where to find the "keep warm" buffer */
585 iwl_write_direct32(priv, FH_KW_MEM_ADDR_REG, priv->kw.dma >> 4);
586
559 iwl_release_nic_access(priv); 587 iwl_release_nic_access(priv);
560 spin_unlock_irqrestore(&priv->lock, flags); 588 spin_unlock_irqrestore(&priv->lock, flags);
561 589
562 590
563 /* Tell nic where to find the keep-warm buffer */
564 ret = iwl_kw_init(priv);
565 if (ret) {
566 IWL_ERROR("kw_init failed\n");
567 goto error_reset;
568 }
569 591
570 /* Alloc and init all Tx queues, including the command queue (#4) */ 592 /* Alloc and init all Tx queues, including the command queue (#4) */
571 for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) { 593 for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) {
@@ -584,8 +606,10 @@ int iwl_txq_ctx_reset(struct iwl_priv *priv)
584 error: 606 error:
585 iwl_hw_txq_ctx_free(priv); 607 iwl_hw_txq_ctx_free(priv);
586 error_reset: 608 error_reset:
587 iwl_kw_free(priv); 609 iwl_free_dma_ptr(priv, &priv->kw);
588 error_kw: 610 error_kw:
611 iwl_free_dma_ptr(priv, &priv->scd_bc_tbls);
612 error_bc_tbls:
589 return ret; 613 return ret;
590} 614}
591 615
@@ -1236,8 +1260,13 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
1236 * command queue then there a command routing bug has been introduced 1260 * command queue then there a command routing bug has been introduced
1237 * in the queue management code. */ 1261 * in the queue management code. */
1238 if (WARN(txq_id != IWL_CMD_QUEUE_NUM, 1262 if (WARN(txq_id != IWL_CMD_QUEUE_NUM,
1239 "wrong command queue %d, command id 0x%X\n", txq_id, pkt->hdr.cmd)) 1263 "wrong command queue %d, sequence 0x%X readp=%d writep=%d\n",
1264 txq_id, sequence,
1265 priv->txq[IWL_CMD_QUEUE_NUM].q.read_ptr,
1266 priv->txq[IWL_CMD_QUEUE_NUM].q.write_ptr)) {
1267 iwl_print_hex_dump(priv, IWL_DL_INFO , rxb, 32);
1240 return; 1268 return;
1269 }
1241 1270
1242 cmd_index = get_cmd_index(&priv->txq[IWL_CMD_QUEUE_NUM].q, index, huge); 1271 cmd_index = get_cmd_index(&priv->txq[IWL_CMD_QUEUE_NUM].q, index, huge);
1243 cmd = priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_index]; 1272 cmd = priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_index];
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index a3ec4d0467a2..3344841b7662 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -1418,9 +1418,16 @@ unsigned int iwl3945_fill_beacon_frame(struct iwl3945_priv *priv,
1418 return priv->ibss_beacon->len; 1418 return priv->ibss_beacon->len;
1419} 1419}
1420 1420
1421static u8 iwl3945_rate_get_lowest_plcp(int rate_mask) 1421static u8 iwl3945_rate_get_lowest_plcp(struct iwl3945_priv *priv)
1422{ 1422{
1423 u8 i; 1423 u8 i;
1424 int rate_mask;
1425
1426 /* Set rate mask*/
1427 if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK)
1428 rate_mask = priv->active_rate_basic & 0xF;
1429 else
1430 rate_mask = priv->active_rate_basic & 0xFF0;
1424 1431
1425 for (i = IWL_RATE_1M_INDEX; i != IWL_RATE_INVALID; 1432 for (i = IWL_RATE_1M_INDEX; i != IWL_RATE_INVALID;
1426 i = iwl3945_rates[i].next_ieee) { 1433 i = iwl3945_rates[i].next_ieee) {
@@ -1428,7 +1435,11 @@ static u8 iwl3945_rate_get_lowest_plcp(int rate_mask)
1428 return iwl3945_rates[i].plcp; 1435 return iwl3945_rates[i].plcp;
1429 } 1436 }
1430 1437
1431 return IWL_RATE_INVALID; 1438 /* No valid rate was found. Assign the lowest one */
1439 if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK)
1440 return IWL_RATE_1M_PLCP;
1441 else
1442 return IWL_RATE_6M_PLCP;
1432} 1443}
1433 1444
1434static int iwl3945_send_beacon_cmd(struct iwl3945_priv *priv) 1445static int iwl3945_send_beacon_cmd(struct iwl3945_priv *priv)
@@ -1446,16 +1457,7 @@ static int iwl3945_send_beacon_cmd(struct iwl3945_priv *priv)
1446 return -ENOMEM; 1457 return -ENOMEM;
1447 } 1458 }
1448 1459
1449 if (!(priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK)) { 1460 rate = iwl3945_rate_get_lowest_plcp(priv);
1450 rate = iwl3945_rate_get_lowest_plcp(priv->active_rate_basic &
1451 0xFF0);
1452 if (rate == IWL_INVALID_RATE)
1453 rate = IWL_RATE_6M_PLCP;
1454 } else {
1455 rate = iwl3945_rate_get_lowest_plcp(priv->active_rate_basic & 0xF);
1456 if (rate == IWL_INVALID_RATE)
1457 rate = IWL_RATE_1M_PLCP;
1458 }
1459 1461
1460 frame_size = iwl3945_hw_get_beacon_cmd(priv, frame, rate); 1462 frame_size = iwl3945_hw_get_beacon_cmd(priv, frame, rate);
1461 1463
@@ -4741,7 +4743,7 @@ static void iwl3945_free_channel_map(struct iwl3945_priv *priv)
4741#define IWL_PASSIVE_DWELL_BASE (100) 4743#define IWL_PASSIVE_DWELL_BASE (100)
4742#define IWL_CHANNEL_TUNE_TIME 5 4744#define IWL_CHANNEL_TUNE_TIME 5
4743 4745
4744#define IWL_SCAN_PROBE_MASK(n) cpu_to_le32((BIT(n) | (BIT(n) - BIT(1)))) 4746#define IWL_SCAN_PROBE_MASK(n) (BIT(n) | (BIT(n) - BIT(1)))
4745 4747
4746static inline u16 iwl3945_get_active_dwell_time(struct iwl3945_priv *priv, 4748static inline u16 iwl3945_get_active_dwell_time(struct iwl3945_priv *priv,
4747 enum ieee80211_band band, 4749 enum ieee80211_band band,
@@ -5601,6 +5603,10 @@ static void iwl3945_init_alive_start(struct iwl3945_priv *priv)
5601} 5603}
5602 5604
5603 5605
5606/* temporary */
5607static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw,
5608 struct sk_buff *skb);
5609
5604/** 5610/**
5605 * iwl3945_alive_start - called after REPLY_ALIVE notification received 5611 * iwl3945_alive_start - called after REPLY_ALIVE notification received
5606 * from protocol/runtime uCode (initialization uCode's 5612 * from protocol/runtime uCode (initialization uCode's
@@ -5704,6 +5710,14 @@ static void iwl3945_alive_start(struct iwl3945_priv *priv)
5704 if (priv->error_recovering) 5710 if (priv->error_recovering)
5705 iwl3945_error_recovery(priv); 5711 iwl3945_error_recovery(priv);
5706 5712
5713 /* reassociate for ADHOC mode */
5714 if (priv->vif && (priv->iw_mode == NL80211_IFTYPE_ADHOC)) {
5715 struct sk_buff *beacon = ieee80211_beacon_get(priv->hw,
5716 priv->vif);
5717 if (beacon)
5718 iwl3945_mac_beacon_update(priv->hw, beacon);
5719 }
5720
5707 return; 5721 return;
5708 5722
5709 restart: 5723 restart:
@@ -6710,9 +6724,6 @@ static void iwl3945_config_ap(struct iwl3945_priv *priv)
6710 * clear sta table, add BCAST sta... */ 6724 * clear sta table, add BCAST sta... */
6711} 6725}
6712 6726
6713/* temporary */
6714static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb);
6715
6716static int iwl3945_mac_config_interface(struct ieee80211_hw *hw, 6727static int iwl3945_mac_config_interface(struct ieee80211_hw *hw,
6717 struct ieee80211_vif *vif, 6728 struct ieee80211_vif *vif,
6718 struct ieee80211_if_conf *conf) 6729 struct ieee80211_if_conf *conf)
@@ -6734,7 +6745,9 @@ static int iwl3945_mac_config_interface(struct ieee80211_hw *hw,
6734 struct sk_buff *beacon = ieee80211_beacon_get(hw, vif); 6745 struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
6735 if (!beacon) 6746 if (!beacon)
6736 return -ENOMEM; 6747 return -ENOMEM;
6748 mutex_lock(&priv->mutex);
6737 rc = iwl3945_mac_beacon_update(hw, beacon); 6749 rc = iwl3945_mac_beacon_update(hw, beacon);
6750 mutex_unlock(&priv->mutex);
6738 if (rc) 6751 if (rc)
6739 return rc; 6752 return rc;
6740 } 6753 }
@@ -7188,18 +7201,15 @@ static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *sk
7188 struct iwl3945_priv *priv = hw->priv; 7201 struct iwl3945_priv *priv = hw->priv;
7189 unsigned long flags; 7202 unsigned long flags;
7190 7203
7191 mutex_lock(&priv->mutex);
7192 IWL_DEBUG_MAC80211("enter\n"); 7204 IWL_DEBUG_MAC80211("enter\n");
7193 7205
7194 if (!iwl3945_is_ready_rf(priv)) { 7206 if (!iwl3945_is_ready_rf(priv)) {
7195 IWL_DEBUG_MAC80211("leave - RF not ready\n"); 7207 IWL_DEBUG_MAC80211("leave - RF not ready\n");
7196 mutex_unlock(&priv->mutex);
7197 return -EIO; 7208 return -EIO;
7198 } 7209 }
7199 7210
7200 if (priv->iw_mode != NL80211_IFTYPE_ADHOC) { 7211 if (priv->iw_mode != NL80211_IFTYPE_ADHOC) {
7201 IWL_DEBUG_MAC80211("leave - not IBSS\n"); 7212 IWL_DEBUG_MAC80211("leave - not IBSS\n");
7202 mutex_unlock(&priv->mutex);
7203 return -EIO; 7213 return -EIO;
7204 } 7214 }
7205 7215
@@ -7219,7 +7229,6 @@ static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *sk
7219 7229
7220 iwl3945_post_associate(priv); 7230 iwl3945_post_associate(priv);
7221 7231
7222 mutex_unlock(&priv->mutex);
7223 7232
7224 return 0; 7233 return 0;
7225} 7234}
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c
index 957fd5a10a8d..639dd02d3d31 100644
--- a/drivers/net/wireless/libertas/cmd.c
+++ b/drivers/net/wireless/libertas/cmd.c
@@ -159,7 +159,8 @@ out:
159 return ret; 159 return ret;
160} 160}
161 161
162int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria) 162int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria,
163 struct wol_config *p_wol_config)
163{ 164{
164 struct cmd_ds_host_sleep cmd_config; 165 struct cmd_ds_host_sleep cmd_config;
165 int ret; 166 int ret;
@@ -169,10 +170,21 @@ int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria)
169 cmd_config.gpio = priv->wol_gpio; 170 cmd_config.gpio = priv->wol_gpio;
170 cmd_config.gap = priv->wol_gap; 171 cmd_config.gap = priv->wol_gap;
171 172
173 if (p_wol_config != NULL)
174 memcpy((uint8_t *)&cmd_config.wol_conf, (uint8_t *)p_wol_config,
175 sizeof(struct wol_config));
176 else
177 cmd_config.wol_conf.action = CMD_ACT_ACTION_NONE;
178
172 ret = lbs_cmd_with_response(priv, CMD_802_11_HOST_SLEEP_CFG, &cmd_config); 179 ret = lbs_cmd_with_response(priv, CMD_802_11_HOST_SLEEP_CFG, &cmd_config);
173 if (!ret) { 180 if (!ret) {
174 lbs_deb_cmd("Set WOL criteria to %x\n", criteria); 181 if (criteria) {
175 priv->wol_criteria = criteria; 182 lbs_deb_cmd("Set WOL criteria to %x\n", criteria);
183 priv->wol_criteria = criteria;
184 } else
185 memcpy((uint8_t *) p_wol_config,
186 (uint8_t *)&cmd_config.wol_conf,
187 sizeof(struct wol_config));
176 } else { 188 } else {
177 lbs_pr_info("HOST_SLEEP_CFG failed %d\n", ret); 189 lbs_pr_info("HOST_SLEEP_CFG failed %d\n", ret);
178 } 190 }
diff --git a/drivers/net/wireless/libertas/cmd.h b/drivers/net/wireless/libertas/cmd.h
index 36be4c9703e0..392e578ca095 100644
--- a/drivers/net/wireless/libertas/cmd.h
+++ b/drivers/net/wireless/libertas/cmd.h
@@ -56,7 +56,8 @@ int lbs_mesh_config_send(struct lbs_private *priv,
56 uint16_t action, uint16_t type); 56 uint16_t action, uint16_t type);
57int lbs_mesh_config(struct lbs_private *priv, uint16_t enable, uint16_t chan); 57int lbs_mesh_config(struct lbs_private *priv, uint16_t enable, uint16_t chan);
58 58
59int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria); 59int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria,
60 struct wol_config *p_wol_config);
60int lbs_suspend(struct lbs_private *priv); 61int lbs_suspend(struct lbs_private *priv);
61void lbs_resume(struct lbs_private *priv); 62void lbs_resume(struct lbs_private *priv);
62 63
diff --git a/drivers/net/wireless/libertas/defs.h b/drivers/net/wireless/libertas/defs.h
index 2d4666f26808..c364e4c01d1b 100644
--- a/drivers/net/wireless/libertas/defs.h
+++ b/drivers/net/wireless/libertas/defs.h
@@ -149,6 +149,18 @@ static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, in
149#define EHS_WAKE_ON_MAC_EVENT 0x0004 149#define EHS_WAKE_ON_MAC_EVENT 0x0004
150#define EHS_WAKE_ON_MULTICAST_DATA 0x0008 150#define EHS_WAKE_ON_MULTICAST_DATA 0x0008
151#define EHS_REMOVE_WAKEUP 0xFFFFFFFF 151#define EHS_REMOVE_WAKEUP 0xFFFFFFFF
152/* Wake rules for Host_Sleep_CFG command */
153#define WOL_RULE_NET_TYPE_INFRA_OR_IBSS 0x00
154#define WOL_RULE_NET_TYPE_MESH 0x10
155#define WOL_RULE_ADDR_TYPE_BCAST 0x01
156#define WOL_RULE_ADDR_TYPE_MCAST 0x08
157#define WOL_RULE_ADDR_TYPE_UCAST 0x02
158#define WOL_RULE_OP_AND 0x01
159#define WOL_RULE_OP_OR 0x02
160#define WOL_RULE_OP_INVALID 0xFF
161#define WOL_RESULT_VALID_CMD 0
162#define WOL_RESULT_NOSPC_ERR 1
163#define WOL_RESULT_EEXIST_ERR 2
152 164
153/** Misc constants */ 165/** Misc constants */
154/* This section defines 802.11 specific contants */ 166/* This section defines 802.11 specific contants */
diff --git a/drivers/net/wireless/libertas/ethtool.c b/drivers/net/wireless/libertas/ethtool.c
index 156f471217bb..61d2f50470c8 100644
--- a/drivers/net/wireless/libertas/ethtool.c
+++ b/drivers/net/wireless/libertas/ethtool.c
@@ -180,7 +180,7 @@ static int lbs_ethtool_set_wol(struct net_device *dev,
180 if (wol->wolopts & WAKE_BCAST) criteria |= EHS_WAKE_ON_BROADCAST_DATA; 180 if (wol->wolopts & WAKE_BCAST) criteria |= EHS_WAKE_ON_BROADCAST_DATA;
181 if (wol->wolopts & WAKE_PHY) criteria |= EHS_WAKE_ON_MAC_EVENT; 181 if (wol->wolopts & WAKE_PHY) criteria |= EHS_WAKE_ON_MAC_EVENT;
182 182
183 return lbs_host_sleep_cfg(priv, criteria); 183 return lbs_host_sleep_cfg(priv, criteria, (struct wol_config *)NULL);
184} 184}
185 185
186struct ethtool_ops lbs_ethtool_ops = { 186struct ethtool_ops lbs_ethtool_ops = {
diff --git a/drivers/net/wireless/libertas/host.h b/drivers/net/wireless/libertas/host.h
index 5004d7679c02..a17b778c172c 100644
--- a/drivers/net/wireless/libertas/host.h
+++ b/drivers/net/wireless/libertas/host.h
@@ -220,6 +220,14 @@ enum cmd_fwt_access_opts {
220 CMD_ACT_FWT_ACCESS_TIME, 220 CMD_ACT_FWT_ACCESS_TIME,
221}; 221};
222 222
223/* Define action or option for CMD_802_11_HOST_SLEEP_CFG */
224enum cmd_wol_cfg_opts {
225 CMD_ACT_ACTION_NONE = 0,
226 CMD_ACT_SET_WOL_RULE,
227 CMD_ACT_GET_WOL_RULE,
228 CMD_ACT_RESET_WOL_RULE,
229};
230
223/* Define action or option for CMD_MESH_ACCESS */ 231/* Define action or option for CMD_MESH_ACCESS */
224enum cmd_mesh_access_opts { 232enum cmd_mesh_access_opts {
225 CMD_ACT_MESH_GET_TTL = 1, 233 CMD_ACT_MESH_GET_TTL = 1,
diff --git a/drivers/net/wireless/libertas/hostcmd.h b/drivers/net/wireless/libertas/hostcmd.h
index d9f9a12a739e..e173b1b46c23 100644
--- a/drivers/net/wireless/libertas/hostcmd.h
+++ b/drivers/net/wireless/libertas/hostcmd.h
@@ -580,13 +580,37 @@ struct MrvlIEtype_keyParamSet {
580 u8 key[32]; 580 u8 key[32];
581}; 581};
582 582
583#define MAX_WOL_RULES 16
584
585struct host_wol_rule {
586 uint8_t rule_no;
587 uint8_t rule_ops;
588 __le16 sig_offset;
589 __le16 sig_length;
590 __le16 reserve;
591 __be32 sig_mask;
592 __be32 signature;
593};
594
595struct wol_config {
596 uint8_t action;
597 uint8_t pattern;
598 uint8_t no_rules_in_cmd;
599 uint8_t result;
600 struct host_wol_rule rule[MAX_WOL_RULES];
601};
602
603
583struct cmd_ds_host_sleep { 604struct cmd_ds_host_sleep {
584 struct cmd_header hdr; 605 struct cmd_header hdr;
585 __le32 criteria; 606 __le32 criteria;
586 uint8_t gpio; 607 uint8_t gpio;
587 uint8_t gap; 608 uint16_t gap;
609 struct wol_config wol_conf;
588} __attribute__ ((packed)); 610} __attribute__ ((packed));
589 611
612
613
590struct cmd_ds_802_11_key_material { 614struct cmd_ds_802_11_key_material {
591 struct cmd_header hdr; 615 struct cmd_header hdr;
592 616
diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c
index cafbccb74143..fcd3fe6abe8c 100644
--- a/drivers/net/wireless/libertas/if_usb.c
+++ b/drivers/net/wireless/libertas/if_usb.c
@@ -178,7 +178,8 @@ static void if_usb_setup_firmware(struct lbs_private *priv)
178 178
179 priv->wol_gpio = 2; /* Wake via GPIO2... */ 179 priv->wol_gpio = 2; /* Wake via GPIO2... */
180 priv->wol_gap = 20; /* ... after 20ms */ 180 priv->wol_gap = 20; /* ... after 20ms */
181 lbs_host_sleep_cfg(priv, EHS_WAKE_ON_UNICAST_DATA); 181 lbs_host_sleep_cfg(priv, EHS_WAKE_ON_UNICAST_DATA,
182 (struct wol_config *) NULL);
182 183
183 wake_method.hdr.size = cpu_to_le16(sizeof(wake_method)); 184 wake_method.hdr.size = cpu_to_le16(sizeof(wake_method));
184 wake_method.action = cpu_to_le16(CMD_ACT_GET); 185 wake_method.action = cpu_to_le16(CMD_ACT_GET);
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index b9230da925ee..d8b5cf389405 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -368,7 +368,8 @@ static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac,
368 368
369 hwsim_check_magic(vif); 369 hwsim_check_magic(vif);
370 370
371 if (vif->type != NL80211_IFTYPE_AP) 371 if (vif->type != NL80211_IFTYPE_AP &&
372 vif->type != NL80211_IFTYPE_MESH_POINT)
372 return; 373 return;
373 374
374 skb = ieee80211_beacon_get(hw, vif); 375 skb = ieee80211_beacon_get(hw, vif);
@@ -774,7 +775,8 @@ static int __init init_mac80211_hwsim(void)
774 hw->queues = 4; 775 hw->queues = 4;
775 hw->wiphy->interface_modes = 776 hw->wiphy->interface_modes =
776 BIT(NL80211_IFTYPE_STATION) | 777 BIT(NL80211_IFTYPE_STATION) |
777 BIT(NL80211_IFTYPE_AP); 778 BIT(NL80211_IFTYPE_AP) |
779 BIT(NL80211_IFTYPE_MESH_POINT);
778 hw->ampdu_queues = 1; 780 hw->ampdu_queues = 1;
779 781
780 /* ask mac80211 to reserve space for magic */ 782 /* ask mac80211 to reserve space for magic */
diff --git a/drivers/net/wireless/orinoco/orinoco.c b/drivers/net/wireless/orinoco/orinoco.c
index 072be44b37de..fd9263980d69 100644
--- a/drivers/net/wireless/orinoco/orinoco.c
+++ b/drivers/net/wireless/orinoco/orinoco.c
@@ -5444,7 +5444,7 @@ static inline char *orinoco_translate_scan(struct net_device *dev,
5444 char *current_ev, 5444 char *current_ev,
5445 char *end_buf, 5445 char *end_buf,
5446 union hermes_scan_info *bss, 5446 union hermes_scan_info *bss,
5447 unsigned int last_scanned) 5447 unsigned long last_scanned)
5448{ 5448{
5449 struct orinoco_private *priv = netdev_priv(dev); 5449 struct orinoco_private *priv = netdev_priv(dev);
5450 u16 capabilities; 5450 u16 capabilities;
@@ -5591,7 +5591,7 @@ static inline char *orinoco_translate_ext_scan(struct net_device *dev,
5591 char *current_ev, 5591 char *current_ev,
5592 char *end_buf, 5592 char *end_buf,
5593 struct agere_ext_scan_info *bss, 5593 struct agere_ext_scan_info *bss,
5594 unsigned int last_scanned) 5594 unsigned long last_scanned)
5595{ 5595{
5596 u16 capabilities; 5596 u16 capabilities;
5597 u16 channel; 5597 u16 channel;
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index 42bd38ac7a1d..78fca1bcc544 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -69,14 +69,14 @@ static void rt2400pci_bbp_write(struct rt2x00_dev *rt2x00dev,
69{ 69{
70 u32 reg; 70 u32 reg;
71 71
72 mutex_lock(&rt2x00dev->csr_mutex);
73
72 /* 74 /*
73 * Wait until the BBP becomes ready. 75 * Wait until the BBP becomes ready.
74 */ 76 */
75 reg = rt2400pci_bbp_check(rt2x00dev); 77 reg = rt2400pci_bbp_check(rt2x00dev);
76 if (rt2x00_get_field32(reg, BBPCSR_BUSY)) { 78 if (rt2x00_get_field32(reg, BBPCSR_BUSY))
77 ERROR(rt2x00dev, "BBPCSR register busy. Write failed.\n"); 79 goto exit_fail;
78 return;
79 }
80 80
81 /* 81 /*
82 * Write the data into the BBP. 82 * Write the data into the BBP.
@@ -88,6 +88,15 @@ static void rt2400pci_bbp_write(struct rt2x00_dev *rt2x00dev,
88 rt2x00_set_field32(&reg, BBPCSR_WRITE_CONTROL, 1); 88 rt2x00_set_field32(&reg, BBPCSR_WRITE_CONTROL, 1);
89 89
90 rt2x00pci_register_write(rt2x00dev, BBPCSR, reg); 90 rt2x00pci_register_write(rt2x00dev, BBPCSR, reg);
91
92 mutex_unlock(&rt2x00dev->csr_mutex);
93
94 return;
95
96exit_fail:
97 mutex_unlock(&rt2x00dev->csr_mutex);
98
99 ERROR(rt2x00dev, "BBPCSR register busy. Write failed.\n");
91} 100}
92 101
93static void rt2400pci_bbp_read(struct rt2x00_dev *rt2x00dev, 102static void rt2400pci_bbp_read(struct rt2x00_dev *rt2x00dev,
@@ -95,14 +104,14 @@ static void rt2400pci_bbp_read(struct rt2x00_dev *rt2x00dev,
95{ 104{
96 u32 reg; 105 u32 reg;
97 106
107 mutex_lock(&rt2x00dev->csr_mutex);
108
98 /* 109 /*
99 * Wait until the BBP becomes ready. 110 * Wait until the BBP becomes ready.
100 */ 111 */
101 reg = rt2400pci_bbp_check(rt2x00dev); 112 reg = rt2400pci_bbp_check(rt2x00dev);
102 if (rt2x00_get_field32(reg, BBPCSR_BUSY)) { 113 if (rt2x00_get_field32(reg, BBPCSR_BUSY))
103 ERROR(rt2x00dev, "BBPCSR register busy. Read failed.\n"); 114 goto exit_fail;
104 return;
105 }
106 115
107 /* 116 /*
108 * Write the request into the BBP. 117 * Write the request into the BBP.
@@ -118,13 +127,20 @@ static void rt2400pci_bbp_read(struct rt2x00_dev *rt2x00dev,
118 * Wait until the BBP becomes ready. 127 * Wait until the BBP becomes ready.
119 */ 128 */
120 reg = rt2400pci_bbp_check(rt2x00dev); 129 reg = rt2400pci_bbp_check(rt2x00dev);
121 if (rt2x00_get_field32(reg, BBPCSR_BUSY)) { 130 if (rt2x00_get_field32(reg, BBPCSR_BUSY))
122 ERROR(rt2x00dev, "BBPCSR register busy. Read failed.\n"); 131 goto exit_fail;
123 *value = 0xff;
124 return;
125 }
126 132
127 *value = rt2x00_get_field32(reg, BBPCSR_VALUE); 133 *value = rt2x00_get_field32(reg, BBPCSR_VALUE);
134
135 mutex_unlock(&rt2x00dev->csr_mutex);
136
137 return;
138
139exit_fail:
140 mutex_unlock(&rt2x00dev->csr_mutex);
141
142 ERROR(rt2x00dev, "BBPCSR register busy. Read failed.\n");
143 *value = 0xff;
128} 144}
129 145
130static void rt2400pci_rf_write(struct rt2x00_dev *rt2x00dev, 146static void rt2400pci_rf_write(struct rt2x00_dev *rt2x00dev,
@@ -136,6 +152,8 @@ static void rt2400pci_rf_write(struct rt2x00_dev *rt2x00dev,
136 if (!word) 152 if (!word)
137 return; 153 return;
138 154
155 mutex_lock(&rt2x00dev->csr_mutex);
156
139 for (i = 0; i < REGISTER_BUSY_COUNT; i++) { 157 for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
140 rt2x00pci_register_read(rt2x00dev, RFCSR, &reg); 158 rt2x00pci_register_read(rt2x00dev, RFCSR, &reg);
141 if (!rt2x00_get_field32(reg, RFCSR_BUSY)) 159 if (!rt2x00_get_field32(reg, RFCSR_BUSY))
@@ -143,6 +161,7 @@ static void rt2400pci_rf_write(struct rt2x00_dev *rt2x00dev,
143 udelay(REGISTER_BUSY_DELAY); 161 udelay(REGISTER_BUSY_DELAY);
144 } 162 }
145 163
164 mutex_unlock(&rt2x00dev->csr_mutex);
146 ERROR(rt2x00dev, "RFCSR register busy. Write failed.\n"); 165 ERROR(rt2x00dev, "RFCSR register busy. Write failed.\n");
147 return; 166 return;
148 167
@@ -155,6 +174,8 @@ rf_write:
155 174
156 rt2x00pci_register_write(rt2x00dev, RFCSR, reg); 175 rt2x00pci_register_write(rt2x00dev, RFCSR, reg);
157 rt2x00_rf_write(rt2x00dev, word, value); 176 rt2x00_rf_write(rt2x00dev, word, value);
177
178 mutex_unlock(&rt2x00dev->csr_mutex);
158} 179}
159 180
160static void rt2400pci_eepromregister_read(struct eeprom_93cx6 *eeprom) 181static void rt2400pci_eepromregister_read(struct eeprom_93cx6 *eeprom)
@@ -322,7 +343,7 @@ static void rt2400pci_config_intf(struct rt2x00_dev *rt2x00dev,
322 /* 343 /*
323 * Enable beacon config 344 * Enable beacon config
324 */ 345 */
325 bcn_preload = PREAMBLE + get_duration(IEEE80211_HEADER, 20); 346 bcn_preload = PREAMBLE + GET_DURATION(IEEE80211_HEADER, 20);
326 rt2x00pci_register_read(rt2x00dev, BCNCSR1, &reg); 347 rt2x00pci_register_read(rt2x00dev, BCNCSR1, &reg);
327 rt2x00_set_field32(&reg, BCNCSR1_PRELOAD, bcn_preload); 348 rt2x00_set_field32(&reg, BCNCSR1_PRELOAD, bcn_preload);
328 rt2x00pci_register_write(rt2x00dev, BCNCSR1, reg); 349 rt2x00pci_register_write(rt2x00dev, BCNCSR1, reg);
@@ -367,25 +388,25 @@ static void rt2400pci_config_erp(struct rt2x00_dev *rt2x00dev,
367 rt2x00pci_register_read(rt2x00dev, ARCSR2, &reg); 388 rt2x00pci_register_read(rt2x00dev, ARCSR2, &reg);
368 rt2x00_set_field32(&reg, ARCSR2_SIGNAL, 0x00); 389 rt2x00_set_field32(&reg, ARCSR2_SIGNAL, 0x00);
369 rt2x00_set_field32(&reg, ARCSR2_SERVICE, 0x04); 390 rt2x00_set_field32(&reg, ARCSR2_SERVICE, 0x04);
370 rt2x00_set_field32(&reg, ARCSR2_LENGTH, get_duration(ACK_SIZE, 10)); 391 rt2x00_set_field32(&reg, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 10));
371 rt2x00pci_register_write(rt2x00dev, ARCSR2, reg); 392 rt2x00pci_register_write(rt2x00dev, ARCSR2, reg);
372 393
373 rt2x00pci_register_read(rt2x00dev, ARCSR3, &reg); 394 rt2x00pci_register_read(rt2x00dev, ARCSR3, &reg);
374 rt2x00_set_field32(&reg, ARCSR3_SIGNAL, 0x01 | preamble_mask); 395 rt2x00_set_field32(&reg, ARCSR3_SIGNAL, 0x01 | preamble_mask);
375 rt2x00_set_field32(&reg, ARCSR3_SERVICE, 0x04); 396 rt2x00_set_field32(&reg, ARCSR3_SERVICE, 0x04);
376 rt2x00_set_field32(&reg, ARCSR2_LENGTH, get_duration(ACK_SIZE, 20)); 397 rt2x00_set_field32(&reg, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 20));
377 rt2x00pci_register_write(rt2x00dev, ARCSR3, reg); 398 rt2x00pci_register_write(rt2x00dev, ARCSR3, reg);
378 399
379 rt2x00pci_register_read(rt2x00dev, ARCSR4, &reg); 400 rt2x00pci_register_read(rt2x00dev, ARCSR4, &reg);
380 rt2x00_set_field32(&reg, ARCSR4_SIGNAL, 0x02 | preamble_mask); 401 rt2x00_set_field32(&reg, ARCSR4_SIGNAL, 0x02 | preamble_mask);
381 rt2x00_set_field32(&reg, ARCSR4_SERVICE, 0x04); 402 rt2x00_set_field32(&reg, ARCSR4_SERVICE, 0x04);
382 rt2x00_set_field32(&reg, ARCSR2_LENGTH, get_duration(ACK_SIZE, 55)); 403 rt2x00_set_field32(&reg, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 55));
383 rt2x00pci_register_write(rt2x00dev, ARCSR4, reg); 404 rt2x00pci_register_write(rt2x00dev, ARCSR4, reg);
384 405
385 rt2x00pci_register_read(rt2x00dev, ARCSR5, &reg); 406 rt2x00pci_register_read(rt2x00dev, ARCSR5, &reg);
386 rt2x00_set_field32(&reg, ARCSR5_SIGNAL, 0x03 | preamble_mask); 407 rt2x00_set_field32(&reg, ARCSR5_SIGNAL, 0x03 | preamble_mask);
387 rt2x00_set_field32(&reg, ARCSR5_SERVICE, 0x84); 408 rt2x00_set_field32(&reg, ARCSR5_SERVICE, 0x84);
388 rt2x00_set_field32(&reg, ARCSR2_LENGTH, get_duration(ACK_SIZE, 110)); 409 rt2x00_set_field32(&reg, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 110));
389 rt2x00pci_register_write(rt2x00dev, ARCSR5, reg); 410 rt2x00pci_register_write(rt2x00dev, ARCSR5, reg);
390 411
391 rt2x00pci_register_write(rt2x00dev, ARCSR1, erp->basic_rates); 412 rt2x00pci_register_write(rt2x00dev, ARCSR1, erp->basic_rates);
@@ -626,36 +647,47 @@ static void rt2400pci_link_tuner(struct rt2x00_dev *rt2x00dev)
626/* 647/*
627 * Initialization functions. 648 * Initialization functions.
628 */ 649 */
629static void rt2400pci_init_rxentry(struct rt2x00_dev *rt2x00dev, 650static bool rt2400pci_get_entry_state(struct queue_entry *entry)
630 struct queue_entry *entry)
631{ 651{
632 struct queue_entry_priv_pci *entry_priv = entry->priv_data; 652 struct queue_entry_priv_pci *entry_priv = entry->priv_data;
633 struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
634 u32 word; 653 u32 word;
635 654
636 rt2x00_desc_read(entry_priv->desc, 2, &word); 655 if (entry->queue->qid == QID_RX) {
637 rt2x00_set_field32(&word, RXD_W2_BUFFER_LENGTH, entry->skb->len); 656 rt2x00_desc_read(entry_priv->desc, 0, &word);
638 rt2x00_desc_write(entry_priv->desc, 2, word);
639 657
640 rt2x00_desc_read(entry_priv->desc, 1, &word); 658 return rt2x00_get_field32(word, RXD_W0_OWNER_NIC);
641 rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma); 659 } else {
642 rt2x00_desc_write(entry_priv->desc, 1, word); 660 rt2x00_desc_read(entry_priv->desc, 0, &word);
643 661
644 rt2x00_desc_read(entry_priv->desc, 0, &word); 662 return (rt2x00_get_field32(word, TXD_W0_OWNER_NIC) ||
645 rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1); 663 rt2x00_get_field32(word, TXD_W0_VALID));
646 rt2x00_desc_write(entry_priv->desc, 0, word); 664 }
647} 665}
648 666
649static void rt2400pci_init_txentry(struct rt2x00_dev *rt2x00dev, 667static void rt2400pci_clear_entry(struct queue_entry *entry)
650 struct queue_entry *entry)
651{ 668{
652 struct queue_entry_priv_pci *entry_priv = entry->priv_data; 669 struct queue_entry_priv_pci *entry_priv = entry->priv_data;
670 struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
653 u32 word; 671 u32 word;
654 672
655 rt2x00_desc_read(entry_priv->desc, 0, &word); 673 if (entry->queue->qid == QID_RX) {
656 rt2x00_set_field32(&word, TXD_W0_VALID, 0); 674 rt2x00_desc_read(entry_priv->desc, 2, &word);
657 rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0); 675 rt2x00_set_field32(&word, RXD_W2_BUFFER_LENGTH, entry->skb->len);
658 rt2x00_desc_write(entry_priv->desc, 0, word); 676 rt2x00_desc_write(entry_priv->desc, 2, word);
677
678 rt2x00_desc_read(entry_priv->desc, 1, &word);
679 rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma);
680 rt2x00_desc_write(entry_priv->desc, 1, word);
681
682 rt2x00_desc_read(entry_priv->desc, 0, &word);
683 rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1);
684 rt2x00_desc_write(entry_priv->desc, 0, word);
685 } else {
686 rt2x00_desc_read(entry_priv->desc, 0, &word);
687 rt2x00_set_field32(&word, TXD_W0_VALID, 0);
688 rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0);
689 rt2x00_desc_write(entry_priv->desc, 0, word);
690 }
659} 691}
660 692
661static int rt2400pci_init_queues(struct rt2x00_dev *rt2x00dev) 693static int rt2400pci_init_queues(struct rt2x00_dev *rt2x00dev)
@@ -1570,8 +1602,8 @@ static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = {
1570 .probe_hw = rt2400pci_probe_hw, 1602 .probe_hw = rt2400pci_probe_hw,
1571 .initialize = rt2x00pci_initialize, 1603 .initialize = rt2x00pci_initialize,
1572 .uninitialize = rt2x00pci_uninitialize, 1604 .uninitialize = rt2x00pci_uninitialize,
1573 .init_rxentry = rt2400pci_init_rxentry, 1605 .get_entry_state = rt2400pci_get_entry_state,
1574 .init_txentry = rt2400pci_init_txentry, 1606 .clear_entry = rt2400pci_clear_entry,
1575 .set_device_state = rt2400pci_set_device_state, 1607 .set_device_state = rt2400pci_set_device_state,
1576 .rfkill_poll = rt2400pci_rfkill_poll, 1608 .rfkill_poll = rt2400pci_rfkill_poll,
1577 .link_stats = rt2400pci_link_stats, 1609 .link_stats = rt2400pci_link_stats,
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index 928452f30c25..972b5a5c3864 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -69,14 +69,14 @@ static void rt2500pci_bbp_write(struct rt2x00_dev *rt2x00dev,
69{ 69{
70 u32 reg; 70 u32 reg;
71 71
72 mutex_lock(&rt2x00dev->csr_mutex);
73
72 /* 74 /*
73 * Wait until the BBP becomes ready. 75 * Wait until the BBP becomes ready.
74 */ 76 */
75 reg = rt2500pci_bbp_check(rt2x00dev); 77 reg = rt2500pci_bbp_check(rt2x00dev);
76 if (rt2x00_get_field32(reg, BBPCSR_BUSY)) { 78 if (rt2x00_get_field32(reg, BBPCSR_BUSY))
77 ERROR(rt2x00dev, "BBPCSR register busy. Write failed.\n"); 79 goto exit_fail;
78 return;
79 }
80 80
81 /* 81 /*
82 * Write the data into the BBP. 82 * Write the data into the BBP.
@@ -88,6 +88,15 @@ static void rt2500pci_bbp_write(struct rt2x00_dev *rt2x00dev,
88 rt2x00_set_field32(&reg, BBPCSR_WRITE_CONTROL, 1); 88 rt2x00_set_field32(&reg, BBPCSR_WRITE_CONTROL, 1);
89 89
90 rt2x00pci_register_write(rt2x00dev, BBPCSR, reg); 90 rt2x00pci_register_write(rt2x00dev, BBPCSR, reg);
91
92 mutex_unlock(&rt2x00dev->csr_mutex);
93
94 return;
95
96exit_fail:
97 mutex_unlock(&rt2x00dev->csr_mutex);
98
99 ERROR(rt2x00dev, "BBPCSR register busy. Write failed.\n");
91} 100}
92 101
93static void rt2500pci_bbp_read(struct rt2x00_dev *rt2x00dev, 102static void rt2500pci_bbp_read(struct rt2x00_dev *rt2x00dev,
@@ -95,14 +104,14 @@ static void rt2500pci_bbp_read(struct rt2x00_dev *rt2x00dev,
95{ 104{
96 u32 reg; 105 u32 reg;
97 106
107 mutex_lock(&rt2x00dev->csr_mutex);
108
98 /* 109 /*
99 * Wait until the BBP becomes ready. 110 * Wait until the BBP becomes ready.
100 */ 111 */
101 reg = rt2500pci_bbp_check(rt2x00dev); 112 reg = rt2500pci_bbp_check(rt2x00dev);
102 if (rt2x00_get_field32(reg, BBPCSR_BUSY)) { 113 if (rt2x00_get_field32(reg, BBPCSR_BUSY))
103 ERROR(rt2x00dev, "BBPCSR register busy. Read failed.\n"); 114 goto exit_fail;
104 return;
105 }
106 115
107 /* 116 /*
108 * Write the request into the BBP. 117 * Write the request into the BBP.
@@ -118,13 +127,20 @@ static void rt2500pci_bbp_read(struct rt2x00_dev *rt2x00dev,
118 * Wait until the BBP becomes ready. 127 * Wait until the BBP becomes ready.
119 */ 128 */
120 reg = rt2500pci_bbp_check(rt2x00dev); 129 reg = rt2500pci_bbp_check(rt2x00dev);
121 if (rt2x00_get_field32(reg, BBPCSR_BUSY)) { 130 if (rt2x00_get_field32(reg, BBPCSR_BUSY))
122 ERROR(rt2x00dev, "BBPCSR register busy. Read failed.\n"); 131 goto exit_fail;
123 *value = 0xff;
124 return;
125 }
126 132
127 *value = rt2x00_get_field32(reg, BBPCSR_VALUE); 133 *value = rt2x00_get_field32(reg, BBPCSR_VALUE);
134
135 mutex_unlock(&rt2x00dev->csr_mutex);
136
137 return;
138
139exit_fail:
140 mutex_unlock(&rt2x00dev->csr_mutex);
141
142 ERROR(rt2x00dev, "BBPCSR register busy. Read failed.\n");
143 *value = 0xff;
128} 144}
129 145
130static void rt2500pci_rf_write(struct rt2x00_dev *rt2x00dev, 146static void rt2500pci_rf_write(struct rt2x00_dev *rt2x00dev,
@@ -136,6 +152,8 @@ static void rt2500pci_rf_write(struct rt2x00_dev *rt2x00dev,
136 if (!word) 152 if (!word)
137 return; 153 return;
138 154
155 mutex_lock(&rt2x00dev->csr_mutex);
156
139 for (i = 0; i < REGISTER_BUSY_COUNT; i++) { 157 for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
140 rt2x00pci_register_read(rt2x00dev, RFCSR, &reg); 158 rt2x00pci_register_read(rt2x00dev, RFCSR, &reg);
141 if (!rt2x00_get_field32(reg, RFCSR_BUSY)) 159 if (!rt2x00_get_field32(reg, RFCSR_BUSY))
@@ -143,6 +161,7 @@ static void rt2500pci_rf_write(struct rt2x00_dev *rt2x00dev,
143 udelay(REGISTER_BUSY_DELAY); 161 udelay(REGISTER_BUSY_DELAY);
144 } 162 }
145 163
164 mutex_unlock(&rt2x00dev->csr_mutex);
146 ERROR(rt2x00dev, "RFCSR register busy. Write failed.\n"); 165 ERROR(rt2x00dev, "RFCSR register busy. Write failed.\n");
147 return; 166 return;
148 167
@@ -155,6 +174,8 @@ rf_write:
155 174
156 rt2x00pci_register_write(rt2x00dev, RFCSR, reg); 175 rt2x00pci_register_write(rt2x00dev, RFCSR, reg);
157 rt2x00_rf_write(rt2x00dev, word, value); 176 rt2x00_rf_write(rt2x00dev, word, value);
177
178 mutex_unlock(&rt2x00dev->csr_mutex);
158} 179}
159 180
160static void rt2500pci_eepromregister_read(struct eeprom_93cx6 *eeprom) 181static void rt2500pci_eepromregister_read(struct eeprom_93cx6 *eeprom)
@@ -327,7 +348,7 @@ static void rt2500pci_config_intf(struct rt2x00_dev *rt2x00dev,
327 /* 348 /*
328 * Enable beacon config 349 * Enable beacon config
329 */ 350 */
330 bcn_preload = PREAMBLE + get_duration(IEEE80211_HEADER, 20); 351 bcn_preload = PREAMBLE + GET_DURATION(IEEE80211_HEADER, 20);
331 rt2x00pci_register_read(rt2x00dev, BCNCSR1, &reg); 352 rt2x00pci_register_read(rt2x00dev, BCNCSR1, &reg);
332 rt2x00_set_field32(&reg, BCNCSR1_PRELOAD, bcn_preload); 353 rt2x00_set_field32(&reg, BCNCSR1_PRELOAD, bcn_preload);
333 rt2x00_set_field32(&reg, BCNCSR1_BEACON_CWMIN, queue->cw_min); 354 rt2x00_set_field32(&reg, BCNCSR1_BEACON_CWMIN, queue->cw_min);
@@ -373,25 +394,25 @@ static void rt2500pci_config_erp(struct rt2x00_dev *rt2x00dev,
373 rt2x00pci_register_read(rt2x00dev, ARCSR2, &reg); 394 rt2x00pci_register_read(rt2x00dev, ARCSR2, &reg);
374 rt2x00_set_field32(&reg, ARCSR2_SIGNAL, 0x00); 395 rt2x00_set_field32(&reg, ARCSR2_SIGNAL, 0x00);
375 rt2x00_set_field32(&reg, ARCSR2_SERVICE, 0x04); 396 rt2x00_set_field32(&reg, ARCSR2_SERVICE, 0x04);
376 rt2x00_set_field32(&reg, ARCSR2_LENGTH, get_duration(ACK_SIZE, 10)); 397 rt2x00_set_field32(&reg, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 10));
377 rt2x00pci_register_write(rt2x00dev, ARCSR2, reg); 398 rt2x00pci_register_write(rt2x00dev, ARCSR2, reg);
378 399
379 rt2x00pci_register_read(rt2x00dev, ARCSR3, &reg); 400 rt2x00pci_register_read(rt2x00dev, ARCSR3, &reg);
380 rt2x00_set_field32(&reg, ARCSR3_SIGNAL, 0x01 | preamble_mask); 401 rt2x00_set_field32(&reg, ARCSR3_SIGNAL, 0x01 | preamble_mask);
381 rt2x00_set_field32(&reg, ARCSR3_SERVICE, 0x04); 402 rt2x00_set_field32(&reg, ARCSR3_SERVICE, 0x04);
382 rt2x00_set_field32(&reg, ARCSR2_LENGTH, get_duration(ACK_SIZE, 20)); 403 rt2x00_set_field32(&reg, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 20));
383 rt2x00pci_register_write(rt2x00dev, ARCSR3, reg); 404 rt2x00pci_register_write(rt2x00dev, ARCSR3, reg);
384 405
385 rt2x00pci_register_read(rt2x00dev, ARCSR4, &reg); 406 rt2x00pci_register_read(rt2x00dev, ARCSR4, &reg);
386 rt2x00_set_field32(&reg, ARCSR4_SIGNAL, 0x02 | preamble_mask); 407 rt2x00_set_field32(&reg, ARCSR4_SIGNAL, 0x02 | preamble_mask);
387 rt2x00_set_field32(&reg, ARCSR4_SERVICE, 0x04); 408 rt2x00_set_field32(&reg, ARCSR4_SERVICE, 0x04);
388 rt2x00_set_field32(&reg, ARCSR2_LENGTH, get_duration(ACK_SIZE, 55)); 409 rt2x00_set_field32(&reg, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 55));
389 rt2x00pci_register_write(rt2x00dev, ARCSR4, reg); 410 rt2x00pci_register_write(rt2x00dev, ARCSR4, reg);
390 411
391 rt2x00pci_register_read(rt2x00dev, ARCSR5, &reg); 412 rt2x00pci_register_read(rt2x00dev, ARCSR5, &reg);
392 rt2x00_set_field32(&reg, ARCSR5_SIGNAL, 0x03 | preamble_mask); 413 rt2x00_set_field32(&reg, ARCSR5_SIGNAL, 0x03 | preamble_mask);
393 rt2x00_set_field32(&reg, ARCSR5_SERVICE, 0x84); 414 rt2x00_set_field32(&reg, ARCSR5_SERVICE, 0x84);
394 rt2x00_set_field32(&reg, ARCSR2_LENGTH, get_duration(ACK_SIZE, 110)); 415 rt2x00_set_field32(&reg, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 110));
395 rt2x00pci_register_write(rt2x00dev, ARCSR5, reg); 416 rt2x00pci_register_write(rt2x00dev, ARCSR5, reg);
396 417
397 rt2x00pci_register_write(rt2x00dev, ARCSR1, erp->basic_rates); 418 rt2x00pci_register_write(rt2x00dev, ARCSR1, erp->basic_rates);
@@ -722,32 +743,43 @@ dynamic_cca_tune:
722/* 743/*
723 * Initialization functions. 744 * Initialization functions.
724 */ 745 */
725static void rt2500pci_init_rxentry(struct rt2x00_dev *rt2x00dev, 746static bool rt2500pci_get_entry_state(struct queue_entry *entry)
726 struct queue_entry *entry)
727{ 747{
728 struct queue_entry_priv_pci *entry_priv = entry->priv_data; 748 struct queue_entry_priv_pci *entry_priv = entry->priv_data;
729 struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
730 u32 word; 749 u32 word;
731 750
732 rt2x00_desc_read(entry_priv->desc, 1, &word); 751 if (entry->queue->qid == QID_RX) {
733 rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma); 752 rt2x00_desc_read(entry_priv->desc, 0, &word);
734 rt2x00_desc_write(entry_priv->desc, 1, word);
735 753
736 rt2x00_desc_read(entry_priv->desc, 0, &word); 754 return rt2x00_get_field32(word, RXD_W0_OWNER_NIC);
737 rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1); 755 } else {
738 rt2x00_desc_write(entry_priv->desc, 0, word); 756 rt2x00_desc_read(entry_priv->desc, 0, &word);
757
758 return (rt2x00_get_field32(word, TXD_W0_OWNER_NIC) ||
759 rt2x00_get_field32(word, TXD_W0_VALID));
760 }
739} 761}
740 762
741static void rt2500pci_init_txentry(struct rt2x00_dev *rt2x00dev, 763static void rt2500pci_clear_entry(struct queue_entry *entry)
742 struct queue_entry *entry)
743{ 764{
744 struct queue_entry_priv_pci *entry_priv = entry->priv_data; 765 struct queue_entry_priv_pci *entry_priv = entry->priv_data;
766 struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
745 u32 word; 767 u32 word;
746 768
747 rt2x00_desc_read(entry_priv->desc, 0, &word); 769 if (entry->queue->qid == QID_RX) {
748 rt2x00_set_field32(&word, TXD_W0_VALID, 0); 770 rt2x00_desc_read(entry_priv->desc, 1, &word);
749 rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0); 771 rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma);
750 rt2x00_desc_write(entry_priv->desc, 0, word); 772 rt2x00_desc_write(entry_priv->desc, 1, word);
773
774 rt2x00_desc_read(entry_priv->desc, 0, &word);
775 rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1);
776 rt2x00_desc_write(entry_priv->desc, 0, word);
777 } else {
778 rt2x00_desc_read(entry_priv->desc, 0, &word);
779 rt2x00_set_field32(&word, TXD_W0_VALID, 0);
780 rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0);
781 rt2x00_desc_write(entry_priv->desc, 0, word);
782 }
751} 783}
752 784
753static int rt2500pci_init_queues(struct rt2x00_dev *rt2x00dev) 785static int rt2500pci_init_queues(struct rt2x00_dev *rt2x00dev)
@@ -1871,8 +1903,8 @@ static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = {
1871 .probe_hw = rt2500pci_probe_hw, 1903 .probe_hw = rt2500pci_probe_hw,
1872 .initialize = rt2x00pci_initialize, 1904 .initialize = rt2x00pci_initialize,
1873 .uninitialize = rt2x00pci_uninitialize, 1905 .uninitialize = rt2x00pci_uninitialize,
1874 .init_rxentry = rt2500pci_init_rxentry, 1906 .get_entry_state = rt2500pci_get_entry_state,
1875 .init_txentry = rt2500pci_init_txentry, 1907 .clear_entry = rt2500pci_clear_entry,
1876 .set_device_state = rt2500pci_set_device_state, 1908 .set_device_state = rt2500pci_set_device_state,
1877 .rfkill_poll = rt2500pci_rfkill_poll, 1909 .rfkill_poll = rt2500pci_rfkill_poll,
1878 .link_stats = rt2500pci_link_stats, 1910 .link_stats = rt2500pci_link_stats,
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index 639d5a2f84e2..e6bae4ae4c47 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -47,7 +47,7 @@
47 * between each attampt. When the busy bit is still set at that time, 47 * between each attampt. When the busy bit is still set at that time,
48 * the access attempt is considered to have failed, 48 * the access attempt is considered to have failed,
49 * and we will print an error. 49 * and we will print an error.
50 * If the usb_cache_mutex is already held then the _lock variants must 50 * If the csr_mutex is already held then the _lock variants must
51 * be used instead. 51 * be used instead.
52 */ 52 */
53static inline void rt2500usb_register_read(struct rt2x00_dev *rt2x00dev, 53static inline void rt2500usb_register_read(struct rt2x00_dev *rt2x00dev,
@@ -132,7 +132,7 @@ static void rt2500usb_bbp_write(struct rt2x00_dev *rt2x00dev,
132{ 132{
133 u16 reg; 133 u16 reg;
134 134
135 mutex_lock(&rt2x00dev->usb_cache_mutex); 135 mutex_lock(&rt2x00dev->csr_mutex);
136 136
137 /* 137 /*
138 * Wait until the BBP becomes ready. 138 * Wait until the BBP becomes ready.
@@ -151,12 +151,12 @@ static void rt2500usb_bbp_write(struct rt2x00_dev *rt2x00dev,
151 151
152 rt2500usb_register_write_lock(rt2x00dev, PHY_CSR7, reg); 152 rt2500usb_register_write_lock(rt2x00dev, PHY_CSR7, reg);
153 153
154 mutex_unlock(&rt2x00dev->usb_cache_mutex); 154 mutex_unlock(&rt2x00dev->csr_mutex);
155 155
156 return; 156 return;
157 157
158exit_fail: 158exit_fail:
159 mutex_unlock(&rt2x00dev->usb_cache_mutex); 159 mutex_unlock(&rt2x00dev->csr_mutex);
160 160
161 ERROR(rt2x00dev, "PHY_CSR8 register busy. Write failed.\n"); 161 ERROR(rt2x00dev, "PHY_CSR8 register busy. Write failed.\n");
162} 162}
@@ -166,7 +166,7 @@ static void rt2500usb_bbp_read(struct rt2x00_dev *rt2x00dev,
166{ 166{
167 u16 reg; 167 u16 reg;
168 168
169 mutex_lock(&rt2x00dev->usb_cache_mutex); 169 mutex_lock(&rt2x00dev->csr_mutex);
170 170
171 /* 171 /*
172 * Wait until the BBP becomes ready. 172 * Wait until the BBP becomes ready.
@@ -194,12 +194,12 @@ static void rt2500usb_bbp_read(struct rt2x00_dev *rt2x00dev,
194 rt2500usb_register_read_lock(rt2x00dev, PHY_CSR7, &reg); 194 rt2500usb_register_read_lock(rt2x00dev, PHY_CSR7, &reg);
195 *value = rt2x00_get_field16(reg, PHY_CSR7_DATA); 195 *value = rt2x00_get_field16(reg, PHY_CSR7_DATA);
196 196
197 mutex_unlock(&rt2x00dev->usb_cache_mutex); 197 mutex_unlock(&rt2x00dev->csr_mutex);
198 198
199 return; 199 return;
200 200
201exit_fail: 201exit_fail:
202 mutex_unlock(&rt2x00dev->usb_cache_mutex); 202 mutex_unlock(&rt2x00dev->csr_mutex);
203 203
204 ERROR(rt2x00dev, "PHY_CSR8 register busy. Read failed.\n"); 204 ERROR(rt2x00dev, "PHY_CSR8 register busy. Read failed.\n");
205 *value = 0xff; 205 *value = 0xff;
@@ -214,7 +214,7 @@ static void rt2500usb_rf_write(struct rt2x00_dev *rt2x00dev,
214 if (!word) 214 if (!word)
215 return; 215 return;
216 216
217 mutex_lock(&rt2x00dev->usb_cache_mutex); 217 mutex_lock(&rt2x00dev->csr_mutex);
218 218
219 for (i = 0; i < REGISTER_BUSY_COUNT; i++) { 219 for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
220 rt2500usb_register_read_lock(rt2x00dev, PHY_CSR10, &reg); 220 rt2500usb_register_read_lock(rt2x00dev, PHY_CSR10, &reg);
@@ -223,7 +223,7 @@ static void rt2500usb_rf_write(struct rt2x00_dev *rt2x00dev,
223 udelay(REGISTER_BUSY_DELAY); 223 udelay(REGISTER_BUSY_DELAY);
224 } 224 }
225 225
226 mutex_unlock(&rt2x00dev->usb_cache_mutex); 226 mutex_unlock(&rt2x00dev->csr_mutex);
227 ERROR(rt2x00dev, "PHY_CSR10 register busy. Write failed.\n"); 227 ERROR(rt2x00dev, "PHY_CSR10 register busy. Write failed.\n");
228 return; 228 return;
229 229
@@ -241,7 +241,7 @@ rf_write:
241 rt2500usb_register_write_lock(rt2x00dev, PHY_CSR10, reg); 241 rt2500usb_register_write_lock(rt2x00dev, PHY_CSR10, reg);
242 rt2x00_rf_write(rt2x00dev, word, value); 242 rt2x00_rf_write(rt2x00dev, word, value);
243 243
244 mutex_unlock(&rt2x00dev->usb_cache_mutex); 244 mutex_unlock(&rt2x00dev->csr_mutex);
245} 245}
246 246
247#ifdef CONFIG_RT2X00_LIB_DEBUGFS 247#ifdef CONFIG_RT2X00_LIB_DEBUGFS
@@ -385,7 +385,7 @@ static void rt2500usb_config_intf(struct rt2x00_dev *rt2x00dev,
385 /* 385 /*
386 * Enable beacon config 386 * Enable beacon config
387 */ 387 */
388 bcn_preload = PREAMBLE + get_duration(IEEE80211_HEADER, 20); 388 bcn_preload = PREAMBLE + GET_DURATION(IEEE80211_HEADER, 20);
389 rt2500usb_register_read(rt2x00dev, TXRX_CSR20, &reg); 389 rt2500usb_register_read(rt2x00dev, TXRX_CSR20, &reg);
390 rt2x00_set_field16(&reg, TXRX_CSR20_OFFSET, bcn_preload >> 6); 390 rt2x00_set_field16(&reg, TXRX_CSR20_OFFSET, bcn_preload >> 6);
391 rt2x00_set_field16(&reg, TXRX_CSR20_BCN_EXPECT_WINDOW, 391 rt2x00_set_field16(&reg, TXRX_CSR20_BCN_EXPECT_WINDOW,
@@ -1777,8 +1777,7 @@ static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = {
1777 .probe_hw = rt2500usb_probe_hw, 1777 .probe_hw = rt2500usb_probe_hw,
1778 .initialize = rt2x00usb_initialize, 1778 .initialize = rt2x00usb_initialize,
1779 .uninitialize = rt2x00usb_uninitialize, 1779 .uninitialize = rt2x00usb_uninitialize,
1780 .init_rxentry = rt2x00usb_init_rxentry, 1780 .clear_entry = rt2x00usb_clear_entry,
1781 .init_txentry = rt2x00usb_init_txentry,
1782 .set_device_state = rt2500usb_set_device_state, 1781 .set_device_state = rt2500usb_set_device_state,
1783 .link_stats = rt2500usb_link_stats, 1782 .link_stats = rt2500usb_link_stats,
1784 .reset_tuner = rt2500usb_reset_tuner, 1783 .reset_tuner = rt2500usb_reset_tuner,
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index f85eedbbad68..fee61bee1e7e 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -92,6 +92,16 @@
92 DEBUG_PRINTK(__dev, KERN_DEBUG, "EEPROM recovery", __msg, ##__args) 92 DEBUG_PRINTK(__dev, KERN_DEBUG, "EEPROM recovery", __msg, ##__args)
93 93
94/* 94/*
95 * Duration calculations
96 * The rate variable passed is: 100kbs.
97 * To convert from bytes to bits we multiply size with 8,
98 * then the size is multiplied with 10 to make the
99 * real rate -> rate argument correction.
100 */
101#define GET_DURATION(__size, __rate) (((__size) * 8 * 10) / (__rate))
102#define GET_DURATION_RES(__size, __rate)(((__size) * 8 * 10) % (__rate))
103
104/*
95 * Standard timing and size defines. 105 * Standard timing and size defines.
96 * These values should follow the ieee80211 specifications. 106 * These values should follow the ieee80211 specifications.
97 */ 107 */
@@ -109,9 +119,9 @@
109#define DIFS ( PIFS + SLOT_TIME ) 119#define DIFS ( PIFS + SLOT_TIME )
110#define SHORT_DIFS ( SHORT_PIFS + SHORT_SLOT_TIME ) 120#define SHORT_DIFS ( SHORT_PIFS + SHORT_SLOT_TIME )
111#define EIFS ( SIFS + DIFS + \ 121#define EIFS ( SIFS + DIFS + \
112 (8 * (IEEE80211_HEADER + ACK_SIZE)) ) 122 GET_DURATION(IEEE80211_HEADER + ACK_SIZE, 10) )
113#define SHORT_EIFS ( SIFS + SHORT_DIFS + \ 123#define SHORT_EIFS ( SIFS + SHORT_DIFS + \
114 (8 * (IEEE80211_HEADER + ACK_SIZE)) ) 124 GET_DURATION(IEEE80211_HEADER + ACK_SIZE, 10) )
115 125
116/* 126/*
117 * Chipset identification 127 * Chipset identification
@@ -523,10 +533,8 @@ struct rt2x00lib_ops {
523 /* 533 /*
524 * queue initialization handlers 534 * queue initialization handlers
525 */ 535 */
526 void (*init_rxentry) (struct rt2x00_dev *rt2x00dev, 536 bool (*get_entry_state) (struct queue_entry *entry);
527 struct queue_entry *entry); 537 void (*clear_entry) (struct queue_entry *entry);
528 void (*init_txentry) (struct rt2x00_dev *rt2x00dev,
529 struct queue_entry *entry);
530 538
531 /* 539 /*
532 * Radio control handlers. 540 * Radio control handlers.
@@ -723,8 +731,7 @@ struct rt2x00_dev {
723 731
724 /* 732 /*
725 * This is the default TX/RX antenna setup as indicated 733 * This is the default TX/RX antenna setup as indicated
726 * by the device's EEPROM. When mac80211 sets its 734 * by the device's EEPROM.
727 * antenna value to 0 we should be using these values.
728 */ 735 */
729 struct antenna_setup default_ant; 736 struct antenna_setup default_ant;
730 737
@@ -739,16 +746,15 @@ struct rt2x00_dev {
739 } csr; 746 } csr;
740 747
741 /* 748 /*
742 * Mutex to protect register accesses on USB devices. 749 * Mutex to protect register accesses.
743 * There are 2 reasons this is needed, one is to ensure 750 * For PCI and USB devices it protects against concurrent indirect
744 * use of the csr_cache (for USB devices) by one thread 751 * register access (BBP, RF, MCU) since accessing those
745 * isn't corrupted by another thread trying to access it. 752 * registers require multiple calls to the CSR registers.
746 * The other is that access to BBP and RF registers 753 * For USB devices it also protects the csr_cache since that
747 * require multiple BUS transactions and if another thread 754 * field is used for normal CSR access and it cannot support
748 * attempted to access one of those registers at the same 755 * multiple callers simultaneously.
749 * time one of the writes could silently fail.
750 */ 756 */
751 struct mutex usb_cache_mutex; 757 struct mutex csr_mutex;
752 758
753 /* 759 /*
754 * Current packet filter configuration for the device. 760 * Current packet filter configuration for the device.
@@ -923,23 +929,6 @@ static inline u16 rt2x00_check_rev(const struct rt2x00_chip *chipset,
923 !!(chipset->rev & 0x0000f)); 929 !!(chipset->rev & 0x0000f));
924} 930}
925 931
926/*
927 * Duration calculations
928 * The rate variable passed is: 100kbs.
929 * To convert from bytes to bits we multiply size with 8,
930 * then the size is multiplied with 10 to make the
931 * real rate -> rate argument correction.
932 */
933static inline u16 get_duration(const unsigned int size, const u8 rate)
934{
935 return ((size * 8 * 10) / rate);
936}
937
938static inline u16 get_duration_res(const unsigned int size, const u8 rate)
939{
940 return ((size * 8 * 10) % rate);
941}
942
943/** 932/**
944 * rt2x00queue_map_txskb - Map a skb into DMA for TX purposes. 933 * rt2x00queue_map_txskb - Map a skb into DMA for TX purposes.
945 * @rt2x00dev: Pointer to &struct rt2x00_dev. 934 * @rt2x00dev: Pointer to &struct rt2x00_dev.
diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c
index 3e4eee3ab7d2..7c62ce125b94 100644
--- a/drivers/net/wireless/rt2x00/rt2x00config.c
+++ b/drivers/net/wireless/rt2x00/rt2x00config.c
@@ -92,8 +92,8 @@ void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev,
92 erp.difs = bss_conf->use_short_slot ? SHORT_DIFS : DIFS; 92 erp.difs = bss_conf->use_short_slot ? SHORT_DIFS : DIFS;
93 erp.eifs = bss_conf->use_short_slot ? SHORT_EIFS : EIFS; 93 erp.eifs = bss_conf->use_short_slot ? SHORT_EIFS : EIFS;
94 94
95 erp.ack_timeout = PLCP + erp.difs + get_duration(ACK_SIZE, 10); 95 erp.ack_timeout = PLCP + erp.difs + GET_DURATION(ACK_SIZE, 10);
96 erp.ack_consume_time = SIFS + PLCP + get_duration(ACK_SIZE, 10); 96 erp.ack_consume_time = SIFS + PLCP + GET_DURATION(ACK_SIZE, 10);
97 97
98 if (bss_conf->use_short_preamble) { 98 if (bss_conf->use_short_preamble) {
99 erp.ack_timeout += SHORT_PREAMBLE; 99 erp.ack_timeout += SHORT_PREAMBLE;
@@ -109,15 +109,32 @@ void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev,
109} 109}
110 110
111void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, 111void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
112 enum antenna rx, enum antenna tx) 112 struct antenna_setup *ant)
113{ 113{
114 struct antenna_setup ant; 114 /*
115 115 * Failsafe: Make sure we are not sending the
116 ant.rx = rx; 116 * ANTENNA_SW_DIVERSITY state to the driver.
117 ant.tx = tx; 117 * If that happes fallback to hardware default,
118 * or our own default.
119 */
120 if (ant->rx == ANTENNA_SW_DIVERSITY) {
121 if (rt2x00dev->default_ant.rx == ANTENNA_SW_DIVERSITY)
122 ant->rx = ANTENNA_B;
123 else
124 ant->rx = rt2x00dev->default_ant.rx;
125 }
126 if (ant->tx == ANTENNA_SW_DIVERSITY) {
127 if (rt2x00dev->default_ant.tx == ANTENNA_SW_DIVERSITY)
128 ant->tx = ANTENNA_B;
129 else
130 ant->tx = rt2x00dev->default_ant.tx;
131 }
118 132
119 if (rx == rt2x00dev->link.ant.active.rx && 133 /*
120 tx == rt2x00dev->link.ant.active.tx) 134 * Only reconfigure when something has changed.
135 */
136 if (ant->rx == rt2x00dev->link.ant.active.rx &&
137 ant->tx == rt2x00dev->link.ant.active.tx)
121 return; 138 return;
122 139
123 /* 140 /*
@@ -132,12 +149,12 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
132 * The latter is required since we need to recalibrate the 149 * The latter is required since we need to recalibrate the
133 * noise-sensitivity ratio for the new setup. 150 * noise-sensitivity ratio for the new setup.
134 */ 151 */
135 rt2x00dev->ops->lib->config_ant(rt2x00dev, &ant); 152 rt2x00dev->ops->lib->config_ant(rt2x00dev, ant);
136 153
137 rt2x00lib_reset_link_tuner(rt2x00dev); 154 rt2x00lib_reset_link_tuner(rt2x00dev);
138 rt2x00_reset_link_ant_rssi(&rt2x00dev->link); 155 rt2x00_reset_link_ant_rssi(&rt2x00dev->link);
139 156
140 memcpy(&rt2x00dev->link.ant.active, &ant, sizeof(ant)); 157 memcpy(&rt2x00dev->link.ant.active, ant, sizeof(*ant));
141 158
142 if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) 159 if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
143 rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON_LINK); 160 rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON_LINK);
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 477a944167c4..7fc1d766062b 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -101,8 +101,7 @@ int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev)
101 /* 101 /*
102 * Initialize all data queues. 102 * Initialize all data queues.
103 */ 103 */
104 rt2x00queue_init_rx(rt2x00dev); 104 rt2x00queue_init_queues(rt2x00dev);
105 rt2x00queue_init_tx(rt2x00dev);
106 105
107 /* 106 /*
108 * Enable radio. 107 * Enable radio.
@@ -176,13 +175,14 @@ void rt2x00lib_toggle_rx(struct rt2x00_dev *rt2x00dev, enum dev_state state)
176 175
177static void rt2x00lib_evaluate_antenna_sample(struct rt2x00_dev *rt2x00dev) 176static void rt2x00lib_evaluate_antenna_sample(struct rt2x00_dev *rt2x00dev)
178{ 177{
179 enum antenna rx = rt2x00dev->link.ant.active.rx; 178 struct antenna_setup ant;
180 enum antenna tx = rt2x00dev->link.ant.active.tx;
181 int sample_a = 179 int sample_a =
182 rt2x00_get_link_ant_rssi_history(&rt2x00dev->link, ANTENNA_A); 180 rt2x00_get_link_ant_rssi_history(&rt2x00dev->link, ANTENNA_A);
183 int sample_b = 181 int sample_b =
184 rt2x00_get_link_ant_rssi_history(&rt2x00dev->link, ANTENNA_B); 182 rt2x00_get_link_ant_rssi_history(&rt2x00dev->link, ANTENNA_B);
185 183
184 memcpy(&ant, &rt2x00dev->link.ant.active, sizeof(ant));
185
186 /* 186 /*
187 * We are done sampling. Now we should evaluate the results. 187 * We are done sampling. Now we should evaluate the results.
188 */ 188 */
@@ -200,21 +200,22 @@ static void rt2x00lib_evaluate_antenna_sample(struct rt2x00_dev *rt2x00dev)
200 return; 200 return;
201 201
202 if (rt2x00dev->link.ant.flags & ANTENNA_RX_DIVERSITY) 202 if (rt2x00dev->link.ant.flags & ANTENNA_RX_DIVERSITY)
203 rx = (sample_a > sample_b) ? ANTENNA_A : ANTENNA_B; 203 ant.rx = (sample_a > sample_b) ? ANTENNA_A : ANTENNA_B;
204 204
205 if (rt2x00dev->link.ant.flags & ANTENNA_TX_DIVERSITY) 205 if (rt2x00dev->link.ant.flags & ANTENNA_TX_DIVERSITY)
206 tx = (sample_a > sample_b) ? ANTENNA_A : ANTENNA_B; 206 ant.tx = (sample_a > sample_b) ? ANTENNA_A : ANTENNA_B;
207 207
208 rt2x00lib_config_antenna(rt2x00dev, rx, tx); 208 rt2x00lib_config_antenna(rt2x00dev, &ant);
209} 209}
210 210
211static void rt2x00lib_evaluate_antenna_eval(struct rt2x00_dev *rt2x00dev) 211static void rt2x00lib_evaluate_antenna_eval(struct rt2x00_dev *rt2x00dev)
212{ 212{
213 enum antenna rx = rt2x00dev->link.ant.active.rx; 213 struct antenna_setup ant;
214 enum antenna tx = rt2x00dev->link.ant.active.tx;
215 int rssi_curr = rt2x00_get_link_ant_rssi(&rt2x00dev->link); 214 int rssi_curr = rt2x00_get_link_ant_rssi(&rt2x00dev->link);
216 int rssi_old = rt2x00_update_ant_rssi(&rt2x00dev->link, rssi_curr); 215 int rssi_old = rt2x00_update_ant_rssi(&rt2x00dev->link, rssi_curr);
217 216
217 memcpy(&ant, &rt2x00dev->link.ant.active, sizeof(ant));
218
218 /* 219 /*
219 * Legacy driver indicates that we should swap antenna's 220 * Legacy driver indicates that we should swap antenna's
220 * when the difference in RSSI is greater that 5. This 221 * when the difference in RSSI is greater that 5. This
@@ -230,12 +231,12 @@ static void rt2x00lib_evaluate_antenna_eval(struct rt2x00_dev *rt2x00dev)
230 rt2x00dev->link.ant.flags |= ANTENNA_MODE_SAMPLE; 231 rt2x00dev->link.ant.flags |= ANTENNA_MODE_SAMPLE;
231 232
232 if (rt2x00dev->link.ant.flags & ANTENNA_RX_DIVERSITY) 233 if (rt2x00dev->link.ant.flags & ANTENNA_RX_DIVERSITY)
233 rx = (rx == ANTENNA_A) ? ANTENNA_B : ANTENNA_A; 234 ant.rx = (ant.rx == ANTENNA_A) ? ANTENNA_B : ANTENNA_A;
234 235
235 if (rt2x00dev->link.ant.flags & ANTENNA_TX_DIVERSITY) 236 if (rt2x00dev->link.ant.flags & ANTENNA_TX_DIVERSITY)
236 tx = (tx == ANTENNA_A) ? ANTENNA_B : ANTENNA_A; 237 ant.tx = (ant.tx == ANTENNA_A) ? ANTENNA_B : ANTENNA_A;
237 238
238 rt2x00lib_config_antenna(rt2x00dev, rx, tx); 239 rt2x00lib_config_antenna(rt2x00dev, &ant);
239} 240}
240 241
241static void rt2x00lib_evaluate_antenna(struct rt2x00_dev *rt2x00dev) 242static void rt2x00lib_evaluate_antenna(struct rt2x00_dev *rt2x00dev)
@@ -574,7 +575,7 @@ void rt2x00lib_txdone(struct queue_entry *entry,
574 entry->skb = NULL; 575 entry->skb = NULL;
575 entry->flags = 0; 576 entry->flags = 0;
576 577
577 rt2x00dev->ops->lib->init_txentry(rt2x00dev, entry); 578 rt2x00dev->ops->lib->clear_entry(entry);
578 579
579 clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); 580 clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
580 rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE); 581 rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE);
@@ -706,7 +707,7 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
706 entry->skb = skb; 707 entry->skb = skb;
707 entry->flags = 0; 708 entry->flags = 0;
708 709
709 rt2x00dev->ops->lib->init_rxentry(rt2x00dev, entry); 710 rt2x00dev->ops->lib->clear_entry(entry);
710 711
711 rt2x00queue_index_inc(entry->queue, Q_INDEX); 712 rt2x00queue_index_inc(entry->queue, Q_INDEX);
712} 713}
@@ -717,31 +718,31 @@ EXPORT_SYMBOL_GPL(rt2x00lib_rxdone);
717 */ 718 */
718const struct rt2x00_rate rt2x00_supported_rates[12] = { 719const struct rt2x00_rate rt2x00_supported_rates[12] = {
719 { 720 {
720 .flags = DEV_RATE_CCK | DEV_RATE_BASIC, 721 .flags = DEV_RATE_CCK,
721 .bitrate = 10, 722 .bitrate = 10,
722 .ratemask = BIT(0), 723 .ratemask = BIT(0),
723 .plcp = 0x00, 724 .plcp = 0x00,
724 }, 725 },
725 { 726 {
726 .flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE | DEV_RATE_BASIC, 727 .flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE,
727 .bitrate = 20, 728 .bitrate = 20,
728 .ratemask = BIT(1), 729 .ratemask = BIT(1),
729 .plcp = 0x01, 730 .plcp = 0x01,
730 }, 731 },
731 { 732 {
732 .flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE | DEV_RATE_BASIC, 733 .flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE,
733 .bitrate = 55, 734 .bitrate = 55,
734 .ratemask = BIT(2), 735 .ratemask = BIT(2),
735 .plcp = 0x02, 736 .plcp = 0x02,
736 }, 737 },
737 { 738 {
738 .flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE | DEV_RATE_BASIC, 739 .flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE,
739 .bitrate = 110, 740 .bitrate = 110,
740 .ratemask = BIT(3), 741 .ratemask = BIT(3),
741 .plcp = 0x03, 742 .plcp = 0x03,
742 }, 743 },
743 { 744 {
744 .flags = DEV_RATE_OFDM | DEV_RATE_BASIC, 745 .flags = DEV_RATE_OFDM,
745 .bitrate = 60, 746 .bitrate = 60,
746 .ratemask = BIT(4), 747 .ratemask = BIT(4),
747 .plcp = 0x0b, 748 .plcp = 0x0b,
@@ -753,7 +754,7 @@ const struct rt2x00_rate rt2x00_supported_rates[12] = {
753 .plcp = 0x0f, 754 .plcp = 0x0f,
754 }, 755 },
755 { 756 {
756 .flags = DEV_RATE_OFDM | DEV_RATE_BASIC, 757 .flags = DEV_RATE_OFDM,
757 .bitrate = 120, 758 .bitrate = 120,
758 .ratemask = BIT(6), 759 .ratemask = BIT(6),
759 .plcp = 0x0a, 760 .plcp = 0x0a,
@@ -765,7 +766,7 @@ const struct rt2x00_rate rt2x00_supported_rates[12] = {
765 .plcp = 0x0e, 766 .plcp = 0x0e,
766 }, 767 },
767 { 768 {
768 .flags = DEV_RATE_OFDM | DEV_RATE_BASIC, 769 .flags = DEV_RATE_OFDM,
769 .bitrate = 240, 770 .bitrate = 240,
770 .ratemask = BIT(8), 771 .ratemask = BIT(8),
771 .plcp = 0x09, 772 .plcp = 0x09,
@@ -1050,6 +1051,8 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
1050{ 1051{
1051 int retval = -ENOMEM; 1052 int retval = -ENOMEM;
1052 1053
1054 mutex_init(&rt2x00dev->csr_mutex);
1055
1053 /* 1056 /*
1054 * Make room for rt2x00_intf inside the per-interface 1057 * Make room for rt2x00_intf inside the per-interface
1055 * structure ieee80211_vif. 1058 * structure ieee80211_vif.
diff --git a/drivers/net/wireless/rt2x00/rt2x00leds.c b/drivers/net/wireless/rt2x00/rt2x00leds.c
index b362a1cf3f8d..66c61b1eca5d 100644
--- a/drivers/net/wireless/rt2x00/rt2x00leds.c
+++ b/drivers/net/wireless/rt2x00/rt2x00leds.c
@@ -72,49 +72,33 @@ void rt2x00leds_led_quality(struct rt2x00_dev *rt2x00dev, int rssi)
72 } 72 }
73} 73}
74 74
75void rt2x00led_led_activity(struct rt2x00_dev *rt2x00dev, bool enabled) 75static void rt2x00led_led_simple(struct rt2x00_led *led, bool enabled)
76{ 76{
77 struct rt2x00_led *led = &rt2x00dev->led_qual; 77 unsigned int brightness = enabled ? LED_FULL : LED_OFF;
78 unsigned int brightness;
79 78
80 if ((led->type != LED_TYPE_ACTIVITY) || !(led->flags & LED_REGISTERED)) 79 if (!(led->flags & LED_REGISTERED))
81 return; 80 return;
82 81
83 brightness = enabled ? LED_FULL : LED_OFF; 82 led->led_dev.brightness_set(&led->led_dev, brightness);
84 if (brightness != led->led_dev.brightness) { 83 led->led_dev.brightness = brightness;
85 led->led_dev.brightness_set(&led->led_dev, brightness);
86 led->led_dev.brightness = brightness;
87 }
88} 84}
89 85
90void rt2x00leds_led_assoc(struct rt2x00_dev *rt2x00dev, bool enabled) 86void rt2x00led_led_activity(struct rt2x00_dev *rt2x00dev, bool enabled)
91{ 87{
92 struct rt2x00_led *led = &rt2x00dev->led_assoc; 88 if (rt2x00dev->led_qual.type == LED_TYPE_ACTIVITY)
93 unsigned int brightness; 89 rt2x00led_led_simple(&rt2x00dev->led_qual, enabled);
94 90}
95 if ((led->type != LED_TYPE_ASSOC) || !(led->flags & LED_REGISTERED))
96 return;
97 91
98 brightness = enabled ? LED_FULL : LED_OFF; 92void rt2x00leds_led_assoc(struct rt2x00_dev *rt2x00dev, bool enabled)
99 if (brightness != led->led_dev.brightness) { 93{
100 led->led_dev.brightness_set(&led->led_dev, brightness); 94 if (rt2x00dev->led_assoc.type == LED_TYPE_ASSOC)
101 led->led_dev.brightness = brightness; 95 rt2x00led_led_simple(&rt2x00dev->led_assoc, enabled);
102 }
103} 96}
104 97
105void rt2x00leds_led_radio(struct rt2x00_dev *rt2x00dev, bool enabled) 98void rt2x00leds_led_radio(struct rt2x00_dev *rt2x00dev, bool enabled)
106{ 99{
107 struct rt2x00_led *led = &rt2x00dev->led_radio; 100 if (rt2x00dev->led_radio.type == LED_TYPE_ASSOC)
108 unsigned int brightness; 101 rt2x00led_led_simple(&rt2x00dev->led_radio, enabled);
109
110 if ((led->type != LED_TYPE_RADIO) || !(led->flags & LED_REGISTERED))
111 return;
112
113 brightness = enabled ? LED_FULL : LED_OFF;
114 if (brightness != led->led_dev.brightness) {
115 led->led_dev.brightness_set(&led->led_dev, brightness);
116 led->led_dev.brightness = brightness;
117 }
118} 102}
119 103
120static int rt2x00leds_register_led(struct rt2x00_dev *rt2x00dev, 104static int rt2x00leds_register_led(struct rt2x00_dev *rt2x00dev,
@@ -125,6 +109,13 @@ static int rt2x00leds_register_led(struct rt2x00_dev *rt2x00dev,
125 int retval; 109 int retval;
126 110
127 led->led_dev.name = name; 111 led->led_dev.name = name;
112 led->led_dev.brightness = LED_OFF;
113
114 /*
115 * Ensure the LED is off, it might have been enabled
116 * by the hardware when the device was powered on.
117 */
118 led->led_dev.brightness_set(&led->led_dev, LED_OFF);
128 119
129 retval = led_classdev_register(device, &led->led_dev); 120 retval = led_classdev_register(device, &led->led_dev);
130 if (retval) { 121 if (retval) {
@@ -199,7 +190,16 @@ exit_fail:
199static void rt2x00leds_unregister_led(struct rt2x00_led *led) 190static void rt2x00leds_unregister_led(struct rt2x00_led *led)
200{ 191{
201 led_classdev_unregister(&led->led_dev); 192 led_classdev_unregister(&led->led_dev);
202 led->led_dev.brightness_set(&led->led_dev, LED_OFF); 193
194 /*
195 * This might look weird, but when we are unregistering while
196 * suspended the led is already off, and since we haven't
197 * fully resumed yet, access to the device might not be
198 * possible yet.
199 */
200 if (!(led->led_dev.flags & LED_SUSPENDED))
201 led->led_dev.brightness_set(&led->led_dev, LED_OFF);
202
203 led->flags &= ~LED_REGISTERED; 203 led->flags &= ~LED_REGISTERED;
204} 204}
205 205
@@ -213,22 +213,40 @@ void rt2x00leds_unregister(struct rt2x00_dev *rt2x00dev)
213 rt2x00leds_unregister_led(&rt2x00dev->led_radio); 213 rt2x00leds_unregister_led(&rt2x00dev->led_radio);
214} 214}
215 215
216static inline void rt2x00leds_suspend_led(struct rt2x00_led *led)
217{
218 led_classdev_suspend(&led->led_dev);
219
220 /* This shouldn't be needed, but just to be safe */
221 led->led_dev.brightness_set(&led->led_dev, LED_OFF);
222 led->led_dev.brightness = LED_OFF;
223}
224
216void rt2x00leds_suspend(struct rt2x00_dev *rt2x00dev) 225void rt2x00leds_suspend(struct rt2x00_dev *rt2x00dev)
217{ 226{
218 if (rt2x00dev->led_qual.flags & LED_REGISTERED) 227 if (rt2x00dev->led_qual.flags & LED_REGISTERED)
219 led_classdev_suspend(&rt2x00dev->led_qual.led_dev); 228 rt2x00leds_suspend_led(&rt2x00dev->led_qual);
220 if (rt2x00dev->led_assoc.flags & LED_REGISTERED) 229 if (rt2x00dev->led_assoc.flags & LED_REGISTERED)
221 led_classdev_suspend(&rt2x00dev->led_assoc.led_dev); 230 rt2x00leds_suspend_led(&rt2x00dev->led_assoc);
222 if (rt2x00dev->led_radio.flags & LED_REGISTERED) 231 if (rt2x00dev->led_radio.flags & LED_REGISTERED)
223 led_classdev_suspend(&rt2x00dev->led_radio.led_dev); 232 rt2x00leds_suspend_led(&rt2x00dev->led_radio);
233}
234
235static inline void rt2x00leds_resume_led(struct rt2x00_led *led)
236{
237 led_classdev_resume(&led->led_dev);
238
239 /* Device might have enabled the LEDS during resume */
240 led->led_dev.brightness_set(&led->led_dev, LED_OFF);
241 led->led_dev.brightness = LED_OFF;
224} 242}
225 243
226void rt2x00leds_resume(struct rt2x00_dev *rt2x00dev) 244void rt2x00leds_resume(struct rt2x00_dev *rt2x00dev)
227{ 245{
228 if (rt2x00dev->led_radio.flags & LED_REGISTERED) 246 if (rt2x00dev->led_radio.flags & LED_REGISTERED)
229 led_classdev_resume(&rt2x00dev->led_radio.led_dev); 247 rt2x00leds_resume_led(&rt2x00dev->led_radio);
230 if (rt2x00dev->led_assoc.flags & LED_REGISTERED) 248 if (rt2x00dev->led_assoc.flags & LED_REGISTERED)
231 led_classdev_resume(&rt2x00dev->led_assoc.led_dev); 249 rt2x00leds_resume_led(&rt2x00dev->led_assoc);
232 if (rt2x00dev->led_qual.flags & LED_REGISTERED) 250 if (rt2x00dev->led_qual.flags & LED_REGISTERED)
233 led_classdev_resume(&rt2x00dev->led_qual.led_dev); 251 rt2x00leds_resume_led(&rt2x00dev->led_qual);
234} 252}
diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h
index 9f214f89ba6d..93997333d46d 100644
--- a/drivers/net/wireless/rt2x00/rt2x00lib.h
+++ b/drivers/net/wireless/rt2x00/rt2x00lib.h
@@ -43,7 +43,6 @@ struct rt2x00_rate {
43#define DEV_RATE_CCK 0x0001 43#define DEV_RATE_CCK 0x0001
44#define DEV_RATE_OFDM 0x0002 44#define DEV_RATE_OFDM 0x0002
45#define DEV_RATE_SHORT_PREAMBLE 0x0004 45#define DEV_RATE_SHORT_PREAMBLE 0x0004
46#define DEV_RATE_BASIC 0x0008
47 46
48 unsigned short bitrate; /* In 100kbit/s */ 47 unsigned short bitrate; /* In 100kbit/s */
49 unsigned short ratemask; 48 unsigned short ratemask;
@@ -94,7 +93,7 @@ void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev,
94 struct rt2x00_intf *intf, 93 struct rt2x00_intf *intf,
95 struct ieee80211_bss_conf *conf); 94 struct ieee80211_bss_conf *conf);
96void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, 95void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
97 enum antenna rx, enum antenna tx); 96 struct antenna_setup *ant);
98void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, 97void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
99 struct ieee80211_conf *conf, 98 struct ieee80211_conf *conf,
100 const unsigned int changed_flags); 99 const unsigned int changed_flags);
@@ -151,8 +150,16 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev,
151 */ 150 */
152void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index); 151void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index);
153 152
154void rt2x00queue_init_rx(struct rt2x00_dev *rt2x00dev); 153/**
155void rt2x00queue_init_tx(struct rt2x00_dev *rt2x00dev); 154 * rt2x00queue_init_queues - Initialize all data queues
155 * @rt2x00dev: Pointer to &struct rt2x00_dev.
156 *
157 * This function will loop through all available queues to clear all
158 * index numbers and set the queue entry to the correct initialization
159 * state.
160 */
161void rt2x00queue_init_queues(struct rt2x00_dev *rt2x00dev);
162
156int rt2x00queue_initialize(struct rt2x00_dev *rt2x00dev); 163int rt2x00queue_initialize(struct rt2x00_dev *rt2x00dev);
157void rt2x00queue_uninitialize(struct rt2x00_dev *rt2x00dev); 164void rt2x00queue_uninitialize(struct rt2x00_dev *rt2x00dev);
158int rt2x00queue_allocate(struct rt2x00_dev *rt2x00dev); 165int rt2x00queue_allocate(struct rt2x00_dev *rt2x00dev);
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index 8fc2315c5963..48636b0dd895 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -339,7 +339,6 @@ int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed)
339{ 339{
340 struct rt2x00_dev *rt2x00dev = hw->priv; 340 struct rt2x00_dev *rt2x00dev = hw->priv;
341 struct ieee80211_conf *conf = &hw->conf; 341 struct ieee80211_conf *conf = &hw->conf;
342 int radio_on;
343 int status; 342 int status;
344 343
345 /* 344 /*
@@ -356,7 +355,6 @@ int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed)
356 * some configuration parameters (e.g. channel and antenna values) can 355 * some configuration parameters (e.g. channel and antenna values) can
357 * only be set when the radio is enabled. 356 * only be set when the radio is enabled.
358 */ 357 */
359 radio_on = test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags);
360 if (conf->radio_enabled) { 358 if (conf->radio_enabled) {
361 /* For programming the values, we have to turn RX off */ 359 /* For programming the values, we have to turn RX off */
362 rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF); 360 rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF);
@@ -372,6 +370,17 @@ int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed)
372 */ 370 */
373 rt2x00lib_config(rt2x00dev, conf, changed); 371 rt2x00lib_config(rt2x00dev, conf, changed);
374 372
373 /*
374 * The radio was enabled, configure the antenna to the
375 * default settings, the link tuner will later start
376 * continue configuring the antenna based on the software
377 * diversity. But for non-diversity configurations, we need
378 * to have configured the correct state now.
379 */
380 if (changed & IEEE80211_CONF_CHANGE_RADIO_ENABLED)
381 rt2x00lib_config_antenna(rt2x00dev,
382 &rt2x00dev->default_ant);
383
375 /* Turn RX back on */ 384 /* Turn RX back on */
376 rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON); 385 rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON);
377 } else { 386 } else {
@@ -486,7 +495,9 @@ int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
486 struct ieee80211_key_conf *key); 495 struct ieee80211_key_conf *key);
487 struct rt2x00lib_crypto crypto; 496 struct rt2x00lib_crypto crypto;
488 497
489 if (!test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags)) 498 if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
499 return 0;
500 else if (!test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags))
490 return -EOPNOTSUPP; 501 return -EOPNOTSUPP;
491 else if (key->keylen > 32) 502 else if (key->keylen > 32)
492 return -ENOSPC; 503 return -ENOSPC;
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c
index 62449da577e5..e33bd0f150c5 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.c
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
@@ -36,20 +36,17 @@
36 */ 36 */
37int rt2x00pci_write_tx_data(struct queue_entry *entry) 37int rt2x00pci_write_tx_data(struct queue_entry *entry)
38{ 38{
39 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
39 struct queue_entry_priv_pci *entry_priv = entry->priv_data; 40 struct queue_entry_priv_pci *entry_priv = entry->priv_data;
40 struct skb_frame_desc *skbdesc; 41 struct skb_frame_desc *skbdesc;
41 u32 word;
42
43 rt2x00_desc_read(entry_priv->desc, 0, &word);
44 42
45 /* 43 /*
46 * This should not happen, we already checked the entry 44 * This should not happen, we already checked the entry
47 * was ours. When the hardware disagrees there has been 45 * was ours. When the hardware disagrees there has been
48 * a queue corruption! 46 * a queue corruption!
49 */ 47 */
50 if (unlikely(rt2x00_get_field32(word, TXD_ENTRY_OWNER_NIC) || 48 if (unlikely(rt2x00dev->ops->lib->get_entry_state(entry))) {
51 rt2x00_get_field32(word, TXD_ENTRY_VALID))) { 49 ERROR(rt2x00dev,
52 ERROR(entry->queue->rt2x00dev,
53 "Corrupt queue %d, accessing entry which is not ours.\n" 50 "Corrupt queue %d, accessing entry which is not ours.\n"
54 "Please file bug report to %s.\n", 51 "Please file bug report to %s.\n",
55 entry->queue->qid, DRV_PROJECT); 52 entry->queue->qid, DRV_PROJECT);
@@ -76,14 +73,12 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev)
76 struct queue_entry *entry; 73 struct queue_entry *entry;
77 struct queue_entry_priv_pci *entry_priv; 74 struct queue_entry_priv_pci *entry_priv;
78 struct skb_frame_desc *skbdesc; 75 struct skb_frame_desc *skbdesc;
79 u32 word;
80 76
81 while (1) { 77 while (1) {
82 entry = rt2x00queue_get_entry(queue, Q_INDEX); 78 entry = rt2x00queue_get_entry(queue, Q_INDEX);
83 entry_priv = entry->priv_data; 79 entry_priv = entry->priv_data;
84 rt2x00_desc_read(entry_priv->desc, 0, &word);
85 80
86 if (rt2x00_get_field32(word, RXD_ENTRY_OWNER_NIC)) 81 if (rt2x00dev->ops->lib->get_entry_state(entry))
87 break; 82 break;
88 83
89 /* 84 /*
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.h b/drivers/net/wireless/rt2x00/rt2x00pci.h
index a83f45f784f2..96a2082a3532 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.h
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.h
@@ -44,17 +44,6 @@
44#define REGISTER_BUSY_DELAY 100 44#define REGISTER_BUSY_DELAY 100
45 45
46/* 46/*
47 * Descriptor availability flags.
48 * All PCI device descriptors have these 2 flags
49 * with the exact same definition.
50 * By storing them here we can use them inside rt2x00pci
51 * for some simple entry availability checking.
52 */
53#define TXD_ENTRY_OWNER_NIC FIELD32(0x00000001)
54#define TXD_ENTRY_VALID FIELD32(0x00000002)
55#define RXD_ENTRY_OWNER_NIC FIELD32(0x00000001)
56
57/*
58 * Register access. 47 * Register access.
59 */ 48 */
60static inline void rt2x00pci_register_read(struct rt2x00_dev *rt2x00dev, 49static inline void rt2x00pci_register_read(struct rt2x00_dev *rt2x00dev,
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index e9f4261054bc..d7752dbd2023 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -319,8 +319,8 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
319 /* 319 /*
320 * Convert length to microseconds. 320 * Convert length to microseconds.
321 */ 321 */
322 residual = get_duration_res(data_length, hwrate->bitrate); 322 residual = GET_DURATION_RES(data_length, hwrate->bitrate);
323 duration = get_duration(data_length, hwrate->bitrate); 323 duration = GET_DURATION(data_length, hwrate->bitrate);
324 324
325 if (residual != 0) { 325 if (residual != 0) {
326 duration++; 326 duration++;
@@ -589,40 +589,18 @@ static void rt2x00queue_reset(struct data_queue *queue)
589 spin_unlock_irqrestore(&queue->lock, irqflags); 589 spin_unlock_irqrestore(&queue->lock, irqflags);
590} 590}
591 591
592void rt2x00queue_init_rx(struct rt2x00_dev *rt2x00dev) 592void rt2x00queue_init_queues(struct rt2x00_dev *rt2x00dev)
593{
594 struct data_queue *queue = rt2x00dev->rx;
595 unsigned int i;
596
597 rt2x00queue_reset(queue);
598
599 if (!rt2x00dev->ops->lib->init_rxentry)
600 return;
601
602 for (i = 0; i < queue->limit; i++) {
603 queue->entries[i].flags = 0;
604
605 rt2x00dev->ops->lib->init_rxentry(rt2x00dev,
606 &queue->entries[i]);
607 }
608}
609
610void rt2x00queue_init_tx(struct rt2x00_dev *rt2x00dev)
611{ 593{
612 struct data_queue *queue; 594 struct data_queue *queue;
613 unsigned int i; 595 unsigned int i;
614 596
615 txall_queue_for_each(rt2x00dev, queue) { 597 queue_for_each(rt2x00dev, queue) {
616 rt2x00queue_reset(queue); 598 rt2x00queue_reset(queue);
617 599
618 if (!rt2x00dev->ops->lib->init_txentry)
619 continue;
620
621 for (i = 0; i < queue->limit; i++) { 600 for (i = 0; i < queue->limit; i++) {
622 queue->entries[i].flags = 0; 601 queue->entries[i].flags = 0;
623 602
624 rt2x00dev->ops->lib->init_txentry(rt2x00dev, 603 rt2x00dev->ops->lib->clear_entry(&queue->entries[i]);
625 &queue->entries[i]);
626 } 604 }
627 } 605 }
628} 606}
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c
index b73a7e0aeed4..c507b0d9409f 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.c
@@ -79,7 +79,7 @@ int rt2x00usb_vendor_req_buff_lock(struct rt2x00_dev *rt2x00dev,
79{ 79{
80 int status; 80 int status;
81 81
82 BUG_ON(!mutex_is_locked(&rt2x00dev->usb_cache_mutex)); 82 BUG_ON(!mutex_is_locked(&rt2x00dev->csr_mutex));
83 83
84 /* 84 /*
85 * Check for Cache availability. 85 * Check for Cache availability.
@@ -110,13 +110,13 @@ int rt2x00usb_vendor_request_buff(struct rt2x00_dev *rt2x00dev,
110{ 110{
111 int status; 111 int status;
112 112
113 mutex_lock(&rt2x00dev->usb_cache_mutex); 113 mutex_lock(&rt2x00dev->csr_mutex);
114 114
115 status = rt2x00usb_vendor_req_buff_lock(rt2x00dev, request, 115 status = rt2x00usb_vendor_req_buff_lock(rt2x00dev, request,
116 requesttype, offset, buffer, 116 requesttype, offset, buffer,
117 buffer_length, timeout); 117 buffer_length, timeout);
118 118
119 mutex_unlock(&rt2x00dev->usb_cache_mutex); 119 mutex_unlock(&rt2x00dev->csr_mutex);
120 120
121 return status; 121 return status;
122} 122}
@@ -132,7 +132,7 @@ int rt2x00usb_vendor_request_large_buff(struct rt2x00_dev *rt2x00dev,
132 unsigned char *tb; 132 unsigned char *tb;
133 u16 off, len, bsize; 133 u16 off, len, bsize;
134 134
135 mutex_lock(&rt2x00dev->usb_cache_mutex); 135 mutex_lock(&rt2x00dev->csr_mutex);
136 136
137 tb = (char *)buffer; 137 tb = (char *)buffer;
138 off = offset; 138 off = offset;
@@ -148,7 +148,7 @@ int rt2x00usb_vendor_request_large_buff(struct rt2x00_dev *rt2x00dev,
148 off += bsize; 148 off += bsize;
149 } 149 }
150 150
151 mutex_unlock(&rt2x00dev->usb_cache_mutex); 151 mutex_unlock(&rt2x00dev->csr_mutex);
152 152
153 return status; 153 return status;
154} 154}
@@ -351,28 +351,25 @@ EXPORT_SYMBOL_GPL(rt2x00usb_disable_radio);
351/* 351/*
352 * Device initialization handlers. 352 * Device initialization handlers.
353 */ 353 */
354void rt2x00usb_init_rxentry(struct rt2x00_dev *rt2x00dev, 354void rt2x00usb_clear_entry(struct queue_entry *entry)
355 struct queue_entry *entry)
356{ 355{
357 struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev); 356 struct usb_device *usb_dev =
357 to_usb_device_intf(entry->queue->rt2x00dev->dev);
358 struct queue_entry_priv_usb *entry_priv = entry->priv_data; 358 struct queue_entry_priv_usb *entry_priv = entry->priv_data;
359 359
360 usb_fill_bulk_urb(entry_priv->urb, usb_dev, 360 if (entry->queue->qid == QID_RX) {
361 usb_rcvbulkpipe(usb_dev, 1), 361 usb_fill_bulk_urb(entry_priv->urb, usb_dev,
362 entry->skb->data, entry->skb->len, 362 usb_rcvbulkpipe(usb_dev, 1),
363 rt2x00usb_interrupt_rxdone, entry); 363 entry->skb->data, entry->skb->len,
364 rt2x00usb_interrupt_rxdone, entry);
364 365
365 set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); 366 set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
366 usb_submit_urb(entry_priv->urb, GFP_ATOMIC); 367 usb_submit_urb(entry_priv->urb, GFP_ATOMIC);
367} 368 } else {
368EXPORT_SYMBOL_GPL(rt2x00usb_init_rxentry); 369 entry->flags = 0;
369 370 }
370void rt2x00usb_init_txentry(struct rt2x00_dev *rt2x00dev,
371 struct queue_entry *entry)
372{
373 entry->flags = 0;
374} 371}
375EXPORT_SYMBOL_GPL(rt2x00usb_init_txentry); 372EXPORT_SYMBOL_GPL(rt2x00usb_clear_entry);
376 373
377static int rt2x00usb_alloc_urb(struct rt2x00_dev *rt2x00dev, 374static int rt2x00usb_alloc_urb(struct rt2x00_dev *rt2x00dev,
378 struct data_queue *queue) 375 struct data_queue *queue)
@@ -534,7 +531,6 @@ int rt2x00usb_probe(struct usb_interface *usb_intf,
534 rt2x00dev->dev = &usb_intf->dev; 531 rt2x00dev->dev = &usb_intf->dev;
535 rt2x00dev->ops = ops; 532 rt2x00dev->ops = ops;
536 rt2x00dev->hw = hw; 533 rt2x00dev->hw = hw;
537 mutex_init(&rt2x00dev->usb_cache_mutex);
538 534
539 rt2x00dev->usb_maxpacket = 535 rt2x00dev->usb_maxpacket =
540 usb_maxpacket(usb_dev, usb_sndbulkpipe(usb_dev, 1), 1); 536 usb_maxpacket(usb_dev, usb_sndbulkpipe(usb_dev, 1), 1);
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.h b/drivers/net/wireless/rt2x00/rt2x00usb.h
index 3b4a67417f95..4104f0e8fa48 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.h
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.h
@@ -286,10 +286,7 @@ void rt2x00usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
286/* 286/*
287 * Device initialization handlers. 287 * Device initialization handlers.
288 */ 288 */
289void rt2x00usb_init_rxentry(struct rt2x00_dev *rt2x00dev, 289void rt2x00usb_clear_entry(struct queue_entry *entry);
290 struct queue_entry *entry);
291void rt2x00usb_init_txentry(struct rt2x00_dev *rt2x00dev,
292 struct queue_entry *entry);
293int rt2x00usb_initialize(struct rt2x00_dev *rt2x00dev); 290int rt2x00usb_initialize(struct rt2x00_dev *rt2x00dev);
294void rt2x00usb_uninitialize(struct rt2x00_dev *rt2x00dev); 291void rt2x00usb_uninitialize(struct rt2x00_dev *rt2x00dev);
295 292
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index 3f272793412a..89ac34fbadf2 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -75,14 +75,14 @@ static void rt61pci_bbp_write(struct rt2x00_dev *rt2x00dev,
75{ 75{
76 u32 reg; 76 u32 reg;
77 77
78 mutex_lock(&rt2x00dev->csr_mutex);
79
78 /* 80 /*
79 * Wait until the BBP becomes ready. 81 * Wait until the BBP becomes ready.
80 */ 82 */
81 reg = rt61pci_bbp_check(rt2x00dev); 83 reg = rt61pci_bbp_check(rt2x00dev);
82 if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) { 84 if (rt2x00_get_field32(reg, PHY_CSR3_BUSY))
83 ERROR(rt2x00dev, "PHY_CSR3 register busy. Write failed.\n"); 85 goto exit_fail;
84 return;
85 }
86 86
87 /* 87 /*
88 * Write the data into the BBP. 88 * Write the data into the BBP.
@@ -94,6 +94,14 @@ static void rt61pci_bbp_write(struct rt2x00_dev *rt2x00dev,
94 rt2x00_set_field32(&reg, PHY_CSR3_READ_CONTROL, 0); 94 rt2x00_set_field32(&reg, PHY_CSR3_READ_CONTROL, 0);
95 95
96 rt2x00pci_register_write(rt2x00dev, PHY_CSR3, reg); 96 rt2x00pci_register_write(rt2x00dev, PHY_CSR3, reg);
97 mutex_unlock(&rt2x00dev->csr_mutex);
98
99 return;
100
101exit_fail:
102 mutex_unlock(&rt2x00dev->csr_mutex);
103
104 ERROR(rt2x00dev, "PHY_CSR3 register busy. Write failed.\n");
97} 105}
98 106
99static void rt61pci_bbp_read(struct rt2x00_dev *rt2x00dev, 107static void rt61pci_bbp_read(struct rt2x00_dev *rt2x00dev,
@@ -101,14 +109,14 @@ static void rt61pci_bbp_read(struct rt2x00_dev *rt2x00dev,
101{ 109{
102 u32 reg; 110 u32 reg;
103 111
112 mutex_lock(&rt2x00dev->csr_mutex);
113
104 /* 114 /*
105 * Wait until the BBP becomes ready. 115 * Wait until the BBP becomes ready.
106 */ 116 */
107 reg = rt61pci_bbp_check(rt2x00dev); 117 reg = rt61pci_bbp_check(rt2x00dev);
108 if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) { 118 if (rt2x00_get_field32(reg, PHY_CSR3_BUSY))
109 ERROR(rt2x00dev, "PHY_CSR3 register busy. Read failed.\n"); 119 goto exit_fail;
110 return;
111 }
112 120
113 /* 121 /*
114 * Write the request into the BBP. 122 * Write the request into the BBP.
@@ -124,13 +132,19 @@ static void rt61pci_bbp_read(struct rt2x00_dev *rt2x00dev,
124 * Wait until the BBP becomes ready. 132 * Wait until the BBP becomes ready.
125 */ 133 */
126 reg = rt61pci_bbp_check(rt2x00dev); 134 reg = rt61pci_bbp_check(rt2x00dev);
127 if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) { 135 if (rt2x00_get_field32(reg, PHY_CSR3_BUSY))
128 ERROR(rt2x00dev, "PHY_CSR3 register busy. Read failed.\n"); 136 goto exit_fail;
129 *value = 0xff;
130 return;
131 }
132 137
133 *value = rt2x00_get_field32(reg, PHY_CSR3_VALUE); 138 *value = rt2x00_get_field32(reg, PHY_CSR3_VALUE);
139 mutex_unlock(&rt2x00dev->csr_mutex);
140
141 return;
142
143exit_fail:
144 mutex_unlock(&rt2x00dev->csr_mutex);
145
146 ERROR(rt2x00dev, "PHY_CSR3 register busy. Read failed.\n");
147 *value = 0xff;
134} 148}
135 149
136static void rt61pci_rf_write(struct rt2x00_dev *rt2x00dev, 150static void rt61pci_rf_write(struct rt2x00_dev *rt2x00dev,
@@ -142,6 +156,8 @@ static void rt61pci_rf_write(struct rt2x00_dev *rt2x00dev,
142 if (!word) 156 if (!word)
143 return; 157 return;
144 158
159 mutex_lock(&rt2x00dev->csr_mutex);
160
145 for (i = 0; i < REGISTER_BUSY_COUNT; i++) { 161 for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
146 rt2x00pci_register_read(rt2x00dev, PHY_CSR4, &reg); 162 rt2x00pci_register_read(rt2x00dev, PHY_CSR4, &reg);
147 if (!rt2x00_get_field32(reg, PHY_CSR4_BUSY)) 163 if (!rt2x00_get_field32(reg, PHY_CSR4_BUSY))
@@ -149,6 +165,7 @@ static void rt61pci_rf_write(struct rt2x00_dev *rt2x00dev,
149 udelay(REGISTER_BUSY_DELAY); 165 udelay(REGISTER_BUSY_DELAY);
150 } 166 }
151 167
168 mutex_unlock(&rt2x00dev->csr_mutex);
152 ERROR(rt2x00dev, "PHY_CSR4 register busy. Write failed.\n"); 169 ERROR(rt2x00dev, "PHY_CSR4 register busy. Write failed.\n");
153 return; 170 return;
154 171
@@ -161,6 +178,8 @@ rf_write:
161 178
162 rt2x00pci_register_write(rt2x00dev, PHY_CSR4, reg); 179 rt2x00pci_register_write(rt2x00dev, PHY_CSR4, reg);
163 rt2x00_rf_write(rt2x00dev, word, value); 180 rt2x00_rf_write(rt2x00dev, word, value);
181
182 mutex_unlock(&rt2x00dev->csr_mutex);
164} 183}
165 184
166#ifdef CONFIG_RT2X00_LIB_LEDS 185#ifdef CONFIG_RT2X00_LIB_LEDS
@@ -175,14 +194,12 @@ static void rt61pci_mcu_request(struct rt2x00_dev *rt2x00dev,
175{ 194{
176 u32 reg; 195 u32 reg;
177 196
197 mutex_lock(&rt2x00dev->csr_mutex);
198
178 rt2x00pci_register_read(rt2x00dev, H2M_MAILBOX_CSR, &reg); 199 rt2x00pci_register_read(rt2x00dev, H2M_MAILBOX_CSR, &reg);
179 200
180 if (rt2x00_get_field32(reg, H2M_MAILBOX_CSR_OWNER)) { 201 if (rt2x00_get_field32(reg, H2M_MAILBOX_CSR_OWNER))
181 ERROR(rt2x00dev, "mcu request error. " 202 goto exit_fail;
182 "Request 0x%02x failed for token 0x%02x.\n",
183 command, token);
184 return;
185 }
186 203
187 rt2x00_set_field32(&reg, H2M_MAILBOX_CSR_OWNER, 1); 204 rt2x00_set_field32(&reg, H2M_MAILBOX_CSR_OWNER, 1);
188 rt2x00_set_field32(&reg, H2M_MAILBOX_CSR_CMD_TOKEN, token); 205 rt2x00_set_field32(&reg, H2M_MAILBOX_CSR_CMD_TOKEN, token);
@@ -194,6 +211,17 @@ static void rt61pci_mcu_request(struct rt2x00_dev *rt2x00dev,
194 rt2x00_set_field32(&reg, HOST_CMD_CSR_HOST_COMMAND, command); 211 rt2x00_set_field32(&reg, HOST_CMD_CSR_HOST_COMMAND, command);
195 rt2x00_set_field32(&reg, HOST_CMD_CSR_INTERRUPT_MCU, 1); 212 rt2x00_set_field32(&reg, HOST_CMD_CSR_INTERRUPT_MCU, 1);
196 rt2x00pci_register_write(rt2x00dev, HOST_CMD_CSR, reg); 213 rt2x00pci_register_write(rt2x00dev, HOST_CMD_CSR, reg);
214
215 mutex_unlock(&rt2x00dev->csr_mutex);
216
217 return;
218
219exit_fail:
220 mutex_unlock(&rt2x00dev->csr_mutex);
221
222 ERROR(rt2x00dev,
223 "mcu request error. Request 0x%02x failed for token 0x%02x.\n",
224 command, token);
197} 225}
198#endif /* CONFIG_RT2X00_LIB_LEDS */ 226#endif /* CONFIG_RT2X00_LIB_LEDS */
199 227
@@ -1261,33 +1289,44 @@ static int rt61pci_load_firmware(struct rt2x00_dev *rt2x00dev, const void *data,
1261/* 1289/*
1262 * Initialization functions. 1290 * Initialization functions.
1263 */ 1291 */
1264static void rt61pci_init_rxentry(struct rt2x00_dev *rt2x00dev, 1292static bool rt61pci_get_entry_state(struct queue_entry *entry)
1265 struct queue_entry *entry)
1266{ 1293{
1267 struct queue_entry_priv_pci *entry_priv = entry->priv_data; 1294 struct queue_entry_priv_pci *entry_priv = entry->priv_data;
1268 struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
1269 u32 word; 1295 u32 word;
1270 1296
1271 rt2x00_desc_read(entry_priv->desc, 5, &word); 1297 if (entry->queue->qid == QID_RX) {
1272 rt2x00_set_field32(&word, RXD_W5_BUFFER_PHYSICAL_ADDRESS, 1298 rt2x00_desc_read(entry_priv->desc, 0, &word);
1273 skbdesc->skb_dma);
1274 rt2x00_desc_write(entry_priv->desc, 5, word);
1275 1299
1276 rt2x00_desc_read(entry_priv->desc, 0, &word); 1300 return rt2x00_get_field32(word, RXD_W0_OWNER_NIC);
1277 rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1); 1301 } else {
1278 rt2x00_desc_write(entry_priv->desc, 0, word); 1302 rt2x00_desc_read(entry_priv->desc, 0, &word);
1303
1304 return (rt2x00_get_field32(word, TXD_W0_OWNER_NIC) ||
1305 rt2x00_get_field32(word, TXD_W0_VALID));
1306 }
1279} 1307}
1280 1308
1281static void rt61pci_init_txentry(struct rt2x00_dev *rt2x00dev, 1309static void rt61pci_clear_entry(struct queue_entry *entry)
1282 struct queue_entry *entry)
1283{ 1310{
1284 struct queue_entry_priv_pci *entry_priv = entry->priv_data; 1311 struct queue_entry_priv_pci *entry_priv = entry->priv_data;
1312 struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
1285 u32 word; 1313 u32 word;
1286 1314
1287 rt2x00_desc_read(entry_priv->desc, 0, &word); 1315 if (entry->queue->qid == QID_RX) {
1288 rt2x00_set_field32(&word, TXD_W0_VALID, 0); 1316 rt2x00_desc_read(entry_priv->desc, 5, &word);
1289 rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0); 1317 rt2x00_set_field32(&word, RXD_W5_BUFFER_PHYSICAL_ADDRESS,
1290 rt2x00_desc_write(entry_priv->desc, 0, word); 1318 skbdesc->skb_dma);
1319 rt2x00_desc_write(entry_priv->desc, 5, word);
1320
1321 rt2x00_desc_read(entry_priv->desc, 0, &word);
1322 rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1);
1323 rt2x00_desc_write(entry_priv->desc, 0, word);
1324 } else {
1325 rt2x00_desc_read(entry_priv->desc, 0, &word);
1326 rt2x00_set_field32(&word, TXD_W0_VALID, 0);
1327 rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0);
1328 rt2x00_desc_write(entry_priv->desc, 0, word);
1329 }
1291} 1330}
1292 1331
1293static int rt61pci_init_queues(struct rt2x00_dev *rt2x00dev) 1332static int rt61pci_init_queues(struct rt2x00_dev *rt2x00dev)
@@ -2722,8 +2761,8 @@ static const struct rt2x00lib_ops rt61pci_rt2x00_ops = {
2722 .load_firmware = rt61pci_load_firmware, 2761 .load_firmware = rt61pci_load_firmware,
2723 .initialize = rt2x00pci_initialize, 2762 .initialize = rt2x00pci_initialize,
2724 .uninitialize = rt2x00pci_uninitialize, 2763 .uninitialize = rt2x00pci_uninitialize,
2725 .init_rxentry = rt61pci_init_rxentry, 2764 .get_entry_state = rt61pci_get_entry_state,
2726 .init_txentry = rt61pci_init_txentry, 2765 .clear_entry = rt61pci_clear_entry,
2727 .set_device_state = rt61pci_set_device_state, 2766 .set_device_state = rt61pci_set_device_state,
2728 .rfkill_poll = rt61pci_rfkill_poll, 2767 .rfkill_poll = rt61pci_rfkill_poll,
2729 .link_stats = rt61pci_link_stats, 2768 .link_stats = rt61pci_link_stats,
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index 767e3c98184c..d1a63e0017da 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -55,7 +55,7 @@ MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
55 * between each attampt. When the busy bit is still set at that time, 55 * between each attampt. When the busy bit is still set at that time,
56 * the access attempt is considered to have failed, 56 * the access attempt is considered to have failed,
57 * and we will print an error. 57 * and we will print an error.
58 * The _lock versions must be used if you already hold the usb_cache_mutex 58 * The _lock versions must be used if you already hold the csr_mutex
59 */ 59 */
60static inline void rt73usb_register_read(struct rt2x00_dev *rt2x00dev, 60static inline void rt73usb_register_read(struct rt2x00_dev *rt2x00dev,
61 const unsigned int offset, u32 *value) 61 const unsigned int offset, u32 *value)
@@ -135,7 +135,7 @@ static void rt73usb_bbp_write(struct rt2x00_dev *rt2x00dev,
135{ 135{
136 u32 reg; 136 u32 reg;
137 137
138 mutex_lock(&rt2x00dev->usb_cache_mutex); 138 mutex_lock(&rt2x00dev->csr_mutex);
139 139
140 /* 140 /*
141 * Wait until the BBP becomes ready. 141 * Wait until the BBP becomes ready.
@@ -154,12 +154,12 @@ static void rt73usb_bbp_write(struct rt2x00_dev *rt2x00dev,
154 rt2x00_set_field32(&reg, PHY_CSR3_READ_CONTROL, 0); 154 rt2x00_set_field32(&reg, PHY_CSR3_READ_CONTROL, 0);
155 155
156 rt73usb_register_write_lock(rt2x00dev, PHY_CSR3, reg); 156 rt73usb_register_write_lock(rt2x00dev, PHY_CSR3, reg);
157 mutex_unlock(&rt2x00dev->usb_cache_mutex); 157 mutex_unlock(&rt2x00dev->csr_mutex);
158 158
159 return; 159 return;
160 160
161exit_fail: 161exit_fail:
162 mutex_unlock(&rt2x00dev->usb_cache_mutex); 162 mutex_unlock(&rt2x00dev->csr_mutex);
163 163
164 ERROR(rt2x00dev, "PHY_CSR3 register busy. Write failed.\n"); 164 ERROR(rt2x00dev, "PHY_CSR3 register busy. Write failed.\n");
165} 165}
@@ -169,7 +169,7 @@ static void rt73usb_bbp_read(struct rt2x00_dev *rt2x00dev,
169{ 169{
170 u32 reg; 170 u32 reg;
171 171
172 mutex_lock(&rt2x00dev->usb_cache_mutex); 172 mutex_lock(&rt2x00dev->csr_mutex);
173 173
174 /* 174 /*
175 * Wait until the BBP becomes ready. 175 * Wait until the BBP becomes ready.
@@ -196,12 +196,12 @@ static void rt73usb_bbp_read(struct rt2x00_dev *rt2x00dev,
196 goto exit_fail; 196 goto exit_fail;
197 197
198 *value = rt2x00_get_field32(reg, PHY_CSR3_VALUE); 198 *value = rt2x00_get_field32(reg, PHY_CSR3_VALUE);
199 mutex_unlock(&rt2x00dev->usb_cache_mutex); 199 mutex_unlock(&rt2x00dev->csr_mutex);
200 200
201 return; 201 return;
202 202
203exit_fail: 203exit_fail:
204 mutex_unlock(&rt2x00dev->usb_cache_mutex); 204 mutex_unlock(&rt2x00dev->csr_mutex);
205 205
206 ERROR(rt2x00dev, "PHY_CSR3 register busy. Read failed.\n"); 206 ERROR(rt2x00dev, "PHY_CSR3 register busy. Read failed.\n");
207 *value = 0xff; 207 *value = 0xff;
@@ -216,7 +216,7 @@ static void rt73usb_rf_write(struct rt2x00_dev *rt2x00dev,
216 if (!word) 216 if (!word)
217 return; 217 return;
218 218
219 mutex_lock(&rt2x00dev->usb_cache_mutex); 219 mutex_lock(&rt2x00dev->csr_mutex);
220 220
221 for (i = 0; i < REGISTER_BUSY_COUNT; i++) { 221 for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
222 rt73usb_register_read_lock(rt2x00dev, PHY_CSR4, &reg); 222 rt73usb_register_read_lock(rt2x00dev, PHY_CSR4, &reg);
@@ -225,7 +225,7 @@ static void rt73usb_rf_write(struct rt2x00_dev *rt2x00dev,
225 udelay(REGISTER_BUSY_DELAY); 225 udelay(REGISTER_BUSY_DELAY);
226 } 226 }
227 227
228 mutex_unlock(&rt2x00dev->usb_cache_mutex); 228 mutex_unlock(&rt2x00dev->csr_mutex);
229 ERROR(rt2x00dev, "PHY_CSR4 register busy. Write failed.\n"); 229 ERROR(rt2x00dev, "PHY_CSR4 register busy. Write failed.\n");
230 return; 230 return;
231 231
@@ -245,7 +245,8 @@ rf_write:
245 245
246 rt73usb_register_write_lock(rt2x00dev, PHY_CSR4, reg); 246 rt73usb_register_write_lock(rt2x00dev, PHY_CSR4, reg);
247 rt2x00_rf_write(rt2x00dev, word, value); 247 rt2x00_rf_write(rt2x00dev, word, value);
248 mutex_unlock(&rt2x00dev->usb_cache_mutex); 248
249 mutex_unlock(&rt2x00dev->csr_mutex);
249} 250}
250 251
251#ifdef CONFIG_RT2X00_LIB_DEBUGFS 252#ifdef CONFIG_RT2X00_LIB_DEBUGFS
@@ -2313,8 +2314,7 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = {
2313 .load_firmware = rt73usb_load_firmware, 2314 .load_firmware = rt73usb_load_firmware,
2314 .initialize = rt2x00usb_initialize, 2315 .initialize = rt2x00usb_initialize,
2315 .uninitialize = rt2x00usb_uninitialize, 2316 .uninitialize = rt2x00usb_uninitialize,
2316 .init_rxentry = rt2x00usb_init_rxentry, 2317 .clear_entry = rt2x00usb_clear_entry,
2317 .init_txentry = rt2x00usb_init_txentry,
2318 .set_device_state = rt73usb_set_device_state, 2318 .set_device_state = rt73usb_set_device_state,
2319 .link_stats = rt73usb_link_stats, 2319 .link_stats = rt73usb_link_stats,
2320 .reset_tuner = rt73usb_reset_tuner, 2320 .reset_tuner = rt73usb_reset_tuner,
diff --git a/drivers/net/wireless/rtl818x/Makefile b/drivers/net/wireless/rtl818x/Makefile
new file mode 100644
index 000000000000..c113b3e69046
--- /dev/null
+++ b/drivers/net/wireless/rtl818x/Makefile
@@ -0,0 +1,7 @@
1rtl8180-objs := rtl8180_dev.o rtl8180_rtl8225.o rtl8180_sa2400.o rtl8180_max2820.o rtl8180_grf5101.o
2rtl8187-objs := rtl8187_dev.o rtl8187_rtl8225.o
3
4obj-$(CONFIG_RTL8180) += rtl8180.o
5obj-$(CONFIG_RTL8187) += rtl8187.o
6
7
diff --git a/drivers/net/wireless/rtl8180.h b/drivers/net/wireless/rtl818x/rtl8180.h
index 8721282a8185..8721282a8185 100644
--- a/drivers/net/wireless/rtl8180.h
+++ b/drivers/net/wireless/rtl818x/rtl8180.h
diff --git a/drivers/net/wireless/rtl8180_dev.c b/drivers/net/wireless/rtl818x/rtl8180_dev.c
index 6c226c024dd9..5f887fb137a9 100644
--- a/drivers/net/wireless/rtl8180_dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8180_dev.c
@@ -720,6 +720,17 @@ static int rtl8180_config_interface(struct ieee80211_hw *dev,
720 return 0; 720 return 0;
721} 721}
722 722
723static void rtl8180_bss_info_changed(struct ieee80211_hw *dev,
724 struct ieee80211_vif *vif,
725 struct ieee80211_bss_conf *info,
726 u32 changed)
727{
728 struct rtl8180_priv *priv = dev->priv;
729
730 if (changed & BSS_CHANGED_ERP_SLOT && priv->rf->conf_erp)
731 priv->rf->conf_erp(dev, info);
732}
733
723static void rtl8180_configure_filter(struct ieee80211_hw *dev, 734static void rtl8180_configure_filter(struct ieee80211_hw *dev,
724 unsigned int changed_flags, 735 unsigned int changed_flags,
725 unsigned int *total_flags, 736 unsigned int *total_flags,
@@ -760,6 +771,7 @@ static const struct ieee80211_ops rtl8180_ops = {
760 .remove_interface = rtl8180_remove_interface, 771 .remove_interface = rtl8180_remove_interface,
761 .config = rtl8180_config, 772 .config = rtl8180_config,
762 .config_interface = rtl8180_config_interface, 773 .config_interface = rtl8180_config_interface,
774 .bss_info_changed = rtl8180_bss_info_changed,
763 .configure_filter = rtl8180_configure_filter, 775 .configure_filter = rtl8180_configure_filter,
764}; 776};
765 777
diff --git a/drivers/net/wireless/rtl8180_grf5101.c b/drivers/net/wireless/rtl818x/rtl8180_grf5101.c
index 947ee55f18b2..947ee55f18b2 100644
--- a/drivers/net/wireless/rtl8180_grf5101.c
+++ b/drivers/net/wireless/rtl818x/rtl8180_grf5101.c
diff --git a/drivers/net/wireless/rtl8180_grf5101.h b/drivers/net/wireless/rtl818x/rtl8180_grf5101.h
index 76647111bcff..76647111bcff 100644
--- a/drivers/net/wireless/rtl8180_grf5101.h
+++ b/drivers/net/wireless/rtl818x/rtl8180_grf5101.h
diff --git a/drivers/net/wireless/rtl8180_max2820.c b/drivers/net/wireless/rtl818x/rtl8180_max2820.c
index 6c825fd7f3b6..6c825fd7f3b6 100644
--- a/drivers/net/wireless/rtl8180_max2820.c
+++ b/drivers/net/wireless/rtl818x/rtl8180_max2820.c
diff --git a/drivers/net/wireless/rtl8180_max2820.h b/drivers/net/wireless/rtl818x/rtl8180_max2820.h
index 61cf6d1e7d57..61cf6d1e7d57 100644
--- a/drivers/net/wireless/rtl8180_max2820.h
+++ b/drivers/net/wireless/rtl818x/rtl8180_max2820.h
diff --git a/drivers/net/wireless/rtl8180_rtl8225.c b/drivers/net/wireless/rtl818x/rtl8180_rtl8225.c
index cd22781728a9..4d2be0d9672b 100644
--- a/drivers/net/wireless/rtl8180_rtl8225.c
+++ b/drivers/net/wireless/rtl818x/rtl8180_rtl8225.c
@@ -725,8 +725,14 @@ static void rtl8225_rf_set_channel(struct ieee80211_hw *dev,
725 725
726 rtl8225_write(dev, 0x7, rtl8225_chan[chan - 1]); 726 rtl8225_write(dev, 0x7, rtl8225_chan[chan - 1]);
727 msleep(10); 727 msleep(10);
728}
729
730static void rtl8225_rf_conf_erp(struct ieee80211_hw *dev,
731 struct ieee80211_bss_conf *info)
732{
733 struct rtl8180_priv *priv = dev->priv;
728 734
729 if (conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME) { 735 if (info->use_short_slot) {
730 rtl818x_iowrite8(priv, &priv->map->SLOT, 0x9); 736 rtl818x_iowrite8(priv, &priv->map->SLOT, 0x9);
731 rtl818x_iowrite8(priv, &priv->map->SIFS, 0x22); 737 rtl818x_iowrite8(priv, &priv->map->SIFS, 0x22);
732 rtl818x_iowrite8(priv, &priv->map->DIFS, 0x14); 738 rtl818x_iowrite8(priv, &priv->map->DIFS, 0x14);
@@ -745,14 +751,16 @@ static const struct rtl818x_rf_ops rtl8225_ops = {
745 .name = "rtl8225", 751 .name = "rtl8225",
746 .init = rtl8225_rf_init, 752 .init = rtl8225_rf_init,
747 .stop = rtl8225_rf_stop, 753 .stop = rtl8225_rf_stop,
748 .set_chan = rtl8225_rf_set_channel 754 .set_chan = rtl8225_rf_set_channel,
755 .conf_erp = rtl8225_rf_conf_erp,
749}; 756};
750 757
751static const struct rtl818x_rf_ops rtl8225z2_ops = { 758static const struct rtl818x_rf_ops rtl8225z2_ops = {
752 .name = "rtl8225z2", 759 .name = "rtl8225z2",
753 .init = rtl8225z2_rf_init, 760 .init = rtl8225z2_rf_init,
754 .stop = rtl8225_rf_stop, 761 .stop = rtl8225_rf_stop,
755 .set_chan = rtl8225_rf_set_channel 762 .set_chan = rtl8225_rf_set_channel,
763 .conf_erp = rtl8225_rf_conf_erp,
756}; 764};
757 765
758const struct rtl818x_rf_ops * rtl8180_detect_rf(struct ieee80211_hw *dev) 766const struct rtl818x_rf_ops * rtl8180_detect_rf(struct ieee80211_hw *dev)
diff --git a/drivers/net/wireless/rtl8180_rtl8225.h b/drivers/net/wireless/rtl818x/rtl8180_rtl8225.h
index 310013a2d726..310013a2d726 100644
--- a/drivers/net/wireless/rtl8180_rtl8225.h
+++ b/drivers/net/wireless/rtl818x/rtl8180_rtl8225.h
diff --git a/drivers/net/wireless/rtl8180_sa2400.c b/drivers/net/wireless/rtl818x/rtl8180_sa2400.c
index cea4e0ccb92d..cea4e0ccb92d 100644
--- a/drivers/net/wireless/rtl8180_sa2400.c
+++ b/drivers/net/wireless/rtl818x/rtl8180_sa2400.c
diff --git a/drivers/net/wireless/rtl8180_sa2400.h b/drivers/net/wireless/rtl818x/rtl8180_sa2400.h
index a4aaa0d413f1..a4aaa0d413f1 100644
--- a/drivers/net/wireless/rtl8180_sa2400.h
+++ b/drivers/net/wireless/rtl818x/rtl8180_sa2400.h
diff --git a/drivers/net/wireless/rtl8187.h b/drivers/net/wireless/rtl818x/rtl8187.h
index 33725d0978b3..33725d0978b3 100644
--- a/drivers/net/wireless/rtl8187.h
+++ b/drivers/net/wireless/rtl818x/rtl8187.h
diff --git a/drivers/net/wireless/rtl8187_dev.c b/drivers/net/wireless/rtl818x/rtl8187_dev.c
index e1399d0b55d3..4a9f76f46f77 100644
--- a/drivers/net/wireless/rtl8187_dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8187_dev.c
@@ -7,6 +7,11 @@
7 * Based on the r8187 driver, which is: 7 * Based on the r8187 driver, which is:
8 * Copyright 2005 Andrea Merello <andreamrl@tiscali.it>, et al. 8 * Copyright 2005 Andrea Merello <andreamrl@tiscali.it>, et al.
9 * 9 *
10 * The driver was extended to the RTL8187B in 2008 by:
11 * Herton Ronaldo Krzesinski <herton@mandriva.com.br>
12 * Hin-Tak Leung <htl10@users.sourceforge.net>
13 * Larry Finger <Larry.Finger@lwfinger.net>
14 *
10 * Magic delays and register offsets below are taken from the original 15 * Magic delays and register offsets below are taken from the original
11 * r8187 driver sources. Thanks to Realtek for their support! 16 * r8187 driver sources. Thanks to Realtek for their support!
12 * 17 *
@@ -27,6 +32,9 @@
27 32
28MODULE_AUTHOR("Michael Wu <flamingice@sourmilk.net>"); 33MODULE_AUTHOR("Michael Wu <flamingice@sourmilk.net>");
29MODULE_AUTHOR("Andrea Merello <andreamrl@tiscali.it>"); 34MODULE_AUTHOR("Andrea Merello <andreamrl@tiscali.it>");
35MODULE_AUTHOR("Herton Ronaldo Krzesinski <herton@mandriva.com.br>");
36MODULE_AUTHOR("Hin-Tak Leung <htl10@users.sourceforge.net>");
37MODULE_AUTHOR("Larry Finger <Larry.Finger@lwfinger.net>");
30MODULE_DESCRIPTION("RTL8187/RTL8187B USB wireless driver"); 38MODULE_DESCRIPTION("RTL8187/RTL8187B USB wireless driver");
31MODULE_LICENSE("GPL"); 39MODULE_LICENSE("GPL");
32 40
diff --git a/drivers/net/wireless/rtl8187_rtl8225.c b/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c
index 69030be62b36..69030be62b36 100644
--- a/drivers/net/wireless/rtl8187_rtl8225.c
+++ b/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c
diff --git a/drivers/net/wireless/rtl8187_rtl8225.h b/drivers/net/wireless/rtl818x/rtl8187_rtl8225.h
index 20c5b6ead0f6..20c5b6ead0f6 100644
--- a/drivers/net/wireless/rtl8187_rtl8225.h
+++ b/drivers/net/wireless/rtl818x/rtl8187_rtl8225.h
diff --git a/drivers/net/wireless/rtl818x.h b/drivers/net/wireless/rtl818x/rtl818x.h
index 3538b15211b1..34a5555cc19c 100644
--- a/drivers/net/wireless/rtl818x.h
+++ b/drivers/net/wireless/rtl818x/rtl818x.h
@@ -191,6 +191,7 @@ struct rtl818x_rf_ops {
191 void (*init)(struct ieee80211_hw *); 191 void (*init)(struct ieee80211_hw *);
192 void (*stop)(struct ieee80211_hw *); 192 void (*stop)(struct ieee80211_hw *);
193 void (*set_chan)(struct ieee80211_hw *, struct ieee80211_conf *); 193 void (*set_chan)(struct ieee80211_hw *, struct ieee80211_conf *);
194 void (*conf_erp)(struct ieee80211_hw *, struct ieee80211_bss_conf *);
194}; 195};
195 196
196/* Tx/Rx flags are common between RTL818X chips */ 197/* Tx/Rx flags are common between RTL818X chips */
diff --git a/drivers/net/wireless/zd1201.c b/drivers/net/wireless/zd1201.c
index 1134e2fb1890..3404807b3e12 100644
--- a/drivers/net/wireless/zd1201.c
+++ b/drivers/net/wireless/zd1201.c
@@ -743,7 +743,7 @@ static int zd1201_join(struct zd1201 *zd, char *essid, int essidlen)
743 743
744static int zd1201_net_open(struct net_device *dev) 744static int zd1201_net_open(struct net_device *dev)
745{ 745{
746 struct zd1201 *zd = (struct zd1201 *)dev->priv; 746 struct zd1201 *zd = netdev_priv(dev);
747 747
748 /* Start MAC with wildcard if no essid set */ 748 /* Start MAC with wildcard if no essid set */
749 if (!zd->mac_enabled) 749 if (!zd->mac_enabled)
@@ -781,7 +781,7 @@ static int zd1201_net_stop(struct net_device *dev)
781 */ 781 */
782static int zd1201_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) 782static int zd1201_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
783{ 783{
784 struct zd1201 *zd = (struct zd1201 *)dev->priv; 784 struct zd1201 *zd = netdev_priv(dev);
785 unsigned char *txbuf = zd->txdata; 785 unsigned char *txbuf = zd->txdata;
786 int txbuflen, pad = 0, err; 786 int txbuflen, pad = 0, err;
787 struct urb *urb = zd->tx_urb; 787 struct urb *urb = zd->tx_urb;
@@ -831,7 +831,7 @@ static int zd1201_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
831 831
832static void zd1201_tx_timeout(struct net_device *dev) 832static void zd1201_tx_timeout(struct net_device *dev)
833{ 833{
834 struct zd1201 *zd = (struct zd1201 *)dev->priv; 834 struct zd1201 *zd = netdev_priv(dev);
835 835
836 if (!zd) 836 if (!zd)
837 return; 837 return;
@@ -846,7 +846,7 @@ static void zd1201_tx_timeout(struct net_device *dev)
846static int zd1201_set_mac_address(struct net_device *dev, void *p) 846static int zd1201_set_mac_address(struct net_device *dev, void *p)
847{ 847{
848 struct sockaddr *addr = p; 848 struct sockaddr *addr = p;
849 struct zd1201 *zd = (struct zd1201 *)dev->priv; 849 struct zd1201 *zd = netdev_priv(dev);
850 int err; 850 int err;
851 851
852 if (!zd) 852 if (!zd)
@@ -863,21 +863,21 @@ static int zd1201_set_mac_address(struct net_device *dev, void *p)
863 863
864static struct net_device_stats *zd1201_get_stats(struct net_device *dev) 864static struct net_device_stats *zd1201_get_stats(struct net_device *dev)
865{ 865{
866 struct zd1201 *zd = (struct zd1201 *)dev->priv; 866 struct zd1201 *zd = netdev_priv(dev);
867 867
868 return &zd->stats; 868 return &zd->stats;
869} 869}
870 870
871static struct iw_statistics *zd1201_get_wireless_stats(struct net_device *dev) 871static struct iw_statistics *zd1201_get_wireless_stats(struct net_device *dev)
872{ 872{
873 struct zd1201 *zd = (struct zd1201 *)dev->priv; 873 struct zd1201 *zd = netdev_priv(dev);
874 874
875 return &zd->iwstats; 875 return &zd->iwstats;
876} 876}
877 877
878static void zd1201_set_multicast(struct net_device *dev) 878static void zd1201_set_multicast(struct net_device *dev)
879{ 879{
880 struct zd1201 *zd = (struct zd1201 *)dev->priv; 880 struct zd1201 *zd = netdev_priv(dev);
881 struct dev_mc_list *mc = dev->mc_list; 881 struct dev_mc_list *mc = dev->mc_list;
882 unsigned char reqbuf[ETH_ALEN*ZD1201_MAXMULTI]; 882 unsigned char reqbuf[ETH_ALEN*ZD1201_MAXMULTI];
883 int i; 883 int i;
@@ -897,7 +897,7 @@ static void zd1201_set_multicast(struct net_device *dev)
897static int zd1201_config_commit(struct net_device *dev, 897static int zd1201_config_commit(struct net_device *dev,
898 struct iw_request_info *info, struct iw_point *data, char *essid) 898 struct iw_request_info *info, struct iw_point *data, char *essid)
899{ 899{
900 struct zd1201 *zd = (struct zd1201 *)dev->priv; 900 struct zd1201 *zd = netdev_priv(dev);
901 901
902 return zd1201_mac_reset(zd); 902 return zd1201_mac_reset(zd);
903} 903}
@@ -912,7 +912,7 @@ static int zd1201_get_name(struct net_device *dev,
912static int zd1201_set_freq(struct net_device *dev, 912static int zd1201_set_freq(struct net_device *dev,
913 struct iw_request_info *info, struct iw_freq *freq, char *extra) 913 struct iw_request_info *info, struct iw_freq *freq, char *extra)
914{ 914{
915 struct zd1201 *zd = (struct zd1201 *)dev->priv; 915 struct zd1201 *zd = netdev_priv(dev);
916 short channel = 0; 916 short channel = 0;
917 int err; 917 int err;
918 918
@@ -937,7 +937,7 @@ static int zd1201_set_freq(struct net_device *dev,
937static int zd1201_get_freq(struct net_device *dev, 937static int zd1201_get_freq(struct net_device *dev,
938 struct iw_request_info *info, struct iw_freq *freq, char *extra) 938 struct iw_request_info *info, struct iw_freq *freq, char *extra)
939{ 939{
940 struct zd1201 *zd = (struct zd1201 *)dev->priv; 940 struct zd1201 *zd = netdev_priv(dev);
941 short channel; 941 short channel;
942 int err; 942 int err;
943 943
@@ -953,7 +953,7 @@ static int zd1201_get_freq(struct net_device *dev,
953static int zd1201_set_mode(struct net_device *dev, 953static int zd1201_set_mode(struct net_device *dev,
954 struct iw_request_info *info, __u32 *mode, char *extra) 954 struct iw_request_info *info, __u32 *mode, char *extra)
955{ 955{
956 struct zd1201 *zd = (struct zd1201 *)dev->priv; 956 struct zd1201 *zd = netdev_priv(dev);
957 short porttype, monitor = 0; 957 short porttype, monitor = 0;
958 unsigned char buffer[IW_ESSID_MAX_SIZE+2]; 958 unsigned char buffer[IW_ESSID_MAX_SIZE+2];
959 int err; 959 int err;
@@ -1015,7 +1015,7 @@ static int zd1201_set_mode(struct net_device *dev,
1015static int zd1201_get_mode(struct net_device *dev, 1015static int zd1201_get_mode(struct net_device *dev,
1016 struct iw_request_info *info, __u32 *mode, char *extra) 1016 struct iw_request_info *info, __u32 *mode, char *extra)
1017{ 1017{
1018 struct zd1201 *zd = (struct zd1201 *)dev->priv; 1018 struct zd1201 *zd = netdev_priv(dev);
1019 short porttype; 1019 short porttype;
1020 int err; 1020 int err;
1021 1021
@@ -1091,7 +1091,7 @@ static int zd1201_get_range(struct net_device *dev,
1091static int zd1201_get_wap(struct net_device *dev, 1091static int zd1201_get_wap(struct net_device *dev,
1092 struct iw_request_info *info, struct sockaddr *ap_addr, char *extra) 1092 struct iw_request_info *info, struct sockaddr *ap_addr, char *extra)
1093{ 1093{
1094 struct zd1201 *zd = (struct zd1201 *)dev->priv; 1094 struct zd1201 *zd = netdev_priv(dev);
1095 unsigned char buffer[6]; 1095 unsigned char buffer[6];
1096 1096
1097 if (!zd1201_getconfig(zd, ZD1201_RID_COMMSQUALITY, buffer, 6)) { 1097 if (!zd1201_getconfig(zd, ZD1201_RID_COMMSQUALITY, buffer, 6)) {
@@ -1119,7 +1119,7 @@ static int zd1201_set_scan(struct net_device *dev,
1119static int zd1201_get_scan(struct net_device *dev, 1119static int zd1201_get_scan(struct net_device *dev,
1120 struct iw_request_info *info, struct iw_point *srq, char *extra) 1120 struct iw_request_info *info, struct iw_point *srq, char *extra)
1121{ 1121{
1122 struct zd1201 *zd = (struct zd1201 *)dev->priv; 1122 struct zd1201 *zd = netdev_priv(dev);
1123 int err, i, j, enabled_save; 1123 int err, i, j, enabled_save;
1124 struct iw_event iwe; 1124 struct iw_event iwe;
1125 char *cev = extra; 1125 char *cev = extra;
@@ -1211,7 +1211,7 @@ static int zd1201_get_scan(struct net_device *dev,
1211static int zd1201_set_essid(struct net_device *dev, 1211static int zd1201_set_essid(struct net_device *dev,
1212 struct iw_request_info *info, struct iw_point *data, char *essid) 1212 struct iw_request_info *info, struct iw_point *data, char *essid)
1213{ 1213{
1214 struct zd1201 *zd = (struct zd1201 *)dev->priv; 1214 struct zd1201 *zd = netdev_priv(dev);
1215 1215
1216 if (data->length > IW_ESSID_MAX_SIZE) 1216 if (data->length > IW_ESSID_MAX_SIZE)
1217 return -EINVAL; 1217 return -EINVAL;
@@ -1226,7 +1226,7 @@ static int zd1201_set_essid(struct net_device *dev,
1226static int zd1201_get_essid(struct net_device *dev, 1226static int zd1201_get_essid(struct net_device *dev,
1227 struct iw_request_info *info, struct iw_point *data, char *essid) 1227 struct iw_request_info *info, struct iw_point *data, char *essid)
1228{ 1228{
1229 struct zd1201 *zd = (struct zd1201 *)dev->priv; 1229 struct zd1201 *zd = netdev_priv(dev);
1230 1230
1231 memcpy(essid, zd->essid, zd->essidlen); 1231 memcpy(essid, zd->essid, zd->essidlen);
1232 data->flags = 1; 1232 data->flags = 1;
@@ -1247,7 +1247,7 @@ static int zd1201_get_nick(struct net_device *dev, struct iw_request_info *info,
1247static int zd1201_set_rate(struct net_device *dev, 1247static int zd1201_set_rate(struct net_device *dev,
1248 struct iw_request_info *info, struct iw_param *rrq, char *extra) 1248 struct iw_request_info *info, struct iw_param *rrq, char *extra)
1249{ 1249{
1250 struct zd1201 *zd = (struct zd1201 *)dev->priv; 1250 struct zd1201 *zd = netdev_priv(dev);
1251 short rate; 1251 short rate;
1252 int err; 1252 int err;
1253 1253
@@ -1280,7 +1280,7 @@ static int zd1201_set_rate(struct net_device *dev,
1280static int zd1201_get_rate(struct net_device *dev, 1280static int zd1201_get_rate(struct net_device *dev,
1281 struct iw_request_info *info, struct iw_param *rrq, char *extra) 1281 struct iw_request_info *info, struct iw_param *rrq, char *extra)
1282{ 1282{
1283 struct zd1201 *zd = (struct zd1201 *)dev->priv; 1283 struct zd1201 *zd = netdev_priv(dev);
1284 short rate; 1284 short rate;
1285 int err; 1285 int err;
1286 1286
@@ -1313,7 +1313,7 @@ static int zd1201_get_rate(struct net_device *dev,
1313static int zd1201_set_rts(struct net_device *dev, struct iw_request_info *info, 1313static int zd1201_set_rts(struct net_device *dev, struct iw_request_info *info,
1314 struct iw_param *rts, char *extra) 1314 struct iw_param *rts, char *extra)
1315{ 1315{
1316 struct zd1201 *zd = (struct zd1201 *)dev->priv; 1316 struct zd1201 *zd = netdev_priv(dev);
1317 int err; 1317 int err;
1318 short val = rts->value; 1318 short val = rts->value;
1319 1319
@@ -1333,7 +1333,7 @@ static int zd1201_set_rts(struct net_device *dev, struct iw_request_info *info,
1333static int zd1201_get_rts(struct net_device *dev, struct iw_request_info *info, 1333static int zd1201_get_rts(struct net_device *dev, struct iw_request_info *info,
1334 struct iw_param *rts, char *extra) 1334 struct iw_param *rts, char *extra)
1335{ 1335{
1336 struct zd1201 *zd = (struct zd1201 *)dev->priv; 1336 struct zd1201 *zd = netdev_priv(dev);
1337 short rtst; 1337 short rtst;
1338 int err; 1338 int err;
1339 1339
@@ -1350,7 +1350,7 @@ static int zd1201_get_rts(struct net_device *dev, struct iw_request_info *info,
1350static int zd1201_set_frag(struct net_device *dev, struct iw_request_info *info, 1350static int zd1201_set_frag(struct net_device *dev, struct iw_request_info *info,
1351 struct iw_param *frag, char *extra) 1351 struct iw_param *frag, char *extra)
1352{ 1352{
1353 struct zd1201 *zd = (struct zd1201 *)dev->priv; 1353 struct zd1201 *zd = netdev_priv(dev);
1354 int err; 1354 int err;
1355 short val = frag->value; 1355 short val = frag->value;
1356 1356
@@ -1371,7 +1371,7 @@ static int zd1201_set_frag(struct net_device *dev, struct iw_request_info *info,
1371static int zd1201_get_frag(struct net_device *dev, struct iw_request_info *info, 1371static int zd1201_get_frag(struct net_device *dev, struct iw_request_info *info,
1372 struct iw_param *frag, char *extra) 1372 struct iw_param *frag, char *extra)
1373{ 1373{
1374 struct zd1201 *zd = (struct zd1201 *)dev->priv; 1374 struct zd1201 *zd = netdev_priv(dev);
1375 short fragt; 1375 short fragt;
1376 int err; 1376 int err;
1377 1377
@@ -1400,7 +1400,7 @@ static int zd1201_get_retry(struct net_device *dev,
1400static int zd1201_set_encode(struct net_device *dev, 1400static int zd1201_set_encode(struct net_device *dev,
1401 struct iw_request_info *info, struct iw_point *erq, char *key) 1401 struct iw_request_info *info, struct iw_point *erq, char *key)
1402{ 1402{
1403 struct zd1201 *zd = (struct zd1201 *)dev->priv; 1403 struct zd1201 *zd = netdev_priv(dev);
1404 short i; 1404 short i;
1405 int err, rid; 1405 int err, rid;
1406 1406
@@ -1457,7 +1457,7 @@ static int zd1201_set_encode(struct net_device *dev,
1457static int zd1201_get_encode(struct net_device *dev, 1457static int zd1201_get_encode(struct net_device *dev,
1458 struct iw_request_info *info, struct iw_point *erq, char *key) 1458 struct iw_request_info *info, struct iw_point *erq, char *key)
1459{ 1459{
1460 struct zd1201 *zd = (struct zd1201 *)dev->priv; 1460 struct zd1201 *zd = netdev_priv(dev);
1461 short i; 1461 short i;
1462 int err; 1462 int err;
1463 1463
@@ -1490,7 +1490,7 @@ static int zd1201_get_encode(struct net_device *dev,
1490static int zd1201_set_power(struct net_device *dev, 1490static int zd1201_set_power(struct net_device *dev,
1491 struct iw_request_info *info, struct iw_param *vwrq, char *extra) 1491 struct iw_request_info *info, struct iw_param *vwrq, char *extra)
1492{ 1492{
1493 struct zd1201 *zd = (struct zd1201 *)dev->priv; 1493 struct zd1201 *zd = netdev_priv(dev);
1494 short enabled, duration, level; 1494 short enabled, duration, level;
1495 int err; 1495 int err;
1496 1496
@@ -1529,7 +1529,7 @@ out:
1529static int zd1201_get_power(struct net_device *dev, 1529static int zd1201_get_power(struct net_device *dev,
1530 struct iw_request_info *info, struct iw_param *vwrq, char *extra) 1530 struct iw_request_info *info, struct iw_param *vwrq, char *extra)
1531{ 1531{
1532 struct zd1201 *zd = (struct zd1201 *)dev->priv; 1532 struct zd1201 *zd = netdev_priv(dev);
1533 short enabled, level, duration; 1533 short enabled, level, duration;
1534 int err; 1534 int err;
1535 1535
@@ -1616,7 +1616,7 @@ static const iw_handler zd1201_iw_handler[] =
1616static int zd1201_set_hostauth(struct net_device *dev, 1616static int zd1201_set_hostauth(struct net_device *dev,
1617 struct iw_request_info *info, struct iw_param *rrq, char *extra) 1617 struct iw_request_info *info, struct iw_param *rrq, char *extra)
1618{ 1618{
1619 struct zd1201 *zd = (struct zd1201 *)dev->priv; 1619 struct zd1201 *zd = netdev_priv(dev);
1620 1620
1621 if (!zd->ap) 1621 if (!zd->ap)
1622 return -EOPNOTSUPP; 1622 return -EOPNOTSUPP;
@@ -1627,7 +1627,7 @@ static int zd1201_set_hostauth(struct net_device *dev,
1627static int zd1201_get_hostauth(struct net_device *dev, 1627static int zd1201_get_hostauth(struct net_device *dev,
1628 struct iw_request_info *info, struct iw_param *rrq, char *extra) 1628 struct iw_request_info *info, struct iw_param *rrq, char *extra)
1629{ 1629{
1630 struct zd1201 *zd = (struct zd1201 *)dev->priv; 1630 struct zd1201 *zd = netdev_priv(dev);
1631 short hostauth; 1631 short hostauth;
1632 int err; 1632 int err;
1633 1633
@@ -1646,7 +1646,7 @@ static int zd1201_get_hostauth(struct net_device *dev,
1646static int zd1201_auth_sta(struct net_device *dev, 1646static int zd1201_auth_sta(struct net_device *dev,
1647 struct iw_request_info *info, struct sockaddr *sta, char *extra) 1647 struct iw_request_info *info, struct sockaddr *sta, char *extra)
1648{ 1648{
1649 struct zd1201 *zd = (struct zd1201 *)dev->priv; 1649 struct zd1201 *zd = netdev_priv(dev);
1650 unsigned char buffer[10]; 1650 unsigned char buffer[10];
1651 1651
1652 if (!zd->ap) 1652 if (!zd->ap)
@@ -1662,7 +1662,7 @@ static int zd1201_auth_sta(struct net_device *dev,
1662static int zd1201_set_maxassoc(struct net_device *dev, 1662static int zd1201_set_maxassoc(struct net_device *dev,
1663 struct iw_request_info *info, struct iw_param *rrq, char *extra) 1663 struct iw_request_info *info, struct iw_param *rrq, char *extra)
1664{ 1664{
1665 struct zd1201 *zd = (struct zd1201 *)dev->priv; 1665 struct zd1201 *zd = netdev_priv(dev);
1666 int err; 1666 int err;
1667 1667
1668 if (!zd->ap) 1668 if (!zd->ap)
@@ -1677,7 +1677,7 @@ static int zd1201_set_maxassoc(struct net_device *dev,
1677static int zd1201_get_maxassoc(struct net_device *dev, 1677static int zd1201_get_maxassoc(struct net_device *dev,
1678 struct iw_request_info *info, struct iw_param *rrq, char *extra) 1678 struct iw_request_info *info, struct iw_param *rrq, char *extra)
1679{ 1679{
1680 struct zd1201 *zd = (struct zd1201 *)dev->priv; 1680 struct zd1201 *zd = netdev_priv(dev);
1681 short maxassoc; 1681 short maxassoc;
1682 int err; 1682 int err;
1683 1683
@@ -1729,6 +1729,7 @@ static int zd1201_probe(struct usb_interface *interface,
1729 const struct usb_device_id *id) 1729 const struct usb_device_id *id)
1730{ 1730{
1731 struct zd1201 *zd; 1731 struct zd1201 *zd;
1732 struct net_device *dev;
1732 struct usb_device *usb; 1733 struct usb_device *usb;
1733 int err; 1734 int err;
1734 short porttype; 1735 short porttype;
@@ -1736,9 +1737,12 @@ static int zd1201_probe(struct usb_interface *interface,
1736 1737
1737 usb = interface_to_usbdev(interface); 1738 usb = interface_to_usbdev(interface);
1738 1739
1739 zd = kzalloc(sizeof(struct zd1201), GFP_KERNEL); 1740 dev = alloc_etherdev(sizeof(*zd));
1740 if (!zd) 1741 if (!dev)
1741 return -ENOMEM; 1742 return -ENOMEM;
1743 zd = netdev_priv(dev);
1744 zd->dev = dev;
1745
1742 zd->ap = ap; 1746 zd->ap = ap;
1743 zd->usb = usb; 1747 zd->usb = usb;
1744 zd->removed = 0; 1748 zd->removed = 0;
@@ -1773,34 +1777,29 @@ static int zd1201_probe(struct usb_interface *interface,
1773 if (err) 1777 if (err)
1774 goto err_start; 1778 goto err_start;
1775 1779
1776 zd->dev = alloc_etherdev(0); 1780 dev->open = zd1201_net_open;
1777 if (!zd->dev) 1781 dev->stop = zd1201_net_stop;
1778 goto err_start; 1782 dev->get_stats = zd1201_get_stats;
1779 1783 dev->wireless_handlers =
1780 zd->dev->priv = zd;
1781 zd->dev->open = zd1201_net_open;
1782 zd->dev->stop = zd1201_net_stop;
1783 zd->dev->get_stats = zd1201_get_stats;
1784 zd->dev->wireless_handlers =
1785 (struct iw_handler_def *)&zd1201_iw_handlers; 1784 (struct iw_handler_def *)&zd1201_iw_handlers;
1786 zd->dev->hard_start_xmit = zd1201_hard_start_xmit; 1785 dev->hard_start_xmit = zd1201_hard_start_xmit;
1787 zd->dev->watchdog_timeo = ZD1201_TX_TIMEOUT; 1786 dev->watchdog_timeo = ZD1201_TX_TIMEOUT;
1788 zd->dev->tx_timeout = zd1201_tx_timeout; 1787 dev->tx_timeout = zd1201_tx_timeout;
1789 zd->dev->set_multicast_list = zd1201_set_multicast; 1788 dev->set_multicast_list = zd1201_set_multicast;
1790 zd->dev->set_mac_address = zd1201_set_mac_address; 1789 dev->set_mac_address = zd1201_set_mac_address;
1791 strcpy(zd->dev->name, "wlan%d"); 1790 strcpy(dev->name, "wlan%d");
1792 1791
1793 err = zd1201_getconfig(zd, ZD1201_RID_CNFOWNMACADDR, 1792 err = zd1201_getconfig(zd, ZD1201_RID_CNFOWNMACADDR,
1794 zd->dev->dev_addr, zd->dev->addr_len); 1793 dev->dev_addr, dev->addr_len);
1795 if (err) 1794 if (err)
1796 goto err_net; 1795 goto err_start;
1797 1796
1798 /* Set wildcard essid to match zd->essid */ 1797 /* Set wildcard essid to match zd->essid */
1799 *(__le16 *)buf = cpu_to_le16(0); 1798 *(__le16 *)buf = cpu_to_le16(0);
1800 err = zd1201_setconfig(zd, ZD1201_RID_CNFDESIREDSSID, buf, 1799 err = zd1201_setconfig(zd, ZD1201_RID_CNFDESIREDSSID, buf,
1801 IW_ESSID_MAX_SIZE+2, 1); 1800 IW_ESSID_MAX_SIZE+2, 1);
1802 if (err) 1801 if (err)
1803 goto err_net; 1802 goto err_start;
1804 1803
1805 if (zd->ap) 1804 if (zd->ap)
1806 porttype = ZD1201_PORTTYPE_AP; 1805 porttype = ZD1201_PORTTYPE_AP;
@@ -1808,30 +1807,28 @@ static int zd1201_probe(struct usb_interface *interface,
1808 porttype = ZD1201_PORTTYPE_BSS; 1807 porttype = ZD1201_PORTTYPE_BSS;
1809 err = zd1201_setconfig16(zd, ZD1201_RID_CNFPORTTYPE, porttype); 1808 err = zd1201_setconfig16(zd, ZD1201_RID_CNFPORTTYPE, porttype);
1810 if (err) 1809 if (err)
1811 goto err_net; 1810 goto err_start;
1812 1811
1813 SET_NETDEV_DEV(zd->dev, &usb->dev); 1812 SET_NETDEV_DEV(dev, &usb->dev);
1814 1813
1815 err = register_netdev(zd->dev); 1814 err = register_netdev(dev);
1816 if (err) 1815 if (err)
1817 goto err_net; 1816 goto err_start;
1818 dev_info(&usb->dev, "%s: ZD1201 USB Wireless interface\n", 1817 dev_info(&usb->dev, "%s: ZD1201 USB Wireless interface\n",
1819 zd->dev->name); 1818 dev->name);
1820 1819
1821 usb_set_intfdata(interface, zd); 1820 usb_set_intfdata(interface, zd);
1822 zd1201_enable(zd); /* zd1201 likes to startup enabled, */ 1821 zd1201_enable(zd); /* zd1201 likes to startup enabled, */
1823 zd1201_disable(zd); /* interfering with all the wifis in range */ 1822 zd1201_disable(zd); /* interfering with all the wifis in range */
1824 return 0; 1823 return 0;
1825 1824
1826err_net:
1827 free_netdev(zd->dev);
1828err_start: 1825err_start:
1829 /* Leave the device in reset state */ 1826 /* Leave the device in reset state */
1830 zd1201_docmd(zd, ZD1201_CMDCODE_INIT, 0, 0, 0); 1827 zd1201_docmd(zd, ZD1201_CMDCODE_INIT, 0, 0, 0);
1831err_zd: 1828err_zd:
1832 usb_free_urb(zd->tx_urb); 1829 usb_free_urb(zd->tx_urb);
1833 usb_free_urb(zd->rx_urb); 1830 usb_free_urb(zd->rx_urb);
1834 kfree(zd); 1831 free_netdev(dev);
1835 return err; 1832 return err;
1836} 1833}
1837 1834