aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-5000.c
diff options
context:
space:
mode:
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>2008-04-24 14:55:30 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-05-07 15:02:24 -0400
commit33fd503346ad86bd7470a0f8c4c3080393d14233 (patch)
tree5753cf92656fa885f80cb8cab2b8b14c4c45f085 /drivers/net/wireless/iwlwifi/iwl-5000.c
parentc031bf806fef4854b02266a4105f55ed31f2d1a8 (diff)
iwlwifi-5000: add run time calibrations for 5000
This patch adds support for run time calibrations for the 5000 family HW. Those calibrations are sensitivity calibration, and chain noise calibration. Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-5000.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c101
1 files changed, 101 insertions, 0 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index 7c42bbffff5..1a18ac187cb 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -125,6 +125,100 @@ static u32 eeprom_indirect_address(const struct iwl_priv *priv, u32 address)
125 return (address & ADDRESS_MSK) + (offset << 1); 125 return (address & ADDRESS_MSK) + (offset << 1);
126} 126}
127 127
128#ifdef CONFIG_IWL5000_RUN_TIME_CALIB
129
130static void iwl5000_gain_computation(struct iwl_priv *priv,
131 u32 average_noise[NUM_RX_CHAINS],
132 u16 min_average_noise_antenna_i,
133 u32 min_average_noise)
134{
135 int i;
136 s32 delta_g;
137 struct iwl_chain_noise_data *data = &priv->chain_noise_data;
138
139 /* Find Gain Code for the antennas B and C */
140 for (i = 1; i < NUM_RX_CHAINS; i++) {
141 if ((data->disconn_array[i])) {
142 data->delta_gain_code[i] = 0;
143 continue;
144 }
145 delta_g = (1000 * ((s32)average_noise[0] -
146 (s32)average_noise[i])) / 1500;
147 /* bound gain by 2 bits value max, 3rd bit is sign */
148 data->delta_gain_code[i] =
149 min(abs(delta_g), CHAIN_NOISE_MAX_DELTA_GAIN_CODE);
150
151 if (delta_g < 0)
152 /* set negative sign */
153 data->delta_gain_code[i] |= (1 << 2);
154 }
155
156 IWL_DEBUG_CALIB("Delta gains: ANT_B = %d ANT_C = %d\n",
157 data->delta_gain_code[1], data->delta_gain_code[2]);
158
159 if (!data->radio_write) {
160 struct iwl5000_calibration_chain_noise_gain_cmd cmd;
161 memset(&cmd, 0, sizeof(cmd));
162
163 cmd.op_code = IWL5000_PHY_CALIBRATE_CHAIN_NOISE_GAIN_CMD;
164 cmd.delta_gain_1 = data->delta_gain_code[1];
165 cmd.delta_gain_2 = data->delta_gain_code[2];
166 iwl_send_cmd_pdu_async(priv, REPLY_PHY_CALIBRATION_CMD,
167 sizeof(cmd), &cmd, NULL);
168
169 data->radio_write = 1;
170 data->state = IWL_CHAIN_NOISE_CALIBRATED;
171 }
172
173 data->chain_noise_a = 0;
174 data->chain_noise_b = 0;
175 data->chain_noise_c = 0;
176 data->chain_signal_a = 0;
177 data->chain_signal_b = 0;
178 data->chain_signal_c = 0;
179 data->beacon_count = 0;
180}
181
182static void iwl5000_chain_noise_reset(struct iwl_priv *priv)
183{
184 struct iwl_chain_noise_data *data = &priv->chain_noise_data;
185
186 if ((data->state == IWL_CHAIN_NOISE_ALIVE) && iwl_is_associated(priv)) {
187 struct iwl5000_calibration_chain_noise_reset_cmd cmd;
188
189 memset(&cmd, 0, sizeof(cmd));
190 cmd.op_code = IWL5000_PHY_CALIBRATE_CHAIN_NOISE_RESET_CMD;
191 if (iwl_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD,
192 sizeof(cmd), &cmd))
193 IWL_ERROR("Could not send REPLY_PHY_CALIBRATION_CMD\n");
194 data->state = IWL_CHAIN_NOISE_ACCUMULATE;
195 IWL_DEBUG_CALIB("Run chain_noise_calibrate\n");
196 }
197}
198
199static struct iwl_sensitivity_ranges iwl5000_sensitivity = {
200 .min_nrg_cck = 95,
201 .max_nrg_cck = 0,
202 .auto_corr_min_ofdm = 90,
203 .auto_corr_min_ofdm_mrc = 170,
204 .auto_corr_min_ofdm_x1 = 120,
205 .auto_corr_min_ofdm_mrc_x1 = 240,
206
207 .auto_corr_max_ofdm = 120,
208 .auto_corr_max_ofdm_mrc = 210,
209 .auto_corr_max_ofdm_x1 = 155,
210 .auto_corr_max_ofdm_mrc_x1 = 290,
211
212 .auto_corr_min_cck = 125,
213 .auto_corr_max_cck = 200,
214 .auto_corr_min_cck_mrc = 170,
215 .auto_corr_max_cck_mrc = 400,
216 .nrg_th_cck = 95,
217 .nrg_th_ofdm = 95,
218};
219
220#endif /* CONFIG_IWL5000_RUN_TIME_CALIB */
221
128static const u8 *iwl5000_eeprom_query_addr(const struct iwl_priv *priv, 222static const u8 *iwl5000_eeprom_query_addr(const struct iwl_priv *priv,
129 size_t offset) 223 size_t offset)
130{ 224{
@@ -159,6 +253,9 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
159 priv->hw_params.max_bsm_size = BSM_SRAM_SIZE; 253 priv->hw_params.max_bsm_size = BSM_SRAM_SIZE;
160 priv->hw_params.fat_channel = BIT(IEEE80211_BAND_2GHZ) | 254 priv->hw_params.fat_channel = BIT(IEEE80211_BAND_2GHZ) |
161 BIT(IEEE80211_BAND_5GHZ); 255 BIT(IEEE80211_BAND_5GHZ);
256#ifdef CONFIG_IWL5000_RUN_TIME_CALIB
257 priv->hw_params.sens = &iwl5000_sensitivity;
258#endif
162 259
163 switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) { 260 switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) {
164 case CSR_HW_REV_TYPE_5100: 261 case CSR_HW_REV_TYPE_5100:
@@ -202,6 +299,10 @@ static struct iwl_hcmd_ops iwl5000_hcmd = {
202}; 299};
203 300
204static struct iwl_hcmd_utils_ops iwl5000_hcmd_utils = { 301static struct iwl_hcmd_utils_ops iwl5000_hcmd_utils = {
302#ifdef CONFIG_IWL5000_RUN_TIME_CALIB
303 .gain_computation = iwl5000_gain_computation,
304 .chain_noise_reset = iwl5000_chain_noise_reset,
305#endif
205}; 306};
206 307
207static struct iwl_lib_ops iwl5000_lib = { 308static struct iwl_lib_ops iwl5000_lib = {