Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 30 Sep 2014 03:19:29 +0000 (UTC)
From:      Adrian Chadd <adrian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r272292 - in head/sys: contrib/dev/ath/ath_hal/ar9300 dev/ath dev/ath/ath_hal dev/ath/ath_hal/ar5210 dev/ath/ath_hal/ar5211 dev/ath/ath_hal/ar5212 dev/ath/ath_hal/ar5312 dev/ath/ath_hal...
Message-ID:  <201409300319.s8U3JTkm005411@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: adrian
Date: Tue Sep 30 03:19:29 2014
New Revision: 272292
URL: http://svnweb.freebsd.org/changeset/base/272292

Log:
  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

Modified:
  head/sys/contrib/dev/ath/ath_hal/ar9300/ar9300.h
  head/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_attach.c
  head/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_eeprom.c
  head/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_freebsd.c
  head/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_freebsd.h
  head/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_reset.c
  head/sys/dev/ath/ath_hal/ah.c
  head/sys/dev/ath/ath_hal/ah.h
  head/sys/dev/ath/ath_hal/ah_internal.h
  head/sys/dev/ath/ath_hal/ar5210/ar5210_attach.c
  head/sys/dev/ath/ath_hal/ar5211/ar5211_attach.c
  head/sys/dev/ath/ath_hal/ar5212/ar5212_attach.c
  head/sys/dev/ath/ath_hal/ar5312/ar5312_attach.c
  head/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c
  head/sys/dev/ath/ath_hal/ar9001/ar9130_attach.c
  head/sys/dev/ath/ath_hal/ar9001/ar9160_attach.c
  head/sys/dev/ath/ath_hal/ar9002/ar9280_attach.c
  head/sys/dev/ath/ath_hal/ar9002/ar9285_attach.c
  head/sys/dev/ath/ath_hal/ar9002/ar9287_attach.c
  head/sys/dev/ath/if_ath.c
  head/sys/dev/ath/if_ath_lna_div.c
  head/sys/dev/ath/if_ath_pci.c
  head/sys/dev/ath/if_athvar.h

Modified: head/sys/contrib/dev/ath/ath_hal/ar9300/ar9300.h
==============================================================================
--- head/sys/contrib/dev/ath/ath_hal/ar9300/ar9300.h	Tue Sep 30 00:06:53 2014	(r272291)
+++ head/sys/contrib/dev/ath/ath_hal/ar9300/ar9300.h	Tue Sep 30 03:19:29 2014	(r272292)
@@ -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);

