diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-5000.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-5000.c | 101 |
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 | |||
130 | static 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 | |||
182 | static 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 | |||
199 | static 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 | |||
128 | static const u8 *iwl5000_eeprom_query_addr(const struct iwl_priv *priv, | 222 | static 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 | ||
204 | static struct iwl_hcmd_utils_ops iwl5000_hcmd_utils = { | 301 | static 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 | ||
207 | static struct iwl_lib_ops iwl5000_lib = { | 308 | static struct iwl_lib_ops iwl5000_lib = { |