2013-05-11 00:51:04

by Ashok Nagarajan

[permalink] [raw]
Subject: [PATCH 1/3] {cfg,mac}80211: move mandatory rates calculation to cfg80211

Move mandatory rates calculation to cfg80211, shared with non mac80211 drivers.

Signed-off-by: Ashok Nagarajan <[email protected]>
---
include/net/cfg80211.h | 8 ++++++++
net/mac80211/ibss.c | 10 +++++++---
net/mac80211/ieee80211_i.h | 3 ---
net/mac80211/mesh.c | 5 +++--
net/mac80211/util.c | 26 --------------------------
net/wireless/util.c | 23 +++++++++++++++++++++++
6 files changed, 41 insertions(+), 34 deletions(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 26b5b69..fcb7764 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -2989,6 +2989,14 @@ struct ieee80211_rate *
ieee80211_get_response_rate(struct ieee80211_supported_band *sband,
u32 basic_rates, int bitrate);

+/**
+ * ieee80211_mandatory_rates - get mandatory rates for a given band
+ * @sband: the band to look for rates in
+ *
+ * This function returns the mandatory rates for the given band
+ */
+u32 ieee80211_mandatory_rates(struct ieee80211_supported_band *sband);
+
/*
* Radiotap parsing functions -- for controlled injection support
*
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 170f9a7..956ba63 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -341,6 +341,7 @@ ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
struct ieee80211_local *local = sdata->local;
struct sta_info *sta;
struct ieee80211_chanctx_conf *chanctx_conf;
+ struct ieee80211_supported_band *sband;
int band;

/*
@@ -380,8 +381,9 @@ ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
sta->last_rx = jiffies;

/* make sure mandatory rates are always added */
+ sband = local->hw.wiphy->bands[band];
sta->sta.supp_rates[band] = supp_rates |
- ieee80211_mandatory_rates(local, band);
+ ieee80211_mandatory_rates(sband);

return ieee80211_ibss_finish_sta(sta, auth);
}
@@ -492,7 +494,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
prev_rates = sta->sta.supp_rates[band];
/* make sure mandatory rates are always added */
sta->sta.supp_rates[band] = supp_rates |
- ieee80211_mandatory_rates(local, band);
+ ieee80211_mandatory_rates(sband);

