linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [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; 14+ 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] 14+ messages in thread

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

[-- Attachment #1: Type: text/plain, Size: 224 bytes --]

On Tue, 2010-01-19 at 17:42 +0100, Benoit Papillault wrote:
> The same code is also used for probe request generation

The code is probably fine, but on its own the patch is wrong, so we
shouldn't merge it.

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

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

* Re: [PATCH] mac80211: Add HT IE to IBSS beacons and probe responses.
  2010-01-20 10:21 ` Johannes Berg
@ 2010-01-20 14:45   ` X Xiao
  2010-01-20 23:03     ` Benoit PAPILLAULT
  0 siblings, 1 reply; 14+ messages in thread
From: X Xiao @ 2010-01-20 14:45 UTC (permalink / raw)
  To: Benoit Papillault, Johannes Berg; +Cc: linux-wireless

Johannes,

What do you mean by saying "on its own the patch is wrong".

Thanks,
xxiao

--- On Wed, 1/20/10, Johannes Berg <johannes@sipsolutions.net> wrote:

> From: Johannes Berg <johannes@sipsolutions.net>
> Subject: Re: [PATCH] mac80211: Add HT IE to IBSS beacons and probe responses.
> To: "Benoit Papillault" <benoit.papillault@free.fr>
> Cc: linux-wireless@vger.kernel.org
> Date: Wednesday, January 20, 2010, 4:21 AM
> On Tue, 2010-01-19 at 17:42 +0100,
> Benoit Papillault wrote:
> > The same code is also used for probe request
> generation
> 
> The code is probably fine, but on its own the patch is
> wrong, so we
> shouldn't merge it.
> 
> johannes
> 

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

* Re: [PATCH] mac80211: Add HT IE to IBSS beacons and probe responses.
  2010-01-20 14:45   ` X Xiao
@ 2010-01-20 23:03     ` Benoit PAPILLAULT
  2010-01-21  9:14       ` Johannes Berg
  0 siblings, 1 reply; 14+ messages in thread
From: Benoit PAPILLAULT @ 2010-01-20 23:03 UTC (permalink / raw)
  To: austinxxh-linux; +Cc: Johannes Berg, linux-wireless

X Xiao a écrit :
> Johannes,
>
> What do you mean by saying "on its own the patch is wrong".
>
> Thanks,
> xxiao
>
>   
Humm... same question for me. What's wrong in the patch? form? content? 
frame format? commit message?

Regards,
Benoit

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

* Re: [PATCH] mac80211: Add HT IE to IBSS beacons and probe responses.
  2010-01-20 23:03     ` Benoit PAPILLAULT
@ 2010-01-21  9:14       ` Johannes Berg
  2010-01-21 17:33         ` Benoit PAPILLAULT
  0 siblings, 1 reply; 14+ messages in thread
From: Johannes Berg @ 2010-01-21  9:14 UTC (permalink / raw)
  To: Benoit PAPILLAULT; +Cc: austinxxh-linux, linux-wireless

[-- Attachment #1: Type: text/plain, Size: 331 bytes --]

On Thu, 2010-01-21 at 00:03 +0100, Benoit PAPILLAULT wrote:
>    
> Humm... same question for me. What's wrong in the patch? form? content? 
> frame format? commit message?

Well shouldn't you only advertise HT if the user or somebody actually
asked to join an HT IBSS and you configured the right channel type?

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

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

* Re: [PATCH] mac80211: Add HT IE to IBSS beacons and probe responses.
  2010-01-21  9:14       ` Johannes Berg
@ 2010-01-21 17:33         ` Benoit PAPILLAULT
  2010-01-21 17:51           ` Johannes Berg
  0 siblings, 1 reply; 14+ messages in thread
From: Benoit PAPILLAULT @ 2010-01-21 17:33 UTC (permalink / raw)
  To: Johannes Berg; +Cc: austinxxh-linux, linux-wireless

Johannes Berg a écrit :
> On Thu, 2010-01-21 at 00:03 +0100, Benoit PAPILLAULT wrote:
>   
>>    
>> Humm... same question for me. What's wrong in the patch? form? content? 
>> frame format? commit message?
>>     
>
> Well shouldn't you only advertise HT if the user or somebody actually
> asked to join an HT IBSS and you configured the right channel type?
>
> johannes
>   
There are things :
- HT Capabilities IE : this should be the hardware capabilities of the 
sender, be it a member of a HT IBSS or not.
- HT Information IE : this should be the BSS information, shared by all 
members of the HT IBSS I think.

BTW, currently, there is no way with iw for the user to tell mac82011 to 
join/create a non-HT, HT20, HT40+ or HT40- IBSS. Maybe we should update 
iw first as a requirement for HT IBSS?

Regards,
Benoit


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

* Re: [PATCH] mac80211: Add HT IE to IBSS beacons and probe responses.
  2010-01-21 17:33         ` Benoit PAPILLAULT
@ 2010-01-21 17:51           ` Johannes Berg
  0 siblings, 0 replies; 14+ messages in thread
From: Johannes Berg @ 2010-01-21 17:51 UTC (permalink / raw)
  To: Benoit PAPILLAULT; +Cc: austinxxh-linux, linux-wireless

[-- Attachment #1: Type: text/plain, Size: 708 bytes --]

On Thu, 2010-01-21 at 18:33 +0100, Benoit PAPILLAULT wrote:

> There are things :
> - HT Capabilities IE : this should be the hardware capabilities of the 
> sender, be it a member of a HT IBSS or not.

I wouldn't advertise that though when the IBSS we want is not HT. Less
confusion that way.

> - HT Information IE : this should be the BSS information, shared by all 
> members of the HT IBSS I think.

So we even need to adopt it, maybe?

> BTW, currently, there is no way with iw for the user to tell mac82011 to 
> join/create a non-HT, HT20, HT40+ or HT40- IBSS. Maybe we should update 
> iw first as a requirement for HT IBSS?

Indeed, we need nl80211/cfg80211 changes.

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

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

* [PATCH] mac80211: Add HT IE to IBSS beacons and probe responses.
  2010-05-04  6:47 ` [PATCH] cfg80211: Check for channel HT capabilities in an IBSS Benoit Papillault
@ 2010-05-04  6:47   ` Benoit Papillault
  2010-05-04  8:26     ` Johannes Berg
  2010-05-05 11:46     ` Johannes Berg
  0 siblings, 2 replies; 14+ messages in thread
From: Benoit Papillault @ 2010-05-04  6:47 UTC (permalink / raw)
  To: johannes; +Cc: linux-wireless, Benoit Papillault

When an HT IBSS is configured, we add HT Information and HT Capabilities
IE to beacon & probe responses. This is done according to channel_type
transmitted by iw/cfg80211.

Signed-off-by: Benoit Papillault <benoit.papillault@free.fr>
---
 net/mac80211/ibss.c        |  114 +++++++++++++++++++++++++++++++++++++++++---
 net/mac80211/ieee80211_i.h |    1 +
 net/mac80211/util.c        |   23 +++++----
 3 files changed, 120 insertions(+), 18 deletions(-)

diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index f657854..c501d3b 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -64,6 +64,7 @@ static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata,
 static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
 				      const u8 *bssid, const int beacon_int,
 				      struct ieee80211_channel *chan,
+				      enum nl80211_channel_type channel_type,
 				      const u32 basic_rates,
 				      const u16 capability, u64 tsf)
 {
@@ -103,7 +104,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;
-	local->oper_channel_type = NL80211_CHAN_NO_HT;
+	local->oper_channel_type = channel_type;
 	ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
 
 	sband = local->hw.wiphy->bands[chan->band];
@@ -118,7 +119,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 |
@@ -165,6 +169,64 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
 		memcpy(pos, &supp_rates[8], rates);
 	}
 
+	if (channel_type != NL80211_CHAN_NO_HT &&
+	    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;
+		switch (local->oper_channel_type) {
+		case NL80211_CHAN_NO_HT: /* to make compiler happy */
+		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);
@@ -202,6 +264,9 @@ static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
 	u32 basic_rates;
 	int i, j;
 	u16 beacon_int = cbss->beacon_interval;
+	const u8 * ht_info_ie;
+	const struct ieee80211_ht_info *ht_info;
+	enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;
 
 	if (beacon_int < 10)
 		beacon_int = 10;
@@ -223,9 +288,28 @@ static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
 		}
 	}
 
