aboutsummaryrefslogtreecommitdiff
path: root/sys/contrib
diff options
context:
space:
mode:
authorAdrian Chadd <adrian@FreeBSD.org>2014-09-30 03:19:29 +0000
committerAdrian Chadd <adrian@FreeBSD.org>2014-09-30 03:19:29 +0000
commit9389d5a95ea6c5e284ee3866a9044ba97482ec8d (patch)
tree6d3205f98a98993af31763f2b88722b87d3dd7f6 /sys/contrib
parentc1efb887306b9d50da81714b633c9bc78195595d (diff)
downloadsrc-9389d5a95ea6c5e284ee3866a9044ba97482ec8d.tar.gz
src-9389d5a95ea6c5e284ee3866a9044ba97482ec8d.zip
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
Notes
Notes: svn path=/head/; revision=272292
Diffstat (limited to 'sys/contrib')
-rw-r--r--sys/contrib/dev/ath/ath_hal/ar9300/ar9300.h3
-rw-r--r--sys/contrib/dev/ath/ath_hal/ar9300/ar9300_attach.c23
-rw-r--r--sys/contrib/dev/ath/ath_hal/ar9300/ar9300_eeprom.c73
-rw-r--r--sys/contrib/dev/ath/ath_hal/ar9300/ar9300_freebsd.c24
-rw-r--r--sys/contrib/dev/ath/ath_hal/ar9300/ar9300_freebsd.h3
-rw-r--r--sys/contrib/dev/ath/ath_hal/ar9300/ar9300_reset.c1
6 files changed, 114 insertions, 13 deletions
diff --git a/sys/contrib/dev/ath/ath_hal/ar9300/ar9300.h b/sys/contrib/dev/ath/ath_hal/ar9300/ar9300.h
index 73b902f1b299..30c55a077ffe 100644
--- a/sys/contrib/dev/ath/ath_hal/ar9300/ar9300.h
+++ b/sys/contrib/dev/ath/ath_hal/ar9300/ar9300.h
@@ -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);
diff --git a/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_attach.c b/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_attach.c
index 9cc99ec701f0..80dc2a3b3068 100644
--- a/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_attach.c
+++ b/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_attach.c
@@ -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
diff --git a/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_eeprom.c b/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_eeprom.c
index ba7777e3079b..669104a00c55 100644
--- a/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_eeprom.c
+++ b/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_eeprom.c
@@ -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)
diff --git a/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_freebsd.c b/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_freebsd.c
index ff4baa01892b..bcd0a26759e6 100644
--- a/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_freebsd.c
+++ b/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_freebsd.c
@@ -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;
}
diff --git a/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_freebsd.h b/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_freebsd.h
index c07c32fa01b1..524c3f3fce5d 100644
--- a/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_freebsd.h
+++ b/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_freebsd.h
@@ -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);
diff --git a/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_reset.c b/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_reset.c
index 1090c9c59ab7..51ce195ff56c 100644
--- a/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_reset.c
+++ b/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_reset.c
@@ -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);