Commit 9fd6f21b authored by Eliad Peller's avatar Eliad Peller Committed by Luciano Coelho

wl12xx: set authorized AP on sta_state notification

wl12xx currently looks for AP authorization by registering
a netdev notifier and waiting for the IF_OPER_UP notification,
which is quite cumbersome.

Use the newly introduced sta_state callback (waiting
for assoc -> auth notification) instead, in order to
simplify it.
Signed-off-by: default avatarEliad Peller <eliad@wizery.com>
Signed-off-by: default avatarLuciano Coelho <coelho@ti.com>
parent 2d6cf2b5
...@@ -392,15 +392,15 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl, ...@@ -392,15 +392,15 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl,
static void wl1271_op_stop(struct ieee80211_hw *hw); static void wl1271_op_stop(struct ieee80211_hw *hw);
static void wl1271_free_ap_keys(struct wl1271 *wl, struct wl12xx_vif *wlvif); static void wl1271_free_ap_keys(struct wl1271 *wl, struct wl12xx_vif *wlvif);
static DEFINE_MUTEX(wl_list_mutex); static int wl12xx_set_authorized(struct wl1271 *wl,
static LIST_HEAD(wl_list); struct wl12xx_vif *wlvif)
static int wl1271_check_operstate(struct wl1271 *wl, struct wl12xx_vif *wlvif,
unsigned char operstate)
{ {
int ret; int ret;
if (operstate != IF_OPER_UP) if (WARN_ON(wlvif->bss_type != BSS_TYPE_STA_BSS))
return -EINVAL;
if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
return 0; return 0;
if (test_and_set_bit(WLVIF_FLAG_STA_STATE_SENT, &wlvif->flags)) if (test_and_set_bit(WLVIF_FLAG_STA_STATE_SENT, &wlvif->flags))
...@@ -415,76 +415,6 @@ static int wl1271_check_operstate(struct wl1271 *wl, struct wl12xx_vif *wlvif, ...@@ -415,76 +415,6 @@ static int wl1271_check_operstate(struct wl1271 *wl, struct wl12xx_vif *wlvif,
wl1271_info("Association completed."); wl1271_info("Association completed.");
return 0; return 0;
} }
static int wl1271_dev_notify(struct notifier_block *me, unsigned long what,
void *arg)
{
struct net_device *dev = arg;
struct wireless_dev *wdev;
struct wiphy *wiphy;
struct ieee80211_hw *hw;
struct wl1271 *wl;
struct wl1271 *wl_temp;
struct wl12xx_vif *wlvif;
int ret = 0;
/* Check that this notification is for us. */
if (what != NETDEV_CHANGE)
return NOTIFY_DONE;
wdev = dev->ieee80211_ptr;
if (wdev == NULL)
return NOTIFY_DONE;
wiphy = wdev->wiphy;
if (wiphy == NULL)
return NOTIFY_DONE;
hw = wiphy_priv(wiphy);
if (hw == NULL)
return NOTIFY_DONE;
wl_temp = hw->priv;
mutex_lock(&wl_list_mutex);
list_for_each_entry(wl, &wl_list, list) {
if (wl == wl_temp)
break;
}
mutex_unlock(&wl_list_mutex);
if (wl != wl_temp)
return NOTIFY_DONE;
mutex_lock(&wl->mutex);
if (wl->state == WL1271_STATE_OFF)
goto out;
if (dev->operstate != IF_OPER_UP)
goto out;
/*
* The correct behavior should be just getting the appropriate wlvif
* from the given dev, but currently we don't have a mac80211
* interface for it.
*/
wl12xx_for_each_wlvif_sta(wl, wlvif) {
struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
continue;
ret = wl1271_ps_elp_wakeup(wl);
if (ret < 0)
goto out;
wl1271_check_operstate(wl, wlvif,
ieee80211_get_operstate(vif));
wl1271_ps_elp_sleep(wl);
}
out:
mutex_unlock(&wl->mutex);
return NOTIFY_OK;
}
static int wl1271_reg_notify(struct wiphy *wiphy, static int wl1271_reg_notify(struct wiphy *wiphy,
struct regulatory_request *request) struct regulatory_request *request)
...@@ -1626,10 +1556,6 @@ static struct sk_buff *wl12xx_alloc_dummy_packet(struct wl1271 *wl) ...@@ -1626,10 +1556,6 @@ static struct sk_buff *wl12xx_alloc_dummy_packet(struct wl1271 *wl)
} }
static struct notifier_block wl1271_dev_notifier = {
.notifier_call = wl1271_dev_notify,
};
#ifdef CONFIG_PM #ifdef CONFIG_PM
static int wl1271_configure_suspend_sta(struct wl1271 *wl, static int wl1271_configure_suspend_sta(struct wl1271 *wl,
struct wl12xx_vif *wlvif) struct wl12xx_vif *wlvif)
...@@ -1856,10 +1782,6 @@ static void wl1271_op_stop(struct ieee80211_hw *hw) ...@@ -1856,10 +1782,6 @@ static void wl1271_op_stop(struct ieee80211_hw *hw)
wl->state = WL1271_STATE_OFF; wl->state = WL1271_STATE_OFF;
mutex_unlock(&wl->mutex); mutex_unlock(&wl->mutex);
mutex_lock(&wl_list_mutex);
list_del(&wl->list);
mutex_unlock(&wl_list_mutex);
wl1271_flush_deferred_work(wl); wl1271_flush_deferred_work(wl);
cancel_delayed_work_sync(&wl->scan_complete_work); cancel_delayed_work_sync(&wl->scan_complete_work);
cancel_work_sync(&wl->netstack_work); cancel_work_sync(&wl->netstack_work);
...@@ -2270,11 +2192,6 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw, ...@@ -2270,11 +2192,6 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw,
out_unlock: out_unlock:
mutex_unlock(&wl->mutex); mutex_unlock(&wl->mutex);
mutex_lock(&wl_list_mutex);
if (!ret)
list_add(&wl->list, &wl_list);
mutex_unlock(&wl_list_mutex);
return ret; return ret;
} }
...@@ -3967,8 +3884,8 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl, ...@@ -3967,8 +3884,8 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
if (ret < 0) if (ret < 0)
goto out; goto out;
wl1271_check_operstate(wl, wlvif, if (test_bit(WLVIF_FLAG_STA_AUTHORIZED, &wlvif->flags))
ieee80211_get_operstate(vif)); wl12xx_set_authorized(wl, wlvif);
} }
/* /*
* stop device role if started (we might already be in * stop device role if started (we might already be in
...@@ -4321,6 +4238,20 @@ static int wl12xx_update_sta_state(struct wl1271 *wl, ...@@ -4321,6 +4238,20 @@ static int wl12xx_update_sta_state(struct wl1271 *wl,
return ret; return ret;
} }
/* Authorize station */
if (is_sta &&
new_state == IEEE80211_STA_AUTHORIZED) {
set_bit(WLVIF_FLAG_STA_AUTHORIZED, &wlvif->flags);
return wl12xx_set_authorized(wl, wlvif);
}
if (is_sta &&
old_state == IEEE80211_STA_AUTHORIZED &&
new_state == IEEE80211_STA_ASSOC) {
clear_bit(WLVIF_FLAG_STA_AUTHORIZED, &wlvif->flags);
return 0;
}
return 0; return 0;
} }
...@@ -5144,8 +5075,6 @@ static int wl1271_register_hw(struct wl1271 *wl) ...@@ -5144,8 +5075,6 @@ static int wl1271_register_hw(struct wl1271 *wl)
wl1271_debugfs_init(wl); wl1271_debugfs_init(wl);
register_netdevice_notifier(&wl1271_dev_notifier);
wl1271_notice("loaded"); wl1271_notice("loaded");
out: out:
...@@ -5157,7 +5086,6 @@ static void wl1271_unregister_hw(struct wl1271 *wl) ...@@ -5157,7 +5086,6 @@ static void wl1271_unregister_hw(struct wl1271 *wl)
if (wl->plt) if (wl->plt)
wl1271_plt_stop(wl); wl1271_plt_stop(wl);
unregister_netdevice_notifier(&wl1271_dev_notifier);
ieee80211_unregister_hw(wl->hw); ieee80211_unregister_hw(wl->hw);
wl->mac80211_registered = false; wl->mac80211_registered = false;
...@@ -5278,7 +5206,6 @@ static struct ieee80211_hw *wl1271_alloc_hw(void) ...@@ -5278,7 +5206,6 @@ static struct ieee80211_hw *wl1271_alloc_hw(void)
wl = hw->priv; wl = hw->priv;
memset(wl, 0, sizeof(*wl)); memset(wl, 0, sizeof(*wl));
INIT_LIST_HEAD(&wl->list);
INIT_LIST_HEAD(&wl->wlvif_list); INIT_LIST_HEAD(&wl->wlvif_list);
wl->hw = hw; wl->hw = hw;
......
...@@ -265,6 +265,7 @@ enum wl12xx_flags { ...@@ -265,6 +265,7 @@ enum wl12xx_flags {
enum wl12xx_vif_flags { enum wl12xx_vif_flags {
WLVIF_FLAG_INITIALIZED, WLVIF_FLAG_INITIALIZED,
WLVIF_FLAG_STA_ASSOCIATED, WLVIF_FLAG_STA_ASSOCIATED,
WLVIF_FLAG_STA_AUTHORIZED,
WLVIF_FLAG_IBSS_JOINED, WLVIF_FLAG_IBSS_JOINED,
WLVIF_FLAG_AP_STARTED, WLVIF_FLAG_AP_STARTED,
WLVIF_FLAG_IN_PS, WLVIF_FLAG_IN_PS,
...@@ -452,8 +453,6 @@ struct wl1271 { ...@@ -452,8 +453,6 @@ struct wl1271 {
bool enable_11a; bool enable_11a;
struct list_head list;
/* Most recently reported noise in dBm */ /* Most recently reported noise in dBm */
s8 noise; s8 noise;
......
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