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