mac80211: refactor the parsing of chan switch ie
authorChun-Yeow Yeoh <yeohchunyeow@cozybit.com>
Tue, 15 Oct 2013 02:08:29 +0000 (19:08 -0700)
committerJohannes Berg <johannes.berg@intel.com>
Mon, 28 Oct 2013 14:05:28 +0000 (15:05 +0100)
Refactor the channel switch IE parsing to reduce the number
of function parameters.

Signed-off-by: Chun-Yeow Yeoh <yeohchunyeow@cozybit.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
net/mac80211/ibss.c
net/mac80211/ieee80211_i.h
net/mac80211/mlme.c
net/mac80211/spectmgmt.c

index 275bbb2..a0ae027 100644 (file)
@@ -836,13 +836,13 @@ ieee80211_ibss_process_chanswitch(struct ieee80211_sub_if_data *sdata,
                                  bool beacon)
 {
        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;
        u32 sta_flags;
-       u8 mode;
 
        if (sdata->vif.csa_active)
                return true;
@@ -865,12 +865,10 @@ ieee80211_ibss_process_chanswitch(struct ieee80211_sub_if_data *sdata,
        }
 
        memset(&params, 0, sizeof(params));
+       memset(&csa_ie, 0, sizeof(csa_ie));
        err = ieee80211_parse_ch_switch_ie(sdata, elems, beacon,
                                           ifibss->chandef.chan->band,
-                                          sta_flags, ifibss->bssid,
-                                          &params.count, &mode,
-                                          &params.chandef);
-
+                                          sta_flags, ifibss->bssid, &csa_ie);
        /* can't switch to destination channel, fail */
        if (err < 0)
                goto disconnect;
@@ -879,6 +877,9 @@ ieee80211_ibss_process_chanswitch(struct ieee80211_sub_if_data *sdata,
        if (err)
                return false;
 
+       params.count = csa_ie.count;
+       params.chandef = csa_ie.chandef;
+
        if (ifibss->chandef.chan->band != params.chandef.chan->band)
                goto disconnect;
 
@@ -965,7 +966,7 @@ ieee80211_ibss_process_chanswitch(struct ieee80211_sub_if_data *sdata,
                 "received channel switch announcement to go to channel %d MHz\n",
                 params.chandef.chan->center_freq);
 
-       params.block_tx = !!mode;
+       params.block_tx = !!csa_ie.mode;
 
        ieee80211_ibss_csa_beacon(sdata, &params);
        sdata->csa_radar_required = params.radar_required;
index ff3c310..cbaea32 100644 (file)
@@ -1208,6 +1208,14 @@ struct ieee80211_ra_tid {
        u16 tid;
 };
 
+/* this struct holds the value parsing from channel switch IE  */
+struct ieee80211_csa_ie {
+       struct cfg80211_chan_def chandef;
+       u8 mode;
+       u8 count;
+       u8 ttl;
+};
+
 /* Parsed Information Elements */
 struct ieee802_11_elems {
        const u8 *ie_start;
@@ -1505,17 +1513,16 @@ void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata,
  *     %IEEE80211_STA_DISABLE_HT, %IEEE80211_STA_DISABLE_VHT,
  *     %IEEE80211_STA_DISABLE_40MHZ, %IEEE80211_STA_DISABLE_80P80MHZ,
  *     %IEEE80211_STA_DISABLE_160MHZ.
- * @count: to be filled with the counter until the switch (on success only)
  * @bssid: the currently connected bssid (for reporting)
- * @mode: to be filled with CSA mode (on success only)
- * @new_chandef: to be filled with destination chandef (on success only)
+ * @csa_ie: parsed 802.11 csa elements on count, mode, chandef and mesh ttl.
+       All of them will be filled with if success only.
  * Return: 0 on success, <0 on error and >0 if there is nothing to parse.
  */
 int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata,
                                 struct ieee802_11_elems *elems, bool beacon,
                                 enum ieee80211_band current_band,
-                                u32 sta_flags, u8 *bssid, u8 *count, u8 *mode,
-                                struct cfg80211_chan_def *new_chandef);
+                                u32 sta_flags, u8 *bssid,
+                                struct ieee80211_csa_ie *csa_ie);
 
 /* Suspend/resume and hw reconfiguration */
 int ieee80211_reconfig(struct ieee80211_local *local);
index 5cc1c27..1305ff9 100644 (file)
@@ -958,9 +958,7 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
        struct cfg80211_bss *cbss = ifmgd->associated;
        struct ieee80211_chanctx *chanctx;
        enum ieee80211_band current_band;
-       u8 count;
-       u8 mode;
-       struct cfg80211_chan_def new_chandef = {};
+       struct ieee80211_csa_ie csa_ie;
        int res;
 
        sdata_assert_lock(sdata);
@@ -976,24 +974,24 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
                return;
 
        current_band = cbss->channel->band;
+       memset(&csa_ie, 0, sizeof(csa_ie));
        res = ieee80211_parse_ch_switch_ie(sdata, elems, beacon, current_band,
                                           ifmgd->flags,
-                                          ifmgd->associated->bssid, &count,
-                                          &mode, &new_chandef);
+                                          ifmgd->associated->bssid, &csa_ie);
        if (res < 0)
                ieee80211_queue_work(&local->hw,
                                     &ifmgd->csa_connection_drop_work);
        if (res)
                return;
 
-       if (!cfg80211_chandef_usable(local->hw.wiphy, &new_chandef,
+       if (!cfg80211_chandef_usable(local->hw.wiphy, &csa_ie.chandef,
                                     IEEE80211_CHAN_DISABLED)) {
                sdata_info(sdata,
                           "AP %pM switches to unsupported channel (%d MHz, width:%d, CF1/2: %d/%d MHz), disconnecting\n",
                           ifmgd->associated->bssid,
-                          new_chandef.chan->center_freq,
-                          new_chandef.width, new_chandef.center_freq1,
-                          new_chandef.center_freq2);
+                          csa_ie.chandef.chan->center_freq,
+                          csa_ie.chandef.width, csa_ie.chandef.center_freq1,
+                          csa_ie.chandef.center_freq2);
                ieee80211_queue_work(&local->hw,
                                     &ifmgd->csa_connection_drop_work);
                return;
@@ -1037,9 +1035,9 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
        }
        mutex_unlock(&local->chanctx_mtx);
 
-       local->csa_chandef = new_chandef;
+       local->csa_chandef = csa_ie.chandef;
 
-       if (mode)
+       if (csa_ie.mode)
                ieee80211_stop_queues_by_reason(&local->hw,
                                IEEE80211_MAX_QUEUE_MAP,
                                IEEE80211_QUEUE_STOP_REASON_CSA);
@@ -1048,9 +1046,9 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
                /* use driver's channel switch callback */
                struct ieee80211_channel_switch ch_switch = {
                        .timestamp = timestamp,
-                       .block_tx = mode,
-                       .chandef = new_chandef,
-                       .count = count,
+                       .block_tx = csa_ie.mode,
+                       .chandef = csa_ie.chandef,
+                       .count = csa_ie.count,
                };
 
                drv_channel_switch(local, &ch_switch);
@@ -1058,11 +1056,11 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
        }
 
        /* channel switch handled in software */
-       if (count <= 1)
+       if (csa_ie.count <= 1)
                ieee80211_queue_work(&local->hw, &ifmgd->chswitch_work);
        else
                mod_timer(&ifmgd->chswitch_timer,
-                         TU_TO_EXP_TIME(count * cbss->beacon_interval));
+                         TU_TO_EXP_TIME(csa_ie.count * cbss->beacon_interval));
 }
 
 static u32 ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata,
@@ -3994,7 +3992,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
        }
 
        /* prepare assoc data */
-       
+
        ifmgd->beacon_crc_valid = false;
 
        /*
index 921597e..a298e12 100644 (file)
@@ -24,8 +24,8 @@
 int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata,
                                 struct ieee802_11_elems *elems, bool beacon,
                                 enum ieee80211_band current_band,
-                                u32 sta_flags, u8 *bssid, u8 *count, u8 *mode,
-                                struct cfg80211_chan_def *new_chandef)
+                                u32 sta_flags, u8 *bssid,
+                                struct ieee80211_csa_ie *csa_ie)
 {
        enum ieee80211_band new_band;
        int new_freq;
@@ -62,13 +62,13 @@ int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata,
                        return -EINVAL;
                }
                new_chan_no = elems->ext_chansw_ie->new_ch_num;
-               *count = elems->ext_chansw_ie->count;
-               *mode = elems->ext_chansw_ie->mode;
+               csa_ie->count = elems->ext_chansw_ie->count;
+               csa_ie->mode = elems->ext_chansw_ie->mode;
        } else if (elems->ch_switch_ie) {
                new_band = current_band;
                new_chan_no = elems->ch_switch_ie->new_ch_num;
-               *count = elems->ch_switch_ie->count;
-               *mode = elems->ch_switch_ie->mode;
+               csa_ie->count = elems->ch_switch_ie->count;
+               csa_ie->mode = elems->ch_switch_ie->mode;
        } else {
                /* nothing here we understand */
                return 1;
@@ -103,25 +103,26 @@ int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata,
        default:
                /* secondary_channel_offset was present but is invalid */
        case IEEE80211_HT_PARAM_CHA_SEC_NONE:
-               cfg80211_chandef_create(new_chandef, new_chan,
+               cfg80211_chandef_create(&csa_ie->chandef, new_chan,
                                        NL80211_CHAN_HT20);
                break;
        case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
-               cfg80211_chandef_create(new_chandef, new_chan,
+               cfg80211_chandef_create(&csa_ie->chandef, new_chan,
                                        NL80211_CHAN_HT40PLUS);
                break;
        case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
-               cfg80211_chandef_create(new_chandef, new_chan,
+               cfg80211_chandef_create(&csa_ie->chandef, new_chan,
                                        NL80211_CHAN_HT40MINUS);
                break;
        case -1:
-               cfg80211_chandef_create(new_chandef, new_chan,
+               cfg80211_chandef_create(&csa_ie->chandef, new_chan,
                                        NL80211_CHAN_NO_HT);
                /* keep width for 5/10 MHz channels */
                switch (sdata->vif.bss_conf.chandef.width) {
                case NL80211_CHAN_WIDTH_5:
                case NL80211_CHAN_WIDTH_10:
-                       new_chandef->width = sdata->vif.bss_conf.chandef.width;
+                       csa_ie->chandef.width =
+                               sdata->vif.bss_conf.chandef.width;
                        break;
                default:
                        break;
@@ -171,13 +172,13 @@ int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata,
        /* if VHT data is there validate & use it */
        if (new_vht_chandef.chan) {
                if (!cfg80211_chandef_compatible(&new_vht_chandef,
-                                                new_chandef)) {
+                                                &csa_ie->chandef)) {
                        sdata_info(sdata,
                                   "BSS %pM: CSA has inconsistent channel data, disconnecting\n",
                                   bssid);
                        return -EINVAL;
                }
-               *new_chandef = new_vht_chandef;
+               csa_ie->chandef = new_vht_chandef;
        }
 
        return 0;