- patches.arch/x86_mce_intel_decode_physical_address.patch:
[linux-flexiantxendom0-3.2.10.git] / drivers / net / wireless / iwlwifi / iwl-4965.c
index 8972166..d3afdda 100644 (file)
@@ -46,6 +46,8 @@
 #include "iwl-calib.h"
 #include "iwl-sta.h"
 #include "iwl-agn-led.h"
+#include "iwl-agn.h"
+#include "iwl-agn-debugfs.h"
 
 static int iwl4965_send_tx_power(struct iwl_priv *priv);
 static int iwl4965_hw_get_temperature(struct iwl_priv *priv);
@@ -60,14 +62,6 @@ static int iwl4965_hw_get_temperature(struct iwl_priv *priv);
 #define _IWL4965_MODULE_FIRMWARE(api) IWL4965_FW_PRE #api ".ucode"
 #define IWL4965_MODULE_FIRMWARE(api) _IWL4965_MODULE_FIRMWARE(api)
 
-
-/* module parameters */
-static struct iwl_mod_params iwl4965_mod_params = {
-       .amsdu_size_8K = 1,
-       .restart_fw = 1,
-       /* the rest are 0 by default */
-};
-
 /* check contents of special bootstrap uCode SRAM */
 static int iwl4965_verify_bsm(struct iwl_priv *priv)
 {
@@ -417,7 +411,7 @@ static void iwl4965_gain_computation(struct iwl_priv *priv,
                                      sizeof(cmd), &cmd);
                if (ret)
                        IWL_DEBUG_CALIB(priv, "fail sending cmd "
-                                    "REPLY_PHY_CALIBRATION_CMD \n");
+                                    "REPLY_PHY_CALIBRATION_CMD\n");
 
                /* TODO we might want recalculate
                 * rx_chain in rxon cmd */
@@ -502,14 +496,14 @@ static void iwl4965_tx_queue_set_status(struct iwl_priv *priv,
                       scd_retry ? "BA" : "AC", txq_id, tx_fifo_id);
 }
 
-static const u16 default_queue_to_tx_fifo[] = {
-       IWL_TX_FIFO_AC3,
-       IWL_TX_FIFO_AC2,
-       IWL_TX_FIFO_AC1,
-       IWL_TX_FIFO_AC0,
+static const s8 default_queue_to_tx_fifo[] = {
+       IWL_TX_FIFO_VO,
+       IWL_TX_FIFO_VI,
+       IWL_TX_FIFO_BE,
+       IWL_TX_FIFO_BK,
        IWL49_CMD_FIFO_NUM,
-       IWL_TX_FIFO_HCCA_1,
-       IWL_TX_FIFO_HCCA_2
+       IWL_TX_FIFO_UNUSED,
+       IWL_TX_FIFO_UNUSED,
 };
 
 static int iwl4965_alive_notify(struct iwl_priv *priv)
@@ -589,9 +583,15 @@ static int iwl4965_alive_notify(struct iwl_priv *priv)
        /* reset to 0 to enable all the queue first */
        priv->txq_ctx_active_msk = 0;
        /* Map each Tx/cmd queue to its corresponding fifo */
+       BUILD_BUG_ON(ARRAY_SIZE(default_queue_to_tx_fifo) != 7);
        for (i = 0; i < ARRAY_SIZE(default_queue_to_tx_fifo); i++) {
                int ac = default_queue_to_tx_fifo[i];
+
                iwl_txq_ctx_activate(priv, i);
+
+               if (ac == IWL_TX_FIFO_UNUSED)
+                       continue;
+
                iwl4965_tx_queue_set_status(priv, &priv->txq[i], ac, 0);
        }
 
@@ -1613,19 +1613,19 @@ static int iwl4965_is_temp_calib_needed(struct iwl_priv *priv)
 
        /* get absolute value */
        if (temp_diff < 0) {
-               IWL_DEBUG_POWER(priv, "Getting cooler, delta %d, \n", temp_diff);
+               IWL_DEBUG_POWER(priv, "Getting cooler, delta %d\n", temp_diff);
                temp_diff = -temp_diff;
        } else if (temp_diff == 0)
-               IWL_DEBUG_POWER(priv, "Same temp, \n");
+               IWL_DEBUG_POWER(priv, "Temperature unchanged\n");
        else
-               IWL_DEBUG_POWER(priv, "Getting warmer, delta %d, \n", temp_diff);
+               IWL_DEBUG_POWER(priv, "Getting warmer, delta %d\n", temp_diff);
 
        if (temp_diff < IWL_TEMPERATURE_THRESHOLD) {
-               IWL_DEBUG_POWER(priv, "Thermal txpower calib not needed\n");
+               IWL_DEBUG_POWER(priv, " => thermal txpower calib not needed\n");
                return 0;
        }
 
-       IWL_DEBUG_POWER(priv, "Thermal txpower calib needed\n");
+       IWL_DEBUG_POWER(priv, " => thermal txpower calib needed\n");
 
        return 1;
 }
