--- a/net80211/ieee80211.c
+++ b/net80211/ieee80211.c
@@ -347,7 +347,9 @@
 			IEEE80211_MS_TO_TU(IEEE80211_BMISSTHRESH_DEFAULT_MS), 
 			ic->ic_lintval), ic->ic_lintval);
 	}
-		
+	ic->ic_protmode_timeout = IEEE80211_PROTMODE_TIMEOUT;
+	ic->ic_protmode_rssi = IEEE80211_PROTMODE_RSSITHR;
+
 	IEEE80211_LOCK_INIT(ic, "ieee80211com");
 	IEEE80211_VAPS_LOCK_INIT(ic, "ieee80211com_vaps");
 	TAILQ_INIT(&ic->ic_vaps);
--- a/net80211/ieee80211_input.c
+++ b/net80211/ieee80211_input.c
@@ -3382,14 +3382,18 @@
 			IEEE80211_IS_CHAN_ANYG(ic->ic_curchan)) {
 
 			/* Assume no ERP IE == 11b AP */
-			if ((!has_erp || (has_erp && (scan.erp & IEEE80211_ERP_NON_ERP_PRESENT))) &&
-				!(ic->ic_flags & IEEE80211_F_USEPROT)) {
+			if ((!has_erp || (has_erp &&
+				(scan.erp & IEEE80211_ERP_NON_ERP_PRESENT))) &&
+				(rssi > ic->ic_protmode_rssi)) {
 				struct ieee80211vap *tmpvap;
 
-				ic->ic_flags |= IEEE80211_F_USEPROT;
-				TAILQ_FOREACH(tmpvap, &ic->ic_vaps, iv_next) {
-					tmpvap->iv_flags_ext |= IEEE80211_FEXT_ERPUPDATE;
+				if (!(ic->ic_flags & IEEE80211_F_USEPROT)) {
+					ic->ic_flags |= IEEE80211_F_USEPROT;
+					TAILQ_FOREACH(tmpvap, &ic->ic_vaps, iv_next) {
+						tmpvap->iv_flags_ext |= IEEE80211_FEXT_ERPUPDATE;
+					}
 				}
+				ic->ic_protmode_lasttrig = jiffies;
 			}
 		}
 
--- a/net80211/ieee80211_ioctl.h
+++ b/net80211/ieee80211_ioctl.h
@@ -652,6 +652,8 @@
 	IEEE80211_PARAM_LEAKTXBUFS		= 82,	/* Leak tx buffers */
 	IEEE80211_PARAM_MAXRATE			= 83,	/* Maximum rate (by table index) */
 	IEEE80211_PARAM_MINRATE			= 84,	/* Minimum rate (by table index) */
+	IEEE80211_PARAM_PROTMODE_RSSI		= 85,	/* RSSI Threshold for enabling protection mode */
+	IEEE80211_PARAM_PROTMODE_TIMEOUT	= 86,	/* Timeout for expiring protection mode */
 };
 
 #define	SIOCG80211STATS			(SIOCDEVPRIVATE+2)
--- a/net80211/ieee80211_var.h
+++ b/net80211/ieee80211_var.h
@@ -138,6 +138,9 @@
 
 #define	IEEE80211_APPIE_MAX	1024
 
+#define IEEE80211_PROTMODE_RSSITHR	15	/* default rssi threshold for protection mode trigger */
+#define IEEE80211_PROTMODE_TIMEOUT	30	/* timeout for keeping protection mode alive */
+
 #define IEEE80211_PWRCONSTRAINT_VAL(ic) \
 	(((ic)->ic_bsschan->ic_maxregpower > (ic)->ic_curchanmaxpwr) ? \
 	    (ic)->ic_bsschan->ic_maxregpower - (ic)->ic_curchanmaxpwr : 0)
@@ -335,6 +338,9 @@
 	u_int16_t ic_newtxpowlimit; 		/* tx power limit to change to (in 0.5 dBm) */
 	u_int16_t ic_uapsdmaxtriggers; 		/* max triggers that could arrive */
 	u_int8_t ic_coverageclass; 		/* coverage class */
+	u_int8_t ic_protmode_rssi;			/* rssi threshold for protection mode */
+	u_int64_t ic_protmode_lasttrig;		/* last trigger for protection mode */
+	u_int16_t ic_protmode_timeout;		/* protection mode timeout */
 
 	/* Channel state:
 	 *
--- a/net80211/ieee80211_wireless.c
+++ b/net80211/ieee80211_wireless.c
@@ -2336,6 +2336,12 @@
 	case IEEE80211_PARAM_RSSI_EWMA:
 		ic->ic_rssi_ewma = value;
 		break;
+	case IEEE80211_PARAM_PROTMODE_TIMEOUT:
+		ic->ic_protmode_timeout = value;
+		break;
+	case IEEE80211_PARAM_PROTMODE_RSSI:
+		ic->ic_protmode_rssi = value;
+		break;
 	case IEEE80211_PARAM_MCASTCIPHER:
 		if ((vap->iv_caps & cipher2cap(value)) == 0 &&
 		    !ieee80211_crypto_available(vap, value))
@@ -2992,6 +2998,12 @@
 	case IEEE80211_PARAM_RSSI_EWMA:
 		param[0] = ic->ic_rssi_ewma;
 		break;
+	case IEEE80211_PARAM_PROTMODE_TIMEOUT:
+		param[0] = ic->ic_protmode_timeout;
+		break;
+	case IEEE80211_PARAM_PROTMODE_RSSI:
+		param[0] = ic->ic_protmode_rssi;
+		break;
 	case IEEE80211_PARAM_MCASTCIPHER:
 		param[0] = rsn->rsn_mcastcipher;
 		break;
@@ -5384,6 +5396,14 @@
 	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "protmode" },
 	{ IEEE80211_PARAM_PROTMODE,
 	  0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_protmode" },
+	{ IEEE80211_PARAM_PROTMODE_RSSI,
+	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "protrssi" },
+	{ IEEE80211_PARAM_PROTMODE_RSSI,
+	  0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_protrssi" },
+	{ IEEE80211_PARAM_PROTMODE_TIMEOUT,
+	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "prottime" },
+	{ IEEE80211_PARAM_PROTMODE_TIMEOUT,
+	  0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_prottime" },
 	{ IEEE80211_PARAM_MCASTCIPHER,
 	  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "mcastcipher" },
 	{ IEEE80211_PARAM_MCASTCIPHER,
--- a/net80211/ieee80211_node.c
+++ b/net80211/ieee80211_node.c
@@ -1591,6 +1591,17 @@
 
 	ieee80211_scan_timeout(ic);
 	ieee80211_timeout_stations(&ic->ic_sta);
+	if ((ic->ic_flags & IEEE80211_F_USEPROT) &&
+		(ic->ic_protmode_lasttrig + ic->ic_protmode_timeout * HZ <
+			jiffies)) {
+		struct ieee80211vap *tmpvap;
+
+		/* expire protection mode */
+		ic->ic_flags &= ~IEEE80211_F_USEPROT;
+		TAILQ_FOREACH(tmpvap, &ic->ic_vaps, iv_next) {
+			tmpvap->iv_flags_ext |= IEEE80211_FEXT_ERPUPDATE;
+		}
+	}
 
 	mod_timer(&ic->ic_inact, jiffies + IEEE80211_INACT_WAIT * HZ);
 }
