diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c index 10c64bd..9f54cb1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c @@ -675,6 +675,11 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev, } rate_mask = sta->supp_rates[sband->band]; + if (!rate_mask) { + sel->rate_idx = rate_lowest_index(local, sband, NULL); + rcu_read_unlock(); + return; + } index = min(sta->last_txrate_idx & 0xffff, IWL_RATE_COUNT - 1); if (sband->band == IEEE80211_BAND_5GHZ) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index 90a2b6d..325a06e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c @@ -798,29 +798,33 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev, IWL_DEBUG_RATE_LIMIT("get frame ack response, update rate scale window\n"); + rcu_read_lock(); + + sta = sta_info_get(local, hdr->addr1); + if (!sta || !sta->rate_ctrl_priv) + goto out; + + lq_sta = (struct iwl_lq_sta *)sta->rate_ctrl_priv; + + /* user changed channel to different band return lowest rate + * in band + */ + if (lq_sta && lq_sta->band != priv->band) + goto out; + if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1)) - return; + goto out; /* This packet was aggregated but doesn't carry rate scale info */ if ((info->flags & IEEE80211_TX_CTL_AMPDU) && !(info->flags & IEEE80211_TX_STAT_AMPDU)) - return; + goto out; retries = info->status.retry_count; if (retries > 15) retries = 15; - rcu_read_lock(); - - sta = sta_info_get(local, hdr->addr1); - - if (!sta || !sta->rate_ctrl_priv) - goto out; - - - lq_sta = (struct iwl_lq_sta *)sta->rate_ctrl_priv; - if ((priv->iw_mode == IEEE80211_IF_TYPE_IBSS) && !lq_sta->ibss_sta_added) goto out; @@ -2089,24 +2093,35 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev, struct sta_info *sta; __le16 fc; struct iwl_priv *priv = (struct iwl_priv *)priv_rate; - struct iwl_lq_sta *lq_sta; + struct iwl_lq_sta *lq_sta = NULL; IWL_DEBUG_RATE_LIMIT("rate scale calculate new rate for skb\n"); rcu_read_lock(); sta = sta_info_get(local, hdr->addr1); + if (!sta) + goto skip; + + /* user changed channel to different band return lowest rate + * in band + */ + lq_sta = (struct iwl_lq_sta *)sta->rate_ctrl_priv; + if (lq_sta && lq_sta->band != priv->band) { + sel->rate_idx = rate_lowest_index(local, sband, NULL); + goto out; + } +skip: /* Send management frames and broadcast/multicast data using lowest * rate. */ fc = hdr->frame_control; if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1) || - !sta || !sta->rate_ctrl_priv) { + !sta || !lq_sta) { sel->rate_idx = rate_lowest_index(local, sband, sta); goto out; } - lq_sta = (struct iwl_lq_sta *)sta->rate_ctrl_priv; i = sta->last_txrate_idx; if ((priv->iw_mode == IEEE80211_IF_TYPE_IBSS) &&