diff -Naur compat-wireless-2011-11-15.orig/drivers/net/wireless/ath/ath5k/ath5k.h compat-wireless-2011-11-15/drivers/net/wireless/ath/ath5k/ath5k.h
--- compat-wireless-2011-11-15.orig/drivers/net/wireless/ath/ath5k/ath5k.h	2012-04-14 10:36:59.000000000 +0200
+++ compat-wireless-2011-11-15/drivers/net/wireless/ath/ath5k/ath5k.h	2012-04-14 22:31:24.000000000 +0200
@@ -1245,6 +1245,12 @@
 		struct ath5k_tx_status *);
 	int (*ah_proc_rx_desc)(struct ath5k_hw *, struct ath5k_desc *,
 		struct ath5k_rx_status *);
+	//&&&HAMNET
+	//sysctl stuff
+	void			*ah_sysctl_header;
+	void			*ah_sysctls;
+	//
+	int			noacks;
 };
 
 struct ath_bus_ops {
diff -Naur compat-wireless-2011-11-15.orig/drivers/net/wireless/ath/ath5k/base.c compat-wireless-2011-11-15/drivers/net/wireless/ath/ath5k/base.c
--- compat-wireless-2011-11-15.orig/drivers/net/wireless/ath/ath5k/base.c	2012-04-14 10:36:59.000000000 +0200
+++ compat-wireless-2011-11-15/drivers/net/wireless/ath/ath5k/base.c	2012-04-14 23:36:27.000000000 +0200
@@ -48,6 +48,9 @@
 #include <linux/io.h>
 #include <linux/netdevice.h>
 #include <linux/cache.h>
+/*&&&HAMNET+++*/
+#include <linux/sysctl.h>
+/*&&&HAMNET---*/
 #include <linux/ethtool.h>
 #include <linux/uaccess.h>
 #include <linux/slab.h>
@@ -186,6 +189,10 @@
 	/* XR missing */
 };
 
+/*&&&HAMNET*/
+static int register_sysctls (struct ath5k_hw *ah);
+static int unregister_sysctls (struct ath5k_hw *ah);
+
 static inline u64 ath5k_extend_tsf(struct ath5k_hw *ah, u32 rstamp)
 {
 	u64 tsf = ath5k_hw_get_tsf64(ah);
@@ -268,7 +275,13 @@
 		/* 802.11j 5.030-5.080 GHz (20MHz) */
 		(chan == 8 || chan == 12 || chan == 16) ||
 		/* 802.11j 4.9GHz (20MHz) */
-		(chan == 184 || chan == 188 || chan == 192 || chan == 196));
+		(chan == 184 || chan == 188 || chan == 192 || chan == 196) ||
+		/*&&&HAMNET 5650: channel 130, 5850: channel 170 - allow 5MHz raster */
+		(chan >= 130 && chan <= 170)
+		);
+/* IARU Region 1:
+ *  5650 - 5850 MHz - allow 5MHz channel raster for HAM-Radio operation
+ */
 }
 
 static unsigned int
@@ -686,6 +699,11 @@
 	if (info->flags & IEEE80211_TX_CTL_NO_ACK)
 		flags |= AR5K_TXDESC_NOACK;
 
+	/* hack to disable ACKs - tell chipset to not expect an ACK for this frame */
+	if (ah->noacks) {
+		flags |= AR5K_TXDESC_NOACK;
+	}
+
 	rc_flags = info->control.rates[0].flags;
 	hw_rate = (rc_flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) ?
 		rate->hw_value_short : rate->hw_value;
@@ -2876,6 +2894,9 @@
 
 	ath5k_init_leds(ah);
 
+/*&&&&*/
+	register_sysctls(ah);
+
 	ath5k_sysfs_register(ah);
 
 	return 0;