Modified: head/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_attach.c
==============================================================================
--- head/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_attach.c	Tue Sep 30 00:06:53 2014	(r272291)
+++ head/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_attach.c	Tue Sep 30 03:19:29 2014	(r272292)
@@ -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
     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
     /* 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_SO
     ** 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_SO
     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 at
     } 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

Modified: head/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_eeprom.c
==============================================================================
--- head/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_eeprom.c	Tue Sep 30 00:06:53 2014	(r272291)
+++ head/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_eeprom.c	Tue Sep 30 03:19:29 2014	(r272292)
@@ -1606,6 +1606,7 @@ HAL_BOOL ar9300_ant_ctrl_apply(struct at
     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 at
             /* 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(stru
     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
     }
     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)

Modified: head/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_freebsd.c
==============================================================================
--- head/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_freebsd.c	Tue Sep 30 00:06:53 2014	(r272291)
+++ head/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_freebsd.c	Tue Sep 30 03:19:29 2014	(r272292)
@@ -254,7 +254,27 @@ ar9300_attach_freebsd_ops(struct ath_hal
 	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 *
  * 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;
 }
 

Modified: head/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_freebsd.h
==============================================================================
--- head/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_freebsd.h	Tue Sep 30 00:06:53 2014	(r272291)
+++ head/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_freebsd.h	Tue Sep 30 03:19:29 2014	(r272292)
@@ -11,7 +11,8 @@ extern	HAL_STATUS ar9300_eeprom_get_free
 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);

Modified: head/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_reset.c
==============================================================================
--- head/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_reset.c	Tue Sep 30 00:06:53 2014	(r272291)
+++ head/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_reset.c	Tue Sep 30 03:19:29 2014	(r272292)
@@ -6151,6 +6151,7 @@ ar9300_ant_ctrl_set_lna_div_use_bt_ant(s
             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);

Modified: head/sys/dev/ath/ath_hal/ah.c
==============================================================================
--- head/sys/dev/ath/ath_hal/ah.c	Tue Sep 30 00:06:53 2014	(r272291)
+++ head/sys/dev/ath/ath_hal/ah.c	Tue Sep 30 03:19:29 2014	(r272292)
@@ -55,7 +55,9 @@ ath_hal_probe(uint16_t vendorid, uint16_
  */
 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
 		/* 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;

Modified: head/sys/dev/ath/ath_hal/ah.h
==============================================================================
--- head/sys/dev/ath/ath_hal/ah.h	Tue Sep 30 00:06:53 2014	(r272291)
+++ head/sys/dev/ath/ath_hal/ah.h	Tue Sep 30 03:19:29 2014	(r272292)
@@ -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_prob
  * 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 *);

Modified: head/sys/dev/ath/ath_hal/ah_internal.h
==============================================================================
--- head/sys/dev/ath/ath_hal/ah_internal.h	Tue Sep 30 00:06:53 2014	(r272291)
+++ head/sys/dev/ath/ath_hal/ah_internal.h	Tue Sep 30 03:19:29 2014	(r272292)
@@ -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

Modified: head/sys/dev/ath/ath_hal/ar5210/ar5210_attach.c
==============================================================================
--- head/sys/dev/ath/ath_hal/ar5210/ar5210_attach.c	Tue Sep 30 00:06:53 2014	(r272291)
+++ head/sys/dev/ath/ath_hal/ar5210/ar5210_attach.c	Tue Sep 30 03:19:29 2014	(r272292)
@@ -183,7 +183,7 @@ static HAL_BOOL ar5210FillCapabilityInfo
  */
 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;

Modified: head/sys/dev/ath/ath_hal/ar5211/ar5211_attach.c
==============================================================================
--- head/sys/dev/ath/ath_hal/ar5211/ar5211_attach.c	Tue Sep 30 00:06:53 2014	(r272291)
+++ head/sys/dev/ath/ath_hal/ar5211/ar5211_attach.c	Tue Sep 30 03:19:29 2014	(r272292)
@@ -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;

Modified: head/sys/dev/ath/ath_hal/ar5212/ar5212_attach.c
==============================================================================
--- head/sys/dev/ath/ath_hal/ar5212/ar5212_attach.c	Tue Sep 30 00:06:53 2014	(r272291)
+++ head/sys/dev/ath/ath_hal/ar5212/ar5212_attach.c	Tue Sep 30 03:19:29 2014	(r272292)
@@ -317,7 +317,7 @@ ar5212IsMacSupported(uint8_t macVersion,
 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)

Modified: head/sys/dev/ath/ath_hal/ar5312/ar5312_attach.c
==============================================================================
--- head/sys/dev/ath/ath_hal/ar5312/ar5312_attach.c	Tue Sep 30 00:06:53 2014	(r272291)
+++ head/sys/dev/ath/ath_hal/ar5312/ar5312_attach.c	Tue Sep 30 03:19:29 2014	(r272292)
@@ -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;

Modified: head/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c
==============================================================================
--- head/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c	Tue Sep 30 00:06:53 2014	(r272291)
+++ head/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c	Tue Sep 30 03:19:29 2014	(r272292)
@@ -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;

