Commit 426001a6 authored by Eliad Peller's avatar Eliad Peller Committed by Luciano Coelho

wlcore: use sta_state-based ROCs for AP mode

Try an opportunistic ROC when a STA is first added and stop the ROC when
the STA is removed or successfully authenticated. This would ensure we
don't miss auth/assoc/EAPOL packets during connection
Signed-off-by: default avatarEliad Peller <eliad@wizery.com>
Signed-off-by: default avatarArik Nemtsov <arik@wizery.com>
Signed-off-by: default avatarLuciano Coelho <coelho@ti.com>
parent de40750f
...@@ -4486,6 +4486,45 @@ static int wl12xx_sta_remove(struct wl1271 *wl, ...@@ -4486,6 +4486,45 @@ static int wl12xx_sta_remove(struct wl1271 *wl,
return ret; return ret;
} }
static void wlcore_roc_if_possible(struct wl1271 *wl,
struct wl12xx_vif *wlvif)
{
if (find_first_bit(wl->roc_map,
WL12XX_MAX_ROLES) < WL12XX_MAX_ROLES)
return;
if (WARN_ON(wlvif->role_id == WL12XX_INVALID_ROLE_ID))
return;
wl12xx_roc(wl, wlvif, wlvif->role_id, wlvif->band, wlvif->channel);
}
static void wlcore_update_inconn_sta(struct wl1271 *wl,
struct wl12xx_vif *wlvif,
struct wl1271_station *wl_sta,
bool in_connection)
{
if (in_connection) {
if (WARN_ON(wl_sta->in_connection))
return;
wl_sta->in_connection = true;
if (!wlvif->inconn_count++)
wlcore_roc_if_possible(wl, wlvif);
} else {
if (!wl_sta->in_connection)
return;
wl_sta->in_connection = false;
wlvif->inconn_count--;
if (WARN_ON(wlvif->inconn_count < 0))
return;
if (!wlvif->inconn_count)
if (test_bit(wlvif->role_id, wl->roc_map))
wl12xx_croc(wl, wlvif->role_id);
}
}
static int wl12xx_update_sta_state(struct wl1271 *wl, static int wl12xx_update_sta_state(struct wl1271 *wl,
struct wl12xx_vif *wlvif, struct wl12xx_vif *wlvif,
struct ieee80211_sta *sta, struct ieee80211_sta *sta,
...@@ -4508,6 +4547,8 @@ static int wl12xx_update_sta_state(struct wl1271 *wl, ...@@ -4508,6 +4547,8 @@ static int wl12xx_update_sta_state(struct wl1271 *wl,
ret = wl12xx_sta_add(wl, wlvif, sta); ret = wl12xx_sta_add(wl, wlvif, sta);
if (ret) if (ret)
return ret; return ret;
wlcore_update_inconn_sta(wl, wlvif, wl_sta, true);
} }
/* Remove station (AP mode) */ /* Remove station (AP mode) */
...@@ -4516,6 +4557,8 @@ static int wl12xx_update_sta_state(struct wl1271 *wl, ...@@ -4516,6 +4557,8 @@ static int wl12xx_update_sta_state(struct wl1271 *wl,
new_state == IEEE80211_STA_NOTEXIST) { new_state == IEEE80211_STA_NOTEXIST) {
/* must not fail */ /* must not fail */
wl12xx_sta_remove(wl, wlvif, sta); wl12xx_sta_remove(wl, wlvif, sta);
wlcore_update_inconn_sta(wl, wlvif, wl_sta, false);
} }
/* Authorize station (AP mode) */ /* Authorize station (AP mode) */
...@@ -4529,6 +4572,8 @@ static int wl12xx_update_sta_state(struct wl1271 *wl, ...@@ -4529,6 +4572,8 @@ static int wl12xx_update_sta_state(struct wl1271 *wl,
hlid); hlid);
if (ret) if (ret)
return ret; return ret;
wlcore_update_inconn_sta(wl, wlvif, wl_sta, false);
} }
/* Authorize station */ /* Authorize station */
......
...@@ -315,6 +315,7 @@ struct wl12xx_rx_filter { ...@@ -315,6 +315,7 @@ struct wl12xx_rx_filter {
struct wl1271_station { struct wl1271_station {
u8 hlid; u8 hlid;
bool in_connection;
}; };
struct wl12xx_vif { struct wl12xx_vif {
...@@ -425,6 +426,9 @@ struct wl12xx_vif { ...@@ -425,6 +426,9 @@ struct wl12xx_vif {
struct delayed_work channel_switch_work; struct delayed_work channel_switch_work;
struct delayed_work connection_loss_work; struct delayed_work connection_loss_work;
/* number of in connection stations */
int inconn_count;
/* /*
* This struct must be last! * This struct must be last!
* data that has to be saved acrossed reconfigs (e.g. recovery) * data that has to be saved acrossed reconfigs (e.g. recovery)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment