Lines Matching refs:mvm
12 #include "mvm.h"
21 static inline int iwl_mvm_add_sta_cmd_size(struct iwl_mvm *mvm)
23 if (iwl_mvm_has_new_rx_api(mvm) ||
24 fw_has_api(&mvm->fw->ucode_capa, IWL_UCODE_TLV_API_STA_TYPE))
30 int iwl_mvm_find_free_sta_id(struct iwl_mvm *mvm, enum nl80211_iftype iftype)
36 WARN_ON_ONCE(test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status));
38 lockdep_assert_held(&mvm->mutex);
44 /* Don't take rcu_read_lock() since we are protected by mvm->mutex */
45 for (sta_id = 0; sta_id < mvm->fw->ucode_capa.num_stations; sta_id++) {
49 if (!rcu_dereference_protected(mvm->fw_id_to_mac_id[sta_id],
50 lockdep_is_held(&mvm->mutex)))
131 int iwl_mvm_sta_send_to_fw(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
148 if (fw_has_api(&mvm->fw->ucode_capa, IWL_UCODE_TLV_API_STA_TYPE))
154 if (!iwl_mvm_has_new_tx_api(mvm)) {
237 ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA,
238 iwl_mvm_add_sta_cmd_size(mvm),
245 IWL_DEBUG_ASSOC(mvm, "ADD_STA PASSED\n");
249 IWL_ERR(mvm, "ADD_STA failed\n");
285 sta = rcu_dereference(ba_data->mvm->fw_id_to_mac_id[sta_id]);
306 static int iwl_mvm_invalidate_sta_queue(struct iwl_mvm *mvm, int queue,
316 if (WARN_ON(iwl_mvm_has_new_tx_api(mvm)))
319 sta_id = mvm->queue_info[queue].ra_sta_id;
323 sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]);
349 return iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA,
350 iwl_mvm_add_sta_cmd_size(mvm),
354 static int iwl_mvm_disable_txq(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
364 lockdep_assert_held(&mvm->mutex);
366 if (iwl_mvm_has_new_tx_api(mvm)) {
367 if (mvm->sta_remove_requires_queue_remove) {
380 ret = iwl_mvm_send_cmd_pdu(mvm, cmd_id, 0,
387 iwl_trans_txq_free(mvm->trans, queue);
393 if (WARN_ON(mvm->queue_info[queue].tid_bitmap == 0))
396 mvm->queue_info[queue].tid_bitmap &= ~BIT(tid);
398 cmd.action = mvm->queue_info[queue].tid_bitmap ?
401 mvm->queue_info[queue].status = IWL_MVM_QUEUE_FREE;
403 IWL_DEBUG_TX_QUEUES(mvm,
406 mvm->queue_info[queue].tid_bitmap);
412 cmd.sta_id = mvm->queue_info[queue].ra_sta_id;
413 cmd.tid = mvm->queue_info[queue].txq_tid;
416 WARN(mvm->queue_info[queue].tid_bitmap,
418 queue, mvm->queue_info[queue].tid_bitmap);
421 mvm->queue_info[queue].tid_bitmap = 0;
427 spin_lock_bh(&mvm->add_stream_lock);
431 spin_unlock_bh(&mvm->add_stream_lock);
435 mvm->queue_info[queue].reserved = false;
437 iwl_trans_txq_disable(mvm->trans, queue, false);
438 ret = iwl_mvm_send_cmd_pdu(mvm, SCD_QUEUE_CFG, 0,
442 IWL_ERR(mvm, "Failed to disable queue %d (ret=%d)\n",
447 static int iwl_mvm_get_queue_agg_tids(struct iwl_mvm *mvm, int queue)
456 lockdep_assert_held(&mvm->mutex);
458 if (WARN_ON(iwl_mvm_has_new_tx_api(mvm)))
461 sta_id = mvm->queue_info[queue].ra_sta_id;
462 tid_bitmap = mvm->queue_info[queue].tid_bitmap;
464 sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[sta_id],
465 lockdep_is_held(&mvm->mutex));
487 static int iwl_mvm_remove_sta_queue_marking(struct iwl_mvm *mvm, int queue)
496 lockdep_assert_held(&mvm->mutex);
498 if (WARN_ON(iwl_mvm_has_new_tx_api(mvm)))
501 sta_id = mvm->queue_info[queue].ra_sta_id;
502 tid_bitmap = mvm->queue_info[queue].tid_bitmap;
506 sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]);
525 spin_lock_bh(&mvm->add_stream_lock);
529 spin_unlock_bh(&mvm->add_stream_lock);
550 static int iwl_mvm_free_inactive_queue(struct iwl_mvm *mvm, int queue,
561 lockdep_assert_held(&mvm->mutex);
563 if (WARN_ON(iwl_mvm_has_new_tx_api(mvm)))
566 sta_id = mvm->queue_info[queue].ra_sta_id;
567 tid = mvm->queue_info[queue].txq_tid;
571 mvmsta = iwl_mvm_sta_from_staid_protected(mvm, sta_id);
575 disable_agg_tids = iwl_mvm_remove_sta_queue_marking(mvm, queue);
578 iwl_mvm_invalidate_sta_queue(mvm, queue,
581 ret = iwl_mvm_disable_txq(mvm, old_sta, sta_id, &queue_tmp, tid);
583 IWL_ERR(mvm,
592 iwl_mvm_invalidate_sta_queue(mvm, queue, 0, true);
597 static int iwl_mvm_get_shared_queue(struct iwl_mvm *mvm,
608 lockdep_assert_held(&mvm->mutex);
610 if (WARN_ON(iwl_mvm_has_new_tx_api(mvm)))
622 ac_to_queue[mvm->queue_info[i].mac80211_ac] = i;
655 if (!iwl_mvm_is_dqa_data_queue(mvm, queue) &&
656 !iwl_mvm_is_dqa_mgmt_queue(mvm, queue) &&
658 IWL_ERR(mvm, "No DATA queues available to share\n");
666 static int iwl_mvm_reconfig_scd(struct iwl_mvm *mvm, int queue, int fifo,
682 if (WARN_ON(iwl_mvm_has_new_tx_api(mvm)))
685 if (WARN(mvm->queue_info[queue].tid_bitmap == 0,
689 IWL_DEBUG_TX_QUEUES(mvm, "Reconfig SCD for TXQ #%d\n", queue);
691 ret = iwl_mvm_send_cmd_pdu(mvm, SCD_QUEUE_CFG, 0, sizeof(cmd), &cmd);
704 static int iwl_mvm_redirect_queue(struct iwl_mvm *mvm, int queue, int tid,
715 if (WARN_ON(iwl_mvm_has_new_tx_api(mvm)))
726 if (ac <= mvm->queue_info[queue].mac80211_ac && !force) {
727 IWL_DEBUG_TX_QUEUES(mvm,
733 cmd.sta_id = mvm->queue_info[queue].ra_sta_id;
734 cmd.tx_fifo = iwl_mvm_ac_to_tx_fifo[mvm->queue_info[queue].mac80211_ac];
735 cmd.tid = mvm->queue_info[queue].txq_tid;
736 shared_queue = hweight16(mvm->queue_info[queue].tid_bitmap) > 1;
738 IWL_DEBUG_TX_QUEUES(mvm, "Redirecting TXQ #%d to FIFO #%d\n",
744 ret = iwl_trans_wait_tx_queues_empty(mvm->trans, BIT(queue));
746 IWL_ERR(mvm, "Error draining queue %d before reconfig\n",
753 iwl_trans_txq_disable(mvm->trans, queue, false);
754 ret = iwl_mvm_send_cmd_pdu(mvm, SCD_QUEUE_CFG, 0, sizeof(cmd), &cmd);
756 IWL_ERR(mvm, "Failed SCD disable TXQ %d (ret=%d)\n", queue,
760 iwl_trans_txq_enable_cfg(mvm->trans, queue, ssn, NULL, wdg_timeout);
763 mvm->queue_info[queue].txq_tid = tid;
768 iwl_mvm_reconfig_scd(mvm, queue, iwl_mvm_ac_to_tx_fifo[ac],
772 mvm->queue_info[queue].mac80211_ac = ac;
781 iwl_trans_txq_set_shared_mode(mvm->trans, queue, true);
790 static int iwl_mvm_find_free_queue(struct iwl_mvm *mvm, u8 sta_id,
795 lockdep_assert_held(&mvm->mutex);
797 if (WARN(maxq >= mvm->trans->trans_cfg->base_params->num_of_queues,
799 mvm->trans->trans_cfg->base_params->num_of_queues))
800 maxq = mvm->trans->trans_cfg->base_params->num_of_queues - 1;
803 if (WARN_ON(iwl_mvm_has_new_tx_api(mvm)))
808 if (mvm->queue_info[i].tid_bitmap == 0 &&
809 mvm->queue_info[i].status == IWL_MVM_QUEUE_FREE)
848 int iwl_mvm_tvqm_enable_txq(struct iwl_mvm *mvm,
858 mvm->trans->cfg->min_txq_size);
872 lockdep_is_held(&mvm->mutex));
887 queue = iwl_trans_txq_alloc(mvm->trans, 0, sta_mask,
891 IWL_DEBUG_TX_QUEUES(mvm,
898 static int iwl_mvm_sta_alloc_queue_tvqm(struct iwl_mvm *mvm,
906 iwl_mvm_get_wd_timeout(mvm, mvmsta->vif, false, false);
909 lockdep_assert_held(&mvm->mutex);
911 IWL_DEBUG_TX_QUEUES(mvm,
914 queue = iwl_mvm_tvqm_enable_txq(mvm, sta, mvmsta->deflink.sta_id,
920 mvm->tvqm_info[queue].txq_tid = tid;
921 mvm->tvqm_info[queue].sta_id = mvmsta->deflink.sta_id;
923 IWL_DEBUG_TX_QUEUES(mvm, "Allocated queue is %d\n", queue);
932 static bool iwl_mvm_update_txq_mapping(struct iwl_mvm *mvm,
939 if (mvm->queue_info[queue].tid_bitmap & BIT(tid)) {
940 IWL_ERR(mvm, "Trying to enable TXQ %d with existing TID %d\n",
946 if (mvm->queue_info[queue].tid_bitmap)
949 mvm->queue_info[queue].tid_bitmap |= BIT(tid);
950 mvm->queue_info[queue].ra_sta_id = sta_id;
954 mvm->queue_info[queue].mac80211_ac =
957 mvm->queue_info[queue].mac80211_ac = IEEE80211_AC_VO;
959 mvm->queue_info[queue].txq_tid = tid;
969 IWL_DEBUG_TX_QUEUES(mvm,
971 queue, mvm->queue_info[queue].tid_bitmap);
976 static bool iwl_mvm_enable_txq(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
993 if (WARN_ON(iwl_mvm_has_new_tx_api(mvm)))
997 if (!iwl_mvm_update_txq_mapping(mvm, sta, queue, cfg->sta_id, cfg->tid))
1000 inc_ssn = iwl_trans_txq_enable_cfg(mvm->trans, queue, ssn,
1005 WARN(iwl_mvm_send_cmd_pdu(mvm, SCD_QUEUE_CFG, 0, sizeof(cmd), &cmd),
1011 static void iwl_mvm_change_queue_tid(struct iwl_mvm *mvm, int queue)
1021 lockdep_assert_held(&mvm->mutex);
1023 if (WARN_ON(iwl_mvm_has_new_tx_api(mvm)))
1026 tid_bitmap = mvm->queue_info[queue].tid_bitmap;
1036 ret = iwl_mvm_send_cmd_pdu(mvm, SCD_QUEUE_CFG, 0, sizeof(cmd), &cmd);
1038 IWL_ERR(mvm, "Failed to update owner of TXQ %d (ret=%d)\n",
1043 mvm->queue_info[queue].txq_tid = tid;
1044 IWL_DEBUG_TX_QUEUES(mvm, "Changed TXQ %d ownership to tid %d\n",
1048 static void iwl_mvm_unshare_queue(struct iwl_mvm *mvm, int queue)
1060 if (WARN_ON(iwl_mvm_has_new_tx_api(mvm)))
1063 lockdep_assert_held(&mvm->mutex);
1065 sta_id = mvm->queue_info[queue].ra_sta_id;
1066 tid_bitmap = mvm->queue_info[queue].tid_bitmap;
1071 IWL_ERR(mvm, "Failed to unshare q %d, active tids=0x%lx\n",
1076 IWL_DEBUG_TX_QUEUES(mvm, "Unsharing TXQ %d, keeping tid %d\n", queue,
1079 sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[sta_id],
1080 lockdep_is_held(&mvm->mutex));
1086 wdg_timeout = iwl_mvm_get_wd_timeout(mvm, mvmsta->vif, false, false);
1090 ret = iwl_mvm_redirect_queue(mvm, queue, tid,
1095 IWL_ERR(mvm, "Failed to redirect TXQ %d\n", queue);
1112 ret = iwl_mvm_send_cmd_pdu(mvm, ADD_STA, CMD_ASYNC,
1113 iwl_mvm_add_sta_cmd_size(mvm), &cmd);
1115 IWL_DEBUG_TX_QUEUES(mvm,
1120 iwl_trans_txq_set_shared_mode(mvm->trans, queue, false);
1124 mvm->queue_info[queue].status = IWL_MVM_QUEUE_READY;
1134 static bool iwl_mvm_remove_inactive_tids(struct iwl_mvm *mvm,
1143 lockdep_assert_held(&mvm->mutex);
1145 if (WARN_ON(iwl_mvm_has_new_tx_api(mvm)))
1151 if (iwl_mvm_tid_queued(mvm, &mvmsta->tid_data[tid]))
1160 if (tid_bitmap == mvm->queue_info[queue].tid_bitmap) {
1161 IWL_DEBUG_TX_QUEUES(mvm, "Queue %d is inactive\n", queue);
1173 mvm->queue_info[queue].tid_bitmap &= ~BIT(tid);
1175 q_tid_bitmap = mvm->queue_info[queue].tid_bitmap;
1188 if (!(q_tid_bitmap & BIT(mvm->queue_info[queue].txq_tid)))
1191 IWL_DEBUG_TX_QUEUES(mvm,
1196 IWL_DEBUG_TX_QUEUES(mvm,
1198 mvm->queue_info[queue].tid_bitmap);
1204 tid_bitmap = mvm->queue_info[queue].tid_bitmap;
1207 if (hweight16(mvm->queue_info[queue].tid_bitmap) == 1 &&
1208 mvm->queue_info[queue].status == IWL_MVM_QUEUE_SHARED) {
1209 IWL_DEBUG_TX_QUEUES(mvm, "Marking Q:%d for reconfig\n",
1226 static int iwl_mvm_inactivity_check(struct iwl_mvm *mvm, u8 alloc_for_sta)
1234 lockdep_assert_held(&mvm->mutex);
1236 if (iwl_mvm_has_new_tx_api(mvm))
1252 queue_tid_bitmap = mvm->queue_info[i].tid_bitmap;
1257 if (mvm->queue_info[i].status != IWL_MVM_QUEUE_READY &&
1258 mvm->queue_info[i].status != IWL_MVM_QUEUE_SHARED)
1264 if (time_after(mvm->queue_info[i].last_frame_time[tid] +
1280 sta_id = mvm->queue_info[i].ra_sta_id;
1281 sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]);
1294 ret = iwl_mvm_remove_inactive_tids(mvm, mvmsta, i,
1309 iwl_mvm_unshare_queue(mvm, i);
1311 iwl_mvm_change_queue_tid(mvm, i);
1316 ret = iwl_mvm_free_inactive_queue(mvm, free_queue, queue_owner,
1325 static int iwl_mvm_sta_alloc_queue(struct iwl_mvm *mvm,
1330 .fifo = iwl_mvm_mac_ac_to_tx_fifo(mvm, ac),
1336 iwl_mvm_get_wd_timeout(mvm, mvmsta->vif, false, false);
1346 lockdep_assert_held(&mvm->mutex);
1348 if (iwl_mvm_has_new_tx_api(mvm))
1349 return iwl_mvm_sta_alloc_queue_tvqm(mvm, sta, ac, tid);
1357 queue = iwl_mvm_find_free_queue(mvm, mvmsta->deflink.sta_id,
1361 IWL_DEBUG_TX_QUEUES(mvm, "Found free MGMT queue #%d\n",
1368 (mvm->queue_info[mvmsta->reserved_queue].status ==
1371 mvm->queue_info[queue].reserved = true;
1372 IWL_DEBUG_TX_QUEUES(mvm, "Using reserved queue #%d\n", queue);
1376 queue = iwl_mvm_find_free_queue(mvm, mvmsta->deflink.sta_id,
1381 queue = iwl_mvm_inactivity_check(mvm, mvmsta->deflink.sta_id);
1386 queue = iwl_mvm_get_shared_queue(mvm, tfd_queue_mask, ac);
1389 mvm->queue_info[queue].status = IWL_MVM_QUEUE_SHARED;
1400 mvm->queue_info[queue].status = IWL_MVM_QUEUE_READY;
1404 IWL_ERR(mvm, "No available queues for tid %d on sta_id %d\n",
1418 IWL_DEBUG_TX_QUEUES(mvm,
1425 disable_agg_tids = iwl_mvm_get_queue_agg_tids(mvm, queue);
1428 IWL_DEBUG_TX_QUEUES(mvm, "Disabling aggs on queue %d\n",
1430 iwl_mvm_invalidate_sta_queue(mvm, queue,
1435 inc_ssn = iwl_mvm_enable_txq(mvm, sta, queue, ssn, &cfg, wdg_timeout);
1444 iwl_trans_txq_set_shared_mode(mvm->trans, queue, true);
1465 ret = iwl_mvm_sta_send_to_fw(mvm, sta, true, STA_MODIFY_QUEUES);
1471 ret = iwl_mvm_sta_tx_agg(mvm, sta, tid, queue, true);
1477 ret = iwl_mvm_redirect_queue(mvm, queue, tid, ac, ssn,
1488 iwl_mvm_disable_txq(mvm, sta, mvmsta->deflink.sta_id, &queue_tmp, tid);
1493 int iwl_mvm_sta_ensure_queue(struct iwl_mvm *mvm,
1499 lockdep_assert_held(&mvm->mutex);
1506 if (!iwl_mvm_sta_alloc_queue(mvm, txq->sta, txq->ac, txq->tid)) {
1512 spin_lock(&mvm->add_stream_lock);
1515 spin_unlock(&mvm->add_stream_lock);
1523 struct iwl_mvm *mvm = container_of(wk, struct iwl_mvm,
1526 mutex_lock(&mvm->mutex);
1528 iwl_mvm_inactivity_check(mvm, IWL_MVM_INVALID_STA);
1530 while (!list_empty(&mvm->add_stream_txqs)) {
1535 mvmtxq = list_first_entry(&mvm->add_stream_txqs,
1550 if (iwl_mvm_sta_alloc_queue(mvm, txq->sta, txq->ac, tid)) {
1551 spin_lock_bh(&mvm->add_stream_lock);
1553 spin_unlock_bh(&mvm->add_stream_lock);
1563 spin_lock(&mvm->add_stream_lock);
1565 spin_unlock(&mvm->add_stream_lock);
1567 iwl_mvm_mac_itxq_xmit(mvm->hw, txq);
1571 mutex_unlock(&mvm->mutex);
1574 static int iwl_mvm_reserve_sta_stream(struct iwl_mvm *mvm,
1582 if (WARN_ON(iwl_mvm_has_new_tx_api(mvm)))
1586 iwl_mvm_inactivity_check(mvm, IWL_MVM_INVALID_STA);
1590 !mvm->queue_info[IWL_MVM_DQA_BSS_CLIENT_QUEUE].tid_bitmap &&
1591 (mvm->queue_info[IWL_MVM_DQA_BSS_CLIENT_QUEUE].status ==
1595 queue = iwl_mvm_find_free_queue(mvm, mvmsta->deflink.sta_id,
1600 queue = iwl_mvm_inactivity_check(mvm, mvmsta->deflink.sta_id);
1602 IWL_ERR(mvm, "No available queues for new station\n");
1606 mvm->queue_info[queue].status = IWL_MVM_QUEUE_RESERVED;
1610 IWL_DEBUG_TX_QUEUES(mvm, "Reserving data queue #%d for sta_id %d\n",
1623 void iwl_mvm_realloc_queues_after_restart(struct iwl_mvm *mvm,
1628 iwl_mvm_get_wd_timeout(mvm, mvm_sta->vif, false, false);
1637 mvm->queue_info[mvm_sta->reserved_queue].status =
1650 if (iwl_mvm_has_new_tx_api(mvm)) {
1651 IWL_DEBUG_TX_QUEUES(mvm,
1654 txq_id = iwl_mvm_tvqm_enable_txq(mvm, sta,
1677 cfg.fifo = iwl_mvm_mac_ac_to_tx_fifo(mvm, ac);
1682 IWL_DEBUG_TX_QUEUES(mvm,
1687 iwl_mvm_enable_txq(mvm, sta, txq_id, seq, &cfg, wdg);
1688 mvm->queue_info[txq_id].status = IWL_MVM_QUEUE_READY;
1693 static int iwl_mvm_add_int_sta_common(struct iwl_mvm *mvm,
1702 lockdep_assert_held(&mvm->mutex);
1707 if (iwl_mvm_has_new_station_api(mvm->fw) &&
1714 if (fw_has_api(&mvm->fw->ucode_capa, IWL_UCODE_TLV_API_STA_TYPE))
1717 if (!iwl_mvm_has_new_tx_api(mvm))
1724 ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA,
1725 iwl_mvm_add_sta_cmd_size(mvm),
1732 IWL_DEBUG_INFO(mvm, "Internal station added.\n");
1736 IWL_ERR(mvm, "Add internal station failed, status=0x%x\n",
1744 int iwl_mvm_sta_init(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
1752 lockdep_assert_held(&mvm->mutex);
1761 if (!mvm->mld_api_is_used) {
1768 if (!mvm->trans->trans_cfg->gen2)
1798 if (iwl_mvm_has_new_rx_api(mvm)) {
1801 dup_data = kcalloc(mvm->trans->num_rx_queues,
1814 for (q = 0; q < mvm->trans->num_rx_queues; q++)
1820 if (!iwl_mvm_has_new_tx_api(mvm)) {
1821 ret = iwl_mvm_reserve_sta_stream(mvm, sta,
1831 if (iwl_mvm_has_tlc_offload(mvm))
1832 iwl_mvm_rs_add_sta(mvm, mvm_sta);
1836 iwl_mvm_toggle_tx_ant(mvm, &mvm_sta->tx_ant);
1842 kcalloc(mvm->trans->num_rx_queues,
1846 for (int q = 0; q < mvm->trans->num_rx_queues; q++)
1853 int iwl_mvm_add_sta(struct iwl_mvm *mvm,
1863 lockdep_assert_held(&mvm->mutex);
1865 if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status))
1866 sta_id = iwl_mvm_find_free_sta_id(mvm,
1877 if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) {
1886 ret = iwl_mvm_add_int_sta_common(mvm, &tmp_sta, sta->addr,
1891 iwl_mvm_realloc_queues_after_restart(mvm, sta);
1893 sta_flags = iwl_mvm_has_new_tx_api(mvm) ? 0 : STA_MODIFY_QUEUES;
1897 ret = iwl_mvm_sta_init(mvm, vif, sta, sta_id,
1903 ret = iwl_mvm_sta_send_to_fw(mvm, sta, sta_update, sta_flags);
1916 rcu_assign_pointer(mvm->fw_id_to_mac_id[sta_id], sta);
1924 int iwl_mvm_drain_sta(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta,
1931 lockdep_assert_held(&mvm->mutex);
1940 ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA,
1941 iwl_mvm_add_sta_cmd_size(mvm),
1948 IWL_DEBUG_INFO(mvm, "Frames for staid %d will drained in fw\n",
1954 IWL_ERR(mvm, "Couldn't drain frames for staid %d\n",
1957 IWL_ERR(mvm, "Couldn't drain frames for staid %d, status %#x\n",
1971 static int iwl_mvm_rm_sta_common(struct iwl_mvm *mvm, u8 sta_id)
1979 sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[sta_id],
1980 lockdep_is_held(&mvm->mutex));
1984 IWL_ERR(mvm, "Invalid station id\n");
1988 ret = iwl_mvm_send_cmd_pdu(mvm, REMOVE_STA, 0,
1991 IWL_ERR(mvm, "Failed to remove station. Id=%d\n", sta_id);
1998 static void iwl_mvm_disable_sta_queues(struct iwl_mvm *mvm,
2005 lockdep_assert_held(&mvm->mutex);
2011 iwl_mvm_disable_txq(mvm, sta, mvm_sta->deflink.sta_id,
2020 spin_lock_bh(&mvm->add_stream_lock);
2024 spin_unlock_bh(&mvm->add_stream_lock);
2028 int iwl_mvm_wait_sta_queues_empty(struct iwl_mvm *mvm,
2044 ret = iwl_trans_wait_txq_empty(mvm->trans, txq_id);
2056 bool iwl_mvm_sta_del(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
2067 lockdep_assert_held(&mvm->mutex);
2071 lockdep_is_held(&mvm->mutex));
2084 status = &mvm->queue_info[reserved_txq].status;
2103 iwl_mvm_sec_key_remove_ap(mvm, vif, mvm_link, 0);
2113 if (WARN_ON_ONCE(mvm->tdls_cs.peer.sta_id == sta_id)) {
2114 mvm->tdls_cs.peer.sta_id = IWL_MVM_INVALID_STA;
2115 cancel_delayed_work(&mvm->tdls_cs.dwork);
2121 int iwl_mvm_rm_sta(struct iwl_mvm *mvm,
2128 lockdep_assert_held(&mvm->mutex);
2130 ret = iwl_mvm_drain_sta(mvm, mvm_sta, true);
2135 ret = iwl_mvm_flush_sta(mvm, mvm_sta->deflink.sta_id,
2139 if (iwl_mvm_has_new_tx_api(mvm)) {
2140 ret = iwl_mvm_wait_sta_queues_empty(mvm, mvm_sta);
2144 ret = iwl_trans_wait_tx_queues_empty(mvm->trans,
2150 ret = iwl_mvm_drain_sta(mvm, mvm_sta, false);
2152 iwl_mvm_disable_sta_queues(mvm, vif, sta);
2154 if (iwl_mvm_sta_del(mvm, vif, sta, &sta->deflink, &ret))
2157 ret = iwl_mvm_rm_sta_common(mvm, mvm_sta->deflink.sta_id);
2158 RCU_INIT_POINTER(mvm->fw_id_to_mac_id[mvm_sta->deflink.sta_id], NULL);
2163 int iwl_mvm_rm_sta_id(struct iwl_mvm *mvm,
2167 int ret = iwl_mvm_rm_sta_common(mvm, sta_id);
2169 lockdep_assert_held(&mvm->mutex);
2171 RCU_INIT_POINTER(mvm->fw_id_to_mac_id[sta_id], NULL);
2175 int iwl_mvm_allocate_int_sta(struct iwl_mvm *mvm,
2180 if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status) ||
2182 sta->sta_id = iwl_mvm_find_free_sta_id(mvm, iftype);
2191 RCU_INIT_POINTER(mvm->fw_id_to_mac_id[sta->sta_id], ERR_PTR(-EINVAL));
2195 void iwl_mvm_dealloc_int_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *sta)
2197 RCU_INIT_POINTER(mvm->fw_id_to_mac_id[sta->sta_id], NULL);
2202 static void iwl_mvm_enable_aux_snif_queue(struct iwl_mvm *mvm, u16 queue,
2206 mvm->trans->trans_cfg->base_params->wd_timeout;
2215 WARN_ON(iwl_mvm_has_new_tx_api(mvm));
2217 iwl_mvm_enable_txq(mvm, NULL, queue, 0, &cfg, wdg_timeout);
2220 static int iwl_mvm_enable_aux_snif_queue_tvqm(struct iwl_mvm *mvm, u8 sta_id)
2223 mvm->trans->trans_cfg->base_params->wd_timeout;
2225 WARN_ON(!iwl_mvm_has_new_tx_api(mvm));
2227 return iwl_mvm_tvqm_enable_txq(mvm, NULL, sta_id, IWL_MAX_TID_COUNT,
2231 static int iwl_mvm_add_int_sta_with_queue(struct iwl_mvm *mvm, int macidx,
2239 if (!iwl_mvm_has_new_tx_api(mvm))
2240 iwl_mvm_enable_aux_snif_queue(mvm, *queue, sta->sta_id, fifo);
2242 ret = iwl_mvm_add_int_sta_common(mvm, sta, addr, macidx, maccolor);
2244 if (!iwl_mvm_has_new_tx_api(mvm))
2245 iwl_mvm_disable_txq(mvm, NULL, sta->sta_id, queue,
2254 if (iwl_mvm_has_new_tx_api(mvm)) {
2257 txq = iwl_mvm_enable_aux_snif_queue_tvqm(mvm, sta->sta_id);
2259 iwl_mvm_rm_sta_common(mvm, sta->sta_id);
2269 int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm, u32 lmac_id)
2272 u32 qmask = mvm->aux_queue == IWL_MVM_INVALID_QUEUE ? 0 :
2273 BIT(mvm->aux_queue);
2275 lockdep_assert_held(&mvm->mutex);
2278 ret = iwl_mvm_allocate_int_sta(mvm, &mvm->aux_sta, qmask,
2288 ret = iwl_mvm_add_int_sta_with_queue(mvm, lmac_id, 0, NULL,
2289 &mvm->aux_sta, &mvm->aux_queue,
2292 iwl_mvm_dealloc_int_sta(mvm, &mvm->aux_sta);
2299 int iwl_mvm_add_snif_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
2303 lockdep_assert_held(&mvm->mutex);
2305 return iwl_mvm_add_int_sta_with_queue(mvm, mvmvif->id, mvmvif->color,
2306 NULL, &mvm->snif_sta,
2307 &mvm->snif_queue,
2311 int iwl_mvm_rm_snif_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
2315 lockdep_assert_held(&mvm->mutex);
2317 if (WARN_ON_ONCE(mvm->snif_sta.sta_id == IWL_MVM_INVALID_STA))
2320 iwl_mvm_disable_txq(mvm, NULL, mvm->snif_sta.sta_id,
2321 &mvm->snif_queue, IWL_MAX_TID_COUNT);
2322 ret = iwl_mvm_rm_sta_common(mvm, mvm->snif_sta.sta_id);
2324 IWL_WARN(mvm, "Failed sending remove station\n");
2329 int iwl_mvm_rm_aux_sta(struct iwl_mvm *mvm)
2333 lockdep_assert_held(&mvm->mutex);
2335 if (WARN_ON_ONCE(mvm->aux_sta.sta_id == IWL_MVM_INVALID_STA))
2338 iwl_mvm_disable_txq(mvm, NULL, mvm->aux_sta.sta_id,
2339 &mvm->aux_queue, IWL_MAX_TID_COUNT);
2340 ret = iwl_mvm_rm_sta_common(mvm, mvm->aux_sta.sta_id);
2342 IWL_WARN(mvm, "Failed sending remove station\n");
2343 iwl_mvm_dealloc_int_sta(mvm, &mvm->aux_sta);
2348 void iwl_mvm_dealloc_snif_sta(struct iwl_mvm *mvm)
2350 iwl_mvm_dealloc_int_sta(mvm, &mvm->snif_sta);
2357 * @mvm: the mvm component
2361 int iwl_mvm_send_add_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
2370 iwl_mvm_get_wd_timeout(mvm, vif, false, false);
2379 lockdep_assert_held(&mvm->mutex);
2381 if (!iwl_mvm_has_new_tx_api(mvm)) {
2384 queue = mvm->probe_queue;
2386 queue = mvm->p2p_dev_queue;
2394 iwl_mvm_enable_txq(mvm, NULL, queue, 0, &cfg, wdg_timeout);
2403 ret = iwl_mvm_add_int_sta_common(mvm, bsta, baddr,
2412 if (iwl_mvm_has_new_tx_api(mvm)) {
2413 queue = iwl_mvm_tvqm_enable_txq(mvm, NULL, bsta->sta_id,
2417 iwl_mvm_rm_sta_common(mvm, bsta->sta_id);
2424 mvm->probe_queue = queue;
2428 mvm->p2p_dev_queue = queue;
2433 mvmvif->deflink.mgmt_queue = mvm->probe_queue;
2439 void iwl_mvm_free_bcast_sta_queues(struct iwl_mvm *mvm,
2445 lockdep_assert_held(&mvm->mutex);
2447 iwl_mvm_flush_sta(mvm, mvmvif->deflink.bcast_sta.sta_id,
2453 queueptr = &mvm->probe_queue;
2456 queueptr = &mvm->p2p_dev_queue;
2465 iwl_mvm_disable_txq(mvm, NULL, mvmvif->deflink.bcast_sta.sta_id,
2469 mvmvif->deflink.mgmt_queue = mvm->probe_queue;
2471 if (iwl_mvm_has_new_tx_api(mvm))
2480 int iwl_mvm_send_rm_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
2485 lockdep_assert_held(&mvm->mutex);
2487 iwl_mvm_free_bcast_sta_queues(mvm, vif);
2489 ret = iwl_mvm_rm_sta_common(mvm, mvmvif->deflink.bcast_sta.sta_id);
2491 IWL_WARN(mvm, "Failed sending remove station\n");
2495 int iwl_mvm_alloc_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
2499 lockdep_assert_held(&mvm->mutex);
2501 return iwl_mvm_allocate_int_sta(mvm, &mvmvif->deflink.bcast_sta, 0,
2510 * @mvm: the mvm component
2513 int iwl_mvm_add_p2p_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
2519 lockdep_assert_held(&mvm->mutex);
2521 ret = iwl_mvm_alloc_bcast_sta(mvm, vif);
2525 ret = iwl_mvm_send_add_bcast_sta(mvm, vif);
2528 iwl_mvm_dealloc_int_sta(mvm, bsta);
2533 void iwl_mvm_dealloc_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
2537 iwl_mvm_dealloc_int_sta(mvm, &mvmvif->deflink.bcast_sta);
2544 int iwl_mvm_rm_p2p_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
2548 lockdep_assert_held(&mvm->mutex);
2550 ret = iwl_mvm_send_rm_bcast_sta(mvm, vif);
2552 iwl_mvm_dealloc_bcast_sta(mvm, vif);
2562 * @mvm: the mvm component
2565 int iwl_mvm_add_mcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
2579 unsigned int timeout = iwl_mvm_get_wd_timeout(mvm, vif, false, false);
2582 lockdep_assert_held(&mvm->mutex);
2601 if (!iwl_mvm_has_new_tx_api(mvm) &&
2602 fw_has_api(&mvm->fw->ucode_capa, IWL_UCODE_TLV_API_STA_TYPE)) {
2603 iwl_mvm_enable_txq(mvm, NULL, mvmvif->deflink.cab_queue, 0,
2608 ret = iwl_mvm_add_int_sta_common(mvm, msta, maddr,
2620 if (iwl_mvm_has_new_tx_api(mvm)) {
2621 int queue = iwl_mvm_tvqm_enable_txq(mvm, NULL, msta->sta_id,
2628 } else if (!fw_has_api(&mvm->fw->ucode_capa,
2630 iwl_mvm_enable_txq(mvm, NULL, mvmvif->deflink.cab_queue, 0,
2636 iwl_mvm_dealloc_int_sta(mvm, msta);
2640 static int __iwl_mvm_remove_sta_key(struct iwl_mvm *mvm, u8 sta_id,
2648 bool new_api = fw_has_api(&mvm->fw->ucode_capa,
2677 ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA_KEY, size, &u.cmd,
2682 IWL_DEBUG_WEP(mvm, "MODIFY_STA: remove sta key passed\n");
2686 IWL_ERR(mvm, "MODIFY_STA: remove sta key failed\n");
2697 int iwl_mvm_rm_mcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
2702 lockdep_assert_held(&mvm->mutex);
2704 iwl_mvm_flush_sta(mvm, mvmvif->deflink.mcast_sta.sta_id,
2707 iwl_mvm_disable_txq(mvm, NULL, mvmvif->deflink.mcast_sta.sta_id,
2710 ret = iwl_mvm_rm_sta_common(mvm, mvmvif->deflink.mcast_sta.sta_id);
2712 IWL_WARN(mvm, "Failed sending remove station\n");
2717 static void iwl_mvm_sync_rxq_del_ba(struct iwl_mvm *mvm, u8 baid)
2723 iwl_mvm_sync_rx_queues_internal(mvm, IWL_MVM_RXQ_NOTIF_DEL_BA, true,
2727 static void iwl_mvm_free_reorder(struct iwl_mvm *mvm,
2732 iwl_mvm_sync_rxq_del_ba(mvm, data->baid);
2734 for (i = 0; i < mvm->trans->num_rx_queues; i++) {
2761 static void iwl_mvm_init_reorder_buffer(struct iwl_mvm *mvm,
2767 for (i = 0; i < mvm->trans->num_rx_queues; i++) {
2784 static int iwl_mvm_fw_baid_op_sta(struct iwl_mvm *mvm,
2809 ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA,
2810 iwl_mvm_add_sta_cmd_size(mvm),
2817 IWL_DEBUG_HT(mvm, "RX BA Session %sed in fw\n",
2819 if (WARN_ON(start && iwl_mvm_has_new_rx_api(mvm) &&
2824 IWL_WARN(mvm, "RX BA Session refused by fw\n");
2827 IWL_ERR(mvm, "RX BA Session failed %sing, status 0x%x\n",
2833 static int iwl_mvm_fw_baid_op_cmd(struct iwl_mvm *mvm,
2854 cpu_to_le32(iwl_mvm_sta_fw_id_mask(mvm, sta, -1));
2859 } else if (iwl_fw_lookup_cmd_ver(mvm->fw, hcmd.id, 1) == 1) {
2864 cpu_to_le32(iwl_mvm_sta_fw_id_mask(mvm, sta, -1));
2868 ret = iwl_mvm_send_cmd_status(mvm, &hcmd, &baid);
2877 IWL_DEBUG_HT(mvm, "RX BA Session %sed in fw\n",
2880 if (baid < 0 || baid >= ARRAY_SIZE(mvm->baid_map))
2886 static int iwl_mvm_fw_baid_op(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
2890 if (fw_has_capa(&mvm->fw->ucode_capa,
2892 return iwl_mvm_fw_baid_op_cmd(mvm, sta, start,
2895 return iwl_mvm_fw_baid_op_sta(mvm, sta, start,
2899 int iwl_mvm_sta_rx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
2905 u32 max_ba_id_sessions = iwl_mvm_has_new_tx_api(mvm) ? IWL_MAX_BAID :
2908 lockdep_assert_held(&mvm->mutex);
2910 if (start && mvm->rx_ba_sessions >= max_ba_id_sessions) {
2911 IWL_WARN(mvm, "Not enough RX BA SESSIONS\n");
2915 if (iwl_mvm_has_new_rx_api(mvm) && start) {
2942 mvm->trans->num_rx_queues *
2956 if (iwl_mvm_has_new_rx_api(mvm) && !start) {
2964 if (start || !test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status))
2965 baid = iwl_mvm_fw_baid_op(mvm, sta, start, tid, ssn, buf_size,
2974 mvm->rx_ba_sessions++;
2976 if (!iwl_mvm_has_new_rx_api(mvm))
2982 baid_data->rcu_ptr = &mvm->baid_map[baid];
2985 baid_data->mvm = mvm;
2987 baid_data->sta_mask = iwl_mvm_sta_fw_id_mask(mvm, sta, -1);
2995 iwl_mvm_init_reorder_buffer(mvm, baid_data, ssn);
3002 IWL_DEBUG_HT(mvm, "Sta %d(%d) is assigned to BAID %d\n",
3004 WARN_ON(rcu_access_pointer(mvm->baid_map[baid]));
3005 rcu_assign_pointer(mvm->baid_map[baid], baid_data);
3009 if (mvm->rx_ba_sessions > 0)
3011 mvm->rx_ba_sessions--;
3012 if (!iwl_mvm_has_new_rx_api(mvm))
3018 baid_data = rcu_access_pointer(mvm->baid_map[baid]);
3023 iwl_mvm_free_reorder(mvm, baid_data);
3025 RCU_INIT_POINTER(mvm->baid_map[baid], NULL);
3027 IWL_DEBUG_HT(mvm, "BAID %d is free\n", baid);
3036 int iwl_mvm_sta_tx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
3044 lockdep_assert_held(&mvm->mutex);
3057 if (!iwl_mvm_has_new_tx_api(mvm))
3064 ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA,
3065 iwl_mvm_add_sta_cmd_size(mvm),
3075 IWL_ERR(mvm, "TX BA Session failed %sing, status 0x%x\n",
3106 int iwl_mvm_sta_tx_agg_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
3120 IWL_ERR(mvm,
3126 lockdep_assert_held(&mvm->mutex);
3129 iwl_mvm_has_new_tx_api(mvm)) {
3132 ret = iwl_mvm_sta_alloc_queue_tvqm(mvm, sta, ac, tid);
3147 ret = iwl_mvm_find_free_queue(mvm, mvmsta->deflink.sta_id,
3151 IWL_ERR(mvm, "Failed to allocate agg queue\n");
3158 mvm->queue_info[txq_id].status = IWL_MVM_QUEUE_RESERVED;
3161 IWL_ERR(mvm, "tid_id %d out of range (0, %d)!\n",
3165 } else if (unlikely(mvm->queue_info[txq_id].status ==
3168 IWL_DEBUG_TX_QUEUES(mvm,
3174 IWL_DEBUG_TX_QUEUES(mvm,
3183 IWL_DEBUG_TX_QUEUES(mvm,
3194 if (mvm->trans->trans_cfg->gen2)
3211 int iwl_mvm_sta_tx_agg_oper(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
3218 iwl_mvm_get_wd_timeout(mvm, vif, sta->tdls, false);
3235 if (WARN_ON_ONCE(iwl_mvm_has_tlc_offload(mvm)))
3250 if (iwl_mvm_has_new_tx_api(mvm)) {
3265 ret = iwl_mvm_sta_tx_agg(mvm, sta, tid, queue, true);
3273 queue_status = mvm->queue_info[queue].status;
3276 if (mvm->queue_info[queue].status == IWL_MVM_QUEUE_READY)
3288 ret = iwl_trans_wait_tx_queues_empty(mvm->trans,
3291 IWL_ERR(mvm,
3296 ret = iwl_mvm_reconfig_scd(mvm, queue, cfg.fifo,
3300 IWL_ERR(mvm,
3307 iwl_mvm_enable_txq(mvm, sta, queue, ssn,
3312 ret = iwl_mvm_sta_tx_agg(mvm, sta, tid, queue, true);
3318 mvm->queue_info[queue].status = IWL_MVM_QUEUE_READY;
3334 IWL_DEBUG_HT(mvm, "Tx aggregation enabled on ra = %pM tid = %d\n",
3337 return iwl_mvm_send_lq_cmd(mvm, &mvmsta->deflink.lq_sta.rs_drv.lq);
3340 static void iwl_mvm_unreserve_agg_queue(struct iwl_mvm *mvm,
3346 lockdep_assert_held(&mvm->mutex);
3348 if (iwl_mvm_has_new_tx_api(mvm))
3358 if (mvm->queue_info[txq_id].status == IWL_MVM_QUEUE_RESERVED) {
3359 mvm->queue_info[txq_id].status = IWL_MVM_QUEUE_FREE;
3364 int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
3376 if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) {
3385 IWL_DEBUG_TX_QUEUES(mvm, "Stop AGG: sta %d tid %d q %d state %d\n",
3391 iwl_mvm_unreserve_agg_queue(mvm, mvmsta, tid_data);
3397 IWL_DEBUG_TX_QUEUES(mvm,
3407 iwl_mvm_sta_tx_agg(mvm, sta, tid, txq_id, false);
3417 lockdep_assert_held(&mvm->mutex);
3424 IWL_ERR(mvm,
3427 IWL_ERR(mvm,
3437 int iwl_mvm_sta_tx_agg_flush(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
3451 IWL_DEBUG_TX_QUEUES(mvm, "Flush AGG: sta %d tid %d q %d state %d\n",
3459 iwl_mvm_unreserve_agg_queue(mvm, mvmsta, tid_data);
3462 iwl_mvm_drain_sta(mvm, mvmsta, true);
3464 if (iwl_mvm_has_new_tx_api(mvm)) {
3465 if (iwl_mvm_flush_sta_tids(mvm, mvmsta->deflink.sta_id,
3467 IWL_ERR(mvm, "Couldn't flush the AGG queue\n");
3468 iwl_trans_wait_txq_empty(mvm->trans, txq_id);
3470 if (iwl_mvm_flush_tx_path(mvm, BIT(txq_id)))
3471 IWL_ERR(mvm, "Couldn't flush the AGG queue\n");
3472 iwl_trans_wait_tx_queues_empty(mvm->trans, BIT(txq_id));
3475 iwl_mvm_drain_sta(mvm, mvmsta, false);
3477 iwl_mvm_sta_tx_agg(mvm, sta, tid, txq_id, false);
3483 static int iwl_mvm_set_fw_key_idx(struct iwl_mvm *mvm)
3487 lockdep_assert_held(&mvm->mutex);
3496 if (test_bit(i, mvm->fw_key_table))
3498 if (mvm->fw_key_deleted[i] > max) {
3499 max = mvm->fw_key_deleted[i];
3510 static struct iwl_mvm_sta *iwl_mvm_get_key_sta(struct iwl_mvm *mvm,
3528 sta = rcu_dereference_check(mvm->fw_id_to_mac_id[sta_id],
3529 lockdep_is_held(&mvm->mutex));
3559 static int iwl_mvm_send_sta_key(struct iwl_mvm *mvm,
3575 bool new_api = fw_has_api(&mvm->fw->ucode_capa,
3577 int api_ver = iwl_fw_lookup_cmd_ver(mvm->fw, ADD_STA_KEY,
3696 ret = iwl_mvm_send_cmd_pdu(mvm, ADD_STA_KEY, CMD_ASYNC, size,
3699 ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA_KEY, size,
3704 IWL_DEBUG_WEP(mvm, "MODIFY_STA: set dynamic key passed\n");
3708 IWL_ERR(mvm, "MODIFY_STA: set dynamic key failed\n");
3715 static int iwl_mvm_send_sta_igtk(struct iwl_mvm *mvm,
3730 if (WARN_ON(!iwl_mvm_has_new_rx_api(mvm) &&
3773 IWL_DEBUG_INFO(mvm, "%s %sIGTK (%d) for sta %u\n",
3778 if (!iwl_mvm_has_new_rx_api(mvm)) {
3788 return iwl_mvm_send_cmd_pdu(mvm, MGMT_MCAST_KEY, 0,
3791 return iwl_mvm_send_cmd_pdu(mvm, MGMT_MCAST_KEY, 0,
3796 static inline u8 *iwl_mvm_get_mac_addr(struct iwl_mvm *mvm,
3808 sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[sta_id],
3809 lockdep_is_held(&mvm->mutex));
3820 static int __iwl_mvm_set_sta_key(struct iwl_mvm *mvm,
3844 IWL_ERR(mvm, "Failed to find station id\n");
3849 addr = iwl_mvm_get_mac_addr(mvm, vif, sta);
3851 IWL_ERR(mvm, "Failed to find mac address\n");
3859 return iwl_mvm_send_sta_key(mvm, sta_id, keyconf, mcast,
3864 return iwl_mvm_send_sta_key(mvm, sta_id, keyconf, mcast,
3868 int iwl_mvm_set_sta_key(struct iwl_mvm *mvm,
3880 lockdep_assert_held(&mvm->mutex);
3884 /* Get the station id from the mvm local station table */
3885 mvm_sta = iwl_mvm_get_key_sta(mvm, vif, sta);
3887 IWL_ERR(mvm, "Failed to find station\n");
3899 mvm->fw_id_to_mac_id[sta_id],
3900 lockdep_is_held(&mvm->mutex));
3902 IWL_ERR(mvm, "Invalid station id\n");
3918 ret = iwl_mvm_send_sta_igtk(mvm, keyconf, sta_id, false);
3934 key_offset = iwl_mvm_set_fw_key_idx(mvm);
3940 ret = __iwl_mvm_set_sta_key(mvm, vif, sta, keyconf, key_offset, mcast);
3953 ret = __iwl_mvm_set_sta_key(mvm, vif, sta, keyconf,
3956 __iwl_mvm_remove_sta_key(mvm, sta_id, keyconf, mcast);
3961 __set_bit(key_offset, mvm->fw_key_table);
3964 IWL_DEBUG_WEP(mvm, "key: cipher=%x len=%d idx=%d sta=%pM ret=%d\n",
3970 int iwl_mvm_remove_sta_key(struct iwl_mvm *mvm,
3980 lockdep_assert_held(&mvm->mutex);
3982 /* Get the station from the mvm local station table */
3983 mvm_sta = iwl_mvm_get_key_sta(mvm, vif, sta);
3990 IWL_DEBUG_WEP(mvm, "mvm remove dynamic key: idx=%d sta=%d\n",
3996 return iwl_mvm_send_sta_igtk(mvm, keyconf, sta_id, true);
3998 if (!__test_and_clear_bit(keyconf->hw_key_idx, mvm->fw_key_table)) {
3999 IWL_ERR(mvm, "offset %d not used in fw key table.\n",
4006 if (mvm->fw_key_deleted[i] < U8_MAX)
4007 mvm->fw_key_deleted[i]++;
4009 mvm->fw_key_deleted[keyconf->hw_key_idx] = 0;
4012 IWL_DEBUG_WEP(mvm, "station non-existent, early return.\n");
4016 ret = __iwl_mvm_remove_sta_key(mvm, sta_id, keyconf, mcast);
4023 ret = __iwl_mvm_remove_sta_key(mvm, sta_id, keyconf, !mcast);
4028 void iwl_mvm_update_tkip_key(struct iwl_mvm *mvm,
4040 mvm_sta = iwl_mvm_get_key_sta(mvm, vif, sta);
4043 iwl_mvm_send_sta_key(mvm, mvm_sta->deflink.sta_id, keyconf, mcast,
4051 void iwl_mvm_sta_modify_ps_wake(struct iwl_mvm *mvm,
4063 ret = iwl_mvm_send_cmd_pdu(mvm, ADD_STA, CMD_ASYNC,
4064 iwl_mvm_add_sta_cmd_size(mvm), &cmd);
4066 IWL_ERR(mvm, "Failed to send ADD_STA command (%d)\n", ret);
4069 void iwl_mvm_sta_modify_sleep_tx_count(struct iwl_mvm *mvm,
4111 n_queued = iwl_mvm_tid_queued(mvm, tid_data);
4143 ret = iwl_mvm_send_cmd_pdu(mvm, ADD_STA,
4145 iwl_mvm_add_sta_cmd_size(mvm), &cmd);
4147 IWL_ERR(mvm, "Failed to send ADD_STA command (%d)\n", ret);
4150 void iwl_mvm_rx_eosp_notif(struct iwl_mvm *mvm,
4158 if (WARN_ON_ONCE(sta_id >= mvm->fw->ucode_capa.num_stations))
4162 sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]);
4168 void iwl_mvm_sta_modify_disable_tx(struct iwl_mvm *mvm,
4181 if (mvm->mld_api_is_used) {
4182 if (!iwl_mvm_has_no_host_disable_tx(mvm))
4183 iwl_mvm_mld_sta_modify_disable_tx(mvm, mvmsta, disable);
4187 ret = iwl_mvm_send_cmd_pdu(mvm, ADD_STA, CMD_ASYNC,
4188 iwl_mvm_add_sta_cmd_size(mvm), &cmd);
4190 IWL_ERR(mvm, "Failed to send ADD_STA command (%d)\n", ret);
4193 void iwl_mvm_sta_modify_disable_tx_ap(struct iwl_mvm *mvm,
4199 if (mvm->mld_api_is_used) {
4200 if (!iwl_mvm_has_no_host_disable_tx(mvm))
4201 iwl_mvm_mld_sta_modify_disable_tx_ap(mvm, sta, disable);
4218 if (!ieee80211_hw_check(mvm->hw, AP_LINK_PS))
4219 ieee80211_sta_block_awake(mvm->hw, sta, disable);
4221 iwl_mvm_sta_modify_disable_tx(mvm, mvm_sta, disable);
4226 static void iwl_mvm_int_sta_modify_disable_tx(struct iwl_mvm *mvm,
4241 ret = iwl_mvm_send_cmd_pdu(mvm, ADD_STA, CMD_ASYNC,
4242 iwl_mvm_add_sta_cmd_size(mvm), &cmd);
4244 IWL_ERR(mvm, "Failed to send ADD_STA command (%d)\n", ret);
4247 void iwl_mvm_modify_all_sta_disable_tx(struct iwl_mvm *mvm,
4255 if (mvm->mld_api_is_used) {
4256 if (!iwl_mvm_has_no_host_disable_tx(mvm))
4257 iwl_mvm_mld_modify_all_sta_disable_tx(mvm, mvmvif,
4265 for (i = 0; i < mvm->fw->ucode_capa.num_stations; i++) {
4266 sta = rcu_dereference(mvm->fw_id_to_mac_id[i]);
4275 iwl_mvm_sta_modify_disable_tx_ap(mvm, sta, disable);
4280 if (!fw_has_api(&mvm->fw->ucode_capa, IWL_UCODE_TLV_API_STA_TYPE))
4285 iwl_mvm_int_sta_modify_disable_tx(mvm, mvmvif,
4294 iwl_mvm_int_sta_modify_disable_tx(mvm, mvmvif,
4299 void iwl_mvm_csa_client_absent(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
4306 mvmsta = iwl_mvm_sta_from_staid_rcu(mvm, mvmvif->deflink.ap_sta_id);
4309 iwl_mvm_sta_modify_disable_tx(mvm, mvmsta, true);
4314 u16 iwl_mvm_tid_queued(struct iwl_mvm *mvm, struct iwl_mvm_tid_data *tid_data)
4322 if (mvm->trans->trans_cfg->gen2)
4329 int iwl_mvm_add_pasn_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
4338 iwl_mvm_get_wd_timeout(mvm, vif, false, false);
4339 bool mld = iwl_mvm_has_mld_api(mvm->fw);
4342 ret = iwl_mvm_allocate_int_sta(mvm, sta, 0,
4348 ret = iwl_mvm_mld_add_int_sta_with_queue(mvm, sta, addr,
4354 ret = iwl_mvm_add_int_sta_with_queue(mvm, mvmvif->id,
4371 iwl_mvm_get_sec_flags(mvm, vif, NULL, keyconf) |
4375 ret = iwl_mvm_mld_send_key(mvm, sta_mask, key_flags, keyconf);
4377 ret = iwl_mvm_send_sta_key(mvm, sta->sta_id, keyconf, false,
4383 iwl_mvm_dealloc_int_sta(mvm, sta);
4388 void iwl_mvm_cancel_channel_switch(struct iwl_mvm *mvm,
4397 ret = iwl_mvm_send_cmd_pdu(mvm,
4403 IWL_ERR(mvm, "Failed to cancel the channel switch\n");
4410 rcu_dereference(mvmvif->mvm->fw_id_to_link_sta[fw_sta_id]);
4430 struct iwl_mvm *mvm = mvmvif->mvm;
4468 IWL_DEBUG_STATS(mvm, "MPDU counters are cleared\n");
4476 wiphy_work_queue(mvmvif->mvm->hw->wiphy,