]> 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 136c29067489ebbadbe9ec25593285cd973ea20a..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,60 @@ 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) {
+               return IWL_AP_ID;
+       } else {
+               u8 *da = ieee80211_get_DA(hdr);
+               return iwl_find_station(priv, da);
+       }
+}
+
 /**
  * iwl4965_rx_reply_tx - Handle standard (non-aggregation) Tx response
  */
@@ -1972,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 "
@@ -1996,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;
@@ -2056,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,
@@ -2112,34 +2172,6 @@ static void iwl4965_cancel_deferred_work(struct iwl_priv *priv)
        cancel_work_sync(&priv->txpower_work);
 }
 
-#define IWL4965_UCODE_GET(item)                                                \
-static u32 iwl4965_ucode_get_##item(const struct iwl_ucode_header *ucode,\
-                                   u32 api_ver)                        \
-{                                                                      \
-       return le32_to_cpu(ucode->u.v1.item);                           \
-}
-
-static u32 iwl4965_ucode_get_header_size(u32 api_ver)
-{
-       return UCODE_HEADER_SIZE(1);
-}
-static u32 iwl4965_ucode_get_build(const struct iwl_ucode_header *ucode,
-                                  u32 api_ver)
-{
-       return 0;
-}
-static u8 *iwl4965_ucode_get_data(const struct iwl_ucode_header *ucode,
-                                 u32 api_ver)
-{
-       return (u8 *) ucode->u.v1.data;
-}
-
-IWL4965_UCODE_GET(inst_size);
-IWL4965_UCODE_GET(data_size);
-IWL4965_UCODE_GET(init_size);
-IWL4965_UCODE_GET(init_data_size);
-IWL4965_UCODE_GET(boot_size);
-
 static struct iwl_hcmd_ops iwl4965_hcmd = {
        .rxon_assoc = iwl4965_send_rxon_assoc,
        .commit_rxon = iwl_commit_rxon,
@@ -2147,16 +2179,6 @@ static struct iwl_hcmd_ops iwl4965_hcmd = {
        .send_bt_config = iwl_send_bt_config,
 };
 
-static struct iwl_ucode_ops iwl4965_ucode = {
-       .get_header_size = iwl4965_ucode_get_header_size,
-       .get_build = iwl4965_ucode_get_build,
-       .get_inst_size = iwl4965_ucode_get_inst_size,
-       .get_data_size = iwl4965_ucode_get_data_size,
-       .get_init_size = iwl4965_ucode_get_init_size,
-       .get_init_data_size = iwl4965_ucode_get_init_data_size,
-       .get_boot_size = iwl4965_ucode_get_boot_size,
-       .get_data = iwl4965_ucode_get_data,
-};
 static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = {
        .get_hcmd_size = iwl4965_get_hcmd_size,
        .build_addsta_hcmd = iwl4965_build_addsta_hcmd,
@@ -2218,7 +2240,7 @@ static struct iwl_lib_ops iwl4965_lib = {
                .temperature = iwl4965_temperature_calib,
                .set_ct_kill = iwl4965_set_ct_threshold,
        },
-       .add_bcast_station = iwl_add_bcast_station,
+       .manage_ibss_station = iwlagn_manage_ibss_station,
        .debugfs_ops = {
                .rx_stats_read = iwl_ucode_rx_stats_read,
                .tx_stats_read = iwl_ucode_tx_stats_read,
@@ -2228,7 +2250,6 @@ static struct iwl_lib_ops iwl4965_lib = {
 };
 
 static const struct iwl_ops iwl4965_ops = {
-       .ucode = &iwl4965_ucode,
        .lib = &iwl4965_lib,
        .hcmd = &iwl4965_hcmd,
        .utils = &iwl4965_hcmd_utils,
@@ -2262,7 +2283,10 @@ struct iwl_cfg iwl4965_agn_cfg = {
        .monitor_recover_period = IWL_MONITORING_PERIOD,
        .temperature_kelvin = true,
        .max_event_log_size = 512,
-
+       .tx_power_by_driver = true,
+       .ucode_tracing = true,
+       .sensitivity_calib_by_driver = true,
+       .chain_noise_calib_by_driver = true,
        /*
         * Force use of chains B and C for scan RX on 5 GHz band
         * because the device has off-channel reception on chain A.