Modified: head/sys/dev/ath/ath_hal/ar9001/ar9130_attach.c
==============================================================================
--- head/sys/dev/ath/ath_hal/ar9001/ar9130_attach.c	Tue Sep 30 00:06:53 2014	(r272291)
+++ head/sys/dev/ath/ath_hal/ar9001/ar9130_attach.c	Tue Sep 30 03:19:29 2014	(r272292)
@@ -69,7 +69,9 @@ static HAL_BOOL ar9130FillCapabilityInfo
  */
 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;

Modified: head/sys/dev/ath/ath_hal/ar9001/ar9160_attach.c
==============================================================================
--- head/sys/dev/ath/ath_hal/ar9001/ar9160_attach.c	Tue Sep 30 00:06:53 2014	(r272291)
+++ head/sys/dev/ath/ath_hal/ar9001/ar9160_attach.c	Tue Sep 30 03:19:29 2014	(r272292)
@@ -114,6 +114,7 @@ ar9160InitPLL(struct ath_hal *ah, const 
 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;

Modified: head/sys/dev/ath/ath_hal/ar9002/ar9280_attach.c
==============================================================================
--- head/sys/dev/ath/ath_hal/ar9002/ar9280_attach.c	Tue Sep 30 00:06:53 2014	(r272291)
+++ head/sys/dev/ath/ath_hal/ar9002/ar9280_attach.c	Tue Sep 30 03:19:29 2014	(r272292)
@@ -148,6 +148,7 @@ ar9280InitPLL(struct ath_hal *ah, const 
 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;

Modified: head/sys/dev/ath/ath_hal/ar9002/ar9285_attach.c
==============================================================================
--- head/sys/dev/ath/ath_hal/ar9002/ar9285_attach.c	Tue Sep 30 00:06:53 2014	(r272291)
+++ head/sys/dev/ath/ath_hal/ar9002/ar9285_attach.c	Tue Sep 30 03:19:29 2014	(r272292)
@@ -133,6 +133,7 @@ ar9285_eeprom_print_diversity_settings(s
 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;

Modified: head/sys/dev/ath/ath_hal/ar9002/ar9287_attach.c
==============================================================================
--- head/sys/dev/ath/ath_hal/ar9002/ar9287_attach.c	Tue Sep 30 00:06:53 2014	(r272291)
+++ head/sys/dev/ath/ath_hal/ar9002/ar9287_attach.c	Tue Sep 30 03:19:29 2014	(r272292)
@@ -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;

Modified: head/sys/dev/ath/if_ath.c
==============================================================================
--- head/sys/dev/ath/if_ath.c	Tue Sep 30 00:06:53 2014	(r272291)
+++ head/sys/dev/ath/if_ath.c	Tue Sep 30 03:19:29 2014	(r272292)
@@ -435,6 +435,81 @@ _ath_power_restore_power_state(struct at
 
 }
 
+/*
+ * 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_s
 	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_s
 		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_no
 
 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

Modified: head/sys/dev/ath/if_ath_lna_div.c
==============================================================================
--- head/sys/dev/ath/if_ath_lna_div.c	Tue Sep 30 00:06:53 2014	(r272291)
+++ head/sys/dev/ath/if_ath_lna_div.c	Tue Sep 30 03:19:29 2014	(r272292)
@@ -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)

Modified: head/sys/dev/ath/if_ath_pci.c
==============================================================================
--- head/sys/dev/ath/if_ath_pci.c	Tue Sep 30 00:06:53 2014	(r272291)
+++ head/sys/dev/ath/if_ath_pci.c	Tue Sep 30 03:19:29 2014	(r272292)
@@ -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.
 	 */

Modified: head/sys/dev/ath/if_athvar.h
==============================================================================
--- head/sys/dev/ath/if_athvar.h	Tue Sep 30 00:06:53 2014	(r272291)
+++ head/sys/dev/ath/if_athvar.h	Tue Sep 30 03:19:29 2014	(r272292)
@@ -82,6 +82,25 @@
 #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.
  * We also setup a mapping table between key cache slot indices
@@ -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) \



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201409300319.s8U3JTkm005411>