aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--MAINTAINERS27
-rw-r--r--drivers/net/wireless/Kconfig23
-rw-r--r--drivers/net/wireless/airo.c52
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx.h174
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c80
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_debugfs.h1
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_dma.c583
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_dma.h296
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_leds.c10
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_main.c840
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_main.h3
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_phy.c33
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_pio.c4
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c104
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_wx.c166
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_xmit.c5
-rw-r--r--drivers/net/wireless/ipw2100.c5
-rw-r--r--drivers/net/wireless/ipw2200.c244
-rw-r--r--drivers/net/wireless/ipw2200.h51
-rw-r--r--drivers/net/wireless/orinoco.c1
-rw-r--r--drivers/net/wireless/orinoco.h8
-rw-r--r--drivers/net/wireless/prism54/isl_ioctl.c573
-rw-r--r--drivers/net/wireless/prism54/isl_ioctl.h6
-rw-r--r--drivers/net/wireless/prism54/islpci_dev.c4
-rw-r--r--drivers/net/wireless/prism54/islpci_dev.h2
-rw-r--r--drivers/net/wireless/ray_cs.c2
-rw-r--r--drivers/net/wireless/zd1211rw/Makefile1
-rw-r--r--drivers/net/wireless/zd1211rw/zd_chip.c62
-rw-r--r--drivers/net/wireless/zd1211rw/zd_chip.h15
-rw-r--r--drivers/net/wireless/zd1211rw/zd_def.h6
-rw-r--r--drivers/net/wireless/zd1211rw/zd_mac.c6
-rw-r--r--drivers/net/wireless/zd1211rw/zd_mac.h2
-rw-r--r--drivers/net/wireless/zd1211rw/zd_netdev.c17
-rw-r--r--drivers/net/wireless/zd1211rw/zd_rf.c7
-rw-r--r--drivers/net/wireless/zd1211rw/zd_rf.h1
-rw-r--r--drivers/net/wireless/zd1211rw/zd_rf_al2230.c155
-rw-r--r--drivers/net/wireless/zd1211rw/zd_rf_al7230b.c274
-rw-r--r--drivers/net/wireless/zd1211rw/zd_usb.c122
-rw-r--r--drivers/net/wireless/zd1211rw/zd_usb.h1
-rw-r--r--include/net/ieee80211.h9
-rw-r--r--include/net/ieee80211softmac.h60
-rw-r--r--net/ieee80211/ieee80211_crypt_ccmp.c23
-rw-r--r--net/ieee80211/ieee80211_crypt_tkip.c108
-rw-r--r--net/ieee80211/ieee80211_crypt_wep.c35
-rw-r--r--net/ieee80211/ieee80211_rx.c56
-rw-r--r--net/ieee80211/ieee80211_tx.c9
-rw-r--r--net/ieee80211/softmac/ieee80211softmac_assoc.c21
-rw-r--r--net/ieee80211/softmac/ieee80211softmac_io.c14
-rw-r--r--net/ieee80211/softmac/ieee80211softmac_module.c90
-rw-r--r--net/ieee80211/softmac/ieee80211softmac_priv.h8
50 files changed, 3141 insertions, 1258 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 25cd7073a20b..c04c25ea3141 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -449,9 +449,9 @@ L: linux-hams@vger.kernel.org
449W: http://www.baycom.org/~tom/ham/ham.html 449W: http://www.baycom.org/~tom/ham/ham.html
450S: Maintained 450S: Maintained
451 451
452BCM43XX WIRELESS DRIVER 452BCM43XX WIRELESS DRIVER (SOFTMAC BASED VERSION)
453P: Michael Buesch 453P: Larry Finger
454M: mb@bu3sch.de 454M: Larry.Finger@lwfinger.net
455P: Stefano Brivio 455P: Stefano Brivio
456M: st3@riseup.net 456M: st3@riseup.net
457W: http://bcm43xx.berlios.de/ 457W: http://bcm43xx.berlios.de/
@@ -2616,6 +2616,18 @@ P: Nicolas Pitre
2616M: nico@cam.org 2616M: nico@cam.org
2617S: Maintained 2617S: Maintained
2618 2618
2619SOFTMAC LAYER (IEEE 802.11)
2620P: Johannes Berg
2621M: johannes@sipsolutions.net
2622P: Joe Jezak
2623M: josejx@gentoo.org
2624P: Daniel Drake
2625M: dsd@gentoo.org
2626W: http://softmac.sipsolutions.net/
2627L: softmac-dev@sipsolutions.net
2628L: netdev@vger.kernel.org
2629S: Maintained
2630
2619SOFTWARE RAID (Multiple Disks) SUPPORT 2631SOFTWARE RAID (Multiple Disks) SUPPORT
2620P: Ingo Molnar 2632P: Ingo Molnar
2621M: mingo@redhat.com 2633M: mingo@redhat.com
@@ -3341,6 +3353,15 @@ W: http://www.qsl.net/dl1bke/
3341L: linux-hams@vger.kernel.org 3353L: linux-hams@vger.kernel.org
3342S: Maintained 3354S: Maintained
3343 3355
3356ZD1211RW WIRELESS DRIVER
3357P: Daniel Drake
3358M: dsd@gentoo.org
3359P: Ulrich Kunitz
3360M: kune@deine-taler.de
3361W: http://zd1211.ath.cx/wiki/DriverRewrite
3362L: zd1211-devs@lists.sourceforge.net (subscribers-only)
3363S: Maintained
3364
3344ZF MACHZ WATCHDOG 3365ZF MACHZ WATCHDOG
3345P: Fernando Fuganti 3366P: Fernando Fuganti
3346M: fuganti@netbank.com.br 3367M: fuganti@netbank.com.br
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index 2e8ac995d56f..bd4a68c85a47 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -271,25 +271,14 @@ config IPW2200_DEBUG
271 bool "Enable full debugging output in IPW2200 module." 271 bool "Enable full debugging output in IPW2200 module."
272 depends on IPW2200 272 depends on IPW2200
273 ---help--- 273 ---help---
274 This option will enable debug tracing output for the IPW2200. 274 This option will enable low level debug tracing output for IPW2200.
275 275
276 This will result in the kernel module being ~100k larger. You can 276 Note, normal debug code is already compiled in. This low level
277 control which debug output is sent to the kernel log by setting the 277 debug option enables debug on hot paths (e.g Tx, Rx, ISR) and
278 value in 278 will result in the kernel module being ~70 larger. Most users
279 279 will typically not need this high verbosity debug information.
280 /sys/bus/pci/drivers/ipw2200/debug_level
281
282 This entry will only exist if this option is enabled.
283 280
284 To set a value, simply echo an 8-byte hex value to the same file: 281 If you are not sure, say N here.
285
286 % echo 0x00000FFO > /sys/bus/pci/drivers/ipw2200/debug_level
287
288 You can find the list of debug mask values in
289 drivers/net/wireless/ipw2200.h
290
291 If you are not trying to debug or develop the IPW2200 driver, you
292 most likely want to say N here.
293 282
294config AIRO 283config AIRO
295 tristate "Cisco/Aironet 34X/35X/4500/4800 ISA and PCI cards" 284 tristate "Cisco/Aironet 34X/35X/4500/4800 ISA and PCI cards"
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index a4dd13942714..e088ceefb4a3 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -47,6 +47,7 @@
47#include <linux/pci.h> 47#include <linux/pci.h>
48#include <asm/uaccess.h> 48#include <asm/uaccess.h>
49#include <net/ieee80211.h> 49#include <net/ieee80211.h>
50#include <linux/kthread.h>
50 51
51#include "airo.h" 52#include "airo.h"
52 53
@@ -1187,11 +1188,10 @@ struct airo_info {
1187 int whichbap); 1188 int whichbap);
1188 unsigned short *flash; 1189 unsigned short *flash;
1189 tdsRssiEntry *rssi; 1190 tdsRssiEntry *rssi;
1190 struct task_struct *task; 1191 struct task_struct *list_bss_task;
1192 struct task_struct *airo_thread_task;
1191 struct semaphore sem; 1193 struct semaphore sem;
1192 pid_t thr_pid;
1193 wait_queue_head_t thr_wait; 1194 wait_queue_head_t thr_wait;
1194 struct completion thr_exited;
1195 unsigned long expires; 1195 unsigned long expires;
1196 struct { 1196 struct {
1197 struct sk_buff *skb; 1197 struct sk_buff *skb;
@@ -1733,12 +1733,12 @@ static int readBSSListRid(struct airo_info *ai, int first,
1733 cmd.cmd=CMD_LISTBSS; 1733 cmd.cmd=CMD_LISTBSS;
1734 if (down_interruptible(&ai->sem)) 1734 if (down_interruptible(&ai->sem))
1735 return -ERESTARTSYS; 1735 return -ERESTARTSYS;
1736 ai->list_bss_task = current;
1736 issuecommand(ai, &cmd, &rsp); 1737 issuecommand(ai, &cmd, &rsp);
1737 up(&ai->sem); 1738 up(&ai->sem);
1738 /* Let the command take effect */ 1739 /* Let the command take effect */
1739 ai->task = current; 1740 schedule_timeout_uninterruptible(3 * HZ);
1740 ssleep(3); 1741 ai->list_bss_task = NULL;
1741 ai->task = NULL;
1742 } 1742 }
1743 rc = PC4500_readrid(ai, first ? ai->bssListFirst : ai->bssListNext, 1743 rc = PC4500_readrid(ai, first ? ai->bssListFirst : ai->bssListNext,
1744 list, ai->bssListRidLen, 1); 1744 list, ai->bssListRidLen, 1);
@@ -2400,8 +2400,7 @@ void stop_airo_card( struct net_device *dev, int freeres )
2400 clear_bit(FLAG_REGISTERED, &ai->flags); 2400 clear_bit(FLAG_REGISTERED, &ai->flags);
2401 } 2401 }
2402 set_bit(JOB_DIE, &ai->jobs); 2402 set_bit(JOB_DIE, &ai->jobs);
2403 kill_proc(ai->thr_pid, SIGTERM, 1); 2403 kthread_stop(ai->airo_thread_task);
2404 wait_for_completion(&ai->thr_exited);
2405 2404
2406 /* 2405 /*
2407 * Clean out tx queue 2406 * Clean out tx queue
@@ -2811,9 +2810,8 @@ static struct net_device *_init_airo_card( unsigned short irq, int port,
2811 ai->config.len = 0; 2810 ai->config.len = 0;
2812 ai->pci = pci; 2811 ai->pci = pci;
2813 init_waitqueue_head (&ai->thr_wait); 2812 init_waitqueue_head (&ai->thr_wait);
2814 init_completion (&ai->thr_exited); 2813 ai->airo_thread_task = kthread_run(airo_thread, dev, dev->name);
2815 ai->thr_pid = kernel_thread(airo_thread, dev, CLONE_FS | CLONE_FILES); 2814 if (IS_ERR(ai->airo_thread_task))
2816 if (ai->thr_pid < 0)
2817 goto err_out_free; 2815 goto err_out_free;
2818 ai->tfm = NULL; 2816 ai->tfm = NULL;
2819 rc = add_airo_dev( dev ); 2817 rc = add_airo_dev( dev );
@@ -2930,8 +2928,7 @@ err_out_unlink:
2930 del_airo_dev(dev); 2928 del_airo_dev(dev);
2931err_out_thr: 2929err_out_thr:
2932 set_bit(JOB_DIE, &ai->jobs); 2930 set_bit(JOB_DIE, &ai->jobs);
2933 kill_proc(ai->thr_pid, SIGTERM, 1); 2931 kthread_stop(ai->airo_thread_task);
2934 wait_for_completion(&ai->thr_exited);
2935err_out_free: 2932err_out_free:
2936 free_netdev(dev); 2933 free_netdev(dev);
2937 return NULL; 2934 return NULL;
@@ -3063,13 +3060,7 @@ static int airo_thread(void *data) {
3063 struct airo_info *ai = dev->priv; 3060 struct airo_info *ai = dev->priv;
3064 int locked; 3061 int locked;
3065 3062
3066 daemonize("%s", dev->name);
3067 allow_signal(SIGTERM);
3068
3069 while(1) { 3063 while(1) {
3070 if (signal_pending(current))
3071 flush_signals(current);
3072
3073 /* make swsusp happy with our thread */ 3064 /* make swsusp happy with our thread */
3074 try_to_freeze(); 3065 try_to_freeze();
3075 3066
@@ -3097,7 +3088,7 @@ static int airo_thread(void *data) {
3097 set_bit(JOB_AUTOWEP, &ai->jobs); 3088 set_bit(JOB_AUTOWEP, &ai->jobs);
3098 break; 3089 break;
3099 } 3090 }
3100 if (!signal_pending(current)) { 3091 if (!kthread_should_stop()) {
3101 unsigned long wake_at; 3092 unsigned long wake_at;
3102 if (!ai->expires || !ai->scan_timeout) { 3093 if (!ai->expires || !ai->scan_timeout) {
3103 wake_at = max(ai->expires, 3094 wake_at = max(ai->expires,
@@ -3109,7 +3100,7 @@ static int airo_thread(void *data) {
3109 schedule_timeout(wake_at - jiffies); 3100 schedule_timeout(wake_at - jiffies);
3110 continue; 3101 continue;
3111 } 3102 }
3112 } else if (!signal_pending(current)) { 3103 } else if (!kthread_should_stop()) {
3113 schedule(); 3104 schedule();
3114 continue; 3105 continue;
3115 } 3106 }
@@ -3154,7 +3145,8 @@ static int airo_thread(void *data) {
3154 else /* Shouldn't get here, but we make sure to unlock */ 3145 else /* Shouldn't get here, but we make sure to unlock */
3155 up(&ai->sem); 3146 up(&ai->sem);
3156 } 3147 }
3157 complete_and_exit (&ai->thr_exited, 0); 3148
3149 return 0;
3158} 3150}
3159 3151
3160static irqreturn_t airo_interrupt ( int irq, void* dev_id, struct pt_regs *regs) { 3152static irqreturn_t airo_interrupt ( int irq, void* dev_id, struct pt_regs *regs) {
@@ -3235,8 +3227,8 @@ static irqreturn_t airo_interrupt ( int irq, void* dev_id, struct pt_regs *regs)
3235 if(newStatus == ASSOCIATED || newStatus == REASSOCIATED) { 3227 if(newStatus == ASSOCIATED || newStatus == REASSOCIATED) {
3236 if (auto_wep) 3228 if (auto_wep)
3237 apriv->expires = 0; 3229 apriv->expires = 0;
3238 if (apriv->task) 3230 if (apriv->list_bss_task)
3239 wake_up_process (apriv->task); 3231 wake_up_process(apriv->list_bss_task);
3240 set_bit(FLAG_UPDATE_UNI, &apriv->flags); 3232 set_bit(FLAG_UPDATE_UNI, &apriv->flags);
3241 set_bit(FLAG_UPDATE_MULTI, &apriv->flags); 3233 set_bit(FLAG_UPDATE_MULTI, &apriv->flags);
3242 3234
@@ -3950,13 +3942,11 @@ static u16 issuecommand(struct airo_info *ai, Cmd *pCmd, Resp *pRsp) {
3950 pRsp->rsp0 = IN4500(ai, RESP0); 3942 pRsp->rsp0 = IN4500(ai, RESP0);
3951 pRsp->rsp1 = IN4500(ai, RESP1); 3943 pRsp->rsp1 = IN4500(ai, RESP1);
3952 pRsp->rsp2 = IN4500(ai, RESP2); 3944 pRsp->rsp2 = IN4500(ai, RESP2);
3953 if ((pRsp->status & 0xff00)!=0 && pCmd->cmd != CMD_SOFTRESET) { 3945 if ((pRsp->status & 0xff00)!=0 && pCmd->cmd != CMD_SOFTRESET)
3954 airo_print_err(ai->dev->name, "cmd= %x\n", pCmd->cmd); 3946 airo_print_err(ai->dev->name,
3955 airo_print_err(ai->dev->name, "status= %x\n", pRsp->status); 3947 "cmd:%x status:%x rsp0:%x rsp1:%x rsp2:%x",
3956 airo_print_err(ai->dev->name, "Rsp0= %x\n", pRsp->rsp0); 3948 pCmd->cmd, pRsp->status, pRsp->rsp0, pRsp->rsp1,
3957 airo_print_err(ai->dev->name, "Rsp1= %x\n", pRsp->rsp1); 3949 pRsp->rsp2);
3958 airo_print_err(ai->dev->name, "Rsp2= %x\n", pRsp->rsp2);
3959 }
3960 3950
3961 // clear stuck command busy if necessary 3951 // clear stuck command busy if necessary
3962 if (IN4500(ai, COMMAND) & COMMAND_BUSY) { 3952 if (IN4500(ai, COMMAND) & COMMAND_BUSY) {
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx.h b/drivers/net/wireless/bcm43xx/bcm43xx.h
index 17a56828e232..62fd7e237789 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx.h
+++ b/drivers/net/wireless/bcm43xx/bcm43xx.h
@@ -33,14 +33,18 @@
33#define BCM43xx_PCICFG_ICR 0x94 33#define BCM43xx_PCICFG_ICR 0x94
34 34
35/* MMIO offsets */ 35/* MMIO offsets */
36#define BCM43xx_MMIO_DMA1_REASON 0x20 36#define BCM43xx_MMIO_DMA0_REASON 0x20
37#define BCM43xx_MMIO_DMA1_IRQ_MASK 0x24 37#define BCM43xx_MMIO_DMA0_IRQ_MASK 0x24
38#define BCM43xx_MMIO_DMA2_REASON 0x28 38#define BCM43xx_MMIO_DMA1_REASON 0x28
39#define BCM43xx_MMIO_DMA2_IRQ_MASK 0x2C 39#define BCM43xx_MMIO_DMA1_IRQ_MASK 0x2C
40#define BCM43xx_MMIO_DMA3_REASON 0x30 40#define BCM43xx_MMIO_DMA2_REASON 0x30
41#define BCM43xx_MMIO_DMA3_IRQ_MASK 0x34 41#define BCM43xx_MMIO_DMA2_IRQ_MASK 0x34
42#define BCM43xx_MMIO_DMA4_REASON 0x38 42#define BCM43xx_MMIO_DMA3_REASON 0x38
43#define BCM43xx_MMIO_DMA4_IRQ_MASK 0x3C 43#define BCM43xx_MMIO_DMA3_IRQ_MASK 0x3C
44#define BCM43xx_MMIO_DMA4_REASON 0x40
45#define BCM43xx_MMIO_DMA4_IRQ_MASK 0x44
46#define BCM43xx_MMIO_DMA5_REASON 0x48
47#define BCM43xx_MMIO_DMA5_IRQ_MASK 0x4C
44#define BCM43xx_MMIO_STATUS_BITFIELD 0x120 48#define BCM43xx_MMIO_STATUS_BITFIELD 0x120
45#define BCM43xx_MMIO_STATUS2_BITFIELD 0x124 49#define BCM43xx_MMIO_STATUS2_BITFIELD 0x124
46#define BCM43xx_MMIO_GEN_IRQ_REASON 0x128 50#define BCM43xx_MMIO_GEN_IRQ_REASON 0x128
@@ -56,14 +60,27 @@
56#define BCM43xx_MMIO_XMITSTAT_1 0x174 60#define BCM43xx_MMIO_XMITSTAT_1 0x174
57#define BCM43xx_MMIO_REV3PLUS_TSF_LOW 0x180 /* core rev >= 3 only */ 61#define BCM43xx_MMIO_REV3PLUS_TSF_LOW 0x180 /* core rev >= 3 only */
58#define BCM43xx_MMIO_REV3PLUS_TSF_HIGH 0x184 /* core rev >= 3 only */ 62#define BCM43xx_MMIO_REV3PLUS_TSF_HIGH 0x184 /* core rev >= 3 only */
59#define BCM43xx_MMIO_DMA1_BASE 0x200 63
60#define BCM43xx_MMIO_DMA2_BASE 0x220 64/* 32-bit DMA */
61#define BCM43xx_MMIO_DMA3_BASE 0x240 65#define BCM43xx_MMIO_DMA32_BASE0 0x200
62#define BCM43xx_MMIO_DMA4_BASE 0x260 66#define BCM43xx_MMIO_DMA32_BASE1 0x220
67#define BCM43xx_MMIO_DMA32_BASE2 0x240
68#define BCM43xx_MMIO_DMA32_BASE3 0x260
69#define BCM43xx_MMIO_DMA32_BASE4 0x280
70#define BCM43xx_MMIO_DMA32_BASE5 0x2A0
71/* 64-bit DMA */
72#define BCM43xx_MMIO_DMA64_BASE0 0x200
73#define BCM43xx_MMIO_DMA64_BASE1 0x240
74#define BCM43xx_MMIO_DMA64_BASE2 0x280
75#define BCM43xx_MMIO_DMA64_BASE3 0x2C0
76#define BCM43xx_MMIO_DMA64_BASE4 0x300
77#define BCM43xx_MMIO_DMA64_BASE5 0x340
78/* PIO */
63#define BCM43xx_MMIO_PIO1_BASE 0x300 79#define BCM43xx_MMIO_PIO1_BASE 0x300
64#define BCM43xx_MMIO_PIO2_BASE 0x310 80#define BCM43xx_MMIO_PIO2_BASE 0x310
65#define BCM43xx_MMIO_PIO3_BASE 0x320 81#define BCM43xx_MMIO_PIO3_BASE 0x320
66#define BCM43xx_MMIO_PIO4_BASE 0x330 82#define BCM43xx_MMIO_PIO4_BASE 0x330
83
67#define BCM43xx_MMIO_PHY_VER 0x3E0 84#define BCM43xx_MMIO_PHY_VER 0x3E0
68#define BCM43xx_MMIO_PHY_RADIO 0x3E2 85#define BCM43xx_MMIO_PHY_RADIO 0x3E2
69#define BCM43xx_MMIO_ANTENNA 0x3E8 86#define BCM43xx_MMIO_ANTENNA 0x3E8
@@ -233,8 +250,14 @@
233#define BCM43xx_SBTMSTATELOW_FORCE_GATE_CLOCK 0x20000 250#define BCM43xx_SBTMSTATELOW_FORCE_GATE_CLOCK 0x20000
234 251
235/* sbtmstatehigh state flags */ 252/* sbtmstatehigh state flags */
236#define BCM43xx_SBTMSTATEHIGH_SERROR 0x1 253#define BCM43xx_SBTMSTATEHIGH_SERROR 0x00000001
237#define BCM43xx_SBTMSTATEHIGH_BUSY 0x4 254#define BCM43xx_SBTMSTATEHIGH_BUSY 0x00000004
255#define BCM43xx_SBTMSTATEHIGH_TIMEOUT 0x00000020
256#define BCM43xx_SBTMSTATEHIGH_COREFLAGS 0x1FFF0000
257#define BCM43xx_SBTMSTATEHIGH_DMA64BIT 0x10000000
258#define BCM43xx_SBTMSTATEHIGH_GATEDCLK 0x20000000
259#define BCM43xx_SBTMSTATEHIGH_BISTFAILED 0x40000000
260#define BCM43xx_SBTMSTATEHIGH_BISTCOMPLETE 0x80000000
238 261
239/* sbimstate flags */ 262/* sbimstate flags */
240#define BCM43xx_SBIMSTATE_IB_ERROR 0x20000 263#define BCM43xx_SBIMSTATE_IB_ERROR 0x20000
@@ -504,6 +527,12 @@ struct bcm43xx_phyinfo {
504 * This lock is only used by bcm43xx_phy_{un}lock() 527 * This lock is only used by bcm43xx_phy_{un}lock()
505 */ 528 */
506 spinlock_t lock; 529 spinlock_t lock;
530
531 /* Firmware. */
532 const struct firmware *ucode;
533 const struct firmware *pcm;
534 const struct firmware *initvals0;
535 const struct firmware *initvals1;
507}; 536};
508 537
509 538
@@ -568,8 +597,11 @@ struct bcm43xx_dma {
568 struct bcm43xx_dmaring *tx_ring1; 597 struct bcm43xx_dmaring *tx_ring1;
569 struct bcm43xx_dmaring *tx_ring2; 598 struct bcm43xx_dmaring *tx_ring2;
570 struct bcm43xx_dmaring *tx_ring3; 599 struct bcm43xx_dmaring *tx_ring3;
600 struct bcm43xx_dmaring *tx_ring4;
601 struct bcm43xx_dmaring *tx_ring5;
602
571 struct bcm43xx_dmaring *rx_ring0; 603 struct bcm43xx_dmaring *rx_ring0;
572 struct bcm43xx_dmaring *rx_ring1; /* only available on core.rev < 5 */ 604 struct bcm43xx_dmaring *rx_ring3; /* only available on core.rev < 5 */
573}; 605};
574 606
575/* Data structures for PIO transmission, per 80211 core. */ 607/* Data structures for PIO transmission, per 80211 core. */
@@ -593,12 +625,14 @@ struct bcm43xx_coreinfo {
593 u8 available:1, 625 u8 available:1,
594 enabled:1, 626 enabled:1,
595 initialized:1; 627 initialized:1;
596 /** core_id ID number */
597 u16 id;
598 /** core_rev revision number */ 628 /** core_rev revision number */
599 u8 rev; 629 u8 rev;
600 /** Index number for _switch_core() */ 630 /** Index number for _switch_core() */
601 u8 index; 631 u8 index;
632 /** core_id ID number */
633 u16 id;
634 /** Core-specific data. */
635 void *priv;
602}; 636};
603 637
604/* Additional information for each 80211 core. */ 638/* Additional information for each 80211 core. */
@@ -647,7 +681,23 @@ enum {
647 BCM43xx_STAT_RESTARTING, /* controller_restart() called. */ 681 BCM43xx_STAT_RESTARTING, /* controller_restart() called. */
648}; 682};
649#define bcm43xx_status(bcm) atomic_read(&(bcm)->init_status) 683#define bcm43xx_status(bcm) atomic_read(&(bcm)->init_status)
650#define bcm43xx_set_status(bcm, stat) atomic_set(&(bcm)->init_status, (stat)) 684#define bcm43xx_set_status(bcm, stat) do { \
685 atomic_set(&(bcm)->init_status, (stat)); \
686 smp_wmb(); \
687 } while (0)
688
689/* *** THEORY OF LOCKING ***
690 *
691 * We have two different locks in the bcm43xx driver.
692 * => bcm->mutex: General sleeping mutex. Protects struct bcm43xx_private
693 * and the device registers. This mutex does _not_ protect
694 * against concurrency from the IRQ handler.
695 * => bcm->irq_lock: IRQ spinlock. Protects against IRQ handler concurrency.
696 *
697 * Please note that, if you only take the irq_lock, you are not protected
698 * against concurrency from the periodic work handlers.
699 * Most times you want to take _both_ locks.
700 */
651 701
652struct bcm43xx_private { 702struct bcm43xx_private {
653 struct ieee80211_device *ieee; 703 struct ieee80211_device *ieee;
@@ -659,7 +709,6 @@ struct bcm43xx_private {
659 709
660 void __iomem *mmio_addr; 710 void __iomem *mmio_addr;
661 711
662 /* Locking, see "theory of locking" text below. */
663 spinlock_t irq_lock; 712 spinlock_t irq_lock;
664 struct mutex mutex; 713 struct mutex mutex;
665 714
@@ -691,6 +740,7 @@ struct bcm43xx_private {
691 struct bcm43xx_sprominfo sprom; 740 struct bcm43xx_sprominfo sprom;
692#define BCM43xx_NR_LEDS 4 741#define BCM43xx_NR_LEDS 4
693 struct bcm43xx_led leds[BCM43xx_NR_LEDS]; 742 struct bcm43xx_led leds[BCM43xx_NR_LEDS];
743 spinlock_t leds_lock;
694 744
695 /* The currently active core. */ 745 /* The currently active core. */
696 struct bcm43xx_coreinfo *current_core; 746 struct bcm43xx_coreinfo *current_core;
@@ -708,10 +758,6 @@ struct bcm43xx_private {
708 struct bcm43xx_coreinfo core_80211[ BCM43xx_MAX_80211_CORES ]; 758 struct bcm43xx_coreinfo core_80211[ BCM43xx_MAX_80211_CORES ];
709 /* Additional information, specific to the 80211 cores. */ 759 /* Additional information, specific to the 80211 cores. */
710 struct bcm43xx_coreinfo_80211 core_80211_ext[ BCM43xx_MAX_80211_CORES ]; 760 struct bcm43xx_coreinfo_80211 core_80211_ext[ BCM43xx_MAX_80211_CORES ];
711 /* Index of the current 80211 core. If current_core is not
712 * an 80211 core, this is -1.
713 */
714 int current_80211_core_idx;
715 /* Number of available 80211 cores. */ 761 /* Number of available 80211 cores. */
716 int nr_80211_available; 762 int nr_80211_available;
717 763
@@ -719,11 +765,13 @@ struct bcm43xx_private {
719 765
720 /* Reason code of the last interrupt. */ 766 /* Reason code of the last interrupt. */
721 u32 irq_reason; 767 u32 irq_reason;
722 u32 dma_reason[4]; 768 u32 dma_reason[6];
723 /* saved irq enable/disable state bitfield. */ 769 /* saved irq enable/disable state bitfield. */
724 u32 irq_savedstate; 770 u32 irq_savedstate;
725 /* Link Quality calculation context. */ 771 /* Link Quality calculation context. */
726 struct bcm43xx_noise_calculation noisecalc; 772 struct bcm43xx_noise_calculation noisecalc;
773 /* if > 0 MAC is suspended. if == 0 MAC is enabled. */
774 int mac_suspended;
727 775
728 /* Threshold values. */ 776 /* Threshold values. */
729 //TODO: The RTS thr has to be _used_. Currently, it is only set via WX. 777 //TODO: The RTS thr has to be _used_. Currently, it is only set via WX.
@@ -746,12 +794,6 @@ struct bcm43xx_private {
746 struct bcm43xx_key key[54]; 794 struct bcm43xx_key key[54];
747 u8 default_key_idx; 795 u8 default_key_idx;
748 796
749 /* Firmware. */
750 const struct firmware *ucode;
751 const struct firmware *pcm;
752 const struct firmware *initvals0;
753 const struct firmware *initvals1;
754
755 /* Random Number Generator. */ 797 /* Random Number Generator. */
756 struct hwrng rng; 798 struct hwrng rng;
757 char rng_name[20 + 1]; 799 char rng_name[20 + 1];
@@ -763,55 +805,6 @@ struct bcm43xx_private {
763}; 805};
764 806
765 807
766/* *** THEORY OF LOCKING ***
767 *
768 * We have two different locks in the bcm43xx driver.
769 * => bcm->mutex: General sleeping mutex. Protects struct bcm43xx_private
770 * and the device registers.
771 * => bcm->irq_lock: IRQ spinlock. Protects against IRQ handler concurrency.
772 *
773 * We have three types of helper function pairs to utilize these locks.
774 * (Always use the helper functions.)
775 * 1) bcm43xx_{un}lock_noirq():
776 * Takes bcm->mutex. Does _not_ protect against IRQ concurrency,
777 * so it is almost always unsafe, if device IRQs are enabled.
778 * So only use this, if device IRQs are masked.
779 * Locking may sleep.
780 * You can sleep within the critical section.
781 * 2) bcm43xx_{un}lock_irqonly():
782 * Takes bcm->irq_lock. Does _not_ protect against
783 * bcm43xx_lock_noirq() critical sections.
784 * Does only protect against the IRQ handler path and other
785 * irqonly() critical sections.
786 * Locking does not sleep.
787 * You must not sleep within the critical section.
788 * 3) bcm43xx_{un}lock_irqsafe():
789 * This is the cummulative lock and takes both, mutex and irq_lock.
790 * Protects against noirq() and irqonly() critical sections (and
791 * the IRQ handler path).
792 * Locking may sleep.
793 * You must not sleep within the critical section.
794 */
795
796/* Lock type 1 */
797#define bcm43xx_lock_noirq(bcm) mutex_lock(&(bcm)->mutex)
798#define bcm43xx_unlock_noirq(bcm) mutex_unlock(&(bcm)->mutex)
799/* Lock type 2 */
800#define bcm43xx_lock_irqonly(bcm, flags) \
801 spin_lock_irqsave(&(bcm)->irq_lock, flags)
802#define bcm43xx_unlock_irqonly(bcm, flags) \
803 spin_unlock_irqrestore(&(bcm)->irq_lock, flags)
804/* Lock type 3 */
805#define bcm43xx_lock_irqsafe(bcm, flags) do { \
806 bcm43xx_lock_noirq(bcm); \
807 bcm43xx_lock_irqonly(bcm, flags); \
808 } while (0)
809#define bcm43xx_unlock_irqsafe(bcm, flags) do { \
810 bcm43xx_unlock_irqonly(bcm, flags); \
811 bcm43xx_unlock_noirq(bcm); \
812 } while (0)
813
814
815static inline 808static inline
816struct bcm43xx_private * bcm43xx_priv(struct net_device *dev) 809struct bcm43xx_private * bcm43xx_priv(struct net_device *dev)
817{ 810{
@@ -863,34 +856,33 @@ int bcm43xx_using_pio(struct bcm43xx_private *bcm)
863 * any of these functions. 856 * any of these functions.
864 */ 857 */
865static inline 858static inline
859struct bcm43xx_coreinfo_80211 *
860bcm43xx_current_80211_priv(struct bcm43xx_private *bcm)
861{
862 assert(bcm->current_core->id == BCM43xx_COREID_80211);
863 return bcm->current_core->priv;
864}
865static inline
866struct bcm43xx_pio * bcm43xx_current_pio(struct bcm43xx_private *bcm) 866struct bcm43xx_pio * bcm43xx_current_pio(struct bcm43xx_private *bcm)
867{ 867{
868 assert(bcm43xx_using_pio(bcm)); 868 assert(bcm43xx_using_pio(bcm));
869 assert(bcm->current_80211_core_idx >= 0); 869 return &(bcm43xx_current_80211_priv(bcm)->pio);
870 assert(bcm->current_80211_core_idx < BCM43xx_MAX_80211_CORES);
871 return &(bcm->core_80211_ext[bcm->current_80211_core_idx].pio);
872} 870}
873static inline 871static inline
874struct bcm43xx_dma * bcm43xx_current_dma(struct bcm43xx_private *bcm) 872struct bcm43xx_dma * bcm43xx_current_dma(struct bcm43xx_private *bcm)
875{ 873{
876 assert(!bcm43xx_using_pio(bcm)); 874 assert(!bcm43xx_using_pio(bcm));
877 assert(bcm->current_80211_core_idx >= 0); 875 return &(bcm43xx_current_80211_priv(bcm)->dma);
878 assert(bcm->current_80211_core_idx < BCM43xx_MAX_80211_CORES);
879 return &(bcm->core_80211_ext[bcm->current_80211_core_idx].dma);
880} 876}
881static inline 877static inline
882struct bcm43xx_phyinfo * bcm43xx_current_phy(struct bcm43xx_private *bcm) 878struct bcm43xx_phyinfo * bcm43xx_current_phy(struct bcm43xx_private *bcm)
883{ 879{
884 assert(bcm->current_80211_core_idx >= 0); 880 return &(bcm43xx_current_80211_priv(bcm)->phy);
885 assert(bcm->current_80211_core_idx < BCM43xx_MAX_80211_CORES);
886 return &(bcm->core_80211_ext[bcm->current_80211_core_idx].phy);
887} 881}
888static inline 882static inline
889struct bcm43xx_radioinfo * bcm43xx_current_radio(struct bcm43xx_private *bcm) 883struct bcm43xx_radioinfo * bcm43xx_current_radio(struct bcm43xx_private *bcm)
890{ 884{
891 assert(bcm->current_80211_core_idx >= 0); 885 return &(bcm43xx_current_80211_priv(bcm)->radio);
892 assert(bcm->current_80211_core_idx < BCM43xx_MAX_80211_CORES);
893 return &(bcm->core_80211_ext[bcm->current_80211_core_idx].radio);
894} 886}
895 887
896 888
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c b/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c
index ce2e40b29b4f..923275ea0789 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c
@@ -77,7 +77,8 @@ static ssize_t devinfo_read_file(struct file *file, char __user *userbuf,
77 77
78 down(&big_buffer_sem); 78 down(&big_buffer_sem);
79 79
80 bcm43xx_lock_irqsafe(bcm, flags); 80 mutex_lock(&bcm->mutex);
81 spin_lock_irqsave(&bcm->irq_lock, flags);
81 if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) { 82 if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) {
82 fappend("Board not initialized.\n"); 83 fappend("Board not initialized.\n");
83 goto out; 84 goto out;
@@ -121,7 +122,8 @@ static ssize_t devinfo_read_file(struct file *file, char __user *userbuf,
121 fappend("\n"); 122 fappend("\n");
122 123
123out: 124out:
124 bcm43xx_unlock_irqsafe(bcm, flags); 125 spin_unlock_irqrestore(&bcm->irq_lock, flags);
126 mutex_unlock(&bcm->mutex);
125 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos); 127 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
126 up(&big_buffer_sem); 128 up(&big_buffer_sem);
127 return res; 129 return res;
@@ -159,7 +161,8 @@ static ssize_t spromdump_read_file(struct file *file, char __user *userbuf,
159 unsigned long flags; 161 unsigned long flags;
160 162
161 down(&big_buffer_sem); 163 down(&big_buffer_sem);
162 bcm43xx_lock_irqsafe(bcm, flags); 164 mutex_lock(&bcm->mutex);
165 spin_lock_irqsave(&bcm->irq_lock, flags);
163 if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) { 166 if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) {
164 fappend("Board not initialized.\n"); 167 fappend("Board not initialized.\n");
165 goto out; 168 goto out;
@@ -169,7 +172,8 @@ static ssize_t spromdump_read_file(struct file *file, char __user *userbuf,
169 fappend("boardflags: 0x%04x\n", bcm->sprom.boardflags); 172 fappend("boardflags: 0x%04x\n", bcm->sprom.boardflags);
170 173
171out: 174out:
172 bcm43xx_unlock_irqsafe(bcm, flags); 175 spin_unlock_irqrestore(&bcm->irq_lock, flags);
176 mutex_unlock(&bcm->mutex);
173 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos); 177 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
174 up(&big_buffer_sem); 178 up(&big_buffer_sem);
175 return res; 179 return res;
@@ -188,7 +192,8 @@ static ssize_t tsf_read_file(struct file *file, char __user *userbuf,
188 u64 tsf; 192 u64 tsf;
189 193
190 down(&big_buffer_sem); 194 down(&big_buffer_sem);
191 bcm43xx_lock_irqsafe(bcm, flags); 195 mutex_lock(&bcm->mutex);
196 spin_lock_irqsave(&bcm->irq_lock, flags);
192 if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) { 197 if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) {
193 fappend("Board not initialized.\n"); 198 fappend("Board not initialized.\n");
194 goto out; 199 goto out;
@@ -199,7 +204,8 @@ static ssize_t tsf_read_file(struct file *file, char __user *userbuf,
199 (unsigned int)(tsf & 0xFFFFFFFFULL)); 204 (unsigned int)(tsf & 0xFFFFFFFFULL));
200 205
201out: 206out:
202 bcm43xx_unlock_irqsafe(bcm, flags); 207 spin_unlock_irqrestore(&bcm->irq_lock, flags);
208 mutex_unlock(&bcm->mutex);
203 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos); 209 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
204 up(&big_buffer_sem); 210 up(&big_buffer_sem);
205 return res; 211 return res;
@@ -221,7 +227,8 @@ static ssize_t tsf_write_file(struct file *file, const char __user *user_buf,
221 res = -EFAULT; 227 res = -EFAULT;
222 goto out_up; 228 goto out_up;
223 } 229 }
224 bcm43xx_lock_irqsafe(bcm, flags); 230 mutex_lock(&bcm->mutex);
231 spin_lock_irqsave(&bcm->irq_lock, flags);
225 if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) { 232 if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) {
226 printk(KERN_INFO PFX "debugfs: Board not initialized.\n"); 233 printk(KERN_INFO PFX "debugfs: Board not initialized.\n");
227 res = -EFAULT; 234 res = -EFAULT;
@@ -237,7 +244,8 @@ static ssize_t tsf_write_file(struct file *file, const char __user *user_buf,
237 res = buf_size; 244 res = buf_size;
238 245
239out_unlock: 246out_unlock:
240 bcm43xx_unlock_irqsafe(bcm, flags); 247 spin_unlock_irqrestore(&bcm->irq_lock, flags);
248 mutex_unlock(&bcm->mutex);
241out_up: 249out_up:
242 up(&big_buffer_sem); 250 up(&big_buffer_sem);
243 return res; 251 return res;
@@ -258,7 +266,8 @@ static ssize_t txstat_read_file(struct file *file, char __user *userbuf,
258 int i, cnt, j = 0; 266 int i, cnt, j = 0;
259 267
260 down(&big_buffer_sem); 268 down(&big_buffer_sem);
261 bcm43xx_lock_irqsafe(bcm, flags); 269 mutex_lock(&bcm->mutex);
270 spin_lock_irqsave(&bcm->irq_lock, flags);
262 271
263 fappend("Last %d logged xmitstatus blobs (Latest first):\n\n", 272 fappend("Last %d logged xmitstatus blobs (Latest first):\n\n",
264 BCM43xx_NR_LOGGED_XMITSTATUS); 273 BCM43xx_NR_LOGGED_XMITSTATUS);
@@ -294,14 +303,51 @@ static ssize_t txstat_read_file(struct file *file, char __user *userbuf,
294 i = BCM43xx_NR_LOGGED_XMITSTATUS - 1; 303 i = BCM43xx_NR_LOGGED_XMITSTATUS - 1;
295 } 304 }
296 305
297 bcm43xx_unlock_irqsafe(bcm, flags); 306 spin_unlock_irqrestore(&bcm->irq_lock, flags);
298 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos); 307 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
299 bcm43xx_lock_irqsafe(bcm, flags); 308 spin_lock_irqsave(&bcm->irq_lock, flags);
300 if (*ppos == pos) { 309 if (*ppos == pos) {
301 /* Done. Drop the copied data. */ 310 /* Done. Drop the copied data. */
302 e->xmitstatus_printing = 0; 311 e->xmitstatus_printing = 0;
303 } 312 }
304 bcm43xx_unlock_irqsafe(bcm, flags); 313 spin_unlock_irqrestore(&bcm->irq_lock, flags);
314 mutex_unlock(&bcm->mutex);
315 up(&big_buffer_sem);
316 return res;
317}
318
319static ssize_t restart_write_file(struct file *file, const char __user *user_buf,
320 size_t count, loff_t *ppos)
321{
322 struct bcm43xx_private *bcm = file->private_data;
323 char *buf = really_big_buffer;
324 ssize_t buf_size;
325 ssize_t res;
326 unsigned long flags;
327
328 buf_size = min(count, sizeof (really_big_buffer) - 1);
329 down(&big_buffer_sem);
330 if (copy_from_user(buf, user_buf, buf_size)) {
331 res = -EFAULT;
332 goto out_up;
333 }
334 mutex_lock(&(bcm)->mutex);
335 spin_lock_irqsave(&(bcm)->irq_lock, flags);
336 if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) {
337 printk(KERN_INFO PFX "debugfs: Board not initialized.\n");
338 res = -EFAULT;
339 goto out_unlock;
340 }
341 if (count > 0 && buf[0] == '1') {
342 bcm43xx_controller_restart(bcm, "manually restarted");
343 res = count;
344 } else
345 res = -EINVAL;
346
347out_unlock:
348 spin_unlock_irqrestore(&(bcm)->irq_lock, flags);
349 mutex_unlock(&(bcm)->mutex);
350out_up:
305 up(&big_buffer_sem); 351 up(&big_buffer_sem);
306 return res; 352 return res;
307} 353}
@@ -339,6 +385,11 @@ static struct file_operations txstat_fops = {
339 .open = open_file_generic, 385 .open = open_file_generic,
340}; 386};
341 387
388static struct file_operations restart_fops = {
389 .write = restart_write_file,
390 .open = open_file_generic,
391};
392
342 393
343void bcm43xx_debugfs_add_device(struct bcm43xx_private *bcm) 394void bcm43xx_debugfs_add_device(struct bcm43xx_private *bcm)
344{ 395{
@@ -390,6 +441,10 @@ void bcm43xx_debugfs_add_device(struct bcm43xx_private *bcm)
390 bcm, &txstat_fops); 441 bcm, &txstat_fops);
391 if (!e->dentry_txstat) 442 if (!e->dentry_txstat)
392 printk(KERN_ERR PFX "debugfs: creating \"tx_status\" for \"%s\" failed!\n", devdir); 443 printk(KERN_ERR PFX "debugfs: creating \"tx_status\" for \"%s\" failed!\n", devdir);
444 e->dentry_restart = debugfs_create_file("restart", 0222, e->subdir,
445 bcm, &restart_fops);
446 if (!e->dentry_restart)
447 printk(KERN_ERR PFX "debugfs: creating \"restart\" for \"%s\" failed!\n", devdir);
393} 448}
394 449
395void bcm43xx_debugfs_remove_device(struct bcm43xx_private *bcm) 450void bcm43xx_debugfs_remove_device(struct bcm43xx_private *bcm)
@@ -405,6 +460,7 @@ void bcm43xx_debugfs_remove_device(struct bcm43xx_private *bcm)
405 debugfs_remove(e->dentry_devinfo); 460 debugfs_remove(e->dentry_devinfo);
406 debugfs_remove(e->dentry_tsf); 461 debugfs_remove(e->dentry_tsf);
407 debugfs_remove(e->dentry_txstat); 462 debugfs_remove(e->dentry_txstat);
463 debugfs_remove(e->dentry_restart);
408 debugfs_remove(e->subdir); 464 debugfs_remove(e->subdir);
409 kfree(e->xmitstatus_buffer); 465 kfree(e->xmitstatus_buffer);
410 kfree(e->xmitstatus_print_buffer); 466 kfree(e->xmitstatus_print_buffer);
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.h b/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.h
index 50ce267f794d..a40d1af35545 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.h
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.h
@@ -20,6 +20,7 @@ struct bcm43xx_dfsentry {
20 struct dentry *dentry_spromdump; 20 struct dentry *dentry_spromdump;
21 struct dentry *dentry_tsf; 21 struct dentry *dentry_tsf;
22 struct dentry *dentry_txstat; 22 struct dentry *dentry_txstat;
23 struct dentry *dentry_restart;
23 24
24 struct bcm43xx_private *bcm; 25 struct bcm43xx_private *bcm;
25 26
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_dma.c b/drivers/net/wireless/bcm43xx/bcm43xx_dma.c
index d0318e525ba7..76e3aed4b471 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_dma.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_dma.c
@@ -4,7 +4,7 @@
4 4
5 DMA ringbuffer and descriptor allocation/management 5 DMA ringbuffer and descriptor allocation/management
6 6
7 Copyright (c) 2005 Michael Buesch <mbuesch@freenet.de> 7 Copyright (c) 2005, 2006 Michael Buesch <mbuesch@freenet.de>
8 8
9 Some code in this file is derived from the b44.c driver 9 Some code in this file is derived from the b44.c driver
10 Copyright (C) 2002 David S. Miller 10 Copyright (C) 2002 David S. Miller
@@ -109,6 +109,35 @@ void return_slot(struct bcm43xx_dmaring *ring, int slot)
109 } 109 }
110} 110}
111 111
112u16 bcm43xx_dmacontroller_base(int dma64bit, int controller_idx)
113{
114 static const u16 map64[] = {
115 BCM43xx_MMIO_DMA64_BASE0,
116 BCM43xx_MMIO_DMA64_BASE1,
117 BCM43xx_MMIO_DMA64_BASE2,
118 BCM43xx_MMIO_DMA64_BASE3,
119 BCM43xx_MMIO_DMA64_BASE4,
120 BCM43xx_MMIO_DMA64_BASE5,
121 };
122 static const u16 map32[] = {
123 BCM43xx_MMIO_DMA32_BASE0,
124 BCM43xx_MMIO_DMA32_BASE1,
125 BCM43xx_MMIO_DMA32_BASE2,
126 BCM43xx_MMIO_DMA32_BASE3,
127 BCM43xx_MMIO_DMA32_BASE4,
128 BCM43xx_MMIO_DMA32_BASE5,
129 };
130
131 if (dma64bit) {
132 assert(controller_idx >= 0 &&
133 controller_idx < ARRAY_SIZE(map64));
134 return map64[controller_idx];
135 }
136 assert(controller_idx >= 0 &&
137 controller_idx < ARRAY_SIZE(map32));
138 return map32[controller_idx];
139}
140
112static inline 141static inline
113dma_addr_t map_descbuffer(struct bcm43xx_dmaring *ring, 142dma_addr_t map_descbuffer(struct bcm43xx_dmaring *ring,
114 unsigned char *buf, 143 unsigned char *buf,
@@ -172,7 +201,6 @@ void sync_descbuffer_for_device(struct bcm43xx_dmaring *ring,
172/* Unmap and free a descriptor buffer. */ 201/* Unmap and free a descriptor buffer. */
173static inline 202static inline
174void free_descriptor_buffer(struct bcm43xx_dmaring *ring, 203void free_descriptor_buffer(struct bcm43xx_dmaring *ring,
175 struct bcm43xx_dmadesc *desc,
176 struct bcm43xx_dmadesc_meta *meta, 204 struct bcm43xx_dmadesc_meta *meta,
177 int irq_context) 205 int irq_context)
178{ 206{
@@ -188,23 +216,13 @@ static int alloc_ringmemory(struct bcm43xx_dmaring *ring)
188{ 216{
189 struct device *dev = &(ring->bcm->pci_dev->dev); 217 struct device *dev = &(ring->bcm->pci_dev->dev);
190 218
191 ring->vbase = dma_alloc_coherent(dev, BCM43xx_DMA_RINGMEMSIZE, 219 ring->descbase = dma_alloc_coherent(dev, BCM43xx_DMA_RINGMEMSIZE,
192 &(ring->dmabase), GFP_KERNEL); 220 &(ring->dmabase), GFP_KERNEL);
193 if (!ring->vbase) { 221 if (!ring->descbase) {
194 printk(KERN_ERR PFX "DMA ringmemory allocation failed\n"); 222 printk(KERN_ERR PFX "DMA ringmemory allocation failed\n");
195 return -ENOMEM; 223 return -ENOMEM;
196 } 224 }
197 if (ring->dmabase + BCM43xx_DMA_RINGMEMSIZE > BCM43xx_DMA_BUSADDRMAX) { 225 memset(ring->descbase, 0, BCM43xx_DMA_RINGMEMSIZE);
198 printk(KERN_ERR PFX ">>>FATAL ERROR<<< DMA RINGMEMORY >1G "
199 "(0x%llx, len: %lu)\n",
200 (unsigned long long)ring->dmabase,
201 BCM43xx_DMA_RINGMEMSIZE);
202 dma_free_coherent(dev, BCM43xx_DMA_RINGMEMSIZE,
203 ring->vbase, ring->dmabase);
204 return -ENOMEM;
205 }
206 assert(!(ring->dmabase & 0x000003FF));
207 memset(ring->vbase, 0, BCM43xx_DMA_RINGMEMSIZE);
208 226
209 return 0; 227 return 0;
210} 228}
@@ -214,26 +232,34 @@ static void free_ringmemory(struct bcm43xx_dmaring *ring)
214 struct device *dev = &(ring->bcm->pci_dev->dev); 232 struct device *dev = &(ring->bcm->pci_dev->dev);
215 233
216 dma_free_coherent(dev, BCM43xx_DMA_RINGMEMSIZE, 234 dma_free_coherent(dev, BCM43xx_DMA_RINGMEMSIZE,
217 ring->vbase, ring->dmabase); 235 ring->descbase, ring->dmabase);
218} 236}
219 237
220/* Reset the RX DMA channel */ 238/* Reset the RX DMA channel */
221int bcm43xx_dmacontroller_rx_reset(struct bcm43xx_private *bcm, 239int bcm43xx_dmacontroller_rx_reset(struct bcm43xx_private *bcm,
222 u16 mmio_base) 240 u16 mmio_base, int dma64)
223{ 241{
224 int i; 242 int i;
225 u32 value; 243 u32 value;
244 u16 offset;
226 245
227 bcm43xx_write32(bcm, 246 offset = dma64 ? BCM43xx_DMA64_RXCTL : BCM43xx_DMA32_RXCTL;
228 mmio_base + BCM43xx_DMA_RX_CONTROL, 247 bcm43xx_write32(bcm, mmio_base + offset, 0);
229 0x00000000);
230 for (i = 0; i < 1000; i++) { 248 for (i = 0; i < 1000; i++) {
231 value = bcm43xx_read32(bcm, 249 offset = dma64 ? BCM43xx_DMA64_RXSTATUS : BCM43xx_DMA32_RXSTATUS;
232 mmio_base + BCM43xx_DMA_RX_STATUS); 250 value = bcm43xx_read32(bcm, mmio_base + offset);
233 value &= BCM43xx_DMA_RXSTAT_STAT_MASK; 251 if (dma64) {
234 if (value == BCM43xx_DMA_RXSTAT_STAT_DISABLED) { 252 value &= BCM43xx_DMA64_RXSTAT;
235 i = -1; 253 if (value == BCM43xx_DMA64_RXSTAT_DISABLED) {
236 break; 254 i = -1;
255 break;
256 }
257 } else {
258 value &= BCM43xx_DMA32_RXSTATE;
259 if (value == BCM43xx_DMA32_RXSTAT_DISABLED) {
260 i = -1;
261 break;
262 }
237 } 263 }
238 udelay(10); 264 udelay(10);
239 } 265 }
@@ -247,31 +273,47 @@ int bcm43xx_dmacontroller_rx_reset(struct bcm43xx_private *bcm,
247 273
248/* Reset the RX DMA channel */ 274/* Reset the RX DMA channel */
249int bcm43xx_dmacontroller_tx_reset(struct bcm43xx_private *bcm, 275int bcm43xx_dmacontroller_tx_reset(struct bcm43xx_private *bcm,
250 u16 mmio_base) 276 u16 mmio_base, int dma64)
251{ 277{
252 int i; 278 int i;
253 u32 value; 279 u32 value;
280 u16 offset;
254 281
255 for (i = 0; i < 1000; i++) { 282 for (i = 0; i < 1000; i++) {
256 value = bcm43xx_read32(bcm, 283 offset = dma64 ? BCM43xx_DMA64_TXSTATUS : BCM43xx_DMA32_TXSTATUS;
257 mmio_base + BCM43xx_DMA_TX_STATUS); 284 value = bcm43xx_read32(bcm, mmio_base + offset);
258 value &= BCM43xx_DMA_TXSTAT_STAT_MASK; 285 if (dma64) {
259 if (value == BCM43xx_DMA_TXSTAT_STAT_DISABLED || 286 value &= BCM43xx_DMA64_TXSTAT;
260 value == BCM43xx_DMA_TXSTAT_STAT_IDLEWAIT || 287 if (value == BCM43xx_DMA64_TXSTAT_DISABLED ||
261 value == BCM43xx_DMA_TXSTAT_STAT_STOPPED) 288 value == BCM43xx_DMA64_TXSTAT_IDLEWAIT ||
262 break; 289 value == BCM43xx_DMA64_TXSTAT_STOPPED)
290 break;
291 } else {
292 value &= BCM43xx_DMA32_TXSTATE;
293 if (value == BCM43xx_DMA32_TXSTAT_DISABLED ||
294 value == BCM43xx_DMA32_TXSTAT_IDLEWAIT ||
295 value == BCM43xx_DMA32_TXSTAT_STOPPED)
296 break;
297 }
263 udelay(10); 298 udelay(10);
264 } 299 }
265 bcm43xx_write32(bcm, 300 offset = dma64 ? BCM43xx_DMA64_TXCTL : BCM43xx_DMA32_TXCTL;
266 mmio_base + BCM43xx_DMA_TX_CONTROL, 301 bcm43xx_write32(bcm, mmio_base + offset, 0);
267 0x00000000);
268 for (i = 0; i < 1000; i++) { 302 for (i = 0; i < 1000; i++) {
269 value = bcm43xx_read32(bcm, 303 offset = dma64 ? BCM43xx_DMA64_TXSTATUS : BCM43xx_DMA32_TXSTATUS;
270 mmio_base + BCM43xx_DMA_TX_STATUS); 304 value = bcm43xx_read32(bcm, mmio_base + offset);
271 value &= BCM43xx_DMA_TXSTAT_STAT_MASK; 305 if (dma64) {
272 if (value == BCM43xx_DMA_TXSTAT_STAT_DISABLED) { 306 value &= BCM43xx_DMA64_TXSTAT;
273 i = -1; 307 if (value == BCM43xx_DMA64_TXSTAT_DISABLED) {
274 break; 308 i = -1;
309 break;
310 }
311 } else {
312 value &= BCM43xx_DMA32_TXSTATE;
313 if (value == BCM43xx_DMA32_TXSTAT_DISABLED) {
314 i = -1;
315 break;
316 }
275 } 317 }
276 udelay(10); 318 udelay(10);
277 } 319 }
@@ -285,47 +327,98 @@ int bcm43xx_dmacontroller_tx_reset(struct bcm43xx_private *bcm,
285 return 0; 327 return 0;
286} 328}
287 329
330static void fill_descriptor(struct bcm43xx_dmaring *ring,
331 struct bcm43xx_dmadesc_generic *desc,
332 dma_addr_t dmaaddr,
333 u16 bufsize,
334 int start, int end, int irq)
335{
336 int slot;
337
338 slot = bcm43xx_dma_desc2idx(ring, desc);
339 assert(slot >= 0 && slot < ring->nr_slots);
340
341 if (ring->dma64) {
342 u32 ctl0 = 0, ctl1 = 0;
343 u32 addrlo, addrhi;
344 u32 addrext;
345
346 addrlo = (u32)(dmaaddr & 0xFFFFFFFF);
347 addrhi = (((u64)dmaaddr >> 32) & ~BCM43xx_DMA64_ROUTING);
348 addrext = (((u64)dmaaddr >> 32) >> BCM43xx_DMA64_ROUTING_SHIFT);
349 addrhi |= ring->routing;
350 if (slot == ring->nr_slots - 1)
351 ctl0 |= BCM43xx_DMA64_DCTL0_DTABLEEND;
352 if (start)
353 ctl0 |= BCM43xx_DMA64_DCTL0_FRAMESTART;
354 if (end)
355 ctl0 |= BCM43xx_DMA64_DCTL0_FRAMEEND;
356 if (irq)
357 ctl0 |= BCM43xx_DMA64_DCTL0_IRQ;
358 ctl1 |= (bufsize - ring->frameoffset)
359 & BCM43xx_DMA64_DCTL1_BYTECNT;
360 ctl1 |= (addrext << BCM43xx_DMA64_DCTL1_ADDREXT_SHIFT)
361 & BCM43xx_DMA64_DCTL1_ADDREXT_MASK;
362
363 desc->dma64.control0 = cpu_to_le32(ctl0);
364 desc->dma64.control1 = cpu_to_le32(ctl1);
365 desc->dma64.address_low = cpu_to_le32(addrlo);
366 desc->dma64.address_high = cpu_to_le32(addrhi);
367 } else {
368 u32 ctl;
369 u32 addr;
370 u32 addrext;
371
372 addr = (u32)(dmaaddr & ~BCM43xx_DMA32_ROUTING);
373 addrext = (u32)(dmaaddr & BCM43xx_DMA32_ROUTING)
374 >> BCM43xx_DMA32_ROUTING_SHIFT;
375 addr |= ring->routing;
376 ctl = (bufsize - ring->frameoffset)
377 & BCM43xx_DMA32_DCTL_BYTECNT;
378 if (slot == ring->nr_slots - 1)
379 ctl |= BCM43xx_DMA32_DCTL_DTABLEEND;
380 if (start)
381 ctl |= BCM43xx_DMA32_DCTL_FRAMESTART;
382 if (end)
383 ctl |= BCM43xx_DMA32_DCTL_FRAMEEND;
384 if (irq)
385 ctl |= BCM43xx_DMA32_DCTL_IRQ;
386 ctl |= (addrext << BCM43xx_DMA32_DCTL_ADDREXT_SHIFT)
387 & BCM43xx_DMA32_DCTL_ADDREXT_MASK;
388
389 desc->dma32.control = cpu_to_le32(ctl);
390 desc->dma32.address = cpu_to_le32(addr);
391 }
392}
393
288static int setup_rx_descbuffer(struct bcm43xx_dmaring *ring, 394static int setup_rx_descbuffer(struct bcm43xx_dmaring *ring,
289 struct bcm43xx_dmadesc *desc, 395 struct bcm43xx_dmadesc_generic *desc,
290 struct bcm43xx_dmadesc_meta *meta, 396 struct bcm43xx_dmadesc_meta *meta,
291 gfp_t gfp_flags) 397 gfp_t gfp_flags)
292{ 398{
293 struct bcm43xx_rxhdr *rxhdr; 399 struct bcm43xx_rxhdr *rxhdr;
400 struct bcm43xx_hwxmitstatus *xmitstat;
294 dma_addr_t dmaaddr; 401 dma_addr_t dmaaddr;
295 u32 desc_addr;
296 u32 desc_ctl;
297 const int slot = (int)(desc - ring->vbase);
298 struct sk_buff *skb; 402 struct sk_buff *skb;
299 403
300 assert(slot >= 0 && slot < ring->nr_slots);
301 assert(!ring->tx); 404 assert(!ring->tx);
302 405
303 skb = __dev_alloc_skb(ring->rx_buffersize, gfp_flags); 406 skb = __dev_alloc_skb(ring->rx_buffersize, gfp_flags);
304 if (unlikely(!skb)) 407 if (unlikely(!skb))
305 return -ENOMEM; 408 return -ENOMEM;
306 dmaaddr = map_descbuffer(ring, skb->data, ring->rx_buffersize, 0); 409 dmaaddr = map_descbuffer(ring, skb->data, ring->rx_buffersize, 0);
307 if (unlikely(dmaaddr + ring->rx_buffersize > BCM43xx_DMA_BUSADDRMAX)) {
308 unmap_descbuffer(ring, dmaaddr, ring->rx_buffersize, 0);
309 dev_kfree_skb_any(skb);
310 printk(KERN_ERR PFX ">>>FATAL ERROR<<< DMA RX SKB >1G "
311 "(0x%llx, len: %u)\n",
312 (unsigned long long)dmaaddr, ring->rx_buffersize);
313 return -ENOMEM;
314 }
315 meta->skb = skb; 410 meta->skb = skb;
316 meta->dmaaddr = dmaaddr; 411 meta->dmaaddr = dmaaddr;
317 skb->dev = ring->bcm->net_dev; 412 skb->dev = ring->bcm->net_dev;
318 desc_addr = (u32)(dmaaddr + ring->memoffset); 413
319 desc_ctl = (BCM43xx_DMADTOR_BYTECNT_MASK & 414 fill_descriptor(ring, desc, dmaaddr,
320 (u32)(ring->rx_buffersize - ring->frameoffset)); 415 ring->rx_buffersize, 0, 0, 0);
321 if (slot == ring->nr_slots - 1)
322 desc_ctl |= BCM43xx_DMADTOR_DTABLEEND;
323 set_desc_addr(desc, desc_addr);
324 set_desc_ctl(desc, desc_ctl);
325 416
326 rxhdr = (struct bcm43xx_rxhdr *)(skb->data); 417 rxhdr = (struct bcm43xx_rxhdr *)(skb->data);
327 rxhdr->frame_length = 0; 418 rxhdr->frame_length = 0;
328 rxhdr->flags1 = 0; 419 rxhdr->flags1 = 0;
420 xmitstat = (struct bcm43xx_hwxmitstatus *)(skb->data);
421 xmitstat->cookie = 0;
329 422
330 return 0; 423 return 0;
331} 424}
@@ -336,17 +429,17 @@ static int setup_rx_descbuffer(struct bcm43xx_dmaring *ring,
336static int alloc_initial_descbuffers(struct bcm43xx_dmaring *ring) 429static int alloc_initial_descbuffers(struct bcm43xx_dmaring *ring)
337{ 430{
338 int i, err = -ENOMEM; 431 int i, err = -ENOMEM;
339 struct bcm43xx_dmadesc *desc; 432 struct bcm43xx_dmadesc_generic *desc;
340 struct bcm43xx_dmadesc_meta *meta; 433 struct bcm43xx_dmadesc_meta *meta;
341 434
342 for (i = 0; i < ring->nr_slots; i++) { 435 for (i = 0; i < ring->nr_slots; i++) {
343 desc = ring->vbase + i; 436 desc = bcm43xx_dma_idx2desc(ring, i, &meta);
344 meta = ring->meta + i;
345 437
346 err = setup_rx_descbuffer(ring, desc, meta, GFP_KERNEL); 438 err = setup_rx_descbuffer(ring, desc, meta, GFP_KERNEL);
347 if (err) 439 if (err)
348 goto err_unwind; 440 goto err_unwind;
349 } 441 }
442 mb();
350 ring->used_slots = ring->nr_slots; 443 ring->used_slots = ring->nr_slots;
351 err = 0; 444 err = 0;
352out: 445out:
@@ -354,8 +447,7 @@ out:
354 447
355err_unwind: 448err_unwind:
356 for (i--; i >= 0; i--) { 449 for (i--; i >= 0; i--) {
357 desc = ring->vbase + i; 450 desc = bcm43xx_dma_idx2desc(ring, i, &meta);
358 meta = ring->meta + i;
359 451
360 unmap_descbuffer(ring, meta->dmaaddr, ring->rx_buffersize, 0); 452 unmap_descbuffer(ring, meta->dmaaddr, ring->rx_buffersize, 0);
361 dev_kfree_skb(meta->skb); 453 dev_kfree_skb(meta->skb);
@@ -371,27 +463,67 @@ static int dmacontroller_setup(struct bcm43xx_dmaring *ring)
371{ 463{
372 int err = 0; 464 int err = 0;
373 u32 value; 465 u32 value;
466 u32 addrext;
374 467
375 if (ring->tx) { 468 if (ring->tx) {
376 /* Set Transmit Control register to "transmit enable" */ 469 if (ring->dma64) {
377 bcm43xx_dma_write(ring, BCM43xx_DMA_TX_CONTROL, 470 u64 ringbase = (u64)(ring->dmabase);
378 BCM43xx_DMA_TXCTRL_ENABLE); 471
379 /* Set Transmit Descriptor ring address. */ 472 addrext = ((ringbase >> 32) >> BCM43xx_DMA64_ROUTING_SHIFT);
380 bcm43xx_dma_write(ring, BCM43xx_DMA_TX_DESC_RING, 473 value = BCM43xx_DMA64_TXENABLE;
381 ring->dmabase + ring->memoffset); 474 value |= (addrext << BCM43xx_DMA64_TXADDREXT_SHIFT)
475 & BCM43xx_DMA64_TXADDREXT_MASK;
476 bcm43xx_dma_write(ring, BCM43xx_DMA64_TXCTL, value);
477 bcm43xx_dma_write(ring, BCM43xx_DMA64_TXRINGLO,
478 (ringbase & 0xFFFFFFFF));
479 bcm43xx_dma_write(ring, BCM43xx_DMA64_TXRINGHI,
480 ((ringbase >> 32) & ~BCM43xx_DMA64_ROUTING)
481 | ring->routing);
482 } else {
483 u32 ringbase = (u32)(ring->dmabase);
484
485 addrext = (ringbase >> BCM43xx_DMA32_ROUTING_SHIFT);
486 value = BCM43xx_DMA32_TXENABLE;
487 value |= (addrext << BCM43xx_DMA32_TXADDREXT_SHIFT)
488 & BCM43xx_DMA32_TXADDREXT_MASK;
489 bcm43xx_dma_write(ring, BCM43xx_DMA32_TXCTL, value);
490 bcm43xx_dma_write(ring, BCM43xx_DMA32_TXRING,
491 (ringbase & ~BCM43xx_DMA32_ROUTING)
492 | ring->routing);
493 }
382 } else { 494 } else {
383 err = alloc_initial_descbuffers(ring); 495 err = alloc_initial_descbuffers(ring);
384 if (err) 496 if (err)
385 goto out; 497 goto out;
386 /* Set Receive Control "receive enable" and frame offset */ 498 if (ring->dma64) {
387 value = (ring->frameoffset << BCM43xx_DMA_RXCTRL_FRAMEOFF_SHIFT); 499 u64 ringbase = (u64)(ring->dmabase);
388 value |= BCM43xx_DMA_RXCTRL_ENABLE; 500
389 bcm43xx_dma_write(ring, BCM43xx_DMA_RX_CONTROL, value); 501 addrext = ((ringbase >> 32) >> BCM43xx_DMA64_ROUTING_SHIFT);
390 /* Set Receive Descriptor ring address. */ 502 value = (ring->frameoffset << BCM43xx_DMA64_RXFROFF_SHIFT);
391 bcm43xx_dma_write(ring, BCM43xx_DMA_RX_DESC_RING, 503 value |= BCM43xx_DMA64_RXENABLE;
392 ring->dmabase + ring->memoffset); 504 value |= (addrext << BCM43xx_DMA64_RXADDREXT_SHIFT)
393 /* Init the descriptor pointer. */ 505 & BCM43xx_DMA64_RXADDREXT_MASK;
394 bcm43xx_dma_write(ring, BCM43xx_DMA_RX_DESC_INDEX, 200); 506 bcm43xx_dma_write(ring, BCM43xx_DMA64_RXCTL, value);
507 bcm43xx_dma_write(ring, BCM43xx_DMA64_RXRINGLO,
508 (ringbase & 0xFFFFFFFF));
509 bcm43xx_dma_write(ring, BCM43xx_DMA64_RXRINGHI,
510 ((ringbase >> 32) & ~BCM43xx_DMA64_ROUTING)
511 | ring->routing);
512 bcm43xx_dma_write(ring, BCM43xx_DMA64_RXINDEX, 200);
513 } else {
514 u32 ringbase = (u32)(ring->dmabase);
515
516 addrext = (ringbase >> BCM43xx_DMA32_ROUTING_SHIFT);
517 value = (ring->frameoffset << BCM43xx_DMA32_RXFROFF_SHIFT);
518 value |= BCM43xx_DMA32_RXENABLE;
519 value |= (addrext << BCM43xx_DMA32_RXADDREXT_SHIFT)
520 & BCM43xx_DMA32_RXADDREXT_MASK;
521 bcm43xx_dma_write(ring, BCM43xx_DMA32_RXCTL, value);
522 bcm43xx_dma_write(ring, BCM43xx_DMA32_RXRING,
523 (ringbase & ~BCM43xx_DMA32_ROUTING)
524 | ring->routing);
525 bcm43xx_dma_write(ring, BCM43xx_DMA32_RXINDEX, 200);
526 }
395 } 527 }
396 528
397out: 529out:
@@ -402,27 +534,32 @@ out:
402static void dmacontroller_cleanup(struct bcm43xx_dmaring *ring) 534static void dmacontroller_cleanup(struct bcm43xx_dmaring *ring)
403{ 535{
404 if (ring->tx) { 536 if (ring->tx) {
405 bcm43xx_dmacontroller_tx_reset(ring->bcm, ring->mmio_base); 537 bcm43xx_dmacontroller_tx_reset(ring->bcm, ring->mmio_base, ring->dma64);
406 /* Zero out Transmit Descriptor ring address. */ 538 if (ring->dma64) {
407 bcm43xx_dma_write(ring, BCM43xx_DMA_TX_DESC_RING, 0); 539 bcm43xx_dma_write(ring, BCM43xx_DMA64_TXRINGLO, 0);
540 bcm43xx_dma_write(ring, BCM43xx_DMA64_TXRINGHI, 0);
541 } else
542 bcm43xx_dma_write(ring, BCM43xx_DMA32_TXRING, 0);
408 } else { 543 } else {
409 bcm43xx_dmacontroller_rx_reset(ring->bcm, ring->mmio_base); 544 bcm43xx_dmacontroller_rx_reset(ring->bcm, ring->mmio_base, ring->dma64);
410 /* Zero out Receive Descriptor ring address. */ 545 if (ring->dma64) {
411 bcm43xx_dma_write(ring, BCM43xx_DMA_RX_DESC_RING, 0); 546 bcm43xx_dma_write(ring, BCM43xx_DMA64_RXRINGLO, 0);
547 bcm43xx_dma_write(ring, BCM43xx_DMA64_RXRINGHI, 0);
548 } else
549 bcm43xx_dma_write(ring, BCM43xx_DMA32_RXRING, 0);
412 } 550 }
413} 551}
414 552
415static void free_all_descbuffers(struct bcm43xx_dmaring *ring) 553static void free_all_descbuffers(struct bcm43xx_dmaring *ring)
416{ 554{
417 struct bcm43xx_dmadesc *desc; 555 struct bcm43xx_dmadesc_generic *desc;
418 struct bcm43xx_dmadesc_meta *meta; 556 struct bcm43xx_dmadesc_meta *meta;
419 int i; 557 int i;
420 558
421 if (!ring->used_slots) 559 if (!ring->used_slots)
422 return; 560 return;
423 for (i = 0; i < ring->nr_slots; i++) { 561 for (i = 0; i < ring->nr_slots; i++) {
424 desc = ring->vbase + i; 562 desc = bcm43xx_dma_idx2desc(ring, i, &meta);
425 meta = ring->meta + i;
426 563
427 if (!meta->skb) { 564 if (!meta->skb) {
428 assert(ring->tx); 565 assert(ring->tx);
@@ -430,62 +567,67 @@ static void free_all_descbuffers(struct bcm43xx_dmaring *ring)
430 } 567 }
431 if (ring->tx) { 568 if (ring->tx) {
432 unmap_descbuffer(ring, meta->dmaaddr, 569 unmap_descbuffer(ring, meta->dmaaddr,
433 meta->skb->len, 1); 570 meta->skb->len, 1);
434 } else { 571 } else {
435 unmap_descbuffer(ring, meta->dmaaddr, 572 unmap_descbuffer(ring, meta->dmaaddr,
436 ring->rx_buffersize, 0); 573 ring->rx_buffersize, 0);
437 } 574 }
438 free_descriptor_buffer(ring, desc, meta, 0); 575 free_descriptor_buffer(ring, meta, 0);
439 } 576 }
440} 577}
441 578
442/* Main initialization function. */ 579/* Main initialization function. */
443static 580static
444struct bcm43xx_dmaring * bcm43xx_setup_dmaring(struct bcm43xx_private *bcm, 581struct bcm43xx_dmaring * bcm43xx_setup_dmaring(struct bcm43xx_private *bcm,
445 u16 dma_controller_base, 582 int controller_index,
446 int nr_descriptor_slots, 583 int for_tx,
447 int tx) 584 int dma64)
448{ 585{
449 struct bcm43xx_dmaring *ring; 586 struct bcm43xx_dmaring *ring;
450 int err; 587 int err;
588 int nr_slots;
451 589
452 ring = kzalloc(sizeof(*ring), GFP_KERNEL); 590 ring = kzalloc(sizeof(*ring), GFP_KERNEL);
453 if (!ring) 591 if (!ring)
454 goto out; 592 goto out;
455 593
456 ring->meta = kzalloc(sizeof(*ring->meta) * nr_descriptor_slots, 594 nr_slots = BCM43xx_RXRING_SLOTS;
595 if (for_tx)
596 nr_slots = BCM43xx_TXRING_SLOTS;
597
598 ring->meta = kcalloc(nr_slots, sizeof(struct bcm43xx_dmadesc_meta),
457 GFP_KERNEL); 599 GFP_KERNEL);
458 if (!ring->meta) 600 if (!ring->meta)
459 goto err_kfree_ring; 601 goto err_kfree_ring;
460 602
461 ring->memoffset = BCM43xx_DMA_DMABUSADDROFFSET; 603 ring->routing = BCM43xx_DMA32_CLIENTTRANS;
604 if (dma64)
605 ring->routing = BCM43xx_DMA64_CLIENTTRANS;
462#ifdef CONFIG_BCM947XX 606#ifdef CONFIG_BCM947XX
463 if (bcm->pci_dev->bus->number == 0) 607 if (bcm->pci_dev->bus->number == 0)
464 ring->memoffset = 0; 608 ring->routing = dma64 ? BCM43xx_DMA64_NOTRANS : BCM43xx_DMA32_NOTRANS;
465#endif 609#endif
466 610
467 ring->bcm = bcm; 611 ring->bcm = bcm;
468 ring->nr_slots = nr_descriptor_slots; 612 ring->nr_slots = nr_slots;
469 ring->suspend_mark = ring->nr_slots * BCM43xx_TXSUSPEND_PERCENT / 100; 613 ring->suspend_mark = ring->nr_slots * BCM43xx_TXSUSPEND_PERCENT / 100;
470 ring->resume_mark = ring->nr_slots * BCM43xx_TXRESUME_PERCENT / 100; 614 ring->resume_mark = ring->nr_slots * BCM43xx_TXRESUME_PERCENT / 100;
471 assert(ring->suspend_mark < ring->resume_mark); 615 assert(ring->suspend_mark < ring->resume_mark);
472 ring->mmio_base = dma_controller_base; 616 ring->mmio_base = bcm43xx_dmacontroller_base(dma64, controller_index);
473 if (tx) { 617 ring->index = controller_index;
618 ring->dma64 = !!dma64;
619 if (for_tx) {
474 ring->tx = 1; 620 ring->tx = 1;
475 ring->current_slot = -1; 621 ring->current_slot = -1;
476 } else { 622 } else {
477 switch (dma_controller_base) { 623 if (ring->index == 0) {
478 case BCM43xx_MMIO_DMA1_BASE: 624 ring->rx_buffersize = BCM43xx_DMA0_RX_BUFFERSIZE;
479 ring->rx_buffersize = BCM43xx_DMA1_RXBUFFERSIZE; 625 ring->frameoffset = BCM43xx_DMA0_RX_FRAMEOFFSET;
480 ring->frameoffset = BCM43xx_DMA1_RX_FRAMEOFFSET; 626 } else if (ring->index == 3) {
481 break; 627 ring->rx_buffersize = BCM43xx_DMA3_RX_BUFFERSIZE;
482 case BCM43xx_MMIO_DMA4_BASE: 628 ring->frameoffset = BCM43xx_DMA3_RX_FRAMEOFFSET;
483 ring->rx_buffersize = BCM43xx_DMA4_RXBUFFERSIZE; 629 } else
484 ring->frameoffset = BCM43xx_DMA4_RX_FRAMEOFFSET;
485 break;
486 default:
487 assert(0); 630 assert(0);
488 }
489 } 631 }
490 632
491 err = alloc_ringmemory(ring); 633 err = alloc_ringmemory(ring);
@@ -514,7 +656,8 @@ static void bcm43xx_destroy_dmaring(struct bcm43xx_dmaring *ring)
514 if (!ring) 656 if (!ring)
515 return; 657 return;
516 658
517 dprintk(KERN_INFO PFX "DMA 0x%04x (%s) max used slots: %d/%d\n", 659 dprintk(KERN_INFO PFX "DMA-%s 0x%04X (%s) max used slots: %d/%d\n",
660 (ring->dma64) ? "64" : "32",
518 ring->mmio_base, 661 ring->mmio_base,
519 (ring->tx) ? "TX" : "RX", 662 (ring->tx) ? "TX" : "RX",
520 ring->max_used_slots, ring->nr_slots); 663 ring->max_used_slots, ring->nr_slots);
@@ -537,10 +680,15 @@ void bcm43xx_dma_free(struct bcm43xx_private *bcm)
537 return; 680 return;
538 dma = bcm43xx_current_dma(bcm); 681 dma = bcm43xx_current_dma(bcm);
539 682
540 bcm43xx_destroy_dmaring(dma->rx_ring1); 683 bcm43xx_destroy_dmaring(dma->rx_ring3);
541 dma->rx_ring1 = NULL; 684 dma->rx_ring3 = NULL;
542 bcm43xx_destroy_dmaring(dma->rx_ring0); 685 bcm43xx_destroy_dmaring(dma->rx_ring0);
543 dma->rx_ring0 = NULL; 686 dma->rx_ring0 = NULL;
687
688 bcm43xx_destroy_dmaring(dma->tx_ring5);
689 dma->tx_ring5 = NULL;
690 bcm43xx_destroy_dmaring(dma->tx_ring4);
691 dma->tx_ring4 = NULL;
544 bcm43xx_destroy_dmaring(dma->tx_ring3); 692 bcm43xx_destroy_dmaring(dma->tx_ring3);
545 dma->tx_ring3 = NULL; 693 dma->tx_ring3 = NULL;
546 bcm43xx_destroy_dmaring(dma->tx_ring2); 694 bcm43xx_destroy_dmaring(dma->tx_ring2);
@@ -556,48 +704,59 @@ int bcm43xx_dma_init(struct bcm43xx_private *bcm)
556 struct bcm43xx_dma *dma = bcm43xx_current_dma(bcm); 704 struct bcm43xx_dma *dma = bcm43xx_current_dma(bcm);
557 struct bcm43xx_dmaring *ring; 705 struct bcm43xx_dmaring *ring;
558 int err = -ENOMEM; 706 int err = -ENOMEM;
707 int dma64 = 0;
708 u32 sbtmstatehi;
709
710 sbtmstatehi = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATEHIGH);
711 if (sbtmstatehi & BCM43xx_SBTMSTATEHIGH_DMA64BIT)
712 dma64 = 1;
559 713
560 /* setup TX DMA channels. */ 714 /* setup TX DMA channels. */
561 ring = bcm43xx_setup_dmaring(bcm, BCM43xx_MMIO_DMA1_BASE, 715 ring = bcm43xx_setup_dmaring(bcm, 0, 1, dma64);
562 BCM43xx_TXRING_SLOTS, 1);
563 if (!ring) 716 if (!ring)
564 goto out; 717 goto out;
565 dma->tx_ring0 = ring; 718 dma->tx_ring0 = ring;
566 719
567 ring = bcm43xx_setup_dmaring(bcm, BCM43xx_MMIO_DMA2_BASE, 720 ring = bcm43xx_setup_dmaring(bcm, 1, 1, dma64);
568 BCM43xx_TXRING_SLOTS, 1);
569 if (!ring) 721 if (!ring)
570 goto err_destroy_tx0; 722 goto err_destroy_tx0;
571 dma->tx_ring1 = ring; 723 dma->tx_ring1 = ring;
572 724
573 ring = bcm43xx_setup_dmaring(bcm, BCM43xx_MMIO_DMA3_BASE, 725 ring = bcm43xx_setup_dmaring(bcm, 2, 1, dma64);
574 BCM43xx_TXRING_SLOTS, 1);
575 if (!ring) 726 if (!ring)
576 goto err_destroy_tx1; 727 goto err_destroy_tx1;
577 dma->tx_ring2 = ring; 728 dma->tx_ring2 = ring;
578 729
579 ring = bcm43xx_setup_dmaring(bcm, BCM43xx_MMIO_DMA4_BASE, 730 ring = bcm43xx_setup_dmaring(bcm, 3, 1, dma64);
580 BCM43xx_TXRING_SLOTS, 1);
581 if (!ring) 731 if (!ring)
582 goto err_destroy_tx2; 732 goto err_destroy_tx2;
583 dma->tx_ring3 = ring; 733 dma->tx_ring3 = ring;
584 734
585 /* setup RX DMA channels. */ 735 ring = bcm43xx_setup_dmaring(bcm, 4, 1, dma64);
586 ring = bcm43xx_setup_dmaring(bcm, BCM43xx_MMIO_DMA1_BASE,
587 BCM43xx_RXRING_SLOTS, 0);
588 if (!ring) 736 if (!ring)
589 goto err_destroy_tx3; 737 goto err_destroy_tx3;
738 dma->tx_ring4 = ring;
739
740 ring = bcm43xx_setup_dmaring(bcm, 5, 1, dma64);
741 if (!ring)
742 goto err_destroy_tx4;
743 dma->tx_ring5 = ring;
744
745 /* setup RX DMA channels. */
746 ring = bcm43xx_setup_dmaring(bcm, 0, 0, dma64);
747 if (!ring)
748 goto err_destroy_tx5;
590 dma->rx_ring0 = ring; 749 dma->rx_ring0 = ring;
591 750
592 if (bcm->current_core->rev < 5) { 751 if (bcm->current_core->rev < 5) {
593 ring = bcm43xx_setup_dmaring(bcm, BCM43xx_MMIO_DMA4_BASE, 752 ring = bcm43xx_setup_dmaring(bcm, 3, 0, dma64);
594 BCM43xx_RXRING_SLOTS, 0);
595 if (!ring) 753 if (!ring)
596 goto err_destroy_rx0; 754 goto err_destroy_rx0;
597 dma->rx_ring1 = ring; 755 dma->rx_ring3 = ring;
598 } 756 }
599 757
600 dprintk(KERN_INFO PFX "DMA initialized\n"); 758 dprintk(KERN_INFO PFX "%s DMA initialized\n",
759 dma64 ? "64-bit" : "32-bit");
601 err = 0; 760 err = 0;
602out: 761out:
603 return err; 762 return err;
@@ -605,6 +764,12 @@ out:
605err_destroy_rx0: 764err_destroy_rx0:
606 bcm43xx_destroy_dmaring(dma->rx_ring0); 765 bcm43xx_destroy_dmaring(dma->rx_ring0);
607 dma->rx_ring0 = NULL; 766 dma->rx_ring0 = NULL;
767err_destroy_tx5:
768 bcm43xx_destroy_dmaring(dma->tx_ring5);
769 dma->tx_ring5 = NULL;
770err_destroy_tx4:
771 bcm43xx_destroy_dmaring(dma->tx_ring4);
772 dma->tx_ring4 = NULL;
608err_destroy_tx3: 773err_destroy_tx3:
609 bcm43xx_destroy_dmaring(dma->tx_ring3); 774 bcm43xx_destroy_dmaring(dma->tx_ring3);
610 dma->tx_ring3 = NULL; 775 dma->tx_ring3 = NULL;
@@ -624,7 +789,7 @@ err_destroy_tx0:
624static u16 generate_cookie(struct bcm43xx_dmaring *ring, 789static u16 generate_cookie(struct bcm43xx_dmaring *ring,
625 int slot) 790 int slot)
626{ 791{
627 u16 cookie = 0xF000; 792 u16 cookie = 0x1000;
628 793
629 /* Use the upper 4 bits of the cookie as 794 /* Use the upper 4 bits of the cookie as
630 * DMA controller ID and store the slot number 795 * DMA controller ID and store the slot number
@@ -632,21 +797,25 @@ static u16 generate_cookie(struct bcm43xx_dmaring *ring,
632 * Note that the cookie must never be 0, as this 797 * Note that the cookie must never be 0, as this
633 * is a special value used in RX path. 798 * is a special value used in RX path.
634 */ 799 */
635 switch (ring->mmio_base) { 800 switch (ring->index) {
636 default: 801 case 0:
637 assert(0);
638 case BCM43xx_MMIO_DMA1_BASE:
639 cookie = 0xA000; 802 cookie = 0xA000;
640 break; 803 break;
641 case BCM43xx_MMIO_DMA2_BASE: 804 case 1:
642 cookie = 0xB000; 805 cookie = 0xB000;
643 break; 806 break;
644 case BCM43xx_MMIO_DMA3_BASE: 807 case 2:
645 cookie = 0xC000; 808 cookie = 0xC000;
646 break; 809 break;
647 case BCM43xx_MMIO_DMA4_BASE: 810 case 3:
648 cookie = 0xD000; 811 cookie = 0xD000;
649 break; 812 break;
813 case 4:
814 cookie = 0xE000;
815 break;
816 case 5:
817 cookie = 0xF000;
818 break;
650 } 819 }
651 assert(((u16)slot & 0xF000) == 0x0000); 820 assert(((u16)slot & 0xF000) == 0x0000);
652 cookie |= (u16)slot; 821 cookie |= (u16)slot;
@@ -675,6 +844,12 @@ struct bcm43xx_dmaring * parse_cookie(struct bcm43xx_private *bcm,
675 case 0xD000: 844 case 0xD000:
676 ring = dma->tx_ring3; 845 ring = dma->tx_ring3;
677 break; 846 break;
847 case 0xE000:
848 ring = dma->tx_ring4;
849 break;
850 case 0xF000:
851 ring = dma->tx_ring5;
852 break;
678 default: 853 default:
679 assert(0); 854 assert(0);
680 } 855 }
@@ -687,6 +862,9 @@ struct bcm43xx_dmaring * parse_cookie(struct bcm43xx_private *bcm,
687static void dmacontroller_poke_tx(struct bcm43xx_dmaring *ring, 862static void dmacontroller_poke_tx(struct bcm43xx_dmaring *ring,
688 int slot) 863 int slot)
689{ 864{
865 u16 offset;
866 int descsize;
867
690 /* Everything is ready to start. Buffers are DMA mapped and 868 /* Everything is ready to start. Buffers are DMA mapped and
691 * associated with slots. 869 * associated with slots.
692 * "slot" is the last slot of the new frame we want to transmit. 870 * "slot" is the last slot of the new frame we want to transmit.
@@ -694,25 +872,26 @@ static void dmacontroller_poke_tx(struct bcm43xx_dmaring *ring,
694 */ 872 */
695 wmb(); 873 wmb();
696 slot = next_slot(ring, slot); 874 slot = next_slot(ring, slot);
697 bcm43xx_dma_write(ring, BCM43xx_DMA_TX_DESC_INDEX, 875 offset = (ring->dma64) ? BCM43xx_DMA64_TXINDEX : BCM43xx_DMA32_TXINDEX;
698 (u32)(slot * sizeof(struct bcm43xx_dmadesc))); 876 descsize = (ring->dma64) ? sizeof(struct bcm43xx_dmadesc64)
877 : sizeof(struct bcm43xx_dmadesc32);
878 bcm43xx_dma_write(ring, offset,
879 (u32)(slot * descsize));
699} 880}
700 881
701static int dma_tx_fragment(struct bcm43xx_dmaring *ring, 882static void dma_tx_fragment(struct bcm43xx_dmaring *ring,
702 struct sk_buff *skb, 883 struct sk_buff *skb,
703 u8 cur_frag) 884 u8 cur_frag)
704{ 885{
705 int slot; 886 int slot;
706 struct bcm43xx_dmadesc *desc; 887 struct bcm43xx_dmadesc_generic *desc;
707 struct bcm43xx_dmadesc_meta *meta; 888 struct bcm43xx_dmadesc_meta *meta;
708 u32 desc_ctl; 889 dma_addr_t dmaaddr;
709 u32 desc_addr;
710 890
711 assert(skb_shinfo(skb)->nr_frags == 0); 891 assert(skb_shinfo(skb)->nr_frags == 0);
712 892
713 slot = request_slot(ring); 893 slot = request_slot(ring);
714 desc = ring->vbase + slot; 894 desc = bcm43xx_dma_idx2desc(ring, slot, &meta);
715 meta = ring->meta + slot;
716 895
717 /* Add a device specific TX header. */ 896 /* Add a device specific TX header. */
718 assert(skb_headroom(skb) >= sizeof(struct bcm43xx_txhdr)); 897 assert(skb_headroom(skb) >= sizeof(struct bcm43xx_txhdr));
@@ -729,29 +908,14 @@ static int dma_tx_fragment(struct bcm43xx_dmaring *ring,
729 generate_cookie(ring, slot)); 908 generate_cookie(ring, slot));
730 909
731 meta->skb = skb; 910 meta->skb = skb;
732 meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1); 911 dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1);
733 if (unlikely(meta->dmaaddr + skb->len > BCM43xx_DMA_BUSADDRMAX)) { 912 meta->dmaaddr = dmaaddr;
734 return_slot(ring, slot);
735 printk(KERN_ERR PFX ">>>FATAL ERROR<<< DMA TX SKB >1G "
736 "(0x%llx, len: %u)\n",
737 (unsigned long long)meta->dmaaddr, skb->len);
738 return -ENOMEM;
739 }
740 913
741 desc_addr = (u32)(meta->dmaaddr + ring->memoffset); 914 fill_descriptor(ring, desc, dmaaddr,
742 desc_ctl = BCM43xx_DMADTOR_FRAMESTART | BCM43xx_DMADTOR_FRAMEEND; 915 skb->len, 1, 1, 1);
743 desc_ctl |= BCM43xx_DMADTOR_COMPIRQ;
744 desc_ctl |= (BCM43xx_DMADTOR_BYTECNT_MASK &
745 (u32)(meta->skb->len - ring->frameoffset));
746 if (slot == ring->nr_slots - 1)
747 desc_ctl |= BCM43xx_DMADTOR_DTABLEEND;
748 916
749 set_desc_ctl(desc, desc_ctl);
750 set_desc_addr(desc, desc_addr);
751 /* Now transfer the whole frame. */ 917 /* Now transfer the whole frame. */
752 dmacontroller_poke_tx(ring, slot); 918 dmacontroller_poke_tx(ring, slot);
753
754 return 0;
755} 919}
756 920
757int bcm43xx_dma_tx(struct bcm43xx_private *bcm, 921int bcm43xx_dma_tx(struct bcm43xx_private *bcm,
@@ -781,7 +945,6 @@ int bcm43xx_dma_tx(struct bcm43xx_private *bcm,
781 /* Take skb from ieee80211_txb_free */ 945 /* Take skb from ieee80211_txb_free */
782 txb->fragments[i] = NULL; 946 txb->fragments[i] = NULL;
783 dma_tx_fragment(ring, skb, i); 947 dma_tx_fragment(ring, skb, i);
784 //TODO: handle failure of dma_tx_fragment
785 } 948 }
786 ieee80211_txb_free(txb); 949 ieee80211_txb_free(txb);
787 950
@@ -792,23 +955,28 @@ void bcm43xx_dma_handle_xmitstatus(struct bcm43xx_private *bcm,
792 struct bcm43xx_xmitstatus *status) 955 struct bcm43xx_xmitstatus *status)
793{ 956{
794 struct bcm43xx_dmaring *ring; 957 struct bcm43xx_dmaring *ring;
795 struct bcm43xx_dmadesc *desc; 958 struct bcm43xx_dmadesc_generic *desc;
796 struct bcm43xx_dmadesc_meta *meta; 959 struct bcm43xx_dmadesc_meta *meta;
797 int is_last_fragment; 960 int is_last_fragment;
798 int slot; 961 int slot;
962 u32 tmp;
799 963
800 ring = parse_cookie(bcm, status->cookie, &slot); 964 ring = parse_cookie(bcm, status->cookie, &slot);
801 assert(ring); 965 assert(ring);
802 assert(ring->tx); 966 assert(ring->tx);
803 assert(get_desc_ctl(ring->vbase + slot) & BCM43xx_DMADTOR_FRAMESTART);
804 while (1) { 967 while (1) {
805 assert(slot >= 0 && slot < ring->nr_slots); 968 assert(slot >= 0 && slot < ring->nr_slots);
806 desc = ring->vbase + slot; 969 desc = bcm43xx_dma_idx2desc(ring, slot, &meta);
807 meta = ring->meta + slot;
808 970
809 is_last_fragment = !!(get_desc_ctl(desc) & BCM43xx_DMADTOR_FRAMEEND); 971 if (ring->dma64) {
972 tmp = le32_to_cpu(desc->dma64.control0);
973 is_last_fragment = !!(tmp & BCM43xx_DMA64_DCTL0_FRAMEEND);
974 } else {
975 tmp = le32_to_cpu(desc->dma32.control);
976 is_last_fragment = !!(tmp & BCM43xx_DMA32_DCTL_FRAMEEND);
977 }
810 unmap_descbuffer(ring, meta->dmaaddr, meta->skb->len, 1); 978 unmap_descbuffer(ring, meta->dmaaddr, meta->skb->len, 1);
811 free_descriptor_buffer(ring, desc, meta, 1); 979 free_descriptor_buffer(ring, meta, 1);
812 /* Everything belonging to the slot is unmapped 980 /* Everything belonging to the slot is unmapped
813 * and freed, so we can return it. 981 * and freed, so we can return it.
814 */ 982 */
@@ -824,7 +992,7 @@ void bcm43xx_dma_handle_xmitstatus(struct bcm43xx_private *bcm,
824static void dma_rx(struct bcm43xx_dmaring *ring, 992static void dma_rx(struct bcm43xx_dmaring *ring,
825 int *slot) 993 int *slot)
826{ 994{
827 struct bcm43xx_dmadesc *desc; 995 struct bcm43xx_dmadesc_generic *desc;
828 struct bcm43xx_dmadesc_meta *meta; 996 struct bcm43xx_dmadesc_meta *meta;
829 struct bcm43xx_rxhdr *rxhdr; 997 struct bcm43xx_rxhdr *rxhdr;
830 struct sk_buff *skb; 998 struct sk_buff *skb;
@@ -832,13 +1000,12 @@ static void dma_rx(struct bcm43xx_dmaring *ring,
832 int err; 1000 int err;
833 dma_addr_t dmaaddr; 1001 dma_addr_t dmaaddr;
834 1002
835 desc = ring->vbase + *slot; 1003 desc = bcm43xx_dma_idx2desc(ring, *slot, &meta);
836 meta = ring->meta + *slot;
837 1004
838 sync_descbuffer_for_cpu(ring, meta->dmaaddr, ring->rx_buffersize); 1005 sync_descbuffer_for_cpu(ring, meta->dmaaddr, ring->rx_buffersize);
839 skb = meta->skb; 1006 skb = meta->skb;
840 1007
841 if (ring->mmio_base == BCM43xx_MMIO_DMA4_BASE) { 1008 if (ring->index == 3) {
842 /* We received an xmit status. */ 1009 /* We received an xmit status. */
843 struct bcm43xx_hwxmitstatus *hw = (struct bcm43xx_hwxmitstatus *)skb->data; 1010 struct bcm43xx_hwxmitstatus *hw = (struct bcm43xx_hwxmitstatus *)skb->data;
844 struct bcm43xx_xmitstatus stat; 1011 struct bcm43xx_xmitstatus stat;
@@ -894,8 +1061,7 @@ static void dma_rx(struct bcm43xx_dmaring *ring,
894 s32 tmp = len; 1061 s32 tmp = len;
895 1062
896 while (1) { 1063 while (1) {
897 desc = ring->vbase + *slot; 1064 desc = bcm43xx_dma_idx2desc(ring, *slot, &meta);
898 meta = ring->meta + *slot;
899 /* recycle the descriptor buffer. */ 1065 /* recycle the descriptor buffer. */
900 sync_descbuffer_for_device(ring, meta->dmaaddr, 1066 sync_descbuffer_for_device(ring, meta->dmaaddr,
901 ring->rx_buffersize); 1067 ring->rx_buffersize);
@@ -906,8 +1072,8 @@ static void dma_rx(struct bcm43xx_dmaring *ring,
906 break; 1072 break;
907 } 1073 }
908 printkl(KERN_ERR PFX "DMA RX buffer too small " 1074 printkl(KERN_ERR PFX "DMA RX buffer too small "
909 "(len: %u, buffer: %u, nr-dropped: %d)\n", 1075 "(len: %u, buffer: %u, nr-dropped: %d)\n",
910 len, ring->rx_buffersize, cnt); 1076 len, ring->rx_buffersize, cnt);
911 goto drop; 1077 goto drop;
912 } 1078 }
913 len -= IEEE80211_FCS_LEN; 1079 len -= IEEE80211_FCS_LEN;
@@ -945,9 +1111,15 @@ void bcm43xx_dma_rx(struct bcm43xx_dmaring *ring)
945#endif 1111#endif
946 1112
947 assert(!ring->tx); 1113 assert(!ring->tx);
948 status = bcm43xx_dma_read(ring, BCM43xx_DMA_RX_STATUS); 1114 if (ring->dma64) {
949 descptr = (status & BCM43xx_DMA_RXSTAT_DPTR_MASK); 1115 status = bcm43xx_dma_read(ring, BCM43xx_DMA64_RXSTATUS);
950 current_slot = descptr / sizeof(struct bcm43xx_dmadesc); 1116 descptr = (status & BCM43xx_DMA64_RXSTATDPTR);
1117 current_slot = descptr / sizeof(struct bcm43xx_dmadesc64);
1118 } else {
1119 status = bcm43xx_dma_read(ring, BCM43xx_DMA32_RXSTATUS);
1120 descptr = (status & BCM43xx_DMA32_RXDPTR);
1121 current_slot = descptr / sizeof(struct bcm43xx_dmadesc32);
1122 }
951 assert(current_slot >= 0 && current_slot < ring->nr_slots); 1123 assert(current_slot >= 0 && current_slot < ring->nr_slots);
952 1124
953 slot = ring->current_slot; 1125 slot = ring->current_slot;
@@ -958,8 +1130,13 @@ void bcm43xx_dma_rx(struct bcm43xx_dmaring *ring)
958 ring->max_used_slots = used_slots; 1130 ring->max_used_slots = used_slots;
959#endif 1131#endif
960 } 1132 }
961 bcm43xx_dma_write(ring, BCM43xx_DMA_RX_DESC_INDEX, 1133 if (ring->dma64) {
962 (u32)(slot * sizeof(struct bcm43xx_dmadesc))); 1134 bcm43xx_dma_write(ring, BCM43xx_DMA64_RXINDEX,
1135 (u32)(slot * sizeof(struct bcm43xx_dmadesc64)));
1136 } else {
1137 bcm43xx_dma_write(ring, BCM43xx_DMA32_RXINDEX,
1138 (u32)(slot * sizeof(struct bcm43xx_dmadesc32)));
1139 }
963 ring->current_slot = slot; 1140 ring->current_slot = slot;
964} 1141}
965 1142
@@ -967,16 +1144,28 @@ void bcm43xx_dma_tx_suspend(struct bcm43xx_dmaring *ring)
967{ 1144{
968 assert(ring->tx); 1145 assert(ring->tx);
969 bcm43xx_power_saving_ctl_bits(ring->bcm, -1, 1); 1146 bcm43xx_power_saving_ctl_bits(ring->bcm, -1, 1);
970 bcm43xx_dma_write(ring, BCM43xx_DMA_TX_CONTROL, 1147 if (ring->dma64) {
971 bcm43xx_dma_read(ring, BCM43xx_DMA_TX_CONTROL) 1148 bcm43xx_dma_write(ring, BCM43xx_DMA64_TXCTL,
972 | BCM43xx_DMA_TXCTRL_SUSPEND); 1149 bcm43xx_dma_read(ring, BCM43xx_DMA64_TXCTL)
1150 | BCM43xx_DMA64_TXSUSPEND);
1151 } else {
1152 bcm43xx_dma_write(ring, BCM43xx_DMA32_TXCTL,
1153 bcm43xx_dma_read(ring, BCM43xx_DMA32_TXCTL)
1154 | BCM43xx_DMA32_TXSUSPEND);
1155 }
973} 1156}
974 1157
975void bcm43xx_dma_tx_resume(struct bcm43xx_dmaring *ring) 1158void bcm43xx_dma_tx_resume(struct bcm43xx_dmaring *ring)
976{ 1159{
977 assert(ring->tx); 1160 assert(ring->tx);
978 bcm43xx_dma_write(ring, BCM43xx_DMA_TX_CONTROL, 1161 if (ring->dma64) {
979 bcm43xx_dma_read(ring, BCM43xx_DMA_TX_CONTROL) 1162 bcm43xx_dma_write(ring, BCM43xx_DMA64_TXCTL,
980 & ~BCM43xx_DMA_TXCTRL_SUSPEND); 1163 bcm43xx_dma_read(ring, BCM43xx_DMA64_TXCTL)
1164 & ~BCM43xx_DMA64_TXSUSPEND);
1165 } else {
1166 bcm43xx_dma_write(ring, BCM43xx_DMA32_TXCTL,
1167 bcm43xx_dma_read(ring, BCM43xx_DMA32_TXCTL)
1168 & ~BCM43xx_DMA32_TXSUSPEND);
1169 }
981 bcm43xx_power_saving_ctl_bits(ring->bcm, -1, -1); 1170 bcm43xx_power_saving_ctl_bits(ring->bcm, -1, -1);
982} 1171}
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_dma.h b/drivers/net/wireless/bcm43xx/bcm43xx_dma.h
index b7d77638ba8c..e04bcaddd1d0 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_dma.h
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_dma.h
@@ -14,63 +14,179 @@
14#define BCM43xx_DMAIRQ_NONFATALMASK (1 << 13) 14#define BCM43xx_DMAIRQ_NONFATALMASK (1 << 13)
15#define BCM43xx_DMAIRQ_RX_DONE (1 << 16) 15#define BCM43xx_DMAIRQ_RX_DONE (1 << 16)
16 16
17/* DMA controller register offsets. (relative to BCM43xx_DMA#_BASE) */ 17
18#define BCM43xx_DMA_TX_CONTROL 0x00 18/*** 32-bit DMA Engine. ***/
19#define BCM43xx_DMA_TX_DESC_RING 0x04 19
20#define BCM43xx_DMA_TX_DESC_INDEX 0x08 20/* 32-bit DMA controller registers. */
21#define BCM43xx_DMA_TX_STATUS 0x0c 21#define BCM43xx_DMA32_TXCTL 0x00
22#define BCM43xx_DMA_RX_CONTROL 0x10 22#define BCM43xx_DMA32_TXENABLE 0x00000001
23#define BCM43xx_DMA_RX_DESC_RING 0x14 23#define BCM43xx_DMA32_TXSUSPEND 0x00000002
24#define BCM43xx_DMA_RX_DESC_INDEX 0x18 24#define BCM43xx_DMA32_TXLOOPBACK 0x00000004
25#define BCM43xx_DMA_RX_STATUS 0x1c 25#define BCM43xx_DMA32_TXFLUSH 0x00000010
26 26#define BCM43xx_DMA32_TXADDREXT_MASK 0x00030000
27/* DMA controller channel control word values. */ 27#define BCM43xx_DMA32_TXADDREXT_SHIFT 16
28#define BCM43xx_DMA_TXCTRL_ENABLE (1 << 0) 28#define BCM43xx_DMA32_TXRING 0x04
29#define BCM43xx_DMA_TXCTRL_SUSPEND (1 << 1) 29#define BCM43xx_DMA32_TXINDEX 0x08
30#define BCM43xx_DMA_TXCTRL_LOOPBACK (1 << 2) 30#define BCM43xx_DMA32_TXSTATUS 0x0C
31#define BCM43xx_DMA_TXCTRL_FLUSH (1 << 4) 31#define BCM43xx_DMA32_TXDPTR 0x00000FFF
32#define BCM43xx_DMA_RXCTRL_ENABLE (1 << 0) 32#define BCM43xx_DMA32_TXSTATE 0x0000F000
33#define BCM43xx_DMA_RXCTRL_FRAMEOFF_MASK 0x000000fe 33#define BCM43xx_DMA32_TXSTAT_DISABLED 0x00000000
34#define BCM43xx_DMA_RXCTRL_FRAMEOFF_SHIFT 1 34#define BCM43xx_DMA32_TXSTAT_ACTIVE 0x00001000
35#define BCM43xx_DMA_RXCTRL_PIO (1 << 8) 35#define BCM43xx_DMA32_TXSTAT_IDLEWAIT 0x00002000
36/* DMA controller channel status word values. */ 36#define BCM43xx_DMA32_TXSTAT_STOPPED 0x00003000
37#define BCM43xx_DMA_TXSTAT_DPTR_MASK 0x00000fff 37#define BCM43xx_DMA32_TXSTAT_SUSP 0x00004000
38#define BCM43xx_DMA_TXSTAT_STAT_MASK 0x0000f000 38#define BCM43xx_DMA32_TXERROR 0x000F0000
39#define BCM43xx_DMA_TXSTAT_STAT_DISABLED 0x00000000 39#define BCM43xx_DMA32_TXERR_NOERR 0x00000000
40#define BCM43xx_DMA_TXSTAT_STAT_ACTIVE 0x00001000 40#define BCM43xx_DMA32_TXERR_PROT 0x00010000
41#define BCM43xx_DMA_TXSTAT_STAT_IDLEWAIT 0x00002000 41#define BCM43xx_DMA32_TXERR_UNDERRUN 0x00020000
42#define BCM43xx_DMA_TXSTAT_STAT_STOPPED 0x00003000 42#define BCM43xx_DMA32_TXERR_BUFREAD 0x00030000
43#define BCM43xx_DMA_TXSTAT_STAT_SUSP 0x00004000 43#define BCM43xx_DMA32_TXERR_DESCREAD 0x00040000
44#define BCM43xx_DMA_TXSTAT_ERROR_MASK 0x000f0000 44#define BCM43xx_DMA32_TXACTIVE 0xFFF00000
45#define BCM43xx_DMA_TXSTAT_FLUSHED (1 << 20) 45#define BCM43xx_DMA32_RXCTL 0x10
46#define BCM43xx_DMA_RXSTAT_DPTR_MASK 0x00000fff 46#define BCM43xx_DMA32_RXENABLE 0x00000001
47#define BCM43xx_DMA_RXSTAT_STAT_MASK 0x0000f000 47#define BCM43xx_DMA32_RXFROFF_MASK 0x000000FE
48#define BCM43xx_DMA_RXSTAT_STAT_DISABLED 0x00000000 48#define BCM43xx_DMA32_RXFROFF_SHIFT 1
49#define BCM43xx_DMA_RXSTAT_STAT_ACTIVE 0x00001000 49#define BCM43xx_DMA32_RXDIRECTFIFO 0x00000100
50#define BCM43xx_DMA_RXSTAT_STAT_IDLEWAIT 0x00002000 50#define BCM43xx_DMA32_RXADDREXT_MASK 0x00030000
51#define BCM43xx_DMA_RXSTAT_STAT_RESERVED 0x00003000 51#define BCM43xx_DMA32_RXADDREXT_SHIFT 16
52#define BCM43xx_DMA_RXSTAT_STAT_ERRORS 0x00004000 52#define BCM43xx_DMA32_RXRING 0x14
53#define BCM43xx_DMA_RXSTAT_ERROR_MASK 0x000f0000 53#define BCM43xx_DMA32_RXINDEX 0x18
54 54#define BCM43xx_DMA32_RXSTATUS 0x1C
55/* DMA descriptor control field values. */ 55#define BCM43xx_DMA32_RXDPTR 0x00000FFF
56#define BCM43xx_DMADTOR_BYTECNT_MASK 0x00001fff 56#define BCM43xx_DMA32_RXSTATE 0x0000F000
57#define BCM43xx_DMADTOR_DTABLEEND (1 << 28) /* End of descriptor table */ 57#define BCM43xx_DMA32_RXSTAT_DISABLED 0x00000000
58#define BCM43xx_DMADTOR_COMPIRQ (1 << 29) /* IRQ on completion request */ 58#define BCM43xx_DMA32_RXSTAT_ACTIVE 0x00001000
59#define BCM43xx_DMADTOR_FRAMEEND (1 << 30) 59#define BCM43xx_DMA32_RXSTAT_IDLEWAIT 0x00002000
60#define BCM43xx_DMADTOR_FRAMESTART (1 << 31) 60#define BCM43xx_DMA32_RXSTAT_STOPPED 0x00003000
61#define BCM43xx_DMA32_RXERROR 0x000F0000
62#define BCM43xx_DMA32_RXERR_NOERR 0x00000000
63#define BCM43xx_DMA32_RXERR_PROT 0x00010000
64#define BCM43xx_DMA32_RXERR_OVERFLOW 0x00020000
65#define BCM43xx_DMA32_RXERR_BUFWRITE 0x00030000
66#define BCM43xx_DMA32_RXERR_DESCREAD 0x00040000
67#define BCM43xx_DMA32_RXACTIVE 0xFFF00000
68
69/* 32-bit DMA descriptor. */
70struct bcm43xx_dmadesc32 {
71 __le32 control;
72 __le32 address;
73} __attribute__((__packed__));
74#define BCM43xx_DMA32_DCTL_BYTECNT 0x00001FFF
75#define BCM43xx_DMA32_DCTL_ADDREXT_MASK 0x00030000
76#define BCM43xx_DMA32_DCTL_ADDREXT_SHIFT 16
77#define BCM43xx_DMA32_DCTL_DTABLEEND 0x10000000
78#define BCM43xx_DMA32_DCTL_IRQ 0x20000000
79#define BCM43xx_DMA32_DCTL_FRAMEEND 0x40000000
80#define BCM43xx_DMA32_DCTL_FRAMESTART 0x80000000
81
82/* Address field Routing value. */
83#define BCM43xx_DMA32_ROUTING 0xC0000000
84#define BCM43xx_DMA32_ROUTING_SHIFT 30
85#define BCM43xx_DMA32_NOTRANS 0x00000000
86#define BCM43xx_DMA32_CLIENTTRANS 0x40000000
87
88
89
90/*** 64-bit DMA Engine. ***/
91
92/* 64-bit DMA controller registers. */
93#define BCM43xx_DMA64_TXCTL 0x00
94#define BCM43xx_DMA64_TXENABLE 0x00000001
95#define BCM43xx_DMA64_TXSUSPEND 0x00000002
96#define BCM43xx_DMA64_TXLOOPBACK 0x00000004
97#define BCM43xx_DMA64_TXFLUSH 0x00000010
98#define BCM43xx_DMA64_TXADDREXT_MASK 0x00030000
99#define BCM43xx_DMA64_TXADDREXT_SHIFT 16
100#define BCM43xx_DMA64_TXINDEX 0x04
101#define BCM43xx_DMA64_TXRINGLO 0x08
102#define BCM43xx_DMA64_TXRINGHI 0x0C
103#define BCM43xx_DMA64_TXSTATUS 0x10
104#define BCM43xx_DMA64_TXSTATDPTR 0x00001FFF
105#define BCM43xx_DMA64_TXSTAT 0xF0000000
106#define BCM43xx_DMA64_TXSTAT_DISABLED 0x00000000
107#define BCM43xx_DMA64_TXSTAT_ACTIVE 0x10000000
108#define BCM43xx_DMA64_TXSTAT_IDLEWAIT 0x20000000
109#define BCM43xx_DMA64_TXSTAT_STOPPED 0x30000000
110#define BCM43xx_DMA64_TXSTAT_SUSP 0x40000000
111#define BCM43xx_DMA64_TXERROR 0x14
112#define BCM43xx_DMA64_TXERRDPTR 0x0001FFFF
113#define BCM43xx_DMA64_TXERR 0xF0000000
114#define BCM43xx_DMA64_TXERR_NOERR 0x00000000
115#define BCM43xx_DMA64_TXERR_PROT 0x10000000
116#define BCM43xx_DMA64_TXERR_UNDERRUN 0x20000000
117#define BCM43xx_DMA64_TXERR_TRANSFER 0x30000000
118#define BCM43xx_DMA64_TXERR_DESCREAD 0x40000000
119#define BCM43xx_DMA64_TXERR_CORE 0x50000000
120#define BCM43xx_DMA64_RXCTL 0x20
121#define BCM43xx_DMA64_RXENABLE 0x00000001
122#define BCM43xx_DMA64_RXFROFF_MASK 0x000000FE
123#define BCM43xx_DMA64_RXFROFF_SHIFT 1
124#define BCM43xx_DMA64_RXDIRECTFIFO 0x00000100
125#define BCM43xx_DMA64_RXADDREXT_MASK 0x00030000
126#define BCM43xx_DMA64_RXADDREXT_SHIFT 16
127#define BCM43xx_DMA64_RXINDEX 0x24
128#define BCM43xx_DMA64_RXRINGLO 0x28
129#define BCM43xx_DMA64_RXRINGHI 0x2C
130#define BCM43xx_DMA64_RXSTATUS 0x30
131#define BCM43xx_DMA64_RXSTATDPTR 0x00001FFF
132#define BCM43xx_DMA64_RXSTAT 0xF0000000
133#define BCM43xx_DMA64_RXSTAT_DISABLED 0x00000000
134#define BCM43xx_DMA64_RXSTAT_ACTIVE 0x10000000
135#define BCM43xx_DMA64_RXSTAT_IDLEWAIT 0x20000000
136#define BCM43xx_DMA64_RXSTAT_STOPPED 0x30000000
137#define BCM43xx_DMA64_RXSTAT_SUSP 0x40000000
138#define BCM43xx_DMA64_RXERROR 0x34
139#define BCM43xx_DMA64_RXERRDPTR 0x0001FFFF
140#define BCM43xx_DMA64_RXERR 0xF0000000
141#define BCM43xx_DMA64_RXERR_NOERR 0x00000000
142#define BCM43xx_DMA64_RXERR_PROT 0x10000000
143#define BCM43xx_DMA64_RXERR_UNDERRUN 0x20000000
144#define BCM43xx_DMA64_RXERR_TRANSFER 0x30000000
145#define BCM43xx_DMA64_RXERR_DESCREAD 0x40000000
146#define BCM43xx_DMA64_RXERR_CORE 0x50000000
147
148/* 64-bit DMA descriptor. */
149struct bcm43xx_dmadesc64 {
150 __le32 control0;
151 __le32 control1;
152 __le32 address_low;
153 __le32 address_high;
154} __attribute__((__packed__));
155#define BCM43xx_DMA64_DCTL0_DTABLEEND 0x10000000
156#define BCM43xx_DMA64_DCTL0_IRQ 0x20000000
157#define BCM43xx_DMA64_DCTL0_FRAMEEND 0x40000000
158#define BCM43xx_DMA64_DCTL0_FRAMESTART 0x80000000
159#define BCM43xx_DMA64_DCTL1_BYTECNT 0x00001FFF
160#define BCM43xx_DMA64_DCTL1_ADDREXT_MASK 0x00030000
161#define BCM43xx_DMA64_DCTL1_ADDREXT_SHIFT 16
162
163/* Address field Routing value. */
164#define BCM43xx_DMA64_ROUTING 0xC0000000
165#define BCM43xx_DMA64_ROUTING_SHIFT 30
166#define BCM43xx_DMA64_NOTRANS 0x00000000
167#define BCM43xx_DMA64_CLIENTTRANS 0x80000000
168
169
170
171struct bcm43xx_dmadesc_generic {
172 union {
173 struct bcm43xx_dmadesc32 dma32;
174 struct bcm43xx_dmadesc64 dma64;
175 } __attribute__((__packed__));
176} __attribute__((__packed__));
177
61 178
62/* Misc DMA constants */ 179/* Misc DMA constants */
63#define BCM43xx_DMA_RINGMEMSIZE PAGE_SIZE 180#define BCM43xx_DMA_RINGMEMSIZE PAGE_SIZE
64#define BCM43xx_DMA_BUSADDRMAX 0x3FFFFFFF 181#define BCM43xx_DMA0_RX_FRAMEOFFSET 30
65#define BCM43xx_DMA_DMABUSADDROFFSET (1 << 30) 182#define BCM43xx_DMA3_RX_FRAMEOFFSET 0
66#define BCM43xx_DMA1_RX_FRAMEOFFSET 30 183
67#define BCM43xx_DMA4_RX_FRAMEOFFSET 0
68 184
69/* DMA engine tuning knobs */ 185/* DMA engine tuning knobs */
70#define BCM43xx_TXRING_SLOTS 512 186#define BCM43xx_TXRING_SLOTS 512
71#define BCM43xx_RXRING_SLOTS 64 187#define BCM43xx_RXRING_SLOTS 64
72#define BCM43xx_DMA1_RXBUFFERSIZE (2304 + 100) 188#define BCM43xx_DMA0_RX_BUFFERSIZE (2304 + 100)
73#define BCM43xx_DMA4_RXBUFFERSIZE 16 189#define BCM43xx_DMA3_RX_BUFFERSIZE 16
74/* Suspend the tx queue, if less than this percent slots are free. */ 190/* Suspend the tx queue, if less than this percent slots are free. */
75#define BCM43xx_TXSUSPEND_PERCENT 20 191#define BCM43xx_TXSUSPEND_PERCENT 20
76/* Resume the tx queue, if more than this percent slots are free. */ 192/* Resume the tx queue, if more than this percent slots are free. */
@@ -86,17 +202,6 @@ struct bcm43xx_private;
86struct bcm43xx_xmitstatus; 202struct bcm43xx_xmitstatus;
87 203
88 204
89struct bcm43xx_dmadesc {
90 __le32 _control;
91 __le32 _address;
92} __attribute__((__packed__));
93
94/* Macros to access the bcm43xx_dmadesc struct */
95#define get_desc_ctl(desc) le32_to_cpu((desc)->_control)
96#define set_desc_ctl(desc, ctl) do { (desc)->_control = cpu_to_le32(ctl); } while (0)
97#define get_desc_addr(desc) le32_to_cpu((desc)->_address)
98#define set_desc_addr(desc, addr) do { (desc)->_address = cpu_to_le32(addr); } while (0)
99
100struct bcm43xx_dmadesc_meta { 205struct bcm43xx_dmadesc_meta {
101 /* The kernel DMA-able buffer. */ 206 /* The kernel DMA-able buffer. */
102 struct sk_buff *skb; 207 struct sk_buff *skb;
@@ -105,15 +210,14 @@ struct bcm43xx_dmadesc_meta {
105}; 210};
106 211
107struct bcm43xx_dmaring { 212struct bcm43xx_dmaring {
108 struct bcm43xx_private *bcm;
109 /* Kernel virtual base address of the ring memory. */ 213 /* Kernel virtual base address of the ring memory. */
110 struct bcm43xx_dmadesc *vbase; 214 void *descbase;
111 /* DMA memory offset */
112 dma_addr_t memoffset;
113 /* (Unadjusted) DMA base bus-address of the ring memory. */
114 dma_addr_t dmabase;
115 /* Meta data about all descriptors. */ 215 /* Meta data about all descriptors. */
116 struct bcm43xx_dmadesc_meta *meta; 216 struct bcm43xx_dmadesc_meta *meta;
217 /* DMA Routing value. */
218 u32 routing;
219 /* (Unadjusted) DMA base bus-address of the ring memory. */
220 dma_addr_t dmabase;
117 /* Number of descriptor slots in the ring. */ 221 /* Number of descriptor slots in the ring. */
118 int nr_slots; 222 int nr_slots;
119 /* Number of used descriptor slots. */ 223 /* Number of used descriptor slots. */
@@ -127,12 +231,17 @@ struct bcm43xx_dmaring {
127 u32 frameoffset; 231 u32 frameoffset;
128 /* Descriptor buffer size. */ 232 /* Descriptor buffer size. */
129 u16 rx_buffersize; 233 u16 rx_buffersize;
130 /* The MMIO base register of the DMA controller, this 234 /* The MMIO base register of the DMA controller. */
131 * ring is posted to.
132 */
133 u16 mmio_base; 235 u16 mmio_base;
134 u8 tx:1, /* TRUE, if this is a TX ring. */ 236 /* DMA controller index number (0-5). */
135 suspended:1; /* TRUE, if transfers are suspended on this ring. */ 237 int index;
238 /* Boolean. Is this a TX ring? */
239 u8 tx;
240 /* Boolean. 64bit DMA if true, 32bit DMA otherwise. */
241 u8 dma64;
242 /* Boolean. Are transfers suspended on this ring? */
243 u8 suspended;
244 struct bcm43xx_private *bcm;
136#ifdef CONFIG_BCM43XX_DEBUG 245#ifdef CONFIG_BCM43XX_DEBUG
137 /* Maximum number of used slots. */ 246 /* Maximum number of used slots. */
138 int max_used_slots; 247 int max_used_slots;
@@ -141,6 +250,34 @@ struct bcm43xx_dmaring {
141 250
142 251
143static inline 252static inline
253int bcm43xx_dma_desc2idx(struct bcm43xx_dmaring *ring,
254 struct bcm43xx_dmadesc_generic *desc)
255{
256 if (ring->dma64) {
257 struct bcm43xx_dmadesc64 *dd64 = ring->descbase;
258 return (int)(&(desc->dma64) - dd64);
259 } else {
260 struct bcm43xx_dmadesc32 *dd32 = ring->descbase;
261 return (int)(&(desc->dma32) - dd32);
262 }
263}
264
265static inline
266struct bcm43xx_dmadesc_generic * bcm43xx_dma_idx2desc(struct bcm43xx_dmaring *ring,
267 int slot,
268 struct bcm43xx_dmadesc_meta **meta)
269{
270 *meta = &(ring->meta[slot]);
271 if (ring->dma64) {
272 struct bcm43xx_dmadesc64 *dd64 = ring->descbase;
273 return (struct bcm43xx_dmadesc_generic *)(&(dd64[slot]));
274 } else {
275 struct bcm43xx_dmadesc32 *dd32 = ring->descbase;
276 return (struct bcm43xx_dmadesc_generic *)(&(dd32[slot]));
277 }
278}
279
280static inline
144u32 bcm43xx_dma_read(struct bcm43xx_dmaring *ring, 281u32 bcm43xx_dma_read(struct bcm43xx_dmaring *ring,
145 u16 offset) 282 u16 offset)
146{ 283{
@@ -159,9 +296,13 @@ int bcm43xx_dma_init(struct bcm43xx_private *bcm);
159void bcm43xx_dma_free(struct bcm43xx_private *bcm); 296void bcm43xx_dma_free(struct bcm43xx_private *bcm);
160 297
161int bcm43xx_dmacontroller_rx_reset(struct bcm43xx_private *bcm, 298int bcm43xx_dmacontroller_rx_reset(struct bcm43xx_private *bcm,
162 u16 dmacontroller_mmio_base); 299 u16 dmacontroller_mmio_base,
300 int dma64);
163int bcm43xx_dmacontroller_tx_reset(struct bcm43xx_private *bcm, 301int bcm43xx_dmacontroller_tx_reset(struct bcm43xx_private *bcm,
164 u16 dmacontroller_mmio_base); 302 u16 dmacontroller_mmio_base,
303 int dma64);
304
305u16 bcm43xx_dmacontroller_base(int dma64bit, int dmacontroller_idx);
165 306
166void bcm43xx_dma_tx_suspend(struct bcm43xx_dmaring *ring); 307void bcm43xx_dma_tx_suspend(struct bcm43xx_dmaring *ring);
167void bcm43xx_dma_tx_resume(struct bcm43xx_dmaring *ring); 308void bcm43xx_dma_tx_resume(struct bcm43xx_dmaring *ring);
@@ -173,7 +314,6 @@ int bcm43xx_dma_tx(struct bcm43xx_private *bcm,
173 struct ieee80211_txb *txb); 314 struct ieee80211_txb *txb);
174void bcm43xx_dma_rx(struct bcm43xx_dmaring *ring); 315void bcm43xx_dma_rx(struct bcm43xx_dmaring *ring);
175 316
176
177#else /* CONFIG_BCM43XX_DMA */ 317#else /* CONFIG_BCM43XX_DMA */
178 318
179 319
@@ -188,13 +328,15 @@ void bcm43xx_dma_free(struct bcm43xx_private *bcm)
188} 328}
189static inline 329static inline
190int bcm43xx_dmacontroller_rx_reset(struct bcm43xx_private *bcm, 330int bcm43xx_dmacontroller_rx_reset(struct bcm43xx_private *bcm,
191 u16 dmacontroller_mmio_base) 331 u16 dmacontroller_mmio_base,
332 int dma64)
192{ 333{
193 return 0; 334 return 0;
194} 335}
195static inline 336static inline
196int bcm43xx_dmacontroller_tx_reset(struct bcm43xx_private *bcm, 337int bcm43xx_dmacontroller_tx_reset(struct bcm43xx_private *bcm,
197 u16 dmacontroller_mmio_base) 338 u16 dmacontroller_mmio_base,
339 int dma64)
198{ 340{
199 return 0; 341 return 0;
200} 342}
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_leds.c b/drivers/net/wireless/bcm43xx/bcm43xx_leds.c
index ec80692d638a..c3f90c8563d9 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_leds.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_leds.c
@@ -51,12 +51,12 @@ static void bcm43xx_led_blink(unsigned long d)
51 struct bcm43xx_private *bcm = led->bcm; 51 struct bcm43xx_private *bcm = led->bcm;
52 unsigned long flags; 52 unsigned long flags;
53 53
54 bcm43xx_lock_irqonly(bcm, flags); 54 spin_lock_irqsave(&bcm->leds_lock, flags);
55 if (led->blink_interval) { 55 if (led->blink_interval) {
56 bcm43xx_led_changestate(led); 56 bcm43xx_led_changestate(led);
57 mod_timer(&led->blink_timer, jiffies + led->blink_interval); 57 mod_timer(&led->blink_timer, jiffies + led->blink_interval);
58 } 58 }
59 bcm43xx_unlock_irqonly(bcm, flags); 59 spin_unlock_irqrestore(&bcm->leds_lock, flags);
60} 60}
61 61
62static void bcm43xx_led_blink_start(struct bcm43xx_led *led, 62static void bcm43xx_led_blink_start(struct bcm43xx_led *led,
@@ -177,7 +177,9 @@ void bcm43xx_leds_update(struct bcm43xx_private *bcm, int activity)
177 int i, turn_on; 177 int i, turn_on;
178 unsigned long interval = 0; 178 unsigned long interval = 0;
179 u16 ledctl; 179 u16 ledctl;
180 unsigned long flags;
180 181
182 spin_lock_irqsave(&bcm->leds_lock, flags);
181 ledctl = bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_CONTROL); 183 ledctl = bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_CONTROL);
182 for (i = 0; i < BCM43xx_NR_LEDS; i++) { 184 for (i = 0; i < BCM43xx_NR_LEDS; i++) {
183 led = &(bcm->leds[i]); 185 led = &(bcm->leds[i]);
@@ -266,6 +268,7 @@ void bcm43xx_leds_update(struct bcm43xx_private *bcm, int activity)
266 ledctl &= ~(1 << i); 268 ledctl &= ~(1 << i);
267 } 269 }
268 bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_CONTROL, ledctl); 270 bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_CONTROL, ledctl);
271 spin_unlock_irqrestore(&bcm->leds_lock, flags);
269} 272}
270 273
271void bcm43xx_leds_switch_all(struct bcm43xx_private *bcm, int on) 274void bcm43xx_leds_switch_all(struct bcm43xx_private *bcm, int on)
@@ -274,7 +277,9 @@ void bcm43xx_leds_switch_all(struct bcm43xx_private *bcm, int on)
274 u16 ledctl; 277 u16 ledctl;
275 int i; 278 int i;
276 int bit_on; 279 int bit_on;
280 unsigned long flags;
277 281
282 spin_lock_irqsave(&bcm->leds_lock, flags);
278 ledctl = bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_CONTROL); 283 ledctl = bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_CONTROL);
279 for (i = 0; i < BCM43xx_NR_LEDS; i++) { 284 for (i = 0; i < BCM43xx_NR_LEDS; i++) {
280 led = &(bcm->leds[i]); 285 led = &(bcm->leds[i]);
@@ -290,4 +295,5 @@ void bcm43xx_leds_switch_all(struct bcm43xx_private *bcm, int on)
290 ledctl &= ~(1 << i); 295 ledctl &= ~(1 << i);
291 } 296 }
292 bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_CONTROL, ledctl); 297 bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_CONTROL, ledctl);
298 spin_unlock_irqrestore(&bcm->leds_lock, flags);
293} 299}
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/drivers/net/wireless/bcm43xx/bcm43xx_main.c
index df317c1e12a8..966815be6955 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_main.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.c
@@ -509,23 +509,19 @@ static void bcm43xx_synchronize_irq(struct bcm43xx_private *bcm)
509} 509}
510 510
511/* Make sure we don't receive more data from the device. */ 511/* Make sure we don't receive more data from the device. */
512static int bcm43xx_disable_interrupts_sync(struct bcm43xx_private *bcm, u32 *oldstate) 512static int bcm43xx_disable_interrupts_sync(struct bcm43xx_private *bcm)
513{ 513{
514 unsigned long flags; 514 unsigned long flags;
515 u32 old;
516 515
517 bcm43xx_lock_irqonly(bcm, flags); 516 spin_lock_irqsave(&bcm->irq_lock, flags);
518 if (unlikely(bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED)) { 517 if (unlikely(bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED)) {
519 bcm43xx_unlock_irqonly(bcm, flags); 518 spin_unlock_irqrestore(&bcm->irq_lock, flags);
520 return -EBUSY; 519 return -EBUSY;
521 } 520 }
522 old = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL); 521 bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
523 bcm43xx_unlock_irqonly(bcm, flags); 522 spin_unlock_irqrestore(&bcm->irq_lock, flags);
524 bcm43xx_synchronize_irq(bcm); 523 bcm43xx_synchronize_irq(bcm);
525 524
526 if (oldstate)
527 *oldstate = old;
528
529 return 0; 525 return 0;
530} 526}
531 527
@@ -537,7 +533,6 @@ static int bcm43xx_read_radioinfo(struct bcm43xx_private *bcm)
537 u16 manufact; 533 u16 manufact;
538 u16 version; 534 u16 version;
539 u8 revision; 535 u8 revision;
540 s8 i;
541 536
542 if (bcm->chip_id == 0x4317) { 537 if (bcm->chip_id == 0x4317) {
543 if (bcm->chip_rev == 0x00) 538 if (bcm->chip_rev == 0x00)
@@ -580,20 +575,11 @@ static int bcm43xx_read_radioinfo(struct bcm43xx_private *bcm)
580 radio->version = version; 575 radio->version = version;
581 radio->revision = revision; 576 radio->revision = revision;
582 577
583 /* Set default attenuation values. */
584 radio->baseband_atten = bcm43xx_default_baseband_attenuation(bcm);
585 radio->radio_atten = bcm43xx_default_radio_attenuation(bcm);
586 radio->txctl1 = bcm43xx_default_txctl1(bcm);
587 radio->txctl2 = 0xFFFF;
588 if (phy->type == BCM43xx_PHYTYPE_A) 578 if (phy->type == BCM43xx_PHYTYPE_A)
589 radio->txpower_desired = bcm->sprom.maxpower_aphy; 579 radio->txpower_desired = bcm->sprom.maxpower_aphy;
590 else 580 else
591 radio->txpower_desired = bcm->sprom.maxpower_bgphy; 581 radio->txpower_desired = bcm->sprom.maxpower_bgphy;
592 582
593 /* Initialize the in-memory nrssi Lookup Table. */
594 for (i = 0; i < 64; i++)
595 radio->nrssi_lt[i] = i;
596
597 return 0; 583 return 0;
598 584
599err_unsupported_radio: 585err_unsupported_radio:
@@ -1250,10 +1236,6 @@ int bcm43xx_switch_core(struct bcm43xx_private *bcm, struct bcm43xx_coreinfo *ne
1250 goto out; 1236 goto out;
1251 1237
1252 bcm->current_core = new_core; 1238 bcm->current_core = new_core;
1253 bcm->current_80211_core_idx = -1;
1254 if (new_core->id == BCM43xx_COREID_80211)
1255 bcm->current_80211_core_idx = (int)(new_core - &(bcm->core_80211[0]));
1256
1257out: 1239out:
1258 return err; 1240 return err;
1259} 1241}
@@ -1389,6 +1371,7 @@ void bcm43xx_wireless_core_reset(struct bcm43xx_private *bcm, int connect_phy)
1389 if ((bcm43xx_core_enabled(bcm)) && 1371 if ((bcm43xx_core_enabled(bcm)) &&
1390 !bcm43xx_using_pio(bcm)) { 1372 !bcm43xx_using_pio(bcm)) {
1391//FIXME: Do we _really_ want #ifndef CONFIG_BCM947XX here? 1373//FIXME: Do we _really_ want #ifndef CONFIG_BCM947XX here?
1374#if 0
1392#ifndef CONFIG_BCM947XX 1375#ifndef CONFIG_BCM947XX
1393 /* reset all used DMA controllers. */ 1376 /* reset all used DMA controllers. */
1394 bcm43xx_dmacontroller_tx_reset(bcm, BCM43xx_MMIO_DMA1_BASE); 1377 bcm43xx_dmacontroller_tx_reset(bcm, BCM43xx_MMIO_DMA1_BASE);
@@ -1399,6 +1382,7 @@ void bcm43xx_wireless_core_reset(struct bcm43xx_private *bcm, int connect_phy)
1399 if (bcm->current_core->rev < 5) 1382 if (bcm->current_core->rev < 5)
1400 bcm43xx_dmacontroller_rx_reset(bcm, BCM43xx_MMIO_DMA4_BASE); 1383 bcm43xx_dmacontroller_rx_reset(bcm, BCM43xx_MMIO_DMA4_BASE);
1401#endif 1384#endif
1385#endif
1402 } 1386 }
1403 if (bcm43xx_status(bcm) == BCM43xx_STAT_SHUTTINGDOWN) { 1387 if (bcm43xx_status(bcm) == BCM43xx_STAT_SHUTTINGDOWN) {
1404 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, 1388 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD,
@@ -1423,43 +1407,23 @@ static void bcm43xx_wireless_core_disable(struct bcm43xx_private *bcm)
1423 bcm43xx_core_disable(bcm, 0); 1407 bcm43xx_core_disable(bcm, 0);
1424} 1408}
1425 1409
1426/* Mark the current 80211 core inactive. 1410/* Mark the current 80211 core inactive. */
1427 * "active_80211_core" is the other 80211 core, which is used. 1411static void bcm43xx_wireless_core_mark_inactive(struct bcm43xx_private *bcm)
1428 */
1429static int bcm43xx_wireless_core_mark_inactive(struct bcm43xx_private *bcm,
1430 struct bcm43xx_coreinfo *active_80211_core)
1431{ 1412{
1432 u32 sbtmstatelow; 1413 u32 sbtmstatelow;
1433 struct bcm43xx_coreinfo *old_core;
1434 int err = 0;
1435 1414
1436 bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL); 1415 bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
1437 bcm43xx_radio_turn_off(bcm); 1416 bcm43xx_radio_turn_off(bcm);
1438 sbtmstatelow = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW); 1417 sbtmstatelow = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
1439 sbtmstatelow &= ~0x200a0000; 1418 sbtmstatelow &= 0xDFF5FFFF;
1440 sbtmstatelow |= 0xa0000; 1419 sbtmstatelow |= 0x000A0000;
1441 bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow); 1420 bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
1442 udelay(1); 1421 udelay(1);
1443 sbtmstatelow = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW); 1422 sbtmstatelow = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
1444 sbtmstatelow &= ~0xa0000; 1423 sbtmstatelow &= 0xFFF5FFFF;
1445 sbtmstatelow |= 0x80000; 1424 sbtmstatelow |= 0x00080000;
1446 bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow); 1425 bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
1447 udelay(1); 1426 udelay(1);
1448
1449 if (bcm43xx_current_phy(bcm)->type == BCM43xx_PHYTYPE_G) {
1450 old_core = bcm->current_core;
1451 err = bcm43xx_switch_core(bcm, active_80211_core);
1452 if (err)
1453 goto out;
1454 sbtmstatelow = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
1455 sbtmstatelow &= ~0x20000000;
1456 sbtmstatelow |= 0x20000000;
1457 bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
1458 err = bcm43xx_switch_core(bcm, old_core);
1459 }
1460
1461out:
1462 return err;
1463} 1427}
1464 1428
1465static void handle_irq_transmit_status(struct bcm43xx_private *bcm) 1429static void handle_irq_transmit_status(struct bcm43xx_private *bcm)
@@ -1709,8 +1673,9 @@ static void handle_irq_beacon(struct bcm43xx_private *bcm)
1709static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm) 1673static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm)
1710{ 1674{
1711 u32 reason; 1675 u32 reason;
1712 u32 dma_reason[4]; 1676 u32 dma_reason[6];
1713 int activity = 0; 1677 u32 merged_dma_reason = 0;
1678 int i, activity = 0;
1714 unsigned long flags; 1679 unsigned long flags;
1715 1680
1716#ifdef CONFIG_BCM43XX_DEBUG 1681#ifdef CONFIG_BCM43XX_DEBUG
@@ -1720,12 +1685,12 @@ static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm)
1720# define bcmirq_handled(irq) do { /* nothing */ } while (0) 1685# define bcmirq_handled(irq) do { /* nothing */ } while (0)
1721#endif /* CONFIG_BCM43XX_DEBUG*/ 1686#endif /* CONFIG_BCM43XX_DEBUG*/
1722 1687
1723 bcm43xx_lock_irqonly(bcm, flags); 1688 spin_lock_irqsave(&bcm->irq_lock, flags);
1724 reason = bcm->irq_reason; 1689 reason = bcm->irq_reason;
1725 dma_reason[0] = bcm->dma_reason[0]; 1690 for (i = 5; i >= 0; i--) {
1726 dma_reason[1] = bcm->dma_reason[1]; 1691 dma_reason[i] = bcm->dma_reason[i];
1727 dma_reason[2] = bcm->dma_reason[2]; 1692 merged_dma_reason |= dma_reason[i];
1728 dma_reason[3] = bcm->dma_reason[3]; 1693 }
1729 1694
1730 if (unlikely(reason & BCM43xx_IRQ_XMIT_ERROR)) { 1695 if (unlikely(reason & BCM43xx_IRQ_XMIT_ERROR)) {
1731 /* TX error. We get this when Template Ram is written in wrong endianess 1696 /* TX error. We get this when Template Ram is written in wrong endianess
@@ -1736,27 +1701,25 @@ static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm)
1736 printkl(KERN_ERR PFX "FATAL ERROR: BCM43xx_IRQ_XMIT_ERROR\n"); 1701 printkl(KERN_ERR PFX "FATAL ERROR: BCM43xx_IRQ_XMIT_ERROR\n");
1737 bcmirq_handled(BCM43xx_IRQ_XMIT_ERROR); 1702 bcmirq_handled(BCM43xx_IRQ_XMIT_ERROR);
1738 } 1703 }
1739 if (unlikely((dma_reason[0] & BCM43xx_DMAIRQ_FATALMASK) | 1704 if (unlikely(merged_dma_reason & BCM43xx_DMAIRQ_FATALMASK)) {
1740 (dma_reason[1] & BCM43xx_DMAIRQ_FATALMASK) |
1741 (dma_reason[2] & BCM43xx_DMAIRQ_FATALMASK) |
1742 (dma_reason[3] & BCM43xx_DMAIRQ_FATALMASK))) {
1743 printkl(KERN_ERR PFX "FATAL ERROR: Fatal DMA error: " 1705 printkl(KERN_ERR PFX "FATAL ERROR: Fatal DMA error: "
1744 "0x%08X, 0x%08X, 0x%08X, 0x%08X\n", 1706 "0x%08X, 0x%08X, 0x%08X, "
1707 "0x%08X, 0x%08X, 0x%08X\n",
1745 dma_reason[0], dma_reason[1], 1708 dma_reason[0], dma_reason[1],
1746 dma_reason[2], dma_reason[3]); 1709 dma_reason[2], dma_reason[3],
1710 dma_reason[4], dma_reason[5]);
1747 bcm43xx_controller_restart(bcm, "DMA error"); 1711 bcm43xx_controller_restart(bcm, "DMA error");
1748 mmiowb(); 1712 mmiowb();
1749 bcm43xx_unlock_irqonly(bcm, flags); 1713 spin_unlock_irqrestore(&bcm->irq_lock, flags);
1750 return; 1714 return;
1751 } 1715 }
1752 if (unlikely((dma_reason[0] & BCM43xx_DMAIRQ_NONFATALMASK) | 1716 if (unlikely(merged_dma_reason & BCM43xx_DMAIRQ_NONFATALMASK)) {
1753 (dma_reason[1] & BCM43xx_DMAIRQ_NONFATALMASK) |
1754 (dma_reason[2] & BCM43xx_DMAIRQ_NONFATALMASK) |
1755 (dma_reason[3] & BCM43xx_DMAIRQ_NONFATALMASK))) {
1756 printkl(KERN_ERR PFX "DMA error: " 1717 printkl(KERN_ERR PFX "DMA error: "
1757 "0x%08X, 0x%08X, 0x%08X, 0x%08X\n", 1718 "0x%08X, 0x%08X, 0x%08X, "
1719 "0x%08X, 0x%08X, 0x%08X\n",
1758 dma_reason[0], dma_reason[1], 1720 dma_reason[0], dma_reason[1],
1759 dma_reason[2], dma_reason[3]); 1721 dma_reason[2], dma_reason[3],
1722 dma_reason[4], dma_reason[5]);
1760 } 1723 }
1761 1724
1762 if (reason & BCM43xx_IRQ_PS) { 1725 if (reason & BCM43xx_IRQ_PS) {
@@ -1791,8 +1754,6 @@ static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm)
1791 } 1754 }
1792 1755
1793 /* Check the DMA reason registers for received data. */ 1756 /* Check the DMA reason registers for received data. */
1794 assert(!(dma_reason[1] & BCM43xx_DMAIRQ_RX_DONE));
1795 assert(!(dma_reason[2] & BCM43xx_DMAIRQ_RX_DONE));
1796 if (dma_reason[0] & BCM43xx_DMAIRQ_RX_DONE) { 1757 if (dma_reason[0] & BCM43xx_DMAIRQ_RX_DONE) {
1797 if (bcm43xx_using_pio(bcm)) 1758 if (bcm43xx_using_pio(bcm))
1798 bcm43xx_pio_rx(bcm43xx_current_pio(bcm)->queue0); 1759 bcm43xx_pio_rx(bcm43xx_current_pio(bcm)->queue0);
@@ -1800,13 +1761,17 @@ static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm)
1800 bcm43xx_dma_rx(bcm43xx_current_dma(bcm)->rx_ring0); 1761 bcm43xx_dma_rx(bcm43xx_current_dma(bcm)->rx_ring0);
1801 /* We intentionally don't set "activity" to 1, here. */ 1762 /* We intentionally don't set "activity" to 1, here. */
1802 } 1763 }
1764 assert(!(dma_reason[1] & BCM43xx_DMAIRQ_RX_DONE));
1765 assert(!(dma_reason[2] & BCM43xx_DMAIRQ_RX_DONE));
1803 if (dma_reason[3] & BCM43xx_DMAIRQ_RX_DONE) { 1766 if (dma_reason[3] & BCM43xx_DMAIRQ_RX_DONE) {
1804 if (bcm43xx_using_pio(bcm)) 1767 if (bcm43xx_using_pio(bcm))
1805 bcm43xx_pio_rx(bcm43xx_current_pio(bcm)->queue3); 1768 bcm43xx_pio_rx(bcm43xx_current_pio(bcm)->queue3);
1806 else 1769 else
1807 bcm43xx_dma_rx(bcm43xx_current_dma(bcm)->rx_ring1); 1770 bcm43xx_dma_rx(bcm43xx_current_dma(bcm)->rx_ring3);
1808 activity = 1; 1771 activity = 1;
1809 } 1772 }
1773 assert(!(dma_reason[4] & BCM43xx_DMAIRQ_RX_DONE));
1774 assert(!(dma_reason[5] & BCM43xx_DMAIRQ_RX_DONE));
1810 bcmirq_handled(BCM43xx_IRQ_RX); 1775 bcmirq_handled(BCM43xx_IRQ_RX);
1811 1776
1812 if (reason & BCM43xx_IRQ_XMIT_STATUS) { 1777 if (reason & BCM43xx_IRQ_XMIT_STATUS) {
@@ -1834,7 +1799,7 @@ static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm)
1834 bcm43xx_leds_update(bcm, activity); 1799 bcm43xx_leds_update(bcm, activity);
1835 bcm43xx_interrupt_enable(bcm, bcm->irq_savedstate); 1800 bcm43xx_interrupt_enable(bcm, bcm->irq_savedstate);
1836 mmiowb(); 1801 mmiowb();
1837 bcm43xx_unlock_irqonly(bcm, flags); 1802 spin_unlock_irqrestore(&bcm->irq_lock, flags);
1838} 1803}
1839 1804
1840static void pio_irq_workaround(struct bcm43xx_private *bcm, 1805static void pio_irq_workaround(struct bcm43xx_private *bcm,
@@ -1863,14 +1828,18 @@ static void bcm43xx_interrupt_ack(struct bcm43xx_private *bcm, u32 reason)
1863 1828
1864 bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, reason); 1829 bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, reason);
1865 1830
1866 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA1_REASON, 1831 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA0_REASON,
1867 bcm->dma_reason[0]); 1832 bcm->dma_reason[0]);
1868 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA2_REASON, 1833 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA1_REASON,
1869 bcm->dma_reason[1]); 1834 bcm->dma_reason[1]);
1870 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA3_REASON, 1835 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA2_REASON,
1871 bcm->dma_reason[2]); 1836 bcm->dma_reason[2]);
1872 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA4_REASON, 1837 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA3_REASON,
1873 bcm->dma_reason[3]); 1838 bcm->dma_reason[3]);
1839 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA4_REASON,
1840 bcm->dma_reason[4]);
1841 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA5_REASON,
1842 bcm->dma_reason[5]);
1874} 1843}
1875 1844
1876/* Interrupt handler top-half */ 1845/* Interrupt handler top-half */
@@ -1885,14 +1854,8 @@ static irqreturn_t bcm43xx_interrupt_handler(int irq, void *dev_id, struct pt_re
1885 1854
1886 spin_lock(&bcm->irq_lock); 1855 spin_lock(&bcm->irq_lock);
1887 1856
1888 /* Only accept IRQs, if we are initialized properly. 1857 assert(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED);
1889 * This avoids an RX race while initializing. 1858 assert(bcm->current_core->id == BCM43xx_COREID_80211);
1890 * We should probably not enable IRQs before we are initialized
1891 * completely, but some careful work is needed to fix this. I think it
1892 * is best to stay with this cheap workaround for now... .
1893 */
1894 if (unlikely(bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED))
1895 goto out;
1896 1859
1897 reason = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); 1860 reason = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON);
1898 if (reason == 0xffffffff) { 1861 if (reason == 0xffffffff) {
@@ -1904,14 +1867,18 @@ static irqreturn_t bcm43xx_interrupt_handler(int irq, void *dev_id, struct pt_re
1904 if (!reason) 1867 if (!reason)
1905 goto out; 1868 goto out;
1906 1869
1907 bcm->dma_reason[0] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA1_REASON) 1870 bcm->dma_reason[0] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA0_REASON)
1908 & 0x0001dc00; 1871 & 0x0001DC00;
1909 bcm->dma_reason[1] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA2_REASON) 1872 bcm->dma_reason[1] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA1_REASON)
1910 & 0x0000dc00; 1873 & 0x0000DC00;
1911 bcm->dma_reason[2] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA3_REASON) 1874 bcm->dma_reason[2] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA2_REASON)
1912 & 0x0000dc00; 1875 & 0x0000DC00;
1913 bcm->dma_reason[3] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA4_REASON) 1876 bcm->dma_reason[3] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA3_REASON)
1914 & 0x0001dc00; 1877 & 0x0001DC00;
1878 bcm->dma_reason[4] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA4_REASON)
1879 & 0x0000DC00;
1880 bcm->dma_reason[5] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA5_REASON)
1881 & 0x0000DC00;
1915 1882
1916 bcm43xx_interrupt_ack(bcm, reason); 1883 bcm43xx_interrupt_ack(bcm, reason);
1917 1884
@@ -1930,16 +1897,18 @@ out:
1930 1897
1931static void bcm43xx_release_firmware(struct bcm43xx_private *bcm, int force) 1898static void bcm43xx_release_firmware(struct bcm43xx_private *bcm, int force)
1932{ 1899{
1900 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
1901
1933 if (bcm->firmware_norelease && !force) 1902 if (bcm->firmware_norelease && !force)
1934 return; /* Suspending or controller reset. */ 1903 return; /* Suspending or controller reset. */
1935 release_firmware(bcm->ucode); 1904 release_firmware(phy->ucode);
1936 bcm->ucode = NULL; 1905 phy->ucode = NULL;
1937 release_firmware(bcm->pcm); 1906 release_firmware(phy->pcm);
1938 bcm->pcm = NULL; 1907 phy->pcm = NULL;
1939 release_firmware(bcm->initvals0); 1908 release_firmware(phy->initvals0);
1940 bcm->initvals0 = NULL; 1909 phy->initvals0 = NULL;
1941 release_firmware(bcm->initvals1); 1910 release_firmware(phy->initvals1);
1942 bcm->initvals1 = NULL; 1911 phy->initvals1 = NULL;
1943} 1912}
1944 1913
1945static int bcm43xx_request_firmware(struct bcm43xx_private *bcm) 1914static int bcm43xx_request_firmware(struct bcm43xx_private *bcm)
@@ -1950,11 +1919,11 @@ static int bcm43xx_request_firmware(struct bcm43xx_private *bcm)
1950 int nr; 1919 int nr;
1951 char buf[22 + sizeof(modparam_fwpostfix) - 1] = { 0 }; 1920 char buf[22 + sizeof(modparam_fwpostfix) - 1] = { 0 };
1952 1921
1953 if (!bcm->ucode) { 1922 if (!phy->ucode) {
1954 snprintf(buf, ARRAY_SIZE(buf), "bcm43xx_microcode%d%s.fw", 1923 snprintf(buf, ARRAY_SIZE(buf), "bcm43xx_microcode%d%s.fw",
1955 (rev >= 5 ? 5 : rev), 1924 (rev >= 5 ? 5 : rev),
1956 modparam_fwpostfix); 1925 modparam_fwpostfix);
1957 err = request_firmware(&bcm->ucode, buf, &bcm->pci_dev->dev); 1926 err = request_firmware(&phy->ucode, buf, &bcm->pci_dev->dev);
1958 if (err) { 1927 if (err) {
1959 printk(KERN_ERR PFX 1928 printk(KERN_ERR PFX
1960 "Error: Microcode \"%s\" not available or load failed.\n", 1929 "Error: Microcode \"%s\" not available or load failed.\n",
@@ -1963,12 +1932,12 @@ static int bcm43xx_request_firmware(struct bcm43xx_private *bcm)
1963 } 1932 }
1964 } 1933 }
1965 1934
1966 if (!bcm->pcm) { 1935 if (!phy->pcm) {
1967 snprintf(buf, ARRAY_SIZE(buf), 1936 snprintf(buf, ARRAY_SIZE(buf),
1968 "bcm43xx_pcm%d%s.fw", 1937 "bcm43xx_pcm%d%s.fw",
1969 (rev < 5 ? 4 : 5), 1938 (rev < 5 ? 4 : 5),
1970 modparam_fwpostfix); 1939 modparam_fwpostfix);
1971 err = request_firmware(&bcm->pcm, buf, &bcm->pci_dev->dev); 1940 err = request_firmware(&phy->pcm, buf, &bcm->pci_dev->dev);
1972 if (err) { 1941 if (err) {
1973 printk(KERN_ERR PFX 1942 printk(KERN_ERR PFX
1974 "Error: PCM \"%s\" not available or load failed.\n", 1943 "Error: PCM \"%s\" not available or load failed.\n",
@@ -1977,7 +1946,7 @@ static int bcm43xx_request_firmware(struct bcm43xx_private *bcm)
1977 } 1946 }
1978 } 1947 }
1979 1948
1980 if (!bcm->initvals0) { 1949 if (!phy->initvals0) {
1981 if (rev == 2 || rev == 4) { 1950 if (rev == 2 || rev == 4) {
1982 switch (phy->type) { 1951 switch (phy->type) {
1983 case BCM43xx_PHYTYPE_A: 1952 case BCM43xx_PHYTYPE_A:
@@ -2008,20 +1977,20 @@ static int bcm43xx_request_firmware(struct bcm43xx_private *bcm)
2008 snprintf(buf, ARRAY_SIZE(buf), "bcm43xx_initval%02d%s.fw", 1977 snprintf(buf, ARRAY_SIZE(buf), "bcm43xx_initval%02d%s.fw",
2009 nr, modparam_fwpostfix); 1978 nr, modparam_fwpostfix);
2010 1979
2011 err = request_firmware(&bcm->initvals0, buf, &bcm->pci_dev->dev); 1980 err = request_firmware(&phy->initvals0, buf, &bcm->pci_dev->dev);
2012 if (err) { 1981 if (err) {
2013 printk(KERN_ERR PFX 1982 printk(KERN_ERR PFX
2014 "Error: InitVals \"%s\" not available or load failed.\n", 1983 "Error: InitVals \"%s\" not available or load failed.\n",
2015 buf); 1984 buf);
2016 goto error; 1985 goto error;
2017 } 1986 }
2018 if (bcm->initvals0->size % sizeof(struct bcm43xx_initval)) { 1987 if (phy->initvals0->size % sizeof(struct bcm43xx_initval)) {
2019 printk(KERN_ERR PFX "InitVals fileformat error.\n"); 1988 printk(KERN_ERR PFX "InitVals fileformat error.\n");
2020 goto error; 1989 goto error;
2021 } 1990 }
2022 } 1991 }
2023 1992
2024 if (!bcm->initvals1) { 1993 if (!phy->initvals1) {
2025 if (rev >= 5) { 1994 if (rev >= 5) {
2026 u32 sbtmstatehigh; 1995 u32 sbtmstatehigh;
2027 1996
@@ -2043,14 +2012,14 @@ static int bcm43xx_request_firmware(struct bcm43xx_private *bcm)
2043 snprintf(buf, ARRAY_SIZE(buf), "bcm43xx_initval%02d%s.fw", 2012 snprintf(buf, ARRAY_SIZE(buf), "bcm43xx_initval%02d%s.fw",
2044 nr, modparam_fwpostfix); 2013 nr, modparam_fwpostfix);
2045 2014
2046 err = request_firmware(&bcm->initvals1, buf, &bcm->pci_dev->dev); 2015 err = request_firmware(&phy->initvals1, buf, &bcm->pci_dev->dev);
2047 if (err) { 2016 if (err) {
2048 printk(KERN_ERR PFX 2017 printk(KERN_ERR PFX
2049 "Error: InitVals \"%s\" not available or load failed.\n", 2018 "Error: InitVals \"%s\" not available or load failed.\n",
2050 buf); 2019 buf);
2051 goto error; 2020 goto error;
2052 } 2021 }
2053 if (bcm->initvals1->size % sizeof(struct bcm43xx_initval)) { 2022 if (phy->initvals1->size % sizeof(struct bcm43xx_initval)) {
2054 printk(KERN_ERR PFX "InitVals fileformat error.\n"); 2023 printk(KERN_ERR PFX "InitVals fileformat error.\n");
2055 goto error; 2024 goto error;
2056 } 2025 }
@@ -2070,12 +2039,13 @@ err_noinitval:
2070 2039
2071static void bcm43xx_upload_microcode(struct bcm43xx_private *bcm) 2040static void bcm43xx_upload_microcode(struct bcm43xx_private *bcm)
2072{ 2041{
2042 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
2073 const u32 *data; 2043 const u32 *data;
2074 unsigned int i, len; 2044 unsigned int i, len;
2075 2045
2076 /* Upload Microcode. */ 2046 /* Upload Microcode. */
2077 data = (u32 *)(bcm->ucode->data); 2047 data = (u32 *)(phy->ucode->data);
2078 len = bcm->ucode->size / sizeof(u32); 2048 len = phy->ucode->size / sizeof(u32);
2079 bcm43xx_shm_control_word(bcm, BCM43xx_SHM_UCODE, 0x0000); 2049 bcm43xx_shm_control_word(bcm, BCM43xx_SHM_UCODE, 0x0000);
2080 for (i = 0; i < len; i++) { 2050 for (i = 0; i < len; i++) {
2081 bcm43xx_write32(bcm, BCM43xx_MMIO_SHM_DATA, 2051 bcm43xx_write32(bcm, BCM43xx_MMIO_SHM_DATA,
@@ -2084,8 +2054,8 @@ static void bcm43xx_upload_microcode(struct bcm43xx_private *bcm)
2084 } 2054 }
2085 2055
2086 /* Upload PCM data. */ 2056 /* Upload PCM data. */
2087 data = (u32 *)(bcm->pcm->data); 2057 data = (u32 *)(phy->pcm->data);
2088 len = bcm->pcm->size / sizeof(u32); 2058 len = phy->pcm->size / sizeof(u32);
2089 bcm43xx_shm_control_word(bcm, BCM43xx_SHM_PCM, 0x01ea); 2059 bcm43xx_shm_control_word(bcm, BCM43xx_SHM_PCM, 0x01ea);
2090 bcm43xx_write32(bcm, BCM43xx_MMIO_SHM_DATA, 0x00004000); 2060 bcm43xx_write32(bcm, BCM43xx_MMIO_SHM_DATA, 0x00004000);
2091 bcm43xx_shm_control_word(bcm, BCM43xx_SHM_PCM, 0x01eb); 2061 bcm43xx_shm_control_word(bcm, BCM43xx_SHM_PCM, 0x01eb);
@@ -2131,15 +2101,16 @@ err_format:
2131 2101
2132static int bcm43xx_upload_initvals(struct bcm43xx_private *bcm) 2102static int bcm43xx_upload_initvals(struct bcm43xx_private *bcm)
2133{ 2103{
2104 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
2134 int err; 2105 int err;
2135 2106
2136 err = bcm43xx_write_initvals(bcm, (struct bcm43xx_initval *)bcm->initvals0->data, 2107 err = bcm43xx_write_initvals(bcm, (struct bcm43xx_initval *)phy->initvals0->data,
2137 bcm->initvals0->size / sizeof(struct bcm43xx_initval)); 2108 phy->initvals0->size / sizeof(struct bcm43xx_initval));
2138 if (err) 2109 if (err)
2139 goto out; 2110 goto out;
2140 if (bcm->initvals1) { 2111 if (phy->initvals1) {
2141 err = bcm43xx_write_initvals(bcm, (struct bcm43xx_initval *)bcm->initvals1->data, 2112 err = bcm43xx_write_initvals(bcm, (struct bcm43xx_initval *)phy->initvals1->data,
2142 bcm->initvals1->size / sizeof(struct bcm43xx_initval)); 2113 phy->initvals1->size / sizeof(struct bcm43xx_initval));
2143 if (err) 2114 if (err)
2144 goto out; 2115 goto out;
2145 } 2116 }
@@ -2156,9 +2127,7 @@ static struct pci_device_id bcm43xx_47xx_ids[] = {
2156 2127
2157static int bcm43xx_initialize_irq(struct bcm43xx_private *bcm) 2128static int bcm43xx_initialize_irq(struct bcm43xx_private *bcm)
2158{ 2129{
2159 int res; 2130 int err;
2160 unsigned int i;
2161 u32 data;
2162 2131
2163 bcm->irq = bcm->pci_dev->irq; 2132 bcm->irq = bcm->pci_dev->irq;
2164#ifdef CONFIG_BCM947XX 2133#ifdef CONFIG_BCM947XX
@@ -2175,32 +2144,12 @@ static int bcm43xx_initialize_irq(struct bcm43xx_private *bcm)
2175 } 2144 }
2176 } 2145 }
2177#endif 2146#endif
2178 res = request_irq(bcm->irq, bcm43xx_interrupt_handler, 2147 err = request_irq(bcm->irq, bcm43xx_interrupt_handler,
2179 IRQF_SHARED, KBUILD_MODNAME, bcm); 2148 IRQF_SHARED, KBUILD_MODNAME, bcm);
2180 if (res) { 2149 if (err)
2181 printk(KERN_ERR PFX "Cannot register IRQ%d\n", bcm->irq); 2150 printk(KERN_ERR PFX "Cannot register IRQ%d\n", bcm->irq);
2182 return -ENODEV;
2183 }
2184 bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, 0xffffffff);
2185 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, 0x00020402);
2186 i = 0;
2187 while (1) {
2188 data = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON);
2189 if (data == BCM43xx_IRQ_READY)
2190 break;
2191 i++;
2192 if (i >= BCM43xx_IRQWAIT_MAX_RETRIES) {
2193 printk(KERN_ERR PFX "Card IRQ register not responding. "
2194 "Giving up.\n");
2195 free_irq(bcm->irq, bcm);
2196 return -ENODEV;
2197 }
2198 udelay(10);
2199 }
2200 // dummy read
2201 bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON);
2202 2151
2203 return 0; 2152 return err;
2204} 2153}
2205 2154
2206/* Switch to the core used to write the GPIO register. 2155/* Switch to the core used to write the GPIO register.
@@ -2298,13 +2247,17 @@ static int bcm43xx_gpio_cleanup(struct bcm43xx_private *bcm)
2298/* http://bcm-specs.sipsolutions.net/EnableMac */ 2247/* http://bcm-specs.sipsolutions.net/EnableMac */
2299void bcm43xx_mac_enable(struct bcm43xx_private *bcm) 2248void bcm43xx_mac_enable(struct bcm43xx_private *bcm)
2300{ 2249{
2301 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, 2250 bcm->mac_suspended--;
2302 bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD) 2251 assert(bcm->mac_suspended >= 0);
2303 | BCM43xx_SBF_MAC_ENABLED); 2252 if (bcm->mac_suspended == 0) {
2304 bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, BCM43xx_IRQ_READY); 2253 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD,
2305 bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); /* dummy read */ 2254 bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD)
2306 bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); /* dummy read */ 2255 | BCM43xx_SBF_MAC_ENABLED);
2307 bcm43xx_power_saving_ctl_bits(bcm, -1, -1); 2256 bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, BCM43xx_IRQ_READY);
2257 bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); /* dummy read */
2258 bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); /* dummy read */
2259 bcm43xx_power_saving_ctl_bits(bcm, -1, -1);
2260 }
2308} 2261}
2309 2262
2310/* http://bcm-specs.sipsolutions.net/SuspendMAC */ 2263/* http://bcm-specs.sipsolutions.net/SuspendMAC */
@@ -2313,18 +2266,23 @@ void bcm43xx_mac_suspend(struct bcm43xx_private *bcm)
2313 int i; 2266 int i;
2314 u32 tmp; 2267 u32 tmp;
2315 2268
2316 bcm43xx_power_saving_ctl_bits(bcm, -1, 1); 2269 assert(bcm->mac_suspended >= 0);
2317 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, 2270 if (bcm->mac_suspended == 0) {
2318 bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD) 2271 bcm43xx_power_saving_ctl_bits(bcm, -1, 1);
2319 & ~BCM43xx_SBF_MAC_ENABLED); 2272 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD,
2320 bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); /* dummy read */ 2273 bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD)
2321 for (i = 100000; i; i--) { 2274 & ~BCM43xx_SBF_MAC_ENABLED);
2322 tmp = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); 2275 bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); /* dummy read */
2323 if (tmp & BCM43xx_IRQ_READY) 2276 for (i = 10000; i; i--) {
2324 return; 2277 tmp = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON);
2325 udelay(10); 2278 if (tmp & BCM43xx_IRQ_READY)
2279 goto out;
2280 udelay(1);
2281 }
2282 printkl(KERN_ERR PFX "MAC suspend failed\n");
2326 } 2283 }
2327 printkl(KERN_ERR PFX "MAC suspend failed\n"); 2284out:
2285 bcm->mac_suspended++;
2328} 2286}
2329 2287
2330void bcm43xx_set_iwmode(struct bcm43xx_private *bcm, 2288void bcm43xx_set_iwmode(struct bcm43xx_private *bcm,
@@ -2394,7 +2352,6 @@ static void bcm43xx_chip_cleanup(struct bcm43xx_private *bcm)
2394 if (!modparam_noleds) 2352 if (!modparam_noleds)
2395 bcm43xx_leds_exit(bcm); 2353 bcm43xx_leds_exit(bcm);
2396 bcm43xx_gpio_cleanup(bcm); 2354 bcm43xx_gpio_cleanup(bcm);
2397 free_irq(bcm->irq, bcm);
2398 bcm43xx_release_firmware(bcm, 0); 2355 bcm43xx_release_firmware(bcm, 0);
2399} 2356}
2400 2357
@@ -2406,7 +2363,7 @@ static int bcm43xx_chip_init(struct bcm43xx_private *bcm)
2406 struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); 2363 struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
2407 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); 2364 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
2408 int err; 2365 int err;
2409 int tmp; 2366 int i, tmp;
2410 u32 value32; 2367 u32 value32;
2411 u16 value16; 2368 u16 value16;
2412 2369
@@ -2419,13 +2376,26 @@ static int bcm43xx_chip_init(struct bcm43xx_private *bcm)
2419 goto out; 2376 goto out;
2420 bcm43xx_upload_microcode(bcm); 2377 bcm43xx_upload_microcode(bcm);
2421 2378
2422 err = bcm43xx_initialize_irq(bcm); 2379 bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, 0xFFFFFFFF);
2423 if (err) 2380 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, 0x00020402);
2424 goto err_release_fw; 2381 i = 0;
2382 while (1) {
2383 value32 = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON);
2384 if (value32 == BCM43xx_IRQ_READY)
2385 break;
2386 i++;
2387 if (i >= BCM43xx_IRQWAIT_MAX_RETRIES) {
2388 printk(KERN_ERR PFX "IRQ_READY timeout\n");
2389 err = -ENODEV;
2390 goto err_release_fw;
2391 }
2392 udelay(10);
2393 }
2394 bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); /* dummy read */
2425 2395
2426 err = bcm43xx_gpio_init(bcm); 2396 err = bcm43xx_gpio_init(bcm);
2427 if (err) 2397 if (err)
2428 goto err_free_irq; 2398 goto err_release_fw;
2429 2399
2430 err = bcm43xx_upload_initvals(bcm); 2400 err = bcm43xx_upload_initvals(bcm);
2431 if (err) 2401 if (err)
@@ -2489,10 +2459,12 @@ static int bcm43xx_chip_init(struct bcm43xx_private *bcm)
2489 bcm43xx_write32(bcm, 0x018C, 0x02000000); 2459 bcm43xx_write32(bcm, 0x018C, 0x02000000);
2490 } 2460 }
2491 bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, 0x00004000); 2461 bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, 0x00004000);
2492 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA1_IRQ_MASK, 0x0001DC00); 2462 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA0_IRQ_MASK, 0x0001DC00);
2463 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA1_IRQ_MASK, 0x0000DC00);
2493 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA2_IRQ_MASK, 0x0000DC00); 2464 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA2_IRQ_MASK, 0x0000DC00);
2494 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA3_IRQ_MASK, 0x0000DC00); 2465 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA3_IRQ_MASK, 0x0001DC00);
2495 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA4_IRQ_MASK, 0x0001DC00); 2466 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA4_IRQ_MASK, 0x0000DC00);
2467 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA5_IRQ_MASK, 0x0000DC00);
2496 2468
2497 value32 = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW); 2469 value32 = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
2498 value32 |= 0x00100000; 2470 value32 |= 0x00100000;
@@ -2509,8 +2481,6 @@ err_radio_off:
2509 bcm43xx_radio_turn_off(bcm); 2481 bcm43xx_radio_turn_off(bcm);
2510err_gpio_cleanup: 2482err_gpio_cleanup:
2511 bcm43xx_gpio_cleanup(bcm); 2483 bcm43xx_gpio_cleanup(bcm);
2512err_free_irq:
2513 free_irq(bcm->irq, bcm);
2514err_release_fw: 2484err_release_fw:
2515 bcm43xx_release_firmware(bcm, 1); 2485 bcm43xx_release_firmware(bcm, 1);
2516 goto out; 2486 goto out;
@@ -2550,11 +2520,9 @@ static void bcm43xx_init_struct_phyinfo(struct bcm43xx_phyinfo *phy)
2550{ 2520{
2551 /* Initialize a "phyinfo" structure. The structure is already 2521 /* Initialize a "phyinfo" structure. The structure is already
2552 * zeroed out. 2522 * zeroed out.
2523 * This is called on insmod time to initialize members.
2553 */ 2524 */
2554 phy->antenna_diversity = 0xFFFF;
2555 phy->savedpctlreg = 0xFFFF; 2525 phy->savedpctlreg = 0xFFFF;
2556 phy->minlowsig[0] = 0xFFFF;
2557 phy->minlowsig[1] = 0xFFFF;
2558 spin_lock_init(&phy->lock); 2526 spin_lock_init(&phy->lock);
2559} 2527}
2560 2528
@@ -2562,14 +2530,11 @@ static void bcm43xx_init_struct_radioinfo(struct bcm43xx_radioinfo *radio)
2562{ 2530{
2563 /* Initialize a "radioinfo" structure. The structure is already 2531 /* Initialize a "radioinfo" structure. The structure is already
2564 * zeroed out. 2532 * zeroed out.
2533 * This is called on insmod time to initialize members.
2565 */ 2534 */
2566 radio->interfmode = BCM43xx_RADIO_INTERFMODE_NONE; 2535 radio->interfmode = BCM43xx_RADIO_INTERFMODE_NONE;
2567 radio->channel = 0xFF; 2536 radio->channel = 0xFF;
2568 radio->initial_channel = 0xFF; 2537 radio->initial_channel = 0xFF;
2569 radio->lofcal = 0xFFFF;
2570 radio->initval = 0xFFFF;
2571 radio->nrssi[0] = -1000;
2572 radio->nrssi[1] = -1000;
2573} 2538}
2574 2539
2575static int bcm43xx_probe_cores(struct bcm43xx_private *bcm) 2540static int bcm43xx_probe_cores(struct bcm43xx_private *bcm)
@@ -2587,7 +2552,6 @@ static int bcm43xx_probe_cores(struct bcm43xx_private *bcm)
2587 * BCM43xx_MAX_80211_CORES); 2552 * BCM43xx_MAX_80211_CORES);
2588 memset(&bcm->core_80211_ext, 0, sizeof(struct bcm43xx_coreinfo_80211) 2553 memset(&bcm->core_80211_ext, 0, sizeof(struct bcm43xx_coreinfo_80211)
2589 * BCM43xx_MAX_80211_CORES); 2554 * BCM43xx_MAX_80211_CORES);
2590 bcm->current_80211_core_idx = -1;
2591 bcm->nr_80211_available = 0; 2555 bcm->nr_80211_available = 0;
2592 bcm->current_core = NULL; 2556 bcm->current_core = NULL;
2593 bcm->active_80211_core = NULL; 2557 bcm->active_80211_core = NULL;
@@ -2757,6 +2721,7 @@ static int bcm43xx_probe_cores(struct bcm43xx_private *bcm)
2757 goto out; 2721 goto out;
2758 } 2722 }
2759 bcm->nr_80211_available++; 2723 bcm->nr_80211_available++;
2724 core->priv = ext_80211;
2760 bcm43xx_init_struct_phyinfo(&ext_80211->phy); 2725 bcm43xx_init_struct_phyinfo(&ext_80211->phy);
2761 bcm43xx_init_struct_radioinfo(&ext_80211->radio); 2726 bcm43xx_init_struct_radioinfo(&ext_80211->radio);
2762 break; 2727 break;
@@ -2857,7 +2822,8 @@ static void bcm43xx_wireless_core_cleanup(struct bcm43xx_private *bcm)
2857} 2822}
2858 2823
2859/* http://bcm-specs.sipsolutions.net/80211Init */ 2824/* http://bcm-specs.sipsolutions.net/80211Init */
2860static int bcm43xx_wireless_core_init(struct bcm43xx_private *bcm) 2825static int bcm43xx_wireless_core_init(struct bcm43xx_private *bcm,
2826 int active_wlcore)
2861{ 2827{
2862 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); 2828 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
2863 struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); 2829 struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
@@ -2939,19 +2905,26 @@ static int bcm43xx_wireless_core_init(struct bcm43xx_private *bcm)
2939 if (bcm->current_core->rev >= 5) 2905 if (bcm->current_core->rev >= 5)
2940 bcm43xx_write16(bcm, 0x043C, 0x000C); 2906 bcm43xx_write16(bcm, 0x043C, 0x000C);
2941 2907
2942 if (bcm43xx_using_pio(bcm)) 2908 if (active_wlcore) {
2943 err = bcm43xx_pio_init(bcm); 2909 if (bcm43xx_using_pio(bcm))
2944 else 2910 err = bcm43xx_pio_init(bcm);
2945 err = bcm43xx_dma_init(bcm); 2911 else
2946 if (err) 2912 err = bcm43xx_dma_init(bcm);
2947 goto err_chip_cleanup; 2913 if (err)
2914 goto err_chip_cleanup;
2915 }
2948 bcm43xx_write16(bcm, 0x0612, 0x0050); 2916 bcm43xx_write16(bcm, 0x0612, 0x0050);
2949 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0416, 0x0050); 2917 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0416, 0x0050);
2950 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0414, 0x01F4); 2918 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0414, 0x01F4);
2951 2919
2952 bcm43xx_mac_enable(bcm); 2920 if (active_wlcore) {
2953 bcm43xx_interrupt_enable(bcm, bcm->irq_savedstate); 2921 if (radio->initial_channel != 0xFF)
2922 bcm43xx_radio_selectchannel(bcm, radio->initial_channel, 0);
2923 }
2954 2924
2925 /* Don't enable MAC/IRQ here, as it will race with the IRQ handler.
2926 * We enable it later.
2927 */
2955 bcm->current_core->initialized = 1; 2928 bcm->current_core->initialized = 1;
2956out: 2929out:
2957 return err; 2930 return err;
@@ -3066,11 +3039,6 @@ out:
3066 return err; 3039 return err;
3067} 3040}
3068 3041
3069static void bcm43xx_softmac_init(struct bcm43xx_private *bcm)
3070{
3071 ieee80211softmac_start(bcm->net_dev);
3072}
3073
3074static void bcm43xx_periodic_every120sec(struct bcm43xx_private *bcm) 3042static void bcm43xx_periodic_every120sec(struct bcm43xx_private *bcm)
3075{ 3043{
3076 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); 3044 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
@@ -3182,39 +3150,40 @@ static void bcm43xx_periodic_work_handler(void *d)
3182 /* Periodic work will take a long time, so we want it to 3150 /* Periodic work will take a long time, so we want it to
3183 * be preemtible. 3151 * be preemtible.
3184 */ 3152 */
3185 bcm43xx_lock_irqonly(bcm, flags);
3186 netif_stop_queue(bcm->net_dev); 3153 netif_stop_queue(bcm->net_dev);
3154 synchronize_net();
3155 spin_lock_irqsave(&bcm->irq_lock, flags);
3156 bcm43xx_mac_suspend(bcm);
3187 if (bcm43xx_using_pio(bcm)) 3157 if (bcm43xx_using_pio(bcm))
3188 bcm43xx_pio_freeze_txqueues(bcm); 3158 bcm43xx_pio_freeze_txqueues(bcm);
3189 savedirqs = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL); 3159 savedirqs = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
3190 bcm43xx_unlock_irqonly(bcm, flags); 3160 spin_unlock_irqrestore(&bcm->irq_lock, flags);
3191 bcm43xx_lock_noirq(bcm); 3161 mutex_lock(&bcm->mutex);
3192 bcm43xx_synchronize_irq(bcm); 3162 bcm43xx_synchronize_irq(bcm);
3193 } else { 3163 } else {
3194 /* Periodic work should take short time, so we want low 3164 /* Periodic work should take short time, so we want low
3195 * locking overhead. 3165 * locking overhead.
3196 */ 3166 */
3197 bcm43xx_lock_irqsafe(bcm, flags); 3167 mutex_lock(&bcm->mutex);
3168 spin_lock_irqsave(&bcm->irq_lock, flags);
3198 } 3169 }
3199 3170
3200 do_periodic_work(bcm); 3171 do_periodic_work(bcm);
3201 3172
3202 if (badness > BADNESS_LIMIT) { 3173 if (badness > BADNESS_LIMIT) {
3203 bcm43xx_lock_irqonly(bcm, flags); 3174 spin_lock_irqsave(&bcm->irq_lock, flags);
3204 if (likely(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED)) { 3175 if (likely(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED)) {
3205 tasklet_enable(&bcm->isr_tasklet); 3176 tasklet_enable(&bcm->isr_tasklet);
3206 bcm43xx_interrupt_enable(bcm, savedirqs); 3177 bcm43xx_interrupt_enable(bcm, savedirqs);
3207 if (bcm43xx_using_pio(bcm)) 3178 if (bcm43xx_using_pio(bcm))
3208 bcm43xx_pio_thaw_txqueues(bcm); 3179 bcm43xx_pio_thaw_txqueues(bcm);
3180 bcm43xx_mac_enable(bcm);
3209 } 3181 }
3210 netif_wake_queue(bcm->net_dev); 3182 netif_wake_queue(bcm->net_dev);
3211 mmiowb();
3212 bcm43xx_unlock_irqonly(bcm, flags);
3213 bcm43xx_unlock_noirq(bcm);
3214 } else {
3215 mmiowb();
3216 bcm43xx_unlock_irqsafe(bcm, flags);
3217 } 3183 }
3184 mmiowb();
3185 spin_unlock_irqrestore(&bcm->irq_lock, flags);
3186 mutex_unlock(&bcm->mutex);
3218} 3187}
3219 3188
3220static void bcm43xx_periodic_tasks_delete(struct bcm43xx_private *bcm) 3189static void bcm43xx_periodic_tasks_delete(struct bcm43xx_private *bcm)
@@ -3243,9 +3212,9 @@ static int bcm43xx_rng_read(struct hwrng *rng, u32 *data)
3243 struct bcm43xx_private *bcm = (struct bcm43xx_private *)rng->priv; 3212 struct bcm43xx_private *bcm = (struct bcm43xx_private *)rng->priv;
3244 unsigned long flags; 3213 unsigned long flags;
3245 3214
3246 bcm43xx_lock_irqonly(bcm, flags); 3215 spin_lock_irqsave(&(bcm)->irq_lock, flags);
3247 *data = bcm43xx_read16(bcm, BCM43xx_MMIO_RNG); 3216 *data = bcm43xx_read16(bcm, BCM43xx_MMIO_RNG);
3248 bcm43xx_unlock_irqonly(bcm, flags); 3217 spin_unlock_irqrestore(&(bcm)->irq_lock, flags);
3249 3218
3250 return (sizeof(u16)); 3219 return (sizeof(u16));
3251} 3220}
@@ -3271,139 +3240,330 @@ static int bcm43xx_rng_init(struct bcm43xx_private *bcm)
3271 return err; 3240 return err;
3272} 3241}
3273 3242
3274/* This is the opposite of bcm43xx_init_board() */ 3243static int bcm43xx_shutdown_all_wireless_cores(struct bcm43xx_private *bcm)
3275static void bcm43xx_free_board(struct bcm43xx_private *bcm)
3276{ 3244{
3245 int ret = 0;
3277 int i, err; 3246 int i, err;
3247 struct bcm43xx_coreinfo *core;
3248
3249 bcm43xx_set_status(bcm, BCM43xx_STAT_SHUTTINGDOWN);
3250 for (i = 0; i < bcm->nr_80211_available; i++) {
3251 core = &(bcm->core_80211[i]);
3252 assert(core->available);
3253 if (!core->initialized)
3254 continue;
3255 err = bcm43xx_switch_core(bcm, core);
3256 if (err) {
3257 dprintk(KERN_ERR PFX "shutdown_all_wireless_cores "
3258 "switch_core failed (%d)\n", err);
3259 ret = err;
3260 continue;
3261 }
3262 bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
3263 bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); /* dummy read */
3264 bcm43xx_wireless_core_cleanup(bcm);
3265 if (core == bcm->active_80211_core)
3266 bcm->active_80211_core = NULL;
3267 }
3268 free_irq(bcm->irq, bcm);
3269 bcm43xx_set_status(bcm, BCM43xx_STAT_UNINIT);
3278 3270
3279 bcm43xx_lock_noirq(bcm); 3271 return ret;
3272}
3273
3274/* This is the opposite of bcm43xx_init_board() */
3275static void bcm43xx_free_board(struct bcm43xx_private *bcm)
3276{
3277 bcm43xx_rng_exit(bcm);
3280 bcm43xx_sysfs_unregister(bcm); 3278 bcm43xx_sysfs_unregister(bcm);
3281 bcm43xx_periodic_tasks_delete(bcm); 3279 bcm43xx_periodic_tasks_delete(bcm);
3282 3280
3283 bcm43xx_set_status(bcm, BCM43xx_STAT_SHUTTINGDOWN); 3281 mutex_lock(&(bcm)->mutex);
3282 bcm43xx_shutdown_all_wireless_cores(bcm);
3283 bcm43xx_pctl_set_crystal(bcm, 0);
3284 mutex_unlock(&(bcm)->mutex);
3285}
3284 3286
3285 bcm43xx_rng_exit(bcm); 3287static void prepare_phydata_for_init(struct bcm43xx_phyinfo *phy)
3288{
3289 phy->antenna_diversity = 0xFFFF;
3290 memset(phy->minlowsig, 0xFF, sizeof(phy->minlowsig));
3291 memset(phy->minlowsigpos, 0, sizeof(phy->minlowsigpos));
3292
3293 /* Flags */
3294 phy->calibrated = 0;
3295 phy->is_locked = 0;
3296
3297 if (phy->_lo_pairs) {
3298 memset(phy->_lo_pairs, 0,
3299 sizeof(struct bcm43xx_lopair) * BCM43xx_LO_COUNT);
3300 }
3301 memset(phy->loopback_gain, 0, sizeof(phy->loopback_gain));
3302}
3303
3304static void prepare_radiodata_for_init(struct bcm43xx_private *bcm,
3305 struct bcm43xx_radioinfo *radio)
3306{
3307 int i;
3308
3309 /* Set default attenuation values. */
3310 radio->baseband_atten = bcm43xx_default_baseband_attenuation(bcm);
3311 radio->radio_atten = bcm43xx_default_radio_attenuation(bcm);
3312 radio->txctl1 = bcm43xx_default_txctl1(bcm);
3313 radio->txctl2 = 0xFFFF;
3314 radio->txpwr_offset = 0;
3315
3316 /* NRSSI */
3317 radio->nrssislope = 0;
3318 for (i = 0; i < ARRAY_SIZE(radio->nrssi); i++)
3319 radio->nrssi[i] = -1000;
3320 for (i = 0; i < ARRAY_SIZE(radio->nrssi_lt); i++)
3321 radio->nrssi_lt[i] = i;
3322
3323 radio->lofcal = 0xFFFF;
3324 radio->initval = 0xFFFF;
3325
3326 radio->aci_enable = 0;
3327 radio->aci_wlan_automatic = 0;
3328 radio->aci_hw_rssi = 0;
3329}
3330
3331static void prepare_priv_for_init(struct bcm43xx_private *bcm)
3332{
3333 int i;
3334 struct bcm43xx_coreinfo *core;
3335 struct bcm43xx_coreinfo_80211 *wlext;
3336
3337 assert(!bcm->active_80211_core);
3338
3339 bcm43xx_set_status(bcm, BCM43xx_STAT_INITIALIZING);
3340
3341 /* Flags */
3342 bcm->was_initialized = 0;
3343 bcm->reg124_set_0x4 = 0;
3344
3345 /* Stats */
3346 memset(&bcm->stats, 0, sizeof(bcm->stats));
3347
3348 /* Wireless core data */
3286 for (i = 0; i < BCM43xx_MAX_80211_CORES; i++) { 3349 for (i = 0; i < BCM43xx_MAX_80211_CORES; i++) {
3287 if (!bcm->core_80211[i].available) 3350 core = &(bcm->core_80211[i]);
3288 continue; 3351 wlext = core->priv;
3289 if (!bcm->core_80211[i].initialized) 3352
3353 if (!core->available)
3290 continue; 3354 continue;
3355 assert(wlext == &(bcm->core_80211_ext[i]));
3291 3356
3292 err = bcm43xx_switch_core(bcm, &bcm->core_80211[i]); 3357 prepare_phydata_for_init(&wlext->phy);
3293 assert(err == 0); 3358 prepare_radiodata_for_init(bcm, &wlext->radio);
3294 bcm43xx_wireless_core_cleanup(bcm);
3295 } 3359 }
3296 3360
3297 bcm43xx_pctl_set_crystal(bcm, 0); 3361 /* IRQ related flags */
3362 bcm->irq_reason = 0;
3363 memset(bcm->dma_reason, 0, sizeof(bcm->dma_reason));
3364 bcm->irq_savedstate = BCM43xx_IRQ_INITIAL;
3298 3365
3299 bcm43xx_set_status(bcm, BCM43xx_STAT_UNINIT); 3366 bcm->mac_suspended = 1;
3300 bcm43xx_unlock_noirq(bcm); 3367
3368 /* Noise calculation context */
3369 memset(&bcm->noisecalc, 0, sizeof(bcm->noisecalc));
3370
3371 /* Periodic work context */
3372 bcm->periodic_state = 0;
3301} 3373}
3302 3374
3303static int bcm43xx_init_board(struct bcm43xx_private *bcm) 3375static int wireless_core_up(struct bcm43xx_private *bcm,
3376 int active_wlcore)
3377{
3378 int err;
3379
3380 if (!bcm43xx_core_enabled(bcm))
3381 bcm43xx_wireless_core_reset(bcm, 1);
3382 if (!active_wlcore)
3383 bcm43xx_wireless_core_mark_inactive(bcm);
3384 err = bcm43xx_wireless_core_init(bcm, active_wlcore);
3385 if (err)
3386 goto out;
3387 if (!active_wlcore)
3388 bcm43xx_radio_turn_off(bcm);
3389out:
3390 return err;
3391}
3392
3393/* Select and enable the "to be used" wireless core.
3394 * Locking: bcm->mutex must be aquired before calling this.
3395 * bcm->irq_lock must not be aquired.
3396 */
3397int bcm43xx_select_wireless_core(struct bcm43xx_private *bcm,
3398 int phytype)
3304{ 3399{
3305 int i, err; 3400 int i, err;
3306 int connect_phy; 3401 struct bcm43xx_coreinfo *active_core = NULL;
3402 struct bcm43xx_coreinfo_80211 *active_wlext = NULL;
3403 struct bcm43xx_coreinfo *core;
3404 struct bcm43xx_coreinfo_80211 *wlext;
3405 int adjust_active_sbtmstatelow = 0;
3307 3406
3308 might_sleep(); 3407 might_sleep();
3309 3408
3310 bcm43xx_lock_noirq(bcm); 3409 if (phytype < 0) {
3311 bcm43xx_set_status(bcm, BCM43xx_STAT_INITIALIZING); 3410 /* If no phytype is requested, select the first core. */
3411 assert(bcm->core_80211[0].available);
3412 wlext = bcm->core_80211[0].priv;
3413 phytype = wlext->phy.type;
3414 }
3415 /* Find the requested core. */
3416 for (i = 0; i < bcm->nr_80211_available; i++) {
3417 core = &(bcm->core_80211[i]);
3418 wlext = core->priv;
3419 if (wlext->phy.type == phytype) {
3420 active_core = core;
3421 active_wlext = wlext;
3422 break;
3423 }
3424 }
3425 if (!active_core)
3426 return -ESRCH; /* No such PHYTYPE on this board. */
3427
3428 if (bcm->active_80211_core) {
3429 /* We already selected a wl core in the past.
3430 * So first clean up everything.
3431 */
3432 dprintk(KERN_INFO PFX "select_wireless_core: cleanup\n");
3433 ieee80211softmac_stop(bcm->net_dev);
3434 bcm43xx_set_status(bcm, BCM43xx_STAT_INITIALIZED);
3435 err = bcm43xx_disable_interrupts_sync(bcm);
3436 assert(!err);
3437 tasklet_enable(&bcm->isr_tasklet);
3438 err = bcm43xx_shutdown_all_wireless_cores(bcm);
3439 if (err)
3440 goto error;
3441 /* Ok, everything down, continue to re-initialize. */
3442 bcm43xx_set_status(bcm, BCM43xx_STAT_INITIALIZING);
3443 }
3444
3445 /* Reset all data structures. */
3446 prepare_priv_for_init(bcm);
3312 3447
3313 err = bcm43xx_pctl_set_crystal(bcm, 1);
3314 if (err)
3315 goto out;
3316 err = bcm43xx_pctl_init(bcm);
3317 if (err)
3318 goto err_crystal_off;
3319 err = bcm43xx_pctl_set_clock(bcm, BCM43xx_PCTL_CLK_FAST); 3448 err = bcm43xx_pctl_set_clock(bcm, BCM43xx_PCTL_CLK_FAST);
3320 if (err) 3449 if (err)
3321 goto err_crystal_off; 3450 goto error;
3322 3451
3323 tasklet_enable(&bcm->isr_tasklet); 3452 /* Mark all unused cores "inactive". */
3324 for (i = 0; i < bcm->nr_80211_available; i++) { 3453 for (i = 0; i < bcm->nr_80211_available; i++) {
3325 err = bcm43xx_switch_core(bcm, &bcm->core_80211[i]); 3454 core = &(bcm->core_80211[i]);
3326 assert(err != -ENODEV); 3455 wlext = core->priv;
3327 if (err)
3328 goto err_80211_unwind;
3329 3456
3330 /* Enable the selected wireless core. 3457 if (core == active_core)
3331 * Connect PHY only on the first core. 3458 continue;
3332 */ 3459 err = bcm43xx_switch_core(bcm, core);
3333 if (!bcm43xx_core_enabled(bcm)) { 3460 if (err) {
3334 if (bcm->nr_80211_available == 1) { 3461 dprintk(KERN_ERR PFX "Could not switch to inactive "
3335 connect_phy = bcm43xx_current_phy(bcm)->connected; 3462 "802.11 core (%d)\n", err);
3336 } else { 3463 goto error;
3337 if (i == 0)
3338 connect_phy = 1;
3339 else
3340 connect_phy = 0;
3341 }
3342 bcm43xx_wireless_core_reset(bcm, connect_phy);
3343 } 3464 }
3465 err = wireless_core_up(bcm, 0);
3466 if (err) {
3467 dprintk(KERN_ERR PFX "core_up for inactive 802.11 core "
3468 "failed (%d)\n", err);
3469 goto error;
3470 }
3471 adjust_active_sbtmstatelow = 1;
3472 }
3344 3473
3345 if (i != 0) 3474 /* Now initialize the active 802.11 core. */
3346 bcm43xx_wireless_core_mark_inactive(bcm, &bcm->core_80211[0]); 3475 err = bcm43xx_switch_core(bcm, active_core);
3347 3476 if (err) {
3348 err = bcm43xx_wireless_core_init(bcm); 3477 dprintk(KERN_ERR PFX "Could not switch to active "
3349 if (err) 3478 "802.11 core (%d)\n", err);
3350 goto err_80211_unwind; 3479 goto error;
3480 }
3481 if (adjust_active_sbtmstatelow &&
3482 active_wlext->phy.type == BCM43xx_PHYTYPE_G) {
3483 u32 sbtmstatelow;
3351 3484
3352 if (i != 0) { 3485 sbtmstatelow = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
3353 bcm43xx_mac_suspend(bcm); 3486 sbtmstatelow |= 0x20000000;
3354 bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL); 3487 bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
3355 bcm43xx_radio_turn_off(bcm);
3356 }
3357 } 3488 }
3358 bcm->active_80211_core = &bcm->core_80211[0]; 3489 err = wireless_core_up(bcm, 1);
3359 if (bcm->nr_80211_available >= 2) { 3490 if (err) {
3360 bcm43xx_switch_core(bcm, &bcm->core_80211[0]); 3491 dprintk(KERN_ERR PFX "core_up for active 802.11 core "
3361 bcm43xx_mac_enable(bcm); 3492 "failed (%d)\n", err);
3493 goto error;
3362 } 3494 }
3363 err = bcm43xx_rng_init(bcm); 3495 err = bcm43xx_pctl_set_clock(bcm, BCM43xx_PCTL_CLK_DYNAMIC);
3364 if (err) 3496 if (err)
3365 goto err_80211_unwind; 3497 goto error;
3498 bcm->active_80211_core = active_core;
3499
3366 bcm43xx_macfilter_clear(bcm, BCM43xx_MACFILTER_ASSOC); 3500 bcm43xx_macfilter_clear(bcm, BCM43xx_MACFILTER_ASSOC);
3367 bcm43xx_macfilter_set(bcm, BCM43xx_MACFILTER_SELF, (u8 *)(bcm->net_dev->dev_addr)); 3501 bcm43xx_macfilter_set(bcm, BCM43xx_MACFILTER_SELF, (u8 *)(bcm->net_dev->dev_addr));
3368 dprintk(KERN_INFO PFX "80211 cores initialized\n");
3369 bcm43xx_security_init(bcm); 3502 bcm43xx_security_init(bcm);
3370 bcm43xx_softmac_init(bcm); 3503 ieee80211softmac_start(bcm->net_dev);
3371 3504
3372 bcm43xx_pctl_set_clock(bcm, BCM43xx_PCTL_CLK_DYNAMIC); 3505 /* Let's go! Be careful after enabling the IRQs.
3506 * Don't switch cores, for example.
3507 */
3508 bcm43xx_mac_enable(bcm);
3509 bcm43xx_set_status(bcm, BCM43xx_STAT_INITIALIZED);
3510 err = bcm43xx_initialize_irq(bcm);
3511 if (err)
3512 goto error;
3513 bcm43xx_interrupt_enable(bcm, bcm->irq_savedstate);
3373 3514
3374 if (bcm43xx_current_radio(bcm)->initial_channel != 0xFF) { 3515 dprintk(KERN_INFO PFX "Selected 802.11 core (phytype %d)\n",
3375 bcm43xx_mac_suspend(bcm); 3516 active_wlext->phy.type);
3376 bcm43xx_radio_selectchannel(bcm, bcm43xx_current_radio(bcm)->initial_channel, 0);
3377 bcm43xx_mac_enable(bcm);
3378 }
3379 3517
3380 /* Initialization of the board is done. Flag it as such. */ 3518 return 0;
3381 bcm43xx_set_status(bcm, BCM43xx_STAT_INITIALIZED); 3519
3520error:
3521 bcm43xx_set_status(bcm, BCM43xx_STAT_UNINIT);
3522 bcm43xx_pctl_set_clock(bcm, BCM43xx_PCTL_CLK_SLOW);
3523 return err;
3524}
3525
3526static int bcm43xx_init_board(struct bcm43xx_private *bcm)
3527{
3528 int err;
3529
3530 mutex_lock(&(bcm)->mutex);
3531
3532 tasklet_enable(&bcm->isr_tasklet);
3533 err = bcm43xx_pctl_set_crystal(bcm, 1);
3534 if (err)
3535 goto err_tasklet;
3536 err = bcm43xx_pctl_init(bcm);
3537 if (err)
3538 goto err_crystal_off;
3539 err = bcm43xx_select_wireless_core(bcm, -1);
3540 if (err)
3541 goto err_crystal_off;
3382 3542
3383 bcm43xx_periodic_tasks_setup(bcm); 3543 bcm43xx_periodic_tasks_setup(bcm);
3384 bcm43xx_sysfs_register(bcm); 3544 err = bcm43xx_sysfs_register(bcm);
3385 //FIXME: check for bcm43xx_sysfs_register failure. This function is a bit messy regarding unwinding, though... 3545 if (err)
3546 goto err_wlshutdown;
3547 err = bcm43xx_rng_init(bcm);
3548 if (err)
3549 goto err_sysfs_unreg;
3386 3550
3387 /*FIXME: This should be handled by softmac instead. */ 3551 /*FIXME: This should be handled by softmac instead. */
3388 schedule_work(&bcm->softmac->associnfo.work); 3552 schedule_work(&bcm->softmac->associnfo.work);
3389 3553
3390 assert(err == 0);
3391out: 3554out:
3392 bcm43xx_unlock_noirq(bcm); 3555 mutex_unlock(&(bcm)->mutex);
3393 3556
3394 return err; 3557 return err;
3395 3558
3396err_80211_unwind: 3559err_sysfs_unreg:
3397 tasklet_disable(&bcm->isr_tasklet); 3560 bcm43xx_sysfs_unregister(bcm);
3398 /* unwind all 80211 initialization */ 3561err_wlshutdown:
3399 for (i = 0; i < bcm->nr_80211_available; i++) { 3562 bcm43xx_shutdown_all_wireless_cores(bcm);
3400 if (!bcm->core_80211[i].initialized)
3401 continue;
3402 bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
3403 bcm43xx_wireless_core_cleanup(bcm);
3404 }
3405err_crystal_off: 3563err_crystal_off:
3406 bcm43xx_pctl_set_crystal(bcm, 0); 3564 bcm43xx_pctl_set_crystal(bcm, 0);
3565err_tasklet:
3566 tasklet_disable(&bcm->isr_tasklet);
3407 goto out; 3567 goto out;
3408} 3568}
3409 3569
@@ -3647,7 +3807,8 @@ static void bcm43xx_ieee80211_set_chan(struct net_device *net_dev,
3647 struct bcm43xx_radioinfo *radio; 3807 struct bcm43xx_radioinfo *radio;
3648 unsigned long flags; 3808 unsigned long flags;
3649 3809
3650 bcm43xx_lock_irqsafe(bcm, flags); 3810 mutex_lock(&bcm->mutex);
3811 spin_lock_irqsave(&bcm->irq_lock, flags);
3651 if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) { 3812 if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) {
3652 bcm43xx_mac_suspend(bcm); 3813 bcm43xx_mac_suspend(bcm);
3653 bcm43xx_radio_selectchannel(bcm, channel, 0); 3814 bcm43xx_radio_selectchannel(bcm, channel, 0);
@@ -3656,7 +3817,8 @@ static void bcm43xx_ieee80211_set_chan(struct net_device *net_dev,
3656 radio = bcm43xx_current_radio(bcm); 3817 radio = bcm43xx_current_radio(bcm);
3657 radio->initial_channel = channel; 3818 radio->initial_channel = channel;
3658 } 3819 }
3659 bcm43xx_unlock_irqsafe(bcm, flags); 3820 spin_unlock_irqrestore(&bcm->irq_lock, flags);
3821 mutex_unlock(&bcm->mutex);
3660} 3822}
3661 3823
3662/* set_security() callback in struct ieee80211_device */ 3824/* set_security() callback in struct ieee80211_device */
@@ -3670,7 +3832,8 @@ static void bcm43xx_ieee80211_set_security(struct net_device *net_dev,
3670 3832
3671 dprintk(KERN_INFO PFX "set security called"); 3833 dprintk(KERN_INFO PFX "set security called");
3672 3834
3673 bcm43xx_lock_irqsafe(bcm, flags); 3835 mutex_lock(&bcm->mutex);
3836 spin_lock_irqsave(&bcm->irq_lock, flags);
3674 3837
3675 for (keyidx = 0; keyidx<WEP_KEYS; keyidx++) 3838 for (keyidx = 0; keyidx<WEP_KEYS; keyidx++)
3676 if (sec->flags & (1<<keyidx)) { 3839 if (sec->flags & (1<<keyidx)) {
@@ -3739,7 +3902,8 @@ static void bcm43xx_ieee80211_set_security(struct net_device *net_dev,
3739 } else 3902 } else
3740 bcm43xx_clear_keys(bcm); 3903 bcm43xx_clear_keys(bcm);
3741 } 3904 }
3742 bcm43xx_unlock_irqsafe(bcm, flags); 3905 spin_unlock_irqrestore(&bcm->irq_lock, flags);
3906 mutex_unlock(&bcm->mutex);
3743} 3907}
3744 3908
3745/* hard_start_xmit() callback in struct ieee80211_device */ 3909/* hard_start_xmit() callback in struct ieee80211_device */
@@ -3751,12 +3915,14 @@ static int bcm43xx_ieee80211_hard_start_xmit(struct ieee80211_txb *txb,
3751 int err = -ENODEV; 3915 int err = -ENODEV;
3752 unsigned long flags; 3916 unsigned long flags;
3753 3917
3754 bcm43xx_lock_irqonly(bcm, flags); 3918 spin_lock_irqsave(&bcm->irq_lock, flags);
3755 if (likely(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED)) 3919 if (likely(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED))
3756 err = bcm43xx_tx(bcm, txb); 3920 err = bcm43xx_tx(bcm, txb);
3757 bcm43xx_unlock_irqonly(bcm, flags); 3921 spin_unlock_irqrestore(&bcm->irq_lock, flags);
3758 3922
3759 return err; 3923 if (unlikely(err))
3924 return NETDEV_TX_BUSY;
3925 return NETDEV_TX_OK;
3760} 3926}
3761 3927
3762static struct net_device_stats * bcm43xx_net_get_stats(struct net_device *net_dev) 3928static struct net_device_stats * bcm43xx_net_get_stats(struct net_device *net_dev)
@@ -3769,9 +3935,9 @@ static void bcm43xx_net_tx_timeout(struct net_device *net_dev)
3769 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); 3935 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
3770 unsigned long flags; 3936 unsigned long flags;
3771 3937
3772 bcm43xx_lock_irqonly(bcm, flags); 3938 spin_lock_irqsave(&bcm->irq_lock, flags);
3773 bcm43xx_controller_restart(bcm, "TX timeout"); 3939 bcm43xx_controller_restart(bcm, "TX timeout");
3774 bcm43xx_unlock_irqonly(bcm, flags); 3940 spin_unlock_irqrestore(&bcm->irq_lock, flags);
3775} 3941}
3776 3942
3777#ifdef CONFIG_NET_POLL_CONTROLLER 3943#ifdef CONFIG_NET_POLL_CONTROLLER
@@ -3781,7 +3947,8 @@ static void bcm43xx_net_poll_controller(struct net_device *net_dev)
3781 unsigned long flags; 3947 unsigned long flags;
3782 3948
3783 local_irq_save(flags); 3949 local_irq_save(flags);
3784 bcm43xx_interrupt_handler(bcm->irq, bcm, NULL); 3950 if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED)
3951 bcm43xx_interrupt_handler(bcm->irq, bcm, NULL);
3785 local_irq_restore(flags); 3952 local_irq_restore(flags);
3786} 3953}
3787#endif /* CONFIG_NET_POLL_CONTROLLER */ 3954#endif /* CONFIG_NET_POLL_CONTROLLER */
@@ -3799,7 +3966,7 @@ static int bcm43xx_net_stop(struct net_device *net_dev)
3799 int err; 3966 int err;
3800 3967
3801 ieee80211softmac_stop(net_dev); 3968 ieee80211softmac_stop(net_dev);
3802 err = bcm43xx_disable_interrupts_sync(bcm, NULL); 3969 err = bcm43xx_disable_interrupts_sync(bcm);
3803 assert(!err); 3970 assert(!err);
3804 bcm43xx_free_board(bcm); 3971 bcm43xx_free_board(bcm);
3805 3972
@@ -3818,10 +3985,12 @@ static int bcm43xx_init_private(struct bcm43xx_private *bcm,
3818 bcm->softmac->set_channel = bcm43xx_ieee80211_set_chan; 3985 bcm->softmac->set_channel = bcm43xx_ieee80211_set_chan;
3819 3986
3820 bcm->irq_savedstate = BCM43xx_IRQ_INITIAL; 3987 bcm->irq_savedstate = BCM43xx_IRQ_INITIAL;
3988 bcm->mac_suspended = 1;
3821 bcm->pci_dev = pci_dev; 3989 bcm->pci_dev = pci_dev;
3822 bcm->net_dev = net_dev; 3990 bcm->net_dev = net_dev;
3823 bcm->bad_frames_preempt = modparam_bad_frames_preempt; 3991 bcm->bad_frames_preempt = modparam_bad_frames_preempt;
3824 spin_lock_init(&bcm->irq_lock); 3992 spin_lock_init(&bcm->irq_lock);
3993 spin_lock_init(&bcm->leds_lock);
3825 mutex_init(&bcm->mutex); 3994 mutex_init(&bcm->mutex);
3826 tasklet_init(&bcm->isr_tasklet, 3995 tasklet_init(&bcm->isr_tasklet,
3827 (void (*)(unsigned long))bcm43xx_interrupt_tasklet, 3996 (void (*)(unsigned long))bcm43xx_interrupt_tasklet,
@@ -3940,7 +4109,6 @@ static void __devexit bcm43xx_remove_one(struct pci_dev *pdev)
3940 bcm43xx_debugfs_remove_device(bcm); 4109 bcm43xx_debugfs_remove_device(bcm);
3941 unregister_netdev(net_dev); 4110 unregister_netdev(net_dev);
3942 bcm43xx_detach_board(bcm); 4111 bcm43xx_detach_board(bcm);
3943 assert(bcm->ucode == NULL);
3944 free_ieee80211softmac(net_dev); 4112 free_ieee80211softmac(net_dev);
3945} 4113}
3946 4114
@@ -3950,47 +4118,25 @@ static void __devexit bcm43xx_remove_one(struct pci_dev *pdev)
3950static void bcm43xx_chip_reset(void *_bcm) 4118static void bcm43xx_chip_reset(void *_bcm)
3951{ 4119{
3952 struct bcm43xx_private *bcm = _bcm; 4120 struct bcm43xx_private *bcm = _bcm;
3953 struct net_device *net_dev = bcm->net_dev; 4121 struct bcm43xx_phyinfo *phy;
3954 struct pci_dev *pci_dev = bcm->pci_dev;
3955 int err; 4122 int err;
3956 int was_initialized = (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED);
3957 4123
3958 netif_stop_queue(bcm->net_dev); 4124 mutex_lock(&(bcm)->mutex);
3959 tasklet_disable(&bcm->isr_tasklet); 4125 phy = bcm43xx_current_phy(bcm);
4126 err = bcm43xx_select_wireless_core(bcm, phy->type);
4127 mutex_unlock(&(bcm)->mutex);
3960 4128
3961 bcm->firmware_norelease = 1; 4129 printk(KERN_ERR PFX "Controller restart%s\n",
3962 if (was_initialized) 4130 (err == 0) ? "ed" : " failed");
3963 bcm43xx_free_board(bcm);
3964 bcm->firmware_norelease = 0;
3965 bcm43xx_detach_board(bcm);
3966 err = bcm43xx_init_private(bcm, net_dev, pci_dev);
3967 if (err)
3968 goto failure;
3969 err = bcm43xx_attach_board(bcm);
3970 if (err)
3971 goto failure;
3972 if (was_initialized) {
3973 err = bcm43xx_init_board(bcm);
3974 if (err)
3975 goto failure;
3976 }
3977 netif_wake_queue(bcm->net_dev);
3978 printk(KERN_INFO PFX "Controller restarted\n");
3979
3980 return;
3981failure:
3982 printk(KERN_ERR PFX "Controller restart failed\n");
3983} 4131}
3984 4132
3985/* Hard-reset the chip. 4133/* Hard-reset the chip.
3986 * This can be called from interrupt or process context. 4134 * This can be called from interrupt or process context.
3987 * Make sure to _not_ re-enable device interrupts after this has been called. 4135 */
3988*/
3989void bcm43xx_controller_restart(struct bcm43xx_private *bcm, const char *reason) 4136void bcm43xx_controller_restart(struct bcm43xx_private *bcm, const char *reason)
3990{ 4137{
4138 assert(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED);
3991 bcm43xx_set_status(bcm, BCM43xx_STAT_RESTARTING); 4139 bcm43xx_set_status(bcm, BCM43xx_STAT_RESTARTING);
3992 bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
3993 bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); /* dummy read */
3994 printk(KERN_ERR PFX "Controller RESET (%s) ...\n", reason); 4140 printk(KERN_ERR PFX "Controller RESET (%s) ...\n", reason);
3995 INIT_WORK(&bcm->restart_work, bcm43xx_chip_reset, bcm); 4141 INIT_WORK(&bcm->restart_work, bcm43xx_chip_reset, bcm);
3996 schedule_work(&bcm->restart_work); 4142 schedule_work(&bcm->restart_work);
@@ -4002,21 +4148,16 @@ static int bcm43xx_suspend(struct pci_dev *pdev, pm_message_t state)
4002{ 4148{
4003 struct net_device *net_dev = pci_get_drvdata(pdev); 4149 struct net_device *net_dev = pci_get_drvdata(pdev);
4004 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); 4150 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
4005 unsigned long flags; 4151 int err;
4006 int try_to_shutdown = 0, err;
4007 4152
4008 dprintk(KERN_INFO PFX "Suspending...\n"); 4153 dprintk(KERN_INFO PFX "Suspending...\n");
4009 4154
4010 bcm43xx_lock_irqsafe(bcm, flags);
4011 bcm->was_initialized = (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED);
4012 if (bcm->was_initialized)
4013 try_to_shutdown = 1;
4014 bcm43xx_unlock_irqsafe(bcm, flags);
4015
4016 netif_device_detach(net_dev); 4155 netif_device_detach(net_dev);
4017 if (try_to_shutdown) { 4156 bcm->was_initialized = 0;
4157 if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) {
4158 bcm->was_initialized = 1;
4018 ieee80211softmac_stop(net_dev); 4159 ieee80211softmac_stop(net_dev);
4019 err = bcm43xx_disable_interrupts_sync(bcm, &bcm->irq_savedstate); 4160 err = bcm43xx_disable_interrupts_sync(bcm);
4020 if (unlikely(err)) { 4161 if (unlikely(err)) {
4021 dprintk(KERN_ERR PFX "Suspend failed.\n"); 4162 dprintk(KERN_ERR PFX "Suspend failed.\n");
4022 return -EAGAIN; 4163 return -EAGAIN;
@@ -4049,17 +4190,14 @@ static int bcm43xx_resume(struct pci_dev *pdev)
4049 pci_restore_state(pdev); 4190 pci_restore_state(pdev);
4050 4191
4051 bcm43xx_chipset_attach(bcm); 4192 bcm43xx_chipset_attach(bcm);
4052 if (bcm->was_initialized) { 4193 if (bcm->was_initialized)
4053 bcm->irq_savedstate = BCM43xx_IRQ_INITIAL;
4054 err = bcm43xx_init_board(bcm); 4194 err = bcm43xx_init_board(bcm);
4055 }
4056 if (err) { 4195 if (err) {
4057 printk(KERN_ERR PFX "Resume failed!\n"); 4196 printk(KERN_ERR PFX "Resume failed!\n");
4058 return err; 4197 return err;
4059 } 4198 }
4060
4061 netif_device_attach(net_dev); 4199 netif_device_attach(net_dev);
4062 4200
4063 dprintk(KERN_INFO PFX "Device resumed.\n"); 4201 dprintk(KERN_INFO PFX "Device resumed.\n");
4064 4202
4065 return 0; 4203 return 0;
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.h b/drivers/net/wireless/bcm43xx/bcm43xx_main.h
index 116493671f88..505c86e2007a 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_main.h
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.h
@@ -133,6 +133,9 @@ void bcm43xx_dummy_transmission(struct bcm43xx_private *bcm);
133 133
134int bcm43xx_switch_core(struct bcm43xx_private *bcm, struct bcm43xx_coreinfo *new_core); 134int bcm43xx_switch_core(struct bcm43xx_private *bcm, struct bcm43xx_coreinfo *new_core);
135 135
136int bcm43xx_select_wireless_core(struct bcm43xx_private *bcm,
137 int phytype);
138
136void bcm43xx_wireless_core_reset(struct bcm43xx_private *bcm, int connect_phy); 139void bcm43xx_wireless_core_reset(struct bcm43xx_private *bcm, int connect_phy);
137 140
138void bcm43xx_mac_suspend(struct bcm43xx_private *bcm); 141void bcm43xx_mac_suspend(struct bcm43xx_private *bcm);
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_phy.c b/drivers/net/wireless/bcm43xx/bcm43xx_phy.c
index f8200deecc8a..eafd0f662686 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_phy.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_phy.c
@@ -81,6 +81,16 @@ static const s8 bcm43xx_tssi2dbm_g_table[] = {
81static void bcm43xx_phy_initg(struct bcm43xx_private *bcm); 81static void bcm43xx_phy_initg(struct bcm43xx_private *bcm);
82 82
83 83
84static inline
85void bcm43xx_voluntary_preempt(void)
86{
87 assert(!in_atomic() && !in_irq() &&
88 !in_interrupt() && !irqs_disabled());
89#ifndef CONFIG_PREEMPT
90 cond_resched();
91#endif /* CONFIG_PREEMPT */
92}
93
84void bcm43xx_raw_phy_lock(struct bcm43xx_private *bcm) 94void bcm43xx_raw_phy_lock(struct bcm43xx_private *bcm)
85{ 95{
86 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); 96 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
@@ -133,22 +143,14 @@ void bcm43xx_phy_write(struct bcm43xx_private *bcm, u16 offset, u16 val)
133void bcm43xx_phy_calibrate(struct bcm43xx_private *bcm) 143void bcm43xx_phy_calibrate(struct bcm43xx_private *bcm)
134{ 144{
135 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); 145 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
136 unsigned long flags;
137 146
138 bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); /* Dummy read. */ 147 bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); /* Dummy read. */
139 if (phy->calibrated) 148 if (phy->calibrated)
140 return; 149 return;
141 if (phy->type == BCM43xx_PHYTYPE_G && phy->rev == 1) { 150 if (phy->type == BCM43xx_PHYTYPE_G && phy->rev == 1) {
142 /* We do not want to be preempted while calibrating
143 * the hardware.
144 */
145 local_irq_save(flags);
146
147 bcm43xx_wireless_core_reset(bcm, 0); 151 bcm43xx_wireless_core_reset(bcm, 0);
148 bcm43xx_phy_initg(bcm); 152 bcm43xx_phy_initg(bcm);
149 bcm43xx_wireless_core_reset(bcm, 1); 153 bcm43xx_wireless_core_reset(bcm, 1);
150
151 local_irq_restore(flags);
152 } 154 }
153 phy->calibrated = 1; 155 phy->calibrated = 1;
154} 156}
@@ -1299,7 +1301,9 @@ static u16 bcm43xx_phy_lo_b_r15_loop(struct bcm43xx_private *bcm)
1299{ 1301{
1300 int i; 1302 int i;
1301 u16 ret = 0; 1303 u16 ret = 0;
1304 unsigned long flags;
1302 1305
1306 local_irq_save(flags);
1303 for (i = 0; i < 10; i++){ 1307 for (i = 0; i < 10; i++){
1304 bcm43xx_phy_write(bcm, 0x0015, 0xAFA0); 1308 bcm43xx_phy_write(bcm, 0x0015, 0xAFA0);
1305 udelay(1); 1309 udelay(1);
@@ -1309,6 +1313,8 @@ static u16 bcm43xx_phy_lo_b_r15_loop(struct bcm43xx_private *bcm)
1309 udelay(40); 1313 udelay(40);
1310 ret += bcm43xx_phy_read(bcm, 0x002C); 1314 ret += bcm43xx_phy_read(bcm, 0x002C);
1311 } 1315 }
1316 local_irq_restore(flags);
1317 bcm43xx_voluntary_preempt();
1312 1318
1313 return ret; 1319 return ret;
1314} 1320}
@@ -1435,6 +1441,7 @@ u16 bcm43xx_phy_lo_g_deviation_subval(struct bcm43xx_private *bcm, u16 control)
1435 } 1441 }
1436 ret = bcm43xx_phy_read(bcm, 0x002D); 1442 ret = bcm43xx_phy_read(bcm, 0x002D);
1437 local_irq_restore(flags); 1443 local_irq_restore(flags);
1444 bcm43xx_voluntary_preempt();
1438 1445
1439 return ret; 1446 return ret;
1440} 1447}
@@ -1760,6 +1767,7 @@ void bcm43xx_phy_lo_g_measure(struct bcm43xx_private *bcm)
1760 bcm43xx_radio_write16(bcm, 0x43, i); 1767 bcm43xx_radio_write16(bcm, 0x43, i);
1761 bcm43xx_radio_write16(bcm, 0x52, radio->txctl2); 1768 bcm43xx_radio_write16(bcm, 0x52, radio->txctl2);
1762 udelay(10); 1769 udelay(10);
1770 bcm43xx_voluntary_preempt();
1763 1771
1764 bcm43xx_phy_set_baseband_attenuation(bcm, j * 2); 1772 bcm43xx_phy_set_baseband_attenuation(bcm, j * 2);
1765 1773
@@ -1803,6 +1811,7 @@ void bcm43xx_phy_lo_g_measure(struct bcm43xx_private *bcm)
1803 radio->txctl2 1811 radio->txctl2
1804 | (3/*txctl1*/ << 4));//FIXME: shouldn't txctl1 be zero here and 3 in the loop above? 1812 | (3/*txctl1*/ << 4));//FIXME: shouldn't txctl1 be zero here and 3 in the loop above?
1805 udelay(10); 1813 udelay(10);
1814 bcm43xx_voluntary_preempt();
1806 1815
1807 bcm43xx_phy_set_baseband_attenuation(bcm, j * 2); 1816 bcm43xx_phy_set_baseband_attenuation(bcm, j * 2);
1808 1817
@@ -1824,6 +1833,7 @@ void bcm43xx_phy_lo_g_measure(struct bcm43xx_private *bcm)
1824 bcm43xx_phy_write(bcm, 0x0812, (r27 << 8) | 0xA2); 1833 bcm43xx_phy_write(bcm, 0x0812, (r27 << 8) | 0xA2);
1825 udelay(2); 1834 udelay(2);
1826 bcm43xx_phy_write(bcm, 0x0812, (r27 << 8) | 0xA3); 1835 bcm43xx_phy_write(bcm, 0x0812, (r27 << 8) | 0xA3);
1836 bcm43xx_voluntary_preempt();
1827 } else 1837 } else
1828 bcm43xx_phy_write(bcm, 0x0015, r27 | 0xEFA0); 1838 bcm43xx_phy_write(bcm, 0x0015, r27 | 0xEFA0);
1829 bcm43xx_phy_lo_adjust(bcm, is_initializing); 1839 bcm43xx_phy_lo_adjust(bcm, is_initializing);
@@ -2188,12 +2198,6 @@ int bcm43xx_phy_init(struct bcm43xx_private *bcm)
2188{ 2198{
2189 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); 2199 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
2190 int err = -ENODEV; 2200 int err = -ENODEV;
2191 unsigned long flags;
2192
2193 /* We do not want to be preempted while calibrating
2194 * the hardware.
2195 */
2196 local_irq_save(flags);
2197 2201
2198 switch (phy->type) { 2202 switch (phy->type) {
2199 case BCM43xx_PHYTYPE_A: 2203 case BCM43xx_PHYTYPE_A:
@@ -2227,7 +2231,6 @@ int bcm43xx_phy_init(struct bcm43xx_private *bcm)
2227 err = 0; 2231 err = 0;
2228 break; 2232 break;
2229 } 2233 }
2230 local_irq_restore(flags);
2231 if (err) 2234 if (err)
2232 printk(KERN_WARNING PFX "Unknown PHYTYPE found!\n"); 2235 printk(KERN_WARNING PFX "Unknown PHYTYPE found!\n");
2233 2236
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_pio.c b/drivers/net/wireless/bcm43xx/bcm43xx_pio.c
index 574085c46152..c60c1743ea06 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_pio.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_pio.c
@@ -262,7 +262,7 @@ static void tx_tasklet(unsigned long d)
262 int err; 262 int err;
263 u16 txctl; 263 u16 txctl;
264 264
265 bcm43xx_lock_irqonly(bcm, flags); 265 spin_lock_irqsave(&bcm->irq_lock, flags);
266 266
267 if (queue->tx_frozen) 267 if (queue->tx_frozen)
268 goto out_unlock; 268 goto out_unlock;
@@ -300,7 +300,7 @@ static void tx_tasklet(unsigned long d)
300 continue; 300 continue;
301 } 301 }
302out_unlock: 302out_unlock:
303 bcm43xx_unlock_irqonly(bcm, flags); 303 spin_unlock_irqrestore(&bcm->irq_lock, flags);
304} 304}
305 305
306static void setup_txqueues(struct bcm43xx_pioqueue *queue) 306static void setup_txqueues(struct bcm43xx_pioqueue *queue)
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c b/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c
index 6a23bdc75412..ece335178f6a 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c
@@ -120,12 +120,14 @@ static ssize_t bcm43xx_attr_sprom_show(struct device *dev,
120 GFP_KERNEL); 120 GFP_KERNEL);
121 if (!sprom) 121 if (!sprom)
122 return -ENOMEM; 122 return -ENOMEM;
123 bcm43xx_lock_irqsafe(bcm, flags); 123 mutex_lock(&bcm->mutex);
124 spin_lock_irqsave(&bcm->irq_lock, flags);
124 err = bcm43xx_sprom_read(bcm, sprom); 125 err = bcm43xx_sprom_read(bcm, sprom);
125 if (!err) 126 if (!err)
126 err = sprom2hex(sprom, buf, PAGE_SIZE); 127 err = sprom2hex(sprom, buf, PAGE_SIZE);
127 mmiowb(); 128 mmiowb();
128 bcm43xx_unlock_irqsafe(bcm, flags); 129 spin_unlock_irqrestore(&bcm->irq_lock, flags);
130 mutex_unlock(&bcm->mutex);
129 kfree(sprom); 131 kfree(sprom);
130 132
131 return err; 133 return err;
@@ -150,10 +152,14 @@ static ssize_t bcm43xx_attr_sprom_store(struct device *dev,
150 err = hex2sprom(sprom, buf, count); 152 err = hex2sprom(sprom, buf, count);
151 if (err) 153 if (err)
152 goto out_kfree; 154 goto out_kfree;
153 bcm43xx_lock_irqsafe(bcm, flags); 155 mutex_lock(&bcm->mutex);
156 spin_lock_irqsave(&bcm->irq_lock, flags);
157 spin_lock(&bcm->leds_lock);
154 err = bcm43xx_sprom_write(bcm, sprom); 158 err = bcm43xx_sprom_write(bcm, sprom);
155 mmiowb(); 159 mmiowb();
156 bcm43xx_unlock_irqsafe(bcm, flags); 160 spin_unlock(&bcm->leds_lock);
161 spin_unlock_irqrestore(&bcm->irq_lock, flags);
162 mutex_unlock(&bcm->mutex);
157out_kfree: 163out_kfree:
158 kfree(sprom); 164 kfree(sprom);
159 165
@@ -176,7 +182,7 @@ static ssize_t bcm43xx_attr_interfmode_show(struct device *dev,
176 if (!capable(CAP_NET_ADMIN)) 182 if (!capable(CAP_NET_ADMIN))
177 return -EPERM; 183 return -EPERM;
178 184
179 bcm43xx_lock_noirq(bcm); 185 mutex_lock(&bcm->mutex);
180 186
181 switch (bcm43xx_current_radio(bcm)->interfmode) { 187 switch (bcm43xx_current_radio(bcm)->interfmode) {
182 case BCM43xx_RADIO_INTERFMODE_NONE: 188 case BCM43xx_RADIO_INTERFMODE_NONE:
@@ -193,7 +199,7 @@ static ssize_t bcm43xx_attr_interfmode_show(struct device *dev,
193 } 199 }
194 err = 0; 200 err = 0;
195 201
196 bcm43xx_unlock_noirq(bcm); 202 mutex_unlock(&bcm->mutex);
197 203
198 return err ? err : count; 204 return err ? err : count;
199 205
@@ -229,7 +235,8 @@ static ssize_t bcm43xx_attr_interfmode_store(struct device *dev,
229 return -EINVAL; 235 return -EINVAL;
230 } 236 }
231 237
232 bcm43xx_lock_irqsafe(bcm, flags); 238 mutex_lock(&bcm->mutex);
239 spin_lock_irqsave(&bcm->irq_lock, flags);
233 240
234 err = bcm43xx_radio_set_interference_mitigation(bcm, mode); 241 err = bcm43xx_radio_set_interference_mitigation(bcm, mode);
235 if (err) { 242 if (err) {
@@ -237,7 +244,8 @@ static ssize_t bcm43xx_attr_interfmode_store(struct device *dev,
237 "supported by device\n"); 244 "supported by device\n");
238 } 245 }
239 mmiowb(); 246 mmiowb();
240 bcm43xx_unlock_irqsafe(bcm, flags); 247 spin_unlock_irqrestore(&bcm->irq_lock, flags);
248 mutex_unlock(&bcm->mutex);
241 249
242 return err ? err : count; 250 return err ? err : count;
243} 251}
@@ -257,7 +265,7 @@ static ssize_t bcm43xx_attr_preamble_show(struct device *dev,
257 if (!capable(CAP_NET_ADMIN)) 265 if (!capable(CAP_NET_ADMIN))
258 return -EPERM; 266 return -EPERM;
259 267
260 bcm43xx_lock_noirq(bcm); 268 mutex_lock(&bcm->mutex);
261 269
262 if (bcm->short_preamble) 270 if (bcm->short_preamble)
263 count = snprintf(buf, PAGE_SIZE, "1 (Short Preamble enabled)\n"); 271 count = snprintf(buf, PAGE_SIZE, "1 (Short Preamble enabled)\n");
@@ -265,7 +273,7 @@ static ssize_t bcm43xx_attr_preamble_show(struct device *dev,
265 count = snprintf(buf, PAGE_SIZE, "0 (Short Preamble disabled)\n"); 273 count = snprintf(buf, PAGE_SIZE, "0 (Short Preamble disabled)\n");
266 274
267 err = 0; 275 err = 0;
268 bcm43xx_unlock_noirq(bcm); 276 mutex_unlock(&bcm->mutex);
269 277
270 return err ? err : count; 278 return err ? err : count;
271} 279}
@@ -285,12 +293,14 @@ static ssize_t bcm43xx_attr_preamble_store(struct device *dev,
285 value = get_boolean(buf, count); 293 value = get_boolean(buf, count);
286 if (value < 0) 294 if (value < 0)
287 return value; 295 return value;
288 bcm43xx_lock_irqsafe(bcm, flags); 296 mutex_lock(&bcm->mutex);
297 spin_lock_irqsave(&bcm->irq_lock, flags);
289 298
290 bcm->short_preamble = !!value; 299 bcm->short_preamble = !!value;
291 300
292 err = 0; 301 err = 0;
293 bcm43xx_unlock_irqsafe(bcm, flags); 302 spin_unlock_irqrestore(&bcm->irq_lock, flags);
303 mutex_unlock(&bcm->mutex);
294 304
295 return err ? err : count; 305 return err ? err : count;
296} 306}
@@ -299,6 +309,70 @@ static DEVICE_ATTR(shortpreamble, 0644,
299 bcm43xx_attr_preamble_show, 309 bcm43xx_attr_preamble_show,
300 bcm43xx_attr_preamble_store); 310 bcm43xx_attr_preamble_store);
301 311
312static ssize_t bcm43xx_attr_phymode_store(struct device *dev,
313 struct device_attribute *attr,
314 const char *buf, size_t count)
315{
316 struct bcm43xx_private *bcm = dev_to_bcm(dev);
317 int phytype;
318 int err = -EINVAL;
319
320 if (count < 1)
321 goto out;
322 switch (buf[0]) {
323 case 'a': case 'A':
324 phytype = BCM43xx_PHYTYPE_A;
325 break;
326 case 'b': case 'B':
327 phytype = BCM43xx_PHYTYPE_B;
328 break;
329 case 'g': case 'G':
330 phytype = BCM43xx_PHYTYPE_G;
331 break;
332 default:
333 goto out;
334 }
335
336 mutex_lock(&(bcm)->mutex);
337 err = bcm43xx_select_wireless_core(bcm, phytype);
338 mutex_unlock(&(bcm)->mutex);
339 if (err == -ESRCH)
340 err = -ENODEV;
341
342out:
343 return err ? err : count;
344}
345
346static ssize_t bcm43xx_attr_phymode_show(struct device *dev,
347 struct device_attribute *attr,
348 char *buf)
349{
350 struct bcm43xx_private *bcm = dev_to_bcm(dev);
351 ssize_t count = 0;
352
353 mutex_lock(&(bcm)->mutex);
354 switch (bcm43xx_current_phy(bcm)->type) {
355 case BCM43xx_PHYTYPE_A:
356 snprintf(buf, PAGE_SIZE, "A");
357 break;
358 case BCM43xx_PHYTYPE_B:
359 snprintf(buf, PAGE_SIZE, "B");
360 break;
361 case BCM43xx_PHYTYPE_G:
362 snprintf(buf, PAGE_SIZE, "G");
363 break;
364 default:
365 assert(0);
366 }
367 mutex_unlock(&(bcm)->mutex);
368
369 return count;
370}
371
372static DEVICE_ATTR(phymode, 0644,
373 bcm43xx_attr_phymode_show,
374 bcm43xx_attr_phymode_store);
375
302int bcm43xx_sysfs_register(struct bcm43xx_private *bcm) 376int bcm43xx_sysfs_register(struct bcm43xx_private *bcm)
303{ 377{
304 struct device *dev = &bcm->pci_dev->dev; 378 struct device *dev = &bcm->pci_dev->dev;
@@ -315,9 +389,14 @@ int bcm43xx_sysfs_register(struct bcm43xx_private *bcm)
315 err = device_create_file(dev, &dev_attr_shortpreamble); 389 err = device_create_file(dev, &dev_attr_shortpreamble);
316 if (err) 390 if (err)
317 goto err_remove_interfmode; 391 goto err_remove_interfmode;
392 err = device_create_file(dev, &dev_attr_phymode);
393 if (err)
394 goto err_remove_shortpreamble;
318 395
319out: 396out:
320 return err; 397 return err;
398err_remove_shortpreamble:
399 device_remove_file(dev, &dev_attr_shortpreamble);
321err_remove_interfmode: 400err_remove_interfmode:
322 device_remove_file(dev, &dev_attr_interference); 401 device_remove_file(dev, &dev_attr_interference);
323err_remove_sprom: 402err_remove_sprom:
@@ -329,6 +408,7 @@ void bcm43xx_sysfs_unregister(struct bcm43xx_private *bcm)
329{ 408{
330 struct device *dev = &bcm->pci_dev->dev; 409 struct device *dev = &bcm->pci_dev->dev;
331 410
411 device_remove_file(dev, &dev_attr_phymode);
332 device_remove_file(dev, &dev_attr_shortpreamble); 412 device_remove_file(dev, &dev_attr_shortpreamble);
333 device_remove_file(dev, &dev_attr_interference); 413 device_remove_file(dev, &dev_attr_interference);
334 device_remove_file(dev, &dev_attr_sprom); 414 device_remove_file(dev, &dev_attr_sprom);
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_wx.c b/drivers/net/wireless/bcm43xx/bcm43xx_wx.c
index 5c36e29efff7..888077fc14c4 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_wx.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_wx.c
@@ -47,6 +47,8 @@
47#define BCM43xx_WX_VERSION 18 47#define BCM43xx_WX_VERSION 18
48 48
49#define MAX_WX_STRING 80 49#define MAX_WX_STRING 80
50/* FIXME: the next line is a guess as to what the maximum RSSI value might be */
51#define RX_RSSI_MAX 60
50 52
51 53
52static int bcm43xx_wx_get_name(struct net_device *net_dev, 54static int bcm43xx_wx_get_name(struct net_device *net_dev,
@@ -56,12 +58,11 @@ static int bcm43xx_wx_get_name(struct net_device *net_dev,
56{ 58{
57 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); 59 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
58 int i; 60 int i;
59 unsigned long flags;
60 struct bcm43xx_phyinfo *phy; 61 struct bcm43xx_phyinfo *phy;
61 char suffix[7] = { 0 }; 62 char suffix[7] = { 0 };
62 int have_a = 0, have_b = 0, have_g = 0; 63 int have_a = 0, have_b = 0, have_g = 0;
63 64
64 bcm43xx_lock_irqsafe(bcm, flags); 65 mutex_lock(&bcm->mutex);
65 for (i = 0; i < bcm->nr_80211_available; i++) { 66 for (i = 0; i < bcm->nr_80211_available; i++) {
66 phy = &(bcm->core_80211_ext[i].phy); 67 phy = &(bcm->core_80211_ext[i].phy);
67 switch (phy->type) { 68 switch (phy->type) {
@@ -77,7 +78,7 @@ static int bcm43xx_wx_get_name(struct net_device *net_dev,
77 assert(0); 78 assert(0);
78 } 79 }
79 } 80 }
80 bcm43xx_unlock_irqsafe(bcm, flags); 81 mutex_unlock(&bcm->mutex);
81 82
82 i = 0; 83 i = 0;
83 if (have_a) { 84 if (have_a) {
@@ -111,7 +112,9 @@ static int bcm43xx_wx_set_channelfreq(struct net_device *net_dev,
111 int freq; 112 int freq;
112 int err = -EINVAL; 113 int err = -EINVAL;
113 114
114 bcm43xx_lock_irqsafe(bcm, flags); 115 mutex_lock(&bcm->mutex);
116 spin_lock_irqsave(&bcm->irq_lock, flags);
117
115 if ((data->freq.m >= 0) && (data->freq.m <= 1000)) { 118 if ((data->freq.m >= 0) && (data->freq.m <= 1000)) {
116 channel = data->freq.m; 119 channel = data->freq.m;
117 freq = bcm43xx_channel_to_freq(bcm, channel); 120 freq = bcm43xx_channel_to_freq(bcm, channel);
@@ -131,7 +134,8 @@ static int bcm43xx_wx_set_channelfreq(struct net_device *net_dev,
131 err = 0; 134 err = 0;
132 } 135 }
133out_unlock: 136out_unlock:
134 bcm43xx_unlock_irqsafe(bcm, flags); 137 spin_unlock_irqrestore(&bcm->irq_lock, flags);
138 mutex_unlock(&bcm->mutex);
135 139
136 return err; 140 return err;
137} 141}
@@ -143,11 +147,10 @@ static int bcm43xx_wx_get_channelfreq(struct net_device *net_dev,
143{ 147{
144 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); 148 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
145 struct bcm43xx_radioinfo *radio; 149 struct bcm43xx_radioinfo *radio;
146 unsigned long flags;
147 int err = -ENODEV; 150 int err = -ENODEV;
148 u16 channel; 151 u16 channel;
149 152
150 bcm43xx_lock_irqsafe(bcm, flags); 153 mutex_lock(&bcm->mutex);
151 radio = bcm43xx_current_radio(bcm); 154 radio = bcm43xx_current_radio(bcm);
152 channel = radio->channel; 155 channel = radio->channel;
153 if (channel == 0xFF) { 156 if (channel == 0xFF) {
@@ -162,7 +165,7 @@ static int bcm43xx_wx_get_channelfreq(struct net_device *net_dev,
162 165
163 err = 0; 166 err = 0;
164out_unlock: 167out_unlock:
165 bcm43xx_unlock_irqsafe(bcm, flags); 168 mutex_unlock(&bcm->mutex);
166 169
167 return err; 170 return err;
168} 171}
@@ -180,13 +183,15 @@ static int bcm43xx_wx_set_mode(struct net_device *net_dev,
180 if (mode == IW_MODE_AUTO) 183 if (mode == IW_MODE_AUTO)
181 mode = BCM43xx_INITIAL_IWMODE; 184 mode = BCM43xx_INITIAL_IWMODE;
182 185
183 bcm43xx_lock_irqsafe(bcm, flags); 186 mutex_lock(&bcm->mutex);
187 spin_lock_irqsave(&bcm->irq_lock, flags);
184 if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) { 188 if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) {
185 if (bcm->ieee->iw_mode != mode) 189 if (bcm->ieee->iw_mode != mode)
186 bcm43xx_set_iwmode(bcm, mode); 190 bcm43xx_set_iwmode(bcm, mode);
187 } else 191 } else
188 bcm->ieee->iw_mode = mode; 192 bcm->ieee->iw_mode = mode;
189 bcm43xx_unlock_irqsafe(bcm, flags); 193 spin_unlock_irqrestore(&bcm->irq_lock, flags);
194 mutex_unlock(&bcm->mutex);
190 195
191 return 0; 196 return 0;
192} 197}
@@ -197,11 +202,10 @@ static int bcm43xx_wx_get_mode(struct net_device *net_dev,
197 char *extra) 202 char *extra)
198{ 203{
199 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); 204 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
200 unsigned long flags;
201 205
202 bcm43xx_lock_irqsafe(bcm, flags); 206 mutex_lock(&bcm->mutex);
203 data->mode = bcm->ieee->iw_mode; 207 data->mode = bcm->ieee->iw_mode;
204 bcm43xx_unlock_irqsafe(bcm, flags); 208 mutex_unlock(&bcm->mutex);
205 209
206 return 0; 210 return 0;
207} 211}
@@ -214,7 +218,6 @@ static int bcm43xx_wx_get_rangeparams(struct net_device *net_dev,
214 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); 218 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
215 struct iw_range *range = (struct iw_range *)extra; 219 struct iw_range *range = (struct iw_range *)extra;
216 const struct ieee80211_geo *geo; 220 const struct ieee80211_geo *geo;
217 unsigned long flags;
218 int i, j; 221 int i, j;
219 struct bcm43xx_phyinfo *phy; 222 struct bcm43xx_phyinfo *phy;
220 223
@@ -226,15 +229,14 @@ static int bcm43xx_wx_get_rangeparams(struct net_device *net_dev,
226 range->throughput = 27 * 1000 * 1000; 229 range->throughput = 27 * 1000 * 1000;
227 230
228 range->max_qual.qual = 100; 231 range->max_qual.qual = 100;
229 /* TODO: Real max RSSI */ 232 range->max_qual.level = 146; /* set floor at -110 dBm (146 - 256) */
230 range->max_qual.level = 3; 233 range->max_qual.noise = 146;
231 range->max_qual.noise = 100; 234 range->max_qual.updated = IW_QUAL_ALL_UPDATED;
232 range->max_qual.updated = 7;
233 235
234 range->avg_qual.qual = 70; 236 range->avg_qual.qual = 50;
235 range->avg_qual.level = 2; 237 range->avg_qual.level = 0;
236 range->avg_qual.noise = 40; 238 range->avg_qual.noise = 0;
237 range->avg_qual.updated = 7; 239 range->avg_qual.updated = IW_QUAL_ALL_UPDATED;
238 240
239 range->min_rts = BCM43xx_MIN_RTS_THRESHOLD; 241 range->min_rts = BCM43xx_MIN_RTS_THRESHOLD;
240 range->max_rts = BCM43xx_MAX_RTS_THRESHOLD; 242 range->max_rts = BCM43xx_MAX_RTS_THRESHOLD;
@@ -254,7 +256,7 @@ static int bcm43xx_wx_get_rangeparams(struct net_device *net_dev,
254 IW_ENC_CAPA_CIPHER_TKIP | 256 IW_ENC_CAPA_CIPHER_TKIP |
255 IW_ENC_CAPA_CIPHER_CCMP; 257 IW_ENC_CAPA_CIPHER_CCMP;
256 258
257 bcm43xx_lock_irqsafe(bcm, flags); 259 mutex_lock(&bcm->mutex);
258 phy = bcm43xx_current_phy(bcm); 260 phy = bcm43xx_current_phy(bcm);
259 261
260 range->num_bitrates = 0; 262 range->num_bitrates = 0;
@@ -301,7 +303,7 @@ static int bcm43xx_wx_get_rangeparams(struct net_device *net_dev,
301 } 303 }
302 range->num_frequency = j; 304 range->num_frequency = j;
303 305
304 bcm43xx_unlock_irqsafe(bcm, flags); 306 mutex_unlock(&bcm->mutex);
305 307
306 return 0; 308 return 0;
307} 309}
@@ -314,11 +316,11 @@ static int bcm43xx_wx_set_nick(struct net_device *net_dev,
314 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); 316 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
315 size_t len; 317 size_t len;
316 318
317 bcm43xx_lock_noirq(bcm); 319 mutex_lock(&bcm->mutex);
318 len = min((size_t)data->data.length, (size_t)IW_ESSID_MAX_SIZE); 320 len = min((size_t)data->data.length, (size_t)IW_ESSID_MAX_SIZE);
319 memcpy(bcm->nick, extra, len); 321 memcpy(bcm->nick, extra, len);
320 bcm->nick[len] = '\0'; 322 bcm->nick[len] = '\0';
321 bcm43xx_unlock_noirq(bcm); 323 mutex_unlock(&bcm->mutex);
322 324
323 return 0; 325 return 0;
324} 326}
@@ -331,12 +333,12 @@ static int bcm43xx_wx_get_nick(struct net_device *net_dev,
331 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); 333 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
332 size_t len; 334 size_t len;
333 335
334 bcm43xx_lock_noirq(bcm); 336 mutex_lock(&bcm->mutex);
335 len = strlen(bcm->nick) + 1; 337 len = strlen(bcm->nick) + 1;
336 memcpy(extra, bcm->nick, len); 338 memcpy(extra, bcm->nick, len);
337 data->data.length = (__u16)len; 339 data->data.length = (__u16)len;
338 data->data.flags = 1; 340 data->data.flags = 1;
339 bcm43xx_unlock_noirq(bcm); 341 mutex_unlock(&bcm->mutex);
340 342
341 return 0; 343 return 0;
342} 344}
@@ -350,7 +352,8 @@ static int bcm43xx_wx_set_rts(struct net_device *net_dev,
350 unsigned long flags; 352 unsigned long flags;
351 int err = -EINVAL; 353 int err = -EINVAL;
352 354
353 bcm43xx_lock_irqsafe(bcm, flags); 355 mutex_lock(&bcm->mutex);
356 spin_lock_irqsave(&bcm->irq_lock, flags);
354 if (data->rts.disabled) { 357 if (data->rts.disabled) {
355 bcm->rts_threshold = BCM43xx_MAX_RTS_THRESHOLD; 358 bcm->rts_threshold = BCM43xx_MAX_RTS_THRESHOLD;
356 err = 0; 359 err = 0;
@@ -361,7 +364,8 @@ static int bcm43xx_wx_set_rts(struct net_device *net_dev,
361 err = 0; 364 err = 0;
362 } 365 }
363 } 366 }
364 bcm43xx_unlock_irqsafe(bcm, flags); 367 spin_unlock_irqrestore(&bcm->irq_lock, flags);
368 mutex_unlock(&bcm->mutex);
365 369
366 return err; 370 return err;
367} 371}
@@ -372,13 +376,12 @@ static int bcm43xx_wx_get_rts(struct net_device *net_dev,
372 char *extra) 376 char *extra)
373{ 377{
374 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); 378 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
375 unsigned long flags;
376 379
377 bcm43xx_lock_irqsafe(bcm, flags); 380 mutex_lock(&bcm->mutex);
378 data->rts.value = bcm->rts_threshold; 381 data->rts.value = bcm->rts_threshold;
379 data->rts.fixed = 0; 382 data->rts.fixed = 0;
380 data->rts.disabled = (bcm->rts_threshold == BCM43xx_MAX_RTS_THRESHOLD); 383 data->rts.disabled = (bcm->rts_threshold == BCM43xx_MAX_RTS_THRESHOLD);
381 bcm43xx_unlock_irqsafe(bcm, flags); 384 mutex_unlock(&bcm->mutex);
382 385
383 return 0; 386 return 0;
384} 387}
@@ -392,7 +395,8 @@ static int bcm43xx_wx_set_frag(struct net_device *net_dev,
392 unsigned long flags; 395 unsigned long flags;
393 int err = -EINVAL; 396 int err = -EINVAL;
394 397
395 bcm43xx_lock_irqsafe(bcm, flags); 398 mutex_lock(&bcm->mutex);
399 spin_lock_irqsave(&bcm->irq_lock, flags);
396 if (data->frag.disabled) { 400 if (data->frag.disabled) {
397 bcm->ieee->fts = MAX_FRAG_THRESHOLD; 401 bcm->ieee->fts = MAX_FRAG_THRESHOLD;
398 err = 0; 402 err = 0;
@@ -403,7 +407,8 @@ static int bcm43xx_wx_set_frag(struct net_device *net_dev,
403 err = 0; 407 err = 0;
404 } 408 }
405 } 409 }
406 bcm43xx_unlock_irqsafe(bcm, flags); 410 spin_unlock_irqrestore(&bcm->irq_lock, flags);
411 mutex_unlock(&bcm->mutex);
407 412
408 return err; 413 return err;
409} 414}
@@ -414,13 +419,12 @@ static int bcm43xx_wx_get_frag(struct net_device *net_dev,
414 char *extra) 419 char *extra)
415{ 420{
416 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); 421 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
417 unsigned long flags;
418 422
419 bcm43xx_lock_irqsafe(bcm, flags); 423 mutex_lock(&bcm->mutex);
420 data->frag.value = bcm->ieee->fts; 424 data->frag.value = bcm->ieee->fts;
421 data->frag.fixed = 0; 425 data->frag.fixed = 0;
422 data->frag.disabled = (bcm->ieee->fts == MAX_FRAG_THRESHOLD); 426 data->frag.disabled = (bcm->ieee->fts == MAX_FRAG_THRESHOLD);
423 bcm43xx_unlock_irqsafe(bcm, flags); 427 mutex_unlock(&bcm->mutex);
424 428
425 return 0; 429 return 0;
426} 430}
@@ -442,7 +446,8 @@ static int bcm43xx_wx_set_xmitpower(struct net_device *net_dev,
442 return -EOPNOTSUPP; 446 return -EOPNOTSUPP;
443 } 447 }
444 448
445 bcm43xx_lock_irqsafe(bcm, flags); 449 mutex_lock(&bcm->mutex);
450 spin_lock_irqsave(&bcm->irq_lock, flags);
446 if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) 451 if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED)
447 goto out_unlock; 452 goto out_unlock;
448 radio = bcm43xx_current_radio(bcm); 453 radio = bcm43xx_current_radio(bcm);
@@ -466,7 +471,8 @@ static int bcm43xx_wx_set_xmitpower(struct net_device *net_dev,
466 err = 0; 471 err = 0;
467 472
468out_unlock: 473out_unlock:
469 bcm43xx_unlock_irqsafe(bcm, flags); 474 spin_unlock_irqrestore(&bcm->irq_lock, flags);
475 mutex_unlock(&bcm->mutex);
470 476
471 return err; 477 return err;
472} 478}
@@ -478,10 +484,9 @@ static int bcm43xx_wx_get_xmitpower(struct net_device *net_dev,
478{ 484{
479 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); 485 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
480 struct bcm43xx_radioinfo *radio; 486 struct bcm43xx_radioinfo *radio;
481 unsigned long flags;
482 int err = -ENODEV; 487 int err = -ENODEV;
483 488
484 bcm43xx_lock_irqsafe(bcm, flags); 489 mutex_lock(&bcm->mutex);
485 if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) 490 if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED)
486 goto out_unlock; 491 goto out_unlock;
487 radio = bcm43xx_current_radio(bcm); 492 radio = bcm43xx_current_radio(bcm);
@@ -493,7 +498,7 @@ static int bcm43xx_wx_get_xmitpower(struct net_device *net_dev,
493 498
494 err = 0; 499 err = 0;
495out_unlock: 500out_unlock:
496 bcm43xx_unlock_irqsafe(bcm, flags); 501 mutex_unlock(&bcm->mutex);
497 502
498 return err; 503 return err;
499} 504}
@@ -580,7 +585,8 @@ static int bcm43xx_wx_set_interfmode(struct net_device *net_dev,
580 return -EINVAL; 585 return -EINVAL;
581 } 586 }
582 587
583 bcm43xx_lock_irqsafe(bcm, flags); 588 mutex_lock(&bcm->mutex);
589 spin_lock_irqsave(&bcm->irq_lock, flags);
584 if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) { 590 if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) {
585 err = bcm43xx_radio_set_interference_mitigation(bcm, mode); 591 err = bcm43xx_radio_set_interference_mitigation(bcm, mode);
586 if (err) { 592 if (err) {
@@ -595,7 +601,8 @@ static int bcm43xx_wx_set_interfmode(struct net_device *net_dev,
595 } else 601 } else
596 bcm43xx_current_radio(bcm)->interfmode = mode; 602 bcm43xx_current_radio(bcm)->interfmode = mode;
597 } 603 }
598 bcm43xx_unlock_irqsafe(bcm, flags); 604 spin_unlock_irqrestore(&bcm->irq_lock, flags);
605 mutex_unlock(&bcm->mutex);
599 606
600 return err; 607 return err;
601} 608}
@@ -606,12 +613,11 @@ static int bcm43xx_wx_get_interfmode(struct net_device *net_dev,
606 char *extra) 613 char *extra)
607{ 614{
608 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); 615 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
609 unsigned long flags;
610 int mode; 616 int mode;
611 617
612 bcm43xx_lock_irqsafe(bcm, flags); 618 mutex_lock(&bcm->mutex);
613 mode = bcm43xx_current_radio(bcm)->interfmode; 619 mode = bcm43xx_current_radio(bcm)->interfmode;
614 bcm43xx_unlock_irqsafe(bcm, flags); 620 mutex_unlock(&bcm->mutex);
615 621
616 switch (mode) { 622 switch (mode) {
617 case BCM43xx_RADIO_INTERFMODE_NONE: 623 case BCM43xx_RADIO_INTERFMODE_NONE:
@@ -641,9 +647,11 @@ static int bcm43xx_wx_set_shortpreamble(struct net_device *net_dev,
641 int on; 647 int on;
642 648
643 on = *((int *)extra); 649 on = *((int *)extra);
644 bcm43xx_lock_irqsafe(bcm, flags); 650 mutex_lock(&bcm->mutex);
651 spin_lock_irqsave(&bcm->irq_lock, flags);
645 bcm->short_preamble = !!on; 652 bcm->short_preamble = !!on;
646 bcm43xx_unlock_irqsafe(bcm, flags); 653 spin_unlock_irqrestore(&bcm->irq_lock, flags);
654 mutex_unlock(&bcm->mutex);
647 655
648 return 0; 656 return 0;
649} 657}
@@ -654,12 +662,11 @@ static int bcm43xx_wx_get_shortpreamble(struct net_device *net_dev,
654 char *extra) 662 char *extra)
655{ 663{
656 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); 664 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
657 unsigned long flags;
658 int on; 665 int on;
659 666
660 bcm43xx_lock_irqsafe(bcm, flags); 667 mutex_lock(&bcm->mutex);
661 on = bcm->short_preamble; 668 on = bcm->short_preamble;
662 bcm43xx_unlock_irqsafe(bcm, flags); 669 mutex_unlock(&bcm->mutex);
663 670
664 if (on) 671 if (on)
665 strncpy(extra, "1 (Short Preamble enabled)", MAX_WX_STRING); 672 strncpy(extra, "1 (Short Preamble enabled)", MAX_WX_STRING);
@@ -681,11 +688,13 @@ static int bcm43xx_wx_set_swencryption(struct net_device *net_dev,
681 688
682 on = *((int *)extra); 689 on = *((int *)extra);
683 690
684 bcm43xx_lock_irqsafe(bcm, flags); 691 mutex_lock(&bcm->mutex);
692 spin_lock_irqsave(&bcm->irq_lock, flags);
685 bcm->ieee->host_encrypt = !!on; 693 bcm->ieee->host_encrypt = !!on;
686 bcm->ieee->host_decrypt = !!on; 694 bcm->ieee->host_decrypt = !!on;
687 bcm->ieee->host_build_iv = !on; 695 bcm->ieee->host_build_iv = !on;
688 bcm43xx_unlock_irqsafe(bcm, flags); 696 spin_unlock_irqrestore(&bcm->irq_lock, flags);
697 mutex_unlock(&bcm->mutex);
689 698
690 return 0; 699 return 0;
691} 700}
@@ -696,12 +705,11 @@ static int bcm43xx_wx_get_swencryption(struct net_device *net_dev,
696 char *extra) 705 char *extra)
697{ 706{
698 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); 707 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
699 unsigned long flags;
700 int on; 708 int on;
701 709
702 bcm43xx_lock_irqsafe(bcm, flags); 710 mutex_lock(&bcm->mutex);
703 on = bcm->ieee->host_encrypt; 711 on = bcm->ieee->host_encrypt;
704 bcm43xx_unlock_irqsafe(bcm, flags); 712 mutex_unlock(&bcm->mutex);
705 713
706 if (on) 714 if (on)
707 strncpy(extra, "1 (SW encryption enabled) ", MAX_WX_STRING); 715 strncpy(extra, "1 (SW encryption enabled) ", MAX_WX_STRING);
@@ -764,11 +772,13 @@ static int bcm43xx_wx_sprom_read(struct net_device *net_dev,
764 if (!sprom) 772 if (!sprom)
765 goto out; 773 goto out;
766 774
767 bcm43xx_lock_irqsafe(bcm, flags); 775 mutex_lock(&bcm->mutex);
776 spin_lock_irqsave(&bcm->irq_lock, flags);
768 err = -ENODEV; 777 err = -ENODEV;
769 if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) 778 if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED)
770 err = bcm43xx_sprom_read(bcm, sprom); 779 err = bcm43xx_sprom_read(bcm, sprom);
771 bcm43xx_unlock_irqsafe(bcm, flags); 780 spin_unlock_irqrestore(&bcm->irq_lock, flags);
781 mutex_unlock(&bcm->mutex);
772 if (!err) 782 if (!err)
773 data->data.length = sprom2hex(sprom, extra); 783 data->data.length = sprom2hex(sprom, extra);
774 kfree(sprom); 784 kfree(sprom);
@@ -809,11 +819,15 @@ static int bcm43xx_wx_sprom_write(struct net_device *net_dev,
809 if (err) 819 if (err)
810 goto out_kfree; 820 goto out_kfree;
811 821
812 bcm43xx_lock_irqsafe(bcm, flags); 822 mutex_lock(&bcm->mutex);
823 spin_lock_irqsave(&bcm->irq_lock, flags);
824 spin_lock(&bcm->leds_lock);
813 err = -ENODEV; 825 err = -ENODEV;
814 if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) 826 if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED)
815 err = bcm43xx_sprom_write(bcm, sprom); 827 err = bcm43xx_sprom_write(bcm, sprom);
816 bcm43xx_unlock_irqsafe(bcm, flags); 828 spin_unlock(&bcm->leds_lock);
829 spin_unlock_irqrestore(&bcm->irq_lock, flags);
830 mutex_unlock(&bcm->mutex);
817out_kfree: 831out_kfree:
818 kfree(sprom); 832 kfree(sprom);
819out: 833out:
@@ -827,6 +841,10 @@ static struct iw_statistics *bcm43xx_get_wireless_stats(struct net_device *net_d
827 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); 841 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
828 struct ieee80211softmac_device *mac = ieee80211_priv(net_dev); 842 struct ieee80211softmac_device *mac = ieee80211_priv(net_dev);
829 struct iw_statistics *wstats; 843 struct iw_statistics *wstats;
844 struct ieee80211_network *network = NULL;
845 static int tmp_level = 0;
846 static int tmp_qual = 0;
847 unsigned long flags;
830 848
831 wstats = &bcm->stats.wstats; 849 wstats = &bcm->stats.wstats;
832 if (!mac->associated) { 850 if (!mac->associated) {
@@ -844,16 +862,28 @@ static struct iw_statistics *bcm43xx_get_wireless_stats(struct net_device *net_d
844 wstats->qual.level = 0; 862 wstats->qual.level = 0;
845 wstats->qual.noise = 0; 863 wstats->qual.noise = 0;
846 wstats->qual.updated = 7; 864 wstats->qual.updated = 7;
847 wstats->qual.updated |= IW_QUAL_NOISE_INVALID | 865 wstats->qual.updated |= IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
848 IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_INVALID;
849 return wstats; 866 return wstats;
850 } 867 }
851 /* fill in the real statistics when iface associated */ 868 /* fill in the real statistics when iface associated */
852 wstats->qual.qual = 100; // TODO: get the real signal quality 869 spin_lock_irqsave(&mac->ieee->lock, flags);
853 wstats->qual.level = 3 - bcm->stats.link_quality; 870 list_for_each_entry(network, &mac->ieee->network_list, list) {
871 if (!memcmp(mac->associnfo.bssid, network->bssid, ETH_ALEN)) {
872 if (!tmp_level) { /* get initial values */
873 tmp_level = network->stats.signal;
874 tmp_qual = network->stats.rssi;
875 } else { /* smooth results */
876 tmp_level = (15 * tmp_level + network->stats.signal)/16;
877 tmp_qual = (15 * tmp_qual + network->stats.rssi)/16;
878 }
879 break;
880 }
881 }
882 spin_unlock_irqrestore(&mac->ieee->lock, flags);
883 wstats->qual.level = tmp_level;
884 wstats->qual.qual = 100 * tmp_qual / RX_RSSI_MAX;
854 wstats->qual.noise = bcm->stats.noise; 885 wstats->qual.noise = bcm->stats.noise;
855 wstats->qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED | 886 wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
856 IW_QUAL_NOISE_UPDATED;
857 wstats->discard.code = bcm->ieee->ieee_stats.rx_discards_undecryptable; 887 wstats->discard.code = bcm->ieee->ieee_stats.rx_discards_undecryptable;
858 wstats->discard.retries = bcm->ieee->ieee_stats.tx_retry_limit_exceeded; 888 wstats->discard.retries = bcm->ieee->ieee_stats.tx_retry_limit_exceeded;
859 wstats->discard.nwid = bcm->ieee->ieee_stats.tx_discards_wrong_sa; 889 wstats->discard.nwid = bcm->ieee->ieee_stats.tx_discards_wrong_sa;
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_xmit.c b/drivers/net/wireless/bcm43xx/bcm43xx_xmit.c
index 6dbd855b3647..c0efbfe605a5 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_xmit.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_xmit.c
@@ -492,16 +492,15 @@ int bcm43xx_rx(struct bcm43xx_private *bcm,
492 492
493 memset(&stats, 0, sizeof(stats)); 493 memset(&stats, 0, sizeof(stats));
494 stats.mac_time = le16_to_cpu(rxhdr->mactime); 494 stats.mac_time = le16_to_cpu(rxhdr->mactime);
495 stats.rssi = bcm43xx_rssi_postprocess(bcm, rxhdr->rssi, is_ofdm, 495 stats.rssi = rxhdr->rssi;
496 stats.signal = bcm43xx_rssi_postprocess(bcm, rxhdr->rssi, is_ofdm,
496 !!(rxflags1 & BCM43xx_RXHDR_FLAGS1_2053RSSIADJ), 497 !!(rxflags1 & BCM43xx_RXHDR_FLAGS1_2053RSSIADJ),
497 !!(rxflags3 & BCM43xx_RXHDR_FLAGS3_2050RSSIADJ)); 498 !!(rxflags3 & BCM43xx_RXHDR_FLAGS3_2050RSSIADJ));
498 stats.signal = rxhdr->signal_quality; //FIXME
499//TODO stats.noise = 499//TODO stats.noise =
500 if (is_ofdm) 500 if (is_ofdm)
501 stats.rate = bcm43xx_plcp_get_bitrate_ofdm(plcp); 501 stats.rate = bcm43xx_plcp_get_bitrate_ofdm(plcp);
502 else 502 else
503 stats.rate = bcm43xx_plcp_get_bitrate_cck(plcp); 503 stats.rate = bcm43xx_plcp_get_bitrate_cck(plcp);
504//printk("RX ofdm %d, rate == %u\n", is_ofdm, stats.rate);
505 stats.received_channel = radio->channel; 504 stats.received_channel = radio->channel;
506//TODO stats.control = 505//TODO stats.control =
507 stats.mask = IEEE80211_STATMASK_SIGNAL | 506 stats.mask = IEEE80211_STATMASK_SIGNAL |
diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c
index e955db435b30..5d5dab6a209c 100644
--- a/drivers/net/wireless/ipw2100.c
+++ b/drivers/net/wireless/ipw2100.c
@@ -6254,13 +6254,14 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
6254 * member to call a function that then just turns and calls ipw2100_up. 6254 * member to call a function that then just turns and calls ipw2100_up.
6255 * net_dev->init is called after name allocation but before the 6255 * net_dev->init is called after name allocation but before the
6256 * notifier chain is called */ 6256 * notifier chain is called */
6257 mutex_lock(&priv->action_mutex);
6258 err = register_netdev(dev); 6257 err = register_netdev(dev);
6259 if (err) { 6258 if (err) {
6260 printk(KERN_WARNING DRV_NAME 6259 printk(KERN_WARNING DRV_NAME
6261 "Error calling register_netdev.\n"); 6260 "Error calling register_netdev.\n");
6262 goto fail_unlock; 6261 goto fail;
6263 } 6262 }
6263
6264 mutex_lock(&priv->action_mutex);
6264 registered = 1; 6265 registered = 1;
6265 6266
6266 IPW_DEBUG_INFO("%s: Bound to %s\n", dev->name, pci_name(pci_dev)); 6267 IPW_DEBUG_INFO("%s: Bound to %s\n", dev->name, pci_name(pci_dev));
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index b3300ffe4eec..fa245f126c84 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -70,7 +70,7 @@
70#define VQ 70#define VQ
71#endif 71#endif
72 72
73#define IPW2200_VERSION "1.1.2" VK VD VM VP VR VQ 73#define IPW2200_VERSION "1.1.4" VK VD VM VP VR VQ
74#define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2200/2915 Network Driver" 74#define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2200/2915 Network Driver"
75#define DRV_COPYRIGHT "Copyright(c) 2003-2006 Intel Corporation" 75#define DRV_COPYRIGHT "Copyright(c) 2003-2006 Intel Corporation"
76#define DRV_VERSION IPW2200_VERSION 76#define DRV_VERSION IPW2200_VERSION
@@ -83,9 +83,7 @@ MODULE_AUTHOR(DRV_COPYRIGHT);
83MODULE_LICENSE("GPL"); 83MODULE_LICENSE("GPL");
84 84
85static int cmdlog = 0; 85static int cmdlog = 0;
86#ifdef CONFIG_IPW2200_DEBUG
87static int debug = 0; 86static int debug = 0;
88#endif
89static int channel = 0; 87static int channel = 0;
90static int mode = 0; 88static int mode = 0;
91 89
@@ -567,7 +565,6 @@ static inline void ipw_disable_interrupts(struct ipw_priv *priv)
567 spin_unlock_irqrestore(&priv->irq_lock, flags); 565 spin_unlock_irqrestore(&priv->irq_lock, flags);
568} 566}
569 567
570#ifdef CONFIG_IPW2200_DEBUG
571static char *ipw_error_desc(u32 val) 568static char *ipw_error_desc(u32 val)
572{ 569{
573 switch (val) { 570 switch (val) {
@@ -634,7 +631,6 @@ static void ipw_dump_error_log(struct ipw_priv *priv,
634 error->log[i].time, 631 error->log[i].time,
635 error->log[i].data, error->log[i].event); 632 error->log[i].data, error->log[i].event);
636} 633}
637#endif
638 634
639static inline int ipw_is_init(struct ipw_priv *priv) 635static inline int ipw_is_init(struct ipw_priv *priv)
640{ 636{
@@ -1435,9 +1431,7 @@ static ssize_t store_scan_age(struct device *d, struct device_attribute *attr,
1435 const char *buf, size_t count) 1431 const char *buf, size_t count)
1436{ 1432{
1437 struct ipw_priv *priv = dev_get_drvdata(d); 1433 struct ipw_priv *priv = dev_get_drvdata(d);
1438#ifdef CONFIG_IPW2200_DEBUG
1439 struct net_device *dev = priv->net_dev; 1434 struct net_device *dev = priv->net_dev;
1440#endif
1441 char buffer[] = "00000000"; 1435 char buffer[] = "00000000";
1442 unsigned long len = 1436 unsigned long len =
1443 (sizeof(buffer) - 1) > count ? count : sizeof(buffer) - 1; 1437 (sizeof(buffer) - 1) > count ? count : sizeof(buffer) - 1;
@@ -1958,14 +1952,12 @@ static void ipw_irq_tasklet(struct ipw_priv *priv)
1958 IPW_WARNING("Firmware error detected. Restarting.\n"); 1952 IPW_WARNING("Firmware error detected. Restarting.\n");
1959 if (priv->error) { 1953 if (priv->error) {
1960 IPW_DEBUG_FW("Sysfs 'error' log already exists.\n"); 1954 IPW_DEBUG_FW("Sysfs 'error' log already exists.\n");
1961#ifdef CONFIG_IPW2200_DEBUG
1962 if (ipw_debug_level & IPW_DL_FW_ERRORS) { 1955 if (ipw_debug_level & IPW_DL_FW_ERRORS) {
1963 struct ipw_fw_error *error = 1956 struct ipw_fw_error *error =
1964 ipw_alloc_error_log(priv); 1957 ipw_alloc_error_log(priv);
1965 ipw_dump_error_log(priv, error); 1958 ipw_dump_error_log(priv, error);
1966 kfree(error); 1959 kfree(error);
1967 } 1960 }
1968#endif
1969 } else { 1961 } else {
1970 priv->error = ipw_alloc_error_log(priv); 1962 priv->error = ipw_alloc_error_log(priv);
1971 if (priv->error) 1963 if (priv->error)
@@ -1973,10 +1965,8 @@ static void ipw_irq_tasklet(struct ipw_priv *priv)
1973 else 1965 else
1974 IPW_DEBUG_FW("Error allocating sysfs 'error' " 1966 IPW_DEBUG_FW("Error allocating sysfs 'error' "
1975 "log.\n"); 1967 "log.\n");
1976#ifdef CONFIG_IPW2200_DEBUG
1977 if (ipw_debug_level & IPW_DL_FW_ERRORS) 1968 if (ipw_debug_level & IPW_DL_FW_ERRORS)
1978 ipw_dump_error_log(priv, priv->error); 1969 ipw_dump_error_log(priv, priv->error);
1979#endif
1980 } 1970 }
1981 1971
1982 /* XXX: If hardware encryption is for WPA/WPA2, 1972 /* XXX: If hardware encryption is for WPA/WPA2,
@@ -2287,7 +2277,7 @@ static int ipw_send_scan_abort(struct ipw_priv *priv)
2287static int ipw_set_sensitivity(struct ipw_priv *priv, u16 sens) 2277static int ipw_set_sensitivity(struct ipw_priv *priv, u16 sens)
2288{ 2278{
2289 struct ipw_sensitivity_calib calib = { 2279 struct ipw_sensitivity_calib calib = {
2290 .beacon_rssi_raw = sens, 2280 .beacon_rssi_raw = cpu_to_le16(sens),
2291 }; 2281 };
2292 2282
2293 return ipw_send_cmd_pdu(priv, IPW_CMD_SENSITIVITY_CALIB, sizeof(calib), 2283 return ipw_send_cmd_pdu(priv, IPW_CMD_SENSITIVITY_CALIB, sizeof(calib),
@@ -2353,6 +2343,7 @@ static int ipw_send_card_disable(struct ipw_priv *priv, u32 phy_off)
2353 return -1; 2343 return -1;
2354 } 2344 }
2355 2345
2346 phy_off = cpu_to_le32(phy_off);
2356 return ipw_send_cmd_pdu(priv, IPW_CMD_CARD_DISABLE, sizeof(phy_off), 2347 return ipw_send_cmd_pdu(priv, IPW_CMD_CARD_DISABLE, sizeof(phy_off),
2357 &phy_off); 2348 &phy_off);
2358} 2349}
@@ -2414,7 +2405,7 @@ static int ipw_set_tx_power(struct ipw_priv *priv)
2414static int ipw_send_rts_threshold(struct ipw_priv *priv, u16 rts) 2405static int ipw_send_rts_threshold(struct ipw_priv *priv, u16 rts)
2415{ 2406{
2416 struct ipw_rts_threshold rts_threshold = { 2407 struct ipw_rts_threshold rts_threshold = {
2417 .rts_threshold = rts, 2408 .rts_threshold = cpu_to_le16(rts),
2418 }; 2409 };
2419 2410
2420 if (!priv) { 2411 if (!priv) {
@@ -2429,7 +2420,7 @@ static int ipw_send_rts_threshold(struct ipw_priv *priv, u16 rts)
2429static int ipw_send_frag_threshold(struct ipw_priv *priv, u16 frag) 2420static int ipw_send_frag_threshold(struct ipw_priv *priv, u16 frag)
2430{ 2421{
2431 struct ipw_frag_threshold frag_threshold = { 2422 struct ipw_frag_threshold frag_threshold = {
2432 .frag_threshold = frag, 2423 .frag_threshold = cpu_to_le16(frag),
2433 }; 2424 };
2434 2425
2435 if (!priv) { 2426 if (!priv) {
@@ -2464,6 +2455,7 @@ static int ipw_send_power_mode(struct ipw_priv *priv, u32 mode)
2464 break; 2455 break;
2465 } 2456 }
2466 2457
2458 param = cpu_to_le32(mode);
2467 return ipw_send_cmd_pdu(priv, IPW_CMD_POWER_MODE, sizeof(param), 2459 return ipw_send_cmd_pdu(priv, IPW_CMD_POWER_MODE, sizeof(param),
2468 &param); 2460 &param);
2469} 2461}
@@ -2667,7 +2659,7 @@ static void ipw_fw_dma_abort(struct ipw_priv *priv)
2667 2659
2668 IPW_DEBUG_FW(">> :\n"); 2660 IPW_DEBUG_FW(">> :\n");
2669 2661
2670 //set the Stop and Abort bit 2662 /* set the Stop and Abort bit */
2671 control = DMA_CONTROL_SMALL_CB_CONST_VALUE | DMA_CB_STOP_AND_ABORT; 2663 control = DMA_CONTROL_SMALL_CB_CONST_VALUE | DMA_CB_STOP_AND_ABORT;
2672 ipw_write_reg32(priv, IPW_DMA_I_DMA_CONTROL, control); 2664 ipw_write_reg32(priv, IPW_DMA_I_DMA_CONTROL, control);
2673 priv->sram_desc.last_cb_index = 0; 2665 priv->sram_desc.last_cb_index = 0;
@@ -3002,8 +2994,6 @@ static int ipw_load_ucode(struct ipw_priv *priv, u8 * data, size_t len)
3002 if (rc < 0) 2994 if (rc < 0)
3003 return rc; 2995 return rc;
3004 2996
3005// spin_lock_irqsave(&priv->lock, flags);
3006
3007 for (addr = IPW_SHARED_LOWER_BOUND; 2997 for (addr = IPW_SHARED_LOWER_BOUND;
3008 addr < IPW_REGISTER_DOMAIN1_END; addr += 4) { 2998 addr < IPW_REGISTER_DOMAIN1_END; addr += 4) {
3009 ipw_write32(priv, addr, 0); 2999 ipw_write32(priv, addr, 0);
@@ -3097,8 +3087,6 @@ static int ipw_load_ucode(struct ipw_priv *priv, u8 * data, size_t len)
3097 firmware have problem getting alive resp. */ 3087 firmware have problem getting alive resp. */
3098 ipw_write_reg8(priv, IPW_BASEBAND_CONTROL_STATUS, 0); 3088 ipw_write_reg8(priv, IPW_BASEBAND_CONTROL_STATUS, 0);
3099 3089
3100// spin_unlock_irqrestore(&priv->lock, flags);
3101
3102 return rc; 3090 return rc;
3103} 3091}
3104 3092
@@ -3919,7 +3907,6 @@ static const struct ipw_status_code ipw_status_codes[] = {
3919 {0x2E, "Cipher suite is rejected per security policy"}, 3907 {0x2E, "Cipher suite is rejected per security policy"},
3920}; 3908};
3921 3909
3922#ifdef CONFIG_IPW2200_DEBUG
3923static const char *ipw_get_status_code(u16 status) 3910static const char *ipw_get_status_code(u16 status)
3924{ 3911{
3925 int i; 3912 int i;
@@ -3928,7 +3915,6 @@ static const char *ipw_get_status_code(u16 status)
3928 return ipw_status_codes[i].reason; 3915 return ipw_status_codes[i].reason;
3929 return "Unknown status value."; 3916 return "Unknown status value.";
3930} 3917}
3931#endif
3932 3918
3933static void inline average_init(struct average *avg) 3919static void inline average_init(struct average *avg)
3934{ 3920{
@@ -4398,7 +4384,6 @@ static void ipw_rx_notification(struct ipw_priv *priv,
4398 if (priv-> 4384 if (priv->
4399 status & (STATUS_ASSOCIATED | 4385 status & (STATUS_ASSOCIATED |
4400 STATUS_AUTH)) { 4386 STATUS_AUTH)) {
4401#ifdef CONFIG_IPW2200_DEBUG
4402 struct notif_authenticate *auth 4387 struct notif_authenticate *auth
4403 = &notif->u.auth; 4388 = &notif->u.auth;
4404 IPW_DEBUG(IPW_DL_NOTIF | 4389 IPW_DEBUG(IPW_DL_NOTIF |
@@ -4416,7 +4401,6 @@ static void ipw_rx_notification(struct ipw_priv *priv,
4416 ipw_get_status_code 4401 ipw_get_status_code
4417 (ntohs 4402 (ntohs
4418 (auth->status))); 4403 (auth->status)));
4419#endif
4420 4404
4421 priv->status &= 4405 priv->status &=
4422 ~(STATUS_ASSOCIATING | 4406 ~(STATUS_ASSOCIATING |
@@ -5059,7 +5043,6 @@ static void ipw_rx_queue_replenish(void *data)
5059 } 5043 }
5060 list_del(element); 5044 list_del(element);
5061 5045
5062 rxb->rxb = (struct ipw_rx_buffer *)rxb->skb->data;
5063 rxb->dma_addr = 5046 rxb->dma_addr =
5064 pci_map_single(priv->pci_dev, rxb->skb->data, 5047 pci_map_single(priv->pci_dev, rxb->skb->data,
5065 IPW_RX_BUF_SIZE, PCI_DMA_FROMDEVICE); 5048 IPW_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
@@ -5838,8 +5821,8 @@ static void ipw_send_tgi_tx_key(struct ipw_priv *priv, int type, int index)
5838 key.station_index = 0; /* always 0 for BSS */ 5821 key.station_index = 0; /* always 0 for BSS */
5839 key.flags = 0; 5822 key.flags = 0;
5840 /* 0 for new key; previous value of counter (after fatal error) */ 5823 /* 0 for new key; previous value of counter (after fatal error) */
5841 key.tx_counter[0] = 0; 5824 key.tx_counter[0] = cpu_to_le32(0);
5842 key.tx_counter[1] = 0; 5825 key.tx_counter[1] = cpu_to_le32(0);
5843 5826
5844 ipw_send_cmd_pdu(priv, IPW_CMD_TGI_TX_KEY, sizeof(key), &key); 5827 ipw_send_cmd_pdu(priv, IPW_CMD_TGI_TX_KEY, sizeof(key), &key);
5845} 5828}
@@ -5973,7 +5956,6 @@ static void ipw_bg_adhoc_check(void *data)
5973 mutex_unlock(&priv->mutex); 5956 mutex_unlock(&priv->mutex);
5974} 5957}
5975 5958
5976#ifdef CONFIG_IPW2200_DEBUG
5977static void ipw_debug_config(struct ipw_priv *priv) 5959static void ipw_debug_config(struct ipw_priv *priv)
5978{ 5960{
5979 IPW_DEBUG_INFO("Scan completed, no valid APs matched " 5961 IPW_DEBUG_INFO("Scan completed, no valid APs matched "
@@ -5998,9 +5980,6 @@ static void ipw_debug_config(struct ipw_priv *priv)
5998 IPW_DEBUG_INFO("PRIVACY off\n"); 5980 IPW_DEBUG_INFO("PRIVACY off\n");
5999 IPW_DEBUG_INFO("RATE MASK: 0x%08X\n", priv->rates_mask); 5981 IPW_DEBUG_INFO("RATE MASK: 0x%08X\n", priv->rates_mask);
6000} 5982}
6001#else
6002#define ipw_debug_config(x) do {} while (0)
6003#endif
6004 5983
6005static void ipw_set_fixed_rate(struct ipw_priv *priv, int mode) 5984static void ipw_set_fixed_rate(struct ipw_priv *priv, int mode)
6006{ 5985{
@@ -6188,7 +6167,7 @@ static void ipw_add_scan_channels(struct ipw_priv *priv,
6188 } 6167 }
6189} 6168}
6190 6169
6191static int ipw_request_scan(struct ipw_priv *priv) 6170static int ipw_request_scan_helper(struct ipw_priv *priv, int type)
6192{ 6171{
6193 struct ipw_scan_request_ext scan; 6172 struct ipw_scan_request_ext scan;
6194 int err = 0, scan_type; 6173 int err = 0, scan_type;
@@ -6219,19 +6198,29 @@ static int ipw_request_scan(struct ipw_priv *priv)
6219 } 6198 }
6220 6199
6221 memset(&scan, 0, sizeof(scan)); 6200 memset(&scan, 0, sizeof(scan));
6201 scan.full_scan_index = cpu_to_le32(ieee80211_get_scans(priv->ieee));
6222 6202
6223 if (priv->config & CFG_SPEED_SCAN) 6203 if (type == IW_SCAN_TYPE_PASSIVE) {
6204 IPW_DEBUG_WX("use passive scanning\n");
6205 scan_type = IPW_SCAN_PASSIVE_FULL_DWELL_SCAN;
6206 scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] =
6207 cpu_to_le16(120);
6208 ipw_add_scan_channels(priv, &scan, scan_type);
6209 goto send_request;
6210 }
6211
6212 /* Use active scan by default. */
6213 if (priv->config & CFG_SPEED_SCAN)
6224 scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_SCAN] = 6214 scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_SCAN] =
6225 cpu_to_le16(30); 6215 cpu_to_le16(30);
6226 else 6216 else
6227 scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_SCAN] = 6217 scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_SCAN] =
6228 cpu_to_le16(20); 6218 cpu_to_le16(20);
6229 6219
6230 scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN] = 6220 scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN] =
6231 cpu_to_le16(20); 6221 cpu_to_le16(20);
6232 scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] = cpu_to_le16(120);
6233 6222
6234 scan.full_scan_index = cpu_to_le32(ieee80211_get_scans(priv->ieee)); 6223 scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] = cpu_to_le16(120);
6235 6224
6236#ifdef CONFIG_IPW2200_MONITOR 6225#ifdef CONFIG_IPW2200_MONITOR
6237 if (priv->ieee->iw_mode == IW_MODE_MONITOR) { 6226 if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
@@ -6268,7 +6257,7 @@ static int ipw_request_scan(struct ipw_priv *priv)
6268 * 6257 *
6269 * TODO: Move SPEED SCAN support to all modes and bands */ 6258 * TODO: Move SPEED SCAN support to all modes and bands */
6270 scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] = 6259 scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] =
6271 cpu_to_le16(2000); 6260 cpu_to_le16(2000);
6272 } else { 6261 } else {
6273#endif /* CONFIG_IPW2200_MONITOR */ 6262#endif /* CONFIG_IPW2200_MONITOR */
6274 /* If we are roaming, then make this a directed scan for the 6263 /* If we are roaming, then make this a directed scan for the
@@ -6294,6 +6283,7 @@ static int ipw_request_scan(struct ipw_priv *priv)
6294 } 6283 }
6295#endif 6284#endif
6296 6285
6286send_request:
6297 err = ipw_send_scan_request_ext(priv, &scan); 6287 err = ipw_send_scan_request_ext(priv, &scan);
6298 if (err) { 6288 if (err) {
6299 IPW_DEBUG_HC("Sending scan command failed: %08X\n", err); 6289 IPW_DEBUG_HC("Sending scan command failed: %08X\n", err);
@@ -6304,11 +6294,19 @@ static int ipw_request_scan(struct ipw_priv *priv)
6304 priv->status &= ~STATUS_SCAN_PENDING; 6294 priv->status &= ~STATUS_SCAN_PENDING;
6305 queue_delayed_work(priv->workqueue, &priv->scan_check, 6295 queue_delayed_work(priv->workqueue, &priv->scan_check,
6306 IPW_SCAN_CHECK_WATCHDOG); 6296 IPW_SCAN_CHECK_WATCHDOG);
6307 done: 6297done:
6308 mutex_unlock(&priv->mutex); 6298 mutex_unlock(&priv->mutex);
6309 return err; 6299 return err;
6310} 6300}
6311 6301
6302static int ipw_request_passive_scan(struct ipw_priv *priv) {
6303 return ipw_request_scan_helper(priv, IW_SCAN_TYPE_PASSIVE);
6304}
6305
6306static int ipw_request_scan(struct ipw_priv *priv) {
6307 return ipw_request_scan_helper(priv, IW_SCAN_TYPE_ACTIVE);
6308}
6309
6312static void ipw_bg_abort_scan(void *data) 6310static void ipw_bg_abort_scan(void *data)
6313{ 6311{
6314 struct ipw_priv *priv = data; 6312 struct ipw_priv *priv = data;
@@ -6387,13 +6385,6 @@ static int ipw_wx_set_genie(struct net_device *dev,
6387 (wrqu->data.length && extra == NULL)) 6385 (wrqu->data.length && extra == NULL))
6388 return -EINVAL; 6386 return -EINVAL;
6389 6387
6390 //mutex_lock(&priv->mutex);
6391
6392 //if (!ieee->wpa_enabled) {
6393 // err = -EOPNOTSUPP;
6394 // goto out;
6395 //}
6396
6397 if (wrqu->data.length) { 6388 if (wrqu->data.length) {
6398 buf = kmalloc(wrqu->data.length, GFP_KERNEL); 6389 buf = kmalloc(wrqu->data.length, GFP_KERNEL);
6399 if (buf == NULL) { 6390 if (buf == NULL) {
@@ -6413,7 +6404,6 @@ static int ipw_wx_set_genie(struct net_device *dev,
6413 6404
6414 ipw_wpa_assoc_frame(priv, ieee->wpa_ie, ieee->wpa_ie_len); 6405 ipw_wpa_assoc_frame(priv, ieee->wpa_ie, ieee->wpa_ie_len);
6415 out: 6406 out:
6416 //mutex_unlock(&priv->mutex);
6417 return err; 6407 return err;
6418} 6408}
6419 6409
@@ -6426,13 +6416,6 @@ static int ipw_wx_get_genie(struct net_device *dev,
6426 struct ieee80211_device *ieee = priv->ieee; 6416 struct ieee80211_device *ieee = priv->ieee;
6427 int err = 0; 6417 int err = 0;
6428 6418
6429 //mutex_lock(&priv->mutex);
6430
6431 //if (!ieee->wpa_enabled) {
6432 // err = -EOPNOTSUPP;
6433 // goto out;
6434 //}
6435
6436 if (ieee->wpa_ie_len == 0 || ieee->wpa_ie == NULL) { 6419 if (ieee->wpa_ie_len == 0 || ieee->wpa_ie == NULL) {
6437 wrqu->data.length = 0; 6420 wrqu->data.length = 0;
6438 goto out; 6421 goto out;
@@ -6447,7 +6430,6 @@ static int ipw_wx_get_genie(struct net_device *dev,
6447 memcpy(extra, ieee->wpa_ie, ieee->wpa_ie_len); 6430 memcpy(extra, ieee->wpa_ie, ieee->wpa_ie_len);
6448 6431
6449 out: 6432 out:
6450 //mutex_unlock(&priv->mutex);
6451 return err; 6433 return err;
6452} 6434}
6453 6435
@@ -6558,7 +6540,6 @@ static int ipw_wx_set_auth(struct net_device *dev,
6558 ieee->ieee802_1x = param->value; 6540 ieee->ieee802_1x = param->value;
6559 break; 6541 break;
6560 6542
6561 //case IW_AUTH_ROAMING_CONTROL:
6562 case IW_AUTH_PRIVACY_INVOKED: 6543 case IW_AUTH_PRIVACY_INVOKED:
6563 ieee->privacy_invoked = param->value; 6544 ieee->privacy_invoked = param->value;
6564 break; 6545 break;
@@ -6680,7 +6661,7 @@ static int ipw_wx_set_mlme(struct net_device *dev,
6680 6661
6681 switch (mlme->cmd) { 6662 switch (mlme->cmd) {
6682 case IW_MLME_DEAUTH: 6663 case IW_MLME_DEAUTH:
6683 // silently ignore 6664 /* silently ignore */
6684 break; 6665 break;
6685 6666
6686 case IW_MLME_DISASSOC: 6667 case IW_MLME_DISASSOC:
@@ -6811,7 +6792,7 @@ static int ipw_qos_activate(struct ipw_priv *priv,
6811 burst_duration = ipw_qos_get_burst_duration(priv); 6792 burst_duration = ipw_qos_get_burst_duration(priv);
6812 for (i = 0; i < QOS_QUEUE_NUM; i++) 6793 for (i = 0; i < QOS_QUEUE_NUM; i++)
6813 qos_parameters[QOS_PARAM_SET_ACTIVE].tx_op_limit[i] = 6794 qos_parameters[QOS_PARAM_SET_ACTIVE].tx_op_limit[i] =
6814 (u16) burst_duration; 6795 (u16)burst_duration;
6815 } else if (priv->ieee->iw_mode == IW_MODE_ADHOC) { 6796 } else if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
6816 if (type == IEEE_B) { 6797 if (type == IEEE_B) {
6817 IPW_DEBUG_QOS("QoS activate IBSS nework mode %d\n", 6798 IPW_DEBUG_QOS("QoS activate IBSS nework mode %d\n",
@@ -6843,11 +6824,20 @@ static int ipw_qos_activate(struct ipw_priv *priv,
6843 burst_duration = ipw_qos_get_burst_duration(priv); 6824 burst_duration = ipw_qos_get_burst_duration(priv);
6844 for (i = 0; i < QOS_QUEUE_NUM; i++) 6825 for (i = 0; i < QOS_QUEUE_NUM; i++)
6845 qos_parameters[QOS_PARAM_SET_ACTIVE]. 6826 qos_parameters[QOS_PARAM_SET_ACTIVE].
6846 tx_op_limit[i] = (u16) burst_duration; 6827 tx_op_limit[i] = (u16)burst_duration;
6847 } 6828 }
6848 } 6829 }
6849 6830
6850 IPW_DEBUG_QOS("QoS sending IPW_CMD_QOS_PARAMETERS\n"); 6831 IPW_DEBUG_QOS("QoS sending IPW_CMD_QOS_PARAMETERS\n");
6832 for (i = 0; i < 3; i++) {
6833 int j;
6834 for (j = 0; j < QOS_QUEUE_NUM; j++) {
6835 qos_parameters[i].cw_min[j] = cpu_to_le16(qos_parameters[i].cw_min[j]);
6836 qos_parameters[i].cw_max[j] = cpu_to_le16(qos_parameters[i].cw_max[j]);
6837 qos_parameters[i].tx_op_limit[j] = cpu_to_le16(qos_parameters[i].tx_op_limit[j]);
6838 }
6839 }
6840
6851 err = ipw_send_qos_params_command(priv, 6841 err = ipw_send_qos_params_command(priv,
6852 (struct ieee80211_qos_parameters *) 6842 (struct ieee80211_qos_parameters *)
6853 &(qos_parameters[0])); 6843 &(qos_parameters[0]));
@@ -7086,7 +7076,7 @@ static int ipw_qos_set_tx_queue_command(struct ipw_priv *priv,
7086 7076
7087 if (priv->qos_data.qos_no_ack_mask & (1UL << tx_queue_id)) { 7077 if (priv->qos_data.qos_no_ack_mask & (1UL << tx_queue_id)) {
7088 tfd->tx_flags &= ~DCT_FLAG_ACK_REQD; 7078 tfd->tx_flags &= ~DCT_FLAG_ACK_REQD;
7089 tfd->tfd.tfd_26.mchdr.qos_ctrl |= CTRL_QOS_NO_ACK; 7079 tfd->tfd.tfd_26.mchdr.qos_ctrl |= cpu_to_le16(CTRL_QOS_NO_ACK);
7090 } 7080 }
7091 return 0; 7081 return 0;
7092} 7082}
@@ -7667,7 +7657,6 @@ static void ipw_handle_data_packet_monitor(struct ipw_priv *priv,
7667 /* Big bitfield of all the fields we provide in radiotap */ 7657 /* Big bitfield of all the fields we provide in radiotap */
7668 ipw_rt->rt_hdr.it_present = 7658 ipw_rt->rt_hdr.it_present =
7669 ((1 << IEEE80211_RADIOTAP_FLAGS) | 7659 ((1 << IEEE80211_RADIOTAP_FLAGS) |
7670 (1 << IEEE80211_RADIOTAP_TSFT) |
7671 (1 << IEEE80211_RADIOTAP_RATE) | 7660 (1 << IEEE80211_RADIOTAP_RATE) |
7672 (1 << IEEE80211_RADIOTAP_CHANNEL) | 7661 (1 << IEEE80211_RADIOTAP_CHANNEL) |
7673 (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | 7662 (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) |
@@ -7676,6 +7665,7 @@ static void ipw_handle_data_packet_monitor(struct ipw_priv *priv,
7676 7665
7677 /* Zero the flags, we'll add to them as we go */ 7666 /* Zero the flags, we'll add to them as we go */
7678 ipw_rt->rt_flags = 0; 7667 ipw_rt->rt_flags = 0;
7668 ipw_rt->rt_tsf = 0ULL;
7679 7669
7680 /* Convert signal to DBM */ 7670 /* Convert signal to DBM */
7681 ipw_rt->rt_dbmsignal = antsignal; 7671 ipw_rt->rt_dbmsignal = antsignal;
@@ -7794,7 +7784,6 @@ static void ipw_handle_promiscuous_rx(struct ipw_priv *priv,
7794 s8 noise = frame->noise; 7784 s8 noise = frame->noise;
7795 u8 rate = frame->rate; 7785 u8 rate = frame->rate;
7796 short len = le16_to_cpu(pkt->u.frame.length); 7786 short len = le16_to_cpu(pkt->u.frame.length);
7797 u64 tsf = 0;
7798 struct sk_buff *skb; 7787 struct sk_buff *skb;
7799 int hdr_only = 0; 7788 int hdr_only = 0;
7800 u16 filter = priv->prom_priv->filter; 7789 u16 filter = priv->prom_priv->filter;
@@ -7829,17 +7818,17 @@ static void ipw_handle_promiscuous_rx(struct ipw_priv *priv,
7829 } 7818 }
7830 7819
7831 hdr = (void *)rxb->skb->data + IPW_RX_FRAME_SIZE; 7820 hdr = (void *)rxb->skb->data + IPW_RX_FRAME_SIZE;
7832 if (ieee80211_is_management(hdr->frame_ctl)) { 7821 if (ieee80211_is_management(le16_to_cpu(hdr->frame_ctl))) {
7833 if (filter & IPW_PROM_NO_MGMT) 7822 if (filter & IPW_PROM_NO_MGMT)
7834 return; 7823 return;
7835 if (filter & IPW_PROM_MGMT_HEADER_ONLY) 7824 if (filter & IPW_PROM_MGMT_HEADER_ONLY)
7836 hdr_only = 1; 7825 hdr_only = 1;
7837 } else if (ieee80211_is_control(hdr->frame_ctl)) { 7826 } else if (ieee80211_is_control(le16_to_cpu(hdr->frame_ctl))) {
7838 if (filter & IPW_PROM_NO_CTL) 7827 if (filter & IPW_PROM_NO_CTL)
7839 return; 7828 return;
7840 if (filter & IPW_PROM_CTL_HEADER_ONLY) 7829 if (filter & IPW_PROM_CTL_HEADER_ONLY)
7841 hdr_only = 1; 7830 hdr_only = 1;
7842 } else if (ieee80211_is_data(hdr->frame_ctl)) { 7831 } else if (ieee80211_is_data(le16_to_cpu(hdr->frame_ctl))) {
7843 if (filter & IPW_PROM_NO_DATA) 7832 if (filter & IPW_PROM_NO_DATA)
7844 return; 7833 return;
7845 if (filter & IPW_PROM_DATA_HEADER_ONLY) 7834 if (filter & IPW_PROM_DATA_HEADER_ONLY)
@@ -7857,7 +7846,7 @@ static void ipw_handle_promiscuous_rx(struct ipw_priv *priv,
7857 ipw_rt = (void *)skb->data; 7846 ipw_rt = (void *)skb->data;
7858 7847
7859 if (hdr_only) 7848 if (hdr_only)
7860 len = ieee80211_get_hdrlen(hdr->frame_ctl); 7849 len = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
7861 7850
7862 memcpy(ipw_rt->payload, hdr, len); 7851 memcpy(ipw_rt->payload, hdr, len);
7863 7852
@@ -7880,7 +7869,6 @@ static void ipw_handle_promiscuous_rx(struct ipw_priv *priv,
7880 /* Big bitfield of all the fields we provide in radiotap */ 7869 /* Big bitfield of all the fields we provide in radiotap */
7881 ipw_rt->rt_hdr.it_present = 7870 ipw_rt->rt_hdr.it_present =
7882 ((1 << IEEE80211_RADIOTAP_FLAGS) | 7871 ((1 << IEEE80211_RADIOTAP_FLAGS) |
7883 (1 << IEEE80211_RADIOTAP_TSFT) |
7884 (1 << IEEE80211_RADIOTAP_RATE) | 7872 (1 << IEEE80211_RADIOTAP_RATE) |
7885 (1 << IEEE80211_RADIOTAP_CHANNEL) | 7873 (1 << IEEE80211_RADIOTAP_CHANNEL) |
7886 (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | 7874 (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) |
@@ -7889,8 +7877,7 @@ static void ipw_handle_promiscuous_rx(struct ipw_priv *priv,
7889 7877
7890 /* Zero the flags, we'll add to them as we go */ 7878 /* Zero the flags, we'll add to them as we go */
7891 ipw_rt->rt_flags = 0; 7879 ipw_rt->rt_flags = 0;
7892 7880 ipw_rt->rt_tsf = 0ULL;
7893 ipw_rt->rt_tsf = tsf;
7894 7881
7895 /* Convert to DBM */ 7882 /* Convert to DBM */
7896 ipw_rt->rt_dbmsignal = signal; 7883 ipw_rt->rt_dbmsignal = signal;
@@ -8163,8 +8150,7 @@ static void ipw_rx(struct ipw_priv *priv)
8163 switch (pkt->header.message_type) { 8150 switch (pkt->header.message_type) {
8164 case RX_FRAME_TYPE: /* 802.11 frame */ { 8151 case RX_FRAME_TYPE: /* 802.11 frame */ {
8165 struct ieee80211_rx_stats stats = { 8152 struct ieee80211_rx_stats stats = {
8166 .rssi = 8153 .rssi = pkt->u.frame.rssi_dbm -
8167 le16_to_cpu(pkt->u.frame.rssi_dbm) -
8168 IPW_RSSI_TO_DBM, 8154 IPW_RSSI_TO_DBM,
8169 .signal = 8155 .signal =
8170 le16_to_cpu(pkt->u.frame.rssi_dbm) - 8156 le16_to_cpu(pkt->u.frame.rssi_dbm) -
@@ -8599,9 +8585,26 @@ static int ipw_wx_get_freq(struct net_device *dev,
8599 * configured CHANNEL then return that; otherwise return ANY */ 8585 * configured CHANNEL then return that; otherwise return ANY */
8600 mutex_lock(&priv->mutex); 8586 mutex_lock(&priv->mutex);
8601 if (priv->config & CFG_STATIC_CHANNEL || 8587 if (priv->config & CFG_STATIC_CHANNEL ||
8602 priv->status & (STATUS_ASSOCIATING | STATUS_ASSOCIATED)) 8588 priv->status & (STATUS_ASSOCIATING | STATUS_ASSOCIATED)) {
8603 wrqu->freq.m = priv->channel; 8589 int i;
8604 else 8590
8591 i = ieee80211_channel_to_index(priv->ieee, priv->channel);
8592 BUG_ON(i == -1);
8593 wrqu->freq.e = 1;
8594
8595 switch (ieee80211_is_valid_channel(priv->ieee, priv->channel)) {
8596 case IEEE80211_52GHZ_BAND:
8597 wrqu->freq.m = priv->ieee->geo.a[i].freq * 100000;
8598 break;
8599
8600 case IEEE80211_24GHZ_BAND:
8601 wrqu->freq.m = priv->ieee->geo.bg[i].freq * 100000;
8602 break;
8603
8604 default:
8605 BUG();
8606 }
8607 } else
8605 wrqu->freq.m = 0; 8608 wrqu->freq.m = 0;
8606 8609
8607 mutex_unlock(&priv->mutex); 8610 mutex_unlock(&priv->mutex);
@@ -8857,42 +8860,38 @@ static int ipw_wx_set_essid(struct net_device *dev,
8857 union iwreq_data *wrqu, char *extra) 8860 union iwreq_data *wrqu, char *extra)
8858{ 8861{
8859 struct ipw_priv *priv = ieee80211_priv(dev); 8862 struct ipw_priv *priv = ieee80211_priv(dev);
8860 char *essid = ""; /* ANY */ 8863 int length;
8861 int length = 0;
8862 mutex_lock(&priv->mutex);
8863 if (wrqu->essid.flags && wrqu->essid.length) {
8864 length = wrqu->essid.length - 1;
8865 essid = extra;
8866 }
8867 if (length == 0) {
8868 IPW_DEBUG_WX("Setting ESSID to ANY\n");
8869 if ((priv->config & CFG_STATIC_ESSID) &&
8870 !(priv->status & (STATUS_ASSOCIATED |
8871 STATUS_ASSOCIATING))) {
8872 IPW_DEBUG_ASSOC("Attempting to associate with new "
8873 "parameters.\n");
8874 priv->config &= ~CFG_STATIC_ESSID;
8875 ipw_associate(priv);
8876 }
8877 mutex_unlock(&priv->mutex);
8878 return 0;
8879 }
8880 8864
8881 length = min(length, IW_ESSID_MAX_SIZE); 8865 mutex_lock(&priv->mutex);
8866
8867 if (!wrqu->essid.flags)
8868 {
8869 IPW_DEBUG_WX("Setting ESSID to ANY\n");
8870 ipw_disassociate(priv);
8871 priv->config &= ~CFG_STATIC_ESSID;
8872 ipw_associate(priv);
8873 mutex_unlock(&priv->mutex);
8874 return 0;
8875 }
8876
8877 length = min((int)wrqu->essid.length, IW_ESSID_MAX_SIZE);
8878 if (!extra[length - 1])
8879 length--;
8882 8880
8883 priv->config |= CFG_STATIC_ESSID; 8881 priv->config |= CFG_STATIC_ESSID;
8884 8882
8885 if (priv->essid_len == length && !memcmp(priv->essid, extra, length)) { 8883 if (priv->essid_len == length && !memcmp(priv->essid, extra, length)
8884 && (priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING))) {
8886 IPW_DEBUG_WX("ESSID set to current ESSID.\n"); 8885 IPW_DEBUG_WX("ESSID set to current ESSID.\n");
8887 mutex_unlock(&priv->mutex); 8886 mutex_unlock(&priv->mutex);
8888 return 0; 8887 return 0;
8889 } 8888 }
8890 8889
8891 IPW_DEBUG_WX("Setting ESSID: '%s' (%d)\n", escape_essid(essid, length), 8890 IPW_DEBUG_WX("Setting ESSID: '%s' (%d)\n", escape_essid(extra, length),
8892 length); 8891 length);
8893 8892
8894 priv->essid_len = length; 8893 priv->essid_len = length;
8895 memcpy(priv->essid, essid, priv->essid_len); 8894 memcpy(priv->essid, extra, priv->essid_len);
8896 8895
8897 /* Network configuration changed -- force [re]association */ 8896 /* Network configuration changed -- force [re]association */
8898 IPW_DEBUG_ASSOC("[re]association triggered due to ESSID change.\n"); 8897 IPW_DEBUG_ASSOC("[re]association triggered due to ESSID change.\n");
@@ -9273,7 +9272,7 @@ static int ipw_wx_set_retry(struct net_device *dev,
9273 if (!(wrqu->retry.flags & IW_RETRY_LIMIT)) 9272 if (!(wrqu->retry.flags & IW_RETRY_LIMIT))
9274 return 0; 9273 return 0;
9275 9274
9276 if (wrqu->retry.value < 0 || wrqu->retry.value > 255) 9275 if (wrqu->retry.value < 0 || wrqu->retry.value >= 255)
9277 return -EINVAL; 9276 return -EINVAL;
9278 9277
9279 mutex_lock(&priv->mutex); 9278 mutex_lock(&priv->mutex);
@@ -9396,15 +9395,19 @@ static int ipw_wx_set_scan(struct net_device *dev,
9396 union iwreq_data *wrqu, char *extra) 9395 union iwreq_data *wrqu, char *extra)
9397{ 9396{
9398 struct ipw_priv *priv = ieee80211_priv(dev); 9397 struct ipw_priv *priv = ieee80211_priv(dev);
9399 struct iw_scan_req *req = NULL; 9398 struct iw_scan_req *req = (struct iw_scan_req *)extra;
9400 if (wrqu->data.length 9399
9401 && wrqu->data.length == sizeof(struct iw_scan_req)) { 9400 if (wrqu->data.length == sizeof(struct iw_scan_req)) {
9402 req = (struct iw_scan_req *)extra;
9403 if (wrqu->data.flags & IW_SCAN_THIS_ESSID) { 9401 if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
9404 ipw_request_direct_scan(priv, req->essid, 9402 ipw_request_direct_scan(priv, req->essid,
9405 req->essid_len); 9403 req->essid_len);
9406 return 0; 9404 return 0;
9407 } 9405 }
9406 if (req->scan_type == IW_SCAN_TYPE_PASSIVE) {
9407 queue_work(priv->workqueue,
9408 &priv->request_passive_scan);
9409 return 0;
9410 }
9408 } 9411 }
9409 9412
9410 IPW_DEBUG_WX("Start scan\n"); 9413 IPW_DEBUG_WX("Start scan\n");
@@ -9766,7 +9769,7 @@ static int ipw_wx_set_monitor(struct net_device *dev,
9766 return 0; 9769 return 0;
9767} 9770}
9768 9771
9769#endif // CONFIG_IPW2200_MONITOR 9772#endif /* CONFIG_IPW2200_MONITOR */
9770 9773
9771static int ipw_wx_reset(struct net_device *dev, 9774static int ipw_wx_reset(struct net_device *dev,
9772 struct iw_request_info *info, 9775 struct iw_request_info *info,
@@ -10009,7 +10012,7 @@ static void init_sys_config(struct ipw_sys_config *sys_config)
10009 sys_config->dot11g_auto_detection = 0; 10012 sys_config->dot11g_auto_detection = 0;
10010 sys_config->enable_cts_to_self = 0; 10013 sys_config->enable_cts_to_self = 0;
10011 sys_config->bt_coexist_collision_thr = 0; 10014 sys_config->bt_coexist_collision_thr = 0;
10012 sys_config->pass_noise_stats_to_host = 1; //1 -- fix for 256 10015 sys_config->pass_noise_stats_to_host = 1; /* 1 -- fix for 256 */
10013 sys_config->silence_threshold = 0x1e; 10016 sys_config->silence_threshold = 0x1e;
10014} 10017}
10015 10018
@@ -10113,7 +10116,7 @@ static int ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb,
10113 switch (priv->ieee->sec.level) { 10116 switch (priv->ieee->sec.level) {
10114 case SEC_LEVEL_3: 10117 case SEC_LEVEL_3:
10115 tfd->u.data.tfd.tfd_24.mchdr.frame_ctl |= 10118 tfd->u.data.tfd.tfd_24.mchdr.frame_ctl |=
10116 IEEE80211_FCTL_PROTECTED; 10119 cpu_to_le16(IEEE80211_FCTL_PROTECTED);
10117 /* XXX: ACK flag must be set for CCMP even if it 10120 /* XXX: ACK flag must be set for CCMP even if it
10118 * is a multicast/broadcast packet, because CCMP 10121 * is a multicast/broadcast packet, because CCMP
10119 * group communication encrypted by GTK is 10122 * group communication encrypted by GTK is
@@ -10128,14 +10131,14 @@ static int ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb,
10128 break; 10131 break;
10129 case SEC_LEVEL_2: 10132 case SEC_LEVEL_2:
10130 tfd->u.data.tfd.tfd_24.mchdr.frame_ctl |= 10133 tfd->u.data.tfd.tfd_24.mchdr.frame_ctl |=
10131 IEEE80211_FCTL_PROTECTED; 10134 cpu_to_le16(IEEE80211_FCTL_PROTECTED);
10132 tfd->u.data.tx_flags &= ~DCT_FLAG_NO_WEP; 10135 tfd->u.data.tx_flags &= ~DCT_FLAG_NO_WEP;
10133 tfd->u.data.tx_flags_ext |= DCT_FLAG_EXT_SECURITY_TKIP; 10136 tfd->u.data.tx_flags_ext |= DCT_FLAG_EXT_SECURITY_TKIP;
10134 tfd->u.data.key_index = DCT_WEP_INDEX_USE_IMMEDIATE; 10137 tfd->u.data.key_index = DCT_WEP_INDEX_USE_IMMEDIATE;
10135 break; 10138 break;
10136 case SEC_LEVEL_1: 10139 case SEC_LEVEL_1:
10137 tfd->u.data.tfd.tfd_24.mchdr.frame_ctl |= 10140 tfd->u.data.tfd.tfd_24.mchdr.frame_ctl |=
10138 IEEE80211_FCTL_PROTECTED; 10141 cpu_to_le16(IEEE80211_FCTL_PROTECTED);
10139 tfd->u.data.key_index = priv->ieee->tx_keyidx; 10142 tfd->u.data.key_index = priv->ieee->tx_keyidx;
10140 if (priv->ieee->sec.key_sizes[priv->ieee->tx_keyidx] <= 10143 if (priv->ieee->sec.key_sizes[priv->ieee->tx_keyidx] <=
10141 40) 10144 40)
@@ -10267,17 +10270,17 @@ static void ipw_handle_promiscuous_tx(struct ipw_priv *priv,
10267 10270
10268 /* Filtering of fragment chains is done agains the first fragment */ 10271 /* Filtering of fragment chains is done agains the first fragment */
10269 hdr = (void *)txb->fragments[0]->data; 10272 hdr = (void *)txb->fragments[0]->data;
10270 if (ieee80211_is_management(hdr->frame_ctl)) { 10273 if (ieee80211_is_management(le16_to_cpu(hdr->frame_ctl))) {
10271 if (filter & IPW_PROM_NO_MGMT) 10274 if (filter & IPW_PROM_NO_MGMT)
10272 return; 10275 return;
10273 if (filter & IPW_PROM_MGMT_HEADER_ONLY) 10276 if (filter & IPW_PROM_MGMT_HEADER_ONLY)
10274 hdr_only = 1; 10277 hdr_only = 1;
10275 } else if (ieee80211_is_control(hdr->frame_ctl)) { 10278 } else if (ieee80211_is_control(le16_to_cpu(hdr->frame_ctl))) {
10276 if (filter & IPW_PROM_NO_CTL) 10279 if (filter & IPW_PROM_NO_CTL)
10277 return; 10280 return;
10278 if (filter & IPW_PROM_CTL_HEADER_ONLY) 10281 if (filter & IPW_PROM_CTL_HEADER_ONLY)
10279 hdr_only = 1; 10282 hdr_only = 1;
10280 } else if (ieee80211_is_data(hdr->frame_ctl)) { 10283 } else if (ieee80211_is_data(le16_to_cpu(hdr->frame_ctl))) {
10281 if (filter & IPW_PROM_NO_DATA) 10284 if (filter & IPW_PROM_NO_DATA)
10282 return; 10285 return;
10283 if (filter & IPW_PROM_DATA_HEADER_ONLY) 10286 if (filter & IPW_PROM_DATA_HEADER_ONLY)
@@ -10292,7 +10295,7 @@ static void ipw_handle_promiscuous_tx(struct ipw_priv *priv,
10292 10295
10293 if (hdr_only) { 10296 if (hdr_only) {
10294 hdr = (void *)src->data; 10297 hdr = (void *)src->data;
10295 len = ieee80211_get_hdrlen(hdr->frame_ctl); 10298 len = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
10296 } else 10299 } else
10297 len = src->len; 10300 len = src->len;
10298 10301
@@ -10636,6 +10639,8 @@ static int ipw_setup_deferred_work(struct ipw_priv *priv)
10636 INIT_WORK(&priv->down, (void (*)(void *))ipw_bg_down, priv); 10639 INIT_WORK(&priv->down, (void (*)(void *))ipw_bg_down, priv);
10637 INIT_WORK(&priv->request_scan, 10640 INIT_WORK(&priv->request_scan,
10638 (void (*)(void *))ipw_request_scan, priv); 10641 (void (*)(void *))ipw_request_scan, priv);
10642 INIT_WORK(&priv->request_passive_scan,
10643 (void (*)(void *))ipw_request_passive_scan, priv);
10639 INIT_WORK(&priv->gather_stats, 10644 INIT_WORK(&priv->gather_stats,
10640 (void (*)(void *))ipw_bg_gather_stats, priv); 10645 (void (*)(void *))ipw_bg_gather_stats, priv);
10641 INIT_WORK(&priv->abort_scan, (void (*)(void *))ipw_bg_abort_scan, priv); 10646 INIT_WORK(&priv->abort_scan, (void (*)(void *))ipw_bg_abort_scan, priv);
@@ -11488,9 +11493,7 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
11488 11493
11489 priv->net_dev = net_dev; 11494 priv->net_dev = net_dev;
11490 priv->pci_dev = pdev; 11495 priv->pci_dev = pdev;
11491#ifdef CONFIG_IPW2200_DEBUG
11492 ipw_debug_level = debug; 11496 ipw_debug_level = debug;
11493#endif
11494 spin_lock_init(&priv->irq_lock); 11497 spin_lock_init(&priv->irq_lock);
11495 spin_lock_init(&priv->lock); 11498 spin_lock_init(&priv->lock);
11496 for (i = 0; i < IPW_IBSS_MAC_HASH_SIZE; i++) 11499 for (i = 0; i < IPW_IBSS_MAC_HASH_SIZE; i++)
@@ -11755,6 +11758,16 @@ static int ipw_pci_resume(struct pci_dev *pdev)
11755} 11758}
11756#endif 11759#endif
11757 11760
11761static void ipw_pci_shutdown(struct pci_dev *pdev)
11762{
11763 struct ipw_priv *priv = pci_get_drvdata(pdev);
11764
11765 /* Take down the device; powers it off, etc. */
11766 ipw_down(priv);
11767
11768 pci_disable_device(pdev);
11769}
11770
11758/* driver initialization stuff */ 11771/* driver initialization stuff */
11759static struct pci_driver ipw_driver = { 11772static struct pci_driver ipw_driver = {
11760 .name = DRV_NAME, 11773 .name = DRV_NAME,
@@ -11765,6 +11778,7 @@ static struct pci_driver ipw_driver = {
11765 .suspend = ipw_pci_suspend, 11778 .suspend = ipw_pci_suspend,
11766 .resume = ipw_pci_resume, 11779 .resume = ipw_pci_resume,
11767#endif 11780#endif
11781 .shutdown = ipw_pci_shutdown,
11768}; 11782};
11769 11783
11770static int __init ipw_init(void) 11784static int __init ipw_init(void)
@@ -11808,10 +11822,8 @@ MODULE_PARM_DESC(auto_create, "auto create adhoc network (default on)");
11808module_param(led, int, 0444); 11822module_param(led, int, 0444);
11809MODULE_PARM_DESC(led, "enable led control on some systems (default 0 off)\n"); 11823MODULE_PARM_DESC(led, "enable led control on some systems (default 0 off)\n");
11810 11824
11811#ifdef CONFIG_IPW2200_DEBUG
11812module_param(debug, int, 0444); 11825module_param(debug, int, 0444);
11813MODULE_PARM_DESC(debug, "debug output mask"); 11826MODULE_PARM_DESC(debug, "debug output mask");
11814#endif
11815 11827
11816module_param(channel, int, 0444); 11828module_param(channel, int, 0444);
11817MODULE_PARM_DESC(channel, "channel to limit associate to (default 0 [ANY])"); 11829MODULE_PARM_DESC(channel, "channel to limit associate to (default 0 [ANY])");
diff --git a/drivers/net/wireless/ipw2200.h b/drivers/net/wireless/ipw2200.h
index 8b1cd7c749a4..dad5eedefbf1 100644
--- a/drivers/net/wireless/ipw2200.h
+++ b/drivers/net/wireless/ipw2200.h
@@ -713,7 +713,6 @@ struct ipw_rx_packet {
713 713
714struct ipw_rx_mem_buffer { 714struct ipw_rx_mem_buffer {
715 dma_addr_t dma_addr; 715 dma_addr_t dma_addr;
716 struct ipw_rx_buffer *rxb;
717 struct sk_buff *skb; 716 struct sk_buff *skb;
718 struct list_head list; 717 struct list_head list;
719}; /* Not transferred over network, so not __attribute__ ((packed)) */ 718}; /* Not transferred over network, so not __attribute__ ((packed)) */
@@ -1297,6 +1296,7 @@ struct ipw_priv {
1297 struct work_struct system_config; 1296 struct work_struct system_config;
1298 struct work_struct rx_replenish; 1297 struct work_struct rx_replenish;
1299 struct work_struct request_scan; 1298 struct work_struct request_scan;
1299 struct work_struct request_passive_scan;
1300 struct work_struct adapter_restart; 1300 struct work_struct adapter_restart;
1301 struct work_struct rf_kill; 1301 struct work_struct rf_kill;
1302 struct work_struct up; 1302 struct work_struct up;
@@ -1381,13 +1381,18 @@ BITC(x,19),BITC(x,18),BITC(x,17),BITC(x,16),\
1381BIT_ARG16(x) 1381BIT_ARG16(x)
1382 1382
1383 1383
1384#ifdef CONFIG_IPW2200_DEBUG
1385#define IPW_DEBUG(level, fmt, args...) \ 1384#define IPW_DEBUG(level, fmt, args...) \
1386do { if (ipw_debug_level & (level)) \ 1385do { if (ipw_debug_level & (level)) \
1387 printk(KERN_DEBUG DRV_NAME": %c %s " fmt, \ 1386 printk(KERN_DEBUG DRV_NAME": %c %s " fmt, \
1388 in_interrupt() ? 'I' : 'U', __FUNCTION__ , ## args); } while (0) 1387 in_interrupt() ? 'I' : 'U', __FUNCTION__ , ## args); } while (0)
1388
1389#ifdef CONFIG_IPW2200_DEBUG
1390#define IPW_LL_DEBUG(level, fmt, args...) \
1391do { if (ipw_debug_level & (level)) \
1392 printk(KERN_DEBUG DRV_NAME": %c %s " fmt, \
1393 in_interrupt() ? 'I' : 'U', __FUNCTION__ , ## args); } while (0)
1389#else 1394#else
1390#define IPW_DEBUG(level, fmt, args...) do {} while (0) 1395#define IPW_LL_DEBUG(level, fmt, args...) do {} while (0)
1391#endif /* CONFIG_IPW2200_DEBUG */ 1396#endif /* CONFIG_IPW2200_DEBUG */
1392 1397
1393/* 1398/*
@@ -1457,28 +1462,27 @@ do { if (ipw_debug_level & (level)) \
1457 1462
1458#define IPW_DEBUG_WX(f, a...) IPW_DEBUG(IPW_DL_WX, f, ## a) 1463#define IPW_DEBUG_WX(f, a...) IPW_DEBUG(IPW_DL_WX, f, ## a)
1459#define IPW_DEBUG_SCAN(f, a...) IPW_DEBUG(IPW_DL_SCAN, f, ## a) 1464#define IPW_DEBUG_SCAN(f, a...) IPW_DEBUG(IPW_DL_SCAN, f, ## a)
1460#define IPW_DEBUG_STATUS(f, a...) IPW_DEBUG(IPW_DL_STATUS, f, ## a) 1465#define IPW_DEBUG_TRACE(f, a...) IPW_LL_DEBUG(IPW_DL_TRACE, f, ## a)
1461#define IPW_DEBUG_TRACE(f, a...) IPW_DEBUG(IPW_DL_TRACE, f, ## a) 1466#define IPW_DEBUG_RX(f, a...) IPW_LL_DEBUG(IPW_DL_RX, f, ## a)
1462#define IPW_DEBUG_RX(f, a...) IPW_DEBUG(IPW_DL_RX, f, ## a) 1467#define IPW_DEBUG_TX(f, a...) IPW_LL_DEBUG(IPW_DL_TX, f, ## a)
1463#define IPW_DEBUG_TX(f, a...) IPW_DEBUG(IPW_DL_TX, f, ## a) 1468#define IPW_DEBUG_ISR(f, a...) IPW_LL_DEBUG(IPW_DL_ISR, f, ## a)
1464#define IPW_DEBUG_ISR(f, a...) IPW_DEBUG(IPW_DL_ISR, f, ## a)
1465#define IPW_DEBUG_MANAGEMENT(f, a...) IPW_DEBUG(IPW_DL_MANAGE, f, ## a) 1469#define IPW_DEBUG_MANAGEMENT(f, a...) IPW_DEBUG(IPW_DL_MANAGE, f, ## a)
1466#define IPW_DEBUG_LED(f, a...) IPW_DEBUG(IPW_DL_LED, f, ## a) 1470#define IPW_DEBUG_LED(f, a...) IPW_LL_DEBUG(IPW_DL_LED, f, ## a)
1467#define IPW_DEBUG_WEP(f, a...) IPW_DEBUG(IPW_DL_WEP, f, ## a) 1471#define IPW_DEBUG_WEP(f, a...) IPW_LL_DEBUG(IPW_DL_WEP, f, ## a)
1468#define IPW_DEBUG_HC(f, a...) IPW_DEBUG(IPW_DL_HOST_COMMAND, f, ## a) 1472#define IPW_DEBUG_HC(f, a...) IPW_LL_DEBUG(IPW_DL_HOST_COMMAND, f, ## a)
1469#define IPW_DEBUG_FRAG(f, a...) IPW_DEBUG(IPW_DL_FRAG, f, ## a) 1473#define IPW_DEBUG_FRAG(f, a...) IPW_LL_DEBUG(IPW_DL_FRAG, f, ## a)
1470#define IPW_DEBUG_FW(f, a...) IPW_DEBUG(IPW_DL_FW, f, ## a) 1474#define IPW_DEBUG_FW(f, a...) IPW_LL_DEBUG(IPW_DL_FW, f, ## a)
1471#define IPW_DEBUG_RF_KILL(f, a...) IPW_DEBUG(IPW_DL_RF_KILL, f, ## a) 1475#define IPW_DEBUG_RF_KILL(f, a...) IPW_DEBUG(IPW_DL_RF_KILL, f, ## a)
1472#define IPW_DEBUG_DROP(f, a...) IPW_DEBUG(IPW_DL_DROP, f, ## a) 1476#define IPW_DEBUG_DROP(f, a...) IPW_DEBUG(IPW_DL_DROP, f, ## a)
1473#define IPW_DEBUG_IO(f, a...) IPW_DEBUG(IPW_DL_IO, f, ## a) 1477#define IPW_DEBUG_IO(f, a...) IPW_LL_DEBUG(IPW_DL_IO, f, ## a)
1474#define IPW_DEBUG_ORD(f, a...) IPW_DEBUG(IPW_DL_ORD, f, ## a) 1478#define IPW_DEBUG_ORD(f, a...) IPW_LL_DEBUG(IPW_DL_ORD, f, ## a)
1475#define IPW_DEBUG_FW_INFO(f, a...) IPW_DEBUG(IPW_DL_FW_INFO, f, ## a) 1479#define IPW_DEBUG_FW_INFO(f, a...) IPW_LL_DEBUG(IPW_DL_FW_INFO, f, ## a)
1476#define IPW_DEBUG_NOTIF(f, a...) IPW_DEBUG(IPW_DL_NOTIF, f, ## a) 1480#define IPW_DEBUG_NOTIF(f, a...) IPW_DEBUG(IPW_DL_NOTIF, f, ## a)
1477#define IPW_DEBUG_STATE(f, a...) IPW_DEBUG(IPW_DL_STATE | IPW_DL_ASSOC | IPW_DL_INFO, f, ## a) 1481#define IPW_DEBUG_STATE(f, a...) IPW_DEBUG(IPW_DL_STATE | IPW_DL_ASSOC | IPW_DL_INFO, f, ## a)
1478#define IPW_DEBUG_ASSOC(f, a...) IPW_DEBUG(IPW_DL_ASSOC | IPW_DL_INFO, f, ## a) 1482#define IPW_DEBUG_ASSOC(f, a...) IPW_DEBUG(IPW_DL_ASSOC | IPW_DL_INFO, f, ## a)
1479#define IPW_DEBUG_STATS(f, a...) IPW_DEBUG(IPW_DL_STATS, f, ## a) 1483#define IPW_DEBUG_STATS(f, a...) IPW_LL_DEBUG(IPW_DL_STATS, f, ## a)
1480#define IPW_DEBUG_MERGE(f, a...) IPW_DEBUG(IPW_DL_MERGE, f, ## a) 1484#define IPW_DEBUG_MERGE(f, a...) IPW_LL_DEBUG(IPW_DL_MERGE, f, ## a)
1481#define IPW_DEBUG_QOS(f, a...) IPW_DEBUG(IPW_DL_QOS, f, ## a) 1485#define IPW_DEBUG_QOS(f, a...) IPW_LL_DEBUG(IPW_DL_QOS, f, ## a)
1482 1486
1483#include <linux/ctype.h> 1487#include <linux/ctype.h>
1484 1488
@@ -1947,10 +1951,17 @@ struct host_cmd {
1947 u32 *param; 1951 u32 *param;
1948} __attribute__ ((packed)); 1952} __attribute__ ((packed));
1949 1953
1954struct cmdlog_host_cmd {
1955 u8 cmd;
1956 u8 len;
1957 u16 reserved;
1958 char param[124];
1959} __attribute__ ((packed));
1960
1950struct ipw_cmd_log { 1961struct ipw_cmd_log {
1951 unsigned long jiffies; 1962 unsigned long jiffies;
1952 int retcode; 1963 int retcode;
1953 struct host_cmd cmd; 1964 struct cmdlog_host_cmd cmd;
1954}; 1965};
1955 1966
1956/* SysConfig command parameters ... */ 1967/* SysConfig command parameters ... */
diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c
index 317ace7f9aae..1174ff53e025 100644
--- a/drivers/net/wireless/orinoco.c
+++ b/drivers/net/wireless/orinoco.c
@@ -82,6 +82,7 @@
82#include <linux/netdevice.h> 82#include <linux/netdevice.h>
83#include <linux/etherdevice.h> 83#include <linux/etherdevice.h>
84#include <linux/ethtool.h> 84#include <linux/ethtool.h>
85#include <linux/if_arp.h>
85#include <linux/wireless.h> 86#include <linux/wireless.h>
86#include <net/iw_handler.h> 87#include <net/iw_handler.h>
87#include <net/ieee80211.h> 88#include <net/ieee80211.h>
diff --git a/drivers/net/wireless/orinoco.h b/drivers/net/wireless/orinoco.h
index 16db3e14b7d2..fb5700d6c454 100644
--- a/drivers/net/wireless/orinoco.h
+++ b/drivers/net/wireless/orinoco.h
@@ -134,11 +134,7 @@ extern irqreturn_t orinoco_interrupt(int irq, void * dev_id, struct pt_regs *reg
134/* Locking and synchronization functions */ 134/* Locking and synchronization functions */
135/********************************************************************/ 135/********************************************************************/
136 136
137/* These functions *must* be inline or they will break horribly on 137static inline int orinoco_lock(struct orinoco_private *priv,
138 * SPARC, due to its weird semantics for save/restore flags. extern
139 * inline should prevent the kernel from linking or module from
140 * loading if they are not inlined. */
141extern inline int orinoco_lock(struct orinoco_private *priv,
142 unsigned long *flags) 138 unsigned long *flags)
143{ 139{
144 spin_lock_irqsave(&priv->lock, *flags); 140 spin_lock_irqsave(&priv->lock, *flags);
@@ -151,7 +147,7 @@ extern inline int orinoco_lock(struct orinoco_private *priv,
151 return 0; 147 return 0;
152} 148}
153 149
154extern inline void orinoco_unlock(struct orinoco_private *priv, 150static inline void orinoco_unlock(struct orinoco_private *priv,
155 unsigned long *flags) 151 unsigned long *flags)
156{ 152{
157 spin_unlock_irqrestore(&priv->lock, *flags); 153 spin_unlock_irqrestore(&priv->lock, *flags);
diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c
index 989599ad33ef..0c30fe7e8f7f 100644
--- a/drivers/net/wireless/prism54/isl_ioctl.c
+++ b/drivers/net/wireless/prism54/isl_ioctl.c
@@ -35,10 +35,14 @@
35 35
36#include <net/iw_handler.h> /* New driver API */ 36#include <net/iw_handler.h> /* New driver API */
37 37
38#define KEY_SIZE_WEP104 13 /* 104/128-bit WEP keys */
39#define KEY_SIZE_WEP40 5 /* 40/64-bit WEP keys */
40/* KEY_SIZE_TKIP should match isl_oid.h, struct obj_key.key[] size */
41#define KEY_SIZE_TKIP 32 /* TKIP keys */
38 42
39static void prism54_wpa_ie_add(islpci_private *priv, u8 *bssid, 43static void prism54_wpa_bss_ie_add(islpci_private *priv, u8 *bssid,
40 u8 *wpa_ie, size_t wpa_ie_len); 44 u8 *wpa_ie, size_t wpa_ie_len);
41static size_t prism54_wpa_ie_get(islpci_private *priv, u8 *bssid, u8 *wpa_ie); 45static size_t prism54_wpa_bss_ie_get(islpci_private *priv, u8 *bssid, u8 *wpa_ie);
42static int prism54_set_wpa(struct net_device *, struct iw_request_info *, 46static int prism54_set_wpa(struct net_device *, struct iw_request_info *,
43 __u32 *, char *); 47 __u32 *, char *);
44 48
@@ -468,6 +472,9 @@ prism54_get_range(struct net_device *ndev, struct iw_request_info *info,
468 range->event_capa[1] = IW_EVENT_CAPA_K_1; 472 range->event_capa[1] = IW_EVENT_CAPA_K_1;
469 range->event_capa[4] = IW_EVENT_CAPA_MASK(IWEVCUSTOM); 473 range->event_capa[4] = IW_EVENT_CAPA_MASK(IWEVCUSTOM);
470 474
475 range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
476 IW_ENC_CAPA_CIPHER_TKIP;
477
471 if (islpci_get_state(priv) < PRV_STATE_INIT) 478 if (islpci_get_state(priv) < PRV_STATE_INIT)
472 return 0; 479 return 0;
473 480
@@ -567,6 +574,8 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev,
567 struct iw_event iwe; /* Temporary buffer */ 574 struct iw_event iwe; /* Temporary buffer */
568 short cap; 575 short cap;
569 islpci_private *priv = netdev_priv(ndev); 576 islpci_private *priv = netdev_priv(ndev);
577 u8 wpa_ie[MAX_WPA_IE_LEN];
578 size_t wpa_ie_len;
570 579
571 /* The first entry must be the MAC address */ 580 /* The first entry must be the MAC address */
572 memcpy(iwe.u.ap_addr.sa_data, bss->address, 6); 581 memcpy(iwe.u.ap_addr.sa_data, bss->address, 6);
@@ -627,27 +636,13 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev,
627 current_ev = 636 current_ev =
628 iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_QUAL_LEN); 637 iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
629 638
630 if (priv->wpa) { 639 /* Add WPA/RSN Information Element, if any */
631 u8 wpa_ie[MAX_WPA_IE_LEN]; 640 wpa_ie_len = prism54_wpa_bss_ie_get(priv, bss->address, wpa_ie);
632 char *buf, *p; 641 if (wpa_ie_len > 0) {
633 size_t wpa_ie_len; 642 iwe.cmd = IWEVGENIE;
634 int i; 643 iwe.u.data.length = min(wpa_ie_len, (size_t)MAX_WPA_IE_LEN);
635 644 current_ev = iwe_stream_add_point(current_ev, end_buf,
636 wpa_ie_len = prism54_wpa_ie_get(priv, bss->address, wpa_ie); 645 &iwe, wpa_ie);
637 if (wpa_ie_len > 0 &&
638 (buf = kmalloc(wpa_ie_len * 2 + 10, GFP_ATOMIC))) {
639 p = buf;
640 p += sprintf(p, "wpa_ie=");
641 for (i = 0; i < wpa_ie_len; i++) {
642 p += sprintf(p, "%02x", wpa_ie[i]);
643 }
644 memset(&iwe, 0, sizeof (iwe));
645 iwe.cmd = IWEVCUSTOM;
646 iwe.u.data.length = strlen(buf);
647 current_ev = iwe_stream_add_point(current_ev, end_buf,
648 &iwe, buf);
649 kfree(buf);
650 }
651 } 646 }
652 return current_ev; 647 return current_ev;
653} 648}
@@ -1051,12 +1046,24 @@ prism54_set_encode(struct net_device *ndev, struct iw_request_info *info,
1051 current_index = r.u; 1046 current_index = r.u;
1052 /* Verify that the key is not marked as invalid */ 1047 /* Verify that the key is not marked as invalid */
1053 if (!(dwrq->flags & IW_ENCODE_NOKEY)) { 1048 if (!(dwrq->flags & IW_ENCODE_NOKEY)) {
1054 key.length = dwrq->length > sizeof (key.key) ? 1049 if (dwrq->length > KEY_SIZE_TKIP) {
1055 sizeof (key.key) : dwrq->length; 1050 /* User-provided key data too big */
1056 memcpy(key.key, extra, key.length); 1051 return -EINVAL;
1057 if (key.length == 32) 1052 }
1058 /* we want WPA-PSK */ 1053 if (dwrq->length > KEY_SIZE_WEP104) {
1054 /* WPA-PSK TKIP */
1059 key.type = DOT11_PRIV_TKIP; 1055 key.type = DOT11_PRIV_TKIP;
1056 key.length = KEY_SIZE_TKIP;
1057 } else if (dwrq->length > KEY_SIZE_WEP40) {
1058 /* WEP 104/128 */
1059 key.length = KEY_SIZE_WEP104;
1060 } else {
1061 /* WEP 40/64 */
1062 key.length = KEY_SIZE_WEP40;
1063 }
1064 memset(key.key, 0, sizeof (key.key));
1065 memcpy(key.key, extra, dwrq->length);
1066
1060 if ((index < 0) || (index > 3)) 1067 if ((index < 0) || (index > 3))
1061 /* no index provided use the current one */ 1068 /* no index provided use the current one */
1062 index = current_index; 1069 index = current_index;
@@ -1210,6 +1217,489 @@ prism54_set_txpower(struct net_device *ndev, struct iw_request_info *info,
1210 } 1217 }
1211} 1218}
1212 1219
1220static int prism54_set_genie(struct net_device *ndev,
1221 struct iw_request_info *info,
1222 struct iw_point *data, char *extra)
1223{
1224 islpci_private *priv = netdev_priv(ndev);
1225 int alen, ret = 0;
1226 struct obj_attachment *attach;
1227
1228 if (data->length > MAX_WPA_IE_LEN ||
1229 (data->length && extra == NULL))
1230 return -EINVAL;
1231
1232 memcpy(priv->wpa_ie, extra, data->length);
1233 priv->wpa_ie_len = data->length;
1234
1235 alen = sizeof(*attach) + priv->wpa_ie_len;
1236 attach = kzalloc(alen, GFP_KERNEL);
1237 if (attach == NULL)
1238 return -ENOMEM;
1239
1240#define WLAN_FC_TYPE_MGMT 0
1241#define WLAN_FC_STYPE_ASSOC_REQ 0
1242#define WLAN_FC_STYPE_REASSOC_REQ 2
1243
1244 /* Note: endianness is covered by mgt_set_varlen */
1245 attach->type = (WLAN_FC_TYPE_MGMT << 2) |
1246 (WLAN_FC_STYPE_ASSOC_REQ << 4);
1247 attach->id = -1;
1248 attach->size = priv->wpa_ie_len;
1249 memcpy(attach->data, extra, priv->wpa_ie_len);
1250
1251 ret = mgt_set_varlen(priv, DOT11_OID_ATTACHMENT, attach,
1252 priv->wpa_ie_len);
1253 if (ret == 0) {
1254 attach->type = (WLAN_FC_TYPE_MGMT << 2) |
1255 (WLAN_FC_STYPE_REASSOC_REQ << 4);
1256
1257 ret = mgt_set_varlen(priv, DOT11_OID_ATTACHMENT, attach,
1258 priv->wpa_ie_len);
1259 if (ret == 0)
1260 printk(KERN_DEBUG "%s: WPA IE Attachment was set\n",
1261 ndev->name);
1262 }
1263
1264 kfree(attach);
1265 return ret;
1266}
1267
1268
1269static int prism54_get_genie(struct net_device *ndev,
1270 struct iw_request_info *info,
1271 struct iw_point *data, char *extra)
1272{
1273 islpci_private *priv = netdev_priv(ndev);
1274 int len = priv->wpa_ie_len;
1275
1276 if (len <= 0) {
1277 data->length = 0;
1278 return 0;
1279 }
1280
1281 if (data->length < len)
1282 return -E2BIG;
1283
1284 data->length = len;
1285 memcpy(extra, priv->wpa_ie, len);
1286
1287 return 0;
1288}
1289
1290static int prism54_set_auth(struct net_device *ndev,
1291 struct iw_request_info *info,
1292 union iwreq_data *wrqu, char *extra)
1293{
1294 islpci_private *priv = netdev_priv(ndev);
1295 struct iw_param *param = &wrqu->param;
1296 u32 mlmelevel = 0, authen = 0, dot1x = 0;
1297 u32 exunencrypt = 0, privinvoked = 0, wpa = 0;
1298 u32 old_wpa;
1299 int ret = 0;
1300 union oid_res_t r;
1301
1302 if (islpci_get_state(priv) < PRV_STATE_INIT)
1303 return 0;
1304
1305 /* first get the flags */
1306 down_write(&priv->mib_sem);
1307 wpa = old_wpa = priv->wpa;
1308 up_write(&priv->mib_sem);
1309 ret = mgt_get_request(priv, DOT11_OID_AUTHENABLE, 0, NULL, &r);
1310 authen = r.u;
1311 ret = mgt_get_request(priv, DOT11_OID_PRIVACYINVOKED, 0, NULL, &r);
1312 privinvoked = r.u;
1313 ret = mgt_get_request(priv, DOT11_OID_EXUNENCRYPTED, 0, NULL, &r);
1314 exunencrypt = r.u;
1315 ret = mgt_get_request(priv, DOT11_OID_DOT1XENABLE, 0, NULL, &r);
1316 dot1x = r.u;
1317 ret = mgt_get_request(priv, DOT11_OID_MLMEAUTOLEVEL, 0, NULL, &r);
1318 mlmelevel = r.u;
1319
1320 if (ret < 0)
1321 goto out;
1322
1323 switch (param->flags & IW_AUTH_INDEX) {
1324 case IW_AUTH_CIPHER_PAIRWISE:
1325 case IW_AUTH_CIPHER_GROUP:
1326 case IW_AUTH_KEY_MGMT:
1327 break;
1328
1329 case IW_AUTH_WPA_ENABLED:
1330 /* Do the same thing as IW_AUTH_WPA_VERSION */
1331 if (param->value) {
1332 wpa = 1;
1333 privinvoked = 1; /* For privacy invoked */
1334 exunencrypt = 1; /* Filter out all unencrypted frames */
1335 dot1x = 0x01; /* To enable eap filter */
1336 mlmelevel = DOT11_MLME_EXTENDED;
1337 authen = DOT11_AUTH_OS; /* Only WEP uses _SK and _BOTH */
1338 } else {
1339 wpa = 0;
1340 privinvoked = 0;
1341 exunencrypt = 0; /* Do not filter un-encrypted data */
1342 dot1x = 0;
1343 mlmelevel = DOT11_MLME_AUTO;
1344 }
1345 break;
1346
1347 case IW_AUTH_WPA_VERSION:
1348 if (param->value & IW_AUTH_WPA_VERSION_DISABLED) {
1349 wpa = 0;
1350 privinvoked = 0;
1351 exunencrypt = 0; /* Do not filter un-encrypted data */
1352 dot1x = 0;
1353 mlmelevel = DOT11_MLME_AUTO;
1354 } else {
1355 if (param->value & IW_AUTH_WPA_VERSION_WPA)
1356 wpa = 1;
1357 else if (param->value & IW_AUTH_WPA_VERSION_WPA2)
1358 wpa = 2;
1359 privinvoked = 1; /* For privacy invoked */
1360 exunencrypt = 1; /* Filter out all unencrypted frames */
1361 dot1x = 0x01; /* To enable eap filter */
1362 mlmelevel = DOT11_MLME_EXTENDED;
1363 authen = DOT11_AUTH_OS; /* Only WEP uses _SK and _BOTH */
1364 }
1365 break;
1366
1367 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
1368 dot1x = param->value ? 1 : 0;
1369 break;
1370
1371 case IW_AUTH_PRIVACY_INVOKED:
1372 privinvoked = param->value ? 1 : 0;
1373
1374 case IW_AUTH_DROP_UNENCRYPTED:
1375 exunencrypt = param->value ? 1 : 0;
1376 break;
1377
1378 case IW_AUTH_80211_AUTH_ALG:
1379 if (param->value & IW_AUTH_ALG_SHARED_KEY) {
1380 /* Only WEP uses _SK and _BOTH */
1381 if (wpa > 0) {
1382 ret = -EINVAL;
1383 goto out;
1384 }
1385 authen = DOT11_AUTH_SK;
1386 } else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM) {
1387 authen = DOT11_AUTH_OS;
1388 } else {
1389 ret = -EINVAL;
1390 goto out;
1391 }
1392 break;
1393
1394 default:
1395 return -EOPNOTSUPP;
1396 }
1397
1398 /* Set all the values */
1399 down_write(&priv->mib_sem);
1400 priv->wpa = wpa;
1401 up_write(&priv->mib_sem);
1402 mgt_set_request(priv, DOT11_OID_AUTHENABLE, 0, &authen);
1403 mgt_set_request(priv, DOT11_OID_PRIVACYINVOKED, 0, &privinvoked);
1404 mgt_set_request(priv, DOT11_OID_EXUNENCRYPTED, 0, &exunencrypt);
1405 mgt_set_request(priv, DOT11_OID_DOT1XENABLE, 0, &dot1x);
1406 mgt_set_request(priv, DOT11_OID_MLMEAUTOLEVEL, 0, &mlmelevel);
1407
1408out:
1409 return ret;
1410}
1411
1412static int prism54_get_auth(struct net_device *ndev,
1413 struct iw_request_info *info,
1414 union iwreq_data *wrqu, char *extra)
1415{
1416 islpci_private *priv = netdev_priv(ndev);
1417 struct iw_param *param = &wrqu->param;
1418 u32 wpa = 0;
1419 int ret = 0;
1420 union oid_res_t r;
1421
1422 if (islpci_get_state(priv) < PRV_STATE_INIT)
1423 return 0;
1424
1425 /* first get the flags */
1426 down_write(&priv->mib_sem);
1427 wpa = priv->wpa;
1428 up_write(&priv->mib_sem);
1429
1430 switch (param->flags & IW_AUTH_INDEX) {
1431 case IW_AUTH_CIPHER_PAIRWISE:
1432 case IW_AUTH_CIPHER_GROUP:
1433 case IW_AUTH_KEY_MGMT:
1434 /*
1435 * wpa_supplicant will control these internally
1436 */
1437 ret = -EOPNOTSUPP;
1438 break;
1439
1440 case IW_AUTH_WPA_VERSION:
1441 switch (wpa) {
1442 case 1:
1443 param->value = IW_AUTH_WPA_VERSION_WPA;
1444 break;
1445 case 2:
1446 param->value = IW_AUTH_WPA_VERSION_WPA2;
1447 break;
1448 case 0:
1449 default:
1450 param->value = IW_AUTH_WPA_VERSION_DISABLED;
1451 break;
1452 }
1453 break;
1454
1455 case IW_AUTH_DROP_UNENCRYPTED:
1456 ret = mgt_get_request(priv, DOT11_OID_EXUNENCRYPTED, 0, NULL, &r);
1457 if (ret >= 0)
1458 param->value = r.u > 0 ? 1 : 0;
1459 break;
1460
1461 case IW_AUTH_80211_AUTH_ALG:
1462 ret = mgt_get_request(priv, DOT11_OID_AUTHENABLE, 0, NULL, &r);
1463 if (ret >= 0) {
1464 switch (r.u) {
1465 case DOT11_AUTH_OS:
1466 param->value = IW_AUTH_ALG_OPEN_SYSTEM;
1467 break;
1468 case DOT11_AUTH_BOTH:
1469 case DOT11_AUTH_SK:
1470 param->value = IW_AUTH_ALG_SHARED_KEY;
1471 case DOT11_AUTH_NONE:
1472 default:
1473 param->value = 0;
1474 break;
1475 }
1476 }
1477 break;
1478
1479 case IW_AUTH_WPA_ENABLED:
1480 param->value = wpa > 0 ? 1 : 0;
1481 break;
1482
1483 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
1484 ret = mgt_get_request(priv, DOT11_OID_DOT1XENABLE, 0, NULL, &r);
1485 if (ret >= 0)
1486 param->value = r.u > 0 ? 1 : 0;
1487 break;
1488
1489 case IW_AUTH_PRIVACY_INVOKED:
1490 ret = mgt_get_request(priv, DOT11_OID_PRIVACYINVOKED, 0, NULL, &r);
1491 if (ret >= 0)
1492 param->value = r.u > 0 ? 1 : 0;
1493 break;
1494
1495 default:
1496 return -EOPNOTSUPP;
1497 }
1498 return ret;
1499}
1500
1501static int prism54_set_encodeext(struct net_device *ndev,
1502 struct iw_request_info *info,
1503 union iwreq_data *wrqu,
1504 char *extra)
1505{
1506 islpci_private *priv = netdev_priv(ndev);
1507 struct iw_point *encoding = &wrqu->encoding;
1508 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
1509 int idx, alg = ext->alg, set_key = 1;
1510 union oid_res_t r;
1511 int authen = DOT11_AUTH_OS, invoke = 0, exunencrypt = 0;
1512 int ret = 0;
1513
1514 if (islpci_get_state(priv) < PRV_STATE_INIT)
1515 return 0;
1516
1517 /* Determine and validate the key index */
1518 idx = (encoding->flags & IW_ENCODE_INDEX) - 1;
1519 if (idx) {
1520 if (idx < 0 || idx > 3)
1521 return -EINVAL;
1522 } else {
1523 ret = mgt_get_request(priv, DOT11_OID_DEFKEYID, 0, NULL, &r);
1524 if (ret < 0)
1525 goto out;
1526 idx = r.u;
1527 }
1528
1529 if (encoding->flags & IW_ENCODE_DISABLED)
1530 alg = IW_ENCODE_ALG_NONE;
1531
1532 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
1533 /* Only set transmit key index here, actual
1534 * key is set below if needed.
1535 */
1536 ret = mgt_set_request(priv, DOT11_OID_DEFKEYID, 0, &idx);
1537 set_key = ext->key_len > 0 ? 1 : 0;
1538 }
1539
1540 if (set_key) {
1541 struct obj_key key = { DOT11_PRIV_WEP, 0, "" };
1542 switch (alg) {
1543 case IW_ENCODE_ALG_NONE:
1544 break;
1545 case IW_ENCODE_ALG_WEP:
1546 if (ext->key_len > KEY_SIZE_WEP104) {
1547 ret = -EINVAL;
1548 goto out;
1549 }
1550 if (ext->key_len > KEY_SIZE_WEP40)
1551 key.length = KEY_SIZE_WEP104;
1552 else
1553 key.length = KEY_SIZE_WEP40;
1554 break;
1555 case IW_ENCODE_ALG_TKIP:
1556 if (ext->key_len > KEY_SIZE_TKIP) {
1557 ret = -EINVAL;
1558 goto out;
1559 }
1560 key.type = DOT11_PRIV_TKIP;
1561 key.length = KEY_SIZE_TKIP;
1562 default:
1563 return -EINVAL;
1564 }
1565
1566 if (key.length) {
1567 memset(key.key, 0, sizeof(key.key));
1568 memcpy(key.key, ext->key, ext->key_len);
1569 ret = mgt_set_request(priv, DOT11_OID_DEFKEYX, idx,
1570 &key);
1571 if (ret < 0)
1572 goto out;
1573 }
1574 }
1575
1576 /* Read the flags */
1577 if (encoding->flags & IW_ENCODE_DISABLED) {
1578 /* Encoding disabled,
1579 * authen = DOT11_AUTH_OS;
1580 * invoke = 0;
1581 * exunencrypt = 0; */
1582 }
1583 if (encoding->flags & IW_ENCODE_OPEN) {
1584 /* Encode but accept non-encoded packets. No auth */
1585 invoke = 1;
1586 }
1587 if (encoding->flags & IW_ENCODE_RESTRICTED) {
1588 /* Refuse non-encoded packets. Auth */
1589 authen = DOT11_AUTH_BOTH;
1590 invoke = 1;
1591 exunencrypt = 1;
1592 }
1593
1594 /* do the change if requested */
1595 if (encoding->flags & IW_ENCODE_MODE) {
1596 ret = mgt_set_request(priv, DOT11_OID_AUTHENABLE, 0,
1597 &authen);
1598 ret = mgt_set_request(priv, DOT11_OID_PRIVACYINVOKED, 0,
1599 &invoke);
1600 ret = mgt_set_request(priv, DOT11_OID_EXUNENCRYPTED, 0,
1601 &exunencrypt);
1602 }
1603
1604out:
1605 return ret;
1606}
1607
1608
1609static int prism54_get_encodeext(struct net_device *ndev,
1610 struct iw_request_info *info,
1611 union iwreq_data *wrqu,
1612 char *extra)
1613{
1614 islpci_private *priv = netdev_priv(ndev);
1615 struct iw_point *encoding = &wrqu->encoding;
1616 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
1617 int idx, max_key_len;
1618 union oid_res_t r;
1619 int authen = DOT11_AUTH_OS, invoke = 0, exunencrypt = 0, wpa = 0;
1620 int ret = 0;
1621
1622 if (islpci_get_state(priv) < PRV_STATE_INIT)
1623 return 0;
1624
1625 /* first get the flags */
1626 ret = mgt_get_request(priv, DOT11_OID_AUTHENABLE, 0, NULL, &r);
1627 authen = r.u;
1628 ret = mgt_get_request(priv, DOT11_OID_PRIVACYINVOKED, 0, NULL, &r);
1629 invoke = r.u;
1630 ret = mgt_get_request(priv, DOT11_OID_EXUNENCRYPTED, 0, NULL, &r);
1631 exunencrypt = r.u;
1632 if (ret < 0)
1633 goto out;
1634
1635 max_key_len = encoding->length - sizeof(*ext);
1636 if (max_key_len < 0)
1637 return -EINVAL;
1638
1639 idx = (encoding->flags & IW_ENCODE_INDEX) - 1;
1640 if (idx) {
1641 if (idx < 0 || idx > 3)
1642 return -EINVAL;
1643 } else {
1644 ret = mgt_get_request(priv, DOT11_OID_DEFKEYID, 0, NULL, &r);
1645 if (ret < 0)
1646 goto out;
1647 idx = r.u;
1648 }
1649
1650 encoding->flags = idx + 1;
1651 memset(ext, 0, sizeof(*ext));
1652
1653 switch (authen) {
1654 case DOT11_AUTH_BOTH:
1655 case DOT11_AUTH_SK:
1656 wrqu->encoding.flags |= IW_ENCODE_RESTRICTED;
1657 case DOT11_AUTH_OS:
1658 default:
1659 wrqu->encoding.flags |= IW_ENCODE_OPEN;
1660 break;
1661 }
1662
1663 down_write(&priv->mib_sem);
1664 wpa = priv->wpa;
1665 up_write(&priv->mib_sem);
1666
1667 if (authen == DOT11_AUTH_OS && !exunencrypt && !invoke && !wpa) {
1668 /* No encryption */
1669 ext->alg = IW_ENCODE_ALG_NONE;
1670 ext->key_len = 0;
1671 wrqu->encoding.flags |= IW_ENCODE_DISABLED;
1672 } else {
1673 struct obj_key *key;
1674
1675 ret = mgt_get_request(priv, DOT11_OID_DEFKEYX, idx, NULL, &r);
1676 if (ret < 0)
1677 goto out;
1678 key = r.ptr;
1679 if (max_key_len < key->length) {
1680 ret = -E2BIG;
1681 goto out;
1682 }
1683 memcpy(ext->key, key->key, key->length);
1684 ext->key_len = key->length;
1685
1686 switch (key->type) {
1687 case DOT11_PRIV_TKIP:
1688 ext->alg = IW_ENCODE_ALG_TKIP;
1689 break;
1690 default:
1691 case DOT11_PRIV_WEP:
1692 ext->alg = IW_ENCODE_ALG_WEP;
1693 break;
1694 }
1695 wrqu->encoding.flags |= IW_ENCODE_ENABLED;
1696 }
1697
1698out:
1699 return ret;
1700}
1701
1702
1213static int 1703static int
1214prism54_reset(struct net_device *ndev, struct iw_request_info *info, 1704prism54_reset(struct net_device *ndev, struct iw_request_info *info,
1215 __u32 * uwrq, char *extra) 1705 __u32 * uwrq, char *extra)
@@ -1591,8 +2081,8 @@ static u8 wpa_oid[4] = { 0x00, 0x50, 0xf2, 1 };
1591#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x" 2081#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
1592 2082
1593static void 2083static void
1594prism54_wpa_ie_add(islpci_private *priv, u8 *bssid, 2084prism54_wpa_bss_ie_add(islpci_private *priv, u8 *bssid,
1595 u8 *wpa_ie, size_t wpa_ie_len) 2085 u8 *wpa_ie, size_t wpa_ie_len)
1596{ 2086{
1597 struct list_head *ptr; 2087 struct list_head *ptr;
1598 struct islpci_bss_wpa_ie *bss = NULL; 2088 struct islpci_bss_wpa_ie *bss = NULL;
@@ -1658,7 +2148,7 @@ prism54_wpa_ie_add(islpci_private *priv, u8 *bssid,
1658} 2148}
1659 2149
1660static size_t 2150static size_t
1661prism54_wpa_ie_get(islpci_private *priv, u8 *bssid, u8 *wpa_ie) 2151prism54_wpa_bss_ie_get(islpci_private *priv, u8 *bssid, u8 *wpa_ie)
1662{ 2152{
1663 struct list_head *ptr; 2153 struct list_head *ptr;
1664 struct islpci_bss_wpa_ie *bss = NULL; 2154 struct islpci_bss_wpa_ie *bss = NULL;
@@ -1683,14 +2173,14 @@ prism54_wpa_ie_get(islpci_private *priv, u8 *bssid, u8 *wpa_ie)
1683} 2173}
1684 2174
1685void 2175void
1686prism54_wpa_ie_init(islpci_private *priv) 2176prism54_wpa_bss_ie_init(islpci_private *priv)
1687{ 2177{
1688 INIT_LIST_HEAD(&priv->bss_wpa_list); 2178 INIT_LIST_HEAD(&priv->bss_wpa_list);
1689 sema_init(&priv->wpa_sem, 1); 2179 sema_init(&priv->wpa_sem, 1);
1690} 2180}
1691 2181
1692void 2182void
1693prism54_wpa_ie_clean(islpci_private *priv) 2183prism54_wpa_bss_ie_clean(islpci_private *priv)
1694{ 2184{
1695 struct list_head *ptr, *n; 2185 struct list_head *ptr, *n;
1696 2186
@@ -1722,7 +2212,7 @@ prism54_process_bss_data(islpci_private *priv, u32 oid, u8 *addr,
1722 } 2212 }
1723 if (pos[0] == WLAN_EID_GENERIC && pos[1] >= 4 && 2213 if (pos[0] == WLAN_EID_GENERIC && pos[1] >= 4 &&
1724 memcmp(pos + 2, wpa_oid, 4) == 0) { 2214 memcmp(pos + 2, wpa_oid, 4) == 0) {
1725 prism54_wpa_ie_add(priv, addr, pos, pos[1] + 2); 2215 prism54_wpa_bss_ie_add(priv, addr, pos, pos[1] + 2);
1726 return; 2216 return;
1727 } 2217 }
1728 pos += 2 + pos[1]; 2218 pos += 2 + pos[1];
@@ -1879,7 +2369,7 @@ prism54_process_trap_helper(islpci_private *priv, enum oid_num_t oid,
1879 send_formatted_event(priv, "Associate request (ex)", mlme, 1); 2369 send_formatted_event(priv, "Associate request (ex)", mlme, 1);
1880 2370
1881 if (priv->iw_mode != IW_MODE_MASTER 2371 if (priv->iw_mode != IW_MODE_MASTER
1882 && mlmeex->state != DOT11_STATE_AUTHING) 2372 && mlmeex->state != DOT11_STATE_ASSOCING)
1883 break; 2373 break;
1884 2374
1885 confirm = kmalloc(sizeof(struct obj_mlmeex), GFP_ATOMIC); 2375 confirm = kmalloc(sizeof(struct obj_mlmeex), GFP_ATOMIC);
@@ -1893,7 +2383,7 @@ prism54_process_trap_helper(islpci_private *priv, enum oid_num_t oid,
1893 confirm->state = 0; /* not used */ 2383 confirm->state = 0; /* not used */
1894 confirm->code = 0; 2384 confirm->code = 0;
1895 2385
1896 wpa_ie_len = prism54_wpa_ie_get(priv, mlmeex->address, wpa_ie); 2386 wpa_ie_len = prism54_wpa_bss_ie_get(priv, mlmeex->address, wpa_ie);
1897 2387
1898 if (!wpa_ie_len) { 2388 if (!wpa_ie_len) {
1899 printk(KERN_DEBUG "No WPA IE found from " 2389 printk(KERN_DEBUG "No WPA IE found from "
@@ -1937,7 +2427,7 @@ prism54_process_trap_helper(islpci_private *priv, enum oid_num_t oid,
1937 confirm->state = 0; /* not used */ 2427 confirm->state = 0; /* not used */
1938 confirm->code = 0; 2428 confirm->code = 0;
1939 2429
1940 wpa_ie_len = prism54_wpa_ie_get(priv, mlmeex->address, wpa_ie); 2430 wpa_ie_len = prism54_wpa_bss_ie_get(priv, mlmeex->address, wpa_ie);
1941 2431
1942 if (!wpa_ie_len) { 2432 if (!wpa_ie_len) {
1943 printk(KERN_DEBUG "No WPA IE found from " 2433 printk(KERN_DEBUG "No WPA IE found from "
@@ -2553,6 +3043,15 @@ static const iw_handler prism54_handler[] = {
2553 (iw_handler) prism54_get_encode, /* SIOCGIWENCODE */ 3043 (iw_handler) prism54_get_encode, /* SIOCGIWENCODE */
2554 (iw_handler) NULL, /* SIOCSIWPOWER */ 3044 (iw_handler) NULL, /* SIOCSIWPOWER */
2555 (iw_handler) NULL, /* SIOCGIWPOWER */ 3045 (iw_handler) NULL, /* SIOCGIWPOWER */
3046 NULL, /* -- hole -- */
3047 NULL, /* -- hole -- */
3048 (iw_handler) prism54_set_genie, /* SIOCSIWGENIE */
3049 (iw_handler) prism54_get_genie, /* SIOCGIWGENIE */
3050 (iw_handler) prism54_set_auth, /* SIOCSIWAUTH */
3051 (iw_handler) prism54_get_auth, /* SIOCGIWAUTH */
3052 (iw_handler) prism54_set_encodeext, /* SIOCSIWENCODEEXT */
3053 (iw_handler) prism54_get_encodeext, /* SIOCGIWENCODEEXT */
3054 NULL, /* SIOCSIWPMKSA */
2556}; 3055};
2557 3056
2558/* The low order bit identify a SET (0) or a GET (1) ioctl. */ 3057/* The low order bit identify a SET (0) or a GET (1) ioctl. */
diff --git a/drivers/net/wireless/prism54/isl_ioctl.h b/drivers/net/wireless/prism54/isl_ioctl.h
index 46d5cde80c85..65f33acd0a42 100644
--- a/drivers/net/wireless/prism54/isl_ioctl.h
+++ b/drivers/net/wireless/prism54/isl_ioctl.h
@@ -27,7 +27,7 @@
27 27
28#include <net/iw_handler.h> /* New driver API */ 28#include <net/iw_handler.h> /* New driver API */
29 29
30#define SUPPORTED_WIRELESS_EXT 16 30#define SUPPORTED_WIRELESS_EXT 19
31 31
32void prism54_mib_init(islpci_private *); 32void prism54_mib_init(islpci_private *);
33 33
@@ -39,8 +39,8 @@ void prism54_acl_clean(struct islpci_acl *);
39 39
40void prism54_process_trap(void *); 40void prism54_process_trap(void *);
41 41
42void prism54_wpa_ie_init(islpci_private *priv); 42void prism54_wpa_bss_ie_init(islpci_private *priv);
43void prism54_wpa_ie_clean(islpci_private *priv); 43void prism54_wpa_bss_ie_clean(islpci_private *priv);
44 44
45int prism54_set_mac_address(struct net_device *, void *); 45int prism54_set_mac_address(struct net_device *, void *);
46 46
diff --git a/drivers/net/wireless/prism54/islpci_dev.c b/drivers/net/wireless/prism54/islpci_dev.c
index 5ddf29599032..ab3c5a27efd9 100644
--- a/drivers/net/wireless/prism54/islpci_dev.c
+++ b/drivers/net/wireless/prism54/islpci_dev.c
@@ -715,7 +715,7 @@ islpci_alloc_memory(islpci_private *priv)
715 } 715 }
716 716
717 prism54_acl_init(&priv->acl); 717 prism54_acl_init(&priv->acl);
718 prism54_wpa_ie_init(priv); 718 prism54_wpa_bss_ie_init(priv);
719 if (mgt_init(priv)) 719 if (mgt_init(priv))
720 goto out_free; 720 goto out_free;
721 721
@@ -774,7 +774,7 @@ islpci_free_memory(islpci_private *priv)
774 774
775 /* Free the acces control list and the WPA list */ 775 /* Free the acces control list and the WPA list */
776 prism54_acl_clean(&priv->acl); 776 prism54_acl_clean(&priv->acl);
777 prism54_wpa_ie_clean(priv); 777 prism54_wpa_bss_ie_clean(priv);
778 mgt_clean(priv); 778 mgt_clean(priv);
779 779
780 return 0; 780 return 0;
diff --git a/drivers/net/wireless/prism54/islpci_dev.h b/drivers/net/wireless/prism54/islpci_dev.h
index 07053165e4c5..5049f37455b1 100644
--- a/drivers/net/wireless/prism54/islpci_dev.h
+++ b/drivers/net/wireless/prism54/islpci_dev.h
@@ -179,6 +179,8 @@ typedef struct {
179 struct list_head bss_wpa_list; 179 struct list_head bss_wpa_list;
180 int num_bss_wpa; 180 int num_bss_wpa;
181 struct semaphore wpa_sem; 181 struct semaphore wpa_sem;
182 u8 wpa_ie[MAX_WPA_IE_LEN];
183 size_t wpa_ie_len;
182 184
183 struct work_struct reset_task; 185 struct work_struct reset_task;
184 int reset_task_pending; 186 int reset_task_pending;
diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c
index 61b83a5e737a..8e112d139e29 100644
--- a/drivers/net/wireless/ray_cs.c
+++ b/drivers/net/wireless/ray_cs.c
@@ -52,8 +52,8 @@
52#include <pcmcia/ds.h> 52#include <pcmcia/ds.h>
53#include <pcmcia/mem_op.h> 53#include <pcmcia/mem_op.h>
54 54
55#include <net/ieee80211.h>
56#include <linux/wireless.h> 55#include <linux/wireless.h>
56#include <net/iw_handler.h>
57 57
58#include <asm/io.h> 58#include <asm/io.h>
59#include <asm/system.h> 59#include <asm/system.h>
diff --git a/drivers/net/wireless/zd1211rw/Makefile b/drivers/net/wireless/zd1211rw/Makefile
index 500314fc74d2..6603ad5be63d 100644
--- a/drivers/net/wireless/zd1211rw/Makefile
+++ b/drivers/net/wireless/zd1211rw/Makefile
@@ -3,6 +3,7 @@ obj-$(CONFIG_ZD1211RW) += zd1211rw.o
3zd1211rw-objs := zd_chip.o zd_ieee80211.o \ 3zd1211rw-objs := zd_chip.o zd_ieee80211.o \
4 zd_mac.o zd_netdev.o \ 4 zd_mac.o zd_netdev.o \
5 zd_rf_al2230.o zd_rf_rf2959.o \ 5 zd_rf_al2230.o zd_rf_rf2959.o \
6 zd_rf_al7230b.o \
6 zd_rf.o zd_usb.o zd_util.o 7 zd_rf.o zd_usb.o zd_util.o
7 8
8ifeq ($(CONFIG_ZD1211RW_DEBUG),y) 9ifeq ($(CONFIG_ZD1211RW_DEBUG),y)
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c
index da9d06bdb818..58419985e00f 100644
--- a/drivers/net/wireless/zd1211rw/zd_chip.c
+++ b/drivers/net/wireless/zd1211rw/zd_chip.c
@@ -42,12 +42,11 @@ void zd_chip_init(struct zd_chip *chip,
42 42
43void zd_chip_clear(struct zd_chip *chip) 43void zd_chip_clear(struct zd_chip *chip)
44{ 44{
45 mutex_lock(&chip->mutex); 45 ZD_ASSERT(!mutex_is_locked(&chip->mutex));
46 zd_usb_clear(&chip->usb); 46 zd_usb_clear(&chip->usb);
47 zd_rf_clear(&chip->rf); 47 zd_rf_clear(&chip->rf);
48 mutex_unlock(&chip->mutex);
49 mutex_destroy(&chip->mutex); 48 mutex_destroy(&chip->mutex);
50 memset(chip, 0, sizeof(*chip)); 49 ZD_MEMCLEAR(chip, sizeof(*chip));
51} 50}
52 51
53static int scnprint_mac_oui(const u8 *addr, char *buffer, size_t size) 52static int scnprint_mac_oui(const u8 *addr, char *buffer, size_t size)
@@ -68,10 +67,11 @@ static int scnprint_id(struct zd_chip *chip, char *buffer, size_t size)
68 i += scnprint_mac_oui(chip->e2p_mac, buffer+i, size-i); 67 i += scnprint_mac_oui(chip->e2p_mac, buffer+i, size-i);
69 i += scnprintf(buffer+i, size-i, " "); 68 i += scnprintf(buffer+i, size-i, " ");
70 i += zd_rf_scnprint_id(&chip->rf, buffer+i, size-i); 69 i += zd_rf_scnprint_id(&chip->rf, buffer+i, size-i);
71 i += scnprintf(buffer+i, size-i, " pa%1x %c%c%c", chip->pa_type, 70 i += scnprintf(buffer+i, size-i, " pa%1x %c%c%c%c", chip->pa_type,
72 chip->patch_cck_gain ? 'g' : '-', 71 chip->patch_cck_gain ? 'g' : '-',
73 chip->patch_cr157 ? '7' : '-', 72 chip->patch_cr157 ? '7' : '-',
74 chip->patch_6m_band_edge ? '6' : '-'); 73 chip->patch_6m_band_edge ? '6' : '-',
74 chip->new_phy_layout ? 'N' : '-');
75 return i; 75 return i;
76} 76}
77 77
@@ -330,13 +330,14 @@ static int read_pod(struct zd_chip *chip, u8 *rf_type)
330 chip->patch_cck_gain = (value >> 8) & 0x1; 330 chip->patch_cck_gain = (value >> 8) & 0x1;
331 chip->patch_cr157 = (value >> 13) & 0x1; 331 chip->patch_cr157 = (value >> 13) & 0x1;
332 chip->patch_6m_band_edge = (value >> 21) & 0x1; 332 chip->patch_6m_band_edge = (value >> 21) & 0x1;
333 chip->new_phy_layout = (value >> 31) & 0x1;
333 334
334 dev_dbg_f(zd_chip_dev(chip), 335 dev_dbg_f(zd_chip_dev(chip),
335 "RF %s %#01x PA type %#01x patch CCK %d patch CR157 %d " 336 "RF %s %#01x PA type %#01x patch CCK %d patch CR157 %d "
336 "patch 6M %d\n", 337 "patch 6M %d new PHY %d\n",
337 zd_rf_name(*rf_type), *rf_type, 338 zd_rf_name(*rf_type), *rf_type,
338 chip->pa_type, chip->patch_cck_gain, 339 chip->pa_type, chip->patch_cck_gain,
339 chip->patch_cr157, chip->patch_6m_band_edge); 340 chip->patch_cr157, chip->patch_6m_band_edge, chip->new_phy_layout);
340 return 0; 341 return 0;
341error: 342error:
342 *rf_type = 0; 343 *rf_type = 0;
@@ -344,6 +345,7 @@ error:
344 chip->patch_cck_gain = 0; 345 chip->patch_cck_gain = 0;
345 chip->patch_cr157 = 0; 346 chip->patch_cr157 = 0;
346 chip->patch_6m_band_edge = 0; 347 chip->patch_6m_band_edge = 0;
348 chip->new_phy_layout = 0;
347 return r; 349 return r;
348} 350}
349 351
@@ -717,7 +719,7 @@ static int zd1211b_hw_reset_phy(struct zd_chip *chip)
717 { CR21, 0x0e }, { CR22, 0x23 }, { CR23, 0x90 }, 719 { CR21, 0x0e }, { CR22, 0x23 }, { CR23, 0x90 },
718 { CR24, 0x14 }, { CR25, 0x40 }, { CR26, 0x10 }, 720 { CR24, 0x14 }, { CR25, 0x40 }, { CR26, 0x10 },
719 { CR27, 0x10 }, { CR28, 0x7f }, { CR29, 0x80 }, 721 { CR27, 0x10 }, { CR28, 0x7f }, { CR29, 0x80 },
720 { CR30, 0x49 }, /* jointly decoder, no ASIC */ 722 { CR30, 0x4b }, /* ASIC/FWT, no jointly decoder */
721 { CR31, 0x60 }, { CR32, 0x43 }, { CR33, 0x08 }, 723 { CR31, 0x60 }, { CR32, 0x43 }, { CR33, 0x08 },
722 { CR34, 0x06 }, { CR35, 0x0a }, { CR36, 0x00 }, 724 { CR34, 0x06 }, { CR35, 0x0a }, { CR36, 0x00 },
723 { CR37, 0x00 }, { CR38, 0x38 }, { CR39, 0x0c }, 725 { CR37, 0x00 }, { CR38, 0x38 }, { CR39, 0x0c },
@@ -807,7 +809,6 @@ static int zd1211_hw_init_hmac(struct zd_chip *chip)
807 { CR_ACK_TIMEOUT_EXT, 0x80 }, 809 { CR_ACK_TIMEOUT_EXT, 0x80 },
808 { CR_ADDA_PWR_DWN, 0x00 }, 810 { CR_ADDA_PWR_DWN, 0x00 },
809 { CR_ACK_TIME_80211, 0x100 }, 811 { CR_ACK_TIME_80211, 0x100 },
810 { CR_IFS_VALUE, 0x547c032 },
811 { CR_RX_PE_DELAY, 0x70 }, 812 { CR_RX_PE_DELAY, 0x70 },
812 { CR_PS_CTRL, 0x10000000 }, 813 { CR_PS_CTRL, 0x10000000 },
813 { CR_RTS_CTS_RATE, 0x02030203 }, 814 { CR_RTS_CTS_RATE, 0x02030203 },
@@ -854,11 +855,10 @@ static int zd1211b_hw_init_hmac(struct zd_chip *chip)
854 { CR_ACK_TIMEOUT_EXT, 0x80 }, 855 { CR_ACK_TIMEOUT_EXT, 0x80 },
855 { CR_ADDA_PWR_DWN, 0x00 }, 856 { CR_ADDA_PWR_DWN, 0x00 },
856 { CR_ACK_TIME_80211, 0x100 }, 857 { CR_ACK_TIME_80211, 0x100 },
857 { CR_IFS_VALUE, 0x547c032 },
858 { CR_RX_PE_DELAY, 0x70 }, 858 { CR_RX_PE_DELAY, 0x70 },
859 { CR_PS_CTRL, 0x10000000 }, 859 { CR_PS_CTRL, 0x10000000 },
860 { CR_RTS_CTS_RATE, 0x02030203 }, 860 { CR_RTS_CTS_RATE, 0x02030203 },
861 { CR_RX_THRESHOLD, 0x000c0640 }, 861 { CR_RX_THRESHOLD, 0x000c0eff, },
862 { CR_AFTER_PNP, 0x1 }, 862 { CR_AFTER_PNP, 0x1 },
863 { CR_WEP_PROTECT, 0x114 }, 863 { CR_WEP_PROTECT, 0x114 },
864 }; 864 };
@@ -970,10 +970,15 @@ static int hw_init(struct zd_chip *chip)
970 r = hw_init_hmac(chip); 970 r = hw_init_hmac(chip);
971 if (r) 971 if (r)
972 return r; 972 return r;
973 r = set_beacon_interval(chip, 100); 973
974 /* Although the vendor driver defaults to a different value during
975 * init, it overwrites the IFS value with the following every time
976 * the channel changes. We should aim to be more intelligent... */
977 r = zd_iowrite32_locked(chip, IFS_VALUE_DEFAULT, CR_IFS_VALUE);
974 if (r) 978 if (r)
975 return r; 979 return r;
976 return 0; 980
981 return set_beacon_interval(chip, 100);
977} 982}
978 983
979#ifdef DEBUG 984#ifdef DEBUG
@@ -1613,3 +1618,34 @@ int zd_rfwritev_locked(struct zd_chip *chip,
1613 1618
1614 return 0; 1619 return 0;
1615} 1620}
1621
1622/*
1623 * We can optionally program the RF directly through CR regs, if supported by
1624 * the hardware. This is much faster than the older method.
1625 */
1626int zd_rfwrite_cr_locked(struct zd_chip *chip, u32 value)
1627{
1628 struct zd_ioreq16 ioreqs[] = {
1629 { CR244, (value >> 16) & 0xff },
1630 { CR243, (value >> 8) & 0xff },
1631 { CR242, value & 0xff },
1632 };
1633 ZD_ASSERT(mutex_is_locked(&chip->mutex));
1634 return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
1635}
1636
1637int zd_rfwritev_cr_locked(struct zd_chip *chip,
1638 const u32 *values, unsigned int count)
1639{
1640 int r;
1641 unsigned int i;
1642
1643 for (i = 0; i < count; i++) {
1644 r = zd_rfwrite_cr_locked(chip, values[i]);
1645 if (r)
1646 return r;
1647 }
1648
1649 return 0;
1650}
1651
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.h b/drivers/net/wireless/zd1211rw/zd_chip.h
index 069d2b467339..4b1250859897 100644
--- a/drivers/net/wireless/zd1211rw/zd_chip.h
+++ b/drivers/net/wireless/zd1211rw/zd_chip.h
@@ -473,7 +473,15 @@
473 473
474#define CR_ACK_TIMEOUT_EXT CTL_REG(0x0690) 474#define CR_ACK_TIMEOUT_EXT CTL_REG(0x0690)
475#define CR_BCN_FIFO_SEMAPHORE CTL_REG(0x0694) 475#define CR_BCN_FIFO_SEMAPHORE CTL_REG(0x0694)
476
476#define CR_IFS_VALUE CTL_REG(0x0698) 477#define CR_IFS_VALUE CTL_REG(0x0698)
478#define IFS_VALUE_DIFS_SH 0
479#define IFS_VALUE_EIFS_SH 12
480#define IFS_VALUE_SIFS_SH 24
481#define IFS_VALUE_DEFAULT (( 50 << IFS_VALUE_DIFS_SH) | \
482 (1148 << IFS_VALUE_EIFS_SH) | \
483 ( 10 << IFS_VALUE_SIFS_SH))
484
477#define CR_RX_TIME_OUT CTL_REG(0x069C) 485#define CR_RX_TIME_OUT CTL_REG(0x069C)
478#define CR_TOTAL_RX_FRM CTL_REG(0x06A0) 486#define CR_TOTAL_RX_FRM CTL_REG(0x06A0)
479#define CR_CRC32_CNT CTL_REG(0x06A4) 487#define CR_CRC32_CNT CTL_REG(0x06A4)
@@ -630,6 +638,7 @@ enum {
630 LOAD_CODE_SIZE = 0xe, /* words */ 638 LOAD_CODE_SIZE = 0xe, /* words */
631 LOAD_VECT_SIZE = 0x10000 - 0xfff7, /* words */ 639 LOAD_VECT_SIZE = 0x10000 - 0xfff7, /* words */
632 EEPROM_REGS_OFFSET = LOAD_CODE_SIZE + LOAD_VECT_SIZE, 640 EEPROM_REGS_OFFSET = LOAD_CODE_SIZE + LOAD_VECT_SIZE,
641 EEPROM_REGS_SIZE = 0x7e, /* words */
633 E2P_BASE_OFFSET = EEPROM_START_OFFSET + 642 E2P_BASE_OFFSET = EEPROM_START_OFFSET +
634 EEPROM_REGS_OFFSET, 643 EEPROM_REGS_OFFSET,
635}; 644};
@@ -655,7 +664,7 @@ struct zd_chip {
655 /* SetPointOFDM in the vendor driver */ 664 /* SetPointOFDM in the vendor driver */
656 u8 ofdm_cal_values[3][E2P_CHANNEL_COUNT]; 665 u8 ofdm_cal_values[3][E2P_CHANNEL_COUNT];
657 u8 pa_type:4, patch_cck_gain:1, patch_cr157:1, patch_6m_band_edge:1, 666 u8 pa_type:4, patch_cck_gain:1, patch_cr157:1, patch_6m_band_edge:1,
658 is_zd1211b:1; 667 new_phy_layout:1, is_zd1211b:1;
659}; 668};
660 669
661static inline struct zd_chip *zd_usb_to_chip(struct zd_usb *usb) 670static inline struct zd_chip *zd_usb_to_chip(struct zd_usb *usb)
@@ -739,8 +748,12 @@ static inline int zd_rfwrite_locked(struct zd_chip *chip, u32 value, u8 bits)
739 return zd_usb_rfwrite(&chip->usb, value, bits); 748 return zd_usb_rfwrite(&chip->usb, value, bits);
740} 749}
741 750
751int zd_rfwrite_cr_locked(struct zd_chip *chip, u32 value);
752
742int zd_rfwritev_locked(struct zd_chip *chip, 753int zd_rfwritev_locked(struct zd_chip *chip,
743 const u32* values, unsigned int count, u8 bits); 754 const u32* values, unsigned int count, u8 bits);
755int zd_rfwritev_cr_locked(struct zd_chip *chip,
756 const u32* values, unsigned int count);
744 757
745/* Locking functions for reading and writing registers. 758/* Locking functions for reading and writing registers.
746 * The different parameters are intentional. 759 * The different parameters are intentional.
diff --git a/drivers/net/wireless/zd1211rw/zd_def.h b/drivers/net/wireless/zd1211rw/zd_def.h
index 465906812fc4..a13ec72eb304 100644
--- a/drivers/net/wireless/zd1211rw/zd_def.h
+++ b/drivers/net/wireless/zd1211rw/zd_def.h
@@ -45,4 +45,10 @@ do { \
45# define ZD_ASSERT(x) do { } while (0) 45# define ZD_ASSERT(x) do { } while (0)
46#endif 46#endif
47 47
48#ifdef DEBUG
49# define ZD_MEMCLEAR(pointer, size) memset((pointer), 0xff, (size))
50#else
51# define ZD_MEMCLEAR(pointer, size) do { } while (0)
52#endif
53
48#endif /* _ZD_DEF_H */ 54#endif /* _ZD_DEF_H */
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c
index d6f3e02a0b54..0eda534a648c 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.c
+++ b/drivers/net/wireless/zd1211rw/zd_mac.c
@@ -127,11 +127,9 @@ out:
127 127
128void zd_mac_clear(struct zd_mac *mac) 128void zd_mac_clear(struct zd_mac *mac)
129{ 129{
130 /* Aquire the lock. */
131 spin_lock(&mac->lock);
132 spin_unlock(&mac->lock);
133 zd_chip_clear(&mac->chip); 130 zd_chip_clear(&mac->chip);
134 memset(mac, 0, sizeof(*mac)); 131 ZD_ASSERT(!spin_is_locked(&mac->lock));
132 ZD_MEMCLEAR(mac, sizeof(struct zd_mac));
135} 133}
136 134
137static int reset_mode(struct zd_mac *mac) 135static int reset_mode(struct zd_mac *mac)
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.h b/drivers/net/wireless/zd1211rw/zd_mac.h
index 71e382c589ee..082bcf8ec8dc 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.h
+++ b/drivers/net/wireless/zd1211rw/zd_mac.h
@@ -121,9 +121,9 @@ enum mac_flags {
121}; 121};
122 122
123struct zd_mac { 123struct zd_mac {
124 struct net_device *netdev;
125 struct zd_chip chip; 124 struct zd_chip chip;
126 spinlock_t lock; 125 spinlock_t lock;
126 struct net_device *netdev;
127 /* Unlocked reading possible */ 127 /* Unlocked reading possible */
128 struct iw_statistics iw_stats; 128 struct iw_statistics iw_stats;
129 u8 qual_average; 129 u8 qual_average;
diff --git a/drivers/net/wireless/zd1211rw/zd_netdev.c b/drivers/net/wireless/zd1211rw/zd_netdev.c
index 9df232c2c863..440ef24b5fd1 100644
--- a/drivers/net/wireless/zd1211rw/zd_netdev.c
+++ b/drivers/net/wireless/zd1211rw/zd_netdev.c
@@ -72,10 +72,18 @@ static int iw_get_name(struct net_device *netdev,
72 struct iw_request_info *info, 72 struct iw_request_info *info,
73 union iwreq_data *req, char *extra) 73 union iwreq_data *req, char *extra)
74{ 74{
75 /* FIXME: check whether 802.11a will also supported, add also 75 /* FIXME: check whether 802.11a will also supported */
76 * zd1211B, if we support it. 76 strlcpy(req->name, "IEEE 802.11b/g", IFNAMSIZ);
77 */ 77 return 0;
78 strlcpy(req->name, "802.11g zd1211", IFNAMSIZ); 78}
79
80static int iw_get_nick(struct net_device *netdev,
81 struct iw_request_info *info,
82 union iwreq_data *req, char *extra)
83{
84 strcpy(extra, "zd1211");
85 req->data.length = strlen(extra) + 1;
86 req->data.flags = 1;
79 return 0; 87 return 0;
80} 88}
81 89
@@ -181,6 +189,7 @@ static int iw_get_encodeext(struct net_device *netdev,
181 189
182static const iw_handler zd_standard_iw_handlers[] = { 190static const iw_handler zd_standard_iw_handlers[] = {
183 WX(SIOCGIWNAME) = iw_get_name, 191 WX(SIOCGIWNAME) = iw_get_name,
192 WX(SIOCGIWNICKN) = iw_get_nick,
184 WX(SIOCSIWFREQ) = iw_set_freq, 193 WX(SIOCSIWFREQ) = iw_set_freq,
185 WX(SIOCGIWFREQ) = iw_get_freq, 194 WX(SIOCGIWFREQ) = iw_get_freq,
186 WX(SIOCSIWMODE) = iw_set_mode, 195 WX(SIOCSIWMODE) = iw_set_mode,
diff --git a/drivers/net/wireless/zd1211rw/zd_rf.c b/drivers/net/wireless/zd1211rw/zd_rf.c
index d3770d2c61bc..f50cff3db916 100644
--- a/drivers/net/wireless/zd1211rw/zd_rf.c
+++ b/drivers/net/wireless/zd1211rw/zd_rf.c
@@ -56,7 +56,7 @@ void zd_rf_init(struct zd_rf *rf)
56 56
57void zd_rf_clear(struct zd_rf *rf) 57void zd_rf_clear(struct zd_rf *rf)
58{ 58{
59 memset(rf, 0, sizeof(*rf)); 59 ZD_MEMCLEAR(rf, sizeof(*rf));
60} 60}
61 61
62int zd_rf_init_hw(struct zd_rf *rf, u8 type) 62int zd_rf_init_hw(struct zd_rf *rf, u8 type)
@@ -76,6 +76,11 @@ int zd_rf_init_hw(struct zd_rf *rf, u8 type)
76 if (r) 76 if (r)
77 return r; 77 return r;
78 break; 78 break;
79 case AL7230B_RF:
80 r = zd_rf_init_al7230b(rf);
81 if (r)
82 return r;
83 break;
79 default: 84 default:
80 dev_err(zd_chip_dev(chip), 85 dev_err(zd_chip_dev(chip),
81 "RF %s %#x is not supported\n", zd_rf_name(type), type); 86 "RF %s %#x is not supported\n", zd_rf_name(type), type);
diff --git a/drivers/net/wireless/zd1211rw/zd_rf.h b/drivers/net/wireless/zd1211rw/zd_rf.h
index ea30f693fcc8..676b3734f1ed 100644
--- a/drivers/net/wireless/zd1211rw/zd_rf.h
+++ b/drivers/net/wireless/zd1211rw/zd_rf.h
@@ -78,5 +78,6 @@ int zd_switch_radio_off(struct zd_rf *rf);
78 78
79int zd_rf_init_rf2959(struct zd_rf *rf); 79int zd_rf_init_rf2959(struct zd_rf *rf);
80int zd_rf_init_al2230(struct zd_rf *rf); 80int zd_rf_init_al2230(struct zd_rf *rf);
81int zd_rf_init_al7230b(struct zd_rf *rf);
81 82
82#endif /* _ZD_RF_H */ 83#endif /* _ZD_RF_H */
diff --git a/drivers/net/wireless/zd1211rw/zd_rf_al2230.c b/drivers/net/wireless/zd1211rw/zd_rf_al2230.c
index 0948b25f660d..25323a13a3db 100644
--- a/drivers/net/wireless/zd1211rw/zd_rf_al2230.c
+++ b/drivers/net/wireless/zd1211rw/zd_rf_al2230.c
@@ -21,7 +21,7 @@
21#include "zd_usb.h" 21#include "zd_usb.h"
22#include "zd_chip.h" 22#include "zd_chip.h"
23 23
24static const u32 al2230_table[][3] = { 24static const u32 zd1211_al2230_table[][3] = {
25 RF_CHANNEL( 1) = { 0x03f790, 0x033331, 0x00000d, }, 25 RF_CHANNEL( 1) = { 0x03f790, 0x033331, 0x00000d, },
26 RF_CHANNEL( 2) = { 0x03f790, 0x0b3331, 0x00000d, }, 26 RF_CHANNEL( 2) = { 0x03f790, 0x0b3331, 0x00000d, },
27 RF_CHANNEL( 3) = { 0x03e790, 0x033331, 0x00000d, }, 27 RF_CHANNEL( 3) = { 0x03e790, 0x033331, 0x00000d, },
@@ -38,6 +38,53 @@ static const u32 al2230_table[][3] = {
38 RF_CHANNEL(14) = { 0x03e7c0, 0x066661, 0x00000d, }, 38 RF_CHANNEL(14) = { 0x03e7c0, 0x066661, 0x00000d, },
39}; 39};
40 40
41static const u32 zd1211b_al2230_table[][3] = {
42 RF_CHANNEL( 1) = { 0x09efc0, 0x8cccc0, 0xb00000, },
43 RF_CHANNEL( 2) = { 0x09efc0, 0x8cccd0, 0xb00000, },
44 RF_CHANNEL( 3) = { 0x09e7c0, 0x8cccc0, 0xb00000, },
45 RF_CHANNEL( 4) = { 0x09e7c0, 0x8cccd0, 0xb00000, },
46 RF_CHANNEL( 5) = { 0x05efc0, 0x8cccc0, 0xb00000, },
47 RF_CHANNEL( 6) = { 0x05efc0, 0x8cccd0, 0xb00000, },
48 RF_CHANNEL( 7) = { 0x05e7c0, 0x8cccc0, 0xb00000, },
49 RF_CHANNEL( 8) = { 0x05e7c0, 0x8cccd0, 0xb00000, },
50 RF_CHANNEL( 9) = { 0x0defc0, 0x8cccc0, 0xb00000, },
51 RF_CHANNEL(10) = { 0x0defc0, 0x8cccd0, 0xb00000, },
52 RF_CHANNEL(11) = { 0x0de7c0, 0x8cccc0, 0xb00000, },
53 RF_CHANNEL(12) = { 0x0de7c0, 0x8cccd0, 0xb00000, },
54 RF_CHANNEL(13) = { 0x03efc0, 0x8cccc0, 0xb00000, },
55 RF_CHANNEL(14) = { 0x03e7c0, 0x866660, 0xb00000, },
56};
57
58static const struct zd_ioreq16 zd1211b_ioreqs_shared_1[] = {
59 { CR240, 0x57 }, { CR9, 0xe0 },
60};
61
62static int zd1211b_al2230_finalize_rf(struct zd_chip *chip)
63{
64 int r;
65 static const struct zd_ioreq16 ioreqs[] = {
66 { CR80, 0x30 }, { CR81, 0x30 }, { CR79, 0x58 },
67 { CR12, 0xf0 }, { CR77, 0x1b }, { CR78, 0x58 },
68 { CR203, 0x06 },
69 { },
70
71 { CR240, 0x80 },
72 };
73
74 r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
75 if (r)
76 return r;
77
78 /* related to antenna selection? */
79 if (chip->new_phy_layout) {
80 r = zd_iowrite16_locked(chip, 0xe1, CR9);
81 if (r)
82 return r;
83 }
84
85 return zd_iowrite16_locked(chip, 0x06, CR203);
86}
87
41static int zd1211_al2230_init_hw(struct zd_rf *rf) 88static int zd1211_al2230_init_hw(struct zd_rf *rf)
42{ 89{
43 int r; 90 int r;
@@ -139,7 +186,7 @@ static int zd1211b_al2230_init_hw(struct zd_rf *rf)
139 { CR47, 0x1e }, 186 { CR47, 0x1e },
140 187
141 /* ZD1211B 05.06.10 */ 188 /* ZD1211B 05.06.10 */
142 { CR48, 0x00 }, { CR49, 0x00 }, { CR51, 0x01 }, 189 { CR48, 0x06 }, { CR49, 0xf9 }, { CR51, 0x01 },
143 { CR52, 0x80 }, { CR53, 0x7e }, { CR65, 0x00 }, 190 { CR52, 0x80 }, { CR53, 0x7e }, { CR65, 0x00 },
144 { CR66, 0x00 }, { CR67, 0x00 }, { CR68, 0x00 }, 191 { CR66, 0x00 }, { CR67, 0x00 }, { CR68, 0x00 },
145 { CR69, 0x28 }, 192 { CR69, 0x28 },
@@ -172,79 +219,78 @@ static int zd1211b_al2230_init_hw(struct zd_rf *rf)
172 { CR137, 0x50 }, /* 5614 */ 219 { CR137, 0x50 }, /* 5614 */
173 { CR138, 0xa8 }, 220 { CR138, 0xa8 },
174 { CR144, 0xac }, /* 5621 */ 221 { CR144, 0xac }, /* 5621 */
175 { CR150, 0x0d }, { CR252, 0x00 }, { CR253, 0x00 }, 222 { CR150, 0x0d }, { CR252, 0x34 }, { CR253, 0x34 },
176 }; 223 };
177 224
178 static const u32 rv1[] = { 225 static const u32 rv1[] = {
179 /* channel 1 */ 226 0x8cccd0,
180 0x03f790, 227 0x481dc0,
181 0x033331, 228 0xcfff00,
182 0x00000d, 229 0x25a000,
183 230
184 0x0b3331, 231 /* To improve AL2230 yield, improve phase noise, 4713 */
185 0x03b812, 232 0x25a000,
186 0x00fff3, 233 0xa3b2f0,
187 0x0005a4, 234
188 0x0f4dc5, /* fix freq shift 0x044dc5 */ 235 0x6da010, /* Reg6 update for MP versio */
189 0x0805b6, 236 0xe36280, /* Modified by jxiao for Bor-Chin on 2004/08/02 */
190 0x0146c7, 237 0x116000,
191 0x000688, 238 0x9dc020, /* External control TX power (CR31) */
192 0x0403b9, /* External control TX power (CR31) */ 239 0x5ddb00, /* RegA update for MP version */
193 0x00dbba, 240 0xd99000, /* RegB update for MP version */
194 0x00099b, 241 0x3ffbd0, /* RegC update for MP version */
195 0x0bdffc, 242 0xb00000, /* RegD update for MP version */
196 0x00000d, 243
197 0x00580f, 244 /* improve phase noise and remove phase calibration,4713 */
245 0xf01a00,
198 }; 246 };
199 247
200 static const struct zd_ioreq16 ioreqs2[] = { 248 static const struct zd_ioreq16 ioreqs2[] = {
201 { CR47, 0x1e }, { CR_RFCFG, 0x03 }, 249 { CR251, 0x2f }, /* shdnb(PLL_ON)=0 */
250 { CR251, 0x7f }, /* shdnb(PLL_ON)=1 */
202 }; 251 };
203 252
204 static const u32 rv2[] = { 253 static const u32 rv2[] = {
205 0x00880f, 254 /* To improve AL2230 yield, 4713 */
206 0x00080f, 255 0xf01b00,
256 0xf01e00,
257 0xf01a00,
207 }; 258 };
208 259
209 static const struct zd_ioreq16 ioreqs3[] = { 260 static const struct zd_ioreq16 ioreqs3[] = {
210 { CR_RFCFG, 0x00 }, { CR47, 0x1e }, { CR251, 0x7f }, 261 /* related to 6M band edge patching, happens unconditionally */
211 }; 262 { CR128, 0x14 }, { CR129, 0x12 }, { CR130, 0x10 },
212
213 static const u32 rv3[] = {
214 0x00d80f,
215 0x00780f,
216 0x00580f,
217 };
218
219 static const struct zd_ioreq16 ioreqs4[] = {
220 { CR138, 0x28 }, { CR203, 0x06 },
221 }; 263 };
222 264
265 r = zd_iowrite16a_locked(chip, zd1211b_ioreqs_shared_1,
266 ARRAY_SIZE(zd1211b_ioreqs_shared_1));
267 if (r)
268 return r;
223 r = zd_iowrite16a_locked(chip, ioreqs1, ARRAY_SIZE(ioreqs1)); 269 r = zd_iowrite16a_locked(chip, ioreqs1, ARRAY_SIZE(ioreqs1));
224 if (r) 270 if (r)
225 return r; 271 return r;
226 r = zd_rfwritev_locked(chip, rv1, ARRAY_SIZE(rv1), RF_RV_BITS); 272 r = zd_rfwritev_cr_locked(chip, zd1211b_al2230_table[0], 3);
227 if (r) 273 if (r)
228 return r; 274 return r;
229 r = zd_iowrite16a_locked(chip, ioreqs2, ARRAY_SIZE(ioreqs2)); 275 r = zd_rfwritev_cr_locked(chip, rv1, ARRAY_SIZE(rv1));
230 if (r) 276 if (r)
231 return r; 277 return r;
232 r = zd_rfwritev_locked(chip, rv2, ARRAY_SIZE(rv2), RF_RV_BITS); 278 r = zd_iowrite16a_locked(chip, ioreqs2, ARRAY_SIZE(ioreqs2));
233 if (r) 279 if (r)
234 return r; 280 return r;
235 r = zd_iowrite16a_locked(chip, ioreqs3, ARRAY_SIZE(ioreqs3)); 281 r = zd_rfwritev_cr_locked(chip, rv2, ARRAY_SIZE(rv2));
236 if (r) 282 if (r)
237 return r; 283 return r;
238 r = zd_rfwritev_locked(chip, rv3, ARRAY_SIZE(rv3), RF_RV_BITS); 284 r = zd_iowrite16a_locked(chip, ioreqs3, ARRAY_SIZE(ioreqs3));
239 if (r) 285 if (r)
240 return r; 286 return r;
241 return zd_iowrite16a_locked(chip, ioreqs4, ARRAY_SIZE(ioreqs4)); 287 return zd1211b_al2230_finalize_rf(chip);
242} 288}
243 289
244static int al2230_set_channel(struct zd_rf *rf, u8 channel) 290static int zd1211_al2230_set_channel(struct zd_rf *rf, u8 channel)
245{ 291{
246 int r; 292 int r;
247 const u32 *rv = al2230_table[channel-1]; 293 const u32 *rv = zd1211_al2230_table[channel-1];
248 struct zd_chip *chip = zd_rf_to_chip(rf); 294 struct zd_chip *chip = zd_rf_to_chip(rf);
249 static const struct zd_ioreq16 ioreqs[] = { 295 static const struct zd_ioreq16 ioreqs[] = {
250 { CR138, 0x28 }, 296 { CR138, 0x28 },
@@ -257,6 +303,24 @@ static int al2230_set_channel(struct zd_rf *rf, u8 channel)
257 return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); 303 return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
258} 304}
259 305
306static int zd1211b_al2230_set_channel(struct zd_rf *rf, u8 channel)
307{
308 int r;
309 const u32 *rv = zd1211b_al2230_table[channel-1];
310 struct zd_chip *chip = zd_rf_to_chip(rf);
311
312 r = zd_iowrite16a_locked(chip, zd1211b_ioreqs_shared_1,
313 ARRAY_SIZE(zd1211b_ioreqs_shared_1));
314 if (r)
315 return r;
316
317 r = zd_rfwritev_cr_locked(chip, rv, 3);
318 if (r)
319 return r;
320
321 return zd1211b_al2230_finalize_rf(chip);
322}
323
260static int zd1211_al2230_switch_radio_on(struct zd_rf *rf) 324static int zd1211_al2230_switch_radio_on(struct zd_rf *rf)
261{ 325{
262 struct zd_chip *chip = zd_rf_to_chip(rf); 326 struct zd_chip *chip = zd_rf_to_chip(rf);
@@ -294,13 +358,14 @@ int zd_rf_init_al2230(struct zd_rf *rf)
294{ 358{
295 struct zd_chip *chip = zd_rf_to_chip(rf); 359 struct zd_chip *chip = zd_rf_to_chip(rf);
296 360
297 rf->set_channel = al2230_set_channel;
298 rf->switch_radio_off = al2230_switch_radio_off; 361 rf->switch_radio_off = al2230_switch_radio_off;
299 if (chip->is_zd1211b) { 362 if (chip->is_zd1211b) {
300 rf->init_hw = zd1211b_al2230_init_hw; 363 rf->init_hw = zd1211b_al2230_init_hw;
364 rf->set_channel = zd1211b_al2230_set_channel;
301 rf->switch_radio_on = zd1211b_al2230_switch_radio_on; 365 rf->switch_radio_on = zd1211b_al2230_switch_radio_on;
302 } else { 366 } else {
303 rf->init_hw = zd1211_al2230_init_hw; 367 rf->init_hw = zd1211_al2230_init_hw;
368 rf->set_channel = zd1211_al2230_set_channel;
304 rf->switch_radio_on = zd1211_al2230_switch_radio_on; 369 rf->switch_radio_on = zd1211_al2230_switch_radio_on;
305 } 370 }
306 rf->patch_6m_band_edge = 1; 371 rf->patch_6m_band_edge = 1;
diff --git a/drivers/net/wireless/zd1211rw/zd_rf_al7230b.c b/drivers/net/wireless/zd1211rw/zd_rf_al7230b.c
new file mode 100644
index 000000000000..a289f95187ec
--- /dev/null
+++ b/drivers/net/wireless/zd1211rw/zd_rf_al7230b.c
@@ -0,0 +1,274 @@
1/* zd_rf_al7230b.c: Functions for the AL7230B RF controller
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 */
17
18#include <linux/kernel.h>
19
20#include "zd_rf.h"
21#include "zd_usb.h"
22#include "zd_chip.h"
23
24static const u32 chan_rv[][2] = {
25 RF_CHANNEL( 1) = { 0x09ec00, 0x8cccc8 },
26 RF_CHANNEL( 2) = { 0x09ec00, 0x8cccd8 },
27 RF_CHANNEL( 3) = { 0x09ec00, 0x8cccc0 },
28 RF_CHANNEL( 4) = { 0x09ec00, 0x8cccd0 },
29 RF_CHANNEL( 5) = { 0x05ec00, 0x8cccc8 },
30 RF_CHANNEL( 6) = { 0x05ec00, 0x8cccd8 },
31 RF_CHANNEL( 7) = { 0x05ec00, 0x8cccc0 },
32 RF_CHANNEL( 8) = { 0x05ec00, 0x8cccd0 },
33 RF_CHANNEL( 9) = { 0x0dec00, 0x8cccc8 },
34 RF_CHANNEL(10) = { 0x0dec00, 0x8cccd8 },
35 RF_CHANNEL(11) = { 0x0dec00, 0x8cccc0 },
36 RF_CHANNEL(12) = { 0x0dec00, 0x8cccd0 },
37 RF_CHANNEL(13) = { 0x03ec00, 0x8cccc8 },
38 RF_CHANNEL(14) = { 0x03ec00, 0x866660 },
39};
40
41static const u32 std_rv[] = {
42 0x4ff821,
43 0xc5fbfc,
44 0x21ebfe,
45 0xafd401, /* freq shift 0xaad401 */
46 0x6cf56a,
47 0xe04073,
48 0x193d76,
49 0x9dd844,
50 0x500007,
51 0xd8c010,
52};
53
54static int al7230b_init_hw(struct zd_rf *rf)
55{
56 int i, r;
57 struct zd_chip *chip = zd_rf_to_chip(rf);
58
59 /* All of these writes are identical to AL2230 unless otherwise
60 * specified */
61 static const struct zd_ioreq16 ioreqs_1[] = {
62 /* This one is 7230-specific, and happens before the rest */
63 { CR240, 0x57 },
64 { },
65
66 { CR15, 0x20 }, { CR23, 0x40 }, { CR24, 0x20 },
67 { CR26, 0x11 }, { CR28, 0x3e }, { CR29, 0x00 },
68 { CR44, 0x33 },
69 /* This value is different for 7230 (was: 0x2a) */
70 { CR106, 0x22 },
71 { CR107, 0x1a }, { CR109, 0x09 }, { CR110, 0x27 },
72 { CR111, 0x2b }, { CR112, 0x2b }, { CR119, 0x0a },
73 /* This happened further down in AL2230,
74 * and the value changed (was: 0xe0) */
75 { CR122, 0xfc },
76 { CR10, 0x89 },
77 /* for newest (3rd cut) AL2300 */
78 { CR17, 0x28 },
79 { CR26, 0x93 }, { CR34, 0x30 },
80 /* for newest (3rd cut) AL2300 */
81 { CR35, 0x3e },
82 { CR41, 0x24 }, { CR44, 0x32 },
83 /* for newest (3rd cut) AL2300 */
84 { CR46, 0x96 },
85 { CR47, 0x1e }, { CR79, 0x58 }, { CR80, 0x30 },
86 { CR81, 0x30 }, { CR87, 0x0a }, { CR89, 0x04 },
87 { CR92, 0x0a }, { CR99, 0x28 },
88 /* This value is different for 7230 (was: 0x00) */
89 { CR100, 0x02 },
90 { CR101, 0x13 }, { CR102, 0x27 },
91 /* This value is different for 7230 (was: 0x24) */
92 { CR106, 0x22 },
93 /* This value is different for 7230 (was: 0x2a) */
94 { CR107, 0x3f },
95 { CR109, 0x09 },
96 /* This value is different for 7230 (was: 0x13) */
97 { CR110, 0x1f },
98 { CR111, 0x1f }, { CR112, 0x1f }, { CR113, 0x27 },
99 { CR114, 0x27 },
100 /* for newest (3rd cut) AL2300 */
101 { CR115, 0x24 },
102 /* This value is different for 7230 (was: 0x24) */
103 { CR116, 0x3f },
104 /* This value is different for 7230 (was: 0xf4) */
105 { CR117, 0xfa },
106 { CR118, 0xfc }, { CR119, 0x10 }, { CR120, 0x4f },
107 { CR121, 0x77 }, { CR137, 0x88 },
108 /* This one is 7230-specific */
109 { CR138, 0xa8 },
110 /* This value is different for 7230 (was: 0xff) */
111 { CR252, 0x34 },
112 /* This value is different for 7230 (was: 0xff) */
113 { CR253, 0x34 },
114
115 /* PLL_OFF */
116 { CR251, 0x2f },
117 };
118
119 static const struct zd_ioreq16 ioreqs_2[] = {
120 /* PLL_ON */
121 { CR251, 0x3f },
122 { CR128, 0x14 }, { CR129, 0x12 }, { CR130, 0x10 },
123 { CR38, 0x38 }, { CR136, 0xdf },
124 };
125
126 r = zd_iowrite16a_locked(chip, ioreqs_1, ARRAY_SIZE(ioreqs_1));
127 if (r)
128 return r;
129
130 r = zd_rfwrite_cr_locked(chip, 0x09ec04);
131 if (r)
132 return r;
133 r = zd_rfwrite_cr_locked(chip, 0x8cccc8);
134 if (r)
135 return r;
136
137 for (i = 0; i < ARRAY_SIZE(std_rv); i++) {
138 r = zd_rfwrite_cr_locked(chip, std_rv[i]);
139 if (r)
140 return r;
141 }
142
143 r = zd_rfwrite_cr_locked(chip, 0x3c9000);
144 if (r)
145 return r;
146 r = zd_rfwrite_cr_locked(chip, 0xbfffff);
147 if (r)
148 return r;
149 r = zd_rfwrite_cr_locked(chip, 0x700000);
150 if (r)
151 return r;
152 r = zd_rfwrite_cr_locked(chip, 0xf15d58);
153 if (r)
154 return r;
155
156 r = zd_iowrite16a_locked(chip, ioreqs_2, ARRAY_SIZE(ioreqs_2));
157 if (r)
158 return r;
159
160 r = zd_rfwrite_cr_locked(chip, 0xf15d59);
161 if (r)
162 return r;
163 r = zd_rfwrite_cr_locked(chip, 0xf15d5c);
164 if (r)
165 return r;
166 r = zd_rfwrite_cr_locked(chip, 0xf15d58);
167 if (r)
168 return r;
169
170 r = zd_iowrite16_locked(chip, 0x06, CR203);
171 if (r)
172 return r;
173 r = zd_iowrite16_locked(chip, 0x80, CR240);
174 if (r)
175 return r;
176
177 return 0;
178}
179
180static int al7230b_set_channel(struct zd_rf *rf, u8 channel)
181{
182 int i, r;
183 const u32 *rv = chan_rv[channel-1];
184 struct zd_chip *chip = zd_rf_to_chip(rf);
185
186 struct zd_ioreq16 ioreqs_1[] = {
187 { CR128, 0x14 }, { CR129, 0x12 }, { CR130, 0x10 },
188 { CR38, 0x38 }, { CR136, 0xdf },
189 };
190
191 struct zd_ioreq16 ioreqs_2[] = {
192 /* PLL_ON */
193 { CR251, 0x3f },
194 { CR203, 0x06 }, { CR240, 0x08 },
195 };
196
197 r = zd_iowrite16_locked(chip, 0x57, CR240);
198 if (r)
199 return r;
200
201 /* PLL_OFF */
202 r = zd_iowrite16_locked(chip, 0x2f, CR251);
203 if (r)
204 return r;
205
206 for (i = 0; i < ARRAY_SIZE(std_rv); i++) {
207 r = zd_rfwrite_cr_locked(chip, std_rv[i]);
208 if (r)
209 return r;
210 }
211
212 r = zd_rfwrite_cr_locked(chip, 0x3c9000);
213 if (r)
214 return r;
215 r = zd_rfwrite_cr_locked(chip, 0xf15d58);
216 if (r)
217 return r;
218
219 r = zd_iowrite16a_locked(chip, ioreqs_1, ARRAY_SIZE(ioreqs_1));
220 if (r)
221 return r;
222
223 for (i = 0; i < 2; i++) {
224 r = zd_rfwrite_cr_locked(chip, rv[i]);
225 if (r)
226 return r;
227 }
228
229 r = zd_rfwrite_cr_locked(chip, 0x3c9000);
230 if (r)
231 return r;
232
233 return zd_iowrite16a_locked(chip, ioreqs_2, ARRAY_SIZE(ioreqs_2));
234}
235
236static int al7230b_switch_radio_on(struct zd_rf *rf)
237{
238 struct zd_chip *chip = zd_rf_to_chip(rf);
239 static const struct zd_ioreq16 ioreqs[] = {
240 { CR11, 0x00 },
241 { CR251, 0x3f },
242 };
243
244 return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
245}
246
247static int al7230b_switch_radio_off(struct zd_rf *rf)
248{
249 struct zd_chip *chip = zd_rf_to_chip(rf);
250 static const struct zd_ioreq16 ioreqs[] = {
251 { CR11, 0x04 },
252 { CR251, 0x2f },
253 };
254
255 return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
256}
257
258int zd_rf_init_al7230b(struct zd_rf *rf)
259{
260 struct zd_chip *chip = zd_rf_to_chip(rf);
261
262 if (chip->is_zd1211b) {
263 dev_err(zd_chip_dev(chip), "AL7230B is currently not "
264 "supported for ZD1211B devices\n");
265 return -ENODEV;
266 }
267
268 rf->init_hw = al7230b_init_hw;
269 rf->set_channel = al7230b_set_channel;
270 rf->switch_radio_on = al7230b_switch_radio_on;
271 rf->switch_radio_off = al7230b_switch_radio_off;
272 rf->patch_6m_band_edge = 1;
273 return 0;
274}
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c
index 6320984126c7..47489fe8ab52 100644
--- a/drivers/net/wireless/zd1211rw/zd_usb.c
+++ b/drivers/net/wireless/zd1211rw/zd_usb.c
@@ -16,6 +16,7 @@
16 */ 16 */
17 17
18#include <asm/unaligned.h> 18#include <asm/unaligned.h>
19#include <linux/kernel.h>
19#include <linux/init.h> 20#include <linux/init.h>
20#include <linux/module.h> 21#include <linux/module.h>
21#include <linux/firmware.h> 22#include <linux/firmware.h>
@@ -39,9 +40,17 @@ static struct usb_device_id usb_ids[] = {
39 { USB_DEVICE(0x6891, 0xa727), .driver_info = DEVICE_ZD1211 }, 40 { USB_DEVICE(0x6891, 0xa727), .driver_info = DEVICE_ZD1211 },
40 { USB_DEVICE(0x0df6, 0x9071), .driver_info = DEVICE_ZD1211 }, 41 { USB_DEVICE(0x0df6, 0x9071), .driver_info = DEVICE_ZD1211 },
41 { USB_DEVICE(0x157e, 0x300b), .driver_info = DEVICE_ZD1211 }, 42 { USB_DEVICE(0x157e, 0x300b), .driver_info = DEVICE_ZD1211 },
43 { USB_DEVICE(0x079b, 0x004a), .driver_info = DEVICE_ZD1211 },
44 { USB_DEVICE(0x1740, 0x2000), .driver_info = DEVICE_ZD1211 },
45 { USB_DEVICE(0x157e, 0x3204), .driver_info = DEVICE_ZD1211 },
46 { USB_DEVICE(0x0586, 0x3402), .driver_info = DEVICE_ZD1211 },
42 /* ZD1211B */ 47 /* ZD1211B */
43 { USB_DEVICE(0x0ace, 0x1215), .driver_info = DEVICE_ZD1211B }, 48 { USB_DEVICE(0x0ace, 0x1215), .driver_info = DEVICE_ZD1211B },
44 { USB_DEVICE(0x157e, 0x300d), .driver_info = DEVICE_ZD1211B }, 49 { USB_DEVICE(0x157e, 0x300d), .driver_info = DEVICE_ZD1211B },
50 { USB_DEVICE(0x079b, 0x0062), .driver_info = DEVICE_ZD1211B },
51 { USB_DEVICE(0x1582, 0x6003), .driver_info = DEVICE_ZD1211B },
52 /* "Driverless" devices that need ejecting */
53 { USB_DEVICE(0x0ace, 0x2011), .driver_info = DEVICE_INSTALLER },
45 {} 54 {}
46}; 55};
47 56
@@ -263,6 +272,39 @@ static char *get_fw_name(char *buffer, size_t size, u8 device_type,
263 return buffer; 272 return buffer;
264} 273}
265 274
275static int handle_version_mismatch(struct usb_device *udev, u8 device_type,
276 const struct firmware *ub_fw)
277{
278 const struct firmware *ur_fw = NULL;
279 int offset;
280 int r = 0;
281 char fw_name[128];
282
283 r = request_fw_file(&ur_fw,
284 get_fw_name(fw_name, sizeof(fw_name), device_type, "ur"),
285 &udev->dev);
286 if (r)
287 goto error;
288
289 r = upload_code(udev, ur_fw->data, ur_fw->size, FW_START_OFFSET,
290 REBOOT);
291 if (r)
292 goto error;
293
294 offset = ((EEPROM_REGS_OFFSET + EEPROM_REGS_SIZE) * sizeof(u16));
295 r = upload_code(udev, ub_fw->data + offset, ub_fw->size - offset,
296 E2P_BASE_OFFSET + EEPROM_REGS_SIZE, REBOOT);
297
298 /* At this point, the vendor driver downloads the whole firmware
299 * image, hacks around with version IDs, and uploads it again,
300 * completely overwriting the boot code. We do not do this here as
301 * it is not required on any tested devices, and it is suspected to
302 * cause problems. */
303error:
304 release_firmware(ur_fw);
305 return r;
306}
307
266static int upload_firmware(struct usb_device *udev, u8 device_type) 308static int upload_firmware(struct usb_device *udev, u8 device_type)
267{ 309{
268 int r; 310 int r;
@@ -282,15 +324,17 @@ static int upload_firmware(struct usb_device *udev, u8 device_type)
282 324
283 fw_bcdDevice = get_word(ub_fw->data, EEPROM_REGS_OFFSET); 325 fw_bcdDevice = get_word(ub_fw->data, EEPROM_REGS_OFFSET);
284 326
285 /* FIXME: do we have any reason to perform the kludge that the vendor
286 * driver does when there is a version mismatch? (their driver uploads
287 * different firmwares and stuff)
288 */
289 if (fw_bcdDevice != bcdDevice) { 327 if (fw_bcdDevice != bcdDevice) {
290 dev_info(&udev->dev, 328 dev_info(&udev->dev,
291 "firmware device id %#06x and actual device id " 329 "firmware version %#06x and device bootcode version "
292 "%#06x differ, continuing anyway\n", 330 "%#06x differ\n", fw_bcdDevice, bcdDevice);
293 fw_bcdDevice, bcdDevice); 331 if (bcdDevice <= 0x4313)
332 dev_warn(&udev->dev, "device has old bootcode, please "
333 "report success or failure\n");
334
335 r = handle_version_mismatch(udev, device_type, ub_fw);
336 if (r)
337 goto error;
294 } else { 338 } else {
295 dev_dbg_f(&udev->dev, 339 dev_dbg_f(&udev->dev,
296 "firmware device id %#06x is equal to the " 340 "firmware device id %#06x is equal to the "
@@ -620,7 +664,7 @@ resubmit:
620 usb_submit_urb(urb, GFP_ATOMIC); 664 usb_submit_urb(urb, GFP_ATOMIC);
621} 665}
622 666
623struct urb *alloc_urb(struct zd_usb *usb) 667static struct urb *alloc_urb(struct zd_usb *usb)
624{ 668{
625 struct usb_device *udev = zd_usb_to_usbdev(usb); 669 struct usb_device *udev = zd_usb_to_usbdev(usb);
626 struct urb *urb; 670 struct urb *urb;
@@ -644,7 +688,7 @@ struct urb *alloc_urb(struct zd_usb *usb)
644 return urb; 688 return urb;
645} 689}
646 690
647void free_urb(struct urb *urb) 691static void free_urb(struct urb *urb)
648{ 692{
649 if (!urb) 693 if (!urb)
650 return; 694 return;
@@ -864,7 +908,7 @@ void zd_usb_clear(struct zd_usb *usb)
864{ 908{
865 usb_set_intfdata(usb->intf, NULL); 909 usb_set_intfdata(usb->intf, NULL);
866 usb_put_intf(usb->intf); 910 usb_put_intf(usb->intf);
867 memset(usb, 0, sizeof(*usb)); 911 ZD_MEMCLEAR(usb, sizeof(*usb));
868 /* FIXME: usb_interrupt, usb_tx, usb_rx? */ 912 /* FIXME: usb_interrupt, usb_tx, usb_rx? */
869} 913}
870 914
@@ -910,6 +954,55 @@ static void print_id(struct usb_device *udev)
910#define print_id(udev) do { } while (0) 954#define print_id(udev) do { } while (0)
911#endif 955#endif
912 956
957static int eject_installer(struct usb_interface *intf)
958{
959 struct usb_device *udev = interface_to_usbdev(intf);
960 struct usb_host_interface *iface_desc = &intf->altsetting[0];
961 struct usb_endpoint_descriptor *endpoint;
962 unsigned char *cmd;
963 u8 bulk_out_ep;
964 int r;
965
966 /* Find bulk out endpoint */
967 endpoint = &iface_desc->endpoint[1].desc;
968 if ((endpoint->bEndpointAddress & USB_TYPE_MASK) == USB_DIR_OUT &&
969 (endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
970 USB_ENDPOINT_XFER_BULK) {
971 bulk_out_ep = endpoint->bEndpointAddress;
972 } else {
973 dev_err(&udev->dev,
974 "zd1211rw: Could not find bulk out endpoint\n");
975 return -ENODEV;
976 }
977
978 cmd = kzalloc(31, GFP_KERNEL);
979 if (cmd == NULL)
980 return -ENODEV;
981
982 /* USB bulk command block */
983 cmd[0] = 0x55; /* bulk command signature */
984 cmd[1] = 0x53; /* bulk command signature */
985 cmd[2] = 0x42; /* bulk command signature */
986 cmd[3] = 0x43; /* bulk command signature */
987 cmd[14] = 6; /* command length */
988
989 cmd[15] = 0x1b; /* SCSI command: START STOP UNIT */
990 cmd[19] = 0x2; /* eject disc */
991
992 dev_info(&udev->dev, "Ejecting virtual installer media...\n");
993 r = usb_bulk_msg(udev, usb_sndbulkpipe(udev, bulk_out_ep),
994 cmd, 31, NULL, 2000);
995 kfree(cmd);
996 if (r)
997 return r;
998
999 /* At this point, the device disconnects and reconnects with the real
1000 * ID numbers. */
1001
1002 usb_set_intfdata(intf, NULL);
1003 return 0;
1004}
1005
913static int probe(struct usb_interface *intf, const struct usb_device_id *id) 1006static int probe(struct usb_interface *intf, const struct usb_device_id *id)
914{ 1007{
915 int r; 1008 int r;
@@ -918,6 +1011,9 @@ static int probe(struct usb_interface *intf, const struct usb_device_id *id)
918 1011
919 print_id(udev); 1012 print_id(udev);
920 1013
1014 if (id->driver_info & DEVICE_INSTALLER)
1015 return eject_installer(intf);
1016
921 switch (udev->speed) { 1017 switch (udev->speed) {
922 case USB_SPEED_LOW: 1018 case USB_SPEED_LOW:
923 case USB_SPEED_FULL: 1019 case USB_SPEED_FULL:
@@ -983,6 +1079,11 @@ static void disconnect(struct usb_interface *intf)
983 struct zd_mac *mac = zd_netdev_mac(netdev); 1079 struct zd_mac *mac = zd_netdev_mac(netdev);
984 struct zd_usb *usb = &mac->chip.usb; 1080 struct zd_usb *usb = &mac->chip.usb;
985 1081
1082 /* Either something really bad happened, or we're just dealing with
1083 * a DEVICE_INSTALLER. */
1084 if (netdev == NULL)
1085 return;
1086
986 dev_dbg_f(zd_usb_dev(usb), "\n"); 1087 dev_dbg_f(zd_usb_dev(usb), "\n");
987 1088
988 zd_netdev_disconnect(netdev); 1089 zd_netdev_disconnect(netdev);
@@ -998,7 +1099,6 @@ static void disconnect(struct usb_interface *intf)
998 */ 1099 */
999 usb_reset_device(interface_to_usbdev(intf)); 1100 usb_reset_device(interface_to_usbdev(intf));
1000 1101
1001 /* If somebody still waits on this lock now, this is an error. */
1002 zd_netdev_free(netdev); 1102 zd_netdev_free(netdev);
1003 dev_dbg(&intf->dev, "disconnected\n"); 1103 dev_dbg(&intf->dev, "disconnected\n");
1004} 1104}
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.h b/drivers/net/wireless/zd1211rw/zd_usb.h
index d6420283bd5a..92746f76239a 100644
--- a/drivers/net/wireless/zd1211rw/zd_usb.h
+++ b/drivers/net/wireless/zd1211rw/zd_usb.h
@@ -30,6 +30,7 @@
30enum devicetype { 30enum devicetype {
31 DEVICE_ZD1211 = 0, 31 DEVICE_ZD1211 = 0,
32 DEVICE_ZD1211B = 1, 32 DEVICE_ZD1211B = 1,
33 DEVICE_INSTALLER = 2,
33}; 34};
34 35
35enum endpoints { 36enum endpoints {
diff --git a/include/net/ieee80211.h b/include/net/ieee80211.h
index ecc42864b001..b174ebb277a9 100644
--- a/include/net/ieee80211.h
+++ b/include/net/ieee80211.h
@@ -240,6 +240,11 @@ struct ieee80211_snap_hdr {
240#define WLAN_CAPABILITY_SHORT_SLOT_TIME (1<<10) 240#define WLAN_CAPABILITY_SHORT_SLOT_TIME (1<<10)
241#define WLAN_CAPABILITY_DSSS_OFDM (1<<13) 241#define WLAN_CAPABILITY_DSSS_OFDM (1<<13)
242 242
243/* 802.11g ERP information element */
244#define WLAN_ERP_NON_ERP_PRESENT (1<<0)
245#define WLAN_ERP_USE_PROTECTION (1<<1)
246#define WLAN_ERP_BARKER_PREAMBLE (1<<2)
247
243/* Status codes */ 248/* Status codes */
244enum ieee80211_statuscode { 249enum ieee80211_statuscode {
245 WLAN_STATUS_SUCCESS = 0, 250 WLAN_STATUS_SUCCESS = 0,
@@ -747,6 +752,8 @@ struct ieee80211_txb {
747#define NETWORK_HAS_IBSS_DFS (1<<8) 752#define NETWORK_HAS_IBSS_DFS (1<<8)
748#define NETWORK_HAS_TPC_REPORT (1<<9) 753#define NETWORK_HAS_TPC_REPORT (1<<9)
749 754
755#define NETWORK_HAS_ERP_VALUE (1<<10)
756
750#define QOS_QUEUE_NUM 4 757#define QOS_QUEUE_NUM 4
751#define QOS_OUI_LEN 3 758#define QOS_OUI_LEN 3
752#define QOS_OUI_TYPE 2 759#define QOS_OUI_TYPE 2
@@ -1252,6 +1259,8 @@ extern int ieee80211_tx_frame(struct ieee80211_device *ieee,
1252 int total_len, int encrypt_mpdu); 1259 int total_len, int encrypt_mpdu);
1253 1260
1254/* ieee80211_rx.c */ 1261/* ieee80211_rx.c */
1262extern void ieee80211_rx_any(struct ieee80211_device *ieee,
1263 struct sk_buff *skb, struct ieee80211_rx_stats *stats);
1255extern int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, 1264extern int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
1256 struct ieee80211_rx_stats *rx_stats); 1265 struct ieee80211_rx_stats *rx_stats);
1257/* make sure to set stats->len */ 1266/* make sure to set stats->len */
diff --git a/include/net/ieee80211softmac.h b/include/net/ieee80211softmac.h
index 00ad810eb883..425b3a57ac74 100644
--- a/include/net/ieee80211softmac.h
+++ b/include/net/ieee80211softmac.h
@@ -86,9 +86,6 @@ struct ieee80211softmac_assoc_info {
86 86
87 /* BSSID we're trying to associate to */ 87 /* BSSID we're trying to associate to */
88 char bssid[ETH_ALEN]; 88 char bssid[ETH_ALEN];
89
90 /* Rates supported by the network */
91 struct ieee80211softmac_ratesinfo supported_rates;
92 89
93 /* some flags. 90 /* some flags.
94 * static_essid is valid if the essid is constant, 91 * static_essid is valid if the essid is constant,
@@ -103,6 +100,7 @@ struct ieee80211softmac_assoc_info {
103 * bssfixed is used for SIOCSIWAP. 100 * bssfixed is used for SIOCSIWAP.
104 */ 101 */
105 u8 static_essid:1, 102 u8 static_essid:1,
103 short_preamble_available:1,
106 associating:1, 104 associating:1,
107 assoc_wait:1, 105 assoc_wait:1,
108 bssvalid:1, 106 bssvalid:1,
@@ -115,6 +113,19 @@ struct ieee80211softmac_assoc_info {
115 struct work_struct timeout; 113 struct work_struct timeout;
116}; 114};
117 115
116struct ieee80211softmac_bss_info {
117 /* Rates supported by the network */
118 struct ieee80211softmac_ratesinfo supported_rates;
119
120 /* This indicates whether frames can currently be transmitted with
121 * short preamble (only use this variable during TX at CCK rates) */
122 u8 short_preamble:1;
123
124 /* This indicates whether protection (e.g. self-CTS) should be used
125 * when transmitting with OFDM modulation */
126 u8 use_protection:1;
127};
128
118enum { 129enum {
119 IEEE80211SOFTMAC_AUTH_OPEN_REQUEST = 1, 130 IEEE80211SOFTMAC_AUTH_OPEN_REQUEST = 1,
120 IEEE80211SOFTMAC_AUTH_OPEN_RESPONSE = 2, 131 IEEE80211SOFTMAC_AUTH_OPEN_RESPONSE = 2,
@@ -157,6 +168,10 @@ struct ieee80211softmac_txrates {
157#define IEEE80211SOFTMAC_TXRATECHG_MCAST (1 << 2) /* mcast_rate */ 168#define IEEE80211SOFTMAC_TXRATECHG_MCAST (1 << 2) /* mcast_rate */
158#define IEEE80211SOFTMAC_TXRATECHG_MGT_MCAST (1 << 3) /* mgt_mcast_rate */ 169#define IEEE80211SOFTMAC_TXRATECHG_MGT_MCAST (1 << 3) /* mgt_mcast_rate */
159 170
171#define IEEE80211SOFTMAC_BSSINFOCHG_RATES (1 << 0) /* supported_rates */
172#define IEEE80211SOFTMAC_BSSINFOCHG_SHORT_PREAMBLE (1 << 1) /* short_preamble */
173#define IEEE80211SOFTMAC_BSSINFOCHG_PROTECTION (1 << 2) /* use_protection */
174
160struct ieee80211softmac_device { 175struct ieee80211softmac_device {
161 /* 802.11 structure for data stuff */ 176 /* 802.11 structure for data stuff */
162 struct ieee80211_device *ieee; 177 struct ieee80211_device *ieee;
@@ -200,10 +215,16 @@ struct ieee80211softmac_device {
200 * The driver just needs to read them. 215 * The driver just needs to read them.
201 */ 216 */
202 struct ieee80211softmac_txrates txrates; 217 struct ieee80211softmac_txrates txrates;
203 /* If the driver needs to do stuff on TX rate changes, assign this callback. */ 218
219 /* If the driver needs to do stuff on TX rate changes, assign this
220 * callback. See IEEE80211SOFTMAC_TXRATECHG for change flags. */
204 void (*txrates_change)(struct net_device *dev, 221 void (*txrates_change)(struct net_device *dev,
205 u32 changes, /* see IEEE80211SOFTMAC_TXRATECHG flags */ 222 u32 changes);
206 const struct ieee80211softmac_txrates *rates_before_change); 223
224 /* If the driver needs to do stuff when BSS properties change, assign
225 * this callback. see IEEE80211SOFTMAC_BSSINFOCHG for change flags. */
226 void (*bssinfo_change)(struct net_device *dev,
227 u32 changes);
207 228
208 /* private stuff follows */ 229 /* private stuff follows */
209 /* this lock protects this structure */ 230 /* this lock protects this structure */
@@ -216,6 +237,7 @@ struct ieee80211softmac_device {
216 237
217 struct ieee80211softmac_scaninfo *scaninfo; 238 struct ieee80211softmac_scaninfo *scaninfo;
218 struct ieee80211softmac_assoc_info associnfo; 239 struct ieee80211softmac_assoc_info associnfo;
240 struct ieee80211softmac_bss_info bssinfo;
219 241
220 struct list_head auth_queue; 242 struct list_head auth_queue;
221 struct list_head events; 243 struct list_head events;
@@ -257,6 +279,14 @@ extern void ieee80211softmac_fragment_lost(struct net_device *dev,
257 * Note that the rates need to be sorted. */ 279 * Note that the rates need to be sorted. */
258extern void ieee80211softmac_set_rates(struct net_device *dev, u8 count, u8 *rates); 280extern void ieee80211softmac_set_rates(struct net_device *dev, u8 count, u8 *rates);
259 281
282/* Finds the highest rate which is:
283 * 1. Present in ri (optionally a basic rate)
284 * 2. Supported by the device
285 * 3. Less than or equal to the user-defined rate
286 */
287extern u8 ieee80211softmac_highest_supported_rate(struct ieee80211softmac_device *mac,
288 struct ieee80211softmac_ratesinfo *ri, int basic_only);
289
260/* Helper function which advises you the rate at which a frame should be 290/* Helper function which advises you the rate at which a frame should be
261 * transmitted at. */ 291 * transmitted at. */
262static inline u8 ieee80211softmac_suggest_txrate(struct ieee80211softmac_device *mac, 292static inline u8 ieee80211softmac_suggest_txrate(struct ieee80211softmac_device *mac,
@@ -279,6 +309,24 @@ static inline u8 ieee80211softmac_suggest_txrate(struct ieee80211softmac_device
279 return txrates->mcast_rate; 309 return txrates->mcast_rate;
280} 310}
281 311
312/* Helper function which advises you when it is safe to transmit with short
313 * preamble.
314 * You should only call this function when transmitting at CCK rates. */
315static inline int ieee80211softmac_short_preamble_ok(struct ieee80211softmac_device *mac,
316 int is_multicast,
317 int is_mgt)
318{
319 return (is_multicast && is_mgt) ? 0 : mac->bssinfo.short_preamble;
320}
321
322/* Helper function which advises you whether protection (e.g. self-CTS) is
323 * needed. 1 = protection needed, 0 = no protection needed
324 * Only use this function when transmitting with OFDM modulation. */
325static inline int ieee80211softmac_protection_needed(struct ieee80211softmac_device *mac)
326{
327 return mac->bssinfo.use_protection;
328}
329
282/* Start the SoftMAC. Call this after you initialized the device 330/* Start the SoftMAC. Call this after you initialized the device
283 * and it is ready to run. 331 * and it is ready to run.
284 */ 332 */
diff --git a/net/ieee80211/ieee80211_crypt_ccmp.c b/net/ieee80211/ieee80211_crypt_ccmp.c
index ed90a8af1444..098c66846339 100644
--- a/net/ieee80211/ieee80211_crypt_ccmp.c
+++ b/net/ieee80211/ieee80211_crypt_ccmp.c
@@ -271,6 +271,27 @@ static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
271 return 0; 271 return 0;
272} 272}
273 273
274/*
275 * deal with seq counter wrapping correctly.
276 * refer to timer_after() for jiffies wrapping handling
277 */
278static inline int ccmp_replay_check(u8 *pn_n, u8 *pn_o)
279{
280 u32 iv32_n, iv16_n;
281 u32 iv32_o, iv16_o;
282
283 iv32_n = (pn_n[0] << 24) | (pn_n[1] << 16) | (pn_n[2] << 8) | pn_n[3];
284 iv16_n = (pn_n[4] << 8) | pn_n[5];
285
286 iv32_o = (pn_o[0] << 24) | (pn_o[1] << 16) | (pn_o[2] << 8) | pn_o[3];
287 iv16_o = (pn_o[4] << 8) | pn_o[5];
288
289 if ((s32)iv32_n - (s32)iv32_o < 0 ||
290 (iv32_n == iv32_o && iv16_n <= iv16_o))
291 return 1;
292 return 0;
293}
294
274static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv) 295static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
275{ 296{
276 struct ieee80211_ccmp_data *key = priv; 297 struct ieee80211_ccmp_data *key = priv;
@@ -323,7 +344,7 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
323 pn[5] = pos[0]; 344 pn[5] = pos[0];
324 pos += 8; 345 pos += 8;
325 346
326 if (memcmp(pn, key->rx_pn, CCMP_PN_LEN) <= 0) { 347 if (ccmp_replay_check(pn, key->rx_pn)) {
327 if (net_ratelimit()) { 348 if (net_ratelimit()) {
328 printk(KERN_DEBUG "CCMP: replay detected: STA=" MAC_FMT 349 printk(KERN_DEBUG "CCMP: replay detected: STA=" MAC_FMT
329 " previous PN %02x%02x%02x%02x%02x%02x " 350 " previous PN %02x%02x%02x%02x%02x%02x "
diff --git a/net/ieee80211/ieee80211_crypt_tkip.c b/net/ieee80211/ieee80211_crypt_tkip.c
index 34dba0ba545d..f2df2f5b3e4c 100644
--- a/net/ieee80211/ieee80211_crypt_tkip.c
+++ b/net/ieee80211/ieee80211_crypt_tkip.c
@@ -52,8 +52,10 @@ struct ieee80211_tkip_data {
52 52
53 int key_idx; 53 int key_idx;
54 54
55 struct crypto_tfm *tfm_arc4; 55 struct crypto_tfm *tx_tfm_arc4;
56 struct crypto_tfm *tfm_michael; 56 struct crypto_tfm *tx_tfm_michael;
57 struct crypto_tfm *rx_tfm_arc4;
58 struct crypto_tfm *rx_tfm_michael;
57 59
58 /* scratch buffers for virt_to_page() (crypto API) */ 60 /* scratch buffers for virt_to_page() (crypto API) */
59 u8 rx_hdr[16], tx_hdr[16]; 61 u8 rx_hdr[16], tx_hdr[16];
@@ -85,15 +87,29 @@ static void *ieee80211_tkip_init(int key_idx)
85 87
86 priv->key_idx = key_idx; 88 priv->key_idx = key_idx;
87 89
88 priv->tfm_arc4 = crypto_alloc_tfm("arc4", 0); 90 priv->tx_tfm_arc4 = crypto_alloc_tfm("arc4", 0);
89 if (priv->tfm_arc4 == NULL) { 91 if (priv->tx_tfm_arc4 == NULL) {
90 printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate " 92 printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
91 "crypto API arc4\n"); 93 "crypto API arc4\n");
92 goto fail; 94 goto fail;
93 } 95 }
94 96
95 priv->tfm_michael = crypto_alloc_tfm("michael_mic", 0); 97 priv->tx_tfm_michael = crypto_alloc_tfm("michael_mic", 0);
96 if (priv->tfm_michael == NULL) { 98 if (priv->tx_tfm_michael == NULL) {
99 printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
100 "crypto API michael_mic\n");
101 goto fail;
102 }
103
104 priv->rx_tfm_arc4 = crypto_alloc_tfm("arc4", 0);
105 if (priv->rx_tfm_arc4 == NULL) {
106 printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
107 "crypto API arc4\n");
108 goto fail;
109 }
110
111 priv->rx_tfm_michael = crypto_alloc_tfm("michael_mic", 0);
112 if (priv->rx_tfm_michael == NULL) {
97 printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate " 113 printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
98 "crypto API michael_mic\n"); 114 "crypto API michael_mic\n");
99 goto fail; 115 goto fail;
@@ -103,10 +119,14 @@ static void *ieee80211_tkip_init(int key_idx)
103 119
104 fail: 120 fail:
105 if (priv) { 121 if (priv) {
106 if (priv->tfm_michael) 122 if (priv->tx_tfm_michael)
107 crypto_free_tfm(priv->tfm_michael); 123 crypto_free_tfm(priv->tx_tfm_michael);
108 if (priv->tfm_arc4) 124 if (priv->tx_tfm_arc4)
109 crypto_free_tfm(priv->tfm_arc4); 125 crypto_free_tfm(priv->tx_tfm_arc4);
126 if (priv->rx_tfm_michael)
127 crypto_free_tfm(priv->rx_tfm_michael);
128 if (priv->rx_tfm_arc4)
129 crypto_free_tfm(priv->rx_tfm_arc4);
110 kfree(priv); 130 kfree(priv);
111 } 131 }
112 132
@@ -116,10 +136,16 @@ static void *ieee80211_tkip_init(int key_idx)
116static void ieee80211_tkip_deinit(void *priv) 136static void ieee80211_tkip_deinit(void *priv)
117{ 137{
118 struct ieee80211_tkip_data *_priv = priv; 138 struct ieee80211_tkip_data *_priv = priv;
119 if (_priv && _priv->tfm_michael) 139 if (_priv) {
120 crypto_free_tfm(_priv->tfm_michael); 140 if (_priv->tx_tfm_michael)
121 if (_priv && _priv->tfm_arc4) 141 crypto_free_tfm(_priv->tx_tfm_michael);
122 crypto_free_tfm(_priv->tfm_arc4); 142 if (_priv->tx_tfm_arc4)
143 crypto_free_tfm(_priv->tx_tfm_arc4);
144 if (_priv->rx_tfm_michael)
145 crypto_free_tfm(_priv->rx_tfm_michael);
146 if (_priv->rx_tfm_arc4)
147 crypto_free_tfm(_priv->rx_tfm_arc4);
148 }
123 kfree(priv); 149 kfree(priv);
124} 150}
125 151
@@ -351,12 +377,25 @@ static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
351 icv[2] = crc >> 16; 377 icv[2] = crc >> 16;
352 icv[3] = crc >> 24; 378 icv[3] = crc >> 24;
353 379
354 crypto_cipher_setkey(tkey->tfm_arc4, rc4key, 16); 380 crypto_cipher_setkey(tkey->tx_tfm_arc4, rc4key, 16);
355 sg.page = virt_to_page(pos); 381 sg.page = virt_to_page(pos);
356 sg.offset = offset_in_page(pos); 382 sg.offset = offset_in_page(pos);
357 sg.length = len + 4; 383 sg.length = len + 4;
358 crypto_cipher_encrypt(tkey->tfm_arc4, &sg, &sg, len + 4); 384 crypto_cipher_encrypt(tkey->tx_tfm_arc4, &sg, &sg, len + 4);
385
386 return 0;
387}
359 388
389/*
390 * deal with seq counter wrapping correctly.
391 * refer to timer_after() for jiffies wrapping handling
392 */
393static inline int tkip_replay_check(u32 iv32_n, u16 iv16_n,
394 u32 iv32_o, u16 iv16_o)
395{
396 if ((s32)iv32_n - (s32)iv32_o < 0 ||
397 (iv32_n == iv32_o && iv16_n <= iv16_o))
398 return 1;
360 return 0; 399 return 0;
361} 400}
362 401
@@ -414,8 +453,7 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
414 iv32 = pos[4] | (pos[5] << 8) | (pos[6] << 16) | (pos[7] << 24); 453 iv32 = pos[4] | (pos[5] << 8) | (pos[6] << 16) | (pos[7] << 24);
415 pos += 8; 454 pos += 8;
416 455
417 if (iv32 < tkey->rx_iv32 || 456 if (tkip_replay_check(iv32, iv16, tkey->rx_iv32, tkey->rx_iv16)) {
418 (iv32 == tkey->rx_iv32 && iv16 <= tkey->rx_iv16)) {
419 if (net_ratelimit()) { 457 if (net_ratelimit()) {
420 printk(KERN_DEBUG "TKIP: replay detected: STA=" MAC_FMT 458 printk(KERN_DEBUG "TKIP: replay detected: STA=" MAC_FMT
421 " previous TSC %08x%04x received TSC " 459 " previous TSC %08x%04x received TSC "
@@ -434,11 +472,11 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
434 472
435 plen = skb->len - hdr_len - 12; 473 plen = skb->len - hdr_len - 12;
436 474
437 crypto_cipher_setkey(tkey->tfm_arc4, rc4key, 16); 475 crypto_cipher_setkey(tkey->rx_tfm_arc4, rc4key, 16);
438 sg.page = virt_to_page(pos); 476 sg.page = virt_to_page(pos);
439 sg.offset = offset_in_page(pos); 477 sg.offset = offset_in_page(pos);
440 sg.length = plen + 4; 478 sg.length = plen + 4;
441 crypto_cipher_decrypt(tkey->tfm_arc4, &sg, &sg, plen + 4); 479 crypto_cipher_decrypt(tkey->rx_tfm_arc4, &sg, &sg, plen + 4);
442 480
443 crc = ~crc32_le(~0, pos, plen); 481 crc = ~crc32_le(~0, pos, plen);
444 icv[0] = crc; 482 icv[0] = crc;
@@ -472,12 +510,12 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
472 return keyidx; 510 return keyidx;
473} 511}
474 512
475static int michael_mic(struct ieee80211_tkip_data *tkey, u8 * key, u8 * hdr, 513static int michael_mic(struct crypto_tfm *tfm_michael, u8 * key, u8 * hdr,
476 u8 * data, size_t data_len, u8 * mic) 514 u8 * data, size_t data_len, u8 * mic)
477{ 515{
478 struct scatterlist sg[2]; 516 struct scatterlist sg[2];
479 517
480 if (tkey->tfm_michael == NULL) { 518 if (tfm_michael == NULL) {
481 printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n"); 519 printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n");
482 return -1; 520 return -1;
483 } 521 }
@@ -489,10 +527,10 @@ static int michael_mic(struct ieee80211_tkip_data *tkey, u8 * key, u8 * hdr,
489 sg[1].offset = offset_in_page(data); 527 sg[1].offset = offset_in_page(data);
490 sg[1].length = data_len; 528 sg[1].length = data_len;
491 529
492 crypto_digest_init(tkey->tfm_michael); 530 crypto_digest_init(tfm_michael);
493 crypto_digest_setkey(tkey->tfm_michael, key, 8); 531 crypto_digest_setkey(tfm_michael, key, 8);
494 crypto_digest_update(tkey->tfm_michael, sg, 2); 532 crypto_digest_update(tfm_michael, sg, 2);
495 crypto_digest_final(tkey->tfm_michael, mic); 533 crypto_digest_final(tfm_michael, mic);
496 534
497 return 0; 535 return 0;
498} 536}
@@ -528,7 +566,7 @@ static void michael_mic_hdr(struct sk_buff *skb, u8 * hdr)
528 if (stype & IEEE80211_STYPE_QOS_DATA) { 566 if (stype & IEEE80211_STYPE_QOS_DATA) {
529 const struct ieee80211_hdr_3addrqos *qoshdr = 567 const struct ieee80211_hdr_3addrqos *qoshdr =
530 (struct ieee80211_hdr_3addrqos *)skb->data; 568 (struct ieee80211_hdr_3addrqos *)skb->data;
531 hdr[12] = le16_to_cpu(qoshdr->qos_ctl) & IEEE80211_QCTL_TID; 569 hdr[12] = qoshdr->qos_ctl & cpu_to_le16(IEEE80211_QCTL_TID);
532 } else 570 } else
533 hdr[12] = 0; /* priority */ 571 hdr[12] = 0; /* priority */
534 572
@@ -550,7 +588,7 @@ static int ieee80211_michael_mic_add(struct sk_buff *skb, int hdr_len,
550 588
551 michael_mic_hdr(skb, tkey->tx_hdr); 589 michael_mic_hdr(skb, tkey->tx_hdr);
552 pos = skb_put(skb, 8); 590 pos = skb_put(skb, 8);
553 if (michael_mic(tkey, &tkey->key[16], tkey->tx_hdr, 591 if (michael_mic(tkey->tx_tfm_michael, &tkey->key[16], tkey->tx_hdr,
554 skb->data + hdr_len, skb->len - 8 - hdr_len, pos)) 592 skb->data + hdr_len, skb->len - 8 - hdr_len, pos))
555 return -1; 593 return -1;
556 594
@@ -588,7 +626,7 @@ static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
588 return -1; 626 return -1;
589 627
590 michael_mic_hdr(skb, tkey->rx_hdr); 628 michael_mic_hdr(skb, tkey->rx_hdr);
591 if (michael_mic(tkey, &tkey->key[24], tkey->rx_hdr, 629 if (michael_mic(tkey->rx_tfm_michael, &tkey->key[24], tkey->rx_hdr,
592 skb->data + hdr_len, skb->len - 8 - hdr_len, mic)) 630 skb->data + hdr_len, skb->len - 8 - hdr_len, mic))
593 return -1; 631 return -1;
594 if (memcmp(mic, skb->data + skb->len - 8, 8) != 0) { 632 if (memcmp(mic, skb->data + skb->len - 8, 8) != 0) {
@@ -618,14 +656,18 @@ static int ieee80211_tkip_set_key(void *key, int len, u8 * seq, void *priv)
618{ 656{
619 struct ieee80211_tkip_data *tkey = priv; 657 struct ieee80211_tkip_data *tkey = priv;
620 int keyidx; 658 int keyidx;
621 struct crypto_tfm *tfm = tkey->tfm_michael; 659 struct crypto_tfm *tfm = tkey->tx_tfm_michael;
622 struct crypto_tfm *tfm2 = tkey->tfm_arc4; 660 struct crypto_tfm *tfm2 = tkey->tx_tfm_arc4;
661 struct crypto_tfm *tfm3 = tkey->rx_tfm_michael;
662 struct crypto_tfm *tfm4 = tkey->rx_tfm_arc4;
623 663
624 keyidx = tkey->key_idx; 664 keyidx = tkey->key_idx;
625 memset(tkey, 0, sizeof(*tkey)); 665 memset(tkey, 0, sizeof(*tkey));
626 tkey->key_idx = keyidx; 666 tkey->key_idx = keyidx;
627 tkey->tfm_michael = tfm; 667 tkey->tx_tfm_michael = tfm;
628 tkey->tfm_arc4 = tfm2; 668 tkey->tx_tfm_arc4 = tfm2;
669 tkey->rx_tfm_michael = tfm3;
670 tkey->rx_tfm_arc4 = tfm4;
629 if (len == TKIP_KEY_LEN) { 671 if (len == TKIP_KEY_LEN) {
630 memcpy(tkey->key, key, TKIP_KEY_LEN); 672 memcpy(tkey->key, key, TKIP_KEY_LEN);
631 tkey->key_set = 1; 673 tkey->key_set = 1;
diff --git a/net/ieee80211/ieee80211_crypt_wep.c b/net/ieee80211/ieee80211_crypt_wep.c
index 0ebf235f6939..b435b28857ed 100644
--- a/net/ieee80211/ieee80211_crypt_wep.c
+++ b/net/ieee80211/ieee80211_crypt_wep.c
@@ -32,7 +32,8 @@ struct prism2_wep_data {
32 u8 key[WEP_KEY_LEN + 1]; 32 u8 key[WEP_KEY_LEN + 1];
33 u8 key_len; 33 u8 key_len;
34 u8 key_idx; 34 u8 key_idx;
35 struct crypto_tfm *tfm; 35 struct crypto_tfm *tx_tfm;
36 struct crypto_tfm *rx_tfm;
36}; 37};
37 38
38static void *prism2_wep_init(int keyidx) 39static void *prism2_wep_init(int keyidx)
@@ -44,13 +45,19 @@ static void *prism2_wep_init(int keyidx)
44 goto fail; 45 goto fail;
45 priv->key_idx = keyidx; 46 priv->key_idx = keyidx;
46 47
47 priv->tfm = crypto_alloc_tfm("arc4", 0); 48 priv->tx_tfm = crypto_alloc_tfm("arc4", 0);
48 if (priv->tfm == NULL) { 49 if (priv->tx_tfm == NULL) {
49 printk(KERN_DEBUG "ieee80211_crypt_wep: could not allocate " 50 printk(KERN_DEBUG "ieee80211_crypt_wep: could not allocate "
50 "crypto API arc4\n"); 51 "crypto API arc4\n");
51 goto fail; 52 goto fail;
52 } 53 }
53 54
55 priv->rx_tfm = crypto_alloc_tfm("arc4", 0);
56 if (priv->rx_tfm == NULL) {
57 printk(KERN_DEBUG "ieee80211_crypt_wep: could not allocate "
58 "crypto API arc4\n");
59 goto fail;
60 }
54 /* start WEP IV from a random value */ 61 /* start WEP IV from a random value */
55 get_random_bytes(&priv->iv, 4); 62 get_random_bytes(&priv->iv, 4);
56 63
@@ -58,8 +65,10 @@ static void *prism2_wep_init(int keyidx)
58 65
59 fail: 66 fail:
60 if (priv) { 67 if (priv) {
61 if (priv->tfm) 68 if (priv->tx_tfm)
62 crypto_free_tfm(priv->tfm); 69 crypto_free_tfm(priv->tx_tfm);
70 if (priv->rx_tfm)
71 crypto_free_tfm(priv->rx_tfm);
63 kfree(priv); 72 kfree(priv);
64 } 73 }
65 return NULL; 74 return NULL;
@@ -68,8 +77,12 @@ static void *prism2_wep_init(int keyidx)
68static void prism2_wep_deinit(void *priv) 77static void prism2_wep_deinit(void *priv)
69{ 78{
70 struct prism2_wep_data *_priv = priv; 79 struct prism2_wep_data *_priv = priv;
71 if (_priv && _priv->tfm) 80 if (_priv) {
72 crypto_free_tfm(_priv->tfm); 81 if (_priv->tx_tfm)
82 crypto_free_tfm(_priv->tx_tfm);
83 if (_priv->rx_tfm)
84 crypto_free_tfm(_priv->rx_tfm);
85 }
73 kfree(priv); 86 kfree(priv);
74} 87}
75 88
@@ -151,11 +164,11 @@ static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
151 icv[2] = crc >> 16; 164 icv[2] = crc >> 16;
152 icv[3] = crc >> 24; 165 icv[3] = crc >> 24;
153 166
154 crypto_cipher_setkey(wep->tfm, key, klen); 167 crypto_cipher_setkey(wep->tx_tfm, key, klen);
155 sg.page = virt_to_page(pos); 168 sg.page = virt_to_page(pos);
156 sg.offset = offset_in_page(pos); 169 sg.offset = offset_in_page(pos);
157 sg.length = len + 4; 170 sg.length = len + 4;
158 crypto_cipher_encrypt(wep->tfm, &sg, &sg, len + 4); 171 crypto_cipher_encrypt(wep->tx_tfm, &sg, &sg, len + 4);
159 172
160 return 0; 173 return 0;
161} 174}
@@ -194,11 +207,11 @@ static int prism2_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
194 /* Apply RC4 to data and compute CRC32 over decrypted data */ 207 /* Apply RC4 to data and compute CRC32 over decrypted data */
195 plen = skb->len - hdr_len - 8; 208 plen = skb->len - hdr_len - 8;
196 209
197 crypto_cipher_setkey(wep->tfm, key, klen); 210 crypto_cipher_setkey(wep->rx_tfm, key, klen);
198 sg.page = virt_to_page(pos); 211 sg.page = virt_to_page(pos);
199 sg.offset = offset_in_page(pos); 212 sg.offset = offset_in_page(pos);
200 sg.length = plen + 4; 213 sg.length = plen + 4;
201 crypto_cipher_decrypt(wep->tfm, &sg, &sg, plen + 4); 214 crypto_cipher_decrypt(wep->rx_tfm, &sg, &sg, plen + 4);
202 215
203 crc = ~crc32_le(~0, pos, plen); 216 crc = ~crc32_le(~0, pos, plen);
204 icv[0] = crc; 217 icv[0] = crc;
diff --git a/net/ieee80211/ieee80211_rx.c b/net/ieee80211/ieee80211_rx.c
index 72d4d4e04d42..770704183a1b 100644
--- a/net/ieee80211/ieee80211_rx.c
+++ b/net/ieee80211/ieee80211_rx.c
@@ -779,33 +779,44 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
779 return 0; 779 return 0;
780} 780}
781 781
782/* Filter out unrelated packets, call ieee80211_rx[_mgt] */ 782/* Filter out unrelated packets, call ieee80211_rx[_mgt]
783int ieee80211_rx_any(struct ieee80211_device *ieee, 783 * This function takes over the skb, it should not be used again after calling
784 * this function. */
785void ieee80211_rx_any(struct ieee80211_device *ieee,
784 struct sk_buff *skb, struct ieee80211_rx_stats *stats) 786 struct sk_buff *skb, struct ieee80211_rx_stats *stats)
785{ 787{
786 struct ieee80211_hdr_4addr *hdr; 788 struct ieee80211_hdr_4addr *hdr;
787 int is_packet_for_us; 789 int is_packet_for_us;
788 u16 fc; 790 u16 fc;
789 791
790 if (ieee->iw_mode == IW_MODE_MONITOR) 792 if (ieee->iw_mode == IW_MODE_MONITOR) {
791 return ieee80211_rx(ieee, skb, stats) ? 0 : -EINVAL; 793 if (!ieee80211_rx(ieee, skb, stats))
794 dev_kfree_skb_irq(skb);
795 return;
796 }
797
798 if (skb->len < sizeof(struct ieee80211_hdr))
799 goto drop_free;
792 800
793 hdr = (struct ieee80211_hdr_4addr *)skb->data; 801 hdr = (struct ieee80211_hdr_4addr *)skb->data;
794 fc = le16_to_cpu(hdr->frame_ctl); 802 fc = le16_to_cpu(hdr->frame_ctl);
795 803
796 if ((fc & IEEE80211_FCTL_VERS) != 0) 804 if ((fc & IEEE80211_FCTL_VERS) != 0)
797 return -EINVAL; 805 goto drop_free;
798 806
799 switch (fc & IEEE80211_FCTL_FTYPE) { 807 switch (fc & IEEE80211_FCTL_FTYPE) {
800 case IEEE80211_FTYPE_MGMT: 808 case IEEE80211_FTYPE_MGMT:
809 if (skb->len < sizeof(struct ieee80211_hdr_3addr))
810 goto drop_free;
801 ieee80211_rx_mgt(ieee, hdr, stats); 811 ieee80211_rx_mgt(ieee, hdr, stats);
802 return 0; 812 dev_kfree_skb_irq(skb);
813 return;
803 case IEEE80211_FTYPE_DATA: 814 case IEEE80211_FTYPE_DATA:
804 break; 815 break;
805 case IEEE80211_FTYPE_CTL: 816 case IEEE80211_FTYPE_CTL:
806 return 0; 817 return;
807 default: 818 default:
808 return -EINVAL; 819 return;
809 } 820 }
810 821
811 is_packet_for_us = 0; 822 is_packet_for_us = 0;
@@ -849,8 +860,14 @@ int ieee80211_rx_any(struct ieee80211_device *ieee,
849 } 860 }
850 861
851 if (is_packet_for_us) 862 if (is_packet_for_us)
852 return (ieee80211_rx(ieee, skb, stats) ? 0 : -EINVAL); 863 if (!ieee80211_rx(ieee, skb, stats))
853 return 0; 864 dev_kfree_skb_irq(skb);
865 return;
866
867drop_free:
868 dev_kfree_skb_irq(skb);
869 ieee->stats.rx_dropped++;
870 return;
854} 871}
855 872
856#define MGMT_FRAME_FIXED_PART_LENGTH 0x24 873#define MGMT_FRAME_FIXED_PART_LENGTH 0x24
@@ -1061,13 +1078,16 @@ static int ieee80211_parse_info_param(struct ieee80211_info_element
1061 1078
1062 while (length >= sizeof(*info_element)) { 1079 while (length >= sizeof(*info_element)) {
1063 if (sizeof(*info_element) + info_element->len > length) { 1080 if (sizeof(*info_element) + info_element->len > length) {
1064 IEEE80211_DEBUG_MGMT("Info elem: parse failed: " 1081 IEEE80211_ERROR("Info elem: parse failed: "
1065 "info_element->len + 2 > left : " 1082 "info_element->len + 2 > left : "
1066 "info_element->len+2=%zd left=%d, id=%d.\n", 1083 "info_element->len+2=%zd left=%d, id=%d.\n",
1067 info_element->len + 1084 info_element->len +
1068 sizeof(*info_element), 1085 sizeof(*info_element),
1069 length, info_element->id); 1086 length, info_element->id);
1070 return 1; 1087 /* We stop processing but don't return an error here
1088 * because some misbehaviour APs break this rule. ie.
1089 * Orinoco AP1000. */
1090 break;
1071 } 1091 }
1072 1092
1073 switch (info_element->id) { 1093 switch (info_element->id) {
@@ -1166,6 +1186,7 @@ static int ieee80211_parse_info_param(struct ieee80211_info_element
1166 1186
1167 case MFIE_TYPE_ERP_INFO: 1187 case MFIE_TYPE_ERP_INFO:
1168 network->erp_value = info_element->data[0]; 1188 network->erp_value = info_element->data[0];
1189 network->flags |= NETWORK_HAS_ERP_VALUE;
1169 IEEE80211_DEBUG_MGMT("MFIE_TYPE_ERP_SET: %d\n", 1190 IEEE80211_DEBUG_MGMT("MFIE_TYPE_ERP_SET: %d\n",
1170 network->erp_value); 1191 network->erp_value);
1171 break; 1192 break;
@@ -1729,5 +1750,6 @@ void ieee80211_rx_mgt(struct ieee80211_device *ieee,
1729 } 1750 }
1730} 1751}
1731 1752
1753EXPORT_SYMBOL_GPL(ieee80211_rx_any);
1732EXPORT_SYMBOL(ieee80211_rx_mgt); 1754EXPORT_SYMBOL(ieee80211_rx_mgt);
1733EXPORT_SYMBOL(ieee80211_rx); 1755EXPORT_SYMBOL(ieee80211_rx);
diff --git a/net/ieee80211/ieee80211_tx.c b/net/ieee80211/ieee80211_tx.c
index bf042139c7ab..ae254497ba3d 100644
--- a/net/ieee80211/ieee80211_tx.c
+++ b/net/ieee80211/ieee80211_tx.c
@@ -337,7 +337,7 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
337 hdr_len += 2; 337 hdr_len += 2;
338 338
339 skb->priority = ieee80211_classify(skb); 339 skb->priority = ieee80211_classify(skb);
340 header.qos_ctl |= skb->priority & IEEE80211_QCTL_TID; 340 header.qos_ctl |= cpu_to_le16(skb->priority & IEEE80211_QCTL_TID);
341 } 341 }
342 header.frame_ctl = cpu_to_le16(fc); 342 header.frame_ctl = cpu_to_le16(fc);
343 343
@@ -532,13 +532,6 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
532 return 0; 532 return 0;
533 } 533 }
534 534
535 if (ret == NETDEV_TX_BUSY) {
536 printk(KERN_ERR "%s: NETDEV_TX_BUSY returned; "
537 "driver should report queue full via "
538 "ieee_device->is_queue_full.\n",
539 ieee->dev->name);
540 }
541
542 ieee80211_txb_free(txb); 535 ieee80211_txb_free(txb);
543 } 536 }
544 537
diff --git a/net/ieee80211/softmac/ieee80211softmac_assoc.c b/net/ieee80211/softmac/ieee80211softmac_assoc.c
index 44215ce64d4e..589f6d2c548a 100644
--- a/net/ieee80211/softmac/ieee80211softmac_assoc.c
+++ b/net/ieee80211/softmac/ieee80211softmac_assoc.c
@@ -96,7 +96,7 @@ ieee80211softmac_disassoc(struct ieee80211softmac_device *mac)
96 mac->associated = 0; 96 mac->associated = 0;
97 mac->associnfo.bssvalid = 0; 97 mac->associnfo.bssvalid = 0;
98 mac->associnfo.associating = 0; 98 mac->associnfo.associating = 0;
99 ieee80211softmac_init_txrates(mac); 99 ieee80211softmac_init_bss(mac);
100 ieee80211softmac_call_events_locked(mac, IEEE80211SOFTMAC_EVENT_DISASSOCIATED, NULL); 100 ieee80211softmac_call_events_locked(mac, IEEE80211SOFTMAC_EVENT_DISASSOCIATED, NULL);
101 spin_unlock_irqrestore(&mac->lock, flags); 101 spin_unlock_irqrestore(&mac->lock, flags);
102} 102}
@@ -334,11 +334,19 @@ ieee80211softmac_associated(struct ieee80211softmac_device *mac,
334 struct ieee80211_assoc_response * resp, 334 struct ieee80211_assoc_response * resp,
335 struct ieee80211softmac_network *net) 335 struct ieee80211softmac_network *net)
336{ 336{
337 u16 cap = le16_to_cpu(resp->capability);
338 u8 erp_value = net->erp_value;
339
337 mac->associnfo.associating = 0; 340 mac->associnfo.associating = 0;
338 mac->associnfo.supported_rates = net->supported_rates; 341 mac->bssinfo.supported_rates = net->supported_rates;
339 ieee80211softmac_recalc_txrates(mac); 342 ieee80211softmac_recalc_txrates(mac);
340 343
341 mac->associated = 1; 344 mac->associated = 1;
345
346 mac->associnfo.short_preamble_available =
347 (cap & WLAN_CAPABILITY_SHORT_PREAMBLE) != 0;
348 ieee80211softmac_process_erp(mac, erp_value);
349
342 if (mac->set_bssid_filter) 350 if (mac->set_bssid_filter)
343 mac->set_bssid_filter(mac->dev, net->bssid); 351 mac->set_bssid_filter(mac->dev, net->bssid);
344 memcpy(mac->ieee->bssid, net->bssid, ETH_ALEN); 352 memcpy(mac->ieee->bssid, net->bssid, ETH_ALEN);
@@ -351,9 +359,9 @@ ieee80211softmac_associated(struct ieee80211softmac_device *mac,
351int 359int
352ieee80211softmac_handle_assoc_response(struct net_device * dev, 360ieee80211softmac_handle_assoc_response(struct net_device * dev,
353 struct ieee80211_assoc_response * resp, 361 struct ieee80211_assoc_response * resp,
354 struct ieee80211_network * _ieee80211_network_do_not_use) 362 struct ieee80211_network * _ieee80211_network)
355{ 363{
356 /* NOTE: the network parameter has to be ignored by 364 /* NOTE: the network parameter has to be mostly ignored by
357 * this code because it is the ieee80211's pointer 365 * this code because it is the ieee80211's pointer
358 * to the struct, not ours (we made a copy) 366 * to the struct, not ours (we made a copy)
359 */ 367 */
@@ -385,6 +393,11 @@ ieee80211softmac_handle_assoc_response(struct net_device * dev,
385 /* now that we know it was for us, we can cancel the timeout */ 393 /* now that we know it was for us, we can cancel the timeout */
386 cancel_delayed_work(&mac->associnfo.timeout); 394 cancel_delayed_work(&mac->associnfo.timeout);
387 395
396 /* if the association response included an ERP IE, update our saved
397 * copy */
398 if (_ieee80211_network->flags & NETWORK_HAS_ERP_VALUE)
399 network->erp_value = _ieee80211_network->erp_value;
400
388 switch (status) { 401 switch (status) {
389 case 0: 402 case 0:
390 dprintk(KERN_INFO PFX "associated!\n"); 403 dprintk(KERN_INFO PFX "associated!\n");
diff --git a/net/ieee80211/softmac/ieee80211softmac_io.c b/net/ieee80211/softmac/ieee80211softmac_io.c
index 6ae5a1dc7956..82bfddbf33a2 100644
--- a/net/ieee80211/softmac/ieee80211softmac_io.c
+++ b/net/ieee80211/softmac/ieee80211softmac_io.c
@@ -467,3 +467,17 @@ ieee80211softmac_send_mgt_frame(struct ieee80211softmac_device *mac,
467 kfree(pkt); 467 kfree(pkt);
468 return 0; 468 return 0;
469} 469}
470
471/* Beacon handling */
472int ieee80211softmac_handle_beacon(struct net_device *dev,
473 struct ieee80211_beacon *beacon,
474 struct ieee80211_network *network)
475{
476 struct ieee80211softmac_device *mac = ieee80211_priv(dev);
477
478 if (mac->associated && memcmp(network->bssid, mac->associnfo.bssid, ETH_ALEN) == 0)
479 ieee80211softmac_process_erp(mac, network->erp_value);
480
481 return 0;
482}
483
diff --git a/net/ieee80211/softmac/ieee80211softmac_module.c b/net/ieee80211/softmac/ieee80211softmac_module.c
index 4b2e57d12418..addea1cf73ae 100644
--- a/net/ieee80211/softmac/ieee80211softmac_module.c
+++ b/net/ieee80211/softmac/ieee80211softmac_module.c
@@ -44,6 +44,7 @@ struct net_device *alloc_ieee80211softmac(int sizeof_priv)
44 softmac->ieee->handle_assoc_response = ieee80211softmac_handle_assoc_response; 44 softmac->ieee->handle_assoc_response = ieee80211softmac_handle_assoc_response;
45 softmac->ieee->handle_reassoc_request = ieee80211softmac_handle_reassoc_req; 45 softmac->ieee->handle_reassoc_request = ieee80211softmac_handle_reassoc_req;
46 softmac->ieee->handle_disassoc = ieee80211softmac_handle_disassoc; 46 softmac->ieee->handle_disassoc = ieee80211softmac_handle_disassoc;
47 softmac->ieee->handle_beacon = ieee80211softmac_handle_beacon;
47 softmac->scaninfo = NULL; 48 softmac->scaninfo = NULL;
48 49
49 softmac->associnfo.scan_retry = IEEE80211SOFTMAC_ASSOC_SCAN_RETRY_LIMIT; 50 softmac->associnfo.scan_retry = IEEE80211SOFTMAC_ASSOC_SCAN_RETRY_LIMIT;
@@ -178,21 +179,14 @@ int ieee80211softmac_ratesinfo_rate_supported(struct ieee80211softmac_ratesinfo
178 return 0; 179 return 0;
179} 180}
180 181
181/* Finds the highest rate which is: 182u8 ieee80211softmac_highest_supported_rate(struct ieee80211softmac_device *mac,
182 * 1. Present in ri (optionally a basic rate)
183 * 2. Supported by the device
184 * 3. Less than or equal to the user-defined rate
185 */
186static u8 highest_supported_rate(struct ieee80211softmac_device *mac,
187 struct ieee80211softmac_ratesinfo *ri, int basic_only) 183 struct ieee80211softmac_ratesinfo *ri, int basic_only)
188{ 184{
189 u8 user_rate = mac->txrates.user_rate; 185 u8 user_rate = mac->txrates.user_rate;
190 int i; 186 int i;
191 187
192 if (ri->count == 0) { 188 if (ri->count == 0)
193 dprintk(KERN_ERR PFX "empty ratesinfo?\n");
194 return IEEE80211_CCK_RATE_1MB; 189 return IEEE80211_CCK_RATE_1MB;
195 }
196 190
197 for (i = ri->count - 1; i >= 0; i--) { 191 for (i = ri->count - 1; i >= 0; i--) {
198 u8 rate = ri->rates[i]; 192 u8 rate = ri->rates[i];
@@ -208,36 +202,61 @@ static u8 highest_supported_rate(struct ieee80211softmac_device *mac,
208 /* If we haven't found a suitable rate by now, just trust the user */ 202 /* If we haven't found a suitable rate by now, just trust the user */
209 return user_rate; 203 return user_rate;
210} 204}
205EXPORT_SYMBOL_GPL(ieee80211softmac_highest_supported_rate);
206
207void ieee80211softmac_process_erp(struct ieee80211softmac_device *mac,
208 u8 erp_value)
209{
210 int use_protection;
211 int short_preamble;
212 u32 changes = 0;
213
214 /* Barker preamble mode */
215 short_preamble = ((erp_value & WLAN_ERP_BARKER_PREAMBLE) == 0
216 && mac->associnfo.short_preamble_available) ? 1 : 0;
217
218 /* Protection needed? */
219 use_protection = (erp_value & WLAN_ERP_USE_PROTECTION) != 0;
220
221 if (mac->bssinfo.short_preamble != short_preamble) {
222 changes |= IEEE80211SOFTMAC_BSSINFOCHG_SHORT_PREAMBLE;
223 mac->bssinfo.short_preamble = short_preamble;
224 }
225
226 if (mac->bssinfo.use_protection != use_protection) {
227 changes |= IEEE80211SOFTMAC_BSSINFOCHG_PROTECTION;
228 mac->bssinfo.use_protection = use_protection;
229 }
230
231 if (mac->bssinfo_change && changes)
232 mac->bssinfo_change(mac->dev, changes);
233}
211 234
212void ieee80211softmac_recalc_txrates(struct ieee80211softmac_device *mac) 235void ieee80211softmac_recalc_txrates(struct ieee80211softmac_device *mac)
213{ 236{
214 struct ieee80211softmac_txrates *txrates = &mac->txrates; 237 struct ieee80211softmac_txrates *txrates = &mac->txrates;
215 struct ieee80211softmac_txrates oldrates;
216 u32 change = 0; 238 u32 change = 0;
217 239
218 if (mac->txrates_change)
219 oldrates = mac->txrates;
220
221 change |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT; 240 change |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT;
222 txrates->default_rate = highest_supported_rate(mac, &mac->associnfo.supported_rates, 0); 241 txrates->default_rate = ieee80211softmac_highest_supported_rate(mac, &mac->bssinfo.supported_rates, 0);
223 242
224 change |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT_FBACK; 243 change |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT_FBACK;
225 txrates->default_fallback = lower_rate(mac, txrates->default_rate); 244 txrates->default_fallback = lower_rate(mac, txrates->default_rate);
226 245
227 change |= IEEE80211SOFTMAC_TXRATECHG_MCAST; 246 change |= IEEE80211SOFTMAC_TXRATECHG_MCAST;
228 txrates->mcast_rate = highest_supported_rate(mac, &mac->associnfo.supported_rates, 1); 247 txrates->mcast_rate = ieee80211softmac_highest_supported_rate(mac, &mac->bssinfo.supported_rates, 1);
229 248
230 if (mac->txrates_change) 249 if (mac->txrates_change)
231 mac->txrates_change(mac->dev, change, &oldrates); 250 mac->txrates_change(mac->dev, change);
232 251
233} 252}
234 253
235void ieee80211softmac_init_txrates(struct ieee80211softmac_device *mac) 254void ieee80211softmac_init_bss(struct ieee80211softmac_device *mac)
236{ 255{
237 struct ieee80211_device *ieee = mac->ieee; 256 struct ieee80211_device *ieee = mac->ieee;
238 u32 change = 0; 257 u32 change = 0;
239 struct ieee80211softmac_txrates *txrates = &mac->txrates; 258 struct ieee80211softmac_txrates *txrates = &mac->txrates;
240 struct ieee80211softmac_txrates oldrates; 259 struct ieee80211softmac_bss_info *bssinfo = &mac->bssinfo;
241 260
242 /* TODO: We need some kind of state machine to lower the default rates 261 /* TODO: We need some kind of state machine to lower the default rates
243 * if we loose too many packets. 262 * if we loose too many packets.
@@ -245,8 +264,6 @@ void ieee80211softmac_init_txrates(struct ieee80211softmac_device *mac)
245 /* Change the default txrate to the highest possible value. 264 /* Change the default txrate to the highest possible value.
246 * The txrate machine will lower it, if it is too high. 265 * The txrate machine will lower it, if it is too high.
247 */ 266 */
248 if (mac->txrates_change)
249 oldrates = mac->txrates;
250 /* FIXME: We don't correctly handle backing down to lower 267 /* FIXME: We don't correctly handle backing down to lower
251 rates, so 801.11g devices start off at 11M for now. People 268 rates, so 801.11g devices start off at 11M for now. People
252 can manually change it if they really need to, but 11M is 269 can manually change it if they really need to, but 11M is
@@ -272,7 +289,23 @@ void ieee80211softmac_init_txrates(struct ieee80211softmac_device *mac)
272 change |= IEEE80211SOFTMAC_TXRATECHG_MGT_MCAST; 289 change |= IEEE80211SOFTMAC_TXRATECHG_MGT_MCAST;
273 290
274 if (mac->txrates_change) 291 if (mac->txrates_change)
275 mac->txrates_change(mac->dev, change, &oldrates); 292 mac->txrates_change(mac->dev, change);
293
294 change = 0;
295
296 bssinfo->supported_rates.count = 0;
297 memset(bssinfo->supported_rates.rates, 0,
298 sizeof(bssinfo->supported_rates.rates));
299 change |= IEEE80211SOFTMAC_BSSINFOCHG_RATES;
300
301 bssinfo->short_preamble = 0;
302 change |= IEEE80211SOFTMAC_BSSINFOCHG_SHORT_PREAMBLE;
303
304 bssinfo->use_protection = 0;
305 change |= IEEE80211SOFTMAC_BSSINFOCHG_PROTECTION;
306
307 if (mac->bssinfo_change)
308 mac->bssinfo_change(mac->dev, change);
276 309
277 mac->running = 1; 310 mac->running = 1;
278} 311}
@@ -282,7 +315,7 @@ void ieee80211softmac_start(struct net_device *dev)
282 struct ieee80211softmac_device *mac = ieee80211_priv(dev); 315 struct ieee80211softmac_device *mac = ieee80211_priv(dev);
283 316
284 ieee80211softmac_start_check_rates(mac); 317 ieee80211softmac_start_check_rates(mac);
285 ieee80211softmac_init_txrates(mac); 318 ieee80211softmac_init_bss(mac);
286} 319}
287EXPORT_SYMBOL_GPL(ieee80211softmac_start); 320EXPORT_SYMBOL_GPL(ieee80211softmac_start);
288 321
@@ -335,7 +368,6 @@ u8 ieee80211softmac_lower_rate_delta(struct ieee80211softmac_device *mac, u8 rat
335static void ieee80211softmac_add_txrates_badness(struct ieee80211softmac_device *mac, 368static void ieee80211softmac_add_txrates_badness(struct ieee80211softmac_device *mac,
336 int amount) 369 int amount)
337{ 370{
338 struct ieee80211softmac_txrates oldrates;
339 u8 default_rate = mac->txrates.default_rate; 371 u8 default_rate = mac->txrates.default_rate;
340 u8 default_fallback = mac->txrates.default_fallback; 372 u8 default_fallback = mac->txrates.default_fallback;
341 u32 changes = 0; 373 u32 changes = 0;
@@ -348,8 +380,6 @@ printk("badness %d\n", mac->txrate_badness);
348 mac->txrate_badness += amount; 380 mac->txrate_badness += amount;
349 if (mac->txrate_badness <= -1000) { 381 if (mac->txrate_badness <= -1000) {
350 /* Very small badness. Try a faster bitrate. */ 382 /* Very small badness. Try a faster bitrate. */
351 if (mac->txrates_change)
352 memcpy(&oldrates, &mac->txrates, sizeof(oldrates));
353 default_rate = raise_rate(mac, default_rate); 383 default_rate = raise_rate(mac, default_rate);
354 changes |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT; 384 changes |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT;
355 default_fallback = get_fallback_rate(mac, default_rate); 385 default_fallback = get_fallback_rate(mac, default_rate);
@@ -358,8 +388,6 @@ printk("badness %d\n", mac->txrate_badness);
358printk("Bitrate raised to %u\n", default_rate); 388printk("Bitrate raised to %u\n", default_rate);
359 } else if (mac->txrate_badness >= 10000) { 389 } else if (mac->txrate_badness >= 10000) {
360 /* Very high badness. Try a slower bitrate. */ 390 /* Very high badness. Try a slower bitrate. */
361 if (mac->txrates_change)
362 memcpy(&oldrates, &mac->txrates, sizeof(oldrates));
363 default_rate = lower_rate(mac, default_rate); 391 default_rate = lower_rate(mac, default_rate);
364 changes |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT; 392 changes |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT;
365 default_fallback = get_fallback_rate(mac, default_rate); 393 default_fallback = get_fallback_rate(mac, default_rate);
@@ -372,7 +400,7 @@ printk("Bitrate lowered to %u\n", default_rate);
372 mac->txrates.default_fallback = default_fallback; 400 mac->txrates.default_fallback = default_fallback;
373 401
374 if (changes && mac->txrates_change) 402 if (changes && mac->txrates_change)
375 mac->txrates_change(mac->dev, changes, &oldrates); 403 mac->txrates_change(mac->dev, changes);
376} 404}
377 405
378void ieee80211softmac_fragment_lost(struct net_device *dev, 406void ieee80211softmac_fragment_lost(struct net_device *dev,
@@ -416,7 +444,11 @@ ieee80211softmac_create_network(struct ieee80211softmac_device *mac,
416 memcpy(&softnet->supported_rates.rates[softnet->supported_rates.count], net->rates_ex, net->rates_ex_len); 444 memcpy(&softnet->supported_rates.rates[softnet->supported_rates.count], net->rates_ex, net->rates_ex_len);
417 softnet->supported_rates.count += net->rates_ex_len; 445 softnet->supported_rates.count += net->rates_ex_len;
418 sort(softnet->supported_rates.rates, softnet->supported_rates.count, sizeof(softnet->supported_rates.rates[0]), rate_cmp, NULL); 446 sort(softnet->supported_rates.rates, softnet->supported_rates.count, sizeof(softnet->supported_rates.rates[0]), rate_cmp, NULL);
419 447
448 /* we save the ERP value because it is needed at association time, and
449 * many AP's do not include an ERP IE in the association response. */
450 softnet->erp_value = net->erp_value;
451
420 softnet->capabilities = net->capability; 452 softnet->capabilities = net->capability;
421 return softnet; 453 return softnet;
422} 454}
diff --git a/net/ieee80211/softmac/ieee80211softmac_priv.h b/net/ieee80211/softmac/ieee80211softmac_priv.h
index fa1f8e3acfc0..0642e090b8a7 100644
--- a/net/ieee80211/softmac/ieee80211softmac_priv.h
+++ b/net/ieee80211/softmac/ieee80211softmac_priv.h
@@ -116,9 +116,11 @@ ieee80211softmac_get_network_by_essid(struct ieee80211softmac_device *mac,
116 struct ieee80211softmac_essid *essid); 116 struct ieee80211softmac_essid *essid);
117 117
118/* Rates related */ 118/* Rates related */
119void ieee80211softmac_process_erp(struct ieee80211softmac_device *mac,
120 u8 erp_value);
119int ieee80211softmac_ratesinfo_rate_supported(struct ieee80211softmac_ratesinfo *ri, u8 rate); 121int ieee80211softmac_ratesinfo_rate_supported(struct ieee80211softmac_ratesinfo *ri, u8 rate);
120u8 ieee80211softmac_lower_rate_delta(struct ieee80211softmac_device *mac, u8 rate, int delta); 122u8 ieee80211softmac_lower_rate_delta(struct ieee80211softmac_device *mac, u8 rate, int delta);
121void ieee80211softmac_init_txrates(struct ieee80211softmac_device *mac); 123void ieee80211softmac_init_bss(struct ieee80211softmac_device *mac);
122void ieee80211softmac_recalc_txrates(struct ieee80211softmac_device *mac); 124void ieee80211softmac_recalc_txrates(struct ieee80211softmac_device *mac);
123static inline u8 lower_rate(struct ieee80211softmac_device *mac, u8 rate) { 125static inline u8 lower_rate(struct ieee80211softmac_device *mac, u8 rate) {
124 return ieee80211softmac_lower_rate_delta(mac, rate, 1); 126 return ieee80211softmac_lower_rate_delta(mac, rate, 1);
@@ -133,6 +135,9 @@ static inline u8 get_fallback_rate(struct ieee80211softmac_device *mac, u8 rate)
133/*** prototypes from _io.c */ 135/*** prototypes from _io.c */
134int ieee80211softmac_send_mgt_frame(struct ieee80211softmac_device *mac, 136int ieee80211softmac_send_mgt_frame(struct ieee80211softmac_device *mac,
135 void* ptrarg, u32 type, u32 arg); 137 void* ptrarg, u32 type, u32 arg);
138int ieee80211softmac_handle_beacon(struct net_device *dev,
139 struct ieee80211_beacon *beacon,
140 struct ieee80211_network *network);
136 141
137/*** prototypes from _auth.c */ 142/*** prototypes from _auth.c */
138/* do these have to go into the public header? */ 143/* do these have to go into the public header? */
@@ -189,6 +194,7 @@ struct ieee80211softmac_network {
189 authenticated:1, 194 authenticated:1,
190 auth_desynced_once:1; 195 auth_desynced_once:1;
191 196
197 u8 erp_value; /* Saved ERP value */
192 u16 capabilities; /* Capabilities bitfield */ 198 u16 capabilities; /* Capabilities bitfield */
193 u8 challenge_len; /* Auth Challenge length */ 199 u8 challenge_len; /* Auth Challenge length */
194 char *challenge; /* Challenge Text */ 200 char *challenge; /* Challenge Text */