aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>2008-05-29 04:35:23 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-06-03 15:00:26 -0400
commit9306102ea5696a3815f8d24ac0c0fbd1e19be7d3 (patch)
tree4dd9e512203616345d43f825ac808b0be1901bea
parent3c57601d0a1993cfc12a27cc6652b750bb44c523 (diff)
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: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--include/linux/ieee80211.h2
-rw-r--r--include/net/wireless.h6
-rw-r--r--net/mac80211/ieee80211_i.h2
-rw-r--r--net/mac80211/mlme.c46
4 files changed, 54 insertions, 2 deletions
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 3c2ac0c37aa8..9300f37cd7e8 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -320,6 +320,8 @@ struct ieee80211_ht_addt_info {
320#define IEEE80211_HT_CAP_MCS_TX_UEQM 0x10 320#define IEEE80211_HT_CAP_MCS_TX_UEQM 0x10
321/* 802.11n HT IE masks */ 321/* 802.11n HT IE masks */
322#define IEEE80211_HT_IE_CHA_SEC_OFFSET 0x03 322#define IEEE80211_HT_IE_CHA_SEC_OFFSET 0x03
323#define IEEE80211_HT_IE_CHA_SEC_ABOVE 0x01
324#define IEEE80211_HT_IE_CHA_SEC_BELOW 0x03
323#define IEEE80211_HT_IE_CHA_WIDTH 0x04 325#define IEEE80211_HT_IE_CHA_WIDTH 0x04
324#define IEEE80211_HT_IE_HT_PROTECTION 0x0003 326#define IEEE80211_HT_IE_HT_PROTECTION 0x0003
325#define IEEE80211_HT_IE_NON_GF_STA_PRSNT 0x0004 327#define IEEE80211_HT_IE_NON_GF_STA_PRSNT 0x0004
diff --git a/include/net/wireless.h b/include/net/wireless.h
index 667b4080d30f..9324f8dd183e 100644
--- a/include/net/wireless.h
+++ b/include/net/wireless.h
@@ -39,12 +39,18 @@ enum ieee80211_band {
39 * on this channel. 39 * on this channel.
40 * @IEEE80211_CHAN_NO_IBSS: IBSS is not allowed on this channel. 40 * @IEEE80211_CHAN_NO_IBSS: IBSS is not allowed on this channel.
41 * @IEEE80211_CHAN_RADAR: Radar detection is required on this channel. 41 * @IEEE80211_CHAN_RADAR: Radar detection is required on this channel.
42 * @IEEE80211_CHAN_NO_FAT_ABOVE: extension channel above this channel
43 * is not permitted.
44 * @IEEE80211_CHAN_NO_FAT_BELOW: extension channel below this channel
45 * is not permitted.
42 */ 46 */
43enum ieee80211_channel_flags { 47enum ieee80211_channel_flags {
44 IEEE80211_CHAN_DISABLED = 1<<0, 48 IEEE80211_CHAN_DISABLED = 1<<0,
45 IEEE80211_CHAN_PASSIVE_SCAN = 1<<1, 49 IEEE80211_CHAN_PASSIVE_SCAN = 1<<1,
46 IEEE80211_CHAN_NO_IBSS = 1<<2, 50 IEEE80211_CHAN_NO_IBSS = 1<<2,
47 IEEE80211_CHAN_RADAR = 1<<3, 51 IEEE80211_CHAN_RADAR = 1<<3,
52 IEEE80211_CHAN_NO_FAT_ABOVE = 1<<4,
53 IEEE80211_CHAN_NO_FAT_BELOW = 1<<5,
48}; 54};
49 55
50/** 56/**
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 3f8601cafffb..432011cd3647 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -92,6 +92,8 @@ struct ieee80211_sta_bss {
92 size_t wmm_ie_len; 92 size_t wmm_ie_len;
93 u8 *ht_ie; 93 u8 *ht_ie;
94 size_t ht_ie_len; 94 size_t ht_ie_len;
95 u8 *ht_add_ie;
96 size_t ht_add_ie_len;
95#ifdef CONFIG_MAC80211_MESH 97#ifdef CONFIG_MAC80211_MESH
96 u8 *mesh_id; 98 u8 *mesh_id;
97 size_t mesh_id_len; 99 size_t mesh_id_len;
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 6faa7006681a..d30c11337b04 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -808,8 +808,29 @@ static void ieee80211_send_assoc(struct net_device *dev,
808 808
809 /* wmm support is a must to HT */ 809 /* wmm support is a must to HT */
810 if (wmm && (ifsta->flags & IEEE80211_STA_WMM_ENABLED) && 810 if (wmm && (ifsta->flags & IEEE80211_STA_WMM_ENABLED) &&
811 sband->ht_info.ht_supported) { 811 sband->ht_info.ht_supported && bss->ht_add_ie) {
812 __le16 tmp = cpu_to_le16(sband->ht_info.cap); 812 struct ieee80211_ht_addt_info *ht_add_info =
813 (struct ieee80211_ht_addt_info *)bss->ht_add_ie;
814 u16 cap = sband->ht_info.cap;
815 __le16 tmp;
816 u32 flags = local->hw.conf.channel->flags;
817
818 switch (ht_add_info->ht_param & IEEE80211_HT_IE_CHA_SEC_OFFSET) {
819 case IEEE80211_HT_IE_CHA_SEC_ABOVE:
820 if (flags & IEEE80211_CHAN_NO_FAT_ABOVE) {
821 cap &= ~IEEE80211_HT_CAP_SUP_WIDTH;
822 cap &= ~IEEE80211_HT_CAP_SGI_40;
823 }
824 break;
825 case IEEE80211_HT_IE_CHA_SEC_BELOW:
826 if (flags & IEEE80211_CHAN_NO_FAT_BELOW) {
827 cap &= ~IEEE80211_HT_CAP_SUP_WIDTH;
828 cap &= ~IEEE80211_HT_CAP_SGI_40;
829 }
830 break;
831 }
832
833 tmp = cpu_to_le16(cap);
813 pos = skb_put(skb, sizeof(struct ieee80211_ht_cap)+2); 834 pos = skb_put(skb, sizeof(struct ieee80211_ht_cap)+2);
814 *pos++ = WLAN_EID_HT_CAPABILITY; 835 *pos++ = WLAN_EID_HT_CAPABILITY;
815 *pos++ = sizeof(struct ieee80211_ht_cap); 836 *pos++ = sizeof(struct ieee80211_ht_cap);
@@ -2264,6 +2285,7 @@ static void ieee80211_rx_bss_free(struct ieee80211_sta_bss *bss)
2264 kfree(bss->rsn_ie); 2285 kfree(bss->rsn_ie);
2265 kfree(bss->wmm_ie); 2286 kfree(bss->wmm_ie);
2266 kfree(bss->ht_ie); 2287 kfree(bss->ht_ie);
2288 kfree(bss->ht_add_ie);
2267 kfree(bss_mesh_id(bss)); 2289 kfree(bss_mesh_id(bss));
2268 kfree(bss_mesh_cfg(bss)); 2290 kfree(bss_mesh_cfg(bss));
2269 kfree(bss); 2291 kfree(bss);
@@ -2640,6 +2662,26 @@ static void ieee80211_rx_bss_info(struct net_device *dev,
2640 bss->ht_ie_len = 0; 2662 bss->ht_ie_len = 0;
2641 } 2663 }
2642 2664
2665 if (elems.ht_info_elem &&
2666 (!bss->ht_add_ie ||
2667 bss->ht_add_ie_len != elems.ht_info_elem_len ||
2668 memcmp(bss->ht_add_ie, elems.ht_info_elem,
2669 elems.ht_info_elem_len))) {
2670 kfree(bss->ht_add_ie);
2671 bss->ht_add_ie =
2672 kmalloc(elems.ht_info_elem_len + 2, GFP_ATOMIC);
2673 if (bss->ht_add_ie) {
2674 memcpy(bss->ht_add_ie, elems.ht_info_elem - 2,
2675 elems.ht_info_elem_len + 2);
2676 bss->ht_add_ie_len = elems.ht_info_elem_len + 2;
2677 } else
2678 bss->ht_add_ie_len = 0;
2679 } else if (!elems.ht_info_elem && bss->ht_add_ie) {
2680 kfree(bss->ht_add_ie);
2681 bss->ht_add_ie = NULL;
2682 bss->ht_add_ie_len = 0;
2683 }
2684
2643 bss->beacon_int = le16_to_cpu(mgmt->u.beacon.beacon_int); 2685 bss->beacon_int = le16_to_cpu(mgmt->u.beacon.beacon_int);
2644 bss->capability = le16_to_cpu(mgmt->u.beacon.capab_info); 2686 bss->capability = le16_to_cpu(mgmt->u.beacon.capab_info);
2645 2687