@@ -1874,7 +1874,7 @@ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv,
                info->status.rates[0].count = tx_resp->failure_frame + 1;
                info->flags &= ~IEEE80211_TX_CTL_AMPDU;
                info->flags |= iwl_tx_status_to_mac80211(status);
-               iwl_hwrate_to_tx_control(priv, rate_n_flags, info);
+               iwlagn_hwrate_to_tx_control(priv, rate_n_flags, info);
                /* FIXME: code repetition end */
 
                IWL_DEBUG_TX_REPLY(priv, "1 Frame 0x%x failure :%d\n",
@@ -1953,6 +1953,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
  */
@@ -2014,7 +2068,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
                        index = iwl_queue_dec_wrap(scd_ssn & 0xff, txq->q.n_bd);
                        IWL_DEBUG_TX_REPLY(priv, "Retry scheduler reclaim scd_ssn "
                                           "%d index %d\n", scd_ssn , index);
-                       freed = iwl_tx_queue_reclaim(priv, txq_id, index);
+                       freed = iwlagn_tx_queue_reclaim(priv, txq_id, index);
                        if (qc)
                                iwl_free_tfds_in_queue(priv, sta_id,
                                                       tid, freed);
@@ -2031,7 +2085,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
        } else {
                info->status.rates[0].count = tx_resp->failure_frame + 1;
                info->flags |= iwl_tx_status_to_mac80211(status);
-               iwl_hwrate_to_tx_control(priv,
+               iwlagn_hwrate_to_tx_control(priv,
                                        le32_to_cpu(tx_resp->rate_n_flags),
                                        info);
 
@@ -2042,7 +2096,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
                                   le32_to_cpu(tx_resp->rate_n_flags),
                                   tx_resp->failure_frame);
 
-               freed = iwl_tx_queue_reclaim(priv, txq_id, index);
+               freed = iwlagn_tx_queue_reclaim(priv, txq_id, index);
                if (qc && likely(sta_id != IWL_INVALID_STATION))
                        iwl_free_tfds_in_queue(priv, sta_id, tid, freed);
                else if (sta_id == IWL_INVALID_STATION)
@@ -2053,10 +2107,9 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
                        iwl_wake_queue(priv, txq_id);
        }
        if (qc && likely(sta_id != IWL_INVALID_STATION))
-               iwl_txq_check_empty(priv, sta_id, tid, txq_id);
+               iwlagn_txq_check_empty(priv, sta_id, tid, txq_id);
 
