aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/Kconfig23
-rw-r--r--drivers/net/wireless/airo.c52
-rw-r--r--drivers/net/wireless/atmel_pci.c2
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx.h181
-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_ethtool.c2
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_ethtool.h2
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_leds.c10
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_main.c900
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_main.h6
-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.c178
-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/hostap/hostap.h2
-rw-r--r--drivers/net/wireless/hostap/hostap_cs.c1
-rw-r--r--drivers/net/wireless/hostap/hostap_ioctl.c2
-rw-r--r--drivers/net/wireless/ipw2100.c9
-rw-r--r--drivers/net/wireless/ipw2200.c248
-rw-r--r--drivers/net/wireless/ipw2200.h51
-rw-r--r--drivers/net/wireless/orinoco.c5
-rw-r--r--drivers/net/wireless/orinoco.h8
-rw-r--r--drivers/net/wireless/orinoco_nortel.c2
-rw-r--r--drivers/net/wireless/orinoco_pci.c2
-rw-r--r--drivers/net/wireless/orinoco_plx.c2
-rw-r--r--drivers/net/wireless/orinoco_tmd.c2
-rw-r--r--drivers/net/wireless/prism54/isl_ioctl.c597
-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/prism54/islpci_hotplug.c2
-rw-r--r--drivers/net/wireless/ray_cs.c6
-rw-r--r--drivers/net/wireless/wavelan_cs.c2
-rw-r--r--drivers/net/wireless/wl3501_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_ieee80211.h2
-rw-r--r--drivers/net/wireless/zd1211rw/zd_mac.c8
-rw-r--r--drivers/net/wireless/zd1211rw/zd_mac.h6
-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.c124
-rw-r--r--drivers/net/wireless/zd1211rw/zd_usb.h15
52 files changed, 2971 insertions, 1201 deletions
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/atmel_pci.c b/drivers/net/wireless/atmel_pci.c
index d425c3cefded..3bfa791c323d 100644
--- a/drivers/net/wireless/atmel_pci.c
+++ b/drivers/net/wireless/atmel_pci.c
@@ -76,7 +76,7 @@ static void __devexit atmel_pci_remove(struct pci_dev *pdev)
76 76
77static int __init atmel_init_module(void) 77static int __init atmel_init_module(void)
78{ 78{
79 return pci_module_init(&atmel_driver); 79 return pci_register_driver(&atmel_driver);
80} 80}
81 81
82static void __exit atmel_cleanup_module(void) 82static void __exit atmel_cleanup_module(void)
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx.h b/drivers/net/wireless/bcm43xx/bcm43xx.h
index 17a56828e232..6d4ea36bc564 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
@@ -283,6 +306,13 @@
283#define BCM43xx_SBF_TIME_UPDATE 0x10000000 306#define BCM43xx_SBF_TIME_UPDATE 0x10000000
284#define BCM43xx_SBF_80000000 0x80000000 /*FIXME: fix name*/ 307#define BCM43xx_SBF_80000000 0x80000000 /*FIXME: fix name*/
285 308
309/* Microcode */
310#define BCM43xx_UCODE_REVISION 0x0000
311#define BCM43xx_UCODE_PATCHLEVEL 0x0002
312#define BCM43xx_UCODE_DATE 0x0004
313#define BCM43xx_UCODE_TIME 0x0006
314#define BCM43xx_UCODE_STATUS 0x0040
315
286/* MicrocodeFlagsBitfield (addr + lo-word values?)*/ 316/* MicrocodeFlagsBitfield (addr + lo-word values?)*/
287#define BCM43xx_UCODEFLAGS_OFFSET 0x005E 317#define BCM43xx_UCODEFLAGS_OFFSET 0x005E
288 318
@@ -504,6 +534,12 @@ struct bcm43xx_phyinfo {
504 * This lock is only used by bcm43xx_phy_{un}lock() 534 * This lock is only used by bcm43xx_phy_{un}lock()
505 */ 535 */
506 spinlock_t lock; 536 spinlock_t lock;
537
538 /* Firmware. */
539 const struct firmware *ucode;
540 const struct firmware *pcm;
541 const struct firmware *initvals0;
542 const struct firmware *initvals1;
507}; 543};
508 544
509 545
@@ -568,8 +604,11 @@ struct bcm43xx_dma {
568 struct bcm43xx_dmaring *tx_ring1; 604 struct bcm43xx_dmaring *tx_ring1;
569 struct bcm43xx_dmaring *tx_ring2; 605 struct bcm43xx_dmaring *tx_ring2;
570 struct bcm43xx_dmaring *tx_ring3; 606 struct bcm43xx_dmaring *tx_ring3;
607 struct bcm43xx_dmaring *tx_ring4;
608 struct bcm43xx_dmaring *tx_ring5;
609
571 struct bcm43xx_dmaring *rx_ring0; 610 struct bcm43xx_dmaring *rx_ring0;
572 struct bcm43xx_dmaring *rx_ring1; /* only available on core.rev < 5 */ 611 struct bcm43xx_dmaring *rx_ring3; /* only available on core.rev < 5 */
573}; 612};
574 613
575/* Data structures for PIO transmission, per 80211 core. */ 614/* Data structures for PIO transmission, per 80211 core. */
@@ -593,12 +632,14 @@ struct bcm43xx_coreinfo {
593 u8 available:1, 632 u8 available:1,
594 enabled:1, 633 enabled:1,
595 initialized:1; 634 initialized:1;
596 /** core_id ID number */
597 u16 id;
598 /** core_rev revision number */ 635 /** core_rev revision number */
599 u8 rev; 636 u8 rev;
600 /** Index number for _switch_core() */ 637 /** Index number for _switch_core() */
601 u8 index; 638 u8 index;
639 /** core_id ID number */
640 u16 id;
641 /** Core-specific data. */
642 void *priv;
602}; 643};
603 644
604/* Additional information for each 80211 core. */ 645/* Additional information for each 80211 core. */
@@ -647,7 +688,23 @@ enum {
647 BCM43xx_STAT_RESTARTING, /* controller_restart() called. */ 688 BCM43xx_STAT_RESTARTING, /* controller_restart() called. */
648}; 689};
649#define bcm43xx_status(bcm) atomic_read(&(bcm)->init_status) 690#define bcm43xx_status(bcm) atomic_read(&(bcm)->init_status)
650#define bcm43xx_set_status(bcm, stat) atomic_set(&(bcm)->init_status, (stat)) 691#define bcm43xx_set_status(bcm, stat) do { \
692 atomic_set(&(bcm)->init_status, (stat)); \
693 smp_wmb(); \
694 } while (0)
695
696/* *** THEORY OF LOCKING ***
697 *
698 * We have two different locks in the bcm43xx driver.
699 * => bcm->mutex: General sleeping mutex. Protects struct bcm43xx_private
700 * and the device registers. This mutex does _not_ protect
701 * against concurrency from the IRQ handler.
702 * => bcm->irq_lock: IRQ spinlock. Protects against IRQ handler concurrency.
703 *
704 * Please note that, if you only take the irq_lock, you are not protected
705 * against concurrency from the periodic work handlers.
706 * Most times you want to take _both_ locks.
707 */
651 708
652struct bcm43xx_private { 709struct bcm43xx_private {
653 struct ieee80211_device *ieee; 710 struct ieee80211_device *ieee;
@@ -659,7 +716,6 @@ struct bcm43xx_private {
659 716
660 void __iomem *mmio_addr; 717 void __iomem *mmio_addr;
661 718
662 /* Locking, see "theory of locking" text below. */
663 spinlock_t irq_lock; 719 spinlock_t irq_lock;
664 struct mutex mutex; 720 struct mutex mutex;
665 721
@@ -691,6 +747,7 @@ struct bcm43xx_private {
691 struct bcm43xx_sprominfo sprom; 747 struct bcm43xx_sprominfo sprom;
692#define BCM43xx_NR_LEDS 4 748#define BCM43xx_NR_LEDS 4
693 struct bcm43xx_led leds[BCM43xx_NR_LEDS]; 749 struct bcm43xx_led leds[BCM43xx_NR_LEDS];
750 spinlock_t leds_lock;
694 751
695 /* The currently active core. */ 752 /* The currently active core. */
696 struct bcm43xx_coreinfo *current_core; 753 struct bcm43xx_coreinfo *current_core;
@@ -708,10 +765,6 @@ struct bcm43xx_private {
708 struct bcm43xx_coreinfo core_80211[ BCM43xx_MAX_80211_CORES ]; 765 struct bcm43xx_coreinfo core_80211[ BCM43xx_MAX_80211_CORES ];
709 /* Additional information, specific to the 80211 cores. */ 766 /* Additional information, specific to the 80211 cores. */
710 struct bcm43xx_coreinfo_80211 core_80211_ext[ BCM43xx_MAX_80211_CORES ]; 767 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. */ 768 /* Number of available 80211 cores. */
716 int nr_80211_available; 769 int nr_80211_available;
717 770
@@ -719,11 +772,13 @@ struct bcm43xx_private {
719 772
720 /* Reason code of the last interrupt. */ 773 /* Reason code of the last interrupt. */
721 u32 irq_reason; 774 u32 irq_reason;
722 u32 dma_reason[4]; 775 u32 dma_reason[6];
723 /* saved irq enable/disable state bitfield. */ 776 /* saved irq enable/disable state bitfield. */
724 u32 irq_savedstate; 777 u32 irq_savedstate;
725 /* Link Quality calculation context. */ 778 /* Link Quality calculation context. */
726 struct bcm43xx_noise_calculation noisecalc; 779 struct bcm43xx_noise_calculation noisecalc;
780 /* if > 0 MAC is suspended. if == 0 MAC is enabled. */
781 int mac_suspended;
727 782
728 /* Threshold values. */ 783 /* Threshold values. */
729 //TODO: The RTS thr has to be _used_. Currently, it is only set via WX. 784 //TODO: The RTS thr has to be _used_. Currently, it is only set via WX.
@@ -746,12 +801,6 @@ struct bcm43xx_private {
746 struct bcm43xx_key key[54]; 801 struct bcm43xx_key key[54];
747 u8 default_key_idx; 802 u8 default_key_idx;
748 803
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. */ 804 /* Random Number Generator. */
756 struct hwrng rng; 805 struct hwrng rng;
757 char rng_name[20 + 1]; 806 char rng_name[20 + 1];
@@ -763,55 +812,6 @@ struct bcm43xx_private {
763}; 812};
764 813
765 814
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 815static inline
816struct bcm43xx_private * bcm43xx_priv(struct net_device *dev) 816struct bcm43xx_private * bcm43xx_priv(struct net_device *dev)
817{ 817{
@@ -863,34 +863,33 @@ int bcm43xx_using_pio(struct bcm43xx_private *bcm)
863 * any of these functions. 863 * any of these functions.
864 */ 864 */
865static inline 865static inline
866struct bcm43xx_coreinfo_80211 *
867bcm43xx_current_80211_priv(struct bcm43xx_private *bcm)
868{
869 assert(bcm->current_core->id == BCM43xx_COREID_80211);
870 return bcm->current_core->priv;
871}
872static inline
866struct bcm43xx_pio * bcm43xx_current_pio(struct bcm43xx_private *bcm) 873struct bcm43xx_pio * bcm43xx_current_pio(struct bcm43xx_private *bcm)
867{ 874{
868 assert(bcm43xx_using_pio(bcm)); 875 assert(bcm43xx_using_pio(bcm));
869 assert(bcm->current_80211_core_idx >= 0); 876 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} 877}
873static inline 878static inline
874struct bcm43xx_dma * bcm43xx_current_dma(struct bcm43xx_private *bcm) 879struct bcm43xx_dma * bcm43xx_current_dma(struct bcm43xx_private *bcm)
875{ 880{
876 assert(!bcm43xx_using_pio(bcm)); 881 assert(!bcm43xx_using_pio(bcm));
877 assert(bcm->current_80211_core_idx >= 0); 882 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} 883}
881static inline 884static inline
882struct bcm43xx_phyinfo * bcm43xx_current_phy(struct bcm43xx_private *bcm) 885struct bcm43xx_phyinfo * bcm43xx_current_phy(struct bcm43xx_private *bcm)
883{ 886{
884 assert(bcm->current_80211_core_idx >= 0); 887 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} 888}
888static inline 889static inline
889struct bcm43xx_radioinfo * bcm43xx_current_radio(struct bcm43xx_private *bcm) 890struct bcm43xx_radioinfo * bcm43xx_current_radio(struct bcm43xx_private *bcm)
890{ 891{
891 assert(bcm->current_80211_core_idx >= 0); 892 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} 893}
895 894
896 895
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_ethtool.c b/drivers/net/wireless/bcm43xx/bcm43xx_ethtool.c
index e386dcc32e8c..c947025d655f 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_ethtool.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_ethtool.c
@@ -44,7 +44,7 @@ static void bcm43xx_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *
44 strncpy(info->bus_info, pci_name(bcm->pci_dev), ETHTOOL_BUSINFO_LEN); 44 strncpy(info->bus_info, pci_name(bcm->pci_dev), ETHTOOL_BUSINFO_LEN);
45} 45}
46 46
47struct ethtool_ops bcm43xx_ethtool_ops = { 47const struct ethtool_ops bcm43xx_ethtool_ops = {
48 .get_drvinfo = bcm43xx_get_drvinfo, 48 .get_drvinfo = bcm43xx_get_drvinfo,
49 .get_link = ethtool_op_get_link, 49 .get_link = ethtool_op_get_link,
50}; 50};
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_ethtool.h b/drivers/net/wireless/bcm43xx/bcm43xx_ethtool.h
index 813704991f62..6f8d42d3cdf5 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_ethtool.h
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_ethtool.h
@@ -3,6 +3,6 @@
3 3
4#include <linux/ethtool.h> 4#include <linux/ethtool.h>
5 5
6extern struct ethtool_ops bcm43xx_ethtool_ops; 6extern const struct ethtool_ops bcm43xx_ethtool_ops;
7 7
8#endif /* BCM43xx_ETHTOOL_H_ */ 8#endif /* BCM43xx_ETHTOOL_H_ */
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..cb9a3ae8463a 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_main.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.c
@@ -509,23 +509,20 @@ 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 bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_MASK); /* flush */
523 spin_unlock_irqrestore(&bcm->irq_lock, flags);
524 bcm43xx_synchronize_irq(bcm); 524 bcm43xx_synchronize_irq(bcm);
525 525
526 if (oldstate)
527 *oldstate = old;
528
529 return 0; 526 return 0;
530} 527}
531 528
@@ -537,7 +534,6 @@ static int bcm43xx_read_radioinfo(struct bcm43xx_private *bcm)
537 u16 manufact; 534 u16 manufact;
538 u16 version; 535 u16 version;
539 u8 revision; 536 u8 revision;
540 s8 i;
541 537
542 if (bcm->chip_id == 0x4317) { 538 if (bcm->chip_id == 0x4317) {
543 if (bcm->chip_rev == 0x00) 539 if (bcm->chip_rev == 0x00)
@@ -580,20 +576,11 @@ static int bcm43xx_read_radioinfo(struct bcm43xx_private *bcm)
580 radio->version = version; 576 radio->version = version;
581 radio->revision = revision; 577 radio->revision = revision;
582 578
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) 579 if (phy->type == BCM43xx_PHYTYPE_A)
589 radio->txpower_desired = bcm->sprom.maxpower_aphy; 580 radio->txpower_desired = bcm->sprom.maxpower_aphy;
590 else 581 else
591 radio->txpower_desired = bcm->sprom.maxpower_bgphy; 582 radio->txpower_desired = bcm->sprom.maxpower_bgphy;
592 583
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; 584 return 0;
598 585
599err_unsupported_radio: 586err_unsupported_radio:
@@ -1250,10 +1237,6 @@ int bcm43xx_switch_core(struct bcm43xx_private *bcm, struct bcm43xx_coreinfo *ne
1250 goto out; 1237 goto out;
1251 1238
1252 bcm->current_core = new_core; 1239 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: 1240out:
1258 return err; 1241 return err;
1259} 1242}
@@ -1389,6 +1372,7 @@ void bcm43xx_wireless_core_reset(struct bcm43xx_private *bcm, int connect_phy)
1389 if ((bcm43xx_core_enabled(bcm)) && 1372 if ((bcm43xx_core_enabled(bcm)) &&
1390 !bcm43xx_using_pio(bcm)) { 1373 !bcm43xx_using_pio(bcm)) {
1391//FIXME: Do we _really_ want #ifndef CONFIG_BCM947XX here? 1374//FIXME: Do we _really_ want #ifndef CONFIG_BCM947XX here?
1375#if 0
1392#ifndef CONFIG_BCM947XX 1376#ifndef CONFIG_BCM947XX
1393 /* reset all used DMA controllers. */ 1377 /* reset all used DMA controllers. */
1394 bcm43xx_dmacontroller_tx_reset(bcm, BCM43xx_MMIO_DMA1_BASE); 1378 bcm43xx_dmacontroller_tx_reset(bcm, BCM43xx_MMIO_DMA1_BASE);
@@ -1399,6 +1383,7 @@ void bcm43xx_wireless_core_reset(struct bcm43xx_private *bcm, int connect_phy)
1399 if (bcm->current_core->rev < 5) 1383 if (bcm->current_core->rev < 5)
1400 bcm43xx_dmacontroller_rx_reset(bcm, BCM43xx_MMIO_DMA4_BASE); 1384 bcm43xx_dmacontroller_rx_reset(bcm, BCM43xx_MMIO_DMA4_BASE);
1401#endif 1385#endif
1386#endif
1402 } 1387 }
1403 if (bcm43xx_status(bcm) == BCM43xx_STAT_SHUTTINGDOWN) { 1388 if (bcm43xx_status(bcm) == BCM43xx_STAT_SHUTTINGDOWN) {
1404 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, 1389 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD,
@@ -1423,43 +1408,23 @@ static void bcm43xx_wireless_core_disable(struct bcm43xx_private *bcm)
1423 bcm43xx_core_disable(bcm, 0); 1408 bcm43xx_core_disable(bcm, 0);
1424} 1409}
1425 1410
1426/* Mark the current 80211 core inactive. 1411/* Mark the current 80211 core inactive. */
1427 * "active_80211_core" is the other 80211 core, which is used. 1412static 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{ 1413{
1432 u32 sbtmstatelow; 1414 u32 sbtmstatelow;
1433 struct bcm43xx_coreinfo *old_core;
1434 int err = 0;
1435 1415
1436 bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL); 1416 bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
1437 bcm43xx_radio_turn_off(bcm); 1417 bcm43xx_radio_turn_off(bcm);
1438 sbtmstatelow = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW); 1418 sbtmstatelow = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
1439 sbtmstatelow &= ~0x200a0000; 1419 sbtmstatelow &= 0xDFF5FFFF;
1440 sbtmstatelow |= 0xa0000; 1420 sbtmstatelow |= 0x000A0000;
1441 bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow); 1421 bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
1442 udelay(1); 1422 udelay(1);
1443 sbtmstatelow = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW); 1423 sbtmstatelow = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
1444 sbtmstatelow &= ~0xa0000; 1424 sbtmstatelow &= 0xFFF5FFFF;
1445 sbtmstatelow |= 0x80000; 1425 sbtmstatelow |= 0x00080000;
1446 bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow); 1426 bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
1447 udelay(1); 1427 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} 1428}
1464 1429
1465static void handle_irq_transmit_status(struct bcm43xx_private *bcm) 1430static void handle_irq_transmit_status(struct bcm43xx_private *bcm)
@@ -1581,17 +1546,7 @@ static void handle_irq_noise(struct bcm43xx_private *bcm)
1581 else 1546 else
1582 average -= 48; 1547 average -= 48;
1583 1548
1584/* FIXME: This is wrong, but people want fancy stats. well... */ 1549 bcm->stats.noise = average;
1585bcm->stats.noise = average;
1586 if (average > -65)
1587 bcm->stats.link_quality = 0;
1588 else if (average > -75)
1589 bcm->stats.link_quality = 1;
1590 else if (average > -85)
1591 bcm->stats.link_quality = 2;
1592 else
1593 bcm->stats.link_quality = 3;
1594// dprintk(KERN_INFO PFX "Link Quality: %u (avg was %d)\n", bcm->stats.link_quality, average);
1595drop_calculation: 1550drop_calculation:
1596 bcm->noisecalc.calculation_running = 0; 1551 bcm->noisecalc.calculation_running = 0;
1597 return; 1552 return;
@@ -1709,8 +1664,9 @@ static void handle_irq_beacon(struct bcm43xx_private *bcm)
1709static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm) 1664static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm)
1710{ 1665{
1711 u32 reason; 1666 u32 reason;
1712 u32 dma_reason[4]; 1667 u32 dma_reason[6];
1713 int activity = 0; 1668 u32 merged_dma_reason = 0;
1669 int i, activity = 0;
1714 unsigned long flags; 1670 unsigned long flags;
1715 1671
1716#ifdef CONFIG_BCM43XX_DEBUG 1672#ifdef CONFIG_BCM43XX_DEBUG
@@ -1720,12 +1676,12 @@ static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm)
1720# define bcmirq_handled(irq) do { /* nothing */ } while (0) 1676# define bcmirq_handled(irq) do { /* nothing */ } while (0)
1721#endif /* CONFIG_BCM43XX_DEBUG*/ 1677#endif /* CONFIG_BCM43XX_DEBUG*/
1722 1678
1723 bcm43xx_lock_irqonly(bcm, flags); 1679 spin_lock_irqsave(&bcm->irq_lock, flags);
1724 reason = bcm->irq_reason; 1680 reason = bcm->irq_reason;
1725 dma_reason[0] = bcm->dma_reason[0]; 1681 for (i = 5; i >= 0; i--) {
1726 dma_reason[1] = bcm->dma_reason[1]; 1682 dma_reason[i] = bcm->dma_reason[i];
1727 dma_reason[2] = bcm->dma_reason[2]; 1683 merged_dma_reason |= dma_reason[i];
1728 dma_reason[3] = bcm->dma_reason[3]; 1684 }
1729 1685
1730 if (unlikely(reason & BCM43xx_IRQ_XMIT_ERROR)) { 1686 if (unlikely(reason & BCM43xx_IRQ_XMIT_ERROR)) {
1731 /* TX error. We get this when Template Ram is written in wrong endianess 1687 /* TX error. We get this when Template Ram is written in wrong endianess
@@ -1736,27 +1692,25 @@ static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm)
1736 printkl(KERN_ERR PFX "FATAL ERROR: BCM43xx_IRQ_XMIT_ERROR\n"); 1692 printkl(KERN_ERR PFX "FATAL ERROR: BCM43xx_IRQ_XMIT_ERROR\n");
1737 bcmirq_handled(BCM43xx_IRQ_XMIT_ERROR); 1693 bcmirq_handled(BCM43xx_IRQ_XMIT_ERROR);
1738 } 1694 }
1739 if (unlikely((dma_reason[0] & BCM43xx_DMAIRQ_FATALMASK) | 1695 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: " 1696 printkl(KERN_ERR PFX "FATAL ERROR: Fatal DMA error: "
1744 "0x%08X, 0x%08X, 0x%08X, 0x%08X\n", 1697 "0x%08X, 0x%08X, 0x%08X, "
1698 "0x%08X, 0x%08X, 0x%08X\n",
1745 dma_reason[0], dma_reason[1], 1699 dma_reason[0], dma_reason[1],
1746 dma_reason[2], dma_reason[3]); 1700 dma_reason[2], dma_reason[3],
1701 dma_reason[4], dma_reason[5]);
1747 bcm43xx_controller_restart(bcm, "DMA error"); 1702 bcm43xx_controller_restart(bcm, "DMA error");
1748 mmiowb(); 1703 mmiowb();
1749 bcm43xx_unlock_irqonly(bcm, flags); 1704 spin_unlock_irqrestore(&bcm->irq_lock, flags);
1750 return; 1705 return;
1751 } 1706 }
1752 if (unlikely((dma_reason[0] & BCM43xx_DMAIRQ_NONFATALMASK) | 1707 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: " 1708 printkl(KERN_ERR PFX "DMA error: "
1757 "0x%08X, 0x%08X, 0x%08X, 0x%08X\n", 1709 "0x%08X, 0x%08X, 0x%08X, "
1710 "0x%08X, 0x%08X, 0x%08X\n",
1758 dma_reason[0], dma_reason[1], 1711 dma_reason[0], dma_reason[1],
1759 dma_reason[2], dma_reason[3]); 1712 dma_reason[2], dma_reason[3],
1713 dma_reason[4], dma_reason[5]);
1760 } 1714 }
1761 1715
1762 if (reason & BCM43xx_IRQ_PS) { 1716 if (reason & BCM43xx_IRQ_PS) {
@@ -1791,8 +1745,6 @@ static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm)
1791 } 1745 }
1792 1746
1793 /* Check the DMA reason registers for received data. */ 1747 /* 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) { 1748 if (dma_reason[0] & BCM43xx_DMAIRQ_RX_DONE) {
1797 if (bcm43xx_using_pio(bcm)) 1749 if (bcm43xx_using_pio(bcm))
1798 bcm43xx_pio_rx(bcm43xx_current_pio(bcm)->queue0); 1750 bcm43xx_pio_rx(bcm43xx_current_pio(bcm)->queue0);
@@ -1800,13 +1752,17 @@ static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm)
1800 bcm43xx_dma_rx(bcm43xx_current_dma(bcm)->rx_ring0); 1752 bcm43xx_dma_rx(bcm43xx_current_dma(bcm)->rx_ring0);
1801 /* We intentionally don't set "activity" to 1, here. */ 1753 /* We intentionally don't set "activity" to 1, here. */
1802 } 1754 }
1755 assert(!(dma_reason[1] & BCM43xx_DMAIRQ_RX_DONE));
1756 assert(!(dma_reason[2] & BCM43xx_DMAIRQ_RX_DONE));
1803 if (dma_reason[3] & BCM43xx_DMAIRQ_RX_DONE) { 1757 if (dma_reason[3] & BCM43xx_DMAIRQ_RX_DONE) {
1804 if (bcm43xx_using_pio(bcm)) 1758 if (bcm43xx_using_pio(bcm))
1805 bcm43xx_pio_rx(bcm43xx_current_pio(bcm)->queue3); 1759 bcm43xx_pio_rx(bcm43xx_current_pio(bcm)->queue3);
1806 else 1760 else
1807 bcm43xx_dma_rx(bcm43xx_current_dma(bcm)->rx_ring1); 1761 bcm43xx_dma_rx(bcm43xx_current_dma(bcm)->rx_ring3);
1808 activity = 1; 1762 activity = 1;
1809 } 1763 }
1764 assert(!(dma_reason[4] & BCM43xx_DMAIRQ_RX_DONE));
1765 assert(!(dma_reason[5] & BCM43xx_DMAIRQ_RX_DONE));
1810 bcmirq_handled(BCM43xx_IRQ_RX); 1766 bcmirq_handled(BCM43xx_IRQ_RX);
1811 1767
1812 if (reason & BCM43xx_IRQ_XMIT_STATUS) { 1768 if (reason & BCM43xx_IRQ_XMIT_STATUS) {
@@ -1834,7 +1790,7 @@ static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm)
1834 bcm43xx_leds_update(bcm, activity); 1790 bcm43xx_leds_update(bcm, activity);
1835 bcm43xx_interrupt_enable(bcm, bcm->irq_savedstate); 1791 bcm43xx_interrupt_enable(bcm, bcm->irq_savedstate);
1836 mmiowb(); 1792 mmiowb();
1837 bcm43xx_unlock_irqonly(bcm, flags); 1793 spin_unlock_irqrestore(&bcm->irq_lock, flags);
1838} 1794}
1839 1795
1840static void pio_irq_workaround(struct bcm43xx_private *bcm, 1796static void pio_irq_workaround(struct bcm43xx_private *bcm,
@@ -1863,14 +1819,18 @@ static void bcm43xx_interrupt_ack(struct bcm43xx_private *bcm, u32 reason)
1863 1819
1864 bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, reason); 1820 bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, reason);
1865 1821
1866 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA1_REASON, 1822 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA0_REASON,
1867 bcm->dma_reason[0]); 1823 bcm->dma_reason[0]);
1868 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA2_REASON, 1824 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA1_REASON,
1869 bcm->dma_reason[1]); 1825 bcm->dma_reason[1]);
1870 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA3_REASON, 1826 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA2_REASON,
1871 bcm->dma_reason[2]); 1827 bcm->dma_reason[2]);
1872 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA4_REASON, 1828 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA3_REASON,
1873 bcm->dma_reason[3]); 1829 bcm->dma_reason[3]);
1830 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA4_REASON,
1831 bcm->dma_reason[4]);
1832 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA5_REASON,
1833 bcm->dma_reason[5]);
1874} 1834}
1875 1835
1876/* Interrupt handler top-half */ 1836/* Interrupt handler top-half */
@@ -1885,14 +1845,8 @@ static irqreturn_t bcm43xx_interrupt_handler(int irq, void *dev_id, struct pt_re
1885 1845
1886 spin_lock(&bcm->irq_lock); 1846 spin_lock(&bcm->irq_lock);
1887 1847
1888 /* Only accept IRQs, if we are initialized properly. 1848 assert(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED);
1889 * This avoids an RX race while initializing. 1849 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 1850
1897 reason = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); 1851 reason = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON);
1898 if (reason == 0xffffffff) { 1852 if (reason == 0xffffffff) {
@@ -1904,14 +1858,18 @@ static irqreturn_t bcm43xx_interrupt_handler(int irq, void *dev_id, struct pt_re
1904 if (!reason) 1858 if (!reason)
1905 goto out; 1859 goto out;
1906 1860
1907 bcm->dma_reason[0] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA1_REASON) 1861 bcm->dma_reason[0] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA0_REASON)
1908 & 0x0001dc00; 1862 & 0x0001DC00;
1909 bcm->dma_reason[1] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA2_REASON) 1863 bcm->dma_reason[1] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA1_REASON)
1910 & 0x0000dc00; 1864 & 0x0000DC00;
1911 bcm->dma_reason[2] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA3_REASON) 1865 bcm->dma_reason[2] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA2_REASON)
1912 & 0x0000dc00; 1866 & 0x0000DC00;
1913 bcm->dma_reason[3] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA4_REASON) 1867 bcm->dma_reason[3] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA3_REASON)
1914 & 0x0001dc00; 1868 & 0x0001DC00;
1869 bcm->dma_reason[4] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA4_REASON)
1870 & 0x0000DC00;
1871 bcm->dma_reason[5] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA5_REASON)
1872 & 0x0000DC00;
1915 1873
1916 bcm43xx_interrupt_ack(bcm, reason); 1874 bcm43xx_interrupt_ack(bcm, reason);
1917 1875
@@ -1930,16 +1888,18 @@ out:
1930 1888
1931static void bcm43xx_release_firmware(struct bcm43xx_private *bcm, int force) 1889static void bcm43xx_release_firmware(struct bcm43xx_private *bcm, int force)
1932{ 1890{
1891 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
1892
1933 if (bcm->firmware_norelease && !force) 1893 if (bcm->firmware_norelease && !force)
1934 return; /* Suspending or controller reset. */ 1894 return; /* Suspending or controller reset. */
1935 release_firmware(bcm->ucode); 1895 release_firmware(phy->ucode);
1936 bcm->ucode = NULL; 1896 phy->ucode = NULL;
1937 release_firmware(bcm->pcm); 1897 release_firmware(phy->pcm);
1938 bcm->pcm = NULL; 1898 phy->pcm = NULL;
1939 release_firmware(bcm->initvals0); 1899 release_firmware(phy->initvals0);
1940 bcm->initvals0 = NULL; 1900 phy->initvals0 = NULL;
1941 release_firmware(bcm->initvals1); 1901 release_firmware(phy->initvals1);
1942 bcm->initvals1 = NULL; 1902 phy->initvals1 = NULL;
1943} 1903}
1944 1904
1945static int bcm43xx_request_firmware(struct bcm43xx_private *bcm) 1905static int bcm43xx_request_firmware(struct bcm43xx_private *bcm)
@@ -1950,11 +1910,11 @@ static int bcm43xx_request_firmware(struct bcm43xx_private *bcm)
1950 int nr; 1910 int nr;
1951 char buf[22 + sizeof(modparam_fwpostfix) - 1] = { 0 }; 1911 char buf[22 + sizeof(modparam_fwpostfix) - 1] = { 0 };
1952 1912
1953 if (!bcm->ucode) { 1913 if (!phy->ucode) {
1954 snprintf(buf, ARRAY_SIZE(buf), "bcm43xx_microcode%d%s.fw", 1914 snprintf(buf, ARRAY_SIZE(buf), "bcm43xx_microcode%d%s.fw",
1955 (rev >= 5 ? 5 : rev), 1915 (rev >= 5 ? 5 : rev),
1956 modparam_fwpostfix); 1916 modparam_fwpostfix);
1957 err = request_firmware(&bcm->ucode, buf, &bcm->pci_dev->dev); 1917 err = request_firmware(&phy->ucode, buf, &bcm->pci_dev->dev);
1958 if (err) { 1918 if (err) {
1959 printk(KERN_ERR PFX 1919 printk(KERN_ERR PFX
1960 "Error: Microcode \"%s\" not available or load failed.\n", 1920 "Error: Microcode \"%s\" not available or load failed.\n",
@@ -1963,12 +1923,12 @@ static int bcm43xx_request_firmware(struct bcm43xx_private *bcm)
1963 } 1923 }
1964 } 1924 }
1965 1925
1966 if (!bcm->pcm) { 1926 if (!phy->pcm) {
1967 snprintf(buf, ARRAY_SIZE(buf), 1927 snprintf(buf, ARRAY_SIZE(buf),
1968 "bcm43xx_pcm%d%s.fw", 1928 "bcm43xx_pcm%d%s.fw",
1969 (rev < 5 ? 4 : 5), 1929 (rev < 5 ? 4 : 5),
1970 modparam_fwpostfix); 1930 modparam_fwpostfix);
1971 err = request_firmware(&bcm->pcm, buf, &bcm->pci_dev->dev); 1931 err = request_firmware(&phy->pcm, buf, &bcm->pci_dev->dev);
1972 if (err) { 1932 if (err) {
1973 printk(KERN_ERR PFX 1933 printk(KERN_ERR PFX
1974 "Error: PCM \"%s\" not available or load failed.\n", 1934 "Error: PCM \"%s\" not available or load failed.\n",
@@ -1977,7 +1937,7 @@ static int bcm43xx_request_firmware(struct bcm43xx_private *bcm)
1977 } 1937 }
1978 } 1938 }
1979 1939
1980 if (!bcm->initvals0) { 1940 if (!phy->initvals0) {
1981 if (rev == 2 || rev == 4) { 1941 if (rev == 2 || rev == 4) {
1982 switch (phy->type) { 1942 switch (phy->type) {
1983 case BCM43xx_PHYTYPE_A: 1943 case BCM43xx_PHYTYPE_A:
@@ -2008,20 +1968,20 @@ static int bcm43xx_request_firmware(struct bcm43xx_private *bcm)
2008 snprintf(buf, ARRAY_SIZE(buf), "bcm43xx_initval%02d%s.fw", 1968 snprintf(buf, ARRAY_SIZE(buf), "bcm43xx_initval%02d%s.fw",
2009 nr, modparam_fwpostfix); 1969 nr, modparam_fwpostfix);
2010 1970
2011 err = request_firmware(&bcm->initvals0, buf, &bcm->pci_dev->dev); 1971 err = request_firmware(&phy->initvals0, buf, &bcm->pci_dev->dev);
2012 if (err) { 1972 if (err) {
2013 printk(KERN_ERR PFX 1973 printk(KERN_ERR PFX
2014 "Error: InitVals \"%s\" not available or load failed.\n", 1974 "Error: InitVals \"%s\" not available or load failed.\n",
2015 buf); 1975 buf);
2016 goto error; 1976 goto error;
2017 } 1977 }
2018 if (bcm->initvals0->size % sizeof(struct bcm43xx_initval)) { 1978 if (phy->initvals0->size % sizeof(struct bcm43xx_initval)) {
2019 printk(KERN_ERR PFX "InitVals fileformat error.\n"); 1979 printk(KERN_ERR PFX "InitVals fileformat error.\n");
2020 goto error; 1980 goto error;
2021 } 1981 }
2022 } 1982 }
2023 1983
2024 if (!bcm->initvals1) { 1984 if (!phy->initvals1) {
2025 if (rev >= 5) { 1985 if (rev >= 5) {
2026 u32 sbtmstatehigh; 1986 u32 sbtmstatehigh;
2027 1987
@@ -2043,14 +2003,14 @@ static int bcm43xx_request_firmware(struct bcm43xx_private *bcm)
2043 snprintf(buf, ARRAY_SIZE(buf), "bcm43xx_initval%02d%s.fw", 2003 snprintf(buf, ARRAY_SIZE(buf), "bcm43xx_initval%02d%s.fw",
2044 nr, modparam_fwpostfix); 2004 nr, modparam_fwpostfix);
2045 2005
2046 err = request_firmware(&bcm->initvals1, buf, &bcm->pci_dev->dev); 2006 err = request_firmware(&phy->initvals1, buf, &bcm->pci_dev->dev);
2047 if (err) { 2007 if (err) {
2048 printk(KERN_ERR PFX 2008 printk(KERN_ERR PFX
2049 "Error: InitVals \"%s\" not available or load failed.\n", 2009 "Error: InitVals \"%s\" not available or load failed.\n",
2050 buf); 2010 buf);
2051 goto error; 2011 goto error;
2052 } 2012 }
2053 if (bcm->initvals1->size % sizeof(struct bcm43xx_initval)) { 2013 if (phy->initvals1->size % sizeof(struct bcm43xx_initval)) {
2054 printk(KERN_ERR PFX "InitVals fileformat error.\n"); 2014 printk(KERN_ERR PFX "InitVals fileformat error.\n");
2055 goto error; 2015 goto error;
2056 } 2016 }
@@ -2070,12 +2030,13 @@ err_noinitval:
2070 2030
2071static void bcm43xx_upload_microcode(struct bcm43xx_private *bcm) 2031static void bcm43xx_upload_microcode(struct bcm43xx_private *bcm)
2072{ 2032{
2033 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
2073 const u32 *data; 2034 const u32 *data;
2074 unsigned int i, len; 2035 unsigned int i, len;
2075 2036
2076 /* Upload Microcode. */ 2037 /* Upload Microcode. */
2077 data = (u32 *)(bcm->ucode->data); 2038 data = (u32 *)(phy->ucode->data);
2078 len = bcm->ucode->size / sizeof(u32); 2039 len = phy->ucode->size / sizeof(u32);
2079 bcm43xx_shm_control_word(bcm, BCM43xx_SHM_UCODE, 0x0000); 2040 bcm43xx_shm_control_word(bcm, BCM43xx_SHM_UCODE, 0x0000);
2080 for (i = 0; i < len; i++) { 2041 for (i = 0; i < len; i++) {
2081 bcm43xx_write32(bcm, BCM43xx_MMIO_SHM_DATA, 2042 bcm43xx_write32(bcm, BCM43xx_MMIO_SHM_DATA,
@@ -2084,8 +2045,8 @@ static void bcm43xx_upload_microcode(struct bcm43xx_private *bcm)
2084 } 2045 }
2085 2046
2086 /* Upload PCM data. */ 2047 /* Upload PCM data. */
2087 data = (u32 *)(bcm->pcm->data); 2048 data = (u32 *)(phy->pcm->data);
2088 len = bcm->pcm->size / sizeof(u32); 2049 len = phy->pcm->size / sizeof(u32);
2089 bcm43xx_shm_control_word(bcm, BCM43xx_SHM_PCM, 0x01ea); 2050 bcm43xx_shm_control_word(bcm, BCM43xx_SHM_PCM, 0x01ea);
2090 bcm43xx_write32(bcm, BCM43xx_MMIO_SHM_DATA, 0x00004000); 2051 bcm43xx_write32(bcm, BCM43xx_MMIO_SHM_DATA, 0x00004000);
2091 bcm43xx_shm_control_word(bcm, BCM43xx_SHM_PCM, 0x01eb); 2052 bcm43xx_shm_control_word(bcm, BCM43xx_SHM_PCM, 0x01eb);
@@ -2131,15 +2092,16 @@ err_format:
2131 2092
2132static int bcm43xx_upload_initvals(struct bcm43xx_private *bcm) 2093static int bcm43xx_upload_initvals(struct bcm43xx_private *bcm)
2133{ 2094{
2095 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
2134 int err; 2096 int err;
2135 2097
2136 err = bcm43xx_write_initvals(bcm, (struct bcm43xx_initval *)bcm->initvals0->data, 2098 err = bcm43xx_write_initvals(bcm, (struct bcm43xx_initval *)phy->initvals0->data,
2137 bcm->initvals0->size / sizeof(struct bcm43xx_initval)); 2099 phy->initvals0->size / sizeof(struct bcm43xx_initval));
2138 if (err) 2100 if (err)
2139 goto out; 2101 goto out;
2140 if (bcm->initvals1) { 2102 if (phy->initvals1) {
2141 err = bcm43xx_write_initvals(bcm, (struct bcm43xx_initval *)bcm->initvals1->data, 2103 err = bcm43xx_write_initvals(bcm, (struct bcm43xx_initval *)phy->initvals1->data,
2142 bcm->initvals1->size / sizeof(struct bcm43xx_initval)); 2104 phy->initvals1->size / sizeof(struct bcm43xx_initval));
2143 if (err) 2105 if (err)
2144 goto out; 2106 goto out;
2145 } 2107 }
@@ -2156,9 +2118,7 @@ static struct pci_device_id bcm43xx_47xx_ids[] = {
2156 2118
2157static int bcm43xx_initialize_irq(struct bcm43xx_private *bcm) 2119static int bcm43xx_initialize_irq(struct bcm43xx_private *bcm)
2158{ 2120{
2159 int res; 2121 int err;
2160 unsigned int i;
2161 u32 data;
2162 2122
2163 bcm->irq = bcm->pci_dev->irq; 2123 bcm->irq = bcm->pci_dev->irq;
2164#ifdef CONFIG_BCM947XX 2124#ifdef CONFIG_BCM947XX
@@ -2175,32 +2135,12 @@ static int bcm43xx_initialize_irq(struct bcm43xx_private *bcm)
2175 } 2135 }
2176 } 2136 }
2177#endif 2137#endif
2178 res = request_irq(bcm->irq, bcm43xx_interrupt_handler, 2138 err = request_irq(bcm->irq, bcm43xx_interrupt_handler,
2179 IRQF_SHARED, KBUILD_MODNAME, bcm); 2139 IRQF_SHARED, KBUILD_MODNAME, bcm);
2180 if (res) { 2140 if (err)
2181 printk(KERN_ERR PFX "Cannot register IRQ%d\n", bcm->irq); 2141 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 2142
2203 return 0; 2143 return err;
2204} 2144}
2205 2145
2206/* Switch to the core used to write the GPIO register. 2146/* Switch to the core used to write the GPIO register.
@@ -2298,13 +2238,17 @@ static int bcm43xx_gpio_cleanup(struct bcm43xx_private *bcm)
2298/* http://bcm-specs.sipsolutions.net/EnableMac */ 2238/* http://bcm-specs.sipsolutions.net/EnableMac */
2299void bcm43xx_mac_enable(struct bcm43xx_private *bcm) 2239void bcm43xx_mac_enable(struct bcm43xx_private *bcm)
2300{ 2240{
2301 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, 2241 bcm->mac_suspended--;
2302 bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD) 2242 assert(bcm->mac_suspended >= 0);
2303 | BCM43xx_SBF_MAC_ENABLED); 2243 if (bcm->mac_suspended == 0) {
2304 bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, BCM43xx_IRQ_READY); 2244 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD,
2305 bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); /* dummy read */ 2245 bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD)
2306 bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); /* dummy read */ 2246 | BCM43xx_SBF_MAC_ENABLED);
2307 bcm43xx_power_saving_ctl_bits(bcm, -1, -1); 2247 bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, BCM43xx_IRQ_READY);
2248 bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); /* dummy read */
2249 bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); /* dummy read */
2250 bcm43xx_power_saving_ctl_bits(bcm, -1, -1);
2251 }
2308} 2252}
2309 2253
2310/* http://bcm-specs.sipsolutions.net/SuspendMAC */ 2254/* http://bcm-specs.sipsolutions.net/SuspendMAC */
@@ -2313,18 +2257,23 @@ void bcm43xx_mac_suspend(struct bcm43xx_private *bcm)
2313 int i; 2257 int i;
2314 u32 tmp; 2258 u32 tmp;
2315 2259
2316 bcm43xx_power_saving_ctl_bits(bcm, -1, 1); 2260 assert(bcm->mac_suspended >= 0);
2317 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, 2261 if (bcm->mac_suspended == 0) {
2318 bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD) 2262 bcm43xx_power_saving_ctl_bits(bcm, -1, 1);
2319 & ~BCM43xx_SBF_MAC_ENABLED); 2263 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD,
2320 bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); /* dummy read */ 2264 bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD)
2321 for (i = 100000; i; i--) { 2265 & ~BCM43xx_SBF_MAC_ENABLED);
2322 tmp = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); 2266 bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); /* dummy read */
2323 if (tmp & BCM43xx_IRQ_READY) 2267 for (i = 10000; i; i--) {
2324 return; 2268 tmp = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON);
2325 udelay(10); 2269 if (tmp & BCM43xx_IRQ_READY)
2270 goto out;
2271 udelay(1);
2272 }
2273 printkl(KERN_ERR PFX "MAC suspend failed\n");
2326 } 2274 }
2327 printkl(KERN_ERR PFX "MAC suspend failed\n"); 2275out:
2276 bcm->mac_suspended++;
2328} 2277}
2329 2278
2330void bcm43xx_set_iwmode(struct bcm43xx_private *bcm, 2279void bcm43xx_set_iwmode(struct bcm43xx_private *bcm,
@@ -2394,7 +2343,6 @@ static void bcm43xx_chip_cleanup(struct bcm43xx_private *bcm)
2394 if (!modparam_noleds) 2343 if (!modparam_noleds)
2395 bcm43xx_leds_exit(bcm); 2344 bcm43xx_leds_exit(bcm);
2396 bcm43xx_gpio_cleanup(bcm); 2345 bcm43xx_gpio_cleanup(bcm);
2397 free_irq(bcm->irq, bcm);
2398 bcm43xx_release_firmware(bcm, 0); 2346 bcm43xx_release_firmware(bcm, 0);
2399} 2347}
2400 2348
@@ -2406,7 +2354,7 @@ static int bcm43xx_chip_init(struct bcm43xx_private *bcm)
2406 struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); 2354 struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
2407 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); 2355 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
2408 int err; 2356 int err;
2409 int tmp; 2357 int i, tmp;
2410 u32 value32; 2358 u32 value32;
2411 u16 value16; 2359 u16 value16;
2412 2360
@@ -2419,13 +2367,53 @@ static int bcm43xx_chip_init(struct bcm43xx_private *bcm)
2419 goto out; 2367 goto out;
2420 bcm43xx_upload_microcode(bcm); 2368 bcm43xx_upload_microcode(bcm);
2421 2369
2422 err = bcm43xx_initialize_irq(bcm); 2370 bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, 0xFFFFFFFF);
2423 if (err) 2371 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, 0x00020402);
2372 i = 0;
2373 while (1) {
2374 value32 = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON);
2375 if (value32 == BCM43xx_IRQ_READY)
2376 break;
2377 i++;
2378 if (i >= BCM43xx_IRQWAIT_MAX_RETRIES) {
2379 printk(KERN_ERR PFX "IRQ_READY timeout\n");
2380 err = -ENODEV;
2381 goto err_release_fw;
2382 }
2383 udelay(10);
2384 }
2385 bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); /* dummy read */
2386
2387 value16 = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED,
2388 BCM43xx_UCODE_REVISION);
2389
2390 dprintk(KERN_INFO PFX "Microcode rev 0x%x, pl 0x%x "
2391 "(20%.2i-%.2i-%.2i %.2i:%.2i:%.2i)\n", value16,
2392 bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED,
2393 BCM43xx_UCODE_PATCHLEVEL),
2394 (bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED,
2395 BCM43xx_UCODE_DATE) >> 12) & 0xf,
2396 (bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED,
2397 BCM43xx_UCODE_DATE) >> 8) & 0xf,
2398 bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED,
2399 BCM43xx_UCODE_DATE) & 0xff,
2400 (bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED,
2401 BCM43xx_UCODE_TIME) >> 11) & 0x1f,
2402 (bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED,
2403 BCM43xx_UCODE_TIME) >> 5) & 0x3f,
2404 bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED,
2405 BCM43xx_UCODE_TIME) & 0x1f);
2406
2407 if ( value16 > 0x128 ) {
2408 dprintk(KERN_ERR PFX
2409 "Firmware: no support for microcode rev > 0x128\n");
2410 err = -1;
2424 goto err_release_fw; 2411 goto err_release_fw;
2412 }
2425 2413
2426 err = bcm43xx_gpio_init(bcm); 2414 err = bcm43xx_gpio_init(bcm);
2427 if (err) 2415 if (err)
2428 goto err_free_irq; 2416 goto err_release_fw;
2429 2417
2430 err = bcm43xx_upload_initvals(bcm); 2418 err = bcm43xx_upload_initvals(bcm);
2431 if (err) 2419 if (err)
@@ -2489,10 +2477,12 @@ static int bcm43xx_chip_init(struct bcm43xx_private *bcm)
2489 bcm43xx_write32(bcm, 0x018C, 0x02000000); 2477 bcm43xx_write32(bcm, 0x018C, 0x02000000);
2490 } 2478 }
2491 bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, 0x00004000); 2479 bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, 0x00004000);
2492 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA1_IRQ_MASK, 0x0001DC00); 2480 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA0_IRQ_MASK, 0x0001DC00);
2481 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA1_IRQ_MASK, 0x0000DC00);
2493 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA2_IRQ_MASK, 0x0000DC00); 2482 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA2_IRQ_MASK, 0x0000DC00);
2494 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA3_IRQ_MASK, 0x0000DC00); 2483 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA3_IRQ_MASK, 0x0001DC00);
2495 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA4_IRQ_MASK, 0x0001DC00); 2484 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA4_IRQ_MASK, 0x0000DC00);
2485 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA5_IRQ_MASK, 0x0000DC00);
2496 2486
2497 value32 = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW); 2487 value32 = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
2498 value32 |= 0x00100000; 2488 value32 |= 0x00100000;
@@ -2509,8 +2499,6 @@ err_radio_off:
2509 bcm43xx_radio_turn_off(bcm); 2499 bcm43xx_radio_turn_off(bcm);
2510err_gpio_cleanup: 2500err_gpio_cleanup:
2511 bcm43xx_gpio_cleanup(bcm); 2501 bcm43xx_gpio_cleanup(bcm);
2512err_free_irq:
2513 free_irq(bcm->irq, bcm);
2514err_release_fw: 2502err_release_fw:
2515 bcm43xx_release_firmware(bcm, 1); 2503 bcm43xx_release_firmware(bcm, 1);
2516 goto out; 2504 goto out;
@@ -2550,11 +2538,9 @@ static void bcm43xx_init_struct_phyinfo(struct bcm43xx_phyinfo *phy)
2550{ 2538{
2551 /* Initialize a "phyinfo" structure. The structure is already 2539 /* Initialize a "phyinfo" structure. The structure is already
2552 * zeroed out. 2540 * zeroed out.
2541 * This is called on insmod time to initialize members.
2553 */ 2542 */
2554 phy->antenna_diversity = 0xFFFF;
2555 phy->savedpctlreg = 0xFFFF; 2543 phy->savedpctlreg = 0xFFFF;
2556 phy->minlowsig[0] = 0xFFFF;
2557 phy->minlowsig[1] = 0xFFFF;
2558 spin_lock_init(&phy->lock); 2544 spin_lock_init(&phy->lock);
2559} 2545}
2560 2546
@@ -2562,14 +2548,11 @@ static void bcm43xx_init_struct_radioinfo(struct bcm43xx_radioinfo *radio)
2562{ 2548{
2563 /* Initialize a "radioinfo" structure. The structure is already 2549 /* Initialize a "radioinfo" structure. The structure is already
2564 * zeroed out. 2550 * zeroed out.
2551 * This is called on insmod time to initialize members.
2565 */ 2552 */
2566 radio->interfmode = BCM43xx_RADIO_INTERFMODE_NONE; 2553 radio->interfmode = BCM43xx_RADIO_INTERFMODE_NONE;
2567 radio->channel = 0xFF; 2554 radio->channel = 0xFF;
2568 radio->initial_channel = 0xFF; 2555 radio->initial_channel = 0xFF;
2569 radio->lofcal = 0xFFFF;
2570 radio->initval = 0xFFFF;
2571 radio->nrssi[0] = -1000;
2572 radio->nrssi[1] = -1000;
2573} 2556}
2574 2557
2575static int bcm43xx_probe_cores(struct bcm43xx_private *bcm) 2558static int bcm43xx_probe_cores(struct bcm43xx_private *bcm)
@@ -2587,7 +2570,6 @@ static int bcm43xx_probe_cores(struct bcm43xx_private *bcm)
2587 * BCM43xx_MAX_80211_CORES); 2570 * BCM43xx_MAX_80211_CORES);
2588 memset(&bcm->core_80211_ext, 0, sizeof(struct bcm43xx_coreinfo_80211) 2571 memset(&bcm->core_80211_ext, 0, sizeof(struct bcm43xx_coreinfo_80211)
2589 * BCM43xx_MAX_80211_CORES); 2572 * BCM43xx_MAX_80211_CORES);
2590 bcm->current_80211_core_idx = -1;
2591 bcm->nr_80211_available = 0; 2573 bcm->nr_80211_available = 0;
2592 bcm->current_core = NULL; 2574 bcm->current_core = NULL;
2593 bcm->active_80211_core = NULL; 2575 bcm->active_80211_core = NULL;
@@ -2757,6 +2739,7 @@ static int bcm43xx_probe_cores(struct bcm43xx_private *bcm)
2757 goto out; 2739 goto out;
2758 } 2740 }
2759 bcm->nr_80211_available++; 2741 bcm->nr_80211_available++;
2742 core->priv = ext_80211;
2760 bcm43xx_init_struct_phyinfo(&ext_80211->phy); 2743 bcm43xx_init_struct_phyinfo(&ext_80211->phy);
2761 bcm43xx_init_struct_radioinfo(&ext_80211->radio); 2744 bcm43xx_init_struct_radioinfo(&ext_80211->radio);
2762 break; 2745 break;
@@ -2857,7 +2840,8 @@ static void bcm43xx_wireless_core_cleanup(struct bcm43xx_private *bcm)
2857} 2840}
2858 2841
2859/* http://bcm-specs.sipsolutions.net/80211Init */ 2842/* http://bcm-specs.sipsolutions.net/80211Init */
2860static int bcm43xx_wireless_core_init(struct bcm43xx_private *bcm) 2843static int bcm43xx_wireless_core_init(struct bcm43xx_private *bcm,
2844 int active_wlcore)
2861{ 2845{
2862 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); 2846 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
2863 struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); 2847 struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
@@ -2939,19 +2923,26 @@ static int bcm43xx_wireless_core_init(struct bcm43xx_private *bcm)
2939 if (bcm->current_core->rev >= 5) 2923 if (bcm->current_core->rev >= 5)
2940 bcm43xx_write16(bcm, 0x043C, 0x000C); 2924 bcm43xx_write16(bcm, 0x043C, 0x000C);
2941 2925
2942 if (bcm43xx_using_pio(bcm)) 2926 if (active_wlcore) {
2943 err = bcm43xx_pio_init(bcm); 2927 if (bcm43xx_using_pio(bcm))
2944 else 2928 err = bcm43xx_pio_init(bcm);
2945 err = bcm43xx_dma_init(bcm); 2929 else
2946 if (err) 2930 err = bcm43xx_dma_init(bcm);
2947 goto err_chip_cleanup; 2931 if (err)
2932 goto err_chip_cleanup;
2933 }
2948 bcm43xx_write16(bcm, 0x0612, 0x0050); 2934 bcm43xx_write16(bcm, 0x0612, 0x0050);
2949 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0416, 0x0050); 2935 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0416, 0x0050);
2950 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0414, 0x01F4); 2936 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0414, 0x01F4);
2951 2937
2952 bcm43xx_mac_enable(bcm); 2938 if (active_wlcore) {
2953 bcm43xx_interrupt_enable(bcm, bcm->irq_savedstate); 2939 if (radio->initial_channel != 0xFF)
2940 bcm43xx_radio_selectchannel(bcm, radio->initial_channel, 0);
2941 }
2954 2942
2943 /* Don't enable MAC/IRQ here, as it will race with the IRQ handler.
2944 * We enable it later.
2945 */
2955 bcm->current_core->initialized = 1; 2946 bcm->current_core->initialized = 1;
2956out: 2947out:
2957 return err; 2948 return err;
@@ -3066,11 +3057,6 @@ out:
3066 return err; 3057 return err;
3067} 3058}
3068 3059
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) 3060static void bcm43xx_periodic_every120sec(struct bcm43xx_private *bcm)
3075{ 3061{
3076 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); 3062 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
@@ -3182,47 +3168,46 @@ static void bcm43xx_periodic_work_handler(void *d)
3182 /* Periodic work will take a long time, so we want it to 3168 /* Periodic work will take a long time, so we want it to
3183 * be preemtible. 3169 * be preemtible.
3184 */ 3170 */
3185 bcm43xx_lock_irqonly(bcm, flags); 3171 mutex_lock(&bcm->mutex);
3186 netif_stop_queue(bcm->net_dev); 3172 netif_stop_queue(bcm->net_dev);
3173 synchronize_net();
3174 spin_lock_irqsave(&bcm->irq_lock, flags);
3175 bcm43xx_mac_suspend(bcm);
3187 if (bcm43xx_using_pio(bcm)) 3176 if (bcm43xx_using_pio(bcm))
3188 bcm43xx_pio_freeze_txqueues(bcm); 3177 bcm43xx_pio_freeze_txqueues(bcm);
3189 savedirqs = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL); 3178 savedirqs = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
3190 bcm43xx_unlock_irqonly(bcm, flags); 3179 spin_unlock_irqrestore(&bcm->irq_lock, flags);
3191 bcm43xx_lock_noirq(bcm);
3192 bcm43xx_synchronize_irq(bcm); 3180 bcm43xx_synchronize_irq(bcm);
3193 } else { 3181 } else {
3194 /* Periodic work should take short time, so we want low 3182 /* Periodic work should take short time, so we want low
3195 * locking overhead. 3183 * locking overhead.
3196 */ 3184 */
3197 bcm43xx_lock_irqsafe(bcm, flags); 3185 mutex_lock(&bcm->mutex);
3186 spin_lock_irqsave(&bcm->irq_lock, flags);
3198 } 3187 }
3199 3188
3200 do_periodic_work(bcm); 3189 do_periodic_work(bcm);
3201 3190
3202 if (badness > BADNESS_LIMIT) { 3191 if (badness > BADNESS_LIMIT) {
3203 bcm43xx_lock_irqonly(bcm, flags); 3192 spin_lock_irqsave(&bcm->irq_lock, flags);
3204 if (likely(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED)) { 3193 tasklet_enable(&bcm->isr_tasklet);
3205 tasklet_enable(&bcm->isr_tasklet); 3194 bcm43xx_interrupt_enable(bcm, savedirqs);
3206 bcm43xx_interrupt_enable(bcm, savedirqs); 3195 if (bcm43xx_using_pio(bcm))
3207 if (bcm43xx_using_pio(bcm)) 3196 bcm43xx_pio_thaw_txqueues(bcm);
3208 bcm43xx_pio_thaw_txqueues(bcm); 3197 bcm43xx_mac_enable(bcm);
3209 }
3210 netif_wake_queue(bcm->net_dev); 3198 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 } 3199 }
3200 mmiowb();
3201 spin_unlock_irqrestore(&bcm->irq_lock, flags);
3202 mutex_unlock(&bcm->mutex);
3218} 3203}
3219 3204
3220static void bcm43xx_periodic_tasks_delete(struct bcm43xx_private *bcm) 3205void bcm43xx_periodic_tasks_delete(struct bcm43xx_private *bcm)
3221{ 3206{
3222 cancel_rearming_delayed_work(&bcm->periodic_work); 3207 cancel_rearming_delayed_work(&bcm->periodic_work);
3223} 3208}
3224 3209
3225static void bcm43xx_periodic_tasks_setup(struct bcm43xx_private *bcm) 3210void bcm43xx_periodic_tasks_setup(struct bcm43xx_private *bcm)
3226{ 3211{
3227 struct work_struct *work = &(bcm->periodic_work); 3212 struct work_struct *work = &(bcm->periodic_work);
3228 3213
@@ -3243,9 +3228,9 @@ static int bcm43xx_rng_read(struct hwrng *rng, u32 *data)
3243 struct bcm43xx_private *bcm = (struct bcm43xx_private *)rng->priv; 3228 struct bcm43xx_private *bcm = (struct bcm43xx_private *)rng->priv;
3244 unsigned long flags; 3229 unsigned long flags;
3245 3230
3246 bcm43xx_lock_irqonly(bcm, flags); 3231 spin_lock_irqsave(&(bcm)->irq_lock, flags);
3247 *data = bcm43xx_read16(bcm, BCM43xx_MMIO_RNG); 3232 *data = bcm43xx_read16(bcm, BCM43xx_MMIO_RNG);
3248 bcm43xx_unlock_irqonly(bcm, flags); 3233 spin_unlock_irqrestore(&(bcm)->irq_lock, flags);
3249 3234
3250 return (sizeof(u16)); 3235 return (sizeof(u16));
3251} 3236}
@@ -3271,139 +3256,329 @@ static int bcm43xx_rng_init(struct bcm43xx_private *bcm)
3271 return err; 3256 return err;
3272} 3257}
3273 3258
3274/* This is the opposite of bcm43xx_init_board() */ 3259static int bcm43xx_shutdown_all_wireless_cores(struct bcm43xx_private *bcm)
3275static void bcm43xx_free_board(struct bcm43xx_private *bcm)
3276{ 3260{
3261 int ret = 0;
3277 int i, err; 3262 int i, err;
3263 struct bcm43xx_coreinfo *core;
3278 3264
3279 bcm43xx_lock_noirq(bcm); 3265 bcm43xx_set_status(bcm, BCM43xx_STAT_SHUTTINGDOWN);
3266 for (i = 0; i < bcm->nr_80211_available; i++) {
3267 core = &(bcm->core_80211[i]);
3268 assert(core->available);
3269 if (!core->initialized)
3270 continue;
3271 err = bcm43xx_switch_core(bcm, core);
3272 if (err) {
3273 dprintk(KERN_ERR PFX "shutdown_all_wireless_cores "
3274 "switch_core failed (%d)\n", err);
3275 ret = err;
3276 continue;
3277 }
3278 bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
3279 bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); /* dummy read */
3280 bcm43xx_wireless_core_cleanup(bcm);
3281 if (core == bcm->active_80211_core)
3282 bcm->active_80211_core = NULL;
3283 }
3284 free_irq(bcm->irq, bcm);
3285 bcm43xx_set_status(bcm, BCM43xx_STAT_UNINIT);
3286
3287 return ret;
3288}
3289
3290/* This is the opposite of bcm43xx_init_board() */
3291static void bcm43xx_free_board(struct bcm43xx_private *bcm)
3292{
3293 bcm43xx_rng_exit(bcm);
3280 bcm43xx_sysfs_unregister(bcm); 3294 bcm43xx_sysfs_unregister(bcm);
3281 bcm43xx_periodic_tasks_delete(bcm); 3295 bcm43xx_periodic_tasks_delete(bcm);
3282 3296
3283 bcm43xx_set_status(bcm, BCM43xx_STAT_SHUTTINGDOWN); 3297 mutex_lock(&(bcm)->mutex);
3298 bcm43xx_shutdown_all_wireless_cores(bcm);
3299 bcm43xx_pctl_set_crystal(bcm, 0);
3300 mutex_unlock(&(bcm)->mutex);
3301}
3284 3302
3285 bcm43xx_rng_exit(bcm); 3303static void prepare_phydata_for_init(struct bcm43xx_phyinfo *phy)
3304{
3305 phy->antenna_diversity = 0xFFFF;
3306 memset(phy->minlowsig, 0xFF, sizeof(phy->minlowsig));
3307 memset(phy->minlowsigpos, 0, sizeof(phy->minlowsigpos));
3308
3309 /* Flags */
3310 phy->calibrated = 0;
3311 phy->is_locked = 0;
3312
3313 if (phy->_lo_pairs) {
3314 memset(phy->_lo_pairs, 0,
3315 sizeof(struct bcm43xx_lopair) * BCM43xx_LO_COUNT);
3316 }
3317 memset(phy->loopback_gain, 0, sizeof(phy->loopback_gain));
3318}
3319
3320static void prepare_radiodata_for_init(struct bcm43xx_private *bcm,
3321 struct bcm43xx_radioinfo *radio)
3322{
3323 int i;
3324
3325 /* Set default attenuation values. */
3326 radio->baseband_atten = bcm43xx_default_baseband_attenuation(bcm);
3327 radio->radio_atten = bcm43xx_default_radio_attenuation(bcm);
3328 radio->txctl1 = bcm43xx_default_txctl1(bcm);
3329 radio->txctl2 = 0xFFFF;
3330 radio->txpwr_offset = 0;
3331
3332 /* NRSSI */
3333 radio->nrssislope = 0;
3334 for (i = 0; i < ARRAY_SIZE(radio->nrssi); i++)
3335 radio->nrssi[i] = -1000;
3336 for (i = 0; i < ARRAY_SIZE(radio->nrssi_lt); i++)
3337 radio->nrssi_lt[i] = i;
3338
3339 radio->lofcal = 0xFFFF;
3340 radio->initval = 0xFFFF;
3341
3342 radio->aci_enable = 0;
3343 radio->aci_wlan_automatic = 0;
3344 radio->aci_hw_rssi = 0;
3345}
3346
3347static void prepare_priv_for_init(struct bcm43xx_private *bcm)
3348{
3349 int i;
3350 struct bcm43xx_coreinfo *core;
3351 struct bcm43xx_coreinfo_80211 *wlext;
3352
3353 assert(!bcm->active_80211_core);
3354
3355 bcm43xx_set_status(bcm, BCM43xx_STAT_INITIALIZING);
3356
3357 /* Flags */
3358 bcm->was_initialized = 0;
3359 bcm->reg124_set_0x4 = 0;
3360
3361 /* Stats */
3362 memset(&bcm->stats, 0, sizeof(bcm->stats));
3363
3364 /* Wireless core data */
3286 for (i = 0; i < BCM43xx_MAX_80211_CORES; i++) { 3365 for (i = 0; i < BCM43xx_MAX_80211_CORES; i++) {
3287 if (!bcm->core_80211[i].available) 3366 core = &(bcm->core_80211[i]);
3288 continue; 3367 wlext = core->priv;
3289 if (!bcm->core_80211[i].initialized) 3368
3369 if (!core->available)
3290 continue; 3370 continue;
3371 assert(wlext == &(bcm->core_80211_ext[i]));
3291 3372
3292 err = bcm43xx_switch_core(bcm, &bcm->core_80211[i]); 3373 prepare_phydata_for_init(&wlext->phy);
3293 assert(err == 0); 3374 prepare_radiodata_for_init(bcm, &wlext->radio);
3294 bcm43xx_wireless_core_cleanup(bcm);
3295 } 3375 }
3296 3376
3297 bcm43xx_pctl_set_crystal(bcm, 0); 3377 /* IRQ related flags */
3378 bcm->irq_reason = 0;
3379 memset(bcm->dma_reason, 0, sizeof(bcm->dma_reason));
3380 bcm->irq_savedstate = BCM43xx_IRQ_INITIAL;
3298 3381
3299 bcm43xx_set_status(bcm, BCM43xx_STAT_UNINIT); 3382 bcm->mac_suspended = 1;
3300 bcm43xx_unlock_noirq(bcm); 3383
3384 /* Noise calculation context */
3385 memset(&bcm->noisecalc, 0, sizeof(bcm->noisecalc));
3386
3387 /* Periodic work context */
3388 bcm->periodic_state = 0;
3301} 3389}
3302 3390
3303static int bcm43xx_init_board(struct bcm43xx_private *bcm) 3391static int wireless_core_up(struct bcm43xx_private *bcm,
3392 int active_wlcore)
3393{
3394 int err;
3395
3396 if (!bcm43xx_core_enabled(bcm))
3397 bcm43xx_wireless_core_reset(bcm, 1);
3398 if (!active_wlcore)
3399 bcm43xx_wireless_core_mark_inactive(bcm);
3400 err = bcm43xx_wireless_core_init(bcm, active_wlcore);
3401 if (err)
3402 goto out;
3403 if (!active_wlcore)
3404 bcm43xx_radio_turn_off(bcm);
3405out:
3406 return err;
3407}
3408
3409/* Select and enable the "to be used" wireless core.
3410 * Locking: bcm->mutex must be aquired before calling this.
3411 * bcm->irq_lock must not be aquired.
3412 */
3413int bcm43xx_select_wireless_core(struct bcm43xx_private *bcm,
3414 int phytype)
3304{ 3415{
3305 int i, err; 3416 int i, err;
3306 int connect_phy; 3417 struct bcm43xx_coreinfo *active_core = NULL;
3418 struct bcm43xx_coreinfo_80211 *active_wlext = NULL;
3419 struct bcm43xx_coreinfo *core;
3420 struct bcm43xx_coreinfo_80211 *wlext;
3421 int adjust_active_sbtmstatelow = 0;
3307 3422
3308 might_sleep(); 3423 might_sleep();
3309 3424
3310 bcm43xx_lock_noirq(bcm); 3425 if (phytype < 0) {
3311 bcm43xx_set_status(bcm, BCM43xx_STAT_INITIALIZING); 3426 /* If no phytype is requested, select the first core. */
3427 assert(bcm->core_80211[0].available);
3428 wlext = bcm->core_80211[0].priv;
3429 phytype = wlext->phy.type;
3430 }
3431 /* Find the requested core. */
3432 for (i = 0; i < bcm->nr_80211_available; i++) {
3433 core = &(bcm->core_80211[i]);
3434 wlext = core->priv;
3435 if (wlext->phy.type == phytype) {
3436 active_core = core;
3437 active_wlext = wlext;
3438 break;
3439 }
3440 }
3441 if (!active_core)
3442 return -ESRCH; /* No such PHYTYPE on this board. */
3443
3444 if (bcm->active_80211_core) {
3445 /* We already selected a wl core in the past.
3446 * So first clean up everything.
3447 */
3448 dprintk(KERN_INFO PFX "select_wireless_core: cleanup\n");
3449 ieee80211softmac_stop(bcm->net_dev);
3450 bcm43xx_set_status(bcm, BCM43xx_STAT_INITIALIZED);
3451 err = bcm43xx_disable_interrupts_sync(bcm);
3452 assert(!err);
3453 tasklet_enable(&bcm->isr_tasklet);
3454 err = bcm43xx_shutdown_all_wireless_cores(bcm);
3455 if (err)
3456 goto error;
3457 /* Ok, everything down, continue to re-initialize. */
3458 bcm43xx_set_status(bcm, BCM43xx_STAT_INITIALIZING);
3459 }
3460
3461 /* Reset all data structures. */
3462 prepare_priv_for_init(bcm);
3312 3463
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); 3464 err = bcm43xx_pctl_set_clock(bcm, BCM43xx_PCTL_CLK_FAST);
3320 if (err) 3465 if (err)
3321 goto err_crystal_off; 3466 goto error;
3322 3467
3323 tasklet_enable(&bcm->isr_tasklet); 3468 /* Mark all unused cores "inactive". */
3324 for (i = 0; i < bcm->nr_80211_available; i++) { 3469 for (i = 0; i < bcm->nr_80211_available; i++) {
3325 err = bcm43xx_switch_core(bcm, &bcm->core_80211[i]); 3470 core = &(bcm->core_80211[i]);
3326 assert(err != -ENODEV); 3471 wlext = core->priv;
3327 if (err)
3328 goto err_80211_unwind;
3329 3472
3330 /* Enable the selected wireless core. 3473 if (core == active_core)
3331 * Connect PHY only on the first core. 3474 continue;
3332 */ 3475 err = bcm43xx_switch_core(bcm, core);
3333 if (!bcm43xx_core_enabled(bcm)) { 3476 if (err) {
3334 if (bcm->nr_80211_available == 1) { 3477 dprintk(KERN_ERR PFX "Could not switch to inactive "
3335 connect_phy = bcm43xx_current_phy(bcm)->connected; 3478 "802.11 core (%d)\n", err);
3336 } else { 3479 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 } 3480 }
3481 err = wireless_core_up(bcm, 0);
3482 if (err) {
3483 dprintk(KERN_ERR PFX "core_up for inactive 802.11 core "
3484 "failed (%d)\n", err);
3485 goto error;
3486 }
3487 adjust_active_sbtmstatelow = 1;
3488 }
3344 3489
3345 if (i != 0) 3490 /* Now initialize the active 802.11 core. */
3346 bcm43xx_wireless_core_mark_inactive(bcm, &bcm->core_80211[0]); 3491 err = bcm43xx_switch_core(bcm, active_core);
3347 3492 if (err) {
3348 err = bcm43xx_wireless_core_init(bcm); 3493 dprintk(KERN_ERR PFX "Could not switch to active "
3349 if (err) 3494 "802.11 core (%d)\n", err);
3350 goto err_80211_unwind; 3495 goto error;
3496 }
3497 if (adjust_active_sbtmstatelow &&
3498 active_wlext->phy.type == BCM43xx_PHYTYPE_G) {
3499 u32 sbtmstatelow;
3351 3500
3352 if (i != 0) { 3501 sbtmstatelow = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
3353 bcm43xx_mac_suspend(bcm); 3502 sbtmstatelow |= 0x20000000;
3354 bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL); 3503 bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
3355 bcm43xx_radio_turn_off(bcm);
3356 }
3357 } 3504 }
3358 bcm->active_80211_core = &bcm->core_80211[0]; 3505 err = wireless_core_up(bcm, 1);
3359 if (bcm->nr_80211_available >= 2) { 3506 if (err) {
3360 bcm43xx_switch_core(bcm, &bcm->core_80211[0]); 3507 dprintk(KERN_ERR PFX "core_up for active 802.11 core "
3361 bcm43xx_mac_enable(bcm); 3508 "failed (%d)\n", err);
3509 goto error;
3362 } 3510 }
3363 err = bcm43xx_rng_init(bcm); 3511 err = bcm43xx_pctl_set_clock(bcm, BCM43xx_PCTL_CLK_DYNAMIC);
3364 if (err) 3512 if (err)
3365 goto err_80211_unwind; 3513 goto error;
3514 bcm->active_80211_core = active_core;
3515
3366 bcm43xx_macfilter_clear(bcm, BCM43xx_MACFILTER_ASSOC); 3516 bcm43xx_macfilter_clear(bcm, BCM43xx_MACFILTER_ASSOC);
3367 bcm43xx_macfilter_set(bcm, BCM43xx_MACFILTER_SELF, (u8 *)(bcm->net_dev->dev_addr)); 3517 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); 3518 bcm43xx_security_init(bcm);
3370 bcm43xx_softmac_init(bcm); 3519 ieee80211softmac_start(bcm->net_dev);
3371 3520
3372 bcm43xx_pctl_set_clock(bcm, BCM43xx_PCTL_CLK_DYNAMIC); 3521 /* Let's go! Be careful after enabling the IRQs.
3522 * Don't switch cores, for example.
3523 */
3524 bcm43xx_mac_enable(bcm);
3525 bcm43xx_set_status(bcm, BCM43xx_STAT_INITIALIZED);
3526 err = bcm43xx_initialize_irq(bcm);
3527 if (err)
3528 goto error;
3529 bcm43xx_interrupt_enable(bcm, bcm->irq_savedstate);
3373 3530
3374 if (bcm43xx_current_radio(bcm)->initial_channel != 0xFF) { 3531 dprintk(KERN_INFO PFX "Selected 802.11 core (phytype %d)\n",
3375 bcm43xx_mac_suspend(bcm); 3532 active_wlext->phy.type);
3376 bcm43xx_radio_selectchannel(bcm, bcm43xx_current_radio(bcm)->initial_channel, 0);
3377 bcm43xx_mac_enable(bcm);
3378 }
3379 3533
3380 /* Initialization of the board is done. Flag it as such. */ 3534 return 0;
3381 bcm43xx_set_status(bcm, BCM43xx_STAT_INITIALIZED); 3535
3536error:
3537 bcm43xx_set_status(bcm, BCM43xx_STAT_UNINIT);
3538 bcm43xx_pctl_set_clock(bcm, BCM43xx_PCTL_CLK_SLOW);
3539 return err;
3540}
3382 3541
3542static int bcm43xx_init_board(struct bcm43xx_private *bcm)
3543{
3544 int err;
3545
3546 mutex_lock(&(bcm)->mutex);
3547
3548 tasklet_enable(&bcm->isr_tasklet);
3549 err = bcm43xx_pctl_set_crystal(bcm, 1);
3550 if (err)
3551 goto err_tasklet;
3552 err = bcm43xx_pctl_init(bcm);
3553 if (err)
3554 goto err_crystal_off;
3555 err = bcm43xx_select_wireless_core(bcm, -1);
3556 if (err)
3557 goto err_crystal_off;
3558 err = bcm43xx_sysfs_register(bcm);
3559 if (err)
3560 goto err_wlshutdown;
3561 err = bcm43xx_rng_init(bcm);
3562 if (err)
3563 goto err_sysfs_unreg;
3383 bcm43xx_periodic_tasks_setup(bcm); 3564 bcm43xx_periodic_tasks_setup(bcm);
3384 bcm43xx_sysfs_register(bcm);
3385 //FIXME: check for bcm43xx_sysfs_register failure. This function is a bit messy regarding unwinding, though...
3386 3565
3387 /*FIXME: This should be handled by softmac instead. */ 3566 /*FIXME: This should be handled by softmac instead. */
3388 schedule_work(&bcm->softmac->associnfo.work); 3567 schedule_work(&bcm->softmac->associnfo.work);
3389 3568
3390 assert(err == 0);
3391out: 3569out:
3392 bcm43xx_unlock_noirq(bcm); 3570 mutex_unlock(&(bcm)->mutex);
3393 3571
3394 return err; 3572 return err;
3395 3573
3396err_80211_unwind: 3574err_sysfs_unreg:
3397 tasklet_disable(&bcm->isr_tasklet); 3575 bcm43xx_sysfs_unregister(bcm);
3398 /* unwind all 80211 initialization */ 3576err_wlshutdown:
3399 for (i = 0; i < bcm->nr_80211_available; i++) { 3577 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: 3578err_crystal_off:
3406 bcm43xx_pctl_set_crystal(bcm, 0); 3579 bcm43xx_pctl_set_crystal(bcm, 0);
3580err_tasklet:
3581 tasklet_disable(&bcm->isr_tasklet);
3407 goto out; 3582 goto out;
3408} 3583}
3409 3584
@@ -3647,7 +3822,8 @@ static void bcm43xx_ieee80211_set_chan(struct net_device *net_dev,
3647 struct bcm43xx_radioinfo *radio; 3822 struct bcm43xx_radioinfo *radio;
3648 unsigned long flags; 3823 unsigned long flags;
3649 3824
3650 bcm43xx_lock_irqsafe(bcm, flags); 3825 mutex_lock(&bcm->mutex);
3826 spin_lock_irqsave(&bcm->irq_lock, flags);
3651 if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) { 3827 if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) {
3652 bcm43xx_mac_suspend(bcm); 3828 bcm43xx_mac_suspend(bcm);
3653 bcm43xx_radio_selectchannel(bcm, channel, 0); 3829 bcm43xx_radio_selectchannel(bcm, channel, 0);
@@ -3656,7 +3832,8 @@ static void bcm43xx_ieee80211_set_chan(struct net_device *net_dev,
3656 radio = bcm43xx_current_radio(bcm); 3832 radio = bcm43xx_current_radio(bcm);
3657 radio->initial_channel = channel; 3833 radio->initial_channel = channel;
3658 } 3834 }
3659 bcm43xx_unlock_irqsafe(bcm, flags); 3835 spin_unlock_irqrestore(&bcm->irq_lock, flags);
3836 mutex_unlock(&bcm->mutex);
3660} 3837}
3661 3838
3662/* set_security() callback in struct ieee80211_device */ 3839/* set_security() callback in struct ieee80211_device */
@@ -3670,7 +3847,8 @@ static void bcm43xx_ieee80211_set_security(struct net_device *net_dev,
3670 3847
3671 dprintk(KERN_INFO PFX "set security called"); 3848 dprintk(KERN_INFO PFX "set security called");
3672 3849
3673 bcm43xx_lock_irqsafe(bcm, flags); 3850 mutex_lock(&bcm->mutex);
3851 spin_lock_irqsave(&bcm->irq_lock, flags);
3674 3852
3675 for (keyidx = 0; keyidx<WEP_KEYS; keyidx++) 3853 for (keyidx = 0; keyidx<WEP_KEYS; keyidx++)
3676 if (sec->flags & (1<<keyidx)) { 3854 if (sec->flags & (1<<keyidx)) {
@@ -3739,7 +3917,8 @@ static void bcm43xx_ieee80211_set_security(struct net_device *net_dev,
3739 } else 3917 } else
3740 bcm43xx_clear_keys(bcm); 3918 bcm43xx_clear_keys(bcm);
3741 } 3919 }
3742 bcm43xx_unlock_irqsafe(bcm, flags); 3920 spin_unlock_irqrestore(&bcm->irq_lock, flags);
3921 mutex_unlock(&bcm->mutex);
3743} 3922}
3744 3923
3745/* hard_start_xmit() callback in struct ieee80211_device */ 3924/* hard_start_xmit() callback in struct ieee80211_device */
@@ -3751,12 +3930,14 @@ static int bcm43xx_ieee80211_hard_start_xmit(struct ieee80211_txb *txb,
3751 int err = -ENODEV; 3930 int err = -ENODEV;
3752 unsigned long flags; 3931 unsigned long flags;
3753 3932
3754 bcm43xx_lock_irqonly(bcm, flags); 3933 spin_lock_irqsave(&bcm->irq_lock, flags);
3755 if (likely(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED)) 3934 if (likely(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED))
3756 err = bcm43xx_tx(bcm, txb); 3935 err = bcm43xx_tx(bcm, txb);
3757 bcm43xx_unlock_irqonly(bcm, flags); 3936 spin_unlock_irqrestore(&bcm->irq_lock, flags);
3758 3937
3759 return err; 3938 if (unlikely(err))
3939 return NETDEV_TX_BUSY;
3940 return NETDEV_TX_OK;
3760} 3941}
3761 3942
3762static struct net_device_stats * bcm43xx_net_get_stats(struct net_device *net_dev) 3943static struct net_device_stats * bcm43xx_net_get_stats(struct net_device *net_dev)
@@ -3769,9 +3950,9 @@ static void bcm43xx_net_tx_timeout(struct net_device *net_dev)
3769 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); 3950 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
3770 unsigned long flags; 3951 unsigned long flags;
3771 3952
3772 bcm43xx_lock_irqonly(bcm, flags); 3953 spin_lock_irqsave(&bcm->irq_lock, flags);
3773 bcm43xx_controller_restart(bcm, "TX timeout"); 3954 bcm43xx_controller_restart(bcm, "TX timeout");
3774 bcm43xx_unlock_irqonly(bcm, flags); 3955 spin_unlock_irqrestore(&bcm->irq_lock, flags);
3775} 3956}
3776 3957
3777#ifdef CONFIG_NET_POLL_CONTROLLER 3958#ifdef CONFIG_NET_POLL_CONTROLLER
@@ -3781,7 +3962,8 @@ static void bcm43xx_net_poll_controller(struct net_device *net_dev)
3781 unsigned long flags; 3962 unsigned long flags;
3782 3963
3783 local_irq_save(flags); 3964 local_irq_save(flags);
3784 bcm43xx_interrupt_handler(bcm->irq, bcm, NULL); 3965 if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED)
3966 bcm43xx_interrupt_handler(bcm->irq, bcm, NULL);
3785 local_irq_restore(flags); 3967 local_irq_restore(flags);
3786} 3968}
3787#endif /* CONFIG_NET_POLL_CONTROLLER */ 3969#endif /* CONFIG_NET_POLL_CONTROLLER */
@@ -3799,9 +3981,10 @@ static int bcm43xx_net_stop(struct net_device *net_dev)
3799 int err; 3981 int err;
3800 3982
3801 ieee80211softmac_stop(net_dev); 3983 ieee80211softmac_stop(net_dev);
3802 err = bcm43xx_disable_interrupts_sync(bcm, NULL); 3984 err = bcm43xx_disable_interrupts_sync(bcm);
3803 assert(!err); 3985 assert(!err);
3804 bcm43xx_free_board(bcm); 3986 bcm43xx_free_board(bcm);
3987 flush_scheduled_work();
3805 3988
3806 return 0; 3989 return 0;
3807} 3990}
@@ -3818,10 +4001,12 @@ static int bcm43xx_init_private(struct bcm43xx_private *bcm,
3818 bcm->softmac->set_channel = bcm43xx_ieee80211_set_chan; 4001 bcm->softmac->set_channel = bcm43xx_ieee80211_set_chan;
3819 4002
3820 bcm->irq_savedstate = BCM43xx_IRQ_INITIAL; 4003 bcm->irq_savedstate = BCM43xx_IRQ_INITIAL;
4004 bcm->mac_suspended = 1;
3821 bcm->pci_dev = pci_dev; 4005 bcm->pci_dev = pci_dev;
3822 bcm->net_dev = net_dev; 4006 bcm->net_dev = net_dev;
3823 bcm->bad_frames_preempt = modparam_bad_frames_preempt; 4007 bcm->bad_frames_preempt = modparam_bad_frames_preempt;
3824 spin_lock_init(&bcm->irq_lock); 4008 spin_lock_init(&bcm->irq_lock);
4009 spin_lock_init(&bcm->leds_lock);
3825 mutex_init(&bcm->mutex); 4010 mutex_init(&bcm->mutex);
3826 tasklet_init(&bcm->isr_tasklet, 4011 tasklet_init(&bcm->isr_tasklet,
3827 (void (*)(unsigned long))bcm43xx_interrupt_tasklet, 4012 (void (*)(unsigned long))bcm43xx_interrupt_tasklet,
@@ -3940,7 +4125,6 @@ static void __devexit bcm43xx_remove_one(struct pci_dev *pdev)
3940 bcm43xx_debugfs_remove_device(bcm); 4125 bcm43xx_debugfs_remove_device(bcm);
3941 unregister_netdev(net_dev); 4126 unregister_netdev(net_dev);
3942 bcm43xx_detach_board(bcm); 4127 bcm43xx_detach_board(bcm);
3943 assert(bcm->ucode == NULL);
3944 free_ieee80211softmac(net_dev); 4128 free_ieee80211softmac(net_dev);
3945} 4129}
3946 4130
@@ -3950,47 +4134,31 @@ static void __devexit bcm43xx_remove_one(struct pci_dev *pdev)
3950static void bcm43xx_chip_reset(void *_bcm) 4134static void bcm43xx_chip_reset(void *_bcm)
3951{ 4135{
3952 struct bcm43xx_private *bcm = _bcm; 4136 struct bcm43xx_private *bcm = _bcm;
3953 struct net_device *net_dev = bcm->net_dev; 4137 struct bcm43xx_phyinfo *phy;
3954 struct pci_dev *pci_dev = bcm->pci_dev; 4138 int err = -ENODEV;
3955 int err;
3956 int was_initialized = (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED);
3957
3958 netif_stop_queue(bcm->net_dev);
3959 tasklet_disable(&bcm->isr_tasklet);
3960 4139
3961 bcm->firmware_norelease = 1; 4140 mutex_lock(&(bcm)->mutex);
3962 if (was_initialized) 4141 if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) {
3963 bcm43xx_free_board(bcm); 4142 bcm43xx_periodic_tasks_delete(bcm);
3964 bcm->firmware_norelease = 0; 4143 phy = bcm43xx_current_phy(bcm);
3965 bcm43xx_detach_board(bcm); 4144 err = bcm43xx_select_wireless_core(bcm, phy->type);
3966 err = bcm43xx_init_private(bcm, net_dev, pci_dev); 4145 if (!err)
3967 if (err) 4146 bcm43xx_periodic_tasks_setup(bcm);
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 } 4147 }
3977 netif_wake_queue(bcm->net_dev); 4148 mutex_unlock(&(bcm)->mutex);
3978 printk(KERN_INFO PFX "Controller restarted\n");
3979 4149
3980 return; 4150 printk(KERN_ERR PFX "Controller restart%s\n",
3981failure: 4151 (err == 0) ? "ed" : " failed");
3982 printk(KERN_ERR PFX "Controller restart failed\n");
3983} 4152}
3984 4153
3985/* Hard-reset the chip. 4154/* Hard-reset the chip.
3986 * This can be called from interrupt or process context. 4155 * This can be called from interrupt or process context.
3987 * Make sure to _not_ re-enable device interrupts after this has been called. 4156 * bcm->irq_lock must be locked.
3988*/ 4157 */
3989void bcm43xx_controller_restart(struct bcm43xx_private *bcm, const char *reason) 4158void bcm43xx_controller_restart(struct bcm43xx_private *bcm, const char *reason)
3990{ 4159{
3991 bcm43xx_set_status(bcm, BCM43xx_STAT_RESTARTING); 4160 if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED)
3992 bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL); 4161 return;
3993 bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); /* dummy read */
3994 printk(KERN_ERR PFX "Controller RESET (%s) ...\n", reason); 4162 printk(KERN_ERR PFX "Controller RESET (%s) ...\n", reason);
3995 INIT_WORK(&bcm->restart_work, bcm43xx_chip_reset, bcm); 4163 INIT_WORK(&bcm->restart_work, bcm43xx_chip_reset, bcm);
3996 schedule_work(&bcm->restart_work); 4164 schedule_work(&bcm->restart_work);
@@ -4002,21 +4170,16 @@ static int bcm43xx_suspend(struct pci_dev *pdev, pm_message_t state)
4002{ 4170{
4003 struct net_device *net_dev = pci_get_drvdata(pdev); 4171 struct net_device *net_dev = pci_get_drvdata(pdev);
4004 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); 4172 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
4005 unsigned long flags; 4173 int err;
4006 int try_to_shutdown = 0, err;
4007 4174
4008 dprintk(KERN_INFO PFX "Suspending...\n"); 4175 dprintk(KERN_INFO PFX "Suspending...\n");
4009 4176
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); 4177 netif_device_detach(net_dev);
4017 if (try_to_shutdown) { 4178 bcm->was_initialized = 0;
4179 if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) {
4180 bcm->was_initialized = 1;
4018 ieee80211softmac_stop(net_dev); 4181 ieee80211softmac_stop(net_dev);
4019 err = bcm43xx_disable_interrupts_sync(bcm, &bcm->irq_savedstate); 4182 err = bcm43xx_disable_interrupts_sync(bcm);
4020 if (unlikely(err)) { 4183 if (unlikely(err)) {
4021 dprintk(KERN_ERR PFX "Suspend failed.\n"); 4184 dprintk(KERN_ERR PFX "Suspend failed.\n");
4022 return -EAGAIN; 4185 return -EAGAIN;
@@ -4049,17 +4212,14 @@ static int bcm43xx_resume(struct pci_dev *pdev)
4049 pci_restore_state(pdev); 4212 pci_restore_state(pdev);
4050 4213
4051 bcm43xx_chipset_attach(bcm); 4214 bcm43xx_chipset_attach(bcm);
4052 if (bcm->was_initialized) { 4215 if (bcm->was_initialized)
4053 bcm->irq_savedstate = BCM43xx_IRQ_INITIAL;
4054 err = bcm43xx_init_board(bcm); 4216 err = bcm43xx_init_board(bcm);
4055 }
4056 if (err) { 4217 if (err) {
4057 printk(KERN_ERR PFX "Resume failed!\n"); 4218 printk(KERN_ERR PFX "Resume failed!\n");
4058 return err; 4219 return err;
4059 } 4220 }
4060
4061 netif_device_attach(net_dev); 4221 netif_device_attach(net_dev);
4062 4222
4063 dprintk(KERN_INFO PFX "Device resumed.\n"); 4223 dprintk(KERN_INFO PFX "Device resumed.\n");
4064 4224
4065 return 0; 4225 return 0;
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.h b/drivers/net/wireless/bcm43xx/bcm43xx_main.h
index 116493671f88..f76357178e4d 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_main.h
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.h
@@ -133,11 +133,17 @@ 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);
139void bcm43xx_mac_enable(struct bcm43xx_private *bcm); 142void bcm43xx_mac_enable(struct bcm43xx_private *bcm);
140 143
144void bcm43xx_periodic_tasks_delete(struct bcm43xx_private *bcm);
145void bcm43xx_periodic_tasks_setup(struct bcm43xx_private *bcm);
146
141void bcm43xx_controller_restart(struct bcm43xx_private *bcm, const char *reason); 147void bcm43xx_controller_restart(struct bcm43xx_private *bcm, const char *reason);
142 148
143int bcm43xx_sprom_read(struct bcm43xx_private *bcm, u16 *sprom); 149int bcm43xx_sprom_read(struct bcm43xx_private *bcm, u16 *sprom);
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..c71b998a3694 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
@@ -170,13 +176,12 @@ static ssize_t bcm43xx_attr_interfmode_show(struct device *dev,
170 char *buf) 176 char *buf)
171{ 177{
172 struct bcm43xx_private *bcm = dev_to_bcm(dev); 178 struct bcm43xx_private *bcm = dev_to_bcm(dev);
173 int err;
174 ssize_t count = 0; 179 ssize_t count = 0;
175 180
176 if (!capable(CAP_NET_ADMIN)) 181 if (!capable(CAP_NET_ADMIN))
177 return -EPERM; 182 return -EPERM;
178 183
179 bcm43xx_lock_noirq(bcm); 184 mutex_lock(&bcm->mutex);
180 185
181 switch (bcm43xx_current_radio(bcm)->interfmode) { 186 switch (bcm43xx_current_radio(bcm)->interfmode) {
182 case BCM43xx_RADIO_INTERFMODE_NONE: 187 case BCM43xx_RADIO_INTERFMODE_NONE:
@@ -191,11 +196,10 @@ static ssize_t bcm43xx_attr_interfmode_show(struct device *dev,
191 default: 196 default:
192 assert(0); 197 assert(0);
193 } 198 }
194 err = 0;
195 199
196 bcm43xx_unlock_noirq(bcm); 200 mutex_unlock(&bcm->mutex);
197 201
198 return err ? err : count; 202 return count;
199 203
200} 204}
201 205
@@ -229,7 +233,8 @@ static ssize_t bcm43xx_attr_interfmode_store(struct device *dev,
229 return -EINVAL; 233 return -EINVAL;
230 } 234 }
231 235
232 bcm43xx_lock_irqsafe(bcm, flags); 236 mutex_lock(&bcm->mutex);
237 spin_lock_irqsave(&bcm->irq_lock, flags);
233 238
234 err = bcm43xx_radio_set_interference_mitigation(bcm, mode); 239 err = bcm43xx_radio_set_interference_mitigation(bcm, mode);
235 if (err) { 240 if (err) {
@@ -237,7 +242,8 @@ static ssize_t bcm43xx_attr_interfmode_store(struct device *dev,
237 "supported by device\n"); 242 "supported by device\n");
238 } 243 }
239 mmiowb(); 244 mmiowb();
240 bcm43xx_unlock_irqsafe(bcm, flags); 245 spin_unlock_irqrestore(&bcm->irq_lock, flags);
246 mutex_unlock(&bcm->mutex);
241 247
242 return err ? err : count; 248 return err ? err : count;
243} 249}
@@ -251,23 +257,21 @@ static ssize_t bcm43xx_attr_preamble_show(struct device *dev,
251 char *buf) 257 char *buf)
252{ 258{
253 struct bcm43xx_private *bcm = dev_to_bcm(dev); 259 struct bcm43xx_private *bcm = dev_to_bcm(dev);
254 int err;
255 ssize_t count; 260 ssize_t count;
256 261
257 if (!capable(CAP_NET_ADMIN)) 262 if (!capable(CAP_NET_ADMIN))
258 return -EPERM; 263 return -EPERM;
259 264
260 bcm43xx_lock_noirq(bcm); 265 mutex_lock(&bcm->mutex);
261 266
262 if (bcm->short_preamble) 267 if (bcm->short_preamble)
263 count = snprintf(buf, PAGE_SIZE, "1 (Short Preamble enabled)\n"); 268 count = snprintf(buf, PAGE_SIZE, "1 (Short Preamble enabled)\n");
264 else 269 else
265 count = snprintf(buf, PAGE_SIZE, "0 (Short Preamble disabled)\n"); 270 count = snprintf(buf, PAGE_SIZE, "0 (Short Preamble disabled)\n");
266 271
267 err = 0; 272 mutex_unlock(&bcm->mutex);
268 bcm43xx_unlock_noirq(bcm);
269 273
270 return err ? err : count; 274 return count;
271} 275}
272 276
273static ssize_t bcm43xx_attr_preamble_store(struct device *dev, 277static ssize_t bcm43xx_attr_preamble_store(struct device *dev,
@@ -276,7 +280,6 @@ static ssize_t bcm43xx_attr_preamble_store(struct device *dev,
276{ 280{
277 struct bcm43xx_private *bcm = dev_to_bcm(dev); 281 struct bcm43xx_private *bcm = dev_to_bcm(dev);
278 unsigned long flags; 282 unsigned long flags;
279 int err;
280 int value; 283 int value;
281 284
282 if (!capable(CAP_NET_ADMIN)) 285 if (!capable(CAP_NET_ADMIN))
@@ -285,20 +288,141 @@ static ssize_t bcm43xx_attr_preamble_store(struct device *dev,
285 value = get_boolean(buf, count); 288 value = get_boolean(buf, count);
286 if (value < 0) 289 if (value < 0)
287 return value; 290 return value;
288 bcm43xx_lock_irqsafe(bcm, flags); 291 mutex_lock(&bcm->mutex);
292 spin_lock_irqsave(&bcm->irq_lock, flags);
289 293
290 bcm->short_preamble = !!value; 294 bcm->short_preamble = !!value;
291 295
292 err = 0; 296 spin_unlock_irqrestore(&bcm->irq_lock, flags);
293 bcm43xx_unlock_irqsafe(bcm, flags); 297 mutex_unlock(&bcm->mutex);
294 298
295 return err ? err : count; 299 return count;
296} 300}
297 301
298static DEVICE_ATTR(shortpreamble, 0644, 302static DEVICE_ATTR(shortpreamble, 0644,
299 bcm43xx_attr_preamble_show, 303 bcm43xx_attr_preamble_show,
300 bcm43xx_attr_preamble_store); 304 bcm43xx_attr_preamble_store);
301 305
306static ssize_t bcm43xx_attr_phymode_store(struct device *dev,
307 struct device_attribute *attr,
308 const char *buf, size_t count)
309{
310 struct bcm43xx_private *bcm = dev_to_bcm(dev);
311 int phytype;
312 int err = -EINVAL;
313
314 if (count < 1)
315 goto out;
316 switch (buf[0]) {
317 case 'a': case 'A':
318 phytype = BCM43xx_PHYTYPE_A;
319 break;
320 case 'b': case 'B':
321 phytype = BCM43xx_PHYTYPE_B;
322 break;
323 case 'g': case 'G':
324 phytype = BCM43xx_PHYTYPE_G;
325 break;
326 default:
327 goto out;
328 }
329
330 bcm43xx_periodic_tasks_delete(bcm);
331 mutex_lock(&(bcm)->mutex);
332 err = bcm43xx_select_wireless_core(bcm, phytype);
333 if (!err)
334 bcm43xx_periodic_tasks_setup(bcm);
335 mutex_unlock(&(bcm)->mutex);
336 if (err == -ESRCH)
337 err = -ENODEV;
338
339out:
340 return err ? err : count;
341}
342
343static ssize_t bcm43xx_attr_phymode_show(struct device *dev,
344 struct device_attribute *attr,
345 char *buf)
346{
347 struct bcm43xx_private *bcm = dev_to_bcm(dev);
348 ssize_t count = 0;
349
350 mutex_lock(&(bcm)->mutex);
351 switch (bcm43xx_current_phy(bcm)->type) {
352 case BCM43xx_PHYTYPE_A:
353 snprintf(buf, PAGE_SIZE, "A");
354 break;
355 case BCM43xx_PHYTYPE_B:
356 snprintf(buf, PAGE_SIZE, "B");
357 break;
358 case BCM43xx_PHYTYPE_G:
359 snprintf(buf, PAGE_SIZE, "G");
360 break;
361 default:
362 assert(0);
363 }
364 mutex_unlock(&(bcm)->mutex);
365
366 return count;
367}
368
369static DEVICE_ATTR(phymode, 0644,
370 bcm43xx_attr_phymode_show,
371 bcm43xx_attr_phymode_store);
372
373static ssize_t bcm43xx_attr_microcode_show(struct device *dev,
374 struct device_attribute *attr,
375 char *buf)
376{
377 unsigned long flags;
378 struct bcm43xx_private *bcm = dev_to_bcm(dev);
379 ssize_t count = 0;
380 u16 status;
381
382 if (!capable(CAP_NET_ADMIN))
383 return -EPERM;
384
385 mutex_lock(&(bcm)->mutex);
386 spin_lock_irqsave(&bcm->irq_lock, flags);
387 status = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED,
388 BCM43xx_UCODE_STATUS);
389
390 spin_unlock_irqrestore(&bcm->irq_lock, flags);
391 mutex_unlock(&(bcm)->mutex);
392 switch (status) {
393 case 0x0000:
394 count = snprintf(buf, PAGE_SIZE, "0x%.4x (invalid)\n",
395 status);
396 break;
397 case 0x0001:
398 count = snprintf(buf, PAGE_SIZE, "0x%.4x (init)\n",
399 status);
400 break;
401 case 0x0002:
402 count = snprintf(buf, PAGE_SIZE, "0x%.4x (active)\n",
403 status);
404 break;
405 case 0x0003:
406 count = snprintf(buf, PAGE_SIZE, "0x%.4x (suspended)\n",
407 status);
408 break;
409 case 0x0004:
410 count = snprintf(buf, PAGE_SIZE, "0x%.4x (asleep)\n",
411 status);
412 break;
413 default:
414 count = snprintf(buf, PAGE_SIZE, "0x%.4x (unknown)\n",
415 status);
416 break;
417 }
418
419 return count;
420}
421
422static DEVICE_ATTR(microcodestatus, 0444,
423 bcm43xx_attr_microcode_show,
424 NULL);
425
302int bcm43xx_sysfs_register(struct bcm43xx_private *bcm) 426int bcm43xx_sysfs_register(struct bcm43xx_private *bcm)
303{ 427{
304 struct device *dev = &bcm->pci_dev->dev; 428 struct device *dev = &bcm->pci_dev->dev;
@@ -315,9 +439,19 @@ int bcm43xx_sysfs_register(struct bcm43xx_private *bcm)
315 err = device_create_file(dev, &dev_attr_shortpreamble); 439 err = device_create_file(dev, &dev_attr_shortpreamble);
316 if (err) 440 if (err)
317 goto err_remove_interfmode; 441 goto err_remove_interfmode;
442 err = device_create_file(dev, &dev_attr_phymode);
443 if (err)
444 goto err_remove_shortpreamble;
445 err = device_create_file(dev, &dev_attr_microcodestatus);
446 if (err)
447 goto err_remove_phymode;
318 448
319out: 449out:
320 return err; 450 return err;
451err_remove_phymode:
452 device_remove_file(dev, &dev_attr_phymode);
453err_remove_shortpreamble:
454 device_remove_file(dev, &dev_attr_shortpreamble);
321err_remove_interfmode: 455err_remove_interfmode:
322 device_remove_file(dev, &dev_attr_interference); 456 device_remove_file(dev, &dev_attr_interference);
323err_remove_sprom: 457err_remove_sprom:
@@ -329,6 +463,8 @@ void bcm43xx_sysfs_unregister(struct bcm43xx_private *bcm)
329{ 463{
330 struct device *dev = &bcm->pci_dev->dev; 464 struct device *dev = &bcm->pci_dev->dev;
331 465
466 device_remove_file(dev, &dev_attr_microcodestatus);
467 device_remove_file(dev, &dev_attr_phymode);
332 device_remove_file(dev, &dev_attr_shortpreamble); 468 device_remove_file(dev, &dev_attr_shortpreamble);
333 device_remove_file(dev, &dev_attr_interference); 469 device_remove_file(dev, &dev_attr_interference);
334 device_remove_file(dev, &dev_attr_sprom); 470 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/hostap/hostap.h b/drivers/net/wireless/hostap/hostap.h
index 5e63765219fe..e663518bd570 100644
--- a/drivers/net/wireless/hostap/hostap.h
+++ b/drivers/net/wireless/hostap/hostap.h
@@ -86,7 +86,7 @@ void hostap_info_process(local_info_t *local, struct sk_buff *skb);
86/* hostap_ioctl.c */ 86/* hostap_ioctl.c */
87 87
88extern const struct iw_handler_def hostap_iw_handler_def; 88extern const struct iw_handler_def hostap_iw_handler_def;
89extern struct ethtool_ops prism2_ethtool_ops; 89extern const struct ethtool_ops prism2_ethtool_ops;
90 90
91int hostap_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); 91int hostap_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
92 92
diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c
index 52e6df5c1a92..686d895116de 100644
--- a/drivers/net/wireless/hostap/hostap_cs.c
+++ b/drivers/net/wireless/hostap/hostap_cs.c
@@ -847,6 +847,7 @@ static struct pcmcia_device_id hostap_cs_ids[] = {
847 PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0002), 847 PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0002),
848 PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0005), 848 PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0005),
849 PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0010), 849 PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0010),
850 PCMCIA_DEVICE_MANF_CARD(0x0126, 0x0002),
850 PCMCIA_DEVICE_MANF_CARD_PROD_ID1(0x0156, 0x0002, "INTERSIL", 851 PCMCIA_DEVICE_MANF_CARD_PROD_ID1(0x0156, 0x0002, "INTERSIL",
851 0x74c5e40d), 852 0x74c5e40d),
852 PCMCIA_DEVICE_MANF_CARD_PROD_ID1(0x0156, 0x0002, "Intersil", 853 PCMCIA_DEVICE_MANF_CARD_PROD_ID1(0x0156, 0x0002, "Intersil",
diff --git a/drivers/net/wireless/hostap/hostap_ioctl.c b/drivers/net/wireless/hostap/hostap_ioctl.c
index 8399de581893..7a4978516eac 100644
--- a/drivers/net/wireless/hostap/hostap_ioctl.c
+++ b/drivers/net/wireless/hostap/hostap_ioctl.c
@@ -3908,7 +3908,7 @@ static void prism2_get_drvinfo(struct net_device *dev,
3908 local->sta_fw_ver & 0xff); 3908 local->sta_fw_ver & 0xff);
3909} 3909}
3910 3910
3911struct ethtool_ops prism2_ethtool_ops = { 3911const struct ethtool_ops prism2_ethtool_ops = {
3912 .get_drvinfo = prism2_get_drvinfo 3912 .get_drvinfo = prism2_get_drvinfo
3913}; 3913};
3914 3914
diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c
index e955db435b30..b4d81a04c895 100644
--- a/drivers/net/wireless/ipw2100.c
+++ b/drivers/net/wireless/ipw2100.c
@@ -5911,7 +5911,7 @@ static u32 ipw2100_ethtool_get_link(struct net_device *dev)
5911 return (priv->status & STATUS_ASSOCIATED) ? 1 : 0; 5911 return (priv->status & STATUS_ASSOCIATED) ? 1 : 0;
5912} 5912}
5913 5913
5914static struct ethtool_ops ipw2100_ethtool_ops = { 5914static const struct ethtool_ops ipw2100_ethtool_ops = {
5915 .get_link = ipw2100_ethtool_get_link, 5915 .get_link = ipw2100_ethtool_get_link,
5916 .get_drvinfo = ipw_ethtool_get_drvinfo, 5916 .get_drvinfo = ipw_ethtool_get_drvinfo,
5917}; 5917};
@@ -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));
@@ -6531,7 +6532,7 @@ static int __init ipw2100_init(void)
6531 printk(KERN_INFO DRV_NAME ": %s, %s\n", DRV_DESCRIPTION, DRV_VERSION); 6532 printk(KERN_INFO DRV_NAME ": %s, %s\n", DRV_DESCRIPTION, DRV_VERSION);
6532 printk(KERN_INFO DRV_NAME ": %s\n", DRV_COPYRIGHT); 6533 printk(KERN_INFO DRV_NAME ": %s\n", DRV_COPYRIGHT);
6533 6534
6534 ret = pci_module_init(&ipw2100_pci_driver); 6535 ret = pci_register_driver(&ipw2100_pci_driver);
6535 6536
6536#ifdef CONFIG_IPW2100_DEBUG 6537#ifdef CONFIG_IPW2100_DEBUG
6537 ipw2100_debug_level = debug; 6538 ipw2100_debug_level = debug;
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index b3300ffe4eec..7358664e0908 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
@@ -10458,7 +10461,7 @@ static int ipw_ethtool_set_eeprom(struct net_device *dev,
10458 return 0; 10461 return 0;
10459} 10462}
10460 10463
10461static struct ethtool_ops ipw_ethtool_ops = { 10464static const struct ethtool_ops ipw_ethtool_ops = {
10462 .get_link = ipw_ethtool_get_link, 10465 .get_link = ipw_ethtool_get_link,
10463 .get_drvinfo = ipw_ethtool_get_drvinfo, 10466 .get_drvinfo = ipw_ethtool_get_drvinfo,
10464 .get_eeprom_len = ipw_ethtool_get_eeprom_len, 10467 .get_eeprom_len = ipw_ethtool_get_eeprom_len,
@@ -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)
@@ -11774,7 +11788,7 @@ static int __init ipw_init(void)
11774 printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION ", " DRV_VERSION "\n"); 11788 printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION ", " DRV_VERSION "\n");
11775 printk(KERN_INFO DRV_NAME ": " DRV_COPYRIGHT "\n"); 11789 printk(KERN_INFO DRV_NAME ": " DRV_COPYRIGHT "\n");
11776 11790
11777 ret = pci_module_init(&ipw_driver); 11791 ret = pci_register_driver(&ipw_driver);
11778 if (ret) { 11792 if (ret) {
11779 IPW_ERROR("Unable to initialize PCI module\n"); 11793 IPW_ERROR("Unable to initialize PCI module\n");
11780 return ret; 11794 return ret;
@@ -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..1840b69e3cb5 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>
@@ -164,7 +165,7 @@ static const u8 encaps_hdr[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
164#define MAX_RID_LEN 1024 165#define MAX_RID_LEN 1024
165 166
166static const struct iw_handler_def orinoco_handler_def; 167static const struct iw_handler_def orinoco_handler_def;
167static struct ethtool_ops orinoco_ethtool_ops; 168static const struct ethtool_ops orinoco_ethtool_ops;
168 169
169/********************************************************************/ 170/********************************************************************/
170/* Data tables */ 171/* Data tables */
@@ -4292,7 +4293,7 @@ static void orinoco_get_drvinfo(struct net_device *dev,
4292 "PCMCIA %p", priv->hw.iobase); 4293 "PCMCIA %p", priv->hw.iobase);
4293} 4294}
4294 4295
4295static struct ethtool_ops orinoco_ethtool_ops = { 4296static const struct ethtool_ops orinoco_ethtool_ops = {
4296 .get_drvinfo = orinoco_get_drvinfo, 4297 .get_drvinfo = orinoco_get_drvinfo,
4297 .get_link = ethtool_op_get_link, 4298 .get_link = ethtool_op_get_link,
4298}; 4299};
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/orinoco_nortel.c b/drivers/net/wireless/orinoco_nortel.c
index bf05b907747e..eaf3d13b851c 100644
--- a/drivers/net/wireless/orinoco_nortel.c
+++ b/drivers/net/wireless/orinoco_nortel.c
@@ -304,7 +304,7 @@ MODULE_LICENSE("Dual MPL/GPL");
304static int __init orinoco_nortel_init(void) 304static int __init orinoco_nortel_init(void)
305{ 305{
306 printk(KERN_DEBUG "%s\n", version); 306 printk(KERN_DEBUG "%s\n", version);
307 return pci_module_init(&orinoco_nortel_driver); 307 return pci_register_driver(&orinoco_nortel_driver);
308} 308}
309 309
310static void __exit orinoco_nortel_exit(void) 310static void __exit orinoco_nortel_exit(void)
diff --git a/drivers/net/wireless/orinoco_pci.c b/drivers/net/wireless/orinoco_pci.c
index 1759c543fbee..97a8b4ff32bd 100644
--- a/drivers/net/wireless/orinoco_pci.c
+++ b/drivers/net/wireless/orinoco_pci.c
@@ -244,7 +244,7 @@ MODULE_LICENSE("Dual MPL/GPL");
244static int __init orinoco_pci_init(void) 244static int __init orinoco_pci_init(void)
245{ 245{
246 printk(KERN_DEBUG "%s\n", version); 246 printk(KERN_DEBUG "%s\n", version);
247 return pci_module_init(&orinoco_pci_driver); 247 return pci_register_driver(&orinoco_pci_driver);
248} 248}
249 249
250static void __exit orinoco_pci_exit(void) 250static void __exit orinoco_pci_exit(void)
diff --git a/drivers/net/wireless/orinoco_plx.c b/drivers/net/wireless/orinoco_plx.c
index 7f006f624171..31162ac25a92 100644
--- a/drivers/net/wireless/orinoco_plx.c
+++ b/drivers/net/wireless/orinoco_plx.c
@@ -351,7 +351,7 @@ MODULE_LICENSE("Dual MPL/GPL");
351static int __init orinoco_plx_init(void) 351static int __init orinoco_plx_init(void)
352{ 352{
353 printk(KERN_DEBUG "%s\n", version); 353 printk(KERN_DEBUG "%s\n", version);
354 return pci_module_init(&orinoco_plx_driver); 354 return pci_register_driver(&orinoco_plx_driver);
355} 355}
356 356
357static void __exit orinoco_plx_exit(void) 357static void __exit orinoco_plx_exit(void)
diff --git a/drivers/net/wireless/orinoco_tmd.c b/drivers/net/wireless/orinoco_tmd.c
index 0831721e4d6c..7c7b960c91df 100644
--- a/drivers/net/wireless/orinoco_tmd.c
+++ b/drivers/net/wireless/orinoco_tmd.c
@@ -228,7 +228,7 @@ MODULE_LICENSE("Dual MPL/GPL");
228static int __init orinoco_tmd_init(void) 228static int __init orinoco_tmd_init(void)
229{ 229{
230 printk(KERN_DEBUG "%s\n", version); 230 printk(KERN_DEBUG "%s\n", version);
231 return pci_module_init(&orinoco_tmd_driver); 231 return pci_register_driver(&orinoco_tmd_driver);
232} 232}
233 233
234static void __exit orinoco_tmd_exit(void) 234static void __exit orinoco_tmd_exit(void)
diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c
index 989599ad33ef..c09fbf733b3a 100644
--- a/drivers/net/wireless/prism54/isl_ioctl.c
+++ b/drivers/net/wireless/prism54/isl_ioctl.c
@@ -35,13 +35,21 @@
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
49/* In 500 kbps */
50static const unsigned char scan_rate_list[] = { 2, 4, 11, 22,
51 12, 18, 24, 36,
52 48, 72, 96, 108 };
45 53
46/** 54/**
47 * prism54_mib_mode_helper - MIB change mode helper function 55 * prism54_mib_mode_helper - MIB change mode helper function
@@ -468,6 +476,9 @@ prism54_get_range(struct net_device *ndev, struct iw_request_info *info,
468 range->event_capa[1] = IW_EVENT_CAPA_K_1; 476 range->event_capa[1] = IW_EVENT_CAPA_K_1;
469 range->event_capa[4] = IW_EVENT_CAPA_MASK(IWEVCUSTOM); 477 range->event_capa[4] = IW_EVENT_CAPA_MASK(IWEVCUSTOM);
470 478
479 range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
480 IW_ENC_CAPA_CIPHER_TKIP;
481
471 if (islpci_get_state(priv) < PRV_STATE_INIT) 482 if (islpci_get_state(priv) < PRV_STATE_INIT)
472 return 0; 483 return 0;
473 484
@@ -567,6 +578,8 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev,
567 struct iw_event iwe; /* Temporary buffer */ 578 struct iw_event iwe; /* Temporary buffer */
568 short cap; 579 short cap;
569 islpci_private *priv = netdev_priv(ndev); 580 islpci_private *priv = netdev_priv(ndev);
581 u8 wpa_ie[MAX_WPA_IE_LEN];
582 size_t wpa_ie_len;
570 583
571 /* The first entry must be the MAC address */ 584 /* The first entry must be the MAC address */
572 memcpy(iwe.u.ap_addr.sa_data, bss->address, 6); 585 memcpy(iwe.u.ap_addr.sa_data, bss->address, 6);
@@ -627,28 +640,40 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev,
627 current_ev = 640 current_ev =
628 iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_QUAL_LEN); 641 iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
629 642
630 if (priv->wpa) { 643 /* Add WPA/RSN Information Element, if any */
631 u8 wpa_ie[MAX_WPA_IE_LEN]; 644 wpa_ie_len = prism54_wpa_bss_ie_get(priv, bss->address, wpa_ie);
632 char *buf, *p; 645 if (wpa_ie_len > 0) {
633 size_t wpa_ie_len; 646 iwe.cmd = IWEVGENIE;
647 iwe.u.data.length = min(wpa_ie_len, (size_t)MAX_WPA_IE_LEN);
648 current_ev = iwe_stream_add_point(current_ev, end_buf,
649 &iwe, wpa_ie);
650 }
651 /* Do the bitrates */
652 {
653 char * current_val = current_ev + IW_EV_LCP_LEN;
634 int i; 654 int i;
635 655 int mask;
636 wpa_ie_len = prism54_wpa_ie_get(priv, bss->address, wpa_ie); 656
637 if (wpa_ie_len > 0 && 657 iwe.cmd = SIOCGIWRATE;
638 (buf = kmalloc(wpa_ie_len * 2 + 10, GFP_ATOMIC))) { 658 /* Those two flags are ignored... */
639 p = buf; 659 iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
640 p += sprintf(p, "wpa_ie="); 660
641 for (i = 0; i < wpa_ie_len; i++) { 661 /* Parse the bitmask */
642 p += sprintf(p, "%02x", wpa_ie[i]); 662 mask = 0x1;
663 for(i = 0; i < sizeof(scan_rate_list); i++) {
664 if(bss->rates & mask) {
665 iwe.u.bitrate.value = (scan_rate_list[i] * 500000);
666 current_val = iwe_stream_add_value(current_ev, current_val,
667 end_buf, &iwe,
668 IW_EV_PARAM_LEN);
643 } 669 }
644 memset(&iwe, 0, sizeof (iwe)); 670 mask <<= 1;
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 } 671 }
672 /* Check if we added any event */
673 if ((current_val - current_ev) > IW_EV_LCP_LEN)
674 current_ev = current_val;
651 } 675 }
676
652 return current_ev; 677 return current_ev;
653} 678}
654 679
@@ -1051,12 +1076,24 @@ prism54_set_encode(struct net_device *ndev, struct iw_request_info *info,
1051 current_index = r.u; 1076 current_index = r.u;
1052 /* Verify that the key is not marked as invalid */ 1077 /* Verify that the key is not marked as invalid */
1053 if (!(dwrq->flags & IW_ENCODE_NOKEY)) { 1078 if (!(dwrq->flags & IW_ENCODE_NOKEY)) {
1054 key.length = dwrq->length > sizeof (key.key) ? 1079 if (dwrq->length > KEY_SIZE_TKIP) {
1055 sizeof (key.key) : dwrq->length; 1080 /* User-provided key data too big */
1056 memcpy(key.key, extra, key.length); 1081 return -EINVAL;
1057 if (key.length == 32) 1082 }
1058 /* we want WPA-PSK */ 1083 if (dwrq->length > KEY_SIZE_WEP104) {
1084 /* WPA-PSK TKIP */
1059 key.type = DOT11_PRIV_TKIP; 1085 key.type = DOT11_PRIV_TKIP;
1086 key.length = KEY_SIZE_TKIP;
1087 } else if (dwrq->length > KEY_SIZE_WEP40) {
1088 /* WEP 104/128 */
1089 key.length = KEY_SIZE_WEP104;
1090 } else {
1091 /* WEP 40/64 */
1092 key.length = KEY_SIZE_WEP40;
1093 }
1094 memset(key.key, 0, sizeof (key.key));
1095 memcpy(key.key, extra, dwrq->length);
1096
1060 if ((index < 0) || (index > 3)) 1097 if ((index < 0) || (index > 3))
1061 /* no index provided use the current one */ 1098 /* no index provided use the current one */
1062 index = current_index; 1099 index = current_index;
@@ -1210,6 +1247,489 @@ prism54_set_txpower(struct net_device *ndev, struct iw_request_info *info,
1210 } 1247 }
1211} 1248}
1212 1249
1250static int prism54_set_genie(struct net_device *ndev,
1251 struct iw_request_info *info,
1252 struct iw_point *data, char *extra)
1253{
1254 islpci_private *priv = netdev_priv(ndev);
1255 int alen, ret = 0;
1256 struct obj_attachment *attach;
1257
1258 if (data->length > MAX_WPA_IE_LEN ||
1259 (data->length && extra == NULL))
1260 return -EINVAL;
1261
1262 memcpy(priv->wpa_ie, extra, data->length);
1263 priv->wpa_ie_len = data->length;
1264
1265 alen = sizeof(*attach) + priv->wpa_ie_len;
1266 attach = kzalloc(alen, GFP_KERNEL);
1267 if (attach == NULL)
1268 return -ENOMEM;
1269
1270#define WLAN_FC_TYPE_MGMT 0
1271#define WLAN_FC_STYPE_ASSOC_REQ 0
1272#define WLAN_FC_STYPE_REASSOC_REQ 2
1273
1274 /* Note: endianness is covered by mgt_set_varlen */
1275 attach->type = (WLAN_FC_TYPE_MGMT << 2) |
1276 (WLAN_FC_STYPE_ASSOC_REQ << 4);
1277 attach->id = -1;
1278 attach->size = priv->wpa_ie_len;
1279 memcpy(attach->data, extra, priv->wpa_ie_len);
1280
1281 ret = mgt_set_varlen(priv, DOT11_OID_ATTACHMENT, attach,
1282 priv->wpa_ie_len);
1283 if (ret == 0) {
1284 attach->type = (WLAN_FC_TYPE_MGMT << 2) |
1285 (WLAN_FC_STYPE_REASSOC_REQ << 4);
1286
1287 ret = mgt_set_varlen(priv, DOT11_OID_ATTACHMENT, attach,
1288 priv->wpa_ie_len);
1289 if (ret == 0)
1290 printk(KERN_DEBUG "%s: WPA IE Attachment was set\n",
1291 ndev->name);
1292 }
1293
1294 kfree(attach);
1295 return ret;
1296}
1297
1298
1299static int prism54_get_genie(struct net_device *ndev,
1300 struct iw_request_info *info,
1301 struct iw_point *data, char *extra)
1302{
1303 islpci_private *priv = netdev_priv(ndev);
1304 int len = priv->wpa_ie_len;
1305
1306 if (len <= 0) {
1307 data->length = 0;
1308 return 0;
1309 }
1310
1311 if (data->length < len)
1312 return -E2BIG;
1313
1314 data->length = len;
1315 memcpy(extra, priv->wpa_ie, len);
1316
1317 return 0;
1318}
1319
1320static int prism54_set_auth(struct net_device *ndev,
1321 struct iw_request_info *info,
1322 union iwreq_data *wrqu, char *extra)
1323{
1324 islpci_private *priv = netdev_priv(ndev);
1325 struct iw_param *param = &wrqu->param;
1326 u32 mlmelevel = 0, authen = 0, dot1x = 0;
1327 u32 exunencrypt = 0, privinvoked = 0, wpa = 0;
1328 u32 old_wpa;
1329 int ret = 0;
1330 union oid_res_t r;
1331
1332 if (islpci_get_state(priv) < PRV_STATE_INIT)
1333 return 0;
1334
1335 /* first get the flags */
1336 down_write(&priv->mib_sem);
1337 wpa = old_wpa = priv->wpa;
1338 up_write(&priv->mib_sem);
1339 ret = mgt_get_request(priv, DOT11_OID_AUTHENABLE, 0, NULL, &r);
1340 authen = r.u;
1341 ret = mgt_get_request(priv, DOT11_OID_PRIVACYINVOKED, 0, NULL, &r);
1342 privinvoked = r.u;
1343 ret = mgt_get_request(priv, DOT11_OID_EXUNENCRYPTED, 0, NULL, &r);
1344 exunencrypt = r.u;
1345 ret = mgt_get_request(priv, DOT11_OID_DOT1XENABLE, 0, NULL, &r);
1346 dot1x = r.u;
1347 ret = mgt_get_request(priv, DOT11_OID_MLMEAUTOLEVEL, 0, NULL, &r);
1348 mlmelevel = r.u;
1349
1350 if (ret < 0)
1351 goto out;
1352
1353 switch (param->flags & IW_AUTH_INDEX) {
1354 case IW_AUTH_CIPHER_PAIRWISE:
1355 case IW_AUTH_CIPHER_GROUP:
1356 case IW_AUTH_KEY_MGMT:
1357 break;
1358
1359 case IW_AUTH_WPA_ENABLED:
1360 /* Do the same thing as IW_AUTH_WPA_VERSION */
1361 if (param->value) {
1362 wpa = 1;
1363 privinvoked = 1; /* For privacy invoked */
1364 exunencrypt = 1; /* Filter out all unencrypted frames */
1365 dot1x = 0x01; /* To enable eap filter */
1366 mlmelevel = DOT11_MLME_EXTENDED;
1367 authen = DOT11_AUTH_OS; /* Only WEP uses _SK and _BOTH */
1368 } else {
1369 wpa = 0;
1370 privinvoked = 0;
1371 exunencrypt = 0; /* Do not filter un-encrypted data */
1372 dot1x = 0;
1373 mlmelevel = DOT11_MLME_AUTO;
1374 }
1375 break;
1376
1377 case IW_AUTH_WPA_VERSION:
1378 if (param->value & IW_AUTH_WPA_VERSION_DISABLED) {
1379 wpa = 0;
1380 privinvoked = 0;
1381 exunencrypt = 0; /* Do not filter un-encrypted data */
1382 dot1x = 0;
1383 mlmelevel = DOT11_MLME_AUTO;
1384 } else {
1385 if (param->value & IW_AUTH_WPA_VERSION_WPA)
1386 wpa = 1;
1387 else if (param->value & IW_AUTH_WPA_VERSION_WPA2)
1388 wpa = 2;
1389 privinvoked = 1; /* For privacy invoked */
1390 exunencrypt = 1; /* Filter out all unencrypted frames */
1391 dot1x = 0x01; /* To enable eap filter */
1392 mlmelevel = DOT11_MLME_EXTENDED;
1393 authen = DOT11_AUTH_OS; /* Only WEP uses _SK and _BOTH */
1394 }
1395 break;
1396
1397 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
1398 dot1x = param->value ? 1 : 0;
1399 break;
1400
1401 case IW_AUTH_PRIVACY_INVOKED:
1402 privinvoked = param->value ? 1 : 0;
1403
1404 case IW_AUTH_DROP_UNENCRYPTED:
1405 exunencrypt = param->value ? 1 : 0;
1406 break;
1407
1408 case IW_AUTH_80211_AUTH_ALG:
1409 if (param->value & IW_AUTH_ALG_SHARED_KEY) {
1410 /* Only WEP uses _SK and _BOTH */
1411 if (wpa > 0) {
1412 ret = -EINVAL;
1413 goto out;
1414 }
1415 authen = DOT11_AUTH_SK;
1416 } else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM) {
1417 authen = DOT11_AUTH_OS;
1418 } else {
1419 ret = -EINVAL;
1420 goto out;
1421 }
1422 break;
1423
1424 default:
1425 return -EOPNOTSUPP;
1426 }
1427
1428 /* Set all the values */
1429 down_write(&priv->mib_sem);
1430 priv->wpa = wpa;
1431 up_write(&priv->mib_sem);
1432 mgt_set_request(priv, DOT11_OID_AUTHENABLE, 0, &authen);
1433 mgt_set_request(priv, DOT11_OID_PRIVACYINVOKED, 0, &privinvoked);
1434 mgt_set_request(priv, DOT11_OID_EXUNENCRYPTED, 0, &exunencrypt);
1435 mgt_set_request(priv, DOT11_OID_DOT1XENABLE, 0, &dot1x);
1436 mgt_set_request(priv, DOT11_OID_MLMEAUTOLEVEL, 0, &mlmelevel);
1437
1438out:
1439 return ret;
1440}
1441
1442static int prism54_get_auth(struct net_device *ndev,
1443 struct iw_request_info *info,
1444 union iwreq_data *wrqu, char *extra)
1445{
1446 islpci_private *priv = netdev_priv(ndev);
1447 struct iw_param *param = &wrqu->param;
1448 u32 wpa = 0;
1449 int ret = 0;
1450 union oid_res_t r;
1451
1452 if (islpci_get_state(priv) < PRV_STATE_INIT)
1453 return 0;
1454
1455 /* first get the flags */
1456 down_write(&priv->mib_sem);
1457 wpa = priv->wpa;
1458 up_write(&priv->mib_sem);
1459
1460 switch (param->flags & IW_AUTH_INDEX) {
1461 case IW_AUTH_CIPHER_PAIRWISE:
1462 case IW_AUTH_CIPHER_GROUP:
1463 case IW_AUTH_KEY_MGMT:
1464 /*
1465 * wpa_supplicant will control these internally
1466 */
1467 ret = -EOPNOTSUPP;
1468 break;
1469
1470 case IW_AUTH_WPA_VERSION:
1471 switch (wpa) {
1472 case 1:
1473 param->value = IW_AUTH_WPA_VERSION_WPA;
1474 break;
1475 case 2:
1476 param->value = IW_AUTH_WPA_VERSION_WPA2;
1477 break;
1478 case 0:
1479 default:
1480 param->value = IW_AUTH_WPA_VERSION_DISABLED;
1481 break;
1482 }
1483 break;
1484
1485 case IW_AUTH_DROP_UNENCRYPTED:
1486 ret = mgt_get_request(priv, DOT11_OID_EXUNENCRYPTED, 0, NULL, &r);
1487 if (ret >= 0)
1488 param->value = r.u > 0 ? 1 : 0;
1489 break;
1490
1491 case IW_AUTH_80211_AUTH_ALG:
1492 ret = mgt_get_request(priv, DOT11_OID_AUTHENABLE, 0, NULL, &r);
1493 if (ret >= 0) {
1494 switch (r.u) {
1495 case DOT11_AUTH_OS:
1496 param->value = IW_AUTH_ALG_OPEN_SYSTEM;
1497 break;
1498 case DOT11_AUTH_BOTH:
1499 case DOT11_AUTH_SK:
1500 param->value = IW_AUTH_ALG_SHARED_KEY;
1501 case DOT11_AUTH_NONE:
1502 default:
1503 param->value = 0;
1504 break;
1505 }
1506 }
1507 break;
1508
1509 case IW_AUTH_WPA_ENABLED:
1510 param->value = wpa > 0 ? 1 : 0;
1511 break;
1512
1513 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
1514 ret = mgt_get_request(priv, DOT11_OID_DOT1XENABLE, 0, NULL, &r);
1515 if (ret >= 0)
1516 param->value = r.u > 0 ? 1 : 0;
1517 break;
1518
1519 case IW_AUTH_PRIVACY_INVOKED:
1520 ret = mgt_get_request(priv, DOT11_OID_PRIVACYINVOKED, 0, NULL, &r);
1521 if (ret >= 0)
1522 param->value = r.u > 0 ? 1 : 0;
1523 break;
1524
1525 default:
1526 return -EOPNOTSUPP;
1527 }
1528 return ret;
1529}
1530
1531static int prism54_set_encodeext(struct net_device *ndev,
1532 struct iw_request_info *info,
1533 union iwreq_data *wrqu,
1534 char *extra)
1535{
1536 islpci_private *priv = netdev_priv(ndev);
1537 struct iw_point *encoding = &wrqu->encoding;
1538 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
1539 int idx, alg = ext->alg, set_key = 1;
1540 union oid_res_t r;
1541 int authen = DOT11_AUTH_OS, invoke = 0, exunencrypt = 0;
1542 int ret = 0;
1543
1544 if (islpci_get_state(priv) < PRV_STATE_INIT)
1545 return 0;
1546
1547 /* Determine and validate the key index */
1548 idx = (encoding->flags & IW_ENCODE_INDEX) - 1;
1549 if (idx) {
1550 if (idx < 0 || idx > 3)
1551 return -EINVAL;
1552 } else {
1553 ret = mgt_get_request(priv, DOT11_OID_DEFKEYID, 0, NULL, &r);
1554 if (ret < 0)
1555 goto out;
1556 idx = r.u;
1557 }
1558
1559 if (encoding->flags & IW_ENCODE_DISABLED)
1560 alg = IW_ENCODE_ALG_NONE;
1561
1562 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
1563 /* Only set transmit key index here, actual
1564 * key is set below if needed.
1565 */
1566 ret = mgt_set_request(priv, DOT11_OID_DEFKEYID, 0, &idx);
1567 set_key = ext->key_len > 0 ? 1 : 0;
1568 }
1569
1570 if (set_key) {
1571 struct obj_key key = { DOT11_PRIV_WEP, 0, "" };
1572 switch (alg) {
1573 case IW_ENCODE_ALG_NONE:
1574 break;
1575 case IW_ENCODE_ALG_WEP:
1576 if (ext->key_len > KEY_SIZE_WEP104) {
1577 ret = -EINVAL;
1578 goto out;
1579 }
1580 if (ext->key_len > KEY_SIZE_WEP40)
1581 key.length = KEY_SIZE_WEP104;
1582 else
1583 key.length = KEY_SIZE_WEP40;
1584 break;
1585 case IW_ENCODE_ALG_TKIP:
1586 if (ext->key_len > KEY_SIZE_TKIP) {
1587 ret = -EINVAL;
1588 goto out;
1589 }
1590 key.type = DOT11_PRIV_TKIP;
1591 key.length = KEY_SIZE_TKIP;
1592 default:
1593 return -EINVAL;
1594 }
1595
1596 if (key.length) {
1597 memset(key.key, 0, sizeof(key.key));
1598 memcpy(key.key, ext->key, ext->key_len);
1599 ret = mgt_set_request(priv, DOT11_OID_DEFKEYX, idx,
1600 &key);
1601 if (ret < 0)
1602 goto out;
1603 }
1604 }
1605
1606 /* Read the flags */
1607 if (encoding->flags & IW_ENCODE_DISABLED) {
1608 /* Encoding disabled,
1609 * authen = DOT11_AUTH_OS;
1610 * invoke = 0;
1611 * exunencrypt = 0; */
1612 }
1613 if (encoding->flags & IW_ENCODE_OPEN) {
1614 /* Encode but accept non-encoded packets. No auth */
1615 invoke = 1;
1616 }
1617 if (encoding->flags & IW_ENCODE_RESTRICTED) {
1618 /* Refuse non-encoded packets. Auth */
1619 authen = DOT11_AUTH_BOTH;
1620 invoke = 1;
1621 exunencrypt = 1;
1622 }
1623
1624 /* do the change if requested */
1625 if (encoding->flags & IW_ENCODE_MODE) {
1626 ret = mgt_set_request(priv, DOT11_OID_AUTHENABLE, 0,
1627 &authen);
1628 ret = mgt_set_request(priv, DOT11_OID_PRIVACYINVOKED, 0,
1629 &invoke);
1630 ret = mgt_set_request(priv, DOT11_OID_EXUNENCRYPTED, 0,
1631 &exunencrypt);
1632 }
1633
1634out:
1635 return ret;
1636}
1637
1638
1639static int prism54_get_encodeext(struct net_device *ndev,
1640 struct iw_request_info *info,
1641 union iwreq_data *wrqu,
1642 char *extra)
1643{
1644 islpci_private *priv = netdev_priv(ndev);
1645 struct iw_point *encoding = &wrqu->encoding;
1646 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
1647 int idx, max_key_len;
1648 union oid_res_t r;
1649 int authen = DOT11_AUTH_OS, invoke = 0, exunencrypt = 0, wpa = 0;
1650 int ret = 0;
1651
1652 if (islpci_get_state(priv) < PRV_STATE_INIT)
1653 return 0;
1654
1655 /* first get the flags */
1656 ret = mgt_get_request(priv, DOT11_OID_AUTHENABLE, 0, NULL, &r);
1657 authen = r.u;
1658 ret = mgt_get_request(priv, DOT11_OID_PRIVACYINVOKED, 0, NULL, &r);
1659 invoke = r.u;
1660 ret = mgt_get_request(priv, DOT11_OID_EXUNENCRYPTED, 0, NULL, &r);
1661 exunencrypt = r.u;
1662 if (ret < 0)
1663 goto out;
1664
1665 max_key_len = encoding->length - sizeof(*ext);
1666 if (max_key_len < 0)
1667 return -EINVAL;
1668
1669 idx = (encoding->flags & IW_ENCODE_INDEX) - 1;
1670 if (idx) {
1671 if (idx < 0 || idx > 3)
1672 return -EINVAL;
1673 } else {
1674 ret = mgt_get_request(priv, DOT11_OID_DEFKEYID, 0, NULL, &r);
1675 if (ret < 0)
1676 goto out;
1677 idx = r.u;
1678 }
1679
1680 encoding->flags = idx + 1;
1681 memset(ext, 0, sizeof(*ext));
1682
1683 switch (authen) {
1684 case DOT11_AUTH_BOTH:
1685 case DOT11_AUTH_SK:
1686 wrqu->encoding.flags |= IW_ENCODE_RESTRICTED;
1687 case DOT11_AUTH_OS:
1688 default:
1689 wrqu->encoding.flags |= IW_ENCODE_OPEN;
1690 break;
1691 }
1692
1693 down_write(&priv->mib_sem);
1694 wpa = priv->wpa;
1695 up_write(&priv->mib_sem);
1696
1697 if (authen == DOT11_AUTH_OS && !exunencrypt && !invoke && !wpa) {
1698 /* No encryption */
1699 ext->alg = IW_ENCODE_ALG_NONE;
1700 ext->key_len = 0;
1701 wrqu->encoding.flags |= IW_ENCODE_DISABLED;
1702 } else {
1703 struct obj_key *key;
1704
1705 ret = mgt_get_request(priv, DOT11_OID_DEFKEYX, idx, NULL, &r);
1706 if (ret < 0)
1707 goto out;
1708 key = r.ptr;
1709 if (max_key_len < key->length) {
1710 ret = -E2BIG;
1711 goto out;
1712 }
1713 memcpy(ext->key, key->key, key->length);
1714 ext->key_len = key->length;
1715
1716 switch (key->type) {
1717 case DOT11_PRIV_TKIP:
1718 ext->alg = IW_ENCODE_ALG_TKIP;
1719 break;
1720 default:
1721 case DOT11_PRIV_WEP:
1722 ext->alg = IW_ENCODE_ALG_WEP;
1723 break;
1724 }
1725 wrqu->encoding.flags |= IW_ENCODE_ENABLED;
1726 }
1727
1728out:
1729 return ret;
1730}
1731
1732
1213static int 1733static int
1214prism54_reset(struct net_device *ndev, struct iw_request_info *info, 1734prism54_reset(struct net_device *ndev, struct iw_request_info *info,
1215 __u32 * uwrq, char *extra) 1735 __u32 * uwrq, char *extra)
@@ -1591,8 +2111,8 @@ static u8 wpa_oid[4] = { 0x00, 0x50, 0xf2, 1 };
1591#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x" 2111#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
1592 2112
1593static void 2113static void
1594prism54_wpa_ie_add(islpci_private *priv, u8 *bssid, 2114prism54_wpa_bss_ie_add(islpci_private *priv, u8 *bssid,
1595 u8 *wpa_ie, size_t wpa_ie_len) 2115 u8 *wpa_ie, size_t wpa_ie_len)
1596{ 2116{
1597 struct list_head *ptr; 2117 struct list_head *ptr;
1598 struct islpci_bss_wpa_ie *bss = NULL; 2118 struct islpci_bss_wpa_ie *bss = NULL;
@@ -1658,7 +2178,7 @@ prism54_wpa_ie_add(islpci_private *priv, u8 *bssid,
1658} 2178}
1659 2179
1660static size_t 2180static size_t
1661prism54_wpa_ie_get(islpci_private *priv, u8 *bssid, u8 *wpa_ie) 2181prism54_wpa_bss_ie_get(islpci_private *priv, u8 *bssid, u8 *wpa_ie)
1662{ 2182{
1663 struct list_head *ptr; 2183 struct list_head *ptr;
1664 struct islpci_bss_wpa_ie *bss = NULL; 2184 struct islpci_bss_wpa_ie *bss = NULL;
@@ -1683,14 +2203,14 @@ prism54_wpa_ie_get(islpci_private *priv, u8 *bssid, u8 *wpa_ie)
1683} 2203}
1684 2204
1685void 2205void
1686prism54_wpa_ie_init(islpci_private *priv) 2206prism54_wpa_bss_ie_init(islpci_private *priv)
1687{ 2207{
1688 INIT_LIST_HEAD(&priv->bss_wpa_list); 2208 INIT_LIST_HEAD(&priv->bss_wpa_list);
1689 sema_init(&priv->wpa_sem, 1); 2209 sema_init(&priv->wpa_sem, 1);
1690} 2210}
1691 2211
1692void 2212void
1693prism54_wpa_ie_clean(islpci_private *priv) 2213prism54_wpa_bss_ie_clean(islpci_private *priv)
1694{ 2214{
1695 struct list_head *ptr, *n; 2215 struct list_head *ptr, *n;
1696 2216
@@ -1722,7 +2242,7 @@ prism54_process_bss_data(islpci_private *priv, u32 oid, u8 *addr,
1722 } 2242 }
1723 if (pos[0] == WLAN_EID_GENERIC && pos[1] >= 4 && 2243 if (pos[0] == WLAN_EID_GENERIC && pos[1] >= 4 &&
1724 memcmp(pos + 2, wpa_oid, 4) == 0) { 2244 memcmp(pos + 2, wpa_oid, 4) == 0) {
1725 prism54_wpa_ie_add(priv, addr, pos, pos[1] + 2); 2245 prism54_wpa_bss_ie_add(priv, addr, pos, pos[1] + 2);
1726 return; 2246 return;
1727 } 2247 }
1728 pos += 2 + pos[1]; 2248 pos += 2 + pos[1];
@@ -1879,7 +2399,7 @@ prism54_process_trap_helper(islpci_private *priv, enum oid_num_t oid,
1879 send_formatted_event(priv, "Associate request (ex)", mlme, 1); 2399 send_formatted_event(priv, "Associate request (ex)", mlme, 1);
1880 2400
1881 if (priv->iw_mode != IW_MODE_MASTER 2401 if (priv->iw_mode != IW_MODE_MASTER
1882 && mlmeex->state != DOT11_STATE_AUTHING) 2402 && mlmeex->state != DOT11_STATE_ASSOCING)
1883 break; 2403 break;
1884 2404
1885 confirm = kmalloc(sizeof(struct obj_mlmeex), GFP_ATOMIC); 2405 confirm = kmalloc(sizeof(struct obj_mlmeex), GFP_ATOMIC);
@@ -1893,7 +2413,7 @@ prism54_process_trap_helper(islpci_private *priv, enum oid_num_t oid,
1893 confirm->state = 0; /* not used */ 2413 confirm->state = 0; /* not used */
1894 confirm->code = 0; 2414 confirm->code = 0;
1895 2415
1896 wpa_ie_len = prism54_wpa_ie_get(priv, mlmeex->address, wpa_ie); 2416 wpa_ie_len = prism54_wpa_bss_ie_get(priv, mlmeex->address, wpa_ie);
1897 2417
1898 if (!wpa_ie_len) { 2418 if (!wpa_ie_len) {
1899 printk(KERN_DEBUG "No WPA IE found from " 2419 printk(KERN_DEBUG "No WPA IE found from "
@@ -1937,7 +2457,7 @@ prism54_process_trap_helper(islpci_private *priv, enum oid_num_t oid,
1937 confirm->state = 0; /* not used */ 2457 confirm->state = 0; /* not used */
1938 confirm->code = 0; 2458 confirm->code = 0;
1939 2459
1940 wpa_ie_len = prism54_wpa_ie_get(priv, mlmeex->address, wpa_ie); 2460 wpa_ie_len = prism54_wpa_bss_ie_get(priv, mlmeex->address, wpa_ie);
1941 2461
1942 if (!wpa_ie_len) { 2462 if (!wpa_ie_len) {
1943 printk(KERN_DEBUG "No WPA IE found from " 2463 printk(KERN_DEBUG "No WPA IE found from "
@@ -2553,6 +3073,15 @@ static const iw_handler prism54_handler[] = {
2553 (iw_handler) prism54_get_encode, /* SIOCGIWENCODE */ 3073 (iw_handler) prism54_get_encode, /* SIOCGIWENCODE */
2554 (iw_handler) NULL, /* SIOCSIWPOWER */ 3074 (iw_handler) NULL, /* SIOCSIWPOWER */
2555 (iw_handler) NULL, /* SIOCGIWPOWER */ 3075 (iw_handler) NULL, /* SIOCGIWPOWER */
3076 NULL, /* -- hole -- */
3077 NULL, /* -- hole -- */
3078 (iw_handler) prism54_set_genie, /* SIOCSIWGENIE */
3079 (iw_handler) prism54_get_genie, /* SIOCGIWGENIE */
3080 (iw_handler) prism54_set_auth, /* SIOCSIWAUTH */
3081 (iw_handler) prism54_get_auth, /* SIOCGIWAUTH */
3082 (iw_handler) prism54_set_encodeext, /* SIOCSIWENCODEEXT */
3083 (iw_handler) prism54_get_encodeext, /* SIOCGIWENCODEEXT */
3084 NULL, /* SIOCSIWPMKSA */
2556}; 3085};
2557 3086
2558/* The low order bit identify a SET (0) or a GET (1) ioctl. */ 3087/* 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/prism54/islpci_hotplug.c b/drivers/net/wireless/prism54/islpci_hotplug.c
index 09fc17a0f029..f692dccf0d07 100644
--- a/drivers/net/wireless/prism54/islpci_hotplug.c
+++ b/drivers/net/wireless/prism54/islpci_hotplug.c
@@ -313,7 +313,7 @@ prism54_module_init(void)
313 313
314 __bug_on_wrong_struct_sizes (); 314 __bug_on_wrong_struct_sizes ();
315 315
316 return pci_module_init(&prism54_driver); 316 return pci_register_driver(&prism54_driver);
317} 317}
318 318
319/* by the time prism54_module_exit() terminates, as a postcondition 319/* by the time prism54_module_exit() terminates, as a postcondition
diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c
index 61b83a5e737a..4574290f971f 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>
@@ -99,7 +99,7 @@ static int ray_dev_config(struct net_device *dev, struct ifmap *map);
99static struct net_device_stats *ray_get_stats(struct net_device *dev); 99static struct net_device_stats *ray_get_stats(struct net_device *dev);
100static int ray_dev_init(struct net_device *dev); 100static int ray_dev_init(struct net_device *dev);
101 101
102static struct ethtool_ops netdev_ethtool_ops; 102static const struct ethtool_ops netdev_ethtool_ops;
103 103
104static int ray_open(struct net_device *dev); 104static int ray_open(struct net_device *dev);
105static int ray_dev_start_xmit(struct sk_buff *skb, struct net_device *dev); 105static int ray_dev_start_xmit(struct sk_buff *skb, struct net_device *dev);
@@ -1092,7 +1092,7 @@ static void netdev_get_drvinfo(struct net_device *dev,
1092 strcpy(info->driver, "ray_cs"); 1092 strcpy(info->driver, "ray_cs");
1093} 1093}
1094 1094
1095static struct ethtool_ops netdev_ethtool_ops = { 1095static const struct ethtool_ops netdev_ethtool_ops = {
1096 .get_drvinfo = netdev_get_drvinfo, 1096 .get_drvinfo = netdev_get_drvinfo,
1097}; 1097};
1098 1098
diff --git a/drivers/net/wireless/wavelan_cs.c b/drivers/net/wireless/wavelan_cs.c
index 561250f73fd3..0065f057bb1c 100644
--- a/drivers/net/wireless/wavelan_cs.c
+++ b/drivers/net/wireless/wavelan_cs.c
@@ -1837,7 +1837,7 @@ static void wl_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
1837 strncpy(info->driver, "wavelan_cs", sizeof(info->driver)-1); 1837 strncpy(info->driver, "wavelan_cs", sizeof(info->driver)-1);
1838} 1838}
1839 1839
1840static struct ethtool_ops ops = { 1840static const struct ethtool_ops ops = {
1841 .get_drvinfo = wl_get_drvinfo 1841 .get_drvinfo = wl_get_drvinfo
1842}; 1842};
1843 1843
diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c
index c03e400facee..e0d294c12970 100644
--- a/drivers/net/wireless/wl3501_cs.c
+++ b/drivers/net/wireless/wl3501_cs.c
@@ -1464,7 +1464,7 @@ static void wl3501_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *i
1464 strlcpy(info->driver, wl3501_dev_info, sizeof(info->driver)); 1464 strlcpy(info->driver, wl3501_dev_info, sizeof(info->driver));
1465} 1465}
1466 1466
1467static struct ethtool_ops ops = { 1467static const struct ethtool_ops ops = {
1468 .get_drvinfo = wl3501_get_drvinfo 1468 .get_drvinfo = wl3501_get_drvinfo
1469}; 1469};
1470 1470
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 aa792821854e..7c4e32cf0d47 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
@@ -1644,3 +1649,34 @@ int zd_rfwritev_locked(struct zd_chip *chip,
1644 1649
1645 return 0; 1650 return 0;
1646} 1651}
1652
1653/*
1654 * We can optionally program the RF directly through CR regs, if supported by
1655 * the hardware. This is much faster than the older method.
1656 */
1657int zd_rfwrite_cr_locked(struct zd_chip *chip, u32 value)
1658{
1659 struct zd_ioreq16 ioreqs[] = {
1660 { CR244, (value >> 16) & 0xff },
1661 { CR243, (value >> 8) & 0xff },
1662 { CR242, value & 0xff },
1663 };
1664 ZD_ASSERT(mutex_is_locked(&chip->mutex));
1665 return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
1666}
1667
1668int zd_rfwritev_cr_locked(struct zd_chip *chip,
1669 const u32 *values, unsigned int count)
1670{
1671 int r;
1672 unsigned int i;
1673
1674 for (i = 0; i < count; i++) {
1675 r = zd_rfwrite_cr_locked(chip, values[i]);
1676 if (r)
1677 return r;
1678 }
1679
1680 return 0;
1681}
1682
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_ieee80211.h b/drivers/net/wireless/zd1211rw/zd_ieee80211.h
index 36329890dfec..f63245b0d966 100644
--- a/drivers/net/wireless/zd1211rw/zd_ieee80211.h
+++ b/drivers/net/wireless/zd1211rw/zd_ieee80211.h
@@ -64,7 +64,7 @@ struct cck_plcp_header {
64 u8 service; 64 u8 service;
65 __le16 length; 65 __le16 length;
66 __le16 crc16; 66 __le16 crc16;
67} __attribute__((packed)); 67};
68 68
69static inline u8 zd_cck_plcp_header_rate(const struct cck_plcp_header *header) 69static inline u8 zd_cck_plcp_header_rate(const struct cck_plcp_header *header)
70{ 70{
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c
index a9bd80a08613..1989f1c05fbe 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)
@@ -716,7 +714,7 @@ struct zd_rt_hdr {
716 u8 rt_rate; 714 u8 rt_rate;
717 u16 rt_channel; 715 u16 rt_channel;
718 u16 rt_chbitmask; 716 u16 rt_chbitmask;
719} __attribute__((packed)); 717};
720 718
721static void fill_rt_header(void *buffer, struct zd_mac *mac, 719static void fill_rt_header(void *buffer, struct zd_mac *mac,
722 const struct ieee80211_rx_stats *stats, 720 const struct ieee80211_rx_stats *stats,
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.h b/drivers/net/wireless/zd1211rw/zd_mac.h
index b3ba49b84634..29b51fd7d4e5 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.h
+++ b/drivers/net/wireless/zd1211rw/zd_mac.h
@@ -82,7 +82,7 @@ struct zd_ctrlset {
82struct rx_length_info { 82struct rx_length_info {
83 __le16 length[3]; 83 __le16 length[3];
84 __le16 tag; 84 __le16 tag;
85} __attribute__((packed)); 85};
86 86
87#define RX_LENGTH_INFO_TAG 0x697e 87#define RX_LENGTH_INFO_TAG 0x697e
88 88
@@ -93,7 +93,7 @@ struct rx_status {
93 u8 signal_quality_ofdm; 93 u8 signal_quality_ofdm;
94 u8 decryption_type; 94 u8 decryption_type;
95 u8 frame_status; 95 u8 frame_status;
96} __attribute__((packed)); 96};
97 97
98/* rx_status field decryption_type */ 98/* rx_status field decryption_type */
99#define ZD_RX_NO_WEP 0 99#define ZD_RX_NO_WEP 0
@@ -123,9 +123,9 @@ enum mac_flags {
123#define ZD_MAC_STATS_BUFFER_SIZE 16 123#define ZD_MAC_STATS_BUFFER_SIZE 16
124 124
125struct zd_mac { 125struct zd_mac {
126 struct net_device *netdev;
127 struct zd_chip chip; 126 struct zd_chip chip;
128 spinlock_t lock; 127 spinlock_t lock;
128 struct net_device *netdev;
129 /* Unlocked reading possible */ 129 /* Unlocked reading possible */
130 struct iw_statistics iw_stats; 130 struct iw_statistics iw_stats;
131 unsigned int stats_count; 131 unsigned int stats_count;
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..31027e52b04b 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,19 @@ 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 },
47 { USB_DEVICE(0x0b3b, 0x5630), .driver_info = DEVICE_ZD1211 },
48 { USB_DEVICE(0x0b05, 0x170c), .driver_info = DEVICE_ZD1211 },
42 /* ZD1211B */ 49 /* ZD1211B */
43 { USB_DEVICE(0x0ace, 0x1215), .driver_info = DEVICE_ZD1211B }, 50 { USB_DEVICE(0x0ace, 0x1215), .driver_info = DEVICE_ZD1211B },
44 { USB_DEVICE(0x157e, 0x300d), .driver_info = DEVICE_ZD1211B }, 51 { USB_DEVICE(0x157e, 0x300d), .driver_info = DEVICE_ZD1211B },
52 { USB_DEVICE(0x079b, 0x0062), .driver_info = DEVICE_ZD1211B },
53 { USB_DEVICE(0x1582, 0x6003), .driver_info = DEVICE_ZD1211B },
54 /* "Driverless" devices that need ejecting */
55 { USB_DEVICE(0x0ace, 0x2011), .driver_info = DEVICE_INSTALLER },
45 {} 56 {}
46}; 57};
47 58
@@ -263,6 +274,39 @@ static char *get_fw_name(char *buffer, size_t size, u8 device_type,
263 return buffer; 274 return buffer;
264} 275}
265 276
277static int handle_version_mismatch(struct usb_device *udev, u8 device_type,
278 const struct firmware *ub_fw)
279{
280 const struct firmware *ur_fw = NULL;
281 int offset;
282 int r = 0;
283 char fw_name[128];
284
285 r = request_fw_file(&ur_fw,
286 get_fw_name(fw_name, sizeof(fw_name), device_type, "ur"),
287 &udev->dev);
288 if (r)
289 goto error;
290
291 r = upload_code(udev, ur_fw->data, ur_fw->size, FW_START_OFFSET,
292 REBOOT);
293 if (r)
294 goto error;
295
296 offset = ((EEPROM_REGS_OFFSET + EEPROM_REGS_SIZE) * sizeof(u16));
297 r = upload_code(udev, ub_fw->data + offset, ub_fw->size - offset,
298 E2P_BASE_OFFSET + EEPROM_REGS_SIZE, REBOOT);
299
300 /* At this point, the vendor driver downloads the whole firmware
301 * image, hacks around with version IDs, and uploads it again,
302 * completely overwriting the boot code. We do not do this here as
303 * it is not required on any tested devices, and it is suspected to
304 * cause problems. */
305error:
306 release_firmware(ur_fw);
307 return r;
308}
309
266static int upload_firmware(struct usb_device *udev, u8 device_type) 310static int upload_firmware(struct usb_device *udev, u8 device_type)
267{ 311{
268 int r; 312 int r;
@@ -282,15 +326,17 @@ static int upload_firmware(struct usb_device *udev, u8 device_type)
282 326
283 fw_bcdDevice = get_word(ub_fw->data, EEPROM_REGS_OFFSET); 327 fw_bcdDevice = get_word(ub_fw->data, EEPROM_REGS_OFFSET);
284 328
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) { 329 if (fw_bcdDevice != bcdDevice) {
290 dev_info(&udev->dev, 330 dev_info(&udev->dev,
291 "firmware device id %#06x and actual device id " 331 "firmware version %#06x and device bootcode version "
292 "%#06x differ, continuing anyway\n", 332 "%#06x differ\n", fw_bcdDevice, bcdDevice);
293 fw_bcdDevice, bcdDevice); 333 if (bcdDevice <= 0x4313)
334 dev_warn(&udev->dev, "device has old bootcode, please "
335 "report success or failure\n");
336
337 r = handle_version_mismatch(udev, device_type, ub_fw);
338 if (r)
339 goto error;
294 } else { 340 } else {
295 dev_dbg_f(&udev->dev, 341 dev_dbg_f(&udev->dev,
296 "firmware device id %#06x is equal to the " 342 "firmware device id %#06x is equal to the "
@@ -620,7 +666,7 @@ resubmit:
620 usb_submit_urb(urb, GFP_ATOMIC); 666 usb_submit_urb(urb, GFP_ATOMIC);
621} 667}
622 668
623struct urb *alloc_urb(struct zd_usb *usb) 669static struct urb *alloc_urb(struct zd_usb *usb)
624{ 670{
625 struct usb_device *udev = zd_usb_to_usbdev(usb); 671 struct usb_device *udev = zd_usb_to_usbdev(usb);
626 struct urb *urb; 672 struct urb *urb;
@@ -644,7 +690,7 @@ struct urb *alloc_urb(struct zd_usb *usb)
644 return urb; 690 return urb;
645} 691}
646 692
647void free_urb(struct urb *urb) 693static void free_urb(struct urb *urb)
648{ 694{
649 if (!urb) 695 if (!urb)
650 return; 696 return;
@@ -864,7 +910,7 @@ void zd_usb_clear(struct zd_usb *usb)
864{ 910{
865 usb_set_intfdata(usb->intf, NULL); 911 usb_set_intfdata(usb->intf, NULL);
866 usb_put_intf(usb->intf); 912 usb_put_intf(usb->intf);
867 memset(usb, 0, sizeof(*usb)); 913 ZD_MEMCLEAR(usb, sizeof(*usb));
868 /* FIXME: usb_interrupt, usb_tx, usb_rx? */ 914 /* FIXME: usb_interrupt, usb_tx, usb_rx? */
869} 915}
870 916
@@ -910,6 +956,55 @@ static void print_id(struct usb_device *udev)
910#define print_id(udev) do { } while (0) 956#define print_id(udev) do { } while (0)
911#endif 957#endif
912 958
959static int eject_installer(struct usb_interface *intf)
960{
961 struct usb_device *udev = interface_to_usbdev(intf);
962 struct usb_host_interface *iface_desc = &intf->altsetting[0];
963 struct usb_endpoint_descriptor *endpoint;
964 unsigned char *cmd;
965 u8 bulk_out_ep;
966 int r;
967
968 /* Find bulk out endpoint */
969 endpoint = &iface_desc->endpoint[1].desc;
970 if ((endpoint->bEndpointAddress & USB_TYPE_MASK) == USB_DIR_OUT &&
971 (endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
972 USB_ENDPOINT_XFER_BULK) {
973 bulk_out_ep = endpoint->bEndpointAddress;
974 } else {
975 dev_err(&udev->dev,
976 "zd1211rw: Could not find bulk out endpoint\n");
977 return -ENODEV;
978 }
979
980 cmd = kzalloc(31, GFP_KERNEL);
981 if (cmd == NULL)
982 return -ENODEV;
983
984 /* USB bulk command block */
985 cmd[0] = 0x55; /* bulk command signature */
986 cmd[1] = 0x53; /* bulk command signature */
987 cmd[2] = 0x42; /* bulk command signature */
988 cmd[3] = 0x43; /* bulk command signature */
989 cmd[14] = 6; /* command length */
990
991 cmd[15] = 0x1b; /* SCSI command: START STOP UNIT */
992 cmd[19] = 0x2; /* eject disc */
993
994 dev_info(&udev->dev, "Ejecting virtual installer media...\n");
995 r = usb_bulk_msg(udev, usb_sndbulkpipe(udev, bulk_out_ep),
996 cmd, 31, NULL, 2000);
997 kfree(cmd);
998 if (r)
999 return r;
1000
1001 /* At this point, the device disconnects and reconnects with the real
1002 * ID numbers. */
1003
1004 usb_set_intfdata(intf, NULL);
1005 return 0;
1006}
1007
913static int probe(struct usb_interface *intf, const struct usb_device_id *id) 1008static int probe(struct usb_interface *intf, const struct usb_device_id *id)
914{ 1009{
915 int r; 1010 int r;
@@ -918,6 +1013,9 @@ static int probe(struct usb_interface *intf, const struct usb_device_id *id)
918 1013
919 print_id(udev); 1014 print_id(udev);
920 1015
1016 if (id->driver_info & DEVICE_INSTALLER)
1017 return eject_installer(intf);
1018
921 switch (udev->speed) { 1019 switch (udev->speed) {
922 case USB_SPEED_LOW: 1020 case USB_SPEED_LOW:
923 case USB_SPEED_FULL: 1021 case USB_SPEED_FULL:
@@ -983,6 +1081,11 @@ static void disconnect(struct usb_interface *intf)
983 struct zd_mac *mac = zd_netdev_mac(netdev); 1081 struct zd_mac *mac = zd_netdev_mac(netdev);
984 struct zd_usb *usb = &mac->chip.usb; 1082 struct zd_usb *usb = &mac->chip.usb;
985 1083
1084 /* Either something really bad happened, or we're just dealing with
1085 * a DEVICE_INSTALLER. */
1086 if (netdev == NULL)
1087 return;
1088
986 dev_dbg_f(zd_usb_dev(usb), "\n"); 1089 dev_dbg_f(zd_usb_dev(usb), "\n");
987 1090
988 zd_netdev_disconnect(netdev); 1091 zd_netdev_disconnect(netdev);
@@ -998,7 +1101,6 @@ static void disconnect(struct usb_interface *intf)
998 */ 1101 */
999 usb_reset_device(interface_to_usbdev(intf)); 1102 usb_reset_device(interface_to_usbdev(intf));
1000 1103
1001 /* If somebody still waits on this lock now, this is an error. */
1002 zd_netdev_free(netdev); 1104 zd_netdev_free(netdev);
1003 dev_dbg(&intf->dev, "disconnected\n"); 1105 dev_dbg(&intf->dev, "disconnected\n");
1004} 1106}
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.h b/drivers/net/wireless/zd1211rw/zd_usb.h
index d6420283bd5a..ded39de5f72d 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 {
@@ -73,17 +74,17 @@ enum control_requests {
73struct usb_req_read_regs { 74struct usb_req_read_regs {
74 __le16 id; 75 __le16 id;
75 __le16 addr[0]; 76 __le16 addr[0];
76} __attribute__((packed)); 77};
77 78
78struct reg_data { 79struct reg_data {
79 __le16 addr; 80 __le16 addr;
80 __le16 value; 81 __le16 value;
81} __attribute__((packed)); 82};
82 83
83struct usb_req_write_regs { 84struct usb_req_write_regs {
84 __le16 id; 85 __le16 id;
85 struct reg_data reg_writes[0]; 86 struct reg_data reg_writes[0];
86} __attribute__((packed)); 87};
87 88
88enum { 89enum {
89 RF_IF_LE = 0x02, 90 RF_IF_LE = 0x02,
@@ -100,7 +101,7 @@ struct usb_req_rfwrite {
100 /* RF2595: 24 */ 101 /* RF2595: 24 */
101 __le16 bit_values[0]; 102 __le16 bit_values[0];
102 /* (CR203 & ~(RF_IF_LE | RF_CLK | RF_DATA)) | (bit ? RF_DATA : 0) */ 103 /* (CR203 & ~(RF_IF_LE | RF_CLK | RF_DATA)) | (bit ? RF_DATA : 0) */
103} __attribute__((packed)); 104};
104 105
105/* USB interrupt */ 106/* USB interrupt */
106 107
@@ -117,12 +118,12 @@ enum usb_int_flags {
117struct usb_int_header { 118struct usb_int_header {
118 u8 type; /* must always be 1 */ 119 u8 type; /* must always be 1 */
119 u8 id; 120 u8 id;
120} __attribute__((packed)); 121};
121 122
122struct usb_int_regs { 123struct usb_int_regs {
123 struct usb_int_header hdr; 124 struct usb_int_header hdr;
124 struct reg_data regs[0]; 125 struct reg_data regs[0];
125} __attribute__((packed)); 126};
126 127
127struct usb_int_retry_fail { 128struct usb_int_retry_fail {
128 struct usb_int_header hdr; 129 struct usb_int_header hdr;
@@ -130,7 +131,7 @@ struct usb_int_retry_fail {
130 u8 _dummy; 131 u8 _dummy;
131 u8 addr[ETH_ALEN]; 132 u8 addr[ETH_ALEN];
132 u8 ibss_wakeup_dest; 133 u8 ibss_wakeup_dest;
133} __attribute__((packed)); 134};
134 135
135struct read_regs_int { 136struct read_regs_int {
136 struct completion completion; 137 struct completion completion;