]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/net/wireless/iwlwifi/iwl-4965.c
iwlwifi: do not clear data after chain noise calib
[karo-tx-linux.git] / drivers / net / wireless / iwlwifi / iwl-4965.c
index 93893aec6cc488ec679e0192ef4c74e8568963c4..a0669ea427909cf431fbb56f549994a237ebf473 100644 (file)
@@ -346,9 +346,19 @@ static void iwl4965_chain_noise_reset(struct iwl_priv *priv)
 {
        struct iwl_chain_noise_data *data = &(priv->chain_noise_data);
 
-       if ((data->state == IWL_CHAIN_NOISE_ALIVE) && iwl_is_associated(priv)) {
+       if ((data->state == IWL_CHAIN_NOISE_ALIVE) &&
+            iwl_is_associated(priv)) {
                struct iwl_calib_diff_gain_cmd cmd;
 
+               /* clear data for chain noise calibration algorithm */
+               data->chain_noise_a = 0;
+               data->chain_noise_b = 0;
+               data->chain_noise_c = 0;
+               data->chain_signal_a = 0;
+               data->chain_signal_b = 0;
+               data->chain_signal_c = 0;
+               data->beacon_count = 0;
+
                memset(&cmd, 0, sizeof(cmd));
                cmd.hdr.op_code = IWL_PHY_CALIBRATE_DIFF_GAIN_CMD;
                cmd.diff_gain_a = 0;
@@ -419,13 +429,6 @@ static void iwl4965_gain_computation(struct iwl_priv *priv,
                /* Mark so we run this algo only once! */
                data->state = IWL_CHAIN_NOISE_CALIBRATED;
        }
-       data->chain_noise_a = 0;
-       data->chain_noise_b = 0;
-       data->chain_noise_c = 0;
-       data->chain_signal_a = 0;
-       data->chain_signal_b = 0;
-       data->chain_signal_c = 0;
-       data->beacon_count = 0;
 }
 
 static void iwl4965_bg_txpower_work(struct work_struct *work)
@@ -1953,6 +1956,50 @@ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv,
        return 0;
 }
 
+static u8 iwl_find_station(struct iwl_priv *priv, const u8 *addr)
+{
+       int i;
+       int start = 0;
+       int ret = IWL_INVALID_STATION;
+       unsigned long flags;
+
+       if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) ||
+           (priv->iw_mode == NL80211_IFTYPE_AP))
+               start = IWL_STA_ID;
+
+       if (is_broadcast_ether_addr(addr))
+               return priv->hw_params.bcast_sta_id;
+
+       spin_lock_irqsave(&priv->sta_lock, flags);
+       for (i = start; i < priv->hw_params.max_stations; i++)
+               if (priv->stations[i].used &&
+                   (!compare_ether_addr(priv->stations[i].sta.sta.addr,
+                                        addr))) {
+                       ret = i;
+                       goto out;
+               }
+
+       IWL_DEBUG_ASSOC_LIMIT(priv, "can not find STA %pM total %d\n",
+                             addr, priv->num_stations);
+
+ out:
+       /*
+        * It may be possible that more commands interacting with stations
+        * arrive before we completed processing the adding of
+        * station
+        */
+       if (ret != IWL_INVALID_STATION &&
+           (!(priv->stations[ret].used & IWL_STA_UCODE_ACTIVE) ||
+            ((priv->stations[ret].used & IWL_STA_UCODE_ACTIVE) &&
+             (priv->stations[ret].used & IWL_STA_UCODE_INPROGRESS)))) {
+               IWL_ERR(priv, "Requested station info for sta %d before ready.\n",
+                       ret);
+               ret = IWL_INVALID_STATION;
+       }
+       spin_unlock_irqrestore(&priv->sta_lock, flags);
+       return ret;
+}
+
 static int iwl_get_ra_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)
 {
        if (priv->iw_mode == NL80211_IFTYPE_STATION) {
@@ -1982,6 +2029,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
        int sta_id;
        int freed;
        u8 *qc = NULL;
+       unsigned long flags;
 
        if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) {
                IWL_ERR(priv, "Read index for DMA queue txq_id (%d) index %d "
@@ -2006,10 +2054,10 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
                return;
        }
 
+       spin_lock_irqsave(&priv->sta_lock, flags);
        if (txq->sched_retry) {
                const u32 scd_ssn = iwl4965_get_scd_ssn(tx_resp);
                struct iwl_ht_agg *agg = NULL;
-
                WARN_ON(!qc);
 
                agg = &priv->stations[sta_id].tid[tid].agg;
@@ -2066,6 +2114,8 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
                iwlagn_txq_check_empty(priv, sta_id, tid, txq_id);
 
        iwl_check_abort_status(priv, tx_resp->frame_count, status);
+
+       spin_unlock_irqrestore(&priv->sta_lock, flags);
 }
 
 static int iwl4965_calc_rssi(struct iwl_priv *priv,