Commit 67d62035 authored by Ron Rindjunsky's avatar Ron Rindjunsky Committed by David S. Miller

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: default avatarRon Rindjunsky <ron.rindjunsky@intel.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent fd105e79
...@@ -2023,8 +2023,8 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev, ...@@ -2023,8 +2023,8 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev,
if (sta_id == IWL_INVALID_STATION) { if (sta_id == IWL_INVALID_STATION) {
IWL_DEBUG_RATE("LQ: ADD station %s\n", IWL_DEBUG_RATE("LQ: ADD station %s\n",
print_mac(mac, hdr->addr1)); print_mac(mac, hdr->addr1));
sta_id = iwl4965_add_station_flags(priv, sta_id = iwl4965_add_station_flags(priv, hdr->addr1,
hdr->addr1, 0, CMD_ASYNC); 0, CMD_ASYNC, NULL);
} }
if ((sta_id != IWL_INVALID_STATION)) { if ((sta_id != IWL_INVALID_STATION)) {
lq->lq.sta_id = sta_id; lq->lq.sta_id = sta_id;
...@@ -2101,8 +2101,8 @@ static void rs_rate_init(void *priv_rate, void *priv_sta, ...@@ -2101,8 +2101,8 @@ static void rs_rate_init(void *priv_rate, void *priv_sta,
if (sta_id == IWL_INVALID_STATION) { if (sta_id == IWL_INVALID_STATION) {
IWL_DEBUG_RATE("LQ: ADD station %s\n", IWL_DEBUG_RATE("LQ: ADD station %s\n",
print_mac(mac, sta->addr)); print_mac(mac, sta->addr));
sta_id = iwl4965_add_station_flags(priv, sta_id = iwl4965_add_station_flags(priv, sta->addr,
sta->addr, 0, CMD_ASYNC); 0, CMD_ASYNC, NULL);
} }
if ((sta_id != IWL_INVALID_STATION)) { if ((sta_id != IWL_INVALID_STATION)) {
crl->lq.sta_id = sta_id; crl->lq.sta_id = sta_id;
......
...@@ -4617,39 +4617,33 @@ void iwl4965_set_rxon_ht(struct iwl4965_priv *priv, struct iwl_ht_info *ht_info) ...@@ -4617,39 +4617,33 @@ void iwl4965_set_rxon_ht(struct iwl4965_priv *priv, struct iwl_ht_info *ht_info)
return; 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; __le32 sta_flags;
struct sta_ht_info *ht_info = &priv->current_assoc_ht;
priv->current_channel_width = IWL_CHANNEL_WIDTH_20MHZ; if (!sta_ht_inf || !sta_ht_inf->ht_supported)
if (!ht_info->is_ht)
goto done; goto done;
sta_flags = priv->stations[index].sta.station_flags; 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; sta_flags |= STA_FLG_RTS_MIMO_PROT_MSK;
else else
sta_flags &= ~STA_FLG_RTS_MIMO_PROT_MSK; sta_flags &= ~STA_FLG_RTS_MIMO_PROT_MSK;
sta_flags |= cpu_to_le32( 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( sta_flags |= cpu_to_le32(
(u32)ht_info->mpdu_density << STA_FLG_AGG_MPDU_DENSITY_POS); (u32)sta_ht_inf->ampdu_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;
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; sta_flags |= STA_FLG_FAT_EN_MSK;
ht_info->chan_width_cap = IWL_CHANNEL_WIDTH_40MHZ; else
if (ht_info->supported_chan_width == IWL_CHANNEL_WIDTH_40MHZ) sta_flags &= (~STA_FLG_FAT_EN_MSK);
ht_info->tx_chan_width = IWL_CHANNEL_WIDTH_40MHZ;
}
priv->current_channel_width = ht_info->tx_chan_width;
priv->stations[index].sta.station_flags = sta_flags; priv->stations[index].sta.station_flags = sta_flags;
done: done:
return; return;
......
...@@ -649,8 +649,8 @@ struct iwl4965_driver_hw_info { ...@@ -649,8 +649,8 @@ struct iwl4965_driver_hw_info {
struct iwl4965_addsta_cmd; struct iwl4965_addsta_cmd;
extern int iwl4965_send_add_station(struct iwl4965_priv *priv, extern int iwl4965_send_add_station(struct iwl4965_priv *priv,
struct iwl4965_addsta_cmd *sta, u8 flags); struct iwl4965_addsta_cmd *sta, u8 flags);
extern u8 iwl4965_add_station_flags(struct iwl4965_priv *priv, const u8 *bssid, extern u8 iwl4965_add_station_flags(struct iwl4965_priv *priv, const u8 *addr,
int is_ap, u8 flags); int is_ap, u8 flags, void *ht_data);
extern int iwl4965_is_network_packet(struct iwl4965_priv *priv, extern int iwl4965_is_network_packet(struct iwl4965_priv *priv,
struct ieee80211_hdr *header); struct ieee80211_hdr *header);
extern int iwl4965_power_init_handle(struct iwl4965_priv *priv); 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 ...@@ -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); struct ieee80211_tx_control *ctrl, void *sta_in);
extern int iwl4965_alive_notify(struct iwl4965_priv *priv); extern int iwl4965_alive_notify(struct iwl4965_priv *priv);
extern void iwl4965_update_rate_scaling(struct iwl4965_priv *priv, u8 mode); 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_chain_noise_reset(struct iwl4965_priv *priv);
extern void iwl4965_init_sensitivity(struct iwl4965_priv *priv, u8 flags, extern void iwl4965_init_sensitivity(struct iwl4965_priv *priv, u8 flags,
u8 force); u8 force);
...@@ -801,6 +799,8 @@ extern void iwl4965_init_ht_hw_capab(struct ieee80211_ht_info *ht_info, ...@@ -801,6 +799,8 @@ extern void iwl4965_init_ht_hw_capab(struct ieee80211_ht_info *ht_info,
int mode); int mode);
extern void iwl4965_set_rxon_ht(struct iwl4965_priv *priv, extern void iwl4965_set_rxon_ht(struct iwl4965_priv *priv,
struct iwl_ht_info *ht_info); 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 #ifdef CONFIG_IWL4965_HT_AGG
extern int iwl4965_mac_ht_tx_agg_start(struct ieee80211_hw *hw, u8 *da, extern int iwl4965_mac_ht_tx_agg_start(struct ieee80211_hw *hw, u8 *da,
u16 tid, u16 *start_seq_num); u16 tid, u16 *start_seq_num);
......
...@@ -497,7 +497,8 @@ static void iwl4965_clear_stations_table(struct iwl4965_priv *priv) ...@@ -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 * 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 i;
int index = IWL_INVALID_STATION; int index = IWL_INVALID_STATION;
...@@ -554,7 +555,8 @@ u8 iwl4965_add_station_flags(struct iwl4965_priv *priv, const u8 *addr, int is_a ...@@ -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 */ /* BCAST station and IBSS stations do not work in HT mode */
if (index != priv->hw_setting.bcast_sta_id && if (index != priv->hw_setting.bcast_sta_id &&
priv->iw_mode != IEEE80211_IF_TYPE_IBSS) 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*/ #endif /*CONFIG_IWL4965_HT*/
spin_unlock_irqrestore(&priv->sta_lock, flags_spin); spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
...@@ -900,7 +902,19 @@ static int iwl4965_rxon_add_station(struct iwl4965_priv *priv, ...@@ -900,7 +902,19 @@ static int iwl4965_rxon_add_station(struct iwl4965_priv *priv,
u8 sta_id; u8 sta_id;
/* Add station to device's station table */ /* 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 */ /* Set up default rate scaling table in device's station table */
iwl4965_add_station(priv, addr, is_ap); iwl4965_add_station(priv, addr, is_ap);
...@@ -2834,7 +2848,8 @@ static int iwl4965_get_sta_id(struct iwl4965_priv *priv, ...@@ -2834,7 +2848,8 @@ static int iwl4965_get_sta_id(struct iwl4965_priv *priv,
return sta_id; return sta_id;
/* Create new station table entry */ /* 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) if (sta_id != IWL_INVALID_STATION)
return sta_id; return sta_id;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment