aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/Kconfig28
-rw-r--r--drivers/net/wireless/Makefile2
-rw-r--r--drivers/net/wireless/ath5k/base.c10
-rw-r--r--drivers/net/wireless/ath5k/debug.c124
-rw-r--r--drivers/net/wireless/ath5k/debug.h18
-rw-r--r--drivers/net/wireless/b43/dma.c30
-rw-r--r--drivers/net/wireless/b43/main.c19
-rw-r--r--drivers/net/wireless/b43/xmit.c23
-rw-r--r--drivers/net/wireless/b43/xmit.h10
-rw-r--r--drivers/net/wireless/b43legacy/b43legacy.h31
-rw-r--r--drivers/net/wireless/b43legacy/main.c133
-rw-r--r--drivers/net/wireless/b43legacy/phy.c14
-rw-r--r--drivers/net/wireless/b43legacy/pio.c6
-rw-r--r--drivers/net/wireless/b43legacy/radio.c16
-rw-r--r--drivers/net/wireless/hostap/hostap_80211.h5
-rw-r--r--drivers/net/wireless/hostap/hostap_cs.c3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-hw.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c14
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965-hw.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c7
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.h1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-helpers.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c86
-rw-r--r--drivers/net/wireless/iwlwifi/iwl4965-base.c84
-rw-r--r--drivers/net/wireless/libertas/assoc.c6
-rw-r--r--drivers/net/wireless/libertas/dev.h2
-rw-r--r--drivers/net/wireless/libertas/if_cs.c6
-rw-r--r--drivers/net/wireless/rndis_wlan.c2757
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c3
-rw-r--r--drivers/net/wireless/rtl8180_dev.c1
31 files changed, 3227 insertions, 222 deletions
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index f372960904b2..714a6ca30ad2 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -545,6 +545,34 @@ config USB_ZD1201
545 To compile this driver as a module, choose M here: the 545 To compile this driver as a module, choose M here: the
546 module will be called zd1201. 546 module will be called zd1201.
547 547
548config USB_NET_RNDIS_WLAN
549 tristate "Wireless RNDIS USB support"
550 depends on USB && WLAN_80211 && EXPERIMENTAL
551 select USB_USBNET
552 select USB_NET_CDCETHER
553 select USB_NET_RNDIS_HOST
554 select WIRELESS_EXT
555 ---help---
556 This is a driver for wireless RNDIS devices.
557 These are USB based adapters found in devices such as:
558
559 Buffalo WLI-U2-KG125S
560 U.S. Robotics USR5421
561 Belkin F5D7051
562 Linksys WUSB54GSv2
563 Linksys WUSB54GSC
564 Asus WL169gE
565 Eminent EM4045
566 BT Voyager 1055
567 Linksys WUSB54GSv1
568 U.S. Robotics USR5420
569 BUFFALO WLI-USB-G54
570
571 All of these devices are based on Broadcom 4320 chip which is the
572 only wireless RNDIS chip known to date.
573
574 If you choose to build a module, it'll be called rndis_wlan.
575
548config RTL8180 576config RTL8180
549 tristate "Realtek 8180/8185 PCI support" 577 tristate "Realtek 8180/8185 PCI support"
550 depends on MAC80211 && PCI && WLAN_80211 && EXPERIMENTAL 578 depends on MAC80211 && PCI && WLAN_80211 && EXPERIMENTAL
diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile
index 6af7b158624e..091dfe2e574e 100644
--- a/drivers/net/wireless/Makefile
+++ b/drivers/net/wireless/Makefile
@@ -44,6 +44,8 @@ obj-$(CONFIG_ZD1211RW) += zd1211rw/
44obj-$(CONFIG_PCMCIA_RAYCS) += ray_cs.o 44obj-$(CONFIG_PCMCIA_RAYCS) += ray_cs.o
45obj-$(CONFIG_PCMCIA_WL3501) += wl3501_cs.o 45obj-$(CONFIG_PCMCIA_WL3501) += wl3501_cs.o
46 46
47obj-$(CONFIG_USB_NET_RNDIS_WLAN) += rndis_wlan.o
48
47obj-$(CONFIG_USB_ZD1201) += zd1201.o 49obj-$(CONFIG_USB_ZD1201) += zd1201.o
48obj-$(CONFIG_LIBERTAS) += libertas/ 50obj-$(CONFIG_LIBERTAS) += libertas/
49 51
diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c
index 72bcf321d1ce..d6599d219193 100644
--- a/drivers/net/wireless/ath5k/base.c
+++ b/drivers/net/wireless/ath5k/base.c
@@ -1980,7 +1980,7 @@ ath5k_beacon_send(struct ath5k_softc *sc)
1980 struct ath5k_buf *bf = sc->bbuf; 1980 struct ath5k_buf *bf = sc->bbuf;
1981 struct ath5k_hw *ah = sc->ah; 1981 struct ath5k_hw *ah = sc->ah;
1982 1982
1983 ATH5K_DBG(sc, ATH5K_DEBUG_BEACON_PROC, "in beacon_send\n"); 1983 ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON, "in beacon_send\n");
1984 1984
1985 if (unlikely(bf->skb == NULL || sc->opmode == IEEE80211_IF_TYPE_STA || 1985 if (unlikely(bf->skb == NULL || sc->opmode == IEEE80211_IF_TYPE_STA ||
1986 sc->opmode == IEEE80211_IF_TYPE_MNTR)) { 1986 sc->opmode == IEEE80211_IF_TYPE_MNTR)) {
@@ -1996,10 +1996,10 @@ ath5k_beacon_send(struct ath5k_softc *sc)
1996 */ 1996 */
1997 if (unlikely(ath5k_hw_num_tx_pending(ah, sc->bhalq) != 0)) { 1997 if (unlikely(ath5k_hw_num_tx_pending(ah, sc->bhalq) != 0)) {
1998 sc->bmisscount++; 1998 sc->bmisscount++;
1999 ATH5K_DBG(sc, ATH5K_DEBUG_BEACON_PROC, 1999 ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
2000 "missed %u consecutive beacons\n", sc->bmisscount); 2000 "missed %u consecutive beacons\n", sc->bmisscount);
2001 if (sc->bmisscount > 3) { /* NB: 3 is a guess */ 2001 if (sc->bmisscount > 3) { /* NB: 3 is a guess */
2002 ATH5K_DBG(sc, ATH5K_DEBUG_BEACON_PROC, 2002 ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
2003 "stuck beacon time (%u missed)\n", 2003 "stuck beacon time (%u missed)\n",
2004 sc->bmisscount); 2004 sc->bmisscount);
2005 tasklet_schedule(&sc->restq); 2005 tasklet_schedule(&sc->restq);
@@ -2007,7 +2007,7 @@ ath5k_beacon_send(struct ath5k_softc *sc)
2007 return; 2007 return;
2008 } 2008 }
2009 if (unlikely(sc->bmisscount != 0)) { 2009 if (unlikely(sc->bmisscount != 0)) {
2010 ATH5K_DBG(sc, ATH5K_DEBUG_BEACON_PROC, 2010 ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
2011 "resume beacon xmit after %u misses\n", 2011 "resume beacon xmit after %u misses\n",
2012 sc->bmisscount); 2012 sc->bmisscount);
2013 sc->bmisscount = 0; 2013 sc->bmisscount = 0;
@@ -2027,7 +2027,7 @@ ath5k_beacon_send(struct ath5k_softc *sc)
2027 2027
2028 ath5k_hw_put_tx_buf(ah, sc->bhalq, bf->daddr); 2028 ath5k_hw_put_tx_buf(ah, sc->bhalq, bf->daddr);
2029 ath5k_hw_tx_start(ah, sc->bhalq); 2029 ath5k_hw_tx_start(ah, sc->bhalq);
2030 ATH5K_DBG(sc, ATH5K_DEBUG_BEACON_PROC, "TXDP[%u] = %llx (%p)\n", 2030 ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, "TXDP[%u] = %llx (%p)\n",
2031 sc->bhalq, (unsigned long long)bf->daddr, bf->desc); 2031 sc->bhalq, (unsigned long long)bf->daddr, bf->desc);
2032 2032
2033 sc->bsent++; 2033 sc->bsent++;
diff --git a/drivers/net/wireless/ath5k/debug.c b/drivers/net/wireless/ath5k/debug.c
index 4ba649e20269..bb581ef6d1ef 100644
--- a/drivers/net/wireless/ath5k/debug.c
+++ b/drivers/net/wireless/ath5k/debug.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2007 Bruno Randolf <bruno@thinktube.com> 2 * Copyright (c) 2007-2008 Bruno Randolf <bruno@thinktube.com>
3 * 3 *
4 * This file is free software: you may copy, redistribute and/or modify it 4 * This file is free software: you may copy, redistribute and/or modify it
5 * under the terms of the GNU General Public License as published by the 5 * under the terms of the GNU General Public License as published by the
@@ -200,7 +200,7 @@ static ssize_t read_file_tsf(struct file *file, char __user *user_buf,
200{ 200{
201 struct ath5k_softc *sc = file->private_data; 201 struct ath5k_softc *sc = file->private_data;
202 char buf[100]; 202 char buf[100];
203 snprintf(buf, 100, "0x%016llx\n", ath5k_hw_get_tsf64(sc->ah)); 203 snprintf(buf, sizeof(buf), "0x%016llx\n", ath5k_hw_get_tsf64(sc->ah));
204 return simple_read_from_buffer(user_buf, count, ppos, buf, 19); 204 return simple_read_from_buffer(user_buf, count, ppos, buf, 19);
205} 205}
206 206
@@ -209,7 +209,12 @@ static ssize_t write_file_tsf(struct file *file,
209 size_t count, loff_t *ppos) 209 size_t count, loff_t *ppos)
210{ 210{
211 struct ath5k_softc *sc = file->private_data; 211 struct ath5k_softc *sc = file->private_data;
212 if (strncmp(userbuf, "reset", 5) == 0) { 212 char buf[20];
213
214 if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
215 return -EFAULT;
216
217 if (strncmp(buf, "reset", 5) == 0) {
213 ath5k_hw_reset_tsf(sc->ah); 218 ath5k_hw_reset_tsf(sc->ah);
214 printk(KERN_INFO "debugfs reset TSF\n"); 219 printk(KERN_INFO "debugfs reset TSF\n");
215 } 220 }
@@ -231,8 +236,8 @@ static ssize_t read_file_beacon(struct file *file, char __user *user_buf,
231{ 236{
232 struct ath5k_softc *sc = file->private_data; 237 struct ath5k_softc *sc = file->private_data;
233 struct ath5k_hw *ah = sc->ah; 238 struct ath5k_hw *ah = sc->ah;
234 char buf[1000]; 239 char buf[500];
235 int len = 0; 240 unsigned int len = 0;
236 unsigned int v; 241 unsigned int v;
237 u64 tsf; 242 u64 tsf;
238 243
@@ -277,11 +282,15 @@ static ssize_t write_file_beacon(struct file *file,
277{ 282{
278 struct ath5k_softc *sc = file->private_data; 283 struct ath5k_softc *sc = file->private_data;
279 struct ath5k_hw *ah = sc->ah; 284 struct ath5k_hw *ah = sc->ah;
285 char buf[20];
286
287 if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
288 return -EFAULT;
280 289
281 if (strncmp(userbuf, "disable", 7) == 0) { 290 if (strncmp(buf, "disable", 7) == 0) {
282 AR5K_REG_DISABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE); 291 AR5K_REG_DISABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE);
283 printk(KERN_INFO "debugfs disable beacons\n"); 292 printk(KERN_INFO "debugfs disable beacons\n");
284 } else if (strncmp(userbuf, "enable", 6) == 0) { 293 } else if (strncmp(buf, "enable", 6) == 0) {
285 AR5K_REG_ENABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE); 294 AR5K_REG_ENABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE);
286 printk(KERN_INFO "debugfs enable beacons\n"); 295 printk(KERN_INFO "debugfs enable beacons\n");
287 } 296 }
@@ -314,6 +323,82 @@ static const struct file_operations fops_reset = {
314}; 323};
315 324
316 325
326/* debugfs: debug level */
327
328static struct {
329 enum ath5k_debug_level level;
330 const char *name;
331 const char *desc;
332} dbg_info[] = {
333 { ATH5K_DEBUG_RESET, "reset", "reset and initialization" },
334 { ATH5K_DEBUG_INTR, "intr", "interrupt handling" },
335 { ATH5K_DEBUG_MODE, "mode", "mode init/setup" },
336 { ATH5K_DEBUG_XMIT, "xmit", "basic xmit operation" },
337 { ATH5K_DEBUG_BEACON, "beacon", "beacon handling" },
338 { ATH5K_DEBUG_CALIBRATE, "calib", "periodic calibration" },
339 { ATH5K_DEBUG_TXPOWER, "txpower", "transmit power setting" },
340 { ATH5K_DEBUG_LED, "led", "LED mamagement" },
341 { ATH5K_DEBUG_DUMP_RX, "dumprx", "print received skb content" },
342 { ATH5K_DEBUG_DUMP_TX, "dumptx", "print transmit skb content" },
343 { ATH5K_DEBUG_DUMPMODES, "dumpmodes", "dump modes" },
344 { ATH5K_DEBUG_TRACE, "trace", "trace function calls" },
345 { ATH5K_DEBUG_ANY, "all", "show all debug levels" },
346};
347
348static ssize_t read_file_debug(struct file *file, char __user *user_buf,
349 size_t count, loff_t *ppos)
350{
351 struct ath5k_softc *sc = file->private_data;
352 char buf[700];
353 unsigned int len = 0;
354 unsigned int i;
355
356 len += snprintf(buf+len, sizeof(buf)-len,
357 "DEBUG LEVEL: 0x%08x\n\n", sc->debug.level);
358
359 for (i = 0; i < ARRAY_SIZE(dbg_info) - 1; i++) {
360 len += snprintf(buf+len, sizeof(buf)-len,
361 "%10s %c 0x%08x - %s\n", dbg_info[i].name,
362 sc->debug.level & dbg_info[i].level ? '+' : ' ',
363 dbg_info[i].level, dbg_info[i].desc);
364 }
365 len += snprintf(buf+len, sizeof(buf)-len,
366 "%10s %c 0x%08x - %s\n", dbg_info[i].name,
367 sc->debug.level == dbg_info[i].level ? '+' : ' ',
368 dbg_info[i].level, dbg_info[i].desc);
369
370 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
371}
372
373static ssize_t write_file_debug(struct file *file,
374 const char __user *userbuf,
375 size_t count, loff_t *ppos)
376{
377 struct ath5k_softc *sc = file->private_data;
378 unsigned int i;
379 char buf[20];
380
381 if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
382 return -EFAULT;
383
384 for (i = 0; i < ARRAY_SIZE(dbg_info); i++) {
385 if (strncmp(buf, dbg_info[i].name,
386 strlen(dbg_info[i].name)) == 0) {
387 sc->debug.level ^= dbg_info[i].level; /* toggle bit */
388 break;
389 }
390 }
391 return count;
392}
393
394static const struct file_operations fops_debug = {
395 .read = read_file_debug,
396 .write = write_file_debug,
397 .open = ath5k_debugfs_open,
398 .owner = THIS_MODULE,
399};
400
401
317/* init */ 402/* init */
318 403
319void 404void
@@ -326,26 +411,24 @@ void
326ath5k_debug_init_device(struct ath5k_softc *sc) 411ath5k_debug_init_device(struct ath5k_softc *sc)
327{ 412{
328 sc->debug.level = ath5k_debug; 413 sc->debug.level = ath5k_debug;
414
329 sc->debug.debugfs_phydir = debugfs_create_dir(wiphy_name(sc->hw->wiphy), 415 sc->debug.debugfs_phydir = debugfs_create_dir(wiphy_name(sc->hw->wiphy),
330 ath5k_global_debugfs); 416 ath5k_global_debugfs);
331 sc->debug.debugfs_debug = debugfs_create_u32("debug", 417
332 0666, sc->debug.debugfs_phydir, &sc->debug.level); 418 sc->debug.debugfs_debug = debugfs_create_file("debug", 0666,
419 sc->debug.debugfs_phydir, sc, &fops_debug);
333 420
334 sc->debug.debugfs_registers = debugfs_create_file("registers", 0444, 421 sc->debug.debugfs_registers = debugfs_create_file("registers", 0444,
335 sc->debug.debugfs_phydir, 422 sc->debug.debugfs_phydir, sc, &fops_registers);
336 sc, &fops_registers);
337 423
338 sc->debug.debugfs_tsf = debugfs_create_file("tsf", 0666, 424 sc->debug.debugfs_tsf = debugfs_create_file("tsf", 0666,
339 sc->debug.debugfs_phydir, 425 sc->debug.debugfs_phydir, sc, &fops_tsf);
340 sc, &fops_tsf);
341 426
342 sc->debug.debugfs_beacon = debugfs_create_file("beacon", 0666, 427 sc->debug.debugfs_beacon = debugfs_create_file("beacon", 0666,
343 sc->debug.debugfs_phydir, 428 sc->debug.debugfs_phydir, sc, &fops_beacon);
344 sc, &fops_beacon);
345 429
346 sc->debug.debugfs_reset = debugfs_create_file("reset", 0222, 430 sc->debug.debugfs_reset = debugfs_create_file("reset", 0222,
347 sc->debug.debugfs_phydir, 431 sc->debug.debugfs_phydir, sc, &fops_reset);
348 sc, &fops_reset);
349} 432}
350 433
351void 434void
@@ -415,8 +498,7 @@ ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah)
415 struct ath5k_buf *bf; 498 struct ath5k_buf *bf;
416 int status; 499 int status;
417 500
418 if (likely(!(sc->debug.level & 501 if (likely(!(sc->debug.level & ATH5K_DEBUG_RESET)))
419 (ATH5K_DEBUG_RESET | ATH5K_DEBUG_FATAL))))
420 return; 502 return;
421 503
422 printk(KERN_DEBUG "rx queue %x, link %p\n", 504 printk(KERN_DEBUG "rx queue %x, link %p\n",
@@ -426,7 +508,7 @@ ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah)
426 list_for_each_entry(bf, &sc->rxbuf, list) { 508 list_for_each_entry(bf, &sc->rxbuf, list) {
427 ds = bf->desc; 509 ds = bf->desc;
428 status = ah->ah_proc_rx_desc(ah, ds); 510 status = ah->ah_proc_rx_desc(ah, ds);
429 if (!status || (sc->debug.level & ATH5K_DEBUG_FATAL)) 511 if (!status)
430 ath5k_debug_printrxbuf(bf, status == 0); 512 ath5k_debug_printrxbuf(bf, status == 0);
431 } 513 }
432 spin_unlock_bh(&sc->rxbuflock); 514 spin_unlock_bh(&sc->rxbuflock);
diff --git a/drivers/net/wireless/ath5k/debug.h b/drivers/net/wireless/ath5k/debug.h
index 2b491cbc8c80..c4fd8c43df0c 100644
--- a/drivers/net/wireless/ath5k/debug.h
+++ b/drivers/net/wireless/ath5k/debug.h
@@ -91,7 +91,6 @@ struct ath5k_dbg_info {
91 * @ATH5K_DEBUG_MODE: mode init/setup 91 * @ATH5K_DEBUG_MODE: mode init/setup
92 * @ATH5K_DEBUG_XMIT: basic xmit operation 92 * @ATH5K_DEBUG_XMIT: basic xmit operation
93 * @ATH5K_DEBUG_BEACON: beacon handling 93 * @ATH5K_DEBUG_BEACON: beacon handling
94 * @ATH5K_DEBUG_BEACON_PROC: beacon ISR proc
95 * @ATH5K_DEBUG_CALIBRATE: periodic calibration 94 * @ATH5K_DEBUG_CALIBRATE: periodic calibration
96 * @ATH5K_DEBUG_TXPOWER: transmit power setting 95 * @ATH5K_DEBUG_TXPOWER: transmit power setting
97 * @ATH5K_DEBUG_LED: led management 96 * @ATH5K_DEBUG_LED: led management
@@ -99,7 +98,6 @@ struct ath5k_dbg_info {
99 * @ATH5K_DEBUG_DUMP_TX: print transmit skb content 98 * @ATH5K_DEBUG_DUMP_TX: print transmit skb content
100 * @ATH5K_DEBUG_DUMPMODES: dump modes 99 * @ATH5K_DEBUG_DUMPMODES: dump modes
101 * @ATH5K_DEBUG_TRACE: trace function calls 100 * @ATH5K_DEBUG_TRACE: trace function calls
102 * @ATH5K_DEBUG_FATAL: fatal errors
103 * @ATH5K_DEBUG_ANY: show at any debug level 101 * @ATH5K_DEBUG_ANY: show at any debug level
104 * 102 *
105 * The debug level is used to control the amount and type of debugging output 103 * The debug level is used to control the amount and type of debugging output
@@ -115,15 +113,13 @@ enum ath5k_debug_level {
115 ATH5K_DEBUG_MODE = 0x00000004, 113 ATH5K_DEBUG_MODE = 0x00000004,
116 ATH5K_DEBUG_XMIT = 0x00000008, 114 ATH5K_DEBUG_XMIT = 0x00000008,
117 ATH5K_DEBUG_BEACON = 0x00000010, 115 ATH5K_DEBUG_BEACON = 0x00000010,
118 ATH5K_DEBUG_BEACON_PROC = 0x00000020, 116 ATH5K_DEBUG_CALIBRATE = 0x00000020,
119 ATH5K_DEBUG_CALIBRATE = 0x00000100, 117 ATH5K_DEBUG_TXPOWER = 0x00000040,
120 ATH5K_DEBUG_TXPOWER = 0x00000200, 118 ATH5K_DEBUG_LED = 0x00000080,
121 ATH5K_DEBUG_LED = 0x00000400, 119 ATH5K_DEBUG_DUMP_RX = 0x00000100,
122 ATH5K_DEBUG_DUMP_RX = 0x00001000, 120 ATH5K_DEBUG_DUMP_TX = 0x00000200,
123 ATH5K_DEBUG_DUMP_TX = 0x00002000, 121 ATH5K_DEBUG_DUMPMODES = 0x00000400,
124 ATH5K_DEBUG_DUMPMODES = 0x00004000, 122 ATH5K_DEBUG_TRACE = 0x00001000,
125 ATH5K_DEBUG_TRACE = 0x00010000,
126 ATH5K_DEBUG_FATAL = 0x80000000,
127 ATH5K_DEBUG_ANY = 0xffffffff 123 ATH5K_DEBUG_ANY = 0xffffffff
128}; 124};
129 125
diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c
index 3e73d2a523aa..8a708b77925d 100644
--- a/drivers/net/wireless/b43/dma.c
+++ b/drivers/net/wireless/b43/dma.c
@@ -1114,7 +1114,7 @@ static int dma_tx_fragment(struct b43_dmaring *ring,
1114{ 1114{
1115 const struct b43_dma_ops *ops = ring->ops; 1115 const struct b43_dma_ops *ops = ring->ops;
1116 u8 *header; 1116 u8 *header;
1117 int slot; 1117 int slot, old_top_slot, old_used_slots;
1118 int err; 1118 int err;
1119 struct b43_dmadesc_generic *desc; 1119 struct b43_dmadesc_generic *desc;
1120 struct b43_dmadesc_meta *meta; 1120 struct b43_dmadesc_meta *meta;
@@ -1126,6 +1126,9 @@ static int dma_tx_fragment(struct b43_dmaring *ring,
1126#define SLOTS_PER_PACKET 2 1126#define SLOTS_PER_PACKET 2
1127 B43_WARN_ON(skb_shinfo(skb)->nr_frags); 1127 B43_WARN_ON(skb_shinfo(skb)->nr_frags);
1128 1128
1129 old_top_slot = ring->current_slot;
1130 old_used_slots = ring->used_slots;
1131
1129 /* Get a slot for the header. */ 1132 /* Get a slot for the header. */
1130 slot = request_slot(ring); 1133 slot = request_slot(ring);
1131 desc = ops->idx2desc(ring, slot, &meta_hdr); 1134 desc = ops->idx2desc(ring, slot, &meta_hdr);
@@ -1133,13 +1136,21 @@ static int dma_tx_fragment(struct b43_dmaring *ring,
1133 1136
1134 header = &(ring->txhdr_cache[slot * hdrsize]); 1137 header = &(ring->txhdr_cache[slot * hdrsize]);
1135 cookie = generate_cookie(ring, slot); 1138 cookie = generate_cookie(ring, slot);
1136 b43_generate_txhdr(ring->dev, header, 1139 err = b43_generate_txhdr(ring->dev, header,
1137 skb->data, skb->len, ctl, cookie); 1140 skb->data, skb->len, ctl, cookie);
1141 if (unlikely(err)) {
1142 ring->current_slot = old_top_slot;
1143 ring->used_slots = old_used_slots;
1144 return err;
1145 }
1138 1146
1139 meta_hdr->dmaaddr = map_descbuffer(ring, (unsigned char *)header, 1147 meta_hdr->dmaaddr = map_descbuffer(ring, (unsigned char *)header,
1140 hdrsize, 1); 1148 hdrsize, 1);
1141 if (dma_mapping_error(meta_hdr->dmaaddr)) 1149 if (dma_mapping_error(meta_hdr->dmaaddr)) {
1150 ring->current_slot = old_top_slot;
1151 ring->used_slots = old_used_slots;
1142 return -EIO; 1152 return -EIO;
1153 }
1143 ops->fill_descriptor(ring, desc, meta_hdr->dmaaddr, 1154 ops->fill_descriptor(ring, desc, meta_hdr->dmaaddr,
1144 hdrsize, 1, 0, 0); 1155 hdrsize, 1, 0, 0);
1145 1156
@@ -1157,6 +1168,8 @@ static int dma_tx_fragment(struct b43_dmaring *ring,
1157 if (dma_mapping_error(meta->dmaaddr)) { 1168 if (dma_mapping_error(meta->dmaaddr)) {
1158 bounce_skb = __dev_alloc_skb(skb->len, GFP_ATOMIC | GFP_DMA); 1169 bounce_skb = __dev_alloc_skb(skb->len, GFP_ATOMIC | GFP_DMA);
1159 if (!bounce_skb) { 1170 if (!bounce_skb) {
1171 ring->current_slot = old_top_slot;
1172 ring->used_slots = old_used_slots;
1160 err = -ENOMEM; 1173 err = -ENOMEM;
1161 goto out_unmap_hdr; 1174 goto out_unmap_hdr;
1162 } 1175 }
@@ -1167,6 +1180,8 @@ static int dma_tx_fragment(struct b43_dmaring *ring,
1167 meta->skb = skb; 1180 meta->skb = skb;
1168 meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1); 1181 meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1);
1169 if (dma_mapping_error(meta->dmaaddr)) { 1182 if (dma_mapping_error(meta->dmaaddr)) {
1183 ring->current_slot = old_top_slot;
1184 ring->used_slots = old_used_slots;
1170 err = -EIO; 1185 err = -EIO;
1171 goto out_free_bounce; 1186 goto out_free_bounce;
1172 } 1187 }
@@ -1252,6 +1267,13 @@ int b43_dma_tx(struct b43_wldev *dev,
1252 B43_WARN_ON(ring->stopped); 1267 B43_WARN_ON(ring->stopped);
1253 1268
1254 err = dma_tx_fragment(ring, skb, ctl); 1269 err = dma_tx_fragment(ring, skb, ctl);
1270 if (unlikely(err == -ENOKEY)) {
1271 /* Drop this packet, as we don't have the encryption key
1272 * anymore and must not transmit it unencrypted. */
1273 dev_kfree_skb_any(skb);
1274 err = 0;
1275 goto out_unlock;
1276 }
1255 if (unlikely(err)) { 1277 if (unlikely(err)) {
1256 b43err(dev->wl, "DMA tx mapping failure\n"); 1278 b43err(dev->wl, "DMA tx mapping failure\n");
1257 goto out_unlock; 1279 goto out_unlock;
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 88d2c15d3fbe..64c154d080d8 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -3532,8 +3532,6 @@ static int b43_wireless_core_init(struct b43_wldev *dev)
3532 b43_bluetooth_coext_enable(dev); 3532 b43_bluetooth_coext_enable(dev);
3533 3533
3534 ssb_bus_powerup(bus, 1); /* Enable dynamic PCTL */ 3534 ssb_bus_powerup(bus, 1); /* Enable dynamic PCTL */
3535 memset(wl->bssid, 0, ETH_ALEN);
3536 memset(wl->mac_addr, 0, ETH_ALEN);
3537 b43_upload_card_macaddress(dev); 3535 b43_upload_card_macaddress(dev);
3538 b43_security_init(dev); 3536 b43_security_init(dev);
3539 b43_rng_init(wl); 3537 b43_rng_init(wl);
@@ -3630,6 +3628,15 @@ static int b43_op_start(struct ieee80211_hw *hw)
3630 struct b43_wldev *dev = wl->current_dev; 3628 struct b43_wldev *dev = wl->current_dev;
3631 int did_init = 0; 3629 int did_init = 0;
3632 int err = 0; 3630 int err = 0;
3631 bool do_rfkill_exit = 0;
3632
3633 /* Kill all old instance specific information to make sure
3634 * the card won't use it in the short timeframe between start
3635 * and mac80211 reconfiguring it. */
3636 memset(wl->bssid, 0, ETH_ALEN);
3637 memset(wl->mac_addr, 0, ETH_ALEN);
3638 wl->filter_flags = 0;
3639 wl->radiotap_enabled = 0;
3633 3640
3634 /* First register RFkill. 3641 /* First register RFkill.
3635 * LEDs that are registered later depend on it. */ 3642 * LEDs that are registered later depend on it. */
@@ -3639,8 +3646,10 @@ static int b43_op_start(struct ieee80211_hw *hw)
3639 3646
3640 if (b43_status(dev) < B43_STAT_INITIALIZED) { 3647 if (b43_status(dev) < B43_STAT_INITIALIZED) {
3641 err = b43_wireless_core_init(dev); 3648 err = b43_wireless_core_init(dev);
3642 if (err) 3649 if (err) {
3650 do_rfkill_exit = 1;
3643 goto out_mutex_unlock; 3651 goto out_mutex_unlock;
3652 }
3644 did_init = 1; 3653 did_init = 1;
3645 } 3654 }
3646 3655
@@ -3649,6 +3658,7 @@ static int b43_op_start(struct ieee80211_hw *hw)
3649 if (err) { 3658 if (err) {
3650 if (did_init) 3659 if (did_init)
3651 b43_wireless_core_exit(dev); 3660 b43_wireless_core_exit(dev);
3661 do_rfkill_exit = 1;
3652 goto out_mutex_unlock; 3662 goto out_mutex_unlock;
3653 } 3663 }
3654 } 3664 }
@@ -3656,6 +3666,9 @@ static int b43_op_start(struct ieee80211_hw *hw)
3656 out_mutex_unlock: 3666 out_mutex_unlock:
3657 mutex_unlock(&wl->mutex); 3667 mutex_unlock(&wl->mutex);
3658 3668
3669 if (do_rfkill_exit)
3670 b43_rfkill_exit(dev);
3671
3659 return err; 3672 return err;
3660} 3673}
3661 3674
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c
index 3fc53e8b4416..7caa26eb4105 100644
--- a/drivers/net/wireless/b43/xmit.c
+++ b/drivers/net/wireless/b43/xmit.c
@@ -178,12 +178,12 @@ static u8 b43_calc_fallback_rate(u8 bitrate)
178} 178}
179 179
180/* Generate a TX data header. */ 180/* Generate a TX data header. */
181void b43_generate_txhdr(struct b43_wldev *dev, 181int b43_generate_txhdr(struct b43_wldev *dev,
182 u8 *_txhdr, 182 u8 *_txhdr,
183 const unsigned char *fragment_data, 183 const unsigned char *fragment_data,
184 unsigned int fragment_len, 184 unsigned int fragment_len,
185 const struct ieee80211_tx_control *txctl, 185 const struct ieee80211_tx_control *txctl,
186 u16 cookie) 186 u16 cookie)
187{ 187{
188 struct b43_txhdr *txhdr = (struct b43_txhdr *)_txhdr; 188 struct b43_txhdr *txhdr = (struct b43_txhdr *)_txhdr;
189 const struct b43_phy *phy = &dev->phy; 189 const struct b43_phy *phy = &dev->phy;
@@ -237,7 +237,15 @@ void b43_generate_txhdr(struct b43_wldev *dev,
237 237
238 B43_WARN_ON(key_idx >= dev->max_nr_keys); 238 B43_WARN_ON(key_idx >= dev->max_nr_keys);
239 key = &(dev->key[key_idx]); 239 key = &(dev->key[key_idx]);
240 B43_WARN_ON(!key->keyconf); 240
241 if (unlikely(!key->keyconf)) {
242 /* This key is invalid. This might only happen
243 * in a short timeframe after machine resume before
244 * we were able to reconfigure keys.
245 * Drop this packet completely. Do not transmit it
246 * unencrypted to avoid leaking information. */
247 return -ENOKEY;
248 }
241 249
242 /* Hardware appends ICV. */ 250 /* Hardware appends ICV. */
243 plcp_fragment_len += txctl->icv_len; 251 plcp_fragment_len += txctl->icv_len;
@@ -408,6 +416,7 @@ void b43_generate_txhdr(struct b43_wldev *dev,
408 txhdr->phy_ctl = cpu_to_le16(phy_ctl); 416 txhdr->phy_ctl = cpu_to_le16(phy_ctl);
409 txhdr->extra_ft = extra_ft; 417 txhdr->extra_ft = extra_ft;
410 418
419 return 0;
411} 420}
412 421
413static s8 b43_rssi_postprocess(struct b43_wldev *dev, 422static s8 b43_rssi_postprocess(struct b43_wldev *dev,
diff --git a/drivers/net/wireless/b43/xmit.h b/drivers/net/wireless/b43/xmit.h
index ca2a2ab8654c..41765039552b 100644
--- a/drivers/net/wireless/b43/xmit.h
+++ b/drivers/net/wireless/b43/xmit.h
@@ -174,11 +174,11 @@ size_t b43_txhdr_size(struct b43_wldev *dev)
174} 174}
175 175
176 176
177void b43_generate_txhdr(struct b43_wldev *dev, 177int b43_generate_txhdr(struct b43_wldev *dev,
178 u8 * txhdr, 178 u8 * txhdr,
179 const unsigned char *fragment_data, 179 const unsigned char *fragment_data,
180 unsigned int fragment_len, 180 unsigned int fragment_len,
181 const struct ieee80211_tx_control *txctl, u16 cookie); 181 const struct ieee80211_tx_control *txctl, u16 cookie);
182 182
183/* Transmit Status */ 183/* Transmit Status */
184struct b43_txstatus { 184struct b43_txstatus {
diff --git a/drivers/net/wireless/b43legacy/b43legacy.h b/drivers/net/wireless/b43legacy/b43legacy.h
index 93419adb925e..c80edd2b9044 100644
--- a/drivers/net/wireless/b43legacy/b43legacy.h
+++ b/drivers/net/wireless/b43legacy/b43legacy.h
@@ -23,7 +23,7 @@
23#include "phy.h" 23#include "phy.h"
24 24
25 25
26#define B43legacy_IRQWAIT_MAX_RETRIES 100 26#define B43legacy_IRQWAIT_MAX_RETRIES 20
27 27
28#define B43legacy_RX_MAX_SSI 60 /* best guess at max ssi */ 28#define B43legacy_RX_MAX_SSI 60 /* best guess at max ssi */
29 29
@@ -40,9 +40,8 @@
40#define B43legacy_MMIO_DMA4_IRQ_MASK 0x44 40#define B43legacy_MMIO_DMA4_IRQ_MASK 0x44
41#define B43legacy_MMIO_DMA5_REASON 0x48 41#define B43legacy_MMIO_DMA5_REASON 0x48
42#define B43legacy_MMIO_DMA5_IRQ_MASK 0x4C 42#define B43legacy_MMIO_DMA5_IRQ_MASK 0x4C
43#define B43legacy_MMIO_MACCTL 0x120 43#define B43legacy_MMIO_MACCTL 0x120 /* MAC control */
44#define B43legacy_MMIO_STATUS_BITFIELD 0x120 44#define B43legacy_MMIO_MACCMD 0x124 /* MAC command */
45#define B43legacy_MMIO_STATUS2_BITFIELD 0x124
46#define B43legacy_MMIO_GEN_IRQ_REASON 0x128 45#define B43legacy_MMIO_GEN_IRQ_REASON 0x128
47#define B43legacy_MMIO_GEN_IRQ_MASK 0x12C 46#define B43legacy_MMIO_GEN_IRQ_MASK 0x12C
48#define B43legacy_MMIO_RAM_CONTROL 0x130 47#define B43legacy_MMIO_RAM_CONTROL 0x130
@@ -177,31 +176,25 @@
177#define B43legacy_RADIOCTL_ID 0x01 176#define B43legacy_RADIOCTL_ID 0x01
178 177
179/* MAC Control bitfield */ 178/* MAC Control bitfield */
179#define B43legacy_MACCTL_ENABLED 0x00000001 /* MAC Enabled */
180#define B43legacy_MACCTL_PSM_RUN 0x00000002 /* Run Microcode */
181#define B43legacy_MACCTL_PSM_JMP0 0x00000004 /* Microcode jump to 0 */
182#define B43legacy_MACCTL_SHM_ENABLED 0x00000100 /* SHM Enabled */
180#define B43legacy_MACCTL_IHR_ENABLED 0x00000400 /* IHR Region Enabled */ 183#define B43legacy_MACCTL_IHR_ENABLED 0x00000400 /* IHR Region Enabled */
184#define B43legacy_MACCTL_BE 0x00010000 /* Big Endian mode */
181#define B43legacy_MACCTL_INFRA 0x00020000 /* Infrastructure mode */ 185#define B43legacy_MACCTL_INFRA 0x00020000 /* Infrastructure mode */
182#define B43legacy_MACCTL_AP 0x00040000 /* AccessPoint mode */ 186#define B43legacy_MACCTL_AP 0x00040000 /* AccessPoint mode */
187#define B43legacy_MACCTL_RADIOLOCK 0x00080000 /* Radio lock */
183#define B43legacy_MACCTL_BEACPROMISC 0x00100000 /* Beacon Promiscuous */ 188#define B43legacy_MACCTL_BEACPROMISC 0x00100000 /* Beacon Promiscuous */
184#define B43legacy_MACCTL_KEEP_BADPLCP 0x00200000 /* Keep bad PLCP frames */ 189#define B43legacy_MACCTL_KEEP_BADPLCP 0x00200000 /* Keep bad PLCP frames */
185#define B43legacy_MACCTL_KEEP_CTL 0x00400000 /* Keep control frames */ 190#define B43legacy_MACCTL_KEEP_CTL 0x00400000 /* Keep control frames */
186#define B43legacy_MACCTL_KEEP_BAD 0x00800000 /* Keep bad frames (FCS) */ 191#define B43legacy_MACCTL_KEEP_BAD 0x00800000 /* Keep bad frames (FCS) */
187#define B43legacy_MACCTL_PROMISC 0x01000000 /* Promiscuous mode */ 192#define B43legacy_MACCTL_PROMISC 0x01000000 /* Promiscuous mode */
193#define B43legacy_MACCTL_HWPS 0x02000000 /* Hardware Power Saving */
194#define B43legacy_MACCTL_AWAKE 0x04000000 /* Device is awake */
195#define B43legacy_MACCTL_TBTTHOLD 0x10000000 /* TBTT Hold */
188#define B43legacy_MACCTL_GMODE 0x80000000 /* G Mode */ 196#define B43legacy_MACCTL_GMODE 0x80000000 /* G Mode */
189 197
190/* StatusBitField */
191#define B43legacy_SBF_MAC_ENABLED 0x00000001
192#define B43legacy_SBF_CORE_READY 0x00000004
193#define B43legacy_SBF_400 0x00000400 /*FIXME: fix name*/
194#define B43legacy_SBF_XFER_REG_BYTESWAP 0x00010000
195#define B43legacy_SBF_MODE_NOTADHOC 0x00020000
196#define B43legacy_SBF_MODE_AP 0x00040000
197#define B43legacy_SBF_RADIOREG_LOCK 0x00080000
198#define B43legacy_SBF_MODE_MONITOR 0x00400000
199#define B43legacy_SBF_MODE_PROMISC 0x01000000
200#define B43legacy_SBF_PS1 0x02000000
201#define B43legacy_SBF_PS2 0x04000000
202#define B43legacy_SBF_NO_SSID_BCAST 0x08000000
203#define B43legacy_SBF_TIME_UPDATE 0x10000000
204
205/* 802.11 core specific TM State Low flags */ 198/* 802.11 core specific TM State Low flags */
206#define B43legacy_TMSLOW_GMODE 0x20000000 /* G Mode Enable */ 199#define B43legacy_TMSLOW_GMODE 0x20000000 /* G Mode Enable */
207#define B43legacy_TMSLOW_PLLREFSEL 0x00200000 /* PLL Freq Ref Select */ 200#define B43legacy_TMSLOW_PLLREFSEL 0x00200000 /* PLL Freq Ref Select */
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c
index 4ed4243feeaa..aa20d5d56e2f 100644
--- a/drivers/net/wireless/b43legacy/main.c
+++ b/drivers/net/wireless/b43legacy/main.c
@@ -225,8 +225,8 @@ static void b43legacy_ram_write(struct b43legacy_wldev *dev, u16 offset,
225 225
226 B43legacy_WARN_ON(offset % 4 != 0); 226 B43legacy_WARN_ON(offset % 4 != 0);
227 227
228 status = b43legacy_read32(dev, B43legacy_MMIO_STATUS_BITFIELD); 228 status = b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
229 if (status & B43legacy_SBF_XFER_REG_BYTESWAP) 229 if (status & B43legacy_MACCTL_BE)
230 val = swab32(val); 230 val = swab32(val);
231 231
232 b43legacy_write32(dev, B43legacy_MMIO_RAM_CONTROL, offset); 232 b43legacy_write32(dev, B43legacy_MMIO_RAM_CONTROL, offset);
@@ -434,9 +434,9 @@ static void b43legacy_time_lock(struct b43legacy_wldev *dev)
434{ 434{
435 u32 status; 435 u32 status;
436 436
437 status = b43legacy_read32(dev, B43legacy_MMIO_STATUS_BITFIELD); 437 status = b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
438 status |= B43legacy_SBF_TIME_UPDATE; 438 status |= B43legacy_MACCTL_TBTTHOLD;
439 b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD, status); 439 b43legacy_write32(dev, B43legacy_MMIO_MACCTL, status);
440 mmiowb(); 440 mmiowb();
441} 441}
442 442
@@ -444,9 +444,9 @@ static void b43legacy_time_unlock(struct b43legacy_wldev *dev)
444{ 444{
445 u32 status; 445 u32 status;
446 446
447 status = b43legacy_read32(dev, B43legacy_MMIO_STATUS_BITFIELD); 447 status = b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
448 status &= ~B43legacy_SBF_TIME_UPDATE; 448 status &= ~B43legacy_MACCTL_TBTTHOLD;
449 b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD, status); 449 b43legacy_write32(dev, B43legacy_MMIO_MACCTL, status);
450} 450}
451 451
452static void b43legacy_tsf_write_locked(struct b43legacy_wldev *dev, u64 tsf) 452static void b43legacy_tsf_write_locked(struct b43legacy_wldev *dev, u64 tsf)
@@ -647,7 +647,7 @@ void b43legacy_dummy_transmission(struct b43legacy_wldev *dev)
647 b43legacy_ram_write(dev, i * 4, buffer[i]); 647 b43legacy_ram_write(dev, i * 4, buffer[i]);
648 648
649 /* dummy read follows */ 649 /* dummy read follows */
650 b43legacy_read32(dev, B43legacy_MMIO_STATUS_BITFIELD); 650 b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
651 651
652 b43legacy_write16(dev, 0x0568, 0x0000); 652 b43legacy_write16(dev, 0x0568, 0x0000);
653 b43legacy_write16(dev, 0x07C0, 0x0000); 653 b43legacy_write16(dev, 0x07C0, 0x0000);
@@ -794,9 +794,9 @@ static void b43legacy_jssi_write(struct b43legacy_wldev *dev, u32 jssi)
794static void b43legacy_generate_noise_sample(struct b43legacy_wldev *dev) 794static void b43legacy_generate_noise_sample(struct b43legacy_wldev *dev)
795{ 795{
796 b43legacy_jssi_write(dev, 0x7F7F7F7F); 796 b43legacy_jssi_write(dev, 0x7F7F7F7F);
797 b43legacy_write32(dev, B43legacy_MMIO_STATUS2_BITFIELD, 797 b43legacy_write32(dev, B43legacy_MMIO_MACCMD,
798 b43legacy_read32(dev, 798 b43legacy_read32(dev,
799 B43legacy_MMIO_STATUS2_BITFIELD) 799 B43legacy_MMIO_MACCMD)
800 | (1 << 4)); 800 | (1 << 4));
801 B43legacy_WARN_ON(dev->noisecalc.channel_at_start != 801 B43legacy_WARN_ON(dev->noisecalc.channel_at_start !=
802 dev->phy.channel); 802 dev->phy.channel);
@@ -895,8 +895,8 @@ static void handle_irq_atim_end(struct b43legacy_wldev *dev)
895{ 895{
896 if (!dev->reg124_set_0x4) /*FIXME rename this variable*/ 896 if (!dev->reg124_set_0x4) /*FIXME rename this variable*/
897 return; 897 return;
898 b43legacy_write32(dev, B43legacy_MMIO_STATUS2_BITFIELD, 898 b43legacy_write32(dev, B43legacy_MMIO_MACCMD,
899 b43legacy_read32(dev, B43legacy_MMIO_STATUS2_BITFIELD) 899 b43legacy_read32(dev, B43legacy_MMIO_MACCMD)
900 | 0x4); 900 | 0x4);
901} 901}
902 902
@@ -1106,9 +1106,9 @@ static void b43legacy_update_templates(struct b43legacy_wldev *dev)
1106 b43legacy_write_probe_resp_template(dev, 0x268, 0x4A, 1106 b43legacy_write_probe_resp_template(dev, 0x268, 0x4A,
1107 B43legacy_CCK_RATE_11MB); 1107 B43legacy_CCK_RATE_11MB);
1108 1108
1109 status = b43legacy_read32(dev, B43legacy_MMIO_STATUS2_BITFIELD); 1109 status = b43legacy_read32(dev, B43legacy_MMIO_MACCMD);
1110 status |= 0x03; 1110 status |= 0x03;
1111 b43legacy_write32(dev, B43legacy_MMIO_STATUS2_BITFIELD, status); 1111 b43legacy_write32(dev, B43legacy_MMIO_MACCMD, status);
1112} 1112}
1113 1113
1114static void b43legacy_refresh_templates(struct b43legacy_wldev *dev, 1114static void b43legacy_refresh_templates(struct b43legacy_wldev *dev,
@@ -1166,7 +1166,7 @@ static void handle_irq_beacon(struct b43legacy_wldev *dev)
1166 return; 1166 return;
1167 1167
1168 dev->irq_savedstate &= ~B43legacy_IRQ_BEACON; 1168 dev->irq_savedstate &= ~B43legacy_IRQ_BEACON;
1169 status = b43legacy_read32(dev, B43legacy_MMIO_STATUS2_BITFIELD); 1169 status = b43legacy_read32(dev, B43legacy_MMIO_MACCMD);
1170 1170
1171 if (!dev->cached_beacon || ((status & 0x1) && (status & 0x2))) { 1171 if (!dev->cached_beacon || ((status & 0x1) && (status & 0x2))) {
1172 /* ACK beacon IRQ. */ 1172 /* ACK beacon IRQ. */
@@ -1182,14 +1182,14 @@ static void handle_irq_beacon(struct b43legacy_wldev *dev)
1182 b43legacy_write_beacon_template(dev, 0x68, 0x18, 1182 b43legacy_write_beacon_template(dev, 0x68, 0x18,
1183 B43legacy_CCK_RATE_1MB); 1183 B43legacy_CCK_RATE_1MB);
1184 status |= 0x1; 1184 status |= 0x1;
1185 b43legacy_write32(dev, B43legacy_MMIO_STATUS2_BITFIELD, 1185 b43legacy_write32(dev, B43legacy_MMIO_MACCMD,
1186 status); 1186 status);
1187 } 1187 }
1188 if (!(status & 0x2)) { 1188 if (!(status & 0x2)) {
1189 b43legacy_write_beacon_template(dev, 0x468, 0x1A, 1189 b43legacy_write_beacon_template(dev, 0x468, 0x1A,
1190 B43legacy_CCK_RATE_1MB); 1190 B43legacy_CCK_RATE_1MB);
1191 status |= 0x2; 1191 status |= 0x2;
1192 b43legacy_write32(dev, B43legacy_MMIO_STATUS2_BITFIELD, 1192 b43legacy_write32(dev, B43legacy_MMIO_MACCMD,
1193 status); 1193 status);
1194 } 1194 }
1195} 1195}
@@ -1548,9 +1548,20 @@ static int b43legacy_upload_microcode(struct b43legacy_wldev *dev)
1548 u16 fwpatch; 1548 u16 fwpatch;
1549 u16 fwdate; 1549 u16 fwdate;
1550 u16 fwtime; 1550 u16 fwtime;
1551 u32 tmp; 1551 u32 tmp, macctl;
1552 int err = 0; 1552 int err = 0;
1553 1553
1554 /* Jump the microcode PSM to offset 0 */
1555 macctl = b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
1556 B43legacy_WARN_ON(macctl & B43legacy_MACCTL_PSM_RUN);
1557 macctl |= B43legacy_MACCTL_PSM_JMP0;
1558 b43legacy_write32(dev, B43legacy_MMIO_MACCTL, macctl);
1559 /* Zero out all microcode PSM registers and shared memory. */
1560 for (i = 0; i < 64; i++)
1561 b43legacy_shm_write16(dev, B43legacy_SHM_WIRELESS, i, 0);
1562 for (i = 0; i < 4096; i += 2)
1563 b43legacy_shm_write16(dev, B43legacy_SHM_SHARED, i, 0);
1564
1554 /* Upload Microcode. */ 1565 /* Upload Microcode. */
1555 data = (__be32 *) (dev->fw.ucode->data + hdr_len); 1566 data = (__be32 *) (dev->fw.ucode->data + hdr_len);
1556 len = (dev->fw.ucode->size - hdr_len) / sizeof(__be32); 1567 len = (dev->fw.ucode->size - hdr_len) / sizeof(__be32);
@@ -1581,7 +1592,12 @@ static int b43legacy_upload_microcode(struct b43legacy_wldev *dev)
1581 1592
1582 b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_REASON, 1593 b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_REASON,
1583 B43legacy_IRQ_ALL); 1594 B43legacy_IRQ_ALL);
1584 b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD, 0x00020402); 1595
1596 /* Start the microcode PSM */
1597 macctl = b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
1598 macctl &= ~B43legacy_MACCTL_PSM_JMP0;
1599 macctl |= B43legacy_MACCTL_PSM_RUN;
1600 b43legacy_write32(dev, B43legacy_MMIO_MACCTL, macctl);
1585 1601
1586 /* Wait for the microcode to load and respond */ 1602 /* Wait for the microcode to load and respond */
1587 i = 0; 1603 i = 0;
@@ -1594,9 +1610,13 @@ static int b43legacy_upload_microcode(struct b43legacy_wldev *dev)
1594 b43legacyerr(dev->wl, "Microcode not responding\n"); 1610 b43legacyerr(dev->wl, "Microcode not responding\n");
1595 b43legacy_print_fw_helptext(dev->wl); 1611 b43legacy_print_fw_helptext(dev->wl);
1596 err = -ENODEV; 1612 err = -ENODEV;
1597 goto out; 1613 goto error;
1614 }
1615 msleep_interruptible(50);
1616 if (signal_pending(current)) {
1617 err = -EINTR;
1618 goto error;
1598 } 1619 }
1599 udelay(10);
1600 } 1620 }
1601 /* dummy read follows */ 1621 /* dummy read follows */
1602 b43legacy_read32(dev, B43legacy_MMIO_GEN_IRQ_REASON); 1622 b43legacy_read32(dev, B43legacy_MMIO_GEN_IRQ_REASON);
@@ -1617,9 +1637,8 @@ static int b43legacy_upload_microcode(struct b43legacy_wldev *dev)
1617 " is supported. You must change your firmware" 1637 " is supported. You must change your firmware"
1618 " files.\n"); 1638 " files.\n");
1619 b43legacy_print_fw_helptext(dev->wl); 1639 b43legacy_print_fw_helptext(dev->wl);
1620 b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD, 0);
1621 err = -EOPNOTSUPP; 1640 err = -EOPNOTSUPP;
1622 goto out; 1641 goto error;
1623 } 1642 }
1624 b43legacydbg(dev->wl, "Loading firmware version 0x%X, patch level %u " 1643 b43legacydbg(dev->wl, "Loading firmware version 0x%X, patch level %u "
1625 "(20%.2i-%.2i-%.2i %.2i:%.2i:%.2i)\n", fwrev, fwpatch, 1644 "(20%.2i-%.2i-%.2i %.2i:%.2i:%.2i)\n", fwrev, fwpatch,
@@ -1629,7 +1648,14 @@ static int b43legacy_upload_microcode(struct b43legacy_wldev *dev)
1629 dev->fw.rev = fwrev; 1648 dev->fw.rev = fwrev;
1630 dev->fw.patch = fwpatch; 1649 dev->fw.patch = fwpatch;
1631 1650
1632out: 1651 return 0;
1652
1653error:
1654 macctl = b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
1655 macctl &= ~B43legacy_MACCTL_PSM_RUN;
1656 macctl |= B43legacy_MACCTL_PSM_JMP0;
1657 b43legacy_write32(dev, B43legacy_MMIO_MACCTL, macctl);
1658
1633 return err; 1659 return err;
1634} 1660}
1635 1661
@@ -1736,9 +1762,9 @@ static int b43legacy_gpio_init(struct b43legacy_wldev *dev)
1736 u32 mask; 1762 u32 mask;
1737 u32 set; 1763 u32 set;
1738 1764
1739 b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD, 1765 b43legacy_write32(dev, B43legacy_MMIO_MACCTL,
1740 b43legacy_read32(dev, 1766 b43legacy_read32(dev,
1741 B43legacy_MMIO_STATUS_BITFIELD) 1767 B43legacy_MMIO_MACCTL)
1742 & 0xFFFF3FFF); 1768 & 0xFFFF3FFF);
1743 1769
1744 b43legacy_write16(dev, B43legacy_MMIO_GPIO_MASK, 1770 b43legacy_write16(dev, B43legacy_MMIO_GPIO_MASK,
@@ -1798,14 +1824,14 @@ void b43legacy_mac_enable(struct b43legacy_wldev *dev)
1798 B43legacy_WARN_ON(dev->mac_suspended < 0); 1824 B43legacy_WARN_ON(dev->mac_suspended < 0);
1799 B43legacy_WARN_ON(irqs_disabled()); 1825 B43legacy_WARN_ON(irqs_disabled());
1800 if (dev->mac_suspended == 0) { 1826 if (dev->mac_suspended == 0) {
1801 b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD, 1827 b43legacy_write32(dev, B43legacy_MMIO_MACCTL,
1802 b43legacy_read32(dev, 1828 b43legacy_read32(dev,
1803 B43legacy_MMIO_STATUS_BITFIELD) 1829 B43legacy_MMIO_MACCTL)
1804 | B43legacy_SBF_MAC_ENABLED); 1830 | B43legacy_MACCTL_ENABLED);
1805 b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_REASON, 1831 b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_REASON,
1806 B43legacy_IRQ_MAC_SUSPENDED); 1832 B43legacy_IRQ_MAC_SUSPENDED);
1807 /* the next two are dummy reads */ 1833 /* the next two are dummy reads */
1808 b43legacy_read32(dev, B43legacy_MMIO_STATUS_BITFIELD); 1834 b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
1809 b43legacy_read32(dev, B43legacy_MMIO_GEN_IRQ_REASON); 1835 b43legacy_read32(dev, B43legacy_MMIO_GEN_IRQ_REASON);
1810 b43legacy_power_saving_ctl_bits(dev, -1, -1); 1836 b43legacy_power_saving_ctl_bits(dev, -1, -1);
1811 1837
@@ -1836,10 +1862,10 @@ void b43legacy_mac_suspend(struct b43legacy_wldev *dev)
1836 dev->irq_savedstate = tmp; 1862 dev->irq_savedstate = tmp;
1837 1863
1838 b43legacy_power_saving_ctl_bits(dev, -1, 1); 1864 b43legacy_power_saving_ctl_bits(dev, -1, 1);
1839 b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD, 1865 b43legacy_write32(dev, B43legacy_MMIO_MACCTL,
1840 b43legacy_read32(dev, 1866 b43legacy_read32(dev,
1841 B43legacy_MMIO_STATUS_BITFIELD) 1867 B43legacy_MMIO_MACCTL)
1842 & ~B43legacy_SBF_MAC_ENABLED); 1868 & ~B43legacy_MACCTL_ENABLED);
1843 b43legacy_read32(dev, B43legacy_MMIO_GEN_IRQ_REASON); 1869 b43legacy_read32(dev, B43legacy_MMIO_GEN_IRQ_REASON);
1844 for (i = 40; i; i--) { 1870 for (i = 40; i; i--) {
1845 tmp = b43legacy_read32(dev, 1871 tmp = b43legacy_read32(dev,
@@ -2007,12 +2033,15 @@ static int b43legacy_chip_init(struct b43legacy_wldev *dev)
2007 struct b43legacy_phy *phy = &dev->phy; 2033 struct b43legacy_phy *phy = &dev->phy;
2008 int err; 2034 int err;
2009 int tmp; 2035 int tmp;
2010 u32 value32; 2036 u32 value32, macctl;
2011 u16 value16; 2037 u16 value16;
2012 2038
2013 b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD, 2039 /* Initialize the MAC control */
2014 B43legacy_SBF_CORE_READY 2040 macctl = B43legacy_MACCTL_IHR_ENABLED | B43legacy_MACCTL_SHM_ENABLED;
2015 | B43legacy_SBF_400); 2041 if (dev->phy.gmode)
2042 macctl |= B43legacy_MACCTL_GMODE;
2043 macctl |= B43legacy_MACCTL_INFRA;
2044 b43legacy_write32(dev, B43legacy_MMIO_MACCTL, macctl);
2016 2045
2017 err = b43legacy_request_firmware(dev); 2046 err = b43legacy_request_firmware(dev);
2018 if (err) 2047 if (err)
@@ -2052,12 +2081,12 @@ static int b43legacy_chip_init(struct b43legacy_wldev *dev)
2052 if (dev->dev->id.revision < 5) 2081 if (dev->dev->id.revision < 5)
2053 b43legacy_write32(dev, 0x010C, 0x01000000); 2082 b43legacy_write32(dev, 0x010C, 0x01000000);
2054 2083
2055 value32 = b43legacy_read32(dev, B43legacy_MMIO_STATUS_BITFIELD); 2084 value32 = b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
2056 value32 &= ~B43legacy_SBF_MODE_NOTADHOC; 2085 value32 &= ~B43legacy_MACCTL_INFRA;
2057 b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD, value32); 2086 b43legacy_write32(dev, B43legacy_MMIO_MACCTL, value32);
2058 value32 = b43legacy_read32(dev, B43legacy_MMIO_STATUS_BITFIELD); 2087 value32 = b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
2059 value32 |= B43legacy_SBF_MODE_NOTADHOC; 2088 value32 |= B43legacy_MACCTL_INFRA;
2060 b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD, value32); 2089 b43legacy_write32(dev, B43legacy_MMIO_MACCTL, value32);
2061 2090
2062 if (b43legacy_using_pio(dev)) { 2091 if (b43legacy_using_pio(dev)) {
2063 b43legacy_write32(dev, 0x0210, 0x00000100); 2092 b43legacy_write32(dev, 0x0210, 0x00000100);
@@ -2951,12 +2980,19 @@ static void b43legacy_wireless_core_exit(struct b43legacy_wldev *dev)
2951{ 2980{
2952 struct b43legacy_wl *wl = dev->wl; 2981 struct b43legacy_wl *wl = dev->wl;
2953 struct b43legacy_phy *phy = &dev->phy; 2982 struct b43legacy_phy *phy = &dev->phy;
2983 u32 macctl;
2954 2984
2955 B43legacy_WARN_ON(b43legacy_status(dev) > B43legacy_STAT_INITIALIZED); 2985 B43legacy_WARN_ON(b43legacy_status(dev) > B43legacy_STAT_INITIALIZED);
2956 if (b43legacy_status(dev) != B43legacy_STAT_INITIALIZED) 2986 if (b43legacy_status(dev) != B43legacy_STAT_INITIALIZED)
2957 return; 2987 return;
2958 b43legacy_set_status(dev, B43legacy_STAT_UNINIT); 2988 b43legacy_set_status(dev, B43legacy_STAT_UNINIT);
2959 2989
2990 /* Stop the microcode PSM. */
2991 macctl = b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
2992 macctl &= ~B43legacy_MACCTL_PSM_RUN;
2993 macctl |= B43legacy_MACCTL_PSM_JMP0;
2994 b43legacy_write32(dev, B43legacy_MMIO_MACCTL, macctl);
2995
2960 mutex_unlock(&wl->mutex); 2996 mutex_unlock(&wl->mutex);
2961 /* Must unlock as it would otherwise deadlock. No races here. 2997 /* Must unlock as it would otherwise deadlock. No races here.
2962 * Cancel possibly pending workqueues. */ 2998 * Cancel possibly pending workqueues. */
@@ -3221,6 +3257,7 @@ static int b43legacy_op_start(struct ieee80211_hw *hw)
3221 struct b43legacy_wldev *dev = wl->current_dev; 3257 struct b43legacy_wldev *dev = wl->current_dev;
3222 int did_init = 0; 3258 int did_init = 0;
3223 int err = 0; 3259 int err = 0;
3260 bool do_rfkill_exit = 0;
3224 3261
3225 /* First register RFkill. 3262 /* First register RFkill.
3226 * LEDs that are registered later depend on it. */ 3263 * LEDs that are registered later depend on it. */
@@ -3230,8 +3267,10 @@ static int b43legacy_op_start(struct ieee80211_hw *hw)
3230 3267
3231 if (b43legacy_status(dev) < B43legacy_STAT_INITIALIZED) { 3268 if (b43legacy_status(dev) < B43legacy_STAT_INITIALIZED) {
3232 err = b43legacy_wireless_core_init(dev); 3269 err = b43legacy_wireless_core_init(dev);
3233 if (err) 3270 if (err) {
3271 do_rfkill_exit = 1;
3234 goto out_mutex_unlock; 3272 goto out_mutex_unlock;
3273 }
3235 did_init = 1; 3274 did_init = 1;
3236 } 3275 }
3237 3276
@@ -3240,6 +3279,7 @@ static int b43legacy_op_start(struct ieee80211_hw *hw)
3240 if (err) { 3279 if (err) {
3241 if (did_init) 3280 if (did_init)
3242 b43legacy_wireless_core_exit(dev); 3281 b43legacy_wireless_core_exit(dev);
3282 do_rfkill_exit = 1;
3243 goto out_mutex_unlock; 3283 goto out_mutex_unlock;
3244 } 3284 }
3245 } 3285 }
@@ -3247,6 +3287,9 @@ static int b43legacy_op_start(struct ieee80211_hw *hw)
3247out_mutex_unlock: 3287out_mutex_unlock:
3248 mutex_unlock(&wl->mutex); 3288 mutex_unlock(&wl->mutex);
3249 3289
3290 if (do_rfkill_exit)
3291 b43legacy_rfkill_exit(dev);
3292
3250 return err; 3293 return err;
3251} 3294}
3252 3295
diff --git a/drivers/net/wireless/b43legacy/phy.c b/drivers/net/wireless/b43legacy/phy.c
index c16febbdbf5d..8e5c09b81871 100644
--- a/drivers/net/wireless/b43legacy/phy.c
+++ b/drivers/net/wireless/b43legacy/phy.c
@@ -140,7 +140,7 @@ void b43legacy_phy_calibrate(struct b43legacy_wldev *dev)
140{ 140{
141 struct b43legacy_phy *phy = &dev->phy; 141 struct b43legacy_phy *phy = &dev->phy;
142 142
143 b43legacy_read32(dev, B43legacy_MMIO_STATUS_BITFIELD); /* Dummy read. */ 143 b43legacy_read32(dev, B43legacy_MMIO_MACCTL); /* Dummy read. */
144 if (phy->calibrated) 144 if (phy->calibrated)
145 return; 145 return;
146 if (phy->type == B43legacy_PHYTYPE_G && phy->rev == 1) { 146 if (phy->type == B43legacy_PHYTYPE_G && phy->rev == 1) {
@@ -2231,16 +2231,16 @@ bit26 = 1;
2231 * or the latest PS-Poll packet sent was successful, 2231 * or the latest PS-Poll packet sent was successful,
2232 * set bit26 */ 2232 * set bit26 */
2233 } 2233 }
2234 status = b43legacy_read32(dev, B43legacy_MMIO_STATUS_BITFIELD); 2234 status = b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
2235 if (bit25) 2235 if (bit25)
2236 status |= B43legacy_SBF_PS1; 2236 status |= B43legacy_MACCTL_HWPS;
2237 else 2237 else
2238 status &= ~B43legacy_SBF_PS1; 2238 status &= ~B43legacy_MACCTL_HWPS;
2239 if (bit26) 2239 if (bit26)
2240 status |= B43legacy_SBF_PS2; 2240 status |= B43legacy_MACCTL_AWAKE;
2241 else 2241 else
2242 status &= ~B43legacy_SBF_PS2; 2242 status &= ~B43legacy_MACCTL_AWAKE;
2243 b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD, status); 2243 b43legacy_write32(dev, B43legacy_MMIO_MACCTL, status);
2244 if (bit26 && dev->dev->id.revision >= 5) { 2244 if (bit26 && dev->dev->id.revision >= 5) {
2245 for (i = 0; i < 100; i++) { 2245 for (i = 0; i < 100; i++) {
2246 if (b43legacy_shm_read32(dev, B43legacy_SHM_SHARED, 2246 if (b43legacy_shm_read32(dev, B43legacy_SHM_SHARED,
diff --git a/drivers/net/wireless/b43legacy/pio.c b/drivers/net/wireless/b43legacy/pio.c
index de843ac147ae..e4f4c5c39e33 100644
--- a/drivers/net/wireless/b43legacy/pio.c
+++ b/drivers/net/wireless/b43legacy/pio.c
@@ -334,9 +334,9 @@ struct b43legacy_pioqueue *b43legacy_setup_pioqueue(struct b43legacy_wldev *dev,
334 tasklet_init(&queue->txtask, tx_tasklet, 334 tasklet_init(&queue->txtask, tx_tasklet,
335 (unsigned long)queue); 335 (unsigned long)queue);
336 336
337 value = b43legacy_read32(dev, B43legacy_MMIO_STATUS_BITFIELD); 337 value = b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
338 value &= ~B43legacy_SBF_XFER_REG_BYTESWAP; 338 value &= ~B43legacy_MACCTL_BE;
339 b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD, value); 339 b43legacy_write32(dev, B43legacy_MMIO_MACCTL, value);
340 340
341 qsize = b43legacy_read16(dev, queue->mmio_base 341 qsize = b43legacy_read16(dev, queue->mmio_base
342 + B43legacy_PIO_TXQBUFSIZE); 342 + B43legacy_PIO_TXQBUFSIZE);
diff --git a/drivers/net/wireless/b43legacy/radio.c b/drivers/net/wireless/b43legacy/radio.c
index 318a270cf9b4..955832e8654f 100644
--- a/drivers/net/wireless/b43legacy/radio.c
+++ b/drivers/net/wireless/b43legacy/radio.c
@@ -91,10 +91,10 @@ void b43legacy_radio_lock(struct b43legacy_wldev *dev)
91{ 91{
92 u32 status; 92 u32 status;
93 93
94 status = b43legacy_read32(dev, B43legacy_MMIO_STATUS_BITFIELD); 94 status = b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
95 B43legacy_WARN_ON(status & B43legacy_SBF_RADIOREG_LOCK); 95 B43legacy_WARN_ON(status & B43legacy_MACCTL_RADIOLOCK);
96 status |= B43legacy_SBF_RADIOREG_LOCK; 96 status |= B43legacy_MACCTL_RADIOLOCK;
97 b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD, status); 97 b43legacy_write32(dev, B43legacy_MMIO_MACCTL, status);
98 mmiowb(); 98 mmiowb();
99 udelay(10); 99 udelay(10);
100} 100}
@@ -104,10 +104,10 @@ void b43legacy_radio_unlock(struct b43legacy_wldev *dev)
104 u32 status; 104 u32 status;
105 105
106 b43legacy_read16(dev, B43legacy_MMIO_PHY_VER); /* dummy read */ 106 b43legacy_read16(dev, B43legacy_MMIO_PHY_VER); /* dummy read */
107 status = b43legacy_read32(dev, B43legacy_MMIO_STATUS_BITFIELD); 107 status = b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
108 B43legacy_WARN_ON(!(status & B43legacy_SBF_RADIOREG_LOCK)); 108 B43legacy_WARN_ON(!(status & B43legacy_MACCTL_RADIOLOCK));
109 status &= ~B43legacy_SBF_RADIOREG_LOCK; 109 status &= ~B43legacy_MACCTL_RADIOLOCK;
110 b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD, status); 110 b43legacy_write32(dev, B43legacy_MMIO_MACCTL, status);
111 mmiowb(); 111 mmiowb();
112} 112}
113 113
diff --git a/drivers/net/wireless/hostap/hostap_80211.h b/drivers/net/wireless/hostap/hostap_80211.h
index d6b9362a3d5c..3694b1eba521 100644
--- a/drivers/net/wireless/hostap/hostap_80211.h
+++ b/drivers/net/wireless/hostap/hostap_80211.h
@@ -71,11 +71,6 @@ struct hostap_80211_rx_status {
71 u16 rate; /* in 100 kbps */ 71 u16 rate; /* in 100 kbps */
72}; 72};
73 73
74
75void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
76 struct hostap_80211_rx_status *rx_stats);
77
78
79/* prism2_rx_80211 'type' argument */ 74/* prism2_rx_80211 'type' argument */
80enum { 75enum {
81 PRISM2_RX_MONITOR, PRISM2_RX_MGMT, PRISM2_RX_NON_ASSOC, 76 PRISM2_RX_MONITOR, PRISM2_RX_MGMT, PRISM2_RX_NON_ASSOC,
diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c
index 07593803065a..437a9bcc9bd3 100644
--- a/drivers/net/wireless/hostap/hostap_cs.c
+++ b/drivers/net/wireless/hostap/hostap_cs.c
@@ -891,6 +891,9 @@ static struct pcmcia_device_id hostap_cs_ids[] = {
891 PCMCIA_DEVICE_PROD_ID123( 891 PCMCIA_DEVICE_PROD_ID123(
892 "The Linksys Group, Inc.", "Wireless Network CF Card", "ISL37300P", 892 "The Linksys Group, Inc.", "Wireless Network CF Card", "ISL37300P",
893 0xa5f472c2, 0x9c05598d, 0xc9049a39), 893 0xa5f472c2, 0x9c05598d, 0xc9049a39),
894 PCMCIA_DEVICE_PROD_ID123(
895 "Wireless LAN" , "11Mbps PC Card", "Version 01.02",
896 0x4b8870ff, 0x70e946d1, 0x4b74baa0),
894 PCMCIA_DEVICE_NULL 897 PCMCIA_DEVICE_NULL
895}; 898};
896MODULE_DEVICE_TABLE(pcmcia, hostap_cs_ids); 899MODULE_DEVICE_TABLE(pcmcia, hostap_cs_ids);
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
index 6e0187393af4..571815d7e8bf 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
@@ -373,7 +373,7 @@ struct iwl3945_eeprom {
373#define CSR_INT_BIT_HW_ERR (1 << 29) /* DMA hardware error FH_INT[31] */ 373#define CSR_INT_BIT_HW_ERR (1 << 29) /* DMA hardware error FH_INT[31] */
374#define CSR_INT_BIT_DNLD (1 << 28) /* uCode Download */ 374#define CSR_INT_BIT_DNLD (1 << 28) /* uCode Download */
375#define CSR_INT_BIT_FH_TX (1 << 27) /* Tx DMA FH_INT[1:0] */ 375#define CSR_INT_BIT_FH_TX (1 << 27) /* Tx DMA FH_INT[1:0] */
376#define CSR_INT_BIT_MAC_CLK_ACTV (1 << 26) /* NIC controller's clock toggled on/off */ 376#define CSR_INT_BIT_SCD (1 << 26) /* TXQ pointer advanced */
377#define CSR_INT_BIT_SW_ERR (1 << 25) /* uCode error */ 377#define CSR_INT_BIT_SW_ERR (1 << 25) /* uCode error */
378#define CSR_INT_BIT_RF_KILL (1 << 7) /* HW RFKILL switch GP_CNTRL[27] toggled */ 378#define CSR_INT_BIT_RF_KILL (1 << 7) /* HW RFKILL switch GP_CNTRL[27] toggled */
379#define CSR_INT_BIT_CT_KILL (1 << 6) /* Critical temp (chip too hot) rfkill */ 379#define CSR_INT_BIT_CT_KILL (1 << 6) /* Critical temp (chip too hot) rfkill */
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 76c4ed1135f2..4fdeb5323248 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -2369,18 +2369,4 @@ struct pci_device_id iwl3945_hw_card_ids[] = {
2369 {0} 2369 {0}
2370}; 2370};
2371 2371
2372/*
2373 * Clear the OWNER_MSK, to establish driver (instead of uCode running on
2374 * embedded controller) as EEPROM reader; each read is a series of pulses
2375 * to/from the EEPROM chip, not a single event, so even reads could conflict
2376 * if they weren't arbitrated by some ownership mechanism. Here, the driver
2377 * simply claims ownership, which should be safe when this function is called
2378 * (i.e. before loading uCode!).
2379 */
2380inline int iwl3945_eeprom_acquire_semaphore(struct iwl3945_priv *priv)
2381{
2382 _iwl3945_clear_bit(priv, CSR_EEPROM_GP, CSR_EEPROM_GP_IF_OWNER_MSK);
2383 return 0;
2384}
2385
2386MODULE_DEVICE_TABLE(pci, iwl3945_hw_card_ids); 2372MODULE_DEVICE_TABLE(pci, iwl3945_hw_card_ids);
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h
index 20b925f57e35..1da14f9bbe0f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.h
@@ -671,7 +671,6 @@ extern int iwl3945_hw_channel_switch(struct iwl3945_priv *priv, u16 channel);
671/* 671/*
672 * Forward declare iwl-3945.c functions for iwl-base.c 672 * Forward declare iwl-3945.c functions for iwl-base.c
673 */ 673 */
674extern int iwl3945_eeprom_acquire_semaphore(struct iwl3945_priv *priv);
675extern __le32 iwl3945_get_antenna_flags(const struct iwl3945_priv *priv); 674extern __le32 iwl3945_get_antenna_flags(const struct iwl3945_priv *priv);
676extern int iwl3945_init_hw_rate_table(struct iwl3945_priv *priv); 675extern int iwl3945_init_hw_rate_table(struct iwl3945_priv *priv);
677extern void iwl3945_reg_txpower_periodic(struct iwl3945_priv *priv); 676extern void iwl3945_reg_txpower_periodic(struct iwl3945_priv *priv);
@@ -791,7 +790,6 @@ struct iwl3945_priv {
791 u16 active_rate_basic; 790 u16 active_rate_basic;
792 791
793 u8 call_post_assoc_from_beacon; 792 u8 call_post_assoc_from_beacon;
794 u8 assoc_station_added;
795 /* Rate scaling data */ 793 /* Rate scaling data */
796 s8 data_retry_limit; 794 s8 data_retry_limit;
797 u8 retry_rate; 795 u8 retry_rate;
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
index ff71c09ab1a7..ffe1e9dfdec7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
@@ -465,7 +465,7 @@ struct iwl4965_eeprom {
465#define CSR_INT_BIT_HW_ERR (1 << 29) /* DMA hardware error FH_INT[31] */ 465#define CSR_INT_BIT_HW_ERR (1 << 29) /* DMA hardware error FH_INT[31] */
466#define CSR_INT_BIT_DNLD (1 << 28) /* uCode Download */ 466#define CSR_INT_BIT_DNLD (1 << 28) /* uCode Download */
467#define CSR_INT_BIT_FH_TX (1 << 27) /* Tx DMA FH_INT[1:0] */ 467#define CSR_INT_BIT_FH_TX (1 << 27) /* Tx DMA FH_INT[1:0] */
468#define CSR_INT_BIT_MAC_CLK_ACTV (1 << 26) /* NIC controller's clock toggled on/off */ 468#define CSR_INT_BIT_SCD (1 << 26) /* TXQ pointer advanced */
469#define CSR_INT_BIT_SW_ERR (1 << 25) /* uCode error */ 469#define CSR_INT_BIT_SW_ERR (1 << 25) /* uCode error */
470#define CSR_INT_BIT_RF_KILL (1 << 7) /* HW RFKILL switch GP_CNTRL[27] toggled */ 470#define CSR_INT_BIT_RF_KILL (1 << 7) /* HW RFKILL switch GP_CNTRL[27] toggled */
471#define CSR_INT_BIT_CT_KILL (1 << 6) /* Critical temp (chip too hot) rfkill */ 471#define CSR_INT_BIT_CT_KILL (1 << 6) /* Critical temp (chip too hot) rfkill */
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 04db34ba814b..569347ff377b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -4961,11 +4961,4 @@ int iwl4965_eeprom_acquire_semaphore(struct iwl4965_priv *priv)
4961 return rc; 4961 return rc;
4962} 4962}
4963 4963
4964inline void iwl4965_eeprom_release_semaphore(struct iwl4965_priv *priv)
4965{
4966 iwl4965_clear_bit(priv, CSR_HW_IF_CONFIG_REG,
4967 CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);
4968}
4969
4970
4971MODULE_DEVICE_TABLE(pci, iwl4965_hw_card_ids); 4964MODULE_DEVICE_TABLE(pci, iwl4965_hw_card_ids);
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.h b/drivers/net/wireless/iwlwifi/iwl-4965.h
index 78bc148c9f7f..9cb82be0ff80 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.h
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.h
@@ -750,7 +750,6 @@ struct iwl4965_priv;
750 * Forward declare iwl-4965.c functions for iwl-base.c 750 * Forward declare iwl-4965.c functions for iwl-base.c
751 */ 751 */
752extern int iwl4965_eeprom_acquire_semaphore(struct iwl4965_priv *priv); 752extern int iwl4965_eeprom_acquire_semaphore(struct iwl4965_priv *priv);
753extern void iwl4965_eeprom_release_semaphore(struct iwl4965_priv *priv);
754 753
755extern int iwl4965_tx_queue_update_wr_ptr(struct iwl4965_priv *priv, 754extern int iwl4965_tx_queue_update_wr_ptr(struct iwl4965_priv *priv,
756 struct iwl4965_tx_queue *txq, 755 struct iwl4965_tx_queue *txq,
diff --git a/drivers/net/wireless/iwlwifi/iwl-helpers.h b/drivers/net/wireless/iwlwifi/iwl-helpers.h
index cd2eb1848310..cb009f4c401f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-helpers.h
+++ b/drivers/net/wireless/iwlwifi/iwl-helpers.h
@@ -246,10 +246,10 @@ static inline int iwl_check_bits(unsigned long field, unsigned long mask)
246static inline unsigned long elapsed_jiffies(unsigned long start, 246static inline unsigned long elapsed_jiffies(unsigned long start,
247 unsigned long end) 247 unsigned long end)
248{ 248{
249 if (end > start) 249 if (end >= start)
250 return end - start; 250 return end - start;
251 251
252 return end + (MAX_JIFFY_OFFSET - start); 252 return end + (MAX_JIFFY_OFFSET - start) + 1;
253} 253}
254 254
255static inline u8 iwl_get_dma_hi_address(dma_addr_t addr) 255static inline u8 iwl_get_dma_hi_address(dma_addr_t addr)
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 748ac1222abb..33239f197984 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -1557,6 +1557,20 @@ static void get_eeprom_mac(struct iwl3945_priv *priv, u8 *mac)
1557 memcpy(mac, priv->eeprom.mac_address, 6); 1557 memcpy(mac, priv->eeprom.mac_address, 6);
1558} 1558}
1559 1559
1560/*
1561 * Clear the OWNER_MSK, to establish driver (instead of uCode running on
1562 * embedded controller) as EEPROM reader; each read is a series of pulses
1563 * to/from the EEPROM chip, not a single event, so even reads could conflict
1564 * if they weren't arbitrated by some ownership mechanism. Here, the driver
1565 * simply claims ownership, which should be safe when this function is called
1566 * (i.e. before loading uCode!).
1567 */
1568static inline int iwl3945_eeprom_acquire_semaphore(struct iwl3945_priv *priv)
1569{
1570 _iwl3945_clear_bit(priv, CSR_EEPROM_GP, CSR_EEPROM_GP_IF_OWNER_MSK);
1571 return 0;
1572}
1573
1560/** 1574/**
1561 * iwl3945_eeprom_init - read EEPROM contents 1575 * iwl3945_eeprom_init - read EEPROM contents
1562 * 1576 *
@@ -2792,7 +2806,7 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv,
2792#endif 2806#endif
2793 2807
2794 /* drop all data frame if we are not associated */ 2808 /* drop all data frame if we are not associated */
2795 if (!iwl3945_is_associated(priv) && !priv->assoc_id && 2809 if ((!iwl3945_is_associated(priv) || !priv->assoc_id) &&
2796 ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA)) { 2810 ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA)) {
2797 IWL_DEBUG_DROP("Dropping - !iwl3945_is_associated\n"); 2811 IWL_DEBUG_DROP("Dropping - !iwl3945_is_associated\n");
2798 goto drop_unlock; 2812 goto drop_unlock;
@@ -4745,8 +4759,9 @@ static void iwl3945_irq_tasklet(struct iwl3945_priv *priv)
4745#ifdef CONFIG_IWL3945_DEBUG 4759#ifdef CONFIG_IWL3945_DEBUG
4746 if (iwl3945_debug_level & (IWL_DL_ISR)) { 4760 if (iwl3945_debug_level & (IWL_DL_ISR)) {
4747 /* NIC fires this, but we don't use it, redundant with WAKEUP */ 4761 /* NIC fires this, but we don't use it, redundant with WAKEUP */
4748 if (inta & CSR_INT_BIT_MAC_CLK_ACTV) 4762 if (inta & CSR_INT_BIT_SCD)
4749 IWL_DEBUG_ISR("Microcode started or stopped.\n"); 4763 IWL_DEBUG_ISR("Scheduler finished to transmit "
4764 "the frame/frames.\n");
4750 4765
4751 /* Alive notification via Rx interrupt will do the real work */ 4766 /* Alive notification via Rx interrupt will do the real work */
4752 if (inta & CSR_INT_BIT_ALIVE) 4767 if (inta & CSR_INT_BIT_ALIVE)
@@ -4754,7 +4769,7 @@ static void iwl3945_irq_tasklet(struct iwl3945_priv *priv)
4754 } 4769 }
4755#endif 4770#endif
4756 /* Safely ignore these bits for debug checks below */ 4771 /* Safely ignore these bits for debug checks below */
4757 inta &= ~(CSR_INT_BIT_MAC_CLK_ACTV | CSR_INT_BIT_ALIVE); 4772 inta &= ~(CSR_INT_BIT_SCD | CSR_INT_BIT_ALIVE);
4758 4773
4759 /* HW RF KILL switch toggled (4965 only) */ 4774 /* HW RF KILL switch toggled (4965 only) */
4760 if (inta & CSR_INT_BIT_RF_KILL) { 4775 if (inta & CSR_INT_BIT_RF_KILL) {
@@ -4890,8 +4905,11 @@ static irqreturn_t iwl3945_isr(int irq, void *data)
4890 IWL_DEBUG_ISR("ISR inta 0x%08x, enabled 0x%08x, fh 0x%08x\n", 4905 IWL_DEBUG_ISR("ISR inta 0x%08x, enabled 0x%08x, fh 0x%08x\n",
4891 inta, inta_mask, inta_fh); 4906 inta, inta_mask, inta_fh);
4892 4907
4908 inta &= ~CSR_INT_BIT_SCD;
4909
4893 /* iwl3945_irq_tasklet() will service interrupts and re-enable them */ 4910 /* iwl3945_irq_tasklet() will service interrupts and re-enable them */
4894 tasklet_schedule(&priv->irq_tasklet); 4911 if (likely(inta || inta_fh))
4912 tasklet_schedule(&priv->irq_tasklet);
4895unplugged: 4913unplugged:
4896 spin_unlock(&priv->lock); 4914 spin_unlock(&priv->lock);
4897 4915
@@ -5146,6 +5164,15 @@ static int iwl3945_init_channel_map(struct iwl3945_priv *priv)
5146 return 0; 5164 return 0;
5147} 5165}
5148 5166
5167/*
5168 * iwl3945_free_channel_map - undo allocations in iwl3945_init_channel_map
5169 */
5170static void iwl3945_free_channel_map(struct iwl3945_priv *priv)
5171{
5172 kfree(priv->channel_info);
5173 priv->channel_count = 0;
5174}
5175
5149/* For active scan, listen ACTIVE_DWELL_TIME (msec) on each channel after 5176/* For active scan, listen ACTIVE_DWELL_TIME (msec) on each channel after
5150 * sending probe req. This should be set long enough to hear probe responses 5177 * sending probe req. This should be set long enough to hear probe responses
5151 * from more than one AP. */ 5178 * from more than one AP. */
@@ -5471,6 +5498,17 @@ static int iwl3945_init_geos(struct iwl3945_priv *priv)
5471 return 0; 5498 return 0;
5472} 5499}
5473 5500
5501/*
5502 * iwl3945_free_geos - undo allocations in iwl3945_init_geos
5503 */
5504static void iwl3945_free_geos(struct iwl3945_priv *priv)
5505{
5506 kfree(priv->modes);
5507 kfree(priv->ieee_channels);
5508 kfree(priv->ieee_rates);
5509 clear_bit(STATUS_GEO_CONFIGURED, &priv->status);
5510}
5511
5474/****************************************************************************** 5512/******************************************************************************
5475 * 5513 *
5476 * uCode download functions 5514 * uCode download functions
@@ -6130,15 +6168,6 @@ static void iwl3945_alive_start(struct iwl3945_priv *priv)
6130 /* Clear out the uCode error bit if it is set */ 6168 /* Clear out the uCode error bit if it is set */
6131 clear_bit(STATUS_FW_ERROR, &priv->status); 6169 clear_bit(STATUS_FW_ERROR, &priv->status);
6132 6170
6133 rc = iwl3945_init_channel_map(priv);
6134 if (rc) {
6135 IWL_ERROR("initializing regulatory failed: %d\n", rc);
6136 return;
6137 }
6138
6139 iwl3945_init_geos(priv);
6140 iwl3945_reset_channel_flag(priv);
6141
6142 if (iwl3945_is_rfkill(priv)) 6171 if (iwl3945_is_rfkill(priv))
6143 return; 6172 return;
6144 6173
@@ -6599,7 +6628,7 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
6599 * that based on the direct_mask added to each channel entry */ 6628 * that based on the direct_mask added to each channel entry */
6600 scan->tx_cmd.len = cpu_to_le16( 6629 scan->tx_cmd.len = cpu_to_le16(
6601 iwl3945_fill_probe_req(priv, (struct ieee80211_mgmt *)scan->data, 6630 iwl3945_fill_probe_req(priv, (struct ieee80211_mgmt *)scan->data,
6602 IWL_MAX_SCAN_SIZE - sizeof(scan), 0)); 6631 IWL_MAX_SCAN_SIZE - sizeof(*scan), 0));
6603 scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK; 6632 scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK;
6604 scan->tx_cmd.sta_id = priv->hw_setting.bcast_sta_id; 6633 scan->tx_cmd.sta_id = priv->hw_setting.bcast_sta_id;
6605 scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; 6634 scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
@@ -7120,7 +7149,7 @@ static void iwl3945_config_ap(struct iwl3945_priv *priv)
7120{ 7149{
7121 int rc = 0; 7150 int rc = 0;
7122 7151
7123 if (priv->status & STATUS_EXIT_PENDING) 7152 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
7124 return; 7153 return;
7125 7154
7126 /* The following should be done only at AP bring up */ 7155 /* The following should be done only at AP bring up */
@@ -8614,11 +8643,24 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
8614 IWL_DEBUG_INFO("MAC address: %s\n", print_mac(mac, priv->mac_addr)); 8643 IWL_DEBUG_INFO("MAC address: %s\n", print_mac(mac, priv->mac_addr));
8615 SET_IEEE80211_PERM_ADDR(priv->hw, priv->mac_addr); 8644 SET_IEEE80211_PERM_ADDR(priv->hw, priv->mac_addr);
8616 8645
8646 err = iwl3945_init_channel_map(priv);
8647 if (err) {
8648 IWL_ERROR("initializing regulatory failed: %d\n", err);
8649 goto out_remove_sysfs;
8650 }
8651
8652 err = iwl3945_init_geos(priv);
8653 if (err) {
8654 IWL_ERROR("initializing geos failed: %d\n", err);
8655 goto out_free_channel_map;
8656 }
8657 iwl3945_reset_channel_flag(priv);
8658
8617 iwl3945_rate_control_register(priv->hw); 8659 iwl3945_rate_control_register(priv->hw);
8618 err = ieee80211_register_hw(priv->hw); 8660 err = ieee80211_register_hw(priv->hw);
8619 if (err) { 8661 if (err) {
8620 IWL_ERROR("Failed to register network device (error %d)\n", err); 8662 IWL_ERROR("Failed to register network device (error %d)\n", err);
8621 goto out_remove_sysfs; 8663 goto out_free_geos;
8622 } 8664 }
8623 8665
8624 priv->hw->conf.beacon_int = 100; 8666 priv->hw->conf.beacon_int = 100;
@@ -8628,6 +8670,10 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
8628 8670
8629 return 0; 8671 return 0;
8630 8672
8673 out_free_geos:
8674 iwl3945_free_geos(priv);
8675 out_free_channel_map:
8676 iwl3945_free_channel_map(priv);
8631 out_remove_sysfs: 8677 out_remove_sysfs:
8632 sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group); 8678 sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group);
8633 8679
@@ -8702,10 +8748,8 @@ static void iwl3945_pci_remove(struct pci_dev *pdev)
8702 pci_disable_device(pdev); 8748 pci_disable_device(pdev);
8703 pci_set_drvdata(pdev, NULL); 8749 pci_set_drvdata(pdev, NULL);
8704 8750
8705 kfree(priv->channel_info); 8751 iwl3945_free_channel_map(priv);
8706 8752 iwl3945_free_geos(priv);
8707 kfree(priv->ieee_channels);
8708 kfree(priv->ieee_rates);
8709 8753
8710 if (priv->ibss_beacon) 8754 if (priv->ibss_beacon)
8711 dev_kfree_skb(priv->ibss_beacon); 8755 dev_kfree_skb(priv->ibss_beacon);
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c
index c86da5cd1df1..bf3a60c037aa 100644
--- a/drivers/net/wireless/iwlwifi/iwl4965-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c
@@ -1639,6 +1639,12 @@ static void get_eeprom_mac(struct iwl4965_priv *priv, u8 *mac)
1639 memcpy(mac, priv->eeprom.mac_address, 6); 1639 memcpy(mac, priv->eeprom.mac_address, 6);
1640} 1640}
1641 1641
1642static inline void iwl4965_eeprom_release_semaphore(struct iwl4965_priv *priv)
1643{
1644 iwl4965_clear_bit(priv, CSR_HW_IF_CONFIG_REG,
1645 CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);
1646}
1647
1642/** 1648/**
1643 * iwl4965_eeprom_init - read EEPROM contents 1649 * iwl4965_eeprom_init - read EEPROM contents
1644 * 1650 *
@@ -2927,8 +2933,10 @@ static int iwl4965_tx_skb(struct iwl4965_priv *priv,
2927#endif 2933#endif
2928 2934
2929 /* drop all data frame if we are not associated */ 2935 /* drop all data frame if we are not associated */
2930 if (!iwl4965_is_associated(priv) && !priv->assoc_id && 2936 if (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) &&
2931 ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA)) { 2937 (!iwl4965_is_associated(priv) ||
2938 !priv->assoc_id ||
2939 !priv->assoc_station_added)) {
2932 IWL_DEBUG_DROP("Dropping - !iwl4965_is_associated\n"); 2940 IWL_DEBUG_DROP("Dropping - !iwl4965_is_associated\n");
2933 goto drop_unlock; 2941 goto drop_unlock;
2934 } 2942 }
@@ -5131,8 +5139,9 @@ static void iwl4965_irq_tasklet(struct iwl4965_priv *priv)
5131#ifdef CONFIG_IWL4965_DEBUG 5139#ifdef CONFIG_IWL4965_DEBUG
5132 if (iwl4965_debug_level & (IWL_DL_ISR)) { 5140 if (iwl4965_debug_level & (IWL_DL_ISR)) {
5133 /* NIC fires this, but we don't use it, redundant with WAKEUP */ 5141 /* NIC fires this, but we don't use it, redundant with WAKEUP */
5134 if (inta & CSR_INT_BIT_MAC_CLK_ACTV) 5142 if (inta & CSR_INT_BIT_SCD)
5135 IWL_DEBUG_ISR("Microcode started or stopped.\n"); 5143 IWL_DEBUG_ISR("Scheduler finished to transmit "
5144 "the frame/frames.\n");
5136 5145
5137 /* Alive notification via Rx interrupt will do the real work */ 5146 /* Alive notification via Rx interrupt will do the real work */
5138 if (inta & CSR_INT_BIT_ALIVE) 5147 if (inta & CSR_INT_BIT_ALIVE)
@@ -5140,7 +5149,7 @@ static void iwl4965_irq_tasklet(struct iwl4965_priv *priv)
5140 } 5149 }
5141#endif 5150#endif
5142 /* Safely ignore these bits for debug checks below */ 5151 /* Safely ignore these bits for debug checks below */
5143 inta &= ~(CSR_INT_BIT_MAC_CLK_ACTV | CSR_INT_BIT_ALIVE); 5152 inta &= ~(CSR_INT_BIT_SCD | CSR_INT_BIT_ALIVE);
5144 5153
5145 /* HW RF KILL switch toggled */ 5154 /* HW RF KILL switch toggled */
5146 if (inta & CSR_INT_BIT_RF_KILL) { 5155 if (inta & CSR_INT_BIT_RF_KILL) {
@@ -5269,8 +5278,11 @@ static irqreturn_t iwl4965_isr(int irq, void *data)
5269 IWL_DEBUG_ISR("ISR inta 0x%08x, enabled 0x%08x, fh 0x%08x\n", 5278 IWL_DEBUG_ISR("ISR inta 0x%08x, enabled 0x%08x, fh 0x%08x\n",
5270 inta, inta_mask, inta_fh); 5279 inta, inta_mask, inta_fh);
5271 5280
5281 inta &= ~CSR_INT_BIT_SCD;
5282
5272 /* iwl4965_irq_tasklet() will service interrupts and re-enable them */ 5283 /* iwl4965_irq_tasklet() will service interrupts and re-enable them */
5273 tasklet_schedule(&priv->irq_tasklet); 5284 if (likely(inta || inta_fh))
5285 tasklet_schedule(&priv->irq_tasklet);
5274 5286
5275 unplugged: 5287 unplugged:
5276 spin_unlock(&priv->lock); 5288 spin_unlock(&priv->lock);
@@ -5576,6 +5588,15 @@ static int iwl4965_init_channel_map(struct iwl4965_priv *priv)
5576 return 0; 5588 return 0;
5577} 5589}
5578 5590
5591/*
5592 * iwl4965_free_channel_map - undo allocations in iwl4965_init_channel_map
5593 */
5594static void iwl4965_free_channel_map(struct iwl4965_priv *priv)
5595{
5596 kfree(priv->channel_info);
5597 priv->channel_count = 0;
5598}
5599
5579/* For active scan, listen ACTIVE_DWELL_TIME (msec) on each channel after 5600/* For active scan, listen ACTIVE_DWELL_TIME (msec) on each channel after
5580 * sending probe req. This should be set long enough to hear probe responses 5601 * sending probe req. This should be set long enough to hear probe responses
5581 * from more than one AP. */ 5602 * from more than one AP. */
@@ -5909,6 +5930,17 @@ static int iwl4965_init_geos(struct iwl4965_priv *priv)
5909 return 0; 5930 return 0;
5910} 5931}
5911 5932
5933/*
5934 * iwl4965_free_geos - undo allocations in iwl4965_init_geos
5935 */
5936static void iwl4965_free_geos(struct iwl4965_priv *priv)
5937{
5938 kfree(priv->modes);
5939 kfree(priv->ieee_channels);
5940 kfree(priv->ieee_rates);
5941 clear_bit(STATUS_GEO_CONFIGURED, &priv->status);
5942}
5943
5912/****************************************************************************** 5944/******************************************************************************
5913 * 5945 *
5914 * uCode download functions 5946 * uCode download functions
@@ -6560,15 +6592,6 @@ static void iwl4965_alive_start(struct iwl4965_priv *priv)
6560 /* Clear out the uCode error bit if it is set */ 6592 /* Clear out the uCode error bit if it is set */
6561 clear_bit(STATUS_FW_ERROR, &priv->status); 6593 clear_bit(STATUS_FW_ERROR, &priv->status);
6562 6594
6563 rc = iwl4965_init_channel_map(priv);
6564 if (rc) {
6565 IWL_ERROR("initializing regulatory failed: %d\n", rc);
6566 return;
6567 }
6568
6569 iwl4965_init_geos(priv);
6570 iwl4965_reset_channel_flag(priv);
6571
6572 if (iwl4965_is_rfkill(priv)) 6595 if (iwl4965_is_rfkill(priv))
6573 return; 6596 return;
6574 6597
@@ -7023,7 +7046,7 @@ static void iwl4965_bg_request_scan(struct work_struct *data)
7023 * that based on the direct_mask added to each channel entry */ 7046 * that based on the direct_mask added to each channel entry */
7024 scan->tx_cmd.len = cpu_to_le16( 7047 scan->tx_cmd.len = cpu_to_le16(
7025 iwl4965_fill_probe_req(priv, (struct ieee80211_mgmt *)scan->data, 7048 iwl4965_fill_probe_req(priv, (struct ieee80211_mgmt *)scan->data,
7026 IWL_MAX_SCAN_SIZE - sizeof(scan), 0)); 7049 IWL_MAX_SCAN_SIZE - sizeof(*scan), 0));
7027 scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK; 7050 scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK;
7028 scan->tx_cmd.sta_id = priv->hw_setting.bcast_sta_id; 7051 scan->tx_cmd.sta_id = priv->hw_setting.bcast_sta_id;
7029 scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; 7052 scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
@@ -7448,7 +7471,7 @@ static int iwl4965_mac_add_interface(struct ieee80211_hw *hw,
7448 7471
7449 if (priv->vif) { 7472 if (priv->vif) {
7450 IWL_DEBUG_MAC80211("leave - vif != NULL\n"); 7473 IWL_DEBUG_MAC80211("leave - vif != NULL\n");
7451 return 0; 7474 return -EOPNOTSUPP;
7452 } 7475 }
7453 7476
7454 spin_lock_irqsave(&priv->lock, flags); 7477 spin_lock_irqsave(&priv->lock, flags);
@@ -7580,7 +7603,7 @@ static void iwl4965_config_ap(struct iwl4965_priv *priv)
7580{ 7603{
7581 int rc = 0; 7604 int rc = 0;
7582 7605
7583 if (priv->status & STATUS_EXIT_PENDING) 7606 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
7584 return; 7607 return;
7585 7608
7586 /* The following should be done only at AP bring up */ 7609 /* The following should be done only at AP bring up */
@@ -9198,11 +9221,24 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
9198 IWL_DEBUG_INFO("MAC address: %s\n", print_mac(mac, priv->mac_addr)); 9221 IWL_DEBUG_INFO("MAC address: %s\n", print_mac(mac, priv->mac_addr));
9199 SET_IEEE80211_PERM_ADDR(priv->hw, priv->mac_addr); 9222 SET_IEEE80211_PERM_ADDR(priv->hw, priv->mac_addr);
9200 9223
9224 err = iwl4965_init_channel_map(priv);
9225 if (err) {
9226 IWL_ERROR("initializing regulatory failed: %d\n", err);
9227 goto out_remove_sysfs;
9228 }
9229
9230 err = iwl4965_init_geos(priv);
9231 if (err) {
9232 IWL_ERROR("initializing geos failed: %d\n", err);
9233 goto out_free_channel_map;
9234 }
9235 iwl4965_reset_channel_flag(priv);
9236
9201 iwl4965_rate_control_register(priv->hw); 9237 iwl4965_rate_control_register(priv->hw);
9202 err = ieee80211_register_hw(priv->hw); 9238 err = ieee80211_register_hw(priv->hw);
9203 if (err) { 9239 if (err) {
9204 IWL_ERROR("Failed to register network device (error %d)\n", err); 9240 IWL_ERROR("Failed to register network device (error %d)\n", err);
9205 goto out_remove_sysfs; 9241 goto out_free_geos;
9206 } 9242 }
9207 9243
9208 priv->hw->conf.beacon_int = 100; 9244 priv->hw->conf.beacon_int = 100;
@@ -9212,6 +9248,10 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
9212 9248
9213 return 0; 9249 return 0;
9214 9250
9251 out_free_geos:
9252 iwl4965_free_geos(priv);
9253 out_free_channel_map:
9254 iwl4965_free_channel_map(priv);
9215 out_remove_sysfs: 9255 out_remove_sysfs:
9216 sysfs_remove_group(&pdev->dev.kobj, &iwl4965_attribute_group); 9256 sysfs_remove_group(&pdev->dev.kobj, &iwl4965_attribute_group);
9217 9257
@@ -9286,10 +9326,8 @@ static void iwl4965_pci_remove(struct pci_dev *pdev)
9286 pci_disable_device(pdev); 9326 pci_disable_device(pdev);
9287 pci_set_drvdata(pdev, NULL); 9327 pci_set_drvdata(pdev, NULL);
9288 9328
9289 kfree(priv->channel_info); 9329 iwl4965_free_channel_map(priv);
9290 9330 iwl4965_free_geos(priv);
9291 kfree(priv->ieee_channels);
9292 kfree(priv->ieee_rates);
9293 9331
9294 if (priv->ibss_beacon) 9332 if (priv->ibss_beacon)
9295 dev_kfree_skb(priv->ibss_beacon); 9333 dev_kfree_skb(priv->ibss_beacon);
diff --git a/drivers/net/wireless/libertas/assoc.c b/drivers/net/wireless/libertas/assoc.c
index c622e9b63cd1..87e145ffe8f1 100644
--- a/drivers/net/wireless/libertas/assoc.c
+++ b/drivers/net/wireless/libertas/assoc.c
@@ -12,8 +12,10 @@
12#include "cmd.h" 12#include "cmd.h"
13 13
14 14
15static const u8 bssid_any[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; 15static const u8 bssid_any[ETH_ALEN] __attribute__ ((aligned (2))) =
16static const u8 bssid_off[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 16 { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
17static const u8 bssid_off[ETH_ALEN] __attribute__ ((aligned (2))) =
18 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
17 19
18 20
19static int assoc_helper_essid(struct lbs_private *priv, 21static int assoc_helper_essid(struct lbs_private *priv,
diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h
index 58d7ef6b5ff5..5a69f2b60865 100644
--- a/drivers/net/wireless/libertas/dev.h
+++ b/drivers/net/wireless/libertas/dev.h
@@ -349,7 +349,7 @@ struct assoc_request {
349 u8 channel; 349 u8 channel;
350 u8 band; 350 u8 band;
351 u8 mode; 351 u8 mode;
352 u8 bssid[ETH_ALEN]; 352 u8 bssid[ETH_ALEN] __attribute__ ((aligned (2)));
353 353
354 /** WEP keys */ 354 /** WEP keys */
355 struct enc_key wep_keys[4]; 355 struct enc_key wep_keys[4];
diff --git a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c
index 4b5ab9a6b97b..5a9cadb97503 100644
--- a/drivers/net/wireless/libertas/if_cs.c
+++ b/drivers/net/wireless/libertas/if_cs.c
@@ -249,14 +249,14 @@ static irqreturn_t if_cs_interrupt(int irq, void *data)
249 lbs_deb_enter(LBS_DEB_CS); 249 lbs_deb_enter(LBS_DEB_CS);
250 250
251 int_cause = if_cs_read16(card, IF_CS_C_INT_CAUSE); 251 int_cause = if_cs_read16(card, IF_CS_C_INT_CAUSE);
252 if(int_cause == 0x0) { 252 if (int_cause == 0x0) {
253 /* Not for us */ 253 /* Not for us */
254 return IRQ_NONE; 254 return IRQ_NONE;
255 255
256 } else if (int_cause == 0xffff) { 256 } else if (int_cause == 0xffff) {
257 /* Read in junk, the card has probably been removed */ 257 /* Read in junk, the card has probably been removed */
258 card->priv->surpriseremoved = 1; 258 card->priv->surpriseremoved = 1;
259 259 return IRQ_HANDLED;
260 } else { 260 } else {
261 if (int_cause & IF_CS_H_IC_TX_OVER) 261 if (int_cause & IF_CS_H_IC_TX_OVER)
262 lbs_host_to_card_done(card->priv); 262 lbs_host_to_card_done(card->priv);
@@ -717,8 +717,8 @@ static void if_cs_release(struct pcmcia_device *p_dev)
717 717
718 lbs_deb_enter(LBS_DEB_CS); 718 lbs_deb_enter(LBS_DEB_CS);
719 719
720 pcmcia_disable_device(p_dev);
721 free_irq(p_dev->irq.AssignedIRQ, card); 720 free_irq(p_dev->irq.AssignedIRQ, card);
721 pcmcia_disable_device(p_dev);
722 if (card->iobase) 722 if (card->iobase)
723 ioport_unmap(card->iobase); 723 ioport_unmap(card->iobase);
724 724
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
new file mode 100644
index 000000000000..d3ecf89abd93
--- /dev/null
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -0,0 +1,2757 @@
1/*
2 * Driver for RNDIS based wireless USB devices.
3 *
4 * Copyright (C) 2007 by Bjorge Dijkstra <bjd@jooz.net>
5 * Copyright (C) 2008 by Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
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 as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 * Portions of this file are based on NDISwrapper project,
22 * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani
23 * http://ndiswrapper.sourceforge.net/
24 */
25
26// #define DEBUG // error path messages, extra info
27// #define VERBOSE // more; success messages
28
29#include <linux/module.h>
30#include <linux/init.h>
31#include <linux/netdevice.h>
32#include <linux/etherdevice.h>
33#include <linux/ethtool.h>
34#include <linux/workqueue.h>
35#include <linux/mutex.h>
36#include <linux/mii.h>
37#include <linux/usb.h>
38#include <linux/usb/cdc.h>
39#include <linux/wireless.h>
40#include <linux/if_arp.h>
41#include <linux/ctype.h>
42#include <linux/spinlock.h>
43#include <net/iw_handler.h>
44#include <net/ieee80211.h>
45#include <linux/usb/usbnet.h>
46#include <linux/usb/rndis_host.h>
47
48
49/* NOTE: All these are settings for Broadcom chipset */
50static char modparam_country[4] = "EU";
51module_param_string(country, modparam_country, 4, 0444);
52MODULE_PARM_DESC(country, "Country code (ISO 3166-1 alpha-2), default: EU");
53
54static int modparam_frameburst = 1;
55module_param_named(frameburst, modparam_frameburst, int, 0444);
56MODULE_PARM_DESC(frameburst, "enable frame bursting (default: on)");
57
58static int modparam_afterburner = 0;
59module_param_named(afterburner, modparam_afterburner, int, 0444);
60MODULE_PARM_DESC(afterburner,
61 "enable afterburner aka '125 High Speed Mode' (default: off)");
62
63static int modparam_power_save = 0;
64module_param_named(power_save, modparam_power_save, int, 0444);
65MODULE_PARM_DESC(power_save,
66 "set power save mode: 0=off, 1=on, 2=fast (default: off)");
67
68static int modparam_power_output = 3;
69module_param_named(power_output, modparam_power_output, int, 0444);
70MODULE_PARM_DESC(power_output,
71 "set power output: 0=25%, 1=50%, 2=75%, 3=100% (default: 100%)");
72
73static int modparam_roamtrigger = -70;
74module_param_named(roamtrigger, modparam_roamtrigger, int, 0444);
75MODULE_PARM_DESC(roamtrigger,
76 "set roaming dBm trigger: -80=optimize for distance, "
77 "-60=bandwidth (default: -70)");
78
79static int modparam_roamdelta = 1;
80module_param_named(roamdelta, modparam_roamdelta, int, 0444);
81MODULE_PARM_DESC(roamdelta,
82 "set roaming tendency: 0=aggressive, 1=moderate, "
83 "2=conservative (default: moderate)");
84
85static int modparam_workaround_interval = 500;
86module_param_named(workaround_interval, modparam_workaround_interval,
87 int, 0444);
88MODULE_PARM_DESC(workaround_interval,
89 "set stall workaround interval in msecs (default: 500)");
90
91
92/* various RNDIS OID defs */
93#define OID_GEN_LINK_SPEED ccpu2(0x00010107)
94#define OID_GEN_RNDIS_CONFIG_PARAMETER ccpu2(0x0001021b)
95
96#define OID_GEN_XMIT_OK ccpu2(0x00020101)
97#define OID_GEN_RCV_OK ccpu2(0x00020102)
98#define OID_GEN_XMIT_ERROR ccpu2(0x00020103)
99#define OID_GEN_RCV_ERROR ccpu2(0x00020104)
100#define OID_GEN_RCV_NO_BUFFER ccpu2(0x00020105)
101
102#define OID_802_3_PERMANENT_ADDRESS ccpu2(0x01010101)
103#define OID_802_3_CURRENT_ADDRESS ccpu2(0x01010102)
104#define OID_802_3_MULTICAST_LIST ccpu2(0x01010103)
105#define OID_802_3_MAXIMUM_LIST_SIZE ccpu2(0x01010104)
106
107#define OID_802_11_BSSID ccpu2(0x0d010101)
108#define OID_802_11_SSID ccpu2(0x0d010102)
109#define OID_802_11_INFRASTRUCTURE_MODE ccpu2(0x0d010108)
110#define OID_802_11_ADD_WEP ccpu2(0x0d010113)
111#define OID_802_11_REMOVE_WEP ccpu2(0x0d010114)
112#define OID_802_11_DISASSOCIATE ccpu2(0x0d010115)
113#define OID_802_11_AUTHENTICATION_MODE ccpu2(0x0d010118)
114#define OID_802_11_PRIVACY_FILTER ccpu2(0x0d010119)
115#define OID_802_11_BSSID_LIST_SCAN ccpu2(0x0d01011a)
116#define OID_802_11_ENCRYPTION_STATUS ccpu2(0x0d01011b)
117#define OID_802_11_ADD_KEY ccpu2(0x0d01011d)
118#define OID_802_11_REMOVE_KEY ccpu2(0x0d01011e)
119#define OID_802_11_PMKID ccpu2(0x0d010123)
120#define OID_802_11_NETWORK_TYPES_SUPPORTED ccpu2(0x0d010203)
121#define OID_802_11_NETWORK_TYPE_IN_USE ccpu2(0x0d010204)
122#define OID_802_11_TX_POWER_LEVEL ccpu2(0x0d010205)
123#define OID_802_11_RSSI ccpu2(0x0d010206)
124#define OID_802_11_RSSI_TRIGGER ccpu2(0x0d010207)
125#define OID_802_11_FRAGMENTATION_THRESHOLD ccpu2(0x0d010209)
126#define OID_802_11_RTS_THRESHOLD ccpu2(0x0d01020a)
127#define OID_802_11_SUPPORTED_RATES ccpu2(0x0d01020e)
128#define OID_802_11_CONFIGURATION ccpu2(0x0d010211)
129#define OID_802_11_BSSID_LIST ccpu2(0x0d010217)
130
131
132/* Typical noise/maximum signal level values taken from ndiswrapper iw_ndis.h */
133#define WL_NOISE -96 /* typical noise level in dBm */
134#define WL_SIGMAX -32 /* typical maximum signal level in dBm */
135
136
137/* Assume that Broadcom 4320 (only chipset at time of writing known to be
138 * based on wireless rndis) has default txpower of 13dBm.
139 * This value is from Linksys WUSB54GSC User Guide, Appendix F: Specifications.
140 * 13dBm == 19.9mW
141 */
142#define BCM4320_DEFAULT_TXPOWER 20
143
144
145/* codes for "status" field of completion messages */
146#define RNDIS_STATUS_ADAPTER_NOT_READY ccpu2(0xc0010011)
147#define RNDIS_STATUS_ADAPTER_NOT_OPEN ccpu2(0xc0010012)
148
149
150/* NDIS data structures. Taken from wpa_supplicant driver_ndis.c
151 * slightly modified for datatype endianess, etc
152 */
153#define NDIS_802_11_LENGTH_SSID 32
154#define NDIS_802_11_LENGTH_RATES 8
155#define NDIS_802_11_LENGTH_RATES_EX 16
156
157struct NDIS_802_11_SSID {
158 __le32 SsidLength;
159 u8 Ssid[NDIS_802_11_LENGTH_SSID];
160} __attribute__((packed));
161
162enum NDIS_802_11_NETWORK_TYPE {
163 Ndis802_11FH,
164 Ndis802_11DS,
165 Ndis802_11OFDM5,
166 Ndis802_11OFDM24,
167 Ndis802_11NetworkTypeMax
168};
169
170struct NDIS_802_11_CONFIGURATION_FH {
171 __le32 Length;
172 __le32 HopPattern;
173 __le32 HopSet;
174 __le32 DwellTime;
175} __attribute__((packed));
176
177struct NDIS_802_11_CONFIGURATION {
178 __le32 Length;
179 __le32 BeaconPeriod;
180 __le32 ATIMWindow;
181 __le32 DSConfig;
182 struct NDIS_802_11_CONFIGURATION_FH FHConfig;
183} __attribute__((packed));
184
185enum NDIS_802_11_NETWORK_INFRASTRUCTURE {
186 Ndis802_11IBSS,
187 Ndis802_11Infrastructure,
188 Ndis802_11AutoUnknown,
189 Ndis802_11InfrastructureMax
190};
191
192enum NDIS_802_11_AUTHENTICATION_MODE {
193 Ndis802_11AuthModeOpen,
194 Ndis802_11AuthModeShared,
195 Ndis802_11AuthModeAutoSwitch,
196 Ndis802_11AuthModeWPA,
197 Ndis802_11AuthModeWPAPSK,
198 Ndis802_11AuthModeWPANone,
199 Ndis802_11AuthModeWPA2,
200 Ndis802_11AuthModeWPA2PSK,
201 Ndis802_11AuthModeMax
202};
203
204enum NDIS_802_11_ENCRYPTION_STATUS {
205 Ndis802_11WEPEnabled,
206 Ndis802_11Encryption1Enabled = Ndis802_11WEPEnabled,
207 Ndis802_11WEPDisabled,
208 Ndis802_11EncryptionDisabled = Ndis802_11WEPDisabled,
209 Ndis802_11WEPKeyAbsent,
210 Ndis802_11Encryption1KeyAbsent = Ndis802_11WEPKeyAbsent,
211 Ndis802_11WEPNotSupported,
212 Ndis802_11EncryptionNotSupported = Ndis802_11WEPNotSupported,
213 Ndis802_11Encryption2Enabled,
214 Ndis802_11Encryption2KeyAbsent,
215 Ndis802_11Encryption3Enabled,
216 Ndis802_11Encryption3KeyAbsent
217};
218
219enum NDIS_802_11_PRIVACY_FILTER {
220 Ndis802_11PrivFilterAcceptAll,
221 Ndis802_11PrivFilter8021xWEP
222};
223
224struct NDIS_WLAN_BSSID_EX {
225 __le32 Length;
226 u8 MacAddress[6];
227 u8 Padding[2];
228 struct NDIS_802_11_SSID Ssid;
229 __le32 Privacy;
230 __le32 Rssi;
231 enum NDIS_802_11_NETWORK_TYPE NetworkTypeInUse;
232 struct NDIS_802_11_CONFIGURATION Configuration;
233 enum NDIS_802_11_NETWORK_INFRASTRUCTURE InfrastructureMode;
234 u8 SupportedRates[NDIS_802_11_LENGTH_RATES_EX];
235 __le32 IELength;
236 u8 IEs[0];
237} __attribute__((packed));
238
239struct NDIS_802_11_BSSID_LIST_EX {
240 __le32 NumberOfItems;
241 struct NDIS_WLAN_BSSID_EX Bssid[0];
242} __attribute__((packed));
243
244struct NDIS_802_11_FIXED_IEs {
245 u8 Timestamp[8];
246 __le16 BeaconInterval;
247 __le16 Capabilities;
248} __attribute__((packed));
249
250struct NDIS_802_11_WEP {
251 __le32 Length;
252 __le32 KeyIndex;
253 __le32 KeyLength;
254 u8 KeyMaterial[32];
255} __attribute__((packed));
256
257struct NDIS_802_11_KEY {
258 __le32 Length;
259 __le32 KeyIndex;
260 __le32 KeyLength;
261 u8 Bssid[6];
262 u8 Padding[6];
263 __le64 KeyRSC;
264 u8 KeyMaterial[32];
265} __attribute__((packed));
266
267struct NDIS_802_11_REMOVE_KEY {
268 __le32 Length;
269 __le32 KeyIndex;
270 u8 Bssid[6];
271} __attribute__((packed));
272
273struct RNDIS_CONFIG_PARAMETER_INFOBUFFER {
274 __le32 ParameterNameOffset;
275 __le32 ParameterNameLength;
276 __le32 ParameterType;
277 __le32 ParameterValueOffset;
278 __le32 ParameterValueLength;
279} __attribute__((packed));
280
281/* these have to match what is in wpa_supplicant */
282enum { WPA_ALG_NONE, WPA_ALG_WEP, WPA_ALG_TKIP, WPA_ALG_CCMP } wpa_alg;
283enum { CIPHER_NONE, CIPHER_WEP40, CIPHER_TKIP, CIPHER_CCMP, CIPHER_WEP104 }
284 wpa_cipher;
285enum { KEY_MGMT_802_1X, KEY_MGMT_PSK, KEY_MGMT_NONE, KEY_MGMT_802_1X_NO_WPA,
286 KEY_MGMT_WPA_NONE } wpa_key_mgmt;
287
288/*
289 * private data
290 */
291#define NET_TYPE_11FB 0
292
293#define CAP_MODE_80211A 1
294#define CAP_MODE_80211B 2
295#define CAP_MODE_80211G 4
296#define CAP_MODE_MASK 7
297#define CAP_SUPPORT_TXPOWER 8
298
299#define WORK_CONNECTION_EVENT (1<<0)
300#define WORK_SET_MULTICAST_LIST (1<<1)
301
302/* RNDIS device private data */
303struct rndis_wext_private {
304 char name[32];
305
306 struct usbnet *usbdev;
307
308 struct workqueue_struct *workqueue;
309 struct delayed_work stats_work;
310 struct work_struct work;
311 struct mutex command_lock;
312 spinlock_t stats_lock;
313 unsigned long work_pending;
314
315 struct iw_statistics iwstats;
316 struct iw_statistics privstats;
317
318 int nick_len;
319 char nick[32];
320
321 int caps;
322 int multicast_size;
323
324 /* module parameters */
325 char param_country[4];
326 int param_frameburst;
327 int param_afterburner;
328 int param_power_save;
329 int param_power_output;
330 int param_roamtrigger;
331 int param_roamdelta;
332 u32 param_workaround_interval;
333
334 /* hardware state */
335 int radio_on;
336 int infra_mode;
337 struct NDIS_802_11_SSID essid;
338
339 /* encryption stuff */
340 int encr_tx_key_index;
341 char encr_keys[4][32];
342 int encr_key_len[4];
343 int wpa_version;
344 int wpa_keymgmt;
345 int wpa_authalg;
346 int wpa_ie_len;
347 u8 *wpa_ie;
348 int wpa_cipher_pair;
349 int wpa_cipher_group;
350};
351
352
353static const int freq_chan[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442,
354 2447, 2452, 2457, 2462, 2467, 2472, 2484 };
355
356static const int rates_80211g[8] = { 6, 9, 12, 18, 24, 36, 48, 54 };
357
358static const int bcm4320_power_output[4] = { 25, 50, 75, 100 };
359
360static const unsigned char zero_bssid[ETH_ALEN] = {0,};
361static const unsigned char ffff_bssid[ETH_ALEN] = { 0xff, 0xff, 0xff,
362 0xff, 0xff, 0xff };
363
364
365static struct rndis_wext_private *get_rndis_wext_priv(struct usbnet *dev)
366{
367 return (struct rndis_wext_private *)dev->driver_priv;
368}
369
370
371static u32 get_bcm4320_power(struct rndis_wext_private *priv)
372{
373 return BCM4320_DEFAULT_TXPOWER *
374 bcm4320_power_output[priv->param_power_output] / 100;
375}
376
377
378/* translate error code */
379static int rndis_error_status(__le32 rndis_status)
380{
381 int ret = -EINVAL;
382 switch (rndis_status) {
383 case RNDIS_STATUS_SUCCESS:
384 ret = 0;
385 break;
386 case RNDIS_STATUS_FAILURE:
387 case RNDIS_STATUS_INVALID_DATA:
388 ret = -EINVAL;
389 break;
390 case RNDIS_STATUS_NOT_SUPPORTED:
391 ret = -EOPNOTSUPP;
392 break;
393 case RNDIS_STATUS_ADAPTER_NOT_READY:
394 case RNDIS_STATUS_ADAPTER_NOT_OPEN:
395 ret = -EBUSY;
396 break;
397 }
398 return ret;
399}
400
401
402static int rndis_query_oid(struct usbnet *dev, __le32 oid, void *data, int *len)
403{
404 struct rndis_wext_private *priv = get_rndis_wext_priv(dev);
405 union {
406 void *buf;
407 struct rndis_msg_hdr *header;
408 struct rndis_query *get;
409 struct rndis_query_c *get_c;
410 } u;
411 int ret, buflen;
412
413 buflen = *len + sizeof(*u.get);
414 if (buflen < CONTROL_BUFFER_SIZE)
415 buflen = CONTROL_BUFFER_SIZE;
416 u.buf = kmalloc(buflen, GFP_KERNEL);
417 if (!u.buf)
418 return -ENOMEM;
419 memset(u.get, 0, sizeof *u.get);
420 u.get->msg_type = RNDIS_MSG_QUERY;
421 u.get->msg_len = ccpu2(sizeof *u.get);
422 u.get->oid = oid;
423
424 mutex_lock(&priv->command_lock);
425 ret = rndis_command(dev, u.header);
426 mutex_unlock(&priv->command_lock);
427
428 if (ret == 0) {
429 ret = le32_to_cpu(u.get_c->len);
430 *len = (*len > ret) ? ret : *len;
431 memcpy(data, u.buf + le32_to_cpu(u.get_c->offset) + 8, *len);
432 ret = rndis_error_status(u.get_c->status);
433 }
434
435 kfree(u.buf);
436 return ret;
437}
438
439
440static int rndis_set_oid(struct usbnet *dev, __le32 oid, void *data, int len)
441{
442 struct rndis_wext_private *priv = get_rndis_wext_priv(dev);
443 union {
444 void *buf;
445 struct rndis_msg_hdr *header;
446 struct rndis_set *set;
447 struct rndis_set_c *set_c;
448 } u;
449 int ret, buflen;
450
451 buflen = len + sizeof(*u.set);
452 if (buflen < CONTROL_BUFFER_SIZE)
453 buflen = CONTROL_BUFFER_SIZE;
454 u.buf = kmalloc(buflen, GFP_KERNEL);
455 if (!u.buf)
456 return -ENOMEM;
457
458 memset(u.set, 0, sizeof *u.set);
459 u.set->msg_type = RNDIS_MSG_SET;
460 u.set->msg_len = cpu_to_le32(sizeof(*u.set) + len);
461 u.set->oid = oid;
462 u.set->len = cpu_to_le32(len);
463 u.set->offset = ccpu2(sizeof(*u.set) - 8);
464 u.set->handle = ccpu2(0);
465 memcpy(u.buf + sizeof(*u.set), data, len);
466
467 mutex_lock(&priv->command_lock);
468 ret = rndis_command(dev, u.header);
469 mutex_unlock(&priv->command_lock);
470
471 if (ret == 0)
472 ret = rndis_error_status(u.set_c->status);
473
474 kfree(u.buf);
475 return ret;
476}
477
478
479/*
480 * Specs say that we can only set config parameters only soon after device
481 * initialization.
482 * value_type: 0 = u32, 2 = unicode string
483 */
484static int rndis_set_config_parameter(struct usbnet *dev, char *param,
485 int value_type, void *value)
486{
487 struct RNDIS_CONFIG_PARAMETER_INFOBUFFER *infobuf;
488 int value_len, info_len, param_len, ret, i;
489 __le16 *unibuf;
490 __le32 *dst_value;
491
492 if (value_type == 0)
493 value_len = sizeof(__le32);
494 else if (value_type == 2)
495 value_len = strlen(value) * sizeof(__le16);
496 else
497 return -EINVAL;
498
499 param_len = strlen(param) * sizeof(__le16);
500 info_len = sizeof(*infobuf) + param_len + value_len;
501
502#ifdef DEBUG
503 info_len += 12;
504#endif
505 infobuf = kmalloc(info_len, GFP_KERNEL);
506 if (!infobuf)
507 return -ENOMEM;
508
509#ifdef DEBUG
510 info_len -= 12;
511 /* extra 12 bytes are for padding (debug output) */
512 memset(infobuf, 0xCC, info_len + 12);
513#endif
514
515 if (value_type == 2)
516 devdbg(dev, "setting config parameter: %s, value: %s",
517 param, (u8 *)value);
518 else
519 devdbg(dev, "setting config parameter: %s, value: %d",
520 param, *(u32 *)value);
521
522 infobuf->ParameterNameOffset = cpu_to_le32(sizeof(*infobuf));
523 infobuf->ParameterNameLength = cpu_to_le32(param_len);
524 infobuf->ParameterType = cpu_to_le32(value_type);
525 infobuf->ParameterValueOffset = cpu_to_le32(sizeof(*infobuf) +
526 param_len);
527 infobuf->ParameterValueLength = cpu_to_le32(value_len);
528
529 /* simple string to unicode string conversion */
530 unibuf = (void *)infobuf + sizeof(*infobuf);
531 for (i = 0; i < param_len / sizeof(__le16); i++)
532 unibuf[i] = cpu_to_le16(param[i]);
533
534 if (value_type == 2) {
535 unibuf = (void *)infobuf + sizeof(*infobuf) + param_len;
536 for (i = 0; i < value_len / sizeof(__le16); i++)
537 unibuf[i] = cpu_to_le16(((u8 *)value)[i]);
538 } else {
539 dst_value = (void *)infobuf + sizeof(*infobuf) + param_len;
540 *dst_value = cpu_to_le32(*(u32 *)value);
541 }
542
543#ifdef DEBUG
544 devdbg(dev, "info buffer (len: %d):", info_len);
545 for (i = 0; i < info_len; i += 12) {
546 u32 *tmp = (u32 *)((u8 *)infobuf + i);
547 devdbg(dev, "%08X:%08X:%08X",
548 cpu_to_be32(tmp[0]),
549 cpu_to_be32(tmp[1]),
550 cpu_to_be32(tmp[2]));
551 }
552#endif
553
554 ret = rndis_set_oid(dev, OID_GEN_RNDIS_CONFIG_PARAMETER,
555 infobuf, info_len);
556 if (ret != 0)
557 devdbg(dev, "setting rndis config paramater failed, %d.", ret);
558
559 kfree(infobuf);
560 return ret;
561}
562
563static int rndis_set_config_parameter_str(struct usbnet *dev,
564 char *param, char *value)
565{
566 return(rndis_set_config_parameter(dev, param, 2, value));
567}
568
569/*static int rndis_set_config_parameter_u32(struct usbnet *dev,
570 char *param, u32 value)
571{
572 return(rndis_set_config_parameter(dev, param, 0, &value));
573}*/
574
575
576/*
577 * data conversion functions
578 */
579static int level_to_qual(int level)
580{
581 int qual = 100 * (level - WL_NOISE) / (WL_SIGMAX - WL_NOISE);
582 return qual >= 0 ? (qual <= 100 ? qual : 100) : 0;
583}
584
585
586static void dsconfig_to_freq(unsigned int dsconfig, struct iw_freq *freq)
587{
588 freq->e = 0;
589 freq->i = 0;
590 freq->flags = 0;
591
592 /* see comment in wireless.h above the "struct iw_freq"
593 * definition for an explanation of this if
594 * NOTE: 1000000 is due to the kHz
595 */
596 if (dsconfig > 1000000) {
597 freq->m = dsconfig / 10;
598 freq->e = 1;
599 } else
600 freq->m = dsconfig;
601
602 /* convert from kHz to Hz */
603 freq->e += 3;
604}
605
606
607static int freq_to_dsconfig(struct iw_freq *freq, unsigned int *dsconfig)
608{
609 if (freq->m < 1000 && freq->e == 0) {
610 if (freq->m >= 1 &&
611 freq->m <= (sizeof(freq_chan) / sizeof(freq_chan[0])))
612 *dsconfig = freq_chan[freq->m - 1] * 1000;
613 else
614 return -1;
615 } else {
616 int i;
617 *dsconfig = freq->m;
618 for (i = freq->e; i > 0; i--)
619 *dsconfig *= 10;
620 *dsconfig /= 1000;
621 }
622
623 return 0;
624}
625
626
627/*
628 * common functions
629 */
630static int
631add_wep_key(struct usbnet *usbdev, char *key, int key_len, int index);
632
633static int get_essid(struct usbnet *usbdev, struct NDIS_802_11_SSID *ssid)
634{
635 int ret, len;
636
637 len = sizeof(*ssid);
638 ret = rndis_query_oid(usbdev, OID_802_11_SSID, ssid, &len);
639
640 if (ret != 0)
641 ssid->SsidLength = 0;
642
643#ifdef DEBUG
644 {
645 unsigned char tmp[NDIS_802_11_LENGTH_SSID + 1];
646
647 memcpy(tmp, ssid->Ssid, le32_to_cpu(ssid->SsidLength));
648 tmp[le32_to_cpu(ssid->SsidLength)] = 0;
649 devdbg(usbdev, "get_essid: '%s', ret: %d", tmp, ret);
650 }
651#endif
652 return ret;
653}
654
655
656static int set_essid(struct usbnet *usbdev, struct NDIS_802_11_SSID *ssid)
657{
658 struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
659 int ret;
660
661 ret = rndis_set_oid(usbdev, OID_802_11_SSID, ssid, sizeof(*ssid));
662 if (ret == 0) {
663 memcpy(&priv->essid, ssid, sizeof(priv->essid));
664 priv->radio_on = 1;
665 devdbg(usbdev, "set_essid: radio_on = 1");
666 }
667
668 return ret;
669}
670
671
672static int get_bssid(struct usbnet *usbdev, u8 bssid[ETH_ALEN])
673{
674 int ret, len;
675
676 len = ETH_ALEN;
677 ret = rndis_query_oid(usbdev, OID_802_11_BSSID, bssid, &len);
678
679 if (ret != 0)
680 memset(bssid, 0, ETH_ALEN);
681
682 return ret;
683}
684
685
686static int is_associated(struct usbnet *usbdev)
687{
688 u8 bssid[ETH_ALEN];
689 int ret;
690
691 ret = get_bssid(usbdev, bssid);
692
693 return(ret == 0 && memcmp(bssid, zero_bssid, ETH_ALEN) != 0);
694}
695
696
697static int disassociate(struct usbnet *usbdev, int reset_ssid)
698{
699 struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
700 struct NDIS_802_11_SSID ssid;
701 int i, ret = 0;
702
703 if (priv->radio_on) {
704 ret = rndis_set_oid(usbdev, OID_802_11_DISASSOCIATE, NULL, 0);
705 if (ret == 0) {
706 priv->radio_on = 0;
707 devdbg(usbdev, "disassociate: radio_on = 0");
708
709 if (reset_ssid)
710 msleep(100);
711 }
712 }
713
714 /* disassociate causes radio to be turned off; if reset_ssid
715 * is given, set random ssid to enable radio */
716 if (reset_ssid) {
717 ssid.SsidLength = cpu_to_le32(sizeof(ssid.Ssid));
718 get_random_bytes(&ssid.Ssid[2], sizeof(ssid.Ssid)-2);
719 ssid.Ssid[0] = 0x1;
720 ssid.Ssid[1] = 0xff;
721 for (i = 2; i < sizeof(ssid.Ssid); i++)
722 ssid.Ssid[i] = 0x1 + (ssid.Ssid[i] * 0xfe / 0xff);
723 ret = set_essid(usbdev, &ssid);
724 }
725 return ret;
726}
727
728
729static int set_auth_mode(struct usbnet *usbdev, int wpa_version, int authalg)
730{
731 struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
732 __le32 tmp;
733 int auth_mode, ret;
734
735 devdbg(usbdev, "set_auth_mode: wpa_version=0x%x authalg=0x%x "
736 "keymgmt=0x%x", wpa_version, authalg, priv->wpa_keymgmt);
737
738 if (wpa_version & IW_AUTH_WPA_VERSION_WPA2) {
739 if (priv->wpa_keymgmt & IW_AUTH_KEY_MGMT_802_1X)
740 auth_mode = Ndis802_11AuthModeWPA2;
741 else
742 auth_mode = Ndis802_11AuthModeWPA2PSK;
743 } else if (wpa_version & IW_AUTH_WPA_VERSION_WPA) {
744 if (priv->wpa_keymgmt & IW_AUTH_KEY_MGMT_802_1X)
745 auth_mode = Ndis802_11AuthModeWPA;
746 else if (priv->wpa_keymgmt & IW_AUTH_KEY_MGMT_PSK)
747 auth_mode = Ndis802_11AuthModeWPAPSK;
748 else
749 auth_mode = Ndis802_11AuthModeWPANone;
750 } else if (authalg & IW_AUTH_ALG_SHARED_KEY) {
751 if (authalg & IW_AUTH_ALG_OPEN_SYSTEM)
752 auth_mode = Ndis802_11AuthModeAutoSwitch;
753 else
754 auth_mode = Ndis802_11AuthModeShared;
755 } else
756 auth_mode = Ndis802_11AuthModeOpen;
757
758 tmp = cpu_to_le32(auth_mode);
759 ret = rndis_set_oid(usbdev, OID_802_11_AUTHENTICATION_MODE, &tmp,
760 sizeof(tmp));
761 if (ret != 0) {
762 devwarn(usbdev, "setting auth mode failed (%08X)", ret);
763 return ret;
764 }
765
766 priv->wpa_version = wpa_version;
767 priv->wpa_authalg = authalg;
768 return 0;
769}
770
771
772static int set_priv_filter(struct usbnet *usbdev)
773{
774 struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
775 __le32 tmp;
776
777 devdbg(usbdev, "set_priv_filter: wpa_version=0x%x", priv->wpa_version);
778
779 if (priv->wpa_version & IW_AUTH_WPA_VERSION_WPA2 ||
780 priv->wpa_version & IW_AUTH_WPA_VERSION_WPA)
781 tmp = cpu_to_le32(Ndis802_11PrivFilter8021xWEP);
782 else
783 tmp = cpu_to_le32(Ndis802_11PrivFilterAcceptAll);
784
785 return rndis_set_oid(usbdev, OID_802_11_PRIVACY_FILTER, &tmp,
786 sizeof(tmp));
787}
788
789
790static int set_encr_mode(struct usbnet *usbdev, int pairwise, int groupwise)
791{
792 struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
793 __le32 tmp;
794 int encr_mode, ret;
795
796 devdbg(usbdev, "set_encr_mode: cipher_pair=0x%x cipher_group=0x%x",
797 pairwise,
798 groupwise);
799
800 if (pairwise & IW_AUTH_CIPHER_CCMP)
801 encr_mode = Ndis802_11Encryption3Enabled;
802 else if (pairwise & IW_AUTH_CIPHER_TKIP)
803 encr_mode = Ndis802_11Encryption2Enabled;
804 else if (pairwise &
805 (IW_AUTH_CIPHER_WEP40 | IW_AUTH_CIPHER_WEP104))
806 encr_mode = Ndis802_11Encryption1Enabled;
807 else if (groupwise & IW_AUTH_CIPHER_CCMP)
808 encr_mode = Ndis802_11Encryption3Enabled;
809 else if (groupwise & IW_AUTH_CIPHER_TKIP)
810 encr_mode = Ndis802_11Encryption2Enabled;
811 else
812 encr_mode = Ndis802_11EncryptionDisabled;
813
814 tmp = cpu_to_le32(encr_mode);
815 ret = rndis_set_oid(usbdev, OID_802_11_ENCRYPTION_STATUS, &tmp,
816 sizeof(tmp));
817 if (ret != 0) {
818 devwarn(usbdev, "setting encr mode failed (%08X)", ret);
819 return ret;
820 }
821
822 priv->wpa_cipher_pair = pairwise;
823 priv->wpa_cipher_group = groupwise;
824 return 0;
825}
826
827
828static int set_assoc_params(struct usbnet *usbdev)
829{
830 struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
831
832 set_auth_mode(usbdev, priv->wpa_version, priv->wpa_authalg);
833 set_priv_filter(usbdev);
834 set_encr_mode(usbdev, priv->wpa_cipher_pair, priv->wpa_cipher_group);
835
836 return 0;
837}
838
839
840static int set_infra_mode(struct usbnet *usbdev, int mode)
841{
842 struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
843 __le32 tmp;
844 int ret, i;
845
846 devdbg(usbdev, "set_infra_mode: infra_mode=0x%x", priv->infra_mode);
847
848 tmp = cpu_to_le32(mode);
849 ret = rndis_set_oid(usbdev, OID_802_11_INFRASTRUCTURE_MODE, &tmp,
850 sizeof(tmp));
851 if (ret != 0) {
852 devwarn(usbdev, "setting infra mode failed (%08X)", ret);
853 return ret;
854 }
855
856 /* NDIS drivers clear keys when infrastructure mode is
857 * changed. But Linux tools assume otherwise. So set the
858 * keys */
859 if (priv->wpa_keymgmt == 0 ||
860 priv->wpa_keymgmt == IW_AUTH_KEY_MGMT_802_1X) {
861 for (i = 0; i < 4; i++) {
862 if (priv->encr_key_len[i] > 0)
863 add_wep_key(usbdev, priv->encr_keys[i],
864 priv->encr_key_len[i], i);
865 }
866 }
867
868 priv->infra_mode = mode;
869 return 0;
870}
871
872
873static void set_default_iw_params(struct usbnet *usbdev)
874{
875 struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
876
877 priv->wpa_keymgmt = 0;
878 priv->wpa_version = 0;
879
880 set_infra_mode(usbdev, Ndis802_11Infrastructure);
881 set_auth_mode(usbdev, IW_AUTH_WPA_VERSION_DISABLED,
882 IW_AUTH_ALG_OPEN_SYSTEM);
883 set_priv_filter(usbdev);
884 set_encr_mode(usbdev, IW_AUTH_CIPHER_NONE, IW_AUTH_CIPHER_NONE);
885}
886
887
888static int deauthenticate(struct usbnet *usbdev)
889{
890 int ret;
891
892 ret = disassociate(usbdev, 1);
893 set_default_iw_params(usbdev);
894 return ret;
895}
896
897
898/* index must be 0 - N, as per NDIS */
899static int add_wep_key(struct usbnet *usbdev, char *key, int key_len, int index)
900{
901 struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
902 struct NDIS_802_11_WEP ndis_key;
903 int ret;
904
905 if (key_len <= 0 || key_len > 32 || index < 0 || index >= 4)
906 return -EINVAL;
907
908 memset(&ndis_key, 0, sizeof(ndis_key));
909
910 ndis_key.Length = cpu_to_le32(sizeof(ndis_key));
911 ndis_key.KeyLength = cpu_to_le32(key_len);
912 ndis_key.KeyIndex = cpu_to_le32(index);
913 memcpy(&ndis_key.KeyMaterial, key, key_len);
914
915 if (index == priv->encr_tx_key_index) {
916 ndis_key.KeyIndex |= cpu_to_le32(1 << 31);
917 ret = set_encr_mode(usbdev, IW_AUTH_CIPHER_WEP104,
918 IW_AUTH_CIPHER_NONE);
919 if (ret)
920 devwarn(usbdev, "encryption couldn't be enabled (%08X)",
921 ret);
922 }
923
924 ret = rndis_set_oid(usbdev, OID_802_11_ADD_WEP, &ndis_key,
925 sizeof(ndis_key));
926 if (ret != 0) {
927 devwarn(usbdev, "adding encryption key %d failed (%08X)",
928 index+1, ret);
929 return ret;
930 }
931
932 priv->encr_key_len[index] = key_len;
933 memcpy(&priv->encr_keys[index], key, key_len);
934
935 return 0;
936}
937
938
939/* remove_key is for both wep and wpa */
940static int remove_key(struct usbnet *usbdev, int index, u8 bssid[ETH_ALEN])
941{
942 struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
943 struct NDIS_802_11_REMOVE_KEY remove_key;
944 __le32 keyindex;
945 int ret;
946
947 if (priv->encr_key_len[index] == 0)
948 return 0;
949
950 priv->encr_key_len[index] = 0;
951 memset(&priv->encr_keys[index], 0, sizeof(priv->encr_keys[index]));
952
953 if (priv->wpa_cipher_pair == IW_AUTH_CIPHER_TKIP ||
954 priv->wpa_cipher_pair == IW_AUTH_CIPHER_CCMP ||
955 priv->wpa_cipher_group == IW_AUTH_CIPHER_TKIP ||
956 priv->wpa_cipher_group == IW_AUTH_CIPHER_CCMP) {
957 remove_key.Length = cpu_to_le32(sizeof(remove_key));
958 remove_key.KeyIndex = cpu_to_le32(index);
959 if (bssid) {
960 /* pairwise key */
961 if (memcmp(bssid, ffff_bssid, ETH_ALEN) != 0)
962 remove_key.KeyIndex |= cpu_to_le32(1 << 30);
963 memcpy(remove_key.Bssid, bssid,
964 sizeof(remove_key.Bssid));
965 } else
966 memset(remove_key.Bssid, 0xff,
967 sizeof(remove_key.Bssid));
968
969 ret = rndis_set_oid(usbdev, OID_802_11_REMOVE_KEY, &remove_key,
970 sizeof(remove_key));
971 if (ret != 0)
972 return ret;
973 } else {
974 keyindex = cpu_to_le32(index);
975 ret = rndis_set_oid(usbdev, OID_802_11_REMOVE_WEP, &keyindex,
976 sizeof(keyindex));
977 if (ret != 0) {
978 devwarn(usbdev,
979 "removing encryption key %d failed (%08X)",
980 index, ret);
981 return ret;
982 }
983 }
984
985 /* if it is transmit key, disable encryption */
986 if (index == priv->encr_tx_key_index)
987 set_encr_mode(usbdev, IW_AUTH_CIPHER_NONE, IW_AUTH_CIPHER_NONE);
988
989 return 0;
990}
991
992
993static void set_multicast_list(struct usbnet *usbdev)
994{
995 struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
996 struct dev_mc_list *mclist;
997 __le32 filter;
998 int ret, i, size;
999 char *buf;
1000
1001 filter = RNDIS_PACKET_TYPE_DIRECTED | RNDIS_PACKET_TYPE_BROADCAST;
1002
1003 if (usbdev->net->flags & IFF_PROMISC) {
1004 filter |= RNDIS_PACKET_TYPE_PROMISCUOUS |
1005 RNDIS_PACKET_TYPE_ALL_LOCAL;
1006 } else if (usbdev->net->flags & IFF_ALLMULTI ||
1007 usbdev->net->mc_count > priv->multicast_size) {
1008 filter |= RNDIS_PACKET_TYPE_ALL_MULTICAST;
1009 } else if (usbdev->net->mc_count > 0) {
1010 size = min(priv->multicast_size, usbdev->net->mc_count);
1011 buf = kmalloc(size * ETH_ALEN, GFP_KERNEL);
1012 if (!buf) {
1013 devwarn(usbdev,
1014 "couldn't alloc %d bytes of memory",
1015 size * ETH_ALEN);
1016 return;
1017 }
1018
1019 mclist = usbdev->net->mc_list;
1020 for (i = 0; i < size && mclist; mclist = mclist->next) {
1021 if (mclist->dmi_addrlen != ETH_ALEN)
1022 continue;
1023
1024 memcpy(buf + i * ETH_ALEN, mclist->dmi_addr, ETH_ALEN);
1025 i++;
1026 }
1027
1028 ret = rndis_set_oid(usbdev, OID_802_3_MULTICAST_LIST, buf,
1029 i * ETH_ALEN);
1030 if (ret == 0 && i > 0)
1031 filter |= RNDIS_PACKET_TYPE_MULTICAST;
1032 else
1033 filter |= RNDIS_PACKET_TYPE_ALL_MULTICAST;
1034
1035 devdbg(usbdev, "OID_802_3_MULTICAST_LIST(%d, max: %d) -> %d",
1036 i, priv->multicast_size, ret);
1037
1038 kfree(buf);
1039 }
1040
1041 ret = rndis_set_oid(usbdev, OID_GEN_CURRENT_PACKET_FILTER, &filter,
1042 sizeof(filter));
1043 if (ret < 0) {
1044 devwarn(usbdev, "couldn't set packet filter: %08x",
1045 le32_to_cpu(filter));
1046 }
1047
1048 devdbg(usbdev, "OID_GEN_CURRENT_PACKET_FILTER(%08x) -> %d",
1049 le32_to_cpu(filter), ret);
1050}
1051
1052
1053/*
1054 * wireless extension handlers
1055 */
1056
1057static int rndis_iw_commit(struct net_device *dev,
1058 struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
1059{
1060 /* dummy op */
1061 return 0;
1062}
1063
1064
1065static int rndis_iw_get_range(struct net_device *dev,
1066 struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
1067{
1068 struct iw_range *range = (struct iw_range *)extra;
1069 struct usbnet *usbdev = dev->priv;
1070 struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
1071 int len, ret, i, j, num, has_80211g_rates;
1072 u8 rates[8];
1073 __le32 tx_power;
1074
1075 devdbg(usbdev, "SIOCGIWRANGE");
1076
1077 /* clear iw_range struct */
1078 memset(range, 0, sizeof(*range));
1079 wrqu->data.length = sizeof(*range);
1080
1081 range->txpower_capa = IW_TXPOW_MWATT;
1082 range->num_txpower = 1;
1083 if (priv->caps & CAP_SUPPORT_TXPOWER) {
1084 len = sizeof(tx_power);
1085 ret = rndis_query_oid(usbdev, OID_802_11_TX_POWER_LEVEL,
1086 &tx_power, &len);
1087 if (ret == 0 && le32_to_cpu(tx_power) != 0xFF)
1088 range->txpower[0] = le32_to_cpu(tx_power);
1089 else
1090 range->txpower[0] = get_bcm4320_power(priv);
1091 } else
1092 range->txpower[0] = get_bcm4320_power(priv);
1093
1094 len = sizeof(rates);
1095 ret = rndis_query_oid(usbdev, OID_802_11_SUPPORTED_RATES, &rates,
1096 &len);
1097 has_80211g_rates = 0;
1098 if (ret == 0) {
1099 j = 0;
1100 for (i = 0; i < len; i++) {
1101 if (rates[i] == 0)
1102 break;
1103 range->bitrate[j] = (rates[i] & 0x7f) * 500000;
1104 /* check for non 802.11b rates */
1105 if (range->bitrate[j] == 6000000 ||
1106 range->bitrate[j] == 9000000 ||
1107 (range->bitrate[j] >= 12000000 &&
1108 range->bitrate[j] != 22000000))
1109 has_80211g_rates = 1;
1110 j++;
1111 }
1112 range->num_bitrates = j;
1113 } else
1114 range->num_bitrates = 0;
1115
1116 /* fill in 802.11g rates */
1117 if (has_80211g_rates) {
1118 num = range->num_bitrates;
1119 for (i = 0; i < sizeof(rates_80211g); i++) {
1120 for (j = 0; j < num; j++) {
1121 if (range->bitrate[j] ==
1122 rates_80211g[i] * 1000000)
1123 break;
1124 }
1125 if (j == num)
1126 range->bitrate[range->num_bitrates++] =
1127 rates_80211g[i] * 1000000;
1128 if (range->num_bitrates == IW_MAX_BITRATES)
1129 break;
1130 }
1131
1132 /* estimated max real througput in bps */
1133 range->throughput = 54 * 1000 * 1000 / 2;
1134
1135 /* ~35% more with afterburner */
1136 if (priv->param_afterburner)
1137 range->throughput = range->throughput / 100 * 135;
1138 } else {
1139 /* estimated max real througput in bps */
1140 range->throughput = 11 * 1000 * 1000 / 2;
1141 }
1142
1143 range->num_channels = (sizeof(freq_chan)/sizeof(freq_chan[0]));
1144
1145 for (i = 0; i < (sizeof(freq_chan)/sizeof(freq_chan[0])) &&
1146 i < IW_MAX_FREQUENCIES; i++) {
1147 range->freq[i].i = i + 1;
1148 range->freq[i].m = freq_chan[i] * 100000;
1149 range->freq[i].e = 1;
1150 }
1151 range->num_frequency = i;
1152
1153 range->min_rts = 0;
1154 range->max_rts = 2347;
1155 range->min_frag = 256;
1156 range->max_frag = 2346;
1157
1158 range->max_qual.qual = 100;
1159 range->max_qual.level = 154;
1160 range->max_qual.updated = IW_QUAL_QUAL_UPDATED
1161 | IW_QUAL_LEVEL_UPDATED
1162 | IW_QUAL_NOISE_INVALID;
1163
1164 range->we_version_compiled = WIRELESS_EXT;
1165 range->we_version_source = WIRELESS_EXT;
1166
1167 range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
1168 IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
1169 return 0;
1170}
1171
1172
1173static int rndis_iw_get_name(struct net_device *dev,
1174 struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
1175{
1176 struct usbnet *usbdev = dev->priv;
1177 struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
1178
1179 strcpy(wrqu->name, priv->name);
1180 return 0;
1181}
1182
1183
1184static int rndis_iw_set_essid(struct net_device *dev,
1185 struct iw_request_info *info, union iwreq_data *wrqu, char *essid)
1186{
1187 struct NDIS_802_11_SSID ssid;
1188 int length = wrqu->essid.length;
1189 struct usbnet *usbdev = dev->priv;
1190
1191 devdbg(usbdev, "SIOCSIWESSID: [flags:%d,len:%d] '%.32s'",
1192 wrqu->essid.flags, wrqu->essid.length, essid);
1193
1194 if (length > NDIS_802_11_LENGTH_SSID)
1195 length = NDIS_802_11_LENGTH_SSID;
1196
1197 ssid.SsidLength = cpu_to_le32(length);
1198 if (length > 0)
1199 memcpy(ssid.Ssid, essid, length);
1200 else
1201 memset(ssid.Ssid, 0, NDIS_802_11_LENGTH_SSID);
1202
1203 set_assoc_params(usbdev);
1204
1205 if (!wrqu->essid.flags || length == 0)
1206 return disassociate(usbdev, 1);
1207 else
1208 return set_essid(usbdev, &ssid);
1209}
1210
1211
1212static int rndis_iw_get_essid(struct net_device *dev,
1213 struct iw_request_info *info, union iwreq_data *wrqu, char *essid)
1214{
1215 struct NDIS_802_11_SSID ssid;
1216 struct usbnet *usbdev = dev->priv;
1217 int ret;
1218
1219 ret = get_essid(usbdev, &ssid);
1220
1221 if (ret == 0 && le32_to_cpu(ssid.SsidLength) > 0) {
1222 wrqu->essid.flags = 1;
1223 wrqu->essid.length = le32_to_cpu(ssid.SsidLength);
1224 memcpy(essid, ssid.Ssid, wrqu->essid.length);
1225 essid[wrqu->essid.length] = 0;
1226 } else {
1227 memset(essid, 0, sizeof(NDIS_802_11_LENGTH_SSID));
1228 wrqu->essid.flags = 0;
1229 wrqu->essid.length = 0;
1230 }
1231 devdbg(usbdev, "SIOCGIWESSID: %s", essid);
1232 return ret;
1233}
1234
1235
1236static int rndis_iw_get_bssid(struct net_device *dev,
1237 struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
1238{
1239 struct usbnet *usbdev = dev->priv;
1240 unsigned char bssid[ETH_ALEN];
1241 int ret;
1242 DECLARE_MAC_BUF(mac);
1243
1244 ret = get_bssid(usbdev, bssid);
1245
1246 if (ret == 0)
1247 devdbg(usbdev, "SIOCGIWAP: %s", print_mac(mac, bssid));
1248 else
1249 devdbg(usbdev, "SIOCGIWAP: <not associated>");
1250
1251 wrqu->ap_addr.sa_family = ARPHRD_ETHER;
1252 memcpy(wrqu->ap_addr.sa_data, bssid, ETH_ALEN);
1253
1254 return ret;
1255}
1256
1257
1258static int rndis_iw_set_bssid(struct net_device *dev,
1259 struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
1260{
1261 struct usbnet *usbdev = dev->priv;
1262 u8 *bssid = (u8 *)wrqu->ap_addr.sa_data;
1263 DECLARE_MAC_BUF(mac);
1264 int ret;
1265
1266 devdbg(usbdev, "SIOCSIWAP: %s", print_mac(mac, bssid));
1267
1268 ret = rndis_set_oid(usbdev, OID_802_11_BSSID, bssid, ETH_ALEN);
1269
1270 /* user apps may set ap's mac address, which is not required;
1271 * they may fail to work if this function fails, so return
1272 * success */
1273 if (ret)
1274 devwarn(usbdev, "setting AP mac address failed (%08X)", ret);
1275
1276 return 0;
1277}
1278
1279
1280static int rndis_iw_set_auth(struct net_device *dev,
1281 struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
1282{
1283 struct iw_param *p = &wrqu->param;
1284 struct usbnet *usbdev = dev->priv;
1285 struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
1286 int ret = -ENOTSUPP;
1287
1288 switch (p->flags & IW_AUTH_INDEX) {
1289 case IW_AUTH_WPA_VERSION:
1290 devdbg(usbdev, "SIOCSIWAUTH: WPA_VERSION, %08x", p->value);
1291 priv->wpa_version = p->value;
1292 ret = 0;
1293 break;
1294
1295 case IW_AUTH_CIPHER_PAIRWISE:
1296 devdbg(usbdev, "SIOCSIWAUTH: CIPHER_PAIRWISE, %08x", p->value);
1297 priv->wpa_cipher_pair = p->value;
1298 ret = 0;
1299 break;
1300
1301 case IW_AUTH_CIPHER_GROUP:
1302 devdbg(usbdev, "SIOCSIWAUTH: CIPHER_GROUP, %08x", p->value);
1303 priv->wpa_cipher_group = p->value;
1304 ret = 0;
1305 break;
1306
1307 case IW_AUTH_KEY_MGMT:
1308 devdbg(usbdev, "SIOCSIWAUTH: KEY_MGMT, %08x", p->value);
1309 priv->wpa_keymgmt = p->value;
1310 ret = 0;
1311 break;
1312
1313 case IW_AUTH_TKIP_COUNTERMEASURES:
1314 devdbg(usbdev, "SIOCSIWAUTH: TKIP_COUNTERMEASURES, %08x",
1315 p->value);
1316 ret = 0;
1317 break;
1318
1319 case IW_AUTH_DROP_UNENCRYPTED:
1320 devdbg(usbdev, "SIOCSIWAUTH: DROP_UNENCRYPTED, %08x", p->value);
1321 ret = 0;
1322 break;
1323
1324 case IW_AUTH_80211_AUTH_ALG:
1325 devdbg(usbdev, "SIOCSIWAUTH: 80211_AUTH_ALG, %08x", p->value);
1326 priv->wpa_authalg = p->value;
1327 ret = 0;
1328 break;
1329
1330 case IW_AUTH_WPA_ENABLED:
1331 devdbg(usbdev, "SIOCSIWAUTH: WPA_ENABLED, %08x", p->value);
1332 if (wrqu->param.value)
1333 deauthenticate(usbdev);
1334 ret = 0;
1335 break;
1336
1337 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
1338 devdbg(usbdev, "SIOCSIWAUTH: RX_UNENCRYPTED_EAPOL, %08x",
1339 p->value);
1340 ret = 0;
1341 break;
1342
1343 case IW_AUTH_ROAMING_CONTROL:
1344 devdbg(usbdev, "SIOCSIWAUTH: ROAMING_CONTROL, %08x", p->value);
1345 ret = 0;
1346 break;
1347
1348 case IW_AUTH_PRIVACY_INVOKED:
1349 devdbg(usbdev, "SIOCSIWAUTH: invalid cmd %d",
1350 wrqu->param.flags & IW_AUTH_INDEX);
1351 return -EOPNOTSUPP;
1352
1353 default:
1354 devdbg(usbdev, "SIOCSIWAUTH: UNKNOWN %08x, %08x",
1355 p->flags & IW_AUTH_INDEX, p->value);
1356 }
1357 return ret;
1358}
1359
1360
1361static int rndis_iw_get_auth(struct net_device *dev,
1362 struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
1363{
1364 struct iw_param *p = &wrqu->param;
1365 struct usbnet *usbdev = dev->priv;
1366 struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
1367
1368 switch (p->flags & IW_AUTH_INDEX) {
1369 case IW_AUTH_WPA_VERSION:
1370 p->value = priv->wpa_version;
1371 break;
1372 case IW_AUTH_CIPHER_PAIRWISE:
1373 p->value = priv->wpa_cipher_pair;
1374 break;
1375 case IW_AUTH_CIPHER_GROUP:
1376 p->value = priv->wpa_cipher_group;
1377 break;
1378 case IW_AUTH_KEY_MGMT:
1379 p->value = priv->wpa_keymgmt;
1380 break;
1381 case IW_AUTH_80211_AUTH_ALG:
1382 p->value = priv->wpa_authalg;
1383 break;
1384 default:
1385 devdbg(usbdev, "SIOCGIWAUTH: invalid cmd %d",
1386 wrqu->param.flags & IW_AUTH_INDEX);
1387 return -EOPNOTSUPP;
1388 }
1389 return 0;
1390}
1391
1392
1393static int rndis_iw_get_mode(struct net_device *dev,
1394 struct iw_request_info *info,
1395 union iwreq_data *wrqu, char *extra)
1396{
1397 struct usbnet *usbdev = dev->priv;
1398 struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
1399
1400 switch (priv->infra_mode) {
1401 case Ndis802_11IBSS:
1402 wrqu->mode = IW_MODE_ADHOC;
1403 break;
1404 case Ndis802_11Infrastructure:
1405 wrqu->mode = IW_MODE_INFRA;
1406 break;
1407 /*case Ndis802_11AutoUnknown:*/
1408 default:
1409 wrqu->mode = IW_MODE_AUTO;
1410 break;
1411 }
1412 devdbg(usbdev, "SIOCGIWMODE: %08x", wrqu->mode);
1413 return 0;
1414}
1415
1416
1417static int rndis_iw_set_mode(struct net_device *dev,
1418 struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
1419{
1420 struct usbnet *usbdev = dev->priv;
1421 int mode;
1422
1423 devdbg(usbdev, "SIOCSIWMODE: %08x", wrqu->mode);
1424
1425 switch (wrqu->mode) {
1426 case IW_MODE_ADHOC:
1427 mode = Ndis802_11IBSS;
1428 break;
1429 case IW_MODE_INFRA:
1430 mode = Ndis802_11Infrastructure;
1431 break;
1432 /*case IW_MODE_AUTO:*/
1433 default:
1434 mode = Ndis802_11AutoUnknown;
1435 break;
1436 }
1437
1438 return set_infra_mode(usbdev, mode);
1439}
1440
1441
1442static int rndis_iw_set_encode(struct net_device *dev,
1443 struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
1444{
1445 struct usbnet *usbdev = dev->priv;
1446 struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
1447 int ret, index, key_len;
1448 u8 *key;
1449
1450 index = (wrqu->encoding.flags & IW_ENCODE_INDEX);
1451
1452 /* iwconfig gives index as 1 - N */
1453 if (index > 0)
1454 index--;
1455 else
1456 index = priv->encr_tx_key_index;
1457
1458 if (index < 0 || index >= 4) {
1459 devwarn(usbdev, "encryption index out of range (%u)", index);
1460 return -EINVAL;
1461 }
1462
1463 /* remove key if disabled */
1464 if (wrqu->data.flags & IW_ENCODE_DISABLED) {
1465 if (remove_key(usbdev, index, NULL))
1466 return -EINVAL;
1467 else
1468 return 0;
1469 }
1470
1471 /* global encryption state (for all keys) */
1472 if (wrqu->data.flags & IW_ENCODE_OPEN)
1473 ret = set_auth_mode(usbdev, IW_AUTH_WPA_VERSION_DISABLED,
1474 IW_AUTH_ALG_OPEN_SYSTEM);
1475 else /*if (wrqu->data.flags & IW_ENCODE_RESTRICTED)*/
1476 ret = set_auth_mode(usbdev, IW_AUTH_WPA_VERSION_DISABLED,
1477 IW_AUTH_ALG_SHARED_KEY);
1478 if (ret != 0)
1479 return ret;
1480
1481 if (wrqu->data.length > 0) {
1482 key_len = wrqu->data.length;
1483 key = extra;
1484 } else {
1485 /* must be set as tx key */
1486 if (priv->encr_key_len[index] == 0)
1487 return -EINVAL;
1488 key_len = priv->encr_key_len[index];
1489 key = priv->encr_keys[index];
1490 priv->encr_tx_key_index = index;
1491 }
1492
1493 if (add_wep_key(usbdev, key, key_len, index) != 0)
1494 return -EINVAL;
1495
1496 if (index == priv->encr_tx_key_index)
1497 /* ndis drivers want essid to be set after setting encr */
1498 set_essid(usbdev, &priv->essid);
1499
1500 return 0;
1501}
1502
1503
1504static int rndis_iw_set_encode_ext(struct net_device *dev,
1505 struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
1506{
1507 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
1508 struct usbnet *usbdev = dev->priv;
1509 struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
1510 struct NDIS_802_11_KEY ndis_key;
1511 int i, keyidx, ret;
1512 u8 *addr;
1513
1514 keyidx = wrqu->encoding.flags & IW_ENCODE_INDEX;
1515
1516 /* iwconfig gives index as 1 - N */
1517 if (keyidx)
1518 keyidx--;
1519 else
1520 keyidx = priv->encr_tx_key_index;
1521
1522 if (keyidx < 0 || keyidx >= 4)
1523 return -EINVAL;
1524
1525 if (ext->alg == WPA_ALG_WEP) {
1526 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
1527 priv->encr_tx_key_index = keyidx;
1528 return add_wep_key(usbdev, ext->key, ext->key_len, keyidx);
1529 }
1530
1531 if ((wrqu->encoding.flags & IW_ENCODE_DISABLED) ||
1532 ext->alg == IW_ENCODE_ALG_NONE || ext->key_len == 0)
1533 return remove_key(usbdev, keyidx, NULL);
1534
1535 if (ext->key_len > sizeof(ndis_key.KeyMaterial))
1536 return -1;
1537
1538 memset(&ndis_key, 0, sizeof(ndis_key));
1539
1540 ndis_key.Length = cpu_to_le32(sizeof(ndis_key) -
1541 sizeof(ndis_key.KeyMaterial) + ext->key_len);
1542 ndis_key.KeyLength = cpu_to_le32(ext->key_len);
1543 ndis_key.KeyIndex = cpu_to_le32(keyidx);
1544
1545 if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) {
1546 for (i = 0; i < 6; i++)
1547 ndis_key.KeyRSC |=
1548 cpu_to_le64(ext->rx_seq[i] << (i * 8));
1549 ndis_key.KeyIndex |= cpu_to_le32(1 << 29);
1550 }
1551
1552 addr = ext->addr.sa_data;
1553 if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
1554 /* group key */
1555 if (priv->infra_mode == Ndis802_11IBSS)
1556 memset(ndis_key.Bssid, 0xff, ETH_ALEN);
1557 else
1558 get_bssid(usbdev, ndis_key.Bssid);
1559 } else {
1560 /* pairwise key */
1561 ndis_key.KeyIndex |= cpu_to_le32(1 << 30);
1562 memcpy(ndis_key.Bssid, addr, ETH_ALEN);
1563 }
1564
1565 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
1566 ndis_key.KeyIndex |= cpu_to_le32(1 << 31);
1567
1568 if (ext->alg == IW_ENCODE_ALG_TKIP && ext->key_len == 32) {
1569 /* wpa_supplicant gives us the Michael MIC RX/TX keys in
1570 * different order than NDIS spec, so swap the order here. */
1571 memcpy(ndis_key.KeyMaterial, ext->key, 16);
1572 memcpy(ndis_key.KeyMaterial + 16, ext->key + 24, 8);
1573 memcpy(ndis_key.KeyMaterial + 24, ext->key + 16, 8);
1574 } else
1575 memcpy(ndis_key.KeyMaterial, ext->key, ext->key_len);
1576
1577 ret = rndis_set_oid(usbdev, OID_802_11_ADD_KEY, &ndis_key,
1578 le32_to_cpu(ndis_key.Length));
1579 devdbg(usbdev, "SIOCSIWENCODEEXT: OID_802_11_ADD_KEY -> %08X", ret);
1580 if (ret != 0)
1581 return ret;
1582
1583 priv->encr_key_len[keyidx] = ext->key_len;
1584 memcpy(&priv->encr_keys[keyidx], ndis_key.KeyMaterial, ext->key_len);
1585 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
1586 priv->encr_tx_key_index = keyidx;
1587
1588 return 0;
1589}
1590
1591
1592static int rndis_iw_set_scan(struct net_device *dev,
1593 struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
1594{
1595 struct iw_param *param = &wrqu->param;
1596 struct usbnet *usbdev = dev->priv;
1597 union iwreq_data evt;
1598 int ret = -EINVAL;
1599 __le32 tmp;
1600
1601 devdbg(usbdev, "SIOCSIWSCAN");
1602
1603 if (param->flags == 0) {
1604 tmp = ccpu2(1);
1605 ret = rndis_set_oid(usbdev, OID_802_11_BSSID_LIST_SCAN, &tmp,
1606 sizeof(tmp));
1607 evt.data.flags = 0;
1608 evt.data.length = 0;
1609 wireless_send_event(dev, SIOCGIWSCAN, &evt, NULL);
1610 }
1611 return ret;
1612}
1613
1614
1615static char *rndis_translate_scan(struct net_device *dev,
1616 char *cev, char *end_buf, struct NDIS_WLAN_BSSID_EX *bssid)
1617{
1618#ifdef DEBUG
1619 struct usbnet *usbdev = dev->priv;
1620#endif
1621 struct ieee80211_info_element *ie;
1622 char *current_val;
1623 int bssid_len, ie_len, i;
1624 u32 beacon, atim;
1625 struct iw_event iwe;
1626 unsigned char sbuf[32];
1627 DECLARE_MAC_BUF(mac);
1628
1629 bssid_len = le32_to_cpu(bssid->Length);
1630
1631 devdbg(usbdev, "BSSID %s", print_mac(mac, bssid->MacAddress));
1632 iwe.cmd = SIOCGIWAP;
1633 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
1634 memcpy(iwe.u.ap_addr.sa_data, bssid->MacAddress, ETH_ALEN);
1635 cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_ADDR_LEN);
1636
1637 devdbg(usbdev, "SSID(%d) %s",
1638 le32_to_cpu(bssid->Ssid.SsidLength),
1639 bssid->Ssid.Ssid);
1640 iwe.cmd = SIOCGIWESSID;
1641 iwe.u.essid.length = le32_to_cpu(bssid->Ssid.SsidLength);
1642 iwe.u.essid.flags = 1;
1643 cev = iwe_stream_add_point(cev, end_buf, &iwe,
1644 bssid->Ssid.Ssid);
1645
1646 devdbg(usbdev, "MODE %d",
1647 le32_to_cpu(bssid->InfrastructureMode));
1648 iwe.cmd = SIOCGIWMODE;
1649 switch (le32_to_cpu(bssid->InfrastructureMode)) {
1650 case Ndis802_11IBSS:
1651 iwe.u.mode = IW_MODE_ADHOC;
1652 break;
1653 case Ndis802_11Infrastructure:
1654 iwe.u.mode = IW_MODE_INFRA;
1655 break;
1656 /*case Ndis802_11AutoUnknown:*/
1657 default:
1658 iwe.u.mode = IW_MODE_AUTO;
1659 break;
1660 }
1661 cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_UINT_LEN);
1662
1663 devdbg(usbdev, "FREQ %d kHz",
1664 le32_to_cpu(bssid->Configuration.DSConfig));
1665 iwe.cmd = SIOCGIWFREQ;
1666 dsconfig_to_freq(le32_to_cpu(bssid->Configuration.DSConfig),
1667 &iwe.u.freq);
1668 cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_FREQ_LEN);
1669
1670 devdbg(usbdev, "QUAL %d", le32_to_cpu(bssid->Rssi));
1671 iwe.cmd = IWEVQUAL;
1672 iwe.u.qual.qual = level_to_qual(le32_to_cpu(bssid->Rssi));
1673 iwe.u.qual.level = le32_to_cpu(bssid->Rssi);
1674 iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED
1675 | IW_QUAL_LEVEL_UPDATED
1676 | IW_QUAL_NOISE_INVALID;
1677 cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_QUAL_LEN);
1678
1679 devdbg(usbdev, "ENCODE %d", le32_to_cpu(bssid->Privacy));
1680 iwe.cmd = SIOCGIWENCODE;
1681 iwe.u.data.length = 0;
1682 if (le32_to_cpu(bssid->Privacy) == Ndis802_11PrivFilterAcceptAll)
1683 iwe.u.data.flags = IW_ENCODE_DISABLED;
1684 else
1685 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
1686
1687 cev = iwe_stream_add_point(cev, end_buf, &iwe, NULL);
1688
1689 devdbg(usbdev, "RATES:");
1690 current_val = cev + IW_EV_LCP_LEN;
1691 iwe.cmd = SIOCGIWRATE;
1692 for (i = 0; i < sizeof(bssid->SupportedRates); i++) {
1693 if (bssid->SupportedRates[i] & 0x7f) {
1694 iwe.u.bitrate.value =
1695 ((bssid->SupportedRates[i] & 0x7f) *
1696 500000);
1697 devdbg(usbdev, " %d", iwe.u.bitrate.value);
1698 current_val = iwe_stream_add_value(cev,
1699 current_val, end_buf, &iwe,
1700 IW_EV_PARAM_LEN);
1701 }
1702 }
1703
1704 if ((current_val - cev) > IW_EV_LCP_LEN)
1705 cev = current_val;
1706
1707 beacon = le32_to_cpu(bssid->Configuration.BeaconPeriod);
1708 devdbg(usbdev, "BCN_INT %d", beacon);
1709 iwe.cmd = IWEVCUSTOM;
1710 snprintf(sbuf, sizeof(sbuf), "bcn_int=%d", beacon);
1711 iwe.u.data.length = strlen(sbuf);
1712 cev = iwe_stream_add_point(cev, end_buf, &iwe, sbuf);
1713
1714 atim = le32_to_cpu(bssid->Configuration.ATIMWindow);
1715 devdbg(usbdev, "ATIM %d", atim);
1716 iwe.cmd = IWEVCUSTOM;
1717 snprintf(sbuf, sizeof(sbuf), "atim=%u", atim);
1718 iwe.u.data.length = strlen(sbuf);
1719 cev = iwe_stream_add_point(cev, end_buf, &iwe, sbuf);
1720
1721 ie = (void *)(bssid->IEs + sizeof(struct NDIS_802_11_FIXED_IEs));
1722 ie_len = min(bssid_len - (int)sizeof(*bssid),
1723 (int)le32_to_cpu(bssid->IELength));
1724 ie_len -= sizeof(struct NDIS_802_11_FIXED_IEs);
1725 while (ie_len >= sizeof(*ie) && sizeof(*ie) + ie->len <= ie_len) {
1726 if ((ie->id == MFIE_TYPE_GENERIC && ie->len >= 4 &&
1727 memcmp(ie->data, "\x00\x50\xf2\x01", 4) == 0) ||
1728 ie->id == MFIE_TYPE_RSN) {
1729 devdbg(usbdev, "IE: WPA%d",
1730 (ie->id == MFIE_TYPE_RSN) ? 2 : 1);
1731 iwe.cmd = IWEVGENIE;
1732 iwe.u.data.length = min(ie->len + 2, MAX_WPA_IE_LEN);
1733 cev = iwe_stream_add_point(cev, end_buf, &iwe,
1734 (u8 *)ie);
1735 }
1736
1737 ie_len -= sizeof(*ie) + ie->len;
1738 ie = (struct ieee80211_info_element *)&ie->data[ie->len];
1739 }
1740
1741 return cev;
1742}
1743
1744
1745static int rndis_iw_get_scan(struct net_device *dev,
1746 struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
1747{
1748 struct usbnet *usbdev = dev->priv;
1749 void *buf = NULL;
1750 char *cev = extra;
1751 struct NDIS_802_11_BSSID_LIST_EX *bssid_list;
1752 struct NDIS_WLAN_BSSID_EX *bssid;
1753 int ret = -EINVAL, len, count, bssid_len;
1754
1755 devdbg(usbdev, "SIOCGIWSCAN");
1756
1757 len = CONTROL_BUFFER_SIZE;
1758 buf = kmalloc(len, GFP_KERNEL);
1759 if (!buf) {
1760 ret = -ENOMEM;
1761 goto out;
1762 }
1763
1764 ret = rndis_query_oid(usbdev, OID_802_11_BSSID_LIST, buf, &len);
1765
1766 if (ret != 0)
1767 goto out;
1768
1769 bssid_list = buf;
1770 bssid = bssid_list->Bssid;
1771 bssid_len = le32_to_cpu(bssid->Length);
1772 count = le32_to_cpu(bssid_list->NumberOfItems);
1773 devdbg(usbdev, "SIOCGIWSCAN: %d BSSIDs found", count);
1774
1775 while (count && ((void *)bssid + bssid_len) <= (buf + len)) {
1776 cev = rndis_translate_scan(dev, cev, extra + IW_SCAN_MAX_DATA,
1777 bssid);
1778 bssid = (void *)bssid + bssid_len;
1779 bssid_len = le32_to_cpu(bssid->Length);
1780 count--;
1781 }
1782
1783out:
1784 wrqu->data.length = cev - extra;
1785 wrqu->data.flags = 0;
1786 kfree(buf);
1787 return ret;
1788}
1789
1790
1791static int rndis_iw_set_genie(struct net_device *dev,
1792 struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
1793{
1794 struct usbnet *usbdev = dev->priv;
1795 struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
1796 int ret = 0;
1797
1798#ifdef DEBUG
1799 int j;
1800 u8 *gie = extra;
1801 for (j = 0; j < wrqu->data.length; j += 8)
1802 devdbg(usbdev,
1803 "SIOCSIWGENIE %04x - "
1804 "%02x %02x %02x %02x %02x %02x %02x %02x", j,
1805 gie[j + 0], gie[j + 1], gie[j + 2], gie[j + 3],
1806 gie[j + 4], gie[j + 5], gie[j + 6], gie[j + 7]);
1807#endif
1808 /* clear existing IEs */
1809 if (priv->wpa_ie_len) {
1810 kfree(priv->wpa_ie);
1811 priv->wpa_ie_len = 0;
1812 }
1813
1814 /* set new IEs */
1815 priv->wpa_ie = kmalloc(wrqu->data.length, GFP_KERNEL);
1816 if (priv->wpa_ie) {
1817 priv->wpa_ie_len = wrqu->data.length;
1818 memcpy(priv->wpa_ie, extra, priv->wpa_ie_len);
1819 } else
1820 ret = -ENOMEM;
1821 return ret;
1822}
1823
1824
1825static int rndis_iw_get_genie(struct net_device *dev,
1826 struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
1827{
1828 struct usbnet *usbdev = dev->priv;
1829 struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
1830
1831 devdbg(usbdev, "SIOCGIWGENIE");
1832
1833 if (priv->wpa_ie_len == 0 || priv->wpa_ie == NULL) {
1834 wrqu->data.length = 0;
1835 return 0;
1836 }
1837
1838 if (wrqu->data.length < priv->wpa_ie_len)
1839 return -E2BIG;
1840
1841 wrqu->data.length = priv->wpa_ie_len;
1842 memcpy(extra, priv->wpa_ie, priv->wpa_ie_len);
1843
1844 return 0;
1845}
1846
1847
1848static int rndis_iw_set_rts(struct net_device *dev,
1849 struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
1850{
1851 struct usbnet *usbdev = dev->priv;
1852 __le32 tmp;
1853 devdbg(usbdev, "SIOCSIWRTS");
1854
1855 tmp = cpu_to_le32(wrqu->rts.value);
1856 return rndis_set_oid(usbdev, OID_802_11_RTS_THRESHOLD, &tmp,
1857 sizeof(tmp));
1858}
1859
1860
1861static int rndis_iw_get_rts(struct net_device *dev,
1862 struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
1863{
1864 struct usbnet *usbdev = dev->priv;
1865 __le32 tmp;
1866 int len, ret;
1867
1868 len = sizeof(tmp);
1869 ret = rndis_query_oid(usbdev, OID_802_11_RTS_THRESHOLD, &tmp, &len);
1870 if (ret == 0) {
1871 wrqu->rts.value = le32_to_cpu(tmp);
1872 wrqu->rts.flags = 1;
1873 wrqu->rts.disabled = 0;
1874 }
1875
1876 devdbg(usbdev, "SIOCGIWRTS: %d", wrqu->rts.value);
1877
1878 return ret;
1879}
1880
1881
1882static int rndis_iw_set_frag(struct net_device *dev,
1883 struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
1884{
1885 struct usbnet *usbdev = dev->priv;
1886 __le32 tmp;
1887
1888 devdbg(usbdev, "SIOCSIWFRAG");
1889
1890 tmp = cpu_to_le32(wrqu->frag.value);
1891 return rndis_set_oid(usbdev, OID_802_11_FRAGMENTATION_THRESHOLD, &tmp,
1892 sizeof(tmp));
1893}
1894
1895
1896static int rndis_iw_get_frag(struct net_device *dev,
1897 struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
1898{
1899 struct usbnet *usbdev = dev->priv;
1900 __le32 tmp;
1901 int len, ret;
1902
1903 len = sizeof(tmp);
1904 ret = rndis_query_oid(usbdev, OID_802_11_FRAGMENTATION_THRESHOLD, &tmp,
1905 &len);
1906 if (ret == 0) {
1907 wrqu->frag.value = le32_to_cpu(tmp);
1908 wrqu->frag.flags = 1;
1909 wrqu->frag.disabled = 0;
1910 }
1911 devdbg(usbdev, "SIOCGIWFRAG: %d", wrqu->frag.value);
1912 return ret;
1913}
1914
1915
1916static int rndis_iw_set_nick(struct net_device *dev,
1917 struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
1918{
1919 struct usbnet *usbdev = dev->priv;
1920 struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
1921
1922 devdbg(usbdev, "SIOCSIWNICK");
1923
1924 priv->nick_len = wrqu->data.length;
1925 if (priv->nick_len > 32)
1926 priv->nick_len = 32;
1927
1928 memcpy(priv->nick, extra, priv->nick_len);
1929 return 0;
1930}
1931
1932
1933static int rndis_iw_get_nick(struct net_device *dev,
1934 struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
1935{
1936 struct usbnet *usbdev = dev->priv;
1937 struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
1938
1939 wrqu->data.flags = 1;
1940 wrqu->data.length = priv->nick_len;
1941 memcpy(extra, priv->nick, priv->nick_len);
1942
1943 devdbg(usbdev, "SIOCGIWNICK: '%s'", priv->nick);
1944
1945 return 0;
1946}
1947
1948
1949static int rndis_iw_set_freq(struct net_device *dev,
1950 struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
1951{
1952 struct usbnet *usbdev = dev->priv;
1953 struct NDIS_802_11_CONFIGURATION config;
1954 unsigned int dsconfig;
1955 int len, ret;
1956
1957 /* this OID is valid only when not associated */
1958 if (is_associated(usbdev))
1959 return 0;
1960
1961 dsconfig = 0;
1962 if (freq_to_dsconfig(&wrqu->freq, &dsconfig))
1963 return -EINVAL;
1964
1965 len = sizeof(config);
1966 ret = rndis_query_oid(usbdev, OID_802_11_CONFIGURATION, &config, &len);
1967 if (ret != 0) {
1968 devdbg(usbdev, "SIOCSIWFREQ: querying configuration failed");
1969 return 0;
1970 }
1971
1972 config.DSConfig = cpu_to_le32(dsconfig);
1973
1974 devdbg(usbdev, "SIOCSIWFREQ: %d * 10^%d", wrqu->freq.m, wrqu->freq.e);
1975 return rndis_set_oid(usbdev, OID_802_11_CONFIGURATION, &config,
1976 sizeof(config));
1977}
1978
1979
1980static int rndis_iw_get_freq(struct net_device *dev,
1981 struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
1982{
1983 struct usbnet *usbdev = dev->priv;
1984 struct NDIS_802_11_CONFIGURATION config;
1985 int len, ret;
1986
1987 len = sizeof(config);
1988 ret = rndis_query_oid(usbdev, OID_802_11_CONFIGURATION, &config, &len);
1989 if (ret == 0)
1990 dsconfig_to_freq(le32_to_cpu(config.DSConfig), &wrqu->freq);
1991
1992 devdbg(usbdev, "SIOCGIWFREQ: %d", wrqu->freq.m);
1993 return ret;
1994}
1995
1996
1997static int rndis_iw_get_txpower(struct net_device *dev,
1998 struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
1999{
2000 struct usbnet *usbdev = dev->priv;
2001 struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
2002 __le32 tx_power;
2003 int ret = 0, len;
2004
2005 if (priv->radio_on) {
2006 if (priv->caps & CAP_SUPPORT_TXPOWER) {
2007 len = sizeof(tx_power);
2008 ret = rndis_query_oid(usbdev, OID_802_11_TX_POWER_LEVEL,
2009 &tx_power, &len);
2010 if (ret != 0)
2011 return ret;
2012 } else
2013 /* fake incase not supported */
2014 tx_power = cpu_to_le32(get_bcm4320_power(priv));
2015
2016 wrqu->txpower.flags = IW_TXPOW_MWATT;
2017 wrqu->txpower.value = le32_to_cpu(tx_power);
2018 wrqu->txpower.disabled = 0;
2019 } else {
2020 wrqu->txpower.flags = IW_TXPOW_MWATT;
2021 wrqu->txpower.value = 0;
2022 wrqu->txpower.disabled = 1;
2023 }
2024
2025 devdbg(usbdev, "SIOCGIWTXPOW: %d", wrqu->txpower.value);
2026
2027 return ret;
2028}
2029
2030
2031static int rndis_iw_set_txpower(struct net_device *dev,
2032 struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
2033{
2034 struct usbnet *usbdev = dev->priv;
2035 struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
2036 __le32 tx_power = 0;
2037 int ret = 0;
2038
2039 if (!wrqu->txpower.disabled) {
2040 if (wrqu->txpower.flags == IW_TXPOW_MWATT)
2041 tx_power = cpu_to_le32(wrqu->txpower.value);
2042 else { /* wrqu->txpower.flags == IW_TXPOW_DBM */
2043 if (wrqu->txpower.value > 20)
2044 tx_power = cpu_to_le32(128);
2045 else if (wrqu->txpower.value < -43)
2046 tx_power = cpu_to_le32(127);
2047 else {
2048 signed char tmp;
2049 tmp = wrqu->txpower.value;
2050 tmp = -12 - tmp;
2051 tmp <<= 2;
2052 tx_power = cpu_to_le32((unsigned char)tmp);
2053 }
2054 }
2055 }
2056
2057 devdbg(usbdev, "SIOCSIWTXPOW: %d", le32_to_cpu(tx_power));
2058
2059 if (le32_to_cpu(tx_power) != 0) {
2060 if (priv->caps & CAP_SUPPORT_TXPOWER) {
2061 /* turn radio on first */
2062 if (!priv->radio_on)
2063 disassociate(usbdev, 1);
2064
2065 ret = rndis_set_oid(usbdev, OID_802_11_TX_POWER_LEVEL,
2066 &tx_power, sizeof(tx_power));
2067 if (ret != 0)
2068 ret = -EOPNOTSUPP;
2069 return ret;
2070 } else {
2071 /* txpower unsupported, just turn radio on */
2072 if (!priv->radio_on)
2073 return disassociate(usbdev, 1);
2074 return 0; /* all ready on */
2075 }
2076 }
2077
2078 /* tx_power == 0, turn off radio */
2079 return disassociate(usbdev, 0);
2080}
2081
2082
2083static int rndis_iw_get_rate(struct net_device *dev,
2084 struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
2085{
2086 struct usbnet *usbdev = dev->priv;
2087 __le32 tmp;
2088 int ret, len;
2089
2090 len = sizeof(tmp);
2091 ret = rndis_query_oid(usbdev, OID_GEN_LINK_SPEED, &tmp, &len);
2092 if (ret == 0) {
2093 wrqu->bitrate.value = le32_to_cpu(tmp) * 100;
2094 wrqu->bitrate.disabled = 0;
2095 wrqu->bitrate.flags = 1;
2096 }
2097 return ret;
2098}
2099
2100
2101static int rndis_iw_set_mlme(struct net_device *dev,
2102 struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
2103{
2104 struct usbnet *usbdev = dev->priv;
2105 struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
2106 struct iw_mlme *mlme = (struct iw_mlme *)extra;
2107 unsigned char bssid[ETH_ALEN];
2108
2109 get_bssid(usbdev, bssid);
2110
2111 if (memcmp(bssid, mlme->addr.sa_data, ETH_ALEN))
2112 return -EINVAL;
2113
2114 switch (mlme->cmd) {
2115 case IW_MLME_DEAUTH:
2116 return deauthenticate(usbdev);
2117 case IW_MLME_DISASSOC:
2118 return disassociate(usbdev, priv->radio_on);
2119 default:
2120 return -EOPNOTSUPP;
2121 }
2122
2123 return 0;
2124}
2125
2126
2127static struct iw_statistics *rndis_get_wireless_stats(struct net_device *dev)
2128{
2129 struct usbnet *usbdev = dev->priv;
2130 struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
2131 unsigned long flags;
2132
2133 spin_lock_irqsave(&priv->stats_lock, flags);
2134 memcpy(&priv->iwstats, &priv->privstats, sizeof(priv->iwstats));
2135 spin_unlock_irqrestore(&priv->stats_lock, flags);
2136
2137 return &priv->iwstats;
2138}
2139
2140
2141#define IW_IOCTL(x) [(x) - SIOCSIWCOMMIT]
2142static const iw_handler rndis_iw_handler[] =
2143{
2144 IW_IOCTL(SIOCSIWCOMMIT) = rndis_iw_commit,
2145 IW_IOCTL(SIOCGIWNAME) = rndis_iw_get_name,
2146 IW_IOCTL(SIOCSIWFREQ) = rndis_iw_set_freq,
2147 IW_IOCTL(SIOCGIWFREQ) = rndis_iw_get_freq,
2148 IW_IOCTL(SIOCSIWMODE) = rndis_iw_set_mode,
2149 IW_IOCTL(SIOCGIWMODE) = rndis_iw_get_mode,
2150 IW_IOCTL(SIOCGIWRANGE) = rndis_iw_get_range,
2151 IW_IOCTL(SIOCSIWAP) = rndis_iw_set_bssid,
2152 IW_IOCTL(SIOCGIWAP) = rndis_iw_get_bssid,
2153 IW_IOCTL(SIOCSIWSCAN) = rndis_iw_set_scan,
2154 IW_IOCTL(SIOCGIWSCAN) = rndis_iw_get_scan,
2155 IW_IOCTL(SIOCSIWESSID) = rndis_iw_set_essid,
2156 IW_IOCTL(SIOCGIWESSID) = rndis_iw_get_essid,
2157 IW_IOCTL(SIOCSIWNICKN) = rndis_iw_set_nick,
2158 IW_IOCTL(SIOCGIWNICKN) = rndis_iw_get_nick,
2159 IW_IOCTL(SIOCGIWRATE) = rndis_iw_get_rate,
2160 IW_IOCTL(SIOCSIWRTS) = rndis_iw_set_rts,
2161 IW_IOCTL(SIOCGIWRTS) = rndis_iw_get_rts,
2162 IW_IOCTL(SIOCSIWFRAG) = rndis_iw_set_frag,
2163 IW_IOCTL(SIOCGIWFRAG) = rndis_iw_get_frag,
2164 IW_IOCTL(SIOCSIWTXPOW) = rndis_iw_set_txpower,
2165 IW_IOCTL(SIOCGIWTXPOW) = rndis_iw_get_txpower,
2166 IW_IOCTL(SIOCSIWENCODE) = rndis_iw_set_encode,
2167 IW_IOCTL(SIOCSIWENCODEEXT) = rndis_iw_set_encode_ext,
2168 IW_IOCTL(SIOCSIWAUTH) = rndis_iw_set_auth,
2169 IW_IOCTL(SIOCGIWAUTH) = rndis_iw_get_auth,
2170 IW_IOCTL(SIOCSIWGENIE) = rndis_iw_set_genie,
2171 IW_IOCTL(SIOCGIWGENIE) = rndis_iw_get_genie,
2172 IW_IOCTL(SIOCSIWMLME) = rndis_iw_set_mlme,
2173};
2174
2175static const iw_handler rndis_wext_private_handler[] = {
2176};
2177
2178static const struct iw_priv_args rndis_wext_private_args[] = {
2179};
2180
2181
2182static const struct iw_handler_def rndis_iw_handlers = {
2183 .num_standard = ARRAY_SIZE(rndis_iw_handler),
2184 .num_private = ARRAY_SIZE(rndis_wext_private_handler),
2185 .num_private_args = ARRAY_SIZE(rndis_wext_private_args),
2186 .standard = (iw_handler *)rndis_iw_handler,
2187 .private = (iw_handler *)rndis_wext_private_handler,
2188 .private_args = (struct iw_priv_args *)rndis_wext_private_args,
2189 .get_wireless_stats = rndis_get_wireless_stats,
2190};
2191
2192
2193static void rndis_wext_worker(struct work_struct *work)
2194{
2195 struct rndis_wext_private *priv =
2196 container_of(work, struct rndis_wext_private, work);
2197 struct usbnet *usbdev = priv->usbdev;
2198 union iwreq_data evt;
2199 unsigned char bssid[ETH_ALEN];
2200 int ret;
2201
2202 if (test_and_clear_bit(WORK_CONNECTION_EVENT, &priv->work_pending)) {
2203 ret = get_bssid(usbdev, bssid);
2204
2205 if (!ret) {
2206 evt.data.flags = 0;
2207 evt.data.length = 0;
2208 memcpy(evt.ap_addr.sa_data, bssid, ETH_ALEN);
2209 wireless_send_event(usbdev->net, SIOCGIWAP, &evt, NULL);
2210 }
2211 }
2212
2213 if (test_and_clear_bit(WORK_SET_MULTICAST_LIST, &priv->work_pending))
2214 set_multicast_list(usbdev);
2215}
2216
2217static void rndis_wext_set_multicast_list(struct net_device *dev)
2218{
2219 struct usbnet *usbdev = dev->priv;
2220 struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
2221
2222 set_bit(WORK_SET_MULTICAST_LIST, &priv->work_pending);
2223 queue_work(priv->workqueue, &priv->work);
2224}
2225
2226static void rndis_wext_link_change(struct usbnet *dev, int state)
2227{
2228 struct rndis_wext_private *priv = get_rndis_wext_priv(dev);
2229 union iwreq_data evt;
2230
2231 if (state) {
2232 /* queue work to avoid recursive calls into rndis_command */
2233 set_bit(WORK_CONNECTION_EVENT, &priv->work_pending);
2234 queue_work(priv->workqueue, &priv->work);
2235 } else {
2236 evt.data.flags = 0;
2237 evt.data.length = 0;
2238 memset(evt.ap_addr.sa_data, 0, ETH_ALEN);
2239 wireless_send_event(dev->net, SIOCGIWAP, &evt, NULL);
2240 }
2241}
2242
2243
2244static int rndis_wext_get_caps(struct usbnet *dev)
2245{
2246 struct {
2247 __le32 num_items;
2248 __le32 items[8];
2249 } networks_supported;
2250 int len, retval, i, n;
2251 __le32 tx_power;
2252 struct rndis_wext_private *priv = get_rndis_wext_priv(dev);
2253
2254 /* determine if supports setting txpower */
2255 len = sizeof(tx_power);
2256 retval = rndis_query_oid(dev, OID_802_11_TX_POWER_LEVEL, &tx_power,
2257 &len);
2258 if (retval == 0 && le32_to_cpu(tx_power) != 0xFF)
2259 priv->caps |= CAP_SUPPORT_TXPOWER;
2260
2261 /* determine supported modes */
2262 len = sizeof(networks_supported);
2263 retval = rndis_query_oid(dev, OID_802_11_NETWORK_TYPES_SUPPORTED,
2264 &networks_supported, &len);
2265 if (retval >= 0) {
2266 n = le32_to_cpu(networks_supported.num_items);
2267 if (n > 8)
2268 n = 8;
2269 for (i = 0; i < n; i++) {
2270 switch (le32_to_cpu(networks_supported.items[i])) {
2271 case Ndis802_11FH:
2272 case Ndis802_11DS:
2273 priv->caps |= CAP_MODE_80211B;
2274 break;
2275 case Ndis802_11OFDM5:
2276 priv->caps |= CAP_MODE_80211A;
2277 break;
2278 case Ndis802_11OFDM24:
2279 priv->caps |= CAP_MODE_80211G;
2280 break;
2281 }
2282 }
2283 if (priv->caps & CAP_MODE_80211A)
2284 strcat(priv->name, "a");
2285 if (priv->caps & CAP_MODE_80211B)
2286 strcat(priv->name, "b");
2287 if (priv->caps & CAP_MODE_80211G)
2288 strcat(priv->name, "g");
2289 }
2290
2291 return retval;
2292}
2293
2294
2295#define STATS_UPDATE_JIFFIES (HZ)
2296static void rndis_update_wireless_stats(struct work_struct *work)
2297{
2298 struct rndis_wext_private *priv =
2299 container_of(work, struct rndis_wext_private, stats_work.work);
2300 struct usbnet *usbdev = priv->usbdev;
2301 struct iw_statistics iwstats;
2302 __le32 rssi, tmp;
2303 int len, ret, bitrate, j;
2304 unsigned long flags;
2305 int update_jiffies = STATS_UPDATE_JIFFIES;
2306 void *buf;
2307
2308 spin_lock_irqsave(&priv->stats_lock, flags);
2309 memcpy(&iwstats, &priv->privstats, sizeof(iwstats));
2310 spin_unlock_irqrestore(&priv->stats_lock, flags);
2311
2312 /* only update stats when connected */
2313 if (!is_associated(usbdev)) {
2314 iwstats.qual.qual = 0;
2315 iwstats.qual.level = 0;
2316 iwstats.qual.updated = IW_QUAL_QUAL_UPDATED
2317 | IW_QUAL_LEVEL_UPDATED
2318 | IW_QUAL_NOISE_INVALID
2319 | IW_QUAL_QUAL_INVALID
2320 | IW_QUAL_LEVEL_INVALID;
2321 goto end;
2322 }
2323
2324 len = sizeof(rssi);
2325 ret = rndis_query_oid(usbdev, OID_802_11_RSSI, &rssi, &len);
2326
2327 devdbg(usbdev, "stats: OID_802_11_RSSI -> %d, rssi:%d", ret,
2328 le32_to_cpu(rssi));
2329 if (ret == 0) {
2330 memset(&iwstats.qual, 0, sizeof(iwstats.qual));
2331 iwstats.qual.qual = level_to_qual(le32_to_cpu(rssi));
2332 iwstats.qual.level = le32_to_cpu(rssi);
2333 iwstats.qual.updated = IW_QUAL_QUAL_UPDATED
2334 | IW_QUAL_LEVEL_UPDATED
2335 | IW_QUAL_NOISE_INVALID;
2336 }
2337
2338 memset(&iwstats.discard, 0, sizeof(iwstats.discard));
2339
2340 len = sizeof(tmp);
2341 ret = rndis_query_oid(usbdev, OID_GEN_XMIT_ERROR, &tmp, &len);
2342 if (ret == 0)
2343 iwstats.discard.misc += le32_to_cpu(tmp);
2344
2345 len = sizeof(tmp);
2346 ret = rndis_query_oid(usbdev, OID_GEN_RCV_ERROR, &tmp, &len);
2347 if (ret == 0)
2348 iwstats.discard.misc += le32_to_cpu(tmp);
2349
2350 len = sizeof(tmp);
2351 ret = rndis_query_oid(usbdev, OID_GEN_RCV_NO_BUFFER, &tmp, &len);
2352 if (ret == 0)
2353 iwstats.discard.misc += le32_to_cpu(tmp);
2354
2355 /* Workaround transfer stalls on poor quality links. */
2356 len = sizeof(tmp);
2357 ret = rndis_query_oid(usbdev, OID_GEN_LINK_SPEED, &tmp, &len);
2358 if (ret == 0) {
2359 bitrate = le32_to_cpu(tmp) * 100;
2360 if (bitrate > 11000000)
2361 goto end;
2362
2363 /* Decrease stats worker interval to catch stalls.
2364 * faster. Faster than 400-500ms causes packet loss,
2365 * Slower doesn't catch stalls fast enough.
2366 */
2367 j = msecs_to_jiffies(priv->param_workaround_interval);
2368 if (j > STATS_UPDATE_JIFFIES)
2369 j = STATS_UPDATE_JIFFIES;
2370 else if (j <= 0)
2371 j = 1;
2372 update_jiffies = j;
2373
2374 /* Send scan OID. Use of both OIDs is required to get device
2375 * working.
2376 */
2377 tmp = ccpu2(1);
2378 rndis_set_oid(usbdev, OID_802_11_BSSID_LIST_SCAN, &tmp,
2379 sizeof(tmp));
2380
2381 len = CONTROL_BUFFER_SIZE;
2382 buf = kmalloc(len, GFP_KERNEL);
2383 if (!buf)
2384 goto end;
2385
2386 rndis_query_oid(usbdev, OID_802_11_BSSID_LIST, buf, &len);
2387 kfree(buf);
2388 }
2389end:
2390 spin_lock_irqsave(&priv->stats_lock, flags);
2391 memcpy(&priv->privstats, &iwstats, sizeof(iwstats));
2392 spin_unlock_irqrestore(&priv->stats_lock, flags);
2393
2394 if (update_jiffies >= HZ)
2395 update_jiffies = round_jiffies_relative(update_jiffies);
2396 else {
2397 j = round_jiffies_relative(update_jiffies);
2398 if (abs(j - update_jiffies) <= 10)
2399 update_jiffies = j;
2400 }
2401
2402 queue_delayed_work(priv->workqueue, &priv->stats_work, update_jiffies);
2403}
2404
2405
2406static int bcm4320_early_init(struct usbnet *dev)
2407{
2408 struct rndis_wext_private *priv = get_rndis_wext_priv(dev);
2409 char buf[8];
2410
2411 /* Early initialization settings, setting these won't have effect
2412 * if called after generic_rndis_bind().
2413 */
2414
2415 priv->param_country[0] = modparam_country[0];
2416 priv->param_country[1] = modparam_country[1];
2417 priv->param_country[2] = 0;
2418 priv->param_frameburst = modparam_frameburst;
2419 priv->param_afterburner = modparam_afterburner;
2420 priv->param_power_save = modparam_power_save;
2421 priv->param_power_output = modparam_power_output;
2422 priv->param_roamtrigger = modparam_roamtrigger;
2423 priv->param_roamdelta = modparam_roamdelta;
2424 priv->param_workaround_interval = modparam_workaround_interval;
2425
2426 priv->param_country[0] = toupper(priv->param_country[0]);
2427 priv->param_country[1] = toupper(priv->param_country[1]);
2428 /* doesn't support EU as country code, use FI instead */
2429 if (!strcmp(priv->param_country, "EU"))
2430 strcpy(priv->param_country, "FI");
2431
2432 if (priv->param_power_save < 0)
2433 priv->param_power_save = 0;
2434 else if (priv->param_power_save > 2)
2435 priv->param_power_save = 2;
2436
2437 if (priv->param_roamtrigger < -80)
2438 priv->param_roamtrigger = -80;
2439 else if (priv->param_roamtrigger > -60)
2440 priv->param_roamtrigger = -60;
2441
2442 if (priv->param_roamdelta < 0)
2443 priv->param_roamdelta = 0;
2444 else if (priv->param_roamdelta > 2)
2445 priv->param_roamdelta = 2;
2446
2447 if (priv->param_workaround_interval < 0)
2448 priv->param_workaround_interval = 500;
2449
2450 rndis_set_config_parameter_str(dev, "Country", priv->param_country);
2451 rndis_set_config_parameter_str(dev, "FrameBursting",
2452 priv->param_frameburst ? "1" : "0");
2453 rndis_set_config_parameter_str(dev, "Afterburner",
2454 priv->param_afterburner ? "1" : "0");
2455 sprintf(buf, "%d", priv->param_power_save);
2456 rndis_set_config_parameter_str(dev, "PowerSaveMode", buf);
2457 sprintf(buf, "%d", priv->param_power_output);
2458 rndis_set_config_parameter_str(dev, "PwrOut", buf);
2459 sprintf(buf, "%d", priv->param_roamtrigger);
2460 rndis_set_config_parameter_str(dev, "RoamTrigger", buf);
2461 sprintf(buf, "%d", priv->param_roamdelta);
2462 rndis_set_config_parameter_str(dev, "RoamDelta", buf);
2463
2464 return 0;
2465}
2466
2467
2468static int rndis_wext_bind(struct usbnet *dev, struct usb_interface *intf)
2469{
2470 struct net_device *net = dev->net;
2471 struct rndis_wext_private *priv;
2472 int retval, len;
2473 __le32 tmp;
2474
2475 /* allocate rndis private data */
2476 priv = kmalloc(sizeof(struct rndis_wext_private), GFP_KERNEL);
2477 if (!priv)
2478 return -ENOMEM;
2479
2480 /* These have to be initialized before calling generic_rndis_bind().
2481 * Otherwise we'll be in big trouble in rndis_wext_early_init().
2482 */
2483 dev->driver_priv = priv;
2484 memset(priv, 0, sizeof(*priv));
2485 memset(priv->name, 0, sizeof(priv->name));
2486 strcpy(priv->name, "IEEE802.11");
2487 net->wireless_handlers = &rndis_iw_handlers;
2488 priv->usbdev = dev;
2489
2490 mutex_init(&priv->command_lock);
2491 spin_lock_init(&priv->stats_lock);
2492
2493 /* try bind rndis_host */
2494 retval = generic_rndis_bind(dev, intf, FLAG_RNDIS_PHYM_WIRELESS);
2495 if (retval < 0)
2496 goto fail;
2497
2498 /* generic_rndis_bind set packet filter to multicast_all+
2499 * promisc mode which doesn't work well for our devices (device
2500 * picks up rssi to closest station instead of to access point).
2501 *
2502 * rndis_host wants to avoid all OID as much as possible
2503 * so do promisc/multicast handling in rndis_wext.
2504 */
2505 dev->net->set_multicast_list = rndis_wext_set_multicast_list;
2506 tmp = RNDIS_PACKET_TYPE_DIRECTED | RNDIS_PACKET_TYPE_BROADCAST;
2507 retval = rndis_set_oid(dev, OID_GEN_CURRENT_PACKET_FILTER, &tmp,
2508 sizeof(tmp));
2509
2510 len = sizeof(tmp);
2511 retval = rndis_query_oid(dev, OID_802_3_MAXIMUM_LIST_SIZE, &tmp, &len);
2512 priv->multicast_size = le32_to_cpu(tmp);
2513 if (retval < 0 || priv->multicast_size < 0)
2514 priv->multicast_size = 0;
2515 if (priv->multicast_size > 0)
2516 dev->net->flags |= IFF_MULTICAST;
2517 else
2518 dev->net->flags &= ~IFF_MULTICAST;
2519
2520 priv->iwstats.qual.qual = 0;
2521 priv->iwstats.qual.level = 0;
2522 priv->iwstats.qual.updated = IW_QUAL_QUAL_UPDATED
2523 | IW_QUAL_LEVEL_UPDATED
2524 | IW_QUAL_NOISE_INVALID
2525 | IW_QUAL_QUAL_INVALID
2526 | IW_QUAL_LEVEL_INVALID;
2527
2528 rndis_wext_get_caps(dev);
2529 set_default_iw_params(dev);
2530
2531 /* turn radio on */
2532 priv->radio_on = 1;
2533 disassociate(dev, 1);
2534
2535 /* because rndis_command() sleeps we need to use workqueue */
2536 priv->workqueue = create_singlethread_workqueue("rndis_wlan");
2537 INIT_DELAYED_WORK(&priv->stats_work, rndis_update_wireless_stats);
2538 queue_delayed_work(priv->workqueue, &priv->stats_work,
2539 round_jiffies_relative(STATS_UPDATE_JIFFIES));
2540 INIT_WORK(&priv->work, rndis_wext_worker);
2541
2542 return 0;
2543
2544fail:
2545 kfree(priv);
2546 return retval;
2547}
2548
2549
2550static void rndis_wext_unbind(struct usbnet *dev, struct usb_interface *intf)
2551{
2552 struct rndis_wext_private *priv = get_rndis_wext_priv(dev);
2553
2554 /* turn radio off */
2555 disassociate(dev, 0);
2556
2557 cancel_delayed_work_sync(&priv->stats_work);
2558 cancel_work_sync(&priv->work);
2559 flush_workqueue(priv->workqueue);
2560 destroy_workqueue(priv->workqueue);
2561
2562 if (priv && priv->wpa_ie_len)
2563 kfree(priv->wpa_ie);
2564 kfree(priv);
2565
2566 rndis_unbind(dev, intf);
2567}
2568
2569
2570static int rndis_wext_reset(struct usbnet *dev)
2571{
2572 return deauthenticate(dev);
2573}
2574
2575
2576static const struct driver_info bcm4320b_info = {
2577 .description = "Wireless RNDIS device, BCM4320b based",
2578 .flags = FLAG_WLAN | FLAG_FRAMING_RN | FLAG_NO_SETINT,
2579 .bind = rndis_wext_bind,
2580 .unbind = rndis_wext_unbind,
2581 .status = rndis_status,
2582 .rx_fixup = rndis_rx_fixup,
2583 .tx_fixup = rndis_tx_fixup,
2584 .reset = rndis_wext_reset,
2585 .early_init = bcm4320_early_init,
2586 .link_change = rndis_wext_link_change,
2587};
2588
2589static const struct driver_info bcm4320a_info = {
2590 .description = "Wireless RNDIS device, BCM4320a based",
2591 .flags = FLAG_WLAN | FLAG_FRAMING_RN | FLAG_NO_SETINT,
2592 .bind = rndis_wext_bind,
2593 .unbind = rndis_wext_unbind,
2594 .status = rndis_status,
2595 .rx_fixup = rndis_rx_fixup,
2596 .tx_fixup = rndis_tx_fixup,
2597 .reset = rndis_wext_reset,
2598 .early_init = bcm4320_early_init,
2599 .link_change = rndis_wext_link_change,
2600};
2601
2602static const struct driver_info rndis_wext_info = {
2603 .description = "Wireless RNDIS device",
2604 .flags = FLAG_WLAN | FLAG_FRAMING_RN | FLAG_NO_SETINT,
2605 .bind = rndis_wext_bind,
2606 .unbind = rndis_wext_unbind,
2607 .status = rndis_status,
2608 .rx_fixup = rndis_rx_fixup,
2609 .tx_fixup = rndis_tx_fixup,
2610 .reset = rndis_wext_reset,
2611 .early_init = bcm4320_early_init,
2612 .link_change = rndis_wext_link_change,
2613};
2614
2615/*-------------------------------------------------------------------------*/
2616
2617static const struct usb_device_id products [] = {
2618#define RNDIS_MASTER_INTERFACE \
2619 .bInterfaceClass = USB_CLASS_COMM, \
2620 .bInterfaceSubClass = 2 /* ACM */, \
2621 .bInterfaceProtocol = 0x0ff
2622
2623/* INF driver for these devices have DriverVer >= 4.xx.xx.xx and many custom
2624 * parameters available. Chipset marked as 'BCM4320SKFBG' in NDISwrapper-wiki.
2625 */
2626{
2627 .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
2628 | USB_DEVICE_ID_MATCH_DEVICE,
2629 .idVendor = 0x0411,
2630 .idProduct = 0x00bc, /* Buffalo WLI-U2-KG125S */
2631 RNDIS_MASTER_INTERFACE,
2632 .driver_info = (unsigned long) &bcm4320b_info,
2633}, {
2634 .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
2635 | USB_DEVICE_ID_MATCH_DEVICE,
2636 .idVendor = 0x0baf,
2637 .idProduct = 0x011b, /* U.S. Robotics USR5421 */
2638 RNDIS_MASTER_INTERFACE,
2639 .driver_info = (unsigned long) &bcm4320b_info,
2640}, {
2641 .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
2642 | USB_DEVICE_ID_MATCH_DEVICE,
2643 .idVendor = 0x050d,
2644 .idProduct = 0x011b, /* Belkin F5D7051 */
2645 RNDIS_MASTER_INTERFACE,
2646 .driver_info = (unsigned long) &bcm4320b_info,
2647}, {
2648 .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
2649 | USB_DEVICE_ID_MATCH_DEVICE,
2650 .idVendor = 0x1799, /* Belkin has two vendor ids */
2651 .idProduct = 0x011b, /* Belkin F5D7051 */
2652 RNDIS_MASTER_INTERFACE,
2653 .driver_info = (unsigned long) &bcm4320b_info,
2654}, {
2655 .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
2656 | USB_DEVICE_ID_MATCH_DEVICE,
2657 .idVendor = 0x13b1,
2658 .idProduct = 0x0014, /* Linksys WUSB54GSv2 */
2659 RNDIS_MASTER_INTERFACE,
2660 .driver_info = (unsigned long) &bcm4320b_info,
2661}, {
2662 .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
2663 | USB_DEVICE_ID_MATCH_DEVICE,
2664 .idVendor = 0x13b1,
2665 .idProduct = 0x0026, /* Linksys WUSB54GSC */
2666 RNDIS_MASTER_INTERFACE,
2667 .driver_info = (unsigned long) &bcm4320b_info,
2668}, {
2669 .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
2670 | USB_DEVICE_ID_MATCH_DEVICE,
2671 .idVendor = 0x0b05,
2672 .idProduct = 0x1717, /* Asus WL169gE */
2673 RNDIS_MASTER_INTERFACE,
2674 .driver_info = (unsigned long) &bcm4320b_info,
2675}, {
2676 .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
2677 | USB_DEVICE_ID_MATCH_DEVICE,
2678 .idVendor = 0x0a5c,
2679 .idProduct = 0xd11b, /* Eminent EM4045 */
2680 RNDIS_MASTER_INTERFACE,
2681 .driver_info = (unsigned long) &bcm4320b_info,
2682}, {
2683 .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
2684 | USB_DEVICE_ID_MATCH_DEVICE,
2685 .idVendor = 0x1690,
2686 .idProduct = 0x0715, /* BT Voyager 1055 */
2687 RNDIS_MASTER_INTERFACE,
2688 .driver_info = (unsigned long) &bcm4320b_info,
2689},
2690/* These devices have DriverVer < 4.xx.xx.xx and do not have any custom
2691 * parameters available, hardware probably contain older firmware version with
2692 * no way of updating. Chipset marked as 'BCM4320????' in NDISwrapper-wiki.
2693 */
2694{
2695 .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
2696 | USB_DEVICE_ID_MATCH_DEVICE,
2697 .idVendor = 0x13b1,
2698 .idProduct = 0x000e, /* Linksys WUSB54GSv1 */
2699 RNDIS_MASTER_INTERFACE,
2700 .driver_info = (unsigned long) &bcm4320a_info,
2701}, {
2702 .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
2703 | USB_DEVICE_ID_MATCH_DEVICE,
2704 .idVendor = 0x0baf,
2705 .idProduct = 0x0111, /* U.S. Robotics USR5420 */
2706 RNDIS_MASTER_INTERFACE,
2707 .driver_info = (unsigned long) &bcm4320a_info,
2708}, {
2709 .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
2710 | USB_DEVICE_ID_MATCH_DEVICE,
2711 .idVendor = 0x0411,
2712 .idProduct = 0x004b, /* BUFFALO WLI-USB-G54 */
2713 RNDIS_MASTER_INTERFACE,
2714 .driver_info = (unsigned long) &bcm4320a_info,
2715},
2716/* Generic Wireless RNDIS devices that we don't have exact
2717 * idVendor/idProduct/chip yet.
2718 */
2719{
2720 /* RNDIS is MSFT's un-official variant of CDC ACM */
2721 USB_INTERFACE_INFO(USB_CLASS_COMM, 2 /* ACM */, 0x0ff),
2722 .driver_info = (unsigned long) &rndis_wext_info,
2723}, {
2724 /* "ActiveSync" is an undocumented variant of RNDIS, used in WM5 */
2725 USB_INTERFACE_INFO(USB_CLASS_MISC, 1, 1),
2726 .driver_info = (unsigned long) &rndis_wext_info,
2727},
2728 { }, // END
2729};
2730MODULE_DEVICE_TABLE(usb, products);
2731
2732static struct usb_driver rndis_wlan_driver = {
2733 .name = "rndis_wlan",
2734 .id_table = products,
2735 .probe = usbnet_probe,
2736 .disconnect = usbnet_disconnect,
2737 .suspend = usbnet_suspend,
2738 .resume = usbnet_resume,
2739};
2740
2741static int __init rndis_wlan_init(void)
2742{
2743 return usb_register(&rndis_wlan_driver);
2744}
2745module_init(rndis_wlan_init);
2746
2747static void __exit rndis_wlan_exit(void)
2748{
2749 usb_deregister(&rndis_wlan_driver);
2750}
2751module_exit(rndis_wlan_exit);
2752
2753MODULE_AUTHOR("Bjorge Dijkstra");
2754MODULE_AUTHOR("Jussi Kivilinna");
2755MODULE_DESCRIPTION("Driver for RNDIS based USB Wireless adapters");
2756MODULE_LICENSE("GPL");
2757
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index ab52f221cd71..b31f0c26c32b 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -1736,7 +1736,8 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev)
1736 WARNING(rt2x00dev, 1736 WARNING(rt2x00dev,
1737 "TX status report missed for entry %p\n", 1737 "TX status report missed for entry %p\n",
1738 entry_done); 1738 entry_done);
1739 rt2x00lib_txdone(entry_done, TX_FAIL_OTHER, 0); 1739 rt2x00pci_txdone(rt2x00dev, entry_done, TX_FAIL_OTHER,
1740 0);
1740 entry_done = rt2x00_get_data_entry_done(ring); 1741 entry_done = rt2x00_get_data_entry_done(ring);
1741 } 1742 }
1742 1743
diff --git a/drivers/net/wireless/rtl8180_dev.c b/drivers/net/wireless/rtl8180_dev.c
index 07f37b0ccf91..27ebd689aa21 100644
--- a/drivers/net/wireless/rtl8180_dev.c
+++ b/drivers/net/wireless/rtl8180_dev.c
@@ -36,6 +36,7 @@ MODULE_LICENSE("GPL");
36static struct pci_device_id rtl8180_table[] __devinitdata = { 36static struct pci_device_id rtl8180_table[] __devinitdata = {
37 /* rtl8185 */ 37 /* rtl8185 */
38 { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8185) }, 38 { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8185) },
39 { PCI_DEVICE(PCI_VENDOR_ID_BELKIN, 0x700f) },
39 { PCI_DEVICE(PCI_VENDOR_ID_BELKIN, 0x701f) }, 40 { PCI_DEVICE(PCI_VENDOR_ID_BELKIN, 0x701f) },
40 41
41 /* rtl8180 */ 42 /* rtl8180 */