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