--- a/ath/if_ath.c
+++ b/ath/if_ath.c
@@ -343,6 +343,8 @@
 		unsigned int param, unsigned int value);
 
 static u_int32_t ath_get_real_maxtxpower(struct ath_softc *sc);
+static int ath_setintmit(struct ath_softc *sc);
+static u_int32_t ath_calcrxfilter(struct ath_softc *sc);
 
 #ifdef AR_DEBUG
 static int ath_txq_check(struct ath_softc *sc, struct ath_txq *txq, const char *msg);
@@ -356,7 +358,6 @@
 static char *ratectl = DEF_RATE_CTL;
 static int rfkill = 0;
 static int hal_tpc = 0;
-static int intmit = 0;
 static int countrycode = CTRY_DEFAULT;
 static int maxvaps = ATH_MAXVAPS_DEFAULT;
 static int outdoor = 0;
@@ -398,7 +399,6 @@
 #endif
 MODULE_PARM(autocreate, "s");
 MODULE_PARM(ratectl, "s");
-MODULE_PARM(intmit, "i");
 #else
 #include <linux/moduleparam.h>
 module_param(beacon_cal, int, 0600);
@@ -412,7 +412,6 @@
 #endif
 module_param(autocreate, charp, 0600);
 module_param(ratectl, charp, 0600);
-module_param(intmit, int, 0600);
 #endif
 MODULE_PARM_DESC(countrycode, "Override default country code.  Default is 0.");
 MODULE_PARM_DESC(maxvaps, "Maximum VAPs.  Default is 4.");
@@ -428,7 +427,6 @@
 		"'none' to disable");
 MODULE_PARM_DESC(ratectl, "Rate control algorithm [amrr|minstrel|onoe|sample], "
 		"defaults to '" DEF_RATE_CTL "'");
-MODULE_PARM_DESC(intmit, "Enable interference mitigation by default.  Default is 0.");
 
 #ifdef AR_DEBUG
 static int	ath_debug = 0;
@@ -585,23 +583,13 @@
 	if (ath_hal_hastxpowlimit(ah)) {
 		ic->ic_caps |= IEEE80211_C_TXPMGT;
 	}
-	/* Interference mitigation/ambient noise immunity (ANI).
-	 * In modes other than HAL_M_STA, it causes receive sensitivity
-	 * problems for OFDM. */
+	/* Interference mitigation/ambient noise immunity (ANI). */
 	sc->sc_hasintmit = ath_hal_hasintmit(ah);
-	sc->sc_useintmit = (intmit && sc->sc_hasintmit);
-	if (!sc->sc_hasintmit && intmit) {
-		WPRINTF(sc, "Interference mitigation was requested, but is not"
-				"supported by the HAL/hardware.\n");
-		intmit = 0; /* Stop use in future ath_attach(). */
-	}
-	else {
-		ath_hal_setintmit(ah, sc->sc_useintmit);
-		DPRINTF(sc, ATH_DEBUG_ANY, "Interference mitigation is "
-			"supported.  Currently %s.\n",
-			(sc->sc_useintmit ? "enabled" : "disabled"));
-	}
 
+	/* auto, mode dependent */
+	sc->sc_useintmit = -1;
+	sc->sc_noise_immunity = -1;
+	sc->sc_ofdm_weak_det = -1;
 	sc->sc_dmasize_stomp = 0;
 
 	/*
@@ -614,15 +602,6 @@
 	sc->sc_mrretry = ath_hal_setupxtxdesc(ah, NULL, 0,0, 0,0, 0,0);
 
 	/*
-	 * Check if the device has hardware counters for PHY
-	 * errors.  If so we need to enable the MIB interrupt
-	 * so we can act on stat triggers.
-	 */
-	sc->sc_needmib = ath_hal_hwphycounters(ah) && 
-		sc->sc_hasintmit && 
-		sc->sc_useintmit;
-
-	/*
 	 * Get the hardware key cache size.
 	 */
 	sc->sc_keymax = ath_hal_keycachesize(ah);
@@ -1593,37 +1572,6 @@
 	ath_init(dev);
 }
 
