cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

main.c (111048B)


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