2012-04-27 03:48:39

by Ashok Nagarajan

[permalink] [raw]
Subject: [PATCH 1/4] mac80211: Advertise HT protection mode in IEs

Signed-off-by: Ashok Nagarajan <[email protected]>
Reviewed-by: Thomas Pedersen <[email protected]>
---
net/mac80211/ibss.c | 2 +-
net/mac80211/ieee80211_i.h | 3 ++-
net/mac80211/mesh.c | 3 ++-
net/mac80211/util.c | 9 +++------
4 files changed, 8 insertions(+), 9 deletions(-)

diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 61cd391..bb1a3e6 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -164,7 +164,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
pos = ieee80211_ie_build_ht_cap(pos, &sband->ht_cap,
sband->ht_cap.cap);
pos = ieee80211_ie_build_ht_oper(pos, &sband->ht_cap,
- chan, channel_type);
+ chan, channel_type, 0);
}

if (local->hw.queues >= IEEE80211_NUM_ACS) {
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 6cd89d4..ae046b5 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1497,7 +1497,8 @@ u8 *ieee80211_ie_build_ht_cap(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap,
u16 cap);
u8 *ieee80211_ie_build_ht_oper(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap,
struct ieee80211_channel *channel,
- enum nl80211_channel_type channel_type);
+ enum nl80211_channel_type channel_type,
+ u16 prot_mode);

/* internal work items */
void ieee80211_work_init(struct ieee80211_local *local);
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 598a96a..8a952e0 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -396,7 +396,8 @@ int mesh_add_ht_oper_ie(struct sk_buff *skb,
return -ENOMEM;

pos = skb_put(skb, 2 + sizeof(struct ieee80211_ht_operation));
- ieee80211_ie_build_ht_oper(pos, ht_cap, channel, channel_type);
+ ieee80211_ie_build_ht_oper(pos, ht_cap, channel, channel_type,
+ sdata->vif.bss_conf.ht_operation_mode);

return 0;
}
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index d9a747d..22f2216 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1663,7 +1663,8 @@ u8 *ieee80211_ie_build_ht_cap(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap,

u8 *ieee80211_ie_build_ht_oper(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap,
struct ieee80211_channel *channel,
- enum nl80211_channel_type channel_type)
+ enum nl80211_channel_type channel_type,
+ u16 prot_mode)
{
struct ieee80211_ht_operation *ht_oper;
/* Build HT Information */
@@ -1689,11 +1690,7 @@ u8 *ieee80211_ie_build_ht_oper(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap,
channel_type != NL80211_CHAN_HT20)
ht_oper->ht_param |= IEEE80211_HT_PARAM_CHAN_WIDTH_ANY;

- /*
- * Note: According to 802.11n-2009 9.13.3.1, HT Protection field and
- * RIFS Mode are reserved in IBSS mode, therefore keep them at 0
- */
- ht_oper->operation_mode = 0x0000;
+ ht_oper->operation_mode = cpu_to_le16(prot_mode);
ht_oper->stbc_param = 0x0000;

/* It seems that Basic MCS set and Supported MCS set
--
1.7.5.4



2012-04-27 03:48:40

by Ashok Nagarajan

[permalink] [raw]
Subject: [PATCH 3/4] mac80211: Allow nonHT/HT peering in mesh

Now that we have protection enabled, allow non-HT and HT20 stations to peer
with HT40+/- stations. Peering is still disallowed for HT40+/- mismatch.

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

diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 8a952e0..d25cb78 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -76,6 +76,7 @@ bool mesh_matches_local(struct ieee80211_sub_if_data *sdata,
struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
struct ieee80211_local *local = sdata->local;
u32 basic_rates = 0;
+ enum nl80211_channel_type sta_channel_type;

/*
* As support for each feature is added, check for matching
@@ -102,10 +103,15 @@ bool mesh_matches_local(struct ieee80211_sub_if_data *sdata,
if (sdata->vif.bss_conf.basic_rates != basic_rates)
goto mismatch;

- /* disallow peering with mismatched channel types for now */
+ if (ie->ht_operation)
+ sta_channel_type =
+ ieee80211_ht_oper_to_channel_type(ie->ht_operation);
+
+ /* Disallow HT40+/- mismatch */
if (ie->ht_operation &&
- (local->_oper_channel_type !=
- ieee80211_ht_oper_to_channel_type(ie->ht_operation)))
+ local->_oper_channel_type > NL80211_CHAN_HT20 &&
+ sta_channel_type > NL80211_CHAN_HT20 &&
+ local->_oper_channel_type != sta_channel_type)
goto mismatch;