+	/* parse HT Information IE, if present */
+	ht_info_ie = ieee80211_bss_get_ie(cbss, WLAN_EID_HT_INFORMATION);
+	if (ht_info_ie) {
+		ht_info = (const struct ieee80211_ht_info *)(ht_info_ie + 2);
+		switch (ht_info->ht_param
+			& IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
+		case IEEE80211_HT_PARAM_CHA_SEC_NONE:
+			channel_type = NL80211_CHAN_HT20;
+			break;
+		case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
+			channel_type = NL80211_CHAN_HT40PLUS;
+			break;
+		case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
+			channel_type = NL80211_CHAN_HT40MINUS;
+			break;
+		}
+	}
+
 	__ieee80211_sta_join_ibss(sdata, cbss->bssid,
 				  beacon_int,
 				  cbss->channel,
+				  channel_type,
 				  basic_rates,
 				  cbss->capability,
 				  cbss->tsf);
@@ -529,7 +613,8 @@ static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
 		sdata->drop_unencrypted = 0;
 
 	__ieee80211_sta_join_ibss(sdata, bssid, sdata->vif.bss_conf.beacon_int,
-				  ifibss->channel, 3, /* first two are basic */
+				  ifibss->channel, ifibss->channel_type,
+				  3, /* first two are basic */
 				  capability, 0);
 }
 
