]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/net/wireless/iwlwifi/iwl-agn-rs.c
Merge master.kernel.org:/home/rmk/linux-2.6-arm
[linux-2.6-omap-h63xx.git] / drivers / net / wireless / iwlwifi / iwl-agn-rs.c
index 0332805cc6306e9d06ea101ad9b1d866a2db0863..27f50471aed8fd0f4e0349975705b6b06c9e9066 100644 (file)
@@ -19,7 +19,7 @@
  * file called LICENSE.
  *
  * Contact Information:
- * James P. Ketrenos <ipw2100-admin@linux.intel.com>
+ *  Intel Linux Wireless <ilw@linux.intel.com>
  * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
  *
  *****************************************************************************/
@@ -38,7 +38,6 @@
 #include "iwl-dev.h"
 #include "iwl-sta.h"
 #include "iwl-core.h"
-#include "iwl-helpers.h"
 
 #define RS_NAME "iwl-agn-rs"
 
@@ -281,10 +280,9 @@ static u8 rs_tl_add_packet(struct iwl_lq_sta *lq_data,
        u32 time_diff;
        s32 index;
        struct iwl_traffic_load *tl = NULL;
-       __le16 fc = hdr->frame_control;
        u8 tid;
 
-       if (ieee80211_is_data_qos(fc)) {
+       if (ieee80211_is_data_qos(hdr->frame_control)) {
                u8 *qc = ieee80211_get_qos_ctl(hdr);
                tid = qc[0] & 0xf;
        } else
@@ -773,7 +771,7 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
        int status;
        u8 retries;
        int rs_index, index = 0;
-       struct iwl_lq_sta *lq_sta;
+       struct iwl_lq_sta *lq_sta = priv_sta;
        struct iwl_link_quality_cmd *table;
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
        struct iwl_priv *priv = (struct iwl_priv *)priv_r;
@@ -785,12 +783,12 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
        struct iwl_scale_tbl_info tbl_type;
        struct iwl_scale_tbl_info *curr_tbl, *search_tbl;
        u8 active_index = 0;
-       __le16 fc = hdr->frame_control;
        s32 tpt = 0;
 
        IWL_DEBUG_RATE_LIMIT("get frame ack response, update rate scale window\n");
 
-       if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1))
+       if (!ieee80211_is_data(hdr->frame_control) ||
+           is_multicast_ether_addr(hdr->addr1))
                return;
 
        /* This packet was aggregated but doesn't carry rate scale info */
@@ -803,8 +801,6 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
        if (retries > 15)
                retries = 15;
 
-       lq_sta = (struct iwl_lq_sta *)priv_sta;
-
        if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) &&
            !lq_sta->ibss_sta_added)
                goto out;
@@ -840,6 +836,10 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
            (hw->wiphy->bands[priv->band]->bitrates[rs_index].bitrate !=
             hw->wiphy->bands[info->band]->bitrates[info->status.rates[0].idx].bitrate)) {
                IWL_DEBUG_RATE("initial rate does not match 0x%x\n", tx_rate);
+               /* the last LQ command could failed so the LQ in ucode not
+                * the same in driver sync up
+                */
+               iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC);
                goto out;
        }
 
@@ -944,7 +944,8 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
        }
 
        /* See if there's a better rate or modulation mode to try. */
-       rs_rate_scale_perform(priv, hdr, sta, lq_sta);
+       if (sta && sta->supp_rates[sband->band])
+               rs_rate_scale_perform(priv, hdr, sta, lq_sta);
 out:
        return;
 }
@@ -1675,7 +1676,6 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
        int high_tpt = IWL_INVALID_VALUE;
        u32 fail_count;
        s8 scale_action = 0;
-       __le16 fc;
        u16 rate_mask;
        u8 update_lq = 0;
        struct iwl_scale_tbl_info *tbl, *tbl1;
@@ -1690,13 +1690,12 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
 
        IWL_DEBUG_RATE("rate scale calculate new rate for skb\n");
 
-       fc = hdr->frame_control;
-       if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1)) {
-               /* Send management frames and broadcast/multicast data using
-                * lowest rate. */
-               /* TODO: this could probably be improved.. */
+       /* Send management frames and broadcast/multicast data using
+        * lowest rate. */
+       /* TODO: this could probably be improved.. */
+       if (!ieee80211_is_data(hdr->frame_control) ||
+           is_multicast_ether_addr(hdr->addr1))
                return;
-       }
 
        if (!sta || !lq_sta)
                return;
