Lines Matching +full:queue +full:- +full:pkt +full:- +full:tx

1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
3 * Copyright (C) 2012-2014, 2018-2024 Intel Corporation
4 * Copyright (C) 2013-2015 Intel Mobile Communications GmbH
10 #include "fw/notif-wait.h"
11 #include "iwl-trans.h"
12 #include "fw-api.h"
13 #include "time-event.h"
15 #include "iwl-io.h"
16 #include "iwl-prph.h"
28 lockdep_assert_held(&mvm->time_event_lock);
30 if (!te_data || !te_data->vif)
33 list_del(&te_data->list);
39 INIT_LIST_HEAD(&te_data->list);
41 te_data->running = false;
42 te_data->uid = 0;
43 te_data->id = TE_MAX;
44 te_data->vif = NULL;
45 te_data->link_id = -1;
51 struct ieee80211_vif *vif = mvm->p2p_device_vif;
53 lockdep_assert_held(&mvm->mutex);
57 * This will cause the TX path to drop offchannel transmissions.
61 * Also flush the offchannel queue -- this is called when the time
63 * won't get stuck on the queue and be transmitted in the next
66 if (test_and_clear_bit(IWL_MVM_STATUS_ROC_P2P_RUNNING, &mvm->status)) {
73 * can only be set when we had a P2P-Device VIF, and we have a
80 iwl_mvm_flush_sta(mvm, mvmvif->deflink.bcast_sta.sta_id,
81 mvmvif->deflink.bcast_sta.tfd_queue_msk);
83 if (mvm->mld_api_is_used) {
85 &vif->bss_conf);
87 iwl_mvm_link_changed(mvm, vif, &vif->bss_conf,
106 * This will cause the TX path to drop offchannel transmissions.
111 if (test_and_clear_bit(IWL_MVM_STATUS_ROC_AUX_RUNNING, &mvm->status)) {
114 iwl_mvm_flush_sta(mvm, mvm->aux_sta.sta_id,
115 mvm->aux_sta.tfd_queue_msk);
117 if (mvm->mld_api_is_used) {
119 mutex_unlock(&mvm->mutex);
124 * in cases of dedicated tx queue and need to be removed in end
126 if (iwl_mvm_has_new_station_api(mvm->fw))
132 mutex_unlock(&mvm->mutex);
139 mutex_lock(&mvm->mutex);
150 * it will of course synchronize the TX path to make sure that
151 * any *new* TX will be rejected.
153 schedule_work(&mvm->roc_done_wk);
162 csa_vif = rcu_dereference(mvm->csa_vif);
163 if (!csa_vif || !csa_vif->bss_conf.csa_active)
183 RCU_INIT_POINTER(mvm->csa_vif, NULL);
197 if (vif->type != NL80211_IFTYPE_STATION)
200 if (!mvmvif->csa_bcn_pending && vif->cfg.assoc &&
201 vif->bss_conf.dtim_period)
206 if (mvmvif->csa_bcn_pending) {
211 mvmvif->deflink.ap_sta_id);
217 if (vif->cfg.assoc) {
222 iwl_dbg_tlv_time_point(&mvm->fwrt,
226 mvmvif->session_prot_connection_loss = true;
238 struct ieee80211_vif *vif = te_data->vif;
241 if (!notif->status)
244 switch (te_data->vif->type) {
246 if (!notif->status)
247 mvmvif->csa_failed = true;
251 if (!notif->status) {
256 iwl_mvm_csa_client_absent(mvm, te_data->vif);
257 cancel_delayed_work(&mvmvif->csa_work);
258 ieee80211_chswitch_done(te_data->vif, true, 0);
278 trig = iwl_fw_dbg_trigger_on(&mvm->fwrt,
279 ieee80211_vif_to_wdev(te_data->vif),
284 te_trig = (void *)trig->data;
286 for (i = 0; i < ARRAY_SIZE(te_trig->time_events); i++) {
287 u32 trig_te_id = le32_to_cpu(te_trig->time_events[i].id);
289 le32_to_cpu(te_trig->time_events[i].action_bitmap);
291 le32_to_cpu(te_trig->time_events[i].status_bitmap);
293 if (trig_te_id != te_data->id ||
294 !(trig_action_bitmap & le32_to_cpu(notif->action)) ||
295 !(trig_status_bitmap & BIT(le32_to_cpu(notif->status))))
298 iwl_fw_dbg_collect_trig(&mvm->fwrt, trig,
300 te_data->id,
301 le32_to_cpu(notif->action),
302 le32_to_cpu(notif->status));
318 lockdep_assert_held(&mvm->time_event_lock);
320 IWL_DEBUG_TE(mvm, "Handle time event notif - UID = 0x%x action %d\n",
321 le32_to_cpu(notif->unique_id),
322 le32_to_cpu(notif->action));
334 if (!le32_to_cpu(notif->status)) {
337 if (notif->action & cpu_to_le32(TE_V2_NOTIF_HOST_EVENT_START))
344 if (iwl_mvm_te_check_disconnect(mvm, te_data->vif, msg)) {
350 if (le32_to_cpu(notif->action) & TE_V2_NOTIF_HOST_EVENT_END) {
352 "TE ended - current time %lu, estimated end %lu\n",
353 jiffies, te_data->end_jiffies);
355 switch (te_data->vif->type) {
357 ieee80211_remain_on_channel_expired(mvm->hw);
366 if (te_data->id == TE_CHANNEL_SWITCH_PERIOD) {
376 iwl_mvm_te_check_disconnect(mvm, te_data->vif,
377 !te_data->vif->cfg.assoc ?
386 } else if (le32_to_cpu(notif->action) & TE_V2_NOTIF_HOST_EVENT_START) {
387 te_data->running = true;
388 te_data->end_jiffies = TU_TO_EXP_TIME(te_data->duration);
390 if (te_data->vif->type == NL80211_IFTYPE_P2P_DEVICE) {
391 set_bit(IWL_MVM_STATUS_ROC_P2P_RUNNING, &mvm->status);
392 ieee80211_ready_on_channel(mvm->hw);
393 } else if (te_data->id == TE_CHANNEL_SWITCH_PERIOD) {
413 if (mvmvif->roc_activity == data->activity) {
414 data->found = true;
415 if (data->end_activity)
416 mvmvif->roc_activity = ROC_NUM_ACTIVITIES;
423 struct iwl_rx_packet *pkt = rxb_addr(rxb);
424 struct iwl_roc_notif *notif = (void *)pkt->data;
425 u32 activity = le32_to_cpu(notif->activity);
426 bool started = le32_to_cpu(notif->success) &&
427 le32_to_cpu(notif->started);
434 ieee80211_iterate_active_interfaces_atomic(mvm->hw,
446 set_bit(IWL_MVM_STATUS_ROC_AUX_RUNNING, &mvm->status);
447 ieee80211_ready_on_channel(mvm->hw);
450 ieee80211_remain_on_channel_expired(mvm->hw);
462 list_for_each_entry(te_data, &mvm->aux_roc_te_list, list) {
463 if (le32_to_cpu(notif->unique_id) == te_data->uid) {
469 return -EINVAL;
474 "Aux ROC time event notification - UID = 0x%x action %d (error = %d)\n",
475 le32_to_cpu(notif->unique_id),
476 le32_to_cpu(notif->action), le32_to_cpu(notif->status));
478 if (!le32_to_cpu(notif->status) ||
479 le32_to_cpu(notif->action) == TE_V2_NOTIF_HOST_EVENT_END) {
481 ieee80211_remain_on_channel_expired(mvm->hw);
482 iwl_mvm_roc_finished(mvm); /* flush aux queue */
483 list_del(&te_data->list); /* remove from list */
484 te_data->running = false;
485 te_data->vif = NULL;
486 te_data->uid = 0;
487 te_data->id = TE_MAX;
488 } else if (le32_to_cpu(notif->action) == TE_V2_NOTIF_HOST_EVENT_START) {
489 set_bit(IWL_MVM_STATUS_ROC_AUX_RUNNING, &mvm->status);
490 te_data->running = true;
491 ieee80211_ready_on_channel(mvm->hw); /* Start TE */
495 le32_to_cpu(notif->action));
496 return -EINVAL;
508 struct iwl_rx_packet *pkt = rxb_addr(rxb);
509 struct iwl_time_event_notif *notif = (void *)pkt->data;
512 IWL_DEBUG_TE(mvm, "Time event notification - UID = 0x%x action %d\n",
513 le32_to_cpu(notif->unique_id),
514 le32_to_cpu(notif->action));
516 spin_lock_bh(&mvm->time_event_lock);
521 list_for_each_entry_safe(te_data, tmp, &mvm->time_event_list, list) {
522 if (le32_to_cpu(notif->unique_id) == te_data->uid)
526 spin_unlock_bh(&mvm->time_event_lock);
530 struct iwl_rx_packet *pkt, void *data)
536 int resp_len = iwl_rx_packet_payload_len(pkt);
538 if (WARN_ON(pkt->hdr.cmd != TIME_EVENT_NOTIFICATION))
546 resp = (void *)pkt->data;
548 /* te_data->uid is already set in the TIME_EVENT_CMD response */
549 if (le32_to_cpu(resp->unique_id) != te_data->uid)
552 IWL_DEBUG_TE(mvm, "TIME_EVENT_NOTIFICATION response - UID = 0x%x\n",
553 te_data->uid);
554 if (!resp->status)
562 struct iwl_rx_packet *pkt, void *data)
568 int resp_len = iwl_rx_packet_payload_len(pkt);
570 if (WARN_ON(pkt->hdr.cmd != TIME_EVENT_CMD))
578 resp = (void *)pkt->data;
581 if (WARN_ON_ONCE(le32_to_cpu(resp->id) != te_data->id))
584 te_data->uid = le32_to_cpu(resp->unique_id);
585 IWL_DEBUG_TE(mvm, "TIME_EVENT_CMD response - UID = 0x%x\n",
586 te_data->uid);
599 lockdep_assert_held(&mvm->mutex);
602 le32_to_cpu(te_cmd->duration));
604 spin_lock_bh(&mvm->time_event_lock);
605 if (WARN_ON(te_data->id != TE_MAX)) {
606 spin_unlock_bh(&mvm->time_event_lock);
607 return -EIO;
609 te_data->vif = vif;
610 te_data->duration = le32_to_cpu(te_cmd->duration);
611 te_data->id = le32_to_cpu(te_cmd->id);
612 list_add_tail(&te_data->list, &mvm->time_event_list);
613 spin_unlock_bh(&mvm->time_event_lock);
624 iwl_init_notification_wait(&mvm->notif_wait, &wait_time_event,
633 iwl_remove_notification(&mvm->notif_wait, &wait_time_event);
638 ret = iwl_wait_notification(&mvm->notif_wait, &wait_time_event, 1);
644 spin_lock_bh(&mvm->time_event_lock);
646 spin_unlock_bh(&mvm->time_event_lock);
657 struct iwl_mvm_time_event_data *te_data = &mvmvif->time_event_data;
662 lockdep_assert_held(&mvm->mutex);
664 if (te_data->running &&
665 time_after(te_data->end_jiffies, TU_TO_EXP_TIME(min_duration))) {
667 jiffies_to_msecs(te_data->end_jiffies - jiffies));
671 if (te_data->running) {
673 te_data->uid,
674 jiffies_to_msecs(te_data->end_jiffies - jiffies));
688 cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color));
712 iwl_init_notification_wait(&mvm->notif_wait, &wait_te_notif,
717 /* If TE was sent OK - wait for the notification that started */
720 iwl_remove_notification(&mvm->notif_wait, &wait_te_notif);
721 } else if (iwl_wait_notification(&mvm->notif_wait, &wait_te_notif,
733 int ver = iwl_fw_lookup_cmd_ver(mvm->fw,
738 return mvmvif->id;
740 if (WARN(link_id < 0 || !mvmvif->link[link_id],
742 return -EINVAL;
744 if (WARN(!mvmvif->link[link_id]->active,
746 return -EINVAL;
748 return mvmvif->link[link_id]->fw_link_id;
782 lockdep_assert_held(&mvm->mutex);
794 struct ieee80211_vif *vif = te_data->vif;
799 u8 roc_ver = iwl_fw_lookup_cmd_ver(mvm->fw,
805 mvmvif = iwl_mvm_vif_from_mac80211(te_data->vif);
806 iftype = te_data->vif->type;
812 spin_lock_bh(&mvm->time_event_lock);
815 *uid = te_data->uid;
816 id = te_data->id;
817 link_id = te_data->link_id;
823 spin_unlock_bh(&mvm->time_event_lock);
826 (roc_ver >= 3 && mvmvif->roc_activity == ROC_ACTIVITY_HOTSPOT)) {
827 if (mvmvif->roc_activity < ROC_NUM_ACTIVITIES) {
828 iwl_mvm_roc_rm_cmd(mvm, mvmvif->roc_activity);
829 mvmvif->roc_activity = ROC_NUM_ACTIVITIES;
833 } else if (fw_has_capa(&mvm->fw->ucode_capa,
836 /* When session protection is used, the te_data->id field
838 * For AUX ROC, HOT_SPOT_CMD is used and the te_data->id
875 u16 len = sizeof(aux_cmd) - iwl_mvm_chan_info_padding(mvm);
886 cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color));
916 cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color));
929 struct iwl_mvm_time_event_data *te_data = &mvmvif->time_event_data;
932 lockdep_assert_held(&mvm->mutex);
934 spin_lock_bh(&mvm->time_event_lock);
935 id = te_data->id;
936 spin_unlock_bh(&mvm->time_event_lock);
938 if (fw_has_capa(&mvm->fw->ucode_capa,
959 struct iwl_rx_packet *pkt = rxb_addr(rxb);
960 struct iwl_mvm_session_prot_notif *notif = (void *)pkt->data;
962 iwl_fw_lookup_notif_ver(mvm->fw, MAC_CONF_GROUP,
964 int id = le32_to_cpu(notif->mac_link_id);
980 notif_link_id = link_conf->link_id;
981 vif = link_conf->vif;
989 if (WARN(ver > 2 && mvmvif->time_event_data.link_id >= 0 &&
990 mvmvif->time_event_data.link_id != notif_link_id,
992 notif_link_id, mvmvif->time_event_data.link_id))
996 if (vif->type != NL80211_IFTYPE_P2P_DEVICE) {
998 &mvmvif->time_event_data;
1000 if (!le32_to_cpu(notif->status)) {
1003 spin_lock_bh(&mvm->time_event_lock);
1005 spin_unlock_bh(&mvm->time_event_lock);
1008 if (le32_to_cpu(notif->start)) {
1009 spin_lock_bh(&mvm->time_event_lock);
1010 te_data->running = le32_to_cpu(notif->start);
1011 te_data->end_jiffies =
1012 TU_TO_EXP_TIME(te_data->duration);
1013 spin_unlock_bh(&mvm->time_event_lock);
1020 !vif->cfg.assoc ?
1023 spin_lock_bh(&mvm->time_event_lock);
1025 spin_unlock_bh(&mvm->time_event_lock);
1031 if (!le32_to_cpu(notif->status) || !le32_to_cpu(notif->start)) {
1033 mvmvif->time_event_data.id = SESSION_PROTECT_CONF_MAX_ID;
1034 mvmvif->time_event_data.link_id = -1;
1036 ieee80211_remain_on_channel_expired(mvm->hw);
1037 } else if (le32_to_cpu(notif->start)) {
1038 if (WARN_ON(mvmvif->time_event_data.id !=
1039 le32_to_cpu(notif->conf_id)))
1041 set_bit(IWL_MVM_STATUS_ROC_P2P_RUNNING, &mvm->status);
1042 ieee80211_ready_on_channel(mvm->hw); /* Start TE */
1071 link_conf->dtim_period * link_conf->beacon_int);
1079 * remain off-channel for the max duration.
1081 * like the delay to be for 2-3 dtim intervals, in case there are
1086 if (vif->cfg.assoc && !WARN_ON(!dtim_interval)) {
1088 /* We cannot remain off-channel longer than the DTIM interval */
1090 *duration_tu = dtim_interval - AUX_ROC_SAFETY_BUFFER;
1092 *duration_tu = dtim_interval -
1108 .sta_id = cpu_to_le32(mvm->aux_sta.sta_id),
1112 lockdep_assert_held(&mvm->mutex);
1114 if (WARN_ON(mvmvif->roc_activity != ROC_NUM_ACTIVITIES))
1115 return -EBUSY;
1119 channel->hw_value,
1120 iwl_mvm_phy_band_from_nl80211(channel->band),
1133 channel->hw_value, duration_tu, activity);
1136 memcpy(roc_req.node_addr, vif->addr, ETH_ALEN);
1141 mvmvif->roc_activity = activity;
1160 lockdep_assert_held(&mvm->mutex);
1166 mvmvif->time_event_data.link_id = 0;
1170 mvmvif->time_event_data.id =
1174 mvmvif->time_event_data.id =
1179 return -EINVAL;
1182 cmd.conf_id = cpu_to_le32(mvmvif->time_event_data.id);
1192 struct iwl_mvm_time_event_data *te_data = &mvmvif->time_event_data;
1195 lockdep_assert_held(&mvm->mutex);
1196 if (te_data->running) {
1198 return -EBUSY;
1201 if (fw_has_capa(&mvm->fw->ucode_capa,
1209 cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color));
1220 return -EINVAL;
1247 lockdep_assert_held(&mvm->mutex);
1249 spin_lock_bh(&mvm->time_event_lock);
1258 list_for_each_entry(te_data, &mvm->time_event_list, list) {
1259 if (te_data->vif->type == NL80211_IFTYPE_P2P_DEVICE)
1266 te_data = list_first_entry_or_null(&mvm->aux_roc_te_list,
1270 spin_unlock_bh(&mvm->time_event_lock);
1289 u8 roc_ver = iwl_fw_lookup_cmd_ver(mvm->fw,
1291 int iftype = vif->type;
1293 mutex_lock(&mvm->mutex);
1296 if (mvmvif->roc_activity < ROC_NUM_ACTIVITIES) {
1297 iwl_mvm_roc_rm_cmd(mvm, mvmvif->roc_activity);
1298 mvmvif->roc_activity = ROC_NUM_ACTIVITIES;
1301 } else if (fw_has_capa(&mvm->fw->ucode_capa,
1303 te_data = &mvmvif->time_event_data;
1306 if (te_data->id >= SESSION_PROTECT_CONF_MAX_ID) {
1309 mutex_unlock(&mvm->mutex);
1313 te_data->id,
1314 te_data->link_id);
1317 &mvmvif->hs_time_event_data);
1325 mutex_unlock(&mvm->mutex);
1329 mvmvif = iwl_mvm_vif_from_mac80211(te_data->vif);
1330 iftype = te_data->vif->type;
1343 set_bit(IWL_MVM_STATUS_ROC_AUX_RUNNING, &mvm->status);
1345 set_bit(IWL_MVM_STATUS_ROC_P2P_RUNNING, &mvm->status);
1355 struct iwl_mvm_time_event_data *te_data = &mvmvif->time_event_data;
1358 lockdep_assert_held(&mvm->mutex);
1360 spin_lock_bh(&mvm->time_event_lock);
1361 id = te_data->id;
1362 spin_unlock_bh(&mvm->time_event_lock);
1375 struct iwl_mvm_time_event_data *te_data = &mvmvif->time_event_data;
1378 lockdep_assert_held(&mvm->mutex);
1380 if (te_data->running) {
1383 spin_lock_bh(&mvm->time_event_lock);
1384 id = te_data->id;
1385 spin_unlock_bh(&mvm->time_event_lock);
1389 return -EBUSY;
1402 cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color));
1418 struct iwl_rx_packet *pkt, void *data)
1423 int resp_len = iwl_rx_packet_payload_len(pkt);
1425 if (WARN_ON(pkt->hdr.cmd != SESSION_PROTECTION_NOTIF ||
1426 pkt->hdr.group_id != MAC_CONF_GROUP))
1434 resp = (void *)pkt->data;
1436 if (!resp->status)
1450 struct iwl_mvm_time_event_data *te_data = &mvmvif->time_event_data;
1464 lockdep_assert_held(&mvm->mutex);
1466 spin_lock_bh(&mvm->time_event_lock);
1467 if (te_data->running && te_data->link_id == link_id &&
1468 time_after(te_data->end_jiffies, TU_TO_EXP_TIME(min_duration))) {
1470 jiffies_to_msecs(te_data->end_jiffies - jiffies));
1471 spin_unlock_bh(&mvm->time_event_lock);
1481 te_data->id = le32_to_cpu(cmd.conf_id);
1482 te_data->duration = le32_to_cpu(cmd.duration_tu);
1483 te_data->vif = vif;
1484 te_data->link_id = link_id;
1485 spin_unlock_bh(&mvm->time_event_lock);
1500 iwl_init_notification_wait(&mvm->notif_wait, &wait_notif,
1507 iwl_remove_notification(&mvm->notif_wait, &wait_notif);
1509 } else if (iwl_wait_notification(&mvm->notif_wait, &wait_notif,
1519 spin_lock_bh(&mvm->time_event_lock);
1521 spin_unlock_bh(&mvm->time_event_lock);