diff options
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 | |||
50 | care of WPA2-PSK authentication. In addition, hostapd is also | 50 | care of WPA2-PSK authentication. In addition, hostapd is also |
51 | processing access point side of association. | 51 | processing access point side of association. |
52 | 52 | ||
53 | Please note that the current Linux kernel does not enable AP mode, so a | ||
54 | simple patch is needed to enable AP mode selection: | ||
55 | http://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 |
67 | wpa_supplicant -Dwext -iwlan1 -c wpa_supplicant.conf | 63 | wpa_supplicant -Dwext -iwlan1 -c wpa_supplicant.conf |
64 | |||
65 | |||
66 | More test cases are available in hostap.git: | ||
67 | git://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 | |||
3608 | W: http://www.linux-ax25.org/ | 3608 | W: http://www.linux-ax25.org/ |
3609 | S: Maintained | 3609 | S: Maintained |
3610 | 3610 | ||
3611 | RTL818X WIRELESS DRIVER | 3611 | RTL8180 WIRELESS DRIVER |
3612 | P: Michael Wu | 3612 | P: John W. Linville |
3613 | M: flamingice@sourmilk.net | 3613 | M: linville@tuxdriver.com |
3614 | P: Andrea Merello | ||
3615 | M: andreamrl@tiscali.it | ||
3616 | L: linux-wireless@vger.kernel.org | 3614 | L: linux-wireless@vger.kernel.org |
3617 | W: http://linuxwireless.org/ | 3615 | W: http://linuxwireless.org/ |
3618 | T: git kernel.org:/pub/scm/linux/kernel/git/mwu/mac80211-drivers.git | 3616 | T: git kernel.org:/pub/scm/linux/kernel/git/linville/wireless-testing.git |
3619 | S: Maintained | 3617 | S: Maintained |
3618 | |||
3619 | RTL8187 WIRELESS DRIVER | ||
3620 | P: Herton Ronaldo Krzesinski | ||
3621 | M: herton@mandriva.com.br | ||
3622 | P: Hin-Tak Leung | ||
3623 | M htl10@users.sourceforge.net | ||
3624 | P: Larry Finger | ||
3625 | M: Larry.Finger@lwfinger.net | ||
3626 | L: linux-wireless@vger.kernel.org | ||
3627 | W: http://linuxwireless.org/ | ||
3628 | T: git kernel.org:/pub/scm/linux/kernel/git/linville/wireless-testing.git | ||
3629 | S: Maintained | ||
3620 | 3630 | ||
3621 | S3 SAVAGE FRAMEBUFFER DRIVER | 3631 | S3 SAVAGE FRAMEBUFFER DRIVER |
3622 | P: Antonino Daplas | 3632 | P: 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 | ||
126 | config 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 | |||
158 | config 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 | |||
167 | config 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 | |||
184 | config 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 | |||
216 | config 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 | |||
225 | config IPW2200_RADIOTAP | ||
226 | bool "Enable radiotap format 802.11 raw packet support" | ||
227 | depends on IPW2200_MONITOR | ||
228 | |||
229 | config 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 | |||
253 | config IPW2200_QOS | ||
254 | bool "Enable QoS support" | ||
255 | depends on IPW2200 && EXPERIMENTAL | ||
256 | |||
257 | config 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 | |||
270 | config LIBERTAS | 126 | config 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 | |||
712 | source "drivers/net/wireless/p54/Kconfig" | 568 | source "drivers/net/wireless/p54/Kconfig" |
713 | source "drivers/net/wireless/ath5k/Kconfig" | 569 | source "drivers/net/wireless/ath5k/Kconfig" |
714 | source "drivers/net/wireless/ath9k/Kconfig" | 570 | source "drivers/net/wireless/ath9k/Kconfig" |
571 | source "drivers/net/wireless/ipw2x00/Kconfig" | ||
715 | source "drivers/net/wireless/iwlwifi/Kconfig" | 572 | source "drivers/net/wireless/iwlwifi/Kconfig" |
716 | source "drivers/net/wireless/hostap/Kconfig" | 573 | source "drivers/net/wireless/hostap/Kconfig" |
717 | source "drivers/net/wireless/b43/Kconfig" | 574 | source "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 | ||
5 | obj-$(CONFIG_IPW2100) += ipw2100.o | 5 | obj-$(CONFIG_IPW2100) += ipw2x00/ |
6 | 6 | obj-$(CONFIG_IPW2200) += ipw2x00/ | |
7 | obj-$(CONFIG_IPW2200) += ipw2200.o | ||
8 | 7 | ||
9 | obj-$(CONFIG_STRIP) += strip.o | 8 | obj-$(CONFIG_STRIP) += strip.o |
10 | obj-$(CONFIG_ARLAN) += arlan.o | 9 | obj-$(CONFIG_ARLAN) += arlan.o |
@@ -31,6 +30,8 @@ obj-$(CONFIG_HOSTAP) += hostap/ | |||
31 | obj-$(CONFIG_B43) += b43/ | 30 | obj-$(CONFIG_B43) += b43/ |
32 | obj-$(CONFIG_B43LEGACY) += b43legacy/ | 31 | obj-$(CONFIG_B43LEGACY) += b43legacy/ |
33 | obj-$(CONFIG_ZD1211RW) += zd1211rw/ | 32 | obj-$(CONFIG_ZD1211RW) += zd1211rw/ |
33 | obj-$(CONFIG_RTL8180) += rtl818x/ | ||
34 | obj-$(CONFIG_RTL8187) += rtl818x/ | ||
34 | 35 | ||
35 | # 16-bit wireless PCMCIA client drivers | 36 | # 16-bit wireless PCMCIA client drivers |
36 | obj-$(CONFIG_PCMCIA_RAYCS) += ray_cs.o | 37 | obj-$(CONFIG_PCMCIA_RAYCS) += ray_cs.o |
@@ -43,12 +44,6 @@ obj-$(CONFIG_LIBERTAS) += libertas/ | |||
43 | 44 | ||
44 | obj-$(CONFIG_LIBERTAS_THINFIRM) += libertas_tf/ | 45 | obj-$(CONFIG_LIBERTAS_THINFIRM) += libertas_tf/ |
45 | 46 | ||
46 | rtl8180-objs := rtl8180_dev.o rtl8180_rtl8225.o rtl8180_sa2400.o rtl8180_max2820.o rtl8180_grf5101.o | ||
47 | rtl8187-objs := rtl8187_dev.o rtl8187_rtl8225.o | ||
48 | |||
49 | obj-$(CONFIG_RTL8180) += rtl8180.o | ||
50 | obj-$(CONFIG_RTL8187) += rtl8187.o | ||
51 | |||
52 | obj-$(CONFIG_ADM8211) += adm8211.o | 47 | obj-$(CONFIG_ADM8211) += adm8211.o |
53 | 48 | ||
54 | obj-$(CONFIG_IWLWIFI) += iwlwifi/ | 49 | obj-$(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 | ||
1523 | static 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 | |||
1535 | static 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 | |||
1550 | static const char * | ||
1551 | ath_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 | |||
1568 | static const char * | ||
1569 | ath_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 | |||
1522 | static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) | 1582 | static 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, | |||
576 | static void b43legacy_short_slot_timing_enable(struct b43legacy_wldev *dev) | 576 | static 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 | ||
582 | static void b43legacy_short_slot_timing_disable(struct b43legacy_wldev *dev) | 581 | static 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 | ||
2653 | static 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 | |||
2698 | static 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 | |||
2665 | static void b43legacy_op_configure_filter(struct ieee80211_hw *hw, | 2751 | static 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); | |||
63 | int ap_control_kick_mac(struct ap_data *ap, struct net_device *dev, u8 *mac); | 63 | int ap_control_kick_mac(struct ap_data *ap, struct net_device *dev, u8 *mac); |
64 | void ap_control_kickall(struct ap_data *ap); | 64 | void ap_control_kickall(struct ap_data *ap); |
65 | void * ap_crypt_get_ptrs(struct ap_data *ap, u8 *addr, int permanent, | 65 | void * ap_crypt_get_ptrs(struct ap_data *ap, u8 *addr, int permanent, |
66 | struct ieee80211_crypt_data ***crypt); | 66 | struct lib80211_crypt_data ***crypt); |
67 | int prism2_ap_get_sta_qual(local_info_t *local, struct sockaddr addr[], | 67 | int 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 | ||
7 | struct hostap_ieee80211_mgmt { | 7 | struct 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) */ |
650 | static int | 650 | static int |
651 | hostap_rx_frame_decrypt(local_info_t *local, struct sk_buff *skb, | 651 | hostap_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) */ |
688 | static int | 688 | static int |
689 | hostap_rx_frame_decrypt_msdu(local_info_t *local, struct sk_buff *skb, | 689 | hostap_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 */ |
308 | static struct sk_buff * hostap_tx_encrypt(struct sk_buff *skb, | 308 | static 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 | ||
1207 | static void ap_crypt_init(struct ap_data *ap) | 1207 | static 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) */ |
3066 | int hostap_handle_sta_crypto(local_info_t *local, | 3066 | int 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 | ||
3215 | void * ap_crypt_get_ptrs(struct ap_data *ap, u8 *addr, int permanent, | 3215 | void * 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 { | |||
229 | struct hostap_tx_data { | 229 | struct 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 | }; |
235 | ap_tx_ret hostap_handle_sta_tx(local_info_t *local, struct hostap_tx_data *tx); | 235 | ap_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); |
246 | int hostap_handle_sta_crypto(local_info_t *local, struct ieee80211_hdr_4addr *hdr, | 246 | int 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); |
249 | int hostap_is_sta_assoc(struct ap_data *ap, u8 *sta_addr); | 249 | int hostap_is_sta_assoc(struct ap_data *ap, u8 *sta_addr); |
250 | int hostap_is_sta_authorized(struct ap_data *ap, u8 *sta_addr); | 250 | int 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 | ||
2791 | static 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 | |||
2812 | static 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 | |||
2830 | static void hostap_passive_scan(unsigned long data) | 2791 | static 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 | ||
119 | static 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 | |||
145 | static int prism2_ioctl_siwencode(struct net_device *dev, | 119 | static 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 | |||
5 | config 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 | |||
38 | config 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 | |||
47 | config 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 | |||
64 | config 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 | |||
97 | config 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 | |||
106 | config IPW2200_RADIOTAP | ||
107 | bool "Enable radiotap format 802.11 raw packet support" | ||
108 | depends on IPW2200_MONITOR | ||
109 | |||
110 | config 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 | |||
134 | config IPW2200_QOS | ||
135 | bool "Enable QoS support" | ||
136 | depends on IPW2200 && EXPERIMENTAL | ||
137 | |||
138 | config 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 | |||
151 | config 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 | |||
170 | config 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 | |||
5 | obj-$(CONFIG_IPW2100) += ipw2100.o | ||
6 | obj-$(CONFIG_IPW2200) += ipw2200.o | ||
7 | |||
8 | obj-$(CONFIG_LIBIPW) += libipw.o | ||
9 | libipw-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 */ |
269 | static int | 269 | static int |
270 | ieee80211_rx_frame_decrypt(struct ieee80211_device *ieee, struct sk_buff *skb, | 270 | ieee80211_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, | |||
300 | static int | 300 | static int |
301 | ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device *ieee, | 301 | ieee80211_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) | |||
152 | static int ieee80211_encrypt_fragment(struct ieee80211_device *ieee, | 152 | static 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 | |||
5 | iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o | 5 | iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o |
6 | iwlcore-$(CONFIG_IWLWIFI_LEDS) += iwl-led.o | 6 | iwlcore-$(CONFIG_IWLWIFI_LEDS) += iwl-led.o |
7 | iwlcore-$(CONFIG_IWLWIFI_RFKILL) += iwl-rfkill.o | 7 | iwlcore-$(CONFIG_IWLWIFI_RFKILL) += iwl-rfkill.o |
8 | iwlcore-$(CONFIG_IWLAGN_SPECTRUM_MEASUREMENT) += iwl-spectrum.o | ||
8 | 9 | ||
9 | obj-$(CONFIG_IWLAGN) += iwlagn.o | 10 | obj-$(CONFIG_IWLAGN) += iwlagn.o |
10 | iwlagn-objs := iwl-agn.o iwl-agn-rs.o | 11 | iwlagn-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 | |||
825 | static 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 | */ | ||
839 | struct 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 | */ | ||
873 | struct 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 | */ |
899 | struct iwl4965_schedq_bc_tbl { | 841 | struct 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 | */ | ||
928 | struct 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 | ||
1634 | static 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 | |||
1640 | static 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 | |||
1655 | static 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 | ||
2305 | static struct iwl_lib_ops iwl4965_lib = { | 2276 | static 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 | */ |
93 | struct iwl5000_schedq_bc_tbl { | 93 | struct 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 | */ | ||
102 | struct 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 | ||
856 | static 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 | |||
871 | static 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 | |||
880 | static 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 | ||
929 | static void iwl5000_txq_inval_byte_cnt_tbl(struct iwl_priv *priv, | 899 | static 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 | ||
1459 | static struct iwl_lib_ops iwl5000_lib = { | 1428 | static 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 | |||
889 | static 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 | |||
908 | static __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 | |||
927 | static 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 | ||
1075 | static 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 | |||
1093 | static void iwl_rx_pm_sleep_notif(struct iwl_priv *priv, | 943 | static 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 */ | ||
1855 | static 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 */ | ||
2934 | static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb); | ||
2935 | 2787 | ||
2936 | static int iwl_mac_config_interface(struct ieee80211_hw *hw, | 2788 | static 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, | |||
3766 | static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, show_filter_flags, | 3616 | static 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 | |||
3771 | static 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 | |||
3803 | static 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, ¶ms, type); | ||
3834 | |||
3835 | return count; | ||
3836 | } | ||
3837 | |||
3838 | static DEVICE_ATTR(measurement, S_IRUSR | S_IWUSR, | ||
3839 | show_measurement, store_measurement); | ||
3840 | #endif /* CONFIG_IWLAGN_SPECTRUM_MEASUREMENT */ | ||
3841 | |||
3842 | static ssize_t store_retry_rate(struct device *d, | 3619 | static 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 | ||
33 | struct 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 | } |
191 | EXPORT_SYMBOL(iwl_hw_detect); | 190 | EXPORT_SYMBOL(iwl_hw_detect); |
192 | 191 | ||
193 | /* Tell nic where to find the "keep warm" buffer */ | ||
194 | int 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); | ||
207 | out: | ||
208 | spin_unlock_irqrestore(&priv->lock, flags); | ||
209 | return ret; | ||
210 | } | ||
211 | |||
212 | int 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 | */ | ||
228 | void 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 | |||
239 | int iwl_hw_nic_init(struct iwl_priv *priv) | 192 | int 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 { | |||
102 | struct iwl_lib_ops { | 102 | struct 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); | |||
198 | int iwl_set_hw_params(struct iwl_priv *priv); | 194 | int iwl_set_hw_params(struct iwl_priv *priv); |
199 | int iwl_init_drv(struct iwl_priv *priv); | 195 | int iwl_init_drv(struct iwl_priv *priv); |
200 | void iwl_uninit_drv(struct iwl_priv *priv); | 196 | void iwl_uninit_drv(struct iwl_priv *priv); |
201 | /* "keep warm" functions */ | ||
202 | int iwl_kw_init(struct iwl_priv *priv); | ||
203 | int iwl_kw_alloc(struct iwl_priv *priv); | ||
204 | void 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); | |||
297 | int iwl_calib_set(struct iwl_calib_result *res, const u8 *buf, int len); | 289 | int iwl_calib_set(struct iwl_calib_result *res, const u8 *buf, int len); |
298 | void iwl_calib_free_results(struct iwl_priv *priv); | 290 | void 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 | ||
296 | void iwl_setup_spectrum_handlers(struct iwl_priv *priv); | ||
297 | #else | ||
298 | static 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) \ | ||
44 | do { \ | ||
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 |
44 | struct iwl_debugfs { | 51 | struct 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...) |
80 | static 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 | */ |
525 | struct iwl_hw_params { | 526 | struct 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) | |||
605 | struct iwl_priv; | 607 | struct iwl_priv; |
606 | 608 | ||
607 | 609 | ||
608 | /* Structures, enum, and defines specific to the 4965 */ | 610 | struct iwl_dma_ptr { |
609 | 611 | dma_addr_t dma; | |
610 | #define IWL_KW_SIZE 0x1000 /*4k */ | 612 | void *addr; |
611 | |||
612 | struct 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 | ||
1097 | static 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 | ||
1107 | static inline void iwl_print_hex_dump(struct iwl_priv *priv, int level, | ||
1108 | void *p, u32 len) | ||
1109 | { | ||
1110 | } | ||
1111 | #endif | ||
1112 | |||
1113 | extern const struct iwl_channel_info *iwl_get_channel_info( | 1092 | extern 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 | */ | ||
418 | struct 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 | |||
431 | static 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 | */ | ||
445 | struct 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 | */ | ||
479 | struct 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 | } |
322 | EXPORT_SYMBOL(iwl_rx_queue_free); | 324 | EXPORT_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 | |||
357 | err_rb: | ||
358 | pci_free_consistent(priv->pci_dev, 4 * RX_QUEUE_SIZE, rxq->bd, | ||
359 | rxq->dma_addr); | ||
360 | err_bd: | ||
361 | return -ENOMEM; | ||
349 | } | 362 | } |
350 | EXPORT_SYMBOL(iwl_rx_queue_alloc); | 363 | EXPORT_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 | ||
60 | static 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 | |||
79 | static __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 | } | ||
97 | static 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 | |||
177 | static 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 | |||
193 | void iwl_setup_spectrum_handlers(struct iwl_priv *priv) | ||
194 | { | ||
195 | priv->rx_handlers[SPECTRUM_MEASURE_NOTIFICATION] = | ||
196 | iwl_rx_spectrum_measure_notif; | ||
197 | } | ||
198 | EXPORT_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 | ||
59 | static 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 | |||
69 | static 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 | |||
59 | static inline dma_addr_t iwl_tfd_tb_get_addr(struct iwl_tfd *tfd, u8 idx) | 79 | static 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 | } |
523 | EXPORT_SYMBOL(iwl_hw_txq_ctx_free); | 544 | EXPORT_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 | ||
1421 | static u8 iwl3945_rate_get_lowest_plcp(int rate_mask) | 1421 | static 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 | ||
1434 | static int iwl3945_send_beacon_cmd(struct iwl3945_priv *priv) | 1445 | static 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 | ||
4746 | static inline u16 iwl3945_get_active_dwell_time(struct iwl3945_priv *priv, | 4748 | static 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 */ | ||
5607 | static 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 */ | ||
6714 | static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb); | ||
6715 | |||
6716 | static int iwl3945_mac_config_interface(struct ieee80211_hw *hw, | 6727 | static 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 | ||
162 | int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria) | 162 | int 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); |
57 | int lbs_mesh_config(struct lbs_private *priv, uint16_t enable, uint16_t chan); | 57 | int lbs_mesh_config(struct lbs_private *priv, uint16_t enable, uint16_t chan); |
58 | 58 | ||
59 | int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria); | 59 | int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria, |
60 | struct wol_config *p_wol_config); | ||
60 | int lbs_suspend(struct lbs_private *priv); | 61 | int lbs_suspend(struct lbs_private *priv); |
61 | void lbs_resume(struct lbs_private *priv); | 62 | void 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 | ||
186 | struct ethtool_ops lbs_ethtool_ops = { | 186 | struct 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 */ | ||
224 | enum 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 */ |
224 | enum cmd_mesh_access_opts { | 232 | enum 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 | |||
585 | struct 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 | |||
595 | struct 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 | |||
583 | struct cmd_ds_host_sleep { | 604 | struct 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 | |||
590 | struct cmd_ds_802_11_key_material { | 614 | struct 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(®, BBPCSR_WRITE_CONTROL, 1); | 88 | rt2x00_set_field32(®, 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 | |||
96 | exit_fail: | ||
97 | mutex_unlock(&rt2x00dev->csr_mutex); | ||
98 | |||
99 | ERROR(rt2x00dev, "BBPCSR register busy. Write failed.\n"); | ||
91 | } | 100 | } |
92 | 101 | ||
93 | static void rt2400pci_bbp_read(struct rt2x00_dev *rt2x00dev, | 102 | static 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 | |||
139 | exit_fail: | ||
140 | mutex_unlock(&rt2x00dev->csr_mutex); | ||
141 | |||
142 | ERROR(rt2x00dev, "BBPCSR register busy. Read failed.\n"); | ||
143 | *value = 0xff; | ||
128 | } | 144 | } |
129 | 145 | ||
130 | static void rt2400pci_rf_write(struct rt2x00_dev *rt2x00dev, | 146 | static 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, ®); | 158 | rt2x00pci_register_read(rt2x00dev, RFCSR, ®); |
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 | ||
160 | static void rt2400pci_eepromregister_read(struct eeprom_93cx6 *eeprom) | 181 | static 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, ®); | 347 | rt2x00pci_register_read(rt2x00dev, BCNCSR1, ®); |
327 | rt2x00_set_field32(®, BCNCSR1_PRELOAD, bcn_preload); | 348 | rt2x00_set_field32(®, 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, ®); | 388 | rt2x00pci_register_read(rt2x00dev, ARCSR2, ®); |
368 | rt2x00_set_field32(®, ARCSR2_SIGNAL, 0x00); | 389 | rt2x00_set_field32(®, ARCSR2_SIGNAL, 0x00); |
369 | rt2x00_set_field32(®, ARCSR2_SERVICE, 0x04); | 390 | rt2x00_set_field32(®, ARCSR2_SERVICE, 0x04); |
370 | rt2x00_set_field32(®, ARCSR2_LENGTH, get_duration(ACK_SIZE, 10)); | 391 | rt2x00_set_field32(®, 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, ®); | 394 | rt2x00pci_register_read(rt2x00dev, ARCSR3, ®); |
374 | rt2x00_set_field32(®, ARCSR3_SIGNAL, 0x01 | preamble_mask); | 395 | rt2x00_set_field32(®, ARCSR3_SIGNAL, 0x01 | preamble_mask); |
375 | rt2x00_set_field32(®, ARCSR3_SERVICE, 0x04); | 396 | rt2x00_set_field32(®, ARCSR3_SERVICE, 0x04); |
376 | rt2x00_set_field32(®, ARCSR2_LENGTH, get_duration(ACK_SIZE, 20)); | 397 | rt2x00_set_field32(®, 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, ®); | 400 | rt2x00pci_register_read(rt2x00dev, ARCSR4, ®); |
380 | rt2x00_set_field32(®, ARCSR4_SIGNAL, 0x02 | preamble_mask); | 401 | rt2x00_set_field32(®, ARCSR4_SIGNAL, 0x02 | preamble_mask); |
381 | rt2x00_set_field32(®, ARCSR4_SERVICE, 0x04); | 402 | rt2x00_set_field32(®, ARCSR4_SERVICE, 0x04); |
382 | rt2x00_set_field32(®, ARCSR2_LENGTH, get_duration(ACK_SIZE, 55)); | 403 | rt2x00_set_field32(®, 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, ®); | 406 | rt2x00pci_register_read(rt2x00dev, ARCSR5, ®); |
386 | rt2x00_set_field32(®, ARCSR5_SIGNAL, 0x03 | preamble_mask); | 407 | rt2x00_set_field32(®, ARCSR5_SIGNAL, 0x03 | preamble_mask); |
387 | rt2x00_set_field32(®, ARCSR5_SERVICE, 0x84); | 408 | rt2x00_set_field32(®, ARCSR5_SERVICE, 0x84); |
388 | rt2x00_set_field32(®, ARCSR2_LENGTH, get_duration(ACK_SIZE, 110)); | 409 | rt2x00_set_field32(®, 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 | */ |
629 | static void rt2400pci_init_rxentry(struct rt2x00_dev *rt2x00dev, | 650 | static 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 | ||
649 | static void rt2400pci_init_txentry(struct rt2x00_dev *rt2x00dev, | 667 | static 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 | ||
661 | static int rt2400pci_init_queues(struct rt2x00_dev *rt2x00dev) | 693 | static 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(®, BBPCSR_WRITE_CONTROL, 1); | 88 | rt2x00_set_field32(®, 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 | |||
96 | exit_fail: | ||
97 | mutex_unlock(&rt2x00dev->csr_mutex); | ||
98 | |||
99 | ERROR(rt2x00dev, "BBPCSR register busy. Write failed.\n"); | ||
91 | } | 100 | } |
92 | 101 | ||
93 | static void rt2500pci_bbp_read(struct rt2x00_dev *rt2x00dev, | 102 | static 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 | |||
139 | exit_fail: | ||
140 | mutex_unlock(&rt2x00dev->csr_mutex); | ||
141 | |||
142 | ERROR(rt2x00dev, "BBPCSR register busy. Read failed.\n"); | ||
143 | *value = 0xff; | ||
128 | } | 144 | } |
129 | 145 | ||
130 | static void rt2500pci_rf_write(struct rt2x00_dev *rt2x00dev, | 146 | static 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, ®); | 158 | rt2x00pci_register_read(rt2x00dev, RFCSR, ®); |
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 | ||
160 | static void rt2500pci_eepromregister_read(struct eeprom_93cx6 *eeprom) | 181 | static 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, ®); | 352 | rt2x00pci_register_read(rt2x00dev, BCNCSR1, ®); |
332 | rt2x00_set_field32(®, BCNCSR1_PRELOAD, bcn_preload); | 353 | rt2x00_set_field32(®, BCNCSR1_PRELOAD, bcn_preload); |
333 | rt2x00_set_field32(®, BCNCSR1_BEACON_CWMIN, queue->cw_min); | 354 | rt2x00_set_field32(®, 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, ®); | 394 | rt2x00pci_register_read(rt2x00dev, ARCSR2, ®); |
374 | rt2x00_set_field32(®, ARCSR2_SIGNAL, 0x00); | 395 | rt2x00_set_field32(®, ARCSR2_SIGNAL, 0x00); |
375 | rt2x00_set_field32(®, ARCSR2_SERVICE, 0x04); | 396 | rt2x00_set_field32(®, ARCSR2_SERVICE, 0x04); |
376 | rt2x00_set_field32(®, ARCSR2_LENGTH, get_duration(ACK_SIZE, 10)); | 397 | rt2x00_set_field32(®, 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, ®); | 400 | rt2x00pci_register_read(rt2x00dev, ARCSR3, ®); |
380 | rt2x00_set_field32(®, ARCSR3_SIGNAL, 0x01 | preamble_mask); | 401 | rt2x00_set_field32(®, ARCSR3_SIGNAL, 0x01 | preamble_mask); |
381 | rt2x00_set_field32(®, ARCSR3_SERVICE, 0x04); | 402 | rt2x00_set_field32(®, ARCSR3_SERVICE, 0x04); |
382 | rt2x00_set_field32(®, ARCSR2_LENGTH, get_duration(ACK_SIZE, 20)); | 403 | rt2x00_set_field32(®, 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, ®); | 406 | rt2x00pci_register_read(rt2x00dev, ARCSR4, ®); |
386 | rt2x00_set_field32(®, ARCSR4_SIGNAL, 0x02 | preamble_mask); | 407 | rt2x00_set_field32(®, ARCSR4_SIGNAL, 0x02 | preamble_mask); |
387 | rt2x00_set_field32(®, ARCSR4_SERVICE, 0x04); | 408 | rt2x00_set_field32(®, ARCSR4_SERVICE, 0x04); |
388 | rt2x00_set_field32(®, ARCSR2_LENGTH, get_duration(ACK_SIZE, 55)); | 409 | rt2x00_set_field32(®, 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, ®); | 412 | rt2x00pci_register_read(rt2x00dev, ARCSR5, ®); |
392 | rt2x00_set_field32(®, ARCSR5_SIGNAL, 0x03 | preamble_mask); | 413 | rt2x00_set_field32(®, ARCSR5_SIGNAL, 0x03 | preamble_mask); |
393 | rt2x00_set_field32(®, ARCSR5_SERVICE, 0x84); | 414 | rt2x00_set_field32(®, ARCSR5_SERVICE, 0x84); |
394 | rt2x00_set_field32(®, ARCSR2_LENGTH, get_duration(ACK_SIZE, 110)); | 415 | rt2x00_set_field32(®, 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 | */ |
725 | static void rt2500pci_init_rxentry(struct rt2x00_dev *rt2x00dev, | 746 | static 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 | ||
741 | static void rt2500pci_init_txentry(struct rt2x00_dev *rt2x00dev, | 763 | static 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 | ||
753 | static int rt2500pci_init_queues(struct rt2x00_dev *rt2x00dev) | 785 | static 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 | */ |
53 | static inline void rt2500usb_register_read(struct rt2x00_dev *rt2x00dev, | 53 | static 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 | ||
158 | exit_fail: | 158 | exit_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, ®); | 194 | rt2500usb_register_read_lock(rt2x00dev, PHY_CSR7, ®); |
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 | ||
201 | exit_fail: | 201 | exit_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, ®); | 220 | rt2500usb_register_read_lock(rt2x00dev, PHY_CSR10, ®); |
@@ -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, ®); | 389 | rt2500usb_register_read(rt2x00dev, TXRX_CSR20, ®); |
390 | rt2x00_set_field16(®, TXRX_CSR20_OFFSET, bcn_preload >> 6); | 390 | rt2x00_set_field16(®, TXRX_CSR20_OFFSET, bcn_preload >> 6); |
391 | rt2x00_set_field16(®, TXRX_CSR20_BCN_EXPECT_WINDOW, | 391 | rt2x00_set_field16(®, 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 | */ | ||
933 | static inline u16 get_duration(const unsigned int size, const u8 rate) | ||
934 | { | ||
935 | return ((size * 8 * 10) / rate); | ||
936 | } | ||
937 | |||
938 | static 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 | ||
111 | void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, | 111 | void 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 | ||
177 | static void rt2x00lib_evaluate_antenna_sample(struct rt2x00_dev *rt2x00dev) | 176 | static 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 | ||
211 | static void rt2x00lib_evaluate_antenna_eval(struct rt2x00_dev *rt2x00dev) | 211 | static 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 | ||
241 | static void rt2x00lib_evaluate_antenna(struct rt2x00_dev *rt2x00dev) | 242 | static 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 | */ |
718 | const struct rt2x00_rate rt2x00_supported_rates[12] = { | 719 | const 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 | ||
75 | void rt2x00led_led_activity(struct rt2x00_dev *rt2x00dev, bool enabled) | 75 | static 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 | ||
90 | void rt2x00leds_led_assoc(struct rt2x00_dev *rt2x00dev, bool enabled) | 86 | void 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; | 92 | void 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 | ||
105 | void rt2x00leds_led_radio(struct rt2x00_dev *rt2x00dev, bool enabled) | 98 | void 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 | ||
120 | static int rt2x00leds_register_led(struct rt2x00_dev *rt2x00dev, | 104 | static 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: | |||
199 | static void rt2x00leds_unregister_led(struct rt2x00_led *led) | 190 | static 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 | ||
216 | static 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 | |||
216 | void rt2x00leds_suspend(struct rt2x00_dev *rt2x00dev) | 225 | void 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 | |||
235 | static 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 | ||
226 | void rt2x00leds_resume(struct rt2x00_dev *rt2x00dev) | 244 | void 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); |
96 | void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, | 95 | void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, |
97 | enum antenna rx, enum antenna tx); | 96 | struct antenna_setup *ant); |
98 | void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, | 97 | void 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 | */ |
152 | void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index); | 151 | void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index); |
153 | 152 | ||
154 | void rt2x00queue_init_rx(struct rt2x00_dev *rt2x00dev); | 153 | /** |
155 | void 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 | */ | ||
161 | void rt2x00queue_init_queues(struct rt2x00_dev *rt2x00dev); | ||
162 | |||
156 | int rt2x00queue_initialize(struct rt2x00_dev *rt2x00dev); | 163 | int rt2x00queue_initialize(struct rt2x00_dev *rt2x00dev); |
157 | void rt2x00queue_uninitialize(struct rt2x00_dev *rt2x00dev); | 164 | void rt2x00queue_uninitialize(struct rt2x00_dev *rt2x00dev); |
158 | int rt2x00queue_allocate(struct rt2x00_dev *rt2x00dev); | 165 | int 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 | */ |
37 | int rt2x00pci_write_tx_data(struct queue_entry *entry) | 37 | int 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 | */ |
60 | static inline void rt2x00pci_register_read(struct rt2x00_dev *rt2x00dev, | 49 | static 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 | ||
592 | void rt2x00queue_init_rx(struct rt2x00_dev *rt2x00dev) | 592 | void 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 | |||
610 | void 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 | */ |
354 | void rt2x00usb_init_rxentry(struct rt2x00_dev *rt2x00dev, | 354 | void 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 { |
368 | EXPORT_SYMBOL_GPL(rt2x00usb_init_rxentry); | 369 | entry->flags = 0; |
369 | 370 | } | |
370 | void rt2x00usb_init_txentry(struct rt2x00_dev *rt2x00dev, | ||
371 | struct queue_entry *entry) | ||
372 | { | ||
373 | entry->flags = 0; | ||
374 | } | 371 | } |
375 | EXPORT_SYMBOL_GPL(rt2x00usb_init_txentry); | 372 | EXPORT_SYMBOL_GPL(rt2x00usb_clear_entry); |
376 | 373 | ||
377 | static int rt2x00usb_alloc_urb(struct rt2x00_dev *rt2x00dev, | 374 | static 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 | */ |
289 | void rt2x00usb_init_rxentry(struct rt2x00_dev *rt2x00dev, | 289 | void rt2x00usb_clear_entry(struct queue_entry *entry); |
290 | struct queue_entry *entry); | ||
291 | void rt2x00usb_init_txentry(struct rt2x00_dev *rt2x00dev, | ||
292 | struct queue_entry *entry); | ||
293 | int rt2x00usb_initialize(struct rt2x00_dev *rt2x00dev); | 290 | int rt2x00usb_initialize(struct rt2x00_dev *rt2x00dev); |
294 | void rt2x00usb_uninitialize(struct rt2x00_dev *rt2x00dev); | 291 | void 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(®, PHY_CSR3_READ_CONTROL, 0); | 94 | rt2x00_set_field32(®, 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 | |||
101 | exit_fail: | ||
102 | mutex_unlock(&rt2x00dev->csr_mutex); | ||
103 | |||
104 | ERROR(rt2x00dev, "PHY_CSR3 register busy. Write failed.\n"); | ||
97 | } | 105 | } |
98 | 106 | ||
99 | static void rt61pci_bbp_read(struct rt2x00_dev *rt2x00dev, | 107 | static 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 | |||
143 | exit_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 | ||
136 | static void rt61pci_rf_write(struct rt2x00_dev *rt2x00dev, | 150 | static 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, ®); | 162 | rt2x00pci_register_read(rt2x00dev, PHY_CSR4, ®); |
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, ®); | 199 | rt2x00pci_register_read(rt2x00dev, H2M_MAILBOX_CSR, ®); |
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(®, H2M_MAILBOX_CSR_OWNER, 1); | 204 | rt2x00_set_field32(®, H2M_MAILBOX_CSR_OWNER, 1); |
188 | rt2x00_set_field32(®, H2M_MAILBOX_CSR_CMD_TOKEN, token); | 205 | rt2x00_set_field32(®, H2M_MAILBOX_CSR_CMD_TOKEN, token); |
@@ -194,6 +211,17 @@ static void rt61pci_mcu_request(struct rt2x00_dev *rt2x00dev, | |||
194 | rt2x00_set_field32(®, HOST_CMD_CSR_HOST_COMMAND, command); | 211 | rt2x00_set_field32(®, HOST_CMD_CSR_HOST_COMMAND, command); |
195 | rt2x00_set_field32(®, HOST_CMD_CSR_INTERRUPT_MCU, 1); | 212 | rt2x00_set_field32(®, 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 | |||
219 | exit_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 | */ |
1264 | static void rt61pci_init_rxentry(struct rt2x00_dev *rt2x00dev, | 1292 | static 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 | ||
1281 | static void rt61pci_init_txentry(struct rt2x00_dev *rt2x00dev, | 1309 | static 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 | ||
1293 | static int rt61pci_init_queues(struct rt2x00_dev *rt2x00dev) | 1332 | static 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 | */ |
60 | static inline void rt73usb_register_read(struct rt2x00_dev *rt2x00dev, | 60 | static 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(®, PHY_CSR3_READ_CONTROL, 0); | 154 | rt2x00_set_field32(®, 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 | ||
161 | exit_fail: | 161 | exit_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 | ||
203 | exit_fail: | 203 | exit_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, ®); | 222 | rt73usb_register_read_lock(rt2x00dev, PHY_CSR4, ®); |
@@ -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 @@ | |||
1 | rtl8180-objs := rtl8180_dev.o rtl8180_rtl8225.o rtl8180_sa2400.o rtl8180_max2820.o rtl8180_grf5101.o | ||
2 | rtl8187-objs := rtl8187_dev.o rtl8187_rtl8225.o | ||
3 | |||
4 | obj-$(CONFIG_RTL8180) += rtl8180.o | ||
5 | obj-$(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 | ||
723 | static 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 | |||
723 | static void rtl8180_configure_filter(struct ieee80211_hw *dev, | 734 | static 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 | |||
730 | static 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 | ||
751 | static const struct rtl818x_rf_ops rtl8225z2_ops = { | 758 | static 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 | ||
758 | const struct rtl818x_rf_ops * rtl8180_detect_rf(struct ieee80211_hw *dev) | 766 | const 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 | ||
28 | MODULE_AUTHOR("Michael Wu <flamingice@sourmilk.net>"); | 33 | MODULE_AUTHOR("Michael Wu <flamingice@sourmilk.net>"); |
29 | MODULE_AUTHOR("Andrea Merello <andreamrl@tiscali.it>"); | 34 | MODULE_AUTHOR("Andrea Merello <andreamrl@tiscali.it>"); |
35 | MODULE_AUTHOR("Herton Ronaldo Krzesinski <herton@mandriva.com.br>"); | ||
36 | MODULE_AUTHOR("Hin-Tak Leung <htl10@users.sourceforge.net>"); | ||
37 | MODULE_AUTHOR("Larry Finger <Larry.Finger@lwfinger.net>"); | ||
30 | MODULE_DESCRIPTION("RTL8187/RTL8187B USB wireless driver"); | 38 | MODULE_DESCRIPTION("RTL8187/RTL8187B USB wireless driver"); |
31 | MODULE_LICENSE("GPL"); | 39 | MODULE_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 | ||
744 | static int zd1201_net_open(struct net_device *dev) | 744 | static 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 | */ |
782 | static int zd1201_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) | 782 | static 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 | ||
832 | static void zd1201_tx_timeout(struct net_device *dev) | 832 | static 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) | |||
846 | static int zd1201_set_mac_address(struct net_device *dev, void *p) | 846 | static 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 | ||
864 | static struct net_device_stats *zd1201_get_stats(struct net_device *dev) | 864 | static 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 | ||
871 | static struct iw_statistics *zd1201_get_wireless_stats(struct net_device *dev) | 871 | static 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 | ||
878 | static void zd1201_set_multicast(struct net_device *dev) | 878 | static 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) | |||
897 | static int zd1201_config_commit(struct net_device *dev, | 897 | static 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, | |||
912 | static int zd1201_set_freq(struct net_device *dev, | 912 | static 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, | |||
937 | static int zd1201_get_freq(struct net_device *dev, | 937 | static 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, | |||
953 | static int zd1201_set_mode(struct net_device *dev, | 953 | static 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, | |||
1015 | static int zd1201_get_mode(struct net_device *dev, | 1015 | static 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, | |||
1091 | static int zd1201_get_wap(struct net_device *dev, | 1091 | static 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, | |||
1119 | static int zd1201_get_scan(struct net_device *dev, | 1119 | static 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, | |||
1211 | static int zd1201_set_essid(struct net_device *dev, | 1211 | static 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, | |||
1226 | static int zd1201_get_essid(struct net_device *dev, | 1226 | static 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, | |||
1247 | static int zd1201_set_rate(struct net_device *dev, | 1247 | static 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, | |||
1280 | static int zd1201_get_rate(struct net_device *dev, | 1280 | static 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, | |||
1313 | static int zd1201_set_rts(struct net_device *dev, struct iw_request_info *info, | 1313 | static 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, | |||
1333 | static int zd1201_get_rts(struct net_device *dev, struct iw_request_info *info, | 1333 | static 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, | |||
1350 | static int zd1201_set_frag(struct net_device *dev, struct iw_request_info *info, | 1350 | static 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, | |||
1371 | static int zd1201_get_frag(struct net_device *dev, struct iw_request_info *info, | 1371 | static 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, | |||
1400 | static int zd1201_set_encode(struct net_device *dev, | 1400 | static 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, | |||
1457 | static int zd1201_get_encode(struct net_device *dev, | 1457 | static 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, | |||
1490 | static int zd1201_set_power(struct net_device *dev, | 1490 | static 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: | |||
1529 | static int zd1201_get_power(struct net_device *dev, | 1529 | static 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[] = | |||
1616 | static int zd1201_set_hostauth(struct net_device *dev, | 1616 | static 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, | |||
1627 | static int zd1201_get_hostauth(struct net_device *dev, | 1627 | static 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, | |||
1646 | static int zd1201_auth_sta(struct net_device *dev, | 1646 | static 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, | |||
1662 | static int zd1201_set_maxassoc(struct net_device *dev, | 1662 | static 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, | |||
1677 | static int zd1201_get_maxassoc(struct net_device *dev, | 1677 | static 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 | ||
1826 | err_net: | ||
1827 | free_netdev(zd->dev); | ||
1828 | err_start: | 1825 | err_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); |
1831 | err_zd: | 1828 | err_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 | ||
356 | struct ieee80211_device; | 358 | struct 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 | |||
31 | enum { | ||
32 | IEEE80211_CRYPTO_TKIP_COUNTERMEASURES = (1 << 0), | ||
33 | }; | ||
34 | |||
35 | struct sk_buff; | ||
36 | struct module; | ||
37 | |||
38 | struct 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 | |||
90 | struct 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 | |||
97 | struct ieee80211_device; | ||
98 | |||
99 | int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops); | ||
100 | int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops); | ||
101 | struct ieee80211_crypto_ops *ieee80211_get_crypto_ops(const char *name); | ||
102 | void ieee80211_crypt_deinit_entries(struct ieee80211_device *, int); | ||
103 | void ieee80211_crypt_deinit_handler(unsigned long); | ||
104 | void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee, | ||
105 | struct ieee80211_crypt_data **crypt); | ||
106 | void 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. */ |
15 | const char *print_ssid(char *buf, const char *ssid, u8 ssid_len); | 36 | const 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 | |||
41 | enum { | ||
42 | IEEE80211_CRYPTO_TKIP_COUNTERMEASURES = (1 << 0), | ||
43 | }; | ||
44 | |||
45 | struct 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 | |||
97 | struct 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 | |||
104 | struct 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 | |||
117 | int lib80211_crypt_info_init(struct lib80211_crypt_info *info, char *name, | ||
118 | spinlock_t *lock); | ||
119 | void lib80211_crypt_info_free(struct lib80211_crypt_info *info); | ||
120 | int lib80211_register_crypto_ops(struct lib80211_crypto_ops *ops); | ||
121 | int lib80211_unregister_crypto_ops(struct lib80211_crypto_ops *ops); | ||
122 | struct lib80211_crypto_ops *lib80211_get_crypto_ops(const char *name); | ||
123 | void lib80211_crypt_deinit_entries(struct lib80211_crypt_info *, int); | ||
124 | void lib80211_crypt_deinit_handler(unsigned long); | ||
125 | void lib80211_crypt_delayed_deinit(struct lib80211_crypt_info *info, | ||
126 | struct lib80211_crypt_data **crypt); | ||
127 | void 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 | ||
252 | source "net/wireless/Kconfig" | 252 | source "net/wireless/Kconfig" |
253 | source "net/mac80211/Kconfig" | 253 | source "net/mac80211/Kconfig" |
254 | source "net/ieee80211/Kconfig" | ||
255 | 254 | ||
256 | endif # WIRELESS | 255 | endif # 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/ | |||
51 | obj-$(CONFIG_IP_SCTP) += sctp/ | 51 | obj-$(CONFIG_IP_SCTP) += sctp/ |
52 | obj-y += wireless/ | 52 | obj-y += wireless/ |
53 | obj-$(CONFIG_MAC80211) += mac80211/ | 53 | obj-$(CONFIG_MAC80211) += mac80211/ |
54 | obj-$(CONFIG_IEEE80211) += ieee80211/ | ||
55 | obj-$(CONFIG_TIPC) += tipc/ | 54 | obj-$(CONFIG_TIPC) += tipc/ |
56 | obj-$(CONFIG_NETLABEL) += netlabel/ | 55 | obj-$(CONFIG_NETLABEL) += netlabel/ |
57 | obj-$(CONFIG_IUCV) += iucv/ | 56 | obj-$(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 @@ | |||
1 | config 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 | |||
20 | config 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 | |||
43 | config IEEE80211_CRYPT_WEP | ||
44 | tristate | ||
45 | |||
46 | config IEEE80211_CRYPT_CCMP | ||
47 | tristate | ||
48 | |||
49 | config 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 @@ | |||
1 | obj-$(CONFIG_IEEE80211) += ieee80211.o | ||
2 | obj-$(CONFIG_IEEE80211) += ieee80211_crypt.o | ||
3 | obj-$(CONFIG_IEEE80211_CRYPT_WEP) += ieee80211_crypt_wep.o | ||
4 | obj-$(CONFIG_IEEE80211_CRYPT_CCMP) += ieee80211_crypt_ccmp.o | ||
5 | obj-$(CONFIG_IEEE80211_CRYPT_TKIP) += ieee80211_crypt_tkip.o | ||
6 | ieee80211-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 | |||
21 | MODULE_AUTHOR("Jouni Malinen"); | ||
22 | MODULE_DESCRIPTION("HostAP crypto"); | ||
23 | MODULE_LICENSE("GPL"); | ||
24 | |||
25 | struct ieee80211_crypto_alg { | ||
26 | struct list_head list; | ||
27 | struct ieee80211_crypto_ops *ops; | ||
28 | }; | ||
29 | |||
30 | static LIST_HEAD(ieee80211_crypto_algs); | ||
31 | static DEFINE_SPINLOCK(ieee80211_crypto_lock); | ||
32 | |||
33 | void 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 */ | ||
55 | void 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 | |||
64 | void 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 | |||
81 | void 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 | |||
108 | int 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 | |||
129 | int 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 | |||
151 | struct 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 | |||
169 | static void *ieee80211_crypt_null_init(int keyidx) | ||
170 | { | ||
171 | return (void *)1; | ||
172 | } | ||
173 | |||
174 | static void ieee80211_crypt_null_deinit(void *priv) | ||
175 | { | ||
176 | } | ||
177 | |||
178 | static 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 | |||
185 | static int __init ieee80211_crypto_init(void) | ||
186 | { | ||
187 | return ieee80211_register_crypto_ops(&ieee80211_crypt_null); | ||
188 | } | ||
189 | |||
190 | static 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 | |||
196 | EXPORT_SYMBOL(ieee80211_crypt_deinit_entries); | ||
197 | EXPORT_SYMBOL(ieee80211_crypt_deinit_handler); | ||
198 | EXPORT_SYMBOL(ieee80211_crypt_delayed_deinit); | ||
199 | EXPORT_SYMBOL(ieee80211_crypt_quiescing); | ||
200 | |||
201 | EXPORT_SYMBOL(ieee80211_register_crypto_ops); | ||
202 | EXPORT_SYMBOL(ieee80211_unregister_crypto_ops); | ||
203 | EXPORT_SYMBOL(ieee80211_get_crypto_ops); | ||
204 | |||
205 | module_init(ieee80211_crypto_init); | ||
206 | module_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 | |||
86 | config LIB80211_CRYPT_WEP | ||
87 | tristate | ||
88 | |||
89 | config LIB80211_CRYPT_CCMP | ||
90 | tristate | ||
91 | |||
92 | config 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 @@ | |||
1 | obj-$(CONFIG_WIRELESS_EXT) += wext.o | 1 | obj-$(CONFIG_WIRELESS_EXT) += wext.o |
2 | obj-$(CONFIG_CFG80211) += cfg80211.o | 2 | obj-$(CONFIG_CFG80211) += cfg80211.o |
3 | obj-$(CONFIG_LIB80211) += lib80211.o | 3 | obj-$(CONFIG_LIB80211) += lib80211.o |
4 | obj-$(CONFIG_LIB80211_CRYPT_WEP) += lib80211_crypt_wep.o | ||
5 | obj-$(CONFIG_LIB80211_CRYPT_CCMP) += lib80211_crypt_ccmp.o | ||
6 | obj-$(CONFIG_LIB80211_CRYPT_TKIP) += lib80211_crypt_tkip.o | ||
4 | 7 | ||
5 | cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o | 8 | cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o |
6 | cfg80211-$(CONFIG_NL80211) += nl80211.o | 9 | cfg80211-$(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); | |||
19 | MODULE_AUTHOR("John W. Linville <linville@tuxdriver.com>"); | 31 | MODULE_AUTHOR("John W. Linville <linville@tuxdriver.com>"); |
20 | MODULE_LICENSE("GPL"); | 32 | MODULE_LICENSE("GPL"); |
21 | 33 | ||
34 | struct lib80211_crypto_alg { | ||
35 | struct list_head list; | ||
36 | struct lib80211_crypto_ops *ops; | ||
37 | }; | ||
38 | |||
39 | static LIST_HEAD(lib80211_crypto_algs); | ||
40 | static DEFINE_SPINLOCK(lib80211_crypto_lock); | ||
41 | |||
22 | const char *print_ssid(char *buf, const char *ssid, u8 ssid_len) | 42 | const 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 | } |
52 | EXPORT_SYMBOL(print_ssid); | 72 | EXPORT_SYMBOL(print_ssid); |
53 | 73 | ||
54 | static int __init ieee80211_init(void) | 74 | int 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 | } |
88 | EXPORT_SYMBOL(lib80211_crypt_info_init); | ||
89 | |||
90 | void 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 | } | ||
110 | EXPORT_SYMBOL(lib80211_crypt_info_free); | ||
111 | |||
112 | void 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 | } | ||
132 | EXPORT_SYMBOL(lib80211_crypt_deinit_entries); | ||
133 | |||
134 | /* After this, crypt_deinit_list won't accept new members */ | ||
135 | void 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 | } | ||
143 | EXPORT_SYMBOL(lib80211_crypt_quiescing); | ||
144 | |||
145 | void 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 | } | ||
161 | EXPORT_SYMBOL(lib80211_crypt_deinit_handler); | ||
162 | |||
163 | void 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 | } | ||
189 | EXPORT_SYMBOL(lib80211_crypt_delayed_deinit); | ||
190 | |||
191 | int 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 | } | ||
211 | EXPORT_SYMBOL(lib80211_register_crypto_ops); | ||
212 | |||
213 | int 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 | } | ||
234 | EXPORT_SYMBOL(lib80211_unregister_crypto_ops); | ||
235 | |||
236 | struct 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 | } | ||
253 | EXPORT_SYMBOL(lib80211_get_crypto_ops); | ||
254 | |||
255 | static void *lib80211_crypt_null_init(int keyidx) | ||
256 | { | ||
257 | return (void *)1; | ||
258 | } | ||
259 | |||
260 | static void lib80211_crypt_null_deinit(void *priv) | ||
261 | { | ||
262 | } | ||
263 | |||
264 | static 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 | |||
271 | static 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 | ||
60 | static void __exit ieee80211_exit(void) | 277 | static 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 | ||
64 | module_init(ieee80211_init); | 283 | module_init(lib80211_init); |
65 | module_exit(ieee80211_exit); | 284 | module_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 | |||
29 | MODULE_AUTHOR("Jouni Malinen"); | 32 | MODULE_AUTHOR("Jouni Malinen"); |
30 | MODULE_DESCRIPTION("Host AP crypt: CCMP"); | 33 | MODULE_DESCRIPTION("Host AP crypt: CCMP"); |
31 | MODULE_LICENSE("GPL"); | 34 | MODULE_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 | ||
39 | struct ieee80211_ccmp_data { | 42 | struct 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 | ||
60 | static inline void ieee80211_ccmp_aes_encrypt(struct crypto_cipher *tfm, | 63 | static 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 | ||
66 | static void *ieee80211_ccmp_init(int key_idx) | 69 | static 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 | ||
95 | static void ieee80211_ccmp_deinit(void *priv) | 98 | static 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 | ||
110 | static void ccmp_init_blocks(struct crypto_cipher *tfm, | 113 | static 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 | ||
183 | static int ieee80211_ccmp_hdr(struct sk_buff *skb, int hdr_len, | 183 | static 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 | ||
220 | static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv) | 220 | static 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 | ||
287 | static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv) | 287 | static 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 | ||
391 | static int ieee80211_ccmp_set_key(void *key, int len, u8 * seq, void *priv) | 391 | static 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 | ||
421 | static int ieee80211_ccmp_get_key(void *key, int len, u8 * seq, void *priv) | 421 | static 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 | ||
444 | static char *ieee80211_ccmp_print_stats(char *p, void *priv) | 444 | static 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 | ||
464 | static struct ieee80211_crypto_ops ieee80211_crypt_ccmp = { | 464 | static 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 | ||
481 | static int __init ieee80211_crypto_ccmp_init(void) | 481 | static 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 | ||
486 | static void __exit ieee80211_crypto_ccmp_exit(void) | 486 | static 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 | ||
491 | module_init(ieee80211_crypto_ccmp_init); | 491 | module_init(lib80211_crypto_ccmp_init); |
492 | module_exit(ieee80211_crypto_ccmp_exit); | 492 | module_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 | |||
30 | MODULE_AUTHOR("Jouni Malinen"); | 35 | MODULE_AUTHOR("Jouni Malinen"); |
31 | MODULE_DESCRIPTION("Host AP crypt: TKIP"); | 36 | MODULE_DESCRIPTION("lib80211 crypt: TKIP"); |
32 | MODULE_LICENSE("GPL"); | 37 | MODULE_LICENSE("GPL"); |
33 | 38 | ||
34 | struct ieee80211_tkip_data { | 39 | struct 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 | ||
68 | static unsigned long ieee80211_tkip_set_flags(unsigned long flags, void *priv) | 73 | static 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 | ||
76 | static unsigned long ieee80211_tkip_get_flags(void *priv) | 81 | static 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 | ||
82 | static void *ieee80211_tkip_init(int key_idx) | 87 | static 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 | ||
146 | static void ieee80211_tkip_deinit(void *priv) | 151 | static 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 | ||
308 | static int ieee80211_tkip_hdr(struct sk_buff *skb, int hdr_len, | 313 | static 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 | ||
354 | static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv) | 359 | static 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 | ||
408 | static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) | 413 | static 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 | ||
546 | static void michael_mic_hdr(struct sk_buff *skb, u8 * hdr) | 551 | static 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 | ||
584 | static int ieee80211_michael_mic_add(struct sk_buff *skb, int hdr_len, | 586 | static 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 | ||
606 | static void ieee80211_michael_mic_failure(struct net_device *dev, | 608 | static 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 | ||
627 | static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx, | 629 | static 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 | ||
663 | static int ieee80211_tkip_set_key(void *key, int len, u8 * seq, void *priv) | 665 | static 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 | ||
696 | static int ieee80211_tkip_get_key(void *key, int len, u8 * seq, void *priv) | 698 | static 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 | ||
725 | static char *ieee80211_tkip_print_stats(char *p, void *priv) | 727 | static 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 | ||
751 | static struct ieee80211_crypto_ops ieee80211_crypt_tkip = { | 753 | static 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 | ||
771 | static int __init ieee80211_crypto_tkip_init(void) | 773 | static 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 | ||
776 | static void __exit ieee80211_crypto_tkip_exit(void) | 778 | static 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 | ||
781 | module_init(ieee80211_crypto_tkip_init); | 783 | module_init(lib80211_crypto_tkip_init); |
782 | module_exit(ieee80211_crypto_tkip_exit); | 784 | module_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 | ||
27 | MODULE_AUTHOR("Jouni Malinen"); | 28 | MODULE_AUTHOR("Jouni Malinen"); |
28 | MODULE_DESCRIPTION("Host AP crypt: WEP"); | 29 | MODULE_DESCRIPTION("lib80211 crypt: WEP"); |
29 | MODULE_LICENSE("GPL"); | 30 | MODULE_LICENSE("GPL"); |
30 | 31 | ||
31 | struct prism2_wep_data { | 32 | struct 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 | ||
41 | static void *prism2_wep_init(int keyidx) | 42 | static 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 | ||
81 | static void prism2_wep_deinit(void *priv) | 82 | static 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 */ |
94 | static int prism2_wep_build_iv(struct sk_buff *skb, int hdr_len, | 95 | static 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 | */ |
137 | static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv) | 138 | static 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 | */ |
184 | static int prism2_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv) | 185 | static 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 | ||
235 | static int prism2_wep_set_key(void *key, int len, u8 * seq, void *priv) | 236 | static 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 | ||
248 | static int prism2_wep_get_key(void *key, int len, u8 * seq, void *priv) | 249 | static 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 | ||
260 | static char *prism2_wep_print_stats(char *p, void *priv) | 261 | static 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 | ||
267 | static struct ieee80211_crypto_ops ieee80211_crypt_wep = { | 268 | static 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 | ||
284 | static int __init ieee80211_crypto_wep_init(void) | 285 | static 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 | ||
289 | static void __exit ieee80211_crypto_wep_exit(void) | 290 | static 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 | ||
294 | module_init(ieee80211_crypto_wep_init); | 295 | module_init(lib80211_crypto_wep_init); |
295 | module_exit(ieee80211_crypto_wep_exit); | 296 | module_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 | ||
26 | static ssize_t _show_index(struct device *dev, struct device_attribute *attr, | 26 | #define SHOW_FMT(name, fmt, member) \ |
27 | char *buf) | 27 | static 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 | ||
32 | static ssize_t _show_permaddr(struct device *dev, | 34 | SHOW_FMT(index, "%d", idx); |
33 | struct device_attribute *attr, | 35 | SHOW_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 | ||
42 | static struct device_attribute ieee80211_dev_attrs[] = { | 37 | static 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 | ||