mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-27 03:20:56 +07:00
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>
This commit is contained in:
parent
35e032d82f
commit
ef1a628d83
@ -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
|
||||
|
@ -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);
|
||||
|
@ -443,76 +443,6 @@ static ssize_t txstat_read_file(struct b43_wldev *dev,
|
||||
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);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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 @@ static int b43_chip_init(struct b43_wldev *dev)
|
||||
|
||||
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(dev->wl, "Radio turned on by software\n");
|
||||
if (!dev->radio_hw_enable) {
|
||||
b43info(dev->wl, "The hardware RF-kill button "
|
||||
@ -3444,7 +3410,7 @@ static int b43_op_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
|
||||
"Press the button to turn it on.\n");
|
||||
}
|
||||
} else {
|
||||
b43_radio_turn_off(dev, 0);
|
||||
b43_software_rfkill(dev, RFKILL_STATE_SOFT_BLOCKED);
|
||||
b43info(dev->wl, "Radio turned off by software\n");
|
||||
}
|
||||
}
|
||||
@ -3818,48 +3784,9 @@ static int b43_phy_versioning(struct b43_wldev *dev)
|
||||
static void setup_struct_phy_for_init(struct b43_wldev *dev,
|
||||
struct b43_phy *phy)
|
||||
{
|
||||
struct b43_txpower_lo_control *lo;
|
||||
int i;
|
||||
|
||||
memset(phy->minlowsig, 0xFF, sizeof(phy->minlowsig));
|
||||
memset(phy->minlowsigpos, 0, sizeof(phy->minlowsigpos));
|
||||
|
||||
phy->aci_enable = 0;
|
||||
phy->aci_wlan_automatic = 0;
|
||||
phy->aci_hw_rssi = 0;
|
||||
|
||||
phy->radio_off_context.valid = 0;
|
||||
|
||||
lo = phy->lo_control;
|
||||
if (lo) {
|
||||
memset(lo, 0, sizeof(*(phy->lo_control)));
|
||||
lo->tx_bias = 0xFF;
|
||||
INIT_LIST_HEAD(&lo->calib_list);
|
||||
}
|
||||
phy->max_lb_gain = 0;
|
||||
phy->trsw_rx_gain = 0;
|
||||
phy->txpwr_offset = 0;
|
||||
|
||||
/* NRSSI */
|
||||
phy->nrssislope = 0;
|
||||
for (i = 0; i < ARRAY_SIZE(phy->nrssi); i++)
|
||||
phy->nrssi[i] = -1000;
|
||||
for (i = 0; i < ARRAY_SIZE(phy->nrssi_lt); i++)
|
||||
phy->nrssi_lt[i] = i;
|
||||
|
||||
phy->lofcal = 0xFFFF;
|
||||
phy->initval = 0xFFFF;
|
||||
|
||||
phy->interfmode = B43_INTERFMODE_NONE;
|
||||
phy->channel = 0xFF;
|
||||
|
||||
phy->hardware_power_control = !!modparam_hwpctl;
|
||||
|
||||
/* PHY TX errors counter. */
|
||||
atomic_set(&phy->txerr_cnt, B43_PHY_TX_BADNESS_LIMIT);
|
||||
|
||||
/* OFDM-table address caching. */
|
||||
phy->ofdmtab_addr_direction = B43_OFDMTAB_DIRECTION_UNKNOWN;
|
||||
}
|
||||
|
||||
static void setup_struct_wldev_for_init(struct b43_wldev *dev)
|
||||
@ -3995,7 +3922,6 @@ static void b43_set_pretbtt(struct b43_wldev *dev)
|
||||
/* Locking: wl->mutex */
|
||||
static void b43_wireless_core_exit(struct b43_wldev *dev)
|
||||
{
|
||||
struct b43_phy *phy = &dev->phy;
|
||||
u32 macctl;
|
||||
|
||||
B43_WARN_ON(b43_status(dev) > B43_STAT_INITIALIZED);
|
||||
@ -4016,16 +3942,12 @@ static void b43_wireless_core_exit(struct b43_wldev *dev)
|
||||
b43_dma_free(dev);
|
||||
b43_pio_free(dev);
|
||||
b43_chip_exit(dev);
|
||||
b43_radio_turn_off(dev, 1);
|
||||
b43_switch_analog(dev, 0);
|
||||
if (phy->dyn_tssi_tbl)
|
||||
kfree(phy->tssi2dbm);
|
||||
kfree(phy->lo_control);
|
||||
phy->lo_control = NULL;
|
||||
if (dev->wl->current_beacon) {
|
||||
dev_kfree_skb_any(dev->wl->current_beacon);
|
||||
dev->wl->current_beacon = NULL;
|
||||
}
|
||||
b43_phy_exit(dev);
|
||||
|
||||
ssb_device_disable(dev->dev, 0);
|
||||
ssb_bus_may_powerdown(dev->dev->bus);
|
||||
@ -4052,29 +3974,24 @@ static int b43_wireless_core_init(struct b43_wldev *dev)
|
||||
b43_wireless_core_reset(dev, tmp);
|
||||
}
|
||||
|
||||
if ((phy->type == B43_PHYTYPE_B) || (phy->type == B43_PHYTYPE_G)) {
|
||||
phy->lo_control =
|
||||
kzalloc(sizeof(*(phy->lo_control)), GFP_KERNEL);
|
||||
if (!phy->lo_control) {
|
||||
err = -ENOMEM;
|
||||
goto err_busdown;
|
||||
}
|
||||
}
|
||||
setup_struct_wldev_for_init(dev);
|
||||
|
||||
err = b43_phy_init_tssi2dbm_table(dev);
|
||||
err = b43_phy_operations_setup(dev);
|
||||
if (err)
|
||||
goto err_kfree_lo_control;
|
||||
goto err_busdown;
|
||||
|
||||
/* Enable IRQ routing to this device. */
|
||||
ssb_pcicore_dev_irqvecs_enable(&bus->pcicore, dev->dev);
|
||||
|
||||
b43_imcfglo_timeouts_workaround(dev);
|
||||
b43_bluetooth_coext_disable(dev);
|
||||
b43_phy_early_init(dev);
|
||||
if (phy->ops->prepare) {
|
||||
err = phy->ops->prepare(dev);
|
||||
if (err)
|
||||
goto err_phy_exit;
|
||||
}
|
||||
err = b43_chip_init(dev);
|
||||
if (err)
|
||||
goto err_kfree_tssitbl;
|
||||
goto err_phy_exit;
|
||||
b43_shm_write16(dev, B43_SHM_SHARED,
|
||||
B43_SHM_SH_WLCOREREV, dev->dev->id.revision);
|
||||
hf = b43_hf_read(dev);
|
||||
@ -4140,15 +4057,11 @@ static int b43_wireless_core_init(struct b43_wldev *dev)
|
||||
out:
|
||||
return err;
|
||||
|
||||
err_chip_exit:
|
||||
err_chip_exit:
|
||||
b43_chip_exit(dev);
|
||||
err_kfree_tssitbl:
|
||||
if (phy->dyn_tssi_tbl)
|
||||
kfree(phy->tssi2dbm);
|
||||
err_kfree_lo_control:
|
||||
kfree(phy->lo_control);
|
||||
phy->lo_control = NULL;
|
||||
err_busdown:
|
||||
err_phy_exit:
|
||||
b43_phy_exit(dev);
|
||||
err_busdown:
|
||||
ssb_bus_may_powerdown(bus);
|
||||
B43_WARN_ON(b43_status(dev) != B43_STAT_UNINIT);
|
||||
return err;
|
||||
@ -4511,7 +4424,6 @@ static int b43_wireless_core_attach(struct b43_wldev *dev)
|
||||
wl->current_dev = dev;
|
||||
INIT_WORK(&dev->restart_work, b43_chip_reset);
|
||||
|
||||
b43_radio_turn_off(dev, 1);
|
||||
b43_switch_analog(dev, 0);
|
||||
ssb_device_disable(dev->dev, 0);
|
||||
ssb_bus_may_powerdown(bus);
|
||||
|
@ -81,9 +81,8 @@ static void b43_nphy_tx_power_fix(struct b43_wldev *dev)
|
||||
//TODO
|
||||
}
|
||||
|
||||
/* Tune the hardware to a new channel. Don't call this directly.
|
||||
* Use b43_radio_selectchannel() */
|
||||
int b43_nphy_selectchannel(struct b43_wldev *dev, u8 channel)
|
||||
/* Tune the hardware to a new channel. */
|
||||
static int nphy_channel_switch(struct b43_wldev *dev, unsigned int channel)
|
||||
{
|
||||
const struct b43_nphy_channeltab_entry *tabent;
|
||||
|
||||
@ -162,7 +161,7 @@ static void b43_radio_init2055_post(struct b43_wldev *dev)
|
||||
msleep(1);
|
||||
b43_radio_mask(dev, B2055_CAL_LPOCTL, 0xFF7F);
|
||||
msleep(1);
|
||||
b43_radio_selectchannel(dev, dev->phy.channel, 0);
|
||||
nphy_channel_switch(dev, dev->phy.channel);
|
||||
b43_radio_write16(dev, B2055_C1_RX_BB_LPF, 0x9);
|
||||
b43_radio_write16(dev, B2055_C2_RX_BB_LPF, 0x9);
|
||||
b43_radio_write16(dev, B2055_C1_RX_BB_MIDACHP, 0x83);
|
||||
@ -484,3 +483,139 @@ int b43_phy_initn(struct b43_wldev *dev)
|
||||
b43err(dev->wl, "IEEE 802.11n devices are not supported, yet.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int b43_nphy_op_allocate(struct b43_wldev *dev)
|
||||
{
|
||||
struct b43_phy_n *nphy;
|
||||
|
||||
nphy = kzalloc(sizeof(*nphy), GFP_KERNEL);
|
||||
if (!nphy)
|
||||
return -ENOMEM;
|
||||
dev->phy.n = nphy;
|
||||
|
||||
//TODO init struct b43_phy_n
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int b43_nphy_op_init(struct b43_wldev *dev)
|
||||
{
|
||||
struct b43_phy_n *nphy = dev->phy.n;
|
||||
int err;
|
||||
|
||||
err = b43_phy_initn(dev);
|
||||
if (err)
|
||||
return err;
|
||||
nphy->initialised = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void b43_nphy_op_exit(struct b43_wldev *dev)
|
||||
{
|
||||
struct b43_phy_n *nphy = dev->phy.n;
|
||||
|
||||
if (nphy->initialised) {
|
||||
//TODO
|
||||
nphy->initialised = 0;
|
||||
}
|
||||
//TODO
|
||||
kfree(nphy);
|
||||
dev->phy.n = NULL;
|
||||
}
|
||||
|
||||
static inline void check_phyreg(struct b43_wldev *dev, u16 offset)
|
||||
{
|
||||
#if B43_DEBUG
|
||||
if ((offset & B43_PHYROUTE) == B43_PHYROUTE_OFDM_GPHY) {
|
||||
/* OFDM registers are onnly available on A/G-PHYs */
|
||||
b43err(dev->wl, "Invalid OFDM PHY access at "
|
||||
"0x%04X on N-PHY\n", offset);
|
||||
dump_stack();
|
||||
}
|
||||
if ((offset & B43_PHYROUTE) == B43_PHYROUTE_EXT_GPHY) {
|
||||
/* Ext-G registers are only available on G-PHYs */
|
||||
b43err(dev->wl, "Invalid EXT-G PHY access at "
|
||||
"0x%04X on N-PHY\n", offset);
|
||||
dump_stack();
|
||||
}
|
||||
#endif /* B43_DEBUG */
|
||||
}
|
||||
|
||||
static u16 b43_nphy_op_read(struct b43_wldev *dev, u16 reg)
|
||||
{
|
||||
check_phyreg(dev, reg);
|
||||
b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
|
||||
return b43_read16(dev, B43_MMIO_PHY_DATA);
|
||||
}
|
||||
|
||||
static void b43_nphy_op_write(struct b43_wldev *dev, u16 reg, u16 value)
|
||||
{
|
||||
check_phyreg(dev, reg);
|
||||
b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
|
||||
b43_write16(dev, B43_MMIO_PHY_DATA, value);
|
||||
}
|
||||
|
||||
static u16 b43_nphy_op_radio_read(struct b43_wldev *dev, u16 reg)
|
||||
{
|
||||
/* Register 1 is a 32-bit register. */
|
||||
B43_WARN_ON(reg == 1);
|
||||
/* N-PHY needs 0x100 for read access */
|
||||
reg |= 0x100;
|
||||
|
||||
b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
|
||||
return b43_read16(dev, B43_MMIO_RADIO_DATA_LOW);
|
||||
}
|
||||
|
||||
static void b43_nphy_op_radio_write(struct b43_wldev *dev, u16 reg, u16 value)
|
||||
{
|
||||
/* Register 1 is a 32-bit register. */
|
||||
B43_WARN_ON(reg == 1);
|
||||
|
||||
b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
|
||||
b43_write16(dev, B43_MMIO_RADIO_DATA_LOW, value);
|
||||
}
|
||||
|
||||
static void b43_nphy_op_software_rfkill(struct b43_wldev *dev,
|
||||
enum rfkill_state state)
|
||||
{//TODO
|
||||
}
|
||||
|
||||
static int b43_nphy_op_switch_channel(struct b43_wldev *dev,
|
||||
unsigned int new_channel)
|
||||
{
|
||||
if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
|
||||
if ((new_channel < 1) || (new_channel > 14))
|
||||
return -EINVAL;
|
||||
} else {
|
||||
if (new_channel > 200)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return nphy_channel_switch(dev, new_channel);
|
||||
}
|
||||
|
||||
static unsigned int b43_nphy_op_get_default_chan(struct b43_wldev *dev)
|
||||
{
|
||||
if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
|
||||
return 1;
|
||||
return 36;
|
||||
}
|
||||
|
||||
static void b43_nphy_op_xmitpower(struct b43_wldev *dev)
|
||||
{//TODO
|
||||
}
|
||||
|
||||
const struct b43_phy_operations b43_phyops_n = {
|
||||
.allocate = b43_nphy_op_allocate,
|
||||
.init = b43_nphy_op_init,
|
||||
.exit = b43_nphy_op_exit,
|
||||
.phy_read = b43_nphy_op_read,
|
||||
.phy_write = b43_nphy_op_write,
|
||||
.radio_read = b43_nphy_op_radio_read,
|
||||
.radio_write = b43_nphy_op_radio_write,
|
||||
.software_rfkill = b43_nphy_op_software_rfkill,
|
||||
.switch_channel = b43_nphy_op_switch_channel,
|
||||
.get_default_chan = b43_nphy_op_get_default_chan,
|
||||
.xmitpower = b43_nphy_op_xmitpower,
|
||||
};
|
||||
|
@ -1,7 +1,7 @@
|
||||
#ifndef B43_NPHY_H_
|
||||
#define B43_NPHY_H_
|
||||
|
||||
#include "phy.h"
|
||||
#include "phy_common.h"
|
||||
|
||||
|
||||
/* N-PHY registers. */
|
||||
@ -919,54 +919,14 @@
|
||||
|
||||
struct b43_wldev;
|
||||
|
||||
struct b43_phy_n {
|
||||
bool initialised;
|
||||
|
||||
#ifdef CONFIG_B43_NPHY
|
||||
/* N-PHY support enabled */
|
||||
|
||||
int b43_phy_initn(struct b43_wldev *dev);
|
||||
|
||||
void b43_nphy_radio_turn_on(struct b43_wldev *dev);
|
||||
void b43_nphy_radio_turn_off(struct b43_wldev *dev);
|
||||
|
||||
int b43_nphy_selectchannel(struct b43_wldev *dev, u8 channel);
|
||||
|
||||
void b43_nphy_xmitpower(struct b43_wldev *dev);
|
||||
void b43_nphy_set_rxantenna(struct b43_wldev *dev, int antenna);
|
||||
//TODO lots of missing stuff
|
||||
};
|
||||
|
||||
|
||||
#else /* CONFIG_B43_NPHY */
|
||||
/* N-PHY support disabled */
|
||||
struct b43_phy_operations;
|
||||
extern const struct b43_phy_operations b43_phyops_n;
|
||||
|
||||
|
||||
static inline
|
||||
int b43_phy_initn(struct b43_wldev *dev)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline
|
||||
void b43_nphy_radio_turn_on(struct b43_wldev *dev)
|
||||
{
|
||||
}
|
||||
static inline
|
||||
void b43_nphy_radio_turn_off(struct b43_wldev *dev)
|
||||
{
|
||||
}
|
||||
|
||||
static inline
|
||||
int b43_nphy_selectchannel(struct b43_wldev *dev, u8 channel)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
static inline
|
||||
void b43_nphy_xmitpower(struct b43_wldev *dev)
|
||||
{
|
||||
}
|
||||
static inline
|
||||
void b43_nphy_set_rxantenna(struct b43_wldev *dev, int antenna)
|
||||
{
|
||||
}
|
||||
|
||||
#endif /* CONFIG_B43_NPHY */
|
||||
#endif /* B43_NPHY_H_ */
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,340 +0,0 @@
|
||||
#ifndef B43_PHY_H_
|
||||
#define B43_PHY_H_
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
struct b43_wldev;
|
||||
struct b43_phy;
|
||||
|
||||
/*** PHY Registers ***/
|
||||
|
||||
/* Routing */
|
||||
#define B43_PHYROUTE 0x0C00 /* PHY register routing bits mask */
|
||||
#define B43_PHYROUTE_BASE 0x0000 /* Base registers */
|
||||
#define B43_PHYROUTE_OFDM_GPHY 0x0400 /* OFDM register routing for G-PHYs */
|
||||
#define B43_PHYROUTE_EXT_GPHY 0x0800 /* Extended G-PHY registers */
|
||||
#define B43_PHYROUTE_N_BMODE 0x0C00 /* N-PHY BMODE registers */
|
||||
|
||||
/* CCK (B-PHY) registers. */
|
||||
#define B43_PHY_CCK(reg) ((reg) | B43_PHYROUTE_BASE)
|
||||
/* N-PHY registers. */
|
||||
#define B43_PHY_N(reg) ((reg) | B43_PHYROUTE_BASE)
|
||||
/* N-PHY BMODE registers. */
|
||||
#define B43_PHY_N_BMODE(reg) ((reg) | B43_PHYROUTE_N_BMODE)
|
||||
/* OFDM (A-PHY) registers. */
|
||||
#define B43_PHY_OFDM(reg) ((reg) | B43_PHYROUTE_OFDM_GPHY)
|
||||
/* Extended G-PHY registers. */
|
||||
#define B43_PHY_EXTG(reg) ((reg) | B43_PHYROUTE_EXT_GPHY)
|
||||
|
||||
/* OFDM (A) PHY Registers */
|
||||
#define B43_PHY_VERSION_OFDM B43_PHY_OFDM(0x00) /* Versioning register for A-PHY */
|
||||
#define B43_PHY_BBANDCFG B43_PHY_OFDM(0x01) /* Baseband config */
|
||||
#define B43_PHY_BBANDCFG_RXANT 0x180 /* RX Antenna selection */
|
||||
#define B43_PHY_BBANDCFG_RXANT_SHIFT 7
|
||||
#define B43_PHY_PWRDOWN B43_PHY_OFDM(0x03) /* Powerdown */
|
||||
#define B43_PHY_CRSTHRES1_R1 B43_PHY_OFDM(0x06) /* CRS Threshold 1 (phy.rev 1 only) */
|
||||
#define B43_PHY_LNAHPFCTL B43_PHY_OFDM(0x1C) /* LNA/HPF control */
|
||||
#define B43_PHY_LPFGAINCTL B43_PHY_OFDM(0x20) /* LPF Gain control */
|
||||
#define B43_PHY_ADIVRELATED B43_PHY_OFDM(0x27) /* FIXME rename */
|
||||
#define B43_PHY_CRS0 B43_PHY_OFDM(0x29)
|
||||
#define B43_PHY_CRS0_EN 0x4000
|
||||
#define B43_PHY_PEAK_COUNT B43_PHY_OFDM(0x30)
|
||||
#define B43_PHY_ANTDWELL B43_PHY_OFDM(0x2B) /* Antenna dwell */
|
||||
#define B43_PHY_ANTDWELL_AUTODIV1 0x0100 /* Automatic RX diversity start antenna */
|
||||
#define B43_PHY_ENCORE B43_PHY_OFDM(0x49) /* "Encore" (RangeMax / BroadRange) */
|
||||
#define B43_PHY_ENCORE_EN 0x0200 /* Encore enable */
|
||||
#define B43_PHY_LMS B43_PHY_OFDM(0x55)
|
||||
#define B43_PHY_OFDM61 B43_PHY_OFDM(0x61) /* FIXME rename */
|
||||
#define B43_PHY_OFDM61_10 0x0010 /* FIXME rename */
|
||||
#define B43_PHY_IQBAL B43_PHY_OFDM(0x69) /* I/Q balance */
|
||||
#define B43_PHY_BBTXDC_BIAS B43_PHY_OFDM(0x6B) /* Baseband TX DC bias */
|
||||
#define B43_PHY_OTABLECTL B43_PHY_OFDM(0x72) /* OFDM table control (see below) */
|
||||
#define B43_PHY_OTABLEOFF 0x03FF /* OFDM table offset (see below) */
|
||||
#define B43_PHY_OTABLENR 0xFC00 /* OFDM table number (see below) */
|
||||
#define B43_PHY_OTABLENR_SHIFT 10
|
||||
#define B43_PHY_OTABLEI B43_PHY_OFDM(0x73) /* OFDM table data I */
|
||||
#define B43_PHY_OTABLEQ B43_PHY_OFDM(0x74) /* OFDM table data Q */
|
||||
#define B43_PHY_HPWR_TSSICTL B43_PHY_OFDM(0x78) /* Hardware power TSSI control */
|
||||
#define B43_PHY_ADCCTL B43_PHY_OFDM(0x7A) /* ADC control */
|
||||
#define B43_PHY_IDLE_TSSI B43_PHY_OFDM(0x7B)
|
||||
#define B43_PHY_A_TEMP_SENSE B43_PHY_OFDM(0x7C) /* A PHY temperature sense */
|
||||
#define B43_PHY_NRSSITHRES B43_PHY_OFDM(0x8A) /* NRSSI threshold */
|
||||
#define B43_PHY_ANTWRSETT B43_PHY_OFDM(0x8C) /* Antenna WR settle */
|
||||
#define B43_PHY_ANTWRSETT_ARXDIV 0x2000 /* Automatic RX diversity enabled */
|
||||
#define B43_PHY_CLIPPWRDOWNT B43_PHY_OFDM(0x93) /* Clip powerdown threshold */
|
||||
#define B43_PHY_OFDM9B B43_PHY_OFDM(0x9B) /* FIXME rename */
|
||||
#define B43_PHY_N1P1GAIN B43_PHY_OFDM(0xA0)
|
||||
#define B43_PHY_P1P2GAIN B43_PHY_OFDM(0xA1)
|
||||
#define B43_PHY_N1N2GAIN B43_PHY_OFDM(0xA2)
|
||||
#define B43_PHY_CLIPTHRES B43_PHY_OFDM(0xA3)
|
||||
#define B43_PHY_CLIPN1P2THRES B43_PHY_OFDM(0xA4)
|
||||
#define B43_PHY_CCKSHIFTBITS_WA B43_PHY_OFDM(0xA5) /* CCK shiftbits workaround, FIXME rename */
|
||||
#define B43_PHY_CCKSHIFTBITS B43_PHY_OFDM(0xA7) /* FIXME rename */
|
||||
#define B43_PHY_DIVSRCHIDX B43_PHY_OFDM(0xA8) /* Divider search gain/index */
|
||||
#define B43_PHY_CLIPP2THRES B43_PHY_OFDM(0xA9)
|
||||
#define B43_PHY_CLIPP3THRES B43_PHY_OFDM(0xAA)
|
||||
#define B43_PHY_DIVP1P2GAIN B43_PHY_OFDM(0xAB)
|
||||
#define B43_PHY_DIVSRCHGAINBACK B43_PHY_OFDM(0xAD) /* Divider search gain back */
|
||||
#define B43_PHY_DIVSRCHGAINCHNG B43_PHY_OFDM(0xAE) /* Divider search gain change */
|
||||
#define B43_PHY_CRSTHRES1 B43_PHY_OFDM(0xC0) /* CRS Threshold 1 (phy.rev >= 2 only) */
|
||||
#define B43_PHY_CRSTHRES2 B43_PHY_OFDM(0xC1) /* CRS Threshold 2 (phy.rev >= 2 only) */
|
||||
#define B43_PHY_TSSIP_LTBASE B43_PHY_OFDM(0x380) /* TSSI power lookup table base */
|
||||
#define B43_PHY_DC_LTBASE B43_PHY_OFDM(0x3A0) /* DC lookup table base */
|
||||
#define B43_PHY_GAIN_LTBASE B43_PHY_OFDM(0x3C0) /* Gain lookup table base */
|
||||
|
||||
/* CCK (B) PHY Registers */
|
||||
#define B43_PHY_VERSION_CCK B43_PHY_CCK(0x00) /* Versioning register for B-PHY */
|
||||
#define B43_PHY_CCKBBANDCFG B43_PHY_CCK(0x01) /* Contains antenna 0/1 control bit */
|
||||
#define B43_PHY_PGACTL B43_PHY_CCK(0x15) /* PGA control */
|
||||
#define B43_PHY_PGACTL_LPF 0x1000 /* Low pass filter (?) */
|
||||
#define B43_PHY_PGACTL_LOWBANDW 0x0040 /* Low bandwidth flag */
|
||||
#define B43_PHY_PGACTL_UNKNOWN 0xEFA0
|
||||
#define B43_PHY_FBCTL1 B43_PHY_CCK(0x18) /* Frequency bandwidth control 1 */
|
||||
#define B43_PHY_ITSSI B43_PHY_CCK(0x29) /* Idle TSSI */
|
||||
#define B43_PHY_LO_LEAKAGE B43_PHY_CCK(0x2D) /* Measured LO leakage */
|
||||
#define B43_PHY_ENERGY B43_PHY_CCK(0x33) /* Energy */
|
||||
#define B43_PHY_SYNCCTL B43_PHY_CCK(0x35)
|
||||
#define B43_PHY_FBCTL2 B43_PHY_CCK(0x38) /* Frequency bandwidth control 2 */
|
||||
#define B43_PHY_DACCTL B43_PHY_CCK(0x60) /* DAC control */
|
||||
#define B43_PHY_RCCALOVER B43_PHY_CCK(0x78) /* RC calibration override */
|
||||
|
||||
/* Extended G-PHY Registers */
|
||||
#define B43_PHY_CLASSCTL B43_PHY_EXTG(0x02) /* Classify control */
|
||||
#define B43_PHY_GTABCTL B43_PHY_EXTG(0x03) /* G-PHY table control (see below) */
|
||||
#define B43_PHY_GTABOFF 0x03FF /* G-PHY table offset (see below) */
|
||||
#define B43_PHY_GTABNR 0xFC00 /* G-PHY table number (see below) */
|
||||
#define B43_PHY_GTABNR_SHIFT 10
|
||||
#define B43_PHY_GTABDATA B43_PHY_EXTG(0x04) /* G-PHY table data */
|
||||
#define B43_PHY_LO_MASK B43_PHY_EXTG(0x0F) /* Local Oscillator control mask */
|
||||
#define B43_PHY_LO_CTL B43_PHY_EXTG(0x10) /* Local Oscillator control */
|
||||
#define B43_PHY_RFOVER B43_PHY_EXTG(0x11) /* RF override */
|
||||
#define B43_PHY_RFOVERVAL B43_PHY_EXTG(0x12) /* RF override value */
|
||||
#define B43_PHY_RFOVERVAL_EXTLNA 0x8000
|
||||
#define B43_PHY_RFOVERVAL_LNA 0x7000
|
||||
#define B43_PHY_RFOVERVAL_LNA_SHIFT 12
|
||||
#define B43_PHY_RFOVERVAL_PGA 0x0F00
|
||||
#define B43_PHY_RFOVERVAL_PGA_SHIFT 8
|
||||
#define B43_PHY_RFOVERVAL_UNK 0x0010 /* Unknown, always set. */
|
||||
#define B43_PHY_RFOVERVAL_TRSWRX 0x00E0
|
||||
#define B43_PHY_RFOVERVAL_BW 0x0003 /* Bandwidth flags */
|
||||
#define B43_PHY_RFOVERVAL_BW_LPF 0x0001 /* Low Pass Filter */
|
||||
#define B43_PHY_RFOVERVAL_BW_LBW 0x0002 /* Low Bandwidth (when set), high when unset */
|
||||
#define B43_PHY_ANALOGOVER B43_PHY_EXTG(0x14) /* Analog override */
|
||||
#define B43_PHY_ANALOGOVERVAL B43_PHY_EXTG(0x15) /* Analog override value */
|
||||
|
||||
/*** OFDM table numbers ***/
|
||||
#define B43_OFDMTAB(number, offset) (((number) << B43_PHY_OTABLENR_SHIFT) | (offset))
|
||||
#define B43_OFDMTAB_AGC1 B43_OFDMTAB(0x00, 0)
|
||||
#define B43_OFDMTAB_GAIN0 B43_OFDMTAB(0x00, 0)
|
||||
#define B43_OFDMTAB_GAINX B43_OFDMTAB(0x01, 0) //TODO rename
|
||||
#define B43_OFDMTAB_GAIN1 B43_OFDMTAB(0x01, 4)
|
||||
#define B43_OFDMTAB_AGC3 B43_OFDMTAB(0x02, 0)
|
||||
#define B43_OFDMTAB_GAIN2 B43_OFDMTAB(0x02, 3)
|
||||
#define B43_OFDMTAB_LNAHPFGAIN1 B43_OFDMTAB(0x03, 0)
|
||||
#define B43_OFDMTAB_WRSSI B43_OFDMTAB(0x04, 0)
|
||||
#define B43_OFDMTAB_LNAHPFGAIN2 B43_OFDMTAB(0x04, 0)
|
||||
#define B43_OFDMTAB_NOISESCALE B43_OFDMTAB(0x05, 0)
|
||||
#define B43_OFDMTAB_AGC2 B43_OFDMTAB(0x06, 0)
|
||||
#define B43_OFDMTAB_ROTOR B43_OFDMTAB(0x08, 0)
|
||||
#define B43_OFDMTAB_ADVRETARD B43_OFDMTAB(0x09, 0)
|
||||
#define B43_OFDMTAB_DAC B43_OFDMTAB(0x0C, 0)
|
||||
#define B43_OFDMTAB_DC B43_OFDMTAB(0x0E, 7)
|
||||
#define B43_OFDMTAB_PWRDYN2 B43_OFDMTAB(0x0E, 12)
|
||||
#define B43_OFDMTAB_LNAGAIN B43_OFDMTAB(0x0E, 13)
|
||||
#define B43_OFDMTAB_UNKNOWN_0F B43_OFDMTAB(0x0F, 0) //TODO rename
|
||||
#define B43_OFDMTAB_UNKNOWN_APHY B43_OFDMTAB(0x0F, 7) //TODO rename
|
||||
#define B43_OFDMTAB_LPFGAIN B43_OFDMTAB(0x0F, 12)
|
||||
#define B43_OFDMTAB_RSSI B43_OFDMTAB(0x10, 0)
|
||||
#define B43_OFDMTAB_UNKNOWN_11 B43_OFDMTAB(0x11, 4) //TODO rename
|
||||
#define B43_OFDMTAB_AGC1_R1 B43_OFDMTAB(0x13, 0)
|
||||
#define B43_OFDMTAB_GAINX_R1 B43_OFDMTAB(0x14, 0) //TODO remove!
|
||||
#define B43_OFDMTAB_MINSIGSQ B43_OFDMTAB(0x14, 0)
|
||||
#define B43_OFDMTAB_AGC3_R1 B43_OFDMTAB(0x15, 0)
|
||||
#define B43_OFDMTAB_WRSSI_R1 B43_OFDMTAB(0x15, 4)
|
||||
#define B43_OFDMTAB_TSSI B43_OFDMTAB(0x15, 0)
|
||||
#define B43_OFDMTAB_DACRFPABB B43_OFDMTAB(0x16, 0)
|
||||
#define B43_OFDMTAB_DACOFF B43_OFDMTAB(0x17, 0)
|
||||
#define B43_OFDMTAB_DCBIAS B43_OFDMTAB(0x18, 0)
|
||||
|
||||
u16 b43_ofdmtab_read16(struct b43_wldev *dev, u16 table, u16 offset);
|
||||
void b43_ofdmtab_write16(struct b43_wldev *dev, u16 table,
|
||||
u16 offset, u16 value);
|
||||
u32 b43_ofdmtab_read32(struct b43_wldev *dev, u16 table, u16 offset);
|
||||
void b43_ofdmtab_write32(struct b43_wldev *dev, u16 table,
|
||||
u16 offset, u32 value);
|
||||
|
||||
/*** G-PHY table numbers */
|
||||
#define B43_GTAB(number, offset) (((number) << B43_PHY_GTABNR_SHIFT) | (offset))
|
||||
#define B43_GTAB_NRSSI B43_GTAB(0x00, 0)
|
||||
#define B43_GTAB_TRFEMW B43_GTAB(0x0C, 0x120)
|
||||
#define B43_GTAB_ORIGTR B43_GTAB(0x2E, 0x298)
|
||||
|
||||
u16 b43_gtab_read(struct b43_wldev *dev, u16 table, u16 offset); //TODO implement
|
||||
void b43_gtab_write(struct b43_wldev *dev, u16 table, u16 offset, u16 value); //TODO implement
|
||||
|
||||
#define B43_DEFAULT_CHANNEL_A 36
|
||||
#define B43_DEFAULT_CHANNEL_BG 6
|
||||
|
||||
enum {
|
||||
B43_ANTENNA0, /* Antenna 0 */
|
||||
B43_ANTENNA1, /* Antenna 0 */
|
||||
B43_ANTENNA_AUTO1, /* Automatic, starting with antenna 1 */
|
||||
B43_ANTENNA_AUTO0, /* Automatic, starting with antenna 0 */
|
||||
B43_ANTENNA2,
|
||||
B43_ANTENNA3 = 8,
|
||||
|
||||
B43_ANTENNA_AUTO = B43_ANTENNA_AUTO0,
|
||||
B43_ANTENNA_DEFAULT = B43_ANTENNA_AUTO,
|
||||
};
|
||||
|
||||
enum {
|
||||
B43_INTERFMODE_NONE,
|
||||
B43_INTERFMODE_NONWLAN,
|
||||
B43_INTERFMODE_MANUALWLAN,
|
||||
B43_INTERFMODE_AUTOWLAN,
|
||||
};
|
||||
|
||||
/* Masks for the different PHY versioning registers. */
|
||||
#define B43_PHYVER_ANALOG 0xF000
|
||||
#define B43_PHYVER_ANALOG_SHIFT 12
|
||||
#define B43_PHYVER_TYPE 0x0F00
|
||||
#define B43_PHYVER_TYPE_SHIFT 8
|
||||
#define B43_PHYVER_VERSION 0x00FF
|
||||
|
||||
void b43_phy_lock(struct b43_wldev *dev);
|
||||
void b43_phy_unlock(struct b43_wldev *dev);
|
||||
|
||||
|
||||
/* Read a value from a PHY register */
|
||||
u16 b43_phy_read(struct b43_wldev *dev, u16 offset);
|
||||
/* Write a value to a PHY register */
|
||||
void b43_phy_write(struct b43_wldev *dev, u16 offset, u16 val);
|
||||
/* Mask a PHY register with a mask */
|
||||
void b43_phy_mask(struct b43_wldev *dev, u16 offset, u16 mask);
|
||||
/* OR a PHY register with a bitmap */
|
||||
void b43_phy_set(struct b43_wldev *dev, u16 offset, u16 set);
|
||||
/* Mask and OR a PHY register with a mask and bitmap */
|
||||
void b43_phy_maskset(struct b43_wldev *dev, u16 offset, u16 mask, u16 set);
|
||||
|
||||
|
||||
int b43_phy_init_tssi2dbm_table(struct b43_wldev *dev);
|
||||
|
||||
void b43_phy_early_init(struct b43_wldev *dev);
|
||||
int b43_phy_init(struct b43_wldev *dev);
|
||||
|
||||
void b43_set_rx_antenna(struct b43_wldev *dev, int antenna);
|
||||
|
||||
void b43_phy_xmitpower(struct b43_wldev *dev);
|
||||
|
||||
/* Returns the boolean whether the board has HardwarePowerControl */
|
||||
bool b43_has_hardware_pctl(struct b43_phy *phy);
|
||||
/* Returns the boolean whether "TX Magnification" is enabled. */
|
||||
#define has_tx_magnification(phy) \
|
||||
(((phy)->rev >= 2) && \
|
||||
((phy)->radio_ver == 0x2050) && \
|
||||
((phy)->radio_rev == 8))
|
||||
/* Card uses the loopback gain stuff */
|
||||
#define has_loopback_gain(phy) \
|
||||
(((phy)->rev > 1) || ((phy)->gmode))
|
||||
|
||||
/* Radio Attenuation (RF Attenuation) */
|
||||
struct b43_rfatt {
|
||||
u8 att; /* Attenuation value */
|
||||
bool with_padmix; /* Flag, PAD Mixer enabled. */
|
||||
};
|
||||
struct b43_rfatt_list {
|
||||
/* Attenuation values list */
|
||||
const struct b43_rfatt *list;
|
||||
u8 len;
|
||||
/* Minimum/Maximum attenuation values */
|
||||
u8 min_val;
|
||||
u8 max_val;
|
||||
};
|
||||
|
||||
/* Returns true, if the values are the same. */
|
||||
static inline bool b43_compare_rfatt(const struct b43_rfatt *a,
|
||||
const struct b43_rfatt *b)
|
||||
{
|
||||
return ((a->att == b->att) &&
|
||||
(a->with_padmix == b->with_padmix));
|
||||
}
|
||||
|
||||
/* Baseband Attenuation */
|
||||
struct b43_bbatt {
|
||||
u8 att; /* Attenuation value */
|
||||
};
|
||||
struct b43_bbatt_list {
|
||||
/* Attenuation values list */
|
||||
const struct b43_bbatt *list;
|
||||
u8 len;
|
||||
/* Minimum/Maximum attenuation values */
|
||||
u8 min_val;
|
||||
u8 max_val;
|
||||
};
|
||||
|
||||
/* Returns true, if the values are the same. */
|
||||
static inline bool b43_compare_bbatt(const struct b43_bbatt *a,
|
||||
const struct b43_bbatt *b)
|
||||
{
|
||||
return (a->att == b->att);
|
||||
}
|
||||
|
||||
/* tx_control bits. */
|
||||
#define B43_TXCTL_PA3DB 0x40 /* PA Gain 3dB */
|
||||
#define B43_TXCTL_PA2DB 0x20 /* PA Gain 2dB */
|
||||
#define B43_TXCTL_TXMIX 0x10 /* TX Mixer Gain */
|
||||
|
||||
/* Write BasebandAttenuation value to the device. */
|
||||
void b43_phy_set_baseband_attenuation(struct b43_wldev *dev,
|
||||
u16 baseband_attenuation);
|
||||
|
||||
extern const u8 b43_radio_channel_codes_bg[];
|
||||
|
||||
void b43_radio_lock(struct b43_wldev *dev);
|
||||
void b43_radio_unlock(struct b43_wldev *dev);
|
||||
|
||||
|
||||
/* Read a value from a 16bit radio register */
|
||||
u16 b43_radio_read16(struct b43_wldev *dev, u16 offset);
|
||||
/* Write a value to a 16bit radio register */
|
||||
void b43_radio_write16(struct b43_wldev *dev, u16 offset, u16 val);
|
||||
/* Mask a 16bit radio register with a mask */
|
||||
void b43_radio_mask(struct b43_wldev *dev, u16 offset, u16 mask);
|
||||
/* OR a 16bit radio register with a bitmap */
|
||||
void b43_radio_set(struct b43_wldev *dev, u16 offset, u16 set);
|
||||
/* Mask and OR a PHY register with a mask and bitmap */
|
||||
void b43_radio_maskset(struct b43_wldev *dev, u16 offset, u16 mask, u16 set);
|
||||
|
||||
|
||||
u16 b43_radio_init2050(struct b43_wldev *dev);
|
||||
void b43_radio_init2060(struct b43_wldev *dev);
|
||||
|
||||
void b43_radio_turn_on(struct b43_wldev *dev);
|
||||
void b43_radio_turn_off(struct b43_wldev *dev, bool force);
|
||||
|
||||
int b43_radio_selectchannel(struct b43_wldev *dev, u8 channel,
|
||||
int synthetic_pu_workaround);
|
||||
|
||||
u8 b43_radio_aci_detect(struct b43_wldev *dev, u8 channel);
|
||||
u8 b43_radio_aci_scan(struct b43_wldev *dev);
|
||||
|
||||
int b43_radio_set_interference_mitigation(struct b43_wldev *dev, int mode);
|
||||
|
||||
void b43_calc_nrssi_slope(struct b43_wldev *dev);
|
||||
void b43_calc_nrssi_threshold(struct b43_wldev *dev);
|
||||
s16 b43_nrssi_hw_read(struct b43_wldev *dev, u16 offset);
|
||||
void b43_nrssi_hw_write(struct b43_wldev *dev, u16 offset, s16 val);
|
||||
void b43_nrssi_hw_update(struct b43_wldev *dev, u16 val);
|
||||
void b43_nrssi_mem_update(struct b43_wldev *dev);
|
||||
|
||||
void b43_radio_set_tx_iq(struct b43_wldev *dev);
|
||||
u16 b43_radio_calibrationvalue(struct b43_wldev *dev);
|
||||
|
||||
void b43_put_attenuation_into_ranges(struct b43_wldev *dev,
|
||||
int *_bbatt, int *_rfatt);
|
||||
|
||||
void b43_set_txpower_g(struct b43_wldev *dev,
|
||||
const struct b43_bbatt *bbatt,
|
||||
const struct b43_rfatt *rfatt, u8 tx_control);
|
||||
|
||||
#endif /* B43_PHY_H_ */
|
536
drivers/net/wireless/b43/phy_a.c
Normal file
536
drivers/net/wireless/b43/phy_a.c
Normal file
@ -0,0 +1,536 @@
|
||||
/*
|
||||
|
||||
Broadcom B43 wireless driver
|
||||
IEEE 802.11a PHY driver
|
||||
|
||||
Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>,
|
||||
Copyright (c) 2005-2007 Stefano Brivio <stefano.brivio@polimi.it>
|
||||
Copyright (c) 2005-2008 Michael Buesch <mb@bu3sch.de>
|
||||
Copyright (c) 2005, 2006 Danny van Dyk <kugelfang@gentoo.org>
|
||||
Copyright (c) 2005, 2006 Andreas Jaggi <andreas.jaggi@waterwave.ch>
|
||||
|
||||
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 "phy_a.h"
|
||||
#include "phy_common.h"
|
||||
#include "wa.h"
|
||||
#include "tables.h"
|
||||
#include "main.h"
|
||||
|
||||
|
||||
/* Get the freq, as it has to be written to the device. */
|
||||
static inline u16 channel2freq_a(u8 channel)
|
||||
{
|
||||
B43_WARN_ON(channel > 200);
|
||||
|
||||
return (5000 + 5 * channel);
|
||||
}
|
||||
|
||||
static inline u16 freq_r3A_value(u16 frequency)
|
||||
{
|
||||
u16 value;
|
||||
|
||||
if (frequency < 5091)
|
||||
value = 0x0040;
|
||||
else if (frequency < 5321)
|
||||
value = 0x0000;
|
||||
else if (frequency < 5806)
|
||||
value = 0x0080;
|
||||
else
|
||||
value = 0x0040;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
void b43_radio_set_tx_iq(struct b43_wldev *dev)
|
||||
{
|
||||
static const u8 data_high[5] = { 0x00, 0x40, 0x80, 0x90, 0xD0 };
|
||||
static const u8 data_low[5] = { 0x00, 0x01, 0x05, 0x06, 0x0A };
|
||||
u16 tmp = b43_radio_read16(dev, 0x001E);
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < 5; i++) {
|
||||
for (j = 0; j < 5; j++) {
|
||||
if (tmp == (data_high[i] << 4 | data_low[j])) {
|
||||
b43_phy_write(dev, 0x0069,
|
||||
(i - j) << 8 | 0x00C0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void aphy_channel_switch(struct b43_wldev *dev, unsigned int channel)
|
||||
{
|
||||
u16 freq, r8, tmp;
|
||||
|
||||
freq = channel2freq_a(channel);
|
||||
|
||||
r8 = b43_radio_read16(dev, 0x0008);
|
||||
b43_write16(dev, 0x03F0, freq);
|
||||
b43_radio_write16(dev, 0x0008, r8);
|
||||
|
||||
//TODO: write max channel TX power? to Radio 0x2D
|
||||
tmp = b43_radio_read16(dev, 0x002E);
|
||||
tmp &= 0x0080;
|
||||
//TODO: OR tmp with the Power out estimation for this channel?
|
||||
b43_radio_write16(dev, 0x002E, tmp);
|
||||
|
||||
if (freq >= 4920 && freq <= 5500) {
|
||||
/*
|
||||
* r8 = (((freq * 15 * 0xE1FC780F) >> 32) / 29) & 0x0F;
|
||||
* = (freq * 0.025862069
|
||||
*/
|
||||
r8 = 3 * freq / 116; /* is equal to r8 = freq * 0.025862 */
|
||||
}
|
||||
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_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_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_set_tx_iq(dev);
|
||||
//TODO: TSSI2dbm workaround
|
||||
//FIXME b43_phy_xmitpower(dev);
|
||||
}
|
||||
|
||||
void b43_radio_init2060(struct b43_wldev *dev)
|
||||
{
|
||||
b43_radio_write16(dev, 0x0004, 0x00C0);
|
||||
b43_radio_write16(dev, 0x0005, 0x0008);
|
||||
b43_radio_write16(dev, 0x0009, 0x0040);
|
||||
b43_radio_write16(dev, 0x0005, 0x00AA);
|
||||
b43_radio_write16(dev, 0x0032, 0x008F);
|
||||
b43_radio_write16(dev, 0x0006, 0x008F);
|
||||
b43_radio_write16(dev, 0x0034, 0x008F);
|
||||
b43_radio_write16(dev, 0x002C, 0x0007);
|
||||
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);
|
||||
msleep(1); /* delay 400usec */
|
||||
|
||||
b43_radio_write16(dev, 0x0081,
|
||||
(b43_radio_read16(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_write16(dev, 0x0005,
|
||||
(b43_radio_read16(dev, 0x0081) & ~0x0008) | 0x0008);
|
||||
b43_phy_write(dev, 0x0063, 0xDDC6);
|
||||
b43_phy_write(dev, 0x0069, 0x07BE);
|
||||
b43_phy_write(dev, 0x006A, 0x0000);
|
||||
|
||||
aphy_channel_switch(dev, dev->phy.ops->get_default_chan(dev));
|
||||
|
||||
msleep(1);
|
||||
}
|
||||
|
||||
static void b43_phy_rssiagc(struct b43_wldev *dev, u8 enable)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (dev->phy.rev < 3) {
|
||||
if (enable)
|
||||
for (i = 0; i < B43_TAB_RSSIAGC1_SIZE; i++) {
|
||||
b43_ofdmtab_write16(dev,
|
||||
B43_OFDMTAB_LNAHPFGAIN1, i, 0xFFF8);
|
||||
b43_ofdmtab_write16(dev,
|
||||
B43_OFDMTAB_WRSSI, i, 0xFFF8);
|
||||
}
|
||||
else
|
||||
for (i = 0; i < B43_TAB_RSSIAGC1_SIZE; i++) {
|
||||
b43_ofdmtab_write16(dev,
|
||||
B43_OFDMTAB_LNAHPFGAIN1, i, b43_tab_rssiagc1[i]);
|
||||
b43_ofdmtab_write16(dev,
|
||||
B43_OFDMTAB_WRSSI, i, b43_tab_rssiagc1[i]);
|
||||
}
|
||||
} else {
|
||||
if (enable)
|
||||
for (i = 0; i < B43_TAB_RSSIAGC1_SIZE; i++)
|
||||
b43_ofdmtab_write16(dev,
|
||||
B43_OFDMTAB_WRSSI, i, 0x0820);
|
||||
else
|
||||
for (i = 0; i < B43_TAB_RSSIAGC2_SIZE; i++)
|
||||
b43_ofdmtab_write16(dev,
|
||||
B43_OFDMTAB_WRSSI, i, b43_tab_rssiagc2[i]);
|
||||
}
|
||||
}
|
||||
|
||||
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_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);
|
||||
for (i = 0x10; i <= 0x20; i++) {
|
||||
b43_radio_write16(dev, 0x0013, i);
|
||||
curr_s = b43_phy_read(dev, B43_PHY_OTABLEQ) & 0x00FF;
|
||||
if (!curr_s) {
|
||||
best_s = 0x0000;
|
||||
break;
|
||||
} else if (curr_s >= 0x0080)
|
||||
curr_s = 0x0100 - curr_s;
|
||||
if (curr_s < best_s)
|
||||
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_write16(dev, 0x0013, best_s);
|
||||
b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1_R1, 0, 0xFFEC);
|
||||
b43_phy_write(dev, B43_PHY_OFDM(0xB7), 0x1E80);
|
||||
b43_phy_write(dev, B43_PHY_OFDM(0xB6), 0x1C00);
|
||||
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_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 6, 0x0017);
|
||||
for (i = 0; i < 6; i++)
|
||||
b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, i, 0x000F);
|
||||
b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 0x0D, 0x000E);
|
||||
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);
|
||||
}
|
||||
|
||||
static void hardware_pctl_init_aphy(struct b43_wldev *dev)
|
||||
{
|
||||
//TODO
|
||||
}
|
||||
|
||||
void b43_phy_inita(struct b43_wldev *dev)
|
||||
{
|
||||
struct ssb_bus *bus = dev->dev->bus;
|
||||
struct b43_phy *phy = &dev->phy;
|
||||
|
||||
/* This lowlevel A-PHY init is also called from G-PHY init.
|
||||
* So we must not access phy->a, if called from G-PHY code.
|
||||
*/
|
||||
B43_WARN_ON((phy->type != B43_PHYTYPE_A) &&
|
||||
(phy->type != B43_PHYTYPE_G));
|
||||
|
||||
might_sleep();
|
||||
|
||||
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);
|
||||
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);
|
||||
else
|
||||
b43_phy_write(dev, B43_PHY_ENCORE,
|
||||
b43_phy_read(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_rssiagc(dev, 0);
|
||||
|
||||
b43_phy_write(dev, B43_PHY_CRS0,
|
||||
b43_phy_read(dev, B43_PHY_CRS0) | B43_PHY_CRS0_EN);
|
||||
|
||||
b43_radio_init2060(dev);
|
||||
|
||||
if ((bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM) &&
|
||||
((bus->boardinfo.type == SSB_BOARD_BU4306) ||
|
||||
(bus->boardinfo.type == SSB_BOARD_BU4309))) {
|
||||
; //TODO: A PHY LO
|
||||
}
|
||||
|
||||
if (phy->rev >= 3)
|
||||
b43_phy_ww(dev);
|
||||
|
||||
hardware_pctl_init_aphy(dev);
|
||||
|
||||
//TODO: radar detection
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
static int b43_aphy_op_allocate(struct b43_wldev *dev)
|
||||
{
|
||||
struct b43_phy_a *aphy;
|
||||
|
||||
aphy = kzalloc(sizeof(*aphy), GFP_KERNEL);
|
||||
if (!aphy)
|
||||
return -ENOMEM;
|
||||
dev->phy.a = aphy;
|
||||
|
||||
//TODO init struct b43_phy_a
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int b43_aphy_op_init(struct b43_wldev *dev)
|
||||
{
|
||||
struct b43_phy_a *aphy = dev->phy.a;
|
||||
|
||||
b43_phy_inita(dev);
|
||||
aphy->initialised = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void b43_aphy_op_exit(struct b43_wldev *dev)
|
||||
{
|
||||
struct b43_phy_a *aphy = dev->phy.a;
|
||||
|
||||
if (aphy->initialised) {
|
||||
//TODO
|
||||
aphy->initialised = 0;
|
||||
}
|
||||
//TODO
|
||||
kfree(aphy);
|
||||
dev->phy.a = NULL;
|
||||
}
|
||||
|
||||
static inline u16 adjust_phyreg(struct b43_wldev *dev, u16 offset)
|
||||
{
|
||||
/* OFDM registers are base-registers for the A-PHY. */
|
||||
if ((offset & B43_PHYROUTE) == B43_PHYROUTE_OFDM_GPHY) {
|
||||
offset &= ~B43_PHYROUTE;
|
||||
offset |= B43_PHYROUTE_BASE;
|
||||
}
|
||||
|
||||
#if B43_DEBUG
|
||||
if ((offset & B43_PHYROUTE) == B43_PHYROUTE_EXT_GPHY) {
|
||||
/* Ext-G registers are only available on G-PHYs */
|
||||
b43err(dev->wl, "Invalid EXT-G PHY access at "
|
||||
"0x%04X on A-PHY\n", offset);
|
||||
dump_stack();
|
||||
}
|
||||
if ((offset & B43_PHYROUTE) == B43_PHYROUTE_N_BMODE) {
|
||||
/* N-BMODE registers are only available on N-PHYs */
|
||||
b43err(dev->wl, "Invalid N-BMODE PHY access at "
|
||||
"0x%04X on A-PHY\n", offset);
|
||||
dump_stack();
|
||||
}
|
||||
#endif /* B43_DEBUG */
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
static u16 b43_aphy_op_read(struct b43_wldev *dev, u16 reg)
|
||||
{
|
||||
reg = adjust_phyreg(dev, reg);
|
||||
b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
|
||||
return b43_read16(dev, B43_MMIO_PHY_DATA);
|
||||
}
|
||||
|
||||
static void b43_aphy_op_write(struct b43_wldev *dev, u16 reg, u16 value)
|
||||
{
|
||||
reg = adjust_phyreg(dev, reg);
|
||||
b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
|
||||
b43_write16(dev, B43_MMIO_PHY_DATA, value);
|
||||
}
|
||||
|
||||
static u16 b43_aphy_op_radio_read(struct b43_wldev *dev, u16 reg)
|
||||
{
|
||||
/* Register 1 is a 32-bit register. */
|
||||
B43_WARN_ON(reg == 1);
|
||||
/* A-PHY needs 0x40 for read access */
|
||||
reg |= 0x40;
|
||||
|
||||
b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
|
||||
return b43_read16(dev, B43_MMIO_RADIO_DATA_LOW);
|
||||
}
|
||||
|
||||
static void b43_aphy_op_radio_write(struct b43_wldev *dev, u16 reg, u16 value)
|
||||
{
|
||||
/* Register 1 is a 32-bit register. */
|
||||
B43_WARN_ON(reg == 1);
|
||||
|
||||
b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
|
||||
b43_write16(dev, B43_MMIO_RADIO_DATA_LOW, value);
|
||||
}
|
||||
|
||||
static bool b43_aphy_op_supports_hwpctl(struct b43_wldev *dev)
|
||||
{
|
||||
return (dev->phy.rev >= 5);
|
||||
}
|
||||
|
||||
static void b43_aphy_op_software_rfkill(struct b43_wldev *dev,
|
||||
enum rfkill_state state)
|
||||
{//TODO
|
||||
}
|
||||
|
||||
static int b43_aphy_op_switch_channel(struct b43_wldev *dev,
|
||||
unsigned int new_channel)
|
||||
{
|
||||
if (new_channel > 200)
|
||||
return -EINVAL;
|
||||
aphy_channel_switch(dev, new_channel);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned int b43_aphy_op_get_default_chan(struct b43_wldev *dev)
|
||||
{
|
||||
return 36; /* Default to channel 36 */
|
||||
}
|
||||
|
||||
static void b43_aphy_op_set_rx_antenna(struct b43_wldev *dev, int antenna)
|
||||
{//TODO
|
||||
struct b43_phy *phy = &dev->phy;
|
||||
u64 hf;
|
||||
u16 tmp;
|
||||
int autodiv = 0;
|
||||
|
||||
if (antenna == B43_ANTENNA_AUTO0 || antenna == B43_ANTENNA_AUTO1)
|
||||
autodiv = 1;
|
||||
|
||||
hf = b43_hf_read(dev);
|
||||
hf &= ~B43_HF_ANTDIVHELP;
|
||||
b43_hf_write(dev, hf);
|
||||
|
||||
tmp = b43_phy_read(dev, B43_PHY_BBANDCFG);
|
||||
tmp &= ~B43_PHY_BBANDCFG_RXANT;
|
||||
tmp |= (autodiv ? B43_ANTENNA_AUTO0 : antenna)
|
||||
<< B43_PHY_BBANDCFG_RXANT_SHIFT;
|
||||
b43_phy_write(dev, B43_PHY_BBANDCFG, tmp);
|
||||
|
||||
if (autodiv) {
|
||||
tmp = b43_phy_read(dev, B43_PHY_ANTDWELL);
|
||||
if (antenna == B43_ANTENNA_AUTO0)
|
||||
tmp &= ~B43_PHY_ANTDWELL_AUTODIV1;
|
||||
else
|
||||
tmp |= B43_PHY_ANTDWELL_AUTODIV1;
|
||||
b43_phy_write(dev, B43_PHY_ANTDWELL, tmp);
|
||||
}
|
||||
if (phy->rev < 3) {
|
||||
tmp = b43_phy_read(dev, B43_PHY_ANTDWELL);
|
||||
tmp = (tmp & 0xFF00) | 0x24;
|
||||
b43_phy_write(dev, B43_PHY_ANTDWELL, tmp);
|
||||
} else {
|
||||
tmp = b43_phy_read(dev, B43_PHY_OFDM61);
|
||||
tmp |= 0x10;
|
||||
b43_phy_write(dev, B43_PHY_OFDM61, tmp);
|
||||
if (phy->analog == 3) {
|
||||
b43_phy_write(dev, B43_PHY_CLIPPWRDOWNT,
|
||||
0x1D);
|
||||
b43_phy_write(dev, B43_PHY_ADIVRELATED,
|
||||
8);
|
||||
} else {
|
||||
b43_phy_write(dev, B43_PHY_CLIPPWRDOWNT,
|
||||
0x3A);
|
||||
tmp =
|
||||
b43_phy_read(dev,
|
||||
B43_PHY_ADIVRELATED);
|
||||
tmp = (tmp & 0xFF00) | 8;
|
||||
b43_phy_write(dev, B43_PHY_ADIVRELATED,
|
||||
tmp);
|
||||
}
|
||||
}
|
||||
|
||||
hf |= B43_HF_ANTDIVHELP;
|
||||
b43_hf_write(dev, hf);
|
||||
}
|
||||
|
||||
static void b43_aphy_op_xmitpower(struct b43_wldev *dev)
|
||||
{//TODO
|
||||
}
|
||||
|
||||
static void b43_aphy_op_pwork_15sec(struct b43_wldev *dev)
|
||||
{//TODO
|
||||
}
|
||||
|
||||
static void b43_aphy_op_pwork_60sec(struct b43_wldev *dev)
|
||||
{//TODO
|
||||
}
|
||||
|
||||
const struct b43_phy_operations b43_phyops_a = {
|
||||
.allocate = b43_aphy_op_allocate,
|
||||
.init = b43_aphy_op_init,
|
||||
.exit = b43_aphy_op_exit,
|
||||
.phy_read = b43_aphy_op_read,
|
||||
.phy_write = b43_aphy_op_write,
|
||||
.radio_read = b43_aphy_op_radio_read,
|
||||
.radio_write = b43_aphy_op_radio_write,
|
||||
.supports_hwpctl = b43_aphy_op_supports_hwpctl,
|
||||
.software_rfkill = b43_aphy_op_software_rfkill,
|
||||
.switch_channel = b43_aphy_op_switch_channel,
|
||||
.get_default_chan = b43_aphy_op_get_default_chan,
|
||||
.set_rx_antenna = b43_aphy_op_set_rx_antenna,
|
||||
.xmitpower = b43_aphy_op_xmitpower,
|
||||
.pwork_15sec = b43_aphy_op_pwork_15sec,
|
||||
.pwork_60sec = b43_aphy_op_pwork_60sec,
|
||||
};
|
124
drivers/net/wireless/b43/phy_a.h
Normal file
124
drivers/net/wireless/b43/phy_a.h
Normal file
@ -0,0 +1,124 @@
|
||||
#ifndef LINUX_B43_PHY_A_H_
|
||||
#define LINUX_B43_PHY_A_H_
|
||||
|
||||
#include "phy_common.h"
|
||||
|
||||
|
||||
/* OFDM (A) PHY Registers */
|
||||
#define B43_PHY_VERSION_OFDM B43_PHY_OFDM(0x00) /* Versioning register for A-PHY */
|
||||
#define B43_PHY_BBANDCFG B43_PHY_OFDM(0x01) /* Baseband config */
|
||||
#define B43_PHY_BBANDCFG_RXANT 0x180 /* RX Antenna selection */
|
||||
#define B43_PHY_BBANDCFG_RXANT_SHIFT 7
|
||||
#define B43_PHY_PWRDOWN B43_PHY_OFDM(0x03) /* Powerdown */
|
||||
#define B43_PHY_CRSTHRES1_R1 B43_PHY_OFDM(0x06) /* CRS Threshold 1 (phy.rev 1 only) */
|
||||
#define B43_PHY_LNAHPFCTL B43_PHY_OFDM(0x1C) /* LNA/HPF control */
|
||||
#define B43_PHY_LPFGAINCTL B43_PHY_OFDM(0x20) /* LPF Gain control */
|
||||
#define B43_PHY_ADIVRELATED B43_PHY_OFDM(0x27) /* FIXME rename */
|
||||
#define B43_PHY_CRS0 B43_PHY_OFDM(0x29)
|
||||
#define B43_PHY_CRS0_EN 0x4000
|
||||
#define B43_PHY_PEAK_COUNT B43_PHY_OFDM(0x30)
|
||||
#define B43_PHY_ANTDWELL B43_PHY_OFDM(0x2B) /* Antenna dwell */
|
||||
#define B43_PHY_ANTDWELL_AUTODIV1 0x0100 /* Automatic RX diversity start antenna */
|
||||
#define B43_PHY_ENCORE B43_PHY_OFDM(0x49) /* "Encore" (RangeMax / BroadRange) */
|
||||
#define B43_PHY_ENCORE_EN 0x0200 /* Encore enable */
|
||||
#define B43_PHY_LMS B43_PHY_OFDM(0x55)
|
||||
#define B43_PHY_OFDM61 B43_PHY_OFDM(0x61) /* FIXME rename */
|
||||
#define B43_PHY_OFDM61_10 0x0010 /* FIXME rename */
|
||||
#define B43_PHY_IQBAL B43_PHY_OFDM(0x69) /* I/Q balance */
|
||||
#define B43_PHY_BBTXDC_BIAS B43_PHY_OFDM(0x6B) /* Baseband TX DC bias */
|
||||
#define B43_PHY_OTABLECTL B43_PHY_OFDM(0x72) /* OFDM table control (see below) */
|
||||
#define B43_PHY_OTABLEOFF 0x03FF /* OFDM table offset (see below) */
|
||||
#define B43_PHY_OTABLENR 0xFC00 /* OFDM table number (see below) */
|
||||
#define B43_PHY_OTABLENR_SHIFT 10
|
||||
#define B43_PHY_OTABLEI B43_PHY_OFDM(0x73) /* OFDM table data I */
|
||||
#define B43_PHY_OTABLEQ B43_PHY_OFDM(0x74) /* OFDM table data Q */
|
||||
#define B43_PHY_HPWR_TSSICTL B43_PHY_OFDM(0x78) /* Hardware power TSSI control */
|
||||
#define B43_PHY_ADCCTL B43_PHY_OFDM(0x7A) /* ADC control */
|
||||
#define B43_PHY_IDLE_TSSI B43_PHY_OFDM(0x7B)
|
||||
#define B43_PHY_A_TEMP_SENSE B43_PHY_OFDM(0x7C) /* A PHY temperature sense */
|
||||
#define B43_PHY_NRSSITHRES B43_PHY_OFDM(0x8A) /* NRSSI threshold */
|
||||
#define B43_PHY_ANTWRSETT B43_PHY_OFDM(0x8C) /* Antenna WR settle */
|
||||
#define B43_PHY_ANTWRSETT_ARXDIV 0x2000 /* Automatic RX diversity enabled */
|
||||
#define B43_PHY_CLIPPWRDOWNT B43_PHY_OFDM(0x93) /* Clip powerdown threshold */
|
||||
#define B43_PHY_OFDM9B B43_PHY_OFDM(0x9B) /* FIXME rename */
|
||||
#define B43_PHY_N1P1GAIN B43_PHY_OFDM(0xA0)
|
||||
#define B43_PHY_P1P2GAIN B43_PHY_OFDM(0xA1)
|
||||
#define B43_PHY_N1N2GAIN B43_PHY_OFDM(0xA2)
|
||||
#define B43_PHY_CLIPTHRES B43_PHY_OFDM(0xA3)
|
||||
#define B43_PHY_CLIPN1P2THRES B43_PHY_OFDM(0xA4)
|
||||
#define B43_PHY_CCKSHIFTBITS_WA B43_PHY_OFDM(0xA5) /* CCK shiftbits workaround, FIXME rename */
|
||||
#define B43_PHY_CCKSHIFTBITS B43_PHY_OFDM(0xA7) /* FIXME rename */
|
||||
#define B43_PHY_DIVSRCHIDX B43_PHY_OFDM(0xA8) /* Divider search gain/index */
|
||||
#define B43_PHY_CLIPP2THRES B43_PHY_OFDM(0xA9)
|
||||
#define B43_PHY_CLIPP3THRES B43_PHY_OFDM(0xAA)
|
||||
#define B43_PHY_DIVP1P2GAIN B43_PHY_OFDM(0xAB)
|
||||
#define B43_PHY_DIVSRCHGAINBACK B43_PHY_OFDM(0xAD) /* Divider search gain back */
|
||||
#define B43_PHY_DIVSRCHGAINCHNG B43_PHY_OFDM(0xAE) /* Divider search gain change */
|
||||
#define B43_PHY_CRSTHRES1 B43_PHY_OFDM(0xC0) /* CRS Threshold 1 (phy.rev >= 2 only) */
|
||||
#define B43_PHY_CRSTHRES2 B43_PHY_OFDM(0xC1) /* CRS Threshold 2 (phy.rev >= 2 only) */
|
||||
#define B43_PHY_TSSIP_LTBASE B43_PHY_OFDM(0x380) /* TSSI power lookup table base */
|
||||
#define B43_PHY_DC_LTBASE B43_PHY_OFDM(0x3A0) /* DC lookup table base */
|
||||
#define B43_PHY_GAIN_LTBASE B43_PHY_OFDM(0x3C0) /* Gain lookup table base */
|
||||
|
||||
/*** OFDM table numbers ***/
|
||||
#define B43_OFDMTAB(number, offset) (((number) << B43_PHY_OTABLENR_SHIFT) | (offset))
|
||||
#define B43_OFDMTAB_AGC1 B43_OFDMTAB(0x00, 0)
|
||||
#define B43_OFDMTAB_GAIN0 B43_OFDMTAB(0x00, 0)
|
||||
#define B43_OFDMTAB_GAINX B43_OFDMTAB(0x01, 0) //TODO rename
|
||||
#define B43_OFDMTAB_GAIN1 B43_OFDMTAB(0x01, 4)
|
||||
#define B43_OFDMTAB_AGC3 B43_OFDMTAB(0x02, 0)
|
||||
#define B43_OFDMTAB_GAIN2 B43_OFDMTAB(0x02, 3)
|
||||
#define B43_OFDMTAB_LNAHPFGAIN1 B43_OFDMTAB(0x03, 0)
|
||||
#define B43_OFDMTAB_WRSSI B43_OFDMTAB(0x04, 0)
|
||||
#define B43_OFDMTAB_LNAHPFGAIN2 B43_OFDMTAB(0x04, 0)
|
||||
#define B43_OFDMTAB_NOISESCALE B43_OFDMTAB(0x05, 0)
|
||||
#define B43_OFDMTAB_AGC2 B43_OFDMTAB(0x06, 0)
|
||||
#define B43_OFDMTAB_ROTOR B43_OFDMTAB(0x08, 0)
|
||||
#define B43_OFDMTAB_ADVRETARD B43_OFDMTAB(0x09, 0)
|
||||
#define B43_OFDMTAB_DAC B43_OFDMTAB(0x0C, 0)
|
||||
#define B43_OFDMTAB_DC B43_OFDMTAB(0x0E, 7)
|
||||
#define B43_OFDMTAB_PWRDYN2 B43_OFDMTAB(0x0E, 12)
|
||||
#define B43_OFDMTAB_LNAGAIN B43_OFDMTAB(0x0E, 13)
|
||||
#define B43_OFDMTAB_UNKNOWN_0F B43_OFDMTAB(0x0F, 0) //TODO rename
|
||||
#define B43_OFDMTAB_UNKNOWN_APHY B43_OFDMTAB(0x0F, 7) //TODO rename
|
||||
#define B43_OFDMTAB_LPFGAIN B43_OFDMTAB(0x0F, 12)
|
||||
#define B43_OFDMTAB_RSSI B43_OFDMTAB(0x10, 0)
|
||||
#define B43_OFDMTAB_UNKNOWN_11 B43_OFDMTAB(0x11, 4) //TODO rename
|
||||
#define B43_OFDMTAB_AGC1_R1 B43_OFDMTAB(0x13, 0)
|
||||
#define B43_OFDMTAB_GAINX_R1 B43_OFDMTAB(0x14, 0) //TODO remove!
|
||||
#define B43_OFDMTAB_MINSIGSQ B43_OFDMTAB(0x14, 0)
|
||||
#define B43_OFDMTAB_AGC3_R1 B43_OFDMTAB(0x15, 0)
|
||||
#define B43_OFDMTAB_WRSSI_R1 B43_OFDMTAB(0x15, 4)
|
||||
#define B43_OFDMTAB_TSSI B43_OFDMTAB(0x15, 0)
|
||||
#define B43_OFDMTAB_DACRFPABB B43_OFDMTAB(0x16, 0)
|
||||
#define B43_OFDMTAB_DACOFF B43_OFDMTAB(0x17, 0)
|
||||
#define B43_OFDMTAB_DCBIAS B43_OFDMTAB(0x18, 0)
|
||||
|
||||
u16 b43_ofdmtab_read16(struct b43_wldev *dev, u16 table, u16 offset);
|
||||
void b43_ofdmtab_write16(struct b43_wldev *dev, u16 table,
|
||||
u16 offset, u16 value);
|
||||
u32 b43_ofdmtab_read32(struct b43_wldev *dev, u16 table, u16 offset);
|
||||
void b43_ofdmtab_write32(struct b43_wldev *dev, u16 table,
|
||||
u16 offset, u32 value);
|
||||
|
||||
|
||||
struct b43_phy_a {
|
||||
bool initialised;
|
||||
|
||||
/* A-PHY TX Power control value. */
|
||||
u16 txpwr_offset;
|
||||
|
||||
//TODO lots of missing stuff
|
||||
};
|
||||
|
||||
/**
|
||||
* b43_phy_inita - Lowlevel A-PHY init routine.
|
||||
* This is _only_ used by the G-PHY code.
|
||||
*/
|
||||
void b43_phy_inita(struct b43_wldev *dev);
|
||||
|
||||
|
||||
struct b43_phy_operations;
|
||||
extern const struct b43_phy_operations b43_phyops_a;
|
||||
|
||||
#endif /* LINUX_B43_PHY_A_H_ */
|
276
drivers/net/wireless/b43/phy_common.c
Normal file
276
drivers/net/wireless/b43/phy_common.c
Normal file
@ -0,0 +1,276 @@
|
||||
/*
|
||||
|
||||
Broadcom B43 wireless driver
|
||||
Common PHY routines
|
||||
|
||||
Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>,
|
||||
Copyright (c) 2005-2007 Stefano Brivio <stefano.brivio@polimi.it>
|
||||
Copyright (c) 2005-2008 Michael Buesch <mb@bu3sch.de>
|
||||
Copyright (c) 2005, 2006 Danny van Dyk <kugelfang@gentoo.org>
|
||||
Copyright (c) 2005, 2006 Andreas Jaggi <andreas.jaggi@waterwave.ch>
|
||||
|
||||
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 "phy_common.h"
|
||||
#include "phy_g.h"
|
||||
#include "phy_a.h"
|
||||
#include "nphy.h"
|
||||
#include "b43.h"
|
||||
#include "main.h"
|
||||
|
||||
|
||||
int b43_phy_operations_setup(struct b43_wldev *dev)
|
||||
{
|
||||
struct b43_phy *phy = &(dev->phy);
|
||||
int err;
|
||||
|
||||
phy->ops = NULL;
|
||||
|
||||
switch (phy->type) {
|
||||
case B43_PHYTYPE_A:
|
||||
phy->ops = &b43_phyops_a;
|
||||
break;
|
||||
case B43_PHYTYPE_G:
|
||||
phy->ops = &b43_phyops_g;
|
||||
break;
|
||||
case B43_PHYTYPE_N:
|
||||
#ifdef CONFIG_B43_NPHY
|
||||
phy->ops = &b43_phyops_n;
|
||||
#endif
|
||||
break;
|
||||
case B43_PHYTYPE_LP:
|
||||
/* FIXME: Not yet */
|
||||
break;
|
||||
}
|
||||
if (B43_WARN_ON(!phy->ops))
|
||||
return -ENODEV;
|
||||
|
||||
err = phy->ops->allocate(dev);
|
||||
if (err)
|
||||
phy->ops = NULL;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int b43_phy_init(struct b43_wldev *dev)
|
||||
{
|
||||
struct b43_phy *phy = &dev->phy;
|
||||
const struct b43_phy_operations *ops = phy->ops;
|
||||
int err;
|
||||
|
||||
phy->channel = ops->get_default_chan(dev);
|
||||
|
||||
ops->software_rfkill(dev, RFKILL_STATE_UNBLOCKED);
|
||||
err = ops->init(dev);
|
||||
if (err) {
|
||||
b43err(dev->wl, "PHY init failed\n");
|
||||
goto err_block_rf;
|
||||
}
|
||||
/* Make sure to switch hardware and firmware (SHM) to
|
||||
* the default channel. */
|
||||
err = b43_switch_channel(dev, ops->get_default_chan(dev));
|
||||
if (err) {
|
||||
b43err(dev->wl, "PHY init: Channel switch to default failed\n");
|
||||
goto err_phy_exit;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_phy_exit:
|
||||
if (ops->exit)
|
||||
ops->exit(dev);
|
||||
err_block_rf:
|
||||
ops->software_rfkill(dev, RFKILL_STATE_SOFT_BLOCKED);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
void b43_phy_exit(struct b43_wldev *dev)
|
||||
{
|
||||
const struct b43_phy_operations *ops = dev->phy.ops;
|
||||
|
||||
ops->software_rfkill(dev, RFKILL_STATE_SOFT_BLOCKED);
|
||||
if (ops->exit)
|
||||
ops->exit(dev);
|
||||
}
|
||||
|
||||
bool b43_has_hardware_pctl(struct b43_wldev *dev)
|
||||
{
|
||||
if (!dev->phy.hardware_power_control)
|
||||
return 0;
|
||||
if (!dev->phy.ops->supports_hwpctl)
|
||||
return 0;
|
||||
return dev->phy.ops->supports_hwpctl(dev);
|
||||
}
|
||||
|
||||
void b43_radio_lock(struct b43_wldev *dev)
|
||||
{
|
||||
u32 macctl;
|
||||
|
||||
macctl = b43_read32(dev, B43_MMIO_MACCTL);
|
||||
B43_WARN_ON(macctl & B43_MACCTL_RADIOLOCK);
|
||||
macctl |= B43_MACCTL_RADIOLOCK;
|
||||
b43_write32(dev, B43_MMIO_MACCTL, macctl);
|
||||
/* Commit the write and wait for the device
|
||||
* to exit any radio register access. */
|
||||
b43_read32(dev, B43_MMIO_MACCTL);
|
||||
udelay(10);
|
||||
}
|
||||
|
||||
void b43_radio_unlock(struct b43_wldev *dev)
|
||||
{
|
||||
u32 macctl;
|
||||
|
||||
/* Commit any write */
|
||||
b43_read16(dev, B43_MMIO_PHY_VER);
|
||||
/* unlock */
|
||||
macctl = b43_read32(dev, B43_MMIO_MACCTL);
|
||||
B43_WARN_ON(!(macctl & B43_MACCTL_RADIOLOCK));
|
||||
macctl &= ~B43_MACCTL_RADIOLOCK;
|
||||
b43_write32(dev, B43_MMIO_MACCTL, macctl);
|
||||
}
|
||||
|
||||
void b43_phy_lock(struct b43_wldev *dev)
|
||||
{
|
||||
#if B43_DEBUG
|
||||
B43_WARN_ON(dev->phy.phy_locked);
|
||||
dev->phy.phy_locked = 1;
|
||||
#endif
|
||||
B43_WARN_ON(dev->dev->id.revision < 3);
|
||||
|
||||
if (!b43_is_mode(dev->wl, IEEE80211_IF_TYPE_AP))
|
||||
b43_power_saving_ctl_bits(dev, B43_PS_AWAKE);
|
||||
}
|
||||
|
||||
void b43_phy_unlock(struct b43_wldev *dev)
|
||||
{
|
||||
#if B43_DEBUG
|
||||
B43_WARN_ON(!dev->phy.phy_locked);
|
||||
dev->phy.phy_locked = 0;
|
||||
#endif
|
||||
B43_WARN_ON(dev->dev->id.revision < 3);
|
||||
|
||||
if (!b43_is_mode(dev->wl, IEEE80211_IF_TYPE_AP))
|
||||
b43_power_saving_ctl_bits(dev, 0);
|
||||
}
|
||||
|
||||
u16 b43_radio_read(struct b43_wldev *dev, u16 reg)
|
||||
{
|
||||
return dev->phy.ops->radio_read(dev, reg);
|
||||
}
|
||||
|
||||
void b43_radio_write(struct b43_wldev *dev, u16 reg, u16 value)
|
||||
{
|
||||
dev->phy.ops->radio_write(dev, reg, value);
|
||||
}
|
||||
|
||||
void b43_radio_mask(struct b43_wldev *dev, u16 offset, u16 mask)
|
||||
{
|
||||
b43_radio_write16(dev, offset,
|
||||
b43_radio_read16(dev, offset) & mask);
|
||||
}
|
||||
|
||||
void b43_radio_set(struct b43_wldev *dev, u16 offset, u16 set)
|
||||
{
|
||||
b43_radio_write16(dev, offset,
|
||||
b43_radio_read16(dev, offset) | set);
|
||||
}
|
||||
|
||||
void b43_radio_maskset(struct b43_wldev *dev, u16 offset, u16 mask, u16 set)
|
||||
{
|
||||
b43_radio_write16(dev, offset,
|
||||
(b43_radio_read16(dev, offset) & mask) | set);
|
||||
}
|
||||
|
||||
u16 b43_phy_read(struct b43_wldev *dev, u16 reg)
|
||||
{
|
||||
return dev->phy.ops->phy_read(dev, reg);
|
||||
}
|
||||
|
||||
void b43_phy_write(struct b43_wldev *dev, u16 reg, u16 value)
|
||||
{
|
||||
dev->phy.ops->phy_write(dev, reg, value);
|
||||
}
|
||||
|
||||
void b43_phy_mask(struct b43_wldev *dev, u16 offset, u16 mask)
|
||||
{
|
||||
b43_phy_write(dev, offset,
|
||||
b43_phy_read(dev, offset) & mask);
|
||||
}
|
||||
|
||||
void b43_phy_set(struct b43_wldev *dev, u16 offset, u16 set)
|
||||
{
|
||||
b43_phy_write(dev, offset,
|
||||
b43_phy_read(dev, offset) | set);
|
||||
}
|
||||
|
||||
void b43_phy_maskset(struct b43_wldev *dev, u16 offset, u16 mask, u16 set)
|
||||
{
|
||||
b43_phy_write(dev, offset,
|
||||
(b43_phy_read(dev, offset) & mask) | set);
|
||||
}
|
||||
|
||||
int b43_switch_channel(struct b43_wldev *dev, unsigned int new_channel)
|
||||
{
|
||||
struct b43_phy *phy = &(dev->phy);
|
||||
u16 channelcookie, savedcookie;
|
||||
int err;
|
||||
|
||||
if (new_channel == B43_DEFAULT_CHANNEL)
|
||||
new_channel = phy->ops->get_default_chan(dev);
|
||||
|
||||
/* First we set the channel radio code to prevent the
|
||||
* firmware from sending ghost packets.
|
||||
*/
|
||||
channelcookie = new_channel;
|
||||
if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ)
|
||||
channelcookie |= 0x100;
|
||||
//FIXME set 40Mhz flag if required
|
||||
savedcookie = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_CHAN);
|
||||
b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_CHAN, channelcookie);
|
||||
|
||||
/* Now try to switch the PHY hardware channel. */
|
||||
err = phy->ops->switch_channel(dev, new_channel);
|
||||
if (err)
|
||||
goto err_restore_cookie;
|
||||
|
||||
dev->phy.channel = new_channel;
|
||||
/* Wait for the radio to tune to the channel and stabilize. */
|
||||
msleep(8);
|
||||
|
||||
return 0;
|
||||
|
||||
err_restore_cookie:
|
||||
b43_shm_write16(dev, B43_SHM_SHARED,
|
||||
B43_SHM_SH_CHAN, savedcookie);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
void b43_software_rfkill(struct b43_wldev *dev, enum rfkill_state state)
|
||||
{
|
||||
struct b43_phy *phy = &dev->phy;
|
||||
|
||||
if (state == RFKILL_STATE_HARD_BLOCKED) {
|
||||
/* We cannot hardware-block the device */
|
||||
state = RFKILL_STATE_SOFT_BLOCKED;
|
||||
}
|
||||
|
||||
phy->ops->software_rfkill(dev, state);
|
||||
phy->radio_on = (state == RFKILL_STATE_UNBLOCKED);
|
||||
}
|
312
drivers/net/wireless/b43/phy_common.h
Normal file
312
drivers/net/wireless/b43/phy_common.h
Normal file
@ -0,0 +1,312 @@
|
||||
#ifndef LINUX_B43_PHY_COMMON_H_
|
||||
#define LINUX_B43_PHY_COMMON_H_
|
||||
|
||||
#include <linux/rfkill.h>
|
||||
|
||||
struct b43_wldev;
|
||||
|
||||
|
||||
/* PHY register routing bits */
|
||||
#define B43_PHYROUTE 0x0C00 /* PHY register routing bits mask */
|
||||
#define B43_PHYROUTE_BASE 0x0000 /* Base registers */
|
||||
#define B43_PHYROUTE_OFDM_GPHY 0x0400 /* OFDM register routing for G-PHYs */
|
||||
#define B43_PHYROUTE_EXT_GPHY 0x0800 /* Extended G-PHY registers */
|
||||
#define B43_PHYROUTE_N_BMODE 0x0C00 /* N-PHY BMODE registers */
|
||||
|
||||
/* CCK (B-PHY) registers. */
|
||||
#define B43_PHY_CCK(reg) ((reg) | B43_PHYROUTE_BASE)
|
||||
/* N-PHY registers. */
|
||||
#define B43_PHY_N(reg) ((reg) | B43_PHYROUTE_BASE)
|
||||
/* N-PHY BMODE registers. */
|
||||
#define B43_PHY_N_BMODE(reg) ((reg) | B43_PHYROUTE_N_BMODE)
|
||||
/* OFDM (A-PHY) registers. */
|
||||
#define B43_PHY_OFDM(reg) ((reg) | B43_PHYROUTE_OFDM_GPHY)
|
||||
/* Extended G-PHY registers. */
|
||||
#define B43_PHY_EXTG(reg) ((reg) | B43_PHYROUTE_EXT_GPHY)
|
||||
|
||||
|
||||
/* Masks for the PHY versioning registers. */
|
||||
#define B43_PHYVER_ANALOG 0xF000
|
||||
#define B43_PHYVER_ANALOG_SHIFT 12
|
||||
#define B43_PHYVER_TYPE 0x0F00
|
||||
#define B43_PHYVER_TYPE_SHIFT 8
|
||||
#define B43_PHYVER_VERSION 0x00FF
|
||||
|
||||
/**
|
||||
* enum b43_interference_mitigation - Interference Mitigation mode
|
||||
*
|
||||
* @B43_INTERFMODE_NONE: Disabled
|
||||
* @B43_INTERFMODE_NONWLAN: Non-WLAN Interference Mitigation
|
||||
* @B43_INTERFMODE_MANUALWLAN: WLAN Interference Mitigation
|
||||
* @B43_INTERFMODE_AUTOWLAN: Automatic WLAN Interference Mitigation
|
||||
*/
|
||||
enum b43_interference_mitigation {
|
||||
B43_INTERFMODE_NONE,
|
||||
B43_INTERFMODE_NONWLAN,
|
||||
B43_INTERFMODE_MANUALWLAN,
|
||||
B43_INTERFMODE_AUTOWLAN,
|
||||
};
|
||||
|
||||
/* Antenna identifiers */
|
||||
enum {
|
||||
B43_ANTENNA0, /* Antenna 0 */
|
||||
B43_ANTENNA1, /* Antenna 0 */
|
||||
B43_ANTENNA_AUTO1, /* Automatic, starting with antenna 1 */
|
||||
B43_ANTENNA_AUTO0, /* Automatic, starting with antenna 0 */
|
||||
B43_ANTENNA2,
|
||||
B43_ANTENNA3 = 8,
|
||||
|
||||
B43_ANTENNA_AUTO = B43_ANTENNA_AUTO0,
|
||||
B43_ANTENNA_DEFAULT = B43_ANTENNA_AUTO,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct b43_phy_operations - Function pointers for PHY ops.
|
||||
*
|
||||
* @prepare: Prepare the PHY. This is called before @init.
|
||||
* Can be NULL, if not required.
|
||||
* @init: Initialize the PHY.
|
||||
* Must not be NULL.
|
||||
* @exit: Shutdown the PHY and free all data structures.
|
||||
* Can be NULL, if not required.
|
||||
*
|
||||
* @phy_read: Read from a PHY register.
|
||||
* Must not be NULL.
|
||||
* @phy_write: Write to a PHY register.
|
||||
* Must not be NULL.
|
||||
* @radio_read: Read from a Radio register.
|
||||
* Must not be NULL.
|
||||
* @radio_write: Write to a Radio register.
|
||||
* Must not be NULL.
|
||||
*
|
||||
* @supports_hwpctl: Returns a boolean whether Hardware Power Control
|
||||
* is supported or not.
|
||||
* If NULL, hwpctl is assumed to be never supported.
|
||||
* @software_rfkill: Turn the radio ON or OFF.
|
||||
* Possible state values are
|
||||
* RFKILL_STATE_SOFT_BLOCKED or
|
||||
* RFKILL_STATE_UNBLOCKED
|
||||
* Must not be NULL.
|
||||
* @switch_channel: Switch the radio to another channel.
|
||||
* Must not be NULL.
|
||||
* @get_default_chan: Just returns the default channel number.
|
||||
* Must not be NULL.
|
||||
* @set_rx_antenna: Set the antenna used for RX.
|
||||
* Can be NULL, if not supported.
|
||||
* @interf_mitigation: Switch the Interference Mitigation mode.
|
||||
* Can be NULL, if not supported.
|
||||
*
|
||||
* @xmitpower: FIXME REMOVEME
|
||||
* Must not be NULL.
|
||||
*
|
||||
* @pwork_15sec: Periodic work. Called every 15 seconds.
|
||||
* Can be NULL, if not required.
|
||||
* @pwork_60sec: Periodic work. Called every 60 seconds.
|
||||
* Can be NULL, if not required.
|
||||
*/
|
||||
struct b43_phy_operations {
|
||||
/* Initialisation */
|
||||
int (*allocate)(struct b43_wldev *dev);
|
||||
int (*prepare)(struct b43_wldev *dev);
|
||||
int (*init)(struct b43_wldev *dev);
|
||||
void (*exit)(struct b43_wldev *dev);
|
||||
|
||||
/* Register access */
|
||||
u16 (*phy_read)(struct b43_wldev *dev, u16 reg);
|
||||
void (*phy_write)(struct b43_wldev *dev, u16 reg, u16 value);
|
||||
u16 (*radio_read)(struct b43_wldev *dev, u16 reg);
|
||||
void (*radio_write)(struct b43_wldev *dev, u16 reg, u16 value);
|
||||
|
||||
/* Radio */
|
||||
bool (*supports_hwpctl)(struct b43_wldev *dev);
|
||||
void (*software_rfkill)(struct b43_wldev *dev, enum rfkill_state state);
|
||||
int (*switch_channel)(struct b43_wldev *dev, unsigned int new_channel);
|
||||
unsigned int (*get_default_chan)(struct b43_wldev *dev);
|
||||
void (*set_rx_antenna)(struct b43_wldev *dev, int antenna);
|
||||
int (*interf_mitigation)(struct b43_wldev *dev,
|
||||
enum b43_interference_mitigation new_mode);
|
||||
|
||||
/* Transmission power adjustment */
|
||||
void (*xmitpower)(struct b43_wldev *dev);
|
||||
|
||||
/* Misc */
|
||||
void (*pwork_15sec)(struct b43_wldev *dev);
|
||||
void (*pwork_60sec)(struct b43_wldev *dev);
|
||||
};
|
||||
|
||||
struct b43_phy_a;
|
||||
struct b43_phy_g;
|
||||
struct b43_phy_n;
|
||||
|
||||
struct b43_phy {
|
||||
/* Hardware operation callbacks. */
|
||||
const struct b43_phy_operations *ops;
|
||||
|
||||
/* Most hardware context information is stored in the standard-
|
||||
* specific data structures pointed to by the pointers below.
|
||||
* Only one of them is valid (the currently enabled PHY). */
|
||||
#ifdef CONFIG_B43_DEBUG
|
||||
/* No union for debug build to force NULL derefs in buggy code. */
|
||||
struct {
|
||||
#else
|
||||
union {
|
||||
#endif
|
||||
/* A-PHY specific information */
|
||||
struct b43_phy_a *a;
|
||||
/* G-PHY specific information */
|
||||
struct b43_phy_g *g;
|
||||
/* N-PHY specific information */
|
||||
struct b43_phy_n *n;
|
||||
};
|
||||
|
||||
/* 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 */
|
||||
|
||||
/* Software state of the radio */
|
||||
bool radio_on;
|
||||
|
||||
/* Desired TX power level (in dBm).
|
||||
* This is set by the user and adjusted in b43_phy_xmitpower(). */
|
||||
u8 power_level;
|
||||
|
||||
/* Hardware Power Control enabled? */
|
||||
bool hardware_power_control;
|
||||
|
||||
/* current channel */
|
||||
unsigned int channel;
|
||||
|
||||
/* PHY TX errors counter. */
|
||||
atomic_t txerr_cnt;
|
||||
|
||||
#ifdef CONFIG_B43_DEBUG
|
||||
/* PHY registers locked by b43_phy_lock()? */
|
||||
bool phy_locked;
|
||||
#endif /* B43_DEBUG */
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* b43_phy_operations_setup - Initialize the PHY operations datastructure
|
||||
* based on the current PHY type.
|
||||
*/
|
||||
int b43_phy_operations_setup(struct b43_wldev *dev);
|
||||
|
||||
/**
|
||||
* b43_phy_init - Initialise the PHY
|
||||
*/
|
||||
int b43_phy_init(struct b43_wldev *dev);
|
||||
|
||||
/**
|
||||
* b43_phy_exit - Cleanup PHY
|
||||
*/
|
||||
void b43_phy_exit(struct b43_wldev *dev);
|
||||
|
||||
/**
|
||||
* b43_has_hardware_pctl - Hardware Power Control supported?
|
||||
* Returns a boolean, whether hardware power control is supported.
|
||||
*/
|
||||
bool b43_has_hardware_pctl(struct b43_wldev *dev);
|
||||
|
||||
/**
|
||||
* b43_phy_read - 16bit PHY register read access
|
||||
*/
|
||||
u16 b43_phy_read(struct b43_wldev *dev, u16 reg);
|
||||
|
||||
/**
|
||||
* b43_phy_write - 16bit PHY register write access
|
||||
*/
|
||||
void b43_phy_write(struct b43_wldev *dev, u16 reg, u16 value);
|
||||
|
||||
/**
|
||||
* b43_phy_mask - Mask a PHY register with a mask
|
||||
*/
|
||||
void b43_phy_mask(struct b43_wldev *dev, u16 offset, u16 mask);
|
||||
|
||||
/**
|
||||
* b43_phy_set - OR a PHY register with a bitmap
|
||||
*/
|
||||
void b43_phy_set(struct b43_wldev *dev, u16 offset, u16 set);
|
||||
|
||||
/**
|
||||
* b43_phy_maskset - Mask and OR a PHY register with a mask and bitmap
|
||||
*/
|
||||
void b43_phy_maskset(struct b43_wldev *dev, u16 offset, u16 mask, u16 set);
|
||||
|
||||
/**
|
||||
* b43_radio_read - 16bit Radio register read access
|
||||
*/
|
||||
u16 b43_radio_read(struct b43_wldev *dev, u16 reg);
|
||||
#define b43_radio_read16 b43_radio_read /* DEPRECATED */
|
||||
|
||||
/**
|
||||
* b43_radio_write - 16bit Radio register write access
|
||||
*/
|
||||
void b43_radio_write(struct b43_wldev *dev, u16 reg, u16 value);
|
||||
#define b43_radio_write16 b43_radio_write /* DEPRECATED */
|
||||
|
||||
/**
|
||||
* b43_radio_mask - Mask a 16bit radio register with a mask
|
||||
*/
|
||||
void b43_radio_mask(struct b43_wldev *dev, u16 offset, u16 mask);
|
||||
|
||||
/**
|
||||
* b43_radio_set - OR a 16bit radio register with a bitmap
|
||||
*/
|
||||
void b43_radio_set(struct b43_wldev *dev, u16 offset, u16 set);
|
||||
|
||||
/**
|
||||
* b43_radio_maskset - Mask and OR a radio register with a mask and bitmap
|
||||
*/
|
||||
void b43_radio_maskset(struct b43_wldev *dev, u16 offset, u16 mask, u16 set);
|
||||
|
||||
/**
|
||||
* b43_radio_lock - Lock firmware radio register access
|
||||
*/
|
||||
void b43_radio_lock(struct b43_wldev *dev);
|
||||
|
||||
/**
|
||||
* b43_radio_unlock - Unlock firmware radio register access
|
||||
*/
|
||||
void b43_radio_unlock(struct b43_wldev *dev);
|
||||
|
||||
/**
|
||||
* b43_phy_lock - Lock firmware PHY register access
|
||||
*/
|
||||
void b43_phy_lock(struct b43_wldev *dev);
|
||||
|
||||
/**
|
||||
* b43_phy_unlock - Unlock firmware PHY register access
|
||||
*/
|
||||
void b43_phy_unlock(struct b43_wldev *dev);
|
||||
|
||||
/**
|
||||
* b43_switch_channel - Switch to another channel
|
||||
*/
|
||||
int b43_switch_channel(struct b43_wldev *dev, unsigned int new_channel);
|
||||
/**
|
||||
* B43_DEFAULT_CHANNEL - Switch to the default channel.
|
||||
*/
|
||||
#define B43_DEFAULT_CHANNEL UINT_MAX
|
||||
|
||||
/**
|
||||
* b43_software_rfkill - Turn the radio ON or OFF in software.
|
||||
*/
|
||||
void b43_software_rfkill(struct b43_wldev *dev, enum rfkill_state state);
|
||||
|
||||
#endif /* LINUX_B43_PHY_COMMON_H_ */
|
3229
drivers/net/wireless/b43/phy_g.c
Normal file
3229
drivers/net/wireless/b43/phy_g.c
Normal file
File diff suppressed because it is too large
Load Diff
201
drivers/net/wireless/b43/phy_g.h
Normal file
201
drivers/net/wireless/b43/phy_g.h
Normal file
@ -0,0 +1,201 @@
|
||||
#ifndef LINUX_B43_PHY_G_H_
|
||||
#define LINUX_B43_PHY_G_H_
|
||||
|
||||
/* OFDM PHY registers are defined in the A-PHY header. */
|
||||
#include "phy_a.h"
|
||||
|
||||
/* CCK (B) PHY Registers */
|
||||
#define B43_PHY_VERSION_CCK B43_PHY_CCK(0x00) /* Versioning register for B-PHY */
|
||||
#define B43_PHY_CCKBBANDCFG B43_PHY_CCK(0x01) /* Contains antenna 0/1 control bit */
|
||||
#define B43_PHY_PGACTL B43_PHY_CCK(0x15) /* PGA control */
|
||||
#define B43_PHY_PGACTL_LPF 0x1000 /* Low pass filter (?) */
|
||||
#define B43_PHY_PGACTL_LOWBANDW 0x0040 /* Low bandwidth flag */
|
||||
#define B43_PHY_PGACTL_UNKNOWN 0xEFA0
|
||||
#define B43_PHY_FBCTL1 B43_PHY_CCK(0x18) /* Frequency bandwidth control 1 */
|
||||
#define B43_PHY_ITSSI B43_PHY_CCK(0x29) /* Idle TSSI */
|
||||
#define B43_PHY_LO_LEAKAGE B43_PHY_CCK(0x2D) /* Measured LO leakage */
|
||||
#define B43_PHY_ENERGY B43_PHY_CCK(0x33) /* Energy */
|
||||
#define B43_PHY_SYNCCTL B43_PHY_CCK(0x35)
|
||||
#define B43_PHY_FBCTL2 B43_PHY_CCK(0x38) /* Frequency bandwidth control 2 */
|
||||
#define B43_PHY_DACCTL B43_PHY_CCK(0x60) /* DAC control */
|
||||
#define B43_PHY_RCCALOVER B43_PHY_CCK(0x78) /* RC calibration override */
|
||||
|
||||
/* Extended G-PHY Registers */
|
||||
#define B43_PHY_CLASSCTL B43_PHY_EXTG(0x02) /* Classify control */
|
||||
#define B43_PHY_GTABCTL B43_PHY_EXTG(0x03) /* G-PHY table control (see below) */
|
||||
#define B43_PHY_GTABOFF 0x03FF /* G-PHY table offset (see below) */
|
||||
#define B43_PHY_GTABNR 0xFC00 /* G-PHY table number (see below) */
|
||||
#define B43_PHY_GTABNR_SHIFT 10
|
||||
#define B43_PHY_GTABDATA B43_PHY_EXTG(0x04) /* G-PHY table data */
|
||||
#define B43_PHY_LO_MASK B43_PHY_EXTG(0x0F) /* Local Oscillator control mask */
|
||||
#define B43_PHY_LO_CTL B43_PHY_EXTG(0x10) /* Local Oscillator control */
|
||||
#define B43_PHY_RFOVER B43_PHY_EXTG(0x11) /* RF override */
|
||||
#define B43_PHY_RFOVERVAL B43_PHY_EXTG(0x12) /* RF override value */
|
||||
#define B43_PHY_RFOVERVAL_EXTLNA 0x8000
|
||||
#define B43_PHY_RFOVERVAL_LNA 0x7000
|
||||
#define B43_PHY_RFOVERVAL_LNA_SHIFT 12
|
||||
#define B43_PHY_RFOVERVAL_PGA 0x0F00
|
||||
#define B43_PHY_RFOVERVAL_PGA_SHIFT 8
|
||||
#define B43_PHY_RFOVERVAL_UNK 0x0010 /* Unknown, always set. */
|
||||
#define B43_PHY_RFOVERVAL_TRSWRX 0x00E0
|
||||
#define B43_PHY_RFOVERVAL_BW 0x0003 /* Bandwidth flags */
|
||||
#define B43_PHY_RFOVERVAL_BW_LPF 0x0001 /* Low Pass Filter */
|
||||
#define B43_PHY_RFOVERVAL_BW_LBW 0x0002 /* Low Bandwidth (when set), high when unset */
|
||||
#define B43_PHY_ANALOGOVER B43_PHY_EXTG(0x14) /* Analog override */
|
||||
#define B43_PHY_ANALOGOVERVAL B43_PHY_EXTG(0x15) /* Analog override value */
|
||||
|
||||
|
||||
/*** G-PHY table numbers */
|
||||
#define B43_GTAB(number, offset) (((number) << B43_PHY_GTABNR_SHIFT) | (offset))
|
||||
#define B43_GTAB_NRSSI B43_GTAB(0x00, 0)
|
||||
#define B43_GTAB_TRFEMW B43_GTAB(0x0C, 0x120)
|
||||
#define B43_GTAB_ORIGTR B43_GTAB(0x2E, 0x298)
|
||||
|
||||
u16 b43_gtab_read(struct b43_wldev *dev, u16 table, u16 offset);
|
||||
void b43_gtab_write(struct b43_wldev *dev, u16 table, u16 offset, u16 value);
|
||||
|
||||
|
||||
/* Returns the boolean whether "TX Magnification" is enabled. */
|
||||
#define has_tx_magnification(phy) \
|
||||
(((phy)->rev >= 2) && \
|
||||
((phy)->radio_ver == 0x2050) && \
|
||||
((phy)->radio_rev == 8))
|
||||
/* Card uses the loopback gain stuff */
|
||||
#define has_loopback_gain(phy) \
|
||||
(((phy)->rev > 1) || ((phy)->gmode))
|
||||
|
||||
/* Radio Attenuation (RF Attenuation) */
|
||||
struct b43_rfatt {
|
||||
u8 att; /* Attenuation value */
|
||||
bool with_padmix; /* Flag, PAD Mixer enabled. */
|
||||
};
|
||||
struct b43_rfatt_list {
|
||||
/* Attenuation values list */
|
||||
const struct b43_rfatt *list;
|
||||
u8 len;
|
||||
/* Minimum/Maximum attenuation values */
|
||||
u8 min_val;
|
||||
u8 max_val;
|
||||
};
|
||||
|
||||
/* Returns true, if the values are the same. */
|
||||
static inline bool b43_compare_rfatt(const struct b43_rfatt *a,
|
||||
const struct b43_rfatt *b)
|
||||
{
|
||||
return ((a->att == b->att) &&
|
||||
(a->with_padmix == b->with_padmix));
|
||||
}
|
||||
|
||||
/* Baseband Attenuation */
|
||||
struct b43_bbatt {
|
||||
u8 att; /* Attenuation value */
|
||||
};
|
||||
struct b43_bbatt_list {
|
||||
/* Attenuation values list */
|
||||
const struct b43_bbatt *list;
|
||||
u8 len;
|
||||
/* Minimum/Maximum attenuation values */
|
||||
u8 min_val;
|
||||
u8 max_val;
|
||||
};
|
||||
|
||||
/* Returns true, if the values are the same. */
|
||||
static inline bool b43_compare_bbatt(const struct b43_bbatt *a,
|
||||
const struct b43_bbatt *b)
|
||||
{
|
||||
return (a->att == b->att);
|
||||
}
|
||||
|
||||
/* tx_control bits. */
|
||||
#define B43_TXCTL_PA3DB 0x40 /* PA Gain 3dB */
|
||||
#define B43_TXCTL_PA2DB 0x20 /* PA Gain 2dB */
|
||||
#define B43_TXCTL_TXMIX 0x10 /* TX Mixer Gain */
|
||||
|
||||
struct b43_txpower_lo_control;
|
||||
|
||||
struct b43_phy_g {
|
||||
bool initialised;
|
||||
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 */
|
||||
|
||||
/* Current TX power level attenuation control values */
|
||||
struct b43_bbatt bbatt;
|
||||
struct b43_rfatt rfatt;
|
||||
u8 tx_control; /* B43_TXCTL_XXX */
|
||||
|
||||
/* 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];
|
||||
|
||||
u16 lofcal;
|
||||
|
||||
u16 initval; //FIXME rename?
|
||||
|
||||
/* 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;
|
||||
};
|
||||
|
||||
void b43_gphy_set_baseband_attenuation(struct b43_wldev *dev,
|
||||
u16 baseband_attenuation);
|
||||
void b43_gphy_channel_switch(struct b43_wldev *dev,
|
||||
unsigned int channel,
|
||||
bool synthetic_pu_workaround);
|
||||
|
||||
struct b43_phy_operations;
|
||||
extern const struct b43_phy_operations b43_phyops_g;
|
||||
|
||||
#endif /* LINUX_B43_PHY_G_H_ */
|
@ -24,6 +24,7 @@
|
||||
|
||||
#include "rfkill.h"
|
||||
#include "b43.h"
|
||||
#include "phy_common.h"
|
||||
|
||||
#include <linux/kmod.h>
|
||||
|
||||
@ -114,11 +115,11 @@ static int b43_rfkill_soft_toggle(void *data, enum rfkill_state state)
|
||||
goto out_unlock;
|
||||
}
|
||||
if (!dev->phy.radio_on)
|
||||
b43_radio_turn_on(dev);
|
||||
b43_software_rfkill(dev, state);
|
||||
break;
|
||||
case RFKILL_STATE_SOFT_BLOCKED:
|
||||
if (dev->phy.radio_on)
|
||||
b43_radio_turn_off(dev, 0);
|
||||
b43_software_rfkill(dev, state);
|
||||
break;
|
||||
default:
|
||||
b43warn(wl, "Received unexpected rfkill state %d.\n", state);
|
||||
|
@ -29,7 +29,7 @@
|
||||
#include "b43.h"
|
||||
#include "sysfs.h"
|
||||
#include "main.h"
|
||||
#include "phy.h"
|
||||
#include "phy_common.h"
|
||||
|
||||
#define GENERIC_FILESIZE 64
|
||||
|
||||
@ -59,7 +59,12 @@ static ssize_t b43_attr_interfmode_show(struct device *dev,
|
||||
|
||||
mutex_lock(&wldev->wl->mutex);
|
||||
|
||||
switch (wldev->phy.interfmode) {
|
||||
if (wldev->phy.type != B43_PHYTYPE_G) {
|
||||
mutex_unlock(&wldev->wl->mutex);
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
switch (wldev->phy.g->interfmode) {
|
||||
case B43_INTERFMODE_NONE:
|
||||
count =
|
||||
snprintf(buf, PAGE_SIZE,
|
||||
@ -117,11 +122,15 @@ static ssize_t b43_attr_interfmode_store(struct device *dev,
|
||||
mutex_lock(&wldev->wl->mutex);
|
||||
spin_lock_irqsave(&wldev->wl->irq_lock, flags);
|
||||
|
||||
err = b43_radio_set_interference_mitigation(wldev, mode);
|
||||
if (err) {
|
||||
b43err(wldev->wl, "Interference Mitigation not "
|
||||
"supported by device\n");
|
||||
}
|
||||
if (wldev->phy.ops->interf_mitigation) {
|
||||
err = wldev->phy.ops->interf_mitigation(wldev, mode);
|
||||
if (err) {
|
||||
b43err(wldev->wl, "Interference Mitigation not "
|
||||
"supported by device\n");
|
||||
}
|
||||
} else
|
||||
err = -ENOSYS;
|
||||
|
||||
mmiowb();
|
||||
spin_unlock_irqrestore(&wldev->wl->irq_lock, flags);
|
||||
mutex_unlock(&wldev->wl->mutex);
|
||||
|
@ -27,7 +27,8 @@
|
||||
|
||||
#include "b43.h"
|
||||
#include "tables.h"
|
||||
#include "phy.h"
|
||||
#include "phy_g.h"
|
||||
|
||||
|
||||
const u32 b43_tab_rotor[] = {
|
||||
0xFEB93FFD, 0xFEC63FFD, /* 0 */
|
||||
@ -377,17 +378,17 @@ static inline void assert_sizes(void)
|
||||
|
||||
u16 b43_ofdmtab_read16(struct b43_wldev *dev, u16 table, u16 offset)
|
||||
{
|
||||
struct b43_phy *phy = &dev->phy;
|
||||
struct b43_phy_g *gphy = dev->phy.g;
|
||||
u16 addr;
|
||||
|
||||
addr = table + offset;
|
||||
if ((phy->ofdmtab_addr_direction != B43_OFDMTAB_DIRECTION_READ) ||
|
||||
(addr - 1 != phy->ofdmtab_addr)) {
|
||||
if ((gphy->ofdmtab_addr_direction != B43_OFDMTAB_DIRECTION_READ) ||
|
||||
(addr - 1 != gphy->ofdmtab_addr)) {
|
||||
/* The hardware has a different address in memory. Update it. */
|
||||
b43_phy_write(dev, B43_PHY_OTABLECTL, addr);
|
||||
phy->ofdmtab_addr_direction = B43_OFDMTAB_DIRECTION_READ;
|
||||
gphy->ofdmtab_addr_direction = B43_OFDMTAB_DIRECTION_READ;
|
||||
}
|
||||
phy->ofdmtab_addr = addr;
|
||||
gphy->ofdmtab_addr = addr;
|
||||
|
||||
return b43_phy_read(dev, B43_PHY_OTABLEI);
|
||||
|
||||
@ -398,34 +399,34 @@ u16 b43_ofdmtab_read16(struct b43_wldev *dev, u16 table, u16 offset)
|
||||
void b43_ofdmtab_write16(struct b43_wldev *dev, u16 table,
|
||||
u16 offset, u16 value)
|
||||
{
|
||||
struct b43_phy *phy = &dev->phy;
|
||||
struct b43_phy_g *gphy = dev->phy.g;
|
||||
u16 addr;
|
||||
|
||||
addr = table + offset;
|
||||
if ((phy->ofdmtab_addr_direction != B43_OFDMTAB_DIRECTION_WRITE) ||
|
||||
(addr - 1 != phy->ofdmtab_addr)) {
|
||||
if ((gphy->ofdmtab_addr_direction != B43_OFDMTAB_DIRECTION_WRITE) ||
|
||||
(addr - 1 != gphy->ofdmtab_addr)) {
|
||||
/* The hardware has a different address in memory. Update it. */
|
||||
b43_phy_write(dev, B43_PHY_OTABLECTL, addr);
|
||||
phy->ofdmtab_addr_direction = B43_OFDMTAB_DIRECTION_WRITE;
|
||||
gphy->ofdmtab_addr_direction = B43_OFDMTAB_DIRECTION_WRITE;
|
||||
}
|
||||
phy->ofdmtab_addr = addr;
|
||||
gphy->ofdmtab_addr = addr;
|
||||
b43_phy_write(dev, B43_PHY_OTABLEI, value);
|
||||
}
|
||||
|
||||
u32 b43_ofdmtab_read32(struct b43_wldev *dev, u16 table, u16 offset)
|
||||
{
|
||||
struct b43_phy *phy = &dev->phy;
|
||||
struct b43_phy_g *gphy = dev->phy.g;
|
||||
u32 ret;
|
||||
u16 addr;
|
||||
|
||||
addr = table + offset;
|
||||
if ((phy->ofdmtab_addr_direction != B43_OFDMTAB_DIRECTION_READ) ||
|
||||
(addr - 1 != phy->ofdmtab_addr)) {
|
||||
if ((gphy->ofdmtab_addr_direction != B43_OFDMTAB_DIRECTION_READ) ||
|
||||
(addr - 1 != gphy->ofdmtab_addr)) {
|
||||
/* The hardware has a different address in memory. Update it. */
|
||||
b43_phy_write(dev, B43_PHY_OTABLECTL, addr);
|
||||
phy->ofdmtab_addr_direction = B43_OFDMTAB_DIRECTION_READ;
|
||||
gphy->ofdmtab_addr_direction = B43_OFDMTAB_DIRECTION_READ;
|
||||
}
|
||||
phy->ofdmtab_addr = addr;
|
||||
gphy->ofdmtab_addr = addr;
|
||||
ret = b43_phy_read(dev, B43_PHY_OTABLEQ);
|
||||
ret <<= 16;
|
||||
ret |= b43_phy_read(dev, B43_PHY_OTABLEI);
|
||||
@ -436,17 +437,17 @@ u32 b43_ofdmtab_read32(struct b43_wldev *dev, u16 table, u16 offset)
|
||||
void b43_ofdmtab_write32(struct b43_wldev *dev, u16 table,
|
||||
u16 offset, u32 value)
|
||||
{
|
||||
struct b43_phy *phy = &dev->phy;
|
||||
struct b43_phy_g *gphy = dev->phy.g;
|
||||
u16 addr;
|
||||
|
||||
addr = table + offset;
|
||||
if ((phy->ofdmtab_addr_direction != B43_OFDMTAB_DIRECTION_WRITE) ||
|
||||
(addr - 1 != phy->ofdmtab_addr)) {
|
||||
if ((gphy->ofdmtab_addr_direction != B43_OFDMTAB_DIRECTION_WRITE) ||
|
||||
(addr - 1 != gphy->ofdmtab_addr)) {
|
||||
/* The hardware has a different address in memory. Update it. */
|
||||
b43_phy_write(dev, B43_PHY_OTABLECTL, addr);
|
||||
phy->ofdmtab_addr_direction = B43_OFDMTAB_DIRECTION_WRITE;
|
||||
gphy->ofdmtab_addr_direction = B43_OFDMTAB_DIRECTION_WRITE;
|
||||
}
|
||||
phy->ofdmtab_addr = addr;
|
||||
gphy->ofdmtab_addr = addr;
|
||||
|
||||
b43_phy_write(dev, B43_PHY_OTABLEI, value);
|
||||
b43_phy_write(dev, B43_PHY_OTABLEQ, (value >> 16));
|
||||
|
@ -24,7 +24,7 @@
|
||||
|
||||
#include "b43.h"
|
||||
#include "tables_nphy.h"
|
||||
#include "phy.h"
|
||||
#include "phy_common.h"
|
||||
#include "nphy.h"
|
||||
|
||||
|
||||
|
@ -27,7 +27,7 @@
|
||||
#include "b43.h"
|
||||
#include "main.h"
|
||||
#include "tables.h"
|
||||
#include "phy.h"
|
||||
#include "phy_common.h"
|
||||
#include "wa.h"
|
||||
|
||||
static void b43_wa_papd(struct b43_wldev *dev)
|
||||
|
@ -28,7 +28,7 @@
|
||||
*/
|
||||
|
||||
#include "xmit.h"
|
||||
#include "phy.h"
|
||||
#include "phy_common.h"
|
||||
#include "dma.h"
|
||||
#include "pio.h"
|
||||
|
||||
@ -431,6 +431,7 @@ static s8 b43_rssi_postprocess(struct b43_wldev *dev,
|
||||
int adjust_2053, int adjust_2050)
|
||||
{
|
||||
struct b43_phy *phy = &dev->phy;
|
||||
struct b43_phy_g *gphy = phy->g;
|
||||
s32 tmp;
|
||||
|
||||
switch (phy->radio_ver) {
|
||||
@ -450,7 +451,8 @@ static s8 b43_rssi_postprocess(struct b43_wldev *dev,
|
||||
boardflags_lo & B43_BFL_RSSI) {
|
||||
if (in_rssi > 63)
|
||||
in_rssi = 63;
|
||||
tmp = phy->nrssi_lt[in_rssi];
|
||||
B43_WARN_ON(phy->type != B43_PHYTYPE_G);
|
||||
tmp = gphy->nrssi_lt[in_rssi];
|
||||
tmp = 31 - tmp;
|
||||
tmp *= -131;
|
||||
tmp /= 128;
|
||||
|
Loading…
Reference in New Issue
Block a user