* [PATCH 0/2] modify the inclusion of supported channels IE @ 2013-12-31 15:32 Ilan Peer 2013-12-31 15:32 ` [PATCH 1/2] cfg80211: Add a function to get the number of enabled channels Ilan Peer 2013-12-31 15:32 ` [PATCH 2/2] [RFC] mac80211: Add all enabled channels to the supported channels element Ilan Peer 0 siblings, 2 replies; 12+ messages in thread From: Ilan Peer @ 2013-12-31 15:32 UTC (permalink / raw) To: linux-wireless; +Cc: Ilan Peer The 80211-2012 specification defines in 8.4.2.20 that the supported channels information element should contain a list of the channel subbands in which the station is capable to operate. Change the mac80211 implementation to add all the channels currently enabled by the device (excluding disabled channels). Note: the implementation is not complete as it missing an better handling for subband in bands other than 2.4 GHz. Ilan Peer (2): cfg80211: Add a function to get the number of enabled channels mac80211: Add all enabled channels to the supported channels element include/net/cfg80211.h | 9 ++++++ net/mac80211/mlme.c | 80 ++++++++++++++++++++++++++++++++++++++++++------ net/wireless/util.c | 21 +++++++++++++ 3 files changed, 100 insertions(+), 10 deletions(-) -- 1.7.10.4 ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 1/2] cfg80211: Add a function to get the number of enabled channels 2013-12-31 15:32 [PATCH 0/2] modify the inclusion of supported channels IE Ilan Peer @ 2013-12-31 15:32 ` Ilan Peer 2014-01-09 9:17 ` [PATCH 1/2 v2] cfg80211: Add a function to get the number of supported channels Ilan Peer 2013-12-31 15:32 ` [PATCH 2/2] [RFC] mac80211: Add all enabled channels to the supported channels element Ilan Peer 1 sibling, 1 reply; 12+ messages in thread From: Ilan Peer @ 2013-12-31 15:32 UTC (permalink / raw) To: linux-wireless; +Cc: Ilan Peer Add a utility function to get the number of channels enabled by the device. Signed-off-by: Ilan Peer <ilan.peer@intel.com> --- include/net/cfg80211.h | 9 +++++++++ net/wireless/util.c | 21 +++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 80a1021..405ef5b 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -4532,6 +4532,15 @@ void cfg80211_report_wowlan_wakeup(struct wireless_dev *wdev, */ void cfg80211_crit_proto_stopped(struct wireless_dev *wdev, gfp_t gfp); +/** + * ieee80211_get_num_enabled_channels - get the number of channels supported + * and enabled by the device. + * @wiphy: the wiphy + * + * Return: the number of channels supported and enabled by the device. + */ +unsigned int ieee80211_get_num_enabled_channels(struct wiphy *wiphy); + /* Logging, debugging and troubleshooting/diagnostic helpers. */ /* wiphy_printk helpers, similar to dev_printk */ diff --git a/net/wireless/util.c b/net/wireless/util.c index 935dea9..fb5f685 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -1462,6 +1462,27 @@ int ieee80211_get_ratemask(struct ieee80211_supported_band *sband, return 0; } +unsigned int ieee80211_get_num_enabled_channels(struct wiphy *wiphy) +{ + struct ieee80211_supported_band *sband; + unsigned int n_channels, i, j; + + for (i = 0, n_channels = 0; i < IEEE80211_NUM_BANDS; i++) { + sband = wiphy->bands[i]; + if (!sband) + continue; + + for (j = 0; j < sband->n_channels; j++) { + if (!(sband->channels[j].flags & + IEEE80211_CHAN_DISABLED)) + n_channels++; + } + } + + return n_channels; +} +EXPORT_SYMBOL(ieee80211_get_num_enabled_channels); + /* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */ /* Ethernet-II snap header (RFC1042 for most EtherTypes) */ const unsigned char rfc1042_header[] __aligned(2) = -- 1.7.10.4 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 1/2 v2] cfg80211: Add a function to get the number of supported channels 2013-12-31 15:32 ` [PATCH 1/2] cfg80211: Add a function to get the number of enabled channels Ilan Peer @ 2014-01-09 9:17 ` Ilan Peer 2014-01-09 9:18 ` Johannes Berg ` (2 more replies) 0 siblings, 3 replies; 12+ messages in thread From: Ilan Peer @ 2014-01-09 9:17 UTC (permalink / raw) To: linux-wireless; +Cc: Ilan Peer Add a utility function to get the number of channels supported by the device, and update the places in the code that need this data. Signed-off-by: Ilan Peer <ilan.peer@intel.com> --- include/net/cfg80211.h | 9 +++++++++ net/wireless/nl80211.c | 13 ++----------- net/wireless/scan.c | 7 ++----- net/wireless/sme.c | 13 +++---------- net/wireless/util.c | 13 +++++++++++++ 5 files changed, 29 insertions(+), 26 deletions(-) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 56c5977..b5ed170 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -4640,6 +4640,15 @@ void cfg80211_report_wowlan_wakeup(struct wireless_dev *wdev, */ void cfg80211_crit_proto_stopped(struct wireless_dev *wdev, gfp_t gfp); +/** + * ieee80211_get_num_supported_channels - get the number of channels supported + * by the device. + * @wiphy: the wiphy + * + * Return: the number of channels supported by the device. + */ +unsigned int ieee80211_get_num_supported_channels(struct wiphy *wiphy); + /* Logging, debugging and troubleshooting/diagnostic helpers. */ /* wiphy_printk helpers, similar to dev_printk */ diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index b4f40fe..2404564 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -5285,12 +5285,7 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) goto unlock; } } else { - enum ieee80211_band band; - n_channels = 0; - - for (band = 0; band < IEEE80211_NUM_BANDS; band++) - if (wiphy->bands[band]) - n_channels += wiphy->bands[band]->n_channels; + n_channels = ieee80211_get_num_supported_channels(wiphy); } if (info->attrs[NL80211_ATTR_SCAN_SSIDS]) @@ -5498,11 +5493,7 @@ static int nl80211_start_sched_scan(struct sk_buff *skb, if (!n_channels) return -EINVAL; } else { - n_channels = 0; - - for (band = 0; band < IEEE80211_NUM_BANDS; band++) - if (wiphy->bands[band]) - n_channels += wiphy->bands[band]->n_channels; + n_channels = ieee80211_get_num_supported_channels(wiphy); } if (info->attrs[NL80211_ATTR_SCAN_SSIDS]) diff --git a/net/wireless/scan.c b/net/wireless/scan.c index a32d52a..2bf4686 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c @@ -1089,11 +1089,8 @@ int cfg80211_wext_siwscan(struct net_device *dev, /* Determine number of channels, needed to allocate creq */ if (wreq && wreq->num_channels) n_channels = wreq->num_channels; - else { - for (band = 0; band < IEEE80211_NUM_BANDS; band++) - if (wiphy->bands[band]) - n_channels += wiphy->bands[band]->n_channels; - } + else + n_channles = ieee80211_get_num_supported_channels(wiphy); creq = kzalloc(sizeof(*creq) + sizeof(struct cfg80211_ssid) + n_channels * sizeof(void *), diff --git a/net/wireless/sme.c b/net/wireless/sme.c index 5d6e7bb..a635091 100644 --- a/net/wireless/sme.c +++ b/net/wireless/sme.c @@ -70,18 +70,11 @@ static int cfg80211_conn_scan(struct wireless_dev *wdev) if (rdev->scan_req) return -EBUSY; - if (wdev->conn->params.channel) { + if (wdev->conn->params.channel) n_channels = 1; - } else { - enum ieee80211_band band; - n_channels = 0; + else + n_channels = ieee80211_get_num_supported_channels(wdev->wiphy); - for (band = 0; band < IEEE80211_NUM_BANDS; band++) { - if (!wdev->wiphy->bands[band]) - continue; - n_channels += wdev->wiphy->bands[band]->n_channels; - } - } request = kzalloc(sizeof(*request) + sizeof(request->ssids[0]) + sizeof(request->channels[0]) * n_channels, GFP_KERNEL); diff --git a/net/wireless/util.c b/net/wireless/util.c index 5618888..959c43c 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -1479,6 +1479,19 @@ int ieee80211_get_ratemask(struct ieee80211_supported_band *sband, return 0; } +unsigned int ieee80211_get_num_supported_channels(struct wiphy *wiphy) +{ + enum ieee80211_band band; + unsigned int n_channels; + + for (band = 0, n_channels = 0; band < IEEE80211_NUM_BANDS; band++) + if (wiphy->bands[band]) + n_channels += wiphy->bands[band]->n_channels; + + return n_channels; +} +EXPORT_SYMBOL(ieee80211_get_num_supported_channels); + /* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */ /* Ethernet-II snap header (RFC1042 for most EtherTypes) */ const unsigned char rfc1042_header[] __aligned(2) = -- 1.7.10.4 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH 1/2 v2] cfg80211: Add a function to get the number of supported channels 2014-01-09 9:17 ` [PATCH 1/2 v2] cfg80211: Add a function to get the number of supported channels Ilan Peer @ 2014-01-09 9:18 ` Johannes Berg 2014-01-09 9:18 ` Johannes Berg 2014-01-09 9:37 ` [PATCH 1/2 v3] " Ilan Peer 2 siblings, 0 replies; 12+ messages in thread From: Johannes Berg @ 2014-01-09 9:18 UTC (permalink / raw) To: Ilan Peer; +Cc: linux-wireless On Thu, 2014-01-09 at 11:17 +0200, Ilan Peer wrote: > + else > + n_channles = ieee80211_get_num_supported_channels(wiphy); err ... johannes ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 1/2 v2] cfg80211: Add a function to get the number of supported channels 2014-01-09 9:17 ` [PATCH 1/2 v2] cfg80211: Add a function to get the number of supported channels Ilan Peer 2014-01-09 9:18 ` Johannes Berg @ 2014-01-09 9:18 ` Johannes Berg 2014-01-09 9:37 ` [PATCH 1/2 v3] " Ilan Peer 2 siblings, 0 replies; 12+ messages in thread From: Johannes Berg @ 2014-01-09 9:18 UTC (permalink / raw) To: Ilan Peer; +Cc: linux-wireless On Thu, 2014-01-09 at 11:17 +0200, Ilan Peer wrote: > +unsigned int ieee80211_get_num_supported_channels(struct wiphy *wiphy) > +{ > + enum ieee80211_band band; > + unsigned int n_channels; Seems nicer to do the = 0 here rather than in the loop? > + for (band = 0, n_channels = 0; band < IEEE80211_NUM_BANDS; band++) johannes ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 1/2 v3] cfg80211: Add a function to get the number of supported channels 2014-01-09 9:17 ` [PATCH 1/2 v2] cfg80211: Add a function to get the number of supported channels Ilan Peer 2014-01-09 9:18 ` Johannes Berg 2014-01-09 9:18 ` Johannes Berg @ 2014-01-09 9:37 ` Ilan Peer 2014-01-09 12:57 ` Johannes Berg 2 siblings, 1 reply; 12+ messages in thread From: Ilan Peer @ 2014-01-09 9:37 UTC (permalink / raw) To: linux-wireless; +Cc: Ilan Peer Add a utility function to get the number of channels supported by the device, and update the places in the code that need this data. Signed-off-by: Ilan Peer <ilan.peer@intel.com> --- include/net/cfg80211.h | 9 +++++++++ net/wireless/nl80211.c | 13 ++----------- net/wireless/scan.c | 7 ++----- net/wireless/sme.c | 13 +++---------- net/wireless/util.c | 13 +++++++++++++ 5 files changed, 29 insertions(+), 26 deletions(-) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 56c5977..b5ed170 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -4640,6 +4640,15 @@ void cfg80211_report_wowlan_wakeup(struct wireless_dev *wdev, */ void cfg80211_crit_proto_stopped(struct wireless_dev *wdev, gfp_t gfp); +/** + * ieee80211_get_num_supported_channels - get the number of channels supported + * by the device. + * @wiphy: the wiphy + * + * Return: the number of channels supported by the device. + */ +unsigned int ieee80211_get_num_supported_channels(struct wiphy *wiphy); + /* Logging, debugging and troubleshooting/diagnostic helpers. */ /* wiphy_printk helpers, similar to dev_printk */ diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index b4f40fe..2404564 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -5285,12 +5285,7 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) goto unlock; } } else { - enum ieee80211_band band; - n_channels = 0; - - for (band = 0; band < IEEE80211_NUM_BANDS; band++) - if (wiphy->bands[band]) - n_channels += wiphy->bands[band]->n_channels; + n_channels = ieee80211_get_num_supported_channels(wiphy); } if (info->attrs[NL80211_ATTR_SCAN_SSIDS]) @@ -5498,11 +5493,7 @@ static int nl80211_start_sched_scan(struct sk_buff *skb, if (!n_channels) return -EINVAL; } else { - n_channels = 0; - - for (band = 0; band < IEEE80211_NUM_BANDS; band++) - if (wiphy->bands[band]) - n_channels += wiphy->bands[band]->n_channels; + n_channels = ieee80211_get_num_supported_channels(wiphy); } if (info->attrs[NL80211_ATTR_SCAN_SSIDS]) diff --git a/net/wireless/scan.c b/net/wireless/scan.c index a32d52a..2bf4686 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c @@ -1089,11 +1089,8 @@ int cfg80211_wext_siwscan(struct net_device *dev, /* Determine number of channels, needed to allocate creq */ if (wreq && wreq->num_channels) n_channels = wreq->num_channels; - else { - for (band = 0; band < IEEE80211_NUM_BANDS; band++) - if (wiphy->bands[band]) - n_channels += wiphy->bands[band]->n_channels; - } + else + n_channles = ieee80211_get_num_supported_channels(wiphy); creq = kzalloc(sizeof(*creq) + sizeof(struct cfg80211_ssid) + n_channels * sizeof(void *), diff --git a/net/wireless/sme.c b/net/wireless/sme.c index 5d6e7bb..a635091 100644 --- a/net/wireless/sme.c +++ b/net/wireless/sme.c @@ -70,18 +70,11 @@ static int cfg80211_conn_scan(struct wireless_dev *wdev) if (rdev->scan_req) return -EBUSY; - if (wdev->conn->params.channel) { + if (wdev->conn->params.channel) n_channels = 1; - } else { - enum ieee80211_band band; - n_channels = 0; + else + n_channels = ieee80211_get_num_supported_channels(wdev->wiphy); - for (band = 0; band < IEEE80211_NUM_BANDS; band++) { - if (!wdev->wiphy->bands[band]) - continue; - n_channels += wdev->wiphy->bands[band]->n_channels; - } - } request = kzalloc(sizeof(*request) + sizeof(request->ssids[0]) + sizeof(request->channels[0]) * n_channels, GFP_KERNEL); diff --git a/net/wireless/util.c b/net/wireless/util.c index 5618888..959c43c 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -1479,6 +1479,19 @@ int ieee80211_get_ratemask(struct ieee80211_supported_band *sband, return 0; } +unsigned int ieee80211_get_num_supported_channels(struct wiphy *wiphy) +{ + enum ieee80211_band band; + unsigned int n_channels; + + for (band = 0, n_channels = 0; band < IEEE80211_NUM_BANDS; band++) + if (wiphy->bands[band]) + n_channels += wiphy->bands[band]->n_channels; + + return n_channels; +} +EXPORT_SYMBOL(ieee80211_get_num_supported_channels); + /* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */ /* Ethernet-II snap header (RFC1042 for most EtherTypes) */ const unsigned char rfc1042_header[] __aligned(2) = -- 1.7.10.4 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH 1/2 v3] cfg80211: Add a function to get the number of supported channels 2014-01-09 9:37 ` [PATCH 1/2 v3] " Ilan Peer @ 2014-01-09 12:57 ` Johannes Berg 0 siblings, 0 replies; 12+ messages in thread From: Johannes Berg @ 2014-01-09 12:57 UTC (permalink / raw) To: Ilan Peer; +Cc: linux-wireless On Thu, 2014-01-09 at 11:37 +0200, Ilan Peer wrote: > Add a utility function to get the number of channels supported by > the device, and update the places in the code that need this data. Applied with some fixes. johannes ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 2/2] [RFC] mac80211: Add all enabled channels to the supported channels element 2013-12-31 15:32 [PATCH 0/2] modify the inclusion of supported channels IE Ilan Peer 2013-12-31 15:32 ` [PATCH 1/2] cfg80211: Add a function to get the number of enabled channels Ilan Peer @ 2013-12-31 15:32 ` Ilan Peer 2013-12-31 15:33 ` Peer, Ilan ` (2 more replies) 1 sibling, 3 replies; 12+ messages in thread From: Ilan Peer @ 2013-12-31 15:32 UTC (permalink / raw) To: linux-wireless; +Cc: Ilan Peer In the current implementation, in case that the AP supports spectrum management, the supported channels information element added to the association and re-association frames includes only the channels that where in the same band as that of the operating channel of the AP. However, the 80211-2012 specification defines in 8.4.2.20 that the supported channels information element should contain a list of the channel subbands in which the station is capable to operate. Fix this gap by including all the channels enabled by the device (excluding channels that are marked as disabled). Signed-off-by: Ilan Peer <ilan.peer@intel.com> --- net/mac80211/mlme.c | 80 ++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 70 insertions(+), 10 deletions(-) diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 9c2c7ee..04da17d 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -540,6 +540,70 @@ static void ieee80211_add_vht_ie(struct ieee80211_sub_if_data *sdata, ieee80211_ie_build_vht_cap(pos, &vht_cap, cap); } +static void ieee80211_add_supported_channels(struct ieee80211_local *local, + struct sk_buff *skb, + unsigned int n_channels) +{ + struct ieee80211_supported_band *sband; + unsigned int i, j; + u8 *pos, *len_pos; + + if (!n_channels) + return; + + pos = skb_put(skb, 2); + *pos++ = WLAN_EID_SUPPORTED_CHANNELS; + len_pos = pos; + *len_pos = 0; + + for (i = 0; i < IEEE80211_NUM_BANDS; i++) { + u8 chan, first_chan = 0, count = 0; + + sband = local->hw.wiphy->bands[i]; + if (!sband) + continue; + + for (j = 0; j < sband->n_channels; j++) { + u16 center_freq; + + if (sband->channels[j].flags & IEEE80211_CHAN_DISABLED) + continue; + + center_freq = sband->channels[j].center_freq; + chan = ieee80211_frequency_to_channel(center_freq); + + if (first_chan == 0) { + /* first subband */ + first_chan = chan; + count = 1; + } else if (first_chan + count == chan) { + /* continue the subband. + * TODO: this is really only useful for 2.4, + * need to add spacing considerations for other + * bands as well (the definition of a subband + * in the 802.11 spec. is a bit vague). + */ + count++; + } else { + /* store the subband and start a new one */ + pos = skb_put(skb, 2); + *pos++ = first_chan; + *pos = count; + *len_pos += 2; + first_chan = chan; + count = 1; + } + } + + if (first_chan) { + pos = skb_put(skb, 2); + *pos++ = first_chan; + *pos = count; + *len_pos += 2; + } + } +} + static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) { struct ieee80211_local *local = sdata->local; @@ -555,6 +619,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) struct ieee80211_chanctx_conf *chanctx_conf; struct ieee80211_channel *chan; u32 rate_flags, rates = 0; + unsigned int n_channels; sdata_assert_lock(sdata); @@ -597,12 +662,15 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) } } + /* Get the number of enabled channels for spectrum management */ + n_channels = ieee80211_get_num_enabled_channels(local->hw.wiphy); + skb = alloc_skb(local->hw.extra_tx_headroom + sizeof(*mgmt) + /* bit too much but doesn't matter */ 2 + assoc_data->ssid_len + /* SSID */ 4 + rates_len + /* (extended) rates */ 4 + /* power capability */ - 2 + 2 * sband->n_channels + /* supported channels */ + 2 + 2 * n_channels + /* supported channels */ 2 + sizeof(struct ieee80211_ht_cap) + /* HT */ 2 + sizeof(struct ieee80211_vht_cap) + /* VHT */ assoc_data->ie_len + /* extra IEs */ @@ -704,15 +772,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) *pos++ = ieee80211_chandef_max_power(&chanctx_conf->def); /* 2. supported channels */ - /* TODO: get this in reg domain format */ - pos = skb_put(skb, 2 * sband->n_channels + 2); - *pos++ = WLAN_EID_SUPPORTED_CHANNELS; - *pos++ = 2 * sband->n_channels; - for (i = 0; i < sband->n_channels; i++) { - *pos++ = ieee80211_frequency_to_channel( - sband->channels[i].center_freq); - *pos++ = 1; /* one channel in the subband*/ - } + ieee80211_add_supported_channels(local, skb, n_channels); } /* if present, add any custom IEs that go before HT */ -- 1.7.10.4 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* RE: [PATCH 2/2] [RFC] mac80211: Add all enabled channels to the supported channels element 2013-12-31 15:32 ` [PATCH 2/2] [RFC] mac80211: Add all enabled channels to the supported channels element Ilan Peer @ 2013-12-31 15:33 ` Peer, Ilan 2014-01-07 15:30 ` Johannes Berg 2014-01-09 9:18 ` [PATCH 2/2 v2] [RFC]mac80211: " Ilan Peer 2 siblings, 0 replies; 12+ messages in thread From: Peer, Ilan @ 2013-12-31 15:33 UTC (permalink / raw) To: linux-wireless@vger.kernel.org > In the current implementation, in case that the AP supports spectrum > management, the supported channels information element added to the > association and re-association frames includes only the channels that where > in the same band as that of the operating channel of the AP. > However, the 80211-2012 specification defines in 8.4.2.20 that the supported > channels information element should contain a list of the channel subbands > in which the station is capable to operate. > > + > + if (first_chan == 0) { > + /* first subband */ > + first_chan = chan; > + count = 1; > + } else if (first_chan + count == chan) { > + /* continue the subband. > + * TODO: this is really only useful for 2.4, > + * need to add spacing considerations for > other > + * bands as well (the definition of a subband > + * in the 802.11 spec. is a bit vague). > + */ Any suggestions on how to better handle this? Thanks in advance :) Ilan. ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 2/2] [RFC] mac80211: Add all enabled channels to the supported channels element 2013-12-31 15:32 ` [PATCH 2/2] [RFC] mac80211: Add all enabled channels to the supported channels element Ilan Peer 2013-12-31 15:33 ` Peer, Ilan @ 2014-01-07 15:30 ` Johannes Berg 2014-01-09 7:42 ` Peer, Ilan 2014-01-09 9:18 ` [PATCH 2/2 v2] [RFC]mac80211: " Ilan Peer 2 siblings, 1 reply; 12+ messages in thread From: Johannes Berg @ 2014-01-07 15:30 UTC (permalink / raw) To: Ilan Peer; +Cc: linux-wireless On Tue, 2013-12-31 at 17:32 +0200, Ilan Peer wrote: > + chan = > ieee80211_frequency_to_channel(center_freq); > + > + if (first_chan == 0) { > + /* first subband */ > + first_chan = chan; > + count = 1; > + } else if (first_chan + count == chan) { > + /* continue the subband. > + * TODO: this is really only useful > for 2.4, > + * need to add spacing considerations for other > + * bands as well (the definition of a > subband > + * in the 802.11 spec. is a bit > vague). > + */ > + count++; I agree this is very vague - anyone have a good idea who to ask? As it is now, I'm not sure it's correct at all, even in the version we have today, since different operating classes could have different requirements. Especially since we support 5/10 MHz now, I suspect even ieee80211_frequency_to_channel() really should be taught about operating classes in some form? > + /* Get the number of enabled channels for spectrum management */ > + n_channels = ieee80211_get_num_enabled_channels(local->hw.wiphy); I would prefer you did this with an upper bound rather than the number of enabled channels - we don't need a good estimate, worst case we'll allocate a few bytes too many, but if we get it completely wrong e.g. because the channel flags are being changed, then we could overrun the SKB allocation, I think? It'd also be faster to iterate only the bands and add up n_channels rather than checking each channel's enabled bit. johannes ^ permalink raw reply [flat|nested] 12+ messages in thread
* RE: [PATCH 2/2] [RFC] mac80211: Add all enabled channels to the supported channels element 2014-01-07 15:30 ` Johannes Berg @ 2014-01-09 7:42 ` Peer, Ilan 0 siblings, 0 replies; 12+ messages in thread From: Peer, Ilan @ 2014-01-09 7:42 UTC (permalink / raw) To: Johannes Berg; +Cc: linux-wireless@vger.kernel.org PiA+ICsgICAgICAgICAgICAgICAgICAgICAgIGNoYW4gPQ0KPiA+IGllZWU4MDIxMV9mcmVxdWVu Y3lfdG9fY2hhbm5lbChjZW50ZXJfZnJlcSk7DQo+ID4gKw0KPiA+ICsgICAgICAgICAgICAgICAg ICAgICAgIGlmIChmaXJzdF9jaGFuID09IDApIHsNCj4gPiArICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgIC8qIGZpcnN0IHN1YmJhbmQgKi8NCj4gPiArICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgIGZpcnN0X2NoYW4gPSBjaGFuOw0KPiA+ICsgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgY291bnQgPSAxOw0KPiA+ICsgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBp ZiAoZmlyc3RfY2hhbiArIGNvdW50ID09IGNoYW4pIHsNCj4gPiArICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgIC8qIGNvbnRpbnVlIHRoZSBzdWJiYW5kLg0KPiA+ICsgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICogVE9ETzogdGhpcyBpcyByZWFsbHkgb25seSB1c2VmdWwNCj4g PiBmb3IgMi40LA0KPiA+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogbmVlZCB0 byBhZGQgc3BhY2luZyBjb25zaWRlcmF0aW9ucyBmb3Igb3RoZXINCj4gPiArICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAqIGJhbmRzIGFzIHdlbGwgKHRoZSBkZWZpbml0aW9uIG9mIGEN Cj4gPiBzdWJiYW5kDQo+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBpbiB0 aGUgODAyLjExIHNwZWMuIGlzIGEgYml0DQo+ID4gdmFndWUpLg0KPiA+ICsgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICovDQo+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICBjb3VudCsrOw0KPiANCj4gSSBhZ3JlZSB0aGlzIGlzIHZlcnkgdmFndWUgLSBhbnlvbmUgaGF2 ZSBhIGdvb2QgaWRlYSB3aG8gdG8gYXNrPw0KPiANCj4gQXMgaXQgaXMgbm93LCBJJ20gbm90IHN1 cmUgaXQncyBjb3JyZWN0IGF0IGFsbCwgZXZlbiBpbiB0aGUgdmVyc2lvbiB3ZSBoYXZlIHRvZGF5 LA0KPiBzaW5jZSBkaWZmZXJlbnQgb3BlcmF0aW5nIGNsYXNzZXMgY291bGQgaGF2ZSBkaWZmZXJl bnQgcmVxdWlyZW1lbnRzLg0KPiBFc3BlY2lhbGx5IHNpbmNlIHdlIHN1cHBvcnQgNS8xMCBNSHog bm93LCBJIHN1c3BlY3QgZXZlbg0KPiBpZWVlODAyMTFfZnJlcXVlbmN5X3RvX2NoYW5uZWwoKSBy ZWFsbHkgc2hvdWxkIGJlIHRhdWdodCBhYm91dCBvcGVyYXRpbmcNCj4gY2xhc3NlcyBpbiBzb21l IGZvcm0/DQo+IA0KPiA+ICsJLyogR2V0IHRoZSBudW1iZXIgb2YgZW5hYmxlZCBjaGFubmVscyBm b3Igc3BlY3RydW0gbWFuYWdlbWVudA0KPiAqLw0KPiA+ICsJbl9jaGFubmVscyA9IGllZWU4MDIx MV9nZXRfbnVtX2VuYWJsZWRfY2hhbm5lbHMobG9jYWwtDQo+ID5ody53aXBoeSk7DQo+IA0KPiBJ IHdvdWxkIHByZWZlciB5b3UgZGlkIHRoaXMgd2l0aCBhbiB1cHBlciBib3VuZCByYXRoZXIgdGhh biB0aGUgbnVtYmVyIG9mDQo+IGVuYWJsZWQgY2hhbm5lbHMgLSB3ZSBkb24ndCBuZWVkIGEgZ29v ZCBlc3RpbWF0ZSwgd29yc3QgY2FzZSB3ZSdsbCBhbGxvY2F0ZQ0KPiBhIGZldyBieXRlcyB0b28g bWFueSwgYnV0IGlmIHdlIGdldCBpdCBjb21wbGV0ZWx5IHdyb25nIGUuZy4NCj4gYmVjYXVzZSB0 aGUgY2hhbm5lbCBmbGFncyBhcmUgYmVpbmcgY2hhbmdlZCwgdGhlbiB3ZSBjb3VsZCBvdmVycnVu IHRoZSBTS0INCj4gYWxsb2NhdGlvbiwgSSB0aGluaz8NCj4gDQo+IEl0J2QgYWxzbyBiZSBmYXN0 ZXIgdG8gaXRlcmF0ZSBvbmx5IHRoZSBiYW5kcyBhbmQgYWRkIHVwIG5fY2hhbm5lbHMgcmF0aGVy DQo+IHRoYW4gY2hlY2tpbmcgZWFjaCBjaGFubmVsJ3MgZW5hYmxlZCBiaXQuDQo+DQoNClN1cmUu IEknbGwgbW9kaWZ5IHRoZSB1dGlsaXR5IGZ1bmN0aW9uIGFzIHRoZSBzYW1lIGxvZ2ljIHRoYXQg eW91IHN1Z2dlc3RlZCBpcyB1c2VkIGluIGEgY291cGxlIG9mIG90aGVyICBwbGFjZXMgaW4gdGhl IGNvZGUuDQoNCklsYW4uDQo= ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 2/2 v2] [RFC]mac80211: Add all enabled channels to the supported channels element 2013-12-31 15:32 ` [PATCH 2/2] [RFC] mac80211: Add all enabled channels to the supported channels element Ilan Peer 2013-12-31 15:33 ` Peer, Ilan 2014-01-07 15:30 ` Johannes Berg @ 2014-01-09 9:18 ` Ilan Peer 2 siblings, 0 replies; 12+ messages in thread From: Ilan Peer @ 2014-01-09 9:18 UTC (permalink / raw) To: linux-wireless; +Cc: Ilan Peer In the current implementation, in case that the AP supports spectrum management, the supported channels information element added to the association and re-association frames includes only the channels that where in the same band as that of the operating channel of the AP. However, the 80211-2012 specification defines in 8.4.2.20 that the supported channels information element should contain a list of the channel subbands in which the station is capable to operate. Fix this gap by include all the channels enabled by the station (excluding channels that are marked as disabled). Signed-off-by: Ilan Peer <ilan.peer@intel.com> --- net/mac80211/mlme.c | 77 ++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 67 insertions(+), 10 deletions(-) diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index fc1d824..d26f7e2 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -540,6 +540,67 @@ static void ieee80211_add_vht_ie(struct ieee80211_sub_if_data *sdata, ieee80211_ie_build_vht_cap(pos, &vht_cap, cap); } +static void ieee80211_add_supported_channels(struct ieee80211_local *local, + struct sk_buff *skb, + unsigned int n_channels) +{ + struct ieee80211_supported_band *sband; + unsigned int i, j; + u8 *pos, *len_pos; + + pos = skb_put(skb, 2); + *pos++ = WLAN_EID_SUPPORTED_CHANNELS; + len_pos = pos; + *len_pos = 0; + + for (i = 0; i < IEEE80211_NUM_BANDS; i++) { + u8 chan, first_chan = 0, count = 0; + + sband = local->hw.wiphy->bands[i]; + if (!sband) + continue; + + for (j = 0; j < sband->n_channels; j++) { + u16 center_freq; + + if (sband->channels[j].flags & IEEE80211_CHAN_DISABLED) + continue; + + center_freq = sband->channels[j].center_freq; + chan = ieee80211_frequency_to_channel(center_freq); + + if (first_chan == 0) { + /* first subband */ + first_chan = chan; + count = 1; + } else if (first_chan + count == chan) { + /* continue the subband. + * TODO: this is really only useful for 2.4, + * need to add spacing considerations for other + * bands as well (the definition of a subband + * in the 802.11 spec. is a bit vague). + */ + count++; + } else { + /* store the subband and start a new one */ + pos = skb_put(skb, 2); + *pos++ = first_chan; + *pos = count; + *len_pos += 2; + first_chan = chan; + count = 1; + } + } + + if (first_chan) { + pos = skb_put(skb, 2); + *pos++ = first_chan; + *pos = count; + *len_pos += 2; + } + } +} + static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) { struct ieee80211_local *local = sdata->local; @@ -555,6 +616,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) struct ieee80211_chanctx_conf *chanctx_conf; struct ieee80211_channel *chan; u32 rate_flags, rates = 0; + unsigned int n_channels; sdata_assert_lock(sdata); @@ -597,12 +659,15 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) } } + /* Get the number of supported channels for spectrum management */ + n_channels = ieee80211_get_num_supported_channels(local->hw.wiphy); + skb = alloc_skb(local->hw.extra_tx_headroom + sizeof(*mgmt) + /* bit too much but doesn't matter */ 2 + assoc_data->ssid_len + /* SSID */ 4 + rates_len + /* (extended) rates */ 4 + /* power capability */ - 2 + 2 * sband->n_channels + /* supported channels */ + 2 + 2 * n_channels + /* supported channels */ 2 + sizeof(struct ieee80211_ht_cap) + /* HT */ 2 + sizeof(struct ieee80211_vht_cap) + /* VHT */ assoc_data->ie_len + /* extra IEs */ @@ -704,15 +769,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) *pos++ = ieee80211_chandef_max_power(&chanctx_conf->def); /* 2. supported channels */ - /* TODO: get this in reg domain format */ - pos = skb_put(skb, 2 * sband->n_channels + 2); - *pos++ = WLAN_EID_SUPPORTED_CHANNELS; - *pos++ = 2 * sband->n_channels; - for (i = 0; i < sband->n_channels; i++) { - *pos++ = ieee80211_frequency_to_channel( - sband->channels[i].center_freq); - *pos++ = 1; /* one channel in the subband*/ - } + ieee80211_add_supported_channels(local, skb, n_channels); } /* if present, add any custom IEs that go before HT */ -- 1.7.10.4 ^ permalink raw reply related [flat|nested] 12+ messages in thread
end of thread, other threads:[~2014-01-09 12:57 UTC | newest] Thread overview: 12+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2013-12-31 15:32 [PATCH 0/2] modify the inclusion of supported channels IE Ilan Peer 2013-12-31 15:32 ` [PATCH 1/2] cfg80211: Add a function to get the number of enabled channels Ilan Peer 2014-01-09 9:17 ` [PATCH 1/2 v2] cfg80211: Add a function to get the number of supported channels Ilan Peer 2014-01-09 9:18 ` Johannes Berg 2014-01-09 9:18 ` Johannes Berg 2014-01-09 9:37 ` [PATCH 1/2 v3] " Ilan Peer 2014-01-09 12:57 ` Johannes Berg 2013-12-31 15:32 ` [PATCH 2/2] [RFC] mac80211: Add all enabled channels to the supported channels element Ilan Peer 2013-12-31 15:33 ` Peer, Ilan 2014-01-07 15:30 ` Johannes Berg 2014-01-09 7:42 ` Peer, Ilan 2014-01-09 9:18 ` [PATCH 2/2 v2] [RFC]mac80211: " Ilan Peer
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.