summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEliad Peller <eliad@wizery.com>2012-11-26 16:05:45 (GMT)
committerLuciano Coelho <coelho@ti.com>2012-12-04 14:36:07 (GMT)
commit426001a6aaffce040226a19ad2795ac26c10f942 (patch)
tree73d9dc25a5b7070c9af86faf6e2dc3c9c5eccc79
parentde40750f4b10aa236ae44a9a3f10f50998e1c345 (diff)
downloadlinux-426001a6aaffce040226a19ad2795ac26c10f942.tar.xz
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>
-rw-r--r--drivers/net/wireless/ti/wlcore/main.c45
-rw-r--r--drivers/net/wireless/ti/wlcore/wlcore_i.h4
2 files changed, 49 insertions, 0 deletions
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index 4bdf3d7..99ac6c5 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -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 */
diff --git a/drivers/net/wireless/ti/wlcore/wlcore_i.h b/drivers/net/wireless/ti/wlcore/wlcore_i.h
index e3a77aa..5a92cb2 100644
--- a/drivers/net/wireless/ti/wlcore/wlcore_i.h
+++ b/drivers/net/wireless/ti/wlcore/wlcore_i.h
@@ -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)