~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise-security

« back to all changes in this revision

Viewing changes to drivers/net/wireless/iwlwifi/iwl-5000.c

  • Committer: Package Import Robot
  • Author(s): Paolo Pisati, Paolo Pisati
  • Date: 2011-12-06 15:56:07 UTC
  • Revision ID: package-import@ubuntu.com-20111206155607-pcf44kv5fmhk564f
Tags: 3.2.0-1401.1
[ Paolo Pisati ]

* Rebased on top of Ubuntu-3.2.0-3.8
* Tilt-tracking @ ef2487af4bb15bdd0689631774b5a5e3a59f74e2
* Delete debian.ti-omap4/control, it shoudln't be tracked
* Fix architecture spelling (s/armel/armhf/)
* [Config] Update configs following 3.2 import
* [Config] Fix compilation: disable CODA and ARCH_OMAP3
* [Config] Fix compilation: disable Ethernet Faraday
* Update series to precise

Show diffs side-by-side

added added

removed removed

Lines of Context:
27
27
#include <linux/kernel.h>
28
28
#include <linux/module.h>
29
29
#include <linux/init.h>
30
 
#include <linux/pci.h>
31
 
#include <linux/dma-mapping.h>
32
30
#include <linux/delay.h>
33
31
#include <linux/sched.h>
34
32
#include <linux/skbuff.h>
35
33
#include <linux/netdevice.h>
36
 
#include <linux/wireless.h>
37
34
#include <net/mac80211.h>
38
35
#include <linux/etherdevice.h>
39
36
#include <asm/unaligned.h>
43
40
#include "iwl-dev.h"
44
41
#include "iwl-core.h"
45
42
#include "iwl-io.h"
46
 
#include "iwl-sta.h"
47
 
#include "iwl-helpers.h"
48
43
#include "iwl-agn.h"
49
44
#include "iwl-agn-hw.h"
50
 
#include "iwl-5000-hw.h"
 
45
#include "iwl-trans.h"
 
46
#include "iwl-shared.h"
 
47
#include "iwl-cfg.h"
51
48
 
52
49
/* Highest firmware API version supported */
53
50
#define IWL5000_UCODE_API_MAX 5
67
64
static void iwl5000_nic_config(struct iwl_priv *priv)
68
65
{
69
66
        unsigned long flags;
70
 
        u16 radio_cfg;
71
 
 
72
 
        spin_lock_irqsave(&priv->lock, flags);
73
 
 
74
 
        radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG);
75
 
 
76
 
        /* write radio config values to register */
77
 
        if (EEPROM_RF_CFG_TYPE_MSK(radio_cfg) < EEPROM_RF_CONFIG_TYPE_MAX)
78
 
                iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
79
 
                            EEPROM_RF_CFG_TYPE_MSK(radio_cfg) |
80
 
                            EEPROM_RF_CFG_STEP_MSK(radio_cfg) |
81
 
                            EEPROM_RF_CFG_DASH_MSK(radio_cfg));
82
 
 
83
 
        /* set CSR_HW_CONFIG_REG for uCode use */
84
 
        iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
85
 
                    CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI |
86
 
                    CSR_HW_IF_CONFIG_REG_BIT_MAC_SI);
 
67
 
 
68
        iwl_rf_config(priv);
 
69
 
 
70
        spin_lock_irqsave(&priv->shrd->lock, flags);
87
71
 
88
72
        /* W/A : NIC is stuck in a reset state after Early PCIe power off
89
73
         * (PCIe power is lost before PERST# is asserted),
90
74
         * causing ME FW to lose ownership and not being able to obtain it back.
91
75
         */
92
 
        iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
 
76
        iwl_set_bits_mask_prph(bus(priv), APMG_PS_CTRL_REG,
93
77
                                APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS,
94
78
                                ~APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS);
95
79
 
96
80
 
97
 
        spin_unlock_irqrestore(&priv->lock, flags);
 
81
        spin_unlock_irqrestore(&priv->shrd->lock, flags);
98
82
}
99
83
 
100
84
static struct iwl_sensitivity_ranges iwl5000_sensitivity = {
101
 
        .min_nrg_cck = 95,
 
85
        .min_nrg_cck = 100,
102
86
        .max_nrg_cck = 0, /* not used, set to 0 */
103
87
        .auto_corr_min_ofdm = 90,
104
88
        .auto_corr_min_ofdm_mrc = 170,
105
 
        .auto_corr_min_ofdm_x1 = 120,
106
 
        .auto_corr_min_ofdm_mrc_x1 = 240,
 
89
        .auto_corr_min_ofdm_x1 = 105,
 
90
        .auto_corr_min_ofdm_mrc_x1 = 220,
107
91
 
108
92
        .auto_corr_max_ofdm = 120,
109
93
        .auto_corr_max_ofdm_mrc = 210,
112
96
 
113
97
        .auto_corr_min_cck = 125,
114
98
        .auto_corr_max_cck = 200,
115
 
