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