aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlwifi')
-rw-r--r--drivers/net/wireless/iwlwifi/Makefile2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-1000.c112
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-2000.c116
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c268
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c219
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-devices.c682
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rx.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c40
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.h10
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-config.h3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h15
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h16
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.c8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-mac80211.c4
14 files changed, 763 insertions, 736 deletions
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile
index c7c4a995dfe5..f2cd67874cf4 100644
--- a/drivers/net/wireless/iwlwifi/Makefile
+++ b/drivers/net/wireless/iwlwifi/Makefile
@@ -7,7 +7,7 @@ iwlwifi-objs += iwl-agn-tt.o iwl-agn-sta.o iwl-agn-rx.o
7 7
8iwlwifi-objs += iwl-core.o iwl-eeprom.o iwl-power.o 8iwlwifi-objs += iwl-core.o iwl-eeprom.o iwl-power.o
9iwlwifi-objs += iwl-scan.o iwl-led.o 9iwlwifi-objs += iwl-scan.o iwl-led.o
10iwlwifi-objs += iwl-agn-rxon.o 10iwlwifi-objs += iwl-agn-rxon.o iwl-agn-devices.o
11iwlwifi-objs += iwl-5000.o 11iwlwifi-objs += iwl-5000.o
12iwlwifi-objs += iwl-6000.o 12iwlwifi-objs += iwl-6000.o
13iwlwifi-objs += iwl-1000.o 13iwlwifi-objs += iwl-1000.o
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index 66f86c8e060f..e9006078f4e2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -24,26 +24,11 @@
24 * 24 *
25 *****************************************************************************/ 25 *****************************************************************************/
26 26
27#include <linux/kernel.h>
28#include <linux/module.h> 27#include <linux/module.h>
29#include <linux/init.h>
30#include <linux/delay.h>
31#include <linux/skbuff.h>
32#include <linux/netdevice.h>
33#include <net/mac80211.h>
34#include <linux/etherdevice.h>
35#include <asm/unaligned.h>
36#include <linux/stringify.h> 28#include <linux/stringify.h>
37 29#include "iwl-config.h"
38#include "iwl-eeprom.h"
39#include "iwl-dev.h"
40#include "iwl-core.h"
41#include "iwl-io.h"
42#include "iwl-agn.h"
43#include "iwl-agn-hw.h"
44#include "iwl-shared.h"
45#include "iwl-cfg.h" 30#include "iwl-cfg.h"
46#include "iwl-prph.h" 31#include "iwl-dev.h" /* still needed */
47 32
48/* Highest firmware API version supported */ 33/* Highest firmware API version supported */
49#define IWL1000_UCODE_API_MAX 6 34#define IWL1000_UCODE_API_MAX 6
@@ -64,97 +49,6 @@
64#define IWL100_MODULE_FIRMWARE(api) IWL100_FW_PRE __stringify(api) ".ucode" 49#define IWL100_MODULE_FIRMWARE(api) IWL100_FW_PRE __stringify(api) ".ucode"
65 50
66 51
67/*
68 * For 1000, use advance thermal throttling critical temperature threshold,
69 * but legacy thermal management implementation for now.
70 * This is for the reason of 1000 uCode using advance thermal throttling API
71 * but not implement ct_kill_exit based on ct_kill exit temperature
72 * so the thermal throttling will still based on legacy thermal throttling
73 * management.
74 * The code here need to be modified once 1000 uCode has the advanced thermal
75 * throttling algorithm in place
76 */
77static void iwl1000_set_ct_threshold(struct iwl_priv *priv)
78{
79 /* want Celsius */
80 priv->hw_params.ct_kill_threshold = CT_KILL_THRESHOLD_LEGACY;
81 priv->hw_params.ct_kill_exit_threshold = CT_KILL_EXIT_THRESHOLD;
82}
83
84/* NIC configuration for 1000 series */
85static void iwl1000_nic_config(struct iwl_priv *priv)
86{
87 /* set CSR_HW_CONFIG_REG for uCode use */
88 iwl_set_bit(trans(priv), CSR_HW_IF_CONFIG_REG,
89 CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI |
90 CSR_HW_IF_CONFIG_REG_BIT_MAC_SI);
91
92 /* Setting digital SVR for 1000 card to 1.32V */
93 /* locking is acquired in iwl_set_bits_mask_prph() function */
94 iwl_set_bits_mask_prph(trans(priv), APMG_DIGITAL_SVR_REG,
95 APMG_SVR_DIGITAL_VOLTAGE_1_32,
96 ~APMG_SVR_VOLTAGE_CONFIG_BIT_MSK);
97}
98
99static const struct iwl_sensitivity_ranges iwl1000_sensitivity = {
100 .min_nrg_cck = 95,
101 .auto_corr_min_ofdm = 90,
102 .auto_corr_min_ofdm_mrc = 170,
103 .auto_corr_min_ofdm_x1 = 120,
104 .auto_corr_min_ofdm_mrc_x1 = 240,
105
106 .auto_corr_max_ofdm = 120,
107 .auto_corr_max_ofdm_mrc = 210,
108 .auto_corr_max_ofdm_x1 = 155,
109 .auto_corr_max_ofdm_mrc_x1 = 290,
110
111 .auto_corr_min_cck = 125,
112 .auto_corr_max_cck = 200,
113 .auto_corr_min_cck_mrc = 170,
114 .auto_corr_max_cck_mrc = 400,
115 .nrg_th_cck = 95,
116 .nrg_th_ofdm = 95,
117
118 .barker_corr_th_min = 190,
119 .barker_corr_th_min_mrc = 390,
120 .nrg_th_cca = 62,
121};
122
123static void iwl1000_hw_set_hw_params(struct iwl_priv *priv)
124{
125 priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ);
126
127 priv->hw_params.tx_chains_num =
128 num_of_ant(priv->hw_params.valid_tx_ant);
129 if (cfg(priv)->rx_with_siso_diversity)
130 priv->hw_params.rx_chains_num = 1;
131 else
132 priv->hw_params.rx_chains_num =
133 num_of_ant(priv->hw_params.valid_rx_ant);
134
135 iwl1000_set_ct_threshold(priv);
136
137 /* Set initial sensitivity parameters */
138 priv->hw_params.sens = &iwl1000_sensitivity;
139}
140
141static struct iwl_lib_ops iwl1000_lib = {
142 .set_hw_params = iwl1000_hw_set_hw_params,
143 .nic_config = iwl1000_nic_config,
144 .eeprom_ops = {
145 .regulatory_bands = {
146 EEPROM_REG_BAND_1_CHANNELS,
147 EEPROM_REG_BAND_2_CHANNELS,
148 EEPROM_REG_BAND_3_CHANNELS,
149 EEPROM_REG_BAND_4_CHANNELS,
150 EEPROM_REG_BAND_5_CHANNELS,
151 EEPROM_REG_BAND_24_HT40_CHANNELS,
152 EEPROM_REGULATORY_BAND_NO_HT40,
153 },
154 },
155 .temperature = iwlagn_temperature,
156};
157
158static const struct iwl_base_params iwl1000_base_params = { 52static const struct iwl_base_params iwl1000_base_params = {
159 .num_of_queues = IWLAGN_NUM_QUEUES, 53 .num_of_queues = IWLAGN_NUM_QUEUES,
160 .eeprom_size = OTP_LOW_IMAGE_SIZE, 54 .eeprom_size = OTP_LOW_IMAGE_SIZE,
@@ -185,7 +79,6 @@ static const struct iwl_ht_params iwl1000_ht_params = {
185 .max_data_size = IWLAGN_RTC_DATA_SIZE, \ 79 .max_data_size = IWLAGN_RTC_DATA_SIZE, \
186 .eeprom_ver = EEPROM_1000_EEPROM_VERSION, \ 80 .eeprom_ver = EEPROM_1000_EEPROM_VERSION, \
187 .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, \ 81 .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, \
188 .lib = &iwl1000_lib, \
189 .base_params = &iwl1000_base_params, \ 82 .base_params = &iwl1000_base_params, \
190 .led_mode = IWL_LED_BLINK 83 .led_mode = IWL_LED_BLINK
191 84
@@ -210,7 +103,6 @@ const struct iwl_cfg iwl1000_bg_cfg = {
210 .max_data_size = IWLAGN_RTC_DATA_SIZE, \ 103 .max_data_size = IWLAGN_RTC_DATA_SIZE, \
211 .eeprom_ver = EEPROM_1000_EEPROM_VERSION, \ 104 .eeprom_ver = EEPROM_1000_EEPROM_VERSION, \
212 .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, \ 105 .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, \
213 .lib = &iwl1000_lib, \
214 .base_params = &iwl1000_base_params, \ 106 .base_params = &iwl1000_base_params, \
215 .led_mode = IWL_LED_RF_STATE, \ 107 .led_mode = IWL_LED_RF_STATE, \
216 .rx_with_siso_diversity = true 108 .rx_with_siso_diversity = true
diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c
index cedec4303f34..3d4a36cf0408 100644
--- a/drivers/net/wireless/iwlwifi/iwl-2000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-2000.c
@@ -24,25 +24,11 @@
24 * 24 *
25 *****************************************************************************/ 25 *****************************************************************************/
26 26
27#include <linux/kernel.h>
28#include <linux/module.h> 27#include <linux/module.h>
29#include <linux/init.h>
30#include <linux/delay.h>
31#include <linux/skbuff.h>
32#include <linux/netdevice.h>
33#include <net/mac80211.h>
34#include <linux/etherdevice.h>
35#include <asm/unaligned.h>
36#include <linux/stringify.h> 28#include <linux/stringify.h>
37 29#include "iwl-config.h"
38#include "iwl-eeprom.h"
39#include "iwl-dev.h"
40#include "iwl-core.h"
41#include "iwl-io.h"
42#include "iwl-agn.h"
43#include "iwl-agn-hw.h"
44#include "iwl-shared.h"
45#include "iwl-cfg.h" 30#include "iwl-cfg.h"
31#include "iwl-dev.h" /* still needed */
46 32
47/* Highest firmware API version supported */ 33/* Highest firmware API version supported */
48#define IWL2030_UCODE_API_MAX 6 34#define IWL2030_UCODE_API_MAX 6
@@ -74,100 +60,6 @@
74#define IWL135_FW_PRE "iwlwifi-135-" 60#define IWL135_FW_PRE "iwlwifi-135-"
75#define IWL135_MODULE_FIRMWARE(api) IWL135_FW_PRE __stringify(api) ".ucode" 61#define IWL135_MODULE_FIRMWARE(api) IWL135_FW_PRE __stringify(api) ".ucode"
76 62
77static void iwl2000_set_ct_threshold(struct iwl_priv *priv)
78{
79 /* want Celsius */
80 priv->hw_params.ct_kill_threshold = CT_KILL_THRESHOLD;
81 priv->hw_params.ct_kill_exit_threshold = CT_KILL_EXIT_THRESHOLD;
82}
83
84/* NIC configuration for 2000 series */
85static void iwl2000_nic_config(struct iwl_priv *priv)
86{
87 iwl_rf_config(priv);
88
89 iwl_set_bit(trans(priv), CSR_GP_DRIVER_REG,
90 CSR_GP_DRIVER_REG_BIT_RADIO_IQ_INVER);
91}
92
93static const struct iwl_sensitivity_ranges iwl2000_sensitivity = {
94 .min_nrg_cck = 97,
95 .auto_corr_min_ofdm = 80,
96 .auto_corr_min_ofdm_mrc = 128,
97 .auto_corr_min_ofdm_x1 = 105,
98 .auto_corr_min_ofdm_mrc_x1 = 192,
99
100 .auto_corr_max_ofdm = 145,
101 .auto_corr_max_ofdm_mrc = 232,
102 .auto_corr_max_ofdm_x1 = 110,
103 .auto_corr_max_ofdm_mrc_x1 = 232,
104
105 .auto_corr_min_cck = 125,
106 .auto_corr_max_cck = 175,
107 .auto_corr_min_cck_mrc = 160,
108 .auto_corr_max_cck_mrc = 310,
109 .nrg_th_cck = 97,
110 .nrg_th_ofdm = 100,
111
112 .barker_corr_th_min = 190,
113 .barker_corr_th_min_mrc = 390,
114 .nrg_th_cca = 62,
115};
116
117static void iwl2000_hw_set_hw_params(struct iwl_priv *priv)
118{
119 priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ);
120
121 priv->hw_params.tx_chains_num =
122 num_of_ant(priv->hw_params.valid_tx_ant);
123 if (cfg(priv)->rx_with_siso_diversity)
124 priv->hw_params.rx_chains_num = 1;
125 else
126 priv->hw_params.rx_chains_num =
127 num_of_ant(priv->hw_params.valid_rx_ant);
128
129 iwl2000_set_ct_threshold(priv);
130
131 /* Set initial sensitivity parameters */
132 priv->hw_params.sens = &iwl2000_sensitivity;
133}
134
135static struct iwl_lib_ops iwl2000_lib = {
136 .set_hw_params = iwl2000_hw_set_hw_params,
137 .nic_config = iwl2000_nic_config,
138 .eeprom_ops = {
139 .regulatory_bands = {
140 EEPROM_REG_BAND_1_CHANNELS,
141 EEPROM_REG_BAND_2_CHANNELS,
142 EEPROM_REG_BAND_3_CHANNELS,
143 EEPROM_REG_BAND_4_CHANNELS,
144 EEPROM_REG_BAND_5_CHANNELS,
145 EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
146 EEPROM_REGULATORY_BAND_NO_HT40,
147 },
148 .enhanced_txpower = true,
149 },
150 .temperature = iwlagn_temperature,
151};
152
153static struct iwl_lib_ops iwl2030_lib = {
154 .set_hw_params = iwl2000_hw_set_hw_params,
155 .nic_config = iwl2000_nic_config,
156 .eeprom_ops = {
157 .regulatory_bands = {
158 EEPROM_REG_BAND_1_CHANNELS,
159 EEPROM_REG_BAND_2_CHANNELS,
160 EEPROM_REG_BAND_3_CHANNELS,
161 EEPROM_REG_BAND_4_CHANNELS,
162 EEPROM_REG_BAND_5_CHANNELS,
163 EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
164 EEPROM_REGULATORY_BAND_NO_HT40,
165 },
166 .enhanced_txpower = true,
167 },
168 .temperature = iwlagn_temperature,
169};
170
171static const struct iwl_base_params iwl2000_base_params = { 63static const struct iwl_base_params iwl2000_base_params = {
172 .eeprom_size = OTP_LOW_IMAGE_SIZE, 64 .eeprom_size = OTP_LOW_IMAGE_SIZE,
173 .num_of_queues = IWLAGN_NUM_QUEUES, 65 .num_of_queues = IWLAGN_NUM_QUEUES,
@@ -228,7 +120,6 @@ static const struct iwl_bt_params iwl2030_bt_params = {
228 .max_data_size = IWL60_RTC_DATA_SIZE, \ 120 .max_data_size = IWL60_RTC_DATA_SIZE, \
229 .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \ 121 .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \
230 .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ 122 .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \
231 .lib = &iwl2000_lib, \
232 .base_params = &iwl2000_base_params, \ 123 .base_params = &iwl2000_base_params, \
233 .need_temp_offset_calib = true, \ 124 .need_temp_offset_calib = true, \
234 .temp_offset_v2 = true, \ 125 .temp_offset_v2 = true, \
@@ -256,7 +147,6 @@ const struct iwl_cfg iwl2000_2bgn_d_cfg = {
256 .max_data_size = IWL60_RTC_DATA_SIZE, \ 147 .max_data_size = IWL60_RTC_DATA_SIZE, \
257 .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \ 148 .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \
258 .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ 149 .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \
259 .lib = &iwl2030_lib, \
260 .base_params = &iwl2030_base_params, \ 150 .base_params = &iwl2030_base_params, \
261 .bt_params = &iwl2030_bt_params, \ 151 .bt_params = &iwl2030_bt_params, \
262 .need_temp_offset_calib = true, \ 152 .need_temp_offset_calib = true, \
@@ -280,7 +170,6 @@ const struct iwl_cfg iwl2030_2bgn_cfg = {
280 .max_data_size = IWL60_RTC_DATA_SIZE, \ 170 .max_data_size = IWL60_RTC_DATA_SIZE, \
281 .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \ 171 .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \
282 .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ 172 .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \
283 .lib = &iwl2000_lib, \
284 .base_params = &iwl2000_base_params, \ 173 .base_params = &iwl2000_base_params, \
285 .need_temp_offset_calib = true, \ 174 .need_temp_offset_calib = true, \
286 .temp_offset_v2 = true, \ 175 .temp_offset_v2 = true, \
@@ -310,7 +199,6 @@ const struct iwl_cfg iwl105_bgn_d_cfg = {
310 .max_data_size = IWL60_RTC_DATA_SIZE, \ 199 .max_data_size = IWL60_RTC_DATA_SIZE, \
311 .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \ 200 .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \
312 .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ 201 .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \
313 .lib = &iwl2030_lib, \
314 .base_params = &iwl2030_base_params, \ 202 .base_params = &iwl2030_base_params, \
315 .bt_params = &iwl2030_bt_params, \ 203 .bt_params = &iwl2030_bt_params, \
316 .need_temp_offset_calib = true, \ 204 .need_temp_offset_calib = true, \
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index 55294a235d65..ffa9ac5fe086 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -24,28 +24,11 @@
24 * 24 *
25 *****************************************************************************/ 25 *****************************************************************************/
26 26
27#include <linux/kernel.h>
28#include <linux/module.h> 27#include <linux/module.h>
29#include <linux/init.h>
30#include <linux/delay.h>
31#include <linux/sched.h>
32#include <linux/skbuff.h>
33#include <linux/netdevice.h>
34#include <net/mac80211.h>
35#include <linux/etherdevice.h>
36#include <asm/unaligned.h>
37#include <linux/stringify.h> 28#include <linux/stringify.h>
38 29#include "iwl-config.h"
39#include "iwl-eeprom.h"
40#include "iwl-dev.h"
41#include "iwl-core.h"
42#include "iwl-io.h"
43#include "iwl-agn.h"
44#include "iwl-agn-hw.h"
45#include "iwl-trans.h"
46#include "iwl-shared.h"
47#include "iwl-cfg.h" 30#include "iwl-cfg.h"
48#include "iwl-prph.h" 31#include "iwl-dev.h" /* still needed */
49 32
50/* Highest firmware API version supported */ 33/* Highest firmware API version supported */
51#define IWL5000_UCODE_API_MAX 5 34#define IWL5000_UCODE_API_MAX 5
@@ -61,250 +44,6 @@
61#define IWL5150_FW_PRE "iwlwifi-5150-" 44#define IWL5150_FW_PRE "iwlwifi-5150-"
62#define IWL5150_MODULE_FIRMWARE(api) IWL5150_FW_PRE __stringify(api) ".ucode" 45#define IWL5150_MODULE_FIRMWARE(api) IWL5150_FW_PRE __stringify(api) ".ucode"
63 46
64/* NIC configuration for 5000 series */
65static void iwl5000_nic_config(struct iwl_priv *priv)
66{
67 iwl_rf_config(priv);
68
69 /* W/A : NIC is stuck in a reset state after Early PCIe power off
70 * (PCIe power is lost before PERST# is asserted),
71 * causing ME FW to lose ownership and not being able to obtain it back.
72 */
73 iwl_set_bits_mask_prph(trans(priv), APMG_PS_CTRL_REG,
74 APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS,
75 ~APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS);
76}
77
78static const struct iwl_sensitivity_ranges iwl5000_sensitivity = {
79 .min_nrg_cck = 100,
80 .auto_corr_min_ofdm = 90,
81 .auto_corr_min_ofdm_mrc = 170,
82 .auto_corr_min_ofdm_x1 = 105,
83 .auto_corr_min_ofdm_mrc_x1 = 220,
84
85 .auto_corr_max_ofdm = 120,
86 .auto_corr_max_ofdm_mrc = 210,
87 .auto_corr_max_ofdm_x1 = 120,
88 .auto_corr_max_ofdm_mrc_x1 = 240,
89
90 .auto_corr_min_cck = 125,
91 .auto_corr_max_cck = 200,
92 .auto_corr_min_cck_mrc = 200,
93 .auto_corr_max_cck_mrc = 400,
94 .nrg_th_cck = 100,
95 .nrg_th_ofdm = 100,
96
97 .barker_corr_th_min = 190,
98 .barker_corr_th_min_mrc = 390,
99 .nrg_th_cca = 62,
100};
101
102static struct iwl_sensitivity_ranges iwl5150_sensitivity = {
103 .min_nrg_cck = 95,
104 .auto_corr_min_ofdm = 90,
105 .auto_corr_min_ofdm_mrc = 170,
106 .auto_corr_min_ofdm_x1 = 105,
107 .auto_corr_min_ofdm_mrc_x1 = 220,
108
109 .auto_corr_max_ofdm = 120,
110 .auto_corr_max_ofdm_mrc = 210,
111 /* max = min for performance bug in 5150 DSP */
112 .auto_corr_max_ofdm_x1 = 105,
113 .auto_corr_max_ofdm_mrc_x1 = 220,
114
115 .auto_corr_min_cck = 125,
116 .auto_corr_max_cck = 200,
117 .auto_corr_min_cck_mrc = 170,
118 .auto_corr_max_cck_mrc = 400,
119 .nrg_th_cck = 95,
120 .nrg_th_ofdm = 95,
121
122 .barker_corr_th_min = 190,
123 .barker_corr_th_min_mrc = 390,
124 .nrg_th_cca = 62,
125};
126
127#define IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF (-5)
128
129static s32 iwl_temp_calib_to_offset(struct iwl_priv *priv)
130{
131 u16 temperature, voltage;
132 __le16 *temp_calib = (__le16 *)iwl_eeprom_query_addr(priv,
133 EEPROM_KELVIN_TEMPERATURE);
134
135 temperature = le16_to_cpu(temp_calib[0]);
136 voltage = le16_to_cpu(temp_calib[1]);
137
138 /* offset = temp - volt / coeff */
139 return (s32)(temperature - voltage / IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF);
140}
141
142static void iwl5150_set_ct_threshold(struct iwl_priv *priv)
143{
144 const s32 volt2temp_coef = IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF;
145 s32 threshold = (s32)CELSIUS_TO_KELVIN(CT_KILL_THRESHOLD_LEGACY) -
146 iwl_temp_calib_to_offset(priv);
147
148 priv->hw_params.ct_kill_threshold = threshold * volt2temp_coef;
149}
150
151static void iwl5000_set_ct_threshold(struct iwl_priv *priv)
152{
153 /* want Celsius */
154 priv->hw_params.ct_kill_threshold = CT_KILL_THRESHOLD_LEGACY;
155}
156
157static void iwl5000_hw_set_hw_params(struct iwl_priv *priv)
158{
159 priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) |
160 BIT(IEEE80211_BAND_5GHZ);
161
162 priv->hw_params.tx_chains_num =
163 num_of_ant(priv->hw_params.valid_tx_ant);
164 priv->hw_params.rx_chains_num =
165 num_of_ant(priv->hw_params.valid_rx_ant);
166
167 iwl5000_set_ct_threshold(priv);
168
169 /* Set initial sensitivity parameters */
170 priv->hw_params.sens = &iwl5000_sensitivity;
171}
172
173static void iwl5150_hw_set_hw_params(struct iwl_priv *priv)
174{
175 priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) |
176 BIT(IEEE80211_BAND_5GHZ);
177
178 priv->hw_params.tx_chains_num =
179 num_of_ant(priv->hw_params.valid_tx_ant);
180 priv->hw_params.rx_chains_num =
181 num_of_ant(priv->hw_params.valid_rx_ant);
182
183 iwl5150_set_ct_threshold(priv);
184
185 /* Set initial sensitivity parameters */
186 priv->hw_params.sens = &iwl5150_sensitivity;
187}
188
189static void iwl5150_temperature(struct iwl_priv *priv)
190{
191 u32 vt = 0;
192 s32 offset = iwl_temp_calib_to_offset(priv);
193
194 vt = le32_to_cpu(priv->statistics.common.temperature);
195 vt = vt / IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF + offset;
196 /* now vt hold the temperature in Kelvin */
197 priv->temperature = KELVIN_TO_CELSIUS(vt);
198 iwl_tt_handler(priv);
199}
200
201static int iwl5000_hw_channel_switch(struct iwl_priv *priv,
202 struct ieee80211_channel_switch *ch_switch)
203{
204 /*
205 * MULTI-FIXME
206 * See iwlagn_mac_channel_switch.
207 */
208 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
209 struct iwl5000_channel_switch_cmd cmd;
210 const struct iwl_channel_info *ch_info;
211 u32 switch_time_in_usec, ucode_switch_time;
212 u16 ch;
213 u32 tsf_low;
214 u8 switch_count;
215 u16 beacon_interval = le16_to_cpu(ctx->timing.beacon_interval);
216 struct ieee80211_vif *vif = ctx->vif;
217 struct iwl_host_cmd hcmd = {
218 .id = REPLY_CHANNEL_SWITCH,
219 .len = { sizeof(cmd), },
220 .flags = CMD_SYNC,
221 .data = { &cmd, },
222 };
223
224 cmd.band = priv->band == IEEE80211_BAND_2GHZ;
225 ch = ch_switch->channel->hw_value;
226 IWL_DEBUG_11H(priv, "channel switch from %d to %d\n",
227 ctx->active.channel, ch);
228 cmd.channel = cpu_to_le16(ch);
229 cmd.rxon_flags = ctx->staging.flags;
230 cmd.rxon_filter_flags = ctx->staging.filter_flags;
231 switch_count = ch_switch->count;
232 tsf_low = ch_switch->timestamp & 0x0ffffffff;
233 /*
234 * calculate the ucode channel switch time
235 * adding TSF as one of the factor for when to switch
236 */
237 if ((priv->ucode_beacon_time > tsf_low) && beacon_interval) {
238 if (switch_count > ((priv->ucode_beacon_time - tsf_low) /
239 beacon_interval)) {
240 switch_count -= (priv->ucode_beacon_time -
241 tsf_low) / beacon_interval;
242 } else
243 switch_count = 0;
244 }
245 if (switch_count <= 1)
246 cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time);
247 else {
248 switch_time_in_usec =
249 vif->bss_conf.beacon_int * switch_count * TIME_UNIT;
250 ucode_switch_time = iwl_usecs_to_beacons(priv,
251 switch_time_in_usec,
252 beacon_interval);
253 cmd.switch_time = iwl_add_beacon_time(priv,
254 priv->ucode_beacon_time,
255 ucode_switch_time,
256 beacon_interval);
257 }
258 IWL_DEBUG_11H(priv, "uCode time for the switch is 0x%x\n",
259 cmd.switch_time);
260 ch_info = iwl_get_channel_info(priv, priv->band, ch);
261 if (ch_info)
262 cmd.expect_beacon = is_channel_radar(ch_info);
263 else {
264 IWL_ERR(priv, "invalid channel switch from %u to %u\n",
265 ctx->active.channel, ch);
266 return -EFAULT;
267 }
268
269 return iwl_dvm_send_cmd(priv, &hcmd);
270}
271
272static struct iwl_lib_ops iwl5000_lib = {
273 .set_hw_params = iwl5000_hw_set_hw_params,
274 .set_channel_switch = iwl5000_hw_channel_switch,
275 .nic_config = iwl5000_nic_config,
276 .eeprom_ops = {
277 .regulatory_bands = {
278 EEPROM_REG_BAND_1_CHANNELS,
279 EEPROM_REG_BAND_2_CHANNELS,
280 EEPROM_REG_BAND_3_CHANNELS,
281 EEPROM_REG_BAND_4_CHANNELS,
282 EEPROM_REG_BAND_5_CHANNELS,
283 EEPROM_REG_BAND_24_HT40_CHANNELS,
284 EEPROM_REG_BAND_52_HT40_CHANNELS
285 },
286 },
287 .temperature = iwlagn_temperature,
288};
289
290static struct iwl_lib_ops iwl5150_lib = {
291 .set_hw_params = iwl5150_hw_set_hw_params,
292 .set_channel_switch = iwl5000_hw_channel_switch,
293 .nic_config = iwl5000_nic_config,
294 .eeprom_ops = {
295 .regulatory_bands = {
296 EEPROM_REG_BAND_1_CHANNELS,
297 EEPROM_REG_BAND_2_CHANNELS,
298 EEPROM_REG_BAND_3_CHANNELS,
299 EEPROM_REG_BAND_4_CHANNELS,
300 EEPROM_REG_BAND_5_CHANNELS,
301 EEPROM_REG_BAND_24_HT40_CHANNELS,
302 EEPROM_REG_BAND_52_HT40_CHANNELS
303 },
304 },
305 .temperature = iwl5150_temperature,
306};
307
308static const struct iwl_base_params iwl5000_base_params = { 47static const struct iwl_base_params iwl5000_base_params = {
309 .eeprom_size = IWLAGN_EEPROM_IMG_SIZE, 48 .eeprom_size = IWLAGN_EEPROM_IMG_SIZE,
310 .num_of_queues = IWLAGN_NUM_QUEUES, 49 .num_of_queues = IWLAGN_NUM_QUEUES,
@@ -330,7 +69,6 @@ static const struct iwl_ht_params iwl5000_ht_params = {
330 .max_data_size = IWLAGN_RTC_DATA_SIZE, \ 69 .max_data_size = IWLAGN_RTC_DATA_SIZE, \
331 .eeprom_ver = EEPROM_5000_EEPROM_VERSION, \ 70 .eeprom_ver = EEPROM_5000_EEPROM_VERSION, \
332 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, \ 71 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, \
333 .lib = &iwl5000_lib, \
334 .base_params = &iwl5000_base_params, \ 72 .base_params = &iwl5000_base_params, \
335 .led_mode = IWL_LED_BLINK 73 .led_mode = IWL_LED_BLINK
336 74
@@ -376,7 +114,6 @@ const struct iwl_cfg iwl5350_agn_cfg = {
376 .max_data_size = IWLAGN_RTC_DATA_SIZE, 114 .max_data_size = IWLAGN_RTC_DATA_SIZE,
377 .eeprom_ver = EEPROM_5050_EEPROM_VERSION, 115 .eeprom_ver = EEPROM_5050_EEPROM_VERSION,
378 .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, 116 .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,
379 .lib = &iwl5000_lib,
380 .base_params = &iwl5000_base_params, 117 .base_params = &iwl5000_base_params,
381 .ht_params = &iwl5000_ht_params, 118 .ht_params = &iwl5000_ht_params,
382 .led_mode = IWL_LED_BLINK, 119 .led_mode = IWL_LED_BLINK,
@@ -392,7 +129,6 @@ const struct iwl_cfg iwl5350_agn_cfg = {
392 .max_data_size = IWLAGN_RTC_DATA_SIZE, \ 129 .max_data_size = IWLAGN_RTC_DATA_SIZE, \
393 .eeprom_ver = EEPROM_5050_EEPROM_VERSION, \ 130 .eeprom_ver = EEPROM_5050_EEPROM_VERSION, \
394 .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, \ 131 .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, \
395 .lib = &iwl5150_lib, \
396 .base_params = &iwl5000_base_params, \ 132 .base_params = &iwl5000_base_params, \
397 .no_xtal_calib = true, \ 133 .no_xtal_calib = true, \
398 .led_mode = IWL_LED_BLINK, \ 134 .led_mode = IWL_LED_BLINK, \
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index f124ec697168..00da2520a4b7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -24,26 +24,11 @@
24 * 24 *
25 *****************************************************************************/ 25 *****************************************************************************/
26 26
27#include <linux/kernel.h>
28#include <linux/module.h> 27#include <linux/module.h>
29#include <linux/init.h>
30#include <linux/delay.h>
31#include <linux/skbuff.h>
32#include <linux/netdevice.h>
33#include <net/mac80211.h>
34#include <linux/etherdevice.h>
35#include <asm/unaligned.h>
36#include <linux/stringify.h> 28#include <linux/stringify.h>
37 29#include "iwl-config.h"
38#include "iwl-eeprom.h"
39#include "iwl-dev.h"
40#include "iwl-core.h"
41#include "iwl-io.h"
42#include "iwl-agn.h"
43#include "iwl-agn-hw.h"
44#include "iwl-trans.h"
45#include "iwl-shared.h"
46#include "iwl-cfg.h" 30#include "iwl-cfg.h"
31#include "iwl-dev.h" /* still needed */
47 32
48/* Highest firmware API version supported */ 33/* Highest firmware API version supported */
49#define IWL6000_UCODE_API_MAX 6 34#define IWL6000_UCODE_API_MAX 6
@@ -71,200 +56,6 @@
71#define IWL6030_FW_PRE "iwlwifi-6000g2b-" 56#define IWL6030_FW_PRE "iwlwifi-6000g2b-"
72#define IWL6030_MODULE_FIRMWARE(api) IWL6030_FW_PRE __stringify(api) ".ucode" 57#define IWL6030_MODULE_FIRMWARE(api) IWL6030_FW_PRE __stringify(api) ".ucode"
73 58
74static void iwl6000_set_ct_threshold(struct iwl_priv *priv)
75{
76 /* want Celsius */
77 priv->hw_params.ct_kill_threshold = CT_KILL_THRESHOLD;
78 priv->hw_params.ct_kill_exit_threshold = CT_KILL_EXIT_THRESHOLD;
79}
80
81/* NIC configuration for 6000 series */
82static void iwl6000_nic_config(struct iwl_priv *priv)
83{
84 iwl_rf_config(priv);
85
86 switch (cfg(priv)->device_family) {
87 case IWL_DEVICE_FAMILY_6005:
88 case IWL_DEVICE_FAMILY_6030:
89 case IWL_DEVICE_FAMILY_6000:
90 break;
91 case IWL_DEVICE_FAMILY_6000i:
92 /* 2x2 IPA phy type */
93 iwl_write32(trans(priv), CSR_GP_DRIVER_REG,
94 CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_IPA);
95 break;
96 case IWL_DEVICE_FAMILY_6050:
97 /* Indicate calibration version to uCode. */
98 if (iwl_eeprom_calib_version(priv) >= 6)
99 iwl_set_bit(trans(priv), CSR_GP_DRIVER_REG,
100 CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6);
101 break;
102 case IWL_DEVICE_FAMILY_6150:
103 /* Indicate calibration version to uCode. */
104 if (iwl_eeprom_calib_version(priv) >= 6)
105 iwl_set_bit(trans(priv), CSR_GP_DRIVER_REG,
106 CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6);
107 iwl_set_bit(trans(priv), CSR_GP_DRIVER_REG,
108 CSR_GP_DRIVER_REG_BIT_6050_1x2);
109 break;
110 default:
111 WARN_ON(1);
112 }
113}
114
115static const struct iwl_sensitivity_ranges iwl6000_sensitivity = {
116 .min_nrg_cck = 110,
117 .auto_corr_min_ofdm = 80,
118 .auto_corr_min_ofdm_mrc = 128,
119 .auto_corr_min_ofdm_x1 = 105,
120 .auto_corr_min_ofdm_mrc_x1 = 192,
121
122 .auto_corr_max_ofdm = 145,
123 .auto_corr_max_ofdm_mrc = 232,
124 .auto_corr_max_ofdm_x1 = 110,
125 .auto_corr_max_ofdm_mrc_x1 = 232,
126
127 .auto_corr_min_cck = 125,
128 .auto_corr_max_cck = 175,
129 .auto_corr_min_cck_mrc = 160,
130 .auto_corr_max_cck_mrc = 310,
131 .nrg_th_cck = 110,
132 .nrg_th_ofdm = 110,
133
134 .barker_corr_th_min = 190,
135 .barker_corr_th_min_mrc = 336,
136 .nrg_th_cca = 62,
137};
138
139static void iwl6000_hw_set_hw_params(struct iwl_priv *priv)
140{
141 priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) |
142 BIT(IEEE80211_BAND_5GHZ);
143
144 priv->hw_params.tx_chains_num =
145 num_of_ant(priv->hw_params.valid_tx_ant);
146 if (cfg(priv)->rx_with_siso_diversity)
147 priv->hw_params.rx_chains_num = 1;
148 else
149 priv->hw_params.rx_chains_num =
150 num_of_ant(priv->hw_params.valid_rx_ant);
151
152 iwl6000_set_ct_threshold(priv);
153
154 /* Set initial sensitivity parameters */
155 priv->hw_params.sens = &iwl6000_sensitivity;
156
157}
158
159static int iwl6000_hw_channel_switch(struct iwl_priv *priv,
160 struct ieee80211_channel_switch *ch_switch)
161{
162 /*
163 * MULTI-FIXME
164 * See iwlagn_mac_channel_switch.
165 */
166 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
167 struct iwl6000_channel_switch_cmd cmd;
168 const struct iwl_channel_info *ch_info;
169 u32 switch_time_in_usec, ucode_switch_time;
170 u16 ch;
171 u32 tsf_low;
172 u8 switch_count;
173 u16 beacon_interval = le16_to_cpu(ctx->timing.beacon_interval);
174 struct ieee80211_vif *vif = ctx->vif;
175 struct iwl_host_cmd hcmd = {
176 .id = REPLY_CHANNEL_SWITCH,
177 .len = { sizeof(cmd), },
178 .flags = CMD_SYNC,
179 .data = { &cmd, },
180 };
181
182 cmd.band = priv->band == IEEE80211_BAND_2GHZ;
183 ch = ch_switch->channel->hw_value;
184 IWL_DEBUG_11H(priv, "channel switch from %u to %u\n",
185 ctx->active.channel, ch);
186 cmd.channel = cpu_to_le16(ch);
187 cmd.rxon_flags = ctx->staging.flags;
188 cmd.rxon_filter_flags = ctx->staging.filter_flags;
189 switch_count = ch_switch->count;
190 tsf_low = ch_switch->timestamp & 0x0ffffffff;
191 /*
192 * calculate the ucode channel switch time
193 * adding TSF as one of the factor for when to switch
194 */
195 if ((priv->ucode_beacon_time > tsf_low) && beacon_interval) {
196 if (switch_count > ((priv->ucode_beacon_time - tsf_low) /
197 beacon_interval)) {
198 switch_count -= (priv->ucode_beacon_time -
199 tsf_low) / beacon_interval;
200 } else
201 switch_count = 0;
202 }
203 if (switch_count <= 1)
204 cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time);
205 else {
206 switch_time_in_usec =
207 vif->bss_conf.beacon_int * switch_count * TIME_UNIT;
208 ucode_switch_time = iwl_usecs_to_beacons(priv,
209 switch_time_in_usec,
210 beacon_interval);
211 cmd.switch_time = iwl_add_beacon_time(priv,
212 priv->ucode_beacon_time,
213 ucode_switch_time,
214 beacon_interval);
215 }
216 IWL_DEBUG_11H(priv, "uCode time for the switch is 0x%x\n",
217 cmd.switch_time);
218 ch_info = iwl_get_channel_info(priv, priv->band, ch);
219 if (ch_info)
220 cmd.expect_beacon = is_channel_radar(ch_info);
221 else {
222 IWL_ERR(priv, "invalid channel switch from %u to %u\n",
223 ctx->active.channel, ch);
224 return -EFAULT;
225 }
226
227 return iwl_dvm_send_cmd(priv, &hcmd);
228}
229
230static struct iwl_lib_ops iwl6000_lib = {
231 .set_hw_params = iwl6000_hw_set_hw_params,
232 .set_channel_switch = iwl6000_hw_channel_switch,
233 .nic_config = iwl6000_nic_config,
234 .eeprom_ops = {
235 .regulatory_bands = {
236 EEPROM_REG_BAND_1_CHANNELS,
237 EEPROM_REG_BAND_2_CHANNELS,
238 EEPROM_REG_BAND_3_CHANNELS,
239 EEPROM_REG_BAND_4_CHANNELS,
240 EEPROM_REG_BAND_5_CHANNELS,
241 EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
242 EEPROM_REG_BAND_52_HT40_CHANNELS
243 },
244 .enhanced_txpower = true,
245 },
246 .temperature = iwlagn_temperature,
247};
248
249static struct iwl_lib_ops iwl6030_lib = {
250 .set_hw_params = iwl6000_hw_set_hw_params,
251 .set_channel_switch = iwl6000_hw_channel_switch,
252 .nic_config = iwl6000_nic_config,
253 .eeprom_ops = {
254 .regulatory_bands = {
255 EEPROM_REG_BAND_1_CHANNELS,
256 EEPROM_REG_BAND_2_CHANNELS,
257 EEPROM_REG_BAND_3_CHANNELS,
258 EEPROM_REG_BAND_4_CHANNELS,
259 EEPROM_REG_BAND_5_CHANNELS,
260 EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
261 EEPROM_REG_BAND_52_HT40_CHANNELS
262 },
263 .enhanced_txpower = true,
264 },
265 .temperature = iwlagn_temperature,
266};
267
268static const struct iwl_base_params iwl6000_base_params = { 59static const struct iwl_base_params iwl6000_base_params = {
269 .eeprom_size = OTP_LOW_IMAGE_SIZE, 60 .eeprom_size = OTP_LOW_IMAGE_SIZE,
270 .num_of_queues = IWLAGN_NUM_QUEUES, 61 .num_of_queues = IWLAGN_NUM_QUEUES,
@@ -337,7 +128,6 @@ static const struct iwl_bt_params iwl6000_bt_params = {
337 .max_data_size = IWL60_RTC_DATA_SIZE, \ 128 .max_data_size = IWL60_RTC_DATA_SIZE, \
338 .eeprom_ver = EEPROM_6005_EEPROM_VERSION, \ 129 .eeprom_ver = EEPROM_6005_EEPROM_VERSION, \
339 .eeprom_calib_ver = EEPROM_6005_TX_POWER_VERSION, \ 130 .eeprom_calib_ver = EEPROM_6005_TX_POWER_VERSION, \
340 .lib = &iwl6000_lib, \
341 .base_params = &iwl6000_g2_base_params, \ 131 .base_params = &iwl6000_g2_base_params, \
342 .need_temp_offset_calib = true, \ 132 .need_temp_offset_calib = true, \
343 .led_mode = IWL_LED_RF_STATE 133 .led_mode = IWL_LED_RF_STATE
@@ -392,7 +182,6 @@ const struct iwl_cfg iwl6005_2agn_mow2_cfg = {
392 .max_data_size = IWL60_RTC_DATA_SIZE, \ 182 .max_data_size = IWL60_RTC_DATA_SIZE, \
393 .eeprom_ver = EEPROM_6030_EEPROM_VERSION, \ 183 .eeprom_ver = EEPROM_6030_EEPROM_VERSION, \
394 .eeprom_calib_ver = EEPROM_6030_TX_POWER_VERSION, \ 184 .eeprom_calib_ver = EEPROM_6030_TX_POWER_VERSION, \
395 .lib = &iwl6030_lib, \
396 .base_params = &iwl6000_g2_base_params, \ 185 .base_params = &iwl6000_g2_base_params, \
397 .bt_params = &iwl6000_bt_params, \ 186 .bt_params = &iwl6000_bt_params, \
398 .need_temp_offset_calib = true, \ 187 .need_temp_offset_calib = true, \
@@ -466,7 +255,6 @@ const struct iwl_cfg iwl130_bg_cfg = {
466 .valid_rx_ant = ANT_BC, /* .cfg overwrite */ \ 255 .valid_rx_ant = ANT_BC, /* .cfg overwrite */ \
467 .eeprom_ver = EEPROM_6000_EEPROM_VERSION, \ 256 .eeprom_ver = EEPROM_6000_EEPROM_VERSION, \
468 .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION, \ 257 .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION, \
469 .lib = &iwl6000_lib, \
470 .base_params = &iwl6000_base_params, \ 258 .base_params = &iwl6000_base_params, \
471 .led_mode = IWL_LED_BLINK 259 .led_mode = IWL_LED_BLINK
472 260
@@ -495,7 +283,6 @@ const struct iwl_cfg iwl6000i_2bg_cfg = {
495 .max_data_size = IWL60_RTC_DATA_SIZE, \ 283 .max_data_size = IWL60_RTC_DATA_SIZE, \
496 .valid_tx_ant = ANT_AB, /* .cfg overwrite */ \ 284 .valid_tx_ant = ANT_AB, /* .cfg overwrite */ \
497 .valid_rx_ant = ANT_AB, /* .cfg overwrite */ \ 285 .valid_rx_ant = ANT_AB, /* .cfg overwrite */ \
498 .lib = &iwl6000_lib, \
499 .eeprom_ver = EEPROM_6050_EEPROM_VERSION, \ 286 .eeprom_ver = EEPROM_6050_EEPROM_VERSION, \
500 .eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION, \ 287 .eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION, \
501 .base_params = &iwl6050_base_params, \ 288 .base_params = &iwl6050_base_params, \
@@ -520,7 +307,6 @@ const struct iwl_cfg iwl6050_2abg_cfg = {
520 .device_family = IWL_DEVICE_FAMILY_6150, \ 307 .device_family = IWL_DEVICE_FAMILY_6150, \
521 .max_inst_size = IWL60_RTC_INST_SIZE, \ 308 .max_inst_size = IWL60_RTC_INST_SIZE, \
522 .max_data_size = IWL60_RTC_DATA_SIZE, \ 309 .max_data_size = IWL60_RTC_DATA_SIZE, \
523 .lib = &iwl6000_lib, \
524 .eeprom_ver = EEPROM_6150_EEPROM_VERSION, \ 310 .eeprom_ver = EEPROM_6150_EEPROM_VERSION, \
525 .eeprom_calib_ver = EEPROM_6150_TX_POWER_VERSION, \ 311 .eeprom_calib_ver = EEPROM_6150_TX_POWER_VERSION, \
526 .base_params = &iwl6050_base_params, \ 312 .base_params = &iwl6050_base_params, \
@@ -549,7 +335,6 @@ const struct iwl_cfg iwl6000_3agn_cfg = {
549 .max_data_size = IWL60_RTC_DATA_SIZE, 335 .max_data_size = IWL60_RTC_DATA_SIZE,
550 .eeprom_ver = EEPROM_6000_EEPROM_VERSION, 336 .eeprom_ver = EEPROM_6000_EEPROM_VERSION,
551 .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION, 337 .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION,
552 .lib = &iwl6000_lib,
553 .base_params = &iwl6000_base_params, 338 .base_params = &iwl6000_base_params,
554 .ht_params = &iwl6000_ht_params, 339 .ht_params = &iwl6000_ht_params,
555 .led_mode = IWL_LED_BLINK, 340 .led_mode = IWL_LED_BLINK,
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-devices.c b/drivers/net/wireless/iwlwifi/iwl-agn-devices.c
new file mode 100644
index 000000000000..bc9cb5c0ec6c
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-devices.c
@@ -0,0 +1,682 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * Intel Linux Wireless <ilw@linux.intel.com>
23 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
24 *
25 *****************************************************************************/
26
27/*
28 * DVM device-specific data & functions
29 */
30#include "iwl-core.h"
31#include "iwl-agn.h"
32#include "iwl-dev.h"
33#include "iwl-commands.h"
34#include "iwl-io.h"
35#include "iwl-prph.h"
36
37/*
38 * 1000 series
39 * ===========
40 */
41
42/*
43 * For 1000, use advance thermal throttling critical temperature threshold,
44 * but legacy thermal management implementation for now.
45 * This is for the reason of 1000 uCode using advance thermal throttling API
46 * but not implement ct_kill_exit based on ct_kill exit temperature
47 * so the thermal throttling will still based on legacy thermal throttling
48 * management.
49 * The code here need to be modified once 1000 uCode has the advanced thermal
50 * throttling algorithm in place
51 */
52static void iwl1000_set_ct_threshold(struct iwl_priv *priv)
53{
54 /* want Celsius */
55 priv->hw_params.ct_kill_threshold = CT_KILL_THRESHOLD_LEGACY;
56 priv->hw_params.ct_kill_exit_threshold = CT_KILL_EXIT_THRESHOLD;
57}
58
59/* NIC configuration for 1000 series */
60static void iwl1000_nic_config(struct iwl_priv *priv)
61{
62 /* set CSR_HW_CONFIG_REG for uCode use */
63 iwl_set_bit(trans(priv), CSR_HW_IF_CONFIG_REG,
64 CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI |
65 CSR_HW_IF_CONFIG_REG_BIT_MAC_SI);
66
67 /* Setting digital SVR for 1000 card to 1.32V */
68 /* locking is acquired in iwl_set_bits_mask_prph() function */
69 iwl_set_bits_mask_prph(trans(priv), APMG_DIGITAL_SVR_REG,
70 APMG_SVR_DIGITAL_VOLTAGE_1_32,
71 ~APMG_SVR_VOLTAGE_CONFIG_BIT_MSK);
72}
73
74static const struct iwl_sensitivity_ranges iwl1000_sensitivity = {
75 .min_nrg_cck = 95,
76 .auto_corr_min_ofdm = 90,
77 .auto_corr_min_ofdm_mrc = 170,
78 .auto_corr_min_ofdm_x1 = 120,
79 .auto_corr_min_ofdm_mrc_x1 = 240,
80
81 .auto_corr_max_ofdm = 120,
82 .auto_corr_max_ofdm_mrc = 210,
83 .auto_corr_max_ofdm_x1 = 155,
84 .auto_corr_max_ofdm_mrc_x1 = 290,
85
86 .auto_corr_min_cck = 125,
87 .auto_corr_max_cck = 200,
88 .auto_corr_min_cck_mrc = 170,
89 .auto_corr_max_cck_mrc = 400,
90 .nrg_th_cck = 95,
91 .nrg_th_ofdm = 95,
92
93 .barker_corr_th_min = 190,
94 .barker_corr_th_min_mrc = 390,
95 .nrg_th_cca = 62,
96};
97
98static void iwl1000_hw_set_hw_params(struct iwl_priv *priv)
99{
100 priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ);
101
102 priv->hw_params.tx_chains_num =
103 num_of_ant(priv->hw_params.valid_tx_ant);
104 if (cfg(priv)->rx_with_siso_diversity)
105 priv->hw_params.rx_chains_num = 1;
106 else
107 priv->hw_params.rx_chains_num =
108 num_of_ant(priv->hw_params.valid_rx_ant);
109
110 iwl1000_set_ct_threshold(priv);
111
112 /* Set initial sensitivity parameters */
113 priv->hw_params.sens = &iwl1000_sensitivity;
114}
115
116struct iwl_lib_ops iwl1000_lib = {
117 .set_hw_params = iwl1000_hw_set_hw_params,
118 .nic_config = iwl1000_nic_config,
119 .eeprom_ops = {
120 .regulatory_bands = {
121 EEPROM_REG_BAND_1_CHANNELS,
122 EEPROM_REG_BAND_2_CHANNELS,
123 EEPROM_REG_BAND_3_CHANNELS,
124 EEPROM_REG_BAND_4_CHANNELS,
125 EEPROM_REG_BAND_5_CHANNELS,
126 EEPROM_REG_BAND_24_HT40_CHANNELS,
127 EEPROM_REGULATORY_BAND_NO_HT40,
128 },
129 },
130 .temperature = iwlagn_temperature,
131};
132
133
134/*
135 * 2000 series
136 * ===========
137 */
138
139static void iwl2000_set_ct_threshold(struct iwl_priv *priv)
140{
141 /* want Celsius */
142 priv->hw_params.ct_kill_threshold = CT_KILL_THRESHOLD;
143 priv->hw_params.ct_kill_exit_threshold = CT_KILL_EXIT_THRESHOLD;
144}
145
146/* NIC configuration for 2000 series */
147static void iwl2000_nic_config(struct iwl_priv *priv)
148{
149 iwl_rf_config(priv);
150
151 iwl_set_bit(trans(priv), CSR_GP_DRIVER_REG,
152 CSR_GP_DRIVER_REG_BIT_RADIO_IQ_INVER);
153}
154
155static const struct iwl_sensitivity_ranges iwl2000_sensitivity = {
156 .min_nrg_cck = 97,
157 .auto_corr_min_ofdm = 80,
158 .auto_corr_min_ofdm_mrc = 128,
159 .auto_corr_min_ofdm_x1 = 105,
160 .auto_corr_min_ofdm_mrc_x1 = 192,
161
162 .auto_corr_max_ofdm = 145,
163 .auto_corr_max_ofdm_mrc = 232,
164 .auto_corr_max_ofdm_x1 = 110,
165 .auto_corr_max_ofdm_mrc_x1 = 232,
166
167 .auto_corr_min_cck = 125,
168 .auto_corr_max_cck = 175,
169 .auto_corr_min_cck_mrc = 160,
170 .auto_corr_max_cck_mrc = 310,
171 .nrg_th_cck = 97,
172 .nrg_th_ofdm = 100,
173
174 .barker_corr_th_min = 190,
175 .barker_corr_th_min_mrc = 390,
176 .nrg_th_cca = 62,
177};
178
179static void iwl2000_hw_set_hw_params(struct iwl_priv *priv)
180{
181 priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ);
182
183 priv->hw_params.tx_chains_num =
184 num_of_ant(priv->hw_params.valid_tx_ant);
185 if (cfg(priv)->rx_with_siso_diversity)
186 priv->hw_params.rx_chains_num = 1;
187 else
188 priv->hw_params.rx_chains_num =
189 num_of_ant(priv->hw_params.valid_rx_ant);
190
191 iwl2000_set_ct_threshold(priv);
192
193 /* Set initial sensitivity parameters */
194 priv->hw_params.sens = &iwl2000_sensitivity;
195}
196
197struct iwl_lib_ops iwl2000_lib = {
198 .set_hw_params = iwl2000_hw_set_hw_params,
199 .nic_config = iwl2000_nic_config,
200 .eeprom_ops = {
201 .regulatory_bands = {
202 EEPROM_REG_BAND_1_CHANNELS,
203 EEPROM_REG_BAND_2_CHANNELS,
204 EEPROM_REG_BAND_3_CHANNELS,
205 EEPROM_REG_BAND_4_CHANNELS,
206 EEPROM_REG_BAND_5_CHANNELS,
207 EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
208 EEPROM_REGULATORY_BAND_NO_HT40,
209 },
210 .enhanced_txpower = true,
211 },
212 .temperature = iwlagn_temperature,
213};
214
215struct iwl_lib_ops iwl2030_lib = {
216 .set_hw_params = iwl2000_hw_set_hw_params,
217 .nic_config = iwl2000_nic_config,
218 .eeprom_ops = {
219 .regulatory_bands = {
220 EEPROM_REG_BAND_1_CHANNELS,
221 EEPROM_REG_BAND_2_CHANNELS,
222 EEPROM_REG_BAND_3_CHANNELS,
223 EEPROM_REG_BAND_4_CHANNELS,
224 EEPROM_REG_BAND_5_CHANNELS,
225 EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
226 EEPROM_REGULATORY_BAND_NO_HT40,
227 },
228 .enhanced_txpower = true,
229 },
230 .temperature = iwlagn_temperature,
231};
232
233/*
234 * 5000 series
235 * ===========
236 */
237
238/* NIC configuration for 5000 series */
239static void iwl5000_nic_config(struct iwl_priv *priv)
240{
241 iwl_rf_config(priv);
242
243 /* W/A : NIC is stuck in a reset state after Early PCIe power off
244 * (PCIe power is lost before PERST# is asserted),
245 * causing ME FW to lose ownership and not being able to obtain it back.
246 */
247 iwl_set_bits_mask_prph(trans(priv), APMG_PS_CTRL_REG,
248 APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS,
249 ~APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS);
250}
251
252static const struct iwl_sensitivity_ranges iwl5000_sensitivity = {
253 .min_nrg_cck = 100,
254 .auto_corr_min_ofdm = 90,
255 .auto_corr_min_ofdm_mrc = 170,
256 .auto_corr_min_ofdm_x1 = 105,
257 .auto_corr_min_ofdm_mrc_x1 = 220,
258
259 .auto_corr_max_ofdm = 120,
260 .auto_corr_max_ofdm_mrc = 210,
261 .auto_corr_max_ofdm_x1 = 120,
262 .auto_corr_max_ofdm_mrc_x1 = 240,
263
264 .auto_corr_min_cck = 125,
265 .auto_corr_max_cck = 200,
266 .auto_corr_min_cck_mrc = 200,
267 .auto_corr_max_cck_mrc = 400,
268 .nrg_th_cck = 100,
269 .nrg_th_ofdm = 100,
270
271 .barker_corr_th_min = 190,
272 .barker_corr_th_min_mrc = 390,
273 .nrg_th_cca = 62,
274};
275
276static struct iwl_sensitivity_ranges iwl5150_sensitivity = {
277 .min_nrg_cck = 95,
278 .auto_corr_min_ofdm = 90,
279 .auto_corr_min_ofdm_mrc = 170,
280 .auto_corr_min_ofdm_x1 = 105,
281 .auto_corr_min_ofdm_mrc_x1 = 220,
282
283 .auto_corr_max_ofdm = 120,
284 .auto_corr_max_ofdm_mrc = 210,
285 /* max = min for performance bug in 5150 DSP */
286 .auto_corr_max_ofdm_x1 = 105,
287 .auto_corr_max_ofdm_mrc_x1 = 220,
288
289 .auto_corr_min_cck = 125,
290 .auto_corr_max_cck = 200,
291 .auto_corr_min_cck_mrc = 170,
292 .auto_corr_max_cck_mrc = 400,
293 .nrg_th_cck = 95,
294 .nrg_th_ofdm = 95,
295
296 .barker_corr_th_min = 190,
297 .barker_corr_th_min_mrc = 390,
298 .nrg_th_cca = 62,
299};
300
301#define IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF (-5)
302
303static s32 iwl_temp_calib_to_offset(struct iwl_priv *priv)
304{
305 u16 temperature, voltage;
306 __le16 *temp_calib = (__le16 *)iwl_eeprom_query_addr(priv,
307 EEPROM_KELVIN_TEMPERATURE);
308
309 temperature = le16_to_cpu(temp_calib[0]);
310 voltage = le16_to_cpu(temp_calib[1]);
311
312 /* offset = temp - volt / coeff */
313 return (s32)(temperature -
314 voltage / IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF);
315}
316
317static void iwl5150_set_ct_threshold(struct iwl_priv *priv)
318{
319 const s32 volt2temp_coef = IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF;
320 s32 threshold = (s32)CELSIUS_TO_KELVIN(CT_KILL_THRESHOLD_LEGACY) -
321 iwl_temp_calib_to_offset(priv);
322
323 priv->hw_params.ct_kill_threshold = threshold * volt2temp_coef;
324}
325
326static void iwl5000_set_ct_threshold(struct iwl_priv *priv)
327{
328 /* want Celsius */
329 priv->hw_params.ct_kill_threshold = CT_KILL_THRESHOLD_LEGACY;
330}
331
332static void iwl5000_hw_set_hw_params(struct iwl_priv *priv)
333{
334 priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) |
335 BIT(IEEE80211_BAND_5GHZ);
336
337 priv->hw_params.tx_chains_num =
338 num_of_ant(priv->hw_params.valid_tx_ant);
339 priv->hw_params.rx_chains_num =
340 num_of_ant(priv->hw_params.valid_rx_ant);
341
342 iwl5000_set_ct_threshold(priv);
343
344 /* Set initial sensitivity parameters */
345 priv->hw_params.sens = &iwl5000_sensitivity;
346}
347
348static void iwl5150_hw_set_hw_params(struct iwl_priv *priv)
349{
350 priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) |
351 BIT(IEEE80211_BAND_5GHZ);
352
353 priv->hw_params.tx_chains_num =
354 num_of_ant(priv->hw_params.valid_tx_ant);
355 priv->hw_params.rx_chains_num =
356 num_of_ant(priv->hw_params.valid_rx_ant);
357
358 iwl5150_set_ct_threshold(priv);
359
360 /* Set initial sensitivity parameters */
361 priv->hw_params.sens = &iwl5150_sensitivity;
362}
363
364static void iwl5150_temperature(struct iwl_priv *priv)
365{
366 u32 vt = 0;
367 s32 offset = iwl_temp_calib_to_offset(priv);
368
369 vt = le32_to_cpu(priv->statistics.common.temperature);
370 vt = vt / IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF + offset;
371 /* now vt hold the temperature in Kelvin */
372 priv->temperature = KELVIN_TO_CELSIUS(vt);
373 iwl_tt_handler(priv);
374}
375
376static int iwl5000_hw_channel_switch(struct iwl_priv *priv,
377 struct ieee80211_channel_switch *ch_switch)
378{
379 /*
380 * MULTI-FIXME
381 * See iwlagn_mac_channel_switch.
382 */
383 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
384 struct iwl5000_channel_switch_cmd cmd;
385 const struct iwl_channel_info *ch_info;
386 u32 switch_time_in_usec, ucode_switch_time;
387 u16 ch;
388 u32 tsf_low;
389 u8 switch_count;
390 u16 beacon_interval = le16_to_cpu(ctx->timing.beacon_interval);
391 struct ieee80211_vif *vif = ctx->vif;
392 struct iwl_host_cmd hcmd = {
393 .id = REPLY_CHANNEL_SWITCH,
394 .len = { sizeof(cmd), },
395 .flags = CMD_SYNC,
396 .data = { &cmd, },
397 };
398
399 cmd.band = priv->band == IEEE80211_BAND_2GHZ;
400 ch = ch_switch->channel->hw_value;
401 IWL_DEBUG_11H(priv, "channel switch from %d to %d\n",
402 ctx->active.channel, ch);
403 cmd.channel = cpu_to_le16(ch);
404 cmd.rxon_flags = ctx->staging.flags;
405 cmd.rxon_filter_flags = ctx->staging.filter_flags;
406 switch_count = ch_switch->count;
407 tsf_low = ch_switch->timestamp & 0x0ffffffff;
408 /*
409 * calculate the ucode channel switch time
410 * adding TSF as one of the factor for when to switch
411 */
412 if ((priv->ucode_beacon_time > tsf_low) && beacon_interval) {
413 if (switch_count > ((priv->ucode_beacon_time - tsf_low) /
414 beacon_interval)) {
415 switch_count -= (priv->ucode_beacon_time -
416 tsf_low) / beacon_interval;
417 } else
418 switch_count = 0;
419 }
420 if (switch_count <= 1)
421 cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time);
422 else {
423 switch_time_in_usec =
424 vif->bss_conf.beacon_int * switch_count * TIME_UNIT;
425 ucode_switch_time = iwl_usecs_to_beacons(priv,
426 switch_time_in_usec,
427 beacon_interval);
428 cmd.switch_time = iwl_add_beacon_time(priv,
429 priv->ucode_beacon_time,
430 ucode_switch_time,
431 beacon_interval);
432 }
433 IWL_DEBUG_11H(priv, "uCode time for the switch is 0x%x\n",
434 cmd.switch_time);
435 ch_info = iwl_get_channel_info(priv, priv->band, ch);
436 if (ch_info)
437 cmd.expect_beacon = is_channel_radar(ch_info);
438 else {
439 IWL_ERR(priv, "invalid channel switch from %u to %u\n",
440 ctx->active.channel, ch);
441 return -EFAULT;
442 }
443
444 return iwl_dvm_send_cmd(priv, &hcmd);
445}
446
447struct iwl_lib_ops iwl5000_lib = {
448 .set_hw_params = iwl5000_hw_set_hw_params,
449 .set_channel_switch = iwl5000_hw_channel_switch,
450 .nic_config = iwl5000_nic_config,
451 .eeprom_ops = {
452 .regulatory_bands = {
453 EEPROM_REG_BAND_1_CHANNELS,
454 EEPROM_REG_BAND_2_CHANNELS,
455 EEPROM_REG_BAND_3_CHANNELS,
456 EEPROM_REG_BAND_4_CHANNELS,
457 EEPROM_REG_BAND_5_CHANNELS,
458 EEPROM_REG_BAND_24_HT40_CHANNELS,
459 EEPROM_REG_BAND_52_HT40_CHANNELS
460 },
461 },
462 .temperature = iwlagn_temperature,
463};
464
465struct iwl_lib_ops iwl5150_lib = {
466 .set_hw_params = iwl5150_hw_set_hw_params,
467 .set_channel_switch = iwl5000_hw_channel_switch,
468 .nic_config = iwl5000_nic_config,
469 .eeprom_ops = {
470 .regulatory_bands = {
471 EEPROM_REG_BAND_1_CHANNELS,
472 EEPROM_REG_BAND_2_CHANNELS,
473 EEPROM_REG_BAND_3_CHANNELS,
474 EEPROM_REG_BAND_4_CHANNELS,
475 EEPROM_REG_BAND_5_CHANNELS,
476 EEPROM_REG_BAND_24_HT40_CHANNELS,
477 EEPROM_REG_BAND_52_HT40_CHANNELS
478 },
479 },
480 .temperature = iwl5150_temperature,
481};
482
483
484
485/*
486 * 6000 series
487 * ===========
488 */
489
490static void iwl6000_set_ct_threshold(struct iwl_priv *priv)
491{
492 /* want Celsius */
493 priv->hw_params.ct_kill_threshold = CT_KILL_THRESHOLD;
494 priv->hw_params.ct_kill_exit_threshold = CT_KILL_EXIT_THRESHOLD;
495}
496
497/* NIC configuration for 6000 series */
498static void iwl6000_nic_config(struct iwl_priv *priv)
499{
500 iwl_rf_config(priv);
501
502 switch (cfg(priv)->device_family) {
503 case IWL_DEVICE_FAMILY_6005:
504 case IWL_DEVICE_FAMILY_6030:
505 case IWL_DEVICE_FAMILY_6000:
506 break;
507 case IWL_DEVICE_FAMILY_6000i:
508 /* 2x2 IPA phy type */
509 iwl_write32(trans(priv), CSR_GP_DRIVER_REG,
510 CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_IPA);
511 break;
512 case IWL_DEVICE_FAMILY_6050:
513 /* Indicate calibration version to uCode. */
514 if (iwl_eeprom_calib_version(priv) >= 6)
515 iwl_set_bit(trans(priv), CSR_GP_DRIVER_REG,
516 CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6);
517 break;
518 case IWL_DEVICE_FAMILY_6150:
519 /* Indicate calibration version to uCode. */
520 if (iwl_eeprom_calib_version(priv) >= 6)
521 iwl_set_bit(trans(priv), CSR_GP_DRIVER_REG,
522 CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6);
523 iwl_set_bit(trans(priv), CSR_GP_DRIVER_REG,
524 CSR_GP_DRIVER_REG_BIT_6050_1x2);
525 break;
526 default:
527 WARN_ON(1);
528 }
529}
530
531static const struct iwl_sensitivity_ranges iwl6000_sensitivity = {
532 .min_nrg_cck = 110,
533 .auto_corr_min_ofdm = 80,
534 .auto_corr_min_ofdm_mrc = 128,
535 .auto_corr_min_ofdm_x1 = 105,
536 .auto_corr_min_ofdm_mrc_x1 = 192,
537
538 .auto_corr_max_ofdm = 145,
539 .auto_corr_max_ofdm_mrc = 232,
540 .auto_corr_max_ofdm_x1 = 110,
541 .auto_corr_max_ofdm_mrc_x1 = 232,
542
543 .auto_corr_min_cck = 125,
544 .auto_corr_max_cck = 175,
545 .auto_corr_min_cck_mrc = 160,
546 .auto_corr_max_cck_mrc = 310,
547 .nrg_th_cck = 110,
548 .nrg_th_ofdm = 110,
549
550 .barker_corr_th_min = 190,
551 .barker_corr_th_min_mrc = 336,
552 .nrg_th_cca = 62,
553};
554
555static void iwl6000_hw_set_hw_params(struct iwl_priv *priv)
556{
557 priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) |
558 BIT(IEEE80211_BAND_5GHZ);
559
560 priv->hw_params.tx_chains_num =
561 num_of_ant(priv->hw_params.valid_tx_ant);
562 if (cfg(priv)->rx_with_siso_diversity)
563 priv->hw_params.rx_chains_num = 1;
564 else
565 priv->hw_params.rx_chains_num =
566 num_of_ant(priv->hw_params.valid_rx_ant);
567
568 iwl6000_set_ct_threshold(priv);
569
570 /* Set initial sensitivity parameters */
571 priv->hw_params.sens = &iwl6000_sensitivity;
572
573}
574
575static int iwl6000_hw_channel_switch(struct iwl_priv *priv,
576 struct ieee80211_channel_switch *ch_switch)
577{
578 /*
579 * MULTI-FIXME
580 * See iwlagn_mac_channel_switch.
581 */
582 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
583 struct iwl6000_channel_switch_cmd cmd;
584 const struct iwl_channel_info *ch_info;
585 u32 switch_time_in_usec, ucode_switch_time;
586 u16 ch;
587 u32 tsf_low;
588 u8 switch_count;
589 u16 beacon_interval = le16_to_cpu(ctx->timing.beacon_interval);
590 struct ieee80211_vif *vif = ctx->vif;
591 struct iwl_host_cmd hcmd = {
592 .id = REPLY_CHANNEL_SWITCH,
593 .len = { sizeof(cmd), },
594 .flags = CMD_SYNC,
595 .data = { &cmd, },
596 };
597
598 cmd.band = priv->band == IEEE80211_BAND_2GHZ;
599 ch = ch_switch->channel->hw_value;
600 IWL_DEBUG_11H(priv, "channel switch from %u to %u\n",
601 ctx->active.channel, ch);
602 cmd.channel = cpu_to_le16(ch);
603 cmd.rxon_flags = ctx->staging.flags;
604 cmd.rxon_filter_flags = ctx->staging.filter_flags;
605 switch_count = ch_switch->count;
606 tsf_low = ch_switch->timestamp & 0x0ffffffff;
607 /*
608 * calculate the ucode channel switch time
609 * adding TSF as one of the factor for when to switch
610 */
611 if ((priv->ucode_beacon_time > tsf_low) && beacon_interval) {
612 if (switch_count > ((priv->ucode_beacon_time - tsf_low) /
613 beacon_interval)) {
614 switch_count -= (priv->ucode_beacon_time -
615 tsf_low) / beacon_interval;
616 } else
617 switch_count = 0;
618 }
619 if (switch_count <= 1)
620 cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time);
621 else {
622 switch_time_in_usec =
623 vif->bss_conf.beacon_int * switch_count * TIME_UNIT;
624 ucode_switch_time = iwl_usecs_to_beacons(priv,
625 switch_time_in_usec,
626 beacon_interval);
627 cmd.switch_time = iwl_add_beacon_time(priv,
628 priv->ucode_beacon_time,
629 ucode_switch_time,
630 beacon_interval);
631 }
632 IWL_DEBUG_11H(priv, "uCode time for the switch is 0x%x\n",
633 cmd.switch_time);
634 ch_info = iwl_get_channel_info(priv, priv->band, ch);
635 if (ch_info)
636 cmd.expect_beacon = is_channel_radar(ch_info);
637 else {
638 IWL_ERR(priv, "invalid channel switch from %u to %u\n",
639 ctx->active.channel, ch);
640 return -EFAULT;
641 }
642
643 return iwl_dvm_send_cmd(priv, &hcmd);
644}
645
646struct iwl_lib_ops iwl6000_lib = {
647 .set_hw_params = iwl6000_hw_set_hw_params,
648 .set_channel_switch = iwl6000_hw_channel_switch,
649 .nic_config = iwl6000_nic_config,
650 .eeprom_ops = {
651 .regulatory_bands = {
652 EEPROM_REG_BAND_1_CHANNELS,
653 EEPROM_REG_BAND_2_CHANNELS,
654 EEPROM_REG_BAND_3_CHANNELS,
655 EEPROM_REG_BAND_4_CHANNELS,
656 EEPROM_REG_BAND_5_CHANNELS,
657 EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
658 EEPROM_REG_BAND_52_HT40_CHANNELS
659 },
660 .enhanced_txpower = true,
661 },
662 .temperature = iwlagn_temperature,
663};
664
665struct iwl_lib_ops iwl6030_lib = {
666 .set_hw_params = iwl6000_hw_set_hw_params,
667 .set_channel_switch = iwl6000_hw_channel_switch,
668 .nic_config = iwl6000_nic_config,
669 .eeprom_ops = {
670 .regulatory_bands = {
671 EEPROM_REG_BAND_1_CHANNELS,
672 EEPROM_REG_BAND_2_CHANNELS,
673 EEPROM_REG_BAND_3_CHANNELS,
674 EEPROM_REG_BAND_4_CHANNELS,
675 EEPROM_REG_BAND_5_CHANNELS,
676 EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
677 EEPROM_REG_BAND_52_HT40_CHANNELS
678 },
679 .enhanced_txpower = true,
680 },
681 .temperature = iwlagn_temperature,
682};
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c
index 934ace9468d6..aba1da231d70 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c
@@ -520,8 +520,8 @@ static int iwlagn_rx_statistics(struct iwl_priv *priv,
520 iwlagn_rx_calc_noise(priv); 520 iwlagn_rx_calc_noise(priv);
521 queue_work(priv->workqueue, &priv->run_time_calib_work); 521 queue_work(priv->workqueue, &priv->run_time_calib_work);
522 } 522 }
523 if (cfg(priv)->lib->temperature && change) 523 if (priv->lib->temperature && change)
524 cfg(priv)->lib->temperature(priv); 524 priv->lib->temperature(priv);
525 525
526 spin_unlock(&priv->statistics.lock); 526 spin_unlock(&priv->statistics.lock);
527 527
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 91b3a420df2a..b507ee69b3bb 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -1394,7 +1394,7 @@ static void iwl_set_hw_params(struct iwl_priv *priv)
1394 priv->hw_params.sku &= ~EEPROM_SKU_CAP_11N_ENABLE; 1394 priv->hw_params.sku &= ~EEPROM_SKU_CAP_11N_ENABLE;
1395 1395
1396 /* Device-specific setup */ 1396 /* Device-specific setup */
1397 cfg(priv)->lib->set_hw_params(priv); 1397 priv->lib->set_hw_params(priv);
1398} 1398}
1399 1399
1400 1400
@@ -1471,6 +1471,42 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
1471 priv->shrd = trans->shrd; 1471 priv->shrd = trans->shrd;
1472 priv->fw = fw; 1472 priv->fw = fw;
1473 1473
1474 switch (cfg(priv)->device_family) {
1475 case IWL_DEVICE_FAMILY_1000:
1476 case IWL_DEVICE_FAMILY_100:
1477 priv->lib = &iwl1000_lib;
1478 break;
1479 case IWL_DEVICE_FAMILY_2000:
1480 case IWL_DEVICE_FAMILY_105:
1481 priv->lib = &iwl2000_lib;
1482 break;
1483 case IWL_DEVICE_FAMILY_2030:
1484 case IWL_DEVICE_FAMILY_135:
1485 priv->lib = &iwl2030_lib;
1486 break;
1487 case IWL_DEVICE_FAMILY_5000:
1488 priv->lib = &iwl5000_lib;
1489 break;
1490 case IWL_DEVICE_FAMILY_5150:
1491 priv->lib = &iwl5150_lib;
1492 break;
1493 case IWL_DEVICE_FAMILY_6000:
1494 case IWL_DEVICE_FAMILY_6005:
1495 case IWL_DEVICE_FAMILY_6000i:
1496 case IWL_DEVICE_FAMILY_6050:
1497 case IWL_DEVICE_FAMILY_6150:
1498 priv->lib = &iwl6000_lib;
1499 break;
1500 case IWL_DEVICE_FAMILY_6030:
1501 priv->lib = &iwl6030_lib;
1502 break;
1503 default:
1504 break;
1505 }
1506
1507 if (WARN_ON(!priv->lib))
1508 goto out_free_traffic_mem;
1509
1474 /* 1510 /*
1475 * Populate the state variables that the transport layer needs 1511 * Populate the state variables that the transport layer needs
1476 * to know about. 1512 * to know about.
@@ -2112,7 +2148,7 @@ static void iwl_nic_config(struct iwl_op_mode *op_mode)
2112{ 2148{
2113 struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); 2149 struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
2114 2150
2115 cfg(priv)->lib->nic_config(priv); 2151 priv->lib->nic_config(priv);
2116} 2152}
2117 2153
2118static void iwl_stop_sw_queue(struct iwl_op_mode *op_mode, int queue) 2154static void iwl_stop_sw_queue(struct iwl_op_mode *op_mode, int queue)
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h
index 17b82e5c1f44..6ebb3f75dad1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.h
@@ -71,6 +71,16 @@
71/* AUX (TX during scan dwell) queue */ 71/* AUX (TX during scan dwell) queue */
72#define IWL_AUX_QUEUE 10 72#define IWL_AUX_QUEUE 10
73 73
74/* device operations */
75extern struct iwl_lib_ops iwl1000_lib;
76extern struct iwl_lib_ops iwl2000_lib;
77extern struct iwl_lib_ops iwl2030_lib;
78extern struct iwl_lib_ops iwl5000_lib;
79extern struct iwl_lib_ops iwl5150_lib;
80extern struct iwl_lib_ops iwl6000_lib;
81extern struct iwl_lib_ops iwl6030_lib;
82
83
74 84
75struct iwl_ucode_capabilities; 85struct iwl_ucode_capabilities;
76 86
diff --git a/drivers/net/wireless/iwlwifi/iwl-config.h b/drivers/net/wireless/iwlwifi/iwl-config.h
index bdf2a776789b..47bfd5e59575 100644
--- a/drivers/net/wireless/iwlwifi/iwl-config.h
+++ b/drivers/net/wireless/iwlwifi/iwl-config.h
@@ -66,8 +66,6 @@
66#include <linux/types.h> 66#include <linux/types.h>
67#include <net/mac80211.h> 67#include <net/mac80211.h>
68 68
69struct iwl_lib_ops;
70
71 69
72enum iwl_device_family { 70enum iwl_device_family {
73 IWL_DEVICE_FAMILY_UNDEFINED, 71 IWL_DEVICE_FAMILY_UNDEFINED,
@@ -212,7 +210,6 @@ struct iwl_cfg {
212 u8 valid_rx_ant; 210 u8 valid_rx_ant;
213 u16 eeprom_ver; 211 u16 eeprom_ver;
214 u16 eeprom_calib_ver; 212 u16 eeprom_calib_ver;
215 const struct iwl_lib_ops *lib;
216 /* params not likely to change within a device family */ 213 /* params not likely to change within a device family */
217 const struct iwl_base_params *base_params; 214 const struct iwl_base_params *base_params;
218 /* params likely to change within a device family */ 215 /* params likely to change within a device family */
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 999a806a3848..96a2f8dee40b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -74,21 +74,6 @@ struct iwl_cmd;
74 74
75#define TIME_UNIT 1024 75#define TIME_UNIT 1024
76 76
77struct iwl_lib_ops {
78 /* set hw dependent parameters */
79 void (*set_hw_params)(struct iwl_priv *priv);
80 int (*set_channel_switch)(struct iwl_priv *priv,
81 struct ieee80211_channel_switch *ch_switch);
82 /* device specific configuration */
83 void (*nic_config)(struct iwl_priv *priv);
84
85 /* eeprom operations (as defined in iwl-eeprom.h) */
86 struct iwl_eeprom_ops eeprom_ops;
87
88 /* temperature */
89 void (*temperature)(struct iwl_priv *priv);
90};
91
92/*************************** 77/***************************
93 * L i b * 78 * L i b *
94 ***************************/ 79 ***************************/
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 4a24e860fac7..2c41423a5e43 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -704,6 +704,21 @@ struct iwl_hw_params {
704 const struct iwl_sensitivity_ranges *sens; 704 const struct iwl_sensitivity_ranges *sens;
705}; 705};
706 706
707struct iwl_lib_ops {
708 /* set hw dependent parameters */
709 void (*set_hw_params)(struct iwl_priv *priv);
710 int (*set_channel_switch)(struct iwl_priv *priv,
711 struct ieee80211_channel_switch *ch_switch);
712 /* device specific configuration */
713 void (*nic_config)(struct iwl_priv *priv);
714
715 /* eeprom operations (as defined in iwl-eeprom.h) */
716 struct iwl_eeprom_ops eeprom_ops;
717
718 /* temperature */
719 void (*temperature)(struct iwl_priv *priv);
720};
721
707#ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE 722#ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE
708struct iwl_testmode_trace { 723struct iwl_testmode_trace {
709 u32 buff_size; 724 u32 buff_size;
@@ -740,6 +755,7 @@ struct iwl_priv {
740 /*data shared among all the driver's layers */ 755 /*data shared among all the driver's layers */
741 struct iwl_shared *shrd; 756 struct iwl_shared *shrd;
742 const struct iwl_fw *fw; 757 const struct iwl_fw *fw;
758 const struct iwl_lib_ops *lib;
743 unsigned long status; 759 unsigned long status;
744 760
745 spinlock_t sta_lock; 761 spinlock_t sta_lock;
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
index 1db98d67706d..a004431d1a60 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
@@ -836,7 +836,7 @@ static void iwl_init_band_reference(struct iwl_priv *priv,
836 const struct iwl_eeprom_channel **eeprom_ch_info, 836 const struct iwl_eeprom_channel **eeprom_ch_info,
837 const u8 **eeprom_ch_index) 837 const u8 **eeprom_ch_index)
838{ 838{
839 u32 offset = cfg(priv)->lib-> 839 u32 offset = priv->lib->
840 eeprom_ops.regulatory_bands[eep_band - 1]; 840 eeprom_ops.regulatory_bands[eep_band - 1];
841 switch (eep_band) { 841 switch (eep_band) {
842 case 1: /* 2.4GHz band */ 842 case 1: /* 2.4GHz band */
@@ -1043,9 +1043,9 @@ int iwl_init_channel_map(struct iwl_priv *priv)
1043 } 1043 }
1044 1044
1045 /* Check if we do have HT40 channels */ 1045 /* Check if we do have HT40 channels */
1046 if (cfg(priv)->lib->eeprom_ops.regulatory_bands[5] == 1046 if (priv->lib->eeprom_ops.regulatory_bands[5] ==
1047 EEPROM_REGULATORY_BAND_NO_HT40 && 1047 EEPROM_REGULATORY_BAND_NO_HT40 &&
1048 cfg(priv)->lib->eeprom_ops.regulatory_bands[6] == 1048 priv->lib->eeprom_ops.regulatory_bands[6] ==
1049 EEPROM_REGULATORY_BAND_NO_HT40) 1049 EEPROM_REGULATORY_BAND_NO_HT40)
1050 return 0; 1050 return 0;
1051 1051
@@ -1081,7 +1081,7 @@ int iwl_init_channel_map(struct iwl_priv *priv)
1081 * driver need to process addition information 1081 * driver need to process addition information
1082 * to determine the max channel tx power limits 1082 * to determine the max channel tx power limits
1083 */ 1083 */
1084 if (cfg(priv)->lib->eeprom_ops.enhanced_txpower) 1084 if (priv->lib->eeprom_ops.enhanced_txpower)
1085 iwl_eeprom_enhanced_txpower(priv); 1085 iwl_eeprom_enhanced_txpower(priv);
1086 1086
1087 return 0; 1087 return 0;
diff --git a/drivers/net/wireless/iwlwifi/iwl-mac80211.c b/drivers/net/wireless/iwlwifi/iwl-mac80211.c
index 75cb4cc1e994..a3aa5a4fe327 100644
--- a/drivers/net/wireless/iwlwifi/iwl-mac80211.c
+++ b/drivers/net/wireless/iwlwifi/iwl-mac80211.c
@@ -867,7 +867,7 @@ static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw,
867 if (!iwl_is_associated_ctx(ctx)) 867 if (!iwl_is_associated_ctx(ctx))
868 goto out; 868 goto out;
869 869
870 if (!cfg(priv)->lib->set_channel_switch) 870 if (!priv->lib->set_channel_switch)
871 goto out; 871 goto out;
872 872
873 ch = channel->hw_value; 873 ch = channel->hw_value;
@@ -903,7 +903,7 @@ static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw,
903 */ 903 */
904 set_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status); 904 set_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status);
905 priv->switch_channel = cpu_to_le16(ch); 905 priv->switch_channel = cpu_to_le16(ch);
906 if (cfg(priv)->lib->set_channel_switch(priv, ch_switch)) { 906 if (priv->lib->set_channel_switch(priv, ch_switch)) {
907 clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status); 907 clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status);
908 priv->switch_channel = 0; 908 priv->switch_channel = 0;
909 ieee80211_chswitch_done(ctx->vif, false); 909 ieee80211_chswitch_done(ctx->vif, false);