2012-03-29 23:28:56

by Ashok Nagarajan

[permalink] [raw]
Subject: [PATCH 1/4] mac80211: Use mandatory rates as basic rates when starting mesh


Signed-off-by: Ashok Nagarajan <[email protected]>
Signed-off-by: Thomas Pedersen <[email protected]>
---
net/mac80211/mesh.c | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 1f82c61..56ec79d 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -579,8 +579,12 @@ void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)
ieee80211_mesh_root_setup(ifmsh);
ieee80211_queue_work(&local->hw, &sdata->work);
sdata->vif.bss_conf.beacon_int = MESH_DEFAULT_BEACON_INTERVAL;
+ sdata->vif.bss_conf.basic_rates =
+ ieee80211_mandatory_rates(sdata->local,
+ sdata->local->hw.conf.channel->band);
ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON |
BSS_CHANGED_BEACON_ENABLED |
+ BSS_CHANGED_BASIC_RATES |
BSS_CHANGED_BEACON_INT);
}

--
1.7.5.4



2012-03-29 23:28:59

by Ashok Nagarajan

[permalink] [raw]
Subject: [PATCH 3/4] mac80211: Modify sta_get_rates to give basic rates


Signed-off-by: Ashok Nagarajan <[email protected]>
Signed-off-by: Thomas Pedersen <[email protected]>
---
net/mac80211/ibss.c | 4 ++--
net/mac80211/ieee80211_i.h | 2 +-
net/mac80211/mesh.c | 5 +++--
net/mac80211/mesh_plink.c | 7 ++++---
net/mac80211/util.c | 16 +++++++++++++---
5 files changed, 23 insertions(+), 11 deletions(-)

diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 33fd8d9..17bfb3a 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -410,7 +410,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,

if (elems->supp_rates) {
supp_rates = ieee80211_sta_get_rates(local, elems,
- band);
+ band, NULL);
if (sta) {
u32 prev_rates;

@@ -560,7 +560,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
sdata->name, mgmt->bssid);
#endif
ieee80211_sta_join_ibss(sdata, bss);
- supp_rates = ieee80211_sta_get_rates(local, elems, band);
+ supp_rates = ieee80211_sta_get_rates(local, elems, band, NULL);
ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa,
supp_rates, true);
rcu_read_unlock();
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index d9798a3..1cf5c03 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1460,7 +1460,7 @@ void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata,
const u8 *supp_rates);
u32 ieee80211_sta_get_rates(struct ieee80211_local *local,
struct ieee802_11_elems *elems,
- enum ieee80211_band band);
+ enum ieee80211_band band, u32 *basic_rates);
int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata,
enum ieee80211_smps_mode smps_mode);
void ieee80211_recalc_smps(struct ieee80211_local *local);
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 56ec79d..964d8a9 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -622,7 +622,7 @@ static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
struct ieee80211_local *local = sdata->local;
struct ieee802_11_elems elems;
struct ieee80211_channel *channel;
- u32 supp_rates = 0;
+ u32 supp_rates = 0, basic_rates = 0;
size_t baselen;
int freq;
enum ieee80211_band band = rx_status->band;
@@ -655,7 +655,8 @@ static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,

