iwlwifi: virtualize the op_mode
[deliverable/linux.git] / drivers / net / wireless / iwlwifi / iwl-mac80211.c
CommitLineData
7335613a
WYG
1/******************************************************************************
2 *
4e318262 3 * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved.
7335613a
WYG
4 *
5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of version 2 of the GNU General Public License as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
16 *
17 * You should have received a copy of the GNU General Public License along with
18 * this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
20 *
21 * The full GNU General Public License is included in this distribution in the
22 * file called LICENSE.
23 *
24 * Contact Information:
25 * Intel Linux Wireless <ilw@linux.intel.com>
26 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
27 *
28 *****************************************************************************/
29#include <linux/kernel.h>
30#include <linux/module.h>
31#include <linux/init.h>
32#include <linux/slab.h>
33#include <linux/dma-mapping.h>
34#include <linux/delay.h>
35#include <linux/sched.h>
36#include <linux/skbuff.h>
37#include <linux/netdevice.h>
7335613a
WYG
38#include <linux/etherdevice.h>
39#include <linux/if_arp.h>
40
41#include <net/mac80211.h>
42
43#include <asm/div64.h>
44
edf38334 45#include "iwl-ucode.h"
7335613a 46#include "iwl-eeprom.h"
69a679b0 47#include "iwl-wifi.h"
7335613a
WYG
48#include "iwl-dev.h"
49#include "iwl-core.h"
50#include "iwl-io.h"
51#include "iwl-agn-calib.h"
52#include "iwl-agn.h"
53#include "iwl-shared.h"
54#include "iwl-bus.h"
55#include "iwl-trans.h"
d0f76d68 56#include "iwl-op-mode.h"
7335613a
WYG
57
58/*****************************************************************************
59 *
60 * mac80211 entry point functions
61 *
62 *****************************************************************************/
63
64static const struct ieee80211_iface_limit iwlagn_sta_ap_limits[] = {
65 {
66 .max = 1,
67 .types = BIT(NL80211_IFTYPE_STATION),
68 },
69 {
70 .max = 1,
71 .types = BIT(NL80211_IFTYPE_AP),
72 },
73};
74
75static const struct ieee80211_iface_limit iwlagn_2sta_limits[] = {
76 {
77 .max = 2,
78 .types = BIT(NL80211_IFTYPE_STATION),
79 },
80};
81
82static const struct ieee80211_iface_limit iwlagn_p2p_sta_go_limits[] = {
83 {
84 .max = 1,
85 .types = BIT(NL80211_IFTYPE_STATION),
86 },
87 {
88 .max = 1,
89 .types = BIT(NL80211_IFTYPE_P2P_GO) |
90 BIT(NL80211_IFTYPE_AP),
91 },
92};
93
94static const struct ieee80211_iface_limit iwlagn_p2p_2sta_limits[] = {
95 {
96 .max = 2,
97 .types = BIT(NL80211_IFTYPE_STATION),
98 },
99 {
100 .max = 1,
101 .types = BIT(NL80211_IFTYPE_P2P_CLIENT),
102 },
103};
104
105static const struct ieee80211_iface_combination
106iwlagn_iface_combinations_dualmode[] = {
107 { .num_different_channels = 1,
108 .max_interfaces = 2,
109 .beacon_int_infra_match = true,
110 .limits = iwlagn_sta_ap_limits,
111 .n_limits = ARRAY_SIZE(iwlagn_sta_ap_limits),
112 },
113 { .num_different_channels = 1,
114 .max_interfaces = 2,
115 .limits = iwlagn_2sta_limits,
116 .n_limits = ARRAY_SIZE(iwlagn_2sta_limits),
117 },
118};
119
120static const struct ieee80211_iface_combination
121iwlagn_iface_combinations_p2p[] = {
122 { .num_different_channels = 1,
123 .max_interfaces = 2,
124 .beacon_int_infra_match = true,
125 .limits = iwlagn_p2p_sta_go_limits,
126 .n_limits = ARRAY_SIZE(iwlagn_p2p_sta_go_limits),
127 },
128 { .num_different_channels = 1,
129 .max_interfaces = 2,
130 .limits = iwlagn_p2p_2sta_limits,
131 .n_limits = ARRAY_SIZE(iwlagn_p2p_2sta_limits),
132 },
133};
134
135/*
136 * Not a mac80211 entry point function, but it fits in with all the
137 * other mac80211 functions grouped here.
138 */
139int iwlagn_mac_setup_register(struct iwl_priv *priv,
4a986777 140 struct iwl_ucode_capabilities *capa)
7335613a
WYG
141{
142 int ret;
143 struct ieee80211_hw *hw = priv->hw;
144 struct iwl_rxon_context *ctx;
145
146 hw->rate_control_algorithm = "iwl-agn-rs";
147
148 /* Tell mac80211 our characteristics */
149 hw->flags = IEEE80211_HW_SIGNAL_DBM |
150 IEEE80211_HW_AMPDU_AGGREGATION |
151 IEEE80211_HW_NEED_DTIM_PERIOD |
152 IEEE80211_HW_SPECTRUM_MGMT |
153 IEEE80211_HW_REPORTS_TX_ACK_STATUS;
154
155 /*
156 * Including the following line will crash some AP's. This
157 * workaround removes the stimulus which causes the crash until
158 * the AP software can be fixed.
159 hw->max_tx_aggregation_subframes = LINK_QUAL_AGG_FRAME_LIMIT_DEF;
160 */
161
162 hw->flags |= IEEE80211_HW_SUPPORTS_PS |
163 IEEE80211_HW_SUPPORTS_DYNAMIC_PS;
164
38622419 165 if (cfg(priv)->sku & EEPROM_SKU_CAP_11N_ENABLE)
7335613a
WYG
166 hw->flags |= IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS |
167 IEEE80211_HW_SUPPORTS_STATIC_SMPS;
168
169 if (capa->flags & IWL_UCODE_TLV_FLAGS_MFP)
170 hw->flags |= IEEE80211_HW_MFP_CAPABLE;
171
172 hw->sta_data_size = sizeof(struct iwl_station_priv);
173 hw->vif_data_size = sizeof(struct iwl_vif_priv);
174
175 for_each_context(priv, ctx) {
176 hw->wiphy->interface_modes |= ctx->interface_modes;
177 hw->wiphy->interface_modes |= ctx->exclusive_interface_modes;
178 }
179
180 BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2);
181
182 if (hw->wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) {
183 hw->wiphy->iface_combinations = iwlagn_iface_combinations_p2p;
184 hw->wiphy->n_iface_combinations =
185 ARRAY_SIZE(iwlagn_iface_combinations_p2p);
186 } else if (hw->wiphy->interface_modes & BIT(NL80211_IFTYPE_AP)) {
187 hw->wiphy->iface_combinations =
188 iwlagn_iface_combinations_dualmode;
189 hw->wiphy->n_iface_combinations =
190 ARRAY_SIZE(iwlagn_iface_combinations_dualmode);
191 }
192
193 hw->wiphy->max_remain_on_channel_duration = 1000;
194
195 hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY |
196 WIPHY_FLAG_DISABLE_BEACON_HINTS |
197 WIPHY_FLAG_IBSS_RSN;
198
6516174d 199 if (nic(priv)->fw.ucode_wowlan.code.len &&
1042db2a 200 device_can_wakeup(trans(priv)->dev)) {
7335613a
WYG
201 hw->wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT |
202 WIPHY_WOWLAN_DISCONNECT |
203 WIPHY_WOWLAN_EAP_IDENTITY_REQ |
204 WIPHY_WOWLAN_RFKILL_RELEASE;
205 if (!iwlagn_mod_params.sw_crypto)
206 hw->wiphy->wowlan.flags |=
207 WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
208 WIPHY_WOWLAN_GTK_REKEY_FAILURE;
209
210 hw->wiphy->wowlan.n_patterns = IWLAGN_WOWLAN_MAX_PATTERNS;
211 hw->wiphy->wowlan.pattern_min_len =
212 IWLAGN_WOWLAN_MIN_PATTERN_LEN;
213 hw->wiphy->wowlan.pattern_max_len =
214 IWLAGN_WOWLAN_MAX_PATTERN_LEN;
215 }
216
217 if (iwlagn_mod_params.power_save)
218 hw->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;
219 else
220 hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
221
222 hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX;
223 /* we create the 802.11 header and a zero-length SSID element */
224 hw->wiphy->max_scan_ie_len = capa->max_probe_length - 24 - 2;
225
226 /* Default value; 4 EDCA QOS priorities */
227 hw->queues = 4;
228
229 hw->max_listen_interval = IWL_CONN_MAX_LISTEN_INTERVAL;
230
231 if (priv->bands[IEEE80211_BAND_2GHZ].n_channels)
232 priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
233 &priv->bands[IEEE80211_BAND_2GHZ];
234 if (priv->bands[IEEE80211_BAND_5GHZ].n_channels)
235 priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
236 &priv->bands[IEEE80211_BAND_5GHZ];
237
99673ee5 238 hw->wiphy->hw_version = trans(priv)->hw_id;
0ba958eb 239
7335613a
WYG
240 iwl_leds_init(priv);
241
242 ret = ieee80211_register_hw(priv->hw);
243 if (ret) {
244 IWL_ERR(priv, "Failed to register hw (error %d)\n", ret);
245 return ret;
246 }
247 priv->mac80211_registered = 1;
248
249 return 0;
250}
251
09af1403
DF
252void iwlagn_mac_unregister(struct iwl_priv *priv)
253{
254 if (!priv->mac80211_registered)
255 return;
256 iwl_leds_exit(priv);
257 ieee80211_unregister_hw(priv->hw);
258 priv->mac80211_registered = 0;
259}
260
7335613a
WYG
261static int __iwl_up(struct iwl_priv *priv)
262{
263 struct iwl_rxon_context *ctx;
264 int ret;
265
266 lockdep_assert_held(&priv->shrd->mutex);
267
268 if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) {
269 IWL_WARN(priv, "Exit pending; will not bring the NIC up\n");
270 return -EIO;
271 }
272
273 for_each_context(priv, ctx) {
274 ret = iwlagn_alloc_bcast_station(priv, ctx);
275 if (ret) {
276 iwl_dealloc_bcast_stations(priv);
277 return ret;
278 }
279 }
280
69a679b0 281 ret = iwl_run_init_ucode(trans(priv));
7335613a
WYG
282 if (ret) {
283 IWL_ERR(priv, "Failed to run INIT ucode: %d\n", ret);
284 goto error;
285 }
286
69a679b0 287 ret = iwl_load_ucode_wait_alive(trans(priv), IWL_UCODE_REGULAR);
7335613a
WYG
288 if (ret) {
289 IWL_ERR(priv, "Failed to start RT ucode: %d\n", ret);
290 goto error;
291 }
292
293 ret = iwl_alive_start(priv);
294 if (ret)
295 goto error;
296 return 0;
297
298 error:
299 set_bit(STATUS_EXIT_PENDING, &priv->shrd->status);
78e5a464 300 iwl_down(priv);
7335613a
WYG
301 clear_bit(STATUS_EXIT_PENDING, &priv->shrd->status);
302
303 IWL_ERR(priv, "Unable to initialize device.\n");
304 return ret;
305}
306
307static int iwlagn_mac_start(struct ieee80211_hw *hw)
308{
d0f76d68 309 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
7335613a
WYG
310 int ret;
311
312 IWL_DEBUG_MAC80211(priv, "enter\n");
313
314 /* we should be verifying the device is ready to be opened */
315 mutex_lock(&priv->shrd->mutex);
316 ret = __iwl_up(priv);
317 mutex_unlock(&priv->shrd->mutex);
318 if (ret)
319 return ret;
320
321 IWL_DEBUG_INFO(priv, "Start UP work done.\n");
322
323 /* Now we should be done, and the READY bit should be set. */
324 if (WARN_ON(!test_bit(STATUS_READY, &priv->shrd->status)))
325 ret = -EIO;
326
327 iwlagn_led_enable(priv);
328
329 priv->is_open = 1;
330 IWL_DEBUG_MAC80211(priv, "leave\n");
331 return 0;
332}
333
334static void iwlagn_mac_stop(struct ieee80211_hw *hw)
335{
d0f76d68 336 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
7335613a
WYG
337
338 IWL_DEBUG_MAC80211(priv, "enter\n");
339
340 if (!priv->is_open)
341 return;
342
343 priv->is_open = 0;
344
78e5a464 345 mutex_lock(&priv->shrd->mutex);
7335613a 346 iwl_down(priv);
78e5a464
EG
347 mutex_unlock(&priv->shrd->mutex);
348
349 iwl_cancel_deferred_work(priv);
7335613a 350
1ee158d8 351 flush_workqueue(priv->workqueue);
7335613a
WYG
352
353 /* User space software may expect getting rfkill changes
1df06bdc
EG
354 * even if interface is down, trans->down will leave the RF
355 * kill interrupt enabled
356 */
357 iwl_trans_stop_hw(trans(priv));
7335613a
WYG
358
359 IWL_DEBUG_MAC80211(priv, "leave\n");
360}
361
362static void iwlagn_mac_set_rekey_data(struct ieee80211_hw *hw,
363 struct ieee80211_vif *vif,
364 struct cfg80211_gtk_rekey_data *data)
365{
d0f76d68 366 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
7335613a
WYG
367
368 if (iwlagn_mod_params.sw_crypto)
369 return;
370
371 IWL_DEBUG_MAC80211(priv, "enter\n");
372 mutex_lock(&priv->shrd->mutex);
373
374 if (priv->contexts[IWL_RXON_CTX_BSS].vif != vif)
375 goto out;
376
377 memcpy(priv->kek, data->kek, NL80211_KEK_LEN);
378 memcpy(priv->kck, data->kck, NL80211_KCK_LEN);
379 priv->replay_ctr =
380 cpu_to_le64(be64_to_cpup((__be64 *)&data->replay_ctr));
381 priv->have_rekey_data = true;
382
383 out:
384 mutex_unlock(&priv->shrd->mutex);
385 IWL_DEBUG_MAC80211(priv, "leave\n");
386}
387
388#ifdef CONFIG_PM_SLEEP
7335613a
WYG
389
390static int iwlagn_mac_suspend(struct ieee80211_hw *hw,
391 struct cfg80211_wowlan *wowlan)
392{
d0f76d68 393 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
7335613a 394 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
023ca58f 395 int ret;
7335613a
WYG
396
397 if (WARN_ON(!wowlan))
398 return -EINVAL;
399
400 IWL_DEBUG_MAC80211(priv, "enter\n");
401 mutex_lock(&priv->shrd->mutex);
402
403 /* Don't attempt WoWLAN when not associated, tear down instead. */
404 if (!ctx->vif || ctx->vif->type != NL80211_IFTYPE_STATION ||
405 !iwl_is_associated_ctx(ctx)) {
406 ret = 1;
407 goto out;
408 }
409
023ca58f 410 ret = iwlagn_suspend(priv, hw, wowlan);
7335613a
WYG
411 if (ret)
412 goto error;
413
1042db2a 414 device_set_wakeup_enable(trans(priv)->dev, true);
7335613a
WYG
415
416 /* Now let the ucode operate on its own */
1042db2a 417 iwl_write32(trans(priv), CSR_UCODE_DRV_GP1_SET,
7335613a
WYG
418 CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE);
419
420 goto out;
421
422 error:
423 priv->shrd->wowlan = false;
424 iwlagn_prepare_restart(priv);
425 ieee80211_restart_hw(priv->hw);
426 out:
427 mutex_unlock(&priv->shrd->mutex);
7335613a
WYG
428 IWL_DEBUG_MAC80211(priv, "leave\n");
429
430 return ret;
431}
432
433static int iwlagn_mac_resume(struct ieee80211_hw *hw)
434{
d0f76d68 435 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
7335613a
WYG
436 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
437 struct ieee80211_vif *vif;
438 unsigned long flags;
439 u32 base, status = 0xffffffff;
440 int ret = -EIO;
441
442 IWL_DEBUG_MAC80211(priv, "enter\n");
443 mutex_lock(&priv->shrd->mutex);
444
1042db2a 445 iwl_write32(trans(priv), CSR_UCODE_DRV_GP1_CLR,
7335613a
WYG
446 CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE);
447
ae6130fc 448 base = priv->shrd->device_pointers.error_event_table;
7335613a 449 if (iwlagn_hw_valid_rtc_data_addr(base)) {
1042db2a
EG
450 spin_lock_irqsave(&trans(priv)->reg_lock, flags);
451 ret = iwl_grab_nic_access_silent(trans(priv));
7335613a 452 if (ret == 0) {
1042db2a
EG
453 iwl_write32(trans(priv), HBUS_TARG_MEM_RADDR, base);
454 status = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT);
455 iwl_release_nic_access(trans(priv));
7335613a 456 }
1042db2a 457 spin_unlock_irqrestore(&trans(priv)->reg_lock, flags);
7335613a
WYG
458
459#ifdef CONFIG_IWLWIFI_DEBUGFS
460 if (ret == 0) {
6516174d 461 struct iwl_nic *nic = nic(priv);
7335613a
WYG
462 if (!priv->wowlan_sram)
463 priv->wowlan_sram =
6516174d 464 kzalloc(nic->fw.ucode_wowlan.data.len,
7335613a
WYG
465 GFP_KERNEL);
466
467 if (priv->wowlan_sram)
468 _iwl_read_targ_mem_words(
1042db2a
EG
469 trans(priv), 0x800000,
470 priv->wowlan_sram,
6516174d 471 nic->fw.ucode_wowlan.data.len / 4);
7335613a
WYG
472 }
473#endif
474 }
475
476 /* we'll clear ctx->vif during iwlagn_prepare_restart() */
477 vif = ctx->vif;
478
479 priv->shrd->wowlan = false;
480
1042db2a 481 device_set_wakeup_enable(trans(priv)->dev, false);
7335613a
WYG
482
483 iwlagn_prepare_restart(priv);
484
485 memset((void *)&ctx->active, 0, sizeof(ctx->active));
486 iwl_connection_init_rx_config(priv, ctx);
487 iwlagn_set_rxon_chain(priv, ctx);
488
489 mutex_unlock(&priv->shrd->mutex);
490 IWL_DEBUG_MAC80211(priv, "leave\n");
491
492 ieee80211_resume_disconnect(vif);
493
494 return 1;
495}
496
497#endif
498
499static void iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
500{
d0f76d68 501 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
7335613a 502
7335613a
WYG
503 IWL_DEBUG_TX(priv, "dev->xmit(%d bytes) at rate 0x%02x\n", skb->len,
504 ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate);
505
506 if (iwlagn_tx_skb(priv, skb))
507 dev_kfree_skb_any(skb);
7335613a
WYG
508}
509
510static void iwlagn_mac_update_tkip_key(struct ieee80211_hw *hw,
511 struct ieee80211_vif *vif,
512 struct ieee80211_key_conf *keyconf,
513 struct ieee80211_sta *sta,
514 u32 iv32, u16 *phase1key)
515{
d0f76d68 516 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
7335613a
WYG
517
518 iwl_update_tkip_key(priv, vif, keyconf, sta, iv32, phase1key);
519}
520
521static int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
522 struct ieee80211_vif *vif,
523 struct ieee80211_sta *sta,
524 struct ieee80211_key_conf *key)
525{
d0f76d68 526 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
7335613a
WYG
527 struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
528 struct iwl_rxon_context *ctx = vif_priv->ctx;
529 int ret;
530 bool is_default_wep_key = false;
531
532 IWL_DEBUG_MAC80211(priv, "enter\n");
533
534 if (iwlagn_mod_params.sw_crypto) {
535 IWL_DEBUG_MAC80211(priv, "leave - hwcrypto disabled\n");
536 return -EOPNOTSUPP;
537 }
538
a7e12c8e
JB
539 switch (key->cipher) {
540 case WLAN_CIPHER_SUITE_TKIP:
541 key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
542 /* fall through */
543 case WLAN_CIPHER_SUITE_CCMP:
544 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
545 break;
546 default:
547 break;
548 }
549
7335613a
WYG
550 /*
551 * We could program these keys into the hardware as well, but we
552 * don't expect much multicast traffic in IBSS and having keys
553 * for more stations is probably more useful.
554 *
555 * Mark key TX-only and return 0.
556 */
557 if (vif->type == NL80211_IFTYPE_ADHOC &&
558 !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) {
559 key->hw_key_idx = WEP_INVALID_OFFSET;
560 return 0;
561 }
562
563 /* If they key was TX-only, accept deletion */
564 if (cmd == DISABLE_KEY && key->hw_key_idx == WEP_INVALID_OFFSET)
565 return 0;
566
567 mutex_lock(&priv->shrd->mutex);
568 iwl_scan_cancel_timeout(priv, 100);
569
570 BUILD_BUG_ON(WEP_INVALID_OFFSET == IWLAGN_HW_KEY_DEFAULT);
571
572 /*
573 * If we are getting WEP group key and we didn't receive any key mapping
574 * so far, we are in legacy wep mode (group key only), otherwise we are
575 * in 1X mode.
576 * In legacy wep mode, we use another host command to the uCode.
577 */
578 if ((key->cipher == WLAN_CIPHER_SUITE_WEP40 ||
579 key->cipher == WLAN_CIPHER_SUITE_WEP104) && !sta) {
580 if (cmd == SET_KEY)
581 is_default_wep_key = !ctx->key_mapping_keys;
582 else
583 is_default_wep_key =
584 key->hw_key_idx == IWLAGN_HW_KEY_DEFAULT;
585 }
586
587
588 switch (cmd) {
589 case SET_KEY:
590 if (is_default_wep_key) {
591 ret = iwl_set_default_wep_key(priv, vif_priv->ctx, key);
592 break;
593 }
594 ret = iwl_set_dynamic_key(priv, vif_priv->ctx, key, sta);
595 if (ret) {
596 /*
597 * can't add key for RX, but we don't need it
598 * in the device for TX so still return 0
599 */
600 ret = 0;
601 key->hw_key_idx = WEP_INVALID_OFFSET;
602 }
603
604 IWL_DEBUG_MAC80211(priv, "enable hwcrypto key\n");
605 break;
606 case DISABLE_KEY:
607 if (is_default_wep_key)
608 ret = iwl_remove_default_wep_key(priv, ctx, key);
609 else
610 ret = iwl_remove_dynamic_key(priv, ctx, key, sta);
611
612 IWL_DEBUG_MAC80211(priv, "disable hwcrypto key\n");
613 break;
614 default:
615 ret = -EINVAL;
616 }
617
618 mutex_unlock(&priv->shrd->mutex);
619 IWL_DEBUG_MAC80211(priv, "leave\n");
620
621 return ret;
622}
623
624static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw,
625 struct ieee80211_vif *vif,
626 enum ieee80211_ampdu_mlme_action action,
627 struct ieee80211_sta *sta, u16 tid, u16 *ssn,
628 u8 buf_size)
629{
d0f76d68 630 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
7335613a
WYG
631 int ret = -EINVAL;
632 struct iwl_station_priv *sta_priv = (void *) sta->drv_priv;
7335613a
WYG
633
634 IWL_DEBUG_HT(priv, "A-MPDU action on addr %pM tid %d\n",
635 sta->addr, tid);
636
38622419 637 if (!(cfg(priv)->sku & EEPROM_SKU_CAP_11N_ENABLE))
7335613a
WYG
638 return -EACCES;
639
640 IWL_DEBUG_MAC80211(priv, "enter\n");
641 mutex_lock(&priv->shrd->mutex);
642
643 switch (action) {
644 case IEEE80211_AMPDU_RX_START:
7428994d
JB
645 if (iwlagn_mod_params.disable_11n & IWL_DISABLE_HT_RXAGG)
646 break;
7335613a
WYG
647 IWL_DEBUG_HT(priv, "start Rx\n");
648 ret = iwl_sta_rx_agg_start(priv, sta, tid, *ssn);
649 break;
650 case IEEE80211_AMPDU_RX_STOP:
651 IWL_DEBUG_HT(priv, "stop Rx\n");
652 ret = iwl_sta_rx_agg_stop(priv, sta, tid);
653 if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
654 ret = 0;
655 break;
656 case IEEE80211_AMPDU_TX_START:
7428994d
JB
657 if (iwlagn_mod_params.disable_11n & IWL_DISABLE_HT_TXAGG)
658 break;
7335613a
WYG
659 IWL_DEBUG_HT(priv, "start Tx\n");
660 ret = iwlagn_tx_agg_start(priv, vif, sta, tid, ssn);
661 break;
662 case IEEE80211_AMPDU_TX_STOP:
663 IWL_DEBUG_HT(priv, "stop Tx\n");
664 ret = iwlagn_tx_agg_stop(priv, vif, sta, tid);
665 if ((ret == 0) && (priv->agg_tids_count > 0)) {
666 priv->agg_tids_count--;
667 IWL_DEBUG_HT(priv, "priv->agg_tids_count = %u\n",
668 priv->agg_tids_count);
669 }
670 if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
671 ret = 0;
38622419
DF
672 if (!priv->agg_tids_count && cfg(priv)->ht_params &&
673 cfg(priv)->ht_params->use_rts_for_aggregation) {
7335613a
WYG
674 /*
675 * switch off RTS/CTS if it was previously enabled
676 */
677 sta_priv->lq_sta.lq.general_params.flags &=
678 ~LINK_QUAL_FLAGS_SET_STA_TLC_RTS_MSK;
679 iwl_send_lq_cmd(priv, iwl_rxon_ctx_from_vif(vif),
680 &sta_priv->lq_sta.lq, CMD_ASYNC, false);
681 }
682 break;
683 case IEEE80211_AMPDU_TX_OPERATIONAL:
822e8b2a 684 ret = iwlagn_tx_agg_oper(priv, vif, sta, tid, buf_size);
7335613a
WYG
685 break;
686 }
687 mutex_unlock(&priv->shrd->mutex);
688 IWL_DEBUG_MAC80211(priv, "leave\n");
689 return ret;
690}
691
692static int iwlagn_mac_sta_add(struct ieee80211_hw *hw,
693 struct ieee80211_vif *vif,
694 struct ieee80211_sta *sta)
695{
d0f76d68 696 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
7335613a
WYG
697 struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
698 struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
699 bool is_ap = vif->type == NL80211_IFTYPE_STATION;
700 int ret = 0;
701 u8 sta_id;
702
703 IWL_DEBUG_MAC80211(priv, "received request to add station %pM\n",
704 sta->addr);
705 mutex_lock(&priv->shrd->mutex);
706 IWL_DEBUG_INFO(priv, "proceeding to add station %pM\n",
707 sta->addr);
708 sta_priv->sta_id = IWL_INVALID_STATION;
709
710 atomic_set(&sta_priv->pending_frames, 0);
711 if (vif->type == NL80211_IFTYPE_AP)
712 sta_priv->client = true;
713
714 ret = iwl_add_station_common(priv, vif_priv->ctx, sta->addr,
715 is_ap, sta, &sta_id);
716 if (ret) {
717 IWL_ERR(priv, "Unable to add station %pM (%d)\n",
718 sta->addr, ret);
719 /* Should we return success if return code is EEXIST ? */
720 goto out;
721 }
722
723 sta_priv->sta_id = sta_id;
724
725 /* Initialize rate scaling */
726 IWL_DEBUG_INFO(priv, "Initializing rate scaling for station %pM\n",
727 sta->addr);
728 iwl_rs_rate_init(priv, sta, sta_id);
729 out:
730 mutex_unlock(&priv->shrd->mutex);
731 IWL_DEBUG_MAC80211(priv, "leave\n");
732
733 return ret;
734}
735
736static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw,
737 struct ieee80211_channel_switch *ch_switch)
738{
d0f76d68 739 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
7335613a
WYG
740 const struct iwl_channel_info *ch_info;
741 struct ieee80211_conf *conf = &hw->conf;
742 struct ieee80211_channel *channel = ch_switch->channel;
743 struct iwl_ht_config *ht_conf = &priv->current_ht_config;
744 /*
745 * MULTI-FIXME
746 * When we add support for multiple interfaces, we need to
747 * revisit this. The channel switch command in the device
748 * only affects the BSS context, but what does that really
749 * mean? And what if we get a CSA on the second interface?
750 * This needs a lot of work.
751 */
752 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
753 u16 ch;
754
755 IWL_DEBUG_MAC80211(priv, "enter\n");
756
757 mutex_lock(&priv->shrd->mutex);
758
759 if (iwl_is_rfkill(priv->shrd))
760 goto out;
761
762 if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status) ||
763 test_bit(STATUS_SCANNING, &priv->shrd->status) ||
764 test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->shrd->status))
765 goto out;
766
767 if (!iwl_is_associated_ctx(ctx))
768 goto out;
769
38622419 770 if (!cfg(priv)->lib->set_channel_switch)
7335613a
WYG
771 goto out;
772
773 ch = channel->hw_value;
774 if (le16_to_cpu(ctx->active.channel) == ch)
775 goto out;
776
777 ch_info = iwl_get_channel_info(priv, channel->band, ch);
778 if (!is_channel_valid(ch_info)) {
779 IWL_DEBUG_MAC80211(priv, "invalid channel\n");
780 goto out;
781 }
782
783 spin_lock_irq(&priv->shrd->lock);
784
785 priv->current_ht_config.smps = conf->smps_mode;
786
787 /* Configure HT40 channels */
788 ctx->ht.enabled = conf_is_ht(conf);
137ce797
WYG
789 if (ctx->ht.enabled)
790 iwlagn_config_ht40(conf, ctx);
791 else
7335613a
WYG
792 ctx->ht.is_40mhz = false;
793
794 if ((le16_to_cpu(ctx->staging.channel) != ch))
795 ctx->staging.flags = 0;
796
797 iwl_set_rxon_channel(priv, channel, ctx);
798 iwl_set_rxon_ht(priv, ht_conf);
799 iwl_set_flags_for_band(priv, ctx, channel->band, ctx->vif);
800
801 spin_unlock_irq(&priv->shrd->lock);
802
803 iwl_set_rate(priv);
804 /*
805 * at this point, staging_rxon has the
806 * configuration for channel switch
807 */
808 set_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->shrd->status);
809 priv->switch_channel = cpu_to_le16(ch);
38622419 810 if (cfg(priv)->lib->set_channel_switch(priv, ch_switch)) {
7335613a
WYG
811 clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->shrd->status);
812 priv->switch_channel = 0;
813 ieee80211_chswitch_done(ctx->vif, false);
814 }
815
816out:
817 mutex_unlock(&priv->shrd->mutex);
818 IWL_DEBUG_MAC80211(priv, "leave\n");
819}
820
821static void iwlagn_configure_filter(struct ieee80211_hw *hw,
822 unsigned int changed_flags,
823 unsigned int *total_flags,
824 u64 multicast)
825{
d0f76d68 826 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
7335613a
WYG
827 __le32 filter_or = 0, filter_nand = 0;
828 struct iwl_rxon_context *ctx;
829
830#define CHK(test, flag) do { \
831 if (*total_flags & (test)) \
832 filter_or |= (flag); \
833 else \
834 filter_nand |= (flag); \
835 } while (0)
836
837 IWL_DEBUG_MAC80211(priv, "Enter: changed: 0x%x, total: 0x%x\n",
838 changed_flags, *total_flags);
839
840 CHK(FIF_OTHER_BSS | FIF_PROMISC_IN_BSS, RXON_FILTER_PROMISC_MSK);
841 /* Setting _just_ RXON_FILTER_CTL2HOST_MSK causes FH errors */
842 CHK(FIF_CONTROL, RXON_FILTER_CTL2HOST_MSK | RXON_FILTER_PROMISC_MSK);
843 CHK(FIF_BCN_PRBRESP_PROMISC, RXON_FILTER_BCON_AWARE_MSK);
844
845#undef CHK
846
847 mutex_lock(&priv->shrd->mutex);
848
849 for_each_context(priv, ctx) {
850 ctx->staging.filter_flags &= ~filter_nand;
851 ctx->staging.filter_flags |= filter_or;
852
853 /*
854 * Not committing directly because hardware can perform a scan,
855 * but we'll eventually commit the filter flags change anyway.
856 */
857 }
858
859 mutex_unlock(&priv->shrd->mutex);
860
861 /*
862 * Receiving all multicast frames is always enabled by the
863 * default flags setup in iwl_connection_init_rx_config()
864 * since we currently do not support programming multicast
865 * filters into the device.
866 */
867 *total_flags &= FIF_OTHER_BSS | FIF_ALLMULTI | FIF_PROMISC_IN_BSS |
868 FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL;
869}
870
871static void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop)
872{
d0f76d68 873 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
7335613a
WYG
874
875 mutex_lock(&priv->shrd->mutex);
876 IWL_DEBUG_MAC80211(priv, "enter\n");
877
878 if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) {
879 IWL_DEBUG_TX(priv, "Aborting flush due to device shutdown\n");
880 goto done;
881 }
882 if (iwl_is_rfkill(priv->shrd)) {
883 IWL_DEBUG_TX(priv, "Aborting flush due to RF Kill\n");
884 goto done;
885 }
886
887 /*
888 * mac80211 will not push any more frames for transmit
889 * until the flush is completed
890 */
891 if (drop) {
892 IWL_DEBUG_MAC80211(priv, "send flush command\n");
893 if (iwlagn_txfifo_flush(priv, IWL_DROP_ALL)) {
894 IWL_ERR(priv, "flush request fail\n");
895 goto done;
896 }
897 }
898 IWL_DEBUG_MAC80211(priv, "wait transmit/flush all frames\n");
899 iwl_trans_wait_tx_queue_empty(trans(priv));
900done:
901 mutex_unlock(&priv->shrd->mutex);
902 IWL_DEBUG_MAC80211(priv, "leave\n");
903}
904
905static int iwlagn_mac_remain_on_channel(struct ieee80211_hw *hw,
906 struct ieee80211_channel *channel,
907 enum nl80211_channel_type channel_type,
908 int duration)
909{
d0f76d68 910 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
7335613a
WYG
911 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_PAN];
912 int err = 0;
913
914 if (!(priv->shrd->valid_contexts & BIT(IWL_RXON_CTX_PAN)))
915 return -EOPNOTSUPP;
916
917 if (!(ctx->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)))
918 return -EOPNOTSUPP;
919
920 IWL_DEBUG_MAC80211(priv, "enter\n");
921 mutex_lock(&priv->shrd->mutex);
922
923 if (test_bit(STATUS_SCAN_HW, &priv->shrd->status)) {
924 err = -EBUSY;
925 goto out;
926 }
927
928 priv->hw_roc_channel = channel;
929 priv->hw_roc_chantype = channel_type;
3ddf6bef
JB
930 /* convert from ms to TU */
931 priv->hw_roc_duration = DIV_ROUND_UP(1000 * duration, 1024);
7335613a
WYG
932 priv->hw_roc_start_notified = false;
933 cancel_delayed_work(&priv->hw_roc_disable_work);
934
935 if (!ctx->is_active) {
a69cd040
JB
936 static const struct iwl_qos_info default_qos_data = {
937 .def_qos_parm = {
938 .ac[0] = {
939 .cw_min = cpu_to_le16(3),
940 .cw_max = cpu_to_le16(7),
941 .aifsn = 2,
942 .edca_txop = cpu_to_le16(1504),
943 },
944 .ac[1] = {
945 .cw_min = cpu_to_le16(7),
946 .cw_max = cpu_to_le16(15),
947 .aifsn = 2,
948 .edca_txop = cpu_to_le16(3008),
949 },
950 .ac[2] = {
951 .cw_min = cpu_to_le16(15),
952 .cw_max = cpu_to_le16(1023),
953 .aifsn = 3,
954 },
955 .ac[3] = {
956 .cw_min = cpu_to_le16(15),
957 .cw_max = cpu_to_le16(1023),
958 .aifsn = 7,
959 },
960 },
961 };
962
7335613a 963 ctx->is_active = true;
a69cd040 964 ctx->qos_data = default_qos_data;
7335613a
WYG
965 ctx->staging.dev_type = RXON_DEV_TYPE_P2P;
966 memcpy(ctx->staging.node_addr,
967 priv->contexts[IWL_RXON_CTX_BSS].staging.node_addr,
968 ETH_ALEN);
969 memcpy(ctx->staging.bssid_addr,
970 priv->contexts[IWL_RXON_CTX_BSS].staging.node_addr,
971 ETH_ALEN);
972 err = iwlagn_commit_rxon(priv, ctx);
973 if (err)
974 goto out;
975 ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK |
976 RXON_FILTER_PROMISC_MSK |
977 RXON_FILTER_CTL2HOST_MSK;
978
979 err = iwlagn_commit_rxon(priv, ctx);
980 if (err) {
981 iwlagn_disable_roc(priv);
982 goto out;
983 }
984 priv->hw_roc_setup = true;
985 }
986
987 err = iwl_scan_initiate(priv, ctx->vif, IWL_SCAN_ROC, channel->band);
988 if (err)
989 iwlagn_disable_roc(priv);
990
991 out:
992 mutex_unlock(&priv->shrd->mutex);
993 IWL_DEBUG_MAC80211(priv, "leave\n");
994
995 return err;
996}
997
998static int iwlagn_mac_cancel_remain_on_channel(struct ieee80211_hw *hw)
999{
d0f76d68 1000 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
7335613a
WYG
1001
1002 if (!(priv->shrd->valid_contexts & BIT(IWL_RXON_CTX_PAN)))
1003 return -EOPNOTSUPP;
1004
1005 IWL_DEBUG_MAC80211(priv, "enter\n");
1006 mutex_lock(&priv->shrd->mutex);
1007 iwl_scan_cancel_timeout(priv, priv->hw_roc_duration);
1008 iwlagn_disable_roc(priv);
1009 mutex_unlock(&priv->shrd->mutex);
1010 IWL_DEBUG_MAC80211(priv, "leave\n");
1011
1012 return 0;
1013}
1014
1015static int iwlagn_mac_tx_sync(struct ieee80211_hw *hw,
1016 struct ieee80211_vif *vif,
1017 const u8 *bssid,
1018 enum ieee80211_tx_sync_type type)
1019{
d0f76d68 1020 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
7335613a
WYG
1021 struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
1022 struct iwl_rxon_context *ctx = vif_priv->ctx;
1023 int ret;
1024 u8 sta_id;
1025
5d22df20
JL
1026 if (ctx->ctxid != IWL_RXON_CTX_PAN)
1027 return 0;
1028
7335613a
WYG
1029 IWL_DEBUG_MAC80211(priv, "enter\n");
1030 mutex_lock(&priv->shrd->mutex);
1031
1032 if (iwl_is_associated_ctx(ctx)) {
1033 ret = 0;
1034 goto out;
1035 }
1036
1037 if (ctx->preauth_bssid || test_bit(STATUS_SCAN_HW,
1038 &priv->shrd->status)) {
1039 ret = -EBUSY;
1040 goto out;
1041 }
1042
1043 ret = iwl_add_station_common(priv, ctx, bssid, true, NULL, &sta_id);
1044 if (ret)
1045 goto out;
1046
1047 if (WARN_ON(sta_id != ctx->ap_sta_id)) {
1048 ret = -EIO;
1049 goto out_remove_sta;
1050 }
1051
1052 memcpy(ctx->bssid, bssid, ETH_ALEN);
1053 ctx->preauth_bssid = true;
1054
1055 ret = iwlagn_commit_rxon(priv, ctx);
1056
1057 if (ret == 0)
1058 goto out;
1059
1060 out_remove_sta:
1061 iwl_remove_station(priv, sta_id, bssid);
1062 out:
1063 mutex_unlock(&priv->shrd->mutex);
1064 IWL_DEBUG_MAC80211(priv, "leave\n");
1065
1066 return ret;
1067}
1068
1069static void iwlagn_mac_finish_tx_sync(struct ieee80211_hw *hw,
1070 struct ieee80211_vif *vif,
1071 const u8 *bssid,
1072 enum ieee80211_tx_sync_type type)
1073{
d0f76d68 1074 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
7335613a
WYG
1075 struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
1076 struct iwl_rxon_context *ctx = vif_priv->ctx;
1077
5d22df20
JL
1078 if (ctx->ctxid != IWL_RXON_CTX_PAN)
1079 return;
1080
7335613a
WYG
1081 IWL_DEBUG_MAC80211(priv, "enter\n");
1082 mutex_lock(&priv->shrd->mutex);
1083
1084 if (iwl_is_associated_ctx(ctx))
1085 goto out;
1086
1087 iwl_remove_station(priv, ctx->ap_sta_id, bssid);
1088 ctx->preauth_bssid = false;
1089 /* no need to commit */
1090 out:
1091 mutex_unlock(&priv->shrd->mutex);
1092 IWL_DEBUG_MAC80211(priv, "leave\n");
1093}
1094
1095static void iwlagn_mac_rssi_callback(struct ieee80211_hw *hw,
1096 enum ieee80211_rssi_event rssi_event)
1097{
d0f76d68 1098 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
7335613a
WYG
1099
1100 IWL_DEBUG_MAC80211(priv, "enter\n");
1101 mutex_lock(&priv->shrd->mutex);
1102
38622419
DF
1103 if (cfg(priv)->bt_params &&
1104 cfg(priv)->bt_params->advanced_bt_coexist) {
7335613a
WYG
1105 if (rssi_event == RSSI_EVENT_LOW)
1106 priv->bt_enable_pspoll = true;
1107 else if (rssi_event == RSSI_EVENT_HIGH)
1108 priv->bt_enable_pspoll = false;
1109
1110 iwlagn_send_advance_bt_config(priv);
1111 } else {
1112 IWL_DEBUG_MAC80211(priv, "Advanced BT coex disabled,"
1113 "ignoring RSSI callback\n");
1114 }
1115
1116 mutex_unlock(&priv->shrd->mutex);
1117 IWL_DEBUG_MAC80211(priv, "leave\n");
1118}
1119
1120static int iwlagn_mac_set_tim(struct ieee80211_hw *hw,
1121 struct ieee80211_sta *sta, bool set)
1122{
d0f76d68 1123 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
7335613a 1124
1ee158d8 1125 queue_work(priv->workqueue, &priv->beacon_update);
7335613a
WYG
1126
1127 return 0;
1128}
1129
0b7a4c78
WYG
1130static int iwlagn_mac_conf_tx(struct ieee80211_hw *hw,
1131 struct ieee80211_vif *vif, u16 queue,
1132 const struct ieee80211_tx_queue_params *params)
1133{
d0f76d68 1134 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
0b7a4c78
WYG
1135 struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
1136 struct iwl_rxon_context *ctx = vif_priv->ctx;
1137 unsigned long flags;
1138 int q;
1139
1140 if (WARN_ON(!ctx))
1141 return -EINVAL;
1142
1143 IWL_DEBUG_MAC80211(priv, "enter\n");
1144
1145 if (!iwl_is_ready_rf(priv->shrd)) {
1146 IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
1147 return -EIO;
1148 }
1149
1150 if (queue >= AC_NUM) {
1151 IWL_DEBUG_MAC80211(priv, "leave - queue >= AC_NUM %d\n", queue);
1152 return 0;
1153 }
1154
1155 q = AC_NUM - 1 - queue;
1156
1157 spin_lock_irqsave(&priv->shrd->lock, flags);
1158
1159 ctx->qos_data.def_qos_parm.ac[q].cw_min =
1160 cpu_to_le16(params->cw_min);
1161 ctx->qos_data.def_qos_parm.ac[q].cw_max =
1162 cpu_to_le16(params->cw_max);
1163 ctx->qos_data.def_qos_parm.ac[q].aifsn = params->aifs;
1164 ctx->qos_data.def_qos_parm.ac[q].edca_txop =
1165 cpu_to_le16((params->txop * 32));
1166
1167 ctx->qos_data.def_qos_parm.ac[q].reserved1 = 0;
1168
1169 spin_unlock_irqrestore(&priv->shrd->lock, flags);
1170
1171 IWL_DEBUG_MAC80211(priv, "leave\n");
1172 return 0;
1173}
1174
1175static int iwlagn_mac_tx_last_beacon(struct ieee80211_hw *hw)
1176{
d0f76d68 1177 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
0b7a4c78
WYG
1178
1179 return priv->ibss_manager == IWL_IBSS_MANAGER;
1180}
1181
1182static int iwl_set_mode(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
1183{
1184 iwl_connection_init_rx_config(priv, ctx);
1185
1186 iwlagn_set_rxon_chain(priv, ctx);
1187
1188 return iwlagn_commit_rxon(priv, ctx);
1189}
1190
1191static int iwl_setup_interface(struct iwl_priv *priv,
1192 struct iwl_rxon_context *ctx)
1193{
1194 struct ieee80211_vif *vif = ctx->vif;
1195 int err;
1196
1197 lockdep_assert_held(&priv->shrd->mutex);
1198
1199 /*
1200 * This variable will be correct only when there's just
1201 * a single context, but all code using it is for hardware
1202 * that supports only one context.
1203 */
1204 priv->iw_mode = vif->type;
1205
1206 ctx->is_active = true;
1207
1208 err = iwl_set_mode(priv, ctx);
1209 if (err) {
1210 if (!ctx->always_active)
1211 ctx->is_active = false;
1212 return err;
1213 }
1214
38622419 1215 if (cfg(priv)->bt_params && cfg(priv)->bt_params->advanced_bt_coexist &&
0b7a4c78
WYG
1216 vif->type == NL80211_IFTYPE_ADHOC) {
1217 /*
1218 * pretend to have high BT traffic as long as we
1219 * are operating in IBSS mode, as this will cause
1220 * the rate scaling etc. to behave as intended.
1221 */
1222 priv->bt_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_HIGH;
1223 }
1224
1225 return 0;
1226}
1227
1228static int iwlagn_mac_add_interface(struct ieee80211_hw *hw,
1229 struct ieee80211_vif *vif)
1230{
d0f76d68 1231 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
0b7a4c78
WYG
1232 struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
1233 struct iwl_rxon_context *tmp, *ctx = NULL;
1234 int err;
1235 enum nl80211_iftype viftype = ieee80211_vif_type_p2p(vif);
1236
1237 IWL_DEBUG_MAC80211(priv, "enter: type %d, addr %pM\n",
1238 viftype, vif->addr);
1239
1240 cancel_delayed_work_sync(&priv->hw_roc_disable_work);
1241
1242 mutex_lock(&priv->shrd->mutex);
1243
1244 iwlagn_disable_roc(priv);
1245
1246 if (!iwl_is_ready_rf(priv->shrd)) {
1247 IWL_WARN(priv, "Try to add interface when device not ready\n");
1248 err = -EINVAL;
1249 goto out;
1250 }
1251
1252 for_each_context(priv, tmp) {
1253 u32 possible_modes =
1254 tmp->interface_modes | tmp->exclusive_interface_modes;
1255
1256 if (tmp->vif) {
1257 /* check if this busy context is exclusive */
1258 if (tmp->exclusive_interface_modes &
1259 BIT(tmp->vif->type)) {
1260 err = -EINVAL;
1261 goto out;
1262 }
1263 continue;
1264 }
1265
1266 if (!(possible_modes & BIT(viftype)))
1267 continue;
1268
1269 /* have maybe usable context w/o interface */
1270 ctx = tmp;
1271 break;
1272 }
1273
1274 if (!ctx) {
1275 err = -EOPNOTSUPP;
1276 goto out;
1277 }
1278
1279 vif_priv->ctx = ctx;
1280 ctx->vif = vif;
1281
1282 err = iwl_setup_interface(priv, ctx);
1283 if (!err)
1284 goto out;
1285
1286 ctx->vif = NULL;
1287 priv->iw_mode = NL80211_IFTYPE_STATION;
1288 out:
1289 mutex_unlock(&priv->shrd->mutex);
1290
1291 IWL_DEBUG_MAC80211(priv, "leave\n");
1292 return err;
1293}
1294
1295static void iwl_teardown_interface(struct iwl_priv *priv,
1296 struct ieee80211_vif *vif,
1297 bool mode_change)
1298{
1299 struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
1300
1301 lockdep_assert_held(&priv->shrd->mutex);
1302
1303 if (priv->scan_vif == vif) {
1304 iwl_scan_cancel_timeout(priv, 200);
1305 iwl_force_scan_end(priv);
1306 }
1307
1308 if (!mode_change) {
1309 iwl_set_mode(priv, ctx);
1310 if (!ctx->always_active)
1311 ctx->is_active = false;
1312 }
1313
1314 /*
1315 * When removing the IBSS interface, overwrite the
1316 * BT traffic load with the stored one from the last
1317 * notification, if any. If this is a device that
1318 * doesn't implement this, this has no effect since
1319 * both values are the same and zero.
1320 */
1321 if (vif->type == NL80211_IFTYPE_ADHOC)
1322 priv->bt_traffic_load = priv->last_bt_traffic_load;
1323}
1324
1325static void iwlagn_mac_remove_interface(struct ieee80211_hw *hw,
1326 struct ieee80211_vif *vif)
1327{
d0f76d68 1328 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
0b7a4c78
WYG
1329 struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
1330
1331 IWL_DEBUG_MAC80211(priv, "enter\n");
1332
1333 mutex_lock(&priv->shrd->mutex);
1334
1335 if (WARN_ON(ctx->vif != vif)) {
1336 struct iwl_rxon_context *tmp;
1337 IWL_ERR(priv, "ctx->vif = %p, vif = %p\n", ctx->vif, vif);
1338 for_each_context(priv, tmp)
1339 IWL_ERR(priv, "\tID = %d:\tctx = %p\tctx->vif = %p\n",
1340 tmp->ctxid, tmp, tmp->vif);
1341 }
1342 ctx->vif = NULL;
1343
1344 iwl_teardown_interface(priv, vif, false);
1345
1346 mutex_unlock(&priv->shrd->mutex);
1347
1348 IWL_DEBUG_MAC80211(priv, "leave\n");
1349
1350}
1351
1352static int iwlagn_mac_change_interface(struct ieee80211_hw *hw,
1353 struct ieee80211_vif *vif,
1354 enum nl80211_iftype newtype, bool newp2p)
1355{
d0f76d68 1356 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
0b7a4c78
WYG
1357 struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
1358 struct iwl_rxon_context *bss_ctx = &priv->contexts[IWL_RXON_CTX_BSS];
1359 struct iwl_rxon_context *tmp;
1360 enum nl80211_iftype newviftype = newtype;
1361 u32 interface_modes;
1362 int err;
1363
1364 IWL_DEBUG_MAC80211(priv, "enter\n");
1365
1366 newtype = ieee80211_iftype_p2p(newtype, newp2p);
1367
1368 mutex_lock(&priv->shrd->mutex);
1369
1370 if (!ctx->vif || !iwl_is_ready_rf(priv->shrd)) {
1371 /*
1372 * Huh? But wait ... this can maybe happen when
1373 * we're in the middle of a firmware restart!
1374 */
1375 err = -EBUSY;
1376 goto out;
1377 }
1378
1379 interface_modes = ctx->interface_modes | ctx->exclusive_interface_modes;
1380
1381 if (!(interface_modes & BIT(newtype))) {
1382 err = -EBUSY;
1383 goto out;
1384 }
1385
1386 /*
1387 * Refuse a change that should be done by moving from the PAN
1388 * context to the BSS context instead, if the BSS context is
1389 * available and can support the new interface type.
1390 */
1391 if (ctx->ctxid == IWL_RXON_CTX_PAN && !bss_ctx->vif &&
1392 (bss_ctx->interface_modes & BIT(newtype) ||
1393 bss_ctx->exclusive_interface_modes & BIT(newtype))) {
1394 BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2);
1395 err = -EBUSY;
1396 goto out;
1397 }
1398
1399 if (ctx->exclusive_interface_modes & BIT(newtype)) {
1400 for_each_context(priv, tmp) {
1401 if (ctx == tmp)
1402 continue;
1403
1404 if (!tmp->vif)
1405 continue;
1406
1407 /*
1408 * The current mode switch would be exclusive, but
1409 * another context is active ... refuse the switch.
1410 */
1411 err = -EBUSY;
1412 goto out;
1413 }
1414 }
1415
1416 /* success */
1417 iwl_teardown_interface(priv, vif, true);
1418 vif->type = newviftype;
1419 vif->p2p = newp2p;
1420 err = iwl_setup_interface(priv, ctx);
1421 WARN_ON(err);
1422 /*
1423 * We've switched internally, but submitting to the
1424 * device may have failed for some reason. Mask this
1425 * error, because otherwise mac80211 will not switch
1426 * (and set the interface type back) and we'll be
1427 * out of sync with it.
1428 */
1429 err = 0;
1430
1431 out:
1432 mutex_unlock(&priv->shrd->mutex);
1433 IWL_DEBUG_MAC80211(priv, "leave\n");
1434
1435 return err;
1436}
1437
ba4c5319
WYG
1438static int iwlagn_mac_hw_scan(struct ieee80211_hw *hw,
1439 struct ieee80211_vif *vif,
1440 struct cfg80211_scan_request *req)
1441{
d0f76d68 1442 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
ba4c5319
WYG
1443 int ret;
1444
1445 IWL_DEBUG_MAC80211(priv, "enter\n");
1446
1447 if (req->n_channels == 0)
1448 return -EINVAL;
1449
1450 mutex_lock(&priv->shrd->mutex);
1451
1452 /*
1453 * If an internal scan is in progress, just set
1454 * up the scan_request as per above.
1455 */
1456 if (priv->scan_type != IWL_SCAN_NORMAL) {
1457 IWL_DEBUG_SCAN(priv,
1458 "SCAN request during internal scan - defer\n");
1459 priv->scan_request = req;
1460 priv->scan_vif = vif;
1461 ret = 0;
1462 } else {
1463 priv->scan_request = req;
1464 priv->scan_vif = vif;
1465 /*
1466 * mac80211 will only ask for one band at a time
1467 * so using channels[0] here is ok
1468 */
1469 ret = iwl_scan_initiate(priv, vif, IWL_SCAN_NORMAL,
1470 req->channels[0]->band);
1471 if (ret) {
1472 priv->scan_request = NULL;
1473 priv->scan_vif = NULL;
1474 }
1475 }
1476
1477 IWL_DEBUG_MAC80211(priv, "leave\n");
1478
1479 mutex_unlock(&priv->shrd->mutex);
1480
1481 return ret;
1482}
1483
76b29331
WYG
1484static int iwlagn_mac_sta_remove(struct ieee80211_hw *hw,
1485 struct ieee80211_vif *vif,
1486 struct ieee80211_sta *sta)
1487{
d0f76d68 1488 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
76b29331
WYG
1489 struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
1490 int ret;
1491
1492 IWL_DEBUG_MAC80211(priv, "enter: received request to remove "
1493 "station %pM\n", sta->addr);
1494 mutex_lock(&priv->shrd->mutex);
1495 IWL_DEBUG_INFO(priv, "proceeding to remove station %pM\n",
1496 sta->addr);
1497 ret = iwl_remove_station(priv, sta_priv->sta_id, sta->addr);
1498 if (ret)
1499 IWL_DEBUG_QUIET_RFKILL(priv, "Error removing station %pM\n",
1500 sta->addr);
1501 mutex_unlock(&priv->shrd->mutex);
1502 IWL_DEBUG_MAC80211(priv, "leave\n");
1503
1504 return ret;
1505}
1506
1507static void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id)
1508{
1509 unsigned long flags;
1510
1511 spin_lock_irqsave(&priv->shrd->sta_lock, flags);
1512 priv->stations[sta_id].sta.station_flags &= ~STA_FLG_PWR_SAVE_MSK;
1513 priv->stations[sta_id].sta.station_flags_msk = STA_FLG_PWR_SAVE_MSK;
1514 priv->stations[sta_id].sta.sta.modify_mask = 0;
1515 priv->stations[sta_id].sta.sleep_tx_count = 0;
1516 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
1517 iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
1518 spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
1519
1520}
1521
1522static void iwlagn_mac_sta_notify(struct ieee80211_hw *hw,
1523 struct ieee80211_vif *vif,
1524 enum sta_notify_cmd cmd,
1525 struct ieee80211_sta *sta)
1526{
d0f76d68 1527 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
76b29331
WYG
1528 struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
1529 int sta_id;
1530
1531 IWL_DEBUG_MAC80211(priv, "enter\n");
1532
1533 switch (cmd) {
1534 case STA_NOTIFY_SLEEP:
1535 WARN_ON(!sta_priv->client);
1536 sta_priv->asleep = true;
1537 if (atomic_read(&sta_priv->pending_frames) > 0)
1538 ieee80211_sta_block_awake(hw, sta, true);
1539 break;
1540 case STA_NOTIFY_AWAKE:
1541 WARN_ON(!sta_priv->client);
1542 if (!sta_priv->asleep)
1543 break;
1544 sta_priv->asleep = false;
1545 sta_id = iwl_sta_id(sta);
1546 if (sta_id != IWL_INVALID_STATION)
1547 iwl_sta_modify_ps_wake(priv, sta_id);
1548 break;
1549 default:
1550 break;
1551 }
1552 IWL_DEBUG_MAC80211(priv, "leave\n");
1553}
1554
7335613a
WYG
1555struct ieee80211_ops iwlagn_hw_ops = {
1556 .tx = iwlagn_mac_tx,
1557 .start = iwlagn_mac_start,
1558 .stop = iwlagn_mac_stop,
1559#ifdef CONFIG_PM_SLEEP
1560 .suspend = iwlagn_mac_suspend,
1561 .resume = iwlagn_mac_resume,
1562#endif
1563 .add_interface = iwlagn_mac_add_interface,
1564 .remove_interface = iwlagn_mac_remove_interface,
1565 .change_interface = iwlagn_mac_change_interface,
1566 .config = iwlagn_mac_config,
1567 .configure_filter = iwlagn_configure_filter,
1568 .set_key = iwlagn_mac_set_key,
1569 .update_tkip_key = iwlagn_mac_update_tkip_key,
1570 .set_rekey_data = iwlagn_mac_set_rekey_data,
1571 .conf_tx = iwlagn_mac_conf_tx,
1572 .bss_info_changed = iwlagn_bss_info_changed,
1573 .ampdu_action = iwlagn_mac_ampdu_action,
1574 .hw_scan = iwlagn_mac_hw_scan,
1575 .sta_notify = iwlagn_mac_sta_notify,
1576 .sta_add = iwlagn_mac_sta_add,
1577 .sta_remove = iwlagn_mac_sta_remove,
1578 .channel_switch = iwlagn_mac_channel_switch,
1579 .flush = iwlagn_mac_flush,
1580 .tx_last_beacon = iwlagn_mac_tx_last_beacon,
1581 .remain_on_channel = iwlagn_mac_remain_on_channel,
1582 .cancel_remain_on_channel = iwlagn_mac_cancel_remain_on_channel,
1583 .rssi_callback = iwlagn_mac_rssi_callback,
1584 CFG80211_TESTMODE_CMD(iwlagn_mac_testmode_cmd)
1585 CFG80211_TESTMODE_DUMP(iwlagn_mac_testmode_dump)
1586 .tx_sync = iwlagn_mac_tx_sync,
1587 .finish_tx_sync = iwlagn_mac_finish_tx_sync,
1588 .set_tim = iwlagn_mac_set_tim,
1589};
1590
1591/* This function both allocates and initializes hw and priv. */
1592struct ieee80211_hw *iwl_alloc_all(void)
1593{
1594 struct iwl_priv *priv;
d0f76d68 1595 struct iwl_op_mode *op_mode;
7335613a
WYG
1596 /* mac80211 allocates memory for this device instance, including
1597 * space for this driver's private structure */
1598 struct ieee80211_hw *hw;
1599
d0f76d68
EG
1600 hw = ieee80211_alloc_hw(sizeof(struct iwl_priv) +
1601 sizeof(struct iwl_op_mode), &iwlagn_hw_ops);
7335613a
WYG
1602 if (!hw)
1603 goto out;
1604
d0f76d68
EG
1605 op_mode = hw->priv;
1606 priv = IWL_OP_MODE_GET_DVM(op_mode);
7335613a
WYG
1607 priv->hw = hw;
1608
1609out:
1610 return hw;
1611}
This page took 0.16835 seconds and 5 git commands to generate.