iwlwifi: move plcp check to separated function
[deliverable/linux.git] / drivers / net / wireless / iwlwifi / iwl-5000.c
index cffaae772d513169a356c3aa28e76a692c2b656d..75f2a5156bebef2d917335a1f8b305b9c1800a47 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -43,6 +43,7 @@
 #include "iwl-io.h"
 #include "iwl-sta.h"
 #include "iwl-helpers.h"
+#include "iwl-agn.h"
 #include "iwl-agn-led.h"
 #include "iwl-5000-hw.h"
 #include "iwl-6000-hw.h"
 #define _IWL5150_MODULE_FIRMWARE(api) IWL5150_FW_PRE #api ".ucode"
 #define IWL5150_MODULE_FIRMWARE(api) _IWL5150_MODULE_FIRMWARE(api)
 
-static const u16 iwl5000_default_queue_to_tx_fifo[] = {
-       IWL_TX_FIFO_AC3,
-       IWL_TX_FIFO_AC2,
-       IWL_TX_FIFO_AC1,
-       IWL_TX_FIFO_AC0,
+static const s8 iwl5000_default_queue_to_tx_fifo[] = {
+       IWL_TX_FIFO_VO,
+       IWL_TX_FIFO_VI,
+       IWL_TX_FIFO_BE,
+       IWL_TX_FIFO_BK,
        IWL50_CMD_FIFO_NUM,
-       IWL_TX_FIFO_HCCA_1,
-       IWL_TX_FIFO_HCCA_2
+       IWL_TX_FIFO_UNUSED,
+       IWL_TX_FIFO_UNUSED,
+       IWL_TX_FIFO_UNUSED,
+       IWL_TX_FIFO_UNUSED,
+       IWL_TX_FIFO_UNUSED,
 };
 
 /* NIC configuration for 5000 series */
@@ -179,14 +183,24 @@ static void iwl5000_gain_computation(struct iwl_priv *priv,
                        data->delta_gain_code[i] = 0;
                        continue;
                }
-               delta_g = (1000 * ((s32)average_noise[default_chain] -
+
+               delta_g = (priv->cfg->chain_noise_scale *
+                       ((s32)average_noise[default_chain] -
                        (s32)average_noise[i])) / 1500;
+
                /* bound gain by 2 bits value max, 3rd bit is sign */
                data->delta_gain_code[i] =
                        min(abs(delta_g), (long) CHAIN_NOISE_MAX_DELTA_GAIN_CODE);
 
                if (delta_g < 0)
-                       /* set negative sign */
+                       /*
+                        * set negative sign ...
+                        * note to Intel developers:  This is uCode API format,
+                        *   not the format of any internal device registers.
+                        *   Do not change this format for e.g. 6050 or similar
+                        *   devices.  Change format only if more resolution
+                        *   (i.e. more than 2 bits magnitude) is needed.
+                        */
                        data->delta_gain_code[i] |= (1 << 2);
        }
 
@@ -263,8 +277,8 @@ static struct iwl_sensitivity_ranges iwl5000_sensitivity = {
 
        .auto_corr_max_ofdm = 120,
        .auto_corr_max_ofdm_mrc = 210,
-       .auto_corr_max_ofdm_x1 = 155,
-       .auto_corr_max_ofdm_mrc_x1 = 290,
+       .auto_corr_max_ofdm_x1 = 120,
+       .auto_corr_max_ofdm_mrc_x1 = 240,
 
        .auto_corr_min_cck = 125,
        .auto_corr_max_cck = 200,
@@ -412,12 +426,14 @@ static void iwl5000_rx_calib_complete(struct iwl_priv *priv,
 /*
  * ucode
  */
-static int iwl5000_load_section(struct iwl_priv *priv,
-                               struct fw_desc *image,
-                               u32 dst_addr)
+static int iwl5000_load_section(struct iwl_priv *priv, const char *name,
+                               struct fw_desc *image, u32 dst_addr)
 {
        dma_addr_t phy_addr = image->p_addr;
        u32 byte_cnt = image->len;
+       int ret;
+
+       priv->ucode_write_complete = 0;
 
        iwl_write_direct32(priv,
                FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL),
@@ -447,57 +463,36 @@ static int iwl5000_load_section(struct iwl_priv *priv,
                FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE    |
                FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD);
 
-       return 0;
-}
-
-static int iwl5000_load_given_ucode(struct iwl_priv *priv,
-               struct fw_desc *inst_image,
-               struct fw_desc *data_image)
-{
-       int ret = 0;
-
-       ret = iwl5000_load_section(priv, inst_image,
-                                  IWL50_RTC_INST_LOWER_BOUND);
-       if (ret)
-               return ret;
-
-       IWL_DEBUG_INFO(priv, "INST uCode section being loaded...\n");
+       IWL_DEBUG_INFO(priv, "%s uCode section being loaded...\n", name);
        ret = wait_event_interruptible_timeout(priv->wait_command_queue,
                                        priv->ucode_write_complete, 5 * HZ);
        if (ret == -ERESTARTSYS) {
-               IWL_ERR(priv, "Could not load the INST uCode section due "
-                       "to interrupt\n");
+               IWL_ERR(priv, "Could not load the %s uCode section due "
+                       "to interrupt\n", name);
                return ret;
        }
        if (!ret) {
-               IWL_ERR(priv, "Could not load the INST uCode section\n");
+               IWL_ERR(priv, "Could not load the %s uCode section\n",
+                       name);
                return -ETIMEDOUT;
        }
 
-       priv->ucode_write_complete = 0;
-
-       ret = iwl5000_load_section(
-               priv, data_image, IWL50_RTC_DATA_LOWER_BOUND);
-       if (ret)
-               return ret;
+       return 0;
+}
 
-       IWL_DEBUG_INFO(priv, "DATA uCode section being loaded...\n");
+static int iwl5000_load_given_ucode(struct iwl_priv *priv,
+               struct fw_desc *inst_image,
+               struct fw_desc *data_image)
+{
+       int ret = 0;
 
-       ret = wait_event_interruptible_timeout(priv->wait_command_queue,
-                               priv->ucode_write_complete, 5 * HZ);
-       if (ret == -ERESTARTSYS) {
-               IWL_ERR(priv, "Could not load the INST uCode section due "
-                       "to interrupt\n");
+       ret = iwl5000_load_section(priv, "INST", inst_image,
+                                  IWL50_RTC_INST_LOWER_BOUND);
+       if (ret)
                return ret;
-       } else if (!ret) {
-               IWL_ERR(priv, "Could not load the DATA uCode section\n");
-               return -ETIMEDOUT;
-       } else
-               ret = 0;
-
-       priv->ucode_write_complete = 0;
 
-       return ret;
+       return iwl5000_load_section(priv, "DATA", data_image,
+                                   IWL50_RTC_DATA_LOWER_BOUND);
 }
 
 int iwl5000_load_ucode(struct iwl_priv *priv)
@@ -549,7 +544,6 @@ void iwl5000_init_alive_start(struct iwl_priv *priv)
                goto restart;
        }
 
-       iwl_clear_stations_table(priv);
        ret = priv->cfg->ops->lib->alive_notify(priv);
        if (ret) {
                IWL_WARN(priv,
@@ -588,9 +582,9 @@ static void iwl5000_tx_queue_set_status(struct iwl_priv *priv,
 
        txq->sched_retry = scd_retry;
 
-       IWL_DEBUG_INFO(priv, "%s %s Queue %d on AC %d\n",
+       IWL_DEBUG_INFO(priv, "%s %s Queue %d on FIFO %d\n",
                       active ? "Activate" : "Deactivate",
-                      scd_retry ? "BA" : "AC", txq_id, tx_fifo_id);
+                      scd_retry ? "BA" : "AC/CMD", txq_id, tx_fifo_id);
 }
 
 int iwl5000_alive_notify(struct iwl_priv *priv)
@@ -657,26 +651,29 @@ int iwl5000_alive_notify(struct iwl_priv *priv)
 
        iwl5000_set_wr_ptrs(priv, IWL_CMD_QUEUE_NUM, 0);
 
+       /* make sure all queue are not stopped */
+       memset(&priv->queue_stopped[0], 0, sizeof(priv->queue_stopped));
+       for (i = 0; i < 4; i++)
+               atomic_set(&priv->queue_stop_count[i], 0);
+
+       /* reset to 0 to enable all the queue first */
+       priv->txq_ctx_active_msk = 0;
        /* map qos queues to fifos one-to-one */
+       BUILD_BUG_ON(ARRAY_SIZE(iwl5000_default_queue_to_tx_fifo) != 10);
+
        for (i = 0; i < ARRAY_SIZE(iwl5000_default_queue_to_tx_fifo); i++) {
                int ac = iwl5000_default_queue_to_tx_fifo[i];
+
                iwl_txq_ctx_activate(priv, i);
+
+               if (ac == IWL_TX_FIFO_UNUSED)
+                       continue;
+
                iwl5000_tx_queue_set_status(priv, &priv->txq[i], ac, 0);
        }
 
-       /*
-        * TODO - need to initialize these queues and map them to FIFOs
-        * in the loop above, not only mark them as active. We do this
-        * because we want the first aggregation queue to be queue #10,
-        * but do not use 8 or 9 otherwise yet.
-        */
-       iwl_txq_ctx_activate(priv, 7);
-       iwl_txq_ctx_activate(priv, 8);
-       iwl_txq_ctx_activate(priv, 9);
-
        spin_unlock_irqrestore(&priv->lock, flags);
 
-
        iwl_send_wimax_coex(priv);
 
        iwl5000_set_Xtal_calib(priv);
@@ -781,7 +778,7 @@ void iwl5000_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
 
        scd_bc_tbl[txq_id].tfd_offset[write_ptr] = bc_ent;
 
-       if (txq->q.write_ptr < TFD_QUEUE_SIZE_BC_DUP)
+       if (write_ptr < TFD_QUEUE_SIZE_BC_DUP)
                scd_bc_tbl[txq_id].
                        tfd_offset[TFD_QUEUE_SIZE_MAX + write_ptr] = bc_ent;
 }
@@ -800,12 +797,12 @@ void iwl5000_txq_inval_byte_cnt_tbl(struct iwl_priv *priv,
        if (txq_id != IWL_CMD_QUEUE_NUM)
                sta_id = txq->cmd[read_ptr]->cmd.tx.sta_id;
 
-       bc_ent =  cpu_to_le16(1 | (sta_id << 12));
+       bc_ent = cpu_to_le16(1 | (sta_id << 12));
        scd_bc_tbl[txq_id].tfd_offset[read_ptr] = bc_ent;
 
-       if (txq->q.write_ptr < TFD_QUEUE_SIZE_BC_DUP)
+       if (read_ptr < TFD_QUEUE_SIZE_BC_DUP)
                scd_bc_tbl[txq_id].
-                       tfd_offset[TFD_QUEUE_SIZE_MAX + read_ptr] =  bc_ent;
+                       tfd_offset[TFD_QUEUE_SIZE_MAX + read_ptr] = bc_ent;
 }
 
 static int iwl5000_tx_queue_set_q2ratid(struct iwl_priv *priv, u16 ra_tid,
@@ -1464,6 +1461,8 @@ struct iwl_lib_ops iwl5000_lib = {
        .is_valid_rtc_data_addr = iwl5000_hw_valid_rtc_data_addr,
        .dump_nic_event_log = iwl_dump_nic_event_log,
        .dump_nic_error_log = iwl_dump_nic_error_log,
+       .dump_csr = iwl_dump_csr,
+       .dump_fh = iwl_dump_fh,
        .load_ucode = iwl5000_load_ucode,
        .init_alive_start = iwl5000_init_alive_start,
        .alive_notify = iwl5000_alive_notify,
@@ -1499,6 +1498,9 @@ struct iwl_lib_ops iwl5000_lib = {
                .temperature = iwl5000_temperature,
                .set_ct_kill = iwl5000_set_ct_threshold,
         },
+       .add_bcast_station = iwl_add_bcast_station,
+       .recover_from_tx_stall = iwl_bg_monitor_recover,
+       .recover_from_statistics = iwl_recover_from_statistics,
 };
 
 static struct iwl_lib_ops iwl5150_lib = {
@@ -1516,6 +1518,7 @@ static struct iwl_lib_ops iwl5150_lib = {
        .is_valid_rtc_data_addr = iwl5000_hw_valid_rtc_data_addr,
        .dump_nic_event_log = iwl_dump_nic_event_log,
        .dump_nic_error_log = iwl_dump_nic_error_log,
+       .dump_csr = iwl_dump_csr,
        .load_ucode = iwl5000_load_ucode,
        .init_alive_start = iwl5000_init_alive_start,
        .alive_notify = iwl5000_alive_notify,
@@ -1551,9 +1554,12 @@ static struct iwl_lib_ops iwl5150_lib = {
                .temperature = iwl5150_temperature,
                .set_ct_kill = iwl5150_set_ct_threshold,
         },
+       .add_bcast_station = iwl_add_bcast_station,
+       .recover_from_tx_stall = iwl_bg_monitor_recover,
+       .recover_from_statistics = iwl_recover_from_statistics,
 };
 
-static struct iwl_ops iwl5000_ops = {
+static const struct iwl_ops iwl5000_ops = {
        .ucode = &iwl5000_ucode,
        .lib = &iwl5000_lib,
        .hcmd = &iwl5000_hcmd,
@@ -1561,7 +1567,7 @@ static struct iwl_ops iwl5000_ops = {
        .led = &iwlagn_led_ops,
 };
 
-static struct iwl_ops iwl5150_ops = {
+static const struct iwl_ops iwl5150_ops = {
        .ucode = &iwl5000_ucode,
        .lib = &iwl5150_lib,
        .hcmd = &iwl5000_hcmd,
@@ -1577,7 +1583,7 @@ struct iwl_mod_params iwl50_mod_params = {
 
 
 struct iwl_cfg iwl5300_agn_cfg = {
-       .name = "5300AGN",
+       .name = "Intel(R) Ultimate N WiFi Link 5300 AGN",
        .fw_name_pre = IWL5000_FW_PRE,
        .ucode_api_max = IWL5000_UCODE_API_MAX,
        .ucode_api_min = IWL5000_UCODE_API_MIN,
@@ -1598,11 +1604,13 @@ struct iwl_cfg iwl5300_agn_cfg = {
        .led_compensation = 51,
        .use_rts_for_ht = true, /* use rts/cts protection */
        .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
-       .sm_ps_mode = WLAN_HT_CAP_SM_PS_DISABLED,
+       .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
+       .chain_noise_scale = 1000,
+       .monitor_recover_period = IWL_MONITORING_PERIOD,
 };
 
 struct iwl_cfg iwl5100_bgn_cfg = {
-       .name = "5100BGN",
+       .name = "Intel(R) WiFi Link 5100 BGN",
        .fw_name_pre = IWL5000_FW_PRE,
        .ucode_api_max = IWL5000_UCODE_API_MAX,
        .ucode_api_min = IWL5000_UCODE_API_MIN,
@@ -1623,10 +1631,13 @@ struct iwl_cfg iwl5100_bgn_cfg = {
        .led_compensation = 51,
        .use_rts_for_ht = true, /* use rts/cts protection */
        .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
+       .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
+       .chain_noise_scale = 1000,
+       .monitor_recover_period = IWL_MONITORING_PERIOD,
 };
 
 struct iwl_cfg iwl5100_abg_cfg = {
-       .name = "5100ABG",
+       .name = "Intel(R) WiFi Link 5100 ABG",
        .fw_name_pre = IWL5000_FW_PRE,
        .ucode_api_max = IWL5000_UCODE_API_MAX,
        .ucode_api_min = IWL5000_UCODE_API_MIN,
@@ -1645,10 +1656,13 @@ struct iwl_cfg iwl5100_abg_cfg = {
        .use_bsm = false,
        .led_compensation = 51,
        .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
+       .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
+       .chain_noise_scale = 1000,
+       .monitor_recover_period = IWL_MONITORING_PERIOD,
 };
 
 struct iwl_cfg iwl5100_agn_cfg = {
-       .name = "5100AGN",
+       .name = "Intel(R) WiFi Link 5100 AGN",
        .fw_name_pre = IWL5000_FW_PRE,
        .ucode_api_max = IWL5000_UCODE_API_MAX,
        .ucode_api_min = IWL5000_UCODE_API_MIN,
@@ -1669,11 +1683,13 @@ struct iwl_cfg iwl5100_agn_cfg = {
        .led_compensation = 51,
        .use_rts_for_ht = true, /* use rts/cts protection */
        .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
-       .sm_ps_mode = WLAN_HT_CAP_SM_PS_DISABLED,
+       .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
+       .chain_noise_scale = 1000,
+       .monitor_recover_period = IWL_MONITORING_PERIOD,
 };
 
 struct iwl_cfg iwl5350_agn_cfg = {
-       .name = "5350AGN",
+       .name = "Intel(R) WiMAX/WiFi Link 5350 AGN",
        .fw_name_pre = IWL5000_FW_PRE,
        .ucode_api_max = IWL5000_UCODE_API_MAX,
        .ucode_api_min = IWL5000_UCODE_API_MIN,
@@ -1694,11 +1710,13 @@ struct iwl_cfg iwl5350_agn_cfg = {
        .led_compensation = 51,
        .use_rts_for_ht = true, /* use rts/cts protection */
        .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
-       .sm_ps_mode = WLAN_HT_CAP_SM_PS_DISABLED,
+       .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
+       .chain_noise_scale = 1000,
+       .monitor_recover_period = IWL_MONITORING_PERIOD,
 };
 
 struct iwl_cfg iwl5150_agn_cfg = {
-       .name = "5150AGN",
+       .name = "Intel(R) WiMAX/WiFi Link 5150 AGN",
        .fw_name_pre = IWL5150_FW_PRE,
        .ucode_api_max = IWL5150_UCODE_API_MAX,
        .ucode_api_min = IWL5150_UCODE_API_MIN,
@@ -1719,11 +1737,13 @@ struct iwl_cfg iwl5150_agn_cfg = {
        .led_compensation = 51,
        .use_rts_for_ht = true, /* use rts/cts protection */
        .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
-       .sm_ps_mode = WLAN_HT_CAP_SM_PS_DISABLED,
+       .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
+       .chain_noise_scale = 1000,
+       .monitor_recover_period = IWL_MONITORING_PERIOD,
 };
 
 struct iwl_cfg iwl5150_abg_cfg = {
-       .name = "5150ABG",
+       .name = "Intel(R) WiMAX/WiFi Link 5150 ABG",
        .fw_name_pre = IWL5150_FW_PRE,
        .ucode_api_max = IWL5150_UCODE_API_MAX,
        .ucode_api_min = IWL5150_UCODE_API_MIN,
@@ -1742,6 +1762,9 @@ struct iwl_cfg iwl5150_abg_cfg = {
        .use_bsm = false,
        .led_compensation = 51,
        .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
+       .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
+       .chain_noise_scale = 1000,
+       .monitor_recover_period = IWL_MONITORING_PERIOD,
 };
 
 MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX));
This page took 0.031988 seconds and 5 git commands to generate.