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