-/* NB: Int. mit. was not implemented so that it could be enabled/disabled,
- * and actually in 0.9.30.13 HAL it really can't even be disabled because
- * it will start adjusting registers even when we turn off the capability
- * in the HAL.
- *
- * NB: This helper function basically clobbers all the related registers
- * if we have disabled int. mit. cap, allowing us to turn it on and off and
- * work around the bug preventing it from being disabled. */
-static inline void ath_override_intmit_if_disabled(struct ath_softc *sc) {
-	/* Restore int. mit. registers if they were turned off. */
-	if (sc->sc_hasintmit && !sc->sc_useintmit)
-		ath_hal_restore_default_intmit(sc->sc_ah);
-	/* Sanity check... remove later. */
-	if (!sc->sc_useintmit) {
-		ath_hal_verify_default_intmit(sc->sc_ah);
-		/* If we don't have int. mit. and we don't have DFS on channel,
-		 * it is safe to filter error packets. */
-		if (!ath_radar_is_dfs_required(sc, &sc->sc_curchan)) {
-			ath_hal_setrxfilter(sc->sc_ah,
-				ath_hal_getrxfilter(sc->sc_ah) & 
-				~HAL_RX_FILTER_PHYERR);
-		}
-	}
-	else {
-		/* Make sure that we have errors in RX filter because ANI needs
-		 * them. */
-		ath_hal_setrxfilter(sc->sc_ah, 
-			ath_hal_getrxfilter(sc->sc_ah) | HAL_RX_FILTER_PHYERR);
-	}
-}
-
 static HAL_BOOL ath_hw_reset(struct ath_softc *sc, HAL_OPMODE opmode,
 		HAL_CHANNEL *channel, HAL_BOOL bChannelChange,
 		HAL_STATUS *status)
@@ -1698,11 +1646,7 @@
 		ath_hal_settpc(sc->sc_ah, hal_tpc);
 	}
 #endif
-#if 0 /* Setting via HAL does not work, so it is done manually below. */
-	if (sc->sc_hasintmit)
-		ath_hal_setintmit(sc->sc_ah, sc->sc_useintmit);
-#endif
-	ath_override_intmit_if_disabled(sc);
+	ath_setintmit(sc);
 	if (sc->sc_dmasize_stomp)
 		ath_hal_set_dmasize_pcie(sc->sc_ah);
 	if (sc->sc_softled)
@@ -2496,7 +2440,6 @@
 
 			/* Let the HAL handle the event. */
 			ath_hal_mibevent(ah, &sc->sc_halstats);
-			ath_override_intmit_if_disabled(sc);
 		}
 	}
 	if (needmark)
@@ -2564,6 +2507,55 @@
 	return flags;
 }
 
+static int ath_setintmit(struct ath_softc *sc)
+{
+	struct ath_hal *ah = sc->sc_ah;
+	int ret;
+	int val;
+
+	if (!sc->sc_hasintmit)
+		return 0;
+
+	switch(sc->sc_useintmit) {
+		case 0: /* disabled */
+		case 1: /* enabled */
+			val = sc->sc_useintmit;
+			break;
+		default:
+			if (sc->sc_opmode != IEEE80211_M_MONITOR)
+				val = 1;
+			else
+				val = 0;
+			break;
+	}
+	ret = ath_hal_setintmit(ah, val);
+	if (val)
+		goto done;
+
+	/* manual settings */
+	if ((sc->sc_noise_immunity >= 0) && (sc->sc_noise_immunity <= 5))
+		ath_hal_setcapability(ah, HAL_CAP_INTMIT, 2, sc->sc_noise_immunity, NULL);
+	if ((sc->sc_ofdm_weak_det == 0) || (sc->sc_ofdm_weak_det == 1))
+		ath_hal_setcapability(ah, HAL_CAP_INTMIT, 3, sc->sc_ofdm_weak_det, NULL);
+
+done:
+	if (!sc->sc_imask)
+		goto out;
+
+	/* MIB interrupt handling */
+	sc->sc_needmib = ath_hal_hwphycounters(ah) &&
+		sc->sc_useintmit;
+	if (sc->sc_needmib)
+		sc->sc_imask |= HAL_INT_MIB;
+	else
+		sc->sc_imask &= ~HAL_INT_MIB;
+	ath_hal_intrset(sc->sc_ah, sc->sc_imask);
+	ath_calcrxfilter(sc);
+
+out:
+	return ret;
+}
+
 /*
  * Context: process context
  */
@@ -4249,8 +4241,7 @@
 	u_int32_t rfilt;
 
 	/* Preserve the current Phy. radar and err. filters. */
-	rfilt = (ath_hal_getrxfilter(ah) &
-			(HAL_RX_FILTER_PHYERR | HAL_RX_FILTER_PHYRADAR)) |
+	rfilt = (ath_hal_getrxfilter(ah) & HAL_RX_FILTER_PHYRADAR) |
 		 HAL_RX_FILTER_UCAST | HAL_RX_FILTER_BCAST |
 		 HAL_RX_FILTER_MCAST;
 	if (ic->ic_opmode != IEEE80211_M_STA)
@@ -4266,6 +4257,8 @@
 	if (sc->sc_nmonvaps > 0)
 		rfilt |= (HAL_RX_FILTER_CONTROL | HAL_RX_FILTER_BEACON |
 			  HAL_RX_FILTER_PROBEREQ | HAL_RX_FILTER_PROM);
