* [PATCH 1/4] mac80211: fill rate filter for internal scan requests
2011-11-28 17:55 [PATCH 0/4] add HT support for IBSS Simon Wunderlich
@ 2011-11-28 17:55 ` Simon Wunderlich
2011-11-28 18:10 ` Johannes Berg
2011-11-28 17:55 ` [PATCH 2/4] nl80211: Parse channel type attribute in an ibss join request Simon Wunderlich
` (4 subsequent siblings)
5 siblings, 1 reply; 13+ messages in thread
From: Simon Wunderlich @ 2011-11-28 17:55 UTC (permalink / raw)
To: linux-wireless
Cc: linville, Johannes Berg, Mathias Kretschmer, Alexander Simon,
Marek Lindner, Felix Fietkau, Simon Wunderlich
The rates bitmap for internal scan requests shoud be filled,
otherwise there will be probe requests with zero rates supported.
Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
Signed-off-by: Mathias Kretschmer <mathias.kretschmer@fokus.fraunhofer.de>
---
net/mac80211/main.c | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index dddedfa..3e15f75 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -779,6 +779,12 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
if (!local->int_scan_req)
return -ENOMEM;
+ for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
+ if (!local->hw.wiphy->bands[band])
+ continue;
+ local->int_scan_req->rates[band] = (u32) -1;
+ }
+
/* if low-level driver supports AP, we also support VLAN */
if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_AP)) {
hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP_VLAN);
--
1.7.7.3
^ permalink raw reply related [flat|nested] 13+ messages in thread* Re: [PATCH 1/4] mac80211: fill rate filter for internal scan requests
2011-11-28 17:55 ` [PATCH 1/4] mac80211: fill rate filter for internal scan requests Simon Wunderlich
@ 2011-11-28 18:10 ` Johannes Berg
0 siblings, 0 replies; 13+ messages in thread
From: Johannes Berg @ 2011-11-28 18:10 UTC (permalink / raw)
To: Simon Wunderlich
Cc: linux-wireless, linville, Mathias Kretschmer, Alexander Simon,
Marek Lindner, Felix Fietkau, Simon Wunderlich
On Mon, 2011-11-28 at 18:55 +0100, Simon Wunderlich wrote:
> The rates bitmap for internal scan requests shoud be filled,
> otherwise there will be probe requests with zero rates supported.
You should probably send this as a separate bugfix, and maybe even Cc
stable.
johannes
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 2/4] nl80211: Parse channel type attribute in an ibss join request
2011-11-28 17:55 [PATCH 0/4] add HT support for IBSS Simon Wunderlich
2011-11-28 17:55 ` [PATCH 1/4] mac80211: fill rate filter for internal scan requests Simon Wunderlich
@ 2011-11-28 17:55 ` Simon Wunderlich
2011-11-30 12:16 ` Johannes Berg
2011-11-28 17:55 ` [PATCH 3/4] mac80211: Add HT operation modes for IBSS Simon Wunderlich
` (3 subsequent siblings)
5 siblings, 1 reply; 13+ messages in thread
From: Simon Wunderlich @ 2011-11-28 17:55 UTC (permalink / raw)
To: linux-wireless
Cc: linville, Johannes Berg, Mathias Kretschmer, Alexander Simon,
Marek Lindner, Felix Fietkau, Simon Wunderlich
Prepare cfg80211 for IBSS HT:
* extend cfg80211 ibss struct with channel_type
* Check if extension channel can be used
* Export can_beacon_sec_chan for use in mac80211 (will be called
from ibss.c later).
Signed-off-by: Alexander Simon <an.alexsimon@googlemail.com>
[siwu@hrz.tu-chemnitz.de: Updates]
* fix cfg80211_can_beacon_ext_chan comment
* remove implicit channel_type enum assumptions
* remove radar channel flags check
* reword commit message
Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
Signed-off-by: Mathias Kretschmer <mathias.kretschmer@fokus.fraunhofer.de>
---
include/net/cfg80211.h | 11 +++++++++++
net/wireless/chan.c | 12 +++++++-----
net/wireless/nl80211.c | 27 +++++++++++++++++++++++++--
3 files changed, 43 insertions(+), 7 deletions(-)
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index d5e1891..d77c6ad 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1146,6 +1146,7 @@ struct cfg80211_ibss_params {
u8 *ssid;
u8 *bssid;
struct ieee80211_channel *channel;
+ enum nl80211_channel_type channel_type;
u8 *ie;
u8 ssid_len, ie_len;
u16 beacon_interval;
@@ -3257,6 +3258,16 @@ void cfg80211_report_obss_beacon(struct wiphy *wiphy,
const u8 *frame, size_t len,
int freq, gfp_t gfp);
+/*
+ * cfg80211_can_beacon_sec_chan - test if ht40 on extension channel can be used
+ * @wiphy: the wiphy
+ * @chan: main channel
+ * @channel_type: HT mode
+ */
+int cfg80211_can_beacon_sec_chan(struct wiphy *wiphy,
+ struct ieee80211_channel *chan,
+ enum nl80211_channel_type channel_type);
+
/* Logging, debugging and troubleshooting/diagnostic helpers. */
/* wiphy_printk helpers, similar to dev_printk */
diff --git a/net/wireless/chan.c b/net/wireless/chan.c
index 17cd0c0..2fcfe09 100644
--- a/net/wireless/chan.c
+++ b/net/wireless/chan.c
@@ -6,6 +6,7 @@
* Copyright 2009 Johannes Berg <johannes@sipsolutions.net>
*/
+#include <linux/export.h>
#include <net/cfg80211.h>
#include "core.h"
@@ -44,9 +45,9 @@ rdev_freq_to_chan(struct cfg80211_registered_device *rdev,
return chan;
}
-static bool can_beacon_sec_chan(struct wiphy *wiphy,
- struct ieee80211_channel *chan,
- enum nl80211_channel_type channel_type)
+int cfg80211_can_beacon_sec_chan(struct wiphy *wiphy,
+ struct ieee80211_channel *chan,
+ enum nl80211_channel_type channel_type)
{
struct ieee80211_channel *sec_chan;
int diff;
@@ -75,6 +76,7 @@ static bool can_beacon_sec_chan(struct wiphy *wiphy,
return true;
}
+EXPORT_SYMBOL(cfg80211_can_beacon_sec_chan);
int cfg80211_set_freq(struct cfg80211_registered_device *rdev,
struct wireless_dev *wdev, int freq,
@@ -109,8 +111,8 @@ int cfg80211_set_freq(struct cfg80211_registered_device *rdev,
switch (channel_type) {
case NL80211_CHAN_HT40PLUS:
case NL80211_CHAN_HT40MINUS:
- if (!can_beacon_sec_chan(&rdev->wiphy, chan,
- channel_type)) {
+ if (!cfg80211_can_beacon_sec_chan(&rdev->wiphy, chan,
+ channel_type)) {
printk(KERN_DEBUG
"cfg80211: Secondary channel not "
"allowed to initiate communication\n");
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index a1cabde..d675398 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -4657,13 +4657,36 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
ibss.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
}
- ibss.channel = ieee80211_get_channel(wiphy,
- nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
+ if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
+ enum nl80211_channel_type channel_type;
+
+ channel_type = nla_get_u32(
+ info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]);
+ if (channel_type != NL80211_CHAN_NO_HT &&
+ channel_type != NL80211_CHAN_HT20 &&
+ channel_type != NL80211_CHAN_HT40MINUS &&
+ channel_type != NL80211_CHAN_HT40PLUS)
+ return -EINVAL;
+ ibss.channel_type = channel_type;
+ } else {
+ ibss.channel_type = NL80211_CHAN_NO_HT;
+ }
+
+ ibss.channel = rdev_freq_to_chan(rdev,
+ nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]),
+ ibss.channel_type);
if (!ibss.channel ||
ibss.channel->flags & IEEE80211_CHAN_NO_IBSS ||
ibss.channel->flags & IEEE80211_CHAN_DISABLED)
return -EINVAL;
+ /* Both channels should be able to initiate communication */
+ if ((ibss.channel_type == NL80211_CHAN_HT40PLUS ||
+ ibss.channel_type == NL80211_CHAN_HT40MINUS) &&
+ !cfg80211_can_beacon_sec_chan(&rdev->wiphy, ibss.channel,
+ ibss.channel_type))
+ return -EINVAL;
+
ibss.channel_fixed = !!info->attrs[NL80211_ATTR_FREQ_FIXED];
ibss.privacy = !!info->attrs[NL80211_ATTR_PRIVACY];
--
1.7.7.3
^ permalink raw reply related [flat|nested] 13+ messages in thread* Re: [PATCH 2/4] nl80211: Parse channel type attribute in an ibss join request
2011-11-28 17:55 ` [PATCH 2/4] nl80211: Parse channel type attribute in an ibss join request Simon Wunderlich
@ 2011-11-30 12:16 ` Johannes Berg
2011-11-30 12:27 ` Simon Wunderlich
0 siblings, 1 reply; 13+ messages in thread
From: Johannes Berg @ 2011-11-30 12:16 UTC (permalink / raw)
To: Simon Wunderlich
Cc: linux-wireless, linville, Mathias Kretschmer, Alexander Simon,
Marek Lindner, Felix Fietkau, Simon Wunderlich
On Mon, 2011-11-28 at 18:55 +0100, Simon Wunderlich wrote:
> Prepare cfg80211 for IBSS HT:
> * extend cfg80211 ibss struct with channel_type
> * Check if extension channel can be used
> * Export can_beacon_sec_chan for use in mac80211 (will be called
> from ibss.c later).
I'm thinking there should be a "driver supports HT IBSS" flag, and we
reject the config otherwise?
johannes
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 2/4] nl80211: Parse channel type attribute in an ibss join request
2011-11-30 12:16 ` Johannes Berg
@ 2011-11-30 12:27 ` Simon Wunderlich
2011-11-30 12:30 ` Johannes Berg
0 siblings, 1 reply; 13+ messages in thread
From: Simon Wunderlich @ 2011-11-30 12:27 UTC (permalink / raw)
To: Johannes Berg
Cc: Simon Wunderlich, linux-wireless, linville, Mathias Kretschmer,
Alexander Simon, Marek Lindner, Felix Fietkau, Simon Wunderlich
[-- Attachment #1: Type: text/plain, Size: 833 bytes --]
Hey Johannes,
On Wed, Nov 30, 2011 at 01:16:46PM +0100, Johannes Berg wrote:
> On Mon, 2011-11-28 at 18:55 +0100, Simon Wunderlich wrote:
> > Prepare cfg80211 for IBSS HT:
> > * extend cfg80211 ibss struct with channel_type
> > * Check if extension channel can be used
> > * Export can_beacon_sec_chan for use in mac80211 (will be called
> > from ibss.c later).
>
> I'm thinking there should be a "driver supports HT IBSS" flag, and we
> reject the config otherwise?
There is already an implicit check for this - rdev_freq_to_chan() checks
if the channel_type is supported, and -EINVAL otherwise. So if I call
ibss_join with HT20 or HT40 on ath5k, it gets rejected already.
If this is not enough and we need a further flag, could you please give
me a hint how/where to implement it?
regards,
Simon
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 2/4] nl80211: Parse channel type attribute in an ibss join request
2011-11-30 12:27 ` Simon Wunderlich
@ 2011-11-30 12:30 ` Johannes Berg
0 siblings, 0 replies; 13+ messages in thread
From: Johannes Berg @ 2011-11-30 12:30 UTC (permalink / raw)
To: Simon Wunderlich
Cc: linux-wireless, linville, Mathias Kretschmer, Alexander Simon,
Marek Lindner, Felix Fietkau, Simon Wunderlich
On Wed, 2011-11-30 at 13:27 +0100, Simon Wunderlich wrote:
> Hey Johannes,
>
> On Wed, Nov 30, 2011 at 01:16:46PM +0100, Johannes Berg wrote:
> > On Mon, 2011-11-28 at 18:55 +0100, Simon Wunderlich wrote:
> > > Prepare cfg80211 for IBSS HT:
> > > * extend cfg80211 ibss struct with channel_type
> > > * Check if extension channel can be used
> > > * Export can_beacon_sec_chan for use in mac80211 (will be called
> > > from ibss.c later).
> >
> > I'm thinking there should be a "driver supports HT IBSS" flag, and we
> > reject the config otherwise?
>
> There is already an implicit check for this - rdev_freq_to_chan() checks
> if the channel_type is supported, and -EINVAL otherwise. So if I call
> ibss_join with HT20 or HT40 on ath5k, it gets rejected already.
Right, but this just checks if HT is supported, not if HT-IBSS is
supported. I can see some cfg80211 drivers implementing HT and IBSS, but
not HT-IBSS, just like mac80211 before these patches.
> If this is not enough and we need a further flag, could you please give
> me a hint how/where to implement it?
I'd add it to enum nl80211_feature_flags.
johannes
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 3/4] mac80211: Add HT operation modes for IBSS
2011-11-28 17:55 [PATCH 0/4] add HT support for IBSS Simon Wunderlich
2011-11-28 17:55 ` [PATCH 1/4] mac80211: fill rate filter for internal scan requests Simon Wunderlich
2011-11-28 17:55 ` [PATCH 2/4] nl80211: Parse channel type attribute in an ibss join request Simon Wunderlich
@ 2011-11-28 17:55 ` Simon Wunderlich
2011-11-28 17:55 ` [PATCH 4/4] mac80211: handle protection mode, RIFS and ADDBA for HT IBSS Simon Wunderlich
` (2 subsequent siblings)
5 siblings, 0 replies; 13+ messages in thread
From: Simon Wunderlich @ 2011-11-28 17:55 UTC (permalink / raw)
To: linux-wireless
Cc: linville, Johannes Berg, Mathias Kretschmer, Alexander Simon,
Marek Lindner, Felix Fietkau, Simon Wunderlich
The HT mode is set by iw (previous patchsets).
The interface is set into the specified HT mode.
HT mode and capabilities are announced in beacons.
If we add a station that uses HT also, the fastest matching HT mode will
be used for transmission. That means if we are using HT40+ and we add a station
running on HT40-, we would transfer at HT20.
If we join an IBSS with HT40, but the secondary channel is not
available, we will fall back into HT20 as well.
Allow frame aggregation to start in IBSS mode.
Signed-off-by: Alexander Simon <an.alexsimon@googlemail.com>
[siwu@hrz.tu-chemnitz.de: Updates]
* remove implicit channel_type enum assumptions
* use rate_control_rate_init() if channel type changed
* remove channel flags check
* slightly reword commit message
* rebase on wireless-testing
Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
Signed-off-by: Mathias Kretschmer <mathias.kretschmer@fokus.fraunhofer.de>
---
net/mac80211/agg-rx.c | 2 +
net/mac80211/agg-tx.c | 5 ++-
net/mac80211/ht.c | 2 +
net/mac80211/ibss.c | 83 +++++++++++++++++++++++++++++++++++++++-----
net/mac80211/ieee80211_i.h | 1 +
net/mac80211/rx.c | 3 +-
6 files changed, 85 insertions(+), 11 deletions(-)
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c
index 476b106..7571be2 100644
--- a/net/mac80211/agg-rx.c
+++ b/net/mac80211/agg-rx.c
@@ -182,6 +182,8 @@ static void ieee80211_send_addba_resp(struct ieee80211_sub_if_data *sdata, u8 *d
memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
else if (sdata->vif.type == NL80211_IFTYPE_STATION)
memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN);
+ else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
+ memcpy(mgmt->bssid, sdata->u.ibss.bssid, ETH_ALEN);
mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
IEEE80211_STYPE_ACTION);
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index 39d72cc..41b9bfd 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -83,6 +83,8 @@ static void ieee80211_send_addba_request(struct ieee80211_sub_if_data *sdata,
memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
else if (sdata->vif.type == NL80211_IFTYPE_STATION)
memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN);
+ else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
+ memcpy(mgmt->bssid, sdata->u.ibss.bssid, ETH_ALEN);
mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
IEEE80211_STYPE_ACTION);
@@ -376,7 +378,8 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid,
if (sdata->vif.type != NL80211_IFTYPE_STATION &&
sdata->vif.type != NL80211_IFTYPE_MESH_POINT &&
sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
- sdata->vif.type != NL80211_IFTYPE_AP)
+ sdata->vif.type != NL80211_IFTYPE_AP &&
+ sdata->vif.type != NL80211_IFTYPE_ADHOC)
return -EINVAL;
if (test_sta_flag(sta, WLAN_STA_BLOCK_BA)) {
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c
index 810cfbe..14c2893 100644
--- a/net/mac80211/ht.c
+++ b/net/mac80211/ht.c
@@ -282,6 +282,8 @@ void ieee80211_send_delba(struct ieee80211_sub_if_data *sdata,
memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
else if (sdata->vif.type == NL80211_IFTYPE_STATION)
memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN);
+ else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
+ memcpy(mgmt->bssid, sdata->u.ibss.bssid, ETH_ALEN);
mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
IEEE80211_STYPE_ACTION);
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 7d84af7..1e4fd0f 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -77,6 +77,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
struct cfg80211_bss *bss;
u32 bss_change;
u8 supp_rates[IEEE80211_MAX_SUPP_RATES];
+ enum nl80211_channel_type channel_type;
lockdep_assert_held(&ifibss->mtx);
@@ -105,8 +106,16 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
sdata->drop_unencrypted = capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0;
- local->oper_channel = chan;
- WARN_ON(!ieee80211_set_channel_type(local, sdata, NL80211_CHAN_NO_HT));
+ channel_type = ifibss->channel_type;
+ if (channel_type > NL80211_CHAN_HT20 &&
+ !cfg80211_can_beacon_sec_chan(local->hw.wiphy, chan, channel_type))
+ channel_type = NL80211_CHAN_HT20;
+ if (!ieee80211_set_channel_type(local, sdata, channel_type)) {
+ /* can only fail due to HT40+/- mismatch */
+ channel_type = NL80211_CHAN_HT20;
+ WARN_ON(!ieee80211_set_channel_type(local, sdata,
+ NL80211_CHAN_HT20));
+ }
ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
sband = local->hw.wiphy->bands[chan->band];
@@ -172,6 +181,19 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
memcpy(skb_put(skb, ifibss->ie_len),
ifibss->ie, ifibss->ie_len);
+ /* add HT capability and information IEs */
+ if (channel_type && sband->ht_cap.ht_supported) {
+ pos = skb_put(skb, 4 +
+ sizeof(struct ieee80211_ht_cap) +
+ sizeof(struct ieee80211_ht_info));
+ pos = ieee80211_ie_build_ht_cap(pos, &sband->ht_cap,
+ sband->ht_cap.cap);
+ pos = ieee80211_ie_build_ht_info(pos,
+ &sband->ht_cap,
+ chan,
+ channel_type);
+ }
+
if (local->hw.queues >= 4) {
pos = skb_put(skb, 9);
*pos++ = WLAN_EID_VENDOR_SPECIFIC;
@@ -195,6 +217,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
bss_change |= BSS_CHANGED_BEACON;
bss_change |= BSS_CHANGED_BEACON_ENABLED;
bss_change |= BSS_CHANGED_BASIC_RATES;
+ bss_change |= BSS_CHANGED_HT;
bss_change |= BSS_CHANGED_IBSS;
sdata->vif.bss_conf.ibss_joined = true;
ieee80211_bss_info_change_notify(sdata, bss_change);
@@ -268,6 +291,8 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
u64 beacon_timestamp, rx_timestamp;
u32 supp_rates = 0;
enum ieee80211_band band = rx_status->band;
+ struct ieee80211_supported_band *sband = local->hw.wiphy->bands[band];
+ bool rates_updated = false;
if (elems->ds_params && elems->ds_params_len == 1)
freq = ieee80211_channel_to_frequency(elems->ds_params[0],
@@ -307,7 +332,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
prev_rates,
sta->sta.supp_rates[band]);
#endif
- rate_control_rate_init(sta);
+ rates_updated = true;
}
} else
sta = ieee80211_ibss_add_sta(sdata, mgmt->bssid,
@@ -318,6 +343,39 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
if (sta && elems->wmm_info)
set_sta_flag(sta, WLAN_STA_WME);
+ if (sta && elems->ht_info_elem && elems->ht_cap_elem &&
+ sdata->u.ibss.channel_type != NL80211_CHAN_NO_HT) {
+ /* we both use HT */
+ struct ieee80211_sta_ht_cap sta_ht_cap_new;
+ enum nl80211_channel_type channel_type =
+ ieee80211_ht_info_to_channel_type(
+ elems->ht_info_elem);
+
+ ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband,
+ elems->ht_cap_elem,
+ &sta_ht_cap_new);
+
+ /*
+ * fall back to HT20 if we don't use or use
+ * the other extension channel
+ */
+ if ((channel_type == NL80211_CHAN_HT40MINUS ||
+ channel_type == NL80211_CHAN_HT40PLUS) &&
+ channel_type != sdata->u.ibss.channel_type)
+ sta_ht_cap_new.cap &=
+ ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
+
+ if (memcmp(&sta->sta.ht_cap, &sta_ht_cap_new,
+ sizeof(sta_ht_cap_new))) {
+ memcpy(&sta->sta.ht_cap, &sta_ht_cap_new,
+ sizeof(sta_ht_cap_new));
+ rates_updated = true;
+ }
+ }
+
+ if (sta && rates_updated)
+ rate_control_rate_init(sta);
+
rcu_read_unlock();
}
@@ -898,10 +956,15 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
struct sk_buff *skb;
skb = dev_alloc_skb(sdata->local->hw.extra_tx_headroom +
- 36 /* bitrates */ +
- 34 /* SSID */ +
- 3 /* DS params */ +
- 4 /* IBSS params */ +
+ sizeof(struct ieee80211_hdr_3addr) +
+ 12 /* struct ieee80211_mgmt.u.beacon */ +
+ 2 + IEEE80211_MAX_SSID_LEN /* max SSID */ +
+ 2 + 8 /* max Supported Rates */ +
+ 3 /* max DS params */ +
+ 4 /* IBSS params */ +
+ 2 + (IEEE80211_MAX_SUPP_RATES - 8) +
+ 2 + sizeof(struct ieee80211_ht_cap) +
+ 2 + sizeof(struct ieee80211_ht_info) +
params->ie_len);
if (!skb)
return -ENOMEM;
@@ -922,13 +985,15 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
sdata->vif.bss_conf.beacon_int = params->beacon_interval;
sdata->u.ibss.channel = params->channel;
+ sdata->u.ibss.channel_type = params->channel_type;
sdata->u.ibss.fixed_channel = params->channel_fixed;
/* fix ourselves to that channel now already */
if (params->channel_fixed) {
sdata->local->oper_channel = params->channel;
- WARN_ON(!ieee80211_set_channel_type(sdata->local, sdata,
- NL80211_CHAN_NO_HT));
+ if (!ieee80211_set_channel_type(sdata->local, sdata,
+ params->channel_type))
+ return -EINVAL;
}
if (params->ie) {
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 762243e..c4af994 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -474,6 +474,7 @@ struct ieee80211_if_ibss {
u8 ssid_len, ie_len;
u8 *ie;
struct ieee80211_channel *channel;
+ enum nl80211_channel_type channel_type;
unsigned long ibss_join_req;
/* probe response/beacon for IBSS */
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index d1a8869..17d7aa3 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -2250,7 +2250,8 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
if (sdata->vif.type != NL80211_IFTYPE_STATION &&
sdata->vif.type != NL80211_IFTYPE_MESH_POINT &&
sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
- sdata->vif.type != NL80211_IFTYPE_AP)
+ sdata->vif.type != NL80211_IFTYPE_AP &&
+ sdata->vif.type != NL80211_IFTYPE_ADHOC)
break;
/* verify action_code is present */
--
1.7.7.3
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH 4/4] mac80211: handle protection mode, RIFS and ADDBA for HT IBSS
2011-11-28 17:55 [PATCH 0/4] add HT support for IBSS Simon Wunderlich
` (2 preceding siblings ...)
2011-11-28 17:55 ` [PATCH 3/4] mac80211: Add HT operation modes for IBSS Simon Wunderlich
@ 2011-11-28 17:55 ` Simon Wunderlich
2011-11-30 12:16 ` Johannes Berg
2011-11-28 17:55 ` [PATCH] iw: add HT options for ibss Simon Wunderlich
2011-11-30 11:32 ` [PATCH 0/4] add HT support for IBSS Simon Wunderlich
5 siblings, 1 reply; 13+ messages in thread
From: Simon Wunderlich @ 2011-11-28 17:55 UTC (permalink / raw)
To: linux-wireless
Cc: linville, Johannes Berg, Mathias Kretschmer, Alexander Simon,
Marek Lindner, Felix Fietkau, Simon Wunderlich
* Follow 802.11n-2009 9.13.3.1 for protection mode and ADDBA
* Send ADDBA only to HT STAs - implement 11.5.1.1 partially
Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
Signed-off-by: Mathias Kretschmer <mathias.kretschmer@fokus.fraunhofer.de>
---
net/mac80211/agg-tx.c | 21 +++++++++++++++++++++
net/mac80211/ibss.c | 18 ++++++++++++++++++
net/mac80211/util.c | 3 +++
3 files changed, 42 insertions(+), 0 deletions(-)
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index 41b9bfd..c85c369 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -390,6 +390,27 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid,
return -EINVAL;
}
+ /*
+ * 11.5.1.1: If the initiating STA is an HT STA, is a member of an
+ * IBSS, and has no other existing Block Ack agreement with the
+ * recipient STA, then the initiating STA shall transmit a Probe
+ * Request frame to the recipient STA and shall not transmit an
+ * ADDBA Request frame unless it receives a Probe Response frame
+ * from the recipient within dot11ADDBAFailureTimeout.
+ *
+ * The probe request mechanism for ADDBA is currently not implemented,
+ * but we only build up Block Ack session with HT STAs. This information
+ * is set when we receive a bss info from a probe response or a beacon.
+ */
+ if (sta->sdata->vif.type == NL80211_IFTYPE_ADHOC &&
+ !sta->sta.ht_cap.ht_supported) {
+#ifdef CONFIG_MAC80211_HT_DEBUG
+ printk(KERN_DEBUG "BA request denied - IBSS STA %pM"
+ "does not advertise HT support\n", pubsta->addr);
+#endif /* CONFIG_MAC80211_HT_DEBUG */
+ return -EINVAL;
+ }
+
spin_lock_bh(&sta->lock);
/* we have tried too many times, receiver does not want A-MPDU */
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 1e4fd0f..ea424de 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -954,6 +954,7 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
struct cfg80211_ibss_params *params)
{
struct sk_buff *skb;
+ u32 changed = 0;
skb = dev_alloc_skb(sdata->local->hw.extra_tx_headroom +
sizeof(struct ieee80211_hdr_3addr) +
@@ -1016,6 +1017,23 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
ieee80211_recalc_idle(sdata->local);
mutex_unlock(&sdata->local->mtx);
+ /*
+ * 9.13.3.1: In an IBSS, the HT Protection field is reserved, but
+ * an HT STA shall protect HT transmissions as though the HT
+ * Protection field were set to non-HT mixed mode.
+ *
+ * In an IBSS, the RIFS Mode field of the HT Operation element is
+ * also reserved, but an HT STA shall operate as though this field
+ * were set to 1.
+ */
+
+ sdata->vif.bss_conf.ht_operation_mode |=
+ IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED
+ | IEEE80211_HT_PARAM_RIFS_MODE;
+
+ changed |= BSS_CHANGED_HT;
+ ieee80211_bss_info_change_notify(sdata, changed);
+
ieee80211_queue_work(&sdata->local->hw, &sdata->work);
return 0;
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 3b9b492..c26e968 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1585,6 +1585,9 @@ u8 *ieee80211_ie_build_ht_info(u8 *pos,
}
if (ht_cap->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)
ht_info->ht_param |= IEEE80211_HT_PARAM_CHAN_WIDTH_ANY;
+
+ /* Note: According to 9.13.3.1, HT Protection field and RIFS Mode
+ * are reserved in IBSS mode, therefore keep them at 0 */
ht_info->operation_mode = 0x0000;
ht_info->stbc_param = 0x0000;
--
1.7.7.3
^ permalink raw reply related [flat|nested] 13+ messages in thread* Re: [PATCH 4/4] mac80211: handle protection mode, RIFS and ADDBA for HT IBSS
2011-11-28 17:55 ` [PATCH 4/4] mac80211: handle protection mode, RIFS and ADDBA for HT IBSS Simon Wunderlich
@ 2011-11-30 12:16 ` Johannes Berg
2011-11-30 12:42 ` Simon Wunderlich
0 siblings, 1 reply; 13+ messages in thread
From: Johannes Berg @ 2011-11-30 12:16 UTC (permalink / raw)
To: Simon Wunderlich
Cc: linux-wireless, linville, Mathias Kretschmer, Alexander Simon,
Marek Lindner, Felix Fietkau, Simon Wunderlich
On Mon, 2011-11-28 at 18:55 +0100, Simon Wunderlich wrote:
> + /*
> + * 11.5.1.1: If the initiating STA is an HT STA, is a member of an
802.11-2012 will renumber clauses, please add new references as
"802.11-2007 11.5.1.1"
Other than that I have a feeling this patch should come before patch 3?
> +++ b/net/mac80211/ibss.c
> @@ -954,6 +954,7 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
> struct cfg80211_ibss_params *params)
> {
> struct sk_buff *skb;
> + u32 changed = 0;
>
> skb = dev_alloc_skb(sdata->local->hw.extra_tx_headroom +
> sizeof(struct ieee80211_hdr_3addr) +
> @@ -1016,6 +1017,23 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
> ieee80211_recalc_idle(sdata->local);
> mutex_unlock(&sdata->local->mtx);
>
> + /*
> + * 9.13.3.1: In an IBSS, the HT Protection field is reserved, but
Same reference thing here.
johannes
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: [PATCH 4/4] mac80211: handle protection mode, RIFS and ADDBA for HT IBSS
2011-11-30 12:16 ` Johannes Berg
@ 2011-11-30 12:42 ` Simon Wunderlich
0 siblings, 0 replies; 13+ messages in thread
From: Simon Wunderlich @ 2011-11-30 12:42 UTC (permalink / raw)
To: Johannes Berg
Cc: Simon Wunderlich, linux-wireless, linville, Mathias Kretschmer,
Alexander Simon, Marek Lindner, Felix Fietkau, Simon Wunderlich
[-- Attachment #1: Type: text/plain, Size: 603 bytes --]
On Wed, Nov 30, 2011 at 01:16:15PM +0100, Johannes Berg wrote:
> On Mon, 2011-11-28 at 18:55 +0100, Simon Wunderlich wrote:
>
> > + /*
> > + * 11.5.1.1: If the initiating STA is an HT STA, is a member of an
>
> 802.11-2012 will renumber clauses, please add new references as
> "802.11-2007 11.5.1.1"
Ok, I will change the references but will use 802.11n-2009 instead of 802.11-2007.
This stuff is not written in 802.11-2007 after all.
>
> Other than that I have a feeling this patch should come before patch 3?
>
OK, will change the order in the next resend.
Thanks!
Simon
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH] iw: add HT options for ibss
2011-11-28 17:55 [PATCH 0/4] add HT support for IBSS Simon Wunderlich
` (3 preceding siblings ...)
2011-11-28 17:55 ` [PATCH 4/4] mac80211: handle protection mode, RIFS and ADDBA for HT IBSS Simon Wunderlich
@ 2011-11-28 17:55 ` Simon Wunderlich
2011-11-30 11:32 ` [PATCH 0/4] add HT support for IBSS Simon Wunderlich
5 siblings, 0 replies; 13+ messages in thread
From: Simon Wunderlich @ 2011-11-28 17:55 UTC (permalink / raw)
To: linux-wireless
Cc: linville, Johannes Berg, Mathias Kretschmer, Alexander Simon,
Marek Lindner, Felix Fietkau, Simon Wunderlich
Allow to set a specific HT mode for ibss_join.
Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
Signed-off-by: Mathias Kretschmer <mathias.kretschmer@fokus.fraunhofer.de>
---
ibss.c | 31 ++++++++++++++++++++++++++++++-
1 files changed, 30 insertions(+), 1 deletions(-)
diff --git a/ibss.c b/ibss.c
index b70dee3..4b43095 100644
--- a/ibss.c
+++ b/ibss.c
@@ -3,6 +3,7 @@
#endif
#include <errno.h>
#include <string.h>
+#include <strings.h>
#include <netlink/genl/genl.h>
#include <netlink/genl/family.h>
@@ -27,6 +28,18 @@ static int join_ibss(struct nl80211_state *state,
char *value = NULL, *sptr = NULL;
float rate;
int bintval;
+ int i;
+ static const struct {
+ const char *name;
+ unsigned int val;
+ } htmap[] = {
+ { .name = "HT20", .val = NL80211_CHAN_HT20, },
+ { .name = "HT40+", .val = NL80211_CHAN_HT40PLUS, },
+ { .name = "HT40-", .val = NL80211_CHAN_HT40MINUS, },
+ { .name = "NOHT", .val = NL80211_CHAN_NO_HT, },
+ };
+ unsigned int htval = NL80211_CHAN_NO_HT;
+
if (argc < 2)
return 1;
@@ -44,6 +57,22 @@ static int join_ibss(struct nl80211_state *state,
argv++;
argc--;
+ if (argc) {
+ for (i = 0; i < ARRAY_SIZE(htmap); i++) {
+ if (strcasecmp(htmap[i].name, argv[0]) == 0) {
+ htval = htmap[i].val;
+ break;
+ }
+ }
+ if (i != ARRAY_SIZE(htmap)) {
+ NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
+ htval);
+ argv++;
+ argc--;
+ }
+
+ }
+
if (argc && strcmp(argv[0], "fixed-freq") == 0) {
NLA_PUT_FLAG(msg, NL80211_ATTR_FREQ_FIXED);
argv++;
@@ -134,7 +163,7 @@ COMMAND(ibss, leave, NULL,
NL80211_CMD_LEAVE_IBSS, 0, CIB_NETDEV, leave_ibss,
"Leave the current IBSS cell.");
COMMAND(ibss, join,
- "<SSID> <freq in MHz> [fixed-freq] [<fixed bssid>] [beacon-interval <TU>]"
+ "<SSID> <freq in MHz> [HT20|HT40+|HT40-|NOHT] [fixed-freq] [<fixed bssid>] [beacon-interval <TU>]"
" [basic-rates <rate in Mbps,rate2,...>] [mcast-rate <rate in Mbps>] "
"[key d:0:abcde]",
NL80211_CMD_JOIN_IBSS, 0, CIB_NETDEV, join_ibss,
--
1.7.7.3
^ permalink raw reply related [flat|nested] 13+ messages in thread* Re: [PATCH 0/4] add HT support for IBSS
2011-11-28 17:55 [PATCH 0/4] add HT support for IBSS Simon Wunderlich
` (4 preceding siblings ...)
2011-11-28 17:55 ` [PATCH] iw: add HT options for ibss Simon Wunderlich
@ 2011-11-30 11:32 ` Simon Wunderlich
5 siblings, 0 replies; 13+ messages in thread
From: Simon Wunderlich @ 2011-11-30 11:32 UTC (permalink / raw)
To: Simon Wunderlich
Cc: linux-wireless, linville, Johannes Berg, Mathias Kretschmer,
Alexander Simon, Marek Lindner, Felix Fietkau, Simon Wunderlich
[-- Attachment #1: Type: text/plain, Size: 3551 bytes --]
Hey there,
thanks for the comments so far. I'll send the scan request patch again separately.
Furthermore, I have to apologize: I've accidently messed up the author flag of
Alex' Patches, therefore as they are, they look like I'm the original author
now (at least for the git attributes and the cover letter). I'm really sorry
about this and will fix it in a v2.
Thanks,
Simon
On Mon, Nov 28, 2011 at 06:55:12PM +0100, Simon Wunderlich wrote:
> This patch set adds support for HT datarates in IBSS. It is based on Alexander
> Simons previous work. The changes can be found in the individual patch messages.
>
> The first patch fixes probe requests sending no rates supported (at least
> wireshark does not find this funny). The second patch adds support for nl80211.
> Feature checking is implicitly performed through rdev_freq_to_chan(), which
> denies the configuration if HT support is not available. The third patch adds
> the mac80211 ibss support. Finally, further IEEE 802.11 standard compatibility
> questions are adressed in the fourth patch.
>
> The HT configuration set through nl80211 is not adopted from other STAs as the
> standard (10.3.2.2.2/11.14.2) suggests - after several discussion with other
> developers, we agreed that this may lead to unpredictable behaviour. We prefer
> to keep the local configuration and adapt the HT parameters for transmission
> to other STAs individually.
>
> For further standard compatibility (see fourth patch):
> * 9.13.3.1: IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED is set and may
> be used, so far only a few drivers consider it (iwl*, rt2x00, wl12xx,
> brcm80211, mwl8k)
> * 9.13.3.1: IEEE80211_HT_PARAM_RIFS_MODE is set and may be used, so far
> no driver seems to consider it.
> * 11.5.1.1: BA is only allowed when we previously received a probe response
> or beacon with HT information. Therefore, this is partially implemented
> - we don't implement a probe request. However, this should serve the same
> purpose IMHO and and avoids sending the ADDBA requests to legacy stations.
>
> I have tested this feature in an IBSS of two ath9k and one ath5k device. The
> devices join the cell succesfully and the ath9k use HT40 if the configuration
> matches (I've measured 70 Mbit/s) or HT20 (~40 Mbit/s) if it does not.
> Also the (legacy) communication to ath5k works.
>
> There is an iw patch as well to make use of this feature.
>
> It should apply well on the latest wireless-testing kernel.
>
> Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
> Signed-off-by: Mathias Kretschmer <mathias.kretschmer@fokus.fraunhofer.de>
>
> Simon Wunderlich (4):
> mac80211: fill rate filter for internal scan requests
> nl80211: Parse channel type attribute in an ibss join request
> mac80211: Add HT operation modes for IBSS
> mac80211: handle protection mode, RIFS and ADDBA for HT IBSS
>
> include/net/cfg80211.h | 11 +++++
> net/mac80211/agg-rx.c | 2 +
> net/mac80211/agg-tx.c | 26 +++++++++++-
> net/mac80211/ht.c | 2 +
> net/mac80211/ibss.c | 101 ++++++++++++++++++++++++++++++++++++++++----
> net/mac80211/ieee80211_i.h | 1 +
> net/mac80211/main.c | 6 +++
> net/mac80211/rx.c | 3 +-
> net/mac80211/util.c | 3 +
> net/wireless/chan.c | 12 +++--
> net/wireless/nl80211.c | 27 +++++++++++-
> 11 files changed, 176 insertions(+), 18 deletions(-)
>
> --
> 1.7.7.3
>
>
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]
^ permalink raw reply [flat|nested] 13+ messages in thread