        .auto_corr_min_cck_mrc = 170,
 
99
        .auto_corr_min_cck_mrc = 200,
116
100
        .auto_corr_max_cck_mrc = 400,
117
 
        .nrg_th_cck = 95,
118
 
        .nrg_th_ofdm = 95,
 
101
        .nrg_th_cck = 100,
 
102
        .nrg_th_ofdm = 100,
119
103
 
120
104
        .barker_corr_th_min = 190,
121
105
        .barker_corr_th_min_mrc = 390,
148
132
        .nrg_th_cca = 62,
149
133
};
150
134
 
 
135
#define IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF   (-5)
 
136
 
 
137
static s32 iwl_temp_calib_to_offset(struct iwl_priv *priv)
 
138
{
 
139
        u16 temperature, voltage;
 
140
        __le16 *temp_calib = (__le16 *)iwl_eeprom_query_addr(priv,
 
141
                                EEPROM_KELVIN_TEMPERATURE);
 
142
 
 
143
        temperature = le16_to_cpu(temp_calib[0]);
 
144
        voltage = le16_to_cpu(temp_calib[1]);
 
145
 
 
146
        /* offset = temp - volt / coeff */
 
147
        return (s32)(temperature - voltage / IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF);
 
148
}
 
149
 
151
150
static void iwl5150_set_ct_threshold(struct iwl_priv *priv)
152
151
{
153
152
        const s32 volt2temp_coef = IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF;
154
153
        s32 threshold = (s32)CELSIUS_TO_KELVIN(CT_KILL_THRESHOLD_LEGACY) -
155
154
                        iwl_temp_calib_to_offset(priv);
156
155
 
157
 
        priv->hw_params.ct_kill_threshold = threshold * volt2temp_coef;
 
156
        hw_params(priv).ct_kill_threshold = threshold * volt2temp_coef;
158
157
}
159
158
 
160
159
static void iwl5000_set_ct_threshold(struct iwl_priv *priv)
161
160
{
162
161
        /* want Celsius */
163
 
        priv->hw_params.ct_kill_threshold = CT_KILL_THRESHOLD_LEGACY;
 
162
        hw_params(priv).ct_kill_threshold = CT_KILL_THRESHOLD_LEGACY;
164
163
}
165
164
 
166
165
static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
170
169
                priv->cfg->base_params->num_of_queues =
171
170
                        iwlagn_mod_params.num_of_queues;
172
171
 
173
 
        priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues;
174
 
        priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM;
175
 
        priv->hw_params.scd_bc_tbls_size =
176
 
                        priv->cfg->base_params->num_of_queues *
177
 
                        sizeof(struct iwlagn_scd_bc_tbl);
178
 
        priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
179
 
        priv->hw_params.max_stations = IWLAGN_STATION_COUNT;
 
172
        hw_params(priv).max_txq_num = priv->cfg->base_params->num_of_queues;
180
173
        priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID;
181
174
 
182
 
        priv->hw_params.max_data_size = IWLAGN_RTC_DATA_SIZE;
183
 
        priv->hw_params.max_inst_size = IWLAGN_RTC_INST_SIZE;
 
175
        hw_params(priv).max_data_size = IWLAGN_RTC_DATA_SIZE;
 
176
        hw_params(priv).max_inst_size = IWLAGN_RTC_INST_SIZE;
184
177
 
185
 
        priv->hw_params.ht40_channel =  BIT(IEEE80211_BAND_2GHZ) |
 
178
        hw_params(priv).ht40_channel =  BIT(IEEE80211_BAND_2GHZ) |
186
179
                                        BIT(IEEE80211_BAND_5GHZ);
187
 
        priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR;
188
180
 
189
 
        priv->hw_params.tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant);
190
 
        priv->hw_params.rx_chains_num = num_of_ant(priv->cfg->valid_rx_ant);
191
 
        priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant;
192
 
        priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant;
 
181
        hw_params(priv).tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant);
 
182
        hw_params(priv).rx_chains_num = num_of_ant(priv->cfg->valid_rx_ant);
 
183
        hw_params(priv).valid_tx_ant = priv->cfg->valid_tx_ant;
 
184
        hw_params(priv).valid_rx_ant = priv->cfg->valid_rx_ant;
193
185
 
194
186
        iwl5000_set_ct_threshold(priv);
195
187
 
196
188
        /* Set initial sensitivity parameters */
197
189
        /* Set initial calibration set */
198
 
        priv->hw_params.sens = &iwl5000_sensitivity;
199
 
        priv->hw_params.calib_init_cfg =
 
190
        hw_params(priv).sens = &iwl5000_sensitivity;
 