if (sta->sta.supp_rates[band] != prev_rates) {
ibss_dbg(sdata,
@@ -624,6 +626,7 @@ void ieee80211_ibss_rx_no_sta(struct ieee80211_sub_if_data *sdata,
struct ieee80211_local *local = sdata->local;
struct sta_info *sta;
struct ieee80211_chanctx_conf *chanctx_conf;
+ struct ieee80211_supported_band *sband;
int band;

/*
@@ -658,8 +661,9 @@ void ieee80211_ibss_rx_no_sta(struct ieee80211_sub_if_data *sdata,
sta->last_rx = jiffies;

/* make sure mandatory rates are always added */
+ sband = local->hw.wiphy->bands[band];
sta->sta.supp_rates[band] = supp_rates |
- ieee80211_mandatory_rates(local, band);
+ ieee80211_mandatory_rates(sband);

spin_lock(&ifibss->incomplete_lock);
list_add(&sta->list, &ifibss->incomplete_stations);
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 158e6eb..b7cbd4e 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1505,9 +1505,6 @@ static inline void ieee802_11_parse_elems(u8 *start, size_t len, bool action,
ieee802_11_parse_elems_crc(start, len, action, elems, 0, 0);
}

-u32 ieee80211_mandatory_rates(struct ieee80211_local *local,
- enum ieee80211_band band);
-
void ieee80211_dynamic_ps_enable_work(struct work_struct *work);
void ieee80211_dynamic_ps_disable_work(struct work_struct *work);
void ieee80211_dynamic_ps_timer(unsigned long data);
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 6952760..5a37f95 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -741,6 +741,8 @@ int ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)
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 */
@@ -759,8 +761,7 @@ 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(local, band);
+ sdata->vif.bss_conf.basic_rates = ieee80211_mandatory_rates(sband);

changed |= ieee80211_mps_local_status_update(sdata);

diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 3f87fa4..707953f 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1072,32 +1072,6 @@ void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata,
ieee80211_set_wmm_default(sdata, true);
}

-u32 ieee80211_mandatory_rates(struct ieee80211_local *local,
- enum ieee80211_band band)
-{
- struct ieee80211_supported_band *sband;
- struct ieee80211_rate *bitrates;
- u32 mandatory_rates;
- enum ieee80211_rate_flags mandatory_flag;
- int i;
-
- sband = local->hw.wiphy->bands[band];
- if (WARN_ON(!sband))
- return 1;
-
- if (band == IEEE80211_BAND_2GHZ)
- mandatory_flag = IEEE80211_RATE_MANDATORY_B;
- else
- mandatory_flag = IEEE80211_RATE_MANDATORY_A;
-
- bitrates = sband->bitrates;
- mandatory_rates = 0;
- for (i = 0; i < sband->n_bitrates; i++)
- if (bitrates[i].flags & mandatory_flag)
- mandatory_rates |= BIT(i);
- return mandatory_rates;
-}
-
void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
u16 transaction, u16 auth_alg, u16 status,
const u8 *extra, size_t extra_len, const u8 *da,
diff --git a/net/wireless/util.c b/net/wireless/util.c
index a7046a4..d6727f2 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -33,6 +33,29 @@ ieee80211_get_response_rate(struct ieee80211_supported_band *sband,
}
EXPORT_SYMBOL(ieee80211_get_response_rate);

+u32 ieee80211_mandatory_rates(struct ieee80211_supported_band *sband)
+{
+ struct ieee80211_rate *bitrates;
+ u32 mandatory_rates = 0;
+ enum ieee80211_rate_flags mandatory_flag;
+ int i;
+
+ if (WARN_ON(!sband))
+ return 1;
+
+ if (sband->band == IEEE80211_BAND_2GHZ)
+ mandatory_flag = IEEE80211_RATE_MANDATORY_B;
+ else
+ mandatory_flag = IEEE80211_RATE_MANDATORY_A;
+
+ bitrates = sband->bitrates;
+ for (i = 0; i < sband->n_bitrates; i++)
+ if (bitrates[i].flags & mandatory_flag)
+ mandatory_rates |= BIT(i);
+ return mandatory_rates;
+}
+EXPORT_SYMBOL(ieee80211_mandatory_rates);
+
int ieee80211_channel_to_frequency(int chan, enum ieee80211_band band)
{
/* see 802.11 17.3.8.3.2 and Annex J
--
1.7.5.4



2013-05-24 21:56:48

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH 1/3] {cfg,mac}80211: move mandatory rates calculation to cfg80211

On Fri, 2013-05-10 at 17:50 -0700, Ashok Nagarajan wrote:
> Move mandatory rates calculation to cfg80211, shared with non mac80211 drivers.

Applied.

johannes


2013-05-13 17:20:50

by Ashok Nagarajan

[permalink] [raw]
Subject: Re: [PATCH 2/3] cfg80211: Allow ieee80211g mandatory rate sets in 2.4GHz band

On Mon, May 13, 2013 at 10:18 AM, Johannes Berg
<[email protected]> wrote:
> On Mon, 2013-05-13 at 10:13 -0700, Ashok Nagarajan wrote:
>> On Mon, May 13, 2013 at 2:42 AM, Johannes Berg
>> <[email protected]> wrote:
>> > On Fri, 2013-05-10 at 17:50 -0700, Ashok Nagarajan wrote:
>> >> This patch assumes 11g support
>> >> implies a 11g operation and returns the appropriate mandatory rates.
>> >
>> > Which is a problem, because it means that by default we'll create IBSS
>> > networks that are not compatible with 11b devices.
>>
>> Okay make sense. I would drop just this patch and send rest.
>
> If you just want the others as is I can do that, no need to resend. Let
> me know.
>
Yes, the rest would be as it is now. That would work.

Thanks,
Ashok
> johannes
>



--
Ashok Raj Nagarajan,
cozybit Inc.
http://www.cozybit.com

2013-05-11 00:51:07

by Ashok Nagarajan

[permalink] [raw]
Subject: [PATCH 3/3] {nl,mac,cfg}80211: Allow user to configure basic rates for mesh

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


2013-05-13 17:18:26

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH 2/3] cfg80211: Allow ieee80211g mandatory rate sets in 2.4GHz band

On Mon, 2013-05-13 at 10:13 -0700, Ashok Nagarajan wrote:
> On Mon, May 13, 2013 at 2:42 AM, Johannes Berg
> <[email protected]> wrote:
> > On Fri, 2013-05-10 at 17:50 -0700, Ashok Nagarajan wrote:
> >> This patch assumes 11g support
> >> implies a 11g operation and returns the appropriate mandatory rates.
> >
> > Which is a problem, because it means that by default we'll create IBSS
> > networks that are not compatible with 11b devices.
>
> Okay make sense. I would drop just this patch and send rest.

If you just want the others as is I can do that, no need to resend. Let
me know.

johannes


2013-05-13 17:13:27

by Ashok Nagarajan

[permalink] [raw]
Subject: Re: [PATCH 2/3] cfg80211: Allow ieee80211g mandatory rate sets in 2.4GHz band

On Mon, May 13, 2013 at 2:42 AM, Johannes Berg
<[email protected]> wrote:
> On Fri, 2013-05-10 at 17:50 -0700, Ashok Nagarajan wrote:
>> This patch assumes 11g support
>> implies a 11g operation and returns the appropriate mandatory rates.
>
> Which is a problem, because it means that by default we'll create IBSS
> networks that are not compatible with 11b devices.

Okay make sense. I would drop just this patch and send rest.

Thanks,
Ashok
>
> johannes
>



--
Ashok Raj Nagarajan,
cozybit Inc.
http://www.cozybit.com

2013-05-11 00:51:05

by Ashok Nagarajan

[permalink] [raw]
Subject: [PATCH 2/3] cfg80211: Allow ieee80211g mandatory rate sets in 2.4GHz band

With the current logic of ieee80211_mandatory_rates(), only 11b mandatory rates
are returned when operating in 2.4GHz band. 802.11g mandatory rates are not
fetched even if the operating mode is 11g. This patch assumes 11g support
implies a 11g operation and returns the appropriate mandatory rates.

Signed-off-by: Ashok Nagarajan <[email protected]>
---
net/wireless/util.c | 15 +++++++++++----
1 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/net/wireless/util.c b/net/wireless/util.c
index d6727f2..d4e3dfa 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -43,12 +43,19 @@ u32 ieee80211_mandatory_rates(struct ieee80211_supported_band *sband)
if (WARN_ON(!sband))
return 1;

- if (sband->band == IEEE80211_BAND_2GHZ)
- mandatory_flag = IEEE80211_RATE_MANDATORY_B;
- else
+ bitrates = sband->bitrates;
+ if (sband->band == IEEE80211_BAND_5GHZ)
mandatory_flag = IEEE80211_RATE_MANDATORY_A;
+ else {
+ mandatory_flag = IEEE80211_RATE_MANDATORY_B;
+ for (i = 0; i < sband->n_bitrates; i++)
+ if (bitrates[i].bitrate > 110) {
+ mandatory_flag =
+ IEEE80211_RATE_MANDATORY_G;
+ break;
+ }
+ }

- bitrates = sband->bitrates;
for (i = 0; i < sband->n_bitrates; i++)
if (bitrates[i].flags & mandatory_flag)
mandatory_rates |= BIT(i);
--
1.7.5.4


2013-05-13 09:42:44

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH 2/3] cfg80211: Allow ieee80211g mandatory rate sets in 2.4GHz band

On Fri, 2013-05-10 at 17:50 -0700, Ashok Nagarajan wrote:
> This patch assumes 11g support
> implies a 11g operation and returns the appropriate mandatory rates.

Which is a problem, because it means that by default we'll create IBSS
networks that are not compatible with 11b devices.

johannes


2013-05-25 08:20:57

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH 3/3] {nl,mac,cfg}80211: Allow user to configure basic rates for mesh


> > I think you should consider allowing this attribute only if the channel
> > is also specified (NL80211_ATTR_WIPHY_FREQ, parsed below), and not make
> > it nested with rates for both bands but just the selected band.
> >
> Yes, I think by this approach, we eliminate the need for the user to
> provide rates for both bands and also not require to have a per-band
> for basic_rates.
>
> Said that, I am wondering why give mcast_rate for both bands, but
> basic_rates only for one band?

Heh, good question. I think it was probably copied from IBSS where you
can pick another channel? Doesn't make all that much sense for mesh I
guess, unless MBSS channel switch could cause us to use another channel?
But then presumably you should follow the basic rates from the STA
initiating the switch, or something, since mesh networks are only
compatible with the same basic rates, right?

johannes


2013-05-24 23:14:05

by Ashok Nagarajan

[permalink] [raw]
Subject: Re: [PATCH 3/3] {nl,mac,cfg}80211: Allow user to configure basic rates for mesh

Hi Johannes,

On Fri, May 24, 2013 at 2:59 PM, Johannes Berg
<[email protected]> wrote:
> Sorry for leaving this open for so long. I think it didn't hurt since
> the merge window was open anyway.
>
>> + * @basic_rates: per-band bitmap of basic rates to use when creating the mesh
>
> Does per-band really make sense? The mesh channel is also determined at
> join time.
>
>> 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]) {
>
> I think you should consider allowing this attribute only if the channel
> is also specified (NL80211_ATTR_WIPHY_FREQ, parsed below), and not make
> it nested with rates for both bands but just the selected band.
>
Yes, I think by this approach, we eliminate the need for the user to
provide rates for both bands and also not require to have a per-band
for basic_rates.

Said that, I am wondering why give mcast_rate for both bands, but
basic_rates only for one band?
> johannes
>



--
Ashok Raj Nagarajan,
cozybit Inc.
http://www.cozybit.com

2013-05-30 16:47:31

by Ashok Nagarajan

[permalink] [raw]
Subject: Re: [PATCH 3/3] {nl,mac,cfg}80211: Allow user to configure basic rates for mesh

On Sat, May 25, 2013 at 1:20 AM, Johannes Berg
<[email protected]> wrote:
>
>> > I think you should consider allowing this attribute only if the channel
>> > is also specified (NL80211_ATTR_WIPHY_FREQ, parsed below), and not make
>> > it nested with rates for both bands but just the selected band.
>> >
>> Yes, I think by this approach, we eliminate the need for the user to
>> provide rates for both bands and also not require to have a per-band
>> for basic_rates.
>>
>> Said that, I am wondering why give mcast_rate for both bands, but
>> basic_rates only for one band?
>
> Heh, good question. I think it was probably copied from IBSS where you
> can pick another channel? Doesn't make all that much sense for mesh I
> guess, unless MBSS channel switch could cause us to use another channel?
> But then presumably you should follow the basic rates from the STA
> initiating the switch, or something, since mesh networks are only
> compatible with the same basic rates, right?
>

Yes, that is right. I will come up with a patch now for basic_rates
configuration as per your suggestion.

Thanks,
Ashok
> johannes
>



--
Ashok Raj Nagarajan,
cozybit Inc.
http://www.cozybit.com

2013-05-24 21:59:02

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH 3/3] {nl,mac,cfg}80211: Allow user to configure basic rates for mesh

Sorry for leaving this open for so long. I think it didn't hurt since
the merge window was open anyway.

> + * @basic_rates: per-band bitmap of basic rates to use when creating the mesh

Does per-band really make sense? The mesh channel is also determined at
join time.

> 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]) {

I think you should consider allowing this attribute only if the channel
is also specified (NL80211_ATTR_WIPHY_FREQ, parsed below), and not make
it nested with rates for both bands but just the selected band.

johannes