-       if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK))
-               IWL_ERR(priv, "TODO:  Implement Tx ABORT REQUIRED!!!\n");
+       iwl_check_abort_status(priv, tx_resp->frame_count, status);
 }
 
 static int iwl4965_calc_rssi(struct iwl_priv *priv,
@@ -2090,7 +2143,7 @@ static int iwl4965_calc_rssi(struct iwl_priv *priv,
 
        /* dBm = max_rssi dB - agc dB - constant.
         * Higher AGC (higher radio gain) means lower signal. */
-       return max_rssi - agc - IWL49_RSSI_OFFSET;
+       return max_rssi - agc - IWLAGN_RSSI_OFFSET;
 }
 
 
@@ -2098,7 +2151,7 @@ static int iwl4965_calc_rssi(struct iwl_priv *priv,
 static void iwl4965_rx_handler_setup(struct iwl_priv *priv)
 {
        /* Legacy Rx frames */
-       priv->rx_handlers[REPLY_RX] = iwl_rx_reply_rx;
+       priv->rx_handlers[REPLY_RX] = iwlagn_rx_reply_rx;
        /* Tx response */
        priv->rx_handlers[REPLY_TX] = iwl4965_rx_reply_tx;
 }
@@ -2113,50 +2166,13 @@ 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,
        .set_rxon_chain = iwl_set_rxon_chain,
+       .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,
@@ -2164,6 +2180,7 @@ static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = {
        .gain_computation = iwl4965_gain_computation,
        .rts_tx_cmd_flag = iwlcore_rts_tx_cmd_flag,
        .calc_rssi = iwl4965_calc_rssi,
+       .request_scan = iwlagn_request_scan,
 };
 
 static struct iwl_lib_ops iwl4965_lib = {
@@ -2184,6 +2201,7 @@ static struct iwl_lib_ops iwl4965_lib = {
        .load_ucode = iwl4965_load_bsm,
        .dump_nic_event_log = iwl_dump_nic_event_log,
        .dump_nic_error_log = iwl_dump_nic_error_log,
+       .dump_fh = iwl_dump_fh,
        .set_channel_switch = iwl4965_hw_channel_switch,
        .apm_ops = {
                .init = iwl_apm_init,
@@ -2216,11 +2234,16 @@ 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,
+               .general_stats_read = iwl_ucode_general_stats_read,
+       },
+       .check_plcp_health = iwl_good_plcp_health,
 };
 
 static const struct iwl_ops iwl4965_ops = {
-       .ucode = &iwl4965_ucode,
        .lib = &iwl4965_lib,
        .hcmd = &iwl4965_hcmd,
        .utils = &iwl4965_hcmd_utils,
@@ -2228,7 +2251,7 @@ static const struct iwl_ops iwl4965_ops = {
 };
 
 struct iwl_cfg iwl4965_agn_cfg = {
-       .name = "4965AGN",
+       .name = "Intel(R) Wireless WiFi Link 4965AGN",
        .fw_name_pre = IWL4965_FW_PRE,
        .ucode_api_max = IWL4965_UCODE_API_MAX,
        .ucode_api_min = IWL4965_UCODE_API_MIN,
@@ -2239,7 +2262,7 @@ struct iwl_cfg iwl4965_agn_cfg = {
        .ops = &iwl4965_ops,
        .num_of_queues = IWL49_NUM_QUEUES,
        .num_of_ampdu_queues = IWL49_NUM_AMPDU_QUEUES,
-       .mod_params = &iwl4965_mod_params,
+       .mod_params = &iwlagn_mod_params,
        .valid_tx_ant = ANT_AB,
        .valid_rx_ant = ANT_ABC,
        .pll_cfg_val = 0,
@@ -2251,27 +2274,20 @@ struct iwl_cfg iwl4965_agn_cfg = {
        .led_compensation = 61,
        .chain_noise_num_beacons = IWL4965_CAL_NUM_BEACONS,
        .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
+       .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.
+        */
+       .scan_antennas[IEEE80211_BAND_5GHZ] = ANT_BC,
 };
 
 /* Module firmware */
 MODULE_FIRMWARE(IWL4965_MODULE_FIRMWARE(IWL4965_UCODE_API_MAX));
 
-module_param_named(antenna, iwl4965_mod_params.antenna, int, S_IRUGO);
-MODULE_PARM_DESC(antenna, "select antenna (1=Main, 2=Aux, default 0 [both])");
-module_param_named(swcrypto, iwl4965_mod_params.sw_crypto, int, S_IRUGO);
-MODULE_PARM_DESC(swcrypto, "using crypto in software (default 0 [hardware])");
-module_param_named(
-       disable_hw_scan, iwl4965_mod_params.disable_hw_scan, int, S_IRUGO);
-MODULE_PARM_DESC(disable_hw_scan, "disable hardware scanning (default 0)");
-
-module_param_named(queues_num, iwl4965_mod_params.num_of_queues, int, S_IRUGO);
-MODULE_PARM_DESC(queues_num, "number of hw queues.");
-/* 11n */
-module_param_named(11n_disable, iwl4965_mod_params.disable_11n, int, S_IRUGO);
-MODULE_PARM_DESC(11n_disable, "disable 11n functionality");
-module_param_named(amsdu_size_8K, iwl4965_mod_params.amsdu_size_8K,
-                  int, S_IRUGO);
-MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size");
-
-module_param_named(fw_restart4965, iwl4965_mod_params.restart_fw, int, S_IRUGO);
-MODULE_PARM_DESC(fw_restart4965, "restart firmware in case of error");