From: Alexander Simon <alexander.simon@saxnet.de>
To: linux-wireless@vger.kernel.org
Subject: [RFC v3 1/3] mac80211: add some helper functions
Date: Tue, 21 Jun 2011 17:45:29 +0200 [thread overview]
Message-ID: <1308671129.2656.4.camel@alex-2> (raw)
Add helper functions cfg80211_get_bss_ht, ieee80211_ie_build_ht_cap
and ieee80211_ie_build_ht_info.
These are needed for my IBSS HT patch but are also used to clean up some
multiple code.
Signed-off-by: Alexander Simon <alexander.simon@saxnet.de>
---
include/net/cfg80211.h | 6 ++
net/mac80211/ieee80211_i.h | 8 +++
net/mac80211/util.c | 116 ++++++++++++++++++++++++++++++++++++++-------
net/mac80211/work.c | 29 -----------
net/wireless/scan.c | 36 +++++++++++++
5 files changed, 148 insertions(+), 47 deletions(-)
diff -Nrup a/include/net/cfg80211.h b/include/net/cfg80211.h
--- a/include/net/cfg80211.h 2011-06-01 21:04:33.000000000 +0200
+++ b/include/net/cfg80211.h 2011-06-21 13:21:38.000000000 +0200
@@ -2530,6 +2531,12 @@ struct cfg80211_bss *cfg80211_get_bss(st
const u8 *bssid,
const u8 *ssid, size_t ssid_len,
u16 capa_mask, u16 capa_val);
+struct cfg80211_bss *cfg80211_get_bss_ht(struct wiphy *wiphy,
+ struct ieee80211_channel *channel,
+ const u8 *bssid,
+ const u8 *ssid, size_t ssid_len,
+ u16 capa_mask, u16 capa_val,
+ enum nl80211_channel_type channel_type);
static inline struct cfg80211_bss *
cfg80211_get_ibss(struct wiphy *wiphy,
struct ieee80211_channel *channel,
diff -Nrup a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
--- a/net/mac80211/ieee80211_i.h 2011-06-01 21:04:32.000000000 +0200
+++ b/net/mac80211/ieee80211_i.h 2011-06-21 13:21:38.000000000 +0200
@@ -1376,6 +1378,12 @@ void ieee80211_recalc_smps(struct ieee80
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);
+u8 *ieee80211_ie_build_ht_cap(u8 *pos, struct ieee80211_supported_band *sband,
+ u16 cap);
+u8 *ieee80211_ie_build_ht_info(u8 *pos,
+ struct ieee80211_sta_ht_cap *ht_cap,
+ struct ieee80211_channel *channel,
+ enum nl80211_channel_type channel_type);
/* internal work items */
void ieee80211_work_init(struct ieee80211_local *local);
@@ -1404,6 +1412,8 @@ ieee80211_get_channel_mode(struct ieee80
bool ieee80211_set_channel_type(struct ieee80211_local *local,
struct ieee80211_sub_if_data *sdata,
enum nl80211_channel_type chantype);
+enum nl80211_channel_type ieee80211_ht_info_to_channel_type(
+ struct ieee80211_ht_info *ht_info);
#ifdef CONFIG_MAC80211_NOINLINE
#define debug_noinline noinline
diff -Nrup a/net/mac80211/util.c b/net/mac80211/util.c
--- a/net/mac80211/util.c 2011-06-01 21:04:32.000000000 +0200
+++ b/net/mac80211/util.c 2011-06-21 13:21:38.000000000 +0200
@@ -1007,23 +1007,8 @@ int ieee80211_build_preq_ies(struct ieee
offset = noffset;
}
- if (sband->ht_cap.ht_supported) {
- u16 cap = sband->ht_cap.cap;
- __le16 tmp;
-
- *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 */
- }
+ if (sband->ht_cap.ht_supported)
+ pos = ieee80211_ie_build_ht_cap(pos, sband, sband->ht_cap.cap);
/*
* If adding more here, adjust code in main.c
@@ -1462,3 +1447,100 @@ size_t ieee80211_ie_split_vendor(const u
return pos;
}
+
+u8 *ieee80211_ie_build_ht_cap(u8 *pos, struct ieee80211_supported_band *sband,
+ u16 cap)
+{
+ __le16 tmp;
+
+ *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);
+
+ return pos;
+}
+
+u8 *ieee80211_ie_build_ht_info(u8 *pos,
+ struct ieee80211_sta_ht_cap *ht_cap,
+ struct ieee80211_channel *channel,
+ enum nl80211_channel_type channel_type)
+{
+ struct ieee80211_ht_info *ht_info;
+ /* Build HT Information */
+ *pos++ = WLAN_EID_HT_INFORMATION;
+ *pos++ = sizeof(struct ieee80211_ht_info);
+ ht_info = (struct ieee80211_ht_info *)pos;
+ ht_info->control_chan =
+ ieee80211_frequency_to_channel(channel->center_freq);
+ switch (channel_type) {
+ 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;
+ case NL80211_CHAN_HT20:
+ default:
+ ht_info->ht_param = IEEE80211_HT_PARAM_CHA_SEC_NONE;
+ break;
+ }
+ if (ht_cap->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)
+ ht_info->ht_param |= IEEE80211_HT_PARAM_CHAN_WIDTH_ANY;
+ ht_info->operation_mode = 0x0000;
+ ht_info->stbc_param = 0x0000;
+
+ /* 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);
+
+ return pos + sizeof(struct ieee80211_ht_info);
+}
+
+enum nl80211_channel_type ieee80211_ht_info_to_channel_type(
+ struct ieee80211_ht_info *ht_info)
+{
+ enum nl80211_channel_type channel_type;
+
+ if (!ht_info)
+ return NL80211_CHAN_NO_HT;
+
+ 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;
+ default:
+ channel_type = NL80211_CHAN_NO_HT;
+ }
+
+ return channel_type;
+}
diff -Nrup a/net/mac80211/work.c b/net/mac80211/work.c
--- a/net/mac80211/work.c 2011-06-01 21:04:33.000000000 +0200
+++ b/net/mac80211/work.c 2011-06-21 13:21:38.000000000 +0200
@@ -117,7 +117,6 @@ static void ieee80211_add_ht_ie(struct s
u8 *pos;
u32 flags = channel->flags;
u16 cap = sband->ht_cap.cap;
- __le16 tmp;
if (!sband->ht_cap.ht_supported)
return;
@@ -168,34 +167,8 @@ static void ieee80211_add_ht_ie(struct s
}
/* 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);
+ ieee80211_ie_build_ht_cap(pos, sband, cap);
}
static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata,
diff -Nrup a/net/wireless/scan.c b/net/wireless/scan.c
--- a/net/wireless/scan.c 2011-06-01 21:04:32.000000000 +0200
+++ b/net/wireless/scan.c 2011-06-21 13:21:38.000000000 +0200
@@ -343,6 +343,18 @@ struct cfg80211_bss *cfg80211_get_bss(st
const u8 *ssid, size_t ssid_len,
u16 capa_mask, u16 capa_val)
{
+ return cfg80211_get_bss_ht(wiphy, channel, bssid, ssid, ssid_len,
+ capa_mask, capa_val, NL80211_CHAN_NO_HT);
+}
+EXPORT_SYMBOL(cfg80211_get_bss);
+
+struct cfg80211_bss *cfg80211_get_bss_ht(struct wiphy *wiphy,
+ struct ieee80211_channel *channel,
+ const u8 *bssid,
+ const u8 *ssid, size_t ssid_len,
+ u16 capa_mask, u16 capa_val,
+ enum nl80211_channel_type channel_type)
+{
struct cfg80211_registered_device *dev = wiphy_to_dev(wiphy);
struct cfg80211_internal_bss *bss, *res = NULL;
unsigned long now = jiffies;
@@ -352,8 +364,27 @@ struct cfg80211_bss *cfg80211_get_bss(st
list_for_each_entry(bss, &dev->bss_list, list) {
if ((bss->pub.capability & capa_mask) != capa_val)
continue;
- if (channel && bss->pub.channel != channel)
- continue;
+ if (channel) {
+ if (bss->pub.channel != channel)
+ continue;
+ if (channel_type == NL80211_CHAN_HT40MINUS ||
+ channel_type == NL80211_CHAN_HT40PLUS) {
+ struct ieee80211_ht_info *ht_info;
+ ht_info = (struct ieee80211_ht_info *)
+ ieee80211_bss_get_ie(&bss->pub,
+ WLAN_EID_HT_INFORMATION);
+ if (!ht_info)
+ continue;
+ if (channel_type == NL80211_CHAN_HT40MINUS &&
+ !(ht_info->ht_param &
+ IEEE80211_HT_PARAM_CHA_SEC_BELOW))
+ continue;
+ if (channel_type == NL80211_CHAN_HT40PLUS &&
+ !(ht_info->ht_param &
+ IEEE80211_HT_PARAM_CHA_SEC_ABOVE))
+ continue;
+ }
+ }
/* Don't get expired BSS structs */
if (time_after(now, bss->ts + IEEE80211_SCAN_RESULT_EXPIRE) &&
!atomic_read(&bss->hold))
@@ -370,7 +401,8 @@ struct cfg80211_bss *cfg80211_get_bss(st
return NULL;
return &res->pub;
}
EXPORT_SYMBOL(cfg80211_get_bss);
+EXPORT_SYMBOL(cfg80211_get_bss_ht);
struct cfg80211_bss *cfg80211_get_mesh(struct wiphy *wiphy,
struct ieee80211_channel *channel,
next reply other threads:[~2011-06-21 15:47 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-06-21 15:45 Alexander Simon [this message]
2011-06-21 15:52 ` [RFC v3 2/3] nl80211: channel type attribute for IBSS Alexander Simon
2011-06-24 18:56 ` Felix Fietkau
2011-07-04 10:07 ` Alexander Simon
2011-07-04 10:10 ` Johannes Berg
2011-06-27 12:46 ` Johannes Berg
2011-06-21 15:53 ` [RFC v3 3/3] mac80211: HT operation in IBSS Alexander Simon
2011-06-24 19:21 ` Felix Fietkau
2011-06-27 12:50 ` Johannes Berg
2011-06-27 12:51 ` Johannes Berg
2011-06-21 16:01 ` patch for iw Alexander Simon
2011-06-27 12:42 ` Johannes Berg
2011-06-21 16:02 ` [RFC v3 1/3] mac80211: add some helper functions Johannes Berg
2011-06-24 19:01 ` Felix Fietkau
2011-06-27 12:46 ` Johannes Berg
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1308671129.2656.4.camel@alex-2 \
--to=alexander.simon@saxnet.de \
--cc=linux-wireless@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.