19af1bba4SBjoern A. Zeeb // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause 29af1bba4SBjoern A. Zeeb /* 3*a4128aadSBjoern A. Zeeb * Copyright (C) 2022 - 2024 Intel Corporation 49af1bba4SBjoern A. Zeeb */ 59af1bba4SBjoern A. Zeeb #include "mvm.h" 69af1bba4SBjoern A. Zeeb 79af1bba4SBjoern A. Zeeb static void iwl_mvm_mld_set_he_support(struct iwl_mvm *mvm, 89af1bba4SBjoern A. Zeeb struct ieee80211_vif *vif, 99af1bba4SBjoern A. Zeeb struct iwl_mac_config_cmd *cmd) 109af1bba4SBjoern A. Zeeb { 119af1bba4SBjoern A. Zeeb if (vif->type == NL80211_IFTYPE_AP) 129af1bba4SBjoern A. Zeeb cmd->he_ap_support = cpu_to_le16(1); 139af1bba4SBjoern A. Zeeb else 149af1bba4SBjoern A. Zeeb cmd->he_support = cpu_to_le16(1); 159af1bba4SBjoern A. Zeeb } 169af1bba4SBjoern A. Zeeb 179af1bba4SBjoern A. Zeeb static void iwl_mvm_mld_mac_ctxt_cmd_common(struct iwl_mvm *mvm, 189af1bba4SBjoern A. Zeeb struct ieee80211_vif *vif, 199af1bba4SBjoern A. Zeeb struct iwl_mac_config_cmd *cmd, 209af1bba4SBjoern A. Zeeb u32 action) 219af1bba4SBjoern A. Zeeb { 229af1bba4SBjoern A. Zeeb struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 239af1bba4SBjoern A. Zeeb struct ieee80211_bss_conf *link_conf; 249af1bba4SBjoern A. Zeeb unsigned int link_id; 259af1bba4SBjoern A. Zeeb 269af1bba4SBjoern A. Zeeb cmd->id_and_color = cpu_to_le32(mvmvif->id); 279af1bba4SBjoern A. Zeeb cmd->action = cpu_to_le32(action); 289af1bba4SBjoern A. Zeeb 299af1bba4SBjoern A. Zeeb cmd->mac_type = cpu_to_le32(iwl_mvm_get_mac_type(vif)); 309af1bba4SBjoern A. Zeeb 319af1bba4SBjoern A. Zeeb memcpy(cmd->local_mld_addr, vif->addr, ETH_ALEN); 329af1bba4SBjoern A. Zeeb 339af1bba4SBjoern A. Zeeb cmd->he_support = 0; 349af1bba4SBjoern A. Zeeb cmd->eht_support = 0; 359af1bba4SBjoern A. Zeeb 369af1bba4SBjoern A. Zeeb /* should be set by specific context type handler */ 379af1bba4SBjoern A. Zeeb cmd->filter_flags = 0; 389af1bba4SBjoern A. Zeeb 399af1bba4SBjoern A. Zeeb cmd->nic_not_ack_enabled = 409af1bba4SBjoern A. Zeeb cpu_to_le32(!iwl_mvm_is_nic_ack_enabled(mvm, vif)); 419af1bba4SBjoern A. Zeeb 429af1bba4SBjoern A. Zeeb if (iwlwifi_mod_params.disable_11ax) 439af1bba4SBjoern A. Zeeb return; 449af1bba4SBjoern A. Zeeb 459af1bba4SBjoern A. Zeeb /* If we have MLO enabled, then the firmware needs to enable 469af1bba4SBjoern A. Zeeb * address translation for the station(s) we add. That depends 479af1bba4SBjoern A. Zeeb * on having EHT enabled in firmware, which in turn depends on 489af1bba4SBjoern A. Zeeb * mac80211 in the code below. 499af1bba4SBjoern A. Zeeb * However, mac80211 doesn't enable HE/EHT until it has parsed 509af1bba4SBjoern A. Zeeb * the association response successfully, so just skip all that 519af1bba4SBjoern A. Zeeb * and enable both when we have MLO. 529af1bba4SBjoern A. Zeeb */ 539af1bba4SBjoern A. Zeeb if (ieee80211_vif_is_mld(vif)) { 549af1bba4SBjoern A. Zeeb iwl_mvm_mld_set_he_support(mvm, vif, cmd); 559af1bba4SBjoern A. Zeeb cmd->eht_support = cpu_to_le32(1); 569af1bba4SBjoern A. Zeeb return; 579af1bba4SBjoern A. Zeeb } 589af1bba4SBjoern A. Zeeb 599af1bba4SBjoern A. Zeeb rcu_read_lock(); 609af1bba4SBjoern A. Zeeb for (link_id = 0; link_id < ARRAY_SIZE((vif)->link_conf); link_id++) { 619af1bba4SBjoern A. Zeeb link_conf = rcu_dereference(vif->link_conf[link_id]); 629af1bba4SBjoern A. Zeeb if (!link_conf) 639af1bba4SBjoern A. Zeeb continue; 649af1bba4SBjoern A. Zeeb 659af1bba4SBjoern A. Zeeb if (link_conf->he_support) 669af1bba4SBjoern A. Zeeb iwl_mvm_mld_set_he_support(mvm, vif, cmd); 679af1bba4SBjoern A. Zeeb 689af1bba4SBjoern A. Zeeb /* it's not reasonable to have EHT without HE and FW API doesn't 699af1bba4SBjoern A. Zeeb * support it. Ignore EHT in this case. 709af1bba4SBjoern A. Zeeb */ 719af1bba4SBjoern A. Zeeb if (!link_conf->he_support && link_conf->eht_support) 729af1bba4SBjoern A. Zeeb continue; 739af1bba4SBjoern A. Zeeb 749af1bba4SBjoern A. Zeeb if (link_conf->eht_support) { 759af1bba4SBjoern A. Zeeb cmd->eht_support = cpu_to_le32(1); 769af1bba4SBjoern A. Zeeb break; 779af1bba4SBjoern A. Zeeb } 789af1bba4SBjoern A. Zeeb } 799af1bba4SBjoern A. Zeeb rcu_read_unlock(); 809af1bba4SBjoern A. Zeeb } 819af1bba4SBjoern A. Zeeb 829af1bba4SBjoern A. Zeeb static int iwl_mvm_mld_mac_ctxt_send_cmd(struct iwl_mvm *mvm, 839af1bba4SBjoern A. Zeeb struct iwl_mac_config_cmd *cmd) 849af1bba4SBjoern A. Zeeb { 859af1bba4SBjoern A. Zeeb int ret = iwl_mvm_send_cmd_pdu(mvm, 869af1bba4SBjoern A. Zeeb WIDE_ID(MAC_CONF_GROUP, MAC_CONFIG_CMD), 879af1bba4SBjoern A. Zeeb 0, sizeof(*cmd), cmd); 889af1bba4SBjoern A. Zeeb if (ret) 899af1bba4SBjoern A. Zeeb IWL_ERR(mvm, "Failed to send MAC_CONFIG_CMD (action:%d): %d\n", 909af1bba4SBjoern A. Zeeb le32_to_cpu(cmd->action), ret); 919af1bba4SBjoern A. Zeeb return ret; 929af1bba4SBjoern A. Zeeb } 939af1bba4SBjoern A. Zeeb 949af1bba4SBjoern A. Zeeb static int iwl_mvm_mld_mac_ctxt_cmd_sta(struct iwl_mvm *mvm, 959af1bba4SBjoern A. Zeeb struct ieee80211_vif *vif, 969af1bba4SBjoern A. Zeeb u32 action, bool force_assoc_off) 979af1bba4SBjoern A. Zeeb { 989af1bba4SBjoern A. Zeeb struct iwl_mac_config_cmd cmd = {}; 999af1bba4SBjoern A. Zeeb u16 esr_transition_timeout; 1009af1bba4SBjoern A. Zeeb 1019af1bba4SBjoern A. Zeeb WARN_ON(vif->type != NL80211_IFTYPE_STATION); 1029af1bba4SBjoern A. Zeeb 1039af1bba4SBjoern A. Zeeb /* Fill the common data for all mac context types */ 1049af1bba4SBjoern A. Zeeb iwl_mvm_mld_mac_ctxt_cmd_common(mvm, vif, &cmd, action); 1059af1bba4SBjoern A. Zeeb 1069af1bba4SBjoern A. Zeeb /* 1079af1bba4SBjoern A. Zeeb * We always want to hear MCAST frames, if we're not authorized yet, 1089af1bba4SBjoern A. Zeeb * we'll drop them. 1099af1bba4SBjoern A. Zeeb */ 1109af1bba4SBjoern A. Zeeb cmd.filter_flags |= cpu_to_le32(MAC_CFG_FILTER_ACCEPT_GRP); 1119af1bba4SBjoern A. Zeeb 1129af1bba4SBjoern A. Zeeb if (vif->p2p) 1139af1bba4SBjoern A. Zeeb cmd.client.ctwin = 1149af1bba4SBjoern A. Zeeb iwl_mvm_mac_ctxt_cmd_p2p_sta_get_oppps_ctwin(mvm, vif); 1159af1bba4SBjoern A. Zeeb 1169af1bba4SBjoern A. Zeeb if (vif->cfg.assoc && !force_assoc_off) { 1179af1bba4SBjoern A. Zeeb struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 1189af1bba4SBjoern A. Zeeb 1199af1bba4SBjoern A. Zeeb cmd.client.is_assoc = 1; 1209af1bba4SBjoern A. Zeeb 1219af1bba4SBjoern A. Zeeb if (!mvmvif->authorized && 1229af1bba4SBjoern A. Zeeb fw_has_capa(&mvm->fw->ucode_capa, 1239af1bba4SBjoern A. Zeeb IWL_UCODE_TLV_CAPA_COEX_HIGH_PRIO)) 1249af1bba4SBjoern A. Zeeb cmd.client.data_policy |= 1259af1bba4SBjoern A. Zeeb cpu_to_le16(COEX_HIGH_PRIORITY_ENABLE); 1269af1bba4SBjoern A. Zeeb 1279af1bba4SBjoern A. Zeeb } else { 1289af1bba4SBjoern A. Zeeb cmd.client.is_assoc = 0; 1299af1bba4SBjoern A. Zeeb 1309af1bba4SBjoern A. Zeeb /* Allow beacons to pass through as long as we are not 1319af1bba4SBjoern A. Zeeb * associated, or we do not have dtim period information. 1329af1bba4SBjoern A. Zeeb */ 1339af1bba4SBjoern A. Zeeb cmd.filter_flags |= cpu_to_le32(MAC_CFG_FILTER_ACCEPT_BEACON); 1349af1bba4SBjoern A. Zeeb } 1359af1bba4SBjoern A. Zeeb 1369af1bba4SBjoern A. Zeeb cmd.client.assoc_id = cpu_to_le16(vif->cfg.aid); 1379af1bba4SBjoern A. Zeeb if (ieee80211_vif_is_mld(vif)) { 1389af1bba4SBjoern A. Zeeb esr_transition_timeout = 1399af1bba4SBjoern A. Zeeb u16_get_bits(vif->cfg.eml_cap, 1409af1bba4SBjoern A. Zeeb IEEE80211_EML_CAP_TRANSITION_TIMEOUT); 1419af1bba4SBjoern A. Zeeb 1429af1bba4SBjoern A. Zeeb cmd.client.esr_transition_timeout = 1439af1bba4SBjoern A. Zeeb min_t(u16, IEEE80211_EML_CAP_TRANSITION_TIMEOUT_128TU, 1449af1bba4SBjoern A. Zeeb esr_transition_timeout); 1459af1bba4SBjoern A. Zeeb cmd.client.medium_sync_delay = 1469af1bba4SBjoern A. Zeeb cpu_to_le16(vif->cfg.eml_med_sync_delay); 1479af1bba4SBjoern A. Zeeb } 1489af1bba4SBjoern A. Zeeb 1499af1bba4SBjoern A. Zeeb if (vif->probe_req_reg && vif->cfg.assoc && vif->p2p) 1509af1bba4SBjoern A. Zeeb cmd.filter_flags |= cpu_to_le32(MAC_CFG_FILTER_ACCEPT_PROBE_REQ); 1519af1bba4SBjoern A. Zeeb 1529af1bba4SBjoern A. Zeeb if (vif->bss_conf.he_support && !iwlwifi_mod_params.disable_11ax) 1539af1bba4SBjoern A. Zeeb cmd.client.data_policy |= 1549af1bba4SBjoern A. Zeeb cpu_to_le16(iwl_mvm_mac_ctxt_cmd_sta_get_twt_policy(mvm, vif)); 1559af1bba4SBjoern A. Zeeb 1569af1bba4SBjoern A. Zeeb return iwl_mvm_mld_mac_ctxt_send_cmd(mvm, &cmd); 1579af1bba4SBjoern A. Zeeb } 1589af1bba4SBjoern A. Zeeb 1599af1bba4SBjoern A. Zeeb static int iwl_mvm_mld_mac_ctxt_cmd_listener(struct iwl_mvm *mvm, 1609af1bba4SBjoern A. Zeeb struct ieee80211_vif *vif, 1619af1bba4SBjoern A. Zeeb u32 action) 1629af1bba4SBjoern A. Zeeb { 1639af1bba4SBjoern A. Zeeb struct iwl_mac_config_cmd cmd = {}; 1649af1bba4SBjoern A. Zeeb 1659af1bba4SBjoern A. Zeeb WARN_ON(vif->type != NL80211_IFTYPE_MONITOR); 1669af1bba4SBjoern A. Zeeb 1679af1bba4SBjoern A. Zeeb iwl_mvm_mld_mac_ctxt_cmd_common(mvm, vif, &cmd, action); 1689af1bba4SBjoern A. Zeeb 1699af1bba4SBjoern A. Zeeb cmd.filter_flags = cpu_to_le32(MAC_CFG_FILTER_PROMISC | 170*a4128aadSBjoern A. Zeeb MAC_CFG_FILTER_ACCEPT_CONTROL_AND_MGMT | 1719af1bba4SBjoern A. Zeeb MAC_CFG_FILTER_ACCEPT_BEACON | 1729af1bba4SBjoern A. Zeeb MAC_CFG_FILTER_ACCEPT_PROBE_REQ | 1739af1bba4SBjoern A. Zeeb MAC_CFG_FILTER_ACCEPT_GRP); 1749af1bba4SBjoern A. Zeeb 1759af1bba4SBjoern A. Zeeb return iwl_mvm_mld_mac_ctxt_send_cmd(mvm, &cmd); 1769af1bba4SBjoern A. Zeeb } 1779af1bba4SBjoern A. Zeeb 1789af1bba4SBjoern A. Zeeb static int iwl_mvm_mld_mac_ctxt_cmd_ibss(struct iwl_mvm *mvm, 1799af1bba4SBjoern A. Zeeb struct ieee80211_vif *vif, 1809af1bba4SBjoern A. Zeeb u32 action) 1819af1bba4SBjoern A. Zeeb { 1829af1bba4SBjoern A. Zeeb struct iwl_mac_config_cmd cmd = {}; 1839af1bba4SBjoern A. Zeeb 1849af1bba4SBjoern A. Zeeb WARN_ON(vif->type != NL80211_IFTYPE_ADHOC); 1859af1bba4SBjoern A. Zeeb 1869af1bba4SBjoern A. Zeeb iwl_mvm_mld_mac_ctxt_cmd_common(mvm, vif, &cmd, action); 1879af1bba4SBjoern A. Zeeb 1889af1bba4SBjoern A. Zeeb cmd.filter_flags = cpu_to_le32(MAC_CFG_FILTER_ACCEPT_BEACON | 1899af1bba4SBjoern A. Zeeb MAC_CFG_FILTER_ACCEPT_PROBE_REQ | 1909af1bba4SBjoern A. Zeeb MAC_CFG_FILTER_ACCEPT_GRP); 1919af1bba4SBjoern A. Zeeb 1929af1bba4SBjoern A. Zeeb return iwl_mvm_mld_mac_ctxt_send_cmd(mvm, &cmd); 1939af1bba4SBjoern A. Zeeb } 1949af1bba4SBjoern A. Zeeb 1959af1bba4SBjoern A. Zeeb static int iwl_mvm_mld_mac_ctxt_cmd_p2p_device(struct iwl_mvm *mvm, 1969af1bba4SBjoern A. Zeeb struct ieee80211_vif *vif, 1979af1bba4SBjoern A. Zeeb u32 action) 1989af1bba4SBjoern A. Zeeb { 1999af1bba4SBjoern A. Zeeb struct iwl_mac_config_cmd cmd = {}; 2009af1bba4SBjoern A. Zeeb 2019af1bba4SBjoern A. Zeeb WARN_ON(vif->type != NL80211_IFTYPE_P2P_DEVICE); 2029af1bba4SBjoern A. Zeeb 2039af1bba4SBjoern A. Zeeb iwl_mvm_mld_mac_ctxt_cmd_common(mvm, vif, &cmd, action); 2049af1bba4SBjoern A. Zeeb 2059af1bba4SBjoern A. Zeeb cmd.p2p_dev.is_disc_extended = 2069af1bba4SBjoern A. Zeeb iwl_mac_ctxt_p2p_dev_has_extended_disc(mvm, vif); 2079af1bba4SBjoern A. Zeeb 208*a4128aadSBjoern A. Zeeb /* Override the filter flags to accept all management frames. This is 209*a4128aadSBjoern A. Zeeb * needed to support both P2P device discovery using probe requests and 210*a4128aadSBjoern A. Zeeb * P2P service discovery using action frames 211*a4128aadSBjoern A. Zeeb */ 212*a4128aadSBjoern A. Zeeb cmd.filter_flags = cpu_to_le32(MAC_CFG_FILTER_ACCEPT_CONTROL_AND_MGMT); 2139af1bba4SBjoern A. Zeeb 2149af1bba4SBjoern A. Zeeb return iwl_mvm_mld_mac_ctxt_send_cmd(mvm, &cmd); 2159af1bba4SBjoern A. Zeeb } 2169af1bba4SBjoern A. Zeeb 2179af1bba4SBjoern A. Zeeb static int iwl_mvm_mld_mac_ctxt_cmd_ap_go(struct iwl_mvm *mvm, 2189af1bba4SBjoern A. Zeeb struct ieee80211_vif *vif, 2199af1bba4SBjoern A. Zeeb u32 action) 2209af1bba4SBjoern A. Zeeb { 2219af1bba4SBjoern A. Zeeb struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 2229af1bba4SBjoern A. Zeeb struct iwl_mac_config_cmd cmd = {}; 2239af1bba4SBjoern A. Zeeb 2249af1bba4SBjoern A. Zeeb WARN_ON(vif->type != NL80211_IFTYPE_AP); 2259af1bba4SBjoern A. Zeeb 2269af1bba4SBjoern A. Zeeb /* Fill the common data for all mac context types */ 2279af1bba4SBjoern A. Zeeb iwl_mvm_mld_mac_ctxt_cmd_common(mvm, vif, &cmd, action); 2289af1bba4SBjoern A. Zeeb 2299af1bba4SBjoern A. Zeeb iwl_mvm_mac_ctxt_cmd_ap_set_filter_flags(mvm, mvmvif, 2309af1bba4SBjoern A. Zeeb &cmd.filter_flags, 2319af1bba4SBjoern A. Zeeb MAC_CFG_FILTER_ACCEPT_PROBE_REQ, 2329af1bba4SBjoern A. Zeeb MAC_CFG_FILTER_ACCEPT_BEACON); 2339af1bba4SBjoern A. Zeeb 2349af1bba4SBjoern A. Zeeb return iwl_mvm_mld_mac_ctxt_send_cmd(mvm, &cmd); 2359af1bba4SBjoern A. Zeeb } 2369af1bba4SBjoern A. Zeeb 2379af1bba4SBjoern A. Zeeb static int iwl_mvm_mld_mac_ctx_send(struct iwl_mvm *mvm, 2389af1bba4SBjoern A. Zeeb struct ieee80211_vif *vif, 2399af1bba4SBjoern A. Zeeb u32 action, bool force_assoc_off) 2409af1bba4SBjoern A. Zeeb { 2419af1bba4SBjoern A. Zeeb switch (vif->type) { 2429af1bba4SBjoern A. Zeeb case NL80211_IFTYPE_STATION: 2439af1bba4SBjoern A. Zeeb return iwl_mvm_mld_mac_ctxt_cmd_sta(mvm, vif, action, 2449af1bba4SBjoern A. Zeeb force_assoc_off); 2459af1bba4SBjoern A. Zeeb case NL80211_IFTYPE_AP: 2469af1bba4SBjoern A. Zeeb return iwl_mvm_mld_mac_ctxt_cmd_ap_go(mvm, vif, action); 2479af1bba4SBjoern A. Zeeb case NL80211_IFTYPE_MONITOR: 2489af1bba4SBjoern A. Zeeb return iwl_mvm_mld_mac_ctxt_cmd_listener(mvm, vif, action); 2499af1bba4SBjoern A. Zeeb case NL80211_IFTYPE_P2P_DEVICE: 2509af1bba4SBjoern A. Zeeb return iwl_mvm_mld_mac_ctxt_cmd_p2p_device(mvm, vif, action); 2519af1bba4SBjoern A. Zeeb case NL80211_IFTYPE_ADHOC: 2529af1bba4SBjoern A. Zeeb return iwl_mvm_mld_mac_ctxt_cmd_ibss(mvm, vif, action); 2539af1bba4SBjoern A. Zeeb default: 2549af1bba4SBjoern A. Zeeb break; 2559af1bba4SBjoern A. Zeeb } 2569af1bba4SBjoern A. Zeeb 2579af1bba4SBjoern A. Zeeb return -EOPNOTSUPP; 2589af1bba4SBjoern A. Zeeb } 2599af1bba4SBjoern A. Zeeb 2609af1bba4SBjoern A. Zeeb int iwl_mvm_mld_mac_ctxt_add(struct iwl_mvm *mvm, struct ieee80211_vif *vif) 2619af1bba4SBjoern A. Zeeb { 2629af1bba4SBjoern A. Zeeb struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 2639af1bba4SBjoern A. Zeeb int ret; 2649af1bba4SBjoern A. Zeeb 2659af1bba4SBjoern A. Zeeb if (WARN_ON_ONCE(vif->type == NL80211_IFTYPE_NAN)) 2669af1bba4SBjoern A. Zeeb return -EOPNOTSUPP; 2679af1bba4SBjoern A. Zeeb 2689af1bba4SBjoern A. Zeeb if (WARN_ONCE(mvmvif->uploaded, "Adding active MAC %pM/%d\n", 2699af1bba4SBjoern A. Zeeb vif->addr, ieee80211_vif_type_p2p(vif))) 2709af1bba4SBjoern A. Zeeb return -EIO; 2719af1bba4SBjoern A. Zeeb 2729af1bba4SBjoern A. Zeeb ret = iwl_mvm_mld_mac_ctx_send(mvm, vif, FW_CTXT_ACTION_ADD, 2739af1bba4SBjoern A. Zeeb true); 2749af1bba4SBjoern A. Zeeb if (ret) 2759af1bba4SBjoern A. Zeeb return ret; 2769af1bba4SBjoern A. Zeeb 2779af1bba4SBjoern A. Zeeb /* will only do anything at resume from D3 time */ 2789af1bba4SBjoern A. Zeeb iwl_mvm_set_last_nonqos_seq(mvm, vif); 2799af1bba4SBjoern A. Zeeb 2809af1bba4SBjoern A. Zeeb mvmvif->uploaded = true; 2819af1bba4SBjoern A. Zeeb return 0; 2829af1bba4SBjoern A. Zeeb } 2839af1bba4SBjoern A. Zeeb 2849af1bba4SBjoern A. Zeeb int iwl_mvm_mld_mac_ctxt_changed(struct iwl_mvm *mvm, 2859af1bba4SBjoern A. Zeeb struct ieee80211_vif *vif, 2869af1bba4SBjoern A. Zeeb bool force_assoc_off) 2879af1bba4SBjoern A. Zeeb { 2889af1bba4SBjoern A. Zeeb struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 2899af1bba4SBjoern A. Zeeb 2909af1bba4SBjoern A. Zeeb if (WARN_ON_ONCE(vif->type == NL80211_IFTYPE_NAN)) 2919af1bba4SBjoern A. Zeeb return -EOPNOTSUPP; 2929af1bba4SBjoern A. Zeeb 2939af1bba4SBjoern A. Zeeb if (WARN_ONCE(!mvmvif->uploaded, "Changing inactive MAC %pM/%d\n", 2949af1bba4SBjoern A. Zeeb vif->addr, ieee80211_vif_type_p2p(vif))) 2959af1bba4SBjoern A. Zeeb return -EIO; 2969af1bba4SBjoern A. Zeeb 2979af1bba4SBjoern A. Zeeb return iwl_mvm_mld_mac_ctx_send(mvm, vif, FW_CTXT_ACTION_MODIFY, 2989af1bba4SBjoern A. Zeeb force_assoc_off); 2999af1bba4SBjoern A. Zeeb } 3009af1bba4SBjoern A. Zeeb 3019af1bba4SBjoern A. Zeeb int iwl_mvm_mld_mac_ctxt_remove(struct iwl_mvm *mvm, struct ieee80211_vif *vif) 3029af1bba4SBjoern A. Zeeb { 3039af1bba4SBjoern A. Zeeb struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 3049af1bba4SBjoern A. Zeeb struct iwl_mac_config_cmd cmd = { 3059af1bba4SBjoern A. Zeeb .action = cpu_to_le32(FW_CTXT_ACTION_REMOVE), 3069af1bba4SBjoern A. Zeeb .id_and_color = cpu_to_le32(mvmvif->id), 3079af1bba4SBjoern A. Zeeb }; 3089af1bba4SBjoern A. Zeeb int ret; 3099af1bba4SBjoern A. Zeeb 3109af1bba4SBjoern A. Zeeb if (WARN_ON_ONCE(vif->type == NL80211_IFTYPE_NAN)) 3119af1bba4SBjoern A. Zeeb return -EOPNOTSUPP; 3129af1bba4SBjoern A. Zeeb 3139af1bba4SBjoern A. Zeeb if (WARN_ONCE(!mvmvif->uploaded, "Removing inactive MAC %pM/%d\n", 3149af1bba4SBjoern A. Zeeb vif->addr, ieee80211_vif_type_p2p(vif))) 3159af1bba4SBjoern A. Zeeb return -EIO; 3169af1bba4SBjoern A. Zeeb 3179af1bba4SBjoern A. Zeeb ret = iwl_mvm_mld_mac_ctxt_send_cmd(mvm, &cmd); 3189af1bba4SBjoern A. Zeeb if (ret) 3199af1bba4SBjoern A. Zeeb return ret; 3209af1bba4SBjoern A. Zeeb 3219af1bba4SBjoern A. Zeeb mvmvif->uploaded = false; 3229af1bba4SBjoern A. Zeeb 3239af1bba4SBjoern A. Zeeb return 0; 3249af1bba4SBjoern A. Zeeb } 325