2015-01-20 12:36:45

by Janusz Dziedzic

[permalink] [raw]
Subject: [RFCv3 1/4] mac80211: ibss/mesh move bw checking

We will need this as a preparetion for VHT.

Signed-off-by: Janusz Dziedzic <[email protected]>
---
net/mac80211/ht.c | 2 --
net/mac80211/ibss.c | 4 ++++
net/mac80211/mesh_plink.c | 4 ++++
3 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c
index ff630be..7a76ce6 100644
--- a/net/mac80211/ht.c
+++ b/net/mac80211/ht.c
@@ -252,8 +252,6 @@ bool ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_sub_if_data *sdata,
break;
}

- if (bw != sta->sta.bandwidth)
- changed = true;
sta->sta.bandwidth = bw;

sta->cur_max_bandwidth =
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index b606b53..9fe045f 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -1048,6 +1048,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
/* we both use HT */
struct ieee80211_ht_cap htcap_ie;
struct cfg80211_chan_def chandef;
+ enum ieee80211_sta_rx_bandwidth bw = sta->sta.bandwidth;

ieee80211_ht_oper_to_chandef(channel,
elems->ht_operation,
@@ -1066,6 +1067,9 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,

rates_updated |= ieee80211_ht_cap_ie_to_sta_ht_cap(
sdata, sband, &htcap_ie, sta);
+
+ if (bw != sta->sta.bandwidth)
+ rates_updated |= true;
}

