1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
2 /*
3 * Copyright (C) 2014 Intel Mobile Communications GmbH
4 * Copyright (C) 2017 Intel Deutschland GmbH
5 * Copyright (C) 2018-2020, 2022 Intel Corporation
6 */
7 #if defined(__FreeBSD__)
8 #include <linux/delay.h>
9 #endif
10 #include <linux/etherdevice.h>
11 #include "mvm.h"
12 #include "time-event.h"
13 #include "iwl-io.h"
14 #include "iwl-prph.h"
15
16 #define TU_TO_US(x) (x * 1024)
17 #define TU_TO_MS(x) (TU_TO_US(x) / 1000)
18
iwl_mvm_teardown_tdls_peers(struct iwl_mvm * mvm)19 void iwl_mvm_teardown_tdls_peers(struct iwl_mvm *mvm)
20 {
21 struct ieee80211_sta *sta;
22 struct iwl_mvm_sta *mvmsta;
23 int i;
24
25 lockdep_assert_held(&mvm->mutex);
26
27 for (i = 0; i < mvm->fw->ucode_capa.num_stations; i++) {
28 sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[i],
29 lockdep_is_held(&mvm->mutex));
30 if (!sta || IS_ERR(sta) || !sta->tdls)
31 continue;
32
33 mvmsta = iwl_mvm_sta_from_mac80211(sta);
34 ieee80211_tdls_oper_request(mvmsta->vif, sta->addr,
35 NL80211_TDLS_TEARDOWN,
36 WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED,
37 GFP_KERNEL);
38 }
39 }
40
iwl_mvm_tdls_sta_count(struct iwl_mvm * mvm,struct ieee80211_vif * vif)41 int iwl_mvm_tdls_sta_count(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
42 {
43 struct ieee80211_sta *sta;
44 struct iwl_mvm_sta *mvmsta;
45 int count = 0;
46 int i;
47
48 lockdep_assert_held(&mvm->mutex);
49
50 for (i = 0; i < mvm->fw->ucode_capa.num_stations; i++) {
51 sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[i],
52 lockdep_is_held(&mvm->mutex));
53 if (!sta || IS_ERR(sta) || !sta->tdls)
54 continue;
55
56 if (vif) {
57 mvmsta = iwl_mvm_sta_from_mac80211(sta);
58 if (mvmsta->vif != vif)
59 continue;
60 }
61
62 count++;
63 }
64
65 return count;
66 }
67
iwl_mvm_tdls_config(struct iwl_mvm * mvm,struct ieee80211_vif * vif)68 static void iwl_mvm_tdls_config(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
69 {
70 struct iwl_rx_packet *pkt;
71 struct iwl_tdls_config_res *resp;
72 struct iwl_tdls_config_cmd tdls_cfg_cmd = {};
73 struct iwl_host_cmd cmd = {
74 .id = TDLS_CONFIG_CMD,
75 .flags = CMD_WANT_SKB,
76 .data = { &tdls_cfg_cmd, },
77 .len = { sizeof(struct iwl_tdls_config_cmd), },
78 };
79 struct ieee80211_sta *sta;
80 int ret, i, cnt;
81 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
82
83 lockdep_assert_held(&mvm->mutex);
84
85 tdls_cfg_cmd.id_and_color =
86 cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color));
87 tdls_cfg_cmd.tx_to_ap_tid = IWL_MVM_TDLS_FW_TID;
88 tdls_cfg_cmd.tx_to_ap_ssn = cpu_to_le16(0); /* not used for now */
89
90 /* for now the Tx cmd is empty and unused */
91
92 /* populate TDLS peer data */
93 cnt = 0;
94 for (i = 0; i < mvm->fw->ucode_capa.num_stations; i++) {
95 sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[i],
96 lockdep_is_held(&mvm->mutex));
97 if (IS_ERR_OR_NULL(sta) || !sta->tdls)
98 continue;
99
100 tdls_cfg_cmd.sta_info[cnt].sta_id = i;
101 tdls_cfg_cmd.sta_info[cnt].tx_to_peer_tid =
102 IWL_MVM_TDLS_FW_TID;
103 tdls_cfg_cmd.sta_info[cnt].tx_to_peer_ssn = cpu_to_le16(0);
104 tdls_cfg_cmd.sta_info[cnt].is_initiator =
105 cpu_to_le32(sta->tdls_initiator ? 1 : 0);
106
107 cnt++;
108 }
109
110 tdls_cfg_cmd.tdls_peer_count = cnt;
111 IWL_DEBUG_TDLS(mvm, "send TDLS config to FW for %d peers\n", cnt);
112
113 ret = iwl_mvm_send_cmd(mvm, &cmd);
114 if (WARN_ON_ONCE(ret))
115 return;
116
117 pkt = cmd.resp_pkt;
118
119 WARN_ON_ONCE(iwl_rx_packet_payload_len(pkt) != sizeof(*resp));
120
121 /* we don't really care about the response at this point */
122
123 iwl_free_resp(&cmd);
124 }
125
iwl_mvm_recalc_tdls_state(struct iwl_mvm * mvm,struct ieee80211_vif * vif,bool sta_added)126 void iwl_mvm_recalc_tdls_state(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
127 bool sta_added)
128 {
129 int tdls_sta_cnt = iwl_mvm_tdls_sta_count(mvm, vif);
130
131 /* when the first peer joins, send a power update first */
132 if (tdls_sta_cnt == 1 && sta_added)
133 iwl_mvm_power_update_mac(mvm);
134
135 /* Configure the FW with TDLS peer info only if TDLS channel switch
136 * capability is set.
137 * TDLS config data is used currently only in TDLS channel switch code.
138 * Supposed to serve also TDLS buffer station which is not implemneted
139 * yet in FW*/
140 if (fw_has_capa(&mvm->fw->ucode_capa,
141 IWL_UCODE_TLV_CAPA_TDLS_CHANNEL_SWITCH))
142 iwl_mvm_tdls_config(mvm, vif);
143
144 /* when the last peer leaves, send a power update last */
145 if (tdls_sta_cnt == 0 && !sta_added)
146 iwl_mvm_power_update_mac(mvm);
147 }
148
iwl_mvm_mac_mgd_protect_tdls_discover(struct ieee80211_hw * hw,struct ieee80211_vif * vif)149 void iwl_mvm_mac_mgd_protect_tdls_discover(struct ieee80211_hw *hw,
150 struct ieee80211_vif *vif)
151 {
152 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
153 u32 duration = 2 * vif->bss_conf.dtim_period * vif->bss_conf.beacon_int;
154
155 /* Protect the session to hear the TDLS setup response on the channel */
156 mutex_lock(&mvm->mutex);
157 if (fw_has_capa(&mvm->fw->ucode_capa,
158 IWL_UCODE_TLV_CAPA_SESSION_PROT_CMD))
159 iwl_mvm_schedule_session_protection(mvm, vif, duration,
160 duration, true);
161 else
162 iwl_mvm_protect_session(mvm, vif, duration,
163 duration, 100, true);
164 mutex_unlock(&mvm->mutex);
165 }
166
167 static const char *
iwl_mvm_tdls_cs_state_str(enum iwl_mvm_tdls_cs_state state)168 iwl_mvm_tdls_cs_state_str(enum iwl_mvm_tdls_cs_state state)
169 {
170 switch (state) {
171 case IWL_MVM_TDLS_SW_IDLE:
172 return "IDLE";
173 case IWL_MVM_TDLS_SW_REQ_SENT:
174 return "REQ SENT";
175 case IWL_MVM_TDLS_SW_RESP_RCVD:
176 return "RESP RECEIVED";
177 case IWL_MVM_TDLS_SW_REQ_RCVD:
178 return "REQ RECEIVED";
179 case IWL_MVM_TDLS_SW_ACTIVE:
180 return "ACTIVE";
181 }
182
183 return NULL;
184 }
185
iwl_mvm_tdls_update_cs_state(struct iwl_mvm * mvm,enum iwl_mvm_tdls_cs_state state)186 static void iwl_mvm_tdls_update_cs_state(struct iwl_mvm *mvm,
187 enum iwl_mvm_tdls_cs_state state)
188 {
189 if (mvm->tdls_cs.state == state)
190 return;
191
192 IWL_DEBUG_TDLS(mvm, "TDLS channel switch state: %s -> %s\n",
193 iwl_mvm_tdls_cs_state_str(mvm->tdls_cs.state),
194 iwl_mvm_tdls_cs_state_str(state));
195 mvm->tdls_cs.state = state;
196
197 /* we only send requests to our switching peer - update sent time */
198 if (state == IWL_MVM_TDLS_SW_REQ_SENT)
199 mvm->tdls_cs.peer.sent_timestamp = iwl_mvm_get_systime(mvm);
200
201 if (state == IWL_MVM_TDLS_SW_IDLE)
202 mvm->tdls_cs.cur_sta_id = IWL_MVM_INVALID_STA;
203 }
204
iwl_mvm_rx_tdls_notif(struct iwl_mvm * mvm,struct iwl_rx_cmd_buffer * rxb)205 void iwl_mvm_rx_tdls_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb)
206 {
207 struct iwl_rx_packet *pkt = rxb_addr(rxb);
208 struct iwl_tdls_channel_switch_notif *notif = (void *)pkt->data;
209 struct ieee80211_sta *sta;
210 unsigned int delay;
211 struct iwl_mvm_sta *mvmsta;
212 struct ieee80211_vif *vif;
213 u32 sta_id = le32_to_cpu(notif->sta_id);
214
215 lockdep_assert_held(&mvm->mutex);
216
217 /* can fail sometimes */
218 if (!le32_to_cpu(notif->status)) {
219 iwl_mvm_tdls_update_cs_state(mvm, IWL_MVM_TDLS_SW_IDLE);
220 return;
221 }
222
223 if (WARN_ON(sta_id >= mvm->fw->ucode_capa.num_stations))
224 return;
225
226 sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[sta_id],
227 lockdep_is_held(&mvm->mutex));
228 /* the station may not be here, but if it is, it must be a TDLS peer */
229 if (IS_ERR_OR_NULL(sta) || WARN_ON(!sta->tdls))
230 return;
231
232 mvmsta = iwl_mvm_sta_from_mac80211(sta);
233 vif = mvmsta->vif;
234
235 /*
236 * Update state and possibly switch again after this is over (DTIM).
237 * Also convert TU to msec.
238 */
239 delay = TU_TO_MS(vif->bss_conf.dtim_period * vif->bss_conf.beacon_int);
240 mod_delayed_work(system_wq, &mvm->tdls_cs.dwork,
241 msecs_to_jiffies(delay));
242
243 iwl_mvm_tdls_update_cs_state(mvm, IWL_MVM_TDLS_SW_ACTIVE);
244 }
245
246 static int
iwl_mvm_tdls_check_action(struct iwl_mvm * mvm,enum iwl_tdls_channel_switch_type type,const u8 * peer,bool peer_initiator,u32 timestamp)247 iwl_mvm_tdls_check_action(struct iwl_mvm *mvm,
248 enum iwl_tdls_channel_switch_type type,
249 const u8 *peer, bool peer_initiator, u32 timestamp)
250 {
251 bool same_peer = false;
252 int ret = 0;
253
254 /* get the existing peer if it's there */
255 if (mvm->tdls_cs.state != IWL_MVM_TDLS_SW_IDLE &&
256 mvm->tdls_cs.cur_sta_id != IWL_MVM_INVALID_STA) {
257 struct ieee80211_sta *sta = rcu_dereference_protected(
258 mvm->fw_id_to_mac_id[mvm->tdls_cs.cur_sta_id],
259 lockdep_is_held(&mvm->mutex));
260 if (!IS_ERR_OR_NULL(sta))
261 same_peer = ether_addr_equal(peer, sta->addr);
262 }
263
264 switch (mvm->tdls_cs.state) {
265 case IWL_MVM_TDLS_SW_IDLE:
266 /*
267 * might be spurious packet from the peer after the switch is
268 * already done
269 */
270 if (type == TDLS_MOVE_CH)
271 ret = -EINVAL;
272 break;
273 case IWL_MVM_TDLS_SW_REQ_SENT:
274 /* only allow requests from the same peer */
275 if (!same_peer)
276 ret = -EBUSY;
277 else if (type == TDLS_SEND_CHAN_SW_RESP_AND_MOVE_CH &&
278 !peer_initiator)
279 /*
280 * We received a ch-switch request while an outgoing
281 * one is pending. Allow it if the peer is the link
282 * initiator.
283 */
284 ret = -EBUSY;
285 else if (type == TDLS_SEND_CHAN_SW_REQ)
286 /* wait for idle before sending another request */
287 ret = -EBUSY;
288 else if (timestamp <= mvm->tdls_cs.peer.sent_timestamp)
289 /* we got a stale response - ignore it */
290 ret = -EINVAL;
291 break;
292 case IWL_MVM_TDLS_SW_RESP_RCVD:
293 /*
294 * we are waiting for the FW to give an "active" notification,
295 * so ignore requests in the meantime
296 */
297 ret = -EBUSY;
298 break;
299 case IWL_MVM_TDLS_SW_REQ_RCVD:
300 /* as above, allow the link initiator to proceed */
301 if (type == TDLS_SEND_CHAN_SW_REQ) {
302 if (!same_peer)
303 ret = -EBUSY;
304 else if (peer_initiator) /* they are the initiator */
305 ret = -EBUSY;
306 } else if (type == TDLS_MOVE_CH) {
307 ret = -EINVAL;
308 }
309 break;
310 case IWL_MVM_TDLS_SW_ACTIVE:
311 /*
312 * the only valid request when active is a request to return
313 * to the base channel by the current off-channel peer
314 */
315 if (type != TDLS_MOVE_CH || !same_peer)
316 ret = -EBUSY;
317 break;
318 }
319
320 if (ret)
321 IWL_DEBUG_TDLS(mvm,
322 "Invalid TDLS action %d state %d peer %pM same_peer %d initiator %d\n",
323 type, mvm->tdls_cs.state, peer, same_peer,
324 peer_initiator);
325
326 return ret;
327 }
328
329 static int
iwl_mvm_tdls_config_channel_switch(struct iwl_mvm * mvm,struct ieee80211_vif * vif,enum iwl_tdls_channel_switch_type type,const u8 * peer,bool peer_initiator,u8 oper_class,struct cfg80211_chan_def * chandef,u32 timestamp,u16 switch_time,u16 switch_timeout,struct sk_buff * skb,u32 ch_sw_tm_ie)330 iwl_mvm_tdls_config_channel_switch(struct iwl_mvm *mvm,
331 struct ieee80211_vif *vif,
332 enum iwl_tdls_channel_switch_type type,
333 const u8 *peer, bool peer_initiator,
334 u8 oper_class,
335 struct cfg80211_chan_def *chandef,
336 u32 timestamp, u16 switch_time,
337 u16 switch_timeout, struct sk_buff *skb,
338 u32 ch_sw_tm_ie)
339 {
340 struct ieee80211_sta *sta;
341 struct iwl_mvm_sta *mvmsta;
342 struct ieee80211_tx_info *info;
343 struct ieee80211_hdr *hdr;
344 struct iwl_tdls_channel_switch_cmd cmd = {0};
345 struct iwl_tdls_channel_switch_cmd_tail *tail =
346 iwl_mvm_chan_info_cmd_tail(mvm, &cmd.ci);
347 u16 len = sizeof(cmd) - iwl_mvm_chan_info_padding(mvm);
348 int ret;
349
350 lockdep_assert_held(&mvm->mutex);
351
352 ret = iwl_mvm_tdls_check_action(mvm, type, peer, peer_initiator,
353 timestamp);
354 if (ret)
355 return ret;
356
357 if (!skb || WARN_ON(skb->len > IWL_TDLS_CH_SW_FRAME_MAX_SIZE)) {
358 ret = -EINVAL;
359 goto out;
360 }
361
362 cmd.switch_type = type;
363 tail->timing.frame_timestamp = cpu_to_le32(timestamp);
364 tail->timing.switch_time = cpu_to_le32(switch_time);
365 tail->timing.switch_timeout = cpu_to_le32(switch_timeout);
366
367 rcu_read_lock();
368 sta = ieee80211_find_sta(vif, peer);
369 if (!sta) {
370 rcu_read_unlock();
371 ret = -ENOENT;
372 goto out;
373 }
374 mvmsta = iwl_mvm_sta_from_mac80211(sta);
375 cmd.peer_sta_id = cpu_to_le32(mvmsta->deflink.sta_id);
376
377 if (!chandef) {
378 if (mvm->tdls_cs.state == IWL_MVM_TDLS_SW_REQ_SENT &&
379 mvm->tdls_cs.peer.chandef.chan) {
380 /* actually moving to the channel */
381 chandef = &mvm->tdls_cs.peer.chandef;
382 } else if (mvm->tdls_cs.state == IWL_MVM_TDLS_SW_ACTIVE &&
383 type == TDLS_MOVE_CH) {
384 /* we need to return to base channel */
385 struct ieee80211_chanctx_conf *chanctx =
386 rcu_dereference(vif->bss_conf.chanctx_conf);
387
388 if (WARN_ON_ONCE(!chanctx)) {
389 rcu_read_unlock();
390 goto out;
391 }
392
393 chandef = &chanctx->def;
394 }
395 }
396
397 if (chandef)
398 iwl_mvm_set_chan_info_chandef(mvm, &cmd.ci, chandef);
399
400 /* keep quota calculation simple for now - 50% of DTIM for TDLS */
401 tail->timing.max_offchan_duration =
402 cpu_to_le32(TU_TO_US(vif->bss_conf.dtim_period *
403 vif->bss_conf.beacon_int) / 2);
404
405 /* Switch time is the first element in the switch-timing IE. */
406 tail->frame.switch_time_offset = cpu_to_le32(ch_sw_tm_ie + 2);
407
408 info = IEEE80211_SKB_CB(skb);
409 hdr = (void *)skb->data;
410 if (info->control.hw_key) {
411 if (info->control.hw_key->cipher != WLAN_CIPHER_SUITE_CCMP) {
412 rcu_read_unlock();
413 ret = -EINVAL;
414 goto out;
415 }
416 iwl_mvm_set_tx_cmd_ccmp(info, &tail->frame.tx_cmd);
417 }
418
419 iwl_mvm_set_tx_cmd(mvm, skb, &tail->frame.tx_cmd, info,
420 mvmsta->deflink.sta_id);
421
422 iwl_mvm_set_tx_cmd_rate(mvm, &tail->frame.tx_cmd, info, sta,
423 hdr->frame_control);
424 rcu_read_unlock();
425
426 memcpy(tail->frame.data, skb->data, skb->len);
427
428 ret = iwl_mvm_send_cmd_pdu(mvm, TDLS_CHANNEL_SWITCH_CMD, 0, len, &cmd);
429 if (ret) {
430 IWL_ERR(mvm, "Failed to send TDLS_CHANNEL_SWITCH cmd: %d\n",
431 ret);
432 goto out;
433 }
434
435 /* channel switch has started, update state */
436 if (type != TDLS_MOVE_CH) {
437 mvm->tdls_cs.cur_sta_id = mvmsta->deflink.sta_id;
438 iwl_mvm_tdls_update_cs_state(mvm,
439 type == TDLS_SEND_CHAN_SW_REQ ?
440 IWL_MVM_TDLS_SW_REQ_SENT :
441 IWL_MVM_TDLS_SW_REQ_RCVD);
442 } else {
443 iwl_mvm_tdls_update_cs_state(mvm, IWL_MVM_TDLS_SW_RESP_RCVD);
444 }
445
446 out:
447
448 /* channel switch failed - we are idle */
449 if (ret)
450 iwl_mvm_tdls_update_cs_state(mvm, IWL_MVM_TDLS_SW_IDLE);
451
452 return ret;
453 }
454
iwl_mvm_tdls_ch_switch_work(struct work_struct * work)455 void iwl_mvm_tdls_ch_switch_work(struct work_struct *work)
456 {
457 struct iwl_mvm *mvm;
458 struct ieee80211_sta *sta;
459 struct iwl_mvm_sta *mvmsta;
460 struct ieee80211_vif *vif;
461 unsigned int delay;
462 int ret;
463
464 mvm = container_of(work, struct iwl_mvm, tdls_cs.dwork.work);
465 mutex_lock(&mvm->mutex);
466
467 /* called after an active channel switch has finished or timed-out */
468 iwl_mvm_tdls_update_cs_state(mvm, IWL_MVM_TDLS_SW_IDLE);
469
470 /* station might be gone, in that case do nothing */
471 if (mvm->tdls_cs.peer.sta_id == IWL_MVM_INVALID_STA)
472 goto out;
473
474 sta = rcu_dereference_protected(
475 mvm->fw_id_to_mac_id[mvm->tdls_cs.peer.sta_id],
476 lockdep_is_held(&mvm->mutex));
477 /* the station may not be here, but if it is, it must be a TDLS peer */
478 if (!sta || IS_ERR(sta) || WARN_ON(!sta->tdls))
479 goto out;
480
481 mvmsta = iwl_mvm_sta_from_mac80211(sta);
482 vif = mvmsta->vif;
483 ret = iwl_mvm_tdls_config_channel_switch(mvm, vif,
484 TDLS_SEND_CHAN_SW_REQ,
485 sta->addr,
486 mvm->tdls_cs.peer.initiator,
487 mvm->tdls_cs.peer.op_class,
488 &mvm->tdls_cs.peer.chandef,
489 0, 0, 0,
490 mvm->tdls_cs.peer.skb,
491 mvm->tdls_cs.peer.ch_sw_tm_ie);
492 if (ret)
493 IWL_ERR(mvm, "Not sending TDLS channel switch: %d\n", ret);
494
495 /* retry after a DTIM if we failed sending now */
496 delay = TU_TO_MS(vif->bss_conf.dtim_period * vif->bss_conf.beacon_int);
497 schedule_delayed_work(&mvm->tdls_cs.dwork, msecs_to_jiffies(delay));
498 out:
499 mutex_unlock(&mvm->mutex);
500 }
501
502 int
iwl_mvm_tdls_channel_switch(struct ieee80211_hw * hw,struct ieee80211_vif * vif,struct ieee80211_sta * sta,u8 oper_class,struct cfg80211_chan_def * chandef,struct sk_buff * tmpl_skb,u32 ch_sw_tm_ie)503 iwl_mvm_tdls_channel_switch(struct ieee80211_hw *hw,
504 struct ieee80211_vif *vif,
505 struct ieee80211_sta *sta, u8 oper_class,
506 struct cfg80211_chan_def *chandef,
507 struct sk_buff *tmpl_skb, u32 ch_sw_tm_ie)
508 {
509 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
510 struct iwl_mvm_sta *mvmsta;
511 unsigned int delay;
512 int ret;
513
514 mutex_lock(&mvm->mutex);
515
516 IWL_DEBUG_TDLS(mvm, "TDLS channel switch with %pM ch %d width %d\n",
517 sta->addr, chandef->chan->center_freq, chandef->width);
518
519 /* we only support a single peer for channel switching */
520 if (mvm->tdls_cs.peer.sta_id != IWL_MVM_INVALID_STA) {
521 IWL_DEBUG_TDLS(mvm,
522 "Existing peer. Can't start switch with %pM\n",
523 sta->addr);
524 ret = -EBUSY;
525 goto out;
526 }
527
528 ret = iwl_mvm_tdls_config_channel_switch(mvm, vif,
529 TDLS_SEND_CHAN_SW_REQ,
530 sta->addr, sta->tdls_initiator,
531 oper_class, chandef, 0, 0, 0,
532 tmpl_skb, ch_sw_tm_ie);
533 if (ret)
534 goto out;
535
536 /*
537 * Mark the peer as "in tdls switch" for this vif. We only allow a
538 * single such peer per vif.
539 */
540 mvm->tdls_cs.peer.skb = skb_copy(tmpl_skb, GFP_KERNEL);
541 if (!mvm->tdls_cs.peer.skb) {
542 ret = -ENOMEM;
543 goto out;
544 }
545
546 mvmsta = iwl_mvm_sta_from_mac80211(sta);
547 mvm->tdls_cs.peer.sta_id = mvmsta->deflink.sta_id;
548 mvm->tdls_cs.peer.chandef = *chandef;
549 mvm->tdls_cs.peer.initiator = sta->tdls_initiator;
550 mvm->tdls_cs.peer.op_class = oper_class;
551 mvm->tdls_cs.peer.ch_sw_tm_ie = ch_sw_tm_ie;
552
553 /*
554 * Wait for 2 DTIM periods before attempting the next switch. The next
555 * switch will be made sooner if the current one completes before that.
556 */
557 delay = 2 * TU_TO_MS(vif->bss_conf.dtim_period *
558 vif->bss_conf.beacon_int);
559 mod_delayed_work(system_wq, &mvm->tdls_cs.dwork,
560 msecs_to_jiffies(delay));
561
562 out:
563 mutex_unlock(&mvm->mutex);
564 return ret;
565 }
566
iwl_mvm_tdls_cancel_channel_switch(struct ieee80211_hw * hw,struct ieee80211_vif * vif,struct ieee80211_sta * sta)567 void iwl_mvm_tdls_cancel_channel_switch(struct ieee80211_hw *hw,
568 struct ieee80211_vif *vif,
569 struct ieee80211_sta *sta)
570 {
571 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
572 struct ieee80211_sta *cur_sta;
573 bool wait_for_phy = false;
574
575 mutex_lock(&mvm->mutex);
576
577 IWL_DEBUG_TDLS(mvm, "TDLS cancel channel switch with %pM\n", sta->addr);
578
579 /* we only support a single peer for channel switching */
580 if (mvm->tdls_cs.peer.sta_id == IWL_MVM_INVALID_STA) {
581 IWL_DEBUG_TDLS(mvm, "No ch switch peer - %pM\n", sta->addr);
582 goto out;
583 }
584
585 cur_sta = rcu_dereference_protected(
586 mvm->fw_id_to_mac_id[mvm->tdls_cs.peer.sta_id],
587 lockdep_is_held(&mvm->mutex));
588 /* make sure it's the same peer */
589 if (cur_sta != sta)
590 goto out;
591
592 /*
593 * If we're currently in a switch because of the now canceled peer,
594 * wait a DTIM here to make sure the phy is back on the base channel.
595 * We can't otherwise force it.
596 */
597 if (mvm->tdls_cs.cur_sta_id == mvm->tdls_cs.peer.sta_id &&
598 mvm->tdls_cs.state != IWL_MVM_TDLS_SW_IDLE)
599 wait_for_phy = true;
600
601 mvm->tdls_cs.peer.sta_id = IWL_MVM_INVALID_STA;
602 dev_kfree_skb(mvm->tdls_cs.peer.skb);
603 mvm->tdls_cs.peer.skb = NULL;
604
605 out:
606 mutex_unlock(&mvm->mutex);
607
608 /* make sure the phy is on the base channel */
609 if (wait_for_phy)
610 #if defined(__linux__)
611 msleep(TU_TO_MS(vif->bss_conf.dtim_period *
612 #elif defined(__FreeBSD__)
613 linux_msleep(TU_TO_MS(vif->bss_conf.dtim_period *
614 #endif
615 vif->bss_conf.beacon_int));
616
617 /* flush the channel switch state */
618 flush_delayed_work(&mvm->tdls_cs.dwork);
619
620 IWL_DEBUG_TDLS(mvm, "TDLS ending channel switch with %pM\n", sta->addr);
621 }
622
623 void
iwl_mvm_tdls_recv_channel_switch(struct ieee80211_hw * hw,struct ieee80211_vif * vif,struct ieee80211_tdls_ch_sw_params * params)624 iwl_mvm_tdls_recv_channel_switch(struct ieee80211_hw *hw,
625 struct ieee80211_vif *vif,
626 struct ieee80211_tdls_ch_sw_params *params)
627 {
628 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
629 enum iwl_tdls_channel_switch_type type;
630 unsigned int delay;
631 const char *action_str =
632 params->action_code == WLAN_TDLS_CHANNEL_SWITCH_REQUEST ?
633 "REQ" : "RESP";
634
635 mutex_lock(&mvm->mutex);
636
637 IWL_DEBUG_TDLS(mvm,
638 "Received TDLS ch switch action %s from %pM status %d\n",
639 action_str, params->sta->addr, params->status);
640
641 /*
642 * we got a non-zero status from a peer we were switching to - move to
643 * the idle state and retry again later
644 */
645 if (params->action_code == WLAN_TDLS_CHANNEL_SWITCH_RESPONSE &&
646 params->status != 0 &&
647 mvm->tdls_cs.state == IWL_MVM_TDLS_SW_REQ_SENT &&
648 mvm->tdls_cs.cur_sta_id != IWL_MVM_INVALID_STA) {
649 struct ieee80211_sta *cur_sta;
650
651 /* make sure it's the same peer */
652 cur_sta = rcu_dereference_protected(
653 mvm->fw_id_to_mac_id[mvm->tdls_cs.cur_sta_id],
654 lockdep_is_held(&mvm->mutex));
655 if (cur_sta == params->sta) {
656 iwl_mvm_tdls_update_cs_state(mvm,
657 IWL_MVM_TDLS_SW_IDLE);
658 goto retry;
659 }
660 }
661
662 type = (params->action_code == WLAN_TDLS_CHANNEL_SWITCH_REQUEST) ?
663 TDLS_SEND_CHAN_SW_RESP_AND_MOVE_CH : TDLS_MOVE_CH;
664
665 iwl_mvm_tdls_config_channel_switch(mvm, vif, type, params->sta->addr,
666 params->sta->tdls_initiator, 0,
667 params->chandef, params->timestamp,
668 params->switch_time,
669 params->switch_timeout,
670 params->tmpl_skb,
671 params->ch_sw_tm_ie);
672
673 retry:
674 /* register a timeout in case we don't succeed in switching */
675 delay = vif->bss_conf.dtim_period * vif->bss_conf.beacon_int *
676 1024 / 1000;
677 mod_delayed_work(system_wq, &mvm->tdls_cs.dwork,
678 msecs_to_jiffies(delay));
679 mutex_unlock(&mvm->mutex);
680 }
681