+	if (sc->sc_hasintmit && !sc->sc_needmib && ath_hal_getintmit(ah, NULL))
+		rfilt |= HAL_RX_FILTER_PHYERR;
 	if (sc->sc_curchan.privFlags & CHANNEL_DFS)
 		rfilt |= (HAL_RX_FILTER_PHYERR | HAL_RX_FILTER_PHYRADAR);
 	return rfilt;
@@ -6810,8 +6803,7 @@
 	dev->quota -= bf_processed;
 #endif
 
-	if (sc->sc_useintmit) 
-		ath_hal_rxmonitor(ah, &sc->sc_halstats, &sc->sc_curchan);
+	ath_hal_rxmonitor(ah, &sc->sc_halstats, &sc->sc_curchan);
 	if (!bf_processed)
 		DPRINTF(sc, ATH_DEBUG_RX_PROC,
 			"Warning: %s got scheduled when no receive "
@@ -8727,7 +8719,6 @@
 	ath_hal_rxena(ah);		/* enable recv descriptors */
 	ath_mode_init(dev);		/* set filters, etc. */
 	ath_hal_startpcurecv(ah);	/* re-enable PCU/DMA engine */
-	ath_override_intmit_if_disabled(sc);
 	return 0;
 }
 
@@ -10633,8 +10624,10 @@
 	ATH_RP_IGNORED 		= 24,
 	ATH_RADAR_IGNORED       = 25,
 	ATH_MAXVAPS  		= 26,
-        ATH_INTMIT 		= 27,
-	ATH_DISTANCE		= 28,
+	ATH_DISTANCE		= 27,
+	ATH_INTMIT			= 28,
+	ATH_NOISE_IMMUNITY	= 29,
+	ATH_OFDM_WEAK_DET	= 30
 };
 
 static inline int 
@@ -10696,6 +10689,48 @@
 }
 
 static int
