Commit 5904d206 authored by Gábor Stefanik's avatar Gábor Stefanik Committed by John W. Linville

b43: LP-PHY: Implement spec updates and remove resolved FIXMEs

Larry has started re-checking all current routines against a new
version of the Broadcom MIPS driver. This patch implements the first
round of changes he documented on the specs wiki.

Also remove a few FIXMEs regarding missing initial values for variables
with dynamic initial values where reading the values has been implemented.
Signed-off-by: default avatarGábor Stefanik <netrolller.3d@gmail.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 16a832e7
...@@ -724,9 +724,39 @@ static void lpphy_set_bb_mult(struct b43_wldev *dev, u8 bb_mult) ...@@ -724,9 +724,39 @@ static void lpphy_set_bb_mult(struct b43_wldev *dev, u8 bb_mult)
b43_lptab_write(dev, B43_LPTAB16(0, 87), (u16)bb_mult << 8); b43_lptab_write(dev, B43_LPTAB16(0, 87), (u16)bb_mult << 8);
} }
static void lpphy_disable_crs(struct b43_wldev *dev) static void lpphy_set_deaf(struct b43_wldev *dev, bool user)
{ {
struct b43_phy_lp *lpphy = dev->phy.lp;
if (user)
lpphy->crs_usr_disable = 1;
else
lpphy->crs_sys_disable = 1;
b43_phy_maskset(dev, B43_LPPHY_CRSGAIN_CTL, 0xFF1F, 0x80); b43_phy_maskset(dev, B43_LPPHY_CRSGAIN_CTL, 0xFF1F, 0x80);
}
static void lpphy_clear_deaf(struct b43_wldev *dev, bool user)
{
struct b43_phy_lp *lpphy = dev->phy.lp;
if (user)
lpphy->crs_usr_disable = 0;
else
lpphy->crs_sys_disable = 0;
if (!lpphy->crs_usr_disable && !lpphy->crs_sys_disable) {
if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
b43_phy_maskset(dev, B43_LPPHY_CRSGAIN_CTL,
0xFF1F, 0x60);
else
b43_phy_maskset(dev, B43_LPPHY_CRSGAIN_CTL,
0xFF1F, 0x20);
}
}
static void lpphy_disable_crs(struct b43_wldev *dev, bool user)
{
lpphy_set_deaf(dev, user);
b43_phy_maskset(dev, B43_LPPHY_RF_OVERRIDE_VAL_0, 0xFFFC, 0x1); b43_phy_maskset(dev, B43_LPPHY_RF_OVERRIDE_VAL_0, 0xFFFC, 0x1);
b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x3); b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x3);
b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_VAL_0, 0xFFFB); b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_VAL_0, 0xFFFB);
...@@ -754,12 +784,9 @@ static void lpphy_disable_crs(struct b43_wldev *dev) ...@@ -754,12 +784,9 @@ static void lpphy_disable_crs(struct b43_wldev *dev)
b43_phy_write(dev, B43_LPPHY_RF_OVERRIDE_2, 0x3FF); b43_phy_write(dev, B43_LPPHY_RF_OVERRIDE_2, 0x3FF);
} }
static void lpphy_restore_crs(struct b43_wldev *dev) static void lpphy_restore_crs(struct b43_wldev *dev, bool user)
{ {
if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) lpphy_clear_deaf(dev, user);
b43_phy_maskset(dev, B43_LPPHY_CRSGAIN_CTL, 0xFF1F, 0x60);
else
b43_phy_maskset(dev, B43_LPPHY_CRSGAIN_CTL, 0xFF1F, 0x20);
b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_0, 0xFF80); b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_0, 0xFF80);
b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFC00); b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFC00);
} }
...@@ -805,10 +832,11 @@ static void lpphy_set_tx_gains(struct b43_wldev *dev, ...@@ -805,10 +832,11 @@ static void lpphy_set_tx_gains(struct b43_wldev *dev,
b43_phy_maskset(dev, B43_LPPHY_TX_GAIN_CTL_OVERRIDE_VAL, b43_phy_maskset(dev, B43_LPPHY_TX_GAIN_CTL_OVERRIDE_VAL,
0xF800, rf_gain); 0xF800, rf_gain);
} else { } else {
pa_gain = b43_phy_read(dev, B43_PHY_OFDM(0xFB)) & 0x7F00; pa_gain = b43_phy_read(dev, B43_PHY_OFDM(0xFB)) & 0x1FC0;
pa_gain <<= 2;
b43_phy_write(dev, B43_LPPHY_TX_GAIN_CTL_OVERRIDE_VAL, b43_phy_write(dev, B43_LPPHY_TX_GAIN_CTL_OVERRIDE_VAL,
(gains.pga << 8) | gains.gm); (gains.pga << 8) | gains.gm);
b43_phy_maskset(dev, B43_LPPHY_TX_GAIN_CTL_OVERRIDE_VAL, b43_phy_maskset(dev, B43_PHY_OFDM(0xFB),
0x8000, gains.pad | pa_gain); 0x8000, gains.pad | pa_gain);
b43_phy_write(dev, B43_PHY_OFDM(0xFC), b43_phy_write(dev, B43_PHY_OFDM(0xFC),
(gains.pga << 8) | gains.gm); (gains.pga << 8) | gains.gm);
...@@ -822,7 +850,7 @@ static void lpphy_set_tx_gains(struct b43_wldev *dev, ...@@ -822,7 +850,7 @@ static void lpphy_set_tx_gains(struct b43_wldev *dev,
b43_phy_maskset(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFF7F, 1 << 7); b43_phy_maskset(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFF7F, 1 << 7);
b43_phy_maskset(dev, B43_LPPHY_RF_OVERRIDE_2, 0xBFFF, 1 << 14); b43_phy_maskset(dev, B43_LPPHY_RF_OVERRIDE_2, 0xBFFF, 1 << 14);
} }
b43_phy_maskset(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFFBF, 1 << 6); b43_phy_maskset(dev, B43_LPPHY_AFE_CTL_OVR, 0xFFBF, 1 << 6);
} }
static void lpphy_rev0_1_set_rx_gain(struct b43_wldev *dev, u32 gain) static void lpphy_rev0_1_set_rx_gain(struct b43_wldev *dev, u32 gain)
...@@ -862,33 +890,33 @@ static void lpphy_rev2plus_set_rx_gain(struct b43_wldev *dev, u32 gain) ...@@ -862,33 +890,33 @@ static void lpphy_rev2plus_set_rx_gain(struct b43_wldev *dev, u32 gain)
} }
} }
static void lpphy_enable_rx_gain_override(struct b43_wldev *dev) static void lpphy_disable_rx_gain_override(struct b43_wldev *dev)
{ {
b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_0, 0xFFFE); b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_0, 0xFFFE);
b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_0, 0xFFEF); b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_0, 0xFFEF);
b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_0, 0xFFBF); b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_0, 0xFFBF);
if (dev->phy.rev >= 2) { if (dev->phy.rev >= 2) {
b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFEFF); b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFEFF);
if (b43_current_band(dev->wl) != IEEE80211_BAND_2GHZ) if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
return; b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFBFF);
b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFBFF); b43_phy_mask(dev, B43_PHY_OFDM(0xE5), 0xFFF7);
b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFFF7); }
} else { } else {
b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFDFF); b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFDFF);
} }
} }
static void lpphy_disable_rx_gain_override(struct b43_wldev *dev) static void lpphy_enable_rx_gain_override(struct b43_wldev *dev)
{ {
b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x1); b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x1);
b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x10); b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x10);
b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x40); b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x40);
if (dev->phy.rev >= 2) { if (dev->phy.rev >= 2) {
b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_2, 0x100); b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_2, 0x100);
if (b43_current_band(dev->wl) != IEEE80211_BAND_2GHZ) if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
return; b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_2, 0x400);
b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_2, 0x400); b43_phy_set(dev, B43_PHY_OFDM(0xE5), 0x8);
b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_2, 0x8); }
} else { } else {
b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_2, 0x200); b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_2, 0x200);
} }
...@@ -1007,26 +1035,22 @@ static u32 lpphy_qdiv_roundup(u32 dividend, u32 divisor, u8 precision) ...@@ -1007,26 +1035,22 @@ static u32 lpphy_qdiv_roundup(u32 dividend, u32 divisor, u8 precision)
{ {
u32 quotient, remainder, rbit, roundup, tmp; u32 quotient, remainder, rbit, roundup, tmp;
if (divisor == 0) { if (divisor == 0)
quotient = 0; return 0;
remainder = 0;
} else { quotient = dividend / divisor;
quotient = dividend / divisor; remainder = dividend % divisor;
remainder = dividend % divisor;
}
rbit = divisor & 0x1; rbit = divisor & 0x1;
roundup = (divisor >> 1) + rbit; roundup = (divisor >> 1) + rbit;
precision--;
while (precision != 0xFF) { while (precision != 0) {
tmp = remainder - roundup; tmp = remainder - roundup;
quotient <<= 1; quotient <<= 1;
remainder <<= 1; if (remainder >= roundup)
if (remainder >= roundup) {
remainder = (tmp << 1) + rbit; remainder = (tmp << 1) + rbit;
quotient--; else
} remainder <<= 1;
precision--; precision--;
} }
...@@ -1128,11 +1152,11 @@ static void lpphy_rev0_1_rc_calib(struct b43_wldev *dev) ...@@ -1128,11 +1152,11 @@ static void lpphy_rev0_1_rc_calib(struct b43_wldev *dev)
struct b43_phy_lp *lpphy = dev->phy.lp; struct b43_phy_lp *lpphy = dev->phy.lp;
struct lpphy_iq_est iq_est; struct lpphy_iq_est iq_est;
struct lpphy_tx_gains tx_gains; struct lpphy_tx_gains tx_gains;
static const u32 ideal_pwr_table[22] = { static const u32 ideal_pwr_table[21] = {
0x10000, 0x10557, 0x10e2d, 0x113e0, 0x10f22, 0x0ff64, 0x10000, 0x10557, 0x10e2d, 0x113e0, 0x10f22, 0x0ff64,
0x0eda2, 0x0e5d4, 0x0efd1, 0x0fbe8, 0x0b7b8, 0x04b35, 0x0eda2, 0x0e5d4, 0x0efd1, 0x0fbe8, 0x0b7b8, 0x04b35,
0x01a5e, 0x00a0b, 0x00444, 0x001fd, 0x000ff, 0x00088, 0x01a5e, 0x00a0b, 0x00444, 0x001fd, 0x000ff, 0x00088,
0x0004c, 0x0002c, 0x0001a, 0xc0006, 0x0004c, 0x0002c, 0x0001a,
}; };
bool old_txg_ovr; bool old_txg_ovr;
u8 old_bbmult; u8 old_bbmult;
...@@ -1150,7 +1174,7 @@ static void lpphy_rev0_1_rc_calib(struct b43_wldev *dev) ...@@ -1150,7 +1174,7 @@ static void lpphy_rev0_1_rc_calib(struct b43_wldev *dev)
"RC calib: Failed to switch to channel 7, error = %d", "RC calib: Failed to switch to channel 7, error = %d",
err); err);
} }
old_txg_ovr = (b43_phy_read(dev, B43_LPPHY_AFE_CTL_OVR) >> 6) & 1; old_txg_ovr = !!(b43_phy_read(dev, B43_LPPHY_AFE_CTL_OVR) & 0x40);
old_bbmult = lpphy_get_bb_mult(dev); old_bbmult = lpphy_get_bb_mult(dev);
if (old_txg_ovr) if (old_txg_ovr)
tx_gains = lpphy_get_tx_gains(dev); tx_gains = lpphy_get_tx_gains(dev);
...@@ -1165,7 +1189,7 @@ static void lpphy_rev0_1_rc_calib(struct b43_wldev *dev) ...@@ -1165,7 +1189,7 @@ static void lpphy_rev0_1_rc_calib(struct b43_wldev *dev)
old_txpctl = lpphy->txpctl_mode; old_txpctl = lpphy->txpctl_mode;
lpphy_set_tx_power_control(dev, B43_LPPHY_TXPCTL_OFF); lpphy_set_tx_power_control(dev, B43_LPPHY_TXPCTL_OFF);
lpphy_disable_crs(dev); lpphy_disable_crs(dev, true);
loopback = lpphy_loopback(dev); loopback = lpphy_loopback(dev);
if (loopback == -1) if (loopback == -1)
goto finish; goto finish;
...@@ -1198,7 +1222,7 @@ static void lpphy_rev0_1_rc_calib(struct b43_wldev *dev) ...@@ -1198,7 +1222,7 @@ static void lpphy_rev0_1_rc_calib(struct b43_wldev *dev)
lpphy_stop_ddfs(dev); lpphy_stop_ddfs(dev);
finish: finish:
lpphy_restore_crs(dev); lpphy_restore_crs(dev, true);
b43_phy_write(dev, B43_LPPHY_RF_OVERRIDE_VAL_0, old_rf_ovrval); b43_phy_write(dev, B43_LPPHY_RF_OVERRIDE_VAL_0, old_rf_ovrval);
b43_phy_write(dev, B43_LPPHY_RF_OVERRIDE_0, old_rf_ovr); b43_phy_write(dev, B43_LPPHY_RF_OVERRIDE_0, old_rf_ovr);
b43_phy_write(dev, B43_LPPHY_AFE_CTL_OVRVAL, old_afe_ovrval); b43_phy_write(dev, B43_LPPHY_AFE_CTL_OVRVAL, old_afe_ovrval);
......
...@@ -825,11 +825,11 @@ struct b43_phy_lp { ...@@ -825,11 +825,11 @@ struct b43_phy_lp {
enum b43_lpphy_txpctl_mode txpctl_mode; enum b43_lpphy_txpctl_mode txpctl_mode;
/* Transmit isolation medium band */ /* Transmit isolation medium band */
u8 tx_isolation_med_band; /* FIXME initial value? */ u8 tx_isolation_med_band;
/* Transmit isolation low band */ /* Transmit isolation low band */
u8 tx_isolation_low_band; /* FIXME initial value? */ u8 tx_isolation_low_band;
/* Transmit isolation high band */ /* Transmit isolation high band */
u8 tx_isolation_hi_band; /* FIXME initial value? */ u8 tx_isolation_hi_band;
/* Max transmit power medium band */ /* Max transmit power medium band */
u16 max_tx_pwr_med_band; u16 max_tx_pwr_med_band;
...@@ -848,7 +848,7 @@ struct b43_phy_lp { ...@@ -848,7 +848,7 @@ struct b43_phy_lp {
s16 txpa[3], txpal[3], txpah[3]; s16 txpa[3], txpal[3], txpah[3];
/* Receive power offset */ /* Receive power offset */
u8 rx_pwr_offset; /* FIXME initial value? */ u8 rx_pwr_offset;
/* TSSI transmit count */ /* TSSI transmit count */
u16 tssi_tx_count; u16 tssi_tx_count;
...@@ -864,16 +864,16 @@ struct b43_phy_lp { ...@@ -864,16 +864,16 @@ struct b43_phy_lp {
s8 tx_pwr_idx_over; /* FIXME initial value? */ s8 tx_pwr_idx_over; /* FIXME initial value? */
/* RSSI vf */ /* RSSI vf */
u8 rssi_vf; /* FIXME initial value? */ u8 rssi_vf;
/* RSSI vc */ /* RSSI vc */
u8 rssi_vc; /* FIXME initial value? */ u8 rssi_vc;
/* RSSI gs */ /* RSSI gs */
u8 rssi_gs; /* FIXME initial value? */ u8 rssi_gs;
/* RC cap */ /* RC cap */
u8 rc_cap; /* FIXME initial value? */ u8 rc_cap; /* FIXME initial value? */
/* BX arch */ /* BX arch */
u8 bx_arch; /* FIXME initial value? */ u8 bx_arch;
/* Full calibration channel */ /* Full calibration channel */
u8 full_calib_chan; /* FIXME initial value? */ u8 full_calib_chan; /* FIXME initial value? */
...@@ -885,6 +885,8 @@ struct b43_phy_lp { ...@@ -885,6 +885,8 @@ struct b43_phy_lp {
/* Used for "Save/Restore Dig Filt State" */ /* Used for "Save/Restore Dig Filt State" */
u16 dig_flt_state[9]; u16 dig_flt_state[9];
bool crs_usr_disable, crs_sys_disable;
unsigned int pdiv; unsigned int pdiv;
}; };
......
...@@ -2367,7 +2367,17 @@ static void lpphy_rev2plus_write_gain_table(struct b43_wldev *dev, int offset, ...@@ -2367,7 +2367,17 @@ static void lpphy_rev2plus_write_gain_table(struct b43_wldev *dev, int offset,
tmp = data.pad << 16; tmp = data.pad << 16;
tmp |= data.pga << 8; tmp |= data.pga << 8;
tmp |= data.gm; tmp |= data.gm;
tmp |= 0x7f000000; if (dev->phy.rev >= 3) {
if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ)
tmp |= 0x10 << 24;
else
tmp |= 0x70 << 24;
} else {
if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ)
tmp |= 0x14 << 24;
else
tmp |= 0x7F << 24;
}
b43_lptab_write(dev, B43_LPTAB32(7, 0xC0 + offset), tmp); b43_lptab_write(dev, B43_LPTAB32(7, 0xC0 + offset), tmp);
tmp = data.bb_mult << 20; tmp = data.bb_mult << 20;
tmp |= data.dac << 28; tmp |= data.dac << 28;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment