diff options
author | Ron Rindjunsky <ron.rindjunsky@intel.com> | 2007-11-26 09:14:39 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-28 18:05:43 -0500 |
commit | fd105e79d19439d29a6561178fb5fe511e141f6b (patch) | |
tree | 4867e5b41bc2a32c1d2c399f85827c5c7909c52f /drivers/net/wireless/iwlwifi/iwl4965-base.c | |
parent | 8fb8803239debda77b90f7e4a5098067187d865e (diff) |
iwlwifi: 802.11n comply HT self configuration flow with mac80211 framework
This patch conforms HW configuration changes according to new mac80211's
HT framework
Signed-off-by: Ron Rindjunsky <ron.rindjunsky@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl4965-base.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl4965-base.c | 186 |
1 files changed, 45 insertions, 141 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index c2366c2d23b7..2c706395e0a4 100644 --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c | |||
@@ -2111,7 +2111,7 @@ static void iwl4965_activate_qos(struct iwl4965_priv *priv, u8 force) | |||
2111 | QOS_PARAM_FLG_UPDATE_EDCA_MSK; | 2111 | QOS_PARAM_FLG_UPDATE_EDCA_MSK; |
2112 | 2112 | ||
2113 | #ifdef CONFIG_IWL4965_HT | 2113 | #ifdef CONFIG_IWL4965_HT |
2114 | if (priv->is_ht_enabled && priv->current_assoc_ht.is_ht) | 2114 | if (priv->current_ht_config.is_ht) |
2115 | priv->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK; | 2115 | priv->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK; |
2116 | #endif /* CONFIG_IWL4965_HT */ | 2116 | #endif /* CONFIG_IWL4965_HT */ |
2117 | 2117 | ||
@@ -7304,13 +7304,8 @@ static void iwl4965_bg_post_associate(struct work_struct *data) | |||
7304 | priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; | 7304 | priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; |
7305 | 7305 | ||
7306 | #ifdef CONFIG_IWL4965_HT | 7306 | #ifdef CONFIG_IWL4965_HT |
7307 | if (priv->is_ht_enabled && priv->current_assoc_ht.is_ht) | 7307 | if (priv->current_ht_config.is_ht) |
7308 | iwl4965_set_rxon_ht(priv, &priv->current_assoc_ht); | 7308 | iwl4965_set_rxon_ht(priv, &priv->current_ht_config); |
7309 | else { | ||
7310 | priv->active_rate_ht[0] = 0; | ||
7311 | priv->active_rate_ht[1] = 0; | ||
7312 | priv->current_channel_width = IWL_CHANNEL_WIDTH_20MHZ; | ||
7313 | } | ||
7314 | #endif /* CONFIG_IWL4965_HT*/ | 7309 | #endif /* CONFIG_IWL4965_HT*/ |
7315 | iwl4965_set_rxon_chain(priv); | 7310 | iwl4965_set_rxon_chain(priv); |
7316 | priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id); | 7311 | priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id); |
@@ -8112,7 +8107,7 @@ static void iwl4965_mac_reset_tsf(struct ieee80211_hw *hw) | |||
8112 | priv->lq_mngr.lq_ready = 0; | 8107 | priv->lq_mngr.lq_ready = 0; |
8113 | #ifdef CONFIG_IWL4965_HT | 8108 | #ifdef CONFIG_IWL4965_HT |
8114 | spin_lock_irqsave(&priv->lock, flags); | 8109 | spin_lock_irqsave(&priv->lock, flags); |
8115 | memset(&priv->current_assoc_ht, 0, sizeof(struct sta_ht_info)); | 8110 | memset(&priv->current_ht_config, 0, sizeof(struct iwl_ht_info)); |
8116 | spin_unlock_irqrestore(&priv->lock, flags); | 8111 | spin_unlock_irqrestore(&priv->lock, flags); |
8117 | #ifdef CONFIG_IWL4965_HT_AGG | 8112 | #ifdef CONFIG_IWL4965_HT_AGG |
8118 | /* if (priv->lq_mngr.agg_ctrl.granted_ba) | 8113 | /* if (priv->lq_mngr.agg_ctrl.granted_ba) |
@@ -8232,132 +8227,61 @@ static int iwl4965_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *sk | |||
8232 | } | 8227 | } |
8233 | 8228 | ||
8234 | #ifdef CONFIG_IWL4965_HT | 8229 | #ifdef CONFIG_IWL4965_HT |
8235 | union ht_cap_info { | ||
8236 | struct { | ||
8237 | u16 advanced_coding_cap :1; | ||
8238 | u16 supported_chan_width_set :1; | ||
8239 | u16 mimo_power_save_mode :2; | ||
8240 | u16 green_field :1; | ||
8241 | u16 short_GI20 :1; | ||
8242 | u16 short_GI40 :1; | ||
8243 | u16 tx_stbc :1; | ||
8244 | u16 rx_stbc :1; | ||
8245 | u16 beam_forming :1; | ||
8246 | u16 delayed_ba :1; | ||
8247 | u16 maximal_amsdu_size :1; | ||
8248 | u16 cck_mode_at_40MHz :1; | ||
8249 | u16 psmp_support :1; | ||
8250 | u16 stbc_ctrl_frame_support :1; | ||
8251 | u16 sig_txop_protection_support :1; | ||
8252 | }; | ||
8253 | u16 val; | ||
8254 | } __attribute__ ((packed)); | ||
8255 | |||
8256 | union ht_param_info{ | ||
8257 | struct { | ||
8258 | u8 max_rx_ampdu_factor :2; | ||
8259 | u8 mpdu_density :3; | ||
8260 | u8 reserved :3; | ||
8261 | }; | ||
8262 | u8 val; | ||
8263 | } __attribute__ ((packed)); | ||
8264 | |||
8265 | union ht_exra_param_info { | ||
8266 | struct { | ||
8267 | u8 ext_chan_offset :2; | ||
8268 | u8 tx_chan_width :1; | ||
8269 | u8 rifs_mode :1; | ||
8270 | u8 controlled_access_only :1; | ||
8271 | u8 service_interval_granularity :3; | ||
8272 | }; | ||
8273 | u8 val; | ||
8274 | } __attribute__ ((packed)); | ||
8275 | |||
8276 | union ht_operation_mode{ | ||
8277 | struct { | ||
8278 | u16 op_mode :2; | ||
8279 | u16 non_GF :1; | ||
8280 | u16 reserved :13; | ||
8281 | }; | ||
8282 | u16 val; | ||
8283 | } __attribute__ ((packed)); | ||
8284 | 8230 | ||
8285 | 8231 | static void iwl4965_ht_info_fill(struct ieee80211_conf *conf, | |
8286 | static int sta_ht_info_init(struct ieee80211_ht_capability *ht_cap, | 8232 | struct iwl4965_priv *priv) |
8287 | struct ieee80211_ht_additional_info *ht_extra, | ||
8288 | struct sta_ht_info *ht_info_ap, | ||
8289 | struct sta_ht_info *ht_info) | ||
8290 | { | 8233 | { |
8291 | union ht_cap_info cap; | 8234 | struct iwl_ht_info *iwl_conf = &priv->current_ht_config; |
8292 | union ht_operation_mode op_mode; | 8235 | struct ieee80211_ht_info *ht_conf = &conf->ht_conf; |
8293 | union ht_param_info param_info; | 8236 | struct ieee80211_ht_bss_info *ht_bss_conf = &conf->ht_bss_conf; |
8294 | union ht_exra_param_info extra_param_info; | ||
8295 | 8237 | ||
8296 | IWL_DEBUG_MAC80211("enter: \n"); | 8238 | IWL_DEBUG_MAC80211("enter: \n"); |
8297 | 8239 | ||
8298 | if (!ht_info) { | 8240 | if (!(conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE)) { |
8299 | IWL_DEBUG_MAC80211("leave: ht_info is NULL\n"); | 8241 | iwl_conf->is_ht = 0; |
8300 | return -1; | 8242 | return; |
8301 | } | 8243 | } |
8302 | 8244 | ||
8303 | if (ht_cap) { | 8245 | iwl_conf->is_ht = 1; |
8304 | cap.val = (u16) le16_to_cpu(ht_cap->capabilities_info); | 8246 | priv->ps_mode = (u8)((ht_conf->cap & IEEE80211_HT_CAP_MIMO_PS) >> 2); |
8305 | param_info.val = ht_cap->mac_ht_params_info; | 8247 | |
8306 | ht_info->is_ht = 1; | 8248 | if (ht_conf->cap & IEEE80211_HT_CAP_SGI_20) |
8307 | if (cap.short_GI20) | 8249 | iwl_conf->sgf |= 0x1; |
8308 | ht_info->sgf |= 0x1; | 8250 | if (ht_conf->cap & IEEE80211_HT_CAP_SGI_40) |
8309 | if (cap.short_GI40) | 8251 | iwl_conf->sgf |= 0x2; |
8310 | ht_info->sgf |= 0x2; | 8252 | |
8311 | ht_info->is_green_field = cap.green_field; | 8253 | iwl_conf->is_green_field = !!(ht_conf->cap & IEEE80211_HT_CAP_GRN_FLD); |
8312 | ht_info->max_amsdu_size = cap.maximal_amsdu_size; | 8254 | iwl_conf->max_amsdu_size = |
8313 | ht_info->supported_chan_width = cap.supported_chan_width_set; | 8255 | !!(ht_conf->cap & IEEE80211_HT_CAP_MAX_AMSDU); |
8314 | ht_info->tx_mimo_ps_mode = cap.mimo_power_save_mode; | 8256 | iwl_conf->supported_chan_width = |
8315 | memcpy(ht_info->supp_rates, ht_cap->supported_mcs_set, 16); | 8257 | !!(ht_conf->cap & IEEE80211_HT_CAP_SUP_WIDTH); |
8316 | 8258 | iwl_conf->tx_mimo_ps_mode = | |
8317 | ht_info->ampdu_factor = param_info.max_rx_ampdu_factor; | 8259 | (u8)((ht_conf->cap & IEEE80211_HT_CAP_MIMO_PS) >> 2); |
8318 | ht_info->mpdu_density = param_info.mpdu_density; | 8260 | memcpy(iwl_conf->supp_mcs_set, ht_conf->supp_mcs_set, 16); |
8319 | 8261 | ||
8320 | IWL_DEBUG_MAC80211("SISO mask 0x%X MIMO mask 0x%X \n", | 8262 | iwl_conf->control_channel = ht_bss_conf->primary_channel; |
8321 | ht_cap->supported_mcs_set[0], | 8263 | iwl_conf->extension_chan_offset = |
8322 | ht_cap->supported_mcs_set[1]); | 8264 | ht_bss_conf->bss_cap & IEEE80211_HT_IE_CHA_SEC_OFFSET; |
8323 | 8265 | iwl_conf->tx_chan_width = | |
8324 | if (ht_info_ap) { | 8266 | !!(ht_bss_conf->bss_cap & IEEE80211_HT_IE_CHA_WIDTH); |
8325 | ht_info->control_channel = ht_info_ap->control_channel; | 8267 | iwl_conf->ht_protection = |
8326 | ht_info->extension_chan_offset = | 8268 | ht_bss_conf->bss_op_mode & IEEE80211_HT_IE_HT_PROTECTION; |
8327 | ht_info_ap->extension_chan_offset; | 8269 | iwl_conf->non_GF_STA_present = |
8328 | ht_info->tx_chan_width = ht_info_ap->tx_chan_width; | 8270 | !!(ht_bss_conf->bss_op_mode & IEEE80211_HT_IE_NON_GF_STA_PRSNT); |
8329 | ht_info->operating_mode = ht_info_ap->operating_mode; | 8271 | |
8330 | } | 8272 | IWL_DEBUG_MAC80211("control channel %d\n", |
8331 | 8273 | iwl_conf->control_channel); | |
8332 | if (ht_extra) { | ||
8333 | extra_param_info.val = ht_extra->ht_param; | ||
8334 | ht_info->control_channel = ht_extra->control_chan; | ||
8335 | ht_info->extension_chan_offset = | ||
8336 | extra_param_info.ext_chan_offset; | ||
8337 | ht_info->tx_chan_width = extra_param_info.tx_chan_width; | ||
8338 | op_mode.val = (u16) | ||
8339 | le16_to_cpu(ht_extra->operation_mode); | ||
8340 | ht_info->operating_mode = op_mode.op_mode; | ||
8341 | IWL_DEBUG_MAC80211("control channel %d\n", | ||
8342 | ht_extra->control_chan); | ||
8343 | } | ||
8344 | } else | ||
8345 | ht_info->is_ht = 0; | ||
8346 | |||
8347 | IWL_DEBUG_MAC80211("leave\n"); | 8274 | IWL_DEBUG_MAC80211("leave\n"); |
8348 | return 0; | ||
8349 | } | 8275 | } |
8350 | 8276 | ||
8351 | static int iwl4965_mac_conf_ht(struct ieee80211_hw *hw, | 8277 | static int iwl4965_mac_conf_ht(struct ieee80211_hw *hw, |
8352 | struct ieee80211_ht_capability *ht_cap, | 8278 | struct ieee80211_conf *conf) |
8353 | struct ieee80211_ht_additional_info *ht_extra) | ||
8354 | { | 8279 | { |
8355 | struct iwl4965_priv *priv = hw->priv; | 8280 | struct iwl4965_priv *priv = hw->priv; |
8356 | int rs; | ||
8357 | 8281 | ||
8358 | IWL_DEBUG_MAC80211("enter: \n"); | 8282 | IWL_DEBUG_MAC80211("enter: \n"); |
8359 | 8283 | ||
8360 | rs = sta_ht_info_init(ht_cap, ht_extra, NULL, &priv->current_assoc_ht); | 8284 | iwl4965_ht_info_fill(conf, priv); |
8361 | iwl4965_set_rxon_chain(priv); | 8285 | iwl4965_set_rxon_chain(priv); |
8362 | 8286 | ||
8363 | if (priv && priv->assoc_id && | 8287 | if (priv && priv->assoc_id && |
@@ -8372,10 +8296,8 @@ static int iwl4965_mac_conf_ht(struct ieee80211_hw *hw, | |||
8372 | spin_unlock_irqrestore(&priv->lock, flags); | 8296 | spin_unlock_irqrestore(&priv->lock, flags); |
8373 | } | 8297 | } |
8374 | 8298 | ||
8375 | IWL_DEBUG_MAC80211("leave: control channel %d\n", | 8299 | IWL_DEBUG_MAC80211("leave:\n"); |
8376 | ht_extra->control_chan); | 8300 | return 0; |
8377 | return rs; | ||
8378 | |||
8379 | } | 8301 | } |
8380 | 8302 | ||
8381 | static void iwl4965_set_ht_capab(struct ieee80211_hw *hw, | 8303 | static void iwl4965_set_ht_capab(struct ieee80211_hw *hw, |
@@ -8400,23 +8322,6 @@ static void iwl4965_set_ht_capab(struct ieee80211_hw *hw, | |||
8400 | IEEE80211_HT_CAP_AMPDU_DENSITY); | 8322 | IEEE80211_HT_CAP_AMPDU_DENSITY); |
8401 | } | 8323 | } |
8402 | 8324 | ||
8403 | static void iwl4965_mac_get_ht_capab(struct ieee80211_hw *hw, | ||
8404 | struct ieee80211_ht_capability *ht_cap) | ||
8405 | { | ||
8406 | u8 use_wide_channel = 1; | ||
8407 | struct iwl4965_priv *priv = hw->priv; | ||
8408 | |||
8409 | IWL_DEBUG_MAC80211("enter: \n"); | ||
8410 | if (priv->channel_width != IWL_CHANNEL_WIDTH_40MHZ) | ||
8411 | use_wide_channel = 0; | ||
8412 | |||
8413 | /* no fat tx allowed on 2.4GHZ */ | ||
8414 | if (priv->phymode != MODE_IEEE80211A) | ||
8415 | use_wide_channel = 0; | ||
8416 | |||
8417 | iwl4965_set_ht_capab(hw, ht_cap, use_wide_channel); | ||
8418 | IWL_DEBUG_MAC80211("leave: \n"); | ||
8419 | } | ||
8420 | #endif /*CONFIG_IWL4965_HT*/ | 8325 | #endif /*CONFIG_IWL4965_HT*/ |
8421 | 8326 | ||
8422 | /***************************************************************************** | 8327 | /***************************************************************************** |
@@ -9134,7 +9039,6 @@ static struct ieee80211_ops iwl4965_hw_ops = { | |||
9134 | .erp_ie_changed = iwl4965_mac_erp_ie_changed, | 9039 | .erp_ie_changed = iwl4965_mac_erp_ie_changed, |
9135 | #ifdef CONFIG_IWL4965_HT | 9040 | #ifdef CONFIG_IWL4965_HT |
9136 | .conf_ht = iwl4965_mac_conf_ht, | 9041 | .conf_ht = iwl4965_mac_conf_ht, |
9137 | .get_ht_capab = iwl4965_mac_get_ht_capab, | ||
9138 | #ifdef CONFIG_IWL4965_HT_AGG | 9042 | #ifdef CONFIG_IWL4965_HT_AGG |
9139 | .ht_tx_agg_start = iwl4965_mac_ht_tx_agg_start, | 9043 | .ht_tx_agg_start = iwl4965_mac_ht_tx_agg_start, |
9140 | .ht_tx_agg_stop = iwl4965_mac_ht_tx_agg_stop, | 9044 | .ht_tx_agg_stop = iwl4965_mac_ht_tx_agg_stop, |