diff options
author | John W. Linville <linville@tuxdriver.com> | 2012-04-18 14:17:13 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2012-04-18 14:27:48 -0400 |
commit | 59ef43e681d103a51c3727dad0315e093f07ec61 (patch) | |
tree | 87f6320f1440ce3ce6c0c15ad3cef8bc98186f88 /drivers/net/wireless/iwlwifi | |
parent | 91fbe33034c184c6a60e31c2207a2f7ec2f180dc (diff) | |
parent | b5abcf0219263f4e961dca71cbe26e06c5b0ee68 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next into for-davem
Conflicts:
drivers/net/wireless/iwlwifi/iwl-testmode.c
include/net/nfc/nfc.h
net/nfc/netlink.c
net/wireless/nl80211.c
Diffstat (limited to 'drivers/net/wireless/iwlwifi')
42 files changed, 2639 insertions, 2714 deletions
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig index 565611eef0d4..db6c6e528022 100644 --- a/drivers/net/wireless/iwlwifi/Kconfig +++ b/drivers/net/wireless/iwlwifi/Kconfig | |||
@@ -113,20 +113,21 @@ config IWLWIFI_DEVICE_TESTMODE | |||
113 | generic netlink message via NL80211_TESTMODE channel. | 113 | generic netlink message via NL80211_TESTMODE channel. |
114 | 114 | ||
115 | config IWLWIFI_P2P | 115 | config IWLWIFI_P2P |
116 | bool "iwlwifi experimental P2P support" | 116 | def_bool y |
117 | depends on IWLWIFI | 117 | bool "iwlwifi experimental P2P support" |
118 | help | 118 | depends on IWLWIFI |
119 | This option enables experimental P2P support for some devices | 119 | help |
120 | based on microcode support. Since P2P support is still under | 120 | This option enables experimental P2P support for some devices |
121 | development, this option may even enable it for some devices | 121 | based on microcode support. Since P2P support is still under |
122 | now that turn out to not support it in the future due to | 122 | development, this option may even enable it for some devices |
123 | microcode restrictions. | 123 | now that turn out to not support it in the future due to |
124 | 124 | microcode restrictions. | |
125 | To determine if your microcode supports the experimental P2P | 125 | |
126 | offered by this option, check if the driver advertises AP | 126 | To determine if your microcode supports the experimental P2P |
127 | support when it is loaded. | 127 | offered by this option, check if the driver advertises AP |
128 | 128 | support when it is loaded. | |
129 | Say Y only if you want to experiment with P2P. | 129 | |
130 | Say Y only if you want to experiment with P2P. | ||
130 | 131 | ||
131 | config IWLWIFI_EXPERIMENTAL_MFP | 132 | config IWLWIFI_EXPERIMENTAL_MFP |
132 | bool "support MFP (802.11w) even if uCode doesn't advertise" | 133 | bool "support MFP (802.11w) even if uCode doesn't advertise" |
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 | ||
8 | iwlwifi-objs += iwl-core.o iwl-eeprom.o iwl-power.o | 8 | iwlwifi-objs += iwl-core.o iwl-eeprom.o iwl-power.o |
9 | iwlwifi-objs += iwl-scan.o iwl-led.o | 9 | iwlwifi-objs += iwl-scan.o iwl-led.o |
10 | iwlwifi-objs += iwl-agn-rxon.o | 10 | iwlwifi-objs += iwl-agn-rxon.o iwl-agn-devices.o |
11 | iwlwifi-objs += iwl-5000.o | 11 | iwlwifi-objs += iwl-5000.o |
12 | iwlwifi-objs += iwl-6000.o | 12 | iwlwifi-objs += iwl-6000.o |
13 | iwlwifi-objs += iwl-1000.o | 13 | iwlwifi-objs += iwl-1000.o |
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 95c59e39b803..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 | */ | ||
77 | static void iwl1000_set_ct_threshold(struct iwl_priv *priv) | ||
78 | { | ||
79 | /* want Celsius */ | ||
80 | hw_params(priv).ct_kill_threshold = CT_KILL_THRESHOLD_LEGACY; | ||
81 | hw_params(priv).ct_kill_exit_threshold = CT_KILL_EXIT_THRESHOLD; | ||
82 | } | ||
83 | |||
84 | /* NIC configuration for 1000 series */ | ||
85 | static 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 | |||
99 | static 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 | |||
123 | static void iwl1000_hw_set_hw_params(struct iwl_priv *priv) | ||
124 | { | ||
125 | hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ); | ||
126 | |||
127 | hw_params(priv).tx_chains_num = | ||
128 | num_of_ant(hw_params(priv).valid_tx_ant); | ||
129 | if (cfg(priv)->rx_with_siso_diversity) | ||
130 | hw_params(priv).rx_chains_num = 1; | ||
131 | else | ||
132 | hw_params(priv).rx_chains_num = | ||
133 | num_of_ant(hw_params(priv).valid_rx_ant); | ||
134 | |||
135 | iwl1000_set_ct_threshold(priv); | ||
136 | |||
137 | /* Set initial sensitivity parameters */ | ||
138 | hw_params(priv).sens = &iwl1000_sensitivity; | ||
139 | } | ||
140 | |||
141 | static 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 | |||
158 | static const struct iwl_base_params iwl1000_base_params = { | 52 | static 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, |
@@ -165,9 +59,8 @@ static const struct iwl_base_params iwl1000_base_params = { | |||
165 | .support_ct_kill_exit = true, | 59 | .support_ct_kill_exit = true, |
166 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF, | 60 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF, |
167 | .chain_noise_scale = 1000, | 61 | .chain_noise_scale = 1000, |
168 | .wd_timeout = IWL_DEF_WD_TIMEOUT, | 62 | .wd_timeout = IWL_WATCHHDOG_DISABLED, |
169 | .max_event_log_size = 128, | 63 | .max_event_log_size = 128, |
170 | .wd_disable = true, | ||
171 | }; | 64 | }; |
172 | 65 | ||
173 | static const struct iwl_ht_params iwl1000_ht_params = { | 66 | static const struct iwl_ht_params iwl1000_ht_params = { |
@@ -181,11 +74,11 @@ static const struct iwl_ht_params iwl1000_ht_params = { | |||
181 | .ucode_api_max = IWL1000_UCODE_API_MAX, \ | 74 | .ucode_api_max = IWL1000_UCODE_API_MAX, \ |
182 | .ucode_api_ok = IWL1000_UCODE_API_OK, \ | 75 | .ucode_api_ok = IWL1000_UCODE_API_OK, \ |
183 | .ucode_api_min = IWL1000_UCODE_API_MIN, \ | 76 | .ucode_api_min = IWL1000_UCODE_API_MIN, \ |
77 | .device_family = IWL_DEVICE_FAMILY_1000, \ | ||
184 | .max_inst_size = IWLAGN_RTC_INST_SIZE, \ | 78 | .max_inst_size = IWLAGN_RTC_INST_SIZE, \ |
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 | ||
@@ -205,11 +98,11 @@ const struct iwl_cfg iwl1000_bg_cfg = { | |||
205 | .ucode_api_max = IWL100_UCODE_API_MAX, \ | 98 | .ucode_api_max = IWL100_UCODE_API_MAX, \ |
206 | .ucode_api_ok = IWL100_UCODE_API_OK, \ | 99 | .ucode_api_ok = IWL100_UCODE_API_OK, \ |
207 | .ucode_api_min = IWL100_UCODE_API_MIN, \ | 100 | .ucode_api_min = IWL100_UCODE_API_MIN, \ |
101 | .device_family = IWL_DEVICE_FAMILY_100, \ | ||
208 | .max_inst_size = IWLAGN_RTC_INST_SIZE, \ | 102 | .max_inst_size = IWLAGN_RTC_INST_SIZE, \ |
209 | .max_data_size = IWLAGN_RTC_DATA_SIZE, \ | 103 | .max_data_size = IWLAGN_RTC_DATA_SIZE, \ |
210 | .eeprom_ver = EEPROM_1000_EEPROM_VERSION, \ | 104 | .eeprom_ver = EEPROM_1000_EEPROM_VERSION, \ |
211 | .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, \ | 105 | .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, \ |
212 | .lib = &iwl1000_lib, \ | ||
213 | .base_params = &iwl1000_base_params, \ | 106 | .base_params = &iwl1000_base_params, \ |
214 | .led_mode = IWL_LED_RF_STATE, \ | 107 | .led_mode = IWL_LED_RF_STATE, \ |
215 | .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 e1329a13f0fd..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 | ||
77 | static void iwl2000_set_ct_threshold(struct iwl_priv *priv) | ||
78 | { | ||
79 | /* want Celsius */ | ||
80 | hw_params(priv).ct_kill_threshold = CT_KILL_THRESHOLD; | ||
81 | hw_params(priv).ct_kill_exit_threshold = CT_KILL_EXIT_THRESHOLD; | ||
82 | } | ||
83 | |||
84 | /* NIC configuration for 2000 series */ | ||
85 | static 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 | |||
93 | static 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 | |||
117 | static void iwl2000_hw_set_hw_params(struct iwl_priv *priv) | ||
118 | { | ||
119 | hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ); | ||
120 | |||
121 | hw_params(priv).tx_chains_num = | ||
122 | num_of_ant(hw_params(priv).valid_tx_ant); | ||
123 | if (cfg(priv)->rx_with_siso_diversity) | ||
124 | hw_params(priv).rx_chains_num = 1; | ||
125 | else | ||
126 | hw_params(priv).rx_chains_num = | ||
127 | num_of_ant(hw_params(priv).valid_rx_ant); | ||
128 | |||
129 | iwl2000_set_ct_threshold(priv); | ||
130 | |||
131 | /* Set initial sensitivity parameters */ | ||
132 | hw_params(priv).sens = &iwl2000_sensitivity; | ||
133 | } | ||
134 | |||
135 | static 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 | |||
153 | static 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 | |||
171 | static const struct iwl_base_params iwl2000_base_params = { | 63 | static 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, |
@@ -223,11 +115,11 @@ static const struct iwl_bt_params iwl2030_bt_params = { | |||
223 | .ucode_api_max = IWL2000_UCODE_API_MAX, \ | 115 | .ucode_api_max = IWL2000_UCODE_API_MAX, \ |
224 | .ucode_api_ok = IWL2000_UCODE_API_OK, \ | 116 | .ucode_api_ok = IWL2000_UCODE_API_OK, \ |
225 | .ucode_api_min = IWL2000_UCODE_API_MIN, \ | 117 | .ucode_api_min = IWL2000_UCODE_API_MIN, \ |
118 | .device_family = IWL_DEVICE_FAMILY_2000, \ | ||
226 | .max_inst_size = IWL60_RTC_INST_SIZE, \ | 119 | .max_inst_size = IWL60_RTC_INST_SIZE, \ |
227 | .max_data_size = IWL60_RTC_DATA_SIZE, \ | 120 | .max_data_size = IWL60_RTC_DATA_SIZE, \ |
228 | .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \ | 121 | .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \ |
229 | .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ | 122 | .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ |
230 | .lib = &iwl2000_lib, \ | ||
231 | .base_params = &iwl2000_base_params, \ | 123 | .base_params = &iwl2000_base_params, \ |
232 | .need_temp_offset_calib = true, \ | 124 | .need_temp_offset_calib = true, \ |
233 | .temp_offset_v2 = true, \ | 125 | .temp_offset_v2 = true, \ |
@@ -250,11 +142,11 @@ const struct iwl_cfg iwl2000_2bgn_d_cfg = { | |||
250 | .ucode_api_max = IWL2030_UCODE_API_MAX, \ | 142 | .ucode_api_max = IWL2030_UCODE_API_MAX, \ |
251 | .ucode_api_ok = IWL2030_UCODE_API_OK, \ | 143 | .ucode_api_ok = IWL2030_UCODE_API_OK, \ |
252 | .ucode_api_min = IWL2030_UCODE_API_MIN, \ | 144 | .ucode_api_min = IWL2030_UCODE_API_MIN, \ |
145 | .device_family = IWL_DEVICE_FAMILY_2030, \ | ||
253 | .max_inst_size = IWL60_RTC_INST_SIZE, \ | 146 | .max_inst_size = IWL60_RTC_INST_SIZE, \ |
254 | .max_data_size = IWL60_RTC_DATA_SIZE, \ | 147 | .max_data_size = IWL60_RTC_DATA_SIZE, \ |
255 | .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \ | 148 | .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \ |
256 | .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ | 149 | .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ |
257 | .lib = &iwl2030_lib, \ | ||
258 | .base_params = &iwl2030_base_params, \ | 150 | .base_params = &iwl2030_base_params, \ |
259 | .bt_params = &iwl2030_bt_params, \ | 151 | .bt_params = &iwl2030_bt_params, \ |
260 | .need_temp_offset_calib = true, \ | 152 | .need_temp_offset_calib = true, \ |
@@ -273,11 +165,11 @@ const struct iwl_cfg iwl2030_2bgn_cfg = { | |||
273 | .ucode_api_max = IWL105_UCODE_API_MAX, \ | 165 | .ucode_api_max = IWL105_UCODE_API_MAX, \ |
274 | .ucode_api_ok = IWL105_UCODE_API_OK, \ | 166 | .ucode_api_ok = IWL105_UCODE_API_OK, \ |
275 | .ucode_api_min = IWL105_UCODE_API_MIN, \ | 167 | .ucode_api_min = IWL105_UCODE_API_MIN, \ |
168 | .device_family = IWL_DEVICE_FAMILY_105, \ | ||
276 | .max_inst_size = IWL60_RTC_INST_SIZE, \ | 169 | .max_inst_size = IWL60_RTC_INST_SIZE, \ |
277 | .max_data_size = IWL60_RTC_DATA_SIZE, \ | 170 | .max_data_size = IWL60_RTC_DATA_SIZE, \ |
278 | .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \ | 171 | .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \ |
279 | .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ | 172 | .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ |
280 | .lib = &iwl2000_lib, \ | ||
281 | .base_params = &iwl2000_base_params, \ | 173 | .base_params = &iwl2000_base_params, \ |
282 | .need_temp_offset_calib = true, \ | 174 | .need_temp_offset_calib = true, \ |
283 | .temp_offset_v2 = true, \ | 175 | .temp_offset_v2 = true, \ |
@@ -302,11 +194,11 @@ const struct iwl_cfg iwl105_bgn_d_cfg = { | |||
302 | .ucode_api_max = IWL135_UCODE_API_MAX, \ | 194 | .ucode_api_max = IWL135_UCODE_API_MAX, \ |
303 | .ucode_api_ok = IWL135_UCODE_API_OK, \ | 195 | .ucode_api_ok = IWL135_UCODE_API_OK, \ |
304 | .ucode_api_min = IWL135_UCODE_API_MIN, \ | 196 | .ucode_api_min = IWL135_UCODE_API_MIN, \ |
197 | .device_family = IWL_DEVICE_FAMILY_135, \ | ||
305 | .max_inst_size = IWL60_RTC_INST_SIZE, \ | 198 | .max_inst_size = IWL60_RTC_INST_SIZE, \ |
306 | .max_data_size = IWL60_RTC_DATA_SIZE, \ | 199 | .max_data_size = IWL60_RTC_DATA_SIZE, \ |
307 | .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \ | 200 | .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \ |
308 | .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ | 201 | .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ |
309 | .lib = &iwl2030_lib, \ | ||
310 | .base_params = &iwl2030_base_params, \ | 202 | .base_params = &iwl2030_base_params, \ |
311 | .bt_params = &iwl2030_bt_params, \ | 203 | .bt_params = &iwl2030_bt_params, \ |
312 | .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 34bc8dd0064b..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 */ | ||
65 | static 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 | |||
78 | static 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 | |||
102 | static 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 | |||
129 | static s32 iwl_temp_calib_to_offset(struct iwl_shared *shrd) | ||
130 | { | ||
131 | u16 temperature, voltage; | ||
132 | __le16 *temp_calib = (__le16 *)iwl_eeprom_query_addr(shrd, | ||
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 | |||
142 | static 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->shrd); | ||
147 | |||
148 | hw_params(priv).ct_kill_threshold = threshold * volt2temp_coef; | ||
149 | } | ||
150 | |||
151 | static void iwl5000_set_ct_threshold(struct iwl_priv *priv) | ||
152 | { | ||
153 | /* want Celsius */ | ||
154 | hw_params(priv).ct_kill_threshold = CT_KILL_THRESHOLD_LEGACY; | ||
155 | } | ||
156 | |||
157 | static void iwl5000_hw_set_hw_params(struct iwl_priv *priv) | ||
158 | { | ||
159 | hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ) | | ||
160 | BIT(IEEE80211_BAND_5GHZ); | ||
161 | |||
162 | hw_params(priv).tx_chains_num = | ||
163 | num_of_ant(hw_params(priv).valid_tx_ant); | ||
164 | hw_params(priv).rx_chains_num = | ||
165 | num_of_ant(hw_params(priv).valid_rx_ant); | ||
166 | |||
167 | iwl5000_set_ct_threshold(priv); | ||
168 | |||
169 | /* Set initial sensitivity parameters */ | ||
170 | hw_params(priv).sens = &iwl5000_sensitivity; | ||
171 | } | ||
172 | |||
173 | static void iwl5150_hw_set_hw_params(struct iwl_priv *priv) | ||
174 | { | ||
175 | hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ) | | ||
176 | BIT(IEEE80211_BAND_5GHZ); | ||
177 | |||
178 | hw_params(priv).tx_chains_num = | ||
179 | num_of_ant(hw_params(priv).valid_tx_ant); | ||
180 | hw_params(priv).rx_chains_num = | ||
181 | num_of_ant(hw_params(priv).valid_rx_ant); | ||
182 | |||
183 | iwl5150_set_ct_threshold(priv); | ||
184 | |||
185 | /* Set initial sensitivity parameters */ | ||
186 | hw_params(priv).sens = &iwl5150_sensitivity; | ||
187 | } | ||
188 | |||
189 | static void iwl5150_temperature(struct iwl_priv *priv) | ||
190 | { | ||
191 | u32 vt = 0; | ||
192 | s32 offset = iwl_temp_calib_to_offset(priv->shrd); | ||
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 | |||
201 | static 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 | |||
272 | static 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 | |||
290 | static 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 | |||
308 | static const struct iwl_base_params iwl5000_base_params = { | 47 | static 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, |
@@ -312,10 +51,9 @@ static const struct iwl_base_params iwl5000_base_params = { | |||
312 | .led_compensation = 51, | 51 | .led_compensation = 51, |
313 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, | 52 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, |
314 | .chain_noise_scale = 1000, | 53 | .chain_noise_scale = 1000, |
315 | .wd_timeout = IWL_LONG_WD_TIMEOUT, | 54 | .wd_timeout = IWL_WATCHHDOG_DISABLED, |
316 | .max_event_log_size = 512, | 55 | .max_event_log_size = 512, |
317 | .no_idle_support = true, | 56 | .no_idle_support = true, |
318 | .wd_disable = true, | ||
319 | }; | 57 | }; |
320 | 58 | ||
321 | static const struct iwl_ht_params iwl5000_ht_params = { | 59 | static const struct iwl_ht_params iwl5000_ht_params = { |
@@ -326,11 +64,11 @@ static const struct iwl_ht_params iwl5000_ht_params = { | |||
326 | .fw_name_pre = IWL5000_FW_PRE, \ | 64 | .fw_name_pre = IWL5000_FW_PRE, \ |
327 | .ucode_api_max = IWL5000_UCODE_API_MAX, \ | 65 | .ucode_api_max = IWL5000_UCODE_API_MAX, \ |
328 | .ucode_api_min = IWL5000_UCODE_API_MIN, \ | 66 | .ucode_api_min = IWL5000_UCODE_API_MIN, \ |
67 | .device_family = IWL_DEVICE_FAMILY_5000, \ | ||
329 | .max_inst_size = IWLAGN_RTC_INST_SIZE, \ | 68 | .max_inst_size = IWLAGN_RTC_INST_SIZE, \ |
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 | ||
@@ -371,11 +109,11 @@ const struct iwl_cfg iwl5350_agn_cfg = { | |||
371 | .fw_name_pre = IWL5000_FW_PRE, | 109 | .fw_name_pre = IWL5000_FW_PRE, |
372 | .ucode_api_max = IWL5000_UCODE_API_MAX, | 110 | .ucode_api_max = IWL5000_UCODE_API_MAX, |
373 | .ucode_api_min = IWL5000_UCODE_API_MIN, | 111 | .ucode_api_min = IWL5000_UCODE_API_MIN, |
112 | .device_family = IWL_DEVICE_FAMILY_5000, | ||
374 | .max_inst_size = IWLAGN_RTC_INST_SIZE, | 113 | .max_inst_size = IWLAGN_RTC_INST_SIZE, |
375 | .max_data_size = IWLAGN_RTC_DATA_SIZE, | 114 | .max_data_size = IWLAGN_RTC_DATA_SIZE, |
376 | .eeprom_ver = EEPROM_5050_EEPROM_VERSION, | 115 | .eeprom_ver = EEPROM_5050_EEPROM_VERSION, |
377 | .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, | 116 | .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, |
378 | .lib = &iwl5000_lib, | ||
379 | .base_params = &iwl5000_base_params, | 117 | .base_params = &iwl5000_base_params, |
380 | .ht_params = &iwl5000_ht_params, | 118 | .ht_params = &iwl5000_ht_params, |
381 | .led_mode = IWL_LED_BLINK, | 119 | .led_mode = IWL_LED_BLINK, |
@@ -386,11 +124,11 @@ const struct iwl_cfg iwl5350_agn_cfg = { | |||
386 | .fw_name_pre = IWL5150_FW_PRE, \ | 124 | .fw_name_pre = IWL5150_FW_PRE, \ |
387 | .ucode_api_max = IWL5150_UCODE_API_MAX, \ | 125 | .ucode_api_max = IWL5150_UCODE_API_MAX, \ |
388 | .ucode_api_min = IWL5150_UCODE_API_MIN, \ | 126 | .ucode_api_min = IWL5150_UCODE_API_MIN, \ |
127 | .device_family = IWL_DEVICE_FAMILY_5150, \ | ||
389 | .max_inst_size = IWLAGN_RTC_INST_SIZE, \ | 128 | .max_inst_size = IWLAGN_RTC_INST_SIZE, \ |
390 | .max_data_size = IWLAGN_RTC_DATA_SIZE, \ | 129 | .max_data_size = IWLAGN_RTC_DATA_SIZE, \ |
391 | .eeprom_ver = EEPROM_5050_EEPROM_VERSION, \ | 130 | .eeprom_ver = EEPROM_5050_EEPROM_VERSION, \ |
392 | .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, \ | 131 | .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, \ |
393 | .lib = &iwl5150_lib, \ | ||
394 | .base_params = &iwl5000_base_params, \ | 132 | .base_params = &iwl5000_base_params, \ |
395 | .no_xtal_calib = true, \ | 133 | .no_xtal_calib = true, \ |
396 | .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 7075570a0f2c..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,201 +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 | ||
74 | static void iwl6000_set_ct_threshold(struct iwl_priv *priv) | ||
75 | { | ||
76 | /* want Celsius */ | ||
77 | hw_params(priv).ct_kill_threshold = CT_KILL_THRESHOLD; | ||
78 | hw_params(priv).ct_kill_exit_threshold = CT_KILL_EXIT_THRESHOLD; | ||
79 | } | ||
80 | |||
81 | static void iwl6050_additional_nic_config(struct iwl_priv *priv) | ||
82 | { | ||
83 | /* Indicate calibration version to uCode. */ | ||
84 | if (iwl_eeprom_calib_version(priv->shrd) >= 6) | ||
85 | iwl_set_bit(trans(priv), CSR_GP_DRIVER_REG, | ||
86 | CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6); | ||
87 | } | ||
88 | |||
89 | static void iwl6150_additional_nic_config(struct iwl_priv *priv) | ||
90 | { | ||
91 | /* Indicate calibration version to uCode. */ | ||
92 | if (iwl_eeprom_calib_version(priv->shrd) >= 6) | ||
93 | iwl_set_bit(trans(priv), CSR_GP_DRIVER_REG, | ||
94 | CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6); | ||
95 | iwl_set_bit(trans(priv), CSR_GP_DRIVER_REG, | ||
96 | CSR_GP_DRIVER_REG_BIT_6050_1x2); | ||
97 | } | ||
98 | |||
99 | static void iwl6000i_additional_nic_config(struct iwl_priv *priv) | ||
100 | { | ||
101 | /* 2x2 IPA phy type */ | ||
102 | iwl_write32(trans(priv), CSR_GP_DRIVER_REG, | ||
103 | CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_IPA); | ||
104 | } | ||
105 | |||
106 | /* NIC configuration for 6000 series */ | ||
107 | static void iwl6000_nic_config(struct iwl_priv *priv) | ||
108 | { | ||
109 | iwl_rf_config(priv); | ||
110 | |||
111 | /* do additional nic configuration if needed */ | ||
112 | if (cfg(priv)->additional_nic_config) | ||
113 | cfg(priv)->additional_nic_config(priv); | ||
114 | } | ||
115 | |||
116 | static const struct iwl_sensitivity_ranges iwl6000_sensitivity = { | ||
117 | .min_nrg_cck = 110, | ||
118 | .auto_corr_min_ofdm = 80, | ||
119 | .auto_corr_min_ofdm_mrc = 128, | ||
120 | .auto_corr_min_ofdm_x1 = 105, | ||
121 | .auto_corr_min_ofdm_mrc_x1 = 192, | ||
122 | |||
123 | .auto_corr_max_ofdm = 145, | ||
124 | .auto_corr_max_ofdm_mrc = 232, | ||
125 | .auto_corr_max_ofdm_x1 = 110, | ||
126 | .auto_corr_max_ofdm_mrc_x1 = 232, | ||
127 | |||
128 | .auto_corr_min_cck = 125, | ||
129 | .auto_corr_max_cck = 175, | ||
130 | .auto_corr_min_cck_mrc = 160, | ||
131 | .auto_corr_max_cck_mrc = 310, | ||
132 | .nrg_th_cck = 110, | ||
133 | .nrg_th_ofdm = 110, | ||
134 | |||
135 | .barker_corr_th_min = 190, | ||
136 | .barker_corr_th_min_mrc = 336, | ||
137 | .nrg_th_cca = 62, | ||
138 | }; | ||
139 | |||
140 | static void iwl6000_hw_set_hw_params(struct iwl_priv *priv) | ||
141 | { | ||
142 | hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ) | | ||
143 | BIT(IEEE80211_BAND_5GHZ); | ||
144 | |||
145 | hw_params(priv).tx_chains_num = | ||
146 | num_of_ant(hw_params(priv).valid_tx_ant); | ||
147 | if (cfg(priv)->rx_with_siso_diversity) | ||
148 | hw_params(priv).rx_chains_num = 1; | ||
149 | else | ||
150 | hw_params(priv).rx_chains_num = | ||
151 | num_of_ant(hw_params(priv).valid_rx_ant); | ||
152 | |||
153 | iwl6000_set_ct_threshold(priv); | ||
154 | |||
155 | /* Set initial sensitivity parameters */ | ||
156 | hw_params(priv).sens = &iwl6000_sensitivity; | ||
157 | |||
158 | } | ||
159 | |||
160 | static int iwl6000_hw_channel_switch(struct iwl_priv *priv, | ||
161 | struct ieee80211_channel_switch *ch_switch) | ||
162 | { | ||
163 | /* | ||
164 | * MULTI-FIXME | ||
165 | * See iwlagn_mac_channel_switch. | ||
166 | */ | ||
167 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | ||
168 | struct iwl6000_channel_switch_cmd cmd; | ||
169 | const struct iwl_channel_info *ch_info; | ||
170 | u32 switch_time_in_usec, ucode_switch_time; | ||
171 | u16 ch; | ||
172 | u32 tsf_low; | ||
173 | u8 switch_count; | ||
174 | u16 beacon_interval = le16_to_cpu(ctx->timing.beacon_interval); | ||
175 | struct ieee80211_vif *vif = ctx->vif; | ||
176 | struct iwl_host_cmd hcmd = { | ||
177 | .id = REPLY_CHANNEL_SWITCH, | ||
178 | .len = { sizeof(cmd), }, | ||
179 | .flags = CMD_SYNC, | ||
180 | .data = { &cmd, }, | ||
181 | }; | ||
182 | |||
183 | cmd.band = priv->band == IEEE80211_BAND_2GHZ; | ||
184 | ch = ch_switch->channel->hw_value; | ||
185 | IWL_DEBUG_11H(priv, "channel switch from %u to %u\n", | ||
186 | ctx->active.channel, ch); | ||
187 | cmd.channel = cpu_to_le16(ch); | ||
188 | cmd.rxon_flags = ctx->staging.flags; | ||
189 | cmd.rxon_filter_flags = ctx->staging.filter_flags; | ||
190 | switch_count = ch_switch->count; | ||
191 | tsf_low = ch_switch->timestamp & 0x0ffffffff; | ||
192 | /* | ||
193 | * calculate the ucode channel switch time | ||
194 | * adding TSF as one of the factor for when to switch | ||
195 | */ | ||
196 | if ((priv->ucode_beacon_time > tsf_low) && beacon_interval) { | ||
197 | if (switch_count > ((priv->ucode_beacon_time - tsf_low) / | ||
198 | beacon_interval)) { | ||
199 | switch_count -= (priv->ucode_beacon_time - | ||
200 | tsf_low) / beacon_interval; | ||
201 | } else | ||
202 | switch_count = 0; | ||
203 | } | ||
204 | if (switch_count <= 1) | ||
205 | cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time); | ||
206 | else { | ||
207 | switch_time_in_usec = | ||
208 | vif->bss_conf.beacon_int * switch_count * TIME_UNIT; | ||
209 | ucode_switch_time = iwl_usecs_to_beacons(priv, | ||
210 | switch_time_in_usec, | ||
211 | beacon_interval); | ||
212 | cmd.switch_time = iwl_add_beacon_time(priv, | ||
213 | priv->ucode_beacon_time, | ||
214 | ucode_switch_time, | ||
215 | beacon_interval); | ||
216 | } | ||
217 | IWL_DEBUG_11H(priv, "uCode time for the switch is 0x%x\n", | ||
218 | cmd.switch_time); | ||
219 | ch_info = iwl_get_channel_info(priv, priv->band, ch); | ||
220 | if (ch_info) | ||
221 | cmd.expect_beacon = is_channel_radar(ch_info); | ||
222 | else { | ||
223 | IWL_ERR(priv, "invalid channel switch from %u to %u\n", | ||
224 | ctx->active.channel, ch); | ||
225 | return -EFAULT; | ||
226 | } | ||
227 | |||
228 | return iwl_dvm_send_cmd(priv, &hcmd); | ||
229 | } | ||
230 | |||
231 | static struct iwl_lib_ops iwl6000_lib = { | ||
232 | .set_hw_params = iwl6000_hw_set_hw_params, | ||
233 | .set_channel_switch = iwl6000_hw_channel_switch, | ||
234 | .nic_config = iwl6000_nic_config, | ||
235 | .eeprom_ops = { | ||
236 | .regulatory_bands = { | ||
237 | EEPROM_REG_BAND_1_CHANNELS, | ||
238 | EEPROM_REG_BAND_2_CHANNELS, | ||
239 | EEPROM_REG_BAND_3_CHANNELS, | ||
240 | EEPROM_REG_BAND_4_CHANNELS, | ||
241 | EEPROM_REG_BAND_5_CHANNELS, | ||
242 | EEPROM_6000_REG_BAND_24_HT40_CHANNELS, | ||
243 | EEPROM_REG_BAND_52_HT40_CHANNELS | ||
244 | }, | ||
245 | .enhanced_txpower = true, | ||
246 | }, | ||
247 | .temperature = iwlagn_temperature, | ||
248 | }; | ||
249 | |||
250 | static struct iwl_lib_ops iwl6030_lib = { | ||
251 | .set_hw_params = iwl6000_hw_set_hw_params, | ||
252 | .set_channel_switch = iwl6000_hw_channel_switch, | ||
253 | .nic_config = iwl6000_nic_config, | ||
254 | .eeprom_ops = { | ||
255 | .regulatory_bands = { | ||
256 | EEPROM_REG_BAND_1_CHANNELS, | ||
257 | EEPROM_REG_BAND_2_CHANNELS, | ||
258 | EEPROM_REG_BAND_3_CHANNELS, | ||
259 | EEPROM_REG_BAND_4_CHANNELS, | ||
260 | EEPROM_REG_BAND_5_CHANNELS, | ||
261 | EEPROM_6000_REG_BAND_24_HT40_CHANNELS, | ||
262 | EEPROM_REG_BAND_52_HT40_CHANNELS | ||
263 | }, | ||
264 | .enhanced_txpower = true, | ||
265 | }, | ||
266 | .temperature = iwlagn_temperature, | ||
267 | }; | ||
268 | |||
269 | static const struct iwl_base_params iwl6000_base_params = { | 59 | static const struct iwl_base_params iwl6000_base_params = { |
270 | .eeprom_size = OTP_LOW_IMAGE_SIZE, | 60 | .eeprom_size = OTP_LOW_IMAGE_SIZE, |
271 | .num_of_queues = IWLAGN_NUM_QUEUES, | 61 | .num_of_queues = IWLAGN_NUM_QUEUES, |
@@ -333,11 +123,11 @@ static const struct iwl_bt_params iwl6000_bt_params = { | |||
333 | .ucode_api_max = IWL6000G2_UCODE_API_MAX, \ | 123 | .ucode_api_max = IWL6000G2_UCODE_API_MAX, \ |
334 | .ucode_api_ok = IWL6000G2_UCODE_API_OK, \ | 124 | .ucode_api_ok = IWL6000G2_UCODE_API_OK, \ |
335 | .ucode_api_min = IWL6000G2_UCODE_API_MIN, \ | 125 | .ucode_api_min = IWL6000G2_UCODE_API_MIN, \ |
126 | .device_family = IWL_DEVICE_FAMILY_6005, \ | ||
336 | .max_inst_size = IWL60_RTC_INST_SIZE, \ | 127 | .max_inst_size = IWL60_RTC_INST_SIZE, \ |
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 |
@@ -387,11 +177,11 @@ const struct iwl_cfg iwl6005_2agn_mow2_cfg = { | |||
387 | .ucode_api_max = IWL6000G2_UCODE_API_MAX, \ | 177 | .ucode_api_max = IWL6000G2_UCODE_API_MAX, \ |
388 | .ucode_api_ok = IWL6000G2_UCODE_API_OK, \ | 178 | .ucode_api_ok = IWL6000G2_UCODE_API_OK, \ |
389 | .ucode_api_min = IWL6000G2_UCODE_API_MIN, \ | 179 | .ucode_api_min = IWL6000G2_UCODE_API_MIN, \ |
180 | .device_family = IWL_DEVICE_FAMILY_6030, \ | ||
390 | .max_inst_size = IWL60_RTC_INST_SIZE, \ | 181 | .max_inst_size = IWL60_RTC_INST_SIZE, \ |
391 | .max_data_size = IWL60_RTC_DATA_SIZE, \ | 182 | .max_data_size = IWL60_RTC_DATA_SIZE, \ |
392 | .eeprom_ver = EEPROM_6030_EEPROM_VERSION, \ | 183 | .eeprom_ver = EEPROM_6030_EEPROM_VERSION, \ |
393 | .eeprom_calib_ver = EEPROM_6030_TX_POWER_VERSION, \ | 184 | .eeprom_calib_ver = EEPROM_6030_TX_POWER_VERSION, \ |
394 | .lib = &iwl6030_lib, \ | ||
395 | .base_params = &iwl6000_g2_base_params, \ | 185 | .base_params = &iwl6000_g2_base_params, \ |
396 | .bt_params = &iwl6000_bt_params, \ | 186 | .bt_params = &iwl6000_bt_params, \ |
397 | .need_temp_offset_calib = true, \ | 187 | .need_temp_offset_calib = true, \ |
@@ -458,14 +248,13 @@ const struct iwl_cfg iwl130_bg_cfg = { | |||
458 | .ucode_api_max = IWL6000_UCODE_API_MAX, \ | 248 | .ucode_api_max = IWL6000_UCODE_API_MAX, \ |
459 | .ucode_api_ok = IWL6000_UCODE_API_OK, \ | 249 | .ucode_api_ok = IWL6000_UCODE_API_OK, \ |
460 | .ucode_api_min = IWL6000_UCODE_API_MIN, \ | 250 | .ucode_api_min = IWL6000_UCODE_API_MIN, \ |
251 | .device_family = IWL_DEVICE_FAMILY_6000i, \ | ||
461 | .max_inst_size = IWL60_RTC_INST_SIZE, \ | 252 | .max_inst_size = IWL60_RTC_INST_SIZE, \ |
462 | .max_data_size = IWL60_RTC_DATA_SIZE, \ | 253 | .max_data_size = IWL60_RTC_DATA_SIZE, \ |
463 | .valid_tx_ant = ANT_BC, /* .cfg overwrite */ \ | 254 | .valid_tx_ant = ANT_BC, /* .cfg overwrite */ \ |
464 | .valid_rx_ant = ANT_BC, /* .cfg overwrite */ \ | 255 | .valid_rx_ant = ANT_BC, /* .cfg overwrite */ \ |
465 | .eeprom_ver = EEPROM_6000_EEPROM_VERSION, \ | 256 | .eeprom_ver = EEPROM_6000_EEPROM_VERSION, \ |
466 | .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION, \ | 257 | .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION, \ |
467 | .lib = &iwl6000_lib, \ | ||
468 | .additional_nic_config = iwl6000i_additional_nic_config,\ | ||
469 | .base_params = &iwl6000_base_params, \ | 258 | .base_params = &iwl6000_base_params, \ |
470 | .led_mode = IWL_LED_BLINK | 259 | .led_mode = IWL_LED_BLINK |
471 | 260 | ||
@@ -489,12 +278,11 @@ const struct iwl_cfg iwl6000i_2bg_cfg = { | |||
489 | .fw_name_pre = IWL6050_FW_PRE, \ | 278 | .fw_name_pre = IWL6050_FW_PRE, \ |
490 | .ucode_api_max = IWL6050_UCODE_API_MAX, \ | 279 | .ucode_api_max = IWL6050_UCODE_API_MAX, \ |
491 | .ucode_api_min = IWL6050_UCODE_API_MIN, \ | 280 | .ucode_api_min = IWL6050_UCODE_API_MIN, \ |
281 | .device_family = IWL_DEVICE_FAMILY_6050, \ | ||
492 | .max_inst_size = IWL60_RTC_INST_SIZE, \ | 282 | .max_inst_size = IWL60_RTC_INST_SIZE, \ |
493 | .max_data_size = IWL60_RTC_DATA_SIZE, \ | 283 | .max_data_size = IWL60_RTC_DATA_SIZE, \ |
494 | .valid_tx_ant = ANT_AB, /* .cfg overwrite */ \ | 284 | .valid_tx_ant = ANT_AB, /* .cfg overwrite */ \ |
495 | .valid_rx_ant = ANT_AB, /* .cfg overwrite */ \ | 285 | .valid_rx_ant = ANT_AB, /* .cfg overwrite */ \ |
496 | .lib = &iwl6000_lib, \ | ||
497 | .additional_nic_config = iwl6050_additional_nic_config, \ | ||
498 | .eeprom_ver = EEPROM_6050_EEPROM_VERSION, \ | 286 | .eeprom_ver = EEPROM_6050_EEPROM_VERSION, \ |
499 | .eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION, \ | 287 | .eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION, \ |
500 | .base_params = &iwl6050_base_params, \ | 288 | .base_params = &iwl6050_base_params, \ |
@@ -516,10 +304,9 @@ const struct iwl_cfg iwl6050_2abg_cfg = { | |||
516 | .fw_name_pre = IWL6050_FW_PRE, \ | 304 | .fw_name_pre = IWL6050_FW_PRE, \ |
517 | .ucode_api_max = IWL6050_UCODE_API_MAX, \ | 305 | .ucode_api_max = IWL6050_UCODE_API_MAX, \ |
518 | .ucode_api_min = IWL6050_UCODE_API_MIN, \ | 306 | .ucode_api_min = IWL6050_UCODE_API_MIN, \ |
307 | .device_family = IWL_DEVICE_FAMILY_6150, \ | ||
519 | .max_inst_size = IWL60_RTC_INST_SIZE, \ | 308 | .max_inst_size = IWL60_RTC_INST_SIZE, \ |
520 | .max_data_size = IWL60_RTC_DATA_SIZE, \ | 309 | .max_data_size = IWL60_RTC_DATA_SIZE, \ |
521 | .lib = &iwl6000_lib, \ | ||
522 | .additional_nic_config = iwl6150_additional_nic_config, \ | ||
523 | .eeprom_ver = EEPROM_6150_EEPROM_VERSION, \ | 310 | .eeprom_ver = EEPROM_6150_EEPROM_VERSION, \ |
524 | .eeprom_calib_ver = EEPROM_6150_TX_POWER_VERSION, \ | 311 | .eeprom_calib_ver = EEPROM_6150_TX_POWER_VERSION, \ |
525 | .base_params = &iwl6050_base_params, \ | 312 | .base_params = &iwl6050_base_params, \ |
@@ -543,11 +330,11 @@ const struct iwl_cfg iwl6000_3agn_cfg = { | |||
543 | .ucode_api_max = IWL6000_UCODE_API_MAX, | 330 | .ucode_api_max = IWL6000_UCODE_API_MAX, |
544 | .ucode_api_ok = IWL6000_UCODE_API_OK, | 331 | .ucode_api_ok = IWL6000_UCODE_API_OK, |
545 | .ucode_api_min = IWL6000_UCODE_API_MIN, | 332 | .ucode_api_min = IWL6000_UCODE_API_MIN, |
333 | .device_family = IWL_DEVICE_FAMILY_6000, | ||
546 | .max_inst_size = IWL60_RTC_INST_SIZE, | 334 | .max_inst_size = IWL60_RTC_INST_SIZE, |
547 | .max_data_size = IWL60_RTC_DATA_SIZE, | 335 | .max_data_size = IWL60_RTC_DATA_SIZE, |
548 | .eeprom_ver = EEPROM_6000_EEPROM_VERSION, | 336 | .eeprom_ver = EEPROM_6000_EEPROM_VERSION, |
549 | .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION, | 337 | .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION, |
550 | .lib = &iwl6000_lib, | ||
551 | .base_params = &iwl6000_base_params, | 338 | .base_params = &iwl6000_base_params, |
552 | .ht_params = &iwl6000_ht_params, | 339 | .ht_params = &iwl6000_ht_params, |
553 | .led_mode = IWL_LED_BLINK, | 340 | .led_mode = IWL_LED_BLINK, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c index 84cbe7bb504c..61c243f7395f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c | |||
@@ -190,7 +190,7 @@ static int iwl_sens_energy_cck(struct iwl_priv *priv, | |||
190 | u32 max_false_alarms = MAX_FA_CCK * rx_enable_time; | 190 | u32 max_false_alarms = MAX_FA_CCK * rx_enable_time; |
191 | u32 min_false_alarms = MIN_FA_CCK * rx_enable_time; | 191 | u32 min_false_alarms = MIN_FA_CCK * rx_enable_time; |
192 | struct iwl_sensitivity_data *data = NULL; | 192 | struct iwl_sensitivity_data *data = NULL; |
193 | const struct iwl_sensitivity_ranges *ranges = hw_params(priv).sens; | 193 | const struct iwl_sensitivity_ranges *ranges = priv->hw_params.sens; |
194 | 194 | ||
195 | data = &(priv->sensitivity_data); | 195 | data = &(priv->sensitivity_data); |
196 | 196 | ||
@@ -373,7 +373,7 @@ static int iwl_sens_auto_corr_ofdm(struct iwl_priv *priv, | |||
373 | u32 max_false_alarms = MAX_FA_OFDM * rx_enable_time; | 373 | u32 max_false_alarms = MAX_FA_OFDM * rx_enable_time; |
374 | u32 min_false_alarms = MIN_FA_OFDM * rx_enable_time; | 374 | u32 min_false_alarms = MIN_FA_OFDM * rx_enable_time; |
375 | struct iwl_sensitivity_data *data = NULL; | 375 | struct iwl_sensitivity_data *data = NULL; |
376 | const struct iwl_sensitivity_ranges *ranges = hw_params(priv).sens; | 376 | const struct iwl_sensitivity_ranges *ranges = priv->hw_params.sens; |
377 | 377 | ||
378 | data = &(priv->sensitivity_data); | 378 | data = &(priv->sensitivity_data); |
379 | 379 | ||
@@ -597,9 +597,9 @@ void iwl_init_sensitivity(struct iwl_priv *priv) | |||
597 | int ret = 0; | 597 | int ret = 0; |
598 | int i; | 598 | int i; |
599 | struct iwl_sensitivity_data *data = NULL; | 599 | struct iwl_sensitivity_data *data = NULL; |
600 | const struct iwl_sensitivity_ranges *ranges = hw_params(priv).sens; | 600 | const struct iwl_sensitivity_ranges *ranges = priv->hw_params.sens; |
601 | 601 | ||
602 | if (priv->disable_sens_cal) | 602 | if (priv->calib_disabled & IWL_SENSITIVITY_CALIB_DISABLED) |
603 | return; | 603 | return; |
604 | 604 | ||
605 | IWL_DEBUG_CALIB(priv, "Start iwl_init_sensitivity\n"); | 605 | IWL_DEBUG_CALIB(priv, "Start iwl_init_sensitivity\n"); |
@@ -663,7 +663,7 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv) | |||
663 | struct statistics_rx_phy *ofdm, *cck; | 663 | struct statistics_rx_phy *ofdm, *cck; |
664 | struct statistics_general_data statis; | 664 | struct statistics_general_data statis; |
665 | 665 | ||
666 | if (priv->disable_sens_cal) | 666 | if (priv->calib_disabled & IWL_SENSITIVITY_CALIB_DISABLED) |
667 | return; | 667 | return; |
668 | 668 | ||
669 | data = &(priv->sensitivity_data); | 669 | data = &(priv->sensitivity_data); |
@@ -833,28 +833,28 @@ static void iwl_find_disconn_antenna(struct iwl_priv *priv, u32* average_sig, | |||
833 | * To be safe, simply mask out any chains that we know | 833 | * To be safe, simply mask out any chains that we know |
834 | * are not on the device. | 834 | * are not on the device. |
835 | */ | 835 | */ |
836 | active_chains &= hw_params(priv).valid_rx_ant; | 836 | active_chains &= priv->hw_params.valid_rx_ant; |
837 | 837 | ||
838 | num_tx_chains = 0; | 838 | num_tx_chains = 0; |
839 | for (i = 0; i < NUM_RX_CHAINS; i++) { | 839 | for (i = 0; i < NUM_RX_CHAINS; i++) { |
840 | /* loops on all the bits of | 840 | /* loops on all the bits of |
841 | * priv->hw_setting.valid_tx_ant */ | 841 | * priv->hw_setting.valid_tx_ant */ |
842 | u8 ant_msk = (1 << i); | 842 | u8 ant_msk = (1 << i); |
843 | if (!(hw_params(priv).valid_tx_ant & ant_msk)) | 843 | if (!(priv->hw_params.valid_tx_ant & ant_msk)) |
844 | continue; | 844 | continue; |
845 | 845 | ||
846 | num_tx_chains++; | 846 | num_tx_chains++; |
847 | if (data->disconn_array[i] == 0) | 847 | if (data->disconn_array[i] == 0) |
848 | /* there is a Tx antenna connected */ | 848 | /* there is a Tx antenna connected */ |
849 | break; | 849 | break; |
850 | if (num_tx_chains == hw_params(priv).tx_chains_num && | 850 | if (num_tx_chains == priv->hw_params.tx_chains_num && |
851 | data->disconn_array[i]) { | 851 | data->disconn_array[i]) { |
852 | /* | 852 | /* |
853 | * If all chains are disconnected | 853 | * If all chains are disconnected |
854 | * connect the first valid tx chain | 854 | * connect the first valid tx chain |
855 | */ | 855 | */ |
856 | first_chain = | 856 | first_chain = |
857 | find_first_chain(hw_params(priv).valid_tx_ant); | 857 | find_first_chain(priv->hw_params.valid_tx_ant); |
858 | data->disconn_array[first_chain] = 0; | 858 | data->disconn_array[first_chain] = 0; |
859 | active_chains |= BIT(first_chain); | 859 | active_chains |= BIT(first_chain); |
860 | IWL_DEBUG_CALIB(priv, | 860 | IWL_DEBUG_CALIB(priv, |
@@ -864,13 +864,13 @@ static void iwl_find_disconn_antenna(struct iwl_priv *priv, u32* average_sig, | |||
864 | } | 864 | } |
865 | } | 865 | } |
866 | 866 | ||
867 | if (active_chains != hw_params(priv).valid_rx_ant && | 867 | if (active_chains != priv->hw_params.valid_rx_ant && |
868 | active_chains != priv->chain_noise_data.active_chains) | 868 | active_chains != priv->chain_noise_data.active_chains) |
869 | IWL_DEBUG_CALIB(priv, | 869 | IWL_DEBUG_CALIB(priv, |
870 | "Detected that not all antennas are connected! " | 870 | "Detected that not all antennas are connected! " |
871 | "Connected: %#x, valid: %#x.\n", | 871 | "Connected: %#x, valid: %#x.\n", |
872 | active_chains, | 872 | active_chains, |
873 | hw_params(priv).valid_rx_ant); | 873 | priv->hw_params.valid_rx_ant); |
874 | 874 | ||
875 | /* Save for use within RXON, TX, SCAN commands, etc. */ | 875 | /* Save for use within RXON, TX, SCAN commands, etc. */ |
876 | data->active_chains = active_chains; | 876 | data->active_chains = active_chains; |
@@ -970,7 +970,7 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv) | |||
970 | */ | 970 | */ |
971 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | 971 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; |
972 | 972 | ||
973 | if (priv->disable_chain_noise_cal) | 973 | if (priv->calib_disabled & IWL_CHAIN_NOISE_CALIB_DISABLED) |
974 | return; | 974 | return; |
975 | 975 | ||
976 | data = &(priv->chain_noise_data); | 976 | data = &(priv->chain_noise_data); |
@@ -1055,7 +1055,7 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv) | |||
1055 | cfg(priv)->bt_params->advanced_bt_coexist) { | 1055 | cfg(priv)->bt_params->advanced_bt_coexist) { |
1056 | /* Disable disconnected antenna algorithm for advanced | 1056 | /* Disable disconnected antenna algorithm for advanced |
1057 | bt coex, assuming valid antennas are connected */ | 1057 | bt coex, assuming valid antennas are connected */ |
1058 | data->active_chains = hw_params(priv).valid_rx_ant; | 1058 | data->active_chains = priv->hw_params.valid_rx_ant; |
1059 | for (i = 0; i < NUM_RX_CHAINS; i++) | 1059 | for (i = 0; i < NUM_RX_CHAINS; i++) |
1060 | if (!(data->active_chains & (1<<i))) | 1060 | if (!(data->active_chains & (1<<i))) |
1061 | data->disconn_array[i] = 1; | 1061 | data->disconn_array[i] = 1; |
@@ -1085,7 +1085,7 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv) | |||
1085 | min_average_noise, min_average_noise_antenna_i); | 1085 | min_average_noise, min_average_noise_antenna_i); |
1086 | 1086 | ||
1087 | iwlagn_gain_computation(priv, average_noise, | 1087 | iwlagn_gain_computation(priv, average_noise, |
1088 | find_first_chain(hw_params(priv).valid_rx_ant)); | 1088 | find_first_chain(priv->hw_params.valid_rx_ant)); |
1089 | 1089 | ||
1090 | /* Some power changes may have been made during the calibration. | 1090 | /* Some power changes may have been made during the calibration. |
1091 | * Update and commit the RXON | 1091 | * Update and commit the RXON |
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..08718caf4aa9 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-agn-devices.c | |||
@@ -0,0 +1,756 @@ | |||
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 | */ | ||
52 | static 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 */ | ||
60 | static 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 | |||
74 | /** | ||
75 | * iwl_beacon_time_mask_low - mask of lower 32 bit of beacon time | ||
76 | * @priv -- pointer to iwl_priv data structure | ||
77 | * @tsf_bits -- number of bits need to shift for masking) | ||
78 | */ | ||
79 | static inline u32 iwl_beacon_time_mask_low(struct iwl_priv *priv, | ||
80 | u16 tsf_bits) | ||
81 | { | ||
82 | return (1 << tsf_bits) - 1; | ||
83 | } | ||
84 | |||
85 | /** | ||
86 | * iwl_beacon_time_mask_high - mask of higher 32 bit of beacon time | ||
87 | * @priv -- pointer to iwl_priv data structure | ||
88 | * @tsf_bits -- number of bits need to shift for masking) | ||
89 | */ | ||
90 | static inline u32 iwl_beacon_time_mask_high(struct iwl_priv *priv, | ||
91 | u16 tsf_bits) | ||
92 | { | ||
93 | return ((1 << (32 - tsf_bits)) - 1) << tsf_bits; | ||
94 | } | ||
95 | |||
96 | /* | ||
97 | * extended beacon time format | ||
98 | * time in usec will be changed into a 32-bit value in extended:internal format | ||
99 | * the extended part is the beacon counts | ||
100 | * the internal part is the time in usec within one beacon interval | ||
101 | */ | ||
102 | static u32 iwl_usecs_to_beacons(struct iwl_priv *priv, u32 usec, | ||
103 | u32 beacon_interval) | ||
104 | { | ||
105 | u32 quot; | ||
106 | u32 rem; | ||
107 | u32 interval = beacon_interval * TIME_UNIT; | ||
108 | |||
109 | if (!interval || !usec) | ||
110 | return 0; | ||
111 | |||
112 | quot = (usec / interval) & | ||
113 | (iwl_beacon_time_mask_high(priv, IWLAGN_EXT_BEACON_TIME_POS) >> | ||
114 | IWLAGN_EXT_BEACON_TIME_POS); | ||
115 | rem = (usec % interval) & iwl_beacon_time_mask_low(priv, | ||
116 | IWLAGN_EXT_BEACON_TIME_POS); | ||
117 | |||
118 | return (quot << IWLAGN_EXT_BEACON_TIME_POS) + rem; | ||
119 | } | ||
120 | |||
121 | /* base is usually what we get from ucode with each received frame, | ||
122 | * the same as HW timer counter counting down | ||
123 | */ | ||
124 | static __le32 iwl_add_beacon_time(struct iwl_priv *priv, u32 base, | ||
125 | u32 addon, u32 beacon_interval) | ||
126 | { | ||
127 | u32 base_low = base & iwl_beacon_time_mask_low(priv, | ||
128 | IWLAGN_EXT_BEACON_TIME_POS); | ||
129 | u32 addon_low = addon & iwl_beacon_time_mask_low(priv, | ||
130 | IWLAGN_EXT_BEACON_TIME_POS); | ||
131 | u32 interval = beacon_interval * TIME_UNIT; | ||
132 | u32 res = (base & iwl_beacon_time_mask_high(priv, | ||
133 | IWLAGN_EXT_BEACON_TIME_POS)) + | ||
134 | (addon & iwl_beacon_time_mask_high(priv, | ||
135 | IWLAGN_EXT_BEACON_TIME_POS)); | ||
136 | |||
137 | if (base_low > addon_low) | ||
138 | res += base_low - addon_low; | ||
139 | else if (base_low < addon_low) { | ||
140 | res += interval + base_low - addon_low; | ||
141 | res += (1 << IWLAGN_EXT_BEACON_TIME_POS); | ||
142 | } else | ||
143 | res += (1 << IWLAGN_EXT_BEACON_TIME_POS); | ||
144 | |||
145 | return cpu_to_le32(res); | ||
146 | } | ||
147 | |||
148 | static const struct iwl_sensitivity_ranges iwl1000_sensitivity = { | ||
149 | .min_nrg_cck = 95, | ||
150 | .auto_corr_min_ofdm = 90, | ||
151 | .auto_corr_min_ofdm_mrc = 170, | ||
152 | .auto_corr_min_ofdm_x1 = 120, | ||
153 | .auto_corr_min_ofdm_mrc_x1 = 240, | ||
154 | |||
155 | .auto_corr_max_ofdm = 120, | ||
156 | .auto_corr_max_ofdm_mrc = 210, | ||
157 | .auto_corr_max_ofdm_x1 = 155, | ||
158 | .auto_corr_max_ofdm_mrc_x1 = 290, | ||
159 | |||
160 | .auto_corr_min_cck = 125, | ||
161 | .auto_corr_max_cck = 200, | ||
162 | .auto_corr_min_cck_mrc = 170, | ||
163 | .auto_corr_max_cck_mrc = 400, | ||
164 | .nrg_th_cck = 95, | ||
165 | .nrg_th_ofdm = 95, | ||
166 | |||
167 | .barker_corr_th_min = 190, | ||
168 | .barker_corr_th_min_mrc = 390, | ||
169 | .nrg_th_cca = 62, | ||
170 | }; | ||
171 | |||
172 | static void iwl1000_hw_set_hw_params(struct iwl_priv *priv) | ||
173 | { | ||
174 | priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ); | ||
175 | |||
176 | priv->hw_params.tx_chains_num = | ||
177 | num_of_ant(priv->hw_params.valid_tx_ant); | ||
178 | if (cfg(priv)->rx_with_siso_diversity) | ||
179 | priv->hw_params.rx_chains_num = 1; | ||
180 | else | ||
181 | priv->hw_params.rx_chains_num = | ||
182 | num_of_ant(priv->hw_params.valid_rx_ant); | ||
183 | |||
184 | iwl1000_set_ct_threshold(priv); | ||
185 | |||
186 | /* Set initial sensitivity parameters */ | ||
187 | priv->hw_params.sens = &iwl1000_sensitivity; | ||
188 | } | ||
189 | |||
190 | struct iwl_lib_ops iwl1000_lib = { | ||
191 | .set_hw_params = iwl1000_hw_set_hw_params, | ||
192 | .nic_config = iwl1000_nic_config, | ||
193 | .eeprom_ops = { | ||
194 | .regulatory_bands = { | ||
195 | EEPROM_REG_BAND_1_CHANNELS, | ||
196 | EEPROM_REG_BAND_2_CHANNELS, | ||
197 | EEPROM_REG_BAND_3_CHANNELS, | ||
198 | EEPROM_REG_BAND_4_CHANNELS, | ||
199 | EEPROM_REG_BAND_5_CHANNELS, | ||
200 | EEPROM_REG_BAND_24_HT40_CHANNELS, | ||
201 | EEPROM_REGULATORY_BAND_NO_HT40, | ||
202 | }, | ||
203 | }, | ||
204 | .temperature = iwlagn_temperature, | ||
205 | }; | ||
206 | |||
207 | |||
208 | /* | ||
209 | * 2000 series | ||
210 | * =========== | ||
211 | */ | ||
212 | |||
213 | static void iwl2000_set_ct_threshold(struct iwl_priv *priv) | ||
214 | { | ||
215 | /* want Celsius */ | ||
216 | priv->hw_params.ct_kill_threshold = CT_KILL_THRESHOLD; | ||
217 | priv->hw_params.ct_kill_exit_threshold = CT_KILL_EXIT_THRESHOLD; | ||
218 | } | ||
219 | |||
220 | /* NIC configuration for 2000 series */ | ||
221 | static void iwl2000_nic_config(struct iwl_priv *priv) | ||
222 | { | ||
223 | iwl_rf_config(priv); | ||
224 | |||
225 | iwl_set_bit(trans(priv), CSR_GP_DRIVER_REG, | ||
226 | CSR_GP_DRIVER_REG_BIT_RADIO_IQ_INVER); | ||
227 | } | ||
228 | |||
229 | static const struct iwl_sensitivity_ranges iwl2000_sensitivity = { | ||
230 | .min_nrg_cck = 97, | ||
231 | .auto_corr_min_ofdm = 80, | ||
232 | .auto_corr_min_ofdm_mrc = 128, | ||
233 | .auto_corr_min_ofdm_x1 = 105, | ||
234 | .auto_corr_min_ofdm_mrc_x1 = 192, | ||
235 | |||
236 | .auto_corr_max_ofdm = 145, | ||
237 | .auto_corr_max_ofdm_mrc = 232, | ||
238 | .auto_corr_max_ofdm_x1 = 110, | ||
239 | .auto_corr_max_ofdm_mrc_x1 = 232, | ||
240 | |||
241 | .auto_corr_min_cck = 125, | ||
242 | .auto_corr_max_cck = 175, | ||
243 | .auto_corr_min_cck_mrc = 160, | ||
244 | .auto_corr_max_cck_mrc = 310, | ||
245 | .nrg_th_cck = 97, | ||
246 | .nrg_th_ofdm = 100, | ||
247 | |||
248 | .barker_corr_th_min = 190, | ||
249 | .barker_corr_th_min_mrc = 390, | ||
250 | .nrg_th_cca = 62, | ||
251 | }; | ||
252 | |||
253 | static void iwl2000_hw_set_hw_params(struct iwl_priv *priv) | ||
254 | { | ||
255 | priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ); | ||
256 | |||
257 | priv->hw_params.tx_chains_num = | ||
258 | num_of_ant(priv->hw_params.valid_tx_ant); | ||
259 | if (cfg(priv)->rx_with_siso_diversity) | ||
260 | priv->hw_params.rx_chains_num = 1; | ||
261 | else | ||
262 | priv->hw_params.rx_chains_num = | ||
263 | num_of_ant(priv->hw_params.valid_rx_ant); | ||
264 | |||
265 | iwl2000_set_ct_threshold(priv); | ||
266 | |||
267 | /* Set initial sensitivity parameters */ | ||
268 | priv->hw_params.sens = &iwl2000_sensitivity; | ||
269 | } | ||
270 | |||
271 | struct iwl_lib_ops iwl2000_lib = { | ||
272 | .set_hw_params = iwl2000_hw_set_hw_params, | ||
273 | .nic_config = iwl2000_nic_config, | ||
274 | .eeprom_ops = { | ||
275 | .regulatory_bands = { | ||
276 | EEPROM_REG_BAND_1_CHANNELS, | ||
277 | EEPROM_REG_BAND_2_CHANNELS, | ||
278 | EEPROM_REG_BAND_3_CHANNELS, | ||
279 | EEPROM_REG_BAND_4_CHANNELS, | ||
280 | EEPROM_REG_BAND_5_CHANNELS, | ||
281 | EEPROM_6000_REG_BAND_24_HT40_CHANNELS, | ||
282 | EEPROM_REGULATORY_BAND_NO_HT40, | ||
283 | }, | ||
284 | .enhanced_txpower = true, | ||
285 | }, | ||
286 | .temperature = iwlagn_temperature, | ||
287 | }; | ||
288 | |||
289 | struct iwl_lib_ops iwl2030_lib = { | ||
290 | .set_hw_params = iwl2000_hw_set_hw_params, | ||
291 | .nic_config = iwl2000_nic_config, | ||
292 | .eeprom_ops = { | ||
293 | .regulatory_bands = { | ||
294 | EEPROM_REG_BAND_1_CHANNELS, | ||
295 | EEPROM_REG_BAND_2_CHANNELS, | ||
296 | EEPROM_REG_BAND_3_CHANNELS, | ||
297 | EEPROM_REG_BAND_4_CHANNELS, | ||
298 | EEPROM_REG_BAND_5_CHANNELS, | ||
299 | EEPROM_6000_REG_BAND_24_HT40_CHANNELS, | ||
300 | EEPROM_REGULATORY_BAND_NO_HT40, | ||
301 | }, | ||
302 | .enhanced_txpower = true, | ||
303 | }, | ||
304 | .temperature = iwlagn_temperature, | ||
305 | }; | ||
306 | |||
307 | /* | ||
308 | * 5000 series | ||
309 | * =========== | ||
310 | */ | ||
311 | |||
312 | /* NIC configuration for 5000 series */ | ||
313 | static void iwl5000_nic_config(struct iwl_priv *priv) | ||
314 | { | ||
315 | iwl_rf_config(priv); | ||
316 | |||
317 | /* W/A : NIC is stuck in a reset state after Early PCIe power off | ||
318 | * (PCIe power is lost before PERST# is asserted), | ||
319 | * causing ME FW to lose ownership and not being able to obtain it back. | ||
320 | */ | ||
321 | iwl_set_bits_mask_prph(trans(priv), APMG_PS_CTRL_REG, | ||
322 | APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS, | ||
323 | ~APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS); | ||
324 | } | ||
325 | |||
326 | static const struct iwl_sensitivity_ranges iwl5000_sensitivity = { | ||
327 | .min_nrg_cck = 100, | ||
328 | .auto_corr_min_ofdm = 90, | ||
329 | .auto_corr_min_ofdm_mrc = 170, | ||
330 | .auto_corr_min_ofdm_x1 = 105, | ||
331 | .auto_corr_min_ofdm_mrc_x1 = 220, | ||
332 | |||
333 | .auto_corr_max_ofdm = 120, | ||
334 | .auto_corr_max_ofdm_mrc = 210, | ||
335 | .auto_corr_max_ofdm_x1 = 120, | ||
336 | .auto_corr_max_ofdm_mrc_x1 = 240, | ||
337 | |||
338 | .auto_corr_min_cck = 125, | ||
339 | .auto_corr_max_cck = 200, | ||
340 | .auto_corr_min_cck_mrc = 200, | ||
341 | .auto_corr_max_cck_mrc = 400, | ||
342 | .nrg_th_cck = 100, | ||
343 | .nrg_th_ofdm = 100, | ||
344 | |||
345 | .barker_corr_th_min = 190, | ||
346 | .barker_corr_th_min_mrc = 390, | ||
347 | .nrg_th_cca = 62, | ||
348 | }; | ||
349 | |||
350 | static struct iwl_sensitivity_ranges iwl5150_sensitivity = { | ||
351 | .min_nrg_cck = 95, | ||
352 | .auto_corr_min_ofdm = 90, | ||
353 | .auto_corr_min_ofdm_mrc = 170, | ||
354 | .auto_corr_min_ofdm_x1 = 105, | ||
355 | .auto_corr_min_ofdm_mrc_x1 = 220, | ||
356 | |||
357 | .auto_corr_max_ofdm = 120, | ||
358 | .auto_corr_max_ofdm_mrc = 210, | ||
359 | /* max = min for performance bug in 5150 DSP */ | ||
360 | .auto_corr_max_ofdm_x1 = 105, | ||
361 | .auto_corr_max_ofdm_mrc_x1 = 220, | ||
362 | |||
363 | .auto_corr_min_cck = 125, | ||
364 | .auto_corr_max_cck = 200, | ||
365 | .auto_corr_min_cck_mrc = 170, | ||
366 | .auto_corr_max_cck_mrc = 400, | ||
367 | .nrg_th_cck = 95, | ||
368 | .nrg_th_ofdm = 95, | ||
369 | |||
370 | .barker_corr_th_min = 190, | ||
371 | .barker_corr_th_min_mrc = 390, | ||
372 | .nrg_th_cca = 62, | ||
373 | }; | ||
374 | |||
375 | #define IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF (-5) | ||
376 | |||
377 | static s32 iwl_temp_calib_to_offset(struct iwl_priv *priv) | ||
378 | { | ||
379 | u16 temperature, voltage; | ||
380 | __le16 *temp_calib = (__le16 *)iwl_eeprom_query_addr(priv, | ||
381 | EEPROM_KELVIN_TEMPERATURE); | ||
382 | |||
383 | temperature = le16_to_cpu(temp_calib[0]); | ||
384 | voltage = le16_to_cpu(temp_calib[1]); | ||
385 | |||
386 | /* offset = temp - volt / coeff */ | ||
387 | return (s32)(temperature - | ||
388 | voltage / IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF); | ||
389 | } | ||
390 | |||
391 | static void iwl5150_set_ct_threshold(struct iwl_priv *priv) | ||
392 | { | ||
393 | const s32 volt2temp_coef = IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF; | ||
394 | s32 threshold = (s32)CELSIUS_TO_KELVIN(CT_KILL_THRESHOLD_LEGACY) - | ||
395 | iwl_temp_calib_to_offset(priv); | ||
396 | |||
397 | priv->hw_params.ct_kill_threshold = threshold * volt2temp_coef; | ||
398 | } | ||
399 | |||
400 | static void iwl5000_set_ct_threshold(struct iwl_priv *priv) | ||
401 | { | ||
402 | /* want Celsius */ | ||
403 | priv->hw_params.ct_kill_threshold = CT_KILL_THRESHOLD_LEGACY; | ||
404 | } | ||
405 | |||
406 | static void iwl5000_hw_set_hw_params(struct iwl_priv *priv) | ||
407 | { | ||
408 | priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) | | ||
409 | BIT(IEEE80211_BAND_5GHZ); | ||
410 | |||
411 | priv->hw_params.tx_chains_num = | ||
412 | num_of_ant(priv->hw_params.valid_tx_ant); | ||
413 | priv->hw_params.rx_chains_num = | ||
414 | num_of_ant(priv->hw_params.valid_rx_ant); | ||
415 | |||
416 | iwl5000_set_ct_threshold(priv); | ||
417 | |||
418 | /* Set initial sensitivity parameters */ | ||
419 | priv->hw_params.sens = &iwl5000_sensitivity; | ||
420 | } | ||
421 | |||
422 | static void iwl5150_hw_set_hw_params(struct iwl_priv *priv) | ||
423 | { | ||
424 | priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) | | ||
425 | BIT(IEEE80211_BAND_5GHZ); | ||
426 | |||
427 | priv->hw_params.tx_chains_num = | ||
428 | num_of_ant(priv->hw_params.valid_tx_ant); | ||
429 | priv->hw_params.rx_chains_num = | ||
430 | num_of_ant(priv->hw_params.valid_rx_ant); | ||
431 | |||
432 | iwl5150_set_ct_threshold(priv); | ||
433 | |||
434 | /* Set initial sensitivity parameters */ | ||
435 | priv->hw_params.sens = &iwl5150_sensitivity; | ||
436 | } | ||
437 | |||
438 | static void iwl5150_temperature(struct iwl_priv *priv) | ||
439 | { | ||
440 | u32 vt = 0; | ||
441 | s32 offset = iwl_temp_calib_to_offset(priv); | ||
442 | |||
443 | vt = le32_to_cpu(priv->statistics.common.temperature); | ||
444 | vt = vt / IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF + offset; | ||
445 | /* now vt hold the temperature in Kelvin */ | ||
446 | priv->temperature = KELVIN_TO_CELSIUS(vt); | ||
447 | iwl_tt_handler(priv); | ||
448 | } | ||
449 | |||
450 | static int iwl5000_hw_channel_switch(struct iwl_priv *priv, | ||
451 | struct ieee80211_channel_switch *ch_switch) | ||
452 | { | ||
453 | /* | ||
454 | * MULTI-FIXME | ||
455 | * See iwlagn_mac_channel_switch. | ||
456 | */ | ||
457 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | ||
458 | struct iwl5000_channel_switch_cmd cmd; | ||
459 | const struct iwl_channel_info *ch_info; | ||
460 | u32 switch_time_in_usec, ucode_switch_time; | ||
461 | u16 ch; | ||
462 | u32 tsf_low; | ||
463 | u8 switch_count; | ||
464 | u16 beacon_interval = le16_to_cpu(ctx->timing.beacon_interval); | ||
465 | struct ieee80211_vif *vif = ctx->vif; | ||
466 | struct iwl_host_cmd hcmd = { | ||
467 | .id = REPLY_CHANNEL_SWITCH, | ||
468 | .len = { sizeof(cmd), }, | ||
469 | .flags = CMD_SYNC, | ||
470 | .data = { &cmd, }, | ||
471 | }; | ||
472 | |||
473 | cmd.band = priv->band == IEEE80211_BAND_2GHZ; | ||
474 | ch = ch_switch->channel->hw_value; | ||
475 | IWL_DEBUG_11H(priv, "channel switch from %d to %d\n", | ||
476 | ctx->active.channel, ch); | ||
477 | cmd.channel = cpu_to_le16(ch); | ||
478 | cmd.rxon_flags = ctx->staging.flags; | ||
479 | cmd.rxon_filter_flags = ctx->staging.filter_flags; | ||
480 | switch_count = ch_switch->count; | ||
481 | tsf_low = ch_switch->timestamp & 0x0ffffffff; | ||
482 | /* | ||
483 | * calculate the ucode channel switch time | ||
484 | * adding TSF as one of the factor for when to switch | ||
485 | */ | ||
486 | if ((priv->ucode_beacon_time > tsf_low) && beacon_interval) { | ||
487 | if (switch_count > ((priv->ucode_beacon_time - tsf_low) / | ||
488 | beacon_interval)) { | ||
489 | switch_count -= (priv->ucode_beacon_time - | ||
490 | tsf_low) / beacon_interval; | ||
491 | } else | ||
492 | switch_count = 0; | ||
493 | } | ||
494 | if (switch_count <= 1) | ||
495 | cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time); | ||
496 | else { | ||
497 | switch_time_in_usec = | ||
498 | vif->bss_conf.beacon_int * switch_count * TIME_UNIT; | ||
499 | ucode_switch_time = iwl_usecs_to_beacons(priv, | ||
500 | switch_time_in_usec, | ||
501 | beacon_interval); | ||
502 | cmd.switch_time = iwl_add_beacon_time(priv, | ||
503 | priv->ucode_beacon_time, | ||
504 | ucode_switch_time, | ||
505 | beacon_interval); | ||
506 | } | ||
507 | IWL_DEBUG_11H(priv, "uCode time for the switch is 0x%x\n", | ||
508 | cmd.switch_time); | ||
509 | ch_info = iwl_get_channel_info(priv, priv->band, ch); | ||
510 | if (ch_info) | ||
511 | cmd.expect_beacon = is_channel_radar(ch_info); | ||
512 | else { | ||
513 | IWL_ERR(priv, "invalid channel switch from %u to %u\n", | ||
514 | ctx->active.channel, ch); | ||
515 | return -EFAULT; | ||
516 | } | ||
517 | |||
518 | return iwl_dvm_send_cmd(priv, &hcmd); | ||
519 | } | ||
520 | |||
521 | struct iwl_lib_ops iwl5000_lib = { | ||
522 | .set_hw_params = iwl5000_hw_set_hw_params, | ||
523 | .set_channel_switch = iwl5000_hw_channel_switch, | ||
524 | .nic_config = iwl5000_nic_config, | ||
525 | .eeprom_ops = { | ||
526 | .regulatory_bands = { | ||
527 | EEPROM_REG_BAND_1_CHANNELS, | ||
528 | EEPROM_REG_BAND_2_CHANNELS, | ||
529 | EEPROM_REG_BAND_3_CHANNELS, | ||
530 | EEPROM_REG_BAND_4_CHANNELS, | ||
531 | EEPROM_REG_BAND_5_CHANNELS, | ||
532 | EEPROM_REG_BAND_24_HT40_CHANNELS, | ||
533 | EEPROM_REG_BAND_52_HT40_CHANNELS | ||
534 | }, | ||
535 | }, | ||
536 | .temperature = iwlagn_temperature, | ||
537 | }; | ||
538 | |||
539 | struct iwl_lib_ops iwl5150_lib = { | ||
540 | .set_hw_params = iwl5150_hw_set_hw_params, | ||
541 | .set_channel_switch = iwl5000_hw_channel_switch, | ||
542 | .nic_config = iwl5000_nic_config, | ||
543 | .eeprom_ops = { | ||
544 | .regulatory_bands = { | ||
545 | EEPROM_REG_BAND_1_CHANNELS, | ||
546 | EEPROM_REG_BAND_2_CHANNELS, | ||
547 | EEPROM_REG_BAND_3_CHANNELS, | ||
548 | EEPROM_REG_BAND_4_CHANNELS, | ||
549 | EEPROM_REG_BAND_5_CHANNELS, | ||
550 | EEPROM_REG_BAND_24_HT40_CHANNELS, | ||
551 | EEPROM_REG_BAND_52_HT40_CHANNELS | ||
552 | }, | ||
553 | }, | ||
554 | .temperature = iwl5150_temperature, | ||
555 | }; | ||
556 | |||
557 | |||
558 | |||
559 | /* | ||
560 | * 6000 series | ||
561 | * =========== | ||
562 | */ | ||
563 | |||
564 | static void iwl6000_set_ct_threshold(struct iwl_priv *priv) | ||
565 | { | ||
566 | /* want Celsius */ | ||
567 | priv->hw_params.ct_kill_threshold = CT_KILL_THRESHOLD; | ||
568 | priv->hw_params.ct_kill_exit_threshold = CT_KILL_EXIT_THRESHOLD; | ||
569 | } | ||
570 | |||
571 | /* NIC configuration for 6000 series */ | ||
572 | static void iwl6000_nic_config(struct iwl_priv *priv) | ||
573 | { | ||
574 | iwl_rf_config(priv); | ||
575 | |||
576 | switch (cfg(priv)->device_family) { | ||
577 | case IWL_DEVICE_FAMILY_6005: | ||
578 | case IWL_DEVICE_FAMILY_6030: | ||
579 | case IWL_DEVICE_FAMILY_6000: | ||
580 | break; | ||
581 | case IWL_DEVICE_FAMILY_6000i: | ||
582 | /* 2x2 IPA phy type */ | ||
583 | iwl_write32(trans(priv), CSR_GP_DRIVER_REG, | ||
584 | CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_IPA); | ||
585 | break; | ||
586 | case IWL_DEVICE_FAMILY_6050: | ||
587 | /* Indicate calibration version to uCode. */ | ||
588 | if (iwl_eeprom_calib_version(priv) >= 6) | ||
589 | iwl_set_bit(trans(priv), CSR_GP_DRIVER_REG, | ||
590 | CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6); | ||
591 | break; | ||
592 | case IWL_DEVICE_FAMILY_6150: | ||
593 | /* Indicate calibration version to uCode. */ | ||
594 | if (iwl_eeprom_calib_version(priv) >= 6) | ||
595 | iwl_set_bit(trans(priv), CSR_GP_DRIVER_REG, | ||
596 | CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6); | ||
597 | iwl_set_bit(trans(priv), CSR_GP_DRIVER_REG, | ||
598 | CSR_GP_DRIVER_REG_BIT_6050_1x2); | ||
599 | break; | ||
600 | default: | ||
601 | WARN_ON(1); | ||
602 | } | ||
603 | } | ||
604 | |||
605 | static const struct iwl_sensitivity_ranges iwl6000_sensitivity = { | ||
606 | .min_nrg_cck = 110, | ||
607 | .auto_corr_min_ofdm = 80, | ||
608 | .auto_corr_min_ofdm_mrc = 128, | ||
609 | .auto_corr_min_ofdm_x1 = 105, | ||
610 | .auto_corr_min_ofdm_mrc_x1 = 192, | ||
611 | |||
612 | .auto_corr_max_ofdm = 145, | ||
613 | .auto_corr_max_ofdm_mrc = 232, | ||
614 | .auto_corr_max_ofdm_x1 = 110, | ||
615 | .auto_corr_max_ofdm_mrc_x1 = 232, | ||
616 | |||
617 | .auto_corr_min_cck = 125, | ||
618 | .auto_corr_max_cck = 175, | ||
619 | .auto_corr_min_cck_mrc = 160, | ||
620 | .auto_corr_max_cck_mrc = 310, | ||
621 | .nrg_th_cck = 110, | ||
622 | .nrg_th_ofdm = 110, | ||
623 | |||
624 | .barker_corr_th_min = 190, | ||
625 | .barker_corr_th_min_mrc = 336, | ||
626 | .nrg_th_cca = 62, | ||
627 | }; | ||
628 | |||
629 | static void iwl6000_hw_set_hw_params(struct iwl_priv *priv) | ||
630 | { | ||
631 | priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) | | ||
632 | BIT(IEEE80211_BAND_5GHZ); | ||
633 | |||
634 | priv->hw_params.tx_chains_num = | ||
635 | num_of_ant(priv->hw_params.valid_tx_ant); | ||
636 | if (cfg(priv)->rx_with_siso_diversity) | ||
637 | priv->hw_params.rx_chains_num = 1; | ||
638 | else | ||
639 | priv->hw_params.rx_chains_num = | ||
640 | num_of_ant(priv->hw_params.valid_rx_ant); | ||
641 | |||
642 | iwl6000_set_ct_threshold(priv); | ||
643 | |||
644 | /* Set initial sensitivity parameters */ | ||
645 | priv->hw_params.sens = &iwl6000_sensitivity; | ||
646 | |||
647 | } | ||
648 | |||
649 | static int iwl6000_hw_channel_switch(struct iwl_priv *priv, | ||
650 | struct ieee80211_channel_switch *ch_switch) | ||
651 | { | ||
652 | /* | ||
653 | * MULTI-FIXME | ||
654 | * See iwlagn_mac_channel_switch. | ||
655 | */ | ||
656 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | ||
657 | struct iwl6000_channel_switch_cmd cmd; | ||
658 | const struct iwl_channel_info *ch_info; | ||
659 | u32 switch_time_in_usec, ucode_switch_time; | ||
660 | u16 ch; | ||
661 | u32 tsf_low; | ||
662 | u8 switch_count; | ||
663 | u16 beacon_interval = le16_to_cpu(ctx->timing.beacon_interval); | ||
664 | struct ieee80211_vif *vif = ctx->vif; | ||
665 | struct iwl_host_cmd hcmd = { | ||
666 | .id = REPLY_CHANNEL_SWITCH, | ||
667 | .len = { sizeof(cmd), }, | ||
668 | .flags = CMD_SYNC, | ||
669 | .data = { &cmd, }, | ||
670 | }; | ||
671 | |||
672 | cmd.band = priv->band == IEEE80211_BAND_2GHZ; | ||
673 | ch = ch_switch->channel->hw_value; | ||
674 | IWL_DEBUG_11H(priv, "channel switch from %u to %u\n", | ||
675 | ctx->active.channel, ch); | ||
676 | cmd.channel = cpu_to_le16(ch); | ||
677 | cmd.rxon_flags = ctx->staging.flags; | ||
678 | cmd.rxon_filter_flags = ctx->staging.filter_flags; | ||
679 | switch_count = ch_switch->count; | ||
680 | tsf_low = ch_switch->timestamp & 0x0ffffffff; | ||
681 | /* | ||
682 | * calculate the ucode channel switch time | ||
683 | * adding TSF as one of the factor for when to switch | ||
684 | */ | ||
685 | if ((priv->ucode_beacon_time > tsf_low) && beacon_interval) { | ||
686 | if (switch_count > ((priv->ucode_beacon_time - tsf_low) / | ||
687 | beacon_interval)) { | ||
688 | switch_count -= (priv->ucode_beacon_time - | ||
689 | tsf_low) / beacon_interval; | ||
690 | } else | ||
691 | switch_count = 0; | ||
692 | } | ||
693 | if (switch_count <= 1) | ||
694 | cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time); | ||
695 | else { | ||
696 | switch_time_in_usec = | ||
697 | vif->bss_conf.beacon_int * switch_count * TIME_UNIT; | ||
698 | ucode_switch_time = iwl_usecs_to_beacons(priv, | ||
699 | switch_time_in_usec, | ||
700 | beacon_interval); | ||
701 | cmd.switch_time = iwl_add_beacon_time(priv, | ||
702 | priv->ucode_beacon_time, | ||
703 | ucode_switch_time, | ||
704 | beacon_interval); | ||
705 | } | ||
706 | IWL_DEBUG_11H(priv, "uCode time for the switch is 0x%x\n", | ||
707 | cmd.switch_time); | ||
708 | ch_info = iwl_get_channel_info(priv, priv->band, ch); | ||
709 | if (ch_info) | ||
710 | cmd.expect_beacon = is_channel_radar(ch_info); | ||
711 | else { | ||
712 | IWL_ERR(priv, "invalid channel switch from %u to %u\n", | ||
713 | ctx->active.channel, ch); | ||
714 | return -EFAULT; | ||
715 | } | ||
716 | |||
717 | return iwl_dvm_send_cmd(priv, &hcmd); | ||
718 | } | ||
719 | |||
720 | struct iwl_lib_ops iwl6000_lib = { | ||
721 | .set_hw_params = iwl6000_hw_set_hw_params, | ||
722 | .set_channel_switch = iwl6000_hw_channel_switch, | ||
723 | .nic_config = iwl6000_nic_config, | ||
724 | .eeprom_ops = { | ||
725 | .regulatory_bands = { | ||
726 | EEPROM_REG_BAND_1_CHANNELS, | ||
727 | EEPROM_REG_BAND_2_CHANNELS, | ||
728 | EEPROM_REG_BAND_3_CHANNELS, | ||
729 | EEPROM_REG_BAND_4_CHANNELS, | ||
730 | EEPROM_REG_BAND_5_CHANNELS, | ||
731 | EEPROM_6000_REG_BAND_24_HT40_CHANNELS, | ||
732 | EEPROM_REG_BAND_52_HT40_CHANNELS | ||
733 | }, | ||
734 | .enhanced_txpower = true, | ||
735 | }, | ||
736 | .temperature = iwlagn_temperature, | ||
737 | }; | ||
738 | |||
739 | struct iwl_lib_ops iwl6030_lib = { | ||
740 | .set_hw_params = iwl6000_hw_set_hw_params, | ||
741 | .set_channel_switch = iwl6000_hw_channel_switch, | ||
742 | .nic_config = iwl6000_nic_config, | ||
743 | .eeprom_ops = { | ||
744 | .regulatory_bands = { | ||
745 | EEPROM_REG_BAND_1_CHANNELS, | ||
746 | EEPROM_REG_BAND_2_CHANNELS, | ||
747 | EEPROM_REG_BAND_3_CHANNELS, | ||
748 | EEPROM_REG_BAND_4_CHANNELS, | ||
749 | EEPROM_REG_BAND_5_CHANNELS, | ||
750 | EEPROM_6000_REG_BAND_24_HT40_CHANNELS, | ||
751 | EEPROM_REG_BAND_52_HT40_CHANNELS | ||
752 | }, | ||
753 | .enhanced_txpower = true, | ||
754 | }, | ||
755 | .temperature = iwlagn_temperature, | ||
756 | }; | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 4da4ab23cce7..4e0c248a0050 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c | |||
@@ -94,77 +94,13 @@ void iwlagn_temperature(struct iwl_priv *priv) | |||
94 | iwl_tt_handler(priv); | 94 | iwl_tt_handler(priv); |
95 | } | 95 | } |
96 | 96 | ||
97 | u16 iwl_eeprom_calib_version(struct iwl_shared *shrd) | ||
98 | { | ||
99 | struct iwl_eeprom_calib_hdr *hdr; | ||
100 | |||
101 | hdr = (struct iwl_eeprom_calib_hdr *)iwl_eeprom_query_addr(shrd, | ||
102 | EEPROM_CALIB_ALL); | ||
103 | return hdr->version; | ||
104 | |||
105 | } | ||
106 | |||
107 | /* | ||
108 | * EEPROM | ||
109 | */ | ||
110 | static u32 eeprom_indirect_address(const struct iwl_shared *shrd, u32 address) | ||
111 | { | ||
112 | u16 offset = 0; | ||
113 | |||
114 | if ((address & INDIRECT_ADDRESS) == 0) | ||
115 | return address; | ||
116 | |||
117 | switch (address & INDIRECT_TYPE_MSK) { | ||
118 | case INDIRECT_HOST: | ||
119 | offset = iwl_eeprom_query16(shrd, EEPROM_LINK_HOST); | ||
120 | break; | ||
121 | case INDIRECT_GENERAL: | ||
122 | offset = iwl_eeprom_query16(shrd, EEPROM_LINK_GENERAL); | ||
123 | break; | ||
124 | case INDIRECT_REGULATORY: | ||
125 | offset = iwl_eeprom_query16(shrd, EEPROM_LINK_REGULATORY); | ||
126 | break; | ||
127 | case INDIRECT_TXP_LIMIT: | ||
128 | offset = iwl_eeprom_query16(shrd, EEPROM_LINK_TXP_LIMIT); | ||
129 | break; | ||
130 | case INDIRECT_TXP_LIMIT_SIZE: | ||
131 | offset = iwl_eeprom_query16(shrd, EEPROM_LINK_TXP_LIMIT_SIZE); | ||
132 | break; | ||
133 | case INDIRECT_CALIBRATION: | ||
134 | offset = iwl_eeprom_query16(shrd, EEPROM_LINK_CALIBRATION); | ||
135 | break; | ||
136 | case INDIRECT_PROCESS_ADJST: | ||
137 | offset = iwl_eeprom_query16(shrd, EEPROM_LINK_PROCESS_ADJST); | ||
138 | break; | ||
139 | case INDIRECT_OTHERS: | ||
140 | offset = iwl_eeprom_query16(shrd, EEPROM_LINK_OTHERS); | ||
141 | break; | ||
142 | default: | ||
143 | IWL_ERR(shrd->trans, "illegal indirect type: 0x%X\n", | ||
144 | address & INDIRECT_TYPE_MSK); | ||
145 | break; | ||
146 | } | ||
147 | |||
148 | /* translate the offset from words to byte */ | ||
149 | return (address & ADDRESS_MSK) + (offset << 1); | ||
150 | } | ||
151 | |||
152 | const u8 *iwl_eeprom_query_addr(const struct iwl_shared *shrd, size_t offset) | ||
153 | { | ||
154 | u32 address = eeprom_indirect_address(shrd, offset); | ||
155 | BUG_ON(address >= shrd->cfg->base_params->eeprom_size); | ||
156 | return &shrd->eeprom[address]; | ||
157 | } | ||
158 | |||
159 | struct iwl_mod_params iwlagn_mod_params = { | 97 | struct iwl_mod_params iwlagn_mod_params = { |
160 | .amsdu_size_8K = 1, | 98 | .amsdu_size_8K = 1, |
161 | .restart_fw = 1, | 99 | .restart_fw = 1, |
162 | .plcp_check = true, | 100 | .plcp_check = true, |
163 | .bt_coex_active = true, | 101 | .bt_coex_active = true, |
164 | .no_sleep_autoadjust = true, | ||
165 | .power_level = IWL_POWER_INDEX_1, | 102 | .power_level = IWL_POWER_INDEX_1, |
166 | .bt_ch_announce = true, | 103 | .bt_ch_announce = true, |
167 | .wanted_ucode_alternative = 1, | ||
168 | .auto_agg = true, | 104 | .auto_agg = true, |
169 | /* the rest are 0 by default */ | 105 | /* the rest are 0 by default */ |
170 | }; | 106 | }; |
@@ -234,7 +170,7 @@ int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control) | |||
234 | IWL_PAN_SCD_BK_MSK | IWL_PAN_SCD_MGMT_MSK | | 170 | IWL_PAN_SCD_BK_MSK | IWL_PAN_SCD_MGMT_MSK | |
235 | IWL_PAN_SCD_MULTICAST_MSK; | 171 | IWL_PAN_SCD_MULTICAST_MSK; |
236 | 172 | ||
237 | if (hw_params(priv).sku & EEPROM_SKU_CAP_11N_ENABLE) | 173 | if (priv->hw_params.sku & EEPROM_SKU_CAP_11N_ENABLE) |
238 | flush_cmd.fifo_control |= IWL_AGG_TX_QUEUE_MSK; | 174 | flush_cmd.fifo_control |= IWL_AGG_TX_QUEUE_MSK; |
239 | 175 | ||
240 | IWL_DEBUG_INFO(priv, "fifo queue control: 0X%x\n", | 176 | IWL_DEBUG_INFO(priv, "fifo queue control: 0X%x\n", |
@@ -369,24 +305,30 @@ void iwlagn_send_advance_bt_config(struct iwl_priv *priv) | |||
369 | .bt3_prio_sample_time = IWLAGN_BT3_PRIO_SAMPLE_DEFAULT, | 305 | .bt3_prio_sample_time = IWLAGN_BT3_PRIO_SAMPLE_DEFAULT, |
370 | .bt3_timer_t2_value = IWLAGN_BT3_T2_DEFAULT, | 306 | .bt3_timer_t2_value = IWLAGN_BT3_T2_DEFAULT, |
371 | }; | 307 | }; |
372 | struct iwl6000_bt_cmd bt_cmd_6000; | 308 | struct iwl_bt_cmd_v1 bt_cmd_v1; |
373 | struct iwl2000_bt_cmd bt_cmd_2000; | 309 | struct iwl_bt_cmd_v2 bt_cmd_v2; |
374 | int ret; | 310 | int ret; |
375 | 311 | ||
376 | BUILD_BUG_ON(sizeof(iwlagn_def_3w_lookup) != | 312 | BUILD_BUG_ON(sizeof(iwlagn_def_3w_lookup) != |
377 | sizeof(basic.bt3_lookup_table)); | 313 | sizeof(basic.bt3_lookup_table)); |
378 | 314 | ||
379 | if (cfg(priv)->bt_params) { | 315 | if (cfg(priv)->bt_params) { |
316 | /* | ||
317 | * newer generation of devices (2000 series and newer) | ||
318 | * use the version 2 of the bt command | ||
319 | * we need to make sure sending the host command | ||
320 | * with correct data structure to avoid uCode assert | ||
321 | */ | ||
380 | if (cfg(priv)->bt_params->bt_session_2) { | 322 | if (cfg(priv)->bt_params->bt_session_2) { |
381 | bt_cmd_2000.prio_boost = cpu_to_le32( | 323 | bt_cmd_v2.prio_boost = cpu_to_le32( |
382 | cfg(priv)->bt_params->bt_prio_boost); | 324 | cfg(priv)->bt_params->bt_prio_boost); |
383 | bt_cmd_2000.tx_prio_boost = 0; | 325 | bt_cmd_v2.tx_prio_boost = 0; |
384 | bt_cmd_2000.rx_prio_boost = 0; | 326 | bt_cmd_v2.rx_prio_boost = 0; |
385 | } else { | 327 | } else { |
386 | bt_cmd_6000.prio_boost = | 328 | bt_cmd_v1.prio_boost = |
387 | cfg(priv)->bt_params->bt_prio_boost; | 329 | cfg(priv)->bt_params->bt_prio_boost; |
388 | bt_cmd_6000.tx_prio_boost = 0; | 330 | bt_cmd_v1.tx_prio_boost = 0; |
389 | bt_cmd_6000.rx_prio_boost = 0; | 331 | bt_cmd_v1.rx_prio_boost = 0; |
390 | } | 332 | } |
391 | } else { | 333 | } else { |
392 | IWL_ERR(priv, "failed to construct BT Coex Config\n"); | 334 | IWL_ERR(priv, "failed to construct BT Coex Config\n"); |
@@ -433,15 +375,15 @@ void iwlagn_send_advance_bt_config(struct iwl_priv *priv) | |||
433 | "full concurrency" : "3-wire"); | 375 | "full concurrency" : "3-wire"); |
434 | 376 | ||
435 | if (cfg(priv)->bt_params->bt_session_2) { | 377 | if (cfg(priv)->bt_params->bt_session_2) { |
436 | memcpy(&bt_cmd_2000.basic, &basic, | 378 | memcpy(&bt_cmd_v2.basic, &basic, |
437 | sizeof(basic)); | 379 | sizeof(basic)); |
438 | ret = iwl_dvm_send_cmd_pdu(priv, REPLY_BT_CONFIG, | 380 | ret = iwl_dvm_send_cmd_pdu(priv, REPLY_BT_CONFIG, |
439 | CMD_SYNC, sizeof(bt_cmd_2000), &bt_cmd_2000); | 381 | CMD_SYNC, sizeof(bt_cmd_v2), &bt_cmd_v2); |
440 | } else { | 382 | } else { |
441 | memcpy(&bt_cmd_6000.basic, &basic, | 383 | memcpy(&bt_cmd_v1.basic, &basic, |
442 | sizeof(basic)); | 384 | sizeof(basic)); |
443 | ret = iwl_dvm_send_cmd_pdu(priv, REPLY_BT_CONFIG, | 385 | ret = iwl_dvm_send_cmd_pdu(priv, REPLY_BT_CONFIG, |
444 | CMD_SYNC, sizeof(bt_cmd_6000), &bt_cmd_6000); | 386 | CMD_SYNC, sizeof(bt_cmd_v1), &bt_cmd_v1); |
445 | } | 387 | } |
446 | if (ret) | 388 | if (ret) |
447 | IWL_ERR(priv, "failed to send BT Coex Config\n"); | 389 | IWL_ERR(priv, "failed to send BT Coex Config\n"); |
@@ -868,7 +810,7 @@ void iwlagn_set_rxon_chain(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | |||
868 | if (priv->chain_noise_data.active_chains) | 810 | if (priv->chain_noise_data.active_chains) |
869 | active_chains = priv->chain_noise_data.active_chains; | 811 | active_chains = priv->chain_noise_data.active_chains; |
870 | else | 812 | else |
871 | active_chains = hw_params(priv).valid_rx_ant; | 813 | active_chains = priv->hw_params.valid_rx_ant; |
872 | 814 | ||
873 | if (cfg(priv)->bt_params && | 815 | if (cfg(priv)->bt_params && |
874 | cfg(priv)->bt_params->advanced_bt_coexist && | 816 | cfg(priv)->bt_params->advanced_bt_coexist && |
@@ -1300,7 +1242,7 @@ int iwl_dvm_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) | |||
1300 | 1242 | ||
1301 | if (test_bit(STATUS_FW_ERROR, &priv->status)) { | 1243 | if (test_bit(STATUS_FW_ERROR, &priv->status)) { |
1302 | IWL_ERR(priv, "Command %s failed: FW Error\n", | 1244 | IWL_ERR(priv, "Command %s failed: FW Error\n", |
1303 | get_cmd_string(cmd->id)); | 1245 | iwl_dvm_get_cmd_string(cmd->id)); |
1304 | return -EIO; | 1246 | return -EIO; |
1305 | } | 1247 | } |
1306 | 1248 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index b936ae7e00a3..8b13b6cf940a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c | |||
@@ -819,7 +819,7 @@ static u32 rs_get_lower_rate(struct iwl_lq_sta *lq_sta, | |||
819 | 819 | ||
820 | if (num_of_ant(tbl->ant_type) > 1) | 820 | if (num_of_ant(tbl->ant_type) > 1) |
821 | tbl->ant_type = | 821 | tbl->ant_type = |
822 | first_antenna(hw_params(priv).valid_tx_ant); | 822 | first_antenna(priv->hw_params.valid_tx_ant); |
823 | 823 | ||
824 | tbl->is_ht40 = 0; | 824 | tbl->is_ht40 = 0; |
825 | tbl->is_SGI = 0; | 825 | tbl->is_SGI = 0; |
@@ -1291,7 +1291,7 @@ static int rs_switch_to_mimo2(struct iwl_priv *priv, | |||
1291 | return -1; | 1291 | return -1; |
1292 | 1292 | ||
1293 | /* Need both Tx chains/antennas to support MIMO */ | 1293 | /* Need both Tx chains/antennas to support MIMO */ |
1294 | if (hw_params(priv).tx_chains_num < 2) | 1294 | if (priv->hw_params.tx_chains_num < 2) |
1295 | return -1; | 1295 | return -1; |
1296 | 1296 | ||
1297 | IWL_DEBUG_RATE(priv, "LQ: try to switch to MIMO2\n"); | 1297 | IWL_DEBUG_RATE(priv, "LQ: try to switch to MIMO2\n"); |
@@ -1347,7 +1347,7 @@ static int rs_switch_to_mimo3(struct iwl_priv *priv, | |||
1347 | return -1; | 1347 | return -1; |
1348 | 1348 | ||
1349 | /* Need both Tx chains/antennas to support MIMO */ | 1349 | /* Need both Tx chains/antennas to support MIMO */ |
1350 | if (hw_params(priv).tx_chains_num < 3) | 1350 | if (priv->hw_params.tx_chains_num < 3) |
1351 | return -1; | 1351 | return -1; |
1352 | 1352 | ||
1353 | IWL_DEBUG_RATE(priv, "LQ: try to switch to MIMO3\n"); | 1353 | IWL_DEBUG_RATE(priv, "LQ: try to switch to MIMO3\n"); |
@@ -1446,8 +1446,8 @@ static int rs_move_legacy_other(struct iwl_priv *priv, | |||
1446 | u32 sz = (sizeof(struct iwl_scale_tbl_info) - | 1446 | u32 sz = (sizeof(struct iwl_scale_tbl_info) - |
1447 | (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); | 1447 | (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); |
1448 | u8 start_action; | 1448 | u8 start_action; |
1449 | u8 valid_tx_ant = hw_params(priv).valid_tx_ant; | 1449 | u8 valid_tx_ant = priv->hw_params.valid_tx_ant; |
1450 | u8 tx_chains_num = hw_params(priv).tx_chains_num; | 1450 | u8 tx_chains_num = priv->hw_params.tx_chains_num; |
1451 | int ret = 0; | 1451 | int ret = 0; |
1452 | u8 update_search_tbl_counter = 0; | 1452 | u8 update_search_tbl_counter = 0; |
1453 | 1453 | ||
@@ -1464,7 +1464,7 @@ static int rs_move_legacy_other(struct iwl_priv *priv, | |||
1464 | case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS: | 1464 | case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS: |
1465 | /* avoid antenna B and MIMO */ | 1465 | /* avoid antenna B and MIMO */ |
1466 | valid_tx_ant = | 1466 | valid_tx_ant = |
1467 | first_antenna(hw_params(priv).valid_tx_ant); | 1467 | first_antenna(priv->hw_params.valid_tx_ant); |
1468 | if (tbl->action >= IWL_LEGACY_SWITCH_ANTENNA2 && | 1468 | if (tbl->action >= IWL_LEGACY_SWITCH_ANTENNA2 && |
1469 | tbl->action != IWL_LEGACY_SWITCH_SISO) | 1469 | tbl->action != IWL_LEGACY_SWITCH_SISO) |
1470 | tbl->action = IWL_LEGACY_SWITCH_SISO; | 1470 | tbl->action = IWL_LEGACY_SWITCH_SISO; |
@@ -1488,7 +1488,7 @@ static int rs_move_legacy_other(struct iwl_priv *priv, | |||
1488 | else if (tbl->action >= IWL_LEGACY_SWITCH_ANTENNA2) | 1488 | else if (tbl->action >= IWL_LEGACY_SWITCH_ANTENNA2) |
1489 | tbl->action = IWL_LEGACY_SWITCH_SISO; | 1489 | tbl->action = IWL_LEGACY_SWITCH_SISO; |
1490 | valid_tx_ant = | 1490 | valid_tx_ant = |
1491 | first_antenna(hw_params(priv).valid_tx_ant); | 1491 | first_antenna(priv->hw_params.valid_tx_ant); |
1492 | } | 1492 | } |
1493 | 1493 | ||
1494 | start_action = tbl->action; | 1494 | start_action = tbl->action; |
@@ -1622,8 +1622,8 @@ static int rs_move_siso_to_other(struct iwl_priv *priv, | |||
1622 | u32 sz = (sizeof(struct iwl_scale_tbl_info) - | 1622 | u32 sz = (sizeof(struct iwl_scale_tbl_info) - |
1623 | (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); | 1623 | (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); |
1624 | u8 start_action; | 1624 | u8 start_action; |
1625 | u8 valid_tx_ant = hw_params(priv).valid_tx_ant; | 1625 | u8 valid_tx_ant = priv->hw_params.valid_tx_ant; |
1626 | u8 tx_chains_num = hw_params(priv).tx_chains_num; | 1626 | u8 tx_chains_num = priv->hw_params.tx_chains_num; |
1627 | u8 update_search_tbl_counter = 0; | 1627 | u8 update_search_tbl_counter = 0; |
1628 | int ret; | 1628 | int ret; |
1629 | 1629 | ||
@@ -1640,7 +1640,7 @@ static int rs_move_siso_to_other(struct iwl_priv *priv, | |||
1640 | case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS: | 1640 | case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS: |
1641 | /* avoid antenna B and MIMO */ | 1641 | /* avoid antenna B and MIMO */ |
1642 | valid_tx_ant = | 1642 | valid_tx_ant = |
1643 | first_antenna(hw_params(priv).valid_tx_ant); | 1643 | first_antenna(priv->hw_params.valid_tx_ant); |
1644 | if (tbl->action != IWL_SISO_SWITCH_ANTENNA1) | 1644 | if (tbl->action != IWL_SISO_SWITCH_ANTENNA1) |
1645 | tbl->action = IWL_SISO_SWITCH_ANTENNA1; | 1645 | tbl->action = IWL_SISO_SWITCH_ANTENNA1; |
1646 | break; | 1646 | break; |
@@ -1658,7 +1658,7 @@ static int rs_move_siso_to_other(struct iwl_priv *priv, | |||
1658 | /* configure as 1x1 if bt full concurrency */ | 1658 | /* configure as 1x1 if bt full concurrency */ |
1659 | if (priv->bt_full_concurrent) { | 1659 | if (priv->bt_full_concurrent) { |
1660 | valid_tx_ant = | 1660 | valid_tx_ant = |
1661 | first_antenna(hw_params(priv).valid_tx_ant); | 1661 | first_antenna(priv->hw_params.valid_tx_ant); |
1662 | if (tbl->action >= IWL_LEGACY_SWITCH_ANTENNA2) | 1662 | if (tbl->action >= IWL_LEGACY_SWITCH_ANTENNA2) |
1663 | tbl->action = IWL_SISO_SWITCH_ANTENNA1; | 1663 | tbl->action = IWL_SISO_SWITCH_ANTENNA1; |
1664 | } | 1664 | } |
@@ -1794,8 +1794,8 @@ static int rs_move_mimo2_to_other(struct iwl_priv *priv, | |||
1794 | u32 sz = (sizeof(struct iwl_scale_tbl_info) - | 1794 | u32 sz = (sizeof(struct iwl_scale_tbl_info) - |
1795 | (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); | 1795 | (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); |
1796 | u8 start_action; | 1796 | u8 start_action; |
1797 | u8 valid_tx_ant = hw_params(priv).valid_tx_ant; | 1797 | u8 valid_tx_ant = priv->hw_params.valid_tx_ant; |
1798 | u8 tx_chains_num = hw_params(priv).tx_chains_num; | 1798 | u8 tx_chains_num = priv->hw_params.tx_chains_num; |
1799 | u8 update_search_tbl_counter = 0; | 1799 | u8 update_search_tbl_counter = 0; |
1800 | int ret; | 1800 | int ret; |
1801 | 1801 | ||
@@ -1964,8 +1964,8 @@ static int rs_move_mimo3_to_other(struct iwl_priv *priv, | |||
1964 | u32 sz = (sizeof(struct iwl_scale_tbl_info) - | 1964 | u32 sz = (sizeof(struct iwl_scale_tbl_info) - |
1965 | (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); | 1965 | (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); |
1966 | u8 start_action; | 1966 | u8 start_action; |
1967 | u8 valid_tx_ant = hw_params(priv).valid_tx_ant; | 1967 | u8 valid_tx_ant = priv->hw_params.valid_tx_ant; |
1968 | u8 tx_chains_num = hw_params(priv).tx_chains_num; | 1968 | u8 tx_chains_num = priv->hw_params.tx_chains_num; |
1969 | int ret; | 1969 | int ret; |
1970 | u8 update_search_tbl_counter = 0; | 1970 | u8 update_search_tbl_counter = 0; |
1971 | 1971 | ||
@@ -2698,7 +2698,7 @@ static void rs_initialize_lq(struct iwl_priv *priv, | |||
2698 | 2698 | ||
2699 | i = lq_sta->last_txrate_idx; | 2699 | i = lq_sta->last_txrate_idx; |
2700 | 2700 | ||
2701 | valid_tx_ant = hw_params(priv).valid_tx_ant; | 2701 | valid_tx_ant = priv->hw_params.valid_tx_ant; |
2702 | 2702 | ||
2703 | if (!lq_sta->search_better_tbl) | 2703 | if (!lq_sta->search_better_tbl) |
2704 | active_tbl = lq_sta->active_tbl; | 2704 | active_tbl = lq_sta->active_tbl; |
@@ -2826,6 +2826,7 @@ void iwl_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, u8 sta_i | |||
2826 | struct iwl_station_priv *sta_priv; | 2826 | struct iwl_station_priv *sta_priv; |
2827 | struct iwl_lq_sta *lq_sta; | 2827 | struct iwl_lq_sta *lq_sta; |
2828 | struct ieee80211_supported_band *sband; | 2828 | struct ieee80211_supported_band *sband; |
2829 | unsigned long supp; /* must be unsigned long for for_each_set_bit */ | ||
2829 | 2830 | ||
2830 | sta_priv = (struct iwl_station_priv *) sta->drv_priv; | 2831 | sta_priv = (struct iwl_station_priv *) sta->drv_priv; |
2831 | lq_sta = &sta_priv->lq_sta; | 2832 | lq_sta = &sta_priv->lq_sta; |
@@ -2855,8 +2856,15 @@ void iwl_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, u8 sta_i | |||
2855 | lq_sta->max_rate_idx = -1; | 2856 | lq_sta->max_rate_idx = -1; |
2856 | lq_sta->missed_rate_counter = IWL_MISSED_RATE_MAX; | 2857 | lq_sta->missed_rate_counter = IWL_MISSED_RATE_MAX; |
2857 | lq_sta->is_green = rs_use_green(sta); | 2858 | lq_sta->is_green = rs_use_green(sta); |
2858 | lq_sta->active_legacy_rate = priv->active_rate & ~(0x1000); | 2859 | lq_sta->band = sband->band; |
2859 | lq_sta->band = priv->band; | 2860 | /* |
2861 | * active legacy rates as per supported rates bitmap | ||
2862 | */ | ||
2863 | supp = sta->supp_rates[sband->band]; | ||
2864 | lq_sta->active_legacy_rate = 0; | ||
2865 | for_each_set_bit(i, &supp, BITS_PER_LONG) | ||
2866 | lq_sta->active_legacy_rate |= BIT(sband->bitrates[i].hw_value); | ||
2867 | |||
2860 | /* | 2868 | /* |
2861 | * active_siso_rate mask includes 9 MBits (bit 5), and CCK (bits 0-3), | 2869 | * active_siso_rate mask includes 9 MBits (bit 5), and CCK (bits 0-3), |
2862 | * supp_rates[] does not; shift to convert format, force 9 MBits off. | 2870 | * supp_rates[] does not; shift to convert format, force 9 MBits off. |
@@ -2884,15 +2892,15 @@ void iwl_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, u8 sta_i | |||
2884 | 2892 | ||
2885 | /* These values will be overridden later */ | 2893 | /* These values will be overridden later */ |
2886 | lq_sta->lq.general_params.single_stream_ant_msk = | 2894 | lq_sta->lq.general_params.single_stream_ant_msk = |
2887 | first_antenna(hw_params(priv).valid_tx_ant); | 2895 | first_antenna(priv->hw_params.valid_tx_ant); |
2888 | lq_sta->lq.general_params.dual_stream_ant_msk = | 2896 | lq_sta->lq.general_params.dual_stream_ant_msk = |
2889 | hw_params(priv).valid_tx_ant & | 2897 | priv->hw_params.valid_tx_ant & |
2890 | ~first_antenna(hw_params(priv).valid_tx_ant); | 2898 | ~first_antenna(priv->hw_params.valid_tx_ant); |
2891 | if (!lq_sta->lq.general_params.dual_stream_ant_msk) { | 2899 | if (!lq_sta->lq.general_params.dual_stream_ant_msk) { |
2892 | lq_sta->lq.general_params.dual_stream_ant_msk = ANT_AB; | 2900 | lq_sta->lq.general_params.dual_stream_ant_msk = ANT_AB; |
2893 | } else if (num_of_ant(hw_params(priv).valid_tx_ant) == 2) { | 2901 | } else if (num_of_ant(priv->hw_params.valid_tx_ant) == 2) { |
2894 | lq_sta->lq.general_params.dual_stream_ant_msk = | 2902 | lq_sta->lq.general_params.dual_stream_ant_msk = |
2895 | hw_params(priv).valid_tx_ant; | 2903 | priv->hw_params.valid_tx_ant; |
2896 | } | 2904 | } |
2897 | 2905 | ||
2898 | /* as default allow aggregation for all tids */ | 2906 | /* as default allow aggregation for all tids */ |
@@ -2938,7 +2946,7 @@ static void rs_fill_link_cmd(struct iwl_priv *priv, | |||
2938 | if (priv && priv->bt_full_concurrent) { | 2946 | if (priv && priv->bt_full_concurrent) { |
2939 | /* 1x1 only */ | 2947 | /* 1x1 only */ |
2940 | tbl_type.ant_type = | 2948 | tbl_type.ant_type = |
2941 | first_antenna(hw_params(priv).valid_tx_ant); | 2949 | first_antenna(priv->hw_params.valid_tx_ant); |
2942 | } | 2950 | } |
2943 | 2951 | ||
2944 | /* How many times should we repeat the initial rate? */ | 2952 | /* How many times should we repeat the initial rate? */ |
@@ -2970,7 +2978,7 @@ static void rs_fill_link_cmd(struct iwl_priv *priv, | |||
2970 | if (priv->bt_full_concurrent) | 2978 | if (priv->bt_full_concurrent) |
2971 | valid_tx_ant = ANT_A; | 2979 | valid_tx_ant = ANT_A; |
2972 | else | 2980 | else |
2973 | valid_tx_ant = hw_params(priv).valid_tx_ant; | 2981 | valid_tx_ant = priv->hw_params.valid_tx_ant; |
2974 | } | 2982 | } |
2975 | 2983 | ||
2976 | /* Fill rest of rate table */ | 2984 | /* Fill rest of rate table */ |
@@ -3004,7 +3012,7 @@ static void rs_fill_link_cmd(struct iwl_priv *priv, | |||
3004 | if (priv && priv->bt_full_concurrent) { | 3012 | if (priv && priv->bt_full_concurrent) { |
3005 | /* 1x1 only */ | 3013 | /* 1x1 only */ |
3006 | tbl_type.ant_type = | 3014 | tbl_type.ant_type = |
3007 | first_antenna(hw_params(priv).valid_tx_ant); | 3015 | first_antenna(priv->hw_params.valid_tx_ant); |
3008 | } | 3016 | } |
3009 | 3017 | ||
3010 | /* Indicate to uCode which entries might be MIMO. | 3018 | /* Indicate to uCode which entries might be MIMO. |
@@ -3091,7 +3099,7 @@ static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta, | |||
3091 | u8 ant_sel_tx; | 3099 | u8 ant_sel_tx; |
3092 | 3100 | ||
3093 | priv = lq_sta->drv; | 3101 | priv = lq_sta->drv; |
3094 | valid_tx_ant = hw_params(priv).valid_tx_ant; | 3102 | valid_tx_ant = priv->hw_params.valid_tx_ant; |
3095 | if (lq_sta->dbg_fixed_rate) { | 3103 | if (lq_sta->dbg_fixed_rate) { |
3096 | ant_sel_tx = | 3104 | ant_sel_tx = |
3097 | ((lq_sta->dbg_fixed_rate & RATE_MCS_ANT_ABC_MSK) | 3105 | ((lq_sta->dbg_fixed_rate & RATE_MCS_ANT_ABC_MSK) |
@@ -3162,9 +3170,9 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file, | |||
3162 | desc += sprintf(buff+desc, "fixed rate 0x%X\n", | 3170 | desc += sprintf(buff+desc, "fixed rate 0x%X\n", |
3163 | lq_sta->dbg_fixed_rate); | 3171 | lq_sta->dbg_fixed_rate); |
3164 | desc += sprintf(buff+desc, "valid_tx_ant %s%s%s\n", | 3172 | desc += sprintf(buff+desc, "valid_tx_ant %s%s%s\n", |
3165 | (hw_params(priv).valid_tx_ant & ANT_A) ? "ANT_A," : "", | 3173 | (priv->hw_params.valid_tx_ant & ANT_A) ? "ANT_A," : "", |
3166 | (hw_params(priv).valid_tx_ant & ANT_B) ? "ANT_B," : "", | 3174 | (priv->hw_params.valid_tx_ant & ANT_B) ? "ANT_B," : "", |
3167 | (hw_params(priv).valid_tx_ant & ANT_C) ? "ANT_C" : ""); | 3175 | (priv->hw_params.valid_tx_ant & ANT_C) ? "ANT_C" : ""); |
3168 | desc += sprintf(buff+desc, "lq type %s\n", | 3176 | desc += sprintf(buff+desc, "lq type %s\n", |
3169 | (is_legacy(tbl->lq_type)) ? "legacy" : "HT"); | 3177 | (is_legacy(tbl->lq_type)) ? "legacy" : "HT"); |
3170 | if (is_Ht(tbl->lq_type)) { | 3178 | if (is_Ht(tbl->lq_type)) { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c index e12f11d50b88..db6c90f6affe 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c | |||
@@ -40,89 +40,86 @@ | |||
40 | #include "iwl-agn.h" | 40 | #include "iwl-agn.h" |
41 | #include "iwl-shared.h" | 41 | #include "iwl-shared.h" |
42 | 42 | ||
43 | const char *get_cmd_string(u8 cmd) | 43 | #define IWL_CMD_ENTRY(x) [x] = #x |
44 | { | 44 | |
45 | switch (cmd) { | 45 | const char *iwl_dvm_cmd_strings[REPLY_MAX] = { |
46 | IWL_CMD(REPLY_ALIVE); | 46 | IWL_CMD_ENTRY(REPLY_ALIVE), |
47 | IWL_CMD(REPLY_ERROR); | 47 | IWL_CMD_ENTRY(REPLY_ERROR), |
48 | IWL_CMD(REPLY_ECHO); | 48 | IWL_CMD_ENTRY(REPLY_ECHO), |
49 | IWL_CMD(REPLY_RXON); | 49 | IWL_CMD_ENTRY(REPLY_RXON), |
50 | IWL_CMD(REPLY_RXON_ASSOC); | 50 | IWL_CMD_ENTRY(REPLY_RXON_ASSOC), |
51 | IWL_CMD(REPLY_QOS_PARAM); | 51 | IWL_CMD_ENTRY(REPLY_QOS_PARAM), |
52 | IWL_CMD(REPLY_RXON_TIMING); | 52 | IWL_CMD_ENTRY(REPLY_RXON_TIMING), |
53 | IWL_CMD(REPLY_ADD_STA); | 53 | IWL_CMD_ENTRY(REPLY_ADD_STA), |
54 | IWL_CMD(REPLY_REMOVE_STA); | 54 | IWL_CMD_ENTRY(REPLY_REMOVE_STA), |
55 | IWL_CMD(REPLY_REMOVE_ALL_STA); | 55 | IWL_CMD_ENTRY(REPLY_REMOVE_ALL_STA), |
56 | IWL_CMD(REPLY_TXFIFO_FLUSH); | 56 | IWL_CMD_ENTRY(REPLY_TXFIFO_FLUSH), |
57 | IWL_CMD(REPLY_WEPKEY); | 57 | IWL_CMD_ENTRY(REPLY_WEPKEY), |
58 | IWL_CMD(REPLY_TX); | 58 | IWL_CMD_ENTRY(REPLY_TX), |
59 | IWL_CMD(REPLY_LEDS_CMD); | 59 | IWL_CMD_ENTRY(REPLY_LEDS_CMD), |
60 | IWL_CMD(REPLY_TX_LINK_QUALITY_CMD); | 60 | IWL_CMD_ENTRY(REPLY_TX_LINK_QUALITY_CMD), |
61 | IWL_CMD(COEX_PRIORITY_TABLE_CMD); | 61 | IWL_CMD_ENTRY(COEX_PRIORITY_TABLE_CMD), |
62 | IWL_CMD(COEX_MEDIUM_NOTIFICATION); | 62 | IWL_CMD_ENTRY(COEX_MEDIUM_NOTIFICATION), |
63 | IWL_CMD(COEX_EVENT_CMD); | 63 | IWL_CMD_ENTRY(COEX_EVENT_CMD), |
64 | IWL_CMD(REPLY_QUIET_CMD); | 64 | IWL_CMD_ENTRY(REPLY_QUIET_CMD), |
65 | IWL_CMD(REPLY_CHANNEL_SWITCH); | 65 | IWL_CMD_ENTRY(REPLY_CHANNEL_SWITCH), |
66 | IWL_CMD(CHANNEL_SWITCH_NOTIFICATION); | 66 | IWL_CMD_ENTRY(CHANNEL_SWITCH_NOTIFICATION), |
67 | IWL_CMD(REPLY_SPECTRUM_MEASUREMENT_CMD); | 67 | IWL_CMD_ENTRY(REPLY_SPECTRUM_MEASUREMENT_CMD), |
68 | IWL_CMD(SPECTRUM_MEASURE_NOTIFICATION); | 68 | IWL_CMD_ENTRY(SPECTRUM_MEASURE_NOTIFICATION), |
69 | IWL_CMD(POWER_TABLE_CMD); | 69 | IWL_CMD_ENTRY(POWER_TABLE_CMD), |
70 | IWL_CMD(PM_SLEEP_NOTIFICATION); | 70 | IWL_CMD_ENTRY(PM_SLEEP_NOTIFICATION), |
71 | IWL_CMD(PM_DEBUG_STATISTIC_NOTIFIC); | 71 | IWL_CMD_ENTRY(PM_DEBUG_STATISTIC_NOTIFIC), |
72 | IWL_CMD(REPLY_SCAN_CMD); | 72 | IWL_CMD_ENTRY(REPLY_SCAN_CMD), |
73 | IWL_CMD(REPLY_SCAN_ABORT_CMD); | 73 | IWL_CMD_ENTRY(REPLY_SCAN_ABORT_CMD), |
74 | IWL_CMD(SCAN_START_NOTIFICATION); | 74 | IWL_CMD_ENTRY(SCAN_START_NOTIFICATION), |
75 | IWL_CMD(SCAN_RESULTS_NOTIFICATION); | 75 | IWL_CMD_ENTRY(SCAN_RESULTS_NOTIFICATION), |
76 | IWL_CMD(SCAN_COMPLETE_NOTIFICATION); | 76 | IWL_CMD_ENTRY(SCAN_COMPLETE_NOTIFICATION), |
77 | IWL_CMD(BEACON_NOTIFICATION); | 77 | IWL_CMD_ENTRY(BEACON_NOTIFICATION), |
78 | IWL_CMD(REPLY_TX_BEACON); | 78 | IWL_CMD_ENTRY(REPLY_TX_BEACON), |
79 | IWL_CMD(WHO_IS_AWAKE_NOTIFICATION); | 79 | IWL_CMD_ENTRY(WHO_IS_AWAKE_NOTIFICATION), |
80 | IWL_CMD(QUIET_NOTIFICATION); | 80 | IWL_CMD_ENTRY(QUIET_NOTIFICATION), |
81 | IWL_CMD(REPLY_TX_PWR_TABLE_CMD); | 81 | IWL_CMD_ENTRY(REPLY_TX_PWR_TABLE_CMD), |
82 | IWL_CMD(MEASURE_ABORT_NOTIFICATION); | 82 | IWL_CMD_ENTRY(MEASURE_ABORT_NOTIFICATION), |
83 | IWL_CMD(REPLY_BT_CONFIG); | 83 | IWL_CMD_ENTRY(REPLY_BT_CONFIG), |
84 | IWL_CMD(REPLY_STATISTICS_CMD); | 84 | IWL_CMD_ENTRY(REPLY_STATISTICS_CMD), |
85 | IWL_CMD(STATISTICS_NOTIFICATION); | 85 | IWL_CMD_ENTRY(STATISTICS_NOTIFICATION), |
86 | IWL_CMD(REPLY_CARD_STATE_CMD); | 86 | IWL_CMD_ENTRY(REPLY_CARD_STATE_CMD), |
87 | IWL_CMD(CARD_STATE_NOTIFICATION); | 87 | IWL_CMD_ENTRY(CARD_STATE_NOTIFICATION), |
88 | IWL_CMD(MISSED_BEACONS_NOTIFICATION); | 88 | IWL_CMD_ENTRY(MISSED_BEACONS_NOTIFICATION), |
89 | IWL_CMD(REPLY_CT_KILL_CONFIG_CMD); | 89 | IWL_CMD_ENTRY(REPLY_CT_KILL_CONFIG_CMD), |
90 | IWL_CMD(SENSITIVITY_CMD); | 90 | IWL_CMD_ENTRY(SENSITIVITY_CMD), |
91 | IWL_CMD(REPLY_PHY_CALIBRATION_CMD); | 91 | IWL_CMD_ENTRY(REPLY_PHY_CALIBRATION_CMD), |
92 | IWL_CMD(REPLY_RX_PHY_CMD); | 92 | IWL_CMD_ENTRY(REPLY_RX_PHY_CMD), |
93 | IWL_CMD(REPLY_RX_MPDU_CMD); | 93 | IWL_CMD_ENTRY(REPLY_RX_MPDU_CMD), |
94 | IWL_CMD(REPLY_RX); | 94 | IWL_CMD_ENTRY(REPLY_RX), |
95 | IWL_CMD(REPLY_COMPRESSED_BA); | 95 | IWL_CMD_ENTRY(REPLY_COMPRESSED_BA), |
96 | IWL_CMD(CALIBRATION_CFG_CMD); | 96 | IWL_CMD_ENTRY(CALIBRATION_CFG_CMD), |
97 | IWL_CMD(CALIBRATION_RES_NOTIFICATION); | 97 | IWL_CMD_ENTRY(CALIBRATION_RES_NOTIFICATION), |
98 | IWL_CMD(CALIBRATION_COMPLETE_NOTIFICATION); | 98 | IWL_CMD_ENTRY(CALIBRATION_COMPLETE_NOTIFICATION), |
99 | IWL_CMD(REPLY_TX_POWER_DBM_CMD); | 99 | IWL_CMD_ENTRY(REPLY_TX_POWER_DBM_CMD), |
100 | IWL_CMD(TEMPERATURE_NOTIFICATION); | 100 | IWL_CMD_ENTRY(TEMPERATURE_NOTIFICATION), |
101 | IWL_CMD(TX_ANT_CONFIGURATION_CMD); | 101 | IWL_CMD_ENTRY(TX_ANT_CONFIGURATION_CMD), |
102 | IWL_CMD(REPLY_BT_COEX_PROFILE_NOTIF); | 102 | IWL_CMD_ENTRY(REPLY_BT_COEX_PROFILE_NOTIF), |
103 | IWL_CMD(REPLY_BT_COEX_PRIO_TABLE); | 103 | IWL_CMD_ENTRY(REPLY_BT_COEX_PRIO_TABLE), |
104 | IWL_CMD(REPLY_BT_COEX_PROT_ENV); | 104 | IWL_CMD_ENTRY(REPLY_BT_COEX_PROT_ENV), |
105 | IWL_CMD(REPLY_WIPAN_PARAMS); | 105 | IWL_CMD_ENTRY(REPLY_WIPAN_PARAMS), |
106 | IWL_CMD(REPLY_WIPAN_RXON); | 106 | IWL_CMD_ENTRY(REPLY_WIPAN_RXON), |
107 | IWL_CMD(REPLY_WIPAN_RXON_TIMING); | 107 | IWL_CMD_ENTRY(REPLY_WIPAN_RXON_TIMING), |
108 | IWL_CMD(REPLY_WIPAN_RXON_ASSOC); | 108 | IWL_CMD_ENTRY(REPLY_WIPAN_RXON_ASSOC), |
109 | IWL_CMD(REPLY_WIPAN_QOS_PARAM); | 109 | IWL_CMD_ENTRY(REPLY_WIPAN_QOS_PARAM), |
110 | IWL_CMD(REPLY_WIPAN_WEPKEY); | 110 | IWL_CMD_ENTRY(REPLY_WIPAN_WEPKEY), |
111 | IWL_CMD(REPLY_WIPAN_P2P_CHANNEL_SWITCH); | 111 | IWL_CMD_ENTRY(REPLY_WIPAN_P2P_CHANNEL_SWITCH), |
112 | IWL_CMD(REPLY_WIPAN_NOA_NOTIFICATION); | 112 | IWL_CMD_ENTRY(REPLY_WIPAN_NOA_NOTIFICATION), |
113 | IWL_CMD(REPLY_WIPAN_DEACTIVATION_COMPLETE); | 113 | IWL_CMD_ENTRY(REPLY_WIPAN_DEACTIVATION_COMPLETE), |
114 | IWL_CMD(REPLY_WOWLAN_PATTERNS); | 114 | IWL_CMD_ENTRY(REPLY_WOWLAN_PATTERNS), |
115 | IWL_CMD(REPLY_WOWLAN_WAKEUP_FILTER); | 115 | IWL_CMD_ENTRY(REPLY_WOWLAN_WAKEUP_FILTER), |
116 | IWL_CMD(REPLY_WOWLAN_TSC_RSC_PARAMS); | 116 | IWL_CMD_ENTRY(REPLY_WOWLAN_TSC_RSC_PARAMS), |
117 | IWL_CMD(REPLY_WOWLAN_TKIP_PARAMS); | 117 | IWL_CMD_ENTRY(REPLY_WOWLAN_TKIP_PARAMS), |
118 | IWL_CMD(REPLY_WOWLAN_KEK_KCK_MATERIAL); | 118 | IWL_CMD_ENTRY(REPLY_WOWLAN_KEK_KCK_MATERIAL), |
119 | IWL_CMD(REPLY_WOWLAN_GET_STATUS); | 119 | IWL_CMD_ENTRY(REPLY_WOWLAN_GET_STATUS), |
120 | IWL_CMD(REPLY_D3_CONFIG); | 120 | IWL_CMD_ENTRY(REPLY_D3_CONFIG), |
121 | default: | 121 | }; |
122 | return "UNKNOWN"; | 122 | #undef IWL_CMD_ENTRY |
123 | |||
124 | } | ||
125 | } | ||
126 | 123 | ||
127 | /****************************************************************************** | 124 | /****************************************************************************** |
128 | * | 125 | * |
@@ -137,10 +134,9 @@ static int iwlagn_rx_reply_error(struct iwl_priv *priv, | |||
137 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 134 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
138 | struct iwl_error_resp *err_resp = (void *)pkt->data; | 135 | struct iwl_error_resp *err_resp = (void *)pkt->data; |
139 | 136 | ||
140 | IWL_ERR(priv, "Error Reply type 0x%08X cmd %s (0x%02X) " | 137 | IWL_ERR(priv, "Error Reply type 0x%08X cmd REPLY_ERROR (0x%02X) " |
141 | "seq 0x%04X ser 0x%08X\n", | 138 | "seq 0x%04X ser 0x%08X\n", |
142 | le32_to_cpu(err_resp->error_type), | 139 | le32_to_cpu(err_resp->error_type), |
143 | get_cmd_string(err_resp->cmd_id), | ||
144 | err_resp->cmd_id, | 140 | err_resp->cmd_id, |
145 | le16_to_cpu(err_resp->bad_cmd_seq_num), | 141 | le16_to_cpu(err_resp->bad_cmd_seq_num), |
146 | le32_to_cpu(err_resp->error_info)); | 142 | le32_to_cpu(err_resp->error_info)); |
@@ -216,8 +212,7 @@ static int iwlagn_rx_pm_debug_statistics_notif(struct iwl_priv *priv, | |||
216 | u32 __maybe_unused len = | 212 | u32 __maybe_unused len = |
217 | le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; | 213 | le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; |
218 | IWL_DEBUG_RADIO(priv, "Dumping %d bytes of unhandled " | 214 | IWL_DEBUG_RADIO(priv, "Dumping %d bytes of unhandled " |
219 | "notification for %s:\n", len, | 215 | "notification for PM_DEBUG_STATISTIC_NOTIFIC:\n", len); |
220 | get_cmd_string(pkt->hdr.cmd)); | ||
221 | iwl_print_hex_dump(priv, IWL_DL_RADIO, pkt->data, len); | 216 | iwl_print_hex_dump(priv, IWL_DL_RADIO, pkt->data, len); |
222 | return 0; | 217 | return 0; |
223 | } | 218 | } |
@@ -246,69 +241,6 @@ static int iwlagn_rx_beacon_notif(struct iwl_priv *priv, | |||
246 | return 0; | 241 | return 0; |
247 | } | 242 | } |
248 | 243 | ||
249 | /* the threshold ratio of actual_ack_cnt to expected_ack_cnt in percent */ | ||
250 | #define ACK_CNT_RATIO (50) | ||
251 | #define BA_TIMEOUT_CNT (5) | ||
252 | #define BA_TIMEOUT_MAX (16) | ||
253 | |||
254 | /** | ||
255 | * iwl_good_ack_health - checks for ACK count ratios, BA timeout retries. | ||
256 | * | ||
257 | * When the ACK count ratio is low and aggregated BA timeout retries exceeding | ||
258 | * the BA_TIMEOUT_MAX, reload firmware and bring system back to normal | ||
259 | * operation state. | ||
260 | */ | ||
261 | static bool iwlagn_good_ack_health(struct iwl_priv *priv, | ||
262 | struct statistics_tx *cur) | ||
263 | { | ||
264 | int actual_delta, expected_delta, ba_timeout_delta; | ||
265 | struct statistics_tx *old; | ||
266 | |||
267 | if (priv->agg_tids_count) | ||
268 | return true; | ||
269 | |||
270 | lockdep_assert_held(&priv->statistics.lock); | ||
271 | |||
272 | old = &priv->statistics.tx; | ||
273 | |||
274 | actual_delta = le32_to_cpu(cur->actual_ack_cnt) - | ||
275 | le32_to_cpu(old->actual_ack_cnt); | ||
276 | expected_delta = le32_to_cpu(cur->expected_ack_cnt) - | ||
277 | le32_to_cpu(old->expected_ack_cnt); | ||
278 | |||
279 | /* Values should not be negative, but we do not trust the firmware */ | ||
280 | if (actual_delta <= 0 || expected_delta <= 0) | ||
281 | return true; | ||
282 | |||
283 | ba_timeout_delta = le32_to_cpu(cur->agg.ba_timeout) - | ||
284 | le32_to_cpu(old->agg.ba_timeout); | ||
285 | |||
286 | if ((actual_delta * 100 / expected_delta) < ACK_CNT_RATIO && | ||
287 | ba_timeout_delta > BA_TIMEOUT_CNT) { | ||
288 | IWL_DEBUG_RADIO(priv, | ||
289 | "deltas: actual %d expected %d ba_timeout %d\n", | ||
290 | actual_delta, expected_delta, ba_timeout_delta); | ||
291 | |||
292 | #ifdef CONFIG_IWLWIFI_DEBUGFS | ||
293 | /* | ||
294 | * This is ifdef'ed on DEBUGFS because otherwise the | ||
295 | * statistics aren't available. If DEBUGFS is set but | ||
296 | * DEBUG is not, these will just compile out. | ||
297 | */ | ||
298 | IWL_DEBUG_RADIO(priv, "rx_detected_cnt delta %d\n", | ||
299 | priv->delta_stats.tx.rx_detected_cnt); | ||
300 | IWL_DEBUG_RADIO(priv, | ||
301 | "ack_or_ba_timeout_collision delta %d\n", | ||
302 | priv->delta_stats.tx.ack_or_ba_timeout_collision); | ||
303 | #endif | ||
304 | |||
305 | if (ba_timeout_delta >= BA_TIMEOUT_MAX) | ||
306 | return false; | ||
307 | } | ||
308 | |||
309 | return true; | ||
310 | } | ||
311 | |||
312 | /** | 244 | /** |
313 | * iwl_good_plcp_health - checks for plcp error. | 245 | * iwl_good_plcp_health - checks for plcp error. |
314 | * | 246 | * |
@@ -347,6 +279,45 @@ static bool iwlagn_good_plcp_health(struct iwl_priv *priv, | |||
347 | return true; | 279 | return true; |
348 | } | 280 | } |
349 | 281 | ||
282 | int iwl_force_rf_reset(struct iwl_priv *priv, bool external) | ||
283 | { | ||
284 | struct iwl_rf_reset *rf_reset; | ||
285 | |||
286 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | ||
287 | return -EAGAIN; | ||
288 | |||
289 | if (!iwl_is_any_associated(priv)) { | ||
290 | IWL_DEBUG_SCAN(priv, "force reset rejected: not associated\n"); | ||
291 | return -ENOLINK; | ||
292 | } | ||
293 | |||
294 | rf_reset = &priv->rf_reset; | ||
295 | rf_reset->reset_request_count++; | ||
296 | if (!external && rf_reset->last_reset_jiffies && | ||
297 | time_after(rf_reset->last_reset_jiffies + | ||
298 | IWL_DELAY_NEXT_FORCE_RF_RESET, jiffies)) { | ||
299 | IWL_DEBUG_INFO(priv, "RF reset rejected\n"); | ||
300 | rf_reset->reset_reject_count++; | ||
301 | return -EAGAIN; | ||
302 | } | ||
303 | rf_reset->reset_success_count++; | ||
304 | rf_reset->last_reset_jiffies = jiffies; | ||
305 | |||
306 | /* | ||
307 | * There is no easy and better way to force reset the radio, | ||
308 | * the only known method is switching channel which will force to | ||
309 | * reset and tune the radio. | ||
310 | * Use internal short scan (single channel) operation to should | ||
311 | * achieve this objective. | ||
312 | * Driver should reset the radio when number of consecutive missed | ||
313 | * beacon, or any other uCode error condition detected. | ||
314 | */ | ||
315 | IWL_DEBUG_INFO(priv, "perform radio reset.\n"); | ||
316 | iwl_internal_short_hw_scan(priv); | ||
317 | return 0; | ||
318 | } | ||
319 | |||
320 | |||
350 | static void iwlagn_recover_from_statistics(struct iwl_priv *priv, | 321 | static void iwlagn_recover_from_statistics(struct iwl_priv *priv, |
351 | struct statistics_rx_phy *cur_ofdm, | 322 | struct statistics_rx_phy *cur_ofdm, |
352 | struct statistics_rx_ht_phy *cur_ofdm_ht, | 323 | struct statistics_rx_ht_phy *cur_ofdm_ht, |
@@ -368,15 +339,9 @@ static void iwlagn_recover_from_statistics(struct iwl_priv *priv, | |||
368 | if (msecs < 99) | 339 | if (msecs < 99) |
369 | return; | 340 | return; |
370 | 341 | ||
371 | if (iwlagn_mod_params.ack_check && !iwlagn_good_ack_health(priv, tx)) { | ||
372 | IWL_ERR(priv, "low ack count detected, restart firmware\n"); | ||
373 | if (!iwl_force_reset(priv, IWL_FW_RESET, false)) | ||
374 | return; | ||
375 | } | ||
376 | |||
377 | if (iwlagn_mod_params.plcp_check && | 342 | if (iwlagn_mod_params.plcp_check && |
378 | !iwlagn_good_plcp_health(priv, cur_ofdm, cur_ofdm_ht, msecs)) | 343 | !iwlagn_good_plcp_health(priv, cur_ofdm, cur_ofdm_ht, msecs)) |
379 | iwl_force_reset(priv, IWL_RF_RESET, false); | 344 | iwl_force_rf_reset(priv, false); |
380 | } | 345 | } |
381 | 346 | ||
382 | /* Calculate noise level, based on measurements during network silence just | 347 | /* Calculate noise level, based on measurements during network silence just |
@@ -589,8 +554,8 @@ static int iwlagn_rx_statistics(struct iwl_priv *priv, | |||
589 | iwlagn_rx_calc_noise(priv); | 554 | iwlagn_rx_calc_noise(priv); |
590 | queue_work(priv->workqueue, &priv->run_time_calib_work); | 555 | queue_work(priv->workqueue, &priv->run_time_calib_work); |
591 | } | 556 | } |
592 | if (cfg(priv)->lib->temperature && change) | 557 | if (priv->lib->temperature && change) |
593 | cfg(priv)->lib->temperature(priv); | 558 | priv->lib->temperature(priv); |
594 | 559 | ||
595 | spin_unlock(&priv->statistics.lock); | 560 | spin_unlock(&priv->statistics.lock); |
596 | 561 | ||
@@ -1182,9 +1147,9 @@ int iwl_rx_dispatch(struct iwl_op_mode *op_mode, struct iwl_rx_cmd_buffer *rxb, | |||
1182 | err = priv->rx_handlers[pkt->hdr.cmd] (priv, rxb, cmd); | 1147 | err = priv->rx_handlers[pkt->hdr.cmd] (priv, rxb, cmd); |
1183 | } else { | 1148 | } else { |
1184 | /* No handling needed */ | 1149 | /* No handling needed */ |
1185 | IWL_DEBUG_RX(priv, | 1150 | IWL_DEBUG_RX(priv, "No handler needed for %s, 0x%02x\n", |
1186 | "No handler needed for %s, 0x%02x\n", | 1151 | iwl_dvm_get_cmd_string(pkt->hdr.cmd), |
1187 | get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd); | 1152 | pkt->hdr.cmd); |
1188 | } | 1153 | } |
1189 | } | 1154 | } |
1190 | return err; | 1155 | return err; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index 79d857d81b41..5c7bddd5cfef 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | |||
@@ -32,6 +32,78 @@ | |||
32 | #include "iwl-trans.h" | 32 | #include "iwl-trans.h" |
33 | #include "iwl-shared.h" | 33 | #include "iwl-shared.h" |
34 | 34 | ||
35 | /* | ||
36 | * initialize rxon structure with default values from eeprom | ||
37 | */ | ||
38 | void iwl_connection_init_rx_config(struct iwl_priv *priv, | ||
39 | struct iwl_rxon_context *ctx) | ||
40 | { | ||
41 | const struct iwl_channel_info *ch_info; | ||
42 | |||
43 | memset(&ctx->staging, 0, sizeof(ctx->staging)); | ||
44 | |||
45 | if (!ctx->vif) { | ||
46 | ctx->staging.dev_type = ctx->unused_devtype; | ||
47 | } else | ||
48 | switch (ctx->vif->type) { | ||
49 | case NL80211_IFTYPE_AP: | ||
50 | ctx->staging.dev_type = ctx->ap_devtype; | ||
51 | break; | ||
52 | |||
53 | case NL80211_IFTYPE_STATION: | ||
54 | ctx->staging.dev_type = ctx->station_devtype; | ||
55 | ctx->staging.filter_flags = RXON_FILTER_ACCEPT_GRP_MSK; | ||
56 | break; | ||
57 | |||
58 | case NL80211_IFTYPE_ADHOC: | ||
59 | ctx->staging.dev_type = ctx->ibss_devtype; | ||
60 | ctx->staging.flags = RXON_FLG_SHORT_PREAMBLE_MSK; | ||
61 | ctx->staging.filter_flags = RXON_FILTER_BCON_AWARE_MSK | | ||
62 | RXON_FILTER_ACCEPT_GRP_MSK; | ||
63 | break; | ||
64 | |||
65 | default: | ||
66 | IWL_ERR(priv, "Unsupported interface type %d\n", | ||
67 | ctx->vif->type); | ||
68 | break; | ||
69 | } | ||
70 | |||
71 | #if 0 | ||
72 | /* TODO: Figure out when short_preamble would be set and cache from | ||
73 | * that */ | ||
74 | if (!hw_to_local(priv->hw)->short_preamble) | ||
75 | ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; | ||
76 | else | ||
77 | ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; | ||
78 | #endif | ||
79 | |||
80 | ch_info = iwl_get_channel_info(priv, priv->band, | ||
81 | le16_to_cpu(ctx->active.channel)); | ||
82 | |||
83 | if (!ch_info) | ||
84 | ch_info = &priv->channel_info[0]; | ||
85 | |||
86 | ctx->staging.channel = cpu_to_le16(ch_info->channel); | ||
87 | priv->band = ch_info->band; | ||
88 | |||
89 | iwl_set_flags_for_band(priv, ctx, priv->band, ctx->vif); | ||
90 | |||
91 | ctx->staging.ofdm_basic_rates = | ||
92 | (IWL_OFDM_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF; | ||
93 | ctx->staging.cck_basic_rates = | ||
94 | (IWL_CCK_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF; | ||
95 | |||
96 | /* clear both MIX and PURE40 mode flag */ | ||
97 | ctx->staging.flags &= ~(RXON_FLG_CHANNEL_MODE_MIXED | | ||
98 | RXON_FLG_CHANNEL_MODE_PURE_40); | ||
99 | if (ctx->vif) | ||
100 | memcpy(ctx->staging.node_addr, ctx->vif->addr, ETH_ALEN); | ||
101 | |||
102 | ctx->staging.ofdm_ht_single_stream_basic_rates = 0xff; | ||
103 | ctx->staging.ofdm_ht_dual_stream_basic_rates = 0xff; | ||
104 | ctx->staging.ofdm_ht_triple_stream_basic_rates = 0xff; | ||
105 | } | ||
106 | |||
35 | static int iwlagn_disable_bss(struct iwl_priv *priv, | 107 | static int iwlagn_disable_bss(struct iwl_priv *priv, |
36 | struct iwl_rxon_context *ctx, | 108 | struct iwl_rxon_context *ctx, |
37 | struct iwl_rxon_cmd *send) | 109 | struct iwl_rxon_cmd *send) |
@@ -105,8 +177,7 @@ static int iwlagn_disconn_pan(struct iwl_priv *priv, | |||
105 | return ret; | 177 | return ret; |
106 | } | 178 | } |
107 | 179 | ||
108 | static void iwlagn_update_qos(struct iwl_priv *priv, | 180 | void iwlagn_update_qos(struct iwl_priv *priv, struct iwl_rxon_context *ctx) |
109 | struct iwl_rxon_context *ctx) | ||
110 | { | 181 | { |
111 | int ret; | 182 | int ret; |
112 | 183 | ||
@@ -133,8 +204,8 @@ static void iwlagn_update_qos(struct iwl_priv *priv, | |||
133 | IWL_DEBUG_QUIET_RFKILL(priv, "Failed to update QoS\n"); | 204 | IWL_DEBUG_QUIET_RFKILL(priv, "Failed to update QoS\n"); |
134 | } | 205 | } |
135 | 206 | ||
136 | static int iwlagn_update_beacon(struct iwl_priv *priv, | 207 | int iwlagn_update_beacon(struct iwl_priv *priv, |
137 | struct ieee80211_vif *vif) | 208 | struct ieee80211_vif *vif) |
138 | { | 209 | { |
139 | lockdep_assert_held(&priv->mutex); | 210 | lockdep_assert_held(&priv->mutex); |
140 | 211 | ||
@@ -335,6 +406,64 @@ static int iwlagn_rxon_disconn(struct iwl_priv *priv, | |||
335 | return 0; | 406 | return 0; |
336 | } | 407 | } |
337 | 408 | ||
409 | static int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force) | ||
410 | { | ||
411 | int ret; | ||
412 | s8 prev_tx_power; | ||
413 | bool defer; | ||
414 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | ||
415 | |||
416 | if (priv->calib_disabled & IWL_TX_POWER_CALIB_DISABLED) | ||
417 | return 0; | ||
418 | |||
419 | lockdep_assert_held(&priv->mutex); | ||
420 | |||
421 | if (priv->tx_power_user_lmt == tx_power && !force) | ||
422 | return 0; | ||
423 | |||
424 | if (tx_power < IWLAGN_TX_POWER_TARGET_POWER_MIN) { | ||
425 | IWL_WARN(priv, | ||
426 | "Requested user TXPOWER %d below lower limit %d.\n", | ||
427 | tx_power, | ||
428 | IWLAGN_TX_POWER_TARGET_POWER_MIN); | ||
429 | return -EINVAL; | ||
430 | } | ||
431 | |||
432 | if (tx_power > priv->tx_power_device_lmt) { | ||
433 | IWL_WARN(priv, | ||
434 | "Requested user TXPOWER %d above upper limit %d.\n", | ||
435 | tx_power, priv->tx_power_device_lmt); | ||
436 | return -EINVAL; | ||
437 | } | ||
438 | |||
439 | if (!iwl_is_ready_rf(priv)) | ||
440 | return -EIO; | ||
441 | |||
442 | /* scan complete and commit_rxon use tx_power_next value, | ||
443 | * it always need to be updated for newest request */ | ||
444 | priv->tx_power_next = tx_power; | ||
445 | |||
446 | /* do not set tx power when scanning or channel changing */ | ||
447 | defer = test_bit(STATUS_SCANNING, &priv->status) || | ||
448 | memcmp(&ctx->active, &ctx->staging, sizeof(ctx->staging)); | ||
449 | if (defer && !force) { | ||
450 | IWL_DEBUG_INFO(priv, "Deferring tx power set\n"); | ||
451 | return 0; | ||
452 | } | ||
453 | |||
454 | prev_tx_power = priv->tx_power_user_lmt; | ||
455 | priv->tx_power_user_lmt = tx_power; | ||
456 | |||
457 | ret = iwlagn_send_tx_power(priv); | ||
458 | |||
459 | /* if fail to set tx_power, restore the orig. tx power */ | ||
460 | if (ret) { | ||
461 | priv->tx_power_user_lmt = prev_tx_power; | ||
462 | priv->tx_power_next = prev_tx_power; | ||
463 | } | ||
464 | return ret; | ||
465 | } | ||
466 | |||
338 | static int iwlagn_rxon_connect(struct iwl_priv *priv, | 467 | static int iwlagn_rxon_connect(struct iwl_priv *priv, |
339 | struct iwl_rxon_context *ctx) | 468 | struct iwl_rxon_context *ctx) |
340 | { | 469 | { |
@@ -501,6 +630,161 @@ int iwlagn_set_pan_params(struct iwl_priv *priv) | |||
501 | return ret; | 630 | return ret; |
502 | } | 631 | } |
503 | 632 | ||
633 | static void _iwl_set_rxon_ht(struct iwl_priv *priv, | ||
634 | struct iwl_ht_config *ht_conf, | ||
635 | struct iwl_rxon_context *ctx) | ||
636 | { | ||
637 | struct iwl_rxon_cmd *rxon = &ctx->staging; | ||
638 | |||
639 | if (!ctx->ht.enabled) { | ||
640 | rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MSK | | ||
641 | RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK | | ||
642 | RXON_FLG_HT40_PROT_MSK | | ||
643 | RXON_FLG_HT_PROT_MSK); | ||
644 | return; | ||
645 | } | ||
646 | |||
647 | /* FIXME: if the definition of ht.protection changed, the "translation" | ||
648 | * will be needed for rxon->flags | ||
649 | */ | ||
650 | rxon->flags |= cpu_to_le32(ctx->ht.protection << | ||
651 | RXON_FLG_HT_OPERATING_MODE_POS); | ||
652 | |||
653 | /* Set up channel bandwidth: | ||
654 | * 20 MHz only, 20/40 mixed or pure 40 if ht40 ok */ | ||
655 | /* clear the HT channel mode before set the mode */ | ||
656 | rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MSK | | ||
657 | RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK); | ||
658 | if (iwl_is_ht40_tx_allowed(priv, ctx, NULL)) { | ||
659 | /* pure ht40 */ | ||
660 | if (ctx->ht.protection == | ||
661 | IEEE80211_HT_OP_MODE_PROTECTION_20MHZ) { | ||
662 | rxon->flags |= RXON_FLG_CHANNEL_MODE_PURE_40; | ||
663 | /* | ||
664 | * Note: control channel is opposite of extension | ||
665 | * channel | ||
666 | */ | ||
667 | switch (ctx->ht.extension_chan_offset) { | ||
668 | case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: | ||
669 | rxon->flags &= | ||
670 | ~RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK; | ||
671 | break; | ||
672 | case IEEE80211_HT_PARAM_CHA_SEC_BELOW: | ||
673 | rxon->flags |= | ||
674 | RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK; | ||
675 | break; | ||
676 | } | ||
677 | } else { | ||
678 | /* | ||
679 | * Note: control channel is opposite of extension | ||
680 | * channel | ||
681 | */ | ||
682 | switch (ctx->ht.extension_chan_offset) { | ||
683 | case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: | ||
684 | rxon->flags &= | ||
685 | ~(RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK); | ||
686 | rxon->flags |= RXON_FLG_CHANNEL_MODE_MIXED; | ||
687 | break; | ||
688 | case IEEE80211_HT_PARAM_CHA_SEC_BELOW: | ||
689 | rxon->flags |= RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK; | ||
690 | rxon->flags |= RXON_FLG_CHANNEL_MODE_MIXED; | ||
691 | break; | ||
692 | case IEEE80211_HT_PARAM_CHA_SEC_NONE: | ||
693 | default: | ||
694 | /* | ||
695 | * channel location only valid if in Mixed | ||
696 | * mode | ||
697 | */ | ||
698 | IWL_ERR(priv, | ||
699 | "invalid extension channel offset\n"); | ||
700 | break; | ||
701 | } | ||
702 | } | ||
703 | } else { | ||
704 | rxon->flags |= RXON_FLG_CHANNEL_MODE_LEGACY; | ||
705 | } | ||
706 | |||
707 | iwlagn_set_rxon_chain(priv, ctx); | ||
708 | |||
709 | IWL_DEBUG_ASSOC(priv, "rxon flags 0x%X operation mode :0x%X " | ||
710 | "extension channel offset 0x%x\n", | ||
711 | le32_to_cpu(rxon->flags), ctx->ht.protection, | ||
712 | ctx->ht.extension_chan_offset); | ||
713 | } | ||
714 | |||
715 | void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_config *ht_conf) | ||
716 | { | ||
717 | struct iwl_rxon_context *ctx; | ||
718 | |||
719 | for_each_context(priv, ctx) | ||
720 | _iwl_set_rxon_ht(priv, ht_conf, ctx); | ||
721 | } | ||
722 | |||
723 | /** | ||
724 | * iwl_set_rxon_channel - Set the band and channel values in staging RXON | ||
725 | * @ch: requested channel as a pointer to struct ieee80211_channel | ||
726 | |||
727 | * NOTE: Does not commit to the hardware; it sets appropriate bit fields | ||
728 | * in the staging RXON flag structure based on the ch->band | ||
729 | */ | ||
730 | void iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch, | ||
731 | struct iwl_rxon_context *ctx) | ||
732 | { | ||
733 | enum ieee80211_band band = ch->band; | ||
734 | u16 channel = ch->hw_value; | ||
735 | |||
736 | if ((le16_to_cpu(ctx->staging.channel) == channel) && | ||
737 | (priv->band == band)) | ||
738 | return; | ||
739 | |||
740 | ctx->staging.channel = cpu_to_le16(channel); | ||
741 | if (band == IEEE80211_BAND_5GHZ) | ||
742 | ctx->staging.flags &= ~RXON_FLG_BAND_24G_MSK; | ||
743 | else | ||
744 | ctx->staging.flags |= RXON_FLG_BAND_24G_MSK; | ||
745 | |||
746 | priv->band = band; | ||
747 | |||
748 | IWL_DEBUG_INFO(priv, "Staging channel set to %d [%d]\n", channel, band); | ||
749 | |||
750 | } | ||
751 | |||
752 | void iwl_set_flags_for_band(struct iwl_priv *priv, | ||
753 | struct iwl_rxon_context *ctx, | ||
754 | enum ieee80211_band band, | ||
755 | struct ieee80211_vif *vif) | ||
756 | { | ||
757 | if (band == IEEE80211_BAND_5GHZ) { | ||
758 | ctx->staging.flags &= | ||
759 | ~(RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK | ||
760 | | RXON_FLG_CCK_MSK); | ||
761 | ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; | ||
762 | } else { | ||
763 | /* Copied from iwl_post_associate() */ | ||
764 | if (vif && vif->bss_conf.use_short_slot) | ||
765 | ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; | ||
766 | else | ||
767 | ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK; | ||
768 | |||
769 | ctx->staging.flags |= RXON_FLG_BAND_24G_MSK; | ||
770 | ctx->staging.flags |= RXON_FLG_AUTO_DETECT_MSK; | ||
771 | ctx->staging.flags &= ~RXON_FLG_CCK_MSK; | ||
772 | } | ||
773 | } | ||
774 | |||
775 | void iwl_set_rate(struct iwl_priv *priv) | ||
776 | { | ||
777 | struct iwl_rxon_context *ctx; | ||
778 | |||
779 | for_each_context(priv, ctx) { | ||
780 | ctx->staging.cck_basic_rates = | ||
781 | (IWL_CCK_BASIC_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF; | ||
782 | |||
783 | ctx->staging.ofdm_basic_rates = | ||
784 | (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF; | ||
785 | } | ||
786 | } | ||
787 | |||
504 | static void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, | 788 | static void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, |
505 | struct iwl_rxon_context *ctx, int hw_decrypt) | 789 | struct iwl_rxon_context *ctx, int hw_decrypt) |
506 | { | 790 | { |
@@ -594,8 +878,8 @@ static int iwl_check_rxon_cmd(struct iwl_priv *priv, | |||
594 | * or is clearing the RXON_FILTER_ASSOC_MSK, then return 1 to indicate that | 878 | * or is clearing the RXON_FILTER_ASSOC_MSK, then return 1 to indicate that |
595 | * a new tune (full RXON command, rather than RXON_ASSOC cmd) is required. | 879 | * a new tune (full RXON command, rather than RXON_ASSOC cmd) is required. |
596 | */ | 880 | */ |
597 | static int iwl_full_rxon_required(struct iwl_priv *priv, | 881 | int iwl_full_rxon_required(struct iwl_priv *priv, |
598 | struct iwl_rxon_context *ctx) | 882 | struct iwl_rxon_context *ctx) |
599 | { | 883 | { |
600 | const struct iwl_rxon_cmd *staging = &ctx->staging; | 884 | const struct iwl_rxon_cmd *staging = &ctx->staging; |
601 | const struct iwl_rxon_cmd *active = &ctx->active; | 885 | const struct iwl_rxon_cmd *active = &ctx->active; |
@@ -649,6 +933,33 @@ static int iwl_full_rxon_required(struct iwl_priv *priv, | |||
649 | return 0; | 933 | return 0; |
650 | } | 934 | } |
651 | 935 | ||
936 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
937 | void iwl_print_rx_config_cmd(struct iwl_priv *priv, | ||
938 | enum iwl_rxon_context_id ctxid) | ||
939 | { | ||
940 | struct iwl_rxon_context *ctx = &priv->contexts[ctxid]; | ||
941 | struct iwl_rxon_cmd *rxon = &ctx->staging; | ||
942 | |||
943 | IWL_DEBUG_RADIO(priv, "RX CONFIG:\n"); | ||
944 | iwl_print_hex_dump(priv, IWL_DL_RADIO, (u8 *) rxon, sizeof(*rxon)); | ||
945 | IWL_DEBUG_RADIO(priv, "u16 channel: 0x%x\n", | ||
946 | le16_to_cpu(rxon->channel)); | ||
947 | IWL_DEBUG_RADIO(priv, "u32 flags: 0x%08X\n", | ||
948 | le32_to_cpu(rxon->flags)); | ||
949 | IWL_DEBUG_RADIO(priv, "u32 filter_flags: 0x%08x\n", | ||
950 | le32_to_cpu(rxon->filter_flags)); | ||
951 | IWL_DEBUG_RADIO(priv, "u8 dev_type: 0x%x\n", rxon->dev_type); | ||
952 | IWL_DEBUG_RADIO(priv, "u8 ofdm_basic_rates: 0x%02x\n", | ||
953 | rxon->ofdm_basic_rates); | ||
954 | IWL_DEBUG_RADIO(priv, "u8 cck_basic_rates: 0x%02x\n", | ||
955 | rxon->cck_basic_rates); | ||
956 | IWL_DEBUG_RADIO(priv, "u8[6] node_addr: %pM\n", rxon->node_addr); | ||
957 | IWL_DEBUG_RADIO(priv, "u8[6] bssid_addr: %pM\n", rxon->bssid_addr); | ||
958 | IWL_DEBUG_RADIO(priv, "u16 assoc_id: 0x%x\n", | ||
959 | le16_to_cpu(rxon->assoc_id)); | ||
960 | } | ||
961 | #endif | ||
962 | |||
652 | /** | 963 | /** |
653 | * iwlagn_commit_rxon - commit staging_rxon to hardware | 964 | * iwlagn_commit_rxon - commit staging_rxon to hardware |
654 | * | 965 | * |
@@ -692,7 +1003,7 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | |||
692 | * force CTS-to-self frames protection if RTS-CTS is not preferred | 1003 | * force CTS-to-self frames protection if RTS-CTS is not preferred |
693 | * one aggregation protection method | 1004 | * one aggregation protection method |
694 | */ | 1005 | */ |
695 | if (!hw_params(priv).use_rts_for_aggregation) | 1006 | if (!priv->hw_params.use_rts_for_aggregation) |
696 | ctx->staging.flags |= RXON_FLG_SELF_CTS_EN; | 1007 | ctx->staging.flags |= RXON_FLG_SELF_CTS_EN; |
697 | 1008 | ||
698 | if ((ctx->vif && ctx->vif->bss_conf.use_short_slot) || | 1009 | if ((ctx->vif && ctx->vif->bss_conf.use_short_slot) || |
@@ -911,9 +1222,9 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) | |||
911 | return ret; | 1222 | return ret; |
912 | } | 1223 | } |
913 | 1224 | ||
914 | static void iwlagn_check_needed_chains(struct iwl_priv *priv, | 1225 | void iwlagn_check_needed_chains(struct iwl_priv *priv, |
915 | struct iwl_rxon_context *ctx, | 1226 | struct iwl_rxon_context *ctx, |
916 | struct ieee80211_bss_conf *bss_conf) | 1227 | struct ieee80211_bss_conf *bss_conf) |
917 | { | 1228 | { |
918 | struct ieee80211_vif *vif = ctx->vif; | 1229 | struct ieee80211_vif *vif = ctx->vif; |
919 | struct iwl_rxon_context *tmp; | 1230 | struct iwl_rxon_context *tmp; |
@@ -1005,11 +1316,14 @@ static void iwlagn_check_needed_chains(struct iwl_priv *priv, | |||
1005 | ht_conf->single_chain_sufficient = !need_multiple; | 1316 | ht_conf->single_chain_sufficient = !need_multiple; |
1006 | } | 1317 | } |
1007 | 1318 | ||
1008 | static void iwlagn_chain_noise_reset(struct iwl_priv *priv) | 1319 | void iwlagn_chain_noise_reset(struct iwl_priv *priv) |
1009 | { | 1320 | { |
1010 | struct iwl_chain_noise_data *data = &priv->chain_noise_data; | 1321 | struct iwl_chain_noise_data *data = &priv->chain_noise_data; |
1011 | int ret; | 1322 | int ret; |
1012 | 1323 | ||
1324 | if (!(priv->calib_disabled & IWL_CHAIN_NOISE_CALIB_DISABLED)) | ||
1325 | return; | ||
1326 | |||
1013 | if ((data->state == IWL_CHAIN_NOISE_ALIVE) && | 1327 | if ((data->state == IWL_CHAIN_NOISE_ALIVE) && |
1014 | iwl_is_any_associated(priv)) { | 1328 | iwl_is_any_associated(priv)) { |
1015 | struct iwl_calib_chain_noise_reset_cmd cmd; | 1329 | struct iwl_calib_chain_noise_reset_cmd cmd; |
@@ -1162,8 +1476,7 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw, | |||
1162 | iwl_power_update_mode(priv, false); | 1476 | iwl_power_update_mode(priv, false); |
1163 | 1477 | ||
1164 | /* Enable RX differential gain and sensitivity calibrations */ | 1478 | /* Enable RX differential gain and sensitivity calibrations */ |
1165 | if (!priv->disable_chain_noise_cal) | 1479 | iwlagn_chain_noise_reset(priv); |
1166 | iwlagn_chain_noise_reset(priv); | ||
1167 | priv->start_calib = 1; | 1480 | priv->start_calib = 1; |
1168 | } | 1481 | } |
1169 | 1482 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c index c4175603864b..0119e7a7b78d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c | |||
@@ -34,6 +34,8 @@ | |||
34 | #include "iwl-agn.h" | 34 | #include "iwl-agn.h" |
35 | #include "iwl-trans.h" | 35 | #include "iwl-trans.h" |
36 | 36 | ||
37 | const u8 iwl_bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; | ||
38 | |||
37 | static int iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id) | 39 | static int iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id) |
38 | { | 40 | { |
39 | lockdep_assert_held(&priv->sta_lock); | 41 | lockdep_assert_held(&priv->sta_lock); |
@@ -170,6 +172,50 @@ int iwl_send_add_sta(struct iwl_priv *priv, | |||
170 | return cmd.handler_status; | 172 | return cmd.handler_status; |
171 | } | 173 | } |
172 | 174 | ||
175 | static bool iwl_is_channel_extension(struct iwl_priv *priv, | ||
176 | enum ieee80211_band band, | ||
177 | u16 channel, u8 extension_chan_offset) | ||
178 | { | ||
179 | const struct iwl_channel_info *ch_info; | ||
180 | |||
181 | ch_info = iwl_get_channel_info(priv, band, channel); | ||
182 | if (!is_channel_valid(ch_info)) | ||
183 | return false; | ||
184 | |||
185 | if (extension_chan_offset == IEEE80211_HT_PARAM_CHA_SEC_ABOVE) | ||
186 | return !(ch_info->ht40_extension_channel & | ||
187 | IEEE80211_CHAN_NO_HT40PLUS); | ||
188 | else if (extension_chan_offset == IEEE80211_HT_PARAM_CHA_SEC_BELOW) | ||
189 | return !(ch_info->ht40_extension_channel & | ||
190 | IEEE80211_CHAN_NO_HT40MINUS); | ||
191 | |||
192 | return false; | ||
193 | } | ||
194 | |||
195 | bool iwl_is_ht40_tx_allowed(struct iwl_priv *priv, | ||
196 | struct iwl_rxon_context *ctx, | ||
197 | struct ieee80211_sta_ht_cap *ht_cap) | ||
198 | { | ||
199 | if (!ctx->ht.enabled || !ctx->ht.is_40mhz) | ||
200 | return false; | ||
201 | |||
202 | /* | ||
203 | * We do not check for IEEE80211_HT_CAP_SUP_WIDTH_20_40 | ||
204 | * the bit will not set if it is pure 40MHz case | ||
205 | */ | ||
206 | if (ht_cap && !ht_cap->ht_supported) | ||
207 | return false; | ||
208 | |||
209 | #ifdef CONFIG_IWLWIFI_DEBUGFS | ||
210 | if (priv->disable_ht40) | ||
211 | return false; | ||
212 | #endif | ||
213 | |||
214 | return iwl_is_channel_extension(priv, priv->band, | ||
215 | le16_to_cpu(ctx->staging.channel), | ||
216 | ctx->ht.extension_chan_offset); | ||
217 | } | ||
218 | |||
173 | static void iwl_sta_calc_ht_flags(struct iwl_priv *priv, | 219 | static void iwl_sta_calc_ht_flags(struct iwl_priv *priv, |
174 | struct ieee80211_sta *sta, | 220 | struct ieee80211_sta *sta, |
175 | struct iwl_rxon_context *ctx, | 221 | struct iwl_rxon_context *ctx, |
@@ -581,6 +627,56 @@ void iwl_deactivate_station(struct iwl_priv *priv, const u8 sta_id, | |||
581 | spin_unlock_bh(&priv->sta_lock); | 627 | spin_unlock_bh(&priv->sta_lock); |
582 | } | 628 | } |
583 | 629 | ||
630 | static void iwl_sta_fill_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx, | ||
631 | u8 sta_id, struct iwl_link_quality_cmd *link_cmd) | ||
632 | { | ||
633 | int i, r; | ||
634 | u32 rate_flags = 0; | ||
635 | __le32 rate_n_flags; | ||
636 | |||
637 | lockdep_assert_held(&priv->mutex); | ||
638 | |||
639 | memset(link_cmd, 0, sizeof(*link_cmd)); | ||
640 | |||
641 | /* Set up the rate scaling to start at selected rate, fall back | ||
642 | * all the way down to 1M in IEEE order, and then spin on 1M */ | ||
643 | if (priv->band == IEEE80211_BAND_5GHZ) | ||
644 | r = IWL_RATE_6M_INDEX; | ||
645 | else if (ctx && ctx->vif && ctx->vif->p2p) | ||
646 | r = IWL_RATE_6M_INDEX; | ||
647 | else | ||
648 | r = IWL_RATE_1M_INDEX; | ||
649 | |||
650 | if (r >= IWL_FIRST_CCK_RATE && r <= IWL_LAST_CCK_RATE) | ||
651 | rate_flags |= RATE_MCS_CCK_MSK; | ||
652 | |||
653 | rate_flags |= first_antenna(priv->hw_params.valid_tx_ant) << | ||
654 | RATE_MCS_ANT_POS; | ||
655 | rate_n_flags = iwl_hw_set_rate_n_flags(iwl_rates[r].plcp, rate_flags); | ||
656 | for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) | ||
657 | link_cmd->rs_table[i].rate_n_flags = rate_n_flags; | ||
658 | |||
659 | link_cmd->general_params.single_stream_ant_msk = | ||
660 | first_antenna(priv->hw_params.valid_tx_ant); | ||
661 | |||
662 | link_cmd->general_params.dual_stream_ant_msk = | ||
663 | priv->hw_params.valid_tx_ant & | ||
664 | ~first_antenna(priv->hw_params.valid_tx_ant); | ||
665 | if (!link_cmd->general_params.dual_stream_ant_msk) { | ||
666 | link_cmd->general_params.dual_stream_ant_msk = ANT_AB; | ||
667 | } else if (num_of_ant(priv->hw_params.valid_tx_ant) == 2) { | ||
668 | link_cmd->general_params.dual_stream_ant_msk = | ||
669 | priv->hw_params.valid_tx_ant; | ||
670 | } | ||
671 | |||
672 | link_cmd->agg_params.agg_dis_start_th = | ||
673 | LINK_QUAL_AGG_DISABLE_START_DEF; | ||
674 | link_cmd->agg_params.agg_time_limit = | ||
675 | cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF); | ||
676 | |||
677 | link_cmd->sta_id = sta_id; | ||
678 | } | ||
679 | |||
584 | /** | 680 | /** |
585 | * iwl_clear_ucode_stations - clear ucode station table bits | 681 | * iwl_clear_ucode_stations - clear ucode station table bits |
586 | * | 682 | * |
@@ -841,56 +937,6 @@ int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx, | |||
841 | } | 937 | } |
842 | 938 | ||
843 | 939 | ||
844 | void iwl_sta_fill_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx, | ||
845 | u8 sta_id, struct iwl_link_quality_cmd *link_cmd) | ||
846 | { | ||
847 | int i, r; | ||
848 | u32 rate_flags = 0; | ||
849 | __le32 rate_n_flags; | ||
850 | |||
851 | lockdep_assert_held(&priv->mutex); | ||
852 | |||
853 | memset(link_cmd, 0, sizeof(*link_cmd)); | ||
854 | |||
855 | /* Set up the rate scaling to start at selected rate, fall back | ||
856 | * all the way down to 1M in IEEE order, and then spin on 1M */ | ||
857 | if (priv->band == IEEE80211_BAND_5GHZ) | ||
858 | r = IWL_RATE_6M_INDEX; | ||
859 | else if (ctx && ctx->vif && ctx->vif->p2p) | ||
860 | r = IWL_RATE_6M_INDEX; | ||
861 | else | ||
862 | r = IWL_RATE_1M_INDEX; | ||
863 | |||
864 | if (r >= IWL_FIRST_CCK_RATE && r <= IWL_LAST_CCK_RATE) | ||
865 | rate_flags |= RATE_MCS_CCK_MSK; | ||
866 | |||
867 | rate_flags |= first_antenna(hw_params(priv).valid_tx_ant) << | ||
868 | RATE_MCS_ANT_POS; | ||
869 | rate_n_flags = iwl_hw_set_rate_n_flags(iwl_rates[r].plcp, rate_flags); | ||
870 | for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) | ||
871 | link_cmd->rs_table[i].rate_n_flags = rate_n_flags; | ||
872 | |||
873 | link_cmd->general_params.single_stream_ant_msk = | ||
874 | first_antenna(hw_params(priv).valid_tx_ant); | ||
875 | |||
876 | link_cmd->general_params.dual_stream_ant_msk = | ||
877 | hw_params(priv).valid_tx_ant & | ||
878 | ~first_antenna(hw_params(priv).valid_tx_ant); | ||
879 | if (!link_cmd->general_params.dual_stream_ant_msk) { | ||
880 | link_cmd->general_params.dual_stream_ant_msk = ANT_AB; | ||
881 | } else if (num_of_ant(hw_params(priv).valid_tx_ant) == 2) { | ||
882 | link_cmd->general_params.dual_stream_ant_msk = | ||
883 | hw_params(priv).valid_tx_ant; | ||
884 | } | ||
885 | |||
886 | link_cmd->agg_params.agg_dis_start_th = | ||
887 | LINK_QUAL_AGG_DISABLE_START_DEF; | ||
888 | link_cmd->agg_params.agg_time_limit = | ||
889 | cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF); | ||
890 | |||
891 | link_cmd->sta_id = sta_id; | ||
892 | } | ||
893 | |||
894 | static struct iwl_link_quality_cmd * | 940 | static struct iwl_link_quality_cmd * |
895 | iwl_sta_alloc_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx, | 941 | iwl_sta_alloc_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx, |
896 | u8 sta_id) | 942 | u8 sta_id) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index 697f2032bfd6..ad21b5ddf59d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c | |||
@@ -208,10 +208,10 @@ static void iwlagn_tx_cmd_build_rate(struct iwl_priv *priv, | |||
208 | priv->bt_full_concurrent) { | 208 | priv->bt_full_concurrent) { |
209 | /* operated as 1x1 in full concurrency mode */ | 209 | /* operated as 1x1 in full concurrency mode */ |
210 | priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant, | 210 | priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant, |
211 | first_antenna(hw_params(priv).valid_tx_ant)); | 211 | first_antenna(priv->hw_params.valid_tx_ant)); |
212 | } else | 212 | } else |
213 | priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant, | 213 | priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant, |
214 | hw_params(priv).valid_tx_ant); | 214 | priv->hw_params.valid_tx_ant); |
215 | rate_flags |= iwl_ant_idx_to_flags(priv->mgmt_tx_ant); | 215 | rate_flags |= iwl_ant_idx_to_flags(priv->mgmt_tx_ant); |
216 | 216 | ||
217 | /* Set the rate in the TX cmd */ | 217 | /* Set the rate in the TX cmd */ |
@@ -689,7 +689,7 @@ int iwlagn_tx_agg_oper(struct iwl_priv *priv, struct ieee80211_vif *vif, | |||
689 | sta_priv->max_agg_bufsize = | 689 | sta_priv->max_agg_bufsize = |
690 | min(sta_priv->max_agg_bufsize, buf_size); | 690 | min(sta_priv->max_agg_bufsize, buf_size); |
691 | 691 | ||
692 | if (hw_params(priv).use_rts_for_aggregation) { | 692 | if (priv->hw_params.use_rts_for_aggregation) { |
693 | /* | 693 | /* |
694 | * switch to RTS/CTS if it is the prefer protection | 694 | * switch to RTS/CTS if it is the prefer protection |
695 | * method for HT traffic | 695 | * method for HT traffic |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 22c953d65be5..7db39866bdc4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -180,7 +180,7 @@ int iwlagn_send_beacon_cmd(struct iwl_priv *priv) | |||
180 | rate = info->control.rates[0].idx; | 180 | rate = info->control.rates[0].idx; |
181 | 181 | ||
182 | priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant, | 182 | priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant, |
183 | hw_params(priv).valid_tx_ant); | 183 | priv->hw_params.valid_tx_ant); |
184 | rate_flags = iwl_ant_idx_to_flags(priv->mgmt_tx_ant); | 184 | rate_flags = iwl_ant_idx_to_flags(priv->mgmt_tx_ant); |
185 | 185 | ||
186 | /* In mac80211, rates for 5 GHz start at 0 */ | 186 | /* In mac80211, rates for 5 GHz start at 0 */ |
@@ -289,6 +289,25 @@ out: | |||
289 | mutex_unlock(&priv->mutex); | 289 | mutex_unlock(&priv->mutex); |
290 | } | 290 | } |
291 | 291 | ||
292 | int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags, bool clear) | ||
293 | { | ||
294 | struct iwl_statistics_cmd statistics_cmd = { | ||
295 | .configuration_flags = | ||
296 | clear ? IWL_STATS_CONF_CLEAR_STATS : 0, | ||
297 | }; | ||
298 | |||
299 | if (flags & CMD_ASYNC) | ||
300 | return iwl_dvm_send_cmd_pdu(priv, REPLY_STATISTICS_CMD, | ||
301 | CMD_ASYNC, | ||
302 | sizeof(struct iwl_statistics_cmd), | ||
303 | &statistics_cmd); | ||
304 | else | ||
305 | return iwl_dvm_send_cmd_pdu(priv, REPLY_STATISTICS_CMD, | ||
306 | CMD_SYNC, | ||
307 | sizeof(struct iwl_statistics_cmd), | ||
308 | &statistics_cmd); | ||
309 | } | ||
310 | |||
292 | /** | 311 | /** |
293 | * iwl_bg_statistics_periodic - Timer callback to queue statistics | 312 | * iwl_bg_statistics_periodic - Timer callback to queue statistics |
294 | * | 313 | * |
@@ -578,7 +597,7 @@ static const u8 iwlagn_pan_queue_to_ac[] = { | |||
578 | IEEE80211_AC_VO, | 597 | IEEE80211_AC_VO, |
579 | }; | 598 | }; |
580 | 599 | ||
581 | static void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags) | 600 | void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags) |
582 | { | 601 | { |
583 | int i; | 602 | int i; |
584 | 603 | ||
@@ -645,7 +664,7 @@ static void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags) | |||
645 | BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2); | 664 | BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2); |
646 | } | 665 | } |
647 | 666 | ||
648 | static void iwl_rf_kill_ct_config(struct iwl_priv *priv) | 667 | void iwl_rf_kill_ct_config(struct iwl_priv *priv) |
649 | { | 668 | { |
650 | struct iwl_ct_kill_config cmd; | 669 | struct iwl_ct_kill_config cmd; |
651 | struct iwl_ct_kill_throttling_config adv_cmd; | 670 | struct iwl_ct_kill_throttling_config adv_cmd; |
@@ -658,9 +677,9 @@ static void iwl_rf_kill_ct_config(struct iwl_priv *priv) | |||
658 | 677 | ||
659 | if (cfg(priv)->base_params->support_ct_kill_exit) { | 678 | if (cfg(priv)->base_params->support_ct_kill_exit) { |
660 | adv_cmd.critical_temperature_enter = | 679 | adv_cmd.critical_temperature_enter = |
661 | cpu_to_le32(hw_params(priv).ct_kill_threshold); | 680 | cpu_to_le32(priv->hw_params.ct_kill_threshold); |
662 | adv_cmd.critical_temperature_exit = | 681 | adv_cmd.critical_temperature_exit = |
663 | cpu_to_le32(hw_params(priv).ct_kill_exit_threshold); | 682 | cpu_to_le32(priv->hw_params.ct_kill_exit_threshold); |
664 | 683 | ||
665 | ret = iwl_dvm_send_cmd_pdu(priv, | 684 | ret = iwl_dvm_send_cmd_pdu(priv, |
666 | REPLY_CT_KILL_CONFIG_CMD, | 685 | REPLY_CT_KILL_CONFIG_CMD, |
@@ -671,11 +690,11 @@ static void iwl_rf_kill_ct_config(struct iwl_priv *priv) | |||
671 | IWL_DEBUG_INFO(priv, "REPLY_CT_KILL_CONFIG_CMD " | 690 | IWL_DEBUG_INFO(priv, "REPLY_CT_KILL_CONFIG_CMD " |
672 | "succeeded, critical temperature enter is %d," | 691 | "succeeded, critical temperature enter is %d," |
673 | "exit is %d\n", | 692 | "exit is %d\n", |
674 | hw_params(priv).ct_kill_threshold, | 693 | priv->hw_params.ct_kill_threshold, |
675 | hw_params(priv).ct_kill_exit_threshold); | 694 | priv->hw_params.ct_kill_exit_threshold); |
676 | } else { | 695 | } else { |
677 | cmd.critical_temperature_R = | 696 | cmd.critical_temperature_R = |
678 | cpu_to_le32(hw_params(priv).ct_kill_threshold); | 697 | cpu_to_le32(priv->hw_params.ct_kill_threshold); |
679 | 698 | ||
680 | ret = iwl_dvm_send_cmd_pdu(priv, | 699 | ret = iwl_dvm_send_cmd_pdu(priv, |
681 | REPLY_CT_KILL_CONFIG_CMD, | 700 | REPLY_CT_KILL_CONFIG_CMD, |
@@ -686,7 +705,7 @@ static void iwl_rf_kill_ct_config(struct iwl_priv *priv) | |||
686 | IWL_DEBUG_INFO(priv, "REPLY_CT_KILL_CONFIG_CMD " | 705 | IWL_DEBUG_INFO(priv, "REPLY_CT_KILL_CONFIG_CMD " |
687 | "succeeded, " | 706 | "succeeded, " |
688 | "critical temperature is %d\n", | 707 | "critical temperature is %d\n", |
689 | hw_params(priv).ct_kill_threshold); | 708 | priv->hw_params.ct_kill_threshold); |
690 | } | 709 | } |
691 | } | 710 | } |
692 | 711 | ||
@@ -726,6 +745,29 @@ static int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant) | |||
726 | } | 745 | } |
727 | } | 746 | } |
728 | 747 | ||
748 | void iwl_send_bt_config(struct iwl_priv *priv) | ||
749 | { | ||
750 | struct iwl_bt_cmd bt_cmd = { | ||
751 | .lead_time = BT_LEAD_TIME_DEF, | ||
752 | .max_kill = BT_MAX_KILL_DEF, | ||
753 | .kill_ack_mask = 0, | ||
754 | .kill_cts_mask = 0, | ||
755 | }; | ||
756 | |||
757 | if (!iwlagn_mod_params.bt_coex_active) | ||
758 | bt_cmd.flags = BT_COEX_DISABLE; | ||
759 | else | ||
760 | bt_cmd.flags = BT_COEX_ENABLE; | ||
761 | |||
762 | priv->bt_enable_flag = bt_cmd.flags; | ||
763 | IWL_DEBUG_INFO(priv, "BT coex %s\n", | ||
764 | (bt_cmd.flags == BT_COEX_DISABLE) ? "disable" : "active"); | ||
765 | |||
766 | if (iwl_dvm_send_cmd_pdu(priv, REPLY_BT_CONFIG, | ||
767 | CMD_SYNC, sizeof(struct iwl_bt_cmd), &bt_cmd)) | ||
768 | IWL_ERR(priv, "failed to send BT Coex Config\n"); | ||
769 | } | ||
770 | |||
729 | /** | 771 | /** |
730 | * iwl_alive_start - called after REPLY_ALIVE notification received | 772 | * iwl_alive_start - called after REPLY_ALIVE notification received |
731 | * from protocol/runtime uCode (initialization uCode's | 773 | * from protocol/runtime uCode (initialization uCode's |
@@ -741,9 +783,6 @@ int iwl_alive_start(struct iwl_priv *priv) | |||
741 | /* After the ALIVE response, we can send host commands to the uCode */ | 783 | /* After the ALIVE response, we can send host commands to the uCode */ |
742 | set_bit(STATUS_ALIVE, &priv->status); | 784 | set_bit(STATUS_ALIVE, &priv->status); |
743 | 785 | ||
744 | /* Enable watchdog to monitor the driver tx queues */ | ||
745 | iwl_setup_watchdog(priv); | ||
746 | |||
747 | if (iwl_is_rfkill(priv)) | 786 | if (iwl_is_rfkill(priv)) |
748 | return -ERFKILL; | 787 | return -ERFKILL; |
749 | 788 | ||
@@ -793,10 +832,8 @@ int iwl_alive_start(struct iwl_priv *priv) | |||
793 | 832 | ||
794 | ieee80211_wake_queues(priv->hw); | 833 | ieee80211_wake_queues(priv->hw); |
795 | 834 | ||
796 | priv->active_rate = IWL_RATES_MASK; | ||
797 | |||
798 | /* Configure Tx antenna selection based on H/W config */ | 835 | /* Configure Tx antenna selection based on H/W config */ |
799 | iwlagn_send_tx_ant_config(priv, hw_params(priv).valid_tx_ant); | 836 | iwlagn_send_tx_ant_config(priv, priv->hw_params.valid_tx_ant); |
800 | 837 | ||
801 | if (iwl_is_associated_ctx(ctx) && !priv->wowlan) { | 838 | if (iwl_is_associated_ctx(ctx) && !priv->wowlan) { |
802 | struct iwl_rxon_cmd *active_rxon = | 839 | struct iwl_rxon_cmd *active_rxon = |
@@ -887,10 +924,6 @@ void iwl_down(struct iwl_priv *priv) | |||
887 | exit_pending = | 924 | exit_pending = |
888 | test_and_set_bit(STATUS_EXIT_PENDING, &priv->status); | 925 | test_and_set_bit(STATUS_EXIT_PENDING, &priv->status); |
889 | 926 | ||
890 | /* Stop TX queues watchdog. We need to have STATUS_EXIT_PENDING bit set | ||
891 | * to prevent rearm timer */ | ||
892 | del_timer_sync(&priv->watchdog); | ||
893 | |||
894 | iwl_clear_ucode_stations(priv, NULL); | 927 | iwl_clear_ucode_stations(priv, NULL); |
895 | iwl_dealloc_bcast_stations(priv); | 928 | iwl_dealloc_bcast_stations(priv); |
896 | iwl_clear_driver_stations(priv); | 929 | iwl_clear_driver_stations(priv); |
@@ -1067,7 +1100,7 @@ static void iwlagn_disable_roc_work(struct work_struct *work) | |||
1067 | * | 1100 | * |
1068 | *****************************************************************************/ | 1101 | *****************************************************************************/ |
1069 | 1102 | ||
1070 | static void iwl_setup_deferred_work(struct iwl_priv *priv) | 1103 | void iwl_setup_deferred_work(struct iwl_priv *priv) |
1071 | { | 1104 | { |
1072 | priv->workqueue = create_singlethread_workqueue(DRV_NAME); | 1105 | priv->workqueue = create_singlethread_workqueue(DRV_NAME); |
1073 | 1106 | ||
@@ -1092,10 +1125,6 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv) | |||
1092 | init_timer(&priv->ucode_trace); | 1125 | init_timer(&priv->ucode_trace); |
1093 | priv->ucode_trace.data = (unsigned long)priv; | 1126 | priv->ucode_trace.data = (unsigned long)priv; |
1094 | priv->ucode_trace.function = iwl_bg_ucode_trace; | 1127 | priv->ucode_trace.function = iwl_bg_ucode_trace; |
1095 | |||
1096 | init_timer(&priv->watchdog); | ||
1097 | priv->watchdog.data = (unsigned long)priv; | ||
1098 | priv->watchdog.function = iwl_bg_watchdog; | ||
1099 | } | 1128 | } |
1100 | 1129 | ||
1101 | void iwl_cancel_deferred_work(struct iwl_priv *priv) | 1130 | void iwl_cancel_deferred_work(struct iwl_priv *priv) |
@@ -1143,8 +1172,8 @@ static void iwl_init_ht_hw_capab(const struct iwl_priv *priv, | |||
1143 | enum ieee80211_band band) | 1172 | enum ieee80211_band band) |
1144 | { | 1173 | { |
1145 | u16 max_bit_rate = 0; | 1174 | u16 max_bit_rate = 0; |
1146 | u8 rx_chains_num = hw_params(priv).rx_chains_num; | 1175 | u8 rx_chains_num = priv->hw_params.rx_chains_num; |
1147 | u8 tx_chains_num = hw_params(priv).tx_chains_num; | 1176 | u8 tx_chains_num = priv->hw_params.tx_chains_num; |
1148 | 1177 | ||
1149 | ht_info->cap = 0; | 1178 | ht_info->cap = 0; |
1150 | memset(&ht_info->mcs, 0, sizeof(ht_info->mcs)); | 1179 | memset(&ht_info->mcs, 0, sizeof(ht_info->mcs)); |
@@ -1156,7 +1185,7 @@ static void iwl_init_ht_hw_capab(const struct iwl_priv *priv, | |||
1156 | ht_info->cap |= IEEE80211_HT_CAP_GRN_FLD; | 1185 | ht_info->cap |= IEEE80211_HT_CAP_GRN_FLD; |
1157 | ht_info->cap |= IEEE80211_HT_CAP_SGI_20; | 1186 | ht_info->cap |= IEEE80211_HT_CAP_SGI_20; |
1158 | max_bit_rate = MAX_BIT_RATE_20_MHZ; | 1187 | max_bit_rate = MAX_BIT_RATE_20_MHZ; |
1159 | if (hw_params(priv).ht40_channel & BIT(band)) { | 1188 | if (priv->hw_params.ht40_channel & BIT(band)) { |
1160 | ht_info->cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40; | 1189 | ht_info->cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40; |
1161 | ht_info->cap |= IEEE80211_HT_CAP_SGI_40; | 1190 | ht_info->cap |= IEEE80211_HT_CAP_SGI_40; |
1162 | ht_info->mcs.rx_mask[4] = 0x01; | 1191 | ht_info->mcs.rx_mask[4] = 0x01; |
@@ -1228,7 +1257,7 @@ static int iwl_init_geos(struct iwl_priv *priv) | |||
1228 | sband->bitrates = &rates[IWL_FIRST_OFDM_RATE]; | 1257 | sband->bitrates = &rates[IWL_FIRST_OFDM_RATE]; |
1229 | sband->n_bitrates = IWL_RATE_COUNT_LEGACY - IWL_FIRST_OFDM_RATE; | 1258 | sband->n_bitrates = IWL_RATE_COUNT_LEGACY - IWL_FIRST_OFDM_RATE; |
1230 | 1259 | ||
1231 | if (hw_params(priv).sku & EEPROM_SKU_CAP_11N_ENABLE) | 1260 | if (priv->hw_params.sku & EEPROM_SKU_CAP_11N_ENABLE) |
1232 | iwl_init_ht_hw_capab(priv, &sband->ht_cap, | 1261 | iwl_init_ht_hw_capab(priv, &sband->ht_cap, |
1233 | IEEE80211_BAND_5GHZ); | 1262 | IEEE80211_BAND_5GHZ); |
1234 | 1263 | ||
@@ -1238,7 +1267,7 @@ static int iwl_init_geos(struct iwl_priv *priv) | |||
1238 | sband->bitrates = rates; | 1267 | sband->bitrates = rates; |
1239 | sband->n_bitrates = IWL_RATE_COUNT_LEGACY; | 1268 | sband->n_bitrates = IWL_RATE_COUNT_LEGACY; |
1240 | 1269 | ||
1241 | if (hw_params(priv).sku & EEPROM_SKU_CAP_11N_ENABLE) | 1270 | if (priv->hw_params.sku & EEPROM_SKU_CAP_11N_ENABLE) |
1242 | iwl_init_ht_hw_capab(priv, &sband->ht_cap, | 1271 | iwl_init_ht_hw_capab(priv, &sband->ht_cap, |
1243 | IEEE80211_BAND_2GHZ); | 1272 | IEEE80211_BAND_2GHZ); |
1244 | 1273 | ||
@@ -1293,11 +1322,11 @@ static int iwl_init_geos(struct iwl_priv *priv) | |||
1293 | priv->tx_power_next = max_tx_power; | 1322 | priv->tx_power_next = max_tx_power; |
1294 | 1323 | ||
1295 | if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) && | 1324 | if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) && |
1296 | hw_params(priv).sku & EEPROM_SKU_CAP_BAND_52GHZ) { | 1325 | priv->hw_params.sku & EEPROM_SKU_CAP_BAND_52GHZ) { |
1297 | IWL_INFO(priv, "Incorrectly detected BG card as ABG. " | 1326 | IWL_INFO(priv, "Incorrectly detected BG card as ABG. " |
1298 | "Please send your %s to maintainer.\n", | 1327 | "Please send your %s to maintainer.\n", |
1299 | trans(priv)->hw_id_str); | 1328 | trans(priv)->hw_id_str); |
1300 | hw_params(priv).sku &= ~EEPROM_SKU_CAP_BAND_52GHZ; | 1329 | priv->hw_params.sku &= ~EEPROM_SKU_CAP_BAND_52GHZ; |
1301 | } | 1330 | } |
1302 | 1331 | ||
1303 | IWL_INFO(priv, "Tunable channels: %d 802.11bg, %d 802.11a channels\n", | 1332 | IWL_INFO(priv, "Tunable channels: %d 802.11bg, %d 802.11a channels\n", |
@@ -1319,7 +1348,7 @@ static void iwl_free_geos(struct iwl_priv *priv) | |||
1319 | clear_bit(STATUS_GEO_CONFIGURED, &priv->status); | 1348 | clear_bit(STATUS_GEO_CONFIGURED, &priv->status); |
1320 | } | 1349 | } |
1321 | 1350 | ||
1322 | static int iwl_init_drv(struct iwl_priv *priv) | 1351 | int iwl_init_drv(struct iwl_priv *priv) |
1323 | { | 1352 | { |
1324 | int ret; | 1353 | int ret; |
1325 | 1354 | ||
@@ -1343,12 +1372,6 @@ static int iwl_init_drv(struct iwl_priv *priv) | |||
1343 | 1372 | ||
1344 | priv->ucode_owner = IWL_OWNERSHIP_DRIVER; | 1373 | priv->ucode_owner = IWL_OWNERSHIP_DRIVER; |
1345 | 1374 | ||
1346 | /* initialize force reset */ | ||
1347 | priv->force_reset[IWL_RF_RESET].reset_duration = | ||
1348 | IWL_DELAY_NEXT_FORCE_RF_RESET; | ||
1349 | priv->force_reset[IWL_FW_RESET].reset_duration = | ||
1350 | IWL_DELAY_NEXT_FORCE_FW_RELOAD; | ||
1351 | |||
1352 | priv->rx_statistics_jiffies = jiffies; | 1375 | priv->rx_statistics_jiffies = jiffies; |
1353 | 1376 | ||
1354 | /* Choose which receivers/antennas to use */ | 1377 | /* Choose which receivers/antennas to use */ |
@@ -1388,7 +1411,7 @@ err: | |||
1388 | return ret; | 1411 | return ret; |
1389 | } | 1412 | } |
1390 | 1413 | ||
1391 | static void iwl_uninit_drv(struct iwl_priv *priv) | 1414 | void iwl_uninit_drv(struct iwl_priv *priv) |
1392 | { | 1415 | { |
1393 | iwl_free_geos(priv); | 1416 | iwl_free_geos(priv); |
1394 | iwl_free_channel_map(priv); | 1417 | iwl_free_channel_map(priv); |
@@ -1401,35 +1424,22 @@ static void iwl_uninit_drv(struct iwl_priv *priv) | |||
1401 | #endif | 1424 | #endif |
1402 | } | 1425 | } |
1403 | 1426 | ||
1404 | /* Size of one Rx buffer in host DRAM */ | 1427 | void iwl_set_hw_params(struct iwl_priv *priv) |
1405 | #define IWL_RX_BUF_SIZE_4K (4 * 1024) | ||
1406 | #define IWL_RX_BUF_SIZE_8K (8 * 1024) | ||
1407 | |||
1408 | static void iwl_set_hw_params(struct iwl_priv *priv) | ||
1409 | { | 1428 | { |
1410 | if (cfg(priv)->ht_params) | 1429 | if (cfg(priv)->ht_params) |
1411 | hw_params(priv).use_rts_for_aggregation = | 1430 | priv->hw_params.use_rts_for_aggregation = |
1412 | cfg(priv)->ht_params->use_rts_for_aggregation; | 1431 | cfg(priv)->ht_params->use_rts_for_aggregation; |
1413 | 1432 | ||
1414 | if (iwlagn_mod_params.amsdu_size_8K) | ||
1415 | hw_params(priv).rx_page_order = | ||
1416 | get_order(IWL_RX_BUF_SIZE_8K); | ||
1417 | else | ||
1418 | hw_params(priv).rx_page_order = | ||
1419 | get_order(IWL_RX_BUF_SIZE_4K); | ||
1420 | |||
1421 | if (iwlagn_mod_params.disable_11n & IWL_DISABLE_HT_ALL) | 1433 | if (iwlagn_mod_params.disable_11n & IWL_DISABLE_HT_ALL) |
1422 | hw_params(priv).sku &= ~EEPROM_SKU_CAP_11N_ENABLE; | 1434 | priv->hw_params.sku &= ~EEPROM_SKU_CAP_11N_ENABLE; |
1423 | |||
1424 | hw_params(priv).wd_timeout = cfg(priv)->base_params->wd_timeout; | ||
1425 | 1435 | ||
1426 | /* Device-specific setup */ | 1436 | /* Device-specific setup */ |
1427 | cfg(priv)->lib->set_hw_params(priv); | 1437 | priv->lib->set_hw_params(priv); |
1428 | } | 1438 | } |
1429 | 1439 | ||
1430 | 1440 | ||
1431 | 1441 | ||
1432 | static void iwl_debug_config(struct iwl_priv *priv) | 1442 | void iwl_debug_config(struct iwl_priv *priv) |
1433 | { | 1443 | { |
1434 | dev_printk(KERN_INFO, trans(priv)->dev, "CONFIG_IWLWIFI_DEBUG " | 1444 | dev_printk(KERN_INFO, trans(priv)->dev, "CONFIG_IWLWIFI_DEBUG " |
1435 | #ifdef CONFIG_IWLWIFI_DEBUG | 1445 | #ifdef CONFIG_IWLWIFI_DEBUG |
@@ -1501,6 +1511,42 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, | |||
1501 | priv->shrd = trans->shrd; | 1511 | priv->shrd = trans->shrd; |
1502 | priv->fw = fw; | 1512 | priv->fw = fw; |
1503 | 1513 | ||
1514 | switch (cfg(priv)->device_family) { | ||
1515 | case IWL_DEVICE_FAMILY_1000: | ||
1516 | case IWL_DEVICE_FAMILY_100: | ||
1517 | priv->lib = &iwl1000_lib; | ||
1518 | break; | ||
1519 | case IWL_DEVICE_FAMILY_2000: | ||
1520 | case IWL_DEVICE_FAMILY_105: | ||
1521 | priv->lib = &iwl2000_lib; | ||
1522 | break; | ||
1523 | case IWL_DEVICE_FAMILY_2030: | ||
1524 | case IWL_DEVICE_FAMILY_135: | ||
1525 | priv->lib = &iwl2030_lib; | ||
1526 | break; | ||
1527 | case IWL_DEVICE_FAMILY_5000: | ||
1528 | priv->lib = &iwl5000_lib; | ||
1529 | break; | ||
1530 | case IWL_DEVICE_FAMILY_5150: | ||
1531 | priv->lib = &iwl5150_lib; | ||
1532 | break; | ||
1533 | case IWL_DEVICE_FAMILY_6000: | ||
1534 | case IWL_DEVICE_FAMILY_6005: | ||
1535 | case IWL_DEVICE_FAMILY_6000i: | ||
1536 | case IWL_DEVICE_FAMILY_6050: | ||
1537 | case IWL_DEVICE_FAMILY_6150: | ||
1538 | priv->lib = &iwl6000_lib; | ||
1539 | break; | ||
1540 | case IWL_DEVICE_FAMILY_6030: | ||
1541 | priv->lib = &iwl6030_lib; | ||
1542 | break; | ||
1543 | default: | ||
1544 | break; | ||
1545 | } | ||
1546 | |||
1547 | if (WARN_ON(!priv->lib)) | ||
1548 | goto out_free_traffic_mem; | ||
1549 | |||
1504 | /* | 1550 | /* |
1505 | * Populate the state variables that the transport layer needs | 1551 | * Populate the state variables that the transport layer needs |
1506 | * to know about. | 1552 | * to know about. |
@@ -1508,11 +1554,18 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, | |||
1508 | trans_cfg.op_mode = op_mode; | 1554 | trans_cfg.op_mode = op_mode; |
1509 | trans_cfg.no_reclaim_cmds = no_reclaim_cmds; | 1555 | trans_cfg.no_reclaim_cmds = no_reclaim_cmds; |
1510 | trans_cfg.n_no_reclaim_cmds = ARRAY_SIZE(no_reclaim_cmds); | 1556 | trans_cfg.n_no_reclaim_cmds = ARRAY_SIZE(no_reclaim_cmds); |
1557 | trans_cfg.rx_buf_size_8k = iwlagn_mod_params.amsdu_size_8K; | ||
1558 | if (!iwlagn_mod_params.wd_disable) | ||
1559 | trans_cfg.queue_watchdog_timeout = | ||
1560 | cfg(priv)->base_params->wd_timeout; | ||
1561 | else | ||
1562 | trans_cfg.queue_watchdog_timeout = IWL_WATCHHDOG_DISABLED; | ||
1563 | trans_cfg.command_names = iwl_dvm_cmd_strings; | ||
1511 | 1564 | ||
1512 | ucode_flags = fw->ucode_capa.flags; | 1565 | ucode_flags = fw->ucode_capa.flags; |
1513 | 1566 | ||
1514 | #ifndef CONFIG_IWLWIFI_P2P | 1567 | #ifndef CONFIG_IWLWIFI_P2P |
1515 | ucode_flags &= ~IWL_UCODE_TLV_FLAGS_PAN; | 1568 | ucode_flags &= ~IWL_UCODE_TLV_FLAGS_P2P; |
1516 | #endif | 1569 | #endif |
1517 | 1570 | ||
1518 | if (ucode_flags & IWL_UCODE_TLV_FLAGS_PAN) { | 1571 | if (ucode_flags & IWL_UCODE_TLV_FLAGS_PAN) { |
@@ -1574,11 +1627,8 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, | |||
1574 | if (iwl_trans_start_hw(trans(priv))) | 1627 | if (iwl_trans_start_hw(trans(priv))) |
1575 | goto out_free_traffic_mem; | 1628 | goto out_free_traffic_mem; |
1576 | 1629 | ||
1577 | /***************** | ||
1578 | * 3. Read EEPROM | ||
1579 | *****************/ | ||
1580 | /* Read the EEPROM */ | 1630 | /* Read the EEPROM */ |
1581 | if (iwl_eeprom_init(trans(priv), trans(priv)->hw_rev)) { | 1631 | if (iwl_eeprom_init(priv, trans(priv)->hw_rev)) { |
1582 | IWL_ERR(priv, "Unable to init EEPROM\n"); | 1632 | IWL_ERR(priv, "Unable to init EEPROM\n"); |
1583 | goto out_free_traffic_mem; | 1633 | goto out_free_traffic_mem; |
1584 | } | 1634 | } |
@@ -1592,11 +1642,11 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, | |||
1592 | goto out_free_eeprom; | 1642 | goto out_free_eeprom; |
1593 | 1643 | ||
1594 | /* extract MAC Address */ | 1644 | /* extract MAC Address */ |
1595 | iwl_eeprom_get_mac(priv->shrd, priv->addresses[0].addr); | 1645 | iwl_eeprom_get_mac(priv, priv->addresses[0].addr); |
1596 | IWL_DEBUG_INFO(priv, "MAC address: %pM\n", priv->addresses[0].addr); | 1646 | IWL_DEBUG_INFO(priv, "MAC address: %pM\n", priv->addresses[0].addr); |
1597 | priv->hw->wiphy->addresses = priv->addresses; | 1647 | priv->hw->wiphy->addresses = priv->addresses; |
1598 | priv->hw->wiphy->n_addresses = 1; | 1648 | priv->hw->wiphy->n_addresses = 1; |
1599 | num_mac = iwl_eeprom_query16(priv->shrd, EEPROM_NUM_MAC_ADDRESS); | 1649 | num_mac = iwl_eeprom_query16(priv, EEPROM_NUM_MAC_ADDRESS); |
1600 | if (num_mac > 1) { | 1650 | if (num_mac > 1) { |
1601 | memcpy(priv->addresses[1].addr, priv->addresses[0].addr, | 1651 | memcpy(priv->addresses[1].addr, priv->addresses[0].addr, |
1602 | ETH_ALEN); | 1652 | ETH_ALEN); |
@@ -1609,7 +1659,7 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, | |||
1609 | ************************/ | 1659 | ************************/ |
1610 | iwl_set_hw_params(priv); | 1660 | iwl_set_hw_params(priv); |
1611 | 1661 | ||
1612 | if (!(hw_params(priv).sku & EEPROM_SKU_CAP_IPAN_ENABLE)) { | 1662 | if (!(priv->hw_params.sku & EEPROM_SKU_CAP_IPAN_ENABLE)) { |
1613 | IWL_DEBUG_INFO(priv, "Your EEPROM disabled PAN"); | 1663 | IWL_DEBUG_INFO(priv, "Your EEPROM disabled PAN"); |
1614 | ucode_flags &= ~IWL_UCODE_TLV_FLAGS_PAN; | 1664 | ucode_flags &= ~IWL_UCODE_TLV_FLAGS_PAN; |
1615 | /* | 1665 | /* |
@@ -1694,7 +1744,7 @@ out_destroy_workqueue: | |||
1694 | priv->workqueue = NULL; | 1744 | priv->workqueue = NULL; |
1695 | iwl_uninit_drv(priv); | 1745 | iwl_uninit_drv(priv); |
1696 | out_free_eeprom: | 1746 | out_free_eeprom: |
1697 | iwl_eeprom_free(priv->shrd); | 1747 | iwl_eeprom_free(priv); |
1698 | out_free_traffic_mem: | 1748 | out_free_traffic_mem: |
1699 | iwl_free_traffic_mem(priv); | 1749 | iwl_free_traffic_mem(priv); |
1700 | ieee80211_free_hw(priv->hw); | 1750 | ieee80211_free_hw(priv->hw); |
@@ -1703,7 +1753,7 @@ out: | |||
1703 | return op_mode; | 1753 | return op_mode; |
1704 | } | 1754 | } |
1705 | 1755 | ||
1706 | static void iwl_op_mode_dvm_stop(struct iwl_op_mode *op_mode) | 1756 | void iwl_op_mode_dvm_stop(struct iwl_op_mode *op_mode) |
1707 | { | 1757 | { |
1708 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); | 1758 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); |
1709 | 1759 | ||
@@ -1720,7 +1770,7 @@ static void iwl_op_mode_dvm_stop(struct iwl_op_mode *op_mode) | |||
1720 | priv->ucode_loaded = false; | 1770 | priv->ucode_loaded = false; |
1721 | iwl_trans_stop_device(trans(priv)); | 1771 | iwl_trans_stop_device(trans(priv)); |
1722 | 1772 | ||
1723 | iwl_eeprom_free(priv->shrd); | 1773 | iwl_eeprom_free(priv); |
1724 | 1774 | ||
1725 | /*netif_stop_queue(dev); */ | 1775 | /*netif_stop_queue(dev); */ |
1726 | flush_workqueue(priv->workqueue); | 1776 | flush_workqueue(priv->workqueue); |
@@ -1838,7 +1888,7 @@ static void iwl_dump_nic_error_log(struct iwl_priv *priv) | |||
1838 | if (ERROR_START_OFFSET <= table.valid * ERROR_ELEM_SIZE) { | 1888 | if (ERROR_START_OFFSET <= table.valid * ERROR_ELEM_SIZE) { |
1839 | IWL_ERR(trans, "Start IWL Error Log Dump:\n"); | 1889 | IWL_ERR(trans, "Start IWL Error Log Dump:\n"); |
1840 | IWL_ERR(trans, "Status: 0x%08lX, count: %d\n", | 1890 | IWL_ERR(trans, "Status: 0x%08lX, count: %d\n", |
1841 | priv->shrd->status, table.valid); | 1891 | priv->status, table.valid); |
1842 | } | 1892 | } |
1843 | 1893 | ||
1844 | trace_iwlwifi_dev_ucode_error(trans->dev, table.error_id, table.tsf_low, | 1894 | trace_iwlwifi_dev_ucode_error(trans->dev, table.error_id, table.tsf_low, |
@@ -2112,7 +2162,63 @@ int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log, | |||
2112 | return pos; | 2162 | return pos; |
2113 | } | 2163 | } |
2114 | 2164 | ||
2115 | static void iwl_nic_error(struct iwl_op_mode *op_mode) | 2165 | static void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand) |
2166 | { | ||
2167 | unsigned int reload_msec; | ||
2168 | unsigned long reload_jiffies; | ||
2169 | |||
2170 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
2171 | if (iwl_have_debug_level(IWL_DL_FW_ERRORS)) | ||
2172 | iwl_print_rx_config_cmd(priv, IWL_RXON_CTX_BSS); | ||
2173 | #endif | ||
2174 | |||
2175 | /* uCode is no longer loaded. */ | ||
2176 | priv->ucode_loaded = false; | ||
2177 | |||
2178 | /* Set the FW error flag -- cleared on iwl_down */ | ||
2179 | set_bit(STATUS_FW_ERROR, &priv->status); | ||
2180 | |||
2181 | iwl_abort_notification_waits(&priv->notif_wait); | ||
2182 | |||
2183 | /* Keep the restart process from trying to send host | ||
2184 | * commands by clearing the ready bit */ | ||
2185 | clear_bit(STATUS_READY, &priv->status); | ||
2186 | |||
2187 | wake_up(&trans(priv)->wait_command_queue); | ||
2188 | |||
2189 | if (!ondemand) { | ||
2190 | /* | ||
2191 | * If firmware keep reloading, then it indicate something | ||
2192 | * serious wrong and firmware having problem to recover | ||
2193 | * from it. Instead of keep trying which will fill the syslog | ||
2194 | * and hang the system, let's just stop it | ||
2195 | */ | ||
2196 | reload_jiffies = jiffies; | ||
2197 | reload_msec = jiffies_to_msecs((long) reload_jiffies - | ||
2198 | (long) priv->reload_jiffies); | ||
2199 | priv->reload_jiffies = reload_jiffies; | ||
2200 | if (reload_msec <= IWL_MIN_RELOAD_DURATION) { | ||
2201 | priv->reload_count++; | ||
2202 | if (priv->reload_count >= IWL_MAX_CONTINUE_RELOAD_CNT) { | ||
2203 | IWL_ERR(priv, "BUG_ON, Stop restarting\n"); | ||
2204 | return; | ||
2205 | } | ||
2206 | } else | ||
2207 | priv->reload_count = 0; | ||
2208 | } | ||
2209 | |||
2210 | if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) { | ||
2211 | if (iwlagn_mod_params.restart_fw) { | ||
2212 | IWL_DEBUG_FW_ERRORS(priv, | ||
2213 | "Restarting adapter due to uCode error.\n"); | ||
2214 | queue_work(priv->workqueue, &priv->restart); | ||
2215 | } else | ||
2216 | IWL_DEBUG_FW_ERRORS(priv, | ||
2217 | "Detected FW error, but not restarting\n"); | ||
2218 | } | ||
2219 | } | ||
2220 | |||
2221 | void iwl_nic_error(struct iwl_op_mode *op_mode) | ||
2116 | { | 2222 | { |
2117 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); | 2223 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); |
2118 | 2224 | ||
@@ -2125,7 +2231,7 @@ static void iwl_nic_error(struct iwl_op_mode *op_mode) | |||
2125 | iwlagn_fw_error(priv, false); | 2231 | iwlagn_fw_error(priv, false); |
2126 | } | 2232 | } |
2127 | 2233 | ||
2128 | static void iwl_cmd_queue_full(struct iwl_op_mode *op_mode) | 2234 | void iwl_cmd_queue_full(struct iwl_op_mode *op_mode) |
2129 | { | 2235 | { |
2130 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); | 2236 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); |
2131 | 2237 | ||
@@ -2135,14 +2241,22 @@ static void iwl_cmd_queue_full(struct iwl_op_mode *op_mode) | |||
2135 | } | 2241 | } |
2136 | } | 2242 | } |
2137 | 2243 | ||
2138 | static void iwl_nic_config(struct iwl_op_mode *op_mode) | 2244 | void iwl_nic_config(struct iwl_op_mode *op_mode) |
2139 | { | 2245 | { |
2140 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); | 2246 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); |
2141 | 2247 | ||
2142 | cfg(priv)->lib->nic_config(priv); | 2248 | priv->lib->nic_config(priv); |
2143 | } | 2249 | } |
2144 | 2250 | ||
2145 | static void iwl_stop_sw_queue(struct iwl_op_mode *op_mode, int queue) | 2251 | static void iwl_wimax_active(struct iwl_op_mode *op_mode) |
2252 | { | ||
2253 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); | ||
2254 | |||
2255 | clear_bit(STATUS_READY, &priv->status); | ||
2256 | IWL_ERR(priv, "RF is used by WiMAX\n"); | ||
2257 | } | ||
2258 | |||
2259 | void iwl_stop_sw_queue(struct iwl_op_mode *op_mode, int queue) | ||
2146 | { | 2260 | { |
2147 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); | 2261 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); |
2148 | int ac = priv->queue_to_ac[queue]; | 2262 | int ac = priv->queue_to_ac[queue]; |
@@ -2161,7 +2275,7 @@ static void iwl_stop_sw_queue(struct iwl_op_mode *op_mode, int queue) | |||
2161 | ieee80211_stop_queue(priv->hw, ac); | 2275 | ieee80211_stop_queue(priv->hw, ac); |
2162 | } | 2276 | } |
2163 | 2277 | ||
2164 | static void iwl_wake_sw_queue(struct iwl_op_mode *op_mode, int queue) | 2278 | void iwl_wake_sw_queue(struct iwl_op_mode *op_mode, int queue) |
2165 | { | 2279 | { |
2166 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); | 2280 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); |
2167 | int ac = priv->queue_to_ac[queue]; | 2281 | int ac = priv->queue_to_ac[queue]; |
@@ -2201,6 +2315,27 @@ void iwlagn_lift_passive_no_rx(struct iwl_priv *priv) | |||
2201 | priv->passive_no_rx = false; | 2315 | priv->passive_no_rx = false; |
2202 | } | 2316 | } |
2203 | 2317 | ||
2318 | void iwl_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb) | ||
2319 | { | ||
2320 | struct ieee80211_tx_info *info; | ||
2321 | |||
2322 | info = IEEE80211_SKB_CB(skb); | ||
2323 | kmem_cache_free(iwl_tx_cmd_pool, (info->driver_data[1])); | ||
2324 | dev_kfree_skb_any(skb); | ||
2325 | } | ||
2326 | |||
2327 | void iwl_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state) | ||
2328 | { | ||
2329 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); | ||
2330 | |||
2331 | if (state) | ||
2332 | set_bit(STATUS_RF_KILL_HW, &priv->status); | ||
2333 | else | ||
2334 | clear_bit(STATUS_RF_KILL_HW, &priv->status); | ||
2335 | |||
2336 | wiphy_rfkill_set_hw_state(priv->hw->wiphy, state); | ||
2337 | } | ||
2338 | |||
2204 | const struct iwl_op_mode_ops iwl_dvm_ops = { | 2339 | const struct iwl_op_mode_ops iwl_dvm_ops = { |
2205 | .start = iwl_op_mode_dvm_start, | 2340 | .start = iwl_op_mode_dvm_start, |
2206 | .stop = iwl_op_mode_dvm_stop, | 2341 | .stop = iwl_op_mode_dvm_stop, |
@@ -2212,6 +2347,7 @@ const struct iwl_op_mode_ops iwl_dvm_ops = { | |||
2212 | .nic_error = iwl_nic_error, | 2347 | .nic_error = iwl_nic_error, |
2213 | .cmd_queue_full = iwl_cmd_queue_full, | 2348 | .cmd_queue_full = iwl_cmd_queue_full, |
2214 | .nic_config = iwl_nic_config, | 2349 | .nic_config = iwl_nic_config, |
2350 | .wimax_active = iwl_wimax_active, | ||
2215 | }; | 2351 | }; |
2216 | 2352 | ||
2217 | /***************************************************************************** | 2353 | /***************************************************************************** |
@@ -2280,12 +2416,6 @@ MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size"); | |||
2280 | module_param_named(fw_restart, iwlagn_mod_params.restart_fw, int, S_IRUGO); | 2416 | module_param_named(fw_restart, iwlagn_mod_params.restart_fw, int, S_IRUGO); |
2281 | MODULE_PARM_DESC(fw_restart, "restart firmware in case of error"); | 2417 | MODULE_PARM_DESC(fw_restart, "restart firmware in case of error"); |
2282 | 2418 | ||
2283 | module_param_named(ucode_alternative, | ||
2284 | iwlagn_mod_params.wanted_ucode_alternative, | ||
2285 | int, S_IRUGO); | ||
2286 | MODULE_PARM_DESC(ucode_alternative, | ||
2287 | "specify ucode alternative to use from ucode file"); | ||
2288 | |||
2289 | module_param_named(antenna_coupling, iwlagn_mod_params.ant_coupling, | 2419 | module_param_named(antenna_coupling, iwlagn_mod_params.ant_coupling, |
2290 | int, S_IRUGO); | 2420 | int, S_IRUGO); |
2291 | MODULE_PARM_DESC(antenna_coupling, | 2421 | MODULE_PARM_DESC(antenna_coupling, |
@@ -2299,9 +2429,6 @@ MODULE_PARM_DESC(bt_ch_inhibition, | |||
2299 | module_param_named(plcp_check, iwlagn_mod_params.plcp_check, bool, S_IRUGO); | 2429 | module_param_named(plcp_check, iwlagn_mod_params.plcp_check, bool, S_IRUGO); |
2300 | MODULE_PARM_DESC(plcp_check, "Check plcp health (default: 1 [enabled])"); | 2430 | MODULE_PARM_DESC(plcp_check, "Check plcp health (default: 1 [enabled])"); |
2301 | 2431 | ||
2302 | module_param_named(ack_check, iwlagn_mod_params.ack_check, bool, S_IRUGO); | ||
2303 | MODULE_PARM_DESC(ack_check, "Check ack health (default: 0 [disabled])"); | ||
2304 | |||
2305 | module_param_named(wd_disable, iwlagn_mod_params.wd_disable, int, S_IRUGO); | 2432 | module_param_named(wd_disable, iwlagn_mod_params.wd_disable, int, S_IRUGO); |
2306 | MODULE_PARM_DESC(wd_disable, | 2433 | MODULE_PARM_DESC(wd_disable, |
2307 | "Disable stuck queue watchdog timer 0=system default, " | 2434 | "Disable stuck queue watchdog timer 0=system default, " |
@@ -2345,13 +2472,3 @@ module_param_named(auto_agg, iwlagn_mod_params.auto_agg, | |||
2345 | bool, S_IRUGO); | 2472 | bool, S_IRUGO); |
2346 | MODULE_PARM_DESC(auto_agg, | 2473 | MODULE_PARM_DESC(auto_agg, |
2347 | "enable agg w/o check traffic load (default: enable)"); | 2474 | "enable agg w/o check traffic load (default: enable)"); |
2348 | |||
2349 | /* | ||
2350 | * For now, keep using power level 1 instead of automatically | ||
2351 | * adjusting ... | ||
2352 | */ | ||
2353 | module_param_named(no_sleep_autoadjust, iwlagn_mod_params.no_sleep_autoadjust, | ||
2354 | bool, S_IRUGO); | ||
2355 | MODULE_PARM_DESC(no_sleep_autoadjust, | ||
2356 | "don't automatically adjust sleep level " | ||
2357 | "according to maximum network latency (default: true)"); | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 51001622430b..20100c72ec6b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h | |||
@@ -71,6 +71,34 @@ | |||
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 */ | ||
75 | extern struct iwl_lib_ops iwl1000_lib; | ||
76 | extern struct iwl_lib_ops iwl2000_lib; | ||
77 | extern struct iwl_lib_ops iwl2030_lib; | ||
78 | extern struct iwl_lib_ops iwl5000_lib; | ||
79 | extern struct iwl_lib_ops iwl5150_lib; | ||
80 | extern struct iwl_lib_ops iwl6000_lib; | ||
81 | extern struct iwl_lib_ops iwl6030_lib; | ||
82 | |||
83 | |||
84 | |||
85 | /***************************************************** | ||
86 | * DRIVER STATUS FUNCTIONS | ||
87 | ******************************************************/ | ||
88 | #define STATUS_RF_KILL_HW 0 | ||
89 | #define STATUS_CT_KILL 1 | ||
90 | #define STATUS_ALIVE 2 | ||
91 | #define STATUS_READY 3 | ||
92 | #define STATUS_GEO_CONFIGURED 4 | ||
93 | #define STATUS_EXIT_PENDING 5 | ||
94 | #define STATUS_STATISTICS 6 | ||
95 | #define STATUS_SCANNING 7 | ||
96 | #define STATUS_SCAN_ABORTING 8 | ||
97 | #define STATUS_SCAN_HW 9 | ||
98 | #define STATUS_FW_ERROR 10 | ||
99 | #define STATUS_CHANNEL_SWITCH_PENDING 11 | ||
100 | #define STATUS_SCAN_COMPLETE 12 | ||
101 | #define STATUS_POWER_PMI 13 | ||
74 | 102 | ||
75 | struct iwl_ucode_capabilities; | 103 | struct iwl_ucode_capabilities; |
76 | 104 | ||
@@ -87,11 +115,9 @@ static inline void iwl_set_calib_hdr(struct iwl_calib_hdr *hdr, u8 cmd) | |||
87 | void iwl_down(struct iwl_priv *priv); | 115 | void iwl_down(struct iwl_priv *priv); |
88 | void iwl_cancel_deferred_work(struct iwl_priv *priv); | 116 | void iwl_cancel_deferred_work(struct iwl_priv *priv); |
89 | void iwlagn_prepare_restart(struct iwl_priv *priv); | 117 | void iwlagn_prepare_restart(struct iwl_priv *priv); |
90 | void iwl_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb); | ||
91 | int __must_check iwl_rx_dispatch(struct iwl_op_mode *op_mode, | 118 | int __must_check iwl_rx_dispatch(struct iwl_op_mode *op_mode, |
92 | struct iwl_rx_cmd_buffer *rxb, | 119 | struct iwl_rx_cmd_buffer *rxb, |
93 | struct iwl_device_cmd *cmd); | 120 | struct iwl_device_cmd *cmd); |
94 | void iwl_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state); | ||
95 | 121 | ||
96 | bool iwl_check_for_ct_kill(struct iwl_priv *priv); | 122 | bool iwl_check_for_ct_kill(struct iwl_priv *priv); |
97 | 123 | ||
@@ -109,6 +135,8 @@ int iwl_dvm_send_cmd_pdu(struct iwl_priv *priv, u8 id, | |||
109 | u32 flags, u16 len, const void *data); | 135 | u32 flags, u16 len, const void *data); |
110 | 136 | ||
111 | /* RXON */ | 137 | /* RXON */ |
138 | void iwl_connection_init_rx_config(struct iwl_priv *priv, | ||
139 | struct iwl_rxon_context *ctx); | ||
112 | int iwlagn_set_pan_params(struct iwl_priv *priv); | 140 | int iwlagn_set_pan_params(struct iwl_priv *priv); |
113 | int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx); | 141 | int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx); |
114 | void iwlagn_set_rxon_chain(struct iwl_priv *priv, struct iwl_rxon_context *ctx); | 142 | void iwlagn_set_rxon_chain(struct iwl_priv *priv, struct iwl_rxon_context *ctx); |
@@ -119,6 +147,14 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw, | |||
119 | u32 changes); | 147 | u32 changes); |
120 | void iwlagn_config_ht40(struct ieee80211_conf *conf, | 148 | void iwlagn_config_ht40(struct ieee80211_conf *conf, |
121 | struct iwl_rxon_context *ctx); | 149 | struct iwl_rxon_context *ctx); |
150 | void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_config *ht_conf); | ||
151 | void iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch, | ||
152 | struct iwl_rxon_context *ctx); | ||
153 | void iwl_set_flags_for_band(struct iwl_priv *priv, | ||
154 | struct iwl_rxon_context *ctx, | ||
155 | enum ieee80211_band band, | ||
156 | struct ieee80211_vif *vif); | ||
157 | void iwl_set_rate(struct iwl_priv *priv); | ||
122 | 158 | ||
123 | /* uCode */ | 159 | /* uCode */ |
124 | int iwl_send_bt_env(struct iwl_priv *priv, u8 action, u8 type); | 160 | int iwl_send_bt_env(struct iwl_priv *priv, u8 action, u8 type); |
@@ -131,17 +167,25 @@ int iwl_send_calib_results(struct iwl_priv *priv); | |||
131 | int iwl_calib_set(struct iwl_priv *priv, | 167 | int iwl_calib_set(struct iwl_priv *priv, |
132 | const struct iwl_calib_hdr *cmd, int len); | 168 | const struct iwl_calib_hdr *cmd, int len); |
133 | void iwl_calib_free_results(struct iwl_priv *priv); | 169 | void iwl_calib_free_results(struct iwl_priv *priv); |
134 | void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand); | ||
135 | int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log, | 170 | int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log, |
136 | char **buf, bool display); | 171 | char **buf, bool display); |
172 | int iwlagn_hw_valid_rtc_data_addr(u32 addr); | ||
137 | 173 | ||
138 | /* lib */ | 174 | /* lib */ |
139 | int iwlagn_send_tx_power(struct iwl_priv *priv); | 175 | int iwlagn_send_tx_power(struct iwl_priv *priv); |
140 | void iwlagn_temperature(struct iwl_priv *priv); | 176 | void iwlagn_temperature(struct iwl_priv *priv); |
141 | u16 iwl_eeprom_calib_version(struct iwl_shared *shrd); | ||
142 | int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control); | 177 | int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control); |
143 | void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control); | 178 | void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control); |
144 | int iwlagn_send_beacon_cmd(struct iwl_priv *priv); | 179 | int iwlagn_send_beacon_cmd(struct iwl_priv *priv); |
180 | int iwl_send_statistics_request(struct iwl_priv *priv, | ||
181 | u8 flags, bool clear); | ||
182 | |||
183 | static inline const struct ieee80211_supported_band *iwl_get_hw_mode( | ||
184 | struct iwl_priv *priv, enum ieee80211_band band) | ||
185 | { | ||
186 | return priv->hw->wiphy->bands[band]; | ||
187 | } | ||
188 | |||
145 | #ifdef CONFIG_PM_SLEEP | 189 | #ifdef CONFIG_PM_SLEEP |
146 | int iwlagn_send_patterns(struct iwl_priv *priv, | 190 | int iwlagn_send_patterns(struct iwl_priv *priv, |
147 | struct cfg80211_wowlan *wowlan); | 191 | struct cfg80211_wowlan *wowlan); |
@@ -151,6 +195,7 @@ int iwlagn_suspend(struct iwl_priv *priv, struct cfg80211_wowlan *wowlan); | |||
151 | /* rx */ | 195 | /* rx */ |
152 | int iwlagn_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band); | 196 | int iwlagn_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band); |
153 | void iwl_setup_rx_handlers(struct iwl_priv *priv); | 197 | void iwl_setup_rx_handlers(struct iwl_priv *priv); |
198 | void iwl_chswitch_done(struct iwl_priv *priv, bool is_success); | ||
154 | 199 | ||
155 | 200 | ||
156 | /* tx */ | 201 | /* tx */ |
@@ -195,6 +240,31 @@ u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant_idx, u8 valid); | |||
195 | /* scan */ | 240 | /* scan */ |
196 | void iwlagn_post_scan(struct iwl_priv *priv); | 241 | void iwlagn_post_scan(struct iwl_priv *priv); |
197 | void iwlagn_disable_roc(struct iwl_priv *priv); | 242 | void iwlagn_disable_roc(struct iwl_priv *priv); |
243 | int iwl_force_rf_reset(struct iwl_priv *priv, bool external); | ||
244 | void iwl_init_scan_params(struct iwl_priv *priv); | ||
245 | int iwl_scan_cancel(struct iwl_priv *priv); | ||
246 | void iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms); | ||
247 | void iwl_force_scan_end(struct iwl_priv *priv); | ||
248 | void iwl_internal_short_hw_scan(struct iwl_priv *priv); | ||
249 | void iwl_setup_rx_scan_handlers(struct iwl_priv *priv); | ||
250 | void iwl_setup_scan_deferred_work(struct iwl_priv *priv); | ||
251 | void iwl_cancel_scan_deferred_work(struct iwl_priv *priv); | ||
252 | int __must_check iwl_scan_initiate(struct iwl_priv *priv, | ||
253 | struct ieee80211_vif *vif, | ||
254 | enum iwl_scan_type scan_type, | ||
255 | enum ieee80211_band band); | ||
256 | |||
257 | /* For faster active scanning, scan will move to the next channel if fewer than | ||
258 | * PLCP_QUIET_THRESH packets are heard on this channel within | ||
259 | * ACTIVE_QUIET_TIME after sending probe request. This shortens the dwell | ||
260 | * time if it's a quiet channel (nothing responded to our probe, and there's | ||
261 | * no other traffic). | ||
262 | * Disable "quiet" feature by setting PLCP_QUIET_THRESH to 0. */ | ||
263 | #define IWL_ACTIVE_QUIET_TIME cpu_to_le16(10) /* msec */ | ||
264 | #define IWL_PLCP_QUIET_THRESH cpu_to_le16(1) /* packets */ | ||
265 | |||
266 | #define IWL_SCAN_CHECK_WATCHDOG (HZ * 7) | ||
267 | |||
198 | 268 | ||
199 | /* bt coex */ | 269 | /* bt coex */ |
200 | void iwlagn_send_advance_bt_config(struct iwl_priv *priv); | 270 | void iwlagn_send_advance_bt_config(struct iwl_priv *priv); |
@@ -207,6 +277,12 @@ void iwlagn_bt_cancel_deferred_work(struct iwl_priv *priv); | |||
207 | void iwlagn_bt_coex_rssi_monitor(struct iwl_priv *priv); | 277 | void iwlagn_bt_coex_rssi_monitor(struct iwl_priv *priv); |
208 | void iwlagn_bt_adjust_rssi_monitor(struct iwl_priv *priv, bool rssi_ena); | 278 | void iwlagn_bt_adjust_rssi_monitor(struct iwl_priv *priv, bool rssi_ena); |
209 | 279 | ||
280 | static inline bool iwl_advanced_bt_coexist(struct iwl_priv *priv) | ||
281 | { | ||
282 | return cfg(priv)->bt_params && | ||
283 | cfg(priv)->bt_params->advanced_bt_coexist; | ||
284 | } | ||
285 | |||
210 | #ifdef CONFIG_IWLWIFI_DEBUG | 286 | #ifdef CONFIG_IWLWIFI_DEBUG |
211 | const char *iwl_get_tx_fail_reason(u32 status); | 287 | const char *iwl_get_tx_fail_reason(u32 status); |
212 | const char *iwl_get_agg_tx_fail_reason(u16 status); | 288 | const char *iwl_get_agg_tx_fail_reason(u16 status); |
@@ -245,8 +321,6 @@ void iwl_deactivate_station(struct iwl_priv *priv, const u8 sta_id, | |||
245 | u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx, | 321 | u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx, |
246 | const u8 *addr, bool is_ap, struct ieee80211_sta *sta); | 322 | const u8 *addr, bool is_ap, struct ieee80211_sta *sta); |
247 | 323 | ||
248 | void iwl_sta_fill_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx, | ||
249 | u8 sta_id, struct iwl_link_quality_cmd *link_cmd); | ||
250 | int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx, | 324 | int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx, |
251 | struct iwl_link_quality_cmd *lq, u8 flags, bool init); | 325 | struct iwl_link_quality_cmd *lq, u8 flags, bool init); |
252 | int iwl_add_sta_callback(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, | 326 | int iwl_add_sta_callback(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, |
@@ -254,6 +328,9 @@ int iwl_add_sta_callback(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, | |||
254 | int iwl_sta_update_ht(struct iwl_priv *priv, struct iwl_rxon_context *ctx, | 328 | int iwl_sta_update_ht(struct iwl_priv *priv, struct iwl_rxon_context *ctx, |
255 | struct ieee80211_sta *sta); | 329 | struct ieee80211_sta *sta); |
256 | 330 | ||
331 | bool iwl_is_ht40_tx_allowed(struct iwl_priv *priv, | ||
332 | struct iwl_rxon_context *ctx, | ||
333 | struct ieee80211_sta_ht_cap *ht_cap); | ||
257 | 334 | ||
258 | static inline int iwl_sta_id(struct ieee80211_sta *sta) | 335 | static inline int iwl_sta_id(struct ieee80211_sta *sta) |
259 | { | 336 | { |
@@ -311,9 +388,6 @@ static inline __le32 iwl_hw_set_rate_n_flags(u8 rate, u32 flags) | |||
311 | return cpu_to_le32(flags|(u32)rate); | 388 | return cpu_to_le32(flags|(u32)rate); |
312 | } | 389 | } |
313 | 390 | ||
314 | /* eeprom */ | ||
315 | void iwl_eeprom_get_mac(const struct iwl_shared *shrd, u8 *mac); | ||
316 | |||
317 | extern int iwl_alive_start(struct iwl_priv *priv); | 391 | extern int iwl_alive_start(struct iwl_priv *priv); |
318 | /* svtool */ | 392 | /* svtool */ |
319 | #ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE | 393 | #ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE |
@@ -421,4 +495,95 @@ do { \ | |||
421 | } while (0) | 495 | } while (0) |
422 | #endif /* CONFIG_IWLWIFI_DEBUG */ | 496 | #endif /* CONFIG_IWLWIFI_DEBUG */ |
423 | 497 | ||
498 | extern const char *iwl_dvm_cmd_strings[REPLY_MAX]; | ||
499 | |||
500 | static inline const char *iwl_dvm_get_cmd_string(u8 cmd) | ||
501 | { | ||
502 | const char *s = iwl_dvm_cmd_strings[cmd]; | ||
503 | if (s) | ||
504 | return s; | ||
505 | return "UNKNOWN"; | ||
506 | } | ||
507 | |||
508 | /* API method exported for mvm hybrid state */ | ||
509 | void iwl_setup_deferred_work(struct iwl_priv *priv); | ||
510 | int iwl_send_wimax_coex(struct iwl_priv *priv); | ||
511 | int iwl_send_bt_env(struct iwl_priv *priv, u8 action, u8 type); | ||
512 | void iwl_debug_config(struct iwl_priv *priv); | ||
513 | int iwl_alloc_traffic_mem(struct iwl_priv *priv); | ||
514 | void iwl_set_hw_params(struct iwl_priv *priv); | ||
515 | void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags); | ||
516 | int iwl_init_drv(struct iwl_priv *priv); | ||
517 | void iwl_uninit_drv(struct iwl_priv *priv); | ||
518 | void iwl_send_bt_config(struct iwl_priv *priv); | ||
519 | void iwl_rf_kill_ct_config(struct iwl_priv *priv); | ||
520 | int iwl_setup_interface(struct iwl_priv *priv, struct iwl_rxon_context *ctx); | ||
521 | void iwl_teardown_interface(struct iwl_priv *priv, | ||
522 | struct ieee80211_vif *vif, | ||
523 | bool mode_change); | ||
524 | int iwl_full_rxon_required(struct iwl_priv *priv, struct iwl_rxon_context *ctx); | ||
525 | void iwlagn_update_qos(struct iwl_priv *priv, struct iwl_rxon_context *ctx); | ||
526 | void iwlagn_check_needed_chains(struct iwl_priv *priv, | ||
527 | struct iwl_rxon_context *ctx, | ||
528 | struct ieee80211_bss_conf *bss_conf); | ||
529 | void iwlagn_chain_noise_reset(struct iwl_priv *priv); | ||
530 | int iwlagn_update_beacon(struct iwl_priv *priv, | ||
531 | struct ieee80211_vif *vif); | ||
532 | void iwl_tt_handler(struct iwl_priv *priv); | ||
533 | void iwl_op_mode_dvm_stop(struct iwl_op_mode *op_mode); | ||
534 | void iwl_stop_sw_queue(struct iwl_op_mode *op_mode, int queue); | ||
535 | void iwl_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state); | ||
536 | void iwl_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb); | ||
537 | void iwl_nic_error(struct iwl_op_mode *op_mode); | ||
538 | void iwl_cmd_queue_full(struct iwl_op_mode *op_mode); | ||
539 | void iwl_nic_config(struct iwl_op_mode *op_mode); | ||
540 | int iwlagn_mac_set_tim(struct ieee80211_hw *hw, | ||
541 | struct ieee80211_sta *sta, bool set); | ||
542 | void iwlagn_mac_rssi_callback(struct ieee80211_hw *hw, | ||
543 | enum ieee80211_rssi_event rssi_event); | ||
544 | int iwlagn_mac_cancel_remain_on_channel(struct ieee80211_hw *hw); | ||
545 | int iwlagn_mac_tx_last_beacon(struct ieee80211_hw *hw); | ||
546 | void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop); | ||
547 | void iwl_wake_sw_queue(struct iwl_op_mode *op_mode, int queue); | ||
548 | void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, | ||
549 | struct ieee80211_channel_switch *ch_switch); | ||
550 | int iwlagn_mac_sta_state(struct ieee80211_hw *hw, | ||
551 | struct ieee80211_vif *vif, | ||
552 | struct ieee80211_sta *sta, | ||
553 | enum ieee80211_sta_state old_state, | ||
554 | enum ieee80211_sta_state new_state); | ||
555 | int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, | ||
556 | struct ieee80211_vif *vif, | ||
557 | enum ieee80211_ampdu_mlme_action action, | ||
558 | struct ieee80211_sta *sta, u16 tid, u16 *ssn, | ||
559 | u8 buf_size); | ||
560 | int iwlagn_mac_hw_scan(struct ieee80211_hw *hw, | ||
561 | struct ieee80211_vif *vif, | ||
562 | struct cfg80211_scan_request *req); | ||
563 | void iwlagn_mac_sta_notify(struct ieee80211_hw *hw, | ||
564 | struct ieee80211_vif *vif, | ||
565 | enum sta_notify_cmd cmd, | ||
566 | struct ieee80211_sta *sta); | ||
567 | void iwlagn_configure_filter(struct ieee80211_hw *hw, | ||
568 | unsigned int changed_flags, | ||
569 | unsigned int *total_flags, | ||
570 | u64 multicast); | ||
571 | int iwlagn_mac_conf_tx(struct ieee80211_hw *hw, | ||
572 | struct ieee80211_vif *vif, u16 queue, | ||
573 | const struct ieee80211_tx_queue_params *params); | ||
574 | void iwlagn_mac_set_rekey_data(struct ieee80211_hw *hw, | ||
575 | struct ieee80211_vif *vif, | ||
576 | struct cfg80211_gtk_rekey_data *data); | ||
577 | void iwlagn_mac_update_tkip_key(struct ieee80211_hw *hw, | ||
578 | struct ieee80211_vif *vif, | ||
579 | struct ieee80211_key_conf *keyconf, | ||
580 | struct ieee80211_sta *sta, | ||
581 | u32 iv32, u16 *phase1key); | ||
582 | int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | ||
583 | struct ieee80211_vif *vif, | ||
584 | struct ieee80211_sta *sta, | ||
585 | struct ieee80211_key_conf *key); | ||
586 | void iwlagn_mac_stop(struct ieee80211_hw *hw); | ||
587 | void iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb); | ||
588 | int iwlagn_mac_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan); | ||
424 | #endif /* __iwl_agn_h__ */ | 589 | #endif /* __iwl_agn_h__ */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index 9ed73e5154be..296347a8290f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h | |||
@@ -1918,7 +1918,7 @@ struct iwl_basic_bt_cmd { | |||
1918 | __le16 valid; | 1918 | __le16 valid; |
1919 | }; | 1919 | }; |
1920 | 1920 | ||
1921 | struct iwl6000_bt_cmd { | 1921 | struct iwl_bt_cmd_v1 { |
1922 | struct iwl_basic_bt_cmd basic; | 1922 | struct iwl_basic_bt_cmd basic; |
1923 | u8 prio_boost; | 1923 | u8 prio_boost; |
1924 | /* | 1924 | /* |
@@ -1929,7 +1929,7 @@ struct iwl6000_bt_cmd { | |||
1929 | __le16 rx_prio_boost; /* SW boost of WiFi rx priority */ | 1929 | __le16 rx_prio_boost; /* SW boost of WiFi rx priority */ |
1930 | }; | 1930 | }; |
1931 | 1931 | ||
1932 | struct iwl2000_bt_cmd { | 1932 | struct iwl_bt_cmd_v2 { |
1933 | struct iwl_basic_bt_cmd basic; | 1933 | struct iwl_basic_bt_cmd basic; |
1934 | __le32 prio_boost; | 1934 | __le32 prio_boost; |
1935 | /* | 1935 | /* |
diff --git a/drivers/net/wireless/iwlwifi/iwl-config.h b/drivers/net/wireless/iwlwifi/iwl-config.h new file mode 100644 index 000000000000..47bfd5e59575 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-config.h | |||
@@ -0,0 +1,227 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * This file is provided under a dual BSD/GPLv2 license. When using or | ||
4 | * redistributing this file, you may do so under either license. | ||
5 | * | ||
6 | * GPL LICENSE SUMMARY | ||
7 | * | ||
8 | * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of version 2 of the GNU General Public License as | ||
12 | * published by the Free Software Foundation. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, but | ||
15 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
17 | * General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, | ||
22 | * USA | ||
23 | * | ||
24 | * The full GNU General Public License is included in this distribution | ||
25 | * in the file called LICENSE.GPL. | ||
26 | * | ||
27 | * Contact Information: | ||
28 | * Intel Linux Wireless <ilw@linux.intel.com> | ||
29 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||
30 | * | ||
31 | * BSD LICENSE | ||
32 | * | ||
33 | * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. | ||
34 | * All rights reserved. | ||
35 | * | ||
36 | * Redistribution and use in source and binary forms, with or without | ||
37 | * modification, are permitted provided that the following conditions | ||
38 | * are met: | ||
39 | * | ||
40 | * * Redistributions of source code must retain the above copyright | ||
41 | * notice, this list of conditions and the following disclaimer. | ||
42 | * * Redistributions in binary form must reproduce the above copyright | ||
43 | * notice, this list of conditions and the following disclaimer in | ||
44 | * the documentation and/or other materials provided with the | ||
45 | * distribution. | ||
46 | * * Neither the name Intel Corporation nor the names of its | ||
47 | * contributors may be used to endorse or promote products derived | ||
48 | * from this software without specific prior written permission. | ||
49 | * | ||
50 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
51 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
52 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
53 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
54 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
55 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
56 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
57 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
58 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
59 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
60 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
61 | * | ||
62 | *****************************************************************************/ | ||
63 | #ifndef __IWL_CONFIG_H__ | ||
64 | #define __IWL_CONFIG_H__ | ||
65 | |||
66 | #include <linux/types.h> | ||
67 | #include <net/mac80211.h> | ||
68 | |||
69 | |||
70 | enum iwl_device_family { | ||
71 | IWL_DEVICE_FAMILY_UNDEFINED, | ||
72 | IWL_DEVICE_FAMILY_1000, | ||
73 | IWL_DEVICE_FAMILY_100, | ||
74 | IWL_DEVICE_FAMILY_2000, | ||
75 | IWL_DEVICE_FAMILY_2030, | ||
76 | IWL_DEVICE_FAMILY_105, | ||
77 | IWL_DEVICE_FAMILY_135, | ||
78 | IWL_DEVICE_FAMILY_5000, | ||
79 | IWL_DEVICE_FAMILY_5150, | ||
80 | IWL_DEVICE_FAMILY_6000, | ||
81 | IWL_DEVICE_FAMILY_6000i, | ||
82 | IWL_DEVICE_FAMILY_6005, | ||
83 | IWL_DEVICE_FAMILY_6030, | ||
84 | IWL_DEVICE_FAMILY_6050, | ||
85 | IWL_DEVICE_FAMILY_6150, | ||
86 | }; | ||
87 | |||
88 | /* | ||
89 | * LED mode | ||
90 | * IWL_LED_DEFAULT: use device default | ||
91 | * IWL_LED_RF_STATE: turn LED on/off based on RF state | ||
92 | * LED ON = RF ON | ||
93 | * LED OFF = RF OFF | ||
94 | * IWL_LED_BLINK: adjust led blink rate based on blink table | ||
95 | * IWL_LED_DISABLE: led disabled | ||
96 | */ | ||
97 | enum iwl_led_mode { | ||
98 | IWL_LED_DEFAULT, | ||
99 | IWL_LED_RF_STATE, | ||
100 | IWL_LED_BLINK, | ||
101 | IWL_LED_DISABLE, | ||
102 | }; | ||
103 | |||
104 | /* | ||
105 | * @max_ll_items: max number of OTP blocks | ||
106 | * @shadow_ram_support: shadow support for OTP memory | ||
107 | * @led_compensation: compensate on the led on/off time per HW according | ||
108 | * to the deviation to achieve the desired led frequency. | ||
109 | * The detail algorithm is described in iwl-led.c | ||
110 | * @chain_noise_num_beacons: number of beacons used to compute chain noise | ||
111 | * @adv_thermal_throttle: support advance thermal throttle | ||
112 | * @support_ct_kill_exit: support ct kill exit condition | ||
113 | * @plcp_delta_threshold: plcp error rate threshold used to trigger | ||
114 | * radio tuning when there is a high receiving plcp error rate | ||
115 | * @chain_noise_scale: default chain noise scale used for gain computation | ||
116 | * @wd_timeout: TX queues watchdog timeout | ||
117 | * @max_event_log_size: size of event log buffer size for ucode event logging | ||
118 | * @shadow_reg_enable: HW shadhow register bit | ||
119 | * @hd_v2: v2 of enhanced sensitivity value, used for 2000 series and up | ||
120 | * @no_idle_support: do not support idle mode | ||
121 | */ | ||
122 | struct iwl_base_params { | ||
123 | int eeprom_size; | ||
124 | int num_of_queues; /* def: HW dependent */ | ||
125 | /* for iwl_apm_init() */ | ||
126 | u32 pll_cfg_val; | ||
127 | |||
128 | const u16 max_ll_items; | ||
129 | const bool shadow_ram_support; | ||
130 | u16 led_compensation; | ||
131 | bool adv_thermal_throttle; | ||
132 | bool support_ct_kill_exit; | ||
133 | u8 plcp_delta_threshold; | ||
134 | s32 chain_noise_scale; | ||
135 | unsigned int wd_timeout; | ||
136 | u32 max_event_log_size; | ||
137 | const bool shadow_reg_enable; | ||
138 | const bool hd_v2; | ||
139 | const bool no_idle_support; | ||
140 | }; | ||
141 | |||
142 | /* | ||
143 | * @advanced_bt_coexist: support advanced bt coexist | ||
144 | * @bt_init_traffic_load: specify initial bt traffic load | ||
145 | * @bt_prio_boost: default bt priority boost value | ||
146 | * @agg_time_limit: maximum number of uSec in aggregation | ||
147 | * @bt_sco_disable: uCode should not response to BT in SCO/ESCO mode | ||
148 | */ | ||
149 | struct iwl_bt_params { | ||
150 | bool advanced_bt_coexist; | ||
151 | u8 bt_init_traffic_load; | ||
152 | u8 bt_prio_boost; | ||
153 | u16 agg_time_limit; | ||
154 | bool bt_sco_disable; | ||
155 | bool bt_session_2; | ||
156 | }; | ||
157 | /* | ||
158 | * @use_rts_for_aggregation: use rts/cts protection for HT traffic | ||
159 | */ | ||
160 | struct iwl_ht_params { | ||
161 | const bool ht_greenfield_support; /* if used set to true */ | ||
162 | bool use_rts_for_aggregation; | ||
163 | enum ieee80211_smps_mode smps_mode; | ||
164 | }; | ||
165 | |||
166 | /** | ||
167 | * struct iwl_cfg | ||
168 | * @name: Offical name of the device | ||
169 | * @fw_name_pre: Firmware filename prefix. The api version and extension | ||
170 | * (.ucode) will be added to filename before loading from disk. The | ||
171 | * filename is constructed as fw_name_pre<api>.ucode. | ||
172 | * @ucode_api_max: Highest version of uCode API supported by driver. | ||
173 | * @ucode_api_ok: oldest version of the uCode API that is OK to load | ||
174 | * without a warning, for use in transitions | ||
175 | * @ucode_api_min: Lowest version of uCode API supported by driver. | ||
176 | * @max_inst_size: The maximal length of the fw inst section | ||
177 | * @max_data_size: The maximal length of the fw data section | ||
178 | * @valid_tx_ant: valid transmit antenna | ||
179 | * @valid_rx_ant: valid receive antenna | ||
180 | * @eeprom_ver: EEPROM version | ||
181 | * @eeprom_calib_ver: EEPROM calibration version | ||
182 | * @lib: pointer to the lib ops | ||
183 | * @base_params: pointer to basic parameters | ||
184 | * @ht_params: point to ht patameters | ||
185 | * @bt_params: pointer to bt parameters | ||
186 | * @need_temp_offset_calib: need to perform temperature offset calibration | ||
187 | * @no_xtal_calib: some devices do not need crystal calibration data, | ||
188 | * don't send it to those | ||
189 | * @led_mode: 0=blinking, 1=On(RF On)/Off(RF Off) | ||
190 | * @adv_pm: advance power management | ||
191 | * @rx_with_siso_diversity: 1x1 device with rx antenna diversity | ||
192 | * @internal_wimax_coex: internal wifi/wimax combo device | ||
193 | * @temp_offset_v2: support v2 of temperature offset calibration | ||
194 | * | ||
195 | * We enable the driver to be backward compatible wrt. hardware features. | ||
196 | * API differences in uCode shouldn't be handled here but through TLVs | ||
197 | * and/or the uCode API version instead. | ||
198 | */ | ||
199 | struct iwl_cfg { | ||
200 | /* params specific to an individual device within a device family */ | ||
201 | const char *name; | ||
202 | const char *fw_name_pre; | ||
203 | const unsigned int ucode_api_max; | ||
204 | const unsigned int ucode_api_ok; | ||
205 | const unsigned int ucode_api_min; | ||
206 | const enum iwl_device_family device_family; | ||
207 | const u32 max_data_size; | ||
208 | const u32 max_inst_size; | ||
209 | u8 valid_tx_ant; | ||
210 | u8 valid_rx_ant; | ||
211 | u16 eeprom_ver; | ||
212 | u16 eeprom_calib_ver; | ||
213 | /* params not likely to change within a device family */ | ||
214 | const struct iwl_base_params *base_params; | ||
215 | /* params likely to change within a device family */ | ||
216 | const struct iwl_ht_params *ht_params; | ||
217 | const struct iwl_bt_params *bt_params; | ||
218 | const bool need_temp_offset_calib; /* if used set to true */ | ||
219 | const bool no_xtal_calib; | ||
220 | enum iwl_led_mode led_mode; | ||
221 | const bool adv_pm; | ||
222 | const bool rx_with_siso_diversity; | ||
223 | const bool internal_wimax_coex; | ||
224 | const bool temp_offset_v2; | ||
225 | }; | ||
226 | |||
227 | #endif /* __IWL_CONFIG_H__ */ | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 88ea31d9eb75..d7a8cde249ff 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
@@ -41,477 +41,6 @@ | |||
41 | #include "iwl-agn.h" | 41 | #include "iwl-agn.h" |
42 | #include "iwl-trans.h" | 42 | #include "iwl-trans.h" |
43 | 43 | ||
44 | const u8 iwl_bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; | ||
45 | |||
46 | static bool iwl_is_channel_extension(struct iwl_priv *priv, | ||
47 | enum ieee80211_band band, | ||
48 | u16 channel, u8 extension_chan_offset) | ||
49 | { | ||
50 | const struct iwl_channel_info *ch_info; | ||
51 | |||
52 | ch_info = iwl_get_channel_info(priv, band, channel); | ||
53 | if (!is_channel_valid(ch_info)) | ||
54 | return false; | ||
55 | |||
56 | if (extension_chan_offset == IEEE80211_HT_PARAM_CHA_SEC_ABOVE) | ||
57 | return !(ch_info->ht40_extension_channel & | ||
58 | IEEE80211_CHAN_NO_HT40PLUS); | ||
59 | else if (extension_chan_offset == IEEE80211_HT_PARAM_CHA_SEC_BELOW) | ||
60 | return !(ch_info->ht40_extension_channel & | ||
61 | IEEE80211_CHAN_NO_HT40MINUS); | ||
62 | |||
63 | return false; | ||
64 | } | ||
65 | |||
66 | bool iwl_is_ht40_tx_allowed(struct iwl_priv *priv, | ||
67 | struct iwl_rxon_context *ctx, | ||
68 | struct ieee80211_sta_ht_cap *ht_cap) | ||
69 | { | ||
70 | if (!ctx->ht.enabled || !ctx->ht.is_40mhz) | ||
71 | return false; | ||
72 | |||
73 | /* | ||
74 | * We do not check for IEEE80211_HT_CAP_SUP_WIDTH_20_40 | ||
75 | * the bit will not set if it is pure 40MHz case | ||
76 | */ | ||
77 | if (ht_cap && !ht_cap->ht_supported) | ||
78 | return false; | ||
79 | |||
80 | #ifdef CONFIG_IWLWIFI_DEBUGFS | ||
81 | if (priv->disable_ht40) | ||
82 | return false; | ||
83 | #endif | ||
84 | |||
85 | return iwl_is_channel_extension(priv, priv->band, | ||
86 | le16_to_cpu(ctx->staging.channel), | ||
87 | ctx->ht.extension_chan_offset); | ||
88 | } | ||
89 | |||
90 | static void _iwl_set_rxon_ht(struct iwl_priv *priv, | ||
91 | struct iwl_ht_config *ht_conf, | ||
92 | struct iwl_rxon_context *ctx) | ||
93 | { | ||
94 | struct iwl_rxon_cmd *rxon = &ctx->staging; | ||
95 | |||
96 | if (!ctx->ht.enabled) { | ||
97 | rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MSK | | ||
98 | RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK | | ||
99 | RXON_FLG_HT40_PROT_MSK | | ||
100 | RXON_FLG_HT_PROT_MSK); | ||
101 | return; | ||
102 | } | ||
103 | |||
104 | /* FIXME: if the definition of ht.protection changed, the "translation" | ||
105 | * will be needed for rxon->flags | ||
106 | */ | ||
107 | rxon->flags |= cpu_to_le32(ctx->ht.protection << RXON_FLG_HT_OPERATING_MODE_POS); | ||
108 | |||
109 | /* Set up channel bandwidth: | ||
110 | * 20 MHz only, 20/40 mixed or pure 40 if ht40 ok */ | ||
111 | /* clear the HT channel mode before set the mode */ | ||
112 | rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MSK | | ||
113 | RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK); | ||
114 | if (iwl_is_ht40_tx_allowed(priv, ctx, NULL)) { | ||
115 | /* pure ht40 */ | ||
116 | if (ctx->ht.protection == IEEE80211_HT_OP_MODE_PROTECTION_20MHZ) { | ||
117 | rxon->flags |= RXON_FLG_CHANNEL_MODE_PURE_40; | ||
118 | /* Note: control channel is opposite of extension channel */ | ||
119 | switch (ctx->ht.extension_chan_offset) { | ||
120 | case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: | ||
121 | rxon->flags &= ~RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK; | ||
122 | break; | ||
123 | case IEEE80211_HT_PARAM_CHA_SEC_BELOW: | ||
124 | rxon->flags |= RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK; | ||
125 | break; | ||
126 | } | ||
127 | } else { | ||
128 | /* Note: control channel is opposite of extension channel */ | ||
129 | switch (ctx->ht.extension_chan_offset) { | ||
130 | case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: | ||
131 | rxon->flags &= ~(RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK); | ||
132 | rxon->flags |= RXON_FLG_CHANNEL_MODE_MIXED; | ||
133 | break; | ||
134 | case IEEE80211_HT_PARAM_CHA_SEC_BELOW: | ||
135 | rxon->flags |= RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK; | ||
136 | rxon->flags |= RXON_FLG_CHANNEL_MODE_MIXED; | ||
137 | break; | ||
138 | case IEEE80211_HT_PARAM_CHA_SEC_NONE: | ||
139 | default: | ||
140 | /* channel location only valid if in Mixed mode */ | ||
141 | IWL_ERR(priv, "invalid extension channel offset\n"); | ||
142 | break; | ||
143 | } | ||
144 | } | ||
145 | } else { | ||
146 | rxon->flags |= RXON_FLG_CHANNEL_MODE_LEGACY; | ||
147 | } | ||
148 | |||
149 | iwlagn_set_rxon_chain(priv, ctx); | ||
150 | |||
151 | IWL_DEBUG_ASSOC(priv, "rxon flags 0x%X operation mode :0x%X " | ||
152 | "extension channel offset 0x%x\n", | ||
153 | le32_to_cpu(rxon->flags), ctx->ht.protection, | ||
154 | ctx->ht.extension_chan_offset); | ||
155 | } | ||
156 | |||
157 | void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_config *ht_conf) | ||
158 | { | ||
159 | struct iwl_rxon_context *ctx; | ||
160 | |||
161 | for_each_context(priv, ctx) | ||
162 | _iwl_set_rxon_ht(priv, ht_conf, ctx); | ||
163 | } | ||
164 | |||
165 | /** | ||
166 | * iwl_set_rxon_channel - Set the band and channel values in staging RXON | ||
167 | * @ch: requested channel as a pointer to struct ieee80211_channel | ||
168 | |||
169 | * NOTE: Does not commit to the hardware; it sets appropriate bit fields | ||
170 | * in the staging RXON flag structure based on the ch->band | ||
171 | */ | ||
172 | void iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch, | ||
173 | struct iwl_rxon_context *ctx) | ||
174 | { | ||
175 | enum ieee80211_band band = ch->band; | ||
176 | u16 channel = ch->hw_value; | ||
177 | |||
178 | if ((le16_to_cpu(ctx->staging.channel) == channel) && | ||
179 | (priv->band == band)) | ||
180 | return; | ||
181 | |||
182 | ctx->staging.channel = cpu_to_le16(channel); | ||
183 | if (band == IEEE80211_BAND_5GHZ) | ||
184 | ctx->staging.flags &= ~RXON_FLG_BAND_24G_MSK; | ||
185 | else | ||
186 | ctx->staging.flags |= RXON_FLG_BAND_24G_MSK; | ||
187 | |||
188 | priv->band = band; | ||
189 | |||
190 | IWL_DEBUG_INFO(priv, "Staging channel set to %d [%d]\n", channel, band); | ||
191 | |||
192 | } | ||
193 | |||
194 | void iwl_set_flags_for_band(struct iwl_priv *priv, | ||
195 | struct iwl_rxon_context *ctx, | ||
196 | enum ieee80211_band band, | ||
197 | struct ieee80211_vif *vif) | ||
198 | { | ||
199 | if (band == IEEE80211_BAND_5GHZ) { | ||
200 | ctx->staging.flags &= | ||
201 | ~(RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK | ||
202 | | RXON_FLG_CCK_MSK); | ||
203 | ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; | ||
204 | } else { | ||
205 | /* Copied from iwl_post_associate() */ | ||
206 | if (vif && vif->bss_conf.use_short_slot) | ||
207 | ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; | ||
208 | else | ||
209 | ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK; | ||
210 | |||
211 | ctx->staging.flags |= RXON_FLG_BAND_24G_MSK; | ||
212 | ctx->staging.flags |= RXON_FLG_AUTO_DETECT_MSK; | ||
213 | ctx->staging.flags &= ~RXON_FLG_CCK_MSK; | ||
214 | } | ||
215 | } | ||
216 | |||
217 | /* | ||
218 | * initialize rxon structure with default values from eeprom | ||
219 | */ | ||
220 | void iwl_connection_init_rx_config(struct iwl_priv *priv, | ||
221 | struct iwl_rxon_context *ctx) | ||
222 | { | ||
223 | const struct iwl_channel_info *ch_info; | ||
224 | |||
225 | memset(&ctx->staging, 0, sizeof(ctx->staging)); | ||
226 | |||
227 | if (!ctx->vif) { | ||
228 | ctx->staging.dev_type = ctx->unused_devtype; | ||
229 | } else switch (ctx->vif->type) { | ||
230 | case NL80211_IFTYPE_AP: | ||
231 | ctx->staging.dev_type = ctx->ap_devtype; | ||
232 | break; | ||
233 | |||
234 | case NL80211_IFTYPE_STATION: | ||
235 | ctx->staging.dev_type = ctx->station_devtype; | ||
236 | ctx->staging.filter_flags = RXON_FILTER_ACCEPT_GRP_MSK; | ||
237 | break; | ||
238 | |||
239 | case NL80211_IFTYPE_ADHOC: | ||
240 | ctx->staging.dev_type = ctx->ibss_devtype; | ||
241 | ctx->staging.flags = RXON_FLG_SHORT_PREAMBLE_MSK; | ||
242 | ctx->staging.filter_flags = RXON_FILTER_BCON_AWARE_MSK | | ||
243 | RXON_FILTER_ACCEPT_GRP_MSK; | ||
244 | break; | ||
245 | |||
246 | default: | ||
247 | IWL_ERR(priv, "Unsupported interface type %d\n", | ||
248 | ctx->vif->type); | ||
249 | break; | ||
250 | } | ||
251 | |||
252 | #if 0 | ||
253 | /* TODO: Figure out when short_preamble would be set and cache from | ||
254 | * that */ | ||
255 | if (!hw_to_local(priv->hw)->short_preamble) | ||
256 | ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; | ||
257 | else | ||
258 | ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; | ||
259 | #endif | ||
260 | |||
261 | ch_info = iwl_get_channel_info(priv, priv->band, | ||
262 | le16_to_cpu(ctx->active.channel)); | ||
263 | |||
264 | if (!ch_info) | ||
265 | ch_info = &priv->channel_info[0]; | ||
266 | |||
267 | ctx->staging.channel = cpu_to_le16(ch_info->channel); | ||
268 | priv->band = ch_info->band; | ||
269 | |||
270 | iwl_set_flags_for_band(priv, ctx, priv->band, ctx->vif); | ||
271 | |||
272 | ctx->staging.ofdm_basic_rates = | ||
273 | (IWL_OFDM_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF; | ||
274 | ctx->staging.cck_basic_rates = | ||
275 | (IWL_CCK_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF; | ||
276 | |||
277 | /* clear both MIX and PURE40 mode flag */ | ||
278 | ctx->staging.flags &= ~(RXON_FLG_CHANNEL_MODE_MIXED | | ||
279 | RXON_FLG_CHANNEL_MODE_PURE_40); | ||
280 | if (ctx->vif) | ||
281 | memcpy(ctx->staging.node_addr, ctx->vif->addr, ETH_ALEN); | ||
282 | |||
283 | ctx->staging.ofdm_ht_single_stream_basic_rates = 0xff; | ||
284 | ctx->staging.ofdm_ht_dual_stream_basic_rates = 0xff; | ||
285 | ctx->staging.ofdm_ht_triple_stream_basic_rates = 0xff; | ||
286 | } | ||
287 | |||
288 | void iwl_set_rate(struct iwl_priv *priv) | ||
289 | { | ||
290 | const struct ieee80211_supported_band *hw = NULL; | ||
291 | struct ieee80211_rate *rate; | ||
292 | struct iwl_rxon_context *ctx; | ||
293 | int i; | ||
294 | |||
295 | hw = iwl_get_hw_mode(priv, priv->band); | ||
296 | if (!hw) { | ||
297 | IWL_ERR(priv, "Failed to set rate: unable to get hw mode\n"); | ||
298 | return; | ||
299 | } | ||
300 | |||
301 | priv->active_rate = 0; | ||
302 | |||
303 | for (i = 0; i < hw->n_bitrates; i++) { | ||
304 | rate = &(hw->bitrates[i]); | ||
305 | if (rate->hw_value < IWL_RATE_COUNT_LEGACY) | ||
306 | priv->active_rate |= (1 << rate->hw_value); | ||
307 | } | ||
308 | |||
309 | IWL_DEBUG_RATE(priv, "Set active_rate = %0x\n", priv->active_rate); | ||
310 | |||
311 | for_each_context(priv, ctx) { | ||
312 | ctx->staging.cck_basic_rates = | ||
313 | (IWL_CCK_BASIC_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF; | ||
314 | |||
315 | ctx->staging.ofdm_basic_rates = | ||
316 | (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF; | ||
317 | } | ||
318 | } | ||
319 | |||
320 | void iwl_chswitch_done(struct iwl_priv *priv, bool is_success) | ||
321 | { | ||
322 | /* | ||
323 | * MULTI-FIXME | ||
324 | * See iwlagn_mac_channel_switch. | ||
325 | */ | ||
326 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | ||
327 | |||
328 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | ||
329 | return; | ||
330 | |||
331 | if (test_and_clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status)) | ||
332 | ieee80211_chswitch_done(ctx->vif, is_success); | ||
333 | } | ||
334 | |||
335 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
336 | void iwl_print_rx_config_cmd(struct iwl_priv *priv, | ||
337 | enum iwl_rxon_context_id ctxid) | ||
338 | { | ||
339 | struct iwl_rxon_context *ctx = &priv->contexts[ctxid]; | ||
340 | struct iwl_rxon_cmd *rxon = &ctx->staging; | ||
341 | |||
342 | IWL_DEBUG_RADIO(priv, "RX CONFIG:\n"); | ||
343 | iwl_print_hex_dump(priv, IWL_DL_RADIO, (u8 *) rxon, sizeof(*rxon)); | ||
344 | IWL_DEBUG_RADIO(priv, "u16 channel: 0x%x\n", le16_to_cpu(rxon->channel)); | ||
345 | IWL_DEBUG_RADIO(priv, "u32 flags: 0x%08X\n", le32_to_cpu(rxon->flags)); | ||
346 | IWL_DEBUG_RADIO(priv, "u32 filter_flags: 0x%08x\n", | ||
347 | le32_to_cpu(rxon->filter_flags)); | ||
348 | IWL_DEBUG_RADIO(priv, "u8 dev_type: 0x%x\n", rxon->dev_type); | ||
349 | IWL_DEBUG_RADIO(priv, "u8 ofdm_basic_rates: 0x%02x\n", | ||
350 | rxon->ofdm_basic_rates); | ||
351 | IWL_DEBUG_RADIO(priv, "u8 cck_basic_rates: 0x%02x\n", rxon->cck_basic_rates); | ||
352 | IWL_DEBUG_RADIO(priv, "u8[6] node_addr: %pM\n", rxon->node_addr); | ||
353 | IWL_DEBUG_RADIO(priv, "u8[6] bssid_addr: %pM\n", rxon->bssid_addr); | ||
354 | IWL_DEBUG_RADIO(priv, "u16 assoc_id: 0x%x\n", le16_to_cpu(rxon->assoc_id)); | ||
355 | } | ||
356 | #endif | ||
357 | |||
358 | void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand) | ||
359 | { | ||
360 | unsigned int reload_msec; | ||
361 | unsigned long reload_jiffies; | ||
362 | |||
363 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
364 | if (iwl_have_debug_level(IWL_DL_FW_ERRORS)) | ||
365 | iwl_print_rx_config_cmd(priv, IWL_RXON_CTX_BSS); | ||
366 | #endif | ||
367 | |||
368 | /* uCode is no longer loaded. */ | ||
369 | priv->ucode_loaded = false; | ||
370 | |||
371 | /* Set the FW error flag -- cleared on iwl_down */ | ||
372 | set_bit(STATUS_FW_ERROR, &priv->status); | ||
373 | |||
374 | /* Cancel currently queued command. */ | ||
375 | clear_bit(STATUS_HCMD_ACTIVE, &priv->shrd->status); | ||
376 | |||
377 | iwl_abort_notification_waits(&priv->notif_wait); | ||
378 | |||
379 | /* Keep the restart process from trying to send host | ||
380 | * commands by clearing the ready bit */ | ||
381 | clear_bit(STATUS_READY, &priv->status); | ||
382 | |||
383 | wake_up(&trans(priv)->wait_command_queue); | ||
384 | |||
385 | if (!ondemand) { | ||
386 | /* | ||
387 | * If firmware keep reloading, then it indicate something | ||
388 | * serious wrong and firmware having problem to recover | ||
389 | * from it. Instead of keep trying which will fill the syslog | ||
390 | * and hang the system, let's just stop it | ||
391 | */ | ||
392 | reload_jiffies = jiffies; | ||
393 | reload_msec = jiffies_to_msecs((long) reload_jiffies - | ||
394 | (long) priv->reload_jiffies); | ||
395 | priv->reload_jiffies = reload_jiffies; | ||
396 | if (reload_msec <= IWL_MIN_RELOAD_DURATION) { | ||
397 | priv->reload_count++; | ||
398 | if (priv->reload_count >= IWL_MAX_CONTINUE_RELOAD_CNT) { | ||
399 | IWL_ERR(priv, "BUG_ON, Stop restarting\n"); | ||
400 | return; | ||
401 | } | ||
402 | } else | ||
403 | priv->reload_count = 0; | ||
404 | } | ||
405 | |||
406 | if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) { | ||
407 | if (iwlagn_mod_params.restart_fw) { | ||
408 | IWL_DEBUG_FW_ERRORS(priv, | ||
409 | "Restarting adapter due to uCode error.\n"); | ||
410 | queue_work(priv->workqueue, &priv->restart); | ||
411 | } else | ||
412 | IWL_DEBUG_FW_ERRORS(priv, | ||
413 | "Detected FW error, but not restarting\n"); | ||
414 | } | ||
415 | } | ||
416 | |||
417 | int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force) | ||
418 | { | ||
419 | int ret; | ||
420 | s8 prev_tx_power; | ||
421 | bool defer; | ||
422 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | ||
423 | |||
424 | lockdep_assert_held(&priv->mutex); | ||
425 | |||
426 | if (priv->tx_power_user_lmt == tx_power && !force) | ||
427 | return 0; | ||
428 | |||
429 | if (tx_power < IWLAGN_TX_POWER_TARGET_POWER_MIN) { | ||
430 | IWL_WARN(priv, | ||
431 | "Requested user TXPOWER %d below lower limit %d.\n", | ||
432 | tx_power, | ||
433 | IWLAGN_TX_POWER_TARGET_POWER_MIN); | ||
434 | return -EINVAL; | ||
435 | } | ||
436 | |||
437 | if (tx_power > priv->tx_power_device_lmt) { | ||
438 | IWL_WARN(priv, | ||
439 | "Requested user TXPOWER %d above upper limit %d.\n", | ||
440 | tx_power, priv->tx_power_device_lmt); | ||
441 | return -EINVAL; | ||
442 | } | ||
443 | |||
444 | if (!iwl_is_ready_rf(priv)) | ||
445 | return -EIO; | ||
446 | |||
447 | /* scan complete and commit_rxon use tx_power_next value, | ||
448 | * it always need to be updated for newest request */ | ||
449 | priv->tx_power_next = tx_power; | ||
450 | |||
451 | /* do not set tx power when scanning or channel changing */ | ||
452 | defer = test_bit(STATUS_SCANNING, &priv->status) || | ||
453 | memcmp(&ctx->active, &ctx->staging, sizeof(ctx->staging)); | ||
454 | if (defer && !force) { | ||
455 | IWL_DEBUG_INFO(priv, "Deferring tx power set\n"); | ||
456 | return 0; | ||
457 | } | ||
458 | |||
459 | prev_tx_power = priv->tx_power_user_lmt; | ||
460 | priv->tx_power_user_lmt = tx_power; | ||
461 | |||
462 | ret = iwlagn_send_tx_power(priv); | ||
463 | |||
464 | /* if fail to set tx_power, restore the orig. tx power */ | ||
465 | if (ret) { | ||
466 | priv->tx_power_user_lmt = prev_tx_power; | ||
467 | priv->tx_power_next = prev_tx_power; | ||
468 | } | ||
469 | return ret; | ||
470 | } | ||
471 | |||
472 | void iwl_send_bt_config(struct iwl_priv *priv) | ||
473 | { | ||
474 | struct iwl_bt_cmd bt_cmd = { | ||
475 | .lead_time = BT_LEAD_TIME_DEF, | ||
476 | .max_kill = BT_MAX_KILL_DEF, | ||
477 | .kill_ack_mask = 0, | ||
478 | .kill_cts_mask = 0, | ||
479 | }; | ||
480 | |||
481 | if (!iwlagn_mod_params.bt_coex_active) | ||
482 | bt_cmd.flags = BT_COEX_DISABLE; | ||
483 | else | ||
484 | bt_cmd.flags = BT_COEX_ENABLE; | ||
485 | |||
486 | priv->bt_enable_flag = bt_cmd.flags; | ||
487 | IWL_DEBUG_INFO(priv, "BT coex %s\n", | ||
488 | (bt_cmd.flags == BT_COEX_DISABLE) ? "disable" : "active"); | ||
489 | |||
490 | if (iwl_dvm_send_cmd_pdu(priv, REPLY_BT_CONFIG, | ||
491 | CMD_SYNC, sizeof(struct iwl_bt_cmd), &bt_cmd)) | ||
492 | IWL_ERR(priv, "failed to send BT Coex Config\n"); | ||
493 | } | ||
494 | |||
495 | int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags, bool clear) | ||
496 | { | ||
497 | struct iwl_statistics_cmd statistics_cmd = { | ||
498 | .configuration_flags = | ||
499 | clear ? IWL_STATS_CONF_CLEAR_STATS : 0, | ||
500 | }; | ||
501 | |||
502 | if (flags & CMD_ASYNC) | ||
503 | return iwl_dvm_send_cmd_pdu(priv, REPLY_STATISTICS_CMD, | ||
504 | CMD_ASYNC, | ||
505 | sizeof(struct iwl_statistics_cmd), | ||
506 | &statistics_cmd); | ||
507 | else | ||
508 | return iwl_dvm_send_cmd_pdu(priv, REPLY_STATISTICS_CMD, | ||
509 | CMD_SYNC, | ||
510 | sizeof(struct iwl_statistics_cmd), | ||
511 | &statistics_cmd); | ||
512 | } | ||
513 | |||
514 | |||
515 | 44 | ||
516 | 45 | ||
517 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 46 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
@@ -611,6 +140,7 @@ void iwl_dbg_log_rx_data_frame(struct iwl_priv *priv, | |||
611 | 140 | ||
612 | const char *get_mgmt_string(int cmd) | 141 | const char *get_mgmt_string(int cmd) |
613 | { | 142 | { |
143 | #define IWL_CMD(x) case x: return #x | ||
614 | switch (cmd) { | 144 | switch (cmd) { |
615 | IWL_CMD(MANAGEMENT_ASSOC_REQ); | 145 | IWL_CMD(MANAGEMENT_ASSOC_REQ); |
616 | IWL_CMD(MANAGEMENT_ASSOC_RESP); | 146 | IWL_CMD(MANAGEMENT_ASSOC_RESP); |
@@ -628,10 +158,12 @@ const char *get_mgmt_string(int cmd) | |||
628 | return "UNKNOWN"; | 158 | return "UNKNOWN"; |
629 | 159 | ||
630 | } | 160 | } |
161 | #undef IWL_CMD | ||
631 | } | 162 | } |
632 | 163 | ||
633 | const char *get_ctrl_string(int cmd) | 164 | const char *get_ctrl_string(int cmd) |
634 | { | 165 | { |
166 | #define IWL_CMD(x) case x: return #x | ||
635 | switch (cmd) { | 167 | switch (cmd) { |
636 | IWL_CMD(CONTROL_BACK_REQ); | 168 | IWL_CMD(CONTROL_BACK_REQ); |
637 | IWL_CMD(CONTROL_BACK); | 169 | IWL_CMD(CONTROL_BACK); |
@@ -645,6 +177,7 @@ const char *get_ctrl_string(int cmd) | |||
645 | return "UNKNOWN"; | 177 | return "UNKNOWN"; |
646 | 178 | ||
647 | } | 179 | } |
180 | #undef IWL_CMD | ||
648 | } | 181 | } |
649 | 182 | ||
650 | void iwl_clear_traffic_stats(struct iwl_priv *priv) | 183 | void iwl_clear_traffic_stats(struct iwl_priv *priv) |
@@ -746,80 +279,6 @@ void iwl_update_stats(struct iwl_priv *priv, bool is_tx, __le16 fc, u16 len) | |||
746 | } | 279 | } |
747 | #endif | 280 | #endif |
748 | 281 | ||
749 | static void iwl_force_rf_reset(struct iwl_priv *priv) | ||
750 | { | ||
751 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | ||
752 | return; | ||
753 | |||
754 | if (!iwl_is_any_associated(priv)) { | ||
755 | IWL_DEBUG_SCAN(priv, "force reset rejected: not associated\n"); | ||
756 | return; | ||
757 | } | ||
758 | /* | ||
759 | * There is no easy and better way to force reset the radio, | ||
760 | * the only known method is switching channel which will force to | ||
761 | * reset and tune the radio. | ||
762 | * Use internal short scan (single channel) operation to should | ||
763 | * achieve this objective. | ||
764 | * Driver should reset the radio when number of consecutive missed | ||
765 | * beacon, or any other uCode error condition detected. | ||
766 | */ | ||
767 | IWL_DEBUG_INFO(priv, "perform radio reset.\n"); | ||
768 | iwl_internal_short_hw_scan(priv); | ||
769 | } | ||
770 | |||
771 | |||
772 | int iwl_force_reset(struct iwl_priv *priv, int mode, bool external) | ||
773 | { | ||
774 | struct iwl_force_reset *force_reset; | ||
775 | |||
776 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | ||
777 | return -EINVAL; | ||
778 | |||
779 | if (mode >= IWL_MAX_FORCE_RESET) { | ||
780 | IWL_DEBUG_INFO(priv, "invalid reset request.\n"); | ||
781 | return -EINVAL; | ||
782 | } | ||
783 | force_reset = &priv->force_reset[mode]; | ||
784 | force_reset->reset_request_count++; | ||
785 | if (!external) { | ||
786 | if (force_reset->last_force_reset_jiffies && | ||
787 | time_after(force_reset->last_force_reset_jiffies + | ||
788 | force_reset->reset_duration, jiffies)) { | ||
789 | IWL_DEBUG_INFO(priv, "force reset rejected\n"); | ||
790 | force_reset->reset_reject_count++; | ||
791 | return -EAGAIN; | ||
792 | } | ||
793 | } | ||
794 | force_reset->reset_success_count++; | ||
795 | force_reset->last_force_reset_jiffies = jiffies; | ||
796 | IWL_DEBUG_INFO(priv, "perform force reset (%d)\n", mode); | ||
797 | switch (mode) { | ||
798 | case IWL_RF_RESET: | ||
799 | iwl_force_rf_reset(priv); | ||
800 | break; | ||
801 | case IWL_FW_RESET: | ||
802 | /* | ||
803 | * if the request is from external(ex: debugfs), | ||
804 | * then always perform the request in regardless the module | ||
805 | * parameter setting | ||
806 | * if the request is from internal (uCode error or driver | ||
807 | * detect failure), then fw_restart module parameter | ||
808 | * need to be check before performing firmware reload | ||
809 | */ | ||
810 | if (!external && !iwlagn_mod_params.restart_fw) { | ||
811 | IWL_DEBUG_INFO(priv, "Cancel firmware reload based on " | ||
812 | "module parameter setting\n"); | ||
813 | break; | ||
814 | } | ||
815 | IWL_ERR(priv, "On demand firmware reload\n"); | ||
816 | iwlagn_fw_error(priv, true); | ||
817 | break; | ||
818 | } | ||
819 | return 0; | ||
820 | } | ||
821 | |||
822 | |||
823 | int iwl_cmd_echo_test(struct iwl_priv *priv) | 282 | int iwl_cmd_echo_test(struct iwl_priv *priv) |
824 | { | 283 | { |
825 | int ret; | 284 | int ret; |
@@ -836,165 +295,3 @@ int iwl_cmd_echo_test(struct iwl_priv *priv) | |||
836 | IWL_DEBUG_INFO(priv, "echo testing pass\n"); | 295 | IWL_DEBUG_INFO(priv, "echo testing pass\n"); |
837 | return ret; | 296 | return ret; |
838 | } | 297 | } |
839 | |||
840 | static inline int iwl_check_stuck_queue(struct iwl_priv *priv, int txq) | ||
841 | { | ||
842 | if (iwl_trans_check_stuck_queue(trans(priv), txq)) { | ||
843 | int ret; | ||
844 | ret = iwl_force_reset(priv, IWL_FW_RESET, false); | ||
845 | return (ret == -EAGAIN) ? 0 : 1; | ||
846 | } | ||
847 | return 0; | ||
848 | } | ||
849 | |||
850 | /* | ||
851 | * Making watchdog tick be a quarter of timeout assure we will | ||
852 | * discover the queue hung between timeout and 1.25*timeout | ||
853 | */ | ||
854 | #define IWL_WD_TICK(timeout) ((timeout) / 4) | ||
855 | |||
856 | /* | ||
857 | * Watchdog timer callback, we check each tx queue for stuck, if if hung | ||
858 | * we reset the firmware. If everything is fine just rearm the timer. | ||
859 | */ | ||
860 | void iwl_bg_watchdog(unsigned long data) | ||
861 | { | ||
862 | struct iwl_priv *priv = (struct iwl_priv *)data; | ||
863 | int cnt; | ||
864 | unsigned long timeout; | ||
865 | |||
866 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | ||
867 | return; | ||
868 | |||
869 | if (iwl_is_rfkill(priv)) | ||
870 | return; | ||
871 | |||
872 | timeout = hw_params(priv).wd_timeout; | ||
873 | if (timeout == 0) | ||
874 | return; | ||
875 | |||
876 | /* monitor and check for stuck queues */ | ||
877 | for (cnt = 0; cnt < cfg(priv)->base_params->num_of_queues; cnt++) | ||
878 | if (iwl_check_stuck_queue(priv, cnt)) | ||
879 | return; | ||
880 | |||
881 | mod_timer(&priv->watchdog, jiffies + | ||
882 | msecs_to_jiffies(IWL_WD_TICK(timeout))); | ||
883 | } | ||
884 | |||
885 | void iwl_setup_watchdog(struct iwl_priv *priv) | ||
886 | { | ||
887 | unsigned int timeout = hw_params(priv).wd_timeout; | ||
888 | |||
889 | if (!iwlagn_mod_params.wd_disable) { | ||
890 | /* use system default */ | ||
891 | if (timeout && !cfg(priv)->base_params->wd_disable) | ||
892 | mod_timer(&priv->watchdog, | ||
893 | jiffies + | ||
894 | msecs_to_jiffies(IWL_WD_TICK(timeout))); | ||
895 | else | ||
896 | del_timer(&priv->watchdog); | ||
897 | } else { | ||
898 | /* module parameter overwrite default configuration */ | ||
899 | if (timeout && iwlagn_mod_params.wd_disable == 2) | ||
900 | mod_timer(&priv->watchdog, | ||
901 | jiffies + | ||
902 | msecs_to_jiffies(IWL_WD_TICK(timeout))); | ||
903 | else | ||
904 | del_timer(&priv->watchdog); | ||
905 | } | ||
906 | } | ||
907 | |||
908 | /** | ||
909 | * iwl_beacon_time_mask_low - mask of lower 32 bit of beacon time | ||
910 | * @priv -- pointer to iwl_priv data structure | ||
911 | * @tsf_bits -- number of bits need to shift for masking) | ||
912 | */ | ||
913 | static inline u32 iwl_beacon_time_mask_low(struct iwl_priv *priv, | ||
914 | u16 tsf_bits) | ||
915 | { | ||
916 | return (1 << tsf_bits) - 1; | ||
917 | } | ||
918 | |||
919 | /** | ||
920 | * iwl_beacon_time_mask_high - mask of higher 32 bit of beacon time | ||
921 | * @priv -- pointer to iwl_priv data structure | ||
922 | * @tsf_bits -- number of bits need to shift for masking) | ||
923 | */ | ||
924 | static inline u32 iwl_beacon_time_mask_high(struct iwl_priv *priv, | ||
925 | u16 tsf_bits) | ||
926 | { | ||
927 | return ((1 << (32 - tsf_bits)) - 1) << tsf_bits; | ||
928 | } | ||
929 | |||
930 | /* | ||
931 | * extended beacon time format | ||
932 | * time in usec will be changed into a 32-bit value in extended:internal format | ||
933 | * the extended part is the beacon counts | ||
934 | * the internal part is the time in usec within one beacon interval | ||
935 | */ | ||
936 | u32 iwl_usecs_to_beacons(struct iwl_priv *priv, u32 usec, u32 beacon_interval) | ||
937 | { | ||
938 | u32 quot; | ||
939 | u32 rem; | ||
940 | u32 interval = beacon_interval * TIME_UNIT; | ||
941 | |||
942 | if (!interval || !usec) | ||
943 | return 0; | ||
944 | |||
945 | quot = (usec / interval) & | ||
946 | (iwl_beacon_time_mask_high(priv, IWLAGN_EXT_BEACON_TIME_POS) >> | ||
947 | IWLAGN_EXT_BEACON_TIME_POS); | ||
948 | rem = (usec % interval) & iwl_beacon_time_mask_low(priv, | ||
949 | IWLAGN_EXT_BEACON_TIME_POS); | ||
950 | |||
951 | return (quot << IWLAGN_EXT_BEACON_TIME_POS) + rem; | ||
952 | } | ||
953 | |||
954 | /* base is usually what we get from ucode with each received frame, | ||
955 | * the same as HW timer counter counting down | ||
956 | */ | ||
957 | __le32 iwl_add_beacon_time(struct iwl_priv *priv, u32 base, | ||
958 | u32 addon, u32 beacon_interval) | ||
959 | { | ||
960 | u32 base_low = base & iwl_beacon_time_mask_low(priv, | ||
961 | IWLAGN_EXT_BEACON_TIME_POS); | ||
962 | u32 addon_low = addon & iwl_beacon_time_mask_low(priv, | ||
963 | IWLAGN_EXT_BEACON_TIME_POS); | ||
964 | u32 interval = beacon_interval * TIME_UNIT; | ||
965 | u32 res = (base & iwl_beacon_time_mask_high(priv, | ||
966 | IWLAGN_EXT_BEACON_TIME_POS)) + | ||
967 | (addon & iwl_beacon_time_mask_high(priv, | ||
968 | IWLAGN_EXT_BEACON_TIME_POS)); | ||
969 | |||
970 | if (base_low > addon_low) | ||
971 | res += base_low - addon_low; | ||
972 | else if (base_low < addon_low) { | ||
973 | res += interval + base_low - addon_low; | ||
974 | res += (1 << IWLAGN_EXT_BEACON_TIME_POS); | ||
975 | } else | ||
976 | res += (1 << IWLAGN_EXT_BEACON_TIME_POS); | ||
977 | |||
978 | return cpu_to_le32(res); | ||
979 | } | ||
980 | |||
981 | void iwl_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state) | ||
982 | { | ||
983 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); | ||
984 | |||
985 | if (state) | ||
986 | set_bit(STATUS_RF_KILL_HW, &priv->status); | ||
987 | else | ||
988 | clear_bit(STATUS_RF_KILL_HW, &priv->status); | ||
989 | |||
990 | wiphy_rfkill_set_hw_state(priv->hw->wiphy, state); | ||
991 | } | ||
992 | |||
993 | void iwl_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb) | ||
994 | { | ||
995 | struct ieee80211_tx_info *info; | ||
996 | |||
997 | info = IEEE80211_SKB_CB(skb); | ||
998 | kmem_cache_free(iwl_tx_cmd_pool, (info->driver_data[1])); | ||
999 | dev_kfree_skb_any(skb); | ||
1000 | } | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 7aa3060fc6b5..199a0c03774c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h | |||
@@ -74,38 +74,10 @@ struct iwl_cmd; | |||
74 | 74 | ||
75 | #define TIME_UNIT 1024 | 75 | #define TIME_UNIT 1024 |
76 | 76 | ||
77 | struct 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 | ***************************/ |
95 | 80 | ||
96 | void iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch, | ||
97 | struct iwl_rxon_context *ctx); | ||
98 | void iwl_set_flags_for_band(struct iwl_priv *priv, | ||
99 | struct iwl_rxon_context *ctx, | ||
100 | enum ieee80211_band band, | ||
101 | struct ieee80211_vif *vif); | ||
102 | void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_config *ht_conf); | ||
103 | bool iwl_is_ht40_tx_allowed(struct iwl_priv *priv, | ||
104 | struct iwl_rxon_context *ctx, | ||
105 | struct ieee80211_sta_ht_cap *ht_cap); | ||
106 | void iwl_connection_init_rx_config(struct iwl_priv *priv, | ||
107 | struct iwl_rxon_context *ctx); | ||
108 | void iwl_set_rate(struct iwl_priv *priv); | ||
109 | int iwl_cmd_echo_test(struct iwl_priv *priv); | 81 | int iwl_cmd_echo_test(struct iwl_priv *priv); |
110 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 82 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
111 | int iwl_alloc_traffic_mem(struct iwl_priv *priv); | 83 | int iwl_alloc_traffic_mem(struct iwl_priv *priv); |
@@ -146,45 +118,9 @@ static inline void iwl_update_stats(struct iwl_priv *priv, bool is_tx, | |||
146 | } | 118 | } |
147 | #endif | 119 | #endif |
148 | 120 | ||
149 | /***************************************************** | ||
150 | * RX | ||
151 | ******************************************************/ | ||
152 | void iwl_chswitch_done(struct iwl_priv *priv, bool is_success); | ||
153 | |||
154 | void iwl_setup_watchdog(struct iwl_priv *priv); | ||
155 | /***************************************************** | ||
156 | * TX power | ||
157 | ****************************************************/ | ||
158 | int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force); | ||
159 | |||
160 | /******************************************************************************* | 121 | /******************************************************************************* |
161 | * Scanning | 122 | * Scanning |
162 | ******************************************************************************/ | 123 | ******************************************************************************/ |
163 | void iwl_init_scan_params(struct iwl_priv *priv); | ||
164 | int iwl_scan_cancel(struct iwl_priv *priv); | ||
165 | void iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms); | ||
166 | void iwl_force_scan_end(struct iwl_priv *priv); | ||
167 | void iwl_internal_short_hw_scan(struct iwl_priv *priv); | ||
168 | int iwl_force_reset(struct iwl_priv *priv, int mode, bool external); | ||
169 | void iwl_setup_rx_scan_handlers(struct iwl_priv *priv); | ||
170 | void iwl_setup_scan_deferred_work(struct iwl_priv *priv); | ||
171 | void iwl_cancel_scan_deferred_work(struct iwl_priv *priv); | ||
172 | int __must_check iwl_scan_initiate(struct iwl_priv *priv, | ||
173 | struct ieee80211_vif *vif, | ||
174 | enum iwl_scan_type scan_type, | ||
175 | enum ieee80211_band band); | ||
176 | |||
177 | /* For faster active scanning, scan will move to the next channel if fewer than | ||
178 | * PLCP_QUIET_THRESH packets are heard on this channel within | ||
179 | * ACTIVE_QUIET_TIME after sending probe request. This shortens the dwell | ||
180 | * time if it's a quiet channel (nothing responded to our probe, and there's | ||
181 | * no other traffic). | ||
182 | * Disable "quiet" feature by setting PLCP_QUIET_THRESH to 0. */ | ||
183 | #define IWL_ACTIVE_QUIET_TIME cpu_to_le16(10) /* msec */ | ||
184 | #define IWL_PLCP_QUIET_THRESH cpu_to_le16(1) /* packets */ | ||
185 | |||
186 | #define IWL_SCAN_CHECK_WATCHDOG (HZ * 7) | ||
187 | |||
188 | /* traffic log definitions */ | 124 | /* traffic log definitions */ |
189 | #define IWL_TRAFFIC_ENTRIES (256) | 125 | #define IWL_TRAFFIC_ENTRIES (256) |
190 | #define IWL_TRAFFIC_ENTRY_SIZE (64) | 126 | #define IWL_TRAFFIC_ENTRY_SIZE (64) |
@@ -192,28 +128,6 @@ int __must_check iwl_scan_initiate(struct iwl_priv *priv, | |||
192 | /***************************************************** | 128 | /***************************************************** |
193 | * S e n d i n g H o s t C o m m a n d s * | 129 | * S e n d i n g H o s t C o m m a n d s * |
194 | *****************************************************/ | 130 | *****************************************************/ |
195 | |||
196 | void iwl_bg_watchdog(unsigned long data); | ||
197 | u32 iwl_usecs_to_beacons(struct iwl_priv *priv, u32 usec, u32 beacon_interval); | ||
198 | __le32 iwl_add_beacon_time(struct iwl_priv *priv, u32 base, | ||
199 | u32 addon, u32 beacon_interval); | ||
200 | |||
201 | extern void iwl_send_bt_config(struct iwl_priv *priv); | ||
202 | extern int iwl_send_statistics_request(struct iwl_priv *priv, | ||
203 | u8 flags, bool clear); | ||
204 | |||
205 | static inline const struct ieee80211_supported_band *iwl_get_hw_mode( | ||
206 | struct iwl_priv *priv, enum ieee80211_band band) | ||
207 | { | ||
208 | return priv->hw->wiphy->bands[band]; | ||
209 | } | ||
210 | |||
211 | static inline bool iwl_advanced_bt_coexist(struct iwl_priv *priv) | ||
212 | { | ||
213 | return cfg(priv)->bt_params && | ||
214 | cfg(priv)->bt_params->advanced_bt_coexist; | ||
215 | } | ||
216 | |||
217 | extern bool bt_siso_mode; | 131 | extern bool bt_siso_mode; |
218 | 132 | ||
219 | #endif /* __iwl_core_h__ */ | 133 | #endif /* __iwl_core_h__ */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h index 5f96ce105f08..59750543fce7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-csr.h +++ b/drivers/net/wireless/iwlwifi/iwl-csr.h | |||
@@ -430,6 +430,9 @@ | |||
430 | #define HBUS_TARG_PRPH_WDAT (HBUS_BASE+0x04c) | 430 | #define HBUS_TARG_PRPH_WDAT (HBUS_BASE+0x04c) |
431 | #define HBUS_TARG_PRPH_RDAT (HBUS_BASE+0x050) | 431 | #define HBUS_TARG_PRPH_RDAT (HBUS_BASE+0x050) |
432 | 432 | ||
433 | /* Used to enable DBGM */ | ||
434 | #define HBUS_TARG_TEST_REG (HBUS_BASE+0x05c) | ||
435 | |||
433 | /* | 436 | /* |
434 | * Per-Tx-queue write pointer (index, really!) | 437 | * Per-Tx-queue write pointer (index, really!) |
435 | * Indicates index to next TFD that driver will fill (1 past latest filled). | 438 | * Indicates index to next TFD that driver will fill (1 past latest filled). |
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index d109d1bbb3a2..32834a797d11 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c | |||
@@ -416,7 +416,7 @@ static ssize_t iwl_dbgfs_nvm_read(struct file *file, | |||
416 | return -ENODATA; | 416 | return -ENODATA; |
417 | } | 417 | } |
418 | 418 | ||
419 | ptr = priv->shrd->eeprom; | 419 | ptr = priv->eeprom; |
420 | if (!ptr) { | 420 | if (!ptr) { |
421 | IWL_ERR(priv, "Invalid EEPROM/OTP memory\n"); | 421 | IWL_ERR(priv, "Invalid EEPROM/OTP memory\n"); |
422 | return -ENOMEM; | 422 | return -ENOMEM; |
@@ -428,10 +428,10 @@ static ssize_t iwl_dbgfs_nvm_read(struct file *file, | |||
428 | IWL_ERR(priv, "Can not allocate Buffer\n"); | 428 | IWL_ERR(priv, "Can not allocate Buffer\n"); |
429 | return -ENOMEM; | 429 | return -ENOMEM; |
430 | } | 430 | } |
431 | eeprom_ver = iwl_eeprom_query16(priv->shrd, EEPROM_VERSION); | 431 | eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION); |
432 | pos += scnprintf(buf + pos, buf_size - pos, "NVM Type: %s, " | 432 | pos += scnprintf(buf + pos, buf_size - pos, "NVM Type: %s, " |
433 | "version: 0x%x\n", | 433 | "version: 0x%x\n", |
434 | (trans(priv)->nvm_device_type == NVM_DEVICE_TYPE_OTP) | 434 | (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP) |
435 | ? "OTP" : "EEPROM", eeprom_ver); | 435 | ? "OTP" : "EEPROM", eeprom_ver); |
436 | for (ofs = 0 ; ofs < eeprom_len ; ofs += 16) { | 436 | for (ofs = 0 ; ofs < eeprom_len ; ofs += 16) { |
437 | pos += scnprintf(buf + pos, buf_size - pos, "0x%.4x ", ofs); | 437 | pos += scnprintf(buf + pos, buf_size - pos, "0x%.4x ", ofs); |
@@ -526,8 +526,6 @@ static ssize_t iwl_dbgfs_status_read(struct file *file, | |||
526 | int pos = 0; | 526 | int pos = 0; |
527 | const size_t bufsz = sizeof(buf); | 527 | const size_t bufsz = sizeof(buf); |
528 | 528 | ||
529 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_HCMD_ACTIVE:\t %d\n", | ||
530 | test_bit(STATUS_HCMD_ACTIVE, &priv->shrd->status)); | ||
531 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_RF_KILL_HW:\t %d\n", | 529 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_RF_KILL_HW:\t %d\n", |
532 | test_bit(STATUS_RF_KILL_HW, &priv->status)); | 530 | test_bit(STATUS_RF_KILL_HW, &priv->status)); |
533 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_CT_KILL:\t\t %d\n", | 531 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_CT_KILL:\t\t %d\n", |
@@ -577,7 +575,7 @@ static ssize_t iwl_dbgfs_rx_handlers_read(struct file *file, | |||
577 | if (priv->rx_handlers_stats[cnt] > 0) | 575 | if (priv->rx_handlers_stats[cnt] > 0) |
578 | pos += scnprintf(buf + pos, bufsz - pos, | 576 | pos += scnprintf(buf + pos, bufsz - pos, |
579 | "\tRx handler[%36s]:\t\t %u\n", | 577 | "\tRx handler[%36s]:\t\t %u\n", |
580 | get_cmd_string(cnt), | 578 | iwl_dvm_get_cmd_string(cnt), |
581 | priv->rx_handlers_stats[cnt]); | 579 | priv->rx_handlers_stats[cnt]); |
582 | } | 580 | } |
583 | 581 | ||
@@ -1541,17 +1539,17 @@ static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file, | |||
1541 | if (tx->tx_power.ant_a || tx->tx_power.ant_b || tx->tx_power.ant_c) { | 1539 | if (tx->tx_power.ant_a || tx->tx_power.ant_b || tx->tx_power.ant_c) { |
1542 | pos += scnprintf(buf + pos, bufsz - pos, | 1540 | pos += scnprintf(buf + pos, bufsz - pos, |
1543 | "tx power: (1/2 dB step)\n"); | 1541 | "tx power: (1/2 dB step)\n"); |
1544 | if ((hw_params(priv).valid_tx_ant & ANT_A) && | 1542 | if ((priv->hw_params.valid_tx_ant & ANT_A) && |
1545 | tx->tx_power.ant_a) | 1543 | tx->tx_power.ant_a) |
1546 | pos += scnprintf(buf + pos, bufsz - pos, | 1544 | pos += scnprintf(buf + pos, bufsz - pos, |
1547 | fmt_hex, "antenna A:", | 1545 | fmt_hex, "antenna A:", |
1548 | tx->tx_power.ant_a); | 1546 | tx->tx_power.ant_a); |
1549 | if ((hw_params(priv).valid_tx_ant & ANT_B) && | 1547 | if ((priv->hw_params.valid_tx_ant & ANT_B) && |
1550 | tx->tx_power.ant_b) | 1548 | tx->tx_power.ant_b) |
1551 | pos += scnprintf(buf + pos, bufsz - pos, | 1549 | pos += scnprintf(buf + pos, bufsz - pos, |
1552 | fmt_hex, "antenna B:", | 1550 | fmt_hex, "antenna B:", |
1553 | tx->tx_power.ant_b); | 1551 | tx->tx_power.ant_b); |
1554 | if ((hw_params(priv).valid_tx_ant & ANT_C) && | 1552 | if ((priv->hw_params.valid_tx_ant & ANT_C) && |
1555 | tx->tx_power.ant_c) | 1553 | tx->tx_power.ant_c) |
1556 | pos += scnprintf(buf + pos, bufsz - pos, | 1554 | pos += scnprintf(buf + pos, bufsz - pos, |
1557 | fmt_hex, "antenna C:", | 1555 | fmt_hex, "antenna C:", |
@@ -2267,59 +2265,39 @@ static ssize_t iwl_dbgfs_plcp_delta_write(struct file *file, | |||
2267 | return count; | 2265 | return count; |
2268 | } | 2266 | } |
2269 | 2267 | ||
2270 | static ssize_t iwl_dbgfs_force_reset_read(struct file *file, | 2268 | static ssize_t iwl_dbgfs_rf_reset_read(struct file *file, |
2271 | char __user *user_buf, | 2269 | char __user *user_buf, |
2272 | size_t count, loff_t *ppos) | 2270 | size_t count, loff_t *ppos) |
2273 | { | 2271 | { |
2274 | struct iwl_priv *priv = file->private_data; | 2272 | struct iwl_priv *priv = file->private_data; |
2275 | int i, pos = 0; | 2273 | int pos = 0; |
2276 | char buf[300]; | 2274 | char buf[300]; |
2277 | const size_t bufsz = sizeof(buf); | 2275 | const size_t bufsz = sizeof(buf); |
2278 | struct iwl_force_reset *force_reset; | 2276 | struct iwl_rf_reset *rf_reset = &priv->rf_reset; |
2277 | |||
2278 | pos += scnprintf(buf + pos, bufsz - pos, | ||
2279 | "RF reset statistics\n"); | ||
2280 | pos += scnprintf(buf + pos, bufsz - pos, | ||
2281 | "\tnumber of reset request: %d\n", | ||
2282 | rf_reset->reset_request_count); | ||
2283 | pos += scnprintf(buf + pos, bufsz - pos, | ||
2284 | "\tnumber of reset request success: %d\n", | ||
2285 | rf_reset->reset_success_count); | ||
2286 | pos += scnprintf(buf + pos, bufsz - pos, | ||
2287 | "\tnumber of reset request reject: %d\n", | ||
2288 | rf_reset->reset_reject_count); | ||
2279 | 2289 | ||
2280 | for (i = 0; i < IWL_MAX_FORCE_RESET; i++) { | ||
2281 | force_reset = &priv->force_reset[i]; | ||
2282 | pos += scnprintf(buf + pos, bufsz - pos, | ||
2283 | "Force reset method %d\n", i); | ||
2284 | pos += scnprintf(buf + pos, bufsz - pos, | ||
2285 | "\tnumber of reset request: %d\n", | ||
2286 | force_reset->reset_request_count); | ||
2287 | pos += scnprintf(buf + pos, bufsz - pos, | ||
2288 | "\tnumber of reset request success: %d\n", | ||
2289 | force_reset->reset_success_count); | ||
2290 | pos += scnprintf(buf + pos, bufsz - pos, | ||
2291 | "\tnumber of reset request reject: %d\n", | ||
2292 | force_reset->reset_reject_count); | ||
2293 | pos += scnprintf(buf + pos, bufsz - pos, | ||
2294 | "\treset duration: %lu\n", | ||
2295 | force_reset->reset_duration); | ||
2296 | } | ||
2297 | return simple_read_from_buffer(user_buf, count, ppos, buf, pos); | 2290 | return simple_read_from_buffer(user_buf, count, ppos, buf, pos); |
2298 | } | 2291 | } |
2299 | 2292 | ||
2300 | static ssize_t iwl_dbgfs_force_reset_write(struct file *file, | 2293 | static ssize_t iwl_dbgfs_rf_reset_write(struct file *file, |
2301 | const char __user *user_buf, | 2294 | const char __user *user_buf, |
2302 | size_t count, loff_t *ppos) { | 2295 | size_t count, loff_t *ppos) { |
2303 | 2296 | ||
2304 | struct iwl_priv *priv = file->private_data; | 2297 | struct iwl_priv *priv = file->private_data; |
2305 | char buf[8]; | 2298 | int ret; |
2306 | int buf_size; | ||
2307 | int reset, ret; | ||
2308 | 2299 | ||
2309 | memset(buf, 0, sizeof(buf)); | 2300 | ret = iwl_force_rf_reset(priv, true); |
2310 | buf_size = min(count, sizeof(buf) - 1); | ||
2311 | if (copy_from_user(buf, user_buf, buf_size)) | ||
2312 | return -EFAULT; | ||
2313 | if (sscanf(buf, "%d", &reset) != 1) | ||
2314 | return -EINVAL; | ||
2315 | switch (reset) { | ||
2316 | case IWL_RF_RESET: | ||
2317 | case IWL_FW_RESET: | ||
2318 | ret = iwl_force_reset(priv, reset, true); | ||
2319 | break; | ||
2320 | default: | ||
2321 | return -EINVAL; | ||
2322 | } | ||
2323 | return ret ? ret : count; | 2301 | return ret ? ret : count; |
2324 | } | 2302 | } |
2325 | 2303 | ||
@@ -2347,29 +2325,6 @@ static ssize_t iwl_dbgfs_txfifo_flush_write(struct file *file, | |||
2347 | return count; | 2325 | return count; |
2348 | } | 2326 | } |
2349 | 2327 | ||
2350 | static ssize_t iwl_dbgfs_wd_timeout_write(struct file *file, | ||
2351 | const char __user *user_buf, | ||
2352 | size_t count, loff_t *ppos) | ||
2353 | { | ||
2354 | struct iwl_priv *priv = file->private_data; | ||
2355 | char buf[8]; | ||
2356 | int buf_size; | ||
2357 | int timeout; | ||
2358 | |||
2359 | memset(buf, 0, sizeof(buf)); | ||
2360 | buf_size = min(count, sizeof(buf) - 1); | ||
2361 | if (copy_from_user(buf, user_buf, buf_size)) | ||
2362 | return -EFAULT; | ||
2363 | if (sscanf(buf, "%d", &timeout) != 1) | ||
2364 | return -EINVAL; | ||
2365 | if (timeout < 0 || timeout > IWL_MAX_WD_TIMEOUT) | ||
2366 | timeout = IWL_DEF_WD_TIMEOUT; | ||
2367 | |||
2368 | hw_params(priv).wd_timeout = timeout; | ||
2369 | iwl_setup_watchdog(priv); | ||
2370 | return count; | ||
2371 | } | ||
2372 | |||
2373 | static ssize_t iwl_dbgfs_bt_traffic_read(struct file *file, | 2328 | static ssize_t iwl_dbgfs_bt_traffic_read(struct file *file, |
2374 | char __user *user_buf, | 2329 | char __user *user_buf, |
2375 | size_t count, loff_t *ppos) { | 2330 | size_t count, loff_t *ppos) { |
@@ -2428,7 +2383,7 @@ static ssize_t iwl_dbgfs_protection_mode_read(struct file *file, | |||
2428 | if (cfg(priv)->ht_params) | 2383 | if (cfg(priv)->ht_params) |
2429 | pos += scnprintf(buf + pos, bufsz - pos, | 2384 | pos += scnprintf(buf + pos, bufsz - pos, |
2430 | "use %s for aggregation\n", | 2385 | "use %s for aggregation\n", |
2431 | (hw_params(priv).use_rts_for_aggregation) ? | 2386 | (priv->hw_params.use_rts_for_aggregation) ? |
2432 | "rts/cts" : "cts-to-self"); | 2387 | "rts/cts" : "cts-to-self"); |
2433 | else | 2388 | else |
2434 | pos += scnprintf(buf + pos, bufsz - pos, "N/A"); | 2389 | pos += scnprintf(buf + pos, bufsz - pos, "N/A"); |
@@ -2455,9 +2410,9 @@ static ssize_t iwl_dbgfs_protection_mode_write(struct file *file, | |||
2455 | if (sscanf(buf, "%d", &rts) != 1) | 2410 | if (sscanf(buf, "%d", &rts) != 1) |
2456 | return -EINVAL; | 2411 | return -EINVAL; |
2457 | if (rts) | 2412 | if (rts) |
2458 | hw_params(priv).use_rts_for_aggregation = true; | 2413 | priv->hw_params.use_rts_for_aggregation = true; |
2459 | else | 2414 | else |
2460 | hw_params(priv).use_rts_for_aggregation = false; | 2415 | priv->hw_params.use_rts_for_aggregation = false; |
2461 | return count; | 2416 | return count; |
2462 | } | 2417 | } |
2463 | 2418 | ||
@@ -2516,6 +2471,34 @@ static ssize_t iwl_dbgfs_log_event_write(struct file *file, | |||
2516 | return count; | 2471 | return count; |
2517 | } | 2472 | } |
2518 | 2473 | ||
2474 | static ssize_t iwl_dbgfs_calib_disabled_read(struct file *file, | ||
2475 | char __user *user_buf, | ||
2476 | size_t count, loff_t *ppos) | ||
2477 | { | ||
2478 | struct iwl_priv *priv = file->private_data; | ||
2479 | char buf[120]; | ||
2480 | int pos = 0; | ||
2481 | const size_t bufsz = sizeof(buf); | ||
2482 | |||
2483 | pos += scnprintf(buf + pos, bufsz - pos, | ||
2484 | "Sensitivity calibrations %s\n", | ||
2485 | (priv->calib_disabled & | ||
2486 | IWL_SENSITIVITY_CALIB_DISABLED) ? | ||
2487 | "DISABLED" : "ENABLED"); | ||
2488 | pos += scnprintf(buf + pos, bufsz - pos, | ||
2489 | "Chain noise calibrations %s\n", | ||
2490 | (priv->calib_disabled & | ||
2491 | IWL_CHAIN_NOISE_CALIB_DISABLED) ? | ||
2492 | "DISABLED" : "ENABLED"); | ||
2493 | pos += scnprintf(buf + pos, bufsz - pos, | ||
2494 | "Tx power calibrations %s\n", | ||
2495 | (priv->calib_disabled & | ||
2496 | IWL_TX_POWER_CALIB_DISABLED) ? | ||
2497 | "DISABLED" : "ENABLED"); | ||
2498 | |||
2499 | return simple_read_from_buffer(user_buf, count, ppos, buf, pos); | ||
2500 | } | ||
2501 | |||
2519 | DEBUGFS_READ_FILE_OPS(rx_statistics); | 2502 | DEBUGFS_READ_FILE_OPS(rx_statistics); |
2520 | DEBUGFS_READ_FILE_OPS(tx_statistics); | 2503 | DEBUGFS_READ_FILE_OPS(tx_statistics); |
2521 | DEBUGFS_READ_WRITE_FILE_OPS(traffic_log); | 2504 | DEBUGFS_READ_WRITE_FILE_OPS(traffic_log); |
@@ -2530,17 +2513,17 @@ DEBUGFS_WRITE_FILE_OPS(clear_traffic_statistics); | |||
2530 | DEBUGFS_READ_WRITE_FILE_OPS(ucode_tracing); | 2513 | DEBUGFS_READ_WRITE_FILE_OPS(ucode_tracing); |
2531 | DEBUGFS_READ_WRITE_FILE_OPS(missed_beacon); | 2514 | DEBUGFS_READ_WRITE_FILE_OPS(missed_beacon); |
2532 | DEBUGFS_READ_WRITE_FILE_OPS(plcp_delta); | 2515 | DEBUGFS_READ_WRITE_FILE_OPS(plcp_delta); |
2533 | DEBUGFS_READ_WRITE_FILE_OPS(force_reset); | 2516 | DEBUGFS_READ_WRITE_FILE_OPS(rf_reset); |
2534 | DEBUGFS_READ_FILE_OPS(rxon_flags); | 2517 | DEBUGFS_READ_FILE_OPS(rxon_flags); |
2535 | DEBUGFS_READ_FILE_OPS(rxon_filter_flags); | 2518 | DEBUGFS_READ_FILE_OPS(rxon_filter_flags); |
2536 | DEBUGFS_WRITE_FILE_OPS(txfifo_flush); | 2519 | DEBUGFS_WRITE_FILE_OPS(txfifo_flush); |
2537 | DEBUGFS_READ_FILE_OPS(ucode_bt_stats); | 2520 | DEBUGFS_READ_FILE_OPS(ucode_bt_stats); |
2538 | DEBUGFS_WRITE_FILE_OPS(wd_timeout); | ||
2539 | DEBUGFS_READ_FILE_OPS(bt_traffic); | 2521 | DEBUGFS_READ_FILE_OPS(bt_traffic); |
2540 | DEBUGFS_READ_WRITE_FILE_OPS(protection_mode); | 2522 | DEBUGFS_READ_WRITE_FILE_OPS(protection_mode); |
2541 | DEBUGFS_READ_FILE_OPS(reply_tx_error); | 2523 | DEBUGFS_READ_FILE_OPS(reply_tx_error); |
2542 | DEBUGFS_WRITE_FILE_OPS(echo_test); | 2524 | DEBUGFS_WRITE_FILE_OPS(echo_test); |
2543 | DEBUGFS_READ_WRITE_FILE_OPS(log_event); | 2525 | DEBUGFS_READ_WRITE_FILE_OPS(log_event); |
2526 | DEBUGFS_READ_FILE_OPS(calib_disabled); | ||
2544 | 2527 | ||
2545 | /* | 2528 | /* |
2546 | * Create the debugfs files and directories | 2529 | * Create the debugfs files and directories |
@@ -2589,7 +2572,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) | |||
2589 | DEBUGFS_ADD_FILE(clear_traffic_statistics, dir_debug, S_IWUSR); | 2572 | DEBUGFS_ADD_FILE(clear_traffic_statistics, dir_debug, S_IWUSR); |
2590 | DEBUGFS_ADD_FILE(missed_beacon, dir_debug, S_IWUSR); | 2573 | DEBUGFS_ADD_FILE(missed_beacon, dir_debug, S_IWUSR); |
2591 | DEBUGFS_ADD_FILE(plcp_delta, dir_debug, S_IWUSR | S_IRUSR); | 2574 | DEBUGFS_ADD_FILE(plcp_delta, dir_debug, S_IWUSR | S_IRUSR); |
2592 | DEBUGFS_ADD_FILE(force_reset, dir_debug, S_IWUSR | S_IRUSR); | 2575 | DEBUGFS_ADD_FILE(rf_reset, dir_debug, S_IWUSR | S_IRUSR); |
2593 | DEBUGFS_ADD_FILE(ucode_rx_stats, dir_debug, S_IRUSR); | 2576 | DEBUGFS_ADD_FILE(ucode_rx_stats, dir_debug, S_IRUSR); |
2594 | DEBUGFS_ADD_FILE(ucode_tx_stats, dir_debug, S_IRUSR); | 2577 | DEBUGFS_ADD_FILE(ucode_tx_stats, dir_debug, S_IRUSR); |
2595 | DEBUGFS_ADD_FILE(ucode_general_stats, dir_debug, S_IRUSR); | 2578 | DEBUGFS_ADD_FILE(ucode_general_stats, dir_debug, S_IRUSR); |
@@ -2602,17 +2585,14 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) | |||
2602 | DEBUGFS_ADD_FILE(reply_tx_error, dir_debug, S_IRUSR); | 2585 | DEBUGFS_ADD_FILE(reply_tx_error, dir_debug, S_IRUSR); |
2603 | DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR); | 2586 | DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR); |
2604 | DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR); | 2587 | DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR); |
2605 | DEBUGFS_ADD_FILE(wd_timeout, dir_debug, S_IWUSR); | ||
2606 | DEBUGFS_ADD_FILE(echo_test, dir_debug, S_IWUSR); | 2588 | DEBUGFS_ADD_FILE(echo_test, dir_debug, S_IWUSR); |
2607 | DEBUGFS_ADD_FILE(log_event, dir_debug, S_IWUSR | S_IRUSR); | 2589 | DEBUGFS_ADD_FILE(log_event, dir_debug, S_IWUSR | S_IRUSR); |
2608 | 2590 | ||
2609 | if (iwl_advanced_bt_coexist(priv)) | 2591 | if (iwl_advanced_bt_coexist(priv)) |
2610 | DEBUGFS_ADD_FILE(bt_traffic, dir_debug, S_IRUSR); | 2592 | DEBUGFS_ADD_FILE(bt_traffic, dir_debug, S_IRUSR); |
2611 | 2593 | ||
2612 | DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf, | 2594 | /* Calibrations disabled/enabled status*/ |
2613 | &priv->disable_sens_cal); | 2595 | DEBUGFS_ADD_FILE(calib_disabled, dir_rf, S_IRUSR); |
2614 | DEBUGFS_ADD_BOOL(disable_chain_noise, dir_rf, | ||
2615 | &priv->disable_chain_noise_cal); | ||
2616 | 2596 | ||
2617 | if (iwl_trans_dbgfs_register(trans(priv), dir_debug)) | 2597 | if (iwl_trans_dbgfs_register(trans(priv), dir_debug)) |
2618 | goto err; | 2598 | goto err; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 99be58940e27..c235a1ea71b4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h | |||
@@ -51,8 +51,6 @@ | |||
51 | #include "iwl-op-mode.h" | 51 | #include "iwl-op-mode.h" |
52 | #include "iwl-notif-wait.h" | 52 | #include "iwl-notif-wait.h" |
53 | 53 | ||
54 | struct iwl_tx_queue; | ||
55 | |||
56 | /* CT-KILL constants */ | 54 | /* CT-KILL constants */ |
57 | #define CT_KILL_THRESHOLD_LEGACY 110 /* in Celsius */ | 55 | #define CT_KILL_THRESHOLD_LEGACY 110 /* in Celsius */ |
58 | #define CT_KILL_THRESHOLD 114 /* in Celsius */ | 56 | #define CT_KILL_THRESHOLD 114 /* in Celsius */ |
@@ -582,9 +580,9 @@ struct iwl_event_log { | |||
582 | #define IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE (0) | 580 | #define IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE (0) |
583 | 581 | ||
584 | #define IWL_DELAY_NEXT_FORCE_RF_RESET (HZ*3) | 582 | #define IWL_DELAY_NEXT_FORCE_RF_RESET (HZ*3) |
585 | #define IWL_DELAY_NEXT_FORCE_FW_RELOAD (HZ*5) | ||
586 | 583 | ||
587 | /* TX queue watchdog timeouts in mSecs */ | 584 | /* TX queue watchdog timeouts in mSecs */ |
585 | #define IWL_WATCHHDOG_DISABLED (0) | ||
588 | #define IWL_DEF_WD_TIMEOUT (2000) | 586 | #define IWL_DEF_WD_TIMEOUT (2000) |
589 | #define IWL_LONG_WD_TIMEOUT (10000) | 587 | #define IWL_LONG_WD_TIMEOUT (10000) |
590 | #define IWL_MAX_WD_TIMEOUT (120000) | 588 | #define IWL_MAX_WD_TIMEOUT (120000) |
@@ -597,18 +595,11 @@ struct iwl_event_log { | |||
597 | #define IWL_MAX_CONTINUE_RELOAD_CNT 4 | 595 | #define IWL_MAX_CONTINUE_RELOAD_CNT 4 |
598 | 596 | ||
599 | 597 | ||
600 | enum iwl_reset { | 598 | struct iwl_rf_reset { |
601 | IWL_RF_RESET = 0, | ||
602 | IWL_FW_RESET, | ||
603 | IWL_MAX_FORCE_RESET, | ||
604 | }; | ||
605 | |||
606 | struct iwl_force_reset { | ||
607 | int reset_request_count; | 599 | int reset_request_count; |
608 | int reset_success_count; | 600 | int reset_success_count; |
609 | int reset_reject_count; | 601 | int reset_reject_count; |
610 | unsigned long reset_duration; | 602 | unsigned long last_reset_jiffies; |
611 | unsigned long last_force_reset_jiffies; | ||
612 | }; | 603 | }; |
613 | 604 | ||
614 | /* extend beacon time format bit shifting */ | 605 | /* extend beacon time format bit shifting */ |
@@ -680,6 +671,52 @@ enum iwl_scan_type { | |||
680 | IWL_SCAN_ROC, | 671 | IWL_SCAN_ROC, |
681 | }; | 672 | }; |
682 | 673 | ||
674 | /** | ||
675 | * struct iwl_hw_params | ||
676 | * | ||
677 | * Holds the module parameters | ||
678 | * | ||
679 | * @tx_chains_num: Number of TX chains | ||
680 | * @rx_chains_num: Number of RX chains | ||
681 | * @valid_tx_ant: usable antennas for TX | ||
682 | * @valid_rx_ant: usable antennas for RX | ||
683 | * @ht40_channel: is 40MHz width possible: BIT(IEEE80211_BAND_XXX) | ||
684 | * @sku: sku read from EEPROM | ||
685 | * @ct_kill_threshold: temperature threshold - in hw dependent unit | ||
686 | * @ct_kill_exit_threshold: when to reeable the device - in hw dependent unit | ||
687 | * relevant for 1000, 6000 and up | ||
688 | * @struct iwl_sensitivity_ranges: range of sensitivity values | ||
689 | * @use_rts_for_aggregation: use rts/cts protection for HT traffic | ||
690 | */ | ||
691 | struct iwl_hw_params { | ||
692 | u8 tx_chains_num; | ||
693 | u8 rx_chains_num; | ||
694 | u8 valid_tx_ant; | ||
695 | u8 valid_rx_ant; | ||
696 | u8 ht40_channel; | ||
697 | bool use_rts_for_aggregation; | ||
698 | u16 sku; | ||
699 | u32 ct_kill_threshold; | ||
700 | u32 ct_kill_exit_threshold; | ||
701 | |||
702 | const struct iwl_sensitivity_ranges *sens; | ||
703 | }; | ||
704 | |||
705 | struct iwl_lib_ops { | ||
706 | /* set hw dependent parameters */ | ||
707 | void (*set_hw_params)(struct iwl_priv *priv); | ||
708 | int (*set_channel_switch)(struct iwl_priv *priv, | ||
709 | struct ieee80211_channel_switch *ch_switch); | ||
710 | /* device specific configuration */ | ||
711 | void (*nic_config)(struct iwl_priv *priv); | ||
712 | |||
713 | /* eeprom operations (as defined in iwl-eeprom.h) */ | ||
714 | struct iwl_eeprom_ops eeprom_ops; | ||
715 | |||
716 | /* temperature */ | ||
717 | void (*temperature)(struct iwl_priv *priv); | ||
718 | }; | ||
719 | |||
683 | #ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE | 720 | #ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE |
684 | struct iwl_testmode_trace { | 721 | struct iwl_testmode_trace { |
685 | u32 buff_size; | 722 | u32 buff_size; |
@@ -704,6 +741,14 @@ struct iwl_wipan_noa_data { | |||
704 | u8 data[]; | 741 | u8 data[]; |
705 | }; | 742 | }; |
706 | 743 | ||
744 | /* Calibration disabling bit mask */ | ||
745 | #define IWL_SENSITIVITY_CALIB_DISABLED BIT(1) | ||
746 | #define IWL_CHAIN_NOISE_CALIB_DISABLED BIT(2) | ||
747 | #define IWL_TX_POWER_CALIB_DISABLED BIT(3) | ||
748 | |||
749 | #define IWL_CALIB_ENABLE_ALL 0 | ||
750 | #define IWL_CALIB_DISABLE_ALL 0xFFFFFFFF | ||
751 | |||
707 | #define IWL_OP_MODE_GET_DVM(_iwl_op_mode) \ | 752 | #define IWL_OP_MODE_GET_DVM(_iwl_op_mode) \ |
708 | ((struct iwl_priv *) ((_iwl_op_mode)->op_mode_specific)) | 753 | ((struct iwl_priv *) ((_iwl_op_mode)->op_mode_specific)) |
709 | 754 | ||
@@ -716,6 +761,7 @@ struct iwl_priv { | |||
716 | /*data shared among all the driver's layers */ | 761 | /*data shared among all the driver's layers */ |
717 | struct iwl_shared *shrd; | 762 | struct iwl_shared *shrd; |
718 | const struct iwl_fw *fw; | 763 | const struct iwl_fw *fw; |
764 | const struct iwl_lib_ops *lib; | ||
719 | unsigned long status; | 765 | unsigned long status; |
720 | 766 | ||
721 | spinlock_t sta_lock; | 767 | spinlock_t sta_lock; |
@@ -738,6 +784,8 @@ struct iwl_priv { | |||
738 | 784 | ||
739 | struct workqueue_struct *workqueue; | 785 | struct workqueue_struct *workqueue; |
740 | 786 | ||
787 | struct iwl_hw_params hw_params; | ||
788 | |||
741 | enum ieee80211_band band; | 789 | enum ieee80211_band band; |
742 | u8 valid_contexts; | 790 | u8 valid_contexts; |
743 | 791 | ||
@@ -772,8 +820,8 @@ struct iwl_priv { | |||
772 | /*counters */ | 820 | /*counters */ |
773 | u32 rx_handlers_stats[REPLY_MAX]; | 821 | u32 rx_handlers_stats[REPLY_MAX]; |
774 | 822 | ||
775 | /* force reset */ | 823 | /* rf reset */ |
776 | struct iwl_force_reset force_reset[IWL_MAX_FORCE_RESET]; | 824 | struct iwl_rf_reset rf_reset; |
777 | 825 | ||
778 | /* firmware reload counter and timestamp */ | 826 | /* firmware reload counter and timestamp */ |
779 | unsigned long reload_jiffies; | 827 | unsigned long reload_jiffies; |
@@ -819,8 +867,6 @@ struct iwl_priv { | |||
819 | 867 | ||
820 | __le16 switch_channel; | 868 | __le16 switch_channel; |
821 | 869 | ||
822 | u16 active_rate; | ||
823 | |||
824 | u8 start_calib; | 870 | u8 start_calib; |
825 | struct iwl_sensitivity_data sensitivity_data; | 871 | struct iwl_sensitivity_data sensitivity_data; |
826 | struct iwl_chain_noise_data chain_noise_data; | 872 | struct iwl_chain_noise_data chain_noise_data; |
@@ -967,13 +1013,15 @@ struct iwl_priv { | |||
967 | void *wowlan_sram; | 1013 | void *wowlan_sram; |
968 | #endif /* CONFIG_IWLWIFI_DEBUGFS */ | 1014 | #endif /* CONFIG_IWLWIFI_DEBUGFS */ |
969 | 1015 | ||
1016 | /* eeprom -- this is in the card's little endian byte order */ | ||
1017 | u8 *eeprom; | ||
1018 | enum iwl_nvm_type nvm_device_type; | ||
1019 | |||
970 | struct work_struct txpower_work; | 1020 | struct work_struct txpower_work; |
971 | u32 disable_sens_cal; | 1021 | u32 calib_disabled; |
972 | u32 disable_chain_noise_cal; | ||
973 | struct work_struct run_time_calib_work; | 1022 | struct work_struct run_time_calib_work; |
974 | struct timer_list statistics_periodic; | 1023 | struct timer_list statistics_periodic; |
975 | struct timer_list ucode_trace; | 1024 | struct timer_list ucode_trace; |
976 | struct timer_list watchdog; | ||
977 | 1025 | ||
978 | struct iwl_event_log event_log; | 1026 | struct iwl_event_log event_log; |
979 | 1027 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c index 6f312c77af5e..17485e715424 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/iwlwifi/iwl-drv.c | |||
@@ -284,6 +284,7 @@ static int iwl_store_ucode_sec(struct iwl_firmware_pieces *pieces, | |||
284 | 284 | ||
285 | sec->offset = le32_to_cpu(sec_parse->offset); | 285 | sec->offset = le32_to_cpu(sec_parse->offset); |
286 | sec->data = sec_parse->data; | 286 | sec->data = sec_parse->data; |
287 | sec->size = size - sizeof(sec_parse->offset); | ||
287 | 288 | ||
288 | ++img->sec_counter; | 289 | ++img->sec_counter; |
289 | 290 | ||
@@ -414,9 +415,6 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv, | |||
414 | struct iwl_ucode_tlv *tlv; | 415 | struct iwl_ucode_tlv *tlv; |
415 | size_t len = ucode_raw->size; | 416 | size_t len = ucode_raw->size; |
416 | const u8 *data; | 417 | const u8 *data; |
417 | int wanted_alternative = iwlagn_mod_params.wanted_ucode_alternative; | ||
418 | int tmp; | ||
419 | u64 alternatives; | ||
420 | u32 tlv_len; | 418 | u32 tlv_len; |
421 | enum iwl_ucode_tlv_type tlv_type; | 419 | enum iwl_ucode_tlv_type tlv_type; |
422 | const u8 *tlv_data; | 420 | const u8 *tlv_data; |
@@ -434,23 +432,6 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv, | |||
434 | return -EINVAL; | 432 | return -EINVAL; |
435 | } | 433 | } |
436 | 434 | ||
437 | /* | ||
438 | * Check which alternatives are present, and "downgrade" | ||
439 | * when the chosen alternative is not present, warning | ||
440 | * the user when that happens. Some files may not have | ||
441 | * any alternatives, so don't warn in that case. | ||
442 | */ | ||
443 | alternatives = le64_to_cpu(ucode->alternatives); | ||
444 | tmp = wanted_alternative; | ||
445 | if (wanted_alternative > 63) | ||
446 | wanted_alternative = 63; | ||
447 | while (wanted_alternative && !(alternatives & BIT(wanted_alternative))) | ||
448 | wanted_alternative--; | ||
449 | if (wanted_alternative && wanted_alternative != tmp) | ||
450 | IWL_WARN(drv, | ||
451 | "uCode alternative %d not available, choosing %d\n", | ||
452 | tmp, wanted_alternative); | ||
453 | |||
454 | drv->fw.ucode_ver = le32_to_cpu(ucode->ver); | 435 | drv->fw.ucode_ver = le32_to_cpu(ucode->ver); |
455 | build = le32_to_cpu(ucode->build); | 436 | build = le32_to_cpu(ucode->build); |
456 | 437 | ||
@@ -475,14 +456,11 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv, | |||
475 | len -= sizeof(*ucode); | 456 | len -= sizeof(*ucode); |
476 | 457 | ||
477 | while (len >= sizeof(*tlv)) { | 458 | while (len >= sizeof(*tlv)) { |
478 | u16 tlv_alt; | ||
479 | |||
480 | len -= sizeof(*tlv); | 459 | len -= sizeof(*tlv); |
481 | tlv = (void *)data; | 460 | tlv = (void *)data; |
482 | 461 | ||
483 | tlv_len = le32_to_cpu(tlv->length); | 462 | tlv_len = le32_to_cpu(tlv->length); |
484 | tlv_type = le16_to_cpu(tlv->type); | 463 | tlv_type = le32_to_cpu(tlv->type); |
485 | tlv_alt = le16_to_cpu(tlv->alternative); | ||
486 | tlv_data = tlv->data; | 464 | tlv_data = tlv->data; |
487 | 465 | ||
488 | if (len < tlv_len) { | 466 | if (len < tlv_len) { |
@@ -493,14 +471,6 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv, | |||
493 | len -= ALIGN(tlv_len, 4); | 471 | len -= ALIGN(tlv_len, 4); |
494 | data += sizeof(*tlv) + ALIGN(tlv_len, 4); | 472 | data += sizeof(*tlv) + ALIGN(tlv_len, 4); |
495 | 473 | ||
496 | /* | ||
497 | * Alternative 0 is always valid. | ||
498 | * | ||
499 | * Skip alternative TLVs that are not selected. | ||
500 | */ | ||
501 | if (tlv_alt != 0 && tlv_alt != wanted_alternative) | ||
502 | continue; | ||
503 | |||
504 | switch (tlv_type) { | 474 | switch (tlv_type) { |
505 | case IWL_UCODE_TLV_INST: | 475 | case IWL_UCODE_TLV_INST: |
506 | set_sec_data(pieces, IWL_UCODE_REGULAR, | 476 | set_sec_data(pieces, IWL_UCODE_REGULAR, |
@@ -838,42 +808,6 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) | |||
838 | IWL_INFO(drv, "loaded firmware version %s", drv->fw.fw_version); | 808 | IWL_INFO(drv, "loaded firmware version %s", drv->fw.fw_version); |
839 | 809 | ||
840 | /* | 810 | /* |
841 | * For any of the failures below (before allocating pci memory) | ||
842 | * we will try to load a version with a smaller API -- maybe the | ||
843 | * user just got a corrupted version of the latest API. | ||
844 | */ | ||
845 | |||
846 | IWL_DEBUG_INFO(drv, "f/w package hdr ucode version raw = 0x%x\n", | ||
847 | drv->fw.ucode_ver); | ||
848 | IWL_DEBUG_INFO(drv, "f/w package hdr runtime inst size = %Zd\n", | ||
849 | get_sec_size(&pieces, IWL_UCODE_REGULAR, | ||
850 | IWL_UCODE_SECTION_INST)); | ||
851 | IWL_DEBUG_INFO(drv, "f/w package hdr runtime data size = %Zd\n", | ||
852 | get_sec_size(&pieces, IWL_UCODE_REGULAR, | ||
853 | IWL_UCODE_SECTION_DATA)); | ||
854 | IWL_DEBUG_INFO(drv, "f/w package hdr init inst size = %Zd\n", | ||
855 | get_sec_size(&pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_INST)); | ||
856 | IWL_DEBUG_INFO(drv, "f/w package hdr init data size = %Zd\n", | ||
857 | get_sec_size(&pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_DATA)); | ||
858 | |||
859 | /* Verify that uCode images will fit in card's SRAM */ | ||
860 | if (get_sec_size(&pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_INST) > | ||
861 | cfg->max_inst_size) { | ||
862 | IWL_ERR(drv, "uCode instr len %Zd too large to fit in\n", | ||
863 | get_sec_size(&pieces, IWL_UCODE_REGULAR, | ||
864 | IWL_UCODE_SECTION_INST)); | ||
865 | goto try_again; | ||
866 | } | ||
867 | |||
868 | if (get_sec_size(&pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_DATA) > | ||
869 | cfg->max_data_size) { | ||
870 | IWL_ERR(drv, "uCode data len %Zd too large to fit in\n", | ||
871 | get_sec_size(&pieces, IWL_UCODE_REGULAR, | ||
872 | IWL_UCODE_SECTION_DATA)); | ||
873 | goto try_again; | ||
874 | } | ||
875 | |||
876 | /* | ||
877 | * In mvm uCode there is no difference between data and instructions | 811 | * In mvm uCode there is no difference between data and instructions |
878 | * sections. | 812 | * sections. |
879 | */ | 813 | */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c index 23cea42b9495..a004431d1a60 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c | |||
@@ -187,33 +187,33 @@ static void iwl_eeprom_release_semaphore(struct iwl_trans *trans) | |||
187 | 187 | ||
188 | } | 188 | } |
189 | 189 | ||
190 | static int iwl_eeprom_verify_signature(struct iwl_trans *trans) | 190 | static int iwl_eeprom_verify_signature(struct iwl_priv *priv) |
191 | { | 191 | { |
192 | u32 gp = iwl_read32(trans, CSR_EEPROM_GP) & | 192 | u32 gp = iwl_read32(trans(priv), CSR_EEPROM_GP) & |
193 | CSR_EEPROM_GP_VALID_MSK; | 193 | CSR_EEPROM_GP_VALID_MSK; |
194 | int ret = 0; | 194 | int ret = 0; |
195 | 195 | ||
196 | IWL_DEBUG_EEPROM(trans, "EEPROM signature=0x%08x\n", gp); | 196 | IWL_DEBUG_EEPROM(priv, "EEPROM signature=0x%08x\n", gp); |
197 | switch (gp) { | 197 | switch (gp) { |
198 | case CSR_EEPROM_GP_BAD_SIG_EEP_GOOD_SIG_OTP: | 198 | case CSR_EEPROM_GP_BAD_SIG_EEP_GOOD_SIG_OTP: |
199 | if (trans->nvm_device_type != NVM_DEVICE_TYPE_OTP) { | 199 | if (priv->nvm_device_type != NVM_DEVICE_TYPE_OTP) { |
200 | IWL_ERR(trans, "EEPROM with bad signature: 0x%08x\n", | 200 | IWL_ERR(priv, "EEPROM with bad signature: 0x%08x\n", |
201 | gp); | 201 | gp); |
202 | ret = -ENOENT; | 202 | ret = -ENOENT; |
203 | } | 203 | } |
204 | break; | 204 | break; |
205 | case CSR_EEPROM_GP_GOOD_SIG_EEP_LESS_THAN_4K: | 205 | case CSR_EEPROM_GP_GOOD_SIG_EEP_LESS_THAN_4K: |
206 | case CSR_EEPROM_GP_GOOD_SIG_EEP_MORE_THAN_4K: | 206 | case CSR_EEPROM_GP_GOOD_SIG_EEP_MORE_THAN_4K: |
207 | if (trans->nvm_device_type != NVM_DEVICE_TYPE_EEPROM) { | 207 | if (priv->nvm_device_type != NVM_DEVICE_TYPE_EEPROM) { |
208 | IWL_ERR(trans, "OTP with bad signature: 0x%08x\n", gp); | 208 | IWL_ERR(priv, "OTP with bad signature: 0x%08x\n", gp); |
209 | ret = -ENOENT; | 209 | ret = -ENOENT; |
210 | } | 210 | } |
211 | break; | 211 | break; |
212 | case CSR_EEPROM_GP_BAD_SIGNATURE_BOTH_EEP_AND_OTP: | 212 | case CSR_EEPROM_GP_BAD_SIGNATURE_BOTH_EEP_AND_OTP: |
213 | default: | 213 | default: |
214 | IWL_ERR(trans, "bad EEPROM/OTP signature, type=%s, " | 214 | IWL_ERR(priv, "bad EEPROM/OTP signature, type=%s, " |
215 | "EEPROM_GP=0x%08x\n", | 215 | "EEPROM_GP=0x%08x\n", |
216 | (trans->nvm_device_type == NVM_DEVICE_TYPE_OTP) | 216 | (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP) |
217 | ? "OTP" : "EEPROM", gp); | 217 | ? "OTP" : "EEPROM", gp); |
218 | ret = -ENOENT; | 218 | ret = -ENOENT; |
219 | break; | 219 | break; |
@@ -221,11 +221,11 @@ static int iwl_eeprom_verify_signature(struct iwl_trans *trans) | |||
221 | return ret; | 221 | return ret; |
222 | } | 222 | } |
223 | 223 | ||
224 | u16 iwl_eeprom_query16(const struct iwl_shared *shrd, size_t offset) | 224 | u16 iwl_eeprom_query16(struct iwl_priv *priv, size_t offset) |
225 | { | 225 | { |
226 | if (!shrd->eeprom) | 226 | if (!priv->eeprom) |
227 | return 0; | 227 | return 0; |
228 | return (u16)shrd->eeprom[offset] | ((u16)shrd->eeprom[offset + 1] << 8); | 228 | return (u16)priv->eeprom[offset] | ((u16)priv->eeprom[offset + 1] << 8); |
229 | } | 229 | } |
230 | 230 | ||
231 | int iwl_eeprom_check_version(struct iwl_priv *priv) | 231 | int iwl_eeprom_check_version(struct iwl_priv *priv) |
@@ -233,8 +233,8 @@ int iwl_eeprom_check_version(struct iwl_priv *priv) | |||
233 | u16 eeprom_ver; | 233 | u16 eeprom_ver; |
234 | u16 calib_ver; | 234 | u16 calib_ver; |
235 | 235 | ||
236 | eeprom_ver = iwl_eeprom_query16(priv->shrd, EEPROM_VERSION); | 236 | eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION); |
237 | calib_ver = iwl_eeprom_calib_version(priv->shrd); | 237 | calib_ver = iwl_eeprom_calib_version(priv); |
238 | 238 | ||
239 | if (eeprom_ver < cfg(priv)->eeprom_ver || | 239 | if (eeprom_ver < cfg(priv)->eeprom_ver || |
240 | calib_ver < cfg(priv)->eeprom_calib_ver) | 240 | calib_ver < cfg(priv)->eeprom_calib_ver) |
@@ -255,50 +255,107 @@ err: | |||
255 | 255 | ||
256 | int iwl_eeprom_init_hw_params(struct iwl_priv *priv) | 256 | int iwl_eeprom_init_hw_params(struct iwl_priv *priv) |
257 | { | 257 | { |
258 | struct iwl_shared *shrd = priv->shrd; | ||
259 | u16 radio_cfg; | 258 | u16 radio_cfg; |
260 | 259 | ||
261 | hw_params(priv).sku = iwl_eeprom_query16(shrd, EEPROM_SKU_CAP); | 260 | priv->hw_params.sku = iwl_eeprom_query16(priv, EEPROM_SKU_CAP); |
262 | if (hw_params(priv).sku & EEPROM_SKU_CAP_11N_ENABLE && | 261 | if (priv->hw_params.sku & EEPROM_SKU_CAP_11N_ENABLE && |
263 | !cfg(priv)->ht_params) { | 262 | !cfg(priv)->ht_params) { |
264 | IWL_ERR(priv, "Invalid 11n configuration\n"); | 263 | IWL_ERR(priv, "Invalid 11n configuration\n"); |
265 | return -EINVAL; | 264 | return -EINVAL; |
266 | } | 265 | } |
267 | 266 | ||
268 | if (!hw_params(priv).sku) { | 267 | if (!priv->hw_params.sku) { |
269 | IWL_ERR(priv, "Invalid device sku\n"); | 268 | IWL_ERR(priv, "Invalid device sku\n"); |
270 | return -EINVAL; | 269 | return -EINVAL; |
271 | } | 270 | } |
272 | 271 | ||
273 | IWL_INFO(priv, "Device SKU: 0x%X\n", hw_params(priv).sku); | 272 | IWL_INFO(priv, "Device SKU: 0x%X\n", priv->hw_params.sku); |
274 | 273 | ||
275 | radio_cfg = iwl_eeprom_query16(shrd, EEPROM_RADIO_CONFIG); | 274 | radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG); |
276 | 275 | ||
277 | hw_params(priv).valid_tx_ant = EEPROM_RF_CFG_TX_ANT_MSK(radio_cfg); | 276 | priv->hw_params.valid_tx_ant = EEPROM_RF_CFG_TX_ANT_MSK(radio_cfg); |
278 | hw_params(priv).valid_rx_ant = EEPROM_RF_CFG_RX_ANT_MSK(radio_cfg); | 277 | priv->hw_params.valid_rx_ant = EEPROM_RF_CFG_RX_ANT_MSK(radio_cfg); |
279 | 278 | ||
280 | /* check overrides (some devices have wrong EEPROM) */ | 279 | /* check overrides (some devices have wrong EEPROM) */ |
281 | if (cfg(priv)->valid_tx_ant) | 280 | if (cfg(priv)->valid_tx_ant) |
282 | hw_params(priv).valid_tx_ant = cfg(priv)->valid_tx_ant; | 281 | priv->hw_params.valid_tx_ant = cfg(priv)->valid_tx_ant; |
283 | if (cfg(priv)->valid_rx_ant) | 282 | if (cfg(priv)->valid_rx_ant) |
284 | hw_params(priv).valid_rx_ant = cfg(priv)->valid_rx_ant; | 283 | priv->hw_params.valid_rx_ant = cfg(priv)->valid_rx_ant; |
285 | 284 | ||
286 | if (!hw_params(priv).valid_tx_ant || !hw_params(priv).valid_rx_ant) { | 285 | if (!priv->hw_params.valid_tx_ant || !priv->hw_params.valid_rx_ant) { |
287 | IWL_ERR(priv, "Invalid chain (0x%X, 0x%X)\n", | 286 | IWL_ERR(priv, "Invalid chain (0x%X, 0x%X)\n", |
288 | hw_params(priv).valid_tx_ant, | 287 | priv->hw_params.valid_tx_ant, |
289 | hw_params(priv).valid_rx_ant); | 288 | priv->hw_params.valid_rx_ant); |
290 | return -EINVAL; | 289 | return -EINVAL; |
291 | } | 290 | } |
292 | 291 | ||
293 | IWL_INFO(priv, "Valid Tx ant: 0x%X, Valid Rx ant: 0x%X\n", | 292 | IWL_INFO(priv, "Valid Tx ant: 0x%X, Valid Rx ant: 0x%X\n", |
294 | hw_params(priv).valid_tx_ant, hw_params(priv).valid_rx_ant); | 293 | priv->hw_params.valid_tx_ant, priv->hw_params.valid_rx_ant); |
295 | 294 | ||
296 | return 0; | 295 | return 0; |
297 | } | 296 | } |
298 | 297 | ||
299 | void iwl_eeprom_get_mac(const struct iwl_shared *shrd, u8 *mac) | 298 | u16 iwl_eeprom_calib_version(struct iwl_priv *priv) |
300 | { | 299 | { |
301 | const u8 *addr = iwl_eeprom_query_addr(shrd, | 300 | struct iwl_eeprom_calib_hdr *hdr; |
301 | |||
302 | hdr = (struct iwl_eeprom_calib_hdr *)iwl_eeprom_query_addr(priv, | ||
303 | EEPROM_CALIB_ALL); | ||
304 | return hdr->version; | ||
305 | } | ||
306 | |||
307 | static u32 eeprom_indirect_address(struct iwl_priv *priv, u32 address) | ||
308 | { | ||
309 | u16 offset = 0; | ||
310 | |||
311 | if ((address & INDIRECT_ADDRESS) == 0) | ||
312 | return address; | ||
313 | |||
314 | switch (address & INDIRECT_TYPE_MSK) { | ||
315 | case INDIRECT_HOST: | ||
316 | offset = iwl_eeprom_query16(priv, EEPROM_LINK_HOST); | ||
317 | break; | ||
318 | case INDIRECT_GENERAL: | ||
319 | offset = iwl_eeprom_query16(priv, EEPROM_LINK_GENERAL); | ||
320 | break; | ||
321 | case INDIRECT_REGULATORY: | ||
322 | offset = iwl_eeprom_query16(priv, EEPROM_LINK_REGULATORY); | ||
323 | break; | ||
324 | case INDIRECT_TXP_LIMIT: | ||
325 | offset = iwl_eeprom_query16(priv, EEPROM_LINK_TXP_LIMIT); | ||
326 | break; | ||
327 | case INDIRECT_TXP_LIMIT_SIZE: | ||
328 | offset = iwl_eeprom_query16(priv, EEPROM_LINK_TXP_LIMIT_SIZE); | ||
329 | break; | ||
330 | case INDIRECT_CALIBRATION: | ||
331 | offset = iwl_eeprom_query16(priv, EEPROM_LINK_CALIBRATION); | ||
332 | break; | ||
333 | case INDIRECT_PROCESS_ADJST: | ||
334 | offset = iwl_eeprom_query16(priv, EEPROM_LINK_PROCESS_ADJST); | ||
335 | break; | ||
336 | case INDIRECT_OTHERS: | ||
337 | offset = iwl_eeprom_query16(priv, EEPROM_LINK_OTHERS); | ||
338 | break; | ||
339 | default: | ||
340 | IWL_ERR(priv, "illegal indirect type: 0x%X\n", | ||
341 | address & INDIRECT_TYPE_MSK); | ||
342 | break; | ||
343 | } | ||
344 | |||
345 | /* translate the offset from words to byte */ | ||
346 | return (address & ADDRESS_MSK) + (offset << 1); | ||
347 | } | ||
348 | |||
349 | const u8 *iwl_eeprom_query_addr(struct iwl_priv *priv, size_t offset) | ||
350 | { | ||
351 | u32 address = eeprom_indirect_address(priv, offset); | ||
352 | BUG_ON(address >= cfg(priv)->base_params->eeprom_size); | ||
353 | return &priv->eeprom[address]; | ||
354 | } | ||
355 | |||
356 | void iwl_eeprom_get_mac(struct iwl_priv *priv, u8 *mac) | ||
357 | { | ||
358 | const u8 *addr = iwl_eeprom_query_addr(priv, | ||
302 | EEPROM_MAC_ADDRESS); | 359 | EEPROM_MAC_ADDRESS); |
303 | memcpy(mac, addr, ETH_ALEN); | 360 | memcpy(mac, addr, ETH_ALEN); |
304 | } | 361 | } |
@@ -591,7 +648,6 @@ iwl_eeprom_enh_txp_read_element(struct iwl_priv *priv, | |||
591 | 648 | ||
592 | static void iwl_eeprom_enhanced_txpower(struct iwl_priv *priv) | 649 | static void iwl_eeprom_enhanced_txpower(struct iwl_priv *priv) |
593 | { | 650 | { |
594 | struct iwl_shared *shrd = priv->shrd; | ||
595 | struct iwl_eeprom_enhanced_txpwr *txp_array, *txp; | 651 | struct iwl_eeprom_enhanced_txpwr *txp_array, *txp; |
596 | int idx, entries; | 652 | int idx, entries; |
597 | __le16 *txp_len; | 653 | __le16 *txp_len; |
@@ -600,10 +656,10 @@ static void iwl_eeprom_enhanced_txpower(struct iwl_priv *priv) | |||
600 | BUILD_BUG_ON(sizeof(struct iwl_eeprom_enhanced_txpwr) != 8); | 656 | BUILD_BUG_ON(sizeof(struct iwl_eeprom_enhanced_txpwr) != 8); |
601 | 657 | ||
602 | /* the length is in 16-bit words, but we want entries */ | 658 | /* the length is in 16-bit words, but we want entries */ |
603 | txp_len = (__le16 *) iwl_eeprom_query_addr(shrd, EEPROM_TXP_SZ_OFFS); | 659 | txp_len = (__le16 *) iwl_eeprom_query_addr(priv, EEPROM_TXP_SZ_OFFS); |
604 | entries = le16_to_cpup(txp_len) * 2 / EEPROM_TXP_ENTRY_LEN; | 660 | entries = le16_to_cpup(txp_len) * 2 / EEPROM_TXP_ENTRY_LEN; |
605 | 661 | ||
606 | txp_array = (void *) iwl_eeprom_query_addr(shrd, EEPROM_TXP_OFFS); | 662 | txp_array = (void *) iwl_eeprom_query_addr(priv, EEPROM_TXP_OFFS); |
607 | 663 | ||
608 | for (idx = 0; idx < entries; idx++) { | 664 | for (idx = 0; idx < entries; idx++) { |
609 | txp = &txp_array[idx]; | 665 | txp = &txp_array[idx]; |
@@ -656,66 +712,66 @@ static void iwl_eeprom_enhanced_txpower(struct iwl_priv *priv) | |||
656 | /** | 712 | /** |
657 | * iwl_eeprom_init - read EEPROM contents | 713 | * iwl_eeprom_init - read EEPROM contents |
658 | * | 714 | * |
659 | * Load the EEPROM contents from adapter into shrd->eeprom | 715 | * Load the EEPROM contents from adapter into priv->eeprom |
660 | * | 716 | * |
661 | * NOTE: This routine uses the non-debug IO access functions. | 717 | * NOTE: This routine uses the non-debug IO access functions. |
662 | */ | 718 | */ |
663 | int iwl_eeprom_init(struct iwl_trans *trans, u32 hw_rev) | 719 | int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev) |
664 | { | 720 | { |
665 | __le16 *e; | 721 | __le16 *e; |
666 | u32 gp = iwl_read32(trans, CSR_EEPROM_GP); | 722 | u32 gp = iwl_read32(trans(priv), CSR_EEPROM_GP); |
667 | int sz; | 723 | int sz; |
668 | int ret; | 724 | int ret; |
669 | u16 addr; | 725 | u16 addr; |
670 | u16 validblockaddr = 0; | 726 | u16 validblockaddr = 0; |
671 | u16 cache_addr = 0; | 727 | u16 cache_addr = 0; |
672 | 728 | ||
673 | trans->nvm_device_type = iwl_get_nvm_type(trans, hw_rev); | 729 | priv->nvm_device_type = iwl_get_nvm_type(trans(priv), hw_rev); |
674 | if (trans->nvm_device_type == -ENOENT) | 730 | if (priv->nvm_device_type == -ENOENT) |
675 | return -ENOENT; | 731 | return -ENOENT; |
676 | /* allocate eeprom */ | 732 | /* allocate eeprom */ |
677 | sz = cfg(trans)->base_params->eeprom_size; | 733 | sz = cfg(priv)->base_params->eeprom_size; |
678 | IWL_DEBUG_EEPROM(trans, "NVM size = %d\n", sz); | 734 | IWL_DEBUG_EEPROM(priv, "NVM size = %d\n", sz); |
679 | trans->shrd->eeprom = kzalloc(sz, GFP_KERNEL); | 735 | priv->eeprom = kzalloc(sz, GFP_KERNEL); |
680 | if (!trans->shrd->eeprom) { | 736 | if (!priv->eeprom) { |
681 | ret = -ENOMEM; | 737 | ret = -ENOMEM; |
682 | goto alloc_err; | 738 | goto alloc_err; |
683 | } | 739 | } |
684 | e = (__le16 *)trans->shrd->eeprom; | 740 | e = (__le16 *)priv->eeprom; |
685 | 741 | ||
686 | ret = iwl_eeprom_verify_signature(trans); | 742 | ret = iwl_eeprom_verify_signature(priv); |
687 | if (ret < 0) { | 743 | if (ret < 0) { |
688 | IWL_ERR(trans, "EEPROM not found, EEPROM_GP=0x%08x\n", gp); | 744 | IWL_ERR(priv, "EEPROM not found, EEPROM_GP=0x%08x\n", gp); |
689 | ret = -ENOENT; | 745 | ret = -ENOENT; |
690 | goto err; | 746 | goto err; |
691 | } | 747 | } |
692 | 748 | ||
693 | /* Make sure driver (instead of uCode) is allowed to read EEPROM */ | 749 | /* Make sure driver (instead of uCode) is allowed to read EEPROM */ |
694 | ret = iwl_eeprom_acquire_semaphore(trans); | 750 | ret = iwl_eeprom_acquire_semaphore(trans(priv)); |
695 | if (ret < 0) { | 751 | if (ret < 0) { |
696 | IWL_ERR(trans, "Failed to acquire EEPROM semaphore.\n"); | 752 | IWL_ERR(priv, "Failed to acquire EEPROM semaphore.\n"); |
697 | ret = -ENOENT; | 753 | ret = -ENOENT; |
698 | goto err; | 754 | goto err; |
699 | } | 755 | } |
700 | 756 | ||
701 | if (trans->nvm_device_type == NVM_DEVICE_TYPE_OTP) { | 757 | if (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP) { |
702 | 758 | ||
703 | ret = iwl_init_otp_access(trans); | 759 | ret = iwl_init_otp_access(trans(priv)); |
704 | if (ret) { | 760 | if (ret) { |
705 | IWL_ERR(trans, "Failed to initialize OTP access.\n"); | 761 | IWL_ERR(priv, "Failed to initialize OTP access.\n"); |
706 | ret = -ENOENT; | 762 | ret = -ENOENT; |
707 | goto done; | 763 | goto done; |
708 | } | 764 | } |
709 | iwl_write32(trans, CSR_EEPROM_GP, | 765 | iwl_write32(trans(priv), CSR_EEPROM_GP, |
710 | iwl_read32(trans, CSR_EEPROM_GP) & | 766 | iwl_read32(trans(priv), CSR_EEPROM_GP) & |
711 | ~CSR_EEPROM_GP_IF_OWNER_MSK); | 767 | ~CSR_EEPROM_GP_IF_OWNER_MSK); |
712 | 768 | ||
713 | iwl_set_bit(trans, CSR_OTP_GP_REG, | 769 | iwl_set_bit(trans(priv), CSR_OTP_GP_REG, |
714 | CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK | | 770 | CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK | |
715 | CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK); | 771 | CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK); |
716 | /* traversing the linked list if no shadow ram supported */ | 772 | /* traversing the linked list if no shadow ram supported */ |
717 | if (!cfg(trans)->base_params->shadow_ram_support) { | 773 | if (!cfg(priv)->base_params->shadow_ram_support) { |
718 | if (iwl_find_otp_image(trans, &validblockaddr)) { | 774 | if (iwl_find_otp_image(trans(priv), &validblockaddr)) { |
719 | ret = -ENOENT; | 775 | ret = -ENOENT; |
720 | goto done; | 776 | goto done; |
721 | } | 777 | } |
@@ -724,7 +780,8 @@ int iwl_eeprom_init(struct iwl_trans *trans, u32 hw_rev) | |||
724 | addr += sizeof(u16)) { | 780 | addr += sizeof(u16)) { |
725 | __le16 eeprom_data; | 781 | __le16 eeprom_data; |
726 | 782 | ||
727 | ret = iwl_read_otp_word(trans, addr, &eeprom_data); | 783 | ret = iwl_read_otp_word(trans(priv), addr, |
784 | &eeprom_data); | ||
728 | if (ret) | 785 | if (ret) |
729 | goto done; | 786 | goto done; |
730 | e[cache_addr / 2] = eeprom_data; | 787 | e[cache_addr / 2] = eeprom_data; |
@@ -735,94 +792,93 @@ int iwl_eeprom_init(struct iwl_trans *trans, u32 hw_rev) | |||
735 | for (addr = 0; addr < sz; addr += sizeof(u16)) { | 792 | for (addr = 0; addr < sz; addr += sizeof(u16)) { |
736 | u32 r; | 793 | u32 r; |
737 | 794 | ||
738 | iwl_write32(trans, CSR_EEPROM_REG, | 795 | iwl_write32(trans(priv), CSR_EEPROM_REG, |
739 | CSR_EEPROM_REG_MSK_ADDR & (addr << 1)); | 796 | CSR_EEPROM_REG_MSK_ADDR & (addr << 1)); |
740 | 797 | ||
741 | ret = iwl_poll_bit(trans, CSR_EEPROM_REG, | 798 | ret = iwl_poll_bit(trans(priv), CSR_EEPROM_REG, |
742 | CSR_EEPROM_REG_READ_VALID_MSK, | 799 | CSR_EEPROM_REG_READ_VALID_MSK, |
743 | CSR_EEPROM_REG_READ_VALID_MSK, | 800 | CSR_EEPROM_REG_READ_VALID_MSK, |
744 | IWL_EEPROM_ACCESS_TIMEOUT); | 801 | IWL_EEPROM_ACCESS_TIMEOUT); |
745 | if (ret < 0) { | 802 | if (ret < 0) { |
746 | IWL_ERR(trans, | 803 | IWL_ERR(priv, |
747 | "Time out reading EEPROM[%d]\n", addr); | 804 | "Time out reading EEPROM[%d]\n", addr); |
748 | goto done; | 805 | goto done; |
749 | } | 806 | } |
750 | r = iwl_read32(trans, CSR_EEPROM_REG); | 807 | r = iwl_read32(trans(priv), CSR_EEPROM_REG); |
751 | e[addr / 2] = cpu_to_le16(r >> 16); | 808 | e[addr / 2] = cpu_to_le16(r >> 16); |
752 | } | 809 | } |
753 | } | 810 | } |
754 | 811 | ||
755 | IWL_DEBUG_EEPROM(trans, "NVM Type: %s, version: 0x%x\n", | 812 | IWL_DEBUG_EEPROM(priv, "NVM Type: %s, version: 0x%x\n", |
756 | (trans->nvm_device_type == NVM_DEVICE_TYPE_OTP) | 813 | (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP) |
757 | ? "OTP" : "EEPROM", | 814 | ? "OTP" : "EEPROM", |
758 | iwl_eeprom_query16(trans->shrd, EEPROM_VERSION)); | 815 | iwl_eeprom_query16(priv, EEPROM_VERSION)); |
759 | 816 | ||
760 | ret = 0; | 817 | ret = 0; |
761 | done: | 818 | done: |
762 | iwl_eeprom_release_semaphore(trans); | 819 | iwl_eeprom_release_semaphore(trans(priv)); |
763 | 820 | ||
764 | err: | 821 | err: |
765 | if (ret) | 822 | if (ret) |
766 | iwl_eeprom_free(trans->shrd); | 823 | iwl_eeprom_free(priv); |
767 | alloc_err: | 824 | alloc_err: |
768 | return ret; | 825 | return ret; |
769 | } | 826 | } |
770 | 827 | ||
771 | void iwl_eeprom_free(struct iwl_shared *shrd) | 828 | void iwl_eeprom_free(struct iwl_priv *priv) |
772 | { | 829 | { |
773 | kfree(shrd->eeprom); | 830 | kfree(priv->eeprom); |
774 | shrd->eeprom = NULL; | 831 | priv->eeprom = NULL; |
775 | } | 832 | } |
776 | 833 | ||
777 | static void iwl_init_band_reference(const struct iwl_priv *priv, | 834 | static void iwl_init_band_reference(struct iwl_priv *priv, |
778 | int eep_band, int *eeprom_ch_count, | 835 | int eep_band, int *eeprom_ch_count, |
779 | const struct iwl_eeprom_channel **eeprom_ch_info, | 836 | const struct iwl_eeprom_channel **eeprom_ch_info, |
780 | const u8 **eeprom_ch_index) | 837 | const u8 **eeprom_ch_index) |
781 | { | 838 | { |
782 | struct iwl_shared *shrd = priv->shrd; | 839 | u32 offset = priv->lib-> |
783 | u32 offset = cfg(priv)->lib-> | ||
784 | eeprom_ops.regulatory_bands[eep_band - 1]; | 840 | eeprom_ops.regulatory_bands[eep_band - 1]; |
785 | switch (eep_band) { | 841 | switch (eep_band) { |
786 | case 1: /* 2.4GHz band */ | 842 | case 1: /* 2.4GHz band */ |
787 | *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_1); | 843 | *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_1); |
788 | *eeprom_ch_info = (struct iwl_eeprom_channel *) | 844 | *eeprom_ch_info = (struct iwl_eeprom_channel *) |
789 | iwl_eeprom_query_addr(shrd, offset); | 845 | iwl_eeprom_query_addr(priv, offset); |
790 | *eeprom_ch_index = iwl_eeprom_band_1; | 846 | *eeprom_ch_index = iwl_eeprom_band_1; |
791 | break; | 847 | break; |
792 | case 2: /* 4.9GHz band */ | 848 | case 2: /* 4.9GHz band */ |
793 | *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_2); | 849 | *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_2); |
794 | *eeprom_ch_info = (struct iwl_eeprom_channel *) | 850 | *eeprom_ch_info = (struct iwl_eeprom_channel *) |
795 | iwl_eeprom_query_addr(shrd, offset); | 851 | iwl_eeprom_query_addr(priv, offset); |
796 | *eeprom_ch_index = iwl_eeprom_band_2; | 852 | *eeprom_ch_index = iwl_eeprom_band_2; |
797 | break; | 853 | break; |
798 | case 3: /* 5.2GHz band */ | 854 | case 3: /* 5.2GHz band */ |
799 | *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_3); | 855 | *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_3); |
800 | *eeprom_ch_info = (struct iwl_eeprom_channel *) | 856 | *eeprom_ch_info = (struct iwl_eeprom_channel *) |
801 | iwl_eeprom_query_addr(shrd, offset); | 857 | iwl_eeprom_query_addr(priv, offset); |
802 | *eeprom_ch_index = iwl_eeprom_band_3; | 858 | *eeprom_ch_index = iwl_eeprom_band_3; |
803 | break; | 859 | break; |
804 | case 4: /* 5.5GHz band */ | 860 | case 4: /* 5.5GHz band */ |
805 | *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_4); | 861 | *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_4); |
806 | *eeprom_ch_info = (struct iwl_eeprom_channel *) | 862 | *eeprom_ch_info = (struct iwl_eeprom_channel *) |
807 | iwl_eeprom_query_addr(shrd, offset); | 863 | iwl_eeprom_query_addr(priv, offset); |
808 | *eeprom_ch_index = iwl_eeprom_band_4; | 864 | *eeprom_ch_index = iwl_eeprom_band_4; |
809 | break; | 865 | break; |
810 | case 5: /* 5.7GHz band */ | 866 | case 5: /* 5.7GHz band */ |
811 | *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_5); | 867 | *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_5); |
812 | *eeprom_ch_info = (struct iwl_eeprom_channel *) | 868 | *eeprom_ch_info = (struct iwl_eeprom_channel *) |
813 | iwl_eeprom_query_addr(shrd, offset); | 869 | iwl_eeprom_query_addr(priv, offset); |
814 | *eeprom_ch_index = iwl_eeprom_band_5; | 870 | *eeprom_ch_index = iwl_eeprom_band_5; |
815 | break; | 871 | break; |
816 | case 6: /* 2.4GHz ht40 channels */ | 872 | case 6: /* 2.4GHz ht40 channels */ |
817 | *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_6); | 873 | *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_6); |
818 | *eeprom_ch_info = (struct iwl_eeprom_channel *) | 874 | *eeprom_ch_info = (struct iwl_eeprom_channel *) |
819 | iwl_eeprom_query_addr(shrd, offset); | 875 | iwl_eeprom_query_addr(priv, offset); |
820 | *eeprom_ch_index = iwl_eeprom_band_6; | 876 | *eeprom_ch_index = iwl_eeprom_band_6; |
821 | break; | 877 | break; |
822 | case 7: /* 5 GHz ht40 channels */ | 878 | case 7: /* 5 GHz ht40 channels */ |
823 | *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_7); | 879 | *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_7); |
824 | *eeprom_ch_info = (struct iwl_eeprom_channel *) | 880 | *eeprom_ch_info = (struct iwl_eeprom_channel *) |
825 | iwl_eeprom_query_addr(shrd, offset); | 881 | iwl_eeprom_query_addr(priv, offset); |
826 | *eeprom_ch_index = iwl_eeprom_band_7; | 882 | *eeprom_ch_index = iwl_eeprom_band_7; |
827 | break; | 883 | break; |
828 | default: | 884 | default: |
@@ -987,9 +1043,9 @@ int iwl_init_channel_map(struct iwl_priv *priv) | |||
987 | } | 1043 | } |
988 | 1044 | ||
989 | /* Check if we do have HT40 channels */ | 1045 | /* Check if we do have HT40 channels */ |
990 | if (cfg(priv)->lib->eeprom_ops.regulatory_bands[5] == | 1046 | if (priv->lib->eeprom_ops.regulatory_bands[5] == |
991 | EEPROM_REGULATORY_BAND_NO_HT40 && | 1047 | EEPROM_REGULATORY_BAND_NO_HT40 && |
992 | cfg(priv)->lib->eeprom_ops.regulatory_bands[6] == | 1048 | priv->lib->eeprom_ops.regulatory_bands[6] == |
993 | EEPROM_REGULATORY_BAND_NO_HT40) | 1049 | EEPROM_REGULATORY_BAND_NO_HT40) |
994 | return 0; | 1050 | return 0; |
995 | 1051 | ||
@@ -1025,7 +1081,7 @@ int iwl_init_channel_map(struct iwl_priv *priv) | |||
1025 | * driver need to process addition information | 1081 | * driver need to process addition information |
1026 | * to determine the max channel tx power limits | 1082 | * to determine the max channel tx power limits |
1027 | */ | 1083 | */ |
1028 | if (cfg(priv)->lib->eeprom_ops.enhanced_txpower) | 1084 | if (priv->lib->eeprom_ops.enhanced_txpower) |
1029 | iwl_eeprom_enhanced_txpower(priv); | 1085 | iwl_eeprom_enhanced_txpower(priv); |
1030 | 1086 | ||
1031 | return 0; | 1087 | return 0; |
@@ -1072,7 +1128,7 @@ void iwl_rf_config(struct iwl_priv *priv) | |||
1072 | { | 1128 | { |
1073 | u16 radio_cfg; | 1129 | u16 radio_cfg; |
1074 | 1130 | ||
1075 | radio_cfg = iwl_eeprom_query16(priv->shrd, EEPROM_RADIO_CONFIG); | 1131 | radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG); |
1076 | 1132 | ||
1077 | /* write radio config values to register */ | 1133 | /* write radio config values to register */ |
1078 | if (EEPROM_RF_CFG_TYPE_MSK(radio_cfg) <= EEPROM_RF_CONFIG_TYPE_MAX) { | 1134 | if (EEPROM_RF_CFG_TYPE_MSK(radio_cfg) <= EEPROM_RF_CONFIG_TYPE_MAX) { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h index e4a758340996..b3a3b1f0fdc4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h | |||
@@ -66,8 +66,6 @@ | |||
66 | #include <net/mac80211.h> | 66 | #include <net/mac80211.h> |
67 | 67 | ||
68 | struct iwl_priv; | 68 | struct iwl_priv; |
69 | struct iwl_shared; | ||
70 | struct iwl_trans; | ||
71 | 69 | ||
72 | /* | 70 | /* |
73 | * EEPROM access time values: | 71 | * EEPROM access time values: |
@@ -306,12 +304,14 @@ struct iwl_eeprom_ops { | |||
306 | }; | 304 | }; |
307 | 305 | ||
308 | 306 | ||
309 | int iwl_eeprom_init(struct iwl_trans *trans, u32 hw_rev); | 307 | int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev); |
310 | void iwl_eeprom_free(struct iwl_shared *shrd); | 308 | void iwl_eeprom_free(struct iwl_priv *priv); |
311 | int iwl_eeprom_check_version(struct iwl_priv *priv); | 309 | int iwl_eeprom_check_version(struct iwl_priv *priv); |
312 | int iwl_eeprom_init_hw_params(struct iwl_priv *priv); | 310 | int iwl_eeprom_init_hw_params(struct iwl_priv *priv); |
313 | const u8 *iwl_eeprom_query_addr(const struct iwl_shared *shrd, size_t offset); | 311 | u16 iwl_eeprom_calib_version(struct iwl_priv *priv); |
314 | u16 iwl_eeprom_query16(const struct iwl_shared *shrd, size_t offset); | 312 | const u8 *iwl_eeprom_query_addr(struct iwl_priv *priv, size_t offset); |
313 | u16 iwl_eeprom_query16(struct iwl_priv *priv, size_t offset); | ||
314 | void iwl_eeprom_get_mac(struct iwl_priv *priv, u8 *mac); | ||
315 | int iwl_init_channel_map(struct iwl_priv *priv); | 315 | int iwl_init_channel_map(struct iwl_priv *priv); |
316 | void iwl_free_channel_map(struct iwl_priv *priv); | 316 | void iwl_free_channel_map(struct iwl_priv *priv); |
317 | const struct iwl_channel_info *iwl_get_channel_info( | 317 | const struct iwl_channel_info *iwl_get_channel_info( |
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-file.h b/drivers/net/wireless/iwlwifi/iwl-fw-file.h index c924ccb93c8c..e71564053e7f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fw-file.h +++ b/drivers/net/wireless/iwlwifi/iwl-fw-file.h | |||
@@ -93,15 +93,7 @@ struct iwl_ucode_header { | |||
93 | * new TLV uCode file layout | 93 | * new TLV uCode file layout |
94 | * | 94 | * |
95 | * The new TLV file format contains TLVs, that each specify | 95 | * The new TLV file format contains TLVs, that each specify |
96 | * some piece of data. To facilitate "groups", for example | 96 | * some piece of data. |
97 | * different instruction image with different capabilities, | ||
98 | * bundled with the same init image, an alternative mechanism | ||
99 | * is provided: | ||
100 | * When the alternative field is 0, that means that the item | ||
101 | * is always valid. When it is non-zero, then it is only | ||
102 | * valid in conjunction with items of the same alternative, | ||
103 | * in which case the driver (user) selects one alternative | ||
104 | * to use. | ||
105 | */ | 97 | */ |
106 | 98 | ||
107 | enum iwl_ucode_tlv_type { | 99 | enum iwl_ucode_tlv_type { |
@@ -132,8 +124,7 @@ enum iwl_ucode_tlv_type { | |||
132 | }; | 124 | }; |
133 | 125 | ||
134 | struct iwl_ucode_tlv { | 126 | struct iwl_ucode_tlv { |
135 | __le16 type; /* see above */ | 127 | __le32 type; /* see above */ |
136 | __le16 alternative; /* see comment */ | ||
137 | __le32 length; /* not including type/length fields */ | 128 | __le32 length; /* not including type/length fields */ |
138 | u8 data[0]; | 129 | u8 data[0]; |
139 | }; | 130 | }; |
@@ -152,7 +143,7 @@ struct iwl_tlv_ucode_header { | |||
152 | u8 human_readable[64]; | 143 | u8 human_readable[64]; |
153 | __le32 ver; /* major/minor/API/serial */ | 144 | __le32 ver; /* major/minor/API/serial */ |
154 | __le32 build; | 145 | __le32 build; |
155 | __le64 alternatives; /* bitmask of valid alternatives */ | 146 | __le64 ignore; |
156 | /* | 147 | /* |
157 | * The data contained herein has a TLV layout, | 148 | * The data contained herein has a TLV layout, |
158 | * see above for the TLV header and types. | 149 | * see above for the TLV header and types. |
diff --git a/drivers/net/wireless/iwlwifi/iwl-mac80211.c b/drivers/net/wireless/iwlwifi/iwl-mac80211.c index f1c675a2a6f3..3f82ff4f3afe 100644 --- a/drivers/net/wireless/iwlwifi/iwl-mac80211.c +++ b/drivers/net/wireless/iwlwifi/iwl-mac80211.c | |||
@@ -160,7 +160,7 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv, | |||
160 | IEEE80211_HW_SUPPORTS_DYNAMIC_PS | | 160 | IEEE80211_HW_SUPPORTS_DYNAMIC_PS | |
161 | IEEE80211_HW_SCAN_WHILE_IDLE; | 161 | IEEE80211_HW_SCAN_WHILE_IDLE; |
162 | 162 | ||
163 | if (hw_params(priv).sku & EEPROM_SKU_CAP_11N_ENABLE) | 163 | if (priv->hw_params.sku & EEPROM_SKU_CAP_11N_ENABLE) |
164 | hw->flags |= IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS | | 164 | hw->flags |= IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS | |
165 | IEEE80211_HW_SUPPORTS_STATIC_SMPS; | 165 | IEEE80211_HW_SUPPORTS_STATIC_SMPS; |
166 | 166 | ||
@@ -333,7 +333,7 @@ static int iwlagn_mac_start(struct ieee80211_hw *hw) | |||
333 | return 0; | 333 | return 0; |
334 | } | 334 | } |
335 | 335 | ||
336 | static void iwlagn_mac_stop(struct ieee80211_hw *hw) | 336 | void iwlagn_mac_stop(struct ieee80211_hw *hw) |
337 | { | 337 | { |
338 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 338 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
339 | 339 | ||
@@ -361,9 +361,9 @@ static void iwlagn_mac_stop(struct ieee80211_hw *hw) | |||
361 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 361 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
362 | } | 362 | } |
363 | 363 | ||
364 | static void iwlagn_mac_set_rekey_data(struct ieee80211_hw *hw, | 364 | void iwlagn_mac_set_rekey_data(struct ieee80211_hw *hw, |
365 | struct ieee80211_vif *vif, | 365 | struct ieee80211_vif *vif, |
366 | struct cfg80211_gtk_rekey_data *data) | 366 | struct cfg80211_gtk_rekey_data *data) |
367 | { | 367 | { |
368 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 368 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
369 | 369 | ||
@@ -389,8 +389,7 @@ static void iwlagn_mac_set_rekey_data(struct ieee80211_hw *hw, | |||
389 | 389 | ||
390 | #ifdef CONFIG_PM_SLEEP | 390 | #ifdef CONFIG_PM_SLEEP |
391 | 391 | ||
392 | static int iwlagn_mac_suspend(struct ieee80211_hw *hw, | 392 | int iwlagn_mac_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) |
393 | struct cfg80211_wowlan *wowlan) | ||
394 | { | 393 | { |
395 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 394 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
396 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | 395 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; |
@@ -499,7 +498,7 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw) | |||
499 | 498 | ||
500 | #endif | 499 | #endif |
501 | 500 | ||
502 | static void iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | 501 | void iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) |
503 | { | 502 | { |
504 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 503 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
505 | 504 | ||
@@ -510,21 +509,21 @@ static void iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
510 | dev_kfree_skb_any(skb); | 509 | dev_kfree_skb_any(skb); |
511 | } | 510 | } |
512 | 511 | ||
513 | static void iwlagn_mac_update_tkip_key(struct ieee80211_hw *hw, | 512 | void iwlagn_mac_update_tkip_key(struct ieee80211_hw *hw, |
514 | struct ieee80211_vif *vif, | 513 | struct ieee80211_vif *vif, |
515 | struct ieee80211_key_conf *keyconf, | 514 | struct ieee80211_key_conf *keyconf, |
516 | struct ieee80211_sta *sta, | 515 | struct ieee80211_sta *sta, |
517 | u32 iv32, u16 *phase1key) | 516 | u32 iv32, u16 *phase1key) |
518 | { | 517 | { |
519 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 518 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
520 | 519 | ||
521 | iwl_update_tkip_key(priv, vif, keyconf, sta, iv32, phase1key); | 520 | iwl_update_tkip_key(priv, vif, keyconf, sta, iv32, phase1key); |
522 | } | 521 | } |
523 | 522 | ||
524 | static int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | 523 | int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, |
525 | struct ieee80211_vif *vif, | 524 | struct ieee80211_vif *vif, |
526 | struct ieee80211_sta *sta, | 525 | struct ieee80211_sta *sta, |
527 | struct ieee80211_key_conf *key) | 526 | struct ieee80211_key_conf *key) |
528 | { | 527 | { |
529 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 528 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
530 | struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; | 529 | struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; |
@@ -624,11 +623,11 @@ static int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
624 | return ret; | 623 | return ret; |
625 | } | 624 | } |
626 | 625 | ||
627 | static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, | 626 | int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, |
628 | struct ieee80211_vif *vif, | 627 | struct ieee80211_vif *vif, |
629 | enum ieee80211_ampdu_mlme_action action, | 628 | enum ieee80211_ampdu_mlme_action action, |
630 | struct ieee80211_sta *sta, u16 tid, u16 *ssn, | 629 | struct ieee80211_sta *sta, u16 tid, u16 *ssn, |
631 | u8 buf_size) | 630 | u8 buf_size) |
632 | { | 631 | { |
633 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 632 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
634 | int ret = -EINVAL; | 633 | int ret = -EINVAL; |
@@ -637,7 +636,7 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, | |||
637 | IWL_DEBUG_HT(priv, "A-MPDU action on addr %pM tid %d\n", | 636 | IWL_DEBUG_HT(priv, "A-MPDU action on addr %pM tid %d\n", |
638 | sta->addr, tid); | 637 | sta->addr, tid); |
639 | 638 | ||
640 | if (!(hw_params(priv).sku & EEPROM_SKU_CAP_11N_ENABLE)) | 639 | if (!(priv->hw_params.sku & EEPROM_SKU_CAP_11N_ENABLE)) |
641 | return -EACCES; | 640 | return -EACCES; |
642 | 641 | ||
643 | IWL_DEBUG_MAC80211(priv, "enter\n"); | 642 | IWL_DEBUG_MAC80211(priv, "enter\n"); |
@@ -671,7 +670,7 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, | |||
671 | priv->agg_tids_count); | 670 | priv->agg_tids_count); |
672 | } | 671 | } |
673 | if (!priv->agg_tids_count && | 672 | if (!priv->agg_tids_count && |
674 | hw_params(priv).use_rts_for_aggregation) { | 673 | priv->hw_params.use_rts_for_aggregation) { |
675 | /* | 674 | /* |
676 | * switch off RTS/CTS if it was previously enabled | 675 | * switch off RTS/CTS if it was previously enabled |
677 | */ | 676 | */ |
@@ -750,11 +749,11 @@ static int iwlagn_mac_sta_remove(struct ieee80211_hw *hw, | |||
750 | return ret; | 749 | return ret; |
751 | } | 750 | } |
752 | 751 | ||
753 | static int iwlagn_mac_sta_state(struct ieee80211_hw *hw, | 752 | int iwlagn_mac_sta_state(struct ieee80211_hw *hw, |
754 | struct ieee80211_vif *vif, | 753 | struct ieee80211_vif *vif, |
755 | struct ieee80211_sta *sta, | 754 | struct ieee80211_sta *sta, |
756 | enum ieee80211_sta_state old_state, | 755 | enum ieee80211_sta_state old_state, |
757 | enum ieee80211_sta_state new_state) | 756 | enum ieee80211_sta_state new_state) |
758 | { | 757 | { |
759 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 758 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
760 | struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; | 759 | struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; |
@@ -833,8 +832,8 @@ static int iwlagn_mac_sta_state(struct ieee80211_hw *hw, | |||
833 | return ret; | 832 | return ret; |
834 | } | 833 | } |
835 | 834 | ||
836 | static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, | 835 | void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, |
837 | struct ieee80211_channel_switch *ch_switch) | 836 | struct ieee80211_channel_switch *ch_switch) |
838 | { | 837 | { |
839 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 838 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
840 | const struct iwl_channel_info *ch_info; | 839 | const struct iwl_channel_info *ch_info; |
@@ -867,7 +866,7 @@ static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, | |||
867 | if (!iwl_is_associated_ctx(ctx)) | 866 | if (!iwl_is_associated_ctx(ctx)) |
868 | goto out; | 867 | goto out; |
869 | 868 | ||
870 | if (!cfg(priv)->lib->set_channel_switch) | 869 | if (!priv->lib->set_channel_switch) |
871 | goto out; | 870 | goto out; |
872 | 871 | ||
873 | ch = channel->hw_value; | 872 | ch = channel->hw_value; |
@@ -903,7 +902,7 @@ static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, | |||
903 | */ | 902 | */ |
904 | set_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status); | 903 | set_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status); |
905 | priv->switch_channel = cpu_to_le16(ch); | 904 | priv->switch_channel = cpu_to_le16(ch); |
906 | if (cfg(priv)->lib->set_channel_switch(priv, ch_switch)) { | 905 | if (priv->lib->set_channel_switch(priv, ch_switch)) { |
907 | clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status); | 906 | clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status); |
908 | priv->switch_channel = 0; | 907 | priv->switch_channel = 0; |
909 | ieee80211_chswitch_done(ctx->vif, false); | 908 | ieee80211_chswitch_done(ctx->vif, false); |
@@ -914,10 +913,25 @@ out: | |||
914 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 913 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
915 | } | 914 | } |
916 | 915 | ||
917 | static void iwlagn_configure_filter(struct ieee80211_hw *hw, | 916 | void iwl_chswitch_done(struct iwl_priv *priv, bool is_success) |
918 | unsigned int changed_flags, | 917 | { |
919 | unsigned int *total_flags, | 918 | /* |
920 | u64 multicast) | 919 | * MULTI-FIXME |
920 | * See iwlagn_mac_channel_switch. | ||
921 | */ | ||
922 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | ||
923 | |||
924 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | ||
925 | return; | ||
926 | |||
927 | if (test_and_clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status)) | ||
928 | ieee80211_chswitch_done(ctx->vif, is_success); | ||
929 | } | ||
930 | |||
931 | void iwlagn_configure_filter(struct ieee80211_hw *hw, | ||
932 | unsigned int changed_flags, | ||
933 | unsigned int *total_flags, | ||
934 | u64 multicast) | ||
921 | { | 935 | { |
922 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 936 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
923 | __le32 filter_or = 0, filter_nand = 0; | 937 | __le32 filter_or = 0, filter_nand = 0; |
@@ -964,7 +978,7 @@ static void iwlagn_configure_filter(struct ieee80211_hw *hw, | |||
964 | FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL; | 978 | FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL; |
965 | } | 979 | } |
966 | 980 | ||
967 | static void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop) | 981 | void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop) |
968 | { | 982 | { |
969 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 983 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
970 | 984 | ||
@@ -1091,7 +1105,7 @@ static int iwlagn_mac_remain_on_channel(struct ieee80211_hw *hw, | |||
1091 | return err; | 1105 | return err; |
1092 | } | 1106 | } |
1093 | 1107 | ||
1094 | static int iwlagn_mac_cancel_remain_on_channel(struct ieee80211_hw *hw) | 1108 | int iwlagn_mac_cancel_remain_on_channel(struct ieee80211_hw *hw) |
1095 | { | 1109 | { |
1096 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 1110 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
1097 | 1111 | ||
@@ -1108,8 +1122,8 @@ static int iwlagn_mac_cancel_remain_on_channel(struct ieee80211_hw *hw) | |||
1108 | return 0; | 1122 | return 0; |
1109 | } | 1123 | } |
1110 | 1124 | ||
1111 | static void iwlagn_mac_rssi_callback(struct ieee80211_hw *hw, | 1125 | void iwlagn_mac_rssi_callback(struct ieee80211_hw *hw, |
1112 | enum ieee80211_rssi_event rssi_event) | 1126 | enum ieee80211_rssi_event rssi_event) |
1113 | { | 1127 | { |
1114 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 1128 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
1115 | 1129 | ||
@@ -1133,8 +1147,8 @@ static void iwlagn_mac_rssi_callback(struct ieee80211_hw *hw, | |||
1133 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 1147 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
1134 | } | 1148 | } |
1135 | 1149 | ||
1136 | static int iwlagn_mac_set_tim(struct ieee80211_hw *hw, | 1150 | int iwlagn_mac_set_tim(struct ieee80211_hw *hw, |
1137 | struct ieee80211_sta *sta, bool set) | 1151 | struct ieee80211_sta *sta, bool set) |
1138 | { | 1152 | { |
1139 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 1153 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
1140 | 1154 | ||
@@ -1143,9 +1157,9 @@ static int iwlagn_mac_set_tim(struct ieee80211_hw *hw, | |||
1143 | return 0; | 1157 | return 0; |
1144 | } | 1158 | } |
1145 | 1159 | ||
1146 | static int iwlagn_mac_conf_tx(struct ieee80211_hw *hw, | 1160 | int iwlagn_mac_conf_tx(struct ieee80211_hw *hw, |
1147 | struct ieee80211_vif *vif, u16 queue, | 1161 | struct ieee80211_vif *vif, u16 queue, |
1148 | const struct ieee80211_tx_queue_params *params) | 1162 | const struct ieee80211_tx_queue_params *params) |
1149 | { | 1163 | { |
1150 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 1164 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
1151 | struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; | 1165 | struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; |
@@ -1187,7 +1201,7 @@ static int iwlagn_mac_conf_tx(struct ieee80211_hw *hw, | |||
1187 | return 0; | 1201 | return 0; |
1188 | } | 1202 | } |
1189 | 1203 | ||
1190 | static int iwlagn_mac_tx_last_beacon(struct ieee80211_hw *hw) | 1204 | int iwlagn_mac_tx_last_beacon(struct ieee80211_hw *hw) |
1191 | { | 1205 | { |
1192 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 1206 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
1193 | 1207 | ||
@@ -1203,8 +1217,7 @@ static int iwl_set_mode(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | |||
1203 | return iwlagn_commit_rxon(priv, ctx); | 1217 | return iwlagn_commit_rxon(priv, ctx); |
1204 | } | 1218 | } |
1205 | 1219 | ||
1206 | static int iwl_setup_interface(struct iwl_priv *priv, | 1220 | int iwl_setup_interface(struct iwl_priv *priv, struct iwl_rxon_context *ctx) |
1207 | struct iwl_rxon_context *ctx) | ||
1208 | { | 1221 | { |
1209 | struct ieee80211_vif *vif = ctx->vif; | 1222 | struct ieee80211_vif *vif = ctx->vif; |
1210 | int err; | 1223 | int err; |
@@ -1307,9 +1320,9 @@ static int iwlagn_mac_add_interface(struct ieee80211_hw *hw, | |||
1307 | return err; | 1320 | return err; |
1308 | } | 1321 | } |
1309 | 1322 | ||
1310 | static void iwl_teardown_interface(struct iwl_priv *priv, | 1323 | void iwl_teardown_interface(struct iwl_priv *priv, |
1311 | struct ieee80211_vif *vif, | 1324 | struct ieee80211_vif *vif, |
1312 | bool mode_change) | 1325 | bool mode_change) |
1313 | { | 1326 | { |
1314 | struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); | 1327 | struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); |
1315 | 1328 | ||
@@ -1450,9 +1463,9 @@ static int iwlagn_mac_change_interface(struct ieee80211_hw *hw, | |||
1450 | return err; | 1463 | return err; |
1451 | } | 1464 | } |
1452 | 1465 | ||
1453 | static int iwlagn_mac_hw_scan(struct ieee80211_hw *hw, | 1466 | int iwlagn_mac_hw_scan(struct ieee80211_hw *hw, |
1454 | struct ieee80211_vif *vif, | 1467 | struct ieee80211_vif *vif, |
1455 | struct cfg80211_scan_request *req) | 1468 | struct cfg80211_scan_request *req) |
1456 | { | 1469 | { |
1457 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 1470 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
1458 | int ret; | 1471 | int ret; |
@@ -1507,7 +1520,7 @@ static void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id) | |||
1507 | iwl_send_add_sta(priv, &cmd, CMD_ASYNC); | 1520 | iwl_send_add_sta(priv, &cmd, CMD_ASYNC); |
1508 | } | 1521 | } |
1509 | 1522 | ||
1510 | static void iwlagn_mac_sta_notify(struct ieee80211_hw *hw, | 1523 | void iwlagn_mac_sta_notify(struct ieee80211_hw *hw, |
1511 | struct ieee80211_vif *vif, | 1524 | struct ieee80211_vif *vif, |
1512 | enum sta_notify_cmd cmd, | 1525 | enum sta_notify_cmd cmd, |
1513 | struct ieee80211_sta *sta) | 1526 | struct ieee80211_sta *sta) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-op-mode.h b/drivers/net/wireless/iwlwifi/iwl-op-mode.h index b1fd251e88d5..ca947aebb727 100644 --- a/drivers/net/wireless/iwlwifi/iwl-op-mode.h +++ b/drivers/net/wireless/iwlwifi/iwl-op-mode.h | |||
@@ -125,6 +125,7 @@ struct iwl_fw; | |||
125 | * @cmd_queue_full: Called when the command queue gets full. Must be atomic. | 125 | * @cmd_queue_full: Called when the command queue gets full. Must be atomic. |
126 | * @nic_config: configure NIC, called before firmware is started. | 126 | * @nic_config: configure NIC, called before firmware is started. |
127 | * May sleep | 127 | * May sleep |
128 | * @wimax_active: invoked when WiMax becomes active. Must be atomic. | ||
128 | */ | 129 | */ |
129 | struct iwl_op_mode_ops { | 130 | struct iwl_op_mode_ops { |
130 | struct iwl_op_mode *(*start)(struct iwl_trans *trans, | 131 | struct iwl_op_mode *(*start)(struct iwl_trans *trans, |
@@ -139,6 +140,7 @@ struct iwl_op_mode_ops { | |||
139 | void (*nic_error)(struct iwl_op_mode *op_mode); | 140 | void (*nic_error)(struct iwl_op_mode *op_mode); |
140 | void (*cmd_queue_full)(struct iwl_op_mode *op_mode); | 141 | void (*cmd_queue_full)(struct iwl_op_mode *op_mode); |
141 | void (*nic_config)(struct iwl_op_mode *op_mode); | 142 | void (*nic_config)(struct iwl_op_mode *op_mode); |
143 | void (*wimax_active)(struct iwl_op_mode *op_mode); | ||
142 | }; | 144 | }; |
143 | 145 | ||
144 | /** | 146 | /** |
@@ -209,6 +211,11 @@ static inline void iwl_op_mode_nic_config(struct iwl_op_mode *op_mode) | |||
209 | op_mode->ops->nic_config(op_mode); | 211 | op_mode->ops->nic_config(op_mode); |
210 | } | 212 | } |
211 | 213 | ||
214 | static inline void iwl_op_mode_wimax_active(struct iwl_op_mode *op_mode) | ||
215 | { | ||
216 | op_mode->ops->wimax_active(op_mode); | ||
217 | } | ||
218 | |||
212 | /***************************************************** | 219 | /***************************************************** |
213 | * Op mode layers implementations | 220 | * Op mode layers implementations |
214 | ******************************************************/ | 221 | ******************************************************/ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-pci.c b/drivers/net/wireless/iwlwifi/iwl-pci.c index f3e56b04d775..754001581340 100644 --- a/drivers/net/wireless/iwlwifi/iwl-pci.c +++ b/drivers/net/wireless/iwlwifi/iwl-pci.c | |||
@@ -67,10 +67,8 @@ | |||
67 | #include <linux/pci.h> | 67 | #include <linux/pci.h> |
68 | #include <linux/pci-aspm.h> | 68 | #include <linux/pci-aspm.h> |
69 | 69 | ||
70 | #include "iwl-io.h" | ||
71 | #include "iwl-shared.h" | 70 | #include "iwl-shared.h" |
72 | #include "iwl-trans.h" | 71 | #include "iwl-trans.h" |
73 | #include "iwl-csr.h" | ||
74 | #include "iwl-cfg.h" | 72 | #include "iwl-cfg.h" |
75 | #include "iwl-drv.h" | 73 | #include "iwl-drv.h" |
76 | #include "iwl-trans.h" | 74 | #include "iwl-trans.h" |
diff --git a/drivers/net/wireless/iwlwifi/iwl-phy-db.c b/drivers/net/wireless/iwlwifi/iwl-phy-db.c index d65305d08ebf..1a791af82d15 100644 --- a/drivers/net/wireless/iwlwifi/iwl-phy-db.c +++ b/drivers/net/wireless/iwlwifi/iwl-phy-db.c | |||
@@ -228,8 +228,24 @@ static u16 channel_id_to_papd(u16 ch_id) | |||
228 | 228 | ||
229 | static u16 channel_id_to_txp(struct iwl_phy_db *phy_db, u16 ch_id) | 229 | static u16 channel_id_to_txp(struct iwl_phy_db *phy_db, u16 ch_id) |
230 | { | 230 | { |
231 | /* TODO David*/ | 231 | struct iwl_phy_db_chg_txp *txp_chg; |
232 | return 0; | 232 | int i; |
233 | u8 ch_index = ch_id_to_ch_index(ch_id); | ||
234 | if (ch_index == 0xff) | ||
235 | return 0xff; | ||
236 | |||
237 | for (i = 0; i < IWL_NUM_TXP_CH_GROUPS; i++) { | ||
238 | txp_chg = (void *)phy_db->calib_ch_group_txp[i].data; | ||
239 | if (!txp_chg) | ||
240 | return 0xff; | ||
241 | /* | ||
242 | * Looking for the first channel group that its max channel is | ||
243 | * higher then wanted channel. | ||
244 | */ | ||
245 | if (le16_to_cpu(txp_chg->max_channel_idx) >= ch_index) | ||
246 | return i; | ||
247 | } | ||
248 | return 0xff; | ||
233 | } | 249 | } |
234 | 250 | ||
235 | int iwl_phy_db_get_section_data(struct iwl_phy_db *phy_db, | 251 | int iwl_phy_db_get_section_data(struct iwl_phy_db *phy_db, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-phy-db.h b/drivers/net/wireless/iwlwifi/iwl-phy-db.h index ba91a8b28398..5e86305de66a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-phy-db.h +++ b/drivers/net/wireless/iwlwifi/iwl-phy-db.h | |||
@@ -108,6 +108,12 @@ enum iwl_phy_db_section_type { | |||
108 | IWL_PHY_DB_MAX | 108 | IWL_PHY_DB_MAX |
109 | }; | 109 | }; |
110 | 110 | ||
111 | /* for parsing of tx power channel group data that comes from the firmware*/ | ||
112 | struct iwl_phy_db_chg_txp { | ||
113 | __le32 space; | ||
114 | __le16 max_channel_idx; | ||
115 | } __packed; | ||
116 | |||
111 | struct iwl_phy_db *iwl_phy_db_init(struct iwl_shared *shrd); | 117 | struct iwl_phy_db *iwl_phy_db_init(struct iwl_shared *shrd); |
112 | 118 | ||
113 | void iwl_phy_db_free(struct iwl_phy_db *phy_db); | 119 | void iwl_phy_db_free(struct iwl_phy_db *phy_db); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c index 7bc7a82aba47..174a0f737214 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.c +++ b/drivers/net/wireless/iwlwifi/iwl-power.c | |||
@@ -268,61 +268,6 @@ static void iwl_power_sleep_cam_cmd(struct iwl_priv *priv, | |||
268 | IWL_DEBUG_POWER(priv, "Sleep command for CAM\n"); | 268 | IWL_DEBUG_POWER(priv, "Sleep command for CAM\n"); |
269 | } | 269 | } |
270 | 270 | ||
271 | static void iwl_power_fill_sleep_cmd(struct iwl_priv *priv, | ||
272 | struct iwl_powertable_cmd *cmd, | ||
273 | int dynps_ms, int wakeup_period) | ||
274 | { | ||
275 | /* | ||
276 | * These are the original power level 3 sleep successions. The | ||
277 | * device may behave better with such succession and was also | ||
278 | * only tested with that. Just like the original sleep commands, | ||
279 | * also adjust the succession here to the wakeup_period below. | ||
280 | * The ranges are the same as for the sleep commands, 0-2, 3-9 | ||
281 | * and >10, which is selected based on the DTIM interval for | ||
282 | * the sleep index but here we use the wakeup period since that | ||
283 | * is what we need to do for the latency requirements. | ||
284 | */ | ||
285 | static const u8 slp_succ_r0[IWL_POWER_VEC_SIZE] = { 2, 2, 2, 2, 2 }; | ||
286 | static const u8 slp_succ_r1[IWL_POWER_VEC_SIZE] = { 2, 4, 6, 7, 9 }; | ||
287 | static const u8 slp_succ_r2[IWL_POWER_VEC_SIZE] = { 2, 7, 9, 9, 0xFF }; | ||
288 | const u8 *slp_succ = slp_succ_r0; | ||
289 | int i; | ||
290 | |||
291 | if (wakeup_period > IWL_DTIM_RANGE_0_MAX) | ||
292 | slp_succ = slp_succ_r1; | ||
293 | if (wakeup_period > IWL_DTIM_RANGE_1_MAX) | ||
294 | slp_succ = slp_succ_r2; | ||
295 | |||
296 | memset(cmd, 0, sizeof(*cmd)); | ||
297 | |||
298 | cmd->flags = IWL_POWER_DRIVER_ALLOW_SLEEP_MSK | | ||
299 | IWL_POWER_FAST_PD; /* no use seeing frames for others */ | ||
300 | |||
301 | if (priv->power_data.bus_pm) | ||
302 | cmd->flags |= IWL_POWER_PCI_PM_MSK; | ||
303 | |||
304 | if (cfg(priv)->base_params->shadow_reg_enable) | ||
305 | cmd->flags |= IWL_POWER_SHADOW_REG_ENA; | ||
306 | else | ||
307 | cmd->flags &= ~IWL_POWER_SHADOW_REG_ENA; | ||
308 | |||
309 | if (iwl_advanced_bt_coexist(priv)) { | ||
310 | if (!cfg(priv)->bt_params->bt_sco_disable) | ||
311 | cmd->flags |= IWL_POWER_BT_SCO_ENA; | ||
312 | else | ||
313 | cmd->flags &= ~IWL_POWER_BT_SCO_ENA; | ||
314 | } | ||
315 | |||
316 | cmd->rx_data_timeout = cpu_to_le32(1000 * dynps_ms); | ||
317 | cmd->tx_data_timeout = cpu_to_le32(1000 * dynps_ms); | ||
318 | |||
319 | for (i = 0; i < IWL_POWER_VEC_SIZE; i++) | ||
320 | cmd->sleep_interval[i] = | ||
321 | cpu_to_le32(min_t(int, slp_succ[i], wakeup_period)); | ||
322 | |||
323 | IWL_DEBUG_POWER(priv, "Automatic sleep command\n"); | ||
324 | } | ||
325 | |||
326 | static int iwl_set_power(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd) | 271 | static int iwl_set_power(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd) |
327 | { | 272 | { |
328 | IWL_DEBUG_POWER(priv, "Sending power/sleep command\n"); | 273 | IWL_DEBUG_POWER(priv, "Sending power/sleep command\n"); |
@@ -363,7 +308,7 @@ static void iwl_power_build_cmd(struct iwl_priv *priv, | |||
363 | iwl_static_sleep_cmd(priv, cmd, | 308 | iwl_static_sleep_cmd(priv, cmd, |
364 | priv->power_data.debug_sleep_level_override, | 309 | priv->power_data.debug_sleep_level_override, |
365 | dtimper); | 310 | dtimper); |
366 | else if (iwlagn_mod_params.no_sleep_autoadjust) { | 311 | else { |
367 | if (iwlagn_mod_params.power_level > IWL_POWER_INDEX_1 && | 312 | if (iwlagn_mod_params.power_level > IWL_POWER_INDEX_1 && |
368 | iwlagn_mod_params.power_level <= IWL_POWER_INDEX_5) | 313 | iwlagn_mod_params.power_level <= IWL_POWER_INDEX_5) |
369 | iwl_static_sleep_cmd(priv, cmd, | 314 | iwl_static_sleep_cmd(priv, cmd, |
@@ -371,10 +316,7 @@ static void iwl_power_build_cmd(struct iwl_priv *priv, | |||
371 | else | 316 | else |
372 | iwl_static_sleep_cmd(priv, cmd, | 317 | iwl_static_sleep_cmd(priv, cmd, |
373 | IWL_POWER_INDEX_1, dtimper); | 318 | IWL_POWER_INDEX_1, dtimper); |
374 | } else | 319 | } |
375 | iwl_power_fill_sleep_cmd(priv, cmd, | ||
376 | priv->hw->conf.dynamic_ps_timeout, | ||
377 | priv->hw->conf.max_sleep_period); | ||
378 | } | 320 | } |
379 | 321 | ||
380 | int iwl_power_set_mode(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd, | 322 | int iwl_power_set_mode(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index dcf5b12071b4..490a60d8ad7d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c | |||
@@ -673,12 +673,12 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
673 | u16 rx_chain = 0; | 673 | u16 rx_chain = 0; |
674 | enum ieee80211_band band; | 674 | enum ieee80211_band band; |
675 | u8 n_probes = 0; | 675 | u8 n_probes = 0; |
676 | u8 rx_ant = hw_params(priv).valid_rx_ant; | 676 | u8 rx_ant = priv->hw_params.valid_rx_ant; |
677 | u8 rate; | 677 | u8 rate; |
678 | bool is_active = false; | 678 | bool is_active = false; |
679 | int chan_mod; | 679 | int chan_mod; |
680 | u8 active_chains; | 680 | u8 active_chains; |
681 | u8 scan_tx_antennas = hw_params(priv).valid_tx_ant; | 681 | u8 scan_tx_antennas = priv->hw_params.valid_tx_ant; |
682 | int ret; | 682 | int ret; |
683 | 683 | ||
684 | lockdep_assert_held(&priv->mutex); | 684 | lockdep_assert_held(&priv->mutex); |
@@ -872,7 +872,7 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
872 | 872 | ||
873 | /* MIMO is not used here, but value is required */ | 873 | /* MIMO is not used here, but value is required */ |
874 | rx_chain |= | 874 | rx_chain |= |
875 | hw_params(priv).valid_rx_ant << RXON_RX_CHAIN_VALID_POS; | 875 | priv->hw_params.valid_rx_ant << RXON_RX_CHAIN_VALID_POS; |
876 | rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS; | 876 | rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS; |
877 | rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_SEL_POS; | 877 | rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_SEL_POS; |
878 | rx_chain |= 0x1 << RXON_RX_CHAIN_DRIVER_FORCE_POS; | 878 | rx_chain |= 0x1 << RXON_RX_CHAIN_DRIVER_FORCE_POS; |
@@ -985,7 +985,7 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
985 | 985 | ||
986 | void iwl_init_scan_params(struct iwl_priv *priv) | 986 | void iwl_init_scan_params(struct iwl_priv *priv) |
987 | { | 987 | { |
988 | u8 ant_idx = fls(hw_params(priv).valid_tx_ant) - 1; | 988 | u8 ant_idx = fls(priv->hw_params.valid_tx_ant) - 1; |
989 | if (!priv->scan_tx_ant[IEEE80211_BAND_5GHZ]) | 989 | if (!priv->scan_tx_ant[IEEE80211_BAND_5GHZ]) |
990 | priv->scan_tx_ant[IEEE80211_BAND_5GHZ] = ant_idx; | 990 | priv->scan_tx_ant[IEEE80211_BAND_5GHZ] = ant_idx; |
991 | if (!priv->scan_tx_ant[IEEE80211_BAND_2GHZ]) | 991 | if (!priv->scan_tx_ant[IEEE80211_BAND_2GHZ]) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h index 983b41e43d4b..35bd83ce3dae 100644 --- a/drivers/net/wireless/iwlwifi/iwl-shared.h +++ b/drivers/net/wireless/iwlwifi/iwl-shared.h | |||
@@ -70,6 +70,7 @@ | |||
70 | 70 | ||
71 | #include "iwl-commands.h" | 71 | #include "iwl-commands.h" |
72 | #include "iwl-fw.h" | 72 | #include "iwl-fw.h" |
73 | #include "iwl-config.h" | ||
73 | 74 | ||
74 | /** | 75 | /** |
75 | * DOC: shared area - role and goal | 76 | * DOC: shared area - role and goal |
@@ -95,7 +96,6 @@ | |||
95 | 96 | ||
96 | struct iwl_priv; | 97 | struct iwl_priv; |
97 | struct iwl_trans; | 98 | struct iwl_trans; |
98 | struct iwl_sensitivity_ranges; | ||
99 | struct iwl_trans_ops; | 99 | struct iwl_trans_ops; |
100 | 100 | ||
101 | #define DRV_NAME "iwlwifi" | 101 | #define DRV_NAME "iwlwifi" |
@@ -118,252 +118,56 @@ extern struct iwl_mod_params iwlagn_mod_params; | |||
118 | * @disable_11n: disable 11n capabilities, default = 0, | 118 | * @disable_11n: disable 11n capabilities, default = 0, |
119 | * use IWL_DISABLE_HT_* constants | 119 | * use IWL_DISABLE_HT_* constants |
120 | * @amsdu_size_8K: enable 8K amsdu size, default = 1 | 120 | * @amsdu_size_8K: enable 8K amsdu size, default = 1 |
121 | * @antenna: both antennas (use diversity), default = 0 | ||
122 | * @restart_fw: restart firmware, default = 1 | 121 | * @restart_fw: restart firmware, default = 1 |
123 | * @plcp_check: enable plcp health check, default = true | 122 | * @plcp_check: enable plcp health check, default = true |
124 | * @ack_check: disable ack health check, default = false | ||
125 | * @wd_disable: enable stuck queue check, default = 0 | 123 | * @wd_disable: enable stuck queue check, default = 0 |
126 | * @bt_coex_active: enable bt coex, default = true | 124 | * @bt_coex_active: enable bt coex, default = true |
127 | * @led_mode: system default, default = 0 | 125 | * @led_mode: system default, default = 0 |
128 | * @no_sleep_autoadjust: disable autoadjust, default = true | ||
129 | * @power_save: disable power save, default = false | 126 | * @power_save: disable power save, default = false |
130 | * @power_level: power level, default = 1 | 127 | * @power_level: power level, default = 1 |
131 | * @debug_level: levels are IWL_DL_* | 128 | * @debug_level: levels are IWL_DL_* |
132 | * @ant_coupling: antenna coupling in dB, default = 0 | 129 | * @ant_coupling: antenna coupling in dB, default = 0 |
133 | * @bt_ch_announce: BT channel inhibition, default = enable | 130 | * @bt_ch_announce: BT channel inhibition, default = enable |
134 | * @wanted_ucode_alternative: ucode alternative to use, default = 1 | ||
135 | * @auto_agg: enable agg. without check, default = true | 131 | * @auto_agg: enable agg. without check, default = true |
136 | */ | 132 | */ |
137 | struct iwl_mod_params { | 133 | struct iwl_mod_params { |
138 | int sw_crypto; | 134 | int sw_crypto; |
139 | unsigned int disable_11n; | 135 | unsigned int disable_11n; |
140 | int amsdu_size_8K; | 136 | int amsdu_size_8K; |
141 | int antenna; | ||
142 | int restart_fw; | 137 | int restart_fw; |
143 | bool plcp_check; | 138 | bool plcp_check; |
144 | bool ack_check; | ||
145 | int wd_disable; | 139 | int wd_disable; |
146 | bool bt_coex_active; | 140 | bool bt_coex_active; |
147 | int led_mode; | 141 | int led_mode; |
148 | bool no_sleep_autoadjust; | ||
149 | bool power_save; | 142 | bool power_save; |
150 | int power_level; | 143 | int power_level; |
151 | u32 debug_level; | 144 | u32 debug_level; |
152 | int ant_coupling; | 145 | int ant_coupling; |
153 | bool bt_ch_announce; | 146 | bool bt_ch_announce; |
154 | int wanted_ucode_alternative; | ||
155 | bool auto_agg; | 147 | bool auto_agg; |
156 | }; | 148 | }; |
157 | 149 | ||
158 | /** | 150 | /** |
159 | * struct iwl_hw_params | ||
160 | * | ||
161 | * Holds the module parameters | ||
162 | * | ||
163 | * @tx_chains_num: Number of TX chains | ||
164 | * @rx_chains_num: Number of RX chains | ||
165 | * @valid_tx_ant: usable antennas for TX | ||
166 | * @valid_rx_ant: usable antennas for RX | ||
167 | * @ht40_channel: is 40MHz width possible: BIT(IEEE80211_BAND_XXX) | ||
168 | * @sku: sku read from EEPROM | ||
169 | * @rx_page_order: Rx buffer page order | ||
170 | * @ct_kill_threshold: temperature threshold - in hw dependent unit | ||
171 | * @ct_kill_exit_threshold: when to reeable the device - in hw dependent unit | ||
172 | * relevant for 1000, 6000 and up | ||
173 | * @wd_timeout: TX queues watchdog timeout | ||
174 | * @struct iwl_sensitivity_ranges: range of sensitivity values | ||
175 | * @use_rts_for_aggregation: use rts/cts protection for HT traffic | ||
176 | */ | ||
177 | struct iwl_hw_params { | ||
178 | u8 tx_chains_num; | ||
179 | u8 rx_chains_num; | ||
180 | u8 valid_tx_ant; | ||
181 | u8 valid_rx_ant; | ||
182 | u8 ht40_channel; | ||
183 | bool use_rts_for_aggregation; | ||
184 | u16 sku; | ||
185 | u32 rx_page_order; | ||
186 | u32 ct_kill_threshold; | ||
187 | u32 ct_kill_exit_threshold; | ||
188 | unsigned int wd_timeout; | ||
189 | |||
190 | const struct iwl_sensitivity_ranges *sens; | ||
191 | }; | ||
192 | |||
193 | /* | ||
194 | * LED mode | ||
195 | * IWL_LED_DEFAULT: use device default | ||
196 | * IWL_LED_RF_STATE: turn LED on/off based on RF state | ||
197 | * LED ON = RF ON | ||
198 | * LED OFF = RF OFF | ||
199 | * IWL_LED_BLINK: adjust led blink rate based on blink table | ||
200 | * IWL_LED_DISABLE: led disabled | ||
201 | */ | ||
202 | enum iwl_led_mode { | ||
203 | IWL_LED_DEFAULT, | ||
204 | IWL_LED_RF_STATE, | ||
205 | IWL_LED_BLINK, | ||
206 | IWL_LED_DISABLE, | ||
207 | }; | ||
208 | |||
209 | /* | ||
210 | * @max_ll_items: max number of OTP blocks | ||
211 | * @shadow_ram_support: shadow support for OTP memory | ||
212 | * @led_compensation: compensate on the led on/off time per HW according | ||
213 | * to the deviation to achieve the desired led frequency. | ||
214 | * The detail algorithm is described in iwl-led.c | ||
215 | * @chain_noise_num_beacons: number of beacons used to compute chain noise | ||
216 | * @adv_thermal_throttle: support advance thermal throttle | ||
217 | * @support_ct_kill_exit: support ct kill exit condition | ||
218 | * @plcp_delta_threshold: plcp error rate threshold used to trigger | ||
219 | * radio tuning when there is a high receiving plcp error rate | ||
220 | * @chain_noise_scale: default chain noise scale used for gain computation | ||
221 | * @wd_timeout: TX queues watchdog timeout | ||
222 | * @max_event_log_size: size of event log buffer size for ucode event logging | ||
223 | * @shadow_reg_enable: HW shadhow register bit | ||
224 | * @hd_v2: v2 of enhanced sensitivity value, used for 2000 series and up | ||
225 | * @no_idle_support: do not support idle mode | ||
226 | * wd_disable: disable watchdog timer | ||
227 | */ | ||
228 | struct iwl_base_params { | ||
229 | int eeprom_size; | ||
230 | int num_of_queues; /* def: HW dependent */ | ||
231 | /* for iwl_apm_init() */ | ||
232 | u32 pll_cfg_val; | ||
233 | |||
234 | const u16 max_ll_items; | ||
235 | const bool shadow_ram_support; | ||
236 | u16 led_compensation; | ||
237 | bool adv_thermal_throttle; | ||
238 | bool support_ct_kill_exit; | ||
239 | u8 plcp_delta_threshold; | ||
240 | s32 chain_noise_scale; | ||
241 | unsigned int wd_timeout; | ||
242 | u32 max_event_log_size; | ||
243 | const bool shadow_reg_enable; | ||
244 | const bool hd_v2; | ||
245 | const bool no_idle_support; | ||
246 | const bool wd_disable; | ||
247 | }; | ||
248 | |||
249 | /* | ||
250 | * @advanced_bt_coexist: support advanced bt coexist | ||
251 | * @bt_init_traffic_load: specify initial bt traffic load | ||
252 | * @bt_prio_boost: default bt priority boost value | ||
253 | * @agg_time_limit: maximum number of uSec in aggregation | ||
254 | * @bt_sco_disable: uCode should not response to BT in SCO/ESCO mode | ||
255 | */ | ||
256 | struct iwl_bt_params { | ||
257 | bool advanced_bt_coexist; | ||
258 | u8 bt_init_traffic_load; | ||
259 | u8 bt_prio_boost; | ||
260 | u16 agg_time_limit; | ||
261 | bool bt_sco_disable; | ||
262 | bool bt_session_2; | ||
263 | }; | ||
264 | /* | ||
265 | * @use_rts_for_aggregation: use rts/cts protection for HT traffic | ||
266 | */ | ||
267 | struct iwl_ht_params { | ||
268 | const bool ht_greenfield_support; /* if used set to true */ | ||
269 | bool use_rts_for_aggregation; | ||
270 | enum ieee80211_smps_mode smps_mode; | ||
271 | }; | ||
272 | |||
273 | /** | ||
274 | * struct iwl_cfg | ||
275 | * @name: Offical name of the device | ||
276 | * @fw_name_pre: Firmware filename prefix. The api version and extension | ||
277 | * (.ucode) will be added to filename before loading from disk. The | ||
278 | * filename is constructed as fw_name_pre<api>.ucode. | ||
279 | * @ucode_api_max: Highest version of uCode API supported by driver. | ||
280 | * @ucode_api_ok: oldest version of the uCode API that is OK to load | ||
281 | * without a warning, for use in transitions | ||
282 | * @ucode_api_min: Lowest version of uCode API supported by driver. | ||
283 | * @max_inst_size: The maximal length of the fw inst section | ||
284 | * @max_data_size: The maximal length of the fw data section | ||
285 | * @valid_tx_ant: valid transmit antenna | ||
286 | * @valid_rx_ant: valid receive antenna | ||
287 | * @eeprom_ver: EEPROM version | ||
288 | * @eeprom_calib_ver: EEPROM calibration version | ||
289 | * @lib: pointer to the lib ops | ||
290 | * @additional_nic_config: additional nic configuration | ||
291 | * @base_params: pointer to basic parameters | ||
292 | * @ht_params: point to ht patameters | ||
293 | * @bt_params: pointer to bt parameters | ||
294 | * @need_temp_offset_calib: need to perform temperature offset calibration | ||
295 | * @no_xtal_calib: some devices do not need crystal calibration data, | ||
296 | * don't send it to those | ||
297 | * @led_mode: 0=blinking, 1=On(RF On)/Off(RF Off) | ||
298 | * @adv_pm: advance power management | ||
299 | * @rx_with_siso_diversity: 1x1 device with rx antenna diversity | ||
300 | * @internal_wimax_coex: internal wifi/wimax combo device | ||
301 | * @temp_offset_v2: support v2 of temperature offset calibration | ||
302 | * | ||
303 | * We enable the driver to be backward compatible wrt. hardware features. | ||
304 | * API differences in uCode shouldn't be handled here but through TLVs | ||
305 | * and/or the uCode API version instead. | ||
306 | */ | ||
307 | struct iwl_cfg { | ||
308 | /* params specific to an individual device within a device family */ | ||
309 | const char *name; | ||
310 | const char *fw_name_pre; | ||
311 | const unsigned int ucode_api_max; | ||
312 | const unsigned int ucode_api_ok; | ||
313 | const unsigned int ucode_api_min; | ||
314 | const u32 max_data_size; | ||
315 | const u32 max_inst_size; | ||
316 | u8 valid_tx_ant; | ||
317 | u8 valid_rx_ant; | ||
318 | u16 eeprom_ver; | ||
319 | u16 eeprom_calib_ver; | ||
320 | const struct iwl_lib_ops *lib; | ||
321 | void (*additional_nic_config)(struct iwl_priv *priv); | ||
322 | /* params not likely to change within a device family */ | ||
323 | const struct iwl_base_params *base_params; | ||
324 | /* params likely to change within a device family */ | ||
325 | const struct iwl_ht_params *ht_params; | ||
326 | const struct iwl_bt_params *bt_params; | ||
327 | const bool need_temp_offset_calib; /* if used set to true */ | ||
328 | const bool no_xtal_calib; | ||
329 | enum iwl_led_mode led_mode; | ||
330 | const bool adv_pm; | ||
331 | const bool rx_with_siso_diversity; | ||
332 | const bool internal_wimax_coex; | ||
333 | const bool temp_offset_v2; | ||
334 | }; | ||
335 | |||
336 | /** | ||
337 | * struct iwl_shared - shared fields for all the layers of the driver | 151 | * struct iwl_shared - shared fields for all the layers of the driver |
338 | * | 152 | * |
339 | * @status: STATUS_* | ||
340 | * @wowlan: are we running wowlan uCode | 153 | * @wowlan: are we running wowlan uCode |
341 | * @bus: pointer to the bus layer data | 154 | * @bus: pointer to the bus layer data |
342 | * @cfg: see struct iwl_cfg | 155 | * @cfg: see struct iwl_cfg |
343 | * @priv: pointer to the upper layer data | 156 | * @priv: pointer to the upper layer data |
344 | * @trans: pointer to the transport layer data | 157 | * @trans: pointer to the transport layer data |
345 | * @nic: pointer to the nic data | 158 | * @nic: pointer to the nic data |
346 | * @hw_params: see struct iwl_hw_params | ||
347 | * @lock: protect general shared data | 159 | * @lock: protect general shared data |
348 | * @eeprom: pointer to the eeprom/OTP image | 160 | * @eeprom: pointer to the eeprom/OTP image |
349 | */ | 161 | */ |
350 | struct iwl_shared { | 162 | struct iwl_shared { |
351 | unsigned long status; | ||
352 | |||
353 | const struct iwl_cfg *cfg; | 163 | const struct iwl_cfg *cfg; |
354 | struct iwl_trans *trans; | 164 | struct iwl_trans *trans; |
355 | void *drv; | 165 | void *drv; |
356 | struct iwl_hw_params hw_params; | ||
357 | |||
358 | /* eeprom -- this is in the card's little endian byte order */ | ||
359 | u8 *eeprom; | ||
360 | |||
361 | }; | 166 | }; |
362 | 167 | ||
363 | /*Whatever _m is (iwl_trans, iwl_priv, these macros will work */ | 168 | /*Whatever _m is (iwl_trans, iwl_priv, these macros will work */ |
364 | #define cfg(_m) ((_m)->shrd->cfg) | 169 | #define cfg(_m) ((_m)->shrd->cfg) |
365 | #define trans(_m) ((_m)->shrd->trans) | 170 | #define trans(_m) ((_m)->shrd->trans) |
366 | #define hw_params(_m) ((_m)->shrd->hw_params) | ||
367 | 171 | ||
368 | static inline bool iwl_have_debug_level(u32 level) | 172 | static inline bool iwl_have_debug_level(u32 level) |
369 | { | 173 | { |
@@ -377,33 +181,4 @@ enum iwl_rxon_context_id { | |||
377 | NUM_IWL_RXON_CTX | 181 | NUM_IWL_RXON_CTX |
378 | }; | 182 | }; |
379 | 183 | ||
380 | int iwlagn_hw_valid_rtc_data_addr(u32 addr); | ||
381 | const char *get_cmd_string(u8 cmd); | ||
382 | |||
383 | #define IWL_CMD(x) case x: return #x | ||
384 | |||
385 | /***************************************************** | ||
386 | * DRIVER STATUS FUNCTIONS | ||
387 | ******************************************************/ | ||
388 | #define STATUS_HCMD_ACTIVE 0 /* host command in progress */ | ||
389 | /* 1 is unused (used to be STATUS_HCMD_SYNC_ACTIVE) */ | ||
390 | #define STATUS_INT_ENABLED 2 | ||
391 | #define STATUS_RF_KILL_HW 3 | ||
392 | #define STATUS_CT_KILL 4 | ||
393 | #define STATUS_INIT 5 | ||
394 | #define STATUS_ALIVE 6 | ||
395 | #define STATUS_READY 7 | ||
396 | #define STATUS_TEMPERATURE 8 | ||
397 | #define STATUS_GEO_CONFIGURED 9 | ||
398 | #define STATUS_EXIT_PENDING 10 | ||
399 | #define STATUS_STATISTICS 12 | ||
400 | #define STATUS_SCANNING 13 | ||
401 | #define STATUS_SCAN_ABORTING 14 | ||
402 | #define STATUS_SCAN_HW 15 | ||
403 | #define STATUS_POWER_PMI 16 | ||
404 | #define STATUS_FW_ERROR 17 | ||
405 | #define STATUS_DEVICE_ENABLED 18 | ||
406 | #define STATUS_CHANNEL_SWITCH_PENDING 19 | ||
407 | #define STATUS_SCAN_COMPLETE 20 | ||
408 | |||
409 | #endif /* #__iwl_shared_h__ */ | 184 | #endif /* #__iwl_shared_h__ */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.c b/drivers/net/wireless/iwlwifi/iwl-testmode.c index f31a0629c6c6..bb275098bb10 100644 --- a/drivers/net/wireless/iwlwifi/iwl-testmode.c +++ b/drivers/net/wireless/iwlwifi/iwl-testmode.c | |||
@@ -536,7 +536,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) | |||
536 | break; | 536 | break; |
537 | 537 | ||
538 | case IWL_TM_CMD_APP2DEV_GET_EEPROM: | 538 | case IWL_TM_CMD_APP2DEV_GET_EEPROM: |
539 | if (priv->shrd->eeprom) { | 539 | if (priv->eeprom) { |
540 | skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, | 540 | skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, |
541 | cfg(priv)->base_params->eeprom_size + 20); | 541 | cfg(priv)->base_params->eeprom_size + 20); |
542 | if (!skb) { | 542 | if (!skb) { |
@@ -547,7 +547,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) | |||
547 | IWL_TM_CMD_DEV2APP_EEPROM_RSP) || | 547 | IWL_TM_CMD_DEV2APP_EEPROM_RSP) || |
548 | nla_put(skb, IWL_TM_ATTR_EEPROM, | 548 | nla_put(skb, IWL_TM_ATTR_EEPROM, |
549 | cfg(priv)->base_params->eeprom_size, | 549 | cfg(priv)->base_params->eeprom_size, |
550 | priv->shrd->eeprom)) | 550 | priv->eeprom)) |
551 | goto nla_put_failure; | 551 | goto nla_put_failure; |
552 | status = cfg80211_testmode_reply(skb); | 552 | status = cfg80211_testmode_reply(skb); |
553 | if (status < 0) | 553 | if (status < 0) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h index 32adee3b54e3..70bdd0e2df38 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/skbuff.h> | 34 | #include <linux/skbuff.h> |
35 | #include <linux/wait.h> | 35 | #include <linux/wait.h> |
36 | #include <linux/pci.h> | 36 | #include <linux/pci.h> |
37 | #include <linux/timer.h> | ||
37 | 38 | ||
38 | #include "iwl-fh.h" | 39 | #include "iwl-fh.h" |
39 | #include "iwl-csr.h" | 40 | #include "iwl-csr.h" |
@@ -43,8 +44,6 @@ | |||
43 | #include "iwl-io.h" | 44 | #include "iwl-io.h" |
44 | #include "iwl-op-mode.h" | 45 | #include "iwl-op-mode.h" |
45 | 46 | ||
46 | struct iwl_tx_queue; | ||
47 | struct iwl_queue; | ||
48 | struct iwl_host_cmd; | 47 | struct iwl_host_cmd; |
49 | 48 | ||
50 | /*This file includes the declaration that are internal to the | 49 | /*This file includes the declaration that are internal to the |
@@ -140,10 +139,10 @@ struct iwl_cmd_meta { | |||
140 | /* only for SYNC commands, iff the reply skb is wanted */ | 139 | /* only for SYNC commands, iff the reply skb is wanted */ |
141 | struct iwl_host_cmd *source; | 140 | struct iwl_host_cmd *source; |
142 | 141 | ||
143 | u32 flags; | ||
144 | |||
145 | DEFINE_DMA_UNMAP_ADDR(mapping); | 142 | DEFINE_DMA_UNMAP_ADDR(mapping); |
146 | DEFINE_DMA_UNMAP_LEN(len); | 143 | DEFINE_DMA_UNMAP_LEN(len); |
144 | |||
145 | u32 flags; | ||
147 | }; | 146 | }; |
148 | 147 | ||
149 | /* | 148 | /* |
@@ -206,7 +205,8 @@ struct iwl_tx_queue { | |||
206 | struct iwl_cmd_meta *meta; | 205 | struct iwl_cmd_meta *meta; |
207 | struct sk_buff **skbs; | 206 | struct sk_buff **skbs; |
208 | spinlock_t lock; | 207 | spinlock_t lock; |
209 | unsigned long time_stamp; | 208 | struct timer_list stuck_timer; |
209 | struct iwl_trans_pcie *trans_pcie; | ||
210 | u8 need_update; | 210 | u8 need_update; |
211 | u8 active; | 211 | u8 active; |
212 | }; | 212 | }; |
@@ -227,6 +227,9 @@ struct iwl_tx_queue { | |||
227 | * @ucode_write_waitq: wait queue for uCode load | 227 | * @ucode_write_waitq: wait queue for uCode load |
228 | * @status - transport specific status flags | 228 | * @status - transport specific status flags |
229 | * @cmd_queue - command queue number | 229 | * @cmd_queue - command queue number |
230 | * @rx_buf_size_8k: 8 kB RX buffer size | ||
231 | * @rx_page_order: page order for receive buffer size | ||
232 | * @wd_timeout: queue watchdog timeout (jiffies) | ||
230 | */ | 233 | */ |
231 | struct iwl_trans_pcie { | 234 | struct iwl_trans_pcie { |
232 | struct iwl_rx_queue rxq; | 235 | struct iwl_rx_queue rxq; |
@@ -266,11 +269,34 @@ struct iwl_trans_pcie { | |||
266 | u8 no_reclaim_cmds[MAX_NO_RECLAIM_CMDS]; | 269 | u8 no_reclaim_cmds[MAX_NO_RECLAIM_CMDS]; |
267 | u8 setup_q_to_fifo[IWL_MAX_HW_QUEUES]; | 270 | u8 setup_q_to_fifo[IWL_MAX_HW_QUEUES]; |
268 | u8 n_q_to_fifo; | 271 | u8 n_q_to_fifo; |
272 | |||
273 | bool rx_buf_size_8k; | ||
274 | u32 rx_page_order; | ||
275 | |||
276 | const char **command_names; | ||
277 | |||
278 | /* queue watchdog */ | ||
279 | unsigned long wd_timeout; | ||
269 | }; | 280 | }; |
270 | 281 | ||
282 | /***************************************************** | ||
283 | * DRIVER STATUS FUNCTIONS | ||
284 | ******************************************************/ | ||
285 | #define STATUS_HCMD_ACTIVE 0 | ||
286 | #define STATUS_DEVICE_ENABLED 1 | ||
287 | #define STATUS_TPOWER_PMI 2 | ||
288 | #define STATUS_INT_ENABLED 3 | ||
289 | |||
271 | #define IWL_TRANS_GET_PCIE_TRANS(_iwl_trans) \ | 290 | #define IWL_TRANS_GET_PCIE_TRANS(_iwl_trans) \ |
272 | ((struct iwl_trans_pcie *) ((_iwl_trans)->trans_specific)) | 291 | ((struct iwl_trans_pcie *) ((_iwl_trans)->trans_specific)) |
273 | 292 | ||
293 | static inline struct iwl_trans * | ||
294 | iwl_trans_pcie_get_trans(struct iwl_trans_pcie *trans_pcie) | ||
295 | { | ||
296 | return container_of((void *)trans_pcie, struct iwl_trans, | ||
297 | trans_specific); | ||
298 | } | ||
299 | |||
274 | /***************************************************** | 300 | /***************************************************** |
275 | * RX | 301 | * RX |
276 | ******************************************************/ | 302 | ******************************************************/ |
@@ -392,4 +418,12 @@ static inline u8 get_cmd_index(struct iwl_queue *q, u32 index) | |||
392 | return index & (q->n_window - 1); | 418 | return index & (q->n_window - 1); |
393 | } | 419 | } |
394 | 420 | ||
421 | static inline const char * | ||
422 | trans_pcie_get_cmd_string(struct iwl_trans_pcie *trans_pcie, u8 cmd) | ||
423 | { | ||
424 | if (!trans_pcie->command_names || !trans_pcie->command_names[cmd]) | ||
425 | return "UNKNOWN"; | ||
426 | return trans_pcie->command_names[cmd]; | ||
427 | } | ||
428 | |||
395 | #endif /* __iwl_trans_int_pcie_h__ */ | 429 | #endif /* __iwl_trans_int_pcie_h__ */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c index ab0f3fc22b87..de78fb8dca9f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c | |||
@@ -150,7 +150,7 @@ void iwl_rx_queue_update_write_ptr(struct iwl_trans *trans, | |||
150 | IWL_TRANS_GET_PCIE_TRANS(trans); | 150 | IWL_TRANS_GET_PCIE_TRANS(trans); |
151 | 151 | ||
152 | /* If power-saving is in use, make sure device is awake */ | 152 | /* If power-saving is in use, make sure device is awake */ |
153 | if (test_bit(STATUS_POWER_PMI, &trans_pcie->status)) { | 153 | if (test_bit(STATUS_TPOWER_PMI, &trans_pcie->status)) { |
154 | reg = iwl_read32(trans, CSR_UCODE_DRV_GP1); | 154 | reg = iwl_read32(trans, CSR_UCODE_DRV_GP1); |
155 | 155 | ||
156 | if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) { | 156 | if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) { |
@@ -274,17 +274,17 @@ static void iwlagn_rx_allocate(struct iwl_trans *trans, gfp_t priority) | |||
274 | if (rxq->free_count > RX_LOW_WATERMARK) | 274 | if (rxq->free_count > RX_LOW_WATERMARK) |
275 | gfp_mask |= __GFP_NOWARN; | 275 | gfp_mask |= __GFP_NOWARN; |
276 | 276 | ||
277 | if (hw_params(trans).rx_page_order > 0) | 277 | if (trans_pcie->rx_page_order > 0) |
278 | gfp_mask |= __GFP_COMP; | 278 | gfp_mask |= __GFP_COMP; |
279 | 279 | ||
280 | /* Alloc a new receive buffer */ | 280 | /* Alloc a new receive buffer */ |
281 | page = alloc_pages(gfp_mask, | 281 | page = alloc_pages(gfp_mask, |
282 | hw_params(trans).rx_page_order); | 282 | trans_pcie->rx_page_order); |
283 | if (!page) { | 283 | if (!page) { |
284 | if (net_ratelimit()) | 284 | if (net_ratelimit()) |
285 | IWL_DEBUG_INFO(trans, "alloc_pages failed, " | 285 | IWL_DEBUG_INFO(trans, "alloc_pages failed, " |
286 | "order: %d\n", | 286 | "order: %d\n", |
287 | hw_params(trans).rx_page_order); | 287 | trans_pcie->rx_page_order); |
288 | 288 | ||
289 | if ((rxq->free_count <= RX_LOW_WATERMARK) && | 289 | if ((rxq->free_count <= RX_LOW_WATERMARK) && |
290 | net_ratelimit()) | 290 | net_ratelimit()) |
@@ -303,7 +303,7 @@ static void iwlagn_rx_allocate(struct iwl_trans *trans, gfp_t priority) | |||
303 | 303 | ||
304 | if (list_empty(&rxq->rx_used)) { | 304 | if (list_empty(&rxq->rx_used)) { |
305 | spin_unlock_irqrestore(&rxq->lock, flags); | 305 | spin_unlock_irqrestore(&rxq->lock, flags); |
306 | __free_pages(page, hw_params(trans).rx_page_order); | 306 | __free_pages(page, trans_pcie->rx_page_order); |
307 | return; | 307 | return; |
308 | } | 308 | } |
309 | element = rxq->rx_used.next; | 309 | element = rxq->rx_used.next; |
@@ -316,7 +316,7 @@ static void iwlagn_rx_allocate(struct iwl_trans *trans, gfp_t priority) | |||
316 | rxb->page = page; | 316 | rxb->page = page; |
317 | /* Get physical address of the RB */ | 317 | /* Get physical address of the RB */ |
318 | rxb->page_dma = dma_map_page(trans->dev, page, 0, | 318 | rxb->page_dma = dma_map_page(trans->dev, page, 0, |
319 | PAGE_SIZE << hw_params(trans).rx_page_order, | 319 | PAGE_SIZE << trans_pcie->rx_page_order, |
320 | DMA_FROM_DEVICE); | 320 | DMA_FROM_DEVICE); |
321 | /* dma address must be no more than 36 bits */ | 321 | /* dma address must be no more than 36 bits */ |
322 | BUG_ON(rxb->page_dma & ~DMA_BIT_MASK(36)); | 322 | BUG_ON(rxb->page_dma & ~DMA_BIT_MASK(36)); |
@@ -367,7 +367,7 @@ static void iwl_rx_handle_rxbuf(struct iwl_trans *trans, | |||
367 | struct iwl_tx_queue *txq = &trans_pcie->txq[trans_pcie->cmd_queue]; | 367 | struct iwl_tx_queue *txq = &trans_pcie->txq[trans_pcie->cmd_queue]; |
368 | unsigned long flags; | 368 | unsigned long flags; |
369 | bool page_stolen = false; | 369 | bool page_stolen = false; |
370 | int max_len = PAGE_SIZE << hw_params(trans).rx_page_order; | 370 | int max_len = PAGE_SIZE << trans_pcie->rx_page_order; |
371 | u32 offset = 0; | 371 | u32 offset = 0; |
372 | 372 | ||
373 | if (WARN_ON(!rxb)) | 373 | if (WARN_ON(!rxb)) |
@@ -393,8 +393,9 @@ static void iwl_rx_handle_rxbuf(struct iwl_trans *trans, | |||
393 | break; | 393 | break; |
394 | 394 | ||
395 | IWL_DEBUG_RX(trans, "cmd at offset %d: %s (0x%.2x)\n", | 395 | IWL_DEBUG_RX(trans, "cmd at offset %d: %s (0x%.2x)\n", |
396 | rxcb._offset, get_cmd_string(pkt->hdr.cmd), | 396 | rxcb._offset, |
397 | pkt->hdr.cmd); | 397 | trans_pcie_get_cmd_string(trans_pcie, pkt->hdr.cmd), |
398 | pkt->hdr.cmd); | ||
398 | 399 | ||
399 | len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; | 400 | len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; |
400 | len += sizeof(u32); /* account for status word */ | 401 | len += sizeof(u32); /* account for status word */ |
@@ -452,7 +453,7 @@ static void iwl_rx_handle_rxbuf(struct iwl_trans *trans, | |||
452 | 453 | ||
453 | /* page was stolen from us -- free our reference */ | 454 | /* page was stolen from us -- free our reference */ |
454 | if (page_stolen) { | 455 | if (page_stolen) { |
455 | __free_pages(rxb->page, hw_params(trans).rx_page_order); | 456 | __free_pages(rxb->page, trans_pcie->rx_page_order); |
456 | rxb->page = NULL; | 457 | rxb->page = NULL; |
457 | } | 458 | } |
458 | 459 | ||
@@ -463,7 +464,7 @@ static void iwl_rx_handle_rxbuf(struct iwl_trans *trans, | |||
463 | if (rxb->page != NULL) { | 464 | if (rxb->page != NULL) { |
464 | rxb->page_dma = | 465 | rxb->page_dma = |
465 | dma_map_page(trans->dev, rxb->page, 0, | 466 | dma_map_page(trans->dev, rxb->page, 0, |
466 | PAGE_SIZE << hw_params(trans).rx_page_order, | 467 | PAGE_SIZE << trans_pcie->rx_page_order, |
467 | DMA_FROM_DEVICE); | 468 | DMA_FROM_DEVICE); |
468 | list_add_tail(&rxb->list, &rxq->rx_free); | 469 | list_add_tail(&rxb->list, &rxq->rx_free); |
469 | rxq->free_count++; | 470 | rxq->free_count++; |
@@ -547,14 +548,12 @@ static void iwl_irq_handle_error(struct iwl_trans *trans) | |||
547 | APMS_CLK_VAL_MRB_FUNC_MODE) || | 548 | APMS_CLK_VAL_MRB_FUNC_MODE) || |
548 | (iwl_read_prph(trans, APMG_PS_CTRL_REG) & | 549 | (iwl_read_prph(trans, APMG_PS_CTRL_REG) & |
549 | APMG_PS_CTRL_VAL_RESET_REQ))) { | 550 | APMG_PS_CTRL_VAL_RESET_REQ))) { |
550 | /* | 551 | struct iwl_trans_pcie *trans_pcie; |
551 | * Keep the restart process from trying to send host | 552 | |
552 | * commands by clearing the ready bit. | 553 | trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
553 | */ | 554 | clear_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status); |
554 | clear_bit(STATUS_READY, &trans->shrd->status); | 555 | iwl_op_mode_wimax_active(trans->op_mode); |
555 | clear_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status); | ||
556 | wake_up(&trans->wait_command_queue); | 556 | wake_up(&trans->wait_command_queue); |
557 | IWL_ERR(trans, "RF is used by WiMAX\n"); | ||
558 | return; | 557 | return; |
559 | } | 558 | } |
560 | 559 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c index 4684e2310cd8..918874067bd3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c | |||
@@ -107,7 +107,7 @@ void iwl_txq_update_write_ptr(struct iwl_trans *trans, struct iwl_tx_queue *txq) | |||
107 | struct iwl_trans_pcie *trans_pcie = | 107 | struct iwl_trans_pcie *trans_pcie = |
108 | IWL_TRANS_GET_PCIE_TRANS(trans); | 108 | IWL_TRANS_GET_PCIE_TRANS(trans); |
109 | /* if we're trying to save power */ | 109 | /* if we're trying to save power */ |
110 | if (test_bit(STATUS_POWER_PMI, &trans_pcie->status)) { | 110 | if (test_bit(STATUS_TPOWER_PMI, &trans_pcie->status)) { |
111 | /* wake up nic if it's powered down ... | 111 | /* wake up nic if it's powered down ... |
112 | * uCode will wake up, and interrupt us again, so next | 112 | * uCode will wake up, and interrupt us again, so next |
113 | * time we'll skip this part. */ | 113 | * time we'll skip this part. */ |
@@ -605,12 +605,11 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) | |||
605 | cmd_dest += cmd->len[i]; | 605 | cmd_dest += cmd->len[i]; |
606 | } | 606 | } |
607 | 607 | ||
608 | IWL_DEBUG_HC(trans, "Sending command %s (#%x), seq: 0x%04X, " | 608 | IWL_DEBUG_HC(trans, |
609 | "%d bytes at %d[%d]:%d\n", | 609 | "Sending command %s (#%x), seq: 0x%04X, %d bytes at %d[%d]:%d\n", |
610 | get_cmd_string(out_cmd->hdr.cmd), | 610 | trans_pcie_get_cmd_string(trans_pcie, out_cmd->hdr.cmd), |
611 | out_cmd->hdr.cmd, | 611 | out_cmd->hdr.cmd, le16_to_cpu(out_cmd->hdr.sequence), cmd_size, |
612 | le16_to_cpu(out_cmd->hdr.sequence), cmd_size, | 612 | q->write_ptr, idx, trans_pcie->cmd_queue); |
613 | q->write_ptr, idx, trans_pcie->cmd_queue); | ||
614 | 613 | ||
615 | phys_addr = dma_map_single(trans->dev, &out_cmd->hdr, copy_size, | 614 | phys_addr = dma_map_single(trans->dev, &out_cmd->hdr, copy_size, |
616 | DMA_BIDIRECTIONAL); | 615 | DMA_BIDIRECTIONAL); |
@@ -668,6 +667,10 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) | |||
668 | trace_bufs[2], trace_lens[2]); | 667 | trace_bufs[2], trace_lens[2]); |
669 | #endif | 668 | #endif |
670 | 669 | ||
670 | /* start timer if queue currently empty */ | ||
671 | if (q->read_ptr == q->write_ptr && trans_pcie->wd_timeout) | ||
672 | mod_timer(&txq->stuck_timer, jiffies + trans_pcie->wd_timeout); | ||
673 | |||
671 | /* Increment and update queue's write index */ | 674 | /* Increment and update queue's write index */ |
672 | q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); | 675 | q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); |
673 | iwl_txq_update_write_ptr(trans, txq); | 676 | iwl_txq_update_write_ptr(trans, txq); |
@@ -677,6 +680,22 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) | |||
677 | return idx; | 680 | return idx; |
678 | } | 681 | } |
679 | 682 | ||
683 | static inline void iwl_queue_progress(struct iwl_trans_pcie *trans_pcie, | ||
684 | struct iwl_tx_queue *txq) | ||
685 | { | ||
686 | if (!trans_pcie->wd_timeout) | ||
687 | return; | ||
688 | |||
689 | /* | ||
690 | * if empty delete timer, otherwise move timer forward | ||
691 | * since we're making progress on this queue | ||
692 | */ | ||
693 | if (txq->q.read_ptr == txq->q.write_ptr) | ||
694 | del_timer(&txq->stuck_timer); | ||
695 | else | ||
696 | mod_timer(&txq->stuck_timer, jiffies + trans_pcie->wd_timeout); | ||
697 | } | ||
698 | |||
680 | /** | 699 | /** |
681 | * iwl_hcmd_queue_reclaim - Reclaim TX command queue entries already Tx'd | 700 | * iwl_hcmd_queue_reclaim - Reclaim TX command queue entries already Tx'd |
682 | * | 701 | * |
@@ -711,6 +730,8 @@ static void iwl_hcmd_queue_reclaim(struct iwl_trans *trans, int txq_id, | |||
711 | } | 730 | } |
712 | 731 | ||
713 | } | 732 | } |
733 | |||
734 | iwl_queue_progress(trans_pcie, txq); | ||
714 | } | 735 | } |
715 | 736 | ||
716 | /** | 737 | /** |
@@ -754,8 +775,6 @@ void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_cmd_buffer *rxb, | |||
754 | cmd = txq->cmd[cmd_index]; | 775 | cmd = txq->cmd[cmd_index]; |
755 | meta = &txq->meta[cmd_index]; | 776 | meta = &txq->meta[cmd_index]; |
756 | 777 | ||
757 | txq->time_stamp = jiffies; | ||
758 | |||
759 | iwlagn_unmap_tfd(trans, meta, &txq->tfds[index], | 778 | iwlagn_unmap_tfd(trans, meta, &txq->tfds[index], |
760 | DMA_BIDIRECTIONAL); | 779 | DMA_BIDIRECTIONAL); |
761 | 780 | ||
@@ -765,21 +784,23 @@ void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_cmd_buffer *rxb, | |||
765 | 784 | ||
766 | meta->source->resp_pkt = pkt; | 785 | meta->source->resp_pkt = pkt; |
767 | meta->source->_rx_page_addr = (unsigned long)page_address(p); | 786 | meta->source->_rx_page_addr = (unsigned long)page_address(p); |
768 | meta->source->_rx_page_order = hw_params(trans).rx_page_order; | 787 | meta->source->_rx_page_order = trans_pcie->rx_page_order; |
769 | meta->source->handler_status = handler_status; | 788 | meta->source->handler_status = handler_status; |
770 | } | 789 | } |
771 | 790 | ||
772 | iwl_hcmd_queue_reclaim(trans, txq_id, index); | 791 | iwl_hcmd_queue_reclaim(trans, txq_id, index); |
773 | 792 | ||
774 | if (!(meta->flags & CMD_ASYNC)) { | 793 | if (!(meta->flags & CMD_ASYNC)) { |
775 | if (!test_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status)) { | 794 | if (!test_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status)) { |
776 | IWL_WARN(trans, | 795 | IWL_WARN(trans, |
777 | "HCMD_ACTIVE already clear for command %s\n", | 796 | "HCMD_ACTIVE already clear for command %s\n", |
778 | get_cmd_string(cmd->hdr.cmd)); | 797 | trans_pcie_get_cmd_string(trans_pcie, |
798 | cmd->hdr.cmd)); | ||
779 | } | 799 | } |
780 | clear_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status); | 800 | clear_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status); |
781 | IWL_DEBUG_INFO(trans, "Clearing HCMD_ACTIVE for command %s\n", | 801 | IWL_DEBUG_INFO(trans, "Clearing HCMD_ACTIVE for command %s\n", |
782 | get_cmd_string(cmd->hdr.cmd)); | 802 | trans_pcie_get_cmd_string(trans_pcie, |
803 | cmd->hdr.cmd)); | ||
783 | wake_up(&trans->wait_command_queue); | 804 | wake_up(&trans->wait_command_queue); |
784 | } | 805 | } |
785 | 806 | ||
@@ -792,6 +813,7 @@ void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_cmd_buffer *rxb, | |||
792 | 813 | ||
793 | static int iwl_send_cmd_async(struct iwl_trans *trans, struct iwl_host_cmd *cmd) | 814 | static int iwl_send_cmd_async(struct iwl_trans *trans, struct iwl_host_cmd *cmd) |
794 | { | 815 | { |
816 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
795 | int ret; | 817 | int ret; |
796 | 818 | ||
797 | /* An asynchronous command can not expect an SKB to be set. */ | 819 | /* An asynchronous command can not expect an SKB to be set. */ |
@@ -803,7 +825,7 @@ static int iwl_send_cmd_async(struct iwl_trans *trans, struct iwl_host_cmd *cmd) | |||
803 | if (ret < 0) { | 825 | if (ret < 0) { |
804 | IWL_ERR(trans, | 826 | IWL_ERR(trans, |
805 | "Error sending %s: enqueue_hcmd failed: %d\n", | 827 | "Error sending %s: enqueue_hcmd failed: %d\n", |
806 | get_cmd_string(cmd->id), ret); | 828 | trans_pcie_get_cmd_string(trans_pcie, cmd->id), ret); |
807 | return ret; | 829 | return ret; |
808 | } | 830 | } |
809 | return 0; | 831 | return 0; |
@@ -816,49 +838,51 @@ static int iwl_send_cmd_sync(struct iwl_trans *trans, struct iwl_host_cmd *cmd) | |||
816 | int ret; | 838 | int ret; |
817 | 839 | ||
818 | IWL_DEBUG_INFO(trans, "Attempting to send sync command %s\n", | 840 | IWL_DEBUG_INFO(trans, "Attempting to send sync command %s\n", |
819 | get_cmd_string(cmd->id)); | 841 | trans_pcie_get_cmd_string(trans_pcie, cmd->id)); |
820 | 842 | ||
821 | if (WARN_ON(test_and_set_bit(STATUS_HCMD_ACTIVE, | 843 | if (WARN_ON(test_and_set_bit(STATUS_HCMD_ACTIVE, |
822 | &trans->shrd->status))) { | 844 | &trans_pcie->status))) { |
823 | IWL_ERR(trans, "Command %s: a command is already active!\n", | 845 | IWL_ERR(trans, "Command %s: a command is already active!\n", |
824 | get_cmd_string(cmd->id)); | 846 | trans_pcie_get_cmd_string(trans_pcie, cmd->id)); |
825 | return -EIO; | 847 | return -EIO; |
826 | } | 848 | } |
827 | 849 | ||
828 | IWL_DEBUG_INFO(trans, "Setting HCMD_ACTIVE for command %s\n", | 850 | IWL_DEBUG_INFO(trans, "Setting HCMD_ACTIVE for command %s\n", |
829 | get_cmd_string(cmd->id)); | 851 | trans_pcie_get_cmd_string(trans_pcie, cmd->id)); |
830 | 852 | ||
831 | cmd_idx = iwl_enqueue_hcmd(trans, cmd); | 853 | cmd_idx = iwl_enqueue_hcmd(trans, cmd); |
832 | if (cmd_idx < 0) { | 854 | if (cmd_idx < 0) { |
833 | ret = cmd_idx; | 855 | ret = cmd_idx; |
834 | clear_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status); | 856 | clear_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status); |
835 | IWL_ERR(trans, | 857 | IWL_ERR(trans, |
836 | "Error sending %s: enqueue_hcmd failed: %d\n", | 858 | "Error sending %s: enqueue_hcmd failed: %d\n", |
837 | get_cmd_string(cmd->id), ret); | 859 | trans_pcie_get_cmd_string(trans_pcie, cmd->id), ret); |
838 | return ret; | 860 | return ret; |
839 | } | 861 | } |
840 | 862 | ||
841 | ret = wait_event_timeout(trans->wait_command_queue, | 863 | ret = wait_event_timeout(trans->wait_command_queue, |
842 | !test_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status), | 864 | !test_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status), |
843 | HOST_COMPLETE_TIMEOUT); | 865 | HOST_COMPLETE_TIMEOUT); |
844 | if (!ret) { | 866 | if (!ret) { |
845 | if (test_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status)) { | 867 | if (test_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status)) { |
846 | struct iwl_tx_queue *txq = | 868 | struct iwl_tx_queue *txq = |
847 | &trans_pcie->txq[trans_pcie->cmd_queue]; | 869 | &trans_pcie->txq[trans_pcie->cmd_queue]; |
848 | struct iwl_queue *q = &txq->q; | 870 | struct iwl_queue *q = &txq->q; |
849 | 871 | ||
850 | IWL_ERR(trans, | 872 | IWL_ERR(trans, |
851 | "Error sending %s: time out after %dms.\n", | 873 | "Error sending %s: time out after %dms.\n", |
852 | get_cmd_string(cmd->id), | 874 | trans_pcie_get_cmd_string(trans_pcie, cmd->id), |
853 | jiffies_to_msecs(HOST_COMPLETE_TIMEOUT)); | 875 | jiffies_to_msecs(HOST_COMPLETE_TIMEOUT)); |
854 | 876 | ||
855 | IWL_ERR(trans, | 877 | IWL_ERR(trans, |
856 | "Current CMD queue read_ptr %d write_ptr %d\n", | 878 | "Current CMD queue read_ptr %d write_ptr %d\n", |
857 | q->read_ptr, q->write_ptr); | 879 | q->read_ptr, q->write_ptr); |
858 | 880 | ||
859 | clear_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status); | 881 | clear_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status); |
860 | IWL_DEBUG_INFO(trans, "Clearing HCMD_ACTIVE for command" | 882 | IWL_DEBUG_INFO(trans, |
861 | "%s\n", get_cmd_string(cmd->id)); | 883 | "Clearing HCMD_ACTIVE for command %s\n", |
884 | trans_pcie_get_cmd_string(trans_pcie, | ||
885 | cmd->id)); | ||
862 | ret = -ETIMEDOUT; | 886 | ret = -ETIMEDOUT; |
863 | goto cancel; | 887 | goto cancel; |
864 | } | 888 | } |
@@ -866,7 +890,7 @@ static int iwl_send_cmd_sync(struct iwl_trans *trans, struct iwl_host_cmd *cmd) | |||
866 | 890 | ||
867 | if ((cmd->flags & CMD_WANT_SKB) && !cmd->resp_pkt) { | 891 | if ((cmd->flags & CMD_WANT_SKB) && !cmd->resp_pkt) { |
868 | IWL_ERR(trans, "Error: Response NULL in '%s'\n", | 892 | IWL_ERR(trans, "Error: Response NULL in '%s'\n", |
869 | get_cmd_string(cmd->id)); | 893 | trans_pcie_get_cmd_string(trans_pcie, cmd->id)); |
870 | ret = -EIO; | 894 | ret = -EIO; |
871 | goto cancel; | 895 | goto cancel; |
872 | } | 896 | } |
@@ -949,5 +973,8 @@ int iwl_tx_queue_reclaim(struct iwl_trans *trans, int txq_id, int index, | |||
949 | iwlagn_txq_free_tfd(trans, txq, txq->q.read_ptr, DMA_TO_DEVICE); | 973 | iwlagn_txq_free_tfd(trans, txq, txq->q.read_ptr, DMA_TO_DEVICE); |
950 | freed++; | 974 | freed++; |
951 | } | 975 | } |
976 | |||
977 | iwl_queue_progress(trans_pcie, txq); | ||
978 | |||
952 | return freed; | 979 | return freed; |
953 | } | 980 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index 9f62283504e3..14a32c420fd4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | |||
@@ -132,10 +132,10 @@ static void iwl_trans_rxq_free_rx_bufs(struct iwl_trans *trans) | |||
132 | * to an SKB, so we need to unmap and free potential storage */ | 132 | * to an SKB, so we need to unmap and free potential storage */ |
133 | if (rxq->pool[i].page != NULL) { | 133 | if (rxq->pool[i].page != NULL) { |
134 | dma_unmap_page(trans->dev, rxq->pool[i].page_dma, | 134 | dma_unmap_page(trans->dev, rxq->pool[i].page_dma, |
135 | PAGE_SIZE << hw_params(trans).rx_page_order, | 135 | PAGE_SIZE << trans_pcie->rx_page_order, |
136 | DMA_FROM_DEVICE); | 136 | DMA_FROM_DEVICE); |
137 | __free_pages(rxq->pool[i].page, | 137 | __free_pages(rxq->pool[i].page, |
138 | hw_params(trans).rx_page_order); | 138 | trans_pcie->rx_page_order); |
139 | rxq->pool[i].page = NULL; | 139 | rxq->pool[i].page = NULL; |
140 | } | 140 | } |
141 | list_add_tail(&rxq->pool[i].list, &rxq->rx_used); | 141 | list_add_tail(&rxq->pool[i].list, &rxq->rx_used); |
@@ -145,11 +145,12 @@ static void iwl_trans_rxq_free_rx_bufs(struct iwl_trans *trans) | |||
145 | static void iwl_trans_rx_hw_init(struct iwl_trans *trans, | 145 | static void iwl_trans_rx_hw_init(struct iwl_trans *trans, |
146 | struct iwl_rx_queue *rxq) | 146 | struct iwl_rx_queue *rxq) |
147 | { | 147 | { |
148 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
148 | u32 rb_size; | 149 | u32 rb_size; |
149 | const u32 rfdnlog = RX_QUEUE_SIZE_LOG; /* 256 RBDs */ | 150 | const u32 rfdnlog = RX_QUEUE_SIZE_LOG; /* 256 RBDs */ |
150 | u32 rb_timeout = RX_RB_TIMEOUT; /* FIXME: RX_RB_TIMEOUT for all devices? */ | 151 | u32 rb_timeout = RX_RB_TIMEOUT; /* FIXME: RX_RB_TIMEOUT for all devices? */ |
151 | 152 | ||
152 | if (iwlagn_mod_params.amsdu_size_8K) | 153 | if (trans_pcie->rx_buf_size_8k) |
153 | rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_8K; | 154 | rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_8K; |
154 | else | 155 | else |
155 | rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K; | 156 | rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K; |
@@ -298,6 +299,33 @@ static inline void iwlagn_free_dma_ptr(struct iwl_trans *trans, | |||
298 | memset(ptr, 0, sizeof(*ptr)); | 299 | memset(ptr, 0, sizeof(*ptr)); |
299 | } | 300 | } |
300 | 301 | ||
302 | static void iwl_trans_pcie_queue_stuck_timer(unsigned long data) | ||
303 | { | ||
304 | struct iwl_tx_queue *txq = (void *)data; | ||
305 | struct iwl_trans_pcie *trans_pcie = txq->trans_pcie; | ||
306 | struct iwl_trans *trans = iwl_trans_pcie_get_trans(trans_pcie); | ||
307 | |||
308 | spin_lock(&txq->lock); | ||
309 | /* check if triggered erroneously */ | ||
310 | if (txq->q.read_ptr == txq->q.write_ptr) { | ||
311 | spin_unlock(&txq->lock); | ||
312 | return; | ||
313 | } | ||
314 | spin_unlock(&txq->lock); | ||
315 | |||
316 | |||
317 | IWL_ERR(trans, "Queue %d stuck for %u ms.\n", txq->q.id, | ||
318 | jiffies_to_msecs(trans_pcie->wd_timeout)); | ||
319 | IWL_ERR(trans, "Current SW read_ptr %d write_ptr %d\n", | ||
320 | txq->q.read_ptr, txq->q.write_ptr); | ||
321 | IWL_ERR(trans, "Current HW read_ptr %d write_ptr %d\n", | ||
322 | iwl_read_prph(trans, SCD_QUEUE_RDPTR(txq->q.id)) | ||
323 | & (TFD_QUEUE_SIZE_MAX - 1), | ||
324 | iwl_read_prph(trans, SCD_QUEUE_WRPTR(txq->q.id))); | ||
325 | |||
326 | iwl_op_mode_nic_error(trans->op_mode); | ||
327 | } | ||
328 | |||
301 | static int iwl_trans_txq_alloc(struct iwl_trans *trans, | 329 | static int iwl_trans_txq_alloc(struct iwl_trans *trans, |
302 | struct iwl_tx_queue *txq, int slots_num, | 330 | struct iwl_tx_queue *txq, int slots_num, |
303 | u32 txq_id) | 331 | u32 txq_id) |
@@ -309,6 +337,10 @@ static int iwl_trans_txq_alloc(struct iwl_trans *trans, | |||
309 | if (WARN_ON(txq->meta || txq->cmd || txq->skbs || txq->tfds)) | 337 | if (WARN_ON(txq->meta || txq->cmd || txq->skbs || txq->tfds)) |
310 | return -EINVAL; | 338 | return -EINVAL; |
311 | 339 | ||
340 | setup_timer(&txq->stuck_timer, iwl_trans_pcie_queue_stuck_timer, | ||
341 | (unsigned long)txq); | ||
342 | txq->trans_pcie = trans_pcie; | ||
343 | |||
312 | txq->q.n_window = slots_num; | 344 | txq->q.n_window = slots_num; |
313 | 345 | ||
314 | txq->meta = kcalloc(slots_num, sizeof(txq->meta[0]), GFP_KERNEL); | 346 | txq->meta = kcalloc(slots_num, sizeof(txq->meta[0]), GFP_KERNEL); |
@@ -471,6 +503,8 @@ static void iwl_tx_queue_free(struct iwl_trans *trans, int txq_id) | |||
471 | txq->cmd = NULL; | 503 | txq->cmd = NULL; |
472 | txq->meta = NULL; | 504 | txq->meta = NULL; |
473 | 505 | ||
506 | del_timer_sync(&txq->stuck_timer); | ||
507 | |||
474 | /* 0-fill queue descriptor structure */ | 508 | /* 0-fill queue descriptor structure */ |
475 | memset(txq, 0, sizeof(*txq)); | 509 | memset(txq, 0, sizeof(*txq)); |
476 | } | 510 | } |
@@ -1214,6 +1248,12 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) | |||
1214 | 1248 | ||
1215 | /* stop and reset the on-board processor */ | 1249 | /* stop and reset the on-board processor */ |
1216 | iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); | 1250 | iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); |
1251 | |||
1252 | /* clear all status bits */ | ||
1253 | clear_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status); | ||
1254 | clear_bit(STATUS_INT_ENABLED, &trans_pcie->status); | ||
1255 | clear_bit(STATUS_DEVICE_ENABLED, &trans_pcie->status); | ||
1256 | clear_bit(STATUS_TPOWER_PMI, &trans_pcie->status); | ||
1217 | } | 1257 | } |
1218 | 1258 | ||
1219 | static void iwl_trans_pcie_wowlan_suspend(struct iwl_trans *trans) | 1259 | static void iwl_trans_pcie_wowlan_suspend(struct iwl_trans *trans) |
@@ -1346,6 +1386,10 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, | |||
1346 | &dev_cmd->hdr, firstlen, | 1386 | &dev_cmd->hdr, firstlen, |
1347 | skb->data + hdr_len, secondlen); | 1387 | skb->data + hdr_len, secondlen); |
1348 | 1388 | ||
1389 | /* start timer if queue currently empty */ | ||
1390 | if (q->read_ptr == q->write_ptr && trans_pcie->wd_timeout) | ||
1391 | mod_timer(&txq->stuck_timer, jiffies + trans_pcie->wd_timeout); | ||
1392 | |||
1349 | /* Tell device the write index *just past* this latest filled TFD */ | 1393 | /* Tell device the write index *just past* this latest filled TFD */ |
1350 | q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); | 1394 | q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); |
1351 | iwl_txq_update_write_ptr(trans, txq); | 1395 | iwl_txq_update_write_ptr(trans, txq); |
@@ -1441,8 +1485,6 @@ static void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn, | |||
1441 | 1485 | ||
1442 | spin_lock(&txq->lock); | 1486 | spin_lock(&txq->lock); |
1443 | 1487 | ||
1444 | txq->time_stamp = jiffies; | ||
1445 | |||
1446 | if (txq->q.read_ptr != tfd_num) { | 1488 | if (txq->q.read_ptr != tfd_num) { |
1447 | IWL_DEBUG_TX_REPLY(trans, "[Q %d] %d -> %d (%d)\n", | 1489 | IWL_DEBUG_TX_REPLY(trans, "[Q %d] %d -> %d (%d)\n", |
1448 | txq_id, txq->q.read_ptr, tfd_num, ssn); | 1490 | txq_id, txq->q.read_ptr, tfd_num, ssn); |
@@ -1493,6 +1535,17 @@ static void iwl_trans_pcie_configure(struct iwl_trans *trans, | |||
1493 | 1535 | ||
1494 | memcpy(trans_pcie->setup_q_to_fifo, trans_cfg->queue_to_fifo, | 1536 | memcpy(trans_pcie->setup_q_to_fifo, trans_cfg->queue_to_fifo, |
1495 | trans_pcie->n_q_to_fifo * sizeof(u8)); | 1537 | trans_pcie->n_q_to_fifo * sizeof(u8)); |
1538 | |||
1539 | trans_pcie->rx_buf_size_8k = trans_cfg->rx_buf_size_8k; | ||
1540 | if (trans_pcie->rx_buf_size_8k) | ||
1541 | trans_pcie->rx_page_order = get_order(8 * 1024); | ||
1542 | else | ||
1543 | trans_pcie->rx_page_order = get_order(4 * 1024); | ||
1544 | |||
1545 | trans_pcie->wd_timeout = | ||
1546 | msecs_to_jiffies(trans_cfg->queue_watchdog_timeout); | ||
1547 | |||
1548 | trans_pcie->command_names = trans_cfg->command_names; | ||
1496 | } | 1549 | } |
1497 | 1550 | ||
1498 | static void iwl_trans_pcie_free(struct iwl_trans *trans) | 1551 | static void iwl_trans_pcie_free(struct iwl_trans *trans) |
@@ -1523,9 +1576,9 @@ static void iwl_trans_pcie_set_pmi(struct iwl_trans *trans, bool state) | |||
1523 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 1576 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
1524 | 1577 | ||
1525 | if (state) | 1578 | if (state) |
1526 | set_bit(STATUS_POWER_PMI, &trans_pcie->status); | 1579 | set_bit(STATUS_TPOWER_PMI, &trans_pcie->status); |
1527 | else | 1580 | else |
1528 | clear_bit(STATUS_POWER_PMI, &trans_pcie->status); | 1581 | clear_bit(STATUS_TPOWER_PMI, &trans_pcie->status); |
1529 | } | 1582 | } |
1530 | 1583 | ||
1531 | #ifdef CONFIG_PM_SLEEP | 1584 | #ifdef CONFIG_PM_SLEEP |
@@ -1582,42 +1635,9 @@ static int iwl_trans_pcie_wait_tx_queue_empty(struct iwl_trans *trans) | |||
1582 | return ret; | 1635 | return ret; |
1583 | } | 1636 | } |
1584 | 1637 | ||
1585 | /* | ||
1586 | * On every watchdog tick we check (latest) time stamp. If it does not | ||
1587 | * change during timeout period and queue is not empty we reset firmware. | ||
1588 | */ | ||
1589 | static int iwl_trans_pcie_check_stuck_queue(struct iwl_trans *trans, int cnt) | ||
1590 | { | ||
1591 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
1592 | struct iwl_tx_queue *txq = &trans_pcie->txq[cnt]; | ||
1593 | struct iwl_queue *q = &txq->q; | ||
1594 | unsigned long timeout; | ||
1595 | |||
1596 | if (q->read_ptr == q->write_ptr) { | ||
1597 | txq->time_stamp = jiffies; | ||
1598 | return 0; | ||
1599 | } | ||
1600 | |||
1601 | timeout = txq->time_stamp + | ||
1602 | msecs_to_jiffies(hw_params(trans).wd_timeout); | ||
1603 | |||
1604 | if (time_after(jiffies, timeout)) { | ||
1605 | IWL_ERR(trans, "Queue %d stuck for %u ms.\n", q->id, | ||
1606 | hw_params(trans).wd_timeout); | ||
1607 | IWL_ERR(trans, "Current SW read_ptr %d write_ptr %d\n", | ||
1608 | q->read_ptr, q->write_ptr); | ||
1609 | IWL_ERR(trans, "Current HW read_ptr %d write_ptr %d\n", | ||
1610 | iwl_read_prph(trans, SCD_QUEUE_RDPTR(cnt)) | ||
1611 | & (TFD_QUEUE_SIZE_MAX - 1), | ||
1612 | iwl_read_prph(trans, SCD_QUEUE_WRPTR(cnt))); | ||
1613 | return 1; | ||
1614 | } | ||
1615 | |||
1616 | return 0; | ||
1617 | } | ||
1618 | |||
1619 | static const char *get_fh_string(int cmd) | 1638 | static const char *get_fh_string(int cmd) |
1620 | { | 1639 | { |
1640 | #define IWL_CMD(x) case x: return #x | ||
1621 | switch (cmd) { | 1641 | switch (cmd) { |
1622 | IWL_CMD(FH_RSCSR_CHNL0_STTS_WPTR_REG); | 1642 | IWL_CMD(FH_RSCSR_CHNL0_STTS_WPTR_REG); |
1623 | IWL_CMD(FH_RSCSR_CHNL0_RBDCB_BASE_REG); | 1643 | IWL_CMD(FH_RSCSR_CHNL0_RBDCB_BASE_REG); |
@@ -1631,6 +1651,7 @@ static const char *get_fh_string(int cmd) | |||
1631 | default: | 1651 | default: |
1632 | return "UNKNOWN"; | 1652 | return "UNKNOWN"; |
1633 | } | 1653 | } |
1654 | #undef IWL_CMD | ||
1634 | } | 1655 | } |
1635 | 1656 | ||
1636 | int iwl_dump_fh(struct iwl_trans *trans, char **buf, bool display) | 1657 | int iwl_dump_fh(struct iwl_trans *trans, char **buf, bool display) |
@@ -1679,6 +1700,7 @@ int iwl_dump_fh(struct iwl_trans *trans, char **buf, bool display) | |||
1679 | 1700 | ||
1680 | static const char *get_csr_string(int cmd) | 1701 | static const char *get_csr_string(int cmd) |
1681 | { | 1702 | { |
1703 | #define IWL_CMD(x) case x: return #x | ||
1682 | switch (cmd) { | 1704 | switch (cmd) { |
1683 | IWL_CMD(CSR_HW_IF_CONFIG_REG); | 1705 | IWL_CMD(CSR_HW_IF_CONFIG_REG); |
1684 | IWL_CMD(CSR_INT_COALESCING); | 1706 | IWL_CMD(CSR_INT_COALESCING); |
@@ -1706,6 +1728,7 @@ static const char *get_csr_string(int cmd) | |||
1706 | default: | 1728 | default: |
1707 | return "UNKNOWN"; | 1729 | return "UNKNOWN"; |
1708 | } | 1730 | } |
1731 | #undef IWL_CMD | ||
1709 | } | 1732 | } |
1710 | 1733 | ||
1711 | void iwl_dump_csr(struct iwl_trans *trans) | 1734 | void iwl_dump_csr(struct iwl_trans *trans) |
@@ -1983,11 +2006,26 @@ static ssize_t iwl_dbgfs_fh_reg_read(struct file *file, | |||
1983 | return ret; | 2006 | return ret; |
1984 | } | 2007 | } |
1985 | 2008 | ||
2009 | static ssize_t iwl_dbgfs_fw_restart_write(struct file *file, | ||
2010 | const char __user *user_buf, | ||
2011 | size_t count, loff_t *ppos) | ||
2012 | { | ||
2013 | struct iwl_trans *trans = file->private_data; | ||
2014 | |||
2015 | if (!trans->op_mode) | ||
2016 | return -EAGAIN; | ||
2017 | |||
2018 | iwl_op_mode_nic_error(trans->op_mode); | ||
2019 | |||
2020 | return count; | ||
2021 | } | ||
2022 | |||
1986 | DEBUGFS_READ_WRITE_FILE_OPS(interrupt); | 2023 | DEBUGFS_READ_WRITE_FILE_OPS(interrupt); |
1987 | DEBUGFS_READ_FILE_OPS(fh_reg); | 2024 | DEBUGFS_READ_FILE_OPS(fh_reg); |
1988 | DEBUGFS_READ_FILE_OPS(rx_queue); | 2025 | DEBUGFS_READ_FILE_OPS(rx_queue); |
1989 | DEBUGFS_READ_FILE_OPS(tx_queue); | 2026 | DEBUGFS_READ_FILE_OPS(tx_queue); |
1990 | DEBUGFS_WRITE_FILE_OPS(csr); | 2027 | DEBUGFS_WRITE_FILE_OPS(csr); |
2028 | DEBUGFS_WRITE_FILE_OPS(fw_restart); | ||
1991 | 2029 | ||
1992 | /* | 2030 | /* |
1993 | * Create the debugfs files and directories | 2031 | * Create the debugfs files and directories |
@@ -2001,6 +2039,7 @@ static int iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans, | |||
2001 | DEBUGFS_ADD_FILE(interrupt, dir, S_IWUSR | S_IRUSR); | 2039 | DEBUGFS_ADD_FILE(interrupt, dir, S_IWUSR | S_IRUSR); |
2002 | DEBUGFS_ADD_FILE(csr, dir, S_IWUSR); | 2040 | DEBUGFS_ADD_FILE(csr, dir, S_IWUSR); |
2003 | DEBUGFS_ADD_FILE(fh_reg, dir, S_IRUSR); | 2041 | DEBUGFS_ADD_FILE(fh_reg, dir, S_IRUSR); |
2042 | DEBUGFS_ADD_FILE(fw_restart, dir, S_IWUSR); | ||
2004 | return 0; | 2043 | return 0; |
2005 | } | 2044 | } |
2006 | #else | 2045 | #else |
@@ -2032,7 +2071,6 @@ const struct iwl_trans_ops trans_ops_pcie = { | |||
2032 | .dbgfs_register = iwl_trans_pcie_dbgfs_register, | 2071 | .dbgfs_register = iwl_trans_pcie_dbgfs_register, |
2033 | 2072 | ||
2034 | .wait_tx_queue_empty = iwl_trans_pcie_wait_tx_queue_empty, | 2073 | .wait_tx_queue_empty = iwl_trans_pcie_wait_tx_queue_empty, |
2035 | .check_stuck_queue = iwl_trans_pcie_check_stuck_queue, | ||
2036 | 2074 | ||
2037 | #ifdef CONFIG_PM_SLEEP | 2075 | #ifdef CONFIG_PM_SLEEP |
2038 | .suspend = iwl_trans_pcie_suspend, | 2076 | .suspend = iwl_trans_pcie_suspend, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 66c54c1b404e..f3496a0490f0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h | |||
@@ -305,6 +305,12 @@ static inline struct page *rxb_steal_page(struct iwl_rx_cmd_buffer *r) | |||
305 | * list of such notifications to filter. Max length is | 305 | * list of such notifications to filter. Max length is |
306 | * %MAX_NO_RECLAIM_CMDS. | 306 | * %MAX_NO_RECLAIM_CMDS. |
307 | * @n_no_reclaim_cmds: # of commands in list | 307 | * @n_no_reclaim_cmds: # of commands in list |
308 | * @rx_buf_size_8k: 8 kB RX buffer size needed for A-MSDUs, | ||
309 | * if unset 4k will be the RX buffer size | ||
310 | * @queue_watchdog_timeout: time (in ms) after which queues | ||
311 | * are considered stuck and will trigger device restart | ||
312 | * @command_names: array of command names, must be 256 entries | ||
313 | * (one for each command); for debugging only | ||
308 | */ | 314 | */ |
309 | struct iwl_trans_config { | 315 | struct iwl_trans_config { |
310 | struct iwl_op_mode *op_mode; | 316 | struct iwl_op_mode *op_mode; |
@@ -314,6 +320,10 @@ struct iwl_trans_config { | |||
314 | u8 cmd_queue; | 320 | u8 cmd_queue; |
315 | const u8 *no_reclaim_cmds; | 321 | const u8 *no_reclaim_cmds; |
316 | int n_no_reclaim_cmds; | 322 | int n_no_reclaim_cmds; |
323 | |||
324 | bool rx_buf_size_8k; | ||
325 | unsigned int queue_watchdog_timeout; | ||
326 | const char **command_names; | ||
317 | }; | 327 | }; |
318 | 328 | ||
319 | /** | 329 | /** |
@@ -351,7 +361,6 @@ struct iwl_trans_config { | |||
351 | * irq, tasklet etc... From this point on, the device may not issue | 361 | * irq, tasklet etc... From this point on, the device may not issue |
352 | * any interrupt (incl. RFKILL). | 362 | * any interrupt (incl. RFKILL). |
353 | * May sleep | 363 | * May sleep |
354 | * @check_stuck_queue: check if a specific queue is stuck | ||
355 | * @wait_tx_queue_empty: wait until all tx queues are empty | 364 | * @wait_tx_queue_empty: wait until all tx queues are empty |
356 | * May sleep | 365 | * May sleep |
357 | * @dbgfs_register: add the dbgfs files under this directory. Files will be | 366 | * @dbgfs_register: add the dbgfs files under this directory. Files will be |
@@ -390,7 +399,6 @@ struct iwl_trans_ops { | |||
390 | void (*free)(struct iwl_trans *trans); | 399 | void (*free)(struct iwl_trans *trans); |
391 | 400 | ||
392 | int (*dbgfs_register)(struct iwl_trans *trans, struct dentry* dir); | 401 | int (*dbgfs_register)(struct iwl_trans *trans, struct dentry* dir); |
393 | int (*check_stuck_queue)(struct iwl_trans *trans, int q); | ||
394 | int (*wait_tx_queue_empty)(struct iwl_trans *trans); | 402 | int (*wait_tx_queue_empty)(struct iwl_trans *trans); |
395 | #ifdef CONFIG_PM_SLEEP | 403 | #ifdef CONFIG_PM_SLEEP |
396 | int (*suspend)(struct iwl_trans *trans); | 404 | int (*suspend)(struct iwl_trans *trans); |
@@ -426,7 +434,6 @@ enum iwl_trans_state { | |||
426 | * @hw_id: a u32 with the ID of the device / subdevice. | 434 | * @hw_id: a u32 with the ID of the device / subdevice. |
427 | * Set during transport allocation. | 435 | * Set during transport allocation. |
428 | * @hw_id_str: a string with info about HW ID. Set during transport allocation. | 436 | * @hw_id_str: a string with info about HW ID. Set during transport allocation. |
429 | * @nvm_device_type: indicates OTP or eeprom | ||
430 | * @pm_support: set to true in start_hw if link pm is supported | 437 | * @pm_support: set to true in start_hw if link pm is supported |
431 | * @wait_command_queue: the wait_queue for SYNC host commands | 438 | * @wait_command_queue: the wait_queue for SYNC host commands |
432 | */ | 439 | */ |
@@ -442,7 +449,6 @@ struct iwl_trans { | |||
442 | u32 hw_id; | 449 | u32 hw_id; |
443 | char hw_id_str[52]; | 450 | char hw_id_str[52]; |
444 | 451 | ||
445 | int nvm_device_type; | ||
446 | bool pm_support; | 452 | bool pm_support; |
447 | 453 | ||
448 | wait_queue_head_t wait_command_queue; | 454 | wait_queue_head_t wait_command_queue; |
@@ -573,13 +579,6 @@ static inline int iwl_trans_wait_tx_queue_empty(struct iwl_trans *trans) | |||
573 | return trans->ops->wait_tx_queue_empty(trans); | 579 | return trans->ops->wait_tx_queue_empty(trans); |
574 | } | 580 | } |
575 | 581 | ||
576 | static inline int iwl_trans_check_stuck_queue(struct iwl_trans *trans, int q) | ||
577 | { | ||
578 | WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, | ||
579 | "%s bad state = %d", __func__, trans->state); | ||
580 | |||
581 | return trans->ops->check_stuck_queue(trans, q); | ||
582 | } | ||
583 | static inline int iwl_trans_dbgfs_register(struct iwl_trans *trans, | 582 | static inline int iwl_trans_dbgfs_register(struct iwl_trans *trans, |
584 | struct dentry *dir) | 583 | struct dentry *dir) |
585 | { | 584 | { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-ucode.c b/drivers/net/wireless/iwlwifi/iwl-ucode.c index ba7c9f883cb6..539171945610 100644 --- a/drivers/net/wireless/iwlwifi/iwl-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-ucode.c | |||
@@ -62,7 +62,7 @@ static int iwl_set_Xtal_calib(struct iwl_priv *priv) | |||
62 | { | 62 | { |
63 | struct iwl_calib_xtal_freq_cmd cmd; | 63 | struct iwl_calib_xtal_freq_cmd cmd; |
64 | __le16 *xtal_calib = | 64 | __le16 *xtal_calib = |
65 | (__le16 *)iwl_eeprom_query_addr(priv->shrd, EEPROM_XTAL); | 65 | (__le16 *)iwl_eeprom_query_addr(priv, EEPROM_XTAL); |
66 | 66 | ||
67 | iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD); | 67 | iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD); |
68 | cmd.cap_pin1 = le16_to_cpu(xtal_calib[0]); | 68 | cmd.cap_pin1 = le16_to_cpu(xtal_calib[0]); |
@@ -74,8 +74,7 @@ static int iwl_set_temperature_offset_calib(struct iwl_priv *priv) | |||
74 | { | 74 | { |
75 | struct iwl_calib_temperature_offset_cmd cmd; | 75 | struct iwl_calib_temperature_offset_cmd cmd; |
76 | __le16 *offset_calib = | 76 | __le16 *offset_calib = |
77 | (__le16 *)iwl_eeprom_query_addr(priv->shrd, | 77 | (__le16 *)iwl_eeprom_query_addr(priv, EEPROM_RAW_TEMPERATURE); |
78 | EEPROM_RAW_TEMPERATURE); | ||
79 | 78 | ||
80 | memset(&cmd, 0, sizeof(cmd)); | 79 | memset(&cmd, 0, sizeof(cmd)); |
81 | iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD); | 80 | iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD); |
@@ -91,16 +90,15 @@ static int iwl_set_temperature_offset_calib(struct iwl_priv *priv) | |||
91 | static int iwl_set_temperature_offset_calib_v2(struct iwl_priv *priv) | 90 | static int iwl_set_temperature_offset_calib_v2(struct iwl_priv *priv) |
92 | { | 91 | { |
93 | struct iwl_calib_temperature_offset_v2_cmd cmd; | 92 | struct iwl_calib_temperature_offset_v2_cmd cmd; |
94 | __le16 *offset_calib_high = (__le16 *)iwl_eeprom_query_addr(priv->shrd, | 93 | __le16 *offset_calib_high = (__le16 *)iwl_eeprom_query_addr(priv, |
95 | EEPROM_KELVIN_TEMPERATURE); | 94 | EEPROM_KELVIN_TEMPERATURE); |
96 | __le16 *offset_calib_low = | 95 | __le16 *offset_calib_low = |
97 | (__le16 *)iwl_eeprom_query_addr(priv->shrd, | 96 | (__le16 *)iwl_eeprom_query_addr(priv, EEPROM_RAW_TEMPERATURE); |
98 | EEPROM_RAW_TEMPERATURE); | ||
99 | struct iwl_eeprom_calib_hdr *hdr; | 97 | struct iwl_eeprom_calib_hdr *hdr; |
100 | 98 | ||
101 | memset(&cmd, 0, sizeof(cmd)); | 99 | memset(&cmd, 0, sizeof(cmd)); |
102 | iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD); | 100 | iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD); |
103 | hdr = (struct iwl_eeprom_calib_hdr *)iwl_eeprom_query_addr(priv->shrd, | 101 | hdr = (struct iwl_eeprom_calib_hdr *)iwl_eeprom_query_addr(priv, |
104 | EEPROM_CALIB_ALL); | 102 | EEPROM_CALIB_ALL); |
105 | memcpy(&cmd.radio_sensor_offset_high, offset_calib_high, | 103 | memcpy(&cmd.radio_sensor_offset_high, offset_calib_high, |
106 | sizeof(*offset_calib_high)); | 104 | sizeof(*offset_calib_high)); |
@@ -180,7 +178,7 @@ int iwl_init_alive_start(struct iwl_priv *priv) | |||
180 | return 0; | 178 | return 0; |
181 | } | 179 | } |
182 | 180 | ||
183 | static int iwl_send_wimax_coex(struct iwl_priv *priv) | 181 | int iwl_send_wimax_coex(struct iwl_priv *priv) |
184 | { | 182 | { |
185 | struct iwl_wimax_coex_cmd coex_cmd; | 183 | struct iwl_wimax_coex_cmd coex_cmd; |
186 | 184 | ||