linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] cfg80211: Parse channel_type in NL80211_CMD_JOIN_IBSS
@ 2010-05-04  6:47 Benoit Papillault
  2010-05-04  6:47 ` [PATCH] cfg80211: Check for channel HT capabilities in an IBSS Benoit Papillault
  0 siblings, 1 reply; 20+ messages in thread
From: Benoit Papillault @ 2010-05-04  6:47 UTC (permalink / raw)
  To: johannes; +Cc: linux-wireless, Benoit Papillault

This field is filled by iw and parse by cfg80211 before being sent to
mac80211 for instance. This information is needed to properly configure
an HT IBSS.

It requires a patch to iw to fill this field.

Signed-off-by: Benoit Papillault <benoit.papillault@free.fr>
---
 include/net/cfg80211.h |    1 +
 net/wireless/nl80211.c |   12 ++++++++++++
 2 files changed, 13 insertions(+), 0 deletions(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 7d10c01..93e5558 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -806,6 +806,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;
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 01da83d..8da9823 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -3792,6 +3792,7 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
 	struct cfg80211_ibss_params ibss;
 	struct wiphy *wiphy;
 	struct cfg80211_cached_keys *connkeys = NULL;
+	enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;
 	int err;
 
 	memset(&ibss, 0, sizeof(ibss));
@@ -3813,6 +3814,17 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
 			return -EINVAL;
 	}
 
+	if (info->attrs[NL80211_ATTR_WIPHY_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_HT40PLUS &&
+		    channel_type != NL80211_CHAN_HT40MINUS)
+			return -EINVAL;
+	}
+	ibss.channel_type = channel_type;
+
 	rtnl_lock();
 
 	err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
-- 
1.5.6.5


^ permalink raw reply related	[flat|nested] 20+ messages in thread
* [PATCH] cfg80211: Parse channel_type in NL80211_CMD_JOIN_IBSS
@ 2010-05-12 21:07 Benoit Papillault
  2010-05-12 21:07 ` [PATCH] mac80211: Move part of the MLME code to helper functions Benoit Papillault
  0 siblings, 1 reply; 20+ messages in thread
From: Benoit Papillault @ 2010-05-12 21:07 UTC (permalink / raw)
  To: johannes; +Cc: linux-wireless, Benoit Papillault

The channel_type field is filled by iw and parse by cfg80211 before
being sent to mac80211 for instance (we also check if the specified
channel is capable of ht40+, ht40- or ht20). This information is needed
to properly configure an HT IBSS.

It requires a patch to iw to fill this field.

Signed-off-by: Benoit Papillault <benoit.papillault@free.fr>
---
 include/net/cfg80211.h |    1 +
 net/wireless/nl80211.c |   20 ++++++++++++++++----
 2 files changed, 17 insertions(+), 4 deletions(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index b44a2e5..5ead439 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -806,6 +806,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;
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index aaa1aad..039c13f 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -3879,6 +3879,7 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
 	struct cfg80211_ibss_params ibss;
 	struct wiphy *wiphy;
 	struct cfg80211_cached_keys *connkeys = NULL;
+	enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;
 	int err;
 
 	memset(&ibss, 0, sizeof(ibss));
@@ -3900,6 +3901,17 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
 			return -EINVAL;
 	}
 
+	if (info->attrs[NL80211_ATTR_WIPHY_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_HT40PLUS &&
+		    channel_type != NL80211_CHAN_HT40MINUS)
+			return -EINVAL;
+	}
+	ibss.channel_type = channel_type;
+
 	rtnl_lock();
 
 	err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
@@ -3933,11 +3945,11 @@ 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]));
+	ibss.channel = rdev_freq_to_chan(rdev,
+		nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]),
+		channel_type);
 	if (!ibss.channel ||
-	    ibss.channel->flags & IEEE80211_CHAN_NO_IBSS ||
-	    ibss.channel->flags & IEEE80211_CHAN_DISABLED) {
+	    ibss.channel->flags & IEEE80211_CHAN_NO_IBSS) {
 		err = -EINVAL;
 		goto out;
 	}
-- 
1.5.6.5


