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