aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2012-04-10 17:10:28 -0400
committerJohn W. Linville <linville@tuxdriver.com>2012-04-12 15:10:48 -0400
commite96766958c914f1240317c967bb322cd3731fb17 (patch)
treed7c6c955f0e00e77bb80a3b576b49721c7c2d69b
parenta141e6a0097118bb35024485f1faffc0d9042f5c (diff)
iwlwifi: dynamically determine lib_ops
Having the pointer to lib_ops in the config makes it impossible to split the driver into different modules. Determine the ops based on the device family enumeration to get rid of the direct pointer. Also move all the opmode specific code from the iwl-[1256]000.c files into a new file iwl-agn-devices.c so that the former only have configuration data now. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-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);