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