Currently mesh uses mandatory rates as the default basic rates. Allow basic
rates to be configured during mesh join.

Signed-off-by: Ashok Nagarajan <[email protected]>
---
 include/net/cfg80211.h |    2 ++
 net/mac80211/cfg.c     |    2 ++
 net/mac80211/mesh.c    |    4 ----
 net/wireless/mesh.c    |   11 +++++++++++
 net/wireless/nl80211.c |   43 +++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 58 insertions(+), 4 deletions(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index fcb7764..06780d1 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1155,6 +1155,7 @@ struct mesh_config {
  * @dtim_period: DTIM period to use
  * @beacon_interval: beacon interval to use
  * @mcast_rate: multicat rate for Mesh Node [6Mbps is the default for 802.11a]
+ * @basic_rates: per-band bitmap of basic rates to use when creating the mesh
  *
  * These parameters are fixed when the mesh is created.
  */
@@ -1173,6 +1174,7 @@ struct mesh_setup {
        u8 dtim_period;
        u16 beacon_interval;
        int mcast_rate[IEEE80211_NUM_BANDS];
+       u32 basic_rates[IEEE80211_NUM_BANDS];
 };
 
 /**
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 1a89c80..2d4131f 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1744,6 +1744,8 @@ static int copy_mesh_setup(struct ieee80211_if_mesh 
*ifmsh,
        /* mcast rate setting in Mesh Node */
        memcpy(sdata->vif.bss_conf.mcast_rate, setup->mcast_rate,
                                                sizeof(setup->mcast_rate));
+       sdata->vif.bss_conf.basic_rates =
+                               setup->basic_rates[setup->chandef.chan->band];
 
        sdata->vif.bss_conf.beacon_int = setup->beacon_interval;
        sdata->vif.bss_conf.dtim_period = setup->dtim_period;
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 5a37f95..7e4fce9 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -740,9 +740,6 @@ int ieee80211_start_mesh(struct ieee80211_sub_if_data 
*sdata)
                      BSS_CHANGED_HT |
                      BSS_CHANGED_BASIC_RATES |
                      BSS_CHANGED_BEACON_INT;
-       enum ieee80211_band band = ieee80211_get_sdata_band(sdata);
-       struct ieee80211_supported_band *sband =
-                                       sdata->local->hw.wiphy->bands[band];
 
        local->fif_other_bss++;
        /* mesh ifaces must set allmulti to forward mcast traffic */
@@ -761,7 +758,6 @@ int ieee80211_start_mesh(struct ieee80211_sub_if_data 
*sdata)
        sdata->vif.bss_conf.ht_operation_mode =
                                ifmsh->mshcfg.ht_opmode;
        sdata->vif.bss_conf.enable_beacon = true;
-       sdata->vif.bss_conf.basic_rates = ieee80211_mandatory_rates(sband);
 
        changed |= ieee80211_mps_local_status_update(sdata);
 
diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c
index 0bb93f3..9133942 100644
--- a/net/wireless/mesh.c
+++ b/net/wireless/mesh.c
@@ -159,6 +159,17 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device 
*rdev,
                setup->chandef.center_freq1 = setup->chandef.chan->center_freq;
        }
 
+       /*
+        * we now know the operating band, so check if basic rates are
+        * available for this band otherwise use mandatory rates as basic rates
+        */
+       if (!setup->basic_rates[setup->chandef.chan->band]) {
+               enum ieee80211_band band = setup->chandef.chan->band;
+               struct ieee80211_supported_band *sband =
+                                                       rdev->wiphy.bands[band];
+               setup->basic_rates[band] = ieee80211_mandatory_rates(sband);
+       }
+
        if (!cfg80211_reg_can_beacon(&rdev->wiphy, &setup->chandef))
                return -EINVAL;
 
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index afa2838..65a1e95 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -6232,6 +6232,33 @@ nl80211_parse_mcast_rate(struct 
cfg80211_registered_device *rdev,
        return found;
 }
 
+static int nl80211_parse_basic_rates(struct cfg80211_registered_device *rdev,
+                                    const u8 *rates, unsigned int n_rates,
+                                    u32 mask[IEEE80211_NUM_BANDS])
+{
+       struct wiphy *wiphy = &rdev->wiphy;
+       bool found = false;
+       int band, err;
+       struct ieee80211_supported_band *sband;
+
+       for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
+               err = 0;
+               sband = wiphy->bands[band];
+
+               if (!sband)
+                       continue;
+
+               err = ieee80211_get_ratemask(sband, rates, n_rates,
+                                            &mask[band]);
+               if (!err)
+                       found = true;
+       }
+
+       if (!found)
+               return -EINVAL;
+       return 0;
+}
+
 static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
 {
        struct cfg80211_registered_device *rdev = info->user_ptr[0];
@@ -7460,6 +7487,22 @@ static int nl80211_join_mesh(struct sk_buff *skb, struct 
genl_info *info)
                            nla_get_u32(info->attrs[NL80211_ATTR_MCAST_RATE])))
                        return -EINVAL;
 
+       if (info->attrs[NL80211_ATTR_BSS_BASIC_RATES]) {
+               u8 *rates = nla_data(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
+               int n_rates =
+                            nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
+
+               /*
+                * since we may or may not have an operating band yet, verify
+                * given basic rates are supported for all available bands
+                */
+
+               err = nl80211_parse_basic_rates(rdev, rates, n_rates,
+                                               setup.basic_rates);
+               if (err)
+                       return err;
+       }
+
        if (info->attrs[NL80211_ATTR_BEACON_INTERVAL]) {
                setup.beacon_interval =
                        nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
-- 
1.7.5.4

_______________________________________________
Devel mailing list
[email protected]
http://lists.open80211s.org/cgi-bin/mailman/listinfo/devel

Reply via email to