--- a/ath/if_ath.c
+++ b/ath/if_ath.c
@@ -10476,11 +10476,11 @@ set_node_txpower(void *arg, struct ieee8
  * XXX: this function needs some locking to avoid being called 
  * twice/interrupted. Returns the value actually stored. */
 static u_int32_t
-ath_set_clamped_maxtxpower(struct ath_softc *sc, 
-		u_int32_t new_clamped_maxtxpower)
+ath_set_clamped_maxtxpower(struct ath_softc *sc, u_int32_t new_txpwr)
 {
-	new_clamped_maxtxpower -= sc->sc_poweroffset;
-	(void)ath_hal_settxpowlimit(sc->sc_ah, new_clamped_maxtxpower);
+	new_txpwr = ((new_txpwr < sc->sc_poweroffset) ? 0 :
+		new_txpwr - sc->sc_poweroffset);
+	(void)ath_hal_settxpowlimit(sc->sc_ah, new_txpwr);
 	return ath_get_clamped_maxtxpower(sc);
 }
 
@@ -11031,6 +11031,7 @@ enum {
 	ATH_DEBUG,
 	ATH_TXANTENNA,
 	ATH_RXANTENNA,
+	ATH_POWEROFFSET,
 	ATH_DIVERSITY,
 	ATH_TXINTRPERIOD,
 	ATH_FFTXQMIN,
@@ -11311,6 +11312,9 @@ ATH_SYSCTL_DECL(ath_sysctl_halparam, ctl
 				ath_debug_global = (val &  ATH_DEBUG_GLOBAL);
 #endif
 				break;
+			case ATH_POWEROFFSET:
+				sc->sc_poweroffset = val;
+				break;
 			case ATH_TXANTENNA:
 				/*
 				 * antenna can be:
@@ -11478,6 +11482,9 @@ ATH_SYSCTL_DECL(ath_sysctl_halparam, ctl
 		case ATH_DEBUG:
 			val = sc->sc_debug | ath_debug_global;
 			break;
+		case ATH_POWEROFFSET:
+			val = sc->sc_poweroffset;
+			break;
 		case ATH_TXANTENNA:
 			val = sc->sc_txantenna;
 			break;
@@ -11619,6 +11626,12 @@ static const ctl_table ath_sysctl_templa
 	},
 #endif
 	{ .ctl_name	= CTL_AUTO,
+	  .procname	= "poweroffset",
+	  .mode		= 0644,
+	  .proc_handler	= ath_sysctl_halparam,
+	  .extra2	= (void *)ATH_POWEROFFSET,
+	},
+	{ .ctl_name	= CTL_AUTO,
 	  .procname	= "txantenna",
 	  .mode		= 0644,
 	  .proc_handler	= ath_sysctl_halparam,