Merge ARM fixes
[sfrench/cifs-2.6.git] / drivers / net / wireless / bcm43xx / bcm43xx_main.c
1 /*
2
3   Broadcom BCM43xx wireless driver
4
5   Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>,
6                      Stefano Brivio <st3@riseup.net>
7                      Michael Buesch <mbuesch@freenet.de>
8                      Danny van Dyk <kugelfang@gentoo.org>
9                      Andreas Jaggi <andreas.jaggi@waterwave.ch>
10
11   Some parts of the code in this file are derived from the ipw2200
12   driver  Copyright(c) 2003 - 2004 Intel Corporation.
13
14   This program is free software; you can redistribute it and/or modify
15   it under the terms of the GNU General Public License as published by
16   the Free Software Foundation; either version 2 of the License, or
17   (at your option) any later version.
18
19   This program is distributed in the hope that it will be useful,
20   but WITHOUT ANY WARRANTY; without even the implied warranty of
21   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22   GNU General Public License for more details.
23
24   You should have received a copy of the GNU General Public License
25   along with this program; see the file COPYING.  If not, write to
26   the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
27   Boston, MA 02110-1301, USA.
28
29 */
30
31 #include <linux/delay.h>
32 #include <linux/init.h>
33 #include <linux/moduleparam.h>
34 #include <linux/if_arp.h>
35 #include <linux/etherdevice.h>
36 #include <linux/version.h>
37 #include <linux/firmware.h>
38 #include <linux/wireless.h>
39 #include <linux/workqueue.h>
40 #include <linux/skbuff.h>
41 #include <linux/dma-mapping.h>
42 #include <net/iw_handler.h>
43
44 #include "bcm43xx.h"
45 #include "bcm43xx_main.h"
46 #include "bcm43xx_debugfs.h"
47 #include "bcm43xx_radio.h"
48 #include "bcm43xx_phy.h"
49 #include "bcm43xx_dma.h"
50 #include "bcm43xx_pio.h"
51 #include "bcm43xx_power.h"
52 #include "bcm43xx_wx.h"
53 #include "bcm43xx_ethtool.h"
54 #include "bcm43xx_xmit.h"
55 #include "bcm43xx_sysfs.h"
56
57
58 MODULE_DESCRIPTION("Broadcom BCM43xx wireless driver");
59 MODULE_AUTHOR("Martin Langer");
60 MODULE_AUTHOR("Stefano Brivio");
61 MODULE_AUTHOR("Michael Buesch");
62 MODULE_LICENSE("GPL");
63
64 #ifdef CONFIG_BCM947XX
65 extern char *nvram_get(char *name);
66 #endif
67
68 #if defined(CONFIG_BCM43XX_DMA) && defined(CONFIG_BCM43XX_PIO)
69 static int modparam_pio;
70 module_param_named(pio, modparam_pio, int, 0444);
71 MODULE_PARM_DESC(pio, "enable(1) / disable(0) PIO mode");
72 #elif defined(CONFIG_BCM43XX_DMA)
73 # define modparam_pio   0
74 #elif defined(CONFIG_BCM43XX_PIO)
75 # define modparam_pio   1
76 #endif
77
78 static int modparam_bad_frames_preempt;
79 module_param_named(bad_frames_preempt, modparam_bad_frames_preempt, int, 0444);
80 MODULE_PARM_DESC(bad_frames_preempt, "enable(1) / disable(0) Bad Frames Preemption");
81
82 static int modparam_short_retry = BCM43xx_DEFAULT_SHORT_RETRY_LIMIT;
83 module_param_named(short_retry, modparam_short_retry, int, 0444);
84 MODULE_PARM_DESC(short_retry, "Short-Retry-Limit (0 - 15)");
85
86 static int modparam_long_retry = BCM43xx_DEFAULT_LONG_RETRY_LIMIT;
87 module_param_named(long_retry, modparam_long_retry, int, 0444);
88 MODULE_PARM_DESC(long_retry, "Long-Retry-Limit (0 - 15)");
89
90 static int modparam_locale = -1;
91 module_param_named(locale, modparam_locale, int, 0444);
92 MODULE_PARM_DESC(country, "Select LocaleCode 0-11 (For travelers)");
93
94 static int modparam_noleds;
95 module_param_named(noleds, modparam_noleds, int, 0444);
96 MODULE_PARM_DESC(noleds, "Turn off all LED activity");
97
98 static char modparam_fwpostfix[64];
99 module_param_string(fwpostfix, modparam_fwpostfix, 64, 0444);
100 MODULE_PARM_DESC(fwpostfix, "Postfix for .fw files. Useful for using multiple firmware image versions.");
101
102
103 /* If you want to debug with just a single device, enable this,
104  * where the string is the pci device ID (as given by the kernel's
105  * pci_name function) of the device to be used.
106  */
107 //#define DEBUG_SINGLE_DEVICE_ONLY      "0001:11:00.0"
108
109 /* If you want to enable printing of each MMIO access, enable this. */
110 //#define DEBUG_ENABLE_MMIO_PRINT
111
112 /* If you want to enable printing of MMIO access within
113  * ucode/pcm upload, initvals write, enable this.
114  */
115 //#define DEBUG_ENABLE_UCODE_MMIO_PRINT
116
117 /* If you want to enable printing of PCI Config Space access, enable this */
118 //#define DEBUG_ENABLE_PCILOG
119
120
121 /* Detailed list maintained at:
122  * http://openfacts.berlios.de/index-en.phtml?title=Bcm43xxDevices
123  */
124         static struct pci_device_id bcm43xx_pci_tbl[] = {
125         /* Broadcom 4303 802.11b */
126         { PCI_VENDOR_ID_BROADCOM, 0x4301, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
127         /* Broadcom 4307 802.11b */
128         { PCI_VENDOR_ID_BROADCOM, 0x4307, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
129         /* Broadcom 4311 802.11(a)/b/g */
130         { PCI_VENDOR_ID_BROADCOM, 0x4311, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
131         /* Broadcom 4312 802.11a/b/g */
132         { PCI_VENDOR_ID_BROADCOM, 0x4312, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
133         /* Broadcom 4318 802.11b/g */
134         { PCI_VENDOR_ID_BROADCOM, 0x4318, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
135         /* Broadcom 4319 802.11a/b/g */
136         { PCI_VENDOR_ID_BROADCOM, 0x4319, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
137         /* Broadcom 4306 802.11b/g */
138         { PCI_VENDOR_ID_BROADCOM, 0x4320, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
139         /* Broadcom 4306 802.11a */
140 //      { PCI_VENDOR_ID_BROADCOM, 0x4321, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
141         /* Broadcom 4309 802.11a/b/g */
142         { PCI_VENDOR_ID_BROADCOM, 0x4324, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
143         /* Broadcom 43XG 802.11b/g */
144         { PCI_VENDOR_ID_BROADCOM, 0x4325, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
145 #ifdef CONFIG_BCM947XX
146         /* SB bus on BCM947xx */
147         { PCI_VENDOR_ID_BROADCOM, 0x0800, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
148 #endif
149         { 0 },
150 };
151 MODULE_DEVICE_TABLE(pci, bcm43xx_pci_tbl);
152
153 static void bcm43xx_ram_write(struct bcm43xx_private *bcm, u16 offset, u32 val)
154 {
155         u32 status;
156
157         status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
158         if (!(status & BCM43xx_SBF_XFER_REG_BYTESWAP))
159                 val = swab32(val);
160
161         bcm43xx_write32(bcm, BCM43xx_MMIO_RAM_CONTROL, offset);
162         mmiowb();
163         bcm43xx_write32(bcm, BCM43xx_MMIO_RAM_DATA, val);
164 }
165
166 static inline
167 void bcm43xx_shm_control_word(struct bcm43xx_private *bcm,
168                               u16 routing, u16 offset)
169 {
170         u32 control;
171
172         /* "offset" is the WORD offset. */
173
174         control = routing;
175         control <<= 16;
176         control |= offset;
177         bcm43xx_write32(bcm, BCM43xx_MMIO_SHM_CONTROL, control);
178 }
179
180 u32 bcm43xx_shm_read32(struct bcm43xx_private *bcm,
181                        u16 routing, u16 offset)
182 {
183         u32 ret;
184
185         if (routing == BCM43xx_SHM_SHARED) {
186                 if (offset & 0x0003) {
187                         /* Unaligned access */
188                         bcm43xx_shm_control_word(bcm, routing, offset >> 2);
189                         ret = bcm43xx_read16(bcm, BCM43xx_MMIO_SHM_DATA_UNALIGNED);
190                         ret <<= 16;
191                         bcm43xx_shm_control_word(bcm, routing, (offset >> 2) + 1);
192                         ret |= bcm43xx_read16(bcm, BCM43xx_MMIO_SHM_DATA);
193
194                         return ret;
195                 }
196                 offset >>= 2;
197         }
198         bcm43xx_shm_control_word(bcm, routing, offset);
199         ret = bcm43xx_read32(bcm, BCM43xx_MMIO_SHM_DATA);
200
201         return ret;
202 }
203
204 u16 bcm43xx_shm_read16(struct bcm43xx_private *bcm,
205                        u16 routing, u16 offset)
206 {
207         u16 ret;
208
209         if (routing == BCM43xx_SHM_SHARED) {
210                 if (offset & 0x0003) {
211                         /* Unaligned access */
212                         bcm43xx_shm_control_word(bcm, routing, offset >> 2);
213                         ret = bcm43xx_read16(bcm, BCM43xx_MMIO_SHM_DATA_UNALIGNED);
214
215                         return ret;
216                 }
217                 offset >>= 2;
218         }
219         bcm43xx_shm_control_word(bcm, routing, offset);
220         ret = bcm43xx_read16(bcm, BCM43xx_MMIO_SHM_DATA);
221
222         return ret;
223 }
224
225 void bcm43xx_shm_write32(struct bcm43xx_private *bcm,
226                          u16 routing, u16 offset,
227                          u32 value)
228 {
229         if (routing == BCM43xx_SHM_SHARED) {
230                 if (offset & 0x0003) {
231                         /* Unaligned access */
232                         bcm43xx_shm_control_word(bcm, routing, offset >> 2);
233                         mmiowb();
234                         bcm43xx_write16(bcm, BCM43xx_MMIO_SHM_DATA_UNALIGNED,
235                                         (value >> 16) & 0xffff);
236                         mmiowb();
237                         bcm43xx_shm_control_word(bcm, routing, (offset >> 2) + 1);
238                         mmiowb();
239                         bcm43xx_write16(bcm, BCM43xx_MMIO_SHM_DATA,
240                                         value & 0xffff);
241                         return;
242                 }
243                 offset >>= 2;
244         }
245         bcm43xx_shm_control_word(bcm, routing, offset);
246         mmiowb();
247         bcm43xx_write32(bcm, BCM43xx_MMIO_SHM_DATA, value);
248 }
249
250 void bcm43xx_shm_write16(struct bcm43xx_private *bcm,
251                          u16 routing, u16 offset,
252                          u16 value)
253 {
254         if (routing == BCM43xx_SHM_SHARED) {
255                 if (offset & 0x0003) {
256                         /* Unaligned access */
257                         bcm43xx_shm_control_word(bcm, routing, offset >> 2);
258                         mmiowb();
259                         bcm43xx_write16(bcm, BCM43xx_MMIO_SHM_DATA_UNALIGNED,
260                                         value);
261                         return;
262                 }
263                 offset >>= 2;
264         }
265         bcm43xx_shm_control_word(bcm, routing, offset);
266         mmiowb();
267         bcm43xx_write16(bcm, BCM43xx_MMIO_SHM_DATA, value);
268 }
269
270 void bcm43xx_tsf_read(struct bcm43xx_private *bcm, u64 *tsf)
271 {
272         /* We need to be careful. As we read the TSF from multiple
273          * registers, we should take care of register overflows.
274          * In theory, the whole tsf read process should be atomic.
275          * We try to be atomic here, by restaring the read process,
276          * if any of the high registers changed (overflew).
277          */
278         if (bcm->current_core->rev >= 3) {
279                 u32 low, high, high2;
280
281                 do {
282                         high = bcm43xx_read32(bcm, BCM43xx_MMIO_REV3PLUS_TSF_HIGH);
283                         low = bcm43xx_read32(bcm, BCM43xx_MMIO_REV3PLUS_TSF_LOW);
284                         high2 = bcm43xx_read32(bcm, BCM43xx_MMIO_REV3PLUS_TSF_HIGH);
285                 } while (unlikely(high != high2));
286
287                 *tsf = high;
288                 *tsf <<= 32;
289                 *tsf |= low;
290         } else {
291                 u64 tmp;
292                 u16 v0, v1, v2, v3;
293                 u16 test1, test2, test3;
294
295                 do {
296                         v3 = bcm43xx_read16(bcm, BCM43xx_MMIO_TSF_3);
297                         v2 = bcm43xx_read16(bcm, BCM43xx_MMIO_TSF_2);
298                         v1 = bcm43xx_read16(bcm, BCM43xx_MMIO_TSF_1);
299                         v0 = bcm43xx_read16(bcm, BCM43xx_MMIO_TSF_0);
300
301                         test3 = bcm43xx_read16(bcm, BCM43xx_MMIO_TSF_3);
302                         test2 = bcm43xx_read16(bcm, BCM43xx_MMIO_TSF_2);
303                         test1 = bcm43xx_read16(bcm, BCM43xx_MMIO_TSF_1);
304                 } while (v3 != test3 || v2 != test2 || v1 != test1);
305
306                 *tsf = v3;
307                 *tsf <<= 48;
308                 tmp = v2;
309                 tmp <<= 32;
310                 *tsf |= tmp;
311                 tmp = v1;
312                 tmp <<= 16;
313                 *tsf |= tmp;
314                 *tsf |= v0;
315         }
316 }
317
318 void bcm43xx_tsf_write(struct bcm43xx_private *bcm, u64 tsf)
319 {
320         u32 status;
321
322         status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
323         status |= BCM43xx_SBF_TIME_UPDATE;
324         bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, status);
325         mmiowb();
326
327         /* Be careful with the in-progress timer.
328          * First zero out the low register, so we have a full
329          * register-overflow duration to complete the operation.
330          */
331         if (bcm->current_core->rev >= 3) {
332                 u32 lo = (tsf & 0x00000000FFFFFFFFULL);
333                 u32 hi = (tsf & 0xFFFFFFFF00000000ULL) >> 32;
334
335                 bcm43xx_write32(bcm, BCM43xx_MMIO_REV3PLUS_TSF_LOW, 0);
336                 mmiowb();
337                 bcm43xx_write32(bcm, BCM43xx_MMIO_REV3PLUS_TSF_HIGH, hi);
338                 mmiowb();
339                 bcm43xx_write32(bcm, BCM43xx_MMIO_REV3PLUS_TSF_LOW, lo);
340         } else {
341                 u16 v0 = (tsf & 0x000000000000FFFFULL);
342                 u16 v1 = (tsf & 0x00000000FFFF0000ULL) >> 16;
343                 u16 v2 = (tsf & 0x0000FFFF00000000ULL) >> 32;
344                 u16 v3 = (tsf & 0xFFFF000000000000ULL) >> 48;
345
346                 bcm43xx_write16(bcm, BCM43xx_MMIO_TSF_0, 0);
347                 mmiowb();
348                 bcm43xx_write16(bcm, BCM43xx_MMIO_TSF_3, v3);
349                 mmiowb();
350                 bcm43xx_write16(bcm, BCM43xx_MMIO_TSF_2, v2);
351                 mmiowb();
352                 bcm43xx_write16(bcm, BCM43xx_MMIO_TSF_1, v1);
353                 mmiowb();
354                 bcm43xx_write16(bcm, BCM43xx_MMIO_TSF_0, v0);
355         }
356
357         status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
358         status &= ~BCM43xx_SBF_TIME_UPDATE;
359         bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, status);
360 }
361
362 static
363 void bcm43xx_macfilter_set(struct bcm43xx_private *bcm,
364                            u16 offset,
365                            const u8 *mac)
366 {
367         u16 data;
368
369         offset |= 0x0020;
370         bcm43xx_write16(bcm, BCM43xx_MMIO_MACFILTER_CONTROL, offset);
371
372         data = mac[0];
373         data |= mac[1] << 8;
374         bcm43xx_write16(bcm, BCM43xx_MMIO_MACFILTER_DATA, data);
375         data = mac[2];
376         data |= mac[3] << 8;
377         bcm43xx_write16(bcm, BCM43xx_MMIO_MACFILTER_DATA, data);
378         data = mac[4];
379         data |= mac[5] << 8;
380         bcm43xx_write16(bcm, BCM43xx_MMIO_MACFILTER_DATA, data);
381 }
382
383 static void bcm43xx_macfilter_clear(struct bcm43xx_private *bcm,
384                                     u16 offset)
385 {
386         const u8 zero_addr[ETH_ALEN] = { 0 };
387
388         bcm43xx_macfilter_set(bcm, offset, zero_addr);
389 }
390
391 static void bcm43xx_write_mac_bssid_templates(struct bcm43xx_private *bcm)
392 {
393         const u8 *mac = (const u8 *)(bcm->net_dev->dev_addr);
394         const u8 *bssid = (const u8 *)(bcm->ieee->bssid);
395         u8 mac_bssid[ETH_ALEN * 2];
396         int i;
397
398         memcpy(mac_bssid, mac, ETH_ALEN);
399         memcpy(mac_bssid + ETH_ALEN, bssid, ETH_ALEN);
400
401         /* Write our MAC address and BSSID to template ram */
402         for (i = 0; i < ARRAY_SIZE(mac_bssid); i += sizeof(u32))
403                 bcm43xx_ram_write(bcm, 0x20 + i, *((u32 *)(mac_bssid + i)));
404         for (i = 0; i < ARRAY_SIZE(mac_bssid); i += sizeof(u32))
405                 bcm43xx_ram_write(bcm, 0x78 + i, *((u32 *)(mac_bssid + i)));
406         for (i = 0; i < ARRAY_SIZE(mac_bssid); i += sizeof(u32))
407                 bcm43xx_ram_write(bcm, 0x478 + i, *((u32 *)(mac_bssid + i)));
408 }
409
410 //FIXME: Well, we should probably call them from somewhere.
411 #if 0
412 static void bcm43xx_set_slot_time(struct bcm43xx_private *bcm, u16 slot_time)
413 {
414         /* slot_time is in usec. */
415         if (bcm43xx_current_phy(bcm)->type != BCM43xx_PHYTYPE_G)
416                 return;
417         bcm43xx_write16(bcm, 0x684, 510 + slot_time);
418         bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0010, slot_time);
419 }
420
421 static void bcm43xx_short_slot_timing_enable(struct bcm43xx_private *bcm)
422 {
423         bcm43xx_set_slot_time(bcm, 9);
424 }
425
426 static void bcm43xx_short_slot_timing_disable(struct bcm43xx_private *bcm)
427 {
428         bcm43xx_set_slot_time(bcm, 20);
429 }
430 #endif
431
432 /* FIXME: To get the MAC-filter working, we need to implement the
433  *        following functions (and rename them :)
434  */
435 #if 0
436 static void bcm43xx_disassociate(struct bcm43xx_private *bcm)
437 {
438         bcm43xx_mac_suspend(bcm);
439         bcm43xx_macfilter_clear(bcm, BCM43xx_MACFILTER_ASSOC);
440
441         bcm43xx_ram_write(bcm, 0x0026, 0x0000);
442         bcm43xx_ram_write(bcm, 0x0028, 0x0000);
443         bcm43xx_ram_write(bcm, 0x007E, 0x0000);
444         bcm43xx_ram_write(bcm, 0x0080, 0x0000);
445         bcm43xx_ram_write(bcm, 0x047E, 0x0000);
446         bcm43xx_ram_write(bcm, 0x0480, 0x0000);
447
448         if (bcm->current_core->rev < 3) {
449                 bcm43xx_write16(bcm, 0x0610, 0x8000);
450                 bcm43xx_write16(bcm, 0x060E, 0x0000);
451         } else
452                 bcm43xx_write32(bcm, 0x0188, 0x80000000);
453
454         bcm43xx_shm_write32(bcm, BCM43xx_SHM_WIRELESS, 0x0004, 0x000003ff);
455
456         if (bcm43xx_current_phy(bcm)->type == BCM43xx_PHYTYPE_G &&
457             ieee80211_is_ofdm_rate(bcm->softmac->txrates.default_rate))
458                 bcm43xx_short_slot_timing_enable(bcm);
459
460         bcm43xx_mac_enable(bcm);
461 }
462
463 static void bcm43xx_associate(struct bcm43xx_private *bcm,
464                               const u8 *mac)
465 {
466         memcpy(bcm->ieee->bssid, mac, ETH_ALEN);
467
468         bcm43xx_mac_suspend(bcm);
469         bcm43xx_macfilter_set(bcm, BCM43xx_MACFILTER_ASSOC, mac);
470         bcm43xx_write_mac_bssid_templates(bcm);
471         bcm43xx_mac_enable(bcm);
472 }
473 #endif
474
475 /* Enable a Generic IRQ. "mask" is the mask of which IRQs to enable.
476  * Returns the _previously_ enabled IRQ mask.
477  */
478 static inline u32 bcm43xx_interrupt_enable(struct bcm43xx_private *bcm, u32 mask)
479 {
480         u32 old_mask;
481
482         old_mask = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_MASK);
483         bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_MASK, old_mask | mask);
484
485         return old_mask;
486 }
487
488 /* Disable a Generic IRQ. "mask" is the mask of which IRQs to disable.
489  * Returns the _previously_ enabled IRQ mask.
490  */
491 static inline u32 bcm43xx_interrupt_disable(struct bcm43xx_private *bcm, u32 mask)
492 {
493         u32 old_mask;
494
495         old_mask = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_MASK);
496         bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_MASK, old_mask & ~mask);
497
498         return old_mask;
499 }
500
501 /* Synchronize IRQ top- and bottom-half.
502  * IRQs must be masked before calling this.
503  * This must not be called with the irq_lock held.
504  */
505 static void bcm43xx_synchronize_irq(struct bcm43xx_private *bcm)
506 {
507         synchronize_irq(bcm->irq);
508         tasklet_disable(&bcm->isr_tasklet);
509 }
510
511 /* Make sure we don't receive more data from the device. */
512 static int bcm43xx_disable_interrupts_sync(struct bcm43xx_private *bcm)
513 {
514         unsigned long flags;
515
516         spin_lock_irqsave(&bcm->irq_lock, flags);
517         if (unlikely(bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED)) {
518                 spin_unlock_irqrestore(&bcm->irq_lock, flags);
519                 return -EBUSY;
520         }
521         bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
522         bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_MASK); /* flush */
523         spin_unlock_irqrestore(&bcm->irq_lock, flags);
524         bcm43xx_synchronize_irq(bcm);
525
526         return 0;
527 }
528
529 static int bcm43xx_read_radioinfo(struct bcm43xx_private *bcm)
530 {
531         struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
532         struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
533         u32 radio_id;
534         u16 manufact;
535         u16 version;
536         u8 revision;
537
538         if (bcm->chip_id == 0x4317) {
539                 if (bcm->chip_rev == 0x00)
540                         radio_id = 0x3205017F;
541                 else if (bcm->chip_rev == 0x01)
542                         radio_id = 0x4205017F;
543                 else
544                         radio_id = 0x5205017F;
545         } else {
546                 bcm43xx_write16(bcm, BCM43xx_MMIO_RADIO_CONTROL, BCM43xx_RADIOCTL_ID);
547                 radio_id = bcm43xx_read16(bcm, BCM43xx_MMIO_RADIO_DATA_HIGH);
548                 radio_id <<= 16;
549                 bcm43xx_write16(bcm, BCM43xx_MMIO_RADIO_CONTROL, BCM43xx_RADIOCTL_ID);
550                 radio_id |= bcm43xx_read16(bcm, BCM43xx_MMIO_RADIO_DATA_LOW);
551         }
552
553         manufact = (radio_id & 0x00000FFF);
554         version = (radio_id & 0x0FFFF000) >> 12;
555         revision = (radio_id & 0xF0000000) >> 28;
556
557         dprintk(KERN_INFO PFX "Detected Radio: ID: %x (Manuf: %x Ver: %x Rev: %x)\n",
558                 radio_id, manufact, version, revision);
559
560         switch (phy->type) {
561         case BCM43xx_PHYTYPE_A:
562                 if ((version != 0x2060) || (revision != 1) || (manufact != 0x17f))
563                         goto err_unsupported_radio;
564                 break;
565         case BCM43xx_PHYTYPE_B:
566                 if ((version & 0xFFF0) != 0x2050)
567                         goto err_unsupported_radio;
568                 break;
569         case BCM43xx_PHYTYPE_G:
570                 if (version != 0x2050)
571                         goto err_unsupported_radio;
572                 break;
573         }
574
575         radio->manufact = manufact;
576         radio->version = version;
577         radio->revision = revision;
578
579         if (phy->type == BCM43xx_PHYTYPE_A)
580                 radio->txpower_desired = bcm->sprom.maxpower_aphy;
581         else
582                 radio->txpower_desired = bcm->sprom.maxpower_bgphy;
583
584         return 0;
585
586 err_unsupported_radio:
587         printk(KERN_ERR PFX "Unsupported Radio connected to the PHY!\n");
588         return -ENODEV;
589 }
590
591 static const char * bcm43xx_locale_iso(u8 locale)
592 {
593         /* ISO 3166-1 country codes.
594          * Note that there aren't ISO 3166-1 codes for
595          * all or locales. (Not all locales are countries)
596          */
597         switch (locale) {
598         case BCM43xx_LOCALE_WORLD:
599         case BCM43xx_LOCALE_ALL:
600                 return "XX";
601         case BCM43xx_LOCALE_THAILAND:
602                 return "TH";
603         case BCM43xx_LOCALE_ISRAEL:
604                 return "IL";
605         case BCM43xx_LOCALE_JORDAN:
606                 return "JO";
607         case BCM43xx_LOCALE_CHINA:
608                 return "CN";
609         case BCM43xx_LOCALE_JAPAN:
610         case BCM43xx_LOCALE_JAPAN_HIGH:
611                 return "JP";
612         case BCM43xx_LOCALE_USA_CANADA_ANZ:
613         case BCM43xx_LOCALE_USA_LOW:
614                 return "US";
615         case BCM43xx_LOCALE_EUROPE:
616                 return "EU";
617         case BCM43xx_LOCALE_NONE:
618                 return "  ";
619         }
620         assert(0);
621         return "  ";
622 }
623
624 static const char * bcm43xx_locale_string(u8 locale)
625 {
626         switch (locale) {
627         case BCM43xx_LOCALE_WORLD:
628                 return "World";
629         case BCM43xx_LOCALE_THAILAND:
630                 return "Thailand";
631         case BCM43xx_LOCALE_ISRAEL:
632                 return "Israel";
633         case BCM43xx_LOCALE_JORDAN:
634                 return "Jordan";
635         case BCM43xx_LOCALE_CHINA:
636                 return "China";
637         case BCM43xx_LOCALE_JAPAN:
638                 return "Japan";
639         case BCM43xx_LOCALE_USA_CANADA_ANZ:
640                 return "USA/Canada/ANZ";
641         case BCM43xx_LOCALE_EUROPE:
642                 return "Europe";
643         case BCM43xx_LOCALE_USA_LOW:
644                 return "USAlow";
645         case BCM43xx_LOCALE_JAPAN_HIGH:
646                 return "JapanHigh";
647         case BCM43xx_LOCALE_ALL:
648                 return "All";
649         case BCM43xx_LOCALE_NONE:
650                 return "None";
651         }
652         assert(0);
653         return "";
654 }
655
656 static inline u8 bcm43xx_crc8(u8 crc, u8 data)
657 {
658         static const u8 t[] = {
659                 0x00, 0xF7, 0xB9, 0x4E, 0x25, 0xD2, 0x9C, 0x6B,
660                 0x4A, 0xBD, 0xF3, 0x04, 0x6F, 0x98, 0xD6, 0x21,
661                 0x94, 0x63, 0x2D, 0xDA, 0xB1, 0x46, 0x08, 0xFF,
662                 0xDE, 0x29, 0x67, 0x90, 0xFB, 0x0C, 0x42, 0xB5,
663                 0x7F, 0x88, 0xC6, 0x31, 0x5A, 0xAD, 0xE3, 0x14,
664                 0x35, 0xC2, 0x8C, 0x7B, 0x10, 0xE7, 0xA9, 0x5E,
665                 0xEB, 0x1C, 0x52, 0xA5, 0xCE, 0x39, 0x77, 0x80,
666                 0xA1, 0x56, 0x18, 0xEF, 0x84, 0x73, 0x3D, 0xCA,
667                 0xFE, 0x09, 0x47, 0xB0, 0xDB, 0x2C, 0x62, 0x95,
668                 0xB4, 0x43, 0x0D, 0xFA, 0x91, 0x66, 0x28, 0xDF,
669                 0x6A, 0x9D, 0xD3, 0x24, 0x4F, 0xB8, 0xF6, 0x01,
670                 0x20, 0xD7, 0x99, 0x6E, 0x05, 0xF2, 0xBC, 0x4B,
671                 0x81, 0x76, 0x38, 0xCF, 0xA4, 0x53, 0x1D, 0xEA,
672                 0xCB, 0x3C, 0x72, 0x85, 0xEE, 0x19, 0x57, 0xA0,
673                 0x15, 0xE2, 0xAC, 0x5B, 0x30, 0xC7, 0x89, 0x7E,
674                 0x5F, 0xA8, 0xE6, 0x11, 0x7A, 0x8D, 0xC3, 0x34,
675                 0xAB, 0x5C, 0x12, 0xE5, 0x8E, 0x79, 0x37, 0xC0,
676                 0xE1, 0x16, 0x58, 0xAF, 0xC4, 0x33, 0x7D, 0x8A,
677                 0x3F, 0xC8, 0x86, 0x71, 0x1A, 0xED, 0xA3, 0x54,
678                 0x75, 0x82, 0xCC, 0x3B, 0x50, 0xA7, 0xE9, 0x1E,
679                 0xD4, 0x23, 0x6D, 0x9A, 0xF1, 0x06, 0x48, 0xBF,
680                 0x9E, 0x69, 0x27, 0xD0, 0xBB, 0x4C, 0x02, 0xF5,
681                 0x40, 0xB7, 0xF9, 0x0E, 0x65, 0x92, 0xDC, 0x2B,
682                 0x0A, 0xFD, 0xB3, 0x44, 0x2F, 0xD8, 0x96, 0x61,
683                 0x55, 0xA2, 0xEC, 0x1B, 0x70, 0x87, 0xC9, 0x3E,
684                 0x1F, 0xE8, 0xA6, 0x51, 0x3A, 0xCD, 0x83, 0x74,
685                 0xC1, 0x36, 0x78, 0x8F, 0xE4, 0x13, 0x5D, 0xAA,
686                 0x8B, 0x7C, 0x32, 0xC5, 0xAE, 0x59, 0x17, 0xE0,
687                 0x2A, 0xDD, 0x93, 0x64, 0x0F, 0xF8, 0xB6, 0x41,
688                 0x60, 0x97, 0xD9, 0x2E, 0x45, 0xB2, 0xFC, 0x0B,
689                 0xBE, 0x49, 0x07, 0xF0, 0x9B, 0x6C, 0x22, 0xD5,
690                 0xF4, 0x03, 0x4D, 0xBA, 0xD1, 0x26, 0x68, 0x9F,
691         };
692         return t[crc ^ data];
693 }
694
695 static u8 bcm43xx_sprom_crc(const u16 *sprom)
696 {
697         int word;
698         u8 crc = 0xFF;
699
700         for (word = 0; word < BCM43xx_SPROM_SIZE - 1; word++) {
701                 crc = bcm43xx_crc8(crc, sprom[word] & 0x00FF);
702                 crc = bcm43xx_crc8(crc, (sprom[word] & 0xFF00) >> 8);
703         }
704         crc = bcm43xx_crc8(crc, sprom[BCM43xx_SPROM_VERSION] & 0x00FF);
705         crc ^= 0xFF;
706
707         return crc;
708 }
709
710 int bcm43xx_sprom_read(struct bcm43xx_private *bcm, u16 *sprom)
711 {
712         int i;
713         u8 crc, expected_crc;
714
715         for (i = 0; i < BCM43xx_SPROM_SIZE; i++)
716                 sprom[i] = bcm43xx_read16(bcm, BCM43xx_SPROM_BASE + (i * 2));
717         /* CRC-8 check. */
718         crc = bcm43xx_sprom_crc(sprom);
719         expected_crc = (sprom[BCM43xx_SPROM_VERSION] & 0xFF00) >> 8;
720         if (crc != expected_crc) {
721                 printk(KERN_WARNING PFX "WARNING: Invalid SPROM checksum "
722                                         "(0x%02X, expected: 0x%02X)\n",
723                        crc, expected_crc);
724                 return -EINVAL;
725         }
726
727         return 0;
728 }
729
730 int bcm43xx_sprom_write(struct bcm43xx_private *bcm, const u16 *sprom)
731 {
732         int i, err;
733         u8 crc, expected_crc;
734         u32 spromctl;
735
736         /* CRC-8 validation of the input data. */
737         crc = bcm43xx_sprom_crc(sprom);
738         expected_crc = (sprom[BCM43xx_SPROM_VERSION] & 0xFF00) >> 8;
739         if (crc != expected_crc) {
740                 printk(KERN_ERR PFX "SPROM input data: Invalid CRC\n");
741                 return -EINVAL;
742         }
743
744         printk(KERN_INFO PFX "Writing SPROM. Do NOT turn off the power! Please stand by...\n");
745         err = bcm43xx_pci_read_config32(bcm, BCM43xx_PCICFG_SPROMCTL, &spromctl);
746         if (err)
747                 goto err_ctlreg;
748         spromctl |= 0x10; /* SPROM WRITE enable. */
749         err = bcm43xx_pci_write_config32(bcm, BCM43xx_PCICFG_SPROMCTL, spromctl);
750         if (err)
751                 goto err_ctlreg;
752         /* We must burn lots of CPU cycles here, but that does not
753          * really matter as one does not write the SPROM every other minute...
754          */
755         printk(KERN_INFO PFX "[ 0%%");
756         mdelay(500);
757         for (i = 0; i < BCM43xx_SPROM_SIZE; i++) {
758                 if (i == 16)
759                         printk("25%%");
760                 else if (i == 32)
761                         printk("50%%");
762                 else if (i == 48)
763                         printk("75%%");
764                 else if (i % 2)
765                         printk(".");
766                 bcm43xx_write16(bcm, BCM43xx_SPROM_BASE + (i * 2), sprom[i]);
767                 mmiowb();
768                 mdelay(20);
769         }
770         spromctl &= ~0x10; /* SPROM WRITE enable. */
771         err = bcm43xx_pci_write_config32(bcm, BCM43xx_PCICFG_SPROMCTL, spromctl);
772         if (err)
773                 goto err_ctlreg;
774         mdelay(500);
775         printk("100%% ]\n");
776         printk(KERN_INFO PFX "SPROM written.\n");
777         bcm43xx_controller_restart(bcm, "SPROM update");
778
779         return 0;
780 err_ctlreg:
781         printk(KERN_ERR PFX "Could not access SPROM control register.\n");
782         return -ENODEV;
783 }
784
785 static int bcm43xx_sprom_extract(struct bcm43xx_private *bcm)
786 {
787         u16 value;
788         u16 *sprom;
789 #ifdef CONFIG_BCM947XX
790         char *c;
791 #endif
792
793         sprom = kzalloc(BCM43xx_SPROM_SIZE * sizeof(u16),
794                         GFP_KERNEL);
795         if (!sprom) {
796                 printk(KERN_ERR PFX "sprom_extract OOM\n");
797                 return -ENOMEM;
798         }
799 #ifdef CONFIG_BCM947XX
800         sprom[BCM43xx_SPROM_BOARDFLAGS2] = atoi(nvram_get("boardflags2"));
801         sprom[BCM43xx_SPROM_BOARDFLAGS] = atoi(nvram_get("boardflags"));
802
803         if ((c = nvram_get("il0macaddr")) != NULL)
804                 e_aton(c, (char *) &(sprom[BCM43xx_SPROM_IL0MACADDR]));
805
806         if ((c = nvram_get("et1macaddr")) != NULL)
807                 e_aton(c, (char *) &(sprom[BCM43xx_SPROM_ET1MACADDR]));
808
809         sprom[BCM43xx_SPROM_PA0B0] = atoi(nvram_get("pa0b0"));
810         sprom[BCM43xx_SPROM_PA0B1] = atoi(nvram_get("pa0b1"));
811         sprom[BCM43xx_SPROM_PA0B2] = atoi(nvram_get("pa0b2"));
812
813         sprom[BCM43xx_SPROM_PA1B0] = atoi(nvram_get("pa1b0"));
814         sprom[BCM43xx_SPROM_PA1B1] = atoi(nvram_get("pa1b1"));
815         sprom[BCM43xx_SPROM_PA1B2] = atoi(nvram_get("pa1b2"));
816
817         sprom[BCM43xx_SPROM_BOARDREV] = atoi(nvram_get("boardrev"));
818 #else
819         bcm43xx_sprom_read(bcm, sprom);
820 #endif
821
822         /* boardflags2 */
823         value = sprom[BCM43xx_SPROM_BOARDFLAGS2];
824         bcm->sprom.boardflags2 = value;
825
826         /* il0macaddr */
827         value = sprom[BCM43xx_SPROM_IL0MACADDR + 0];
828         *(((u16 *)bcm->sprom.il0macaddr) + 0) = cpu_to_be16(value);
829         value = sprom[BCM43xx_SPROM_IL0MACADDR + 1];
830         *(((u16 *)bcm->sprom.il0macaddr) + 1) = cpu_to_be16(value);
831         value = sprom[BCM43xx_SPROM_IL0MACADDR + 2];
832         *(((u16 *)bcm->sprom.il0macaddr) + 2) = cpu_to_be16(value);
833
834         /* et0macaddr */
835         value = sprom[BCM43xx_SPROM_ET0MACADDR + 0];
836         *(((u16 *)bcm->sprom.et0macaddr) + 0) = cpu_to_be16(value);
837         value = sprom[BCM43xx_SPROM_ET0MACADDR + 1];
838         *(((u16 *)bcm->sprom.et0macaddr) + 1) = cpu_to_be16(value);
839         value = sprom[BCM43xx_SPROM_ET0MACADDR + 2];
840         *(((u16 *)bcm->sprom.et0macaddr) + 2) = cpu_to_be16(value);
841
842         /* et1macaddr */
843         value = sprom[BCM43xx_SPROM_ET1MACADDR + 0];
844         *(((u16 *)bcm->sprom.et1macaddr) + 0) = cpu_to_be16(value);
845         value = sprom[BCM43xx_SPROM_ET1MACADDR + 1];
846         *(((u16 *)bcm->sprom.et1macaddr) + 1) = cpu_to_be16(value);
847         value = sprom[BCM43xx_SPROM_ET1MACADDR + 2];
848         *(((u16 *)bcm->sprom.et1macaddr) + 2) = cpu_to_be16(value);
849
850         /* ethernet phy settings */
851         value = sprom[BCM43xx_SPROM_ETHPHY];
852         bcm->sprom.et0phyaddr = (value & 0x001F);
853         bcm->sprom.et1phyaddr = (value & 0x03E0) >> 5;
854         bcm->sprom.et0mdcport = (value & (1 << 14)) >> 14;
855         bcm->sprom.et1mdcport = (value & (1 << 15)) >> 15;
856
857         /* boardrev, antennas, locale */
858         value = sprom[BCM43xx_SPROM_BOARDREV];
859         bcm->sprom.boardrev = (value & 0x00FF);
860         bcm->sprom.locale = (value & 0x0F00) >> 8;
861         bcm->sprom.antennas_aphy = (value & 0x3000) >> 12;
862         bcm->sprom.antennas_bgphy = (value & 0xC000) >> 14;
863         if (modparam_locale != -1) {
864                 if (modparam_locale >= 0 && modparam_locale <= 11) {
865                         bcm->sprom.locale = modparam_locale;
866                         printk(KERN_WARNING PFX "Operating with modified "
867                                                 "LocaleCode %u (%s)\n",
868                                bcm->sprom.locale,
869                                bcm43xx_locale_string(bcm->sprom.locale));
870                 } else {
871                         printk(KERN_WARNING PFX "Module parameter \"locale\" "
872                                                 "invalid value. (0 - 11)\n");
873                 }
874         }
875
876         /* pa0b* */
877         value = sprom[BCM43xx_SPROM_PA0B0];
878         bcm->sprom.pa0b0 = value;
879         value = sprom[BCM43xx_SPROM_PA0B1];
880         bcm->sprom.pa0b1 = value;
881         value = sprom[BCM43xx_SPROM_PA0B2];
882         bcm->sprom.pa0b2 = value;
883
884         /* wl0gpio* */
885         value = sprom[BCM43xx_SPROM_WL0GPIO0];
886         if (value == 0x0000)
887                 value = 0xFFFF;
888         bcm->sprom.wl0gpio0 = value & 0x00FF;
889         bcm->sprom.wl0gpio1 = (value & 0xFF00) >> 8;
890         value = sprom[BCM43xx_SPROM_WL0GPIO2];
891         if (value == 0x0000)
892                 value = 0xFFFF;
893         bcm->sprom.wl0gpio2 = value & 0x00FF;
894         bcm->sprom.wl0gpio3 = (value & 0xFF00) >> 8;
895
896         /* maxpower */
897         value = sprom[BCM43xx_SPROM_MAXPWR];
898         bcm->sprom.maxpower_aphy = (value & 0xFF00) >> 8;
899         bcm->sprom.maxpower_bgphy = value & 0x00FF;
900
901         /* pa1b* */
902         value = sprom[BCM43xx_SPROM_PA1B0];
903         bcm->sprom.pa1b0 = value;
904         value = sprom[BCM43xx_SPROM_PA1B1];
905         bcm->sprom.pa1b1 = value;
906         value = sprom[BCM43xx_SPROM_PA1B2];
907         bcm->sprom.pa1b2 = value;
908
909         /* idle tssi target */
910         value = sprom[BCM43xx_SPROM_IDL_TSSI_TGT];
911         bcm->sprom.idle_tssi_tgt_aphy = value & 0x00FF;
912         bcm->sprom.idle_tssi_tgt_bgphy = (value & 0xFF00) >> 8;
913
914         /* boardflags */
915         value = sprom[BCM43xx_SPROM_BOARDFLAGS];
916         if (value == 0xFFFF)
917                 value = 0x0000;
918         bcm->sprom.boardflags = value;
919         /* boardflags workarounds */
920         if (bcm->board_vendor == PCI_VENDOR_ID_DELL &&
921             bcm->chip_id == 0x4301 &&
922             bcm->board_revision == 0x74)
923                 bcm->sprom.boardflags |= BCM43xx_BFL_BTCOEXIST;
924         if (bcm->board_vendor == PCI_VENDOR_ID_APPLE &&
925             bcm->board_type == 0x4E &&
926             bcm->board_revision > 0x40)
927                 bcm->sprom.boardflags |= BCM43xx_BFL_PACTRL;
928
929         /* antenna gain */
930         value = sprom[BCM43xx_SPROM_ANTENNA_GAIN];
931         if (value == 0x0000 || value == 0xFFFF)
932                 value = 0x0202;
933         /* convert values to Q5.2 */
934         bcm->sprom.antennagain_aphy = ((value & 0xFF00) >> 8) * 4;
935         bcm->sprom.antennagain_bgphy = (value & 0x00FF) * 4;
936
937         kfree(sprom);
938
939         return 0;
940 }
941
942 static int bcm43xx_geo_init(struct bcm43xx_private *bcm)
943 {
944         struct ieee80211_geo *geo;
945         struct ieee80211_channel *chan;
946         int have_a = 0, have_bg = 0;
947         int i;
948         u8 channel;
949         struct bcm43xx_phyinfo *phy;
950         const char *iso_country;
951
952         geo = kzalloc(sizeof(*geo), GFP_KERNEL);
953         if (!geo)
954                 return -ENOMEM;
955
956         for (i = 0; i < bcm->nr_80211_available; i++) {
957                 phy = &(bcm->core_80211_ext[i].phy);
958                 switch (phy->type) {
959                 case BCM43xx_PHYTYPE_B:
960                 case BCM43xx_PHYTYPE_G:
961                         have_bg = 1;
962                         break;
963                 case BCM43xx_PHYTYPE_A:
964                         have_a = 1;
965                         break;
966                 default:
967                         assert(0);
968                 }
969         }
970         iso_country = bcm43xx_locale_iso(bcm->sprom.locale);
971
972         if (have_a) {
973                 for (i = 0, channel = IEEE80211_52GHZ_MIN_CHANNEL;
974                       channel <= IEEE80211_52GHZ_MAX_CHANNEL; channel++) {
975                         chan = &geo->a[i++];
976                         chan->freq = bcm43xx_channel_to_freq_a(channel);
977                         chan->channel = channel;
978                 }
979                 geo->a_channels = i;
980         }
981         if (have_bg) {
982                 for (i = 0, channel = IEEE80211_24GHZ_MIN_CHANNEL;
983                       channel <= IEEE80211_24GHZ_MAX_CHANNEL; channel++) {
984                         chan = &geo->bg[i++];
985                         chan->freq = bcm43xx_channel_to_freq_bg(channel);
986                         chan->channel = channel;
987                 }
988                 geo->bg_channels = i;
989         }
990         memcpy(geo->name, iso_country, 2);
991         if (0 /*TODO: Outdoor use only */)
992                 geo->name[2] = 'O';
993         else if (0 /*TODO: Indoor use only */)
994                 geo->name[2] = 'I';
995         else
996                 geo->name[2] = ' ';
997         geo->name[3] = '\0';
998
999         ieee80211_set_geo(bcm->ieee, geo);
1000         kfree(geo);
1001
1002         return 0;
1003 }
1004
1005 /* DummyTransmission function, as documented on 
1006  * http://bcm-specs.sipsolutions.net/DummyTransmission
1007  */
1008 void bcm43xx_dummy_transmission(struct bcm43xx_private *bcm)
1009 {
1010         struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
1011         struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
1012         unsigned int i, max_loop;
1013         u16 value = 0;
1014         u32 buffer[5] = {
1015                 0x00000000,
1016                 0x0000D400,
1017                 0x00000000,
1018                 0x00000001,
1019                 0x00000000,
1020         };
1021
1022         switch (phy->type) {
1023         case BCM43xx_PHYTYPE_A:
1024                 max_loop = 0x1E;
1025                 buffer[0] = 0xCC010200;
1026                 break;
1027         case BCM43xx_PHYTYPE_B:
1028         case BCM43xx_PHYTYPE_G:
1029                 max_loop = 0xFA;
1030                 buffer[0] = 0x6E840B00; 
1031                 break;
1032         default:
1033                 assert(0);
1034                 return;
1035         }
1036
1037         for (i = 0; i < 5; i++)
1038                 bcm43xx_ram_write(bcm, i * 4, buffer[i]);
1039
1040         bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); /* dummy read */
1041
1042         bcm43xx_write16(bcm, 0x0568, 0x0000);
1043         bcm43xx_write16(bcm, 0x07C0, 0x0000);
1044         bcm43xx_write16(bcm, 0x050C, ((phy->type == BCM43xx_PHYTYPE_A) ? 1 : 0));
1045         bcm43xx_write16(bcm, 0x0508, 0x0000);
1046         bcm43xx_write16(bcm, 0x050A, 0x0000);
1047         bcm43xx_write16(bcm, 0x054C, 0x0000);
1048         bcm43xx_write16(bcm, 0x056A, 0x0014);
1049         bcm43xx_write16(bcm, 0x0568, 0x0826);
1050         bcm43xx_write16(bcm, 0x0500, 0x0000);
1051         bcm43xx_write16(bcm, 0x0502, 0x0030);
1052
1053         if (radio->version == 0x2050 && radio->revision <= 0x5)
1054                 bcm43xx_radio_write16(bcm, 0x0051, 0x0017);
1055         for (i = 0x00; i < max_loop; i++) {
1056                 value = bcm43xx_read16(bcm, 0x050E);
1057                 if (value & 0x0080)
1058                         break;
1059                 udelay(10);
1060         }
1061         for (i = 0x00; i < 0x0A; i++) {
1062                 value = bcm43xx_read16(bcm, 0x050E);
1063                 if (value & 0x0400)
1064                         break;
1065                 udelay(10);
1066         }
1067         for (i = 0x00; i < 0x0A; i++) {
1068                 value = bcm43xx_read16(bcm, 0x0690);
1069                 if (!(value & 0x0100))
1070                         break;
1071                 udelay(10);
1072         }
1073         if (radio->version == 0x2050 && radio->revision <= 0x5)
1074                 bcm43xx_radio_write16(bcm, 0x0051, 0x0037);
1075 }
1076
1077 static void key_write(struct bcm43xx_private *bcm,
1078                       u8 index, u8 algorithm, const u16 *key)
1079 {
1080         unsigned int i, basic_wep = 0;
1081         u32 offset;
1082         u16 value;
1083  
1084         /* Write associated key information */
1085         bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x100 + (index * 2),
1086                             ((index << 4) | (algorithm & 0x0F)));
1087  
1088         /* The first 4 WEP keys need extra love */
1089         if (((algorithm == BCM43xx_SEC_ALGO_WEP) ||
1090             (algorithm == BCM43xx_SEC_ALGO_WEP104)) && (index < 4))
1091                 basic_wep = 1;
1092  
1093         /* Write key payload, 8 little endian words */
1094         offset = bcm->security_offset + (index * BCM43xx_SEC_KEYSIZE);
1095         for (i = 0; i < (BCM43xx_SEC_KEYSIZE / sizeof(u16)); i++) {
1096                 value = cpu_to_le16(key[i]);
1097                 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED,
1098                                     offset + (i * 2), value);
1099  
1100                 if (!basic_wep)
1101                         continue;
1102  
1103                 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED,
1104                                     offset + (i * 2) + 4 * BCM43xx_SEC_KEYSIZE,
1105                                     value);
1106         }
1107 }
1108
1109 static void keymac_write(struct bcm43xx_private *bcm,
1110                          u8 index, const u32 *addr)
1111 {
1112         /* for keys 0-3 there is no associated mac address */
1113         if (index < 4)
1114                 return;
1115
1116         index -= 4;
1117         if (bcm->current_core->rev >= 5) {
1118                 bcm43xx_shm_write32(bcm,
1119                                     BCM43xx_SHM_HWMAC,
1120                                     index * 2,
1121                                     cpu_to_be32(*addr));
1122                 bcm43xx_shm_write16(bcm,
1123                                     BCM43xx_SHM_HWMAC,
1124                                     (index * 2) + 1,
1125                                     cpu_to_be16(*((u16 *)(addr + 1))));
1126         } else {
1127                 if (index < 8) {
1128                         TODO(); /* Put them in the macaddress filter */
1129                 } else {
1130                         TODO();
1131                         /* Put them BCM43xx_SHM_SHARED, stating index 0x0120.
1132                            Keep in mind to update the count of keymacs in 0x003E as well! */
1133                 }
1134         }
1135 }
1136
1137 static int bcm43xx_key_write(struct bcm43xx_private *bcm,
1138                              u8 index, u8 algorithm,
1139                              const u8 *_key, int key_len,
1140                              const u8 *mac_addr)
1141 {
1142         u8 key[BCM43xx_SEC_KEYSIZE] = { 0 };
1143
1144         if (index >= ARRAY_SIZE(bcm->key))
1145                 return -EINVAL;
1146         if (key_len > ARRAY_SIZE(key))
1147                 return -EINVAL;
1148         if (algorithm < 1 || algorithm > 5)
1149                 return -EINVAL;
1150
1151         memcpy(key, _key, key_len);
1152         key_write(bcm, index, algorithm, (const u16 *)key);
1153         keymac_write(bcm, index, (const u32 *)mac_addr);
1154
1155         bcm->key[index].algorithm = algorithm;
1156
1157         return 0;
1158 }
1159
1160 static void bcm43xx_clear_keys(struct bcm43xx_private *bcm)
1161 {
1162         static const u32 zero_mac[2] = { 0 };
1163         unsigned int i,j, nr_keys = 54;
1164         u16 offset;
1165
1166         if (bcm->current_core->rev < 5)
1167                 nr_keys = 16;
1168         assert(nr_keys <= ARRAY_SIZE(bcm->key));
1169
1170         for (i = 0; i < nr_keys; i++) {
1171                 bcm->key[i].enabled = 0;
1172                 /* returns for i < 4 immediately */
1173                 keymac_write(bcm, i, zero_mac);
1174                 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED,
1175                                     0x100 + (i * 2), 0x0000);
1176                 for (j = 0; j < 8; j++) {
1177                         offset = bcm->security_offset + (j * 4) + (i * BCM43xx_SEC_KEYSIZE);
1178                         bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED,
1179                                             offset, 0x0000);
1180                 }
1181         }
1182         dprintk(KERN_INFO PFX "Keys cleared\n");
1183 }
1184
1185 /* Lowlevel core-switch function. This is only to be used in
1186  * bcm43xx_switch_core() and bcm43xx_probe_cores()
1187  */
1188 static int _switch_core(struct bcm43xx_private *bcm, int core)
1189 {
1190         int err;
1191         int attempts = 0;
1192         u32 current_core;
1193
1194         assert(core >= 0);
1195         while (1) {
1196                 err = bcm43xx_pci_write_config32(bcm, BCM43xx_PCICFG_ACTIVE_CORE,
1197                                                  (core * 0x1000) + 0x18000000);
1198                 if (unlikely(err))
1199                         goto error;
1200                 err = bcm43xx_pci_read_config32(bcm, BCM43xx_PCICFG_ACTIVE_CORE,
1201                                                 &current_core);
1202                 if (unlikely(err))
1203                         goto error;
1204                 current_core = (current_core - 0x18000000) / 0x1000;
1205                 if (current_core == core)
1206                         break;
1207
1208                 if (unlikely(attempts++ > BCM43xx_SWITCH_CORE_MAX_RETRIES))
1209                         goto error;
1210                 udelay(10);
1211         }
1212 #ifdef CONFIG_BCM947XX
1213         if (bcm->pci_dev->bus->number == 0)
1214                 bcm->current_core_offset = 0x1000 * core;
1215         else
1216                 bcm->current_core_offset = 0;
1217 #endif
1218
1219         return 0;
1220 error:
1221         printk(KERN_ERR PFX "Failed to switch to core %d\n", core);
1222         return -ENODEV;
1223 }
1224
1225 int bcm43xx_switch_core(struct bcm43xx_private *bcm, struct bcm43xx_coreinfo *new_core)
1226 {
1227         int err;
1228
1229         if (unlikely(!new_core))
1230                 return 0;
1231         if (!new_core->available)
1232                 return -ENODEV;
1233         if (bcm->current_core == new_core)
1234                 return 0;
1235         err = _switch_core(bcm, new_core->index);
1236         if (unlikely(err))
1237                 goto out;
1238
1239         bcm->current_core = new_core;
1240 out:
1241         return err;
1242 }
1243
1244 static int bcm43xx_core_enabled(struct bcm43xx_private *bcm)
1245 {
1246         u32 value;
1247
1248         value = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
1249         value &= BCM43xx_SBTMSTATELOW_CLOCK | BCM43xx_SBTMSTATELOW_RESET
1250                  | BCM43xx_SBTMSTATELOW_REJECT;
1251
1252         return (value == BCM43xx_SBTMSTATELOW_CLOCK);
1253 }
1254
1255 /* disable current core */
1256 static int bcm43xx_core_disable(struct bcm43xx_private *bcm, u32 core_flags)
1257 {
1258         u32 sbtmstatelow;
1259         u32 sbtmstatehigh;
1260         int i;
1261
1262         /* fetch sbtmstatelow from core information registers */
1263         sbtmstatelow = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
1264
1265         /* core is already in reset */
1266         if (sbtmstatelow & BCM43xx_SBTMSTATELOW_RESET)
1267                 goto out;
1268
1269         if (sbtmstatelow & BCM43xx_SBTMSTATELOW_CLOCK) {
1270                 sbtmstatelow = BCM43xx_SBTMSTATELOW_CLOCK |
1271                                BCM43xx_SBTMSTATELOW_REJECT;
1272                 bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
1273
1274                 for (i = 0; i < 1000; i++) {
1275                         sbtmstatelow = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
1276                         if (sbtmstatelow & BCM43xx_SBTMSTATELOW_REJECT) {
1277                                 i = -1;
1278                                 break;
1279                         }
1280                         udelay(10);
1281                 }
1282                 if (i != -1) {
1283                         printk(KERN_ERR PFX "Error: core_disable() REJECT timeout!\n");
1284                         return -EBUSY;
1285                 }
1286
1287                 for (i = 0; i < 1000; i++) {
1288                         sbtmstatehigh = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATEHIGH);
1289                         if (!(sbtmstatehigh & BCM43xx_SBTMSTATEHIGH_BUSY)) {
1290                                 i = -1;
1291                                 break;
1292                         }
1293                         udelay(10);
1294                 }
1295                 if (i != -1) {
1296                         printk(KERN_ERR PFX "Error: core_disable() BUSY timeout!\n");
1297                         return -EBUSY;
1298                 }
1299
1300                 sbtmstatelow = BCM43xx_SBTMSTATELOW_FORCE_GATE_CLOCK |
1301                                BCM43xx_SBTMSTATELOW_REJECT |
1302                                BCM43xx_SBTMSTATELOW_RESET |
1303                                BCM43xx_SBTMSTATELOW_CLOCK |
1304                                core_flags;
1305                 bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
1306                 udelay(10);
1307         }
1308
1309         sbtmstatelow = BCM43xx_SBTMSTATELOW_RESET |
1310                        BCM43xx_SBTMSTATELOW_REJECT |
1311                        core_flags;
1312         bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
1313
1314 out:
1315         bcm->current_core->enabled = 0;
1316
1317         return 0;
1318 }
1319
1320 /* enable (reset) current core */
1321 static int bcm43xx_core_enable(struct bcm43xx_private *bcm, u32 core_flags)
1322 {
1323         u32 sbtmstatelow;
1324         u32 sbtmstatehigh;
1325         u32 sbimstate;
1326         int err;
1327
1328         err = bcm43xx_core_disable(bcm, core_flags);
1329         if (err)
1330                 goto out;
1331
1332         sbtmstatelow = BCM43xx_SBTMSTATELOW_CLOCK |
1333                        BCM43xx_SBTMSTATELOW_RESET |
1334                        BCM43xx_SBTMSTATELOW_FORCE_GATE_CLOCK |
1335                        core_flags;
1336         bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
1337         udelay(1);
1338
1339         sbtmstatehigh = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATEHIGH);
1340         if (sbtmstatehigh & BCM43xx_SBTMSTATEHIGH_SERROR) {
1341                 sbtmstatehigh = 0x00000000;
1342                 bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATEHIGH, sbtmstatehigh);
1343         }
1344
1345         sbimstate = bcm43xx_read32(bcm, BCM43xx_CIR_SBIMSTATE);
1346         if (sbimstate & (BCM43xx_SBIMSTATE_IB_ERROR | BCM43xx_SBIMSTATE_TIMEOUT)) {
1347                 sbimstate &= ~(BCM43xx_SBIMSTATE_IB_ERROR | BCM43xx_SBIMSTATE_TIMEOUT);
1348                 bcm43xx_write32(bcm, BCM43xx_CIR_SBIMSTATE, sbimstate);
1349         }
1350
1351         sbtmstatelow = BCM43xx_SBTMSTATELOW_CLOCK |
1352                        BCM43xx_SBTMSTATELOW_FORCE_GATE_CLOCK |
1353                        core_flags;
1354         bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
1355         udelay(1);
1356
1357         sbtmstatelow = BCM43xx_SBTMSTATELOW_CLOCK | core_flags;
1358         bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
1359         udelay(1);
1360
1361         bcm->current_core->enabled = 1;
1362         assert(err == 0);
1363 out:
1364         return err;
1365 }
1366
1367 /* http://bcm-specs.sipsolutions.net/80211CoreReset */
1368 void bcm43xx_wireless_core_reset(struct bcm43xx_private *bcm, int connect_phy)
1369 {
1370         u32 flags = 0x00040000;
1371
1372         if ((bcm43xx_core_enabled(bcm)) &&
1373             !bcm43xx_using_pio(bcm)) {
1374 //FIXME: Do we _really_ want #ifndef CONFIG_BCM947XX here?
1375 #if 0
1376 #ifndef CONFIG_BCM947XX
1377                 /* reset all used DMA controllers. */
1378                 bcm43xx_dmacontroller_tx_reset(bcm, BCM43xx_MMIO_DMA1_BASE);
1379                 bcm43xx_dmacontroller_tx_reset(bcm, BCM43xx_MMIO_DMA2_BASE);
1380                 bcm43xx_dmacontroller_tx_reset(bcm, BCM43xx_MMIO_DMA3_BASE);
1381                 bcm43xx_dmacontroller_tx_reset(bcm, BCM43xx_MMIO_DMA4_BASE);
1382                 bcm43xx_dmacontroller_rx_reset(bcm, BCM43xx_MMIO_DMA1_BASE);
1383                 if (bcm->current_core->rev < 5)
1384                         bcm43xx_dmacontroller_rx_reset(bcm, BCM43xx_MMIO_DMA4_BASE);
1385 #endif
1386 #endif
1387         }
1388         if (bcm43xx_status(bcm) == BCM43xx_STAT_SHUTTINGDOWN) {
1389                 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD,
1390                                 bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD)
1391                                 & ~(BCM43xx_SBF_MAC_ENABLED | 0x00000002));
1392         } else {
1393                 if (connect_phy)
1394                         flags |= 0x20000000;
1395                 bcm43xx_phy_connect(bcm, connect_phy);
1396                 bcm43xx_core_enable(bcm, flags);
1397                 bcm43xx_write16(bcm, 0x03E6, 0x0000);
1398                 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD,
1399                                 bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD)
1400                                 | BCM43xx_SBF_400);
1401         }
1402 }
1403
1404 static void bcm43xx_wireless_core_disable(struct bcm43xx_private *bcm)
1405 {
1406         bcm43xx_radio_turn_off(bcm);
1407         bcm43xx_write16(bcm, 0x03E6, 0x00F4);
1408         bcm43xx_core_disable(bcm, 0);
1409 }
1410
1411 /* Mark the current 80211 core inactive. */
1412 static void bcm43xx_wireless_core_mark_inactive(struct bcm43xx_private *bcm)
1413 {
1414         u32 sbtmstatelow;
1415
1416         bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
1417         bcm43xx_radio_turn_off(bcm);
1418         sbtmstatelow = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
1419         sbtmstatelow &= 0xDFF5FFFF;
1420         sbtmstatelow |= 0x000A0000;
1421         bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
1422         udelay(1);
1423         sbtmstatelow = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
1424         sbtmstatelow &= 0xFFF5FFFF;
1425         sbtmstatelow |= 0x00080000;
1426         bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
1427         udelay(1);
1428 }
1429
1430 static void handle_irq_transmit_status(struct bcm43xx_private *bcm)
1431 {
1432         u32 v0, v1;
1433         u16 tmp;
1434         struct bcm43xx_xmitstatus stat;
1435
1436         while (1) {
1437                 v0 = bcm43xx_read32(bcm, BCM43xx_MMIO_XMITSTAT_0);
1438                 if (!v0)
1439                         break;
1440                 v1 = bcm43xx_read32(bcm, BCM43xx_MMIO_XMITSTAT_1);
1441
1442                 stat.cookie = (v0 >> 16) & 0x0000FFFF;
1443                 tmp = (u16)((v0 & 0xFFF0) | ((v0 & 0xF) >> 1));
1444                 stat.flags = tmp & 0xFF;
1445                 stat.cnt1 = (tmp & 0x0F00) >> 8;
1446                 stat.cnt2 = (tmp & 0xF000) >> 12;
1447                 stat.seq = (u16)(v1 & 0xFFFF);
1448                 stat.unknown = (u16)((v1 >> 16) & 0xFF);
1449
1450                 bcm43xx_debugfs_log_txstat(bcm, &stat);
1451
1452                 if (stat.flags & BCM43xx_TXSTAT_FLAG_IGNORE)
1453                         continue;
1454                 if (!(stat.flags & BCM43xx_TXSTAT_FLAG_ACK)) {
1455                         //TODO: packet was not acked (was lost)
1456                 }
1457                 //TODO: There are more (unknown) flags to test. see bcm43xx_main.h
1458
1459                 if (bcm43xx_using_pio(bcm))
1460                         bcm43xx_pio_handle_xmitstatus(bcm, &stat);
1461                 else
1462                         bcm43xx_dma_handle_xmitstatus(bcm, &stat);
1463         }
1464 }
1465
1466 static void drain_txstatus_queue(struct bcm43xx_private *bcm)
1467 {
1468         u32 dummy;
1469
1470         if (bcm->current_core->rev < 5)
1471                 return;
1472         /* Read all entries from the microcode TXstatus FIFO
1473          * and throw them away.
1474          */
1475         while (1) {
1476                 dummy = bcm43xx_read32(bcm, BCM43xx_MMIO_XMITSTAT_0);
1477                 if (!dummy)
1478                         break;
1479                 dummy = bcm43xx_read32(bcm, BCM43xx_MMIO_XMITSTAT_1);
1480         }
1481 }
1482
1483 static void bcm43xx_generate_noise_sample(struct bcm43xx_private *bcm)
1484 {
1485         bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x408, 0x7F7F);
1486         bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x40A, 0x7F7F);
1487         bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD,
1488                         bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD) | (1 << 4));
1489         assert(bcm->noisecalc.core_at_start == bcm->current_core);
1490         assert(bcm->noisecalc.channel_at_start == bcm43xx_current_radio(bcm)->channel);
1491 }
1492
1493 static void bcm43xx_calculate_link_quality(struct bcm43xx_private *bcm)
1494 {
1495         /* Top half of Link Quality calculation. */
1496
1497         if (bcm->noisecalc.calculation_running)
1498                 return;
1499         bcm->noisecalc.core_at_start = bcm->current_core;
1500         bcm->noisecalc.channel_at_start = bcm43xx_current_radio(bcm)->channel;
1501         bcm->noisecalc.calculation_running = 1;
1502         bcm->noisecalc.nr_samples = 0;
1503
1504         bcm43xx_generate_noise_sample(bcm);
1505 }
1506
1507 static void handle_irq_noise(struct bcm43xx_private *bcm)
1508 {
1509         struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
1510         u16 tmp;
1511         u8 noise[4];
1512         u8 i, j;
1513         s32 average;
1514
1515         /* Bottom half of Link Quality calculation. */
1516
1517         assert(bcm->noisecalc.calculation_running);
1518         if (bcm->noisecalc.core_at_start != bcm->current_core ||
1519             bcm->noisecalc.channel_at_start != radio->channel)
1520                 goto drop_calculation;
1521         tmp = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED, 0x408);
1522         noise[0] = (tmp & 0x00FF);
1523         noise[1] = (tmp & 0xFF00) >> 8;
1524         tmp = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED, 0x40A);
1525         noise[2] = (tmp & 0x00FF);
1526         noise[3] = (tmp & 0xFF00) >> 8;
1527         if (noise[0] == 0x7F || noise[1] == 0x7F ||
1528             noise[2] == 0x7F || noise[3] == 0x7F)
1529                 goto generate_new;
1530
1531         /* Get the noise samples. */
1532         assert(bcm->noisecalc.nr_samples < 8);
1533         i = bcm->noisecalc.nr_samples;
1534         noise[0] = limit_value(noise[0], 0, ARRAY_SIZE(radio->nrssi_lt) - 1);
1535         noise[1] = limit_value(noise[1], 0, ARRAY_SIZE(radio->nrssi_lt) - 1);
1536         noise[2] = limit_value(noise[2], 0, ARRAY_SIZE(radio->nrssi_lt) - 1);
1537         noise[3] = limit_value(noise[3], 0, ARRAY_SIZE(radio->nrssi_lt) - 1);
1538         bcm->noisecalc.samples[i][0] = radio->nrssi_lt[noise[0]];
1539         bcm->noisecalc.samples[i][1] = radio->nrssi_lt[noise[1]];
1540         bcm->noisecalc.samples[i][2] = radio->nrssi_lt[noise[2]];
1541         bcm->noisecalc.samples[i][3] = radio->nrssi_lt[noise[3]];
1542         bcm->noisecalc.nr_samples++;
1543         if (bcm->noisecalc.nr_samples == 8) {
1544                 /* Calculate the Link Quality by the noise samples. */
1545                 average = 0;
1546                 for (i = 0; i < 8; i++) {
1547                         for (j = 0; j < 4; j++)
1548                                 average += bcm->noisecalc.samples[i][j];
1549                 }
1550                 average /= (8 * 4);
1551                 average *= 125;
1552                 average += 64;
1553                 average /= 128;
1554
1555                 tmp = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED, 0x40C);
1556                 tmp = (tmp / 128) & 0x1F;
1557                 if (tmp >= 8)
1558                         average += 2;
1559                 else
1560                         average -= 25;
1561                 if (tmp == 8)
1562                         average -= 72;
1563                 else
1564                         average -= 48;
1565
1566                 bcm->stats.noise = average;
1567 drop_calculation:
1568                 bcm->noisecalc.calculation_running = 0;
1569                 return;
1570         }
1571 generate_new:
1572         bcm43xx_generate_noise_sample(bcm);
1573 }
1574
1575 static void handle_irq_ps(struct bcm43xx_private *bcm)
1576 {
1577         if (bcm->ieee->iw_mode == IW_MODE_MASTER) {
1578                 ///TODO: PS TBTT
1579         } else {
1580                 if (1/*FIXME: the last PSpoll frame was sent successfully */)
1581                         bcm43xx_power_saving_ctl_bits(bcm, -1, -1);
1582         }
1583         if (bcm->ieee->iw_mode == IW_MODE_ADHOC)
1584                 bcm->reg124_set_0x4 = 1;
1585         //FIXME else set to false?
1586 }
1587
1588 static void handle_irq_reg124(struct bcm43xx_private *bcm)
1589 {
1590         if (!bcm->reg124_set_0x4)
1591                 return;
1592         bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD,
1593                         bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD)
1594                         | 0x4);
1595         //FIXME: reset reg124_set_0x4 to false?
1596 }
1597
1598 static void handle_irq_pmq(struct bcm43xx_private *bcm)
1599 {
1600         u32 tmp;
1601
1602         //TODO: AP mode.
1603
1604         while (1) {
1605                 tmp = bcm43xx_read32(bcm, BCM43xx_MMIO_PS_STATUS);
1606                 if (!(tmp & 0x00000008))
1607                         break;
1608         }
1609         /* 16bit write is odd, but correct. */
1610         bcm43xx_write16(bcm, BCM43xx_MMIO_PS_STATUS, 0x0002);
1611 }
1612
1613 static void bcm43xx_generate_beacon_template(struct bcm43xx_private *bcm,
1614                                              u16 ram_offset, u16 shm_size_offset)
1615 {
1616         u32 value;
1617         u16 size = 0;
1618
1619         /* Timestamp. */
1620         //FIXME: assumption: The chip sets the timestamp
1621         value = 0;
1622         bcm43xx_ram_write(bcm, ram_offset++, value);
1623         bcm43xx_ram_write(bcm, ram_offset++, value);
1624         size += 8;
1625
1626         /* Beacon Interval / Capability Information */
1627         value = 0x0000;//FIXME: Which interval?
1628         value |= (1 << 0) << 16; /* ESS */
1629         value |= (1 << 2) << 16; /* CF Pollable */      //FIXME?
1630         value |= (1 << 3) << 16; /* CF Poll Request */  //FIXME?
1631         if (!bcm->ieee->open_wep)
1632                 value |= (1 << 4) << 16; /* Privacy */
1633         bcm43xx_ram_write(bcm, ram_offset++, value);
1634         size += 4;
1635
1636         /* SSID */
1637         //TODO
1638
1639         /* FH Parameter Set */
1640         //TODO
1641
1642         /* DS Parameter Set */
1643         //TODO
1644
1645         /* CF Parameter Set */
1646         //TODO
1647
1648         /* TIM */
1649         //TODO
1650
1651         bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, shm_size_offset, size);
1652 }
1653
1654 static void handle_irq_beacon(struct bcm43xx_private *bcm)
1655 {
1656         u32 status;
1657
1658         bcm->irq_savedstate &= ~BCM43xx_IRQ_BEACON;
1659         status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD);
1660
1661         if ((status & 0x1) && (status & 0x2)) {
1662                 /* ACK beacon IRQ. */
1663                 bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON,
1664                                 BCM43xx_IRQ_BEACON);
1665                 bcm->irq_savedstate |= BCM43xx_IRQ_BEACON;
1666                 return;
1667         }
1668         if (!(status & 0x1)) {
1669                 bcm43xx_generate_beacon_template(bcm, 0x68, 0x18);
1670                 status |= 0x1;
1671                 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD, status);
1672         }
1673         if (!(status & 0x2)) {
1674                 bcm43xx_generate_beacon_template(bcm, 0x468, 0x1A);
1675                 status |= 0x2;
1676                 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD, status);
1677         }
1678 }
1679
1680 /* Interrupt handler bottom-half */
1681 static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm)
1682 {
1683         u32 reason;
1684         u32 dma_reason[6];
1685         u32 merged_dma_reason = 0;
1686         int i, activity = 0;
1687         unsigned long flags;
1688
1689 #ifdef CONFIG_BCM43XX_DEBUG
1690         u32 _handled = 0x00000000;
1691 # define bcmirq_handled(irq)    do { _handled |= (irq); } while (0)
1692 #else
1693 # define bcmirq_handled(irq)    do { /* nothing */ } while (0)
1694 #endif /* CONFIG_BCM43XX_DEBUG*/
1695
1696         spin_lock_irqsave(&bcm->irq_lock, flags);
1697         reason = bcm->irq_reason;
1698         for (i = 5; i >= 0; i--) {
1699                 dma_reason[i] = bcm->dma_reason[i];
1700                 merged_dma_reason |= dma_reason[i];
1701         }
1702
1703         if (unlikely(reason & BCM43xx_IRQ_XMIT_ERROR)) {
1704                 /* TX error. We get this when Template Ram is written in wrong endianess
1705                  * in dummy_tx(). We also get this if something is wrong with the TX header
1706                  * on DMA or PIO queues.
1707                  * Maybe we get this in other error conditions, too.
1708                  */
1709                 printkl(KERN_ERR PFX "FATAL ERROR: BCM43xx_IRQ_XMIT_ERROR\n");
1710                 bcmirq_handled(BCM43xx_IRQ_XMIT_ERROR);
1711         }
1712         if (unlikely(merged_dma_reason & BCM43xx_DMAIRQ_FATALMASK)) {
1713                 printkl(KERN_ERR PFX "FATAL ERROR: Fatal DMA error: "
1714                                      "0x%08X, 0x%08X, 0x%08X, "
1715                                      "0x%08X, 0x%08X, 0x%08X\n",
1716                         dma_reason[0], dma_reason[1],
1717                         dma_reason[2], dma_reason[3],
1718                         dma_reason[4], dma_reason[5]);
1719                 bcm43xx_controller_restart(bcm, "DMA error");
1720                 mmiowb();
1721                 spin_unlock_irqrestore(&bcm->irq_lock, flags);
1722                 return;
1723         }
1724         if (unlikely(merged_dma_reason & BCM43xx_DMAIRQ_NONFATALMASK)) {
1725                 printkl(KERN_ERR PFX "DMA error: "
1726                                      "0x%08X, 0x%08X, 0x%08X, "
1727                                      "0x%08X, 0x%08X, 0x%08X\n",
1728                         dma_reason[0], dma_reason[1],
1729                         dma_reason[2], dma_reason[3],
1730                         dma_reason[4], dma_reason[5]);
1731         }
1732
1733         if (reason & BCM43xx_IRQ_PS) {
1734                 handle_irq_ps(bcm);
1735                 bcmirq_handled(BCM43xx_IRQ_PS);
1736         }
1737
1738         if (reason & BCM43xx_IRQ_REG124) {
1739                 handle_irq_reg124(bcm);
1740                 bcmirq_handled(BCM43xx_IRQ_REG124);
1741         }
1742
1743         if (reason & BCM43xx_IRQ_BEACON) {
1744                 if (bcm->ieee->iw_mode == IW_MODE_MASTER)
1745                         handle_irq_beacon(bcm);
1746                 bcmirq_handled(BCM43xx_IRQ_BEACON);
1747         }
1748
1749         if (reason & BCM43xx_IRQ_PMQ) {
1750                 handle_irq_pmq(bcm);
1751                 bcmirq_handled(BCM43xx_IRQ_PMQ);
1752         }
1753
1754         if (reason & BCM43xx_IRQ_SCAN) {
1755                 /*TODO*/
1756                 //bcmirq_handled(BCM43xx_IRQ_SCAN);
1757         }
1758
1759         if (reason & BCM43xx_IRQ_NOISE) {
1760                 handle_irq_noise(bcm);
1761                 bcmirq_handled(BCM43xx_IRQ_NOISE);
1762         }
1763
1764         /* Check the DMA reason registers for received data. */
1765         if (dma_reason[0] & BCM43xx_DMAIRQ_RX_DONE) {
1766                 if (bcm43xx_using_pio(bcm))
1767                         bcm43xx_pio_rx(bcm43xx_current_pio(bcm)->queue0);
1768                 else
1769                         bcm43xx_dma_rx(bcm43xx_current_dma(bcm)->rx_ring0);
1770                 /* We intentionally don't set "activity" to 1, here. */
1771         }
1772         assert(!(dma_reason[1] & BCM43xx_DMAIRQ_RX_DONE));
1773         assert(!(dma_reason[2] & BCM43xx_DMAIRQ_RX_DONE));
1774         if (dma_reason[3] & BCM43xx_DMAIRQ_RX_DONE) {
1775                 if (bcm43xx_using_pio(bcm))
1776                         bcm43xx_pio_rx(bcm43xx_current_pio(bcm)->queue3);
1777                 else
1778                         bcm43xx_dma_rx(bcm43xx_current_dma(bcm)->rx_ring3);
1779                 activity = 1;
1780         }
1781         assert(!(dma_reason[4] & BCM43xx_DMAIRQ_RX_DONE));
1782         assert(!(dma_reason[5] & BCM43xx_DMAIRQ_RX_DONE));
1783         bcmirq_handled(BCM43xx_IRQ_RX);
1784
1785         if (reason & BCM43xx_IRQ_XMIT_STATUS) {
1786                 handle_irq_transmit_status(bcm);
1787                 activity = 1;
1788                 //TODO: In AP mode, this also causes sending of powersave responses.
1789                 bcmirq_handled(BCM43xx_IRQ_XMIT_STATUS);
1790         }
1791
1792         /* IRQ_PIO_WORKAROUND is handled in the top-half. */
1793         bcmirq_handled(BCM43xx_IRQ_PIO_WORKAROUND);
1794 #ifdef CONFIG_BCM43XX_DEBUG
1795         if (unlikely(reason & ~_handled)) {
1796                 printkl(KERN_WARNING PFX
1797                         "Unhandled IRQ! Reason: 0x%08x,  Unhandled: 0x%08x,  "
1798                         "DMA: 0x%08x, 0x%08x, 0x%08x, 0x%08x\n",
1799                         reason, (reason & ~_handled),
1800                         dma_reason[0], dma_reason[1],
1801                         dma_reason[2], dma_reason[3]);
1802         }
1803 #endif
1804 #undef bcmirq_handled
1805
1806         if (!modparam_noleds)
1807                 bcm43xx_leds_update(bcm, activity);
1808         bcm43xx_interrupt_enable(bcm, bcm->irq_savedstate);
1809         mmiowb();
1810         spin_unlock_irqrestore(&bcm->irq_lock, flags);
1811 }
1812
1813 static void pio_irq_workaround(struct bcm43xx_private *bcm,
1814                                u16 base, int queueidx)
1815 {
1816         u16 rxctl;
1817
1818         rxctl = bcm43xx_read16(bcm, base + BCM43xx_PIO_RXCTL);
1819         if (rxctl & BCM43xx_PIO_RXCTL_DATAAVAILABLE)
1820                 bcm->dma_reason[queueidx] |= BCM43xx_DMAIRQ_RX_DONE;
1821         else
1822                 bcm->dma_reason[queueidx] &= ~BCM43xx_DMAIRQ_RX_DONE;
1823 }
1824
1825 static void bcm43xx_interrupt_ack(struct bcm43xx_private *bcm, u32 reason)
1826 {
1827         if (bcm43xx_using_pio(bcm) &&
1828             (bcm->current_core->rev < 3) &&
1829             (!(reason & BCM43xx_IRQ_PIO_WORKAROUND))) {
1830                 /* Apply a PIO specific workaround to the dma_reasons */
1831                 pio_irq_workaround(bcm, BCM43xx_MMIO_PIO1_BASE, 0);
1832                 pio_irq_workaround(bcm, BCM43xx_MMIO_PIO2_BASE, 1);
1833                 pio_irq_workaround(bcm, BCM43xx_MMIO_PIO3_BASE, 2);
1834                 pio_irq_workaround(bcm, BCM43xx_MMIO_PIO4_BASE, 3);
1835         }
1836
1837         bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, reason);
1838
1839         bcm43xx_write32(bcm, BCM43xx_MMIO_DMA0_REASON,
1840                         bcm->dma_reason[0]);
1841         bcm43xx_write32(bcm, BCM43xx_MMIO_DMA1_REASON,
1842                         bcm->dma_reason[1]);
1843         bcm43xx_write32(bcm, BCM43xx_MMIO_DMA2_REASON,
1844                         bcm->dma_reason[2]);
1845         bcm43xx_write32(bcm, BCM43xx_MMIO_DMA3_REASON,
1846                         bcm->dma_reason[3]);
1847         bcm43xx_write32(bcm, BCM43xx_MMIO_DMA4_REASON,
1848                         bcm->dma_reason[4]);
1849         bcm43xx_write32(bcm, BCM43xx_MMIO_DMA5_REASON,
1850                         bcm->dma_reason[5]);
1851 }
1852
1853 /* Interrupt handler top-half */
1854 static irqreturn_t bcm43xx_interrupt_handler(int irq, void *dev_id)
1855 {
1856         irqreturn_t ret = IRQ_HANDLED;
1857         struct bcm43xx_private *bcm = dev_id;
1858         u32 reason;
1859
1860         if (!bcm)
1861                 return IRQ_NONE;
1862
1863         spin_lock(&bcm->irq_lock);
1864
1865         assert(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED);
1866         assert(bcm->current_core->id == BCM43xx_COREID_80211);
1867
1868         reason = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON);
1869         if (reason == 0xffffffff) {
1870                 /* irq not for us (shared irq) */
1871                 ret = IRQ_NONE;
1872                 goto out;
1873         }
1874         reason &= bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_MASK);
1875         if (!reason)
1876                 goto out;
1877
1878         bcm->dma_reason[0] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA0_REASON)
1879                              & 0x0001DC00;
1880         bcm->dma_reason[1] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA1_REASON)
1881                              & 0x0000DC00;
1882         bcm->dma_reason[2] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA2_REASON)
1883                              & 0x0000DC00;
1884         bcm->dma_reason[3] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA3_REASON)
1885                              & 0x0001DC00;
1886         bcm->dma_reason[4] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA4_REASON)
1887                              & 0x0000DC00;
1888         bcm->dma_reason[5] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA5_REASON)
1889                              & 0x0000DC00;
1890
1891         bcm43xx_interrupt_ack(bcm, reason);
1892
1893         /* disable all IRQs. They are enabled again in the bottom half. */
1894         bcm->irq_savedstate = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
1895         /* save the reason code and call our bottom half. */
1896         bcm->irq_reason = reason;
1897         tasklet_schedule(&bcm->isr_tasklet);
1898
1899 out:
1900         mmiowb();
1901         spin_unlock(&bcm->irq_lock);
1902
1903         return ret;
1904 }
1905
1906 static void bcm43xx_release_firmware(struct bcm43xx_private *bcm, int force)
1907 {
1908         struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
1909
1910         if (bcm->firmware_norelease && !force)
1911                 return; /* Suspending or controller reset. */
1912         release_firmware(phy->ucode);
1913         phy->ucode = NULL;
1914         release_firmware(phy->pcm);
1915         phy->pcm = NULL;
1916         release_firmware(phy->initvals0);
1917         phy->initvals0 = NULL;
1918         release_firmware(phy->initvals1);
1919         phy->initvals1 = NULL;
1920 }
1921
1922 static int bcm43xx_request_firmware(struct bcm43xx_private *bcm)
1923 {
1924         struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
1925         u8 rev = bcm->current_core->rev;
1926         int err = 0;
1927         int nr;
1928         char buf[22 + sizeof(modparam_fwpostfix) - 1] = { 0 };
1929
1930         if (!phy->ucode) {
1931                 snprintf(buf, ARRAY_SIZE(buf), "bcm43xx_microcode%d%s.fw",
1932                          (rev >= 5 ? 5 : rev),
1933                          modparam_fwpostfix);
1934                 err = request_firmware(&phy->ucode, buf, &bcm->pci_dev->dev);
1935                 if (err) {
1936                         printk(KERN_ERR PFX 
1937                                "Error: Microcode \"%s\" not available or load failed.\n",
1938                                 buf);
1939                         goto error;
1940                 }
1941         }
1942
1943         if (!phy->pcm) {
1944                 snprintf(buf, ARRAY_SIZE(buf),
1945                          "bcm43xx_pcm%d%s.fw",
1946                          (rev < 5 ? 4 : 5),
1947                          modparam_fwpostfix);
1948                 err = request_firmware(&phy->pcm, buf, &bcm->pci_dev->dev);
1949                 if (err) {
1950                         printk(KERN_ERR PFX
1951                                "Error: PCM \"%s\" not available or load failed.\n",
1952                                buf);
1953                         goto error;
1954                 }
1955         }
1956
1957         if (!phy->initvals0) {
1958                 if (rev == 2 || rev == 4) {
1959                         switch (phy->type) {
1960                         case BCM43xx_PHYTYPE_A:
1961                                 nr = 3;
1962                                 break;
1963                         case BCM43xx_PHYTYPE_B:
1964                         case BCM43xx_PHYTYPE_G:
1965                                 nr = 1;
1966                                 break;
1967                         default:
1968                                 goto err_noinitval;
1969                         }
1970                 
1971                 } else if (rev >= 5) {
1972                         switch (phy->type) {
1973                         case BCM43xx_PHYTYPE_A:
1974                                 nr = 7;
1975                                 break;
1976                         case BCM43xx_PHYTYPE_B:
1977                         case BCM43xx_PHYTYPE_G:
1978                                 nr = 5;
1979                                 break;
1980                         default:
1981                                 goto err_noinitval;
1982                         }
1983                 } else
1984                         goto err_noinitval;
1985                 snprintf(buf, ARRAY_SIZE(buf), "bcm43xx_initval%02d%s.fw",
1986                          nr, modparam_fwpostfix);
1987
1988                 err = request_firmware(&phy->initvals0, buf, &bcm->pci_dev->dev);
1989                 if (err) {
1990                         printk(KERN_ERR PFX 
1991                                "Error: InitVals \"%s\" not available or load failed.\n",
1992                                 buf);
1993                         goto error;
1994                 }
1995                 if (phy->initvals0->size % sizeof(struct bcm43xx_initval)) {
1996                         printk(KERN_ERR PFX "InitVals fileformat error.\n");
1997                         goto error;
1998                 }
1999         }
2000
2001         if (!phy->initvals1) {
2002                 if (rev >= 5) {
2003                         u32 sbtmstatehigh;
2004
2005                         switch (phy->type) {
2006                         case BCM43xx_PHYTYPE_A:
2007                                 sbtmstatehigh = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATEHIGH);
2008                                 if (sbtmstatehigh & 0x00010000)
2009                                         nr = 9;
2010                                 else
2011                                         nr = 10;
2012                                 break;
2013                         case BCM43xx_PHYTYPE_B:
2014                         case BCM43xx_PHYTYPE_G:
2015                                         nr = 6;
2016                                 break;
2017                         default:
2018                                 goto err_noinitval;
2019                         }
2020                         snprintf(buf, ARRAY_SIZE(buf), "bcm43xx_initval%02d%s.fw",
2021                                  nr, modparam_fwpostfix);
2022
2023                         err = request_firmware(&phy->initvals1, buf, &bcm->pci_dev->dev);
2024                         if (err) {
2025                                 printk(KERN_ERR PFX 
2026                                        "Error: InitVals \"%s\" not available or load failed.\n",
2027                                         buf);
2028                                 goto error;
2029                         }
2030                         if (phy->initvals1->size % sizeof(struct bcm43xx_initval)) {
2031                                 printk(KERN_ERR PFX "InitVals fileformat error.\n");
2032                                 goto error;
2033                         }
2034                 }
2035         }
2036
2037 out:
2038         return err;
2039 error:
2040         bcm43xx_release_firmware(bcm, 1);
2041         goto out;
2042 err_noinitval:
2043         printk(KERN_ERR PFX "Error: No InitVals available!\n");
2044         err = -ENOENT;
2045         goto error;
2046 }
2047
2048 static void bcm43xx_upload_microcode(struct bcm43xx_private *bcm)
2049 {
2050         struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
2051         const u32 *data;
2052         unsigned int i, len;
2053
2054         /* Upload Microcode. */
2055         data = (u32 *)(phy->ucode->data);
2056         len = phy->ucode->size / sizeof(u32);
2057         bcm43xx_shm_control_word(bcm, BCM43xx_SHM_UCODE, 0x0000);
2058         for (i = 0; i < len; i++) {
2059                 bcm43xx_write32(bcm, BCM43xx_MMIO_SHM_DATA,
2060                                 be32_to_cpu(data[i]));
2061                 udelay(10);
2062         }
2063
2064         /* Upload PCM data. */
2065         data = (u32 *)(phy->pcm->data);
2066         len = phy->pcm->size / sizeof(u32);
2067         bcm43xx_shm_control_word(bcm, BCM43xx_SHM_PCM, 0x01ea);
2068         bcm43xx_write32(bcm, BCM43xx_MMIO_SHM_DATA, 0x00004000);
2069         bcm43xx_shm_control_word(bcm, BCM43xx_SHM_PCM, 0x01eb);
2070         for (i = 0; i < len; i++) {
2071                 bcm43xx_write32(bcm, BCM43xx_MMIO_SHM_DATA,
2072                                 be32_to_cpu(data[i]));
2073                 udelay(10);
2074         }
2075 }
2076
2077 static int bcm43xx_write_initvals(struct bcm43xx_private *bcm,
2078                                   const struct bcm43xx_initval *data,
2079                                   const unsigned int len)
2080 {
2081         u16 offset, size;
2082         u32 value;
2083         unsigned int i;
2084
2085         for (i = 0; i < len; i++) {
2086                 offset = be16_to_cpu(data[i].offset);
2087                 size = be16_to_cpu(data[i].size);
2088                 value = be32_to_cpu(data[i].value);
2089
2090                 if (unlikely(offset >= 0x1000))
2091                         goto err_format;
2092                 if (size == 2) {
2093                         if (unlikely(value & 0xFFFF0000))
2094                                 goto err_format;
2095                         bcm43xx_write16(bcm, offset, (u16)value);
2096                 } else if (size == 4) {
2097                         bcm43xx_write32(bcm, offset, value);
2098                 } else
2099                         goto err_format;
2100         }
2101
2102         return 0;
2103
2104 err_format:
2105         printk(KERN_ERR PFX "InitVals (bcm43xx_initvalXX.fw) file-format error. "
2106                             "Please fix your bcm43xx firmware files.\n");
2107         return -EPROTO;
2108 }
2109
2110 static int bcm43xx_upload_initvals(struct bcm43xx_private *bcm)
2111 {
2112         struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
2113         int err;
2114
2115         err = bcm43xx_write_initvals(bcm, (struct bcm43xx_initval *)phy->initvals0->data,
2116                                      phy->initvals0->size / sizeof(struct bcm43xx_initval));
2117         if (err)
2118                 goto out;
2119         if (phy->initvals1) {
2120                 err = bcm43xx_write_initvals(bcm, (struct bcm43xx_initval *)phy->initvals1->data,
2121                                              phy->initvals1->size / sizeof(struct bcm43xx_initval));
2122                 if (err)
2123                         goto out;
2124         }
2125 out:
2126         return err;
2127 }
2128
2129 #ifdef CONFIG_BCM947XX
2130 static struct pci_device_id bcm43xx_47xx_ids[] = {
2131         { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4324) },
2132         { 0 }
2133 };
2134 #endif
2135
2136 static int bcm43xx_initialize_irq(struct bcm43xx_private *bcm)
2137 {
2138         int err;
2139
2140         bcm->irq = bcm->pci_dev->irq;
2141 #ifdef CONFIG_BCM947XX
2142         if (bcm->pci_dev->bus->number == 0) {
2143                 struct pci_dev *d;
2144                 struct pci_device_id *id;
2145                 for (id = bcm43xx_47xx_ids; id->vendor; id++) {
2146                         d = pci_get_device(id->vendor, id->device, NULL);
2147                         if (d != NULL) {
2148                                 bcm->irq = d->irq;
2149                                 pci_dev_put(d);
2150                                 break;
2151                         }
2152                 }
2153         }
2154 #endif
2155         err = request_irq(bcm->irq, bcm43xx_interrupt_handler,
2156                           IRQF_SHARED, KBUILD_MODNAME, bcm);
2157         if (err)
2158                 printk(KERN_ERR PFX "Cannot register IRQ%d\n", bcm->irq);
2159
2160         return err;
2161 }
2162
2163 /* Switch to the core used to write the GPIO register.
2164  * This is either the ChipCommon, or the PCI core.
2165  */
2166 static int switch_to_gpio_core(struct bcm43xx_private *bcm)
2167 {
2168         int err;
2169
2170         /* Where to find the GPIO register depends on the chipset.
2171          * If it has a ChipCommon, its register at offset 0x6c is the GPIO
2172          * control register. Otherwise the register at offset 0x6c in the
2173          * PCI core is the GPIO control register.
2174          */
2175         err = bcm43xx_switch_core(bcm, &bcm->core_chipcommon);
2176         if (err == -ENODEV) {
2177                 err = bcm43xx_switch_core(bcm, &bcm->core_pci);
2178                 if (unlikely(err == -ENODEV)) {
2179                         printk(KERN_ERR PFX "gpio error: "
2180                                "Neither ChipCommon nor PCI core available!\n");
2181                 }
2182         }
2183
2184         return err;
2185 }
2186
2187 /* Initialize the GPIOs
2188  * http://bcm-specs.sipsolutions.net/GPIO
2189  */
2190 static int bcm43xx_gpio_init(struct bcm43xx_private *bcm)
2191 {
2192         struct bcm43xx_coreinfo *old_core;
2193         int err;
2194         u32 mask, set;
2195
2196         bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD,
2197                         bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD)
2198                         & 0xFFFF3FFF);
2199
2200         bcm43xx_leds_switch_all(bcm, 0);
2201         bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_MASK,
2202                         bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_MASK) | 0x000F);
2203
2204         mask = 0x0000001F;
2205         set = 0x0000000F;
2206         if (bcm->chip_id == 0x4301) {
2207                 mask |= 0x0060;
2208                 set |= 0x0060;
2209         }
2210         if (0 /* FIXME: conditional unknown */) {
2211                 bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_MASK,
2212                                 bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_MASK)
2213                                 | 0x0100);
2214                 mask |= 0x0180;
2215                 set |= 0x0180;
2216         }
2217         if (bcm->sprom.boardflags & BCM43xx_BFL_PACTRL) {
2218                 bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_MASK,
2219                                 bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_MASK)
2220                                 | 0x0200);
2221                 mask |= 0x0200;
2222                 set |= 0x0200;
2223         }
2224         if (bcm->current_core->rev >= 2)
2225                 mask  |= 0x0010; /* FIXME: This is redundant. */
2226
2227         old_core = bcm->current_core;
2228         err = switch_to_gpio_core(bcm);
2229         if (err)
2230                 goto out;
2231         bcm43xx_write32(bcm, BCM43xx_GPIO_CONTROL,
2232                         (bcm43xx_read32(bcm, BCM43xx_GPIO_CONTROL) & mask) | set);
2233         err = bcm43xx_switch_core(bcm, old_core);
2234 out:
2235         return err;
2236 }
2237
2238 /* Turn off all GPIO stuff. Call this on module unload, for example. */
2239 static int bcm43xx_gpio_cleanup(struct bcm43xx_private *bcm)
2240 {
2241         struct bcm43xx_coreinfo *old_core;
2242         int err;
2243
2244         old_core = bcm->current_core;
2245         err = switch_to_gpio_core(bcm);
2246         if (err)
2247                 return err;
2248         bcm43xx_write32(bcm, BCM43xx_GPIO_CONTROL, 0x00000000);
2249         err = bcm43xx_switch_core(bcm, old_core);
2250         assert(err == 0);
2251
2252         return 0;
2253 }
2254
2255 /* http://bcm-specs.sipsolutions.net/EnableMac */
2256 void bcm43xx_mac_enable(struct bcm43xx_private *bcm)
2257 {
2258         bcm->mac_suspended--;
2259         assert(bcm->mac_suspended >= 0);
2260         if (bcm->mac_suspended == 0) {
2261                 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD,
2262                                 bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD)
2263                                 | BCM43xx_SBF_MAC_ENABLED);
2264                 bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, BCM43xx_IRQ_READY);
2265                 bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); /* dummy read */
2266                 bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); /* dummy read */
2267                 bcm43xx_power_saving_ctl_bits(bcm, -1, -1);
2268         }
2269 }
2270
2271 /* http://bcm-specs.sipsolutions.net/SuspendMAC */
2272 void bcm43xx_mac_suspend(struct bcm43xx_private *bcm)
2273 {
2274         int i;
2275         u32 tmp;
2276
2277         assert(bcm->mac_suspended >= 0);
2278         if (bcm->mac_suspended == 0) {
2279                 bcm43xx_power_saving_ctl_bits(bcm, -1, 1);
2280                 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD,
2281                                 bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD)
2282                                 & ~BCM43xx_SBF_MAC_ENABLED);
2283                 bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); /* dummy read */
2284                 for (i = 10000; i; i--) {
2285                         tmp = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON);
2286                         if (tmp & BCM43xx_IRQ_READY)
2287                                 goto out;
2288                         udelay(1);
2289                 }
2290                 printkl(KERN_ERR PFX "MAC suspend failed\n");
2291         }
2292 out:
2293         bcm->mac_suspended++;
2294 }
2295
2296 void bcm43xx_set_iwmode(struct bcm43xx_private *bcm,
2297                         int iw_mode)
2298 {
2299         unsigned long flags;
2300         struct net_device *net_dev = bcm->net_dev;
2301         u32 status;
2302         u16 value;
2303
2304         spin_lock_irqsave(&bcm->ieee->lock, flags);
2305         bcm->ieee->iw_mode = iw_mode;
2306         spin_unlock_irqrestore(&bcm->ieee->lock, flags);
2307         if (iw_mode == IW_MODE_MONITOR)
2308                 net_dev->type = ARPHRD_IEEE80211;
2309         else
2310                 net_dev->type = ARPHRD_ETHER;
2311
2312         status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
2313         /* Reset status to infrastructured mode */
2314         status &= ~(BCM43xx_SBF_MODE_AP | BCM43xx_SBF_MODE_MONITOR);
2315         status &= ~BCM43xx_SBF_MODE_PROMISC;
2316         status |= BCM43xx_SBF_MODE_NOTADHOC;
2317
2318 /* FIXME: Always enable promisc mode, until we get the MAC filters working correctly. */
2319 status |= BCM43xx_SBF_MODE_PROMISC;
2320
2321         switch (iw_mode) {
2322         case IW_MODE_MONITOR:
2323                 status |= BCM43xx_SBF_MODE_MONITOR;
2324                 status |= BCM43xx_SBF_MODE_PROMISC;
2325                 break;
2326         case IW_MODE_ADHOC:
2327                 status &= ~BCM43xx_SBF_MODE_NOTADHOC;
2328                 break;
2329         case IW_MODE_MASTER:
2330                 status |= BCM43xx_SBF_MODE_AP;
2331                 break;
2332         case IW_MODE_SECOND:
2333         case IW_MODE_REPEAT:
2334                 TODO(); /* TODO */
2335                 break;
2336         case IW_MODE_INFRA:
2337                 /* nothing to be done here... */
2338                 break;
2339         default:
2340                 dprintk(KERN_ERR PFX "Unknown mode in set_iwmode: %d\n", iw_mode);
2341         }
2342         if (net_dev->flags & IFF_PROMISC)
2343                 status |= BCM43xx_SBF_MODE_PROMISC;
2344         bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, status);
2345
2346         value = 0x0002;
2347         if (iw_mode != IW_MODE_ADHOC && iw_mode != IW_MODE_MASTER) {
2348                 if (bcm->chip_id == 0x4306 && bcm->chip_rev == 3)
2349                         value = 0x0064;
2350                 else
2351                         value = 0x0032;
2352         }
2353         bcm43xx_write16(bcm, 0x0612, value);
2354 }
2355
2356 /* This is the opposite of bcm43xx_chip_init() */
2357 static void bcm43xx_chip_cleanup(struct bcm43xx_private *bcm)
2358 {
2359         bcm43xx_radio_turn_off(bcm);
2360         if (!modparam_noleds)
2361                 bcm43xx_leds_exit(bcm);
2362         bcm43xx_gpio_cleanup(bcm);
2363         bcm43xx_release_firmware(bcm, 0);
2364 }
2365
2366 /* Initialize the chip
2367  * http://bcm-specs.sipsolutions.net/ChipInit
2368  */
2369 static int bcm43xx_chip_init(struct bcm43xx_private *bcm)
2370 {
2371         struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
2372         struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
2373         int err;
2374         int i, tmp;
2375         u32 value32;
2376         u16 value16;
2377
2378         bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD,
2379                         BCM43xx_SBF_CORE_READY
2380                         | BCM43xx_SBF_400);
2381
2382         err = bcm43xx_request_firmware(bcm);
2383         if (err)
2384                 goto out;
2385         bcm43xx_upload_microcode(bcm);
2386
2387         bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, 0xFFFFFFFF);
2388         bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, 0x00020402);
2389         i = 0;
2390         while (1) {
2391                 value32 = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON);
2392                 if (value32 == BCM43xx_IRQ_READY)
2393                         break;
2394                 i++;
2395                 if (i >= BCM43xx_IRQWAIT_MAX_RETRIES) {
2396                         printk(KERN_ERR PFX "IRQ_READY timeout\n");
2397                         err = -ENODEV;
2398                         goto err_release_fw;
2399                 }
2400                 udelay(10);
2401         }
2402         bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); /* dummy read */
2403
2404         value16 = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED,
2405                                      BCM43xx_UCODE_REVISION);
2406
2407         dprintk(KERN_INFO PFX "Microcode rev 0x%x, pl 0x%x "
2408                 "(20%.2i-%.2i-%.2i  %.2i:%.2i:%.2i)\n", value16,
2409                 bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED,
2410                                    BCM43xx_UCODE_PATCHLEVEL),
2411                 (bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED,
2412                                     BCM43xx_UCODE_DATE) >> 12) & 0xf,
2413                 (bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED,
2414                                     BCM43xx_UCODE_DATE) >> 8) & 0xf,
2415                 bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED,
2416                                    BCM43xx_UCODE_DATE) & 0xff,
2417                 (bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED,
2418                                    BCM43xx_UCODE_TIME) >> 11) & 0x1f,
2419                 (bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED,
2420                                    BCM43xx_UCODE_TIME) >> 5) & 0x3f,
2421                 bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED,
2422                                    BCM43xx_UCODE_TIME) & 0x1f);
2423
2424         if ( value16 > 0x128 ) {
2425                 printk(KERN_ERR PFX
2426                         "Firmware: no support for microcode extracted "
2427                         "from version 4.x binary drivers.\n");
2428                 err = -EOPNOTSUPP;
2429                 goto err_release_fw;
2430         }
2431
2432         err = bcm43xx_gpio_init(bcm);
2433         if (err)
2434                 goto err_release_fw;
2435
2436         err = bcm43xx_upload_initvals(bcm);
2437         if (err)
2438                 goto err_gpio_cleanup;
2439         bcm43xx_radio_turn_on(bcm);
2440         bcm->radio_hw_enable = bcm43xx_is_hw_radio_enabled(bcm);
2441         dprintk(KERN_INFO PFX "Radio %s by hardware\n",
2442                 (bcm->radio_hw_enable == 0) ? "disabled" : "enabled");
2443
2444         bcm43xx_write16(bcm, 0x03E6, 0x0000);
2445         err = bcm43xx_phy_init(bcm);
2446         if (err)
2447                 goto err_radio_off;
2448
2449         /* Select initial Interference Mitigation. */
2450         tmp = radio->interfmode;
2451         radio->interfmode = BCM43xx_RADIO_INTERFMODE_NONE;
2452         bcm43xx_radio_set_interference_mitigation(bcm, tmp);
2453
2454         bcm43xx_phy_set_antenna_diversity(bcm);
2455         bcm43xx_radio_set_txantenna(bcm, BCM43xx_RADIO_TXANTENNA_DEFAULT);
2456         if (phy->type == BCM43xx_PHYTYPE_B) {
2457                 value16 = bcm43xx_read16(bcm, 0x005E);
2458                 value16 |= 0x0004;
2459                 bcm43xx_write16(bcm, 0x005E, value16);
2460         }
2461         bcm43xx_write32(bcm, 0x0100, 0x01000000);
2462         if (bcm->current_core->rev < 5)
2463                 bcm43xx_write32(bcm, 0x010C, 0x01000000);
2464
2465         value32 = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
2466         value32 &= ~ BCM43xx_SBF_MODE_NOTADHOC;
2467         bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, value32);
2468         value32 = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
2469         value32 |= BCM43xx_SBF_MODE_NOTADHOC;
2470         bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, value32);
2471
2472         value32 = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
2473         value32 |= 0x100000;
2474         bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, value32);
2475
2476         if (bcm43xx_using_pio(bcm)) {
2477                 bcm43xx_write32(bcm, 0x0210, 0x00000100);
2478                 bcm43xx_write32(bcm, 0x0230, 0x00000100);
2479                 bcm43xx_write32(bcm, 0x0250, 0x00000100);
2480                 bcm43xx_write32(bcm, 0x0270, 0x00000100);
2481                 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0034, 0x0000);
2482         }
2483
2484         /* Probe Response Timeout value */
2485         /* FIXME: Default to 0, has to be set by ioctl probably... :-/ */
2486         bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0074, 0x0000);
2487
2488         /* Initially set the wireless operation mode. */
2489         bcm43xx_set_iwmode(bcm, bcm->ieee->iw_mode);
2490
2491         if (bcm->current_core->rev < 3) {
2492                 bcm43xx_write16(bcm, 0x060E, 0x0000);
2493                 bcm43xx_write16(bcm, 0x0610, 0x8000);
2494                 bcm43xx_write16(bcm, 0x0604, 0x0000);
2495                 bcm43xx_write16(bcm, 0x0606, 0x0200);
2496         } else {
2497                 bcm43xx_write32(bcm, 0x0188, 0x80000000);
2498                 bcm43xx_write32(bcm, 0x018C, 0x02000000);
2499         }
2500         bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, 0x00004000);
2501         bcm43xx_write32(bcm, BCM43xx_MMIO_DMA0_IRQ_MASK, 0x0001DC00);
2502         bcm43xx_write32(bcm, BCM43xx_MMIO_DMA1_IRQ_MASK, 0x0000DC00);
2503         bcm43xx_write32(bcm, BCM43xx_MMIO_DMA2_IRQ_MASK, 0x0000DC00);
2504         bcm43xx_write32(bcm, BCM43xx_MMIO_DMA3_IRQ_MASK, 0x0001DC00);
2505         bcm43xx_write32(bcm, BCM43xx_MMIO_DMA4_IRQ_MASK, 0x0000DC00);
2506         bcm43xx_write32(bcm, BCM43xx_MMIO_DMA5_IRQ_MASK, 0x0000DC00);
2507
2508         value32 = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
2509         value32 |= 0x00100000;
2510         bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, value32);
2511
2512         bcm43xx_write16(bcm, BCM43xx_MMIO_POWERUP_DELAY, bcm43xx_pctl_powerup_delay(bcm));
2513
2514         assert(err == 0);
2515         dprintk(KERN_INFO PFX "Chip initialized\n");
2516 out:
2517         return err;
2518
2519 err_radio_off:
2520         bcm43xx_radio_turn_off(bcm);
2521 err_gpio_cleanup:
2522         bcm43xx_gpio_cleanup(bcm);
2523 err_release_fw:
2524         bcm43xx_release_firmware(bcm, 1);
2525         goto out;
2526 }
2527         
2528 /* Validate chip access
2529  * http://bcm-specs.sipsolutions.net/ValidateChipAccess */
2530 static int bcm43xx_validate_chip(struct bcm43xx_private *bcm)
2531 {
2532         u32 value;
2533         u32 shm_backup;
2534
2535         shm_backup = bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED, 0x0000);
2536         bcm43xx_shm_write32(bcm, BCM43xx_SHM_SHARED, 0x0000, 0xAA5555AA);
2537         if (bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED, 0x0000) != 0xAA5555AA)
2538                 goto error;
2539         bcm43xx_shm_write32(bcm, BCM43xx_SHM_SHARED, 0x0000, 0x55AAAA55);
2540         if (bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED, 0x0000) != 0x55AAAA55)
2541                 goto error;
2542         bcm43xx_shm_write32(bcm, BCM43xx_SHM_SHARED, 0x0000, shm_backup);
2543
2544         value = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
2545         if ((value | 0x80000000) != 0x80000400)
2546                 goto error;
2547
2548         value = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON);
2549         if (value != 0x00000000)
2550                 goto error;
2551
2552         return 0;
2553 error:
2554         printk(KERN_ERR PFX "Failed to validate the chipaccess\n");
2555         return -ENODEV;
2556 }
2557
2558 static void bcm43xx_init_struct_phyinfo(struct bcm43xx_phyinfo *phy)
2559 {
2560         /* Initialize a "phyinfo" structure. The structure is already
2561          * zeroed out.
2562          * This is called on insmod time to initialize members.
2563          */
2564         phy->savedpctlreg = 0xFFFF;
2565         spin_lock_init(&phy->lock);
2566 }
2567
2568 static void bcm43xx_init_struct_radioinfo(struct bcm43xx_radioinfo *radio)
2569 {
2570         /* Initialize a "radioinfo" structure. The structure is already
2571          * zeroed out.
2572          * This is called on insmod time to initialize members.
2573          */
2574         radio->interfmode = BCM43xx_RADIO_INTERFMODE_NONE;
2575         radio->channel = 0xFF;
2576         radio->initial_channel = 0xFF;
2577 }
2578
2579 static int bcm43xx_probe_cores(struct bcm43xx_private *bcm)
2580 {
2581         int err, i;
2582         int current_core;
2583         u32 core_vendor, core_id, core_rev;
2584         u32 sb_id_hi, chip_id_32 = 0;
2585         u16 pci_device, chip_id_16;
2586         u8 core_count;
2587
2588         memset(&bcm->core_chipcommon, 0, sizeof(struct bcm43xx_coreinfo));
2589         memset(&bcm->core_pci, 0, sizeof(struct bcm43xx_coreinfo));
2590         memset(&bcm->core_80211, 0, sizeof(struct bcm43xx_coreinfo)
2591                                     * BCM43xx_MAX_80211_CORES);
2592         memset(&bcm->core_80211_ext, 0, sizeof(struct bcm43xx_coreinfo_80211)
2593                                         * BCM43xx_MAX_80211_CORES);
2594         bcm->nr_80211_available = 0;
2595         bcm->current_core = NULL;
2596         bcm->active_80211_core = NULL;
2597
2598         /* map core 0 */
2599         err = _switch_core(bcm, 0);
2600         if (err)
2601                 goto out;
2602
2603         /* fetch sb_id_hi from core information registers */
2604         sb_id_hi = bcm43xx_read32(bcm, BCM43xx_CIR_SB_ID_HI);
2605
2606         core_id = (sb_id_hi & 0x8FF0) >> 4;
2607         core_rev = (sb_id_hi & 0x7000) >> 8;
2608         core_rev |= (sb_id_hi & 0xF);
2609         core_vendor = (sb_id_hi & 0xFFFF0000) >> 16;
2610
2611         /* if present, chipcommon is always core 0; read the chipid from it */
2612         if (core_id == BCM43xx_COREID_CHIPCOMMON) {
2613                 chip_id_32 = bcm43xx_read32(bcm, 0);
2614                 chip_id_16 = chip_id_32 & 0xFFFF;
2615                 bcm->core_chipcommon.available = 1;
2616                 bcm->core_chipcommon.id = core_id;
2617                 bcm->core_chipcommon.rev = core_rev;
2618                 bcm->core_chipcommon.index = 0;
2619                 /* While we are at it, also read the capabilities. */
2620                 bcm->chipcommon_capabilities = bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_CAPABILITIES);
2621         } else {
2622                 /* without a chipCommon, use a hard coded table. */
2623                 pci_device = bcm->pci_dev->device;
2624                 if (pci_device == 0x4301)
2625                         chip_id_16 = 0x4301;
2626                 else if ((pci_device >= 0x4305) && (pci_device <= 0x4307))
2627                         chip_id_16 = 0x4307;
2628                 else if ((pci_device >= 0x4402) && (pci_device <= 0x4403))
2629                         chip_id_16 = 0x4402;
2630                 else if ((pci_device >= 0x4610) && (pci_device <= 0x4615))
2631                         chip_id_16 = 0x4610;
2632                 else if ((pci_device >= 0x4710) && (pci_device <= 0x4715))
2633                         chip_id_16 = 0x4710;
2634 #ifdef CONFIG_BCM947XX
2635                 else if ((pci_device >= 0x4320) && (pci_device <= 0x4325))
2636                         chip_id_16 = 0x4309;
2637 #endif
2638                 else {
2639                         printk(KERN_ERR PFX "Could not determine Chip ID\n");
2640                         return -ENODEV;
2641                 }
2642         }
2643
2644         /* ChipCommon with Core Rev >=4 encodes number of cores,
2645          * otherwise consult hardcoded table */
2646         if ((core_id == BCM43xx_COREID_CHIPCOMMON) && (core_rev >= 4)) {
2647                 core_count = (chip_id_32 & 0x0F000000) >> 24;
2648         } else {
2649                 switch (chip_id_16) {
2650                         case 0x4610:
2651                         case 0x4704:
2652                         case 0x4710:
2653                                 core_count = 9;
2654                                 break;
2655                         case 0x4310:
2656                                 core_count = 8;
2657                                 break;
2658                         case 0x5365:
2659                                 core_count = 7;
2660                                 break;
2661                         case 0x4306:
2662                                 core_count = 6;
2663                                 break;
2664                         case 0x4301:
2665                         case 0x4307:
2666                                 core_count = 5;
2667                                 break;
2668                         case 0x4402:
2669                                 core_count = 3;
2670                                 break;
2671                         default:
2672                                 /* SOL if we get here */
2673                                 assert(0);
2674                                 core_count = 1;
2675                 }
2676         }
2677
2678         bcm->chip_id = chip_id_16;
2679         bcm->chip_rev = (chip_id_32 & 0x000F0000) >> 16;
2680         bcm->chip_package = (chip_id_32 & 0x00F00000) >> 20;
2681
2682         dprintk(KERN_INFO PFX "Chip ID 0x%x, rev 0x%x\n",
2683                 bcm->chip_id, bcm->chip_rev);
2684         dprintk(KERN_INFO PFX "Number of cores: %d\n", core_count);
2685         if (bcm->core_chipcommon.available) {
2686                 dprintk(KERN_INFO PFX "Core 0: ID 0x%x, rev 0x%x, vendor 0x%x\n",
2687                         core_id, core_rev, core_vendor);
2688                 current_core = 1;
2689         } else
2690                 current_core = 0;
2691         for ( ; current_core < core_count; current_core++) {
2692                 struct bcm43xx_coreinfo *core;
2693                 struct bcm43xx_coreinfo_80211 *ext_80211;
2694
2695                 err = _switch_core(bcm, current_core);
2696                 if (err)
2697                         goto out;
2698                 /* Gather information */
2699                 /* fetch sb_id_hi from core information registers */
2700                 sb_id_hi = bcm43xx_read32(bcm, BCM43xx_CIR_SB_ID_HI);
2701
2702                 /* extract core_id, core_rev, core_vendor */
2703                 core_id = (sb_id_hi & 0x8FF0) >> 4;
2704                 core_rev = ((sb_id_hi & 0xF) | ((sb_id_hi & 0x7000) >> 8));
2705                 core_vendor = (sb_id_hi & 0xFFFF0000) >> 16;
2706
2707                 dprintk(KERN_INFO PFX "Core %d: ID 0x%x, rev 0x%x, vendor 0x%x\n",
2708                         current_core, core_id, core_rev, core_vendor);
2709
2710                 core = NULL;
2711                 switch (core_id) {
2712                 case BCM43xx_COREID_PCI:
2713                 case BCM43xx_COREID_PCIE:
2714                         core = &bcm->core_pci;
2715                         if (core->available) {
2716                                 printk(KERN_WARNING PFX "Multiple PCI cores found.\n");
2717                                 continue;
2718                         }
2719                         break;
2720                 case BCM43xx_COREID_80211:
2721                         for (i = 0; i < BCM43xx_MAX_80211_CORES; i++) {
2722                                 core = &(bcm->core_80211[i]);
2723                                 ext_80211 = &(bcm->core_80211_ext[i]);
2724                                 if (!core->available)
2725                                         break;
2726                                 core = NULL;
2727                         }
2728                         if (!core) {
2729                                 printk(KERN_WARNING PFX "More than %d cores of type 802.11 found.\n",
2730                                        BCM43xx_MAX_80211_CORES);
2731                                 continue;
2732                         }
2733                         if (i != 0) {
2734                                 /* More than one 80211 core is only supported
2735                                  * by special chips.
2736                                  * There are chips with two 80211 cores, but with
2737                                  * dangling pins on the second core. Be careful
2738                                  * and ignore these cores here.
2739                                  */
2740                                 if (bcm->pci_dev->device != 0x4324) {
2741                                         dprintk(KERN_INFO PFX "Ignoring additional 802.11 core.\n");
2742                                         continue;
2743                                 }
2744                         }
2745                         switch (core_rev) {
2746                         case 2:
2747                         case 4:
2748                         case 5:
2749                         case 6:
2750                         case 7:
2751                         case 9:
2752                         case 10:
2753                                 break;
2754                         default:
2755                                 printk(KERN_WARNING PFX
2756                                        "Unsupported 80211 core revision %u\n",
2757                                        core_rev);
2758                         }
2759                         bcm->nr_80211_available++;
2760                         core->priv = ext_80211;
2761                         bcm43xx_init_struct_phyinfo(&ext_80211->phy);
2762                         bcm43xx_init_struct_radioinfo(&ext_80211->radio);
2763                         break;
2764                 case BCM43xx_COREID_CHIPCOMMON:
2765                         printk(KERN_WARNING PFX "Multiple CHIPCOMMON cores found.\n");
2766                         break;
2767                 }
2768                 if (core) {
2769                         core->available = 1;
2770                         core->id = core_id;
2771                         core->rev = core_rev;
2772                         core->index = current_core;
2773                 }
2774         }
2775
2776         if (!bcm->core_80211[0].available) {
2777                 printk(KERN_ERR PFX "Error: No 80211 core found!\n");
2778                 err = -ENODEV;
2779                 goto out;
2780         }
2781
2782         err = bcm43xx_switch_core(bcm, &bcm->core_80211[0]);
2783
2784         assert(err == 0);
2785 out:
2786         return err;
2787 }
2788
2789 static void bcm43xx_gen_bssid(struct bcm43xx_private *bcm)
2790 {
2791         const u8 *mac = (const u8*)(bcm->net_dev->dev_addr);
2792         u8 *bssid = bcm->ieee->bssid;
2793
2794         switch (bcm->ieee->iw_mode) {
2795         case IW_MODE_ADHOC:
2796                 random_ether_addr(bssid);
2797                 break;
2798         case IW_MODE_MASTER:
2799         case IW_MODE_INFRA:
2800         case IW_MODE_REPEAT:
2801         case IW_MODE_SECOND:
2802         case IW_MODE_MONITOR:
2803                 memcpy(bssid, mac, ETH_ALEN);
2804                 break;
2805         default:
2806                 assert(0);
2807         }
2808 }
2809
2810 static void bcm43xx_rate_memory_write(struct bcm43xx_private *bcm,
2811                                       u16 rate,
2812                                       int is_ofdm)
2813 {
2814         u16 offset;
2815
2816         if (is_ofdm) {
2817                 offset = 0x480;
2818                 offset += (bcm43xx_plcp_get_ratecode_ofdm(rate) & 0x000F) * 2;
2819         }
2820         else {
2821                 offset = 0x4C0;
2822                 offset += (bcm43xx_plcp_get_ratecode_cck(rate) & 0x000F) * 2;
2823         }
2824         bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, offset + 0x20,
2825                             bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED, offset));
2826 }
2827
2828 static void bcm43xx_rate_memory_init(struct bcm43xx_private *bcm)
2829 {
2830         switch (bcm43xx_current_phy(bcm)->type) {
2831         case BCM43xx_PHYTYPE_A:
2832         case BCM43xx_PHYTYPE_G:
2833                 bcm43xx_rate_memory_write(bcm, IEEE80211_OFDM_RATE_6MB, 1);
2834                 bcm43xx_rate_memory_write(bcm, IEEE80211_OFDM_RATE_12MB, 1);
2835                 bcm43xx_rate_memory_write(bcm, IEEE80211_OFDM_RATE_18MB, 1);
2836                 bcm43xx_rate_memory_write(bcm, IEEE80211_OFDM_RATE_24MB, 1);
2837                 bcm43xx_rate_memory_write(bcm, IEEE80211_OFDM_RATE_36MB, 1);
2838                 bcm43xx_rate_memory_write(bcm, IEEE80211_OFDM_RATE_48MB, 1);
2839                 bcm43xx_rate_memory_write(bcm, IEEE80211_OFDM_RATE_54MB, 1);
2840         case BCM43xx_PHYTYPE_B:
2841                 bcm43xx_rate_memory_write(bcm, IEEE80211_CCK_RATE_1MB, 0);
2842                 bcm43xx_rate_memory_write(bcm, IEEE80211_CCK_RATE_2MB, 0);
2843                 bcm43xx_rate_memory_write(bcm, IEEE80211_CCK_RATE_5MB, 0);
2844                 bcm43xx_rate_memory_write(bcm, IEEE80211_CCK_RATE_11MB, 0);
2845                 break;
2846         default:
2847                 assert(0);
2848         }
2849 }
2850
2851 static void bcm43xx_wireless_core_cleanup(struct bcm43xx_private *bcm)
2852 {
2853         bcm43xx_chip_cleanup(bcm);
2854         bcm43xx_pio_free(bcm);
2855         bcm43xx_dma_free(bcm);
2856
2857         bcm->current_core->initialized = 0;
2858 }
2859
2860 /* http://bcm-specs.sipsolutions.net/80211Init */
2861 static int bcm43xx_wireless_core_init(struct bcm43xx_private *bcm,
2862                                       int active_wlcore)
2863 {
2864         struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
2865         struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
2866         u32 ucodeflags;
2867         int err;
2868         u32 sbimconfiglow;
2869         u8 limit;
2870
2871         if (bcm->core_pci.rev <= 5 && bcm->core_pci.id != BCM43xx_COREID_PCIE) {
2872                 sbimconfiglow = bcm43xx_read32(bcm, BCM43xx_CIR_SBIMCONFIGLOW);
2873                 sbimconfiglow &= ~ BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_MASK;
2874                 sbimconfiglow &= ~ BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_MASK;
2875                 if (bcm->bustype == BCM43xx_BUSTYPE_PCI)
2876                         sbimconfiglow |= 0x32;
2877                 else
2878                         sbimconfiglow |= 0x53;
2879                 bcm43xx_write32(bcm, BCM43xx_CIR_SBIMCONFIGLOW, sbimconfiglow);
2880         }
2881
2882         bcm43xx_phy_calibrate(bcm);
2883         err = bcm43xx_chip_init(bcm);
2884         if (err)
2885                 goto out;
2886
2887         bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0016, bcm->current_core->rev);
2888         ucodeflags = bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED, BCM43xx_UCODEFLAGS_OFFSET);
2889
2890         if (0 /*FIXME: which condition has to be used here? */)
2891                 ucodeflags |= 0x00000010;
2892
2893         /* HW decryption needs to be set now */
2894         ucodeflags |= 0x40000000;
2895         
2896         if (phy->type == BCM43xx_PHYTYPE_G) {
2897                 ucodeflags |= BCM43xx_UCODEFLAG_UNKBGPHY;
2898                 if (phy->rev == 1)
2899                         ucodeflags |= BCM43xx_UCODEFLAG_UNKGPHY;
2900                 if (bcm->sprom.boardflags & BCM43xx_BFL_PACTRL)
2901                         ucodeflags |= BCM43xx_UCODEFLAG_UNKPACTRL;
2902         } else if (phy->type == BCM43xx_PHYTYPE_B) {
2903                 ucodeflags |= BCM43xx_UCODEFLAG_UNKBGPHY;
2904                 if (phy->rev >= 2 && radio->version == 0x2050)
2905                         ucodeflags &= ~BCM43xx_UCODEFLAG_UNKGPHY;
2906         }
2907
2908         if (ucodeflags != bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED,
2909                                              BCM43xx_UCODEFLAGS_OFFSET)) {
2910                 bcm43xx_shm_write32(bcm, BCM43xx_SHM_SHARED,
2911                                     BCM43xx_UCODEFLAGS_OFFSET, ucodeflags);
2912         }
2913
2914         /* Short/Long Retry Limit.
2915          * The retry-limit is a 4-bit counter. Enforce this to avoid overflowing
2916          * the chip-internal counter.
2917          */
2918         limit = limit_value(modparam_short_retry, 0, 0xF);
2919         bcm43xx_shm_write32(bcm, BCM43xx_SHM_WIRELESS, 0x0006, limit);
2920         limit = limit_value(modparam_long_retry, 0, 0xF);
2921         bcm43xx_shm_write32(bcm, BCM43xx_SHM_WIRELESS, 0x0007, limit);
2922
2923         bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0044, 3);
2924         bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0046, 2);
2925
2926         bcm43xx_rate_memory_init(bcm);
2927
2928         /* Minimum Contention Window */
2929         if (phy->type == BCM43xx_PHYTYPE_B)
2930                 bcm43xx_shm_write32(bcm, BCM43xx_SHM_WIRELESS, 0x0003, 0x0000001f);
2931         else
2932                 bcm43xx_shm_write32(bcm, BCM43xx_SHM_WIRELESS, 0x0003, 0x0000000f);
2933         /* Maximum Contention Window */
2934         bcm43xx_shm_write32(bcm, BCM43xx_SHM_WIRELESS, 0x0004, 0x000003ff);
2935
2936         bcm43xx_gen_bssid(bcm);
2937         bcm43xx_write_mac_bssid_templates(bcm);
2938
2939         if (bcm->current_core->rev >= 5)
2940                 bcm43xx_write16(bcm, 0x043C, 0x000C);
2941
2942         if (active_wlcore) {
2943                 if (bcm43xx_using_pio(bcm)) {
2944                         err = bcm43xx_pio_init(bcm);
2945                 } else {
2946                         err = bcm43xx_dma_init(bcm);
2947                         if (err == -ENOSYS)
2948                                 err = bcm43xx_pio_init(bcm);
2949                 }
2950                 if (err)
2951                         goto err_chip_cleanup;
2952         }
2953         bcm43xx_write16(bcm, 0x0612, 0x0050);
2954         bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0416, 0x0050);
2955         bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0414, 0x01F4);
2956
2957         if (active_wlcore) {
2958                 if (radio->initial_channel != 0xFF)
2959                         bcm43xx_radio_selectchannel(bcm, radio->initial_channel, 0);
2960         }
2961
2962         /* Don't enable MAC/IRQ here, as it will race with the IRQ handler.
2963          * We enable it later.
2964          */
2965         bcm->current_core->initialized = 1;
2966 out:
2967         return err;
2968
2969 err_chip_cleanup:
2970         bcm43xx_chip_cleanup(bcm);
2971         goto out;
2972 }
2973
2974 static int bcm43xx_chipset_attach(struct bcm43xx_private *bcm)
2975 {
2976         int err;
2977         u16 pci_status;
2978
2979         err = bcm43xx_pctl_set_crystal(bcm, 1);
2980         if (err)
2981                 goto out;
2982         err = bcm43xx_pci_read_config16(bcm, PCI_STATUS, &pci_status);
2983         if (err)
2984                 goto out;
2985         err = bcm43xx_pci_write_config16(bcm, PCI_STATUS, pci_status & ~PCI_STATUS_SIG_TARGET_ABORT);
2986
2987 out:
2988         return err;
2989 }
2990
2991 static void bcm43xx_chipset_detach(struct bcm43xx_private *bcm)
2992 {
2993         bcm43xx_pctl_set_clock(bcm, BCM43xx_PCTL_CLK_SLOW);
2994         bcm43xx_pctl_set_crystal(bcm, 0);
2995 }
2996
2997 static void bcm43xx_pcicore_broadcast_value(struct bcm43xx_private *bcm,
2998                                             u32 address,
2999                                             u32 data)
3000 {
3001         bcm43xx_write32(bcm, BCM43xx_PCICORE_BCAST_ADDR, address);
3002         bcm43xx_write32(bcm, BCM43xx_PCICORE_BCAST_DATA, data);
3003 }
3004
3005 static int bcm43xx_pcicore_commit_settings(struct bcm43xx_private *bcm)
3006 {
3007         int err = 0;
3008
3009         bcm->irq_savedstate = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
3010
3011         if (bcm->core_chipcommon.available) {
3012                 err = bcm43xx_switch_core(bcm, &bcm->core_chipcommon);
3013                 if (err)
3014                         goto out;
3015
3016                 bcm43xx_pcicore_broadcast_value(bcm, 0xfd8, 0x00000000);
3017
3018                 /* this function is always called when a PCI core is mapped */
3019                 err = bcm43xx_switch_core(bcm, &bcm->core_pci);
3020                 if (err)
3021                         goto out;
3022         } else
3023                 bcm43xx_pcicore_broadcast_value(bcm, 0xfd8, 0x00000000);
3024
3025         bcm43xx_interrupt_enable(bcm, bcm->irq_savedstate);
3026
3027 out:
3028         return err;
3029 }
3030
3031 static u32 bcm43xx_pcie_reg_read(struct bcm43xx_private *bcm, u32 address)
3032 {
3033         bcm43xx_write32(bcm, BCM43xx_PCIECORE_REG_ADDR, address);
3034         return bcm43xx_read32(bcm, BCM43xx_PCIECORE_REG_DATA);
3035 }
3036
3037 static void bcm43xx_pcie_reg_write(struct bcm43xx_private *bcm, u32 address,
3038                                     u32 data)
3039 {
3040         bcm43xx_write32(bcm, BCM43xx_PCIECORE_REG_ADDR, address);
3041         bcm43xx_write32(bcm, BCM43xx_PCIECORE_REG_DATA, data);
3042 }
3043
3044 static void bcm43xx_pcie_mdio_write(struct bcm43xx_private *bcm, u8 dev, u8 reg,
3045                                     u16 data)
3046 {
3047         int i;
3048
3049         bcm43xx_write32(bcm, BCM43xx_PCIECORE_MDIO_CTL, 0x0082);
3050         bcm43xx_write32(bcm, BCM43xx_PCIECORE_MDIO_DATA, BCM43xx_PCIE_MDIO_ST |
3051                         BCM43xx_PCIE_MDIO_WT | (dev << BCM43xx_PCIE_MDIO_DEV) |
3052                         (reg << BCM43xx_PCIE_MDIO_REG) | BCM43xx_PCIE_MDIO_TA |
3053                         data);
3054         udelay(10);
3055
3056         for (i = 0; i < 10; i++) {
3057                 if (bcm43xx_read32(bcm, BCM43xx_PCIECORE_MDIO_CTL) &
3058                     BCM43xx_PCIE_MDIO_TC)
3059                         break;
3060                 msleep(1);
3061         }
3062         bcm43xx_write32(bcm, BCM43xx_PCIECORE_MDIO_CTL, 0);
3063 }
3064
3065 /* Make an I/O Core usable. "core_mask" is the bitmask of the cores to enable.
3066  * To enable core 0, pass a core_mask of 1<<0
3067  */
3068 static int bcm43xx_setup_backplane_pci_connection(struct bcm43xx_private *bcm,
3069                                                   u32 core_mask)
3070 {
3071         u32 backplane_flag_nr;
3072         u32 value;
3073         struct bcm43xx_coreinfo *old_core;
3074         int err = 0;
3075
3076         value = bcm43xx_read32(bcm, BCM43xx_CIR_SBTPSFLAG);
3077         backplane_flag_nr = value & BCM43xx_BACKPLANE_FLAG_NR_MASK;
3078
3079         old_core = bcm->current_core;
3080         err = bcm43xx_switch_core(bcm, &bcm->core_pci);
3081         if (err)
3082                 goto out;
3083
3084         if (bcm->current_core->rev < 6 &&
3085                 bcm->current_core->id == BCM43xx_COREID_PCI) {
3086                 value = bcm43xx_read32(bcm, BCM43xx_CIR_SBINTVEC);
3087                 value |= (1 << backplane_flag_nr);
3088                 bcm43xx_write32(bcm, BCM43xx_CIR_SBINTVEC, value);
3089         } else {
3090                 err = bcm43xx_pci_read_config32(bcm, BCM43xx_PCICFG_ICR, &value);
3091                 if (err) {
3092                         printk(KERN_ERR PFX "Error: ICR setup failure!\n");
3093                         goto out_switch_back;
3094                 }
3095                 value |= core_mask << 8;
3096                 err = bcm43xx_pci_write_config32(bcm, BCM43xx_PCICFG_ICR, value);
3097                 if (err) {
3098                         printk(KERN_ERR PFX "Error: ICR setup failure!\n");
3099                         goto out_switch_back;
3100                 }
3101         }
3102
3103         if (bcm->current_core->id == BCM43xx_COREID_PCI) {
3104                 value = bcm43xx_read32(bcm, BCM43xx_PCICORE_SBTOPCI2);
3105                 value |= BCM43xx_SBTOPCI2_PREFETCH | BCM43xx_SBTOPCI2_BURST;
3106                 bcm43xx_write32(bcm, BCM43xx_PCICORE_SBTOPCI2, value);
3107
3108                 if (bcm->current_core->rev < 5) {
3109                         value = bcm43xx_read32(bcm, BCM43xx_CIR_SBIMCONFIGLOW);
3110                         value |= (2 << BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_SHIFT)
3111                                  & BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_MASK;
3112                         value |= (3 << BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_SHIFT)
3113                                  & BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_MASK;
3114                         bcm43xx_write32(bcm, BCM43xx_CIR_SBIMCONFIGLOW, value);
3115                         err = bcm43xx_pcicore_commit_settings(bcm);
3116                         assert(err == 0);
3117                 } else if (bcm->current_core->rev >= 11) {
3118                         value = bcm43xx_read32(bcm, BCM43xx_PCICORE_SBTOPCI2);
3119                         value |= BCM43xx_SBTOPCI2_MEMREAD_MULTI;
3120                         bcm43xx_write32(bcm, BCM43xx_PCICORE_SBTOPCI2, value);
3121                 }
3122         } else {
3123                 if (bcm->current_core->rev == 0 || bcm->current_core->rev == 1) {
3124                         value = bcm43xx_pcie_reg_read(bcm, BCM43xx_PCIE_TLP_WORKAROUND);
3125                         value |= 0x8;
3126                         bcm43xx_pcie_reg_write(bcm, BCM43xx_PCIE_TLP_WORKAROUND,
3127                                                value);
3128                 }
3129                 if (bcm->current_core->rev == 0) {
3130                         bcm43xx_pcie_mdio_write(bcm, BCM43xx_MDIO_SERDES_RX,
3131                                                 BCM43xx_SERDES_RXTIMER, 0x8128);
3132                         bcm43xx_pcie_mdio_write(bcm, BCM43xx_MDIO_SERDES_RX,
3133                                                 BCM43xx_SERDES_CDR, 0x0100);
3134                         bcm43xx_pcie_mdio_write(bcm, BCM43xx_MDIO_SERDES_RX,
3135                                                 BCM43xx_SERDES_CDR_BW, 0x1466);
3136                 } else if (bcm->current_core->rev == 1) {
3137                         value = bcm43xx_pcie_reg_read(bcm, BCM43xx_PCIE_DLLP_LINKCTL);
3138                         value |= 0x40;
3139                         bcm43xx_pcie_reg_write(bcm, BCM43xx_PCIE_DLLP_LINKCTL,
3140                                                value);
3141                 }
3142         }
3143 out_switch_back:
3144         err = bcm43xx_switch_core(bcm, old_core);
3145 out:
3146         return err;
3147 }
3148
3149 static void bcm43xx_periodic_every120sec(struct bcm43xx_private *bcm)
3150 {
3151         struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
3152
3153         if (phy->type != BCM43xx_PHYTYPE_G || phy->rev < 2)
3154                 return;
3155
3156         bcm43xx_mac_suspend(bcm);
3157         bcm43xx_phy_lo_g_measure(bcm);
3158         bcm43xx_mac_enable(bcm);
3159 }
3160
3161 static void bcm43xx_periodic_every60sec(struct bcm43xx_private *bcm)
3162 {
3163         bcm43xx_phy_lo_mark_all_unused(bcm);
3164         if (bcm->sprom.boardflags & BCM43xx_BFL_RSSI) {
3165                 bcm43xx_mac_suspend(bcm);
3166                 bcm43xx_calc_nrssi_slope(bcm);
3167                 bcm43xx_mac_enable(bcm);
3168         }
3169 }
3170
3171 static void bcm43xx_periodic_every30sec(struct bcm43xx_private *bcm)
3172 {
3173         /* Update device statistics. */
3174         bcm43xx_calculate_link_quality(bcm);
3175 }
3176
3177 static void bcm43xx_periodic_every15sec(struct bcm43xx_private *bcm)
3178 {
3179         bcm43xx_phy_xmitpower(bcm); //FIXME: unless scanning?
3180         //TODO for APHY (temperature?)
3181 }
3182
3183 static void bcm43xx_periodic_every1sec(struct bcm43xx_private *bcm)
3184 {
3185         struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
3186         struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
3187         int radio_hw_enable;
3188
3189         /* check if radio hardware enabled status changed */
3190         radio_hw_enable = bcm43xx_is_hw_radio_enabled(bcm);
3191         if (unlikely(bcm->radio_hw_enable != radio_hw_enable)) {
3192                 bcm->radio_hw_enable = radio_hw_enable;
3193                 dprintk(KERN_INFO PFX "Radio hardware status changed to %s\n",
3194                        (radio_hw_enable == 0) ? "disabled" : "enabled");
3195                 bcm43xx_leds_update(bcm, 0);
3196         }
3197         if (phy->type == BCM43xx_PHYTYPE_G) {
3198                 //TODO: update_aci_moving_average
3199                 if (radio->aci_enable && radio->aci_wlan_automatic) {
3200                         bcm43xx_mac_suspend(bcm);
3201                         if (!radio->aci_enable && 1 /*TODO: not scanning? */) {
3202                                 if (0 /*TODO: bunch of conditions*/) {
3203                                         bcm43xx_radio_set_interference_mitigation(bcm,
3204                                                                                   BCM43xx_RADIO_INTERFMODE_MANUALWLAN);
3205                                 }
3206                         } else if (1/*TODO*/) {
3207                                 /*
3208                                 if ((aci_average > 1000) && !(bcm43xx_radio_aci_scan(bcm))) {
3209                                         bcm43xx_radio_set_interference_mitigation(bcm,
3210                                                                                   BCM43xx_RADIO_INTERFMODE_NONE);
3211                                 }
3212                                 */
3213                         }
3214                         bcm43xx_mac_enable(bcm);
3215                 } else if (radio->interfmode == BCM43xx_RADIO_INTERFMODE_NONWLAN &&
3216                            phy->rev == 1) {
3217                         //TODO: implement rev1 workaround
3218                 }
3219         }
3220 }
3221
3222 static void do_periodic_work(struct bcm43xx_private *bcm)
3223 {
3224         if (bcm->periodic_state % 120 == 0)
3225                 bcm43xx_periodic_every120sec(bcm);
3226         if (bcm->periodic_state % 60 == 0)
3227                 bcm43xx_periodic_every60sec(bcm);
3228         if (bcm->periodic_state % 30 == 0)
3229                 bcm43xx_periodic_every30sec(bcm);
3230         if (bcm->periodic_state % 15 == 0)
3231                 bcm43xx_periodic_every15sec(bcm);
3232         bcm43xx_periodic_every1sec(bcm);
3233
3234         schedule_delayed_work(&bcm->periodic_work, HZ);
3235 }
3236
3237 static void bcm43xx_periodic_work_handler(struct work_struct *work)
3238 {
3239         struct bcm43xx_private *bcm =
3240                 container_of(work, struct bcm43xx_private, periodic_work.work);
3241         struct net_device *net_dev = bcm->net_dev;
3242         unsigned long flags;
3243         u32 savedirqs = 0;
3244         unsigned long orig_trans_start = 0;
3245
3246         mutex_lock(&bcm->mutex);
3247         if (unlikely(bcm->periodic_state % 60 == 0)) {
3248                 /* Periodic work will take a long time, so we want it to
3249                  * be preemtible.
3250                  */
3251
3252                 netif_tx_lock_bh(net_dev);
3253                 /* We must fake a started transmission here, as we are going to
3254                  * disable TX. If we wouldn't fake a TX, it would be possible to
3255                  * trigger the netdev watchdog, if the last real TX is already
3256                  * some time on the past (slightly less than 5secs)
3257                  */
3258                 orig_trans_start = net_dev->trans_start;
3259                 net_dev->trans_start = jiffies;
3260                 netif_stop_queue(net_dev);
3261                 netif_tx_unlock_bh(net_dev);
3262
3263                 spin_lock_irqsave(&bcm->irq_lock, flags);
3264                 bcm43xx_mac_suspend(bcm);
3265                 if (bcm43xx_using_pio(bcm))
3266                         bcm43xx_pio_freeze_txqueues(bcm);
3267                 savedirqs = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
3268                 spin_unlock_irqrestore(&bcm->irq_lock, flags);
3269                 bcm43xx_synchronize_irq(bcm);
3270         } else {
3271                 /* Periodic work should take short time, so we want low
3272                  * locking overhead.
3273                  */
3274                 spin_lock_irqsave(&bcm->irq_lock, flags);
3275         }
3276
3277         do_periodic_work(bcm);
3278
3279         if (unlikely(bcm->periodic_state % 60 == 0)) {
3280                 spin_lock_irqsave(&bcm->irq_lock, flags);
3281                 tasklet_enable(&bcm->isr_tasklet);
3282                 bcm43xx_interrupt_enable(bcm, savedirqs);
3283                 if (bcm43xx_using_pio(bcm))
3284                         bcm43xx_pio_thaw_txqueues(bcm);
3285                 bcm43xx_mac_enable(bcm);
3286                 netif_wake_queue(bcm->net_dev);
3287                 net_dev->trans_start = orig_trans_start;
3288         }
3289         mmiowb();
3290         bcm->periodic_state++;
3291         spin_unlock_irqrestore(&bcm->irq_lock, flags);
3292         mutex_unlock(&bcm->mutex);
3293 }
3294
3295 void bcm43xx_periodic_tasks_delete(struct bcm43xx_private *bcm)
3296 {
3297         cancel_rearming_delayed_work(&bcm->periodic_work);
3298 }
3299
3300 void bcm43xx_periodic_tasks_setup(struct bcm43xx_private *bcm)
3301 {
3302         struct delayed_work *work = &bcm->periodic_work;
3303
3304         assert(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED);
3305         INIT_DELAYED_WORK(work, bcm43xx_periodic_work_handler);
3306         schedule_delayed_work(work, 0);
3307 }
3308
3309 static void bcm43xx_security_init(struct bcm43xx_private *bcm)
3310 {
3311         bcm->security_offset = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED,
3312                                                   0x0056) * 2;
3313         bcm43xx_clear_keys(bcm);
3314 }
3315
3316 static int bcm43xx_rng_read(struct hwrng *rng, u32 *data)
3317 {
3318         struct bcm43xx_private *bcm = (struct bcm43xx_private *)rng->priv;
3319         unsigned long flags;
3320
3321         spin_lock_irqsave(&(bcm)->irq_lock, flags);
3322         *data = bcm43xx_read16(bcm, BCM43xx_MMIO_RNG);
3323         spin_unlock_irqrestore(&(bcm)->irq_lock, flags);
3324
3325         return (sizeof(u16));
3326 }
3327
3328 static void bcm43xx_rng_exit(struct bcm43xx_private *bcm)
3329 {
3330         hwrng_unregister(&bcm->rng);
3331 }
3332
3333 static int bcm43xx_rng_init(struct bcm43xx_private *bcm)
3334 {
3335         int err;
3336
3337         snprintf(bcm->rng_name, ARRAY_SIZE(bcm->rng_name),
3338                  "%s_%s", KBUILD_MODNAME, bcm->net_dev->name);
3339         bcm->rng.name = bcm->rng_name;
3340         bcm->rng.data_read = bcm43xx_rng_read;
3341         bcm->rng.priv = (unsigned long)bcm;
3342         err = hwrng_register(&bcm->rng);
3343         if (err)
3344                 printk(KERN_ERR PFX "RNG init failed (%d)\n", err);
3345
3346         return err;
3347 }
3348
3349 static int bcm43xx_shutdown_all_wireless_cores(struct bcm43xx_private *bcm)
3350 {
3351         int ret = 0;
3352         int i, err;
3353         struct bcm43xx_coreinfo *core;
3354
3355         bcm43xx_set_status(bcm, BCM43xx_STAT_SHUTTINGDOWN);
3356         for (i = 0; i < bcm->nr_80211_available; i++) {
3357                 core = &(bcm->core_80211[i]);
3358                 assert(core->available);
3359                 if (!core->initialized)
3360                         continue;
3361                 err = bcm43xx_switch_core(bcm, core);
3362                 if (err) {
3363                         dprintk(KERN_ERR PFX "shutdown_all_wireless_cores "
3364                                              "switch_core failed (%d)\n", err);
3365                         ret = err;
3366                         continue;
3367                 }
3368                 bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
3369                 bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); /* dummy read */
3370                 bcm43xx_wireless_core_cleanup(bcm);
3371                 if (core == bcm->active_80211_core)
3372                         bcm->active_80211_core = NULL;
3373         }
3374         free_irq(bcm->irq, bcm);
3375         bcm43xx_set_status(bcm, BCM43xx_STAT_UNINIT);
3376
3377         return ret;
3378 }
3379
3380 /* This is the opposite of bcm43xx_init_board() */
3381 static void bcm43xx_free_board(struct bcm43xx_private *bcm)
3382 {
3383         bcm43xx_rng_exit(bcm);
3384         bcm43xx_sysfs_unregister(bcm);
3385         bcm43xx_periodic_tasks_delete(bcm);
3386
3387         mutex_lock(&(bcm)->mutex);
3388         bcm43xx_shutdown_all_wireless_cores(bcm);
3389         bcm43xx_pctl_set_crystal(bcm, 0);
3390         mutex_unlock(&(bcm)->mutex);
3391 }
3392
3393 static void prepare_phydata_for_init(struct bcm43xx_phyinfo *phy)
3394 {
3395         phy->antenna_diversity = 0xFFFF;
3396         memset(phy->minlowsig, 0xFF, sizeof(phy->minlowsig));
3397         memset(phy->minlowsigpos, 0, sizeof(phy->minlowsigpos));
3398
3399         /* Flags */
3400         phy->calibrated = 0;
3401         phy->is_locked = 0;
3402
3403         if (phy->_lo_pairs) {
3404                 memset(phy->_lo_pairs, 0,
3405                        sizeof(struct bcm43xx_lopair) * BCM43xx_LO_COUNT);
3406         }
3407         memset(phy->loopback_gain, 0, sizeof(phy->loopback_gain));
3408 }
3409
3410 static void prepare_radiodata_for_init(struct bcm43xx_private *bcm,
3411                                        struct bcm43xx_radioinfo *radio)
3412 {
3413         int i;
3414
3415         /* Set default attenuation values. */
3416         radio->baseband_atten = bcm43xx_default_baseband_attenuation(bcm);
3417         radio->radio_atten = bcm43xx_default_radio_attenuation(bcm);
3418         radio->txctl1 = bcm43xx_default_txctl1(bcm);
3419         radio->txctl2 = 0xFFFF;
3420         radio->txpwr_offset = 0;
3421
3422         /* NRSSI */
3423         radio->nrssislope = 0;
3424         for (i = 0; i < ARRAY_SIZE(radio->nrssi); i++)
3425                 radio->nrssi[i] = -1000;
3426         for (i = 0; i < ARRAY_SIZE(radio->nrssi_lt); i++)
3427                 radio->nrssi_lt[i] = i;
3428
3429         radio->lofcal = 0xFFFF;
3430         radio->initval = 0xFFFF;
3431
3432         radio->aci_enable = 0;
3433         radio->aci_wlan_automatic = 0;
3434         radio->aci_hw_rssi = 0;
3435 }
3436
3437 static void prepare_priv_for_init(struct bcm43xx_private *bcm)
3438 {
3439         int i;
3440         struct bcm43xx_coreinfo *core;
3441         struct bcm43xx_coreinfo_80211 *wlext;
3442
3443         assert(!bcm->active_80211_core);
3444
3445         bcm43xx_set_status(bcm, BCM43xx_STAT_INITIALIZING);
3446
3447         /* Flags */
3448         bcm->was_initialized = 0;
3449         bcm->reg124_set_0x4 = 0;
3450
3451         /* Stats */
3452         memset(&bcm->stats, 0, sizeof(bcm->stats));
3453
3454         /* Wireless core data */
3455         for (i = 0; i < BCM43xx_MAX_80211_CORES; i++) {
3456                 core = &(bcm->core_80211[i]);
3457                 wlext = core->priv;
3458
3459                 if (!core->available)
3460                         continue;
3461                 assert(wlext == &(bcm->core_80211_ext[i]));
3462
3463                 prepare_phydata_for_init(&wlext->phy);
3464                 prepare_radiodata_for_init(bcm, &wlext->radio);
3465         }
3466
3467         /* IRQ related flags */
3468         bcm->irq_reason = 0;
3469         memset(bcm->dma_reason, 0, sizeof(bcm->dma_reason));
3470         bcm->irq_savedstate = BCM43xx_IRQ_INITIAL;
3471
3472         bcm->mac_suspended = 1;
3473
3474         /* Noise calculation context */
3475         memset(&bcm->noisecalc, 0, sizeof(bcm->noisecalc));
3476
3477         /* Periodic work context */
3478         bcm->periodic_state = 0;
3479 }
3480
3481 static int wireless_core_up(struct bcm43xx_private *bcm,
3482                             int active_wlcore)
3483 {
3484         int err;
3485
3486         if (!bcm43xx_core_enabled(bcm))
3487                 bcm43xx_wireless_core_reset(bcm, 1);
3488         if (!active_wlcore)
3489                 bcm43xx_wireless_core_mark_inactive(bcm);
3490         err = bcm43xx_wireless_core_init(bcm, active_wlcore);
3491         if (err)
3492                 goto out;
3493         if (!active_wlcore)
3494                 bcm43xx_radio_turn_off(bcm);
3495 out:
3496         return err;
3497 }
3498
3499 /* Select and enable the "to be used" wireless core.
3500  * Locking: bcm->mutex must be aquired before calling this.
3501  *          bcm->irq_lock must not be aquired.
3502  */
3503 int bcm43xx_select_wireless_core(struct bcm43xx_private *bcm,
3504                                  int phytype)
3505 {
3506         int i, err;
3507         struct bcm43xx_coreinfo *active_core = NULL;
3508         struct bcm43xx_coreinfo_80211 *active_wlext = NULL;
3509         struct bcm43xx_coreinfo *core;
3510         struct bcm43xx_coreinfo_80211 *wlext;
3511         int adjust_active_sbtmstatelow = 0;
3512
3513         might_sleep();
3514
3515         if (phytype < 0) {
3516                 /* If no phytype is requested, select the first core. */
3517                 assert(bcm->core_80211[0].available);
3518                 wlext = bcm->core_80211[0].priv;
3519                 phytype = wlext->phy.type;
3520         }
3521         /* Find the requested core. */
3522         for (i = 0; i < bcm->nr_80211_available; i++) {
3523                 core = &(bcm->core_80211[i]);
3524                 wlext = core->priv;
3525                 if (wlext->phy.type == phytype) {
3526                         active_core = core;
3527                         active_wlext = wlext;
3528                         break;
3529                 }
3530         }
3531         if (!active_core)
3532                 return -ESRCH; /* No such PHYTYPE on this board. */
3533
3534         if (bcm->active_80211_core) {
3535                 /* We already selected a wl core in the past.
3536                  * So first clean up everything.
3537                  */
3538                 dprintk(KERN_INFO PFX "select_wireless_core: cleanup\n");
3539                 ieee80211softmac_stop(bcm->net_dev);
3540                 bcm43xx_set_status(bcm, BCM43xx_STAT_INITIALIZED);
3541                 err = bcm43xx_disable_interrupts_sync(bcm);
3542                 assert(!err);
3543                 tasklet_enable(&bcm->isr_tasklet);
3544                 err = bcm43xx_shutdown_all_wireless_cores(bcm);
3545                 if (err)
3546                         goto error;
3547                 /* Ok, everything down, continue to re-initialize. */
3548                 bcm43xx_set_status(bcm, BCM43xx_STAT_INITIALIZING);
3549         }
3550
3551         /* Reset all data structures. */
3552         prepare_priv_for_init(bcm);
3553
3554         err = bcm43xx_pctl_set_clock(bcm, BCM43xx_PCTL_CLK_FAST);
3555         if (err)
3556                 goto error;
3557
3558         /* Mark all unused cores "inactive". */
3559         for (i = 0; i < bcm->nr_80211_available; i++) {
3560                 core = &(bcm->core_80211[i]);
3561                 wlext = core->priv;
3562
3563                 if (core == active_core)
3564                         continue;
3565                 err = bcm43xx_switch_core(bcm, core);
3566                 if (err) {
3567                         dprintk(KERN_ERR PFX "Could not switch to inactive "
3568                                              "802.11 core (%d)\n", err);
3569                         goto error;
3570                 }
3571                 err = wireless_core_up(bcm, 0);
3572                 if (err) {
3573                         dprintk(KERN_ERR PFX "core_up for inactive 802.11 core "
3574                                              "failed (%d)\n", err);
3575                         goto error;
3576                 }
3577                 adjust_active_sbtmstatelow = 1;
3578         }
3579
3580         /* Now initialize the active 802.11 core. */
3581         err = bcm43xx_switch_core(bcm, active_core);
3582         if (err) {
3583                 dprintk(KERN_ERR PFX "Could not switch to active "
3584                                      "802.11 core (%d)\n", err);
3585                 goto error;
3586         }
3587         if (adjust_active_sbtmstatelow &&
3588             active_wlext->phy.type == BCM43xx_PHYTYPE_G) {
3589                 u32 sbtmstatelow;
3590
3591                 sbtmstatelow = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
3592                 sbtmstatelow |= 0x20000000;
3593                 bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
3594         }
3595         err = wireless_core_up(bcm, 1);
3596         if (err) {
3597                 dprintk(KERN_ERR PFX "core_up for active 802.11 core "
3598                                      "failed (%d)\n", err);
3599                 goto error;
3600         }
3601         err = bcm43xx_pctl_set_clock(bcm, BCM43xx_PCTL_CLK_DYNAMIC);
3602         if (err)
3603                 goto error;
3604         bcm->active_80211_core = active_core;
3605
3606         bcm43xx_macfilter_clear(bcm, BCM43xx_MACFILTER_ASSOC);
3607         bcm43xx_macfilter_set(bcm, BCM43xx_MACFILTER_SELF, (u8 *)(bcm->net_dev->dev_addr));
3608         bcm43xx_security_init(bcm);
3609         drain_txstatus_queue(bcm);
3610         ieee80211softmac_start(bcm->net_dev);
3611
3612         /* Let's go! Be careful after enabling the IRQs.
3613          * Don't switch cores, for example.
3614          */
3615         bcm43xx_mac_enable(bcm);
3616         bcm43xx_set_status(bcm, BCM43xx_STAT_INITIALIZED);
3617         err = bcm43xx_initialize_irq(bcm);
3618         if (err)
3619                 goto error;
3620         bcm43xx_interrupt_enable(bcm, bcm->irq_savedstate);
3621
3622         dprintk(KERN_INFO PFX "Selected 802.11 core (phytype %d)\n",
3623                 active_wlext->phy.type);
3624
3625         return 0;
3626
3627 error:
3628         bcm43xx_set_status(bcm, BCM43xx_STAT_UNINIT);
3629         bcm43xx_pctl_set_clock(bcm, BCM43xx_PCTL_CLK_SLOW);
3630         return err;
3631 }
3632
3633 static int bcm43xx_init_board(struct bcm43xx_private *bcm)
3634 {
3635         int err;
3636
3637         mutex_lock(&(bcm)->mutex);
3638
3639         tasklet_enable(&bcm->isr_tasklet);
3640         err = bcm43xx_pctl_set_crystal(bcm, 1);
3641         if (err)
3642                 goto err_tasklet;
3643         err = bcm43xx_pctl_init(bcm);
3644         if (err)
3645                 goto err_crystal_off;
3646         err = bcm43xx_select_wireless_core(bcm, -1);
3647         if (err)
3648                 goto err_crystal_off;
3649         err = bcm43xx_sysfs_register(bcm);
3650         if (err)
3651                 goto err_wlshutdown;
3652         err = bcm43xx_rng_init(bcm);
3653         if (err)
3654                 goto err_sysfs_unreg;
3655         bcm43xx_periodic_tasks_setup(bcm);
3656
3657         /*FIXME: This should be handled by softmac instead. */
3658         schedule_delayed_work(&bcm->softmac->associnfo.work, 0);
3659
3660 out:
3661         mutex_unlock(&(bcm)->mutex);
3662
3663         return err;
3664
3665 err_sysfs_unreg:
3666         bcm43xx_sysfs_unregister(bcm);
3667 err_wlshutdown:
3668         bcm43xx_shutdown_all_wireless_cores(bcm);
3669 err_crystal_off:
3670         bcm43xx_pctl_set_crystal(bcm, 0);
3671 err_tasklet:
3672         tasklet_disable(&bcm->isr_tasklet);
3673         goto out;
3674 }
3675
3676 static void bcm43xx_detach_board(struct bcm43xx_private *bcm)
3677 {
3678         struct pci_dev *pci_dev = bcm->pci_dev;
3679         int i;
3680
3681         bcm43xx_chipset_detach(bcm);
3682         /* Do _not_ access the chip, after it is detached. */
3683         pci_iounmap(pci_dev, bcm->mmio_addr);
3684         pci_release_regions(pci_dev);
3685         pci_disable_device(pci_dev);
3686
3687         /* Free allocated structures/fields */
3688         for (i = 0; i < BCM43xx_MAX_80211_CORES; i++) {
3689                 kfree(bcm->core_80211_ext[i].phy._lo_pairs);
3690                 if (bcm->core_80211_ext[i].phy.dyn_tssi_tbl)
3691                         kfree(bcm->core_80211_ext[i].phy.tssi2dbm);
3692         }
3693 }       
3694
3695 static int bcm43xx_read_phyinfo(struct bcm43xx_private *bcm)
3696 {
3697         struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
3698         u16 value;
3699         u8 phy_version;
3700         u8 phy_type;
3701         u8 phy_rev;
3702         int phy_rev_ok = 1;
3703         void *p;
3704
3705         value = bcm43xx_read16(bcm, BCM43xx_MMIO_PHY_VER);
3706
3707         phy_version = (value & 0xF000) >> 12;
3708         phy_type = (value & 0x0F00) >> 8;
3709         phy_rev = (value & 0x000F);
3710
3711         dprintk(KERN_INFO PFX "Detected PHY: Version: %x, Type %x, Revision %x\n",
3712                 phy_version, phy_type, phy_rev);
3713
3714         switch (phy_type) {
3715         case BCM43xx_PHYTYPE_A:
3716                 if (phy_rev >= 4)
3717                         phy_rev_ok = 0;
3718                 /*FIXME: We need to switch the ieee->modulation, etc.. flags,
3719                  *       if we switch 80211 cores after init is done.
3720                  *       As we do not implement on the fly switching between
3721                  *       wireless cores, I will leave this as a future task.
3722                  */
3723                 bcm->ieee->modulation = IEEE80211_OFDM_MODULATION;
3724                 bcm->ieee->mode = IEEE_A;
3725                 bcm->ieee->freq_band = IEEE80211_52GHZ_BAND |
3726                                        IEEE80211_24GHZ_BAND;
3727                 break;
3728         case BCM43xx_PHYTYPE_B:
3729                 if (phy_rev != 2 && phy_rev != 4 && phy_rev != 6 && phy_rev != 7)
3730                         phy_rev_ok = 0;
3731                 bcm->ieee->modulation = IEEE80211_CCK_MODULATION;
3732                 bcm->ieee->mode = IEEE_B;
3733                 bcm->ieee->freq_band = IEEE80211_24GHZ_BAND;
3734                 break;
3735         case BCM43xx_PHYTYPE_G:
3736                 if (phy_rev > 8)
3737                         phy_rev_ok = 0;
3738                 bcm->ieee->modulation = IEEE80211_OFDM_MODULATION |
3739                                         IEEE80211_CCK_MODULATION;
3740                 bcm->ieee->mode = IEEE_G;
3741                 bcm->ieee->freq_band = IEEE80211_24GHZ_BAND;
3742                 break;
3743         default:
3744                 printk(KERN_ERR PFX "Error: Unknown PHY Type %x\n",
3745                        phy_type);
3746                 return -ENODEV;
3747         };
3748         bcm->ieee->perfect_rssi = RX_RSSI_MAX;
3749         bcm->ieee->worst_rssi = 0;
3750         if (!phy_rev_ok) {
3751                 printk(KERN_WARNING PFX "Invalid PHY Revision %x\n",
3752                        phy_rev);
3753         }
3754
3755         phy->version = phy_version;
3756         phy->type = phy_type;
3757         phy->rev = phy_rev;
3758         if ((phy_type == BCM43xx_PHYTYPE_B) || (phy_type == BCM43xx_PHYTYPE_G)) {
3759                 p = kzalloc(sizeof(struct bcm43xx_lopair) * BCM43xx_LO_COUNT,
3760                             GFP_KERNEL);
3761                 if (!p)
3762                         return -ENOMEM;
3763                 phy->_lo_pairs = p;
3764         }
3765
3766         return 0;
3767 }
3768
3769 static int bcm43xx_attach_board(struct bcm43xx_private *bcm)
3770 {
3771         struct pci_dev *pci_dev = bcm->pci_dev;
3772         struct net_device *net_dev = bcm->net_dev;
3773         int err;
3774         int i;
3775         u32 coremask;
3776
3777         err = pci_enable_device(pci_dev);
3778         if (err) {
3779                 printk(KERN_ERR PFX "pci_enable_device() failed\n");
3780                 goto out;
3781         }
3782         err = pci_request_regions(pci_dev, KBUILD_MODNAME);
3783         if (err) {
3784                 printk(KERN_ERR PFX "pci_request_regions() failed\n");
3785                 goto err_pci_disable;
3786         }
3787         /* enable PCI bus-mastering */
3788         pci_set_master(pci_dev);
3789         bcm->mmio_addr = pci_iomap(pci_dev, 0, ~0UL);
3790         if (!bcm->mmio_addr) {
3791                 printk(KERN_ERR PFX "pci_iomap() failed\n");
3792                 err = -EIO;
3793                 goto err_pci_release;
3794         }
3795         net_dev->base_addr = (unsigned long)bcm->mmio_addr;
3796
3797         err = bcm43xx_pci_read_config16(bcm, PCI_SUBSYSTEM_VENDOR_ID,
3798                                   &bcm->board_vendor);
3799         if (err)
3800                 goto err_iounmap;
3801         err = bcm43xx_pci_read_config16(bcm, PCI_SUBSYSTEM_ID,
3802                                   &bcm->board_type);
3803         if (err)
3804                 goto err_iounmap;
3805         err = bcm43xx_pci_read_config16(bcm, PCI_REVISION_ID,
3806                                   &bcm->board_revision);
3807         if (err)
3808                 goto err_iounmap;
3809
3810         err = bcm43xx_chipset_attach(bcm);
3811         if (err)
3812                 goto err_iounmap;
3813         err = bcm43xx_pctl_init(bcm);
3814         if (err)
3815                 goto err_chipset_detach;
3816         err = bcm43xx_probe_cores(bcm);
3817         if (err)
3818                 goto err_chipset_detach;
3819         
3820         /* Attach all IO cores to the backplane. */
3821         coremask = 0;
3822         for (i = 0; i < bcm->nr_80211_available; i++)
3823                 coremask |= (1 << bcm->core_80211[i].index);
3824         //FIXME: Also attach some non80211 cores?
3825         err = bcm43xx_setup_backplane_pci_connection(bcm, coremask);
3826         if (err) {
3827                 printk(KERN_ERR PFX "Backplane->PCI connection failed!\n");
3828                 goto err_chipset_detach;
3829         }
3830
3831         err = bcm43xx_sprom_extract(bcm);
3832         if (err)
3833                 goto err_chipset_detach;
3834         err = bcm43xx_leds_init(bcm);
3835         if (err)
3836                 goto err_chipset_detach;
3837
3838         for (i = 0; i < bcm->nr_80211_available; i++) {
3839                 err = bcm43xx_switch_core(bcm, &bcm->core_80211[i]);
3840                 assert(err != -ENODEV);
3841                 if (err)
3842                         goto err_80211_unwind;
3843
3844                 /* Enable the selected wireless core.
3845                  * Connect PHY only on the first core.
3846                  */
3847                 bcm43xx_wireless_core_reset(bcm, (i == 0));
3848
3849                 err = bcm43xx_read_phyinfo(bcm);
3850                 if (err && (i == 0))
3851                         goto err_80211_unwind;
3852
3853                 err = bcm43xx_read_radioinfo(bcm);
3854                 if (err && (i == 0))
3855                         goto err_80211_unwind;
3856
3857                 err = bcm43xx_validate_chip(bcm);
3858                 if (err && (i == 0))
3859                         goto err_80211_unwind;
3860
3861                 bcm43xx_radio_turn_off(bcm);
3862                 err = bcm43xx_phy_init_tssi2dbm_table(bcm);
3863                 if (err)
3864                         goto err_80211_unwind;
3865                 bcm43xx_wireless_core_disable(bcm);
3866         }
3867         err = bcm43xx_geo_init(bcm);
3868         if (err)
3869                 goto err_80211_unwind;
3870         bcm43xx_pctl_set_crystal(bcm, 0);
3871
3872         /* Set the MAC address in the networking subsystem */
3873         if (is_valid_ether_addr(bcm->sprom.et1macaddr))
3874                 memcpy(bcm->net_dev->dev_addr, bcm->sprom.et1macaddr, 6);
3875         else
3876                 memcpy(bcm->net_dev->dev_addr, bcm->sprom.il0macaddr, 6);
3877
3878         snprintf(bcm->nick, IW_ESSID_MAX_SIZE,
3879                  "Broadcom %04X", bcm->chip_id);
3880
3881         assert(err == 0);
3882 out:
3883         return err;
3884
3885 err_80211_unwind:
3886         for (i = 0; i < BCM43xx_MAX_80211_CORES; i++) {
3887                 kfree(bcm->core_80211_ext[i].phy._lo_pairs);
3888                 if (bcm->core_80211_ext[i].phy.dyn_tssi_tbl)
3889                         kfree(bcm->core_80211_ext[i].phy.tssi2dbm);
3890         }
3891 err_chipset_detach:
3892         bcm43xx_chipset_detach(bcm);
3893 err_iounmap:
3894         pci_iounmap(pci_dev, bcm->mmio_addr);
3895 err_pci_release:
3896         pci_release_regions(pci_dev);
3897 err_pci_disable:
3898         pci_disable_device(pci_dev);
3899         printk(KERN_ERR PFX "Unable to attach board\n");
3900         goto out;
3901 }
3902
3903 /* Do the Hardware IO operations to send the txb */
3904 static inline int bcm43xx_tx(struct bcm43xx_private *bcm,
3905                              struct ieee80211_txb *txb)
3906 {
3907         int err = -ENODEV;
3908
3909         if (bcm43xx_using_pio(bcm))
3910                 err = bcm43xx_pio_tx(bcm, txb);
3911         else
3912                 err = bcm43xx_dma_tx(bcm, txb);
3913         bcm->net_dev->trans_start = jiffies;
3914
3915         return err;
3916 }
3917
3918 static void bcm43xx_ieee80211_set_chan(struct net_device *net_dev,
3919                                        u8 channel)
3920 {
3921         struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
3922         struct bcm43xx_radioinfo *radio;
3923         unsigned long flags;
3924
3925         mutex_lock(&bcm->mutex);
3926         spin_lock_irqsave(&bcm->irq_lock, flags);
3927         if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) {
3928                 bcm43xx_mac_suspend(bcm);
3929                 bcm43xx_radio_selectchannel(bcm, channel, 0);
3930                 bcm43xx_mac_enable(bcm);
3931         } else {
3932                 radio = bcm43xx_current_radio(bcm);
3933                 radio->initial_channel = channel;
3934         }
3935         spin_unlock_irqrestore(&bcm->irq_lock, flags);
3936         mutex_unlock(&bcm->mutex);
3937 }
3938
3939 /* set_security() callback in struct ieee80211_device */
3940 static void bcm43xx_ieee80211_set_security(struct net_device *net_dev,
3941                                            struct ieee80211_security *sec)
3942 {
3943         struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
3944         struct ieee80211_security *secinfo = &bcm->ieee->sec;
3945         unsigned long flags;
3946         int keyidx;
3947         
3948         dprintk(KERN_INFO PFX "set security called");
3949
3950         mutex_lock(&bcm->mutex);
3951         spin_lock_irqsave(&bcm->irq_lock, flags);
3952
3953         for (keyidx = 0; keyidx<WEP_KEYS; keyidx++)
3954                 if (sec->flags & (1<<keyidx)) {
3955                         secinfo->encode_alg[keyidx] = sec->encode_alg[keyidx];
3956                         secinfo->key_sizes[keyidx] = sec->key_sizes[keyidx];
3957                         memcpy(secinfo->keys[keyidx], sec->keys[keyidx], SCM_KEY_LEN);
3958                 }
3959         
3960         if (sec->flags & SEC_ACTIVE_KEY) {
3961                 secinfo->active_key = sec->active_key;
3962                 dprintk(", .active_key = %d", sec->active_key);
3963         }
3964         if (sec->flags & SEC_UNICAST_GROUP) {
3965                 secinfo->unicast_uses_group = sec->unicast_uses_group;
3966                 dprintk(", .unicast_uses_group = %d", sec->unicast_uses_group);
3967         }
3968         if (sec->flags & SEC_LEVEL) {
3969                 secinfo->level = sec->level;
3970                 dprintk(", .level = %d", sec->level);
3971         }
3972         if (sec->flags & SEC_ENABLED) {
3973                 secinfo->enabled = sec->enabled;
3974                 dprintk(", .enabled = %d", sec->enabled);
3975         }
3976         if (sec->flags & SEC_ENCRYPT) {
3977                 secinfo->encrypt = sec->encrypt;
3978                 dprintk(", .encrypt = %d", sec->encrypt);
3979         }
3980         if (sec->flags & SEC_AUTH_MODE) {
3981                 secinfo->auth_mode = sec->auth_mode;
3982                 dprintk(", .auth_mode = %d", sec->auth_mode);
3983         }
3984         dprintk("\n");
3985         if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED &&
3986             !bcm->ieee->host_encrypt) {
3987                 if (secinfo->enabled) {
3988                         /* upload WEP keys to hardware */
3989                         char null_address[6] = { 0 };
3990                         u8 algorithm = 0;
3991                         for (keyidx = 0; keyidx<WEP_KEYS; keyidx++) {
3992                                 if (!(sec->flags & (1<<keyidx)))
3993                                         continue;
3994                                 switch (sec->encode_alg[keyidx]) {
3995                                         case SEC_ALG_NONE: algorithm = BCM43xx_SEC_ALGO_NONE; break;
3996                                         case SEC_ALG_WEP:
3997                                                 algorithm = BCM43xx_SEC_ALGO_WEP;
3998                                                 if (secinfo->key_sizes[keyidx] == 13)
3999                                                         algorithm = BCM43xx_SEC_ALGO_WEP104;
4000                                                 break;
4001                                         case SEC_ALG_TKIP:
4002                                                 FIXME();
4003                                                 algorithm = BCM43xx_SEC_ALGO_TKIP;
4004                                                 break;
4005                                         case SEC_ALG_CCMP:
4006                                                 FIXME();
4007                                                 algorithm = BCM43xx_SEC_ALGO_AES;
4008                                                 break;
4009                                         default:
4010                                                 assert(0);
4011                                                 break;
4012                                 }
4013                                 bcm43xx_key_write(bcm, keyidx, algorithm, sec->keys[keyidx], secinfo->key_sizes[keyidx], &null_address[0]);
4014                                 bcm->key[keyidx].enabled = 1;
4015                                 bcm->key[keyidx].algorithm = algorithm;
4016                         }
4017                 } else
4018                                 bcm43xx_clear_keys(bcm);
4019         }
4020         spin_unlock_irqrestore(&bcm->irq_lock, flags);
4021         mutex_unlock(&bcm->mutex);
4022 }
4023
4024 /* hard_start_xmit() callback in struct ieee80211_device */
4025 static int bcm43xx_ieee80211_hard_start_xmit(struct ieee80211_txb *txb,
4026                                              struct net_device *net_dev,
4027                                              int pri)
4028 {
4029         struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
4030         int err = -ENODEV;
4031         unsigned long flags;
4032
4033         spin_lock_irqsave(&bcm->irq_lock, flags);
4034         if (likely(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED))
4035                 err = bcm43xx_tx(bcm, txb);
4036         spin_unlock_irqrestore(&bcm->irq_lock, flags);
4037
4038         if (unlikely(err))
4039                 return NETDEV_TX_BUSY;
4040         return NETDEV_TX_OK;
4041 }
4042
4043 static void bcm43xx_net_tx_timeout(struct net_device *net_dev)
4044 {
4045         struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
4046         unsigned long flags;
4047
4048         spin_lock_irqsave(&bcm->irq_lock, flags);
4049         bcm43xx_controller_restart(bcm, "TX timeout");
4050         spin_unlock_irqrestore(&bcm->irq_lock, flags);
4051 }
4052
4053 #ifdef CONFIG_NET_POLL_CONTROLLER
4054 static void bcm43xx_net_poll_controller(struct net_device *net_dev)
4055 {
4056         struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
4057         unsigned long flags;
4058
4059         local_irq_save(flags);
4060         if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED)
4061                 bcm43xx_interrupt_handler(bcm->irq, bcm);
4062         local_irq_restore(flags);
4063 }
4064 #endif /* CONFIG_NET_POLL_CONTROLLER */
4065
4066 static int bcm43xx_net_open(struct net_device *net_dev)
4067 {
4068         struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
4069
4070         return bcm43xx_init_board(bcm);
4071 }
4072
4073 static int bcm43xx_net_stop(struct net_device *net_dev)
4074 {
4075         struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
4076         int err;
4077
4078         ieee80211softmac_stop(net_dev);
4079         err = bcm43xx_disable_interrupts_sync(bcm);
4080         assert(!err);
4081         bcm43xx_free_board(bcm);
4082         flush_scheduled_work();
4083
4084         return 0;
4085 }
4086
4087 static int bcm43xx_init_private(struct bcm43xx_private *bcm,
4088                                 struct net_device *net_dev,
4089                                 struct pci_dev *pci_dev)
4090 {
4091         bcm43xx_set_status(bcm, BCM43xx_STAT_UNINIT);
4092         bcm->ieee = netdev_priv(net_dev);
4093         bcm->softmac = ieee80211_priv(net_dev);
4094         bcm->softmac->set_channel = bcm43xx_ieee80211_set_chan;
4095
4096         bcm->irq_savedstate = BCM43xx_IRQ_INITIAL;
4097         bcm->mac_suspended = 1;
4098         bcm->pci_dev = pci_dev;
4099         bcm->net_dev = net_dev;
4100         bcm->bad_frames_preempt = modparam_bad_frames_preempt;
4101         spin_lock_init(&bcm->irq_lock);
4102         spin_lock_init(&bcm->leds_lock);
4103         mutex_init(&bcm->mutex);
4104         tasklet_init(&bcm->isr_tasklet,
4105                      (void (*)(unsigned long))bcm43xx_interrupt_tasklet,
4106                      (unsigned long)bcm);
4107         tasklet_disable_nosync(&bcm->isr_tasklet);
4108         if (modparam_pio)
4109                 bcm->__using_pio = 1;
4110         bcm->rts_threshold = BCM43xx_DEFAULT_RTS_THRESHOLD;
4111
4112         /* default to sw encryption for now */
4113         bcm->ieee->host_build_iv = 0;
4114         bcm->ieee->host_encrypt = 1;
4115         bcm->ieee->host_decrypt = 1;
4116         
4117         bcm->ieee->iw_mode = BCM43xx_INITIAL_IWMODE;
4118         bcm->ieee->tx_headroom = sizeof(struct bcm43xx_txhdr);
4119         bcm->ieee->set_security = bcm43xx_ieee80211_set_security;
4120         bcm->ieee->hard_start_xmit = bcm43xx_ieee80211_hard_start_xmit;
4121
4122         return 0;
4123 }
4124
4125 static int __devinit bcm43xx_init_one(struct pci_dev *pdev,
4126                                       const struct pci_device_id *ent)
4127 {
4128         struct net_device *net_dev;
4129         struct bcm43xx_private *bcm;
4130         int err;
4131
4132 #ifdef CONFIG_BCM947XX
4133         if ((pdev->bus->number == 0) && (pdev->device != 0x0800))
4134                 return -ENODEV;
4135 #endif
4136
4137 #ifdef DEBUG_SINGLE_DEVICE_ONLY
4138         if (strcmp(pci_name(pdev), DEBUG_SINGLE_DEVICE_ONLY))
4139                 return -ENODEV;
4140 #endif
4141
4142         net_dev = alloc_ieee80211softmac(sizeof(*bcm));
4143         if (!net_dev) {
4144                 printk(KERN_ERR PFX
4145                        "could not allocate ieee80211 device %s\n",
4146                        pci_name(pdev));
4147                 err = -ENOMEM;
4148                 goto out;
4149         }
4150         /* initialize the net_device struct */
4151         SET_MODULE_OWNER(net_dev);
4152         SET_NETDEV_DEV(net_dev, &pdev->dev);
4153
4154         net_dev->open = bcm43xx_net_open;
4155         net_dev->stop = bcm43xx_net_stop;
4156         net_dev->tx_timeout = bcm43xx_net_tx_timeout;
4157 #ifdef CONFIG_NET_POLL_CONTROLLER
4158         net_dev->poll_controller = bcm43xx_net_poll_controller;
4159 #endif
4160         net_dev->wireless_handlers = &bcm43xx_wx_handlers_def;
4161         net_dev->irq = pdev->irq;
4162         SET_ETHTOOL_OPS(net_dev, &bcm43xx_ethtool_ops);
4163
4164         /* initialize the bcm43xx_private struct */
4165         bcm = bcm43xx_priv(net_dev);
4166         memset(bcm, 0, sizeof(*bcm));
4167         err = bcm43xx_init_private(bcm, net_dev, pdev);
4168         if (err)
4169                 goto err_free_netdev;
4170
4171         pci_set_drvdata(pdev, net_dev);
4172
4173         err = bcm43xx_attach_board(bcm);
4174         if (err)
4175                 goto err_free_netdev;
4176
4177         err = register_netdev(net_dev);
4178         if (err) {
4179                 printk(KERN_ERR PFX "Cannot register net device, "
4180                        "aborting.\n");
4181                 err = -ENOMEM;
4182                 goto err_detach_board;
4183         }
4184
4185         bcm43xx_debugfs_add_device(bcm);
4186
4187         assert(err == 0);
4188 out:
4189         return err;
4190
4191 err_detach_board:
4192         bcm43xx_detach_board(bcm);
4193 err_free_netdev:
4194         free_ieee80211softmac(net_dev);
4195         goto out;
4196 }
4197
4198 static void __devexit bcm43xx_remove_one(struct pci_dev *pdev)
4199 {
4200         struct net_device *net_dev = pci_get_drvdata(pdev);
4201         struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
4202
4203         bcm43xx_debugfs_remove_device(bcm);
4204         unregister_netdev(net_dev);
4205         bcm43xx_detach_board(bcm);
4206         free_ieee80211softmac(net_dev);
4207 }
4208
4209 /* Hard-reset the chip. Do not call this directly.
4210  * Use bcm43xx_controller_restart()
4211  */
4212 static void bcm43xx_chip_reset(struct work_struct *work)
4213 {
4214         struct bcm43xx_private *bcm =
4215                 container_of(work, struct bcm43xx_private, restart_work);
4216         struct bcm43xx_phyinfo *phy;
4217         int err = -ENODEV;
4218
4219         mutex_lock(&(bcm)->mutex);
4220         if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) {
4221                 bcm43xx_periodic_tasks_delete(bcm);
4222                 phy = bcm43xx_current_phy(bcm);
4223                 err = bcm43xx_select_wireless_core(bcm, phy->type);
4224                 if (!err)
4225                         bcm43xx_periodic_tasks_setup(bcm);
4226         }
4227         mutex_unlock(&(bcm)->mutex);
4228
4229         printk(KERN_ERR PFX "Controller restart%s\n",
4230                (err == 0) ? "ed" : " failed");
4231 }
4232
4233 /* Hard-reset the chip.
4234  * This can be called from interrupt or process context.
4235  * bcm->irq_lock must be locked.
4236  */
4237 void bcm43xx_controller_restart(struct bcm43xx_private *bcm, const char *reason)
4238 {
4239         if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED)
4240                 return;
4241         printk(KERN_ERR PFX "Controller RESET (%s) ...\n", reason);
4242         INIT_WORK(&bcm->restart_work, bcm43xx_chip_reset);
4243         schedule_work(&bcm->restart_work);
4244 }
4245
4246 #ifdef CONFIG_PM
4247
4248 static int bcm43xx_suspend(struct pci_dev *pdev, pm_message_t state)
4249 {
4250         struct net_device *net_dev = pci_get_drvdata(pdev);
4251         struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
4252         int err;
4253
4254         dprintk(KERN_INFO PFX "Suspending...\n");
4255
4256         netif_device_detach(net_dev);
4257         bcm->was_initialized = 0;
4258         if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) {
4259                 bcm->was_initialized = 1;
4260                 ieee80211softmac_stop(net_dev);
4261                 err = bcm43xx_disable_interrupts_sync(bcm);
4262                 if (unlikely(err)) {
4263                         dprintk(KERN_ERR PFX "Suspend failed.\n");
4264                         return -EAGAIN;
4265                 }
4266                 bcm->firmware_norelease = 1;
4267                 bcm43xx_free_board(bcm);
4268                 bcm->firmware_norelease = 0;
4269         }
4270         bcm43xx_chipset_detach(bcm);
4271
4272         pci_save_state(pdev);
4273         pci_disable_device(pdev);
4274         pci_set_power_state(pdev, pci_choose_state(pdev, state));
4275
4276         dprintk(KERN_INFO PFX "Device suspended.\n");
4277
4278         return 0;
4279 }
4280
4281 static int bcm43xx_resume(struct pci_dev *pdev)
4282 {
4283         struct net_device *net_dev = pci_get_drvdata(pdev);
4284         struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
4285         int err = 0;
4286
4287         dprintk(KERN_INFO PFX "Resuming...\n");
4288
4289         pci_set_power_state(pdev, 0);
4290         err = pci_enable_device(pdev);
4291         if (err) {
4292                 printk(KERN_ERR PFX "Failure with pci_enable_device!\n");
4293                 return err;
4294         }
4295         pci_restore_state(pdev);
4296
4297         bcm43xx_chipset_attach(bcm);
4298         if (bcm->was_initialized)
4299                 err = bcm43xx_init_board(bcm);
4300         if (err) {
4301                 printk(KERN_ERR PFX "Resume failed!\n");
4302                 return err;
4303         }
4304         netif_device_attach(net_dev);
4305
4306         dprintk(KERN_INFO PFX "Device resumed.\n");
4307
4308         return 0;
4309 }
4310
4311 #endif                          /* CONFIG_PM */
4312
4313 static struct pci_driver bcm43xx_pci_driver = {
4314         .name = KBUILD_MODNAME,
4315         .id_table = bcm43xx_pci_tbl,
4316         .probe = bcm43xx_init_one,
4317         .remove = __devexit_p(bcm43xx_remove_one),
4318 #ifdef CONFIG_PM
4319         .suspend = bcm43xx_suspend,
4320         .resume = bcm43xx_resume,
4321 #endif                          /* CONFIG_PM */
4322 };
4323
4324 static int __init bcm43xx_init(void)
4325 {
4326         printk(KERN_INFO KBUILD_MODNAME " driver\n");
4327         bcm43xx_debugfs_init();
4328         return pci_register_driver(&bcm43xx_pci_driver);
4329 }
4330
4331 static void __exit bcm43xx_exit(void)
4332 {
4333         pci_unregister_driver(&bcm43xx_pci_driver);
4334         bcm43xx_debugfs_exit();
4335 }
4336
4337 module_init(bcm43xx_init)
4338 module_exit(bcm43xx_exit)