if (sta && rates_updated) {
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index b488e18..9875d82 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -382,6 +382,7 @@ static void mesh_sta_info_init(struct ieee80211_sub_if_data *sdata,
enum ieee80211_band band = ieee80211_get_sdata_band(sdata);
struct ieee80211_supported_band *sband;
u32 rates, basic_rates = 0, changed = 0;
+ enum ieee80211_sta_rx_bandwidth bw = sta->sta.bandwidth;

sband = local->hw.wiphy->bands[band];
rates = ieee80211_sta_get_rates(sdata, elems, band, &basic_rates);
@@ -401,6 +402,9 @@ static void mesh_sta_info_init(struct ieee80211_sub_if_data *sdata,
elems->ht_cap_elem, sta))
changed |= IEEE80211_RC_BW_CHANGED;

+ if (bw != sta->sta.bandwidth)
+ changed |= IEEE80211_RC_BW_CHANGED;
+
/* HT peer is operating 20MHz-only */
if (elems->ht_operation &&
!(elems->ht_operation->ht_param &
--
1.9.1



2015-01-20 12:36:47

by Janusz Dziedzic

[permalink] [raw]
Subject: [RFCv3 2/4] cfg80211: add VHT support for IBSS

Add NL80211_FEATURE_VHT_IBSS flag and VHT
support for IBSS.

Signed-off-by: Janusz Dziedzic <[email protected]>
---
include/uapi/linux/nl80211.h | 2 ++
net/wireless/nl80211.c | 14 ++++++++++++--
2 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index e2fc08b..3f40789 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -4203,11 +4203,13 @@ enum nl80211_feature_flags {

/**
* enum nl80211_ext_feature_index - bit index of extended features.
+ * @NL80211_FEATURE_VHT_IBSS: This driver supports IBSS with VHT datarates.
*
* @NUM_NL80211_EXT_FEATURES: number of extended features.
* @MAX_NL80211_EXT_FEATURES: highest extended feature index.
*/
enum nl80211_ext_feature_index {
+ NL80211_FEATURE_VHT_IBSS,

/* add new features before the definition below */
NUM_NL80211_EXT_FEATURES,
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index b18d2bc..05d6db0 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -7095,8 +7095,18 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
break;
case NL80211_CHAN_WIDTH_20:
case NL80211_CHAN_WIDTH_40:
- if (rdev->wiphy.features & NL80211_FEATURE_HT_IBSS)
- break;
+ if (!(rdev->wiphy.features & NL80211_FEATURE_HT_IBSS))
+ return -EINVAL;
+ break;
+ case NL80211_CHAN_WIDTH_80:
+ case NL80211_CHAN_WIDTH_80P80:
+ case NL80211_CHAN_WIDTH_160:
+ if (!(rdev->wiphy.features & NL80211_FEATURE_HT_IBSS))
+ return -EINVAL;
+ if (!wiphy_ext_feature_isset(&rdev->wiphy,
+ NL80211_FEATURE_VHT_IBSS))
+ return -EINVAL;
+ break;
default:
return -EINVAL;
}
--
1.9.1


2015-01-26 09:49:28

by Janusz Dziedzic

[permalink] [raw]
Subject: Re: [RFCv3 4/4] mac80211: add VHT support for IBSS

On 26 January 2015 at 10:25, Johannes Berg <[email protected]> wrote:
> On Mon, 2015-01-26 at 10:19 +0100, Janusz Dziedzic wrote:
>> On 26 January 2015 at 10:00, Johannes Berg <[email protected]> wrote:
>> > On Mon, 2015-01-26 at 10:37 +0200, Arik Nemtsov wrote:
>> >
>> >> >> Shouldn't you also set vht_oper->basic_mcs_set here? Of course if you
>> >> >> have no use for it in IBSS I can add it later.
>> >> >
>> >> > Why would you want to require VHT rates?
>> >>
>> >> Are you sure it's required and no the other way around in this case?
>> >> As in specifying which rates are not supported.
>> >> Not sure it means the same thing as in the HT instance.
>> >
>> > Well, it does mean the same thing ("these rates are required") but it's
>> > encoded in a way that you have to set it to all-ones (rather than
>> > all-zeroes) to mean "no requirements", so in that sense you're right.
>> >
>>
>> I already set this in the patch:
>> + vht_oper->basic_mcs_set = vht_cap->vht_mcs.rx_mcs_map;
>
> But do you really want to require the local capabilities as basic MCSes?
>
I am not sure. Will check spec and how we do that for an AP.

BR
Janusz

2015-01-23 10:01:16

by Johannes Berg

[permalink] [raw]
Subject: Re: [RFCv3 1/4] mac80211: ibss/mesh move bw checking

On Tue, 2015-01-20 at 13:35 +0100, Janusz Dziedzic wrote:
> We will need this as a preparetion for VHT.

"preparation" :)

It'd be good to explain it a little more though. At least the very last
hunk:

> @@ -401,6 +402,9 @@ static void mesh_sta_info_init(struct ieee80211_sub_if_data *sdata,
> elems->ht_cap_elem, sta))
> changed |= IEEE80211_RC_BW_CHANGED;
>
> + if (bw != sta->sta.bandwidth)
> + changed |= IEEE80211_RC_BW_CHANGED;
> +

seems new - not just moved.

johannes


2015-01-25 10:30:36

by Arik Nemtsov

[permalink] [raw]
Subject: Re: [RFCv3 4/4] mac80211: add VHT support for IBSS

On Tue, Jan 20, 2015 at 2:35 PM, Janusz Dziedzic
<[email protected]> wrote:
> Add VHT80/VHT160 support for IBSS.
> Drivers could activate this feature by
> setting NL80211_FEATURE_VHT_IBSS flag.
>
> Signed-off-by: Janusz Dziedzic <[email protected]>
[...]
> +u8 *ieee80211_ie_build_vht_oper(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap,
> + const struct cfg80211_chan_def *chandef)
> +{
> + struct ieee80211_vht_operation *vht_oper;
> +
> + /* Build VHT Operation */
> + *pos++ = WLAN_EID_VHT_OPERATION;
> + *pos++ = sizeof(struct ieee80211_vht_operation);
> +
> + vht_oper = (struct ieee80211_vht_operation *)pos;
> +
> + vht_oper->center_freq_seg1_idx =
> + ieee80211_frequency_to_channel(chandef->center_freq1);
> + vht_oper->center_freq_seg2_idx = 0;
> + vht_oper->basic_mcs_set = vht_cap->vht_mcs.rx_mcs_map;
> +
> + switch (chandef->width) {
> + case NL80211_CHAN_WIDTH_80:
> + vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_80MHZ;
> + break;
> + case NL80211_CHAN_WIDTH_80P80:
> + vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_80P80MHZ;
> + vht_oper->center_freq_seg2_idx =
> + ieee80211_frequency_to_channel(chandef->center_freq2);
> + break;
> + case NL80211_CHAN_WIDTH_160:
> + vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_160MHZ;
> + break;
> + default:
> + return pos;
> + }

Shouldn't you also set vht_oper->basic_mcs_set here? Of course if you
have no use for it in IBSS I can add it later.
Some peers (notably mac80211-based ones) might not use the info, but
others might..

Arik

2015-01-26 09:19:06

by Janusz Dziedzic

[permalink] [raw]
Subject: Re: [RFCv3 4/4] mac80211: add VHT support for IBSS

On 26 January 2015 at 10:00, Johannes Berg <[email protected]> wrote:
> On Mon, 2015-01-26 at 10:37 +0200, Arik Nemtsov wrote:
>
>> >> Shouldn't you also set vht_oper->basic_mcs_set here? Of course if you
>> >> have no use for it in IBSS I can add it later.
>> >
>> > Why would you want to require VHT rates?
>>
>> Are you sure it's required and no the other way around in this case?
>> As in specifying which rates are not supported.
>> Not sure it means the same thing as in the HT instance.
>
> Well, it does mean the same thing ("these rates are required") but it's
> encoded in a way that you have to set it to all-ones (rather than
> all-zeroes) to mean "no requirements", so in that sense you're right.
>

I already set this in the patch:
+ vht_oper->basic_mcs_set = vht_cap->vht_mcs.rx_mcs_map;

BR
Janusz

2015-01-26 08:37:21

by Arik Nemtsov

[permalink] [raw]
Subject: Re: [RFCv3 4/4] mac80211: add VHT support for IBSS

On Mon, Jan 26, 2015 at 10:26 AM, Johannes Berg
<[email protected]> wrote:
> On Sun, 2015-01-25 at 12:30 +0200, Arik Nemtsov wrote:
>
>> > + switch (chandef->width) {
>> > + case NL80211_CHAN_WIDTH_80:
>> > + vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_80MHZ;
>> > + break;
>> > + case NL80211_CHAN_WIDTH_80P80:
>> > + vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_80P80MHZ;
>> > + vht_oper->center_freq_seg2_idx =
>> > + ieee80211_frequency_to_channel(chandef->center_freq2);
>> > + break;
>> > + case NL80211_CHAN_WIDTH_160:
>> > + vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_160MHZ;
>> > + break;
>> > + default:
>> > + return pos;
>> > + }
>>
>> Shouldn't you also set vht_oper->basic_mcs_set here? Of course if you
>> have no use for it in IBSS I can add it later.
>
> Why would you want to require VHT rates?

Are you sure it's required and no the other way around in this case?
As in specifying which rates are not supported.
Not sure it means the same thing as in the HT instance.

Arik

2015-01-26 08:26:27

by Johannes Berg

[permalink] [raw]
Subject: Re: [RFCv3 4/4] mac80211: add VHT support for IBSS

On Sun, 2015-01-25 at 12:25 +0200, Arik Nemtsov wrote:

> >> +u8 *ieee80211_ie_build_vht_oper(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap,
> >> + const struct cfg80211_chan_def *chandef)
> >
> > I still think you should keep this a static function in ibss.c since
> > nobody else is going to use it soon - the only possible user is mesh
> > anyway I think.
>
> Actually TDLS needs to use it pretty soon as well :)

Ok, fair enough.

johannes


2015-01-26 10:01:04

by Janusz Dziedzic

[permalink] [raw]
Subject: Re: [RFCv3 4/4] mac80211: add VHT support for IBSS

On 26 January 2015 at 10:49, Janusz Dziedzic <[email protected]> wrote:
> On 26 January 2015 at 10:25, Johannes Berg <[email protected]> wrote:
>> On Mon, 2015-01-26 at 10:19 +0100, Janusz Dziedzic wrote:
>>> On 26 January 2015 at 10:00, Johannes Berg <[email protected]> wrote:
>>> > On Mon, 2015-01-26 at 10:37 +0200, Arik Nemtsov wrote:
>>> >
>>> >> >> Shouldn't you also set vht_oper->basic_mcs_set here? Of course if you
>>> >> >> have no use for it in IBSS I can add it later.
>>> >> >
>>> >> > Why would you want to require VHT rates?
>>> >>
>>> >> Are you sure it's required and no the other way around in this case?
>>> >> As in specifying which rates are not supported.
>>> >> Not sure it means the same thing as in the HT instance.
>>> >
>>> > Well, it does mean the same thing ("these rates are required") but it's
>>> > encoded in a way that you have to set it to all-ones (rather than
>>> > all-zeroes) to mean "no requirements", so in that sense you're right.
>>> >
>>>
>>> I already set this in the patch:
>>> + vht_oper->basic_mcs_set = vht_cap->vht_mcs.rx_mcs_map;
>>
>> But do you really want to require the local capabilities as basic MCSes?
>>
> I am not sure. Will check spec and how we do that for an AP.
>
The Basic VHT-MCS and NSS Set field indicates the VHT-MCSs for each
number of spatial streams in VHT
PPDUs that are supported by all VHT STAs in the BSS (including IBSS and MBSS).

hostapd set this as: 0xfffc - 1 stream, MCS0-7 as a min Basic VHT MCS
rates - this seems to be secure.

BR
Janusz

2015-01-20 12:36:48

by Janusz Dziedzic

[permalink] [raw]
Subject: [RFCv3 3/4] mac80211: IBSS fix scan request

In case of wide bandwidth scan all channels we have
in chandef, not only control one.

Signed-off-by: Janusz Dziedzic <[email protected]>
---
net/mac80211/ibss.c | 80 ++++++++++++++++++++++++++++++++++++++++++++--
net/mac80211/ieee80211_i.h | 3 +-
net/mac80211/scan.c | 25 +++++++++------
3 files changed, 96 insertions(+), 12 deletions(-)

diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 9fe045f..fda5e2f 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -1277,7 +1277,7 @@ static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata)

scan_width = cfg80211_chandef_to_scan_width(&ifibss->chandef);
ieee80211_request_ibss_scan(sdata, ifibss->ssid, ifibss->ssid_len,
- NULL, scan_width);
+ NULL, 0, scan_width);
}

