* [PATCHv2 0/3] add HT support for IBSS
@ 2011-11-30 15:56 Simon Wunderlich
2011-11-30 15:56 ` [PATCHv2 1/3] nl80211: Parse channel type attribute in an ibss join request Simon Wunderlich
` (4 more replies)
0 siblings, 5 replies; 7+ messages in thread
From: Simon Wunderlich @ 2011-11-30 15:56 UTC (permalink / raw)
To: linux-wireless
Cc: linville, Johannes Berg, Simon Wunderlich, Mathias Kretschmer,
Alexander Simon, Marek Lindner, Felix Fietkau
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 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.
Changes between this version and PATCH:
* change patch order
* add 802.11n-2009 reference name
* fix authorship
* add nl80211_feature_flag for HT IBSS
* remove internal scan request fix to send it separately
Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
Signed-off-by: Mathias Kretschmer <mathias.kretschmer@fokus.fraunhofer.de>
Alexander Simon (2):
nl80211: Parse channel type attribute in an ibss join request
mac80211: Add HT operation modes for IBSS
Simon Wunderlich (1):
mac80211: handle protection mode, RIFS and ADDBA for HT IBSS
include/linux/nl80211.h | 2 +
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 | 3 +-
net/mac80211/rx.c | 3 +-
net/mac80211/util.c | 5 ++
net/wireless/chan.c | 12 +++--
net/wireless/nl80211.c | 32 +++++++++++++-
12 files changed, 181 insertions(+), 19 deletions(-)
--
1.7.7.3
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCHv2 1/3] nl80211: Parse channel type attribute in an ibss join request
2011-11-30 15:56 [PATCHv2 0/3] add HT support for IBSS Simon Wunderlich
@ 2011-11-30 15:56 ` Simon Wunderlich
2011-11-30 15:56 ` [PATCHv2 2/3] mac80211: handle protection mode, RIFS and ADDBA for HT IBSS Simon Wunderlich
` (3 subsequent siblings)
4 siblings, 0 replies; 7+ messages in thread
From: Simon Wunderlich @ 2011-11-30 15:56 UTC (permalink / raw)
To: linux-wireless
Cc: linville, Johannes Berg, Simon Wunderlich, Mathias Kretschmer,
Alexander Simon, Marek Lindner, Felix Fietkau
From: Alexander Simon <an.alexsimon@googlemail.com>
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
* add HT IBSS feature flag
* reword commit message
Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
Signed-off-by: Mathias Kretschmer <mathias.kretschmer@fokus.fraunhofer.de>
---
include/linux/nl80211.h | 2 ++
include/net/cfg80211.h | 11 +++++++++++
net/wireless/chan.c | 12 +++++++-----
net/wireless/nl80211.c | 32 ++++++++++++++++++++++++++++++--
4 files changed, 50 insertions(+), 7 deletions(-)
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index 97bfebf..88cd0c6 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -2770,9 +2770,11 @@ enum nl80211_ap_sme_features {
* @NL80211_FEATURE_SK_TX_STATUS: This driver supports reflecting back
* TX status to the socket error queue when requested with the
* socket option.
+ * @NL80211_FEATURE_HT_IBSS: This driver supports IBSS with HT datarates.
*/
enum nl80211_feature_flags {
NL80211_FEATURE_SK_TX_STATUS = 1 << 0,
+ NL80211_FEATURE_HT_IBSS = 1 << 1,
};
/**
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..ee253b5 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -4657,13 +4657,41 @@ 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;
+
+ if (channel_type != NL80211_CHAN_NO_HT &&
+ !(wiphy->features & NL80211_FEATURE_HT_IBSS))
+ 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] 7+ messages in thread
* [PATCHv2 2/3] mac80211: handle protection mode, RIFS and ADDBA for HT IBSS
2011-11-30 15:56 [PATCHv2 0/3] add HT support for IBSS Simon Wunderlich
2011-11-30 15:56 ` [PATCHv2 1/3] nl80211: Parse channel type attribute in an ibss join request Simon Wunderlich
@ 2011-11-30 15:56 ` Simon Wunderlich
2011-11-30 15:56 ` [PATCHv2 3/3] mac80211: Add HT operation modes for IBSS Simon Wunderlich
` (2 subsequent siblings)
4 siblings, 0 replies; 7+ messages in thread
From: Simon Wunderlich @ 2011-11-30 15:56 UTC (permalink / raw)
To: linux-wireless
Cc: linville, Johannes Berg, Simon Wunderlich, Mathias Kretschmer,
Alexander Simon, Marek Lindner, Felix Fietkau
* 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 | 5 +++++
3 files changed, 44 insertions(+), 0 deletions(-)
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index 39d72cc..611b64e 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -387,6 +387,27 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid,
return -EINVAL;
}
+ /*
+ * 802.11n-2009 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 7d84af7..a82f6b4 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -896,6 +896,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 +
36 /* bitrates */ +
@@ -951,6 +952,23 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
ieee80211_recalc_idle(sdata->local);
mutex_unlock(&sdata->local->mtx);
+ /*
+ * 802.11n-2009 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..614b646 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1585,6 +1585,11 @@ 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 802.11n-2009 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] 7+ messages in thread
* [PATCHv2 3/3] mac80211: Add HT operation modes for IBSS
2011-11-30 15:56 [PATCHv2 0/3] add HT support for IBSS Simon Wunderlich
2011-11-30 15:56 ` [PATCHv2 1/3] nl80211: Parse channel type attribute in an ibss join request Simon Wunderlich
2011-11-30 15:56 ` [PATCHv2 2/3] mac80211: handle protection mode, RIFS and ADDBA for HT IBSS Simon Wunderlich
@ 2011-11-30 15:56 ` Simon Wunderlich
2011-11-30 15:56 ` [PATCH] iw: add HT options for ibss Simon Wunderlich
2011-12-06 12:26 ` [PATCHv2 0/3] add HT support for IBSS Johannes Berg
4 siblings, 0 replies; 7+ messages in thread
From: Simon Wunderlich @ 2011-11-30 15:56 UTC (permalink / raw)
To: linux-wireless
Cc: linville, Johannes Berg, Simon Wunderlich, Mathias Kretschmer,
Alexander Simon, Marek Lindner, Felix Fietkau
From: Alexander Simon <an.alexsimon@googlemail.com>
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
* activate HT IBSS feature support
* 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/main.c | 3 +-
net/mac80211/rx.c | 3 +-
7 files changed, 87 insertions(+), 12 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 611b64e..aede794 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 a82f6b4..3f830ac 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();
}
@@ -899,10 +957,15 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
u32 changed = 0;
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;
@@ -923,13 +986,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/main.c b/net/mac80211/main.c
index 3e15f75..62e3365 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -611,7 +611,8 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
WIPHY_FLAG_OFFCHAN_TX |
WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
- wiphy->features = NL80211_FEATURE_SK_TX_STATUS;
+ wiphy->features = NL80211_FEATURE_SK_TX_STATUS |
+ NL80211_FEATURE_HT_IBSS;
if (!ops->set_key)
wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
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] 7+ messages in thread
* [PATCH] iw: add HT options for ibss
2011-11-30 15:56 [PATCHv2 0/3] add HT support for IBSS Simon Wunderlich
` (2 preceding siblings ...)
2011-11-30 15:56 ` [PATCHv2 3/3] mac80211: Add HT operation modes for IBSS Simon Wunderlich
@ 2011-11-30 15:56 ` Simon Wunderlich
2011-12-06 12:26 ` [PATCHv2 0/3] add HT support for IBSS Johannes Berg
4 siblings, 0 replies; 7+ messages in thread
From: Simon Wunderlich @ 2011-11-30 15:56 UTC (permalink / raw)
To: linux-wireless
Cc: linville, Johannes Berg, Simon Wunderlich, Mathias Kretschmer,
Alexander Simon, Marek Lindner, Felix Fietkau
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] 7+ messages in thread
* Re: [PATCHv2 0/3] add HT support for IBSS
2011-11-30 15:56 [PATCHv2 0/3] add HT support for IBSS Simon Wunderlich
` (3 preceding siblings ...)
2011-11-30 15:56 ` [PATCH] iw: add HT options for ibss Simon Wunderlich
@ 2011-12-06 12:26 ` Johannes Berg
2011-12-06 12:32 ` Johannes Berg
4 siblings, 1 reply; 7+ messages in thread
From: Johannes Berg @ 2011-12-06 12:26 UTC (permalink / raw)
To: Simon Wunderlich
Cc: linux-wireless, linville, Simon Wunderlich, Mathias Kretschmer,
Alexander Simon, Marek Lindner, Felix Fietkau
On Wed, 2011-11-30 at 16:56 +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.
Looks good to me, I only wonder if all drivers are willing to support
NL80211_FEATURE_HT_IBSS. If there's any driver not willing to have it,
we'd have to move setting it into drivers.
Anyway, we can do that later.
Reviewed-by: Johannes Berg <johannes@sipsolutions.net>
johannes
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCHv2 0/3] add HT support for IBSS
2011-12-06 12:26 ` [PATCHv2 0/3] add HT support for IBSS Johannes Berg
@ 2011-12-06 12:32 ` Johannes Berg
0 siblings, 0 replies; 7+ messages in thread
From: Johannes Berg @ 2011-12-06 12:32 UTC (permalink / raw)
To: Simon Wunderlich
Cc: linux-wireless, linville, Simon Wunderlich, Mathias Kretschmer,
Alexander Simon, Marek Lindner, Felix Fietkau
On Tue, 2011-12-06 at 13:26 +0100, Johannes Berg wrote:
> On Wed, 2011-11-30 at 16:56 +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.
>
> Looks good to me, I only wonder if all drivers are willing to support
> NL80211_FEATURE_HT_IBSS. If there's any driver not willing to have it,
> we'd have to move setting it into drivers.
>
> Anyway, we can do that later.
In fact, drivers who don't want it can explicitly unset it too.
johannes
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2011-12-06 12:32 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-11-30 15:56 [PATCHv2 0/3] add HT support for IBSS Simon Wunderlich
2011-11-30 15:56 ` [PATCHv2 1/3] nl80211: Parse channel type attribute in an ibss join request Simon Wunderlich
2011-11-30 15:56 ` [PATCHv2 2/3] mac80211: handle protection mode, RIFS and ADDBA for HT IBSS Simon Wunderlich
2011-11-30 15:56 ` [PATCHv2 3/3] mac80211: Add HT operation modes for IBSS Simon Wunderlich
2011-11-30 15:56 ` [PATCH] iw: add HT options for ibss Simon Wunderlich
2011-12-06 12:26 ` [PATCHv2 0/3] add HT support for IBSS Johannes Berg
2011-12-06 12:32 ` Johannes Berg
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox