提交 9306102e 编写于 作者: E Emmanuel Grumbach 提交者: John W. Linville

mac80211: allow disable FAT in specific configurations

This patch allows to disable FAT channel in specific configurations.

For example the configuration (8, +1), (primary channel 8, extension
channel 12) isn't permitted in U.S., but (8, -1), (primary channel 8,
extension channel 4) is. When FAT channel configuration is not
permitted, FAT channel should be reported as not supported in the
capabilities of the HT IE in association request. And sssociation is
performed on 20Mhz channel.
Signed-off-by: NEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: NTomas Winkler <tomas.winkler@intel.com>
Signed-off-by: NJohn W. Linville <linville@tuxdriver.com>
上级 3c57601d
...@@ -320,6 +320,8 @@ struct ieee80211_ht_addt_info { ...@@ -320,6 +320,8 @@ struct ieee80211_ht_addt_info {
#define IEEE80211_HT_CAP_MCS_TX_UEQM 0x10 #define IEEE80211_HT_CAP_MCS_TX_UEQM 0x10
/* 802.11n HT IE masks */ /* 802.11n HT IE masks */
#define IEEE80211_HT_IE_CHA_SEC_OFFSET 0x03 #define IEEE80211_HT_IE_CHA_SEC_OFFSET 0x03
#define IEEE80211_HT_IE_CHA_SEC_ABOVE 0x01
#define IEEE80211_HT_IE_CHA_SEC_BELOW 0x03
#define IEEE80211_HT_IE_CHA_WIDTH 0x04 #define IEEE80211_HT_IE_CHA_WIDTH 0x04
#define IEEE80211_HT_IE_HT_PROTECTION 0x0003 #define IEEE80211_HT_IE_HT_PROTECTION 0x0003
#define IEEE80211_HT_IE_NON_GF_STA_PRSNT 0x0004 #define IEEE80211_HT_IE_NON_GF_STA_PRSNT 0x0004
......
...@@ -39,12 +39,18 @@ enum ieee80211_band { ...@@ -39,12 +39,18 @@ enum ieee80211_band {
* on this channel. * on this channel.
* @IEEE80211_CHAN_NO_IBSS: IBSS is not allowed on this channel. * @IEEE80211_CHAN_NO_IBSS: IBSS is not allowed on this channel.
* @IEEE80211_CHAN_RADAR: Radar detection is required on this channel. * @IEEE80211_CHAN_RADAR: Radar detection is required on this channel.
* @IEEE80211_CHAN_NO_FAT_ABOVE: extension channel above this channel
* is not permitted.
* @IEEE80211_CHAN_NO_FAT_BELOW: extension channel below this channel
* is not permitted.
*/ */
enum ieee80211_channel_flags { enum ieee80211_channel_flags {
IEEE80211_CHAN_DISABLED = 1<<0, IEEE80211_CHAN_DISABLED = 1<<0,
IEEE80211_CHAN_PASSIVE_SCAN = 1<<1, IEEE80211_CHAN_PASSIVE_SCAN = 1<<1,
IEEE80211_CHAN_NO_IBSS = 1<<2, IEEE80211_CHAN_NO_IBSS = 1<<2,
IEEE80211_CHAN_RADAR = 1<<3, IEEE80211_CHAN_RADAR = 1<<3,
IEEE80211_CHAN_NO_FAT_ABOVE = 1<<4,
IEEE80211_CHAN_NO_FAT_BELOW = 1<<5,
}; };
/** /**
......
...@@ -92,6 +92,8 @@ struct ieee80211_sta_bss { ...@@ -92,6 +92,8 @@ struct ieee80211_sta_bss {
size_t wmm_ie_len; size_t wmm_ie_len;
u8 *ht_ie; u8 *ht_ie;
size_t ht_ie_len; size_t ht_ie_len;
u8 *ht_add_ie;
size_t ht_add_ie_len;
#ifdef CONFIG_MAC80211_MESH #ifdef CONFIG_MAC80211_MESH
u8 *mesh_id; u8 *mesh_id;
size_t mesh_id_len; size_t mesh_id_len;
......
...@@ -808,8 +808,29 @@ static void ieee80211_send_assoc(struct net_device *dev, ...@@ -808,8 +808,29 @@ static void ieee80211_send_assoc(struct net_device *dev,
/* wmm support is a must to HT */ /* wmm support is a must to HT */
if (wmm && (ifsta->flags & IEEE80211_STA_WMM_ENABLED) && if (wmm && (ifsta->flags & IEEE80211_STA_WMM_ENABLED) &&
sband->ht_info.ht_supported) { sband->ht_info.ht_supported && bss->ht_add_ie) {
__le16 tmp = cpu_to_le16(sband->ht_info.cap); struct ieee80211_ht_addt_info *ht_add_info =
(struct ieee80211_ht_addt_info *)bss->ht_add_ie;
u16 cap = sband->ht_info.cap;
__le16 tmp;
u32 flags = local->hw.conf.channel->flags;
switch (ht_add_info->ht_param & IEEE80211_HT_IE_CHA_SEC_OFFSET) {
case IEEE80211_HT_IE_CHA_SEC_ABOVE:
if (flags & IEEE80211_CHAN_NO_FAT_ABOVE) {
cap &= ~IEEE80211_HT_CAP_SUP_WIDTH;
cap &= ~IEEE80211_HT_CAP_SGI_40;
}
break;
case IEEE80211_HT_IE_CHA_SEC_BELOW:
if (flags & IEEE80211_CHAN_NO_FAT_BELOW) {
cap &= ~IEEE80211_HT_CAP_SUP_WIDTH;
cap &= ~IEEE80211_HT_CAP_SGI_40;
}
break;
}
tmp = cpu_to_le16(cap);
pos = skb_put(skb, sizeof(struct ieee80211_ht_cap)+2); pos = skb_put(skb, sizeof(struct ieee80211_ht_cap)+2);
*pos++ = WLAN_EID_HT_CAPABILITY; *pos++ = WLAN_EID_HT_CAPABILITY;
*pos++ = sizeof(struct ieee80211_ht_cap); *pos++ = sizeof(struct ieee80211_ht_cap);
...@@ -2264,6 +2285,7 @@ static void ieee80211_rx_bss_free(struct ieee80211_sta_bss *bss) ...@@ -2264,6 +2285,7 @@ static void ieee80211_rx_bss_free(struct ieee80211_sta_bss *bss)
kfree(bss->rsn_ie); kfree(bss->rsn_ie);
kfree(bss->wmm_ie); kfree(bss->wmm_ie);
kfree(bss->ht_ie); kfree(bss->ht_ie);
kfree(bss->ht_add_ie);
kfree(bss_mesh_id(bss)); kfree(bss_mesh_id(bss));
kfree(bss_mesh_cfg(bss)); kfree(bss_mesh_cfg(bss));
kfree(bss); kfree(bss);
...@@ -2640,6 +2662,26 @@ static void ieee80211_rx_bss_info(struct net_device *dev, ...@@ -2640,6 +2662,26 @@ static void ieee80211_rx_bss_info(struct net_device *dev,
bss->ht_ie_len = 0; bss->ht_ie_len = 0;
} }
if (elems.ht_info_elem &&
(!bss->ht_add_ie ||
bss->ht_add_ie_len != elems.ht_info_elem_len ||
memcmp(bss->ht_add_ie, elems.ht_info_elem,
elems.ht_info_elem_len))) {
kfree(bss->ht_add_ie);
bss->ht_add_ie =
kmalloc(elems.ht_info_elem_len + 2, GFP_ATOMIC);
if (bss->ht_add_ie) {
memcpy(bss->ht_add_ie, elems.ht_info_elem - 2,
elems.ht_info_elem_len + 2);
bss->ht_add_ie_len = elems.ht_info_elem_len + 2;
} else
bss->ht_add_ie_len = 0;
} else if (!elems.ht_info_elem && bss->ht_add_ie) {
kfree(bss->ht_add_ie);
bss->ht_add_ie = NULL;
bss->ht_add_ie_len = 0;
}
bss->beacon_int = le16_to_cpu(mgmt->u.beacon.beacon_int); bss->beacon_int = le16_to_cpu(mgmt->u.beacon.beacon_int);
bss->capability = le16_to_cpu(mgmt->u.beacon.capab_info); bss->capability = le16_to_cpu(mgmt->u.beacon.capab_info);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册