if (elems.mesh_id && elems.mesh_config &&
mesh_matches_local(&elems, sdata)) {
- supp_rates = ieee80211_sta_get_rates(local, &elems, band);
+ supp_rates = ieee80211_sta_get_rates(local, &elems,
+ band, &basic_rates);
mesh_neighbour_update(mgmt, supp_rates, sdata, &elems,
rx_status);
}
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index 8ba5f5e..879b0a1 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -474,6 +474,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
bool deactivated, matches_local = true;
u8 ie_len;
u8 *baseaddr;
+ u32 rates, basic_rates = 0;
__le16 plid, llid, reason;
#ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG
static const char *mplstates[] = {
@@ -568,6 +569,9 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m

/* Now we will figure out the appropriate event... */
event = PLINK_UNDEFINED;
+ rates = ieee80211_sta_get_rates(local, &elems,
+ rx_status->band, &basic_rates);
+
if (ftype != WLAN_SP_MESH_PEERING_CLOSE &&
(!mesh_matches_local(&elems, sdata))) {
matches_local = false;
@@ -592,7 +596,6 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
return;
} else if (!sta) {
/* ftype == WLAN_SP_MESH_PEERING_OPEN */
- u32 rates;

rcu_read_unlock();

@@ -600,8 +603,6 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
mpl_dbg("Mesh plink error: no more free plinks\n");
return;
}
-
- rates = ieee80211_sta_get_rates(local, &elems, rx_status->band);
sta = mesh_plink_alloc(sdata, mgmt->sa, rates, &elems);
if (!sta) {
mpl_dbg("Mesh plink error: plink table full\n");
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index a1e2ff5..0b8763d 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1106,7 +1106,7 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,

u32 ieee80211_sta_get_rates(struct ieee80211_local *local,
struct ieee802_11_elems *elems,
- enum ieee80211_band band)
+ enum ieee80211_band band, u32 *basic_rates)
{
struct ieee80211_supported_band *sband;
struct ieee80211_rate *bitrates;
@@ -1127,15 +1127,25 @@ u32 ieee80211_sta_get_rates(struct ieee80211_local *local,
elems->ext_supp_rates_len; i++) {
u8 rate = 0;
int own_rate;
+ bool is_basic;
if (i < elems->supp_rates_len)
rate = elems->supp_rates[i];
else if (elems->ext_supp_rates)
rate = elems->ext_supp_rates
[i - elems->supp_rates_len];
own_rate = 5 * (rate & 0x7f);
- for (j = 0; j < num_rates; j++)
- if (bitrates[j].bitrate == own_rate)
+ is_basic = !!(rate & 0x80);
+
+ if (is_basic && (rate & 0x7f) == BSS_MEMBERSHIP_SELECTOR_HT_PHY)
+ continue;
+
+ for (j = 0; j < num_rates; j++) {
+ if (bitrates[j].bitrate == own_rate) {
supp_rates |= BIT(j);
+ if (basic_rates && is_basic)
+ *basic_rates |= BIT(j);
+ }
+ }
}
return supp_rates;
}
--
1.7.5.4


2012-03-30 17:57:59

by Ashok Nagarajan

[permalink] [raw]
Subject: Re: [PATCH 2/4] mac80211: Indicate basic rates when adding supported rates

Hello Johannes,

On Thu, Mar 29, 2012 at 11:49 PM, Johannes Berg
<[email protected]> wrote:
> On Thu, 2012-03-29 at 16:28 -0700, Ashok Nagarajan wrote:
>> and extended supported rates
>>
>> Signed-off-by: Ashok Nagarajan <[email protected]>
>> Signed-off-by: Thomas Pedersen <[email protected]>
>> ---
>> ?net/mac80211/util.c | ? 12 ++++++++++--
>> ?1 files changed, 10 insertions(+), 2 deletions(-)
>>
>> diff --git a/net/mac80211/util.c b/net/mac80211/util.c
>> index 32f7a3b..a1e2ff5 100644
>> --- a/net/mac80211/util.c
>> +++ b/net/mac80211/util.c
>> @@ -1685,6 +1685,7 @@ int ieee80211_add_srates_ie(struct ieee80211_vif *vif, struct sk_buff *skb)
>> ? ? ? struct ieee80211_supported_band *sband;
>> ? ? ? int rate;
>> ? ? ? u8 i, rates, *pos;
>> + ? ? u32 basic_rates = vif->bss_conf.basic_rates;
>>
>> ? ? ? sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
>> ? ? ? rates = sband->n_bitrates;
>> @@ -1698,8 +1699,11 @@ int ieee80211_add_srates_ie(struct ieee80211_vif *vif, struct sk_buff *skb)
>> ? ? ? *pos++ = WLAN_EID_SUPP_RATES;
>> ? ? ? *pos++ = rates;
>> ? ? ? for (i = 0; i < rates; i++) {
>> + ? ? ? ? ? ? u8 basic = 0;
>> + ? ? ? ? ? ? if (basic_rates & BIT(i))
>> + ? ? ? ? ? ? ? ? ? ? basic = 0x80;
>> ? ? ? ? ? ? ? rate = sband->bitrates[i].bitrate;
>> - ? ? ? ? ? ? *pos++ = (u8) (rate / 5);
>> + ? ? ? ? ? ? *pos++ = basic | (u8) (rate / 5);
>> ? ? ? }
>
> I'm not sure you should do this unconditionally with the
> vif->bss_conf.basic_rates, for example this code is also used with TDLS
> and I have no idea what that should be there -- since we didn't add
> anything before maybe it should indeed not have any basic rate bits?
>
> johannes
>

Do you want us to add a check if the vif.type is mesh point or have an
extra parameter indicating the need for basic rates? What approach
would you suggest?

Thanks
Ashok

2012-03-30 18:37:05

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH 2/4] mac80211: Indicate basic rates when adding supported rates

