/* wlc_lcnphy_rev0_baseband_init */ static void b43_phy_lcn_rev0_baseband_init(struct b43_wldev *dev) { b43_radio_write(dev, 0x11c, 0); b43_phy_write(dev, 0x43b, 0); b43_phy_write(dev, 0x43c, 0); b43_phy_write(dev, 0x44c, 0); b43_phy_write(dev, 0x4e6, 0); b43_phy_write(dev, 0x4f9, 0); b43_phy_write(dev, 0x4b0, 0); b43_phy_write(dev, 0x938, 0); b43_phy_write(dev, 0x4b0, 0); b43_phy_write(dev, 0x44e, 0); b43_phy_set(dev, 0x567, 0x03); b43_phy_set(dev, 0x44a, 0x44); b43_phy_write(dev, 0x44a, 0x80); if (!(dev->dev->bus_sprom->boardflags_lo & B43_BFL_FEM)) ; /* TODO */ b43_phy_maskset(dev, 0x634, ~0xff, 0xc); if (dev->dev->bus_sprom->boardflags_lo & B43_BFL_FEM) { b43_phy_maskset(dev, 0x634, ~0xff, 0xa); b43_phy_write(dev, 0x910, 0x1); } b43_phy_write(dev, 0x910, 0x1); b43_phy_maskset(dev, 0x448, ~0x300, 0x100); b43_phy_maskset(dev, 0x608, ~0xff, 0x17); b43_phy_maskset(dev, 0x604, ~0x7ff, 0x3ea); }
/* http://bcm-v4.sipsolutions.net/802.11/Radio/Switch%20Radio */ static void b43_phy_ht_op_software_rfkill(struct b43_wldev *dev, bool blocked) { if (b43_read32(dev, B43_MMIO_MACCTL) & B43_MACCTL_ENABLED) b43err(dev->wl, "MAC not suspended\n"); /* In the following PHY ops we copy wl's dummy behaviour. * TODO: Find out if reads (currently hidden in masks/masksets) are * needed and replace following ops with just writes or w&r. * Note: B43_PHY_HT_RF_CTL1 register is tricky, wrong operation can * cause delayed (!) machine lock up. */ if (blocked) { b43_phy_mask(dev, B43_PHY_HT_RF_CTL1, 0); } else { b43_phy_mask(dev, B43_PHY_HT_RF_CTL1, 0); b43_phy_maskset(dev, B43_PHY_HT_RF_CTL1, 0, 0x1); b43_phy_mask(dev, B43_PHY_HT_RF_CTL1, 0); b43_phy_maskset(dev, B43_PHY_HT_RF_CTL1, 0, 0x2); if (dev->phy.radio_ver == 0x2059) b43_radio_2059_init(dev); else B43_WARN_ON(1); b43_switch_channel(dev, dev->phy.channel); } }
/* wlc_radio_2064_init */ static void b43_radio_2064_init(struct b43_wldev *dev) { if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { b43_radio_write(dev, 0x09c, 0x0020); b43_radio_write(dev, 0x105, 0x0008); } else { /* TODO */ } b43_radio_write(dev, 0x032, 0x0062); b43_radio_write(dev, 0x033, 0x0019); b43_radio_write(dev, 0x090, 0x0010); b43_radio_write(dev, 0x010, 0x0000); if (dev->phy.rev == 1) { b43_radio_write(dev, 0x060, 0x007f); b43_radio_write(dev, 0x061, 0x0072); b43_radio_write(dev, 0x062, 0x007f); } b43_radio_write(dev, 0x01d, 0x0002); b43_radio_write(dev, 0x01e, 0x0006); b43_phy_write(dev, 0x4ea, 0x4688); b43_phy_maskset(dev, 0x4eb, ~0x7, 0x2); b43_phy_mask(dev, 0x4eb, ~0x01c0); b43_phy_maskset(dev, 0x46a, 0xff00, 0x19); b43_lcntab_write(dev, B43_LCNTAB16(0x00, 0x55), 0); b43_radio_mask(dev, 0x05b, (u16) ~0xff02); b43_radio_set(dev, 0x004, 0x40); b43_radio_set(dev, 0x120, 0x10); b43_radio_set(dev, 0x078, 0x80); b43_radio_set(dev, 0x129, 0x2); b43_radio_set(dev, 0x057, 0x1); b43_radio_set(dev, 0x05b, 0x2); /* TODO: wait for some bit to be set */ b43_radio_read(dev, 0x05c); b43_radio_mask(dev, 0x05b, (u16) ~0xff02); b43_radio_mask(dev, 0x057, (u16) ~0xff01); b43_phy_write(dev, 0x933, 0x2d6b); b43_phy_write(dev, 0x934, 0x2d6b); b43_phy_write(dev, 0x935, 0x2d6b); b43_phy_write(dev, 0x936, 0x2d6b); b43_phy_write(dev, 0x937, 0x016b); b43_radio_mask(dev, 0x057, (u16) ~0xff02); b43_radio_write(dev, 0x0c2, 0x006f); }
/* wlc_lcnphy_bu_tweaks */ static void b43_phy_lcn_bu_tweaks(struct b43_wldev *dev) { b43_phy_set(dev, 0x805, 0x1); b43_phy_maskset(dev, 0x42f, ~0x7, 0x3); b43_phy_maskset(dev, 0x030, ~0x7, 0x3); b43_phy_write(dev, 0x414, 0x1e10); b43_phy_write(dev, 0x415, 0x0640); b43_phy_maskset(dev, 0x4df, (u16) ~0xff00, 0xf700); b43_phy_set(dev, 0x44a, 0x44); b43_phy_write(dev, 0x44a, 0x80); b43_phy_maskset(dev, 0x434, ~0xff, 0xfd); b43_phy_maskset(dev, 0x420, ~0xff, 0x10); if (dev->dev->bus_sprom->board_rev >= 0x1204) b43_radio_set(dev, 0x09b, 0xf0); b43_phy_write(dev, 0x7d6, 0x0902); b43_phy_maskset(dev, 0x429, ~0xf, 0x9); b43_phy_maskset(dev, 0x429, ~(0x3f << 4), 0xe << 4); if (dev->phy.rev == 1) { b43_phy_maskset(dev, 0x423, ~0xff, 0x46); b43_phy_maskset(dev, 0x411, ~0xff, 1); b43_phy_set(dev, 0x434, 0xff); /* FIXME: update to wl */ /* TODO: wl operates on PHY 0x416, brcmsmac is outdated here */ b43_phy_maskset(dev, 0x656, ~0xf, 2); b43_phy_set(dev, 0x44d, 4); b43_radio_set(dev, 0x0f7, 0x4); b43_radio_mask(dev, 0x0f1, ~0x3); b43_radio_maskset(dev, 0x0f2, ~0xf8, 0x90); b43_radio_maskset(dev, 0x0f3, ~0x3, 0x2); b43_radio_maskset(dev, 0x0f3, ~0xf0, 0xa0); b43_radio_set(dev, 0x11f, 0x2); b43_phy_lcn_clear_tx_power_offsets(dev); /* TODO: something more? */ } }
static void b43_phy_ww(struct b43_wldev *dev) { u16 b, curr_s, best_s = 0xFFFF; int i; b43_phy_mask(dev, B43_PHY_CRS0, ~B43_PHY_CRS0_EN); b43_phy_set(dev, B43_PHY_OFDM(0x1B), 0x1000); b43_phy_maskset(dev, B43_PHY_OFDM(0x82), 0xF0FF, 0x0300); b43_radio_set(dev, 0x0009, 0x0080); b43_radio_maskset(dev, 0x0012, 0xFFFC, 0x0002); b43_wa_initgains(dev); b43_phy_write(dev, B43_PHY_OFDM(0xBA), 0x3ED5); b = b43_phy_read(dev, B43_PHY_PWRDOWN); b43_phy_write(dev, B43_PHY_PWRDOWN, (b & 0xFFF8) | 0x0005); b43_radio_set(dev, 0x0004, 0x0004); for (i = 0x10; i <= 0x20; i++) { b43_radio_write16(dev, 0x0013, i); curr_s = b43_phy_read(dev, B43_PHY_OTABLEQ) & 0x00FF; 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_mask(dev, 0x0004, 0xFFFB); b43_radio_write16(dev, 0x0013, best_s); b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1_R1, 0, 0xFFEC); b43_phy_write(dev, B43_PHY_OFDM(0xB7), 0x1E80); 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_maskset(dev, B43_PHY_OFDM(0xBB), 0xF000, 0x0053); b43_phy_maskset(dev, B43_PHY_OFDM61, 0xFE1F, 0x0120); b43_phy_maskset(dev, B43_PHY_OFDM(0x13), 0x0FFF, 0x3000); b43_phy_maskset(dev, B43_PHY_OFDM(0x14), 0x0FFF, 0x3000); b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 6, 0x0017); for (i = 0; i < 6; i++) b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, i, 0x000F); 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_set(dev, B43_PHY_CRS0, B43_PHY_CRS0_EN); }
/* wlc_lcnphy_set_tx_gain */ static void b43_phy_lcn_set_tx_gain(struct b43_wldev *dev, struct lcn_tx_gains *target_gains) { u16 pa_gain = b43_phy_lcn_get_pa_gain(dev); b43_phy_write(dev, 0x4b5, (target_gains->gm_gain | (target_gains->pga_gain << 8))); b43_phy_maskset(dev, 0x4fb, ~0x7fff, (target_gains->pad_gain | (pa_gain << 8))); b43_phy_write(dev, 0x4fc, (target_gains->gm_gain | (target_gains->pga_gain << 8))); b43_phy_maskset(dev, 0x4fd, ~0x7fff, (target_gains->pad_gain | (pa_gain << 8))); b43_phy_lcn_set_dac_gain(dev, target_gains->dac_gain); b43_phy_lcn_set_tx_gain_override(dev, true); }
/* wlc_lcnphy_set_dac_gain */ static void b43_phy_lcn_set_dac_gain(struct b43_wldev *dev, u16 dac_gain) { u16 dac_ctrl; dac_ctrl = b43_phy_read(dev, 0x439); dac_ctrl = dac_ctrl & 0xc7f; dac_ctrl = dac_ctrl | (dac_gain << 7); b43_phy_maskset(dev, 0x439, ~0xfff, dac_ctrl); }
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_mask(dev, B43_PHY_OFDM(0x1B), ~0x1000); if (b43_phy_read(dev, B43_PHY_ENCORE) & B43_PHY_ENCORE_EN) b43_phy_set(dev, B43_PHY_ENCORE, 0x0010); else b43_phy_mask(dev, B43_PHY_ENCORE, ~0x1010); } b43_wa_all(dev); if (phy->type == B43_PHYTYPE_A) { if (phy->gmode && (phy->rev < 3)) b43_phy_set(dev, 0x0034, 0x0001); b43_phy_rssiagc(dev, 0); b43_phy_set(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_maskset(dev, B43_PHY_OFDM(0x6E), 0xE000, 0x3CF); } }
/* wlc_phy_chanspec_set_lcnphy */ static int b43_phy_lcn_set_channel(struct b43_wldev *dev, struct ieee80211_channel *channel, enum nl80211_channel_type channel_type) { static const u16 sfo_cfg[14][2] = { {965, 1087}, {967, 1085}, {969, 1082}, {971, 1080}, {973, 1078}, {975, 1076}, {977, 1073}, {979, 1071}, {981, 1069}, {983, 1067}, {985, 1065}, {987, 1063}, {989, 1060}, {994, 1055}, }; b43_phy_lcn_set_channel_tweaks(dev, channel->hw_value); b43_phy_set(dev, 0x44a, 0x44); b43_phy_write(dev, 0x44a, 0x80); b43_radio_2064_channel_setup(dev); mdelay(1); b43_phy_lcn_afe_set_unset(dev); b43_phy_write(dev, 0x657, sfo_cfg[channel->hw_value - 1][0]); b43_phy_write(dev, 0x658, sfo_cfg[channel->hw_value - 1][1]); if (channel->hw_value == 14) { b43_phy_maskset(dev, 0x448, ~(0x3 << 8), (2) << 8); b43_phy_lcn_load_tx_iir_cck_filter(dev, 3); } else { b43_phy_maskset(dev, 0x448, ~(0x3 << 8), (1) << 8); /* brcmsmac uses filter_type 2, we follow wl with 25 */ b43_phy_lcn_load_tx_iir_cck_filter(dev, 25); } /* brcmsmac uses filter_type 2, we follow wl with 0 */ b43_phy_lcn_load_tx_iir_ofdm_filter(dev, 0); b43_phy_maskset(dev, 0x4eb, ~(0x7 << 3), 0x1 << 3); return 0; }
static void b43_aphy_op_set_rx_antenna(struct b43_wldev *dev, int antenna) {//TODO struct b43_phy *phy = &dev->phy; u16 tmp; int autodiv = 0; if (antenna == B43_ANTENNA_AUTO0 || antenna == B43_ANTENNA_AUTO1) autodiv = 1; b43_hf_write(dev, b43_hf_read(dev) & ~B43_HF_ANTDIVHELP); b43_phy_maskset(dev, B43_PHY_BBANDCFG, ~B43_PHY_BBANDCFG_RXANT, (autodiv ? B43_ANTENNA_AUTO1 : antenna) << B43_PHY_BBANDCFG_RXANT_SHIFT); if (autodiv) { tmp = b43_phy_read(dev, B43_PHY_ANTDWELL); if (antenna == B43_ANTENNA_AUTO1) tmp &= ~B43_PHY_ANTDWELL_AUTODIV1; else tmp |= B43_PHY_ANTDWELL_AUTODIV1; b43_phy_write(dev, B43_PHY_ANTDWELL, tmp); } if (phy->rev < 3) b43_phy_maskset(dev, B43_PHY_ANTDWELL, 0xFF00, 0x24); else { b43_phy_set(dev, B43_PHY_OFDM61, 0x10); if (phy->rev == 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); b43_phy_maskset(dev, B43_PHY_ADIVRELATED, 0xFF00, 8); } } b43_hf_write(dev, b43_hf_read(dev) | B43_HF_ANTDIVHELP); }
void b43_wa_initgains(struct b43_wldev *dev) { struct b43_phy *phy = &dev->phy; b43_phy_write(dev, B43_PHY_LNAHPFCTL, 0x1FF9); b43_phy_mask(dev, B43_PHY_LPFGAINCTL, 0xFF0F); if (phy->rev <= 2) b43_ofdmtab_write16(dev, B43_OFDMTAB_LPFGAIN, 0, 0x1FBF); b43_radio_write16(dev, 0x0002, 0x1FBF); b43_phy_write(dev, 0x0024, 0x4680); b43_phy_write(dev, 0x0020, 0x0003); b43_phy_write(dev, 0x001D, 0x0F40); b43_phy_write(dev, 0x001F, 0x1C00); if (phy->rev <= 3) b43_phy_maskset(dev, 0x002A, 0x00FF, 0x0400); else if (phy->rev == 5) { b43_phy_maskset(dev, 0x002A, 0x00FF, 0x1A00); b43_phy_write(dev, 0x00CC, 0x2121); } if (phy->rev >= 3) b43_phy_write(dev, 0x00BA, 0x3ED5); }
static u16 b43_phy_ht_classifier(struct b43_wldev *dev, u16 mask, u16 val) { u16 tmp; u16 allowed = B43_PHY_HT_CLASS_CTL_CCK_EN | B43_PHY_HT_CLASS_CTL_OFDM_EN | B43_PHY_HT_CLASS_CTL_WAITED_EN; tmp = b43_phy_read(dev, B43_PHY_HT_CLASS_CTL); tmp &= allowed; tmp &= ~mask; tmp |= (val & mask); b43_phy_maskset(dev, B43_PHY_HT_CLASS_CTL, ~allowed, tmp); return tmp; }
/* wlc_lcnphy_set_chanspec_tweaks */ static void b43_phy_lcn_set_channel_tweaks(struct b43_wldev *dev, int channel) { struct bcma_drv_cc *cc = &dev->dev->bdev->bus->drv_cc; b43_phy_maskset(dev, 0x448, ~0x300, (channel == 14) ? 0x200 : 0x100); if (channel == 1 || channel == 2 || channel == 3 || channel == 4 || channel == 9 || channel == 10 || channel == 11 || channel == 12) { bcma_chipco_pll_write(cc, 0x2, 0x03000c04); bcma_chipco_pll_maskset(cc, 0x3, 0x00ffffff, 0x0); bcma_chipco_pll_write(cc, 0x4, 0x200005c0); bcma_cc_set32(cc, BCMA_CC_PMU_CTL, 0x400); b43_phy_write(dev, 0x942, 0); b43_phy_lcn_txrx_spur_avoidance_mode(dev, false); b43_phy_maskset(dev, 0x424, (u16) ~0xff00, 0x1b00); b43_phy_write(dev, 0x425, 0x5907); } else { bcma_chipco_pll_write(cc, 0x2, 0x03140c04); bcma_chipco_pll_maskset(cc, 0x3, 0x00ffffff, 0x333333); bcma_chipco_pll_write(cc, 0x4, 0x202c2820); bcma_cc_set32(cc, BCMA_CC_PMU_CTL, 0x400); b43_phy_write(dev, 0x942, 0); b43_phy_lcn_txrx_spur_avoidance_mode(dev, true); b43_phy_maskset(dev, 0x424, (u16) ~0xff00, 0x1f00); b43_phy_write(dev, 0x425, 0x590a); } b43_phy_set(dev, 0x44a, 0x44); b43_phy_write(dev, 0x44a, 0x80); }
/* wlc_phy_init_lcnphy */ static int b43_phy_lcn_op_init(struct b43_wldev *dev) { struct bcma_drv_cc *cc = &dev->dev->bdev->bus->drv_cc; b43_phy_set(dev, 0x44a, 0x80); b43_phy_mask(dev, 0x44a, 0x7f); b43_phy_set(dev, 0x6d1, 0x80); b43_phy_write(dev, 0x6d0, 0x7); b43_phy_lcn_afe_set_unset(dev); b43_phy_write(dev, 0x60a, 0xa0); b43_phy_write(dev, 0x46a, 0x19); b43_phy_maskset(dev, 0x663, 0xFF00, 0x64); b43_phy_lcn_tables_init(dev); b43_phy_lcn_rev0_baseband_init(dev); b43_phy_lcn_bu_tweaks(dev); if (dev->phy.radio_ver == 0x2064) b43_radio_2064_init(dev); else B43_WARN_ON(1); if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) b43_phy_lcn_tx_pwr_ctl_init(dev); b43_switch_channel(dev, dev->phy.channel); bcma_chipco_regctl_maskset(cc, 0, 0xf, 0x9); bcma_chipco_chipctl_maskset(cc, 0, 0, 0x03cddddd); /* TODO */ b43_phy_set(dev, 0x448, 0x4000); udelay(100); b43_phy_mask(dev, 0x448, ~0x4000); /* TODO */ return 0; }
static void b43_phy_ht_tx_power_ctl_setup(struct b43_wldev *dev) { struct b43_phy_ht *phy_ht = dev->phy.ht; struct ssb_sprom *sprom = dev->dev->bus_sprom; u8 *idle = phy_ht->idle_tssi; u8 target[3]; s16 a1[3], b0[3], b1[3]; u16 freq = dev->phy.channel_freq; int i, c; if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { for (c = 0; c < 3; c++) { target[c] = sprom->core_pwr_info[c].maxpwr_2g; a1[c] = sprom->core_pwr_info[c].pa_2g[0]; b0[c] = sprom->core_pwr_info[c].pa_2g[1]; b1[c] = sprom->core_pwr_info[c].pa_2g[2]; } } else if (freq >= 4900 && freq < 5100) { for (c = 0; c < 3; c++) { target[c] = sprom->core_pwr_info[c].maxpwr_5gl; a1[c] = sprom->core_pwr_info[c].pa_5gl[0]; b0[c] = sprom->core_pwr_info[c].pa_5gl[1]; b1[c] = sprom->core_pwr_info[c].pa_5gl[2]; } } else if (freq >= 5100 && freq < 5500) { for (c = 0; c < 3; c++) { target[c] = sprom->core_pwr_info[c].maxpwr_5g; a1[c] = sprom->core_pwr_info[c].pa_5g[0]; b0[c] = sprom->core_pwr_info[c].pa_5g[1]; b1[c] = sprom->core_pwr_info[c].pa_5g[2]; } } else if (freq >= 5500) { for (c = 0; c < 3; c++) { target[c] = sprom->core_pwr_info[c].maxpwr_5gh; a1[c] = sprom->core_pwr_info[c].pa_5gh[0]; b0[c] = sprom->core_pwr_info[c].pa_5gh[1]; b1[c] = sprom->core_pwr_info[c].pa_5gh[2]; } } else { target[0] = target[1] = target[2] = 52; a1[0] = a1[1] = a1[2] = -424; b0[0] = b0[1] = b0[2] = 5612; b1[0] = b1[1] = b1[2] = -1393; } b43_phy_set(dev, B43_PHY_HT_TSSIMODE, B43_PHY_HT_TSSIMODE_EN); b43_phy_mask(dev, B43_PHY_HT_TXPCTL_CMD_C1, ~B43_PHY_HT_TXPCTL_CMD_C1_PCTLEN & 0xFFFF); /* TODO: Does it depend on sprom->fem.ghz2.tssipos? */ b43_phy_set(dev, B43_PHY_HT_TXPCTL_IDLE_TSSI, 0x4000); b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_CMD_C1, ~B43_PHY_HT_TXPCTL_CMD_C1_INIT, 0x19); b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_CMD_C2, ~B43_PHY_HT_TXPCTL_CMD_C2_INIT, 0x19); b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_CMD_C3, ~B43_PHY_HT_TXPCTL_CMD_C3_INIT, 0x19); b43_phy_set(dev, B43_PHY_HT_TXPCTL_IDLE_TSSI, B43_PHY_HT_TXPCTL_IDLE_TSSI_BINF); b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_IDLE_TSSI, ~B43_PHY_HT_TXPCTL_IDLE_TSSI_C1, idle[0] << B43_PHY_HT_TXPCTL_IDLE_TSSI_C1_SHIFT); b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_IDLE_TSSI, ~B43_PHY_HT_TXPCTL_IDLE_TSSI_C2, idle[1] << B43_PHY_HT_TXPCTL_IDLE_TSSI_C2_SHIFT); b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_IDLE_TSSI2, ~B43_PHY_HT_TXPCTL_IDLE_TSSI2_C3, idle[2] << B43_PHY_HT_TXPCTL_IDLE_TSSI2_C3_SHIFT); b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_N, ~B43_PHY_HT_TXPCTL_N_TSSID, 0xf0); b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_N, ~B43_PHY_HT_TXPCTL_N_NPTIL2, 0x3 << B43_PHY_HT_TXPCTL_N_NPTIL2_SHIFT); #if 0 /* TODO: what to mask/set? */ b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_CMD_C1, 0x800, 0) b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_CMD_C1, 0x400, 0) #endif b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_TARG_PWR, ~B43_PHY_HT_TXPCTL_TARG_PWR_C1, target[0] << B43_PHY_HT_TXPCTL_TARG_PWR_C1_SHIFT); b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_TARG_PWR, ~B43_PHY_HT_TXPCTL_TARG_PWR_C2 & 0xFFFF, target[1] << B43_PHY_HT_TXPCTL_TARG_PWR_C2_SHIFT); b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_TARG_PWR2, ~B43_PHY_HT_TXPCTL_TARG_PWR2_C3, target[2] << B43_PHY_HT_TXPCTL_TARG_PWR2_C3_SHIFT); for (c = 0; c < 3; c++) { s32 num, den, pwr; u32 regval[64]; for (i = 0; i < 64; i++) { num = 8 * (16 * b0[c] + b1[c] * i); den = 32768 + a1[c] * i; pwr = max((4 * num + den / 2) / den, -8); regval[i] = pwr; } b43_httab_write_bulk(dev, B43_HTTAB16(26 + c, 0), 64, regval); } }
static int b43_phy_ht_op_init(struct b43_wldev *dev) { u16 tmp; u16 clip_state[3]; b43_phy_ht_tables_init(dev); b43_phy_mask(dev, 0x0be, ~0x2); b43_phy_set(dev, 0x23f, 0x7ff); b43_phy_set(dev, 0x240, 0x7ff); b43_phy_set(dev, 0x241, 0x7ff); b43_phy_ht_zero_extg(dev); b43_phy_mask(dev, B43_PHY_EXTG(0), ~0x3); b43_phy_write(dev, B43_PHY_HT_AFE_CTL1, 0); b43_phy_write(dev, B43_PHY_HT_AFE_CTL3, 0); b43_phy_write(dev, B43_PHY_HT_AFE_CTL5, 0); b43_phy_write(dev, B43_PHY_EXTG(0x103), 0x20); b43_phy_write(dev, B43_PHY_EXTG(0x101), 0x20); b43_phy_write(dev, 0x20d, 0xb8); b43_phy_write(dev, B43_PHY_EXTG(0x14f), 0xc8); b43_phy_write(dev, 0x70, 0x50); b43_phy_write(dev, 0x1ff, 0x30); if (0) /* TODO: condition */ ; /* TODO: PHY op on reg 0x217 */ b43_phy_read(dev, 0xb0); /* TODO: what for? */ b43_phy_set(dev, 0xb0, 0x1); b43_phy_set(dev, 0xb1, 0x91); b43_phy_write(dev, 0x32f, 0x0003); b43_phy_write(dev, 0x077, 0x0010); b43_phy_write(dev, 0x0b4, 0x0258); b43_phy_mask(dev, 0x17e, ~0x4000); b43_phy_write(dev, 0x0b9, 0x0072); b43_httab_write_few(dev, B43_HTTAB16(7, 0x14e), 2, 0x010f, 0x010f); b43_httab_write_few(dev, B43_HTTAB16(7, 0x15e), 2, 0x010f, 0x010f); b43_httab_write_few(dev, B43_HTTAB16(7, 0x16e), 2, 0x010f, 0x010f); b43_phy_ht_afe_unk1(dev); b43_httab_write_few(dev, B43_HTTAB16(7, 0x130), 9, 0x777, 0x111, 0x111, 0x777, 0x111, 0x111, 0x777, 0x111, 0x111); b43_httab_write(dev, B43_HTTAB16(7, 0x120), 0x0777); b43_httab_write(dev, B43_HTTAB16(7, 0x124), 0x0777); b43_httab_write(dev, B43_HTTAB16(8, 0x00), 0x02); b43_httab_write(dev, B43_HTTAB16(8, 0x10), 0x02); b43_httab_write(dev, B43_HTTAB16(8, 0x20), 0x02); b43_httab_write_few(dev, B43_HTTAB16(8, 0x08), 4, 0x8e, 0x96, 0x96, 0x96); b43_httab_write_few(dev, B43_HTTAB16(8, 0x18), 4, 0x8f, 0x9f, 0x9f, 0x9f); b43_httab_write_few(dev, B43_HTTAB16(8, 0x28), 4, 0x8f, 0x9f, 0x9f, 0x9f); b43_httab_write_few(dev, B43_HTTAB16(8, 0x0c), 4, 0x2, 0x2, 0x2, 0x2); b43_httab_write_few(dev, B43_HTTAB16(8, 0x1c), 4, 0x2, 0x2, 0x2, 0x2); b43_httab_write_few(dev, B43_HTTAB16(8, 0x2c), 4, 0x2, 0x2, 0x2, 0x2); b43_phy_maskset(dev, 0x0280, 0xff00, 0x3e); b43_phy_maskset(dev, 0x0283, 0xff00, 0x3e); b43_phy_maskset(dev, B43_PHY_OFDM(0x0141), 0xff00, 0x46); b43_phy_maskset(dev, 0x0283, 0xff00, 0x40); b43_httab_write_few(dev, B43_HTTAB16(00, 0x8), 4, 0x09, 0x0e, 0x13, 0x18); b43_httab_write_few(dev, B43_HTTAB16(01, 0x8), 4, 0x09, 0x0e, 0x13, 0x18); /* TODO: Did wl mean 2 instead of 40? */ b43_httab_write_few(dev, B43_HTTAB16(40, 0x8), 4, 0x09, 0x0e, 0x13, 0x18); b43_phy_maskset(dev, B43_PHY_OFDM(0x24), 0x3f, 0xd); b43_phy_maskset(dev, B43_PHY_OFDM(0x64), 0x3f, 0xd); b43_phy_maskset(dev, B43_PHY_OFDM(0xa4), 0x3f, 0xd); b43_phy_set(dev, B43_PHY_EXTG(0x060), 0x1); b43_phy_set(dev, B43_PHY_EXTG(0x064), 0x1); b43_phy_set(dev, B43_PHY_EXTG(0x080), 0x1); b43_phy_set(dev, B43_PHY_EXTG(0x084), 0x1); /* Copy some tables entries */ tmp = b43_httab_read(dev, B43_HTTAB16(7, 0x144)); b43_httab_write(dev, B43_HTTAB16(7, 0x14a), tmp); tmp = b43_httab_read(dev, B43_HTTAB16(7, 0x154)); b43_httab_write(dev, B43_HTTAB16(7, 0x15a), tmp); tmp = b43_httab_read(dev, B43_HTTAB16(7, 0x164)); b43_httab_write(dev, B43_HTTAB16(7, 0x16a), tmp); /* Reset CCA */ b43_phy_force_clock(dev, true); tmp = b43_phy_read(dev, B43_PHY_HT_BBCFG); b43_phy_write(dev, B43_PHY_HT_BBCFG, tmp | B43_PHY_HT_BBCFG_RSTCCA); b43_phy_write(dev, B43_PHY_HT_BBCFG, tmp & ~B43_PHY_HT_BBCFG_RSTCCA); b43_phy_force_clock(dev, false); b43_mac_phy_clock_set(dev, true); b43_phy_ht_force_rf_sequence(dev, B43_PHY_HT_RF_SEQ_TRIG_RX2TX); b43_phy_ht_force_rf_sequence(dev, B43_PHY_HT_RF_SEQ_TRIG_RST2RX); /* TODO: PHY op on reg 0xb0 */ /* TODO: Should we restore it? Or store it in global PHY info? */ b43_phy_ht_read_clip_detection(dev, clip_state); if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) b43_phy_ht_bphy_init(dev); b43_httab_write_bulk(dev, B43_HTTAB32(0x1a, 0xc0), B43_HTTAB_1A_C0_LATE_SIZE, b43_httab_0x1a_0xc0_late); return 0; }
static void b43_wa_lms(struct b43_wldev *dev) { b43_phy_maskset(dev, 0x0055, 0xFFC0, 0x0004); }
static void b43_wa_crs_thr(struct b43_wldev *dev) { b43_phy_maskset(dev, B43_PHY_CRS0, ~0x03C0, 0xD000); }
/* wlc_lcnphy_set_tx_gain_override */ static void b43_phy_lcn_set_tx_gain_override(struct b43_wldev *dev, bool enable) { b43_phy_maskset(dev, 0x4b0, ~(0x1 << 7), enable << 7); b43_phy_maskset(dev, 0x4b0, ~(0x1 << 14), enable << 14); b43_phy_maskset(dev, 0x43b, ~(0x1 << 6), enable << 6); }
/* wlc_lcnphy_vbat_temp_sense_setup */ static void b43_phy_lcn_sense_setup(struct b43_wldev *dev, enum lcn_sense_type sense_type) { u8 auxpga_vmidcourse, auxpga_vmidfine, auxpga_gain; u16 auxpga_vmid; u8 tx_pwr_idx; u8 i; u16 save_radio_regs[6][2] = { { 0x007, 0 }, { 0x0ff, 0 }, { 0x11f, 0 }, { 0x005, 0 }, { 0x025, 0 }, { 0x112, 0 }, }; u16 save_phy_regs[14][2] = { { 0x503, 0 }, { 0x4a4, 0 }, { 0x4d0, 0 }, { 0x4d9, 0 }, { 0x4da, 0 }, { 0x4a6, 0 }, { 0x938, 0 }, { 0x939, 0 }, { 0x4d8, 0 }, { 0x4d0, 0 }, { 0x4d7, 0 }, { 0x4a5, 0 }, { 0x40d, 0 }, { 0x4a2, 0 }, }; u16 save_radio_4a4; msleep(1); /* Save */ for (i = 0; i < 6; i++) save_radio_regs[i][1] = b43_radio_read(dev, save_radio_regs[i][0]); for (i = 0; i < 14; i++) save_phy_regs[i][1] = b43_phy_read(dev, save_phy_regs[i][0]); b43_mac_suspend(dev); save_radio_4a4 = b43_radio_read(dev, 0x4a4); /* wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF); */ tx_pwr_idx = dev->phy.lcn->tx_pwr_curr_idx; /* Setup */ /* TODO: wlc_lcnphy_set_tx_pwr_by_index(pi, 127); */ b43_radio_set(dev, 0x007, 0x1); b43_radio_set(dev, 0x0ff, 0x10); b43_radio_set(dev, 0x11f, 0x4); b43_phy_mask(dev, 0x503, ~0x1); b43_phy_mask(dev, 0x503, ~0x4); b43_phy_mask(dev, 0x4a4, ~0x4000); b43_phy_mask(dev, 0x4a4, (u16) ~0x8000); b43_phy_mask(dev, 0x4d0, ~0x20); b43_phy_set(dev, 0x4a5, 0xff); b43_phy_maskset(dev, 0x4a5, ~0x7000, 0x5000); b43_phy_mask(dev, 0x4a5, ~0x700); b43_phy_maskset(dev, 0x40d, ~0xff, 64); b43_phy_maskset(dev, 0x40d, ~0x700, 0x600); b43_phy_maskset(dev, 0x4a2, ~0xff, 64); b43_phy_maskset(dev, 0x4a2, ~0x700, 0x600); b43_phy_maskset(dev, 0x4d9, ~0x70, 0x20); b43_phy_maskset(dev, 0x4d9, ~0x700, 0x300); b43_phy_maskset(dev, 0x4d9, ~0x7000, 0x1000); b43_phy_mask(dev, 0x4da, ~0x1000); b43_phy_set(dev, 0x4da, 0x2000); b43_phy_set(dev, 0x4a6, 0x8000); b43_radio_write(dev, 0x025, 0xc); b43_radio_set(dev, 0x005, 0x8); b43_phy_set(dev, 0x938, 0x4); b43_phy_set(dev, 0x939, 0x4); b43_phy_set(dev, 0x4a4, 0x1000); /* FIXME: don't hardcode */ b43_lcntab_write(dev, B43_LCNTAB16(0x8, 0x6), 0x640); switch (sense_type) { case B43_SENSE_TEMP: b43_phy_set(dev, 0x4d7, 0x8); b43_phy_maskset(dev, 0x4d7, ~0x7000, 0x1000); auxpga_vmidcourse = 8; auxpga_vmidfine = 0x4; auxpga_gain = 2; b43_radio_set(dev, 0x082, 0x20); break; case B43_SENSE_VBAT: b43_phy_set(dev, 0x4d7, 0x8); b43_phy_maskset(dev, 0x4d7, ~0x7000, 0x3000); auxpga_vmidcourse = 7; auxpga_vmidfine = 0xa; auxpga_gain = 2; break; } auxpga_vmid = (0x200 | (auxpga_vmidcourse << 4) | auxpga_vmidfine); b43_phy_set(dev, 0x4d8, 0x1); b43_phy_maskset(dev, 0x4d8, ~(0x3ff << 2), auxpga_vmid << 2); b43_phy_set(dev, 0x4d8, 0x2); b43_phy_maskset(dev, 0x4d8, ~(0x7 << 12), auxpga_gain << 12); b43_phy_set(dev, 0x4d0, 0x20); b43_radio_write(dev, 0x112, 0x6); /* TODO: dummy transmission? */ /* Wait if not done */ if (!(b43_phy_read(dev, 0x476) & 0x8000)) udelay(10); /* Restore */ for (i = 0; i < 6; i++) b43_radio_write(dev, save_radio_regs[i][0], save_radio_regs[i][1]); for (i = 0; i < 14; i++) b43_phy_write(dev, save_phy_regs[i][0], save_phy_regs[i][1]); /* TODO: wlc_lcnphy_set_tx_pwr_by_index(tx_pwr_idx) */ b43_radio_write(dev, 0x4a4, save_radio_4a4); b43_mac_enable(dev); msleep(1); }
static void b43_wa_altagc(struct b43_wldev *dev) { struct b43_phy *phy = &dev->phy; if (phy->rev == 1) { b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1_R1, 0, 254); b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1_R1, 1, 13); b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1_R1, 2, 19); b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1_R1, 3, 25); b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC2, 0, 0x2710); b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC2, 1, 0x9B83); b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC2, 2, 0x9B83); b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC2, 3, 0x0F8D); b43_phy_write(dev, B43_PHY_LMS, 4); } else { b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 0, 254); b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 1, 13); b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 2, 19); b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 3, 25); } b43_phy_maskset(dev, B43_PHY_CCKSHIFTBITS_WA, 0x00FF, 0x5700); b43_phy_maskset(dev, B43_PHY_OFDM(0x1A), ~0x007F, 0x000F); b43_phy_maskset(dev, B43_PHY_OFDM(0x1A), ~0x3F80, 0x2B80); b43_phy_maskset(dev, B43_PHY_ANTWRSETT, 0xF0FF, 0x0300); b43_radio_set(dev, 0x7A, 0x0008); b43_phy_maskset(dev, B43_PHY_N1P1GAIN, ~0x000F, 0x0008); b43_phy_maskset(dev, B43_PHY_P1P2GAIN, ~0x0F00, 0x0600); b43_phy_maskset(dev, B43_PHY_N1N2GAIN, ~0x0F00, 0x0700); b43_phy_maskset(dev, B43_PHY_N1P1GAIN, ~0x0F00, 0x0100); if (phy->rev == 1) { b43_phy_maskset(dev, B43_PHY_N1N2GAIN, ~0x000F, 0x0007); } b43_phy_maskset(dev, B43_PHY_OFDM(0x88), ~0x00FF, 0x001C); b43_phy_maskset(dev, B43_PHY_OFDM(0x88), ~0x3F00, 0x0200); b43_phy_maskset(dev, B43_PHY_OFDM(0x96), ~0x00FF, 0x001C); b43_phy_maskset(dev, B43_PHY_OFDM(0x89), ~0x00FF, 0x0020); b43_phy_maskset(dev, B43_PHY_OFDM(0x89), ~0x3F00, 0x0200); b43_phy_maskset(dev, B43_PHY_OFDM(0x82), ~0x00FF, 0x002E); b43_phy_maskset(dev, B43_PHY_OFDM(0x96), 0x00FF, 0x1A00); b43_phy_maskset(dev, B43_PHY_OFDM(0x81), ~0x00FF, 0x0028); b43_phy_maskset(dev, B43_PHY_OFDM(0x81), 0x00FF, 0x2C00); if (phy->rev == 1) { b43_phy_write(dev, B43_PHY_PEAK_COUNT, 0x092B); b43_phy_maskset(dev, B43_PHY_OFDM(0x1B), ~0x001E, 0x0002); } else { b43_phy_mask(dev, B43_PHY_OFDM(0x1B), ~0x001E); b43_phy_write(dev, B43_PHY_OFDM(0x1F), 0x287A); b43_phy_maskset(dev, B43_PHY_LPFGAINCTL, ~0x000F, 0x0004); if (phy->rev >= 6) { b43_phy_write(dev, B43_PHY_OFDM(0x22), 0x287A); b43_phy_maskset(dev, B43_PHY_LPFGAINCTL, 0x0FFF, 0x3000); } } b43_phy_maskset(dev, B43_PHY_DIVSRCHIDX, 0x8080, 0x7874); b43_phy_write(dev, B43_PHY_OFDM(0x8E), 0x1C00); if (phy->rev == 1) { b43_phy_maskset(dev, B43_PHY_DIVP1P2GAIN, ~0x0F00, 0x0600); b43_phy_write(dev, B43_PHY_OFDM(0x8B), 0x005E); b43_phy_maskset(dev, B43_PHY_ANTWRSETT, ~0x00FF, 0x001E); b43_phy_write(dev, B43_PHY_OFDM(0x8D), 0x0002); b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3_R1, 0, 0); b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3_R1, 1, 7); b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3_R1, 2, 16); b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3_R1, 3, 28); } else { b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3, 0, 0); b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3, 1, 7); b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3, 2, 16); b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3, 3, 28); } if (phy->rev >= 6) { b43_phy_mask(dev, B43_PHY_OFDM(0x26), ~0x0003); b43_phy_mask(dev, B43_PHY_OFDM(0x26), ~0x1000); } b43_phy_read(dev, B43_PHY_VERSION_OFDM); /* Dummy read */ }
static int b43_phy_ht_op_init(struct b43_wldev *dev) { struct b43_phy_ht *phy_ht = dev->phy.ht; u16 tmp; u16 clip_state[3]; bool saved_tx_pwr_ctl; if (dev->dev->bus_type != B43_BUS_BCMA) { b43err(dev->wl, "HT-PHY is supported only on BCMA bus!\n"); return -EOPNOTSUPP; } b43_phy_ht_tables_init(dev); b43_phy_mask(dev, 0x0be, ~0x2); b43_phy_set(dev, 0x23f, 0x7ff); b43_phy_set(dev, 0x240, 0x7ff); b43_phy_set(dev, 0x241, 0x7ff); b43_phy_ht_zero_extg(dev); b43_phy_mask(dev, B43_PHY_EXTG(0), ~0x3); b43_phy_write(dev, B43_PHY_HT_AFE_C1_OVER, 0); b43_phy_write(dev, B43_PHY_HT_AFE_C2_OVER, 0); b43_phy_write(dev, B43_PHY_HT_AFE_C3_OVER, 0); b43_phy_write(dev, B43_PHY_EXTG(0x103), 0x20); b43_phy_write(dev, B43_PHY_EXTG(0x101), 0x20); b43_phy_write(dev, 0x20d, 0xb8); b43_phy_write(dev, B43_PHY_EXTG(0x14f), 0xc8); b43_phy_write(dev, 0x70, 0x50); b43_phy_write(dev, 0x1ff, 0x30); if (0) /* TODO: condition */ ; /* TODO: PHY op on reg 0x217 */ if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) b43_phy_ht_classifier(dev, B43_PHY_HT_CLASS_CTL_CCK_EN, 0); else b43_phy_ht_classifier(dev, B43_PHY_HT_CLASS_CTL_CCK_EN, B43_PHY_HT_CLASS_CTL_CCK_EN); b43_phy_set(dev, 0xb1, 0x91); b43_phy_write(dev, 0x32f, 0x0003); b43_phy_write(dev, 0x077, 0x0010); b43_phy_write(dev, 0x0b4, 0x0258); b43_phy_mask(dev, 0x17e, ~0x4000); b43_phy_write(dev, 0x0b9, 0x0072); b43_httab_write_few(dev, B43_HTTAB16(7, 0x14e), 2, 0x010f, 0x010f); b43_httab_write_few(dev, B43_HTTAB16(7, 0x15e), 2, 0x010f, 0x010f); b43_httab_write_few(dev, B43_HTTAB16(7, 0x16e), 2, 0x010f, 0x010f); b43_phy_ht_afe_unk1(dev); b43_httab_write_few(dev, B43_HTTAB16(7, 0x130), 9, 0x777, 0x111, 0x111, 0x777, 0x111, 0x111, 0x777, 0x111, 0x111); b43_httab_write(dev, B43_HTTAB16(7, 0x120), 0x0777); b43_httab_write(dev, B43_HTTAB16(7, 0x124), 0x0777); b43_httab_write(dev, B43_HTTAB16(8, 0x00), 0x02); b43_httab_write(dev, B43_HTTAB16(8, 0x10), 0x02); b43_httab_write(dev, B43_HTTAB16(8, 0x20), 0x02); b43_httab_write_few(dev, B43_HTTAB16(8, 0x08), 4, 0x8e, 0x96, 0x96, 0x96); b43_httab_write_few(dev, B43_HTTAB16(8, 0x18), 4, 0x8f, 0x9f, 0x9f, 0x9f); b43_httab_write_few(dev, B43_HTTAB16(8, 0x28), 4, 0x8f, 0x9f, 0x9f, 0x9f); b43_httab_write_few(dev, B43_HTTAB16(8, 0x0c), 4, 0x2, 0x2, 0x2, 0x2); b43_httab_write_few(dev, B43_HTTAB16(8, 0x1c), 4, 0x2, 0x2, 0x2, 0x2); b43_httab_write_few(dev, B43_HTTAB16(8, 0x2c), 4, 0x2, 0x2, 0x2, 0x2); b43_phy_maskset(dev, 0x0280, 0xff00, 0x3e); b43_phy_maskset(dev, 0x0283, 0xff00, 0x3e); b43_phy_maskset(dev, B43_PHY_OFDM(0x0141), 0xff00, 0x46); b43_phy_maskset(dev, 0x0283, 0xff00, 0x40); b43_httab_write_few(dev, B43_HTTAB16(00, 0x8), 4, 0x09, 0x0e, 0x13, 0x18); b43_httab_write_few(dev, B43_HTTAB16(01, 0x8), 4, 0x09, 0x0e, 0x13, 0x18); /* TODO: Did wl mean 2 instead of 40? */ b43_httab_write_few(dev, B43_HTTAB16(40, 0x8), 4, 0x09, 0x0e, 0x13, 0x18); b43_phy_maskset(dev, B43_PHY_OFDM(0x24), 0x3f, 0xd); b43_phy_maskset(dev, B43_PHY_OFDM(0x64), 0x3f, 0xd); b43_phy_maskset(dev, B43_PHY_OFDM(0xa4), 0x3f, 0xd); b43_phy_set(dev, B43_PHY_EXTG(0x060), 0x1); b43_phy_set(dev, B43_PHY_EXTG(0x064), 0x1); b43_phy_set(dev, B43_PHY_EXTG(0x080), 0x1); b43_phy_set(dev, B43_PHY_EXTG(0x084), 0x1); /* Copy some tables entries */ tmp = b43_httab_read(dev, B43_HTTAB16(7, 0x144)); b43_httab_write(dev, B43_HTTAB16(7, 0x14a), tmp); tmp = b43_httab_read(dev, B43_HTTAB16(7, 0x154)); b43_httab_write(dev, B43_HTTAB16(7, 0x15a), tmp); tmp = b43_httab_read(dev, B43_HTTAB16(7, 0x164)); b43_httab_write(dev, B43_HTTAB16(7, 0x16a), tmp); /* Reset CCA */ b43_phy_force_clock(dev, true); tmp = b43_phy_read(dev, B43_PHY_HT_BBCFG); b43_phy_write(dev, B43_PHY_HT_BBCFG, tmp | B43_PHY_HT_BBCFG_RSTCCA); b43_phy_write(dev, B43_PHY_HT_BBCFG, tmp & ~B43_PHY_HT_BBCFG_RSTCCA); b43_phy_force_clock(dev, false); b43_mac_phy_clock_set(dev, true); b43_phy_ht_pa_override(dev, false); b43_phy_ht_force_rf_sequence(dev, B43_PHY_HT_RF_SEQ_TRIG_RX2TX); b43_phy_ht_force_rf_sequence(dev, B43_PHY_HT_RF_SEQ_TRIG_RST2RX); b43_phy_ht_pa_override(dev, true); /* TODO: Should we restore it? Or store it in global PHY info? */ b43_phy_ht_classifier(dev, 0, 0); b43_phy_ht_read_clip_detection(dev, clip_state); if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) b43_phy_ht_bphy_init(dev); b43_httab_write_bulk(dev, B43_HTTAB32(0x1a, 0xc0), B43_HTTAB_1A_C0_LATE_SIZE, b43_httab_0x1a_0xc0_late); saved_tx_pwr_ctl = phy_ht->tx_pwr_ctl; b43_phy_ht_tx_power_fix(dev); b43_phy_ht_tx_power_ctl(dev, false); b43_phy_ht_tx_power_ctl_idle_tssi(dev); b43_phy_ht_tx_power_ctl_setup(dev); b43_phy_ht_tx_power_ctl(dev, saved_tx_pwr_ctl); return 0; }
static void b43_nphy_workarounds(struct b43_wldev *dev) { struct b43_phy *phy = &dev->phy; unsigned int i; b43_phy_set(dev, B43_NPHY_IQFLIP, B43_NPHY_IQFLIP_ADC1 | B43_NPHY_IQFLIP_ADC2); if (1 /* FIXME band is 2.4GHz */) { b43_phy_set(dev, B43_NPHY_CLASSCTL, B43_NPHY_CLASSCTL_CCKEN); } else { b43_phy_mask(dev, B43_NPHY_CLASSCTL, ~B43_NPHY_CLASSCTL_CCKEN); } b43_radio_set(dev, B2055_C1_TX_RF_SPARE, 0x8); b43_phy_write(dev, B43_NPHY_TXFRAMEDELAY, 8); /* Fixup some tables */ b43_ntab_write(dev, B43_NTAB16(8, 0x00), 0xA); b43_ntab_write(dev, B43_NTAB16(8, 0x10), 0xA); b43_ntab_write(dev, B43_NTAB16(8, 0x02), 0xCDAA); b43_ntab_write(dev, B43_NTAB16(8, 0x12), 0xCDAA); b43_ntab_write(dev, B43_NTAB16(8, 0x08), 0); b43_ntab_write(dev, B43_NTAB16(8, 0x18), 0); b43_ntab_write(dev, B43_NTAB16(8, 0x07), 0x7AAB); b43_ntab_write(dev, B43_NTAB16(8, 0x17), 0x7AAB); b43_ntab_write(dev, B43_NTAB16(8, 0x06), 0x800); b43_ntab_write(dev, B43_NTAB16(8, 0x16), 0x800); b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO1, 0x2D8); b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP1, 0x301); b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO2, 0x2D8); b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2, 0x301); //TODO set RF sequence /* Set narrowband clip threshold */ b43_phy_write(dev, B43_NPHY_C1_NBCLIPTHRES, 66); b43_phy_write(dev, B43_NPHY_C2_NBCLIPTHRES, 66); /* Set wideband clip 2 threshold */ b43_phy_maskset(dev, B43_NPHY_C1_CLIPWBTHRES, ~B43_NPHY_C1_CLIPWBTHRES_CLIP2, 21 << B43_NPHY_C1_CLIPWBTHRES_CLIP2_SHIFT); b43_phy_maskset(dev, B43_NPHY_C2_CLIPWBTHRES, ~B43_NPHY_C2_CLIPWBTHRES_CLIP2, 21 << B43_NPHY_C2_CLIPWBTHRES_CLIP2_SHIFT); /* Set Clip 2 detect */ b43_phy_set(dev, B43_NPHY_C1_CGAINI, B43_NPHY_C1_CGAINI_CL2DETECT); b43_phy_set(dev, B43_NPHY_C2_CGAINI, B43_NPHY_C2_CGAINI_CL2DETECT); if (0 /*FIXME*/) { /* Set dwell lengths */ b43_phy_write(dev, B43_NPHY_CLIP1_NBDWELL_LEN, 43); b43_phy_write(dev, B43_NPHY_CLIP2_NBDWELL_LEN, 43); b43_phy_write(dev, B43_NPHY_W1CLIP1_DWELL_LEN, 9); b43_phy_write(dev, B43_NPHY_W1CLIP2_DWELL_LEN, 9); /* Set gain backoff */ b43_phy_maskset(dev, B43_NPHY_C1_CGAINI, ~B43_NPHY_C1_CGAINI_GAINBKOFF, 1 << B43_NPHY_C1_CGAINI_GAINBKOFF_SHIFT); b43_phy_maskset(dev, B43_NPHY_C2_CGAINI, ~B43_NPHY_C2_CGAINI_GAINBKOFF, 1 << B43_NPHY_C2_CGAINI_GAINBKOFF_SHIFT); /* Set HPVGA2 index */ b43_phy_maskset(dev, B43_NPHY_C1_INITGAIN, ~B43_NPHY_C1_INITGAIN_HPVGA2, 6 << B43_NPHY_C1_INITGAIN_HPVGA2_SHIFT); b43_phy_maskset(dev, B43_NPHY_C2_INITGAIN, ~B43_NPHY_C2_INITGAIN_HPVGA2, 6 << B43_NPHY_C2_INITGAIN_HPVGA2_SHIFT); //FIXME verify that the specs really mean to use autoinc here. for (i = 0; i < 3; i++) b43_ntab_write(dev, B43_NTAB16(7, 0x106) + i, 0x673); } /* Set minimum gain value */ b43_phy_maskset(dev, B43_NPHY_C1_MINMAX_GAIN, ~B43_NPHY_C1_MINGAIN, 23 << B43_NPHY_C1_MINGAIN_SHIFT); b43_phy_maskset(dev, B43_NPHY_C2_MINMAX_GAIN, ~B43_NPHY_C2_MINGAIN, 23 << B43_NPHY_C2_MINGAIN_SHIFT); if (phy->rev < 2) { b43_phy_mask(dev, B43_NPHY_SCRAM_SIGCTL, ~B43_NPHY_SCRAM_SIGCTL_SCM); } /* Set phase track alpha and beta */ b43_phy_write(dev, B43_NPHY_PHASETR_A0, 0x125); b43_phy_write(dev, B43_NPHY_PHASETR_A1, 0x1B3); b43_phy_write(dev, B43_NPHY_PHASETR_A2, 0x105); b43_phy_write(dev, B43_NPHY_PHASETR_B0, 0x16E); b43_phy_write(dev, B43_NPHY_PHASETR_B1, 0xCD); b43_phy_write(dev, B43_NPHY_PHASETR_B2, 0x20); }