diff options
| author | Landon J. Fuller <landonf@FreeBSD.org> | 2018-02-05 23:38:15 +0000 |
|---|---|---|
| committer | Landon J. Fuller <landonf@FreeBSD.org> | 2018-02-05 23:38:15 +0000 |
| commit | d177c19903e8e6ebdcdf769d1d344de4fd24f364 (patch) | |
| tree | 47b4539e5366e89d73ce905bf38edd1fe0c57199 /sys/gnu | |
| parent | 15746ef43ade36c3f233b15723a0a87dd80ec13c (diff) | |
Notes
Diffstat (limited to 'sys/gnu')
| -rw-r--r-- | sys/gnu/dev/bwn/phy_n/if_bwn_phy_n_core.c | 318 | ||||
| -rw-r--r-- | sys/gnu/dev/bwn/phy_n/if_bwn_phy_n_core.h | 3 | ||||
| -rw-r--r-- | sys/gnu/dev/bwn/phy_n/if_bwn_phy_n_ppr.c | 101 | ||||
| -rw-r--r-- | sys/gnu/dev/bwn/phy_n/if_bwn_phy_n_sprom.c | 181 | ||||
| -rw-r--r-- | sys/gnu/dev/bwn/phy_n/if_bwn_phy_n_sprom.h | 56 | ||||
| -rw-r--r-- | sys/gnu/dev/bwn/phy_n/if_bwn_phy_n_tables.c | 91 |
6 files changed, 602 insertions, 148 deletions
diff --git a/sys/gnu/dev/bwn/phy_n/if_bwn_phy_n_core.c b/sys/gnu/dev/bwn/phy_n/if_bwn_phy_n_core.c index 0e1291ea39b3..c7ecb9747e7a 100644 --- a/sys/gnu/dev/bwn/phy_n/if_bwn_phy_n_core.c +++ b/sys/gnu/dev/bwn/phy_n/if_bwn_phy_n_core.c @@ -69,23 +69,31 @@ __FBSDID("$FreeBSD$"); #include <net80211/ieee80211_phy.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_bwnvar.h> #include <dev/bwn/if_bwn_misc.h> #include <dev/bwn/if_bwn_util.h> #include <dev/bwn/if_bwn_debug.h> #include <dev/bwn/if_bwn_phy_common.h> -#include <dev/bwn/if_bwn_chipid.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_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_radio_2055.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_phy_n_core.h> +#include "bhnd_nvram_map.h" + struct bwn_nphy_txgains { uint16_t tx_lpf[2]; uint16_t txgm[2]; @@ -590,7 +598,7 @@ static uint16_t bwn_nphy_classifier(struct bwn_mac *mac, uint16_t mask, uint16_t struct bwn_softc *sc = mac->mac_sc; uint16_t tmp; - if (siba_get_revid(sc->sc_dev) == 16) + if (bhnd_get_hwrev(sc->sc_dev) == 16) bwn_mac_suspend(mac); tmp = BWN_PHY_READ(mac, BWN_NPHY_CLASSCTL); @@ -600,7 +608,7 @@ static uint16_t bwn_nphy_classifier(struct bwn_mac *mac, uint16_t mask, uint16_t tmp |= (val & mask); 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); return tmp; @@ -1232,20 +1240,20 @@ static void bwn_radio_2056_setup(struct bwn_mac *mac, } is_pkg_fab_smic = - ((siba_get_chipid(sc->sc_dev) == BCMA_CHIP_ID_BCM43224 || - siba_get_chipid(sc->sc_dev) == BCMA_CHIP_ID_BCM43225 || - siba_get_chipid(sc->sc_dev) == BCMA_CHIP_ID_BCM43421) && - siba_get_chippkg(sc->sc_dev) == BCMA_PKG_ID_BCM43224_FAB_SMIC); + ((sc->sc_cid.chip_id == BHND_CHIPID_BCM43224 || + sc->sc_cid.chip_id == BHND_CHIPID_BCM43225 || + sc->sc_cid.chip_id == BHND_CHIPID_BCM43421) && + sc->sc_cid.chip_pkg == BHND_PKGID_BCM43224_FAB_SMIC); bwn_chantab_radio_2056_upload(mac, e); 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_RF_WRITE(mac, B2056_SYN_PLL_LOOPFILTER1, 0x1F); BWN_RF_WRITE(mac, B2056_SYN_PLL_LOOPFILTER2, 0x1F); - if (siba_get_chipid(sc->sc_dev) == BCMA_CHIP_ID_BCM4716 || - siba_get_chipid(sc->sc_dev) == BCMA_CHIP_ID_BCM47162) { + if (sc->sc_cid.chip_id == BHND_CHIPID_BCM4716 || + sc->sc_cid.chip_id == BHND_CHIPID_BCM47162) { BWN_RF_WRITE(mac, B2056_SYN_PLL_LOOPFILTER4, 0x14); BWN_RF_WRITE(mac, B2056_SYN_PLL_CP2, 0); } else { @@ -1253,14 +1261,14 @@ static void bwn_radio_2056_setup(struct bwn_mac *mac, 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_RF_WRITE(mac, B2056_SYN_PLL_LOOPFILTER1, 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_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_RF_WRITE(mac, B2056_SYN_PLL_LOOPFILTER1, 0x1F); BWN_RF_WRITE(mac, B2056_SYN_PLL_LOOPFILTER2, 0x1F); @@ -1275,8 +1283,8 @@ static void bwn_radio_2056_setup(struct bwn_mac *mac, BWN_RF_WRITE(mac, offset | B2056_TX_PADG_IDAC, 0xcc); - if (siba_get_chipid(sc->sc_dev) == BCMA_CHIP_ID_BCM4716 || - siba_get_chipid(sc->sc_dev) == BCMA_CHIP_ID_BCM47162) { + if (sc->sc_cid.chip_id == BHND_CHIPID_BCM4716 || + sc->sc_cid.chip_id == BHND_CHIPID_BCM47162) { bias = 0x40; cbias = 0x45; pag_boost = 0x5; @@ -1551,14 +1559,14 @@ static void bwn_radio_init2055_post(struct bwn_mac *mac) struct bwn_phy_n *nphy = mac->mac_phy.phy_n; bool workaround = false; - if (siba_get_revid(sc->sc_dev) < 4) + if (bhnd_get_hwrev(sc->sc_dev) < 4) workaround = - (siba_get_pci_subvendor(sc->sc_dev) != SIBA_BOARDVENDOR_BCM) - && (siba_get_pci_subdevice(sc->sc_dev) == SIBA_BOARD_BCM4321) - && (siba_sprom_get_brev(sc->sc_dev) >= 0x41); + (sc->sc_board_info.board_vendor != PCI_VENDOR_BROADCOM) + && (sc->sc_board_info.board_type == BHND_BOARD_BCM4321CB2) + && (sc->sc_board_info.board_rev >= 0x41); else 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); if (workaround) { @@ -2618,8 +2626,8 @@ static void bwn_nphy_gain_ctl_workarounds_rev3(struct bwn_mac *mac) /* Prepare values */ ghz5 = BWN_PHY_READ(mac, BWN_NPHY_BANDCTL) & BWN_NPHY_BANDCTL_5GHZ; - ext_lna = ghz5 ? siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_EXTLNA_5GHZ : - siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA; + ext_lna = ghz5 ? sc->sc_board_info.board_flags & BHND_BFL_EXTLNA_5GHZ : + sc->sc_board_info.board_flags & BHND_BFL_EXTLNA; e = bwn_nphy_get_gain_ctl_workaround_ent(mac, ghz5, ext_lna); if (ghz5 && mac->mac_phy.rev >= 5) rssi_gain = 0x90; @@ -2811,7 +2819,7 @@ static void bwn_nphy_gain_ctl_workarounds(struct bwn_mac *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_phy *phy = &mac->mac_phy; @@ -3073,8 +3081,8 @@ static void bwn_nphy_workarounds_rev7plus(struct bwn_mac *mac) 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 (siba_sprom_get_rev(sc->sc_dev) && - siba_sprom_get_bf2_hi(sc->sc_dev) & BWN_BFH2_IPALVLSHIFT_3P3) { + if (sc->sc_board_info.board_srom_rev && + sc->sc_board_info.board_flags2 & BHND_BFL2_IPALVLSHIFT_3P3) { BWN_RF_WRITE(mac, 0x5, 0x05); BWN_RF_WRITE(mac, 0x6, 0x30); BWN_RF_WRITE(mac, 0x7, 0x00); @@ -3254,9 +3262,11 @@ static void bwn_nphy_workarounds_rev7plus(struct bwn_mac *mac) bwn_ntab_write_bulk(mac, BWN_NTAB16(8, 0x1C), 4, 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_phy_n *nphy = mac->mac_phy.phy_n; @@ -3287,9 +3297,11 @@ static void bwn_nphy_workarounds_rev3plus(struct bwn_mac *mac) }; uint16_t *vmid, *gain; + const char *pdet_range_var; uint8_t pdet_range; uint16_t tmp16; uint32_t tmp32; + int error; BWN_PHY_WRITE(mac, BWN_NPHY_FORCEFRONT0, 0x1f8); BWN_PHY_WRITE(mac, BWN_NPHY_FORCEFRONT1, 0x1f8); @@ -3347,9 +3359,18 @@ static void bwn_nphy_workarounds_rev3plus(struct bwn_mac *mac) bwn_ntab_write(mac, BWN_NTAB16(8, 16), 2); 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 - 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() */ vmid = vmids[min(pdet_range, 4)]; gain = gains[min(pdet_range, 4)]; @@ -3428,9 +3449,9 @@ static void bwn_nphy_workarounds_rev3plus(struct bwn_mac *mac) /* 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) || - (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)) tmp32 = 0x00088888; else @@ -3461,11 +3482,13 @@ static void bwn_nphy_workarounds_rev3plus(struct bwn_mac *mac) BWN_PHY_WRITE(mac, BWN_NPHY_ED_CRS20UDEASSERTTHRESH0, 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 */ + + 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_phy *phy = &mac->mac_phy; @@ -3477,8 +3500,8 @@ static void bwn_nphy_workarounds_rev1_2(struct bwn_mac *mac) uint8_t events2[7] = { 0x0, 0x3, 0x5, 0x4, 0x2, 0x1, 0x8 }; uint8_t delays2[7] = { 0x8, 0x6, 0x2, 0x4, 0x4, 0x6, 0x1 }; - if (siba_sprom_get_bf2_lo(sc->sc_dev) & BWN_BFL2_SKWRKFEM_BRD || - siba_get_pci_subdevice(sc->sc_dev)== BCMA_BOARD_TYPE_BCM943224M93) { + if (sc->sc_board_info.board_flags2 & BHND_BFL2_SKWRKFEM_BRD || + sc->sc_board_info.board_type == BHND_BOARD_BCM943224M93) { delays1[0] = 0x1; delays1[5] = 0x14; } @@ -3550,13 +3573,16 @@ static void bwn_nphy_workarounds_rev1_2(struct bwn_mac *mac) if (mac->mac_phy.rev == 2) BWN_PHY_SET(mac, BWN_NPHY_FINERX2_CGC, BWN_NPHY_FINERX2_CGC_DECGC); + + return (0); } /* 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_n *nphy = phy->phy_n; + int error; if (bwn_current_band(mac) == BWN_BAND_5G) bwn_nphy_classifier(mac, 1, 0); @@ -3571,14 +3597,19 @@ static void bwn_nphy_workarounds(struct bwn_mac *mac) /* TODO: rev19+ */ if (mac->mac_phy.rev >= 7) - bwn_nphy_workarounds_rev7plus(mac); + error = bwn_nphy_workarounds_rev7plus(mac); else if (mac->mac_phy.rev >= 3) - bwn_nphy_workarounds_rev3plus(mac); + error = bwn_nphy_workarounds_rev3plus(mac); else - bwn_nphy_workarounds_rev1_2(mac); + error = bwn_nphy_workarounds_rev1_2(mac); + + if (error) + return (error); if (nphy->hang_avoid) bwn_nphy_stay_in_carrier_search(mac, 0); + + return (0); } /************************************************** @@ -3852,7 +3883,7 @@ static void bwn_nphy_tx_power_ctrl(struct bwn_mac *mac, bool enable) } /* 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_phy_n *nphy = mac->mac_phy.phy_n; @@ -3872,26 +3903,40 @@ static void bwn_nphy_tx_power_fix(struct bwn_mac *mac) } else if (mac->mac_phy.rev >= 3) { txpi[0] = 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[1] = 72; } 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) { - txpi[0] = siba_sprom_get_txpid_2g_0(sc->sc_dev); - txpi[1] = siba_sprom_get_txpid_2g_1(sc->sc_dev); + BWN_NPHY_GET_TXPI(BHND_NVAR_TXPID2GA0, &txpi[0]); + BWN_NPHY_GET_TXPI(BHND_NVAR_TXPID2GA1, &txpi[1]); } else if (freq >= 4900 && freq < 5100) { - txpi[0] = siba_sprom_get_txpid_5gl_0(sc->sc_dev); - txpi[1] = siba_sprom_get_txpid_5gl_1(sc->sc_dev); + BWN_NPHY_GET_TXPI(BHND_NVAR_TXPID5GLA0, &txpi[0]); + BWN_NPHY_GET_TXPI(BHND_NVAR_TXPID5GLA1, &txpi[1]); } else if (freq >= 5100 && freq < 5500) { - txpi[0] = siba_sprom_get_txpid_5g_0(sc->sc_dev); - txpi[1] = siba_sprom_get_txpid_5g_1(sc->sc_dev); + BWN_NPHY_GET_TXPI(BHND_NVAR_TXPID5GA0, &txpi[0]); + BWN_NPHY_GET_TXPI(BHND_NVAR_TXPID5GA1, &txpi[1]); } else if (freq >= 5500) { - txpi[0] = siba_sprom_get_txpid_5gh_0(sc->sc_dev); - txpi[1] = siba_sprom_get_txpid_5gh_1(sc->sc_dev); + BWN_NPHY_GET_TXPI(BHND_NVAR_TXPID5GHA0, &txpi[0]); + BWN_NPHY_GET_TXPI(BHND_NVAR_TXPID5GHA1, &txpi[1]); } else { txpi[0] = 91; txpi[1] = 91; } + +#undef BWN_NPHY_GET_TXPI } if (mac->mac_phy.rev < 7 && (txpi[0] < 40 || txpi[0] > 100 || txpi[1] < 40 || txpi[1] > 100)) @@ -3960,6 +4005,8 @@ static void bwn_nphy_tx_power_fix(struct bwn_mac *mac) if (nphy->hang_avoid) bwn_nphy_stay_in_carrier_search(mac, 0); + + return (0); } static void bwn_nphy_ipa_internal_tssi_setup(struct bwn_mac *mac) @@ -4163,7 +4210,7 @@ static void bwn_nphy_tx_power_ctl_setup(struct bwn_mac *mac) struct bwn_softc *sc = mac->mac_sc; struct bwn_phy *phy = &mac->mac_phy; 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; int16_t a1[2], b0[2], b1[2]; @@ -4180,7 +4227,7 @@ static void bwn_nphy_tx_power_ctl_setup(struct bwn_mac *mac) for (n = 0; n < 4; 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) { BWN_ERRPRINTF(mac->mac_sc, "%s: failed to get core_pwr_info for core %d\n", @@ -4189,7 +4236,7 @@ static void bwn_nphy_tx_power_ctl_setup(struct bwn_mac *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, 0x200000); BWN_READ_4(mac, BWN_MACCTL); DELAY(1); @@ -4206,14 +4253,14 @@ static void bwn_nphy_tx_power_ctl_setup(struct bwn_mac *mac) BWN_PHY_SET(mac, BWN_NPHY_TXPCTL_CMD, 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); /* * XXX TODO: see if those bandsbelow map to 5g-lo, 5g-mid, 5g-hi in * 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[1] = nphy->pwr_ctl_info[1].idle_tssi_2g; target[0] = target[1] = 52; @@ -4270,7 +4317,7 @@ static void bwn_nphy_tx_power_ctl_setup(struct bwn_mac *mac) } 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); if (mac->mac_phy.rev >= 7) { for (c = 0; c < 2; c++) { @@ -4294,7 +4341,7 @@ static void bwn_nphy_tx_power_ctl_setup(struct bwn_mac *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, 0x200000); BWN_READ_4(mac, BWN_MACCTL); DELAY(1); @@ -4315,7 +4362,7 @@ static void bwn_nphy_tx_power_ctl_setup(struct bwn_mac *mac) ~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_PHY_WRITE(mac, BWN_NPHY_TXPCTL_N, @@ -6061,13 +6108,13 @@ bwn_nphy_op_recalc_txpower(struct bwn_mac *mac, bool ignore_tssi) tx_pwr_state = nphy->txpwrctrl; bwn_mac_suspend(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_READ_4(mac, BWN_MACCTL); DELAY(1); } 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_mac_enable(mac); @@ -6115,16 +6162,16 @@ static void bwn_nphy_bphy_init(struct bwn_mac *mac) } /* 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) - return; + return (0); if (mac->mac_phy.rev >= 3) { if (!init) - return; + return (0); if (0 /* FIXME */) { bwn_ntab_write(mac, BWN_NTAB16(9, 2), 0x211); bwn_ntab_write(mac, BWN_NTAB16(9, 3), 0x222); @@ -6135,7 +6182,8 @@ static void bwn_nphy_superswitch_init(struct bwn_mac *mac, bool init) BWN_PHY_WRITE(mac, BWN_NPHY_GPIO_LOOEN, 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_SETMASK2(mac, BWN_GPIO_MASK, ~0, 0xFC00); @@ -6149,6 +6197,8 @@ static void bwn_nphy_superswitch_init(struct bwn_mac *mac, bool init) BWN_PHY_WRITE(mac, BWN_NPHY_RFCTL_LUT_TRSW_UP2, 0x301); } } + + return (0); } /* http://bcm-v4.sipsolutions.net/802.11/PHY/Init/N */ @@ -6159,6 +6209,7 @@ static int bwn_phy_initn(struct bwn_mac *mac) struct bwn_phy_n *nphy = phy->phy_n; uint8_t tx_pwr_state; struct bwn_nphy_txgains target; + int error; uint16_t tmp; bwn_band_t tmp2; bool do_rssi_cal; @@ -6166,15 +6217,28 @@ static int bwn_phy_initn(struct bwn_mac *mac) uint16_t clip[2]; 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) && - (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_EXTLNA) && - (bwn_current_band(mac) == BWN_BAND_2G)) { - siba_cc_set32(sc->sc_dev, SIBA_CC_CHIPCTL, 0x40); + (sc->sc_board_info.board_flags & BHND_BFL_EXTLNA) && + (bwn_current_band(mac) == BWN_BAND_2G)) + { + BHND_CHIPC_WRITE_CHIPCTRL(sc->sc_chipc, 0x40, 0x40); } nphy->use_int_tx_iq_lo_cal = bwn_nphy_ipa(mac) || phy->rev >= 7 || (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; bwn_nphy_tables_init(mac); nphy->crsminpwr_adjusted = false; @@ -6221,9 +6285,9 @@ static int bwn_phy_initn(struct bwn_mac *mac) BWN_PHY_WRITE(mac, BWN_NPHY_AFESEQ_TX2RX_PUD_20M, 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 || - (siba_get_pci_subvendor(sc->sc_dev) == PCI_VENDOR_APPLE && - siba_get_pci_subdevice(sc->sc_dev) == BCMA_BOARD_TYPE_BCM943224M93)) + if (sc->sc_board_info.board_flags2 & BHND_BFL2_SKWRKFEM_BRD || + (sc->sc_board_info.board_vendor == PCI_VENDOR_APPLE && + sc->sc_board_info.board_type == BHND_BOARD_BCM943224M93)) BWN_PHY_WRITE(mac, BWN_NPHY_TXREALFD, 0xA0); else BWN_PHY_WRITE(mac, BWN_NPHY_TXREALFD, 0xB8); @@ -6254,7 +6318,8 @@ static int bwn_phy_initn(struct bwn_mac *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 */ bwn_phy_force_clock(mac, 1); @@ -6279,7 +6344,8 @@ static int bwn_phy_initn(struct bwn_mac *mac) tx_pwr_state = nphy->txpwrctrl; 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_setup(mac); bwn_nphy_tx_gain_table_upload(mac); @@ -6316,8 +6382,11 @@ static int bwn_phy_initn(struct bwn_mac *mac) if (do_cal) { target = bwn_nphy_get_tx_gains(mac); - if (nphy->antsel_type == 2) - bwn_nphy_superswitch_init(mac, true); + if (nphy->antsel_type == 2) { + error = bwn_nphy_superswitch_init(mac, true); + if (error) + return (error); + } if (nphy->perical != 2) { bwn_nphy_rssi_cal(mac); if (phy->rev >= 3) { @@ -6367,16 +6436,28 @@ static void bwn_chantab_phy_upload(struct bwn_mac *mac, } /* 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; + int error; - DPRINTF(sc, BWN_DEBUG_RESET, "%s: spuravoid %d\n", __func__, avoid); - siba_pmu_spuravoid_pllupdate(sc->sc_dev, avoid); + DPRINTF(sc, BWN_DEBUG_RESET, "%s: spuravoid %d\n", __func__, mode); + + 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 */ -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, struct ieee80211_channel *new_channel) { @@ -6384,6 +6465,7 @@ static void bwn_nphy_channel_setup(struct bwn_mac *mac, struct bwn_phy *phy = &mac->mac_phy; struct bwn_phy_n *nphy = mac->mac_phy.phy_n; int ch = new_channel->ic_ieee; + int error; uint16_t tmp16; if (bwn_channel_band(mac, new_channel) == BWN_BAND_5G) { @@ -6422,8 +6504,10 @@ static void bwn_nphy_channel_setup(struct bwn_mac *mac, BWN_PHY_MASK(mac, BWN_PHY_B_TEST, ~0x840); } - if (!nphy->txpwrctrl) - bwn_nphy_tx_power_fix(mac); + if (!nphy->txpwrctrl) { + if ((error = bwn_nphy_tx_power_fix(mac))) + return (error); + } if (mac->mac_phy.rev < 3) bwn_nphy_adjust_lna_gain_table(mac); @@ -6432,10 +6516,10 @@ static void bwn_nphy_channel_setup(struct bwn_mac *mac, if (mac->mac_phy.rev >= 3 && 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) { - spuravoid = 1; + spuravoid = BHND_PMU_SPURAVOID_M1; } else if (phy->rev >= 19) { /* TODO */ } else if (phy->rev >= 18) { @@ -6447,19 +6531,20 @@ static void bwn_nphy_channel_setup(struct bwn_mac *mac, } else if (phy->rev >= 7) { if (!bwn_is_40mhz(mac)) { /* 20MHz */ if (ch == 13 || ch == 14 || ch == 153) - spuravoid = 1; + spuravoid = BHND_PMU_SPURAVOID_M1; } else { /* 40 MHz */ if (ch == 54) - spuravoid = 1; + spuravoid = BHND_PMU_SPURAVOID_M1; } } else { if (!bwn_is_40mhz(mac)) { /* 20MHz */ if ((ch >= 5 && ch <= 8) || ch == 13 || ch == 14) - spuravoid = 1; + spuravoid = BHND_PMU_SPURAVOID_M1; } else { /* 40MHz */ if (nphy->aband_spurwar_en && - (ch == 38 || ch == 102 || ch == 118)) - spuravoid = siba_get_chipid(sc->sc_dev) == 0x4716; + (ch == 38 || ch == 102 || ch == 118) && + sc->sc_cid.chip_id == BHND_CHIPID_BCM4716) + spuravoid = BHND_PMU_SPURAVOID_M1; } } @@ -6470,7 +6555,7 @@ static void bwn_nphy_channel_setup(struct bwn_mac *mac, if (mac->mac_phy.rev == 3 || mac->mac_phy.rev == 4) 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); else BWN_PHY_MASK(mac, BWN_NPHY_BBCFG, @@ -6485,6 +6570,8 @@ static void bwn_nphy_channel_setup(struct bwn_mac *mac, if (phy->rev >= 3) bwn_nphy_spur_workaround(mac); + + return (0); } /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SetChanspec */ @@ -6499,6 +6586,7 @@ static int bwn_nphy_set_channel(struct bwn_mac *mac, const struct bwn_nphy_chantabent_rev7 *tabent_r7 = NULL; const struct bwn_nphy_chantabent_rev7_2g *tabent_r7_2g = NULL; + int error; uint8_t tmp; if (phy->rev >= 19) { @@ -6545,6 +6633,7 @@ static int bwn_nphy_set_channel(struct bwn_mac *mac, if (phy->rev >= 19) { /* TODO */ + error = ENODEV; } else if (phy->rev >= 7) { const struct bwn_phy_n_sfo_cfg *phy_regs = tabent_r7 ? &(tabent_r7->phy_regs) : &(tabent_r7_2g->phy_regs); @@ -6556,20 +6645,22 @@ static int bwn_nphy_set_channel(struct bwn_mac *mac, } 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) { tmp = (bwn_channel_band(mac, channel) == BWN_BAND_5G) ? 4 : 0; BWN_RF_SETMASK(mac, 0x08, 0xFFFB, tmp); 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 { tmp = (bwn_channel_band(mac, channel) == BWN_BAND_5G) ? 0x0020 : 0x0050; BWN_RF_SETMASK(mac, B2055_MASTER1, 0xFF8F, tmp); 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); } /************************************************** @@ -6590,12 +6681,13 @@ bwn_nphy_op_allocate(struct bwn_mac *mac) return 0; } -void +int bwn_nphy_op_prepare_structs(struct bwn_mac *mac) { struct bwn_softc *sc = mac->mac_sc; struct bwn_phy *phy = &mac->mac_phy; struct bwn_phy_n *nphy = phy->phy_n; + int error; memset(nphy, 0, sizeof(*nphy)); @@ -6615,28 +6707,46 @@ bwn_nphy_op_prepare_structs(struct bwn_mac *mac) nphy->txpwrctrl = false; nphy->pwg_gain_5ghz = false; if (mac->mac_phy.rev >= 3 || - (siba_get_pci_subvendor(sc->sc_dev) == PCI_VENDOR_APPLE && - (siba_get_revid(sc->sc_dev) == 11 || siba_get_revid(sc->sc_dev) == 12))) { + (sc->sc_board_info.board_vendor == PCI_VENDOR_APPLE && + (bhnd_get_hwrev(sc->sc_dev) == 11 || bhnd_get_hwrev(sc->sc_dev) == 12))) { nphy->txpwrctrl = 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 && - (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; - if (siba_get_type(sc->sc_dev) == SIBA_TYPE_PCI) { - if ((siba_get_pci_device(sc->sc_dev) == 0x4328) || - (siba_get_pci_device(sc->sc_dev) == 0x432a)) - nphy->pwg_gain_5ghz = true; - } - } else if (siba_sprom_get_bf2_lo(sc->sc_dev) & BWN_BFL2_5G_PWRGAIN) { + if ((sc->sc_board_info.board_devid == PCI_DEVID_BCM4321_D11N) || + (sc->sc_board_info.board_devid == PCI_DEVID_BCM4321_D11N5G)) + nphy->pwg_gain_5ghz = true; + } else if (sc->sc_board_info.board_flags2 & BHND_BFL2_5G_PWRGAIN) { nphy->pwg_gain_5ghz = true; } } if (mac->mac_phy.rev >= 3) { - nphy->ipa2g_on = siba_sprom_get_fem_2ghz_extpa_gain(sc->sc_dev) == 2; - nphy->ipa5g_on = siba_sprom_get_fem_5ghz_extpa_gain(sc->sc_dev) == 2; + uint8_t extpa_gain2g, extpa_gain5g; + + 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 diff --git a/sys/gnu/dev/bwn/phy_n/if_bwn_phy_n_core.h b/sys/gnu/dev/bwn/phy_n/if_bwn_phy_n_core.h index 3876a3e0db78..72a9fb920789 100644 --- a/sys/gnu/dev/bwn/phy_n/if_bwn_phy_n_core.h +++ b/sys/gnu/dev/bwn/phy_n/if_bwn_phy_n_core.h @@ -136,6 +136,7 @@ struct bwn_phy_n { struct bwn_ppr tx_pwr_max_ppr; uint16_t tx_pwr_last_recalc_freq; int tx_pwr_last_recalc_limit; + uint8_t tsspos_2g; uint8_t txrx_chain; uint16_t tx_rx_cal_phy_saveregs[11]; @@ -167,7 +168,7 @@ struct bwn_phy_n { extern bwn_txpwr_result_t bwn_nphy_op_recalc_txpower(struct bwn_mac *mac, bool ignore_tssi); extern int bwn_nphy_op_allocate(struct bwn_mac *mac); -extern void bwn_nphy_op_prepare_structs(struct bwn_mac *mac); +extern int bwn_nphy_op_prepare_structs(struct bwn_mac *mac); extern void bwn_nphy_op_free(struct bwn_mac *mac); extern int bwn_nphy_op_init(struct bwn_mac *mac); extern void bwn_nphy_op_maskset(struct bwn_mac *mac, uint16_t reg, uint16_t mask, uint16_t set); diff --git a/sys/gnu/dev/bwn/phy_n/if_bwn_phy_n_ppr.c b/sys/gnu/dev/bwn/phy_n/if_bwn_phy_n_ppr.c index d62911b51511..080a57ef9435 100644 --- a/sys/gnu/dev/bwn/phy_n/if_bwn_phy_n_ppr.c +++ b/sys/gnu/dev/bwn/phy_n/if_bwn_phy_n_ppr.c @@ -67,6 +67,9 @@ __FBSDID("$FreeBSD$"); #include <net80211/ieee80211_phy.h> #include <net80211/ieee80211_ratectl.h> +#include <dev/bhnd/bhnd.h> +#include <dev/bhnd/cores/pmu/bhnd_pmu.h> + #include <dev/bwn/if_bwnreg.h> #include <dev/bwn/if_bwnvar.h> #include <dev/bwn/if_bwn_debug.h> @@ -74,8 +77,11 @@ __FBSDID("$FreeBSD$"); #include <dev/bwn/if_bwn_phy_common.h> #include <gnu/dev/bwn/phy_n/if_bwn_phy_n_regs.h> +#include <gnu/dev/bwn/phy_n/if_bwn_phy_n_sprom.h> #include <gnu/dev/bwn/phy_n/if_bwn_phy_n_ppr.h> +#include "bhnd_nvram_map.h" + #define ppr_for_each_entry(ppr, i, entry) \ for (i = 0, entry = &(ppr)->__all_rates[i]; \ i < BWN_PPR_RATES_NUM; \ @@ -136,18 +142,21 @@ bool bwn_ppr_load_max_from_sprom(struct bwn_mac *mac, struct bwn_ppr *ppr, bwn_phy_band_t band) { struct bwn_softc *sc = mac->mac_sc; - struct siba_sprom_core_pwr_info core_pwr_info[4]; + struct bwn_phy_n_core_pwr_info core_pwr_info[4]; struct bwn_ppr_rates *rates = &ppr->rates; struct bwn_phy *phy = &mac->mac_phy; + const char *var_ofdmgpo, *var_mcsgpo_prefix; uint8_t maxpwr, off; uint32_t sprom_ofdm_po; uint16_t sprom_mcs_po[8]; + uint16_t cddpo, stbcpo; uint8_t extra_cdd_po, extra_stbc_po; + int error; int i; for (i = 0; i < 4; i++) { bzero(&core_pwr_info[i], sizeof(core_pwr_info[i])); - if (siba_sprom_get_core_power_info(sc->sc_dev, i, + if (bwn_nphy_get_core_power_info(mac, i, &core_pwr_info[i]) != 0) { BWN_ERRPRINTF(mac->mac_sc, "%s: failed to get core_pwr_info for core %d\n", @@ -156,38 +165,53 @@ bool bwn_ppr_load_max_from_sprom(struct bwn_mac *mac, struct bwn_ppr *ppr, } } + error = bhnd_nvram_getvar_uint16(sc->sc_dev, BHND_NVAR_CDDPO, &cddpo); + if (error) { + BWN_ERRPRINTF(mac->mac_sc, "NVRAM variable %s unreadable: %d\n", + BHND_NVAR_CDDPO, error); + return (false); + } + + error = bhnd_nvram_getvar_uint16(sc->sc_dev, BHND_NVAR_STBCPO, &stbcpo); + if (error) { + BWN_ERRPRINTF(mac->mac_sc, "NVRAM variable %s unreadable: %d\n", + BHND_NVAR_STBCPO, error); + return (false); + } + switch (band) { case BWN_PHY_BAND_2G: maxpwr = min(core_pwr_info[0].maxpwr_2g, core_pwr_info[1].maxpwr_2g); - sprom_ofdm_po = siba_sprom_get_ofdm2gpo(sc->sc_dev); - siba_sprom_get_mcs2gpo(sc->sc_dev, sprom_mcs_po); - extra_cdd_po = (siba_sprom_get_cddpo(sc->sc_dev) >> 0) & 0xf; - extra_stbc_po = (siba_sprom_get_stbcpo(sc->sc_dev) >> 0) & 0xf; + + var_ofdmgpo = BHND_NVAR_OFDM2GPO; + var_mcsgpo_prefix = "mcs2gpo"; + extra_cdd_po = (cddpo >> 0) & 0xf; + extra_stbc_po = (stbcpo >> 0) & 0xf; break; case BWN_PHY_BAND_5G_LO: maxpwr = min(core_pwr_info[0].maxpwr_5gl, core_pwr_info[1].maxpwr_5gl); - sprom_ofdm_po = siba_sprom_get_ofdm5glpo(sc->sc_dev); - siba_sprom_get_mcs5glpo(sc->sc_dev, sprom_mcs_po); - extra_cdd_po = (siba_sprom_get_cddpo(sc->sc_dev) >> 8) & 0xf; - extra_stbc_po = (siba_sprom_get_stbcpo(sc->sc_dev) >> 8) & 0xf; + var_ofdmgpo = BHND_NVAR_OFDM5GLPO; + var_mcsgpo_prefix = "mcs5glpo"; + extra_cdd_po = (cddpo >> 8) & 0xf; + extra_stbc_po = (stbcpo >> 8) & 0xf; break; case BWN_PHY_BAND_5G_MI: maxpwr = min(core_pwr_info[0].maxpwr_5g, core_pwr_info[1].maxpwr_5g); - sprom_ofdm_po = siba_sprom_get_ofdm5gpo(sc->sc_dev); - siba_sprom_get_mcs5gpo(sc->sc_dev, sprom_mcs_po); - extra_cdd_po = (siba_sprom_get_cddpo(sc->sc_dev) >> 4) & 0xf; - extra_stbc_po = (siba_sprom_get_stbcpo(sc->sc_dev) >> 4) & 0xf; + var_ofdmgpo = BHND_NVAR_OFDM5GPO; + var_mcsgpo_prefix = "mcs5gpo"; + extra_cdd_po = (cddpo >> 4) & 0xf; + extra_stbc_po = (stbcpo >> 4) & 0xf; break; case BWN_PHY_BAND_5G_HI: maxpwr = min(core_pwr_info[0].maxpwr_5gh, core_pwr_info[1].maxpwr_5gh); - sprom_ofdm_po = siba_sprom_get_ofdm5ghpo(sc->sc_dev); - siba_sprom_get_mcs5ghpo(sc->sc_dev, sprom_mcs_po); - extra_cdd_po = (siba_sprom_get_cddpo(sc->sc_dev) >> 12) & 0xf; - extra_stbc_po = (siba_sprom_get_stbcpo(sc->sc_dev) >> 12) & 0xf; + var_ofdmgpo = BHND_NVAR_OFDM5GHPO; + var_mcsgpo_prefix = "mcs5ghpo"; + extra_cdd_po = (cddpo >> 12) & 0xf; + extra_stbc_po = (stbcpo >> 12) & 0xf; break; default: device_printf(mac->mac_sc->sc_dev, "%s: invalid band (%d)\n", @@ -196,9 +220,48 @@ bool bwn_ppr_load_max_from_sprom(struct bwn_mac *mac, struct bwn_ppr *ppr, return false; } + error = bhnd_nvram_getvar_uint32(sc->sc_dev, var_ofdmgpo, + &sprom_ofdm_po); + if (error) { + device_printf(sc->sc_dev, "NVRAM variable %s unreadable: %d\n", + var_ofdmgpo, error); + return (false); + } + + for (size_t i = 0; i < nitems(sprom_mcs_po); i++) { + char var[strlen(var_mcsgpo_prefix) + sizeof("XX")]; + int ret; + + /* mcs[25]g[lh]?po[0-9] */ + ret = snprintf(var, sizeof(var), "%s%zu", var_mcsgpo_prefix, i); + if (ret >= sizeof(var)) { + device_printf(sc->sc_dev, "buffer too small for " + "%s%zu\n", var_mcsgpo_prefix, i); + return (false); + } + + error = bhnd_nvram_getvar_uint16(sc->sc_dev, var, + &sprom_mcs_po[i]); + if (error) { + device_printf(sc->sc_dev, "NVRAM variable %s " + "unreadable: %d\n", var, error); + return (false); + } + } + if (band == BWN_BAND_2G) { + uint16_t ck2gpo; + + error = bhnd_nvram_getvar_uint16(sc->sc_dev, BHND_NVAR_CCK2GPO, + &ck2gpo); + if (error) { + device_printf(sc->sc_dev, "NVRAM variable %s " + "unreadable: %d\n", BHND_NVAR_CCK2GPO, error); + return (false); + } + for (i = 0; i < 4; i++) { - off = ((siba_sprom_get_cck2gpo(sc->sc_dev) >> (i * 4)) & 0xf) * 2; + off = ((ck2gpo >> (i * 4)) & 0xf) * 2; rates->cck[i] = maxpwr - off; } } diff --git a/sys/gnu/dev/bwn/phy_n/if_bwn_phy_n_sprom.c b/sys/gnu/dev/bwn/phy_n/if_bwn_phy_n_sprom.c new file mode 100644 index 000000000000..25c1c82dca5b --- /dev/null +++ b/sys/gnu/dev/bwn/phy_n/if_bwn_phy_n_sprom.c @@ -0,0 +1,181 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2016 Landon Fuller <landonf@FreeBSD.org> + * Copyright (c) 2017 The FreeBSD Foundation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any + * redistribution must be conditioned upon including a substantially + * similar Disclaimer requirement for further binary redistribution. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, + * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGES. + * + * $FreeBSD$ + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/malloc.h> +#include <sys/kernel.h> +#include <sys/socket.h> + +#include <net/ethernet.h> +#include <net/if.h> +#include <net/if_var.h> +#include <net/if_arp.h> +#include <net/if_dl.h> +#include <net/if_llc.h> +#include <net/if_media.h> +#include <net/if_types.h> + +#include <net80211/ieee80211_var.h> +#include <net80211/ieee80211_radiotap.h> +#include <net80211/ieee80211_regdomain.h> +#include <net80211/ieee80211_phy.h> +#include <net80211/ieee80211_ratectl.h> + +#include <dev/bhnd/bhnd.h> + +#include <dev/bwn/if_bwnvar.h> + +#include "if_bwn_phy_n_sprom.h" + +#include "bhnd_nvram_map.h" + + +/* Core power NVRAM variables, indexed by D11 core unit number */ +static const struct bwn_nphy_power_vars { + const char *itt2ga; + const char *itt5ga; + const char *maxp2ga; + const char *pa2ga; + const char *pa5ga; +} bwn_nphy_power_vars[BWN_NPHY_NUM_CORE_PWR] = { +#define BHND_POWER_NVAR(_idx) \ + { BHND_NVAR_ITT2GA ## _idx, BHND_NVAR_ITT5GA ## _idx, \ + BHND_NVAR_MAXP2GA ## _idx, BHND_NVAR_PA2GA ## _idx, \ + BHND_NVAR_PA5GA ## _idx } + BHND_POWER_NVAR(0), + BHND_POWER_NVAR(1), + BHND_POWER_NVAR(2), + BHND_POWER_NVAR(3) +#undef BHND_POWER_NVAR +}; + +static int +bwn_nphy_get_core_power_info_r11(struct bwn_softc *sc, + const struct bwn_nphy_power_vars *v, struct bwn_phy_n_core_pwr_info *c) +{ + int16_t pa5ga[12]; + int error; + + /* BHND_NVAR_PA2GA[core] */ + error = bhnd_nvram_getvar_array(sc->sc_dev, v->pa2ga, c->pa_2g, + sizeof(c->pa_2g), BHND_NVRAM_TYPE_INT16); + if (error) + return (error); + + /* + * BHND_NVAR_PA5GA + * + * The NVRAM variable is defined as a single pa5ga[12] array; we have + * to split this into pa_5gl[4], pa_5g[4], and pa_5gh[4] for use + * by bwn(4); + */ + _Static_assert(nitems(pa5ga) == nitems(c->pa_5g) + nitems(c->pa_5gh) + + nitems(c->pa_5gl), "cannot split pa5ga into pa_5gl/pa_5g/pa_5gh"); + + error = bhnd_nvram_getvar_array(sc->sc_dev, v->pa5ga, pa5ga, + sizeof(pa5ga), BHND_NVRAM_TYPE_INT16); + if (error) + return (error); + + memcpy(c->pa_5gl, &pa5ga[0], sizeof(c->pa_5gl)); + memcpy(c->pa_5g, &pa5ga[4], sizeof(c->pa_5g)); + memcpy(c->pa_5gh, &pa5ga[8], sizeof(c->pa_5gh)); + return (0); +} + +static int +bwn_nphy_get_core_power_info_r4_r10(struct bwn_softc *sc, + const struct bwn_nphy_power_vars *v, struct bwn_phy_n_core_pwr_info *c) +{ + int error; + + /* BHND_NVAR_ITT2GA[core] */ + error = bhnd_nvram_getvar_uint8(sc->sc_dev, v->itt2ga, &c->itssi_2g); + if (error) + return (error); + + /* BHND_NVAR_ITT5GA[core] */ + error = bhnd_nvram_getvar_uint8(sc->sc_dev, v->itt5ga, &c->itssi_5g); + if (error) + return (error); + + return (0); +} + +/* + * siba_sprom_get_core_power_info() + * + * Referenced by: + * bwn_nphy_tx_power_ctl_setup() + * bwn_ppr_load_max_from_sprom() + */ +int +bwn_nphy_get_core_power_info(struct bwn_mac *mac, int core, + struct bwn_phy_n_core_pwr_info *c) +{ + struct bwn_softc *sc; + const struct bwn_nphy_power_vars *v; + uint8_t sromrev; + int error; + + sc = mac->mac_sc; + + if (core < 0 || core >= nitems(bwn_nphy_power_vars)) + return (EINVAL); + + sromrev = sc->sc_board_info.board_srom_rev; + if (sromrev < 4) + return (ENXIO); + + v = &bwn_nphy_power_vars[core]; + + /* Any power variables not found in NVRAM (or returning a + * shorter array for a particular NVRAM revision) should be zero + * initialized */ + memset(c, 0x0, sizeof(*c)); + + /* Populate SPROM revision-independent values */ + error = bhnd_nvram_getvar_uint8(sc->sc_dev, v->maxp2ga, &c->maxpwr_2g); + if (error) + return (error); + + /* Populate SPROM revision-specific values */ + if (sromrev >= 4 && sromrev <= 10) + return (bwn_nphy_get_core_power_info_r4_r10(sc, v, c)); + else + return (bwn_nphy_get_core_power_info_r11(sc, v, c)); +} diff --git a/sys/gnu/dev/bwn/phy_n/if_bwn_phy_n_sprom.h b/sys/gnu/dev/bwn/phy_n/if_bwn_phy_n_sprom.h new file mode 100644 index 000000000000..0dd038c069d1 --- /dev/null +++ b/sys/gnu/dev/bwn/phy_n/if_bwn_phy_n_sprom.h @@ -0,0 +1,56 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2017 The FreeBSD Foundation + * Copyright (c) 2016 Landon J. Fuller <landonf@FreeBSD.org> + * Copyright (c) 2007 Bruce M. Simpson. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _IF_BWN_PHY_N_SPROM_H_ +#define _IF_BWN_PHY_N_SPROM_H_ + +struct bwn_mac; + +#define BWN_NPHY_NUM_CORE_PWR 4 + +struct bwn_phy_n_core_pwr_info { + uint8_t itssi_2g; + uint8_t itssi_5g; + uint8_t maxpwr_2g; + uint8_t maxpwr_5gl; + uint8_t maxpwr_5g; + uint8_t maxpwr_5gh; + int16_t pa_2g[3]; + int16_t pa_5gl[4]; + int16_t pa_5g[4]; + int16_t pa_5gh[4]; +}; + +int bwn_nphy_get_core_power_info(struct bwn_mac *mac, int core, + struct bwn_phy_n_core_pwr_info *c); + +#endif /* _IF_BWN_PHY_N_SPROM_H_ */ diff --git a/sys/gnu/dev/bwn/phy_n/if_bwn_phy_n_tables.c b/sys/gnu/dev/bwn/phy_n/if_bwn_phy_n_tables.c index 2a3725caa632..b59271f65933 100644 --- a/sys/gnu/dev/bwn/phy_n/if_bwn_phy_n_tables.c +++ b/sys/gnu/dev/bwn/phy_n/if_bwn_phy_n_tables.c @@ -68,6 +68,9 @@ __FBSDID("$FreeBSD$"); #include <net80211/ieee80211_phy.h> #include <net80211/ieee80211_ratectl.h> +#include <dev/bhnd/bhnd.h> +#include <dev/bhnd/bhnd_ids.h> + #include <dev/bwn/if_bwnreg.h> #include <dev/bwn/if_bwnvar.h> #include <dev/bwn/if_bwn_debug.h> @@ -77,6 +80,8 @@ __FBSDID("$FreeBSD$"); #include <gnu/dev/bwn/phy_n/if_bwn_phy_n_tables.h> #include <gnu/dev/bwn/phy_n/if_bwn_phy_n_core.h> +#include "bhnd_nvram_map.h" + static const uint8_t bwn_ntab_adjustpower0[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -3418,8 +3423,8 @@ void bwn_ntab_read_bulk(struct bwn_mac *mac, uint32_t offset, for (i = 0; i < nr_elements; i++) { /* Auto increment broken + caching issue on BCM43224? */ - if (siba_get_chipid(sc->sc_dev) == 43224 && - siba_get_revid(sc->sc_dev) == 1) { + if (sc->sc_cid.chip_id == BHND_CHIPID_BCM43224 && + bhnd_get_hwrev(sc->sc_dev) == 1) { BWN_PHY_READ(mac, BWN_NPHY_TABLE_DATALO); BWN_PHY_WRITE(mac, BWN_NPHY_TABLE_ADDR, offset + i); } @@ -3504,8 +3509,8 @@ void bwn_ntab_write_bulk(struct bwn_mac *mac, uint32_t offset, for (i = 0; i < nr_elements; i++) { /* Auto increment broken + caching issue on BCM43224? */ if ((offset >> 10) == 9 && - siba_get_chipid(sc->sc_dev) == 43224 && - siba_get_revid(sc->sc_dev) == 1) { + sc->sc_cid.chip_id == BHND_CHIPID_BCM43224 && + bhnd_get_hwrev(sc->sc_dev) == 1) { BWN_PHY_READ(mac, BWN_NPHY_TABLE_DATALO); BWN_PHY_WRITE(mac, BWN_NPHY_TABLE_ADDR, offset + i); } @@ -3557,12 +3562,30 @@ static void bwn_nphy_tables_init_shared_lut(struct bwn_mac *mac) ntab_upload(mac, BWN_NTAB_C1_LOFEEDTH_R3, bwn_ntab_loftlt1_r3); } +static int bwn_nphy_tables_get_antswlut(struct bwn_mac *mac, uint8_t *antswlut) +{ + struct ieee80211com *ic = &mac->mac_sc->sc_ic; + struct bwn_softc *sc = mac->mac_sc; + const char *antswlut_var; + int error; + + if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) + antswlut_var = BHND_NVAR_ANTSWCTL5G; + else + antswlut_var = BHND_NVAR_ANTSWCTL2G; + + error = bhnd_nvram_getvar_uint8(sc->sc_dev, antswlut_var, antswlut); + if (error) + BWN_ERRPRINTF(mac->mac_sc, "NVRAM variable %s unreadable: %d", + antswlut_var, error); + + return (error); +} + static void bwn_nphy_tables_init_rev7_volatile(struct bwn_mac *mac) { - struct ieee80211com *ic = &mac->mac_sc->sc_ic; - struct bwn_softc *sc = mac->mac_sc; - uint8_t antswlut; - int core, offset, i; + int core, error, offset, i; + uint8_t antswlut; const int antswlut0_offsets[] = { 0, 4, 8, }; /* Offsets for values */ const uint8_t antswlut0_values[][3] = { @@ -3570,10 +3593,8 @@ static void bwn_nphy_tables_init_rev7_volatile(struct bwn_mac *mac) { 0x2, 0x18, 0x2 }, /* Core 1 */ }; - if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) - antswlut = siba_sprom_get_fem_5ghz_antswlut(sc->sc_dev); - else - antswlut = siba_sprom_get_fem_2ghz_antswlut(sc->sc_dev); + if ((error = bwn_nphy_tables_get_antswlut(mac, &antswlut))) + return; switch (antswlut) { case 0: @@ -3631,14 +3652,11 @@ static void bwn_nphy_tables_init_rev7(struct bwn_mac *mac) static void bwn_nphy_tables_init_rev3(struct bwn_mac *mac) { - struct ieee80211com *ic = &mac->mac_sc->sc_ic; - struct bwn_softc *sc = mac->mac_sc; - uint8_t antswlut; + int error; + uint8_t antswlut; - if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) - antswlut = siba_sprom_get_fem_5ghz_antswlut(sc->sc_dev); - else - antswlut = siba_sprom_get_fem_2ghz_antswlut(sc->sc_dev); + if ((error = bwn_nphy_tables_get_antswlut(mac, &antswlut))) + return; /* Static tables */ if (mac->mac_phy.phy_do_full_init) { @@ -3738,7 +3756,7 @@ static const uint32_t *bwn_nphy_get_ipa_gain_table(struct bwn_mac *mac) return bwn_ntab_tx_gain_ipa_2057_rev5_2g; break; case 6: - if (siba_get_chipid(sc->sc_dev) == 47162) /* BCM47612 */ + if (sc->sc_cid.chip_id == BHND_CHIPID_BCM47162) return bwn_ntab_tx_gain_ipa_rev5_2g; return bwn_ntab_tx_gain_ipa_rev6_2g; case 5: @@ -3772,7 +3790,8 @@ const uint32_t *bwn_nphy_get_tx_gain_table(struct bwn_mac *mac) struct ieee80211com *ic = &mac->mac_sc->sc_ic; struct bwn_softc *sc = mac->mac_sc; struct bwn_phy *phy = &mac->mac_phy; - int is_5ghz; + int error, is_5ghz; + uint8_t extpa_gain; /* XXX ideally we'd have is2, is5, etc */ is_5ghz = !! IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan); @@ -3790,7 +3809,16 @@ const uint32_t *bwn_nphy_get_tx_gain_table(struct bwn_mac *mac) case 5: return bwn_ntab_tx_gain_epa_rev5_5g; case 4: - return siba_sprom_get_fem_5ghz_extpa_gain(sc->sc_dev) == 3 ? + error = bhnd_nvram_getvar_uint8(sc->sc_dev, + BHND_NVAR_EXTPAGAIN5G, &extpa_gain); + if (error) { + BWN_ERRPRINTF(mac->mac_sc, "Error reading EPA " + "gain configuration (%s) from NVRAM: %d\n", + BHND_NVAR_EXTPAGAIN5G, error); + return (NULL); + } + + return (extpa_gain == 3) ? bwn_ntab_tx_gain_epa_rev4_5g : bwn_ntab_tx_gain_epa_rev4_hi_pwr_5g; case 3: @@ -3804,7 +3832,16 @@ const uint32_t *bwn_nphy_get_tx_gain_table(struct bwn_mac *mac) switch (phy->rev) { case 6: case 5: - if (siba_sprom_get_fem_5ghz_extpa_gain(sc->sc_dev) == 3) + error = bhnd_nvram_getvar_uint8(sc->sc_dev, + BHND_NVAR_EXTPAGAIN2G, &extpa_gain); + if (error) { + BWN_ERRPRINTF(mac->mac_sc, "Error reading EPA " + "gain configuration (%s) from NVRAM: %d\n", + BHND_NVAR_EXTPAGAIN2G, error); + return (NULL); + } + + if (extpa_gain == 3) return bwn_ntab_tx_gain_epa_rev3_hi_pwr_2g; /* fall through */ case 4: @@ -3879,7 +3916,13 @@ struct bwn_nphy_gain_ctl_workaround_entry *bwn_nphy_get_gain_ctl_workaround_ent( /* Some workarounds to the workarounds... */ if (!ghz5) { - uint8_t tr_iso = siba_sprom_get_fem_2ghz_tr_iso(sc->sc_dev); + uint8_t tr_iso; + int error; + + error = bhnd_nvram_getvar_uint8(sc->sc_dev, BHND_NVAR_TRISO2G, + &tr_iso); + BWN_ERRPRINTF(mac->mac_sc, "Error reading %s from NVRAM: %d\n", + BHND_NVAR_TRISO2G, error); if (tr_iso > 7) tr_iso = 3; |
