Changeset View
Changeset View
Standalone View
Standalone View
sys/gnu/dev/bwn/phy_n/if_bwn_phy_n_core.c
Show First 20 Lines • Show All 63 Lines • ▼ Show 20 Lines | |||||
#include <dev/pci/pcireg.h> | #include <dev/pci/pcireg.h> | ||||
#include <net80211/ieee80211_var.h> | #include <net80211/ieee80211_var.h> | ||||
#include <net80211/ieee80211_radiotap.h> | #include <net80211/ieee80211_radiotap.h> | ||||
#include <net80211/ieee80211_regdomain.h> | #include <net80211/ieee80211_regdomain.h> | ||||
#include <net80211/ieee80211_phy.h> | #include <net80211/ieee80211_phy.h> | ||||
#include <net80211/ieee80211_ratectl.h> | #include <net80211/ieee80211_ratectl.h> | ||||
#include <dev/bhnd/bhnd.h> | |||||
#include <dev/bhnd/bhnd_ids.h> | |||||
#include <dev/bhnd/cores/pmu/bhnd_pmu.h> | |||||
#include <dev/bhnd/cores/chipc/chipc.h> | |||||
#include <dev/bwn/if_bwnreg.h> | #include <dev/bwn/if_bwnreg.h> | ||||
#include <dev/bwn/if_bwnvar.h> | #include <dev/bwn/if_bwnvar.h> | ||||
#include <dev/bwn/if_bwn_misc.h> | #include <dev/bwn/if_bwn_misc.h> | ||||
#include <dev/bwn/if_bwn_util.h> | #include <dev/bwn/if_bwn_util.h> | ||||
#include <dev/bwn/if_bwn_debug.h> | #include <dev/bwn/if_bwn_debug.h> | ||||
#include <dev/bwn/if_bwn_phy_common.h> | #include <dev/bwn/if_bwn_phy_common.h> | ||||
#include <dev/bwn/if_bwn_chipid.h> | |||||
#include <dev/bwn/if_bwn_cordic.h> | #include <dev/bwn/if_bwn_cordic.h> | ||||
#include <gnu/dev/bwn/phy_n/if_bwn_phy_n_regs.h> | #include <gnu/dev/bwn/phy_n/if_bwn_phy_n_regs.h> | ||||
#include <gnu/dev/bwn/phy_n/if_bwn_phy_n_ppr.h> | #include <gnu/dev/bwn/phy_n/if_bwn_phy_n_ppr.h> | ||||
#include <gnu/dev/bwn/phy_n/if_bwn_phy_n_sprom.h> | |||||
#include <gnu/dev/bwn/phy_n/if_bwn_phy_n_tables.h> | #include <gnu/dev/bwn/phy_n/if_bwn_phy_n_tables.h> | ||||
#include <gnu/dev/bwn/phy_n/if_bwn_radio_2055.h> | #include <gnu/dev/bwn/phy_n/if_bwn_radio_2055.h> | ||||
#include <gnu/dev/bwn/phy_n/if_bwn_radio_2056.h> | #include <gnu/dev/bwn/phy_n/if_bwn_radio_2056.h> | ||||
#include <gnu/dev/bwn/phy_n/if_bwn_radio_2057.h> | #include <gnu/dev/bwn/phy_n/if_bwn_radio_2057.h> | ||||
#include <gnu/dev/bwn/phy_n/if_bwn_phy_n_core.h> | #include <gnu/dev/bwn/phy_n/if_bwn_phy_n_core.h> | ||||
#include "bhnd_nvram_map.h" | |||||
struct bwn_nphy_txgains { | struct bwn_nphy_txgains { | ||||
uint16_t tx_lpf[2]; | uint16_t tx_lpf[2]; | ||||
uint16_t txgm[2]; | uint16_t txgm[2]; | ||||
uint16_t pga[2]; | uint16_t pga[2]; | ||||
uint16_t pad[2]; | uint16_t pad[2]; | ||||
uint16_t ipa[2]; | uint16_t ipa[2]; | ||||
}; | }; | ||||
▲ Show 20 Lines • Show All 488 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/classifier */ | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/classifier */ | ||||
static uint16_t bwn_nphy_classifier(struct bwn_mac *mac, uint16_t mask, uint16_t val) | static uint16_t bwn_nphy_classifier(struct bwn_mac *mac, uint16_t mask, uint16_t val) | ||||
{ | { | ||||
struct bwn_softc *sc = mac->mac_sc; | struct bwn_softc *sc = mac->mac_sc; | ||||
uint16_t tmp; | uint16_t tmp; | ||||
if (siba_get_revid(sc->sc_dev) == 16) | if (bhnd_get_hwrev(sc->sc_dev) == 16) | ||||
bwn_mac_suspend(mac); | bwn_mac_suspend(mac); | ||||
tmp = BWN_PHY_READ(mac, BWN_NPHY_CLASSCTL); | tmp = BWN_PHY_READ(mac, BWN_NPHY_CLASSCTL); | ||||
tmp &= (BWN_NPHY_CLASSCTL_CCKEN | BWN_NPHY_CLASSCTL_OFDMEN | | tmp &= (BWN_NPHY_CLASSCTL_CCKEN | BWN_NPHY_CLASSCTL_OFDMEN | | ||||
BWN_NPHY_CLASSCTL_WAITEDEN); | BWN_NPHY_CLASSCTL_WAITEDEN); | ||||
tmp &= ~mask; | tmp &= ~mask; | ||||
tmp |= (val & mask); | tmp |= (val & mask); | ||||
BWN_PHY_SETMASK(mac, BWN_NPHY_CLASSCTL, 0xFFF8, tmp); | BWN_PHY_SETMASK(mac, BWN_NPHY_CLASSCTL, 0xFFF8, tmp); | ||||
if (siba_get_revid(sc->sc_dev) == 16) | if (bhnd_get_hwrev(sc->sc_dev) == 16) | ||||
bwn_mac_enable(mac); | bwn_mac_enable(mac); | ||||
return tmp; | return tmp; | ||||
} | } | ||||
/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CCA */ | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CCA */ | ||||
static void bwn_nphy_reset_cca(struct bwn_mac *mac) | static void bwn_nphy_reset_cca(struct bwn_mac *mac) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 615 Lines • ▼ Show 20 Lines | static void bwn_radio_2056_setup(struct bwn_mac *mac, | ||||
if (mac->mac_phy.rev < 3) { | if (mac->mac_phy.rev < 3) { | ||||
BWN_ERRPRINTF(mac->mac_sc, "%s: phy rev %d out of range\n", | BWN_ERRPRINTF(mac->mac_sc, "%s: phy rev %d out of range\n", | ||||
__func__, | __func__, | ||||
mac->mac_phy.rev); | mac->mac_phy.rev); | ||||
} | } | ||||
is_pkg_fab_smic = | is_pkg_fab_smic = | ||||
((siba_get_chipid(sc->sc_dev) == BCMA_CHIP_ID_BCM43224 || | ((sc->sc_cid.chip_id == BHND_CHIPID_BCM43224 || | ||||
siba_get_chipid(sc->sc_dev) == BCMA_CHIP_ID_BCM43225 || | sc->sc_cid.chip_id == BHND_CHIPID_BCM43225 || | ||||
siba_get_chipid(sc->sc_dev) == BCMA_CHIP_ID_BCM43421) && | sc->sc_cid.chip_id == BHND_CHIPID_BCM43421) && | ||||
siba_get_chippkg(sc->sc_dev) == BCMA_PKG_ID_BCM43224_FAB_SMIC); | sc->sc_cid.chip_pkg == BHND_PKGID_BCM43224_FAB_SMIC); | ||||
bwn_chantab_radio_2056_upload(mac, e); | bwn_chantab_radio_2056_upload(mac, e); | ||||
b2056_upload_syn_pll_cp2(mac, band == BWN_BAND_5G); | b2056_upload_syn_pll_cp2(mac, band == BWN_BAND_5G); | ||||
if (siba_sprom_get_bf2_lo(sc->sc_dev) & BWN_BFL2_GPLL_WAR && | if (sc->sc_board_info.board_flags2 & BHND_BFL2_GPLL_WAR && | ||||
bwn_current_band(mac) == BWN_BAND_2G) { | bwn_current_band(mac) == BWN_BAND_2G) { | ||||
BWN_RF_WRITE(mac, B2056_SYN_PLL_LOOPFILTER1, 0x1F); | BWN_RF_WRITE(mac, B2056_SYN_PLL_LOOPFILTER1, 0x1F); | ||||
BWN_RF_WRITE(mac, B2056_SYN_PLL_LOOPFILTER2, 0x1F); | BWN_RF_WRITE(mac, B2056_SYN_PLL_LOOPFILTER2, 0x1F); | ||||
if (siba_get_chipid(sc->sc_dev) == BCMA_CHIP_ID_BCM4716 || | if (sc->sc_cid.chip_id == BHND_CHIPID_BCM4716 || | ||||
siba_get_chipid(sc->sc_dev) == BCMA_CHIP_ID_BCM47162) { | sc->sc_cid.chip_id == BHND_CHIPID_BCM47162) { | ||||
BWN_RF_WRITE(mac, B2056_SYN_PLL_LOOPFILTER4, 0x14); | BWN_RF_WRITE(mac, B2056_SYN_PLL_LOOPFILTER4, 0x14); | ||||
BWN_RF_WRITE(mac, B2056_SYN_PLL_CP2, 0); | BWN_RF_WRITE(mac, B2056_SYN_PLL_CP2, 0); | ||||
} else { | } else { | ||||
BWN_RF_WRITE(mac, B2056_SYN_PLL_LOOPFILTER4, 0x0B); | BWN_RF_WRITE(mac, B2056_SYN_PLL_LOOPFILTER4, 0x0B); | ||||
BWN_RF_WRITE(mac, B2056_SYN_PLL_CP2, 0x14); | BWN_RF_WRITE(mac, B2056_SYN_PLL_CP2, 0x14); | ||||
} | } | ||||
} | } | ||||
if (siba_sprom_get_bf2_hi(sc->sc_dev) & BWN_BFH2_GPLL_WAR2 && | if (sc->sc_board_info.board_flags2 & BHND_BFL2_GPLL_WAR && | ||||
bwn_current_band(mac) == BWN_BAND_2G) { | bwn_current_band(mac) == BWN_BAND_2G) { | ||||
BWN_RF_WRITE(mac, B2056_SYN_PLL_LOOPFILTER1, 0x1f); | BWN_RF_WRITE(mac, B2056_SYN_PLL_LOOPFILTER1, 0x1f); | ||||
BWN_RF_WRITE(mac, B2056_SYN_PLL_LOOPFILTER2, 0x1f); | BWN_RF_WRITE(mac, B2056_SYN_PLL_LOOPFILTER2, 0x1f); | ||||
BWN_RF_WRITE(mac, B2056_SYN_PLL_LOOPFILTER4, 0x0b); | BWN_RF_WRITE(mac, B2056_SYN_PLL_LOOPFILTER4, 0x0b); | ||||
BWN_RF_WRITE(mac, B2056_SYN_PLL_CP2, 0x20); | BWN_RF_WRITE(mac, B2056_SYN_PLL_CP2, 0x20); | ||||
} | } | ||||
if (siba_sprom_get_bf2_lo(sc->sc_dev) & BWN_BFL2_APLL_WAR && | if (sc->sc_board_info.board_flags2 & BHND_BFL2_APLL_WAR && | ||||
bwn_current_band(mac) == BWN_BAND_5G) { | bwn_current_band(mac) == BWN_BAND_5G) { | ||||
BWN_RF_WRITE(mac, B2056_SYN_PLL_LOOPFILTER1, 0x1F); | BWN_RF_WRITE(mac, B2056_SYN_PLL_LOOPFILTER1, 0x1F); | ||||
BWN_RF_WRITE(mac, B2056_SYN_PLL_LOOPFILTER2, 0x1F); | BWN_RF_WRITE(mac, B2056_SYN_PLL_LOOPFILTER2, 0x1F); | ||||
BWN_RF_WRITE(mac, B2056_SYN_PLL_LOOPFILTER4, 0x05); | BWN_RF_WRITE(mac, B2056_SYN_PLL_LOOPFILTER4, 0x05); | ||||
BWN_RF_WRITE(mac, B2056_SYN_PLL_CP2, 0x0C); | BWN_RF_WRITE(mac, B2056_SYN_PLL_CP2, 0x0C); | ||||
} | } | ||||
if (mac->mac_phy.phy_n->ipa2g_on && band == BWN_BAND_2G) { | if (mac->mac_phy.phy_n->ipa2g_on && band == BWN_BAND_2G) { | ||||
for (i = 0; i < 2; i++) { | for (i = 0; i < 2; i++) { | ||||
offset = i ? B2056_TX1 : B2056_TX0; | offset = i ? B2056_TX1 : B2056_TX0; | ||||
if (mac->mac_phy.rev >= 5) { | if (mac->mac_phy.rev >= 5) { | ||||
BWN_RF_WRITE(mac, | BWN_RF_WRITE(mac, | ||||
offset | B2056_TX_PADG_IDAC, 0xcc); | offset | B2056_TX_PADG_IDAC, 0xcc); | ||||
if (siba_get_chipid(sc->sc_dev) == BCMA_CHIP_ID_BCM4716 || | if (sc->sc_cid.chip_id == BHND_CHIPID_BCM4716 || | ||||
siba_get_chipid(sc->sc_dev) == BCMA_CHIP_ID_BCM47162) { | sc->sc_cid.chip_id == BHND_CHIPID_BCM47162) { | ||||
bias = 0x40; | bias = 0x40; | ||||
cbias = 0x45; | cbias = 0x45; | ||||
pag_boost = 0x5; | pag_boost = 0x5; | ||||
pgag_boost = 0x33; | pgag_boost = 0x33; | ||||
mixg_boost = 0x55; | mixg_boost = 0x55; | ||||
} else { | } else { | ||||
bias = 0x25; | bias = 0x25; | ||||
cbias = 0x20; | cbias = 0x20; | ||||
▲ Show 20 Lines • Show All 258 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
static void bwn_radio_init2055_post(struct bwn_mac *mac) | static void bwn_radio_init2055_post(struct bwn_mac *mac) | ||||
{ | { | ||||
struct bwn_softc *sc = mac->mac_sc; | struct bwn_softc *sc = mac->mac_sc; | ||||
struct bwn_phy_n *nphy = mac->mac_phy.phy_n; | struct bwn_phy_n *nphy = mac->mac_phy.phy_n; | ||||
bool workaround = false; | bool workaround = false; | ||||
if (siba_get_revid(sc->sc_dev) < 4) | if (bhnd_get_hwrev(sc->sc_dev) < 4) | ||||
workaround = | workaround = | ||||
(siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM) | (sc->sc_board_info.board_vendor != PCI_VENDOR_BROADCOM) | ||||
&& (siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BCM4321) | && (sc->sc_board_info.board_type == BHND_BOARD_BCM4321CB2) | ||||
&& (siba_sprom_get_brev(sc->sc_dev) >= 0x41); | && (sc->sc_board_info.board_rev >= 0x41); | ||||
else | else | ||||
workaround = | workaround = | ||||
!(siba_sprom_get_bf2_lo(sc->sc_dev) & BWN_BFL2_RXBB_INT_REG_DIS); | !(sc->sc_board_info.board_flags2 & BHND_BFL2_RXBB_INT_REG_DIS); | ||||
BWN_RF_MASK(mac, B2055_MASTER1, 0xFFF3); | BWN_RF_MASK(mac, B2055_MASTER1, 0xFFF3); | ||||
if (workaround) { | if (workaround) { | ||||
BWN_RF_MASK(mac, B2055_C1_RX_BB_REG, 0x7F); | BWN_RF_MASK(mac, B2055_C1_RX_BB_REG, 0x7F); | ||||
BWN_RF_MASK(mac, B2055_C2_RX_BB_REG, 0x7F); | BWN_RF_MASK(mac, B2055_C2_RX_BB_REG, 0x7F); | ||||
} | } | ||||
BWN_RF_SETMASK(mac, B2055_RRCCAL_NOPTSEL, 0xFFC0, 0x2C); | BWN_RF_SETMASK(mac, B2055_RRCCAL_NOPTSEL, 0xFFC0, 0x2C); | ||||
BWN_RF_WRITE(mac, B2055_CAL_MISC, 0x3C); | BWN_RF_WRITE(mac, B2055_CAL_MISC, 0x3C); | ||||
▲ Show 20 Lines • Show All 1,044 Lines • ▼ Show 20 Lines | static void bwn_nphy_gain_ctl_workarounds_rev3(struct bwn_mac *mac) | ||||
uint16_t rssi_gain; | uint16_t rssi_gain; | ||||
struct bwn_nphy_gain_ctl_workaround_entry *e; | struct bwn_nphy_gain_ctl_workaround_entry *e; | ||||
uint8_t lpf_gain[6] = { 0x00, 0x06, 0x0C, 0x12, 0x12, 0x12 }; | uint8_t lpf_gain[6] = { 0x00, 0x06, 0x0C, 0x12, 0x12, 0x12 }; | ||||
uint8_t lpf_bits[6] = { 0, 1, 2, 3, 3, 3 }; | uint8_t lpf_bits[6] = { 0, 1, 2, 3, 3, 3 }; | ||||
/* Prepare values */ | /* Prepare values */ | ||||
ghz5 = BWN_PHY_READ(mac, BWN_NPHY_BANDCTL) | ghz5 = BWN_PHY_READ(mac, BWN_NPHY_BANDCTL) | ||||
& BWN_NPHY_BANDCTL_5GHZ; | & BWN_NPHY_BANDCTL_5GHZ; | ||||
ext_lna = ghz5 ? siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_EXTLNA_5GHZ : | ext_lna = ghz5 ? sc->sc_board_info.board_flags & BHND_BFL_EXTLNA_5GHZ : | ||||
siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA; | sc->sc_board_info.board_flags & BHND_BFL_EXTLNA; | ||||
e = bwn_nphy_get_gain_ctl_workaround_ent(mac, ghz5, ext_lna); | e = bwn_nphy_get_gain_ctl_workaround_ent(mac, ghz5, ext_lna); | ||||
if (ghz5 && mac->mac_phy.rev >= 5) | if (ghz5 && mac->mac_phy.rev >= 5) | ||||
rssi_gain = 0x90; | rssi_gain = 0x90; | ||||
else | else | ||||
rssi_gain = 0x50; | rssi_gain = 0x50; | ||||
BWN_PHY_SET(mac, BWN_NPHY_RXCTL, 0x0040); | BWN_PHY_SET(mac, BWN_NPHY_RXCTL, 0x0040); | ||||
▲ Show 20 Lines • Show All 175 Lines • ▼ Show 20 Lines | static void bwn_nphy_gain_ctl_workarounds(struct bwn_mac *mac) | ||||
else if (mac->mac_phy.rev >= 7) | else if (mac->mac_phy.rev >= 7) | ||||
bwn_nphy_gain_ctl_workarounds_rev7(mac); | bwn_nphy_gain_ctl_workarounds_rev7(mac); | ||||
else if (mac->mac_phy.rev >= 3) | else if (mac->mac_phy.rev >= 3) | ||||
bwn_nphy_gain_ctl_workarounds_rev3(mac); | bwn_nphy_gain_ctl_workarounds_rev3(mac); | ||||
else | else | ||||
bwn_nphy_gain_ctl_workarounds_rev1_2(mac); | bwn_nphy_gain_ctl_workarounds_rev1_2(mac); | ||||
} | } | ||||
static void bwn_nphy_workarounds_rev7plus(struct bwn_mac *mac) | static int bwn_nphy_workarounds_rev7plus(struct bwn_mac *mac) | ||||
{ | { | ||||
struct bwn_softc *sc = mac->mac_sc; | struct bwn_softc *sc = mac->mac_sc; | ||||
struct bwn_phy *phy = &mac->mac_phy; | struct bwn_phy *phy = &mac->mac_phy; | ||||
/* TX to RX */ | /* TX to RX */ | ||||
uint8_t tx2rx_events[7] = { 4, 3, 5, 2, 1, 8, 31, }; | uint8_t tx2rx_events[7] = { 4, 3, 5, 2, 1, 8, 31, }; | ||||
uint8_t tx2rx_delays[7] = { 8, 4, 4, 4, 4, 6, 1, }; | uint8_t tx2rx_delays[7] = { 8, 4, 4, 4, 4, 6, 1, }; | ||||
/* RX to TX */ | /* RX to TX */ | ||||
▲ Show 20 Lines • Show All 245 Lines • ▼ Show 20 Lines | static int bwn_nphy_workarounds_rev7plus(struct bwn_mac *mac) | ||||
} | } | ||||
BWN_PHY_WRITE(mac, 0x32F, 0x3); | BWN_PHY_WRITE(mac, 0x32F, 0x3); | ||||
if (phy->rf_rev == 4 || phy->rf_rev == 6) | if (phy->rf_rev == 4 || phy->rf_rev == 6) | ||||
bwn_nphy_rf_ctl_override_rev7(mac, 4, 1, 3, false, 0); | bwn_nphy_rf_ctl_override_rev7(mac, 4, 1, 3, false, 0); | ||||
if (phy->rf_rev == 3 || phy->rf_rev == 4 || phy->rf_rev == 6) { | if (phy->rf_rev == 3 || phy->rf_rev == 4 || phy->rf_rev == 6) { | ||||
if (siba_sprom_get_rev(sc->sc_dev) && | if (sc->sc_board_info.board_srom_rev && | ||||
siba_sprom_get_bf2_hi(sc->sc_dev) & BWN_BFH2_IPALVLSHIFT_3P3) { | sc->sc_board_info.board_flags2 & BHND_BFL2_IPALVLSHIFT_3P3) { | ||||
BWN_RF_WRITE(mac, 0x5, 0x05); | BWN_RF_WRITE(mac, 0x5, 0x05); | ||||
BWN_RF_WRITE(mac, 0x6, 0x30); | BWN_RF_WRITE(mac, 0x6, 0x30); | ||||
BWN_RF_WRITE(mac, 0x7, 0x00); | BWN_RF_WRITE(mac, 0x7, 0x00); | ||||
BWN_RF_SET(mac, 0x4f, 0x1); | BWN_RF_SET(mac, 0x4f, 0x1); | ||||
BWN_RF_SET(mac, 0xd4, 0x1); | BWN_RF_SET(mac, 0xd4, 0x1); | ||||
bias = 0x1f; | bias = 0x1f; | ||||
conv = 0x6f; | conv = 0x6f; | ||||
filt = 0xaa; | filt = 0xaa; | ||||
▲ Show 20 Lines • Show All 163 Lines • ▼ Show 20 Lines | bwn_ntab_write_bulk(mac, BWN_NTAB16(8, 0x08), 4, | ||||
aux_adc_vmid_rev7_core0); | aux_adc_vmid_rev7_core0); | ||||
bwn_ntab_write_bulk(mac, BWN_NTAB16(8, 0x18), 4, | bwn_ntab_write_bulk(mac, BWN_NTAB16(8, 0x18), 4, | ||||
aux_adc_vmid_rev7_core1); | aux_adc_vmid_rev7_core1); | ||||
bwn_ntab_write_bulk(mac, BWN_NTAB16(8, 0x0C), 4, | bwn_ntab_write_bulk(mac, BWN_NTAB16(8, 0x0C), 4, | ||||
aux_adc_gain_rev7); | aux_adc_gain_rev7); | ||||
bwn_ntab_write_bulk(mac, BWN_NTAB16(8, 0x1C), 4, | bwn_ntab_write_bulk(mac, BWN_NTAB16(8, 0x1C), 4, | ||||
aux_adc_gain_rev7); | aux_adc_gain_rev7); | ||||
*/ | */ | ||||
return (0); | |||||
} | } | ||||
static void bwn_nphy_workarounds_rev3plus(struct bwn_mac *mac) | static int bwn_nphy_workarounds_rev3plus(struct bwn_mac *mac) | ||||
{ | { | ||||
struct bwn_softc *sc = mac->mac_sc; | struct bwn_softc *sc = mac->mac_sc; | ||||
struct bwn_phy_n *nphy = mac->mac_phy.phy_n; | struct bwn_phy_n *nphy = mac->mac_phy.phy_n; | ||||
/* TX to RX */ | /* TX to RX */ | ||||
uint8_t tx2rx_events[7] = { 0x4, 0x3, 0x5, 0x2, 0x1, 0x8, 0x1F }; | uint8_t tx2rx_events[7] = { 0x4, 0x3, 0x5, 0x2, 0x1, 0x8, 0x1F }; | ||||
uint8_t tx2rx_delays[7] = { 8, 4, 4, 4, 4, 6, 1 }; | uint8_t tx2rx_delays[7] = { 8, 4, 4, 4, 4, 6, 1 }; | ||||
/* RX to TX */ | /* RX to TX */ | ||||
Show All 14 Lines | uint16_t gains[5][4] = { | ||||
{ 0x02, 0x02, 0x02, 0x00, }, /* 0 */ | { 0x02, 0x02, 0x02, 0x00, }, /* 0 */ | ||||
{ 0x02, 0x02, 0x02, 0x02, }, /* 1 */ | { 0x02, 0x02, 0x02, 0x02, }, /* 1 */ | ||||
{ 0x02, 0x02, 0x02, 0x04, }, /* 2 */ | { 0x02, 0x02, 0x02, 0x04, }, /* 2 */ | ||||
{ 0x02, 0x02, 0x02, 0x00, }, /* 3 */ | { 0x02, 0x02, 0x02, 0x00, }, /* 3 */ | ||||
{ 0x02, 0x02, 0x02, 0x00, }, /* 4 and 5 */ | { 0x02, 0x02, 0x02, 0x00, }, /* 4 and 5 */ | ||||
}; | }; | ||||
uint16_t *vmid, *gain; | uint16_t *vmid, *gain; | ||||
const char *pdet_range_var; | |||||
uint8_t pdet_range; | uint8_t pdet_range; | ||||
uint16_t tmp16; | uint16_t tmp16; | ||||
uint32_t tmp32; | uint32_t tmp32; | ||||
int error; | |||||
BWN_PHY_WRITE(mac, BWN_NPHY_FORCEFRONT0, 0x1f8); | BWN_PHY_WRITE(mac, BWN_NPHY_FORCEFRONT0, 0x1f8); | ||||
BWN_PHY_WRITE(mac, BWN_NPHY_FORCEFRONT1, 0x1f8); | BWN_PHY_WRITE(mac, BWN_NPHY_FORCEFRONT1, 0x1f8); | ||||
tmp32 = bwn_ntab_read(mac, BWN_NTAB32(30, 0)); | tmp32 = bwn_ntab_read(mac, BWN_NTAB32(30, 0)); | ||||
tmp32 &= 0xffffff; | tmp32 &= 0xffffff; | ||||
bwn_ntab_write(mac, BWN_NTAB32(30, 0), tmp32); | bwn_ntab_write(mac, BWN_NTAB32(30, 0), tmp32); | ||||
▲ Show 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | static int bwn_nphy_workarounds_rev3plus(struct bwn_mac *mac) | ||||
} | } | ||||
bwn_nphy_gain_ctl_workarounds(mac); | bwn_nphy_gain_ctl_workarounds(mac); | ||||
bwn_ntab_write(mac, BWN_NTAB16(8, 0), 2); | bwn_ntab_write(mac, BWN_NTAB16(8, 0), 2); | ||||
bwn_ntab_write(mac, BWN_NTAB16(8, 16), 2); | bwn_ntab_write(mac, BWN_NTAB16(8, 16), 2); | ||||
if (bwn_current_band(mac) == BWN_BAND_2G) | if (bwn_current_band(mac) == BWN_BAND_2G) | ||||
pdet_range = siba_sprom_get_fem_2ghz_pdet_range(sc->sc_dev); | pdet_range_var = BHND_NVAR_PDETRANGE2G; | ||||
else | else | ||||
pdet_range = siba_sprom_get_fem_5ghz_pdet_range(sc->sc_dev); | pdet_range_var = BHND_NVAR_PDETRANGE5G; | ||||
error = bhnd_nvram_getvar_uint8(sc->sc_dev, pdet_range_var, | |||||
&pdet_range); | |||||
if (error) { | |||||
BWN_ERRPRINTF(mac->mac_sc, "Error reading PDet range %s from " | |||||
"NVRAM: %d\n", pdet_range_var, error); | |||||
return (error); | |||||
} | |||||
/* uint16_t min() */ | /* uint16_t min() */ | ||||
vmid = vmids[min(pdet_range, 4)]; | vmid = vmids[min(pdet_range, 4)]; | ||||
gain = gains[min(pdet_range, 4)]; | gain = gains[min(pdet_range, 4)]; | ||||
switch (pdet_range) { | switch (pdet_range) { | ||||
case 3: | case 3: | ||||
if (!(mac->mac_phy.rev >= 4 && | if (!(mac->mac_phy.rev >= 4 && | ||||
bwn_current_band(mac) == BWN_BAND_2G)) | bwn_current_band(mac) == BWN_BAND_2G)) | ||||
break; | break; | ||||
▲ Show 20 Lines • Show All 62 Lines • ▼ Show 20 Lines | static int bwn_nphy_workarounds_rev3plus(struct bwn_mac *mac) | ||||
BWN_RF_WRITE(mac, B2056_RX1 | B2056_RX_MIXA_LOB_BIAS, 0x88); | BWN_RF_WRITE(mac, B2056_RX1 | B2056_RX_MIXA_LOB_BIAS, 0x88); | ||||
BWN_RF_WRITE(mac, B2056_RX0 | B2056_RX_MIXA_CMFB_IDAC, 0x00); | BWN_RF_WRITE(mac, B2056_RX0 | B2056_RX_MIXA_CMFB_IDAC, 0x00); | ||||
BWN_RF_WRITE(mac, B2056_RX1 | B2056_RX_MIXA_CMFB_IDAC, 0x00); | BWN_RF_WRITE(mac, B2056_RX1 | B2056_RX_MIXA_CMFB_IDAC, 0x00); | ||||
BWN_RF_WRITE(mac, B2056_RX0 | B2056_RX_MIXG_CMFB_IDAC, 0x00); | BWN_RF_WRITE(mac, B2056_RX0 | B2056_RX_MIXG_CMFB_IDAC, 0x00); | ||||
BWN_RF_WRITE(mac, B2056_RX1 | B2056_RX_MIXG_CMFB_IDAC, 0x00); | BWN_RF_WRITE(mac, B2056_RX1 | B2056_RX_MIXG_CMFB_IDAC, 0x00); | ||||
/* N PHY WAR TX Chain Update with hw_phytxchain as argument */ | /* N PHY WAR TX Chain Update with hw_phytxchain as argument */ | ||||
if ((siba_sprom_get_bf2_lo(sc->sc_dev) & BWN_BFL2_APLL_WAR && | if ((sc->sc_board_info.board_flags2 & BHND_BFL2_APLL_WAR && | ||||
bwn_current_band(mac) == BWN_BAND_5G) || | bwn_current_band(mac) == BWN_BAND_5G) || | ||||
(siba_sprom_get_bf2_lo(sc->sc_dev) & BWN_BFL2_GPLL_WAR && | (sc->sc_board_info.board_flags2 & BHND_BFL2_GPLL_WAR2 && | ||||
bwn_current_band(mac) == BWN_BAND_2G)) | bwn_current_band(mac) == BWN_BAND_2G)) | ||||
tmp32 = 0x00088888; | tmp32 = 0x00088888; | ||||
else | else | ||||
tmp32 = 0x88888888; | tmp32 = 0x88888888; | ||||
bwn_ntab_write(mac, BWN_NTAB32(30, 1), tmp32); | bwn_ntab_write(mac, BWN_NTAB32(30, 1), tmp32); | ||||
bwn_ntab_write(mac, BWN_NTAB32(30, 2), tmp32); | bwn_ntab_write(mac, BWN_NTAB32(30, 2), tmp32); | ||||
bwn_ntab_write(mac, BWN_NTAB32(30, 3), tmp32); | bwn_ntab_write(mac, BWN_NTAB32(30, 3), tmp32); | ||||
Show All 14 Lines | static int bwn_nphy_workarounds_rev3plus(struct bwn_mac *mac) | ||||
BWN_PHY_WRITE(mac, BWN_NPHY_ED_CRS20LASSERTTHRESH1, 0x042b); | BWN_PHY_WRITE(mac, BWN_NPHY_ED_CRS20LASSERTTHRESH1, 0x042b); | ||||
BWN_PHY_WRITE(mac, BWN_NPHY_ED_CRS20LDEASSERTTHRESH0, 0x0381); | BWN_PHY_WRITE(mac, BWN_NPHY_ED_CRS20LDEASSERTTHRESH0, 0x0381); | ||||
BWN_PHY_WRITE(mac, BWN_NPHY_ED_CRS20LDEASSERTTHRESH1, 0x0381); | BWN_PHY_WRITE(mac, BWN_NPHY_ED_CRS20LDEASSERTTHRESH1, 0x0381); | ||||
BWN_PHY_WRITE(mac, BWN_NPHY_ED_CRS20UASSERTTHRESH0, 0x042b); | BWN_PHY_WRITE(mac, BWN_NPHY_ED_CRS20UASSERTTHRESH0, 0x042b); | ||||
BWN_PHY_WRITE(mac, BWN_NPHY_ED_CRS20UASSERTTHRESH1, 0x042b); | BWN_PHY_WRITE(mac, BWN_NPHY_ED_CRS20UASSERTTHRESH1, 0x042b); | ||||
BWN_PHY_WRITE(mac, BWN_NPHY_ED_CRS20UDEASSERTTHRESH0, 0x0381); | BWN_PHY_WRITE(mac, BWN_NPHY_ED_CRS20UDEASSERTTHRESH0, 0x0381); | ||||
BWN_PHY_WRITE(mac, BWN_NPHY_ED_CRS20UDEASSERTTHRESH1, 0x0381); | BWN_PHY_WRITE(mac, BWN_NPHY_ED_CRS20UDEASSERTTHRESH1, 0x0381); | ||||
if (mac->mac_phy.rev >= 6 && siba_sprom_get_bf2_lo(sc->sc_dev) & BWN_BFL2_SINGLEANT_CCK) | if (mac->mac_phy.rev >= 6 && sc->sc_board_info.board_flags2 & BHND_BFL2_SINGLEANT_CCK) | ||||
; /* TODO: 0x0080000000000000 HF */ | ; /* TODO: 0x0080000000000000 HF */ | ||||
return (0); | |||||
} | } | ||||
static void bwn_nphy_workarounds_rev1_2(struct bwn_mac *mac) | static int bwn_nphy_workarounds_rev1_2(struct bwn_mac *mac) | ||||
{ | { | ||||
struct bwn_softc *sc = mac->mac_sc; | struct bwn_softc *sc = mac->mac_sc; | ||||
struct bwn_phy *phy = &mac->mac_phy; | struct bwn_phy *phy = &mac->mac_phy; | ||||
struct bwn_phy_n *nphy = phy->phy_n; | struct bwn_phy_n *nphy = phy->phy_n; | ||||
uint8_t events1[7] = { 0x0, 0x1, 0x2, 0x8, 0x4, 0x5, 0x3 }; | uint8_t events1[7] = { 0x0, 0x1, 0x2, 0x8, 0x4, 0x5, 0x3 }; | ||||
uint8_t delays1[7] = { 0x8, 0x6, 0x6, 0x2, 0x4, 0x3C, 0x1 }; | uint8_t delays1[7] = { 0x8, 0x6, 0x6, 0x2, 0x4, 0x3C, 0x1 }; | ||||
uint8_t events2[7] = { 0x0, 0x3, 0x5, 0x4, 0x2, 0x1, 0x8 }; | uint8_t events2[7] = { 0x0, 0x3, 0x5, 0x4, 0x2, 0x1, 0x8 }; | ||||
uint8_t delays2[7] = { 0x8, 0x6, 0x2, 0x4, 0x4, 0x6, 0x1 }; | uint8_t delays2[7] = { 0x8, 0x6, 0x2, 0x4, 0x4, 0x6, 0x1 }; | ||||
if (siba_sprom_get_bf2_lo(sc->sc_dev) & BWN_BFL2_SKWRKFEM_BRD || | if (sc->sc_board_info.board_flags2 & BHND_BFL2_SKWRKFEM_BRD || | ||||
siba_get_pci_subdevice(sc->sc_dev)== BCMA_BOARD_TYPE_BCM943224M93) { | sc->sc_board_info.board_type == BHND_BOARD_BCM943224M93) { | ||||
delays1[0] = 0x1; | delays1[0] = 0x1; | ||||
delays1[5] = 0x14; | delays1[5] = 0x14; | ||||
} | } | ||||
if (bwn_current_band(mac) == BWN_BAND_5G && | if (bwn_current_band(mac) == BWN_BAND_5G && | ||||
nphy->band5g_pwrgain) { | nphy->band5g_pwrgain) { | ||||
BWN_RF_MASK(mac, B2055_C1_TX_RF_SPARE, ~0x8); | BWN_RF_MASK(mac, B2055_C1_TX_RF_SPARE, ~0x8); | ||||
BWN_RF_MASK(mac, B2055_C2_TX_RF_SPARE, ~0x8); | BWN_RF_MASK(mac, B2055_C2_TX_RF_SPARE, ~0x8); | ||||
▲ Show 20 Lines • Show All 55 Lines • ▼ Show 20 Lines | if (mac->mac_phy.rev < 3) { | ||||
BWN_PHY_WRITE(mac, BWN_NPHY_TXF_20CO_S2B1, 0xB5); | BWN_PHY_WRITE(mac, BWN_NPHY_TXF_20CO_S2B1, 0xB5); | ||||
BWN_PHY_WRITE(mac, BWN_NPHY_TXF_20CO_S2B2, 0xA4); | BWN_PHY_WRITE(mac, BWN_NPHY_TXF_20CO_S2B2, 0xA4); | ||||
BWN_PHY_WRITE(mac, BWN_NPHY_TXF_20CO_S2B3, 0x00); | BWN_PHY_WRITE(mac, BWN_NPHY_TXF_20CO_S2B3, 0x00); | ||||
} | } | ||||
if (mac->mac_phy.rev == 2) | if (mac->mac_phy.rev == 2) | ||||
BWN_PHY_SET(mac, BWN_NPHY_FINERX2_CGC, | BWN_PHY_SET(mac, BWN_NPHY_FINERX2_CGC, | ||||
BWN_NPHY_FINERX2_CGC_DECGC); | BWN_NPHY_FINERX2_CGC_DECGC); | ||||
return (0); | |||||
} | } | ||||
/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/Workarounds */ | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/Workarounds */ | ||||
static void bwn_nphy_workarounds(struct bwn_mac *mac) | static int bwn_nphy_workarounds(struct bwn_mac *mac) | ||||
{ | { | ||||
struct bwn_phy *phy = &mac->mac_phy; | struct bwn_phy *phy = &mac->mac_phy; | ||||
struct bwn_phy_n *nphy = phy->phy_n; | struct bwn_phy_n *nphy = phy->phy_n; | ||||
int error; | |||||
if (bwn_current_band(mac) == BWN_BAND_5G) | if (bwn_current_band(mac) == BWN_BAND_5G) | ||||
bwn_nphy_classifier(mac, 1, 0); | bwn_nphy_classifier(mac, 1, 0); | ||||
else | else | ||||
bwn_nphy_classifier(mac, 1, 1); | bwn_nphy_classifier(mac, 1, 1); | ||||
if (nphy->hang_avoid) | if (nphy->hang_avoid) | ||||
bwn_nphy_stay_in_carrier_search(mac, 1); | bwn_nphy_stay_in_carrier_search(mac, 1); | ||||
BWN_PHY_SET(mac, BWN_NPHY_IQFLIP, | BWN_PHY_SET(mac, BWN_NPHY_IQFLIP, | ||||
BWN_NPHY_IQFLIP_ADC1 | BWN_NPHY_IQFLIP_ADC2); | BWN_NPHY_IQFLIP_ADC1 | BWN_NPHY_IQFLIP_ADC2); | ||||
/* TODO: rev19+ */ | /* TODO: rev19+ */ | ||||
if (mac->mac_phy.rev >= 7) | if (mac->mac_phy.rev >= 7) | ||||
bwn_nphy_workarounds_rev7plus(mac); | error = bwn_nphy_workarounds_rev7plus(mac); | ||||
else if (mac->mac_phy.rev >= 3) | else if (mac->mac_phy.rev >= 3) | ||||
bwn_nphy_workarounds_rev3plus(mac); | error = bwn_nphy_workarounds_rev3plus(mac); | ||||
else | else | ||||
bwn_nphy_workarounds_rev1_2(mac); | error = bwn_nphy_workarounds_rev1_2(mac); | ||||
if (error) | |||||
return (error); | |||||
if (nphy->hang_avoid) | if (nphy->hang_avoid) | ||||
bwn_nphy_stay_in_carrier_search(mac, 0); | bwn_nphy_stay_in_carrier_search(mac, 0); | ||||
return (0); | |||||
} | } | ||||
/************************************************** | /************************************************** | ||||
* Tx/Rx common | * Tx/Rx common | ||||
**************************************************/ | **************************************************/ | ||||
/* | /* | ||||
* Transmits a known value for LO calibration | * Transmits a known value for LO calibration | ||||
▲ Show 20 Lines • Show All 257 Lines • ▼ Show 20 Lines | if (!enable) { | ||||
} | } | ||||
} | } | ||||
if (nphy->hang_avoid) | if (nphy->hang_avoid) | ||||
bwn_nphy_stay_in_carrier_search(mac, 0); | bwn_nphy_stay_in_carrier_search(mac, 0); | ||||
} | } | ||||
/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrFix */ | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrFix */ | ||||
static void bwn_nphy_tx_power_fix(struct bwn_mac *mac) | static int bwn_nphy_tx_power_fix(struct bwn_mac *mac) | ||||
{ | { | ||||
struct bwn_softc *sc = mac->mac_sc; | struct bwn_softc *sc = mac->mac_sc; | ||||
struct bwn_phy_n *nphy = mac->mac_phy.phy_n; | struct bwn_phy_n *nphy = mac->mac_phy.phy_n; | ||||
uint8_t txpi[2], bbmult, i; | uint8_t txpi[2], bbmult, i; | ||||
uint16_t tmp, radio_gain, dac_gain; | uint16_t tmp, radio_gain, dac_gain; | ||||
uint16_t freq = bwn_get_centre_freq(mac); | uint16_t freq = bwn_get_centre_freq(mac); | ||||
uint32_t txgain; | uint32_t txgain; | ||||
/* uint32_t gaintbl; rev3+ */ | /* uint32_t gaintbl; rev3+ */ | ||||
if (nphy->hang_avoid) | if (nphy->hang_avoid) | ||||
bwn_nphy_stay_in_carrier_search(mac, 1); | bwn_nphy_stay_in_carrier_search(mac, 1); | ||||
/* TODO: rev19+ */ | /* TODO: rev19+ */ | ||||
if (mac->mac_phy.rev >= 7) { | if (mac->mac_phy.rev >= 7) { | ||||
txpi[0] = txpi[1] = 30; | txpi[0] = txpi[1] = 30; | ||||
} else if (mac->mac_phy.rev >= 3) { | } else if (mac->mac_phy.rev >= 3) { | ||||
txpi[0] = 40; | txpi[0] = 40; | ||||
txpi[1] = 40; | txpi[1] = 40; | ||||
} else if (siba_sprom_get_rev(sc->sc_dev) < 4) { | } else if (sc->sc_board_info.board_srom_rev < 4) { | ||||
txpi[0] = 72; | txpi[0] = 72; | ||||
txpi[1] = 72; | txpi[1] = 72; | ||||
} else { | } else { | ||||
#define BWN_NPHY_GET_TXPI(_name, _result) \ | |||||
do { \ | |||||
int error; \ | |||||
error = bhnd_nvram_getvar_uint8(sc->sc_dev, (_name), \ | |||||
(_result)); \ | |||||
if (error) { \ | |||||
device_printf(sc->sc_dev, "NVRAM variable %s " \ | |||||
"unreadable: %d\n", (_name), error); \ | |||||
return (error); \ | |||||
} \ | |||||
} while(0) | |||||
if (bwn_current_band(mac) == BWN_BAND_2G) { | if (bwn_current_band(mac) == BWN_BAND_2G) { | ||||
txpi[0] = siba_sprom_get_txpid_2g_0(sc->sc_dev); | BWN_NPHY_GET_TXPI(BHND_NVAR_TXPID2GA0, &txpi[0]); | ||||
txpi[1] = siba_sprom_get_txpid_2g_1(sc->sc_dev); | BWN_NPHY_GET_TXPI(BHND_NVAR_TXPID2GA1, &txpi[1]); | ||||
} else if (freq >= 4900 && freq < 5100) { | } else if (freq >= 4900 && freq < 5100) { | ||||
txpi[0] = siba_sprom_get_txpid_5gl_0(sc->sc_dev); | BWN_NPHY_GET_TXPI(BHND_NVAR_TXPID5GLA0, &txpi[0]); | ||||
txpi[1] = siba_sprom_get_txpid_5gl_1(sc->sc_dev); | BWN_NPHY_GET_TXPI(BHND_NVAR_TXPID5GLA1, &txpi[1]); | ||||
} else if (freq >= 5100 && freq < 5500) { | } else if (freq >= 5100 && freq < 5500) { | ||||
txpi[0] = siba_sprom_get_txpid_5g_0(sc->sc_dev); | BWN_NPHY_GET_TXPI(BHND_NVAR_TXPID5GA0, &txpi[0]); | ||||
txpi[1] = siba_sprom_get_txpid_5g_1(sc->sc_dev); | BWN_NPHY_GET_TXPI(BHND_NVAR_TXPID5GA1, &txpi[1]); | ||||
} else if (freq >= 5500) { | } else if (freq >= 5500) { | ||||
txpi[0] = siba_sprom_get_txpid_5gh_0(sc->sc_dev); | BWN_NPHY_GET_TXPI(BHND_NVAR_TXPID5GHA0, &txpi[0]); | ||||
txpi[1] = siba_sprom_get_txpid_5gh_1(sc->sc_dev); | BWN_NPHY_GET_TXPI(BHND_NVAR_TXPID5GHA1, &txpi[1]); | ||||
} else { | } else { | ||||
txpi[0] = 91; | txpi[0] = 91; | ||||
txpi[1] = 91; | txpi[1] = 91; | ||||
} | } | ||||
#undef BWN_NPHY_GET_TXPI | |||||
} | } | ||||
if (mac->mac_phy.rev < 7 && | if (mac->mac_phy.rev < 7 && | ||||
(txpi[0] < 40 || txpi[0] > 100 || txpi[1] < 40 || txpi[1] > 100)) | (txpi[0] < 40 || txpi[0] > 100 || txpi[1] < 40 || txpi[1] > 100)) | ||||
txpi[0] = txpi[1] = 91; | txpi[0] = txpi[1] = 91; | ||||
/* | /* | ||||
for (i = 0; i < 2; i++) { | for (i = 0; i < 2; i++) { | ||||
nphy->txpwrindex[i].index_internal = txpi[i]; | nphy->txpwrindex[i].index_internal = txpi[i]; | ||||
▲ Show 20 Lines • Show All 52 Lines • ▼ Show 20 Lines | if (bwn_nphy_ipa(mac)) { | ||||
BWN_PHY_SET(mac, reg, 0x4); | BWN_PHY_SET(mac, reg, 0x4); | ||||
} | } | ||||
} | } | ||||
BWN_PHY_MASK(mac, BWN_NPHY_BPHY_CTL2, ~BWN_NPHY_BPHY_CTL2_LUT); | BWN_PHY_MASK(mac, BWN_NPHY_BPHY_CTL2, ~BWN_NPHY_BPHY_CTL2_LUT); | ||||
if (nphy->hang_avoid) | if (nphy->hang_avoid) | ||||
bwn_nphy_stay_in_carrier_search(mac, 0); | bwn_nphy_stay_in_carrier_search(mac, 0); | ||||
return (0); | |||||
} | } | ||||
static void bwn_nphy_ipa_internal_tssi_setup(struct bwn_mac *mac) | static void bwn_nphy_ipa_internal_tssi_setup(struct bwn_mac *mac) | ||||
{ | { | ||||
struct bwn_phy *phy = &mac->mac_phy; | struct bwn_phy *phy = &mac->mac_phy; | ||||
uint8_t core; | uint8_t core; | ||||
uint16_t r; /* routing */ | uint16_t r; /* routing */ | ||||
▲ Show 20 Lines • Show All 187 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrCtrlSetup */ | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrCtrlSetup */ | ||||
static void bwn_nphy_tx_power_ctl_setup(struct bwn_mac *mac) | static void bwn_nphy_tx_power_ctl_setup(struct bwn_mac *mac) | ||||
{ | { | ||||
struct bwn_softc *sc = mac->mac_sc; | struct bwn_softc *sc = mac->mac_sc; | ||||
struct bwn_phy *phy = &mac->mac_phy; | struct bwn_phy *phy = &mac->mac_phy; | ||||
struct bwn_phy_n *nphy = mac->mac_phy.phy_n; | struct bwn_phy_n *nphy = mac->mac_phy.phy_n; | ||||
struct siba_sprom_core_pwr_info core_pwr_info[4]; | struct bwn_phy_n_core_pwr_info core_pwr_info[4]; | ||||
int n; | int n; | ||||
int16_t a1[2], b0[2], b1[2]; | int16_t a1[2], b0[2], b1[2]; | ||||
uint8_t idle[2]; | uint8_t idle[2]; | ||||
uint8_t ppr_max; | uint8_t ppr_max; | ||||
int8_t target[2]; | int8_t target[2]; | ||||
int32_t num, den, pwr; | int32_t num, den, pwr; | ||||
uint32_t regval[64]; | uint32_t regval[64]; | ||||
uint16_t freq = bwn_get_centre_freq(mac); | uint16_t freq = bwn_get_centre_freq(mac); | ||||
uint16_t tmp; | uint16_t tmp; | ||||
uint16_t r; /* routing */ | uint16_t r; /* routing */ | ||||
uint8_t i, c; | uint8_t i, c; | ||||
for (n = 0; n < 4; n++) { | for (n = 0; n < 4; n++) { | ||||
bzero(&core_pwr_info[n], sizeof(core_pwr_info[n])); | bzero(&core_pwr_info[n], sizeof(core_pwr_info[n])); | ||||
if (siba_sprom_get_core_power_info(sc->sc_dev, n, | if (bwn_nphy_get_core_power_info(mac, n, | ||||
&core_pwr_info[n]) != 0) { | &core_pwr_info[n]) != 0) { | ||||
BWN_ERRPRINTF(mac->mac_sc, | BWN_ERRPRINTF(mac->mac_sc, | ||||
"%s: failed to get core_pwr_info for core %d\n", | "%s: failed to get core_pwr_info for core %d\n", | ||||
__func__, | __func__, | ||||
n); | n); | ||||
} | } | ||||
} | } | ||||
if (siba_get_revid(sc->sc_dev) == 11 || siba_get_revid(sc->sc_dev) == 12) { | if (bhnd_get_hwrev(sc->sc_dev) == 11 || bhnd_get_hwrev(sc->sc_dev) == 12) { | ||||
BWN_WRITE_SETMASK4(mac, BWN_MACCTL, ~0, 0x200000); | BWN_WRITE_SETMASK4(mac, BWN_MACCTL, ~0, 0x200000); | ||||
BWN_READ_4(mac, BWN_MACCTL); | BWN_READ_4(mac, BWN_MACCTL); | ||||
DELAY(1); | DELAY(1); | ||||
} | } | ||||
if (nphy->hang_avoid) | if (nphy->hang_avoid) | ||||
bwn_nphy_stay_in_carrier_search(mac, true); | bwn_nphy_stay_in_carrier_search(mac, true); | ||||
BWN_PHY_SET(mac, BWN_NPHY_TSSIMODE, BWN_NPHY_TSSIMODE_EN); | BWN_PHY_SET(mac, BWN_NPHY_TSSIMODE, BWN_NPHY_TSSIMODE_EN); | ||||
if (mac->mac_phy.rev >= 3) | if (mac->mac_phy.rev >= 3) | ||||
BWN_PHY_MASK(mac, BWN_NPHY_TXPCTL_CMD, | BWN_PHY_MASK(mac, BWN_NPHY_TXPCTL_CMD, | ||||
~BWN_NPHY_TXPCTL_CMD_PCTLEN & 0xFFFF); | ~BWN_NPHY_TXPCTL_CMD_PCTLEN & 0xFFFF); | ||||
else | else | ||||
BWN_PHY_SET(mac, BWN_NPHY_TXPCTL_CMD, | BWN_PHY_SET(mac, BWN_NPHY_TXPCTL_CMD, | ||||
BWN_NPHY_TXPCTL_CMD_PCTLEN); | BWN_NPHY_TXPCTL_CMD_PCTLEN); | ||||
if (siba_get_revid(sc->sc_dev) == 11 || siba_get_revid(sc->sc_dev) == 12) | if (bhnd_get_hwrev(sc->sc_dev) == 11 || bhnd_get_hwrev(sc->sc_dev) == 12) | ||||
BWN_WRITE_SETMASK4(mac, BWN_MACCTL, ~0x200000, 0); | BWN_WRITE_SETMASK4(mac, BWN_MACCTL, ~0x200000, 0); | ||||
/* | /* | ||||
* XXX TODO: see if those bandsbelow map to 5g-lo, 5g-mid, 5g-hi in | * XXX TODO: see if those bandsbelow map to 5g-lo, 5g-mid, 5g-hi in | ||||
* any way. | * any way. | ||||
*/ | */ | ||||
if (siba_sprom_get_rev(sc->sc_dev) < 4) { | if (sc->sc_board_info.board_srom_rev < 4) { | ||||
idle[0] = nphy->pwr_ctl_info[0].idle_tssi_2g; | idle[0] = nphy->pwr_ctl_info[0].idle_tssi_2g; | ||||
idle[1] = nphy->pwr_ctl_info[1].idle_tssi_2g; | idle[1] = nphy->pwr_ctl_info[1].idle_tssi_2g; | ||||
target[0] = target[1] = 52; | target[0] = target[1] = 52; | ||||
a1[0] = a1[1] = -424; | a1[0] = a1[1] = -424; | ||||
b0[0] = b0[1] = 5612; | b0[0] = b0[1] = 5612; | ||||
b1[0] = b1[1] = -1393; | b1[0] = b1[1] = -1393; | ||||
} else { | } else { | ||||
if (bwn_current_band(mac) == BWN_BAND_2G) { | if (bwn_current_band(mac) == BWN_BAND_2G) { | ||||
Show All 40 Lines | static void bwn_nphy_tx_power_ctl_setup(struct bwn_mac *mac) | ||||
ppr_max = bwn_ppr_get_max(mac, &nphy->tx_pwr_max_ppr); | ppr_max = bwn_ppr_get_max(mac, &nphy->tx_pwr_max_ppr); | ||||
if (ppr_max) { | if (ppr_max) { | ||||
target[0] = ppr_max; | target[0] = ppr_max; | ||||
target[1] = ppr_max; | target[1] = ppr_max; | ||||
} | } | ||||
if (mac->mac_phy.rev >= 3) { | if (mac->mac_phy.rev >= 3) { | ||||
if (siba_sprom_get_fem_2ghz_tssipos(sc->sc_dev)) | if (nphy->tsspos_2g) | ||||
BWN_PHY_SET(mac, BWN_NPHY_TXPCTL_ITSSI, 0x4000); | BWN_PHY_SET(mac, BWN_NPHY_TXPCTL_ITSSI, 0x4000); | ||||
if (mac->mac_phy.rev >= 7) { | if (mac->mac_phy.rev >= 7) { | ||||
for (c = 0; c < 2; c++) { | for (c = 0; c < 2; c++) { | ||||
r = c ? 0x190 : 0x170; | r = c ? 0x190 : 0x170; | ||||
if (bwn_nphy_ipa(mac)) | if (bwn_nphy_ipa(mac)) | ||||
BWN_RF_WRITE(mac, r + 0x9, (bwn_current_band(mac) == BWN_BAND_2G) ? 0xE : 0xC); | BWN_RF_WRITE(mac, r + 0x9, (bwn_current_band(mac) == BWN_BAND_2G) ? 0xE : 0xC); | ||||
} | } | ||||
} else { | } else { | ||||
if (bwn_nphy_ipa(mac)) { | if (bwn_nphy_ipa(mac)) { | ||||
tmp = (bwn_current_band(mac) == BWN_BAND_5G) ? 0xC : 0xE; | tmp = (bwn_current_band(mac) == BWN_BAND_5G) ? 0xC : 0xE; | ||||
BWN_RF_WRITE(mac, | BWN_RF_WRITE(mac, | ||||
B2056_TX0 | B2056_TX_TX_SSI_MUX, tmp); | B2056_TX0 | B2056_TX_TX_SSI_MUX, tmp); | ||||
BWN_RF_WRITE(mac, | BWN_RF_WRITE(mac, | ||||
B2056_TX1 | B2056_TX_TX_SSI_MUX, tmp); | B2056_TX1 | B2056_TX_TX_SSI_MUX, tmp); | ||||
} else { | } else { | ||||
BWN_RF_WRITE(mac, | BWN_RF_WRITE(mac, | ||||
B2056_TX0 | B2056_TX_TX_SSI_MUX, 0x11); | B2056_TX0 | B2056_TX_TX_SSI_MUX, 0x11); | ||||
BWN_RF_WRITE(mac, | BWN_RF_WRITE(mac, | ||||
B2056_TX1 | B2056_TX_TX_SSI_MUX, 0x11); | B2056_TX1 | B2056_TX_TX_SSI_MUX, 0x11); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
if (siba_get_revid(sc->sc_dev) == 11 || siba_get_revid(sc->sc_dev) == 12) { | if (bhnd_get_hwrev(sc->sc_dev) == 11 || bhnd_get_hwrev(sc->sc_dev) == 12) { | ||||
BWN_WRITE_SETMASK4(mac, BWN_MACCTL, ~0, 0x200000); | BWN_WRITE_SETMASK4(mac, BWN_MACCTL, ~0, 0x200000); | ||||
BWN_READ_4(mac, BWN_MACCTL); | BWN_READ_4(mac, BWN_MACCTL); | ||||
DELAY(1); | DELAY(1); | ||||
} | } | ||||
if (phy->rev >= 19) { | if (phy->rev >= 19) { | ||||
/* TODO */ | /* TODO */ | ||||
} else if (phy->rev >= 7) { | } else if (phy->rev >= 7) { | ||||
BWN_PHY_SETMASK(mac, BWN_NPHY_TXPCTL_CMD, | BWN_PHY_SETMASK(mac, BWN_NPHY_TXPCTL_CMD, | ||||
~BWN_NPHY_TXPCTL_CMD_INIT, 0x19); | ~BWN_NPHY_TXPCTL_CMD_INIT, 0x19); | ||||
BWN_PHY_SETMASK(mac, BWN_NPHY_TXPCTL_INIT, | BWN_PHY_SETMASK(mac, BWN_NPHY_TXPCTL_INIT, | ||||
~BWN_NPHY_TXPCTL_INIT_PIDXI1, 0x19); | ~BWN_NPHY_TXPCTL_INIT_PIDXI1, 0x19); | ||||
} else { | } else { | ||||
BWN_PHY_SETMASK(mac, BWN_NPHY_TXPCTL_CMD, | BWN_PHY_SETMASK(mac, BWN_NPHY_TXPCTL_CMD, | ||||
~BWN_NPHY_TXPCTL_CMD_INIT, 0x40); | ~BWN_NPHY_TXPCTL_CMD_INIT, 0x40); | ||||
if (mac->mac_phy.rev > 1) | if (mac->mac_phy.rev > 1) | ||||
BWN_PHY_SETMASK(mac, BWN_NPHY_TXPCTL_INIT, | BWN_PHY_SETMASK(mac, BWN_NPHY_TXPCTL_INIT, | ||||
~BWN_NPHY_TXPCTL_INIT_PIDXI1, 0x40); | ~BWN_NPHY_TXPCTL_INIT_PIDXI1, 0x40); | ||||
} | } | ||||
if (siba_get_revid(sc->sc_dev) == 11 || siba_get_revid(sc->sc_dev) == 12) | if (bhnd_get_hwrev(sc->sc_dev) == 11 || bhnd_get_hwrev(sc->sc_dev) == 12) | ||||
BWN_WRITE_SETMASK4(mac, BWN_MACCTL, ~0x200000, 0); | BWN_WRITE_SETMASK4(mac, BWN_MACCTL, ~0x200000, 0); | ||||
BWN_PHY_WRITE(mac, BWN_NPHY_TXPCTL_N, | BWN_PHY_WRITE(mac, BWN_NPHY_TXPCTL_N, | ||||
0xF0 << BWN_NPHY_TXPCTL_N_TSSID_SHIFT | | 0xF0 << BWN_NPHY_TXPCTL_N_TSSID_SHIFT | | ||||
3 << BWN_NPHY_TXPCTL_N_NPTIL2_SHIFT); | 3 << BWN_NPHY_TXPCTL_N_NPTIL2_SHIFT); | ||||
BWN_PHY_WRITE(mac, BWN_NPHY_TXPCTL_ITSSI, | BWN_PHY_WRITE(mac, BWN_NPHY_TXPCTL_ITSSI, | ||||
idle[0] << BWN_NPHY_TXPCTL_ITSSI_0_SHIFT | | idle[0] << BWN_NPHY_TXPCTL_ITSSI_0_SHIFT | | ||||
idle[1] << BWN_NPHY_TXPCTL_ITSSI_1_SHIFT | | idle[1] << BWN_NPHY_TXPCTL_ITSSI_1_SHIFT | | ||||
▲ Show 20 Lines • Show All 1,729 Lines • ▼ Show 20 Lines | #endif | ||||
/* Make sure we didn't go too low */ | /* Make sure we didn't go too low */ | ||||
bwn_ppr_apply_min(mac, ppr, INT_TO_Q52(8)); | bwn_ppr_apply_min(mac, ppr, INT_TO_Q52(8)); | ||||
/* Apply */ | /* Apply */ | ||||
tx_pwr_state = nphy->txpwrctrl; | tx_pwr_state = nphy->txpwrctrl; | ||||
bwn_mac_suspend(mac); | bwn_mac_suspend(mac); | ||||
bwn_nphy_tx_power_ctl_setup(mac); | bwn_nphy_tx_power_ctl_setup(mac); | ||||
if (siba_get_revid(sc->sc_dev) == 11 || siba_get_revid(sc->sc_dev) == 12) { | if (bhnd_get_hwrev(sc->sc_dev) == 11 || bhnd_get_hwrev(sc->sc_dev) == 12) { | ||||
BWN_WRITE_SETMASK4(mac, BWN_MACCTL, ~0, BWN_MACCTL_PHY_LOCK); | BWN_WRITE_SETMASK4(mac, BWN_MACCTL, ~0, BWN_MACCTL_PHY_LOCK); | ||||
BWN_READ_4(mac, BWN_MACCTL); | BWN_READ_4(mac, BWN_MACCTL); | ||||
DELAY(1); | DELAY(1); | ||||
} | } | ||||
bwn_nphy_tx_power_ctrl(mac, nphy->txpwrctrl); | bwn_nphy_tx_power_ctrl(mac, nphy->txpwrctrl); | ||||
if (siba_get_revid(sc->sc_dev) == 11 || siba_get_revid(sc->sc_dev) == 12) | if (bhnd_get_hwrev(sc->sc_dev) == 11 || bhnd_get_hwrev(sc->sc_dev) == 12) | ||||
BWN_WRITE_SETMASK4(mac, BWN_MACCTL, ~BWN_MACCTL_PHY_LOCK, 0); | BWN_WRITE_SETMASK4(mac, BWN_MACCTL, ~BWN_MACCTL_PHY_LOCK, 0); | ||||
bwn_mac_enable(mac); | bwn_mac_enable(mac); | ||||
nphy->tx_pwr_last_recalc_freq = bwn_get_centre_freq(mac); | nphy->tx_pwr_last_recalc_freq = bwn_get_centre_freq(mac); | ||||
nphy->tx_pwr_last_recalc_limit = phy->txpower; | nphy->tx_pwr_last_recalc_limit = phy->txpower; | ||||
return BWN_TXPWR_RES_DONE; | return BWN_TXPWR_RES_DONE; | ||||
} | } | ||||
Show All 31 Lines | static void bwn_nphy_bphy_init(struct bwn_mac *mac) | ||||
for (i = 0; i < 16; i++) { | for (i = 0; i < 16; i++) { | ||||
BWN_PHY_WRITE(mac, BWN_PHY_N_BMODE(0x98 + i), val); | BWN_PHY_WRITE(mac, BWN_PHY_N_BMODE(0x98 + i), val); | ||||
val -= 0x202; | val -= 0x202; | ||||
} | } | ||||
BWN_PHY_WRITE(mac, BWN_PHY_N_BMODE(0x38), 0x668); | BWN_PHY_WRITE(mac, BWN_PHY_N_BMODE(0x38), 0x668); | ||||
} | } | ||||
/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SuperSwitchInit */ | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SuperSwitchInit */ | ||||
static void bwn_nphy_superswitch_init(struct bwn_mac *mac, bool init) | static int bwn_nphy_superswitch_init(struct bwn_mac *mac, bool init) | ||||
{ | { | ||||
struct bwn_softc *sc = mac->mac_sc; | int error; | ||||
if (mac->mac_phy.rev >= 7) | if (mac->mac_phy.rev >= 7) | ||||
return; | return (0); | ||||
if (mac->mac_phy.rev >= 3) { | if (mac->mac_phy.rev >= 3) { | ||||
if (!init) | if (!init) | ||||
return; | return (0); | ||||
if (0 /* FIXME */) { | if (0 /* FIXME */) { | ||||
bwn_ntab_write(mac, BWN_NTAB16(9, 2), 0x211); | bwn_ntab_write(mac, BWN_NTAB16(9, 2), 0x211); | ||||
bwn_ntab_write(mac, BWN_NTAB16(9, 3), 0x222); | bwn_ntab_write(mac, BWN_NTAB16(9, 3), 0x222); | ||||
bwn_ntab_write(mac, BWN_NTAB16(9, 8), 0x144); | bwn_ntab_write(mac, BWN_NTAB16(9, 8), 0x144); | ||||
bwn_ntab_write(mac, BWN_NTAB16(9, 12), 0x188); | bwn_ntab_write(mac, BWN_NTAB16(9, 12), 0x188); | ||||
} | } | ||||
} else { | } else { | ||||
BWN_PHY_WRITE(mac, BWN_NPHY_GPIO_LOOEN, 0); | BWN_PHY_WRITE(mac, BWN_NPHY_GPIO_LOOEN, 0); | ||||
BWN_PHY_WRITE(mac, BWN_NPHY_GPIO_HIOEN, 0); | BWN_PHY_WRITE(mac, BWN_NPHY_GPIO_HIOEN, 0); | ||||
siba_gpio_set(sc->sc_dev, 0xfc00); | if ((error = bwn_gpio_control(mac, 0xfc00))) | ||||
return (error); | |||||
BWN_WRITE_SETMASK4(mac, BWN_MACCTL, ~BWN_MACCTL_GPOUT_MASK, 0); | BWN_WRITE_SETMASK4(mac, BWN_MACCTL, ~BWN_MACCTL_GPOUT_MASK, 0); | ||||
BWN_WRITE_SETMASK2(mac, BWN_GPIO_MASK, ~0, 0xFC00); | BWN_WRITE_SETMASK2(mac, BWN_GPIO_MASK, ~0, 0xFC00); | ||||
BWN_WRITE_SETMASK2(mac, BWN_GPIO_CONTROL, (~0xFC00 & 0xFFFF), | BWN_WRITE_SETMASK2(mac, BWN_GPIO_CONTROL, (~0xFC00 & 0xFFFF), | ||||
0); | 0); | ||||
if (init) { | if (init) { | ||||
BWN_PHY_WRITE(mac, BWN_NPHY_RFCTL_LUT_TRSW_LO1, 0x2D8); | BWN_PHY_WRITE(mac, BWN_NPHY_RFCTL_LUT_TRSW_LO1, 0x2D8); | ||||
BWN_PHY_WRITE(mac, BWN_NPHY_RFCTL_LUT_TRSW_UP1, 0x301); | BWN_PHY_WRITE(mac, BWN_NPHY_RFCTL_LUT_TRSW_UP1, 0x301); | ||||
BWN_PHY_WRITE(mac, BWN_NPHY_RFCTL_LUT_TRSW_LO2, 0x2D8); | BWN_PHY_WRITE(mac, BWN_NPHY_RFCTL_LUT_TRSW_LO2, 0x2D8); | ||||
BWN_PHY_WRITE(mac, BWN_NPHY_RFCTL_LUT_TRSW_UP2, 0x301); | BWN_PHY_WRITE(mac, BWN_NPHY_RFCTL_LUT_TRSW_UP2, 0x301); | ||||
} | } | ||||
} | } | ||||
return (0); | |||||
} | } | ||||
/* http://bcm-v4.sipsolutions.net/802.11/PHY/Init/N */ | /* http://bcm-v4.sipsolutions.net/802.11/PHY/Init/N */ | ||||
static int bwn_phy_initn(struct bwn_mac *mac) | static int bwn_phy_initn(struct bwn_mac *mac) | ||||
{ | { | ||||
struct bwn_softc *sc = mac->mac_sc; | struct bwn_softc *sc = mac->mac_sc; | ||||
struct bwn_phy *phy = &mac->mac_phy; | struct bwn_phy *phy = &mac->mac_phy; | ||||
struct bwn_phy_n *nphy = phy->phy_n; | struct bwn_phy_n *nphy = phy->phy_n; | ||||
uint8_t tx_pwr_state; | uint8_t tx_pwr_state; | ||||
struct bwn_nphy_txgains target; | struct bwn_nphy_txgains target; | ||||
int error; | |||||
uint16_t tmp; | uint16_t tmp; | ||||
bwn_band_t tmp2; | bwn_band_t tmp2; | ||||
bool do_rssi_cal; | bool do_rssi_cal; | ||||
uint16_t clip[2]; | uint16_t clip[2]; | ||||
bool do_cal = false; | bool do_cal = false; | ||||
if (mac->mac_phy.rev >= 3) { | |||||
error = bhnd_nvram_getvar_uint8(sc->sc_dev, BHND_NVAR_TSSIPOS2G, | |||||
&nphy->tsspos_2g); | |||||
if (error) { | |||||
BWN_ERRPRINTF(mac->mac_sc, "Error reading %s from " | |||||
"NVRAM: %d\n", BHND_NVAR_TSSIPOS2G, error); | |||||
return (error); | |||||
} | |||||
} else { | |||||
nphy->tsspos_2g = 0; | |||||
} | |||||
if ((mac->mac_phy.rev >= 3) && | if ((mac->mac_phy.rev >= 3) && | ||||
(siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) && | (sc->sc_board_info.board_flags & BHND_BFL_EXTLNA) && | ||||
(bwn_current_band(mac) == BWN_BAND_2G)) { | (bwn_current_band(mac) == BWN_BAND_2G)) | ||||
siba_cc_set32(sc->sc_dev, SIBA_CC_CHIPCTL, 0x40); | { | ||||
BHND_CHIPC_WRITE_CHIPCTRL(sc->sc_chipc, 0x40, 0x40); | |||||
} | } | ||||
nphy->use_int_tx_iq_lo_cal = bwn_nphy_ipa(mac) || | nphy->use_int_tx_iq_lo_cal = bwn_nphy_ipa(mac) || | ||||
phy->rev >= 7 || | phy->rev >= 7 || | ||||
(phy->rev >= 5 && | (phy->rev >= 5 && | ||||
siba_sprom_get_bf2_hi(sc->sc_dev) & BWN_BFH2_INTERNDET_TXIQCAL); | sc->sc_board_info.board_flags2 & BHND_BFL2_INTERNDET_TXIQCAL); | ||||
nphy->deaf_count = 0; | nphy->deaf_count = 0; | ||||
bwn_nphy_tables_init(mac); | bwn_nphy_tables_init(mac); | ||||
nphy->crsminpwr_adjusted = false; | nphy->crsminpwr_adjusted = false; | ||||
nphy->noisevars_adjusted = false; | nphy->noisevars_adjusted = false; | ||||
/* Clear all overrides */ | /* Clear all overrides */ | ||||
if (mac->mac_phy.rev >= 3) { | if (mac->mac_phy.rev >= 3) { | ||||
BWN_PHY_WRITE(mac, BWN_NPHY_TXF_40CO_B1S1, 0); | BWN_PHY_WRITE(mac, BWN_NPHY_TXF_40CO_B1S1, 0); | ||||
Show All 30 Lines | if (mac->mac_phy.rev <= 2) { | ||||
tmp = (mac->mac_phy.rev == 2) ? 0x3B : 0x40; | tmp = (mac->mac_phy.rev == 2) ? 0x3B : 0x40; | ||||
BWN_PHY_SETMASK(mac, BWN_NPHY_BPHY_CTL3, | BWN_PHY_SETMASK(mac, BWN_NPHY_BPHY_CTL3, | ||||
~BWN_NPHY_BPHY_CTL3_SCALE, | ~BWN_NPHY_BPHY_CTL3_SCALE, | ||||
tmp << BWN_NPHY_BPHY_CTL3_SCALE_SHIFT); | tmp << BWN_NPHY_BPHY_CTL3_SCALE_SHIFT); | ||||
} | } | ||||
BWN_PHY_WRITE(mac, BWN_NPHY_AFESEQ_TX2RX_PUD_20M, 0x20); | BWN_PHY_WRITE(mac, BWN_NPHY_AFESEQ_TX2RX_PUD_20M, 0x20); | ||||
BWN_PHY_WRITE(mac, BWN_NPHY_AFESEQ_TX2RX_PUD_40M, 0x20); | BWN_PHY_WRITE(mac, BWN_NPHY_AFESEQ_TX2RX_PUD_40M, 0x20); | ||||
if (siba_sprom_get_bf2_lo(sc->sc_dev) & BWN_BFL2_SKWRKFEM_BRD || | if (sc->sc_board_info.board_flags2 & BHND_BFL2_SKWRKFEM_BRD || | ||||
(siba_get_pci_subvendor(sc->sc_dev) == PCI_VENDOR_APPLE && | (sc->sc_board_info.board_vendor == PCI_VENDOR_APPLE && | ||||
siba_get_pci_subdevice(sc->sc_dev) == BCMA_BOARD_TYPE_BCM943224M93)) | sc->sc_board_info.board_type == BHND_BOARD_BCM943224M93)) | ||||
BWN_PHY_WRITE(mac, BWN_NPHY_TXREALFD, 0xA0); | BWN_PHY_WRITE(mac, BWN_NPHY_TXREALFD, 0xA0); | ||||
else | else | ||||
BWN_PHY_WRITE(mac, BWN_NPHY_TXREALFD, 0xB8); | BWN_PHY_WRITE(mac, BWN_NPHY_TXREALFD, 0xB8); | ||||
BWN_PHY_WRITE(mac, BWN_NPHY_MIMO_CRSTXEXT, 0xC8); | BWN_PHY_WRITE(mac, BWN_NPHY_MIMO_CRSTXEXT, 0xC8); | ||||
BWN_PHY_WRITE(mac, BWN_NPHY_PLOAD_CSENSE_EXTLEN, 0x50); | BWN_PHY_WRITE(mac, BWN_NPHY_PLOAD_CSENSE_EXTLEN, 0x50); | ||||
BWN_PHY_WRITE(mac, BWN_NPHY_TXRIFS_FRDEL, 0x30); | BWN_PHY_WRITE(mac, BWN_NPHY_TXRIFS_FRDEL, 0x30); | ||||
if (phy->rev < 8) | if (phy->rev < 8) | ||||
Show All 14 Lines | if (bwn_nphy_ipa(mac)) { | ||||
BWN_PHY_SET(mac, BWN_NPHY_PAPD_EN1, 0x1); | BWN_PHY_SET(mac, BWN_NPHY_PAPD_EN1, 0x1); | ||||
BWN_PHY_SETMASK(mac, BWN_NPHY_EPS_TABLE_ADJ1, 0x007F, | BWN_PHY_SETMASK(mac, BWN_NPHY_EPS_TABLE_ADJ1, 0x007F, | ||||
nphy->papd_epsilon_offset[1] << 7); | nphy->papd_epsilon_offset[1] << 7); | ||||
bwn_nphy_int_pa_set_tx_dig_filters(mac); | bwn_nphy_int_pa_set_tx_dig_filters(mac); | ||||
} else if (phy->rev >= 5) { | } else if (phy->rev >= 5) { | ||||
bwn_nphy_ext_pa_set_tx_dig_filters(mac); | bwn_nphy_ext_pa_set_tx_dig_filters(mac); | ||||
} | } | ||||
bwn_nphy_workarounds(mac); | if ((error = bwn_nphy_workarounds(mac))) | ||||
return (error); | |||||
/* Reset CCA, in init code it differs a little from standard way */ | /* Reset CCA, in init code it differs a little from standard way */ | ||||
bwn_phy_force_clock(mac, 1); | bwn_phy_force_clock(mac, 1); | ||||
tmp = BWN_PHY_READ(mac, BWN_NPHY_BBCFG); | tmp = BWN_PHY_READ(mac, BWN_NPHY_BBCFG); | ||||
BWN_PHY_WRITE(mac, BWN_NPHY_BBCFG, tmp | BWN_NPHY_BBCFG_RSTCCA); | BWN_PHY_WRITE(mac, BWN_NPHY_BBCFG, tmp | BWN_NPHY_BBCFG_RSTCCA); | ||||
BWN_PHY_WRITE(mac, BWN_NPHY_BBCFG, tmp & ~BWN_NPHY_BBCFG_RSTCCA); | BWN_PHY_WRITE(mac, BWN_NPHY_BBCFG, tmp & ~BWN_NPHY_BBCFG_RSTCCA); | ||||
bwn_phy_force_clock(mac, 0); | bwn_phy_force_clock(mac, 0); | ||||
bwn_mac_phy_clock_set(mac, true); | bwn_mac_phy_clock_set(mac, true); | ||||
if (phy->rev < 7) { | if (phy->rev < 7) { | ||||
bwn_nphy_pa_override(mac, false); | bwn_nphy_pa_override(mac, false); | ||||
bwn_nphy_force_rf_sequence(mac, BWN_RFSEQ_RX2TX); | bwn_nphy_force_rf_sequence(mac, BWN_RFSEQ_RX2TX); | ||||
bwn_nphy_force_rf_sequence(mac, BWN_RFSEQ_RESET2RX); | bwn_nphy_force_rf_sequence(mac, BWN_RFSEQ_RESET2RX); | ||||
bwn_nphy_pa_override(mac, true); | bwn_nphy_pa_override(mac, true); | ||||
} | } | ||||
bwn_nphy_classifier(mac, 0, 0); | bwn_nphy_classifier(mac, 0, 0); | ||||
bwn_nphy_read_clip_detection(mac, clip); | bwn_nphy_read_clip_detection(mac, clip); | ||||
if (bwn_current_band(mac) == BWN_BAND_2G) | if (bwn_current_band(mac) == BWN_BAND_2G) | ||||
bwn_nphy_bphy_init(mac); | bwn_nphy_bphy_init(mac); | ||||
tx_pwr_state = nphy->txpwrctrl; | tx_pwr_state = nphy->txpwrctrl; | ||||
bwn_nphy_tx_power_ctrl(mac, false); | bwn_nphy_tx_power_ctrl(mac, false); | ||||
bwn_nphy_tx_power_fix(mac); | if ((error = bwn_nphy_tx_power_fix(mac))) | ||||
return (error); | |||||
bwn_nphy_tx_power_ctl_idle_tssi(mac); | bwn_nphy_tx_power_ctl_idle_tssi(mac); | ||||
bwn_nphy_tx_power_ctl_setup(mac); | bwn_nphy_tx_power_ctl_setup(mac); | ||||
bwn_nphy_tx_gain_table_upload(mac); | bwn_nphy_tx_gain_table_upload(mac); | ||||
if (nphy->phyrxchain != 3) | if (nphy->phyrxchain != 3) | ||||
bwn_nphy_set_rx_core_state(mac, nphy->phyrxchain); | bwn_nphy_set_rx_core_state(mac, nphy->phyrxchain); | ||||
if (nphy->mphase_cal_phase_id > 0) | if (nphy->mphase_cal_phase_id > 0) | ||||
;/* TODO PHY Periodic Calibration Multi-Phase Restart */ | ;/* TODO PHY Periodic Calibration Multi-Phase Restart */ | ||||
Show All 20 Lines | else | ||||
do_cal = !nphy->iqcal_chanspec_5G.center_freq; | do_cal = !nphy->iqcal_chanspec_5G.center_freq; | ||||
if (nphy->mute) | if (nphy->mute) | ||||
do_cal = false; | do_cal = false; | ||||
if (do_cal) { | if (do_cal) { | ||||
target = bwn_nphy_get_tx_gains(mac); | target = bwn_nphy_get_tx_gains(mac); | ||||
if (nphy->antsel_type == 2) | if (nphy->antsel_type == 2) { | ||||
bwn_nphy_superswitch_init(mac, true); | error = bwn_nphy_superswitch_init(mac, true); | ||||
if (error) | |||||
return (error); | |||||
} | |||||
if (nphy->perical != 2) { | if (nphy->perical != 2) { | ||||
bwn_nphy_rssi_cal(mac); | bwn_nphy_rssi_cal(mac); | ||||
if (phy->rev >= 3) { | if (phy->rev >= 3) { | ||||
nphy->cal_orig_pwr_idx[0] = | nphy->cal_orig_pwr_idx[0] = | ||||
nphy->txpwrindex[0].index_internal; | nphy->txpwrindex[0].index_internal; | ||||
nphy->cal_orig_pwr_idx[1] = | nphy->cal_orig_pwr_idx[1] = | ||||
nphy->txpwrindex[1].index_internal; | nphy->txpwrindex[1].index_internal; | ||||
/* TODO N PHY Pre Calibrate TX Gain */ | /* TODO N PHY Pre Calibrate TX Gain */ | ||||
Show All 33 Lines | static void bwn_chantab_phy_upload(struct bwn_mac *mac, | ||||
BWN_PHY_WRITE(mac, BWN_NPHY_BW2, e->phy_bw2); | BWN_PHY_WRITE(mac, BWN_NPHY_BW2, e->phy_bw2); | ||||
BWN_PHY_WRITE(mac, BWN_NPHY_BW3, e->phy_bw3); | BWN_PHY_WRITE(mac, BWN_NPHY_BW3, e->phy_bw3); | ||||
BWN_PHY_WRITE(mac, BWN_NPHY_BW4, e->phy_bw4); | BWN_PHY_WRITE(mac, BWN_NPHY_BW4, e->phy_bw4); | ||||
BWN_PHY_WRITE(mac, BWN_NPHY_BW5, e->phy_bw5); | BWN_PHY_WRITE(mac, BWN_NPHY_BW5, e->phy_bw5); | ||||
BWN_PHY_WRITE(mac, BWN_NPHY_BW6, e->phy_bw6); | BWN_PHY_WRITE(mac, BWN_NPHY_BW6, e->phy_bw6); | ||||
} | } | ||||
/* http://bcm-v4.sipsolutions.net/802.11/PmuSpurAvoid */ | /* http://bcm-v4.sipsolutions.net/802.11/PmuSpurAvoid */ | ||||
static void bwn_nphy_pmu_spur_avoid(struct bwn_mac *mac, bool avoid) | static void bwn_nphy_pmu_spur_avoid(struct bwn_mac *mac, | ||||
bhnd_pmu_spuravoid mode) | |||||
{ | { | ||||
struct bwn_softc *sc = mac->mac_sc; | struct bwn_softc *sc = mac->mac_sc; | ||||
int error; | |||||
DPRINTF(sc, BWN_DEBUG_RESET, "%s: spuravoid %d\n", __func__, avoid); | DPRINTF(sc, BWN_DEBUG_RESET, "%s: spuravoid %d\n", __func__, mode); | ||||
siba_pmu_spuravoid_pllupdate(sc->sc_dev, avoid); | |||||
if (sc->sc_pmu == NULL) { | |||||
BWN_ERRPRINTF(mac->mac_sc, "no PMU; cannot configure spurious " | |||||
"signal avoidance\n"); | |||||
return; | |||||
} | } | ||||
if ((error = bhnd_pmu_request_spuravoid(sc->sc_pmu, mode))) { | |||||
device_printf(sc->sc_dev, "spuravoid request failed: %d", | |||||
error); | |||||
} | |||||
} | |||||
/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ChanspecSetup */ | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ChanspecSetup */ | ||||
static void bwn_nphy_channel_setup(struct bwn_mac *mac, | static int bwn_nphy_channel_setup(struct bwn_mac *mac, | ||||
const struct bwn_phy_n_sfo_cfg *e, | const struct bwn_phy_n_sfo_cfg *e, | ||||
struct ieee80211_channel *new_channel) | struct ieee80211_channel *new_channel) | ||||
{ | { | ||||
struct bwn_softc *sc = mac->mac_sc; | struct bwn_softc *sc = mac->mac_sc; | ||||
struct bwn_phy *phy = &mac->mac_phy; | struct bwn_phy *phy = &mac->mac_phy; | ||||
struct bwn_phy_n *nphy = mac->mac_phy.phy_n; | struct bwn_phy_n *nphy = mac->mac_phy.phy_n; | ||||
int ch = new_channel->ic_ieee; | int ch = new_channel->ic_ieee; | ||||
int error; | |||||
uint16_t tmp16; | uint16_t tmp16; | ||||
if (bwn_channel_band(mac, new_channel) == BWN_BAND_5G) { | if (bwn_channel_band(mac, new_channel) == BWN_BAND_5G) { | ||||
DPRINTF(sc, BWN_DEBUG_RESET, "%s: BAND_5G; chan=%d\n", __func__, ch); | DPRINTF(sc, BWN_DEBUG_RESET, "%s: BAND_5G; chan=%d\n", __func__, ch); | ||||
/* Switch to 2 GHz for a moment to access BWN_PHY_B_BBCFG */ | /* Switch to 2 GHz for a moment to access BWN_PHY_B_BBCFG */ | ||||
BWN_PHY_MASK(mac, BWN_NPHY_BANDCTL, ~BWN_NPHY_BANDCTL_5GHZ); | BWN_PHY_MASK(mac, BWN_NPHY_BANDCTL, ~BWN_NPHY_BANDCTL_5GHZ); | ||||
tmp16 = BWN_READ_2(mac, BWN_PSM_PHY_HDR); | tmp16 = BWN_READ_2(mac, BWN_PSM_PHY_HDR); | ||||
Show All 22 Lines | if (new_channel->ic_ieee == 14) { | ||||
bwn_nphy_classifier(mac, 2, 0); | bwn_nphy_classifier(mac, 2, 0); | ||||
BWN_PHY_SET(mac, BWN_PHY_B_TEST, 0x0800); | BWN_PHY_SET(mac, BWN_PHY_B_TEST, 0x0800); | ||||
} else { | } else { | ||||
bwn_nphy_classifier(mac, 2, 2); | bwn_nphy_classifier(mac, 2, 2); | ||||
if (bwn_channel_band(mac, new_channel) == BWN_BAND_2G) | if (bwn_channel_band(mac, new_channel) == BWN_BAND_2G) | ||||
BWN_PHY_MASK(mac, BWN_PHY_B_TEST, ~0x840); | BWN_PHY_MASK(mac, BWN_PHY_B_TEST, ~0x840); | ||||
} | } | ||||
if (!nphy->txpwrctrl) | if (!nphy->txpwrctrl) { | ||||
bwn_nphy_tx_power_fix(mac); | if ((error = bwn_nphy_tx_power_fix(mac))) | ||||
return (error); | |||||
} | |||||
if (mac->mac_phy.rev < 3) | if (mac->mac_phy.rev < 3) | ||||
bwn_nphy_adjust_lna_gain_table(mac); | bwn_nphy_adjust_lna_gain_table(mac); | ||||
bwn_nphy_tx_lpf_bw(mac); | bwn_nphy_tx_lpf_bw(mac); | ||||
if (mac->mac_phy.rev >= 3 && | if (mac->mac_phy.rev >= 3 && | ||||
mac->mac_phy.phy_n->spur_avoid != BWN_SPUR_AVOID_DISABLE) { | mac->mac_phy.phy_n->spur_avoid != BWN_SPUR_AVOID_DISABLE) { | ||||
uint8_t spuravoid = 0; | bhnd_pmu_spuravoid spuravoid = BHND_PMU_SPURAVOID_NONE; | ||||
if (mac->mac_phy.phy_n->spur_avoid == BWN_SPUR_AVOID_FORCE) { | if (mac->mac_phy.phy_n->spur_avoid == BWN_SPUR_AVOID_FORCE) { | ||||
spuravoid = 1; | spuravoid = BHND_PMU_SPURAVOID_M1; | ||||
} else if (phy->rev >= 19) { | } else if (phy->rev >= 19) { | ||||
/* TODO */ | /* TODO */ | ||||
} else if (phy->rev >= 18) { | } else if (phy->rev >= 18) { | ||||
/* TODO */ | /* TODO */ | ||||
} else if (phy->rev >= 17) { | } else if (phy->rev >= 17) { | ||||
/* TODO: Off for channels 1-11, but check 12-14! */ | /* TODO: Off for channels 1-11, but check 12-14! */ | ||||
} else if (phy->rev >= 16) { | } else if (phy->rev >= 16) { | ||||
/* TODO: Off for 2 GHz, but check 5 GHz! */ | /* TODO: Off for 2 GHz, but check 5 GHz! */ | ||||
} else if (phy->rev >= 7) { | } else if (phy->rev >= 7) { | ||||
if (!bwn_is_40mhz(mac)) { /* 20MHz */ | if (!bwn_is_40mhz(mac)) { /* 20MHz */ | ||||
if (ch == 13 || ch == 14 || ch == 153) | if (ch == 13 || ch == 14 || ch == 153) | ||||
spuravoid = 1; | spuravoid = BHND_PMU_SPURAVOID_M1; | ||||
} else { /* 40 MHz */ | } else { /* 40 MHz */ | ||||
if (ch == 54) | if (ch == 54) | ||||
spuravoid = 1; | spuravoid = BHND_PMU_SPURAVOID_M1; | ||||
} | } | ||||
} else { | } else { | ||||
if (!bwn_is_40mhz(mac)) { /* 20MHz */ | if (!bwn_is_40mhz(mac)) { /* 20MHz */ | ||||
if ((ch >= 5 && ch <= 8) || ch == 13 || ch == 14) | if ((ch >= 5 && ch <= 8) || ch == 13 || ch == 14) | ||||
spuravoid = 1; | spuravoid = BHND_PMU_SPURAVOID_M1; | ||||
} else { /* 40MHz */ | } else { /* 40MHz */ | ||||
if (nphy->aband_spurwar_en && | if (nphy->aband_spurwar_en && | ||||
(ch == 38 || ch == 102 || ch == 118)) | (ch == 38 || ch == 102 || ch == 118) && | ||||
spuravoid = siba_get_chipid(sc->sc_dev) == 0x4716; | sc->sc_cid.chip_id == BHND_CHIPID_BCM4716) | ||||
spuravoid = BHND_PMU_SPURAVOID_M1; | |||||
} | } | ||||
} | } | ||||
bwn_nphy_pmu_spur_avoid(mac, spuravoid); | bwn_nphy_pmu_spur_avoid(mac, spuravoid); | ||||
bwn_mac_switch_freq(mac, spuravoid); | bwn_mac_switch_freq(mac, spuravoid); | ||||
if (mac->mac_phy.rev == 3 || mac->mac_phy.rev == 4) | if (mac->mac_phy.rev == 3 || mac->mac_phy.rev == 4) | ||||
bwn_wireless_core_phy_pll_reset(mac); | bwn_wireless_core_phy_pll_reset(mac); | ||||
if (spuravoid) | if (spuravoid != BHND_PMU_SPURAVOID_NONE) | ||||
BWN_PHY_SET(mac, BWN_NPHY_BBCFG, BWN_NPHY_BBCFG_RSTRX); | BWN_PHY_SET(mac, BWN_NPHY_BBCFG, BWN_NPHY_BBCFG_RSTRX); | ||||
else | else | ||||
BWN_PHY_MASK(mac, BWN_NPHY_BBCFG, | BWN_PHY_MASK(mac, BWN_NPHY_BBCFG, | ||||
~BWN_NPHY_BBCFG_RSTRX & 0xFFFF); | ~BWN_NPHY_BBCFG_RSTRX & 0xFFFF); | ||||
bwn_nphy_reset_cca(mac); | bwn_nphy_reset_cca(mac); | ||||
/* wl sets useless phy_isspuravoid here */ | /* wl sets useless phy_isspuravoid here */ | ||||
} | } | ||||
BWN_PHY_WRITE(mac, BWN_NPHY_NDATAT_DUP40, 0x3830); | BWN_PHY_WRITE(mac, BWN_NPHY_NDATAT_DUP40, 0x3830); | ||||
if (phy->rev >= 3) | if (phy->rev >= 3) | ||||
bwn_nphy_spur_workaround(mac); | bwn_nphy_spur_workaround(mac); | ||||
return (0); | |||||
} | } | ||||
/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SetChanspec */ | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SetChanspec */ | ||||
static int bwn_nphy_set_channel(struct bwn_mac *mac, | static int bwn_nphy_set_channel(struct bwn_mac *mac, | ||||
struct ieee80211_channel *channel, | struct ieee80211_channel *channel, | ||||
bwn_chan_type_t channel_type) | bwn_chan_type_t channel_type) | ||||
{ | { | ||||
struct bwn_phy *phy = &mac->mac_phy; | struct bwn_phy *phy = &mac->mac_phy; | ||||
const struct bwn_nphy_channeltab_entry_rev2 *tabent_r2 = NULL; | const struct bwn_nphy_channeltab_entry_rev2 *tabent_r2 = NULL; | ||||
const struct bwn_nphy_channeltab_entry_rev3 *tabent_r3 = NULL; | const struct bwn_nphy_channeltab_entry_rev3 *tabent_r3 = NULL; | ||||
const struct bwn_nphy_chantabent_rev7 *tabent_r7 = NULL; | const struct bwn_nphy_chantabent_rev7 *tabent_r7 = NULL; | ||||
const struct bwn_nphy_chantabent_rev7_2g *tabent_r7_2g = NULL; | const struct bwn_nphy_chantabent_rev7_2g *tabent_r7_2g = NULL; | ||||
int error; | |||||
uint8_t tmp; | uint8_t tmp; | ||||
if (phy->rev >= 19) { | if (phy->rev >= 19) { | ||||
return -ESRCH; | return -ESRCH; | ||||
/* TODO */ | /* TODO */ | ||||
} else if (phy->rev >= 7) { | } else if (phy->rev >= 7) { | ||||
r2057_get_chantabent_rev7(mac, bwn_get_chan_centre_freq(mac, channel), | r2057_get_chantabent_rev7(mac, bwn_get_chan_centre_freq(mac, channel), | ||||
&tabent_r7, &tabent_r7_2g); | &tabent_r7, &tabent_r7_2g); | ||||
Show All 30 Lines | #endif | ||||
} else if (channel_type == BWN_CHAN_TYPE_40_HT_D) { | } else if (channel_type == BWN_CHAN_TYPE_40_HT_D) { | ||||
BWN_PHY_MASK(mac, BWN_NPHY_RXCTL, ~BWN_NPHY_RXCTL_BSELU20); | BWN_PHY_MASK(mac, BWN_NPHY_RXCTL, ~BWN_NPHY_RXCTL_BSELU20); | ||||
if (phy->rev >= 7) | if (phy->rev >= 7) | ||||
BWN_PHY_MASK(mac, 0x310, (uint16_t)~0x8000); | BWN_PHY_MASK(mac, 0x310, (uint16_t)~0x8000); | ||||
} | } | ||||
if (phy->rev >= 19) { | if (phy->rev >= 19) { | ||||
/* TODO */ | /* TODO */ | ||||
error = ENODEV; | |||||
} else if (phy->rev >= 7) { | } else if (phy->rev >= 7) { | ||||
const struct bwn_phy_n_sfo_cfg *phy_regs = tabent_r7 ? | const struct bwn_phy_n_sfo_cfg *phy_regs = tabent_r7 ? | ||||
&(tabent_r7->phy_regs) : &(tabent_r7_2g->phy_regs); | &(tabent_r7->phy_regs) : &(tabent_r7_2g->phy_regs); | ||||
if (phy->rf_rev <= 4 || phy->rf_rev == 6) { | if (phy->rf_rev <= 4 || phy->rf_rev == 6) { | ||||
tmp = (bwn_channel_band(mac, channel) == BWN_BAND_5G) ? 2 : 0; | tmp = (bwn_channel_band(mac, channel) == BWN_BAND_5G) ? 2 : 0; | ||||
BWN_RF_SETMASK(mac, R2057_TIA_CONFIG_CORE0, ~2, tmp); | BWN_RF_SETMASK(mac, R2057_TIA_CONFIG_CORE0, ~2, tmp); | ||||
BWN_RF_SETMASK(mac, R2057_TIA_CONFIG_CORE1, ~2, tmp); | BWN_RF_SETMASK(mac, R2057_TIA_CONFIG_CORE1, ~2, tmp); | ||||
} | } | ||||
bwn_radio_2057_setup(mac, tabent_r7, tabent_r7_2g); | bwn_radio_2057_setup(mac, tabent_r7, tabent_r7_2g); | ||||
bwn_nphy_channel_setup(mac, phy_regs, channel); | error = bwn_nphy_channel_setup(mac, phy_regs, channel); | ||||
} else if (phy->rev >= 3) { | } else if (phy->rev >= 3) { | ||||
tmp = (bwn_channel_band(mac, channel) == BWN_BAND_5G) ? 4 : 0; | tmp = (bwn_channel_band(mac, channel) == BWN_BAND_5G) ? 4 : 0; | ||||
BWN_RF_SETMASK(mac, 0x08, 0xFFFB, tmp); | BWN_RF_SETMASK(mac, 0x08, 0xFFFB, tmp); | ||||
bwn_radio_2056_setup(mac, tabent_r3); | bwn_radio_2056_setup(mac, tabent_r3); | ||||
bwn_nphy_channel_setup(mac, &(tabent_r3->phy_regs), channel); | error = bwn_nphy_channel_setup(mac, &(tabent_r3->phy_regs), | ||||
channel); | |||||
} else { | } else { | ||||
tmp = (bwn_channel_band(mac, channel) == BWN_BAND_5G) ? 0x0020 : 0x0050; | tmp = (bwn_channel_band(mac, channel) == BWN_BAND_5G) ? 0x0020 : 0x0050; | ||||
BWN_RF_SETMASK(mac, B2055_MASTER1, 0xFF8F, tmp); | BWN_RF_SETMASK(mac, B2055_MASTER1, 0xFF8F, tmp); | ||||
bwn_radio_2055_setup(mac, tabent_r2); | bwn_radio_2055_setup(mac, tabent_r2); | ||||
bwn_nphy_channel_setup(mac, &(tabent_r2->phy_regs), channel); | error = bwn_nphy_channel_setup(mac, &(tabent_r2->phy_regs), | ||||
channel); | |||||
} | } | ||||
return 0; | return (error); | ||||
} | } | ||||
/************************************************** | /************************************************** | ||||
* Basic PHY ops. | * Basic PHY ops. | ||||
**************************************************/ | **************************************************/ | ||||
int | int | ||||
bwn_nphy_op_allocate(struct bwn_mac *mac) | bwn_nphy_op_allocate(struct bwn_mac *mac) | ||||
{ | { | ||||
struct bwn_phy_n *nphy; | struct bwn_phy_n *nphy; | ||||
nphy = malloc(sizeof(*nphy), M_DEVBUF, M_ZERO | M_NOWAIT); | nphy = malloc(sizeof(*nphy), M_DEVBUF, M_ZERO | M_NOWAIT); | ||||
if (!nphy) | if (!nphy) | ||||
return -ENOMEM; | return -ENOMEM; | ||||
mac->mac_phy.phy_n = nphy; | mac->mac_phy.phy_n = nphy; | ||||
return 0; | return 0; | ||||
} | } | ||||
void | int | ||||
bwn_nphy_op_prepare_structs(struct bwn_mac *mac) | bwn_nphy_op_prepare_structs(struct bwn_mac *mac) | ||||
{ | { | ||||
struct bwn_softc *sc = mac->mac_sc; | struct bwn_softc *sc = mac->mac_sc; | ||||
struct bwn_phy *phy = &mac->mac_phy; | struct bwn_phy *phy = &mac->mac_phy; | ||||
struct bwn_phy_n *nphy = phy->phy_n; | struct bwn_phy_n *nphy = phy->phy_n; | ||||
int error; | |||||
memset(nphy, 0, sizeof(*nphy)); | memset(nphy, 0, sizeof(*nphy)); | ||||
nphy->hang_avoid = (phy->rev == 3 || phy->rev == 4); | nphy->hang_avoid = (phy->rev == 3 || phy->rev == 4); | ||||
nphy->spur_avoid = (phy->rev >= 3) ? | nphy->spur_avoid = (phy->rev >= 3) ? | ||||
BWN_SPUR_AVOID_AUTO : BWN_SPUR_AVOID_DISABLE; | BWN_SPUR_AVOID_AUTO : BWN_SPUR_AVOID_DISABLE; | ||||
nphy->gain_boost = true; /* this way we follow wl, assume it is true */ | nphy->gain_boost = true; /* this way we follow wl, assume it is true */ | ||||
nphy->txrx_chain = 2; /* sth different than 0 and 1 for now */ | nphy->txrx_chain = 2; /* sth different than 0 and 1 for now */ | ||||
nphy->phyrxchain = 3; /* to avoid bwn_nphy_set_rx_core_state like wl */ | nphy->phyrxchain = 3; /* to avoid bwn_nphy_set_rx_core_state like wl */ | ||||
nphy->perical = 2; /* avoid additional rssi cal on init (like wl) */ | nphy->perical = 2; /* avoid additional rssi cal on init (like wl) */ | ||||
/* 128 can mean disabled-by-default state of TX pwr ctl. Max value is | /* 128 can mean disabled-by-default state of TX pwr ctl. Max value is | ||||
* 0x7f == 127 and we check for 128 when restoring TX pwr ctl. */ | * 0x7f == 127 and we check for 128 when restoring TX pwr ctl. */ | ||||
nphy->tx_pwr_idx[0] = 128; | nphy->tx_pwr_idx[0] = 128; | ||||
nphy->tx_pwr_idx[1] = 128; | nphy->tx_pwr_idx[1] = 128; | ||||
/* Hardware TX power control and 5GHz power gain */ | /* Hardware TX power control and 5GHz power gain */ | ||||
nphy->txpwrctrl = false; | nphy->txpwrctrl = false; | ||||
nphy->pwg_gain_5ghz = false; | nphy->pwg_gain_5ghz = false; | ||||
if (mac->mac_phy.rev >= 3 || | if (mac->mac_phy.rev >= 3 || | ||||
(siba_get_pci_subvendor(sc->sc_dev) == PCI_VENDOR_APPLE && | (sc->sc_board_info.board_vendor == PCI_VENDOR_APPLE && | ||||
(siba_get_revid(sc->sc_dev) == 11 || siba_get_revid(sc->sc_dev) == 12))) { | (bhnd_get_hwrev(sc->sc_dev) == 11 || bhnd_get_hwrev(sc->sc_dev) == 12))) { | ||||
nphy->txpwrctrl = true; | nphy->txpwrctrl = true; | ||||
nphy->pwg_gain_5ghz = true; | nphy->pwg_gain_5ghz = true; | ||||
} else if (siba_sprom_get_rev(sc->sc_dev) >= 4) { | } else if (sc->sc_board_info.board_srom_rev >= 4) { | ||||
if (mac->mac_phy.rev >= 2 && | if (mac->mac_phy.rev >= 2 && | ||||
(siba_sprom_get_bf2_lo(sc->sc_dev) & BWN_BFL2_TXPWRCTRL_EN)) { | (sc->sc_board_info.board_flags2 & BHND_BFL2_TXPWRCTRL_EN)) { | ||||
nphy->txpwrctrl = true; | nphy->txpwrctrl = true; | ||||
if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCI) { | if ((sc->sc_board_info.board_devid == PCI_DEVID_BCM4321_D11N) || | ||||
if ((siba_get_pci_device(sc->sc_dev) == 0x4328) || | (sc->sc_board_info.board_devid == PCI_DEVID_BCM4321_D11N5G)) | ||||
(siba_get_pci_device(sc->sc_dev) == 0x432a)) | |||||
nphy->pwg_gain_5ghz = true; | nphy->pwg_gain_5ghz = true; | ||||
} | } else if (sc->sc_board_info.board_flags2 & BHND_BFL2_5G_PWRGAIN) { | ||||
} else if (siba_sprom_get_bf2_lo(sc->sc_dev) & BWN_BFL2_5G_PWRGAIN) { | |||||
nphy->pwg_gain_5ghz = true; | nphy->pwg_gain_5ghz = true; | ||||
} | } | ||||
} | } | ||||
if (mac->mac_phy.rev >= 3) { | if (mac->mac_phy.rev >= 3) { | ||||
nphy->ipa2g_on = siba_sprom_get_fem_2ghz_extpa_gain(sc->sc_dev) == 2; | uint8_t extpa_gain2g, extpa_gain5g; | ||||
nphy->ipa5g_on = siba_sprom_get_fem_5ghz_extpa_gain(sc->sc_dev) == 2; | |||||
error = bhnd_nvram_getvar_uint8(sc->sc_dev, | |||||
BHND_NVAR_EXTPAGAIN2G, &extpa_gain2g); | |||||
if (error) { | |||||
BWN_ERRPRINTF(mac->mac_sc, "Error reading 2GHz EPA " | |||||
"gain configuration from NVRAM: %d\n", error); | |||||
return (error); | |||||
} | } | ||||
error = bhnd_nvram_getvar_uint8(sc->sc_dev, | |||||
BHND_NVAR_EXTPAGAIN5G, &extpa_gain5g); | |||||
if (error) { | |||||
BWN_ERRPRINTF(mac->mac_sc, "Error reading 5GHz EPA " | |||||
"gain configuration from NVRAM: %d\n", error); | |||||
return (error); | |||||
} | |||||
nphy->ipa2g_on = (extpa_gain2g == 2); | |||||
nphy->ipa5g_on = (extpa_gain5g == 2); | |||||
} | |||||
return (0); | |||||
} | } | ||||
void | void | ||||
bwn_nphy_op_free(struct bwn_mac *mac) | bwn_nphy_op_free(struct bwn_mac *mac) | ||||
{ | { | ||||
struct bwn_phy *phy = &mac->mac_phy; | struct bwn_phy *phy = &mac->mac_phy; | ||||
struct bwn_phy_n *nphy = phy->phy_n; | struct bwn_phy_n *nphy = phy->phy_n; | ||||
▲ Show 20 Lines • Show All 186 Lines • Show Last 20 Lines |