• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/components/opensource/linux/linux-2.6.36/drivers/net/wireless/b43legacy/
1/*
2 *
3 *  Broadcom B43legacy wireless driver
4 *
5 *  Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>
6 *  Copyright (c) 2005-2008 Stefano Brivio <stefano.brivio@polimi.it>
7 *  Copyright (c) 2005, 2006 Michael Buesch <mb@bu3sch.de>
8 *  Copyright (c) 2005 Danny van Dyk <kugelfang@gentoo.org>
9 *  Copyright (c) 2005 Andreas Jaggi <andreas.jaggi@waterwave.ch>
10 *  Copyright (c) 2007 Larry Finger <Larry.Finger@lwfinger.net>
11 *
12 *  Some parts of the code in this file are derived from the ipw2200
13 *  driver  Copyright(c) 2003 - 2004 Intel Corporation.
14
15 *  This program is free software; you can redistribute it and/or modify
16 *  it under the terms of the GNU General Public License as published by
17 *  the Free Software Foundation; either version 2 of the License, or
18 *  (at your option) any later version.
19 *
20 *  This program is distributed in the hope that it will be useful,
21 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
22 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23 *  GNU General Public License for more details.
24 *
25 *  You should have received a copy of the GNU General Public License
26 *  along with this program; see the file COPYING.  If not, write to
27 *  the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
28 *  Boston, MA 02110-1301, USA.
29 *
30 */
31
32#include <linux/delay.h>
33#include <linux/init.h>
34#include <linux/moduleparam.h>
35#include <linux/if_arp.h>
36#include <linux/etherdevice.h>
37#include <linux/firmware.h>
38#include <linux/wireless.h>
39#include <linux/workqueue.h>
40#include <linux/sched.h>
41#include <linux/skbuff.h>
42#include <linux/dma-mapping.h>
43#include <linux/slab.h>
44#include <net/dst.h>
45#include <asm/unaligned.h>
46
47#include "b43legacy.h"
48#include "main.h"
49#include "debugfs.h"
50#include "phy.h"
51#include "dma.h"
52#include "pio.h"
53#include "sysfs.h"
54#include "xmit.h"
55#include "radio.h"
56
57
58MODULE_DESCRIPTION("Broadcom B43legacy wireless driver");
59MODULE_AUTHOR("Martin Langer");
60MODULE_AUTHOR("Stefano Brivio");
61MODULE_AUTHOR("Michael Buesch");
62MODULE_LICENSE("GPL");
63
64MODULE_FIRMWARE(B43legacy_SUPPORTED_FIRMWARE_ID);
65MODULE_FIRMWARE("b43legacy/ucode2.fw");
66MODULE_FIRMWARE("b43legacy/ucode4.fw");
67
68#if defined(CONFIG_B43LEGACY_DMA) && defined(CONFIG_B43LEGACY_PIO)
69static int modparam_pio;
70module_param_named(pio, modparam_pio, int, 0444);
71MODULE_PARM_DESC(pio, "enable(1) / disable(0) PIO mode");
72#elif defined(CONFIG_B43LEGACY_DMA)
73# define modparam_pio	0
74#elif defined(CONFIG_B43LEGACY_PIO)
75# define modparam_pio	1
76#endif
77
78static int modparam_bad_frames_preempt;
79module_param_named(bad_frames_preempt, modparam_bad_frames_preempt, int, 0444);
80MODULE_PARM_DESC(bad_frames_preempt, "enable(1) / disable(0) Bad Frames"
81		 " Preemption");
82
83static char modparam_fwpostfix[16];
84module_param_string(fwpostfix, modparam_fwpostfix, 16, 0444);
85MODULE_PARM_DESC(fwpostfix, "Postfix for the firmware files to load.");
86
87/* The following table supports BCM4301, BCM4303 and BCM4306/2 devices. */
88static const struct ssb_device_id b43legacy_ssb_tbl[] = {
89	SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 2),
90	SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 4),
91	SSB_DEVTABLE_END
92};
93MODULE_DEVICE_TABLE(ssb, b43legacy_ssb_tbl);
94
95
96/* Channel and ratetables are shared for all devices.
97 * They can't be const, because ieee80211 puts some precalculated
98 * data in there. This data is the same for all devices, so we don't
99 * get concurrency issues */
100#define RATETAB_ENT(_rateid, _flags) \
101	{								\
102		.bitrate	= B43legacy_RATE_TO_100KBPS(_rateid),	\
103		.hw_value	= (_rateid),				\
104		.flags		= (_flags),				\
105	}
106/*
107 * NOTE: When changing this, sync with xmit.c's
108 *	 b43legacy_plcp_get_bitrate_idx_* functions!
109 */
110static struct ieee80211_rate __b43legacy_ratetable[] = {
111	RATETAB_ENT(B43legacy_CCK_RATE_1MB, 0),
112	RATETAB_ENT(B43legacy_CCK_RATE_2MB, IEEE80211_RATE_SHORT_PREAMBLE),
113	RATETAB_ENT(B43legacy_CCK_RATE_5MB, IEEE80211_RATE_SHORT_PREAMBLE),
114	RATETAB_ENT(B43legacy_CCK_RATE_11MB, IEEE80211_RATE_SHORT_PREAMBLE),
115	RATETAB_ENT(B43legacy_OFDM_RATE_6MB, 0),
116	RATETAB_ENT(B43legacy_OFDM_RATE_9MB, 0),
117	RATETAB_ENT(B43legacy_OFDM_RATE_12MB, 0),
118	RATETAB_ENT(B43legacy_OFDM_RATE_18MB, 0),
119	RATETAB_ENT(B43legacy_OFDM_RATE_24MB, 0),
120	RATETAB_ENT(B43legacy_OFDM_RATE_36MB, 0),
121	RATETAB_ENT(B43legacy_OFDM_RATE_48MB, 0),
122	RATETAB_ENT(B43legacy_OFDM_RATE_54MB, 0),
123};
124#define b43legacy_b_ratetable		(__b43legacy_ratetable + 0)
125#define b43legacy_b_ratetable_size	4
126#define b43legacy_g_ratetable		(__b43legacy_ratetable + 0)
127#define b43legacy_g_ratetable_size	12
128
129#define CHANTAB_ENT(_chanid, _freq) \
130	{							\
131		.center_freq	= (_freq),			\
132		.hw_value	= (_chanid),			\
133	}
134static struct ieee80211_channel b43legacy_bg_chantable[] = {
135	CHANTAB_ENT(1, 2412),
136	CHANTAB_ENT(2, 2417),
137	CHANTAB_ENT(3, 2422),
138	CHANTAB_ENT(4, 2427),
139	CHANTAB_ENT(5, 2432),
140	CHANTAB_ENT(6, 2437),
141	CHANTAB_ENT(7, 2442),
142	CHANTAB_ENT(8, 2447),
143	CHANTAB_ENT(9, 2452),
144	CHANTAB_ENT(10, 2457),
145	CHANTAB_ENT(11, 2462),
146	CHANTAB_ENT(12, 2467),
147	CHANTAB_ENT(13, 2472),
148	CHANTAB_ENT(14, 2484),
149};
150
151static struct ieee80211_supported_band b43legacy_band_2GHz_BPHY = {
152	.channels = b43legacy_bg_chantable,
153	.n_channels = ARRAY_SIZE(b43legacy_bg_chantable),
154	.bitrates = b43legacy_b_ratetable,
155	.n_bitrates = b43legacy_b_ratetable_size,
156};
157
158static struct ieee80211_supported_band b43legacy_band_2GHz_GPHY = {
159	.channels = b43legacy_bg_chantable,
160	.n_channels = ARRAY_SIZE(b43legacy_bg_chantable),
161	.bitrates = b43legacy_g_ratetable,
162	.n_bitrates = b43legacy_g_ratetable_size,
163};
164
165static void b43legacy_wireless_core_exit(struct b43legacy_wldev *dev);
166static int b43legacy_wireless_core_init(struct b43legacy_wldev *dev);
167static void b43legacy_wireless_core_stop(struct b43legacy_wldev *dev);
168static int b43legacy_wireless_core_start(struct b43legacy_wldev *dev);
169
170
171static int b43legacy_ratelimit(struct b43legacy_wl *wl)
172{
173	if (!wl || !wl->current_dev)
174		return 1;
175	if (b43legacy_status(wl->current_dev) < B43legacy_STAT_STARTED)
176		return 1;
177	/* We are up and running.
178	 * Ratelimit the messages to avoid DoS over the net. */
179	return net_ratelimit();
180}
181
182void b43legacyinfo(struct b43legacy_wl *wl, const char *fmt, ...)
183{
184	va_list args;
185
186	if (!b43legacy_ratelimit(wl))
187		return;
188	va_start(args, fmt);
189	printk(KERN_INFO "b43legacy-%s: ",
190	       (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan");
191	vprintk(fmt, args);
192	va_end(args);
193}
194
195void b43legacyerr(struct b43legacy_wl *wl, const char *fmt, ...)
196{
197	va_list args;
198
199	if (!b43legacy_ratelimit(wl))
200		return;
201	va_start(args, fmt);
202	printk(KERN_ERR "b43legacy-%s ERROR: ",
203	       (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan");
204	vprintk(fmt, args);
205	va_end(args);
206}
207
208void b43legacywarn(struct b43legacy_wl *wl, const char *fmt, ...)
209{
210	va_list args;
211
212	if (!b43legacy_ratelimit(wl))
213		return;
214	va_start(args, fmt);
215	printk(KERN_WARNING "b43legacy-%s warning: ",
216	       (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan");
217	vprintk(fmt, args);
218	va_end(args);
219}
220
221#if B43legacy_DEBUG
222void b43legacydbg(struct b43legacy_wl *wl, const char *fmt, ...)
223{
224	va_list args;
225
226	va_start(args, fmt);
227	printk(KERN_DEBUG "b43legacy-%s debug: ",
228	       (wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan");
229	vprintk(fmt, args);
230	va_end(args);
231}
232#endif /* DEBUG */
233
234static void b43legacy_ram_write(struct b43legacy_wldev *dev, u16 offset,
235				u32 val)
236{
237	u32 status;
238
239	B43legacy_WARN_ON(offset % 4 != 0);
240
241	status = b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
242	if (status & B43legacy_MACCTL_BE)
243		val = swab32(val);
244
245	b43legacy_write32(dev, B43legacy_MMIO_RAM_CONTROL, offset);
246	mmiowb();
247	b43legacy_write32(dev, B43legacy_MMIO_RAM_DATA, val);
248}
249
250static inline
251void b43legacy_shm_control_word(struct b43legacy_wldev *dev,
252				u16 routing, u16 offset)
253{
254	u32 control;
255
256	/* "offset" is the WORD offset. */
257
258	control = routing;
259	control <<= 16;
260	control |= offset;
261	b43legacy_write32(dev, B43legacy_MMIO_SHM_CONTROL, control);
262}
263
264u32 b43legacy_shm_read32(struct b43legacy_wldev *dev,
265		       u16 routing, u16 offset)
266{
267	u32 ret;
268
269	if (routing == B43legacy_SHM_SHARED) {
270		B43legacy_WARN_ON((offset & 0x0001) != 0);
271		if (offset & 0x0003) {
272			/* Unaligned access */
273			b43legacy_shm_control_word(dev, routing, offset >> 2);
274			ret = b43legacy_read16(dev,
275				B43legacy_MMIO_SHM_DATA_UNALIGNED);
276			ret <<= 16;
277			b43legacy_shm_control_word(dev, routing,
278						     (offset >> 2) + 1);
279			ret |= b43legacy_read16(dev, B43legacy_MMIO_SHM_DATA);
280
281			return ret;
282		}
283		offset >>= 2;
284	}
285	b43legacy_shm_control_word(dev, routing, offset);
286	ret = b43legacy_read32(dev, B43legacy_MMIO_SHM_DATA);
287
288	return ret;
289}
290
291u16 b43legacy_shm_read16(struct b43legacy_wldev *dev,
292			   u16 routing, u16 offset)
293{
294	u16 ret;
295
296	if (routing == B43legacy_SHM_SHARED) {
297		B43legacy_WARN_ON((offset & 0x0001) != 0);
298		if (offset & 0x0003) {
299			/* Unaligned access */
300			b43legacy_shm_control_word(dev, routing, offset >> 2);
301			ret = b43legacy_read16(dev,
302					     B43legacy_MMIO_SHM_DATA_UNALIGNED);
303
304			return ret;
305		}
306		offset >>= 2;
307	}
308	b43legacy_shm_control_word(dev, routing, offset);
309	ret = b43legacy_read16(dev, B43legacy_MMIO_SHM_DATA);
310
311	return ret;
312}
313
314void b43legacy_shm_write32(struct b43legacy_wldev *dev,
315			   u16 routing, u16 offset,
316			   u32 value)
317{
318	if (routing == B43legacy_SHM_SHARED) {
319		B43legacy_WARN_ON((offset & 0x0001) != 0);
320		if (offset & 0x0003) {
321			/* Unaligned access */
322			b43legacy_shm_control_word(dev, routing, offset >> 2);
323			mmiowb();
324			b43legacy_write16(dev,
325					  B43legacy_MMIO_SHM_DATA_UNALIGNED,
326					  (value >> 16) & 0xffff);
327			mmiowb();
328			b43legacy_shm_control_word(dev, routing,
329						   (offset >> 2) + 1);
330			mmiowb();
331			b43legacy_write16(dev, B43legacy_MMIO_SHM_DATA,
332					  value & 0xffff);
333			return;
334		}
335		offset >>= 2;
336	}
337	b43legacy_shm_control_word(dev, routing, offset);
338	mmiowb();
339	b43legacy_write32(dev, B43legacy_MMIO_SHM_DATA, value);
340}
341
342void b43legacy_shm_write16(struct b43legacy_wldev *dev, u16 routing, u16 offset,
343			   u16 value)
344{
345	if (routing == B43legacy_SHM_SHARED) {
346		B43legacy_WARN_ON((offset & 0x0001) != 0);
347		if (offset & 0x0003) {
348			/* Unaligned access */
349			b43legacy_shm_control_word(dev, routing, offset >> 2);
350			mmiowb();
351			b43legacy_write16(dev,
352					  B43legacy_MMIO_SHM_DATA_UNALIGNED,
353					  value);
354			return;
355		}
356		offset >>= 2;
357	}
358	b43legacy_shm_control_word(dev, routing, offset);
359	mmiowb();
360	b43legacy_write16(dev, B43legacy_MMIO_SHM_DATA, value);
361}
362
363/* Read HostFlags */
364u32 b43legacy_hf_read(struct b43legacy_wldev *dev)
365{
366	u32 ret;
367
368	ret = b43legacy_shm_read16(dev, B43legacy_SHM_SHARED,
369				   B43legacy_SHM_SH_HOSTFHI);
370	ret <<= 16;
371	ret |= b43legacy_shm_read16(dev, B43legacy_SHM_SHARED,
372				    B43legacy_SHM_SH_HOSTFLO);
373
374	return ret;
375}
376
377/* Write HostFlags */
378void b43legacy_hf_write(struct b43legacy_wldev *dev, u32 value)
379{
380	b43legacy_shm_write16(dev, B43legacy_SHM_SHARED,
381			      B43legacy_SHM_SH_HOSTFLO,
382			      (value & 0x0000FFFF));
383	b43legacy_shm_write16(dev, B43legacy_SHM_SHARED,
384			      B43legacy_SHM_SH_HOSTFHI,
385			      ((value & 0xFFFF0000) >> 16));
386}
387
388void b43legacy_tsf_read(struct b43legacy_wldev *dev, u64 *tsf)
389{
390	/* We need to be careful. As we read the TSF from multiple
391	 * registers, we should take care of register overflows.
392	 * In theory, the whole tsf read process should be atomic.
393	 * We try to be atomic here, by restaring the read process,
394	 * if any of the high registers changed (overflew).
395	 */
396	if (dev->dev->id.revision >= 3) {
397		u32 low;
398		u32 high;
399		u32 high2;
400
401		do {
402			high = b43legacy_read32(dev,
403					B43legacy_MMIO_REV3PLUS_TSF_HIGH);
404			low = b43legacy_read32(dev,
405					B43legacy_MMIO_REV3PLUS_TSF_LOW);
406			high2 = b43legacy_read32(dev,
407					B43legacy_MMIO_REV3PLUS_TSF_HIGH);
408		} while (unlikely(high != high2));
409
410		*tsf = high;
411		*tsf <<= 32;
412		*tsf |= low;
413	} else {
414		u64 tmp;
415		u16 v0;
416		u16 v1;
417		u16 v2;
418		u16 v3;
419		u16 test1;
420		u16 test2;
421		u16 test3;
422
423		do {
424			v3 = b43legacy_read16(dev, B43legacy_MMIO_TSF_3);
425			v2 = b43legacy_read16(dev, B43legacy_MMIO_TSF_2);
426			v1 = b43legacy_read16(dev, B43legacy_MMIO_TSF_1);
427			v0 = b43legacy_read16(dev, B43legacy_MMIO_TSF_0);
428
429			test3 = b43legacy_read16(dev, B43legacy_MMIO_TSF_3);
430			test2 = b43legacy_read16(dev, B43legacy_MMIO_TSF_2);
431			test1 = b43legacy_read16(dev, B43legacy_MMIO_TSF_1);
432		} while (v3 != test3 || v2 != test2 || v1 != test1);
433
434		*tsf = v3;
435		*tsf <<= 48;
436		tmp = v2;
437		tmp <<= 32;
438		*tsf |= tmp;
439		tmp = v1;
440		tmp <<= 16;
441		*tsf |= tmp;
442		*tsf |= v0;
443	}
444}
445
446static void b43legacy_time_lock(struct b43legacy_wldev *dev)
447{
448	u32 status;
449
450	status = b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
451	status |= B43legacy_MACCTL_TBTTHOLD;
452	b43legacy_write32(dev, B43legacy_MMIO_MACCTL, status);
453	mmiowb();
454}
455
456static void b43legacy_time_unlock(struct b43legacy_wldev *dev)
457{
458	u32 status;
459
460	status = b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
461	status &= ~B43legacy_MACCTL_TBTTHOLD;
462	b43legacy_write32(dev, B43legacy_MMIO_MACCTL, status);
463}
464
465static void b43legacy_tsf_write_locked(struct b43legacy_wldev *dev, u64 tsf)
466{
467	/* Be careful with the in-progress timer.
468	 * First zero out the low register, so we have a full
469	 * register-overflow duration to complete the operation.
470	 */
471	if (dev->dev->id.revision >= 3) {
472		u32 lo = (tsf & 0x00000000FFFFFFFFULL);
473		u32 hi = (tsf & 0xFFFFFFFF00000000ULL) >> 32;
474
475		b43legacy_write32(dev, B43legacy_MMIO_REV3PLUS_TSF_LOW, 0);
476		mmiowb();
477		b43legacy_write32(dev, B43legacy_MMIO_REV3PLUS_TSF_HIGH,
478				    hi);
479		mmiowb();
480		b43legacy_write32(dev, B43legacy_MMIO_REV3PLUS_TSF_LOW,
481				    lo);
482	} else {
483		u16 v0 = (tsf & 0x000000000000FFFFULL);
484		u16 v1 = (tsf & 0x00000000FFFF0000ULL) >> 16;
485		u16 v2 = (tsf & 0x0000FFFF00000000ULL) >> 32;
486		u16 v3 = (tsf & 0xFFFF000000000000ULL) >> 48;
487
488		b43legacy_write16(dev, B43legacy_MMIO_TSF_0, 0);
489		mmiowb();
490		b43legacy_write16(dev, B43legacy_MMIO_TSF_3, v3);
491		mmiowb();
492		b43legacy_write16(dev, B43legacy_MMIO_TSF_2, v2);
493		mmiowb();
494		b43legacy_write16(dev, B43legacy_MMIO_TSF_1, v1);
495		mmiowb();
496		b43legacy_write16(dev, B43legacy_MMIO_TSF_0, v0);
497	}
498}
499
500void b43legacy_tsf_write(struct b43legacy_wldev *dev, u64 tsf)
501{
502	b43legacy_time_lock(dev);
503	b43legacy_tsf_write_locked(dev, tsf);
504	b43legacy_time_unlock(dev);
505}
506
507static
508void b43legacy_macfilter_set(struct b43legacy_wldev *dev,
509			     u16 offset, const u8 *mac)
510{
511	static const u8 zero_addr[ETH_ALEN] = { 0 };
512	u16 data;
513
514	if (!mac)
515		mac = zero_addr;
516
517	offset |= 0x0020;
518	b43legacy_write16(dev, B43legacy_MMIO_MACFILTER_CONTROL, offset);
519
520	data = mac[0];
521	data |= mac[1] << 8;
522	b43legacy_write16(dev, B43legacy_MMIO_MACFILTER_DATA, data);
523	data = mac[2];
524	data |= mac[3] << 8;
525	b43legacy_write16(dev, B43legacy_MMIO_MACFILTER_DATA, data);
526	data = mac[4];
527	data |= mac[5] << 8;
528	b43legacy_write16(dev, B43legacy_MMIO_MACFILTER_DATA, data);
529}
530
531static void b43legacy_write_mac_bssid_templates(struct b43legacy_wldev *dev)
532{
533	static const u8 zero_addr[ETH_ALEN] = { 0 };
534	const u8 *mac = dev->wl->mac_addr;
535	const u8 *bssid = dev->wl->bssid;
536	u8 mac_bssid[ETH_ALEN * 2];
537	int i;
538	u32 tmp;
539
540	if (!bssid)
541		bssid = zero_addr;
542	if (!mac)
543		mac = zero_addr;
544
545	b43legacy_macfilter_set(dev, B43legacy_MACFILTER_BSSID, bssid);
546
547	memcpy(mac_bssid, mac, ETH_ALEN);
548	memcpy(mac_bssid + ETH_ALEN, bssid, ETH_ALEN);
549
550	/* Write our MAC address and BSSID to template ram */
551	for (i = 0; i < ARRAY_SIZE(mac_bssid); i += sizeof(u32)) {
552		tmp =  (u32)(mac_bssid[i + 0]);
553		tmp |= (u32)(mac_bssid[i + 1]) << 8;
554		tmp |= (u32)(mac_bssid[i + 2]) << 16;
555		tmp |= (u32)(mac_bssid[i + 3]) << 24;
556		b43legacy_ram_write(dev, 0x20 + i, tmp);
557		b43legacy_ram_write(dev, 0x78 + i, tmp);
558		b43legacy_ram_write(dev, 0x478 + i, tmp);
559	}
560}
561
562static void b43legacy_upload_card_macaddress(struct b43legacy_wldev *dev)
563{
564	b43legacy_write_mac_bssid_templates(dev);
565	b43legacy_macfilter_set(dev, B43legacy_MACFILTER_SELF,
566				dev->wl->mac_addr);
567}
568
569static void b43legacy_set_slot_time(struct b43legacy_wldev *dev,
570				    u16 slot_time)
571{
572	/* slot_time is in usec. */
573	if (dev->phy.type != B43legacy_PHYTYPE_G)
574		return;
575	b43legacy_write16(dev, 0x684, 510 + slot_time);
576	b43legacy_shm_write16(dev, B43legacy_SHM_SHARED, 0x0010,
577			      slot_time);
578}
579
580static void b43legacy_short_slot_timing_enable(struct b43legacy_wldev *dev)
581{
582	b43legacy_set_slot_time(dev, 9);
583}
584
585static void b43legacy_short_slot_timing_disable(struct b43legacy_wldev *dev)
586{
587	b43legacy_set_slot_time(dev, 20);
588}
589
590/* Synchronize IRQ top- and bottom-half.
591 * IRQs must be masked before calling this.
592 * This must not be called with the irq_lock held.
593 */
594static void b43legacy_synchronize_irq(struct b43legacy_wldev *dev)
595{
596	synchronize_irq(dev->dev->irq);
597	tasklet_kill(&dev->isr_tasklet);
598}
599
600/* DummyTransmission function, as documented on
601 * http://bcm-specs.sipsolutions.net/DummyTransmission
602 */
603void b43legacy_dummy_transmission(struct b43legacy_wldev *dev)
604{
605	struct b43legacy_phy *phy = &dev->phy;
606	unsigned int i;
607	unsigned int max_loop;
608	u16 value;
609	u32 buffer[5] = {
610		0x00000000,
611		0x00D40000,
612		0x00000000,
613		0x01000000,
614		0x00000000,
615	};
616
617	switch (phy->type) {
618	case B43legacy_PHYTYPE_B:
619	case B43legacy_PHYTYPE_G:
620		max_loop = 0xFA;
621		buffer[0] = 0x000B846E;
622		break;
623	default:
624		B43legacy_BUG_ON(1);
625		return;
626	}
627
628	for (i = 0; i < 5; i++)
629		b43legacy_ram_write(dev, i * 4, buffer[i]);
630
631	/* dummy read follows */
632	b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
633
634	b43legacy_write16(dev, 0x0568, 0x0000);
635	b43legacy_write16(dev, 0x07C0, 0x0000);
636	b43legacy_write16(dev, 0x050C, 0x0000);
637	b43legacy_write16(dev, 0x0508, 0x0000);
638	b43legacy_write16(dev, 0x050A, 0x0000);
639	b43legacy_write16(dev, 0x054C, 0x0000);
640	b43legacy_write16(dev, 0x056A, 0x0014);
641	b43legacy_write16(dev, 0x0568, 0x0826);
642	b43legacy_write16(dev, 0x0500, 0x0000);
643	b43legacy_write16(dev, 0x0502, 0x0030);
644
645	if (phy->radio_ver == 0x2050 && phy->radio_rev <= 0x5)
646		b43legacy_radio_write16(dev, 0x0051, 0x0017);
647	for (i = 0x00; i < max_loop; i++) {
648		value = b43legacy_read16(dev, 0x050E);
649		if (value & 0x0080)
650			break;
651		udelay(10);
652	}
653	for (i = 0x00; i < 0x0A; i++) {
654		value = b43legacy_read16(dev, 0x050E);
655		if (value & 0x0400)
656			break;
657		udelay(10);
658	}
659	for (i = 0x00; i < 0x0A; i++) {
660		value = b43legacy_read16(dev, 0x0690);
661		if (!(value & 0x0100))
662			break;
663		udelay(10);
664	}
665	if (phy->radio_ver == 0x2050 && phy->radio_rev <= 0x5)
666		b43legacy_radio_write16(dev, 0x0051, 0x0037);
667}
668
669/* Turn the Analog ON/OFF */
670static void b43legacy_switch_analog(struct b43legacy_wldev *dev, int on)
671{
672	b43legacy_write16(dev, B43legacy_MMIO_PHY0, on ? 0 : 0xF4);
673}
674
675void b43legacy_wireless_core_reset(struct b43legacy_wldev *dev, u32 flags)
676{
677	u32 tmslow;
678	u32 macctl;
679
680	flags |= B43legacy_TMSLOW_PHYCLKEN;
681	flags |= B43legacy_TMSLOW_PHYRESET;
682	ssb_device_enable(dev->dev, flags);
683	msleep(2); /* Wait for the PLL to turn on. */
684
685	/* Now take the PHY out of Reset again */
686	tmslow = ssb_read32(dev->dev, SSB_TMSLOW);
687	tmslow |= SSB_TMSLOW_FGC;
688	tmslow &= ~B43legacy_TMSLOW_PHYRESET;
689	ssb_write32(dev->dev, SSB_TMSLOW, tmslow);
690	ssb_read32(dev->dev, SSB_TMSLOW); /* flush */
691	msleep(1);
692	tmslow &= ~SSB_TMSLOW_FGC;
693	ssb_write32(dev->dev, SSB_TMSLOW, tmslow);
694	ssb_read32(dev->dev, SSB_TMSLOW); /* flush */
695	msleep(1);
696
697	/* Turn Analog ON */
698	b43legacy_switch_analog(dev, 1);
699
700	macctl = b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
701	macctl &= ~B43legacy_MACCTL_GMODE;
702	if (flags & B43legacy_TMSLOW_GMODE) {
703		macctl |= B43legacy_MACCTL_GMODE;
704		dev->phy.gmode = 1;
705	} else
706		dev->phy.gmode = 0;
707	macctl |= B43legacy_MACCTL_IHR_ENABLED;
708	b43legacy_write32(dev, B43legacy_MMIO_MACCTL, macctl);
709}
710
711static void handle_irq_transmit_status(struct b43legacy_wldev *dev)
712{
713	u32 v0;
714	u32 v1;
715	u16 tmp;
716	struct b43legacy_txstatus stat;
717
718	while (1) {
719		v0 = b43legacy_read32(dev, B43legacy_MMIO_XMITSTAT_0);
720		if (!(v0 & 0x00000001))
721			break;
722		v1 = b43legacy_read32(dev, B43legacy_MMIO_XMITSTAT_1);
723
724		stat.cookie = (v0 >> 16);
725		stat.seq = (v1 & 0x0000FFFF);
726		stat.phy_stat = ((v1 & 0x00FF0000) >> 16);
727		tmp = (v0 & 0x0000FFFF);
728		stat.frame_count = ((tmp & 0xF000) >> 12);
729		stat.rts_count = ((tmp & 0x0F00) >> 8);
730		stat.supp_reason = ((tmp & 0x001C) >> 2);
731		stat.pm_indicated = !!(tmp & 0x0080);
732		stat.intermediate = !!(tmp & 0x0040);
733		stat.for_ampdu = !!(tmp & 0x0020);
734		stat.acked = !!(tmp & 0x0002);
735
736		b43legacy_handle_txstatus(dev, &stat);
737	}
738}
739
740static void drain_txstatus_queue(struct b43legacy_wldev *dev)
741{
742	u32 dummy;
743
744	if (dev->dev->id.revision < 5)
745		return;
746	/* Read all entries from the microcode TXstatus FIFO
747	 * and throw them away.
748	 */
749	while (1) {
750		dummy = b43legacy_read32(dev, B43legacy_MMIO_XMITSTAT_0);
751		if (!(dummy & 0x00000001))
752			break;
753		dummy = b43legacy_read32(dev, B43legacy_MMIO_XMITSTAT_1);
754	}
755}
756
757static u32 b43legacy_jssi_read(struct b43legacy_wldev *dev)
758{
759	u32 val = 0;
760
761	val = b43legacy_shm_read16(dev, B43legacy_SHM_SHARED, 0x40A);
762	val <<= 16;
763	val |= b43legacy_shm_read16(dev, B43legacy_SHM_SHARED, 0x408);
764
765	return val;
766}
767
768static void b43legacy_jssi_write(struct b43legacy_wldev *dev, u32 jssi)
769{
770	b43legacy_shm_write16(dev, B43legacy_SHM_SHARED, 0x408,
771			      (jssi & 0x0000FFFF));
772	b43legacy_shm_write16(dev, B43legacy_SHM_SHARED, 0x40A,
773			      (jssi & 0xFFFF0000) >> 16);
774}
775
776static void b43legacy_generate_noise_sample(struct b43legacy_wldev *dev)
777{
778	b43legacy_jssi_write(dev, 0x7F7F7F7F);
779	b43legacy_write32(dev, B43legacy_MMIO_MACCMD,
780			  b43legacy_read32(dev, B43legacy_MMIO_MACCMD)
781			  | B43legacy_MACCMD_BGNOISE);
782	B43legacy_WARN_ON(dev->noisecalc.channel_at_start !=
783			    dev->phy.channel);
784}
785
786static void b43legacy_calculate_link_quality(struct b43legacy_wldev *dev)
787{
788	/* Top half of Link Quality calculation. */
789
790	if (dev->noisecalc.calculation_running)
791		return;
792	dev->noisecalc.channel_at_start = dev->phy.channel;
793	dev->noisecalc.calculation_running = 1;
794	dev->noisecalc.nr_samples = 0;
795
796	b43legacy_generate_noise_sample(dev);
797}
798
799static void handle_irq_noise(struct b43legacy_wldev *dev)
800{
801	struct b43legacy_phy *phy = &dev->phy;
802	u16 tmp;
803	u8 noise[4];
804	u8 i;
805	u8 j;
806	s32 average;
807
808	/* Bottom half of Link Quality calculation. */
809
810	B43legacy_WARN_ON(!dev->noisecalc.calculation_running);
811	if (dev->noisecalc.channel_at_start != phy->channel)
812		goto drop_calculation;
813	*((__le32 *)noise) = cpu_to_le32(b43legacy_jssi_read(dev));
814	if (noise[0] == 0x7F || noise[1] == 0x7F ||
815	    noise[2] == 0x7F || noise[3] == 0x7F)
816		goto generate_new;
817
818	/* Get the noise samples. */
819	B43legacy_WARN_ON(dev->noisecalc.nr_samples >= 8);
820	i = dev->noisecalc.nr_samples;
821	noise[0] = clamp_val(noise[0], 0, ARRAY_SIZE(phy->nrssi_lt) - 1);
822	noise[1] = clamp_val(noise[1], 0, ARRAY_SIZE(phy->nrssi_lt) - 1);
823	noise[2] = clamp_val(noise[2], 0, ARRAY_SIZE(phy->nrssi_lt) - 1);
824	noise[3] = clamp_val(noise[3], 0, ARRAY_SIZE(phy->nrssi_lt) - 1);
825	dev->noisecalc.samples[i][0] = phy->nrssi_lt[noise[0]];
826	dev->noisecalc.samples[i][1] = phy->nrssi_lt[noise[1]];
827	dev->noisecalc.samples[i][2] = phy->nrssi_lt[noise[2]];
828	dev->noisecalc.samples[i][3] = phy->nrssi_lt[noise[3]];
829	dev->noisecalc.nr_samples++;
830	if (dev->noisecalc.nr_samples == 8) {
831		/* Calculate the Link Quality by the noise samples. */
832		average = 0;
833		for (i = 0; i < 8; i++) {
834			for (j = 0; j < 4; j++)
835				average += dev->noisecalc.samples[i][j];
836		}
837		average /= (8 * 4);
838		average *= 125;
839		average += 64;
840		average /= 128;
841		tmp = b43legacy_shm_read16(dev, B43legacy_SHM_SHARED,
842					     0x40C);
843		tmp = (tmp / 128) & 0x1F;
844		if (tmp >= 8)
845			average += 2;
846		else
847			average -= 25;
848		if (tmp == 8)
849			average -= 72;
850		else
851			average -= 48;
852
853		dev->stats.link_noise = average;
854drop_calculation:
855		dev->noisecalc.calculation_running = 0;
856		return;
857	}
858generate_new:
859	b43legacy_generate_noise_sample(dev);
860}
861
862static void handle_irq_tbtt_indication(struct b43legacy_wldev *dev)
863{
864	if (b43legacy_is_mode(dev->wl, NL80211_IFTYPE_AP)) {
865		/* TODO: PS TBTT */
866	} else {
867		if (1)
868			b43legacy_power_saving_ctl_bits(dev, -1, -1);
869	}
870	if (b43legacy_is_mode(dev->wl, NL80211_IFTYPE_ADHOC))
871		dev->dfq_valid = 1;
872}
873
874static void handle_irq_atim_end(struct b43legacy_wldev *dev)
875{
876	if (dev->dfq_valid) {
877		b43legacy_write32(dev, B43legacy_MMIO_MACCMD,
878				  b43legacy_read32(dev, B43legacy_MMIO_MACCMD)
879				  | B43legacy_MACCMD_DFQ_VALID);
880		dev->dfq_valid = 0;
881	}
882}
883
884static void handle_irq_pmq(struct b43legacy_wldev *dev)
885{
886	u32 tmp;
887
888	/* TODO: AP mode. */
889
890	while (1) {
891		tmp = b43legacy_read32(dev, B43legacy_MMIO_PS_STATUS);
892		if (!(tmp & 0x00000008))
893			break;
894	}
895	/* 16bit write is odd, but correct. */
896	b43legacy_write16(dev, B43legacy_MMIO_PS_STATUS, 0x0002);
897}
898
899static void b43legacy_write_template_common(struct b43legacy_wldev *dev,
900					    const u8 *data, u16 size,
901					    u16 ram_offset,
902					    u16 shm_size_offset, u8 rate)
903{
904	u32 i;
905	u32 tmp;
906	struct b43legacy_plcp_hdr4 plcp;
907
908	plcp.data = 0;
909	b43legacy_generate_plcp_hdr(&plcp, size + FCS_LEN, rate);
910	b43legacy_ram_write(dev, ram_offset, le32_to_cpu(plcp.data));
911	ram_offset += sizeof(u32);
912	/* The PLCP is 6 bytes long, but we only wrote 4 bytes, yet.
913	 * So leave the first two bytes of the next write blank.
914	 */
915	tmp = (u32)(data[0]) << 16;
916	tmp |= (u32)(data[1]) << 24;
917	b43legacy_ram_write(dev, ram_offset, tmp);
918	ram_offset += sizeof(u32);
919	for (i = 2; i < size; i += sizeof(u32)) {
920		tmp = (u32)(data[i + 0]);
921		if (i + 1 < size)
922			tmp |= (u32)(data[i + 1]) << 8;
923		if (i + 2 < size)
924			tmp |= (u32)(data[i + 2]) << 16;
925		if (i + 3 < size)
926			tmp |= (u32)(data[i + 3]) << 24;
927		b43legacy_ram_write(dev, ram_offset + i - 2, tmp);
928	}
929	b43legacy_shm_write16(dev, B43legacy_SHM_SHARED, shm_size_offset,
930			      size + sizeof(struct b43legacy_plcp_hdr6));
931}
932
933/* Convert a b43legacy antenna number value to the PHY TX control value. */
934static u16 b43legacy_antenna_to_phyctl(int antenna)
935{
936	switch (antenna) {
937	case B43legacy_ANTENNA0:
938		return B43legacy_TX4_PHY_ANT0;
939	case B43legacy_ANTENNA1:
940		return B43legacy_TX4_PHY_ANT1;
941	}
942	return B43legacy_TX4_PHY_ANTLAST;
943}
944
945static void b43legacy_write_beacon_template(struct b43legacy_wldev *dev,
946					    u16 ram_offset,
947					    u16 shm_size_offset)
948{
949
950	unsigned int i, len, variable_len;
951	const struct ieee80211_mgmt *bcn;
952	const u8 *ie;
953	bool tim_found = 0;
954	unsigned int rate;
955	u16 ctl;
956	int antenna;
957	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(dev->wl->current_beacon);
958
959	bcn = (const struct ieee80211_mgmt *)(dev->wl->current_beacon->data);
960	len = min((size_t)dev->wl->current_beacon->len,
961		  0x200 - sizeof(struct b43legacy_plcp_hdr6));
962	rate = ieee80211_get_tx_rate(dev->wl->hw, info)->hw_value;
963
964	b43legacy_write_template_common(dev, (const u8 *)bcn, len, ram_offset,
965					shm_size_offset, rate);
966
967	/* Write the PHY TX control parameters. */
968	antenna = B43legacy_ANTENNA_DEFAULT;
969	antenna = b43legacy_antenna_to_phyctl(antenna);
970	ctl = b43legacy_shm_read16(dev, B43legacy_SHM_SHARED,
971				   B43legacy_SHM_SH_BEACPHYCTL);
972	/* We can't send beacons with short preamble. Would get PHY errors. */
973	ctl &= ~B43legacy_TX4_PHY_SHORTPRMBL;
974	ctl &= ~B43legacy_TX4_PHY_ANT;
975	ctl &= ~B43legacy_TX4_PHY_ENC;
976	ctl |= antenna;
977	ctl |= B43legacy_TX4_PHY_ENC_CCK;
978	b43legacy_shm_write16(dev, B43legacy_SHM_SHARED,
979			      B43legacy_SHM_SH_BEACPHYCTL, ctl);
980
981	/* Find the position of the TIM and the DTIM_period value
982	 * and write them to SHM. */
983	ie = bcn->u.beacon.variable;
984	variable_len = len - offsetof(struct ieee80211_mgmt, u.beacon.variable);
985	for (i = 0; i < variable_len - 2; ) {
986		uint8_t ie_id, ie_len;
987
988		ie_id = ie[i];
989		ie_len = ie[i + 1];
990		if (ie_id == 5) {
991			u16 tim_position;
992			u16 dtim_period;
993			/* This is the TIM Information Element */
994
995			/* Check whether the ie_len is in the beacon data range. */
996			if (variable_len < ie_len + 2 + i)
997				break;
998			/* A valid TIM is at least 4 bytes long. */
999			if (ie_len < 4)
1000				break;
1001			tim_found = 1;
1002
1003			tim_position = sizeof(struct b43legacy_plcp_hdr6);
1004			tim_position += offsetof(struct ieee80211_mgmt,
1005						 u.beacon.variable);
1006			tim_position += i;
1007
1008			dtim_period = ie[i + 3];
1009
1010			b43legacy_shm_write16(dev, B43legacy_SHM_SHARED,
1011					B43legacy_SHM_SH_TIMPOS, tim_position);
1012			b43legacy_shm_write16(dev, B43legacy_SHM_SHARED,
1013					B43legacy_SHM_SH_DTIMP, dtim_period);
1014			break;
1015		}
1016		i += ie_len + 2;
1017	}
1018	if (!tim_found) {
1019		b43legacywarn(dev->wl, "Did not find a valid TIM IE in the "
1020			      "beacon template packet. AP or IBSS operation "
1021			      "may be broken.\n");
1022	} else
1023		b43legacydbg(dev->wl, "Updated beacon template\n");
1024}
1025
1026static void b43legacy_write_probe_resp_plcp(struct b43legacy_wldev *dev,
1027					    u16 shm_offset, u16 size,
1028					    struct ieee80211_rate *rate)
1029{
1030	struct b43legacy_plcp_hdr4 plcp;
1031	u32 tmp;
1032	__le16 dur;
1033
1034	plcp.data = 0;
1035	b43legacy_generate_plcp_hdr(&plcp, size + FCS_LEN, rate->hw_value);
1036	dur = ieee80211_generic_frame_duration(dev->wl->hw,
1037					       dev->wl->vif,
1038					       size,
1039					       rate);
1040	/* Write PLCP in two parts and timing for packet transfer */
1041	tmp = le32_to_cpu(plcp.data);
1042	b43legacy_shm_write16(dev, B43legacy_SHM_SHARED, shm_offset,
1043			      tmp & 0xFFFF);
1044	b43legacy_shm_write16(dev, B43legacy_SHM_SHARED, shm_offset + 2,
1045			      tmp >> 16);
1046	b43legacy_shm_write16(dev, B43legacy_SHM_SHARED, shm_offset + 6,
1047			      le16_to_cpu(dur));
1048}
1049
1050/* Instead of using custom probe response template, this function
1051 * just patches custom beacon template by:
1052 * 1) Changing packet type
1053 * 2) Patching duration field
1054 * 3) Stripping TIM
1055 */
1056static const u8 *b43legacy_generate_probe_resp(struct b43legacy_wldev *dev,
1057					       u16 *dest_size,
1058					       struct ieee80211_rate *rate)
1059{
1060	const u8 *src_data;
1061	u8 *dest_data;
1062	u16 src_size, elem_size, src_pos, dest_pos;
1063	__le16 dur;
1064	struct ieee80211_hdr *hdr;
1065	size_t ie_start;
1066
1067	src_size = dev->wl->current_beacon->len;
1068	src_data = (const u8 *)dev->wl->current_beacon->data;
1069
1070	/* Get the start offset of the variable IEs in the packet. */
1071	ie_start = offsetof(struct ieee80211_mgmt, u.probe_resp.variable);
1072	B43legacy_WARN_ON(ie_start != offsetof(struct ieee80211_mgmt,
1073					       u.beacon.variable));
1074
1075	if (B43legacy_WARN_ON(src_size < ie_start))
1076		return NULL;
1077
1078	dest_data = kmalloc(src_size, GFP_ATOMIC);
1079	if (unlikely(!dest_data))
1080		return NULL;
1081
1082	/* Copy the static data and all Information Elements, except the TIM. */
1083	memcpy(dest_data, src_data, ie_start);
1084	src_pos = ie_start;
1085	dest_pos = ie_start;
1086	for ( ; src_pos < src_size - 2; src_pos += elem_size) {
1087		elem_size = src_data[src_pos + 1] + 2;
1088		if (src_data[src_pos] == 5) {
1089			/* This is the TIM. */
1090			continue;
1091		}
1092		memcpy(dest_data + dest_pos, src_data + src_pos, elem_size);
1093		dest_pos += elem_size;
1094	}
1095	*dest_size = dest_pos;
1096	hdr = (struct ieee80211_hdr *)dest_data;
1097
1098	/* Set the frame control. */
1099	hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
1100					 IEEE80211_STYPE_PROBE_RESP);
1101	dur = ieee80211_generic_frame_duration(dev->wl->hw,
1102					       dev->wl->vif,
1103					       *dest_size,
1104					       rate);
1105	hdr->duration_id = dur;
1106
1107	return dest_data;
1108}
1109
1110static void b43legacy_write_probe_resp_template(struct b43legacy_wldev *dev,
1111						u16 ram_offset,
1112						u16 shm_size_offset,
1113						struct ieee80211_rate *rate)
1114{
1115	const u8 *probe_resp_data;
1116	u16 size;
1117
1118	size = dev->wl->current_beacon->len;
1119	probe_resp_data = b43legacy_generate_probe_resp(dev, &size, rate);
1120	if (unlikely(!probe_resp_data))
1121		return;
1122
1123	/* Looks like PLCP headers plus packet timings are stored for
1124	 * all possible basic rates
1125	 */
1126	b43legacy_write_probe_resp_plcp(dev, 0x31A, size,
1127					&b43legacy_b_ratetable[0]);
1128	b43legacy_write_probe_resp_plcp(dev, 0x32C, size,
1129					&b43legacy_b_ratetable[1]);
1130	b43legacy_write_probe_resp_plcp(dev, 0x33E, size,
1131					&b43legacy_b_ratetable[2]);
1132	b43legacy_write_probe_resp_plcp(dev, 0x350, size,
1133					&b43legacy_b_ratetable[3]);
1134
1135	size = min((size_t)size,
1136		   0x200 - sizeof(struct b43legacy_plcp_hdr6));
1137	b43legacy_write_template_common(dev, probe_resp_data,
1138					size, ram_offset,
1139					shm_size_offset, rate->hw_value);
1140	kfree(probe_resp_data);
1141}
1142
1143static void b43legacy_upload_beacon0(struct b43legacy_wldev *dev)
1144{
1145	struct b43legacy_wl *wl = dev->wl;
1146
1147	if (wl->beacon0_uploaded)
1148		return;
1149	b43legacy_write_beacon_template(dev, 0x68, 0x18);
1150	b43legacy_write_probe_resp_template(dev, 0x268, 0x4A,
1151				      &__b43legacy_ratetable[3]);
1152	wl->beacon0_uploaded = 1;
1153}
1154
1155static void b43legacy_upload_beacon1(struct b43legacy_wldev *dev)
1156{
1157	struct b43legacy_wl *wl = dev->wl;
1158
1159	if (wl->beacon1_uploaded)
1160		return;
1161	b43legacy_write_beacon_template(dev, 0x468, 0x1A);
1162	wl->beacon1_uploaded = 1;
1163}
1164
1165static void handle_irq_beacon(struct b43legacy_wldev *dev)
1166{
1167	struct b43legacy_wl *wl = dev->wl;
1168	u32 cmd, beacon0_valid, beacon1_valid;
1169
1170	if (!b43legacy_is_mode(wl, NL80211_IFTYPE_AP))
1171		return;
1172
1173	/* This is the bottom half of the asynchronous beacon update. */
1174
1175	/* Ignore interrupt in the future. */
1176	dev->irq_mask &= ~B43legacy_IRQ_BEACON;
1177
1178	cmd = b43legacy_read32(dev, B43legacy_MMIO_MACCMD);
1179	beacon0_valid = (cmd & B43legacy_MACCMD_BEACON0_VALID);
1180	beacon1_valid = (cmd & B43legacy_MACCMD_BEACON1_VALID);
1181
1182	/* Schedule interrupt manually, if busy. */
1183	if (beacon0_valid && beacon1_valid) {
1184		b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_REASON, B43legacy_IRQ_BEACON);
1185		dev->irq_mask |= B43legacy_IRQ_BEACON;
1186		return;
1187	}
1188
1189	if (unlikely(wl->beacon_templates_virgin)) {
1190		/* We never uploaded a beacon before.
1191		 * Upload both templates now, but only mark one valid. */
1192		wl->beacon_templates_virgin = 0;
1193		b43legacy_upload_beacon0(dev);
1194		b43legacy_upload_beacon1(dev);
1195		cmd = b43legacy_read32(dev, B43legacy_MMIO_MACCMD);
1196		cmd |= B43legacy_MACCMD_BEACON0_VALID;
1197		b43legacy_write32(dev, B43legacy_MMIO_MACCMD, cmd);
1198	} else {
1199		if (!beacon0_valid) {
1200			b43legacy_upload_beacon0(dev);
1201			cmd = b43legacy_read32(dev, B43legacy_MMIO_MACCMD);
1202			cmd |= B43legacy_MACCMD_BEACON0_VALID;
1203			b43legacy_write32(dev, B43legacy_MMIO_MACCMD, cmd);
1204		} else if (!beacon1_valid) {
1205			b43legacy_upload_beacon1(dev);
1206			cmd = b43legacy_read32(dev, B43legacy_MMIO_MACCMD);
1207			cmd |= B43legacy_MACCMD_BEACON1_VALID;
1208			b43legacy_write32(dev, B43legacy_MMIO_MACCMD, cmd);
1209		}
1210	}
1211}
1212
1213static void b43legacy_beacon_update_trigger_work(struct work_struct *work)
1214{
1215	struct b43legacy_wl *wl = container_of(work, struct b43legacy_wl,
1216					 beacon_update_trigger);
1217	struct b43legacy_wldev *dev;
1218
1219	mutex_lock(&wl->mutex);
1220	dev = wl->current_dev;
1221	if (likely(dev && (b43legacy_status(dev) >= B43legacy_STAT_INITIALIZED))) {
1222		spin_lock_irq(&wl->irq_lock);
1223		/* Update beacon right away or defer to IRQ. */
1224		handle_irq_beacon(dev);
1225		/* The handler might have updated the IRQ mask. */
1226		b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_MASK,
1227				  dev->irq_mask);
1228		mmiowb();
1229		spin_unlock_irq(&wl->irq_lock);
1230	}
1231	mutex_unlock(&wl->mutex);
1232}
1233
1234/* Asynchronously update the packet templates in template RAM.
1235 * Locking: Requires wl->irq_lock to be locked. */
1236static void b43legacy_update_templates(struct b43legacy_wl *wl)
1237{
1238	struct sk_buff *beacon;
1239	/* This is the top half of the ansynchronous beacon update. The bottom
1240	 * half is the beacon IRQ. Beacon update must be asynchronous to avoid
1241	 * sending an invalid beacon. This can happen for example, if the
1242	 * firmware transmits a beacon while we are updating it. */
1243
1244	/* We could modify the existing beacon and set the aid bit in the TIM
1245	 * field, but that would probably require resizing and moving of data
1246	 * within the beacon template. Simply request a new beacon and let
1247	 * mac80211 do the hard work. */
1248	beacon = ieee80211_beacon_get(wl->hw, wl->vif);
1249	if (unlikely(!beacon))
1250		return;
1251
1252	if (wl->current_beacon)
1253		dev_kfree_skb_any(wl->current_beacon);
1254	wl->current_beacon = beacon;
1255	wl->beacon0_uploaded = 0;
1256	wl->beacon1_uploaded = 0;
1257	ieee80211_queue_work(wl->hw, &wl->beacon_update_trigger);
1258}
1259
1260static void b43legacy_set_beacon_int(struct b43legacy_wldev *dev,
1261				     u16 beacon_int)
1262{
1263	b43legacy_time_lock(dev);
1264	if (dev->dev->id.revision >= 3) {
1265		b43legacy_write32(dev, B43legacy_MMIO_TSF_CFP_REP,
1266				 (beacon_int << 16));
1267		b43legacy_write32(dev, B43legacy_MMIO_TSF_CFP_START,
1268				 (beacon_int << 10));
1269	} else {
1270		b43legacy_write16(dev, 0x606, (beacon_int >> 6));
1271		b43legacy_write16(dev, 0x610, beacon_int);
1272	}
1273	b43legacy_time_unlock(dev);
1274	b43legacydbg(dev->wl, "Set beacon interval to %u\n", beacon_int);
1275}
1276
1277static void handle_irq_ucode_debug(struct b43legacy_wldev *dev)
1278{
1279}
1280
1281/* Interrupt handler bottom-half */
1282static void b43legacy_interrupt_tasklet(struct b43legacy_wldev *dev)
1283{
1284	u32 reason;
1285	u32 dma_reason[ARRAY_SIZE(dev->dma_reason)];
1286	u32 merged_dma_reason = 0;
1287	int i;
1288	unsigned long flags;
1289
1290	spin_lock_irqsave(&dev->wl->irq_lock, flags);
1291
1292	B43legacy_WARN_ON(b43legacy_status(dev) <
1293			  B43legacy_STAT_INITIALIZED);
1294
1295	reason = dev->irq_reason;
1296	for (i = 0; i < ARRAY_SIZE(dma_reason); i++) {
1297		dma_reason[i] = dev->dma_reason[i];
1298		merged_dma_reason |= dma_reason[i];
1299	}
1300
1301	if (unlikely(reason & B43legacy_IRQ_MAC_TXERR))
1302		b43legacyerr(dev->wl, "MAC transmission error\n");
1303
1304	if (unlikely(reason & B43legacy_IRQ_PHY_TXERR)) {
1305		b43legacyerr(dev->wl, "PHY transmission error\n");
1306		rmb();
1307		if (unlikely(atomic_dec_and_test(&dev->phy.txerr_cnt))) {
1308			b43legacyerr(dev->wl, "Too many PHY TX errors, "
1309					      "restarting the controller\n");
1310			b43legacy_controller_restart(dev, "PHY TX errors");
1311		}
1312	}
1313
1314	if (unlikely(merged_dma_reason & (B43legacy_DMAIRQ_FATALMASK |
1315					  B43legacy_DMAIRQ_NONFATALMASK))) {
1316		if (merged_dma_reason & B43legacy_DMAIRQ_FATALMASK) {
1317			b43legacyerr(dev->wl, "Fatal DMA error: "
1318			       "0x%08X, 0x%08X, 0x%08X, "
1319			       "0x%08X, 0x%08X, 0x%08X\n",
1320			       dma_reason[0], dma_reason[1],
1321			       dma_reason[2], dma_reason[3],
1322			       dma_reason[4], dma_reason[5]);
1323			b43legacy_controller_restart(dev, "DMA error");
1324			mmiowb();
1325			spin_unlock_irqrestore(&dev->wl->irq_lock, flags);
1326			return;
1327		}
1328		if (merged_dma_reason & B43legacy_DMAIRQ_NONFATALMASK)
1329			b43legacyerr(dev->wl, "DMA error: "
1330			       "0x%08X, 0x%08X, 0x%08X, "
1331			       "0x%08X, 0x%08X, 0x%08X\n",
1332			       dma_reason[0], dma_reason[1],
1333			       dma_reason[2], dma_reason[3],
1334			       dma_reason[4], dma_reason[5]);
1335	}
1336
1337	if (unlikely(reason & B43legacy_IRQ_UCODE_DEBUG))
1338		handle_irq_ucode_debug(dev);
1339	if (reason & B43legacy_IRQ_TBTT_INDI)
1340		handle_irq_tbtt_indication(dev);
1341	if (reason & B43legacy_IRQ_ATIM_END)
1342		handle_irq_atim_end(dev);
1343	if (reason & B43legacy_IRQ_BEACON)
1344		handle_irq_beacon(dev);
1345	if (reason & B43legacy_IRQ_PMQ)
1346		handle_irq_pmq(dev);
1347	if (reason & B43legacy_IRQ_TXFIFO_FLUSH_OK)
1348		;/*TODO*/
1349	if (reason & B43legacy_IRQ_NOISESAMPLE_OK)
1350		handle_irq_noise(dev);
1351
1352	/* Check the DMA reason registers for received data. */
1353	if (dma_reason[0] & B43legacy_DMAIRQ_RX_DONE) {
1354		if (b43legacy_using_pio(dev))
1355			b43legacy_pio_rx(dev->pio.queue0);
1356		else
1357			b43legacy_dma_rx(dev->dma.rx_ring0);
1358	}
1359	B43legacy_WARN_ON(dma_reason[1] & B43legacy_DMAIRQ_RX_DONE);
1360	B43legacy_WARN_ON(dma_reason[2] & B43legacy_DMAIRQ_RX_DONE);
1361	if (dma_reason[3] & B43legacy_DMAIRQ_RX_DONE) {
1362		if (b43legacy_using_pio(dev))
1363			b43legacy_pio_rx(dev->pio.queue3);
1364		else
1365			b43legacy_dma_rx(dev->dma.rx_ring3);
1366	}
1367	B43legacy_WARN_ON(dma_reason[4] & B43legacy_DMAIRQ_RX_DONE);
1368	B43legacy_WARN_ON(dma_reason[5] & B43legacy_DMAIRQ_RX_DONE);
1369
1370	if (reason & B43legacy_IRQ_TX_OK)
1371		handle_irq_transmit_status(dev);
1372
1373	b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_MASK, dev->irq_mask);
1374	mmiowb();
1375	spin_unlock_irqrestore(&dev->wl->irq_lock, flags);
1376}
1377
1378static void pio_irq_workaround(struct b43legacy_wldev *dev,
1379			       u16 base, int queueidx)
1380{
1381	u16 rxctl;
1382
1383	rxctl = b43legacy_read16(dev, base + B43legacy_PIO_RXCTL);
1384	if (rxctl & B43legacy_PIO_RXCTL_DATAAVAILABLE)
1385		dev->dma_reason[queueidx] |= B43legacy_DMAIRQ_RX_DONE;
1386	else
1387		dev->dma_reason[queueidx] &= ~B43legacy_DMAIRQ_RX_DONE;
1388}
1389
1390static void b43legacy_interrupt_ack(struct b43legacy_wldev *dev, u32 reason)
1391{
1392	if (b43legacy_using_pio(dev) &&
1393	    (dev->dev->id.revision < 3) &&
1394	    (!(reason & B43legacy_IRQ_PIO_WORKAROUND))) {
1395		pio_irq_workaround(dev, B43legacy_MMIO_PIO1_BASE, 0);
1396		pio_irq_workaround(dev, B43legacy_MMIO_PIO2_BASE, 1);
1397		pio_irq_workaround(dev, B43legacy_MMIO_PIO3_BASE, 2);
1398		pio_irq_workaround(dev, B43legacy_MMIO_PIO4_BASE, 3);
1399	}
1400
1401	b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_REASON, reason);
1402
1403	b43legacy_write32(dev, B43legacy_MMIO_DMA0_REASON,
1404			  dev->dma_reason[0]);
1405	b43legacy_write32(dev, B43legacy_MMIO_DMA1_REASON,
1406			  dev->dma_reason[1]);
1407	b43legacy_write32(dev, B43legacy_MMIO_DMA2_REASON,
1408			  dev->dma_reason[2]);
1409	b43legacy_write32(dev, B43legacy_MMIO_DMA3_REASON,
1410			  dev->dma_reason[3]);
1411	b43legacy_write32(dev, B43legacy_MMIO_DMA4_REASON,
1412			  dev->dma_reason[4]);
1413	b43legacy_write32(dev, B43legacy_MMIO_DMA5_REASON,
1414			  dev->dma_reason[5]);
1415}
1416
1417/* Interrupt handler top-half */
1418static irqreturn_t b43legacy_interrupt_handler(int irq, void *dev_id)
1419{
1420	irqreturn_t ret = IRQ_NONE;
1421	struct b43legacy_wldev *dev = dev_id;
1422	u32 reason;
1423
1424	B43legacy_WARN_ON(!dev);
1425
1426	spin_lock(&dev->wl->irq_lock);
1427
1428	if (unlikely(b43legacy_status(dev) < B43legacy_STAT_STARTED))
1429		/* This can only happen on shared IRQ lines. */
1430		goto out;
1431	reason = b43legacy_read32(dev, B43legacy_MMIO_GEN_IRQ_REASON);
1432	if (reason == 0xffffffff) /* shared IRQ */
1433		goto out;
1434	ret = IRQ_HANDLED;
1435	reason &= dev->irq_mask;
1436	if (!reason)
1437		goto out;
1438
1439	dev->dma_reason[0] = b43legacy_read32(dev,
1440					      B43legacy_MMIO_DMA0_REASON)
1441					      & 0x0001DC00;
1442	dev->dma_reason[1] = b43legacy_read32(dev,
1443					      B43legacy_MMIO_DMA1_REASON)
1444					      & 0x0000DC00;
1445	dev->dma_reason[2] = b43legacy_read32(dev,
1446					      B43legacy_MMIO_DMA2_REASON)
1447					      & 0x0000DC00;
1448	dev->dma_reason[3] = b43legacy_read32(dev,
1449					      B43legacy_MMIO_DMA3_REASON)
1450					      & 0x0001DC00;
1451	dev->dma_reason[4] = b43legacy_read32(dev,
1452					      B43legacy_MMIO_DMA4_REASON)
1453					      & 0x0000DC00;
1454	dev->dma_reason[5] = b43legacy_read32(dev,
1455					      B43legacy_MMIO_DMA5_REASON)
1456					      & 0x0000DC00;
1457
1458	b43legacy_interrupt_ack(dev, reason);
1459	/* Disable all IRQs. They are enabled again in the bottom half. */
1460	b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_MASK, 0);
1461	/* Save the reason code and call our bottom half. */
1462	dev->irq_reason = reason;
1463	tasklet_schedule(&dev->isr_tasklet);
1464out:
1465	mmiowb();
1466	spin_unlock(&dev->wl->irq_lock);
1467
1468	return ret;
1469}
1470
1471static void b43legacy_release_firmware(struct b43legacy_wldev *dev)
1472{
1473	release_firmware(dev->fw.ucode);
1474	dev->fw.ucode = NULL;
1475	release_firmware(dev->fw.pcm);
1476	dev->fw.pcm = NULL;
1477	release_firmware(dev->fw.initvals);
1478	dev->fw.initvals = NULL;
1479	release_firmware(dev->fw.initvals_band);
1480	dev->fw.initvals_band = NULL;
1481}
1482
1483static void b43legacy_print_fw_helptext(struct b43legacy_wl *wl)
1484{
1485	b43legacyerr(wl, "You must go to http://linuxwireless.org/en/users/"
1486		     "Drivers/b43#devicefirmware "
1487		     "and download the correct firmware (version 3).\n");
1488}
1489
1490static int do_request_fw(struct b43legacy_wldev *dev,
1491			 const char *name,
1492			 const struct firmware **fw)
1493{
1494	char path[sizeof(modparam_fwpostfix) + 32];
1495	struct b43legacy_fw_header *hdr;
1496	u32 size;
1497	int err;
1498
1499	if (!name)
1500		return 0;
1501
1502	snprintf(path, ARRAY_SIZE(path),
1503		 "b43legacy%s/%s.fw",
1504		 modparam_fwpostfix, name);
1505	err = request_firmware(fw, path, dev->dev->dev);
1506	if (err) {
1507		b43legacyerr(dev->wl, "Firmware file \"%s\" not found "
1508		       "or load failed.\n", path);
1509		return err;
1510	}
1511	if ((*fw)->size < sizeof(struct b43legacy_fw_header))
1512		goto err_format;
1513	hdr = (struct b43legacy_fw_header *)((*fw)->data);
1514	switch (hdr->type) {
1515	case B43legacy_FW_TYPE_UCODE:
1516	case B43legacy_FW_TYPE_PCM:
1517		size = be32_to_cpu(hdr->size);
1518		if (size != (*fw)->size - sizeof(struct b43legacy_fw_header))
1519			goto err_format;
1520		/* fallthrough */
1521	case B43legacy_FW_TYPE_IV:
1522		if (hdr->ver != 1)
1523			goto err_format;
1524		break;
1525	default:
1526		goto err_format;
1527	}
1528
1529	return err;
1530
1531err_format:
1532	b43legacyerr(dev->wl, "Firmware file \"%s\" format error.\n", path);
1533	return -EPROTO;
1534}
1535
1536static int b43legacy_request_firmware(struct b43legacy_wldev *dev)
1537{
1538	struct b43legacy_firmware *fw = &dev->fw;
1539	const u8 rev = dev->dev->id.revision;
1540	const char *filename;
1541	u32 tmshigh;
1542	int err;
1543
1544	tmshigh = ssb_read32(dev->dev, SSB_TMSHIGH);
1545	if (!fw->ucode) {
1546		if (rev == 2)
1547			filename = "ucode2";
1548		else if (rev == 4)
1549			filename = "ucode4";
1550		else
1551			filename = "ucode5";
1552		err = do_request_fw(dev, filename, &fw->ucode);
1553		if (err)
1554			goto err_load;
1555	}
1556	if (!fw->pcm) {
1557		if (rev < 5)
1558			filename = "pcm4";
1559		else
1560			filename = "pcm5";
1561		err = do_request_fw(dev, filename, &fw->pcm);
1562		if (err)
1563			goto err_load;
1564	}
1565	if (!fw->initvals) {
1566		switch (dev->phy.type) {
1567		case B43legacy_PHYTYPE_B:
1568		case B43legacy_PHYTYPE_G:
1569			if ((rev >= 5) && (rev <= 10))
1570				filename = "b0g0initvals5";
1571			else if (rev == 2 || rev == 4)
1572				filename = "b0g0initvals2";
1573			else
1574				goto err_no_initvals;
1575			break;
1576		default:
1577			goto err_no_initvals;
1578		}
1579		err = do_request_fw(dev, filename, &fw->initvals);
1580		if (err)
1581			goto err_load;
1582	}
1583	if (!fw->initvals_band) {
1584		switch (dev->phy.type) {
1585		case B43legacy_PHYTYPE_B:
1586		case B43legacy_PHYTYPE_G:
1587			if ((rev >= 5) && (rev <= 10))
1588				filename = "b0g0bsinitvals5";
1589			else if (rev >= 11)
1590				filename = NULL;
1591			else if (rev == 2 || rev == 4)
1592				filename = NULL;
1593			else
1594				goto err_no_initvals;
1595			break;
1596		default:
1597			goto err_no_initvals;
1598		}
1599		err = do_request_fw(dev, filename, &fw->initvals_band);
1600		if (err)
1601			goto err_load;
1602	}
1603
1604	return 0;
1605
1606err_load:
1607	b43legacy_print_fw_helptext(dev->wl);
1608	goto error;
1609
1610err_no_initvals:
1611	err = -ENODEV;
1612	b43legacyerr(dev->wl, "No Initial Values firmware file for PHY %u, "
1613	       "core rev %u\n", dev->phy.type, rev);
1614	goto error;
1615
1616error:
1617	b43legacy_release_firmware(dev);
1618	return err;
1619}
1620
1621static int b43legacy_upload_microcode(struct b43legacy_wldev *dev)
1622{
1623	const size_t hdr_len = sizeof(struct b43legacy_fw_header);
1624	const __be32 *data;
1625	unsigned int i;
1626	unsigned int len;
1627	u16 fwrev;
1628	u16 fwpatch;
1629	u16 fwdate;
1630	u16 fwtime;
1631	u32 tmp, macctl;
1632	int err = 0;
1633
1634	/* Jump the microcode PSM to offset 0 */
1635	macctl = b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
1636	B43legacy_WARN_ON(macctl & B43legacy_MACCTL_PSM_RUN);
1637	macctl |= B43legacy_MACCTL_PSM_JMP0;
1638	b43legacy_write32(dev, B43legacy_MMIO_MACCTL, macctl);
1639	/* Zero out all microcode PSM registers and shared memory. */
1640	for (i = 0; i < 64; i++)
1641		b43legacy_shm_write16(dev, B43legacy_SHM_WIRELESS, i, 0);
1642	for (i = 0; i < 4096; i += 2)
1643		b43legacy_shm_write16(dev, B43legacy_SHM_SHARED, i, 0);
1644
1645	/* Upload Microcode. */
1646	data = (__be32 *) (dev->fw.ucode->data + hdr_len);
1647	len = (dev->fw.ucode->size - hdr_len) / sizeof(__be32);
1648	b43legacy_shm_control_word(dev,
1649				   B43legacy_SHM_UCODE |
1650				   B43legacy_SHM_AUTOINC_W,
1651				   0x0000);
1652	for (i = 0; i < len; i++) {
1653		b43legacy_write32(dev, B43legacy_MMIO_SHM_DATA,
1654				    be32_to_cpu(data[i]));
1655		udelay(10);
1656	}
1657
1658	if (dev->fw.pcm) {
1659		/* Upload PCM data. */
1660		data = (__be32 *) (dev->fw.pcm->data + hdr_len);
1661		len = (dev->fw.pcm->size - hdr_len) / sizeof(__be32);
1662		b43legacy_shm_control_word(dev, B43legacy_SHM_HW, 0x01EA);
1663		b43legacy_write32(dev, B43legacy_MMIO_SHM_DATA, 0x00004000);
1664		/* No need for autoinc bit in SHM_HW */
1665		b43legacy_shm_control_word(dev, B43legacy_SHM_HW, 0x01EB);
1666		for (i = 0; i < len; i++) {
1667			b43legacy_write32(dev, B43legacy_MMIO_SHM_DATA,
1668					  be32_to_cpu(data[i]));
1669			udelay(10);
1670		}
1671	}
1672
1673	b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_REASON,
1674			  B43legacy_IRQ_ALL);
1675
1676	/* Start the microcode PSM */
1677	macctl = b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
1678	macctl &= ~B43legacy_MACCTL_PSM_JMP0;
1679	macctl |= B43legacy_MACCTL_PSM_RUN;
1680	b43legacy_write32(dev, B43legacy_MMIO_MACCTL, macctl);
1681
1682	/* Wait for the microcode to load and respond */
1683	i = 0;
1684	while (1) {
1685		tmp = b43legacy_read32(dev, B43legacy_MMIO_GEN_IRQ_REASON);
1686		if (tmp == B43legacy_IRQ_MAC_SUSPENDED)
1687			break;
1688		i++;
1689		if (i >= B43legacy_IRQWAIT_MAX_RETRIES) {
1690			b43legacyerr(dev->wl, "Microcode not responding\n");
1691			b43legacy_print_fw_helptext(dev->wl);
1692			err = -ENODEV;
1693			goto error;
1694		}
1695		msleep_interruptible(50);
1696		if (signal_pending(current)) {
1697			err = -EINTR;
1698			goto error;
1699		}
1700	}
1701	/* dummy read follows */
1702	b43legacy_read32(dev, B43legacy_MMIO_GEN_IRQ_REASON);
1703
1704	/* Get and check the revisions. */
1705	fwrev = b43legacy_shm_read16(dev, B43legacy_SHM_SHARED,
1706				     B43legacy_SHM_SH_UCODEREV);
1707	fwpatch = b43legacy_shm_read16(dev, B43legacy_SHM_SHARED,
1708				       B43legacy_SHM_SH_UCODEPATCH);
1709	fwdate = b43legacy_shm_read16(dev, B43legacy_SHM_SHARED,
1710				      B43legacy_SHM_SH_UCODEDATE);
1711	fwtime = b43legacy_shm_read16(dev, B43legacy_SHM_SHARED,
1712				      B43legacy_SHM_SH_UCODETIME);
1713
1714	if (fwrev > 0x128) {
1715		b43legacyerr(dev->wl, "YOU ARE TRYING TO LOAD V4 FIRMWARE."
1716			     " Only firmware from binary drivers version 3.x"
1717			     " is supported. You must change your firmware"
1718			     " files.\n");
1719		b43legacy_print_fw_helptext(dev->wl);
1720		err = -EOPNOTSUPP;
1721		goto error;
1722	}
1723	b43legacyinfo(dev->wl, "Loading firmware version 0x%X, patch level %u "
1724		      "(20%.2i-%.2i-%.2i %.2i:%.2i:%.2i)\n", fwrev, fwpatch,
1725		      (fwdate >> 12) & 0xF, (fwdate >> 8) & 0xF, fwdate & 0xFF,
1726		      (fwtime >> 11) & 0x1F, (fwtime >> 5) & 0x3F,
1727		      fwtime & 0x1F);
1728
1729	dev->fw.rev = fwrev;
1730	dev->fw.patch = fwpatch;
1731
1732	return 0;
1733
1734error:
1735	macctl = b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
1736	macctl &= ~B43legacy_MACCTL_PSM_RUN;
1737	macctl |= B43legacy_MACCTL_PSM_JMP0;
1738	b43legacy_write32(dev, B43legacy_MMIO_MACCTL, macctl);
1739
1740	return err;
1741}
1742
1743static int b43legacy_write_initvals(struct b43legacy_wldev *dev,
1744				    const struct b43legacy_iv *ivals,
1745				    size_t count,
1746				    size_t array_size)
1747{
1748	const struct b43legacy_iv *iv;
1749	u16 offset;
1750	size_t i;
1751	bool bit32;
1752
1753	BUILD_BUG_ON(sizeof(struct b43legacy_iv) != 6);
1754	iv = ivals;
1755	for (i = 0; i < count; i++) {
1756		if (array_size < sizeof(iv->offset_size))
1757			goto err_format;
1758		array_size -= sizeof(iv->offset_size);
1759		offset = be16_to_cpu(iv->offset_size);
1760		bit32 = !!(offset & B43legacy_IV_32BIT);
1761		offset &= B43legacy_IV_OFFSET_MASK;
1762		if (offset >= 0x1000)
1763			goto err_format;
1764		if (bit32) {
1765			u32 value;
1766
1767			if (array_size < sizeof(iv->data.d32))
1768				goto err_format;
1769			array_size -= sizeof(iv->data.d32);
1770
1771			value = get_unaligned_be32(&iv->data.d32);
1772			b43legacy_write32(dev, offset, value);
1773
1774			iv = (const struct b43legacy_iv *)((const uint8_t *)iv +
1775							sizeof(__be16) +
1776							sizeof(__be32));
1777		} else {
1778			u16 value;
1779
1780			if (array_size < sizeof(iv->data.d16))
1781				goto err_format;
1782			array_size -= sizeof(iv->data.d16);
1783
1784			value = be16_to_cpu(iv->data.d16);
1785			b43legacy_write16(dev, offset, value);
1786
1787			iv = (const struct b43legacy_iv *)((const uint8_t *)iv +
1788							sizeof(__be16) +
1789							sizeof(__be16));
1790		}
1791	}
1792	if (array_size)
1793		goto err_format;
1794
1795	return 0;
1796
1797err_format:
1798	b43legacyerr(dev->wl, "Initial Values Firmware file-format error.\n");
1799	b43legacy_print_fw_helptext(dev->wl);
1800
1801	return -EPROTO;
1802}
1803
1804static int b43legacy_upload_initvals(struct b43legacy_wldev *dev)
1805{
1806	const size_t hdr_len = sizeof(struct b43legacy_fw_header);
1807	const struct b43legacy_fw_header *hdr;
1808	struct b43legacy_firmware *fw = &dev->fw;
1809	const struct b43legacy_iv *ivals;
1810	size_t count;
1811	int err;
1812
1813	hdr = (const struct b43legacy_fw_header *)(fw->initvals->data);
1814	ivals = (const struct b43legacy_iv *)(fw->initvals->data + hdr_len);
1815	count = be32_to_cpu(hdr->size);
1816	err = b43legacy_write_initvals(dev, ivals, count,
1817				 fw->initvals->size - hdr_len);
1818	if (err)
1819		goto out;
1820	if (fw->initvals_band) {
1821		hdr = (const struct b43legacy_fw_header *)
1822		      (fw->initvals_band->data);
1823		ivals = (const struct b43legacy_iv *)(fw->initvals_band->data
1824			+ hdr_len);
1825		count = be32_to_cpu(hdr->size);
1826		err = b43legacy_write_initvals(dev, ivals, count,
1827					 fw->initvals_band->size - hdr_len);
1828		if (err)
1829			goto out;
1830	}
1831out:
1832
1833	return err;
1834}
1835
1836/* Initialize the GPIOs
1837 * http://bcm-specs.sipsolutions.net/GPIO
1838 */
1839static int b43legacy_gpio_init(struct b43legacy_wldev *dev)
1840{
1841	struct ssb_bus *bus = dev->dev->bus;
1842	struct ssb_device *gpiodev, *pcidev = NULL;
1843	u32 mask;
1844	u32 set;
1845
1846	b43legacy_write32(dev, B43legacy_MMIO_MACCTL,
1847			  b43legacy_read32(dev,
1848			  B43legacy_MMIO_MACCTL)
1849			  & 0xFFFF3FFF);
1850
1851	b43legacy_write16(dev, B43legacy_MMIO_GPIO_MASK,
1852			  b43legacy_read16(dev,
1853			  B43legacy_MMIO_GPIO_MASK)
1854			  | 0x000F);
1855
1856	mask = 0x0000001F;
1857	set = 0x0000000F;
1858	if (dev->dev->bus->chip_id == 0x4301) {
1859		mask |= 0x0060;
1860		set |= 0x0060;
1861	}
1862	if (dev->dev->bus->sprom.boardflags_lo & B43legacy_BFL_PACTRL) {
1863		b43legacy_write16(dev, B43legacy_MMIO_GPIO_MASK,
1864				  b43legacy_read16(dev,
1865				  B43legacy_MMIO_GPIO_MASK)
1866				  | 0x0200);
1867		mask |= 0x0200;
1868		set |= 0x0200;
1869	}
1870	if (dev->dev->id.revision >= 2)
1871		mask  |= 0x0010;
1872
1873#ifdef CONFIG_SSB_DRIVER_PCICORE
1874	pcidev = bus->pcicore.dev;
1875#endif
1876	gpiodev = bus->chipco.dev ? : pcidev;
1877	if (!gpiodev)
1878		return 0;
1879	ssb_write32(gpiodev, B43legacy_GPIO_CONTROL,
1880		    (ssb_read32(gpiodev, B43legacy_GPIO_CONTROL)
1881		     & mask) | set);
1882
1883	return 0;
1884}
1885
1886/* Turn off all GPIO stuff. Call this on module unload, for example. */
1887static void b43legacy_gpio_cleanup(struct b43legacy_wldev *dev)
1888{
1889	struct ssb_bus *bus = dev->dev->bus;
1890	struct ssb_device *gpiodev, *pcidev = NULL;
1891
1892#ifdef CONFIG_SSB_DRIVER_PCICORE
1893	pcidev = bus->pcicore.dev;
1894#endif
1895	gpiodev = bus->chipco.dev ? : pcidev;
1896	if (!gpiodev)
1897		return;
1898	ssb_write32(gpiodev, B43legacy_GPIO_CONTROL, 0);
1899}
1900
1901/* http://bcm-specs.sipsolutions.net/EnableMac */
1902void b43legacy_mac_enable(struct b43legacy_wldev *dev)
1903{
1904	dev->mac_suspended--;
1905	B43legacy_WARN_ON(dev->mac_suspended < 0);
1906	B43legacy_WARN_ON(irqs_disabled());
1907	if (dev->mac_suspended == 0) {
1908		b43legacy_write32(dev, B43legacy_MMIO_MACCTL,
1909				  b43legacy_read32(dev,
1910				  B43legacy_MMIO_MACCTL)
1911				  | B43legacy_MACCTL_ENABLED);
1912		b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_REASON,
1913				  B43legacy_IRQ_MAC_SUSPENDED);
1914		/* the next two are dummy reads */
1915		b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
1916		b43legacy_read32(dev, B43legacy_MMIO_GEN_IRQ_REASON);
1917		b43legacy_power_saving_ctl_bits(dev, -1, -1);
1918
1919		/* Re-enable IRQs. */
1920		spin_lock_irq(&dev->wl->irq_lock);
1921		b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_MASK,
1922				  dev->irq_mask);
1923		spin_unlock_irq(&dev->wl->irq_lock);
1924	}
1925}
1926
1927/* http://bcm-specs.sipsolutions.net/SuspendMAC */
1928void b43legacy_mac_suspend(struct b43legacy_wldev *dev)
1929{
1930	int i;
1931	u32 tmp;
1932
1933	might_sleep();
1934	B43legacy_WARN_ON(irqs_disabled());
1935	B43legacy_WARN_ON(dev->mac_suspended < 0);
1936
1937	if (dev->mac_suspended == 0) {
1938		/* Mask IRQs before suspending MAC. Otherwise
1939		 * the MAC stays busy and won't suspend. */
1940		spin_lock_irq(&dev->wl->irq_lock);
1941		b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_MASK, 0);
1942		spin_unlock_irq(&dev->wl->irq_lock);
1943		b43legacy_synchronize_irq(dev);
1944
1945		b43legacy_power_saving_ctl_bits(dev, -1, 1);
1946		b43legacy_write32(dev, B43legacy_MMIO_MACCTL,
1947				  b43legacy_read32(dev,
1948				  B43legacy_MMIO_MACCTL)
1949				  & ~B43legacy_MACCTL_ENABLED);
1950		b43legacy_read32(dev, B43legacy_MMIO_GEN_IRQ_REASON);
1951		for (i = 40; i; i--) {
1952			tmp = b43legacy_read32(dev,
1953					       B43legacy_MMIO_GEN_IRQ_REASON);
1954			if (tmp & B43legacy_IRQ_MAC_SUSPENDED)
1955				goto out;
1956			msleep(1);
1957		}
1958		b43legacyerr(dev->wl, "MAC suspend failed\n");
1959	}
1960out:
1961	dev->mac_suspended++;
1962}
1963
1964static void b43legacy_adjust_opmode(struct b43legacy_wldev *dev)
1965{
1966	struct b43legacy_wl *wl = dev->wl;
1967	u32 ctl;
1968	u16 cfp_pretbtt;
1969
1970	ctl = b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
1971	/* Reset status to STA infrastructure mode. */
1972	ctl &= ~B43legacy_MACCTL_AP;
1973	ctl &= ~B43legacy_MACCTL_KEEP_CTL;
1974	ctl &= ~B43legacy_MACCTL_KEEP_BADPLCP;
1975	ctl &= ~B43legacy_MACCTL_KEEP_BAD;
1976	ctl &= ~B43legacy_MACCTL_PROMISC;
1977	ctl &= ~B43legacy_MACCTL_BEACPROMISC;
1978	ctl |= B43legacy_MACCTL_INFRA;
1979
1980	if (b43legacy_is_mode(wl, NL80211_IFTYPE_AP))
1981		ctl |= B43legacy_MACCTL_AP;
1982	else if (b43legacy_is_mode(wl, NL80211_IFTYPE_ADHOC))
1983		ctl &= ~B43legacy_MACCTL_INFRA;
1984
1985	if (wl->filter_flags & FIF_CONTROL)
1986		ctl |= B43legacy_MACCTL_KEEP_CTL;
1987	if (wl->filter_flags & FIF_FCSFAIL)
1988		ctl |= B43legacy_MACCTL_KEEP_BAD;
1989	if (wl->filter_flags & FIF_PLCPFAIL)
1990		ctl |= B43legacy_MACCTL_KEEP_BADPLCP;
1991	if (wl->filter_flags & FIF_PROMISC_IN_BSS)
1992		ctl |= B43legacy_MACCTL_PROMISC;
1993	if (wl->filter_flags & FIF_BCN_PRBRESP_PROMISC)
1994		ctl |= B43legacy_MACCTL_BEACPROMISC;
1995
1996	if (dev->dev->id.revision <= 4)
1997		ctl |= B43legacy_MACCTL_PROMISC;
1998
1999	b43legacy_write32(dev, B43legacy_MMIO_MACCTL, ctl);
2000
2001	cfp_pretbtt = 2;
2002	if ((ctl & B43legacy_MACCTL_INFRA) &&
2003	    !(ctl & B43legacy_MACCTL_AP)) {
2004		if (dev->dev->bus->chip_id == 0x4306 &&
2005		    dev->dev->bus->chip_rev == 3)
2006			cfp_pretbtt = 100;
2007		else
2008			cfp_pretbtt = 50;
2009	}
2010	b43legacy_write16(dev, 0x612, cfp_pretbtt);
2011}
2012
2013static void b43legacy_rate_memory_write(struct b43legacy_wldev *dev,
2014					u16 rate,
2015					int is_ofdm)
2016{
2017	u16 offset;
2018
2019	if (is_ofdm) {
2020		offset = 0x480;
2021		offset += (b43legacy_plcp_get_ratecode_ofdm(rate) & 0x000F) * 2;
2022	} else {
2023		offset = 0x4C0;
2024		offset += (b43legacy_plcp_get_ratecode_cck(rate) & 0x000F) * 2;
2025	}
2026	b43legacy_shm_write16(dev, B43legacy_SHM_SHARED, offset + 0x20,
2027			      b43legacy_shm_read16(dev,
2028			      B43legacy_SHM_SHARED, offset));
2029}
2030
2031static void b43legacy_rate_memory_init(struct b43legacy_wldev *dev)
2032{
2033	switch (dev->phy.type) {
2034	case B43legacy_PHYTYPE_G:
2035		b43legacy_rate_memory_write(dev, B43legacy_OFDM_RATE_6MB, 1);
2036		b43legacy_rate_memory_write(dev, B43legacy_OFDM_RATE_12MB, 1);
2037		b43legacy_rate_memory_write(dev, B43legacy_OFDM_RATE_18MB, 1);
2038		b43legacy_rate_memory_write(dev, B43legacy_OFDM_RATE_24MB, 1);
2039		b43legacy_rate_memory_write(dev, B43legacy_OFDM_RATE_36MB, 1);
2040		b43legacy_rate_memory_write(dev, B43legacy_OFDM_RATE_48MB, 1);
2041		b43legacy_rate_memory_write(dev, B43legacy_OFDM_RATE_54MB, 1);
2042		/* fallthrough */
2043	case B43legacy_PHYTYPE_B:
2044		b43legacy_rate_memory_write(dev, B43legacy_CCK_RATE_1MB, 0);
2045		b43legacy_rate_memory_write(dev, B43legacy_CCK_RATE_2MB, 0);
2046		b43legacy_rate_memory_write(dev, B43legacy_CCK_RATE_5MB, 0);
2047		b43legacy_rate_memory_write(dev, B43legacy_CCK_RATE_11MB, 0);
2048		break;
2049	default:
2050		B43legacy_BUG_ON(1);
2051	}
2052}
2053
2054/* Set the TX-Antenna for management frames sent by firmware. */
2055static void b43legacy_mgmtframe_txantenna(struct b43legacy_wldev *dev,
2056					  int antenna)
2057{
2058	u16 ant = 0;
2059	u16 tmp;
2060
2061	switch (antenna) {
2062	case B43legacy_ANTENNA0:
2063		ant |= B43legacy_TX4_PHY_ANT0;
2064		break;
2065	case B43legacy_ANTENNA1:
2066		ant |= B43legacy_TX4_PHY_ANT1;
2067		break;
2068	case B43legacy_ANTENNA_AUTO:
2069		ant |= B43legacy_TX4_PHY_ANTLAST;
2070		break;
2071	default:
2072		B43legacy_BUG_ON(1);
2073	}
2074
2075
2076	/* For Beacons */
2077	tmp = b43legacy_shm_read16(dev, B43legacy_SHM_SHARED,
2078				   B43legacy_SHM_SH_BEACPHYCTL);
2079	tmp = (tmp & ~B43legacy_TX4_PHY_ANT) | ant;
2080	b43legacy_shm_write16(dev, B43legacy_SHM_SHARED,
2081			      B43legacy_SHM_SH_BEACPHYCTL, tmp);
2082	/* For ACK/CTS */
2083	tmp = b43legacy_shm_read16(dev, B43legacy_SHM_SHARED,
2084				   B43legacy_SHM_SH_ACKCTSPHYCTL);
2085	tmp = (tmp & ~B43legacy_TX4_PHY_ANT) | ant;
2086	b43legacy_shm_write16(dev, B43legacy_SHM_SHARED,
2087			      B43legacy_SHM_SH_ACKCTSPHYCTL, tmp);
2088	/* For Probe Resposes */
2089	tmp = b43legacy_shm_read16(dev, B43legacy_SHM_SHARED,
2090				   B43legacy_SHM_SH_PRPHYCTL);
2091	tmp = (tmp & ~B43legacy_TX4_PHY_ANT) | ant;
2092	b43legacy_shm_write16(dev, B43legacy_SHM_SHARED,
2093			      B43legacy_SHM_SH_PRPHYCTL, tmp);
2094}
2095
2096/* This is the opposite of b43legacy_chip_init() */
2097static void b43legacy_chip_exit(struct b43legacy_wldev *dev)
2098{
2099	b43legacy_radio_turn_off(dev, 1);
2100	b43legacy_gpio_cleanup(dev);
2101	/* firmware is released later */
2102}
2103
2104/* Initialize the chip
2105 * http://bcm-specs.sipsolutions.net/ChipInit
2106 */
2107static int b43legacy_chip_init(struct b43legacy_wldev *dev)
2108{
2109	struct b43legacy_phy *phy = &dev->phy;
2110	int err;
2111	int tmp;
2112	u32 value32, macctl;
2113	u16 value16;
2114
2115	/* Initialize the MAC control */
2116	macctl = B43legacy_MACCTL_IHR_ENABLED | B43legacy_MACCTL_SHM_ENABLED;
2117	if (dev->phy.gmode)
2118		macctl |= B43legacy_MACCTL_GMODE;
2119	macctl |= B43legacy_MACCTL_INFRA;
2120	b43legacy_write32(dev, B43legacy_MMIO_MACCTL, macctl);
2121
2122	err = b43legacy_request_firmware(dev);
2123	if (err)
2124		goto out;
2125	err = b43legacy_upload_microcode(dev);
2126	if (err)
2127		goto out; /* firmware is released later */
2128
2129	err = b43legacy_gpio_init(dev);
2130	if (err)
2131		goto out; /* firmware is released later */
2132
2133	err = b43legacy_upload_initvals(dev);
2134	if (err)
2135		goto err_gpio_clean;
2136	b43legacy_radio_turn_on(dev);
2137
2138	b43legacy_write16(dev, 0x03E6, 0x0000);
2139	err = b43legacy_phy_init(dev);
2140	if (err)
2141		goto err_radio_off;
2142
2143	/* Select initial Interference Mitigation. */
2144	tmp = phy->interfmode;
2145	phy->interfmode = B43legacy_INTERFMODE_NONE;
2146	b43legacy_radio_set_interference_mitigation(dev, tmp);
2147
2148	b43legacy_phy_set_antenna_diversity(dev);
2149	b43legacy_mgmtframe_txantenna(dev, B43legacy_ANTENNA_DEFAULT);
2150
2151	if (phy->type == B43legacy_PHYTYPE_B) {
2152		value16 = b43legacy_read16(dev, 0x005E);
2153		value16 |= 0x0004;
2154		b43legacy_write16(dev, 0x005E, value16);
2155	}
2156	b43legacy_write32(dev, 0x0100, 0x01000000);
2157	if (dev->dev->id.revision < 5)
2158		b43legacy_write32(dev, 0x010C, 0x01000000);
2159
2160	value32 = b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
2161	value32 &= ~B43legacy_MACCTL_INFRA;
2162	b43legacy_write32(dev, B43legacy_MMIO_MACCTL, value32);
2163	value32 = b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
2164	value32 |= B43legacy_MACCTL_INFRA;
2165	b43legacy_write32(dev, B43legacy_MMIO_MACCTL, value32);
2166
2167	if (b43legacy_using_pio(dev)) {
2168		b43legacy_write32(dev, 0x0210, 0x00000100);
2169		b43legacy_write32(dev, 0x0230, 0x00000100);
2170		b43legacy_write32(dev, 0x0250, 0x00000100);
2171		b43legacy_write32(dev, 0x0270, 0x00000100);
2172		b43legacy_shm_write16(dev, B43legacy_SHM_SHARED, 0x0034,
2173				      0x0000);
2174	}
2175
2176	/* Probe Response Timeout value */
2177	b43legacy_shm_write16(dev, B43legacy_SHM_SHARED, 0x0074, 0x0000);
2178
2179	/* Initially set the wireless operation mode. */
2180	b43legacy_adjust_opmode(dev);
2181
2182	if (dev->dev->id.revision < 3) {
2183		b43legacy_write16(dev, 0x060E, 0x0000);
2184		b43legacy_write16(dev, 0x0610, 0x8000);
2185		b43legacy_write16(dev, 0x0604, 0x0000);
2186		b43legacy_write16(dev, 0x0606, 0x0200);
2187	} else {
2188		b43legacy_write32(dev, 0x0188, 0x80000000);
2189		b43legacy_write32(dev, 0x018C, 0x02000000);
2190	}
2191	b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_REASON, 0x00004000);
2192	b43legacy_write32(dev, B43legacy_MMIO_DMA0_IRQ_MASK, 0x0001DC00);
2193	b43legacy_write32(dev, B43legacy_MMIO_DMA1_IRQ_MASK, 0x0000DC00);
2194	b43legacy_write32(dev, B43legacy_MMIO_DMA2_IRQ_MASK, 0x0000DC00);
2195	b43legacy_write32(dev, B43legacy_MMIO_DMA3_IRQ_MASK, 0x0001DC00);
2196	b43legacy_write32(dev, B43legacy_MMIO_DMA4_IRQ_MASK, 0x0000DC00);
2197	b43legacy_write32(dev, B43legacy_MMIO_DMA5_IRQ_MASK, 0x0000DC00);
2198
2199	value32 = ssb_read32(dev->dev, SSB_TMSLOW);
2200	value32 |= 0x00100000;
2201	ssb_write32(dev->dev, SSB_TMSLOW, value32);
2202
2203	b43legacy_write16(dev, B43legacy_MMIO_POWERUP_DELAY,
2204			  dev->dev->bus->chipco.fast_pwrup_delay);
2205
2206	/* PHY TX errors counter. */
2207	atomic_set(&phy->txerr_cnt, B43legacy_PHY_TX_BADNESS_LIMIT);
2208
2209	B43legacy_WARN_ON(err != 0);
2210	b43legacydbg(dev->wl, "Chip initialized\n");
2211out:
2212	return err;
2213
2214err_radio_off:
2215	b43legacy_radio_turn_off(dev, 1);
2216err_gpio_clean:
2217	b43legacy_gpio_cleanup(dev);
2218	goto out;
2219}
2220
2221static void b43legacy_periodic_every120sec(struct b43legacy_wldev *dev)
2222{
2223	struct b43legacy_phy *phy = &dev->phy;
2224
2225	if (phy->type != B43legacy_PHYTYPE_G || phy->rev < 2)
2226		return;
2227
2228	b43legacy_mac_suspend(dev);
2229	b43legacy_phy_lo_g_measure(dev);
2230	b43legacy_mac_enable(dev);
2231}
2232
2233static void b43legacy_periodic_every60sec(struct b43legacy_wldev *dev)
2234{
2235	b43legacy_phy_lo_mark_all_unused(dev);
2236	if (dev->dev->bus->sprom.boardflags_lo & B43legacy_BFL_RSSI) {
2237		b43legacy_mac_suspend(dev);
2238		b43legacy_calc_nrssi_slope(dev);
2239		b43legacy_mac_enable(dev);
2240	}
2241}
2242
2243static void b43legacy_periodic_every30sec(struct b43legacy_wldev *dev)
2244{
2245	/* Update device statistics. */
2246	b43legacy_calculate_link_quality(dev);
2247}
2248
2249static void b43legacy_periodic_every15sec(struct b43legacy_wldev *dev)
2250{
2251	b43legacy_phy_xmitpower(dev);
2252
2253	atomic_set(&dev->phy.txerr_cnt, B43legacy_PHY_TX_BADNESS_LIMIT);
2254	wmb();
2255}
2256
2257static void do_periodic_work(struct b43legacy_wldev *dev)
2258{
2259	unsigned int state;
2260
2261	state = dev->periodic_state;
2262	if (state % 8 == 0)
2263		b43legacy_periodic_every120sec(dev);
2264	if (state % 4 == 0)
2265		b43legacy_periodic_every60sec(dev);
2266	if (state % 2 == 0)
2267		b43legacy_periodic_every30sec(dev);
2268	b43legacy_periodic_every15sec(dev);
2269}
2270
2271/* Periodic work locking policy:
2272 * 	The whole periodic work handler is protected by
2273 * 	wl->mutex. If another lock is needed somewhere in the
2274 * 	pwork callchain, it's acquired in-place, where it's needed.
2275 */
2276static void b43legacy_periodic_work_handler(struct work_struct *work)
2277{
2278	struct b43legacy_wldev *dev = container_of(work, struct b43legacy_wldev,
2279					     periodic_work.work);
2280	struct b43legacy_wl *wl = dev->wl;
2281	unsigned long delay;
2282
2283	mutex_lock(&wl->mutex);
2284
2285	if (unlikely(b43legacy_status(dev) != B43legacy_STAT_STARTED))
2286		goto out;
2287	if (b43legacy_debug(dev, B43legacy_DBG_PWORK_STOP))
2288		goto out_requeue;
2289
2290	do_periodic_work(dev);
2291
2292	dev->periodic_state++;
2293out_requeue:
2294	if (b43legacy_debug(dev, B43legacy_DBG_PWORK_FAST))
2295		delay = msecs_to_jiffies(50);
2296	else
2297		delay = round_jiffies_relative(HZ * 15);
2298	ieee80211_queue_delayed_work(wl->hw, &dev->periodic_work, delay);
2299out:
2300	mutex_unlock(&wl->mutex);
2301}
2302
2303static void b43legacy_periodic_tasks_setup(struct b43legacy_wldev *dev)
2304{
2305	struct delayed_work *work = &dev->periodic_work;
2306
2307	dev->periodic_state = 0;
2308	INIT_DELAYED_WORK(work, b43legacy_periodic_work_handler);
2309	ieee80211_queue_delayed_work(dev->wl->hw, work, 0);
2310}
2311
2312/* Validate access to the chip (SHM) */
2313static int b43legacy_validate_chipaccess(struct b43legacy_wldev *dev)
2314{
2315	u32 value;
2316	u32 shm_backup;
2317
2318	shm_backup = b43legacy_shm_read32(dev, B43legacy_SHM_SHARED, 0);
2319	b43legacy_shm_write32(dev, B43legacy_SHM_SHARED, 0, 0xAA5555AA);
2320	if (b43legacy_shm_read32(dev, B43legacy_SHM_SHARED, 0) !=
2321				 0xAA5555AA)
2322		goto error;
2323	b43legacy_shm_write32(dev, B43legacy_SHM_SHARED, 0, 0x55AAAA55);
2324	if (b43legacy_shm_read32(dev, B43legacy_SHM_SHARED, 0) !=
2325				 0x55AAAA55)
2326		goto error;
2327	b43legacy_shm_write32(dev, B43legacy_SHM_SHARED, 0, shm_backup);
2328
2329	value = b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
2330	if ((value | B43legacy_MACCTL_GMODE) !=
2331	    (B43legacy_MACCTL_GMODE | B43legacy_MACCTL_IHR_ENABLED))
2332		goto error;
2333
2334	value = b43legacy_read32(dev, B43legacy_MMIO_GEN_IRQ_REASON);
2335	if (value)
2336		goto error;
2337
2338	return 0;
2339error:
2340	b43legacyerr(dev->wl, "Failed to validate the chipaccess\n");
2341	return -ENODEV;
2342}
2343
2344static void b43legacy_security_init(struct b43legacy_wldev *dev)
2345{
2346	dev->max_nr_keys = (dev->dev->id.revision >= 5) ? 58 : 20;
2347	B43legacy_WARN_ON(dev->max_nr_keys > ARRAY_SIZE(dev->key));
2348	dev->ktp = b43legacy_shm_read16(dev, B43legacy_SHM_SHARED,
2349					0x0056);
2350	/* KTP is a word address, but we address SHM bytewise.
2351	 * So multiply by two.
2352	 */
2353	dev->ktp *= 2;
2354	if (dev->dev->id.revision >= 5)
2355		/* Number of RCMTA address slots */
2356		b43legacy_write16(dev, B43legacy_MMIO_RCMTA_COUNT,
2357				  dev->max_nr_keys - 8);
2358}
2359
2360#ifdef CONFIG_B43LEGACY_HWRNG
2361static int b43legacy_rng_read(struct hwrng *rng, u32 *data)
2362{
2363	struct b43legacy_wl *wl = (struct b43legacy_wl *)rng->priv;
2364	unsigned long flags;
2365
2366	/* Don't take wl->mutex here, as it could deadlock with
2367	 * hwrng internal locking. It's not needed to take
2368	 * wl->mutex here, anyway. */
2369
2370	spin_lock_irqsave(&wl->irq_lock, flags);
2371	*data = b43legacy_read16(wl->current_dev, B43legacy_MMIO_RNG);
2372	spin_unlock_irqrestore(&wl->irq_lock, flags);
2373
2374	return (sizeof(u16));
2375}
2376#endif
2377
2378static void b43legacy_rng_exit(struct b43legacy_wl *wl)
2379{
2380#ifdef CONFIG_B43LEGACY_HWRNG
2381	if (wl->rng_initialized)
2382		hwrng_unregister(&wl->rng);
2383#endif
2384}
2385
2386static int b43legacy_rng_init(struct b43legacy_wl *wl)
2387{
2388	int err = 0;
2389
2390#ifdef CONFIG_B43LEGACY_HWRNG
2391	snprintf(wl->rng_name, ARRAY_SIZE(wl->rng_name),
2392		 "%s_%s", KBUILD_MODNAME, wiphy_name(wl->hw->wiphy));
2393	wl->rng.name = wl->rng_name;
2394	wl->rng.data_read = b43legacy_rng_read;
2395	wl->rng.priv = (unsigned long)wl;
2396	wl->rng_initialized = 1;
2397	err = hwrng_register(&wl->rng);
2398	if (err) {
2399		wl->rng_initialized = 0;
2400		b43legacyerr(wl, "Failed to register the random "
2401		       "number generator (%d)\n", err);
2402	}
2403
2404#endif
2405	return err;
2406}
2407
2408static int b43legacy_op_tx(struct ieee80211_hw *hw,
2409			   struct sk_buff *skb)
2410{
2411	struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
2412	struct b43legacy_wldev *dev = wl->current_dev;
2413	int err = -ENODEV;
2414	unsigned long flags;
2415
2416	if (unlikely(!dev))
2417		goto out;
2418	if (unlikely(b43legacy_status(dev) < B43legacy_STAT_STARTED))
2419		goto out;
2420	/* DMA-TX is done without a global lock. */
2421	if (b43legacy_using_pio(dev)) {
2422		spin_lock_irqsave(&wl->irq_lock, flags);
2423		err = b43legacy_pio_tx(dev, skb);
2424		spin_unlock_irqrestore(&wl->irq_lock, flags);
2425	} else
2426		err = b43legacy_dma_tx(dev, skb);
2427out:
2428	if (unlikely(err)) {
2429		/* Drop the packet. */
2430		dev_kfree_skb_any(skb);
2431	}
2432	return NETDEV_TX_OK;
2433}
2434
2435static int b43legacy_op_conf_tx(struct ieee80211_hw *hw, u16 queue,
2436				const struct ieee80211_tx_queue_params *params)
2437{
2438	return 0;
2439}
2440
2441static int b43legacy_op_get_stats(struct ieee80211_hw *hw,
2442				  struct ieee80211_low_level_stats *stats)
2443{
2444	struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
2445	unsigned long flags;
2446
2447	spin_lock_irqsave(&wl->irq_lock, flags);
2448	memcpy(stats, &wl->ieee_stats, sizeof(*stats));
2449	spin_unlock_irqrestore(&wl->irq_lock, flags);
2450
2451	return 0;
2452}
2453
2454static const char *phymode_to_string(unsigned int phymode)
2455{
2456	switch (phymode) {
2457	case B43legacy_PHYMODE_B:
2458		return "B";
2459	case B43legacy_PHYMODE_G:
2460		return "G";
2461	default:
2462		B43legacy_BUG_ON(1);
2463	}
2464	return "";
2465}
2466
2467static int find_wldev_for_phymode(struct b43legacy_wl *wl,
2468				  unsigned int phymode,
2469				  struct b43legacy_wldev **dev,
2470				  bool *gmode)
2471{
2472	struct b43legacy_wldev *d;
2473
2474	list_for_each_entry(d, &wl->devlist, list) {
2475		if (d->phy.possible_phymodes & phymode) {
2476			/* Ok, this device supports the PHY-mode.
2477			 * Set the gmode bit. */
2478			*gmode = 1;
2479			*dev = d;
2480
2481			return 0;
2482		}
2483	}
2484
2485	return -ESRCH;
2486}
2487
2488static void b43legacy_put_phy_into_reset(struct b43legacy_wldev *dev)
2489{
2490	struct ssb_device *sdev = dev->dev;
2491	u32 tmslow;
2492
2493	tmslow = ssb_read32(sdev, SSB_TMSLOW);
2494	tmslow &= ~B43legacy_TMSLOW_GMODE;
2495	tmslow |= B43legacy_TMSLOW_PHYRESET;
2496	tmslow |= SSB_TMSLOW_FGC;
2497	ssb_write32(sdev, SSB_TMSLOW, tmslow);
2498	msleep(1);
2499
2500	tmslow = ssb_read32(sdev, SSB_TMSLOW);
2501	tmslow &= ~SSB_TMSLOW_FGC;
2502	tmslow |= B43legacy_TMSLOW_PHYRESET;
2503	ssb_write32(sdev, SSB_TMSLOW, tmslow);
2504	msleep(1);
2505}
2506
2507/* Expects wl->mutex locked */
2508static int b43legacy_switch_phymode(struct b43legacy_wl *wl,
2509				      unsigned int new_mode)
2510{
2511	struct b43legacy_wldev *uninitialized_var(up_dev);
2512	struct b43legacy_wldev *down_dev;
2513	int err;
2514	bool gmode = 0;
2515	int prev_status;
2516
2517	err = find_wldev_for_phymode(wl, new_mode, &up_dev, &gmode);
2518	if (err) {
2519		b43legacyerr(wl, "Could not find a device for %s-PHY mode\n",
2520		       phymode_to_string(new_mode));
2521		return err;
2522	}
2523	if ((up_dev == wl->current_dev) &&
2524	    (!!wl->current_dev->phy.gmode == !!gmode))
2525		/* This device is already running. */
2526		return 0;
2527	b43legacydbg(wl, "Reconfiguring PHYmode to %s-PHY\n",
2528	       phymode_to_string(new_mode));
2529	down_dev = wl->current_dev;
2530
2531	prev_status = b43legacy_status(down_dev);
2532	/* Shutdown the currently running core. */
2533	if (prev_status >= B43legacy_STAT_STARTED)
2534		b43legacy_wireless_core_stop(down_dev);
2535	if (prev_status >= B43legacy_STAT_INITIALIZED)
2536		b43legacy_wireless_core_exit(down_dev);
2537
2538	if (down_dev != up_dev)
2539		/* We switch to a different core, so we put PHY into
2540		 * RESET on the old core. */
2541		b43legacy_put_phy_into_reset(down_dev);
2542
2543	/* Now start the new core. */
2544	up_dev->phy.gmode = gmode;
2545	if (prev_status >= B43legacy_STAT_INITIALIZED) {
2546		err = b43legacy_wireless_core_init(up_dev);
2547		if (err) {
2548			b43legacyerr(wl, "Fatal: Could not initialize device"
2549				     " for newly selected %s-PHY mode\n",
2550				     phymode_to_string(new_mode));
2551			goto init_failure;
2552		}
2553	}
2554	if (prev_status >= B43legacy_STAT_STARTED) {
2555		err = b43legacy_wireless_core_start(up_dev);
2556		if (err) {
2557			b43legacyerr(wl, "Fatal: Coult not start device for "
2558			       "newly selected %s-PHY mode\n",
2559			       phymode_to_string(new_mode));
2560			b43legacy_wireless_core_exit(up_dev);
2561			goto init_failure;
2562		}
2563	}
2564	B43legacy_WARN_ON(b43legacy_status(up_dev) != prev_status);
2565
2566	b43legacy_shm_write32(up_dev, B43legacy_SHM_SHARED, 0x003E, 0);
2567
2568	wl->current_dev = up_dev;
2569
2570	return 0;
2571init_failure:
2572	/* Whoops, failed to init the new core. No core is operating now. */
2573	wl->current_dev = NULL;
2574	return err;
2575}
2576
2577/* Write the short and long frame retry limit values. */
2578static void b43legacy_set_retry_limits(struct b43legacy_wldev *dev,
2579				       unsigned int short_retry,
2580				       unsigned int long_retry)
2581{
2582	/* The retry limit is a 4-bit counter. Enforce this to avoid overflowing
2583	 * the chip-internal counter. */
2584	short_retry = min(short_retry, (unsigned int)0xF);
2585	long_retry = min(long_retry, (unsigned int)0xF);
2586
2587	b43legacy_shm_write16(dev, B43legacy_SHM_WIRELESS, 0x0006, short_retry);
2588	b43legacy_shm_write16(dev, B43legacy_SHM_WIRELESS, 0x0007, long_retry);
2589}
2590
2591static int b43legacy_op_dev_config(struct ieee80211_hw *hw,
2592				   u32 changed)
2593{
2594	struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
2595	struct b43legacy_wldev *dev;
2596	struct b43legacy_phy *phy;
2597	struct ieee80211_conf *conf = &hw->conf;
2598	unsigned long flags;
2599	unsigned int new_phymode = 0xFFFF;
2600	int antenna_tx;
2601	int antenna_rx;
2602	int err = 0;
2603
2604	antenna_tx = B43legacy_ANTENNA_DEFAULT;
2605	antenna_rx = B43legacy_ANTENNA_DEFAULT;
2606
2607	mutex_lock(&wl->mutex);
2608	dev = wl->current_dev;
2609	phy = &dev->phy;
2610
2611	if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS)
2612		b43legacy_set_retry_limits(dev,
2613					   conf->short_frame_max_tx_count,
2614					   conf->long_frame_max_tx_count);
2615	changed &= ~IEEE80211_CONF_CHANGE_RETRY_LIMITS;
2616	if (!changed)
2617		goto out_unlock_mutex;
2618
2619	/* Switch the PHY mode (if necessary). */
2620	switch (conf->channel->band) {
2621	case IEEE80211_BAND_2GHZ:
2622		if (phy->type == B43legacy_PHYTYPE_B)
2623			new_phymode = B43legacy_PHYMODE_B;
2624		else
2625			new_phymode = B43legacy_PHYMODE_G;
2626		break;
2627	default:
2628		B43legacy_WARN_ON(1);
2629	}
2630	err = b43legacy_switch_phymode(wl, new_phymode);
2631	if (err)
2632		goto out_unlock_mutex;
2633
2634	/* Disable IRQs while reconfiguring the device.
2635	 * This makes it possible to drop the spinlock throughout
2636	 * the reconfiguration process. */
2637	spin_lock_irqsave(&wl->irq_lock, flags);
2638	if (b43legacy_status(dev) < B43legacy_STAT_STARTED) {
2639		spin_unlock_irqrestore(&wl->irq_lock, flags);
2640		goto out_unlock_mutex;
2641	}
2642	b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_MASK, 0);
2643	spin_unlock_irqrestore(&wl->irq_lock, flags);
2644	b43legacy_synchronize_irq(dev);
2645
2646	/* Switch to the requested channel.
2647	 * The firmware takes care of races with the TX handler. */
2648	if (conf->channel->hw_value != phy->channel)
2649		b43legacy_radio_selectchannel(dev, conf->channel->hw_value, 0);
2650
2651	dev->wl->radiotap_enabled = !!(conf->flags & IEEE80211_CONF_MONITOR);
2652
2653	/* Adjust the desired TX power level. */
2654	if (conf->power_level != 0) {
2655		if (conf->power_level != phy->power_level) {
2656			phy->power_level = conf->power_level;
2657			b43legacy_phy_xmitpower(dev);
2658		}
2659	}
2660
2661	/* Antennas for RX and management frame TX. */
2662	b43legacy_mgmtframe_txantenna(dev, antenna_tx);
2663
2664	if (wl->radio_enabled != phy->radio_on) {
2665		if (wl->radio_enabled) {
2666			b43legacy_radio_turn_on(dev);
2667			b43legacyinfo(dev->wl, "Radio turned on by software\n");
2668			if (!dev->radio_hw_enable)
2669				b43legacyinfo(dev->wl, "The hardware RF-kill"
2670					      " button still turns the radio"
2671					      " physically off. Press the"
2672					      " button to turn it on.\n");
2673		} else {
2674			b43legacy_radio_turn_off(dev, 0);
2675			b43legacyinfo(dev->wl, "Radio turned off by"
2676				      " software\n");
2677		}
2678	}
2679
2680	spin_lock_irqsave(&wl->irq_lock, flags);
2681	b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_MASK, dev->irq_mask);
2682	mmiowb();
2683	spin_unlock_irqrestore(&wl->irq_lock, flags);
2684out_unlock_mutex:
2685	mutex_unlock(&wl->mutex);
2686
2687	return err;
2688}
2689
2690static void b43legacy_update_basic_rates(struct b43legacy_wldev *dev, u32 brates)
2691{
2692	struct ieee80211_supported_band *sband =
2693		dev->wl->hw->wiphy->bands[IEEE80211_BAND_2GHZ];
2694	struct ieee80211_rate *rate;
2695	int i;
2696	u16 basic, direct, offset, basic_offset, rateptr;
2697
2698	for (i = 0; i < sband->n_bitrates; i++) {
2699		rate = &sband->bitrates[i];
2700
2701		if (b43legacy_is_cck_rate(rate->hw_value)) {
2702			direct = B43legacy_SHM_SH_CCKDIRECT;
2703			basic = B43legacy_SHM_SH_CCKBASIC;
2704			offset = b43legacy_plcp_get_ratecode_cck(rate->hw_value);
2705			offset &= 0xF;
2706		} else {
2707			direct = B43legacy_SHM_SH_OFDMDIRECT;
2708			basic = B43legacy_SHM_SH_OFDMBASIC;
2709			offset = b43legacy_plcp_get_ratecode_ofdm(rate->hw_value);
2710			offset &= 0xF;
2711		}
2712
2713		rate = ieee80211_get_response_rate(sband, brates, rate->bitrate);
2714
2715		if (b43legacy_is_cck_rate(rate->hw_value)) {
2716			basic_offset = b43legacy_plcp_get_ratecode_cck(rate->hw_value);
2717			basic_offset &= 0xF;
2718		} else {
2719			basic_offset = b43legacy_plcp_get_ratecode_ofdm(rate->hw_value);
2720			basic_offset &= 0xF;
2721		}
2722
2723		/*
2724		 * Get the pointer that we need to point to
2725		 * from the direct map
2726		 */
2727		rateptr = b43legacy_shm_read16(dev, B43legacy_SHM_SHARED,
2728					       direct + 2 * basic_offset);
2729		/* and write it to the basic map */
2730		b43legacy_shm_write16(dev, B43legacy_SHM_SHARED,
2731				      basic + 2 * offset, rateptr);
2732	}
2733}
2734
2735static void b43legacy_op_bss_info_changed(struct ieee80211_hw *hw,
2736				    struct ieee80211_vif *vif,
2737				    struct ieee80211_bss_conf *conf,
2738				    u32 changed)
2739{
2740	struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
2741	struct b43legacy_wldev *dev;
2742	struct b43legacy_phy *phy;
2743	unsigned long flags;
2744
2745	mutex_lock(&wl->mutex);
2746	B43legacy_WARN_ON(wl->vif != vif);
2747
2748	dev = wl->current_dev;
2749	phy = &dev->phy;
2750
2751	/* Disable IRQs while reconfiguring the device.
2752	 * This makes it possible to drop the spinlock throughout
2753	 * the reconfiguration process. */
2754	spin_lock_irqsave(&wl->irq_lock, flags);
2755	if (b43legacy_status(dev) < B43legacy_STAT_STARTED) {
2756		spin_unlock_irqrestore(&wl->irq_lock, flags);
2757		goto out_unlock_mutex;
2758	}
2759	b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_MASK, 0);
2760
2761	if (changed & BSS_CHANGED_BSSID) {
2762		b43legacy_synchronize_irq(dev);
2763
2764		if (conf->bssid)
2765			memcpy(wl->bssid, conf->bssid, ETH_ALEN);
2766		else
2767			memset(wl->bssid, 0, ETH_ALEN);
2768	}
2769
2770	if (b43legacy_status(dev) >= B43legacy_STAT_INITIALIZED) {
2771		if (changed & BSS_CHANGED_BEACON &&
2772		    (b43legacy_is_mode(wl, NL80211_IFTYPE_AP) ||
2773		     b43legacy_is_mode(wl, NL80211_IFTYPE_ADHOC)))
2774			b43legacy_update_templates(wl);
2775
2776		if (changed & BSS_CHANGED_BSSID)
2777			b43legacy_write_mac_bssid_templates(dev);
2778	}
2779	spin_unlock_irqrestore(&wl->irq_lock, flags);
2780
2781	b43legacy_mac_suspend(dev);
2782
2783	if (changed & BSS_CHANGED_BEACON_INT &&
2784	    (b43legacy_is_mode(wl, NL80211_IFTYPE_AP) ||
2785	     b43legacy_is_mode(wl, NL80211_IFTYPE_ADHOC)))
2786		b43legacy_set_beacon_int(dev, conf->beacon_int);
2787
2788	if (changed & BSS_CHANGED_BASIC_RATES)
2789		b43legacy_update_basic_rates(dev, conf->basic_rates);
2790
2791	if (changed & BSS_CHANGED_ERP_SLOT) {
2792		if (conf->use_short_slot)
2793			b43legacy_short_slot_timing_enable(dev);
2794		else
2795			b43legacy_short_slot_timing_disable(dev);
2796	}
2797
2798	b43legacy_mac_enable(dev);
2799
2800	spin_lock_irqsave(&wl->irq_lock, flags);
2801	b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_MASK, dev->irq_mask);
2802	mmiowb();
2803	spin_unlock_irqrestore(&wl->irq_lock, flags);
2804 out_unlock_mutex:
2805	mutex_unlock(&wl->mutex);
2806}
2807
2808static void b43legacy_op_configure_filter(struct ieee80211_hw *hw,
2809					  unsigned int changed,
2810					  unsigned int *fflags,u64 multicast)
2811{
2812	struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
2813	struct b43legacy_wldev *dev = wl->current_dev;
2814	unsigned long flags;
2815
2816	if (!dev) {
2817		*fflags = 0;
2818		return;
2819	}
2820
2821	spin_lock_irqsave(&wl->irq_lock, flags);
2822	*fflags &= FIF_PROMISC_IN_BSS |
2823		  FIF_ALLMULTI |
2824		  FIF_FCSFAIL |
2825		  FIF_PLCPFAIL |
2826		  FIF_CONTROL |
2827		  FIF_OTHER_BSS |
2828		  FIF_BCN_PRBRESP_PROMISC;
2829
2830	changed &= FIF_PROMISC_IN_BSS |
2831		   FIF_ALLMULTI |
2832		   FIF_FCSFAIL |
2833		   FIF_PLCPFAIL |
2834		   FIF_CONTROL |
2835		   FIF_OTHER_BSS |
2836		   FIF_BCN_PRBRESP_PROMISC;
2837
2838	wl->filter_flags = *fflags;
2839
2840	if (changed && b43legacy_status(dev) >= B43legacy_STAT_INITIALIZED)
2841		b43legacy_adjust_opmode(dev);
2842	spin_unlock_irqrestore(&wl->irq_lock, flags);
2843}
2844
2845/* Locking: wl->mutex */
2846static void b43legacy_wireless_core_stop(struct b43legacy_wldev *dev)
2847{
2848	struct b43legacy_wl *wl = dev->wl;
2849	unsigned long flags;
2850
2851	if (b43legacy_status(dev) < B43legacy_STAT_STARTED)
2852		return;
2853
2854	/* Disable and sync interrupts. We must do this before than
2855	 * setting the status to INITIALIZED, as the interrupt handler
2856	 * won't care about IRQs then. */
2857	spin_lock_irqsave(&wl->irq_lock, flags);
2858	b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_MASK, 0);
2859	b43legacy_read32(dev, B43legacy_MMIO_GEN_IRQ_MASK); /* flush */
2860	spin_unlock_irqrestore(&wl->irq_lock, flags);
2861	b43legacy_synchronize_irq(dev);
2862
2863	b43legacy_set_status(dev, B43legacy_STAT_INITIALIZED);
2864
2865	mutex_unlock(&wl->mutex);
2866	/* Must unlock as it would otherwise deadlock. No races here.
2867	 * Cancel the possibly running self-rearming periodic work. */
2868	cancel_delayed_work_sync(&dev->periodic_work);
2869	mutex_lock(&wl->mutex);
2870
2871	ieee80211_stop_queues(wl->hw);
2872
2873	b43legacy_mac_suspend(dev);
2874	free_irq(dev->dev->irq, dev);
2875	b43legacydbg(wl, "Wireless interface stopped\n");
2876}
2877
2878/* Locking: wl->mutex */
2879static int b43legacy_wireless_core_start(struct b43legacy_wldev *dev)
2880{
2881	int err;
2882
2883	B43legacy_WARN_ON(b43legacy_status(dev) != B43legacy_STAT_INITIALIZED);
2884
2885	drain_txstatus_queue(dev);
2886	err = request_irq(dev->dev->irq, b43legacy_interrupt_handler,
2887			  IRQF_SHARED, KBUILD_MODNAME, dev);
2888	if (err) {
2889		b43legacyerr(dev->wl, "Cannot request IRQ-%d\n",
2890		       dev->dev->irq);
2891		goto out;
2892	}
2893	/* We are ready to run. */
2894	ieee80211_wake_queues(dev->wl->hw);
2895	b43legacy_set_status(dev, B43legacy_STAT_STARTED);
2896
2897	/* Start data flow (TX/RX) */
2898	b43legacy_mac_enable(dev);
2899	b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_MASK, dev->irq_mask);
2900
2901	/* Start maintenance work */
2902	b43legacy_periodic_tasks_setup(dev);
2903
2904	b43legacydbg(dev->wl, "Wireless interface started\n");
2905out:
2906	return err;
2907}
2908
2909/* Get PHY and RADIO versioning numbers */
2910static int b43legacy_phy_versioning(struct b43legacy_wldev *dev)
2911{
2912	struct b43legacy_phy *phy = &dev->phy;
2913	u32 tmp;
2914	u8 analog_type;
2915	u8 phy_type;
2916	u8 phy_rev;
2917	u16 radio_manuf;
2918	u16 radio_ver;
2919	u16 radio_rev;
2920	int unsupported = 0;
2921
2922	/* Get PHY versioning */
2923	tmp = b43legacy_read16(dev, B43legacy_MMIO_PHY_VER);
2924	analog_type = (tmp & B43legacy_PHYVER_ANALOG)
2925		      >> B43legacy_PHYVER_ANALOG_SHIFT;
2926	phy_type = (tmp & B43legacy_PHYVER_TYPE) >> B43legacy_PHYVER_TYPE_SHIFT;
2927	phy_rev = (tmp & B43legacy_PHYVER_VERSION);
2928	switch (phy_type) {
2929	case B43legacy_PHYTYPE_B:
2930		if (phy_rev != 2 && phy_rev != 4
2931		    && phy_rev != 6 && phy_rev != 7)
2932			unsupported = 1;
2933		break;
2934	case B43legacy_PHYTYPE_G:
2935		if (phy_rev > 8)
2936			unsupported = 1;
2937		break;
2938	default:
2939		unsupported = 1;
2940	};
2941	if (unsupported) {
2942		b43legacyerr(dev->wl, "FOUND UNSUPPORTED PHY "
2943		       "(Analog %u, Type %u, Revision %u)\n",
2944		       analog_type, phy_type, phy_rev);
2945		return -EOPNOTSUPP;
2946	}
2947	b43legacydbg(dev->wl, "Found PHY: Analog %u, Type %u, Revision %u\n",
2948	       analog_type, phy_type, phy_rev);
2949
2950
2951	/* Get RADIO versioning */
2952	if (dev->dev->bus->chip_id == 0x4317) {
2953		if (dev->dev->bus->chip_rev == 0)
2954			tmp = 0x3205017F;
2955		else if (dev->dev->bus->chip_rev == 1)
2956			tmp = 0x4205017F;
2957		else
2958			tmp = 0x5205017F;
2959	} else {
2960		b43legacy_write16(dev, B43legacy_MMIO_RADIO_CONTROL,
2961				  B43legacy_RADIOCTL_ID);
2962		tmp = b43legacy_read16(dev, B43legacy_MMIO_RADIO_DATA_HIGH);
2963		tmp <<= 16;
2964		b43legacy_write16(dev, B43legacy_MMIO_RADIO_CONTROL,
2965				  B43legacy_RADIOCTL_ID);
2966		tmp |= b43legacy_read16(dev, B43legacy_MMIO_RADIO_DATA_LOW);
2967	}
2968	radio_manuf = (tmp & 0x00000FFF);
2969	radio_ver = (tmp & 0x0FFFF000) >> 12;
2970	radio_rev = (tmp & 0xF0000000) >> 28;
2971	switch (phy_type) {
2972	case B43legacy_PHYTYPE_B:
2973		if ((radio_ver & 0xFFF0) != 0x2050)
2974			unsupported = 1;
2975		break;
2976	case B43legacy_PHYTYPE_G:
2977		if (radio_ver != 0x2050)
2978			unsupported = 1;
2979		break;
2980	default:
2981		B43legacy_BUG_ON(1);
2982	}
2983	if (unsupported) {
2984		b43legacyerr(dev->wl, "FOUND UNSUPPORTED RADIO "
2985		       "(Manuf 0x%X, Version 0x%X, Revision %u)\n",
2986		       radio_manuf, radio_ver, radio_rev);
2987		return -EOPNOTSUPP;
2988	}
2989	b43legacydbg(dev->wl, "Found Radio: Manuf 0x%X, Version 0x%X,"
2990		     " Revision %u\n", radio_manuf, radio_ver, radio_rev);
2991
2992
2993	phy->radio_manuf = radio_manuf;
2994	phy->radio_ver = radio_ver;
2995	phy->radio_rev = radio_rev;
2996
2997	phy->analog = analog_type;
2998	phy->type = phy_type;
2999	phy->rev = phy_rev;
3000
3001	return 0;
3002}
3003
3004static void setup_struct_phy_for_init(struct b43legacy_wldev *dev,
3005				      struct b43legacy_phy *phy)
3006{
3007	struct b43legacy_lopair *lo;
3008	int i;
3009
3010	memset(phy->minlowsig, 0xFF, sizeof(phy->minlowsig));
3011	memset(phy->minlowsigpos, 0, sizeof(phy->minlowsigpos));
3012
3013	/* Assume the radio is enabled. If it's not enabled, the state will
3014	 * immediately get fixed on the first periodic work run. */
3015	dev->radio_hw_enable = 1;
3016
3017	phy->savedpctlreg = 0xFFFF;
3018	phy->aci_enable = 0;
3019	phy->aci_wlan_automatic = 0;
3020	phy->aci_hw_rssi = 0;
3021
3022	lo = phy->_lo_pairs;
3023	if (lo)
3024		memset(lo, 0, sizeof(struct b43legacy_lopair) *
3025				     B43legacy_LO_COUNT);
3026	phy->max_lb_gain = 0;
3027	phy->trsw_rx_gain = 0;
3028
3029	/* Set default attenuation values. */
3030	phy->bbatt = b43legacy_default_baseband_attenuation(dev);
3031	phy->rfatt = b43legacy_default_radio_attenuation(dev);
3032	phy->txctl1 = b43legacy_default_txctl1(dev);
3033	phy->txpwr_offset = 0;
3034
3035	/* NRSSI */
3036	phy->nrssislope = 0;
3037	for (i = 0; i < ARRAY_SIZE(phy->nrssi); i++)
3038		phy->nrssi[i] = -1000;
3039	for (i = 0; i < ARRAY_SIZE(phy->nrssi_lt); i++)
3040		phy->nrssi_lt[i] = i;
3041
3042	phy->lofcal = 0xFFFF;
3043	phy->initval = 0xFFFF;
3044
3045	phy->interfmode = B43legacy_INTERFMODE_NONE;
3046	phy->channel = 0xFF;
3047}
3048
3049static void setup_struct_wldev_for_init(struct b43legacy_wldev *dev)
3050{
3051	/* Flags */
3052	dev->dfq_valid = 0;
3053
3054	/* Stats */
3055	memset(&dev->stats, 0, sizeof(dev->stats));
3056
3057	setup_struct_phy_for_init(dev, &dev->phy);
3058
3059	/* IRQ related flags */
3060	dev->irq_reason = 0;
3061	memset(dev->dma_reason, 0, sizeof(dev->dma_reason));
3062	dev->irq_mask = B43legacy_IRQ_MASKTEMPLATE;
3063
3064	dev->mac_suspended = 1;
3065
3066	/* Noise calculation context */
3067	memset(&dev->noisecalc, 0, sizeof(dev->noisecalc));
3068}
3069
3070static void b43legacy_imcfglo_timeouts_workaround(struct b43legacy_wldev *dev)
3071{
3072#ifdef CONFIG_SSB_DRIVER_PCICORE
3073	struct ssb_bus *bus = dev->dev->bus;
3074	u32 tmp;
3075
3076	if (bus->pcicore.dev &&
3077	    bus->pcicore.dev->id.coreid == SSB_DEV_PCI &&
3078	    bus->pcicore.dev->id.revision <= 5) {
3079		tmp = ssb_read32(dev->dev, SSB_IMCFGLO);
3080		switch (bus->bustype) {
3081		case SSB_BUSTYPE_PCI:
3082		case SSB_BUSTYPE_PCMCIA:
3083			tmp &= ~SSB_IMCFGLO_REQTO;
3084			tmp &= ~SSB_IMCFGLO_SERTO;
3085			tmp |= 0x32;
3086			break;
3087		case SSB_BUSTYPE_SSB:
3088			tmp &= ~SSB_IMCFGLO_REQTO;
3089			tmp &= ~SSB_IMCFGLO_SERTO;
3090			tmp |= 0x53;
3091			break;
3092		default:
3093			break;
3094		}
3095		ssb_write32(dev->dev, SSB_IMCFGLO, tmp);
3096	}
3097#endif /* CONFIG_SSB_DRIVER_PCICORE */
3098}
3099
3100static void b43legacy_set_synth_pu_delay(struct b43legacy_wldev *dev,
3101					  bool idle) {
3102	u16 pu_delay = 1050;
3103
3104	if (b43legacy_is_mode(dev->wl, NL80211_IFTYPE_ADHOC) || idle)
3105		pu_delay = 500;
3106	if ((dev->phy.radio_ver == 0x2050) && (dev->phy.radio_rev == 8))
3107		pu_delay = max(pu_delay, (u16)2400);
3108
3109	b43legacy_shm_write16(dev, B43legacy_SHM_SHARED,
3110			      B43legacy_SHM_SH_SPUWKUP, pu_delay);
3111}
3112
3113/* Set the TSF CFP pre-TargetBeaconTransmissionTime. */
3114static void b43legacy_set_pretbtt(struct b43legacy_wldev *dev)
3115{
3116	u16 pretbtt;
3117
3118	/* The time value is in microseconds. */
3119	if (b43legacy_is_mode(dev->wl, NL80211_IFTYPE_ADHOC))
3120		pretbtt = 2;
3121	else
3122		pretbtt = 250;
3123	b43legacy_shm_write16(dev, B43legacy_SHM_SHARED,
3124			      B43legacy_SHM_SH_PRETBTT, pretbtt);
3125	b43legacy_write16(dev, B43legacy_MMIO_TSF_CFP_PRETBTT, pretbtt);
3126}
3127
3128/* Shutdown a wireless core */
3129/* Locking: wl->mutex */
3130static void b43legacy_wireless_core_exit(struct b43legacy_wldev *dev)
3131{
3132	struct b43legacy_phy *phy = &dev->phy;
3133	u32 macctl;
3134
3135	B43legacy_WARN_ON(b43legacy_status(dev) > B43legacy_STAT_INITIALIZED);
3136	if (b43legacy_status(dev) != B43legacy_STAT_INITIALIZED)
3137		return;
3138	b43legacy_set_status(dev, B43legacy_STAT_UNINIT);
3139
3140	/* Stop the microcode PSM. */
3141	macctl = b43legacy_read32(dev, B43legacy_MMIO_MACCTL);
3142	macctl &= ~B43legacy_MACCTL_PSM_RUN;
3143	macctl |= B43legacy_MACCTL_PSM_JMP0;
3144	b43legacy_write32(dev, B43legacy_MMIO_MACCTL, macctl);
3145
3146	b43legacy_leds_exit(dev);
3147	b43legacy_rng_exit(dev->wl);
3148	b43legacy_pio_free(dev);
3149	b43legacy_dma_free(dev);
3150	b43legacy_chip_exit(dev);
3151	b43legacy_radio_turn_off(dev, 1);
3152	b43legacy_switch_analog(dev, 0);
3153	if (phy->dyn_tssi_tbl)
3154		kfree(phy->tssi2dbm);
3155	kfree(phy->lo_control);
3156	phy->lo_control = NULL;
3157	if (dev->wl->current_beacon) {
3158		dev_kfree_skb_any(dev->wl->current_beacon);
3159		dev->wl->current_beacon = NULL;
3160	}
3161
3162	ssb_device_disable(dev->dev, 0);
3163	ssb_bus_may_powerdown(dev->dev->bus);
3164}
3165
3166static void prepare_phy_data_for_init(struct b43legacy_wldev *dev)
3167{
3168	struct b43legacy_phy *phy = &dev->phy;
3169	int i;
3170
3171	/* Set default attenuation values. */
3172	phy->bbatt = b43legacy_default_baseband_attenuation(dev);
3173	phy->rfatt = b43legacy_default_radio_attenuation(dev);
3174	phy->txctl1 = b43legacy_default_txctl1(dev);
3175	phy->txctl2 = 0xFFFF;
3176	phy->txpwr_offset = 0;
3177
3178	/* NRSSI */
3179	phy->nrssislope = 0;
3180	for (i = 0; i < ARRAY_SIZE(phy->nrssi); i++)
3181		phy->nrssi[i] = -1000;
3182	for (i = 0; i < ARRAY_SIZE(phy->nrssi_lt); i++)
3183		phy->nrssi_lt[i] = i;
3184
3185	phy->lofcal = 0xFFFF;
3186	phy->initval = 0xFFFF;
3187
3188	phy->aci_enable = 0;
3189	phy->aci_wlan_automatic = 0;
3190	phy->aci_hw_rssi = 0;
3191
3192	phy->antenna_diversity = 0xFFFF;
3193	memset(phy->minlowsig, 0xFF, sizeof(phy->minlowsig));
3194	memset(phy->minlowsigpos, 0, sizeof(phy->minlowsigpos));
3195
3196	/* Flags */
3197	phy->calibrated = 0;
3198
3199	if (phy->_lo_pairs)
3200		memset(phy->_lo_pairs, 0,
3201		       sizeof(struct b43legacy_lopair) * B43legacy_LO_COUNT);
3202	memset(phy->loopback_gain, 0, sizeof(phy->loopback_gain));
3203}
3204
3205/* Initialize a wireless core */
3206static int b43legacy_wireless_core_init(struct b43legacy_wldev *dev)
3207{
3208	struct b43legacy_wl *wl = dev->wl;
3209	struct ssb_bus *bus = dev->dev->bus;
3210	struct b43legacy_phy *phy = &dev->phy;
3211	struct ssb_sprom *sprom = &dev->dev->bus->sprom;
3212	int err;
3213	u32 hf;
3214	u32 tmp;
3215
3216	B43legacy_WARN_ON(b43legacy_status(dev) != B43legacy_STAT_UNINIT);
3217
3218	err = ssb_bus_powerup(bus, 0);
3219	if (err)
3220		goto out;
3221	if (!ssb_device_is_enabled(dev->dev)) {
3222		tmp = phy->gmode ? B43legacy_TMSLOW_GMODE : 0;
3223		b43legacy_wireless_core_reset(dev, tmp);
3224	}
3225
3226	if ((phy->type == B43legacy_PHYTYPE_B) ||
3227	    (phy->type == B43legacy_PHYTYPE_G)) {
3228		phy->_lo_pairs = kzalloc(sizeof(struct b43legacy_lopair)
3229					 * B43legacy_LO_COUNT,
3230					 GFP_KERNEL);
3231		if (!phy->_lo_pairs)
3232			return -ENOMEM;
3233	}
3234	setup_struct_wldev_for_init(dev);
3235
3236	err = b43legacy_phy_init_tssi2dbm_table(dev);
3237	if (err)
3238		goto err_kfree_lo_control;
3239
3240	/* Enable IRQ routing to this device. */
3241	ssb_pcicore_dev_irqvecs_enable(&bus->pcicore, dev->dev);
3242
3243	b43legacy_imcfglo_timeouts_workaround(dev);
3244	prepare_phy_data_for_init(dev);
3245	b43legacy_phy_calibrate(dev);
3246	err = b43legacy_chip_init(dev);
3247	if (err)
3248		goto err_kfree_tssitbl;
3249	b43legacy_shm_write16(dev, B43legacy_SHM_SHARED,
3250			      B43legacy_SHM_SH_WLCOREREV,
3251			      dev->dev->id.revision);
3252	hf = b43legacy_hf_read(dev);
3253	if (phy->type == B43legacy_PHYTYPE_G) {
3254		hf |= B43legacy_HF_SYMW;
3255		if (phy->rev == 1)
3256			hf |= B43legacy_HF_GDCW;
3257		if (sprom->boardflags_lo & B43legacy_BFL_PACTRL)
3258			hf |= B43legacy_HF_OFDMPABOOST;
3259	} else if (phy->type == B43legacy_PHYTYPE_B) {
3260		hf |= B43legacy_HF_SYMW;
3261		if (phy->rev >= 2 && phy->radio_ver == 0x2050)
3262			hf &= ~B43legacy_HF_GDCW;
3263	}
3264	b43legacy_hf_write(dev, hf);
3265
3266	b43legacy_set_retry_limits(dev,
3267				   B43legacy_DEFAULT_SHORT_RETRY_LIMIT,
3268				   B43legacy_DEFAULT_LONG_RETRY_LIMIT);
3269
3270	b43legacy_shm_write16(dev, B43legacy_SHM_SHARED,
3271			      0x0044, 3);
3272	b43legacy_shm_write16(dev, B43legacy_SHM_SHARED,
3273			      0x0046, 2);
3274
3275	/* Disable sending probe responses from firmware.
3276	 * Setting the MaxTime to one usec will always trigger
3277	 * a timeout, so we never send any probe resp.
3278	 * A timeout of zero is infinite. */
3279	b43legacy_shm_write16(dev, B43legacy_SHM_SHARED,
3280			      B43legacy_SHM_SH_PRMAXTIME, 1);
3281
3282	b43legacy_rate_memory_init(dev);
3283
3284	/* Minimum Contention Window */
3285	if (phy->type == B43legacy_PHYTYPE_B)
3286		b43legacy_shm_write16(dev, B43legacy_SHM_WIRELESS,
3287				      0x0003, 31);
3288	else
3289		b43legacy_shm_write16(dev, B43legacy_SHM_WIRELESS,
3290				      0x0003, 15);
3291	/* Maximum Contention Window */
3292	b43legacy_shm_write16(dev, B43legacy_SHM_WIRELESS,
3293			      0x0004, 1023);
3294
3295	do {
3296		if (b43legacy_using_pio(dev))
3297			err = b43legacy_pio_init(dev);
3298		else {
3299			err = b43legacy_dma_init(dev);
3300			if (!err)
3301				b43legacy_qos_init(dev);
3302		}
3303	} while (err == -EAGAIN);
3304	if (err)
3305		goto err_chip_exit;
3306
3307	b43legacy_set_synth_pu_delay(dev, 1);
3308
3309	ssb_bus_powerup(bus, 1); /* Enable dynamic PCTL */
3310	b43legacy_upload_card_macaddress(dev);
3311	b43legacy_security_init(dev);
3312	b43legacy_rng_init(wl);
3313
3314	ieee80211_wake_queues(dev->wl->hw);
3315	b43legacy_set_status(dev, B43legacy_STAT_INITIALIZED);
3316
3317	b43legacy_leds_init(dev);
3318out:
3319	return err;
3320
3321err_chip_exit:
3322	b43legacy_chip_exit(dev);
3323err_kfree_tssitbl:
3324	if (phy->dyn_tssi_tbl)
3325		kfree(phy->tssi2dbm);
3326err_kfree_lo_control:
3327	kfree(phy->lo_control);
3328	phy->lo_control = NULL;
3329	ssb_bus_may_powerdown(bus);
3330	B43legacy_WARN_ON(b43legacy_status(dev) != B43legacy_STAT_UNINIT);
3331	return err;
3332}
3333
3334static int b43legacy_op_add_interface(struct ieee80211_hw *hw,
3335				      struct ieee80211_vif *vif)
3336{
3337	struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
3338	struct b43legacy_wldev *dev;
3339	unsigned long flags;
3340	int err = -EOPNOTSUPP;
3341
3342	/* TODO: allow WDS/AP devices to coexist */
3343
3344	if (vif->type != NL80211_IFTYPE_AP &&
3345	    vif->type != NL80211_IFTYPE_STATION &&
3346	    vif->type != NL80211_IFTYPE_WDS &&
3347	    vif->type != NL80211_IFTYPE_ADHOC)
3348		return -EOPNOTSUPP;
3349
3350	mutex_lock(&wl->mutex);
3351	if (wl->operating)
3352		goto out_mutex_unlock;
3353
3354	b43legacydbg(wl, "Adding Interface type %d\n", vif->type);
3355
3356	dev = wl->current_dev;
3357	wl->operating = 1;
3358	wl->vif = vif;
3359	wl->if_type = vif->type;
3360	memcpy(wl->mac_addr, vif->addr, ETH_ALEN);
3361
3362	spin_lock_irqsave(&wl->irq_lock, flags);
3363	b43legacy_adjust_opmode(dev);
3364	b43legacy_set_pretbtt(dev);
3365	b43legacy_set_synth_pu_delay(dev, 0);
3366	b43legacy_upload_card_macaddress(dev);
3367	spin_unlock_irqrestore(&wl->irq_lock, flags);
3368
3369	err = 0;
3370 out_mutex_unlock:
3371	mutex_unlock(&wl->mutex);
3372
3373	return err;
3374}
3375
3376static void b43legacy_op_remove_interface(struct ieee80211_hw *hw,
3377					  struct ieee80211_vif *vif)
3378{
3379	struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
3380	struct b43legacy_wldev *dev = wl->current_dev;
3381	unsigned long flags;
3382
3383	b43legacydbg(wl, "Removing Interface type %d\n", vif->type);
3384
3385	mutex_lock(&wl->mutex);
3386
3387	B43legacy_WARN_ON(!wl->operating);
3388	B43legacy_WARN_ON(wl->vif != vif);
3389	wl->vif = NULL;
3390
3391	wl->operating = 0;
3392
3393	spin_lock_irqsave(&wl->irq_lock, flags);
3394	b43legacy_adjust_opmode(dev);
3395	memset(wl->mac_addr, 0, ETH_ALEN);
3396	b43legacy_upload_card_macaddress(dev);
3397	spin_unlock_irqrestore(&wl->irq_lock, flags);
3398
3399	mutex_unlock(&wl->mutex);
3400}
3401
3402static int b43legacy_op_start(struct ieee80211_hw *hw)
3403{
3404	struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
3405	struct b43legacy_wldev *dev = wl->current_dev;
3406	int did_init = 0;
3407	int err = 0;
3408
3409	/* Kill all old instance specific information to make sure
3410	 * the card won't use it in the short timeframe between start
3411	 * and mac80211 reconfiguring it. */
3412	memset(wl->bssid, 0, ETH_ALEN);
3413	memset(wl->mac_addr, 0, ETH_ALEN);
3414	wl->filter_flags = 0;
3415	wl->beacon0_uploaded = 0;
3416	wl->beacon1_uploaded = 0;
3417	wl->beacon_templates_virgin = 1;
3418	wl->radio_enabled = 1;
3419
3420	mutex_lock(&wl->mutex);
3421
3422	if (b43legacy_status(dev) < B43legacy_STAT_INITIALIZED) {
3423		err = b43legacy_wireless_core_init(dev);
3424		if (err)
3425			goto out_mutex_unlock;
3426		did_init = 1;
3427	}
3428
3429	if (b43legacy_status(dev) < B43legacy_STAT_STARTED) {
3430		err = b43legacy_wireless_core_start(dev);
3431		if (err) {
3432			if (did_init)
3433				b43legacy_wireless_core_exit(dev);
3434			goto out_mutex_unlock;
3435		}
3436	}
3437
3438	wiphy_rfkill_start_polling(hw->wiphy);
3439
3440out_mutex_unlock:
3441	mutex_unlock(&wl->mutex);
3442
3443	return err;
3444}
3445
3446static void b43legacy_op_stop(struct ieee80211_hw *hw)
3447{
3448	struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
3449	struct b43legacy_wldev *dev = wl->current_dev;
3450
3451	cancel_work_sync(&(wl->beacon_update_trigger));
3452
3453	mutex_lock(&wl->mutex);
3454	if (b43legacy_status(dev) >= B43legacy_STAT_STARTED)
3455		b43legacy_wireless_core_stop(dev);
3456	b43legacy_wireless_core_exit(dev);
3457	wl->radio_enabled = 0;
3458	mutex_unlock(&wl->mutex);
3459}
3460
3461static int b43legacy_op_beacon_set_tim(struct ieee80211_hw *hw,
3462				       struct ieee80211_sta *sta, bool set)
3463{
3464	struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
3465	unsigned long flags;
3466
3467	spin_lock_irqsave(&wl->irq_lock, flags);
3468	b43legacy_update_templates(wl);
3469	spin_unlock_irqrestore(&wl->irq_lock, flags);
3470
3471	return 0;
3472}
3473
3474static int b43legacy_op_get_survey(struct ieee80211_hw *hw, int idx,
3475				   struct survey_info *survey)
3476{
3477	struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
3478	struct b43legacy_wldev *dev = wl->current_dev;
3479	struct ieee80211_conf *conf = &hw->conf;
3480
3481	if (idx != 0)
3482		return -ENOENT;
3483
3484	survey->channel = conf->channel;
3485	survey->filled = SURVEY_INFO_NOISE_DBM;
3486	survey->noise = dev->stats.link_noise;
3487
3488	return 0;
3489}
3490
3491static const struct ieee80211_ops b43legacy_hw_ops = {
3492	.tx			= b43legacy_op_tx,
3493	.conf_tx		= b43legacy_op_conf_tx,
3494	.add_interface		= b43legacy_op_add_interface,
3495	.remove_interface	= b43legacy_op_remove_interface,
3496	.config			= b43legacy_op_dev_config,
3497	.bss_info_changed	= b43legacy_op_bss_info_changed,
3498	.configure_filter	= b43legacy_op_configure_filter,
3499	.get_stats		= b43legacy_op_get_stats,
3500	.start			= b43legacy_op_start,
3501	.stop			= b43legacy_op_stop,
3502	.set_tim		= b43legacy_op_beacon_set_tim,
3503	.get_survey		= b43legacy_op_get_survey,
3504	.rfkill_poll		= b43legacy_rfkill_poll,
3505};
3506
3507/* Hard-reset the chip. Do not call this directly.
3508 * Use b43legacy_controller_restart()
3509 */
3510static void b43legacy_chip_reset(struct work_struct *work)
3511{
3512	struct b43legacy_wldev *dev =
3513		container_of(work, struct b43legacy_wldev, restart_work);
3514	struct b43legacy_wl *wl = dev->wl;
3515	int err = 0;
3516	int prev_status;
3517
3518	mutex_lock(&wl->mutex);
3519
3520	prev_status = b43legacy_status(dev);
3521	/* Bring the device down... */
3522	if (prev_status >= B43legacy_STAT_STARTED)
3523		b43legacy_wireless_core_stop(dev);
3524	if (prev_status >= B43legacy_STAT_INITIALIZED)
3525		b43legacy_wireless_core_exit(dev);
3526
3527	/* ...and up again. */
3528	if (prev_status >= B43legacy_STAT_INITIALIZED) {
3529		err = b43legacy_wireless_core_init(dev);
3530		if (err)
3531			goto out;
3532	}
3533	if (prev_status >= B43legacy_STAT_STARTED) {
3534		err = b43legacy_wireless_core_start(dev);
3535		if (err) {
3536			b43legacy_wireless_core_exit(dev);
3537			goto out;
3538		}
3539	}
3540out:
3541	if (err)
3542		wl->current_dev = NULL; /* Failed to init the dev. */
3543	mutex_unlock(&wl->mutex);
3544	if (err)
3545		b43legacyerr(wl, "Controller restart FAILED\n");
3546	else
3547		b43legacyinfo(wl, "Controller restarted\n");
3548}
3549
3550static int b43legacy_setup_modes(struct b43legacy_wldev *dev,
3551				 int have_bphy,
3552				 int have_gphy)
3553{
3554	struct ieee80211_hw *hw = dev->wl->hw;
3555	struct b43legacy_phy *phy = &dev->phy;
3556
3557	phy->possible_phymodes = 0;
3558	if (have_bphy) {
3559		hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
3560			&b43legacy_band_2GHz_BPHY;
3561		phy->possible_phymodes |= B43legacy_PHYMODE_B;
3562	}
3563
3564	if (have_gphy) {
3565		hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
3566			&b43legacy_band_2GHz_GPHY;
3567		phy->possible_phymodes |= B43legacy_PHYMODE_G;
3568	}
3569
3570	return 0;
3571}
3572
3573static void b43legacy_wireless_core_detach(struct b43legacy_wldev *dev)
3574{
3575	/* We release firmware that late to not be required to re-request
3576	 * is all the time when we reinit the core. */
3577	b43legacy_release_firmware(dev);
3578}
3579
3580static int b43legacy_wireless_core_attach(struct b43legacy_wldev *dev)
3581{
3582	struct b43legacy_wl *wl = dev->wl;
3583	struct ssb_bus *bus = dev->dev->bus;
3584	struct pci_dev *pdev = (bus->bustype == SSB_BUSTYPE_PCI) ? bus->host_pci : NULL;
3585	int err;
3586	int have_bphy = 0;
3587	int have_gphy = 0;
3588	u32 tmp;
3589
3590	/* Do NOT do any device initialization here.
3591	 * Do it in wireless_core_init() instead.
3592	 * This function is for gathering basic information about the HW, only.
3593	 * Also some structs may be set up here. But most likely you want to
3594	 * have that in core_init(), too.
3595	 */
3596
3597	err = ssb_bus_powerup(bus, 0);
3598	if (err) {
3599		b43legacyerr(wl, "Bus powerup failed\n");
3600		goto out;
3601	}
3602	/* Get the PHY type. */
3603	if (dev->dev->id.revision >= 5) {
3604		u32 tmshigh;
3605
3606		tmshigh = ssb_read32(dev->dev, SSB_TMSHIGH);
3607		have_gphy = !!(tmshigh & B43legacy_TMSHIGH_GPHY);
3608		if (!have_gphy)
3609			have_bphy = 1;
3610	} else if (dev->dev->id.revision == 4)
3611		have_gphy = 1;
3612	else
3613		have_bphy = 1;
3614
3615	dev->phy.gmode = (have_gphy || have_bphy);
3616	dev->phy.radio_on = 1;
3617	tmp = dev->phy.gmode ? B43legacy_TMSLOW_GMODE : 0;
3618	b43legacy_wireless_core_reset(dev, tmp);
3619
3620	err = b43legacy_phy_versioning(dev);
3621	if (err)
3622		goto err_powerdown;
3623	/* Check if this device supports multiband. */
3624	if (!pdev ||
3625	    (pdev->device != 0x4312 &&
3626	     pdev->device != 0x4319 &&
3627	     pdev->device != 0x4324)) {
3628		/* No multiband support. */
3629		have_bphy = 0;
3630		have_gphy = 0;
3631		switch (dev->phy.type) {
3632		case B43legacy_PHYTYPE_B:
3633			have_bphy = 1;
3634			break;
3635		case B43legacy_PHYTYPE_G:
3636			have_gphy = 1;
3637			break;
3638		default:
3639			B43legacy_BUG_ON(1);
3640		}
3641	}
3642	dev->phy.gmode = (have_gphy || have_bphy);
3643	tmp = dev->phy.gmode ? B43legacy_TMSLOW_GMODE : 0;
3644	b43legacy_wireless_core_reset(dev, tmp);
3645
3646	err = b43legacy_validate_chipaccess(dev);
3647	if (err)
3648		goto err_powerdown;
3649	err = b43legacy_setup_modes(dev, have_bphy, have_gphy);
3650	if (err)
3651		goto err_powerdown;
3652
3653	/* Now set some default "current_dev" */
3654	if (!wl->current_dev)
3655		wl->current_dev = dev;
3656	INIT_WORK(&dev->restart_work, b43legacy_chip_reset);
3657
3658	b43legacy_radio_turn_off(dev, 1);
3659	b43legacy_switch_analog(dev, 0);
3660	ssb_device_disable(dev->dev, 0);
3661	ssb_bus_may_powerdown(bus);
3662
3663out:
3664	return err;
3665
3666err_powerdown:
3667	ssb_bus_may_powerdown(bus);
3668	return err;
3669}
3670
3671static void b43legacy_one_core_detach(struct ssb_device *dev)
3672{
3673	struct b43legacy_wldev *wldev;
3674	struct b43legacy_wl *wl;
3675
3676	/* Do not cancel ieee80211-workqueue based work here.
3677	 * See comment in b43legacy_remove(). */
3678
3679	wldev = ssb_get_drvdata(dev);
3680	wl = wldev->wl;
3681	b43legacy_debugfs_remove_device(wldev);
3682	b43legacy_wireless_core_detach(wldev);
3683	list_del(&wldev->list);
3684	wl->nr_devs--;
3685	ssb_set_drvdata(dev, NULL);
3686	kfree(wldev);
3687}
3688
3689static int b43legacy_one_core_attach(struct ssb_device *dev,
3690				     struct b43legacy_wl *wl)
3691{
3692	struct b43legacy_wldev *wldev;
3693	struct pci_dev *pdev;
3694	int err = -ENOMEM;
3695
3696	if (!list_empty(&wl->devlist)) {
3697		/* We are not the first core on this chip. */
3698		pdev = (dev->bus->bustype == SSB_BUSTYPE_PCI) ? dev->bus->host_pci : NULL;
3699		/* Only special chips support more than one wireless
3700		 * core, although some of the other chips have more than
3701		 * one wireless core as well. Check for this and
3702		 * bail out early.
3703		 */
3704		if (!pdev ||
3705		    ((pdev->device != 0x4321) &&
3706		     (pdev->device != 0x4313) &&
3707		     (pdev->device != 0x431A))) {
3708			b43legacydbg(wl, "Ignoring unconnected 802.11 core\n");
3709			return -ENODEV;
3710		}
3711	}
3712
3713	wldev = kzalloc(sizeof(*wldev), GFP_KERNEL);
3714	if (!wldev)
3715		goto out;
3716
3717	wldev->dev = dev;
3718	wldev->wl = wl;
3719	b43legacy_set_status(wldev, B43legacy_STAT_UNINIT);
3720	wldev->bad_frames_preempt = modparam_bad_frames_preempt;
3721	tasklet_init(&wldev->isr_tasklet,
3722		     (void (*)(unsigned long))b43legacy_interrupt_tasklet,
3723		     (unsigned long)wldev);
3724	if (modparam_pio)
3725		wldev->__using_pio = 1;
3726	INIT_LIST_HEAD(&wldev->list);
3727
3728	err = b43legacy_wireless_core_attach(wldev);
3729	if (err)
3730		goto err_kfree_wldev;
3731
3732	list_add(&wldev->list, &wl->devlist);
3733	wl->nr_devs++;
3734	ssb_set_drvdata(dev, wldev);
3735	b43legacy_debugfs_add_device(wldev);
3736out:
3737	return err;
3738
3739err_kfree_wldev:
3740	kfree(wldev);
3741	return err;
3742}
3743
3744static void b43legacy_sprom_fixup(struct ssb_bus *bus)
3745{
3746	/* boardflags workarounds */
3747	if (bus->boardinfo.vendor == PCI_VENDOR_ID_APPLE &&
3748	    bus->boardinfo.type == 0x4E &&
3749	    bus->boardinfo.rev > 0x40)
3750		bus->sprom.boardflags_lo |= B43legacy_BFL_PACTRL;
3751}
3752
3753static void b43legacy_wireless_exit(struct ssb_device *dev,
3754				  struct b43legacy_wl *wl)
3755{
3756	struct ieee80211_hw *hw = wl->hw;
3757
3758	ssb_set_devtypedata(dev, NULL);
3759	ieee80211_free_hw(hw);
3760}
3761
3762static int b43legacy_wireless_init(struct ssb_device *dev)
3763{
3764	struct ssb_sprom *sprom = &dev->bus->sprom;
3765	struct ieee80211_hw *hw;
3766	struct b43legacy_wl *wl;
3767	int err = -ENOMEM;
3768
3769	b43legacy_sprom_fixup(dev->bus);
3770
3771	hw = ieee80211_alloc_hw(sizeof(*wl), &b43legacy_hw_ops);
3772	if (!hw) {
3773		b43legacyerr(NULL, "Could not allocate ieee80211 device\n");
3774		goto out;
3775	}
3776
3777	/* fill hw info */
3778	hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
3779		    IEEE80211_HW_SIGNAL_DBM;
3780	hw->wiphy->interface_modes =
3781		BIT(NL80211_IFTYPE_AP) |
3782		BIT(NL80211_IFTYPE_STATION) |
3783		BIT(NL80211_IFTYPE_WDS) |
3784		BIT(NL80211_IFTYPE_ADHOC);
3785	hw->queues = 1;
3786	hw->max_rates = 2;
3787	SET_IEEE80211_DEV(hw, dev->dev);
3788	if (is_valid_ether_addr(sprom->et1mac))
3789		SET_IEEE80211_PERM_ADDR(hw, sprom->et1mac);
3790	else
3791		SET_IEEE80211_PERM_ADDR(hw, sprom->il0mac);
3792
3793	/* Get and initialize struct b43legacy_wl */
3794	wl = hw_to_b43legacy_wl(hw);
3795	memset(wl, 0, sizeof(*wl));
3796	wl->hw = hw;
3797	spin_lock_init(&wl->irq_lock);
3798	spin_lock_init(&wl->leds_lock);
3799	mutex_init(&wl->mutex);
3800	INIT_LIST_HEAD(&wl->devlist);
3801	INIT_WORK(&wl->beacon_update_trigger, b43legacy_beacon_update_trigger_work);
3802
3803	ssb_set_devtypedata(dev, wl);
3804	b43legacyinfo(wl, "Broadcom %04X WLAN found\n", dev->bus->chip_id);
3805	err = 0;
3806out:
3807	return err;
3808}
3809
3810static int b43legacy_probe(struct ssb_device *dev,
3811			 const struct ssb_device_id *id)
3812{
3813	struct b43legacy_wl *wl;
3814	int err;
3815	int first = 0;
3816
3817	wl = ssb_get_devtypedata(dev);
3818	if (!wl) {
3819		/* Probing the first core - setup common struct b43legacy_wl */
3820		first = 1;
3821		err = b43legacy_wireless_init(dev);
3822		if (err)
3823			goto out;
3824		wl = ssb_get_devtypedata(dev);
3825		B43legacy_WARN_ON(!wl);
3826	}
3827	err = b43legacy_one_core_attach(dev, wl);
3828	if (err)
3829		goto err_wireless_exit;
3830
3831	if (first) {
3832		err = ieee80211_register_hw(wl->hw);
3833		if (err)
3834			goto err_one_core_detach;
3835	}
3836
3837out:
3838	return err;
3839
3840err_one_core_detach:
3841	b43legacy_one_core_detach(dev);
3842err_wireless_exit:
3843	if (first)
3844		b43legacy_wireless_exit(dev, wl);
3845	return err;
3846}
3847
3848static void b43legacy_remove(struct ssb_device *dev)
3849{
3850	struct b43legacy_wl *wl = ssb_get_devtypedata(dev);
3851	struct b43legacy_wldev *wldev = ssb_get_drvdata(dev);
3852
3853	/* We must cancel any work here before unregistering from ieee80211,
3854	 * as the ieee80211 unreg will destroy the workqueue. */
3855	cancel_work_sync(&wldev->restart_work);
3856
3857	B43legacy_WARN_ON(!wl);
3858	if (wl->current_dev == wldev)
3859		ieee80211_unregister_hw(wl->hw);
3860
3861	b43legacy_one_core_detach(dev);
3862
3863	if (list_empty(&wl->devlist))
3864		/* Last core on the chip unregistered.
3865		 * We can destroy common struct b43legacy_wl.
3866		 */
3867		b43legacy_wireless_exit(dev, wl);
3868}
3869
3870/* Perform a hardware reset. This can be called from any context. */
3871void b43legacy_controller_restart(struct b43legacy_wldev *dev,
3872				  const char *reason)
3873{
3874	/* Must avoid requeueing, if we are in shutdown. */
3875	if (b43legacy_status(dev) < B43legacy_STAT_INITIALIZED)
3876		return;
3877	b43legacyinfo(dev->wl, "Controller RESET (%s) ...\n", reason);
3878	ieee80211_queue_work(dev->wl->hw, &dev->restart_work);
3879}
3880
3881#ifdef CONFIG_PM
3882
3883static int b43legacy_suspend(struct ssb_device *dev, pm_message_t state)
3884{
3885	struct b43legacy_wldev *wldev = ssb_get_drvdata(dev);
3886	struct b43legacy_wl *wl = wldev->wl;
3887
3888	b43legacydbg(wl, "Suspending...\n");
3889
3890	mutex_lock(&wl->mutex);
3891	wldev->suspend_init_status = b43legacy_status(wldev);
3892	if (wldev->suspend_init_status >= B43legacy_STAT_STARTED)
3893		b43legacy_wireless_core_stop(wldev);
3894	if (wldev->suspend_init_status >= B43legacy_STAT_INITIALIZED)
3895		b43legacy_wireless_core_exit(wldev);
3896	mutex_unlock(&wl->mutex);
3897
3898	b43legacydbg(wl, "Device suspended.\n");
3899
3900	return 0;
3901}
3902
3903static int b43legacy_resume(struct ssb_device *dev)
3904{
3905	struct b43legacy_wldev *wldev = ssb_get_drvdata(dev);
3906	struct b43legacy_wl *wl = wldev->wl;
3907	int err = 0;
3908
3909	b43legacydbg(wl, "Resuming...\n");
3910
3911	mutex_lock(&wl->mutex);
3912	if (wldev->suspend_init_status >= B43legacy_STAT_INITIALIZED) {
3913		err = b43legacy_wireless_core_init(wldev);
3914		if (err) {
3915			b43legacyerr(wl, "Resume failed at core init\n");
3916			goto out;
3917		}
3918	}
3919	if (wldev->suspend_init_status >= B43legacy_STAT_STARTED) {
3920		err = b43legacy_wireless_core_start(wldev);
3921		if (err) {
3922			b43legacy_wireless_core_exit(wldev);
3923			b43legacyerr(wl, "Resume failed at core start\n");
3924			goto out;
3925		}
3926	}
3927
3928	b43legacydbg(wl, "Device resumed.\n");
3929out:
3930	mutex_unlock(&wl->mutex);
3931	return err;
3932}
3933
3934#else	/* CONFIG_PM */
3935# define b43legacy_suspend	NULL
3936# define b43legacy_resume		NULL
3937#endif	/* CONFIG_PM */
3938
3939static struct ssb_driver b43legacy_ssb_driver = {
3940	.name		= KBUILD_MODNAME,
3941	.id_table	= b43legacy_ssb_tbl,
3942	.probe		= b43legacy_probe,
3943	.remove		= b43legacy_remove,
3944	.suspend	= b43legacy_suspend,
3945	.resume		= b43legacy_resume,
3946};
3947
3948static void b43legacy_print_driverinfo(void)
3949{
3950	const char *feat_pci = "", *feat_leds = "",
3951		   *feat_pio = "", *feat_dma = "";
3952
3953#ifdef CONFIG_B43LEGACY_PCI_AUTOSELECT
3954	feat_pci = "P";
3955#endif
3956#ifdef CONFIG_B43LEGACY_LEDS
3957	feat_leds = "L";
3958#endif
3959#ifdef CONFIG_B43LEGACY_PIO
3960	feat_pio = "I";
3961#endif
3962#ifdef CONFIG_B43LEGACY_DMA
3963	feat_dma = "D";
3964#endif
3965	printk(KERN_INFO "Broadcom 43xx-legacy driver loaded "
3966	       "[ Features: %s%s%s%s, Firmware-ID: "
3967	       B43legacy_SUPPORTED_FIRMWARE_ID " ]\n",
3968	       feat_pci, feat_leds, feat_pio, feat_dma);
3969}
3970
3971static int __init b43legacy_init(void)
3972{
3973	int err;
3974
3975	b43legacy_debugfs_init();
3976
3977	err = ssb_driver_register(&b43legacy_ssb_driver);
3978	if (err)
3979		goto err_dfs_exit;
3980
3981	b43legacy_print_driverinfo();
3982
3983	return err;
3984
3985err_dfs_exit:
3986	b43legacy_debugfs_exit();
3987	return err;
3988}
3989
3990static void __exit b43legacy_exit(void)
3991{
3992	ssb_driver_unregister(&b43legacy_ssb_driver);
3993	b43legacy_debugfs_exit();
3994}
3995
3996module_init(b43legacy_init)
3997module_exit(b43legacy_exit)
3998