aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/b43
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/b43')
-rw-r--r--drivers/net/wireless/b43/Kconfig14
-rw-r--r--drivers/net/wireless/b43/Makefile1
-rw-r--r--drivers/net/wireless/b43/b43.h43
-rw-r--r--drivers/net/wireless/b43/debugfs.c48
-rw-r--r--drivers/net/wireless/b43/debugfs.h5
-rw-r--r--drivers/net/wireless/b43/dma.c65
-rw-r--r--drivers/net/wireless/b43/dma.h17
-rw-r--r--drivers/net/wireless/b43/lo.c77
-rw-r--r--drivers/net/wireless/b43/main.c460
-rw-r--r--drivers/net/wireless/b43/main.h25
-rw-r--r--drivers/net/wireless/b43/phy_a.c111
-rw-r--r--drivers/net/wireless/b43/phy_g.c614
-rw-r--r--drivers/net/wireless/b43/phy_lp.c395
-rw-r--r--drivers/net/wireless/b43/phy_lp.h329
-rw-r--r--drivers/net/wireless/b43/pio.c16
-rw-r--r--drivers/net/wireless/b43/rfkill.c2
-rw-r--r--drivers/net/wireless/b43/tables_lpphy.c394
-rw-r--r--drivers/net/wireless/b43/tables_lpphy.h31
-rw-r--r--drivers/net/wireless/b43/wa.c113
-rw-r--r--drivers/net/wireless/b43/xmit.c19
20 files changed, 1900 insertions, 879 deletions
diff --git a/drivers/net/wireless/b43/Kconfig b/drivers/net/wireless/b43/Kconfig
index 1f81d36f87c5..aab71a70ba78 100644
--- a/drivers/net/wireless/b43/Kconfig
+++ b/drivers/net/wireless/b43/Kconfig
@@ -110,10 +110,18 @@ config B43_DEBUG
bool "Broadcom 43xx debugging"
depends on B43
---help---
- Broadcom 43xx debugging messages.
+ Broadcom 43xx debugging.
- Say Y, if you want to find out why the driver does not
- work for you.
+ This adds additional runtime sanity checks and statistics to the driver.
+ These checks and statistics might me expensive and hurt runtime performance
+ of your system.
+ This also adds the b43 debugfs interface.
+
+ Do not enable this, unless you are debugging the driver.
+
+ Say N, if you are a distributor or user building a release kernel
+ for production use.
+ Only say Y, if you are debugging a problem in the b43 driver sourcecode.
config B43_FORCE_PIO
bool "Force usage of PIO instead of DMA"
diff --git a/drivers/net/wireless/b43/Makefile b/drivers/net/wireless/b43/Makefile
index 14a02b3aea53..281ef8310350 100644
--- a/drivers/net/wireless/b43/Makefile
+++ b/drivers/net/wireless/b43/Makefile
@@ -6,6 +6,7 @@ b43-y += phy_g.o
b43-y += phy_a.o
b43-$(CONFIG_B43_NPHY) += phy_n.o
b43-$(CONFIG_B43_PHY_LP) += phy_lp.o
+b43-$(CONFIG_B43_PHY_LP) += tables_lpphy.o
b43-y += sysfs.o
b43-y += xmit.o
b43-y += lo.o
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
index a53c378e7484..beaf18d6e8a7 100644
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -120,6 +120,9 @@
#define B43_MMIO_IFSCTL 0x688 /* Interframe space control */
#define B43_MMIO_IFSCTL_USE_EDCF 0x0004
#define B43_MMIO_POWERUP_DELAY 0x6A8
+#define B43_MMIO_BTCOEX_CTL 0x6B4 /* Bluetooth Coexistence Control */
+#define B43_MMIO_BTCOEX_STAT 0x6B6 /* Bluetooth Coexistence Status */
+#define B43_MMIO_BTCOEX_TXCTL 0x6B8 /* Bluetooth Coexistence Transmit Control */
/* SPROM boardflags_lo values */
#define B43_BFL_BTCOEXIST 0x0001 /* implements Bluetooth coexistance */
@@ -547,9 +550,6 @@ struct b43_noise_calculation {
struct b43_stats {
u8 link_noise;
- /* Store the last TX/RX times here for updating the leds. */
- unsigned long last_tx;
- unsigned long last_rx;
};
struct b43_key {
@@ -655,10 +655,39 @@ struct b43_wl {
struct work_struct txpower_adjust_work;
};
+/* The type of the firmware file. */
+enum b43_firmware_file_type {
+ B43_FWTYPE_PROPRIETARY,
+ B43_FWTYPE_OPENSOURCE,
+ B43_NR_FWTYPES,
+};
+
+/* Context data for fetching firmware. */
+struct b43_request_fw_context {
+ /* The device we are requesting the fw for. */
+ struct b43_wldev *dev;
+ /* The type of firmware to request. */
+ enum b43_firmware_file_type req_type;
+ /* Error messages for each firmware type. */
+ char errors[B43_NR_FWTYPES][128];
+ /* Temporary buffer for storing the firmware name. */
+ char fwname[64];
+ /* A fatal error occured while requesting. Firmware reqest
+ * can not continue, as any other reqest will also fail. */
+ int fatal_failure;
+};
+
/* In-memory representation of a cached microcode file. */
struct b43_firmware_file {
const char *filename;
const struct firmware *data;
+ /* Type of the firmware file name. Note that this does only indicate
+ * the type by the firmware name. NOT the file contents.
+ * If you want to check for proprietary vs opensource, use (struct b43_firmware)->opensource
+ * instead! The (struct b43_firmware)->opensource flag is derived from the actual firmware
+ * binary code, not just the filename.
+ */
+ enum b43_firmware_file_type type;
};
/* Pointers to the firmware data and meta information about it. */
@@ -677,7 +706,8 @@ struct b43_firmware {
/* Firmware patchlevel */
u16 patch;
- /* Set to true, if we are using an opensource firmware. */
+ /* Set to true, if we are using an opensource firmware.
+ * Use this to check for proprietary vs opensource. */
bool opensource;
/* Set to true, if the core needs a PCM firmware, but
* we failed to load one. This is always false for
@@ -848,12 +878,9 @@ void b43err(struct b43_wl *wl, const char *fmt, ...)
__attribute__ ((format(printf, 2, 3)));
void b43warn(struct b43_wl *wl, const char *fmt, ...)
__attribute__ ((format(printf, 2, 3)));
-#if B43_DEBUG
void b43dbg(struct b43_wl *wl, const char *fmt, ...)
__attribute__ ((format(printf, 2, 3)));
-#else /* DEBUG */
-# define b43dbg(wl, fmt...) do { /* nothing */ } while (0)
-#endif /* DEBUG */
+
/* A WARN_ON variant that vanishes when b43 debugging is disabled.
* This _also_ evaluates the arg with debugging disabled. */
diff --git a/drivers/net/wireless/b43/debugfs.c b/drivers/net/wireless/b43/debugfs.c
index e04fc91f569e..45e3d6af69f5 100644
--- a/drivers/net/wireless/b43/debugfs.c
+++ b/drivers/net/wireless/b43/debugfs.c
@@ -51,8 +51,8 @@ struct b43_debugfs_fops {
};
static inline
-struct b43_dfs_file * fops_to_dfs_file(struct b43_wldev *dev,
- const struct b43_debugfs_fops *dfops)
+struct b43_dfs_file *fops_to_dfs_file(struct b43_wldev *dev,
+ const struct b43_debugfs_fops *dfops)
{
void *p;
@@ -367,34 +367,6 @@ static int mmio32write__write_file(struct b43_wldev *dev,
return 0;
}
-/* wl->irq_lock is locked */
-static ssize_t tsf_read_file(struct b43_wldev *dev,
- char *buf, size_t bufsize)
-{
- ssize_t count = 0;
- u64 tsf;
-
- b43_tsf_read(dev, &tsf);
- fappend("0x%08x%08x\n",
- (unsigned int)((tsf & 0xFFFFFFFF00000000ULL) >> 32),
- (unsigned int)(tsf & 0xFFFFFFFFULL));
-
- return count;
-}
-
-/* wl->irq_lock is locked */
-static int tsf_write_file(struct b43_wldev *dev,
- const char *buf, size_t count)
-{
- u64 tsf;
-
- if (sscanf(buf, "%llu", (unsigned long long *)(&tsf)) != 1)
- return -EINVAL;
- b43_tsf_write(dev, tsf);
-
- return 0;
-}
-
static ssize_t txstat_read_file(struct b43_wldev *dev,
char *buf, size_t bufsize)
{
@@ -691,15 +663,23 @@ B43_DEBUGFS_FOPS(mmio16read, mmio16read__read_file, mmio16read__write_file, 1);
B43_DEBUGFS_FOPS(mmio16write, NULL, mmio16write__write_file, 1);
B43_DEBUGFS_FOPS(mmio32read, mmio32read__read_file, mmio32read__write_file, 1);
B43_DEBUGFS_FOPS(mmio32write, NULL, mmio32write__write_file, 1);
-B43_DEBUGFS_FOPS(tsf, tsf_read_file, tsf_write_file, 1);
B43_DEBUGFS_FOPS(txstat, txstat_read_file, NULL, 0);
B43_DEBUGFS_FOPS(restart, NULL, restart_write_file, 1);
B43_DEBUGFS_FOPS(loctls, loctls_read_file, NULL, 0);
-int b43_debug(struct b43_wldev *dev, enum b43_dyndbg feature)
+bool b43_debug(struct b43_wldev *dev, enum b43_dyndbg feature)
{
- return !!(dev->dfsentry && dev->dfsentry->dyn_debug[feature]);
+ bool enabled;
+
+ enabled = (dev->dfsentry && dev->dfsentry->dyn_debug[feature]);
+ if (unlikely(enabled)) {
+ /* Force full debugging messages, if the user enabled
+ * some dynamic debugging feature. */
+ b43_modparam_verbose = B43_VERBOSITY_MAX;
+ }
+
+ return enabled;
}
static void b43_remove_dynamic_debug(struct b43_wldev *dev)
@@ -805,7 +785,6 @@ void b43_debugfs_add_device(struct b43_wldev *dev)
ADD_FILE(mmio16write, 0200);
ADD_FILE(mmio32read, 0600);
ADD_FILE(mmio32write, 0200);
- ADD_FILE(tsf, 0600);
ADD_FILE(txstat, 0400);
ADD_FILE(restart, 0200);
ADD_FILE(loctls, 0400);
@@ -834,7 +813,6 @@ void b43_debugfs_remove_device(struct b43_wldev *dev)
debugfs_remove(e->file_mmio16write.dentry);
debugfs_remove(e->file_mmio32read.dentry);
debugfs_remove(e->file_mmio32write.dentry);
- debugfs_remove(e->file_tsf.dentry);
debugfs_remove(e->file_txstat.dentry);
debugfs_remove(e->file_restart.dentry);
debugfs_remove(e->file_loctls.dentry);
diff --git a/drivers/net/wireless/b43/debugfs.h b/drivers/net/wireless/b43/debugfs.h
index 7886cbe2d1d1..b9d4de4a979c 100644
--- a/drivers/net/wireless/b43/debugfs.h
+++ b/drivers/net/wireless/b43/debugfs.h
@@ -46,7 +46,6 @@ struct b43_dfsentry {
struct b43_dfs_file file_mmio16write;
struct b43_dfs_file file_mmio32read;
struct b43_dfs_file file_mmio32write;
- struct b43_dfs_file file_tsf;
struct b43_dfs_file file_txstat;
struct b43_dfs_file file_txpower_g;
struct b43_dfs_file file_restart;
@@ -72,7 +71,7 @@ struct b43_dfsentry {
struct dentry *dyn_debug_dentries[__B43_NR_DYNDBG];
};
-int b43_debug(struct b43_wldev *dev, enum b43_dyndbg feature);
+bool b43_debug(struct b43_wldev *dev, enum b43_dyndbg feature);
void b43_debugfs_init(void);
void b43_debugfs_exit(void);
@@ -83,7 +82,7 @@ void b43_debugfs_log_txstat(struct b43_wldev *dev,
#else /* CONFIG_B43_DEBUG */
-static inline int b43_debug(struct b43_wldev *dev, enum b43_dyndbg feature)
+static inline bool b43_debug(struct b43_wldev *dev, enum b43_dyndbg feature)
{
return 0;
}
diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c
index 6d65a02b7052..0cc804d0a214 100644
--- a/drivers/net/wireless/b43/dma.c
+++ b/drivers/net/wireless/b43/dma.c
@@ -41,6 +41,12 @@
#include <asm/div64.h>
+/* Required number of TX DMA slots per TX frame.
+ * This currently is 2, because we put the header and the ieee80211 frame
+ * into separate slots. */
+#define TX_SLOTS_PER_FRAME 2
+
+
/* 32bit DMA ops. */
static
struct b43_dmadesc_generic *op32_idx2desc(struct b43_dmaring *ring,
@@ -74,8 +80,7 @@ static void op32_fill_descriptor(struct b43_dmaring *ring,
addrext = (u32) (dmaaddr & SSB_DMA_TRANSLATION_MASK)
>> SSB_DMA_TRANSLATION_SHIFT;
addr |= ssb_dma_translation(ring->dev->dev);
- ctl = (bufsize - ring->frameoffset)
- & B43_DMA32_DCTL_BYTECNT;
+ ctl = bufsize & B43_DMA32_DCTL_BYTECNT;
if (slot == ring->nr_slots - 1)
ctl |= B43_DMA32_DCTL_DTABLEEND;
if (start)
@@ -177,8 +182,7 @@ static void op64_fill_descriptor(struct b43_dmaring *ring,
ctl0 |= B43_DMA64_DCTL0_FRAMEEND;
if (irq)
ctl0 |= B43_DMA64_DCTL0_IRQ;
- ctl1 |= (bufsize - ring->frameoffset)
- & B43_DMA64_DCTL1_BYTECNT;
+ ctl1 |= bufsize & B43_DMA64_DCTL1_BYTECNT;
ctl1 |= (addrext << B43_DMA64_DCTL1_ADDREXT_SHIFT)
& B43_DMA64_DCTL1_ADDREXT_MASK;
@@ -576,12 +580,11 @@ static int setup_rx_descbuffer(struct b43_dmaring *ring,
return -ENOMEM;
dmaaddr = map_descbuffer(ring, skb->data,
ring->rx_buffersize, 0);
- }
-
- if (b43_dma_mapping_error(ring, dmaaddr, ring->rx_buffersize, 0)) {
- b43err(ring->dev->wl, "RX DMA buffer allocation failed\n");
- dev_kfree_skb_any(skb);
- return -EIO;
+ if (b43_dma_mapping_error(ring, dmaaddr, ring->rx_buffersize, 0)) {
+ b43err(ring->dev->wl, "RX DMA buffer allocation failed\n");
+ dev_kfree_skb_any(skb);
+ return -EIO;
+ }
}
meta->skb = skb;
@@ -830,9 +833,6 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev,
if (ring->index == 0) {
ring->rx_buffersize = B43_DMA0_RX_BUFFERSIZE;
ring->frameoffset = B43_DMA0_RX_FRAMEOFFSET;
- } else if (ring->index == 3) {
- ring->rx_buffersize = B43_DMA3_RX_BUFFERSIZE;
- ring->frameoffset = B43_DMA3_RX_FRAMEOFFSET;
} else
B43_WARN_ON(1);
}
@@ -842,7 +842,10 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev,
#endif
if (for_tx) {
- ring->txhdr_cache = kcalloc(ring->nr_slots,
+ /* Assumption: B43_TXRING_SLOTS can be divided by TX_SLOTS_PER_FRAME */
+ BUILD_BUG_ON(B43_TXRING_SLOTS % TX_SLOTS_PER_FRAME != 0);
+
+ ring->txhdr_cache = kcalloc(ring->nr_slots / TX_SLOTS_PER_FRAME,
b43_txhdr_size(dev),
GFP_KERNEL);
if (!ring->txhdr_cache)
@@ -858,7 +861,7 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev,
b43_txhdr_size(dev), 1)) {
/* ugh realloc */
kfree(ring->txhdr_cache);
- ring->txhdr_cache = kcalloc(ring->nr_slots,
+ ring->txhdr_cache = kcalloc(ring->nr_slots / TX_SLOTS_PER_FRAME,
b43_txhdr_size(dev),
GFP_KERNEL | GFP_DMA);
if (!ring->txhdr_cache)
@@ -1149,7 +1152,10 @@ static int dma_tx_fragment(struct b43_dmaring *ring,
u16 cookie;
size_t hdrsize = b43_txhdr_size(ring->dev);
-#define SLOTS_PER_PACKET 2
+ /* Important note: If the number of used DMA slots per TX frame
+ * is changed here, the TX_SLOTS_PER_FRAME definition at the top of
+ * the file has to be updated, too!
+ */
old_top_slot = ring->current_slot;
old_used_slots = ring->used_slots;
@@ -1159,7 +1165,7 @@ static int dma_tx_fragment(struct b43_dmaring *ring,
desc = ops->idx2desc(ring, slot, &meta_hdr);
memset(meta_hdr, 0, sizeof(*meta_hdr));
- header = &(ring->txhdr_cache[slot * hdrsize]);
+ header = &(ring->txhdr_cache[(slot / TX_SLOTS_PER_FRAME) * hdrsize]);
cookie = generate_cookie(ring, slot);
err = b43_generate_txhdr(ring->dev, header,
skb->data, skb->len, info, cookie);
@@ -1254,8 +1260,8 @@ static inline int should_inject_overflow(struct b43_dmaring *ring)
}
/* Static mapping of mac80211's queues (priorities) to b43 DMA rings. */
-static struct b43_dmaring * select_ring_by_priority(struct b43_wldev *dev,
- u8 queue_prio)
+static struct b43_dmaring *select_ring_by_priority(struct b43_wldev *dev,
+ u8 queue_prio)
{
struct b43_dmaring *ring;
@@ -1306,17 +1312,19 @@ int b43_dma_tx(struct b43_wldev *dev, struct sk_buff *skb)
}
spin_lock_irqsave(&ring->lock, flags);
+
B43_WARN_ON(!ring->tx);
- if (unlikely(free_slots(ring) < SLOTS_PER_PACKET)) {
- b43warn(dev->wl, "DMA queue overflow\n");
- err = -ENOSPC;
- goto out_unlock;
- }
/* Check if the queue was stopped in mac80211,
* but we got called nevertheless.
* That would be a mac80211 bug. */
B43_WARN_ON(ring->stopped);
+ if (unlikely(free_slots(ring) < TX_SLOTS_PER_FRAME)) {
+ b43warn(dev->wl, "DMA queue overflow\n");
+ err = -ENOSPC;
+ goto out_unlock;
+ }
+
/* Assign the queue number to the ring (if not already done before)
* so TX status handling can use it. The queue to ring mapping is
* static, so we don't need to store it per frame. */
@@ -1335,7 +1343,7 @@ int b43_dma_tx(struct b43_wldev *dev, struct sk_buff *skb)
goto out_unlock;
}
ring->nr_tx_packets++;
- if ((free_slots(ring) < SLOTS_PER_PACKET) ||
+ if ((free_slots(ring) < TX_SLOTS_PER_FRAME) ||
should_inject_overflow(ring)) {
/* This TX ring is full. */
ieee80211_stop_queue(dev->wl->hw, skb_get_queue_mapping(skb));
@@ -1417,9 +1425,8 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev,
break;
slot = next_slot(ring, slot);
}
- dev->stats.last_tx = jiffies;
if (ring->stopped) {
- B43_WARN_ON(free_slots(ring) < SLOTS_PER_PACKET);
+ B43_WARN_ON(free_slots(ring) < TX_SLOTS_PER_FRAME);
ieee80211_wake_queue(dev->wl->hw, ring->queue_prio);
ring->stopped = 0;
if (b43_debug(dev, B43_DBG_DMAVERBOSE)) {
@@ -1442,8 +1449,8 @@ void b43_dma_get_tx_stats(struct b43_wldev *dev,
ring = select_ring_by_priority(dev, i);
spin_lock_irqsave(&ring->lock, flags);
- stats[i].len = ring->used_slots / SLOTS_PER_PACKET;
- stats[i].limit = ring->nr_slots / SLOTS_PER_PACKET;
+ stats[i].len = ring->used_slots / TX_SLOTS_PER_FRAME;
+ stats[i].limit = ring->nr_slots / TX_SLOTS_PER_FRAME;
stats[i].count = ring->nr_tx_packets;
spin_unlock_irqrestore(&ring->lock, flags);
}
diff --git a/drivers/net/wireless/b43/dma.h b/drivers/net/wireless/b43/dma.h
index d1eb5c0848a5..05dde646d831 100644
--- a/drivers/net/wireless/b43/dma.h
+++ b/drivers/net/wireless/b43/dma.h
@@ -1,14 +1,12 @@
#ifndef B43_DMA_H_
#define B43_DMA_H_
-#include <linux/list.h>
+#include <linux/ieee80211.h>
#include <linux/spinlock.h>
-#include <linux/workqueue.h>
-#include <linux/linkage.h>
-#include <asm/atomic.h>
#include "b43.h"
+
/* DMA-Interrupt reasons. */
#define B43_DMAIRQ_FATALMASK ((1 << 10) | (1 << 11) | (1 << 12) \
| (1 << 14) | (1 << 15))
@@ -161,14 +159,13 @@ struct b43_dmadesc_generic {
/* Misc DMA constants */
#define B43_DMA_RINGMEMSIZE PAGE_SIZE
-#define B43_DMA0_RX_FRAMEOFFSET 30
-#define B43_DMA3_RX_FRAMEOFFSET 0
+#define B43_DMA0_RX_FRAMEOFFSET 30
/* DMA engine tuning knobs */
-#define B43_TXRING_SLOTS 128
+#define B43_TXRING_SLOTS 256
#define B43_RXRING_SLOTS 64
-#define B43_DMA0_RX_BUFFERSIZE (2304 + 100)
-#define B43_DMA3_RX_BUFFERSIZE 16
+#define B43_DMA0_RX_BUFFERSIZE IEEE80211_MAX_FRAME_LEN
+
struct sk_buff;
struct b43_private;
@@ -215,7 +212,7 @@ struct b43_dmaring {
void *descbase;
/* Meta data about all descriptors. */
struct b43_dmadesc_meta *meta;
- /* Cache of TX headers for each slot.
+ /* Cache of TX headers for each TX frame.
* This is to avoid an allocation on each TX.
* This is NULL for an RX ring.
*/
diff --git a/drivers/net/wireless/b43/lo.c b/drivers/net/wireless/b43/lo.c
index 6a18a1470465..22d0fbd83a62 100644
--- a/drivers/net/wireless/b43/lo.c
+++ b/drivers/net/wireless/b43/lo.c
@@ -36,8 +36,8 @@
#include <linux/sched.h>
-static struct b43_lo_calib * b43_find_lo_calib(struct b43_txpower_lo_control *lo,
- const struct b43_bbatt *bbatt,
+static struct b43_lo_calib *b43_find_lo_calib(struct b43_txpower_lo_control *lo,
+ const struct b43_bbatt *bbatt,
const struct b43_rfatt *rfatt)
{
struct b43_lo_calib *c;
@@ -138,7 +138,7 @@ static u16 lo_measure_feedthrough(struct b43_wldev *dev,
* "pad_mix_gain" is the PAD Mixer Gain.
*/
static u16 lo_txctl_register_table(struct b43_wldev *dev,
- u16 * value, u16 * pad_mix_gain)
+ u16 *value, u16 *pad_mix_gain)
{
struct b43_phy *phy = &dev->phy;
u16 reg, v, padmix;
@@ -225,14 +225,12 @@ static void lo_measure_txctl_values(struct b43_wldev *dev)
radio_pctl_reg = tmp;
}
}
- b43_radio_write16(dev, 0x43, (b43_radio_read16(dev, 0x43)
- & 0xFFF0) | radio_pctl_reg);
+ b43_radio_maskset(dev, 0x43, 0xFFF0, radio_pctl_reg);
b43_gphy_set_baseband_attenuation(dev, 2);
reg = lo_txctl_register_table(dev, &mask, NULL);
mask = ~mask;
- b43_radio_write16(dev, reg, b43_radio_read16(dev, reg)
- & mask);
+ b43_radio_mask(dev, reg, mask);
if (has_tx_magnification(phy)) {
int i, j;
@@ -242,14 +240,10 @@ static void lo_measure_txctl_values(struct b43_wldev *dev)
for (i = 0; i < ARRAY_SIZE(tx_magn_values); i++) {
tx_magn = tx_magn_values[i];
- b43_radio_write16(dev, 0x52,
- (b43_radio_read16(dev, 0x52)
- & 0xFF0F) | tx_magn);
+ b43_radio_maskset(dev, 0x52, 0xFF0F, tx_magn);
for (j = 0; j < ARRAY_SIZE(tx_bias_values); j++) {
tx_bias = tx_bias_values[j];
- b43_radio_write16(dev, 0x52,
- (b43_radio_read16(dev, 0x52)
- & 0xFFF0) | tx_bias);
+ b43_radio_maskset(dev, 0x52, 0xFFF0, tx_bias);
feedthrough =
lo_measure_feedthrough(dev, 0, pga,
trsw_rx);
@@ -269,8 +263,7 @@ static void lo_measure_txctl_values(struct b43_wldev *dev)
} else {
lo->tx_magn = 0;
lo->tx_bias = 0;
- b43_radio_write16(dev, 0x52, b43_radio_read16(dev, 0x52)
- & 0xFFF0); /* TX bias == 0 */
+ b43_radio_mask(dev, 0x52, 0xFFF0); /* TX bias == 0 */
}
lo->txctl_measured_time = jiffies;
}
@@ -406,18 +399,10 @@ static void lo_measure_setup(struct b43_wldev *dev,
sav->phy_cck_14 = b43_phy_read(dev, B43_PHY_CCK(0x14));
sav->phy_hpwr_tssictl = b43_phy_read(dev, B43_PHY_HPWR_TSSICTL);
- b43_phy_write(dev, B43_PHY_HPWR_TSSICTL,
- b43_phy_read(dev, B43_PHY_HPWR_TSSICTL)
- | 0x100);
- b43_phy_write(dev, B43_PHY_EXTG(0x01),
- b43_phy_read(dev, B43_PHY_EXTG(0x01))
- | 0x40);
- b43_phy_write(dev, B43_PHY_DACCTL,
- b43_phy_read(dev, B43_PHY_DACCTL)
- | 0x40);
- b43_phy_write(dev, B43_PHY_CCK(0x14),
- b43_phy_read(dev, B43_PHY_CCK(0x14))
- | 0x200);
+ b43_phy_set(dev, B43_PHY_HPWR_TSSICTL, 0x100);
+ b43_phy_set(dev, B43_PHY_EXTG(0x01), 0x40);
+ b43_phy_set(dev, B43_PHY_DACCTL, 0x40);
+ b43_phy_set(dev, B43_PHY_CCK(0x14), 0x200);
}
if (phy->type == B43_PHYTYPE_B &&
phy->radio_ver == 0x2050 && phy->radio_rev < 6) {
@@ -434,17 +419,10 @@ static void lo_measure_setup(struct b43_wldev *dev,
sav->phy_cck_3E = b43_phy_read(dev, B43_PHY_CCK(0x3E));
sav->phy_crs0 = b43_phy_read(dev, B43_PHY_CRS0);
- b43_phy_write(dev, B43_PHY_CLASSCTL,
- b43_phy_read(dev, B43_PHY_CLASSCTL)
- & 0xFFFC);
- b43_phy_write(dev, B43_PHY_CRS0, b43_phy_read(dev, B43_PHY_CRS0)
- & 0x7FFF);
- b43_phy_write(dev, B43_PHY_ANALOGOVER,
- b43_phy_read(dev, B43_PHY_ANALOGOVER)
- | 0x0003);
- b43_phy_write(dev, B43_PHY_ANALOGOVERVAL,
- b43_phy_read(dev, B43_PHY_ANALOGOVERVAL)
- & 0xFFFC);
+ b43_phy_mask(dev, B43_PHY_CLASSCTL, 0xFFFC);
+ b43_phy_mask(dev, B43_PHY_CRS0, 0x7FFF);
+ b43_phy_set(dev, B43_PHY_ANALOGOVER, 0x0003);
+ b43_phy_mask(dev, B43_PHY_ANALOGOVERVAL, 0xFFFC);
if (phy->type == B43_PHYTYPE_G) {
if ((phy->rev >= 7) &&
(sprom->boardflags_lo & B43_BFL_EXTLNA)) {
@@ -558,8 +536,7 @@ static void lo_measure_restore(struct b43_wldev *dev,
b43_radio_write16(dev, 0x7A, sav->radio_7A);
if (!has_tx_magnification(phy)) {
tmp = sav->radio_52;
- b43_radio_write16(dev, 0x52, (b43_radio_read16(dev, 0x52)
- & 0xFF0F) | tmp);
+ b43_radio_maskset(dev, 0x52, 0xFF0F, tmp);
}
b43_write16(dev, 0x3E2, sav->reg_3E2);
if (phy->type == B43_PHYTYPE_B &&
@@ -754,9 +731,9 @@ static void lo_probe_loctls_statemachine(struct b43_wldev *dev,
}
static
-struct b43_lo_calib * b43_calibrate_lo_setting(struct b43_wldev *dev,
- const struct b43_bbatt *bbatt,
- const struct b43_rfatt *rfatt)
+struct b43_lo_calib *b43_calibrate_lo_setting(struct b43_wldev *dev,
+ const struct b43_bbatt *bbatt,
+ const struct b43_rfatt *rfatt)
{
struct b43_phy *phy = &dev->phy;
struct b43_phy_g *gphy = phy->g;
@@ -778,12 +755,8 @@ struct b43_lo_calib * b43_calibrate_lo_setting(struct b43_wldev *dev,
txctl_reg = lo_txctl_register_table(dev, &txctl_value, &pad_mix_gain);
- b43_radio_write16(dev, 0x43,
- (b43_radio_read16(dev, 0x43) & 0xFFF0)
- | rfatt->att);
- b43_radio_write16(dev, txctl_reg,
- (b43_radio_read16(dev, txctl_reg) & ~txctl_value)
- | (rfatt->with_padmix) ? txctl_value : 0);
+ b43_radio_maskset(dev, 0x43, 0xFFF0, rfatt->att);
+ b43_radio_maskset(dev, txctl_reg, ~txctl_value, (rfatt->with_padmix ? txctl_value :0));
max_rx_gain = rfatt->att * 2;
max_rx_gain += bbatt->att / 2;
@@ -824,9 +797,9 @@ struct b43_lo_calib * b43_calibrate_lo_setting(struct b43_wldev *dev,
/* Get a calibrated LO setting for the given attenuation values.
* Might return a NULL pointer under OOM! */
static
-struct b43_lo_calib * b43_get_calib_lo_settings(struct b43_wldev *dev,
- const struct b43_bbatt *bbatt,
- const struct b43_rfatt *rfatt)
+struct b43_lo_calib *b43_get_calib_lo_settings(struct b43_wldev *dev,
+ const struct b43_bbatt *bbatt,
+ const struct b43_rfatt *rfatt)
{
struct b43_txpower_lo_control *lo = dev->phy.g->lo_control;
struct b43_lo_calib *c;
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index c788bad10661..4896e0831114 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -4,7 +4,7 @@
Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>
Copyright (c) 2005 Stefano Brivio <stefano.brivio@polimi.it>
- Copyright (c) 2005, 2006 Michael Buesch <mb@bu3sch.de>
+ Copyright (c) 2005-2009 Michael Buesch <mb@bu3sch.de>
Copyright (c) 2005 Danny van Dyk <kugelfang@gentoo.org>
Copyright (c) 2005 Andreas Jaggi <andreas.jaggi@waterwave.ch>
@@ -88,6 +88,10 @@ static int modparam_btcoex = 1;
module_param_named(btcoex, modparam_btcoex, int, 0444);
MODULE_PARM_DESC(btcoex, "Enable Bluetooth coexistance (default on)");
+int b43_modparam_verbose = B43_VERBOSITY_DEFAULT;
+module_param_named(verbose, b43_modparam_verbose, int, 0644);
+MODULE_PARM_DESC(verbose, "Log message verbosity: 0=error, 1=warn, 2=info(default), 3=debug");
+
static const struct ssb_device_id b43_ssb_tbl[] = {
SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 5),
@@ -97,6 +101,8 @@ static const struct ssb_device_id b43_ssb_tbl[] = {
SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 10),
SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 11),
SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 13),
+ SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 15),
+ SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 16),
SSB_DEVTABLE_END
};
@@ -298,6 +304,8 @@ void b43info(struct b43_wl *wl, const char *fmt, ...)
{
va_list args;
+ if (b43_modparam_verbose < B43_VERBOSITY_INFO)
+ return;
if (!b43_ratelimit(wl))
return;
va_start(args, fmt);
@@ -311,6 +319,8 @@ void b43err(struct b43_wl *wl, const char *fmt, ...)
{
va_list args;
+ if (b43_modparam_verbose < B43_VERBOSITY_ERROR)
+ return;
if (!b43_ratelimit(wl))
return;
va_start(args, fmt);
@@ -324,6 +334,8 @@ void b43warn(struct b43_wl *wl, const char *fmt, ...)
{
va_list args;
+ if (b43_modparam_verbose < B43_VERBOSITY_WARN)
+ return;
if (!b43_ratelimit(wl))
return;
va_start(args, fmt);
@@ -333,18 +345,18 @@ void b43warn(struct b43_wl *wl, const char *fmt, ...)
va_end(args);
}
-#if B43_DEBUG
void b43dbg(struct b43_wl *wl, const char *fmt, ...)
{
va_list args;
+ if (b43_modparam_verbose < B43_VERBOSITY_DEBUG)
+ return;
va_start(args, fmt);
printk(KERN_DEBUG "b43-%s debug: ",
(wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan");
vprintk(fmt, args);
va_end(args);
}
-#endif /* DEBUG */
static void b43_ram_write(struct b43_wldev *dev, u16 offset, u32 val)
{
@@ -500,7 +512,7 @@ void b43_shm_write16(struct b43_wldev *dev, u16 routing, u16 offset, u16 value)
}
/* Read HostFlags */
-u64 b43_hf_read(struct b43_wldev * dev)
+u64 b43_hf_read(struct b43_wldev *dev)
{
u64 ret;
@@ -526,52 +538,20 @@ void b43_hf_write(struct b43_wldev *dev, u64 value)
b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_HOSTFHI, hi);
}
-void b43_tsf_read(struct b43_wldev *dev, u64 * tsf)
+void b43_tsf_read(struct b43_wldev *dev, u64 *tsf)
{
- /* We need to be careful. As we read the TSF from multiple
- * registers, we should take care of register overflows.
- * In theory, the whole tsf read process should be atomic.
- * We try to be atomic here, by restaring the read process,
- * if any of the high registers changed (overflew).
- */
- if (dev->dev->id.revision >= 3) {
- u32 low, high, high2;
+ u32 low, high;
- do {
- high = b43_read32(dev, B43_MMIO_REV3PLUS_TSF_HIGH);
- low = b43_read32(dev, B43_MMIO_REV3PLUS_TSF_LOW);
- high2 = b43_read32(dev, B43_MMIO_REV3PLUS_TSF_HIGH);
- } while (unlikely(high != high2));
-
- *tsf = high;
- *tsf <<= 32;
- *tsf |= low;
- } else {
- u64 tmp;
- u16 v0, v1, v2, v3;
- u16 test1, test2, test3;
+ B43_WARN_ON(dev->dev->id.revision < 3);
- do {
- v3 = b43_read16(dev, B43_MMIO_TSF_3);
- v2 = b43_read16(dev, B43_MMIO_TSF_2);
- v1 = b43_read16(dev, B43_MMIO_TSF_1);
- v0 = b43_read16(dev, B43_MMIO_TSF_0);
+ /* The hardware guarantees us an atomic read, if we
+ * read the low register first. */
+ low = b43_read32(dev, B43_MMIO_REV3PLUS_TSF_LOW);
+ high = b43_read32(dev, B43_MMIO_REV3PLUS_TSF_HIGH);
- test3 = b43_read16(dev, B43_MMIO_TSF_3);
- test2 = b43_read16(dev, B43_MMIO_TSF_2);
- test1 = b43_read16(dev, B43_MMIO_TSF_1);
- } while (v3 != test3 || v2 != test2 || v1 != test1);
-
- *tsf = v3;
- *tsf <<= 48;
- tmp = v2;
- tmp <<= 32;
- *tsf |= tmp;
- tmp = v1;
- tmp <<= 16;
- *tsf |= tmp;
- *tsf |= v0;
- }
+ *tsf = high;
+ *tsf <<= 32;
+ *tsf |= low;
}
static void b43_time_lock(struct b43_wldev *dev)
@@ -598,35 +578,18 @@ static void b43_time_unlock(struct b43_wldev *dev)
static void b43_tsf_write_locked(struct b43_wldev *dev, u64 tsf)
{
- /* Be careful with the in-progress timer.
- * First zero out the low register, so we have a full
- * register-overflow duration to complete the operation.
- */
- if (dev->dev->id.revision >= 3) {
- u32 lo = (tsf & 0x00000000FFFFFFFFULL);
- u32 hi = (tsf & 0xFFFFFFFF00000000ULL) >> 32;
+ u32 low, high;
- b43_write32(dev, B43_MMIO_REV3PLUS_TSF_LOW, 0);
- mmiowb();
- b43_write32(dev, B43_MMIO_REV3PLUS_TSF_HIGH, hi);
- mmiowb();
- b43_write32(dev, B43_MMIO_REV3PLUS_TSF_LOW, lo);
- } else {
- u16 v0 = (tsf & 0x000000000000FFFFULL);
- u16 v1 = (tsf & 0x00000000FFFF0000ULL) >> 16;
- u16 v2 = (tsf & 0x0000FFFF00000000ULL) >> 32;
- u16 v3 = (tsf & 0xFFFF000000000000ULL) >> 48;
+ B43_WARN_ON(dev->dev->id.revision < 3);
- b43_write16(dev, B43_MMIO_TSF_0, 0);
- mmiowb();
- b43_write16(dev, B43_MMIO_TSF_3, v3);
- mmiowb();
- b43_write16(dev, B43_MMIO_TSF_2, v2);
- mmiowb();
- b43_write16(dev, B43_MMIO_TSF_1, v1);
- mmiowb();
- b43_write16(dev, B43_MMIO_TSF_0, v0);
- }
+ low = tsf;
+ high = (tsf >> 32);
+ /* The hardware guarantees us an atomic write, if we
+ * write the low register first. */
+ b43_write32(dev, B43_MMIO_REV3PLUS_TSF_LOW, low);
+ mmiowb();
+ b43_write32(dev, B43_MMIO_REV3PLUS_TSF_HIGH, high);
+ mmiowb();
}
void b43_tsf_write(struct b43_wldev *dev, u64 tsf)
@@ -637,7 +600,7 @@ void b43_tsf_write(struct b43_wldev *dev, u64 tsf)
}
static
-void b43_macfilter_set(struct b43_wldev *dev, u16 offset, const u8 * mac)
+void b43_macfilter_set(struct b43_wldev *dev, u16 offset, const u8 *mac)
{
static const u8 zero_addr[ETH_ALEN] = { 0 };
u16 data;
@@ -827,7 +790,7 @@ void b43_dummy_transmission(struct b43_wldev *dev)
}
static void key_write(struct b43_wldev *dev,
- u8 index, u8 algorithm, const u8 * key)
+ u8 index, u8 algorithm, const u8 *key)
{
unsigned int i;
u32 offset;
@@ -849,7 +812,7 @@ static void key_write(struct b43_wldev *dev,
}
}
-static void keymac_write(struct b43_wldev *dev, u8 index, const u8 * addr)
+static void keymac_write(struct b43_wldev *dev, u8 index, const u8 *addr)
{
u32 addrtmp[2] = { 0, 0, };
u8 per_sta_keys_start = 8;
@@ -899,7 +862,7 @@ static void keymac_write(struct b43_wldev *dev, u8 index, const u8 * addr)
static void do_key_write(struct b43_wldev *dev,
u8 index, u8 algorithm,
- const u8 * key, size_t key_len, const u8 * mac_addr)
+ const u8 *key, size_t key_len, const u8 *mac_addr)
{
u8 buf[B43_SEC_KEYSIZE] = { 0, };
u8 per_sta_keys_start = 8;
@@ -923,8 +886,8 @@ static void do_key_write(struct b43_wldev *dev,
static int b43_key_write(struct b43_wldev *dev,
int index, u8 algorithm,
- const u8 * key, size_t key_len,
- const u8 * mac_addr,
+ const u8 *key, size_t key_len,
+ const u8 *mac_addr,
struct ieee80211_key_conf *keyconf)
{
int i;
@@ -937,8 +900,7 @@ static int b43_key_write(struct b43_wldev *dev,
B43_WARN_ON(dev->key[i].keyconf == keyconf);
}
if (index < 0) {
- /* Either pairwise key or address is 00:00:00:00:00:00
- * for transmit-only keys. Search the index. */
+ /* Pairwise key. Get an empty slot for the key. */
if (b43_new_kidx_api(dev))
sta_keys_start = 4;
else
@@ -951,7 +913,7 @@ static int b43_key_write(struct b43_wldev *dev,
}
}
if (index < 0) {
- b43err(dev->wl, "Out of hardware key memory\n");
+ b43warn(dev->wl, "Out of hardware key memory\n");
return -ENOSPC;
}
} else
@@ -1324,7 +1286,7 @@ static void handle_irq_pmq(struct b43_wldev *dev)
}
static void b43_write_template_common(struct b43_wldev *dev,
- const u8 * data, u16 size,
+ const u8 *data, u16 size,
u16 ram_offset,
u16 shm_size_offset, u8 rate)
{
@@ -1514,9 +1476,9 @@ static void b43_write_probe_resp_plcp(struct b43_wldev *dev,
* 2) Patching duration field
* 3) Stripping TIM
*/
-static const u8 * b43_generate_probe_resp(struct b43_wldev *dev,
- u16 *dest_size,
- struct ieee80211_rate *rate)
+static const u8 *b43_generate_probe_resp(struct b43_wldev *dev,
+ u16 *dest_size,
+ struct ieee80211_rate *rate)
{
const u8 *src_data;
u8 *dest_data;
@@ -1982,7 +1944,7 @@ static irqreturn_t b43_interrupt_handler(int irq, void *dev_id)
return ret;
}
-static void do_release_fw(struct b43_firmware_file *fw)
+void b43_do_release_fw(struct b43_firmware_file *fw)
{
release_firmware(fw->data);
fw->data = NULL;
@@ -1991,31 +1953,30 @@ static void do_release_fw(struct b43_firmware_file *fw)
static void b43_release_firmware(struct b43_wldev *dev)
{
- do_release_fw(&dev->fw.ucode);
- do_release_fw(&dev->fw.pcm);
- do_release_fw(&dev->fw.initvals);
- do_release_fw(&dev->fw.initvals_band);
+ b43_do_release_fw(&dev->fw.ucode);
+ b43_do_release_fw(&dev->fw.pcm);
+ b43_do_release_fw(&dev->fw.initvals);
+ b43_do_release_fw(&dev->fw.initvals_band);
}
static void b43_print_fw_helptext(struct b43_wl *wl, bool error)
{
- const char *text;
+ const char text[] =
+ "You must go to " \
+ "http://wireless.kernel.org/en/users/Drivers/b43#devicefirmware " \
+ "and download the correct firmware for this driver version. " \
+ "Please carefully read all instructions on this website.\n";
- text = "You must go to "
- "http://linuxwireless.org/en/users/Drivers/b43#devicefirmware "
- "and download the latest firmware (version 4).\n";
if (error)
b43err(wl, text);
else
b43warn(wl, text);
}
-static int do_request_fw(struct b43_wldev *dev,
- const char *name,
- struct b43_firmware_file *fw,
- bool silent)
+int b43_do_request_fw(struct b43_request_fw_context *ctx,
+ const char *name,
+ struct b43_firmware_file *fw)
{
- char path[sizeof(modparam_fwpostfix) + 32];
const struct firmware *blob;
struct b43_fw_header *hdr;
u32 size;
@@ -2023,29 +1984,49 @@ static int do_request_fw(struct b43_wldev *dev,
if (!name) {
/* Don't fetch anything. Free possibly cached firmware. */
- do_release_fw(fw);
+ /* FIXME: We should probably keep it anyway, to save some headache
+ * on suspend/resume with multiband devices. */
+ b43_do_release_fw(fw);
return 0;
}
if (fw->filename) {
- if (strcmp(fw->filename, name) == 0)
+ if ((fw->type == ctx->req_type) &&
+ (strcmp(fw->filename, name) == 0))
return 0; /* Already have this fw. */
/* Free the cached firmware first. */
- do_release_fw(fw);
+ /* FIXME: We should probably do this later after we successfully
+ * got the new fw. This could reduce headache with multiband devices.
+ * We could also redesign this to cache the firmware for all possible
+ * bands all the time. */
+ b43_do_release_fw(fw);
+ }
+
+ switch (ctx->req_type) {
+ case B43_FWTYPE_PROPRIETARY:
+ snprintf(ctx->fwname, sizeof(ctx->fwname),
+ "b43%s/%s.fw",
+ modparam_fwpostfix, name);
+ break;
+ case B43_FWTYPE_OPENSOURCE:
+ snprintf(ctx->fwname, sizeof(ctx->fwname),
+ "b43-open%s/%s.fw",
+ modparam_fwpostfix, name);
+ break;
+ default:
+ B43_WARN_ON(1);
+ return -ENOSYS;
}
-
- snprintf(path, ARRAY_SIZE(path),
- "b43%s/%s.fw",
- modparam_fwpostfix, name);
- err = request_firmware(&blob, path, dev->dev->dev);
+ err = request_firmware(&blob, ctx->fwname, ctx->dev->dev->dev);
if (err == -ENOENT) {
- if (!silent) {
- b43err(dev->wl, "Firmware file \"%s\" not found\n",
- path);
- }
+ snprintf(ctx->errors[ctx->req_type],
+ sizeof(ctx->errors[ctx->req_type]),
+ "Firmware file \"%s\" not found\n", ctx->fwname);
return err;
} else if (err) {
- b43err(dev->wl, "Firmware file \"%s\" request failed (err=%d)\n",
- path, err);
+ snprintf(ctx->errors[ctx->req_type],
+ sizeof(ctx->errors[ctx->req_type]),
+ "Firmware file \"%s\" request failed (err=%d)\n",
+ ctx->fwname, err);
return err;
}
if (blob->size < sizeof(struct b43_fw_header))
@@ -2068,20 +2049,24 @@ static int do_request_fw(struct b43_wldev *dev,
fw->data = blob;
fw->filename = name;
+ fw->type = ctx->req_type;
return 0;
err_format:
- b43err(dev->wl, "Firmware file \"%s\" format error.\n", path);
+ snprintf(ctx->errors[ctx->req_type],
+ sizeof(ctx->errors[ctx->req_type]),
+ "Firmware file \"%s\" format error.\n", ctx->fwname);
release_firmware(blob);
return -EPROTO;
}
-static int b43_request_firmware(struct b43_wldev *dev)
+static int b43_try_request_fw(struct b43_request_fw_context *ctx)
{
- struct b43_firmware *fw = &dev->fw;
- const u8 rev = dev->dev->id.revision;
+ struct b43_wldev *dev = ctx->dev;
+ struct b43_firmware *fw = &ctx->dev->fw;
+ const u8 rev = ctx->dev->dev->id.revision;
const char *filename;
u32 tmshigh;
int err;
@@ -2096,7 +2081,7 @@ static int b43_request_firmware(struct b43_wldev *dev)
filename = "ucode13";
else
goto err_no_ucode;
- err = do_request_fw(dev, filename, &fw->ucode, 0);
+ err = b43_do_request_fw(ctx, filename, &fw->ucode);
if (err)
goto err_load;
@@ -2108,7 +2093,7 @@ static int b43_request_firmware(struct b43_wldev *dev)
else
goto err_no_pcm;
fw->pcm_request_failed = 0;
- err = do_request_fw(dev, filename, &fw->pcm, 1);
+ err = b43_do_request_fw(ctx, filename, &fw->pcm);
if (err == -ENOENT) {
/* We did not find a PCM file? Not fatal, but
* core rev <= 10 must do without hwcrypto then. */
@@ -2144,7 +2129,7 @@ static int b43_request_firmware(struct b43_wldev *dev)
default:
goto err_no_initvals;
}
- err = do_request_fw(dev, filename, &fw->initvals, 0);
+ err = b43_do_request_fw(ctx, filename, &fw->initvals);
if (err)
goto err_load;
@@ -2178,30 +2163,34 @@ static int b43_request_firmware(struct b43_wldev *dev)
default:
goto err_no_initvals;
}
- err = do_request_fw(dev, filename, &fw->initvals_band, 0);
+ err = b43_do_request_fw(ctx, filename, &fw->initvals_band);
if (err)
goto err_load;
return 0;
-err_load:
- b43_print_fw_helptext(dev->wl, 1);
- goto error;
-
err_no_ucode:
- err = -ENODEV;
- b43err(dev->wl, "No microcode available for core rev %u\n", rev);
+ err = ctx->fatal_failure = -EOPNOTSUPP;
+ b43err(dev->wl, "The driver does not know which firmware (ucode) "
+ "is required for your device (wl-core rev %u)\n", rev);
goto error;
err_no_pcm:
- err = -ENODEV;
- b43err(dev->wl, "No PCM available for core rev %u\n", rev);
+ err = ctx->fatal_failure = -EOPNOTSUPP;
+ b43err(dev->wl, "The driver does not know which firmware (PCM) "
+ "is required for your device (wl-core rev %u)\n", rev);
goto error;
err_no_initvals:
- err = -ENODEV;
- b43err(dev->wl, "No Initial Values firmware file for PHY %u, "
- "core rev %u\n", dev->phy.type, rev);
+ err = ctx->fatal_failure = -EOPNOTSUPP;
+ b43err(dev->wl, "The driver does not know which firmware (initvals) "
+ "is required for your device (wl-core rev %u)\n", rev);
+ goto error;
+
+err_load:
+ /* We failed to load this firmware image. The error message
+ * already is in ctx->errors. Return and let our caller decide
+ * what to do. */
goto error;
error:
@@ -2209,6 +2198,48 @@ error:
return err;
}
+static int b43_request_firmware(struct b43_wldev *dev)
+{
+ struct b43_request_fw_context *ctx;
+ unsigned int i;
+ int err;
+ const char *errmsg;
+
+ ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
+ if (!ctx)
+ return -ENOMEM;
+ ctx->dev = dev;
+
+ ctx->req_type = B43_FWTYPE_PROPRIETARY;
+ err = b43_try_request_fw(ctx);
+ if (!err)
+ goto out; /* Successfully loaded it. */
+ err = ctx->fatal_failure;
+ if (err)
+ goto out;
+
+ ctx->req_type = B43_FWTYPE_OPENSOURCE;
+ err = b43_try_request_fw(ctx);
+ if (!err)
+ goto out; /* Successfully loaded it. */
+ err = ctx->fatal_failure;
+ if (err)
+ goto out;
+
+ /* Could not find a usable firmware. Print the errors. */
+ for (i = 0; i < B43_NR_FWTYPES; i++) {
+ errmsg = ctx->errors[i];
+ if (strlen(errmsg))
+ b43err(dev->wl, errmsg);
+ }
+ b43_print_fw_helptext(dev->wl, 1);
+ err = -ENOENT;
+
+out:
+ kfree(ctx);
+ return err;
+}
+
static int b43_upload_microcode(struct b43_wldev *dev)
{
const size_t hdr_len = sizeof(struct b43_fw_header);
@@ -2319,8 +2350,11 @@ static int b43_upload_microcode(struct b43_wldev *dev)
}
if (b43_is_old_txhdr_format(dev)) {
+ /* We're over the deadline, but we keep support for old fw
+ * until it turns out to be in major conflict with something new. */
b43warn(dev->wl, "You are using an old firmware image. "
- "Support for old firmware will be removed in July 2008.\n");
+ "Support for old firmware will be removed soon "
+ "(official deadline was July 2008).\n");
b43_print_fw_helptext(dev->wl, 0);
}
@@ -2946,7 +2980,7 @@ static void b43_security_init(struct b43_wldev *dev)
b43_clear_keys(dev);
}
-static int b43_rng_read(struct hwrng *rng, u32 * data)
+static int b43_rng_read(struct hwrng *rng, u32 *data)
{
struct b43_wl *wl = (struct b43_wl *)rng->priv;
unsigned long flags;
@@ -3221,6 +3255,43 @@ static int b43_op_get_stats(struct ieee80211_hw *hw,
return 0;
}
+static u64 b43_op_get_tsf(struct ieee80211_hw *hw)
+{
+ struct b43_wl *wl = hw_to_b43_wl(hw);
+ struct b43_wldev *dev;
+ u64 tsf;
+
+ mutex_lock(&wl->mutex);
+ spin_lock_irq(&wl->irq_lock);
+ dev = wl->current_dev;
+
+ if (dev && (b43_status(dev) >= B43_STAT_INITIALIZED))
+ b43_tsf_read(dev, &tsf);
+ else
+ tsf = 0;
+
+ spin_unlock_irq(&wl->irq_lock);
+ mutex_unlock(&wl->mutex);
+
+ return tsf;
+}
+
+static void b43_op_set_tsf(struct ieee80211_hw *hw, u64 tsf)
+{
+ struct b43_wl *wl = hw_to_b43_wl(hw);
+ struct b43_wldev *dev;
+
+ mutex_lock(&wl->mutex);
+ spin_lock_irq(&wl->irq_lock);
+ dev = wl->current_dev;
+
+ if (dev && (b43_status(dev) >= B43_STAT_INITIALIZED))
+ b43_tsf_write(dev, tsf);
+
+ spin_unlock_irq(&wl->irq_lock);
+ mutex_unlock(&wl->mutex);
+}
+
static void b43_put_phy_into_reset(struct b43_wldev *dev)
{
struct ssb_device *sdev = dev->dev;
@@ -3240,7 +3311,7 @@ static void b43_put_phy_into_reset(struct b43_wldev *dev)
msleep(1);
}
-static const char * band_to_string(enum ieee80211_band band)
+static const char *band_to_string(enum ieee80211_band band)
{
switch (band) {
case IEEE80211_BAND_5GHZ:
@@ -3442,7 +3513,7 @@ out_unlock_mutex:
return err;
}
-static void b43_update_basic_rates(struct b43_wldev *dev, u64 brates)
+static void b43_update_basic_rates(struct b43_wldev *dev, u32 brates)
{
struct ieee80211_supported_band *sband =
dev->wl->hw->wiphy->bands[b43_current_band(dev->wl)];
@@ -3520,21 +3591,29 @@ out_unlock_mutex:
}
static int b43_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
- const u8 *local_addr, const u8 *addr,
- struct ieee80211_key_conf *key)
+ struct ieee80211_vif *vif, struct ieee80211_sta *sta,
+ struct ieee80211_key_conf *key)
{
struct b43_wl *wl = hw_to_b43_wl(hw);
struct b43_wldev *dev;
- unsigned long flags;
u8 algorithm;
u8 index;
int err;
+ static const u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
if (modparam_nohwcrypt)
return -ENOSPC; /* User disabled HW-crypto */
mutex_lock(&wl->mutex);
- spin_lock_irqsave(&wl->irq_lock, flags);
+ spin_lock_irq(&wl->irq_lock);
+ write_lock(&wl->tx_lock);
+ /* Why do we need all this locking here?
+ * mutex -> Every config operation must take it.
+ * irq_lock -> We modify the dev->key array, which is accessed
+ * in the IRQ handlers.
+ * tx_lock -> We modify the dev->key array, which is accessed
+ * in the TX handler.
+ */
dev = wl->current_dev;
err = -ENODEV;
@@ -3551,7 +3630,7 @@ static int b43_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
err = -EINVAL;
switch (key->alg) {
case ALG_WEP:
- if (key->keylen == 5)
+ if (key->keylen == LEN_WEP40)
algorithm = B43_SEC_ALGO_WEP40;
else
algorithm = B43_SEC_ALGO_WEP104;
@@ -3578,17 +3657,19 @@ static int b43_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
goto out_unlock;
}
- if (is_broadcast_ether_addr(addr)) {
- /* addr is FF:FF:FF:FF:FF:FF for default keys */
+ if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
+ if (WARN_ON(!sta)) {
+ err = -EOPNOTSUPP;
+ goto out_unlock;
+ }
+ /* Pairwise key with an assigned MAC address. */
+ err = b43_key_write(dev, -1, algorithm,
+ key->key, key->keylen,
+ sta->addr, key);
+ } else {
+ /* Group key */
err = b43_key_write(dev, index, algorithm,
key->key, key->keylen, NULL, key);
- } else {
- /*
- * either pairwise key or address is 00:00:00:00:00:00
- * for transmit-only keys
- */
- err = b43_key_write(dev, -1, algorithm,
- key->key, key->keylen, addr, key);
}
if (err)
goto out_unlock;
@@ -3617,10 +3698,11 @@ out_unlock:
b43dbg(wl, "%s hardware based encryption for keyidx: %d, "
"mac: %pM\n",
cmd == SET_KEY ? "Using" : "Disabling", key->keyidx,
- addr);
+ sta ? sta->addr : bcast_addr);
b43_dump_keymemory(dev);
}
- spin_unlock_irqrestore(&wl->irq_lock, flags);
+ write_unlock(&wl->tx_lock);
+ spin_unlock_irq(&wl->irq_lock);
mutex_unlock(&wl->mutex);
return err;
@@ -3796,6 +3878,12 @@ static int b43_phy_versioning(struct b43_wldev *dev)
break;
#ifdef CONFIG_B43_NPHY
case B43_PHYTYPE_N:
+ if (phy_rev > 4)
+ unsupported = 1;
+ break;
+#endif
+#ifdef CONFIG_B43_PHY_LP
+ case B43_PHYTYPE_LP:
if (phy_rev > 1)
unsupported = 1;
break;
@@ -3849,7 +3937,11 @@ static int b43_phy_versioning(struct b43_wldev *dev)
unsupported = 1;
break;
case B43_PHYTYPE_N:
- if (radio_ver != 0x2055)
+ if (radio_ver != 0x2055 && radio_ver != 0x2056)
+ unsupported = 1;
+ break;
+ case B43_PHYTYPE_LP:
+ if (radio_ver != 0x2062)
unsupported = 1;
break;
default:
@@ -3901,6 +3993,8 @@ static void setup_struct_wldev_for_init(struct b43_wldev *dev)
dev->irq_reason = 0;
memset(dev->dma_reason, 0, sizeof(dev->dma_reason));
dev->irq_savedstate = B43_IRQ_MASKTEMPLATE;
+ if (b43_modparam_verbose < B43_VERBOSITY_DEBUG)
+ dev->irq_savedstate &= ~B43_IRQ_PHY_TXERR;
dev->mac_suspended = 1;
@@ -4078,11 +4172,21 @@ static int b43_wireless_core_init(struct b43_wldev *dev)
hf |= B43_HF_GDCW;
if (sprom->boardflags_lo & B43_BFL_PACTRL)
hf |= B43_HF_OFDMPABOOST;
- } else if (phy->type == B43_PHYTYPE_B) {
- hf |= B43_HF_SYMW;
- if (phy->rev >= 2 && phy->radio_ver == 0x2050)
- hf &= ~B43_HF_GDCW;
}
+ if (phy->radio_ver == 0x2050) {
+ if (phy->radio_rev == 6)
+ hf |= B43_HF_4318TSSI;
+ if (phy->radio_rev < 6)
+ hf |= B43_HF_VCORECALC;
+ }
+ if (sprom->boardflags_lo & B43_BFL_XTAL_NOSLOW)
+ hf |= B43_HF_DSCRQ; /* Disable slowclock requests from ucode. */
+#ifdef CONFIG_SSB_DRIVER_PCICORE
+ if ((bus->bustype == SSB_BUSTYPE_PCI) &&
+ (bus->pcicore.dev->id.revision <= 10))
+ hf |= B43_HF_PCISCW; /* PCI slow clock workaround. */
+#endif
+ hf &= ~B43_HF_SKCFPUP;
b43_hf_write(dev, hf);
b43_set_retry_limits(dev, B43_DEFAULT_SHORT_RETRY_LIMIT,
@@ -4121,7 +4225,7 @@ static int b43_wireless_core_init(struct b43_wldev *dev)
b43_set_synth_pu_delay(dev, 1);
b43_bluetooth_coext_enable(dev);
- ssb_bus_powerup(bus, 1); /* Enable dynamic PCTL */
+ ssb_bus_powerup(bus, !(sprom->boardflags_lo & B43_BFL_XTAL_NOSLOW));
b43_upload_card_macaddress(dev);
b43_security_init(dev);
if (!dev->suspend_in_progress)
@@ -4305,6 +4409,34 @@ static void b43_op_sta_notify(struct ieee80211_hw *hw,
B43_WARN_ON(!vif || wl->vif != vif);
}
+static void b43_op_sw_scan_start_notifier(struct ieee80211_hw *hw)
+{
+ struct b43_wl *wl = hw_to_b43_wl(hw);
+ struct b43_wldev *dev;
+
+ mutex_lock(&wl->mutex);
+ dev = wl->current_dev;
+ if (dev && (b43_status(dev) >= B43_STAT_INITIALIZED)) {
+ /* Disable CFP update during scan on other channels. */
+ b43_hf_write(dev, b43_hf_read(dev) | B43_HF_SKCFPUP);
+ }
+ mutex_unlock(&wl->mutex);
+}
+
+static void b43_op_sw_scan_complete_notifier(struct ieee80211_hw *hw)
+{
+ struct b43_wl *wl = hw_to_b43_wl(hw);
+ struct b43_wldev *dev;
+
+ mutex_lock(&wl->mutex);
+ dev = wl->current_dev;
+ if (dev && (b43_status(dev) >= B43_STAT_INITIALIZED)) {
+ /* Re-enable CFP update. */
+ b43_hf_write(dev, b43_hf_read(dev) & ~B43_HF_SKCFPUP);
+ }
+ mutex_unlock(&wl->mutex);
+}
+
static const struct ieee80211_ops b43_hw_ops = {
.tx = b43_op_tx,
.conf_tx = b43_op_conf_tx,
@@ -4317,10 +4449,14 @@ static const struct ieee80211_ops b43_hw_ops = {
.set_key = b43_op_set_key,
.get_stats = b43_op_get_stats,
.get_tx_stats = b43_op_get_tx_stats,
+ .get_tsf = b43_op_get_tsf,
+ .set_tsf = b43_op_set_tsf,
.start = b43_op_start,
.stop = b43_op_stop,
.set_tim = b43_op_beacon_set_tim,
.sta_notify = b43_op_sta_notify,
+ .sw_scan_start = b43_op_sw_scan_start_notifier,
+ .sw_scan_complete = b43_op_sw_scan_complete_notifier,
};
/* Hard-reset the chip. Do not call this directly.
@@ -4446,6 +4582,7 @@ static int b43_wireless_core_attach(struct b43_wldev *dev)
break;
case B43_PHYTYPE_G:
case B43_PHYTYPE_N:
+ case B43_PHYTYPE_LP:
have_2ghz_phy = 1;
break;
default:
@@ -4657,9 +4794,10 @@ static int b43_wireless_init(struct ssb_device *dev)
INIT_WORK(&wl->txpower_adjust_work, b43_phy_txpower_adjust_work);
ssb_set_devtypedata(dev, wl);
- b43info(wl, "Broadcom %04X WLAN found\n", dev->bus->chip_id);
+ b43info(wl, "Broadcom %04X WLAN found (core revision %u)\n",
+ dev->bus->chip_id, dev->id.revision);
err = 0;
- out:
+out:
return err;
}
diff --git a/drivers/net/wireless/b43/main.h b/drivers/net/wireless/b43/main.h
index f871a252cb55..40abcf5d1b43 100644
--- a/drivers/net/wireless/b43/main.h
+++ b/drivers/net/wireless/b43/main.h
@@ -40,6 +40,24 @@
extern int b43_modparam_qos;
+extern int b43_modparam_verbose;
+
+/* Logmessage verbosity levels. Update the b43_modparam_verbose helptext, if
+ * you add or remove levels. */
+enum b43_verbosity {
+ B43_VERBOSITY_ERROR,
+ B43_VERBOSITY_WARN,
+ B43_VERBOSITY_INFO,
+ B43_VERBOSITY_DEBUG,
+ __B43_VERBOSITY_AFTERLAST, /* keep last */
+
+ B43_VERBOSITY_MAX = __B43_VERBOSITY_AFTERLAST - 1,
+#if B43_DEBUG
+ B43_VERBOSITY_DEFAULT = B43_VERBOSITY_DEBUG,
+#else
+ B43_VERBOSITY_DEFAULT = B43_VERBOSITY_INFO,
+#endif
+};
/* Lightweight function to convert a frequency (in Mhz) to a channel number. */
@@ -121,4 +139,11 @@ void b43_power_saving_ctl_bits(struct b43_wldev *dev, unsigned int ps_flags);
void b43_mac_suspend(struct b43_wldev *dev);
void b43_mac_enable(struct b43_wldev *dev);
+
+struct b43_request_fw_context;
+int b43_do_request_fw(struct b43_request_fw_context *ctx,
+ const char *name,
+ struct b43_firmware_file *fw);
+void b43_do_release_fw(struct b43_firmware_file *fw);
+
#endif /* B43_MAIN_H_ */
diff --git a/drivers/net/wireless/b43/phy_a.c b/drivers/net/wireless/b43/phy_a.c
index 7fe9d1701624..c836c077d51d 100644
--- a/drivers/net/wireless/b43/phy_a.c
+++ b/drivers/net/wireless/b43/phy_a.c
@@ -121,27 +121,18 @@ static void aphy_channel_switch(struct b43_wldev *dev, unsigned int channel)
b43_radio_write16(dev, 0x0007, (r8 << 4) | r8);
b43_radio_write16(dev, 0x0020, (r8 << 4) | r8);
b43_radio_write16(dev, 0x0021, (r8 << 4) | r8);
- b43_radio_write16(dev, 0x0022, (b43_radio_read16(dev, 0x0022)
- & 0x000F) | (r8 << 4));
+ b43_radio_maskset(dev, 0x0022, 0x000F, (r8 << 4));
b43_radio_write16(dev, 0x002A, (r8 << 4));
b43_radio_write16(dev, 0x002B, (r8 << 4));
- b43_radio_write16(dev, 0x0008, (b43_radio_read16(dev, 0x0008)
- & 0x00F0) | (r8 << 4));
- b43_radio_write16(dev, 0x0029, (b43_radio_read16(dev, 0x0029)
- & 0xFF0F) | 0x00B0);
+ b43_radio_maskset(dev, 0x0008, 0x00F0, (r8 << 4));
+ b43_radio_maskset(dev, 0x0029, 0xFF0F, 0x00B0);
b43_radio_write16(dev, 0x0035, 0x00AA);
b43_radio_write16(dev, 0x0036, 0x0085);
- b43_radio_write16(dev, 0x003A, (b43_radio_read16(dev, 0x003A)
- & 0xFF20) |
- freq_r3A_value(freq));
- b43_radio_write16(dev, 0x003D,
- b43_radio_read16(dev, 0x003D) & 0x00FF);
- b43_radio_write16(dev, 0x0081, (b43_radio_read16(dev, 0x0081)
- & 0xFF7F) | 0x0080);
- b43_radio_write16(dev, 0x0035,
- b43_radio_read16(dev, 0x0035) & 0xFFEF);
- b43_radio_write16(dev, 0x0035, (b43_radio_read16(dev, 0x0035)
- & 0xFFEF) | 0x0010);
+ b43_radio_maskset(dev, 0x003A, 0xFF20, freq_r3A_value(freq));
+ b43_radio_mask(dev, 0x003D, 0x00FF);
+ b43_radio_maskset(dev, 0x0081, 0xFF7F, 0x0080);
+ b43_radio_mask(dev, 0x0035, 0xFFEF);
+ b43_radio_maskset(dev, 0x0035, 0xFFEF, 0x0010);
b43_radio_set_tx_iq(dev);
//TODO: TSSI2dbm workaround
//FIXME b43_phy_xmitpower(dev);
@@ -160,23 +151,20 @@ static void b43_radio_init2060(struct b43_wldev *dev)
b43_radio_write16(dev, 0x0082, 0x0080);
b43_radio_write16(dev, 0x0080, 0x0000);
b43_radio_write16(dev, 0x003F, 0x00DA);
- b43_radio_write16(dev, 0x0005, b43_radio_read16(dev, 0x0005) & ~0x0008);
- b43_radio_write16(dev, 0x0081, b43_radio_read16(dev, 0x0081) & ~0x0010);
- b43_radio_write16(dev, 0x0081, b43_radio_read16(dev, 0x0081) & ~0x0020);
- b43_radio_write16(dev, 0x0081, b43_radio_read16(dev, 0x0081) & ~0x0020);
+ b43_radio_mask(dev, 0x0005, ~0x0008);
+ b43_radio_mask(dev, 0x0081, ~0x0010);
+ b43_radio_mask(dev, 0x0081, ~0x0020);
+ b43_radio_mask(dev, 0x0081, ~0x0020);
msleep(1); /* delay 400usec */
- b43_radio_write16(dev, 0x0081,
- (b43_radio_read16(dev, 0x0081) & ~0x0020) | 0x0010);
+ b43_radio_maskset(dev, 0x0081, ~0x0020, 0x0010);
msleep(1); /* delay 400usec */
- b43_radio_write16(dev, 0x0005,
- (b43_radio_read16(dev, 0x0005) & ~0x0008) | 0x0008);
- b43_radio_write16(dev, 0x0085, b43_radio_read16(dev, 0x0085) & ~0x0010);
- b43_radio_write16(dev, 0x0005, b43_radio_read16(dev, 0x0005) & ~0x0008);
- b43_radio_write16(dev, 0x0081, b43_radio_read16(dev, 0x0081) & ~0x0040);
- b43_radio_write16(dev, 0x0081,
- (b43_radio_read16(dev, 0x0081) & ~0x0040) | 0x0040);
+ b43_radio_maskset(dev, 0x0005, ~0x0008, 0x0008);
+ b43_radio_mask(dev, 0x0085, ~0x0010);
+ b43_radio_mask(dev, 0x0005, ~0x0008);
+ b43_radio_mask(dev, 0x0081, ~0x0040);
+ b43_radio_maskset(dev, 0x0081, ~0x0040, 0x0040);
b43_radio_write16(dev, 0x0005,
(b43_radio_read16(dev, 0x0081) & ~0x0008) | 0x0008);
b43_phy_write(dev, 0x0063, 0xDDC6);
@@ -224,22 +212,16 @@ static void b43_phy_ww(struct b43_wldev *dev)
u16 b, curr_s, best_s = 0xFFFF;
int i;
- b43_phy_write(dev, B43_PHY_CRS0,
- b43_phy_read(dev, B43_PHY_CRS0) & ~B43_PHY_CRS0_EN);
- b43_phy_write(dev, B43_PHY_OFDM(0x1B),
- b43_phy_read(dev, B43_PHY_OFDM(0x1B)) | 0x1000);
- b43_phy_write(dev, B43_PHY_OFDM(0x82),
- (b43_phy_read(dev, B43_PHY_OFDM(0x82)) & 0xF0FF) | 0x0300);
- b43_radio_write16(dev, 0x0009,
- b43_radio_read16(dev, 0x0009) | 0x0080);
- b43_radio_write16(dev, 0x0012,
- (b43_radio_read16(dev, 0x0012) & 0xFFFC) | 0x0002);
+ b43_phy_mask(dev, B43_PHY_CRS0, ~B43_PHY_CRS0_EN);
+ b43_phy_set(dev, B43_PHY_OFDM(0x1B), 0x1000);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0x82), 0xF0FF, 0x0300);
+ b43_radio_set(dev, 0x0009, 0x0080);
+ b43_radio_maskset(dev, 0x0012, 0xFFFC, 0x0002);
b43_wa_initgains(dev);
b43_phy_write(dev, B43_PHY_OFDM(0xBA), 0x3ED5);
b = b43_phy_read(dev, B43_PHY_PWRDOWN);
b43_phy_write(dev, B43_PHY_PWRDOWN, (b & 0xFFF8) | 0x0005);
- b43_radio_write16(dev, 0x0004,
- b43_radio_read16(dev, 0x0004) | 0x0004);
+ b43_radio_set(dev, 0x0004, 0x0004);
for (i = 0x10; i <= 0x20; i++) {
b43_radio_write16(dev, 0x0013, i);
curr_s = b43_phy_read(dev, B43_PHY_OTABLEQ) & 0x00FF;
@@ -252,8 +234,7 @@ static void b43_phy_ww(struct b43_wldev *dev)
best_s = curr_s;
}
b43_phy_write(dev, B43_PHY_PWRDOWN, b);
- b43_radio_write16(dev, 0x0004,
- b43_radio_read16(dev, 0x0004) & 0xFFFB);
+ b43_radio_mask(dev, 0x0004, 0xFFFB);
b43_radio_write16(dev, 0x0013, best_s);
b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1_R1, 0, 0xFFEC);
b43_phy_write(dev, B43_PHY_OFDM(0xB7), 0x1E80);
@@ -261,14 +242,10 @@ static void b43_phy_ww(struct b43_wldev *dev)
b43_phy_write(dev, B43_PHY_OFDM(0xB5), 0x0EC0);
b43_phy_write(dev, B43_PHY_OFDM(0xB2), 0x00C0);
b43_phy_write(dev, B43_PHY_OFDM(0xB9), 0x1FFF);
- b43_phy_write(dev, B43_PHY_OFDM(0xBB),
- (b43_phy_read(dev, B43_PHY_OFDM(0xBB)) & 0xF000) | 0x0053);
- b43_phy_write(dev, B43_PHY_OFDM61,
- (b43_phy_read(dev, B43_PHY_OFDM61) & 0xFE1F) | 0x0120);
- b43_phy_write(dev, B43_PHY_OFDM(0x13),
- (b43_phy_read(dev, B43_PHY_OFDM(0x13)) & 0x0FFF) | 0x3000);
- b43_phy_write(dev, B43_PHY_OFDM(0x14),
- (b43_phy_read(dev, B43_PHY_OFDM(0x14)) & 0x0FFF) | 0x3000);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0xBB), 0xF000, 0x0053);
+ b43_phy_maskset(dev, B43_PHY_OFDM61, 0xFE1F, 0x0120);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0x13), 0x0FFF, 0x3000);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0x14), 0x0FFF, 0x3000);
b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 6, 0x0017);
for (i = 0; i < 6; i++)
b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, i, 0x000F);
@@ -276,8 +253,7 @@ static void b43_phy_ww(struct b43_wldev *dev)
b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 0x0E, 0x0011);
b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 0x0F, 0x0013);
b43_phy_write(dev, B43_PHY_OFDM(0x33), 0x5030);
- b43_phy_write(dev, B43_PHY_CRS0,
- b43_phy_read(dev, B43_PHY_CRS0) | B43_PHY_CRS0_EN);
+ b43_phy_set(dev, B43_PHY_CRS0, B43_PHY_CRS0_EN);
}
static void hardware_pctl_init_aphy(struct b43_wldev *dev)
@@ -300,26 +276,21 @@ void b43_phy_inita(struct b43_wldev *dev)
if (phy->rev >= 6) {
if (phy->type == B43_PHYTYPE_A)
- b43_phy_write(dev, B43_PHY_OFDM(0x1B),
- b43_phy_read(dev, B43_PHY_OFDM(0x1B)) & ~0x1000);
+ b43_phy_mask(dev, B43_PHY_OFDM(0x1B), ~0x1000);
if (b43_phy_read(dev, B43_PHY_ENCORE) & B43_PHY_ENCORE_EN)
- b43_phy_write(dev, B43_PHY_ENCORE,
- b43_phy_read(dev, B43_PHY_ENCORE) | 0x0010);
+ b43_phy_set(dev, B43_PHY_ENCORE, 0x0010);
else
- b43_phy_write(dev, B43_PHY_ENCORE,
- b43_phy_read(dev, B43_PHY_ENCORE) & ~0x1010);
+ b43_phy_mask(dev, B43_PHY_ENCORE, ~0x1010);
}
b43_wa_all(dev);
if (phy->type == B43_PHYTYPE_A) {
if (phy->gmode && (phy->rev < 3))
- b43_phy_write(dev, 0x0034,
- b43_phy_read(dev, 0x0034) | 0x0001);
+ b43_phy_set(dev, 0x0034, 0x0001);
b43_phy_rssiagc(dev, 0);
- b43_phy_write(dev, B43_PHY_CRS0,
- b43_phy_read(dev, B43_PHY_CRS0) | B43_PHY_CRS0_EN);
+ b43_phy_set(dev, B43_PHY_CRS0, B43_PHY_CRS0_EN);
b43_radio_init2060(dev);
@@ -339,9 +310,7 @@ void b43_phy_inita(struct b43_wldev *dev)
if ((phy->type == B43_PHYTYPE_G) &&
(dev->dev->bus->sprom.boardflags_lo & B43_BFL_PACTRL)) {
- b43_phy_write(dev, B43_PHY_OFDM(0x6E),
- (b43_phy_read(dev, B43_PHY_OFDM(0x6E))
- & 0xE000) | 0x3CF);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0x6E), 0xE000, 0x3CF);
}
}
@@ -520,14 +489,14 @@ static void b43_aphy_op_software_rfkill(struct b43_wldev *dev,
return;
b43_radio_write16(dev, 0x0004, 0x00C0);
b43_radio_write16(dev, 0x0005, 0x0008);
- b43_phy_write(dev, 0x0010, b43_phy_read(dev, 0x0010) & 0xFFF7);
- b43_phy_write(dev, 0x0011, b43_phy_read(dev, 0x0011) & 0xFFF7);
+ b43_phy_mask(dev, 0x0010, 0xFFF7);
+ b43_phy_mask(dev, 0x0011, 0xFFF7);
b43_radio_init2060(dev);
} else {
b43_radio_write16(dev, 0x0004, 0x00FF);
b43_radio_write16(dev, 0x0005, 0x00FB);
- b43_phy_write(dev, 0x0010, b43_phy_read(dev, 0x0010) | 0x0008);
- b43_phy_write(dev, 0x0011, b43_phy_read(dev, 0x0011) | 0x0008);
+ b43_phy_set(dev, 0x0010, 0x0008);
+ b43_phy_set(dev, 0x0011, 0x0008);
}
}
diff --git a/drivers/net/wireless/b43/phy_g.c b/drivers/net/wireless/b43/phy_g.c
index caac4a45f0bf..e7b98f013b0f 100644
--- a/drivers/net/wireless/b43/phy_g.c
+++ b/drivers/net/wireless/b43/phy_g.c
@@ -204,13 +204,9 @@ void b43_gphy_set_baseband_attenuation(struct b43_wldev *dev,
& 0xFFF0) |
baseband_attenuation);
} else if (phy->analog > 1) {
- b43_phy_write(dev, B43_PHY_DACCTL,
- (b43_phy_read(dev, B43_PHY_DACCTL)
- & 0xFFC3) | (baseband_attenuation << 2));
+ b43_phy_maskset(dev, B43_PHY_DACCTL, 0xFFC3, (baseband_attenuation << 2));
} else {
- b43_phy_write(dev, B43_PHY_DACCTL,
- (b43_phy_read(dev, B43_PHY_DACCTL)
- & 0xFF87) | (baseband_attenuation << 3));
+ b43_phy_maskset(dev, B43_PHY_DACCTL, 0xFF87, (baseband_attenuation << 3));
}
}
@@ -252,17 +248,13 @@ static void b43_set_txpower_g(struct b43_wldev *dev,
b43_radio_write16(dev, 0x43,
(rf & 0x000F) | (tx_control & 0x0070));
} else {
- b43_radio_write16(dev, 0x43, (b43_radio_read16(dev, 0x43)
- & 0xFFF0) | (rf & 0x000F));
- b43_radio_write16(dev, 0x52, (b43_radio_read16(dev, 0x52)
- & ~0x0070) | (tx_control &
- 0x0070));
+ b43_radio_maskset(dev, 0x43, 0xFFF0, (rf & 0x000F));
+ b43_radio_maskset(dev, 0x52, ~0x0070, (tx_control & 0x0070));
}
if (has_tx_magnification(phy)) {
b43_radio_write16(dev, 0x52, tx_magn | tx_bias);
} else {
- b43_radio_write16(dev, 0x52, (b43_radio_read16(dev, 0x52)
- & 0xFFF0) | (tx_bias & 0x000F));
+ b43_radio_maskset(dev, 0x52, 0xFFF0, (tx_bias & 0x000F));
}
b43_lo_g_adjust(dev);
}
@@ -337,12 +329,9 @@ static void b43_set_all_gains(struct b43_wldev *dev,
if (third != -1) {
tmp = ((u16) third << 14) | ((u16) third << 6);
- b43_phy_write(dev, 0x04A0,
- (b43_phy_read(dev, 0x04A0) & 0xBFBF) | tmp);
- b43_phy_write(dev, 0x04A1,
- (b43_phy_read(dev, 0x04A1) & 0xBFBF) | tmp);
- b43_phy_write(dev, 0x04A2,
- (b43_phy_read(dev, 0x04A2) & 0xBFBF) | tmp);
+ b43_phy_maskset(dev, 0x04A0, 0xBFBF, tmp);
+ b43_phy_maskset(dev, 0x04A1, 0xBFBF, tmp);
+ b43_phy_maskset(dev, 0x04A2, 0xBFBF, tmp);
}
b43_dummy_transmission(dev);
}
@@ -373,12 +362,9 @@ static void b43_set_original_gains(struct b43_wldev *dev)
for (i = start; i < end; i++)
b43_ofdmtab_write16(dev, table, i, i - start);
- b43_phy_write(dev, 0x04A0,
- (b43_phy_read(dev, 0x04A0) & 0xBFBF) | 0x4040);
- b43_phy_write(dev, 0x04A1,
- (b43_phy_read(dev, 0x04A1) & 0xBFBF) | 0x4040);
- b43_phy_write(dev, 0x04A2,
- (b43_phy_read(dev, 0x04A2) & 0xBFBF) | 0x4000);
+ b43_phy_maskset(dev, 0x04A0, 0xBFBF, 0x4040);
+ b43_phy_maskset(dev, 0x04A1, 0xBFBF, 0x4040);
+ b43_phy_maskset(dev, 0x04A2, 0xBFBF, 0x4000);
b43_dummy_transmission(dev);
}
@@ -454,13 +440,11 @@ static void b43_calc_nrssi_offset(struct b43_wldev *dev)
backup[10] = b43_radio_read16(dev, 0x007A);
backup[11] = b43_radio_read16(dev, 0x0043);
- b43_phy_write(dev, 0x0429, b43_phy_read(dev, 0x0429) & 0x7FFF);
- b43_phy_write(dev, 0x0001,
- (b43_phy_read(dev, 0x0001) & 0x3FFF) | 0x4000);
- b43_phy_write(dev, 0x0811, b43_phy_read(dev, 0x0811) | 0x000C);
- b43_phy_write(dev, 0x0812,
- (b43_phy_read(dev, 0x0812) & 0xFFF3) | 0x0004);
- b43_phy_write(dev, 0x0802, b43_phy_read(dev, 0x0802) & ~(0x1 | 0x2));
+ b43_phy_mask(dev, 0x0429, 0x7FFF);
+ b43_phy_maskset(dev, 0x0001, 0x3FFF, 0x4000);
+ b43_phy_set(dev, 0x0811, 0x000C);
+ b43_phy_maskset(dev, 0x0812, 0xFFF3, 0x0004);
+ b43_phy_mask(dev, 0x0802, ~(0x1 | 0x2));
if (phy->rev >= 6) {
backup[12] = b43_phy_read(dev, 0x002E);
backup[13] = b43_phy_read(dev, 0x002F);
@@ -475,13 +459,13 @@ static void b43_calc_nrssi_offset(struct b43_wldev *dev)
b43_phy_write(dev, 0x002F, 0);
b43_phy_write(dev, 0x080F, 0);
b43_phy_write(dev, 0x0810, 0);
- b43_phy_write(dev, 0x0478, b43_phy_read(dev, 0x0478) | 0x0100);
- b43_phy_write(dev, 0x0801, b43_phy_read(dev, 0x0801) | 0x0040);
- b43_phy_write(dev, 0x0060, b43_phy_read(dev, 0x0060) | 0x0040);
- b43_phy_write(dev, 0x0014, b43_phy_read(dev, 0x0014) | 0x0200);
+ b43_phy_set(dev, 0x0478, 0x0100);
+ b43_phy_set(dev, 0x0801, 0x0040);
+ b43_phy_set(dev, 0x0060, 0x0040);
+ b43_phy_set(dev, 0x0014, 0x0200);
}
- b43_radio_write16(dev, 0x007A, b43_radio_read16(dev, 0x007A) | 0x0070);
- b43_radio_write16(dev, 0x007A, b43_radio_read16(dev, 0x007A) | 0x0080);
+ b43_radio_set(dev, 0x007A, 0x0070);
+ b43_radio_set(dev, 0x007A, 0x0080);
udelay(30);
v47F = (s16) ((b43_phy_read(dev, 0x047F) >> 8) & 0x003F);
@@ -501,40 +485,31 @@ static void b43_calc_nrssi_offset(struct b43_wldev *dev)
if (saved == 0xFFFF)
saved = 4;
} else {
- b43_radio_write16(dev, 0x007A,
- b43_radio_read16(dev, 0x007A) & 0x007F);
+ b43_radio_mask(dev, 0x007A, 0x007F);
if (phy->rev != 1) { /* Not in specs, but needed to prevent PPC machine check */
- b43_phy_write(dev, 0x0814,
- b43_phy_read(dev, 0x0814) | 0x0001);
- b43_phy_write(dev, 0x0815,
- b43_phy_read(dev, 0x0815) & 0xFFFE);
+ b43_phy_set(dev, 0x0814, 0x0001);
+ b43_phy_mask(dev, 0x0815, 0xFFFE);
}
- b43_phy_write(dev, 0x0811, b43_phy_read(dev, 0x0811) | 0x000C);
- b43_phy_write(dev, 0x0812, b43_phy_read(dev, 0x0812) | 0x000C);
- b43_phy_write(dev, 0x0811, b43_phy_read(dev, 0x0811) | 0x0030);
- b43_phy_write(dev, 0x0812, b43_phy_read(dev, 0x0812) | 0x0030);
+ b43_phy_set(dev, 0x0811, 0x000C);
+ b43_phy_set(dev, 0x0812, 0x000C);
+ b43_phy_set(dev, 0x0811, 0x0030);
+ b43_phy_set(dev, 0x0812, 0x0030);
b43_phy_write(dev, 0x005A, 0x0480);
b43_phy_write(dev, 0x0059, 0x0810);
b43_phy_write(dev, 0x0058, 0x000D);
if (phy->rev == 0) {
b43_phy_write(dev, 0x0003, 0x0122);
} else {
- b43_phy_write(dev, 0x000A, b43_phy_read(dev, 0x000A)
- | 0x2000);
+ b43_phy_set(dev, 0x000A, 0x2000);
}
if (phy->rev != 1) { /* Not in specs, but needed to prevent PPC machine check */
- b43_phy_write(dev, 0x0814,
- b43_phy_read(dev, 0x0814) | 0x0004);
- b43_phy_write(dev, 0x0815,
- b43_phy_read(dev, 0x0815) & 0xFFFB);
+ b43_phy_set(dev, 0x0814, 0x0004);
+ b43_phy_mask(dev, 0x0815, 0xFFFB);
}
- b43_phy_write(dev, 0x0003, (b43_phy_read(dev, 0x0003) & 0xFF9F)
- | 0x0040);
- b43_radio_write16(dev, 0x007A,
- b43_radio_read16(dev, 0x007A) | 0x000F);
+ b43_phy_maskset(dev, 0x0003, 0xFF9F, 0x0040);
+ b43_radio_set(dev, 0x007A, 0x000F);
b43_set_all_gains(dev, 3, 0, 1);
- b43_radio_write16(dev, 0x0043, (b43_radio_read16(dev, 0x0043)
- & 0x00F0) | 0x000F);
+ b43_radio_maskset(dev, 0x0043, 0x00F0, 0x000F);
udelay(30);
v47F = (s16) ((b43_phy_read(dev, 0x047F) >> 8) & 0x003F);
if (v47F >= 0x20)
@@ -576,7 +551,7 @@ static void b43_calc_nrssi_offset(struct b43_wldev *dev)
b43_radio_write16(dev, 0x0043, backup[11]);
b43_radio_write16(dev, 0x007A, backup[10]);
b43_phy_write(dev, 0x0802, b43_phy_read(dev, 0x0802) | 0x1 | 0x2);
- b43_phy_write(dev, 0x0429, b43_phy_read(dev, 0x0429) | 0x8000);
+ b43_phy_set(dev, 0x0429, 0x8000);
b43_set_original_gains(dev);
if (phy->rev >= 6) {
b43_phy_write(dev, 0x0801, backup[16]);
@@ -604,9 +579,8 @@ static void b43_calc_nrssi_slope(struct b43_wldev *dev)
if (phy->radio_rev == 8)
b43_calc_nrssi_offset(dev);
- b43_phy_write(dev, B43_PHY_G_CRS,
- b43_phy_read(dev, B43_PHY_G_CRS) & 0x7FFF);
- b43_phy_write(dev, 0x0802, b43_phy_read(dev, 0x0802) & 0xFFFC);
+ b43_phy_mask(dev, B43_PHY_G_CRS, 0x7FFF);
+ b43_phy_mask(dev, 0x0802, 0xFFFC);
backup[7] = b43_read16(dev, 0x03E2);
b43_write16(dev, 0x03E2, b43_read16(dev, 0x03E2) | 0x8000);
backup[0] = b43_radio_read16(dev, 0x007A);
@@ -633,66 +607,44 @@ static void b43_calc_nrssi_slope(struct b43_wldev *dev)
case 4:
case 6:
case 7:
- b43_phy_write(dev, 0x0478,
- b43_phy_read(dev, 0x0478)
- | 0x0100);
- b43_phy_write(dev, 0x0801,
- b43_phy_read(dev, 0x0801)
- | 0x0040);
+ b43_phy_set(dev, 0x0478, 0x0100);
+ b43_phy_set(dev, 0x0801, 0x0040);
break;
case 3:
case 5:
- b43_phy_write(dev, 0x0801,
- b43_phy_read(dev, 0x0801)
- & 0xFFBF);
+ b43_phy_mask(dev, 0x0801, 0xFFBF);
break;
}
- b43_phy_write(dev, 0x0060, b43_phy_read(dev, 0x0060)
- | 0x0040);
- b43_phy_write(dev, 0x0014, b43_phy_read(dev, 0x0014)
- | 0x0200);
+ b43_phy_set(dev, 0x0060, 0x0040);
+ b43_phy_set(dev, 0x0014, 0x0200);
}
- b43_radio_write16(dev, 0x007A,
- b43_radio_read16(dev, 0x007A) | 0x0070);
+ b43_radio_set(dev, 0x007A, 0x0070);
b43_set_all_gains(dev, 0, 8, 0);
- b43_radio_write16(dev, 0x007A,
- b43_radio_read16(dev, 0x007A) & 0x00F7);
+ b43_radio_mask(dev, 0x007A, 0x00F7);
if (phy->rev >= 2) {
- b43_phy_write(dev, 0x0811,
- (b43_phy_read(dev, 0x0811) & 0xFFCF) |
- 0x0030);
- b43_phy_write(dev, 0x0812,
- (b43_phy_read(dev, 0x0812) & 0xFFCF) |
- 0x0010);
+ b43_phy_maskset(dev, 0x0811, 0xFFCF, 0x0030);
+ b43_phy_maskset(dev, 0x0812, 0xFFCF, 0x0010);
}
- b43_radio_write16(dev, 0x007A,
- b43_radio_read16(dev, 0x007A) | 0x0080);
+ b43_radio_set(dev, 0x007A, 0x0080);
udelay(20);
nrssi0 = (s16) ((b43_phy_read(dev, 0x047F) >> 8) & 0x003F);
if (nrssi0 >= 0x0020)
nrssi0 -= 0x0040;
- b43_radio_write16(dev, 0x007A,
- b43_radio_read16(dev, 0x007A) & 0x007F);
+ b43_radio_mask(dev, 0x007A, 0x007F);
if (phy->rev >= 2) {
- b43_phy_write(dev, 0x0003, (b43_phy_read(dev, 0x0003)
- & 0xFF9F) | 0x0040);
+ b43_phy_maskset(dev, 0x0003, 0xFF9F, 0x0040);
}
b43_write16(dev, B43_MMIO_CHANNEL_EXT,
b43_read16(dev, B43_MMIO_CHANNEL_EXT)
| 0x2000);
- b43_radio_write16(dev, 0x007A,
- b43_radio_read16(dev, 0x007A) | 0x000F);
+ b43_radio_set(dev, 0x007A, 0x000F);
b43_phy_write(dev, 0x0015, 0xF330);
if (phy->rev >= 2) {
- b43_phy_write(dev, 0x0812,
- (b43_phy_read(dev, 0x0812) & 0xFFCF) |
- 0x0020);
- b43_phy_write(dev, 0x0811,
- (b43_phy_read(dev, 0x0811) & 0xFFCF) |
- 0x0020);
+ b43_phy_maskset(dev, 0x0812, 0xFFCF, 0x0020);
+ b43_phy_maskset(dev, 0x0811, 0xFFCF, 0x0020);
}
b43_set_all_gains(dev, 3, 0, 1);
@@ -726,10 +678,8 @@ static void b43_calc_nrssi_slope(struct b43_wldev *dev)
b43_phy_write(dev, B43_PHY_G_LO_CONTROL, backup[13]);
}
if (phy->rev >= 2) {
- b43_phy_write(dev, 0x0812,
- b43_phy_read(dev, 0x0812) & 0xFFCF);
- b43_phy_write(dev, 0x0811,
- b43_phy_read(dev, 0x0811) & 0xFFCF);
+ b43_phy_mask(dev, 0x0812, 0xFFCF);
+ b43_phy_mask(dev, 0x0811, 0xFFCF);
}
b43_radio_write16(dev, 0x007A, backup[0]);
@@ -743,11 +693,9 @@ static void b43_calc_nrssi_slope(struct b43_wldev *dev)
b43_phy_write(dev, 0x0059, backup[5]);
b43_phy_write(dev, 0x0058, backup[6]);
b43_synth_pu_workaround(dev, phy->channel);
- b43_phy_write(dev, 0x0802,
- b43_phy_read(dev, 0x0802) | (0x0001 | 0x0002));
+ b43_phy_set(dev, 0x0802, (0x0001 | 0x0002));
b43_set_original_gains(dev);
- b43_phy_write(dev, B43_PHY_G_CRS,
- b43_phy_read(dev, B43_PHY_G_CRS) | 0x8000);
+ b43_phy_set(dev, B43_PHY_G_CRS, 0x8000);
if (phy->rev >= 3) {
b43_phy_write(dev, 0x0801, backup[14]);
b43_phy_write(dev, 0x0060, backup[15]);
@@ -774,13 +722,9 @@ static void b43_calc_nrssi_threshold(struct b43_wldev *dev)
if (tmp16 >= 0x20)
tmp16 -= 0x40;
if (tmp16 < 3) {
- b43_phy_write(dev, 0x048A,
- (b43_phy_read(dev, 0x048A)
- & 0xF000) | 0x09EB);
+ b43_phy_maskset(dev, 0x048A, 0xF000, 0x09EB);
} else {
- b43_phy_write(dev, 0x048A,
- (b43_phy_read(dev, 0x048A)
- & 0xF000) | 0x0AED);
+ b43_phy_maskset(dev, 0x048A, 0xF000, 0x0AED);
}
} else {
if (gphy->interfmode == B43_INTERFMODE_NONWLAN) {
@@ -823,7 +767,7 @@ static void b43_calc_nrssi_threshold(struct b43_wldev *dev)
* interference mitigation code.
* It is save to restore values in random order.
*/
-static void _stack_save(u32 * _stackptr, size_t * stackidx,
+static void _stack_save(u32 *_stackptr, size_t *stackidx,
u8 id, u16 offset, u16 value)
{
u32 *stackptr = &(_stackptr[*stackidx]);
@@ -837,7 +781,7 @@ static void _stack_save(u32 * _stackptr, size_t * stackidx,
B43_WARN_ON(*stackidx >= B43_INTERFSTACK_SIZE);
}
-static u16 _stack_restore(u32 * stackptr, u8 id, u16 offset)
+static u16 _stack_restore(u32 *stackptr, u8 id, u16 offset)
{
size_t i;
@@ -901,11 +845,8 @@ b43_radio_interference_mitigation_enable(struct b43_wldev *dev, int mode)
switch (mode) {
case B43_INTERFMODE_NONWLAN:
if (phy->rev != 1) {
- b43_phy_write(dev, 0x042B,
- b43_phy_read(dev, 0x042B) | 0x0800);
- b43_phy_write(dev, B43_PHY_G_CRS,
- b43_phy_read(dev,
- B43_PHY_G_CRS) & ~0x4000);
+ b43_phy_set(dev, 0x042B, 0x0800);
+ b43_phy_mask(dev, B43_PHY_G_CRS, ~0x4000);
break;
}
radio_stacksave(0x0078);
@@ -924,26 +865,19 @@ b43_radio_interference_mitigation_enable(struct b43_wldev *dev, int mode)
phy_stacksave(0x0406);
b43_phy_write(dev, 0x0406, 0x7E28);
- b43_phy_write(dev, 0x042B, b43_phy_read(dev, 0x042B) | 0x0800);
- b43_phy_write(dev, B43_PHY_RADIO_BITFIELD,
- b43_phy_read(dev,
- B43_PHY_RADIO_BITFIELD) | 0x1000);
+ b43_phy_set(dev, 0x042B, 0x0800);
+ b43_phy_set(dev, B43_PHY_RADIO_BITFIELD, 0x1000);
phy_stacksave(0x04A0);
- b43_phy_write(dev, 0x04A0,
- (b43_phy_read(dev, 0x04A0) & 0xC0C0) | 0x0008);
+ b43_phy_maskset(dev, 0x04A0, 0xC0C0, 0x0008);
phy_stacksave(0x04A1);
- b43_phy_write(dev, 0x04A1,
- (b43_phy_read(dev, 0x04A1) & 0xC0C0) | 0x0605);
+ b43_phy_maskset(dev, 0x04A1, 0xC0C0, 0x0605);
phy_stacksave(0x04A2);
- b43_phy_write(dev, 0x04A2,
- (b43_phy_read(dev, 0x04A2) & 0xC0C0) | 0x0204);
+ b43_phy_maskset(dev, 0x04A2, 0xC0C0, 0x0204);
phy_stacksave(0x04A8);
- b43_phy_write(dev, 0x04A8,
- (b43_phy_read(dev, 0x04A8) & 0xC0C0) | 0x0803);
+ b43_phy_maskset(dev, 0x04A8, 0xC0C0, 0x0803);
phy_stacksave(0x04AB);
- b43_phy_write(dev, 0x04AB,
- (b43_phy_read(dev, 0x04AB) & 0xC0C0) | 0x0605);
+ b43_phy_maskset(dev, 0x04AB, 0xC0C0, 0x0605);
phy_stacksave(0x04A7);
b43_phy_write(dev, 0x04A7, 0x0002);
@@ -999,12 +933,8 @@ b43_radio_interference_mitigation_enable(struct b43_wldev *dev, int mode)
phy_stacksave(0x042B);
phy_stacksave(0x048C);
- b43_phy_write(dev, B43_PHY_RADIO_BITFIELD,
- b43_phy_read(dev, B43_PHY_RADIO_BITFIELD)
- & ~0x1000);
- b43_phy_write(dev, B43_PHY_G_CRS,
- (b43_phy_read(dev, B43_PHY_G_CRS)
- & 0xFFFC) | 0x0002);
+ b43_phy_mask(dev, B43_PHY_RADIO_BITFIELD, ~0x1000);
+ b43_phy_maskset(dev, B43_PHY_G_CRS, 0xFFFC, 0x0002);
b43_phy_write(dev, 0x0033, 0x0800);
b43_phy_write(dev, 0x04A3, 0x2027);
@@ -1013,8 +943,7 @@ b43_radio_interference_mitigation_enable(struct b43_wldev *dev, int mode)
b43_phy_write(dev, 0x04AA, 0x1CA8);
b43_phy_write(dev, 0x04AC, 0x287A);
- b43_phy_write(dev, 0x04A0, (b43_phy_read(dev, 0x04A0)
- & 0xFFC0) | 0x001A);
+ b43_phy_maskset(dev, 0x04A0, 0xFFC0, 0x001A);
b43_phy_write(dev, 0x04A7, 0x000D);
if (phy->rev < 2) {
@@ -1027,65 +956,41 @@ b43_radio_interference_mitigation_enable(struct b43_wldev *dev, int mode)
b43_phy_write(dev, 0x04C1, 0x0059);
}
- b43_phy_write(dev, 0x04A1, (b43_phy_read(dev, 0x04A1)
- & 0xC0FF) | 0x1800);
- b43_phy_write(dev, 0x04A1, (b43_phy_read(dev, 0x04A1)
- & 0xFFC0) | 0x0015);
- b43_phy_write(dev, 0x04A8, (b43_phy_read(dev, 0x04A8)
- & 0xCFFF) | 0x1000);
- b43_phy_write(dev, 0x04A8, (b43_phy_read(dev, 0x04A8)
- & 0xF0FF) | 0x0A00);
- b43_phy_write(dev, 0x04AB, (b43_phy_read(dev, 0x04AB)
- & 0xCFFF) | 0x1000);
- b43_phy_write(dev, 0x04AB, (b43_phy_read(dev, 0x04AB)
- & 0xF0FF) | 0x0800);
- b43_phy_write(dev, 0x04AB, (b43_phy_read(dev, 0x04AB)
- & 0xFFCF) | 0x0010);
- b43_phy_write(dev, 0x04AB, (b43_phy_read(dev, 0x04AB)
- & 0xFFF0) | 0x0005);
- b43_phy_write(dev, 0x04A8, (b43_phy_read(dev, 0x04A8)
- & 0xFFCF) | 0x0010);
- b43_phy_write(dev, 0x04A8, (b43_phy_read(dev, 0x04A8)
- & 0xFFF0) | 0x0006);
- b43_phy_write(dev, 0x04A2, (b43_phy_read(dev, 0x04A2)
- & 0xF0FF) | 0x0800);
- b43_phy_write(dev, 0x04A0, (b43_phy_read(dev, 0x04A0)
- & 0xF0FF) | 0x0500);
- b43_phy_write(dev, 0x04A2, (b43_phy_read(dev, 0x04A2)
- & 0xFFF0) | 0x000B);
+ b43_phy_maskset(dev, 0x04A1, 0xC0FF, 0x1800);
+ b43_phy_maskset(dev, 0x04A1, 0xFFC0, 0x0015);
+ b43_phy_maskset(dev, 0x04A8, 0xCFFF, 0x1000);
+ b43_phy_maskset(dev, 0x04A8, 0xF0FF, 0x0A00);
+ b43_phy_maskset(dev, 0x04AB, 0xCFFF, 0x1000);
+ b43_phy_maskset(dev, 0x04AB, 0xF0FF, 0x0800);
+ b43_phy_maskset(dev, 0x04AB, 0xFFCF, 0x0010);
+ b43_phy_maskset(dev, 0x04AB, 0xFFF0, 0x0005);
+ b43_phy_maskset(dev, 0x04A8, 0xFFCF, 0x0010);
+ b43_phy_maskset(dev, 0x04A8, 0xFFF0, 0x0006);
+ b43_phy_maskset(dev, 0x04A2, 0xF0FF, 0x0800);
+ b43_phy_maskset(dev, 0x04A0, 0xF0FF, 0x0500);
+ b43_phy_maskset(dev, 0x04A2, 0xFFF0, 0x000B);
if (phy->rev >= 3) {
- b43_phy_write(dev, 0x048A, b43_phy_read(dev, 0x048A)
- & ~0x8000);
- b43_phy_write(dev, 0x0415, (b43_phy_read(dev, 0x0415)
- & 0x8000) | 0x36D8);
- b43_phy_write(dev, 0x0416, (b43_phy_read(dev, 0x0416)
- & 0x8000) | 0x36D8);
- b43_phy_write(dev, 0x0417, (b43_phy_read(dev, 0x0417)
- & 0xFE00) | 0x016D);
+ b43_phy_mask(dev, 0x048A, (u16)~0x8000);
+ b43_phy_maskset(dev, 0x0415, 0x8000, 0x36D8);
+ b43_phy_maskset(dev, 0x0416, 0x8000, 0x36D8);
+ b43_phy_maskset(dev, 0x0417, 0xFE00, 0x016D);
} else {
- b43_phy_write(dev, 0x048A, b43_phy_read(dev, 0x048A)
- | 0x1000);
- b43_phy_write(dev, 0x048A, (b43_phy_read(dev, 0x048A)
- & 0x9FFF) | 0x2000);
+ b43_phy_set(dev, 0x048A, 0x1000);
+ b43_phy_maskset(dev, 0x048A, 0x9FFF, 0x2000);
b43_hf_write(dev, b43_hf_read(dev) | B43_HF_ACIW);
}
if (phy->rev >= 2) {
- b43_phy_write(dev, 0x042B, b43_phy_read(dev, 0x042B)
- | 0x0800);
+ b43_phy_set(dev, 0x042B, 0x0800);
}
- b43_phy_write(dev, 0x048C, (b43_phy_read(dev, 0x048C)
- & 0xF0FF) | 0x0200);
+ b43_phy_maskset(dev, 0x048C, 0xF0FF, 0x0200);
if (phy->rev == 2) {
- b43_phy_write(dev, 0x04AE, (b43_phy_read(dev, 0x04AE)
- & 0xFF00) | 0x007F);
- b43_phy_write(dev, 0x04AD, (b43_phy_read(dev, 0x04AD)
- & 0x00FF) | 0x1300);
+ b43_phy_maskset(dev, 0x04AE, 0xFF00, 0x007F);
+ b43_phy_maskset(dev, 0x04AD, 0x00FF, 0x1300);
} else if (phy->rev >= 6) {
b43_ofdmtab_write16(dev, 0x1A00, 0x3, 0x007F);
b43_ofdmtab_write16(dev, 0x1A00, 0x2, 0x007F);
- b43_phy_write(dev, 0x04AD, b43_phy_read(dev, 0x04AD)
- & 0x00FF);
+ b43_phy_mask(dev, 0x04AD, 0x00FF);
}
b43_calc_nrssi_slope(dev);
break;
@@ -1104,24 +1009,18 @@ b43_radio_interference_mitigation_disable(struct b43_wldev *dev, int mode)
switch (mode) {
case B43_INTERFMODE_NONWLAN:
if (phy->rev != 1) {
- b43_phy_write(dev, 0x042B,
- b43_phy_read(dev, 0x042B) & ~0x0800);
- b43_phy_write(dev, B43_PHY_G_CRS,
- b43_phy_read(dev,
- B43_PHY_G_CRS) | 0x4000);
+ b43_phy_mask(dev, 0x042B, ~0x0800);
+ b43_phy_set(dev, B43_PHY_G_CRS, 0x4000);
break;
}
radio_stackrestore(0x0078);
b43_calc_nrssi_threshold(dev);
phy_stackrestore(0x0406);
- b43_phy_write(dev, 0x042B, b43_phy_read(dev, 0x042B) & ~0x0800);
+ b43_phy_mask(dev, 0x042B, ~0x0800);
if (!dev->bad_frames_preempt) {
- b43_phy_write(dev, B43_PHY_RADIO_BITFIELD,
- b43_phy_read(dev, B43_PHY_RADIO_BITFIELD)
- & ~(1 << 11));
+ b43_phy_mask(dev, B43_PHY_RADIO_BITFIELD, ~(1 << 11));
}
- b43_phy_write(dev, B43_PHY_G_CRS,
- b43_phy_read(dev, B43_PHY_G_CRS) | 0x4000);
+ b43_phy_set(dev, B43_PHY_G_CRS, 0x4000);
phy_stackrestore(0x04A0);
phy_stackrestore(0x04A1);
phy_stackrestore(0x04A2);
@@ -1389,17 +1288,10 @@ static u16 b43_radio_init2050(struct b43_wldev *dev)
sav.phy_crs0 = b43_phy_read(dev, B43_PHY_CRS0);
sav.phy_classctl = b43_phy_read(dev, B43_PHY_CLASSCTL);
- b43_phy_write(dev, B43_PHY_ANALOGOVER,
- b43_phy_read(dev, B43_PHY_ANALOGOVER)
- | 0x0003);
- b43_phy_write(dev, B43_PHY_ANALOGOVERVAL,
- b43_phy_read(dev, B43_PHY_ANALOGOVERVAL)
- & 0xFFFC);
- b43_phy_write(dev, B43_PHY_CRS0, b43_phy_read(dev, B43_PHY_CRS0)
- & 0x7FFF);
- b43_phy_write(dev, B43_PHY_CLASSCTL,
- b43_phy_read(dev, B43_PHY_CLASSCTL)
- & 0xFFFC);
+ b43_phy_set(dev, B43_PHY_ANALOGOVER, 0x0003);
+ b43_phy_mask(dev, B43_PHY_ANALOGOVERVAL, 0xFFFC);
+ b43_phy_mask(dev, B43_PHY_CRS0, 0x7FFF);
+ b43_phy_mask(dev, B43_PHY_CLASSCTL, 0xFFFC);
if (has_loopback_gain(phy)) {
sav.phy_lo_mask = b43_phy_read(dev, B43_PHY_LO_MASK);
sav.phy_lo_ctl = b43_phy_read(dev, B43_PHY_LO_CTL);
@@ -1420,8 +1312,7 @@ static u16 b43_radio_init2050(struct b43_wldev *dev)
b43_write16(dev, 0x3E2, b43_read16(dev, 0x3E2) | 0x8000);
sav.phy_syncctl = b43_phy_read(dev, B43_PHY_SYNCCTL);
- b43_phy_write(dev, B43_PHY_SYNCCTL, b43_phy_read(dev, B43_PHY_SYNCCTL)
- & 0xFF7F);
+ b43_phy_mask(dev, B43_PHY_SYNCCTL, 0xFF7F);
sav.reg_3E6 = b43_read16(dev, 0x3E6);
sav.reg_3F4 = b43_read16(dev, 0x3F4);
@@ -1429,9 +1320,7 @@ static u16 b43_radio_init2050(struct b43_wldev *dev)
b43_write16(dev, 0x03E6, 0x0122);
} else {
if (phy->analog >= 2) {
- b43_phy_write(dev, B43_PHY_CCK(0x03),
- (b43_phy_read(dev, B43_PHY_CCK(0x03))
- & 0xFFBF) | 0x40);
+ b43_phy_maskset(dev, B43_PHY_CCK(0x03), 0xFFBF, 0x40);
}
b43_write16(dev, B43_MMIO_CHANNEL_EXT,
(b43_read16(dev, B43_MMIO_CHANNEL_EXT) | 0x2000));
@@ -1454,14 +1343,12 @@ static u16 b43_radio_init2050(struct b43_wldev *dev)
LPD(0, 0, 1)));
}
b43_phy_write(dev, B43_PHY_PGACTL, 0xBFA0);
- b43_radio_write16(dev, 0x51, b43_radio_read16(dev, 0x51)
- | 0x0004);
+ b43_radio_set(dev, 0x51, 0x0004);
if (phy->radio_rev == 8) {
b43_radio_write16(dev, 0x43, 0x1F);
} else {
b43_radio_write16(dev, 0x52, 0);
- b43_radio_write16(dev, 0x43, (b43_radio_read16(dev, 0x43)
- & 0xFFF0) | 0x0009);
+ b43_radio_maskset(dev, 0x43, 0xFFF0, 0x0009);
}
b43_phy_write(dev, B43_PHY_CCK(0x58), 0);
@@ -1610,8 +1497,7 @@ static void b43_phy_initb5(struct b43_wldev *dev)
u8 old_channel;
if (phy->analog == 1) {
- b43_radio_write16(dev, 0x007A, b43_radio_read16(dev, 0x007A)
- | 0x0050);
+ b43_radio_set(dev, 0x007A, 0x0050);
}
if ((bus->boardinfo.vendor != SSB_BOARDVENDOR_BCM) &&
(bus->boardinfo.type != SSB_BOARD_BU4306)) {
@@ -1621,39 +1507,29 @@ static void b43_phy_initb5(struct b43_wldev *dev)
value += 0x202;
}
}
- b43_phy_write(dev, 0x0035, (b43_phy_read(dev, 0x0035) & 0xF0FF)
- | 0x0700);
+ b43_phy_maskset(dev, 0x0035, 0xF0FF, 0x0700);
if (phy->radio_ver == 0x2050)
b43_phy_write(dev, 0x0038, 0x0667);
if (phy->gmode || phy->rev >= 2) {
if (phy->radio_ver == 0x2050) {
- b43_radio_write16(dev, 0x007A,
- b43_radio_read16(dev, 0x007A)
- | 0x0020);
- b43_radio_write16(dev, 0x0051,
- b43_radio_read16(dev, 0x0051)
- | 0x0004);
+ b43_radio_set(dev, 0x007A, 0x0020);
+ b43_radio_set(dev, 0x0051, 0x0004);
}
b43_write16(dev, B43_MMIO_PHY_RADIO, 0x0000);
- b43_phy_write(dev, 0x0802, b43_phy_read(dev, 0x0802) | 0x0100);
- b43_phy_write(dev, 0x042B, b43_phy_read(dev, 0x042B) | 0x2000);
+ b43_phy_set(dev, 0x0802, 0x0100);
+ b43_phy_set(dev, 0x042B, 0x2000);
b43_phy_write(dev, 0x001C, 0x186A);
- b43_phy_write(dev, 0x0013,
- (b43_phy_read(dev, 0x0013) & 0x00FF) | 0x1900);
- b43_phy_write(dev, 0x0035,
- (b43_phy_read(dev, 0x0035) & 0xFFC0) | 0x0064);
- b43_phy_write(dev, 0x005D,
- (b43_phy_read(dev, 0x005D) & 0xFF80) | 0x000A);
+ b43_phy_maskset(dev, 0x0013, 0x00FF, 0x1900);
+ b43_phy_maskset(dev, 0x0035, 0xFFC0, 0x0064);
+ b43_phy_maskset(dev, 0x005D, 0xFF80, 0x000A);
}
if (dev->bad_frames_preempt) {
- b43_phy_write(dev, B43_PHY_RADIO_BITFIELD,
- b43_phy_read(dev,
- B43_PHY_RADIO_BITFIELD) | (1 << 11));
+ b43_phy_set(dev, B43_PHY_RADIO_BITFIELD, (1 << 11));
}
if (phy->analog == 1) {
@@ -1695,7 +1571,7 @@ static void b43_phy_initb5(struct b43_wldev *dev)
b43_radio_write16(dev, 0x005B, 0x007B);
b43_radio_write16(dev, 0x005C, 0x00B0);
- b43_radio_write16(dev, 0x007A, b43_radio_read16(dev, 0x007A) | 0x0007);
+ b43_radio_set(dev, 0x007A, 0x0007);
b43_gphy_channel_switch(dev, old_channel, 0);
@@ -1771,12 +1647,10 @@ static void b43_phy_initb6(struct b43_wldev *dev)
val += 0x0202;
}
if (phy->type == B43_PHYTYPE_G) {
- b43_radio_write16(dev, 0x007A,
- b43_radio_read16(dev, 0x007A) | 0x0020);
- b43_radio_write16(dev, 0x0051,
- b43_radio_read16(dev, 0x0051) | 0x0004);
- b43_phy_write(dev, 0x0802, b43_phy_read(dev, 0x0802) | 0x0100);
- b43_phy_write(dev, 0x042B, b43_phy_read(dev, 0x042B) | 0x2000);
+ b43_radio_set(dev, 0x007A, 0x0020);
+ b43_radio_set(dev, 0x0051, 0x0004);
+ b43_phy_set(dev, 0x0802, 0x0100);
+ b43_phy_set(dev, 0x042B, 0x2000);
b43_phy_write(dev, 0x5B, 0);
b43_phy_write(dev, 0x5C, 0);
}
@@ -1801,8 +1675,7 @@ static void b43_phy_initb6(struct b43_wldev *dev)
b43_radio_write16(dev, 0x5B, 0x7B);
b43_radio_write16(dev, 0x5C, 0xB0);
}
- b43_radio_write16(dev, 0x007A,
- (b43_radio_read16(dev, 0x007A) & 0x00F8) | 0x0007);
+ b43_radio_maskset(dev, 0x007A, 0x00F8, 0x0007);
b43_gphy_channel_switch(dev, old_channel, 0);
@@ -1814,19 +1687,16 @@ static void b43_phy_initb6(struct b43_wldev *dev)
b43_phy_write(dev, 0x0038, 0x0668);
b43_set_txpower_g(dev, &gphy->bbatt, &gphy->rfatt, gphy->tx_control);
if (phy->radio_rev <= 5) {
- b43_phy_write(dev, 0x5D, (b43_phy_read(dev, 0x5D)
- & 0xFF80) | 0x0003);
+ b43_phy_maskset(dev, 0x5D, 0xFF80, 0x0003);
}
if (phy->radio_rev <= 2)
b43_radio_write16(dev, 0x005D, 0x000D);
if (phy->analog == 4) {
b43_write16(dev, 0x3E4, 9);
- b43_phy_write(dev, 0x61, b43_phy_read(dev, 0x61)
- & 0x0FFF);
+ b43_phy_mask(dev, 0x61, 0x0FFF);
} else {
- b43_phy_write(dev, 0x0002, (b43_phy_read(dev, 0x0002) & 0xFFC0)
- | 0x0004);
+ b43_phy_maskset(dev, 0x0002, 0xFFC0, 0x0004);
}
if (phy->type == B43_PHYTYPE_B)
B43_WARN_ON(1);
@@ -1868,63 +1738,39 @@ static void b43_calc_loopback_gain(struct b43_wldev *dev)
backup_radio[1] = b43_radio_read16(dev, 0x43);
backup_radio[2] = b43_radio_read16(dev, 0x7A);
- b43_phy_write(dev, B43_PHY_CRS0,
- b43_phy_read(dev, B43_PHY_CRS0) & 0x3FFF);
- b43_phy_write(dev, B43_PHY_CCKBBANDCFG,
- b43_phy_read(dev, B43_PHY_CCKBBANDCFG) | 0x8000);
- b43_phy_write(dev, B43_PHY_RFOVER,
- b43_phy_read(dev, B43_PHY_RFOVER) | 0x0002);
- b43_phy_write(dev, B43_PHY_RFOVERVAL,
- b43_phy_read(dev, B43_PHY_RFOVERVAL) & 0xFFFD);
- b43_phy_write(dev, B43_PHY_RFOVER,
- b43_phy_read(dev, B43_PHY_RFOVER) | 0x0001);
- b43_phy_write(dev, B43_PHY_RFOVERVAL,
- b43_phy_read(dev, B43_PHY_RFOVERVAL) & 0xFFFE);
+ b43_phy_mask(dev, B43_PHY_CRS0, 0x3FFF);
+ b43_phy_set(dev, B43_PHY_CCKBBANDCFG, 0x8000);
+ b43_phy_set(dev, B43_PHY_RFOVER, 0x0002);
+ b43_phy_mask(dev, B43_PHY_RFOVERVAL, 0xFFFD);
+ b43_phy_set(dev, B43_PHY_RFOVER, 0x0001);
+ b43_phy_mask(dev, B43_PHY_RFOVERVAL, 0xFFFE);
if (phy->rev != 1) { /* Not in specs, but needed to prevent PPC machine check */
- b43_phy_write(dev, B43_PHY_ANALOGOVER,
- b43_phy_read(dev, B43_PHY_ANALOGOVER) | 0x0001);
- b43_phy_write(dev, B43_PHY_ANALOGOVERVAL,
- b43_phy_read(dev,
- B43_PHY_ANALOGOVERVAL) & 0xFFFE);
- b43_phy_write(dev, B43_PHY_ANALOGOVER,
- b43_phy_read(dev, B43_PHY_ANALOGOVER) | 0x0002);
- b43_phy_write(dev, B43_PHY_ANALOGOVERVAL,
- b43_phy_read(dev,
- B43_PHY_ANALOGOVERVAL) & 0xFFFD);
- }
- b43_phy_write(dev, B43_PHY_RFOVER,
- b43_phy_read(dev, B43_PHY_RFOVER) | 0x000C);
- b43_phy_write(dev, B43_PHY_RFOVERVAL,
- b43_phy_read(dev, B43_PHY_RFOVERVAL) | 0x000C);
- b43_phy_write(dev, B43_PHY_RFOVER,
- b43_phy_read(dev, B43_PHY_RFOVER) | 0x0030);
- b43_phy_write(dev, B43_PHY_RFOVERVAL,
- (b43_phy_read(dev, B43_PHY_RFOVERVAL)
- & 0xFFCF) | 0x10);
+ b43_phy_set(dev, B43_PHY_ANALOGOVER, 0x0001);
+ b43_phy_mask(dev, B43_PHY_ANALOGOVERVAL, 0xFFFE);
+ b43_phy_set(dev, B43_PHY_ANALOGOVER, 0x0002);
+ b43_phy_mask(dev, B43_PHY_ANALOGOVERVAL, 0xFFFD);
+ }
+ b43_phy_set(dev, B43_PHY_RFOVER, 0x000C);
+ b43_phy_set(dev, B43_PHY_RFOVERVAL, 0x000C);
+ b43_phy_set(dev, B43_PHY_RFOVER, 0x0030);
+ b43_phy_maskset(dev, B43_PHY_RFOVERVAL, 0xFFCF, 0x10);
b43_phy_write(dev, B43_PHY_CCK(0x5A), 0x0780);
b43_phy_write(dev, B43_PHY_CCK(0x59), 0xC810);
b43_phy_write(dev, B43_PHY_CCK(0x58), 0x000D);
- b43_phy_write(dev, B43_PHY_CCK(0x0A),
- b43_phy_read(dev, B43_PHY_CCK(0x0A)) | 0x2000);
+ b43_phy_set(dev, B43_PHY_CCK(0x0A), 0x2000);
if (phy->rev != 1) { /* Not in specs, but needed to prevent PPC machine check */
- b43_phy_write(dev, B43_PHY_ANALOGOVER,
- b43_phy_read(dev, B43_PHY_ANALOGOVER) | 0x0004);
- b43_phy_write(dev, B43_PHY_ANALOGOVERVAL,
- b43_phy_read(dev,
- B43_PHY_ANALOGOVERVAL) & 0xFFFB);
+ b43_phy_set(dev, B43_PHY_ANALOGOVER, 0x0004);
+ b43_phy_mask(dev, B43_PHY_ANALOGOVERVAL, 0xFFFB);
}
- b43_phy_write(dev, B43_PHY_CCK(0x03),
- (b43_phy_read(dev, B43_PHY_CCK(0x03))
- & 0xFF9F) | 0x40);
+ b43_phy_maskset(dev, B43_PHY_CCK(0x03), 0xFF9F, 0x40);
if (phy->radio_rev == 8) {
b43_radio_write16(dev, 0x43, 0x000F);
} else {
b43_radio_write16(dev, 0x52, 0);
- b43_radio_write16(dev, 0x43, (b43_radio_read16(dev, 0x43)
- & 0xFFF0) | 0x9);
+ b43_radio_maskset(dev, 0x43, 0xFFF0, 0x9);
}
b43_gphy_set_baseband_attenuation(dev, 11);
@@ -1934,45 +1780,28 @@ static void b43_calc_loopback_gain(struct b43_wldev *dev)
b43_phy_write(dev, B43_PHY_LO_MASK, 0x8020);
b43_phy_write(dev, B43_PHY_LO_CTL, 0);
- b43_phy_write(dev, B43_PHY_CCK(0x2B),
- (b43_phy_read(dev, B43_PHY_CCK(0x2B))
- & 0xFFC0) | 0x01);
- b43_phy_write(dev, B43_PHY_CCK(0x2B),
- (b43_phy_read(dev, B43_PHY_CCK(0x2B))
- & 0xC0FF) | 0x800);
+ b43_phy_maskset(dev, B43_PHY_CCK(0x2B), 0xFFC0, 0x01);
+ b43_phy_maskset(dev, B43_PHY_CCK(0x2B), 0xC0FF, 0x800);
- b43_phy_write(dev, B43_PHY_RFOVER,
- b43_phy_read(dev, B43_PHY_RFOVER) | 0x0100);
- b43_phy_write(dev, B43_PHY_RFOVERVAL,
- b43_phy_read(dev, B43_PHY_RFOVERVAL) & 0xCFFF);
+ b43_phy_set(dev, B43_PHY_RFOVER, 0x0100);
+ b43_phy_mask(dev, B43_PHY_RFOVERVAL, 0xCFFF);
if (dev->dev->bus->sprom.boardflags_lo & B43_BFL_EXTLNA) {
if (phy->rev >= 7) {
- b43_phy_write(dev, B43_PHY_RFOVER,
- b43_phy_read(dev, B43_PHY_RFOVER)
- | 0x0800);
- b43_phy_write(dev, B43_PHY_RFOVERVAL,
- b43_phy_read(dev, B43_PHY_RFOVERVAL)
- | 0x8000);
+ b43_phy_set(dev, B43_PHY_RFOVER, 0x0800);
+ b43_phy_set(dev, B43_PHY_RFOVERVAL, 0x8000);
}
}
- b43_radio_write16(dev, 0x7A, b43_radio_read16(dev, 0x7A)
- & 0x00F7);
+ b43_radio_mask(dev, 0x7A, 0x00F7);
j = 0;
loop_i_max = (phy->radio_rev == 8) ? 15 : 9;
for (i = 0; i < loop_i_max; i++) {
for (j = 0; j < 16; j++) {
b43_radio_write16(dev, 0x43, i);
- b43_phy_write(dev, B43_PHY_RFOVERVAL,
- (b43_phy_read(dev, B43_PHY_RFOVERVAL)
- & 0xF0FF) | (j << 8));
- b43_phy_write(dev, B43_PHY_PGACTL,
- (b43_phy_read(dev, B43_PHY_PGACTL)
- & 0x0FFF) | 0xA000);
- b43_phy_write(dev, B43_PHY_PGACTL,
- b43_phy_read(dev, B43_PHY_PGACTL)
- | 0xF000);
+ b43_phy_maskset(dev, B43_PHY_RFOVERVAL, 0xF0FF, (j << 8));
+ b43_phy_maskset(dev, B43_PHY_PGACTL, 0x0FFF, 0xA000);
+ b43_phy_set(dev, B43_PHY_PGACTL, 0xF000);
udelay(20);
if (b43_phy_read(dev, B43_PHY_LO_LEAKAGE) >= 0xDFC)
goto exit_loop1;
@@ -1982,20 +1811,12 @@ static void b43_calc_loopback_gain(struct b43_wldev *dev)
loop1_outer_done = i;
loop1_inner_done = j;
if (j >= 8) {
- b43_phy_write(dev, B43_PHY_RFOVERVAL,
- b43_phy_read(dev, B43_PHY_RFOVERVAL)
- | 0x30);
+ b43_phy_set(dev, B43_PHY_RFOVERVAL, 0x30);
trsw_rx = 0x1B;
for (j = j - 8; j < 16; j++) {
- b43_phy_write(dev, B43_PHY_RFOVERVAL,
- (b43_phy_read(dev, B43_PHY_RFOVERVAL)
- & 0xF0FF) | (j << 8));
- b43_phy_write(dev, B43_PHY_PGACTL,
- (b43_phy_read(dev, B43_PHY_PGACTL)
- & 0x0FFF) | 0xA000);
- b43_phy_write(dev, B43_PHY_PGACTL,
- b43_phy_read(dev, B43_PHY_PGACTL)
- | 0xF000);
+ b43_phy_maskset(dev, B43_PHY_RFOVERVAL, 0xF0FF, (j << 8));
+ b43_phy_maskset(dev, B43_PHY_PGACTL, 0x0FFF, 0xA000);
+ b43_phy_set(dev, B43_PHY_PGACTL, 0xF000);
udelay(20);
trsw_rx -= 3;
if (b43_phy_read(dev, B43_PHY_LO_LEAKAGE) >= 0xDFC)
@@ -2046,34 +1867,24 @@ static void b43_hardware_pctl_early_init(struct b43_wldev *dev)
return;
}
- b43_phy_write(dev, 0x0036, b43_phy_read(dev, 0x0036) & 0xFEFF);
+ b43_phy_mask(dev, 0x0036, 0xFEFF);
b43_phy_write(dev, 0x002F, 0x0202);
- b43_phy_write(dev, 0x047C, b43_phy_read(dev, 0x047C) | 0x0002);
- b43_phy_write(dev, 0x047A, b43_phy_read(dev, 0x047A) | 0xF000);
+ b43_phy_set(dev, 0x047C, 0x0002);
+ b43_phy_set(dev, 0x047A, 0xF000);
if (phy->radio_ver == 0x2050 && phy->radio_rev == 8) {
- b43_phy_write(dev, 0x047A, (b43_phy_read(dev, 0x047A)
- & 0xFF0F) | 0x0010);
- b43_phy_write(dev, 0x005D, b43_phy_read(dev, 0x005D)
- | 0x8000);
- b43_phy_write(dev, 0x004E, (b43_phy_read(dev, 0x004E)
- & 0xFFC0) | 0x0010);
+ b43_phy_maskset(dev, 0x047A, 0xFF0F, 0x0010);
+ b43_phy_set(dev, 0x005D, 0x8000);
+ b43_phy_maskset(dev, 0x004E, 0xFFC0, 0x0010);
b43_phy_write(dev, 0x002E, 0xC07F);
- b43_phy_write(dev, 0x0036, b43_phy_read(dev, 0x0036)
- | 0x0400);
+ b43_phy_set(dev, 0x0036, 0x0400);
} else {
- b43_phy_write(dev, 0x0036, b43_phy_read(dev, 0x0036)
- | 0x0200);
- b43_phy_write(dev, 0x0036, b43_phy_read(dev, 0x0036)
- | 0x0400);
- b43_phy_write(dev, 0x005D, b43_phy_read(dev, 0x005D)
- & 0x7FFF);
- b43_phy_write(dev, 0x004F, b43_phy_read(dev, 0x004F)
- & 0xFFFE);
- b43_phy_write(dev, 0x004E, (b43_phy_read(dev, 0x004E)
- & 0xFFC0) | 0x0010);
+ b43_phy_set(dev, 0x0036, 0x0200);
+ b43_phy_set(dev, 0x0036, 0x0400);
+ b43_phy_mask(dev, 0x005D, 0x7FFF);
+ b43_phy_mask(dev, 0x004F, 0xFFFE);
+ b43_phy_maskset(dev, 0x004E, 0xFFC0, 0x0010);
b43_phy_write(dev, 0x002E, 0xC07F);
- b43_phy_write(dev, 0x047A, (b43_phy_read(dev, 0x047A)
- & 0xFF0F) | 0x0010);
+ b43_phy_maskset(dev, 0x047A, 0xFF0F, 0x0010);
}
}
@@ -2089,22 +1900,17 @@ static void b43_hardware_pctl_init_gphy(struct b43_wldev *dev)
return;
}
- b43_phy_write(dev, 0x0036, (b43_phy_read(dev, 0x0036) & 0xFFC0)
- | (gphy->tgt_idle_tssi - gphy->cur_idle_tssi));
- b43_phy_write(dev, 0x0478, (b43_phy_read(dev, 0x0478) & 0xFF00)
- | (gphy->tgt_idle_tssi - gphy->cur_idle_tssi));
+ b43_phy_maskset(dev, 0x0036, 0xFFC0, (gphy->tgt_idle_tssi - gphy->cur_idle_tssi));
+ b43_phy_maskset(dev, 0x0478, 0xFF00, (gphy->tgt_idle_tssi - gphy->cur_idle_tssi));
b43_gphy_tssi_power_lt_init(dev);
b43_gphy_gain_lt_init(dev);
- b43_phy_write(dev, 0x0060, b43_phy_read(dev, 0x0060) & 0xFFBF);
+ b43_phy_mask(dev, 0x0060, 0xFFBF);
b43_phy_write(dev, 0x0014, 0x0000);
B43_WARN_ON(phy->rev < 6);
- b43_phy_write(dev, 0x0478, b43_phy_read(dev, 0x0478)
- | 0x0800);
- b43_phy_write(dev, 0x0478, b43_phy_read(dev, 0x0478)
- & 0xFEFF);
- b43_phy_write(dev, 0x0801, b43_phy_read(dev, 0x0801)
- & 0xFFBF);
+ b43_phy_set(dev, 0x0478, 0x0800);
+ b43_phy_mask(dev, 0x0478, 0xFEFF);
+ b43_phy_mask(dev, 0x0801, 0xFFBF);
b43_gphy_dc_lt_init(dev, 1);
@@ -2139,9 +1945,7 @@ static void b43_phy_init_pctl(struct b43_wldev *dev)
b43_hardware_pctl_early_init(dev);
if (gphy->cur_idle_tssi == 0) {
if (phy->radio_ver == 0x2050 && phy->analog == 0) {
- b43_radio_write16(dev, 0x0076,
- (b43_radio_read16(dev, 0x0076)
- & 0x00F7) | 0x0084);
+ b43_radio_maskset(dev, 0x0076, 0x00F7, 0x0084);
} else {
struct b43_rfatt rfatt;
struct b43_bbatt bbatt;
@@ -2174,9 +1978,7 @@ static void b43_phy_init_pctl(struct b43_wldev *dev)
}
}
if (phy->radio_ver == 0x2050 && phy->analog == 0) {
- b43_radio_write16(dev, 0x0076,
- b43_radio_read16(dev, 0x0076)
- & 0xFF7B);
+ b43_radio_mask(dev, 0x0076, 0xFF7B);
} else {
b43_set_txpower_g(dev, &old_bbatt,
&old_rfatt, old_tx_control);
@@ -2220,20 +2022,14 @@ static void b43_phy_initg(struct b43_wldev *dev)
b43_phy_write(dev, B43_PHY_OFDM(0xC3), 0x8006);
}
if (tmp == 5) {
- b43_phy_write(dev, B43_PHY_OFDM(0xCC),
- (b43_phy_read(dev, B43_PHY_OFDM(0xCC))
- & 0x00FF) | 0x1F00);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0xCC), 0x00FF, 0x1F00);
}
}
if ((phy->rev <= 2 && phy->gmode) || phy->rev >= 2)
b43_phy_write(dev, B43_PHY_OFDM(0x7E), 0x78);
if (phy->radio_rev == 8) {
- b43_phy_write(dev, B43_PHY_EXTG(0x01),
- b43_phy_read(dev, B43_PHY_EXTG(0x01))
- | 0x80);
- b43_phy_write(dev, B43_PHY_OFDM(0x3E),
- b43_phy_read(dev, B43_PHY_OFDM(0x3E))
- | 0x4);
+ b43_phy_set(dev, B43_PHY_EXTG(0x01), 0x80);
+ b43_phy_set(dev, B43_PHY_OFDM(0x3E), 0x4);
}
if (has_loopback_gain(phy))
b43_calc_loopback_gain(dev);
@@ -2251,15 +2047,10 @@ static void b43_phy_initg(struct b43_wldev *dev)
| gphy->lo_control->tx_bias | gphy->
lo_control->tx_magn);
} else {
- b43_radio_write16(dev, 0x52,
- (b43_radio_read16(dev, 0x52) & 0xFFF0)
- | gphy->lo_control->tx_bias);
+ b43_radio_maskset(dev, 0x52, 0xFFF0, gphy->lo_control->tx_bias);
}
if (phy->rev >= 6) {
- b43_phy_write(dev, B43_PHY_CCK(0x36),
- (b43_phy_read(dev, B43_PHY_CCK(0x36))
- & 0x0FFF) | (gphy->lo_control->
- tx_bias << 12));
+ b43_phy_maskset(dev, B43_PHY_CCK(0x36), 0x0FFF, (gphy->lo_control->tx_bias << 12));
}
if (dev->dev->bus->sprom.boardflags_lo & B43_BFL_PACTRL)
b43_phy_write(dev, B43_PHY_CCK(0x2E), 0x8075);
@@ -2298,11 +2089,8 @@ static void b43_phy_initg(struct b43_wldev *dev)
but OFDM is legal everywhere */
if ((dev->dev->bus->chip_id == 0x4306
&& dev->dev->bus->chip_package == 2) || 0) {
- b43_phy_write(dev, B43_PHY_CRS0, b43_phy_read(dev, B43_PHY_CRS0)
- & 0xBFFF);
- b43_phy_write(dev, B43_PHY_OFDM(0xC3),
- b43_phy_read(dev, B43_PHY_OFDM(0xC3))
- & 0x7FFF);
+ b43_phy_mask(dev, B43_PHY_CRS0, 0xBFFF);
+ b43_phy_mask(dev, B43_PHY_OFDM(0xC3), 0x7FFF);
}
}
@@ -2504,9 +2292,8 @@ static u8 b43_gphy_aci_scan(struct b43_wldev *dev)
b43_phy_lock(dev);
b43_radio_lock(dev);
- b43_phy_write(dev, 0x0802, b43_phy_read(dev, 0x0802) & 0xFFFC);
- b43_phy_write(dev, B43_PHY_G_CRS,
- b43_phy_read(dev, B43_PHY_G_CRS) & 0x7FFF);
+ b43_phy_mask(dev, 0x0802, 0xFFFC);
+ b43_phy_mask(dev, B43_PHY_G_CRS, 0x7FFF);
b43_set_all_gains(dev, 3, 8, 1);
start = (channel - 5 > 0) ? channel - 5 : 1;
@@ -2517,11 +2304,9 @@ static u8 b43_gphy_aci_scan(struct b43_wldev *dev)
ret[i - 1] = b43_gphy_aci_detect(dev, i);
}
b43_switch_channel(dev, channel);
- b43_phy_write(dev, 0x0802,
- (b43_phy_read(dev, 0x0802) & 0xFFFC) | 0x0003);
- b43_phy_write(dev, 0x0403, b43_phy_read(dev, 0x0403) & 0xFFF8);
- b43_phy_write(dev, B43_PHY_G_CRS,
- b43_phy_read(dev, B43_PHY_G_CRS) | 0x8000);
+ b43_phy_maskset(dev, 0x0802, 0xFFFC, 0x0003);
+ b43_phy_mask(dev, 0x0403, 0xFFF8);
+ b43_phy_set(dev, B43_PHY_G_CRS, 0x8000);
b43_set_original_gains(dev);
for (i = 0; i < 13; i++) {
if (!ret[i])
@@ -2565,8 +2350,8 @@ static s8 b43_tssi2dbm_entry(s8 entry[], u8 index,
return 0;
}
-u8 * b43_generate_dyn_tssi2dbm_tab(struct b43_wldev *dev,
- s16 pab0, s16 pab1, s16 pab2)
+u8 *b43_generate_dyn_tssi2dbm_tab(struct b43_wldev *dev,
+ s16 pab0, s16 pab1, s16 pab2)
{
unsigned int i;
u8 *tab;
@@ -3191,6 +2976,7 @@ static enum b43_txpwr_result b43_gphy_op_recalc_txpower(struct b43_wldev *dev,
* Baseband attennuation. Subtract it. */
bbatt_delta -= 4 * rfatt_delta;
+#if B43_DEBUG
if (b43_debug(dev, B43_DBG_XMITPOWER)) {
int dbm = pwr_adjust < 0 ? -pwr_adjust : pwr_adjust;
b43dbg(dev->wl,
@@ -3199,6 +2985,8 @@ static enum b43_txpwr_result b43_gphy_op_recalc_txpower(struct b43_wldev *dev,
(pwr_adjust < 0 ? "-" : ""), Q52_ARG(dbm),
bbatt_delta, rfatt_delta);
}
+#endif /* DEBUG */
+
/* So do we finally need to adjust something in hardware? */
if ((rfatt_delta == 0) && (bbatt_delta == 0))
goto no_adjustment_needed;
diff --git a/drivers/net/wireless/b43/phy_lp.c b/drivers/net/wireless/b43/phy_lp.c
index c5d9dc3667c0..58e319d6b1ed 100644
--- a/drivers/net/wireless/b43/phy_lp.c
+++ b/drivers/net/wireless/b43/phy_lp.c
@@ -3,7 +3,7 @@
Broadcom B43 wireless driver
IEEE 802.11g LP-PHY driver
- Copyright (c) 2008 Michael Buesch <mb@bu3sch.de>
+ Copyright (c) 2008-2009 Michael Buesch <mb@bu3sch.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -23,8 +23,10 @@
*/
#include "b43.h"
+#include "main.h"
#include "phy_lp.h"
#include "phy_common.h"
+#include "tables_lpphy.h"
static int b43_lpphy_op_allocate(struct b43_wldev *dev)
@@ -57,9 +59,394 @@ static void b43_lpphy_op_free(struct b43_wldev *dev)
dev->phy.lp = NULL;
}
-static int b43_lpphy_op_init(struct b43_wldev *dev)
+static void lpphy_table_init(struct b43_wldev *dev)
+{
+ //TODO
+}
+
+static void lpphy_baseband_rev0_1_init(struct b43_wldev *dev)
+{
+ B43_WARN_ON(1);//TODO rev < 2 not supported, yet.
+}
+
+static void lpphy_baseband_rev2plus_init(struct b43_wldev *dev)
+{
+ struct ssb_bus *bus = dev->dev->bus;
+ struct b43_phy_lp *lpphy = dev->phy.lp;
+
+ b43_phy_write(dev, B43_LPPHY_AFE_DAC_CTL, 0x50);
+ b43_phy_write(dev, B43_LPPHY_AFE_CTL, 0x8800);
+ b43_phy_write(dev, B43_LPPHY_AFE_CTL_OVR, 0);
+ b43_phy_write(dev, B43_LPPHY_AFE_CTL_OVRVAL, 0);
+ b43_phy_write(dev, B43_LPPHY_RF_OVERRIDE_0, 0);
+ b43_phy_write(dev, B43_LPPHY_RF_OVERRIDE_2, 0);
+ b43_phy_write(dev, B43_PHY_OFDM(0xF9), 0);
+ b43_phy_write(dev, B43_LPPHY_TR_LOOKUP_1, 0);
+ b43_phy_set(dev, B43_LPPHY_ADC_COMPENSATION_CTL, 0x10);
+ b43_phy_maskset(dev, B43_LPPHY_OFDMSYNCTHRESH0, 0xFF00, 0x78);
+ b43_phy_maskset(dev, B43_LPPHY_DCOFFSETTRANSIENT, 0xF8FF, 0x200);
+ b43_phy_maskset(dev, B43_LPPHY_DCOFFSETTRANSIENT, 0xFF00, 0x7F);
+ b43_phy_maskset(dev, B43_LPPHY_GAINDIRECTMISMATCH, 0xFF0F, 0x40);
+ b43_phy_maskset(dev, B43_LPPHY_PREAMBLECONFIRMTO, 0xFF00, 0x2);
+ b43_phy_mask(dev, B43_LPPHY_CRSGAIN_CTL, ~0x4000);
+ b43_phy_mask(dev, B43_LPPHY_CRSGAIN_CTL, ~0x2000);
+ b43_phy_set(dev, B43_PHY_OFDM(0x10A), 0x1);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0x10A), 0xFF01, 0x10);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0xDF), 0xFF00, 0xF4);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0xDF), 0x00FF, 0xF100);
+ b43_phy_write(dev, B43_LPPHY_CLIPTHRESH, 0x48);
+ b43_phy_maskset(dev, B43_LPPHY_HIGAINDB, 0xFF00, 0x46);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0xE4), 0xFF00, 0x10);
+ b43_phy_maskset(dev, B43_LPPHY_PWR_THRESH1, 0xFFF0, 0x9);
+ b43_phy_mask(dev, B43_LPPHY_GAINDIRECTMISMATCH, ~0xF);
+ b43_phy_maskset(dev, B43_LPPHY_VERYLOWGAINDB, 0x00FF, 0x5500);
+ b43_phy_maskset(dev, B43_LPPHY_CLIPCTRTHRESH, 0xF81F, 0xA0);
+ b43_phy_maskset(dev, B43_LPPHY_GAINDIRECTMISMATCH, 0xE0FF, 0x300);
+ b43_phy_maskset(dev, B43_LPPHY_HIGAINDB, 0x00FF, 0x2A00);
+ if ((bus->chip_id == 0x4325) && (bus->chip_rev == 0)) {
+ b43_phy_maskset(dev, B43_LPPHY_LOWGAINDB, 0x00FF, 0x2100);
+ b43_phy_maskset(dev, B43_LPPHY_VERYLOWGAINDB, 0xFF00, 0xA);
+ } else {
+ b43_phy_maskset(dev, B43_LPPHY_LOWGAINDB, 0x00FF, 0x1E00);
+ b43_phy_maskset(dev, B43_LPPHY_VERYLOWGAINDB, 0xFF00, 0xD);
+ }
+ b43_phy_maskset(dev, B43_PHY_OFDM(0xFE), 0xFFE0, 0x1F);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0xFF), 0xFFE0, 0xC);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0x100), 0xFF00, 0x19);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0xFF), 0x03FF, 0x3C00);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0xFE), 0xFC1F, 0x3E0);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0xFF), 0xFFE0, 0xC);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0x100), 0x00FF, 0x1900);
+ b43_phy_maskset(dev, B43_LPPHY_CLIPCTRTHRESH, 0x83FF, 0x5800);
+ b43_phy_maskset(dev, B43_LPPHY_CLIPCTRTHRESH, 0xFFE0, 0x12);
+ b43_phy_maskset(dev, B43_LPPHY_GAINMISMATCH, 0x0FFF, 0x9000);
+
+ b43_lptab_write(dev, B43_LPTAB16(0x08, 0x14), 0);
+ b43_lptab_write(dev, B43_LPTAB16(0x08, 0x12), 0x40);
+
+ if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
+ b43_phy_set(dev, B43_LPPHY_CRSGAIN_CTL, 0x40);
+ b43_phy_maskset(dev, B43_LPPHY_CRSGAIN_CTL, 0xF0FF, 0xB00);
+ b43_phy_maskset(dev, B43_LPPHY_SYNCPEAKCNT, 0xFFF8, 0x6);
+ b43_phy_maskset(dev, B43_LPPHY_MINPWR_LEVEL, 0x00FF, 0x9D00);
+ b43_phy_maskset(dev, B43_LPPHY_MINPWR_LEVEL, 0xFF00, 0xA1);
+ } else /* 5GHz */
+ b43_phy_mask(dev, B43_LPPHY_CRSGAIN_CTL, ~0x40);
+
+ b43_phy_maskset(dev, B43_LPPHY_CRS_ED_THRESH, 0xFF00, 0xB3);
+ b43_phy_maskset(dev, B43_LPPHY_CRS_ED_THRESH, 0x00FF, 0xAD00);
+ b43_phy_maskset(dev, B43_LPPHY_INPUT_PWRDB, 0xFF00, lpphy->rx_pwr_offset);
+ b43_phy_set(dev, B43_LPPHY_RESET_CTL, 0x44);
+ b43_phy_write(dev, B43_LPPHY_RESET_CTL, 0x80);
+ b43_phy_write(dev, B43_LPPHY_AFE_RSSI_CTL_0, 0xA954);
+ b43_phy_write(dev, B43_LPPHY_AFE_RSSI_CTL_1,
+ 0x2000 | ((u16)lpphy->rssi_gs << 10) |
+ ((u16)lpphy->rssi_vc << 4) | lpphy->rssi_vf);
+}
+
+static void lpphy_baseband_init(struct b43_wldev *dev)
+{
+ lpphy_table_init(dev);
+ if (dev->phy.rev >= 2)
+ lpphy_baseband_rev2plus_init(dev);
+ else
+ lpphy_baseband_rev0_1_init(dev);
+}
+
+struct b2062_freqdata {
+ u16 freq;
+ u8 data[6];
+};
+
+/* Initialize the 2062 radio. */
+static void lpphy_2062_init(struct b43_wldev *dev)
+{
+ struct ssb_bus *bus = dev->dev->bus;
+ u32 crystalfreq, pdiv, tmp, ref;
+ unsigned int i;
+ const struct b2062_freqdata *fd = NULL;
+
+ static const struct b2062_freqdata freqdata_tab[] = {
+ { .freq = 12000, .data[0] = 6, .data[1] = 6, .data[2] = 6,
+ .data[3] = 6, .data[4] = 10, .data[5] = 6, },
+ { .freq = 13000, .data[0] = 4, .data[1] = 4, .data[2] = 4,
+ .data[3] = 4, .data[4] = 11, .data[5] = 7, },
+ { .freq = 14400, .data[0] = 3, .data[1] = 3, .data[2] = 3,
+ .data[3] = 3, .data[4] = 12, .data[5] = 7, },
+ { .freq = 16200, .data[0] = 3, .data[1] = 3, .data[2] = 3,
+ .data[3] = 3, .data[4] = 13, .data[5] = 8, },
+ { .freq = 18000, .data[0] = 2, .data[1] = 2, .data[2] = 2,
+ .data[3] = 2, .data[4] = 14, .data[5] = 8, },
+ { .freq = 19200, .data[0] = 1, .data[1] = 1, .data[2] = 1,
+ .data[3] = 1, .data[4] = 14, .data[5] = 9, },
+ };
+
+ b2062_upload_init_table(dev);
+
+ b43_radio_write(dev, B2062_N_TX_CTL3, 0);
+ b43_radio_write(dev, B2062_N_TX_CTL4, 0);
+ b43_radio_write(dev, B2062_N_TX_CTL5, 0);
+ b43_radio_write(dev, B2062_N_PDN_CTL0, 0x40);
+ b43_radio_write(dev, B2062_N_PDN_CTL0, 0);
+ b43_radio_write(dev, B2062_N_CALIB_TS, 0x10);
+ b43_radio_write(dev, B2062_N_CALIB_TS, 0);
+ if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
+ b43_radio_set(dev, B2062_N_TSSI_CTL0, 0x1);
+ else
+ b43_radio_mask(dev, B2062_N_TSSI_CTL0, ~0x1);
+
+ /* Get the crystal freq, in Hz. */
+ crystalfreq = bus->chipco.pmu.crystalfreq * 1000;
+
+ B43_WARN_ON(!(bus->chipco.capabilities & SSB_CHIPCO_CAP_PMU));
+ B43_WARN_ON(crystalfreq == 0);
+
+ if (crystalfreq >= 30000000) {
+ pdiv = 1;
+ b43_radio_mask(dev, B2062_S_RFPLL_CTL1, 0xFFFB);
+ } else {
+ pdiv = 2;
+ b43_radio_set(dev, B2062_S_RFPLL_CTL1, 0x4);
+ }
+
+ tmp = (800000000 * pdiv + crystalfreq) / (32000000 * pdiv);
+ tmp = (tmp - 1) & 0xFF;
+ b43_radio_write(dev, B2062_S_RFPLL_CTL18, tmp);
+
+ tmp = (2 * crystalfreq + 1000000 * pdiv) / (2000000 * pdiv);
+ tmp = ((tmp & 0xFF) - 1) & 0xFFFF;
+ b43_radio_write(dev, B2062_S_RFPLL_CTL19, tmp);
+
+ ref = (1000 * pdiv + 2 * crystalfreq) / (2000 * pdiv);
+ ref &= 0xFFFF;
+ for (i = 0; i < ARRAY_SIZE(freqdata_tab); i++) {
+ if (ref < freqdata_tab[i].freq) {
+ fd = &freqdata_tab[i];
+ break;
+ }
+ }
+ if (!fd)
+ fd = &freqdata_tab[ARRAY_SIZE(freqdata_tab) - 1];
+ b43dbg(dev->wl, "b2062: Using crystal tab entry %u kHz.\n",
+ fd->freq); /* FIXME: Keep this printk until the code is fully debugged. */
+
+ b43_radio_write(dev, B2062_S_RFPLL_CTL8,
+ ((u16)(fd->data[1]) << 4) | fd->data[0]);
+ b43_radio_write(dev, B2062_S_RFPLL_CTL9,
+ ((u16)(fd->data[3]) << 4) | fd->data[2]);
+ b43_radio_write(dev, B2062_S_RFPLL_CTL10, fd->data[4]);
+ b43_radio_write(dev, B2062_S_RFPLL_CTL11, fd->data[5]);
+}
+
+/* Initialize the 2063 radio. */
+static void lpphy_2063_init(struct b43_wldev *dev)
{
//TODO
+}
+
+static void lpphy_sync_stx(struct b43_wldev *dev)
+{
+ //TODO
+}
+
+static void lpphy_radio_init(struct b43_wldev *dev)
+{
+ /* The radio is attached through the 4wire bus. */
+ b43_phy_set(dev, B43_LPPHY_FOURWIRE_CTL, 0x2);
+ udelay(1);
+ b43_phy_mask(dev, B43_LPPHY_FOURWIRE_CTL, 0xFFFD);
+ udelay(1);
+
+ if (dev->phy.rev < 2) {
+ lpphy_2062_init(dev);
+ } else {
+ lpphy_2063_init(dev);
+ lpphy_sync_stx(dev);
+ b43_phy_write(dev, B43_PHY_OFDM(0xF0), 0x5F80);
+ b43_phy_write(dev, B43_PHY_OFDM(0xF1), 0);
+ //TODO Do something on the backplane
+ }
+}
+
+/* Read the TX power control mode from hardware. */
+static void lpphy_read_tx_pctl_mode_from_hardware(struct b43_wldev *dev)
+{
+ struct b43_phy_lp *lpphy = dev->phy.lp;
+ u16 ctl;
+
+ ctl = b43_phy_read(dev, B43_LPPHY_TX_PWR_CTL_CMD);
+ switch (ctl & B43_LPPHY_TX_PWR_CTL_CMD_MODE) {
+ case B43_LPPHY_TX_PWR_CTL_CMD_MODE_OFF:
+ lpphy->txpctl_mode = B43_LPPHY_TXPCTL_OFF;
+ break;
+ case B43_LPPHY_TX_PWR_CTL_CMD_MODE_SW:
+ lpphy->txpctl_mode = B43_LPPHY_TXPCTL_SW;
+ break;
+ case B43_LPPHY_TX_PWR_CTL_CMD_MODE_HW:
+ lpphy->txpctl_mode = B43_LPPHY_TXPCTL_HW;
+ break;
+ default:
+ lpphy->txpctl_mode = B43_LPPHY_TXPCTL_UNKNOWN;
+ B43_WARN_ON(1);
+ break;
+ }
+}
+
+/* Set the TX power control mode in hardware. */
+static void lpphy_write_tx_pctl_mode_to_hardware(struct b43_wldev *dev)
+{
+ struct b43_phy_lp *lpphy = dev->phy.lp;
+ u16 ctl;
+
+ switch (lpphy->txpctl_mode) {
+ case B43_LPPHY_TXPCTL_OFF:
+ ctl = B43_LPPHY_TX_PWR_CTL_CMD_MODE_OFF;
+ break;
+ case B43_LPPHY_TXPCTL_HW:
+ ctl = B43_LPPHY_TX_PWR_CTL_CMD_MODE_HW;
+ break;
+ case B43_LPPHY_TXPCTL_SW:
+ ctl = B43_LPPHY_TX_PWR_CTL_CMD_MODE_SW;
+ break;
+ default:
+ ctl = 0;
+ B43_WARN_ON(1);
+ }
+ b43_phy_maskset(dev, B43_LPPHY_TX_PWR_CTL_CMD,
+ (u16)~B43_LPPHY_TX_PWR_CTL_CMD_MODE, ctl);
+}
+
+static void lpphy_set_tx_power_control(struct b43_wldev *dev,
+ enum b43_lpphy_txpctl_mode mode)
+{
+ struct b43_phy_lp *lpphy = dev->phy.lp;
+ enum b43_lpphy_txpctl_mode oldmode;
+
+ oldmode = lpphy->txpctl_mode;
+ lpphy_read_tx_pctl_mode_from_hardware(dev);
+ if (lpphy->txpctl_mode == mode)
+ return;
+ lpphy->txpctl_mode = mode;
+
+ if (oldmode == B43_LPPHY_TXPCTL_HW) {
+ //TODO Update TX Power NPT
+ //TODO Clear all TX Power offsets
+ } else {
+ if (mode == B43_LPPHY_TXPCTL_HW) {
+ //TODO Recalculate target TX power
+ b43_phy_maskset(dev, B43_LPPHY_TX_PWR_CTL_CMD,
+ 0xFF80, lpphy->tssi_idx);
+ b43_phy_maskset(dev, B43_LPPHY_TX_PWR_CTL_NNUM,
+ 0x8FFF, ((u16)lpphy->tssi_npt << 16));
+ //TODO Set "TSSI Transmit Count" variable to total transmitted frame count
+ //TODO Disable TX gain override
+ lpphy->tx_pwr_idx_over = -1;
+ }
+ }
+ if (dev->phy.rev >= 2) {
+ if (mode == B43_LPPHY_TXPCTL_HW)
+ b43_phy_maskset(dev, B43_PHY_OFDM(0xD0), 0xFD, 0x2);
+ else
+ b43_phy_maskset(dev, B43_PHY_OFDM(0xD0), 0xFD, 0);
+ }
+ lpphy_write_tx_pctl_mode_to_hardware(dev);
+}
+
+static void lpphy_set_tx_power_by_index(struct b43_wldev *dev, u8 index)
+{
+ struct b43_phy_lp *lpphy = dev->phy.lp;
+
+ lpphy->tx_pwr_idx_over = index;
+ if (lpphy->txpctl_mode != B43_LPPHY_TXPCTL_OFF)
+ lpphy_set_tx_power_control(dev, B43_LPPHY_TXPCTL_SW);
+
+ //TODO
+}
+
+static void lpphy_btcoex_override(struct b43_wldev *dev)
+{
+ b43_write16(dev, B43_MMIO_BTCOEX_CTL, 0x3);
+ b43_write16(dev, B43_MMIO_BTCOEX_TXCTL, 0xFF);
+}
+
+static void lpphy_pr41573_workaround(struct b43_wldev *dev)
+{
+ struct b43_phy_lp *lpphy = dev->phy.lp;
+ u32 *saved_tab;
+ const unsigned int saved_tab_size = 256;
+ enum b43_lpphy_txpctl_mode txpctl_mode;
+ s8 tx_pwr_idx_over;
+ u16 tssi_npt, tssi_idx;
+
+ saved_tab = kcalloc(saved_tab_size, sizeof(saved_tab[0]), GFP_KERNEL);
+ if (!saved_tab) {
+ b43err(dev->wl, "PR41573 failed. Out of memory!\n");
+ return;
+ }
+
+ lpphy_read_tx_pctl_mode_from_hardware(dev);
+ txpctl_mode = lpphy->txpctl_mode;
+ tx_pwr_idx_over = lpphy->tx_pwr_idx_over;
+ tssi_npt = lpphy->tssi_npt;
+ tssi_idx = lpphy->tssi_idx;
+
+ if (dev->phy.rev < 2) {
+ b43_lptab_read_bulk(dev, B43_LPTAB32(10, 0x140),
+ saved_tab_size, saved_tab);
+ } else {
+ b43_lptab_read_bulk(dev, B43_LPTAB32(7, 0x140),
+ saved_tab_size, saved_tab);
+ }
+ //TODO
+
+ kfree(saved_tab);
+}
+
+static void lpphy_calibration(struct b43_wldev *dev)
+{
+ struct b43_phy_lp *lpphy = dev->phy.lp;
+ enum b43_lpphy_txpctl_mode saved_pctl_mode;
+
+ b43_mac_suspend(dev);
+
+ lpphy_btcoex_override(dev);
+ lpphy_read_tx_pctl_mode_from_hardware(dev);
+ saved_pctl_mode = lpphy->txpctl_mode;
+ lpphy_set_tx_power_control(dev, B43_LPPHY_TXPCTL_OFF);
+ //TODO Perform transmit power table I/Q LO calibration
+ if ((dev->phy.rev == 0) && (saved_pctl_mode != B43_LPPHY_TXPCTL_OFF))
+ lpphy_pr41573_workaround(dev);
+ //TODO If a full calibration has not been performed on this channel yet, perform PAPD TX-power calibration
+ lpphy_set_tx_power_control(dev, saved_pctl_mode);
+ //TODO Perform I/Q calibration with a single control value set
+
+ b43_mac_enable(dev);
+}
+
+/* Initialize TX power control */
+static void lpphy_tx_pctl_init(struct b43_wldev *dev)
+{
+ if (0/*FIXME HWPCTL capable */) {
+ //TODO
+ } else { /* This device is only software TX power control capable. */
+ if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
+ //TODO
+ } else {
+ //TODO
+ }
+ //TODO set BB multiplier to 0x0096
+ }
+}
+
+static int b43_lpphy_op_init(struct b43_wldev *dev)
+{
+ /* TODO: band SPROM */
+ lpphy_baseband_init(dev);
+ lpphy_radio_init(dev);
+ //TODO calibrate RC
+ //TODO set channel
+ lpphy_tx_pctl_init(dev);
+ //TODO full calib
return 0;
}
@@ -115,7 +502,9 @@ static int b43_lpphy_op_switch_channel(struct b43_wldev *dev,
static unsigned int b43_lpphy_op_get_default_chan(struct b43_wldev *dev)
{
- return 1; /* Default to channel 1 */
+ if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
+ return 1;
+ return 36;
}
static void b43_lpphy_op_set_rx_antenna(struct b43_wldev *dev, int antenna)
diff --git a/drivers/net/wireless/b43/phy_lp.h b/drivers/net/wireless/b43/phy_lp.h
index b0b5357abf93..18370b4ac38e 100644
--- a/drivers/net/wireless/b43/phy_lp.h
+++ b/drivers/net/wireless/b43/phy_lp.h
@@ -4,8 +4,285 @@
/* Definitions for the LP-PHY */
+/* The CCK PHY register range. */
+#define B43_LPPHY_B_VERSION B43_PHY_CCK(0x00) /* B PHY version */
+#define B43_LPPHY_B_BBCONFIG B43_PHY_CCK(0x01) /* B PHY BBConfig */
+#define B43_LPPHY_B_RX_STAT0 B43_PHY_CCK(0x04) /* B PHY RX Status0 */
+#define B43_LPPHY_B_RX_STAT1 B43_PHY_CCK(0x05) /* B PHY RX Status1 */
+#define B43_LPPHY_B_CRS_THRESH B43_PHY_CCK(0x06) /* B PHY CRS Thresh */
+#define B43_LPPHY_B_TXERROR B43_PHY_CCK(0x07) /* B PHY TxError */
+#define B43_LPPHY_B_CHANNEL B43_PHY_CCK(0x08) /* B PHY Channel */
+#define B43_LPPHY_B_WORKAROUND B43_PHY_CCK(0x09) /* B PHY workaround */
+#define B43_LPPHY_B_TEST B43_PHY_CCK(0x0A) /* B PHY Test */
+#define B43_LPPHY_B_FOURWIRE_ADDR B43_PHY_CCK(0x0B) /* B PHY Fourwire Address */
+#define B43_LPPHY_B_FOURWIRE_DATA_HI B43_PHY_CCK(0x0C) /* B PHY Fourwire Data Hi */
+#define B43_LPPHY_B_FOURWIRE_DATA_LO B43_PHY_CCK(0x0D) /* B PHY Fourwire Data Lo */
+#define B43_LPPHY_B_BIST_STAT B43_PHY_CCK(0x0E) /* B PHY Bist Status */
+#define B43_LPPHY_PA_RAMP_TX_TO B43_PHY_CCK(0x10) /* PA Ramp TX Timeout */
+#define B43_LPPHY_RF_SYNTH_DC_TIMER B43_PHY_CCK(0x11) /* RF Synth DC Timer */
+#define B43_LPPHY_PA_RAMP_TX_TIME_IN B43_PHY_CCK(0x12) /* PA ramp TX Time in */
+#define B43_LPPHY_RX_FILTER_TIME_IN B43_PHY_CCK(0x13) /* RX Filter Time in */
+#define B43_LPPHY_PLL_COEFF_S B43_PHY_CCK(0x18) /* PLL Coefficient(s) */
+#define B43_LPPHY_PLL_OUT B43_PHY_CCK(0x19) /* PLL Out */
+#define B43_LPPHY_RSSI_THRES B43_PHY_CCK(0x20) /* RSSI Threshold */
+#define B43_LPPHY_IQ_THRES_HH B43_PHY_CCK(0x21) /* IQ Threshold HH */
+#define B43_LPPHY_IQ_THRES_H B43_PHY_CCK(0x22) /* IQ Threshold H */
+#define B43_LPPHY_IQ_THRES_L B43_PHY_CCK(0x23) /* IQ Threshold L */
+#define B43_LPPHY_IQ_THRES_LL B43_PHY_CCK(0x24) /* IQ Threshold LL */
+#define B43_LPPHY_AGC_GAIN B43_PHY_CCK(0x25) /* AGC Gain */
+#define B43_LPPHY_LNA_GAIN_RANGE B43_PHY_CCK(0x26) /* LNA Gain Range */
+#define B43_LPPHY_JSSI B43_PHY_CCK(0x27) /* JSSI */
+#define B43_LPPHY_TSSI_CTL B43_PHY_CCK(0x28) /* TSSI Control */
+#define B43_LPPHY_TSSI B43_PHY_CCK(0x29) /* TSSI */
+#define B43_LPPHY_TR_LOSS B43_PHY_CCK(0x2A) /* TR Loss */
+#define B43_LPPHY_LO_LEAKAGE B43_PHY_CCK(0x2B) /* LO Leakage */
+#define B43_LPPHY_LO_RSSIACC B43_PHY_CCK(0x2C) /* LO RSSIAcc */
+#define B43_LPPHY_LO_IQ_MAG_ACC B43_PHY_CCK(0x2D) /* LO IQ Mag Acc */
+#define B43_LPPHY_TX_DCOFFSET1 B43_PHY_CCK(0x2E) /* TX DCOffset1 */
+#define B43_LPPHY_TX_DCOFFSET2 B43_PHY_CCK(0x2F) /* TX DCOffset2 */
+#define B43_LPPHY_SYNCPEAKCNT B43_PHY_CCK(0x30) /* SyncPeakCnt */
+#define B43_LPPHY_SYNCFREQ B43_PHY_CCK(0x31) /* SyncFreq */
+#define B43_LPPHY_SYNCDIVERSITYCTL B43_PHY_CCK(0x32) /* SyncDiversityControl */
+#define B43_LPPHY_PEAKENERGYL B43_PHY_CCK(0x33) /* PeakEnergyL */
+#define B43_LPPHY_PEAKENERGYH B43_PHY_CCK(0x34) /* PeakEnergyH */
+#define B43_LPPHY_SYNCCTL B43_PHY_CCK(0x35) /* SyncControl */
+#define B43_LPPHY_DSSSSTEP B43_PHY_CCK(0x38) /* DsssStep */
+#define B43_LPPHY_DSSSWARMUP B43_PHY_CCK(0x39) /* DsssWarmup */
+#define B43_LPPHY_DSSSSIGPOW B43_PHY_CCK(0x3D) /* DsssSigPow */
+#define B43_LPPHY_SFDDETECTBLOCKTIME B43_PHY_CCK(0x40) /* SfdDetectBlockTIme */
+#define B43_LPPHY_SFDTO B43_PHY_CCK(0x41) /* SFDTimeOut */
+#define B43_LPPHY_SFDCTL B43_PHY_CCK(0x42) /* SFDControl */
+#define B43_LPPHY_RXDBG B43_PHY_CCK(0x43) /* rxDebug */
+#define B43_LPPHY_RX_DELAYCOMP B43_PHY_CCK(0x44) /* RX DelayComp */
+#define B43_LPPHY_CRSDROPOUTTO B43_PHY_CCK(0x45) /* CRSDropoutTimeout */
+#define B43_LPPHY_PSEUDOSHORTTO B43_PHY_CCK(0x46) /* PseudoShortTimeout */
+#define B43_LPPHY_PR3931 B43_PHY_CCK(0x47) /* PR3931 */
+#define B43_LPPHY_DSSSCOEFF1 B43_PHY_CCK(0x48) /* DSSSCoeff1 */
+#define B43_LPPHY_DSSSCOEFF2 B43_PHY_CCK(0x49) /* DSSSCoeff2 */
+#define B43_LPPHY_CCKCOEFF1 B43_PHY_CCK(0x4A) /* CCKCoeff1 */
+#define B43_LPPHY_CCKCOEFF2 B43_PHY_CCK(0x4B) /* CCKCoeff2 */
+#define B43_LPPHY_TRCORR B43_PHY_CCK(0x4C) /* TRCorr */
+#define B43_LPPHY_ANGLESCALE B43_PHY_CCK(0x4D) /* AngleScale */
+#define B43_LPPHY_OPTIONALMODES2 B43_PHY_CCK(0x4F) /* OptionalModes2 */
+#define B43_LPPHY_CCKLMSSTEPSIZE B43_PHY_CCK(0x50) /* CCKLMSStepSize */
+#define B43_LPPHY_DFEBYPASS B43_PHY_CCK(0x51) /* DFEBypass */
+#define B43_LPPHY_CCKSTARTDELAYLONG B43_PHY_CCK(0x52) /* CCKStartDelayLong */
+#define B43_LPPHY_CCKSTARTDELAYSHORT B43_PHY_CCK(0x53) /* CCKStartDelayShort */
+#define B43_LPPHY_PPROCCHDELAY B43_PHY_CCK(0x54) /* PprocChDelay */
+#define B43_LPPHY_PPROCONOFF B43_PHY_CCK(0x55) /* PProcOnOff */
+#define B43_LPPHY_LNAGAINTWOBIT10 B43_PHY_CCK(0x5B) /* LNAGainTwoBit10 */
+#define B43_LPPHY_LNAGAINTWOBIT32 B43_PHY_CCK(0x5C) /* LNAGainTwoBit32 */
+#define B43_LPPHY_OPTIONALMODES B43_PHY_CCK(0x5D) /* OptionalModes */
+#define B43_LPPHY_B_RX_STAT2 B43_PHY_CCK(0x5E) /* B PHY RX Status2 */
+#define B43_LPPHY_B_RX_STAT3 B43_PHY_CCK(0x5F) /* B PHY RX Status3 */
+#define B43_LPPHY_PWDNDACDELAY B43_PHY_CCK(0x63) /* pwdnDacDelay */
+#define B43_LPPHY_FINEDIGIGAIN_CTL B43_PHY_CCK(0x67) /* FineDigiGain Control */
+#define B43_LPPHY_LG2GAINTBLLNA8 B43_PHY_CCK(0x68) /* Lg2GainTblLNA8 */
+#define B43_LPPHY_LG2GAINTBLLNA28 B43_PHY_CCK(0x69) /* Lg2GainTblLNA28 */
+#define B43_LPPHY_GAINTBLLNATRSW B43_PHY_CCK(0x6A) /* GainTblLNATrSw */
+#define B43_LPPHY_PEAKENERGY B43_PHY_CCK(0x6B) /* PeakEnergy */
+#define B43_LPPHY_LG2INITGAIN B43_PHY_CCK(0x6C) /* lg2InitGain */
+#define B43_LPPHY_BLANKCOUNTLNAPGA B43_PHY_CCK(0x6D) /* BlankCountLnaPga */
+#define B43_LPPHY_LNAGAINTWOBIT54 B43_PHY_CCK(0x6E) /* LNAGainTwoBit54 */
+#define B43_LPPHY_LNAGAINTWOBIT76 B43_PHY_CCK(0x6F) /* LNAGainTwoBit76 */
+#define B43_LPPHY_JSSICTL B43_PHY_CCK(0x70) /* JSSIControl */
+#define B43_LPPHY_LG2GAINTBLLNA44 B43_PHY_CCK(0x71) /* Lg2GainTblLNA44 */
+#define B43_LPPHY_LG2GAINTBLLNA62 B43_PHY_CCK(0x72) /* Lg2GainTblLNA62 */
+/* The OFDM PHY register range. */
+#define B43_LPPHY_VERSION B43_PHY_OFDM(0x00) /* Version */
+#define B43_LPPHY_BBCONFIG B43_PHY_OFDM(0x01) /* BBConfig */
+#define B43_LPPHY_RX_STAT0 B43_PHY_OFDM(0x04) /* RX Status0 */
+#define B43_LPPHY_RX_STAT1 B43_PHY_OFDM(0x05) /* RX Status1 */
+#define B43_LPPHY_TX_ERROR B43_PHY_OFDM(0x07) /* TX Error */
+#define B43_LPPHY_CHANNEL B43_PHY_OFDM(0x08) /* Channel */
+#define B43_LPPHY_WORKAROUND B43_PHY_OFDM(0x09) /* workaround */
+#define B43_LPPHY_FOURWIRE_ADDR B43_PHY_OFDM(0x0B) /* Fourwire Address */
+#define B43_LPPHY_FOURWIREDATAHI B43_PHY_OFDM(0x0C) /* FourwireDataHi */
+#define B43_LPPHY_FOURWIREDATALO B43_PHY_OFDM(0x0D) /* FourwireDataLo */
+#define B43_LPPHY_BISTSTAT0 B43_PHY_OFDM(0x0E) /* BistStatus0 */
+#define B43_LPPHY_BISTSTAT1 B43_PHY_OFDM(0x0F) /* BistStatus1 */
+#define B43_LPPHY_CRSGAIN_CTL B43_PHY_OFDM(0x10) /* crsgain Control */
+#define B43_LPPHY_OFDMPWR_THRESH0 B43_PHY_OFDM(0x11) /* ofdmPower Thresh0 */
+#define B43_LPPHY_OFDMPWR_THRESH1 B43_PHY_OFDM(0x12) /* ofdmPower Thresh1 */
+#define B43_LPPHY_OFDMPWR_THRESH2 B43_PHY_OFDM(0x13) /* ofdmPower Thresh2 */
+#define B43_LPPHY_DSSSPWR_THRESH0 B43_PHY_OFDM(0x14) /* dsssPower Thresh0 */
+#define B43_LPPHY_DSSSPWR_THRESH1 B43_PHY_OFDM(0x15) /* dsssPower Thresh1 */
+#define B43_LPPHY_MINPWR_LEVEL B43_PHY_OFDM(0x16) /* MinPower Level */
+#define B43_LPPHY_OFDMSYNCTHRESH0 B43_PHY_OFDM(0x17) /* ofdmSyncThresh0 */
+#define B43_LPPHY_OFDMSYNCTHRESH1 B43_PHY_OFDM(0x18) /* ofdmSyncThresh1 */
+#define B43_LPPHY_FINEFREQEST B43_PHY_OFDM(0x19) /* FineFreqEst */
+#define B43_LPPHY_IDLEAFTERPKTRXTO B43_PHY_OFDM(0x1A) /* IDLEafterPktRXTimeout */
+#define B43_LPPHY_LTRN_CTL B43_PHY_OFDM(0x1B) /* LTRN Control */
+#define B43_LPPHY_DCOFFSETTRANSIENT B43_PHY_OFDM(0x1C) /* DCOffsetTransient */
+#define B43_LPPHY_PREAMBLEINTO B43_PHY_OFDM(0x1D) /* PreambleInTimeout */
+#define B43_LPPHY_PREAMBLECONFIRMTO B43_PHY_OFDM(0x1E) /* PreambleConfirmTimeout */
+#define B43_LPPHY_CLIPTHRESH B43_PHY_OFDM(0x1F) /* ClipThresh */
+#define B43_LPPHY_CLIPCTRTHRESH B43_PHY_OFDM(0x20) /* ClipCtrThresh */
+#define B43_LPPHY_OFDMSYNCTIMER_CTL B43_PHY_OFDM(0x21) /* ofdmSyncTimer Control */
+#define B43_LPPHY_WAITFORPHYSELTO B43_PHY_OFDM(0x22) /* WaitforPHYSelTimeout */
+#define B43_LPPHY_HIGAINDB B43_PHY_OFDM(0x23) /* HiGainDB */
+#define B43_LPPHY_LOWGAINDB B43_PHY_OFDM(0x24) /* LowGainDB */
+#define B43_LPPHY_VERYLOWGAINDB B43_PHY_OFDM(0x25) /* VeryLowGainDB */
+#define B43_LPPHY_GAINMISMATCH B43_PHY_OFDM(0x26) /* gainMismatch */
+#define B43_LPPHY_GAINDIRECTMISMATCH B43_PHY_OFDM(0x27) /* gaindirectMismatch */
+#define B43_LPPHY_PWR_THRESH0 B43_PHY_OFDM(0x28) /* Power Thresh0 */
+#define B43_LPPHY_PWR_THRESH1 B43_PHY_OFDM(0x29) /* Power Thresh1 */
+#define B43_LPPHY_DETECTOR_DELAY_ADJUST B43_PHY_OFDM(0x2A) /* Detector Delay Adjust */
+#define B43_LPPHY_REDUCED_DETECTOR_DELAY B43_PHY_OFDM(0x2B) /* Reduced Detector Delay */
+#define B43_LPPHY_DATA_TO B43_PHY_OFDM(0x2C) /* data Timeout */
+#define B43_LPPHY_CORRELATOR_DIS_DELAY B43_PHY_OFDM(0x2D) /* correlator Dis Delay */
+#define B43_LPPHY_DIVERSITY_GAINBACK B43_PHY_OFDM(0x2E) /* Diversity GainBack */
+#define B43_LPPHY_DSSS_CONFIRM_CNT B43_PHY_OFDM(0x2F) /* DSSS Confirm Cnt */
+#define B43_LPPHY_DC_BLANK_INT B43_PHY_OFDM(0x30) /* DC Blank Interval */
+#define B43_LPPHY_GAIN_MISMATCH_LIMIT B43_PHY_OFDM(0x31) /* gain Mismatch Limit */
+#define B43_LPPHY_CRS_ED_THRESH B43_PHY_OFDM(0x32) /* crs ed thresh */
+#define B43_LPPHY_PHASE_SHIFT_CTL B43_PHY_OFDM(0x33) /* phase shift Control */
+#define B43_LPPHY_INPUT_PWRDB B43_PHY_OFDM(0x34) /* Input PowerDB */
+#define B43_LPPHY_OFDM_SYNC_CTL B43_PHY_OFDM(0x35) /* ofdm sync Control */
+#define B43_LPPHY_AFE_ADC_CTL_0 B43_PHY_OFDM(0x36) /* Afe ADC Control 0 */
+#define B43_LPPHY_AFE_ADC_CTL_1 B43_PHY_OFDM(0x37) /* Afe ADC Control 1 */
+#define B43_LPPHY_AFE_ADC_CTL_2 B43_PHY_OFDM(0x38) /* Afe ADC Control 2 */
+#define B43_LPPHY_AFE_DAC_CTL B43_PHY_OFDM(0x39) /* Afe DAC Control */
+#define B43_LPPHY_AFE_CTL B43_PHY_OFDM(0x3A) /* Afe Control */
+#define B43_LPPHY_AFE_CTL_OVR B43_PHY_OFDM(0x3B) /* Afe Control Ovr */
+#define B43_LPPHY_AFE_CTL_OVRVAL B43_PHY_OFDM(0x3C) /* Afe Control OvrVal */
+#define B43_LPPHY_AFE_RSSI_CTL_0 B43_PHY_OFDM(0x3D) /* Afe RSSI Control 0 */
+#define B43_LPPHY_AFE_RSSI_CTL_1 B43_PHY_OFDM(0x3E) /* Afe RSSI Control 1 */
+#define B43_LPPHY_AFE_RSSI_SEL B43_PHY_OFDM(0x3F) /* Afe RSSI Sel */
+#define B43_LPPHY_RADAR_THRESH B43_PHY_OFDM(0x40) /* Radar Thresh */
+#define B43_LPPHY_RADAR_BLANK_INT B43_PHY_OFDM(0x41) /* Radar blank Interval */
+#define B43_LPPHY_RADAR_MIN_FM_INT B43_PHY_OFDM(0x42) /* Radar min fm Interval */
+#define B43_LPPHY_RADAR_GAIN_TO B43_PHY_OFDM(0x43) /* Radar gain timeout */
+#define B43_LPPHY_RADAR_PULSE_TO B43_PHY_OFDM(0x44) /* Radar pulse timeout */
+#define B43_LPPHY_RADAR_DETECT_FM_CTL B43_PHY_OFDM(0x45) /* Radar detect FM Control */
+#define B43_LPPHY_RADAR_DETECT_EN B43_PHY_OFDM(0x46) /* Radar detect En */
+#define B43_LPPHY_RADAR_RD_DATA_REG B43_PHY_OFDM(0x47) /* Radar Rd Data Reg */
+#define B43_LPPHY_LP_PHY_CTL B43_PHY_OFDM(0x48) /* LP PHY Control */
+#define B43_LPPHY_CLASSIFIER_CTL B43_PHY_OFDM(0x49) /* classifier Control */
+#define B43_LPPHY_RESET_CTL B43_PHY_OFDM(0x4A) /* reset Control */
+#define B43_LPPHY_CLKEN_CTL B43_PHY_OFDM(0x4B) /* ClkEn Control */
+#define B43_LPPHY_RF_OVERRIDE_0 B43_PHY_OFDM(0x4C) /* RF Override 0 */
+#define B43_LPPHY_RF_OVERRIDE_VAL_0 B43_PHY_OFDM(0x4D) /* RF Override Val 0 */
+#define B43_LPPHY_TR_LOOKUP_1 B43_PHY_OFDM(0x4E) /* TR Lookup 1 */
+#define B43_LPPHY_TR_LOOKUP_2 B43_PHY_OFDM(0x4F) /* TR Lookup 2 */
+#define B43_LPPHY_RSSISELLOOKUP1 B43_PHY_OFDM(0x50) /* RssiSelLookup1 */
+#define B43_LPPHY_IQLO_CAL_CMD B43_PHY_OFDM(0x51) /* iqlo Cal Cmd */
+#define B43_LPPHY_IQLO_CAL_CMD_N_NUM B43_PHY_OFDM(0x52) /* iqlo Cal Cmd N num */
+#define B43_LPPHY_IQLO_CAL_CMD_G_CTL B43_PHY_OFDM(0x53) /* iqlo Cal Cmd G control */
+#define B43_LPPHY_MACINT_DBG_REGISTER B43_PHY_OFDM(0x54) /* macint Debug Register */
+#define B43_LPPHY_TABLE_ADDR B43_PHY_OFDM(0x55) /* Table Address */
+#define B43_LPPHY_TABLEDATALO B43_PHY_OFDM(0x56) /* TabledataLo */
+#define B43_LPPHY_TABLEDATAHI B43_PHY_OFDM(0x57) /* TabledataHi */
+#define B43_LPPHY_PHY_CRS_ENABLE_ADDR B43_PHY_OFDM(0x58) /* phy CRS Enable Address */
+#define B43_LPPHY_IDLETIME_CTL B43_PHY_OFDM(0x59) /* Idletime Control */
+#define B43_LPPHY_IDLETIME_CRS_ON_LO B43_PHY_OFDM(0x5A) /* Idletime CRS On Lo */
+#define B43_LPPHY_IDLETIME_CRS_ON_HI B43_PHY_OFDM(0x5B) /* Idletime CRS On Hi */
+#define B43_LPPHY_IDLETIME_MEAS_TIME_LO B43_PHY_OFDM(0x5C) /* Idletime Meas Time Lo */
+#define B43_LPPHY_IDLETIME_MEAS_TIME_HI B43_PHY_OFDM(0x5D) /* Idletime Meas Time Hi */
+#define B43_LPPHY_RESET_LEN_OFDM_TX_ADDR B43_PHY_OFDM(0x5E) /* Reset len Ofdm TX Address */
+#define B43_LPPHY_RESET_LEN_OFDM_RX_ADDR B43_PHY_OFDM(0x5F) /* Reset len Ofdm RX Address */
+#define B43_LPPHY_REG_CRS_ENABLE B43_PHY_OFDM(0x60) /* reg crs enable */
+#define B43_LPPHY_PLCP_TMT_STR0_CTR_MIN B43_PHY_OFDM(0x61) /* PLCP Tmt Str0 Ctr Min */
+#define B43_LPPHY_PKT_FSM_RESET_LEN_VAL B43_PHY_OFDM(0x62) /* Pkt fsm Reset Len Value */
+#define B43_LPPHY_READSYM2RESET_CTL B43_PHY_OFDM(0x63) /* readsym2reset Control */
+#define B43_LPPHY_DC_FILTER_DELAY1 B43_PHY_OFDM(0x64) /* Dc filter delay1 */
+#define B43_LPPHY_PACKET_RX_ACTIVE_TO B43_PHY_OFDM(0x65) /* packet rx Active timeout */
+#define B43_LPPHY_ED_TOVAL B43_PHY_OFDM(0x66) /* ed timeoutValue */
+#define B43_LPPHY_HOLD_CRS_ON_VAL B43_PHY_OFDM(0x67) /* hold CRS On Value */
+#define B43_LPPHY_OFDM_TX_PHY_CRS_DELAY_VAL B43_PHY_OFDM(0x69) /* ofdm tx phy CRS Delay Value */
+#define B43_LPPHY_CCK_TX_PHY_CRS_DELAY_VAL B43_PHY_OFDM(0x6A) /* cck tx phy CRS Delay Value */
+#define B43_LPPHY_ED_ON_CONFIRM_TIMER_VAL B43_PHY_OFDM(0x6B) /* Ed on confirm Timer Value */
+#define B43_LPPHY_ED_OFFSET_CONFIRM_TIMER_VAL B43_PHY_OFDM(0x6C) /* Ed offset confirm Timer Value */
+#define B43_LPPHY_PHY_CRS_OFFSET_TIMER_VAL B43_PHY_OFDM(0x6D) /* phy CRS offset Timer Value */
+#define B43_LPPHY_ADC_COMPENSATION_CTL B43_PHY_OFDM(0x70) /* ADC Compensation Control */
+#define B43_LPPHY_LOG2_RBPSK_ADDR B43_PHY_OFDM(0x71) /* log2 RBPSK Address */
+#define B43_LPPHY_LOG2_RQPSK_ADDR B43_PHY_OFDM(0x72) /* log2 RQPSK Address */
+#define B43_LPPHY_LOG2_R16QAM_ADDR B43_PHY_OFDM(0x73) /* log2 R16QAM Address */
+#define B43_LPPHY_LOG2_R64QAM_ADDR B43_PHY_OFDM(0x74) /* log2 R64QAM Address */
+#define B43_LPPHY_OFFSET_BPSK_ADDR B43_PHY_OFDM(0x75) /* offset BPSK Address */
+#define B43_LPPHY_OFFSET_QPSK_ADDR B43_PHY_OFDM(0x76) /* offset QPSK Address */
+#define B43_LPPHY_OFFSET_16QAM_ADDR B43_PHY_OFDM(0x77) /* offset 16QAM Address */
+#define B43_LPPHY_OFFSET_64QAM_ADDR B43_PHY_OFDM(0x78) /* offset 64QAM Address */
+#define B43_LPPHY_ALPHA1 B43_PHY_OFDM(0x79) /* Alpha1 */
+#define B43_LPPHY_ALPHA2 B43_PHY_OFDM(0x7A) /* Alpha2 */
+#define B43_LPPHY_BETA1 B43_PHY_OFDM(0x7B) /* Beta1 */
+#define B43_LPPHY_BETA2 B43_PHY_OFDM(0x7C) /* Beta2 */
+#define B43_LPPHY_LOOP_NUM_ADDR B43_PHY_OFDM(0x7D) /* Loop Num Address */
+#define B43_LPPHY_STR_COLLMAX_SMPL_ADDR B43_PHY_OFDM(0x7E) /* Str Collmax Sample Address */
+#define B43_LPPHY_MAX_SMPL_COARSE_FINE_ADDR B43_PHY_OFDM(0x7F) /* Max Sample Coarse/Fine Address */
+#define B43_LPPHY_MAX_SMPL_COARSE_STR0CTR_ADDR B43_PHY_OFDM(0x80) /* Max Sample Coarse/Str0Ctr Address */
+#define B43_LPPHY_IQ_ENABLE_WAIT_TIME_ADDR B43_PHY_OFDM(0x81) /* IQ Enable Wait Time Address */
+#define B43_LPPHY_IQ_NUM_SMPLS_ADDR B43_PHY_OFDM(0x82) /* IQ Num Samples Address */
+#define B43_LPPHY_IQ_ACC_HI_ADDR B43_PHY_OFDM(0x83) /* IQ Acc Hi Address */
+#define B43_LPPHY_IQ_ACC_LO_ADDR B43_PHY_OFDM(0x84) /* IQ Acc Lo Address */
+#define B43_LPPHY_IQ_I_PWR_ACC_HI_ADDR B43_PHY_OFDM(0x85) /* IQ I PWR Acc Hi Address */
+#define B43_LPPHY_IQ_I_PWR_ACC_LO_ADDR B43_PHY_OFDM(0x86) /* IQ I PWR Acc Lo Address */
+#define B43_LPPHY_IQ_Q_PWR_ACC_HI_ADDR B43_PHY_OFDM(0x87) /* IQ Q PWR Acc Hi Address */
+#define B43_LPPHY_IQ_Q_PWR_ACC_LO_ADDR B43_PHY_OFDM(0x88) /* IQ Q PWR Acc Lo Address */
+#define B43_LPPHY_MAXNUMSTEPS B43_PHY_OFDM(0x89) /* MaxNumsteps */
+#define B43_LPPHY_ROTORPHASE_ADDR B43_PHY_OFDM(0x8A) /* RotorPhase Address */
+#define B43_LPPHY_ADVANCEDRETARDROTOR_ADDR B43_PHY_OFDM(0x8B) /* AdvancedRetardRotor Address */
+#define B43_LPPHY_RSSIADCDELAY_CTL_ADDR B43_PHY_OFDM(0x8D) /* rssiAdcdelay Control Address */
+#define B43_LPPHY_TSSISTAT_ADDR B43_PHY_OFDM(0x8E) /* tssiStatus Address */
+#define B43_LPPHY_TEMPSENSESTAT_ADDR B43_PHY_OFDM(0x8F) /* tempsenseStatus Address */
+#define B43_LPPHY_TEMPSENSE_CTL_ADDR B43_PHY_OFDM(0x90) /* tempsense Control Address */
+#define B43_LPPHY_WRSSISTAT_ADDR B43_PHY_OFDM(0x91) /* wrssistatus Address */
+#define B43_LPPHY_MUFACTORADDR B43_PHY_OFDM(0x92) /* mufactoraddr */
+#define B43_LPPHY_SCRAMSTATE_ADDR B43_PHY_OFDM(0x93) /* scramstate Address */
+#define B43_LPPHY_TXHOLDOFFADDR B43_PHY_OFDM(0x94) /* txholdoffaddr */
+#define B43_LPPHY_PKTGAINVAL_ADDR B43_PHY_OFDM(0x95) /* pktgainval Address */
+#define B43_LPPHY_COARSEESTIM_ADDR B43_PHY_OFDM(0x96) /* Coarseestim Address */
+#define B43_LPPHY_STATE_TRANSITION_ADDR B43_PHY_OFDM(0x97) /* state Transition Address */
+#define B43_LPPHY_TRN_OFFSET_ADDR B43_PHY_OFDM(0x98) /* TRN offset Address */
+#define B43_LPPHY_NUM_ROTOR_ADDR B43_PHY_OFDM(0x99) /* Num Rotor Address */
+#define B43_LPPHY_VITERBI_OFFSET_ADDR B43_PHY_OFDM(0x9A) /* Viterbi Offset Address */
+#define B43_LPPHY_SMPL_COLLECT_WAIT_ADDR B43_PHY_OFDM(0x9B) /* Sample collect wait Address */
+#define B43_LPPHY_A_PHY_CTL_ADDR B43_PHY_OFDM(0x9C) /* A PHY Control Address */
+#define B43_LPPHY_NUM_PASS_THROUGH_ADDR B43_PHY_OFDM(0x9D) /* Num Pass Through Address */
+#define B43_LPPHY_RX_COMP_COEFF_S B43_PHY_OFDM(0x9E) /* RX Comp coefficient(s) */
+#define B43_LPPHY_CPAROTATEVAL B43_PHY_OFDM(0x9F) /* cpaRotateValue */
+#define B43_LPPHY_SMPL_PLAY_COUNT B43_PHY_OFDM(0xA0) /* Sample play count */
+#define B43_LPPHY_SMPL_PLAY_BUFFER_CTL B43_PHY_OFDM(0xA1) /* Sample play Buffer Control */
+#define B43_LPPHY_FOURWIRE_CTL B43_PHY_OFDM(0xA2) /* fourwire Control */
+#define B43_LPPHY_CPA_TAILCOUNT_VAL B43_PHY_OFDM(0xA3) /* CPA TailCount Value */
+#define B43_LPPHY_TX_PWR_CTL_CMD B43_PHY_OFDM(0xA4) /* TX Power Control Cmd */
+#define B43_LPPHY_TX_PWR_CTL_CMD_MODE 0xE000 /* TX power control mode mask */
+#define B43_LPPHY_TX_PWR_CTL_CMD_MODE_OFF 0x0000 /* TX power control is OFF */
+#define B43_LPPHY_TX_PWR_CTL_CMD_MODE_SW 0x8000 /* TX power control is SOFTWARE */
+#define B43_LPPHY_TX_PWR_CTL_CMD_MODE_HW 0xE000 /* TX power control is HARDWARE */
+#define B43_LPPHY_TX_PWR_CTL_NNUM B43_PHY_OFDM(0xA5) /* TX Power Control Nnum */
+#define B43_LPPHY_TX_PWR_CTL_IDLETSSI B43_PHY_OFDM(0xA6) /* TX Power Control IdleTssi */
+#define B43_LPPHY_TX_PWR_CTL_TARGETPWR B43_PHY_OFDM(0xA7) /* TX Power Control TargetPower */
+#define B43_LPPHY_TX_PWR_CTL_DELTAPWR_LIMIT B43_PHY_OFDM(0xA8) /* TX Power Control DeltaPower Limit */
+#define B43_LPPHY_TX_PWR_CTL_BASEINDEX B43_PHY_OFDM(0xA9) /* TX Power Control BaseIndex */
+#define B43_LPPHY_TX_PWR_CTL_PWR_INDEX B43_PHY_OFDM(0xAA) /* TX Power Control Power Index */
+#define B43_LPPHY_TX_PWR_CTL_STAT B43_PHY_OFDM(0xAB) /* TX Power Control Status */
+#define B43_LPPHY_LP_RF_SIGNAL_LUT B43_PHY_OFDM(0xAC) /* LP RF signal LUT */
+#define B43_LPPHY_RX_RADIO_CTL_FILTER_STATE B43_PHY_OFDM(0xAD) /* RX Radio Control Filter State */
+#define B43_LPPHY_RX_RADIO_CTL B43_PHY_OFDM(0xAE) /* RX Radio Control */
+#define B43_LPPHY_NRSSI_STAT_ADDR B43_PHY_OFDM(0xAF) /* NRSSI status Address */
+#define B43_LPPHY_RF_OVERRIDE_2 B43_PHY_OFDM(0xB0) /* RF override 2 */
+#define B43_LPPHY_RF_OVERRIDE_2_VAL B43_PHY_OFDM(0xB1) /* RF override 2 val */
+#define B43_LPPHY_PS_CTL_OVERRIDE_VAL0 B43_PHY_OFDM(0xB2) /* PS Control override val0 */
+#define B43_LPPHY_PS_CTL_OVERRIDE_VAL1 B43_PHY_OFDM(0xB3) /* PS Control override val1 */
+#define B43_LPPHY_PS_CTL_OVERRIDE_VAL2 B43_PHY_OFDM(0xB4) /* PS Control override val2 */
+#define B43_LPPHY_TX_GAIN_CTL_OVERRIDE_VAL B43_PHY_OFDM(0xB5) /* TX gain Control override val */
+#define B43_LPPHY_RX_GAIN_CTL_OVERRIDE_VAL B43_PHY_OFDM(0xB6) /* RX gain Control override val */
+#define B43_LPPHY_AFE_DDFS B43_PHY_OFDM(0xB7) /* AFE DDFS */
+#define B43_LPPHY_AFE_DDFS_POINTER_INIT B43_PHY_OFDM(0xB8) /* AFE DDFS pointer init */
+#define B43_LPPHY_AFE_DDFS_INCR_INIT B43_PHY_OFDM(0xB9) /* AFE DDFS incr init */
+#define B43_LPPHY_MRCNOISEREDUCTION B43_PHY_OFDM(0xBA) /* mrcNoiseReduction */
+#define B43_LPPHY_TRLOOKUP3 B43_PHY_OFDM(0xBB) /* TRLookup3 */
+#define B43_LPPHY_TRLOOKUP4 B43_PHY_OFDM(0xBC) /* TRLookup4 */
+#define B43_LPPHY_RADAR_FIFO_STAT B43_PHY_OFDM(0xBD) /* Radar FIFO Status */
+#define B43_LPPHY_GPIO_OUTEN B43_PHY_OFDM(0xBE) /* GPIO Out enable */
+#define B43_LPPHY_GPIO_SELECT B43_PHY_OFDM(0xBF) /* GPIO Select */
+#define B43_LPPHY_GPIO_OUT B43_PHY_OFDM(0xC0) /* GPIO Out */
+
+
+/* Radio register access decorators. */
#define B43_LP_RADIO(radio_reg) (radio_reg)
#define B43_LP_NORTH(radio_reg) B43_LP_RADIO(radio_reg)
#define B43_LP_SOUTH(radio_reg) B43_LP_RADIO((radio_reg) | 0x4000)
@@ -529,8 +806,58 @@
+enum b43_lpphy_txpctl_mode {
+ B43_LPPHY_TXPCTL_UNKNOWN = 0,
+ B43_LPPHY_TXPCTL_OFF, /* TX power control is OFF */
+ B43_LPPHY_TXPCTL_SW, /* TX power control is set to Software */
+ B43_LPPHY_TXPCTL_HW, /* TX power control is set to Hardware */
+};
+
struct b43_phy_lp {
- //TODO
+ /* Current TX power control mode. */
+ enum b43_lpphy_txpctl_mode txpctl_mode;
+
+ /* Transmit isolation medium band */
+ u8 tx_isolation_med_band; /* FIXME initial value? */
+ /* Transmit isolation low band */
+ u8 tx_isolation_low_band; /* FIXME initial value? */
+ /* Transmit isolation high band */
+ u8 tx_isolation_hi_band; /* FIXME initial value? */
+
+ /* Receive power offset */
+ u8 rx_pwr_offset; /* FIXME initial value? */
+
+ /* TSSI transmit count */
+ u16 tssi_tx_count;
+ /* TSSI index */
+ u16 tssi_idx; /* FIXME initial value? */
+ /* TSSI npt */
+ u16 tssi_npt; /* FIXME initial value? */
+
+ /* Target TX frequency */
+ u16 tgt_tx_freq; /* FIXME initial value? */
+
+ /* Transmit power index override */
+ s8 tx_pwr_idx_over; /* FIXME initial value? */
+
+ /* RSSI vf */
+ u8 rssi_vf; /* FIXME initial value? */
+ /* RSSI vc */
+ u8 rssi_vc; /* FIXME initial value? */
+ /* RSSI gs */
+ u8 rssi_gs; /* FIXME initial value? */
+
+ /* RC cap */
+ u8 rc_cap; /* FIXME initial value? */
+ /* BX arch */
+ u8 bx_arch; /* FIXME initial value? */
+
+ /* Full calibration channel */
+ u8 full_calib_chan; /* FIXME initial value? */
+
+ /* Transmit iqlocal best coeffs */
+ bool tx_iqloc_best_coeffs_valid;
+ u8 tx_iqloc_best_coeffs[11];
};
diff --git a/drivers/net/wireless/b43/pio.c b/drivers/net/wireless/b43/pio.c
index 1036bef8c4cc..8cd9776752e6 100644
--- a/drivers/net/wireless/b43/pio.c
+++ b/drivers/net/wireless/b43/pio.c
@@ -55,8 +55,8 @@ static u16 generate_cookie(struct b43_pio_txqueue *q,
}
static
-struct b43_pio_txqueue * parse_cookie(struct b43_wldev *dev,
- u16 cookie,
+struct b43_pio_txqueue *parse_cookie(struct b43_wldev *dev,
+ u16 cookie,
struct b43_pio_txpacket **pack)
{
struct b43_pio *pio = &dev->pio;
@@ -134,8 +134,8 @@ static u16 pio_rxqueue_offset(struct b43_wldev *dev)
return 8;
}
-static struct b43_pio_txqueue * b43_setup_pioqueue_tx(struct b43_wldev *dev,
- unsigned int index)
+static struct b43_pio_txqueue *b43_setup_pioqueue_tx(struct b43_wldev *dev,
+ unsigned int index)
{
struct b43_pio_txqueue *q;
struct b43_pio_txpacket *p;
@@ -171,8 +171,8 @@ static struct b43_pio_txqueue * b43_setup_pioqueue_tx(struct b43_wldev *dev,
return q;
}
-static struct b43_pio_rxqueue * b43_setup_pioqueue_rx(struct b43_wldev *dev,
- unsigned int index)
+static struct b43_pio_rxqueue *b43_setup_pioqueue_rx(struct b43_wldev *dev,
+ unsigned int index)
{
struct b43_pio_rxqueue *q;
@@ -308,8 +308,8 @@ err_destroy_bk:
}
/* Static mapping of mac80211's queues (priorities) to b43 PIO queues. */
-static struct b43_pio_txqueue * select_queue_by_priority(struct b43_wldev *dev,
- u8 queue_prio)
+static struct b43_pio_txqueue *select_queue_by_priority(struct b43_wldev *dev,
+ u8 queue_prio)
{
struct b43_pio_txqueue *q;
diff --git a/drivers/net/wireless/b43/rfkill.c b/drivers/net/wireless/b43/rfkill.c
index 713753781f40..afad42358693 100644
--- a/drivers/net/wireless/b43/rfkill.c
+++ b/drivers/net/wireless/b43/rfkill.c
@@ -113,7 +113,7 @@ out_unlock:
return err;
}
-char * b43_rfkill_led_name(struct b43_wldev *dev)
+char *b43_rfkill_led_name(struct b43_wldev *dev)
{
struct b43_rfkill *rfk = &(dev->wl->rfkill);
diff --git a/drivers/net/wireless/b43/tables_lpphy.c b/drivers/net/wireless/b43/tables_lpphy.c
new file mode 100644
index 000000000000..4ea734dce218
--- /dev/null
+++ b/drivers/net/wireless/b43/tables_lpphy.c
@@ -0,0 +1,394 @@
+/*
+
+ Broadcom B43 wireless driver
+ IEEE 802.11g LP-PHY and radio device data tables
+
+ Copyright (c) 2009 Michael Buesch <mb@bu3sch.de>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+
+*/
+
+#include "b43.h"
+#include "tables_lpphy.h"
+#include "phy_common.h"
+#include "phy_lp.h"
+
+
+/* Entry of the 2062 radio init table */
+struct b2062_init_tab_entry {
+ u16 offset;
+ u16 value_a;
+ u16 value_g;
+ u8 flags;
+};
+#define B2062_FLAG_A 0x01 /* Flag: Init in A mode */
+#define B2062_FLAG_G 0x02 /* Flag: Init in G mode */
+
+static const struct b2062_init_tab_entry b2062_init_tab[] = {
+ /* { .offset = B2062_N_COMM1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = 0x0001, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_COMM2, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_COMM3, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ { .offset = B2062_N_COMM4, .value_a = 0x0001, .value_g = 0x0000, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ /* { .offset = B2062_N_COMM5, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_COMM6, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_COMM7, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_COMM8, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_COMM9, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_COMM10, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_COMM11, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_COMM12, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_COMM13, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_COMM14, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_COMM15, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_PDN_CTL0, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ { .offset = B2062_N_PDN_CTL1, .value_a = 0x0000, .value_g = 0x00CA, .flags = B2062_FLAG_G, },
+ /* { .offset = B2062_N_PDN_CTL2, .value_a = 0x0018, .value_g = 0x0018, .flags = 0, }, */
+ { .offset = B2062_N_PDN_CTL3, .value_a = 0x0000, .value_g = 0x0000, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ { .offset = B2062_N_PDN_CTL4, .value_a = 0x0015, .value_g = 0x002A, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ /* { .offset = B2062_N_GEN_CTL0, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_IQ_CALIB, .value_a = 0x0001, .value_g = 0x0001, .flags = 0, }, */
+ { .offset = B2062_N_LGENC, .value_a = 0x00DB, .value_g = 0x00FF, .flags = B2062_FLAG_A, },
+ /* { .offset = B2062_N_LGENA_LPF, .value_a = 0x0001, .value_g = 0x0001, .flags = 0, }, */
+ /* { .offset = B2062_N_LGENA_BIAS0, .value_a = 0x0041, .value_g = 0x0041, .flags = 0, }, */
+ /* { .offset = B2062_N_LGNEA_BIAS1, .value_a = 0x0002, .value_g = 0x0002, .flags = 0, }, */
+ /* { .offset = B2062_N_LGENA_CTL0, .value_a = 0x0032, .value_g = 0x0032, .flags = 0, }, */
+ /* { .offset = B2062_N_LGENA_CTL1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_LGENA_CTL2, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ { .offset = B2062_N_LGENA_TUNE0, .value_a = 0x00DD, .value_g = 0x0000, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ /* { .offset = B2062_N_LGENA_TUNE1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ { .offset = B2062_N_LGENA_TUNE2, .value_a = 0x00DD, .value_g = 0x0000, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ { .offset = B2062_N_LGENA_TUNE3, .value_a = 0x0077, .value_g = 0x00B5, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ { .offset = B2062_N_LGENA_CTL3, .value_a = 0x0000, .value_g = 0x00FF, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ /* { .offset = B2062_N_LGENA_CTL4, .value_a = 0x001F, .value_g = 0x001F, .flags = 0, }, */
+ /* { .offset = B2062_N_LGENA_CTL5, .value_a = 0x0032, .value_g = 0x0032, .flags = 0, }, */
+ /* { .offset = B2062_N_LGENA_CTL6, .value_a = 0x0032, .value_g = 0x0032, .flags = 0, }, */
+ { .offset = B2062_N_LGENA_CTL7, .value_a = 0x0033, .value_g = 0x0033, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ /* { .offset = B2062_N_RXA_CTL0, .value_a = 0x0009, .value_g = 0x0009, .flags = 0, }, */
+ { .offset = B2062_N_RXA_CTL1, .value_a = 0x0000, .value_g = 0x0000, .flags = B2062_FLAG_G, },
+ /* { .offset = B2062_N_RXA_CTL2, .value_a = 0x0018, .value_g = 0x0018, .flags = 0, }, */
+ /* { .offset = B2062_N_RXA_CTL3, .value_a = 0x0027, .value_g = 0x0027, .flags = 0, }, */
+ /* { .offset = B2062_N_RXA_CTL4, .value_a = 0x0028, .value_g = 0x0028, .flags = 0, }, */
+ /* { .offset = B2062_N_RXA_CTL5, .value_a = 0x0007, .value_g = 0x0007, .flags = 0, }, */
+ /* { .offset = B2062_N_RXA_CTL6, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_RXA_CTL7, .value_a = 0x0008, .value_g = 0x0008, .flags = 0, }, */
+ { .offset = B2062_N_RXBB_CTL0, .value_a = 0x0082, .value_g = 0x0080, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ /* { .offset = B2062_N_RXBB_CTL1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_RXBB_CTL2, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_RXBB_GAIN0, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ { .offset = B2062_N_RXBB_GAIN1, .value_a = 0x0004, .value_g = 0x0004, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ { .offset = B2062_N_RXBB_GAIN2, .value_a = 0x0000, .value_g = 0x0000, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ /* { .offset = B2062_N_RXBB_GAIN3, .value_a = 0x0011, .value_g = 0x0011, .flags = 0, }, */
+ /* { .offset = B2062_N_RXBB_RSSI0, .value_a = 0x0043, .value_g = 0x0043, .flags = 0, }, */
+ /* { .offset = B2062_N_RXBB_RSSI1, .value_a = 0x0033, .value_g = 0x0033, .flags = 0, }, */
+ /* { .offset = B2062_N_RXBB_CALIB0, .value_a = 0x0010, .value_g = 0x0010, .flags = 0, }, */
+ /* { .offset = B2062_N_RXBB_CALIB1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_RXBB_CALIB2, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_RXBB_BIAS0, .value_a = 0x0006, .value_g = 0x0006, .flags = 0, }, */
+ /* { .offset = B2062_N_RXBB_BIAS1, .value_a = 0x002A, .value_g = 0x002A, .flags = 0, }, */
+ /* { .offset = B2062_N_RXBB_BIAS2, .value_a = 0x00AA, .value_g = 0x00AA, .flags = 0, }, */
+ /* { .offset = B2062_N_RXBB_BIAS3, .value_a = 0x0021, .value_g = 0x0021, .flags = 0, }, */
+ /* { .offset = B2062_N_RXBB_BIAS4, .value_a = 0x00AA, .value_g = 0x00AA, .flags = 0, }, */
+ /* { .offset = B2062_N_RXBB_BIAS5, .value_a = 0x0022, .value_g = 0x0022, .flags = 0, }, */
+ /* { .offset = B2062_N_RXBB_RSSI2, .value_a = 0x0001, .value_g = 0x0001, .flags = 0, }, */
+ /* { .offset = B2062_N_RXBB_RSSI3, .value_a = 0x0055, .value_g = 0x0055, .flags = 0, }, */
+ /* { .offset = B2062_N_RXBB_RSSI4, .value_a = 0x0001, .value_g = 0x0001, .flags = 0, }, */
+ /* { .offset = B2062_N_RXBB_RSSI5, .value_a = 0x0055, .value_g = 0x0055, .flags = 0, }, */
+ /* { .offset = B2062_N_TX_CTL0, .value_a = 0x0001, .value_g = 0x0001, .flags = 0, }, */
+ /* { .offset = B2062_N_TX_CTL1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_TX_CTL2, .value_a = 0x0084, .value_g = 0x0084, .flags = 0, }, */
+ /* { .offset = B2062_N_TX_CTL3, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ { .offset = B2062_N_TX_CTL4, .value_a = 0x0003, .value_g = 0x0003, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ { .offset = B2062_N_TX_CTL5, .value_a = 0x0002, .value_g = 0x0002, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ /* { .offset = B2062_N_TX_CTL6, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_TX_CTL7, .value_a = 0x0058, .value_g = 0x0058, .flags = 0, }, */
+ /* { .offset = B2062_N_TX_CTL8, .value_a = 0x0082, .value_g = 0x0082, .flags = 0, }, */
+ /* { .offset = B2062_N_TX_CTL9, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_TX_CTL_A, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_TX_GC2G, .value_a = 0x00FF, .value_g = 0x00FF, .flags = 0, }, */
+ /* { .offset = B2062_N_TX_GC5G, .value_a = 0x00FF, .value_g = 0x00FF, .flags = 0, }, */
+ { .offset = B2062_N_TX_TUNE, .value_a = 0x0088, .value_g = 0x001B, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ /* { .offset = B2062_N_TX_PAD, .value_a = 0x0088, .value_g = 0x0088, .flags = 0, }, */
+ /* { .offset = B2062_N_TX_PGA, .value_a = 0x0088, .value_g = 0x0088, .flags = 0, }, */
+ /* { .offset = B2062_N_TX_PADAUX, .value_a = 0x0033, .value_g = 0x0033, .flags = 0, }, */
+ /* { .offset = B2062_N_TX_PGAAUX, .value_a = 0x0033, .value_g = 0x0033, .flags = 0, }, */
+ /* { .offset = B2062_N_TSSI_CTL0, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_TSSI_CTL1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_TSSI_CTL2, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_IQ_CALIB_CTL0, .value_a = 0x0033, .value_g = 0x0033, .flags = 0, }, */
+ /* { .offset = B2062_N_IQ_CALIB_CTL1, .value_a = 0x0055, .value_g = 0x0055, .flags = 0, }, */
+ /* { .offset = B2062_N_IQ_CALIB_CTL2, .value_a = 0x0032, .value_g = 0x0032, .flags = 0, }, */
+ /* { .offset = B2062_N_CALIB_TS, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_CALIB_CTL0, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_CALIB_CTL1, .value_a = 0x0015, .value_g = 0x0015, .flags = 0, }, */
+ /* { .offset = B2062_N_CALIB_CTL2, .value_a = 0x000F, .value_g = 0x000F, .flags = 0, }, */
+ /* { .offset = B2062_N_CALIB_CTL3, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_CALIB_CTL4, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_CALIB_DBG0, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_CALIB_DBG1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_CALIB_DBG2, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_CALIB_DBG3, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_PSENSE_CTL0, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_PSENSE_CTL1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_PSENSE_CTL2, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_TEST_BUF0, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_COMM1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_RADIO_ID_CODE, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_COMM2, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_COMM3, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ { .offset = B2062_S_COMM4, .value_a = 0x0001, .value_g = 0x0000, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ /* { .offset = B2062_S_COMM5, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_COMM6, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_COMM7, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_COMM8, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_COMM9, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_COMM10, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_COMM11, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_COMM12, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_COMM13, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_COMM14, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_COMM15, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ { .offset = B2062_S_PDS_CTL0, .value_a = 0x00FF, .value_g = 0x00FF, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ /* { .offset = B2062_S_PDS_CTL1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_PDS_CTL2, .value_a = 0x008E, .value_g = 0x008E, .flags = 0, }, */
+ /* { .offset = B2062_S_PDS_CTL3, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_BG_CTL0, .value_a = 0x0006, .value_g = 0x0006, .flags = 0, }, */
+ /* { .offset = B2062_S_BG_CTL1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_BG_CTL2, .value_a = 0x0011, .value_g = 0x0011, .flags = 0, }, */
+ { .offset = B2062_S_LGENG_CTL0, .value_a = 0x00F8, .value_g = 0x00D8, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ { .offset = B2062_S_LGENG_CTL1, .value_a = 0x003C, .value_g = 0x0024, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ /* { .offset = B2062_S_LGENG_CTL2, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_LGENG_CTL3, .value_a = 0x0041, .value_g = 0x0041, .flags = 0, }, */
+ /* { .offset = B2062_S_LGENG_CTL4, .value_a = 0x0002, .value_g = 0x0002, .flags = 0, }, */
+ /* { .offset = B2062_S_LGENG_CTL5, .value_a = 0x0033, .value_g = 0x0033, .flags = 0, }, */
+ /* { .offset = B2062_S_LGENG_CTL6, .value_a = 0x0022, .value_g = 0x0022, .flags = 0, }, */
+ /* { .offset = B2062_S_LGENG_CTL7, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ { .offset = B2062_S_LGENG_CTL8, .value_a = 0x0088, .value_g = 0x0080, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ /* { .offset = B2062_S_LGENG_CTL9, .value_a = 0x0088, .value_g = 0x0088, .flags = 0, }, */
+ { .offset = B2062_S_LGENG_CTL10, .value_a = 0x0088, .value_g = 0x0080, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ /* { .offset = B2062_S_LGENG_CTL11, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_REFPLL_CTL0, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_REFPLL_CTL1, .value_a = 0x0007, .value_g = 0x0007, .flags = 0, }, */
+ /* { .offset = B2062_S_REFPLL_CTL2, .value_a = 0x00AF, .value_g = 0x00AF, .flags = 0, }, */
+ /* { .offset = B2062_S_REFPLL_CTL3, .value_a = 0x0012, .value_g = 0x0012, .flags = 0, }, */
+ /* { .offset = B2062_S_REFPLL_CTL4, .value_a = 0x000B, .value_g = 0x000B, .flags = 0, }, */
+ /* { .offset = B2062_S_REFPLL_CTL5, .value_a = 0x005F, .value_g = 0x005F, .flags = 0, }, */
+ /* { .offset = B2062_S_REFPLL_CTL6, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_REFPLL_CTL7, .value_a = 0x0040, .value_g = 0x0040, .flags = 0, }, */
+ /* { .offset = B2062_S_REFPLL_CTL8, .value_a = 0x0052, .value_g = 0x0052, .flags = 0, }, */
+ /* { .offset = B2062_S_REFPLL_CTL9, .value_a = 0x0026, .value_g = 0x0026, .flags = 0, }, */
+ /* { .offset = B2062_S_REFPLL_CTL10, .value_a = 0x0003, .value_g = 0x0003, .flags = 0, }, */
+ /* { .offset = B2062_S_REFPLL_CTL11, .value_a = 0x0036, .value_g = 0x0036, .flags = 0, }, */
+ /* { .offset = B2062_S_REFPLL_CTL12, .value_a = 0x0057, .value_g = 0x0057, .flags = 0, }, */
+ /* { .offset = B2062_S_REFPLL_CTL13, .value_a = 0x0011, .value_g = 0x0011, .flags = 0, }, */
+ /* { .offset = B2062_S_REFPLL_CTL14, .value_a = 0x0075, .value_g = 0x0075, .flags = 0, }, */
+ /* { .offset = B2062_S_REFPLL_CTL15, .value_a = 0x00B4, .value_g = 0x00B4, .flags = 0, }, */
+ /* { .offset = B2062_S_REFPLL_CTL16, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ { .offset = B2062_S_RFPLL_CTL0, .value_a = 0x0098, .value_g = 0x0098, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ { .offset = B2062_S_RFPLL_CTL1, .value_a = 0x0010, .value_g = 0x0010, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ /* { .offset = B2062_S_RFPLL_CTL2, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_RFPLL_CTL3, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_RFPLL_CTL4, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ { .offset = B2062_S_RFPLL_CTL5, .value_a = 0x0043, .value_g = 0x0043, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ { .offset = B2062_S_RFPLL_CTL6, .value_a = 0x0047, .value_g = 0x0047, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ { .offset = B2062_S_RFPLL_CTL7, .value_a = 0x000C, .value_g = 0x000C, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ { .offset = B2062_S_RFPLL_CTL8, .value_a = 0x0011, .value_g = 0x0011, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ { .offset = B2062_S_RFPLL_CTL9, .value_a = 0x0011, .value_g = 0x0011, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ { .offset = B2062_S_RFPLL_CTL10, .value_a = 0x000E, .value_g = 0x000E, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ { .offset = B2062_S_RFPLL_CTL11, .value_a = 0x0008, .value_g = 0x0008, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ { .offset = B2062_S_RFPLL_CTL12, .value_a = 0x0033, .value_g = 0x0033, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ { .offset = B2062_S_RFPLL_CTL13, .value_a = 0x000A, .value_g = 0x000A, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ { .offset = B2062_S_RFPLL_CTL14, .value_a = 0x0006, .value_g = 0x0006, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ /* { .offset = B2062_S_RFPLL_CTL15, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_RFPLL_CTL16, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_RFPLL_CTL17, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ { .offset = B2062_S_RFPLL_CTL18, .value_a = 0x003E, .value_g = 0x003E, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ { .offset = B2062_S_RFPLL_CTL19, .value_a = 0x0013, .value_g = 0x0013, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ /* { .offset = B2062_S_RFPLL_CTL20, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ { .offset = B2062_S_RFPLL_CTL21, .value_a = 0x0062, .value_g = 0x0062, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ { .offset = B2062_S_RFPLL_CTL22, .value_a = 0x0007, .value_g = 0x0007, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ { .offset = B2062_S_RFPLL_CTL23, .value_a = 0x0016, .value_g = 0x0016, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ { .offset = B2062_S_RFPLL_CTL24, .value_a = 0x005C, .value_g = 0x005C, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ { .offset = B2062_S_RFPLL_CTL25, .value_a = 0x0095, .value_g = 0x0095, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ /* { .offset = B2062_S_RFPLL_CTL26, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_RFPLL_CTL27, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_RFPLL_CTL28, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_RFPLL_CTL29, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ { .offset = B2062_S_RFPLL_CTL30, .value_a = 0x00A0, .value_g = 0x00A0, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ { .offset = B2062_S_RFPLL_CTL31, .value_a = 0x0004, .value_g = 0x0004, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ /* { .offset = B2062_S_RFPLL_CTL32, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ { .offset = B2062_S_RFPLL_CTL33, .value_a = 0x00CC, .value_g = 0x00CC, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ { .offset = B2062_S_RFPLL_CTL34, .value_a = 0x0007, .value_g = 0x0007, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ /* { .offset = B2062_S_RXG_CNT0, .value_a = 0x0010, .value_g = 0x0010, .flags = 0, }, */
+ /* { .offset = B2062_S_RXG_CNT1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_RXG_CNT2, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_RXG_CNT3, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_RXG_CNT4, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_RXG_CNT5, .value_a = 0x0055, .value_g = 0x0055, .flags = 0, }, */
+ /* { .offset = B2062_S_RXG_CNT6, .value_a = 0x0055, .value_g = 0x0055, .flags = 0, }, */
+ /* { .offset = B2062_S_RXG_CNT7, .value_a = 0x0005, .value_g = 0x0005, .flags = 0, }, */
+ { .offset = B2062_S_RXG_CNT8, .value_a = 0x000F, .value_g = 0x000F, .flags = B2062_FLAG_A, },
+ /* { .offset = B2062_S_RXG_CNT9, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_RXG_CNT10, .value_a = 0x0055, .value_g = 0x0055, .flags = 0, }, */
+ /* { .offset = B2062_S_RXG_CNT11, .value_a = 0x0066, .value_g = 0x0066, .flags = 0, }, */
+ /* { .offset = B2062_S_RXG_CNT12, .value_a = 0x0055, .value_g = 0x0055, .flags = 0, }, */
+ /* { .offset = B2062_S_RXG_CNT13, .value_a = 0x0044, .value_g = 0x0044, .flags = 0, }, */
+ /* { .offset = B2062_S_RXG_CNT14, .value_a = 0x00A0, .value_g = 0x00A0, .flags = 0, }, */
+ /* { .offset = B2062_S_RXG_CNT15, .value_a = 0x0004, .value_g = 0x0004, .flags = 0, }, */
+ /* { .offset = B2062_S_RXG_CNT16, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_RXG_CNT17, .value_a = 0x0055, .value_g = 0x0055, .flags = 0, }, */
+};
+
+void b2062_upload_init_table(struct b43_wldev *dev)
+{
+ const struct b2062_init_tab_entry *e;
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(b2062_init_tab); i++) {
+ e = &b2062_init_tab[i];
+ if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
+ if (!(e->flags & B2062_FLAG_G))
+ continue;
+ b43_radio_write(dev, e->offset, e->value_g);
+ } else {
+ if (!(e->flags & B2062_FLAG_A))
+ continue;
+ b43_radio_write(dev, e->offset, e->value_a);
+ }
+ }
+}
+
+u32 b43_lptab_read(struct b43_wldev *dev, u32 offset)
+{
+ u32 type, value;
+
+ type = offset & B43_LPTAB_TYPEMASK;
+ offset &= ~B43_LPTAB_TYPEMASK;
+ B43_WARN_ON(offset > 0xFFFF);
+
+ switch (type) {
+ case B43_LPTAB_8BIT:
+ b43_phy_write(dev, B43_LPPHY_TABLE_ADDR, offset);
+ value = b43_phy_read(dev, B43_LPPHY_TABLEDATALO) & 0xFF;
+ break;
+ case B43_LPTAB_16BIT:
+ b43_phy_write(dev, B43_LPPHY_TABLE_ADDR, offset);
+ value = b43_phy_read(dev, B43_LPPHY_TABLEDATALO);
+ break;
+ case B43_LPTAB_32BIT:
+ b43_phy_write(dev, B43_LPPHY_TABLE_ADDR, offset);
+ value = b43_phy_read(dev, B43_LPPHY_TABLEDATAHI);
+ value <<= 16;
+ value |= b43_phy_read(dev, B43_LPPHY_TABLEDATALO);
+ break;
+ default:
+ B43_WARN_ON(1);
+ value = 0;
+ }
+
+ return value;
+}
+
+void b43_lptab_read_bulk(struct b43_wldev *dev, u32 offset,
+ unsigned int nr_elements, void *_data)
+{
+ u32 type, value;
+ u8 *data = _data;
+ unsigned int i;
+
+ type = offset & B43_LPTAB_TYPEMASK;
+ for (i = 0; i < nr_elements; i++) {
+ value = b43_lptab_read(dev, offset);
+ switch (type) {
+ case B43_LPTAB_8BIT:
+ *data = value;
+ data++;
+ break;
+ case B43_LPTAB_16BIT:
+ *((u16 *)data) = value;
+ data += 2;
+ break;
+ case B43_LPTAB_32BIT:
+ *((u32 *)data) = value;
+ data += 4;
+ break;
+ default:
+ B43_WARN_ON(1);
+ }
+ offset++;
+ }
+}
+
+void b43_lptab_write(struct b43_wldev *dev, u32 offset, u32 value)
+{
+ u32 type;
+
+ type = offset & B43_LPTAB_TYPEMASK;
+ offset &= ~B43_LPTAB_TYPEMASK;
+ B43_WARN_ON(offset > 0xFFFF);
+
+ switch (type) {
+ case B43_LPTAB_8BIT:
+ B43_WARN_ON(value & ~0xFF);
+ b43_phy_write(dev, B43_LPPHY_TABLE_ADDR, offset);
+ b43_phy_write(dev, B43_LPPHY_TABLEDATALO, value);
+ break;
+ case B43_LPTAB_16BIT:
+ B43_WARN_ON(value & ~0xFFFF);
+ b43_phy_write(dev, B43_LPPHY_TABLE_ADDR, offset);
+ b43_phy_write(dev, B43_LPPHY_TABLEDATALO, value);
+ break;
+ case B43_LPTAB_32BIT:
+ b43_phy_write(dev, B43_LPPHY_TABLE_ADDR, offset);
+ b43_phy_write(dev, B43_LPPHY_TABLEDATAHI, value >> 16);
+ b43_phy_write(dev, B43_LPPHY_TABLEDATALO, value);
+ break;
+ default:
+ B43_WARN_ON(1);
+ }
+}
+
+void b43_lptab_write_bulk(struct b43_wldev *dev, u32 offset,
+ unsigned int nr_elements, const void *_data)
+{
+ u32 type, value;
+ const u8 *data = _data;
+ unsigned int i;
+
+ type = offset & B43_LPTAB_TYPEMASK;
+ for (i = 0; i < nr_elements; i++) {
+ switch (type) {
+ case B43_LPTAB_8BIT:
+ value = *data;
+ data++;
+ break;
+ case B43_LPTAB_16BIT:
+ value = *((u16 *)data);
+ data += 2;
+ break;
+ case B43_LPTAB_32BIT:
+ value = *((u32 *)data);
+ data += 4;
+ break;
+ default:
+ B43_WARN_ON(1);
+ value = 0;
+ }
+ b43_lptab_write(dev, offset, value);
+ offset++;
+ }
+}
diff --git a/drivers/net/wireless/b43/tables_lpphy.h b/drivers/net/wireless/b43/tables_lpphy.h
new file mode 100644
index 000000000000..0b8d02895a5d
--- /dev/null
+++ b/drivers/net/wireless/b43/tables_lpphy.h
@@ -0,0 +1,31 @@
+#ifndef B43_TABLES_LPPHY_H_
+#define B43_TABLES_LPPHY_H_
+
+
+#define B43_LPTAB_TYPEMASK 0xF0000000
+#define B43_LPTAB_8BIT 0x10000000
+#define B43_LPTAB_16BIT 0x20000000
+#define B43_LPTAB_32BIT 0x30000000
+#define B43_LPTAB8(table, offset) (((table) << 10) | (offset) | B43_LPTAB_8BIT)
+#define B43_LPTAB16(table, offset) (((table) << 10) | (offset) | B43_LPTAB_16BIT)
+#define B43_LPTAB32(table, offset) (((table) << 10) | (offset) | B43_LPTAB_32BIT)
+
+/* Table definitions */
+#define B43_LPTAB_TXPWR_R2PLUS B43_LPTAB32(0x07, 0) /* TX power lookup table (rev >= 2) */
+#define B43_LPTAB_TXPWR_R0_1 B43_LPTAB32(0xA0, 0) /* TX power lookup table (rev < 2) */
+
+u32 b43_lptab_read(struct b43_wldev *dev, u32 offset);
+void b43_lptab_write(struct b43_wldev *dev, u32 offset, u32 value);
+
+/* Bulk table access. Note that these functions return the bulk data in
+ * host endianness! The returned data is _not_ a bytearray, but an array
+ * consisting of nr_elements of the data type. */
+void b43_lptab_read_bulk(struct b43_wldev *dev, u32 offset,
+ unsigned int nr_elements, void *data);
+void b43_lptab_write_bulk(struct b43_wldev *dev, u32 offset,
+ unsigned int nr_elements, const void *data);
+
+void b2062_upload_init_table(struct b43_wldev *dev);
+
+
+#endif /* B43_TABLES_LPPHY_H_ */
diff --git a/drivers/net/wireless/b43/wa.c b/drivers/net/wireless/b43/wa.c
index 0c0fb15abb9f..e1e20f69f6d7 100644
--- a/drivers/net/wireless/b43/wa.c
+++ b/drivers/net/wireless/b43/wa.c
@@ -62,8 +62,7 @@ void b43_wa_initgains(struct b43_wldev *dev)
struct b43_phy *phy = &dev->phy;
b43_phy_write(dev, B43_PHY_LNAHPFCTL, 0x1FF9);
- b43_phy_write(dev, B43_PHY_LPFGAINCTL,
- b43_phy_read(dev, B43_PHY_LPFGAINCTL) & 0xFF0F);
+ b43_phy_mask(dev, B43_PHY_LPFGAINCTL, 0xFF0F);
if (phy->rev <= 2)
b43_ofdmtab_write16(dev, B43_OFDMTAB_LPFGAIN, 0, 0x1FBF);
b43_radio_write16(dev, 0x0002, 0x1FBF);
@@ -73,11 +72,9 @@ void b43_wa_initgains(struct b43_wldev *dev)
b43_phy_write(dev, 0x001D, 0x0F40);
b43_phy_write(dev, 0x001F, 0x1C00);
if (phy->rev <= 3)
- b43_phy_write(dev, 0x002A,
- (b43_phy_read(dev, 0x002A) & 0x00FF) | 0x0400);
+ b43_phy_maskset(dev, 0x002A, 0x00FF, 0x0400);
else if (phy->rev == 5) {
- b43_phy_write(dev, 0x002A,
- (b43_phy_read(dev, 0x002A) & 0x00FF) | 0x1A00);
+ b43_phy_maskset(dev, 0x002A, 0x00FF, 0x1A00);
b43_phy_write(dev, 0x00CC, 0x2121);
}
if (phy->rev >= 3)
@@ -86,7 +83,7 @@ void b43_wa_initgains(struct b43_wldev *dev)
static void b43_wa_divider(struct b43_wldev *dev)
{
- b43_phy_write(dev, 0x002B, b43_phy_read(dev, 0x002B) & ~0x0100);
+ b43_phy_mask(dev, 0x002B, ~0x0100);
b43_phy_write(dev, 0x008E, 0x58C1);
}
@@ -272,8 +269,7 @@ static void b43_wa_2060txlna_gain(struct b43_wldev *dev)
static void b43_wa_lms(struct b43_wldev *dev)
{
- b43_phy_write(dev, 0x0055,
- (b43_phy_read(dev, 0x0055) & 0xFFC0) | 0x0004);
+ b43_phy_maskset(dev, 0x0055, 0xFFC0, 0x0004);
}
static void b43_wa_mixedsignal(struct b43_wldev *dev)
@@ -318,23 +314,18 @@ static void b43_wa_crs_ed(struct b43_wldev *dev)
} else if (phy->rev == 2) {
b43_phy_write(dev, B43_PHY_CRSTHRES1, 0x1861);
b43_phy_write(dev, B43_PHY_CRSTHRES2, 0x0271);
- b43_phy_write(dev, B43_PHY_ANTDWELL,
- b43_phy_read(dev, B43_PHY_ANTDWELL)
- | 0x0800);
+ b43_phy_set(dev, B43_PHY_ANTDWELL, 0x0800);
} else {
b43_phy_write(dev, B43_PHY_CRSTHRES1, 0x0098);
b43_phy_write(dev, B43_PHY_CRSTHRES2, 0x0070);
b43_phy_write(dev, B43_PHY_OFDM(0xC9), 0x0080);
- b43_phy_write(dev, B43_PHY_ANTDWELL,
- b43_phy_read(dev, B43_PHY_ANTDWELL)
- | 0x0800);
+ b43_phy_set(dev, B43_PHY_ANTDWELL, 0x0800);
}
}
static void b43_wa_crs_thr(struct b43_wldev *dev)
{
- b43_phy_write(dev, B43_PHY_CRS0,
- (b43_phy_read(dev, B43_PHY_CRS0) & ~0x03C0) | 0xD000);
+ b43_phy_maskset(dev, B43_PHY_CRS0, ~0x03C0, 0xD000);
}
static void b43_wa_crs_blank(struct b43_wldev *dev)
@@ -391,72 +382,45 @@ static void b43_wa_altagc(struct b43_wldev *dev)
b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 3, 25);
}
- b43_phy_write(dev, B43_PHY_CCKSHIFTBITS_WA,
- (b43_phy_read(dev, B43_PHY_CCKSHIFTBITS_WA) & ~0xFF00) | 0x5700);
- b43_phy_write(dev, B43_PHY_OFDM(0x1A),
- (b43_phy_read(dev, B43_PHY_OFDM(0x1A)) & ~0x007F) | 0x000F);
- b43_phy_write(dev, B43_PHY_OFDM(0x1A),
- (b43_phy_read(dev, B43_PHY_OFDM(0x1A)) & ~0x3F80) | 0x2B80);
- b43_phy_write(dev, B43_PHY_ANTWRSETT,
- (b43_phy_read(dev, B43_PHY_ANTWRSETT) & 0xF0FF) | 0x0300);
- b43_radio_write16(dev, 0x7A,
- b43_radio_read16(dev, 0x7A) | 0x0008);
- b43_phy_write(dev, B43_PHY_N1P1GAIN,
- (b43_phy_read(dev, B43_PHY_N1P1GAIN) & ~0x000F) | 0x0008);
- b43_phy_write(dev, B43_PHY_P1P2GAIN,
- (b43_phy_read(dev, B43_PHY_P1P2GAIN) & ~0x0F00) | 0x0600);
- b43_phy_write(dev, B43_PHY_N1N2GAIN,
- (b43_phy_read(dev, B43_PHY_N1N2GAIN) & ~0x0F00) | 0x0700);
- b43_phy_write(dev, B43_PHY_N1P1GAIN,
- (b43_phy_read(dev, B43_PHY_N1P1GAIN) & ~0x0F00) | 0x0100);
+ b43_phy_maskset(dev, B43_PHY_CCKSHIFTBITS_WA, (u16)~0xFF00, 0x5700);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0x1A), ~0x007F, 0x000F);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0x1A), ~0x3F80, 0x2B80);
+ b43_phy_maskset(dev, B43_PHY_ANTWRSETT, 0xF0FF, 0x0300);
+ b43_radio_set(dev, 0x7A, 0x0008);
+ b43_phy_maskset(dev, B43_PHY_N1P1GAIN, ~0x000F, 0x0008);
+ b43_phy_maskset(dev, B43_PHY_P1P2GAIN, ~0x0F00, 0x0600);
+ b43_phy_maskset(dev, B43_PHY_N1N2GAIN, ~0x0F00, 0x0700);
+ b43_phy_maskset(dev, B43_PHY_N1P1GAIN, ~0x0F00, 0x0100);
if (phy->rev == 1) {
- b43_phy_write(dev, B43_PHY_N1N2GAIN,
- (b43_phy_read(dev, B43_PHY_N1N2GAIN)
- & ~0x000F) | 0x0007);
+ b43_phy_maskset(dev, B43_PHY_N1N2GAIN, ~0x000F, 0x0007);
}
- b43_phy_write(dev, B43_PHY_OFDM(0x88),
- (b43_phy_read(dev, B43_PHY_OFDM(0x88)) & ~0x00FF) | 0x001C);
- b43_phy_write(dev, B43_PHY_OFDM(0x88),
- (b43_phy_read(dev, B43_PHY_OFDM(0x88)) & ~0x3F00) | 0x0200);
- b43_phy_write(dev, B43_PHY_OFDM(0x96),
- (b43_phy_read(dev, B43_PHY_OFDM(0x96)) & ~0x00FF) | 0x001C);
- b43_phy_write(dev, B43_PHY_OFDM(0x89),
- (b43_phy_read(dev, B43_PHY_OFDM(0x89)) & ~0x00FF) | 0x0020);
- b43_phy_write(dev, B43_PHY_OFDM(0x89),
- (b43_phy_read(dev, B43_PHY_OFDM(0x89)) & ~0x3F00) | 0x0200);
- b43_phy_write(dev, B43_PHY_OFDM(0x82),
- (b43_phy_read(dev, B43_PHY_OFDM(0x82)) & ~0x00FF) | 0x002E);
- b43_phy_write(dev, B43_PHY_OFDM(0x96),
- (b43_phy_read(dev, B43_PHY_OFDM(0x96)) & ~0xFF00) | 0x1A00);
- b43_phy_write(dev, B43_PHY_OFDM(0x81),
- (b43_phy_read(dev, B43_PHY_OFDM(0x81)) & ~0x00FF) | 0x0028);
- b43_phy_write(dev, B43_PHY_OFDM(0x81),
- (b43_phy_read(dev, B43_PHY_OFDM(0x81)) & ~0xFF00) | 0x2C00);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0x88), ~0x00FF, 0x001C);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0x88), ~0x3F00, 0x0200);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0x96), ~0x00FF, 0x001C);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0x89), ~0x00FF, 0x0020);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0x89), ~0x3F00, 0x0200);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0x82), ~0x00FF, 0x002E);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0x96), (u16)~0xFF00, 0x1A00);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0x81), ~0x00FF, 0x0028);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0x81), (u16)~0xFF00, 0x2C00);
if (phy->rev == 1) {
b43_phy_write(dev, B43_PHY_PEAK_COUNT, 0x092B);
- b43_phy_write(dev, B43_PHY_OFDM(0x1B),
- (b43_phy_read(dev, B43_PHY_OFDM(0x1B)) & ~0x001E) | 0x0002);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0x1B), ~0x001E, 0x0002);
} else {
- b43_phy_write(dev, B43_PHY_OFDM(0x1B),
- b43_phy_read(dev, B43_PHY_OFDM(0x1B)) & ~0x001E);
+ b43_phy_mask(dev, B43_PHY_OFDM(0x1B), ~0x001E);
b43_phy_write(dev, B43_PHY_OFDM(0x1F), 0x287A);
- b43_phy_write(dev, B43_PHY_LPFGAINCTL,
- (b43_phy_read(dev, B43_PHY_LPFGAINCTL) & ~0x000F) | 0x0004);
+ b43_phy_maskset(dev, B43_PHY_LPFGAINCTL, ~0x000F, 0x0004);
if (phy->rev >= 6) {
b43_phy_write(dev, B43_PHY_OFDM(0x22), 0x287A);
- b43_phy_write(dev, B43_PHY_LPFGAINCTL,
- (b43_phy_read(dev, B43_PHY_LPFGAINCTL) & ~0xF000) | 0x3000);
+ b43_phy_maskset(dev, B43_PHY_LPFGAINCTL, (u16)~0xF000, 0x3000);
}
}
- b43_phy_write(dev, B43_PHY_DIVSRCHIDX,
- (b43_phy_read(dev, B43_PHY_DIVSRCHIDX) & 0x8080) | 0x7874);
+ b43_phy_maskset(dev, B43_PHY_DIVSRCHIDX, 0x8080, 0x7874);
b43_phy_write(dev, B43_PHY_OFDM(0x8E), 0x1C00);
if (phy->rev == 1) {
- b43_phy_write(dev, B43_PHY_DIVP1P2GAIN,
- (b43_phy_read(dev, B43_PHY_DIVP1P2GAIN) & ~0x0F00) | 0x0600);
+ b43_phy_maskset(dev, B43_PHY_DIVP1P2GAIN, ~0x0F00, 0x0600);
b43_phy_write(dev, B43_PHY_OFDM(0x8B), 0x005E);
- b43_phy_write(dev, B43_PHY_ANTWRSETT,
- (b43_phy_read(dev, B43_PHY_ANTWRSETT) & ~0x00FF) | 0x001E);
+ b43_phy_maskset(dev, B43_PHY_ANTWRSETT, ~0x00FF, 0x001E);
b43_phy_write(dev, B43_PHY_OFDM(0x8D), 0x0002);
b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3_R1, 0, 0);
b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3_R1, 1, 7);
@@ -469,10 +433,8 @@ static void b43_wa_altagc(struct b43_wldev *dev)
b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3, 3, 28);
}
if (phy->rev >= 6) {
- b43_phy_write(dev, B43_PHY_OFDM(0x26),
- b43_phy_read(dev, B43_PHY_OFDM(0x26)) & ~0x0003);
- b43_phy_write(dev, B43_PHY_OFDM(0x26),
- b43_phy_read(dev, B43_PHY_OFDM(0x26)) & ~0x1000);
+ b43_phy_mask(dev, B43_PHY_OFDM(0x26), ~0x0003);
+ b43_phy_mask(dev, B43_PHY_OFDM(0x26), ~0x1000);
}
b43_phy_read(dev, B43_PHY_VERSION_OFDM); /* Dummy read */
}
@@ -538,8 +500,7 @@ static void b43_wa_boards_g(struct b43_wldev *dev)
b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 2, 0x0001);
if ((bus->sprom.boardflags_lo & B43_BFL_EXTLNA) &&
(phy->rev >= 7)) {
- b43_phy_write(dev, B43_PHY_EXTG(0x11),
- b43_phy_read(dev, B43_PHY_EXTG(0x11)) & 0xF7FF);
+ b43_phy_mask(dev, B43_PHY_EXTG(0x11), 0xF7FF);
b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 0x0020, 0x0001);
b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 0x0021, 0x0001);
b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 0x0022, 0x0001);
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c
index eae9b8052658..a63d88841df8 100644
--- a/drivers/net/wireless/b43/xmit.c
+++ b/drivers/net/wireless/b43/xmit.c
@@ -50,7 +50,7 @@ static int b43_plcp_get_bitrate_idx_cck(struct b43_plcp_hdr6 *plcp)
}
/* Extract the bitrate index out of an OFDM PLCP header. */
-static u8 b43_plcp_get_bitrate_idx_ofdm(struct b43_plcp_hdr6 *plcp, bool aphy)
+static int b43_plcp_get_bitrate_idx_ofdm(struct b43_plcp_hdr6 *plcp, bool aphy)
{
int base = aphy ? 0 : 4;
@@ -538,8 +538,14 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
chanstat = le16_to_cpu(rxhdr->channel);
phytype = chanstat & B43_RX_CHAN_PHYTYPE;
- if (macstat & B43_RX_MAC_FCSERR)
+ if (unlikely(macstat & B43_RX_MAC_FCSERR)) {
dev->wl->ieee_stats.dot11FCSErrorCount++;
+ status.flag |= RX_FLAG_FAILED_FCS_CRC;
+ }
+ if (unlikely(phystat0 & (B43_RX_PHYST0_PLCPHCF | B43_RX_PHYST0_PLCPFV)))
+ status.flag |= RX_FLAG_FAILED_PLCP_CRC;
+ if (phystat0 & B43_RX_PHYST0_SHORTPRMBL)
+ status.flag |= RX_FLAG_SHORTPRE;
if (macstat & B43_RX_MAC_DECERR) {
/* Decryption with the given key failed.
* Drop the packet. We also won't be able to decrypt it with
@@ -606,8 +612,12 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
phytype == B43_PHYTYPE_A);
else
status.rate_idx = b43_plcp_get_bitrate_idx_cck(plcp);
- if (unlikely(status.rate_idx == -1))
- goto drop;
+ if (unlikely(status.rate_idx == -1)) {
+ /* PLCP seems to be corrupted.
+ * Drop the frame, if we are not interested in corrupted frames. */
+ if (!(dev->wl->filter_flags & FIF_PLCPFAIL))
+ goto drop;
+ }
status.antenna = !!(phystat0 & B43_RX_PHYST0_ANT);
/*
@@ -661,7 +671,6 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
goto drop;
}
- dev->stats.last_rx = jiffies;
ieee80211_rx_irqsafe(dev->wl->hw, skb, &status);
return;