@@ -2894,6 +2915,9 @@
 {
 	struct ieee80211_hw *hw = ah->hw;
 
+/*&&&&*/
+	unregister_sysctls(ah);
+
 	/*
 	 * NB: the order of these is important:
 	 * o call the 802.11 layer before detaching ath5k_hw to
@@ -2950,3 +2974,540 @@
 	ath5k_hw_set_rx_filter(ah, rfilt);
 	ah->filter_flags = rfilt;
 }
+
+
+/*&&&&--------------------------------------------------------
+sysctl stuff beyond this point
+*/
+enum {
+	/* IN: int, OUT: int */
+	ATH_SYSCTL_CHANNELBW		= 1,
+	ATH_SYSCTL_ACKTIMEOUT		= 2,
+	ATH_SYSCTL_CTSTIMEOUT		= 3,
+	ATH_SYSCTL_SLOTTIME		= 4,
+	ATH_SYSCTL_DISTANCE		= 5,
+	ATH_SYSCTL_NOACKS		= 6,
+	ATH_SYSCTL_NOISEFLOOR		= 7,
+	/* IN: int, OUT: char* */
+	ATH_SYSCTL_ANTSWITCHING		= 101,
+	/* IN: char*, OUT: char* */
+	ATH_SYSCTL_INFO			= 201,
+	ATH_SYSCTL_REGDUMP		= 202,
+};
+
+/* sysctl handler */
+static int
+ATH_SYSCTL_DECL(ath_sysctl, ctl, write, filp, buffer, lenp, ppos) {
+#define NUM_ANT_MODES	7
+#define VAL_S_SIZE	1024
+	struct ath5k_hw *ah = ctl->extra1;
+	uint val;
+	char val_s[VAL_S_SIZE];
+	int ret = 0;
+
+	if (!ah) return -EINVAL;
+
+	mutex_lock(&ah->lock);
+
+	// WRITE access
+	if (write) {
+		/* ID > 200 operate on strings, see above */
+		if ((long)ctl->extra2 > 200) {
+			ctl->data = val_s;
+			ctl->maxlen = VAL_S_SIZE * sizeof(char);
+			ret = ATH_SYSCTL_PROC_DOSTRING(ctl, write, filp, buffer, 
+				lenp, ppos);
+		} else {
+			ctl->data = &val;
+			ctl->maxlen = sizeof(val);
+			ret = ATH_SYSCTL_PROC_DOINTVEC(ctl, write, filp, buffer, 
+				lenp, ppos);
+		}
+		if (ret == 0) {
+			switch ((long)ctl->extra2) {
+			case ATH_SYSCTL_CHANNELBW:
+				if (val > 0) {
+					switch(val) {
+						case 40: ah->ah_bwmode=AR5K_BWMODE_40MHZ;  break;
+						case 20: ah->ah_bwmode=AR5K_BWMODE_DEFAULT; break;
+						case 10: ah->ah_bwmode=AR5K_BWMODE_10MHZ;   break;
+						case 5:  ah->ah_bwmode=AR5K_BWMODE_5MHZ;    break;
+						default: ret =  -EINVAL; break;
+					}
+				}
+				break;
+#if 0
++			case ATH_SYSCTL_ACKTIMEOUT:
++/*&&&*/printk(KERN_INFO "ath5k_hamnet: set ack timeout: %i\n", val);
++				if ( (sc && sc->ah) &&		   /* 0...8.192ms - guess... */
++				     (val >= 0) && (val <= AR5K_TIME_OUT_ACK) ) { /* 0x1fff mask in chip    */
++					sc->ack_timeout = val;
++					ret = ath5k_hw_set_ack_timeout(sc->ah, val);
++/*&&&*/printk(KERN_INFO "ath5k_hamnet: set ack timeout ret=%i\n", ret);
++				} else { ret = -EINVAL; }
++				break;
++			case ATH_SYSCTL_CTSTIMEOUT:
++/*&&&*/printk(KERN_INFO "ath5k_hamnet: set cts timeout: %i\n", val);
++				if ( (sc && sc->ah) &&		   /* 0...8.192ms - guess... */
++				     (val >= 0) && (val <= AR5K_TIME_OUT_ACK) ) { /* 0x1fff mask in chip    */
++					sc->cts_timeout = val;
++					ret = ath5k_hw_set_cts_timeout(sc->ah, val);
++/*&&&*/printk(KERN_INFO "ath5k_hamnet: set cts timeout ret=%i\n", ret);
++				} else { ret = -EINVAL; }
++				break;
++			case ATH_SYSCTL_SLOTTIME:
++/*&&&*/printk(KERN_INFO "ath5k_hamnet: set slottime: %i\n", val);
++				if ( (sc && sc->ah) &&
++				     (val >= 0) && (val <= AR5K_SLOT_TIME_MAX) ) { /* 0xffff mask in qcu.c   */
++					sc->slottime = val;
++					ret = ath5k_hw_set_slot_time(sc->ah, val);
++					if (sc->curchan) ath5k_reset(sc, sc->curchan); /* required to re-set eifs */
++/*&&&*/printk(KERN_INFO "ath5k_hamnet: set slottime ret=%i\n", ret);
++				} else { ret = -EINVAL; }
++				break;
+#endif
+			case ATH_SYSCTL_DISTANCE:
+				if (val < 0) { ret = -EINVAL; }
+				else if (ah) {
+					unsigned int coverage;
+					/* calculate distance -> coverage class */
+					/*
+					 * Divide double the distance by the speed of light in m/usec (300) to
+					 * get round-trip time in microseconds and then divide the result by
+					 * three to get coverage class as specified in IEEE 802.11-2007 table
+					 * 7-27. Values are rounded upwards.
+					 * coverage = (distance + 449) / 450;
+					 */
+					coverage = ((val + 449) / 450)+1; // +1 -> round up
+					if (coverage <= 255) {
+						ath5k_hw_set_coverage_class(ah, coverage);
+/*&&&*/printk(KERN_INFO "ath5k_hamnet: set distance: %i, coverage class=%i\n", val, ah->ah_coverage_class);
+					} else {
+						ret = -EINVAL;
+					}
+#if 0
++					/* Some magic is explained here:
++					 * http://www.air-stream.org.au/ACK_Timeouts
++					*/
++					/* distance to slottime: */
++					int c = 300;	/* Speed of light in vacuum in m/us. */ 
++					int aAirPropagationTime;
++					int defaultSlotTime=9;
++					int defaultSIFS=16;
++					int aSlotTime;
++					int timeout;
++
++					aAirPropagationTime = val * 2 / c; /* in usec */
++					aSlotTime = defaultSlotTime + aAirPropagationTime;
++
++					timeout = defaultSIFS + aSlotTime;
++
++					sc->distance = val;
++					sc->slottime = aSlotTime;
++					sc->ack_timeout = timeout;
++					sc->cts_timeout = timeout;
++
++					ret = ath5k_hw_set_slot_time(sc->ah, aSlotTime);
++/*&&&*/printk(KERN_INFO "ath5k_hamnet: set distance: ath5k_hw_set_slot_time(%u us)=%i\n", aSlotTime, ret);
++					ret = ath5k_hw_set_ack_timeout(sc->ah, timeout);
++/*&&&*/printk(KERN_INFO "ath5k_hamnet: set distance: ath5k_hw_set_ack_timeout(%u us)=%i\n", timeout, ret);
++					ret = ath5k_hw_set_cts_timeout(sc->ah, timeout);
++/*&&&*/printk(KERN_INFO "ath5k_hamnet: set distance: ath5k_hw_set_cts_timeout(%u us)=%i\n", timeout, ret);
++					if (sc->curchan) ath5k_reset(sc, sc->curchan); /* required to re-set eifs */
+#endif
+				}
+				break;
+
+			case ATH_SYSCTL_ANTSWITCHING:
+				if ( (ah) &&
+				    ((val >= 0) && (val < NUM_ANT_MODES)) ) {
+					ath5k_hw_set_antenna_mode(ah, val);
+				}
+				break;
+			case ATH_SYSCTL_NOACKS:
+				if ((val >= 0) && (val <= 1)) {
+					ah->noacks = val;
+					if (val == 1) printk(KERN_INFO "ath5k_hamnet: 802.11 L2 ACKs disabled "
+								       "- you know what you're doing, right?\n");
+				}
+				break;
+			default:
+				ret = -EINVAL;
+				break;
+			}
+		}
+	// Read access
+	} else {
+		switch ((long)ctl->extra2) {
+		case ATH_SYSCTL_CHANNELBW:
+			switch (ah->ah_bwmode) {
+				case AR5K_BWMODE_40MHZ:   val=40; break;
+				case AR5K_BWMODE_DEFAULT: val=20; break;
+				case AR5K_BWMODE_10MHZ:   val=10; break;
+				case AR5K_BWMODE_5MHZ:    val=5;  break;
+				default: val=-1;
+				}
+			break;
+#if 0
++		case ATH_SYSCTL_ACKTIMEOUT:
++			if (sc && sc->ah) {
++				val = ath5k_hw_get_ack_timeout(sc->ah);
++			} else {
++				ret=-EINVAL;
++			}
++			break;
++/*&&&*/printk(KERN_INFO "ath5k_hamnet: ath5k_hw_get_ack_timeout=%i, ret=%i\n", val, ret);
++		case ATH_SYSCTL_CTSTIMEOUT:
++			if (sc && sc->ah) {
++				val = ath5k_hw_get_cts_timeout(sc->ah);
++			} else {
++				ret=-EINVAL;
++			}
++/*&&&*/printk(KERN_INFO "ath5k_hamnet: ath5k_hw_get_cts_timeout=%i, ret=%i\n", val, ret);
++			break;
++		case ATH_SYSCTL_SLOTTIME:
++			if (sc && sc->ah) {
++				val = ath5k_hw_get_slot_time(sc->ah);
++			} else {
++				ret=-EINVAL;
++			}
++/*&&&*/printk(KERN_INFO "ath5k_hamnet: ath5k_hw_get_slot_time=%i, ret=%i\n", val, ret);
++			break;
+#endif
+		case ATH_SYSCTL_DISTANCE:
+/*&&&*/printk(KERN_INFO "ath5k_hamnet: coverage class: %i\n", ah->ah_coverage_class);
+			val = ah->ah_coverage_class; /*&&&*/
+			/*
+			 * Divide double the distance by the speed of light in m/usec (300) to
+			 * get round-trip time in microseconds and then divide the result by
+			 * three to get coverage class as specified in IEEE 802.11-2007 table
+			 * 7-27. Values are rounded upwards.
+			 *
+			 *coverage = (distance + 449) / 450;
+			 * ->
+			 * distance = (coverage *450) - 449;
+			 */
+			val = (ah->ah_coverage_class *450) - 449;
+/*&&&*/printk(KERN_INFO "ath5k_hamnet: get distance: %i\n", val);
+#if 0
++			if ((val == 0) && (sc && sc->ah)) {
++				/* in case no distance has been set, estimate from slottime... */
++				int c = 300;	/* Speed of light in vacuum in m/us. */ 
++				int defaultSlotTime=9;
++				int aAirPropagationTime;
++				int aSlotTime;
++
++				aSlotTime = ath5k_hw_get_slot_time(sc->ah);
++				aAirPropagationTime = aSlotTime - defaultSlotTime;
++				val = aAirPropagationTime / 2 * c;
++			}
+#endif
+			break;
+
+		case ATH_SYSCTL_ANTSWITCHING:
+			if (ah) {
+				int ant_mode=ah->ah_ant_mode;
+				int tx_ant=ah->ah_tx_ant;
+				int def_ant=ah->ah_def_ant;
+				char *modes[] ={
+					"[0] AR5K_ANTMODE_DEFAULT",	/* 0: default antenna setup */
+					"[1] AR5K_ANTMODE_FIXED_A",	/* 1: only antenna A is present */
+					"[2] AR5K_ANTMODE_FIXED_B",	/* 2: only antenna B is present */
+					"[3] AR5K_ANTMODE_SINGLE_AP",	/* 3: sta locked on a single ap */
+					"[4] AR5K_ANTMODE_SECTOR_AP",	/* 4: AP with tx antenna set on tx desc */
+					"[5] AR5K_ANTMODE_SECTOR_STA",	/* 5: STA with tx antenna set on tx desc */
+					"[6] AR5K_ANTMODE_DEBUG",	/* 6: Debug mode -A -> Rx, B-> Tx- */
+					};
+				snprintf(val_s, VAL_S_SIZE,
+					"Mode:   %s\n" 
+					"TX Ant: %i\n"
+					"Def Ant: %i\n",
+					(ant_mode >=0 && ant_mode < NUM_ANT_MODES) ?
+					modes[ant_mode] : "**unknown**", 
+					tx_ant,
+					def_ant
+				);
+				val_s[VAL_S_SIZE-1]='\0';
+			} else {
+				snprintf(val_s, VAL_S_SIZE,
+					"ERR: no PHY device found...\n");
+				val_s[VAL_S_SIZE-1]='\0';
+			}
+			break;
+		case ATH_SYSCTL_INFO:
+			if (ah) {
+				int channelbw;
+				char *modestring="not initialized";
+				struct ieee80211_channel *channel = ah->ah_current_channel;
+				if (channel) {
+					switch (channel->hw_value) {
+					case AR5K_MODE_11A:
+						modestring="11a";
+						break;
+					case AR5K_MODE_11G:
+						modestring="11g";
+						break;
+					case AR5K_MODE_11B:
+						modestring="11b";
+						break;
+					default:
+						modestring="unknown";
+						break;
+					}
+				}
+
+				switch (ah->ah_bwmode) {
+					case AR5K_BWMODE_40MHZ:   channelbw=40; break;
+					case AR5K_BWMODE_DEFAULT: channelbw=20; break;
+					case AR5K_BWMODE_10MHZ:   channelbw=10; break;
+					case AR5K_BWMODE_5MHZ:    channelbw=5;  break;
+					default: val=-1;
+				}
+
+				snprintf(val_s, VAL_S_SIZE,
+					"AR%s (MAC: 0x%x PHY: 0x%x) 2GHz RF%s 5GHz RF%s (single chip: %s)\n"
+					"ah->ah_version: %i %s\n"
+					"TX Pwr Lvl: %i\n"
+					"Noisefloor: %i\n"
+					"TX Ant:     %i\n"
+					"Def Ant:    %i\n"
+					"Chan BW:    %i\n"
+					"Mode:       %s\n"
+					"PLL Reg:    0x%x\n"
+					"PHY Mode:   0x%x\n"
+					"Ant Div:    %i\n"
+					"STA ID1:    0x%x\n",
+					ath5k_chip_name(AR5K_VERSION_MAC, ah->ah_mac_srev),
+					ah->ah_mac_srev,
+					ah->ah_phy_revision,
+					ath5k_chip_name(AR5K_VERSION_RAD, ah->ah_radio_2ghz_revision),
+					ath5k_chip_name(AR5K_VERSION_RAD, ah->ah_radio_5ghz_revision),
+					(ah->ah_single_chip)? "yes" : "no",
+					ah->ah_version, 
+					(ah->ah_version == 0)? "AR5K_AR5210" : 
+					(ah->ah_version == 1)? "AR5K_AR5211" : 
+					(ah->ah_version == 2)? "AR5K_AR5212" : "unknown",
+					ah->power_level,
+					ah->ah_noise_floor,
+					ah->ah_tx_ant,
+					ah->ah_def_ant,
+					channelbw,
+					modestring,
+					ath5k_hw_reg_read(ah, AR5K_PHY_PLL),
+					ath5k_hw_reg_read(ah, AR5K_PHY_MODE),
+					(ath5k_hw_reg_read(ah, AR5K_PHY_FAST_ANT_DIV)
+					   & AR5K_PHY_FAST_ANT_DIV_EN) ? 1:0,
+					ath5k_hw_reg_read(ah, AR5K_STA_ID1)
+				);
+				val_s[VAL_S_SIZE-1]='\0';
+			}
+			break;
+		case ATH_SYSCTL_REGDUMP:
+			if (ah) {
+				snprintf(val_s, VAL_S_SIZE,
+					"Register Dump (Timing related)\n\n"
+					"          sc      | current   | raw reg value\n"
+					"-----------------------------------------\n"
+/*					"SlotTime: %4i us | %4i us   | 0x%04x\n"
+					"ACK t/o:  %4i us | %4i us   | 0x%04x\n"
+					"CTS t/o:  %4i us | %4i us   | 0x%04x\n"
+*/					"EIFS:        -    | %4i us   | 0x%04x\n"
+					"ACKs:     %s\n"
+					,
+/*					sc->slottime,
+					ath5k_hw_get_slot_time(sc->ah), 
+					(sc->ah->ah_version == AR5K_AR5210) ?
+						ath5k_hw_reg_read(sc->ah, AR5K_SLOT_TIME) & 0xffff :
+						ath5k_hw_reg_read(sc->ah, AR5K_DCU_GBL_IFS_SLOT) & 0xffff,
+					sc->ack_timeout,
+					ath5k_hw_get_ack_timeout(sc->ah), 
+					AR5K_REG_MS(ath5k_hw_reg_read(sc->ah, AR5K_TIME_OUT), AR5K_TIME_OUT_ACK),
+					sc->cts_timeout,
+					ath5k_hw_get_cts_timeout(sc->ah),
+					AR5K_REG_MS(ath5k_hw_reg_read(sc->ah, AR5K_TIME_OUT), AR5K_TIME_OUT_CTS),
+*/					ath5k_hw_clocktoh(ah, ath5k_hw_reg_read(ah, AR5K_DCU_GBL_IFS_EIFS) & 0xffff),
+					ath5k_hw_reg_read(ah, AR5K_DCU_GBL_IFS_EIFS) & 0xffff,
+					(ah->noacks)? "disabled" : "enabled"
+				);
+				val_s[VAL_S_SIZE-1]='\0';
+			}
+			break;
+		case ATH_SYSCTL_NOACKS:
+			val = ah->noacks;
+			break;
+		case ATH_SYSCTL_NOISEFLOOR:
+			val = ah->ah_noise_floor;
+			break;
+		default:
+			ret = -EINVAL;
+			break;
+		}
+		/* ID > 100 operate on strings, see above */
+		if ((long)ctl->extra2 > 100) {
+			ctl->data = val_s;
+			ctl->maxlen = VAL_S_SIZE * sizeof(char);
+			ret = ATH_SYSCTL_PROC_DOSTRING(ctl, write, filp, buffer, 
+				lenp, ppos);
+		} else {
+			ctl->data = &val;
+			ctl->maxlen = sizeof(val);
+			ret = ATH_SYSCTL_PROC_DOINTVEC(ctl, write, filp, buffer, 
+				lenp, ppos);
+		}
+	}
+
+	mutex_unlock(&ah->lock);
+	return ret;
+#undef VAL_S_SIZE
+#undef NUM_ANT_MODES
+}
+
+static ctl_table ath_sysctl_table[] = {
+	{ .ctl_name	= CTL_UNNUMBERED,
+	  .procname	= "channelbw",
+	  .mode		= 0644,
+	  .proc_handler	= ath_sysctl,
+	  .extra2	= (void *)ATH_SYSCTL_CHANNELBW,
+	},
+	{ .ctl_name	= CTL_UNNUMBERED,
+	  .procname	= "ant_mode",
+	  .mode		= 0644,
+	  .proc_handler	= ath_sysctl,
+	  .extra2	= (void *)ATH_SYSCTL_ANTSWITCHING,
+	},
+	{ .ctl_name	= CTL_UNNUMBERED,
+	  .procname	= "info",
+	  .mode		= 0444,
+	  .proc_handler	= ath_sysctl,
+	  .extra2	= (void *)ATH_SYSCTL_INFO,
+	},
+#if 0
+	{ .ctl_name	= CTL_UNNUMBERED,
+	  .procname	= "ack_timeout",
+	  .mode		= 0644,
+	  .proc_handler	= ath_sysctl,
+	  .extra2	= (void *)ATH_SYSCTL_ACKTIMEOUT,
+	},
+	{ .ctl_name	= CTL_UNNUMBERED,
+	  .procname	= "cts_timeout",
+	  .mode		= 0644,
+	  .proc_handler	= ath_sysctl,
+	  .extra2	= (void *)ATH_SYSCTL_CTSTIMEOUT,
+	},
+	{ .ctl_name	= CTL_UNNUMBERED,
+	  .procname	= "slottime",
+	  .mode		= 0644,
+	  .proc_handler	= ath_sysctl,
+	  .extra2	= (void *)ATH_SYSCTL_SLOTTIME,
+	},
+#endif
+	{ .ctl_name	= CTL_UNNUMBERED,
+	  .procname	= "distance",
+	  .mode		= 0644,
+	  .proc_handler	= ath_sysctl,
+	  .extra2	= (void *)ATH_SYSCTL_DISTANCE,
+	},
+	{ .ctl_name	= CTL_UNNUMBERED,
+	  .procname	= "regdump",
+	  .mode		= 0444,
+	  .proc_handler	= ath_sysctl,
+	  .extra2	= (void *)ATH_SYSCTL_REGDUMP,
+	},
+	{ .ctl_name	= CTL_UNNUMBERED,
+	  .procname	= "use_no_acks",
+	  .mode		= 0644,
+	  .proc_handler	= ath_sysctl,
+	  .extra2	= (void *)ATH_SYSCTL_NOACKS,
+	},
+	{ .ctl_name	= CTL_UNNUMBERED,
+	  .procname	= "noisefloor",
+	  .mode		= 0444,
+	  .proc_handler	= ath_sysctl,
+	  .extra2	= (void *)ATH_SYSCTL_NOISEFLOOR,
+	},
+	{0}
+};
+
+static int register_sysctls (struct ath5k_hw *ah) {
+	unsigned int i, space;
+	char *dev_name = NULL;
+
+	ctl_table *ctl_table_hdr;
+
+	/* Prevent multiple registrations */
+	if (ah->ah_sysctls)
+		return 0;
+
+	if (!ah || !ah->hw || !ah->hw->wiphy) {
+		ATH5K_WARN(ah, "ah->hw->wiphy not defined (NULL)!\n");
+		return 0;
+	}
+
+	space = 5 * sizeof(struct ctl_table) + sizeof(ath_sysctl_table);
+	ctl_table_hdr = kzalloc(space, GFP_KERNEL);
+	if (ctl_table_hdr == NULL) {
+		ATH5K_WARN(ah, "Insufficient memory for sysctl table!\n");
+		return 0;
+	}
+
+	dev_name = kmalloc((strlen(wiphy_name(ah->hw->wiphy)) + 1)
+			   * sizeof(char), GFP_KERNEL);
+	if (dev_name == NULL) {
+		ATH5K_WARN(ah, "Insufficient memory for device name storage!\n");
+		kfree(ctl_table_hdr);
+		ctl_table_hdr = NULL;
+		return 0;
+	}
+	strncpy(dev_name, wiphy_name(ah->hw->wiphy), 
+	        strlen(wiphy_name(ah->hw->wiphy)) + 1);
+
+	/* setup the table */
+	ctl_table_hdr[0].ctl_name = CTL_DEV;
+	ctl_table_hdr[0].procname = "dev";
+	ctl_table_hdr[0].mode = 0555;
+	ctl_table_hdr[0].child = &ctl_table_hdr[2];
+	/* [1] is NULL terminator */
+	ctl_table_hdr[2].ctl_name = CTL_UNNUMBERED;
+	ctl_table_hdr[2].procname = dev_name;
+	ctl_table_hdr[2].mode = 0555;
+	ctl_table_hdr[2].child = &ctl_table_hdr[4];
+	/* [3] is NULL terminator */
+	/* copy in pre-defined data */
+	memcpy(&ctl_table_hdr[4], ath_sysctl_table, sizeof(ath_sysctl_table));
+
+	/* add in dynamic data references */
+	for (i = 4; ctl_table_hdr[i].procname; i++)
+		if (ctl_table_hdr[i].extra1 == NULL)
+			ctl_table_hdr[i].extra1 = ah;
+
+	/* and register everything */
+	ah->ah_sysctl_header = register_sysctl_table(ctl_table_hdr);
+	if (!ah->ah_sysctl_header) {
+		ATH5K_WARN(ah, "Failed to register sysctls!\n");
+		kfree(dev_name);
+		kfree(ctl_table_hdr);
+		return 0;
+	}
+
+	ah->ah_sysctls = ctl_table_hdr;
+	return 0;
+}
+
+static int unregister_sysctls (struct ath5k_hw *ah) {
+	if (ah && ah->ah_sysctl_header) {
+		unregister_sysctl_table(ah->ah_sysctl_header);
+		ah->ah_sysctl_header = NULL;
+	}
+
+	if (ah && ah->ah_sysctls ) {
+		ctl_table *ctl_table_hdr = ah->ah_sysctls;
+		if (ctl_table_hdr[2].procname) {
+			kfree(ctl_table_hdr[2].procname);
+			ctl_table_hdr[2].procname = NULL;
+		}
+		kfree(ah->ah_sysctls);
+		ah->ah_sysctls = NULL;
+	}
+
+	return 0;
+}
diff -Naur compat-wireless-2011-11-15.orig/drivers/net/wireless/ath/ath5k/base.h compat-wireless-2011-11-15/drivers/net/wireless/ath/ath5k/base.h
--- compat-wireless-2011-11-15.orig/drivers/net/wireless/ath/ath5k/base.h	2012-04-14 10:36:59.000000000 +0200
+++ compat-wireless-2011-11-15/drivers/net/wireless/ath/ath5k/base.h	2012-04-14 21:29:44.000000000 +0200
@@ -116,4 +116,34 @@
 /* Check whether virtual EOL is supported */
 #define ath5k_hw_hasveol(_ah) (ah->ah_version != AR5K_AR5210)
 
+/*&&&&&&&&&&&&&&&&&&&&&&&&&&*/
+/*
+ * Deal with the sysctl handler api changing.
+ */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,8)
+#define	ATH_SYSCTL_DECL(f, ctl, write, filp, buffer, lenp, ppos) \
+	f(ctl_table *ctl, int write, struct file *filp, \
+	  void __user *buffer, size_t *lenp)
+#define	ATH_SYSCTL_PROC_DOINTVEC(ctl, write, filp, buffer, lenp, ppos) \
+	proc_dointvec(ctl, write, filp, buffer, lenp)
+#define	ATH_SYSCTL_PROC_DOSTRING(ctl, write, filp, buffer, lenp, ppos) \
+	proc_dostring(ctl, write, filp, buffer, lenp)
+#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)
+#define	ATH_SYSCTL_DECL(f, ctl, write, filp, buffer, lenp, ppos) \
+	f(ctl_table *ctl, int write, struct file *filp, \
+	  void __user *buffer, size_t *lenp, loff_t *ppos)
+#define	ATH_SYSCTL_PROC_DOINTVEC(ctl, write, filp, buffer, lenp, ppos) \
+	proc_dointvec(ctl, write, filp, buffer, lenp, ppos)
+#define	ATH_SYSCTL_PROC_DOSTRING(ctl, write, filp, buffer, lenp, ppos) \
+	proc_dostring(ctl, write, filp, buffer, lenp, ppos)
+#else /* Linux 2.6.32+ */
+#define	ATH_SYSCTL_DECL(f, ctl, write, filp, buffer, lenp, ppos) \
+	f(ctl_table *ctl, int write, \
+	  void __user *buffer, size_t *lenp, loff_t *ppos)
+#define	ATH_SYSCTL_PROC_DOINTVEC(ctl, write, filp, buffer, lenp, ppos) \
+	proc_dointvec(ctl, write, buffer, lenp, ppos)
+#define	ATH_SYSCTL_PROC_DOSTRING(ctl, write, filp, buffer, lenp, ppos) \
+	proc_dostring(ctl, write, buffer, lenp, ppos)
+#endif
+
 #endif	/* _DEV_ATH5K_BASE_H */