191
        hw_params(priv).calib_init_cfg =
200
192
                BIT(IWL_CALIB_XTAL)             |
201
193
                BIT(IWL_CALIB_LO)               |
202
194
                BIT(IWL_CALIB_TX_IQ)            |
203
195
                BIT(IWL_CALIB_TX_IQ_PERD)       |
204
196
                BIT(IWL_CALIB_BASE_BAND);
205
197
 
206
 
        priv->hw_params.beacon_time_tsf_bits = IWLAGN_EXT_BEACON_TIME_POS;
207
 
 
208
198
        return 0;
209
199
}
210
200
 
215
205
                priv->cfg->base_params->num_of_queues =
216
206
                        iwlagn_mod_params.num_of_queues;
217
207
 
218
 
        priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues;
219
 
        priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM;
220
 
        priv->hw_params.scd_bc_tbls_size =
221
 
                        priv->cfg->base_params->num_of_queues *
222
 
                        sizeof(struct iwlagn_scd_bc_tbl);
223
 
        priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
224
 
        priv->hw_params.max_stations = IWLAGN_STATION_COUNT;
 
208
        hw_params(priv).max_txq_num = priv->cfg->base_params->num_of_queues;
225
209
        priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID;
226
210
 
227
 
        priv->hw_params.max_data_size = IWLAGN_RTC_DATA_SIZE;
228
 
        priv->hw_params.max_inst_size = IWLAGN_RTC_INST_SIZE;
 
211
        hw_params(priv).max_data_size = IWLAGN_RTC_DATA_SIZE;
 
212
        hw_params(priv).max_inst_size = IWLAGN_RTC_INST_SIZE;
229
213
 
230
 
        priv->hw_params.ht40_channel =  BIT(IEEE80211_BAND_2GHZ) |
 
214
        hw_params(priv).ht40_channel =  BIT(IEEE80211_BAND_2GHZ) |
231
215
                                        BIT(IEEE80211_BAND_5GHZ);
232
 
        priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR;
233
216
 
234
 
        priv->hw_params.tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant);
235
 
        priv->hw_params.rx_chains_num = num_of_ant(priv->cfg->valid_rx_ant);
236
 
        priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant;
237
 
        priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant;
 
217
        hw_params(priv).tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant);
 
218
        hw_params(priv).rx_chains_num = num_of_ant(priv->cfg->valid_rx_ant);
 
219
        hw_params(priv).valid_tx_ant = priv->cfg->valid_tx_ant;
 
220
        hw_params(priv).valid_rx_ant = priv->cfg->valid_rx_ant;
238
221
 
239
222
        iwl5150_set_ct_threshold(priv);
240
223
 
241
224
        /* Set initial sensitivity parameters */
242
225
        /* Set initial calibration set */
243
 
        priv->hw_params.sens = &iwl5150_sensitivity;
244
 
        priv->hw_params.calib_init_cfg =
 
226
        hw_params(priv).sens = &iwl5150_sensitivity;
 
227
        hw_params(priv).calib_init_cfg =
245
228
                BIT(IWL_CALIB_LO)               |
246
229
                BIT(IWL_CALIB_TX_IQ)            |
247
230
                BIT(IWL_CALIB_BASE_BAND);
248
231
        if (priv->cfg->need_dc_calib)
249
 
                priv->hw_params.calib_init_cfg |= BIT(IWL_CALIB_DC);
250
 
 
251
 
        priv->hw_params.beacon_time_tsf_bits = IWLAGN_EXT_BEACON_TIME_POS;
 
232
                hw_params(priv).calib_init_cfg |= BIT(IWL_CALIB_DC);
252
233
 
253
234
        return 0;
254
235
}
270
251
{
271
252
        /*
272
253
         * MULTI-FIXME
273
 
         * See iwl_mac_channel_switch.
 
254
         * See iwlagn_mac_channel_switch.
274
255
         */
275
256
        struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
276
257
        struct iwl5000_channel_switch_cmd cmd;
333
314
                return -EFAULT;
334
315
        }
335
316
 
336
 
        return iwl_send_cmd_sync(priv, &hcmd);
 
317
        return iwl_trans_send_cmd(trans(priv), &hcmd);
337
318
}
338
319
 
339
320
static struct iwl_lib_ops iwl5000_lib = {
340
321
        .set_hw_params = iwl5000_hw_set_hw_params,
341
 
        .rx_handler_setup = iwlagn_rx_handler_setup,
342
 
        .setup_deferred_work = iwlagn_setup_deferred_work,
343
 
        .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
344
 
        .send_tx_power = iwlagn_send_tx_power,
345
 
        .update_chain_flags = iwl_update_chain_flags,
346
322
        .set_channel_switch = iwl5000_hw_channel_switch,
347
 
