diff options
Diffstat (limited to 'package/mac80211/patches/418-ieee80211-cleanup-ht-terminology.patch')
-rw-r--r-- | package/mac80211/patches/418-ieee80211-cleanup-ht-terminology.patch | 1427 |
1 files changed, 1427 insertions, 0 deletions
diff --git a/package/mac80211/patches/418-ieee80211-cleanup-ht-terminology.patch b/package/mac80211/patches/418-ieee80211-cleanup-ht-terminology.patch new file mode 100644 index 0000000000..61ae15a885 --- /dev/null +++ b/package/mac80211/patches/418-ieee80211-cleanup-ht-terminology.patch @@ -0,0 +1,1427 @@ +Subject: 802.11: clean up/fix HT support + +This patch cleans up a number of things: + * the unusable definition of the HT capabilities/HT information + information elements + * variable names that are hard to understand + * mac80211: move ieee80211_handle_ht to ht.c and remove the unused + enable_ht parameter + * mac80211: fix bug with MCS rate 32 in ieee80211_handle_ht + * mac80211: fix bug with casting the result of ieee80211_bss_get_ie + to an information element _contents_ rather than the + whole element, add size checking (another out-of-bounds + access bug fixed!) + * mac80211: remove some unused return values in favour of BUG_ON + checking + * a few minor other things + +Signed-off-by: Johannes Berg <johannes@sipsolutions.net> +--- + drivers/net/wireless/ath9k/main.c | 57 +++++------ + drivers/net/wireless/ath9k/rc.c | 10 - + drivers/net/wireless/ath9k/rc.h | 1 + drivers/net/wireless/ath9k/recv.c | 2 + drivers/net/wireless/ath9k/xmit.c | 2 + drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 18 +-- + drivers/net/wireless/iwlwifi/iwl-agn.c | 20 +-- + drivers/net/wireless/iwlwifi/iwl-core.c | 71 +++++++------- + drivers/net/wireless/iwlwifi/iwl-core.h | 2 + drivers/net/wireless/iwlwifi/iwl-dev.h | 4 + drivers/net/wireless/iwlwifi/iwl-scan.c | 12 +- + drivers/net/wireless/iwlwifi/iwl-sta.c | 6 - + drivers/net/wireless/mac80211_hwsim.c | 19 +-- + include/linux/ieee80211.h | 133 ++++++++++++++++++-------- + include/net/mac80211.h | 12 +- + include/net/wireless.h | 15 +- + net/mac80211/cfg.c | 7 - + net/mac80211/ht.c | 151 +++++++++++++++++++++++++----- + net/mac80211/ieee80211_i.h | 16 +-- + net/mac80211/main.c | 94 ------------------ + net/mac80211/mlme.c | 45 ++++---- + net/mac80211/util.c | 4 + net/mac80211/wext.c | 4 + 23 files changed, 386 insertions(+), 319 deletions(-) + +--- everything.orig/include/linux/ieee80211.h 2008-10-08 20:44:47.000000000 +0200 ++++ everything/include/linux/ieee80211.h 2008-10-09 02:16:21.000000000 +0200 +@@ -685,28 +685,88 @@ struct ieee80211_bar { + #define IEEE80211_BAR_CTRL_ACK_POLICY_NORMAL 0x0000 + #define IEEE80211_BAR_CTRL_CBMTID_COMPRESSED_BA 0x0004 + ++ ++#define IEEE80211_HT_MCS_MASK_LEN 10 ++ ++/** ++ * struct ieee80211_mcs_info - MCS information ++ * @rx_mask: RX mask ++ * @rx_highest: highest supported RX rate ++ * @tx_params: TX parameters ++ */ ++struct ieee80211_mcs_info { ++ u8 rx_mask[IEEE80211_HT_MCS_MASK_LEN]; ++ __le16 rx_highest; ++ u8 tx_params; ++ u8 reserved[3]; ++} __attribute__((packed)); ++ ++/* 802.11n HT capability MSC set */ ++#define IEEE80211_HT_MCS_RX_HIGHEST_MASK 0x3ff ++#define IEEE80211_HT_MCS_TX_DEFINED 0x01 ++#define IEEE80211_HT_MCS_TX_RX_DIFF 0x02 ++/* value 0 == 1 stream etc */ ++#define IEEE80211_HT_MCS_TX_MAX_STREAMS_MASK 0x0C ++#define IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT 2 ++#define IEEE80211_HT_MCS_TX_MAX_STREAMS 4 ++#define IEEE80211_HT_MCS_TX_UNEQUAL_MODULATION 0x10 ++ ++/* ++ * 802.11n D5.0 20.3.5 / 20.6 says: ++ * - indices 0 to 7 and 32 are single spatial stream ++ * - 8 to 31 are multiple spatial streams using equal modulation ++ * [8..15 for two streams, 16..23 for three and 24..31 for four] ++ * - remainder are multiple spatial streams using unequal modulation ++ */ ++#define IEEE80211_HT_MCS_UNEQUAL_MODULATION_START 33 ++#define IEEE80211_HT_MCS_UNEQUAL_MODULATION_START_BYTE \ ++ (IEEE80211_HT_MCS_UNEQUAL_MODULATION_START / 8) ++ + /** + * struct ieee80211_ht_cap - HT capabilities + * +- * This structure refers to "HT capabilities element" as +- * described in 802.11n draft section 7.3.2.52 ++ * This structure is the "HT capabilities element" as ++ * described in 802.11n D5.0 7.3.2.57 + */ + struct ieee80211_ht_cap { + __le16 cap_info; + u8 ampdu_params_info; +- u8 supp_mcs_set[16]; ++ ++ /* 16 bytes MCS information */ ++ struct ieee80211_mcs_info mcs; ++ + __le16 extended_ht_cap_info; + __le32 tx_BF_cap_info; + u8 antenna_selection_info; + } __attribute__ ((packed)); + ++/* 802.11n HT capabilities masks (for cap_info) */ ++#define IEEE80211_HT_CAP_LDPC_CODING 0x0001 ++#define IEEE80211_HT_CAP_SUP_WIDTH_20_40 0x0002 ++#define IEEE80211_HT_CAP_SM_PS 0x000C ++#define IEEE80211_HT_CAP_GRN_FLD 0x0010 ++#define IEEE80211_HT_CAP_SGI_20 0x0020 ++#define IEEE80211_HT_CAP_SGI_40 0x0040 ++#define IEEE80211_HT_CAP_TX_STBC 0x0080 ++#define IEEE80211_HT_CAP_RX_STBC 0x0300 ++#define IEEE80211_HT_CAP_DELAY_BA 0x0400 ++#define IEEE80211_HT_CAP_MAX_AMSDU 0x0800 ++#define IEEE80211_HT_CAP_DSSSCCK40 0x1000 ++#define IEEE80211_HT_CAP_PSMP_SUPPORT 0x2000 ++#define IEEE80211_HT_CAP_40MHZ_INTOLERANT 0x4000 ++#define IEEE80211_HT_CAP_LSIG_TXOP_PROT 0x8000 ++ ++/* 802.11n HT capability AMPDU settings (for ampdu_params_info) */ ++#define IEEE80211_HT_AMPDU_PARM_FACTOR 0x03 ++#define IEEE80211_HT_AMPDU_PARM_DENSITY 0x1C ++ + /** +- * struct ieee80211_ht_cap - HT additional information ++ * struct ieee80211_ht_info - HT information + * +- * This structure refers to "HT information element" as +- * described in 802.11n draft section 7.3.2.53 ++ * This structure is the "HT information element" as ++ * described in 802.11n D5.0 7.3.2.58 + */ +-struct ieee80211_ht_addt_info { ++struct ieee80211_ht_info { + u8 control_chan; + u8 ht_param; + __le16 operation_mode; +@@ -714,36 +774,33 @@ struct ieee80211_ht_addt_info { + u8 basic_set[16]; + } __attribute__ ((packed)); + +-/* 802.11n HT capabilities masks */ +-#define IEEE80211_HT_CAP_SUP_WIDTH 0x0002 +-#define IEEE80211_HT_CAP_SM_PS 0x000C +-#define IEEE80211_HT_CAP_GRN_FLD 0x0010 +-#define IEEE80211_HT_CAP_SGI_20 0x0020 +-#define IEEE80211_HT_CAP_SGI_40 0x0040 +-#define IEEE80211_HT_CAP_DELAY_BA 0x0400 +-#define IEEE80211_HT_CAP_MAX_AMSDU 0x0800 +-#define IEEE80211_HT_CAP_DSSSCCK40 0x1000 +-/* 802.11n HT capability AMPDU settings */ +-#define IEEE80211_HT_CAP_AMPDU_FACTOR 0x03 +-#define IEEE80211_HT_CAP_AMPDU_DENSITY 0x1C +-/* 802.11n HT capability MSC set */ +-#define IEEE80211_SUPP_MCS_SET_UEQM 4 +-#define IEEE80211_HT_CAP_MAX_STREAMS 4 +-#define IEEE80211_SUPP_MCS_SET_LEN 10 +-/* maximum streams the spec allows */ +-#define IEEE80211_HT_CAP_MCS_TX_DEFINED 0x01 +-#define IEEE80211_HT_CAP_MCS_TX_RX_DIFF 0x02 +-#define IEEE80211_HT_CAP_MCS_TX_STREAMS 0x0C +-#define IEEE80211_HT_CAP_MCS_TX_UEQM 0x10 +-/* 802.11n HT IE masks */ +-#define IEEE80211_HT_IE_CHA_SEC_OFFSET 0x03 +-#define IEEE80211_HT_IE_CHA_SEC_NONE 0x00 +-#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_HT_PROTECTION 0x0003 +-#define IEEE80211_HT_IE_NON_GF_STA_PRSNT 0x0004 +-#define IEEE80211_HT_IE_NON_HT_STA_PRSNT 0x0010 ++/* for ht_param */ ++#define IEEE80211_HT_PARAM_CHA_SEC_OFFSET 0x03 ++#define IEEE80211_HT_PARAM_CHA_SEC_NONE 0x00 ++#define IEEE80211_HT_PARAM_CHA_SEC_ABOVE 0x01 ++#define IEEE80211_HT_PARAM_CHA_SEC_BELOW 0x03 ++#define IEEE80211_HT_PARAM_CHAN_WIDTH_ANY 0x04 ++#define IEEE80211_HT_PARAM_RIFS_MODE 0x08 ++#define IEEE80211_HT_PARAM_SPSMP_SUPPORT 0x10 ++#define IEEE80211_HT_PARAM_SERV_INTERVAL_GRAN 0xE0 ++ ++/* for operation_mode */ ++#define IEEE80211_HT_OP_MODE_PROTECTION 0x0003 ++#define IEEE80211_HT_OP_MODE_PROTECTION_NONE 0 ++#define IEEE80211_HT_OP_MODE_PROTECTION_NONMEMBER 1 ++#define IEEE80211_HT_OP_MODE_PROTECTION_20MHZ 2 ++#define IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED 3 ++#define IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT 0x0004 ++#define IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT 0x0010 ++ ++/* for stbc_param */ ++#define IEEE80211_HT_STBC_PARAM_DUAL_BEACON 0x0040 ++#define IEEE80211_HT_STBC_PARAM_DUAL_CTS_PROT 0x0080 ++#define IEEE80211_HT_STBC_PARAM_STBC_BEACON 0x0100 ++#define IEEE80211_HT_STBC_PARAM_LSIG_TXOP_FULLPROT 0x0200 ++#define IEEE80211_HT_STBC_PARAM_PCO_ACTIVE 0x0400 ++#define IEEE80211_HT_STBC_PARAM_PCO_PHASE 0x0800 ++ + + /* block-ack parameters */ + #define IEEE80211_ADDBA_PARAM_POLICY_MASK 0x0002 +@@ -949,7 +1006,7 @@ enum ieee80211_eid { + WLAN_EID_EXT_SUPP_RATES = 50, + /* 802.11n */ + WLAN_EID_HT_CAPABILITY = 45, +- WLAN_EID_HT_EXTRA_INFO = 61, ++ WLAN_EID_HT_INFORMATION = 61, + /* 802.11i */ + WLAN_EID_RSN = 48, + WLAN_EID_WPA = 221, +--- everything.orig/include/net/wireless.h 2008-10-08 20:44:46.000000000 +0200 ++++ everything/include/net/wireless.h 2008-10-09 02:16:20.000000000 +0200 +@@ -10,6 +10,7 @@ + #include <linux/netdevice.h> + #include <linux/debugfs.h> + #include <linux/list.h> ++#include <linux/ieee80211.h> + #include <net/cfg80211.h> + + /** +@@ -133,23 +134,23 @@ struct ieee80211_rate { + }; + + /** +- * struct ieee80211_ht_info - describing STA's HT capabilities ++ * struct ieee80211_sta_ht_cap - STA's HT capabilities + * + * This structure describes most essential parameters needed + * to describe 802.11n HT capabilities for an STA. + * +- * @ht_supported: is HT supported by STA, 0: no, 1: yes ++ * @ht_supported: is HT supported by the STA + * @cap: HT capabilities map as described in 802.11n spec + * @ampdu_factor: Maximum A-MPDU length factor + * @ampdu_density: Minimum A-MPDU spacing +- * @supp_mcs_set: Supported MCS set as described in 802.11n spec ++ * @mcs: Supported MCS rates + */ +-struct ieee80211_ht_info { ++struct ieee80211_sta_ht_cap { + u16 cap; /* use IEEE80211_HT_CAP_ */ +- u8 ht_supported; ++ bool ht_supported; + u8 ampdu_factor; + u8 ampdu_density; +- u8 supp_mcs_set[16]; ++ struct ieee80211_mcs_info mcs; + }; + + /** +@@ -173,7 +174,7 @@ struct ieee80211_supported_band { + enum ieee80211_band band; + int n_channels; + int n_bitrates; +- struct ieee80211_ht_info ht_info; ++ struct ieee80211_sta_ht_cap ht_cap; + }; + + /** +--- everything.orig/net/mac80211/main.c 2008-10-08 20:45:06.000000000 +0200 ++++ everything/net/mac80211/main.c 2008-10-09 02:16:29.000000000 +0200 +@@ -232,100 +232,6 @@ int ieee80211_hw_config(struct ieee80211 + return ret; + } + +-/** +- * ieee80211_handle_ht should be used only after legacy configuration +- * has been determined namely band, as ht configuration depends upon +- * the hardware's HT abilities for a _specific_ band. +- */ +-u32 ieee80211_handle_ht(struct ieee80211_local *local, int enable_ht, +- struct ieee80211_ht_info *req_ht_cap, +- struct ieee80211_ht_bss_info *req_bss_cap) +-{ +- struct ieee80211_conf *conf = &local->hw.conf; +- struct ieee80211_supported_band *sband; +- struct ieee80211_ht_info ht_conf; +- struct ieee80211_ht_bss_info ht_bss_conf; +- u32 changed = 0; +- int i; +- u8 max_tx_streams = IEEE80211_HT_CAP_MAX_STREAMS; +- u8 tx_mcs_set_cap; +- +- sband = local->hw.wiphy->bands[conf->channel->band]; +- +- memset(&ht_conf, 0, sizeof(struct ieee80211_ht_info)); +- memset(&ht_bss_conf, 0, sizeof(struct ieee80211_ht_bss_info)); +- +- /* HT is not supported */ +- if (!sband->ht_info.ht_supported) { +- conf->flags &= ~IEEE80211_CONF_SUPPORT_HT_MODE; +- goto out; +- } +- +- /* disable HT */ +- if (!enable_ht) { +- if (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) +- changed |= BSS_CHANGED_HT; +- conf->flags &= ~IEEE80211_CONF_SUPPORT_HT_MODE; +- conf->ht_conf.ht_supported = 0; +- goto out; +- } +- +- +- if (!(conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE)) +- changed |= BSS_CHANGED_HT; +- +- conf->flags |= IEEE80211_CONF_SUPPORT_HT_MODE; +- ht_conf.ht_supported = 1; +- +- ht_conf.cap = req_ht_cap->cap & sband->ht_info.cap; +- ht_conf.cap &= ~(IEEE80211_HT_CAP_SM_PS); +- ht_conf.cap |= sband->ht_info.cap & IEEE80211_HT_CAP_SM_PS; +- ht_bss_conf.primary_channel = req_bss_cap->primary_channel; +- ht_bss_conf.bss_cap = req_bss_cap->bss_cap; +- ht_bss_conf.bss_op_mode = req_bss_cap->bss_op_mode; +- +- ht_conf.ampdu_factor = req_ht_cap->ampdu_factor; +- ht_conf.ampdu_density = req_ht_cap->ampdu_density; +- +- /* Bits 96-100 */ +- tx_mcs_set_cap = sband->ht_info.supp_mcs_set[12]; +- +- /* configure suppoerted Tx MCS according to requested MCS +- * (based in most cases on Rx capabilities of peer) and self +- * Tx MCS capabilities (as defined by low level driver HW +- * Tx capabilities) */ +- if (!(tx_mcs_set_cap & IEEE80211_HT_CAP_MCS_TX_DEFINED)) +- goto check_changed; +- +- /* Counting from 0 therfore + 1 */ +- if (tx_mcs_set_cap & IEEE80211_HT_CAP_MCS_TX_RX_DIFF) +- max_tx_streams = ((tx_mcs_set_cap & +- IEEE80211_HT_CAP_MCS_TX_STREAMS) >> 2) + 1; +- +- for (i = 0; i < max_tx_streams; i++) +- ht_conf.supp_mcs_set[i] = +- sband->ht_info.supp_mcs_set[i] & +- req_ht_cap->supp_mcs_set[i]; +- +- if (tx_mcs_set_cap & IEEE80211_HT_CAP_MCS_TX_UEQM) +- for (i = IEEE80211_SUPP_MCS_SET_UEQM; +- i < IEEE80211_SUPP_MCS_SET_LEN; i++) +- ht_conf.supp_mcs_set[i] = +- sband->ht_info.supp_mcs_set[i] & +- req_ht_cap->supp_mcs_set[i]; +- +-check_changed: +- /* if bss configuration changed store the new one */ +- if (memcmp(&conf->ht_conf, &ht_conf, sizeof(ht_conf)) || +- memcmp(&conf->ht_bss_conf, &ht_bss_conf, sizeof(ht_bss_conf))) { +- changed |= BSS_CHANGED_HT; +- memcpy(&conf->ht_conf, &ht_conf, sizeof(ht_conf)); +- memcpy(&conf->ht_bss_conf, &ht_bss_conf, sizeof(ht_bss_conf)); +- } +-out: +- return changed; +-} +- + void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, + u32 changed) + { +--- everything.orig/include/net/mac80211.h 2008-10-08 20:45:06.000000000 +0200 ++++ everything/include/net/mac80211.h 2008-10-09 02:16:30.000000000 +0200 +@@ -191,7 +191,7 @@ enum ieee80211_bss_change { + * @beacon_int: beacon interval + * @assoc_capability: capabilities taken from assoc resp + * @assoc_ht: association in HT mode +- * @ht_conf: ht capabilities ++ * @ht_cap: ht capabilities + * @ht_bss_conf: ht extended capabilities + * @basic_rates: bitmap of basic rates, each bit stands for an + * index into the rate table configured by the driver in +@@ -212,7 +212,7 @@ struct ieee80211_bss_conf { + u64 basic_rates; + /* ht related data */ + bool assoc_ht; +- struct ieee80211_ht_info *ht_conf; ++ struct ieee80211_sta_ht_cap *ht_cap; + struct ieee80211_ht_bss_info *ht_bss_conf; + }; + +@@ -477,7 +477,7 @@ static inline int __deprecated __IEEE802 + * @antenna_sel_tx: transmit antenna selection, 0: default/diversity, + * 1/2: antenna 0/1 + * @antenna_sel_rx: receive antenna selection, like @antenna_sel_tx +- * @ht_conf: describes current self configuration of 802.11n HT capabilies ++ * @ht_cap: describes current self configuration of 802.11n HT capabilities + * @ht_bss_conf: describes current BSS configuration of 802.11n HT parameters + * @channel: the channel to tune to + */ +@@ -493,7 +493,7 @@ struct ieee80211_conf { + + struct ieee80211_channel *channel; + +- struct ieee80211_ht_info ht_conf; ++ struct ieee80211_sta_ht_cap ht_cap; + struct ieee80211_ht_bss_info ht_bss_conf; + }; + +@@ -686,7 +686,7 @@ enum set_key_cmd { + * @addr: MAC address + * @aid: AID we assigned to the station if we're an AP + * @supp_rates: Bitmap of supported rates (per band) +- * @ht_info: HT capabilities of this STA ++ * @ht_cap: HT capabilities of this STA + * @drv_priv: data area for driver use, will always be aligned to + * sizeof(void *), size is determined in hw information. + */ +@@ -694,7 +694,7 @@ struct ieee80211_sta { + u64 supp_rates[IEEE80211_NUM_BANDS]; + u8 addr[ETH_ALEN]; + u16 aid; +- struct ieee80211_ht_info ht_info; ++ struct ieee80211_sta_ht_cap ht_cap; + + /* must be last */ + u8 drv_priv[0] __attribute__((__aligned__(sizeof(void *)))); +--- everything.orig/net/mac80211/ieee80211_i.h 2008-10-08 20:45:06.000000000 +0200 ++++ everything/net/mac80211/ieee80211_i.h 2008-10-09 02:16:30.000000000 +0200 +@@ -817,7 +817,7 @@ struct ieee802_11_elems { + u8 *wmm_info; + u8 *wmm_param; + struct ieee80211_ht_cap *ht_cap_elem; +- struct ieee80211_ht_addt_info *ht_info_elem; ++ struct ieee80211_ht_info *ht_info_elem; + u8 *mesh_config; + u8 *mesh_id; + u8 *peer_link; +@@ -885,9 +885,6 @@ static inline int ieee80211_bssid_match( + int ieee80211_hw_config(struct ieee80211_local *local); + int ieee80211_if_config(struct ieee80211_sub_if_data *sdata, u32 changed); + void ieee80211_tx_set_protected(struct ieee80211_tx_data *tx); +-u32 ieee80211_handle_ht(struct ieee80211_local *local, int enable_ht, +- struct ieee80211_ht_info *req_ht_cap, +- struct ieee80211_ht_bss_info *req_bss_cap); + void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, + u32 changed); + void ieee80211_configure_filter(struct ieee80211_local *local); +@@ -968,11 +965,14 @@ int ieee80211_monitor_start_xmit(struct + int ieee80211_subif_start_xmit(struct sk_buff *skb, struct net_device *dev); + + /* HT */ +-int ieee80211_ht_cap_ie_to_ht_info(struct ieee80211_ht_cap *ht_cap_ie, +- struct ieee80211_ht_info *ht_info); +-int ieee80211_ht_addt_info_ie_to_ht_bss_info( +- struct ieee80211_ht_addt_info *ht_add_info_ie, ++void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_ht_cap *ht_cap_ie, ++ struct ieee80211_sta_ht_cap *ht_cap); ++void ieee80211_ht_info_ie_to_ht_bss_info( ++ struct ieee80211_ht_info *ht_add_info_ie, + struct ieee80211_ht_bss_info *bss_info); ++u32 ieee80211_handle_ht(struct ieee80211_local *local, ++ struct ieee80211_sta_ht_cap *req_ht_cap, ++ struct ieee80211_ht_bss_info *req_bss_cap); + void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u16 ssn); + + void ieee80211_sta_stop_rx_ba_session(struct ieee80211_sub_if_data *sdata, u8 *da, +--- everything.orig/net/mac80211/wext.c 2008-10-08 20:45:06.000000000 +0200 ++++ everything/net/mac80211/wext.c 2008-10-09 02:16:28.000000000 +0200 +@@ -147,7 +147,7 @@ static int ieee80211_ioctl_giwname(struc + sband = local->hw.wiphy->bands[IEEE80211_BAND_5GHZ]; + if (sband) { + is_a = 1; +- is_ht |= sband->ht_info.ht_supported; ++ is_ht |= sband->ht_cap.ht_supported; + } + + sband = local->hw.wiphy->bands[IEEE80211_BAND_2GHZ]; +@@ -160,7 +160,7 @@ static int ieee80211_ioctl_giwname(struc + if (sband->bitrates[i].bitrate == 60) + is_g = 1; + } +- is_ht |= sband->ht_info.ht_supported; ++ is_ht |= sband->ht_cap.ht_supported; + } + + strcpy(name, "IEEE 802.11"); +--- everything.orig/net/mac80211/ht.c 2008-10-08 20:44:47.000000000 +0200 ++++ everything/net/mac80211/ht.c 2008-10-09 02:16:26.000000000 +0200 +@@ -20,37 +20,33 @@ + #include "sta_info.h" + #include "wme.h" + +-int ieee80211_ht_cap_ie_to_ht_info(struct ieee80211_ht_cap *ht_cap_ie, +- struct ieee80211_ht_info *ht_info) ++void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_ht_cap *ht_cap_ie, ++ struct ieee80211_sta_ht_cap *ht_cap) + { + +- if (ht_info == NULL) +- return -EINVAL; ++ BUG_ON(!ht_cap); + +- memset(ht_info, 0, sizeof(*ht_info)); ++ memset(ht_cap, 0, sizeof(*ht_cap)); + + if (ht_cap_ie) { + u8 ampdu_info = ht_cap_ie->ampdu_params_info; + +- ht_info->ht_supported = 1; +- ht_info->cap = le16_to_cpu(ht_cap_ie->cap_info); +- ht_info->ampdu_factor = +- ampdu_info & IEEE80211_HT_CAP_AMPDU_FACTOR; +- ht_info->ampdu_density = +- (ampdu_info & IEEE80211_HT_CAP_AMPDU_DENSITY) >> 2; +- memcpy(ht_info->supp_mcs_set, ht_cap_ie->supp_mcs_set, 16); ++ ht_cap->ht_supported = true; ++ ht_cap->cap = le16_to_cpu(ht_cap_ie->cap_info); ++ ht_cap->ampdu_factor = ++ ampdu_info & IEEE80211_HT_AMPDU_PARM_FACTOR; ++ ht_cap->ampdu_density = ++ (ampdu_info & IEEE80211_HT_AMPDU_PARM_DENSITY) >> 2; ++ memcpy(&ht_cap->mcs, &ht_cap_ie->mcs, sizeof(ht_cap->mcs)); + } else +- ht_info->ht_supported = 0; +- +- return 0; ++ ht_cap->ht_supported = false; + } + +-int ieee80211_ht_addt_info_ie_to_ht_bss_info( +- struct ieee80211_ht_addt_info *ht_add_info_ie, ++void ieee80211_ht_info_ie_to_ht_bss_info( ++ struct ieee80211_ht_info *ht_add_info_ie, + struct ieee80211_ht_bss_info *bss_info) + { +- if (bss_info == NULL) +- return -EINVAL; ++ BUG_ON(!bss_info); + + memset(bss_info, 0, sizeof(*bss_info)); + +@@ -62,8 +58,119 @@ int ieee80211_ht_addt_info_ie_to_ht_bss_ + bss_info->bss_cap = ht_add_info_ie->ht_param; + bss_info->bss_op_mode = (u8)(op_mode & 0xff); + } ++} ++ ++/* ++ * ieee80211_handle_ht should be called only after the operating band ++ * has been determined as ht configuration depends on the hw's ++ * HT abilities for a specific band. ++ */ ++u32 ieee80211_handle_ht(struct ieee80211_local *local, ++ struct ieee80211_sta_ht_cap *req_ht_cap, ++ struct ieee80211_ht_bss_info *req_bss_cap) ++{ ++ struct ieee80211_conf *conf = &local->hw.conf; ++ struct ieee80211_supported_band *sband; ++ struct ieee80211_sta_ht_cap ht_cap; ++ struct ieee80211_ht_bss_info ht_bss_conf; ++ u32 changed = 0; ++ int i; ++ u8 max_tx_streams; ++ u8 tx_mcs_set_cap; ++ bool enable_ht = true; ++ ++ sband = local->hw.wiphy->bands[conf->channel->band]; ++ ++ memset(&ht_cap, 0, sizeof(ht_cap)); ++ memset(&ht_bss_conf, 0, sizeof(struct ieee80211_ht_bss_info)); ++ ++ /* HT is not supported */ ++ if (!sband->ht_cap.ht_supported) ++ enable_ht = false; ++ ++ /* disable HT */ ++ if (!enable_ht) { ++ if (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) ++ changed |= BSS_CHANGED_HT; ++ conf->flags &= ~IEEE80211_CONF_SUPPORT_HT_MODE; ++ conf->ht_cap.ht_supported = false; ++ return changed; ++ } ++ ++ ++ if (!(conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE)) ++ changed |= BSS_CHANGED_HT; ++ ++ conf->flags |= IEEE80211_CONF_SUPPORT_HT_MODE; ++ ht_cap.ht_supported = true; ++ ++ ht_cap.cap = req_ht_cap->cap & sband->ht_cap.cap; ++ ht_cap.cap &= ~IEEE80211_HT_CAP_SM_PS; ++ ht_cap.cap |= sband->ht_cap.cap & IEEE80211_HT_CAP_SM_PS; ++ ++ ht_bss_conf.primary_channel = req_bss_cap->primary_channel; ++ ht_bss_conf.bss_cap = req_bss_cap->bss_cap; ++ ht_bss_conf.bss_op_mode = req_bss_cap->bss_op_mode; ++ ++ ht_cap.ampdu_factor = req_ht_cap->ampdu_factor; ++ ht_cap.ampdu_density = req_ht_cap->ampdu_density; ++ ++ /* own MCS TX capabilities */ ++ tx_mcs_set_cap = sband->ht_cap.mcs.tx_params; ++ ++ /* ++ * configure supported Tx MCS according to requested MCS ++ * (based in most cases on Rx capabilities of peer) and self ++ * Tx MCS capabilities (as defined by low level driver HW ++ * Tx capabilities) ++ */ ++ ++ /* can we TX with MCS rates? */ ++ if (!(tx_mcs_set_cap & IEEE80211_HT_MCS_TX_DEFINED)) ++ goto check_changed; ++ ++ /* Counting from 0, therefore +1 */ ++ if (tx_mcs_set_cap & IEEE80211_HT_MCS_TX_RX_DIFF) ++ max_tx_streams = ++ ((tx_mcs_set_cap & IEEE80211_HT_MCS_TX_MAX_STREAMS_MASK) ++ >> IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT) + 1; ++ else ++ max_tx_streams = IEEE80211_HT_MCS_TX_MAX_STREAMS; ++ ++ /* ++ * 802.11n D5.0 20.3.5 / 20.6 says: ++ * - indices 0 to 7 and 32 are single spatial stream ++ * - 8 to 31 are multiple spatial streams using equal modulation ++ * [8..15 for two streams, 16..23 for three and 24..31 for four] ++ * - remainder are multiple spatial streams using unequal modulation ++ */ ++ for (i = 0; i < max_tx_streams; i++) ++ ht_cap.mcs.rx_mask[i] = ++ sband->ht_cap.mcs.rx_mask[i] & ++ req_ht_cap->mcs.rx_mask[i]; ++ ++ if (tx_mcs_set_cap & IEEE80211_HT_MCS_TX_UNEQUAL_MODULATION) ++ for (i = IEEE80211_HT_MCS_UNEQUAL_MODULATION_START_BYTE; ++ i < IEEE80211_HT_MCS_MASK_LEN; i++) ++ ht_cap.mcs.rx_mask[i] = ++ sband->ht_cap.mcs.rx_mask[i] & ++ req_ht_cap->mcs.rx_mask[i]; ++ ++ /* handle MCS rate 32 too */ ++ if (sband->ht_cap.mcs.rx_mask[32/8] & ++ req_ht_cap->mcs.rx_mask[32/8] & 1) ++ ht_cap.mcs.rx_mask[32/8] |= 1; ++ ++ check_changed: ++ /* if bss configuration changed store the new one */ ++ if (memcmp(&conf->ht_cap, &ht_cap, sizeof(ht_cap)) || ++ memcmp(&conf->ht_bss_conf, &ht_bss_conf, sizeof(ht_bss_conf))) { ++ changed |= BSS_CHANGED_HT; ++ memcpy(&conf->ht_cap, &ht_cap, sizeof(ht_cap)); ++ memcpy(&conf->ht_bss_conf, &ht_bss_conf, sizeof(ht_bss_conf)); ++ } + +- return 0; ++ return changed; + } + + static void ieee80211_send_addba_request(struct ieee80211_sub_if_data *sdata, +@@ -802,7 +909,7 @@ void ieee80211_process_addba_request(str + * check if configuration can support the BA policy + * and if buffer size does not exceeds max value */ + if (((ba_policy != 1) +- && (!(conf->ht_conf.cap & IEEE80211_HT_CAP_DELAY_BA))) ++ && (!(conf->ht_cap.cap & IEEE80211_HT_CAP_DELAY_BA))) + || (buf_size > IEEE80211_MAX_AMPDU_BUF)) { + status = WLAN_STATUS_INVALID_QOS_PARAM; + #ifdef CONFIG_MAC80211_HT_DEBUG +@@ -820,7 +927,7 @@ void ieee80211_process_addba_request(str + + sband = local->hw.wiphy->bands[conf->channel->band]; + buf_size = IEEE80211_MIN_AMPDU_BUF; +- buf_size = buf_size << sband->ht_info.ampdu_factor; ++ buf_size = buf_size << sband->ht_cap.ampdu_factor; + } + + +--- everything.orig/net/mac80211/mlme.c 2008-10-08 20:45:06.000000000 +0200 ++++ everything/net/mac80211/mlme.c 2008-10-09 02:16:26.000000000 +0200 +@@ -236,7 +236,7 @@ static void ieee80211_send_assoc(struct + struct ieee80211_local *local = sdata->local; + struct sk_buff *skb; + struct ieee80211_mgmt *mgmt; +- u8 *pos, *ies, *ht_add_ie; ++ u8 *pos, *ies, *ht_ie; + int i, len, count, rates_len, supp_rates_len; + u16 capab; + struct ieee80211_bss *bss; +@@ -393,24 +393,25 @@ static void ieee80211_send_assoc(struct + + /* wmm support is a must to HT */ + if (wmm && (ifsta->flags & IEEE80211_STA_WMM_ENABLED) && +- sband->ht_info.ht_supported && +- (ht_add_ie = ieee80211_bss_get_ie(bss, WLAN_EID_HT_EXTRA_INFO))) { +- struct ieee80211_ht_addt_info *ht_add_info = +- (struct ieee80211_ht_addt_info *)ht_add_ie; +- u16 cap = sband->ht_info.cap; ++ sband->ht_cap.ht_supported && ++ (ht_ie = ieee80211_bss_get_ie(bss, WLAN_EID_HT_INFORMATION)) && ++ ht_ie[1] >= sizeof(struct ieee80211_ht_info)) { ++ struct ieee80211_ht_info *ht_info = ++ (struct ieee80211_ht_info *)(ht_ie + 2); ++ u16 cap = sband->ht_cap.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: ++ switch (ht_info->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) { ++ case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: + if (flags & IEEE80211_CHAN_NO_FAT_ABOVE) { +- cap &= ~IEEE80211_HT_CAP_SUP_WIDTH; ++ cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; + cap &= ~IEEE80211_HT_CAP_SGI_40; + } + break; +- case IEEE80211_HT_IE_CHA_SEC_BELOW: ++ case IEEE80211_HT_PARAM_CHA_SEC_BELOW: + if (flags & IEEE80211_CHAN_NO_FAT_BELOW) { +- cap &= ~IEEE80211_HT_CAP_SUP_WIDTH; ++ cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; + cap &= ~IEEE80211_HT_CAP_SGI_40; + } + break; +@@ -424,9 +425,9 @@ static void ieee80211_send_assoc(struct + memcpy(pos, &tmp, sizeof(u16)); + pos += sizeof(u16); + /* TODO: needs a define here for << 2 */ +- *pos++ = sband->ht_info.ampdu_factor | +- (sband->ht_info.ampdu_density << 2); +- memcpy(pos, sband->ht_info.supp_mcs_set, 16); ++ *pos++ = sband->ht_cap.ampdu_factor | ++ (sband->ht_cap.ampdu_density << 2); ++ memcpy(pos, &sband->ht_cap.mcs, sizeof(sband->ht_cap.mcs)); + } + + kfree(ifsta->assocreq_ies); +@@ -732,7 +733,7 @@ static void ieee80211_set_associated(str + if (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) { + changed |= BSS_CHANGED_HT; + sdata->bss_conf.assoc_ht = 1; +- sdata->bss_conf.ht_conf = &conf->ht_conf; ++ sdata->bss_conf.ht_cap = &conf->ht_cap; + sdata->bss_conf.ht_bss_conf = &conf->ht_bss_conf; + } + +@@ -856,7 +857,7 @@ static void ieee80211_set_disassoc(struc + changed |= BSS_CHANGED_HT; + + sdata->bss_conf.assoc_ht = 0; +- sdata->bss_conf.ht_conf = NULL; ++ sdata->bss_conf.ht_cap = NULL; + sdata->bss_conf.ht_bss_conf = NULL; + + ieee80211_led_assoc(local, 0); +@@ -1348,11 +1349,11 @@ static void ieee80211_rx_mgmt_assoc_resp + if (elems.ht_cap_elem && elems.ht_info_elem && elems.wmm_param && + (ifsta->flags & IEEE80211_STA_WMM_ENABLED)) { + struct ieee80211_ht_bss_info bss_info; +- ieee80211_ht_cap_ie_to_ht_info( +- elems.ht_cap_elem, &sta->sta.ht_info); +- ieee80211_ht_addt_info_ie_to_ht_bss_info( ++ ieee80211_ht_cap_ie_to_sta_ht_cap( ++ elems.ht_cap_elem, &sta->sta.ht_cap); ++ ieee80211_ht_info_ie_to_ht_bss_info( + elems.ht_info_elem, &bss_info); +- ieee80211_handle_ht(local, 1, &sta->sta.ht_info, &bss_info); ++ ieee80211_handle_ht(local, &sta->sta.ht_cap, &bss_info); + } + + rate_control_rate_init(sta); +@@ -1712,9 +1713,9 @@ static void ieee80211_rx_mgmt_beacon(str + elems.wmm_param && conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) { + struct ieee80211_ht_bss_info bss_info; + +- ieee80211_ht_addt_info_ie_to_ht_bss_info( ++ ieee80211_ht_info_ie_to_ht_bss_info( + elems.ht_info_elem, &bss_info); +- changed |= ieee80211_handle_ht(local, 1, &conf->ht_conf, ++ changed |= ieee80211_handle_ht(local, &conf->ht_cap, + &bss_info); + } + +--- everything.orig/net/mac80211/util.c 2008-10-08 20:45:06.000000000 +0200 ++++ everything/net/mac80211/util.c 2008-10-09 02:16:28.000000000 +0200 +@@ -532,8 +532,8 @@ void ieee802_11_parse_elems(u8 *start, s + if (elen >= sizeof(struct ieee80211_ht_cap)) + elems->ht_cap_elem = (void *)pos; + break; +- case WLAN_EID_HT_EXTRA_INFO: +- if (elen >= sizeof(struct ieee80211_ht_addt_info)) ++ case WLAN_EID_HT_INFORMATION: ++ if (elen >= sizeof(struct ieee80211_ht_info)) + elems->ht_info_elem = (void *)pos; + break; + case WLAN_EID_MESH_ID: +--- everything.orig/net/mac80211/cfg.c 2008-10-08 20:45:06.000000000 +0200 ++++ everything/net/mac80211/cfg.c 2008-10-09 02:16:29.000000000 +0200 +@@ -635,10 +635,9 @@ static void sta_apply_parameters(struct + sta->sta.supp_rates[local->oper_channel->band] = rates; + } + +- if (params->ht_capa) { +- ieee80211_ht_cap_ie_to_ht_info(params->ht_capa, +- &sta->sta.ht_info); +- } ++ if (params->ht_capa) ++ ieee80211_ht_cap_ie_to_sta_ht_cap(params->ht_capa, ++ &sta->sta.ht_cap); + + if (ieee80211_vif_is_mesh(&sdata->vif) && params->plink_action) { + switch (params->plink_action) { +--- everything.orig/drivers/net/wireless/iwlwifi/iwl-agn-rs.c 2008-10-08 20:44:47.000000000 +0200 ++++ everything/drivers/net/wireless/iwlwifi/iwl-agn-rs.c 2008-10-09 02:16:27.000000000 +0200 +@@ -1136,10 +1136,10 @@ static int rs_switch_to_mimo2(struct iwl + s8 is_green = lq_sta->is_green; + + if (!(conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) || +- !sta->ht_info.ht_supported) ++ !sta->ht_cap.ht_supported) + return -1; + +- if (((sta->ht_info.cap & IEEE80211_HT_CAP_SM_PS) >> 2) ++ if (((sta->ht_cap.cap & IEEE80211_HT_CAP_SM_PS) >> 2) + == WLAN_HT_CAP_SM_PS_STATIC) + return -1; + +@@ -1204,7 +1204,7 @@ static int rs_switch_to_siso(struct iwl_ + s32 rate; + + if (!(conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) || +- !sta->ht_info.ht_supported) ++ !sta->ht_cap.ht_supported) + return -1; + + IWL_DEBUG_RATE("LQ: try to switch to SISO\n"); +@@ -2244,19 +2244,19 @@ static void rs_rate_init(void *priv_r, s + * active_siso_rate mask includes 9 MBits (bit 5), and CCK (bits 0-3), + * supp_rates[] does not; shift to convert format, force 9 MBits off. + */ +- lq_sta->active_siso_rate = conf->ht_conf.supp_mcs_set[0] << 1; +- lq_sta->active_siso_rate |= conf->ht_conf.supp_mcs_set[0] & 0x1; ++ lq_sta->active_siso_rate = conf->ht_cap.mcs.rx_mask[0] << 1; ++ lq_sta->active_siso_rate |= conf->ht_cap.mcs.rx_mask[0] & 0x1; + lq_sta->active_siso_rate &= ~((u16)0x2); + lq_sta->active_siso_rate <<= IWL_FIRST_OFDM_RATE; + + /* Same here */ +- lq_sta->active_mimo2_rate = conf->ht_conf.supp_mcs_set[1] << 1; +- lq_sta->active_mimo2_rate |= conf->ht_conf.supp_mcs_set[1] & 0x1; ++ lq_sta->active_mimo2_rate = conf->ht_cap.mcs.rx_mask[1] << 1; ++ lq_sta->active_mimo2_rate |= conf->ht_cap.mcs.rx_mask[1] & 0x1; + lq_sta->active_mimo2_rate &= ~((u16)0x2); + lq_sta->active_mimo2_rate <<= IWL_FIRST_OFDM_RATE; + +- lq_sta->active_mimo3_rate = conf->ht_conf.supp_mcs_set[2] << 1; +- lq_sta->active_mimo3_rate |= conf->ht_conf.supp_mcs_set[2] & 0x1; ++ lq_sta->active_mimo3_rate = conf->ht_cap.mcs.rx_mask[2] << 1; ++ lq_sta->active_mimo3_rate |= conf->ht_cap.mcs.rx_mask[2] & 0x1; + lq_sta->active_mimo3_rate &= ~((u16)0x2); + lq_sta->active_mimo3_rate <<= IWL_FIRST_OFDM_RATE; + +--- everything.orig/drivers/net/wireless/iwlwifi/iwl-agn.c 2008-10-08 20:44:48.000000000 +0200 ++++ everything/drivers/net/wireless/iwlwifi/iwl-agn.c 2008-10-09 02:16:29.000000000 +0200 +@@ -553,7 +553,7 @@ static int iwl4965_send_beacon_cmd(struc + static void iwl4965_ht_conf(struct iwl_priv *priv, + struct ieee80211_bss_conf *bss_conf) + { +- struct ieee80211_ht_info *ht_conf = bss_conf->ht_conf; ++ struct ieee80211_sta_ht_cap *ht_conf = bss_conf->ht_cap; + struct ieee80211_ht_bss_info *ht_bss_conf = bss_conf->ht_bss_conf; + struct iwl_ht_info *iwl_conf = &priv->current_ht_config; + +@@ -574,27 +574,27 @@ static void iwl4965_ht_conf(struct iwl_p + !!(ht_conf->cap & IEEE80211_HT_CAP_MAX_AMSDU); + + iwl_conf->supported_chan_width = +- !!(ht_conf->cap & IEEE80211_HT_CAP_SUP_WIDTH); ++ !!(ht_conf->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40); + iwl_conf->extension_chan_offset = +- ht_bss_conf->bss_cap & IEEE80211_HT_IE_CHA_SEC_OFFSET; ++ ht_bss_conf->bss_cap & IEEE80211_HT_PARAM_CHA_SEC_OFFSET; + /* If no above or below channel supplied disable FAT channel */ +- if (iwl_conf->extension_chan_offset != IEEE80211_HT_IE_CHA_SEC_ABOVE && +- iwl_conf->extension_chan_offset != IEEE80211_HT_IE_CHA_SEC_BELOW) { +- iwl_conf->extension_chan_offset = IEEE80211_HT_IE_CHA_SEC_NONE; ++ if (iwl_conf->extension_chan_offset != IEEE80211_HT_PARAM_CHA_SEC_ABOVE && ++ iwl_conf->extension_chan_offset != IEEE80211_HT_PARAM_CHA_SEC_BELOW) { ++ iwl_conf->extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_NONE; + iwl_conf->supported_chan_width = 0; + } + + iwl_conf->sm_ps = (u8)((ht_conf->cap & IEEE80211_HT_CAP_SM_PS) >> 2); + +- memcpy(iwl_conf->supp_mcs_set, ht_conf->supp_mcs_set, 16); ++ memcpy(&iwl_conf->mcs, &ht_conf->mcs, 16); + + iwl_conf->control_channel = ht_bss_conf->primary_channel; + iwl_conf->tx_chan_width = +- !!(ht_bss_conf->bss_cap & IEEE80211_HT_IE_CHA_WIDTH); ++ !!(ht_bss_conf->bss_cap & IEEE80211_HT_PARAM_CHAN_WIDTH_ANY); + iwl_conf->ht_protection = +- ht_bss_conf->bss_op_mode & IEEE80211_HT_IE_HT_PROTECTION; ++ ht_bss_conf->bss_op_mode & IEEE80211_HT_OP_MODE_PROTECTION; + iwl_conf->non_GF_STA_present = +- !!(ht_bss_conf->bss_op_mode & IEEE80211_HT_IE_NON_GF_STA_PRSNT); ++ !!(ht_bss_conf->bss_op_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT); + + IWL_DEBUG_MAC80211("control channel %d\n", iwl_conf->control_channel); + IWL_DEBUG_MAC80211("leave\n"); +--- everything.orig/drivers/net/wireless/iwlwifi/iwl-core.c 2008-10-08 20:44:47.000000000 +0200 ++++ everything/drivers/net/wireless/iwlwifi/iwl-core.c 2008-10-09 02:16:26.000000000 +0200 +@@ -382,10 +382,10 @@ void iwl_reset_qos(struct iwl_priv *priv + } + EXPORT_SYMBOL(iwl_reset_qos); + +-#define MAX_BIT_RATE_40_MHZ 0x96 /* 150 Mbps */ +-#define MAX_BIT_RATE_20_MHZ 0x48 /* 72 Mbps */ ++#define MAX_BIT_RATE_40_MHZ 150 /* Mbps */ ++#define MAX_BIT_RATE_20_MHZ 72 /* Mbps */ + static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv, +- struct ieee80211_ht_info *ht_info, ++ struct ieee80211_sta_ht_cap *ht_info, + enum ieee80211_band band) + { + u16 max_bit_rate = 0; +@@ -393,45 +393,46 @@ static void iwlcore_init_ht_hw_capab(con + u8 tx_chains_num = priv->hw_params.tx_chains_num; + + ht_info->cap = 0; +- memset(ht_info->supp_mcs_set, 0, 16); ++ memset(&ht_info->mcs, 0, sizeof(ht_info->mcs)); + +- ht_info->ht_supported = 1; ++ ht_info->ht_supported = true; + +- ht_info->cap |= (u16)IEEE80211_HT_CAP_GRN_FLD; +- ht_info->cap |= (u16)IEEE80211_HT_CAP_SGI_20; +- ht_info->cap |= (u16)(IEEE80211_HT_CAP_SM_PS & ++ ht_info->cap |= IEEE80211_HT_CAP_GRN_FLD; ++ ht_info->cap |= IEEE80211_HT_CAP_SGI_20; ++ ht_info->cap |= (IEEE80211_HT_CAP_SM_PS & + (WLAN_HT_CAP_SM_PS_DISABLED << 2)); + + max_bit_rate = MAX_BIT_RATE_20_MHZ; + if (priv->hw_params.fat_channel & BIT(band)) { +- ht_info->cap |= (u16)IEEE80211_HT_CAP_SUP_WIDTH; +- ht_info->cap |= (u16)IEEE80211_HT_CAP_SGI_40; +- ht_info->supp_mcs_set[4] = 0x01; ++ ht_info->cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40; ++ ht_info->cap |= IEEE80211_HT_CAP_SGI_40; ++ ht_info->mcs.rx_mask[4] = 0x01; + max_bit_rate = MAX_BIT_RATE_40_MHZ; + } + + if (priv->cfg->mod_params->amsdu_size_8K) +- ht_info->cap |= (u16)IEEE80211_HT_CAP_MAX_AMSDU; ++ ht_info->cap |= IEEE80211_HT_CAP_MAX_AMSDU; + + ht_info->ampdu_factor = CFG_HT_RX_AMPDU_FACTOR_DEF; + ht_info->ampdu_density = CFG_HT_MPDU_DENSITY_DEF; + +- ht_info->supp_mcs_set[0] = 0xFF; ++ ht_info->mcs.rx_mask[0] = 0xFF; + if (rx_chains_num >= 2) +- ht_info->supp_mcs_set[1] = 0xFF; ++ ht_info->mcs.rx_mask[1] = 0xFF; + if (rx_chains_num >= 3) +- ht_info->supp_mcs_set[2] = 0xFF; ++ ht_info->mcs.rx_mask[2] = 0xFF; + + /* Highest supported Rx data rate */ + max_bit_rate *= rx_chains_num; +- ht_info->supp_mcs_set[10] = (u8)(max_bit_rate & 0x00FF); +- ht_info->supp_mcs_set[11] = (u8)((max_bit_rate & 0xFF00) >> 8); ++ WARN_ON(max_bit_rate & ~IEEE80211_HT_MCS_RX_HIGHEST_MASK); ++ ht_info->mcs.rx_highest = cpu_to_le16(max_bit_rate); + + /* Tx MCS capabilities */ +- ht_info->supp_mcs_set[12] = IEEE80211_HT_CAP_MCS_TX_DEFINED; ++ ht_info->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; + if (tx_chains_num != rx_chains_num) { +- ht_info->supp_mcs_set[12] |= IEEE80211_HT_CAP_MCS_TX_RX_DIFF; +- ht_info->supp_mcs_set[12] |= ((tx_chains_num - 1) << 2); ++ ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF; ++ ht_info->mcs.tx_params |= ((tx_chains_num - 1) << ++ IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT); + } + } + +@@ -495,7 +496,7 @@ static int iwlcore_init_geos(struct iwl_ + sband->n_bitrates = IWL_RATE_COUNT - IWL_FIRST_OFDM_RATE; + + if (priv->cfg->sku & IWL_SKU_N) +- iwlcore_init_ht_hw_capab(priv, &sband->ht_info, ++ iwlcore_init_ht_hw_capab(priv, &sband->ht_cap, + IEEE80211_BAND_5GHZ); + + sband = &priv->bands[IEEE80211_BAND_2GHZ]; +@@ -505,7 +506,7 @@ static int iwlcore_init_geos(struct iwl_ + sband->n_bitrates = IWL_RATE_COUNT; + + if (priv->cfg->sku & IWL_SKU_N) +- iwlcore_init_ht_hw_capab(priv, &sband->ht_info, ++ iwlcore_init_ht_hw_capab(priv, &sband->ht_cap, + IEEE80211_BAND_2GHZ); + + priv->ieee_channels = channels; +@@ -595,8 +596,8 @@ static void iwlcore_free_geos(struct iwl + static bool is_single_rx_stream(struct iwl_priv *priv) + { + return !priv->current_ht_config.is_ht || +- ((priv->current_ht_config.supp_mcs_set[1] == 0) && +- (priv->current_ht_config.supp_mcs_set[2] == 0)); ++ ((priv->current_ht_config.mcs.rx_mask[1] == 0) && ++ (priv->current_ht_config.mcs.rx_mask[2] == 0)); + } + + static u8 iwl_is_channel_extension(struct iwl_priv *priv, +@@ -609,10 +610,10 @@ static u8 iwl_is_channel_extension(struc + if (!is_channel_valid(ch_info)) + return 0; + +- if (extension_chan_offset == IEEE80211_HT_IE_CHA_SEC_ABOVE) ++ if (extension_chan_offset == IEEE80211_HT_PARAM_CHA_SEC_ABOVE) + return !(ch_info->fat_extension_channel & + IEEE80211_CHAN_NO_FAT_ABOVE); +- else if (extension_chan_offset == IEEE80211_HT_IE_CHA_SEC_BELOW) ++ else if (extension_chan_offset == IEEE80211_HT_PARAM_CHA_SEC_BELOW) + return !(ch_info->fat_extension_channel & + IEEE80211_CHAN_NO_FAT_BELOW); + +@@ -620,18 +621,18 @@ static u8 iwl_is_channel_extension(struc + } + + u8 iwl_is_fat_tx_allowed(struct iwl_priv *priv, +- struct ieee80211_ht_info *sta_ht_inf) ++ struct ieee80211_sta_ht_cap *sta_ht_inf) + { + struct iwl_ht_info *iwl_ht_conf = &priv->current_ht_config; + + if ((!iwl_ht_conf->is_ht) || + (iwl_ht_conf->supported_chan_width != IWL_CHANNEL_WIDTH_40MHZ) || +- (iwl_ht_conf->extension_chan_offset == IEEE80211_HT_IE_CHA_SEC_NONE)) ++ (iwl_ht_conf->extension_chan_offset == IEEE80211_HT_PARAM_CHA_SEC_NONE)) + return 0; + + if (sta_ht_inf) { + if ((!sta_ht_inf->ht_supported) || +- (!(sta_ht_inf->cap & IEEE80211_HT_CAP_SUP_WIDTH))) ++ (!(sta_ht_inf->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40))) + return 0; + } + +@@ -671,13 +672,13 @@ void iwl_set_rxon_ht(struct iwl_priv *pr + + /* Note: control channel is opposite of extension channel */ + switch (ht_info->extension_chan_offset) { +- case IEEE80211_HT_IE_CHA_SEC_ABOVE: ++ case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: + rxon->flags &= ~(RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK); + break; +- case IEEE80211_HT_IE_CHA_SEC_BELOW: ++ case IEEE80211_HT_PARAM_CHA_SEC_BELOW: + rxon->flags |= RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK; + break; +- case IEEE80211_HT_IE_CHA_SEC_NONE: ++ case IEEE80211_HT_PARAM_CHA_SEC_NONE: + default: + rxon->flags &= ~RXON_FLG_CHANNEL_MODE_MIXED_MSK; + break; +@@ -693,9 +694,9 @@ void iwl_set_rxon_ht(struct iwl_priv *pr + "rxon flags 0x%X operation mode :0x%X " + "extension channel offset 0x%x " + "control chan %d\n", +- ht_info->supp_mcs_set[0], +- ht_info->supp_mcs_set[1], +- ht_info->supp_mcs_set[2], ++ ht_info->mcs.rx_mask[0], ++ ht_info->mcs.rx_mask[1], ++ ht_info->mcs.rx_mask[2], + le32_to_cpu(rxon->flags), ht_info->ht_protection, + ht_info->extension_chan_offset, + ht_info->control_channel); +--- everything.orig/drivers/net/wireless/iwlwifi/iwl-core.h 2008-10-08 20:44:47.000000000 +0200 ++++ everything/drivers/net/wireless/iwlwifi/iwl-core.h 2008-10-08 20:45:06.000000000 +0200 +@@ -190,7 +190,7 @@ void iwl_set_rxon_chain(struct iwl_priv + int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch); + void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info); + u8 iwl_is_fat_tx_allowed(struct iwl_priv *priv, +- struct ieee80211_ht_info *sta_ht_inf); ++ struct ieee80211_sta_ht_cap *sta_ht_inf); + int iwl_hw_nic_init(struct iwl_priv *priv); + int iwl_setup_mac(struct iwl_priv *priv); + int iwl_set_hw_params(struct iwl_priv *priv); +--- everything.orig/drivers/net/wireless/iwlwifi/iwl-dev.h 2008-10-08 20:44:47.000000000 +0200 ++++ everything/drivers/net/wireless/iwlwifi/iwl-dev.h 2008-10-09 02:16:27.000000000 +0200 +@@ -412,7 +412,7 @@ struct iwl_ht_info { + u8 max_amsdu_size; + u8 ampdu_factor; + u8 mpdu_density; +- u8 supp_mcs_set[16]; ++ struct ieee80211_mcs_info mcs; + /* BSS related data */ + u8 control_channel; + u8 extension_chan_offset; +@@ -584,7 +584,7 @@ struct iwl_addsta_cmd; + extern int iwl_send_add_sta(struct iwl_priv *priv, + struct iwl_addsta_cmd *sta, u8 flags); + extern u8 iwl_add_station_flags(struct iwl_priv *priv, const u8 *addr, +- int is_ap, u8 flags, struct ieee80211_ht_info *ht_info); ++ int is_ap, u8 flags, struct ieee80211_sta_ht_cap *ht_info); + extern void iwl4965_update_chain_flags(struct iwl_priv *priv); + extern int iwl4965_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src); + extern const u8 iwl_bcast_addr[ETH_ALEN]; +--- everything.orig/drivers/net/wireless/iwlwifi/iwl-sta.c 2008-10-08 20:44:47.000000000 +0200 ++++ everything/drivers/net/wireless/iwlwifi/iwl-sta.c 2008-10-09 02:16:29.000000000 +0200 +@@ -183,7 +183,7 @@ int iwl_send_add_sta(struct iwl_priv *pr + EXPORT_SYMBOL(iwl_send_add_sta); + + static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index, +- struct ieee80211_ht_info *sta_ht_inf) ++ struct ieee80211_sta_ht_cap *sta_ht_inf) + { + __le32 sta_flags; + u8 mimo_ps_mode; +@@ -231,7 +231,7 @@ static void iwl_set_ht_add_station(struc + * iwl_add_station_flags - Add station to tables in driver and device + */ + u8 iwl_add_station_flags(struct iwl_priv *priv, const u8 *addr, int is_ap, +- u8 flags, struct ieee80211_ht_info *ht_info) ++ u8 flags, struct ieee80211_sta_ht_cap *ht_info) + { + int i; + int sta_id = IWL_INVALID_STATION; +@@ -900,7 +900,7 @@ int iwl_rxon_add_station(struct iwl_priv + + /* Add station to device's station table */ + struct ieee80211_conf *conf = &priv->hw->conf; +- struct ieee80211_ht_info *cur_ht_config = &conf->ht_conf; ++ struct ieee80211_sta_ht_cap *cur_ht_config = &conf->ht_cap; + + if ((is_ap) && + (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) && +--- everything.orig/drivers/net/wireless/iwlwifi/iwl-scan.c 2008-10-08 20:44:47.000000000 +0200 ++++ everything/drivers/net/wireless/iwlwifi/iwl-scan.c 2008-10-08 20:45:06.000000000 +0200 +@@ -550,7 +550,7 @@ static void iwl_ht_cap_to_ie(const struc + { + struct ieee80211_ht_cap *ht_cap; + +- if (!sband || !sband->ht_info.ht_supported) ++ if (!sband || !sband->ht_cap.ht_supported) + return; + + if (*left < sizeof(struct ieee80211_ht_cap)) +@@ -559,12 +559,12 @@ static void iwl_ht_cap_to_ie(const struc + *pos++ = sizeof(struct ieee80211_ht_cap); + ht_cap = (struct ieee80211_ht_cap *) pos; + +- ht_cap->cap_info = cpu_to_le16(sband->ht_info.cap); +- memcpy(ht_cap->supp_mcs_set, sband->ht_info.supp_mcs_set, 16); ++ ht_cap->cap_info = cpu_to_le16(sband->ht_cap.cap); ++ memcpy(&ht_cap->mcs, &sband->ht_cap.mcs, 16); + ht_cap->ampdu_params_info = +- (sband->ht_info.ampdu_factor & IEEE80211_HT_CAP_AMPDU_FACTOR) | +- ((sband->ht_info.ampdu_density << 2) & +- IEEE80211_HT_CAP_AMPDU_DENSITY); ++ (sband->ht_cap.ampdu_factor & IEEE80211_HT_AMPDU_PARM_FACTOR) | ++ ((sband->ht_cap.ampdu_density << 2) & ++ IEEE80211_HT_AMPDU_PARM_DENSITY); + *left -= sizeof(struct ieee80211_ht_cap); + } + +--- everything.orig/drivers/net/wireless/ath9k/main.c 2008-10-08 20:44:48.000000000 +0200 ++++ everything/drivers/net/wireless/ath9k/main.c 2008-10-09 02:16:30.000000000 +0200 +@@ -61,24 +61,24 @@ static u32 ath_get_extchanmode(struct at + + switch (chan->band) { + case IEEE80211_BAND_2GHZ: +- if ((ext_chan_offset == IEEE80211_HT_IE_CHA_SEC_NONE) && ++ if ((ext_chan_offset == IEEE80211_HT_PARAM_CHA_SEC_NONE) && + (tx_chan_width == ATH9K_HT_MACMODE_20)) + chanmode = CHANNEL_G_HT20; +- if ((ext_chan_offset == IEEE80211_HT_IE_CHA_SEC_ABOVE) && ++ if ((ext_chan_offset == IEEE80211_HT_PARAM_CHA_SEC_ABOVE) && + (tx_chan_width == ATH9K_HT_MACMODE_2040)) + chanmode = CHANNEL_G_HT40PLUS; +- if ((ext_chan_offset == IEEE80211_HT_IE_CHA_SEC_BELOW) && ++ if ((ext_chan_offset == IEEE80211_HT_PARAM_CHA_SEC_BELOW) && + (tx_chan_width == ATH9K_HT_MACMODE_2040)) + chanmode = CHANNEL_G_HT40MINUS; + break; + case IEEE80211_BAND_5GHZ: +- if ((ext_chan_offset == IEEE80211_HT_IE_CHA_SEC_NONE) && ++ if ((ext_chan_offset == IEEE80211_HT_PARAM_CHA_SEC_NONE) && + (tx_chan_width == ATH9K_HT_MACMODE_20)) + chanmode = CHANNEL_A_HT20; +- if ((ext_chan_offset == IEEE80211_HT_IE_CHA_SEC_ABOVE) && ++ if ((ext_chan_offset == IEEE80211_HT_PARAM_CHA_SEC_ABOVE) && + (tx_chan_width == ATH9K_HT_MACMODE_2040)) + chanmode = CHANNEL_A_HT40PLUS; +- if ((ext_chan_offset == IEEE80211_HT_IE_CHA_SEC_BELOW) && ++ if ((ext_chan_offset == IEEE80211_HT_PARAM_CHA_SEC_BELOW) && + (tx_chan_width == ATH9K_HT_MACMODE_2040)) + chanmode = CHANNEL_A_HT40MINUS; + break; +@@ -215,24 +215,24 @@ static void ath_key_delete(struct ath_so + ath_key_reset(sc, key->keyidx, freeslot); + } + +-static void setup_ht_cap(struct ieee80211_ht_info *ht_info) ++static void setup_ht_cap(struct ieee80211_sta_ht_cap *ht_info) + { + #define ATH9K_HT_CAP_MAXRXAMPDU_65536 0x3 /* 2 ^ 16 */ + #define ATH9K_HT_CAP_MPDUDENSITY_8 0x6 /* 8 usec */ + +- ht_info->ht_supported = 1; +- ht_info->cap = (u16)IEEE80211_HT_CAP_SUP_WIDTH +- |(u16)IEEE80211_HT_CAP_SM_PS +- |(u16)IEEE80211_HT_CAP_SGI_40 +- |(u16)IEEE80211_HT_CAP_DSSSCCK40; ++ ht_info->ht_supported = true; ++ ht_info->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 | ++ IEEE80211_HT_CAP_SM_PS | ++ IEEE80211_HT_CAP_SGI_40 | ++ IEEE80211_HT_CAP_DSSSCCK40; + + ht_info->ampdu_factor = ATH9K_HT_CAP_MAXRXAMPDU_65536; + ht_info->ampdu_density = ATH9K_HT_CAP_MPDUDENSITY_8; +- /* setup supported mcs set */ +- memset(ht_info->supp_mcs_set, 0, 16); +- ht_info->supp_mcs_set[0] = 0xff; +- ht_info->supp_mcs_set[1] = 0xff; +- ht_info->supp_mcs_set[12] = IEEE80211_HT_CAP_MCS_TX_DEFINED; ++ /* set up supported mcs set */ ++ memset(&ht_info->mcs, 0, sizeof(ht_info->mcs)); ++ ht_info->mcs.rx_mask[0] = 0xff; ++ ht_info->mcs.rx_mask[1] = 0xff; ++ ht_info->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; + } + + static int ath_rate2idx(struct ath_softc *sc, int rate) +@@ -328,31 +328,28 @@ static u8 parse_mpdudensity(u8 mpdudensi + static void ath9k_ht_conf(struct ath_softc *sc, + struct ieee80211_bss_conf *bss_conf) + { +-#define IEEE80211_HT_CAP_40MHZ_INTOLERANT BIT(14) + struct ath_ht_info *ht_info = &sc->sc_ht_info; + + if (bss_conf->assoc_ht) { + ht_info->ext_chan_offset = + bss_conf->ht_bss_conf->bss_cap & +- IEEE80211_HT_IE_CHA_SEC_OFFSET; ++ IEEE80211_HT_PARAM_CHA_SEC_OFFSET; + +- if (!(bss_conf->ht_conf->cap & ++ if (!(bss_conf->ht_cap->cap & + IEEE80211_HT_CAP_40MHZ_INTOLERANT) && + (bss_conf->ht_bss_conf->bss_cap & +- IEEE80211_HT_IE_CHA_WIDTH)) ++ IEEE80211_HT_PARAM_CHAN_WIDTH_ANY)) + ht_info->tx_chan_width = ATH9K_HT_MACMODE_2040; + else + ht_info->tx_chan_width = ATH9K_HT_MACMODE_20; + + ath9k_hw_set11nmac2040(sc->sc_ah, ht_info->tx_chan_width); + ht_info->maxampdu = 1 << (IEEE80211_HTCAP_MAXRXAMPDU_FACTOR + +- bss_conf->ht_conf->ampdu_factor); ++ bss_conf->ht_cap->ampdu_factor); + ht_info->mpdudensity = +- parse_mpdudensity(bss_conf->ht_conf->ampdu_density); ++ parse_mpdudensity(bss_conf->ht_cap->ampdu_density); + + } +- +-#undef IEEE80211_HT_CAP_40MHZ_INTOLERANT + } + + static void ath9k_bss_assoc_info(struct ath_softc *sc, +@@ -412,7 +409,7 @@ static void ath9k_bss_assoc_info(struct + return; + } + +- if (hw->conf.ht_conf.ht_supported) ++ if (hw->conf.ht_cap.ht_supported) + sc->sc_ah->ah_channels[pos].chanmode = + ath_get_extchanmode(sc, curchan); + else +@@ -535,7 +532,7 @@ int _ath_rx_indicate(struct ath_softc *s + + if (an) { + ath_rx_input(sc, an, +- hw->conf.ht_conf.ht_supported, ++ hw->conf.ht_cap.ht_supported, + skb, status, &st); + } + if (!an || (st != ATH_RX_CONSUMED)) +@@ -944,7 +941,7 @@ static int ath_attach(u16 devid, + + if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT) + /* Setup HT capabilities for 2.4Ghz*/ +- setup_ht_cap(&sc->sbands[IEEE80211_BAND_2GHZ].ht_info); ++ setup_ht_cap(&sc->sbands[IEEE80211_BAND_2GHZ].ht_cap); + + hw->wiphy->bands[IEEE80211_BAND_2GHZ] = + &sc->sbands[IEEE80211_BAND_2GHZ]; +@@ -959,7 +956,7 @@ static int ath_attach(u16 devid, + + if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT) + /* Setup HT capabilities for 5Ghz*/ +- setup_ht_cap(&sc->sbands[IEEE80211_BAND_5GHZ].ht_info); ++ setup_ht_cap(&sc->sbands[IEEE80211_BAND_5GHZ].ht_cap); + + hw->wiphy->bands[IEEE80211_BAND_5GHZ] = + &sc->sbands[IEEE80211_BAND_5GHZ]; +@@ -1255,7 +1252,7 @@ static int ath9k_config(struct ieee80211 + (curchan->band == IEEE80211_BAND_2GHZ) ? + CHANNEL_G : CHANNEL_A; + +- if (sc->sc_curaid && hw->conf.ht_conf.ht_supported) ++ if (sc->sc_curaid && hw->conf.ht_cap.ht_supported) + sc->sc_ah->ah_channels[pos].chanmode = + ath_get_extchanmode(sc, curchan); + +--- everything.orig/drivers/net/wireless/ath9k/rc.c 2008-10-08 20:44:48.000000000 +0200 ++++ everything/drivers/net/wireless/ath9k/rc.c 2008-10-09 02:16:27.000000000 +0200 +@@ -1838,7 +1838,7 @@ void ath_rc_node_update(struct ieee80211 + struct ath_softc *sc = hw->priv; + u32 capflag = 0; + +- if (hw->conf.ht_conf.ht_supported) { ++ if (hw->conf.ht_cap.ht_supported) { + capflag |= ATH_RC_HT_FLAG | ATH_RC_DS_FLAG; + if (sc->sc_ht_info.tx_chan_width == ATH9K_HT_MACMODE_2040) + capflag |= ATH_RC_CW40_FLAG; +@@ -1910,7 +1910,7 @@ static void ath_tx_aggr_resp(struct ath_ + */ + si = container_of(sta, struct sta_info, sta); + buffersize = IEEE80211_MIN_AMPDU_BUF << +- sband->ht_info.ampdu_factor; /* FIXME */ ++ sband->ht_cap.ampdu_factor; /* FIXME */ + state = si->ampdu_mlme.tid_state_tx[tidno]; + + if (state & HT_ADDBA_RECEIVED_MSK) { +@@ -1980,7 +1980,7 @@ static void ath_get_rate(void *priv, str + + /* Check if aggregation has to be enabled for this tid */ + +- if (hw->conf.ht_conf.ht_supported) { ++ if (hw->conf.ht_cap.ht_supported) { + if (ieee80211_is_data_qos(fc)) { + qc = ieee80211_get_qos_ctl(hdr); + tid = qc[0] & 0xf; +@@ -2028,8 +2028,8 @@ static void ath_rate_init(void *priv, st + + ath_setup_rates(sc, sband, sta, ath_rc_priv); + if (sc->hw->conf.flags & IEEE80211_CONF_SUPPORT_HT_MODE) { +- for (i = 0; i < MCS_SET_SIZE; i++) { +- if (sc->hw->conf.ht_conf.supp_mcs_set[i/8] & (1<<(i%8))) ++ for (i = 0; i < 77; i++) { ++ if (sc->hw->conf.ht_cap.mcs.rx_mask[i/8] & (1<<(i%8))) + ath_rc_priv->neg_ht_rates.rs_rates[j++] = i; + if (j == ATH_RATE_MAX) + break; +--- everything.orig/drivers/net/wireless/ath9k/recv.c 2008-10-08 20:44:48.000000000 +0200 ++++ everything/drivers/net/wireless/ath9k/recv.c 2008-10-09 02:16:27.000000000 +0200 +@@ -1119,7 +1119,7 @@ int ath_rx_aggr_start(struct ath_softc * + + sband = hw->wiphy->bands[hw->conf.channel->band]; + buffersize = IEEE80211_MIN_AMPDU_BUF << +- sband->ht_info.ampdu_factor; /* FIXME */ ++ sband->ht_cap.ampdu_factor; /* FIXME */ + + rxtid = &an->an_aggr.rx.tid[tid]; + +--- everything.orig/drivers/net/wireless/ath9k/xmit.c 2008-10-08 20:44:48.000000000 +0200 ++++ everything/drivers/net/wireless/ath9k/xmit.c 2008-10-09 02:16:27.000000000 +0200 +@@ -300,7 +300,7 @@ static int ath_tx_prepare(struct ath_sof + if (ieee80211_is_data(fc) && !txctl->use_minrate) { + + /* Enable HT only for DATA frames and not for EAPOL */ +- txctl->ht = (hw->conf.ht_conf.ht_supported && ++ txctl->ht = (hw->conf.ht_cap.ht_supported && + (tx_info->flags & IEEE80211_TX_CTL_AMPDU)); + + if (is_multicast_ether_addr(hdr->addr1)) { +--- everything.orig/drivers/net/wireless/ath9k/rc.h 2008-10-08 20:44:48.000000000 +0200 ++++ everything/drivers/net/wireless/ath9k/rc.h 2008-10-08 20:45:06.000000000 +0200 +@@ -59,7 +59,6 @@ struct ath_softc; + #define FALSE 0 + + #define ATH_RATE_MAX 30 +-#define MCS_SET_SIZE 128 + + enum ieee80211_fixed_rate_mode { + IEEE80211_FIXED_RATE_NONE = 0, +--- everything.orig/drivers/net/wireless/mac80211_hwsim.c 2008-10-08 20:44:48.000000000 +0200 ++++ everything/drivers/net/wireless/mac80211_hwsim.c 2008-10-09 02:16:30.000000000 +0200 +@@ -566,19 +566,18 @@ static int __init init_mac80211_hwsim(vo + data->band.n_channels = ARRAY_SIZE(hwsim_channels); + data->band.bitrates = data->rates; + data->band.n_bitrates = ARRAY_SIZE(hwsim_rates); +- data->band.ht_info.ht_supported = 1; +- data->band.ht_info.cap = IEEE80211_HT_CAP_SUP_WIDTH | ++ data->band.ht_cap.ht_supported = true; ++ data->band.ht_cap.cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 | + IEEE80211_HT_CAP_GRN_FLD | + IEEE80211_HT_CAP_SGI_40 | + IEEE80211_HT_CAP_DSSSCCK40; +- data->band.ht_info.ampdu_factor = 0x3; +- data->band.ht_info.ampdu_density = 0x6; +- memset(data->band.ht_info.supp_mcs_set, 0, +- sizeof(data->band.ht_info.supp_mcs_set)); +- data->band.ht_info.supp_mcs_set[0] = 0xff; +- data->band.ht_info.supp_mcs_set[1] = 0xff; +- data->band.ht_info.supp_mcs_set[12] = +- IEEE80211_HT_CAP_MCS_TX_DEFINED; ++ data->band.ht_cap.ampdu_factor = 0x3; ++ data->band.ht_cap.ampdu_density = 0x6; ++ memset(&data->band.ht_cap.mcs, 0, ++ sizeof(data->band.ht_cap.mcs)); ++ data->band.ht_cap.mcs.rx_mask[0] = 0xff; ++ data->band.ht_cap.mcs.rx_mask[1] = 0xff; ++ data->band.ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; + hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &data->band; + + err = ieee80211_register_hw(hw); |