diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi')
20 files changed, 373 insertions, 383 deletions
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig index ad3bdba6bee..1d7572f9887 100644 --- a/drivers/net/wireless/iwlwifi/Kconfig +++ b/drivers/net/wireless/iwlwifi/Kconfig | |||
@@ -111,20 +111,3 @@ config IWLWIFI_DEVICE_SVTOOL | |||
111 | NL80211_TESTMODE. svtool is a software validation tool that runs in | 111 | NL80211_TESTMODE. svtool is a software validation tool that runs in |
112 | the user space and interacts with the device in the kernel space | 112 | the user space and interacts with the device in the kernel space |
113 | through the generic netlink message via NL80211_TESTMODE channel. | 113 | through the generic netlink message via NL80211_TESTMODE channel. |
114 | |||
115 | config IWL_P2P | ||
116 | bool "iwlwifi experimental P2P support" | ||
117 | depends on IWLAGN | ||
118 | help | ||
119 | This option enables experimental P2P support for some devices | ||
120 | based on microcode support. Since P2P support is still under | ||
121 | development, this option may even enable it for some devices | ||
122 | now that turn out to not support it in the future due to | ||
123 | microcode restrictions. | ||
124 | |||
125 | To determine if your microcode supports the experimental P2P | ||
126 | offered by this option, check if the driver advertises AP | ||
127 | support when it is loaded. | ||
128 | |||
129 | Say Y only if you want to experiment with P2P. | ||
130 | |||
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 01b49eb8c8e..ccdbed56717 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c | |||
@@ -30,7 +30,6 @@ | |||
30 | #include <linux/delay.h> | 30 | #include <linux/delay.h> |
31 | #include <linux/skbuff.h> | 31 | #include <linux/skbuff.h> |
32 | #include <linux/netdevice.h> | 32 | #include <linux/netdevice.h> |
33 | #include <linux/wireless.h> | ||
34 | #include <net/mac80211.h> | 33 | #include <net/mac80211.h> |
35 | #include <linux/etherdevice.h> | 34 | #include <linux/etherdevice.h> |
36 | #include <asm/unaligned.h> | 35 | #include <asm/unaligned.h> |
@@ -46,8 +45,12 @@ | |||
46 | #include "iwl-agn-hw.h" | 45 | #include "iwl-agn-hw.h" |
47 | 46 | ||
48 | /* Highest firmware API version supported */ | 47 | /* Highest firmware API version supported */ |
49 | #define IWL1000_UCODE_API_MAX 5 | 48 | #define IWL1000_UCODE_API_MAX 6 |
50 | #define IWL100_UCODE_API_MAX 5 | 49 | #define IWL100_UCODE_API_MAX 6 |
50 | |||
51 | /* Oldest version we won't warn about */ | ||
52 | #define IWL1000_UCODE_API_OK 5 | ||
53 | #define IWL100_UCODE_API_OK 5 | ||
51 | 54 | ||
52 | /* Lowest firmware API version supported */ | 55 | /* Lowest firmware API version supported */ |
53 | #define IWL1000_UCODE_API_MIN 1 | 56 | #define IWL1000_UCODE_API_MIN 1 |
@@ -135,8 +138,7 @@ static int iwl1000_hw_set_hw_params(struct iwl_priv *priv) | |||
135 | priv->hw_params.max_data_size = IWLAGN_RTC_DATA_SIZE; | 138 | priv->hw_params.max_data_size = IWLAGN_RTC_DATA_SIZE; |
136 | priv->hw_params.max_inst_size = IWLAGN_RTC_INST_SIZE; | 139 | priv->hw_params.max_inst_size = IWLAGN_RTC_INST_SIZE; |
137 | 140 | ||
138 | priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) | | 141 | priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ); |
139 | BIT(IEEE80211_BAND_5GHZ); | ||
140 | 142 | ||
141 | priv->hw_params.tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant); | 143 | priv->hw_params.tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant); |
142 | if (priv->cfg->rx_with_siso_diversity) | 144 | if (priv->cfg->rx_with_siso_diversity) |
@@ -201,12 +203,13 @@ static struct iwl_base_params iwl1000_base_params = { | |||
201 | static struct iwl_ht_params iwl1000_ht_params = { | 203 | static struct iwl_ht_params iwl1000_ht_params = { |
202 | .ht_greenfield_support = true, | 204 | .ht_greenfield_support = true, |
203 | .use_rts_for_aggregation = true, /* use rts/cts protection */ | 205 | .use_rts_for_aggregation = true, /* use rts/cts protection */ |
204 | .smps_mode = IEEE80211_SMPS_STATIC, | 206 | .smps_mode = IEEE80211_SMPS_DYNAMIC, |
205 | }; | 207 | }; |
206 | 208 | ||
207 | #define IWL_DEVICE_1000 \ | 209 | #define IWL_DEVICE_1000 \ |
208 | .fw_name_pre = IWL1000_FW_PRE, \ | 210 | .fw_name_pre = IWL1000_FW_PRE, \ |
209 | .ucode_api_max = IWL1000_UCODE_API_MAX, \ | 211 | .ucode_api_max = IWL1000_UCODE_API_MAX, \ |
212 | .ucode_api_ok = IWL1000_UCODE_API_OK, \ | ||
210 | .ucode_api_min = IWL1000_UCODE_API_MIN, \ | 213 | .ucode_api_min = IWL1000_UCODE_API_MIN, \ |
211 | .eeprom_ver = EEPROM_1000_EEPROM_VERSION, \ | 214 | .eeprom_ver = EEPROM_1000_EEPROM_VERSION, \ |
212 | .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, \ | 215 | .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, \ |
@@ -228,6 +231,7 @@ struct iwl_cfg iwl1000_bg_cfg = { | |||
228 | #define IWL_DEVICE_100 \ | 231 | #define IWL_DEVICE_100 \ |
229 | .fw_name_pre = IWL100_FW_PRE, \ | 232 | .fw_name_pre = IWL100_FW_PRE, \ |
230 | .ucode_api_max = IWL100_UCODE_API_MAX, \ | 233 | .ucode_api_max = IWL100_UCODE_API_MAX, \ |
234 | .ucode_api_ok = IWL100_UCODE_API_OK, \ | ||
231 | .ucode_api_min = IWL100_UCODE_API_MIN, \ | 235 | .ucode_api_min = IWL100_UCODE_API_MIN, \ |
232 | .eeprom_ver = EEPROM_1000_EEPROM_VERSION, \ | 236 | .eeprom_ver = EEPROM_1000_EEPROM_VERSION, \ |
233 | .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, \ | 237 | .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, \ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index 0e13f0bb2e1..54d931d614f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c | |||
@@ -30,7 +30,6 @@ | |||
30 | #include <linux/delay.h> | 30 | #include <linux/delay.h> |
31 | #include <linux/skbuff.h> | 31 | #include <linux/skbuff.h> |
32 | #include <linux/netdevice.h> | 32 | #include <linux/netdevice.h> |
33 | #include <linux/wireless.h> | ||
34 | #include <net/mac80211.h> | 33 | #include <net/mac80211.h> |
35 | #include <linux/etherdevice.h> | 34 | #include <linux/etherdevice.h> |
36 | #include <asm/unaligned.h> | 35 | #include <asm/unaligned.h> |
@@ -47,10 +46,16 @@ | |||
47 | #include "iwl-6000-hw.h" | 46 | #include "iwl-6000-hw.h" |
48 | 47 | ||
49 | /* Highest firmware API version supported */ | 48 | /* Highest firmware API version supported */ |
50 | #define IWL2030_UCODE_API_MAX 5 | 49 | #define IWL2030_UCODE_API_MAX 6 |
51 | #define IWL2000_UCODE_API_MAX 5 | 50 | #define IWL2000_UCODE_API_MAX 6 |
52 | #define IWL105_UCODE_API_MAX 5 | 51 | #define IWL105_UCODE_API_MAX 6 |
53 | #define IWL135_UCODE_API_MAX 5 | 52 | #define IWL135_UCODE_API_MAX 6 |
53 | |||
54 | /* Oldest version we won't warn about */ | ||
55 | #define IWL2030_UCODE_API_OK 5 | ||
56 | #define IWL2000_UCODE_API_OK 5 | ||
57 | #define IWL105_UCODE_API_OK 5 | ||
58 | #define IWL135_UCODE_API_OK 5 | ||
54 | 59 | ||
55 | /* Lowest firmware API version supported */ | 60 | /* Lowest firmware API version supported */ |
56 | #define IWL2030_UCODE_API_MIN 5 | 61 | #define IWL2030_UCODE_API_MIN 5 |
@@ -130,8 +135,7 @@ static int iwl2000_hw_set_hw_params(struct iwl_priv *priv) | |||
130 | priv->hw_params.max_data_size = IWL60_RTC_DATA_SIZE; | 135 | priv->hw_params.max_data_size = IWL60_RTC_DATA_SIZE; |
131 | priv->hw_params.max_inst_size = IWL60_RTC_INST_SIZE; | 136 | priv->hw_params.max_inst_size = IWL60_RTC_INST_SIZE; |
132 | 137 | ||
133 | priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) | | 138 | priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ); |
134 | BIT(IEEE80211_BAND_5GHZ); | ||
135 | 139 | ||
136 | priv->hw_params.tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant); | 140 | priv->hw_params.tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant); |
137 | if (priv->cfg->rx_with_siso_diversity) | 141 | if (priv->cfg->rx_with_siso_diversity) |
@@ -217,6 +221,7 @@ static struct iwl_base_params iwl2000_base_params = { | |||
217 | .wd_timeout = IWL_DEF_WD_TIMEOUT, | 221 | .wd_timeout = IWL_DEF_WD_TIMEOUT, |
218 | .max_event_log_size = 512, | 222 | .max_event_log_size = 512, |
219 | .shadow_reg_enable = true, | 223 | .shadow_reg_enable = true, |
224 | .hd_v2 = true, | ||
220 | }; | 225 | }; |
221 | 226 | ||
222 | 227 | ||
@@ -236,6 +241,7 @@ static struct iwl_base_params iwl2030_base_params = { | |||
236 | .wd_timeout = IWL_LONG_WD_TIMEOUT, | 241 | .wd_timeout = IWL_LONG_WD_TIMEOUT, |
237 | .max_event_log_size = 512, | 242 | .max_event_log_size = 512, |
238 | .shadow_reg_enable = true, | 243 | .shadow_reg_enable = true, |
244 | .hd_v2 = true, | ||
239 | }; | 245 | }; |
240 | 246 | ||
241 | static struct iwl_ht_params iwl2000_ht_params = { | 247 | static struct iwl_ht_params iwl2000_ht_params = { |
@@ -256,6 +262,7 @@ static struct iwl_bt_params iwl2030_bt_params = { | |||
256 | #define IWL_DEVICE_2000 \ | 262 | #define IWL_DEVICE_2000 \ |
257 | .fw_name_pre = IWL2000_FW_PRE, \ | 263 | .fw_name_pre = IWL2000_FW_PRE, \ |
258 | .ucode_api_max = IWL2000_UCODE_API_MAX, \ | 264 | .ucode_api_max = IWL2000_UCODE_API_MAX, \ |
265 | .ucode_api_ok = IWL2000_UCODE_API_OK, \ | ||
259 | .ucode_api_min = IWL2000_UCODE_API_MIN, \ | 266 | .ucode_api_min = IWL2000_UCODE_API_MIN, \ |
260 | .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \ | 267 | .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \ |
261 | .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ | 268 | .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ |
@@ -280,6 +287,7 @@ struct iwl_cfg iwl2000_2bg_cfg = { | |||
280 | #define IWL_DEVICE_2030 \ | 287 | #define IWL_DEVICE_2030 \ |
281 | .fw_name_pre = IWL2030_FW_PRE, \ | 288 | .fw_name_pre = IWL2030_FW_PRE, \ |
282 | .ucode_api_max = IWL2030_UCODE_API_MAX, \ | 289 | .ucode_api_max = IWL2030_UCODE_API_MAX, \ |
290 | .ucode_api_ok = IWL2030_UCODE_API_OK, \ | ||
283 | .ucode_api_min = IWL2030_UCODE_API_MIN, \ | 291 | .ucode_api_min = IWL2030_UCODE_API_MIN, \ |
284 | .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \ | 292 | .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \ |
285 | .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ | 293 | .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ |
@@ -306,6 +314,7 @@ struct iwl_cfg iwl2030_2bg_cfg = { | |||
306 | #define IWL_DEVICE_105 \ | 314 | #define IWL_DEVICE_105 \ |
307 | .fw_name_pre = IWL105_FW_PRE, \ | 315 | .fw_name_pre = IWL105_FW_PRE, \ |
308 | .ucode_api_max = IWL105_UCODE_API_MAX, \ | 316 | .ucode_api_max = IWL105_UCODE_API_MAX, \ |
317 | .ucode_api_ok = IWL105_UCODE_API_OK, \ | ||
309 | .ucode_api_min = IWL105_UCODE_API_MIN, \ | 318 | .ucode_api_min = IWL105_UCODE_API_MIN, \ |
310 | .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \ | 319 | .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \ |
311 | .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ | 320 | .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ |
@@ -332,6 +341,7 @@ struct iwl_cfg iwl105_bgn_cfg = { | |||
332 | #define IWL_DEVICE_135 \ | 341 | #define IWL_DEVICE_135 \ |
333 | .fw_name_pre = IWL135_FW_PRE, \ | 342 | .fw_name_pre = IWL135_FW_PRE, \ |
334 | .ucode_api_max = IWL135_UCODE_API_MAX, \ | 343 | .ucode_api_max = IWL135_UCODE_API_MAX, \ |
344 | .ucode_api_ok = IWL135_UCODE_API_OK, \ | ||
335 | .ucode_api_min = IWL135_UCODE_API_MIN, \ | 345 | .ucode_api_min = IWL135_UCODE_API_MIN, \ |
336 | .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \ | 346 | .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \ |
337 | .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ | 347 | .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index c95cefd529d..a9adee5634d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c | |||
@@ -31,7 +31,6 @@ | |||
31 | #include <linux/sched.h> | 31 | #include <linux/sched.h> |
32 | #include <linux/skbuff.h> | 32 | #include <linux/skbuff.h> |
33 | #include <linux/netdevice.h> | 33 | #include <linux/netdevice.h> |
34 | #include <linux/wireless.h> | ||
35 | #include <net/mac80211.h> | 34 | #include <net/mac80211.h> |
36 | #include <linux/etherdevice.h> | 35 | #include <linux/etherdevice.h> |
37 | #include <asm/unaligned.h> | 36 | #include <asm/unaligned.h> |
@@ -84,12 +83,12 @@ static void iwl5000_nic_config(struct iwl_priv *priv) | |||
84 | } | 83 | } |
85 | 84 | ||
86 | static struct iwl_sensitivity_ranges iwl5000_sensitivity = { | 85 | static struct iwl_sensitivity_ranges iwl5000_sensitivity = { |
87 | .min_nrg_cck = 95, | 86 | .min_nrg_cck = 100, |
88 | .max_nrg_cck = 0, /* not used, set to 0 */ | 87 | .max_nrg_cck = 0, /* not used, set to 0 */ |
89 | .auto_corr_min_ofdm = 90, | 88 | .auto_corr_min_ofdm = 90, |
90 | .auto_corr_min_ofdm_mrc = 170, | 89 | .auto_corr_min_ofdm_mrc = 170, |
91 | .auto_corr_min_ofdm_x1 = 120, | 90 | .auto_corr_min_ofdm_x1 = 105, |
92 | .auto_corr_min_ofdm_mrc_x1 = 240, | 91 | .auto_corr_min_ofdm_mrc_x1 = 220, |
93 | 92 | ||
94 | .auto_corr_max_ofdm = 120, | 93 | .auto_corr_max_ofdm = 120, |
95 | .auto_corr_max_ofdm_mrc = 210, | 94 | .auto_corr_max_ofdm_mrc = 210, |
@@ -98,10 +97,10 @@ static struct iwl_sensitivity_ranges iwl5000_sensitivity = { | |||
98 | 97 | ||
99 | .auto_corr_min_cck = 125, | 98 | .auto_corr_min_cck = 125, |
100 | .auto_corr_max_cck = 200, | 99 | .auto_corr_max_cck = 200, |
101 | .auto_corr_min_cck_mrc = 170, | 100 | .auto_corr_min_cck_mrc = 200, |
102 | .auto_corr_max_cck_mrc = 400, | 101 | .auto_corr_max_cck_mrc = 400, |
103 | .nrg_th_cck = 95, | 102 | .nrg_th_cck = 100, |
104 | .nrg_th_ofdm = 95, | 103 | .nrg_th_ofdm = 100, |
105 | 104 | ||
106 | .barker_corr_th_min = 190, | 105 | .barker_corr_th_min = 190, |
107 | .barker_corr_th_min_mrc = 390, | 106 | .barker_corr_th_min_mrc = 390, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 973d1972e8c..339de88d9ae 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c | |||
@@ -30,7 +30,6 @@ | |||
30 | #include <linux/delay.h> | 30 | #include <linux/delay.h> |
31 | #include <linux/skbuff.h> | 31 | #include <linux/skbuff.h> |
32 | #include <linux/netdevice.h> | 32 | #include <linux/netdevice.h> |
33 | #include <linux/wireless.h> | ||
34 | #include <net/mac80211.h> | 33 | #include <net/mac80211.h> |
35 | #include <linux/etherdevice.h> | 34 | #include <linux/etherdevice.h> |
36 | #include <asm/unaligned.h> | 35 | #include <asm/unaligned.h> |
@@ -50,7 +49,10 @@ | |||
50 | /* Highest firmware API version supported */ | 49 | /* Highest firmware API version supported */ |
51 | #define IWL6000_UCODE_API_MAX 4 | 50 | #define IWL6000_UCODE_API_MAX 4 |
52 | #define IWL6050_UCODE_API_MAX 5 | 51 | #define IWL6050_UCODE_API_MAX 5 |
53 | #define IWL6000G2_UCODE_API_MAX 5 | 52 | #define IWL6000G2_UCODE_API_MAX 6 |
53 | |||
54 | /* Oldest version we won't warn about */ | ||
55 | #define IWL6000G2_UCODE_API_OK 5 | ||
54 | 56 | ||
55 | /* Lowest firmware API version supported */ | 57 | /* Lowest firmware API version supported */ |
56 | #define IWL6000_UCODE_API_MIN 4 | 58 | #define IWL6000_UCODE_API_MIN 4 |
@@ -111,7 +113,7 @@ static void iwl6000_nic_config(struct iwl_priv *priv) | |||
111 | } | 113 | } |
112 | 114 | ||
113 | static struct iwl_sensitivity_ranges iwl6000_sensitivity = { | 115 | static struct iwl_sensitivity_ranges iwl6000_sensitivity = { |
114 | .min_nrg_cck = 97, | 116 | .min_nrg_cck = 110, |
115 | .max_nrg_cck = 0, /* not used, set to 0 */ | 117 | .max_nrg_cck = 0, /* not used, set to 0 */ |
116 | .auto_corr_min_ofdm = 80, | 118 | .auto_corr_min_ofdm = 80, |
117 | .auto_corr_min_ofdm_mrc = 128, | 119 | .auto_corr_min_ofdm_mrc = 128, |
@@ -127,11 +129,11 @@ static struct iwl_sensitivity_ranges iwl6000_sensitivity = { | |||
127 | .auto_corr_max_cck = 175, | 129 | .auto_corr_max_cck = 175, |
128 | .auto_corr_min_cck_mrc = 160, | 130 | .auto_corr_min_cck_mrc = 160, |
129 | .auto_corr_max_cck_mrc = 310, | 131 | .auto_corr_max_cck_mrc = 310, |
130 | .nrg_th_cck = 97, | 132 | .nrg_th_cck = 110, |
131 | .nrg_th_ofdm = 100, | 133 | .nrg_th_ofdm = 110, |
132 | 134 | ||
133 | .barker_corr_th_min = 190, | 135 | .barker_corr_th_min = 190, |
134 | .barker_corr_th_min_mrc = 390, | 136 | .barker_corr_th_min_mrc = 336, |
135 | .nrg_th_cca = 62, | 137 | .nrg_th_cca = 62, |
136 | }; | 138 | }; |
137 | 139 | ||
@@ -365,8 +367,9 @@ static struct iwl_bt_params iwl6000_bt_params = { | |||
365 | }; | 367 | }; |
366 | 368 | ||
367 | #define IWL_DEVICE_6005 \ | 369 | #define IWL_DEVICE_6005 \ |
368 | .fw_name_pre = IWL6005_FW_PRE, \ | 370 | .fw_name_pre = IWL6005_FW_PRE, \ |
369 | .ucode_api_max = IWL6000G2_UCODE_API_MAX, \ | 371 | .ucode_api_max = IWL6000G2_UCODE_API_MAX, \ |
372 | .ucode_api_ok = IWL6000G2_UCODE_API_OK, \ | ||
370 | .ucode_api_min = IWL6000G2_UCODE_API_MIN, \ | 373 | .ucode_api_min = IWL6000G2_UCODE_API_MIN, \ |
371 | .eeprom_ver = EEPROM_6005_EEPROM_VERSION, \ | 374 | .eeprom_ver = EEPROM_6005_EEPROM_VERSION, \ |
372 | .eeprom_calib_ver = EEPROM_6005_TX_POWER_VERSION, \ | 375 | .eeprom_calib_ver = EEPROM_6005_TX_POWER_VERSION, \ |
@@ -393,8 +396,9 @@ struct iwl_cfg iwl6005_2bg_cfg = { | |||
393 | }; | 396 | }; |
394 | 397 | ||
395 | #define IWL_DEVICE_6030 \ | 398 | #define IWL_DEVICE_6030 \ |
396 | .fw_name_pre = IWL6030_FW_PRE, \ | 399 | .fw_name_pre = IWL6030_FW_PRE, \ |
397 | .ucode_api_max = IWL6000G2_UCODE_API_MAX, \ | 400 | .ucode_api_max = IWL6000G2_UCODE_API_MAX, \ |
401 | .ucode_api_ok = IWL6000G2_UCODE_API_OK, \ | ||
398 | .ucode_api_min = IWL6000G2_UCODE_API_MIN, \ | 402 | .ucode_api_min = IWL6000G2_UCODE_API_MIN, \ |
399 | .eeprom_ver = EEPROM_6030_EEPROM_VERSION, \ | 403 | .eeprom_ver = EEPROM_6030_EEPROM_VERSION, \ |
400 | .eeprom_calib_ver = EEPROM_6030_TX_POWER_VERSION, \ | 404 | .eeprom_calib_ver = EEPROM_6030_TX_POWER_VERSION, \ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c index 72d6297602b..1789e3af810 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c | |||
@@ -505,28 +505,53 @@ static int iwl_enhance_sensitivity_write(struct iwl_priv *priv) | |||
505 | 505 | ||
506 | iwl_prepare_legacy_sensitivity_tbl(priv, data, &cmd.enhance_table[0]); | 506 | iwl_prepare_legacy_sensitivity_tbl(priv, data, &cmd.enhance_table[0]); |
507 | 507 | ||
508 | cmd.enhance_table[HD_INA_NON_SQUARE_DET_OFDM_INDEX] = | 508 | if (priv->cfg->base_params->hd_v2) { |
509 | HD_INA_NON_SQUARE_DET_OFDM_DATA; | 509 | cmd.enhance_table[HD_INA_NON_SQUARE_DET_OFDM_INDEX] = |
510 | cmd.enhance_table[HD_INA_NON_SQUARE_DET_CCK_INDEX] = | 510 | HD_INA_NON_SQUARE_DET_OFDM_DATA_V2; |
511 | HD_INA_NON_SQUARE_DET_CCK_DATA; | 511 | cmd.enhance_table[HD_INA_NON_SQUARE_DET_CCK_INDEX] = |
512 | cmd.enhance_table[HD_CORR_11_INSTEAD_OF_CORR_9_EN_INDEX] = | 512 | HD_INA_NON_SQUARE_DET_CCK_DATA_V2; |
513 | HD_CORR_11_INSTEAD_OF_CORR_9_EN_DATA; | 513 | cmd.enhance_table[HD_CORR_11_INSTEAD_OF_CORR_9_EN_INDEX] = |
514 | cmd.enhance_table[HD_OFDM_NON_SQUARE_DET_SLOPE_MRC_INDEX] = | 514 | HD_CORR_11_INSTEAD_OF_CORR_9_EN_DATA_V2; |
515 | HD_OFDM_NON_SQUARE_DET_SLOPE_MRC_DATA; | 515 | cmd.enhance_table[HD_OFDM_NON_SQUARE_DET_SLOPE_MRC_INDEX] = |
516 | cmd.enhance_table[HD_OFDM_NON_SQUARE_DET_INTERCEPT_MRC_INDEX] = | 516 | HD_OFDM_NON_SQUARE_DET_SLOPE_MRC_DATA_V2; |
517 | HD_OFDM_NON_SQUARE_DET_INTERCEPT_MRC_DATA; | 517 | cmd.enhance_table[HD_OFDM_NON_SQUARE_DET_INTERCEPT_MRC_INDEX] = |
518 | cmd.enhance_table[HD_OFDM_NON_SQUARE_DET_SLOPE_INDEX] = | 518 | HD_OFDM_NON_SQUARE_DET_INTERCEPT_MRC_DATA_V2; |
519 | HD_OFDM_NON_SQUARE_DET_SLOPE_DATA; | 519 | cmd.enhance_table[HD_OFDM_NON_SQUARE_DET_SLOPE_INDEX] = |
520 | cmd.enhance_table[HD_OFDM_NON_SQUARE_DET_INTERCEPT_INDEX] = | 520 | HD_OFDM_NON_SQUARE_DET_SLOPE_DATA_V2; |
521 | HD_OFDM_NON_SQUARE_DET_INTERCEPT_DATA; | 521 | cmd.enhance_table[HD_OFDM_NON_SQUARE_DET_INTERCEPT_INDEX] = |
522 | cmd.enhance_table[HD_CCK_NON_SQUARE_DET_SLOPE_MRC_INDEX] = | 522 | HD_OFDM_NON_SQUARE_DET_INTERCEPT_DATA_V2; |
523 | HD_CCK_NON_SQUARE_DET_SLOPE_MRC_DATA; | 523 | cmd.enhance_table[HD_CCK_NON_SQUARE_DET_SLOPE_MRC_INDEX] = |
524 | cmd.enhance_table[HD_CCK_NON_SQUARE_DET_INTERCEPT_MRC_INDEX] = | 524 | HD_CCK_NON_SQUARE_DET_SLOPE_MRC_DATA_V2; |
525 | HD_CCK_NON_SQUARE_DET_INTERCEPT_MRC_DATA; | 525 | cmd.enhance_table[HD_CCK_NON_SQUARE_DET_INTERCEPT_MRC_INDEX] = |
526 | cmd.enhance_table[HD_CCK_NON_SQUARE_DET_SLOPE_INDEX] = | 526 | HD_CCK_NON_SQUARE_DET_INTERCEPT_MRC_DATA_V2; |
527 | HD_CCK_NON_SQUARE_DET_SLOPE_DATA; | 527 | cmd.enhance_table[HD_CCK_NON_SQUARE_DET_SLOPE_INDEX] = |
528 | cmd.enhance_table[HD_CCK_NON_SQUARE_DET_INTERCEPT_INDEX] = | 528 | HD_CCK_NON_SQUARE_DET_SLOPE_DATA_V2; |
529 | HD_CCK_NON_SQUARE_DET_INTERCEPT_DATA; | 529 | cmd.enhance_table[HD_CCK_NON_SQUARE_DET_INTERCEPT_INDEX] = |
530 | HD_CCK_NON_SQUARE_DET_INTERCEPT_DATA_V2; | ||
531 | } else { | ||
532 | cmd.enhance_table[HD_INA_NON_SQUARE_DET_OFDM_INDEX] = | ||
533 | HD_INA_NON_SQUARE_DET_OFDM_DATA_V1; | ||
534 | cmd.enhance_table[HD_INA_NON_SQUARE_DET_CCK_INDEX] = | ||
535 | HD_INA_NON_SQUARE_DET_CCK_DATA_V1; | ||
536 | cmd.enhance_table[HD_CORR_11_INSTEAD_OF_CORR_9_EN_INDEX] = | ||
537 | HD_CORR_11_INSTEAD_OF_CORR_9_EN_DATA_V1; | ||
538 | cmd.enhance_table[HD_OFDM_NON_SQUARE_DET_SLOPE_MRC_INDEX] = | ||
539 | HD_OFDM_NON_SQUARE_DET_SLOPE_MRC_DATA_V1; | ||
540 | cmd.enhance_table[HD_OFDM_NON_SQUARE_DET_INTERCEPT_MRC_INDEX] = | ||
541 | HD_OFDM_NON_SQUARE_DET_INTERCEPT_MRC_DATA_V1; | ||
542 | cmd.enhance_table[HD_OFDM_NON_SQUARE_DET_SLOPE_INDEX] = | ||
543 | HD_OFDM_NON_SQUARE_DET_SLOPE_DATA_V1; | ||
544 | cmd.enhance_table[HD_OFDM_NON_SQUARE_DET_INTERCEPT_INDEX] = | ||
545 | HD_OFDM_NON_SQUARE_DET_INTERCEPT_DATA_V1; | ||
546 | cmd.enhance_table[HD_CCK_NON_SQUARE_DET_SLOPE_MRC_INDEX] = | ||
547 | HD_CCK_NON_SQUARE_DET_SLOPE_MRC_DATA_V1; | ||
548 | cmd.enhance_table[HD_CCK_NON_SQUARE_DET_INTERCEPT_MRC_INDEX] = | ||
549 | HD_CCK_NON_SQUARE_DET_INTERCEPT_MRC_DATA_V1; | ||
550 | cmd.enhance_table[HD_CCK_NON_SQUARE_DET_SLOPE_INDEX] = | ||
551 | HD_CCK_NON_SQUARE_DET_SLOPE_DATA_V1; | ||
552 | cmd.enhance_table[HD_CCK_NON_SQUARE_DET_INTERCEPT_INDEX] = | ||
553 | HD_CCK_NON_SQUARE_DET_INTERCEPT_DATA_V1; | ||
554 | } | ||
530 | 555 | ||
531 | /* Update uCode's "work" table, and copy it to DSP */ | 556 | /* Update uCode's "work" table, and copy it to DSP */ |
532 | cmd.control = SENSITIVITY_CMD_CONTROL_WORK_TABLE; | 557 | cmd.control = SENSITIVITY_CMD_CONTROL_WORK_TABLE; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hw.h b/drivers/net/wireless/iwlwifi/iwl-agn-hw.h index 0e5b842529c..47c43042ba4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-hw.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn-hw.h | |||
@@ -92,8 +92,8 @@ | |||
92 | 92 | ||
93 | #define IWLAGN_CMD_FIFO_NUM 7 | 93 | #define IWLAGN_CMD_FIFO_NUM 7 |
94 | #define IWLAGN_NUM_QUEUES 20 | 94 | #define IWLAGN_NUM_QUEUES 20 |
95 | #define IWLAGN_NUM_AMPDU_QUEUES 10 | 95 | #define IWLAGN_NUM_AMPDU_QUEUES 9 |
96 | #define IWLAGN_FIRST_AMPDU_QUEUE 10 | 96 | #define IWLAGN_FIRST_AMPDU_QUEUE 11 |
97 | 97 | ||
98 | /* Fixed (non-configurable) rx data from phy */ | 98 | /* Fixed (non-configurable) rx data from phy */ |
99 | 99 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 3bee0f119bc..4edb6cfc548 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c | |||
@@ -753,18 +753,6 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv, | |||
753 | return added; | 753 | return added; |
754 | } | 754 | } |
755 | 755 | ||
756 | static int iwl_fill_offch_tx(struct iwl_priv *priv, void *data, size_t maxlen) | ||
757 | { | ||
758 | struct sk_buff *skb = priv->offchan_tx_skb; | ||
759 | |||
760 | if (skb->len < maxlen) | ||
761 | maxlen = skb->len; | ||
762 | |||
763 | memcpy(data, skb->data, maxlen); | ||
764 | |||
765 | return maxlen; | ||
766 | } | ||
767 | |||
768 | int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) | 756 | int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) |
769 | { | 757 | { |
770 | struct iwl_host_cmd cmd = { | 758 | struct iwl_host_cmd cmd = { |
@@ -807,7 +795,7 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
807 | scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH; | 795 | scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH; |
808 | scan->quiet_time = IWL_ACTIVE_QUIET_TIME; | 796 | scan->quiet_time = IWL_ACTIVE_QUIET_TIME; |
809 | 797 | ||
810 | if (priv->scan_type != IWL_SCAN_OFFCH_TX && | 798 | if (priv->scan_type != IWL_SCAN_ROC && |
811 | iwl_is_any_associated(priv)) { | 799 | iwl_is_any_associated(priv)) { |
812 | u16 interval = 0; | 800 | u16 interval = 0; |
813 | u32 extra; | 801 | u32 extra; |
@@ -816,7 +804,7 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
816 | 804 | ||
817 | IWL_DEBUG_INFO(priv, "Scanning while associated...\n"); | 805 | IWL_DEBUG_INFO(priv, "Scanning while associated...\n"); |
818 | switch (priv->scan_type) { | 806 | switch (priv->scan_type) { |
819 | case IWL_SCAN_OFFCH_TX: | 807 | case IWL_SCAN_ROC: |
820 | WARN_ON(1); | 808 | WARN_ON(1); |
821 | break; | 809 | break; |
822 | case IWL_SCAN_RADIO_RESET: | 810 | case IWL_SCAN_RADIO_RESET: |
@@ -838,10 +826,11 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
838 | scan->suspend_time = cpu_to_le32(scan_suspend_time); | 826 | scan->suspend_time = cpu_to_le32(scan_suspend_time); |
839 | IWL_DEBUG_SCAN(priv, "suspend_time 0x%X beacon interval %d\n", | 827 | IWL_DEBUG_SCAN(priv, "suspend_time 0x%X beacon interval %d\n", |
840 | scan_suspend_time, interval); | 828 | scan_suspend_time, interval); |
841 | } else if (priv->scan_type == IWL_SCAN_OFFCH_TX) { | 829 | } else if (priv->scan_type == IWL_SCAN_ROC) { |
842 | scan->suspend_time = 0; | 830 | scan->suspend_time = 0; |
843 | scan->max_out_time = | 831 | scan->max_out_time = 0; |
844 | cpu_to_le32(1024 * priv->offchan_tx_timeout); | 832 | scan->quiet_time = 0; |
833 | scan->quiet_plcp_th = 0; | ||
845 | } | 834 | } |
846 | 835 | ||
847 | switch (priv->scan_type) { | 836 | switch (priv->scan_type) { |
@@ -869,8 +858,8 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
869 | } else | 858 | } else |
870 | IWL_DEBUG_SCAN(priv, "Start passive scan.\n"); | 859 | IWL_DEBUG_SCAN(priv, "Start passive scan.\n"); |
871 | break; | 860 | break; |
872 | case IWL_SCAN_OFFCH_TX: | 861 | case IWL_SCAN_ROC: |
873 | IWL_DEBUG_SCAN(priv, "Start offchannel TX scan.\n"); | 862 | IWL_DEBUG_SCAN(priv, "Start ROC scan.\n"); |
874 | break; | 863 | break; |
875 | } | 864 | } |
876 | 865 | ||
@@ -988,19 +977,13 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
988 | IWL_MAX_SCAN_SIZE - sizeof(*scan)); | 977 | IWL_MAX_SCAN_SIZE - sizeof(*scan)); |
989 | break; | 978 | break; |
990 | case IWL_SCAN_RADIO_RESET: | 979 | case IWL_SCAN_RADIO_RESET: |
980 | case IWL_SCAN_ROC: | ||
991 | /* use bcast addr, will not be transmitted but must be valid */ | 981 | /* use bcast addr, will not be transmitted but must be valid */ |
992 | cmd_len = iwl_fill_probe_req(priv, | 982 | cmd_len = iwl_fill_probe_req(priv, |
993 | (struct ieee80211_mgmt *)scan->data, | 983 | (struct ieee80211_mgmt *)scan->data, |
994 | iwl_bcast_addr, NULL, 0, | 984 | iwl_bcast_addr, NULL, 0, |
995 | IWL_MAX_SCAN_SIZE - sizeof(*scan)); | 985 | IWL_MAX_SCAN_SIZE - sizeof(*scan)); |
996 | break; | 986 | break; |
997 | case IWL_SCAN_OFFCH_TX: | ||
998 | cmd_len = iwl_fill_offch_tx(priv, scan->data, | ||
999 | IWL_MAX_SCAN_SIZE | ||
1000 | - sizeof(*scan) | ||
1001 | - sizeof(struct iwl_scan_channel)); | ||
1002 | scan->scan_flags |= IWL_SCAN_FLAGS_ACTION_FRAME_TX; | ||
1003 | break; | ||
1004 | default: | 987 | default: |
1005 | BUG(); | 988 | BUG(); |
1006 | } | 989 | } |
@@ -1021,18 +1004,18 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
1021 | is_active, n_probes, | 1004 | is_active, n_probes, |
1022 | (void *)&scan->data[cmd_len]); | 1005 | (void *)&scan->data[cmd_len]); |
1023 | break; | 1006 | break; |
1024 | case IWL_SCAN_OFFCH_TX: { | 1007 | case IWL_SCAN_ROC: { |
1025 | struct iwl_scan_channel *scan_ch; | 1008 | struct iwl_scan_channel *scan_ch; |
1026 | 1009 | ||
1027 | scan->channel_count = 1; | 1010 | scan->channel_count = 1; |
1028 | 1011 | ||
1029 | scan_ch = (void *)&scan->data[cmd_len]; | 1012 | scan_ch = (void *)&scan->data[cmd_len]; |
1030 | scan_ch->type = SCAN_CHANNEL_TYPE_ACTIVE; | 1013 | scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE; |
1031 | scan_ch->channel = | 1014 | scan_ch->channel = |
1032 | cpu_to_le16(priv->offchan_tx_chan->hw_value); | 1015 | cpu_to_le16(priv->hw_roc_channel->hw_value); |
1033 | scan_ch->active_dwell = | 1016 | scan_ch->active_dwell = |
1034 | cpu_to_le16(priv->offchan_tx_timeout); | 1017 | scan_ch->passive_dwell = |
1035 | scan_ch->passive_dwell = 0; | 1018 | cpu_to_le16(priv->hw_roc_duration); |
1036 | 1019 | ||
1037 | /* Set txpower levels to defaults */ | 1020 | /* Set txpower levels to defaults */ |
1038 | scan_ch->dsp_atten = 110; | 1021 | scan_ch->dsp_atten = 110; |
@@ -1041,7 +1024,7 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
1041 | * power level: | 1024 | * power level: |
1042 | * scan_ch->tx_gain = ((1 << 5) | (2 << 3)) | 3; | 1025 | * scan_ch->tx_gain = ((1 << 5) | (2 << 3)) | 3; |
1043 | */ | 1026 | */ |
1044 | if (priv->offchan_tx_chan->band == IEEE80211_BAND_5GHZ) | 1027 | if (priv->hw_roc_channel->band == IEEE80211_BAND_5GHZ) |
1045 | scan_ch->tx_gain = ((1 << 5) | (3 << 3)) | 3; | 1028 | scan_ch->tx_gain = ((1 << 5) | (3 << 3)) | 3; |
1046 | else | 1029 | else |
1047 | scan_ch->tx_gain = ((1 << 5) | (5 << 3)); | 1030 | scan_ch->tx_gain = ((1 << 5) | (5 << 3)); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index 3789ff4bf53..1fa438e20f0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c | |||
@@ -27,7 +27,6 @@ | |||
27 | #include <linux/init.h> | 27 | #include <linux/init.h> |
28 | #include <linux/skbuff.h> | 28 | #include <linux/skbuff.h> |
29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
30 | #include <linux/wireless.h> | ||
31 | #include <net/mac80211.h> | 30 | #include <net/mac80211.h> |
32 | 31 | ||
33 | #include <linux/netdevice.h> | 32 | #include <linux/netdevice.h> |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index d42ef1763a7..d562e9359d9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | |||
@@ -337,10 +337,10 @@ int iwlagn_set_pan_params(struct iwl_priv *priv) | |||
337 | cmd.slots[0].type = 0; /* BSS */ | 337 | cmd.slots[0].type = 0; /* BSS */ |
338 | cmd.slots[1].type = 1; /* PAN */ | 338 | cmd.slots[1].type = 1; /* PAN */ |
339 | 339 | ||
340 | if (priv->hw_roc_channel) { | 340 | if (priv->hw_roc_setup) { |
341 | /* both contexts must be used for this to happen */ | 341 | /* both contexts must be used for this to happen */ |
342 | slot1 = priv->hw_roc_duration; | 342 | slot1 = IWL_MIN_SLOT_TIME; |
343 | slot0 = IWL_MIN_SLOT_TIME; | 343 | slot0 = 3000; |
344 | } else if (ctx_bss->vif && ctx_pan->vif) { | 344 | } else if (ctx_bss->vif && ctx_pan->vif) { |
345 | int bcnint = ctx_pan->beacon_int; | 345 | int bcnint = ctx_pan->beacon_int; |
346 | int dtim = ctx_pan->vif->bss_conf.dtim_period ?: 1; | 346 | int dtim = ctx_pan->vif->bss_conf.dtim_period ?: 1; |
@@ -437,23 +437,6 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | |||
437 | /* always get timestamp with Rx frame */ | 437 | /* always get timestamp with Rx frame */ |
438 | ctx->staging.flags |= RXON_FLG_TSF2HOST_MSK; | 438 | ctx->staging.flags |= RXON_FLG_TSF2HOST_MSK; |
439 | 439 | ||
440 | if (ctx->ctxid == IWL_RXON_CTX_PAN && priv->hw_roc_channel) { | ||
441 | struct ieee80211_channel *chan = priv->hw_roc_channel; | ||
442 | |||
443 | iwl_set_rxon_channel(priv, chan, ctx); | ||
444 | iwl_set_flags_for_band(priv, ctx, chan->band, NULL); | ||
445 | ctx->staging.filter_flags |= | ||
446 | RXON_FILTER_ASSOC_MSK | | ||
447 | RXON_FILTER_PROMISC_MSK | | ||
448 | RXON_FILTER_CTL2HOST_MSK; | ||
449 | ctx->staging.dev_type = RXON_DEV_TYPE_P2P; | ||
450 | new_assoc = true; | ||
451 | |||
452 | if (memcmp(&ctx->staging, &ctx->active, | ||
453 | sizeof(ctx->staging)) == 0) | ||
454 | return 0; | ||
455 | } | ||
456 | |||
457 | /* | 440 | /* |
458 | * force CTS-to-self frames protection if RTS-CTS is not preferred | 441 | * force CTS-to-self frames protection if RTS-CTS is not preferred |
459 | * one aggregation protection method | 442 | * one aggregation protection method |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index 53bb59ee719..9bc26da6276 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c | |||
@@ -128,11 +128,10 @@ static void iwlagn_tx_cmd_protection(struct iwl_priv *priv, | |||
128 | * handle build REPLY_TX command notification. | 128 | * handle build REPLY_TX command notification. |
129 | */ | 129 | */ |
130 | static void iwlagn_tx_cmd_build_basic(struct iwl_priv *priv, | 130 | static void iwlagn_tx_cmd_build_basic(struct iwl_priv *priv, |
131 | struct sk_buff *skb, | 131 | struct sk_buff *skb, |
132 | struct iwl_tx_cmd *tx_cmd, | 132 | struct iwl_tx_cmd *tx_cmd, |
133 | struct ieee80211_tx_info *info, | 133 | struct ieee80211_tx_info *info, |
134 | struct ieee80211_hdr *hdr, | 134 | struct ieee80211_hdr *hdr, u8 sta_id) |
135 | u8 std_id) | ||
136 | { | 135 | { |
137 | __le16 fc = hdr->frame_control; | 136 | __le16 fc = hdr->frame_control; |
138 | __le32 tx_flags = tx_cmd->tx_flags; | 137 | __le32 tx_flags = tx_cmd->tx_flags; |
@@ -157,7 +156,7 @@ static void iwlagn_tx_cmd_build_basic(struct iwl_priv *priv, | |||
157 | tx_flags |= TX_CMD_FLG_IGNORE_BT; | 156 | tx_flags |= TX_CMD_FLG_IGNORE_BT; |
158 | 157 | ||
159 | 158 | ||
160 | tx_cmd->sta_id = std_id; | 159 | tx_cmd->sta_id = sta_id; |
161 | if (ieee80211_has_morefrags(fc)) | 160 | if (ieee80211_has_morefrags(fc)) |
162 | tx_flags |= TX_CMD_FLG_MORE_FRAG_MSK; | 161 | tx_flags |= TX_CMD_FLG_MORE_FRAG_MSK; |
163 | 162 | ||
@@ -189,9 +188,9 @@ static void iwlagn_tx_cmd_build_basic(struct iwl_priv *priv, | |||
189 | #define RTS_DFAULT_RETRY_LIMIT 60 | 188 | #define RTS_DFAULT_RETRY_LIMIT 60 |
190 | 189 | ||
191 | static void iwlagn_tx_cmd_build_rate(struct iwl_priv *priv, | 190 | static void iwlagn_tx_cmd_build_rate(struct iwl_priv *priv, |
192 | struct iwl_tx_cmd *tx_cmd, | 191 | struct iwl_tx_cmd *tx_cmd, |
193 | struct ieee80211_tx_info *info, | 192 | struct ieee80211_tx_info *info, |
194 | __le16 fc) | 193 | __le16 fc) |
195 | { | 194 | { |
196 | u32 rate_flags; | 195 | u32 rate_flags; |
197 | int rate_idx; | 196 | int rate_idx; |
@@ -334,14 +333,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
334 | unsigned long flags; | 333 | unsigned long flags; |
335 | bool is_agg = false; | 334 | bool is_agg = false; |
336 | 335 | ||
337 | /* | 336 | if (info->control.vif) |
338 | * If the frame needs to go out off-channel, then | ||
339 | * we'll have put the PAN context to that channel, | ||
340 | * so make the frame go out there. | ||
341 | */ | ||
342 | if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) | ||
343 | ctx = &priv->contexts[IWL_RXON_CTX_PAN]; | ||
344 | else if (info->control.vif) | ||
345 | ctx = iwl_rxon_ctx_from_vif(info->control.vif); | 337 | ctx = iwl_rxon_ctx_from_vif(info->control.vif); |
346 | 338 | ||
347 | spin_lock_irqsave(&priv->lock, flags); | 339 | spin_lock_irqsave(&priv->lock, flags); |
@@ -407,7 +399,9 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
407 | */ | 399 | */ |
408 | hdr->frame_control |= | 400 | hdr->frame_control |= |
409 | cpu_to_le16(IEEE80211_FCTL_MOREDATA); | 401 | cpu_to_le16(IEEE80211_FCTL_MOREDATA); |
410 | } else | 402 | } else if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) |
403 | txq_id = IWL_AUX_QUEUE; | ||
404 | else | ||
411 | txq_id = ctx->ac_to_queue[skb_get_queue_mapping(skb)]; | 405 | txq_id = ctx->ac_to_queue[skb_get_queue_mapping(skb)]; |
412 | 406 | ||
413 | /* irqs already disabled/saved above when locking priv->lock */ | 407 | /* irqs already disabled/saved above when locking priv->lock */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index b0ae4de7f08..33894dde1ae 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -35,7 +35,6 @@ | |||
35 | #include <linux/sched.h> | 35 | #include <linux/sched.h> |
36 | #include <linux/skbuff.h> | 36 | #include <linux/skbuff.h> |
37 | #include <linux/netdevice.h> | 37 | #include <linux/netdevice.h> |
38 | #include <linux/wireless.h> | ||
39 | #include <linux/firmware.h> | 38 | #include <linux/firmware.h> |
40 | #include <linux/etherdevice.h> | 39 | #include <linux/etherdevice.h> |
41 | #include <linux/if_arp.h> | 40 | #include <linux/if_arp.h> |
@@ -614,6 +613,87 @@ static int iwl_alloc_fw_desc(struct iwl_priv *priv, struct fw_desc *desc, | |||
614 | return 0; | 613 | return 0; |
615 | } | 614 | } |
616 | 615 | ||
616 | static void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags) | ||
617 | { | ||
618 | static const u8 iwlagn_bss_ac_to_fifo[] = { | ||
619 | IWL_TX_FIFO_VO, | ||
620 | IWL_TX_FIFO_VI, | ||
621 | IWL_TX_FIFO_BE, | ||
622 | IWL_TX_FIFO_BK, | ||
623 | }; | ||
624 | static const u8 iwlagn_bss_ac_to_queue[] = { | ||
625 | 0, 1, 2, 3, | ||
626 | }; | ||
627 | static const u8 iwlagn_pan_ac_to_fifo[] = { | ||
628 | IWL_TX_FIFO_VO_IPAN, | ||
629 | IWL_TX_FIFO_VI_IPAN, | ||
630 | IWL_TX_FIFO_BE_IPAN, | ||
631 | IWL_TX_FIFO_BK_IPAN, | ||
632 | }; | ||
633 | static const u8 iwlagn_pan_ac_to_queue[] = { | ||
634 | 7, 6, 5, 4, | ||
635 | }; | ||
636 | int i; | ||
637 | |||
638 | /* | ||
639 | * The default context is always valid, | ||
640 | * the PAN context depends on uCode. | ||
641 | */ | ||
642 | priv->valid_contexts = BIT(IWL_RXON_CTX_BSS); | ||
643 | if (ucode_flags & IWL_UCODE_TLV_FLAGS_PAN) | ||
644 | priv->valid_contexts |= BIT(IWL_RXON_CTX_PAN); | ||
645 | |||
646 | for (i = 0; i < NUM_IWL_RXON_CTX; i++) | ||
647 | priv->contexts[i].ctxid = i; | ||
648 | |||
649 | priv->contexts[IWL_RXON_CTX_BSS].always_active = true; | ||
650 | priv->contexts[IWL_RXON_CTX_BSS].is_active = true; | ||
651 | priv->contexts[IWL_RXON_CTX_BSS].rxon_cmd = REPLY_RXON; | ||
652 | priv->contexts[IWL_RXON_CTX_BSS].rxon_timing_cmd = REPLY_RXON_TIMING; | ||
653 | priv->contexts[IWL_RXON_CTX_BSS].rxon_assoc_cmd = REPLY_RXON_ASSOC; | ||
654 | priv->contexts[IWL_RXON_CTX_BSS].qos_cmd = REPLY_QOS_PARAM; | ||
655 | priv->contexts[IWL_RXON_CTX_BSS].ap_sta_id = IWL_AP_ID; | ||
656 | priv->contexts[IWL_RXON_CTX_BSS].wep_key_cmd = REPLY_WEPKEY; | ||
657 | priv->contexts[IWL_RXON_CTX_BSS].ac_to_fifo = iwlagn_bss_ac_to_fifo; | ||
658 | priv->contexts[IWL_RXON_CTX_BSS].ac_to_queue = iwlagn_bss_ac_to_queue; | ||
659 | priv->contexts[IWL_RXON_CTX_BSS].exclusive_interface_modes = | ||
660 | BIT(NL80211_IFTYPE_ADHOC); | ||
661 | priv->contexts[IWL_RXON_CTX_BSS].interface_modes = | ||
662 | BIT(NL80211_IFTYPE_STATION); | ||
663 | priv->contexts[IWL_RXON_CTX_BSS].ap_devtype = RXON_DEV_TYPE_AP; | ||
664 | priv->contexts[IWL_RXON_CTX_BSS].ibss_devtype = RXON_DEV_TYPE_IBSS; | ||
665 | priv->contexts[IWL_RXON_CTX_BSS].station_devtype = RXON_DEV_TYPE_ESS; | ||
666 | priv->contexts[IWL_RXON_CTX_BSS].unused_devtype = RXON_DEV_TYPE_ESS; | ||
667 | |||
668 | priv->contexts[IWL_RXON_CTX_PAN].rxon_cmd = REPLY_WIPAN_RXON; | ||
669 | priv->contexts[IWL_RXON_CTX_PAN].rxon_timing_cmd = | ||
670 | REPLY_WIPAN_RXON_TIMING; | ||
671 | priv->contexts[IWL_RXON_CTX_PAN].rxon_assoc_cmd = | ||
672 | REPLY_WIPAN_RXON_ASSOC; | ||
673 | priv->contexts[IWL_RXON_CTX_PAN].qos_cmd = REPLY_WIPAN_QOS_PARAM; | ||
674 | priv->contexts[IWL_RXON_CTX_PAN].ap_sta_id = IWL_AP_ID_PAN; | ||
675 | priv->contexts[IWL_RXON_CTX_PAN].wep_key_cmd = REPLY_WIPAN_WEPKEY; | ||
676 | priv->contexts[IWL_RXON_CTX_PAN].bcast_sta_id = IWLAGN_PAN_BCAST_ID; | ||
677 | priv->contexts[IWL_RXON_CTX_PAN].station_flags = STA_FLG_PAN_STATION; | ||
678 | priv->contexts[IWL_RXON_CTX_PAN].ac_to_fifo = iwlagn_pan_ac_to_fifo; | ||
679 | priv->contexts[IWL_RXON_CTX_PAN].ac_to_queue = iwlagn_pan_ac_to_queue; | ||
680 | priv->contexts[IWL_RXON_CTX_PAN].mcast_queue = IWL_IPAN_MCAST_QUEUE; | ||
681 | priv->contexts[IWL_RXON_CTX_PAN].interface_modes = | ||
682 | BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP); | ||
683 | |||
684 | if (ucode_flags & IWL_UCODE_TLV_FLAGS_P2P) | ||
685 | priv->contexts[IWL_RXON_CTX_PAN].interface_modes |= | ||
686 | BIT(NL80211_IFTYPE_P2P_CLIENT) | | ||
687 | BIT(NL80211_IFTYPE_P2P_GO); | ||
688 | |||
689 | priv->contexts[IWL_RXON_CTX_PAN].ap_devtype = RXON_DEV_TYPE_CP; | ||
690 | priv->contexts[IWL_RXON_CTX_PAN].station_devtype = RXON_DEV_TYPE_2STA; | ||
691 | priv->contexts[IWL_RXON_CTX_PAN].unused_devtype = RXON_DEV_TYPE_P2P; | ||
692 | |||
693 | BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2); | ||
694 | } | ||
695 | |||
696 | |||
617 | struct iwlagn_ucode_capabilities { | 697 | struct iwlagn_ucode_capabilities { |
618 | u32 max_probe_length; | 698 | u32 max_probe_length; |
619 | u32 standard_phy_calibration_size; | 699 | u32 standard_phy_calibration_size; |
@@ -952,6 +1032,7 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) | |||
952 | int err; | 1032 | int err; |
953 | struct iwlagn_firmware_pieces pieces; | 1033 | struct iwlagn_firmware_pieces pieces; |
954 | const unsigned int api_max = priv->cfg->ucode_api_max; | 1034 | const unsigned int api_max = priv->cfg->ucode_api_max; |
1035 | unsigned int api_ok = priv->cfg->ucode_api_ok; | ||
955 | const unsigned int api_min = priv->cfg->ucode_api_min; | 1036 | const unsigned int api_min = priv->cfg->ucode_api_min; |
956 | u32 api_ver; | 1037 | u32 api_ver; |
957 | char buildstr[25]; | 1038 | char buildstr[25]; |
@@ -962,10 +1043,13 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) | |||
962 | IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE, | 1043 | IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE, |
963 | }; | 1044 | }; |
964 | 1045 | ||
1046 | if (!api_ok) | ||
1047 | api_ok = api_max; | ||
1048 | |||
965 | memset(&pieces, 0, sizeof(pieces)); | 1049 | memset(&pieces, 0, sizeof(pieces)); |
966 | 1050 | ||
967 | if (!ucode_raw) { | 1051 | if (!ucode_raw) { |
968 | if (priv->fw_index <= priv->cfg->ucode_api_max) | 1052 | if (priv->fw_index <= api_ok) |
969 | IWL_ERR(priv, | 1053 | IWL_ERR(priv, |
970 | "request for firmware file '%s' failed.\n", | 1054 | "request for firmware file '%s' failed.\n", |
971 | priv->firmware_name); | 1055 | priv->firmware_name); |
@@ -1011,12 +1095,18 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) | |||
1011 | goto try_again; | 1095 | goto try_again; |
1012 | } | 1096 | } |
1013 | 1097 | ||
1014 | if (api_ver != api_max) | 1098 | if (api_ver < api_ok) { |
1015 | IWL_ERR(priv, | 1099 | if (api_ok != api_max) |
1016 | "Firmware has old API version. Expected v%u, " | 1100 | IWL_ERR(priv, "Firmware has old API version, " |
1017 | "got v%u. New firmware can be obtained " | 1101 | "expected v%u through v%u, got v%u.\n", |
1018 | "from http://www.intellinuxwireless.org.\n", | 1102 | api_ok, api_max, api_ver); |
1019 | api_max, api_ver); | 1103 | else |
1104 | IWL_ERR(priv, "Firmware has old API version, " | ||
1105 | "expected v%u, got v%u.\n", | ||
1106 | api_max, api_ver); | ||
1107 | IWL_ERR(priv, "New firmware can be obtained from " | ||
1108 | "http://www.intellinuxwireless.org/.\n"); | ||
1109 | } | ||
1020 | } | 1110 | } |
1021 | 1111 | ||
1022 | if (build) | 1112 | if (build) |
@@ -1143,17 +1233,23 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) | |||
1143 | priv->new_scan_threshold_behaviour = | 1233 | priv->new_scan_threshold_behaviour = |
1144 | !!(ucode_capa.flags & IWL_UCODE_TLV_FLAGS_NEWSCAN); | 1234 | !!(ucode_capa.flags & IWL_UCODE_TLV_FLAGS_NEWSCAN); |
1145 | 1235 | ||
1146 | if ((priv->cfg->sku & EEPROM_SKU_CAP_IPAN_ENABLE) && | 1236 | if (!(priv->cfg->sku & EEPROM_SKU_CAP_IPAN_ENABLE)) |
1147 | (ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PAN)) { | 1237 | ucode_capa.flags &= ~IWL_UCODE_TLV_FLAGS_PAN; |
1148 | priv->valid_contexts |= BIT(IWL_RXON_CTX_PAN); | ||
1149 | priv->sta_key_max_num = STA_KEY_MAX_NUM_PAN; | ||
1150 | } else | ||
1151 | priv->sta_key_max_num = STA_KEY_MAX_NUM; | ||
1152 | 1238 | ||
1153 | if (priv->valid_contexts != BIT(IWL_RXON_CTX_BSS)) | 1239 | /* |
1240 | * if not PAN, then don't support P2P -- might be a uCode | ||
1241 | * packaging bug or due to the eeprom check above | ||
1242 | */ | ||
1243 | if (!(ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PAN)) | ||
1244 | ucode_capa.flags &= ~IWL_UCODE_TLV_FLAGS_P2P; | ||
1245 | |||
1246 | if (ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PAN) { | ||
1247 | priv->sta_key_max_num = STA_KEY_MAX_NUM_PAN; | ||
1154 | priv->cmd_queue = IWL_IPAN_CMD_QUEUE_NUM; | 1248 | priv->cmd_queue = IWL_IPAN_CMD_QUEUE_NUM; |
1155 | else | 1249 | } else { |
1250 | priv->sta_key_max_num = STA_KEY_MAX_NUM; | ||
1156 | priv->cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM; | 1251 | priv->cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM; |
1252 | } | ||
1157 | 1253 | ||
1158 | /* | 1254 | /* |
1159 | * figure out the offset of chain noise reset and gain commands | 1255 | * figure out the offset of chain noise reset and gain commands |
@@ -1169,6 +1265,9 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) | |||
1169 | priv->phy_calib_chain_noise_gain_cmd = | 1265 | priv->phy_calib_chain_noise_gain_cmd = |
1170 | ucode_capa.standard_phy_calibration_size + 1; | 1266 | ucode_capa.standard_phy_calibration_size + 1; |
1171 | 1267 | ||
1268 | /* initialize all valid contexts */ | ||
1269 | iwl_init_context(priv, ucode_capa.flags); | ||
1270 | |||
1172 | /************************************************** | 1271 | /************************************************** |
1173 | * This is still part of probe() in a sense... | 1272 | * This is still part of probe() in a sense... |
1174 | * | 1273 | * |
@@ -1765,6 +1864,13 @@ static void __iwl_down(struct iwl_priv *priv) | |||
1765 | 1864 | ||
1766 | iwl_scan_cancel_timeout(priv, 200); | 1865 | iwl_scan_cancel_timeout(priv, 200); |
1767 | 1866 | ||
1867 | /* | ||
1868 | * If active, scanning won't cancel it, so say it expired. | ||
1869 | * No race since we hold the mutex here and a new one | ||
1870 | * can't come in at this time. | ||
1871 | */ | ||
1872 | ieee80211_remain_on_channel_expired(priv->hw); | ||
1873 | |||
1768 | exit_pending = test_and_set_bit(STATUS_EXIT_PENDING, &priv->status); | 1874 | exit_pending = test_and_set_bit(STATUS_EXIT_PENDING, &priv->status); |
1769 | 1875 | ||
1770 | /* Stop TX queues watchdog. We need to have STATUS_EXIT_PENDING bit set | 1876 | /* Stop TX queues watchdog. We need to have STATUS_EXIT_PENDING bit set |
@@ -1955,94 +2061,6 @@ static void iwl_bg_restart(struct work_struct *data) | |||
1955 | } | 2061 | } |
1956 | } | 2062 | } |
1957 | 2063 | ||
1958 | static int iwl_mac_offchannel_tx(struct ieee80211_hw *hw, struct sk_buff *skb, | ||
1959 | struct ieee80211_channel *chan, | ||
1960 | enum nl80211_channel_type channel_type, | ||
1961 | unsigned int wait) | ||
1962 | { | ||
1963 | struct iwl_priv *priv = hw->priv; | ||
1964 | int ret; | ||
1965 | |||
1966 | /* Not supported if we don't have PAN */ | ||
1967 | if (!(priv->valid_contexts & BIT(IWL_RXON_CTX_PAN))) { | ||
1968 | ret = -EOPNOTSUPP; | ||
1969 | goto free; | ||
1970 | } | ||
1971 | |||
1972 | /* Not supported on pre-P2P firmware */ | ||
1973 | if (!(priv->contexts[IWL_RXON_CTX_PAN].interface_modes & | ||
1974 | BIT(NL80211_IFTYPE_P2P_CLIENT))) { | ||
1975 | ret = -EOPNOTSUPP; | ||
1976 | goto free; | ||
1977 | } | ||
1978 | |||
1979 | mutex_lock(&priv->mutex); | ||
1980 | |||
1981 | if (!priv->contexts[IWL_RXON_CTX_PAN].is_active) { | ||
1982 | /* | ||
1983 | * If the PAN context is free, use the normal | ||
1984 | * way of doing remain-on-channel offload + TX. | ||
1985 | */ | ||
1986 | ret = 1; | ||
1987 | goto out; | ||
1988 | } | ||
1989 | |||
1990 | /* TODO: queue up if scanning? */ | ||
1991 | if (test_bit(STATUS_SCANNING, &priv->status) || | ||
1992 | priv->offchan_tx_skb) { | ||
1993 | ret = -EBUSY; | ||
1994 | goto out; | ||
1995 | } | ||
1996 | |||
1997 | /* | ||
1998 | * max_scan_ie_len doesn't include the blank SSID or the header, | ||
1999 | * so need to add that again here. | ||
2000 | */ | ||
2001 | if (skb->len > hw->wiphy->max_scan_ie_len + 24 + 2) { | ||
2002 | ret = -ENOBUFS; | ||
2003 | goto out; | ||
2004 | } | ||
2005 | |||
2006 | priv->offchan_tx_skb = skb; | ||
2007 | priv->offchan_tx_timeout = wait; | ||
2008 | priv->offchan_tx_chan = chan; | ||
2009 | |||
2010 | ret = iwl_scan_initiate(priv, priv->contexts[IWL_RXON_CTX_PAN].vif, | ||
2011 | IWL_SCAN_OFFCH_TX, chan->band); | ||
2012 | if (ret) | ||
2013 | priv->offchan_tx_skb = NULL; | ||
2014 | out: | ||
2015 | mutex_unlock(&priv->mutex); | ||
2016 | free: | ||
2017 | if (ret < 0) | ||
2018 | kfree_skb(skb); | ||
2019 | |||
2020 | return ret; | ||
2021 | } | ||
2022 | |||
2023 | static int iwl_mac_offchannel_tx_cancel_wait(struct ieee80211_hw *hw) | ||
2024 | { | ||
2025 | struct iwl_priv *priv = hw->priv; | ||
2026 | int ret; | ||
2027 | |||
2028 | mutex_lock(&priv->mutex); | ||
2029 | |||
2030 | if (!priv->offchan_tx_skb) { | ||
2031 | ret = -EINVAL; | ||
2032 | goto unlock; | ||
2033 | } | ||
2034 | |||
2035 | priv->offchan_tx_skb = NULL; | ||
2036 | |||
2037 | ret = iwl_scan_cancel_timeout(priv, 200); | ||
2038 | if (ret) | ||
2039 | ret = -EIO; | ||
2040 | unlock: | ||
2041 | mutex_unlock(&priv->mutex); | ||
2042 | |||
2043 | return ret; | ||
2044 | } | ||
2045 | |||
2046 | /***************************************************************************** | 2064 | /***************************************************************************** |
2047 | * | 2065 | * |
2048 | * mac80211 entry point functions | 2066 | * mac80211 entry point functions |
@@ -3198,35 +3216,34 @@ done: | |||
3198 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 3216 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
3199 | } | 3217 | } |
3200 | 3218 | ||
3201 | static void iwlagn_disable_roc(struct iwl_priv *priv) | 3219 | void iwlagn_disable_roc(struct iwl_priv *priv) |
3202 | { | 3220 | { |
3203 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_PAN]; | 3221 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_PAN]; |
3204 | struct ieee80211_channel *chan = ACCESS_ONCE(priv->hw->conf.channel); | ||
3205 | 3222 | ||
3206 | lockdep_assert_held(&priv->mutex); | 3223 | lockdep_assert_held(&priv->mutex); |
3207 | 3224 | ||
3208 | if (!ctx->is_active) | 3225 | if (!priv->hw_roc_setup) |
3209 | return; | 3226 | return; |
3210 | 3227 | ||
3211 | ctx->staging.dev_type = RXON_DEV_TYPE_2STA; | 3228 | ctx->staging.dev_type = RXON_DEV_TYPE_P2P; |
3212 | ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; | 3229 | ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; |
3213 | iwl_set_rxon_channel(priv, chan, ctx); | ||
3214 | iwl_set_flags_for_band(priv, ctx, chan->band, NULL); | ||
3215 | 3230 | ||
3216 | priv->hw_roc_channel = NULL; | 3231 | priv->hw_roc_channel = NULL; |
3217 | 3232 | ||
3233 | memset(ctx->staging.node_addr, 0, ETH_ALEN); | ||
3234 | |||
3218 | iwlagn_commit_rxon(priv, ctx); | 3235 | iwlagn_commit_rxon(priv, ctx); |
3219 | 3236 | ||
3220 | ctx->is_active = false; | 3237 | ctx->is_active = false; |
3238 | priv->hw_roc_setup = false; | ||
3221 | } | 3239 | } |
3222 | 3240 | ||
3223 | static void iwlagn_bg_roc_done(struct work_struct *work) | 3241 | static void iwlagn_disable_roc_work(struct work_struct *work) |
3224 | { | 3242 | { |
3225 | struct iwl_priv *priv = container_of(work, struct iwl_priv, | 3243 | struct iwl_priv *priv = container_of(work, struct iwl_priv, |
3226 | hw_roc_work.work); | 3244 | hw_roc_disable_work.work); |
3227 | 3245 | ||
3228 | mutex_lock(&priv->mutex); | 3246 | mutex_lock(&priv->mutex); |
3229 | ieee80211_remain_on_channel_expired(priv->hw); | ||
3230 | iwlagn_disable_roc(priv); | 3247 | iwlagn_disable_roc(priv); |
3231 | mutex_unlock(&priv->mutex); | 3248 | mutex_unlock(&priv->mutex); |
3232 | } | 3249 | } |
@@ -3237,33 +3254,63 @@ static int iwl_mac_remain_on_channel(struct ieee80211_hw *hw, | |||
3237 | int duration) | 3254 | int duration) |
3238 | { | 3255 | { |
3239 | struct iwl_priv *priv = hw->priv; | 3256 | struct iwl_priv *priv = hw->priv; |
3257 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_PAN]; | ||
3240 | int err = 0; | 3258 | int err = 0; |
3241 | 3259 | ||
3242 | if (!(priv->valid_contexts & BIT(IWL_RXON_CTX_PAN))) | 3260 | if (!(priv->valid_contexts & BIT(IWL_RXON_CTX_PAN))) |
3243 | return -EOPNOTSUPP; | 3261 | return -EOPNOTSUPP; |
3244 | 3262 | ||
3245 | if (!(priv->contexts[IWL_RXON_CTX_PAN].interface_modes & | 3263 | if (!(ctx->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT))) |
3246 | BIT(NL80211_IFTYPE_P2P_CLIENT))) | ||
3247 | return -EOPNOTSUPP; | 3264 | return -EOPNOTSUPP; |
3248 | 3265 | ||
3249 | mutex_lock(&priv->mutex); | 3266 | mutex_lock(&priv->mutex); |
3250 | 3267 | ||
3251 | if (priv->contexts[IWL_RXON_CTX_PAN].is_active || | 3268 | /* |
3252 | test_bit(STATUS_SCAN_HW, &priv->status)) { | 3269 | * TODO: Remove this hack! Firmware needs to be updated |
3270 | * to allow longer off-channel periods in scanning for | ||
3271 | * this use case, based on a flag (and we'll need an API | ||
3272 | * flag in the firmware when it has that). | ||
3273 | */ | ||
3274 | if (iwl_is_associated(priv, IWL_RXON_CTX_BSS) && duration > 80) | ||
3275 | duration = 80; | ||
3276 | |||
3277 | if (test_bit(STATUS_SCAN_HW, &priv->status)) { | ||
3253 | err = -EBUSY; | 3278 | err = -EBUSY; |
3254 | goto out; | 3279 | goto out; |
3255 | } | 3280 | } |
3256 | 3281 | ||
3257 | priv->contexts[IWL_RXON_CTX_PAN].is_active = true; | ||
3258 | priv->hw_roc_channel = channel; | 3282 | priv->hw_roc_channel = channel; |
3259 | priv->hw_roc_chantype = channel_type; | 3283 | priv->hw_roc_chantype = channel_type; |
3260 | priv->hw_roc_duration = DIV_ROUND_UP(duration * 1000, 1024); | 3284 | priv->hw_roc_duration = duration; |
3261 | iwlagn_commit_rxon(priv, &priv->contexts[IWL_RXON_CTX_PAN]); | 3285 | cancel_delayed_work(&priv->hw_roc_disable_work); |
3262 | queue_delayed_work(priv->workqueue, &priv->hw_roc_work, | 3286 | |
3263 | msecs_to_jiffies(duration + 20)); | 3287 | if (!ctx->is_active) { |
3288 | ctx->is_active = true; | ||
3289 | ctx->staging.dev_type = RXON_DEV_TYPE_P2P; | ||
3290 | memcpy(ctx->staging.node_addr, | ||
3291 | priv->contexts[IWL_RXON_CTX_BSS].staging.node_addr, | ||
3292 | ETH_ALEN); | ||
3293 | memcpy(ctx->staging.bssid_addr, | ||
3294 | priv->contexts[IWL_RXON_CTX_BSS].staging.node_addr, | ||
3295 | ETH_ALEN); | ||
3296 | err = iwlagn_commit_rxon(priv, ctx); | ||
3297 | if (err) | ||
3298 | goto out; | ||
3299 | ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK | | ||
3300 | RXON_FILTER_PROMISC_MSK | | ||
3301 | RXON_FILTER_CTL2HOST_MSK; | ||
3302 | |||
3303 | err = iwlagn_commit_rxon(priv, ctx); | ||
3304 | if (err) { | ||
3305 | iwlagn_disable_roc(priv); | ||
3306 | goto out; | ||
3307 | } | ||
3308 | priv->hw_roc_setup = true; | ||
3309 | } | ||
3264 | 3310 | ||
3265 | msleep(IWL_MIN_SLOT_TIME); /* TU is almost ms */ | 3311 | err = iwl_scan_initiate(priv, ctx->vif, IWL_SCAN_ROC, channel->band); |
3266 | ieee80211_ready_on_channel(priv->hw); | 3312 | if (err) |
3313 | iwlagn_disable_roc(priv); | ||
3267 | 3314 | ||
3268 | out: | 3315 | out: |
3269 | mutex_unlock(&priv->mutex); | 3316 | mutex_unlock(&priv->mutex); |
@@ -3278,9 +3325,8 @@ static int iwl_mac_cancel_remain_on_channel(struct ieee80211_hw *hw) | |||
3278 | if (!(priv->valid_contexts & BIT(IWL_RXON_CTX_PAN))) | 3325 | if (!(priv->valid_contexts & BIT(IWL_RXON_CTX_PAN))) |
3279 | return -EOPNOTSUPP; | 3326 | return -EOPNOTSUPP; |
3280 | 3327 | ||
3281 | cancel_delayed_work_sync(&priv->hw_roc_work); | ||
3282 | |||
3283 | mutex_lock(&priv->mutex); | 3328 | mutex_lock(&priv->mutex); |
3329 | iwl_scan_cancel_timeout(priv, priv->hw_roc_duration); | ||
3284 | iwlagn_disable_roc(priv); | 3330 | iwlagn_disable_roc(priv); |
3285 | mutex_unlock(&priv->mutex); | 3331 | mutex_unlock(&priv->mutex); |
3286 | 3332 | ||
@@ -3305,7 +3351,8 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv) | |||
3305 | INIT_WORK(&priv->tx_flush, iwl_bg_tx_flush); | 3351 | INIT_WORK(&priv->tx_flush, iwl_bg_tx_flush); |
3306 | INIT_WORK(&priv->bt_full_concurrency, iwl_bg_bt_full_concurrency); | 3352 | INIT_WORK(&priv->bt_full_concurrency, iwl_bg_bt_full_concurrency); |
3307 | INIT_WORK(&priv->bt_runtime_config, iwl_bg_bt_runtime_config); | 3353 | INIT_WORK(&priv->bt_runtime_config, iwl_bg_bt_runtime_config); |
3308 | INIT_DELAYED_WORK(&priv->hw_roc_work, iwlagn_bg_roc_done); | 3354 | INIT_DELAYED_WORK(&priv->hw_roc_disable_work, |
3355 | iwlagn_disable_roc_work); | ||
3309 | 3356 | ||
3310 | iwl_setup_scan_deferred_work(priv); | 3357 | iwl_setup_scan_deferred_work(priv); |
3311 | 3358 | ||
@@ -3337,6 +3384,7 @@ static void iwl_cancel_deferred_work(struct iwl_priv *priv) | |||
3337 | 3384 | ||
3338 | cancel_work_sync(&priv->bt_full_concurrency); | 3385 | cancel_work_sync(&priv->bt_full_concurrency); |
3339 | cancel_work_sync(&priv->bt_runtime_config); | 3386 | cancel_work_sync(&priv->bt_runtime_config); |
3387 | cancel_delayed_work_sync(&priv->hw_roc_disable_work); | ||
3340 | 3388 | ||
3341 | del_timer_sync(&priv->statistics_periodic); | 3389 | del_timer_sync(&priv->statistics_periodic); |
3342 | del_timer_sync(&priv->ucode_trace); | 3390 | del_timer_sync(&priv->ucode_trace); |
@@ -3489,8 +3537,6 @@ struct ieee80211_ops iwlagn_hw_ops = { | |||
3489 | .tx_last_beacon = iwl_mac_tx_last_beacon, | 3537 | .tx_last_beacon = iwl_mac_tx_last_beacon, |
3490 | .remain_on_channel = iwl_mac_remain_on_channel, | 3538 | .remain_on_channel = iwl_mac_remain_on_channel, |
3491 | .cancel_remain_on_channel = iwl_mac_cancel_remain_on_channel, | 3539 | .cancel_remain_on_channel = iwl_mac_cancel_remain_on_channel, |
3492 | .offchannel_tx = iwl_mac_offchannel_tx, | ||
3493 | .offchannel_tx_cancel_wait = iwl_mac_offchannel_tx_cancel_wait, | ||
3494 | .rssi_callback = iwl_mac_rssi_callback, | 3540 | .rssi_callback = iwl_mac_rssi_callback, |
3495 | CFG80211_TESTMODE_CMD(iwl_testmode_cmd) | 3541 | CFG80211_TESTMODE_CMD(iwl_testmode_cmd) |
3496 | CFG80211_TESTMODE_DUMP(iwl_testmode_dump) | 3542 | CFG80211_TESTMODE_DUMP(iwl_testmode_dump) |
@@ -3519,28 +3565,6 @@ static int iwl_set_hw_params(struct iwl_priv *priv) | |||
3519 | return priv->cfg->lib->set_hw_params(priv); | 3565 | return priv->cfg->lib->set_hw_params(priv); |
3520 | } | 3566 | } |
3521 | 3567 | ||
3522 | static const u8 iwlagn_bss_ac_to_fifo[] = { | ||
3523 | IWL_TX_FIFO_VO, | ||
3524 | IWL_TX_FIFO_VI, | ||
3525 | IWL_TX_FIFO_BE, | ||
3526 | IWL_TX_FIFO_BK, | ||
3527 | }; | ||
3528 | |||
3529 | static const u8 iwlagn_bss_ac_to_queue[] = { | ||
3530 | 0, 1, 2, 3, | ||
3531 | }; | ||
3532 | |||
3533 | static const u8 iwlagn_pan_ac_to_fifo[] = { | ||
3534 | IWL_TX_FIFO_VO_IPAN, | ||
3535 | IWL_TX_FIFO_VI_IPAN, | ||
3536 | IWL_TX_FIFO_BE_IPAN, | ||
3537 | IWL_TX_FIFO_BK_IPAN, | ||
3538 | }; | ||
3539 | |||
3540 | static const u8 iwlagn_pan_ac_to_queue[] = { | ||
3541 | 7, 6, 5, 4, | ||
3542 | }; | ||
3543 | |||
3544 | /* This function both allocates and initializes hw and priv. */ | 3568 | /* This function both allocates and initializes hw and priv. */ |
3545 | static struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg) | 3569 | static struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg) |
3546 | { | 3570 | { |
@@ -3563,65 +3587,6 @@ out: | |||
3563 | return hw; | 3587 | return hw; |
3564 | } | 3588 | } |
3565 | 3589 | ||
3566 | static void iwl_init_context(struct iwl_priv *priv) | ||
3567 | { | ||
3568 | int i; | ||
3569 | |||
3570 | /* | ||
3571 | * The default context is always valid, | ||
3572 | * more may be discovered when firmware | ||
3573 | * is loaded. | ||
3574 | */ | ||
3575 | priv->valid_contexts = BIT(IWL_RXON_CTX_BSS); | ||
3576 | |||
3577 | for (i = 0; i < NUM_IWL_RXON_CTX; i++) | ||
3578 | priv->contexts[i].ctxid = i; | ||
3579 | |||
3580 | priv->contexts[IWL_RXON_CTX_BSS].always_active = true; | ||
3581 | priv->contexts[IWL_RXON_CTX_BSS].is_active = true; | ||
3582 | priv->contexts[IWL_RXON_CTX_BSS].rxon_cmd = REPLY_RXON; | ||
3583 | priv->contexts[IWL_RXON_CTX_BSS].rxon_timing_cmd = REPLY_RXON_TIMING; | ||
3584 | priv->contexts[IWL_RXON_CTX_BSS].rxon_assoc_cmd = REPLY_RXON_ASSOC; | ||
3585 | priv->contexts[IWL_RXON_CTX_BSS].qos_cmd = REPLY_QOS_PARAM; | ||
3586 | priv->contexts[IWL_RXON_CTX_BSS].ap_sta_id = IWL_AP_ID; | ||
3587 | priv->contexts[IWL_RXON_CTX_BSS].wep_key_cmd = REPLY_WEPKEY; | ||
3588 | priv->contexts[IWL_RXON_CTX_BSS].ac_to_fifo = iwlagn_bss_ac_to_fifo; | ||
3589 | priv->contexts[IWL_RXON_CTX_BSS].ac_to_queue = iwlagn_bss_ac_to_queue; | ||
3590 | priv->contexts[IWL_RXON_CTX_BSS].exclusive_interface_modes = | ||
3591 | BIT(NL80211_IFTYPE_ADHOC); | ||
3592 | priv->contexts[IWL_RXON_CTX_BSS].interface_modes = | ||
3593 | BIT(NL80211_IFTYPE_STATION); | ||
3594 | priv->contexts[IWL_RXON_CTX_BSS].ap_devtype = RXON_DEV_TYPE_AP; | ||
3595 | priv->contexts[IWL_RXON_CTX_BSS].ibss_devtype = RXON_DEV_TYPE_IBSS; | ||
3596 | priv->contexts[IWL_RXON_CTX_BSS].station_devtype = RXON_DEV_TYPE_ESS; | ||
3597 | priv->contexts[IWL_RXON_CTX_BSS].unused_devtype = RXON_DEV_TYPE_ESS; | ||
3598 | |||
3599 | priv->contexts[IWL_RXON_CTX_PAN].rxon_cmd = REPLY_WIPAN_RXON; | ||
3600 | priv->contexts[IWL_RXON_CTX_PAN].rxon_timing_cmd = | ||
3601 | REPLY_WIPAN_RXON_TIMING; | ||
3602 | priv->contexts[IWL_RXON_CTX_PAN].rxon_assoc_cmd = | ||
3603 | REPLY_WIPAN_RXON_ASSOC; | ||
3604 | priv->contexts[IWL_RXON_CTX_PAN].qos_cmd = REPLY_WIPAN_QOS_PARAM; | ||
3605 | priv->contexts[IWL_RXON_CTX_PAN].ap_sta_id = IWL_AP_ID_PAN; | ||
3606 | priv->contexts[IWL_RXON_CTX_PAN].wep_key_cmd = REPLY_WIPAN_WEPKEY; | ||
3607 | priv->contexts[IWL_RXON_CTX_PAN].bcast_sta_id = IWLAGN_PAN_BCAST_ID; | ||
3608 | priv->contexts[IWL_RXON_CTX_PAN].station_flags = STA_FLG_PAN_STATION; | ||
3609 | priv->contexts[IWL_RXON_CTX_PAN].ac_to_fifo = iwlagn_pan_ac_to_fifo; | ||
3610 | priv->contexts[IWL_RXON_CTX_PAN].ac_to_queue = iwlagn_pan_ac_to_queue; | ||
3611 | priv->contexts[IWL_RXON_CTX_PAN].mcast_queue = IWL_IPAN_MCAST_QUEUE; | ||
3612 | priv->contexts[IWL_RXON_CTX_PAN].interface_modes = | ||
3613 | BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP); | ||
3614 | #ifdef CONFIG_IWL_P2P | ||
3615 | priv->contexts[IWL_RXON_CTX_PAN].interface_modes |= | ||
3616 | BIT(NL80211_IFTYPE_P2P_CLIENT) | BIT(NL80211_IFTYPE_P2P_GO); | ||
3617 | #endif | ||
3618 | priv->contexts[IWL_RXON_CTX_PAN].ap_devtype = RXON_DEV_TYPE_CP; | ||
3619 | priv->contexts[IWL_RXON_CTX_PAN].station_devtype = RXON_DEV_TYPE_2STA; | ||
3620 | priv->contexts[IWL_RXON_CTX_PAN].unused_devtype = RXON_DEV_TYPE_P2P; | ||
3621 | |||
3622 | BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2); | ||
3623 | } | ||
3624 | |||
3625 | int iwl_probe(struct iwl_bus *bus, struct iwl_cfg *cfg) | 3590 | int iwl_probe(struct iwl_bus *bus, struct iwl_cfg *cfg) |
3626 | { | 3591 | { |
3627 | int err = 0; | 3592 | int err = 0; |
@@ -3724,9 +3689,6 @@ int iwl_probe(struct iwl_bus *bus, struct iwl_cfg *cfg) | |||
3724 | priv->hw->wiphy->n_addresses++; | 3689 | priv->hw->wiphy->n_addresses++; |
3725 | } | 3690 | } |
3726 | 3691 | ||
3727 | /* initialize all valid contexts */ | ||
3728 | iwl_init_context(priv); | ||
3729 | |||
3730 | /************************ | 3692 | /************************ |
3731 | * 5. Setup HW constants | 3693 | * 5. Setup HW constants |
3732 | ************************/ | 3694 | ************************/ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index d941c4c98e4..df2960ae92a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h | |||
@@ -209,6 +209,7 @@ u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant_idx, u8 valid); | |||
209 | /* scan */ | 209 | /* scan */ |
210 | int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif); | 210 | int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif); |
211 | void iwlagn_post_scan(struct iwl_priv *priv); | 211 | void iwlagn_post_scan(struct iwl_priv *priv); |
212 | void iwlagn_disable_roc(struct iwl_priv *priv); | ||
212 | 213 | ||
213 | /* station mgmt */ | 214 | /* station mgmt */ |
214 | int iwlagn_manage_ibss_station(struct iwl_priv *priv, | 215 | int iwlagn_manage_ibss_station(struct iwl_priv *priv, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index e9e9d1d1778..0016c61b300 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h | |||
@@ -3067,17 +3067,29 @@ struct iwl_missed_beacon_notif { | |||
3067 | /* number of additional entries for enhanced tbl */ | 3067 | /* number of additional entries for enhanced tbl */ |
3068 | #define ENHANCE_HD_TABLE_ENTRIES (ENHANCE_HD_TABLE_SIZE - HD_TABLE_SIZE) | 3068 | #define ENHANCE_HD_TABLE_ENTRIES (ENHANCE_HD_TABLE_SIZE - HD_TABLE_SIZE) |
3069 | 3069 | ||
3070 | #define HD_INA_NON_SQUARE_DET_OFDM_DATA cpu_to_le16(0) | 3070 | #define HD_INA_NON_SQUARE_DET_OFDM_DATA_V1 cpu_to_le16(0) |
3071 | #define HD_INA_NON_SQUARE_DET_CCK_DATA cpu_to_le16(0) | 3071 | #define HD_INA_NON_SQUARE_DET_CCK_DATA_V1 cpu_to_le16(0) |
3072 | #define HD_CORR_11_INSTEAD_OF_CORR_9_EN_DATA cpu_to_le16(0) | 3072 | #define HD_CORR_11_INSTEAD_OF_CORR_9_EN_DATA_V1 cpu_to_le16(0) |
3073 | #define HD_OFDM_NON_SQUARE_DET_SLOPE_MRC_DATA cpu_to_le16(668) | 3073 | #define HD_OFDM_NON_SQUARE_DET_SLOPE_MRC_DATA_V1 cpu_to_le16(668) |
3074 | #define HD_OFDM_NON_SQUARE_DET_INTERCEPT_MRC_DATA cpu_to_le16(4) | 3074 | #define HD_OFDM_NON_SQUARE_DET_INTERCEPT_MRC_DATA_V1 cpu_to_le16(4) |
3075 | #define HD_OFDM_NON_SQUARE_DET_SLOPE_DATA cpu_to_le16(486) | 3075 | #define HD_OFDM_NON_SQUARE_DET_SLOPE_DATA_V1 cpu_to_le16(486) |
3076 | #define HD_OFDM_NON_SQUARE_DET_INTERCEPT_DATA cpu_to_le16(37) | 3076 | #define HD_OFDM_NON_SQUARE_DET_INTERCEPT_DATA_V1 cpu_to_le16(37) |
3077 | #define HD_CCK_NON_SQUARE_DET_SLOPE_MRC_DATA cpu_to_le16(853) | 3077 | #define HD_CCK_NON_SQUARE_DET_SLOPE_MRC_DATA_V1 cpu_to_le16(853) |
3078 | #define HD_CCK_NON_SQUARE_DET_INTERCEPT_MRC_DATA cpu_to_le16(4) | 3078 | #define HD_CCK_NON_SQUARE_DET_INTERCEPT_MRC_DATA_V1 cpu_to_le16(4) |
3079 | #define HD_CCK_NON_SQUARE_DET_SLOPE_DATA cpu_to_le16(476) | 3079 | #define HD_CCK_NON_SQUARE_DET_SLOPE_DATA_V1 cpu_to_le16(476) |
3080 | #define HD_CCK_NON_SQUARE_DET_INTERCEPT_DATA cpu_to_le16(99) | 3080 | #define HD_CCK_NON_SQUARE_DET_INTERCEPT_DATA_V1 cpu_to_le16(99) |
3081 | |||
3082 | #define HD_INA_NON_SQUARE_DET_OFDM_DATA_V2 cpu_to_le16(1) | ||
3083 | #define HD_INA_NON_SQUARE_DET_CCK_DATA_V2 cpu_to_le16(1) | ||
3084 | #define HD_CORR_11_INSTEAD_OF_CORR_9_EN_DATA_V2 cpu_to_le16(1) | ||
3085 | #define HD_OFDM_NON_SQUARE_DET_SLOPE_MRC_DATA_V2 cpu_to_le16(600) | ||
3086 | #define HD_OFDM_NON_SQUARE_DET_INTERCEPT_MRC_DATA_V2 cpu_to_le16(40) | ||
3087 | #define HD_OFDM_NON_SQUARE_DET_SLOPE_DATA_V2 cpu_to_le16(486) | ||
3088 | #define HD_OFDM_NON_SQUARE_DET_INTERCEPT_DATA_V2 cpu_to_le16(45) | ||
3089 | #define HD_CCK_NON_SQUARE_DET_SLOPE_MRC_DATA_V2 cpu_to_le16(853) | ||
3090 | #define HD_CCK_NON_SQUARE_DET_INTERCEPT_MRC_DATA_V2 cpu_to_le16(60) | ||
3091 | #define HD_CCK_NON_SQUARE_DET_SLOPE_DATA_V2 cpu_to_le16(476) | ||
3092 | #define HD_CCK_NON_SQUARE_DET_INTERCEPT_DATA_V2 cpu_to_le16(99) | ||
3081 | 3093 | ||
3082 | 3094 | ||
3083 | /* Control field in struct iwl_sensitivity_cmd */ | 3095 | /* Control field in struct iwl_sensitivity_cmd */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index cf376f62b2f..e269987cd64 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
@@ -40,6 +40,7 @@ | |||
40 | #include "iwl-io.h" | 40 | #include "iwl-io.h" |
41 | #include "iwl-power.h" | 41 | #include "iwl-power.h" |
42 | #include "iwl-sta.h" | 42 | #include "iwl-sta.h" |
43 | #include "iwl-agn.h" | ||
43 | #include "iwl-helpers.h" | 44 | #include "iwl-helpers.h" |
44 | #include "iwl-agn.h" | 45 | #include "iwl-agn.h" |
45 | #include "iwl-trans.h" | 46 | #include "iwl-trans.h" |
@@ -1273,8 +1274,12 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) | |||
1273 | IWL_DEBUG_MAC80211(priv, "enter: type %d, addr %pM\n", | 1274 | IWL_DEBUG_MAC80211(priv, "enter: type %d, addr %pM\n", |
1274 | viftype, vif->addr); | 1275 | viftype, vif->addr); |
1275 | 1276 | ||
1277 | cancel_delayed_work_sync(&priv->hw_roc_disable_work); | ||
1278 | |||
1276 | mutex_lock(&priv->mutex); | 1279 | mutex_lock(&priv->mutex); |
1277 | 1280 | ||
1281 | iwlagn_disable_roc(priv); | ||
1282 | |||
1278 | if (!iwl_is_ready_rf(priv)) { | 1283 | if (!iwl_is_ready_rf(priv)) { |
1279 | IWL_WARN(priv, "Try to add interface when device not ready\n"); | 1284 | IWL_WARN(priv, "Try to add interface when device not ready\n"); |
1280 | err = -EINVAL; | 1285 | err = -EINVAL; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 02817a43855..42bcb469d32 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h | |||
@@ -136,6 +136,7 @@ struct iwl_mod_params { | |||
136 | * @max_event_log_size: size of event log buffer size for ucode event logging | 136 | * @max_event_log_size: size of event log buffer size for ucode event logging |
137 | * @shadow_reg_enable: HW shadhow register bit | 137 | * @shadow_reg_enable: HW shadhow register bit |
138 | * @no_idle_support: do not support idle mode | 138 | * @no_idle_support: do not support idle mode |
139 | * @hd_v2: v2 of enhanced sensitivity value, used for 2000 series and up | ||
139 | */ | 140 | */ |
140 | struct iwl_base_params { | 141 | struct iwl_base_params { |
141 | int eeprom_size; | 142 | int eeprom_size; |
@@ -158,6 +159,7 @@ struct iwl_base_params { | |||
158 | u32 max_event_log_size; | 159 | u32 max_event_log_size; |
159 | const bool shadow_reg_enable; | 160 | const bool shadow_reg_enable; |
160 | const bool no_idle_support; | 161 | const bool no_idle_support; |
162 | const bool hd_v2; | ||
161 | }; | 163 | }; |
162 | /* | 164 | /* |
163 | * @advanced_bt_coexist: support advanced bt coexist | 165 | * @advanced_bt_coexist: support advanced bt coexist |
@@ -194,6 +196,8 @@ struct iwl_ht_params { | |||
194 | * (.ucode) will be added to filename before loading from disk. The | 196 | * (.ucode) will be added to filename before loading from disk. The |
195 | * filename is constructed as fw_name_pre<api>.ucode. | 197 | * filename is constructed as fw_name_pre<api>.ucode. |
196 | * @ucode_api_max: Highest version of uCode API supported by driver. | 198 | * @ucode_api_max: Highest version of uCode API supported by driver. |
199 | * @ucode_api_ok: oldest version of the uCode API that is OK to load | ||
200 | * without a warning, for use in transitions | ||
197 | * @ucode_api_min: Lowest version of uCode API supported by driver. | 201 | * @ucode_api_min: Lowest version of uCode API supported by driver. |
198 | * @valid_tx_ant: valid transmit antenna | 202 | * @valid_tx_ant: valid transmit antenna |
199 | * @valid_rx_ant: valid receive antenna | 203 | * @valid_rx_ant: valid receive antenna |
@@ -237,6 +241,7 @@ struct iwl_cfg { | |||
237 | const char *name; | 241 | const char *name; |
238 | const char *fw_name_pre; | 242 | const char *fw_name_pre; |
239 | const unsigned int ucode_api_max; | 243 | const unsigned int ucode_api_max; |
244 | const unsigned int ucode_api_ok; | ||
240 | const unsigned int ucode_api_min; | 245 | const unsigned int ucode_api_min; |
241 | u8 valid_tx_ant; | 246 | u8 valid_tx_ant; |
242 | u8 valid_rx_ant; | 247 | u8 valid_rx_ant; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 6c9790cac8d..dd34c7c502f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h | |||
@@ -230,12 +230,23 @@ struct iwl_channel_info { | |||
230 | #define IWL_TX_FIFO_BE_IPAN 4 | 230 | #define IWL_TX_FIFO_BE_IPAN 4 |
231 | #define IWL_TX_FIFO_VI_IPAN IWL_TX_FIFO_VI | 231 | #define IWL_TX_FIFO_VI_IPAN IWL_TX_FIFO_VI |
232 | #define IWL_TX_FIFO_VO_IPAN 5 | 232 | #define IWL_TX_FIFO_VO_IPAN 5 |
233 | /* re-uses the VO FIFO, uCode will properly flush/schedule */ | ||
234 | #define IWL_TX_FIFO_AUX 5 | ||
233 | #define IWL_TX_FIFO_UNUSED -1 | 235 | #define IWL_TX_FIFO_UNUSED -1 |
234 | 236 | ||
235 | /* Minimum number of queues. MAX_NUM is defined in hw specific files. | 237 | /* AUX (TX during scan dwell) queue */ |
236 | * Set the minimum to accommodate the 4 standard TX queues, 1 command | 238 | #define IWL_AUX_QUEUE 10 |
237 | * queue, 2 (unused) HCCA queues, and 4 HT queues (one for each AC) */ | 239 | |
238 | #define IWL_MIN_NUM_QUEUES 10 | 240 | /* |
241 | * Minimum number of queues. MAX_NUM is defined in hw specific files. | ||
242 | * Set the minimum to accommodate | ||
243 | * - 4 standard TX queues | ||
244 | * - the command queue | ||
245 | * - 4 PAN TX queues | ||
246 | * - the PAN multicast queue, and | ||
247 | * - the AUX (TX during scan dwell) queue. | ||
248 | */ | ||
249 | #define IWL_MIN_NUM_QUEUES 11 | ||
239 | 250 | ||
240 | /* | 251 | /* |
241 | * Command queue depends on iPAN support. | 252 | * Command queue depends on iPAN support. |
@@ -564,11 +575,13 @@ enum iwl_ucode_tlv_type { | |||
564 | * @IWL_UCODE_TLV_FLAGS_NEWSCAN: new uCode scan behaviour on hidden SSID, | 575 | * @IWL_UCODE_TLV_FLAGS_NEWSCAN: new uCode scan behaviour on hidden SSID, |
565 | * treats good CRC threshold as a boolean | 576 | * treats good CRC threshold as a boolean |
566 | * @IWL_UCODE_TLV_FLAGS_MFP: This uCode image supports MFP (802.11w). | 577 | * @IWL_UCODE_TLV_FLAGS_MFP: This uCode image supports MFP (802.11w). |
578 | * @IWL_UCODE_TLV_FLAGS_P2P: This uCode image supports P2P. | ||
567 | */ | 579 | */ |
568 | enum iwl_ucode_tlv_flag { | 580 | enum iwl_ucode_tlv_flag { |
569 | IWL_UCODE_TLV_FLAGS_PAN = BIT(0), | 581 | IWL_UCODE_TLV_FLAGS_PAN = BIT(0), |
570 | IWL_UCODE_TLV_FLAGS_NEWSCAN = BIT(1), | 582 | IWL_UCODE_TLV_FLAGS_NEWSCAN = BIT(1), |
571 | IWL_UCODE_TLV_FLAGS_MFP = BIT(2), | 583 | IWL_UCODE_TLV_FLAGS_MFP = BIT(2), |
584 | IWL_UCODE_TLV_FLAGS_P2P = BIT(3), | ||
572 | }; | 585 | }; |
573 | 586 | ||
574 | struct iwl_ucode_tlv { | 587 | struct iwl_ucode_tlv { |
@@ -1168,7 +1181,7 @@ struct iwl_rxon_context { | |||
1168 | enum iwl_scan_type { | 1181 | enum iwl_scan_type { |
1169 | IWL_SCAN_NORMAL, | 1182 | IWL_SCAN_NORMAL, |
1170 | IWL_SCAN_RADIO_RESET, | 1183 | IWL_SCAN_RADIO_RESET, |
1171 | IWL_SCAN_OFFCH_TX, | 1184 | IWL_SCAN_ROC, |
1172 | }; | 1185 | }; |
1173 | 1186 | ||
1174 | enum iwlagn_ucode_type { | 1187 | enum iwlagn_ucode_type { |
@@ -1438,15 +1451,11 @@ struct iwl_priv { | |||
1438 | 1451 | ||
1439 | /* remain-on-channel offload support */ | 1452 | /* remain-on-channel offload support */ |
1440 | struct ieee80211_channel *hw_roc_channel; | 1453 | struct ieee80211_channel *hw_roc_channel; |
1441 | struct delayed_work hw_roc_work; | 1454 | struct delayed_work hw_roc_disable_work; |
1442 | enum nl80211_channel_type hw_roc_chantype; | 1455 | enum nl80211_channel_type hw_roc_chantype; |
1443 | int hw_roc_duration; | 1456 | int hw_roc_duration; |
1444 | bool hw_roc_setup; | 1457 | bool hw_roc_setup; |
1445 | 1458 | ||
1446 | struct sk_buff *offchan_tx_skb; | ||
1447 | int offchan_tx_timeout; | ||
1448 | struct ieee80211_channel *offchan_tx_chan; | ||
1449 | |||
1450 | /* bt coex */ | 1459 | /* bt coex */ |
1451 | u8 bt_enable_flag; | 1460 | u8 bt_enable_flag; |
1452 | u8 bt_status; | 1461 | u8 bt_status; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c index a67ae56d546..1a5252d8ca7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-led.c +++ b/drivers/net/wireless/iwlwifi/iwl-led.c | |||
@@ -31,7 +31,6 @@ | |||
31 | #include <linux/delay.h> | 31 | #include <linux/delay.h> |
32 | #include <linux/skbuff.h> | 32 | #include <linux/skbuff.h> |
33 | #include <linux/netdevice.h> | 33 | #include <linux/netdevice.h> |
34 | #include <linux/wireless.h> | ||
35 | #include <net/mac80211.h> | 34 | #include <net/mac80211.h> |
36 | #include <linux/etherdevice.h> | 35 | #include <linux/etherdevice.h> |
37 | #include <asm/unaligned.h> | 36 | #include <asm/unaligned.h> |
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index dd6937e9705..28e59319f58 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c | |||
@@ -103,6 +103,12 @@ static void iwl_complete_scan(struct iwl_priv *priv, bool aborted) | |||
103 | ieee80211_scan_completed(priv->hw, aborted); | 103 | ieee80211_scan_completed(priv->hw, aborted); |
104 | } | 104 | } |
105 | 105 | ||
106 | if (priv->scan_type == IWL_SCAN_ROC) { | ||
107 | ieee80211_remain_on_channel_expired(priv->hw); | ||
108 | priv->hw_roc_channel = NULL; | ||
109 | schedule_delayed_work(&priv->hw_roc_disable_work, 10 * HZ); | ||
110 | } | ||
111 | |||
106 | priv->scan_type = IWL_SCAN_NORMAL; | 112 | priv->scan_type = IWL_SCAN_NORMAL; |
107 | priv->scan_vif = NULL; | 113 | priv->scan_vif = NULL; |
108 | priv->scan_request = NULL; | 114 | priv->scan_request = NULL; |
@@ -211,6 +217,9 @@ static void iwl_rx_scan_start_notif(struct iwl_priv *priv, | |||
211 | le32_to_cpu(notif->tsf_high), | 217 | le32_to_cpu(notif->tsf_high), |
212 | le32_to_cpu(notif->tsf_low), | 218 | le32_to_cpu(notif->tsf_low), |
213 | notif->status, notif->beacon_timer); | 219 | notif->status, notif->beacon_timer); |
220 | |||
221 | if (priv->scan_type == IWL_SCAN_ROC) | ||
222 | ieee80211_ready_on_channel(priv->hw); | ||
214 | } | 223 | } |
215 | 224 | ||
216 | /* Service SCAN_RESULTS_NOTIFICATION (0x83) */ | 225 | /* Service SCAN_RESULTS_NOTIFICATION (0x83) */ |
@@ -370,7 +379,7 @@ int __must_check iwl_scan_initiate(struct iwl_priv *priv, | |||
370 | 379 | ||
371 | IWL_DEBUG_SCAN(priv, "Starting %sscan...\n", | 380 | IWL_DEBUG_SCAN(priv, "Starting %sscan...\n", |
372 | scan_type == IWL_SCAN_NORMAL ? "" : | 381 | scan_type == IWL_SCAN_NORMAL ? "" : |
373 | scan_type == IWL_SCAN_OFFCH_TX ? "offchan TX " : | 382 | scan_type == IWL_SCAN_ROC ? "remain-on-channel " : |
374 | "internal short "); | 383 | "internal short "); |
375 | 384 | ||
376 | set_bit(STATUS_SCANNING, &priv->status); | 385 | set_bit(STATUS_SCANNING, &priv->status); |
@@ -565,10 +574,10 @@ static void iwl_bg_scan_completed(struct work_struct *work) | |||
565 | goto out_settings; | 574 | goto out_settings; |
566 | } | 575 | } |
567 | 576 | ||
568 | if (priv->scan_type == IWL_SCAN_OFFCH_TX && priv->offchan_tx_skb) { | 577 | if (priv->scan_type == IWL_SCAN_ROC) { |
569 | ieee80211_tx_status_irqsafe(priv->hw, | 578 | ieee80211_remain_on_channel_expired(priv->hw); |
570 | priv->offchan_tx_skb); | 579 | priv->hw_roc_channel = NULL; |
571 | priv->offchan_tx_skb = NULL; | 580 | schedule_delayed_work(&priv->hw_roc_disable_work, 10 * HZ); |
572 | } | 581 | } |
573 | 582 | ||
574 | if (priv->scan_type != IWL_SCAN_NORMAL && !aborted) { | 583 | if (priv->scan_type != IWL_SCAN_NORMAL && !aborted) { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.c b/drivers/net/wireless/iwlwifi/iwl-trans.c index 41f0de91400..3001bfb46e2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans.c | |||
@@ -750,6 +750,7 @@ static const struct queue_to_fifo_ac iwlagn_default_queue_to_tx_fifo[] = { | |||
750 | { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, }, | 750 | { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, }, |
751 | { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, }, | 751 | { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, }, |
752 | { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, }, | 752 | { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, }, |
753 | { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, }, | ||
753 | }; | 754 | }; |
754 | 755 | ||
755 | static const struct queue_to_fifo_ac iwlagn_ipan_queue_to_tx_fifo[] = { | 756 | static const struct queue_to_fifo_ac iwlagn_ipan_queue_to_tx_fifo[] = { |
@@ -763,6 +764,7 @@ static const struct queue_to_fifo_ac iwlagn_ipan_queue_to_tx_fifo[] = { | |||
763 | { IWL_TX_FIFO_VO_IPAN, IEEE80211_AC_VO, }, | 764 | { IWL_TX_FIFO_VO_IPAN, IEEE80211_AC_VO, }, |
764 | { IWL_TX_FIFO_BE_IPAN, 2, }, | 765 | { IWL_TX_FIFO_BE_IPAN, 2, }, |
765 | { IWLAGN_CMD_FIFO_NUM, IWL_AC_UNSET, }, | 766 | { IWLAGN_CMD_FIFO_NUM, IWL_AC_UNSET, }, |
767 | { IWL_TX_FIFO_AUX, IWL_AC_UNSET, }, | ||
766 | }; | 768 | }; |
767 | static void iwl_trans_tx_start(struct iwl_priv *priv) | 769 | static void iwl_trans_tx_start(struct iwl_priv *priv) |
768 | { | 770 | { |
@@ -848,10 +850,12 @@ static void iwl_trans_tx_start(struct iwl_priv *priv) | |||
848 | /* reset to 0 to enable all the queue first */ | 850 | /* reset to 0 to enable all the queue first */ |
849 | priv->txq_ctx_active_msk = 0; | 851 | priv->txq_ctx_active_msk = 0; |
850 | 852 | ||
851 | BUILD_BUG_ON(ARRAY_SIZE(iwlagn_default_queue_to_tx_fifo) != 10); | 853 | BUILD_BUG_ON(ARRAY_SIZE(iwlagn_default_queue_to_tx_fifo) != |
852 | BUILD_BUG_ON(ARRAY_SIZE(iwlagn_ipan_queue_to_tx_fifo) != 10); | 854 | IWLAGN_FIRST_AMPDU_QUEUE); |
855 | BUILD_BUG_ON(ARRAY_SIZE(iwlagn_ipan_queue_to_tx_fifo) != | ||
856 | IWLAGN_FIRST_AMPDU_QUEUE); | ||
853 | 857 | ||
854 | for (i = 0; i < 10; i++) { | 858 | for (i = 0; i < IWLAGN_FIRST_AMPDU_QUEUE; i++) { |
855 | int fifo = queue_to_fifo[i].fifo; | 859 | int fifo = queue_to_fifo[i].fifo; |
856 | int ac = queue_to_fifo[i].ac; | 860 | int ac = queue_to_fifo[i].ac; |
857 | 861 | ||