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: Eliad Peller <eliad@wizery.com> Signed-off-by: Arik Nemtsov <arik@wizery.com> Signed-off-by: Luciano Coelho <coelho@ti.com>
This commit is contained in:
parent
de40750f4b
commit
426001a6aa
2 changed files with 49 additions and 0 deletions
|
@ -4486,6 +4486,45 @@ static int wl12xx_sta_remove(struct wl1271 *wl,
|
|||
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,
|
||||
struct wl12xx_vif *wlvif,
|
||||
struct ieee80211_sta *sta,
|
||||
|
@ -4508,6 +4547,8 @@ static int wl12xx_update_sta_state(struct wl1271 *wl,
|
|||
ret = wl12xx_sta_add(wl, wlvif, sta);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
wlcore_update_inconn_sta(wl, wlvif, wl_sta, true);
|
||||
}
|
||||
|
||||
/* Remove station (AP mode) */
|
||||
|
@ -4516,6 +4557,8 @@ static int wl12xx_update_sta_state(struct wl1271 *wl,
|
|||
new_state == IEEE80211_STA_NOTEXIST) {
|
||||
/* must not fail */
|
||||
wl12xx_sta_remove(wl, wlvif, sta);
|
||||
|
||||
wlcore_update_inconn_sta(wl, wlvif, wl_sta, false);
|
||||
}
|
||||
|
||||
/* Authorize station (AP mode) */
|
||||
|
@ -4529,6 +4572,8 @@ static int wl12xx_update_sta_state(struct wl1271 *wl,
|
|||
hlid);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
wlcore_update_inconn_sta(wl, wlvif, wl_sta, false);
|
||||
}
|
||||
|
||||
/* Authorize station */
|
||||
|
|
|
@ -315,6 +315,7 @@ struct wl12xx_rx_filter {
|
|||
|
||||
struct wl1271_station {
|
||||
u8 hlid;
|
||||
bool in_connection;
|
||||
};
|
||||
|
||||
struct wl12xx_vif {
|
||||
|
@ -425,6 +426,9 @@ struct wl12xx_vif {
|
|||
struct delayed_work channel_switch_work;
|
||||
struct delayed_work connection_loss_work;
|
||||
|
||||
/* number of in connection stations */
|
||||
int inconn_count;
|
||||
|
||||
/*
|
||||
* This struct must be last!
|
||||
* data that has to be saved acrossed reconfigs (e.g. recovery)
|
||||
|
|
Loading…
Reference in a new issue