[PATCH] bcm43xx: rewrite and simplify the periodic task handling.
[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];
ab4977f8 2942 core->radio->interfmode = BCM43xx_RADIO_INTERFMODE_NONE;
f222313a
JL
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
ab4977f8 3264static void bcm43xx_periodic_every120sec(struct bcm43xx_private *bcm)
f222313a 3265{
ab4977f8 3266 struct bcm43xx_phyinfo *phy = bcm->current_core->phy;
f222313a 3267
ab4977f8
MB
3268 if (phy->type != BCM43xx_PHYTYPE_G || phy->rev < 2)
3269 return;
f222313a 3270
ab4977f8
MB
3271 bcm43xx_mac_suspend(bcm);
3272 bcm43xx_phy_lo_g_measure(bcm);
3273 bcm43xx_mac_enable(bcm);
f222313a
JL
3274}
3275
ab4977f8 3276static void bcm43xx_periodic_every60sec(struct bcm43xx_private *bcm)
f222313a 3277{
f222313a
JL
3278 bcm43xx_phy_lo_mark_all_unused(bcm);
3279 if (bcm->sprom.boardflags & BCM43xx_BFL_RSSI) {
3280 bcm43xx_mac_suspend(bcm);
3281 bcm43xx_calc_nrssi_slope(bcm);
3282 bcm43xx_mac_enable(bcm);
3283 }
f222313a
JL
3284}
3285
ab4977f8 3286static void bcm43xx_periodic_every30sec(struct bcm43xx_private *bcm)
f222313a 3287{
ab4977f8
MB
3288 /* Update device statistics. */
3289 bcm43xx_calculate_link_quality(bcm);
3290}
f222313a 3291
ab4977f8
MB
3292static void bcm43xx_periodic_every15sec(struct bcm43xx_private *bcm)
3293{
3294 struct bcm43xx_phyinfo *phy = bcm->current_core->phy;
3295 struct bcm43xx_radioinfo *radio = bcm->current_core->radio;
f222313a 3296
ab4977f8
MB
3297 if (phy->type == BCM43xx_PHYTYPE_G) {
3298 //TODO: update_aci_moving_average
3299 if (radio->aci_enable && radio->aci_wlan_automatic) {
3300 bcm43xx_mac_suspend(bcm);
3301 if (!radio->aci_enable && 1 /*TODO: not scanning? */) {
3302 if (0 /*TODO: bunch of conditions*/) {
3303 bcm43xx_radio_set_interference_mitigation(bcm,
3304 BCM43xx_RADIO_INTERFMODE_MANUALWLAN);
3305 }
3306 } else if (1/*TODO*/) {
3307 /*
3308 if ((aci_average > 1000) && !(bcm43xx_radio_aci_scan(bcm))) {
3309 bcm43xx_radio_set_interference_mitigation(bcm,
3310 BCM43xx_RADIO_INTERFMODE_NONE);
3311 }
3312 */
3313 }
3314 bcm43xx_mac_enable(bcm);
3315 } else if (radio->interfmode == BCM43xx_RADIO_INTERFMODE_NONWLAN &&
3316 phy->rev == 1) {
3317 //TODO: implement rev1 workaround
3318 }
f222313a 3319 }
ab4977f8
MB
3320 bcm43xx_phy_xmitpower(bcm); //FIXME: unless scanning?
3321 //TODO for APHY (temperature?)
f222313a
JL
3322}
3323
ab4977f8 3324static void bcm43xx_periodic_task_handler(unsigned long d)
f222313a 3325{
ab4977f8 3326 struct bcm43xx_private *bcm = (struct bcm43xx_private *)d;
f222313a 3327 unsigned long flags;
ab4977f8 3328 unsigned int state;
f222313a
JL
3329
3330 spin_lock_irqsave(&bcm->lock, flags);
3331
ab4977f8
MB
3332 assert(bcm->initialized);
3333 state = bcm->periodic_state;
3334 if (state % 8 == 0)
3335 bcm43xx_periodic_every120sec(bcm);
3336 if (state % 4 == 0)
3337 bcm43xx_periodic_every60sec(bcm);
3338 if (state % 2 == 0)
3339 bcm43xx_periodic_every30sec(bcm);
3340 bcm43xx_periodic_every15sec(bcm);
3341 bcm->periodic_state = state + 1;
3342
3343 mod_timer(&bcm->periodic_tasks, jiffies + (HZ * 15));
f222313a 3344
f222313a
JL
3345 spin_unlock_irqrestore(&bcm->lock, flags);
3346}
3347
f222313a
JL
3348static void bcm43xx_periodic_tasks_delete(struct bcm43xx_private *bcm)
3349{
ab4977f8 3350 del_timer_sync(&bcm->periodic_tasks);
f222313a
JL
3351}
3352
f222313a
JL
3353static void bcm43xx_periodic_tasks_setup(struct bcm43xx_private *bcm)
3354{
ab4977f8 3355 struct timer_list *timer = &(bcm->periodic_tasks);
f222313a 3356
ab4977f8
MB
3357 setup_timer(timer,
3358 bcm43xx_periodic_task_handler,
3359 (unsigned long)bcm);
3360 timer->expires = jiffies;
3361 add_timer(timer);
f222313a
JL
3362}
3363
3364static void bcm43xx_security_init(struct bcm43xx_private *bcm)
3365{
3366 bcm->security_offset = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED,
3367 0x0056) * 2;
3368 bcm43xx_clear_keys(bcm);
3369}
3370
3371/* This is the opposite of bcm43xx_init_board() */
3372static void bcm43xx_free_board(struct bcm43xx_private *bcm)
3373{
3374 int i, err;
3375 unsigned long flags;
3376
ab4977f8
MB
3377 bcm43xx_periodic_tasks_delete(bcm);
3378
f222313a
JL
3379 spin_lock_irqsave(&bcm->lock, flags);
3380 bcm->initialized = 0;
3381 bcm->shutting_down = 1;
3382 spin_unlock_irqrestore(&bcm->lock, flags);
3383
f222313a
JL
3384 for (i = 0; i < BCM43xx_MAX_80211_CORES; i++) {
3385 if (!(bcm->core_80211[i].flags & BCM43xx_COREFLAG_AVAILABLE))
3386 continue;
3387 if (!(bcm->core_80211[i].flags & BCM43xx_COREFLAG_INITIALIZED))
3388 continue;
3389
3390 err = bcm43xx_switch_core(bcm, &bcm->core_80211[i]);
3391 assert(err == 0);
3392 bcm43xx_wireless_core_cleanup(bcm);
3393 }
3394
3395 bcm43xx_pctl_set_crystal(bcm, 0);
3396
3397 spin_lock_irqsave(&bcm->lock, flags);
3398 bcm->shutting_down = 0;
3399 spin_unlock_irqrestore(&bcm->lock, flags);
3400}
3401
3402static int bcm43xx_init_board(struct bcm43xx_private *bcm)
3403{
3404 int i, err;
3405 int num_80211_cores;
3406 int connect_phy;
3407 unsigned long flags;
3408
3409 might_sleep();
3410
3411 spin_lock_irqsave(&bcm->lock, flags);
3412 bcm->initialized = 0;
3413 bcm->shutting_down = 0;
3414 spin_unlock_irqrestore(&bcm->lock, flags);
3415
3416 err = bcm43xx_pctl_set_crystal(bcm, 1);
3417 if (err)
3418 goto out;
3419 err = bcm43xx_pctl_init(bcm);
3420 if (err)
3421 goto err_crystal_off;
3422 err = bcm43xx_pctl_set_clock(bcm, BCM43xx_PCTL_CLK_FAST);
3423 if (err)
3424 goto err_crystal_off;
3425
3426 tasklet_enable(&bcm->isr_tasklet);
3427 num_80211_cores = bcm43xx_num_80211_cores(bcm);
3428 for (i = 0; i < num_80211_cores; i++) {
3429 err = bcm43xx_switch_core(bcm, &bcm->core_80211[i]);
3430 assert(err != -ENODEV);
3431 if (err)
3432 goto err_80211_unwind;
3433
3434 /* Enable the selected wireless core.
3435 * Connect PHY only on the first core.
3436 */
3437 if (!bcm43xx_core_enabled(bcm)) {
3438 if (num_80211_cores == 1) {
3439 connect_phy = bcm->current_core->phy->connected;
3440 } else {
3441 if (i == 0)
3442 connect_phy = 1;
3443 else
3444 connect_phy = 0;
3445 }
3446 bcm43xx_wireless_core_reset(bcm, connect_phy);
3447 }
3448
3449 if (i != 0)
3450 bcm43xx_wireless_core_mark_inactive(bcm, &bcm->core_80211[0]);
3451
3452 err = bcm43xx_wireless_core_init(bcm);
3453 if (err)
3454 goto err_80211_unwind;
3455
3456 if (i != 0) {
3457 bcm43xx_mac_suspend(bcm);
3458 bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
3459 bcm43xx_radio_turn_off(bcm);
3460 }
3461 }
3462 bcm->active_80211_core = &bcm->core_80211[0];
3463 if (num_80211_cores >= 2) {
3464 bcm43xx_switch_core(bcm, &bcm->core_80211[0]);
3465 bcm43xx_mac_enable(bcm);
3466 }
3467 bcm43xx_macfilter_clear(bcm, BCM43xx_MACFILTER_ASSOC);
3468 bcm43xx_macfilter_set(bcm, BCM43xx_MACFILTER_SELF, (u8 *)(bcm->net_dev->dev_addr));
3469 dprintk(KERN_INFO PFX "80211 cores initialized\n");
3470 bcm43xx_security_init(bcm);
3471 bcm43xx_softmac_init(bcm);
3472
3473 bcm43xx_pctl_set_clock(bcm, BCM43xx_PCTL_CLK_DYNAMIC);
3474
3475 spin_lock_irqsave(&bcm->lock, flags);
3476 bcm->initialized = 1;
3477 spin_unlock_irqrestore(&bcm->lock, flags);
3478
3479 if (bcm->current_core->radio->initial_channel != 0xFF) {
3480 bcm43xx_mac_suspend(bcm);
3481 bcm43xx_radio_selectchannel(bcm, bcm->current_core->radio->initial_channel, 0);
3482 bcm43xx_mac_enable(bcm);
3483 }
3484 bcm43xx_periodic_tasks_setup(bcm);
3485
3486 assert(err == 0);
3487out:
3488 return err;
3489
3490err_80211_unwind:
3491 tasklet_disable(&bcm->isr_tasklet);
3492 /* unwind all 80211 initialization */
3493 for (i = 0; i < num_80211_cores; i++) {
3494 if (!(bcm->core_80211[i].flags & BCM43xx_COREFLAG_INITIALIZED))
3495 continue;
3496 bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
3497 bcm43xx_wireless_core_cleanup(bcm);
3498 }
3499err_crystal_off:
3500 bcm43xx_pctl_set_crystal(bcm, 0);
3501 goto out;
3502}
3503
3504static void bcm43xx_detach_board(struct bcm43xx_private *bcm)
3505{
3506 struct pci_dev *pci_dev = bcm->pci_dev;
3507 int i;
3508
3509 bcm43xx_chipset_detach(bcm);
3510 /* Do _not_ access the chip, after it is detached. */
3511 iounmap(bcm->mmio_addr);
3512
3513 pci_release_regions(pci_dev);
3514 pci_disable_device(pci_dev);
3515
3516 /* Free allocated structures/fields */
3517 for (i = 0; i < BCM43xx_MAX_80211_CORES; i++) {
3518 kfree(bcm->phy[i]._lo_pairs);
3519 if (bcm->phy[i].dyn_tssi_tbl)
3520 kfree(bcm->phy[i].tssi2dbm);
3521 }
3522}
3523
3524static int bcm43xx_read_phyinfo(struct bcm43xx_private *bcm)
3525{
3526 u16 value;
3527 u8 phy_version;
3528 u8 phy_type;
3529 u8 phy_rev;
3530 int phy_rev_ok = 1;
3531 void *p;
3532
3533 value = bcm43xx_read16(bcm, BCM43xx_MMIO_PHY_VER);
3534
3535 phy_version = (value & 0xF000) >> 12;
3536 phy_type = (value & 0x0F00) >> 8;
3537 phy_rev = (value & 0x000F);
3538
3539 dprintk(KERN_INFO PFX "Detected PHY: Version: %x, Type %x, Revision %x\n",
3540 phy_version, phy_type, phy_rev);
3541
3542 switch (phy_type) {
3543 case BCM43xx_PHYTYPE_A:
3544 if (phy_rev >= 4)
3545 phy_rev_ok = 0;
3546 /*FIXME: We need to switch the ieee->modulation, etc.. flags,
3547 * if we switch 80211 cores after init is done.
3548 * As we do not implement on the fly switching between
3549 * wireless cores, I will leave this as a future task.
3550 */
3551 bcm->ieee->modulation = IEEE80211_OFDM_MODULATION;
3552 bcm->ieee->mode = IEEE_A;
3553 bcm->ieee->freq_band = IEEE80211_52GHZ_BAND |
3554 IEEE80211_24GHZ_BAND;
3555 break;
3556 case BCM43xx_PHYTYPE_B:
3557 if (phy_rev != 2 && phy_rev != 4 && phy_rev != 6 && phy_rev != 7)
3558 phy_rev_ok = 0;
3559 bcm->ieee->modulation = IEEE80211_CCK_MODULATION;
3560 bcm->ieee->mode = IEEE_B;
3561 bcm->ieee->freq_band = IEEE80211_24GHZ_BAND;
3562 break;
3563 case BCM43xx_PHYTYPE_G:
3564 if (phy_rev > 7)
3565 phy_rev_ok = 0;
3566 bcm->ieee->modulation = IEEE80211_OFDM_MODULATION |
3567 IEEE80211_CCK_MODULATION;
3568 bcm->ieee->mode = IEEE_G;
3569 bcm->ieee->freq_band = IEEE80211_24GHZ_BAND;
3570 break;
3571 default:
3572 printk(KERN_ERR PFX "Error: Unknown PHY Type %x\n",
3573 phy_type);
3574 return -ENODEV;
3575 };
3576 if (!phy_rev_ok) {
3577 printk(KERN_WARNING PFX "Invalid PHY Revision %x\n",
3578 phy_rev);
3579 }
3580
3581 bcm->current_core->phy->version = phy_version;
3582 bcm->current_core->phy->type = phy_type;
3583 bcm->current_core->phy->rev = phy_rev;
3584 if ((phy_type == BCM43xx_PHYTYPE_B) || (phy_type == BCM43xx_PHYTYPE_G)) {
3585 p = kzalloc(sizeof(struct bcm43xx_lopair) * BCM43xx_LO_COUNT,
3586 GFP_KERNEL);
3587 if (!p)
3588 return -ENOMEM;
3589 bcm->current_core->phy->_lo_pairs = p;
3590 }
3591
3592 return 0;
3593}
3594
3595static int bcm43xx_attach_board(struct bcm43xx_private *bcm)
3596{
3597 struct pci_dev *pci_dev = bcm->pci_dev;
3598 struct net_device *net_dev = bcm->net_dev;
3599 int err;
3600 int i;
3601 void __iomem *ioaddr;
3602 unsigned long mmio_start, mmio_end, mmio_flags, mmio_len;
3603 int num_80211_cores;
3604 u32 coremask;
3605
3606 err = pci_enable_device(pci_dev);
3607 if (err) {
3608 printk(KERN_ERR PFX "unable to wake up pci device (%i)\n", err);
3609 err = -ENODEV;
3610 goto out;
3611 }
3612
3613 mmio_start = pci_resource_start(pci_dev, 0);
3614 mmio_end = pci_resource_end(pci_dev, 0);
3615 mmio_flags = pci_resource_flags(pci_dev, 0);
3616 mmio_len = pci_resource_len(pci_dev, 0);
3617
3618 /* make sure PCI base addr is MMIO */
3619 if (!(mmio_flags & IORESOURCE_MEM)) {
3620 printk(KERN_ERR PFX
3621 "%s, region #0 not an MMIO resource, aborting\n",
3622 pci_name(pci_dev));
3623 err = -ENODEV;
3624 goto err_pci_disable;
3625 }
3626//FIXME: Why is this check disabled for BCM947XX? What is the IO_SIZE there?
3627#ifndef CONFIG_BCM947XX
3628 if (mmio_len != BCM43xx_IO_SIZE) {
3629 printk(KERN_ERR PFX
3630 "%s: invalid PCI mem region size(s), aborting\n",
3631 pci_name(pci_dev));
3632 err = -ENODEV;
3633 goto err_pci_disable;
3634 }
3635#endif
3636
65f3f191 3637 err = pci_request_regions(pci_dev, KBUILD_MODNAME);
f222313a
JL
3638 if (err) {
3639 printk(KERN_ERR PFX
3640 "could not access PCI resources (%i)\n", err);
3641 goto err_pci_disable;
3642 }
3643
3644 /* enable PCI bus-mastering */
3645 pci_set_master(pci_dev);
3646
3647 /* ioremap MMIO region */
3648 ioaddr = ioremap(mmio_start, mmio_len);
3649 if (!ioaddr) {
3650 printk(KERN_ERR PFX "%s: cannot remap MMIO, aborting\n",
3651 pci_name(pci_dev));
3652 err = -EIO;
3653 goto err_pci_release;
3654 }
3655
3656 net_dev->base_addr = (unsigned long)ioaddr;
3657 bcm->mmio_addr = ioaddr;
3658 bcm->mmio_len = mmio_len;
3659
3660 bcm43xx_pci_read_config16(bcm, PCI_SUBSYSTEM_VENDOR_ID,
3661 &bcm->board_vendor);
3662 bcm43xx_pci_read_config16(bcm, PCI_SUBSYSTEM_ID,
3663 &bcm->board_type);
3664 bcm43xx_pci_read_config16(bcm, PCI_REVISION_ID,
3665 &bcm->board_revision);
3666
3667 err = bcm43xx_chipset_attach(bcm);
3668 if (err)
3669 goto err_iounmap;
3670 err = bcm43xx_pctl_init(bcm);
3671 if (err)
3672 goto err_chipset_detach;
3673 err = bcm43xx_probe_cores(bcm);
3674 if (err)
3675 goto err_chipset_detach;
3676
3677 num_80211_cores = bcm43xx_num_80211_cores(bcm);
3678
3679 /* Attach all IO cores to the backplane. */
3680 coremask = 0;
3681 for (i = 0; i < num_80211_cores; i++)
3682 coremask |= (1 << bcm->core_80211[i].index);
3683 //FIXME: Also attach some non80211 cores?
3684 err = bcm43xx_setup_backplane_pci_connection(bcm, coremask);
3685 if (err) {
3686 printk(KERN_ERR PFX "Backplane->PCI connection failed!\n");
3687 goto err_chipset_detach;
3688 }
3689
3690 err = bcm43xx_read_sprom(bcm);
3691 if (err)
3692 goto err_chipset_detach;
3693 err = bcm43xx_leds_init(bcm);
3694 if (err)
3695 goto err_chipset_detach;
3696
3697 for (i = 0; i < num_80211_cores; i++) {
3698 err = bcm43xx_switch_core(bcm, &bcm->core_80211[i]);
3699 assert(err != -ENODEV);
3700 if (err)
3701 goto err_80211_unwind;
3702
3703 /* Enable the selected wireless core.
3704 * Connect PHY only on the first core.
3705 */
3706 bcm43xx_wireless_core_reset(bcm, (i == 0));
3707
3708 err = bcm43xx_read_phyinfo(bcm);
3709 if (err && (i == 0))
3710 goto err_80211_unwind;
3711
3712 err = bcm43xx_read_radioinfo(bcm);
3713 if (err && (i == 0))
3714 goto err_80211_unwind;
3715
3716 err = bcm43xx_validate_chip(bcm);
3717 if (err && (i == 0))
3718 goto err_80211_unwind;
3719
3720 bcm43xx_radio_turn_off(bcm);
3721 err = bcm43xx_phy_init_tssi2dbm_table(bcm);
3722 if (err)
3723 goto err_80211_unwind;
3724 bcm43xx_wireless_core_disable(bcm);
3725 }
3726 bcm43xx_pctl_set_crystal(bcm, 0);
3727
3728 /* Set the MAC address in the networking subsystem */
3729 if (bcm->current_core->phy->type == BCM43xx_PHYTYPE_A)
3730 memcpy(bcm->net_dev->dev_addr, bcm->sprom.et1macaddr, 6);
3731 else
3732 memcpy(bcm->net_dev->dev_addr, bcm->sprom.il0macaddr, 6);
3733
3734 bcm43xx_geo_init(bcm);
3735
3736 snprintf(bcm->nick, IW_ESSID_MAX_SIZE,
3737 "Broadcom %04X", bcm->chip_id);
3738
3739 assert(err == 0);
3740out:
3741 return err;
3742
3743err_80211_unwind:
3744 for (i = 0; i < BCM43xx_MAX_80211_CORES; i++) {
3745 kfree(bcm->phy[i]._lo_pairs);
3746 if (bcm->phy[i].dyn_tssi_tbl)
3747 kfree(bcm->phy[i].tssi2dbm);
3748 }
3749err_chipset_detach:
3750 bcm43xx_chipset_detach(bcm);
3751err_iounmap:
3752 iounmap(bcm->mmio_addr);
3753err_pci_release:
3754 pci_release_regions(pci_dev);
3755err_pci_disable:
3756 pci_disable_device(pci_dev);
3757 goto out;
3758}
3759
3760static inline
3761s8 bcm43xx_rssi_postprocess(struct bcm43xx_private *bcm, u8 in_rssi,
3762 int ofdm, int adjust_2053, int adjust_2050)
3763{
3764 s32 tmp;
3765
3766 switch (bcm->current_core->radio->version) {
3767 case 0x2050:
3768 if (ofdm) {
3769 tmp = in_rssi;
3770 if (tmp > 127)
3771 tmp -= 256;
3772 tmp *= 73;
3773 tmp /= 64;
3774 if (adjust_2050)
3775 tmp += 25;
3776 else
3777 tmp -= 3;
3778 } else {
3779 if (bcm->sprom.boardflags & BCM43xx_BFL_RSSI) {
3780 if (in_rssi > 63)
3781 in_rssi = 63;
3782 tmp = bcm->current_core->radio->nrssi_lt[in_rssi];
3783 tmp = 31 - tmp;
3784 tmp *= -131;
3785 tmp /= 128;
3786 tmp -= 57;
3787 } else {
3788 tmp = in_rssi;
3789 tmp = 31 - tmp;
3790 tmp *= -149;
3791 tmp /= 128;
3792 tmp -= 68;
3793 }
3794 if (bcm->current_core->phy->type == BCM43xx_PHYTYPE_G &&
3795 adjust_2050)
3796 tmp += 25;
3797 }
3798 break;
3799 case 0x2060:
3800 if (in_rssi > 127)
3801 tmp = in_rssi - 256;
3802 else
3803 tmp = in_rssi;
3804 break;
3805 default:
3806 tmp = in_rssi;
3807 tmp -= 11;
3808 tmp *= 103;
3809 tmp /= 64;
3810 if (adjust_2053)
3811 tmp -= 109;
3812 else
3813 tmp -= 83;
3814 }
3815
3816 return (s8)tmp;
3817}
3818
3819static inline
3820s8 bcm43xx_rssinoise_postprocess(struct bcm43xx_private *bcm, u8 in_rssi)
3821{
3822 s8 ret;
3823
3824 if (bcm->current_core->phy->type == BCM43xx_PHYTYPE_A) {
3825 //TODO: Incomplete specs.
3826 ret = 0;
3827 } else
3828 ret = bcm43xx_rssi_postprocess(bcm, in_rssi, 0, 1, 1);
3829
3830 return ret;
3831}
3832
3833static inline
3834int bcm43xx_rx_packet(struct bcm43xx_private *bcm,
3835 struct sk_buff *skb,
3836 struct ieee80211_rx_stats *stats)
3837{
3838 int err;
3839
3840 err = ieee80211_rx(bcm->ieee, skb, stats);
3841 if (unlikely(err == 0))
3842 return -EINVAL;
3843 return 0;
3844}
3845
3846int fastcall bcm43xx_rx(struct bcm43xx_private *bcm,
3847 struct sk_buff *skb,
3848 struct bcm43xx_rxhdr *rxhdr)
3849{
3850 struct bcm43xx_plcp_hdr4 *plcp;
3851 struct ieee80211_rx_stats stats;
3852 struct ieee80211_hdr_4addr *wlhdr;
3853 u16 frame_ctl;
3854 int is_packet_for_us = 0;
3855 int err = -EINVAL;
3856 const u16 rxflags1 = le16_to_cpu(rxhdr->flags1);
3857 const u16 rxflags2 = le16_to_cpu(rxhdr->flags2);
3858 const u16 rxflags3 = le16_to_cpu(rxhdr->flags3);
3859 const int is_ofdm = !!(rxflags1 & BCM43xx_RXHDR_FLAGS1_OFDM);
3860
3861 if (rxflags2 & BCM43xx_RXHDR_FLAGS2_TYPE2FRAME) {
3862 plcp = (struct bcm43xx_plcp_hdr4 *)(skb->data + 2);
3863 /* Skip two unknown bytes and the PLCP header. */
3864 skb_pull(skb, 2 + sizeof(struct bcm43xx_plcp_hdr6));
3865 } else {
3866 plcp = (struct bcm43xx_plcp_hdr4 *)(skb->data);
3867 /* Skip the PLCP header. */
3868 skb_pull(skb, sizeof(struct bcm43xx_plcp_hdr6));
3869 }
3870 /* The SKB contains the PAYLOAD (wireless header + data)
3871 * at this point. The FCS at the end is stripped.
3872 */
3873
3874 memset(&stats, 0, sizeof(stats));
3875 stats.mac_time = le16_to_cpu(rxhdr->mactime);
3876 stats.rssi = bcm43xx_rssi_postprocess(bcm, rxhdr->rssi, is_ofdm,
3877 !!(rxflags1 & BCM43xx_RXHDR_FLAGS1_2053RSSIADJ),
3878 !!(rxflags3 & BCM43xx_RXHDR_FLAGS3_2050RSSIADJ));
3879 stats.signal = rxhdr->signal_quality; //FIXME
3880//TODO stats.noise =
3881 stats.rate = bcm43xx_plcp_get_bitrate(plcp, is_ofdm);
3882//printk("RX ofdm %d, rate == %u\n", is_ofdm, stats.rate);
3883 stats.received_channel = bcm->current_core->radio->channel;
3884//TODO stats.control =
3885 stats.mask = IEEE80211_STATMASK_SIGNAL |
3886//TODO IEEE80211_STATMASK_NOISE |
3887 IEEE80211_STATMASK_RATE |
3888 IEEE80211_STATMASK_RSSI;
3889 if (bcm->current_core->phy->type == BCM43xx_PHYTYPE_A)
3890 stats.freq = IEEE80211_52GHZ_BAND;
3891 else
3892 stats.freq = IEEE80211_24GHZ_BAND;
3893 stats.len = skb->len;
3894
3895 bcm->stats.last_rx = jiffies;
3896 if (bcm->ieee->iw_mode == IW_MODE_MONITOR)
3897 return bcm43xx_rx_packet(bcm, skb, &stats);
3898
3899 wlhdr = (struct ieee80211_hdr_4addr *)(skb->data);
3900
3901 switch (bcm->ieee->iw_mode) {
3902 case IW_MODE_ADHOC:
3903 if (memcmp(wlhdr->addr1, bcm->net_dev->dev_addr, ETH_ALEN) == 0 ||
3904 memcmp(wlhdr->addr3, bcm->ieee->bssid, ETH_ALEN) == 0 ||
3905 is_broadcast_ether_addr(wlhdr->addr1) ||
3906 is_multicast_ether_addr(wlhdr->addr1) ||
3907 bcm->net_dev->flags & IFF_PROMISC)
3908 is_packet_for_us = 1;
3909 break;
3910 case IW_MODE_INFRA:
3911 default:
3912 /* When receiving multicast or broadcast packets, filter out
3913 the packets we send ourself; we shouldn't see those */
3914 if (memcmp(wlhdr->addr3, bcm->ieee->bssid, ETH_ALEN) == 0 ||
3915 memcmp(wlhdr->addr1, bcm->net_dev->dev_addr, ETH_ALEN) == 0 ||
3916 (memcmp(wlhdr->addr3, bcm->net_dev->dev_addr, ETH_ALEN) &&
3917 (is_broadcast_ether_addr(wlhdr->addr1) ||
3918 is_multicast_ether_addr(wlhdr->addr1) ||
3919 bcm->net_dev->flags & IFF_PROMISC)))
3920 is_packet_for_us = 1;
3921 break;
3922 }
3923
3924 frame_ctl = le16_to_cpu(wlhdr->frame_ctl);
f222313a
JL
3925 if ((frame_ctl & IEEE80211_FCTL_PROTECTED) && !bcm->ieee->host_decrypt) {
3926 frame_ctl &= ~IEEE80211_FCTL_PROTECTED;
3927 wlhdr->frame_ctl = cpu_to_le16(frame_ctl);
3928 /* trim IV and ICV */
3929 /* FIXME: this must be done only for WEP encrypted packets */
3930 if (skb->len < 32) {
3931 dprintkl(KERN_ERR PFX "RX packet dropped (PROTECTED flag "
3932 "set and length < 32)\n");
3933 return -EINVAL;
3934 } else {
3935 memmove(skb->data + 4, skb->data, 24);
3936 skb_pull(skb, 4);
3937 skb_trim(skb, skb->len - 4);
3938 stats.len -= 8;
3939 }
ea72ab22 3940 wlhdr = (struct ieee80211_hdr_4addr *)(skb->data);
f222313a
JL
3941 }
3942
3943 switch (WLAN_FC_GET_TYPE(frame_ctl)) {
3944 case IEEE80211_FTYPE_MGMT:
ea72ab22 3945 ieee80211_rx_mgt(bcm->ieee, wlhdr, &stats);
f222313a
JL
3946 break;
3947 case IEEE80211_FTYPE_DATA:
3948 if (is_packet_for_us)
3949 err = bcm43xx_rx_packet(bcm, skb, &stats);
3950 break;
3951 case IEEE80211_FTYPE_CTL:
3952 break;
3953 default:
3954 assert(0);
3955 return -EINVAL;
3956 }
3957
3958 return err;
3959}
3960
3961/* Do the Hardware IO operations to send the txb */
3962static inline int bcm43xx_tx(struct bcm43xx_private *bcm,
3963 struct ieee80211_txb *txb)
3964{
3965 int err = -ENODEV;
3966
77db31ea
MB
3967 if (bcm43xx_using_pio(bcm))
3968 err = bcm43xx_pio_tx(bcm, txb);
f222313a 3969 else
ea72ab22 3970 err = bcm43xx_dma_tx(bcm, txb);
f222313a
JL
3971
3972 return err;
3973}
3974
3975static void bcm43xx_ieee80211_set_chan(struct net_device *net_dev,
3976 u8 channel)
3977{
3978 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
3979 unsigned long flags;
3980
3981 spin_lock_irqsave(&bcm->lock, flags);
3982 bcm43xx_mac_suspend(bcm);
3983 bcm43xx_radio_selectchannel(bcm, channel, 0);
3984 bcm43xx_mac_enable(bcm);
3985 spin_unlock_irqrestore(&bcm->lock, flags);
3986}
3987
3988/* set_security() callback in struct ieee80211_device */
3989static void bcm43xx_ieee80211_set_security(struct net_device *net_dev,
3990 struct ieee80211_security *sec)
3991{
3992 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
3993 struct ieee80211_security *secinfo = &bcm->ieee->sec;
3994 unsigned long flags;
3995 int keyidx;
3996
3997 dprintk(KERN_INFO PFX "set security called\n");
3998
3999 spin_lock_irqsave(&bcm->lock, flags);
4000
4001 for (keyidx = 0; keyidx<WEP_KEYS; keyidx++)
4002 if (sec->flags & (1<<keyidx)) {
4003 secinfo->encode_alg[keyidx] = sec->encode_alg[keyidx];
4004 secinfo->key_sizes[keyidx] = sec->key_sizes[keyidx];
4005 memcpy(secinfo->keys[keyidx], sec->keys[keyidx], SCM_KEY_LEN);
4006 }
4007
4008 if (sec->flags & SEC_ACTIVE_KEY) {
4009 secinfo->active_key = sec->active_key;
4010 dprintk(KERN_INFO PFX " .active_key = %d\n", sec->active_key);
4011 }
4012 if (sec->flags & SEC_UNICAST_GROUP) {
4013 secinfo->unicast_uses_group = sec->unicast_uses_group;
4014 dprintk(KERN_INFO PFX " .unicast_uses_group = %d\n", sec->unicast_uses_group);
4015 }
4016 if (sec->flags & SEC_LEVEL) {
4017 secinfo->level = sec->level;
4018 dprintk(KERN_INFO PFX " .level = %d\n", sec->level);
4019 }
4020 if (sec->flags & SEC_ENABLED) {
4021 secinfo->enabled = sec->enabled;
4022 dprintk(KERN_INFO PFX " .enabled = %d\n", sec->enabled);
4023 }
4024 if (sec->flags & SEC_ENCRYPT) {
4025 secinfo->encrypt = sec->encrypt;
4026 dprintk(KERN_INFO PFX " .encrypt = %d\n", sec->encrypt);
4027 }
4028 if (bcm->initialized && !bcm->ieee->host_encrypt) {
4029 if (secinfo->enabled) {
4030 /* upload WEP keys to hardware */
4031 char null_address[6] = { 0 };
4032 u8 algorithm = 0;
4033 for (keyidx = 0; keyidx<WEP_KEYS; keyidx++) {
4034 if (!(sec->flags & (1<<keyidx)))
4035 continue;
4036 switch (sec->encode_alg[keyidx]) {
4037 case SEC_ALG_NONE: algorithm = BCM43xx_SEC_ALGO_NONE; break;
4038 case SEC_ALG_WEP:
4039 algorithm = BCM43xx_SEC_ALGO_WEP;
4040 if (secinfo->key_sizes[keyidx] == 13)
4041 algorithm = BCM43xx_SEC_ALGO_WEP104;
4042 break;
4043 case SEC_ALG_TKIP:
4044 FIXME();
4045 algorithm = BCM43xx_SEC_ALGO_TKIP;
4046 break;
4047 case SEC_ALG_CCMP:
4048 FIXME();
4049 algorithm = BCM43xx_SEC_ALGO_AES;
4050 break;
4051 default:
4052 assert(0);
4053 break;
4054 }
4055 bcm43xx_key_write(bcm, keyidx, algorithm, sec->keys[keyidx], secinfo->key_sizes[keyidx], &null_address[0]);
4056 bcm->key[keyidx].enabled = 1;
4057 bcm->key[keyidx].algorithm = algorithm;
4058 }
4059 } else
4060 bcm43xx_clear_keys(bcm);
4061 }
4062 spin_unlock_irqrestore(&bcm->lock, flags);
4063}
4064
4065/* hard_start_xmit() callback in struct ieee80211_device */
4066static int bcm43xx_ieee80211_hard_start_xmit(struct ieee80211_txb *txb,
4067 struct net_device *net_dev,
4068 int pri)
4069{
4070 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
4071 int err = -ENODEV;
4072 unsigned long flags;
4073
4074 spin_lock_irqsave(&bcm->lock, flags);
4075 if (likely(bcm->initialized))
4076 err = bcm43xx_tx(bcm, txb);
4077 spin_unlock_irqrestore(&bcm->lock, flags);
4078
4079 return err;
4080}
4081
4082static struct net_device_stats * bcm43xx_net_get_stats(struct net_device *net_dev)
4083{
4084 return &(bcm43xx_priv(net_dev)->ieee->stats);
4085}
4086
4087static void bcm43xx_net_tx_timeout(struct net_device *net_dev)
4088{
4089 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
4090
4091 bcm43xx_controller_restart(bcm, "TX timeout");
4092}
4093
4094#ifdef CONFIG_NET_POLL_CONTROLLER
4095static void bcm43xx_net_poll_controller(struct net_device *net_dev)
4096{
4097 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
4098 unsigned long flags;
4099
4100 local_irq_save(flags);
4101 bcm43xx_interrupt_handler(bcm->irq, bcm, NULL);
4102 local_irq_restore(flags);
4103}
4104#endif /* CONFIG_NET_POLL_CONTROLLER */
4105
4106static int bcm43xx_net_open(struct net_device *net_dev)
4107{
4108 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
4109
4110 return bcm43xx_init_board(bcm);
4111}
4112
4113static int bcm43xx_net_stop(struct net_device *net_dev)
4114{
4115 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
4116
4117 ieee80211softmac_stop(net_dev);
4118 bcm43xx_disable_interrupts_sync(bcm, NULL);
4119 bcm43xx_free_board(bcm);
4120
4121 return 0;
4122}
4123
77db31ea
MB
4124static int bcm43xx_init_private(struct bcm43xx_private *bcm,
4125 struct net_device *net_dev,
ab4977f8 4126 struct pci_dev *pci_dev)
f222313a
JL
4127{
4128 bcm->ieee = netdev_priv(net_dev);
4129 bcm->softmac = ieee80211_priv(net_dev);
4130 bcm->softmac->set_channel = bcm43xx_ieee80211_set_chan;
f222313a
JL
4131
4132#ifdef DEBUG_ENABLE_MMIO_PRINT
4133 bcm43xx_mmioprint_initial(bcm, 1);
4134#else
4135 bcm43xx_mmioprint_initial(bcm, 0);
4136#endif
4137#ifdef DEBUG_ENABLE_PCILOG
4138 bcm43xx_pciprint_initial(bcm, 1);
4139#else
4140 bcm43xx_pciprint_initial(bcm, 0);
4141#endif
4142
4143 bcm->irq_savedstate = BCM43xx_IRQ_INITIAL;
4144 bcm->pci_dev = pci_dev;
4145 bcm->net_dev = net_dev;
4146 if (modparam_bad_frames_preempt)
4147 bcm->bad_frames_preempt = 1;
4148 spin_lock_init(&bcm->lock);
4149 tasklet_init(&bcm->isr_tasklet,
4150 (void (*)(unsigned long))bcm43xx_interrupt_tasklet,
4151 (unsigned long)bcm);
4152 tasklet_disable_nosync(&bcm->isr_tasklet);
4153 if (modparam_pio) {
77db31ea 4154 bcm->__using_pio = 1;
f222313a 4155 } else {
77db31ea
MB
4156 if (pci_set_dma_mask(pci_dev, DMA_30BIT_MASK)) {
4157#ifdef CONFIG_BCM43XX_PIO
f222313a 4158 printk(KERN_WARNING PFX "DMA not supported. Falling back to PIO.\n");
77db31ea
MB
4159 bcm->__using_pio = 1;
4160#else
4161 printk(KERN_ERR PFX "FATAL: DMA not supported and PIO not configured. "
4162 "Recompile the driver with PIO support, please.\n");
4163 return -ENODEV;
4164#endif /* CONFIG_BCM43XX_PIO */
f222313a
JL
4165 }
4166 }
4167 bcm->rts_threshold = BCM43xx_DEFAULT_RTS_THRESHOLD;
4168
4169 /* default to sw encryption for now */
4170 bcm->ieee->host_build_iv = 0;
4171 bcm->ieee->host_encrypt = 1;
4172 bcm->ieee->host_decrypt = 1;
4173
4174 bcm->ieee->iw_mode = BCM43xx_INITIAL_IWMODE;
4175 bcm->ieee->tx_headroom = sizeof(struct bcm43xx_txhdr);
4176 bcm->ieee->set_security = bcm43xx_ieee80211_set_security;
4177 bcm->ieee->hard_start_xmit = bcm43xx_ieee80211_hard_start_xmit;
77db31ea
MB
4178
4179 return 0;
f222313a
JL
4180}
4181
4182static int __devinit bcm43xx_init_one(struct pci_dev *pdev,
4183 const struct pci_device_id *ent)
4184{
4185 struct net_device *net_dev;
4186 struct bcm43xx_private *bcm;
f222313a
JL
4187 int err;
4188
4189#ifdef CONFIG_BCM947XX
4190 if ((pdev->bus->number == 0) && (pdev->device != 0x0800))
4191 return -ENODEV;
4192#endif
4193
4194#ifdef DEBUG_SINGLE_DEVICE_ONLY
4195 if (strcmp(pci_name(pdev), DEBUG_SINGLE_DEVICE_ONLY))
4196 return -ENODEV;
4197#endif
4198
4199 net_dev = alloc_ieee80211softmac(sizeof(*bcm));
4200 if (!net_dev) {
4201 printk(KERN_ERR PFX
4202 "could not allocate ieee80211 device %s\n",
4203 pci_name(pdev));
4204 err = -ENOMEM;
4205 goto out;
4206 }
4207 /* initialize the net_device struct */
4208 SET_MODULE_OWNER(net_dev);
4209 SET_NETDEV_DEV(net_dev, &pdev->dev);
4210
4211 net_dev->open = bcm43xx_net_open;
4212 net_dev->stop = bcm43xx_net_stop;
4213 net_dev->get_stats = bcm43xx_net_get_stats;
4214 net_dev->tx_timeout = bcm43xx_net_tx_timeout;
4215#ifdef CONFIG_NET_POLL_CONTROLLER
4216 net_dev->poll_controller = bcm43xx_net_poll_controller;
4217#endif
4218 net_dev->wireless_handlers = &bcm43xx_wx_handlers_def;
4219 net_dev->irq = pdev->irq;
6465ce1b 4220 SET_ETHTOOL_OPS(net_dev, &bcm43xx_ethtool_ops);
f222313a
JL
4221
4222 /* initialize the bcm43xx_private struct */
4223 bcm = bcm43xx_priv(net_dev);
4224 memset(bcm, 0, sizeof(*bcm));
ab4977f8 4225 err = bcm43xx_init_private(bcm, net_dev, pdev);
77db31ea 4226 if (err)
ab4977f8 4227 goto err_free_netdev;
f222313a
JL
4228
4229 pci_set_drvdata(pdev, net_dev);
4230
4231 err = bcm43xx_attach_board(bcm);
4232 if (err)
ab4977f8 4233 goto err_free_netdev;
f222313a
JL
4234
4235 err = register_netdev(net_dev);
4236 if (err) {
4237 printk(KERN_ERR PFX "Cannot register net device, "
4238 "aborting.\n");
4239 err = -ENOMEM;
4240 goto err_detach_board;
4241 }
4242
4243 bcm43xx_debugfs_add_device(bcm);
4244
4245 assert(err == 0);
4246out:
4247 return err;
4248
4249err_detach_board:
4250 bcm43xx_detach_board(bcm);
f222313a
JL
4251err_free_netdev:
4252 free_ieee80211softmac(net_dev);
4253 goto out;
4254}
4255
4256static void __devexit bcm43xx_remove_one(struct pci_dev *pdev)
4257{
4258 struct net_device *net_dev = pci_get_drvdata(pdev);
4259 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
4260
4261 bcm43xx_debugfs_remove_device(bcm);
4262 unregister_netdev(net_dev);
4263 bcm43xx_detach_board(bcm);
4264 assert(bcm->ucode == NULL);
f222313a
JL
4265 free_ieee80211softmac(net_dev);
4266}
4267
4268/* Hard-reset the chip. Do not call this directly.
4269 * Use bcm43xx_controller_restart()
4270 */
4271static void bcm43xx_chip_reset(void *_bcm)
4272{
4273 struct bcm43xx_private *bcm = _bcm;
4274 struct net_device *net_dev = bcm->net_dev;
4275 struct pci_dev *pci_dev = bcm->pci_dev;
f222313a
JL
4276 int err;
4277 int was_initialized = bcm->initialized;
4278
4279 netif_stop_queue(bcm->net_dev);
4280 tasklet_disable(&bcm->isr_tasklet);
4281
4282 bcm->firmware_norelease = 1;
4283 if (was_initialized)
4284 bcm43xx_free_board(bcm);
4285 bcm->firmware_norelease = 0;
4286 bcm43xx_detach_board(bcm);
ab4977f8 4287 err = bcm43xx_init_private(bcm, net_dev, pci_dev);
77db31ea
MB
4288 if (err)
4289 goto failure;
f222313a
JL
4290 err = bcm43xx_attach_board(bcm);
4291 if (err)
4292 goto failure;
4293 if (was_initialized) {
4294 err = bcm43xx_init_board(bcm);
4295 if (err)
4296 goto failure;
4297 }
4298 netif_wake_queue(bcm->net_dev);
4299 printk(KERN_INFO PFX "Controller restarted\n");
4300
4301 return;
4302failure:
4303 printk(KERN_ERR PFX "Controller restart failed\n");
4304}
4305
4306/* Hard-reset the chip.
4307 * This can be called from interrupt or process context.
4308 * Make sure to _not_ re-enable device interrupts after this has been called.
4309*/
4310void bcm43xx_controller_restart(struct bcm43xx_private *bcm, const char *reason)
4311{
4312 bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
4313 printk(KERN_ERR PFX "Controller RESET (%s) ...\n", reason);
4314 INIT_WORK(&bcm->restart_work, bcm43xx_chip_reset, bcm);
ab4977f8 4315 schedule_work(&bcm->restart_work);
f222313a
JL
4316}
4317
4318#ifdef CONFIG_PM
4319
4320static int bcm43xx_suspend(struct pci_dev *pdev, pm_message_t state)
4321{
4322 struct net_device *net_dev = pci_get_drvdata(pdev);
4323 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
4324 unsigned long flags;
4325 int try_to_shutdown = 0, err;
4326
4327 dprintk(KERN_INFO PFX "Suspending...\n");
4328
4329 spin_lock_irqsave(&bcm->lock, flags);
4330 bcm->was_initialized = bcm->initialized;
4331 if (bcm->initialized)
4332 try_to_shutdown = 1;
4333 spin_unlock_irqrestore(&bcm->lock, flags);
4334
4335 netif_device_detach(net_dev);
4336 if (try_to_shutdown) {
4337 ieee80211softmac_stop(net_dev);
4338 err = bcm43xx_disable_interrupts_sync(bcm, &bcm->irq_savedstate);
4339 if (unlikely(err)) {
4340 dprintk(KERN_ERR PFX "Suspend failed.\n");
4341 return -EAGAIN;
4342 }
4343 bcm->firmware_norelease = 1;
4344 bcm43xx_free_board(bcm);
4345 bcm->firmware_norelease = 0;
4346 }
4347 bcm43xx_chipset_detach(bcm);
4348
4349 pci_save_state(pdev);
4350 pci_disable_device(pdev);
4351 pci_set_power_state(pdev, pci_choose_state(pdev, state));
4352
4353 dprintk(KERN_INFO PFX "Device suspended.\n");
4354
4355 return 0;
4356}
4357
4358static int bcm43xx_resume(struct pci_dev *pdev)
4359{
4360 struct net_device *net_dev = pci_get_drvdata(pdev);
4361 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
4362 int err = 0;
4363
4364 dprintk(KERN_INFO PFX "Resuming...\n");
4365
4366 pci_set_power_state(pdev, 0);
4367 pci_enable_device(pdev);
4368 pci_restore_state(pdev);
4369
4370 bcm43xx_chipset_attach(bcm);
4371 if (bcm->was_initialized) {
4372 bcm->irq_savedstate = BCM43xx_IRQ_INITIAL;
4373 err = bcm43xx_init_board(bcm);
4374 }
4375 if (err) {
4376 printk(KERN_ERR PFX "Resume failed!\n");
4377 return err;
4378 }
4379
4380 netif_device_attach(net_dev);
4381
4382 /*FIXME: This should be handled by softmac instead. */
4383 schedule_work(&bcm->softmac->associnfo.work);
4384
4385 dprintk(KERN_INFO PFX "Device resumed.\n");
4386
4387 return 0;
4388}
4389
4390#endif /* CONFIG_PM */
4391
4392static struct pci_driver bcm43xx_pci_driver = {
65f3f191 4393 .name = KBUILD_MODNAME,
f222313a
JL
4394 .id_table = bcm43xx_pci_tbl,
4395 .probe = bcm43xx_init_one,
4396 .remove = __devexit_p(bcm43xx_remove_one),
4397#ifdef CONFIG_PM
4398 .suspend = bcm43xx_suspend,
4399 .resume = bcm43xx_resume,
4400#endif /* CONFIG_PM */
4401};
4402
4403static int __init bcm43xx_init(void)
4404{
65f3f191 4405 printk(KERN_INFO KBUILD_MODNAME " driver\n");
f222313a
JL
4406 bcm43xx_debugfs_init();
4407 return pci_register_driver(&bcm43xx_pci_driver);
4408}
4409
4410static void __exit bcm43xx_exit(void)
4411{
4412 pci_unregister_driver(&bcm43xx_pci_driver);
4413 bcm43xx_debugfs_exit();
4414}
4415
4416module_init(bcm43xx_init)
4417module_exit(bcm43xx_exit)
4418
4419/* vim: set ts=8 sw=8 sts=8: */
This page took 0.194869 seconds and 5 git commands to generate.