[PATCH] bcm43xx: Fix makefile. Remove all the "out-of-tree" stuff.
[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
2232static void bcm43xx_release_firmware(struct bcm43xx_private *bcm)
2233{
2234 if (bcm->firmware_norelease)
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:
2364 bcm43xx_release_firmware(bcm);
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
2412static void bcm43xx_write_initvals(struct bcm43xx_private *bcm,
2413 const struct bcm43xx_initval *data,
2414 const unsigned int len)
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
2425 if (size == 2)
2426 bcm43xx_write16(bcm, offset, value);
2427 else if (size == 4)
2428 bcm43xx_write32(bcm, offset, value);
2429 else
2430 printk(KERN_ERR PFX "InitVals fileformat error.\n");
2431 }
2432}
2433
2434static void bcm43xx_upload_initvals(struct bcm43xx_private *bcm)
2435{
2436#ifdef DEBUG_ENABLE_UCODE_MMIO_PRINT
2437 bcm43xx_mmioprint_enable(bcm);
2438#else
2439 bcm43xx_mmioprint_disable(bcm);
2440#endif
2441
2442 bcm43xx_write_initvals(bcm, (struct bcm43xx_initval *)bcm->initvals0->data,
2443 bcm->initvals0->size / sizeof(struct bcm43xx_initval));
2444 if (bcm->initvals1) {
2445 bcm43xx_write_initvals(bcm, (struct bcm43xx_initval *)bcm->initvals1->data,
2446 bcm->initvals1->size / sizeof(struct bcm43xx_initval));
2447 }
2448
2449#ifdef DEBUG_ENABLE_UCODE_MMIO_PRINT
2450 bcm43xx_mmioprint_disable(bcm);
2451#else
2452 bcm43xx_mmioprint_enable(bcm);
2453#endif
2454}
2455
2456static int bcm43xx_initialize_irq(struct bcm43xx_private *bcm)
2457{
2458 int res;
2459 unsigned int i;
2460 u32 data;
2461
2462 bcm->irq = bcm->pci_dev->irq;
2463#ifdef CONFIG_BCM947XX
2464 if (bcm->pci_dev->bus->number == 0) {
2465 struct pci_dev *d = NULL;
2466 /* FIXME: we will probably need more device IDs here... */
2467 d = pci_find_device(PCI_VENDOR_ID_BROADCOM, 0x4324, NULL);
2468 if (d != NULL) {
2469 bcm->irq = d->irq;
2470 }
2471 }
2472#endif
2473 res = request_irq(bcm->irq, bcm43xx_interrupt_handler,
65f3f191 2474 SA_SHIRQ, KBUILD_MODNAME, bcm);
f222313a
JL
2475 if (res) {
2476 printk(KERN_ERR PFX "Cannot register IRQ%d\n", bcm->irq);
2477 return -EFAULT;
2478 }
2479 bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, 0xffffffff);
2480 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, 0x00020402);
2481 i = 0;
2482 while (1) {
2483 data = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON);
2484 if (data == BCM43xx_IRQ_READY)
2485 break;
2486 i++;
2487 if (i >= BCM43xx_IRQWAIT_MAX_RETRIES) {
2488 printk(KERN_ERR PFX "Card IRQ register not responding. "
2489 "Giving up.\n");
2490 free_irq(bcm->irq, bcm);
2491 return -ENODEV;
2492 }
2493 udelay(10);
2494 }
2495 // dummy read
2496 bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON);
2497
2498 return 0;
2499}
2500
2501/* Switch to the core used to write the GPIO register.
2502 * This is either the ChipCommon, or the PCI core.
2503 */
2504static inline int switch_to_gpio_core(struct bcm43xx_private *bcm)
2505{
2506 int err;
2507
2508 /* Where to find the GPIO register depends on the chipset.
2509 * If it has a ChipCommon, its register at offset 0x6c is the GPIO
2510 * control register. Otherwise the register at offset 0x6c in the
2511 * PCI core is the GPIO control register.
2512 */
2513 err = bcm43xx_switch_core(bcm, &bcm->core_chipcommon);
2514 if (err == -ENODEV) {
2515 err = bcm43xx_switch_core(bcm, &bcm->core_pci);
2516 if (err == -ENODEV) {
2517 printk(KERN_ERR PFX "gpio error: "
2518 "Neither ChipCommon nor PCI core available!\n");
2519 return -ENODEV;
2520 } else if (err != 0)
2521 return -ENODEV;
2522 } else if (err != 0)
2523 return -ENODEV;
2524
2525 return 0;
2526}
2527
2528/* Initialize the GPIOs
2529 * http://bcm-specs.sipsolutions.net/GPIO
2530 */
2531static int bcm43xx_gpio_init(struct bcm43xx_private *bcm)
2532{
2533 struct bcm43xx_coreinfo *old_core;
2534 int err;
2535 u32 mask, value;
2536
2537 value = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
2538 value &= ~0xc000;
2539 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, value);
2540
2541 mask = 0x0000001F;
2542 value = 0x0000000F;
2543 bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_CONTROL,
2544 bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_CONTROL) & 0xFFF0);
2545 bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_MASK,
2546 bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_MASK) | 0x000F);
2547
2548 old_core = bcm->current_core;
2549
2550 err = switch_to_gpio_core(bcm);
2551 if (err)
2552 return err;
2553
2554 if (bcm->current_core->rev >= 2){
2555 mask |= 0x10;
2556 value |= 0x10;
2557 }
2558 if (bcm->chip_id == 0x4301) {
2559 mask |= 0x60;
2560 value |= 0x60;
2561 }
2562 if (bcm->sprom.boardflags & BCM43xx_BFL_PACTRL) {
2563 mask |= 0x200;
2564 value |= 0x200;
2565 }
2566
2567 bcm43xx_write32(bcm, BCM43xx_GPIO_CONTROL,
2568 (bcm43xx_read32(bcm, BCM43xx_GPIO_CONTROL) & mask) | value);
2569
2570 err = bcm43xx_switch_core(bcm, old_core);
2571 assert(err == 0);
2572
2573 return 0;
2574}
2575
2576/* Turn off all GPIO stuff. Call this on module unload, for example. */
2577static int bcm43xx_gpio_cleanup(struct bcm43xx_private *bcm)
2578{
2579 struct bcm43xx_coreinfo *old_core;
2580 int err;
2581
2582 old_core = bcm->current_core;
2583 err = switch_to_gpio_core(bcm);
2584 if (err)
2585 return err;
2586 bcm43xx_write32(bcm, BCM43xx_GPIO_CONTROL, 0x00000000);
2587 err = bcm43xx_switch_core(bcm, old_core);
2588 assert(err == 0);
2589
2590 return 0;
2591}
2592
2593/* http://bcm-specs.sipsolutions.net/EnableMac */
2594void bcm43xx_mac_enable(struct bcm43xx_private *bcm)
2595{
2596 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD,
2597 bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD)
2598 | BCM43xx_SBF_MAC_ENABLED);
2599 bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, BCM43xx_IRQ_READY);
2600 bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); /* dummy read */
2601 bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); /* dummy read */
2602 bcm43xx_power_saving_ctl_bits(bcm, -1, -1);
2603}
2604
2605/* http://bcm-specs.sipsolutions.net/SuspendMAC */
2606void bcm43xx_mac_suspend(struct bcm43xx_private *bcm)
2607{
2608 int i;
2609 u32 tmp;
2610
2611 bcm43xx_power_saving_ctl_bits(bcm, -1, 1);
2612 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD,
2613 bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD)
2614 & ~BCM43xx_SBF_MAC_ENABLED);
2615 bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); /* dummy read */
2616 for (i = 1000; i > 0; i--) {
2617 tmp = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON);
2618 if (tmp & BCM43xx_IRQ_READY) {
2619 i = -1;
2620 break;
2621 }
2622 udelay(10);
2623 }
2624 if (!i)
2625 printkl(KERN_ERR PFX "Failed to suspend mac!\n");
2626}
2627
2628void bcm43xx_set_iwmode(struct bcm43xx_private *bcm,
2629 int iw_mode)
2630{
2631 unsigned long flags;
2632 u32 status;
2633
2634 spin_lock_irqsave(&bcm->ieee->lock, flags);
2635 bcm->ieee->iw_mode = iw_mode;
2636 spin_unlock_irqrestore(&bcm->ieee->lock, flags);
2637 if (iw_mode == IW_MODE_MONITOR)
2638 bcm->net_dev->type = ARPHRD_IEEE80211;
2639 else
2640 bcm->net_dev->type = ARPHRD_ETHER;
2641
2642 if (!bcm->initialized)
2643 return;
2644
2645 bcm43xx_mac_suspend(bcm);
2646 status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
2647 /* Reset status to infrastructured mode */
2648 status &= ~(BCM43xx_SBF_MODE_AP | BCM43xx_SBF_MODE_MONITOR);
2649 /*FIXME: We actually set promiscuous mode as well, until we don't
2650 * get the HW mac filter working */
2651 status |= BCM43xx_SBF_MODE_NOTADHOC | BCM43xx_SBF_MODE_PROMISC;
2652
2653 switch (iw_mode) {
2654 case IW_MODE_MONITOR:
2655 status |= (BCM43xx_SBF_MODE_PROMISC |
2656 BCM43xx_SBF_MODE_MONITOR);
2657 break;
2658 case IW_MODE_ADHOC:
2659 status &= ~BCM43xx_SBF_MODE_NOTADHOC;
2660 break;
2661 case IW_MODE_MASTER:
2662 case IW_MODE_SECOND:
2663 case IW_MODE_REPEAT:
2664 /* TODO: No AP/Repeater mode for now :-/ */
2665 TODO();
2666 break;
2667 case IW_MODE_INFRA:
2668 /* nothing to be done here... */
2669 break;
2670 default:
2671 printk(KERN_ERR PFX "Unknown iwmode %d\n", iw_mode);
2672 }
2673
2674 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, status);
2675 bcm43xx_mac_enable(bcm);
2676}
2677
2678/* This is the opposite of bcm43xx_chip_init() */
2679static void bcm43xx_chip_cleanup(struct bcm43xx_private *bcm)
2680{
2681 bcm43xx_radio_turn_off(bcm);
2682 if (!modparam_noleds)
2683 bcm43xx_leds_exit(bcm);
2684 bcm43xx_gpio_cleanup(bcm);
2685 free_irq(bcm->irq, bcm);
2686 bcm43xx_release_firmware(bcm);
2687}
2688
2689/* Initialize the chip
2690 * http://bcm-specs.sipsolutions.net/ChipInit
2691 */
2692static int bcm43xx_chip_init(struct bcm43xx_private *bcm)
2693{
2694 int err;
2695 int iw_mode = bcm->ieee->iw_mode;
2696 int tmp;
2697 u32 value32;
2698 u16 value16;
2699
2700 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD,
2701 BCM43xx_SBF_CORE_READY
2702 | BCM43xx_SBF_400);
2703
2704 err = bcm43xx_request_firmware(bcm);
2705 if (err)
2706 goto out;
2707 bcm43xx_upload_microcode(bcm);
2708
2709 err = bcm43xx_initialize_irq(bcm);
2710 if (err)
2711 goto out;
2712
2713 err = bcm43xx_gpio_init(bcm);
2714 if (err)
2715 goto err_free_irq;
2716
2717 bcm43xx_upload_initvals(bcm);
2718 bcm43xx_radio_turn_on(bcm);
2719
2720 if (modparam_noleds)
2721 bcm43xx_leds_turn_off(bcm);
2722 else
2723 bcm43xx_leds_update(bcm, 0);
2724
2725 bcm43xx_write16(bcm, 0x03E6, 0x0000);
2726 err = bcm43xx_phy_init(bcm);
2727 if (err)
2728 goto err_radio_off;
2729
2730 /* Select initial Interference Mitigation. */
2731 tmp = bcm->current_core->radio->interfmode;
2732 bcm->current_core->radio->interfmode = BCM43xx_RADIO_INTERFMODE_NONE;
2733 bcm43xx_radio_set_interference_mitigation(bcm, tmp);
2734
2735 bcm43xx_phy_set_antenna_diversity(bcm);
2736 bcm43xx_radio_set_txantenna(bcm, BCM43xx_RADIO_TXANTENNA_DEFAULT);
2737 if (bcm->current_core->phy->type == BCM43xx_PHYTYPE_B) {
2738 value16 = bcm43xx_read16(bcm, 0x005E);
2739 value16 |= 0x0004;
2740 bcm43xx_write16(bcm, 0x005E, value16);
2741 }
2742 bcm43xx_write32(bcm, 0x0100, 0x01000000);
2743 if (bcm->current_core->rev < 5)
2744 bcm43xx_write32(bcm, 0x010C, 0x01000000);
2745
2746 value32 = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
2747 value32 &= ~ BCM43xx_SBF_MODE_NOTADHOC;
2748 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, value32);
2749 value32 = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
2750 value32 |= BCM43xx_SBF_MODE_NOTADHOC;
2751 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, value32);
2752 /*FIXME: For now, use promiscuous mode at all times; otherwise we don't
2753 get broadcast or multicast packets */
2754 value32 = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
2755 value32 |= BCM43xx_SBF_MODE_PROMISC;
2756 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, value32);
2757
2758 if (iw_mode == IW_MODE_MONITOR) {
2759 value32 = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
2760 value32 |= BCM43xx_SBF_MODE_PROMISC;
2761 value32 |= BCM43xx_SBF_MODE_MONITOR;
2762 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, value32);
2763 }
2764 value32 = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
2765 value32 |= 0x100000; //FIXME: What's this? Is this correct?
2766 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, value32);
2767
2768 if (bcm->pio_mode) {
2769 bcm43xx_write32(bcm, 0x0210, 0x00000100);
2770 bcm43xx_write32(bcm, 0x0230, 0x00000100);
2771 bcm43xx_write32(bcm, 0x0250, 0x00000100);
2772 bcm43xx_write32(bcm, 0x0270, 0x00000100);
2773 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0034, 0x0000);
2774 }
2775
2776 /* Probe Response Timeout value */
2777 /* FIXME: Default to 0, has to be set by ioctl probably... :-/ */
2778 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0074, 0x0000);
2779
2780 if (iw_mode != IW_MODE_ADHOC && iw_mode != IW_MODE_MASTER) {
2781 if ((bcm->chip_id == 0x4306) && (bcm->chip_rev == 3))
2782 bcm43xx_write16(bcm, 0x0612, 0x0064);
2783 else
2784 bcm43xx_write16(bcm, 0x0612, 0x0032);
2785 } else
2786 bcm43xx_write16(bcm, 0x0612, 0x0002);
2787
2788 if (bcm->current_core->rev < 3) {
2789 bcm43xx_write16(bcm, 0x060E, 0x0000);
2790 bcm43xx_write16(bcm, 0x0610, 0x8000);
2791 bcm43xx_write16(bcm, 0x0604, 0x0000);
2792 bcm43xx_write16(bcm, 0x0606, 0x0200);
2793 } else {
2794 bcm43xx_write32(bcm, 0x0188, 0x80000000);
2795 bcm43xx_write32(bcm, 0x018C, 0x02000000);
2796 }
2797 bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, 0x00004000);
2798 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA1_IRQ_MASK, 0x0001DC00);
2799 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA2_IRQ_MASK, 0x0000DC00);
2800 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA3_IRQ_MASK, 0x0000DC00);
2801 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA4_IRQ_MASK, 0x0001DC00);
2802
2803 value32 = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
2804 value32 |= 0x00100000;
2805 bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, value32);
2806
2807 bcm43xx_write16(bcm, BCM43xx_MMIO_POWERUP_DELAY, bcm43xx_pctl_powerup_delay(bcm));
2808
2809 assert(err == 0);
2810 dprintk(KERN_INFO PFX "Chip initialized\n");
2811out:
2812 return err;
2813
2814err_radio_off:
2815 bcm43xx_radio_turn_off(bcm);
2816 bcm43xx_gpio_cleanup(bcm);
2817err_free_irq:
2818 free_irq(bcm->irq, bcm);
2819 goto out;
2820}
2821
2822/* Validate chip access
2823 * http://bcm-specs.sipsolutions.net/ValidateChipAccess */
2824static int bcm43xx_validate_chip(struct bcm43xx_private *bcm)
2825{
2826 int err = -ENODEV;
2827 u32 value;
2828 u32 shm_backup;
2829
2830 shm_backup = bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED, 0x0000);
2831 bcm43xx_shm_write32(bcm, BCM43xx_SHM_SHARED, 0x0000, 0xAA5555AA);
2832 if (bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED, 0x0000) != 0xAA5555AA) {
2833 printk(KERN_ERR PFX "Error: SHM mismatch (1) validating chip\n");
2834 goto out;
2835 }
2836
2837 bcm43xx_shm_write32(bcm, BCM43xx_SHM_SHARED, 0x0000, 0x55AAAA55);
2838 if (bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED, 0x0000) != 0x55AAAA55) {
2839 printk(KERN_ERR PFX "Error: SHM mismatch (2) validating chip\n");
2840 goto out;
2841 }
2842
2843 bcm43xx_shm_write32(bcm, BCM43xx_SHM_SHARED, 0x0000, shm_backup);
2844
2845 value = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
2846 if ((value | 0x80000000) != 0x80000400) {
2847 printk(KERN_ERR PFX "Error: Bad Status Bitfield while validating chip\n");
2848 goto out;
2849 }
2850
2851 value = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON);
2852 if (value != 0x00000000) {
2853 printk(KERN_ERR PFX "Error: Bad interrupt reason code while validating chip\n");
2854 goto out;
2855 }
2856
2857 err = 0;
2858out:
2859 return err;
2860}
2861
2862static int bcm43xx_probe_cores(struct bcm43xx_private *bcm)
2863{
2864 int err, i;
2865 int current_core;
2866 u32 core_vendor, core_id, core_rev;
2867 u32 sb_id_hi, chip_id_32 = 0;
2868 u16 pci_device, chip_id_16;
2869 u8 core_count;
2870
2871 memset(&bcm->core_chipcommon, 0, sizeof(struct bcm43xx_coreinfo));
2872 memset(&bcm->core_pci, 0, sizeof(struct bcm43xx_coreinfo));
2873 memset(&bcm->core_v90, 0, sizeof(struct bcm43xx_coreinfo));
2874 memset(&bcm->core_pcmcia, 0, sizeof(struct bcm43xx_coreinfo));
2875 memset(&bcm->core_80211, 0, sizeof(struct bcm43xx_coreinfo)
2876 * BCM43xx_MAX_80211_CORES);
2877
2878 memset(&bcm->phy, 0, sizeof(struct bcm43xx_phyinfo)
2879 * BCM43xx_MAX_80211_CORES);
2880 memset(&bcm->radio, 0, sizeof(struct bcm43xx_radioinfo)
2881 * BCM43xx_MAX_80211_CORES);
2882
2883 /* map core 0 */
2884 err = _switch_core(bcm, 0);
2885 if (err)
2886 goto out;
2887
2888 /* fetch sb_id_hi from core information registers */
2889 sb_id_hi = bcm43xx_read32(bcm, BCM43xx_CIR_SB_ID_HI);
2890
2891 core_id = (sb_id_hi & 0xFFF0) >> 4;
2892 core_rev = (sb_id_hi & 0xF);
2893 core_vendor = (sb_id_hi & 0xFFFF0000) >> 16;
2894
2895 /* if present, chipcommon is always core 0; read the chipid from it */
2896 if (core_id == BCM43xx_COREID_CHIPCOMMON) {
2897 chip_id_32 = bcm43xx_read32(bcm, 0);
2898 chip_id_16 = chip_id_32 & 0xFFFF;
2899 bcm->core_chipcommon.flags |= BCM43xx_COREFLAG_AVAILABLE;
2900 bcm->core_chipcommon.id = core_id;
2901 bcm->core_chipcommon.rev = core_rev;
2902 bcm->core_chipcommon.index = 0;
2903 /* While we are at it, also read the capabilities. */
2904 bcm->chipcommon_capabilities = bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_CAPABILITIES);
2905 } else {
2906 /* without a chipCommon, use a hard coded table. */
2907 pci_device = bcm->pci_dev->device;
2908 if (pci_device == 0x4301)
2909 chip_id_16 = 0x4301;
2910 else if ((pci_device >= 0x4305) && (pci_device <= 0x4307))
2911 chip_id_16 = 0x4307;
2912 else if ((pci_device >= 0x4402) && (pci_device <= 0x4403))
2913 chip_id_16 = 0x4402;
2914 else if ((pci_device >= 0x4610) && (pci_device <= 0x4615))
2915 chip_id_16 = 0x4610;
2916 else if ((pci_device >= 0x4710) && (pci_device <= 0x4715))
2917 chip_id_16 = 0x4710;
2918#ifdef CONFIG_BCM947XX
2919 else if ((pci_device >= 0x4320) && (pci_device <= 0x4325))
2920 chip_id_16 = 0x4309;
2921#endif
2922 else {
2923 printk(KERN_ERR PFX "Could not determine Chip ID\n");
2924 return -ENODEV;
2925 }
2926 }
2927
2928 /* ChipCommon with Core Rev >=4 encodes number of cores,
2929 * otherwise consult hardcoded table */
2930 if ((core_id == BCM43xx_COREID_CHIPCOMMON) && (core_rev >= 4)) {
2931 core_count = (chip_id_32 & 0x0F000000) >> 24;
2932 } else {
2933 switch (chip_id_16) {
2934 case 0x4610:
2935 case 0x4704:
2936 case 0x4710:
2937 core_count = 9;
2938 break;
2939 case 0x4310:
2940 core_count = 8;
2941 break;
2942 case 0x5365:
2943 core_count = 7;
2944 break;
2945 case 0x4306:
2946 core_count = 6;
2947 break;
2948 case 0x4301:
2949 case 0x4307:
2950 core_count = 5;
2951 break;
2952 case 0x4402:
2953 core_count = 3;
2954 break;
2955 default:
2956 /* SOL if we get here */
2957 assert(0);
2958 core_count = 1;
2959 }
2960 }
2961
2962 bcm->chip_id = chip_id_16;
2963 bcm->chip_rev = (chip_id_32 & 0x000f0000) >> 16;
2964
2965 dprintk(KERN_INFO PFX "Chip ID 0x%x, rev 0x%x\n",
2966 bcm->chip_id, bcm->chip_rev);
2967 dprintk(KERN_INFO PFX "Number of cores: %d\n", core_count);
2968 if (bcm->core_chipcommon.flags & BCM43xx_COREFLAG_AVAILABLE) {
2969 dprintk(KERN_INFO PFX "Core 0: ID 0x%x, rev 0x%x, vendor 0x%x, %s\n",
2970 core_id, core_rev, core_vendor,
2971 bcm43xx_core_enabled(bcm) ? "enabled" : "disabled");
2972 }
2973
2974 if (bcm->core_chipcommon.flags & BCM43xx_COREFLAG_AVAILABLE)
2975 current_core = 1;
2976 else
2977 current_core = 0;
2978 for ( ; current_core < core_count; current_core++) {
2979 struct bcm43xx_coreinfo *core;
2980
2981 err = _switch_core(bcm, current_core);
2982 if (err)
2983 goto out;
2984 /* Gather information */
2985 /* fetch sb_id_hi from core information registers */
2986 sb_id_hi = bcm43xx_read32(bcm, BCM43xx_CIR_SB_ID_HI);
2987
2988 /* extract core_id, core_rev, core_vendor */
2989 core_id = (sb_id_hi & 0xFFF0) >> 4;
2990 core_rev = (sb_id_hi & 0xF);
2991 core_vendor = (sb_id_hi & 0xFFFF0000) >> 16;
2992
2993 dprintk(KERN_INFO PFX "Core %d: ID 0x%x, rev 0x%x, vendor 0x%x, %s\n",
2994 current_core, core_id, core_rev, core_vendor,
2995 bcm43xx_core_enabled(bcm) ? "enabled" : "disabled" );
2996
2997 core = NULL;
2998 switch (core_id) {
2999 case BCM43xx_COREID_PCI:
3000 core = &bcm->core_pci;
3001 if (core->flags & BCM43xx_COREFLAG_AVAILABLE) {
3002 printk(KERN_WARNING PFX "Multiple PCI cores found.\n");
3003 continue;
3004 }
3005 break;
3006 case BCM43xx_COREID_V90:
3007 core = &bcm->core_v90;
3008 if (core->flags & BCM43xx_COREFLAG_AVAILABLE) {
3009 printk(KERN_WARNING PFX "Multiple V90 cores found.\n");
3010 continue;
3011 }
3012 break;
3013 case BCM43xx_COREID_PCMCIA:
3014 core = &bcm->core_pcmcia;
3015 if (core->flags & BCM43xx_COREFLAG_AVAILABLE) {
3016 printk(KERN_WARNING PFX "Multiple PCMCIA cores found.\n");
3017 continue;
3018 }
3019 break;
3020 case BCM43xx_COREID_ETHERNET:
3021 core = &bcm->core_ethernet;
3022 if (core->flags & BCM43xx_COREFLAG_AVAILABLE) {
3023 printk(KERN_WARNING PFX "Multiple Ethernet cores found.\n");
3024 continue;
3025 }
3026 break;
3027 case BCM43xx_COREID_80211:
3028 for (i = 0; i < BCM43xx_MAX_80211_CORES; i++) {
3029 core = &(bcm->core_80211[i]);
3030 if (!(core->flags & BCM43xx_COREFLAG_AVAILABLE))
3031 break;
3032 core = NULL;
3033 }
3034 if (!core) {
3035 printk(KERN_WARNING PFX "More than %d cores of type 802.11 found.\n",
3036 BCM43xx_MAX_80211_CORES);
3037 continue;
3038 }
3039 if (i != 0) {
3040 /* More than one 80211 core is only supported
3041 * by special chips.
3042 * There are chips with two 80211 cores, but with
3043 * dangling pins on the second core. Be careful
3044 * and ignore these cores here.
3045 */
3046 if (bcm->pci_dev->device != 0x4324) {
3047 dprintk(KERN_INFO PFX "Ignoring additional 802.11 core.\n");
3048 continue;
3049 }
3050 }
3051 switch (core_rev) {
3052 case 2:
3053 case 4:
3054 case 5:
3055 case 6:
3056 case 7:
3057 case 9:
3058 break;
3059 default:
3060 printk(KERN_ERR PFX "Error: Unsupported 80211 core revision %u\n",
3061 core_rev);
3062 err = -ENODEV;
3063 goto out;
3064 }
3065 core->phy = &bcm->phy[i];
3066 core->phy->antenna_diversity = 0xffff;
3067 core->phy->savedpctlreg = 0xFFFF;
3068 core->phy->minlowsig[0] = 0xFFFF;
3069 core->phy->minlowsig[1] = 0xFFFF;
3070 core->phy->minlowsigpos[0] = 0;
3071 core->phy->minlowsigpos[1] = 0;
3072 spin_lock_init(&core->phy->lock);
3073 core->radio = &bcm->radio[i];
3074 core->radio->interfmode = BCM43xx_RADIO_INTERFMODE_AUTOWLAN;
3075 core->radio->channel = 0xFF;
3076 core->radio->initial_channel = 0xFF;
3077 core->radio->lofcal = 0xFFFF;
3078 core->radio->initval = 0xFFFF;
3079 core->radio->nrssi[0] = -1000;
3080 core->radio->nrssi[1] = -1000;
3081 core->dma = &bcm->dma[i];
3082 core->pio = &bcm->pio[i];
3083 break;
3084 case BCM43xx_COREID_CHIPCOMMON:
3085 printk(KERN_WARNING PFX "Multiple CHIPCOMMON cores found.\n");
3086 break;
3087 default:
3088 printk(KERN_WARNING PFX "Unknown core found (ID 0x%x)\n", core_id);
3089 }
3090 if (core) {
3091 core->flags |= BCM43xx_COREFLAG_AVAILABLE;
3092 core->id = core_id;
3093 core->rev = core_rev;
3094 core->index = current_core;
3095 }
3096 }
3097
3098 if (!(bcm->core_80211[0].flags & BCM43xx_COREFLAG_AVAILABLE)) {
3099 printk(KERN_ERR PFX "Error: No 80211 core found!\n");
3100 err = -ENODEV;
3101 goto out;
3102 }
3103
3104 err = bcm43xx_switch_core(bcm, &bcm->core_80211[0]);
3105
3106 assert(err == 0);
3107out:
3108 return err;
3109}
3110
3111static void bcm43xx_gen_bssid(struct bcm43xx_private *bcm)
3112{
3113 const u8 *mac = (const u8*)(bcm->net_dev->dev_addr);
3114 u8 *bssid = bcm->ieee->bssid;
3115
3116 switch (bcm->ieee->iw_mode) {
3117 case IW_MODE_ADHOC:
3118 random_ether_addr(bssid);
3119 break;
3120 case IW_MODE_MASTER:
3121 case IW_MODE_INFRA:
3122 case IW_MODE_REPEAT:
3123 case IW_MODE_SECOND:
3124 case IW_MODE_MONITOR:
3125 memcpy(bssid, mac, ETH_ALEN);
3126 break;
3127 default:
3128 assert(0);
3129 }
3130}
3131
3132static void bcm43xx_rate_memory_write(struct bcm43xx_private *bcm,
3133 u16 rate,
3134 int is_ofdm)
3135{
3136 u16 offset;
3137
3138 if (is_ofdm) {
3139 offset = 0x480;
3140 offset += (bcm43xx_plcp_get_ratecode_ofdm(rate) & 0x000F) * 2;
3141 }
3142 else {
3143 offset = 0x4C0;
3144 offset += (bcm43xx_plcp_get_ratecode_cck(rate) & 0x000F) * 2;
3145 }
3146 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, offset + 0x20,
3147 bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED, offset));
3148}
3149
3150static void bcm43xx_rate_memory_init(struct bcm43xx_private *bcm)
3151{
3152 switch (bcm->current_core->phy->type) {
3153 case BCM43xx_PHYTYPE_A:
3154 case BCM43xx_PHYTYPE_G:
3155 bcm43xx_rate_memory_write(bcm, IEEE80211_OFDM_RATE_6MB, 1);
3156 bcm43xx_rate_memory_write(bcm, IEEE80211_OFDM_RATE_12MB, 1);
3157 bcm43xx_rate_memory_write(bcm, IEEE80211_OFDM_RATE_18MB, 1);
3158 bcm43xx_rate_memory_write(bcm, IEEE80211_OFDM_RATE_24MB, 1);
3159 bcm43xx_rate_memory_write(bcm, IEEE80211_OFDM_RATE_36MB, 1);
3160 bcm43xx_rate_memory_write(bcm, IEEE80211_OFDM_RATE_48MB, 1);
3161 bcm43xx_rate_memory_write(bcm, IEEE80211_OFDM_RATE_54MB, 1);
3162 case BCM43xx_PHYTYPE_B:
3163 bcm43xx_rate_memory_write(bcm, IEEE80211_CCK_RATE_1MB, 0);
3164 bcm43xx_rate_memory_write(bcm, IEEE80211_CCK_RATE_2MB, 0);
3165 bcm43xx_rate_memory_write(bcm, IEEE80211_CCK_RATE_5MB, 0);
3166 bcm43xx_rate_memory_write(bcm, IEEE80211_CCK_RATE_11MB, 0);
3167 break;
3168 default:
3169 assert(0);
3170 }
3171}
3172
3173static void bcm43xx_wireless_core_cleanup(struct bcm43xx_private *bcm)
3174{
3175 bcm43xx_chip_cleanup(bcm);
3176 bcm43xx_pio_free(bcm);
3177 bcm43xx_dma_free(bcm);
3178
3179 bcm->current_core->flags &= ~ BCM43xx_COREFLAG_INITIALIZED;
3180}
3181
3182/* http://bcm-specs.sipsolutions.net/80211Init */
3183static int bcm43xx_wireless_core_init(struct bcm43xx_private *bcm)
3184{
3185 u32 ucodeflags;
3186 int err;
3187 u32 sbimconfiglow;
3188 u8 limit;
3189
3190 if (bcm->chip_rev < 5) {
3191 sbimconfiglow = bcm43xx_read32(bcm, BCM43xx_CIR_SBIMCONFIGLOW);
3192 sbimconfiglow &= ~ BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_MASK;
3193 sbimconfiglow &= ~ BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_MASK;
3194 if (bcm->bustype == BCM43xx_BUSTYPE_PCI)
3195 sbimconfiglow |= 0x32;
3196 else if (bcm->bustype == BCM43xx_BUSTYPE_SB)
3197 sbimconfiglow |= 0x53;
3198 else
3199 assert(0);
3200 bcm43xx_write32(bcm, BCM43xx_CIR_SBIMCONFIGLOW, sbimconfiglow);
3201 }
3202
3203 bcm43xx_phy_calibrate(bcm);
3204 err = bcm43xx_chip_init(bcm);
3205 if (err)
3206 goto out;
3207
3208 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0016, bcm->current_core->rev);
3209 ucodeflags = bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED, BCM43xx_UCODEFLAGS_OFFSET);
3210
3211 if (0 /*FIXME: which condition has to be used here? */)
3212 ucodeflags |= 0x00000010;
3213
3214 /* HW decryption needs to be set now */
3215 ucodeflags |= 0x40000000;
3216
3217 if (bcm->current_core->phy->type == BCM43xx_PHYTYPE_G) {
3218 ucodeflags |= BCM43xx_UCODEFLAG_UNKBGPHY;
3219 if (bcm->current_core->phy->rev == 1)
3220 ucodeflags |= BCM43xx_UCODEFLAG_UNKGPHY;
3221 if (bcm->sprom.boardflags & BCM43xx_BFL_PACTRL)
3222 ucodeflags |= BCM43xx_UCODEFLAG_UNKPACTRL;
3223 } else if (bcm->current_core->phy->type == BCM43xx_PHYTYPE_B) {
3224 ucodeflags |= BCM43xx_UCODEFLAG_UNKBGPHY;
3225 if ((bcm->current_core->phy->rev >= 2) &&
3226 (bcm->current_core->radio->version == 0x2050))
3227 ucodeflags &= ~BCM43xx_UCODEFLAG_UNKGPHY;
3228 }
3229
3230 if (ucodeflags != bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED,
3231 BCM43xx_UCODEFLAGS_OFFSET)) {
3232 bcm43xx_shm_write32(bcm, BCM43xx_SHM_SHARED,
3233 BCM43xx_UCODEFLAGS_OFFSET, ucodeflags);
3234 }
3235
3236 /* Short/Long Retry Limit.
3237 * The retry-limit is a 4-bit counter. Enforce this to avoid overflowing
3238 * the chip-internal counter.
3239 */
3240 limit = limit_value(modparam_short_retry, 0, 0xF);
3241 bcm43xx_shm_write32(bcm, BCM43xx_SHM_WIRELESS, 0x0006, limit);
3242 limit = limit_value(modparam_long_retry, 0, 0xF);
3243 bcm43xx_shm_write32(bcm, BCM43xx_SHM_WIRELESS, 0x0007, limit);
3244
3245 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0044, 3);
3246 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0046, 2);
3247
3248 bcm43xx_rate_memory_init(bcm);
3249
3250 /* Minimum Contention Window */
3251 if (bcm->current_core->phy->type == BCM43xx_PHYTYPE_B)
3252 bcm43xx_shm_write32(bcm, BCM43xx_SHM_WIRELESS, 0x0003, 0x0000001f);
3253 else
3254 bcm43xx_shm_write32(bcm, BCM43xx_SHM_WIRELESS, 0x0003, 0x0000000f);
3255 /* Maximum Contention Window */
3256 bcm43xx_shm_write32(bcm, BCM43xx_SHM_WIRELESS, 0x0004, 0x000003ff);
3257
3258 bcm43xx_gen_bssid(bcm);
3259 bcm43xx_write_mac_bssid_templates(bcm);
3260
3261 if (bcm->current_core->rev >= 5)
3262 bcm43xx_write16(bcm, 0x043C, 0x000C);
3263
3264 if (!bcm->pio_mode) {
3265 err = bcm43xx_dma_init(bcm);
3266 if (err)
3267 goto err_chip_cleanup;
3268 } else {
3269 err = bcm43xx_pio_init(bcm);
3270 if (err)
3271 goto err_chip_cleanup;
3272 }
3273 bcm43xx_write16(bcm, 0x0612, 0x0050);
3274 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0416, 0x0050);
3275 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0414, 0x01F4);
3276
3277 bcm43xx_mac_enable(bcm);
3278 bcm43xx_interrupt_enable(bcm, bcm->irq_savedstate);
3279
3280 bcm->current_core->flags |= BCM43xx_COREFLAG_INITIALIZED;
3281out:
3282 return err;
3283
3284err_chip_cleanup:
3285 bcm43xx_chip_cleanup(bcm);
3286 goto out;
3287}
3288
3289static int bcm43xx_chipset_attach(struct bcm43xx_private *bcm)
3290{
3291 int err;
3292 u16 pci_status;
3293
3294 err = bcm43xx_pctl_set_crystal(bcm, 1);
3295 if (err)
3296 goto out;
3297 bcm43xx_pci_read_config16(bcm, PCI_STATUS, &pci_status);
3298 bcm43xx_pci_write_config16(bcm, PCI_STATUS, pci_status & ~PCI_STATUS_SIG_TARGET_ABORT);
3299
3300out:
3301 return err;
3302}
3303
3304static void bcm43xx_chipset_detach(struct bcm43xx_private *bcm)
3305{
3306 bcm43xx_pctl_set_clock(bcm, BCM43xx_PCTL_CLK_SLOW);
3307 bcm43xx_pctl_set_crystal(bcm, 0);
3308}
3309
3310static inline void bcm43xx_pcicore_broadcast_value(struct bcm43xx_private *bcm,
3311 u32 address,
3312 u32 data)
3313{
3314 bcm43xx_write32(bcm, BCM43xx_PCICORE_BCAST_ADDR, address);
3315 bcm43xx_write32(bcm, BCM43xx_PCICORE_BCAST_DATA, data);
3316}
3317
3318static int bcm43xx_pcicore_commit_settings(struct bcm43xx_private *bcm)
3319{
3320 int err;
3321 struct bcm43xx_coreinfo *old_core;
3322
3323 old_core = bcm->current_core;
3324 err = bcm43xx_switch_core(bcm, &bcm->core_pci);
3325 if (err)
3326 goto out;
3327
3328 bcm43xx_pcicore_broadcast_value(bcm, 0xfd8, 0x00000000);
3329
3330 bcm43xx_switch_core(bcm, old_core);
3331 assert(err == 0);
3332out:
3333 return err;
3334}
3335
3336/* Make an I/O Core usable. "core_mask" is the bitmask of the cores to enable.
3337 * To enable core 0, pass a core_mask of 1<<0
3338 */
3339static int bcm43xx_setup_backplane_pci_connection(struct bcm43xx_private *bcm,
3340 u32 core_mask)
3341{
3342 u32 backplane_flag_nr;
3343 u32 value;
3344 struct bcm43xx_coreinfo *old_core;
3345 int err = 0;
3346
3347 value = bcm43xx_read32(bcm, BCM43xx_CIR_SBTPSFLAG);
3348 backplane_flag_nr = value & BCM43xx_BACKPLANE_FLAG_NR_MASK;
3349
3350 old_core = bcm->current_core;
3351 err = bcm43xx_switch_core(bcm, &bcm->core_pci);
3352 if (err)
3353 goto out;
3354
3355 if (bcm->core_pci.rev < 6) {
3356 value = bcm43xx_read32(bcm, BCM43xx_CIR_SBINTVEC);
3357 value |= (1 << backplane_flag_nr);
3358 bcm43xx_write32(bcm, BCM43xx_CIR_SBINTVEC, value);
3359 } else {
3360 err = bcm43xx_pci_read_config32(bcm, BCM43xx_PCICFG_ICR, &value);
3361 if (err) {
3362 printk(KERN_ERR PFX "Error: ICR setup failure!\n");
3363 goto out_switch_back;
3364 }
3365 value |= core_mask << 8;
3366 err = bcm43xx_pci_write_config32(bcm, BCM43xx_PCICFG_ICR, value);
3367 if (err) {
3368 printk(KERN_ERR PFX "Error: ICR setup failure!\n");
3369 goto out_switch_back;
3370 }
3371 }
3372
3373 value = bcm43xx_read32(bcm, BCM43xx_PCICORE_SBTOPCI2);
3374 value |= BCM43xx_SBTOPCI2_PREFETCH | BCM43xx_SBTOPCI2_BURST;
3375 bcm43xx_write32(bcm, BCM43xx_PCICORE_SBTOPCI2, value);
3376
3377 if (bcm->core_pci.rev < 5) {
3378 value = bcm43xx_read32(bcm, BCM43xx_CIR_SBIMCONFIGLOW);
3379 value |= (2 << BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_SHIFT)
3380 & BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_MASK;
3381 value |= (3 << BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_SHIFT)
3382 & BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_MASK;
3383 bcm43xx_write32(bcm, BCM43xx_CIR_SBIMCONFIGLOW, value);
3384 err = bcm43xx_pcicore_commit_settings(bcm);
3385 assert(err == 0);
3386 }
3387
3388out_switch_back:
3389 err = bcm43xx_switch_core(bcm, old_core);
3390out:
3391 return err;
3392}
3393
3394static void bcm43xx_softmac_init(struct bcm43xx_private *bcm)
3395{
3396 ieee80211softmac_start(bcm->net_dev);
3397}
3398
3399static void bcm43xx_periodic_work0_handler(void *d)
3400{
3401 struct bcm43xx_private *bcm = d;
3402 unsigned long flags;
3403 //TODO: unsigned int aci_average;
3404
3405 spin_lock_irqsave(&bcm->lock, flags);
3406
3407 if (bcm->current_core->phy->type == BCM43xx_PHYTYPE_G) {
3408 //FIXME: aci_average = bcm43xx_update_aci_average(bcm);
3409 if (bcm->current_core->radio->aci_enable && bcm->current_core->radio->aci_wlan_automatic) {
3410 bcm43xx_mac_suspend(bcm);
3411 if (!bcm->current_core->radio->aci_enable &&
3412 1 /*FIXME: We are not scanning? */) {
3413 /*FIXME: First add bcm43xx_update_aci_average() before
3414 * uncommenting this: */
3415 //if (bcm43xx_radio_aci_scan)
3416 // bcm43xx_radio_set_interference_mitigation(bcm,
3417 // BCM43xx_RADIO_INTERFMODE_MANUALWLAN);
3418 } else if (1/*FIXME*/) {
3419 //if ((aci_average > 1000) && !(bcm43xx_radio_aci_scan(bcm)))
3420 // bcm43xx_radio_set_interference_mitigation(bcm,
3421 // BCM43xx_RADIO_INTERFMODE_MANUALWLAN);
3422 }
3423 bcm43xx_mac_enable(bcm);
3424 } else if (bcm->current_core->radio->interfmode == BCM43xx_RADIO_INTERFMODE_NONWLAN) {
3425 if (bcm->current_core->phy->rev == 1) {
3426 //FIXME: implement rev1 workaround
3427 }
3428 }
3429 }
3430 bcm43xx_phy_xmitpower(bcm); //FIXME: unless scanning?
3431 //TODO for APHY (temperature?)
3432
3433 if (likely(!bcm->shutting_down)) {
3434 queue_delayed_work(bcm->workqueue, &bcm->periodic_work0,
3435 BCM43xx_PERIODIC_0_DELAY);
3436 }
3437 spin_unlock_irqrestore(&bcm->lock, flags);
3438}
3439
3440static void bcm43xx_periodic_work1_handler(void *d)
3441{
3442 struct bcm43xx_private *bcm = d;
3443 unsigned long flags;
3444
3445 spin_lock_irqsave(&bcm->lock, flags);
3446
3447 bcm43xx_phy_lo_mark_all_unused(bcm);
3448 if (bcm->sprom.boardflags & BCM43xx_BFL_RSSI) {
3449 bcm43xx_mac_suspend(bcm);
3450 bcm43xx_calc_nrssi_slope(bcm);
3451 bcm43xx_mac_enable(bcm);
3452 }
3453
3454 if (likely(!bcm->shutting_down)) {
3455 queue_delayed_work(bcm->workqueue, &bcm->periodic_work1,
3456 BCM43xx_PERIODIC_1_DELAY);
3457 }
3458 spin_unlock_irqrestore(&bcm->lock, flags);
3459}
3460
3461static void bcm43xx_periodic_work2_handler(void *d)
3462{
3463 struct bcm43xx_private *bcm = d;
3464 unsigned long flags;
3465
3466 spin_lock_irqsave(&bcm->lock, flags);
3467
3468 assert(bcm->current_core->phy->type == BCM43xx_PHYTYPE_G);
3469 assert(bcm->current_core->phy->rev >= 2);
3470
3471 bcm43xx_mac_suspend(bcm);
3472 bcm43xx_phy_lo_g_measure(bcm);
3473 bcm43xx_mac_enable(bcm);
3474
3475 if (likely(!bcm->shutting_down)) {
3476 queue_delayed_work(bcm->workqueue, &bcm->periodic_work2,
3477 BCM43xx_PERIODIC_2_DELAY);
3478 }
3479 spin_unlock_irqrestore(&bcm->lock, flags);
3480}
3481
3482static void bcm43xx_periodic_work3_handler(void *d)
3483{
3484 struct bcm43xx_private *bcm = d;
3485 unsigned long flags;
3486
3487 spin_lock_irqsave(&bcm->lock, flags);
3488
3489 /* Update device statistics. */
3490 bcm43xx_calculate_link_quality(bcm);
3491
3492 if (likely(!bcm->shutting_down)) {
3493 queue_delayed_work(bcm->workqueue, &bcm->periodic_work3,
3494 BCM43xx_PERIODIC_3_DELAY);
3495 }
3496 spin_unlock_irqrestore(&bcm->lock, flags);
3497}
3498
3499/* Delete all periodic tasks and make
3500 * sure they are not running any longer
3501 */
3502static void bcm43xx_periodic_tasks_delete(struct bcm43xx_private *bcm)
3503{
3504 cancel_delayed_work(&bcm->periodic_work0);
3505 cancel_delayed_work(&bcm->periodic_work1);
3506 cancel_delayed_work(&bcm->periodic_work2);
3507 cancel_delayed_work(&bcm->periodic_work3);
3508 flush_workqueue(bcm->workqueue);
3509}
3510
3511/* Setup all periodic tasks. */
3512static void bcm43xx_periodic_tasks_setup(struct bcm43xx_private *bcm)
3513{
3514 INIT_WORK(&bcm->periodic_work0, bcm43xx_periodic_work0_handler, bcm);
3515 INIT_WORK(&bcm->periodic_work1, bcm43xx_periodic_work1_handler, bcm);
3516 INIT_WORK(&bcm->periodic_work2, bcm43xx_periodic_work2_handler, bcm);
3517 INIT_WORK(&bcm->periodic_work3, bcm43xx_periodic_work3_handler, bcm);
3518
3519 /* Periodic task 0: Delay ~15sec */
3520 queue_delayed_work(bcm->workqueue, &bcm->periodic_work0,
3521 BCM43xx_PERIODIC_0_DELAY);
3522
3523 /* Periodic task 1: Delay ~60sec */
3524 queue_delayed_work(bcm->workqueue, &bcm->periodic_work1,
3525 BCM43xx_PERIODIC_1_DELAY);
3526
3527 /* Periodic task 2: Delay ~120sec */
3528 if (bcm->current_core->phy->type == BCM43xx_PHYTYPE_G &&
3529 bcm->current_core->phy->rev >= 2) {
3530 queue_delayed_work(bcm->workqueue, &bcm->periodic_work2,
3531 BCM43xx_PERIODIC_2_DELAY);
3532 }
3533
3534 /* Periodic task 3: Delay ~30sec */
3535 queue_delayed_work(bcm->workqueue, &bcm->periodic_work3,
3536 BCM43xx_PERIODIC_3_DELAY);
3537}
3538
3539static void bcm43xx_security_init(struct bcm43xx_private *bcm)
3540{
3541 bcm->security_offset = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED,
3542 0x0056) * 2;
3543 bcm43xx_clear_keys(bcm);
3544}
3545
3546/* This is the opposite of bcm43xx_init_board() */
3547static void bcm43xx_free_board(struct bcm43xx_private *bcm)
3548{
3549 int i, err;
3550 unsigned long flags;
3551
3552 spin_lock_irqsave(&bcm->lock, flags);
3553 bcm->initialized = 0;
3554 bcm->shutting_down = 1;
3555 spin_unlock_irqrestore(&bcm->lock, flags);
3556
3557 bcm43xx_periodic_tasks_delete(bcm);
3558
3559 for (i = 0; i < BCM43xx_MAX_80211_CORES; i++) {
3560 if (!(bcm->core_80211[i].flags & BCM43xx_COREFLAG_AVAILABLE))
3561 continue;
3562 if (!(bcm->core_80211[i].flags & BCM43xx_COREFLAG_INITIALIZED))
3563 continue;
3564
3565 err = bcm43xx_switch_core(bcm, &bcm->core_80211[i]);
3566 assert(err == 0);
3567 bcm43xx_wireless_core_cleanup(bcm);
3568 }
3569
3570 bcm43xx_pctl_set_crystal(bcm, 0);
3571
3572 spin_lock_irqsave(&bcm->lock, flags);
3573 bcm->shutting_down = 0;
3574 spin_unlock_irqrestore(&bcm->lock, flags);
3575}
3576
3577static int bcm43xx_init_board(struct bcm43xx_private *bcm)
3578{
3579 int i, err;
3580 int num_80211_cores;
3581 int connect_phy;
3582 unsigned long flags;
3583
3584 might_sleep();
3585
3586 spin_lock_irqsave(&bcm->lock, flags);
3587 bcm->initialized = 0;
3588 bcm->shutting_down = 0;
3589 spin_unlock_irqrestore(&bcm->lock, flags);
3590
3591 err = bcm43xx_pctl_set_crystal(bcm, 1);
3592 if (err)
3593 goto out;
3594 err = bcm43xx_pctl_init(bcm);
3595 if (err)
3596 goto err_crystal_off;
3597 err = bcm43xx_pctl_set_clock(bcm, BCM43xx_PCTL_CLK_FAST);
3598 if (err)
3599 goto err_crystal_off;
3600
3601 tasklet_enable(&bcm->isr_tasklet);
3602 num_80211_cores = bcm43xx_num_80211_cores(bcm);
3603 for (i = 0; i < num_80211_cores; i++) {
3604 err = bcm43xx_switch_core(bcm, &bcm->core_80211[i]);
3605 assert(err != -ENODEV);
3606 if (err)
3607 goto err_80211_unwind;
3608
3609 /* Enable the selected wireless core.
3610 * Connect PHY only on the first core.
3611 */
3612 if (!bcm43xx_core_enabled(bcm)) {
3613 if (num_80211_cores == 1) {
3614 connect_phy = bcm->current_core->phy->connected;
3615 } else {
3616 if (i == 0)
3617 connect_phy = 1;
3618 else
3619 connect_phy = 0;
3620 }
3621 bcm43xx_wireless_core_reset(bcm, connect_phy);
3622 }
3623
3624 if (i != 0)
3625 bcm43xx_wireless_core_mark_inactive(bcm, &bcm->core_80211[0]);
3626
3627 err = bcm43xx_wireless_core_init(bcm);
3628 if (err)
3629 goto err_80211_unwind;
3630
3631 if (i != 0) {
3632 bcm43xx_mac_suspend(bcm);
3633 bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
3634 bcm43xx_radio_turn_off(bcm);
3635 }
3636 }
3637 bcm->active_80211_core = &bcm->core_80211[0];
3638 if (num_80211_cores >= 2) {
3639 bcm43xx_switch_core(bcm, &bcm->core_80211[0]);
3640 bcm43xx_mac_enable(bcm);
3641 }
3642 bcm43xx_macfilter_clear(bcm, BCM43xx_MACFILTER_ASSOC);
3643 bcm43xx_macfilter_set(bcm, BCM43xx_MACFILTER_SELF, (u8 *)(bcm->net_dev->dev_addr));
3644 dprintk(KERN_INFO PFX "80211 cores initialized\n");
3645 bcm43xx_security_init(bcm);
3646 bcm43xx_softmac_init(bcm);
3647
3648 bcm43xx_pctl_set_clock(bcm, BCM43xx_PCTL_CLK_DYNAMIC);
3649
3650 spin_lock_irqsave(&bcm->lock, flags);
3651 bcm->initialized = 1;
3652 spin_unlock_irqrestore(&bcm->lock, flags);
3653
3654 if (bcm->current_core->radio->initial_channel != 0xFF) {
3655 bcm43xx_mac_suspend(bcm);
3656 bcm43xx_radio_selectchannel(bcm, bcm->current_core->radio->initial_channel, 0);
3657 bcm43xx_mac_enable(bcm);
3658 }
3659 bcm43xx_periodic_tasks_setup(bcm);
3660
3661 assert(err == 0);
3662out:
3663 return err;
3664
3665err_80211_unwind:
3666 tasklet_disable(&bcm->isr_tasklet);
3667 /* unwind all 80211 initialization */
3668 for (i = 0; i < num_80211_cores; i++) {
3669 if (!(bcm->core_80211[i].flags & BCM43xx_COREFLAG_INITIALIZED))
3670 continue;
3671 bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
3672 bcm43xx_wireless_core_cleanup(bcm);
3673 }
3674err_crystal_off:
3675 bcm43xx_pctl_set_crystal(bcm, 0);
3676 goto out;
3677}
3678
3679static void bcm43xx_detach_board(struct bcm43xx_private *bcm)
3680{
3681 struct pci_dev *pci_dev = bcm->pci_dev;
3682 int i;
3683
3684 bcm43xx_chipset_detach(bcm);
3685 /* Do _not_ access the chip, after it is detached. */
3686 iounmap(bcm->mmio_addr);
3687
3688 pci_release_regions(pci_dev);
3689 pci_disable_device(pci_dev);
3690
3691 /* Free allocated structures/fields */
3692 for (i = 0; i < BCM43xx_MAX_80211_CORES; i++) {
3693 kfree(bcm->phy[i]._lo_pairs);
3694 if (bcm->phy[i].dyn_tssi_tbl)
3695 kfree(bcm->phy[i].tssi2dbm);
3696 }
3697}
3698
3699static int bcm43xx_read_phyinfo(struct bcm43xx_private *bcm)
3700{
3701 u16 value;
3702 u8 phy_version;
3703 u8 phy_type;
3704 u8 phy_rev;
3705 int phy_rev_ok = 1;
3706 void *p;
3707
3708 value = bcm43xx_read16(bcm, BCM43xx_MMIO_PHY_VER);
3709
3710 phy_version = (value & 0xF000) >> 12;
3711 phy_type = (value & 0x0F00) >> 8;
3712 phy_rev = (value & 0x000F);
3713
3714 dprintk(KERN_INFO PFX "Detected PHY: Version: %x, Type %x, Revision %x\n",
3715 phy_version, phy_type, phy_rev);
3716
3717 switch (phy_type) {
3718 case BCM43xx_PHYTYPE_A:
3719 if (phy_rev >= 4)
3720 phy_rev_ok = 0;
3721 /*FIXME: We need to switch the ieee->modulation, etc.. flags,
3722 * if we switch 80211 cores after init is done.
3723 * As we do not implement on the fly switching between
3724 * wireless cores, I will leave this as a future task.
3725 */
3726 bcm->ieee->modulation = IEEE80211_OFDM_MODULATION;
3727 bcm->ieee->mode = IEEE_A;
3728 bcm->ieee->freq_band = IEEE80211_52GHZ_BAND |
3729 IEEE80211_24GHZ_BAND;
3730 break;
3731 case BCM43xx_PHYTYPE_B:
3732 if (phy_rev != 2 && phy_rev != 4 && phy_rev != 6 && phy_rev != 7)
3733 phy_rev_ok = 0;
3734 bcm->ieee->modulation = IEEE80211_CCK_MODULATION;
3735 bcm->ieee->mode = IEEE_B;
3736 bcm->ieee->freq_band = IEEE80211_24GHZ_BAND;
3737 break;
3738 case BCM43xx_PHYTYPE_G:
3739 if (phy_rev > 7)
3740 phy_rev_ok = 0;
3741 bcm->ieee->modulation = IEEE80211_OFDM_MODULATION |
3742 IEEE80211_CCK_MODULATION;
3743 bcm->ieee->mode = IEEE_G;
3744 bcm->ieee->freq_band = IEEE80211_24GHZ_BAND;
3745 break;
3746 default:
3747 printk(KERN_ERR PFX "Error: Unknown PHY Type %x\n",
3748 phy_type);
3749 return -ENODEV;
3750 };
3751 if (!phy_rev_ok) {
3752 printk(KERN_WARNING PFX "Invalid PHY Revision %x\n",
3753 phy_rev);
3754 }
3755
3756 bcm->current_core->phy->version = phy_version;
3757 bcm->current_core->phy->type = phy_type;
3758 bcm->current_core->phy->rev = phy_rev;
3759 if ((phy_type == BCM43xx_PHYTYPE_B) || (phy_type == BCM43xx_PHYTYPE_G)) {
3760 p = kzalloc(sizeof(struct bcm43xx_lopair) * BCM43xx_LO_COUNT,
3761 GFP_KERNEL);
3762 if (!p)
3763 return -ENOMEM;
3764 bcm->current_core->phy->_lo_pairs = p;
3765 }
3766
3767 return 0;
3768}
3769
3770static int bcm43xx_attach_board(struct bcm43xx_private *bcm)
3771{
3772 struct pci_dev *pci_dev = bcm->pci_dev;
3773 struct net_device *net_dev = bcm->net_dev;
3774 int err;
3775 int i;
3776 void __iomem *ioaddr;
3777 unsigned long mmio_start, mmio_end, mmio_flags, mmio_len;
3778 int num_80211_cores;
3779 u32 coremask;
3780
3781 err = pci_enable_device(pci_dev);
3782 if (err) {
3783 printk(KERN_ERR PFX "unable to wake up pci device (%i)\n", err);
3784 err = -ENODEV;
3785 goto out;
3786 }
3787
3788 mmio_start = pci_resource_start(pci_dev, 0);
3789 mmio_end = pci_resource_end(pci_dev, 0);
3790 mmio_flags = pci_resource_flags(pci_dev, 0);
3791 mmio_len = pci_resource_len(pci_dev, 0);
3792
3793 /* make sure PCI base addr is MMIO */
3794 if (!(mmio_flags & IORESOURCE_MEM)) {
3795 printk(KERN_ERR PFX
3796 "%s, region #0 not an MMIO resource, aborting\n",
3797 pci_name(pci_dev));
3798 err = -ENODEV;
3799 goto err_pci_disable;
3800 }
3801//FIXME: Why is this check disabled for BCM947XX? What is the IO_SIZE there?
3802#ifndef CONFIG_BCM947XX
3803 if (mmio_len != BCM43xx_IO_SIZE) {
3804 printk(KERN_ERR PFX
3805 "%s: invalid PCI mem region size(s), aborting\n",
3806 pci_name(pci_dev));
3807 err = -ENODEV;
3808 goto err_pci_disable;
3809 }
3810#endif
3811
65f3f191 3812 err = pci_request_regions(pci_dev, KBUILD_MODNAME);
f222313a
JL
3813 if (err) {
3814 printk(KERN_ERR PFX
3815 "could not access PCI resources (%i)\n", err);
3816 goto err_pci_disable;
3817 }
3818
3819 /* enable PCI bus-mastering */
3820 pci_set_master(pci_dev);
3821
3822 /* ioremap MMIO region */
3823 ioaddr = ioremap(mmio_start, mmio_len);
3824 if (!ioaddr) {
3825 printk(KERN_ERR PFX "%s: cannot remap MMIO, aborting\n",
3826 pci_name(pci_dev));
3827 err = -EIO;
3828 goto err_pci_release;
3829 }
3830
3831 net_dev->base_addr = (unsigned long)ioaddr;
3832 bcm->mmio_addr = ioaddr;
3833 bcm->mmio_len = mmio_len;
3834
3835 bcm43xx_pci_read_config16(bcm, PCI_SUBSYSTEM_VENDOR_ID,
3836 &bcm->board_vendor);
3837 bcm43xx_pci_read_config16(bcm, PCI_SUBSYSTEM_ID,
3838 &bcm->board_type);
3839 bcm43xx_pci_read_config16(bcm, PCI_REVISION_ID,
3840 &bcm->board_revision);
3841
3842 err = bcm43xx_chipset_attach(bcm);
3843 if (err)
3844 goto err_iounmap;
3845 err = bcm43xx_pctl_init(bcm);
3846 if (err)
3847 goto err_chipset_detach;
3848 err = bcm43xx_probe_cores(bcm);
3849 if (err)
3850 goto err_chipset_detach;
3851
3852 num_80211_cores = bcm43xx_num_80211_cores(bcm);
3853
3854 /* Attach all IO cores to the backplane. */
3855 coremask = 0;
3856 for (i = 0; i < num_80211_cores; i++)
3857 coremask |= (1 << bcm->core_80211[i].index);
3858 //FIXME: Also attach some non80211 cores?
3859 err = bcm43xx_setup_backplane_pci_connection(bcm, coremask);
3860 if (err) {
3861 printk(KERN_ERR PFX "Backplane->PCI connection failed!\n");
3862 goto err_chipset_detach;
3863 }
3864
3865 err = bcm43xx_read_sprom(bcm);
3866 if (err)
3867 goto err_chipset_detach;
3868 err = bcm43xx_leds_init(bcm);
3869 if (err)
3870 goto err_chipset_detach;
3871
3872 for (i = 0; i < num_80211_cores; i++) {
3873 err = bcm43xx_switch_core(bcm, &bcm->core_80211[i]);
3874 assert(err != -ENODEV);
3875 if (err)
3876 goto err_80211_unwind;
3877
3878 /* Enable the selected wireless core.
3879 * Connect PHY only on the first core.
3880 */
3881 bcm43xx_wireless_core_reset(bcm, (i == 0));
3882
3883 err = bcm43xx_read_phyinfo(bcm);
3884 if (err && (i == 0))
3885 goto err_80211_unwind;
3886
3887 err = bcm43xx_read_radioinfo(bcm);
3888 if (err && (i == 0))
3889 goto err_80211_unwind;
3890
3891 err = bcm43xx_validate_chip(bcm);
3892 if (err && (i == 0))
3893 goto err_80211_unwind;
3894
3895 bcm43xx_radio_turn_off(bcm);
3896 err = bcm43xx_phy_init_tssi2dbm_table(bcm);
3897 if (err)
3898 goto err_80211_unwind;
3899 bcm43xx_wireless_core_disable(bcm);
3900 }
3901 bcm43xx_pctl_set_crystal(bcm, 0);
3902
3903 /* Set the MAC address in the networking subsystem */
3904 if (bcm->current_core->phy->type == BCM43xx_PHYTYPE_A)
3905 memcpy(bcm->net_dev->dev_addr, bcm->sprom.et1macaddr, 6);
3906 else
3907 memcpy(bcm->net_dev->dev_addr, bcm->sprom.il0macaddr, 6);
3908
3909 bcm43xx_geo_init(bcm);
3910
3911 snprintf(bcm->nick, IW_ESSID_MAX_SIZE,
3912 "Broadcom %04X", bcm->chip_id);
3913
3914 assert(err == 0);
3915out:
3916 return err;
3917
3918err_80211_unwind:
3919 for (i = 0; i < BCM43xx_MAX_80211_CORES; i++) {
3920 kfree(bcm->phy[i]._lo_pairs);
3921 if (bcm->phy[i].dyn_tssi_tbl)
3922 kfree(bcm->phy[i].tssi2dbm);
3923 }
3924err_chipset_detach:
3925 bcm43xx_chipset_detach(bcm);
3926err_iounmap:
3927 iounmap(bcm->mmio_addr);
3928err_pci_release:
3929 pci_release_regions(pci_dev);
3930err_pci_disable:
3931 pci_disable_device(pci_dev);
3932 goto out;
3933}
3934
3935static inline
3936s8 bcm43xx_rssi_postprocess(struct bcm43xx_private *bcm, u8 in_rssi,
3937 int ofdm, int adjust_2053, int adjust_2050)
3938{
3939 s32 tmp;
3940
3941 switch (bcm->current_core->radio->version) {
3942 case 0x2050:
3943 if (ofdm) {
3944 tmp = in_rssi;
3945 if (tmp > 127)
3946 tmp -= 256;
3947 tmp *= 73;
3948 tmp /= 64;
3949 if (adjust_2050)
3950 tmp += 25;
3951 else
3952 tmp -= 3;
3953 } else {
3954 if (bcm->sprom.boardflags & BCM43xx_BFL_RSSI) {
3955 if (in_rssi > 63)
3956 in_rssi = 63;
3957 tmp = bcm->current_core->radio->nrssi_lt[in_rssi];
3958 tmp = 31 - tmp;
3959 tmp *= -131;
3960 tmp /= 128;
3961 tmp -= 57;
3962 } else {
3963 tmp = in_rssi;
3964 tmp = 31 - tmp;
3965 tmp *= -149;
3966 tmp /= 128;
3967 tmp -= 68;
3968 }
3969 if (bcm->current_core->phy->type == BCM43xx_PHYTYPE_G &&
3970 adjust_2050)
3971 tmp += 25;
3972 }
3973 break;
3974 case 0x2060:
3975 if (in_rssi > 127)
3976 tmp = in_rssi - 256;
3977 else
3978 tmp = in_rssi;
3979 break;
3980 default:
3981 tmp = in_rssi;
3982 tmp -= 11;
3983 tmp *= 103;
3984 tmp /= 64;
3985 if (adjust_2053)
3986 tmp -= 109;
3987 else
3988 tmp -= 83;
3989 }
3990
3991 return (s8)tmp;
3992}
3993
3994static inline
3995s8 bcm43xx_rssinoise_postprocess(struct bcm43xx_private *bcm, u8 in_rssi)
3996{
3997 s8 ret;
3998
3999 if (bcm->current_core->phy->type == BCM43xx_PHYTYPE_A) {
4000 //TODO: Incomplete specs.
4001 ret = 0;
4002 } else
4003 ret = bcm43xx_rssi_postprocess(bcm, in_rssi, 0, 1, 1);
4004
4005 return ret;
4006}
4007
4008static inline
4009int bcm43xx_rx_packet(struct bcm43xx_private *bcm,
4010 struct sk_buff *skb,
4011 struct ieee80211_rx_stats *stats)
4012{
4013 int err;
4014
4015 err = ieee80211_rx(bcm->ieee, skb, stats);
4016 if (unlikely(err == 0))
4017 return -EINVAL;
4018 return 0;
4019}
4020
4021int fastcall bcm43xx_rx(struct bcm43xx_private *bcm,
4022 struct sk_buff *skb,
4023 struct bcm43xx_rxhdr *rxhdr)
4024{
4025 struct bcm43xx_plcp_hdr4 *plcp;
4026 struct ieee80211_rx_stats stats;
4027 struct ieee80211_hdr_4addr *wlhdr;
4028 u16 frame_ctl;
4029 int is_packet_for_us = 0;
4030 int err = -EINVAL;
4031 const u16 rxflags1 = le16_to_cpu(rxhdr->flags1);
4032 const u16 rxflags2 = le16_to_cpu(rxhdr->flags2);
4033 const u16 rxflags3 = le16_to_cpu(rxhdr->flags3);
4034 const int is_ofdm = !!(rxflags1 & BCM43xx_RXHDR_FLAGS1_OFDM);
4035
4036 if (rxflags2 & BCM43xx_RXHDR_FLAGS2_TYPE2FRAME) {
4037 plcp = (struct bcm43xx_plcp_hdr4 *)(skb->data + 2);
4038 /* Skip two unknown bytes and the PLCP header. */
4039 skb_pull(skb, 2 + sizeof(struct bcm43xx_plcp_hdr6));
4040 } else {
4041 plcp = (struct bcm43xx_plcp_hdr4 *)(skb->data);
4042 /* Skip the PLCP header. */
4043 skb_pull(skb, sizeof(struct bcm43xx_plcp_hdr6));
4044 }
4045 /* The SKB contains the PAYLOAD (wireless header + data)
4046 * at this point. The FCS at the end is stripped.
4047 */
4048
4049 memset(&stats, 0, sizeof(stats));
4050 stats.mac_time = le16_to_cpu(rxhdr->mactime);
4051 stats.rssi = bcm43xx_rssi_postprocess(bcm, rxhdr->rssi, is_ofdm,
4052 !!(rxflags1 & BCM43xx_RXHDR_FLAGS1_2053RSSIADJ),
4053 !!(rxflags3 & BCM43xx_RXHDR_FLAGS3_2050RSSIADJ));
4054 stats.signal = rxhdr->signal_quality; //FIXME
4055//TODO stats.noise =
4056 stats.rate = bcm43xx_plcp_get_bitrate(plcp, is_ofdm);
4057//printk("RX ofdm %d, rate == %u\n", is_ofdm, stats.rate);
4058 stats.received_channel = bcm->current_core->radio->channel;
4059//TODO stats.control =
4060 stats.mask = IEEE80211_STATMASK_SIGNAL |
4061//TODO IEEE80211_STATMASK_NOISE |
4062 IEEE80211_STATMASK_RATE |
4063 IEEE80211_STATMASK_RSSI;
4064 if (bcm->current_core->phy->type == BCM43xx_PHYTYPE_A)
4065 stats.freq = IEEE80211_52GHZ_BAND;
4066 else
4067 stats.freq = IEEE80211_24GHZ_BAND;
4068 stats.len = skb->len;
4069
4070 bcm->stats.last_rx = jiffies;
4071 if (bcm->ieee->iw_mode == IW_MODE_MONITOR)
4072 return bcm43xx_rx_packet(bcm, skb, &stats);
4073
4074 wlhdr = (struct ieee80211_hdr_4addr *)(skb->data);
4075
4076 switch (bcm->ieee->iw_mode) {
4077 case IW_MODE_ADHOC:
4078 if (memcmp(wlhdr->addr1, bcm->net_dev->dev_addr, ETH_ALEN) == 0 ||
4079 memcmp(wlhdr->addr3, bcm->ieee->bssid, ETH_ALEN) == 0 ||
4080 is_broadcast_ether_addr(wlhdr->addr1) ||
4081 is_multicast_ether_addr(wlhdr->addr1) ||
4082 bcm->net_dev->flags & IFF_PROMISC)
4083 is_packet_for_us = 1;
4084 break;
4085 case IW_MODE_INFRA:
4086 default:
4087 /* When receiving multicast or broadcast packets, filter out
4088 the packets we send ourself; we shouldn't see those */
4089 if (memcmp(wlhdr->addr3, bcm->ieee->bssid, ETH_ALEN) == 0 ||
4090 memcmp(wlhdr->addr1, bcm->net_dev->dev_addr, ETH_ALEN) == 0 ||
4091 (memcmp(wlhdr->addr3, bcm->net_dev->dev_addr, ETH_ALEN) &&
4092 (is_broadcast_ether_addr(wlhdr->addr1) ||
4093 is_multicast_ether_addr(wlhdr->addr1) ||
4094 bcm->net_dev->flags & IFF_PROMISC)))
4095 is_packet_for_us = 1;
4096 break;
4097 }
4098
4099 frame_ctl = le16_to_cpu(wlhdr->frame_ctl);
f222313a
JL
4100 if ((frame_ctl & IEEE80211_FCTL_PROTECTED) && !bcm->ieee->host_decrypt) {
4101 frame_ctl &= ~IEEE80211_FCTL_PROTECTED;
4102 wlhdr->frame_ctl = cpu_to_le16(frame_ctl);
4103 /* trim IV and ICV */
4104 /* FIXME: this must be done only for WEP encrypted packets */
4105 if (skb->len < 32) {
4106 dprintkl(KERN_ERR PFX "RX packet dropped (PROTECTED flag "
4107 "set and length < 32)\n");
4108 return -EINVAL;
4109 } else {
4110 memmove(skb->data + 4, skb->data, 24);
4111 skb_pull(skb, 4);
4112 skb_trim(skb, skb->len - 4);
4113 stats.len -= 8;
4114 }
ea72ab22 4115 wlhdr = (struct ieee80211_hdr_4addr *)(skb->data);
f222313a
JL
4116 }
4117
4118 switch (WLAN_FC_GET_TYPE(frame_ctl)) {
4119 case IEEE80211_FTYPE_MGMT:
ea72ab22 4120 ieee80211_rx_mgt(bcm->ieee, wlhdr, &stats);
f222313a
JL
4121 break;
4122 case IEEE80211_FTYPE_DATA:
4123 if (is_packet_for_us)
4124 err = bcm43xx_rx_packet(bcm, skb, &stats);
4125 break;
4126 case IEEE80211_FTYPE_CTL:
4127 break;
4128 default:
4129 assert(0);
4130 return -EINVAL;
4131 }
4132
4133 return err;
4134}
4135
4136/* Do the Hardware IO operations to send the txb */
4137static inline int bcm43xx_tx(struct bcm43xx_private *bcm,
4138 struct ieee80211_txb *txb)
4139{
4140 int err = -ENODEV;
4141
4142 if (bcm->pio_mode)
4143 err = bcm43xx_pio_transfer_txb(bcm, txb);
4144 else
ea72ab22 4145 err = bcm43xx_dma_tx(bcm, txb);
f222313a
JL
4146
4147 return err;
4148}
4149
4150static void bcm43xx_ieee80211_set_chan(struct net_device *net_dev,
4151 u8 channel)
4152{
4153 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
4154 unsigned long flags;
4155
4156 spin_lock_irqsave(&bcm->lock, flags);
4157 bcm43xx_mac_suspend(bcm);
4158 bcm43xx_radio_selectchannel(bcm, channel, 0);
4159 bcm43xx_mac_enable(bcm);
4160 spin_unlock_irqrestore(&bcm->lock, flags);
4161}
4162
4163/* set_security() callback in struct ieee80211_device */
4164static void bcm43xx_ieee80211_set_security(struct net_device *net_dev,
4165 struct ieee80211_security *sec)
4166{
4167 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
4168 struct ieee80211_security *secinfo = &bcm->ieee->sec;
4169 unsigned long flags;
4170 int keyidx;
4171
4172 dprintk(KERN_INFO PFX "set security called\n");
4173
4174 spin_lock_irqsave(&bcm->lock, flags);
4175
4176 for (keyidx = 0; keyidx<WEP_KEYS; keyidx++)
4177 if (sec->flags & (1<<keyidx)) {
4178 secinfo->encode_alg[keyidx] = sec->encode_alg[keyidx];
4179 secinfo->key_sizes[keyidx] = sec->key_sizes[keyidx];
4180 memcpy(secinfo->keys[keyidx], sec->keys[keyidx], SCM_KEY_LEN);
4181 }
4182
4183 if (sec->flags & SEC_ACTIVE_KEY) {
4184 secinfo->active_key = sec->active_key;
4185 dprintk(KERN_INFO PFX " .active_key = %d\n", sec->active_key);
4186 }
4187 if (sec->flags & SEC_UNICAST_GROUP) {
4188 secinfo->unicast_uses_group = sec->unicast_uses_group;
4189 dprintk(KERN_INFO PFX " .unicast_uses_group = %d\n", sec->unicast_uses_group);
4190 }
4191 if (sec->flags & SEC_LEVEL) {
4192 secinfo->level = sec->level;
4193 dprintk(KERN_INFO PFX " .level = %d\n", sec->level);
4194 }
4195 if (sec->flags & SEC_ENABLED) {
4196 secinfo->enabled = sec->enabled;
4197 dprintk(KERN_INFO PFX " .enabled = %d\n", sec->enabled);
4198 }
4199 if (sec->flags & SEC_ENCRYPT) {
4200 secinfo->encrypt = sec->encrypt;
4201 dprintk(KERN_INFO PFX " .encrypt = %d\n", sec->encrypt);
4202 }
4203 if (bcm->initialized && !bcm->ieee->host_encrypt) {
4204 if (secinfo->enabled) {
4205 /* upload WEP keys to hardware */
4206 char null_address[6] = { 0 };
4207 u8 algorithm = 0;
4208 for (keyidx = 0; keyidx<WEP_KEYS; keyidx++) {
4209 if (!(sec->flags & (1<<keyidx)))
4210 continue;
4211 switch (sec->encode_alg[keyidx]) {
4212 case SEC_ALG_NONE: algorithm = BCM43xx_SEC_ALGO_NONE; break;
4213 case SEC_ALG_WEP:
4214 algorithm = BCM43xx_SEC_ALGO_WEP;
4215 if (secinfo->key_sizes[keyidx] == 13)
4216 algorithm = BCM43xx_SEC_ALGO_WEP104;
4217 break;
4218 case SEC_ALG_TKIP:
4219 FIXME();
4220 algorithm = BCM43xx_SEC_ALGO_TKIP;
4221 break;
4222 case SEC_ALG_CCMP:
4223 FIXME();
4224 algorithm = BCM43xx_SEC_ALGO_AES;
4225 break;
4226 default:
4227 assert(0);
4228 break;
4229 }
4230 bcm43xx_key_write(bcm, keyidx, algorithm, sec->keys[keyidx], secinfo->key_sizes[keyidx], &null_address[0]);
4231 bcm->key[keyidx].enabled = 1;
4232 bcm->key[keyidx].algorithm = algorithm;
4233 }
4234 } else
4235 bcm43xx_clear_keys(bcm);
4236 }
4237 spin_unlock_irqrestore(&bcm->lock, flags);
4238}
4239
4240/* hard_start_xmit() callback in struct ieee80211_device */
4241static int bcm43xx_ieee80211_hard_start_xmit(struct ieee80211_txb *txb,
4242 struct net_device *net_dev,
4243 int pri)
4244{
4245 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
4246 int err = -ENODEV;
4247 unsigned long flags;
4248
4249 spin_lock_irqsave(&bcm->lock, flags);
4250 if (likely(bcm->initialized))
4251 err = bcm43xx_tx(bcm, txb);
4252 spin_unlock_irqrestore(&bcm->lock, flags);
4253
4254 return err;
4255}
4256
4257static struct net_device_stats * bcm43xx_net_get_stats(struct net_device *net_dev)
4258{
4259 return &(bcm43xx_priv(net_dev)->ieee->stats);
4260}
4261
4262static void bcm43xx_net_tx_timeout(struct net_device *net_dev)
4263{
4264 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
4265
4266 bcm43xx_controller_restart(bcm, "TX timeout");
4267}
4268
4269#ifdef CONFIG_NET_POLL_CONTROLLER
4270static void bcm43xx_net_poll_controller(struct net_device *net_dev)
4271{
4272 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
4273 unsigned long flags;
4274
4275 local_irq_save(flags);
4276 bcm43xx_interrupt_handler(bcm->irq, bcm, NULL);
4277 local_irq_restore(flags);
4278}
4279#endif /* CONFIG_NET_POLL_CONTROLLER */
4280
4281static int bcm43xx_net_open(struct net_device *net_dev)
4282{
4283 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
4284
4285 return bcm43xx_init_board(bcm);
4286}
4287
4288static int bcm43xx_net_stop(struct net_device *net_dev)
4289{
4290 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
4291
4292 ieee80211softmac_stop(net_dev);
4293 bcm43xx_disable_interrupts_sync(bcm, NULL);
4294 bcm43xx_free_board(bcm);
4295
4296 return 0;
4297}
4298
4299static void bcm43xx_init_private(struct bcm43xx_private *bcm,
4300 struct net_device *net_dev,
4301 struct pci_dev *pci_dev,
4302 struct workqueue_struct *wq)
4303{
4304 bcm->ieee = netdev_priv(net_dev);
4305 bcm->softmac = ieee80211_priv(net_dev);
4306 bcm->softmac->set_channel = bcm43xx_ieee80211_set_chan;
4307 bcm->workqueue = wq;
4308
4309#ifdef DEBUG_ENABLE_MMIO_PRINT
4310 bcm43xx_mmioprint_initial(bcm, 1);
4311#else
4312 bcm43xx_mmioprint_initial(bcm, 0);
4313#endif
4314#ifdef DEBUG_ENABLE_PCILOG
4315 bcm43xx_pciprint_initial(bcm, 1);
4316#else
4317 bcm43xx_pciprint_initial(bcm, 0);
4318#endif
4319
4320 bcm->irq_savedstate = BCM43xx_IRQ_INITIAL;
4321 bcm->pci_dev = pci_dev;
4322 bcm->net_dev = net_dev;
4323 if (modparam_bad_frames_preempt)
4324 bcm->bad_frames_preempt = 1;
4325 spin_lock_init(&bcm->lock);
4326 tasklet_init(&bcm->isr_tasklet,
4327 (void (*)(unsigned long))bcm43xx_interrupt_tasklet,
4328 (unsigned long)bcm);
4329 tasklet_disable_nosync(&bcm->isr_tasklet);
4330 if (modparam_pio) {
4331 bcm->pio_mode = 1;
4332 } else {
4333 if (pci_set_dma_mask(pci_dev, DMA_30BIT_MASK) == 0) {
4334 bcm->pio_mode = 0;
4335 } else {
4336 printk(KERN_WARNING PFX "DMA not supported. Falling back to PIO.\n");
4337 bcm->pio_mode = 1;
4338 }
4339 }
4340 bcm->rts_threshold = BCM43xx_DEFAULT_RTS_THRESHOLD;
4341
4342 /* default to sw encryption for now */
4343 bcm->ieee->host_build_iv = 0;
4344 bcm->ieee->host_encrypt = 1;
4345 bcm->ieee->host_decrypt = 1;
4346
4347 bcm->ieee->iw_mode = BCM43xx_INITIAL_IWMODE;
4348 bcm->ieee->tx_headroom = sizeof(struct bcm43xx_txhdr);
4349 bcm->ieee->set_security = bcm43xx_ieee80211_set_security;
4350 bcm->ieee->hard_start_xmit = bcm43xx_ieee80211_hard_start_xmit;
4351}
4352
4353static int __devinit bcm43xx_init_one(struct pci_dev *pdev,
4354 const struct pci_device_id *ent)
4355{
4356 struct net_device *net_dev;
4357 struct bcm43xx_private *bcm;
4358 struct workqueue_struct *wq;
4359 int err;
4360
4361#ifdef CONFIG_BCM947XX
4362 if ((pdev->bus->number == 0) && (pdev->device != 0x0800))
4363 return -ENODEV;
4364#endif
4365
4366#ifdef DEBUG_SINGLE_DEVICE_ONLY
4367 if (strcmp(pci_name(pdev), DEBUG_SINGLE_DEVICE_ONLY))
4368 return -ENODEV;
4369#endif
4370
4371 net_dev = alloc_ieee80211softmac(sizeof(*bcm));
4372 if (!net_dev) {
4373 printk(KERN_ERR PFX
4374 "could not allocate ieee80211 device %s\n",
4375 pci_name(pdev));
4376 err = -ENOMEM;
4377 goto out;
4378 }
4379 /* initialize the net_device struct */
4380 SET_MODULE_OWNER(net_dev);
4381 SET_NETDEV_DEV(net_dev, &pdev->dev);
4382
4383 net_dev->open = bcm43xx_net_open;
4384 net_dev->stop = bcm43xx_net_stop;
4385 net_dev->get_stats = bcm43xx_net_get_stats;
4386 net_dev->tx_timeout = bcm43xx_net_tx_timeout;
4387#ifdef CONFIG_NET_POLL_CONTROLLER
4388 net_dev->poll_controller = bcm43xx_net_poll_controller;
4389#endif
4390 net_dev->wireless_handlers = &bcm43xx_wx_handlers_def;
4391 net_dev->irq = pdev->irq;
f222313a
JL
4392
4393 /* initialize the bcm43xx_private struct */
4394 bcm = bcm43xx_priv(net_dev);
4395 memset(bcm, 0, sizeof(*bcm));
65f3f191 4396 wq = create_workqueue(KBUILD_MODNAME "_wq");
f222313a
JL
4397 if (!wq) {
4398 err = -ENOMEM;
4399 goto err_free_netdev;
4400 }
4401 bcm43xx_init_private(bcm, net_dev, pdev, wq);
4402
4403 pci_set_drvdata(pdev, net_dev);
4404
4405 err = bcm43xx_attach_board(bcm);
4406 if (err)
4407 goto err_destroy_wq;
4408
4409 err = register_netdev(net_dev);
4410 if (err) {
4411 printk(KERN_ERR PFX "Cannot register net device, "
4412 "aborting.\n");
4413 err = -ENOMEM;
4414 goto err_detach_board;
4415 }
4416
4417 bcm43xx_debugfs_add_device(bcm);
4418
4419 assert(err == 0);
4420out:
4421 return err;
4422
4423err_detach_board:
4424 bcm43xx_detach_board(bcm);
4425err_destroy_wq:
4426 destroy_workqueue(wq);
4427err_free_netdev:
4428 free_ieee80211softmac(net_dev);
4429 goto out;
4430}
4431
4432static void __devexit bcm43xx_remove_one(struct pci_dev *pdev)
4433{
4434 struct net_device *net_dev = pci_get_drvdata(pdev);
4435 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
4436
4437 bcm43xx_debugfs_remove_device(bcm);
4438 unregister_netdev(net_dev);
4439 bcm43xx_detach_board(bcm);
4440 assert(bcm->ucode == NULL);
4441 destroy_workqueue(bcm->workqueue);
4442 free_ieee80211softmac(net_dev);
4443}
4444
4445/* Hard-reset the chip. Do not call this directly.
4446 * Use bcm43xx_controller_restart()
4447 */
4448static void bcm43xx_chip_reset(void *_bcm)
4449{
4450 struct bcm43xx_private *bcm = _bcm;
4451 struct net_device *net_dev = bcm->net_dev;
4452 struct pci_dev *pci_dev = bcm->pci_dev;
4453 struct workqueue_struct *wq = bcm->workqueue;
4454 int err;
4455 int was_initialized = bcm->initialized;
4456
4457 netif_stop_queue(bcm->net_dev);
4458 tasklet_disable(&bcm->isr_tasklet);
4459
4460 bcm->firmware_norelease = 1;
4461 if (was_initialized)
4462 bcm43xx_free_board(bcm);
4463 bcm->firmware_norelease = 0;
4464 bcm43xx_detach_board(bcm);
4465 bcm43xx_init_private(bcm, net_dev, pci_dev, wq);
4466 err = bcm43xx_attach_board(bcm);
4467 if (err)
4468 goto failure;
4469 if (was_initialized) {
4470 err = bcm43xx_init_board(bcm);
4471 if (err)
4472 goto failure;
4473 }
4474 netif_wake_queue(bcm->net_dev);
4475 printk(KERN_INFO PFX "Controller restarted\n");
4476
4477 return;
4478failure:
4479 printk(KERN_ERR PFX "Controller restart failed\n");
4480}
4481
4482/* Hard-reset the chip.
4483 * This can be called from interrupt or process context.
4484 * Make sure to _not_ re-enable device interrupts after this has been called.
4485*/
4486void bcm43xx_controller_restart(struct bcm43xx_private *bcm, const char *reason)
4487{
4488 bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
4489 printk(KERN_ERR PFX "Controller RESET (%s) ...\n", reason);
4490 INIT_WORK(&bcm->restart_work, bcm43xx_chip_reset, bcm);
4491 queue_work(bcm->workqueue, &bcm->restart_work);
4492}
4493
4494#ifdef CONFIG_PM
4495
4496static int bcm43xx_suspend(struct pci_dev *pdev, pm_message_t state)
4497{
4498 struct net_device *net_dev = pci_get_drvdata(pdev);
4499 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
4500 unsigned long flags;
4501 int try_to_shutdown = 0, err;
4502
4503 dprintk(KERN_INFO PFX "Suspending...\n");
4504
4505 spin_lock_irqsave(&bcm->lock, flags);
4506 bcm->was_initialized = bcm->initialized;
4507 if (bcm->initialized)
4508 try_to_shutdown = 1;
4509 spin_unlock_irqrestore(&bcm->lock, flags);
4510
4511 netif_device_detach(net_dev);
4512 if (try_to_shutdown) {
4513 ieee80211softmac_stop(net_dev);
4514 err = bcm43xx_disable_interrupts_sync(bcm, &bcm->irq_savedstate);
4515 if (unlikely(err)) {
4516 dprintk(KERN_ERR PFX "Suspend failed.\n");
4517 return -EAGAIN;
4518 }
4519 bcm->firmware_norelease = 1;
4520 bcm43xx_free_board(bcm);
4521 bcm->firmware_norelease = 0;
4522 }
4523 bcm43xx_chipset_detach(bcm);
4524
4525 pci_save_state(pdev);
4526 pci_disable_device(pdev);
4527 pci_set_power_state(pdev, pci_choose_state(pdev, state));
4528
4529 dprintk(KERN_INFO PFX "Device suspended.\n");
4530
4531 return 0;
4532}
4533
4534static int bcm43xx_resume(struct pci_dev *pdev)
4535{
4536 struct net_device *net_dev = pci_get_drvdata(pdev);
4537 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
4538 int err = 0;
4539
4540 dprintk(KERN_INFO PFX "Resuming...\n");
4541
4542 pci_set_power_state(pdev, 0);
4543 pci_enable_device(pdev);
4544 pci_restore_state(pdev);
4545
4546 bcm43xx_chipset_attach(bcm);
4547 if (bcm->was_initialized) {
4548 bcm->irq_savedstate = BCM43xx_IRQ_INITIAL;
4549 err = bcm43xx_init_board(bcm);
4550 }
4551 if (err) {
4552 printk(KERN_ERR PFX "Resume failed!\n");
4553 return err;
4554 }
4555
4556 netif_device_attach(net_dev);
4557
4558 /*FIXME: This should be handled by softmac instead. */
4559 schedule_work(&bcm->softmac->associnfo.work);
4560
4561 dprintk(KERN_INFO PFX "Device resumed.\n");
4562
4563 return 0;
4564}
4565
4566#endif /* CONFIG_PM */
4567
4568static struct pci_driver bcm43xx_pci_driver = {
65f3f191 4569 .name = KBUILD_MODNAME,
f222313a
JL
4570 .id_table = bcm43xx_pci_tbl,
4571 .probe = bcm43xx_init_one,
4572 .remove = __devexit_p(bcm43xx_remove_one),
4573#ifdef CONFIG_PM
4574 .suspend = bcm43xx_suspend,
4575 .resume = bcm43xx_resume,
4576#endif /* CONFIG_PM */
4577};
4578
4579static int __init bcm43xx_init(void)
4580{
65f3f191 4581 printk(KERN_INFO KBUILD_MODNAME " driver\n");
f222313a
JL
4582 bcm43xx_debugfs_init();
4583 return pci_register_driver(&bcm43xx_pci_driver);
4584}
4585
4586static void __exit bcm43xx_exit(void)
4587{
4588 pci_unregister_driver(&bcm43xx_pci_driver);
4589 bcm43xx_debugfs_exit();
4590}
4591
4592module_init(bcm43xx_init)
4593module_exit(bcm43xx_exit)
4594
4595/* vim: set ts=8 sw=8 sts=8: */
This page took 0.189317 seconds and 5 git commands to generate.