* [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: Check for channel HT capabilities in an IBSS 2010-05-04 6:47 [PATCH] cfg80211: Parse channel_type in NL80211_CMD_JOIN_IBSS Benoit Papillault @ 2010-05-04 6:47 ` Benoit Papillault 2010-05-04 6:47 ` [PATCH] mac80211: Add HT IE to IBSS beacons and probe responses Benoit Papillault ` (2 more replies) 0 siblings, 3 replies; 20+ messages in thread From: Benoit Papillault @ 2010-05-04 6:47 UTC (permalink / raw) To: johannes; +Cc: linux-wireless, Benoit Papillault When configuring an HT IBSS, we need to check if the specified channel is capable of ht40+, ht40- or ht20. Signed-off-by: Benoit Papillault <benoit.papillault@free.fr> --- net/wireless/nl80211.c | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-) diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 8da9823..0a82623 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -3858,11 +3858,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-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 2010-05-04 8:23 ` [PATCH] cfg80211: Check for channel HT capabilities in an IBSS Johannes Berg 2010-05-04 18:14 ` Luis R. Rodriguez 2 siblings, 2 replies; 20+ 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] 20+ 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; 20+ 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] 20+ 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; 20+ 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] 20+ 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; 20+ 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] 20+ 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; 20+ 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] 20+ messages in thread
* Re: [PATCH] cfg80211: Check for channel HT capabilities in an IBSS 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:23 ` Johannes Berg 2010-05-05 6:29 ` Benoit Papillault 2010-05-04 18:14 ` Luis R. Rodriguez 2 siblings, 1 reply; 20+ messages in thread From: Johannes Berg @ 2010-05-04 8:23 UTC (permalink / raw) To: Benoit Papillault; +Cc: linux-wireless On Tue, 2010-05-04 at 08:47 +0200, Benoit Papillault wrote: > When configuring an HT IBSS, we need to check if the specified channel > is capable of ht40+, ht40- or ht20. These first two patches cannot be separate. johannes ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH] cfg80211: Check for channel HT capabilities in an IBSS 2010-05-04 8:23 ` [PATCH] cfg80211: Check for channel HT capabilities in an IBSS Johannes Berg @ 2010-05-05 6:29 ` Benoit Papillault 0 siblings, 0 replies; 20+ messages in thread From: Benoit Papillault @ 2010-05-05 6:29 UTC (permalink / raw) To: Johannes Berg; +Cc: linux-wireless Le 04/05/2010 10:23, Johannes Berg a écrit : > On Tue, 2010-05-04 at 08:47 +0200, Benoit Papillault wrote: >> When configuring an HT IBSS, we need to check if the specified channel >> is capable of ht40+, ht40- or ht20. > > These first two patches cannot be separate. > > johannes > > Right. Will repost a single patch including both. Regards, Benoit ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH] cfg80211: Check for channel HT capabilities in an IBSS 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:23 ` [PATCH] cfg80211: Check for channel HT capabilities in an IBSS Johannes Berg @ 2010-05-04 18:14 ` Luis R. Rodriguez 2010-05-05 6:28 ` Benoit Papillault 2 siblings, 1 reply; 20+ messages in thread From: Luis R. Rodriguez @ 2010-05-04 18:14 UTC (permalink / raw) To: Benoit Papillault; +Cc: johannes, linux-wireless On Mon, May 3, 2010 at 11:47 PM, Benoit Papillault <benoit.papillault@free.fr> wrote: > When configuring an HT IBSS, we need to check if the specified channel > is capable of ht40+, ht40- or ht20. > > Signed-off-by: Benoit Papillault <benoit.papillault@free.fr> > --- > net/wireless/nl80211.c | 8 ++++---- > 1 files changed, 4 insertions(+), 4 deletions(-) > > diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c > index 8da9823..0a82623 100644 > --- a/net/wireless/nl80211.c > +++ b/net/wireless/nl80211.c > @@ -3858,11 +3858,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; Why is the disabled channel check being removed here? Luis ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH] cfg80211: Check for channel HT capabilities in an IBSS 2010-05-04 18:14 ` Luis R. Rodriguez @ 2010-05-05 6:28 ` Benoit Papillault 0 siblings, 0 replies; 20+ messages in thread From: Benoit Papillault @ 2010-05-05 6:28 UTC (permalink / raw) To: Luis R. Rodriguez; +Cc: johannes, linux-wireless Le 04/05/2010 20:14, Luis R. Rodriguez a écrit : > On Mon, May 3, 2010 at 11:47 PM, Benoit Papillault > <benoit.papillault@free.fr> wrote: >> When configuring an HT IBSS, we need to check if the specified channel >> is capable of ht40+, ht40- or ht20. >> >> Signed-off-by: Benoit Papillault<benoit.papillault@free.fr> >> --- >> net/wireless/nl80211.c | 8 ++++---- >> 1 files changed, 4 insertions(+), 4 deletions(-) >> >> diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c >> index 8da9823..0a82623 100644 >> --- a/net/wireless/nl80211.c >> +++ b/net/wireless/nl80211.c >> @@ -3858,11 +3858,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; > > Why is the disabled channel check being removed here? > > Luis > Hi Luis, It's because the check is already done in rdev_freq_to_chan. Regards, Benoit ^ permalink raw reply [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: Move part of the MLME code to helper functions 2010-05-12 21:07 [PATCH] cfg80211: Parse channel_type in NL80211_CMD_JOIN_IBSS Benoit Papillault @ 2010-05-12 21:07 ` Benoit Papillault 2010-05-12 21:07 ` [PATCH] mac80211: Use struct ieee80211_ht_cap to build HT Capabilities IE 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 We moved code parsing the HT Operation IE to get the associated channel type and the HT Capabilities IE generation code to util.c. This is a preliminary step that will be used by HT IBSS code later. Signed-off-by: Benoit Papillault <benoit.papillault@free.fr> --- net/mac80211/ieee80211_i.h | 12 +++ net/mac80211/mlme.c | 20 +----- net/mac80211/util.c | 179 ++++++++++++++++++++++++++++++++++++++------ net/mac80211/work.c | 96 ----------------------- 4 files changed, 170 insertions(+), 137 deletions(-) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 69e7f41..742e12b 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1215,6 +1215,18 @@ size_t ieee80211_ie_split(const u8 *ies, size_t ielen, const u8 *ids, int n_ids, size_t offset); size_t ieee80211_ie_split_vendor(const u8 *ies, size_t ielen, size_t offset); +enum nl80211_channel_type ieee80211_channel_type_from_ht_info( + struct ieee80211_local *local, + struct ieee80211_ht_info *hti, u16 ap_ht_cap_flags); + +void ieee80211_add_ht_ie(struct sk_buff *skb, const u8 *ht_info_ie, + struct ieee80211_supported_band *sband, + struct ieee80211_channel *channel, + enum ieee80211_smps_mode smps); + +u8 *ieee80211_add_ht_cap(u8 *pos, + struct ieee80211_supported_band *sband); + /* internal work items */ void ieee80211_work_init(struct ieee80211_local *local); void ieee80211_add_work(struct ieee80211_work *wk); diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 3093e46..55d96a6 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -155,24 +155,8 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata, enable_ht = false; if (enable_ht) { - channel_type = NL80211_CHAN_HT20; - - if (!(ap_ht_cap_flags & IEEE80211_HT_CAP_40MHZ_INTOLERANT) && - (sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) && - (hti->ht_param & IEEE80211_HT_PARAM_CHAN_WIDTH_ANY)) { - switch(hti->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) { - case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: - if (!(local->hw.conf.channel->flags & - IEEE80211_CHAN_NO_HT40PLUS)) - channel_type = NL80211_CHAN_HT40PLUS; - break; - case IEEE80211_HT_PARAM_CHA_SEC_BELOW: - if (!(local->hw.conf.channel->flags & - IEEE80211_CHAN_NO_HT40MINUS)) - channel_type = NL80211_CHAN_HT40MINUS; - break; - } - } + channel_type = ieee80211_channel_type_from_ht_info(local, + hti, ap_ht_cap_flags); } if (local->tmp_channel) diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 5b79d55..4a76fa5 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -965,29 +965,7 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, offset = noffset; } - if (sband->ht_cap.ht_supported) { - u16 cap = sband->ht_cap.cap; - __le16 tmp; - - if (ieee80211_disable_40mhz_24ghz && - sband->band == IEEE80211_BAND_2GHZ) { - cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; - cap &= ~IEEE80211_HT_CAP_SGI_40; - } - - *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 */ - } + pos = ieee80211_add_ht_cap(pos, sband); /* * If adding more here, adjust code in main.c @@ -1389,3 +1367,158 @@ size_t ieee80211_ie_split_vendor(const u8 *ies, size_t ielen, size_t offset) return pos; } + +enum nl80211_channel_type ieee80211_channel_type_from_ht_info( + struct ieee80211_local *local, + struct ieee80211_ht_info *hti, u16 ap_ht_cap_flags) +{ + struct ieee80211_supported_band *sband; + enum nl80211_channel_type channel_type = NL80211_CHAN_HT20; + + sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; + + if (!(ap_ht_cap_flags & IEEE80211_HT_CAP_40MHZ_INTOLERANT) && + (sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) && + (hti->ht_param & IEEE80211_HT_PARAM_CHAN_WIDTH_ANY)) { + switch (hti->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) { + case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: + if (!(local->hw.conf.channel->flags & + IEEE80211_CHAN_NO_HT40PLUS)) + channel_type = NL80211_CHAN_HT40PLUS; + break; + case IEEE80211_HT_PARAM_CHA_SEC_BELOW: + if (!(local->hw.conf.channel->flags & + IEEE80211_CHAN_NO_HT40MINUS)) + channel_type = NL80211_CHAN_HT40MINUS; + break; + } + } + + return channel_type; +} + +u8 *ieee80211_add_ht_cap(u8 *pos, + struct ieee80211_supported_band *sband) +{ + if (sband->ht_cap.ht_supported) { + u16 cap = sband->ht_cap.cap; + __le16 tmp; + + if (ieee80211_disable_40mhz_24ghz && + sband->band == IEEE80211_BAND_2GHZ) { + cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; + cap &= ~IEEE80211_HT_CAP_SGI_40; + } + + *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 */ + } + + return pos; +} + +void ieee80211_add_ht_ie(struct sk_buff *skb, const u8 *ht_info_ie, + struct ieee80211_supported_band *sband, + struct ieee80211_channel *channel, + enum ieee80211_smps_mode smps) +{ + struct ieee80211_ht_info *ht_info; + u8 *pos; + u32 flags = channel->flags; + u16 cap = sband->ht_cap.cap; + __le16 tmp; + + if (!sband->ht_cap.ht_supported) + return; + + if (!ht_info_ie) + return; + + if (ht_info_ie[1] < sizeof(struct ieee80211_ht_info)) + return; + + ht_info = (struct ieee80211_ht_info *)(ht_info_ie + 2); + + /* determine capability flags */ + + if (ieee80211_disable_40mhz_24ghz && + sband->band == IEEE80211_BAND_2GHZ) { + cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; + cap &= ~IEEE80211_HT_CAP_SGI_40; + } + + switch (ht_info->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) { + case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: + if (flags & IEEE80211_CHAN_NO_HT40PLUS) { + cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; + cap &= ~IEEE80211_HT_CAP_SGI_40; + } + break; + case IEEE80211_HT_PARAM_CHA_SEC_BELOW: + if (flags & IEEE80211_CHAN_NO_HT40MINUS) { + cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; + cap &= ~IEEE80211_HT_CAP_SGI_40; + } + break; + } + + /* set SM PS mode properly */ + cap &= ~IEEE80211_HT_CAP_SM_PS; + switch (smps) { + case IEEE80211_SMPS_AUTOMATIC: + case IEEE80211_SMPS_NUM_MODES: + WARN_ON(1); + case IEEE80211_SMPS_OFF: + cap |= WLAN_HT_CAP_SM_PS_DISABLED << + IEEE80211_HT_CAP_SM_PS_SHIFT; + break; + case IEEE80211_SMPS_STATIC: + cap |= WLAN_HT_CAP_SM_PS_STATIC << + IEEE80211_HT_CAP_SM_PS_SHIFT; + break; + case IEEE80211_SMPS_DYNAMIC: + cap |= WLAN_HT_CAP_SM_PS_DYNAMIC << + IEEE80211_HT_CAP_SM_PS_SHIFT; + break; + } + + /* reserve and fill IE */ + + pos = skb_put(skb, sizeof(struct ieee80211_ht_cap) + 2); + *pos++ = WLAN_EID_HT_CAPABILITY; + *pos++ = sizeof(struct ieee80211_ht_cap); + memset(pos, 0, sizeof(struct ieee80211_ht_cap)); + + /* capability flags */ + tmp = cpu_to_le16(cap); + memcpy(pos, &tmp, sizeof(u16)); + pos += sizeof(u16); + + /* AMPDU parameters */ + *pos++ = sband->ht_cap.ampdu_factor | + (sband->ht_cap.ampdu_density << + IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT); + + /* MCS set */ + memcpy(pos, &sband->ht_cap.mcs, sizeof(sband->ht_cap.mcs)); + pos += sizeof(sband->ht_cap.mcs); + + /* extended capabilities */ + pos += sizeof(__le16); + + /* BF capabilities */ + pos += sizeof(__le32); + + /* antenna selection */ + pos += sizeof(u8); +} diff --git a/net/mac80211/work.c b/net/mac80211/work.c index 3dd0760..df6940d 100644 --- a/net/mac80211/work.c +++ b/net/mac80211/work.c @@ -101,102 +101,6 @@ static int ieee80211_compatible_rates(const u8 *supp_rates, int supp_rates_len, /* frame sending functions */ -static void ieee80211_add_ht_ie(struct sk_buff *skb, const u8 *ht_info_ie, - struct ieee80211_supported_band *sband, - struct ieee80211_channel *channel, - enum ieee80211_smps_mode smps) -{ - struct ieee80211_ht_info *ht_info; - u8 *pos; - u32 flags = channel->flags; - u16 cap = sband->ht_cap.cap; - __le16 tmp; - - if (!sband->ht_cap.ht_supported) - return; - - if (!ht_info_ie) - return; - - if (ht_info_ie[1] < sizeof(struct ieee80211_ht_info)) - return; - - ht_info = (struct ieee80211_ht_info *)(ht_info_ie + 2); - - /* determine capability flags */ - - if (ieee80211_disable_40mhz_24ghz && - sband->band == IEEE80211_BAND_2GHZ) { - cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; - cap &= ~IEEE80211_HT_CAP_SGI_40; - } - - switch (ht_info->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) { - case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: - if (flags & IEEE80211_CHAN_NO_HT40PLUS) { - cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; - cap &= ~IEEE80211_HT_CAP_SGI_40; - } - break; - case IEEE80211_HT_PARAM_CHA_SEC_BELOW: - if (flags & IEEE80211_CHAN_NO_HT40MINUS) { - cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; - cap &= ~IEEE80211_HT_CAP_SGI_40; - } - break; - } - - /* set SM PS mode properly */ - cap &= ~IEEE80211_HT_CAP_SM_PS; - switch (smps) { - case IEEE80211_SMPS_AUTOMATIC: - case IEEE80211_SMPS_NUM_MODES: - WARN_ON(1); - case IEEE80211_SMPS_OFF: - cap |= WLAN_HT_CAP_SM_PS_DISABLED << - IEEE80211_HT_CAP_SM_PS_SHIFT; - break; - case IEEE80211_SMPS_STATIC: - cap |= WLAN_HT_CAP_SM_PS_STATIC << - IEEE80211_HT_CAP_SM_PS_SHIFT; - break; - case IEEE80211_SMPS_DYNAMIC: - cap |= WLAN_HT_CAP_SM_PS_DYNAMIC << - IEEE80211_HT_CAP_SM_PS_SHIFT; - break; - } - - /* reserve and fill IE */ - - pos = skb_put(skb, sizeof(struct ieee80211_ht_cap) + 2); - *pos++ = WLAN_EID_HT_CAPABILITY; - *pos++ = sizeof(struct ieee80211_ht_cap); - memset(pos, 0, sizeof(struct ieee80211_ht_cap)); - - /* capability flags */ - tmp = cpu_to_le16(cap); - memcpy(pos, &tmp, sizeof(u16)); - pos += sizeof(u16); - - /* AMPDU parameters */ - *pos++ = sband->ht_cap.ampdu_factor | - (sband->ht_cap.ampdu_density << - IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT); - - /* MCS set */ - memcpy(pos, &sband->ht_cap.mcs, sizeof(sband->ht_cap.mcs)); - pos += sizeof(sband->ht_cap.mcs); - - /* extended capabilities */ - pos += sizeof(__le16); - - /* BF capabilities */ - pos += sizeof(__le32); - - /* antenna selection */ - pos += sizeof(u8); -} - static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata, struct ieee80211_work *wk) { -- 1.5.6.5 ^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH] mac80211: Use struct ieee80211_ht_cap to build HT Capabilities IE 2010-05-12 21:07 ` [PATCH] mac80211: Move part of the MLME code to helper functions Benoit Papillault @ 2010-05-12 21:07 ` Benoit Papillault 2010-05-12 21:07 ` [PATCH] mac80211: Add HT IE to IBSS beacons and probe responses 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 Instead of writing the HT Capabilities IE byte after byte, we use the existing ieee80211_ht_cap structure. Signed-off-by: Benoit Papillault <benoit.papillault@free.fr> --- net/mac80211/util.c | 55 +++++++++++++++++++++++++-------------------------- 1 files changed, 27 insertions(+), 28 deletions(-) diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 4a76fa5..047acb8 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -1402,7 +1402,7 @@ u8 *ieee80211_add_ht_cap(u8 *pos, { 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) { @@ -1410,18 +1410,20 @@ u8 *ieee80211_add_ht_cap(u8 *pos, cap &= ~IEEE80211_HT_CAP_SGI_40; } - *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 | + 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); - 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 */ + 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++ = WLAN_EID_HT_CAPABILITY; + *pos++ = sizeof(struct ieee80211_ht_cap); + memcpy(pos, &ht_cap, sizeof(struct ieee80211_ht_cap)); + pos += sizeof(struct ieee80211_ht_cap); } return pos; @@ -1436,7 +1438,7 @@ void ieee80211_add_ht_ie(struct sk_buff *skb, const u8 *ht_info_ie, u8 *pos; u32 flags = channel->flags; u16 cap = sband->ht_cap.cap; - __le16 tmp; + struct ieee80211_ht_cap ht_cap; if (!sband->ht_cap.ht_supported) return; @@ -1492,33 +1494,30 @@ void ieee80211_add_ht_ie(struct sk_buff *skb, const u8 *ht_info_ie, break; } - /* reserve and fill IE */ - - pos = skb_put(skb, sizeof(struct ieee80211_ht_cap) + 2); - *pos++ = WLAN_EID_HT_CAPABILITY; - *pos++ = sizeof(struct ieee80211_ht_cap); - memset(pos, 0, sizeof(struct ieee80211_ht_cap)); - /* capability flags */ - tmp = cpu_to_le16(cap); - memcpy(pos, &tmp, sizeof(u16)); - pos += sizeof(u16); + ht_cap.cap_info = cpu_to_le16(cap); /* AMPDU parameters */ - *pos++ = sband->ht_cap.ampdu_factor | + ht_cap.ampdu_params_info = sband->ht_cap.ampdu_factor | (sband->ht_cap.ampdu_density << IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT); /* MCS set */ - memcpy(pos, &sband->ht_cap.mcs, sizeof(sband->ht_cap.mcs)); - pos += sizeof(sband->ht_cap.mcs); + ht_cap.mcs = sband->ht_cap.mcs; /* extended capabilities */ - pos += sizeof(__le16); + ht_cap.extended_ht_cap_info = cpu_to_le16(0); /* BF capabilities */ - pos += sizeof(__le32); + ht_cap.tx_BF_cap_info = cpu_to_le32(0); /* antenna selection */ - pos += sizeof(u8); + ht_cap.antenna_selection_info = 0; + + /* reserve and fill IE */ + 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)); } -- 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-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; 20+ 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] 20+ 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; 20+ 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] 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
* Re: [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 2010-01-20 14:45 ` X Xiao 0 siblings, 1 reply; 20+ 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] 20+ 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; 20+ 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] 20+ 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; 20+ 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] 20+ 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; 20+ 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] 20+ 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; 20+ 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] 20+ 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; 20+ 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] 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).