Commit f0832f13 authored by Emmanuel Grumbach's avatar Emmanuel Grumbach Committed by John W. Linville

iwlwifi: HW dependent run time calibration

This patch does several things:

1) rename CONFIG_IWL4965_SENSITIVITY to IWL4965_RUN_TIME_CALIB which is
   better semantic
2) move all the run time calibration to a new file: iwl-calib.c
3) simplify the sensitivity calibration flow and make it HW dependent
4) make the chain noise calibration flow HW dependent
Signed-off-by: default avatarEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: default avatarTomas Winkler <tomas.winkler@intel.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent a7ca0268
...@@ -15,6 +15,15 @@ config IWLWIFI_LEDS ...@@ -15,6 +15,15 @@ config IWLWIFI_LEDS
bool bool
default n default n
config IWLWIFI_RUN_TIME_CALIB
bool
depends on IWLCORE
default n
---help---
This option will enable run time calibration for the iwlwifi driver.
These calibrations are Sensitivity and Chain Noise.
config IWLWIFI_RFKILL config IWLWIFI_RFKILL
boolean "IWLWIFI RF kill support" boolean "IWLWIFI RF kill support"
depends on IWLCORE depends on IWLCORE
...@@ -68,12 +77,14 @@ config IWL4965_SPECTRUM_MEASUREMENT ...@@ -68,12 +77,14 @@ config IWL4965_SPECTRUM_MEASUREMENT
---help--- ---help---
This option will enable spectrum measurement for the iwl4965 driver. This option will enable spectrum measurement for the iwl4965 driver.
config IWL4965_SENSITIVITY config IWL4965_RUN_TIME_CALIB
bool "Enable Sensitivity Calibration in iwl4965 driver" bool "Enable run time Calibration for 4965 NIC"
select IWLWIFI_RUN_TIME_CALIB
depends on IWL4965 depends on IWL4965
default y
---help--- ---help---
This option will enable sensitivity calibration for the iwl4965 This option will enable run time calibration for the iwl4965 driver.
driver. These calibrations are Sensitivity and Chain Noise. If unsure, say yes
config IWLWIFI_DEBUG config IWLWIFI_DEBUG
bool "Enable full debugging output in iwl4965 driver" bool "Enable full debugging output in iwl4965 driver"
......
...@@ -3,6 +3,7 @@ iwlcore-objs := iwl-core.o iwl-eeprom.o iwl-hcmd.o ...@@ -3,6 +3,7 @@ iwlcore-objs := iwl-core.o iwl-eeprom.o iwl-hcmd.o
iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o
iwlcore-$(CONFIG_IWLWIFI_LEDS) += iwl-led.o iwlcore-$(CONFIG_IWLWIFI_LEDS) += iwl-led.o
iwlcore-$(CONFIG_IWLWIFI_RFKILL) += iwl-rfkill.o iwlcore-$(CONFIG_IWLWIFI_RFKILL) += iwl-rfkill.o
iwlcore-$(CONFIG_IWLWIFI_RUN_TIME_CALIB) += iwl-calib.o
obj-$(CONFIG_IWL3945) += iwl3945.o obj-$(CONFIG_IWL3945) += iwl3945.o
iwl3945-objs := iwl3945-base.o iwl-3945.o iwl-3945-rs.o iwl3945-objs := iwl3945-base.o iwl-3945.o iwl-3945-rs.o
......
...@@ -2559,7 +2559,7 @@ struct iwl4965_missed_beacon_notif { ...@@ -2559,7 +2559,7 @@ struct iwl4965_missed_beacon_notif {
*/ */
/* /*
* Table entries in SENSITIVITY_CMD (struct iwl4965_sensitivity_cmd) * Table entries in SENSITIVITY_CMD (struct iwl_sensitivity_cmd)
*/ */
#define HD_TABLE_SIZE (11) /* number of entries */ #define HD_TABLE_SIZE (11) /* number of entries */
#define HD_MIN_ENERGY_CCK_DET_INDEX (0) /* table indexes */ #define HD_MIN_ENERGY_CCK_DET_INDEX (0) /* table indexes */
...@@ -2574,18 +2574,18 @@ struct iwl4965_missed_beacon_notif { ...@@ -2574,18 +2574,18 @@ struct iwl4965_missed_beacon_notif {
#define HD_AUTO_CORR40_X4_TH_ADD_MIN_INDEX (9) #define HD_AUTO_CORR40_X4_TH_ADD_MIN_INDEX (9)
#define HD_OFDM_ENERGY_TH_IN_INDEX (10) #define HD_OFDM_ENERGY_TH_IN_INDEX (10)
/* Control field in struct iwl4965_sensitivity_cmd */ /* Control field in struct iwl_sensitivity_cmd */
#define SENSITIVITY_CMD_CONTROL_DEFAULT_TABLE __constant_cpu_to_le16(0) #define SENSITIVITY_CMD_CONTROL_DEFAULT_TABLE __constant_cpu_to_le16(0)
#define SENSITIVITY_CMD_CONTROL_WORK_TABLE __constant_cpu_to_le16(1) #define SENSITIVITY_CMD_CONTROL_WORK_TABLE __constant_cpu_to_le16(1)
/** /**
* struct iwl4965_sensitivity_cmd * struct iwl_sensitivity_cmd
* @control: (1) updates working table, (0) updates default table * @control: (1) updates working table, (0) updates default table
* @table: energy threshold values, use HD_* as index into table * @table: energy threshold values, use HD_* as index into table
* *
* Always use "1" in "control" to update uCode's working table and DSP. * Always use "1" in "control" to update uCode's working table and DSP.
*/ */
struct iwl4965_sensitivity_cmd { struct iwl_sensitivity_cmd {
__le16 control; /* always use "1" */ __le16 control; /* always use "1" */
__le16 table[HD_TABLE_SIZE]; /* use HD_* as index */ __le16 table[HD_TABLE_SIZE]; /* use HD_* as index */
} __attribute__ ((packed)); } __attribute__ ((packed));
......
This diff is collapsed.
...@@ -566,6 +566,29 @@ struct iwl4965_ibss_seq { ...@@ -566,6 +566,29 @@ struct iwl4965_ibss_seq {
struct list_head list; struct list_head list;
}; };
struct iwl_sensitivity_ranges {
u16 min_nrg_cck;
u16 max_nrg_cck;
u16 nrg_th_cck;
u16 nrg_th_ofdm;
u16 auto_corr_min_ofdm;
u16 auto_corr_min_ofdm_mrc;
u16 auto_corr_min_ofdm_x1;
u16 auto_corr_min_ofdm_mrc_x1;
u16 auto_corr_max_ofdm;
u16 auto_corr_max_ofdm_mrc;
u16 auto_corr_max_ofdm_x1;
u16 auto_corr_max_ofdm_mrc_x1;
u16 auto_corr_max_cck;
u16 auto_corr_max_cck_mrc;
u16 auto_corr_min_cck;
u16 auto_corr_min_cck_mrc;
};
/** /**
* struct iwl_hw_params * struct iwl_hw_params
* @max_txq_num: Max # Tx queues supported * @max_txq_num: Max # Tx queues supported
...@@ -576,6 +599,7 @@ struct iwl4965_ibss_seq { ...@@ -576,6 +599,7 @@ struct iwl4965_ibss_seq {
* @max_rxq_log: Log-base-2 of max_rxq_size * @max_rxq_log: Log-base-2 of max_rxq_size
* @max_stations: * @max_stations:
* @bcast_sta_id: * @bcast_sta_id:
* @struct iwl_sensitivity_ranges: range of sensitivity values
*/ */
struct iwl_hw_params { struct iwl_hw_params {
u16 max_txq_num; u16 max_txq_num;
...@@ -590,6 +614,9 @@ struct iwl_hw_params { ...@@ -590,6 +614,9 @@ struct iwl_hw_params {
u32 max_pkt_size; u32 max_pkt_size;
u8 max_stations; u8 max_stations;
u8 bcast_sta_id; u8 bcast_sta_id;
#ifdef CONFIG_IWLWIFI_RUN_TIME_CALIB
const struct iwl_sensitivity_ranges *sens;
#endif
}; };
#define HT_SHORT_GI_20MHZ_ONLY (1 << 0) #define HT_SHORT_GI_20MHZ_ONLY (1 << 0)
...@@ -732,9 +759,6 @@ extern void iwl4965_add_station(struct iwl_priv *priv, const u8 *addr, ...@@ -732,9 +759,6 @@ extern void iwl4965_add_station(struct iwl_priv *priv, const u8 *addr,
extern void iwl4965_set_rxon_chain(struct iwl_priv *priv); extern void iwl4965_set_rxon_chain(struct iwl_priv *priv);
extern int iwl4965_alive_notify(struct iwl_priv *priv); extern int iwl4965_alive_notify(struct iwl_priv *priv);
extern void iwl4965_update_rate_scaling(struct iwl_priv *priv, u8 mode); extern void iwl4965_update_rate_scaling(struct iwl_priv *priv, u8 mode);
extern void iwl4965_chain_noise_reset(struct iwl_priv *priv);
extern void iwl4965_init_sensitivity(struct iwl_priv *priv, u8 flags,
u8 force);
extern void iwl4965_rf_kill_ct_config(struct iwl_priv *priv); extern void iwl4965_rf_kill_ct_config(struct iwl_priv *priv);
extern void iwl4965_hwrate_to_tx_control(struct iwl_priv *priv, extern void iwl4965_hwrate_to_tx_control(struct iwl_priv *priv,
u32 rate_n_flags, u32 rate_n_flags,
...@@ -818,23 +842,8 @@ struct iwl4965_lq_mngr { ...@@ -818,23 +842,8 @@ struct iwl4965_lq_mngr {
#define MAX_FA_CCK 50 #define MAX_FA_CCK 50
#define MIN_FA_CCK 5 #define MIN_FA_CCK 5
#define NRG_MIN_CCK 97
#define NRG_MAX_CCK 0
#define AUTO_CORR_MIN_OFDM 85
#define AUTO_CORR_MIN_OFDM_MRC 170
#define AUTO_CORR_MIN_OFDM_X1 105
#define AUTO_CORR_MIN_OFDM_MRC_X1 220
#define AUTO_CORR_MAX_OFDM 120
#define AUTO_CORR_MAX_OFDM_MRC 210
#define AUTO_CORR_MAX_OFDM_X1 140
#define AUTO_CORR_MAX_OFDM_MRC_X1 270
#define AUTO_CORR_STEP_OFDM 1 #define AUTO_CORR_STEP_OFDM 1
#define AUTO_CORR_MIN_CCK (125)
#define AUTO_CORR_MAX_CCK (200)
#define AUTO_CORR_MIN_CCK_MRC 200
#define AUTO_CORR_MAX_CCK_MRC 400
#define AUTO_CORR_STEP_CCK 3 #define AUTO_CORR_STEP_CCK 3
#define AUTO_CORR_MAX_TH_CCK 160 #define AUTO_CORR_MAX_TH_CCK 160
...@@ -865,11 +874,6 @@ enum iwl4965_chain_noise_state { ...@@ -865,11 +874,6 @@ enum iwl4965_chain_noise_state {
IWL_CHAIN_NOISE_CALIBRATED = 2, IWL_CHAIN_NOISE_CALIBRATED = 2,
}; };
enum iwl4965_sensitivity_state {
IWL_SENS_CALIB_ALLOWED = 0,
IWL_SENS_CALIB_NEED_REINIT = 1,
};
enum iwl4965_calib_enabled_state { enum iwl4965_calib_enabled_state {
IWL_CALIB_DISABLED = 0, /* must be 0 */ IWL_CALIB_DISABLED = 0, /* must be 0 */
IWL_CALIB_ENABLED = 1, IWL_CALIB_ENABLED = 1,
...@@ -884,8 +888,9 @@ struct statistics_general_data { ...@@ -884,8 +888,9 @@ struct statistics_general_data {
u32 beacon_energy_c; u32 beacon_energy_c;
}; };
#ifdef CONFIG_IWLWIFI_RUN_TIME_CALIB
/* Sensitivity calib data */ /* Sensitivity calib data */
struct iwl4965_sensitivity_data { struct iwl_sensitivity_data {
u32 auto_corr_ofdm; u32 auto_corr_ofdm;
u32 auto_corr_ofdm_mrc; u32 auto_corr_ofdm_mrc;
u32 auto_corr_ofdm_x1; u32 auto_corr_ofdm_x1;
...@@ -909,12 +914,10 @@ struct iwl4965_sensitivity_data { ...@@ -909,12 +914,10 @@ struct iwl4965_sensitivity_data {
s32 nrg_auto_corr_silence_diff; s32 nrg_auto_corr_silence_diff;
u32 num_in_cck_no_fa; u32 num_in_cck_no_fa;
u32 nrg_th_ofdm; u32 nrg_th_ofdm;
u8 state;
}; };
/* Chain noise (differential Rx gain) calib data */ /* Chain noise (differential Rx gain) calib data */
struct iwl4965_chain_noise_data { struct iwl_chain_noise_data {
u8 state; u8 state;
u16 beacon_count; u16 beacon_count;
u32 chain_noise_a; u32 chain_noise_a;
...@@ -927,6 +930,7 @@ struct iwl4965_chain_noise_data { ...@@ -927,6 +930,7 @@ struct iwl4965_chain_noise_data {
u8 delta_gain_code[NUM_RX_CHAINS]; u8 delta_gain_code[NUM_RX_CHAINS];
u8 radio_write; u8 radio_write;
}; };
#endif /* CONFIG_IWLWIFI_RUN_TIME_CALIB */
#define EEPROM_SEM_TIMEOUT 10 /* milliseconds */ #define EEPROM_SEM_TIMEOUT 10 /* milliseconds */
#define EEPROM_SEM_RETRY_LIMIT 1000 /* number of attempts (not time) */ #define EEPROM_SEM_RETRY_LIMIT 1000 /* number of attempts (not time) */
...@@ -1051,12 +1055,12 @@ struct iwl_priv { ...@@ -1051,12 +1055,12 @@ struct iwl_priv {
u8 assoc_station_added; u8 assoc_station_added;
u8 use_ant_b_for_management_frame; /* Tx antenna selection */ u8 use_ant_b_for_management_frame; /* Tx antenna selection */
u8 valid_antenna; /* Bit mask of antennas actually connected */ u8 valid_antenna; /* Bit mask of antennas actually connected */
#ifdef CONFIG_IWL4965_SENSITIVITY
struct iwl4965_sensitivity_data sensitivity_data;
struct iwl4965_chain_noise_data chain_noise_data;
u8 start_calib; u8 start_calib;
#ifdef CONFIG_IWLWIFI_RUN_TIME_CALIB
struct iwl_sensitivity_data sensitivity_data;
struct iwl_chain_noise_data chain_noise_data;
__le16 sensitivity_tbl[HD_TABLE_SIZE]; __le16 sensitivity_tbl[HD_TABLE_SIZE];
#endif /*CONFIG_IWL4965_SENSITIVITY*/ #endif /*CONFIG_IWLWIFI_RUN_TIME_CALIB*/
#ifdef CONFIG_IWL4965_HT #ifdef CONFIG_IWL4965_HT
struct iwl_ht_info current_ht_config; struct iwl_ht_info current_ht_config;
...@@ -1206,7 +1210,7 @@ struct iwl_priv { ...@@ -1206,7 +1210,7 @@ struct iwl_priv {
#endif /* CONFIG_IWLWIFI_DEBUG */ #endif /* CONFIG_IWLWIFI_DEBUG */
struct work_struct txpower_work; struct work_struct txpower_work;
#ifdef CONFIG_IWL4965_SENSITIVITY #ifdef CONFIG_IWL4965_RUN_TIME_CALIB
struct work_struct sensitivity_work; struct work_struct sensitivity_work;
#endif #endif
struct timer_list statistics_periodic; struct timer_list statistics_periodic;
......
This diff is collapsed.
/******************************************************************************
*
* This file is provided under a dual BSD/GPLv2 license. When using or
* redistributing this file, you may do so under either license.
*
* GPL LICENSE SUMMARY
*
* Copyright(c) 2008 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
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
* USA
*
* The full GNU General Public License is included in this distribution
* in the file called LICENSE.GPL.
*
* Contact Information:
* Tomas Winkler <tomas.winkler@intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
* BSD LICENSE
*
* Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
#ifndef __iwl_calib_h__
#define __iwl_calib_h__
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/version.h>
#include <net/mac80211.h>
#include "iwl-eeprom.h"
#include "iwl-core.h"
#include "iwl-4965.h"
#ifdef CONFIG_IWLWIFI_RUN_TIME_CALIB
void iwl_chain_noise_calibration(struct iwl_priv *priv,
struct iwl4965_notif_statistics *stat_resp);
void iwl_sensitivity_calibration(struct iwl_priv *priv,
struct iwl4965_notif_statistics *resp);
void iwl_init_sensitivity(struct iwl_priv *priv);
static inline void iwl_chain_noise_reset(struct iwl_priv *priv)
{
if (priv->cfg->ops->utils->chain_noise_reset)
priv->cfg->ops->utils->chain_noise_reset(priv);
}
#else
static inline void iwl_chain_noise_calibration(struct iwl_priv *priv,
struct iwl4965_notif_statistics *stat_resp)
{
}
static inline void iwl_sensitivity_calibration(struct iwl_priv *priv,
struct iwl4965_notif_statistics *resp)
{
}
static inline void iwl_init_sensitivity(struct iwl_priv *priv)
{
}
static inline void iwl_chain_noise_reset(struct iwl_priv *priv)
{
}
#endif
#endif /* __iwl_calib_h__ */
...@@ -87,6 +87,13 @@ struct iwl_hcmd_ops { ...@@ -87,6 +87,13 @@ struct iwl_hcmd_ops {
}; };
struct iwl_hcmd_utils_ops { struct iwl_hcmd_utils_ops {
int (*enqueue_hcmd)(struct iwl_priv *priv, struct iwl_host_cmd *cmd); int (*enqueue_hcmd)(struct iwl_priv *priv, struct iwl_host_cmd *cmd);
#ifdef CONFIG_IWLWIFI_RUN_TIME_CALIB
void (*gain_computation)(struct iwl_priv *priv,
u32 *average_noise,
u16 min_average_noise_antennat_i,
u32 min_average_noise);
void (*chain_noise_reset)(struct iwl_priv *priv);
#endif
}; };
struct iwl_lib_ops { struct iwl_lib_ops {
......
...@@ -51,6 +51,7 @@ ...@@ -51,6 +51,7 @@
#include "iwl-io.h" #include "iwl-io.h"
#include "iwl-helpers.h" #include "iwl-helpers.h"
#include "iwl-sta.h" #include "iwl-sta.h"
#include "iwl-calib.h"
static int iwl4965_tx_queue_update_write_ptr(struct iwl_priv *priv, static int iwl4965_tx_queue_update_write_ptr(struct iwl_priv *priv,
struct iwl4965_tx_queue *txq); struct iwl4965_tx_queue *txq);
...@@ -795,14 +796,6 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv) ...@@ -795,14 +796,6 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv)
/* station table will be cleared */ /* station table will be cleared */
priv->assoc_station_added = 0; priv->assoc_station_added = 0;
#ifdef CONFIG_IWL4965_SENSITIVITY
priv->sensitivity_data.state = IWL_SENS_CALIB_NEED_REINIT;
if (!priv->error_recovering)
priv->start_calib = 0;
iwl4965_init_sensitivity(priv, CMD_ASYNC, 1);
#endif /* CONFIG_IWL4965_SENSITIVITY */
/* If we are currently associated and the new config requires /* If we are currently associated and the new config requires
* an RXON_ASSOC and the new config wants the associated mask enabled, * an RXON_ASSOC and the new config wants the associated mask enabled,
* we must clear the associated from the active configuration * we must clear the associated from the active configuration
...@@ -846,13 +839,10 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv) ...@@ -846,13 +839,10 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv)
iwlcore_clear_stations_table(priv); iwlcore_clear_stations_table(priv);
#ifdef CONFIG_IWL4965_SENSITIVITY
if (!priv->error_recovering) if (!priv->error_recovering)
priv->start_calib = 0; priv->start_calib = 0;
priv->sensitivity_data.state = IWL_SENS_CALIB_NEED_REINIT; iwl_init_sensitivity(priv);
iwl4965_init_sensitivity(priv, CMD_ASYNC, 1);
#endif /* CONFIG_IWL4965_SENSITIVITY */
memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon)); memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon));
...@@ -6040,11 +6030,9 @@ static void iwl4965_post_associate(struct iwl_priv *priv) ...@@ -6040,11 +6030,9 @@ static void iwl4965_post_associate(struct iwl_priv *priv)
iwl4965_sequence_reset(priv); iwl4965_sequence_reset(priv);
#ifdef CONFIG_IWL4965_SENSITIVITY
/* Enable Rx differential gain and sensitivity calibrations */ /* Enable Rx differential gain and sensitivity calibrations */
iwl4965_chain_noise_reset(priv); iwl_chain_noise_reset(priv);
priv->start_calib = 1; priv->start_calib = 1;
#endif /* CONFIG_IWL4965_SENSITIVITY */
if (priv->iw_mode == IEEE80211_IF_TYPE_IBSS) if (priv->iw_mode == IEEE80211_IF_TYPE_IBSS)
priv->assoc_station_added = 1; priv->assoc_station_added = 1;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment