#include "radio_2056.h"
#include "radio_2057.h"
#include "main.h"
+#include "ppr.h"
struct nphy_txgains {
u16 tx_lpf[2];
* Tx and Rx
**************************************************/
-static void b43_nphy_op_adjust_txpower(struct b43_wldev *dev)
-{//TODO
-}
-
-static enum b43_txpwr_result b43_nphy_op_recalc_txpower(struct b43_wldev *dev,
- bool ignore_tssi)
-{//TODO
- return B43_TXPWR_RES_DONE;
-}
-
/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrCtrlEnable */
static void b43_nphy_tx_power_ctrl(struct b43_wldev *dev, bool enable)
{
s16 a1[2], b0[2], b1[2];
u8 idle[2];
+ u8 ppr_max;
s8 target[2];
s32 num, den, pwr;
u32 regval[64];
b1[0] = b1[1] = -1393;
}
}
- /* target[0] = target[1] = nphy->tx_power_max; */
+
+ ppr_max = b43_ppr_get_max(dev, &nphy->tx_pwr_max_ppr);
+ if (ppr_max) {
+ target[0] = ppr_max;
+ target[1] = ppr_max;
+ }
if (dev->phy.rev >= 3) {
if (sprom->fem.ghz2.tssipos)
const u32 *table = NULL;
u32 rfpwr_offset;
- u8 pga_gain;
+ u8 pga_gain, pad_gain;
int i;
+ const s16 *uninitialized_var(rf_pwr_offset_table);
table = b43_nphy_get_tx_gain_table(dev);
if (!table)
nphy->gmval = (table[0] >> 16) & 0x7000;
#endif
+ if (phy->rev >= 19) {
+ return;
+ } else if (phy->rev >= 7) {
+ rf_pwr_offset_table = b43_ntab_get_rf_pwr_offset_table(dev);
+ if (!rf_pwr_offset_table)
+ return;
+ /* TODO: Enable this once we have gains configured */
+ return;
+ }
+
for (i = 0; i < 128; i++) {
if (phy->rev >= 19) {
/* TODO */
return;
} else if (phy->rev >= 7) {
- /* TODO */
- return;
+ pga_gain = (table[i] >> 24) & 0xf;
+ pad_gain = (table[i] >> 19) & 0x1f;
+ if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
+ rfpwr_offset = rf_pwr_offset_table[pad_gain];
+ else
+ rfpwr_offset = rf_pwr_offset_table[pga_gain];
} else {
pga_gain = (table[i] >> 24) & 0xF;
if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
b43_mac_enable(dev);
}
+static enum b43_txpwr_result b43_nphy_op_recalc_txpower(struct b43_wldev *dev,
+ bool ignore_tssi)
+{
+ struct b43_phy *phy = &dev->phy;
+ struct b43_phy_n *nphy = dev->phy.n;
+ struct ieee80211_channel *channel = dev->wl->hw->conf.chandef.chan;
+ struct b43_ppr *ppr = &nphy->tx_pwr_max_ppr;
+ u8 max; /* qdBm */
+ bool tx_pwr_state;
+
+ if (nphy->tx_pwr_last_recalc_freq == channel->center_freq &&
+ nphy->tx_pwr_last_recalc_limit == phy->desired_txpower)
+ return B43_TXPWR_RES_DONE;
+
+ /* Make sure we have a clean PPR */
+ b43_ppr_clear(dev, ppr);
+
+ /* HW limitations */
+ b43_ppr_load_max_from_sprom(dev, ppr, B43_BAND_2G);
+
+ /* Regulatory & user settings */
+ max = INT_TO_Q52(phy->chandef->chan->max_power);
+ if (phy->desired_txpower)
+ max = min_t(u8, max, INT_TO_Q52(phy->desired_txpower));
+ b43_ppr_apply_max(dev, ppr, max);
+ if (b43_debug(dev, B43_DBG_XMITPOWER))
+ b43dbg(dev->wl, "Calculated TX power: " Q52_FMT "\n",
+ Q52_ARG(b43_ppr_get_max(dev, ppr)));
+
+ /* TODO: Enable this once we get gains working */
+#if 0
+ /* Some extra gains */
+ hw_gain = 6; /* N-PHY specific */
+ if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
+ hw_gain += sprom->antenna_gain.a0;
+ else
+ hw_gain += sprom->antenna_gain.a1;
+ b43_ppr_add(dev, ppr, -hw_gain);
+#endif
+
+ /* Make sure we didn't go too low */
+ b43_ppr_apply_min(dev, ppr, INT_TO_Q52(8));
+
+ /* Apply */
+ tx_pwr_state = nphy->txpwrctrl;
+ b43_mac_suspend(dev);
+ b43_nphy_tx_power_ctl_setup(dev);
+ if (dev->dev->core_rev == 11 || dev->dev->core_rev == 12) {
+ b43_maskset32(dev, B43_MMIO_MACCTL, ~0, B43_MACCTL_PHY_LOCK);
+ b43_read32(dev, B43_MMIO_MACCTL);
+ udelay(1);
+ }
+ b43_nphy_tx_power_ctrl(dev, nphy->txpwrctrl);
+ if (dev->dev->core_rev == 11 || dev->dev->core_rev == 12)
+ b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_PHY_LOCK, 0);
+ b43_mac_enable(dev);
+
+ nphy->tx_pwr_last_recalc_freq = channel->center_freq;
+ nphy->tx_pwr_last_recalc_limit = phy->desired_txpower;
+
+ return B43_TXPWR_RES_DONE;
+}
+
/**************************************************
* N-PHY init
**************************************************/
b43_mac_switch_freq(dev, spuravoid);
if (dev->phy.rev == 3 || dev->phy.rev == 4)
- ; /* TODO: reset PLL */
+ b43_wireless_core_phy_pll_reset(dev);
if (spuravoid)
b43_phy_set(dev, B43_NPHY_BBCFG, B43_NPHY_BBCFG_RSTRX);
nphy = kzalloc(sizeof(*nphy), GFP_KERNEL);
if (!nphy)
return -ENOMEM;
+
dev->phy.n = nphy;
return 0;
#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 void b43_nphy_op_maskset(struct b43_wldev *dev, u16 reg, u16 mask,
u16 set)
{
check_phyreg(dev, reg);
- b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
+ b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
b43_maskset16(dev, B43_MMIO_PHY_DATA, mask, set);
+ dev->phy.writes_counter = 1;
}
static u16 b43_nphy_op_radio_read(struct b43_wldev *dev, u16 reg)
else
reg |= 0x100;
- b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
+ b43_write16f(dev, B43_MMIO_RADIO_CONTROL, reg);
return b43_read16(dev, B43_MMIO_RADIO_DATA_LOW);
}
/* Register 1 is a 32-bit register. */
B43_WARN_ON(dev->phy.rev < 7 && reg == 1);
- b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
+ b43_write16f(dev, B43_MMIO_RADIO_CONTROL, reg);
b43_write16(dev, B43_MMIO_RADIO_DATA_LOW, value);
}
.free = b43_nphy_op_free,
.prepare_structs = b43_nphy_op_prepare_structs,
.init = b43_nphy_op_init,
- .phy_read = b43_nphy_op_read,
- .phy_write = b43_nphy_op_write,
.phy_maskset = b43_nphy_op_maskset,
.radio_read = b43_nphy_op_radio_read,
.radio_write = b43_nphy_op_radio_write,
.switch_channel = b43_nphy_op_switch_channel,
.get_default_chan = b43_nphy_op_get_default_chan,
.recalc_txpower = b43_nphy_op_recalc_txpower,
- .adjust_txpower = b43_nphy_op_adjust_txpower,
};