aboutsummaryrefslogtreecommitdiffstats
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
parente243455d345ef62751723671bc2605a2f6032ceb (diff)
parenta1eb5fe319beb9e181aa52c8adf75ad9aab56a89 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
-rw-r--r--Documentation/networking/mac80211_hwsim/README9
-rw-r--r--MAINTAINERS24
-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.c (renamed from net/ieee80211/ieee80211_geo.c)0
-rw-r--r--drivers/net/wireless/ipw2x00/libipw_module.c (renamed from net/ieee80211/ieee80211_module.c)25
-rw-r--r--drivers/net/wireless/ipw2x00/libipw_rx.c (renamed from net/ieee80211/ieee80211_rx.c)8
-rw-r--r--drivers/net/wireless/ipw2x00/libipw_tx.c (renamed from net/ieee80211/ieee80211_tx.c)7
-rw-r--r--drivers/net/wireless/ipw2x00/libipw_wx.c (renamed from net/ieee80211/ieee80211_wx.c)68
-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
-rw-r--r--drivers/ssb/main.c11
-rw-r--r--drivers/ssb/pcihost_wrapper.c2
-rw-r--r--include/net/ieee80211.h10
-rw-r--r--include/net/ieee80211_crypt.h108
-rw-r--r--include/net/lib80211.h113
-rw-r--r--include/net/mac80211.h5
-rw-r--r--net/Kconfig1
-rw-r--r--net/Makefile1
-rw-r--r--net/ieee80211/Kconfig50
-rw-r--r--net/ieee80211/Makefile12
-rw-r--r--net/ieee80211/ieee80211_crypt.c206
-rw-r--r--net/mac80211/iface.c17
-rw-r--r--net/mac80211/mlme.c1
-rw-r--r--net/mac80211/rc80211_pid_algo.c6
-rw-r--r--net/mac80211/sta_info.h3
-rw-r--r--net/wireless/Kconfig9
-rw-r--r--net/wireless/Makefile3
-rw-r--r--net/wireless/lib80211.c229
-rw-r--r--net/wireless/lib80211_crypt_ccmp.c (renamed from net/ieee80211/ieee80211_crypt_ccmp.c)118
-rw-r--r--net/wireless/lib80211_crypt_tkip.c (renamed from net/ieee80211/ieee80211_crypt_tkip.c)154
-rw-r--r--net/wireless/lib80211_crypt_wep.c (renamed from net/ieee80211/ieee80211_crypt_wep.c)79
-rw-r--r--net/wireless/sysfs.c25
119 files changed, 2193 insertions, 2071 deletions
diff --git a/Documentation/networking/mac80211_hwsim/README b/Documentation/networking/mac80211_hwsim/README
index 2ff8ccb8dc37..24ac91d56698 100644
--- a/Documentation/networking/mac80211_hwsim/README
+++ b/Documentation/networking/mac80211_hwsim/README
@@ -50,10 +50,6 @@ associates with the AP. hostapd and wpa_supplicant are used to take
50care of WPA2-PSK authentication. In addition, hostapd is also 50care of WPA2-PSK authentication. In addition, hostapd is also
51processing access point side of association. 51processing access point side of association.
52 52
53Please note that the current Linux kernel does not enable AP mode, so a
54simple patch is needed to enable AP mode selection:
55http://johannes.sipsolutions.net/patches/kernel/all/LATEST/006-allow-ap-vlan-modes.patch
56
57 53
58# Build mac80211_hwsim as part of kernel configuration 54# Build mac80211_hwsim as part of kernel configuration
59 55
@@ -65,3 +61,8 @@ hostapd hostapd.conf
65 61
66# Run wpa_supplicant (station) for wlan1 62# Run wpa_supplicant (station) for wlan1
67wpa_supplicant -Dwext -iwlan1 -c wpa_supplicant.conf 63wpa_supplicant -Dwext -iwlan1 -c wpa_supplicant.conf
64
65
66More test cases are available in hostap.git:
67git://w1.fi/srv/git/hostap.git and mac80211_hwsim/tests subdirectory
68(http://w1.fi/gitweb/gitweb.cgi?p=hostap.git;a=tree;f=mac80211_hwsim/tests)
diff --git a/MAINTAINERS b/MAINTAINERS
index ecfcc24113c5..7b98da9e264e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3608,15 +3608,25 @@ L: linux-hams@vger.kernel.org
3608W: http://www.linux-ax25.org/ 3608W: http://www.linux-ax25.org/
3609S: Maintained 3609S: Maintained
3610 3610
3611RTL818X WIRELESS DRIVER 3611RTL8180 WIRELESS DRIVER
3612P: Michael Wu 3612P: John W. Linville
3613M: flamingice@sourmilk.net 3613M: linville@tuxdriver.com
3614P: Andrea Merello
3615M: andreamrl@tiscali.it
3616L: linux-wireless@vger.kernel.org 3614L: linux-wireless@vger.kernel.org
3617W: http://linuxwireless.org/ 3615W: http://linuxwireless.org/
3618T: git kernel.org:/pub/scm/linux/kernel/git/mwu/mac80211-drivers.git 3616T: git kernel.org:/pub/scm/linux/kernel/git/linville/wireless-testing.git
3619S: Maintained 3617S: Maintained
3618
3619RTL8187 WIRELESS DRIVER
3620P: Herton Ronaldo Krzesinski
3621M: herton@mandriva.com.br
3622P: Hin-Tak Leung
3623M htl10@users.sourceforge.net
3624P: Larry Finger
3625M: Larry.Finger@lwfinger.net
3626L: linux-wireless@vger.kernel.org
3627W: http://linuxwireless.org/
3628T: git kernel.org:/pub/scm/linux/kernel/git/linville/wireless-testing.git
3629S: Maintained
3620 3630
3621S3 SAVAGE FRAMEBUFFER DRIVER 3631S3 SAVAGE FRAMEBUFFER DRIVER
3622P: Antonino Daplas 3632P: Antonino Daplas
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/net/ieee80211/ieee80211_geo.c b/drivers/net/wireless/ipw2x00/libipw_geo.c
index 960ad13f5e9f..960ad13f5e9f 100644
--- a/net/ieee80211/ieee80211_geo.c
+++ b/drivers/net/wireless/ipw2x00/libipw_geo.c
diff --git a/net/ieee80211/ieee80211_module.c b/drivers/net/wireless/ipw2x00/libipw_module.c
index d34d4e79b6f7..a2f5616d5b09 100644
--- a/net/ieee80211/ieee80211_module.c
+++ b/drivers/net/wireless/ipw2x00/libipw_module.c
@@ -180,13 +180,10 @@ struct net_device *alloc_ieee80211(int sizeof_priv)
180 ieee->host_open_frag = 1; 180 ieee->host_open_frag = 1;
181 ieee->ieee802_1x = 1; /* Default to supporting 802.1x */ 181 ieee->ieee802_1x = 1; /* Default to supporting 802.1x */
182 182
183 INIT_LIST_HEAD(&ieee->crypt_deinit_list);
184 setup_timer(&ieee->crypt_deinit_timer, ieee80211_crypt_deinit_handler,
185 (unsigned long)ieee);
186 ieee->crypt_quiesced = 0;
187
188 spin_lock_init(&ieee->lock); 183 spin_lock_init(&ieee->lock);
189 184
185 lib80211_crypt_info_init(&ieee->crypt_info, dev->name, &ieee->lock);
186
190 ieee->wpa_enabled = 0; 187 ieee->wpa_enabled = 0;
191 ieee->drop_unencrypted = 0; 188 ieee->drop_unencrypted = 0;
192 ieee->privacy_invoked = 0; 189 ieee->privacy_invoked = 0;
@@ -203,23 +200,7 @@ void free_ieee80211(struct net_device *dev)
203{ 200{
204 struct ieee80211_device *ieee = netdev_priv(dev); 201 struct ieee80211_device *ieee = netdev_priv(dev);
205 202
206 int i; 203 lib80211_crypt_info_free(&ieee->crypt_info);
207
208 ieee80211_crypt_quiescing(ieee);
209 del_timer_sync(&ieee->crypt_deinit_timer);
210 ieee80211_crypt_deinit_entries(ieee, 1);
211
212 for (i = 0; i < WEP_KEYS; i++) {
213 struct ieee80211_crypt_data *crypt = ieee->crypt[i];
214 if (crypt) {
215 if (crypt->ops) {
216 crypt->ops->deinit(crypt->priv);
217 module_put(crypt->ops->owner);
218 }
219 kfree(crypt);
220 ieee->crypt[i] = NULL;
221 }
222 }
223 204
224 ieee80211_networks_free(ieee); 205 ieee80211_networks_free(ieee);
225 free_netdev(dev); 206 free_netdev(dev);
diff --git a/net/ieee80211/ieee80211_rx.c b/drivers/net/wireless/ipw2x00/libipw_rx.c
index 3dd58b594f6a..9c67dfae4320 100644
--- a/net/ieee80211/ieee80211_rx.c
+++ b/drivers/net/wireless/ipw2x00/libipw_rx.c
@@ -268,7 +268,7 @@ static int ieee80211_is_eapol_frame(struct ieee80211_device *ieee,
268/* Called only as a tasklet (software IRQ), by ieee80211_rx */ 268/* Called only as a tasklet (software IRQ), by ieee80211_rx */
269static int 269static int
270ieee80211_rx_frame_decrypt(struct ieee80211_device *ieee, struct sk_buff *skb, 270ieee80211_rx_frame_decrypt(struct ieee80211_device *ieee, struct sk_buff *skb,
271 struct ieee80211_crypt_data *crypt) 271 struct lib80211_crypt_data *crypt)
272{ 272{
273 struct ieee80211_hdr_3addr *hdr; 273 struct ieee80211_hdr_3addr *hdr;
274 int res, hdrlen; 274 int res, hdrlen;
@@ -300,7 +300,7 @@ ieee80211_rx_frame_decrypt(struct ieee80211_device *ieee, struct sk_buff *skb,
300static int 300static int
301ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device *ieee, 301ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device *ieee,
302 struct sk_buff *skb, int keyidx, 302 struct sk_buff *skb, int keyidx,
303 struct ieee80211_crypt_data *crypt) 303 struct lib80211_crypt_data *crypt)
304{ 304{
305 struct ieee80211_hdr_3addr *hdr; 305 struct ieee80211_hdr_3addr *hdr;
306 int res, hdrlen; 306 int res, hdrlen;
@@ -348,7 +348,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
348#endif 348#endif
349 u8 dst[ETH_ALEN]; 349 u8 dst[ETH_ALEN];
350 u8 src[ETH_ALEN]; 350 u8 src[ETH_ALEN];
351 struct ieee80211_crypt_data *crypt = NULL; 351 struct lib80211_crypt_data *crypt = NULL;
352 int keyidx = 0; 352 int keyidx = 0;
353 int can_be_decrypted = 0; 353 int can_be_decrypted = 0;
354 354
@@ -431,7 +431,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
431 * is only allowed 2-bits of storage, no value of keyidx can 431 * is only allowed 2-bits of storage, no value of keyidx can
432 * be provided via above code that would result in keyidx 432 * be provided via above code that would result in keyidx
433 * being out of range */ 433 * being out of range */
434 crypt = ieee->crypt[keyidx]; 434 crypt = ieee->crypt_info.crypt[keyidx];
435 435
436#ifdef NOT_YET 436#ifdef NOT_YET
437 sta = NULL; 437 sta = NULL;
diff --git a/net/ieee80211/ieee80211_tx.c b/drivers/net/wireless/ipw2x00/libipw_tx.c
index d996547f7a62..f78f57e8844a 100644
--- a/net/ieee80211/ieee80211_tx.c
+++ b/drivers/net/wireless/ipw2x00/libipw_tx.c
@@ -152,7 +152,8 @@ static int ieee80211_copy_snap(u8 * data, __be16 h_proto)
152static int ieee80211_encrypt_fragment(struct ieee80211_device *ieee, 152static int ieee80211_encrypt_fragment(struct ieee80211_device *ieee,
153 struct sk_buff *frag, int hdr_len) 153 struct sk_buff *frag, int hdr_len)
154{ 154{
155 struct ieee80211_crypt_data *crypt = ieee->crypt[ieee->tx_keyidx]; 155 struct lib80211_crypt_data *crypt =
156 ieee->crypt_info.crypt[ieee->crypt_info.tx_keyidx];
156 int res; 157 int res;
157 158
158 if (crypt == NULL) 159 if (crypt == NULL)
@@ -270,7 +271,7 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
270 .qos_ctl = 0 271 .qos_ctl = 0
271 }; 272 };
272 u8 dest[ETH_ALEN], src[ETH_ALEN]; 273 u8 dest[ETH_ALEN], src[ETH_ALEN];
273 struct ieee80211_crypt_data *crypt; 274 struct lib80211_crypt_data *crypt;
274 int priority = skb->priority; 275 int priority = skb->priority;
275 int snapped = 0; 276 int snapped = 0;
276 277
@@ -294,7 +295,7 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
294 295
295 ether_type = ((struct ethhdr *)skb->data)->h_proto; 296 ether_type = ((struct ethhdr *)skb->data)->h_proto;
296 297
297 crypt = ieee->crypt[ieee->tx_keyidx]; 298 crypt = ieee->crypt_info.crypt[ieee->crypt_info.tx_keyidx];
298 299
299 encrypt = !(ether_type == htons(ETH_P_PAE) && ieee->ieee802_1x) && 300 encrypt = !(ether_type == htons(ETH_P_PAE) && ieee->ieee802_1x) &&
300 ieee->sec.encrypt; 301 ieee->sec.encrypt;
diff --git a/net/ieee80211/ieee80211_wx.c b/drivers/net/wireless/ipw2x00/libipw_wx.c
index 7cc4e5ee3660..31ea3abfc327 100644
--- a/net/ieee80211/ieee80211_wx.c
+++ b/drivers/net/wireless/ipw2x00/libipw_wx.c
@@ -307,7 +307,7 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
307 .flags = 0 307 .flags = 0
308 }; 308 };
309 int i, key, key_provided, len; 309 int i, key, key_provided, len;
310 struct ieee80211_crypt_data **crypt; 310 struct lib80211_crypt_data **crypt;
311 int host_crypto = ieee->host_encrypt || ieee->host_decrypt || ieee->host_build_iv; 311 int host_crypto = ieee->host_encrypt || ieee->host_decrypt || ieee->host_build_iv;
312 DECLARE_SSID_BUF(ssid); 312 DECLARE_SSID_BUF(ssid);
313 313
@@ -321,30 +321,30 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
321 key_provided = 1; 321 key_provided = 1;
322 } else { 322 } else {
323 key_provided = 0; 323 key_provided = 0;
324 key = ieee->tx_keyidx; 324 key = ieee->crypt_info.tx_keyidx;
325 } 325 }
326 326
327 IEEE80211_DEBUG_WX("Key: %d [%s]\n", key, key_provided ? 327 IEEE80211_DEBUG_WX("Key: %d [%s]\n", key, key_provided ?
328 "provided" : "default"); 328 "provided" : "default");
329 329
330 crypt = &ieee->crypt[key]; 330 crypt = &ieee->crypt_info.crypt[key];
331 331
332 if (erq->flags & IW_ENCODE_DISABLED) { 332 if (erq->flags & IW_ENCODE_DISABLED) {
333 if (key_provided && *crypt) { 333 if (key_provided && *crypt) {
334 IEEE80211_DEBUG_WX("Disabling encryption on key %d.\n", 334 IEEE80211_DEBUG_WX("Disabling encryption on key %d.\n",
335 key); 335 key);
336 ieee80211_crypt_delayed_deinit(ieee, crypt); 336 lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt);
337 } else 337 } else
338 IEEE80211_DEBUG_WX("Disabling encryption.\n"); 338 IEEE80211_DEBUG_WX("Disabling encryption.\n");
339 339
340 /* Check all the keys to see if any are still configured, 340 /* Check all the keys to see if any are still configured,
341 * and if no key index was provided, de-init them all */ 341 * and if no key index was provided, de-init them all */
342 for (i = 0; i < WEP_KEYS; i++) { 342 for (i = 0; i < WEP_KEYS; i++) {
343 if (ieee->crypt[i] != NULL) { 343 if (ieee->crypt_info.crypt[i] != NULL) {
344 if (key_provided) 344 if (key_provided)
345 break; 345 break;
346 ieee80211_crypt_delayed_deinit(ieee, 346 lib80211_crypt_delayed_deinit(&ieee->crypt_info,
347 &ieee->crypt[i]); 347 &ieee->crypt_info.crypt[i]);
348 } 348 }
349 } 349 }
350 350
@@ -366,21 +366,21 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
366 strcmp((*crypt)->ops->name, "WEP") != 0) { 366 strcmp((*crypt)->ops->name, "WEP") != 0) {
367 /* changing to use WEP; deinit previously used algorithm 367 /* changing to use WEP; deinit previously used algorithm
368 * on this key */ 368 * on this key */
369 ieee80211_crypt_delayed_deinit(ieee, crypt); 369 lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt);
370 } 370 }
371 371
372 if (*crypt == NULL && host_crypto) { 372 if (*crypt == NULL && host_crypto) {
373 struct ieee80211_crypt_data *new_crypt; 373 struct lib80211_crypt_data *new_crypt;
374 374
375 /* take WEP into use */ 375 /* take WEP into use */
376 new_crypt = kzalloc(sizeof(struct ieee80211_crypt_data), 376 new_crypt = kzalloc(sizeof(struct lib80211_crypt_data),
377 GFP_KERNEL); 377 GFP_KERNEL);
378 if (new_crypt == NULL) 378 if (new_crypt == NULL)
379 return -ENOMEM; 379 return -ENOMEM;
380 new_crypt->ops = ieee80211_get_crypto_ops("WEP"); 380 new_crypt->ops = lib80211_get_crypto_ops("WEP");
381 if (!new_crypt->ops) { 381 if (!new_crypt->ops) {
382 request_module("ieee80211_crypt_wep"); 382 request_module("lib80211_crypt_wep");
383 new_crypt->ops = ieee80211_get_crypto_ops("WEP"); 383 new_crypt->ops = lib80211_get_crypto_ops("WEP");
384 } 384 }
385 385
386 if (new_crypt->ops && try_module_get(new_crypt->ops->owner)) 386 if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
@@ -391,7 +391,7 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
391 new_crypt = NULL; 391 new_crypt = NULL;
392 392
393 printk(KERN_WARNING "%s: could not initialize WEP: " 393 printk(KERN_WARNING "%s: could not initialize WEP: "
394 "load module ieee80211_crypt_wep\n", dev->name); 394 "load module lib80211_crypt_wep\n", dev->name);
395 return -EOPNOTSUPP; 395 return -EOPNOTSUPP;
396 } 396 }
397 *crypt = new_crypt; 397 *crypt = new_crypt;
@@ -440,7 +440,7 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
440 if (key_provided) { 440 if (key_provided) {
441 IEEE80211_DEBUG_WX("Setting key %d to default Tx " 441 IEEE80211_DEBUG_WX("Setting key %d to default Tx "
442 "key.\n", key); 442 "key.\n", key);
443 ieee->tx_keyidx = key; 443 ieee->crypt_info.tx_keyidx = key;
444 sec.active_key = key; 444 sec.active_key = key;
445 sec.flags |= SEC_ACTIVE_KEY; 445 sec.flags |= SEC_ACTIVE_KEY;
446 } 446 }
@@ -485,7 +485,7 @@ int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
485{ 485{
486 struct iw_point *erq = &(wrqu->encoding); 486 struct iw_point *erq = &(wrqu->encoding);
487 int len, key; 487 int len, key;
488 struct ieee80211_crypt_data *crypt; 488 struct lib80211_crypt_data *crypt;
489 struct ieee80211_security *sec = &ieee->sec; 489 struct ieee80211_security *sec = &ieee->sec;
490 490
491 IEEE80211_DEBUG_WX("GET_ENCODE\n"); 491 IEEE80211_DEBUG_WX("GET_ENCODE\n");
@@ -496,9 +496,9 @@ int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
496 return -EINVAL; 496 return -EINVAL;
497 key--; 497 key--;
498 } else 498 } else
499 key = ieee->tx_keyidx; 499 key = ieee->crypt_info.tx_keyidx;
500 500
501 crypt = ieee->crypt[key]; 501 crypt = ieee->crypt_info.crypt[key];
502 erq->flags = key + 1; 502 erq->flags = key + 1;
503 503
504 if (!sec->enabled) { 504 if (!sec->enabled) {
@@ -531,8 +531,8 @@ int ieee80211_wx_set_encodeext(struct ieee80211_device *ieee,
531 int i, idx, ret = 0; 531 int i, idx, ret = 0;
532 int group_key = 0; 532 int group_key = 0;
533 const char *alg, *module; 533 const char *alg, *module;
534 struct ieee80211_crypto_ops *ops; 534 struct lib80211_crypto_ops *ops;
535 struct ieee80211_crypt_data **crypt; 535 struct lib80211_crypt_data **crypt;
536 536
537 struct ieee80211_security sec = { 537 struct ieee80211_security sec = {
538 .flags = 0, 538 .flags = 0,
@@ -544,17 +544,17 @@ int ieee80211_wx_set_encodeext(struct ieee80211_device *ieee,
544 return -EINVAL; 544 return -EINVAL;
545 idx--; 545 idx--;
546 } else 546 } else
547 idx = ieee->tx_keyidx; 547 idx = ieee->crypt_info.tx_keyidx;
548 548
549 if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) { 549 if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
550 crypt = &ieee->crypt[idx]; 550 crypt = &ieee->crypt_info.crypt[idx];
551 group_key = 1; 551 group_key = 1;
552 } else { 552 } else {
553 /* some Cisco APs use idx>0 for unicast in dynamic WEP */ 553 /* some Cisco APs use idx>0 for unicast in dynamic WEP */
554 if (idx != 0 && ext->alg != IW_ENCODE_ALG_WEP) 554 if (idx != 0 && ext->alg != IW_ENCODE_ALG_WEP)
555 return -EINVAL; 555 return -EINVAL;
556 if (ieee->iw_mode == IW_MODE_INFRA) 556 if (ieee->iw_mode == IW_MODE_INFRA)
557 crypt = &ieee->crypt[idx]; 557 crypt = &ieee->crypt_info.crypt[idx];
558 else 558 else
559 return -EINVAL; 559 return -EINVAL;
560 } 560 }
@@ -563,10 +563,10 @@ int ieee80211_wx_set_encodeext(struct ieee80211_device *ieee,
563 if ((encoding->flags & IW_ENCODE_DISABLED) || 563 if ((encoding->flags & IW_ENCODE_DISABLED) ||
564 ext->alg == IW_ENCODE_ALG_NONE) { 564 ext->alg == IW_ENCODE_ALG_NONE) {
565 if (*crypt) 565 if (*crypt)
566 ieee80211_crypt_delayed_deinit(ieee, crypt); 566 lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt);
567 567
568 for (i = 0; i < WEP_KEYS; i++) 568 for (i = 0; i < WEP_KEYS; i++)
569 if (ieee->crypt[i] != NULL) 569 if (ieee->crypt_info.crypt[i] != NULL)
570 break; 570 break;
571 571
572 if (i == WEP_KEYS) { 572 if (i == WEP_KEYS) {
@@ -589,15 +589,15 @@ int ieee80211_wx_set_encodeext(struct ieee80211_device *ieee,
589 switch (ext->alg) { 589 switch (ext->alg) {
590 case IW_ENCODE_ALG_WEP: 590 case IW_ENCODE_ALG_WEP:
591 alg = "WEP"; 591 alg = "WEP";
592 module = "ieee80211_crypt_wep"; 592 module = "lib80211_crypt_wep";
593 break; 593 break;
594 case IW_ENCODE_ALG_TKIP: 594 case IW_ENCODE_ALG_TKIP:
595 alg = "TKIP"; 595 alg = "TKIP";
596 module = "ieee80211_crypt_tkip"; 596 module = "lib80211_crypt_tkip";
597 break; 597 break;
598 case IW_ENCODE_ALG_CCMP: 598 case IW_ENCODE_ALG_CCMP:
599 alg = "CCMP"; 599 alg = "CCMP";
600 module = "ieee80211_crypt_ccmp"; 600 module = "lib80211_crypt_ccmp";
601 break; 601 break;
602 default: 602 default:
603 IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n", 603 IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
@@ -606,10 +606,10 @@ int ieee80211_wx_set_encodeext(struct ieee80211_device *ieee,
606 goto done; 606 goto done;
607 } 607 }
608 608
609 ops = ieee80211_get_crypto_ops(alg); 609 ops = lib80211_get_crypto_ops(alg);
610 if (ops == NULL) { 610 if (ops == NULL) {
611 request_module(module); 611 request_module(module);
612 ops = ieee80211_get_crypto_ops(alg); 612 ops = lib80211_get_crypto_ops(alg);
613 } 613 }
614 if (ops == NULL) { 614 if (ops == NULL) {
615 IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n", 615 IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
@@ -619,9 +619,9 @@ int ieee80211_wx_set_encodeext(struct ieee80211_device *ieee,
619 } 619 }
620 620
621 if (*crypt == NULL || (*crypt)->ops != ops) { 621 if (*crypt == NULL || (*crypt)->ops != ops) {
622 struct ieee80211_crypt_data *new_crypt; 622 struct lib80211_crypt_data *new_crypt;
623 623
624 ieee80211_crypt_delayed_deinit(ieee, crypt); 624 lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt);
625 625
626 new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL); 626 new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL);
627 if (new_crypt == NULL) { 627 if (new_crypt == NULL) {
@@ -649,7 +649,7 @@ int ieee80211_wx_set_encodeext(struct ieee80211_device *ieee,
649 649
650 skip_host_crypt: 650 skip_host_crypt:
651 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) { 651 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
652 ieee->tx_keyidx = idx; 652 ieee->crypt_info.tx_keyidx = idx;
653 sec.active_key = idx; 653 sec.active_key = idx;
654 sec.flags |= SEC_ACTIVE_KEY; 654 sec.flags |= SEC_ACTIVE_KEY;
655 } 655 }
@@ -715,7 +715,7 @@ int ieee80211_wx_get_encodeext(struct ieee80211_device *ieee,
715 return -EINVAL; 715 return -EINVAL;
716 idx--; 716 idx--;
717 } else 717 } else
718 idx = ieee->tx_keyidx; 718 idx = ieee->crypt_info.tx_keyidx;
719 719
720 if (!(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) && 720 if (!(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) &&
721 ext->alg != IW_ENCODE_ALG_WEP) 721 ext->alg != IW_ENCODE_ALG_WEP)
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
diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c
index 0ffabf5c0b60..65a1ed951a1d 100644
--- a/drivers/ssb/main.c
+++ b/drivers/ssb/main.c
@@ -226,7 +226,7 @@ int ssb_devices_freeze(struct ssb_bus *bus)
226 err = drv->suspend(dev, state); 226 err = drv->suspend(dev, state);
227 if (err) { 227 if (err) {
228 ssb_printk(KERN_ERR PFX "Failed to freeze device %s\n", 228 ssb_printk(KERN_ERR PFX "Failed to freeze device %s\n",
229 dev->dev->bus_id); 229 dev_name(dev->dev));
230 goto err_unwind; 230 goto err_unwind;
231 } 231 }
232 } 232 }
@@ -269,7 +269,7 @@ int ssb_devices_thaw(struct ssb_bus *bus)
269 err = drv->resume(dev); 269 err = drv->resume(dev);
270 if (err) { 270 if (err) {
271 ssb_printk(KERN_ERR PFX "Failed to thaw device %s\n", 271 ssb_printk(KERN_ERR PFX "Failed to thaw device %s\n",
272 dev->dev->bus_id); 272 dev_name(dev->dev));
273 } 273 }
274 } 274 }
275 275
@@ -454,8 +454,7 @@ static int ssb_devices_register(struct ssb_bus *bus)
454 454
455 dev->release = ssb_release_dev; 455 dev->release = ssb_release_dev;
456 dev->bus = &ssb_bustype; 456 dev->bus = &ssb_bustype;
457 snprintf(dev->bus_id, sizeof(dev->bus_id), 457 dev_set_name(dev, "ssb%u:%d", bus->busnumber, dev_idx);
458 "ssb%u:%d", bus->busnumber, dev_idx);
459 458
460 switch (bus->bustype) { 459 switch (bus->bustype) {
461 case SSB_BUSTYPE_PCI: 460 case SSB_BUSTYPE_PCI:
@@ -480,7 +479,7 @@ static int ssb_devices_register(struct ssb_bus *bus)
480 if (err) { 479 if (err) {
481 ssb_printk(KERN_ERR PFX 480 ssb_printk(KERN_ERR PFX
482 "Could not register %s\n", 481 "Could not register %s\n",
483 dev->bus_id); 482 dev_name(dev));
484 /* Set dev to NULL to not unregister 483 /* Set dev to NULL to not unregister
485 * dev on error unwinding. */ 484 * dev on error unwinding. */
486 sdev->dev = NULL; 485 sdev->dev = NULL;
@@ -796,7 +795,7 @@ int ssb_bus_pcibus_register(struct ssb_bus *bus,
796 err = ssb_bus_register(bus, ssb_pci_get_invariants, 0); 795 err = ssb_bus_register(bus, ssb_pci_get_invariants, 0);
797 if (!err) { 796 if (!err) {
798 ssb_printk(KERN_INFO PFX "Sonics Silicon Backplane found on " 797 ssb_printk(KERN_INFO PFX "Sonics Silicon Backplane found on "
799 "PCI device %s\n", host_pci->dev.bus_id); 798 "PCI device %s\n", dev_name(&host_pci->dev));
800 } 799 }
801 800
802 return err; 801 return err;
diff --git a/drivers/ssb/pcihost_wrapper.c b/drivers/ssb/pcihost_wrapper.c
index e82db4aaa050..26737a010c6d 100644
--- a/drivers/ssb/pcihost_wrapper.c
+++ b/drivers/ssb/pcihost_wrapper.c
@@ -65,7 +65,7 @@ static int ssb_pcihost_probe(struct pci_dev *dev,
65 err = pci_enable_device(dev); 65 err = pci_enable_device(dev);
66 if (err) 66 if (err)
67 goto err_kfree_ssb; 67 goto err_kfree_ssb;
68 name = dev->dev.bus_id; 68 name = dev_name(&dev->dev);
69 if (dev->driver && dev->driver->name) 69 if (dev->driver && dev->driver->name)
70 name = dev->driver->name; 70 name = dev->driver->name;
71 err = pci_request_regions(dev, name); 71 err = pci_request_regions(dev, name);
diff --git a/include/net/ieee80211.h b/include/net/ieee80211.h
index 738734a4653b..7ab3ed2bbccb 100644
--- a/include/net/ieee80211.h
+++ b/include/net/ieee80211.h
@@ -30,6 +30,8 @@
30#include <linux/wireless.h> 30#include <linux/wireless.h>
31#include <linux/ieee80211.h> 31#include <linux/ieee80211.h>
32 32
33#include <net/lib80211.h>
34
33#define IEEE80211_VERSION "git-1.1.13" 35#define IEEE80211_VERSION "git-1.1.13"
34 36
35#define IEEE80211_DATA_LEN 2304 37#define IEEE80211_DATA_LEN 2304
@@ -355,8 +357,6 @@ struct ieee80211_stats {
355 357
356struct ieee80211_device; 358struct ieee80211_device;
357 359
358#include "ieee80211_crypt.h"
359
360#define SEC_KEY_1 (1<<0) 360#define SEC_KEY_1 (1<<0)
361#define SEC_KEY_2 (1<<1) 361#define SEC_KEY_2 (1<<1)
362#define SEC_KEY_3 (1<<2) 362#define SEC_KEY_3 (1<<2)
@@ -937,11 +937,7 @@ struct ieee80211_device {
937 size_t wpa_ie_len; 937 size_t wpa_ie_len;
938 u8 *wpa_ie; 938 u8 *wpa_ie;
939 939
940 struct list_head crypt_deinit_list; 940 struct lib80211_crypt_info crypt_info;
941 struct ieee80211_crypt_data *crypt[WEP_KEYS];
942 int tx_keyidx; /* default TX key index (crypt[tx_keyidx]) */
943 struct timer_list crypt_deinit_timer;
944 int crypt_quiesced;
945 941
946 int bcrx_sta_key; /* use individual keys to override default keys even 942 int bcrx_sta_key; /* use individual keys to override default keys even
947 * with RX of broad/multicast frames */ 943 * with RX of broad/multicast frames */
diff --git a/include/net/ieee80211_crypt.h b/include/net/ieee80211_crypt.h
deleted file mode 100644
index b3d65e0bedd3..000000000000
--- a/include/net/ieee80211_crypt.h
+++ /dev/null
@@ -1,108 +0,0 @@
1/*
2 * Original code based on Host AP (software wireless LAN access point) driver
3 * for Intersil Prism2/2.5/3.
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 *
9 * Adaption to a generic IEEE 802.11 stack by James Ketrenos
10 * <jketreno@linux.intel.com>
11 *
12 * Copyright (c) 2004, Intel Corporation
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2 as
16 * published by the Free Software Foundation. See README and COPYING for
17 * more details.
18 */
19
20/*
21 * This file defines the interface to the ieee80211 crypto module.
22 */
23#ifndef IEEE80211_CRYPT_H
24#define IEEE80211_CRYPT_H
25
26#include <linux/types.h>
27#include <linux/list.h>
28#include <net/ieee80211.h>
29#include <asm/atomic.h>
30
31enum {
32 IEEE80211_CRYPTO_TKIP_COUNTERMEASURES = (1 << 0),
33};
34
35struct sk_buff;
36struct module;
37
38struct ieee80211_crypto_ops {
39 const char *name;
40 struct list_head list;
41
42 /* init new crypto context (e.g., allocate private data space,
43 * select IV, etc.); returns NULL on failure or pointer to allocated
44 * private data on success */
45 void *(*init) (int keyidx);
46
47 /* deinitialize crypto context and free allocated private data */
48 void (*deinit) (void *priv);
49
50 int (*build_iv) (struct sk_buff * skb, int hdr_len,
51 u8 *key, int keylen, void *priv);
52
53 /* encrypt/decrypt return < 0 on error or >= 0 on success. The return
54 * value from decrypt_mpdu is passed as the keyidx value for
55 * decrypt_msdu. skb must have enough head and tail room for the
56 * encryption; if not, error will be returned; these functions are
57 * called for all MPDUs (i.e., fragments).
58 */
59 int (*encrypt_mpdu) (struct sk_buff * skb, int hdr_len, void *priv);
60 int (*decrypt_mpdu) (struct sk_buff * skb, int hdr_len, void *priv);
61
62 /* These functions are called for full MSDUs, i.e. full frames.
63 * These can be NULL if full MSDU operations are not needed. */
64 int (*encrypt_msdu) (struct sk_buff * skb, int hdr_len, void *priv);
65 int (*decrypt_msdu) (struct sk_buff * skb, int keyidx, int hdr_len,
66 void *priv);
67
68 int (*set_key) (void *key, int len, u8 * seq, void *priv);
69 int (*get_key) (void *key, int len, u8 * seq, void *priv);
70
71 /* procfs handler for printing out key information and possible
72 * statistics */
73 char *(*print_stats) (char *p, void *priv);
74
75 /* Crypto specific flag get/set for configuration settings */
76 unsigned long (*get_flags) (void *priv);
77 unsigned long (*set_flags) (unsigned long flags, void *priv);
78
79 /* maximum number of bytes added by encryption; encrypt buf is
80 * allocated with extra_prefix_len bytes, copy of in_buf, and
81 * extra_postfix_len; encrypt need not use all this space, but
82 * the result must start at the beginning of the buffer and correct
83 * length must be returned */
84 int extra_mpdu_prefix_len, extra_mpdu_postfix_len;
85 int extra_msdu_prefix_len, extra_msdu_postfix_len;
86
87 struct module *owner;
88};
89
90struct ieee80211_crypt_data {
91 struct list_head list; /* delayed deletion list */
92 struct ieee80211_crypto_ops *ops;
93 void *priv;
94 atomic_t refcnt;
95};
96
97struct ieee80211_device;
98
99int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops);
100int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops);
101struct ieee80211_crypto_ops *ieee80211_get_crypto_ops(const char *name);
102void ieee80211_crypt_deinit_entries(struct ieee80211_device *, int);
103void ieee80211_crypt_deinit_handler(unsigned long);
104void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee,
105 struct ieee80211_crypt_data **crypt);
106void ieee80211_crypt_quiescing(struct ieee80211_device *ieee);
107
108#endif
diff --git a/include/net/lib80211.h b/include/net/lib80211.h
index e1558a187ac0..fb4e2784857d 100644
--- a/include/net/lib80211.h
+++ b/include/net/lib80211.h
@@ -3,16 +3,127 @@
3 * 3 *
4 * Copyright (c) 2008, John W. Linville <linville@tuxdriver.com> 4 * Copyright (c) 2008, John W. Linville <linville@tuxdriver.com>
5 * 5 *
6 * Some bits copied from old ieee80211 component, w/ original copyright
7 * notices below:
8 *
9 * Original code based on Host AP (software wireless LAN access point) driver
10 * for Intersil Prism2/2.5/3.
11 *
12 * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
13 * <j@w1.fi>
14 * Copyright (c) 2002-2003, Jouni Malinen <j@w1.fi>
15 *
16 * Adaption to a generic IEEE 802.11 stack by James Ketrenos
17 * <jketreno@linux.intel.com>
18 *
19 * Copyright (c) 2004, Intel Corporation
20 *
6 */ 21 */
7 22
8#ifndef LIB80211_H 23#ifndef LIB80211_H
9#define LIB80211_H 24#define LIB80211_H
10 25
26#include <linux/types.h>
27#include <linux/list.h>
28#include <linux/module.h>
29#include <asm/atomic.h>
30#include <linux/if.h>
31#include <linux/skbuff.h>
11#include <linux/ieee80211.h> 32#include <linux/ieee80211.h>
12 33#include <linux/timer.h>
13/* print_ssid() is intended to be used in debug (and possibly error) 34/* print_ssid() is intended to be used in debug (and possibly error)
14 * messages. It should never be used for passing ssid to user space. */ 35 * messages. It should never be used for passing ssid to user space. */
15const char *print_ssid(char *buf, const char *ssid, u8 ssid_len); 36const char *print_ssid(char *buf, const char *ssid, u8 ssid_len);
16#define DECLARE_SSID_BUF(var) char var[IEEE80211_MAX_SSID_LEN * 4 + 1] __maybe_unused 37#define DECLARE_SSID_BUF(var) char var[IEEE80211_MAX_SSID_LEN * 4 + 1] __maybe_unused
17 38
39#define NUM_WEP_KEYS 4
40
41enum {
42 IEEE80211_CRYPTO_TKIP_COUNTERMEASURES = (1 << 0),
43};
44
45struct lib80211_crypto_ops {
46 const char *name;
47 struct list_head list;
48
49 /* init new crypto context (e.g., allocate private data space,
50 * select IV, etc.); returns NULL on failure or pointer to allocated
51 * private data on success */
52 void *(*init) (int keyidx);
53
54 /* deinitialize crypto context and free allocated private data */
55 void (*deinit) (void *priv);
56
57 int (*build_iv) (struct sk_buff * skb, int hdr_len,
58 u8 *key, int keylen, void *priv);
59
60 /* encrypt/decrypt return < 0 on error or >= 0 on success. The return
61 * value from decrypt_mpdu is passed as the keyidx value for
62 * decrypt_msdu. skb must have enough head and tail room for the
63 * encryption; if not, error will be returned; these functions are
64 * called for all MPDUs (i.e., fragments).
65 */
66 int (*encrypt_mpdu) (struct sk_buff * skb, int hdr_len, void *priv);
67 int (*decrypt_mpdu) (struct sk_buff * skb, int hdr_len, void *priv);
68
69 /* These functions are called for full MSDUs, i.e. full frames.
70 * These can be NULL if full MSDU operations are not needed. */
71 int (*encrypt_msdu) (struct sk_buff * skb, int hdr_len, void *priv);
72 int (*decrypt_msdu) (struct sk_buff * skb, int keyidx, int hdr_len,
73 void *priv);
74
75 int (*set_key) (void *key, int len, u8 * seq, void *priv);
76 int (*get_key) (void *key, int len, u8 * seq, void *priv);
77
78 /* procfs handler for printing out key information and possible
79 * statistics */
80 char *(*print_stats) (char *p, void *priv);
81
82 /* Crypto specific flag get/set for configuration settings */
83 unsigned long (*get_flags) (void *priv);
84 unsigned long (*set_flags) (unsigned long flags, void *priv);
85
86 /* maximum number of bytes added by encryption; encrypt buf is
87 * allocated with extra_prefix_len bytes, copy of in_buf, and
88 * extra_postfix_len; encrypt need not use all this space, but
89 * the result must start at the beginning of the buffer and correct
90 * length must be returned */
91 int extra_mpdu_prefix_len, extra_mpdu_postfix_len;
92 int extra_msdu_prefix_len, extra_msdu_postfix_len;
93
94 struct module *owner;
95};
96
97struct lib80211_crypt_data {
98 struct list_head list; /* delayed deletion list */
99 struct lib80211_crypto_ops *ops;
100 void *priv;
101 atomic_t refcnt;
102};
103
104struct lib80211_crypt_info {
105 char *name;
106 /* Most clients will already have a lock,
107 so just point to that. */
108 spinlock_t *lock;
109
110 struct lib80211_crypt_data *crypt[NUM_WEP_KEYS];
111 int tx_keyidx; /* default TX key index (crypt[tx_keyidx]) */
112 struct list_head crypt_deinit_list;
113 struct timer_list crypt_deinit_timer;
114 int crypt_quiesced;
115};
116
117int lib80211_crypt_info_init(struct lib80211_crypt_info *info, char *name,
118 spinlock_t *lock);
119void lib80211_crypt_info_free(struct lib80211_crypt_info *info);
120int lib80211_register_crypto_ops(struct lib80211_crypto_ops *ops);
121int lib80211_unregister_crypto_ops(struct lib80211_crypto_ops *ops);
122struct lib80211_crypto_ops *lib80211_get_crypto_ops(const char *name);
123void lib80211_crypt_deinit_entries(struct lib80211_crypt_info *, int);
124void lib80211_crypt_deinit_handler(unsigned long);
125void lib80211_crypt_delayed_deinit(struct lib80211_crypt_info *info,
126 struct lib80211_crypt_data **crypt);
127void lib80211_crypt_quiescing(struct lib80211_crypt_info *info);
128
18#endif /* LIB80211_H */ 129#endif /* LIB80211_H */
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 1b8ed421feaa..6a1d4ea18186 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -307,7 +307,7 @@ struct ieee80211_tx_rate {
307 s8 idx; 307 s8 idx;
308 u8 count; 308 u8 count;
309 u8 flags; 309 u8 flags;
310}; 310} __attribute__((packed));
311 311
312/** 312/**
313 * struct ieee80211_tx_info - skb transmit information 313 * struct ieee80211_tx_info - skb transmit information
@@ -341,6 +341,7 @@ struct ieee80211_tx_info {
341 u8 antenna_sel_tx; 341 u8 antenna_sel_tx;
342 342
343 /* 2 byte hole */ 343 /* 2 byte hole */
344 u8 pad[2];
344 345
345 union { 346 union {
346 struct { 347 struct {
@@ -1269,8 +1270,6 @@ enum ieee80211_ampdu_mlme_action {
1269 * This is needed only for IBSS mode and the result of this function is 1270 * This is needed only for IBSS mode and the result of this function is
1270 * used to determine whether to reply to Probe Requests. 1271 * used to determine whether to reply to Probe Requests.
1271 * 1272 *
1272 * @conf_ht: Configures low level driver with 802.11n HT data. Must be atomic.
1273 *
1274 * @ampdu_action: Perform a certain A-MPDU action 1273 * @ampdu_action: Perform a certain A-MPDU action
1275 * The RA/TID combination determines the destination and TID we want 1274 * The RA/TID combination determines the destination and TID we want
1276 * the ampdu action to be performed for. The action is defined through 1275 * the ampdu action to be performed for. The action is defined through
diff --git a/net/Kconfig b/net/Kconfig
index c7d01c3a23c5..6ec2cce7c167 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -251,7 +251,6 @@ if WIRELESS
251 251
252source "net/wireless/Kconfig" 252source "net/wireless/Kconfig"
253source "net/mac80211/Kconfig" 253source "net/mac80211/Kconfig"
254source "net/ieee80211/Kconfig"
255 254
256endif # WIRELESS 255endif # WIRELESS
257 256
diff --git a/net/Makefile b/net/Makefile
index 83b064651f1d..e5af3dc3a037 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -51,7 +51,6 @@ obj-$(CONFIG_IP_DCCP) += dccp/
51obj-$(CONFIG_IP_SCTP) += sctp/ 51obj-$(CONFIG_IP_SCTP) += sctp/
52obj-y += wireless/ 52obj-y += wireless/
53obj-$(CONFIG_MAC80211) += mac80211/ 53obj-$(CONFIG_MAC80211) += mac80211/
54obj-$(CONFIG_IEEE80211) += ieee80211/
55obj-$(CONFIG_TIPC) += tipc/ 54obj-$(CONFIG_TIPC) += tipc/
56obj-$(CONFIG_NETLABEL) += netlabel/ 55obj-$(CONFIG_NETLABEL) += netlabel/
57obj-$(CONFIG_IUCV) += iucv/ 56obj-$(CONFIG_IUCV) += iucv/
diff --git a/net/ieee80211/Kconfig b/net/ieee80211/Kconfig
deleted file mode 100644
index d2282bb2e4f1..000000000000
--- a/net/ieee80211/Kconfig
+++ /dev/null
@@ -1,50 +0,0 @@
1config IEEE80211
2 tristate
3 select WIRELESS_EXT
4 select CRYPTO
5 select CRYPTO_ARC4
6 select CRYPTO_ECB
7 select CRYPTO_AES
8 select CRYPTO_MICHAEL_MIC
9 select CRYPTO_ECB
10 select CRC32
11 select IEEE80211_CRYPT_WEP
12 select IEEE80211_CRYPT_TKIP
13 select IEEE80211_CRYPT_CCMP
14 select LIB80211
15 ---help---
16 This option enables the hardware independent IEEE 802.11
17 networking stack. This component is deprecated in favor of the
18 mac80211 component.
19
20config IEEE80211_DEBUG
21 bool "Full debugging output for the old IEEE80211 stack"
22 depends on IEEE80211
23 ---help---
24 This option will enable debug tracing output for the
25 ieee80211 network stack.
26
27 This will result in the kernel module being ~70k larger. You
28 can control which debug output is sent to the kernel log by
29 setting the value in
30
31 /proc/net/ieee80211/debug_level
32
33 For example:
34
35 % echo 0x00000FFO > /proc/net/ieee80211/debug_level
36
37 For a list of values you can assign to debug_level, you
38 can look at the bit mask values in <net/ieee80211.h>
39
40 If you are not trying to debug or develop the ieee80211
41 subsystem, you most likely want to say N here.
42
43config IEEE80211_CRYPT_WEP
44 tristate
45
46config IEEE80211_CRYPT_CCMP
47 tristate
48
49config IEEE80211_CRYPT_TKIP
50 tristate
diff --git a/net/ieee80211/Makefile b/net/ieee80211/Makefile
deleted file mode 100644
index f988417121da..000000000000
--- a/net/ieee80211/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
1obj-$(CONFIG_IEEE80211) += ieee80211.o
2obj-$(CONFIG_IEEE80211) += ieee80211_crypt.o
3obj-$(CONFIG_IEEE80211_CRYPT_WEP) += ieee80211_crypt_wep.o
4obj-$(CONFIG_IEEE80211_CRYPT_CCMP) += ieee80211_crypt_ccmp.o
5obj-$(CONFIG_IEEE80211_CRYPT_TKIP) += ieee80211_crypt_tkip.o
6ieee80211-objs := \
7 ieee80211_module.o \
8 ieee80211_tx.o \
9 ieee80211_rx.o \
10 ieee80211_wx.o \
11 ieee80211_geo.o
12
diff --git a/net/ieee80211/ieee80211_crypt.c b/net/ieee80211/ieee80211_crypt.c
deleted file mode 100644
index df5592c9339f..000000000000
--- a/net/ieee80211/ieee80211_crypt.c
+++ /dev/null
@@ -1,206 +0,0 @@
1/*
2 * Host AP crypto routines
3 *
4 * Copyright (c) 2002-2003, Jouni Malinen <j@w1.fi>
5 * Portions Copyright (C) 2004, Intel Corporation <jketreno@linux.intel.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation. See README and COPYING for
10 * more details.
11 *
12 */
13
14#include <linux/errno.h>
15#include <linux/module.h>
16#include <linux/init.h>
17#include <linux/slab.h>
18#include <linux/string.h>
19#include <net/ieee80211.h>
20
21MODULE_AUTHOR("Jouni Malinen");
22MODULE_DESCRIPTION("HostAP crypto");
23MODULE_LICENSE("GPL");
24
25struct ieee80211_crypto_alg {
26 struct list_head list;
27 struct ieee80211_crypto_ops *ops;
28};
29
30static LIST_HEAD(ieee80211_crypto_algs);
31static DEFINE_SPINLOCK(ieee80211_crypto_lock);
32
33void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee, int force)
34{
35 struct ieee80211_crypt_data *entry, *next;
36 unsigned long flags;
37
38 spin_lock_irqsave(&ieee->lock, flags);
39 list_for_each_entry_safe(entry, next, &ieee->crypt_deinit_list, list) {
40 if (atomic_read(&entry->refcnt) != 0 && !force)
41 continue;
42
43 list_del(&entry->list);
44
45 if (entry->ops) {
46 entry->ops->deinit(entry->priv);
47 module_put(entry->ops->owner);
48 }
49 kfree(entry);
50 }
51 spin_unlock_irqrestore(&ieee->lock, flags);
52}
53
54/* After this, crypt_deinit_list won't accept new members */
55void ieee80211_crypt_quiescing(struct ieee80211_device *ieee)
56{
57 unsigned long flags;
58
59 spin_lock_irqsave(&ieee->lock, flags);
60 ieee->crypt_quiesced = 1;
61 spin_unlock_irqrestore(&ieee->lock, flags);
62}
63
64void ieee80211_crypt_deinit_handler(unsigned long data)
65{
66 struct ieee80211_device *ieee = (struct ieee80211_device *)data;
67 unsigned long flags;
68
69 ieee80211_crypt_deinit_entries(ieee, 0);
70
71 spin_lock_irqsave(&ieee->lock, flags);
72 if (!list_empty(&ieee->crypt_deinit_list) && !ieee->crypt_quiesced) {
73 printk(KERN_DEBUG "%s: entries remaining in delayed crypt "
74 "deletion list\n", ieee->dev->name);
75 ieee->crypt_deinit_timer.expires = jiffies + HZ;
76 add_timer(&ieee->crypt_deinit_timer);
77 }
78 spin_unlock_irqrestore(&ieee->lock, flags);
79}
80
81void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee,
82 struct ieee80211_crypt_data **crypt)
83{
84 struct ieee80211_crypt_data *tmp;
85 unsigned long flags;
86
87 if (*crypt == NULL)
88 return;
89
90 tmp = *crypt;
91 *crypt = NULL;
92
93 /* must not run ops->deinit() while there may be pending encrypt or
94 * decrypt operations. Use a list of delayed deinits to avoid needing
95 * locking. */
96
97 spin_lock_irqsave(&ieee->lock, flags);
98 if (!ieee->crypt_quiesced) {
99 list_add(&tmp->list, &ieee->crypt_deinit_list);
100 if (!timer_pending(&ieee->crypt_deinit_timer)) {
101 ieee->crypt_deinit_timer.expires = jiffies + HZ;
102 add_timer(&ieee->crypt_deinit_timer);
103 }
104 }
105 spin_unlock_irqrestore(&ieee->lock, flags);
106}
107
108int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops)
109{
110 unsigned long flags;
111 struct ieee80211_crypto_alg *alg;
112
113 alg = kzalloc(sizeof(*alg), GFP_KERNEL);
114 if (alg == NULL)
115 return -ENOMEM;
116
117 alg->ops = ops;
118
119 spin_lock_irqsave(&ieee80211_crypto_lock, flags);
120 list_add(&alg->list, &ieee80211_crypto_algs);
121 spin_unlock_irqrestore(&ieee80211_crypto_lock, flags);
122
123 printk(KERN_DEBUG "ieee80211_crypt: registered algorithm '%s'\n",
124 ops->name);
125
126 return 0;
127}
128
129int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops)
130{
131 struct ieee80211_crypto_alg *alg;
132 unsigned long flags;
133
134 spin_lock_irqsave(&ieee80211_crypto_lock, flags);
135 list_for_each_entry(alg, &ieee80211_crypto_algs, list) {
136 if (alg->ops == ops)
137 goto found;
138 }
139 spin_unlock_irqrestore(&ieee80211_crypto_lock, flags);
140 return -EINVAL;
141
142 found:
143 printk(KERN_DEBUG "ieee80211_crypt: unregistered algorithm "
144 "'%s'\n", ops->name);
145 list_del(&alg->list);
146 spin_unlock_irqrestore(&ieee80211_crypto_lock, flags);
147 kfree(alg);
148 return 0;
149}
150
151struct ieee80211_crypto_ops *ieee80211_get_crypto_ops(const char *name)
152{
153 struct ieee80211_crypto_alg *alg;
154 unsigned long flags;
155
156 spin_lock_irqsave(&ieee80211_crypto_lock, flags);
157 list_for_each_entry(alg, &ieee80211_crypto_algs, list) {
158 if (strcmp(alg->ops->name, name) == 0)
159 goto found;
160 }
161 spin_unlock_irqrestore(&ieee80211_crypto_lock, flags);
162 return NULL;
163
164 found:
165 spin_unlock_irqrestore(&ieee80211_crypto_lock, flags);
166 return alg->ops;
167}
168
169static void *ieee80211_crypt_null_init(int keyidx)
170{
171 return (void *)1;
172}
173
174static void ieee80211_crypt_null_deinit(void *priv)
175{
176}
177
178static struct ieee80211_crypto_ops ieee80211_crypt_null = {
179 .name = "NULL",
180 .init = ieee80211_crypt_null_init,
181 .deinit = ieee80211_crypt_null_deinit,
182 .owner = THIS_MODULE,
183};
184
185static int __init ieee80211_crypto_init(void)
186{
187 return ieee80211_register_crypto_ops(&ieee80211_crypt_null);
188}
189
190static void __exit ieee80211_crypto_deinit(void)
191{
192 ieee80211_unregister_crypto_ops(&ieee80211_crypt_null);
193 BUG_ON(!list_empty(&ieee80211_crypto_algs));
194}
195
196EXPORT_SYMBOL(ieee80211_crypt_deinit_entries);
197EXPORT_SYMBOL(ieee80211_crypt_deinit_handler);
198EXPORT_SYMBOL(ieee80211_crypt_delayed_deinit);
199EXPORT_SYMBOL(ieee80211_crypt_quiescing);
200
201EXPORT_SYMBOL(ieee80211_register_crypto_ops);
202EXPORT_SYMBOL(ieee80211_unregister_crypto_ops);
203EXPORT_SYMBOL(ieee80211_get_crypto_ops);
204
205module_init(ieee80211_crypto_init);
206module_exit(ieee80211_crypto_deinit);
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index cde145221b61..46082125f3e1 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -229,8 +229,14 @@ static int ieee80211_open(struct net_device *dev)
229 if (res) 229 if (res)
230 goto err_stop; 230 goto err_stop;
231 231
232 if (ieee80211_vif_is_mesh(&sdata->vif)) 232 if (ieee80211_vif_is_mesh(&sdata->vif)) {
233 local->fif_other_bss++;
234 netif_addr_lock_bh(local->mdev);
235 ieee80211_configure_filter(local);
236 netif_addr_unlock_bh(local->mdev);
237
233 ieee80211_start_mesh(sdata); 238 ieee80211_start_mesh(sdata);
239 }
234 changed |= ieee80211_reset_erp_info(sdata); 240 changed |= ieee80211_reset_erp_info(sdata);
235 ieee80211_bss_info_change_notify(sdata, changed); 241 ieee80211_bss_info_change_notify(sdata, changed);
236 ieee80211_enable_keys(sdata); 242 ieee80211_enable_keys(sdata);
@@ -456,8 +462,15 @@ static int ieee80211_stop(struct net_device *dev)
456 /* fall through */ 462 /* fall through */
457 case NL80211_IFTYPE_MESH_POINT: 463 case NL80211_IFTYPE_MESH_POINT:
458 if (ieee80211_vif_is_mesh(&sdata->vif)) { 464 if (ieee80211_vif_is_mesh(&sdata->vif)) {
459 /* allmulti is always set on mesh ifaces */ 465 /* other_bss and allmulti are always set on mesh
466 * ifaces */
467 local->fif_other_bss--;
460 atomic_dec(&local->iff_allmultis); 468 atomic_dec(&local->iff_allmultis);
469
470 netif_addr_lock_bh(local->mdev);
471 ieee80211_configure_filter(local);
472 netif_addr_unlock_bh(local->mdev);
473
461 ieee80211_stop_mesh(sdata); 474 ieee80211_stop_mesh(sdata);
462 } 475 }
463 /* fall through */ 476 /* fall through */
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 4d76bf25bada..d81a4d2cd3aa 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -14,7 +14,6 @@
14#include <linux/delay.h> 14#include <linux/delay.h>
15#include <linux/if_ether.h> 15#include <linux/if_ether.h>
16#include <linux/skbuff.h> 16#include <linux/skbuff.h>
17#include <linux/netdevice.h>
18#include <linux/if_arp.h> 17#include <linux/if_arp.h>
19#include <linux/wireless.h> 18#include <linux/wireless.h>
20#include <linux/random.h> 19#include <linux/random.h>
diff --git a/net/mac80211/rc80211_pid_algo.c b/net/mac80211/rc80211_pid_algo.c
index 2328ba568039..96ceb7e86c5c 100644
--- a/net/mac80211/rc80211_pid_algo.c
+++ b/net/mac80211/rc80211_pid_algo.c
@@ -403,11 +403,11 @@ static void *rate_control_pid_alloc(struct ieee80211_hw *hw,
403 S_IRUSR | S_IWUSR, debugfsdir, 403 S_IRUSR | S_IWUSR, debugfsdir,
404 &pinfo->sampling_period); 404 &pinfo->sampling_period);
405 de->coeff_p = debugfs_create_u32("coeff_p", S_IRUSR | S_IWUSR, 405 de->coeff_p = debugfs_create_u32("coeff_p", S_IRUSR | S_IWUSR,
406 debugfsdir, &pinfo->coeff_p); 406 debugfsdir, (u32 *)&pinfo->coeff_p);
407 de->coeff_i = debugfs_create_u32("coeff_i", S_IRUSR | S_IWUSR, 407 de->coeff_i = debugfs_create_u32("coeff_i", S_IRUSR | S_IWUSR,
408 debugfsdir, &pinfo->coeff_i); 408 debugfsdir, (u32 *)&pinfo->coeff_i);
409 de->coeff_d = debugfs_create_u32("coeff_d", S_IRUSR | S_IWUSR, 409 de->coeff_d = debugfs_create_u32("coeff_d", S_IRUSR | S_IWUSR,
410 debugfsdir, &pinfo->coeff_d); 410 debugfsdir, (u32 *)&pinfo->coeff_d);
411 de->smoothing_shift = debugfs_create_u32("smoothing_shift", 411 de->smoothing_shift = debugfs_create_u32("smoothing_shift",
412 S_IRUSR | S_IWUSR, debugfsdir, 412 S_IRUSR | S_IWUSR, debugfsdir,
413 &pinfo->smoothing_shift); 413 &pinfo->smoothing_shift);
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 5ad9250b63ab..dc2606d0ae77 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -169,9 +169,6 @@ struct sta_ampdu_mlme {
169 * @lock: used for locking all fields that require locking, see comments 169 * @lock: used for locking all fields that require locking, see comments
170 * in the header file. 170 * in the header file.
171 * @flaglock: spinlock for flags accesses 171 * @flaglock: spinlock for flags accesses
172 * @addr: MAC address of this STA
173 * @aid: STA's unique AID (1..2007, 0 = not assigned yet),
174 * only used in AP (and IBSS?) mode
175 * @listen_interval: listen interval of this station, when we're acting as AP 172 * @listen_interval: listen interval of this station, when we're acting as AP
176 * @pin_status: used internally for pinning a STA struct into memory 173 * @pin_status: used internally for pinning a STA struct into memory
177 * @flags: STA flags, see &enum ieee80211_sta_info_flags 174 * @flags: STA flags, see &enum ieee80211_sta_info_flags
diff --git a/net/wireless/Kconfig b/net/wireless/Kconfig
index ae7f2262dfb5..f7c64dbe86cc 100644
--- a/net/wireless/Kconfig
+++ b/net/wireless/Kconfig
@@ -82,3 +82,12 @@ config LIB80211
82 82
83 Drivers should select this themselves if needed. Say Y if 83 Drivers should select this themselves if needed. Say Y if
84 you want this built into your kernel. 84 you want this built into your kernel.
85
86config LIB80211_CRYPT_WEP
87 tristate
88
89config LIB80211_CRYPT_CCMP
90 tristate
91
92config LIB80211_CRYPT_TKIP
93 tristate
diff --git a/net/wireless/Makefile b/net/wireless/Makefile
index d2d848d445f2..cc547edb111f 100644
--- a/net/wireless/Makefile
+++ b/net/wireless/Makefile
@@ -1,6 +1,9 @@
1obj-$(CONFIG_WIRELESS_EXT) += wext.o 1obj-$(CONFIG_WIRELESS_EXT) += wext.o
2obj-$(CONFIG_CFG80211) += cfg80211.o 2obj-$(CONFIG_CFG80211) += cfg80211.o
3obj-$(CONFIG_LIB80211) += lib80211.o 3obj-$(CONFIG_LIB80211) += lib80211.o
4obj-$(CONFIG_LIB80211_CRYPT_WEP) += lib80211_crypt_wep.o
5obj-$(CONFIG_LIB80211_CRYPT_CCMP) += lib80211_crypt_ccmp.o
6obj-$(CONFIG_LIB80211_CRYPT_TKIP) += lib80211_crypt_tkip.o
4 7
5cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o 8cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o
6cfg80211-$(CONFIG_NL80211) += nl80211.o 9cfg80211-$(CONFIG_NL80211) += nl80211.o
diff --git a/net/wireless/lib80211.c b/net/wireless/lib80211.c
index e71f7d085621..97d411f74507 100644
--- a/net/wireless/lib80211.c
+++ b/net/wireless/lib80211.c
@@ -3,11 +3,23 @@
3 * 3 *
4 * Copyright(c) 2008 John W. Linville <linville@tuxdriver.com> 4 * Copyright(c) 2008 John W. Linville <linville@tuxdriver.com>
5 * 5 *
6 * Portions copied from old ieee80211 component, w/ original copyright
7 * notices below:
8 *
9 * Host AP crypto routines
10 *
11 * Copyright (c) 2002-2003, Jouni Malinen <j@w1.fi>
12 * Portions Copyright (C) 2004, Intel Corporation <jketreno@linux.intel.com>
13 *
6 */ 14 */
7 15
8#include <linux/module.h> 16#include <linux/module.h>
9#include <linux/ctype.h> 17#include <linux/ctype.h>
10#include <linux/ieee80211.h> 18#include <linux/ieee80211.h>
19#include <linux/errno.h>
20#include <linux/init.h>
21#include <linux/slab.h>
22#include <linux/string.h>
11 23
12#include <net/lib80211.h> 24#include <net/lib80211.h>
13 25
@@ -19,6 +31,14 @@ MODULE_DESCRIPTION(DRV_DESCRIPTION);
19MODULE_AUTHOR("John W. Linville <linville@tuxdriver.com>"); 31MODULE_AUTHOR("John W. Linville <linville@tuxdriver.com>");
20MODULE_LICENSE("GPL"); 32MODULE_LICENSE("GPL");
21 33
34struct lib80211_crypto_alg {
35 struct list_head list;
36 struct lib80211_crypto_ops *ops;
37};
38
39static LIST_HEAD(lib80211_crypto_algs);
40static DEFINE_SPINLOCK(lib80211_crypto_lock);
41
22const char *print_ssid(char *buf, const char *ssid, u8 ssid_len) 42const char *print_ssid(char *buf, const char *ssid, u8 ssid_len)
23{ 43{
24 const char *s = ssid; 44 const char *s = ssid;
@@ -51,15 +71,214 @@ const char *print_ssid(char *buf, const char *ssid, u8 ssid_len)
51} 71}
52EXPORT_SYMBOL(print_ssid); 72EXPORT_SYMBOL(print_ssid);
53 73
54static int __init ieee80211_init(void) 74int lib80211_crypt_info_init(struct lib80211_crypt_info *info, char *name,
75 spinlock_t *lock)
55{ 76{
56 printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION "\n"); 77 memset(info, 0, sizeof(*info));
78
79 info->name = name;
80 info->lock = lock;
81
82 INIT_LIST_HEAD(&info->crypt_deinit_list);
83 setup_timer(&info->crypt_deinit_timer, lib80211_crypt_deinit_handler,
84 (unsigned long)info);
85
57 return 0; 86 return 0;
58} 87}
88EXPORT_SYMBOL(lib80211_crypt_info_init);
89
90void lib80211_crypt_info_free(struct lib80211_crypt_info *info)
91{
92 int i;
93
94 lib80211_crypt_quiescing(info);
95 del_timer_sync(&info->crypt_deinit_timer);
96 lib80211_crypt_deinit_entries(info, 1);
97
98 for (i = 0; i < NUM_WEP_KEYS; i++) {
99 struct lib80211_crypt_data *crypt = info->crypt[i];
100 if (crypt) {
101 if (crypt->ops) {
102 crypt->ops->deinit(crypt->priv);
103 module_put(crypt->ops->owner);
104 }
105 kfree(crypt);
106 info->crypt[i] = NULL;
107 }
108 }
109}
110EXPORT_SYMBOL(lib80211_crypt_info_free);
111
112void lib80211_crypt_deinit_entries(struct lib80211_crypt_info *info, int force)
113{
114 struct lib80211_crypt_data *entry, *next;
115 unsigned long flags;
116
117 spin_lock_irqsave(info->lock, flags);
118 list_for_each_entry_safe(entry, next, &info->crypt_deinit_list, list) {
119 if (atomic_read(&entry->refcnt) != 0 && !force)
120 continue;
121
122 list_del(&entry->list);
123
124 if (entry->ops) {
125 entry->ops->deinit(entry->priv);
126 module_put(entry->ops->owner);
127 }
128 kfree(entry);
129 }
130 spin_unlock_irqrestore(info->lock, flags);
131}
132EXPORT_SYMBOL(lib80211_crypt_deinit_entries);
133
134/* After this, crypt_deinit_list won't accept new members */
135void lib80211_crypt_quiescing(struct lib80211_crypt_info *info)
136{
137 unsigned long flags;
138
139 spin_lock_irqsave(info->lock, flags);
140 info->crypt_quiesced = 1;
141 spin_unlock_irqrestore(info->lock, flags);
142}
143EXPORT_SYMBOL(lib80211_crypt_quiescing);
144
145void lib80211_crypt_deinit_handler(unsigned long data)
146{
147 struct lib80211_crypt_info *info = (struct lib80211_crypt_info *)data;
148 unsigned long flags;
149
150 lib80211_crypt_deinit_entries(info, 0);
151
152 spin_lock_irqsave(info->lock, flags);
153 if (!list_empty(&info->crypt_deinit_list) && !info->crypt_quiesced) {
154 printk(KERN_DEBUG "%s: entries remaining in delayed crypt "
155 "deletion list\n", info->name);
156 info->crypt_deinit_timer.expires = jiffies + HZ;
157 add_timer(&info->crypt_deinit_timer);
158 }
159 spin_unlock_irqrestore(info->lock, flags);
160}
161EXPORT_SYMBOL(lib80211_crypt_deinit_handler);
162
163void lib80211_crypt_delayed_deinit(struct lib80211_crypt_info *info,
164 struct lib80211_crypt_data **crypt)
165{
166 struct lib80211_crypt_data *tmp;
167 unsigned long flags;
168
169 if (*crypt == NULL)
170 return;
171
172 tmp = *crypt;
173 *crypt = NULL;
174
175 /* must not run ops->deinit() while there may be pending encrypt or
176 * decrypt operations. Use a list of delayed deinits to avoid needing
177 * locking. */
178
179 spin_lock_irqsave(info->lock, flags);
180 if (!info->crypt_quiesced) {
181 list_add(&tmp->list, &info->crypt_deinit_list);
182 if (!timer_pending(&info->crypt_deinit_timer)) {
183 info->crypt_deinit_timer.expires = jiffies + HZ;
184 add_timer(&info->crypt_deinit_timer);
185 }
186 }
187 spin_unlock_irqrestore(info->lock, flags);
188}
189EXPORT_SYMBOL(lib80211_crypt_delayed_deinit);
190
191int lib80211_register_crypto_ops(struct lib80211_crypto_ops *ops)
192{
193 unsigned long flags;
194 struct lib80211_crypto_alg *alg;
195
196 alg = kzalloc(sizeof(*alg), GFP_KERNEL);
197 if (alg == NULL)
198 return -ENOMEM;
199
200 alg->ops = ops;
201
202 spin_lock_irqsave(&lib80211_crypto_lock, flags);
203 list_add(&alg->list, &lib80211_crypto_algs);
204 spin_unlock_irqrestore(&lib80211_crypto_lock, flags);
205
206 printk(KERN_DEBUG "lib80211_crypt: registered algorithm '%s'\n",
207 ops->name);
208
209 return 0;
210}
211EXPORT_SYMBOL(lib80211_register_crypto_ops);
212
213int lib80211_unregister_crypto_ops(struct lib80211_crypto_ops *ops)
214{
215 struct lib80211_crypto_alg *alg;
216 unsigned long flags;
217
218 spin_lock_irqsave(&lib80211_crypto_lock, flags);
219 list_for_each_entry(alg, &lib80211_crypto_algs, list) {
220 if (alg->ops == ops)
221 goto found;
222 }
223 spin_unlock_irqrestore(&lib80211_crypto_lock, flags);
224 return -EINVAL;
225
226 found:
227 printk(KERN_DEBUG "lib80211_crypt: unregistered algorithm "
228 "'%s'\n", ops->name);
229 list_del(&alg->list);
230 spin_unlock_irqrestore(&lib80211_crypto_lock, flags);
231 kfree(alg);
232 return 0;
233}
234EXPORT_SYMBOL(lib80211_unregister_crypto_ops);
235
236struct lib80211_crypto_ops *lib80211_get_crypto_ops(const char *name)
237{
238 struct lib80211_crypto_alg *alg;
239 unsigned long flags;
240
241 spin_lock_irqsave(&lib80211_crypto_lock, flags);
242 list_for_each_entry(alg, &lib80211_crypto_algs, list) {
243 if (strcmp(alg->ops->name, name) == 0)
244 goto found;
245 }
246 spin_unlock_irqrestore(&lib80211_crypto_lock, flags);
247 return NULL;
248
249 found:
250 spin_unlock_irqrestore(&lib80211_crypto_lock, flags);
251 return alg->ops;
252}
253EXPORT_SYMBOL(lib80211_get_crypto_ops);
254
255static void *lib80211_crypt_null_init(int keyidx)
256{
257 return (void *)1;
258}
259
260static void lib80211_crypt_null_deinit(void *priv)
261{
262}
263
264static struct lib80211_crypto_ops lib80211_crypt_null = {
265 .name = "NULL",
266 .init = lib80211_crypt_null_init,
267 .deinit = lib80211_crypt_null_deinit,
268 .owner = THIS_MODULE,
269};
270
271static int __init lib80211_init(void)
272{
273 printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION "\n");
274 return lib80211_register_crypto_ops(&lib80211_crypt_null);
275}
59 276
60static void __exit ieee80211_exit(void) 277static void __exit lib80211_exit(void)
61{ 278{
279 lib80211_unregister_crypto_ops(&lib80211_crypt_null);
280 BUG_ON(!list_empty(&lib80211_crypto_algs));
62} 281}
63 282
64module_init(ieee80211_init); 283module_init(lib80211_init);
65module_exit(ieee80211_exit); 284module_exit(lib80211_exit);
diff --git a/net/ieee80211/ieee80211_crypt_ccmp.c b/net/wireless/lib80211_crypt_ccmp.c
index bea04af0b482..db428194c16a 100644
--- a/net/ieee80211/ieee80211_crypt_ccmp.c
+++ b/net/wireless/lib80211_crypt_ccmp.c
@@ -1,7 +1,8 @@
1/* 1/*
2 * Host AP crypt: host-based CCMP encryption implementation for Host AP driver 2 * lib80211 crypt: host-based CCMP encryption implementation for lib80211
3 * 3 *
4 * Copyright (c) 2003-2004, Jouni Malinen <j@w1.fi> 4 * Copyright (c) 2003-2004, Jouni Malinen <j@w1.fi>
5 * Copyright (c) 2008, John W. Linville <linville@tuxdriver.com>
5 * 6 *
6 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as 8 * it under the terms of the GNU General Public License version 2 as
@@ -22,10 +23,12 @@
22#include <asm/string.h> 23#include <asm/string.h>
23#include <linux/wireless.h> 24#include <linux/wireless.h>
24 25
25#include <net/ieee80211.h> 26#include <linux/ieee80211.h>
26 27
27#include <linux/crypto.h> 28#include <linux/crypto.h>
28 29
30#include <net/lib80211.h>
31
29MODULE_AUTHOR("Jouni Malinen"); 32MODULE_AUTHOR("Jouni Malinen");
30MODULE_DESCRIPTION("Host AP crypt: CCMP"); 33MODULE_DESCRIPTION("Host AP crypt: CCMP");
31MODULE_LICENSE("GPL"); 34MODULE_LICENSE("GPL");
@@ -36,7 +39,7 @@ MODULE_LICENSE("GPL");
36#define CCMP_TK_LEN 16 39#define CCMP_TK_LEN 16
37#define CCMP_PN_LEN 6 40#define CCMP_PN_LEN 6
38 41
39struct ieee80211_ccmp_data { 42struct lib80211_ccmp_data {
40 u8 key[CCMP_TK_LEN]; 43 u8 key[CCMP_TK_LEN];
41 int key_set; 44 int key_set;
42 45
@@ -57,15 +60,15 @@ struct ieee80211_ccmp_data {
57 u8 rx_b0[AES_BLOCK_LEN], rx_b[AES_BLOCK_LEN], rx_a[AES_BLOCK_LEN]; 60 u8 rx_b0[AES_BLOCK_LEN], rx_b[AES_BLOCK_LEN], rx_a[AES_BLOCK_LEN];
58}; 61};
59 62
60static inline void ieee80211_ccmp_aes_encrypt(struct crypto_cipher *tfm, 63static inline void lib80211_ccmp_aes_encrypt(struct crypto_cipher *tfm,
61 const u8 pt[16], u8 ct[16]) 64 const u8 pt[16], u8 ct[16])
62{ 65{
63 crypto_cipher_encrypt_one(tfm, ct, pt); 66 crypto_cipher_encrypt_one(tfm, ct, pt);
64} 67}
65 68
66static void *ieee80211_ccmp_init(int key_idx) 69static void *lib80211_ccmp_init(int key_idx)
67{ 70{
68 struct ieee80211_ccmp_data *priv; 71 struct lib80211_ccmp_data *priv;
69 72
70 priv = kzalloc(sizeof(*priv), GFP_ATOMIC); 73 priv = kzalloc(sizeof(*priv), GFP_ATOMIC);
71 if (priv == NULL) 74 if (priv == NULL)
@@ -74,7 +77,7 @@ static void *ieee80211_ccmp_init(int key_idx)
74 77
75 priv->tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC); 78 priv->tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC);
76 if (IS_ERR(priv->tfm)) { 79 if (IS_ERR(priv->tfm)) {
77 printk(KERN_DEBUG "ieee80211_crypt_ccmp: could not allocate " 80 printk(KERN_DEBUG "lib80211_crypt_ccmp: could not allocate "
78 "crypto API aes\n"); 81 "crypto API aes\n");
79 priv->tfm = NULL; 82 priv->tfm = NULL;
80 goto fail; 83 goto fail;
@@ -92,9 +95,9 @@ static void *ieee80211_ccmp_init(int key_idx)
92 return NULL; 95 return NULL;
93} 96}
94 97
95static void ieee80211_ccmp_deinit(void *priv) 98static void lib80211_ccmp_deinit(void *priv)
96{ 99{
97 struct ieee80211_ccmp_data *_priv = priv; 100 struct lib80211_ccmp_data *_priv = priv;
98 if (_priv && _priv->tfm) 101 if (_priv && _priv->tfm)
99 crypto_free_cipher(_priv->tfm); 102 crypto_free_cipher(_priv->tfm);
100 kfree(priv); 103 kfree(priv);
@@ -108,20 +111,17 @@ static inline void xor_block(u8 * b, u8 * a, size_t len)
108} 111}
109 112
110static void ccmp_init_blocks(struct crypto_cipher *tfm, 113static void ccmp_init_blocks(struct crypto_cipher *tfm,
111 struct ieee80211_hdr_4addr *hdr, 114 struct ieee80211_hdr *hdr,
112 u8 * pn, size_t dlen, u8 * b0, u8 * auth, u8 * s0) 115 u8 * pn, size_t dlen, u8 * b0, u8 * auth, u8 * s0)
113{ 116{
114 u8 *pos, qc = 0; 117 u8 *pos, qc = 0;
115 size_t aad_len; 118 size_t aad_len;
116 u16 fc;
117 int a4_included, qc_included; 119 int a4_included, qc_included;
118 u8 aad[2 * AES_BLOCK_LEN]; 120 u8 aad[2 * AES_BLOCK_LEN];
119 121
120 fc = le16_to_cpu(hdr->frame_ctl); 122 a4_included = ieee80211_has_a4(hdr->frame_control);
121 a4_included = ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) == 123 qc_included = ieee80211_is_data_qos(hdr->frame_control);
122 (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)); 124
123 qc_included = ((WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA) &&
124 (WLAN_FC_GET_STYPE(fc) & IEEE80211_STYPE_QOS_DATA));
125 aad_len = 22; 125 aad_len = 22;
126 if (a4_included) 126 if (a4_included)
127 aad_len += 6; 127 aad_len += 6;
@@ -158,7 +158,7 @@ static void ccmp_init_blocks(struct crypto_cipher *tfm,
158 aad[2] = pos[0] & 0x8f; 158 aad[2] = pos[0] & 0x8f;
159 aad[3] = pos[1] & 0xc7; 159 aad[3] = pos[1] & 0xc7;
160 memcpy(aad + 4, hdr->addr1, 3 * ETH_ALEN); 160 memcpy(aad + 4, hdr->addr1, 3 * ETH_ALEN);
161 pos = (u8 *) & hdr->seq_ctl; 161 pos = (u8 *) & hdr->seq_ctrl;
162 aad[22] = pos[0] & 0x0f; 162 aad[22] = pos[0] & 0x0f;
163 aad[23] = 0; /* all bits masked */ 163 aad[23] = 0; /* all bits masked */
164 memset(aad + 24, 0, 8); 164 memset(aad + 24, 0, 8);
@@ -170,20 +170,20 @@ static void ccmp_init_blocks(struct crypto_cipher *tfm,
170 } 170 }
171 171
172 /* Start with the first block and AAD */ 172 /* Start with the first block and AAD */
173 ieee80211_ccmp_aes_encrypt(tfm, b0, auth); 173 lib80211_ccmp_aes_encrypt(tfm, b0, auth);
174 xor_block(auth, aad, AES_BLOCK_LEN); 174 xor_block(auth, aad, AES_BLOCK_LEN);
175 ieee80211_ccmp_aes_encrypt(tfm, auth, auth); 175 lib80211_ccmp_aes_encrypt(tfm, auth, auth);
176 xor_block(auth, &aad[AES_BLOCK_LEN], AES_BLOCK_LEN); 176 xor_block(auth, &aad[AES_BLOCK_LEN], AES_BLOCK_LEN);
177 ieee80211_ccmp_aes_encrypt(tfm, auth, auth); 177 lib80211_ccmp_aes_encrypt(tfm, auth, auth);
178 b0[0] &= 0x07; 178 b0[0] &= 0x07;
179 b0[14] = b0[15] = 0; 179 b0[14] = b0[15] = 0;
180 ieee80211_ccmp_aes_encrypt(tfm, b0, s0); 180 lib80211_ccmp_aes_encrypt(tfm, b0, s0);
181} 181}
182 182
183static int ieee80211_ccmp_hdr(struct sk_buff *skb, int hdr_len, 183static int lib80211_ccmp_hdr(struct sk_buff *skb, int hdr_len,
184 u8 *aeskey, int keylen, void *priv) 184 u8 *aeskey, int keylen, void *priv)
185{ 185{
186 struct ieee80211_ccmp_data *key = priv; 186 struct lib80211_ccmp_data *key = priv;
187 int i; 187 int i;
188 u8 *pos; 188 u8 *pos;
189 189
@@ -217,12 +217,12 @@ static int ieee80211_ccmp_hdr(struct sk_buff *skb, int hdr_len,
217 return CCMP_HDR_LEN; 217 return CCMP_HDR_LEN;
218} 218}
219 219
220static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv) 220static int lib80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
221{ 221{
222 struct ieee80211_ccmp_data *key = priv; 222 struct lib80211_ccmp_data *key = priv;
223 int data_len, i, blocks, last, len; 223 int data_len, i, blocks, last, len;
224 u8 *pos, *mic; 224 u8 *pos, *mic;
225 struct ieee80211_hdr_4addr *hdr; 225 struct ieee80211_hdr *hdr;
226 u8 *b0 = key->tx_b0; 226 u8 *b0 = key->tx_b0;
227 u8 *b = key->tx_b; 227 u8 *b = key->tx_b;
228 u8 *e = key->tx_e; 228 u8 *e = key->tx_e;
@@ -232,13 +232,13 @@ static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
232 return -1; 232 return -1;
233 233
234 data_len = skb->len - hdr_len; 234 data_len = skb->len - hdr_len;
235 len = ieee80211_ccmp_hdr(skb, hdr_len, NULL, 0, priv); 235 len = lib80211_ccmp_hdr(skb, hdr_len, NULL, 0, priv);
236 if (len < 0) 236 if (len < 0)
237 return -1; 237 return -1;
238 238
239 pos = skb->data + hdr_len + CCMP_HDR_LEN; 239 pos = skb->data + hdr_len + CCMP_HDR_LEN;
240 mic = skb_put(skb, CCMP_MIC_LEN); 240 mic = skb_put(skb, CCMP_MIC_LEN);
241 hdr = (struct ieee80211_hdr_4addr *)skb->data; 241 hdr = (struct ieee80211_hdr *)skb->data;
242 ccmp_init_blocks(key->tfm, hdr, key->tx_pn, data_len, b0, b, s0); 242 ccmp_init_blocks(key->tfm, hdr, key->tx_pn, data_len, b0, b, s0);
243 243
244 blocks = DIV_ROUND_UP(data_len, AES_BLOCK_LEN); 244 blocks = DIV_ROUND_UP(data_len, AES_BLOCK_LEN);
@@ -248,11 +248,11 @@ static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
248 len = (i == blocks && last) ? last : AES_BLOCK_LEN; 248 len = (i == blocks && last) ? last : AES_BLOCK_LEN;
249 /* Authentication */ 249 /* Authentication */
250 xor_block(b, pos, len); 250 xor_block(b, pos, len);
251 ieee80211_ccmp_aes_encrypt(key->tfm, b, b); 251 lib80211_ccmp_aes_encrypt(key->tfm, b, b);
252 /* Encryption, with counter */ 252 /* Encryption, with counter */
253 b0[14] = (i >> 8) & 0xff; 253 b0[14] = (i >> 8) & 0xff;
254 b0[15] = i & 0xff; 254 b0[15] = i & 0xff;
255 ieee80211_ccmp_aes_encrypt(key->tfm, b0, e); 255 lib80211_ccmp_aes_encrypt(key->tfm, b0, e);
256 xor_block(pos, e, len); 256 xor_block(pos, e, len);
257 pos += len; 257 pos += len;
258 } 258 }
@@ -284,11 +284,11 @@ static inline int ccmp_replay_check(u8 *pn_n, u8 *pn_o)
284 return 0; 284 return 0;
285} 285}
286 286
287static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv) 287static int lib80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
288{ 288{
289 struct ieee80211_ccmp_data *key = priv; 289 struct lib80211_ccmp_data *key = priv;
290 u8 keyidx, *pos; 290 u8 keyidx, *pos;
291 struct ieee80211_hdr_4addr *hdr; 291 struct ieee80211_hdr *hdr;
292 u8 *b0 = key->rx_b0; 292 u8 *b0 = key->rx_b0;
293 u8 *b = key->rx_b; 293 u8 *b = key->rx_b;
294 u8 *a = key->rx_a; 294 u8 *a = key->rx_a;
@@ -302,7 +302,7 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
302 return -1; 302 return -1;
303 } 303 }
304 304
305 hdr = (struct ieee80211_hdr_4addr *)skb->data; 305 hdr = (struct ieee80211_hdr *)skb->data;
306 pos = skb->data + hdr_len; 306 pos = skb->data + hdr_len;
307 keyidx = pos[3]; 307 keyidx = pos[3];
308 if (!(keyidx & (1 << 5))) { 308 if (!(keyidx & (1 << 5))) {
@@ -337,8 +337,8 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
337 pos += 8; 337 pos += 8;
338 338
339 if (ccmp_replay_check(pn, key->rx_pn)) { 339 if (ccmp_replay_check(pn, key->rx_pn)) {
340 if (ieee80211_ratelimit_debug(IEEE80211_DL_DROP)) { 340 if (net_ratelimit()) {
341 IEEE80211_DEBUG_DROP("CCMP: replay detected: STA=%pM " 341 printk(KERN_DEBUG "CCMP: replay detected: STA=%pM "
342 "previous PN %02x%02x%02x%02x%02x%02x " 342 "previous PN %02x%02x%02x%02x%02x%02x "
343 "received PN %02x%02x%02x%02x%02x%02x\n", 343 "received PN %02x%02x%02x%02x%02x%02x\n",
344 hdr->addr2, 344 hdr->addr2,
@@ -361,11 +361,11 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
361 /* Decrypt, with counter */ 361 /* Decrypt, with counter */
362 b0[14] = (i >> 8) & 0xff; 362 b0[14] = (i >> 8) & 0xff;
363 b0[15] = i & 0xff; 363 b0[15] = i & 0xff;
364 ieee80211_ccmp_aes_encrypt(key->tfm, b0, b); 364 lib80211_ccmp_aes_encrypt(key->tfm, b0, b);
365 xor_block(pos, b, len); 365 xor_block(pos, b, len);
366 /* Authentication */ 366 /* Authentication */
367 xor_block(a, pos, len); 367 xor_block(a, pos, len);
368 ieee80211_ccmp_aes_encrypt(key->tfm, a, a); 368 lib80211_ccmp_aes_encrypt(key->tfm, a, a);
369 pos += len; 369 pos += len;
370 } 370 }
371 371
@@ -388,9 +388,9 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
388 return keyidx; 388 return keyidx;
389} 389}
390 390
391static int ieee80211_ccmp_set_key(void *key, int len, u8 * seq, void *priv) 391static int lib80211_ccmp_set_key(void *key, int len, u8 * seq, void *priv)
392{ 392{
393 struct ieee80211_ccmp_data *data = priv; 393 struct lib80211_ccmp_data *data = priv;
394 int keyidx; 394 int keyidx;
395 struct crypto_cipher *tfm = data->tfm; 395 struct crypto_cipher *tfm = data->tfm;
396 396
@@ -418,9 +418,9 @@ static int ieee80211_ccmp_set_key(void *key, int len, u8 * seq, void *priv)
418 return 0; 418 return 0;
419} 419}
420 420
421static int ieee80211_ccmp_get_key(void *key, int len, u8 * seq, void *priv) 421static int lib80211_ccmp_get_key(void *key, int len, u8 * seq, void *priv)
422{ 422{
423 struct ieee80211_ccmp_data *data = priv; 423 struct lib80211_ccmp_data *data = priv;
424 424
425 if (len < CCMP_TK_LEN) 425 if (len < CCMP_TK_LEN)
426 return -1; 426 return -1;
@@ -441,9 +441,9 @@ static int ieee80211_ccmp_get_key(void *key, int len, u8 * seq, void *priv)
441 return CCMP_TK_LEN; 441 return CCMP_TK_LEN;
442} 442}
443 443
444static char *ieee80211_ccmp_print_stats(char *p, void *priv) 444static char *lib80211_ccmp_print_stats(char *p, void *priv)
445{ 445{
446 struct ieee80211_ccmp_data *ccmp = priv; 446 struct lib80211_ccmp_data *ccmp = priv;
447 447
448 p += sprintf(p, "key[%d] alg=CCMP key_set=%d " 448 p += sprintf(p, "key[%d] alg=CCMP key_set=%d "
449 "tx_pn=%02x%02x%02x%02x%02x%02x " 449 "tx_pn=%02x%02x%02x%02x%02x%02x "
@@ -461,32 +461,32 @@ static char *ieee80211_ccmp_print_stats(char *p, void *priv)
461 return p; 461 return p;
462} 462}
463 463
464static struct ieee80211_crypto_ops ieee80211_crypt_ccmp = { 464static struct lib80211_crypto_ops lib80211_crypt_ccmp = {
465 .name = "CCMP", 465 .name = "CCMP",
466 .init = ieee80211_ccmp_init, 466 .init = lib80211_ccmp_init,
467 .deinit = ieee80211_ccmp_deinit, 467 .deinit = lib80211_ccmp_deinit,
468 .build_iv = ieee80211_ccmp_hdr, 468 .build_iv = lib80211_ccmp_hdr,
469 .encrypt_mpdu = ieee80211_ccmp_encrypt, 469 .encrypt_mpdu = lib80211_ccmp_encrypt,
470 .decrypt_mpdu = ieee80211_ccmp_decrypt, 470 .decrypt_mpdu = lib80211_ccmp_decrypt,
471 .encrypt_msdu = NULL, 471 .encrypt_msdu = NULL,
472 .decrypt_msdu = NULL, 472 .decrypt_msdu = NULL,
473 .set_key = ieee80211_ccmp_set_key, 473 .set_key = lib80211_ccmp_set_key,
474 .get_key = ieee80211_ccmp_get_key, 474 .get_key = lib80211_ccmp_get_key,
475 .print_stats = ieee80211_ccmp_print_stats, 475 .print_stats = lib80211_ccmp_print_stats,
476 .extra_mpdu_prefix_len = CCMP_HDR_LEN, 476 .extra_mpdu_prefix_len = CCMP_HDR_LEN,
477 .extra_mpdu_postfix_len = CCMP_MIC_LEN, 477 .extra_mpdu_postfix_len = CCMP_MIC_LEN,
478 .owner = THIS_MODULE, 478 .owner = THIS_MODULE,
479}; 479};
480 480
481static int __init ieee80211_crypto_ccmp_init(void) 481static int __init lib80211_crypto_ccmp_init(void)
482{ 482{
483 return ieee80211_register_crypto_ops(&ieee80211_crypt_ccmp); 483 return lib80211_register_crypto_ops(&lib80211_crypt_ccmp);
484} 484}
485 485
486static void __exit ieee80211_crypto_ccmp_exit(void) 486static void __exit lib80211_crypto_ccmp_exit(void)
487{ 487{
488 ieee80211_unregister_crypto_ops(&ieee80211_crypt_ccmp); 488 lib80211_unregister_crypto_ops(&lib80211_crypt_ccmp);
489} 489}
490 490
491module_init(ieee80211_crypto_ccmp_init); 491module_init(lib80211_crypto_ccmp_init);
492module_exit(ieee80211_crypto_ccmp_exit); 492module_exit(lib80211_crypto_ccmp_exit);
diff --git a/net/ieee80211/ieee80211_crypt_tkip.c b/net/wireless/lib80211_crypt_tkip.c
index d12da1da6328..7e8e22bfed90 100644
--- a/net/ieee80211/ieee80211_crypt_tkip.c
+++ b/net/wireless/lib80211_crypt_tkip.c
@@ -1,7 +1,8 @@
1/* 1/*
2 * Host AP crypt: host-based TKIP encryption implementation for Host AP driver 2 * lib80211 crypt: host-based TKIP encryption implementation for lib80211
3 * 3 *
4 * Copyright (c) 2003-2004, Jouni Malinen <j@w1.fi> 4 * Copyright (c) 2003-2004, Jouni Malinen <j@w1.fi>
5 * Copyright (c) 2008, John W. Linville <linville@tuxdriver.com>
5 * 6 *
6 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as 8 * it under the terms of the GNU General Public License version 2 as
@@ -22,16 +23,20 @@
22#include <linux/if_arp.h> 23#include <linux/if_arp.h>
23#include <asm/string.h> 24#include <asm/string.h>
24 25
25#include <net/ieee80211.h> 26#include <linux/wireless.h>
27#include <linux/ieee80211.h>
28#include <net/iw_handler.h>
26 29
27#include <linux/crypto.h> 30#include <linux/crypto.h>
28#include <linux/crc32.h> 31#include <linux/crc32.h>
29 32
33#include <net/lib80211.h>
34
30MODULE_AUTHOR("Jouni Malinen"); 35MODULE_AUTHOR("Jouni Malinen");
31MODULE_DESCRIPTION("Host AP crypt: TKIP"); 36MODULE_DESCRIPTION("lib80211 crypt: TKIP");
32MODULE_LICENSE("GPL"); 37MODULE_LICENSE("GPL");
33 38
34struct ieee80211_tkip_data { 39struct lib80211_tkip_data {
35#define TKIP_KEY_LEN 32 40#define TKIP_KEY_LEN 32
36 u8 key[TKIP_KEY_LEN]; 41 u8 key[TKIP_KEY_LEN];
37 int key_set; 42 int key_set;
@@ -65,23 +70,23 @@ struct ieee80211_tkip_data {
65 unsigned long flags; 70 unsigned long flags;
66}; 71};
67 72
68static unsigned long ieee80211_tkip_set_flags(unsigned long flags, void *priv) 73static unsigned long lib80211_tkip_set_flags(unsigned long flags, void *priv)
69{ 74{
70 struct ieee80211_tkip_data *_priv = priv; 75 struct lib80211_tkip_data *_priv = priv;
71 unsigned long old_flags = _priv->flags; 76 unsigned long old_flags = _priv->flags;
72 _priv->flags = flags; 77 _priv->flags = flags;
73 return old_flags; 78 return old_flags;
74} 79}
75 80
76static unsigned long ieee80211_tkip_get_flags(void *priv) 81static unsigned long lib80211_tkip_get_flags(void *priv)
77{ 82{
78 struct ieee80211_tkip_data *_priv = priv; 83 struct lib80211_tkip_data *_priv = priv;
79 return _priv->flags; 84 return _priv->flags;
80} 85}
81 86
82static void *ieee80211_tkip_init(int key_idx) 87static void *lib80211_tkip_init(int key_idx)
83{ 88{
84 struct ieee80211_tkip_data *priv; 89 struct lib80211_tkip_data *priv;
85 90
86 priv = kzalloc(sizeof(*priv), GFP_ATOMIC); 91 priv = kzalloc(sizeof(*priv), GFP_ATOMIC);
87 if (priv == NULL) 92 if (priv == NULL)
@@ -92,7 +97,7 @@ static void *ieee80211_tkip_init(int key_idx)
92 priv->tx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0, 97 priv->tx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0,
93 CRYPTO_ALG_ASYNC); 98 CRYPTO_ALG_ASYNC);
94 if (IS_ERR(priv->tx_tfm_arc4)) { 99 if (IS_ERR(priv->tx_tfm_arc4)) {
95 printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate " 100 printk(KERN_DEBUG "lib80211_crypt_tkip: could not allocate "
96 "crypto API arc4\n"); 101 "crypto API arc4\n");
97 priv->tx_tfm_arc4 = NULL; 102 priv->tx_tfm_arc4 = NULL;
98 goto fail; 103 goto fail;
@@ -101,7 +106,7 @@ static void *ieee80211_tkip_init(int key_idx)
101 priv->tx_tfm_michael = crypto_alloc_hash("michael_mic", 0, 106 priv->tx_tfm_michael = crypto_alloc_hash("michael_mic", 0,
102 CRYPTO_ALG_ASYNC); 107 CRYPTO_ALG_ASYNC);
103 if (IS_ERR(priv->tx_tfm_michael)) { 108 if (IS_ERR(priv->tx_tfm_michael)) {
104 printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate " 109 printk(KERN_DEBUG "lib80211_crypt_tkip: could not allocate "
105 "crypto API michael_mic\n"); 110 "crypto API michael_mic\n");
106 priv->tx_tfm_michael = NULL; 111 priv->tx_tfm_michael = NULL;
107 goto fail; 112 goto fail;
@@ -110,7 +115,7 @@ static void *ieee80211_tkip_init(int key_idx)
110 priv->rx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0, 115 priv->rx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0,
111 CRYPTO_ALG_ASYNC); 116 CRYPTO_ALG_ASYNC);
112 if (IS_ERR(priv->rx_tfm_arc4)) { 117 if (IS_ERR(priv->rx_tfm_arc4)) {
113 printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate " 118 printk(KERN_DEBUG "lib80211_crypt_tkip: could not allocate "
114 "crypto API arc4\n"); 119 "crypto API arc4\n");
115 priv->rx_tfm_arc4 = NULL; 120 priv->rx_tfm_arc4 = NULL;
116 goto fail; 121 goto fail;
@@ -119,7 +124,7 @@ static void *ieee80211_tkip_init(int key_idx)
119 priv->rx_tfm_michael = crypto_alloc_hash("michael_mic", 0, 124 priv->rx_tfm_michael = crypto_alloc_hash("michael_mic", 0,
120 CRYPTO_ALG_ASYNC); 125 CRYPTO_ALG_ASYNC);
121 if (IS_ERR(priv->rx_tfm_michael)) { 126 if (IS_ERR(priv->rx_tfm_michael)) {
122 printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate " 127 printk(KERN_DEBUG "lib80211_crypt_tkip: could not allocate "
123 "crypto API michael_mic\n"); 128 "crypto API michael_mic\n");
124 priv->rx_tfm_michael = NULL; 129 priv->rx_tfm_michael = NULL;
125 goto fail; 130 goto fail;
@@ -143,9 +148,9 @@ static void *ieee80211_tkip_init(int key_idx)
143 return NULL; 148 return NULL;
144} 149}
145 150
146static void ieee80211_tkip_deinit(void *priv) 151static void lib80211_tkip_deinit(void *priv)
147{ 152{
148 struct ieee80211_tkip_data *_priv = priv; 153 struct lib80211_tkip_data *_priv = priv;
149 if (_priv) { 154 if (_priv) {
150 if (_priv->tx_tfm_michael) 155 if (_priv->tx_tfm_michael)
151 crypto_free_hash(_priv->tx_tfm_michael); 156 crypto_free_hash(_priv->tx_tfm_michael);
@@ -305,15 +310,15 @@ static void tkip_mixing_phase2(u8 * WEPSeed, const u8 * TK, const u16 * TTAK,
305#endif 310#endif
306} 311}
307 312
308static int ieee80211_tkip_hdr(struct sk_buff *skb, int hdr_len, 313static int lib80211_tkip_hdr(struct sk_buff *skb, int hdr_len,
309 u8 * rc4key, int keylen, void *priv) 314 u8 * rc4key, int keylen, void *priv)
310{ 315{
311 struct ieee80211_tkip_data *tkey = priv; 316 struct lib80211_tkip_data *tkey = priv;
312 int len; 317 int len;
313 u8 *pos; 318 u8 *pos;
314 struct ieee80211_hdr_4addr *hdr; 319 struct ieee80211_hdr *hdr;
315 320
316 hdr = (struct ieee80211_hdr_4addr *)skb->data; 321 hdr = (struct ieee80211_hdr *)skb->data;
317 322
318 if (skb_headroom(skb) < 8 || skb->len < hdr_len) 323 if (skb_headroom(skb) < 8 || skb->len < hdr_len)
319 return -1; 324 return -1;
@@ -351,9 +356,9 @@ static int ieee80211_tkip_hdr(struct sk_buff *skb, int hdr_len,
351 return 8; 356 return 8;
352} 357}
353 358
354static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv) 359static int lib80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
355{ 360{
356 struct ieee80211_tkip_data *tkey = priv; 361 struct lib80211_tkip_data *tkey = priv;
357 struct blkcipher_desc desc = { .tfm = tkey->tx_tfm_arc4 }; 362 struct blkcipher_desc desc = { .tfm = tkey->tx_tfm_arc4 };
358 int len; 363 int len;
359 u8 rc4key[16], *pos, *icv; 364 u8 rc4key[16], *pos, *icv;
@@ -362,8 +367,8 @@ static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
362 367
363 if (tkey->flags & IEEE80211_CRYPTO_TKIP_COUNTERMEASURES) { 368 if (tkey->flags & IEEE80211_CRYPTO_TKIP_COUNTERMEASURES) {
364 if (net_ratelimit()) { 369 if (net_ratelimit()) {
365 struct ieee80211_hdr_4addr *hdr = 370 struct ieee80211_hdr *hdr =
366 (struct ieee80211_hdr_4addr *)skb->data; 371 (struct ieee80211_hdr *)skb->data;
367 printk(KERN_DEBUG ": TKIP countermeasures: dropped " 372 printk(KERN_DEBUG ": TKIP countermeasures: dropped "
368 "TX packet to %pM\n", hdr->addr1); 373 "TX packet to %pM\n", hdr->addr1);
369 } 374 }
@@ -376,7 +381,7 @@ static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
376 len = skb->len - hdr_len; 381 len = skb->len - hdr_len;
377 pos = skb->data + hdr_len; 382 pos = skb->data + hdr_len;
378 383
379 if ((ieee80211_tkip_hdr(skb, hdr_len, rc4key, 16, priv)) < 0) 384 if ((lib80211_tkip_hdr(skb, hdr_len, rc4key, 16, priv)) < 0)
380 return -1; 385 return -1;
381 386
382 icv = skb_put(skb, 4); 387 icv = skb_put(skb, 4);
@@ -405,21 +410,21 @@ static inline int tkip_replay_check(u32 iv32_n, u16 iv16_n,
405 return 0; 410 return 0;
406} 411}
407 412
408static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) 413static int lib80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
409{ 414{
410 struct ieee80211_tkip_data *tkey = priv; 415 struct lib80211_tkip_data *tkey = priv;
411 struct blkcipher_desc desc = { .tfm = tkey->rx_tfm_arc4 }; 416 struct blkcipher_desc desc = { .tfm = tkey->rx_tfm_arc4 };
412 u8 rc4key[16]; 417 u8 rc4key[16];
413 u8 keyidx, *pos; 418 u8 keyidx, *pos;
414 u32 iv32; 419 u32 iv32;
415 u16 iv16; 420 u16 iv16;
416 struct ieee80211_hdr_4addr *hdr; 421 struct ieee80211_hdr *hdr;
417 u8 icv[4]; 422 u8 icv[4];
418 u32 crc; 423 u32 crc;
419 struct scatterlist sg; 424 struct scatterlist sg;
420 int plen; 425 int plen;
421 426
422 hdr = (struct ieee80211_hdr_4addr *)skb->data; 427 hdr = (struct ieee80211_hdr *)skb->data;
423 428
424 if (tkey->flags & IEEE80211_CRYPTO_TKIP_COUNTERMEASURES) { 429 if (tkey->flags & IEEE80211_CRYPTO_TKIP_COUNTERMEASURES) {
425 if (net_ratelimit()) { 430 if (net_ratelimit()) {
@@ -460,8 +465,8 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
460 pos += 8; 465 pos += 8;
461 466
462 if (tkip_replay_check(iv32, iv16, tkey->rx_iv32, tkey->rx_iv16)) { 467 if (tkip_replay_check(iv32, iv16, tkey->rx_iv32, tkey->rx_iv16)) {
463 if (ieee80211_ratelimit_debug(IEEE80211_DL_DROP)) { 468 if (net_ratelimit()) {
464 IEEE80211_DEBUG_DROP("TKIP: replay detected: STA=%pM" 469 printk(KERN_DEBUG "TKIP: replay detected: STA=%pM"
465 " previous TSC %08x%04x received TSC " 470 " previous TSC %08x%04x received TSC "
466 "%08x%04x\n", hdr->addr2, 471 "%08x%04x\n", hdr->addr2,
467 tkey->rx_iv32, tkey->rx_iv16, iv32, iv16); 472 tkey->rx_iv32, tkey->rx_iv16, iv32, iv16);
@@ -500,8 +505,8 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
500 * it needs to be recalculated for the next packet. */ 505 * it needs to be recalculated for the next packet. */
501 tkey->rx_phase1_done = 0; 506 tkey->rx_phase1_done = 0;
502 } 507 }
503 if (ieee80211_ratelimit_debug(IEEE80211_DL_DROP)) { 508 if (net_ratelimit()) {
504 IEEE80211_DEBUG_DROP("TKIP: ICV error detected: STA=" 509 printk(KERN_DEBUG "TKIP: ICV error detected: STA="
505 "%pM\n", hdr->addr2); 510 "%pM\n", hdr->addr2);
506 } 511 }
507 tkey->dot11RSNAStatsTKIPICVErrors++; 512 tkey->dot11RSNAStatsTKIPICVErrors++;
@@ -545,13 +550,11 @@ static int michael_mic(struct crypto_hash *tfm_michael, u8 * key, u8 * hdr,
545 550
546static void michael_mic_hdr(struct sk_buff *skb, u8 * hdr) 551static void michael_mic_hdr(struct sk_buff *skb, u8 * hdr)
547{ 552{
548 struct ieee80211_hdr_4addr *hdr11; 553 struct ieee80211_hdr *hdr11;
549 u16 stype;
550 554
551 hdr11 = (struct ieee80211_hdr_4addr *)skb->data; 555 hdr11 = (struct ieee80211_hdr *)skb->data;
552 stype = WLAN_FC_GET_STYPE(le16_to_cpu(hdr11->frame_ctl));
553 556
554 switch (le16_to_cpu(hdr11->frame_ctl) & 557 switch (le16_to_cpu(hdr11->frame_control) &
555 (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) { 558 (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
556 case IEEE80211_FCTL_TODS: 559 case IEEE80211_FCTL_TODS:
557 memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */ 560 memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
@@ -571,20 +574,19 @@ static void michael_mic_hdr(struct sk_buff *skb, u8 * hdr)
571 break; 574 break;
572 } 575 }
573 576
574 if (stype & IEEE80211_STYPE_QOS_DATA) { 577 if (ieee80211_is_data_qos(hdr11->frame_control)) {
575 const struct ieee80211_hdr_3addrqos *qoshdr = 578 hdr[12] = le16_to_cpu(*ieee80211_get_qos_ctl(hdr11))
576 (struct ieee80211_hdr_3addrqos *)skb->data; 579 & IEEE80211_QOS_CTL_TID_MASK;
577 hdr[12] = le16_to_cpu(qoshdr->qos_ctl) & IEEE80211_QCTL_TID;
578 } else 580 } else
579 hdr[12] = 0; /* priority */ 581 hdr[12] = 0; /* priority */
580 582
581 hdr[13] = hdr[14] = hdr[15] = 0; /* reserved */ 583 hdr[13] = hdr[14] = hdr[15] = 0; /* reserved */
582} 584}
583 585
584static int ieee80211_michael_mic_add(struct sk_buff *skb, int hdr_len, 586static int lib80211_michael_mic_add(struct sk_buff *skb, int hdr_len,
585 void *priv) 587 void *priv)
586{ 588{
587 struct ieee80211_tkip_data *tkey = priv; 589 struct lib80211_tkip_data *tkey = priv;
588 u8 *pos; 590 u8 *pos;
589 591
590 if (skb_tailroom(skb) < 8 || skb->len < hdr_len) { 592 if (skb_tailroom(skb) < 8 || skb->len < hdr_len) {
@@ -603,8 +605,8 @@ static int ieee80211_michael_mic_add(struct sk_buff *skb, int hdr_len,
603 return 0; 605 return 0;
604} 606}
605 607
606static void ieee80211_michael_mic_failure(struct net_device *dev, 608static void lib80211_michael_mic_failure(struct net_device *dev,
607 struct ieee80211_hdr_4addr *hdr, 609 struct ieee80211_hdr *hdr,
608 int keyidx) 610 int keyidx)
609{ 611{
610 union iwreq_data wrqu; 612 union iwreq_data wrqu;
@@ -624,10 +626,10 @@ static void ieee80211_michael_mic_failure(struct net_device *dev,
624 wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu, (char *)&ev); 626 wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu, (char *)&ev);
625} 627}
626 628
627static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx, 629static int lib80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
628 int hdr_len, void *priv) 630 int hdr_len, void *priv)
629{ 631{
630 struct ieee80211_tkip_data *tkey = priv; 632 struct lib80211_tkip_data *tkey = priv;
631 u8 mic[8]; 633 u8 mic[8];
632 634
633 if (!tkey->key_set) 635 if (!tkey->key_set)
@@ -638,14 +640,14 @@ static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
638 skb->data + hdr_len, skb->len - 8 - hdr_len, mic)) 640 skb->data + hdr_len, skb->len - 8 - hdr_len, mic))
639 return -1; 641 return -1;
640 if (memcmp(mic, skb->data + skb->len - 8, 8) != 0) { 642 if (memcmp(mic, skb->data + skb->len - 8, 8) != 0) {
641 struct ieee80211_hdr_4addr *hdr; 643 struct ieee80211_hdr *hdr;
642 hdr = (struct ieee80211_hdr_4addr *)skb->data; 644 hdr = (struct ieee80211_hdr *)skb->data;
643 printk(KERN_DEBUG "%s: Michael MIC verification failed for " 645 printk(KERN_DEBUG "%s: Michael MIC verification failed for "
644 "MSDU from %pM keyidx=%d\n", 646 "MSDU from %pM keyidx=%d\n",
645 skb->dev ? skb->dev->name : "N/A", hdr->addr2, 647 skb->dev ? skb->dev->name : "N/A", hdr->addr2,
646 keyidx); 648 keyidx);
647 if (skb->dev) 649 if (skb->dev)
648 ieee80211_michael_mic_failure(skb->dev, hdr, keyidx); 650 lib80211_michael_mic_failure(skb->dev, hdr, keyidx);
649 tkey->dot11RSNAStatsTKIPLocalMICFailures++; 651 tkey->dot11RSNAStatsTKIPLocalMICFailures++;
650 return -1; 652 return -1;
651 } 653 }
@@ -660,9 +662,9 @@ static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
660 return 0; 662 return 0;
661} 663}
662 664
663static int ieee80211_tkip_set_key(void *key, int len, u8 * seq, void *priv) 665static int lib80211_tkip_set_key(void *key, int len, u8 * seq, void *priv)
664{ 666{
665 struct ieee80211_tkip_data *tkey = priv; 667 struct lib80211_tkip_data *tkey = priv;
666 int keyidx; 668 int keyidx;
667 struct crypto_hash *tfm = tkey->tx_tfm_michael; 669 struct crypto_hash *tfm = tkey->tx_tfm_michael;
668 struct crypto_blkcipher *tfm2 = tkey->tx_tfm_arc4; 670 struct crypto_blkcipher *tfm2 = tkey->tx_tfm_arc4;
@@ -693,9 +695,9 @@ static int ieee80211_tkip_set_key(void *key, int len, u8 * seq, void *priv)
693 return 0; 695 return 0;
694} 696}
695 697
696static int ieee80211_tkip_get_key(void *key, int len, u8 * seq, void *priv) 698static int lib80211_tkip_get_key(void *key, int len, u8 * seq, void *priv)
697{ 699{
698 struct ieee80211_tkip_data *tkey = priv; 700 struct lib80211_tkip_data *tkey = priv;
699 701
700 if (len < TKIP_KEY_LEN) 702 if (len < TKIP_KEY_LEN)
701 return -1; 703 return -1;
@@ -722,9 +724,9 @@ static int ieee80211_tkip_get_key(void *key, int len, u8 * seq, void *priv)
722 return TKIP_KEY_LEN; 724 return TKIP_KEY_LEN;
723} 725}
724 726
725static char *ieee80211_tkip_print_stats(char *p, void *priv) 727static char *lib80211_tkip_print_stats(char *p, void *priv)
726{ 728{
727 struct ieee80211_tkip_data *tkip = priv; 729 struct lib80211_tkip_data *tkip = priv;
728 p += sprintf(p, "key[%d] alg=TKIP key_set=%d " 730 p += sprintf(p, "key[%d] alg=TKIP key_set=%d "
729 "tx_pn=%02x%02x%02x%02x%02x%02x " 731 "tx_pn=%02x%02x%02x%02x%02x%02x "
730 "rx_pn=%02x%02x%02x%02x%02x%02x " 732 "rx_pn=%02x%02x%02x%02x%02x%02x "
@@ -748,35 +750,35 @@ static char *ieee80211_tkip_print_stats(char *p, void *priv)
748 return p; 750 return p;
749} 751}
750 752
751static struct ieee80211_crypto_ops ieee80211_crypt_tkip = { 753static struct lib80211_crypto_ops lib80211_crypt_tkip = {
752 .name = "TKIP", 754 .name = "TKIP",
753 .init = ieee80211_tkip_init, 755 .init = lib80211_tkip_init,
754 .deinit = ieee80211_tkip_deinit, 756 .deinit = lib80211_tkip_deinit,
755 .build_iv = ieee80211_tkip_hdr, 757 .build_iv = lib80211_tkip_hdr,
756 .encrypt_mpdu = ieee80211_tkip_encrypt, 758 .encrypt_mpdu = lib80211_tkip_encrypt,
757 .decrypt_mpdu = ieee80211_tkip_decrypt, 759 .decrypt_mpdu = lib80211_tkip_decrypt,
758 .encrypt_msdu = ieee80211_michael_mic_add, 760 .encrypt_msdu = lib80211_michael_mic_add,
759 .decrypt_msdu = ieee80211_michael_mic_verify, 761 .decrypt_msdu = lib80211_michael_mic_verify,
760 .set_key = ieee80211_tkip_set_key, 762 .set_key = lib80211_tkip_set_key,
761 .get_key = ieee80211_tkip_get_key, 763 .get_key = lib80211_tkip_get_key,
762 .print_stats = ieee80211_tkip_print_stats, 764 .print_stats = lib80211_tkip_print_stats,
763 .extra_mpdu_prefix_len = 4 + 4, /* IV + ExtIV */ 765 .extra_mpdu_prefix_len = 4 + 4, /* IV + ExtIV */
764 .extra_mpdu_postfix_len = 4, /* ICV */ 766 .extra_mpdu_postfix_len = 4, /* ICV */
765 .extra_msdu_postfix_len = 8, /* MIC */ 767 .extra_msdu_postfix_len = 8, /* MIC */
766 .get_flags = ieee80211_tkip_get_flags, 768 .get_flags = lib80211_tkip_get_flags,
767 .set_flags = ieee80211_tkip_set_flags, 769 .set_flags = lib80211_tkip_set_flags,
768 .owner = THIS_MODULE, 770 .owner = THIS_MODULE,
769}; 771};
770 772
771static int __init ieee80211_crypto_tkip_init(void) 773static int __init lib80211_crypto_tkip_init(void)
772{ 774{
773 return ieee80211_register_crypto_ops(&ieee80211_crypt_tkip); 775 return lib80211_register_crypto_ops(&lib80211_crypt_tkip);
774} 776}
775 777
776static void __exit ieee80211_crypto_tkip_exit(void) 778static void __exit lib80211_crypto_tkip_exit(void)
777{ 779{
778 ieee80211_unregister_crypto_ops(&ieee80211_crypt_tkip); 780 lib80211_unregister_crypto_ops(&lib80211_crypt_tkip);
779} 781}
780 782
781module_init(ieee80211_crypto_tkip_init); 783module_init(lib80211_crypto_tkip_init);
782module_exit(ieee80211_crypto_tkip_exit); 784module_exit(lib80211_crypto_tkip_exit);
diff --git a/net/ieee80211/ieee80211_crypt_wep.c b/net/wireless/lib80211_crypt_wep.c
index 3fa30c40779f..6d41e05ca33b 100644
--- a/net/ieee80211/ieee80211_crypt_wep.c
+++ b/net/wireless/lib80211_crypt_wep.c
@@ -1,7 +1,8 @@
1/* 1/*
2 * Host AP crypt: host-based WEP encryption implementation for Host AP driver 2 * lib80211 crypt: host-based WEP encryption implementation for lib80211
3 * 3 *
4 * Copyright (c) 2002-2004, Jouni Malinen <j@w1.fi> 4 * Copyright (c) 2002-2004, Jouni Malinen <j@w1.fi>
5 * Copyright (c) 2008, John W. Linville <linville@tuxdriver.com>
5 * 6 *
6 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as 8 * it under the terms of the GNU General Public License version 2 as
@@ -19,16 +20,16 @@
19#include <linux/mm.h> 20#include <linux/mm.h>
20#include <asm/string.h> 21#include <asm/string.h>
21 22
22#include <net/ieee80211.h> 23#include <net/lib80211.h>
23 24
24#include <linux/crypto.h> 25#include <linux/crypto.h>
25#include <linux/crc32.h> 26#include <linux/crc32.h>
26 27
27MODULE_AUTHOR("Jouni Malinen"); 28MODULE_AUTHOR("Jouni Malinen");
28MODULE_DESCRIPTION("Host AP crypt: WEP"); 29MODULE_DESCRIPTION("lib80211 crypt: WEP");
29MODULE_LICENSE("GPL"); 30MODULE_LICENSE("GPL");
30 31
31struct prism2_wep_data { 32struct lib80211_wep_data {
32 u32 iv; 33 u32 iv;
33#define WEP_KEY_LEN 13 34#define WEP_KEY_LEN 13
34 u8 key[WEP_KEY_LEN + 1]; 35 u8 key[WEP_KEY_LEN + 1];
@@ -38,9 +39,9 @@ struct prism2_wep_data {
38 struct crypto_blkcipher *rx_tfm; 39 struct crypto_blkcipher *rx_tfm;
39}; 40};
40 41
41static void *prism2_wep_init(int keyidx) 42static void *lib80211_wep_init(int keyidx)
42{ 43{
43 struct prism2_wep_data *priv; 44 struct lib80211_wep_data *priv;
44 45
45 priv = kzalloc(sizeof(*priv), GFP_ATOMIC); 46 priv = kzalloc(sizeof(*priv), GFP_ATOMIC);
46 if (priv == NULL) 47 if (priv == NULL)
@@ -49,7 +50,7 @@ static void *prism2_wep_init(int keyidx)
49 50
50 priv->tx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC); 51 priv->tx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC);
51 if (IS_ERR(priv->tx_tfm)) { 52 if (IS_ERR(priv->tx_tfm)) {
52 printk(KERN_DEBUG "ieee80211_crypt_wep: could not allocate " 53 printk(KERN_DEBUG "lib80211_crypt_wep: could not allocate "
53 "crypto API arc4\n"); 54 "crypto API arc4\n");
54 priv->tx_tfm = NULL; 55 priv->tx_tfm = NULL;
55 goto fail; 56 goto fail;
@@ -57,7 +58,7 @@ static void *prism2_wep_init(int keyidx)
57 58
58 priv->rx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC); 59 priv->rx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC);
59 if (IS_ERR(priv->rx_tfm)) { 60 if (IS_ERR(priv->rx_tfm)) {
60 printk(KERN_DEBUG "ieee80211_crypt_wep: could not allocate " 61 printk(KERN_DEBUG "lib80211_crypt_wep: could not allocate "
61 "crypto API arc4\n"); 62 "crypto API arc4\n");
62 priv->rx_tfm = NULL; 63 priv->rx_tfm = NULL;
63 goto fail; 64 goto fail;
@@ -78,9 +79,9 @@ static void *prism2_wep_init(int keyidx)
78 return NULL; 79 return NULL;
79} 80}
80 81
81static void prism2_wep_deinit(void *priv) 82static void lib80211_wep_deinit(void *priv)
82{ 83{
83 struct prism2_wep_data *_priv = priv; 84 struct lib80211_wep_data *_priv = priv;
84 if (_priv) { 85 if (_priv) {
85 if (_priv->tx_tfm) 86 if (_priv->tx_tfm)
86 crypto_free_blkcipher(_priv->tx_tfm); 87 crypto_free_blkcipher(_priv->tx_tfm);
@@ -91,10 +92,10 @@ static void prism2_wep_deinit(void *priv)
91} 92}
92 93
93/* Add WEP IV/key info to a frame that has at least 4 bytes of headroom */ 94/* Add WEP IV/key info to a frame that has at least 4 bytes of headroom */
94static int prism2_wep_build_iv(struct sk_buff *skb, int hdr_len, 95static int lib80211_wep_build_iv(struct sk_buff *skb, int hdr_len,
95 u8 *key, int keylen, void *priv) 96 u8 *key, int keylen, void *priv)
96{ 97{
97 struct prism2_wep_data *wep = priv; 98 struct lib80211_wep_data *wep = priv;
98 u32 klen, len; 99 u32 klen, len;
99 u8 *pos; 100 u8 *pos;
100 101
@@ -134,21 +135,21 @@ static int prism2_wep_build_iv(struct sk_buff *skb, int hdr_len,
134 * 135 *
135 * WEP frame payload: IV + TX key idx, RC4(data), ICV = RC4(CRC32(data)) 136 * WEP frame payload: IV + TX key idx, RC4(data), ICV = RC4(CRC32(data))
136 */ 137 */
137static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv) 138static int lib80211_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
138{ 139{
139 struct prism2_wep_data *wep = priv; 140 struct lib80211_wep_data *wep = priv;
140 struct blkcipher_desc desc = { .tfm = wep->tx_tfm }; 141 struct blkcipher_desc desc = { .tfm = wep->tx_tfm };
141 u32 crc, klen, len; 142 u32 crc, klen, len;
142 u8 *pos, *icv; 143 u8 *pos, *icv;
143 struct scatterlist sg; 144 struct scatterlist sg;
144 u8 key[WEP_KEY_LEN + 3]; 145 u8 key[WEP_KEY_LEN + 3];
145 146
146 /* other checks are in prism2_wep_build_iv */ 147 /* other checks are in lib80211_wep_build_iv */
147 if (skb_tailroom(skb) < 4) 148 if (skb_tailroom(skb) < 4)
148 return -1; 149 return -1;
149 150
150 /* add the IV to the frame */ 151 /* add the IV to the frame */
151 if (prism2_wep_build_iv(skb, hdr_len, NULL, 0, priv)) 152 if (lib80211_wep_build_iv(skb, hdr_len, NULL, 0, priv))
152 return -1; 153 return -1;
153 154
154 /* Copy the IV into the first 3 bytes of the key */ 155 /* Copy the IV into the first 3 bytes of the key */
@@ -181,9 +182,9 @@ static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
181 * Returns 0 if frame was decrypted successfully and ICV was correct and -1 on 182 * Returns 0 if frame was decrypted successfully and ICV was correct and -1 on
182 * failure. If frame is OK, IV and ICV will be removed. 183 * failure. If frame is OK, IV and ICV will be removed.
183 */ 184 */
184static int prism2_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv) 185static int lib80211_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
185{ 186{
186 struct prism2_wep_data *wep = priv; 187 struct lib80211_wep_data *wep = priv;
187 struct blkcipher_desc desc = { .tfm = wep->rx_tfm }; 188 struct blkcipher_desc desc = { .tfm = wep->rx_tfm };
188 u32 crc, klen, plen; 189 u32 crc, klen, plen;
189 u8 key[WEP_KEY_LEN + 3]; 190 u8 key[WEP_KEY_LEN + 3];
@@ -232,9 +233,9 @@ static int prism2_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
232 return 0; 233 return 0;
233} 234}
234 235
235static int prism2_wep_set_key(void *key, int len, u8 * seq, void *priv) 236static int lib80211_wep_set_key(void *key, int len, u8 * seq, void *priv)
236{ 237{
237 struct prism2_wep_data *wep = priv; 238 struct lib80211_wep_data *wep = priv;
238 239
239 if (len < 0 || len > WEP_KEY_LEN) 240 if (len < 0 || len > WEP_KEY_LEN)
240 return -1; 241 return -1;
@@ -245,9 +246,9 @@ static int prism2_wep_set_key(void *key, int len, u8 * seq, void *priv)
245 return 0; 246 return 0;
246} 247}
247 248
248static int prism2_wep_get_key(void *key, int len, u8 * seq, void *priv) 249static int lib80211_wep_get_key(void *key, int len, u8 * seq, void *priv)
249{ 250{
250 struct prism2_wep_data *wep = priv; 251 struct lib80211_wep_data *wep = priv;
251 252
252 if (len < wep->key_len) 253 if (len < wep->key_len)
253 return -1; 254 return -1;
@@ -257,39 +258,39 @@ static int prism2_wep_get_key(void *key, int len, u8 * seq, void *priv)
257 return wep->key_len; 258 return wep->key_len;
258} 259}
259 260
260static char *prism2_wep_print_stats(char *p, void *priv) 261static char *lib80211_wep_print_stats(char *p, void *priv)
261{ 262{
262 struct prism2_wep_data *wep = priv; 263 struct lib80211_wep_data *wep = priv;
263 p += sprintf(p, "key[%d] alg=WEP len=%d\n", wep->key_idx, wep->key_len); 264 p += sprintf(p, "key[%d] alg=WEP len=%d\n", wep->key_idx, wep->key_len);
264 return p; 265 return p;
265} 266}
266 267
267static struct ieee80211_crypto_ops ieee80211_crypt_wep = { 268static struct lib80211_crypto_ops lib80211_crypt_wep = {
268 .name = "WEP", 269 .name = "WEP",
269 .init = prism2_wep_init, 270 .init = lib80211_wep_init,
270 .deinit = prism2_wep_deinit, 271 .deinit = lib80211_wep_deinit,
271 .build_iv = prism2_wep_build_iv, 272 .build_iv = lib80211_wep_build_iv,
272 .encrypt_mpdu = prism2_wep_encrypt, 273 .encrypt_mpdu = lib80211_wep_encrypt,
273 .decrypt_mpdu = prism2_wep_decrypt, 274 .decrypt_mpdu = lib80211_wep_decrypt,
274 .encrypt_msdu = NULL, 275 .encrypt_msdu = NULL,
275 .decrypt_msdu = NULL, 276 .decrypt_msdu = NULL,
276 .set_key = prism2_wep_set_key, 277 .set_key = lib80211_wep_set_key,
277 .get_key = prism2_wep_get_key, 278 .get_key = lib80211_wep_get_key,
278 .print_stats = prism2_wep_print_stats, 279 .print_stats = lib80211_wep_print_stats,
279 .extra_mpdu_prefix_len = 4, /* IV */ 280 .extra_mpdu_prefix_len = 4, /* IV */
280 .extra_mpdu_postfix_len = 4, /* ICV */ 281 .extra_mpdu_postfix_len = 4, /* ICV */
281 .owner = THIS_MODULE, 282 .owner = THIS_MODULE,
282}; 283};
283 284
284static int __init ieee80211_crypto_wep_init(void) 285static int __init lib80211_crypto_wep_init(void)
285{ 286{
286 return ieee80211_register_crypto_ops(&ieee80211_crypt_wep); 287 return lib80211_register_crypto_ops(&lib80211_crypt_wep);
287} 288}
288 289
289static void __exit ieee80211_crypto_wep_exit(void) 290static void __exit lib80211_crypto_wep_exit(void)
290{ 291{
291 ieee80211_unregister_crypto_ops(&ieee80211_crypt_wep); 292 lib80211_unregister_crypto_ops(&lib80211_crypt_wep);
292} 293}
293 294
294module_init(ieee80211_crypto_wep_init); 295module_init(lib80211_crypto_wep_init);
295module_exit(ieee80211_crypto_wep_exit); 296module_exit(lib80211_crypto_wep_exit);
diff --git a/net/wireless/sysfs.c b/net/wireless/sysfs.c
index 29f820e18251..79a382877641 100644
--- a/net/wireless/sysfs.c
+++ b/net/wireless/sysfs.c
@@ -23,25 +23,20 @@ static inline struct cfg80211_registered_device *dev_to_rdev(
23 return container_of(dev, struct cfg80211_registered_device, wiphy.dev); 23 return container_of(dev, struct cfg80211_registered_device, wiphy.dev);
24} 24}
25 25
26static ssize_t _show_index(struct device *dev, struct device_attribute *attr, 26#define SHOW_FMT(name, fmt, member) \
27 char *buf) 27static ssize_t name ## _show(struct device *dev, \
28{ 28 struct device_attribute *attr, \
29 return sprintf(buf, "%d\n", dev_to_rdev(dev)->idx); 29 char *buf) \
30{ \
31 return sprintf(buf, fmt "\n", dev_to_rdev(dev)->member); \
30} 32}
31 33
32static ssize_t _show_permaddr(struct device *dev, 34SHOW_FMT(index, "%d", idx);
33 struct device_attribute *attr, 35SHOW_FMT(macaddress, "%pM", wiphy.perm_addr);
34 char *buf)
35{
36 unsigned char *addr = dev_to_rdev(dev)->wiphy.perm_addr;
37
38 return sprintf(buf, "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
39 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
40}
41 36
42static struct device_attribute ieee80211_dev_attrs[] = { 37static struct device_attribute ieee80211_dev_attrs[] = {
43 __ATTR(index, S_IRUGO, _show_index, NULL), 38 __ATTR_RO(index),
44 __ATTR(macaddress, S_IRUGO, _show_permaddr, NULL), 39 __ATTR_RO(macaddress),
45 {} 40 {}
46}; 41};
47 42