On Fri, 2012-03-30 at 10:57 -0700, Ashok Nagarajan wrote:
> Hello Johannes,
>
> On Thu, Mar 29, 2012 at 11:49 PM, Johannes Berg
> <[email protected]> wrote:
> > On Thu, 2012-03-29 at 16:28 -0700, Ashok Nagarajan wrote:
> >> and extended supported rates
> >>
> >> Signed-off-by: Ashok Nagarajan <[email protected]>
> >> Signed-off-by: Thomas Pedersen <[email protected]>
> >> ---
> >> net/mac80211/util.c | 12 ++++++++++--
> >> 1 files changed, 10 insertions(+), 2 deletions(-)
> >>
> >> diff --git a/net/mac80211/util.c b/net/mac80211/util.c
> >> index 32f7a3b..a1e2ff5 100644
> >> --- a/net/mac80211/util.c
> >> +++ b/net/mac80211/util.c
> >> @@ -1685,6 +1685,7 @@ int ieee80211_add_srates_ie(struct ieee80211_vif *vif, struct sk_buff *skb)
> >> struct ieee80211_supported_band *sband;
> >> int rate;
> >> u8 i, rates, *pos;
> >> + u32 basic_rates = vif->bss_conf.basic_rates;
> >>
> >> sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
> >> rates = sband->n_bitrates;
> >> @@ -1698,8 +1699,11 @@ int ieee80211_add_srates_ie(struct ieee80211_vif *vif, struct sk_buff *skb)
> >> *pos++ = WLAN_EID_SUPP_RATES;
> >> *pos++ = rates;
> >> for (i = 0; i < rates; i++) {
> >> + u8 basic = 0;
> >> + if (basic_rates & BIT(i))
> >> + basic = 0x80;
> >> rate = sband->bitrates[i].bitrate;
> >> - *pos++ = (u8) (rate / 5);
> >> + *pos++ = basic | (u8) (rate / 5);
> >> }
> >
> > I'm not sure you should do this unconditionally with the
> > vif->bss_conf.basic_rates, for example this code is also used with TDLS
> > and I have no idea what that should be there -- since we didn't add
> > anything before maybe it should indeed not have any basic rate bits?
> >
> > johannes
> >
>
> Do you want us to add a check if the vif.type is mesh point or have an
> extra parameter indicating the need for basic rates? What approach
> would you suggest?

I'd probably say add an argument since you might want to actually set
the basic rate bits in some other cases too.

johannes


2012-03-30 06:49:09

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH 2/4] mac80211: Indicate basic rates when adding supported rates

