svn commit: r251655 - in head/sys: conf dev/ath dev/ath/ath_hal dev/ath/ath_hal/ar9002 modules/ath

Adrian Chadd adrian at FreeBSD.org
Wed Jun 12 14:52:59 UTC 2013


Author: adrian
Date: Wed Jun 12 14:52:57 2013
New Revision: 251655
URL: http://svnweb.freebsd.org/changeset/base/251655

Log:
  Migrate the LNA mixing diversity machinery from the AR9285 HAL to the driver.
  
  The AR9485 chip and AR933x SoC both implement LNA diversity.
  There are a few extra things that need to happen before this can be
  flipped on for those chips (mostly to do with setting up the different
  bias values and LNA1/LNA2 RSSI differences) but the first stage is
  putting this code into the driver layer so it can be reused.
  
  This has the added benefit of making it easier to expose configuration
  options and diagnostic information via the ioctl API.  That's not yet
  being done but it sure would be nice to do so.
  
  Tested:
  
  * AR9285, with LNA diversity enabled
  * AR9285, with LNA diversity disabled in EEPROM

Added:
  head/sys/dev/ath/if_ath_lna_div.c   (contents, props changed)
  head/sys/dev/ath/if_ath_lna_div.h   (contents, props changed)
Modified:
  head/sys/conf/files
  head/sys/dev/ath/ath_hal/ah.h
  head/sys/dev/ath/ath_hal/ar9002/ar9285.h
  head/sys/dev/ath/ath_hal/ar9002/ar9285_attach.c
  head/sys/dev/ath/ath_hal/ar9002/ar9285_diversity.c
  head/sys/dev/ath/ath_hal/ar9002/ar9285_diversity.h
  head/sys/dev/ath/ath_hal/ar9002/ar9285_reset.c
  head/sys/dev/ath/if_ath.c
  head/sys/dev/ath/if_ath_debug.h
  head/sys/dev/ath/if_ath_rx.c
  head/sys/dev/ath/if_athvar.h
  head/sys/modules/ath/Makefile

Modified: head/sys/conf/files
==============================================================================
--- head/sys/conf/files	Wed Jun 12 13:36:20 2013	(r251654)
+++ head/sys/conf/files	Wed Jun 12 14:52:57 2013	(r251655)
@@ -733,6 +733,8 @@ dev/ath/if_ath_keycache.c	optional ath \
 	compile-with "${NORMAL_C} -I$S/dev/ath"
 dev/ath/if_ath_led.c		optional ath \
 	compile-with "${NORMAL_C} -I$S/dev/ath"
+dev/ath/if_ath_lna_div.c	optional ath \
+	compile-with "${NORMAL_C} -I$S/dev/ath"
 dev/ath/if_ath_tx.c		optional ath \
 	compile-with "${NORMAL_C} -I$S/dev/ath"
 dev/ath/if_ath_tx_edma.c	optional ath \

Modified: head/sys/dev/ath/ath_hal/ah.h
==============================================================================
--- head/sys/dev/ath/ath_hal/ah.h	Wed Jun 12 13:36:20 2013	(r251654)
+++ head/sys/dev/ath/ath_hal/ah.h	Wed Jun 12 14:52:57 2013	(r251655)
@@ -1402,9 +1402,6 @@ struct ath_hal {
 				const struct ieee80211_channel *);
 	void	  __ahdecl(*ah_procMibEvent)(struct ath_hal *,
 				const HAL_NODE_STATS *);
