Add an optional threshold for low-rssi disconnection. This can be useful when letting wpa_supplicant control roaming. Signed-off-by: Felix Fietkau --- a/net80211/ieee80211_ioctl.h +++ b/net80211/ieee80211_ioctl.h @@ -656,6 +656,8 @@ IEEE80211_PARAM_PROTMODE_RSSI = 85, /* RSSI Threshold for enabling protection mode */ IEEE80211_PARAM_PROTMODE_TIMEOUT = 86, /* Timeout for expiring protection mode */ IEEE80211_PARAM_BGSCAN_THRESH = 87, /* bg scan rssi threshold */ + IEEE80211_PARAM_RSSI_DIS_THR = 88, /* rssi threshold for disconnection */ + IEEE80211_PARAM_RSSI_DIS_COUNT = 89, /* counter for rssi threshold */ }; #define SIOCG80211STATS (SIOCDEVPRIVATE+2) --- a/net80211/ieee80211_wireless.c +++ b/net80211/ieee80211_wireless.c @@ -2832,6 +2832,12 @@ case IEEE80211_PARAM_ROAM_RATE_11G: vap->iv_roam.rate11g = value; break; + case IEEE80211_PARAM_RSSI_DIS_THR: + vap->iv_rssi_dis_thr = value; + break; + case IEEE80211_PARAM_RSSI_DIS_COUNT: + vap->iv_rssi_dis_max = value; + break; case IEEE80211_PARAM_UAPSDINFO: if (vap->iv_opmode == IEEE80211_M_HOSTAP) { if (ic->ic_caps & IEEE80211_C_UAPSD) { @@ -3220,6 +3226,12 @@ case IEEE80211_PARAM_ROAM_RATE_11G: param[0] = vap->iv_roam.rate11g; break; + case IEEE80211_PARAM_RSSI_DIS_THR: + param[0] = vap->iv_rssi_dis_thr; + break; + case IEEE80211_PARAM_RSSI_DIS_COUNT: + param[0] = vap->iv_rssi_dis_max; + break; case IEEE80211_PARAM_UAPSDINFO: if (vap->iv_opmode == IEEE80211_M_HOSTAP) { if (IEEE80211_VAP_UAPSD_ENABLED(vap)) @@ -5770,6 +5782,14 @@ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rate11g_x2" }, { IEEE80211_PARAM_ROAM_RATE_11G, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_rate11g_x2" }, + { IEEE80211_PARAM_RSSI_DIS_THR, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rssi_disthr" }, + { IEEE80211_PARAM_RSSI_DIS_THR, + 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_rssi_disthr" }, + { IEEE80211_PARAM_RSSI_DIS_COUNT, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rssi_discnt" }, + { IEEE80211_PARAM_RSSI_DIS_COUNT, + 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_rssi_discnt" }, { IEEE80211_PARAM_UAPSDINFO, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "uapsd" }, { IEEE80211_PARAM_UAPSDINFO, --- a/net80211/ieee80211_input.c +++ b/net80211/ieee80211_input.c @@ -3234,6 +3234,17 @@ /* When rssi is low, start doing bgscans more frequently to allow * the supplicant to make a better switching decision */ + if ((vap->iv_rssi_dis_thr > 0) && (vap->iv_rssi_dis_max > 0)) { + if ((rssi > 0) && (rssi < vap->iv_rssi_dis_thr)) { + if (++vap->iv_rssi_dis_trig > vap->iv_rssi_dis_max) { + vap->iv_rssi_dis_trig = 0; + ieee80211_node_leave(ni); + return 0; + } + } else { + vap->iv_rssi_dis_trig = 0; + } + } if ((rssi < vap->iv_bgscanthr) && (!vap->iv_bgscanthr_next || !time_before(jiffies, vap->iv_bgscanthr_next)) && --- a/net80211/ieee80211_var.h +++ b/net80211/ieee80211_var.h @@ -233,6 +233,9 @@ u_int iv_bgscanintvl; /* bg scan min interval */ u_int iv_bgscanthr; /* bg scan rssi threshold */ u_int iv_bgscantrintvl; /* bg scan trigger interval */ + u_int iv_rssi_dis_thr; /* rssi disassoc threshold */ + u_int iv_rssi_dis_max; /* max beacons below disconnect threshold */ + u_int iv_rssi_dis_trig; /* rssi disassoc trigger count */ unsigned long iv_bgscanthr_next; /* last trigger for bgscan */ u_int iv_scanvalid; /* scan cache valid threshold */ struct ieee80211_roam iv_roam; /* sta-mode roaming state */