On Thu, 2012-03-29 at 16:28 -0700, Ashok Nagarajan wrote:
> and extended supported rates
>
> Signed-off-by: Ashok Nagarajan <[email protected]>
> Signed-off-by: Thomas Pedersen <[email protected]>
> ---
> net/mac80211/util.c | 12 ++++++++++--
> 1 files changed, 10 insertions(+), 2 deletions(-)
>
> diff --git a/net/mac80211/util.c b/net/mac80211/util.c
> index 32f7a3b..a1e2ff5 100644
> --- a/net/mac80211/util.c
> +++ b/net/mac80211/util.c
> @@ -1685,6 +1685,7 @@ int ieee80211_add_srates_ie(struct ieee80211_vif *vif, struct sk_buff *skb)
> struct ieee80211_supported_band *sband;
> int rate;
> u8 i, rates, *pos;
> + u32 basic_rates = vif->bss_conf.basic_rates;
>
> sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
> rates = sband->n_bitrates;
> @@ -1698,8 +1699,11 @@ int ieee80211_add_srates_ie(struct ieee80211_vif *vif, struct sk_buff *skb)
> *pos++ = WLAN_EID_SUPP_RATES;
> *pos++ = rates;
> for (i = 0; i < rates; i++) {
> + u8 basic = 0;
> + if (basic_rates & BIT(i))
> + basic = 0x80;
> rate = sband->bitrates[i].bitrate;
> - *pos++ = (u8) (rate / 5);
> + *pos++ = basic | (u8) (rate / 5);
> }

I'm not sure you should do this unconditionally with the
vif->bss_conf.basic_rates, for example this code is also used with TDLS
and I have no idea what that should be there -- since we didn't add
anything before maybe it should indeed not have any basic rate bits?

johannes


2012-03-29 23:29:00

by Ashok Nagarajan

[permalink] [raw]
Subject: [PATCH 4/4] mac80211: Check basic rates when peering

Section 13.2.3 of IEEE 80211s standard requires BSSBasicRateSet of mesh nodes
to be identical to establish peer link.

Signed-off-by: Ashok Nagarajan <[email protected]>
Signed-off-by: Thomas Pedersen <[email protected]>
---
net/mac80211/mesh.c | 15 ++++++++++-----
net/mac80211/mesh.h | 2 +-
net/mac80211/mesh_plink.c | 2 +-
3 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 964d8a9..a67b24e 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -69,11 +69,13 @@ static void ieee80211_mesh_housekeeping_timer(unsigned long data)
*
* @ie: information elements of a management frame from the mesh peer
* @sdata: local mesh subif
+ * @basic_rates: BSSBasicRateSet of the peer candidate
*
* This function checks if the mesh configuration of a mesh point matches the
* local mesh configuration, i.e. if both nodes belong to the same mesh network.
*/
-bool mesh_matches_local(struct ieee802_11_elems *ie, struct ieee80211_sub_if_data *sdata)
+bool mesh_matches_local(struct ieee802_11_elems *ie,
+ struct ieee80211_sub_if_data *sdata, u32 basic_rates)
{
struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
struct ieee80211_local *local = sdata->local;
@@ -97,6 +99,9 @@ bool mesh_matches_local(struct ieee802_11_elems *ie, struct ieee80211_sub_if_dat
(ifmsh->mesh_auth_id == ie->mesh_config->meshconf_auth)))
goto mismatch;