-	void	  __ahdecl(*ah_rxAntCombDiversity)(struct ath_hal *,
-				struct ath_rx_status *,
-				unsigned long, int);
 
 	/* Misc Functions */
 	HAL_STATUS __ahdecl(*ah_getCapability)(struct ath_hal *,
@@ -1585,6 +1582,12 @@ struct ath_hal {
 				uint32_t, uint32_t);
 	void	    __ahdecl(*ah_btCoexDisable)(struct ath_hal *);
 	int	    __ahdecl(*ah_btCoexEnable)(struct ath_hal *);
+
+	/* LNA diversity configuration */
+	void	    __ahdecl(*ah_divLnaConfGet)(struct ath_hal *,
+				HAL_ANT_COMB_CONFIG *);
+	void	    __ahdecl(*ah_divLnaConfSet)(struct ath_hal *,
+				HAL_ANT_COMB_CONFIG *);
 };
 
 /* 

Modified: head/sys/dev/ath/ath_hal/ar9002/ar9285.h
==============================================================================
--- head/sys/dev/ath/ath_hal/ar9002/ar9285.h	Wed Jun 12 13:36:20 2013	(r251654)
+++ head/sys/dev/ath/ath_hal/ar9002/ar9285.h	Wed Jun 12 14:52:57 2013	(r251655)
@@ -20,42 +20,12 @@
 
 #include "ar5416/ar5416.h"
 
-struct ar9285_ant_comb {
-	uint16_t count;
-	uint16_t total_pkt_count;
-	HAL_BOOL scan;
-	HAL_BOOL scan_not_start;
-	int main_total_rssi;
-	int alt_total_rssi;
-	int alt_recv_cnt;
-	int main_recv_cnt;
-	int rssi_lna1;
-	int rssi_lna2;
-	int rssi_add;
-	int rssi_sub;
-	int rssi_first;
-	int rssi_second;
-	int rssi_third;
-	HAL_BOOL alt_good;
-	int quick_scan_cnt;
-	int main_conf;
-	HAL_ANT_DIV_COMB_LNA_CONF first_quick_scan_conf;
-	HAL_ANT_DIV_COMB_LNA_CONF second_quick_scan_conf;
-	int first_bias;
-	int second_bias;
-	HAL_BOOL first_ratio;
-	HAL_BOOL second_ratio;
-	unsigned long scan_start_time;
-};
-
 struct ath_hal_9285 {
 	struct ath_hal_5416 ah_5416;
 
 	HAL_INI_ARRAY	ah_ini_txgain;
 	HAL_INI_ARRAY	ah_ini_rxgain;
 
-	struct ar9285_ant_comb ant_comb;	/* Kite Antenna comb/diversity */
-
 	struct {
 		int32_t prev_offset;	/* Previous value of PA offset value */
 		int8_t max_skipcount;	/* Max No. of times PACAL can be skipped */
@@ -71,7 +41,6 @@ struct ath_hal_9285 {
 #define	AR_PHY_CCA_MIN_GOOD_VAL_9285_2GHZ	-127
 #define	AR_PHY_CCA_MAX_GOOD_VAL_9285_2GHZ	-108
 
-HAL_BOOL ar9285SetAntennaSwitch(struct ath_hal *, HAL_ANT_SETTING);
 HAL_BOOL ar9285RfAttach(struct ath_hal *, HAL_STATUS *);
 
 extern	HAL_BOOL ar9285SetTransmitPower(struct ath_hal *,

Modified: head/sys/dev/ath/ath_hal/ar9002/ar9285_attach.c
==============================================================================
--- head/sys/dev/ath/ath_hal/ar9002/ar9285_attach.c	Wed Jun 12 13:36:20 2013	(r251654)
+++ head/sys/dev/ath/ath_hal/ar9002/ar9285_attach.c	Wed Jun 12 14:52:57 2013	(r251655)
@@ -180,6 +180,8 @@ ar9285Attach(uint16_t devid, HAL_SOFTC s
 	ah->ah_setTxPower		= ar9285SetTransmitPower;
 	ah->ah_setBoardValues		= ar9285SetBoardValues;
 	ah->ah_btCoexSetParameter	= ar9285BTCoexSetParameter;
+	ah->ah_divLnaConfGet		= ar9285_antdiv_comb_conf_get;
+	ah->ah_divLnaConfSet		= ar9285_antdiv_comb_conf_set;
 
 	AH5416(ah)->ah_cal.iqCalData.calData = &ar9280_iq_cal;
 	AH5416(ah)->ah_cal.adcGainCalData.calData = &ar9280_adc_gain_cal;
@@ -341,7 +343,6 @@ ar9285Attach(uint16_t devid, HAL_SOFTC s
 	/* Print out whether the EEPROM settings enable AR9285 diversity */
 	if (ar9285_check_div_comb(ah)) {
 		ath_hal_printf(ah, "[ath] Enabling diversity for Kite\n");
-		ah->ah_rxAntCombDiversity = ar9285_ant_comb_scan;
 	}
 
 	/* Disable 11n for the AR2427 */

Modified: head/sys/dev/ath/ath_hal/ar9002/ar9285_diversity.c
==============================================================================
--- head/sys/dev/ath/ath_hal/ar9002/ar9285_diversity.c	Wed Jun 12 13:36:20 2013	(r251654)
+++ head/sys/dev/ath/ath_hal/ar9002/ar9285_diversity.c	Wed Jun 12 14:52:57 2013	(r251655)
@@ -33,609 +33,13 @@
 #include "ah_eeprom_v4k.h"
 
 #include "ar9002/ar9280.h"
-#include "ar9002/ar9285_diversity.h"
 #include "ar9002/ar9285.h"
 #include "ar5416/ar5416reg.h"
 #include "ar5416/ar5416phy.h"
 #include "ar9002/ar9285phy.h"
 #include "ar9002/ar9285_phy.h"
 
-
-/* Linux compability macros */
-/*
- * XXX these don't handle rounding, underflow, overflow, wrapping!
- */
-#define	msecs_to_jiffies(a)		( (a) * hz / 1000 )
-#define	time_after(a, b)		( (long) (b) - (long) (a) < 0 )
-
-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)
-{
-	return (((alt_ratio >= ATH_ANT_DIV_COMB_ALT_ANT_RATIO2) &&
-		(alt_rssi_avg > main_rssi_avg + maxdelta)) ||
-		(alt_rssi_avg > main_rssi_avg + mindelta)) && (pkt_count > 50);
-}
-
-static void
-ath_lnaconf_alt_good_scan(struct ar9285_ant_comb *antcomb,
-    HAL_ANT_COMB_CONFIG *ant_conf, int main_rssi_avg)
-{
-	antcomb->quick_scan_cnt = 0;
-
-	if (ant_conf->main_lna_conf == HAL_ANT_DIV_COMB_LNA2)
-		antcomb->rssi_lna2 = main_rssi_avg;
-	else if (ant_conf->main_lna_conf == HAL_ANT_DIV_COMB_LNA1)
-		antcomb->rssi_lna1 = main_rssi_avg;
-
-	switch ((ant_conf->main_lna_conf << 4) | ant_conf->alt_lna_conf) {
-	case (0x10): /* LNA2 A-B */
-		antcomb->main_conf = HAL_ANT_DIV_COMB_LNA1_MINUS_LNA2;
-		antcomb->first_quick_scan_conf =
-			HAL_ANT_DIV_COMB_LNA1_PLUS_LNA2;
-		antcomb->second_quick_scan_conf = HAL_ANT_DIV_COMB_LNA1;
-		break;
-	case (0x20): /* LNA1 A-B */
-		antcomb->main_conf = HAL_ANT_DIV_COMB_LNA1_MINUS_LNA2;
-		antcomb->first_quick_scan_conf =
-			HAL_ANT_DIV_COMB_LNA1_PLUS_LNA2;
-		antcomb->second_quick_scan_conf = HAL_ANT_DIV_COMB_LNA2;
-		break;
-	case (0x21): /* LNA1 LNA2 */
-		antcomb->main_conf = HAL_ANT_DIV_COMB_LNA2;
-		antcomb->first_quick_scan_conf =
-			HAL_ANT_DIV_COMB_LNA1_MINUS_LNA2;
-		antcomb->second_quick_scan_conf =
-			HAL_ANT_DIV_COMB_LNA1_PLUS_LNA2;
-		break;
-	case (0x12): /* LNA2 LNA1 */
-		antcomb->main_conf = HAL_ANT_DIV_COMB_LNA1;
-		antcomb->first_quick_scan_conf =
-			HAL_ANT_DIV_COMB_LNA1_MINUS_LNA2;
-		antcomb->second_quick_scan_conf =
-			HAL_ANT_DIV_COMB_LNA1_PLUS_LNA2;
-		break;
-	case (0x13): /* LNA2 A+B */
-		antcomb->main_conf = HAL_ANT_DIV_COMB_LNA1_PLUS_LNA2;
-		antcomb->first_quick_scan_conf =
-			HAL_ANT_DIV_COMB_LNA1_MINUS_LNA2;
-		antcomb->second_quick_scan_conf = HAL_ANT_DIV_COMB_LNA1;
-		break;
-	case (0x23): /* LNA1 A+B */
-		antcomb->main_conf = HAL_ANT_DIV_COMB_LNA1_PLUS_LNA2;
-		antcomb->first_quick_scan_conf =
-			HAL_ANT_DIV_COMB_LNA1_MINUS_LNA2;
-		antcomb->second_quick_scan_conf = HAL_ANT_DIV_COMB_LNA2;
-		break;
-	default:
-		break;
-	}
-}
-
-static void
-ath_select_ant_div_from_quick_scan(struct ar9285_ant_comb *antcomb,
-    HAL_ANT_COMB_CONFIG *div_ant_conf, int main_rssi_avg,
-    int alt_rssi_avg, int alt_ratio)
-{
-	/* alt_good */
-	switch (antcomb->quick_scan_cnt) {
-	case 0:
-		/* set alt to main, and alt to first conf */
-		div_ant_conf->main_lna_conf = antcomb->main_conf;
-		div_ant_conf->alt_lna_conf = antcomb->first_quick_scan_conf;
-		break;
-	case 1:
-		/* set alt to main, and alt to first conf */
-		div_ant_conf->main_lna_conf = antcomb->main_conf;
-		div_ant_conf->alt_lna_conf = antcomb->second_quick_scan_conf;
-		antcomb->rssi_first = main_rssi_avg;
-		antcomb->rssi_second = alt_rssi_avg;
-
-		if (antcomb->main_conf == HAL_ANT_DIV_COMB_LNA1) {
-			/* main is LNA1 */
-			if (ath_is_alt_ant_ratio_better(alt_ratio,
-						ATH_ANT_DIV_COMB_LNA1_DELTA_HI,
-						ATH_ANT_DIV_COMB_LNA1_DELTA_LOW,
-						main_rssi_avg, alt_rssi_avg,
-						antcomb->total_pkt_count))
-				antcomb->first_ratio = AH_TRUE;
-			else
-				antcomb->first_ratio = AH_FALSE;
-		} else if (antcomb->main_conf == HAL_ANT_DIV_COMB_LNA2) {
-			if (ath_is_alt_ant_ratio_better(alt_ratio,
-						ATH_ANT_DIV_COMB_LNA1_DELTA_MID,
-						ATH_ANT_DIV_COMB_LNA1_DELTA_LOW,
-						main_rssi_avg, alt_rssi_avg,
-						antcomb->total_pkt_count))
-				antcomb->first_ratio = AH_TRUE;
-			else
-				antcomb->first_ratio = AH_FALSE;
-		} else {
-			if ((((alt_ratio >= ATH_ANT_DIV_COMB_ALT_ANT_RATIO2) &&
-			    (alt_rssi_avg > main_rssi_avg +
-			    ATH_ANT_DIV_COMB_LNA1_DELTA_HI)) ||
-			    (alt_rssi_avg > main_rssi_avg)) &&
-			    (antcomb->total_pkt_count > 50))
-				antcomb->first_ratio = AH_TRUE;
-			else
-				antcomb->first_ratio = AH_FALSE;
-		}
-		break;
-	case 2:
-		antcomb->alt_good = AH_FALSE;
-		antcomb->scan_not_start = AH_FALSE;
-		antcomb->scan = AH_FALSE;
-		antcomb->rssi_first = main_rssi_avg;
-		antcomb->rssi_third = alt_rssi_avg;
-
-		if (antcomb->second_quick_scan_conf == HAL_ANT_DIV_COMB_LNA1)
-			antcomb->rssi_lna1 = alt_rssi_avg;
-		else if (antcomb->second_quick_scan_conf ==
-			 HAL_ANT_DIV_COMB_LNA2)
-			antcomb->rssi_lna2 = alt_rssi_avg;
-		else if (antcomb->second_quick_scan_conf ==
-			 HAL_ANT_DIV_COMB_LNA1_PLUS_LNA2) {
-			if (antcomb->main_conf == HAL_ANT_DIV_COMB_LNA2)
-				antcomb->rssi_lna2 = main_rssi_avg;
-			else if (antcomb->main_conf == HAL_ANT_DIV_COMB_LNA1)
-				antcomb->rssi_lna1 = main_rssi_avg;
-		}
-
-		if (antcomb->rssi_lna2 > antcomb->rssi_lna1 +
-		    ATH_ANT_DIV_COMB_LNA1_LNA2_SWITCH_DELTA)
-			div_ant_conf->main_lna_conf = HAL_ANT_DIV_COMB_LNA2;
-		else
-			div_ant_conf->main_lna_conf = HAL_ANT_DIV_COMB_LNA1;
-
-		if (antcomb->main_conf == HAL_ANT_DIV_COMB_LNA1) {
-			if (ath_is_alt_ant_ratio_better(alt_ratio,
-						ATH_ANT_DIV_COMB_LNA1_DELTA_HI,
-						ATH_ANT_DIV_COMB_LNA1_DELTA_LOW,
-						main_rssi_avg, alt_rssi_avg,
-						antcomb->total_pkt_count))
-				antcomb->second_ratio = AH_TRUE;
-			else
-				antcomb->second_ratio = AH_FALSE;
-		} else if (antcomb->main_conf == HAL_ANT_DIV_COMB_LNA2) {
-			if (ath_is_alt_ant_ratio_better(alt_ratio,
-						ATH_ANT_DIV_COMB_LNA1_DELTA_MID,
-						ATH_ANT_DIV_COMB_LNA1_DELTA_LOW,
-						main_rssi_avg, alt_rssi_avg,
-						antcomb->total_pkt_count))
-				antcomb->second_ratio = AH_TRUE;
-			else
-				antcomb->second_ratio = AH_FALSE;
-		} else {
-			if ((((alt_ratio >= ATH_ANT_DIV_COMB_ALT_ANT_RATIO2) &&
-			    (alt_rssi_avg > main_rssi_avg +
-			    ATH_ANT_DIV_COMB_LNA1_DELTA_HI)) ||
-			    (alt_rssi_avg > main_rssi_avg)) &&
-			    (antcomb->total_pkt_count > 50))
-				antcomb->second_ratio = AH_TRUE;
-			else
-				antcomb->second_ratio = AH_FALSE;
-		}
-
-		/* set alt to the conf with maximun ratio */
-		if (antcomb->first_ratio && antcomb->second_ratio) {
-			if (antcomb->rssi_second > antcomb->rssi_third) {
-				/* first alt*/
-				if ((antcomb->first_quick_scan_conf ==
-				    HAL_ANT_DIV_COMB_LNA1) ||
-				    (antcomb->first_quick_scan_conf ==
-				    HAL_ANT_DIV_COMB_LNA2))
-					/* Set alt LNA1 or LNA2*/
-					if (div_ant_conf->main_lna_conf ==
-					    HAL_ANT_DIV_COMB_LNA2)
-						div_ant_conf->alt_lna_conf =
-							HAL_ANT_DIV_COMB_LNA1;
-					else
-						div_ant_conf->alt_lna_conf =
-							HAL_ANT_DIV_COMB_LNA2;
-				else
-					/* Set alt to A+B or A-B */
-					div_ant_conf->alt_lna_conf =
-						antcomb->first_quick_scan_conf;
-			} else if ((antcomb->second_quick_scan_conf ==
-				   HAL_ANT_DIV_COMB_LNA1) ||
-				   (antcomb->second_quick_scan_conf ==
-				   HAL_ANT_DIV_COMB_LNA2)) {
-				/* Set alt LNA1 or LNA2 */
-				if (div_ant_conf->main_lna_conf ==
-				    HAL_ANT_DIV_COMB_LNA2)
-					div_ant_conf->alt_lna_conf =
-						HAL_ANT_DIV_COMB_LNA1;
-				else
-					div_ant_conf->alt_lna_conf =
-						HAL_ANT_DIV_COMB_LNA2;
-			} else {
-				/* Set alt to A+B or A-B */
-				div_ant_conf->alt_lna_conf =
-					antcomb->second_quick_scan_conf;
-			}
-		} else if (antcomb->first_ratio) {
-			/* first alt */
-			if ((antcomb->first_quick_scan_conf ==
-			    HAL_ANT_DIV_COMB_LNA1) ||
-			    (antcomb->first_quick_scan_conf ==
-			    HAL_ANT_DIV_COMB_LNA2))
-					/* Set alt LNA1 or LNA2 */
-				if (div_ant_conf->main_lna_conf ==
-				    HAL_ANT_DIV_COMB_LNA2)
-					div_ant_conf->alt_lna_conf =
-							HAL_ANT_DIV_COMB_LNA1;
-				else
-					div_ant_conf->alt_lna_conf =
-							HAL_ANT_DIV_COMB_LNA2;
-			else
-				/* Set alt to A+B or A-B */
-				div_ant_conf->alt_lna_conf =
-						antcomb->first_quick_scan_conf;
-		} else if (antcomb->second_ratio) {
-				/* second alt */
-			if ((antcomb->second_quick_scan_conf ==
-			    HAL_ANT_DIV_COMB_LNA1) ||
-			    (antcomb->second_quick_scan_conf ==
-			    HAL_ANT_DIV_COMB_LNA2))
-				/* Set alt LNA1 or LNA2 */
-				if (div_ant_conf->main_lna_conf ==
-				    HAL_ANT_DIV_COMB_LNA2)
-					div_ant_conf->alt_lna_conf =
-						HAL_ANT_DIV_COMB_LNA1;
-				else
-					div_ant_conf->alt_lna_conf =
-						HAL_ANT_DIV_COMB_LNA2;
-			else
-				/* Set alt to A+B or A-B */
-				div_ant_conf->alt_lna_conf =
-						antcomb->second_quick_scan_conf;
-		} else {
-			/* main is largest */
-			if ((antcomb->main_conf == HAL_ANT_DIV_COMB_LNA1) ||
-			    (antcomb->main_conf == HAL_ANT_DIV_COMB_LNA2))
-				/* Set alt LNA1 or LNA2 */
-				if (div_ant_conf->main_lna_conf ==
-				    HAL_ANT_DIV_COMB_LNA2)
-					div_ant_conf->alt_lna_conf =
-							HAL_ANT_DIV_COMB_LNA1;
-				else
-					div_ant_conf->alt_lna_conf =
-							HAL_ANT_DIV_COMB_LNA2;
-			else
-				/* Set alt to A+B or A-B */
-				div_ant_conf->alt_lna_conf = antcomb->main_conf;
-		}
-		break;
-	default:
-		break;
-	}
-}
-
-static void
-ath_ant_div_conf_fast_divbias(HAL_ANT_COMB_CONFIG *ant_conf)
-{
-	/* Adjust the fast_div_bias based on main and alt lna conf */
-	switch ((ant_conf->main_lna_conf << 4) | ant_conf->alt_lna_conf) {
-	case (0x01): /* A-B LNA2 */
-		ant_conf->fast_div_bias = 0x3b;
-		break;
-	case (0x02): /* A-B LNA1 */
-		ant_conf->fast_div_bias = 0x3d;
-		break;
-	case (0x03): /* A-B A+B */
-		ant_conf->fast_div_bias = 0x1;
-		break;
-	case (0x10): /* LNA2 A-B */
-		ant_conf->fast_div_bias = 0x7;
-		break;
-	case (0x12): /* LNA2 LNA1 */
-		ant_conf->fast_div_bias = 0x2;
-		break;
-	case (0x13): /* LNA2 A+B */
-		ant_conf->fast_div_bias = 0x7;
-		break;
-	case (0x20): /* LNA1 A-B */
-		ant_conf->fast_div_bias = 0x6;
-		break;
-	case (0x21): /* LNA1 LNA2 */
-		ant_conf->fast_div_bias = 0x0;
-		break;
-	case (0x23): /* LNA1 A+B */
-		ant_conf->fast_div_bias = 0x6;
-		break;
-	case (0x30): /* A+B A-B */
-		ant_conf->fast_div_bias = 0x1;
-		break;
-	case (0x31): /* A+B LNA2 */
-		ant_conf->fast_div_bias = 0x3b;
-		break;
-	case (0x32): /* A+B LNA1 */
-		ant_conf->fast_div_bias = 0x3d;
-		break;
-	default:
-		break;
-	}
-}
-
-/* Antenna diversity and combining */
-void
-ar9285_ant_comb_scan(struct ath_hal *ah, struct ath_rx_status *rs,
-    unsigned long ticks, int hz)
-{
-	HAL_ANT_COMB_CONFIG div_ant_conf;
-	struct ar9285_ant_comb *antcomb = &AH9285(ah)->ant_comb;
-	int alt_ratio = 0, alt_rssi_avg = 0, main_rssi_avg = 0, curr_alt_set;
-	int curr_main_set, curr_bias;
-	int main_rssi = rs->rs_rssi_ctl[0];
-	int alt_rssi = rs->rs_rssi_ctl[1];
-	int rx_ant_conf, main_ant_conf, alt_ant_conf;
-	HAL_BOOL short_scan = AH_FALSE;
-
-	rx_ant_conf = (rs->rs_rssi_ctl[2] >> 4) & ATH_ANT_RX_MASK;
-	main_ant_conf = (rs->rs_rssi_ctl[2] >> 2) & ATH_ANT_RX_MASK;
-	alt_ant_conf = (rs->rs_rssi_ctl[2] >> 0) & ATH_ANT_RX_MASK;
-
-#if 0
-	HALDEBUG(ah, HAL_DEBUG_DIVERSITY, "%s: RSSI %d/%d, conf %x/%x, rxconf %x, LNA: %d; ANT: %d; FastDiv: %d\n",
-	    __func__, main_rssi, alt_rssi, main_ant_conf,alt_ant_conf, rx_ant_conf,
-	    !!(rs->rs_rssi_ctl[2] & 0x80), !!(rs->rs_rssi_ctl[2] & 0x40), !!(rs->rs_rssi_ext[2] & 0x40));
-#endif
-
-	if (! ar9285_check_div_comb(ah))
-		return;
-
-	if (AH5212(ah)->ah_diversity == AH_FALSE)
-		return;
-
-#if 0
-	HALDEBUG(ah, HAL_DEBUG_DIVERSITY, "%s: main: %d, alt: %d, rx_ant_conf: %x, main_ant_conf: %x\n",
-	    __func__, main_rssi, alt_rssi, rx_ant_conf, main_ant_conf);
-#endif
-
-	/* Record packet only when alt_rssi is positive */
-	if (main_rssi > 0 && alt_rssi > 0) {
-		antcomb->total_pkt_count++;
-		antcomb->main_total_rssi += main_rssi;
-		antcomb->alt_total_rssi  += alt_rssi;
-		if (main_ant_conf == rx_ant_conf)
-			antcomb->main_recv_cnt++;
-		else
-			antcomb->alt_recv_cnt++;
-	}
-
-	/* Short scan check */
-	if (antcomb->scan && antcomb->alt_good) {
-		if (time_after(ticks, antcomb->scan_start_time +
-		    msecs_to_jiffies(ATH_ANT_DIV_COMB_SHORT_SCAN_INTR)))
-			short_scan = AH_TRUE;
-		else
-			if (antcomb->total_pkt_count ==
-			    ATH_ANT_DIV_COMB_SHORT_SCAN_PKTCOUNT) {
-				alt_ratio = ((antcomb->alt_recv_cnt * 100) /
-					    antcomb->total_pkt_count);
-				if (alt_ratio < ATH_ANT_DIV_COMB_ALT_ANT_RATIO)
-					short_scan = AH_TRUE;
-			}
-	}
-
-	if (((antcomb->total_pkt_count < ATH_ANT_DIV_COMB_MAX_PKTCOUNT) ||
-	    rs->rs_moreaggr) && !short_scan)
-		return;
-
-	if (antcomb->total_pkt_count) {
-		alt_ratio = ((antcomb->alt_recv_cnt * 100) /
-			     antcomb->total_pkt_count);
-		main_rssi_avg = (antcomb->main_total_rssi /
-				 antcomb->total_pkt_count);
-		alt_rssi_avg = (antcomb->alt_total_rssi /
-				 antcomb->total_pkt_count);
-	}
-
-	OS_MEMZERO(&div_ant_conf, sizeof(div_ant_conf));
-	ar9285_antdiv_comb_conf_get(ah, &div_ant_conf);
-	curr_alt_set = div_ant_conf.alt_lna_conf;
-	curr_main_set = div_ant_conf.main_lna_conf;
-	curr_bias = div_ant_conf.fast_div_bias;
-
-	antcomb->count++;
-
-	if (antcomb->count == ATH_ANT_DIV_COMB_MAX_COUNT) {
-		if (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO) {
-			ath_lnaconf_alt_good_scan(antcomb, &div_ant_conf,
-						  main_rssi_avg);
-			antcomb->alt_good = AH_TRUE;
-		} else {
-			antcomb->alt_good = AH_FALSE;
-		}
-
-		antcomb->count = 0;
-		antcomb->scan = AH_TRUE;
-		antcomb->scan_not_start = AH_TRUE;
-	}
-
-	if (!antcomb->scan) {
-		if (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO) {
-			if (curr_alt_set == HAL_ANT_DIV_COMB_LNA2) {
-				/* Switch main and alt LNA */
-				div_ant_conf.main_lna_conf =
-						HAL_ANT_DIV_COMB_LNA2;
-				div_ant_conf.alt_lna_conf  =
-						HAL_ANT_DIV_COMB_LNA1;
-			} else if (curr_alt_set == HAL_ANT_DIV_COMB_LNA1) {
-				div_ant_conf.main_lna_conf =
-						HAL_ANT_DIV_COMB_LNA1;
-				div_ant_conf.alt_lna_conf  =
-						HAL_ANT_DIV_COMB_LNA2;
-			}
-
-			goto div_comb_done;
-		} else if ((curr_alt_set != HAL_ANT_DIV_COMB_LNA1) &&
-			   (curr_alt_set != HAL_ANT_DIV_COMB_LNA2)) {
-			/* Set alt to another LNA */
-			if (curr_main_set == HAL_ANT_DIV_COMB_LNA2)
-				div_ant_conf.alt_lna_conf =
-						HAL_ANT_DIV_COMB_LNA1;
-			else if (curr_main_set == HAL_ANT_DIV_COMB_LNA1)
-				div_ant_conf.alt_lna_conf =
-						HAL_ANT_DIV_COMB_LNA2;
-
-			goto div_comb_done;
-		}
-
-		if ((alt_rssi_avg < (main_rssi_avg +
-		    ATH_ANT_DIV_COMB_LNA1_LNA2_DELTA)))
-			goto div_comb_done;
-	}
-
-	if (!antcomb->scan_not_start) {
-		switch (curr_alt_set) {
-		case HAL_ANT_DIV_COMB_LNA2:
-			antcomb->rssi_lna2 = alt_rssi_avg;
-			antcomb->rssi_lna1 = main_rssi_avg;
-			antcomb->scan = AH_TRUE;
-			/* set to A+B */
-			div_ant_conf.main_lna_conf =
-				HAL_ANT_DIV_COMB_LNA1;
-			div_ant_conf.alt_lna_conf  =
-				HAL_ANT_DIV_COMB_LNA1_PLUS_LNA2;
-			break;
-		case HAL_ANT_DIV_COMB_LNA1:
-			antcomb->rssi_lna1 = alt_rssi_avg;
-			antcomb->rssi_lna2 = main_rssi_avg;
-			antcomb->scan = AH_TRUE;
-			/* set to A+B */
-			div_ant_conf.main_lna_conf = HAL_ANT_DIV_COMB_LNA2;
-			div_ant_conf.alt_lna_conf  =
-				HAL_ANT_DIV_COMB_LNA1_PLUS_LNA2;
-			break;
-		case HAL_ANT_DIV_COMB_LNA1_PLUS_LNA2:
-			antcomb->rssi_add = alt_rssi_avg;
-			antcomb->scan = AH_TRUE;
-			/* set to A-B */
-			div_ant_conf.alt_lna_conf =
-				HAL_ANT_DIV_COMB_LNA1_MINUS_LNA2;
-			break;
-		case HAL_ANT_DIV_COMB_LNA1_MINUS_LNA2:
-			antcomb->rssi_sub = alt_rssi_avg;
-			antcomb->scan = AH_FALSE;
-			if (antcomb->rssi_lna2 >
-			    (antcomb->rssi_lna1 +
-			    ATH_ANT_DIV_COMB_LNA1_LNA2_SWITCH_DELTA)) {
-				/* use LNA2 as main LNA */
-				if ((antcomb->rssi_add > antcomb->rssi_lna1) &&
-				    (antcomb->rssi_add > antcomb->rssi_sub)) {
-					/* set to A+B */
-					div_ant_conf.main_lna_conf =
-						HAL_ANT_DIV_COMB_LNA2;
-					div_ant_conf.alt_lna_conf  =
-						HAL_ANT_DIV_COMB_LNA1_PLUS_LNA2;
-				} else if (antcomb->rssi_sub >
-					   antcomb->rssi_lna1) {
-					/* set to A-B */
-					div_ant_conf.main_lna_conf =
-						HAL_ANT_DIV_COMB_LNA2;
-					div_ant_conf.alt_lna_conf =
-						HAL_ANT_DIV_COMB_LNA1_MINUS_LNA2;
-				} else {
-					/* set to LNA1 */
-					div_ant_conf.main_lna_conf =
-						HAL_ANT_DIV_COMB_LNA2;
-					div_ant_conf.alt_lna_conf =
-						HAL_ANT_DIV_COMB_LNA1;
-				}
-			} else {
-				/* use LNA1 as main LNA */
-				if ((antcomb->rssi_add > antcomb->rssi_lna2) &&
-				    (antcomb->rssi_add > antcomb->rssi_sub)) {
-					/* set to A+B */
-					div_ant_conf.main_lna_conf =
-						HAL_ANT_DIV_COMB_LNA1;
-					div_ant_conf.alt_lna_conf  =
-						HAL_ANT_DIV_COMB_LNA1_PLUS_LNA2;
-				} else if (antcomb->rssi_sub >
-					   antcomb->rssi_lna1) {
-					/* set to A-B */
-					div_ant_conf.main_lna_conf =
-						HAL_ANT_DIV_COMB_LNA1;
-					div_ant_conf.alt_lna_conf =
-						HAL_ANT_DIV_COMB_LNA1_MINUS_LNA2;
-				} else {
-					/* set to LNA2 */
-					div_ant_conf.main_lna_conf =
-						HAL_ANT_DIV_COMB_LNA1;
-					div_ant_conf.alt_lna_conf =
-						HAL_ANT_DIV_COMB_LNA2;
-				}
-			}
-			break;
-		default:
-			break;
-		}
-	} else {
-		if (!antcomb->alt_good) {
-			antcomb->scan_not_start = AH_FALSE;
-			/* Set alt to another LNA */
-			if (curr_main_set == HAL_ANT_DIV_COMB_LNA2) {
-				div_ant_conf.main_lna_conf =
-						HAL_ANT_DIV_COMB_LNA2;
-				div_ant_conf.alt_lna_conf =
-						HAL_ANT_DIV_COMB_LNA1;
-			} else if (curr_main_set == HAL_ANT_DIV_COMB_LNA1) {
-				div_ant_conf.main_lna_conf =
-						HAL_ANT_DIV_COMB_LNA1;
-				div_ant_conf.alt_lna_conf =
-						HAL_ANT_DIV_COMB_LNA2;
-			}
-			goto div_comb_done;
-		}
-	}
-
-	ath_select_ant_div_from_quick_scan(antcomb, &div_ant_conf,
-					   main_rssi_avg, alt_rssi_avg,
-					   alt_ratio);
-
-	antcomb->quick_scan_cnt++;
-
-div_comb_done:
-	ath_ant_div_conf_fast_divbias(&div_ant_conf);
-
-	ar9285_antdiv_comb_conf_set(ah, &div_ant_conf);
-
-	HALDEBUG(ah, HAL_DEBUG_DIVERSITY, "%s: total_pkt_count=%d\n",
-	   __func__, antcomb->total_pkt_count);
-
-	HALDEBUG(ah, HAL_DEBUG_DIVERSITY, "%s: main_total_rssi=%d\n",
-	   __func__, antcomb->main_total_rssi);
-	HALDEBUG(ah, HAL_DEBUG_DIVERSITY, "%s: alt_total_rssi=%d\n",
-	   __func__, antcomb->alt_total_rssi);
-
-	HALDEBUG(ah, HAL_DEBUG_DIVERSITY, "%s: main_rssi_avg=%d\n",
-	   __func__, main_rssi_avg);
-	HALDEBUG(ah, HAL_DEBUG_DIVERSITY, "%s: alt_alt_rssi_avg=%d\n",
-	   __func__, alt_rssi_avg);
-
-	HALDEBUG(ah, HAL_DEBUG_DIVERSITY, "%s: main_recv_cnt=%d\n",
-	   __func__, antcomb->main_recv_cnt);
-	HALDEBUG(ah, HAL_DEBUG_DIVERSITY, "%s: alt_recv_cnt=%d\n",
-	   __func__, antcomb->alt_recv_cnt);
-
-//	if (curr_alt_set != div_ant_conf.alt_lna_conf)
-		HALDEBUG(ah, HAL_DEBUG_DIVERSITY, "%s: lna_conf: %x -> %x\n",
-		    __func__, curr_alt_set, div_ant_conf.alt_lna_conf);
-//	if (curr_main_set != div_ant_conf.main_lna_conf)
-		HALDEBUG(ah, HAL_DEBUG_DIVERSITY, "%s: main_lna_conf: %x -> %x\n",
-		    __func__, curr_main_set, div_ant_conf.main_lna_conf);
-//	if (curr_bias != div_ant_conf.fast_div_bias)
-		HALDEBUG(ah, HAL_DEBUG_DIVERSITY, "%s: fast_div_bias: %x -> %x\n",
-		    __func__, curr_bias, div_ant_conf.fast_div_bias);
-
-	antcomb->scan_start_time = ticks;
-	antcomb->total_pkt_count = 0;
-	antcomb->main_total_rssi = 0;
-	antcomb->alt_total_rssi = 0;
-	antcomb->main_recv_cnt = 0;
-	antcomb->alt_recv_cnt = 0;
-}
+#include "ar9002/ar9285_diversity.h"
 
 /*
  * Set the antenna switch to control RX antenna diversity.

Modified: head/sys/dev/ath/ath_hal/ar9002/ar9285_diversity.h
==============================================================================
--- head/sys/dev/ath/ath_hal/ar9002/ar9285_diversity.h	Wed Jun 12 13:36:20 2013	(r251654)
+++ head/sys/dev/ath/ath_hal/ar9002/ar9285_diversity.h	Wed Jun 12 14:52:57 2013	(r251655)
@@ -28,26 +28,6 @@
 #ifndef	__AR9285_DIVERSITY_H__
 #define	__AR9285_DIVERSITY_H__
 
-/* Antenna diversity/combining */
-#define	ATH_ANT_RX_CURRENT_SHIFT	4
-#define	ATH_ANT_RX_MAIN_SHIFT		2
-#define	ATH_ANT_RX_MASK			0x3
-
-#define	ATH_ANT_DIV_COMB_SHORT_SCAN_INTR	50
-#define	ATH_ANT_DIV_COMB_SHORT_SCAN_PKTCOUNT	0x100
-#define	ATH_ANT_DIV_COMB_MAX_PKTCOUNT		0x200
-#define	ATH_ANT_DIV_COMB_INIT_COUNT		95
-#define	ATH_ANT_DIV_COMB_MAX_COUNT		100
-#define	ATH_ANT_DIV_COMB_ALT_ANT_RATIO		30
-#define	ATH_ANT_DIV_COMB_ALT_ANT_RATIO2		20
-
-#define	ATH_ANT_DIV_COMB_LNA1_LNA2_DELTA	-3
-#define	ATH_ANT_DIV_COMB_LNA1_LNA2_SWITCH_DELTA	-1
-#define	ATH_ANT_DIV_COMB_LNA1_DELTA_HI		-4
-#define	ATH_ANT_DIV_COMB_LNA1_DELTA_MID		-2
-#define	ATH_ANT_DIV_COMB_LNA1_DELTA_LOW		2
-
-extern	void ar9285_ant_comb_scan(struct ath_hal *ah, struct ath_rx_status *rs,
-		unsigned long ticks, int hz);
+extern	HAL_BOOL ar9285SetAntennaSwitch(struct ath_hal *, HAL_ANT_SETTING);
 
 #endif

Modified: head/sys/dev/ath/ath_hal/ar9002/ar9285_reset.c
==============================================================================
--- head/sys/dev/ath/ath_hal/ar9002/ar9285_reset.c	Wed Jun 12 13:36:20 2013	(r251654)
+++ head/sys/dev/ath/ath_hal/ar9002/ar9285_reset.c	Wed Jun 12 14:52:57 2013	(r251655)
@@ -38,6 +38,7 @@
 #include "ar9002/ar9002phy.h"
 #include "ar9002/ar9285phy.h"
 #include "ar9002/ar9285an.h"
+#include "ar9002/ar9285_diversity.h"
 
 /* Eeprom versioning macros. Returns true if the version is equal or newer than the ver specified */ 
 #define	EEP_MINOR(_ah) \

Modified: head/sys/dev/ath/if_ath.c
==============================================================================
--- head/sys/dev/ath/if_ath.c	Wed Jun 12 13:36:20 2013	(r251654)
+++ head/sys/dev/ath/if_ath.c	Wed Jun 12 14:52:57 2013	(r251655)
@@ -113,6 +113,7 @@ __FBSDID("$FreeBSD$");
 #include <dev/ath/if_ath_beacon.h>
 #include <dev/ath/if_ath_btcoex.h>
 #include <dev/ath/if_ath_spectral.h>
+#include <dev/ath/if_ath_lna_div.h>
 #include <dev/ath/if_athdfs.h>
 
 #ifdef ATH_TX99_DIAG
@@ -530,6 +531,14 @@ ath_attach(u_int16_t devid, struct ath_s
 		goto bad2;
 	}
 
+	/* Attach LNA diversity module */
+	if (ath_lna_div_attach(sc) < 0) {
+		device_printf(sc->sc_dev,
+		    "%s: unable to attach LNA diversity\n", __func__);
+		error = EIO;
+		goto bad2;
+	}
+
 	/* Start DFS processing tasklet */
 	TASK_INIT(&sc->sc_dfstask, 0, ath_dfs_tasklet, sc);
 
@@ -680,6 +689,8 @@ ath_attach(u_int16_t devid, struct ath_s
 	sc->sc_rxtsf32 = ath_hal_has_long_rxdesc_tsf(ah);
 	sc->sc_hasenforcetxop = ath_hal_hasenforcetxop(ah);
 	sc->sc_rx_lnamixer = ath_hal_hasrxlnamixer(ah);
+	sc->sc_hasdivcomb = ath_hal_hasdivantcomb(ah);
+
 	if (ath_hal_hasfastframes(ah))
 		ic->ic_caps |= IEEE80211_C_FF;
 	wmodes = ath_hal_getwirelessmodes(ah);
@@ -1038,6 +1049,7 @@ ath_detach(struct ath_softc *sc)
 #ifdef	ATH_DEBUG_ALQ
 	if_ath_alq_tidyup(&sc->sc_alq);
 #endif
+	ath_lna_div_detach(sc);
 	ath_btcoex_detach(sc);
 	ath_spectral_detach(sc);
 	ath_dfs_detach(sc);

Modified: head/sys/dev/ath/if_ath_debug.h
==============================================================================
--- head/sys/dev/ath/if_ath_debug.h	Wed Jun 12 13:36:20 2013	(r251654)
+++ head/sys/dev/ath/if_ath_debug.h	Wed Jun 12 14:52:57 2013	(r251655)
@@ -67,6 +67,7 @@ enum { 
 	ATH_DEBUG_EDMA_RX	= 0x200000000ULL,	/* RX EDMA state */
 	ATH_DEBUG_SW_TX_FILT	= 0x400000000ULL,	/* SW TX FF */
 	ATH_DEBUG_NODE_PWRSAVE	= 0x800000000ULL,	/* node powersave */
+	ATH_DEBUG_DIVERSITY	= 0x1000000000ULL,	/* Diversity logic */
 
 	ATH_DEBUG_ANY		= 0xffffffffffffffffULL
 };

Added: head/sys/dev/ath/if_ath_lna_div.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/dev/ath/if_ath_lna_div.c	Wed Jun 12 14:52:57 2013	(r251655)
@@ -0,0 +1,798 @@
+/*-
+ * Copyright (c) 2013 Adrian Chadd <adrian at FreeBSD.org>
+ * 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$");
+
+/*
+ * This module handles LNA diversity for those chips which implement LNA
+ * mixing (AR9285/AR9485.)
+ */
+#include "opt_ath.h"
+#include "opt_inet.h"
+#include "opt_wlan.h"
+
+#include <sys/param.h>
+#include <sys/systm.h> 
+#include <sys/sysctl.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/errno.h>
+
+#include <machine/bus.h>
+#include <machine/resource.h>
+#include <sys/bus.h>
+
+#include <sys/socket.h>
+ 
+#include <net/if.h>
+#include <net/if_media.h>
+#include <net/if_arp.h>
+#include <net/ethernet.h>		/* XXX for ether_sprintf */
+
+#include <net80211/ieee80211_var.h>
+
+#include <net/bpf.h>
+
+#ifdef INET
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+#endif
+
+#include <dev/ath/if_athvar.h>
+#include <dev/ath/if_ath_debug.h>
+#include <dev/ath/if_ath_lna_div.h>
+
+/* Linux compability macros */
+/*
+ * XXX these don't handle rounding, underflow, overflow, wrapping!
+ */
+#define	msecs_to_jiffies(a)		( (a) * hz / 1000 )
+
+/*
+ * Methods which are required
+ */
+
+/*
+ * Attach the LNA diversity to the given interface
+ */
+int
+ath_lna_div_attach(struct ath_softc *sc)
+{
+	struct if_ath_ant_comb_state *ss;
+
+	/* Only do this if diversity is enabled */
+	if (! ath_hal_hasdivantcomb(sc->sc_ah))
+		return (0);
+
+	ss = malloc(sizeof(struct if_ath_ant_comb_state),
+	    M_TEMP, M_WAITOK | M_ZERO);
+	if (ss == NULL) {
+		device_printf(sc->sc_dev, "%s: failed to allocate\n",
+		    __func__);
+		/* Don't fail at this point */
+		return (0);
+	}
+
+	/* Let's flip this on */
+	sc->sc_lna_div = ss;
+	sc->sc_dolnadiv = 1;
+
+	return (0);
+}
+
+/*
+ * Detach the LNA diversity state from the given interface
+ */
+int
+ath_lna_div_detach(struct ath_softc *sc)
+{
+	if (sc->sc_lna_div != NULL) {
+		free(sc->sc_lna_div, M_TEMP);
+		sc->sc_lna_div = NULL;
+	}
+	sc->sc_dolnadiv = 0;
+	return (0);
+}
+
+/*
+ * Enable LNA diversity on the current channel if it's required.
+ */
+int
+ath_lna_div_enable(struct ath_softc *sc, const struct ieee80211_channel *chan)
+{
+
+	return (0);
+}
+
+/*
+ * Handle ioctl requests from the diagnostic interface.
+ *
+ * The initial part of this code resembles ath_ioctl_diag();
+ * it's likely a good idea to reduce duplication between
+ * these two routines.
+ */
+int
+ath_lna_div_ioctl(struct ath_softc *sc, struct ath_diag *ad)
+{
+	unsigned int id = ad->ad_id & ATH_DIAG_ID;
+	void *indata = NULL;
+	void *outdata = NULL;
+	u_int32_t insize = ad->ad_in_size;
+	u_int32_t outsize = ad->ad_out_size;
+	int error = 0;
+//	int val;
+
+	if (ad->ad_id & ATH_DIAG_IN) {
+		/*
+		 * Copy in data.
+		 */
+		indata = malloc(insize, M_TEMP, M_NOWAIT);
+		if (indata == NULL) {
+			error = ENOMEM;
+			goto bad;
+		}
+		error = copyin(ad->ad_in_data, indata, insize);
+		if (error)
+			goto bad;
+	}
+	if (ad->ad_id & ATH_DIAG_DYN) {
+		/*
+		 * Allocate a buffer for the results (otherwise the HAL
+		 * returns a pointer to a buffer where we can read the
+		 * results).  Note that we depend on the HAL leaving this
+		 * pointer for us to use below in reclaiming the buffer;
+		 * may want to be more defensive.
+		 */
+		outdata = malloc(outsize, M_TEMP, M_NOWAIT);
+		if (outdata == NULL) {
+			error = ENOMEM;
+			goto bad;
+		}
+	}
+	switch (id) {
+		default:
+			error = EINVAL;
+	}

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-all mailing list