@@ -2095,29 +2094,35 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta,
                        struct ieee80211_tx_rate_control *txrc)
 {
 
-       int i;
        struct sk_buff *skb = txrc->skb;
        struct ieee80211_supported_band *sband = txrc->sband;
        struct iwl_priv *priv = (struct iwl_priv *)priv_r;
        struct ieee80211_conf *conf = &priv->hw->conf;
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-       __le16 fc;
-       struct iwl_lq_sta *lq_sta;
+       struct iwl_lq_sta *lq_sta = priv_sta;
+       int rate_idx;
+       u64 mask_bit = 0;
 
        IWL_DEBUG_RATE_LIMIT("rate scale calculate new rate for skb\n");
 
+       if (sta)
+               mask_bit = sta->supp_rates[sband->band];
+
        /* 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 || !priv_sta) {
-               info->control.rates[0].idx = rate_lowest_index(sband, sta);
+       if (!ieee80211_is_data(hdr->frame_control) ||
+           is_multicast_ether_addr(hdr->addr1) || !sta || !lq_sta) {
+               if (!mask_bit)
+                       info->control.rates[0].idx =
+                                       rate_lowest_index(sband, NULL);
+               else
+                       info->control.rates[0].idx =
+                                       rate_lowest_index(sband, sta);
                return;
        }
 
-       lq_sta = (struct iwl_lq_sta *)priv_sta;
-       i = lq_sta->last_txrate_idx;
+       rate_idx  = lq_sta->last_txrate_idx;
 
        if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) &&
            !lq_sta->ibss_sta_added) {
@@ -2137,14 +2142,12 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta,
                }
        }
 
-       if ((i < 0) || (i > IWL_RATE_COUNT)) {
-               info->control.rates[0].idx = rate_lowest_index(sband, sta);
-               return;
-       }
+       if (rate_idx < 0 || rate_idx > IWL_RATE_COUNT)
+               rate_idx = rate_lowest_index(sband, sta);
+       else if (sband->band == IEEE80211_BAND_5GHZ)
+               rate_idx -= IWL_FIRST_OFDM_RATE;
 
-       if (sband->band == IEEE80211_BAND_5GHZ)
-               i -= IWL_FIRST_OFDM_RATE;
-       info->control.rates[0].idx = i;
+       info->control.rates[0].idx = rate_idx;
 }
 
 static void *rs_alloc_sta(void *priv_rate, struct ieee80211_sta *sta,
@@ -2178,6 +2181,7 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
        struct iwl_priv *priv = (struct iwl_priv *)priv_r;
        struct ieee80211_conf *conf = &priv->hw->conf;
        struct iwl_lq_sta *lq_sta = priv_sta;
+       u16 mask_bit = 0;
 
        lq_sta->flush_timer = 0;
        lq_sta->supp_rates = sta->supp_rates[sband->band];
@@ -2211,16 +2215,6 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
                priv->assoc_station_added = 1;
        }
 
-       /* Find highest tx rate supported by hardware and destination station */
-       lq_sta->last_txrate_idx = 3;
-       for (i = 0; i < sband->n_bitrates; i++)
-               if (sta->supp_rates[sband->band] & BIT(i))
-                       lq_sta->last_txrate_idx = i;
-
-       /* For MODE_IEEE80211A, skip over cck rates in global rate table */
-       if (sband->band == IEEE80211_BAND_5GHZ)
-               lq_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE;
-
        lq_sta->is_dup = 0;
        lq_sta->is_green = rs_use_green(priv, conf);
        lq_sta->active_legacy_rate = priv->active_rate & ~(0x1000);
@@ -2259,6 +2253,17 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
        lq_sta->tx_agg_tid_en = IWL_AGG_ALL_TID;
        lq_sta->drv = priv;
 
+       /* Find highest tx rate supported by hardware and destination station */
+       mask_bit = sta->supp_rates[sband->band] & lq_sta->active_legacy_rate;
+       lq_sta->last_txrate_idx = 3;
+       for (i = 0; i < sband->n_bitrates; i++)
+               if (mask_bit & BIT(i))
+                       lq_sta->last_txrate_idx = i;
+
+       /* For MODE_IEEE80211A, skip over cck rates in global rate table */
+       if (sband->band == IEEE80211_BAND_5GHZ)
+               lq_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE;
+
        rs_initialize_lq(priv, conf, sta, lq_sta);
 }
 
@@ -2525,7 +2530,7 @@ static ssize_t rs_sta_dbgfs_stats_table_read(struct file *file,
        for (i = 0; i < LQ_SIZE; i++) {
                desc += sprintf(buff+desc, "%s type=%d SGI=%d FAT=%d DUP=%d\n"
                                "rate=0x%X\n",
-                               lq_sta->active_tbl == i?"*":"x",
+                               lq_sta->active_tbl == i ? "*" : "x",
                                lq_sta->lq_info[i].lq_type,
                                lq_sta->lq_info[i].is_SGI,
                                lq_sta->lq_info[i].is_fat,