diff -Naur compat-wireless-2011-11-15.orig/drivers/net/wireless/ath/ath5k/desc.h compat-wireless-2011-11-15/drivers/net/wireless/ath/ath5k/desc.h
--- compat-wireless-2011-11-15.orig/drivers/net/wireless/ath/ath5k/desc.h	2012-04-14 10:36:59.000000000 +0200
+++ compat-wireless-2011-11-15/drivers/net/wireless/ath/ath5k/desc.h	2012-04-14 21:28:12.000000000 +0200
@@ -207,7 +207,7 @@
 #define AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_IDX_S	13
 #define AR5K_4W_TX_DESC_CTL1_FRAME_TYPE		0x00f00000 /* frame type */
 #define AR5K_4W_TX_DESC_CTL1_FRAME_TYPE_S	20
-#define AR5K_4W_TX_DESC_CTL1_NOACK		0x01000000 /* no ACK */
+#define AR5K_4W_TX_DESC_CTL1_NOACK		0x01000000 /* no ACK, tells HW to not expect ACK for this frame */
 #define AR5K_4W_TX_DESC_CTL1_COMP_PROC		0x06000000 /* compression processing */
 #define AR5K_4W_TX_DESC_CTL1_COMP_PROC_S	25
 #define AR5K_4W_TX_DESC_CTL1_COMP_IV_LEN	0x18000000 /* length of frame IV */