static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
@@ -1316,6 +1316,75 @@ static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
capability, 0, true);
}

+static unsigned ibss_setup_channels(struct wiphy *wiphy,
+ struct ieee80211_channel **channels,
+ unsigned int channels_max,
+ u32 center_freq, u32 width)
+{
+ struct ieee80211_channel *chan = NULL;
+ unsigned int n_chan = 0;
+ u32 start_freq, end_freq, freq;
+
+ if (width <= 20) {
+ start_freq = center_freq;
+ end_freq = center_freq;
+ } else {
+ start_freq = center_freq - width/2 + 10;
+ end_freq = center_freq + width/2 - 10;
+ }
+
+ for (freq = start_freq; freq <= end_freq; freq += 20) {
+ chan = ieee80211_get_channel(wiphy, freq);
+ if (!chan)
+ continue;
+ if (n_chan >= channels_max)
+ return n_chan;
+
+ channels[n_chan] = chan;
+ n_chan++;
+ }
+
+ return n_chan;
+}
+
+static unsigned int
+ieee80211_ibss_setup_scan_channels(struct wiphy *wiphy,
+ const struct cfg80211_chan_def *chandef,
+ struct ieee80211_channel **channels,
+ unsigned int channels_max)
+{
+ unsigned int n_chan = 0;
+ u32 width, cf1, cf2 = 0;
+
+ switch (chandef->width) {
+ case NL80211_CHAN_WIDTH_40:
+ width = 40;
+ break;
+ case NL80211_CHAN_WIDTH_80P80:
+ cf2 = chandef->center_freq2;
+ case NL80211_CHAN_WIDTH_80:
+ width = 80;
+ break;
+ case NL80211_CHAN_WIDTH_160:
+ width = 160;
+ break;
+ default:
+ width = 20;
+ break;
+ }
+
+ cf1 = chandef->center_freq1;
+
+ n_chan = ibss_setup_channels(wiphy, channels, channels_max, cf1, width);
+
+ if (cf2)
+ n_chan += ibss_setup_channels(wiphy, &channels[n_chan],
+ channels_max - n_chan, cf2,
+ width);
+
+ return n_chan;
+}
+
/*
* This function is called with state == IEEE80211_IBSS_MLME_SEARCH
*/
@@ -1385,11 +1454,18 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
/* Selected IBSS not found in current scan results - try to scan */
if (time_after(jiffies, ifibss->last_scan_completed +
IEEE80211_SCAN_INTERVAL)) {
+ struct ieee80211_channel *channels[8];
+ unsigned int num = 0;
+
sdata_info(sdata, "Trigger new scan to find an IBSS to join\n");

+ num = ieee80211_ibss_setup_scan_channels(local->hw.wiphy,
+ &ifibss->chandef,
+ channels,
+ ARRAY_SIZE(channels));
scan_width = cfg80211_chandef_to_scan_width(&ifibss->chandef);
ieee80211_request_ibss_scan(sdata, ifibss->ssid,
- ifibss->ssid_len, chan,
+ ifibss->ssid_len, channels, num,
scan_width);
} else {
int interval = IEEE80211_SCAN_INTERVAL;
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index cc6e964..9254546 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1558,7 +1558,8 @@ int ieee80211_mesh_finish_csa(struct ieee80211_sub_if_data *sdata);
void ieee80211_scan_work(struct work_struct *work);
int ieee80211_request_ibss_scan(struct ieee80211_sub_if_data *sdata,
const u8 *ssid, u8 ssid_len,
- struct ieee80211_channel *chan,
+ struct ieee80211_channel **channels,
+ unsigned int n_channels,
enum nl80211_bss_scan_width scan_width);
int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata,
struct cfg80211_scan_request *req);
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index ae84267..f76a5d1 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -923,11 +923,12 @@ int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata,

