aboutsummaryrefslogtreecommitdiff
path: root/drivers/net/wireless/b43
diff options
context:
space:
mode:
authorMichael Buesch <mb@bu3sch.de>2008-08-27 18:53:02 +0200
committerJohn W. Linville <linville@tuxdriver.com>2008-08-29 16:24:12 -0400
commitef1a628d83fc0423c36e773281162be790503168 (patch)
tree436d3d7d91434febb1813dcea16060e6937288b9 /drivers/net/wireless/b43
parent35e032d82f3e2a9b0d92077b4fbc97166525ed53 (diff)
b43: Implement dynamic PHY API
This patch implements a dynamic "ops" based PHY API. This is needed in order to conveniently support future PHY types to avoid the "switch"-hell. This patch does not change any functionality. It just moves lots of code from one place to another and adjusts it for the changed data structures. Signed-off-by: Michael Buesch <mb@bu3sch.de> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/b43')
-rw-r--r--drivers/net/wireless/b43/Makefile4
-rw-r--r--drivers/net/wireless/b43/b43.h127
-rw-r--r--drivers/net/wireless/b43/debugfs.c79
-rw-r--r--drivers/net/wireless/b43/lo.c120
-rw-r--r--drivers/net/wireless/b43/lo.h4
-rw-r--r--drivers/net/wireless/b43/main.c172
-rw-r--r--drivers/net/wireless/b43/nphy.c143
-rw-r--r--drivers/net/wireless/b43/nphy.h54
-rw-r--r--drivers/net/wireless/b43/phy.c3421
-rw-r--r--drivers/net/wireless/b43/phy.h340
-rw-r--r--drivers/net/wireless/b43/phy_a.c536
-rw-r--r--drivers/net/wireless/b43/phy_a.h124
-rw-r--r--drivers/net/wireless/b43/phy_common.c276
-rw-r--r--drivers/net/wireless/b43/phy_common.h312
-rw-r--r--drivers/net/wireless/b43/phy_g.c3229
-rw-r--r--drivers/net/wireless/b43/phy_g.h201
-rw-r--r--drivers/net/wireless/b43/rfkill.c5
-rw-r--r--drivers/net/wireless/b43/sysfs.c23
-rw-r--r--drivers/net/wireless/b43/tables.c43
-rw-r--r--drivers/net/wireless/b43/tables_nphy.c2
-rw-r--r--drivers/net/wireless/b43/wa.c2
-rw-r--r--drivers/net/wireless/b43/xmit.c6
22 files changed, 4998 insertions, 4225 deletions
diff --git a/drivers/net/wireless/b43/Makefile b/drivers/net/wireless/b43/Makefile
index 8c52b0b9862..fb6ffce03f0 100644
--- a/drivers/net/wireless/b43/Makefile
+++ b/drivers/net/wireless/b43/Makefile
@@ -1,7 +1,9 @@
b43-y += main.o
b43-y += tables.o
b43-$(CONFIG_B43_NPHY) += tables_nphy.o
-b43-y += phy.o
+b43-y += phy_common.o
+b43-y += phy_g.o
+b43-y += phy_a.o
b43-$(CONFIG_B43_NPHY) += nphy.o
b43-y += sysfs.o
b43-y += xmit.o
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
index edcdfa36645..fc280157596 100644
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -12,7 +12,7 @@
#include "leds.h"
#include "rfkill.h"
#include "lo.h"
-#include "phy.h"
+#include "phy_common.h"
/* The unique identifier of the firmware that's officially supported by
@@ -508,122 +508,6 @@ struct b43_iv {
} __attribute__((__packed__));
-struct b43_phy {
- /* Band support flags. */
- bool supports_2ghz;
- bool supports_5ghz;
-
- /* GMODE bit enabled? */
- bool gmode;
-
- /* Analog Type */
- u8 analog;
- /* B43_PHYTYPE_ */
- u8 type;
- /* PHY revision number. */
- u8 rev;
-
- /* Radio versioning */
- u16 radio_manuf; /* Radio manufacturer */
- u16 radio_ver; /* Radio version */
- u8 radio_rev; /* Radio revision */
-
- bool dyn_tssi_tbl; /* tssi2dbm is kmalloc()ed. */
-
- /* ACI (adjacent channel interference) flags. */
- bool aci_enable;
- bool aci_wlan_automatic;
- bool aci_hw_rssi;
-
- /* Radio switched on/off */
- bool radio_on;
- struct {
- /* Values saved when turning the radio off.
- * They are needed when turning it on again. */
- bool valid;
- u16 rfover;
- u16 rfoverval;
- } radio_off_context;
-
- u16 minlowsig[2];
- u16 minlowsigpos[2];
-
- /* TSSI to dBm table in use */
- const s8 *tssi2dbm;
- /* Target idle TSSI */
- int tgt_idle_tssi;
- /* Current idle TSSI */
- int cur_idle_tssi;
-
- /* LocalOscillator control values. */
- struct b43_txpower_lo_control *lo_control;
- /* Values from b43_calc_loopback_gain() */
- s16 max_lb_gain; /* Maximum Loopback gain in hdB */
- s16 trsw_rx_gain; /* TRSW RX gain in hdB */
- s16 lna_lod_gain; /* LNA lod */
- s16 lna_gain; /* LNA */
- s16 pga_gain; /* PGA */
-
- /* Desired TX power level (in dBm).
- * This is set by the user and adjusted in b43_phy_xmitpower(). */
- u8 power_level;
- /* A-PHY TX Power control value. */
- u16 txpwr_offset;
-
- /* Current TX power level attenuation control values */
- struct b43_bbatt bbatt;
- struct b43_rfatt rfatt;
- u8 tx_control; /* B43_TXCTL_XXX */
-
- /* Hardware Power Control enabled? */
- bool hardware_power_control;
-
- /* Current Interference Mitigation mode */
- int interfmode;
- /* Stack of saved values from the Interference Mitigation code.
- * Each value in the stack is layed out as follows:
- * bit 0-11: offset
- * bit 12-15: register ID
- * bit 16-32: value
- * register ID is: 0x1 PHY, 0x2 Radio, 0x3 ILT
- */
-#define B43_INTERFSTACK_SIZE 26
- u32 interfstack[B43_INTERFSTACK_SIZE]; //FIXME: use a data structure
-
- /* Saved values from the NRSSI Slope calculation */
- s16 nrssi[2];
- s32 nrssislope;
- /* In memory nrssi lookup table. */
- s8 nrssi_lt[64];
-
- /* current channel */
- u8 channel;
-
- u16 lofcal;
-
- u16 initval; //FIXME rename?
-
- /* PHY TX errors counter. */
- atomic_t txerr_cnt;
-
- /* The device does address auto increment for the OFDM tables.
- * We cache the previously used address here and omit the address
- * write on the next table access, if possible. */
- u16 ofdmtab_addr; /* The address currently set in hardware. */
- enum { /* The last data flow direction. */
- B43_OFDMTAB_DIRECTION_UNKNOWN = 0,
- B43_OFDMTAB_DIRECTION_READ,
- B43_OFDMTAB_DIRECTION_WRITE,
- } ofdmtab_addr_direction;
-
-#if B43_DEBUG
- /* Manual TX-power control enabled? */
- bool manual_txpower_control;
- /* PHY registers locked by b43_phy_lock()? */
- bool phy_locked;
-#endif /* B43_DEBUG */
-};
-
/* Data structures for DMA transmission, per 80211 core. */
struct b43_dma {
struct b43_dmaring *tx_ring_AC_BK; /* Background */
@@ -908,6 +792,15 @@ static inline int b43_is_mode(struct b43_wl *wl, int type)
return (wl->operating && wl->if_type == type);
}
+/**
+ * b43_current_band - Returns the currently used band.
+ * Returns one of IEEE80211_BAND_2GHZ and IEEE80211_BAND_5GHZ.
+ */
+static inline enum ieee80211_band b43_current_band(struct b43_wl *wl)
+{
+ return wl->hw->conf.channel->band;
+}
+
static inline u16 b43_read16(struct b43_wldev *dev, u16 offset)
{
return ssb_read16(dev->dev, offset);
diff --git a/drivers/net/wireless/b43/debugfs.c b/drivers/net/wireless/b43/debugfs.c
index 29851bc1101..06a01da8016 100644
--- a/drivers/net/wireless/b43/debugfs.c
+++ b/drivers/net/wireless/b43/debugfs.c
@@ -443,76 +443,6 @@ out_unlock:
return count;
}
-static ssize_t txpower_g_read_file(struct b43_wldev *dev,
- char *buf, size_t bufsize)
-{
- ssize_t count = 0;
-
- if (dev->phy.type != B43_PHYTYPE_G) {
- fappend("Device is not a G-PHY\n");
- goto out;
- }
- fappend("Control: %s\n", dev->phy.manual_txpower_control ?
- "MANUAL" : "AUTOMATIC");
- fappend("Baseband attenuation: %u\n", dev->phy.bbatt.att);
- fappend("Radio attenuation: %u\n", dev->phy.rfatt.att);
- fappend("TX Mixer Gain: %s\n",
- (dev->phy.tx_control & B43_TXCTL_TXMIX) ? "ON" : "OFF");
- fappend("PA Gain 2dB: %s\n",
- (dev->phy.tx_control & B43_TXCTL_PA2DB) ? "ON" : "OFF");
- fappend("PA Gain 3dB: %s\n",
- (dev->phy.tx_control & B43_TXCTL_PA3DB) ? "ON" : "OFF");
- fappend("\n\n");
- fappend("You can write to this file:\n");
- fappend("Writing \"auto\" enables automatic txpower control.\n");
- fappend
- ("Writing the attenuation values as \"bbatt rfatt txmix pa2db pa3db\" "
- "enables manual txpower control.\n");
- fappend("Example: 5 4 0 0 1\n");
- fappend("Enables manual control with Baseband attenuation 5, "
- "Radio attenuation 4, No TX Mixer Gain, "
- "No PA Gain 2dB, With PA Gain 3dB.\n");
-out:
- return count;
-}
-
-static int txpower_g_write_file(struct b43_wldev *dev,
- const char *buf, size_t count)
-{
- if (dev->phy.type != B43_PHYTYPE_G)
- return -ENODEV;
- if ((count >= 4) && (memcmp(buf, "auto", 4) == 0)) {
- /* Automatic control */
- dev->phy.manual_txpower_control = 0;
- b43_phy_xmitpower(dev);
- } else {
- int bbatt = 0, rfatt = 0, txmix = 0, pa2db = 0, pa3db = 0;
- /* Manual control */
- if (sscanf(buf, "%d %d %d %d %d", &bbatt, &rfatt,
- &txmix, &pa2db, &pa3db) != 5)
- return -EINVAL;
- b43_put_attenuation_into_ranges(dev, &bbatt, &rfatt);
- dev->phy.manual_txpower_control = 1;
- dev->phy.bbatt.att = bbatt;
- dev->phy.rfatt.att = rfatt;
- dev->phy.tx_control = 0;
- if (txmix)
- dev->phy.tx_control |= B43_TXCTL_TXMIX;
- if (pa2db)
- dev->phy.tx_control |= B43_TXCTL_PA2DB;
- if (pa3db)
- dev->phy.tx_control |= B43_TXCTL_PA3DB;
- b43_phy_lock(dev);
- b43_radio_lock(dev);
- b43_set_txpower_g(dev, &dev->phy.bbatt,
- &dev->phy.rfatt, dev->phy.tx_control);
- b43_radio_unlock(dev);
- b43_phy_unlock(dev);
- }
-
- return 0;
-}
-
/* wl->irq_lock is locked */
static int restart_write_file(struct b43_wldev *dev,
const char *buf, size_t count)
@@ -560,7 +490,7 @@ static ssize_t loctls_read_file(struct b43_wldev *dev,
err = -ENODEV;
goto out;
}
- lo = phy->lo_control;
+ lo = phy->g->lo_control;
fappend("-- Local Oscillator calibration data --\n\n");
fappend("HW-power-control enabled: %d\n",
dev->phy.hardware_power_control);
@@ -578,8 +508,8 @@ static ssize_t loctls_read_file(struct b43_wldev *dev,
list_for_each_entry(cal, &lo->calib_list, list) {
bool active;
- active = (b43_compare_bbatt(&cal->bbatt, &phy->bbatt) &&
- b43_compare_rfatt(&cal->rfatt, &phy->rfatt));
+ active = (b43_compare_bbatt(&cal->bbatt, &phy->g->bbatt) &&
+ b43_compare_rfatt(&cal->rfatt, &phy->g->rfatt));
fappend("BB(%d), RF(%d,%d) -> I=%d, Q=%d "
"(expires in %lu sec)%s\n",
cal->bbatt.att,
@@ -763,7 +693,6 @@ 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(txpower_g, txpower_g_read_file, txpower_g_write_file, 0);
B43_DEBUGFS_FOPS(restart, NULL, restart_write_file, 1);
B43_DEBUGFS_FOPS(loctls, loctls_read_file, NULL, 0);
@@ -877,7 +806,6 @@ void b43_debugfs_add_device(struct b43_wldev *dev)
ADD_FILE(mmio32write, 0200);
ADD_FILE(tsf, 0600);
ADD_FILE(txstat, 0400);
- ADD_FILE(txpower_g, 0600);
ADD_FILE(restart, 0200);
ADD_FILE(loctls, 0400);
@@ -907,7 +835,6 @@ void b43_debugfs_remove_device(struct b43_wldev *dev)
debugfs_remove(e->file_mmio32write.dentry);
debugfs_remove(e->file_tsf.dentry);
debugfs_remove(e->file_txstat.dentry);
- debugfs_remove(e->file_txpower_g.dentry);
debugfs_remove(e->file_restart.dentry);
debugfs_remove(e->file_loctls.dentry);
diff --git a/drivers/net/wireless/b43/lo.c b/drivers/net/wireless/b43/lo.c
index 9c854d6aae3..6a18a147046 100644
--- a/drivers/net/wireless/b43/lo.c
+++ b/drivers/net/wireless/b43/lo.c
@@ -29,7 +29,7 @@
#include "b43.h"
#include "lo.h"
-#include "phy.h"
+#include "phy_g.h"
#include "main.h"
#include <linux/delay.h>
@@ -174,7 +174,8 @@ static u16 lo_txctl_register_table(struct b43_wldev *dev,
static void lo_measure_txctl_values(struct b43_wldev *dev)
{
struct b43_phy *phy = &dev->phy;
- struct b43_txpower_lo_control *lo = phy->lo_control;
+ struct b43_phy_g *gphy = phy->g;
+ struct b43_txpower_lo_control *lo = gphy->lo_control;
u16 reg, mask;
u16 trsw_rx, pga;
u16 radio_pctl_reg;
@@ -195,7 +196,7 @@ static void lo_measure_txctl_values(struct b43_wldev *dev)
int lb_gain; /* Loopback gain (in dB) */
trsw_rx = 0;
- lb_gain = phy->max_lb_gain / 2;
+ lb_gain = gphy->max_lb_gain / 2;
if (lb_gain > 10) {
radio_pctl_reg = 0;
pga = abs(10 - lb_gain) / 6;
@@ -226,7 +227,7 @@ static void lo_measure_txctl_values(struct b43_wldev *dev)
}
b43_radio_write16(dev, 0x43, (b43_radio_read16(dev, 0x43)
& 0xFFF0) | radio_pctl_reg);
- b43_phy_set_baseband_attenuation(dev, 2);
+ b43_gphy_set_baseband_attenuation(dev, 2);
reg = lo_txctl_register_table(dev, &mask, NULL);
mask = ~mask;
@@ -277,7 +278,8 @@ static void lo_measure_txctl_values(struct b43_wldev *dev)
static void lo_read_power_vector(struct b43_wldev *dev)
{
struct b43_phy *phy = &dev->phy;
- struct b43_txpower_lo_control *lo = phy->lo_control;
+ struct b43_phy_g *gphy = phy->g;
+ struct b43_txpower_lo_control *lo = gphy->lo_control;
int i;
u64 tmp;
u64 power_vector = 0;
@@ -298,6 +300,7 @@ static void lo_measure_gain_values(struct b43_wldev *dev,
s16 max_rx_gain, int use_trsw_rx)
{
struct b43_phy *phy = &dev->phy;
+ struct b43_phy_g *gphy = phy->g;
u16 tmp;
if (max_rx_gain < 0)
@@ -308,7 +311,7 @@ static void lo_measure_gain_values(struct b43_wldev *dev,
int trsw_rx_gain;
if (use_trsw_rx) {
- trsw_rx_gain = phy->trsw_rx_gain / 2;
+ trsw_rx_gain = gphy->trsw_rx_gain / 2;
if (max_rx_gain >= trsw_rx_gain) {
trsw_rx_gain = max_rx_gain - trsw_rx_gain;
trsw_rx = 0x20;
@@ -316,38 +319,38 @@ static void lo_measure_gain_values(struct b43_wldev *dev,
} else
trsw_rx_gain = max_rx_gain;
if (trsw_rx_gain < 9) {
- phy->lna_lod_gain = 0;
+ gphy->lna_lod_gain = 0;
} else {
- phy->lna_lod_gain = 1;
+ gphy->lna_lod_gain = 1;
trsw_rx_gain -= 8;
}
trsw_rx_gain = clamp_val(trsw_rx_gain, 0, 0x2D);
- phy->pga_gain = trsw_rx_gain / 3;
- if (phy->pga_gain >= 5) {
- phy->pga_gain -= 5;
- phy->lna_gain = 2;
+ gphy->pga_gain = trsw_rx_gain / 3;
+ if (gphy->pga_gain >= 5) {
+ gphy->pga_gain -= 5;
+ gphy->lna_gain = 2;
} else
- phy->lna_gain = 0;
+ gphy->lna_gain = 0;
} else {
- phy->lna_gain = 0;
- phy->trsw_rx_gain = 0x20;
+ gphy->lna_gain = 0;
+ gphy->trsw_rx_gain = 0x20;
if (max_rx_gain >= 0x14) {
- phy->lna_lod_gain = 1;
- phy->pga_gain = 2;
+ gphy->lna_lod_gain = 1;
+ gphy->pga_gain = 2;
} else if (max_rx_gain >= 0x12) {
- phy->lna_lod_gain = 1;
- phy->pga_gain = 1;
+ gphy->lna_lod_gain = 1;
+ gphy->pga_gain = 1;
} else if (max_rx_gain >= 0xF) {
- phy->lna_lod_gain = 1;
- phy->pga_gain = 0;
+ gphy->lna_lod_gain = 1;
+ gphy->pga_gain = 0;
} else {
- phy->lna_lod_gain = 0;
- phy->pga_gain = 0;
+ gphy->lna_lod_gain = 0;
+ gphy->pga_gain = 0;
}
}
tmp = b43_radio_read16(dev, 0x7A);
- if (phy->lna_lod_gain == 0)
+ if (gphy->lna_lod_gain == 0)
tmp &= ~0x0008;
else
tmp |= 0x0008;
@@ -392,10 +395,11 @@ static void lo_measure_setup(struct b43_wldev *dev,
{
struct ssb_sprom *sprom = &dev->dev->bus->sprom;
struct b43_phy *phy = &dev->phy;
- struct b43_txpower_lo_control *lo = phy->lo_control;
+ struct b43_phy_g *gphy = phy->g;
+ struct b43_txpower_lo_control *lo = gphy->lo_control;
u16 tmp;
- if (b43_has_hardware_pctl(phy)) {
+ if (b43_has_hardware_pctl(dev)) {
sav->phy_lo_mask = b43_phy_read(dev, B43_PHY_LO_MASK);
sav->phy_extg_01 = b43_phy_read(dev, B43_PHY_EXTG(0x01));
sav->phy_dacctl_hwpctl = b43_phy_read(dev, B43_PHY_DACCTL);
@@ -496,7 +500,7 @@ static void lo_measure_setup(struct b43_wldev *dev,
b43_phy_write(dev, B43_PHY_CCK(0x2B), 0x0802);
if (phy->rev >= 2)
b43_dummy_transmission(dev);
- b43_radio_selectchannel(dev, 6, 0);
+ b43_gphy_channel_switch(dev, 6, 0);
b43_radio_read16(dev, 0x51); /* dummy read */
if (phy->type == B43_PHYTYPE_G)
b43_phy_write(dev, B43_PHY_CCK(0x2F), 0);
@@ -520,18 +524,19 @@ static void lo_measure_restore(struct b43_wldev *dev,
struct lo_g_saved_values *sav)
{
struct b43_phy *phy = &dev->phy;
+ struct b43_phy_g *gphy = phy->g;
u16 tmp;
if (phy->rev >= 2) {
b43_phy_write(dev, B43_PHY_PGACTL, 0xE300);
- tmp = (phy->pga_gain << 8);
+ tmp = (gphy->pga_gain << 8);
b43_phy_write(dev, B43_PHY_RFOVERVAL, tmp | 0xA0);
udelay(5);
b43_phy_write(dev, B43_PHY_RFOVERVAL, tmp | 0xA2);
udelay(2);
b43_phy_write(dev, B43_PHY_RFOVERVAL, tmp | 0xA3);
} else {
- tmp = (phy->pga_gain | 0xEFA0);
+ tmp = (gphy->pga_gain | 0xEFA0);
b43_phy_write(dev, B43_PHY_PGACTL, tmp);
}
if (phy->type == B43_PHYTYPE_G) {
@@ -572,7 +577,7 @@ static void lo_measure_restore(struct b43_wldev *dev,
b43_phy_write(dev, B43_PHY_CCK(0x3E), sav->phy_cck_3E);
b43_phy_write(dev, B43_PHY_CRS0, sav->phy_crs0);
}
- if (b43_has_hardware_pctl(phy)) {
+ if (b43_has_hardware_pctl(dev)) {
tmp = (sav->phy_lo_mask & 0xBFFF);
b43_phy_write(dev, B43_PHY_LO_MASK, tmp);
b43_phy_write(dev, B43_PHY_EXTG(0x01), sav->phy_extg_01);
@@ -580,7 +585,7 @@ static void lo_measure_restore(struct b43_wldev *dev,
b43_phy_write(dev, B43_PHY_CCK(0x14), sav->phy_cck_14);
b43_phy_write(dev, B43_PHY_HPWR_TSSICTL, sav->phy_hpwr_tssictl);
}
- b43_radio_selectchannel(dev, sav->old_channel, 1);
+ b43_gphy_channel_switch(dev, sav->old_channel, 1);
}
struct b43_lo_g_statemachine {
@@ -597,6 +602,7 @@ static int lo_probe_possible_loctls(struct b43_wldev *dev,
struct b43_lo_g_statemachine *d)
{
struct b43_phy *phy = &dev->phy;
+ struct b43_phy_g *gphy = phy->g;
struct b43_loctl test_loctl;
struct b43_loctl orig_loctl;
struct b43_loctl prev_loctl = {
@@ -646,9 +652,9 @@ static int lo_probe_possible_loctls(struct b43_wldev *dev,
test_loctl.q != prev_loctl.q) &&
(abs(test_loctl.i) <= 16 && abs(test_loctl.q) <= 16)) {
b43_lo_write(dev, &test_loctl);
- feedth = lo_measure_feedthrough(dev, phy->lna_gain,
- phy->pga_gain,
- phy->trsw_rx_gain);
+ feedth = lo_measure_feedthrough(dev, gphy->lna_gain,
+ gphy->pga_gain,
+ gphy->trsw_rx_gain);
if (feedth < d->lowest_feedth) {
memcpy(probe_loctl, &test_loctl,
sizeof(struct b43_loctl));
@@ -677,6 +683,7 @@ static void lo_probe_loctls_statemachine(struct b43_wldev *dev,
int *max_rx_gain)
{
struct b43_phy *phy = &dev->phy;
+ struct b43_phy_g *gphy = phy->g;
struct b43_lo_g_statemachine d;
u16 feedth;
int found_lower;
@@ -693,17 +700,17 @@ static void lo_probe_loctls_statemachine(struct b43_wldev *dev,
max_repeat = 4;
do {
b43_lo_write(dev, &d.min_loctl);
- feedth = lo_measure_feedthrough(dev, phy->lna_gain,
- phy->pga_gain,
- phy->trsw_rx_gain);
+ feedth = lo_measure_feedthrough(dev, gphy->lna_gain,
+ gphy->pga_gain,
+ gphy->trsw_rx_gain);
if (feedth < 0x258) {
if (feedth >= 0x12C)
*max_rx_gain += 6;
else
*max_rx_gain += 3;
- feedth = lo_measure_feedthrough(dev, phy->lna_gain,
- phy->pga_gain,
- phy->trsw_rx_gain);
+ feedth = lo_measure_feedthrough(dev, gphy->lna_gain,
+ gphy->pga_gain,
+ gphy->trsw_rx_gain);
}
d.lowest_feedth = feedth;
@@ -752,6 +759,7 @@ struct b43_lo_calib * b43_calibrate_lo_setting(struct b43_wldev *dev,
const struct b43_rfatt *rfatt)
{
struct b43_phy *phy = &dev->phy;
+ struct b43_phy_g *gphy = phy->g;
struct b43_loctl loctl = {
.i = 0,
.q = 0,
@@ -782,11 +790,11 @@ struct b43_lo_calib * b43_calibrate_lo_setting(struct b43_wldev *dev,
if (rfatt->with_padmix)
max_rx_gain -= pad_mix_gain;
if (has_loopback_gain(phy))
- max_rx_gain += phy->max_lb_gain;
+ max_rx_gain += gphy->max_lb_gain;
lo_measure_gain_values(dev, max_rx_gain,
has_loopback_gain(phy));
- b43_phy_set_baseband_attenuation(dev, bbatt->att);
+ b43_gphy_set_baseband_attenuation(dev, bbatt->att);
lo_probe_loctls_statemachine(dev, &loctl, &max_rx_gain);
lo_measure_restore(dev, &saved_regs);
@@ -820,7 +828,7 @@ 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.lo_control;
+ struct b43_txpower_lo_control *lo = dev->phy.g->lo_control;
struct b43_lo_calib *c;
c = b43_find_lo_calib(lo, bbatt, rfatt);
@@ -839,7 +847,8 @@ struct b43_lo_calib * b43_get_calib_lo_settings(struct b43_wldev *dev,
void b43_gphy_dc_lt_init(struct b43_wldev *dev, bool update_all)
{
struct b43_phy *phy = &dev->phy;
- struct b43_txpower_lo_control *lo = phy->lo_control;
+ struct b43_phy_g *gphy = phy->g;
+ struct b43_txpower_lo_control *lo = gphy->lo_control;
int i;
int rf_offset, bb_offset;
const struct b43_rfatt *rfatt;
@@ -917,14 +926,14 @@ static inline void b43_lo_fixup_rfatt(struct b43_rfatt *rf)
void b43_lo_g_adjust(struct b43_wldev *dev)
{
- struct b43_phy *phy = &dev->phy;
+ struct b43_phy_g *gphy = dev->phy.g;
struct b43_lo_calib *cal;
struct b43_rfatt rf;
- memcpy(&rf, &phy->rfatt, sizeof(rf));
+ memcpy(&rf, &gphy->rfatt, sizeof(rf));
b43_lo_fixup_rfatt(&rf);
- cal = b43_get_calib_lo_settings(dev, &phy->bbatt, &rf);
+ cal = b43_get_calib_lo_settings(dev, &gphy->bbatt, &rf);
if (!cal)
return;
b43_lo_write(dev, &cal->ctl);
@@ -952,7 +961,8 @@ void b43_lo_g_adjust_to(struct b43_wldev *dev,
void b43_lo_g_maintanance_work(struct b43_wldev *dev)
{
struct b43_phy *phy = &dev->phy;
- struct b43_txpower_lo_control *lo = phy->lo_control;
+ struct b43_phy_g *gphy = phy->g;
+ struct b43_txpower_lo_control *lo = gphy->lo_control;
unsigned long now;
unsigned long expire;
struct b43_lo_calib *cal, *tmp;
@@ -962,7 +972,7 @@ void b43_lo_g_maintanance_work(struct b43_wldev *dev)
if (!lo)
return;
now = jiffies;
- hwpctl = b43_has_hardware_pctl(phy);
+ hwpctl = b43_has_hardware_pctl(dev);
if (hwpctl) {
/* Read the power vector and update it, if needed. */
@@ -983,8 +993,8 @@ void b43_lo_g_maintanance_work(struct b43_wldev *dev)
if (!time_before(cal->calib_time, expire))
continue;
/* This item expired. */
- if (b43_compare_bbatt(&cal->bbatt, &phy->bbatt) &&
- b43_compare_rfatt(&cal->rfatt, &phy->rfatt)) {
+ if (b43_compare_bbatt(&cal->bbatt, &gphy->bbatt) &&
+ b43_compare_rfatt(&cal->rfatt, &gphy->rfatt)) {
B43_WARN_ON(current_item_expired);
current_item_expired = 1;
}
@@ -1002,7 +1012,7 @@ void b43_lo_g_maintanance_work(struct b43_wldev *dev)
/* Recalibrate currently used LO setting. */
if (b43_debug(dev, B43_DBG_LO))
b43dbg(dev->wl, "LO: Recalibrating current LO setting\n");
- cal = b43_calibrate_lo_setting(dev, &phy->bbatt, &phy->rfatt);
+ cal = b43_calibrate_lo_setting(dev, &gphy->bbatt, &gphy->rfatt);
if (cal) {
list_add(&cal->list, &lo->calib_list);
b43_lo_write(dev, &cal->ctl);
@@ -1013,7 +1023,7 @@ void b43_lo_g_maintanance_work(struct b43_wldev *dev)
void b43_lo_g_cleanup(struct b43_wldev *dev)
{
- struct b43_txpower_lo_control *lo = dev->phy.lo_control;
+ struct b43_txpower_lo_control *lo = dev->phy.g->lo_control;
struct b43_lo_calib *cal, *tmp;
if (!lo)
@@ -1027,9 +1037,7 @@ void b43_lo_g_cleanup(struct b43_wldev *dev)
/* LO Initialization */
void b43_lo_g_init(struct b43_wldev *dev)
{
- struct b43_phy *phy = &dev->phy;
-
- if (b43_has_hardware_pctl(phy)) {
+ if (b43_has_hardware_pctl(dev)) {
lo_read_power_vector(dev);
b43_gphy_dc_lt_init(dev, 1);
}
diff --git a/drivers/net/wireless/b43/lo.h b/drivers/net/wireless/b43/lo.h
index 1da321cabc1..3b27e20eff8 100644
--- a/drivers/net/wireless/b43/lo.h
+++ b/drivers/net/wireless/b43/lo.h
@@ -1,7 +1,9 @@
#ifndef B43_LO_H_
#define B43_LO_H_
-#include "phy.h"
+/* G-PHY Local Oscillator */
+
+#include "phy_g.h"
struct b43_wldev;
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 7205a936ec7..af43f03b318 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -44,7 +44,8 @@
#include "b43.h"
#include "main.h"
#include "debugfs.h"
-#include "phy.h"
+#include "phy_common.h"
+#include "phy_g.h"
#include "nphy.h"
#include "dma.h"
#include "pio.h"
@@ -1174,6 +1175,8 @@ static void b43_calculate_link_quality(struct b43_wldev *dev)
{
/* Top half of Link Quality calculation. */
+ if (dev->phy.type != B43_PHYTYPE_G)
+ return;
if (dev->noisecalc.calculation_running)
return;
dev->noisecalc.calculation_running = 1;
@@ -1184,7 +1187,7 @@ static void b43_calculate_link_quality(struct b43_wldev *dev)
static void handle_irq_noise(struct b43_wldev *dev)
{
- struct b43_phy *phy = &dev->phy;
+ struct b43_phy_g *phy = dev->phy.g;
u16 tmp;
u8 noise[4];
u8 i, j;
@@ -1192,6 +1195,9 @@ static void handle_irq_noise(struct b43_wldev *dev)
/* Bottom half of Link Quality calculation. */
+ if (dev->phy.type != B43_PHYTYPE_G)
+ return;
+
/* Possible race condition: It might be possible that the user
* changed to a different channel in the meantime since we
* started the calculation. We ignore that fact, since it's
@@ -2688,9 +2694,7 @@ static void b43_mgmtframe_txantenna(struct b43_wldev *dev, int antenna)
/* This is the opposite of b43_chip_init() */
static void b43_chip_exit(struct b43_wldev *dev)
{
- b43_radio_turn_off(dev, 1);
b43_gpio_cleanup(dev);
- b43_lo_g_cleanup(dev);
/* firmware is released later */
}
@@ -2700,7 +2704,7 @@ static void b43_chip_exit(struct b43_wldev *dev)
static int b43_chip_init(struct b43_wldev *dev)
{
struct b43_phy *phy = &dev->phy;
- int err, tmp;
+ int err;
u32 value32, macctl;
u16 value16;
@@ -2725,19 +2729,19 @@ static int b43_chip_init(struct b43_wldev *dev)
err = b43_upload_initvals(dev);
if (err)
goto err_gpio_clean;
- b43_radio_turn_on(dev);
b43_write16(dev, 0x03E6, 0x0000);
err = b43_phy_init(dev);
if (err)
- goto err_radio_off;
+ goto err_gpio_clean;
- /* Select initial Interference Mitigation. */
- tmp = phy->interfmode;
- phy->interfmode = B43_INTERFMODE_NONE;
- b43_radio_set_interference_mitigation(dev, tmp);
+ /* Disable Interference Mitigation. */
+ if (phy->ops->interf_mitigation)
+ phy->ops->interf_mitigation(dev, B43_INTERFMODE_NONE);
- b43_set_rx_antenna(dev, B43_ANTENNA_DEFAULT);
+ /* Select the antennae */
+ if (phy->ops->set_rx_antenna)
+ phy->ops->set_rx_antenna(dev, B43_ANTENNA_DEFAULT);
b43_mgmtframe_txantenna(dev, B43_ANTENNA_DEFAULT);
if (phy->type == B43_PHYTYPE_B) {
@@ -2790,8 +2794,6 @@ static int b43_chip_init(struct b43_wldev *dev)
out:
return err;
-err_radio_off:
- b43_radio_turn_off(dev, 1);
err_gpio_clean:
b43_gpio_cleanup(dev);
return err;
@@ -2799,25 +2801,10 @@ err_gpio_clean:
static void b43_periodic_every60sec(struct b43_wldev *dev)
{
- struct b43_phy *phy = &dev->phy;
+ const struct b43_phy_operations *ops = dev->phy.ops;
- if (phy->type != B43_PHYTYPE_G)
- return;
- if (dev->dev->bus->sprom.boardflags_lo & B43_BFL_RSSI) {
- b43_mac_suspend(dev);
- b43_calc_nrssi_slope(dev);
- if ((phy->radio_ver == 0x2050) && (phy->radio_rev == 8)) {
- u8 old_chan = phy->channel;
-
- /* VCO Calibration */
- if (old_chan >= 8)
- b43_radio_selectchannel(dev, 1, 0);
- else
- b43_radio_selectchannel(dev, 13, 0);
- b43_radio_selectchannel(dev, old_chan, 0);
- }
- b43_mac_enable(dev);
- }
+ if (ops->pwork_60sec)
+ ops->pwork_60sec(dev);
}
static void b43_periodic_every30sec(struct b43_wldev *dev)
@@ -2845,32 +2832,10 @@ static void b43_periodic_every15sec(struct b43_wldev *dev)
}
}
- if (phy->type == B43_PHYTYPE_G) {
- //TODO: update_aci_moving_average
- if (phy->aci_enable && phy->aci_wlan_automatic) {
- b43_mac_suspend(dev);
- if (!phy->aci_enable && 1 /*TODO: not scanning? */ ) {
- if (0 /*TODO: bunch of conditions */ ) {
- b43_radio_set_interference_mitigation
- (dev, B43_INTERFMODE_MANUALWLAN);
- }
- } else if (1 /*TODO*/) {
- /*
- if ((aci_average > 1000) && !(b43_radio_aci_scan(dev))) {
- b43_radio_set_interference_mitigation(dev,
- B43_INTERFMODE_NONE);
- }
- */
- }
- b43_mac_enable(dev);
- } else if (phy->interfmode == B43_INTERFMODE_NONWLAN &&
- phy->rev == 1) {
- //TODO: implement rev1 workaround
- }
- }
- b43_phy_xmitpower(dev); //FIXME: unless scanning?
- b43_lo_g_maintanance_work(dev);
- //TODO for APHY (temperature?)
+ if (phy->ops->pwork_15sec)
+ phy->ops->pwork_15sec(dev);
+
+ phy->ops->xmitpower(dev);
atomic_set(&phy->txerr_cnt, B43_PHY_TX_BADNESS_LIMIT);
wmb();
@@ -3401,7 +3366,7 @@ static int b43_op_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
/* Switch to the requested channel.
* The firmware takes care of races with the TX handler. */
if (conf->channel->hw_value != phy->channel)
- b43_radio_selectchannel(dev, conf->channel->hw_value, 0);
+ b43_switch_channel(dev, conf->channel->hw_value);
/* Enable/Disable ShortSlot timing. */
if ((!!(conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME)) !=
@@ -3419,7 +3384,7 @@ static int b43_op_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
if (conf->power_level != 0) {
if (conf->power_level != phy->power_level) {
phy->power_level = conf->power_level;
- b43_phy_xmitpower(dev);
+ phy->ops->xmitpower(dev);
}
}
@@ -3427,7 +3392,8 @@ static int b43_op_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
antenna = b43_antenna_from_ieee80211(dev, conf->antenna_sel_tx);
b43_mgmtframe_txantenna(dev, antenna);
antenna = b43_antenna_from_ieee80211(dev, conf->antenna_sel_rx);
- b43_set_rx_antenna(dev, antenna);
+ if (phy->ops->set_rx_antenna)
+ phy->ops->set_rx_antenna(dev, antenna);
/* Update templates for AP/mesh mode. */
if (b43_is_mode(wl, IEEE80211_IF_TYPE_AP) ||
@@ -3436,7 +3402,7 @@ static int b43_op_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
if (!!conf->radio_enabled != phy->radio_on) {
if (conf->radio_enabled) {
- b43_radio_turn_on(dev);
+ b43_software_rfkill(dev, RFKILL_STATE_UNBLOCKED);
b43info