2012-03-31 20:32:22

by Ashok Nagarajan

[permalink] [raw]
Subject: [[PATCH v2 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-31 20:32:25

by Ashok Nagarajan

[permalink] [raw]
Subject: [[PATCH v2 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 133f267..d742355 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-31 20:32:24

by Ashok Nagarajan

[permalink] [raw]
Subject: [[PATCH v2 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 e1a5fc4..133f267 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 ca5aa32..8ae0363 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-31 20:32:23

by Ashok Nagarajan

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

Basic rates are added with supported rates IE and extended supported
rates IE.

Signed-off-by: Ashok Nagarajan <[email protected]>
Signed-off-by: Thomas Pedersen <[email protected]>
---
v2:
indicate basic_rates conditionally (Johannes)
include/net/mac80211.h | 5 +++--
net/mac80211/cfg.c | 12 ++++++------
net/mac80211/mesh_plink.c | 4 ++--
net/mac80211/tx.c | 4 ++--
net/mac80211/util.c | 18 ++++++++++++++----
5 files changed, 27 insertions(+), 16 deletions(-)

diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 9a012be..60f4cf4 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -3704,8 +3704,9 @@ void ieee80211_enable_rssi_reports(struct ieee80211_vif *vif,

void ieee80211_disable_rssi_reports(struct ieee80211_vif *vif);

-int ieee80211_add_srates_ie(struct ieee80211_vif *vif, struct sk_buff *skb);
+int ieee80211_add_srates_ie(struct ieee80211_vif *vif,
+ struct sk_buff *skb, bool need_basic);

int ieee80211_add_ext_srates_ie(struct ieee80211_vif *vif,
- struct sk_buff *skb);
+ struct sk_buff *skb, bool need_basic);
#endif /* MAC80211_H */
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 75a5bcd..37f6b35 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -2354,8 +2354,8 @@ ieee80211_prep_tdls_encap_data(struct wiphy *wiphy, struct net_device *dev,
tf->u.setup_req.capability =
cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata));

- ieee80211_add_srates_ie(&sdata->vif, skb);
- ieee80211_add_ext_srates_ie(&sdata->vif, skb);
+ ieee80211_add_srates_ie(&sdata->vif, skb, false);
+ ieee80211_add_ext_srates_ie(&sdata->vif, skb, false);
ieee80211_tdls_add_ext_capab(skb);
break;
case WLAN_TDLS_SETUP_RESPONSE:
@@ -2368,8 +2368,8 @@ ieee80211_prep_tdls_encap_data(struct wiphy *wiphy, struct net_device *dev,
tf->u.setup_resp.capability =
cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata));

- ieee80211_add_srates_ie(&sdata->vif, skb);
- ieee80211_add_ext_srates_ie(&sdata->vif, skb);
+ ieee80211_add_srates_ie(&sdata->vif, skb, false);
+ ieee80211_add_ext_srates_ie(&sdata->vif, skb, false);
ieee80211_tdls_add_ext_capab(skb);
break;
case WLAN_TDLS_SETUP_CONFIRM:
@@ -2429,8 +2429,8 @@ ieee80211_prep_tdls_direct(struct wiphy *wiphy, struct net_device *dev,
mgmt->u.action.u.tdls_discover_resp.capability =
cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata));

- ieee80211_add_srates_ie(&sdata->vif, skb);
- ieee80211_add_ext_srates_ie(&sdata->vif, skb);
+ ieee80211_add_srates_ie(&sdata->vif, skb, false);
+ ieee80211_add_ext_srates_ie(&sdata->vif, skb, false);
ieee80211_tdls_add_ext_capab(skb);
break;
default:
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index 8ba5f5e..e1a5fc4 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -212,8 +212,8 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
pos = skb_put(skb, 2);
memcpy(pos + 2, &plid, 2);
}
- if (ieee80211_add_srates_ie(&sdata->vif, skb) ||
- ieee80211_add_ext_srates_ie(&sdata->vif, skb) ||
+ if (ieee80211_add_srates_ie(&sdata->vif, skb, true) ||
+ ieee80211_add_ext_srates_ie(&sdata->vif, skb, true) ||
mesh_add_rsn_ie(skb, sdata) ||
mesh_add_meshid_ie(skb, sdata) ||
mesh_add_meshconf_ie(skb, sdata))
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 782a601..196cc58 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -2414,9 +2414,9 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
*pos++ = WLAN_EID_SSID;
*pos++ = 0x0;

- if (ieee80211_add_srates_ie(&sdata->vif, skb) ||
+ if (ieee80211_add_srates_ie(&sdata->vif, skb, true) ||
mesh_add_ds_params_ie(skb, sdata) ||
- ieee80211_add_ext_srates_ie(&sdata->vif, skb) ||
+ ieee80211_add_ext_srates_ie(&sdata->vif, skb, true) ||
mesh_add_rsn_ie(skb, sdata) ||
mesh_add_ht_cap_ie(skb, sdata) ||
mesh_add_ht_info_ie(skb, sdata) ||
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 32f7a3b..ca5aa32 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1678,13 +1678,15 @@ ieee80211_ht_info_to_channel_type(struct ieee80211_ht_info *ht_info)
return channel_type;
}

-int ieee80211_add_srates_ie(struct ieee80211_vif *vif, struct sk_buff *skb)
+int ieee80211_add_srates_ie(struct ieee80211_vif *vif,
+ struct sk_buff *skb, bool need_basic)
{
struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
struct ieee80211_local *local = sdata->local;
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,20 +1700,25 @@ 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 (need_basic && basic_rates & BIT(i))
+ basic = 0x80;
rate = sband->bitrates[i].bitrate;
- *pos++ = (u8) (rate / 5);
+ *pos++ = basic | (u8) (rate / 5);
}

return 0;
}

-int ieee80211_add_ext_srates_ie(struct ieee80211_vif *vif, struct sk_buff *skb)
+int ieee80211_add_ext_srates_ie(struct ieee80211_vif *vif,
+ struct sk_buff *skb, bool need_basic)
{
struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
struct ieee80211_local *local = sdata->local;
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 +1735,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 (need_basic && 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


2012-04-02 10:37:51

by Johannes Berg

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

On Sat, 2012-03-31 at 13:32 -0700, Ashok Nagarajan wrote:

> @@ -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);
> + }
> + }

Seems it'd be worth skipping the entire logic if basic_rates is NULL?

johannes


2012-04-03 02:30:37

by Ashok Nagarajan

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

Hello John,

Please do not apply this patch set as they might rise conflicts.
Version 3 is coming.

Thanks,
Ashok

On Sat, Mar 31, 2012 at 1:32 PM, Ashok Nagarajan <[email protected]> wrote:
> 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 133f267..d742355 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-04-02 10:41:32

by Johannes Berg

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

On Mon, 2012-04-02 at 12:37 +0200, Johannes Berg wrote:
> On Sat, 2012-03-31 at 13:32 -0700, Ashok Nagarajan wrote:
>
> > @@ -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);
> > + }
> > + }
>
> Seems it'd be worth skipping the entire logic if basic_rates is NULL?

Oh, never mind, got confused.

johannes