Changeset View
Changeset View
Standalone View
Standalone View
sys/gnu/dev/bwn/phy_n/if_bwn_phy_n_tables.c
Show First 20 Lines • Show All 62 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/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_debug.h> | #include <dev/bwn/if_bwn_debug.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_tables.h> | #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 <gnu/dev/bwn/phy_n/if_bwn_phy_n_core.h> | ||||
#include "bhnd_nvram_map.h" | |||||
static const uint8_t bwn_ntab_adjustpower0[] = { | static const uint8_t bwn_ntab_adjustpower0[] = { | ||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
▲ Show 20 Lines • Show All 3,325 Lines • ▼ Show 20 Lines | void bwn_ntab_read_bulk(struct bwn_mac *mac, uint32_t offset, | ||||
offset &= ~BWN_NTAB_TYPEMASK; | offset &= ~BWN_NTAB_TYPEMASK; | ||||
KASSERT(offset <= 0xFFFF, ("%s: invalid offset (%d)\n", | KASSERT(offset <= 0xFFFF, ("%s: invalid offset (%d)\n", | ||||
__func__, offset)); | __func__, offset)); | ||||
BWN_PHY_WRITE(mac, BWN_NPHY_TABLE_ADDR, offset); | BWN_PHY_WRITE(mac, BWN_NPHY_TABLE_ADDR, offset); | ||||
for (i = 0; i < nr_elements; i++) { | for (i = 0; i < nr_elements; i++) { | ||||
/* Auto increment broken + caching issue on BCM43224? */ | /* Auto increment broken + caching issue on BCM43224? */ | ||||
if (siba_get_chipid(sc->sc_dev) == 43224 && | if (sc->sc_cid.chip_id == BHND_CHIPID_BCM43224 && | ||||
siba_get_revid(sc->sc_dev) == 1) { | bhnd_get_hwrev(sc->sc_dev) == 1) { | ||||
BWN_PHY_READ(mac, BWN_NPHY_TABLE_DATALO); | BWN_PHY_READ(mac, BWN_NPHY_TABLE_DATALO); | ||||
BWN_PHY_WRITE(mac, BWN_NPHY_TABLE_ADDR, offset + i); | BWN_PHY_WRITE(mac, BWN_NPHY_TABLE_ADDR, offset + i); | ||||
} | } | ||||
switch (type) { | switch (type) { | ||||
case BWN_NTAB_8BIT: | case BWN_NTAB_8BIT: | ||||
*data = BWN_PHY_READ(mac, BWN_NPHY_TABLE_DATALO) & 0xFF; | *data = BWN_PHY_READ(mac, BWN_NPHY_TABLE_DATALO) & 0xFF; | ||||
data++; | data++; | ||||
▲ Show 20 Lines • Show All 68 Lines • ▼ Show 20 Lines | void bwn_ntab_write_bulk(struct bwn_mac *mac, uint32_t offset, | ||||
KASSERT(offset <= 0xFFFF, ("%s: invalid offset (%d)\n", | KASSERT(offset <= 0xFFFF, ("%s: invalid offset (%d)\n", | ||||
__func__, offset)); | __func__, offset)); | ||||
BWN_PHY_WRITE(mac, BWN_NPHY_TABLE_ADDR, offset); | BWN_PHY_WRITE(mac, BWN_NPHY_TABLE_ADDR, offset); | ||||
for (i = 0; i < nr_elements; i++) { | for (i = 0; i < nr_elements; i++) { | ||||
/* Auto increment broken + caching issue on BCM43224? */ | /* Auto increment broken + caching issue on BCM43224? */ | ||||
if ((offset >> 10) == 9 && | if ((offset >> 10) == 9 && | ||||
siba_get_chipid(sc->sc_dev) == 43224 && | sc->sc_cid.chip_id == BHND_CHIPID_BCM43224 && | ||||
siba_get_revid(sc->sc_dev) == 1) { | bhnd_get_hwrev(sc->sc_dev) == 1) { | ||||
BWN_PHY_READ(mac, BWN_NPHY_TABLE_DATALO); | BWN_PHY_READ(mac, BWN_NPHY_TABLE_DATALO); | ||||
BWN_PHY_WRITE(mac, BWN_NPHY_TABLE_ADDR, offset + i); | BWN_PHY_WRITE(mac, BWN_NPHY_TABLE_ADDR, offset + i); | ||||
} | } | ||||
switch (type) { | switch (type) { | ||||
case BWN_NTAB_8BIT: | case BWN_NTAB_8BIT: | ||||
value = *data; | value = *data; | ||||
data++; | data++; | ||||
Show All 35 Lines | static void bwn_nphy_tables_init_shared_lut(struct bwn_mac *mac) | ||||
ntab_upload(mac, BWN_NTAB_C0_GAINCTL_R3, bwn_ntab_gainctl0_r3); | ntab_upload(mac, BWN_NTAB_C0_GAINCTL_R3, bwn_ntab_gainctl0_r3); | ||||
ntab_upload(mac, BWN_NTAB_C1_GAINCTL_R3, bwn_ntab_gainctl1_r3); | ntab_upload(mac, BWN_NTAB_C1_GAINCTL_R3, bwn_ntab_gainctl1_r3); | ||||
ntab_upload(mac, BWN_NTAB_C0_IQLT_R3, bwn_ntab_iqlt0_r3); | ntab_upload(mac, BWN_NTAB_C0_IQLT_R3, bwn_ntab_iqlt0_r3); | ||||
ntab_upload(mac, BWN_NTAB_C1_IQLT_R3, bwn_ntab_iqlt1_r3); | ntab_upload(mac, BWN_NTAB_C1_IQLT_R3, bwn_ntab_iqlt1_r3); | ||||
ntab_upload(mac, BWN_NTAB_C0_LOFEEDTH_R3, bwn_ntab_loftlt0_r3); | ntab_upload(mac, BWN_NTAB_C0_LOFEEDTH_R3, bwn_ntab_loftlt0_r3); | ||||
ntab_upload(mac, BWN_NTAB_C1_LOFEEDTH_R3, bwn_ntab_loftlt1_r3); | ntab_upload(mac, BWN_NTAB_C1_LOFEEDTH_R3, bwn_ntab_loftlt1_r3); | ||||
} | } | ||||
static void bwn_nphy_tables_init_rev7_volatile(struct bwn_mac *mac) | static int bwn_nphy_tables_get_antswlut(struct bwn_mac *mac, uint8_t *antswlut) | ||||
{ | { | ||||
struct ieee80211com *ic = &mac->mac_sc->sc_ic; | struct ieee80211com *ic = &mac->mac_sc->sc_ic; | ||||
struct bwn_softc *sc = mac->mac_sc; | 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) | |||||
{ | |||||
int core, error, offset, i; | |||||
uint8_t antswlut; | uint8_t antswlut; | ||||
int core, offset, i; | |||||
const int antswlut0_offsets[] = { 0, 4, 8, }; /* Offsets for values */ | const int antswlut0_offsets[] = { 0, 4, 8, }; /* Offsets for values */ | ||||
const uint8_t antswlut0_values[][3] = { | const uint8_t antswlut0_values[][3] = { | ||||
{ 0x2, 0x12, 0x8 }, /* Core 0 */ | { 0x2, 0x12, 0x8 }, /* Core 0 */ | ||||
{ 0x2, 0x18, 0x2 }, /* Core 1 */ | { 0x2, 0x18, 0x2 }, /* Core 1 */ | ||||
}; | }; | ||||
if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) | if ((error = bwn_nphy_tables_get_antswlut(mac, &antswlut))) | ||||
antswlut = siba_sprom_get_fem_5ghz_antswlut(sc->sc_dev); | return; | ||||
else | |||||
antswlut = siba_sprom_get_fem_2ghz_antswlut(sc->sc_dev); | |||||
switch (antswlut) { | switch (antswlut) { | ||||
case 0: | case 0: | ||||
for (core = 0; core < 2; core++) { | for (core = 0; core < 2; core++) { | ||||
for (i = 0; i < nitems(antswlut0_values[0]); i++) { | for (i = 0; i < nitems(antswlut0_values[0]); i++) { | ||||
offset = core ? 0x20 : 0x00; | offset = core ? 0x20 : 0x00; | ||||
offset += antswlut0_offsets[i]; | offset += antswlut0_offsets[i]; | ||||
bwn_ntab_write(mac, BWN_NTAB8(9, offset), | bwn_ntab_write(mac, BWN_NTAB8(9, offset), | ||||
▲ Show 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | static void bwn_nphy_tables_init_rev7(struct bwn_mac *mac) | ||||
} | } | ||||
/* Volatile tables */ | /* Volatile tables */ | ||||
bwn_nphy_tables_init_rev7_volatile(mac); | bwn_nphy_tables_init_rev7_volatile(mac); | ||||
} | } | ||||
static void bwn_nphy_tables_init_rev3(struct bwn_mac *mac) | static void bwn_nphy_tables_init_rev3(struct bwn_mac *mac) | ||||
{ | { | ||||
struct ieee80211com *ic = &mac->mac_sc->sc_ic; | int error; | ||||
struct bwn_softc *sc = mac->mac_sc; | |||||
uint8_t antswlut; | uint8_t antswlut; | ||||
if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) | if ((error = bwn_nphy_tables_get_antswlut(mac, &antswlut))) | ||||
antswlut = siba_sprom_get_fem_5ghz_antswlut(sc->sc_dev); | return; | ||||
else | |||||
antswlut = siba_sprom_get_fem_2ghz_antswlut(sc->sc_dev); | |||||
/* Static tables */ | /* Static tables */ | ||||
if (mac->mac_phy.phy_do_full_init) { | if (mac->mac_phy.phy_do_full_init) { | ||||
ntab_upload(mac, BWN_NTAB_FRAMESTRUCT_R3, bwn_ntab_framestruct_r3); | ntab_upload(mac, BWN_NTAB_FRAMESTRUCT_R3, bwn_ntab_framestruct_r3); | ||||
ntab_upload(mac, BWN_NTAB_PILOT_R3, bwn_ntab_pilot_r3); | ntab_upload(mac, BWN_NTAB_PILOT_R3, bwn_ntab_pilot_r3); | ||||
ntab_upload(mac, BWN_NTAB_TMAP_R3, bwn_ntab_tmap_r3); | ntab_upload(mac, BWN_NTAB_TMAP_R3, bwn_ntab_tmap_r3); | ||||
ntab_upload(mac, BWN_NTAB_INTLEVEL_R3, bwn_ntab_intlevel_r3); | ntab_upload(mac, BWN_NTAB_INTLEVEL_R3, bwn_ntab_intlevel_r3); | ||||
ntab_upload(mac, BWN_NTAB_TDTRN_R3, bwn_ntab_tdtrn_r3); | ntab_upload(mac, BWN_NTAB_TDTRN_R3, bwn_ntab_tdtrn_r3); | ||||
▲ Show 20 Lines • Show All 83 Lines • ▼ Show 20 Lines | case 16: | ||||
if (phy->rf_rev == 9) | if (phy->rf_rev == 9) | ||||
return bwn_ntab_tx_gain_ipa_2057_rev9_2g; | return bwn_ntab_tx_gain_ipa_2057_rev9_2g; | ||||
break; | break; | ||||
case 8: | case 8: | ||||
if (phy->rf_rev == 5) | if (phy->rf_rev == 5) | ||||
return bwn_ntab_tx_gain_ipa_2057_rev5_2g; | return bwn_ntab_tx_gain_ipa_2057_rev5_2g; | ||||
break; | break; | ||||
case 6: | 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_rev5_2g; | ||||
return bwn_ntab_tx_gain_ipa_rev6_2g; | return bwn_ntab_tx_gain_ipa_rev6_2g; | ||||
case 5: | case 5: | ||||
return bwn_ntab_tx_gain_ipa_rev5_2g; | return bwn_ntab_tx_gain_ipa_rev5_2g; | ||||
case 4: | case 4: | ||||
case 3: | case 3: | ||||
return bwn_ntab_tx_gain_ipa_rev3_2g; | return bwn_ntab_tx_gain_ipa_rev3_2g; | ||||
} | } | ||||
Show All 17 Lines | static const uint32_t *bwn_nphy_get_ipa_gain_table(struct bwn_mac *mac) | ||||
} | } | ||||
} | } | ||||
const uint32_t *bwn_nphy_get_tx_gain_table(struct bwn_mac *mac) | const uint32_t *bwn_nphy_get_tx_gain_table(struct bwn_mac *mac) | ||||
{ | { | ||||
struct ieee80211com *ic = &mac->mac_sc->sc_ic; | struct ieee80211com *ic = &mac->mac_sc->sc_ic; | ||||
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; | ||||
int is_5ghz; | int error, is_5ghz; | ||||
uint8_t extpa_gain; | |||||
/* XXX ideally we'd have is2, is5, etc */ | /* XXX ideally we'd have is2, is5, etc */ | ||||
is_5ghz = !! IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan); | is_5ghz = !! IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan); | ||||
if (mac->mac_phy.rev < 3) | if (mac->mac_phy.rev < 3) | ||||
return bwn_ntab_tx_gain_rev0_1_2; | return bwn_ntab_tx_gain_rev0_1_2; | ||||
/* rev 3+ */ | /* rev 3+ */ | ||||
if ((mac->mac_phy.phy_n->ipa2g_on && is_5ghz == 0) || | if ((mac->mac_phy.phy_n->ipa2g_on && is_5ghz == 0) || | ||||
(mac->mac_phy.phy_n->ipa5g_on && is_5ghz == 1)) { | (mac->mac_phy.phy_n->ipa5g_on && is_5ghz == 1)) { | ||||
return bwn_nphy_get_ipa_gain_table(mac); | return bwn_nphy_get_ipa_gain_table(mac); | ||||
} else if (is_5ghz == 1) { | } else if (is_5ghz == 1) { | ||||
switch (phy->rev) { | switch (phy->rev) { | ||||
case 6: | case 6: | ||||
case 5: | case 5: | ||||
return bwn_ntab_tx_gain_epa_rev5_5g; | return bwn_ntab_tx_gain_epa_rev5_5g; | ||||
case 4: | 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_5g : | ||||
bwn_ntab_tx_gain_epa_rev4_hi_pwr_5g; | bwn_ntab_tx_gain_epa_rev4_hi_pwr_5g; | ||||
case 3: | case 3: | ||||
return bwn_ntab_tx_gain_epa_rev3_5g; | return bwn_ntab_tx_gain_epa_rev3_5g; | ||||
default: | default: | ||||
BWN_ERRPRINTF(mac->mac_sc, | BWN_ERRPRINTF(mac->mac_sc, | ||||
"No 5GHz EPA gain table available for this device\n"); | "No 5GHz EPA gain table available for this device\n"); | ||||
return NULL; | return NULL; | ||||
} | } | ||||
} else { | } else { | ||||
switch (phy->rev) { | switch (phy->rev) { | ||||
case 6: | case 6: | ||||
case 5: | 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; | return bwn_ntab_tx_gain_epa_rev3_hi_pwr_2g; | ||||
/* fall through */ | /* fall through */ | ||||
case 4: | case 4: | ||||
case 3: | case 3: | ||||
return bwn_ntab_tx_gain_epa_rev3_2g; | return bwn_ntab_tx_gain_epa_rev3_2g; | ||||
default: | default: | ||||
BWN_ERRPRINTF(mac->mac_sc, | BWN_ERRPRINTF(mac->mac_sc, | ||||
"No 2GHz EPA gain table available for this device\n"); | "No 2GHz EPA gain table available for this device\n"); | ||||
▲ Show 20 Lines • Show All 58 Lines • ▼ Show 20 Lines | struct bwn_nphy_gain_ctl_workaround_entry *bwn_nphy_get_gain_ctl_workaround_ent( | ||||
else if (mac->mac_phy.rev == 4) | else if (mac->mac_phy.rev == 4) | ||||
phy_idx = 1; | phy_idx = 1; | ||||
else | else | ||||
phy_idx = 0; | phy_idx = 0; | ||||
e = &nphy_gain_ctl_workaround[ghz5][phy_idx]; | e = &nphy_gain_ctl_workaround[ghz5][phy_idx]; | ||||
/* Some workarounds to the workarounds... */ | /* Some workarounds to the workarounds... */ | ||||
if (!ghz5) { | 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) | if (tr_iso > 7) | ||||
tr_iso = 3; | tr_iso = 3; | ||||
if (phy->rev >= 6) { | if (phy->rev >= 6) { | ||||
static const int gain_data[] = { 0x106a, 0x106c, 0x1074, | static const int gain_data[] = { 0x106a, 0x106c, 0x1074, | ||||
0x107c, 0x007e, 0x107e, | 0x107c, 0x007e, 0x107e, | ||||
0x207e, 0x307e, }; | 0x207e, 0x307e, }; | ||||
▲ Show 20 Lines • Show All 72 Lines • Show Last 20 Lines |