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