Add initial support for the AR9485 CUS198 / CUS230 variants.

These variants have a few differences from the default AR9485 NIC,
namely:

* a non-default antenna switch config;
* slightly different RX gain table setup;
* an external XLNA hooked up to a GPIO pin;
* (and not yet done) RSSI threshold differences when
  doing slow diversity.

To make this possible:

* Add the PCI device list from Linux ath9k, complete with vendor and
  sub-vendor IDs for various things to be enabled;
* .. and until FreeBSD learns about a PCI device list like this,
  write a search function inspired by the USB device enumeration code;
* add HAL_OPS_CONFIG to the HAL attach methods; the HAL can use this
  to initialise its local driver parameters upon attach;
* copy these parameters over in the AR9300 HAL;
* don't default to override the antenna switch - only do it for
  the chips that require it;
* I brought over ar9300_attenuation_apply() from ath9k which is cleaner
  and easier to read for this particular NIC.

This is a work in progress.  I'm worried that there's some post-AR9380
NIC out there which doesn't work without the antenna override set as
I currently haven't implemented bluetooth coexistence for the AR9380
and later HAL.  But I'd rather have this code in the tree and fix it
up before 11.0-RELEASE happens versus having a set of newer NICs
in laptops be effectively RX deaf.

Tested:

* AR9380 (STA)
* AR9485 CUS198 (STA)

Obtained from:	Qualcomm Atheros, Linux ath9k
This commit is contained in:
Adrian Chadd 2014-09-30 03:19:29 +00:00
parent c1efb88730
commit 9389d5a95e
23 changed files with 346 additions and 24 deletions

@ -1181,10 +1181,11 @@ struct ath_hal;
extern struct ath_hal_9300 * ar9300_new_state(u_int16_t devid,
HAL_SOFTC sc, HAL_BUS_TAG st, HAL_BUS_HANDLE sh, uint16_t *eepromdata,
HAL_OPS_CONFIG *ah_config,
HAL_STATUS *status);
extern struct ath_hal * ar9300_attach(u_int16_t devid,
HAL_SOFTC sc, HAL_BUS_TAG st, HAL_BUS_HANDLE sh, uint16_t *eepromdata,
HAL_STATUS *status);
HAL_OPS_CONFIG *ah_config, HAL_STATUS *status);
extern void ar9300_detach(struct ath_hal *ah);
extern void ar9300_read_revisions(struct ath_hal *ah);
extern HAL_BOOL ar9300_chip_test(struct ath_hal *ah);

