• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  * This file is provided under a dual BSD/GPLv2 license.  When using or
4  * redistributing this file, you may do so under either license.
5  *
6  * GPL LICENSE SUMMARY
7  *
8  * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of version 2 of the GNU General Public License as
12  * published by the Free Software Foundation.
13  *
14  * This program is distributed in the hope that it will be useful, but
15  * WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22  * USA
23  *
24  * The full GNU General Public License is included in this distribution
25  * in the file called COPYING.
26  *
27  * Contact Information:
28  *  Intel Linux Wireless <ilw@linux.intel.com>
29  * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30  *
31  * BSD LICENSE
32  *
33  * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved.
34  * All rights reserved.
35  *
36  * Redistribution and use in source and binary forms, with or without
37  * modification, are permitted provided that the following conditions
38  * are met:
39  *
40  *  * Redistributions of source code must retain the above copyright
41  *    notice, this list of conditions and the following disclaimer.
42  *  * Redistributions in binary form must reproduce the above copyright
43  *    notice, this list of conditions and the following disclaimer in
44  *    the documentation and/or other materials provided with the
45  *    distribution.
46  *  * Neither the name Intel Corporation nor the names of its
47  *    contributors may be used to endorse or promote products derived
48  *    from this software without specific prior written permission.
49  *
50  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61  *
62  *****************************************************************************/
63 #include <linux/kernel.h>
64 #include <linux/slab.h>
65 #include <linux/skbuff.h>
66 #include <linux/netdevice.h>
67 #include <linux/etherdevice.h>
68 #include <linux/ip.h>
69 #include <net/mac80211.h>
70 #include <net/tcp.h>
71 
72 #include "iwl-op-mode.h"
73 #include "iwl-io.h"
74 #include "mvm.h"
75 #include "sta.h"
76 #include "time-event.h"
77 #include "iwl-eeprom-parse.h"
78 #include "fw-api-scan.h"
79 #include "iwl-phy-db.h"
80 
81 static const struct ieee80211_iface_limit iwl_mvm_limits[] = {
82 	{
83 		.max = 1,
84 		.types = BIT(NL80211_IFTYPE_STATION) |
85 			BIT(NL80211_IFTYPE_AP),
86 	},
87 	{
88 		.max = 1,
89 		.types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
90 			BIT(NL80211_IFTYPE_P2P_GO),
91 	},
92 	{
93 		.max = 1,
94 		.types = BIT(NL80211_IFTYPE_P2P_DEVICE),
95 	},
96 };
97 
98 static const struct ieee80211_iface_combination iwl_mvm_iface_combinations[] = {
99 	{
100 		.num_different_channels = 1,
101 		.max_interfaces = 3,
102 		.limits = iwl_mvm_limits,
103 		.n_limits = ARRAY_SIZE(iwl_mvm_limits),
104 	},
105 };
106 
107 #ifdef CONFIG_PM_SLEEP
108 static const struct nl80211_wowlan_tcp_data_token_feature
109 iwl_mvm_wowlan_tcp_token_feature = {
110 	.min_len = 0,
111 	.max_len = 255,
112 	.bufsize = IWL_WOWLAN_REMOTE_WAKE_MAX_TOKENS,
113 };
114 
115 static const struct wiphy_wowlan_tcp_support iwl_mvm_wowlan_tcp_support = {
116 	.tok = &iwl_mvm_wowlan_tcp_token_feature,
117 	.data_payload_max = IWL_WOWLAN_TCP_MAX_PACKET_LEN -
118 			    sizeof(struct ethhdr) -
119 			    sizeof(struct iphdr) -
120 			    sizeof(struct tcphdr),
121 	.data_interval_max = 65535, /* __le16 in API */
122 	.wake_payload_max = IWL_WOWLAN_REMOTE_WAKE_MAX_PACKET_LEN -
123 			    sizeof(struct ethhdr) -
124 			    sizeof(struct iphdr) -
125 			    sizeof(struct tcphdr),
126 	.seq = true,
127 };
128 #endif
129 
iwl_mvm_mac_setup_register(struct iwl_mvm * mvm)130 int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
131 {
132 	struct ieee80211_hw *hw = mvm->hw;
133 	int num_mac, ret, i;
134 
135 	/* Tell mac80211 our characteristics */
136 	hw->flags = IEEE80211_HW_SIGNAL_DBM |
137 		    IEEE80211_HW_SPECTRUM_MGMT |
138 		    IEEE80211_HW_REPORTS_TX_ACK_STATUS |
139 		    IEEE80211_HW_QUEUE_CONTROL |
140 		    IEEE80211_HW_WANT_MONITOR_VIF |
141 		    IEEE80211_HW_SUPPORTS_PS |
142 		    IEEE80211_HW_SUPPORTS_DYNAMIC_PS |
143 		    IEEE80211_HW_AMPDU_AGGREGATION |
144 		    IEEE80211_HW_TIMING_BEACON_ONLY;
145 
146 	hw->queues = IWL_MVM_FIRST_AGG_QUEUE;
147 	hw->offchannel_tx_hw_queue = IWL_MVM_OFFCHANNEL_QUEUE;
148 	hw->rate_control_algorithm = "iwl-mvm-rs";
149 
150 	/*
151 	 * Enable 11w if advertised by firmware and software crypto
152 	 * is not enabled (as the firmware will interpret some mgmt
153 	 * packets, so enabling it with software crypto isn't safe)
154 	 */
155 	if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_MFP &&
156 	    !iwlwifi_mod_params.sw_crypto)
157 		hw->flags |= IEEE80211_HW_MFP_CAPABLE;
158 
159 	hw->sta_data_size = sizeof(struct iwl_mvm_sta);
160 	hw->vif_data_size = sizeof(struct iwl_mvm_vif);
161 	hw->chanctx_data_size = sizeof(struct iwl_mvm_phy_ctxt);
162 
163 	hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
164 		BIT(NL80211_IFTYPE_P2P_CLIENT) |
165 		BIT(NL80211_IFTYPE_AP) |
166 		BIT(NL80211_IFTYPE_P2P_GO) |
167 		BIT(NL80211_IFTYPE_P2P_DEVICE);
168 
169 	hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY |
170 			    WIPHY_FLAG_DISABLE_BEACON_HINTS |
171 			    WIPHY_FLAG_IBSS_RSN;
172 
173 	hw->wiphy->iface_combinations = iwl_mvm_iface_combinations;
174 	hw->wiphy->n_iface_combinations =
175 		ARRAY_SIZE(iwl_mvm_iface_combinations);
176 
177 	hw->wiphy->max_remain_on_channel_duration = 10000;
178 	hw->max_listen_interval = IWL_CONN_MAX_LISTEN_INTERVAL;
179 
180 	/* Extract MAC address */
181 	memcpy(mvm->addresses[0].addr, mvm->nvm_data->hw_addr, ETH_ALEN);
182 	hw->wiphy->addresses = mvm->addresses;
183 	hw->wiphy->n_addresses = 1;
184 
185 	/* Extract additional MAC addresses if available */
186 	num_mac = (mvm->nvm_data->n_hw_addrs > 1) ?
187 		min(IWL_MVM_MAX_ADDRESSES, mvm->nvm_data->n_hw_addrs) : 1;
188 
189 	for (i = 1; i < num_mac; i++) {
190 		memcpy(mvm->addresses[i].addr, mvm->addresses[i-1].addr,
191 		       ETH_ALEN);
192 		mvm->addresses[i].addr[5]++;
193 		hw->wiphy->n_addresses++;
194 	}
195 
196 	/* we create the 802.11 header and a max-length SSID element */
197 	hw->wiphy->max_scan_ie_len =
198 		mvm->fw->ucode_capa.max_probe_length - 24 - 34;
199 	hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX;
200 
201 	if (mvm->nvm_data->bands[IEEE80211_BAND_2GHZ].n_channels)
202 		hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
203 			&mvm->nvm_data->bands[IEEE80211_BAND_2GHZ];
204 	if (mvm->nvm_data->bands[IEEE80211_BAND_5GHZ].n_channels)
205 		hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
206 			&mvm->nvm_data->bands[IEEE80211_BAND_5GHZ];
207 
208 	hw->wiphy->hw_version = mvm->trans->hw_id;
209 
210 	if (iwlmvm_mod_params.power_scheme != IWL_POWER_SCHEME_CAM)
211 		hw->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;
212 	else
213 		hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
214 
215 	hw->wiphy->features |= NL80211_FEATURE_P2P_GO_CTWIN |
216 			       NL80211_FEATURE_P2P_GO_OPPPS;
217 
218 	mvm->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD;
219 
220 #ifdef CONFIG_PM_SLEEP
221 	if (mvm->fw->img[IWL_UCODE_WOWLAN].sec[0].len &&
222 	    mvm->trans->ops->d3_suspend &&
223 	    mvm->trans->ops->d3_resume &&
224 	    device_can_wakeup(mvm->trans->dev)) {
225 		hw->wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT |
226 					  WIPHY_WOWLAN_DISCONNECT |
227 					  WIPHY_WOWLAN_EAP_IDENTITY_REQ |
228 					  WIPHY_WOWLAN_RFKILL_RELEASE;
229 		if (!iwlwifi_mod_params.sw_crypto)
230 			hw->wiphy->wowlan.flags |=
231 				WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
232 				WIPHY_WOWLAN_GTK_REKEY_FAILURE |
233 				WIPHY_WOWLAN_4WAY_HANDSHAKE;
234 
235 		hw->wiphy->wowlan.n_patterns = IWL_WOWLAN_MAX_PATTERNS;
236 		hw->wiphy->wowlan.pattern_min_len = IWL_WOWLAN_MIN_PATTERN_LEN;
237 		hw->wiphy->wowlan.pattern_max_len = IWL_WOWLAN_MAX_PATTERN_LEN;
238 		hw->wiphy->wowlan.tcp = &iwl_mvm_wowlan_tcp_support;
239 	}
240 #endif
241 
242 	ret = iwl_mvm_leds_init(mvm);
243 	if (ret)
244 		return ret;
245 
246 	return ieee80211_register_hw(mvm->hw);
247 }
248 
iwl_mvm_mac_tx(struct ieee80211_hw * hw,struct ieee80211_tx_control * control,struct sk_buff * skb)249 static void iwl_mvm_mac_tx(struct ieee80211_hw *hw,
250 			   struct ieee80211_tx_control *control,
251 			   struct sk_buff *skb)
252 {
253 	struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
254 
255 	if (test_bit(IWL_MVM_STATUS_HW_RFKILL, &mvm->status)) {
256 		IWL_DEBUG_DROP(mvm, "Dropping - RF KILL\n");
257 		goto drop;
258 	}
259 
260 	if (IEEE80211_SKB_CB(skb)->hw_queue == IWL_MVM_OFFCHANNEL_QUEUE &&
261 	    !test_bit(IWL_MVM_STATUS_ROC_RUNNING, &mvm->status))
262 		goto drop;
263 
264 	if (control->sta) {
265 		if (iwl_mvm_tx_skb(mvm, skb, control->sta))
266 			goto drop;
267 		return;
268 	}
269 
270 	if (iwl_mvm_tx_skb_non_sta(mvm, skb))
271 		goto drop;
272 	return;
273  drop:
274 	ieee80211_free_txskb(hw, skb);
275 }
276 
iwl_mvm_mac_ampdu_action(struct ieee80211_hw * hw,struct ieee80211_vif * vif,enum ieee80211_ampdu_mlme_action action,struct ieee80211_sta * sta,u16 tid,u16 * ssn,u8 buf_size)277 static int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw,
278 				    struct ieee80211_vif *vif,
279 				    enum ieee80211_ampdu_mlme_action action,
280 				    struct ieee80211_sta *sta, u16 tid,
281 				    u16 *ssn, u8 buf_size)
282 {
283 	struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
284 	int ret;
285 
286 	IWL_DEBUG_HT(mvm, "A-MPDU action on addr %pM tid %d: action %d\n",
287 		     sta->addr, tid, action);
288 
289 	if (!(mvm->nvm_data->sku_cap_11n_enable))
290 		return -EACCES;
291 
292 	mutex_lock(&mvm->mutex);
293 
294 	switch (action) {
295 	case IEEE80211_AMPDU_RX_START:
296 		if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_RXAGG) {
297 			ret = -EINVAL;
298 			break;
299 		}
300 		ret = iwl_mvm_sta_rx_agg(mvm, sta, tid, *ssn, true);
301 		break;
302 	case IEEE80211_AMPDU_RX_STOP:
303 		ret = iwl_mvm_sta_rx_agg(mvm, sta, tid, 0, false);
304 		break;
305 	case IEEE80211_AMPDU_TX_START:
306 		if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_TXAGG) {
307 			ret = -EINVAL;
308 			break;
309 		}
310 		ret = iwl_mvm_sta_tx_agg_start(mvm, vif, sta, tid, ssn);
311 		break;
312 	case IEEE80211_AMPDU_TX_STOP_CONT:
313 		ret = iwl_mvm_sta_tx_agg_stop(mvm, vif, sta, tid);
314 		break;
315 	case IEEE80211_AMPDU_TX_STOP_FLUSH:
316 	case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
317 		ret = iwl_mvm_sta_tx_agg_flush(mvm, vif, sta, tid);
318 		break;
319 	case IEEE80211_AMPDU_TX_OPERATIONAL:
320 		ret = iwl_mvm_sta_tx_agg_oper(mvm, vif, sta, tid, buf_size);
321 		break;
322 	default:
323 		WARN_ON_ONCE(1);
324 		ret = -EINVAL;
325 		break;
326 	}
327 	mutex_unlock(&mvm->mutex);
328 
329 	return ret;
330 }
331 
iwl_mvm_cleanup_iterator(void * data,u8 * mac,struct ieee80211_vif * vif)332 static void iwl_mvm_cleanup_iterator(void *data, u8 *mac,
333 				     struct ieee80211_vif *vif)
334 {
335 	struct iwl_mvm *mvm = data;
336 	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
337 
338 	mvmvif->uploaded = false;
339 	mvmvif->ap_sta_id = IWL_MVM_STATION_COUNT;
340 
341 	/* does this make sense at all? */
342 	mvmvif->color++;
343 
344 	spin_lock_bh(&mvm->time_event_lock);
345 	iwl_mvm_te_clear_data(mvm, &mvmvif->time_event_data);
346 	spin_unlock_bh(&mvm->time_event_lock);
347 
348 	if (vif->type != NL80211_IFTYPE_P2P_DEVICE)
349 		mvmvif->phy_ctxt = NULL;
350 }
351 
iwl_mvm_restart_cleanup(struct iwl_mvm * mvm)352 static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm)
353 {
354 	iwl_trans_stop_device(mvm->trans);
355 	iwl_trans_stop_hw(mvm->trans, false);
356 
357 	mvm->scan_status = IWL_MVM_SCAN_NONE;
358 
359 	/* just in case one was running */
360 	ieee80211_remain_on_channel_expired(mvm->hw);
361 
362 	ieee80211_iterate_active_interfaces_atomic(
363 		mvm->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
364 		iwl_mvm_cleanup_iterator, mvm);
365 
366 	memset(mvm->fw_key_table, 0, sizeof(mvm->fw_key_table));
367 	memset(mvm->sta_drained, 0, sizeof(mvm->sta_drained));
368 
369 	ieee80211_wake_queues(mvm->hw);
370 
371 	mvm->vif_count = 0;
372 }
373 
iwl_mvm_mac_start(struct ieee80211_hw * hw)374 static int iwl_mvm_mac_start(struct ieee80211_hw *hw)
375 {
376 	struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
377 	int ret;
378 
379 	mutex_lock(&mvm->mutex);
380 
381 	/* Clean up some internal and mac80211 state on restart */
382 	if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status))
383 		iwl_mvm_restart_cleanup(mvm);
384 
385 	ret = iwl_mvm_up(mvm);
386 	mutex_unlock(&mvm->mutex);
387 
388 	return ret;
389 }
390 
iwl_mvm_mac_restart_complete(struct ieee80211_hw * hw)391 static void iwl_mvm_mac_restart_complete(struct ieee80211_hw *hw)
392 {
393 	struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
394 	int ret;
395 
396 	mutex_lock(&mvm->mutex);
397 
398 	clear_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status);
399 	ret = iwl_mvm_update_quotas(mvm, NULL);
400 	if (ret)
401 		IWL_ERR(mvm, "Failed to update quotas after restart (%d)\n",
402 			ret);
403 
404 	mutex_unlock(&mvm->mutex);
405 }
406 
iwl_mvm_mac_stop(struct ieee80211_hw * hw)407 static void iwl_mvm_mac_stop(struct ieee80211_hw *hw)
408 {
409 	struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
410 
411 	flush_work(&mvm->async_handlers_wk);
412 
413 	mutex_lock(&mvm->mutex);
414 	/* async_handlers_wk is now blocked */
415 
416 	/*
417 	 * The work item could be running or queued if the
418 	 * ROC time event stops just as we get here.
419 	 */
420 	cancel_work_sync(&mvm->roc_done_wk);
421 
422 	iwl_trans_stop_device(mvm->trans);
423 	iwl_trans_stop_hw(mvm->trans, false);
424 
425 	iwl_mvm_async_handlers_purge(mvm);
426 	/* async_handlers_list is empty and will stay empty: HW is stopped */
427 
428 	/* the fw is stopped, the aux sta is dead: clean up driver state */
429 	iwl_mvm_dealloc_int_sta(mvm, &mvm->aux_sta);
430 
431 	mutex_unlock(&mvm->mutex);
432 
433 	/*
434 	 * The worker might have been waiting for the mutex, let it run and
435 	 * discover that its list is now empty.
436 	 */
437 	cancel_work_sync(&mvm->async_handlers_wk);
438 }
439 
iwl_mvm_pm_disable_iterator(void * data,u8 * mac,struct ieee80211_vif * vif)440 static void iwl_mvm_pm_disable_iterator(void *data, u8 *mac,
441 					struct ieee80211_vif *vif)
442 {
443 	struct iwl_mvm *mvm = data;
444 	int ret;
445 
446 	ret = iwl_mvm_power_disable(mvm, vif);
447 	if (ret)
448 		IWL_ERR(mvm, "failed to disable power management\n");
449 }
450 
iwl_mvm_power_update_iterator(void * data,u8 * mac,struct ieee80211_vif * vif)451 static void iwl_mvm_power_update_iterator(void *data, u8 *mac,
452 					  struct ieee80211_vif *vif)
453 {
454 	struct iwl_mvm *mvm = data;
455 
456 	iwl_mvm_power_update_mode(mvm, vif);
457 }
458 
iwl_mvm_mac_add_interface(struct ieee80211_hw * hw,struct ieee80211_vif * vif)459 static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
460 				     struct ieee80211_vif *vif)
461 {
462 	struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
463 	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
464 	int ret;
465 
466 	/*
467 	 * Not much to do here. The stack will not allow interface
468 	 * types or combinations that we didn't advertise, so we
469 	 * don't really have to check the types.
470 	 */
471 
472 	mutex_lock(&mvm->mutex);
473 
474 	/* Allocate resources for the MAC context, and add it the the fw  */
475 	ret = iwl_mvm_mac_ctxt_init(mvm, vif);
476 	if (ret)
477 		goto out_unlock;
478 
479 	/*
480 	 * The AP binding flow can be done only after the beacon
481 	 * template is configured (which happens only in the mac80211
482 	 * start_ap() flow), and adding the broadcast station can happen
483 	 * only after the binding.
484 	 * In addition, since modifying the MAC before adding a bcast
485 	 * station is not allowed by the FW, delay the adding of MAC context to
486 	 * the point where we can also add the bcast station.
487 	 * In short: there's not much we can do at this point, other than
488 	 * allocating resources :)
489 	 */
490 	if (vif->type == NL80211_IFTYPE_AP) {
491 		u32 qmask = iwl_mvm_mac_get_queues_mask(mvm, vif);
492 		ret = iwl_mvm_allocate_int_sta(mvm, &mvmvif->bcast_sta,
493 					       qmask);
494 		if (ret) {
495 			IWL_ERR(mvm, "Failed to allocate bcast sta\n");
496 			goto out_release;
497 		}
498 
499 		goto out_unlock;
500 	}
501 
502 	/*
503 	 * TODO: remove this temporary code.
504 	 * Currently MVM FW supports power management only on single MAC.
505 	 * If new interface added, disable PM on existing interface.
506 	 * P2P device is a special case, since it is handled by FW similary to
507 	 * scan. If P2P deviced is added, PM remains enabled on existing
508 	 * interface.
509 	 * Note: the method below does not count the new interface being added
510 	 * at this moment.
511 	 */
512 	if (vif->type != NL80211_IFTYPE_P2P_DEVICE)
513 		mvm->vif_count++;
514 	if (mvm->vif_count > 1) {
515 		IWL_DEBUG_MAC80211(mvm,
516 				   "Disable power on existing interfaces\n");
517 		ieee80211_iterate_active_interfaces_atomic(
518 					    mvm->hw,
519 					    IEEE80211_IFACE_ITER_NORMAL,
520 					    iwl_mvm_pm_disable_iterator, mvm);
521 	}
522 
523 	ret = iwl_mvm_mac_ctxt_add(mvm, vif);
524 	if (ret)
525 		goto out_release;
526 
527 	/*
528 	 * Update power state on the new interface. Admittedly, based on
529 	 * mac80211 logics this power update will disable power management
530 	 */
531 	iwl_mvm_power_update_mode(mvm, vif);
532 
533 	/*
534 	 * P2P_DEVICE interface does not have a channel context assigned to it,
535 	 * so a dedicated PHY context is allocated to it and the corresponding
536 	 * MAC context is bound to it at this stage.
537 	 */
538 	if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
539 		struct ieee80211_channel *chan;
540 		struct cfg80211_chan_def chandef;
541 
542 		mvmvif->phy_ctxt = &mvm->phy_ctxt_roc;
543 
544 		/*
545 		 * The channel used here isn't relevant as it's
546 		 * going to be overwritten as part of the ROC flow.
547 		 * For now use the first channel we have.
548 		 */
549 		chan = &mvm->hw->wiphy->bands[IEEE80211_BAND_2GHZ]->channels[0];
550 		cfg80211_chandef_create(&chandef, chan, NL80211_CHAN_NO_HT);
551 		ret = iwl_mvm_phy_ctxt_add(mvm, mvmvif->phy_ctxt,
552 					   &chandef, 1, 1);
553 		if (ret)
554 			goto out_remove_mac;
555 
556 		ret = iwl_mvm_binding_add_vif(mvm, vif);
557 		if (ret)
558 			goto out_remove_phy;
559 
560 		ret = iwl_mvm_add_bcast_sta(mvm, vif, &mvmvif->bcast_sta);
561 		if (ret)
562 			goto out_unbind;
563 
564 		/* Save a pointer to p2p device vif, so it can later be used to
565 		 * update the p2p device MAC when a GO is started/stopped */
566 		mvm->p2p_device_vif = vif;
567 	}
568 
569 	iwl_mvm_vif_dbgfs_register(mvm, vif);
570 	goto out_unlock;
571 
572  out_unbind:
573 	iwl_mvm_binding_remove_vif(mvm, vif);
574  out_remove_phy:
575 	iwl_mvm_phy_ctxt_remove(mvm, mvmvif->phy_ctxt);
576  out_remove_mac:
577 	mvmvif->phy_ctxt = NULL;
578 	iwl_mvm_mac_ctxt_remove(mvm, vif);
579  out_release:
580 	/*
581 	 * TODO: remove this temporary code.
582 	 * Currently MVM FW supports power management only on single MAC.
583 	 * Check if only one additional interface remains after releasing
584 	 * current one. Update power mode on the remaining interface.
585 	 */
586 	if (vif->type != NL80211_IFTYPE_P2P_DEVICE)
587 		mvm->vif_count--;
588 	IWL_DEBUG_MAC80211(mvm, "Currently %d interfaces active\n",
589 			   mvm->vif_count);
590 	if (mvm->vif_count == 1) {
591 		ieee80211_iterate_active_interfaces(
592 					mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
593 					iwl_mvm_power_update_iterator, mvm);
594 	}
595 	iwl_mvm_mac_ctxt_release(mvm, vif);
596  out_unlock:
597 	mutex_unlock(&mvm->mutex);
598 
599 	return ret;
600 }
601 
iwl_mvm_prepare_mac_removal(struct iwl_mvm * mvm,struct ieee80211_vif * vif)602 static void iwl_mvm_prepare_mac_removal(struct iwl_mvm *mvm,
603 					struct ieee80211_vif *vif)
604 {
605 	u32 tfd_msk = 0, ac;
606 
607 	for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
608 		if (vif->hw_queue[ac] != IEEE80211_INVAL_HW_QUEUE)
609 			tfd_msk |= BIT(vif->hw_queue[ac]);
610 
611 	if (vif->cab_queue != IEEE80211_INVAL_HW_QUEUE)
612 		tfd_msk |= BIT(vif->cab_queue);
613 
614 	if (tfd_msk) {
615 		mutex_lock(&mvm->mutex);
616 		iwl_mvm_flush_tx_path(mvm, tfd_msk, true);
617 		mutex_unlock(&mvm->mutex);
618 	}
619 
620 	if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
621 		/*
622 		 * Flush the ROC worker which will flush the OFFCHANNEL queue.
623 		 * We assume here that all the packets sent to the OFFCHANNEL
624 		 * queue are sent in ROC session.
625 		 */
626 		flush_work(&mvm->roc_done_wk);
627 	} else {
628 		/*
629 		 * By now, all the AC queues are empty. The AGG queues are
630 		 * empty too. We already got all the Tx responses for all the
631 		 * packets in the queues. The drain work can have been
632 		 * triggered. Flush it. This work item takes the mutex, so kill
633 		 * it before we take it.
634 		 */
635 		flush_work(&mvm->sta_drained_wk);
636 	}
637 }
638 
iwl_mvm_mac_remove_interface(struct ieee80211_hw * hw,struct ieee80211_vif * vif)639 static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw,
640 					 struct ieee80211_vif *vif)
641 {
642 	struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
643 	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
644 
645 	iwl_mvm_prepare_mac_removal(mvm, vif);
646 
647 	mutex_lock(&mvm->mutex);
648 
649 	iwl_mvm_vif_dbgfs_clean(mvm, vif);
650 
651 	/*
652 	 * For AP/GO interface, the tear down of the resources allocated to the
653 	 * interface is be handled as part of the stop_ap flow.
654 	 */
655 	if (vif->type == NL80211_IFTYPE_AP) {
656 		iwl_mvm_dealloc_int_sta(mvm, &mvmvif->bcast_sta);
657 		goto out_release;
658 	}
659 
660 	if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
661 		mvm->p2p_device_vif = NULL;
662 		iwl_mvm_rm_bcast_sta(mvm, &mvmvif->bcast_sta);
663 		iwl_mvm_binding_remove_vif(mvm, vif);
664 		iwl_mvm_phy_ctxt_remove(mvm, mvmvif->phy_ctxt);
665 		mvmvif->phy_ctxt = NULL;
666 	}
667 
668 	/*
669 	 * TODO: remove this temporary code.
670 	 * Currently MVM FW supports power management only on single MAC.
671 	 * Check if only one additional interface remains after removing
672 	 * current one. Update power mode on the remaining interface.
673 	 */
674 	if (mvm->vif_count && vif->type != NL80211_IFTYPE_P2P_DEVICE)
675 		mvm->vif_count--;
676 	IWL_DEBUG_MAC80211(mvm, "Currently %d interfaces active\n",
677 			   mvm->vif_count);
678 	if (mvm->vif_count == 1) {
679 		ieee80211_iterate_active_interfaces(
680 					mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
681 					iwl_mvm_power_update_iterator, mvm);
682 	}
683 
684 	iwl_mvm_mac_ctxt_remove(mvm, vif);
685 
686 out_release:
687 	iwl_mvm_mac_ctxt_release(mvm, vif);
688 	mutex_unlock(&mvm->mutex);
689 }
690 
iwl_mvm_mac_config(struct ieee80211_hw * hw,u32 changed)691 static int iwl_mvm_mac_config(struct ieee80211_hw *hw, u32 changed)
692 {
693 	return 0;
694 }
695 
iwl_mvm_configure_filter(struct ieee80211_hw * hw,unsigned int changed_flags,unsigned int * total_flags,u64 multicast)696 static void iwl_mvm_configure_filter(struct ieee80211_hw *hw,
697 				     unsigned int changed_flags,
698 				     unsigned int *total_flags,
699 				     u64 multicast)
700 {
701 	*total_flags = 0;
702 }
703 
iwl_mvm_configure_mcast_filter(struct iwl_mvm * mvm,struct ieee80211_vif * vif)704 static int iwl_mvm_configure_mcast_filter(struct iwl_mvm *mvm,
705 					  struct ieee80211_vif *vif)
706 {
707 	struct iwl_mcast_filter_cmd mcast_filter_cmd = {
708 		.pass_all = 1,
709 	};
710 
711 	memcpy(mcast_filter_cmd.bssid, vif->bss_conf.bssid, ETH_ALEN);
712 
713 	return iwl_mvm_send_cmd_pdu(mvm, MCAST_FILTER_CMD, CMD_SYNC,
714 				    sizeof(mcast_filter_cmd),
715 				    &mcast_filter_cmd);
716 }
717 
iwl_mvm_bss_info_changed_station(struct iwl_mvm * mvm,struct ieee80211_vif * vif,struct ieee80211_bss_conf * bss_conf,u32 changes)718 static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
719 					     struct ieee80211_vif *vif,
720 					     struct ieee80211_bss_conf *bss_conf,
721 					     u32 changes)
722 {
723 	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
724 	int ret;
725 
726 	ret = iwl_mvm_mac_ctxt_changed(mvm, vif);
727 	if (ret)
728 		IWL_ERR(mvm, "failed to update MAC %pM\n", vif->addr);
729 
730 	if (changes & BSS_CHANGED_ASSOC) {
731 		if (bss_conf->assoc) {
732 			/* add quota for this interface */
733 			ret = iwl_mvm_update_quotas(mvm, vif);
734 			if (ret) {
735 				IWL_ERR(mvm, "failed to update quotas\n");
736 				return;
737 			}
738 			iwl_mvm_bt_coex_vif_assoc(mvm, vif);
739 			iwl_mvm_configure_mcast_filter(mvm, vif);
740 		} else if (mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT) {
741 			/* remove AP station now that the MAC is unassoc */
742 			ret = iwl_mvm_rm_sta_id(mvm, vif, mvmvif->ap_sta_id);
743 			if (ret)
744 				IWL_ERR(mvm, "failed to remove AP station\n");
745 			mvmvif->ap_sta_id = IWL_MVM_STATION_COUNT;
746 			/* remove quota for this interface */
747 			ret = iwl_mvm_update_quotas(mvm, NULL);
748 			if (ret)
749 				IWL_ERR(mvm, "failed to update quotas\n");
750 		}
751 	} else if (changes & BSS_CHANGED_DTIM_PERIOD) {
752 		/*
753 		 * We received a beacon _after_ association so
754 		 * remove the session protection.
755 		 */
756 		iwl_mvm_remove_time_event(mvm, mvmvif,
757 					  &mvmvif->time_event_data);
758 	} else if (changes & BSS_CHANGED_PS) {
759 		/*
760 		 * TODO: remove this temporary code.
761 		 * Currently MVM FW supports power management only on single
762 		 * MAC. Avoid power mode update if more than one interface
763 		 * is active.
764 		 */
765 		IWL_DEBUG_MAC80211(mvm, "Currently %d interfaces active\n",
766 				   mvm->vif_count);
767 		if (mvm->vif_count == 1) {
768 			ret = iwl_mvm_power_update_mode(mvm, vif);
769 			if (ret)
770 				IWL_ERR(mvm, "failed to update power mode\n");
771 		}
772 	}
773 }
774 
iwl_mvm_start_ap(struct ieee80211_hw * hw,struct ieee80211_vif * vif)775 static int iwl_mvm_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
776 {
777 	struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
778 	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
779 	int ret;
780 
781 	mutex_lock(&mvm->mutex);
782 
783 	/* Send the beacon template */
784 	ret = iwl_mvm_mac_ctxt_beacon_changed(mvm, vif);
785 	if (ret)
786 		goto out_unlock;
787 
788 	/* Add the mac context */
789 	ret = iwl_mvm_mac_ctxt_add(mvm, vif);
790 	if (ret)
791 		goto out_unlock;
792 
793 	/* Perform the binding */
794 	ret = iwl_mvm_binding_add_vif(mvm, vif);
795 	if (ret)
796 		goto out_remove;
797 
798 	mvmvif->ap_active = true;
799 
800 	/* Send the bcast station. At this stage the TBTT and DTIM time events
801 	 * are added and applied to the scheduler */
802 	ret = iwl_mvm_send_bcast_sta(mvm, vif, &mvmvif->bcast_sta);
803 	if (ret)
804 		goto out_unbind;
805 
806 	ret = iwl_mvm_update_quotas(mvm, vif);
807 	if (ret)
808 		goto out_rm_bcast;
809 
810 	/* Need to update the P2P Device MAC */
811 	if (vif->p2p && mvm->p2p_device_vif)
812 		iwl_mvm_mac_ctxt_changed(mvm, mvm->p2p_device_vif);
813 
814 	mutex_unlock(&mvm->mutex);
815 	return 0;
816 
817 out_rm_bcast:
818 	iwl_mvm_send_rm_bcast_sta(mvm, &mvmvif->bcast_sta);
819 out_unbind:
820 	iwl_mvm_binding_remove_vif(mvm, vif);
821 out_remove:
822 	iwl_mvm_mac_ctxt_remove(mvm, vif);
823 out_unlock:
824 	mutex_unlock(&mvm->mutex);
825 	return ret;
826 }
827 
iwl_mvm_stop_ap(struct ieee80211_hw * hw,struct ieee80211_vif * vif)828 static void iwl_mvm_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
829 {
830 	struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
831 	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
832 
833 	iwl_mvm_prepare_mac_removal(mvm, vif);
834 
835 	mutex_lock(&mvm->mutex);
836 
837 	mvmvif->ap_active = false;
838 
839 	/* Need to update the P2P Device MAC */
840 	if (vif->p2p && mvm->p2p_device_vif)
841 		iwl_mvm_mac_ctxt_changed(mvm, mvm->p2p_device_vif);
842 
843 	iwl_mvm_update_quotas(mvm, NULL);
844 	iwl_mvm_send_rm_bcast_sta(mvm, &mvmvif->bcast_sta);
845 	iwl_mvm_binding_remove_vif(mvm, vif);
846 	iwl_mvm_mac_ctxt_remove(mvm, vif);
847 
848 	mutex_unlock(&mvm->mutex);
849 }
850 
iwl_mvm_bss_info_changed_ap(struct iwl_mvm * mvm,struct ieee80211_vif * vif,struct ieee80211_bss_conf * bss_conf,u32 changes)851 static void iwl_mvm_bss_info_changed_ap(struct iwl_mvm *mvm,
852 					struct ieee80211_vif *vif,
853 					struct ieee80211_bss_conf *bss_conf,
854 					u32 changes)
855 {
856 	/* Need to send a new beacon template to the FW */
857 	if (changes & BSS_CHANGED_BEACON) {
858 		if (iwl_mvm_mac_ctxt_beacon_changed(mvm, vif))
859 			IWL_WARN(mvm, "Failed updating beacon data\n");
860 	}
861 }
862 
iwl_mvm_bss_info_changed(struct ieee80211_hw * hw,struct ieee80211_vif * vif,struct ieee80211_bss_conf * bss_conf,u32 changes)863 static void iwl_mvm_bss_info_changed(struct ieee80211_hw *hw,
864 				     struct ieee80211_vif *vif,
865 				     struct ieee80211_bss_conf *bss_conf,
866 				     u32 changes)
867 {
868 	struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
869 
870 	mutex_lock(&mvm->mutex);
871 
872 	switch (vif->type) {
873 	case NL80211_IFTYPE_STATION:
874 		iwl_mvm_bss_info_changed_station(mvm, vif, bss_conf, changes);
875 		break;
876 	case NL80211_IFTYPE_AP:
877 		iwl_mvm_bss_info_changed_ap(mvm, vif, bss_conf, changes);
878 		break;
879 	default:
880 		/* shouldn't happen */
881 		WARN_ON_ONCE(1);
882 	}
883 
884 	mutex_unlock(&mvm->mutex);
885 }
886 
iwl_mvm_mac_hw_scan(struct ieee80211_hw * hw,struct ieee80211_vif * vif,struct cfg80211_scan_request * req)887 static int iwl_mvm_mac_hw_scan(struct ieee80211_hw *hw,
888 			       struct ieee80211_vif *vif,
889 			       struct cfg80211_scan_request *req)
890 {
891 	struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
892 	int ret;
893 
894 	if (req->n_channels == 0 || req->n_channels > MAX_NUM_SCAN_CHANNELS)
895 		return -EINVAL;
896 
897 	mutex_lock(&mvm->mutex);
898 
899 	if (mvm->scan_status == IWL_MVM_SCAN_NONE)
900 		ret = iwl_mvm_scan_request(mvm, vif, req);
901 	else
902 		ret = -EBUSY;
903 
904 	mutex_unlock(&mvm->mutex);
905 
906 	return ret;
907 }
908 
iwl_mvm_mac_cancel_hw_scan(struct ieee80211_hw * hw,struct ieee80211_vif * vif)909 static void iwl_mvm_mac_cancel_hw_scan(struct ieee80211_hw *hw,
910 				       struct ieee80211_vif *vif)
911 {
912 	struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
913 
914 	mutex_lock(&mvm->mutex);
915 
916 	iwl_mvm_cancel_scan(mvm);
917 
918 	mutex_unlock(&mvm->mutex);
919 }
920 
921 static void
iwl_mvm_mac_allow_buffered_frames(struct ieee80211_hw * hw,struct ieee80211_sta * sta,u16 tid,int num_frames,enum ieee80211_frame_release_type reason,bool more_data)922 iwl_mvm_mac_allow_buffered_frames(struct ieee80211_hw *hw,
923 				  struct ieee80211_sta *sta, u16 tid,
924 				  int num_frames,
925 				  enum ieee80211_frame_release_type reason,
926 				  bool more_data)
927 {
928 	struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
929 
930 	/* TODO: how do we tell the fw to send frames for a specific TID */
931 
932 	/*
933 	 * The fw will send EOSP notification when the last frame will be
934 	 * transmitted.
935 	 */
936 	iwl_mvm_sta_modify_sleep_tx_count(mvm, sta, reason, num_frames);
937 }
938 
iwl_mvm_mac_sta_notify(struct ieee80211_hw * hw,struct ieee80211_vif * vif,enum sta_notify_cmd cmd,struct ieee80211_sta * sta)939 static void iwl_mvm_mac_sta_notify(struct ieee80211_hw *hw,
940 				   struct ieee80211_vif *vif,
941 				   enum sta_notify_cmd cmd,
942 				   struct ieee80211_sta *sta)
943 {
944 	struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
945 	struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv;
946 
947 	switch (cmd) {
948 	case STA_NOTIFY_SLEEP:
949 		if (atomic_read(&mvm->pending_frames[mvmsta->sta_id]) > 0)
950 			ieee80211_sta_block_awake(hw, sta, true);
951 		/*
952 		 * The fw updates the STA to be asleep. Tx packets on the Tx
953 		 * queues to this station will not be transmitted. The fw will
954 		 * send a Tx response with TX_STATUS_FAIL_DEST_PS.
955 		 */
956 		break;
957 	case STA_NOTIFY_AWAKE:
958 		if (WARN_ON(mvmsta->sta_id == IWL_MVM_STATION_COUNT))
959 			break;
960 		iwl_mvm_sta_modify_ps_wake(mvm, sta);
961 		break;
962 	default:
963 		break;
964 	}
965 }
966 
iwl_mvm_mac_sta_state(struct ieee80211_hw * hw,struct ieee80211_vif * vif,struct ieee80211_sta * sta,enum ieee80211_sta_state old_state,enum ieee80211_sta_state new_state)967 static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
968 				 struct ieee80211_vif *vif,
969 				 struct ieee80211_sta *sta,
970 				 enum ieee80211_sta_state old_state,
971 				 enum ieee80211_sta_state new_state)
972 {
973 	struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
974 	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
975 	int ret;
976 
977 	IWL_DEBUG_MAC80211(mvm, "station %pM state change %d->%d\n",
978 			   sta->addr, old_state, new_state);
979 
980 	/* this would be a mac80211 bug ... but don't crash */
981 	if (WARN_ON_ONCE(!mvmvif->phy_ctxt))
982 		return -EINVAL;
983 
984 	/* if a STA is being removed, reuse its ID */
985 	flush_work(&mvm->sta_drained_wk);
986 
987 	mutex_lock(&mvm->mutex);
988 	if (old_state == IEEE80211_STA_NOTEXIST &&
989 	    new_state == IEEE80211_STA_NONE) {
990 		ret = iwl_mvm_add_sta(mvm, vif, sta);
991 	} else if (old_state == IEEE80211_STA_NONE &&
992 		   new_state == IEEE80211_STA_AUTH) {
993 		ret = 0;
994 	} else if (old_state == IEEE80211_STA_AUTH &&
995 		   new_state == IEEE80211_STA_ASSOC) {
996 		ret = iwl_mvm_update_sta(mvm, vif, sta);
997 		if (ret == 0)
998 			iwl_mvm_rs_rate_init(mvm, sta,
999 					     mvmvif->phy_ctxt->channel->band);
1000 	} else if (old_state == IEEE80211_STA_ASSOC &&
1001 		   new_state == IEEE80211_STA_AUTHORIZED) {
1002 		ret = 0;
1003 	} else if (old_state == IEEE80211_STA_AUTHORIZED &&
1004 		   new_state == IEEE80211_STA_ASSOC) {
1005 		ret = 0;
1006 	} else if (old_state == IEEE80211_STA_ASSOC &&
1007 		   new_state == IEEE80211_STA_AUTH) {
1008 		ret = 0;
1009 	} else if (old_state == IEEE80211_STA_AUTH &&
1010 		   new_state == IEEE80211_STA_NONE) {
1011 		ret = 0;
1012 	} else if (old_state == IEEE80211_STA_NONE &&
1013 		   new_state == IEEE80211_STA_NOTEXIST) {
1014 		ret = iwl_mvm_rm_sta(mvm, vif, sta);
1015 	} else {
1016 		ret = -EIO;
1017 	}
1018 	mutex_unlock(&mvm->mutex);
1019 
1020 	return ret;
1021 }
1022 
iwl_mvm_mac_set_rts_threshold(struct ieee80211_hw * hw,u32 value)1023 static int iwl_mvm_mac_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
1024 {
1025 	struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1026 
1027 	mvm->rts_threshold = value;
1028 
1029 	return 0;
1030 }
1031 
iwl_mvm_mac_conf_tx(struct ieee80211_hw * hw,struct ieee80211_vif * vif,u16 ac,const struct ieee80211_tx_queue_params * params)1032 static int iwl_mvm_mac_conf_tx(struct ieee80211_hw *hw,
1033 			       struct ieee80211_vif *vif, u16 ac,
1034 			       const struct ieee80211_tx_queue_params *params)
1035 {
1036 	struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1037 	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1038 
1039 	mvmvif->queue_params[ac] = *params;
1040 
1041 	/*
1042 	 * No need to update right away, we'll get BSS_CHANGED_QOS
1043 	 * The exception is P2P_DEVICE interface which needs immediate update.
1044 	 */
1045 	if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
1046 		int ret;
1047 
1048 		mutex_lock(&mvm->mutex);
1049 		ret = iwl_mvm_mac_ctxt_changed(mvm, vif);
1050 		mutex_unlock(&mvm->mutex);
1051 		return ret;
1052 	}
1053 	return 0;
1054 }
1055 
iwl_mvm_mac_mgd_prepare_tx(struct ieee80211_hw * hw,struct ieee80211_vif * vif)1056 static void iwl_mvm_mac_mgd_prepare_tx(struct ieee80211_hw *hw,
1057 				      struct ieee80211_vif *vif)
1058 {
1059 	struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1060 	u32 duration = min(IWL_MVM_TE_SESSION_PROTECTION_MAX_TIME_MS,
1061 			   200 + vif->bss_conf.beacon_int);
1062 	u32 min_duration = min(IWL_MVM_TE_SESSION_PROTECTION_MIN_TIME_MS,
1063 			       100 + vif->bss_conf.beacon_int);
1064 
1065 	if (WARN_ON_ONCE(vif->bss_conf.assoc))
1066 		return;
1067 
1068 	mutex_lock(&mvm->mutex);
1069 	/* Try really hard to protect the session and hear a beacon */
1070 	iwl_mvm_protect_session(mvm, vif, duration, min_duration);
1071 	mutex_unlock(&mvm->mutex);
1072 }
1073 
iwl_mvm_mac_set_key(struct ieee80211_hw * hw,enum set_key_cmd cmd,struct ieee80211_vif * vif,struct ieee80211_sta * sta,struct ieee80211_key_conf * key)1074 static int iwl_mvm_mac_set_key(struct ieee80211_hw *hw,
1075 			       enum set_key_cmd cmd,
1076 			       struct ieee80211_vif *vif,
1077 			       struct ieee80211_sta *sta,
1078 			       struct ieee80211_key_conf *key)
1079 {
1080 	struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1081 	int ret;
1082 
1083 	if (iwlwifi_mod_params.sw_crypto) {
1084 		IWL_DEBUG_MAC80211(mvm, "leave - hwcrypto disabled\n");
1085 		return -EOPNOTSUPP;
1086 	}
1087 
1088 	switch (key->cipher) {
1089 	case WLAN_CIPHER_SUITE_TKIP:
1090 		key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
1091 		/* fall-through */
1092 	case WLAN_CIPHER_SUITE_CCMP:
1093 		key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
1094 		break;
1095 	case WLAN_CIPHER_SUITE_AES_CMAC:
1096 		WARN_ON_ONCE(!(hw->flags & IEEE80211_HW_MFP_CAPABLE));
1097 		break;
1098 	case WLAN_CIPHER_SUITE_WEP40:
1099 	case WLAN_CIPHER_SUITE_WEP104:
1100 		/*
1101 		 * Support for TX only, at least for now, so accept
1102 		 * the key and do nothing else. Then mac80211 will
1103 		 * pass it for TX but we don't have to use it for RX.
1104 		 */
1105 		return 0;
1106 	default:
1107 		return -EOPNOTSUPP;
1108 	}
1109 
1110 	mutex_lock(&mvm->mutex);
1111 
1112 	switch (cmd) {
1113 	case SET_KEY:
1114 		if (vif->type == NL80211_IFTYPE_AP && !sta) {
1115 			/* GTK on AP interface is a TX-only key, return 0 */
1116 			ret = 0;
1117 			key->hw_key_idx = STA_KEY_IDX_INVALID;
1118 			break;
1119 		}
1120 
1121 		IWL_DEBUG_MAC80211(mvm, "set hwcrypto key\n");
1122 		ret = iwl_mvm_set_sta_key(mvm, vif, sta, key, false);
1123 		if (ret) {
1124 			IWL_WARN(mvm, "set key failed\n");
1125 			/*
1126 			 * can't add key for RX, but we don't need it
1127 			 * in the device for TX so still return 0
1128 			 */
1129 			key->hw_key_idx = STA_KEY_IDX_INVALID;
1130 			ret = 0;
1131 		}
1132 
1133 		break;
1134 	case DISABLE_KEY:
1135 		if (key->hw_key_idx == STA_KEY_IDX_INVALID) {
1136 			ret = 0;
1137 			break;
1138 		}
1139 
1140 		IWL_DEBUG_MAC80211(mvm, "disable hwcrypto key\n");
1141 		ret = iwl_mvm_remove_sta_key(mvm, vif, sta, key);
1142 		break;
1143 	default:
1144 		ret = -EINVAL;
1145 	}
1146 
1147 	mutex_unlock(&mvm->mutex);
1148 	return ret;
1149 }
1150 
iwl_mvm_mac_update_tkip_key(struct ieee80211_hw * hw,struct ieee80211_vif * vif,struct ieee80211_key_conf * keyconf,struct ieee80211_sta * sta,u32 iv32,u16 * phase1key)1151 static void iwl_mvm_mac_update_tkip_key(struct ieee80211_hw *hw,
1152 					struct ieee80211_vif *vif,
1153 					struct ieee80211_key_conf *keyconf,
1154 					struct ieee80211_sta *sta,
1155 					u32 iv32, u16 *phase1key)
1156 {
1157 	struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1158 
1159 	iwl_mvm_update_tkip_key(mvm, vif, keyconf, sta, iv32, phase1key);
1160 }
1161 
1162 
iwl_mvm_roc(struct ieee80211_hw * hw,struct ieee80211_vif * vif,struct ieee80211_channel * channel,int duration,enum ieee80211_roc_type type)1163 static int iwl_mvm_roc(struct ieee80211_hw *hw,
1164 		       struct ieee80211_vif *vif,
1165 		       struct ieee80211_channel *channel,
1166 		       int duration,
1167 		       enum ieee80211_roc_type type)
1168 {
1169 	struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1170 	struct cfg80211_chan_def chandef;
1171 	int ret;
1172 
1173 	if (vif->type != NL80211_IFTYPE_P2P_DEVICE) {
1174 		IWL_ERR(mvm, "vif isn't a P2P_DEVICE: %d\n", vif->type);
1175 		return -EINVAL;
1176 	}
1177 
1178 	IWL_DEBUG_MAC80211(mvm, "enter (%d, %d, %d)\n", channel->hw_value,
1179 			   duration, type);
1180 
1181 	mutex_lock(&mvm->mutex);
1182 
1183 	cfg80211_chandef_create(&chandef, channel, NL80211_CHAN_NO_HT);
1184 	ret = iwl_mvm_phy_ctxt_changed(mvm, &mvm->phy_ctxt_roc,
1185 				       &chandef, 1, 1);
1186 
1187 	/* Schedule the time events */
1188 	ret = iwl_mvm_start_p2p_roc(mvm, vif, duration, type);
1189 
1190 	mutex_unlock(&mvm->mutex);
1191 	IWL_DEBUG_MAC80211(mvm, "leave\n");
1192 
1193 	return ret;
1194 }
1195 
iwl_mvm_cancel_roc(struct ieee80211_hw * hw)1196 static int iwl_mvm_cancel_roc(struct ieee80211_hw *hw)
1197 {
1198 	struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1199 
1200 	IWL_DEBUG_MAC80211(mvm, "enter\n");
1201 
1202 	mutex_lock(&mvm->mutex);
1203 	iwl_mvm_stop_p2p_roc(mvm);
1204 	mutex_unlock(&mvm->mutex);
1205 
1206 	IWL_DEBUG_MAC80211(mvm, "leave\n");
1207 	return 0;
1208 }
1209 
iwl_mvm_add_chanctx(struct ieee80211_hw * hw,struct ieee80211_chanctx_conf * ctx)1210 static int iwl_mvm_add_chanctx(struct ieee80211_hw *hw,
1211 			       struct ieee80211_chanctx_conf *ctx)
1212 {
1213 	struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1214 	struct iwl_mvm_phy_ctxt *phy_ctxt = (void *)ctx->drv_priv;
1215 	int ret;
1216 
1217 	mutex_lock(&mvm->mutex);
1218 
1219 	IWL_DEBUG_MAC80211(mvm, "Add PHY context\n");
1220 	ret = iwl_mvm_phy_ctxt_add(mvm, phy_ctxt, &ctx->def,
1221 				   ctx->rx_chains_static,
1222 				   ctx->rx_chains_dynamic);
1223 	mutex_unlock(&mvm->mutex);
1224 	return ret;
1225 }
1226 
iwl_mvm_remove_chanctx(struct ieee80211_hw * hw,struct ieee80211_chanctx_conf * ctx)1227 static void iwl_mvm_remove_chanctx(struct ieee80211_hw *hw,
1228 				   struct ieee80211_chanctx_conf *ctx)
1229 {
1230 	struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1231 	struct iwl_mvm_phy_ctxt *phy_ctxt = (void *)ctx->drv_priv;
1232 
1233 	mutex_lock(&mvm->mutex);
1234 	iwl_mvm_phy_ctxt_remove(mvm, phy_ctxt);
1235 	mutex_unlock(&mvm->mutex);
1236 }
1237 
iwl_mvm_change_chanctx(struct ieee80211_hw * hw,struct ieee80211_chanctx_conf * ctx,u32 changed)1238 static void iwl_mvm_change_chanctx(struct ieee80211_hw *hw,
1239 				   struct ieee80211_chanctx_conf *ctx,
1240 				   u32 changed)
1241 {
1242 	struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1243 	struct iwl_mvm_phy_ctxt *phy_ctxt = (void *)ctx->drv_priv;
1244 
1245 	mutex_lock(&mvm->mutex);
1246 	iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, &ctx->def,
1247 				 ctx->rx_chains_static,
1248 				 ctx->rx_chains_dynamic);
1249 	mutex_unlock(&mvm->mutex);
1250 }
1251 
iwl_mvm_assign_vif_chanctx(struct ieee80211_hw * hw,struct ieee80211_vif * vif,struct ieee80211_chanctx_conf * ctx)1252 static int iwl_mvm_assign_vif_chanctx(struct ieee80211_hw *hw,
1253 				      struct ieee80211_vif *vif,
1254 				      struct ieee80211_chanctx_conf *ctx)
1255 {
1256 	struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1257 	struct iwl_mvm_phy_ctxt *phyctx = (void *)ctx->drv_priv;
1258 	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1259 	int ret;
1260 
1261 	mutex_lock(&mvm->mutex);
1262 
1263 	mvmvif->phy_ctxt = phyctx;
1264 
1265 	switch (vif->type) {
1266 	case NL80211_IFTYPE_AP:
1267 		/*
1268 		 * The AP binding flow is handled as part of the start_ap flow
1269 		 * (in bss_info_changed).
1270 		 */
1271 		ret = 0;
1272 		goto out_unlock;
1273 	case NL80211_IFTYPE_STATION:
1274 	case NL80211_IFTYPE_ADHOC:
1275 	case NL80211_IFTYPE_MONITOR:
1276 		break;
1277 	default:
1278 		ret = -EINVAL;
1279 		goto out_unlock;
1280 	}
1281 
1282 	ret = iwl_mvm_binding_add_vif(mvm, vif);
1283 	if (ret)
1284 		goto out_unlock;
1285 
1286 	/*
1287 	 * Setting the quota at this stage is only required for monitor
1288 	 * interfaces. For the other types, the bss_info changed flow
1289 	 * will handle quota settings.
1290 	 */
1291 	if (vif->type == NL80211_IFTYPE_MONITOR) {
1292 		mvmvif->monitor_active = true;
1293 		ret = iwl_mvm_update_quotas(mvm, vif);
1294 		if (ret)
1295 			goto out_remove_binding;
1296 	}
1297 
1298 	goto out_unlock;
1299 
1300  out_remove_binding:
1301 	iwl_mvm_binding_remove_vif(mvm, vif);
1302  out_unlock:
1303 	mutex_unlock(&mvm->mutex);
1304 	if (ret)
1305 		mvmvif->phy_ctxt = NULL;
1306 	return ret;
1307 }
1308 
iwl_mvm_unassign_vif_chanctx(struct ieee80211_hw * hw,struct ieee80211_vif * vif,struct ieee80211_chanctx_conf * ctx)1309 static void iwl_mvm_unassign_vif_chanctx(struct ieee80211_hw *hw,
1310 					 struct ieee80211_vif *vif,
1311 					 struct ieee80211_chanctx_conf *ctx)
1312 {
1313 	struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1314 	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1315 
1316 	mutex_lock(&mvm->mutex);
1317 
1318 	iwl_mvm_remove_time_event(mvm, mvmvif, &mvmvif->time_event_data);
1319 
1320 	if (vif->type == NL80211_IFTYPE_AP)
1321 		goto out_unlock;
1322 
1323 	switch (vif->type) {
1324 	case NL80211_IFTYPE_MONITOR:
1325 		mvmvif->monitor_active = false;
1326 		iwl_mvm_update_quotas(mvm, NULL);
1327 		break;
1328 	default:
1329 		break;
1330 	}
1331 
1332 	iwl_mvm_binding_remove_vif(mvm, vif);
1333 out_unlock:
1334 	mvmvif->phy_ctxt = NULL;
1335 	mutex_unlock(&mvm->mutex);
1336 }
1337 
iwl_mvm_set_tim(struct ieee80211_hw * hw,struct ieee80211_sta * sta,bool set)1338 static int iwl_mvm_set_tim(struct ieee80211_hw *hw,
1339 			   struct ieee80211_sta *sta,
1340 			   bool set)
1341 {
1342 	struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1343 	struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv;
1344 
1345 	if (!mvm_sta || !mvm_sta->vif) {
1346 		IWL_ERR(mvm, "Station is not associated to a vif\n");
1347 		return -EINVAL;
1348 	}
1349 
1350 	return iwl_mvm_mac_ctxt_beacon_changed(mvm, mvm_sta->vif);
1351 }
1352 
iwl_mvm_mac_rssi_callback(struct ieee80211_hw * hw,struct ieee80211_vif * vif,enum ieee80211_rssi_event rssi_event)1353 static void iwl_mvm_mac_rssi_callback(struct ieee80211_hw *hw,
1354 				      struct ieee80211_vif *vif,
1355 				      enum ieee80211_rssi_event rssi_event)
1356 {
1357 	struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1358 
1359 	iwl_mvm_bt_rssi_event(mvm, vif, rssi_event);
1360 }
1361 
1362 struct ieee80211_ops iwl_mvm_hw_ops = {
1363 	.tx = iwl_mvm_mac_tx,
1364 	.ampdu_action = iwl_mvm_mac_ampdu_action,
1365 	.start = iwl_mvm_mac_start,
1366 	.restart_complete = iwl_mvm_mac_restart_complete,
1367 	.stop = iwl_mvm_mac_stop,
1368 	.add_interface = iwl_mvm_mac_add_interface,
1369 	.remove_interface = iwl_mvm_mac_remove_interface,
1370 	.config = iwl_mvm_mac_config,
1371 	.configure_filter = iwl_mvm_configure_filter,
1372 	.bss_info_changed = iwl_mvm_bss_info_changed,
1373 	.hw_scan = iwl_mvm_mac_hw_scan,
1374 	.cancel_hw_scan = iwl_mvm_mac_cancel_hw_scan,
1375 	.sta_state = iwl_mvm_mac_sta_state,
1376 	.sta_notify = iwl_mvm_mac_sta_notify,
1377 	.allow_buffered_frames = iwl_mvm_mac_allow_buffered_frames,
1378 	.set_rts_threshold = iwl_mvm_mac_set_rts_threshold,
1379 	.conf_tx = iwl_mvm_mac_conf_tx,
1380 	.mgd_prepare_tx = iwl_mvm_mac_mgd_prepare_tx,
1381 	.set_key = iwl_mvm_mac_set_key,
1382 	.update_tkip_key = iwl_mvm_mac_update_tkip_key,
1383 	.remain_on_channel = iwl_mvm_roc,
1384 	.cancel_remain_on_channel = iwl_mvm_cancel_roc,
1385 	.rssi_callback = iwl_mvm_mac_rssi_callback,
1386 
1387 	.add_chanctx = iwl_mvm_add_chanctx,
1388 	.remove_chanctx = iwl_mvm_remove_chanctx,
1389 	.change_chanctx = iwl_mvm_change_chanctx,
1390 	.assign_vif_chanctx = iwl_mvm_assign_vif_chanctx,
1391 	.unassign_vif_chanctx = iwl_mvm_unassign_vif_chanctx,
1392 
1393 	.start_ap = iwl_mvm_start_ap,
1394 	.stop_ap = iwl_mvm_stop_ap,
1395 
1396 	.set_tim = iwl_mvm_set_tim,
1397 
1398 #ifdef CONFIG_PM_SLEEP
1399 	/* look at d3.c */
1400 	.suspend = iwl_mvm_suspend,
1401 	.resume = iwl_mvm_resume,
1402 	.set_wakeup = iwl_mvm_set_wakeup,
1403 	.set_rekey_data = iwl_mvm_set_rekey_data,
1404 #if IS_ENABLED(CONFIG_IPV6)
1405 	.ipv6_addr_change = iwl_mvm_ipv6_addr_change,
1406 #endif
1407 	.set_default_unicast_key = iwl_mvm_set_default_unicast_key,
1408 #endif
1409 };
1410