---- 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);
- }