return true;
--
1.7.5.4


2012-04-30 19:17:49

by John W. Linville

[permalink] [raw]
Subject: Re: [PATCH 3/4] mac80211: Allow nonHT/HT peering in mesh

On Thu, Apr 26, 2012 at 08:48:25PM -0700, Ashok Nagarajan wrote:
> Now that we have protection enabled, allow non-HT and HT20 stations to peer
> with HT40+/- stations. Peering is still disallowed for HT40+/- mismatch.
>
> Signed-off-by: Ashok Nagarajan <[email protected]>
> Reviewed-by: Thomas Pedersen <[email protected]>

CC net/mac80211/mesh.o
net/mac80211/mesh.c: In function ‘mesh_matches_local’:
net/mac80211/mesh.c:79:28: warning: ‘sta_channel_type’ may be used uninitialized in this function

Please don't add warnings!

> ---
> net/mac80211/mesh.c | 12 +++++++++---
> 1 files changed, 9 insertions(+), 3 deletions(-)
>
> diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
> index 8a952e0..d25cb78 100644
> --- a/net/mac80211/mesh.c
> +++ b/net/mac80211/mesh.c
> @@ -76,6 +76,7 @@ bool mesh_matches_local(struct ieee80211_sub_if_data *sdata,
> struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
> struct ieee80211_local *local = sdata->local;
> u32 basic_rates = 0;
> + enum nl80211_channel_type sta_channel_type;
>
> /*
> * As support for each feature is added, check for matching
> @@ -102,10 +103,15 @@ bool mesh_matches_local(struct ieee80211_sub_if_data *sdata,
> if (sdata->vif.bss_conf.basic_rates != basic_rates)
> goto mismatch;
>
> - /* disallow peering with mismatched channel types for now */
> + if (ie->ht_operation)
> + sta_channel_type =
> + ieee80211_ht_oper_to_channel_type(ie->ht_operation);
> +
> + /* Disallow HT40+/- mismatch */
> if (ie->ht_operation &&
> - (local->_oper_channel_type !=
> - ieee80211_ht_oper_to_channel_type(ie->ht_operation)))
> + local->_oper_channel_type > NL80211_CHAN_HT20 &&
> + sta_channel_type > NL80211_CHAN_HT20 &&
> + local->_oper_channel_type != sta_channel_type)
> goto mismatch;
>
> return true;
> --
> 1.7.5.4
>
>

--
John W. Linville Someday the world will need a hero, and you
[email protected] might be all we have. Be ready.

2012-04-27 03:48:39

by Ashok Nagarajan

[permalink] [raw]
Subject: [PATCH 2/4] mac80211: Implement HT mixed protection mode

Section 9.23.3.5 of IEEE 80211s standard describes the protection rules for
HT mesh STA in a MBSS. Three HT protection modes are supported for now:

non-HT mixed mode - is selected if any non-HT peers are present in our MBSS.
20MHz-protection mode - is selected if all peers in our 20/40MHz MBSS support
HT and atleast one HT20 peer is present.
no-protection mode - is selected otherwise.

This is a limited implementation of 9.23.3.5, which only considers mesh peers
when determining the HT protection mode. Station's channel_type needs to be
maintained.

Signed-off-by: Ashok Nagarajan <[email protected]>
Reviewed-by: Thomas Pedersen <[email protected]>
---
net/mac80211/mesh_plink.c | 82 +++++++++++++++++++++++++++++++++++++++++---
net/mac80211/sta_info.h | 1 +
2 files changed, 77 insertions(+), 6 deletions(-)

diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index 1ff2a5c..8007f9c 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -108,6 +108,66 @@ static struct sta_info *mesh_plink_alloc(struct ieee80211_sub_if_data *sdata,
return sta;
}