@@ -906,6 +991,7 @@ 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;
 
 	if (params->ie) {
@@ -915,11 +1001,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/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index c8077a3..30876f3 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -404,6 +404,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/util.c b/net/mac80211/util.c
index 2b75b4f..b83f264 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -967,7 +967,7 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
 
 	if (sband->ht_cap.ht_supported) {
 		u16 cap = sband->ht_cap.cap;
-		__le16 tmp;
+		struct ieee80211_ht_cap ht_cap;
 
 		if (ieee80211_disable_40mhz_24ghz &&
 		    sband->band == IEEE80211_BAND_2GHZ) {
@@ -975,18 +975,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.5.6.5


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

* Re: [PATCH] mac80211: Add HT IE to IBSS beacons and probe responses.
  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
  1 sibling, 1 reply; 14+ messages in thread
From: Johannes Berg @ 2010-05-04  8:26 UTC (permalink / raw)
  To: Benoit Papillault; +Cc: linux-wireless


> @@ -118,7 +119,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())
> +	 */

That change is wrong -- no way beacon code can call into IBSS code.

I think you meant to say "I need to create a common helper function that
I call here and in the beacon code."

> --- a/net/mac80211/util.c
> +++ b/net/mac80211/util.c
> @@ -967,7 +967,7 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
>  
>  	if (sband->ht_cap.ht_supported) {
>  		u16 cap = sband->ht_cap.cap;
> -		__le16 tmp;
> +		struct ieee80211_ht_cap ht_cap;
>  
>  		if (ieee80211_disable_40mhz_24ghz &&
>  		    sband->band == IEEE80211_BAND_2GHZ) {
> @@ -975,18 +975,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);

And this is an unrelated change that doesn't belong into this patch at
all.

johannes


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

* Re: [PATCH] mac80211: Add HT IE to IBSS beacons and probe responses.
  2010-05-04  8:26     ` Johannes Berg
@ 2010-05-05  6:37       ` Benoit Papillault
  0 siblings, 0 replies; 14+ messages in thread
From: Benoit Papillault @ 2010-05-05  6:37 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless

Le 04/05/2010 10:26, Johannes Berg a écrit :
>
>> @@ -118,7 +119,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())
>> +	 */
>
> That change is wrong -- no way beacon code can call into IBSS code.

I meant the skb that is produced here and stored in ifibss->presp is 
then used both for sending beacons in ieee80211_beacon_get_tim and for 
sending probe response in ieee80211_rx_mgmt_probe_req

>
> I think you meant to say "I need to create a common helper function that
> I call here and in the beacon code."

You are right : I will add a helper function to create HT Capability IE.

>
>> --- a/net/mac80211/util.c
>> +++ b/net/mac80211/util.c
>> @@ -967,7 +967,7 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
>>
>>   	if (sband->ht_cap.ht_supported) {
>>   		u16 cap = sband->ht_cap.cap;
>> -		__le16 tmp;
>> +		struct ieee80211_ht_cap ht_cap;
>>
>>   		if (ieee80211_disable_40mhz_24ghz&&
>>   		sband->band == IEEE80211_BAND_2GHZ) {
>> @@ -975,18 +975,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);
>
> And this is an unrelated change that doesn't belong into this patch at
> all.
>
> johannes
>
>

Regards,
Benoit

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

* Re: [PATCH] mac80211: Add HT IE to IBSS beacons and probe responses.
  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 11:46     ` Johannes Berg
  2010-05-05 21:37       ` Benoit Papillault
  1 sibling, 1 reply; 14+ messages in thread
From: Johannes Berg @ 2010-05-05 11:46 UTC (permalink / raw)
  To: Benoit Papillault; +Cc: linux-wireless

On Tue, 2010-05-04 at 08:47 +0200, Benoit Papillault wrote:
> When an HT IBSS is configured, we add HT Information and HT Capabilities
> IE to beacon & probe responses. This is done according to channel_type
> transmitted by iw/cfg80211.

Just noticed something else -- this allows creating an HT40 IBSS on an
invalid channel pair -- do we want to catch that?

johannse


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

* Re: [PATCH] mac80211: Add HT IE to IBSS beacons and probe responses.
  2010-05-05 11:46     ` Johannes Berg
@ 2010-05-05 21:37       ` Benoit Papillault
  0 siblings, 0 replies; 14+ messages in thread
From: Benoit Papillault @ 2010-05-05 21:37 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless

Le 05/05/2010 13:46, Johannes Berg a écrit :
> On Tue, 2010-05-04 at 08:47 +0200, Benoit Papillault wrote:
>> When an HT IBSS is configured, we add HT Information and HT Capabilities
>> IE to beacon&  probe responses. This is done according to channel_type
>> transmitted by iw/cfg80211.
>
> Just noticed something else -- this allows creating an HT40 IBSS on an
> invalid channel pair -- do we want to catch that?
>
> johannse
>

Do you mean creating an ht40+ over channel 112, where only ht40- is 
allowed by 802.11 ? Since it's the same for AP & IBSS, maybe it could be 
done in the regulatory code?

Anyway, since this latter issue was already there for a while, it could 
be fixed in a follow up patch.

Regards,
Benoit

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

* [PATCH] mac80211: Add HT IE to IBSS beacons and probe responses
  2010-05-12 21:07   ` [PATCH] mac80211: Use struct ieee80211_ht_cap to build HT Capabilities IE Benoit Papillault
@ 2010-05-12 21:07     ` Benoit Papillault
  2010-05-14 13:56       ` Johannes Berg
  0 siblings, 1 reply; 14+ messages in thread
From: Benoit Papillault @ 2010-05-12 21:07 UTC (permalink / raw)
  To: johannes; +Cc: linux-wireless, Benoit Papillault

When an HT IBSS is configured, we add HT Capabilities and HT Operation
IE to beacons and probe responses. This is done according to
channel_type transmitted by iw/cfg80211.

Signed-off-by: Benoit Papillault <benoit.papillault@free.fr>
---
 net/mac80211/ibss.c        |   67 ++++++++++++++++++++++++++++++++++++++-----
 net/mac80211/ieee80211_i.h |   14 +++++++++
 net/mac80211/util.c        |   40 ++++++++++++++++++++++++++
 3 files changed, 113 insertions(+), 8 deletions(-)

diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index b2cc1fd..288f512 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -64,6 +64,7 @@ static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata,
 static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
 				      const u8 *bssid, const int beacon_int,
 				      struct ieee80211_channel *chan,
+				      enum nl80211_channel_type channel_type,
 				      const u32 basic_rates,
 				      const u16 capability, u64 tsf)
 {
@@ -103,7 +104,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;
-	WARN_ON(!ieee80211_set_channel_type(local, sdata, NL80211_CHAN_NO_HT));
+	WARN_ON(!ieee80211_set_channel_type(local, sdata, channel_type));
 	ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
 
 	sband = local->hw.wiphy->bands[chan->band];
@@ -118,7 +119,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 (this template is also used
+	 * when sending beacon, see 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 |
@@ -165,6 +169,17 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
 		memcpy(pos, &supp_rates[8], rates);
 	}
 
+	if (sband->ht_cap.ht_supported) {
+		pos = skb_put(skb, 2 + sizeof(struct ieee80211_ht_cap));
+		ieee80211_add_ht_cap(pos, sband);
+	}
+
+	if (channel_type != NL80211_CHAN_NO_HT &&
+	    sband->ht_cap.ht_supported) {
+		pos = skb_put(skb, 2 + sizeof(struct ieee80211_ht_info));
+		ieee80211_add_ht_info(pos, sband, chan, channel_type);
+	}
+
 	if (ifibss->ie_len)
 		memcpy(skb_put(skb, ifibss->ie_len),
 		       ifibss->ie, ifibss->ie_len);
@@ -202,6 +217,8 @@ static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
 	u32 basic_rates;
 	int i, j;
 	u16 beacon_int = cbss->beacon_interval;
+	const u8 *ht_cap_ie, *ht_info_ie;
+	enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;
 
 	if (beacon_int < 10)
 		beacon_int = 10;
@@ -223,9 +240,27 @@ static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
 		}
 	}
 
+	/* parse HT Capabilities & Information IE, if present */
+	ht_cap_ie = ieee80211_bss_get_ie(cbss, WLAN_EID_HT_CAPABILITY);
+	ht_info_ie = ieee80211_bss_get_ie(cbss, WLAN_EID_HT_INFORMATION);
+	if (ht_cap_ie && ht_info_ie) {
+		struct ieee80211_ht_cap *ht_cap;
+		struct ieee80211_ht_info *ht_info;
+		struct ieee80211_sta_ht_cap sta_ht_cap;
+
+		ht_cap = (struct ieee80211_ht_cap *)(ht_cap_ie + 2);
+		ht_info = (struct ieee80211_ht_info *)(ht_info_ie + 2);
+
+		ieee80211_ht_cap_ie_to_sta_ht_cap(sband, ht_cap, &sta_ht_cap);
+
+		channel_type = ieee80211_channel_type_from_ht_info(
+					sdata->local, ht_info, sta_ht_cap.cap);
+	}
+
 	__ieee80211_sta_join_ibss(sdata, cbss->bssid,
 				  beacon_int,
 				  cbss->channel,
+				  channel_type,
 				  basic_rates,
 				  cbss->capability,
 				  cbss->tsf);
@@ -529,7 +564,8 @@ static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
 		sdata->drop_unencrypted = 0;
 
 	__ieee80211_sta_join_ibss(sdata, bssid, sdata->vif.bss_conf.beacon_int,
-				  ifibss->channel, 3, /* first two are basic */
+				  ifibss->channel, ifibss->channel_type,
+				  3, /* first two are basic */
 				  capability, 0);
 }
 
@@ -906,13 +942,14 @@ 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));
+						    params->channel_type));
 	}
 
 	if (params->ie) {
@@ -922,11 +959,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/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 742e12b..78c4716 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -404,6 +404,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 */
@@ -1193,6 +1194,19 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
 			 u16 transaction, u16 auth_alg,
 			 u8 *extra, size_t extra_len, const u8 *bssid,
 			 const u8 *key, u8 key_len, u8 key_idx);
+
+u8 *ieee80211_add_ht_cap(u8 *pos,
+			 struct ieee80211_supported_band *sband);
+
+u8 *ieee80211_add_ht_info(u8 *pos,
+			  struct ieee80211_supported_band *sband,
+			  struct ieee80211_channel *channel,
+			  enum nl80211_channel_type channel_type);
+
+enum nl80211_channel_type ieee80211_channel_type_from_ht_info(
+	struct ieee80211_local *local,
+	struct ieee80211_ht_info *hti, u16 ap_ht_cap_flags);
+
 int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
 			     const u8 *ie, size_t ie_len,
 			     enum ieee80211_band band);
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 047acb8..78c43b8 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -898,6 +898,46 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
 	ieee80211_tx_skb(sdata, skb);
 }
 
+u8 *ieee80211_add_ht_info(u8 *pos,
+			  struct ieee80211_supported_band *sband,
+			  struct ieee80211_channel *channel,
+			  enum nl80211_channel_type channel_type)
+{
+	struct ieee80211_ht_info ht_info;
+
+	ht_info.control_chan =
+		ieee80211_frequency_to_channel(channel->center_freq);
+	ht_info.ht_param = 0;
+	switch (channel_type) {
+	case NL80211_CHAN_NO_HT: /* to make compiler happy */
+	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, &sband->ht_cap.mcs, 10);
+
+	/* HT Information element */
+	*pos++ = WLAN_EID_HT_INFORMATION;
+	*pos++ = sizeof(struct ieee80211_ht_info);
+	memcpy(pos, &ht_info, sizeof(struct ieee80211_ht_info));
+	pos += sizeof(struct ieee80211_ht_info);
+
+	return pos;
+}
+
 int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
 			     const u8 *ie, size_t ie_len,
 			     enum ieee80211_band band)
-- 
1.5.6.5


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

* Re: [PATCH] mac80211: Add HT IE to IBSS beacons and probe responses
  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
  0 siblings, 0 replies; 14+ messages in thread
From: Johannes Berg @ 2010-05-14 13:56 UTC (permalink / raw)
  To: Benoit Papillault; +Cc: linux-wireless


> @@ -103,7 +104,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;
> -	WARN_ON(!ieee80211_set_channel_type(local, sdata, NL80211_CHAN_NO_HT));
> +	WARN_ON(!ieee80211_set_channel_type(local, sdata, channel_type));
>  	ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);

This is incorrect .. you need to fall back to HT20 when HT40 fails, like
mlme.c does.

>  	/* 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));
> +						    params->channel_type));
>  	}

Same here.

>  			 u16 transaction, u16 auth_alg,
>  			 u8 *extra, size_t extra_len, const u8 *bssid,
>  			 const u8 *key, u8 key_len, u8 key_idx);
> +
> +u8 *ieee80211_add_ht_cap(u8 *pos,
> +			 struct ieee80211_supported_band *sband);
> +
> +u8 *ieee80211_add_ht_info(u8 *pos,
> +			  struct ieee80211_supported_band *sband,
> +			  struct ieee80211_channel *channel,
> +			  enum nl80211_channel_type channel_type);
> +
> +enum nl80211_channel_type ieee80211_channel_type_from_ht_info(
> +	struct ieee80211_local *local,
> +	struct ieee80211_ht_info *hti, u16 ap_ht_cap_flags);
> +
>  int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
>  			     const u8 *ie, size_t ie_len,
>  			     enum ieee80211_band band);

Didn't you just do this in the first patch??

johannes


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

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

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-01-19 16:42 [PATCH] mac80211: Add HT IE to IBSS beacons and probe responses 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
  -- strict thread matches above, loose matches on Subject: below --
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-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

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).