diff -Naur compat-wireless-2011-11-15.orig/drivers/net/wireless/ath/ath5k/reset.c compat-wireless-2011-11-15/drivers/net/wireless/ath/ath5k/reset.c
--- compat-wireless-2011-11-15.orig/drivers/net/wireless/ath/ath5k/reset.c	2012-04-14 10:36:59.000000000 +0200
+++ compat-wireless-2011-11-15/drivers/net/wireless/ath/ath5k/reset.c	2012-04-15 11:32:50.000000000 +0200
@@ -1237,6 +1237,16 @@
 	/* Ledstate */
 	AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, s_led[0]);
 
+	/* Hack to disable L2 ACKs */
+	if ( (ah->ah_version == AR5K_AR5211) ||
+	     (ah->ah_version == AR5K_AR5212) )  { /* currently on 5211 & 5212 only... */
+		if (ah->noacks) {
+			AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_ACK);
+		} else {
+			AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_ACK);
+		}
+	}
+
 	/* Gpio settings */
 	ath5k_hw_reg_write(ah, s_led[1], AR5K_GPIOCR);
 	ath5k_hw_reg_write(ah, s_led[2], AR5K_GPIODO);
diff -Naur compat-wireless-2011-11-15.orig/net/mac80211/rx.c compat-wireless-2011-11-15/net/mac80211/rx.c
--- compat-wireless-2011-11-15.orig/net/mac80211/rx.c	2012-04-14 10:36:59.000000000 +0200
+++ compat-wireless-2011-11-15/net/mac80211/rx.c	2012-05-12 16:16:09.000000000 +0200
@@ -182,6 +182,20 @@
 		pos++;
 	}
 
+#if 0
+// status->noise field has been optimized away :-(
+/*&&& hb9xar: Adding noise floor to radiotap header has been optimized
+              away. Until I know why and what is the proper way  to get
+              it back we do  it this way. */
+	/* IEEE80211_RADIOTAP_DBM_ANTNOISE */
+	if (local->hw.flags & IEEE80211_HW_NOISE_DBM) {
+		*pos = status->noise;
+		rthdr->it_present |=
+			cpu_to_le32(1 << IEEE80211_RADIOTAP_DBM_ANTNOISE );
+		pos++;
+	}
+#endif
+
 	/* IEEE80211_RADIOTAP_LOCK_QUALITY is missing */
 
 	/* IEEE80211_RADIOTAP_ANTENNA */