int ieee80211_request_ibss_scan(struct ieee80211_sub_if_data *sdata,
const u8 *ssid, u8 ssid_len,
- struct ieee80211_channel *chan,
+ struct ieee80211_channel **channels,
+ unsigned int n_channels,
enum nl80211_bss_scan_width scan_width)
{
struct ieee80211_local *local = sdata->local;
- int ret = -EBUSY;
+ int ret = -EBUSY, i, n_ch = 0;
enum ieee80211_band band;

mutex_lock(&local->mtx);
@@ -937,9 +938,8 @@ int ieee80211_request_ibss_scan(struct ieee80211_sub_if_data *sdata,
goto unlock;

/* fill internal scan request */
- if (!chan) {
- int i, max_n;
- int n_ch = 0;
+ if (!channels) {
+ int max_n;

for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
if (!local->hw.wiphy->bands[band])
@@ -964,12 +964,19 @@ int ieee80211_request_ibss_scan(struct ieee80211_sub_if_data *sdata,

local->int_scan_req->n_channels = n_ch;
} else {
- if (WARN_ON_ONCE(chan->flags & (IEEE80211_CHAN_NO_IR |
- IEEE80211_CHAN_DISABLED)))
+ for (i = 0; i < n_channels; i++) {
+ if (channels[i]->flags & (IEEE80211_CHAN_NO_IR |
+ IEEE80211_CHAN_DISABLED))
+ continue;
+
+ local->int_scan_req->channels[n_ch] = channels[i];
+ n_ch++;
+ }
+
+ if (WARN_ON_ONCE(n_ch == 0))
goto unlock;

- local->int_scan_req->channels[0] = chan;
- local->int_scan_req->n_channels = 1;
+ local->int_scan_req->n_channels = n_ch;
}

local->int_scan_req->ssids = &local->scan_ssid;
--
1.9.1


2015-01-26 09:25:08

by Johannes Berg

[permalink] [raw]
Subject: Re: [RFCv3 4/4] mac80211: add VHT support for IBSS

On Mon, 2015-01-26 at 10:19 +0100, Janusz Dziedzic wrote:
> On 26 January 2015 at 10:00, Johannes Berg <[email protected]> wrote:
> > On Mon, 2015-01-26 at 10:37 +0200, Arik Nemtsov wrote:
> >
> >> >> Shouldn't you also set vht_oper->basic_mcs_set here? Of course if you
> >> >> have no use for it in IBSS I can add it later.
> >> >
> >> > Why would you want to require VHT rates?
> >>
> >> Are you sure it's required and no the other way around in this case?
> >> As in specifying which rates are not supported.
> >> Not sure it means the same thing as in the HT instance.
> >
> > Well, it does mean the same thing ("these rates are required") but it's
> > encoded in a way that you have to set it to all-ones (rather than
> > all-zeroes) to mean "no requirements", so in that sense you're right.
> >
>
> I already set this in the patch:
> + vht_oper->basic_mcs_set = vht_cap->vht_mcs.rx_mcs_map;

But do you really want to require the local capabilities as basic MCSes?

johannes


2015-01-20 12:36:50

by Janusz Dziedzic

[permalink] [raw]
Subject: [RFCv3 4/4] mac80211: add VHT support for IBSS

Add VHT80/VHT160 support for IBSS.
Drivers could activate this feature by
setting NL80211_FEATURE_VHT_IBSS flag.

Signed-off-by: Janusz Dziedzic <[email protected]>
---
net/mac80211/ibss.c | 41 +++++++++++++++++++++++++++--------------
net/mac80211/ieee80211_i.h | 2 ++
net/mac80211/util.c | 35 +++++++++++++++++++++++++++++++++++
3 files changed, 64 insertions(+), 14 deletions(-)

diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index fda5e2f..e041bde 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -188,6 +188,15 @@ ieee80211_ibss_build_presp(struct ieee80211_sub_if_data *sdata,
*/
pos = ieee80211_ie_build_ht_oper(pos, &sband->ht_cap,
chandef, 0);
+
+ if (chandef->width != NL80211_CHAN_WIDTH_20 &&
+ chandef->width != NL80211_CHAN_WIDTH_40 &&
+ sband->vht_cap.vht_supported) {
+ pos = ieee80211_ie_build_vht_cap(pos, &sband->vht_cap,
+ sband->vht_cap.cap);
+ pos = ieee80211_ie_build_vht_oper(pos, &sband->vht_cap,
+ chandef);
+ }
}

if (local->hw.queues >= IEEE80211_NUM_ACS)
@@ -411,6 +420,11 @@ static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
chan_type = cfg80211_get_chandef_type(&sdata->u.ibss.chandef);
cfg80211_chandef_create(&chandef, cbss->channel, chan_type);
break;
+ case NL80211_CHAN_WIDTH_80:
+ case NL80211_CHAN_WIDTH_160:
+ chandef = sdata->u.ibss.chandef;
+ chandef.chan = cbss->channel;
+ break;
case NL80211_CHAN_WIDTH_5:
case NL80211_CHAN_WIDTH_10:
cfg80211_chandef_create(&chandef, cbss->channel,
@@ -1047,27 +1061,26 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
sdata->u.ibss.chandef.width != NL80211_CHAN_WIDTH_10) {
/* we both use HT */
struct ieee80211_ht_cap htcap_ie;
- struct cfg80211_chan_def chandef;
enum ieee80211_sta_rx_bandwidth bw = sta->sta.bandwidth;

- ieee80211_ht_oper_to_chandef(channel,
- elems->ht_operation,
- &chandef);
-
memcpy(&htcap_ie, elems->ht_cap_elem, sizeof(htcap_ie));

- /*
- * fall back to HT20 if we don't use or use
- * the other extension channel
- */
- if (chandef.center_freq1 !=
- sdata->u.ibss.chandef.center_freq1)
- htcap_ie.cap_info &=
- cpu_to_le16(~IEEE80211_HT_CAP_SUP_WIDTH_20_40);
-
rates_updated |= ieee80211_ht_cap_ie_to_sta_ht_cap(
sdata, sband, &htcap_ie, sta);

+ if (elems->vht_operation && elems->vht_cap_elem &&
+ sdata->u.ibss.chandef.width != NL80211_CHAN_WIDTH_20 &&
+ sdata->u.ibss.chandef.width != NL80211_CHAN_WIDTH_40) {
+ /* we both use VHT */
+ struct ieee80211_vht_cap vhtcap_ie;
+ struct ieee80211_sta_vht_cap vht_cap = sta->sta.vht_cap;
+
+ memcpy(&vhtcap_ie, elems->vht_cap_elem, sizeof(vhtcap_ie));
+ ieee80211_vht_cap_ie_to_sta_vht_cap(sdata, sband, &vhtcap_ie, sta);
+ if (memcmp(&vht_cap, &sta->sta.vht_cap, sizeof(vht_cap)))
+ rates_updated |= true;
+ }
+
if (bw != sta->sta.bandwidth)
rates_updated |= true;
}
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 9254546..9d1967f 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1937,6 +1937,8 @@ u8 *ieee80211_ie_build_ht_oper(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap,
u16 prot_mode);
u8 *ieee80211_ie_build_vht_cap(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap,
u32 cap);
+u8 *ieee80211_ie_build_vht_oper(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap,
+ const struct cfg80211_chan_def *chandef);
int ieee80211_parse_bitrates(struct cfg80211_chan_def *chandef,
const struct ieee80211_supported_band *sband,
const u8 *srates, int srates_len, u32 *rates);
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index bb9664c..3824de7 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -2317,6 +2317,41 @@ u8 *ieee80211_ie_build_ht_oper(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap,
return pos + sizeof(struct ieee80211_ht_operation);
}

+u8 *ieee80211_ie_build_vht_oper(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap,
+ const struct cfg80211_chan_def *chandef)
+{
+ struct ieee80211_vht_operation *vht_oper;
+
+ /* Build VHT Operation */
+ *pos++ = WLAN_EID_VHT_OPERATION;
+ *pos++ = sizeof(struct ieee80211_vht_operation);
+
+ vht_oper = (struct ieee80211_vht_operation *)pos;
+
+ vht_oper->center_freq_seg1_idx =
+ ieee80211_frequency_to_channel(chandef->center_freq1);
+ vht_oper->center_freq_seg2_idx = 0;
+ vht_oper->basic_mcs_set = vht_cap->vht_mcs.rx_mcs_map;
+
+ switch (chandef->width) {
+ case NL80211_CHAN_WIDTH_80:
+ vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_80MHZ;
+ break;
+ case NL80211_CHAN_WIDTH_80P80:
+ vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_80P80MHZ;
+ vht_oper->center_freq_seg2_idx =
+ ieee80211_frequency_to_channel(chandef->center_freq2);
+ break;
+ case NL80211_CHAN_WIDTH_160:
+ vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_160MHZ;
+ break;
+ default:
+ return pos;
+ }
+
+ return pos + sizeof(struct ieee80211_vht_operation);
+}
+
void ieee80211_ht_oper_to_chandef(struct ieee80211_channel *control_chan,
const struct ieee80211_ht_operation *ht_oper,
struct cfg80211_chan_def *chandef)
--
1.9.1


2015-01-23 10:04:57

by Johannes Berg

[permalink] [raw]
Subject: Re: [RFCv3 4/4] mac80211: add VHT support for IBSS

> +++ b/net/mac80211/util.c
> @@ -2317,6 +2317,41 @@ u8 *ieee80211_ie_build_ht_oper(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap,
> return pos + sizeof(struct ieee80211_ht_operation);
> }
>
> +u8 *ieee80211_ie_build_vht_oper(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap,
> + const struct cfg80211_chan_def *chandef)

I still think you should keep this a static function in ibss.c since
nobody else is going to use it soon - the only possible user is mesh
anyway I think.

johannes


2015-01-25 10:25:36

by Arik Nemtsov

[permalink] [raw]
Subject: Re: [RFCv3 4/4] mac80211: add VHT support for IBSS

On Fri, Jan 23, 2015 at 12:04 PM, Johannes Berg
<[email protected]> wrote:
>> +++ b/net/mac80211/util.c
>> @@ -2317,6 +2317,41 @@ u8 *ieee80211_ie_build_ht_oper(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap,
>> return pos + sizeof(struct ieee80211_ht_operation);
>> }
>>
>> +u8 *ieee80211_ie_build_vht_oper(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap,
>> + const struct cfg80211_chan_def *chandef)
>
> I still think you should keep this a static function in ibss.c since
> nobody else is going to use it soon - the only possible user is mesh
> anyway I think.

Actually TDLS needs to use it pretty soon as well :)

Arik

2015-01-23 10:02:09

by Johannes Berg

[permalink] [raw]
Subject: Re: [RFCv3 2/4] cfg80211: add VHT support for IBSS


> /**
> * enum nl80211_ext_feature_index - bit index of extended features.
> + * @NL80211_FEATURE_VHT_IBSS: This driver supports IBSS with VHT datarates.

I think that should be NL80211_EXT_FEATURE_VHT_IBSS to indicate where it
lives.

johannes


2015-01-26 09:00:21

by Johannes Berg

[permalink] [raw]
Subject: Re: [RFCv3 4/4] mac80211: add VHT support for IBSS

On Mon, 2015-01-26 at 10:37 +0200, Arik Nemtsov wrote:

> >> Shouldn't you also set vht_oper->basic_mcs_set here? Of course if you
> >> have no use for it in IBSS I can add it later.
> >
> > Why would you want to require VHT rates?
>
> Are you sure it's required and no the other way around in this case?
> As in specifying which rates are not supported.
> Not sure it means the same thing as in the HT instance.

Well, it does mean the same thing ("these rates are required") but it's
encoded in a way that you have to set it to all-ones (rather than
all-zeroes) to mean "no requirements", so in that sense you're right.

johannes


2015-01-26 08:26:15

by Johannes Berg

[permalink] [raw]
Subject: Re: [RFCv3 4/4] mac80211: add VHT support for IBSS

On Sun, 2015-01-25 at 12:30 +0200, Arik Nemtsov wrote:

> > + switch (chandef->width) {
> > + case NL80211_CHAN_WIDTH_80:
> > + vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_80MHZ;
> > + break;
> > + case NL80211_CHAN_WIDTH_80P80:
> > + vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_80P80MHZ;
> > + vht_oper->center_freq_seg2_idx =
> > + ieee80211_frequency_to_channel(chandef->center_freq2);
> > + break;
> > + case NL80211_CHAN_WIDTH_160:
> > + vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_160MHZ;
> > + break;
> > + default:
> > + return pos;
> > + }
>
> Shouldn't you also set vht_oper->basic_mcs_set here? Of course if you
> have no use for it in IBSS I can add it later.

Why would you want to require VHT rates?

johannes