+ if (sdata->vif.bss_conf.basic_rates != basic_rates)
+ goto mismatch;
+
/* disallow peering with mismatched channel types for now */
/*if (ie->ht_info_elem &&
(local->_oper_channel_type !=
@@ -653,13 +658,13 @@ static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
if (!channel || channel->flags & IEEE80211_CHAN_DISABLED)
return;

+ supp_rates = ieee80211_sta_get_rates(local, &elems,
+ band, &basic_rates);
+
if (elems.mesh_id && elems.mesh_config &&
- mesh_matches_local(&elems, sdata)) {
- supp_rates = ieee80211_sta_get_rates(local, &elems,
- band, &basic_rates);
+ mesh_matches_local(&elems, sdata, basic_rates))
mesh_neighbour_update(mgmt, supp_rates, sdata, &elems,
rx_status);
- }
}

static void ieee80211_mesh_rx_mgmt_action(struct ieee80211_sub_if_data *sdata,
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index 7d5d34b..0e40c8a 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -204,7 +204,7 @@ int ieee80211_new_mesh_header(struct ieee80211s_hdr *meshhdr,
int mesh_rmc_check(u8 *addr, struct ieee80211s_hdr *mesh_hdr,
struct ieee80211_sub_if_data *sdata);
bool mesh_matches_local(struct ieee802_11_elems *ie,
- struct ieee80211_sub_if_data *sdata);
+ struct ieee80211_sub_if_data *sdata, u32 basic_rates);
void mesh_ids_set_default(struct ieee80211_if_mesh *mesh);
void mesh_mgmt_ies_add(struct sk_buff *skb,
struct ieee80211_sub_if_data *sdata);
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index 879b0a1..abc4cb4 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -573,7 +573,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
rx_status->band, &basic_rates);

if (ftype != WLAN_SP_MESH_PEERING_CLOSE &&
- (!mesh_matches_local(&elems, sdata))) {
+ (!mesh_matches_local(&elems, sdata, basic_rates))) {
matches_local = false;
switch (ftype) {
case WLAN_SP_MESH_PEERING_OPEN:
--
1.7.5.4


2012-03-29 23:28:57

by Ashok Nagarajan

[permalink] [raw]
Subject: [PATCH 2/4] mac80211: Indicate basic rates when adding supported rates

and extended supported rates

Signed-off-by: Ashok Nagarajan <[email protected]>
Signed-off-by: Thomas Pedersen <[email protected]>
---
net/mac80211/util.c | 12 ++++++++++--
1 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 32f7a3b..a1e2ff5 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1685,6 +1685,7 @@ int ieee80211_add_srates_ie(struct ieee80211_vif *vif, struct sk_buff *skb)
struct ieee80211_supported_band *sband;
int rate;
u8 i, rates, *pos;
+ u32 basic_rates = vif->bss_conf.basic_rates;

sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
rates = sband->n_bitrates;
@@ -1698,8 +1699,11 @@ int ieee80211_add_srates_ie(struct ieee80211_vif *vif, struct sk_buff *skb)
*pos++ = WLAN_EID_SUPP_RATES;
*pos++ = rates;
for (i = 0; i < rates; i++) {
+ u8 basic = 0;
+ if (basic_rates & BIT(i))
+ basic = 0x80;
rate = sband->bitrates[i].bitrate;
- *pos++ = (u8) (rate / 5);
+ *pos++ = basic | (u8) (rate / 5);
}

return 0;
@@ -1712,6 +1716,7 @@ int ieee80211_add_ext_srates_ie(struct ieee80211_vif *vif, struct sk_buff *skb)
struct ieee80211_supported_band *sband;
int rate;
u8 i, exrates, *pos;
+ u32 basic_rates = vif->bss_conf.basic_rates;

sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
exrates = sband->n_bitrates;
@@ -1728,8 +1733,11 @@ int ieee80211_add_ext_srates_ie(struct ieee80211_vif *vif, struct sk_buff *skb)
*pos++ = WLAN_EID_EXT_SUPP_RATES;
*pos++ = exrates;
for (i = 8; i < sband->n_bitrates; i++) {
+ u8 basic = 0;
+ if (basic_rates & BIT(i))
+ basic = 0x80;
rate = sband->bitrates[i].bitrate;
- *pos++ = (u8) (rate / 5);
+ *pos++ = basic | (u8) (rate / 5);
}
}
return 0;
--
1.7.5.4