+/** mesh_set_ht_prot_mode - set correct HT protection mode
+ *
+ * Section 9.23.3.5 of IEEE 80211s standard describes the protection rules for
+ * HT mesh STA in a MBSS. Three HT protection modes are supported for now,
+ * non-HT mixed mode, 20MHz-protection and no-protection mode. non-HT mixed
+ * mode is selected if any non-HT peers are present in our MBSS.
+ * 20MHz-protection mode is selected if all peers in our 20/40MHz MBSS support
+ * HT and atleast one HT20 peer is present. Otherwise no-protection mode is
+ * selected.
+ */
+static u32 mesh_set_ht_prot_mode(struct ieee80211_sub_if_data *sdata)
+{
+ struct ieee80211_local *local = sdata->local;
+ struct sta_info *sta;
+ u32 changed = 0;
+ u16 ht_opmode;
+ bool non_ht_sta = false, ht20_sta = false;
+
+ if (local->_oper_channel_type == NL80211_CHAN_NO_HT)
+ return 0;
+
+ rcu_read_lock();
+ list_for_each_entry_rcu(sta, &local->sta_list, list) {
+ if (sdata == sta->sdata &&
+ sta->plink_state == NL80211_PLINK_ESTAB) {
+ switch (sta->ch_type) {
+ case NL80211_CHAN_NO_HT:
+ mpl_dbg("mesh_plink %pM: nonHT sta (%pM) is present",
+ sdata->vif.addr, sta->sta.addr);
+ non_ht_sta = true;
+ goto out;
+ case NL80211_CHAN_HT20:
+ mpl_dbg("mesh_plink %pM: HT20 sta (%pM) is present",
+ sdata->vif.addr, sta->sta.addr);
+ ht20_sta = true;
+ default:
+ break;
+ }
+ }
+ }
+out:
+ rcu_read_unlock();
+
+ if (non_ht_sta)
+ ht_opmode = IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED;
+ else if (ht20_sta && local->_oper_channel_type > NL80211_CHAN_HT20)
+ ht_opmode = IEEE80211_HT_OP_MODE_PROTECTION_20MHZ;
+ else
+ ht_opmode = IEEE80211_HT_OP_MODE_PROTECTION_NONE;
+
+ if (sdata->vif.bss_conf.ht_operation_mode != ht_opmode) {
+ sdata->vif.bss_conf.ht_operation_mode = ht_opmode;
+ changed = BSS_CHANGED_HT;
+ mpl_dbg("mesh_plink %pM: protection mode changed to %d",
+ sdata->vif.addr, ht_opmode);
+ }
+
+ return changed;
+}
+
/**
* __mesh_plink_deactivate - deactivate mesh peer link
*
@@ -303,6 +363,10 @@ static struct sta_info *mesh_peer_init(struct ieee80211_sub_if_data *sdata,
else
memset(&sta->sta.ht_cap, 0, sizeof(sta->sta.ht_cap));

+ if (elems->ht_operation)
+ sta->ch_type =
+ ieee80211_ht_oper_to_channel_type(elems->ht_operation);
+
rate_control_rate_init(sta);
spin_unlock_bh(&sta->lock);

@@ -487,9 +551,10 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
enum plink_event event;
enum ieee80211_self_protected_actioncode ftype;
size_t baselen;
- bool deactivated, matches_local = true;
+ bool matches_local = true;
u8 ie_len;
u8 *baseaddr;
+ u32 changed = 0;
__le16 plid, llid, reason;
#ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG
static const char *mplstates[] = {
@@ -775,7 +840,8 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
sta->plink_state = NL80211_PLINK_ESTAB;
spin_unlock_bh(&sta->lock);
mesh_plink_inc_estab_count(sdata);
- ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON);
+ changed |= mesh_set_ht_prot_mode(sdata);
+ changed |= BSS_CHANGED_BEACON;
mpl_dbg("Mesh plink with %pM ESTABLISHED\n",
sta->sta.addr);
break;
@@ -810,7 +876,8 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
sta->plink_state = NL80211_PLINK_ESTAB;
spin_unlock_bh(&sta->lock);
mesh_plink_inc_estab_count(sdata);
- ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON);
+ changed |= mesh_set_ht_prot_mode(sdata);
+ changed |= BSS_CHANGED_BEACON;
mpl_dbg("Mesh plink with %pM ESTABLISHED\n",
sta->sta.addr);
mesh_plink_frame_tx(sdata,
@@ -828,13 +895,13 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
case CLS_ACPT:
reason = cpu_to_le16(WLAN_REASON_MESH_CLOSE);
sta->reason = reason;
- deactivated = __mesh_plink_deactivate(sta);
+ __mesh_plink_deactivate(sta);
sta->plink_state = NL80211_PLINK_HOLDING;
llid = sta->llid;
mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata));
spin_unlock_bh(&sta->lock);
- if (deactivated)
- ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON);
+ changed |= mesh_set_ht_prot_mode(sdata);
+ changed |= BSS_CHANGED_BEACON;
mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
sta->sta.addr, llid, plid, reason);
break;
@@ -881,4 +948,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
}

rcu_read_unlock();
+
+ if (changed)
+ ieee80211_bss_info_change_notify(sdata, changed);
}
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index f75f5d9..663dc90 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -362,6 +362,7 @@ struct sta_info {
struct timer_list plink_timer;
s64 t_offset;
s64 t_offset_setpoint;
+ enum nl80211_channel_type ch_type;
#endif

#ifdef CONFIG_MAC80211_DEBUGFS
--
1.7.5.4


2012-04-30 20:46:46

by Ashok Nagarajan

[permalink] [raw]
Subject: Re: [PATCH 3/4] mac80211: Allow nonHT/HT peering in mesh

Hello John,

On Mon, Apr 30, 2012 at 12:09 PM, John W. Linville
<[email protected]> wrote:
> On Thu, Apr 26, 2012 at 08:48:25PM -0700, Ashok Nagarajan wrote:
>> Now that we have protection enabled, allow non-HT and HT20 stations to peer
>> with HT40+/- stations. Peering is still disallowed for HT40+/- mismatch.
>>
>> Signed-off-by: Ashok Nagarajan <[email protected]>
>> Reviewed-by: Thomas Pedersen <[email protected]>
>
> ?CC ? ? ?net/mac80211/mesh.o
> net/mac80211/mesh.c: In function ?mesh_matches_local?:
> net/mac80211/mesh.c:79:28: warning: ?sta_channel_type? may be used uninitialized in this function
>
> Please don't add warnings!
>
Sorry for the warning. Version 2 is coming.

Thanks,
Ashok
>> ---
>> ?net/mac80211/mesh.c | ? 12 +++++++++---
>> ?1 files changed, 9 insertions(+), 3 deletions(-)
>>
>> diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
>> index 8a952e0..d25cb78 100644
>> --- a/net/mac80211/mesh.c
>> +++ b/net/mac80211/mesh.c
>> @@ -76,6 +76,7 @@ bool mesh_matches_local(struct ieee80211_sub_if_data *sdata,
>> ? ? ? struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
>> ? ? ? struct ieee80211_local *local = sdata->local;
>> ? ? ? u32 basic_rates = 0;
>> + ? ? enum nl80211_channel_type sta_channel_type;
>>
>> ? ? ? /*
>> ? ? ? ?* As support for each feature is added, check for matching
>> @@ -102,10 +103,15 @@ bool mesh_matches_local(struct ieee80211_sub_if_data *sdata,
>> ? ? ? if (sdata->vif.bss_conf.basic_rates != basic_rates)
>> ? ? ? ? ? ? ? goto mismatch;
>>
>> - ? ? /* disallow peering with mismatched channel types for now */
>> + ? ? if (ie->ht_operation)
>> + ? ? ? ? ? ? sta_channel_type =
>> + ? ? ? ? ? ? ? ? ? ? ieee80211_ht_oper_to_channel_type(ie->ht_operation);
>> +
>> + ? ? /* Disallow HT40+/- mismatch */
>> ? ? ? if (ie->ht_operation &&
>> - ? ? ? ? (local->_oper_channel_type !=
>> - ? ? ? ? ?ieee80211_ht_oper_to_channel_type(ie->ht_operation)))
>> + ? ? ? ? local->_oper_channel_type > NL80211_CHAN_HT20 &&
>> + ? ? ? ? sta_channel_type > NL80211_CHAN_HT20 &&
>> + ? ? ? ? local->_oper_channel_type != sta_channel_type)
>> ? ? ? ? ? ? ? goto mismatch;
>>
>> ? ? ? return true;
>> --
>> 1.7.5.4
>>
>>
>
> --
> John W. Linville ? ? ? ? ? ? ? ?Someday the world will need a hero, and you
> [email protected] ? ? ? ? ? ? ? ? ?might be all we have. ?Be ready.