+ath_sysctl_set_intmit(struct ath_softc *sc, long ctl, u_int val)
+{
+	int ret;
+
+	switch(ctl) {
+	case ATH_INTMIT:
+		sc->sc_intmit = val;
+		break;
+	case ATH_NOISE_IMMUNITY:
+		sc->sc_noise_immunity = val;
+		break;
+	case ATH_OFDM_WEAK_DET:
+		sc->sc_ofdm_weak_det = val;
+		break;
+	default:
+		return -EINVAL;
+	}
+	ret = ath_setintmit(sc);
+	return ret;
+}
+
+static int
+ath_sysctl_get_intmit(struct ath_softc *sc, long ctl, u_int *val)
+{
+	struct ath_hal *ah = sc->sc_ah;
+
+	switch(ctl) {
+	case ATH_INTMIT:
+		*val = (ath_hal_getcapability(ah, HAL_CAP_INTMIT, 1, NULL) == HAL_OK);
+		break;
+	case ATH_NOISE_IMMUNITY:
+		return ath_hal_getcapability(ah, HAL_CAP_INTMIT, 2, val);
+	case ATH_OFDM_WEAK_DET:
+		return ath_hal_getcapability(ah, HAL_CAP_INTMIT, 3, val);
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+
+static int
 ATH_SYSCTL_DECL(ath_sysctl_halparam, ctl, write, filp, buffer, lenp, ppos)
 {
 	struct ath_softc *sc = ctl->extra1;
@@ -10934,30 +10969,13 @@
 				sc->sc_radar_ignored = val;
 				break;
 			case ATH_INTMIT:
-				if (!sc->sc_hasintmit) {
+			case ATH_NOISE_IMMUNITY:
+			case ATH_OFDM_WEAK_DET:
+				if (!sc->sc_hasintmit)
 					ret = -EOPNOTSUPP;
-					break;
-				}
-				if (sc->sc_useintmit == val)
-					break;
-				sc->sc_useintmit = val; 
-				sc->sc_needmib = ath_hal_hwphycounters(ah) && 
-					sc->sc_useintmit;
-				/* Update the HAL and MIB interrupt mask bits */
-				ath_hal_setintmit(ah, !!val); 
-				sc->sc_imask = (sc->sc_imask & ~HAL_INT_MIB) | 
-					(sc->sc_needmib ? HAL_INT_MIB : 0);
-				ath_hal_intrset(sc->sc_ah, sc->sc_imask);
-				/* Only do a reset if device is valid and UP 
-				 * and we just made a change to the settings. */
-				if (sc->sc_dev && !sc->sc_invalid &&
-				    (sc->sc_dev->flags & IFF_RUNNING))
-					ath_reset(sc->sc_dev); 
-				/* NB: Run this step to cleanup if HAL doesn't 
-				 * obey capability flags and hangs onto ANI
-				 * settings. */
-				ath_override_intmit_if_disabled(sc);
-                                break; 
+				else
+					ret = ath_sysctl_set_intmit(sc, (long)ctl->extra2, val);
+				break;
 			default:
 				ret = -EINVAL;
 				break;
@@ -11029,9 +11047,14 @@
 		case ATH_RADAR_IGNORED:
 			val = sc->sc_radar_ignored;
 			break;
-                case ATH_INTMIT: 
-			val = sc->sc_useintmit; 
-			break; 
+		case ATH_INTMIT:
+		case ATH_NOISE_IMMUNITY:
+		case ATH_OFDM_WEAK_DET:
+			if (!sc->sc_hasintmit)
+				ret = -EOPNOTSUPP;
+			else
+				ret = ath_sysctl_get_intmit(sc, (long)ctl->extra2, &val);
+			break;
 		default:
 			ret = -EINVAL;
 			break;
@@ -11413,6 +11436,24 @@
 	  .maxlen	= sizeof(ath_xchanmode),
 	  .proc_handler	= proc_dointvec
 	},
+	{ .ctl_name	= CTL_AUTO,
+	  .procname     = "intmit",
+	  .mode         = 0644,
+	  .proc_handler = ath_sysctl_halparam,
+	  .extra2	= (void *)ATH_INTMIT,
+	},
+	{ .ctl_name	= CTL_AUTO,
+	  .procname     = "noise_immunity",
+	  .mode         = 0644,
+	  .proc_handler = ath_sysctl_halparam,
+	  .extra2	= (void *)ATH_NOISE_IMMUNITY,
+	},
+	{ .ctl_name	= CTL_AUTO,
+	  .procname     = "ofdm_weak_det",
+	  .mode         = 0644,
+	  .proc_handler = ath_sysctl_halparam,
+	  .extra2	= (void *)ATH_OFDM_WEAK_DET,
+	},
 	{ 0 }
 };
 static ctl_table ath_ath_table[] = {
--- a/ath/if_athvar.h
+++ b/ath/if_athvar.h
@@ -712,6 +712,10 @@
 	unsigned int sc_txcont_power; /* Continuous transmit power in 0.5dBm units */
 	unsigned int sc_txcont_rate;  /* Continuous transmit rate in Mbps */
 
+	int8_t sc_intmit; /* Interference mitigation enabled, -1 = auto, based on mode, 0/1 = off/on */
+	int8_t sc_noise_immunity; /* Noise immunity level, 0-4, -1 == auto) */
+	int8_t sc_ofdm_weak_det; /* OFDM weak frames detection, -1 == auto */
+
 	/* rate tables */
 	const HAL_RATE_TABLE *sc_rates[IEEE80211_MODE_MAX];
 	const HAL_RATE_TABLE *sc_currates;	/* current rate table */
--- a/ath/if_ath_hal_extensions.h
+++ b/ath/if_ath_hal_extensions.h
@@ -237,296 +237,18 @@
 	AR5K_DMASIZE_512B
 };
 
-
-int ath_set_ack_bitrate(struct ath_softc *sc, int);
-int ar_device(int devid);
-const char * ath5k_chip_name(enum ath5k_srev_type type, u_int16_t val);
-
-static inline unsigned long field_width(unsigned long mask, unsigned long shift)
-{
-	unsigned long r = 0;
-	unsigned long x = mask >> shift;
-	if ( 0 == mask )  return  0;
-#if  BITS_PER_LONG >= 64
-	if ( x & (~0UL<<32) )  { x >>= 32;  r += 32; }
-#endif
-	if ( x & 0xffff0000 )  { x >>= 16;  r += 16; }
-	if ( x & 0x0000ff00 )  { x >>=  8;  r +=  8; }
-	if ( x & 0x000000f0 )  { x >>=  4;  r +=  4; }
-	if ( x & 0x0000000c )  { x >>=  2;  r +=  2; }
-	if ( x & 0x00000002 )  {            r +=  1; }
-	return r+1;
-}
-
-static inline u_int32_t get_field(struct ath_hal *ah, u_int32_t reg, u_int32_t mask, u_int32_t shift, int is_signed) {
-	unsigned long x = ((OS_REG_READ(ah, reg) & mask) >> shift);
-	if (is_signed) {
-		unsigned long c =(-1) << (field_width(mask, shift)-1);
-		return (x + c) ^ c;
-	}
-	return x;
-}
-
 static inline void set_field(struct ath_hal *ah, u_int32_t reg, u_int32_t mask, u_int32_t shift, u_int32_t value) {
 	OS_REG_WRITE(ah, reg, 
 			  (OS_REG_READ(ah, reg) & ~mask) | 
 			  ((value << shift) & mask));
 }
 
-static inline u_int32_t field_eq(struct ath_hal *ah, u_int32_t reg, 
-				 u_int32_t mask, u_int32_t shift, 
-				 u_int32_t value, int is_signed) {
-	return  (get_field(ah, reg, mask, shift, is_signed) & (mask >> shift)) == 
-		(value & (mask >> shift));
-}
-
-static inline void override_warning(struct ath_hal *ah, const char *name,
-				    u_int32_t reg, u_int32_t mask,
-				    u_int32_t shift, u_int32_t expected, int is_signed) {
-
-	if (!field_eq(ah, reg, mask, shift, expected, is_signed)) 
-		printk("%s: Correcting 0x%04x[%s] from 0x%x (%d) to 0x%x (%d).\n", 
-		       SC_DEV_NAME(ah->ah_sc),
-		       reg,
-		       name, 
-		       (get_field(ah, reg, mask, shift, is_signed) & (mask >> shift)),
-		       get_field(ah, reg, mask, shift, is_signed), 
-		       (expected & (mask >> shift)), /* not sign extended */
-		       expected);
-#if 0 /* NB: For checking to see if HAL is fixed or not */
-	else {
-			printk("%s: Keeping 0x%04x[%s] - 0x%x (%d).\n",
-			       SC_DEV_NAME(ah->ah_sc),
-			       reg,
-			       name, 
-			       (get_field(ah, reg, mask, shift, is_signed) & (mask >> shift)),
-			       get_field(ah, reg, mask, shift, is_signed));
-	}
-#endif
-}
-
-static inline void verification_warning(struct ath_hal *ah, const char *name,
-    u_int32_t reg, u_int32_t mask, 
-    u_int32_t shift, u_int32_t expected, int is_signed) {
-
-	int ret = field_eq(ah, reg, mask, shift, expected, is_signed);
-	if (!ret) {
-		printk("%s: %s verification of %s default value "
-		       "[found=0x%x (%d) expected=0x%x (%d)].\n", 
-		       SC_DEV_NAME(ah->ah_sc),
-		       (ret ? "PASSED" : "FAILED"),
-			name, 
-		       (get_field(ah, reg, mask, shift, is_signed) & (mask >> shift)), 
-		       get_field(ah, reg, mask, shift, is_signed), 
-		       (expected & (mask >> shift)), /* not sign extended */
-		       expected);
-		ath_hal_print_decoded_register(ah, NULL, reg, 
-					       OS_REG_READ(ah, reg), OS_REG_READ(ah, reg), 0);
-	}
-}
-
-#define GET_FIELD(ah, __reg, __mask, __signed) \
-	get_field(ah, __reg, __mask, __mask ## _S, __signed)
 #define SET_FIELD(ah, __reg, __mask, __value) \
 	set_field(ah, __reg, __mask, __mask ## _S, __value);
-#define FIELD_EQ(ah, __reg, __mask, __value, __signed) \
-	field_eq(ah, __reg, __mask, __mask ## _S, __value, __signed)
-
-#if 0 /* NB: These are working at this point, and HAL tweaks them a lot */
-#define OVERRIDE_WARNING(ah, __reg, __mask, __expected, __signed) \
-	override_warning(ah, #__mask, __reg, __mask, __mask ## _S, __expected, __signed)
-#else
-#define OVERRIDE_WARNING(ah, __reg, __mask, __expected, __signed) 
-#endif
-	
-#define VERIFICATION_WARNING(ah, __reg, __mask, __signed) \
-	verification_warning(ah, #__mask, __reg, __mask, __mask ## _S, DEFAULT_ ## __mask, __signed)
-#define VERIFICATION_WARNING_SW(ah, __reg, __mask, __signed) \
-	verification_warning(ah, #__mask, __reg, __mask, __mask ## _S, DEFAULT_ENABLE_ ## __reg ? __mask ## _ON : __mask ## _OFF, __signed)
-
-static inline void ath_hal_set_noise_immunity(struct ath_hal *ah,
-					      int agc_desired_size, 
-					      int agc_coarse_hi,
-					      int agc_coarse_lo, 
-					      int sig_firpwr) 
-{
-	ATH_HAL_LOCK_IRQ(ah->ah_sc);
-	ath_hal_set_function(__func__);
-	ath_hal_set_device(SC_DEV_NAME(ah->ah_sc));
-
-#if 0 /* NB: These are working at this point, and HAL tweaks them a lot */
-	OVERRIDE_WARNING(ah, AR5K_PHY_AGCSIZE, AR5K_PHY_AGCSIZE_DESIRED, agc_desired_size, 1);
-	OVERRIDE_WARNING(ah, AR5K_PHY_AGCCOARSE, AR5K_PHY_AGCCOARSE_LO, agc_coarse_lo, 1);
-	OVERRIDE_WARNING(ah, AR5K_PHY_AGCCOARSE, AR5K_PHY_AGCCOARSE_HI, agc_coarse_hi, 1);
-	OVERRIDE_WARNING(ah, AR5K_PHY_SIG, AR5K_PHY_SIG_FIRPWR, sig_firpwr, 1);
-#endif
-
-	SET_FIELD(ah, AR5K_PHY_AGCSIZE, AR5K_PHY_AGCSIZE_DESIRED, agc_desired_size);
-	SET_FIELD(ah, AR5K_PHY_AGCCOARSE, AR5K_PHY_AGCCOARSE_LO, agc_coarse_lo);
-	SET_FIELD(ah, AR5K_PHY_AGCCOARSE, AR5K_PHY_AGCCOARSE_HI, agc_coarse_hi);
-	SET_FIELD(ah, AR5K_PHY_SIG, AR5K_PHY_SIG_FIRPWR, sig_firpwr);
-
-	ath_hal_set_function(NULL);
-	ath_hal_set_device(NULL);
-	ATH_HAL_UNLOCK_IRQ(ah->ah_sc);
-}
-
-static inline void ath_hal_set_ofdm_weak_det(struct ath_hal *ah, 
-	int low_m1, int low_m2, int low_m2_count, int low_self_corr,
-	int high_m1, int high_m2, int high_m2_count)
-{
-	ATH_HAL_LOCK_IRQ(ah->ah_sc);
-	ath_hal_set_function(__func__);
-	ath_hal_set_device(SC_DEV_NAME(ah->ah_sc));
-
-	OVERRIDE_WARNING(ah, AR5K_PHY_WEAK_OFDM_LOW, AR5K_PHY_WEAK_OFDM_LOW_M1, low_m1, 0);
-	OVERRIDE_WARNING(ah, AR5K_PHY_WEAK_OFDM_LOW, AR5K_PHY_WEAK_OFDM_LOW_M2, low_m2, 0);
-	OVERRIDE_WARNING(ah, AR5K_PHY_WEAK_OFDM_LOW, AR5K_PHY_WEAK_OFDM_LOW_M2_COUNT, low_m2_count, 0);
-	OVERRIDE_WARNING(ah, AR5K_PHY_WEAK_OFDM_LOW, AR5K_PHY_WEAK_OFDM_LOW_SELFCOR, low_self_corr, 0);
-	OVERRIDE_WARNING(ah, AR5K_PHY_WEAK_OFDM_HIGH, AR5K_PHY_WEAK_OFDM_HIGH_M1, high_m1, 0);
-	OVERRIDE_WARNING(ah, AR5K_PHY_WEAK_OFDM_HIGH, AR5K_PHY_WEAK_OFDM_HIGH_M2, high_m2, 0);
-	OVERRIDE_WARNING(ah, AR5K_PHY_WEAK_OFDM_HIGH, AR5K_PHY_WEAK_OFDM_HIGH_M2_COUNT, high_m2_count, 0);
-
-	SET_FIELD(ah, AR5K_PHY_WEAK_OFDM_LOW, AR5K_PHY_WEAK_OFDM_LOW_M1, low_m1);
-	SET_FIELD(ah, AR5K_PHY_WEAK_OFDM_LOW, AR5K_PHY_WEAK_OFDM_LOW_M2, low_m2);
-	SET_FIELD(ah, AR5K_PHY_WEAK_OFDM_LOW, AR5K_PHY_WEAK_OFDM_LOW_M2_COUNT, low_m2_count);
-	SET_FIELD(ah, AR5K_PHY_WEAK_OFDM_LOW, AR5K_PHY_WEAK_OFDM_LOW_SELFCOR, low_self_corr);
-	SET_FIELD(ah, AR5K_PHY_WEAK_OFDM_HIGH, AR5K_PHY_WEAK_OFDM_HIGH_M1, high_m1);
-	SET_FIELD(ah, AR5K_PHY_WEAK_OFDM_HIGH, AR5K_PHY_WEAK_OFDM_HIGH_M2, high_m2);
-	SET_FIELD(ah, AR5K_PHY_WEAK_OFDM_HIGH, AR5K_PHY_WEAK_OFDM_HIGH_M2_COUNT, high_m2_count);
-
-	ath_hal_set_function(NULL);
-	ath_hal_set_device(NULL);
-	ATH_HAL_UNLOCK_IRQ(ah->ah_sc);
-}
-
-static inline void ath_hal_set_cck_weak_det(struct ath_hal *ah, int thresh)
-{
-	ATH_HAL_LOCK_IRQ(ah->ah_sc);
-	ath_hal_set_function(__func__);
-	ath_hal_set_device(SC_DEV_NAME(ah->ah_sc));
-
-	OVERRIDE_WARNING(ah, AR5K_PHY_WEAK_CCK, AR5K_PHY_WEAK_CCK_THRESH, thresh, 0);
-
-	SET_FIELD(ah, AR5K_PHY_WEAK_CCK, AR5K_PHY_WEAK_CCK_THRESH, thresh);
-
-	ath_hal_set_function(NULL);
-	ath_hal_set_device(NULL);
-	ATH_HAL_UNLOCK_IRQ(ah->ah_sc);
-}
-
-static inline void ath_hal_set_sig_firstep(struct ath_hal *ah, int firstep)
-{
-	ATH_HAL_LOCK_IRQ(ah->ah_sc);
-	ath_hal_set_function(__func__);
-	ath_hal_set_device(SC_DEV_NAME(ah->ah_sc));
 
-	OVERRIDE_WARNING(ah, AR5K_PHY_SIG, AR5K_PHY_SIG_FIRSTEP, firstep, 0);
-
-	SET_FIELD(ah, AR5K_PHY_SIG, AR5K_PHY_SIG_FIRSTEP, firstep);
-
-	ath_hal_set_function(NULL);
-	ath_hal_set_device(NULL);
-	ATH_HAL_UNLOCK_IRQ(ah->ah_sc);
-}
-
-static inline void ath_hal_set_spur_immunity(struct ath_hal *ah, int thresh)
-{
-	ATH_HAL_LOCK_IRQ(ah->ah_sc);
-	ath_hal_set_function(__func__);
-	ath_hal_set_device(SC_DEV_NAME(ah->ah_sc));
-
-	OVERRIDE_WARNING(ah, AR5K_PHY_SPUR, AR5K_PHY_SPUR_THRESH, thresh, 0);
-
-	SET_FIELD(ah, AR5K_PHY_SPUR, AR5K_PHY_SPUR_THRESH, thresh);
-
-	ath_hal_set_function(NULL);
-	ath_hal_set_device(NULL);
-	ATH_HAL_UNLOCK_IRQ(ah->ah_sc);
-}
-
-static inline void ath_hal_restore_default_noise_immunity(struct ath_hal *ah) {
-
-	ath_hal_set_noise_immunity(ah, 
-		DEFAULT_AR5K_PHY_AGCSIZE_DESIRED, 
-		DEFAULT_AR5K_PHY_AGCCOARSE_HI,
-		DEFAULT_AR5K_PHY_AGCCOARSE_LO,
-		DEFAULT_AR5K_PHY_SIG_FIRPWR);
-}
-
-static inline void ath_hal_enable_ofdm_weak_det(struct ath_hal *ah, int enable) {
-	if (enable)
-		ath_hal_set_ofdm_weak_det(ah, 
-			AR5K_PHY_WEAK_OFDM_LOW_M1_ON,
-			AR5K_PHY_WEAK_OFDM_LOW_M2_ON,
-			AR5K_PHY_WEAK_OFDM_LOW_M2_COUNT_ON,
-		        AR5K_PHY_WEAK_OFDM_LOW_SELFCOR_ON,
-			AR5K_PHY_WEAK_OFDM_HIGH_M1_ON,
-			AR5K_PHY_WEAK_OFDM_HIGH_M2_ON,
-			AR5K_PHY_WEAK_OFDM_HIGH_M2_COUNT_ON);
-	else
-		ath_hal_set_ofdm_weak_det(ah, 
-			AR5K_PHY_WEAK_OFDM_LOW_M1_OFF,
-			AR5K_PHY_WEAK_OFDM_LOW_M2_OFF,
-			AR5K_PHY_WEAK_OFDM_LOW_M2_COUNT_OFF,
-			AR5K_PHY_WEAK_OFDM_LOW_SELFCOR_OFF,
-			AR5K_PHY_WEAK_OFDM_HIGH_M1_OFF,
-			AR5K_PHY_WEAK_OFDM_HIGH_M2_OFF,
-			AR5K_PHY_WEAK_OFDM_HIGH_M2_COUNT_OFF);
-}
-
-static inline void ath_hal_enable_cck_weak_det(struct ath_hal *ah, int enable) {
-	ath_hal_set_cck_weak_det(ah, enable 
-				 ? AR5K_PHY_WEAK_CCK_THRESH_ON 
-				 : AR5K_PHY_WEAK_CCK_THRESH_OFF);
-}
-
-static inline void ath_hal_restore_default_ofdm_weak_det(struct ath_hal *ah) {
-	ath_hal_enable_ofdm_weak_det(ah, DEFAULT_ENABLE_AR5K_PHY_WEAK_OFDM);
-}
-
-static inline void ath_hal_restore_default_cck_weak_det(struct ath_hal *ah) {
-	ath_hal_enable_cck_weak_det(ah, DEFAULT_ENABLE_AR5K_PHY_WEAK_CCK);
-}
-
-static inline void ath_hal_restore_default_sig_firstep(struct ath_hal *ah) {
-
-	ath_hal_set_sig_firstep(ah, 
-		DEFAULT_AR5K_PHY_SIG_FIRSTEP);
-}
-
-static inline void ath_hal_restore_default_spur_immunity(struct ath_hal *ah) {
-
-	ath_hal_set_spur_immunity(ah, 
-		DEFAULT_AR5K_PHY_SPUR_THRESH);
-}
-
-static inline void ath_hal_restore_default_intmit(struct ath_hal *ah) {
-	ath_hal_restore_default_noise_immunity(ah);
-	ath_hal_restore_default_ofdm_weak_det(ah);
-	ath_hal_restore_default_cck_weak_det(ah);
-	ath_hal_restore_default_sig_firstep(ah);
-	ath_hal_restore_default_spur_immunity(ah);
-
-}
-
-static inline void ath_hal_verify_default_intmit(struct ath_hal *ah) {
-	/* Just a list of all the fields above, for sanity checks... */
-	VERIFICATION_WARNING(ah, AR5K_PHY_AGCSIZE, AR5K_PHY_AGCSIZE_DESIRED, 1);
-	VERIFICATION_WARNING(ah, AR5K_PHY_AGCCOARSE, AR5K_PHY_AGCCOARSE_LO, 1);
-	VERIFICATION_WARNING(ah, AR5K_PHY_AGCCOARSE, AR5K_PHY_AGCCOARSE_HI, 1);
-	VERIFICATION_WARNING(ah, AR5K_PHY_SIG, AR5K_PHY_SIG_FIRPWR, 1);
-	VERIFICATION_WARNING_SW(ah, AR5K_PHY_WEAK_OFDM_LOW, AR5K_PHY_WEAK_OFDM_LOW_M1, 0);
-	VERIFICATION_WARNING_SW(ah, AR5K_PHY_WEAK_OFDM_LOW, AR5K_PHY_WEAK_OFDM_LOW_M2, 0);
-	VERIFICATION_WARNING_SW(ah, AR5K_PHY_WEAK_OFDM_LOW, AR5K_PHY_WEAK_OFDM_LOW_M2_COUNT, 0);
-	VERIFICATION_WARNING_SW(ah, AR5K_PHY_WEAK_OFDM_LOW, AR5K_PHY_WEAK_OFDM_LOW_SELFCOR, 0);
-	VERIFICATION_WARNING_SW(ah, AR5K_PHY_WEAK_OFDM_HIGH, AR5K_PHY_WEAK_OFDM_HIGH_M1, 0);
-	VERIFICATION_WARNING_SW(ah, AR5K_PHY_WEAK_OFDM_HIGH, AR5K_PHY_WEAK_OFDM_HIGH_M2, 0);
-	VERIFICATION_WARNING_SW(ah, AR5K_PHY_WEAK_OFDM_HIGH, AR5K_PHY_WEAK_OFDM_HIGH_M2_COUNT, 0);
-	VERIFICATION_WARNING_SW(ah, AR5K_PHY_WEAK_CCK, AR5K_PHY_WEAK_CCK_THRESH, 0);
-	VERIFICATION_WARNING(ah, AR5K_PHY_SIG, AR5K_PHY_SIG_FIRSTEP, 0);
-	VERIFICATION_WARNING(ah, AR5K_PHY_SPUR, AR5K_PHY_SPUR_THRESH, 0);
-}
+int ath_set_ack_bitrate(struct ath_softc *sc, int);
+int ar_device(int devid);
+const char * ath5k_chip_name(enum ath5k_srev_type type, u_int16_t val);
 
 static inline void ath_hal_set_dmasize_pcie(struct ath_hal *ah) {
 	SET_FIELD(ah, AR5K_TXCFG, AR5K_TXCFG_SDMAMR, AR5K_DMASIZE_128B);
--- a/ath/if_ath_hal.h
+++ b/ath/if_ath_hal.h
@@ -79,7 +79,7 @@
 	ath_hal_set_function(__func__);
 	ath_hal_set_device(SC_DEV_NAME(ah->ah_sc));
 	ret =
-	    ah->ah_getDiagState(ah, request, args, argsize, *result,
+	    ah->ah_getDiagState(ah, request, args, argsize, result,
 				resultsize);
 	ath_hal_set_function(NULL);
 	ath_hal_set_device(NULL);
--- a/scripts/if_ath_hal_generator.pl
+++ b/scripts/if_ath_hal_generator.pl
@@ -145,7 +145,9 @@
     "ah_waitForBeaconDone"        => "ath_hal_waitforbeacon",
     "ah_writeAssocid"             => "ath_hal_setassocid",
     "ah_clrMulticastFilterIndex"  => "ath_hal_clearmcastfilter",
-    "ah_detectCardPresent"        => "ath_hal_detectcardpresent"
+    "ah_detectCardPresent"        => "ath_hal_detectcardpresent",
+    "ah_setSifsTime"              => "ath_hal_setsifstime",
+    "ah_getSifsTime"              => "ath_hal_getsifstime"
 );
 
 #
@@ -254,7 +256,7 @@
 
     foreach (@parameters) {
         s/ \*/\* /;
-        /^((?:(?:const|struct|\*)\s*)*)([^\s]+\*?)\s*([^\s]*)\s*/;
+        /^((?:(?:const|struct|\*)\s*)*)([^\s]+\**)\s*([^\s]*)\s*/;
         my $type = "$1$2";
         my $name = "$3";
         if ( 0 == length($name) ) {