mac80211: refactor ieee80211_ibss_process_chanswitch()
authorLuciano Coelho <luciano.coelho@intel.com>
Fri, 13 Dec 2013 19:13:50 +0000 (21:13 +0200)
committerJohannes Berg <johannes.berg@intel.com>
Mon, 16 Dec 2013 14:07:46 +0000 (15:07 +0100)
Refactor ieee80211_ibss_process_chanswitch() to use
ieee80211_channel_switch() and avoid code duplication.

Tested by: Simon Wunderlich <sw@simonwunderlich.de>
Acked by: Simon Wunderlich <sw@simonwunderlich.de>
Signed-off-by: Luciano Coelho <luciano.coelho@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
net/mac80211/cfg.c
net/mac80211/ibss.c
net/mac80211/ieee80211_i.h

index df32df3..35bb71b 100644 (file)
@@ -3038,8 +3038,8 @@ unlock:
        sdata_unlock(sdata);
 }
 
-static int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
-                                   struct cfg80211_csa_settings *params)
+int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
+                            struct cfg80211_csa_settings *params)
 {
        struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
        struct ieee80211_local *local = sdata->local;
index a6ca56d..5ad3183 100644 (file)
@@ -788,18 +788,10 @@ ieee80211_ibss_process_chanswitch(struct ieee80211_sub_if_data *sdata,
        struct cfg80211_csa_settings params;
        struct ieee80211_csa_ie csa_ie;
        struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
-       struct ieee80211_chanctx_conf *chanctx_conf;
-       struct ieee80211_chanctx *chanctx;
        enum nl80211_channel_type ch_type;
-       int err, num_chanctx;
+       int err;
        u32 sta_flags;
 
-       if (sdata->vif.csa_active)
-               return true;
-
-       if (!sdata->vif.bss_conf.ibss_joined)
-               return false;
-
        sta_flags = IEEE80211_STA_DISABLE_VHT;
        switch (ifibss->chandef.width) {
        case NL80211_CHAN_WIDTH_5:
@@ -834,9 +826,6 @@ ieee80211_ibss_process_chanswitch(struct ieee80211_sub_if_data *sdata,
        params.count = csa_ie.count;
        params.chandef = csa_ie.chandef;
 
-       if (ifibss->chandef.chan->band != params.chandef.chan->band)
-               goto disconnect;
-
        switch (ifibss->chandef.width) {
        case NL80211_CHAN_WIDTH_20_NOHT:
        case NL80211_CHAN_WIDTH_20:
@@ -892,28 +881,12 @@ ieee80211_ibss_process_chanswitch(struct ieee80211_sub_if_data *sdata,
                params.radar_required = true;
        }
 
-       rcu_read_lock();
-       chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
-       if (!chanctx_conf) {
-               rcu_read_unlock();
-               goto disconnect;
-       }
-
-       /* don't handle for multi-VIF cases */
-       chanctx = container_of(chanctx_conf, struct ieee80211_chanctx, conf);
-       if (chanctx->refcount > 1) {
-               rcu_read_unlock();
-               goto disconnect;
-       }
-       num_chanctx = 0;
-       list_for_each_entry_rcu(chanctx, &sdata->local->chanctx_list, list)
-               num_chanctx++;
-
-       if (num_chanctx > 1) {
-               rcu_read_unlock();
-               goto disconnect;
+       if (cfg80211_chandef_identical(&params.chandef,
+                                      &sdata->vif.bss_conf.chandef)) {
+               ibss_dbg(sdata,
+                        "received csa with an identical chandef, ignoring\n");
+               return true;
        }
-       rcu_read_unlock();
 
        /* all checks done, now perform the channel switch. */
        ibss_dbg(sdata,
@@ -922,19 +895,9 @@ ieee80211_ibss_process_chanswitch(struct ieee80211_sub_if_data *sdata,
 
        params.block_tx = !!csa_ie.mode;
 
-       ieee80211_ibss_csa_beacon(sdata, &params);
-       sdata->csa_radar_required = params.radar_required;
-
-       if (params.block_tx)
-               ieee80211_stop_queues_by_reason(&sdata->local->hw,
-                               IEEE80211_MAX_QUEUE_MAP,
-                               IEEE80211_QUEUE_STOP_REASON_CSA);
-
-       sdata->csa_chandef = params.chandef;
-       sdata->vif.csa_active = true;
-
-       ieee80211_bss_info_change_notify(sdata, err);
-       drv_channel_switch_beacon(sdata, &params.chandef);
+       if (ieee80211_channel_switch(sdata->local->hw.wiphy, sdata->dev,
+                                    &params))
+               goto disconnect;
 
        ieee80211_ibss_csa_mark_radar(sdata);
 
@@ -970,7 +933,8 @@ ieee80211_rx_mgmt_spectrum_mgmt(struct ieee80211_sub_if_data *sdata,
        if (len < required_len)
                return;
 
-       ieee80211_ibss_process_chanswitch(sdata, elems, false);
+       if (!sdata->vif.csa_active)
+               ieee80211_ibss_process_chanswitch(sdata, elems, false);
 }
 
 static void ieee80211_rx_mgmt_deauth_ibss(struct ieee80211_sub_if_data *sdata,
@@ -1151,7 +1115,8 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
                goto put_bss;
 
        /* process channel switch */
-       if (ieee80211_ibss_process_chanswitch(sdata, elems, true))
+       if (sdata->vif.csa_active ||
+           ieee80211_ibss_process_chanswitch(sdata, elems, true))
                goto put_bss;
 
        /* same BSSID */
index adbff71..fb5dbcb 100644 (file)
@@ -1450,6 +1450,8 @@ void ieee80211_handle_roc_started(struct ieee80211_roc_work *roc);
 
 /* channel switch handling */
 void ieee80211_csa_finalize_work(struct work_struct *work);
+int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
+                            struct cfg80211_csa_settings *params);
 
 /* interface handling */
 int ieee80211_iface_init(void);