2012-04-27 03:48:42

by Ashok Nagarajan

[permalink] [raw]
Subject: [PATCH 4/4] [nl,cfg,mac]80211: Allow user to see/configure HT protection mode

This patch introduces a new mesh configuration parameter "ht_opmode" and will
allow user to check the current HT protection mode selected. Users could
configure the protection mode by the command "iw mesh_iface set mesh_param
mesh_ht_protection_mode=2". The default protection mode of mesh is set to
non-HT mixed mode.

Signed-off-by: Ashok Nagarajan <[email protected]>
Reviewed-by: Thomas Pedersen <[email protected]>
---
include/linux/nl80211.h | 3 +++
include/net/cfg80211.h | 1 +
net/mac80211/cfg.c | 5 +++++
net/mac80211/mesh.c | 3 +++
net/mac80211/mesh_plink.c | 1 +
net/wireless/mesh.c | 1 +
net/wireless/nl80211.c | 5 +++++
7 files changed, 19 insertions(+), 0 deletions(-)

diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index 1335084..2540e86 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -2154,6 +2154,8 @@ enum nl80211_mntr_flags {
* @NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR: maximum number of neighbors
* to synchronize to for 11s default synchronization method (see 11C.12.2.2)
*
+ * @NL80211_MESHCONF_HT_OPMODE: set mesh HT protection mode.
+ *
* @__NL80211_MESHCONF_ATTR_AFTER_LAST: internal use
*/
enum nl80211_meshconf_params {
@@ -2179,6 +2181,7 @@ enum nl80211_meshconf_params {
NL80211_MESHCONF_FORWARDING,
NL80211_MESHCONF_RSSI_THRESHOLD,
NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR,
+ NL80211_MESHCONF_HT_OPMODE,

/* keep last */
__NL80211_MESHCONF_ATTR_AFTER_LAST,
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 815dc3f..1c36cb5 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -821,6 +821,7 @@ struct mesh_config {
bool dot11MeshGateAnnouncementProtocol;
bool dot11MeshForwarding;
s32 rssi_threshold;
+ u16 ht_opmode;
};

/**
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 70b2af2..3532ae0 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1364,6 +1364,11 @@ static int ieee80211_update_mesh_config(struct wiphy *wiphy,
return -ENOTSUPP;
conf->rssi_threshold = nconf->rssi_threshold;
}
+ if (_chg_mesh_attr(NL80211_MESHCONF_HT_OPMODE, mask)) {
+ conf->ht_opmode = nconf->ht_opmode;
+ sdata->vif.bss_conf.ht_operation_mode = nconf->ht_opmode;
+ ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_HT);
+ }
return 0;
}

diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index d25cb78..98faac6 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -595,12 +595,15 @@ void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)
set_bit(MESH_WORK_HOUSEKEEPING, &ifmsh->wrkq_flags);
ieee80211_mesh_root_setup(ifmsh);
ieee80211_queue_work(&local->hw, &sdata->work);
+ sdata->vif.bss_conf.ht_operation_mode =
+ ifmsh->mshcfg.ht_opmode;
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_HT |
BSS_CHANGED_BASIC_RATES |
BSS_CHANGED_BEACON_INT);
}
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index 8007f9c..b293006 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -160,6 +160,7 @@ out:

if (sdata->vif.bss_conf.ht_operation_mode != ht_opmode) {
sdata->vif.bss_conf.ht_operation_mode = ht_opmode;
+ sdata->u.mesh.mshcfg.ht_opmode = ht_opmode;
changed = BSS_CHANGED_HT;
mpl_dbg("mesh_plink %pM: protection mode changed to %d",
sdata->vif.addr, ht_opmode);
diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c
index 8c747fa..2749cb8 100644
--- a/net/wireless/mesh.c
+++ b/net/wireless/mesh.c
@@ -61,6 +61,7 @@ const struct mesh_config default_mesh_config = {
.dot11MeshGateAnnouncementProtocol = false,
.dot11MeshForwarding = true,
.rssi_threshold = MESH_RSSI_THRESHOLD,
+ .ht_opmode = IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED,
};

const struct mesh_setup default_mesh_setup = {
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 140c1d2..859bd66 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -3335,6 +3335,8 @@ static int nl80211_get_mesh_config(struct sk_buff *skb,
cur_params.dot11MeshForwarding);
NLA_PUT_U32(msg, NL80211_MESHCONF_RSSI_THRESHOLD,
cur_params.rssi_threshold);
+ NLA_PUT_U32(msg, NL80211_MESHCONF_HT_OPMODE,
+ cur_params.ht_opmode);
nla_nest_end(msg, pinfoattr);
genlmsg_end(msg, hdr);
return genlmsg_reply(msg, info);
@@ -3369,6 +3371,7 @@ static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_A
[NL80211_MESHCONF_GATE_ANNOUNCEMENTS] = { .type = NLA_U8 },
[NL80211_MESHCONF_FORWARDING] = { .type = NLA_U8 },
[NL80211_MESHCONF_RSSI_THRESHOLD] = { .type = NLA_U32},
+ [NL80211_MESHCONF_HT_OPMODE] = { .type = NLA_U16},
};

static const struct nla_policy
@@ -3466,6 +3469,8 @@ do {\
mask, NL80211_MESHCONF_FORWARDING, nla_get_u8);
FILL_IN_MESH_PARAM_IF_SET(tb, cfg, rssi_threshold,
mask, NL80211_MESHCONF_RSSI_THRESHOLD, nla_get_u32);
+ FILL_IN_MESH_PARAM_IF_SET(tb, cfg, ht_opmode,
+ mask, NL80211_MESHCONF_HT_OPMODE, nla_get_u16);
if (mask_out)
*mask_out = mask;

--
1.7.5.4