提交 d545daba 编写于 作者: M Mahesh Palivela 提交者: Johannes Berg

mac80211: VHT (11ac) association

Insert VHT IEs into association frames to allow
mac80211 to connect as a VHT client.
Signed-off-by: NMahesh Palivela <maheshp@posedge.com>
[clarify commit message]
Signed-off-by: NJohannes Berg <johannes.berg@intel.com>
上级 bae35d92
...@@ -359,6 +359,7 @@ enum ieee80211_sta_flags { ...@@ -359,6 +359,7 @@ enum ieee80211_sta_flags {
IEEE80211_STA_NULLFUNC_ACKED = BIT(8), IEEE80211_STA_NULLFUNC_ACKED = BIT(8),
IEEE80211_STA_RESET_SIGNAL_AVE = BIT(9), IEEE80211_STA_RESET_SIGNAL_AVE = BIT(9),
IEEE80211_STA_DISABLE_40MHZ = BIT(10), IEEE80211_STA_DISABLE_40MHZ = BIT(10),
IEEE80211_STA_DISABLE_VHT = BIT(11),
}; };
struct ieee80211_mgd_auth_data { struct ieee80211_mgd_auth_data {
......
...@@ -326,6 +326,26 @@ static void ieee80211_add_ht_ie(struct ieee80211_sub_if_data *sdata, ...@@ -326,6 +326,26 @@ static void ieee80211_add_ht_ie(struct ieee80211_sub_if_data *sdata,
ieee80211_ie_build_ht_cap(pos, &ht_cap, cap); ieee80211_ie_build_ht_cap(pos, &ht_cap, cap);
} }
static void ieee80211_add_vht_ie(struct ieee80211_sub_if_data *sdata,
struct sk_buff *skb,
struct ieee80211_supported_band *sband)
{
u8 *pos;
u32 cap;
struct ieee80211_sta_vht_cap vht_cap;
BUILD_BUG_ON(sizeof(vht_cap) != sizeof(sband->vht_cap));
memcpy(&vht_cap, &sband->vht_cap, sizeof(vht_cap));
/* determine capability flags */
cap = vht_cap.cap;
/* reserve and fill IE */
pos = skb_put(skb, sizeof(struct ieee80211_vht_capabilities) + 2);
ieee80211_ie_build_vht_cap(pos, &vht_cap, cap);
}
static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
{ {
struct ieee80211_local *local = sdata->local; struct ieee80211_local *local = sdata->local;
...@@ -371,6 +391,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) ...@@ -371,6 +391,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
4 + /* power capability */ 4 + /* power capability */
2 + 2 * sband->n_channels + /* supported channels */ 2 + 2 * sband->n_channels + /* supported channels */
2 + sizeof(struct ieee80211_ht_cap) + /* HT */ 2 + sizeof(struct ieee80211_ht_cap) + /* HT */
2 + sizeof(struct ieee80211_vht_capabilities) + /* VHT */
assoc_data->ie_len + /* extra IEs */ assoc_data->ie_len + /* extra IEs */
9, /* WMM */ 9, /* WMM */
GFP_KERNEL); GFP_KERNEL);
...@@ -503,6 +524,9 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) ...@@ -503,6 +524,9 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
ieee80211_add_ht_ie(sdata, skb, assoc_data->ap_ht_param, ieee80211_add_ht_ie(sdata, skb, assoc_data->ap_ht_param,
sband, local->oper_channel, ifmgd->ap_smps); sband, local->oper_channel, ifmgd->ap_smps);
if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT))
ieee80211_add_vht_ie(sdata, skb, sband);
/* if present, add any custom non-vendor IEs that go after HT */ /* if present, add any custom non-vendor IEs that go after HT */
if (assoc_data->ie_len && assoc_data->ie) { if (assoc_data->ie_len && assoc_data->ie) {
noffset = ieee80211_ie_split_vendor(assoc_data->ie, noffset = ieee80211_ie_split_vendor(assoc_data->ie,
...@@ -3301,6 +3325,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, ...@@ -3301,6 +3325,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
ifmgd->flags &= ~IEEE80211_STA_DISABLE_11N; ifmgd->flags &= ~IEEE80211_STA_DISABLE_11N;
ifmgd->flags &= ~IEEE80211_STA_NULLFUNC_ACKED; ifmgd->flags &= ~IEEE80211_STA_NULLFUNC_ACKED;
ifmgd->flags &= ~IEEE80211_STA_DISABLE_VHT;
ifmgd->beacon_crc_valid = false; ifmgd->beacon_crc_valid = false;
...@@ -3316,13 +3341,16 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, ...@@ -3316,13 +3341,16 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP || req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP ||
req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP104) { req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP104) {
ifmgd->flags |= IEEE80211_STA_DISABLE_11N; ifmgd->flags |= IEEE80211_STA_DISABLE_11N;
ifmgd->flags |= IEEE80211_STA_DISABLE_VHT;
netdev_info(sdata->dev, netdev_info(sdata->dev,
"disabling HT due to WEP/TKIP use\n"); "disabling HT/VHT due to WEP/TKIP use\n");
} }
} }
if (req->flags & ASSOC_REQ_DISABLE_HT) if (req->flags & ASSOC_REQ_DISABLE_HT) {
ifmgd->flags |= IEEE80211_STA_DISABLE_11N; ifmgd->flags |= IEEE80211_STA_DISABLE_11N;
ifmgd->flags |= IEEE80211_STA_DISABLE_VHT;
}
/* Also disable HT if we don't support it or the AP doesn't use WMM */ /* Also disable HT if we don't support it or the AP doesn't use WMM */
sband = local->hw.wiphy->bands[req->bss->channel->band]; sband = local->hw.wiphy->bands[req->bss->channel->band];
...@@ -3333,6 +3361,14 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, ...@@ -3333,6 +3361,14 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
"disabling HT as WMM/QoS is not supported\n"); "disabling HT as WMM/QoS is not supported\n");
} }
/* disable VHT if we don't support it or the AP doesn't use WMM */
if (!sband->vht_cap.vht_supported ||
local->hw.queues < IEEE80211_NUM_ACS || !bss->wmm_used) {
ifmgd->flags |= IEEE80211_STA_DISABLE_VHT;
netdev_info(sdata->dev,
"disabling VHT as WMM/QoS is not supported\n");
}
memcpy(&ifmgd->ht_capa, &req->ht_capa, sizeof(ifmgd->ht_capa)); memcpy(&ifmgd->ht_capa, &req->ht_capa, sizeof(ifmgd->ht_capa));
memcpy(&ifmgd->ht_capa_mask, &req->ht_capa_mask, memcpy(&ifmgd->ht_capa_mask, &req->ht_capa_mask,
sizeof(ifmgd->ht_capa_mask)); sizeof(ifmgd->ht_capa_mask));
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册