From 67d620357a186adc0f4e7d1f5b095ea2c77e7072 Mon Sep 17 00:00:00 2001 From: Ron Rindjunsky Date: Mon, 26 Nov 2007 16:14:40 +0200 Subject: [PATCH] iwlwifi: 802.11n comply HT add station flow with mac80211 framework This patch conforms the addition of a new station to the iwlwifi station table according to the new mac80211's HT framework Signed-off-by: Ron Rindjunsky Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-4965-rs.c | 8 +++--- drivers/net/wireless/iwlwifi/iwl-4965.c | 28 ++++++++------------- drivers/net/wireless/iwlwifi/iwl-4965.h | 8 +++--- drivers/net/wireless/iwlwifi/iwl4965-base.c | 23 ++++++++++++++--- 4 files changed, 38 insertions(+), 29 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c index b4edadf96e..503b917451 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c @@ -2023,8 +2023,8 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev, if (sta_id == IWL_INVALID_STATION) { IWL_DEBUG_RATE("LQ: ADD station %s\n", print_mac(mac, hdr->addr1)); - sta_id = iwl4965_add_station_flags(priv, - hdr->addr1, 0, CMD_ASYNC); + sta_id = iwl4965_add_station_flags(priv, hdr->addr1, + 0, CMD_ASYNC, NULL); } if ((sta_id != IWL_INVALID_STATION)) { lq->lq.sta_id = sta_id; @@ -2101,8 +2101,8 @@ static void rs_rate_init(void *priv_rate, void *priv_sta, if (sta_id == IWL_INVALID_STATION) { IWL_DEBUG_RATE("LQ: ADD station %s\n", print_mac(mac, sta->addr)); - sta_id = iwl4965_add_station_flags(priv, - sta->addr, 0, CMD_ASYNC); + sta_id = iwl4965_add_station_flags(priv, sta->addr, + 0, CMD_ASYNC, NULL); } if ((sta_id != IWL_INVALID_STATION)) { crl->lq.sta_id = sta_id; diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 2724208aca..55d61000e3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -4617,39 +4617,33 @@ void iwl4965_set_rxon_ht(struct iwl4965_priv *priv, struct iwl_ht_info *ht_info) return; } -void iwl4965_set_ht_add_station(struct iwl4965_priv *priv, u8 index) +void iwl4965_set_ht_add_station(struct iwl4965_priv *priv, u8 index, + struct ieee80211_ht_info *sta_ht_inf) { __le32 sta_flags; - struct sta_ht_info *ht_info = &priv->current_assoc_ht; - priv->current_channel_width = IWL_CHANNEL_WIDTH_20MHZ; - if (!ht_info->is_ht) + if (!sta_ht_inf || !sta_ht_inf->ht_supported) goto done; sta_flags = priv->stations[index].sta.station_flags; - if (ht_info->tx_mimo_ps_mode == IWL_MIMO_PS_DYNAMIC) + if (((sta_ht_inf->cap & IEEE80211_HT_CAP_MIMO_PS >> 2)) + == IWL_MIMO_PS_DYNAMIC) sta_flags |= STA_FLG_RTS_MIMO_PROT_MSK; else sta_flags &= ~STA_FLG_RTS_MIMO_PROT_MSK; sta_flags |= cpu_to_le32( - (u32)ht_info->ampdu_factor << STA_FLG_MAX_AGG_SIZE_POS); + (u32)sta_ht_inf->ampdu_factor << STA_FLG_MAX_AGG_SIZE_POS); sta_flags |= cpu_to_le32( - (u32)ht_info->mpdu_density << STA_FLG_AGG_MPDU_DENSITY_POS); - - sta_flags &= (~STA_FLG_FAT_EN_MSK); - ht_info->tx_chan_width = IWL_CHANNEL_WIDTH_20MHZ; - ht_info->chan_width_cap = IWL_CHANNEL_WIDTH_20MHZ; + (u32)sta_ht_inf->ampdu_density << STA_FLG_AGG_MPDU_DENSITY_POS); - if (iwl4965_is_fat_tx_allowed(priv, ht_info)) { + if (iwl4965_is_fat_tx_allowed(priv, sta_ht_inf)) sta_flags |= STA_FLG_FAT_EN_MSK; - ht_info->chan_width_cap = IWL_CHANNEL_WIDTH_40MHZ; - if (ht_info->supported_chan_width == IWL_CHANNEL_WIDTH_40MHZ) - ht_info->tx_chan_width = IWL_CHANNEL_WIDTH_40MHZ; - } - priv->current_channel_width = ht_info->tx_chan_width; + else + sta_flags &= (~STA_FLG_FAT_EN_MSK); + priv->stations[index].sta.station_flags = sta_flags; done: return; diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.h b/drivers/net/wireless/iwlwifi/iwl-4965.h index 6fdfb4a3be..50209e6cdd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.h +++ b/drivers/net/wireless/iwlwifi/iwl-4965.h @@ -649,8 +649,8 @@ struct iwl4965_driver_hw_info { struct iwl4965_addsta_cmd; extern int iwl4965_send_add_station(struct iwl4965_priv *priv, struct iwl4965_addsta_cmd *sta, u8 flags); -extern u8 iwl4965_add_station_flags(struct iwl4965_priv *priv, const u8 *bssid, - int is_ap, u8 flags); +extern u8 iwl4965_add_station_flags(struct iwl4965_priv *priv, const u8 *addr, + int is_ap, u8 flags, void *ht_data); extern int iwl4965_is_network_packet(struct iwl4965_priv *priv, struct ieee80211_hdr *header); extern int iwl4965_power_init_handle(struct iwl4965_priv *priv); @@ -785,8 +785,6 @@ extern int iwl4965_tx_cmd(struct iwl4965_priv *priv, struct iwl4965_cmd *out_cmd struct ieee80211_tx_control *ctrl, void *sta_in); extern int iwl4965_alive_notify(struct iwl4965_priv *priv); extern void iwl4965_update_rate_scaling(struct iwl4965_priv *priv, u8 mode); -extern void iwl4965_set_ht_add_station(struct iwl4965_priv *priv, u8 index); - extern void iwl4965_chain_noise_reset(struct iwl4965_priv *priv); extern void iwl4965_init_sensitivity(struct iwl4965_priv *priv, u8 flags, u8 force); @@ -801,6 +799,8 @@ extern void iwl4965_init_ht_hw_capab(struct ieee80211_ht_info *ht_info, int mode); extern void iwl4965_set_rxon_ht(struct iwl4965_priv *priv, struct iwl_ht_info *ht_info); +extern void iwl4965_set_ht_add_station(struct iwl4965_priv *priv, u8 index, + struct ieee80211_ht_info *sta_ht_inf); #ifdef CONFIG_IWL4965_HT_AGG extern int iwl4965_mac_ht_tx_agg_start(struct ieee80211_hw *hw, u8 *da, u16 tid, u16 *start_seq_num); diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index 2c706395e0..9f89f59628 100644 --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c @@ -497,7 +497,8 @@ static void iwl4965_clear_stations_table(struct iwl4965_priv *priv) /** * iwl4965_add_station_flags - Add station to tables in driver and device */ -u8 iwl4965_add_station_flags(struct iwl4965_priv *priv, const u8 *addr, int is_ap, u8 flags) +u8 iwl4965_add_station_flags(struct iwl4965_priv *priv, const u8 *addr, + int is_ap, u8 flags, void *ht_data) { int i; int index = IWL_INVALID_STATION; @@ -554,7 +555,8 @@ u8 iwl4965_add_station_flags(struct iwl4965_priv *priv, const u8 *addr, int is_a /* BCAST station and IBSS stations do not work in HT mode */ if (index != priv->hw_setting.bcast_sta_id && priv->iw_mode != IEEE80211_IF_TYPE_IBSS) - iwl4965_set_ht_add_station(priv, index); + iwl4965_set_ht_add_station(priv, index, + (struct ieee80211_ht_info *) ht_data); #endif /*CONFIG_IWL4965_HT*/ spin_unlock_irqrestore(&priv->sta_lock, flags_spin); @@ -900,7 +902,19 @@ static int iwl4965_rxon_add_station(struct iwl4965_priv *priv, u8 sta_id; /* Add station to device's station table */ - sta_id = iwl4965_add_station_flags(priv, addr, is_ap, 0); +#ifdef CONFIG_IWL4965_HT + struct ieee80211_conf *conf = &priv->hw->conf; + struct ieee80211_ht_info *cur_ht_config = &conf->ht_conf; + + if ((is_ap) && + (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) && + (priv->iw_mode == IEEE80211_IF_TYPE_STA)) + sta_id = iwl4965_add_station_flags(priv, addr, is_ap, + 0, cur_ht_config); + else +#endif /* CONFIG_IWL4965_HT */ + sta_id = iwl4965_add_station_flags(priv, addr, is_ap, + 0, NULL); /* Set up default rate scaling table in device's station table */ iwl4965_add_station(priv, addr, is_ap); @@ -2834,7 +2848,8 @@ static int iwl4965_get_sta_id(struct iwl4965_priv *priv, return sta_id; /* Create new station table entry */ - sta_id = iwl4965_add_station_flags(priv, hdr->addr1, 0, CMD_ASYNC); + sta_id = iwl4965_add_station_flags(priv, hdr->addr1, + 0, CMD_ASYNC, NULL); if (sta_id != IWL_INVALID_STATION) return sta_id; -- 2.39.5