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