^ permalink raw reply related	[flat|nested] 20+ messages in thread
* [PATCH] mac80211: Add HT IE to IBSS beacons and probe responses.
@ 2010-01-19 16:42 Benoit Papillault
  2010-01-20 10:21 ` Johannes Berg
  0 siblings, 1 reply; 20+ messages in thread
From: Benoit Papillault @ 2010-01-19 16:42 UTC (permalink / raw)
  To: johannes; +Cc: linux-wireless, Benoit Papillault

The same code is also used for probe request generation

Signed-off-by: Benoit Papillault <benoit.papillault@free.fr>
---
 net/mac80211/ibss.c |   86 ++++++++++++++++++++++++++++++++++++++++++++++++---
 net/mac80211/util.c |   22 +++++++------
 2 files changed, 93 insertions(+), 15 deletions(-)

diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index f95750b..86bd2a0 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -96,6 +96,7 @@ 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;
+	/* FIXME : we can have HT channels here */
 	local->oper_channel_type = NL80211_CHAN_NO_HT;
 	ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
 
@@ -111,7 +112,10 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
 		*pos++ = basic | (u8) (rate / 5);
 	}
 
-	/* Build IBSS probe response */
+	/* 
+	 * Build IBSS probe response template (also used for beacon template
+	 * in ieee80211_beacon_get_tim())
+	 */
 	mgmt = (void *) skb_put(skb, 24 + sizeof(mgmt->u.beacon));
 	memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon));
 	mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
@@ -158,6 +162,64 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
 		memcpy(pos, &supp_rates[8], rates);
 	}
 
+	if (sband->ht_cap.ht_supported) {
+		u16 cap = sband->ht_cap.cap;
+		struct ieee80211_ht_cap ht_cap;
+		struct ieee80211_ht_info ht_info;
+
+		if (ieee80211_disable_40mhz_24ghz &&
+		    sband->band == IEEE80211_BAND_2GHZ) {
+			cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
+			cap &= ~IEEE80211_HT_CAP_SGI_40;
+		}
+
+		ht_cap.cap_info = cpu_to_le16(cap);
+		ht_cap.ampdu_params_info = sband->ht_cap.ampdu_factor |
+			(sband->ht_cap.ampdu_density <<
+			 IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT);
+		ht_cap.mcs = sband->ht_cap.mcs;
+		ht_cap.extended_ht_cap_info = cpu_to_le16(0);
+		ht_cap.tx_BF_cap_info = cpu_to_le32(0);
+		ht_cap.antenna_selection_info = 0;
+
+		/* HT Capabilities element */
+		pos = skb_put(skb, 2 + sizeof(struct ieee80211_ht_cap));
+		*pos++ = WLAN_EID_HT_CAPABILITY;
+		*pos++ = sizeof(struct ieee80211_ht_cap);
+		memcpy(pos, &ht_cap, sizeof(struct ieee80211_ht_cap));
+
+		ht_info.control_chan = 
+			ieee80211_frequency_to_channel(chan->center_freq);
+		ht_info.ht_param = 0;
+		/* FIXME : local->oper_channel_type is set to a fixed value */
+		switch (local->oper_channel_type) {
+		case NL80211_CHAN_NO_HT:
+		case NL80211_CHAN_HT20:
+			ht_info.ht_param |= IEEE80211_HT_PARAM_CHA_SEC_NONE;
+			break;
+		case NL80211_CHAN_HT40MINUS:
+			ht_info.ht_param |= IEEE80211_HT_PARAM_CHA_SEC_BELOW;
+			break;
+		case NL80211_CHAN_HT40PLUS:
+			ht_info.ht_param |= IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
+			break;
+		}
+		if (sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)
+			ht_info.ht_param |= IEEE80211_HT_PARAM_CHAN_WIDTH_ANY;
+		ht_info.operation_mode = cpu_to_le16(0);
+		ht_info.stbc_param = cpu_to_le16(0);
+		/* It seems that Basic MCS set and Supported MCS set
+		   are identical for the first 10 bytes */
+		memset(&ht_info.basic_set, 0, 16);
+		memcpy(&ht_info.basic_set, &ht_cap.mcs, 10);
+
+		/* HT Information element */
+		pos = skb_put(skb, 2 + sizeof(struct ieee80211_ht_info));
+		*pos++ = WLAN_EID_HT_INFORMATION;
+		*pos++ = sizeof(struct ieee80211_ht_info);
+		memcpy(pos, &ht_info, sizeof(struct ieee80211_ht_info));
+	}
+	  
 	if (ifibss->ie_len)
 		memcpy(skb_put(skb, ifibss->ie_len),
 		       ifibss->ie, ifibss->ie_len);
@@ -899,11 +961,25 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
 			sdata->u.ibss.ie_len = params->ie_len;
 	}
 
+	/*
+	 * Allocate IBSS probe response template (see
+	 * __ieee80211_sta_join_ibss for the needed size). According to IEEE
+	 * 802.11-2007 10.4.4.2, there is only 20 possibles values. We
+	 * support up IEEE80211_MAX_SUPP_RATES (currently 32) : so 8 for
+	 * Supported Rates and IEEE80211_MAX_SUPP_RATES-8 for Extended
+	 * Supported Rates
+	 */
+
 	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) /* max Ext Rates */ +
+			    2 + sizeof(struct ieee80211_ht_cap) +
+			    2 + sizeof(struct ieee80211_ht_info) +
 			    params->ie_len);
 	if (!skb)
 		return -ENOMEM;
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index ca170b4..416b0e2 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -958,6 +958,7 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
 
 	if (sband->ht_cap.ht_supported) {
 		u16 cap = sband->ht_cap.cap;
+		struct ieee80211_ht_cap ht_cap;
 		__le16 tmp;
 
 		if (ieee80211_disable_40mhz_24ghz &&
@@ -966,18 +967,19 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
 			cap &= ~IEEE80211_HT_CAP_SGI_40;
 		}
 
+		ht_cap.cap_info = cpu_to_le16(cap);
+		ht_cap.ampdu_params_info = sband->ht_cap.ampdu_factor |
+			(sband->ht_cap.ampdu_density <<
+			 IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT);
+		ht_cap.mcs = sband->ht_cap.mcs;
+		ht_cap.extended_ht_cap_info = cpu_to_le16(0);
+		ht_cap.tx_BF_cap_info = cpu_to_le32(0);
+		ht_cap.antenna_selection_info = 0;
+
 		*pos++ = WLAN_EID_HT_CAPABILITY;
 		*pos++ = sizeof(struct ieee80211_ht_cap);
-		memset(pos, 0, sizeof(struct ieee80211_ht_cap));
-		tmp = cpu_to_le16(cap);
-		memcpy(pos, &tmp, sizeof(u16));
-		pos += sizeof(u16);
-		*pos++ = sband->ht_cap.ampdu_factor |
-			 (sband->ht_cap.ampdu_density <<
-				IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT);
-		memcpy(pos, &sband->ht_cap.mcs, sizeof(sband->ht_cap.mcs));
-		pos += sizeof(sband->ht_cap.mcs);
-		pos += 2 + 4 + 1; /* ext info, BF cap, antsel */
+		memcpy(pos, &ht_cap, sizeof(struct ieee80211_ht_cap));
+		pos += sizeof(struct ieee80211_ht_cap);
 	}
 
 	/*
-- 
1.6.3.3




^ permalink raw reply related	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2010-05-14 13:56 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-05-04  6:47 [PATCH] cfg80211: Parse channel_type in NL80211_CMD_JOIN_IBSS Benoit Papillault
2010-05-04  6:47 ` [PATCH] cfg80211: Check for channel HT capabilities in an IBSS Benoit Papillault
2010-05-04  6:47   ` [PATCH] mac80211: Add HT IE to IBSS beacons and probe responses Benoit Papillault
2010-05-04  8:26     ` Johannes Berg
2010-05-05  6:37       ` Benoit Papillault
2010-05-05 11:46     ` Johannes Berg
2010-05-05 21:37       ` Benoit Papillault
2010-05-04  8:23   ` [PATCH] cfg80211: Check for channel HT capabilities in an IBSS Johannes Berg
2010-05-05  6:29     ` Benoit Papillault
2010-05-04 18:14   ` Luis R. Rodriguez
2010-05-05  6:28     ` Benoit Papillault
  -- strict thread matches above, loose matches on Subject: below --
2010-05-12 21:07 [PATCH] cfg80211: Parse channel_type in NL80211_CMD_JOIN_IBSS Benoit Papillault
2010-05-12 21:07 ` [PATCH] mac80211: Move part of the MLME code to helper functions Benoit Papillault
2010-05-12 21:07   ` [PATCH] mac80211: Use struct ieee80211_ht_cap to build HT Capabilities IE Benoit Papillault
2010-05-12 21:07     ` [PATCH] mac80211: Add HT IE to IBSS beacons and probe responses Benoit Papillault
2010-05-14 13:56       ` Johannes Berg
2010-01-19 16:42 Benoit Papillault
2010-01-20 10:21 ` Johannes Berg
2010-01-20 14:45   ` X Xiao
2010-01-20 23:03     ` Benoit PAPILLAULT
2010-01-21  9:14       ` Johannes Berg
2010-01-21 17:33         ` Benoit PAPILLAULT
2010-01-21 17:51           ` Johannes Berg

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).