@ -618,7 +618,8 @@ ar9300_read_revisions(struct ath_hal *ah)
*/
struct ath_hal *
ar9300_attach(u_int16_t devid, HAL_SOFTC sc, HAL_BUS_TAG st,
HAL_BUS_HANDLE sh, uint16_t *eepromdata, HAL_STATUS *status)
HAL_BUS_HANDLE sh, uint16_t *eepromdata, HAL_OPS_CONFIG *ah_config,
HAL_STATUS *status)
{
struct ath_hal_9300 *ahp;
struct ath_hal *ah;
@ -628,7 +629,7 @@ ar9300_attach(u_int16_t devid, HAL_SOFTC sc, HAL_BUS_TAG st,
HAL_NO_INTERSPERSED_READS;
/* NB: memory is returned zero'd */
ahp = ar9300_new_state(devid, sc, st, sh, eepromdata, status);
ahp = ar9300_new_state(devid, sc, st, sh, eepromdata, ah_config, status);
if (ahp == AH_NULL) {
return AH_NULL;
}
@ -654,12 +655,6 @@ ar9300_attach(u_int16_t devid, HAL_SOFTC sc, HAL_BUS_TAG st,
/* XXX FreeBSD: enable RX mitigation */
ah->ah_config.ath_hal_intr_mitigation_rx = 1;
/*
* XXX what's this do? Check in the qcamain driver code
* as to what it does.
*/
ah->ah_config.ath_hal_ext_atten_margin_cfg = 0;
/* interrupt mitigation */
#ifdef AR5416_INT_MITIGATION
if (ah->ah_config.ath_hal_intr_mitigation_rx != 0) {
@ -2378,7 +2373,9 @@ ar9300_detach(struct ath_hal *ah)
struct ath_hal_9300 *
ar9300_new_state(u_int16_t devid, HAL_SOFTC sc,
HAL_BUS_TAG st, HAL_BUS_HANDLE sh,
uint16_t *eepromdata, HAL_STATUS *status)
uint16_t *eepromdata,
HAL_OPS_CONFIG *ah_config,
HAL_STATUS *status)
{
static const u_int8_t defbssidmask[IEEE80211_ADDR_LEN] =
{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
@ -2430,7 +2427,7 @@ ar9300_new_state(u_int16_t devid, HAL_SOFTC sc,
** Initialize factory defaults in the private space
*/
// ath_hal_factory_defaults(AH_PRIVATE(ah), hal_conf_parm);
ar9300_config_defaults_freebsd(ah);
ar9300_config_defaults_freebsd(ah, ah_config);
/* XXX FreeBSD: cal is always in EEPROM */
#if 0
@ -2456,6 +2453,7 @@ ar9300_new_state(u_int16_t devid, HAL_SOFTC sc,
AH_PRIVATE(ah)->ah_tpScale = HAL_TP_SCALE_MAX; /* no scaling */
ahp->ah_atim_window = 0; /* [0..1000] */
ahp->ah_diversity_control =
ah->ah_config.ath_hal_diversity_control;
ahp->ah_antenna_switch_swap =
@ -3835,6 +3833,11 @@ ar9300_ant_div_comb_get_config(struct ath_hal *ah,
} else {
div_comb_conf->antdiv_configgroup = DEFAULT_ANTDIV_CONFIG_GROUP;
}
/*
* XXX TODO: allow the HAL to override the rssithres and fast_div_bias
* values (eg CUS198.)
*/
}
void

@ -1606,6 +1606,7 @@ HAL_BOOL ar9300_ant_ctrl_apply(struct ath_hal *ah, HAL_BOOL is_2ghz)
if ( AR_SREV_POSEIDON(ah) && (ahp->ah_lna_div_use_bt_ant_enable == TRUE) ) {
value &= ~AR_SWITCH_TABLE_COM2_ALL;
value |= ah->ah_config.ath_hal_ant_ctrl_comm2g_switch_enable;
HALDEBUG(ah, HAL_DEBUG_RESET, "%s: com2=0x%08x\n", __func__, value)
}
#endif /* ATH_ANT_DIV_COMB */
OS_REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM_2, AR_SWITCH_TABLE_COM2_ALL, value);
@ -1711,6 +1712,8 @@ HAL_BOOL ar9300_ant_ctrl_apply(struct ath_hal *ah, HAL_BOOL is_2ghz)
/* For WB225, need to swith ANT2 from BT to Wifi
* This will not affect HB125 LNA diversity feature.
*/
HALDEBUG(ah, HAL_DEBUG_RESET, "%s: com2=0x%08x\n", __func__,
ah->ah_config.ath_hal_ant_ctrl_comm2g_switch_enable)
OS_REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM_2, AR_SWITCH_TABLE_COM2_ALL,
ah->ah_config.ath_hal_ant_ctrl_comm2g_switch_enable);
break;
@ -1776,6 +1779,7 @@ ar9300_attenuation_margin_chain_get(struct ath_hal *ah, int chain,
return 0;
}
#if 0
HAL_BOOL ar9300_attenuation_apply(struct ath_hal *ah, u_int16_t channel)
{
u_int32_t value;
@ -1814,6 +1818,75 @@ HAL_BOOL ar9300_attenuation_apply(struct ath_hal *ah, u_int16_t channel)
}
return 0;
}
#endif
HAL_BOOL
ar9300_attenuation_apply(struct ath_hal *ah, u_int16_t channel)
{
int i;
uint32_t value;
uint32_t ext_atten_reg[3] = {
AR_PHY_EXT_ATTEN_CTL_0,
AR_PHY_EXT_ATTEN_CTL_1,
AR_PHY_EXT_ATTEN_CTL_2
};
/*
* If it's an AR9462 and we're receiving on the second
* chain only, set the chain 0 details from chain 1
* calibration.
*
* This is from ath9k.
*/
if (AR_SREV_JUPITER(ah) && (AH9300(ah)->ah_rx_chainmask == 0x2)) {
value = ar9300_attenuation_chain_get(ah, 1, channel);
OS_REG_RMW_FIELD(ah, ext_atten_reg[0],
AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, value);
value = ar9300_attenuation_margin_chain_get(ah, 1, channel);
OS_REG_RMW_FIELD(ah, ext_atten_reg[0],
AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN, value);
}
/*
* Now, loop over the configured transmit chains and
* load in the attenuation/margin settings as appropriate.
*/
for (i = 0; i < 3; i++) {
if ((AH9300(ah)->ah_tx_chainmask & (1 << i)) == 0)
continue;
value = ar9300_attenuation_chain_get(ah, i, channel);
OS_REG_RMW_FIELD(ah, ext_atten_reg[i],
AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB,
value);
if (AR_SREV_POSEIDON(ah) &&
(ar9300_rx_gain_index_get(ah) == 0) &&
ah->ah_config.ath_hal_ext_atten_margin_cfg) {
value = 5;
} else {
value = ar9300_attenuation_margin_chain_get(ah, 0,
channel);
}
/*
* I'm not sure why it's loading in this setting into
* the chain 0 margin regardless of the current chain.
*/
if (ah->ah_config.ath_hal_min_gainidx)
OS_REG_RMW_FIELD(ah,
AR_PHY_EXT_ATTEN_CTL_0,
AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN,
value);
OS_REG_RMW_FIELD(ah,
ext_atten_reg[i],
AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN,
value);
}
return (0);
}
static u_int16_t ar9300_quick_drop_get(struct ath_hal *ah,
int chain, u_int16_t channel)

@ -254,7 +254,27 @@ ar9300_attach_freebsd_ops(struct ath_hal *ah)
ah->ah_divLnaConfSet = ar9300_ant_div_comb_set_config;
/* Setup HAL configuration defaults */
/* XXX cus198 defaults from ath9k */
/* xlna_gpio = 9 */
/* xatten_margin_cfg = true */
/* alt_mingainidx = true */
/* comm2g_switch_enable = 0x000bbb88 */
/* ant_comb.low_rssi_thresh = 20 */
/* ant_comb.fast_div_bias = 3 */
#if 0
/*
* The HAL code treats this as a mask.
* The ath9k code above treats it as a bit offset.
* So it should be set to 0x200, not 0x9.
*/
ah->ah_config.ath_hal_ext_lna_ctl_gpio = 0x200; /* bit 9 */
ah->ah_config.ath_hal_ext_atten_margin_cfg = AH_TRUE;
ah->ah_config.ath_hal_min_gainidx = AH_TRUE;
ah->ah_config.ath_hal_ant_ctrl_comm2g_switch_enable = 0x000bbb88;
/* XXX low_rssi_thresh */
/* XXX fast_div_bias */
#endif
}
HAL_BOOL
@ -338,9 +358,11 @@ ar9300_ani_poll_freebsd(struct ath_hal *ah,
* wants.
*/
void
ar9300_config_defaults_freebsd(struct ath_hal *ah)
ar9300_config_defaults_freebsd(struct ath_hal *ah, HAL_OPS_CONFIG *ah_config)
{
/* Until FreeBSD's HAL does this by default - just copy */
OS_MEMCPY(&ah->ah_config, ah_config, sizeof(HAL_OPS_CONFIG));
ah->ah_config.ath_hal_enable_ani = AH_TRUE;
}

@ -11,7 +11,8 @@ extern HAL_STATUS ar9300_eeprom_get_freebsd(struct ath_hal *, int param,
extern HAL_BOOL ar9300_stop_tx_dma_freebsd(struct ath_hal *ah, u_int q);
extern void ar9300_ani_poll_freebsd(struct ath_hal *ah,
const struct ieee80211_channel *chan);
extern void ar9300_config_defaults_freebsd(struct ath_hal *ah);
extern void ar9300_config_defaults_freebsd(struct ath_hal *ah,
HAL_OPS_CONFIG *ah_config);
extern HAL_BOOL ar9300_stop_dma_receive_freebsd(struct ath_hal *ah);
extern HAL_BOOL ar9300_get_pending_interrupts_freebsd(struct ath_hal *ah,
HAL_INT *masked);

@ -6151,6 +6151,7 @@ ar9300_ant_ctrl_set_lna_div_use_bt_ant(struct ath_hal *ah, HAL_BOOL enable, cons
value &= ~AR_SWITCH_TABLE_COM2_ALL;
value |= ah->ah_config.ath_hal_ant_ctrl_comm2g_switch_enable;
}
HALDEBUG(ah, HAL_DEBUG_RESET, "%s: com2=0x%08x\n", __func__, value);
OS_REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM_2, AR_SWITCH_TABLE_COM2_ALL, value);
value = ar9300_eeprom_get(ahp, EEP_ANTDIV_control);

@ -55,7 +55,9 @@ ath_hal_probe(uint16_t vendorid, uint16_t devid)
*/
struct ath_hal*
ath_hal_attach(uint16_t devid, HAL_SOFTC sc,
HAL_BUS_TAG st, HAL_BUS_HANDLE sh, uint16_t *eepromdata, HAL_STATUS *error)
HAL_BUS_TAG st, HAL_BUS_HANDLE sh, uint16_t *eepromdata,
HAL_OPS_CONFIG *ah_config,
HAL_STATUS *error)
{
struct ath_hal_chip * const *pchip;
@ -66,7 +68,8 @@ ath_hal_attach(uint16_t devid, HAL_SOFTC sc,
/* XXX don't have vendorid, assume atheros one works */
if (chip->probe(ATHEROS_VENDOR_ID, devid) == AH_NULL)
continue;
ah = chip->attach(devid, sc, st, sh, eepromdata, error);
ah = chip->attach(devid, sc, st, sh, eepromdata, ah_config,
error);
if (ah != AH_NULL) {
/* copy back private state to public area */
ah->ah_devid = AH_PRIVATE(ah)->ah_devid;

@ -1264,6 +1264,7 @@ typedef struct
int ath_hal_show_bb_panic;
int ath_hal_ant_ctrl_comm2g_switch_enable;
int ath_hal_ext_atten_margin_cfg;
int ath_hal_min_gainidx;
int ath_hal_war70c;
uint32_t ath_hal_mci_config;
} HAL_OPS_CONFIG;
@ -1616,7 +1617,8 @@ extern const char *__ahdecl ath_hal_probe(uint16_t vendorid, uint16_t devid);
* be returned if the status parameter is non-zero.
*/
extern struct ath_hal * __ahdecl ath_hal_attach(uint16_t devid, HAL_SOFTC,
HAL_BUS_TAG, HAL_BUS_HANDLE, uint16_t *eepromdata, HAL_STATUS* status);
HAL_BUS_TAG, HAL_BUS_HANDLE, uint16_t *eepromdata,
HAL_OPS_CONFIG *ah_config, HAL_STATUS* status);
extern const char *ath_hal_mac_name(struct ath_hal *);
extern const char *ath_hal_rf_name(struct ath_hal *);

@ -91,6 +91,7 @@ struct ath_hal_chip {
const char *(*probe)(uint16_t vendorid, uint16_t devid);
struct ath_hal *(*attach)(uint16_t devid, HAL_SOFTC,
HAL_BUS_TAG, HAL_BUS_HANDLE, uint16_t *eepromdata,
HAL_OPS_CONFIG *ah,
HAL_STATUS *error);
};
#ifndef AH_CHIP

@ -183,7 +183,7 @@ static HAL_BOOL ar5210FillCapabilityInfo(struct ath_hal *ah);
*/
static struct ath_hal *
ar5210Attach(uint16_t devid, HAL_SOFTC sc, HAL_BUS_TAG st, HAL_BUS_HANDLE sh,
uint16_t *eepromdata, HAL_STATUS *status)
uint16_t *eepromdata, HAL_OPS_CONFIG *ah_config, HAL_STATUS *status)
{
#define N(a) (sizeof(a)/sizeof(a[0]))
struct ath_hal_5210 *ahp;

@ -203,7 +203,7 @@ ar5211GetRadioRev(struct ath_hal *ah)
static struct ath_hal *
ar5211Attach(uint16_t devid, HAL_SOFTC sc,
HAL_BUS_TAG st, HAL_BUS_HANDLE sh, uint16_t *eepromdata,
HAL_STATUS *status)
HAL_OPS_CONFIG *ah_config, HAL_STATUS *status)
{
#define N(a) (sizeof(a)/sizeof(a[0]))
struct ath_hal_5211 *ahp;

@ -317,7 +317,7 @@ ar5212IsMacSupported(uint8_t macVersion, uint8_t macRev)
static struct ath_hal *
ar5212Attach(uint16_t devid, HAL_SOFTC sc,
HAL_BUS_TAG st, HAL_BUS_HANDLE sh, uint16_t *eepromdata,
HAL_STATUS *status)
HAL_OPS_CONFIG *ah_config, HAL_STATUS *status)
{
#define AH_EEPROM_PROTECT(ah) \
(AH_PRIVATE(ah)->ah_ispcie)? AR_EEPROM_PROTECT_PCIE : AR_EEPROM_PROTECT)

@ -62,7 +62,7 @@ ar5312AniSetup(struct ath_hal *ah)
static struct ath_hal *
ar5312Attach(uint16_t devid, HAL_SOFTC sc,
HAL_BUS_TAG st, HAL_BUS_HANDLE sh, uint16_t *eepromdata,
HAL_STATUS *status)
HAL_OPS_CONFIG *ah_config, HAL_STATUS *status)
{
struct ath_hal_5212 *ahp = AH_NULL;
struct ath_hal *ah;

@ -297,7 +297,7 @@ ar5416GetRadioRev(struct ath_hal *ah)
static struct ath_hal *
ar5416Attach(uint16_t devid, HAL_SOFTC sc,
HAL_BUS_TAG st, HAL_BUS_HANDLE sh, uint16_t *eepromdata,
HAL_STATUS *status)
HAL_OPS_CONFIG *ah_config, HAL_STATUS *status)
{
struct ath_hal_5416 *ahp5416;
struct ath_hal_5212 *ahp;

@ -69,7 +69,9 @@ static HAL_BOOL ar9130FillCapabilityInfo(struct ath_hal *ah);
*/
static struct ath_hal *
ar9130Attach(uint16_t devid, HAL_SOFTC sc,
HAL_BUS_TAG st, HAL_BUS_HANDLE sh, uint16_t *eepromdata, HAL_STATUS *status)
HAL_BUS_TAG st, HAL_BUS_HANDLE sh, uint16_t *eepromdata,
HAL_OPS_CONFIG *ah_config,
HAL_STATUS *status)
{
struct ath_hal_5416 *ahp5416;
struct ath_hal_5212 *ahp;

@ -114,6 +114,7 @@ ar9160InitPLL(struct ath_hal *ah, const struct ieee80211_channel *chan)
static struct ath_hal *
ar9160Attach(uint16_t devid, HAL_SOFTC sc,
HAL_BUS_TAG st, HAL_BUS_HANDLE sh, uint16_t *eepromdata,
HAL_OPS_CONFIG *ah_config,
HAL_STATUS *status)
{
struct ath_hal_5416 *ahp5416;

@ -148,6 +148,7 @@ ar9280InitPLL(struct ath_hal *ah, const struct ieee80211_channel *chan)
static struct ath_hal *
ar9280Attach(uint16_t devid, HAL_SOFTC sc,
HAL_BUS_TAG st, HAL_BUS_HANDLE sh, uint16_t *eepromdata,
HAL_OPS_CONFIG *ah_config,
HAL_STATUS *status)
{
struct ath_hal_9280 *ahp9280;

@ -133,6 +133,7 @@ ar9285_eeprom_print_diversity_settings(struct ath_hal *ah)
static struct ath_hal *
ar9285Attach(uint16_t devid, HAL_SOFTC sc,
HAL_BUS_TAG st, HAL_BUS_HANDLE sh, uint16_t *eepromdata,
HAL_OPS_CONFIG *ah_config,
HAL_STATUS *status)
{
struct ath_hal_9285 *ahp9285;

@ -111,6 +111,7 @@ ar9287AniSetup(struct ath_hal *ah)
static struct ath_hal *
ar9287Attach(uint16_t devid, HAL_SOFTC sc,
HAL_BUS_TAG st, HAL_BUS_HANDLE sh, uint16_t *eepromdata,
HAL_OPS_CONFIG *ah_config,
HAL_STATUS *status)
{
struct ath_hal_9287 *ahp9287;

@ -435,6 +435,81 @@ _ath_power_restore_power_state(struct ath_softc *sc, const char *file, int line)
}
/*
* Configure the initial HAL configuration values based on bus
* specific parameters.
*
* Some PCI IDs and other information may need tweaking.
*
* XXX TODO: ath9k and the Atheros HAL only program comm2g_switch_enable
* if BT antenna diversity isn't enabled.
*
* So, let's also figure out how to enable BT diversity for AR9485.
*/
static void
ath_setup_hal_config(struct ath_softc *sc, HAL_OPS_CONFIG *ah_config)
{
/* XXX TODO: only for PCI devices? */
if (sc->sc_pci_devinfo & (ATH_PCI_CUS198 | ATH_PCI_CUS230)) {
ah_config->ath_hal_ext_lna_ctl_gpio = 0x200; /* bit 9 */
ah_config->ath_hal_ext_atten_margin_cfg = AH_TRUE;
ah_config->ath_hal_min_gainidx = AH_TRUE;
ah_config->ath_hal_ant_ctrl_comm2g_switch_enable = 0x000bbb88;
/* XXX low_rssi_thresh */
/* XXX fast_div_bias */
device_printf(sc->sc_dev, "configuring for %s\n",
(sc->sc_pci_devinfo & ATH_PCI_CUS198) ?
"CUS198" : "CUS230");
}
if (sc->sc_pci_devinfo & ATH_PCI_CUS217)
device_printf(sc->sc_dev, "CUS217 card detected\n");
if (sc->sc_pci_devinfo & ATH_PCI_CUS252)
device_printf(sc->sc_dev, "CUS252 card detected\n");
if (sc->sc_pci_devinfo & ATH_PCI_AR9565_1ANT)
device_printf(sc->sc_dev, "WB335 1-ANT card detected\n");
if (sc->sc_pci_devinfo & ATH_PCI_AR9565_2ANT)
device_printf(sc->sc_dev, "WB335 2-ANT card detected\n");
if (sc->sc_pci_devinfo & ATH_PCI_KILLER)
device_printf(sc->sc_dev, "Killer Wireless card detected\n");
#if 0
/*
* Some WB335 cards do not support antenna diversity. Since
* we use a hardcoded value for AR9565 instead of using the
* EEPROM/OTP data, remove the combining feature from
* the HW capabilities bitmap.
*/
if (sc->sc_pci_devinfo & (ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_AR9565_2ANT)) {
if (!(sc->sc_pci_devinfo & ATH9K_PCI_BT_ANT_DIV))
pCap->hw_caps &= ~ATH9K_HW_CAP_ANT_DIV_COMB;
}
if (sc->sc_pci_devinfo & ATH9K_PCI_BT_ANT_DIV) {
pCap->hw_caps |= ATH9K_HW_CAP_BT_ANT_DIV;
device_printf(sc->sc_dev, "Set BT/WLAN RX diversity capability\n");
}
#endif
if (sc->sc_pci_devinfo & ATH_PCI_D3_L1_WAR) {
ah_config->ath_hal_pcie_waen = 0x0040473b;
device_printf(sc->sc_dev, "Enable WAR for ASPM D3/L1\n");
}
#if 0
if (sc->sc_pci_devinfo & ATH9K_PCI_NO_PLL_PWRSAVE) {
ah->config.no_pll_pwrsave = true;
device_printf(sc->sc_dev, "Disable PLL PowerSave\n");
}
#endif
}
#define HAL_MODE_HT20 (HAL_MODE_11NG_HT20 | HAL_MODE_11NA_HT20)
#define HAL_MODE_HT40 \
(HAL_MODE_11NG_HT40PLUS | HAL_MODE_11NG_HT40MINUS | \
@ -450,6 +525,7 @@ ath_attach(u_int16_t devid, struct ath_softc *sc)
u_int wmodes;
uint8_t macaddr[IEEE80211_ADDR_LEN];
int rx_chainmask, tx_chainmask;
HAL_OPS_CONFIG ah_config;
DPRINTF(sc, ATH_DEBUG_ANY, "%s: devid 0x%x\n", __func__, devid);
@ -468,8 +544,17 @@ ath_attach(u_int16_t devid, struct ath_softc *sc)
device_get_unit(sc->sc_dev));
CURVNET_RESTORE();
/*
* Configure the initial configuration data.
*
* This is stuff that may be needed early during attach
* rather than done via configuration calls later.
*/
bzero(&ah_config, sizeof(ah_config));
ath_setup_hal_config(sc, &ah_config);
ah = ath_hal_attach(devid, sc, sc->sc_st, sc->sc_sh,
sc->sc_eepromdata, &status);
sc->sc_eepromdata, &ah_config, &status);
if (ah == NULL) {
if_printf(ifp, "unable to attach hardware; HAL status %u\n",
status);
@ -7101,6 +7186,6 @@ ath_node_recv_pspoll(struct ieee80211_node *ni, struct mbuf *m)
MODULE_VERSION(if_ath, 1);
MODULE_DEPEND(if_ath, wlan, 1, 1, 1); /* 802.11 media layer */
#if defined(IEEE80211_ALQ) || defined(AH_DEBUG_ALQ)
#if defined(IEEE80211_ALQ) || defined(AH_DEBUG_ALQ) || defined(ATH_DEBUG_ALQ)
MODULE_DEPEND(if_ath, alq, 1, 1, 1);
#endif

@ -209,6 +209,10 @@ bad:
return (error);
}
/*
* XXX need to low_rssi_thresh config from ath9k, to support CUS198
* antenna diversity correctly.
*/
static HAL_BOOL
ath_is_alt_ant_ratio_better(int alt_ratio, int maxdelta, int mindelta,
int main_rssi_avg, int alt_rssi_avg, int pkt_count)

@ -80,6 +80,98 @@ struct ath_pci_softc {
void *sc_ih; /* interrupt handler */
};
/*
* XXX eventually this should be some system level definition
* so modules will hvae probe/attach information like USB.
* But for now..
*/
struct pci_device_id {
int vendor_id;
int device_id;
int sub_vendor_id;
int sub_device_id;
int driver_data;
int match_populated:1;
int match_vendor_id:1;
int match_device_id:1;
int match_sub_vendor_id:1;
int match_sub_device_id:1;
};
#define PCI_VDEVICE(v, s) \
.vendor_id = (v), \
.device_id = (s), \
.match_populated = 1, \
.match_vendor_id = 1, \
.match_device_id = 1
#define PCI_DEVICE_SUB(v, d, dv, ds) \
.match_populated = 1, \
.vendor_id = (v), .match_vendor_id = 1, \
.device_id = (d), .match_device_id = 1, \
.sub_vendor_id = (dv), .match_sub_vendor_id = 1, \
.sub_device_id = (ds), .match_sub_device_id = 1
#define PCI_VENDOR_ID_ATHEROS 0x168c
#define PCI_VENDOR_ID_SAMSUNG 0x144d
#define PCI_VENDOR_ID_AZWAVE 0x1a3b
#define PCI_VENDOR_ID_FOXCONN 0x105b
#define PCI_VENDOR_ID_ATTANSIC 0x1969
#define PCI_VENDOR_ID_ASUSTEK 0x1043
#define PCI_VENDOR_ID_DELL 0x1028
#define PCI_VENDOR_ID_QMI 0x1a32
#define PCI_VENDOR_ID_LENOVO 0x17aa
#define PCI_VENDOR_ID_HP 0x103c
#include "if_ath_pci_devlist.h"
/*
* Attempt to find a match for the given device in
* the given device table.
*
* Returns the device structure or NULL if no matching
* PCI device is found.
*/
static const struct pci_device_id *
ath_pci_probe_device(device_t dev, const struct pci_device_id *dev_table, int nentries)
{
int i;
int vendor_id, device_id;
int sub_vendor_id, sub_device_id;
vendor_id = pci_get_vendor(dev);
device_id = pci_get_device(dev);
sub_vendor_id = pci_get_subvendor(dev);
sub_device_id = pci_get_subdevice(dev);
for (i = 0; i < nentries; i++) {
/* Don't match on non-populated (eg empty) entries */
if (! dev_table[i].match_populated)
continue;
if (dev_table[i].match_vendor_id &&
(dev_table[i].vendor_id != vendor_id))
continue;
if (dev_table[i].match_device_id &&
(dev_table[i].device_id != device_id))
continue;
if (dev_table[i].match_sub_vendor_id &&
(dev_table[i].sub_vendor_id != sub_vendor_id))
continue;
if (dev_table[i].match_sub_device_id &&
(dev_table[i].sub_device_id != sub_device_id))
continue;
/* Match */
return (&dev_table[i]);
}
return (NULL);
}
#define BS_BAR 0x10
#define PCIR_RETRY_TIMEOUT 0x41
#define PCIR_CFG_PMCSR 0x48
@ -150,9 +242,15 @@ ath_pci_attach(device_t dev)
const struct firmware *fw = NULL;
const char *buf;
#endif
const struct pci_device_id *pd;
sc->sc_dev = dev;
/* Do this lookup anyway; figure out what to do with it later */
pd = ath_pci_probe_device(dev, ath_pci_id_table, nitems(ath_pci_id_table));
if (pd)
sc->sc_pci_devinfo = pd->driver_data;
/*
* Enable bus mastering.
*/

@ -81,6 +81,25 @@
#define ATH_BEACON_CWMIN_DEFAULT 0 /* default cwmin for ap beacon q */
#define ATH_BEACON_CWMAX_DEFAULT 0 /* default cwmax for ap beacon q */
/*
* The following bits can be set during the PCI (and perhaps non-PCI
* later) device probe path.
*
* It controls some of the driver and HAL behaviour.
*/
#define ATH_PCI_CUS198 0x0001
#define ATH_PCI_CUS230 0x0002
#define ATH_PCI_CUS217 0x0004
#define ATH_PCI_CUS252 0x0008
#define ATH_PCI_WOW 0x0010
#define ATH_PCI_BT_ANT_DIV 0x0020
#define ATH_PCI_D3_L1_WAR 0x0040
#define ATH_PCI_AR9565_1ANT 0x0080
#define ATH_PCI_AR9565_2ANT 0x0100
#define ATH_PCI_NO_PLL_PWRSAVE 0x0200
#define ATH_PCI_KILLER 0x0400
/*
* The key cache is used for h/w cipher state and also for
* tracking station state such as the current tx antenna.
@ -884,6 +903,9 @@ struct ath_softc {
HAL_POWER_MODE sc_cur_powerstate;
int sc_powersave_refcnt;
/* ATH_PCI_* flags */
uint32_t sc_pci_devinfo;
};
#define ATH_LOCK_INIT(_sc) \