aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlwifi')
-rw-r--r--drivers/net/wireless/iwlwifi/Kconfig17
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-1000.c16
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-2000.c24
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c13
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c20
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-calib.c69
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-hw.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-lib.c47
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rxon.c23
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-tx.c30
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c388
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.h1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-commands.h34
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h29
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-led.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-scan.c19
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans.c10
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
115config 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 = {
201static struct iwl_ht_params iwl1000_ht_params = { 203static 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
241static struct iwl_ht_params iwl2000_ht_params = { 247static 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
86static struct iwl_sensitivity_ranges iwl5000_sensitivity = { 85static 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
113static struct iwl_sensitivity_ranges iwl6000_sensitivity = { 115static 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
756static 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
768int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) 756int 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 */
130static void iwlagn_tx_cmd_build_basic(struct iwl_priv *priv, 130static 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
191static void iwlagn_tx_cmd_build_rate(struct iwl_priv *priv, 190static 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
616static 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
617struct iwlagn_ucode_capabilities { 697struct 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
1958static 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
2023static 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;
2040unlock:
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
3201static void iwlagn_disable_roc(struct iwl_priv *priv) 3219void 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
3223static void iwlagn_bg_roc_done(struct work_struct *work) 3241static 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
3522static 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
3529static const u8 iwlagn_bss_ac_to_queue[] = {
3530 0, 1, 2, 3,
3531};
3532
3533static 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
3540static 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. */
3545static struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg) 3569static 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
3566static 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
3625int iwl_probe(struct iwl_bus *bus, struct iwl_cfg *cfg) 3590int 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 */
210int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif); 210int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif);
211void iwlagn_post_scan(struct iwl_priv *priv); 211void iwlagn_post_scan(struct iwl_priv *priv);
212void iwlagn_disable_roc(struct iwl_priv *priv);
212 213
213/* station mgmt */ 214/* station mgmt */
214int iwlagn_manage_ibss_station(struct iwl_priv *priv, 215int 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 */
140struct iwl_base_params { 141struct 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 */
568enum iwl_ucode_tlv_flag { 580enum 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
574struct iwl_ucode_tlv { 587struct iwl_ucode_tlv {
@@ -1168,7 +1181,7 @@ struct iwl_rxon_context {
1168enum iwl_scan_type { 1181enum 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
1174enum iwlagn_ucode_type { 1187enum 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
755static const struct queue_to_fifo_ac iwlagn_ipan_queue_to_tx_fifo[] = { 756static 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};
767static void iwl_trans_tx_start(struct iwl_priv *priv) 769static 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