        .apm_ops = {
348
 
                .init = iwl_apm_init,
349
 
                .config = iwl5000_nic_config,
350
 
        },
 
323
        .nic_config = iwl5000_nic_config,
351
324
        .eeprom_ops = {
352
325
                .regulatory_bands = {
353
326
                        EEPROM_REG_BAND_1_CHANNELS,
358
331
                        EEPROM_REG_BAND_24_HT40_CHANNELS,
359
332
                        EEPROM_REG_BAND_52_HT40_CHANNELS
360
333
                },
361
 
                .query_addr = iwlagn_eeprom_query_addr,
362
334
        },
363
 
        .temp_ops = {
364
 
                .temperature = iwlagn_temperature,
365
 
         },
366
 
        .txfifo_flush = iwlagn_txfifo_flush,
367
 
        .dev_txfifo_flush = iwlagn_dev_txfifo_flush,
 
335
        .temperature = iwlagn_temperature,
368
336
};
369
337
 
370
338
static struct iwl_lib_ops iwl5150_lib = {
371
339
        .set_hw_params = iwl5150_hw_set_hw_params,
372
 
        .rx_handler_setup = iwlagn_rx_handler_setup,
373
 
        .setup_deferred_work = iwlagn_setup_deferred_work,
374
 
        .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
375
 
        .send_tx_power = iwlagn_send_tx_power,
376
 
        .update_chain_flags = iwl_update_chain_flags,
377
340
        .set_channel_switch = iwl5000_hw_channel_switch,
378
 
        .apm_ops = {
379
 
                .init = iwl_apm_init,
380
 
                .config = iwl5000_nic_config,
381
 
        },
 
341
        .nic_config = iwl5000_nic_config,
382
342
        .eeprom_ops = {
383
343
                .regulatory_bands = {
384
344
                        EEPROM_REG_BAND_1_CHANNELS,
389
349
                        EEPROM_REG_BAND_24_HT40_CHANNELS,
390
350
                        EEPROM_REG_BAND_52_HT40_CHANNELS
391
351
                },
392
 
                .query_addr = iwlagn_eeprom_query_addr,
393
352
        },
394
 
        .temp_ops = {
395
 
                .temperature = iwl5150_temperature,
396
 
         },
397
 
        .txfifo_flush = iwlagn_txfifo_flush,
398
 
        .dev_txfifo_flush = iwlagn_dev_txfifo_flush,
399
 
};
400
 
 
401
 
static const struct iwl_ops iwl5000_ops = {
402
 
        .lib = &iwl5000_lib,
403
 
        .hcmd = &iwlagn_hcmd,
404
 
        .utils = &iwlagn_hcmd_utils,
405
 
};
406
 
 
407
 
static const struct iwl_ops iwl5150_ops = {
408
 
        .lib = &iwl5150_lib,
409
 
        .hcmd = &iwlagn_hcmd,
410
 
        .utils = &iwlagn_hcmd_utils,
 
353
        .temperature = iwl5150_temperature,
411
354
};
412
355
 
413
356
static struct iwl_base_params iwl5000_base_params = {
416
359
        .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
417
360
        .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
418
361
        .led_compensation = 51,
419
 
        .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
420
362
        .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
421
363
        .chain_noise_scale = 1000,
422
364
        .wd_timeout = IWL_LONG_WD_TIMEOUT,
433
375
        .ucode_api_min = IWL5000_UCODE_API_MIN,                 \
434
376
        .eeprom_ver = EEPROM_5000_EEPROM_VERSION,               \
435
377
        .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,       \
436
 
        .ops = &iwl5000_ops,                                    \
 
378
        .lib = &iwl5000_lib,                                    \
437
379
        .base_params = &iwl5000_base_params,                    \
438
380
        .led_mode = IWL_LED_BLINK
439
381
 
476
418
        .ucode_api_min = IWL5000_UCODE_API_MIN,
477
419
        .eeprom_ver = EEPROM_5050_EEPROM_VERSION,
478
420
        .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,
479
 
        .ops = &iwl5000_ops,
 
421
        .lib = &iwl5000_lib,
480
422
        .base_params = &iwl5000_base_params,
481
423
        .ht_params = &iwl5000_ht_params,
482
424
        .led_mode = IWL_LED_BLINK,
489
431
        .ucode_api_min = IWL5150_UCODE_API_MIN,                 \
490
432
        .eeprom_ver = EEPROM_5050_EEPROM_VERSION,               \
491
433
        .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,       \
492
 
        .ops = &iwl5150_ops,                                    \
 
434
        .lib = &iwl5150_lib,                                    \
493
435
        .base_params = &iwl5000_base_params,                    \
494
436
        .need_dc_calib = true,                                  \
495
437
        .led_mode = IWL_LED_BLINK,                              \