Index: src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ar5416/ar5416phy.h
===================================================================
--- src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ar5416/ar5416phy.h	(revision 38867)
+++ src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ar5416/ar5416phy.h	(working copy)
@@ -111,6 +111,9 @@
 
 #define AR_PHY_HEAVY_CLIP_ENABLE    0x99E0
 
+#define AR_PHY_HEAVY_CLIP_FACTOR_RIFS	0x99ec
+#define AR_PHY_RIFS_INIT_DELAY		0x03ff0000
+
 #define AR_PHY_M_SLEEP      0x99f0      /* sleep control registers */
 #define AR_PHY_REFCLKDLY    0x99f4
 #define AR_PHY_REFCLKPD     0x99f8
Index: src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ar5416/ar9160.ini
===================================================================
--- src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ar5416/ar9160.ini	(revision 38867)
+++ src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ar5416/ar9160.ini	(working copy)
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
- * Copyright (c) 2002-2008 Atheros Communications, Inc.
+ * Copyright (c) 2002-2009 Atheros Communications, Inc.
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -35,22 +35,24 @@
     { 0x00009848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
     { 0x0000a848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
     { 0x0000b848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
-    { 0x00009850, 0x6d48b4e2, 0x6d48b4e2, 0x6d48b0e2, 0x6d48b0e2, 0x6d48b0e2 },
+    { 0x00009850, 0x6c48b4e2, 0x6c48b4e2, 0x6c48b0e2, 0x6c48b0e2, 0x6c48b0e2 },
     { 0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e },
-    { 0x0000985c, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e },
+    { 0x0000985c, 0x31395d5e, 0x31395d5e, 0x31395d5e, 0x31395d5e, 0x31395d5e },
     { 0x00009860, 0x00048d18, 0x00048d18, 0x00048d20, 0x00048d20, 0x00048d18 },
+    { 0x00009864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 },
     { 0x0000c864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 },
     { 0x00009868, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0 },
     { 0x0000986c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 },
-    { 0x00009914, 0x000007d0, 0x000007d0, 0x00000898, 0x00000898, 0x000007d0 },
+    { 0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0 },
     { 0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016 },
     { 0x00009924, 0xd00a8a07, 0xd00a8a07, 0xd00a8a0d, 0xd00a8a0d, 0xd00a8a0d },
-    { 0x00009944, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020 },
+    { 0x00009944, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020 },
     { 0x00009960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40 },
     { 0x0000a960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40 },
     { 0x0000b960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40 },
     { 0x00009964, 0x00001120, 0x00001120, 0x00001120, 0x00001120, 0x00001120 },
     { 0x0000c968, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce, 0x000003ce },
+    { 0x000099bc, 0x001a0600, 0x001a0600, 0x001a0c00, 0x001a0c00, 0x001a0c00 },
     { 0x0000c9bc, 0x001a0600, 0x001a0600, 0x001a0c00, 0x001a0c00, 0x001a0c00 },
     { 0x000099c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, 0x038919be },
     { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 },
@@ -212,7 +214,7 @@
     { 0x00008134, 0x00000000 },
     { 0x00008138, 0x00000000 },
     { 0x0000813c, 0x00000000 },
-    { 0x00008144, 0x00000000 },
+    { 0x00008144, 0xffffffff },
     { 0x00008168, 0x00000000 },
     { 0x0000816c, 0x00000000 },
     { 0x00008170, 0x32143320 },
@@ -271,7 +273,7 @@
     { 0x0000832c, 0x00000007 },
     { 0x00008330, 0x00000302 },
     { 0x00008334, 0x00000e00 },
-    { 0x00008338, 0x00000000 },
+    { 0x00008338, 0x00ff0000 },
     { 0x0000833c, 0x00000000 },
     { 0x00008340, 0x000107ff },
     { 0x00009808, 0x00000000 },
@@ -326,6 +328,7 @@
     { 0x000099e4, 0xaaaaaaaa },
     { 0x000099e8, 0x3c466478 },
     { 0x000099ec, 0x0cc80caa },
+    { 0x000099f0, 0x00000000 },		/* XXX adrian's addition: AR_PHY_CALMODE == 0 */
     { 0x000099fc, 0x00001042 },
     { 0x00009b00, 0x00000000 },
     { 0x00009b04, 0x00000001 },
@@ -405,7 +408,7 @@
     { 0x0000a244, 0x00007bb6 },
     { 0x0000a248, 0x0fff3ffc },
     { 0x0000a24c, 0x00000001 },
-    { 0x0000a250, 0x0000a000 },
+    { 0x0000a250, 0x0000e000 },
     { 0x0000a254, 0x00000000 },
     { 0x0000a258, 0x0cc75380 },
     { 0x0000a25c, 0x0f0f0f01 },
@@ -425,7 +428,7 @@
     { 0x0000a34c, 0x3fffffff },
     { 0x0000a350, 0x3fffffff },
     { 0x0000a354, 0x0003ffff },
-    { 0x0000a358, 0x79a8aa33 },
+    { 0x0000a358, 0x79bfaa03 },
     { 0x0000d35c, 0x07ffffef },
     { 0x0000d360, 0x0fffffe7 },
     { 0x0000d364, 0x17ffffe5 },
Index: src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ar5416/ar5416reg.h
===================================================================
--- src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ar5416/ar5416reg.h	(revision 38867)
+++ src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ar5416/ar5416reg.h	(working copy)
@@ -127,6 +127,7 @@
 #define	AR_EXTRCCNT		0x8328	/* extension channel rx clear count */
 #define	AR_SELFGEN_MASK		0x832c	/* rx and cal chain masks */
 #define	AR_PCU_TXBUF_CTRL	0x8340
+#define	AR_PCU_MISC_MODE2	0x8344
 
 /* DMA & PCI Registers in PCI space (usable during sleep)*/
 #define	AR_RC_AHB		0x00000001	/* AHB reset */
@@ -244,6 +245,10 @@
 #define	AR_ISR_S2_GTT		0x00800000	/* Global transmit timeout */
 #define	AR_ISR_S2_TSFOOR	0x40000000	/* RX TSF out of range */
 
+#define	AR_ISR_S5		0x0098
+#define	AR_ISR_S5_S		0x00d8
+#define	AR_ISR_S5_TIM_TIMER	0x00000010
+
 #define	AR_INTR_SPURIOUS	0xffffffff
 #define	AR_INTR_RTC_IRQ		0x00000001	/* rtc in shutdown state */
 #define	AR_INTR_MAC_IRQ		0x00000002	/* pending mac interrupt */
@@ -495,6 +500,8 @@
 #define	AR_PCU_CLEAR_VMF		0x01000000 /* clear vmf mode (fast cc)*/
 #define	AR_PCU_CLEAR_BA_VALID		0x04000000 /* clear ba state */
 
+#define	AR_PCU_MISC_MODE2_HWWAR1	0x00100000
+
 /* GPIO Interrupt */
 #define	AR_INTR_GPIO		0x3FF00000	/* gpio interrupted */
 #define	AR_INTR_GPIO_S		20
@@ -521,6 +528,8 @@
 #define	AR_GPIO_INTR_POL_VAL	0x1FFF
 #define	AR_GPIO_INTR_POL_VAL_S	0
 
+#define	AR_GPIO_JTAG_DISABLE	0x00020000
+
 #define	AR_2040_JOINED_RX_CLEAR	0x00000001	/* use ctl + ext rx_clear for cca */
 
 #define	AR_PCU_TXBUF_CTRL_SIZE_MASK	0x7FF
@@ -603,7 +612,7 @@
 	 AH_PRIVATE((_ah))->ah_macRev == AR_XSREV_REVISION_MERLIN_20)
 #define	AR_SREV_MERLIN_20_OR_LATER(_ah) \
 	(AR_SREV_MERLIN_20(_ah) || \
-	 AH_PRIVATE((_ah))->ah_macVersion > AR_XSREV_VERSION_MERLIN)
+	 AH_PRIVATE((_ah))->ah_macVersion >= AR_XSREV_VERSION_MERLIN)
 
 #define	AR_SREV_KITE(_ah) \
 	(AH_PRIVATE((_ah))->ah_macVersion == AR_XSREV_VERSION_KITE)
Index: src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ar5416/ar9285_reset.c
===================================================================
--- src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ar5416/ar9285_reset.c	(revision 38867)
+++ src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ar5416/ar9285_reset.c	(working copy)
@@ -245,107 +245,60 @@
     const HAL_EEPROM_v4k *ee = AH_PRIVATE(ah)->ah_eeprom;
     const struct ar5416eeprom_4k *eep = &ee->ee_base;
     const MODAL_EEP4K_HEADER *pModal;
-    int			i, regChainOffset;
-    uint8_t		txRxAttenLocal;    /* workaround for eeprom versions <= 14.2 */
+    uint8_t	txRxAttenLocal = 23;
 
     HALASSERT(AH_PRIVATE(ah)->ah_eeversion >= AR_EEPROM_VER14_1);
     pModal = &eep->modalHeader;
 
-    /* NB: workaround for eeprom versions <= 14.2 */
-    txRxAttenLocal = 23;
-
     OS_REG_WRITE(ah, AR_PHY_SWITCH_COM, pModal->antCtrlCommon);
-    for (i = 0; i < AR5416_4K_MAX_CHAINS; i++) { 
-	   if (AR_SREV_MERLIN(ah)) {
-		if (i >= 2) break;
-	   }
-       	   if (AR_SREV_OWL_20_OR_LATER(ah) &&
-            (AH5416(ah)->ah_rx_chainmask == 0x5 ||
-	     AH5416(ah)->ah_tx_chainmask == 0x5) && i != 0) {
-            /* Regs are swapped from chain 2 to 1 for 5416 2_0 with 
-             * only chains 0 and 2 populated 
-             */
-            regChainOffset = (i == 1) ? 0x2000 : 0x1000;
-        } else {
-            regChainOffset = i * 0x1000;
-        }
-
-        OS_REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset, pModal->antCtrlChain[i]);
-        OS_REG_WRITE(ah, AR_PHY_TIMING_CTRL4 + regChainOffset, 
-        	(OS_REG_READ(ah, AR_PHY_TIMING_CTRL4 + regChainOffset) &
+    OS_REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0, pModal->antCtrlChain[0]);
+    OS_REG_WRITE(ah, AR_PHY_TIMING_CTRL4,
+        	(OS_REG_READ(ah, AR_PHY_TIMING_CTRL4) &
         	~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF | AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) |
-        	SM(pModal->iqCalICh[i], AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
-        	SM(pModal->iqCalQCh[i], AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));
+        	SM(pModal->iqCalICh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
+        	SM(pModal->iqCalQCh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));
 
-        /*
-         * Large signal upgrade.
-	 * XXX update
-         */
+    if (IS_EEP_MINOR_V3(ah)) {
+	if (IEEE80211_IS_CHAN_HT40(chan)) {
+		/* Overwrite switch settling with HT40 value */
+		OS_REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH,
+		    pModal->swSettleHt40);
+	}
+	txRxAttenLocal = pModal->txRxAttenCh[0];
 
-        if ((i == 0) || AR_SREV_OWL_20_OR_LATER(ah)) {
-            OS_REG_WRITE(ah, AR_PHY_RXGAIN + regChainOffset, 
-		(OS_REG_READ(ah, AR_PHY_RXGAIN + regChainOffset) & ~AR_PHY_RXGAIN_TXRX_ATTEN) |
-			SM(IS_EEP_MINOR_V3(ah)  ? pModal->txRxAttenCh[i] : txRxAttenLocal,
-				AR_PHY_RXGAIN_TXRX_ATTEN));
+        OS_REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ, AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN,
+	    pModal->bswMargin[0]);
+        OS_REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ, AR_PHY_GAIN_2GHZ_XATTEN1_DB,
+	    pModal->bswAtten[0]);
+	OS_REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ, AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN,
+	    pModal->xatten2Margin[0]);
+	OS_REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ, AR_PHY_GAIN_2GHZ_XATTEN2_DB,
+	    pModal->xatten2Db[0]);
 
-            OS_REG_WRITE(ah, AR_PHY_GAIN_2GHZ + regChainOffset, 
-	    	(OS_REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) & ~AR_PHY_GAIN_2GHZ_RXTX_MARGIN) |
-			SM(pModal->rxTxMarginCh[i], AR_PHY_GAIN_2GHZ_RXTX_MARGIN));
-        }
+	/* block 1 has the same values as block 0 */	
+        OS_REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + 0x1000,
+	    AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN, pModal->bswMargin[0]);
+        OS_REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + 0x1000,
+	    AR_PHY_GAIN_2GHZ_XATTEN1_DB, pModal->bswAtten[0]);
+	OS_REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + 0x1000,
+	    AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN, pModal->xatten2Margin[0]);
+	OS_REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + 0x1000,
+	    AR_PHY_GAIN_2GHZ_XATTEN2_DB, pModal->xatten2Db[0]);
+
     }
+    OS_REG_RMW_FIELD(ah, AR_PHY_RXGAIN,
+        AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal);
+    OS_REG_RMW_FIELD(ah, AR_PHY_RXGAIN,
+        AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[0]);
 
-    OS_REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH, pModal->switchSettling);
-    OS_REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC, pModal->adcDesiredSize);
-    OS_REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_PGA, pModal->pgaDesiredSize);
-    OS_REG_WRITE(ah, AR_PHY_RF_CTL4,
-        SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF)
-        | SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAB_OFF)
-        | SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAA_ON)
-        | SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAB_ON));
+    OS_REG_RMW_FIELD(ah, AR_PHY_RXGAIN + 0x1000,
+        AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal);
+    OS_REG_RMW_FIELD(ah, AR_PHY_RXGAIN + 0x1000,
+        AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[0]);
 
-    OS_REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON, pModal->txEndToRxOn);
+    if (AR_SREV_KITE_11(ah))
+	    OS_REG_WRITE(ah, AR9285_AN_TOP4, (AR9285_AN_TOP4_DEFAULT | 0x14));
 
-     OS_REG_RMW_FIELD(ah, AR_PHY_CCA, AR9280_PHY_CCA_THRESH62,
-	    pModal->thresh62);
-     OS_REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0, AR_PHY_EXT_CCA0_THRESH62,
-	    pModal->thresh62);
-    
-    /* Minor Version Specific application */
-    if (IS_EEP_MINOR_V2(ah)) {
-        OS_REG_RMW_FIELD(ah, AR_PHY_RF_CTL2,  AR_PHY_TX_FRAME_TO_DATA_START, pModal->txFrameToDataStart);
-        OS_REG_RMW_FIELD(ah, AR_PHY_RF_CTL2,  AR_PHY_TX_FRAME_TO_PA_ON, pModal->txFrameToPaOn);    
-    }	
-    
-    if (IS_EEP_MINOR_V3(ah)) {
-	if (IEEE80211_IS_CHAN_HT40(chan)) {
-		/* Overwrite switch settling with HT40 value */
-		OS_REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH, pModal->swSettleHt40);
-	}
-	
-        if ((AR_SREV_OWL_20_OR_LATER(ah)) &&
-            (  AH5416(ah)->ah_rx_chainmask == 0x5 || AH5416(ah)->ah_tx_chainmask == 0x5)){
-            /* Reg Offsets are swapped for logical mapping */
-		OS_REG_WRITE(ah, AR_PHY_GAIN_2GHZ + 0x1000, (OS_REG_READ(ah, AR_PHY_GAIN_2GHZ + 0x1000) & ~AR_PHY_GAIN_2GHZ_BSW_MARGIN) |
-			SM(pModal->bswMargin[2], AR_PHY_GAIN_2GHZ_BSW_MARGIN));
-		OS_REG_WRITE(ah, AR_PHY_GAIN_2GHZ + 0x1000, (OS_REG_READ(ah, AR_PHY_GAIN_2GHZ + 0x1000) & ~AR_PHY_GAIN_2GHZ_BSW_ATTEN) |
-			SM(pModal->bswAtten[2], AR_PHY_GAIN_2GHZ_BSW_ATTEN));
-		OS_REG_WRITE(ah, AR_PHY_GAIN_2GHZ + 0x2000, (OS_REG_READ(ah, AR_PHY_GAIN_2GHZ + 0x2000) & ~AR_PHY_GAIN_2GHZ_BSW_MARGIN) |
-			SM(pModal->bswMargin[1], AR_PHY_GAIN_2GHZ_BSW_MARGIN));
-		OS_REG_WRITE(ah, AR_PHY_GAIN_2GHZ + 0x2000, (OS_REG_READ(ah, AR_PHY_GAIN_2GHZ + 0x2000) & ~AR_PHY_GAIN_2GHZ_BSW_ATTEN) |
-			SM(pModal->bswAtten[1], AR_PHY_GAIN_2GHZ_BSW_ATTEN));
-        } else {
-		OS_REG_WRITE(ah, AR_PHY_GAIN_2GHZ + 0x1000, (OS_REG_READ(ah, AR_PHY_GAIN_2GHZ + 0x1000) & ~AR_PHY_GAIN_2GHZ_BSW_MARGIN) |
-			SM(pModal->bswMargin[1], AR_PHY_GAIN_2GHZ_BSW_MARGIN));
-		OS_REG_WRITE(ah, AR_PHY_GAIN_2GHZ + 0x1000, (OS_REG_READ(ah, AR_PHY_GAIN_2GHZ + 0x1000) & ~AR_PHY_GAIN_2GHZ_BSW_ATTEN) |
-			SM(pModal->bswAtten[1], AR_PHY_GAIN_2GHZ_BSW_ATTEN));
-		OS_REG_WRITE(ah, AR_PHY_GAIN_2GHZ + 0x2000, (OS_REG_READ(ah, AR_PHY_GAIN_2GHZ + 0x2000) & ~AR_PHY_GAIN_2GHZ_BSW_MARGIN) |
-			SM(pModal->bswMargin[2],AR_PHY_GAIN_2GHZ_BSW_MARGIN));
-		OS_REG_WRITE(ah, AR_PHY_GAIN_2GHZ + 0x2000, (OS_REG_READ(ah, AR_PHY_GAIN_2GHZ + 0x2000) & ~AR_PHY_GAIN_2GHZ_BSW_ATTEN) |
-			SM(pModal->bswAtten[2], AR_PHY_GAIN_2GHZ_BSW_ATTEN));
-        }
-        OS_REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ, AR_PHY_GAIN_2GHZ_BSW_MARGIN, pModal->bswMargin[0]);
-        OS_REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ, AR_PHY_GAIN_2GHZ_BSW_ATTEN, pModal->bswAtten[0]);
-    }
     return AH_TRUE;
 }
 
@@ -634,7 +587,7 @@
     OS_REG_WRITE(ah, AR_PHY_TPCRG1, (OS_REG_READ(ah, AR_PHY_TPCRG1) & 
     	~(AR_PHY_TPCRG1_NUM_PD_GAIN | AR_PHY_TPCRG1_PD_GAIN_1 | AR_PHY_TPCRG1_PD_GAIN_2 | AR_PHY_TPCRG1_PD_GAIN_3)) | 
 	SM(numXpdGain - 1, AR_PHY_TPCRG1_NUM_PD_GAIN) | SM(xpdGainValues[0], AR_PHY_TPCRG1_PD_GAIN_1 ) |
-	SM(xpdGainValues[1], AR_PHY_TPCRG1_PD_GAIN_2) | SM(xpdGainValues[2],  AR_PHY_TPCRG1_PD_GAIN_3));
+	SM(xpdGainValues[1], AR_PHY_TPCRG1_PD_GAIN_2) | SM(0, AR_PHY_TPCRG1_PD_GAIN_3));
 
     for (i = 0; i < AR5416_MAX_CHAINS; i++) {
 
@@ -839,7 +792,7 @@
          * for last gain, pdGainBoundary == Pmax_t2, so will
          * have to extrapolate
          */
-        if (tgtIndex > maxIndex) {  /* need to extrapolate above */
+        if (tgtIndex >= maxIndex) {  /* need to extrapolate above */
             while ((ss <= tgtIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
                 tmpVal = (int16_t)((vpdTableI[i][sizeCurrVpdTable - 1] +
                           (ss - maxIndex +1) * vpdStep));
Index: src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ar5416/ar5416_cal.c
===================================================================
--- src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ar5416/ar5416_cal.c	(revision 38867)
+++ src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ar5416/ar5416_cal.c	(working copy)
@@ -24,6 +24,8 @@
 
 #include "ah_eeprom_v14.h"
 
+#include "ar5212/ar5212.h"	/* for NF cal related declarations */
+
 #include "ar5416/ar5416.h"
 #include "ar5416/ar5416reg.h"
 #include "ar5416/ar5416phy.h"
@@ -219,7 +221,17 @@
 	 * higher than normal value if DC offset and noise floor cal are
 	 * triggered at the same time.
 	 */
+	/* XXX this actually kicks off a NF calibration -adrian */
 	OS_REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
+	/*
+	 * Try to make sure the above NF cal completes, just so
+	 * it doesn't clash with subsequent percals -adrian
+	 */
+	if (! ar5212WaitNFCalComplete(ah, 10000)) {
+		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: initial NF calibration did "
+		    "not complete in time; noisy environment?\n", __func__);
+		return AH_FALSE;
+	}
 
 	/* Initialize list pointers */
 	cal->cal_list = cal->cal_last = cal->cal_curr = AH_NULL;
@@ -396,6 +408,13 @@
 
 	*isCalDone = AH_TRUE;
 
+	/*
+	 * Since ath_hal calls the PerCal method with rxchainmask=0x1;
+	 * override it with the current chainmask. The upper levels currently
+	 * doesn't know about the chainmask.
+	 */
+	rxchainmask = AH5416(ah)->ah_rx_chainmask;
+
 	/* Invalid channel check */
 	ichan = ath_hal_checkchannel(ah, chan);
 	if (ichan == AH_NULL) {
@@ -509,7 +528,7 @@
 		AR_PHY_CH2_EXT_CCA
 	};
 	struct ar5212NfCalHist *h;
-	int i, j;
+	int i;
 	int32_t val;
 	uint8_t chainmask;
 
@@ -545,10 +564,20 @@
 	OS_REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
 
 	/* Wait for load to complete, should be fast, a few 10s of us. */
-	for (j = 0; j < 1000; j++) {
-		if ((OS_REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) == 0)
-			break;
-		OS_DELAY(10);
+	if (! ar5212WaitNFCalComplete(ah, 1000)) {
+		/*
+		 * We timed out waiting for the noisefloor to load, probably due to an
+		 * in-progress rx. Simply return here and allow the load plenty of time
+		 * to complete before the next calibration interval.  We need to avoid
+		 * trying to load -50 (which happens below) while the previous load is
+		 * still in progress as this can cause rx deafness. Instead by returning
+		 * here, the baseband nf cal will just be capped by our present
+		 * noisefloor until the next calibration timer.
+		 */
+		HALDEBUG(ah, HAL_DEBUG_ANY, "Timeout while waiting for nf "
+		    "to load: AR_PHY_AGC_CONTROL=0x%x\n",
+		    OS_REG_READ(ah, AR_PHY_AGC_CONTROL));
+		return;
 	}
 
 	/*
@@ -614,7 +643,7 @@
 {
 	int16_t nf, nfThresh;
 
-	if (OS_REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) {
+	if (ar5212IsNFCalInProgress(ah)) {
 		HALDEBUG(ah, HAL_DEBUG_ANY,
 		    "%s: NF didn't complete in calibration window\n", __func__);
 		nf = 0;
Index: src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ar5416/ar9285_attach.c
===================================================================
--- src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ar5416/ar9285_attach.c	(revision 38867)
+++ src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ar5416/ar9285_attach.c	(working copy)
@@ -121,6 +121,8 @@
 	AH5416(ah)->ah_writeIni		= ar9285WriteIni;
 	AH5416(ah)->ah_rx_chainmask	= AR9285_DEFAULT_RXCHAINMASK;
 	AH5416(ah)->ah_tx_chainmask	= AR9285_DEFAULT_TXCHAINMASK;
+	
+	ahp->ah_maxTxTrigLev		= MAX_TX_FIFO_THRESHOLD >> 1;
 
 	if (!ar5416SetResetReg(ah, HAL_RESET_POWER_ON)) {
 		/* reset chip */
@@ -314,6 +316,16 @@
 	regWrites = ath_hal_ini_write(ah, &AH5212(ah)->ah_ini_common,
 	    1, regWrites);
 
+      	OS_REG_SET_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
+
+	if (AR_SREV_MERLIN_10_OR_LATER(ah)) {
+		uint32_t val;
+		val = OS_REG_READ(ah, AR_PCU_MISC_MODE2) &
+			(~AR_PCU_MISC_MODE2_HWWAR1);
+		OS_REG_WRITE(ah, AR_PCU_MISC_MODE2, val);
+		OS_REG_WRITE(ah, 0x9800 + (651 << 2), 0x11);
+	}
+
 }
 
 /*
@@ -376,8 +388,8 @@
 	case HAL_ANT_VARIABLE:
 		/* Restore original chainmask settings */
 		/* XXX */
-		ahp->ah_tx_chainmask = AR5416_DEFAULT_TXCHAINMASK;
-		ahp->ah_rx_chainmask = AR5416_DEFAULT_RXCHAINMASK;
+		ahp->ah_tx_chainmask = AR9285_DEFAULT_TXCHAINMASK;
+		ahp->ah_rx_chainmask = AR9285_DEFAULT_RXCHAINMASK;
 		break;
 	}
 	return AH_TRUE;
Index: src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ar5416/ar5416.ini
===================================================================
--- src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ar5416/ar5416.ini	(revision 38867)
+++ src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ar5416/ar5416.ini	(working copy)
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
- * Copyright (c) 2002-2008 Atheros Communications, Inc.
+ * Copyright (c) 2008-2009 Atheros Communications Inc.
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -24,29 +24,31 @@
     { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
     { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 },
     { 0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000, 0x00014008 },
-    { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801080, 0x08400840, 0x06e006e0 },
+    { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 },
     { 0x0000801c, 0x128d93a7, 0x128d93cf, 0x12e013d7, 0x12e013ab, 0x098813cf },
+    { 0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810, 0x08f04810 },
+    { 0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a, 0x0000320a },
     { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 },
     { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 },
     { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
     { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 },
     { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
     { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 },
-    { 0x00009844, 0x1372161e, 0x13721c1e, 0x13721c30, 0x137216a4, 0x13721c25 },
+    { 0x00009844, 0x1372161e, 0x1372161e, 0x137216a0, 0x137216a0, 0x137216a0 },
     { 0x00009848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
     { 0x0000a848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
     { 0x0000b848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
-    { 0x00009850, 0x6c28b4e0, 0x6c28b4e0, 0x6d68b0de, 0x6d68b0de, 0x6c28b0de },
+    { 0x00009850, 0x6c48b4e0, 0x6d48b4e0, 0x6d48b0de, 0x6c48b0de, 0x6c48b0de },
     { 0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e },
-    { 0x0000985c, 0x313a5d5e, 0x313a5d5e, 0x313a605e, 0x313a605e, 0x313a5d5e },
-    { 0x00009860, 0x00049d10, 0x00049d10, 0x00049d20, 0x00049d20, 0x00049d10 },
-    { 0x0000c864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 },
+    { 0x0000985c, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e, 0x31395d5e },
+    { 0x00009860, 0x00049d18, 0x00049d18, 0x00049d18, 0x00049d18, 0x00049d18 },
+    { 0x00009864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 },
     { 0x00009868, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190 },
     { 0x0000986c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 },
-    { 0x00009914, 0x000007d0, 0x000007d0, 0x00000898, 0x00000898, 0x000007d0 },
-    { 0x00009918, 0x000001b8, 0x00000370, 0x00000268, 0x00000134, 0x00000370 },
-    { 0x00009924, 0xd0058a0b, 0xd0058a0b, 0xd0058a19, 0xd0058a13, 0xd0058a0b },
-    { 0x00009944, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020 },
+    { 0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0 },
+    { 0x00009918, 0x000001b8, 0x00000370, 0x00000268, 0x00000134, 0x00000134 },
+    { 0x00009924, 0xd0058a0b, 0xd0058a0b, 0xd0058a0b, 0xd0058a0b, 0xd0058a0b },
+    { 0x00009944, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020 },
 #ifdef TB243
     { 0x00009960, 0x00000900, 0x00000900, 0x00009b40, 0x00009b40, 0x00012d80 },
     { 0x0000a960, 0x00000900, 0x00000900, 0x00009b40, 0x00009b40, 0x00012d80 },
@@ -63,14 +65,16 @@
 #endif
 #endif
     { 0x0000c9bc, 0x001a0a00, 0x001a0a00, 0x001a0a00, 0x001a0a00, 0x001a0a00 },
+    { 0x00009964, 0x00000000, 0x00000000, 0x00001120, 0x00001120, 0x00001120 },
+    { 0x000099bc, 0x001a0a00, 0x001a0a00, 0x001a0a00, 0x001a0a00, 0x001a0a00 },
     { 0x000099c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, 0x038919be },
     { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 },
-    { 0x000099c8, 0x60f6532c, 0x60f6532c, 0x60f6532c, 0x60f6532c, 0x60f6532c },
+    { 0x000099c8, 0x6af6532c, 0x6af6532c, 0x6af6532c, 0x6af6532c, 0x6af6532c },
     { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 },
     { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 },
     { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
     { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-    { 0x0000a204, 0x00000440, 0x00000440, 0x00000440, 0x00000440, 0x00000440 },
+    { 0x0000a204, 0x00000880, 0x00000880, 0x00000880, 0x00000880, 0x00000880 },
     { 0x0000a208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, 0xd03e4788 },
     { 0x0000a20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120 },
     { 0x0000b20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120 },
@@ -219,7 +223,6 @@
     { 0x00008110, 0x00000168 },
     { 0x00008118, 0x000100aa },
     { 0x0000811c, 0x00003210 },
-    { 0x00008120, 0x08f04800 },
     { 0x00008124, 0x00000000 },
     { 0x00008128, 0x00000000 },
     { 0x0000812c, 0x00000000 },
@@ -227,7 +230,7 @@
     { 0x00008134, 0x00000000 },
     { 0x00008138, 0x00000000 },
     { 0x0000813c, 0x00000000 },
-    { 0x00008144, 0x00000000 },
+    { 0x00008144, 0xffffffff },
     { 0x00008168, 0x00000000 },
     { 0x0000816c, 0x00000000 },
     { 0x00008170, 0x32143320 },
@@ -235,7 +238,6 @@
     { 0x00008178, 0x00000100 },
     { 0x0000817c, 0x00000000 },
     { 0x000081c4, 0x00000000 },
-    { 0x000081d0, 0x00003210 },
     { 0x000081ec, 0x00000000 },
     { 0x000081f0, 0x00000000 },
     { 0x000081f4, 0x00000000 },
@@ -266,6 +268,7 @@
     { 0x00008258, 0x00000000 },
     { 0x0000825c, 0x400000ff },
     { 0x00008260, 0x00080922 },
+    { 0x00008264, 0xa8000010 },
     { 0x00008270, 0x00000000 },
     { 0x00008274, 0x40000000 },
     { 0x00008278, 0x003e4180 },
@@ -286,7 +289,7 @@
     { 0x0000832c, 0x00000007 },
     { 0x00008330, 0x00000302 },
     { 0x00008334, 0x00000e00 },
-    { 0x00008338, 0x00000000 },
+    { 0x00008338, 0x00070000 },
     { 0x0000833c, 0x00000000 },
     { 0x00008340, 0x000107ff },
     { 0x00009808, 0x00000000 },
@@ -297,7 +300,7 @@
     { 0x0000982c, 0x0000a000 },
     { 0x00009830, 0x00000000 },
     { 0x0000983c, 0x00200400 },
-    { 0x00009840, 0x206a016e },
+    { 0x00009840, 0x206a002e },
     { 0x0000984c, 0x1284233c },
     { 0x00009854, 0x00000859 },
     { 0x00009900, 0x00000000 },
@@ -319,7 +322,7 @@
     { 0x00009958, 0x00081fff },
     { 0x0000c95c, 0x004b6a8e },
     { 0x0000c968, 0x000003ce },
-    { 0x00009970, 0x190c0514 },
+    { 0x00009970, 0x190fb515 },
     { 0x00009974, 0x00000000 },
     { 0x00009978, 0x00000001 },
     { 0x0000997c, 0x00000000 },
@@ -334,7 +337,7 @@
     { 0x000099a0, 0x00000000 },
     { 0x000099a4, 0x00000001 },
     { 0x000099a8, 0x001fff00 },
-    { 0x000099ac, 0x000000c4 },
+    { 0x000099ac, 0x00000000 },
     { 0x000099b0, 0x03051000 },
     { 0x000099dc, 0x00000000 },
     { 0x000099e0, 0x00000200 },
@@ -426,9 +429,9 @@
     { 0x0000a25c, 0x0f0f0f01 },
     { 0x0000a260, 0xdfa91f01 },
     { 0x0000a268, 0x00000000 },
-    { 0x0000a26c, 0x0ebae9c6 },
-    { 0x0000b26c, 0x0ebae9c6 },
-    { 0x0000c26c, 0x0ebae9c6 },
+    { 0x0000a26c, 0x0e79e5c6 },
+    { 0x0000b26c, 0x0e79e5c6 },
+    { 0x0000c26c, 0x0e79e5c6 },
     { 0x0000d270, 0x00820820 },
     { 0x0000a278, 0x1ce739ce },
     { 0x0000a27c, 0x051701ce },
@@ -441,15 +444,15 @@
     { 0x0000a350, 0x3fffffff },
     { 0x0000a354, 0x0003ffff },
     { 0x0000a358, 0x79a8aa1f },
-    { 0x0000d35c, 0x066c420f },
-    { 0x0000d360, 0x0f282207 },
-    { 0x0000d364, 0x17601685 },
-    { 0x0000d368, 0x1f801104 },
-    { 0x0000d36c, 0x37a00c03 },
-    { 0x0000d370, 0x3fc40883 },
-    { 0x0000d374, 0x57c00803 },
-    { 0x0000d378, 0x5fd80682 },
-    { 0x0000d37c, 0x7fe00482 },
+    { 0x0000d35c, 0x07ffffef },
+    { 0x0000d360, 0x0fffffe7 },
+    { 0x0000d364, 0x17ffffe5 },
+    { 0x0000d368, 0x1fffffe4 },
+    { 0x0000d36c, 0x37ffffe3 },
+    { 0x0000d370, 0x3fffffe3 },
+    { 0x0000d374, 0x57ffffe3 },
+    { 0x0000d378, 0x5fffffe2 },
+    { 0x0000d37c, 0x7fffffe2 },
     { 0x0000d380, 0x7f3c7bba },
     { 0x0000d384, 0xf3307ff0 },
     { 0x0000a388, 0x08000000 },
@@ -625,8 +628,8 @@
     { 0x0000989c, 0x00dc0000, 0x00dc0000 },
     { 0x0000989c, 0x00110000, 0x00110000 },
     { 0x0000989c, 0x006100a8, 0x006100a8 },
-    { 0x0000989c, 0x00421022, 0x00421022 },
-    { 0x0000989c, 0x001400df, 0x001400df },
+    { 0x0000989c, 0x00423022, 0x00423022 },
+    { 0x0000989c, 0x201400df, 0x201400df },
     { 0x0000989c, 0x00c40002, 0x00c40002 },
     { 0x0000989c, 0x003000f2, 0x003000f2 },
     { 0x0000989c, 0x00440016, 0x00440016 },
@@ -634,7 +637,7 @@
     { 0x0000989c, 0x0001805e, 0x0001805e },
     { 0x0000989c, 0x0000c0ab, 0x0000c0ab },
     { 0x0000989c, 0x000000e1, 0x000000e1 },
-    { 0x0000989c, 0x00002081, 0x00002081 },
+    { 0x0000989c, 0x00007081, 0x00007081 },
     { 0x0000989c, 0x000000d4, 0x000000d4 },
     { 0x000098d0, 0x0000000f, 0x0010000f },
 };
@@ -648,43 +651,43 @@
 };
 
 static const uint32_t ar5416Addac[][2] = {
-    {0x0989c,  0x00000000 },
-    {0x0989c,  0x00000003 },
-    {0x0989c,  0x00000000 },
-    {0x0989c,  0x0000000c },
-    {0x0989c,  0x00000000 },
-    {0x0989c,  0x00000030 },
-    {0x0989c,  0x00000000 },
-    {0x0989c,  0x00000000 },
-    {0x0989c,  0x00000000 },
-    {0x0989c,  0x00000000 },
-    {0x0989c,  0x00000000 },
-    {0x0989c,  0x00000000 },
-    {0x0989c,  0x00000000 },
-    {0x0989c,  0x00000000 },
-    {0x0989c,  0x00000000 },
-    {0x0989c,  0x00000000 },
-    {0x0989c,  0x00000000 },
-    {0x0989c,  0x00000000 },
-    {0x0989c,  0x00000060 },
-    {0x0989c,  0x00000000 },
-    {0x0989c,  0x00000000 },
-    {0x0989c,  0x00000000 },
-    {0x0989c,  0x00000000 },
-    {0x0989c,  0x00000000 },
-    {0x0989c,  0x00000000 },
-    {0x0989c,  0x00000000 },
-    {0x0989c,  0x00000000 },
-    {0x0989c,  0x00000000 },
-    {0x0989c,  0x00000000 },
-    {0x0989c,  0x00000000 },
-    {0x0989c,  0x00000000 },
-    {0x0989c,  0x00000058 },
-    {0x0989c,  0x00000000 },
-    {0x0989c,  0x00000000 },
-    {0x0989c,  0x00000000 },
-    {0x0989c,  0x00000000 },
-    {0x098c4,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000003 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x0000000c },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000030 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000060 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000058 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x000098cc,  0x00000000 },
 };
 
 /* hand-crafted from code that does explicit register writes */
Index: src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ar5416/ar5416_interrupts.c
===================================================================
--- src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ar5416/ar5416_interrupts.c	(revision 38867)
+++ src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ar5416/ar5416_interrupts.c	(working copy)
@@ -120,6 +120,13 @@
 			ahp->ah_intrTxqs |= MS(isr1, AR_ISR_S1_QCU_TXEOL);
 		}
 
+		if (AR_SREV_MERLIN(ah) || AR_SREV_KITE(ah)) {
+			uint32_t isr5;
+			isr5 = OS_REG_READ(ah, AR_ISR_S5_S);
+			if (isr5 & AR_ISR_S5_TIM_TIMER)
+				*masked |= HAL_INT_TIM_TIMER;
+		}
+
 		/* Interrupt Mitigation on AR5416 */
 #ifdef AR5416_INT_MITIGATION
 		if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM))
Index: src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ar5416/ar5416_reset.c
===================================================================
--- src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ar5416/ar5416_reset.c	(revision 38867)
+++ src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ar5416/ar5416_reset.c	(working copy)
@@ -170,7 +170,16 @@
 	OS_REG_WRITE(ah, AR_RSSI_THR, rssiThrReg);
 
 	OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);
+	if (AR_SREV_MERLIN_10_OR_LATER(ah))
+		OS_REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE);
 
+	if (AR_SREV_KITE(ah)) {
+		uint32_t val;
+		val = OS_REG_READ(ah, AR_PHY_HEAVY_CLIP_FACTOR_RIFS);
+		val &= ~AR_PHY_RIFS_INIT_DELAY;
+		OS_REG_WRITE(ah, AR_PHY_HEAVY_CLIP_FACTOR_RIFS, val);
+	}
+	
 	AH5416(ah)->ah_writeIni(ah, chan);
 
 	/* Setup 11n MAC/Phy mode registers */
@@ -436,6 +445,7 @@
 static void
 ar5416InitDMA(struct ath_hal *ah)
 {
+	struct ath_hal_5212 *ahp = AH5212(ah);
 
 	/*
 	 * set AHB_MODE not to do cacheline prefetches
@@ -454,7 +464,10 @@
 	OS_REG_WRITE(ah, AR_RXCFG, 
 		(OS_REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_DMASZ_MASK) | AR_RXCFG_DMASZ_128B);
 
-	/* XXX restore TX trigger level */
+	/* restore TX trigger level */
+	OS_REG_WRITE(ah, AR_TXCFG,
+		(OS_REG_READ(ah, AR_TXCFG) &~ AR_FTRIG) |
+		    SM(ahp->ah_txTrigLev, AR_FTRIG));
 
 	/*
 	 * Setup receive FIFO threshold to hold off TX activities
@@ -1015,8 +1028,11 @@
     /*
      * RTC reset and clear
      */
+    OS_REG_WRITE(ah, AR_RC, AR_RC_AHB);
     OS_REG_WRITE(ah, AR_RTC_RESET, 0);
     OS_DELAY(20);
+    OS_REG_WRITE(ah, AR_RC, 0);
+
     OS_REG_WRITE(ah, AR_RTC_RESET, 1);
 
     /*
@@ -1992,7 +2008,7 @@
          * for last gain, pdGainBoundary == Pmax_t2, so will
          * have to extrapolate
          */
-        if (tgtIndex > maxIndex) {  /* need to extrapolate above */
+        if (tgtIndex >= maxIndex) {  /* need to extrapolate above */
             while ((ss <= tgtIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
                 tmpVal = (int16_t)((vpdTableI[i][sizeCurrVpdTable - 1] +
                           (ss - maxIndex +1) * vpdStep));
Index: src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ar5416/ar5416_cal_iq.c
===================================================================
--- src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ar5416/ar5416_cal_iq.c	(revision 38867)
+++ src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ar5416/ar5416_cal_iq.c	(working copy)
@@ -115,7 +115,7 @@
 			if (qCoff > 15)
 				qCoff = 15;
 			else if (qCoff <= -16)
-				qCoff = 16;
+				qCoff = -16;
 			HALDEBUG(ah, HAL_DEBUG_PERCAL,
 			    " : iCoff = 0x%x  qCoff = 0x%x\n", iCoff, qCoff);
 
Index: src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ah_eeprom_v1.c
===================================================================
--- src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ah_eeprom_v1.c	(revision 38867)
+++ src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ah_eeprom_v1.c	(working copy)
@@ -112,7 +112,7 @@
 {
 	HAL_EEPROM_v1 *ee = AH_PRIVATE(ah)->ah_eeprom;
 	uint16_t athvals[AR_EEPROM_ATHEROS_MAX];	/* XXX off stack */
-	uint16_t protect, version, eeval;
+	uint16_t protect, eeprom_version, eeval;
 	uint32_t sum;
 	int i, loc;
 
@@ -138,18 +138,18 @@
 	HALDEBUG(ah, HAL_DEBUG_ATTACH, "EEPROM protect 0x%x\n", protect);
 	/* XXX check proper access before continuing */
 
-	if (!ath_hal_eepromRead(ah, AR_EEPROM_VERSION, &version)) {
+	if (!ath_hal_eepromRead(ah, AR_EEPROM_VERSION, &eeprom_version)) {
 		HALDEBUG(ah, HAL_DEBUG_ANY,
 		    "%s: unable to read EEPROM version\n", __func__);
 		return HAL_EEREAD;
 	}
-	if (((version>>12) & 0xf) != 1) {
+	if (((eeprom_version>>12) & 0xf) != 1) {
 		/*
 		 * This code only groks the version 1 EEPROM layout.
 		 */
 		HALDEBUG(ah, HAL_DEBUG_ANY,
 		    "%s: unsupported EEPROM version 0x%x found\n",
-		    __func__, version);
+		    __func__, eeprom_version);
 		return HAL_EEVERSION;
 	}
 
@@ -183,7 +183,7 @@
 		return HAL_ENOMEM;
 	}
 
-	ee->ee_version		= version;
+	ee->ee_version		= eeprom_version;
 	ee->ee_protect		= protect;
 	ee->ee_antenna		= athvals[2];
 	ee->ee_biasCurrents	= athvals[3];
@@ -243,7 +243,7 @@
 	}
 
 	AH_PRIVATE(ah)->ah_eeprom = ee;
-	AH_PRIVATE(ah)->ah_eeversion = version;
+	AH_PRIVATE(ah)->ah_eeversion = eeprom_version;
 	AH_PRIVATE(ah)->ah_eepromDetach = v1EepromDetach;
 	AH_PRIVATE(ah)->ah_eepromGet = v1EepromGet;
 	AH_PRIVATE(ah)->ah_eepromSet = v1EepromSet;
Index: src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ah_eeprom_v4k.c
===================================================================
--- src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ah_eeprom_v4k.c	(revision 38867)
+++ src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ah_eeprom_v4k.c	(working copy)
@@ -38,11 +38,8 @@
 	int i;
 
 	switch (param) {
-        case AR_EEP_NFTHRESH_5:
-		*(int16_t *)val = pModal[0].noiseFloorThreshCh[0];
-		return HAL_OK;
         case AR_EEP_NFTHRESH_2:
-		*(int16_t *)val = pModal[1].noiseFloorThreshCh[0];
+		*(int16_t *)val = pModal->noiseFloorThreshCh[0];
 		return HAL_OK;
         case AR_EEP_MACADDR:		/* Get MAC Address */
 		sum = 0;
@@ -67,14 +64,10 @@
 		return pBase->opCapFlags;
         case AR_EEP_RFSILENT:
 		return pBase->rfSilent;
-	case AR_EEP_OB_5:
-		return pModal[CHAN_A_IDX].ob;
-    	case AR_EEP_DB_5:
-		return pModal[CHAN_A_IDX].db;
     	case AR_EEP_OB_2:
-		return pModal[CHAN_B_IDX].ob;
+		return pModal->ob;
     	case AR_EEP_DB_2:
-		return pModal[CHAN_B_IDX].db;
+		return pModal->db;
 	case AR_EEP_TXMASK:
 		return pBase->txMask;
 	case AR_EEP_RXMASK:
@@ -84,11 +77,9 @@
 	case AR_EEP_TXGAIN_TYPE:
 		return IS_VERS(>=, AR5416_EEP_MINOR_VER_19) ?
 		    pBase->txGainType : AR5416_EEP_TXGAIN_ORIG;
-#if 0
 	case AR_EEP_OL_PWRCTRL:
 		HALASSERT(val == AH_NULL);
-		return pBase->openLoopPwrCntl ?  HAL_OK : HAL_EIO;
-#endif
+		return HAL_EIO;
 	case AR_EEP_AMODE:
 		HALASSERT(val == AH_NULL);
 		return pBase->opCapFlags & AR5416_OPFLAGS_11A ?
@@ -110,16 +101,12 @@
 	case AR_EEP_AES:
 	case AR_EEP_BURST:
         case AR_EEP_RFKILL:
-	case AR_EEP_TURBO5DISABLE:
 	case AR_EEP_TURBO2DISABLE:
 		HALASSERT(val == AH_NULL);
 		return HAL_OK;
 	case AR_EEP_ANTGAINMAX_2:
-		*(int8_t *) val = ee->ee_antennaGainMax[1];
+		*(int8_t *) val = ee->ee_antennaGainMax;
 		return HAL_OK;
-	case AR_EEP_ANTGAINMAX_5:
-		*(int8_t *) val = ee->ee_antennaGainMax[0];
-		return HAL_OK;
         default:
 		HALASSERT(0);
 		return HAL_EINVAL;
@@ -136,11 +123,8 @@
 
 	switch (param) {
 	case AR_EEP_ANTGAINMAX_2:
-		ee->ee_antennaGainMax[1] = (int8_t) v;
+		ee->ee_antennaGainMax = (int8_t) v;
 		return HAL_OK;
-	case AR_EEP_ANTGAINMAX_5:
-		ee->ee_antennaGainMax[0] = (int8_t) v;
-		return HAL_OK;
 	}
 	return HAL_EINVAL;
 }
@@ -252,7 +236,7 @@
 	RD_EDGES_POWER *rep = ee->ee_rdEdgesPower;
 	int i, j;
 	
-	HALASSERT(AR5416_NUM_CTLS <= sizeof(ee->ee_rdEdgesPower)/NUM_EDGES);
+	HALASSERT(AR5416_4K_NUM_CTLS <= sizeof(ee->ee_rdEdgesPower)/NUM_EDGES);
 
 	for (i = 0; ee->ee_base.ctlIndex[i] != 0 && i < AR5416_4K_NUM_CTLS; i++) {
 		for (j = 0; j < NUM_EDGES; j ++) {
Index: src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ah_eeprom_v4k.h
===================================================================
--- src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ah_eeprom_v4k.h	(revision 38867)
+++ src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ah_eeprom_v4k.h	(working copy)
@@ -23,6 +23,8 @@
 #include "ah_eeprom.h"
 #include "ah_eeprom_v14.h"
 
+#define	AR9285_RDEXT_DEFAULT	0x1F
+
 #undef owl_eep_start_loc
 #ifdef __LINUX_ARM_ARCH__ /* AP71 */
 #define owl_eep_start_loc		0
@@ -150,6 +152,6 @@
 	uint16_t	ee_numCtls;
 	RD_EDGES_POWER	ee_rdEdgesPower[NUM_EDGES*AR5416_4K_NUM_CTLS];
 	/* XXX these are dynamically calculated for use by shared code */
-	int8_t		ee_antennaGainMax[2];
+	int8_t		ee_antennaGainMax;
 } HAL_EEPROM_v4k;
 #endif /* _AH_EEPROM_V4K_H_ */
Index: src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ar5210/ar5210_reset.c
===================================================================
--- src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ar5210/ar5210_reset.c	(revision 38867)
+++ src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ar5210/ar5210_reset.c	(working copy)
@@ -526,9 +526,10 @@
 	/* AGC calibration (this was added to make the NF threshold check work) */
 	OS_REG_WRITE(ah, AR_PHY_AGCCTL,
 		 OS_REG_READ(ah, AR_PHY_AGCCTL) | AR_PHY_AGC_CAL);
-	if (!ath_hal_wait(ah, AR_PHY_AGCCTL, AR_PHY_AGC_CAL, 0))
+	if (!ath_hal_wait(ah, AR_PHY_AGCCTL, AR_PHY_AGC_CAL, 0)) {
 		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: AGC calibration timeout\n",
 		    __func__);
+	}
 
 	/* Rewrite our AGC values we stored off earlier (return AGC to normal operation) */
 	OS_REG_WRITE(ah, 0x9858, reg9858);
Index: src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ah_internal.h
===================================================================
--- src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ah_internal.h	(revision 38867)
+++ src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ah_internal.h	(working copy)
@@ -334,6 +334,8 @@
 	(_ah)->ah_configPCIE(_ah, _reset)
 #define	ath_hal_disablePCIE(_ah) \
 	(_ah)->ah_disablePCIE(_ah)
+#define	ath_hal_setInterrupts(_ah, _mask) \
+	(_ah)->ah_setInterrupts(_ah, _mask)
 
 #define	ath_hal_eepromDetach(_ah) do {				\
 	if (AH_PRIVATE(_ah)->ah_eepromDetach != AH_NULL)	\
Index: src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ar5211/ar5211_reset.c
===================================================================
--- src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ar5211/ar5211_reset.c	(revision 38867)
+++ src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ar5211/ar5211_reset.c	(working copy)
@@ -46,7 +46,7 @@
 } CHAN_INFO_2GHZ;
 
 #define CI_2GHZ_INDEX_CORRECTION 19
-const static CHAN_INFO_2GHZ chan2GHzData[] = {
+static const CHAN_INFO_2GHZ chan2GHzData[] = {
 	{ 1, 0x46, 96  },	/* 2312 -19 */
 	{ 1, 0x46, 97  },	/* 2317 -18 */
 	{ 1, 0x46, 98  },	/* 2322 -17 */
@@ -926,9 +926,10 @@
 
 	if (!getNoiseFloorThresh(ah, chan, &nfThresh))
 		return AH_FALSE;
-	if (OS_REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF)
+	if (OS_REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) {
 		HALDEBUG(ah, HAL_DEBUG_ANY,
 		    "%s: NF did not complete in calibration window\n", __func__);
+	}
 	nf = ar5211GetNoiseFloor(ah);
 	if (nf > nfThresh) {
 		HALDEBUG(ah, HAL_DEBUG_ANY,
Index: src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ar5212/ar5212_attach.c
===================================================================
--- src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ar5212/ar5212_attach.c	(revision 38867)
+++ src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ar5212/ar5212_attach.c	(working copy)
@@ -248,6 +248,9 @@
 	ahp->ah_acktimeout = (u_int) -1;
 	ahp->ah_ctstimeout = (u_int) -1;
 	ahp->ah_sifstime = (u_int) -1;
+	ahp->ah_txTrigLev = INIT_TX_FIFO_THRESHOLD,
+	ahp->ah_maxTxTrigLev = MAX_TX_FIFO_THRESHOLD,
+
 	OS_MEMCPY(&ahp->ah_bssidmask, defbssidmask, IEEE80211_ADDR_LEN);
 #undef N
 }
Index: src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ar5212/ar5212_xmit.c
===================================================================
--- src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ar5212/ar5212_xmit.c	(revision 38867)
+++ src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ar5212/ar5212_xmit.c	(working copy)
@@ -48,16 +48,19 @@
 	uint32_t txcfg, curLevel, newLevel;
 	HAL_INT omask;
 
+	if (ahp->ah_txTrigLev >= ahp->ah_maxTxTrigLev)
+		return AH_FALSE;
+
 	/*
 	 * Disable interrupts while futzing with the fifo level.
 	 */
-	omask = ar5212SetInterrupts(ah, ahp->ah_maskReg &~ HAL_INT_GLOBAL);
+	omask = ath_hal_setInterrupts(ah, ahp->ah_maskReg &~ HAL_INT_GLOBAL);
 
 	txcfg = OS_REG_READ(ah, AR_TXCFG);
 	curLevel = MS(txcfg, AR_FTRIG);
 	newLevel = curLevel;
 	if (bIncTrigLevel) {		/* increase the trigger level */
-		if (curLevel < MAX_TX_FIFO_THRESHOLD)
+		if (curLevel < ahp->ah_maxTxTrigLev)
 			newLevel++;
 	} else if (curLevel > MIN_TX_FIFO_THRESHOLD)
 		newLevel--;
@@ -66,8 +69,10 @@
 		OS_REG_WRITE(ah, AR_TXCFG,
 			(txcfg &~ AR_FTRIG) | SM(newLevel, AR_FTRIG));
 
+	ahp->ah_txTrigLev = newLevel;
+
 	/* re-enable chip interrupts */
-	ar5212SetInterrupts(ah, omask);
+	ath_hal_setInterrupts(ah, omask);
 
 	return (newLevel != curLevel);
 }
Index: src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ar5212/ar5212_reset.c
===================================================================
--- src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ar5212/ar5212_reset.c	(revision 38867)
+++ src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ar5212/ar5212_reset.c	(working copy)
@@ -283,6 +283,14 @@
 	regWrites = ath_hal_ini_write(ah, &ahp->ah_ini_modes, modesIndex, 0);
 	regWrites = write_common(ah, &ahp->ah_ini_common, bChannelChange,
 		regWrites);
+#ifdef AH_RXCFG_SDMAMW_4BYTES
+	/*
+	 * Nala doesn't work with 128 byte bursts on pb42(hydra) (ar71xx),
+	 * use 4 instead.  Enabling it on all platforms would hurt performance,
+	 * so we only enable it on the ones that are affected by it.
+	 */
+	OS_REG_WRITE(ah, AR_RXCFG, 0);
+#endif
 	ahp->ah_rfHal->writeRegs(ah, modesIndex, freqIndex, regWrites);
 
 	OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);
Index: src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ar5212/ar5212.h
===================================================================
--- src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ar5212/ar5212.h	(revision 38867)
+++ src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ar5212/ar5212.h	(working copy)
@@ -327,6 +327,9 @@
 	uint16_t	*ah_pcdacTable;
 	u_int		ah_pcdacTableSize;
 	uint16_t	ah_ratesArray[16];
+
+	uint8_t		ah_txTrigLev;		/* current Tx trigger level */
+	uint8_t		ah_maxTxTrigLev;	/* max tx trigger level */
 };
 #define	AH5212(_ah)	((struct ath_hal_5212 *)(_ah))
 
@@ -605,4 +608,8 @@
 			     const struct ieee80211_channel *);
 extern	void ar5212AniReset(struct ath_hal *, const struct ieee80211_channel *,
 		HAL_OPMODE, int);
+
+extern	HAL_BOOL ar5212IsNFCalInProgress(struct ath_hal *ah);
+extern	HAL_BOOL ar5212WaitNFCalComplete(struct ath_hal *ah, int i);
+
 #endif	/* _ATH_AR5212_H_ */
Index: src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ar5212/ar5212_misc.c
===================================================================
--- src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ar5212/ar5212_misc.c	(revision 38867)
+++ src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ar5212/ar5212_misc.c	(working copy)
@@ -1071,3 +1071,38 @@
 	}
 	return AH_FALSE;
 }
+
+/*
+ * Check whether there's an in-progress NF completion.
+ *
+ * Returns AH_TRUE if there's a in-progress NF calibration, AH_FALSE
+ * otherwise.
+ */
+HAL_BOOL
+ar5212IsNFCalInProgress(struct ath_hal *ah)
+{
+	if (OS_REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF)
+		return AH_TRUE;
+	return AH_FALSE;
+}
+
+/*
+ * Wait for an in-progress NF calibration to complete.
+ *
+ * The completion function waits "i" times 10uS.
+ * It returns AH_TRUE if the NF calibration completed (or was never
+ * in progress); AH_FALSE if it was still in progress after "i" checks.
+ */
+HAL_BOOL
+ar5212WaitNFCalComplete(struct ath_hal *ah, int i)
+{
+	int j;
+	if (i <= 0)
+		i = 1;	  /* it should run at least once */
+	for (j = 0; j < i; j++) {
+		if (! ar5212IsNFCalInProgress(ah))
+			return AH_TRUE;
+		OS_DELAY(10);
+	}
+	return AH_FALSE;
+}
Index: src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ah.h
===================================================================
--- src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ah.h	(revision 38867)
+++ src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/ath_hal/ah.h	(working copy)
@@ -324,6 +324,7 @@
 	HAL_INT_RXORN	= 0x00000020,
 	HAL_INT_TX	= 0x00000040,	/* Non-common mapping */
 	HAL_INT_TXDESC	= 0x00000080,
+	HAL_INT_TIM_TIMER= 0x00000100,
 	HAL_INT_TXURN	= 0x00000800,
 	HAL_INT_MIB	= 0x00001000,
 	HAL_INT_RXPHY	= 0x00004000,
Index: src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/if_athvar.h
===================================================================
--- src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/if_athvar.h	(revision 38867)
+++ src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/if_athvar.h	(working copy)
@@ -306,7 +306,7 @@
 	u_int			sc_txqsetup;	/* h/w queues setup */
 	u_int			sc_txintrperiod;/* tx interrupt batching */
 	struct ath_txq		sc_txq[HAL_NUM_TX_QUEUES];
-	struct ath_txq		*sc_ac2q[5];	/* WME AC -> h/w q map */
+	struct ath_txq		*sc_ac2q[5];	/* WME AC -> h/w q map */ 
 	struct task		sc_txtask;	/* tx int processing */
 	int			sc_wd_timer;	/* count down for wd timer */
 	struct callout		sc_wd_ch;	/* tx watchdog timer */
Index: src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/if_ath.c
===================================================================
--- src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/if_ath.c	(revision 38867)
+++ src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/if_ath.c	(working copy)
@@ -215,6 +215,7 @@
 static int	ath_raw_xmit(struct ieee80211_node *,
 			struct mbuf *, const struct ieee80211_bpf_params *);
 static void	ath_announce(struct ath_softc *);
+static void	ath_sysctl_stats_attach(struct ath_softc *sc);
 
 #ifdef IEEE80211_SUPPORT_TDMA
 static void	ath_tdma_settimers(struct ath_softc *sc, u_int32_t nexttbtt,
@@ -314,7 +315,7 @@
 	ATH_DEBUG_FATAL		= 0x80000000,	/* fatal errors */
 	ATH_DEBUG_ANY		= 0xffffffff
 };
-static	int ath_debug = ATH_DEBUG_INTR |
+static int ath_debug = ATH_DEBUG_INTR |
 		ATH_DEBUG_STATE |
 		ATH_DEBUG_REGDOMAIN;
 SYSCTL_INT(_hw_ath, OID_AUTO, debug, CTLFLAG_RW, &ath_debug,
@@ -326,7 +327,7 @@
 	    (sc->sc_ifp->if_flags & (IFF_DEBUG|IFF_LINK2)) == (IFF_DEBUG|IFF_LINK2))
 #define	DPRINTF(sc, m, fmt, ...) do {				\
 	if (sc->sc_debug & (m))					\
-		printf(fmt, __VA_ARGS__);			\
+		device_printf(sc->sc_dev, fmt, __VA_ARGS__);		\
 } while (0)
 #define	KEYPRINTF(sc, ix, hk, mac) do {				\
 	if (sc->sc_debug & ATH_DEBUG_KEYCACHE)			\
@@ -735,6 +736,7 @@
 	 * regdomain are available from the hal.
 	 */
 	ath_sysctlattach(sc);
+	ath_sysctl_stats_attach(sc);
 
 	if (bootverbose)
 		ieee80211_announce(ic);
@@ -2832,6 +2834,7 @@
 	 */
 	if (ath_hal_numtxpending(ah, sc->sc_bhalq) != 0) {
 		sc->sc_bmisscount++;
+		sc->sc_stats.ast_be_missed++;
 		DPRINTF(sc, ATH_DEBUG_BEACON,
 			"%s: missed %u consecutive beacons\n",
 			__func__, sc->sc_bmisscount);
@@ -3663,7 +3666,7 @@
 		if (vap->iv_opmode == IEEE80211_M_IBSS &&
 		    vap->iv_state == IEEE80211_S_RUN) {
 			uint32_t rstamp = sc->sc_lastrs->rs_tstamp;
-			u_int64_t tsf = ath_extend_tsf(rstamp,
+			uint64_t tsf = ath_extend_tsf(rstamp,
 				ath_hal_gettsf64(sc->sc_ah));
 			/*
 			 * Handle ibss merge as needed; check the tsf on the
@@ -4004,11 +4007,11 @@
 			mtod(m, const struct ieee80211_frame_min *),
 			rs->rs_keyix == HAL_RXKEYIX_INVALID ?
 				IEEE80211_KEYIX_NONE : rs->rs_keyix);
+		sc->sc_lastrs = rs;
 		if (ni != NULL) {
 			/*
 			 * Sending station is known, dispatch directly.
 			 */
-			sc->sc_lastrs = rs;
 			type = ieee80211_input(ni, m, rs->rs_rssi, nf);
 			ieee80211_free_node(ni);
 			/*
@@ -5426,6 +5429,7 @@
 	longCal = (ticks - sc->sc_lastlongcal >= ath_longcalinterval*hz);
 	if (longCal) {
 		sc->sc_stats.ast_per_cal++;
+		sc->sc_lastlongcal = ticks;
 		if (ath_hal_getrfgain(ah) == HAL_RFGAIN_NEED_CHANGE) {
 			/*
 			 * Rfgain is out of bounds, reset the chip
@@ -5474,7 +5478,6 @@
 			nextcal *= 10;
 	} else {
 		nextcal = ath_longcalinterval*hz;
-		sc->sc_lastlongcal = ticks;
 		if (sc->sc_lastcalreset == 0)
 			sc->sc_lastcalreset = sc->sc_lastlongcal;
 		else if (ticks - sc->sc_lastcalreset >= ath_resetcalinterval*hz)
@@ -7335,3 +7338,189 @@
 	}
 }
 #endif /* IEEE80211_SUPPORT_TDMA */
+
+static int
+ath_sysctl_clearstats(SYSCTL_HANDLER_ARGS)
+{
+	struct ath_softc *sc = arg1;
+	int val = 0;
+	int error;
+
+	error = sysctl_handle_int(oidp, &val, 0, req);
+	if (error || !req->newptr)
+		return error;
+	if (val == 0)
+		return 0;       /* Not clearing the stats is still valid */
+	memset(&sc->sc_stats, 0, sizeof(sc->sc_stats));
+	val = 0;
+	return 0;
+}
+
+static void
+ath_sysctl_stats_attach(struct ath_softc *sc)
+{
+	struct sysctl_oid *tree = device_get_sysctl_tree(sc->sc_dev);
+	struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->sc_dev);
+	struct sysctl_oid_list *child = SYSCTL_CHILDREN(tree);
+ 
+	/* Create "clear" node */
+	SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
+	    "clear_stats", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
+	    ath_sysctl_clearstats, "I", "clear stats");
+
+	/* Create stats node */
+	tree = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "stats", CTLFLAG_RD,
+	    NULL, "Statistics");
+	child = SYSCTL_CHILDREN(tree);
+
+	/* This was generated from if_athioctl.h */
+
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_watchdog", CTLFLAG_RD,
+	    &sc->sc_stats.ast_watchdog, 0, "device reset by watchdog");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_hardware", CTLFLAG_RD,
+	    &sc->sc_stats.ast_hardware, 0, "fatal hardware error interrupts");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_bmiss", CTLFLAG_RD,
+	    &sc->sc_stats.ast_bmiss, 0, "beacon miss interrupts");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_bmiss_phantom", CTLFLAG_RD,
+	    &sc->sc_stats.ast_bmiss_phantom, 0, "beacon miss interrupts");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_bstuck", CTLFLAG_RD,
+	    &sc->sc_stats.ast_bstuck, 0, "beacon stuck interrupts");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rxorn", CTLFLAG_RD,
+	    &sc->sc_stats.ast_rxorn, 0, "rx overrun interrupts");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rxeol", CTLFLAG_RD,
+	    &sc->sc_stats.ast_rxeol, 0, "rx eol interrupts");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_txurn", CTLFLAG_RD,
+	    &sc->sc_stats.ast_txurn, 0, "tx underrun interrupts");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_mib", CTLFLAG_RD,
+	    &sc->sc_stats.ast_mib, 0, "mib interrupts");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_intrcoal", CTLFLAG_RD,
+	    &sc->sc_stats.ast_intrcoal, 0, "interrupts coalesced");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_packets", CTLFLAG_RD,
+	    &sc->sc_stats.ast_tx_packets, 0, "packet sent on the interface");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_mgmt", CTLFLAG_RD,
+	    &sc->sc_stats.ast_tx_mgmt, 0, "management frames transmitted");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_discard", CTLFLAG_RD,
+	    &sc->sc_stats.ast_tx_discard, 0, "frames discarded prior to assoc");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_qstop", CTLFLAG_RD,
+	    &sc->sc_stats.ast_tx_qstop, 0, "output stopped 'cuz no buffer");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_encap", CTLFLAG_RD,
+	    &sc->sc_stats.ast_tx_encap, 0, "tx encapsulation failed");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_nonode", CTLFLAG_RD,
+	    &sc->sc_stats.ast_tx_nonode, 0, "tx failed 'cuz no node");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_nombuf", CTLFLAG_RD,
+	    &sc->sc_stats.ast_tx_nombuf, 0, "tx failed 'cuz no mbuf");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_nomcl", CTLFLAG_RD,
+	    &sc->sc_stats.ast_tx_nomcl, 0, "tx failed 'cuz no cluster");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_linear", CTLFLAG_RD,
+	    &sc->sc_stats.ast_tx_linear, 0, "tx linearized to cluster");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_nodata", CTLFLAG_RD,
+	    &sc->sc_stats.ast_tx_nodata, 0, "tx discarded empty frame");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_busdma", CTLFLAG_RD,
+	    &sc->sc_stats.ast_tx_busdma, 0, "tx failed for dma resrcs");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_xretries", CTLFLAG_RD,
+	    &sc->sc_stats.ast_tx_xretries, 0, "tx failed 'cuz too many retries");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_fifoerr", CTLFLAG_RD,
+	    &sc->sc_stats.ast_tx_fifoerr, 0, "tx failed 'cuz FIFO underrun");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_filtered", CTLFLAG_RD,
+	    &sc->sc_stats.ast_tx_filtered, 0, "tx failed 'cuz xmit filtered");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_shortretry", CTLFLAG_RD,
+	    &sc->sc_stats.ast_tx_shortretry, 0, "tx on-chip retries (short)");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_longretry", CTLFLAG_RD,
+	    &sc->sc_stats.ast_tx_longretry, 0, "tx on-chip retries (long)");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_badrate", CTLFLAG_RD,
+	    &sc->sc_stats.ast_tx_badrate, 0, "tx failed 'cuz bogus xmit rate");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_noack", CTLFLAG_RD,
+	    &sc->sc_stats.ast_tx_noack, 0, "tx frames with no ack marked");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_rts", CTLFLAG_RD,
+	    &sc->sc_stats.ast_tx_rts, 0, "tx frames with rts enabled");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_cts", CTLFLAG_RD,
+	    &sc->sc_stats.ast_tx_cts, 0, "tx frames with cts enabled");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_shortpre", CTLFLAG_RD,
+	    &sc->sc_stats.ast_tx_shortpre, 0, "tx frames with short preamble");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_altrate", CTLFLAG_RD,
+	    &sc->sc_stats.ast_tx_altrate, 0, "tx frames with alternate rate");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_protect", CTLFLAG_RD,
+	    &sc->sc_stats.ast_tx_protect, 0, "tx frames with protection");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_ctsburst", CTLFLAG_RD,
+	    &sc->sc_stats.ast_tx_ctsburst, 0, "tx frames with cts and bursting");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_ctsext", CTLFLAG_RD,
+	    &sc->sc_stats.ast_tx_ctsext, 0, "tx frames with cts extension");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_nombuf", CTLFLAG_RD,
+	    &sc->sc_stats.ast_rx_nombuf, 0, "rx setup failed 'cuz no mbuf");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_busdma", CTLFLAG_RD,
+	    &sc->sc_stats.ast_rx_busdma, 0, "rx setup failed for dma resrcs");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_orn", CTLFLAG_RD,
+	    &sc->sc_stats.ast_rx_orn, 0, "rx failed 'cuz of desc overrun");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_crcerr", CTLFLAG_RD,
+	    &sc->sc_stats.ast_rx_crcerr, 0, "rx failed 'cuz of bad CRC");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_fifoerr", CTLFLAG_RD,
+	    &sc->sc_stats.ast_rx_fifoerr, 0, "rx failed 'cuz of FIFO overrun");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_badcrypt", CTLFLAG_RD,
+	    &sc->sc_stats.ast_rx_badcrypt, 0, "rx failed 'cuz decryption");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_badmic", CTLFLAG_RD,
+	    &sc->sc_stats.ast_rx_badmic, 0, "rx failed 'cuz MIC failure");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_phyerr", CTLFLAG_RD,
+	    &sc->sc_stats.ast_rx_phyerr, 0, "rx failed 'cuz of PHY err");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_tooshort", CTLFLAG_RD,
+	    &sc->sc_stats.ast_rx_tooshort, 0, "rx discarded 'cuz frame too short");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_toobig", CTLFLAG_RD,
+	    &sc->sc_stats.ast_rx_toobig, 0, "rx discarded 'cuz frame too large");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_packets", CTLFLAG_RD,
+	    &sc->sc_stats.ast_rx_packets, 0, "packet recv on the interface");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_mgt", CTLFLAG_RD,
+	    &sc->sc_stats.ast_rx_mgt, 0, "management frames received");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rx_ctl", CTLFLAG_RD,
+	    &sc->sc_stats.ast_rx_ctl, 0, "rx discarded 'cuz ctl frame");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_be_xmit", CTLFLAG_RD,
+	    &sc->sc_stats.ast_be_xmit, 0, "beacons transmitted");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_be_nombuf", CTLFLAG_RD,
+	    &sc->sc_stats.ast_be_nombuf, 0, "beacon setup failed 'cuz no mbuf");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_per_cal", CTLFLAG_RD,
+	    &sc->sc_stats.ast_per_cal, 0, "periodic calibration calls");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_per_calfail", CTLFLAG_RD,
+	    &sc->sc_stats.ast_per_calfail, 0, "periodic calibration failed");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_per_rfgain", CTLFLAG_RD,
+	    &sc->sc_stats.ast_per_rfgain, 0, "periodic calibration rfgain reset");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rate_calls", CTLFLAG_RD,
+	    &sc->sc_stats.ast_rate_calls, 0, "rate control checks");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rate_raise", CTLFLAG_RD,
+	    &sc->sc_stats.ast_rate_raise, 0, "rate control raised xmit rate");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_rate_drop", CTLFLAG_RD,
+	    &sc->sc_stats.ast_rate_drop, 0, "rate control dropped xmit rate");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_ant_defswitch", CTLFLAG_RD,
+	    &sc->sc_stats.ast_ant_defswitch, 0, "rx/default antenna switches");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_ant_txswitch", CTLFLAG_RD,
+	    &sc->sc_stats.ast_ant_txswitch, 0, "tx antenna switches");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_cabq_xmit", CTLFLAG_RD,
+	    &sc->sc_stats.ast_cabq_xmit, 0, "cabq frames transmitted");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_cabq_busy", CTLFLAG_RD,
+	    &sc->sc_stats.ast_cabq_busy, 0, "cabq found busy");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_raw", CTLFLAG_RD,
+	    &sc->sc_stats.ast_tx_raw, 0, "tx frames through raw api");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_ff_txok", CTLFLAG_RD,
+	    &sc->sc_stats.ast_ff_txok, 0, "fast frames tx'd successfully");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_ff_txerr", CTLFLAG_RD,
+	    &sc->sc_stats.ast_ff_txerr, 0, "fast frames tx'd w/ error");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_ff_rx", CTLFLAG_RD,
+	    &sc->sc_stats.ast_ff_rx, 0, "fast frames rx'd");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_ff_flush", CTLFLAG_RD,
+	    &sc->sc_stats.ast_ff_flush, 0, "fast frames flushed from staging q");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_qfull", CTLFLAG_RD,
+	    &sc->sc_stats.ast_tx_qfull, 0, "tx dropped 'cuz of queue limit");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_nobuf", CTLFLAG_RD,
+	    &sc->sc_stats.ast_tx_nobuf, 0, "tx dropped 'cuz no ath buffer");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tdma_update", CTLFLAG_RD,
+	    &sc->sc_stats.ast_tdma_update, 0, "TDMA slot timing updates");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tdma_timers", CTLFLAG_RD,
+	    &sc->sc_stats.ast_tdma_timers, 0, "TDMA slot update set beacon timers");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tdma_tsf", CTLFLAG_RD,
+	    &sc->sc_stats.ast_tdma_tsf, 0, "TDMA slot update set TSF");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tdma_ack", CTLFLAG_RD,
+	    &sc->sc_stats.ast_tdma_ack, 0, "TDMA tx failed 'cuz ACK required");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_raw_fail", CTLFLAG_RD,
+	    &sc->sc_stats.ast_tx_raw_fail, 0, "raw tx failed 'cuz h/w down");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_tx_nofrag", CTLFLAG_RD,
+	    &sc->sc_stats.ast_tx_nofrag, 0, "tx dropped 'cuz no ath frag buffer");
+	SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "ast_be_missed", CTLFLAG_RD,
+	    &sc->sc_stats.ast_be_missed, 0, "number of -missed- beacons");
+}
Index: src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/if_athioctl.h
===================================================================
--- src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/if_athioctl.h	(revision 38867)
+++ src/add-ons/kernel/drivers/network/wlan/atheroswifi/dev/ath/if_athioctl.h	(working copy)
@@ -118,7 +118,8 @@
 	u_int32_t	ast_tdma_ack;	/* TDMA tx failed 'cuz ACK required */
 	u_int32_t	ast_tx_raw_fail;/* raw tx failed 'cuz h/w down */
 	u_int32_t	ast_tx_nofrag;	/* tx dropped 'cuz no ath frag buffer */
-	u_int32_t	ast_pad[14];
+	u_int32_t	ast_be_missed;	/* missed beacons */
+	u_int32_t	ast_pad[13];
 };
 
 #define	SIOCGATHSTATS	_IOWR('i', 137, struct ifreq)
