// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/*
 * Copyright (C) 2024-2025 Intel Corporation
 */
#include <net/cfg80211.h>

#include "iface.h"
#include "hcmd.h"
#include "key.h"
#include "mlo.h"
#include "mac80211.h"

#include "fw/api/context.h"
#include "fw/api/mac.h"
#include "fw/api/time-event.h"
#include "fw/api/datapath.h"

/* Cleanup function for struct iwl_mld_vif, will be called in restart */
void iwl_mld_cleanup_vif(void *data, u8 *mac, struct ieee80211_vif *vif)
{
	struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(vif);
	struct iwl_mld *mld = mld_vif->mld;
	struct iwl_mld_link *link;

	mld_vif->emlsr.blocked_reasons &= ~IWL_MLD_EMLSR_BLOCKED_ROC;

	if (mld_vif->aux_sta.sta_id != IWL_INVALID_STA)
		iwl_mld_free_internal_sta(mld, &mld_vif->aux_sta);

	/* EMLSR is turned back on during recovery */
	vif->driver_flags &= ~IEEE80211_VIF_EML_ACTIVE;

	if (mld_vif->roc_activity != ROC_NUM_ACTIVITIES)
		ieee80211_remain_on_channel_expired(mld->hw);

	mld_vif->roc_activity = ROC_NUM_ACTIVITIES;

	for_each_mld_vif_valid_link(mld_vif, link) {
		iwl_mld_cleanup_link(mld_vif->mld, link);

		/* Correctly allocated primary link in non-MLO mode */
		if (!ieee80211_vif_is_mld(vif) &&
		    link_id == 0 && link == &mld_vif->deflink)
			continue;

		if (vif->active_links & BIT(link_id))
			continue;

		/* Should not happen as link removal should always succeed */
		WARN_ON(1);
		if (link != &mld_vif->deflink)
			kfree_rcu(link, rcu_head);
		RCU_INIT_POINTER(mld_vif->link[link_id], NULL);
	}

	ieee80211_iter_keys(mld->hw, vif, iwl_mld_cleanup_keys_iter, NULL);

	wiphy_delayed_work_cancel(mld->wiphy, &mld_vif->mlo_scan_start_wk);

	CLEANUP_STRUCT(mld_vif);
}

static int iwl_mld_send_mac_cmd(struct iwl_mld *mld,
				struct iwl_mac_config_cmd *cmd)
{
	int ret;

	lockdep_assert_wiphy(mld->wiphy);

	ret = iwl_mld_send_cmd_pdu(mld,
				   WIDE_ID(MAC_CONF_GROUP, MAC_CONFIG_CMD),
				   cmd);
	if (ret)
		IWL_ERR(mld, "Failed to send MAC_CONFIG_CMD ret = %d\n", ret);

	return ret;
}

int iwl_mld_mac80211_iftype_to_fw(const struct ieee80211_vif *vif)
{
	switch (vif->type) {
	case NL80211_IFTYPE_STATION:
		return vif->p2p ? FW_MAC_TYPE_P2P_STA : FW_MAC_TYPE_BSS_STA;
	case NL80211_IFTYPE_AP:
		return FW_MAC_TYPE_GO;
	case NL80211_IFTYPE_MONITOR:
		return FW_MAC_TYPE_LISTENER;
	case NL80211_IFTYPE_P2P_DEVICE:
		return FW_MAC_TYPE_P2P_DEVICE;
	case NL80211_IFTYPE_ADHOC:
		return FW_MAC_TYPE_IBSS;
	default:
		WARN_ON_ONCE(1);
	}
	return FW_MAC_TYPE_BSS_STA;
}

static bool iwl_mld_is_nic_ack_enabled(struct iwl_mld *mld,
				       struct ieee80211_vif *vif)
{
	const struct ieee80211_supported_band *sband;
	const struct ieee80211_sta_he_cap *own_he_cap;

	lockdep_assert_wiphy(mld->wiphy);

	/* This capability is the same for all bands,
	 * so take it from one of them.
	 */
	sband = mld->hw->wiphy->bands[NL80211_BAND_2GHZ];
	own_he_cap = ieee80211_get_he_iftype_cap_vif(sband, vif);

	return own_he_cap && (own_he_cap->he_cap_elem.mac_cap_info[2] &
			       IEEE80211_HE_MAC_CAP2_ACK_EN);
}

static void iwl_mld_set_he_support(struct iwl_mld *mld,
				   struct ieee80211_vif *vif,
				   struct iwl_mac_config_cmd *cmd,
				   int cmd_ver)
{
	if (vif->type == NL80211_IFTYPE_AP) {
		if (cmd_ver == 2)
			cmd->wifi_gen_v2.he_ap_support = cpu_to_le16(1);
		else
			cmd->wifi_gen.he_ap_support = 1;
	} else {
		if (cmd_ver == 2)
			cmd->wifi_gen_v2.he_support = cpu_to_le16(1);
		else
			cmd->wifi_gen.he_support = 1;
	}
}

/* fill the common part for all interface types */
static void iwl_mld_mac_cmd_fill_common(struct iwl_mld *mld,
					struct ieee80211_vif *vif,
					struct iwl_mac_config_cmd *cmd,
					u32 action)
{
	struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(vif);
	struct ieee80211_bss_conf *link_conf;
	unsigned int link_id;
	int cmd_ver = iwl_fw_lookup_cmd_ver(mld->fw,
					    WIDE_ID(MAC_CONF_GROUP,
						    MAC_CONFIG_CMD), 0);

	lockdep_assert_wiphy(mld->wiphy);

	cmd->id_and_color = cpu_to_le32(mld_vif->fw_id);
	cmd->action = cpu_to_le32(action);

	cmd->mac_type =
		cpu_to_le32(iwl_mld_mac80211_iftype_to_fw(vif));

	memcpy(cmd->local_mld_addr, vif->addr, ETH_ALEN);

	if (iwlwifi_mod_params.disable_11ax)
		return;

	cmd->nic_not_ack_enabled =
		cpu_to_le32(!iwl_mld_is_nic_ack_enabled(mld, vif));

	/* If we have MLO enabled, then the firmware needs to enable
	 * address translation for the station(s) we add. That depends
	 * on having EHT enabled in firmware, which in turn depends on
	 * mac80211 in the code below.
	 * However, mac80211 doesn't enable HE/EHT until it has parsed
	 * the association response successfully, so just skip all that
	 * and enable both when we have MLO.
	 */
	if (ieee80211_vif_is_mld(vif)) {
		iwl_mld_set_he_support(mld, vif, cmd, cmd_ver);
		if (cmd_ver == 2)
			cmd->wifi_gen_v2.eht_support = cpu_to_le32(1);
		else
			cmd->wifi_gen.eht_support = 1;
		return;
	}

	for_each_vif_active_link(vif, link_conf, link_id) {
		if (!link_conf->he_support)
			continue;

		iwl_mld_set_he_support(mld, vif, cmd, cmd_ver);

		/* EHT, if supported, was already set above */
		break;
	}
}

static void iwl_mld_fill_mac_cmd_sta(struct iwl_mld *mld,
				     struct ieee80211_vif *vif, u32 action,
				     struct iwl_mac_config_cmd *cmd)
{
	struct ieee80211_bss_conf *link;
	u32 twt_policy = 0;
	int link_id;

	lockdep_assert_wiphy(mld->wiphy);

	WARN_ON(vif->type != NL80211_IFTYPE_STATION);

	/* We always want to hear MCAST frames, if we're not authorized yet,
	 * we'll drop them.
	 */
	cmd->filter_flags |= cpu_to_le32(MAC_CFG_FILTER_ACCEPT_GRP);

	/* Adding a MAC ctxt with is_assoc set is not allowed in fw
	 * (and shouldn't happen)
	 */
	if (vif->cfg.assoc && action != FW_CTXT_ACTION_ADD) {
		cmd->client.is_assoc = 1;

		if (!iwl_mld_vif_from_mac80211(vif)->authorized)
			cmd->client.data_policy |=
				cpu_to_le16(COEX_HIGH_PRIORITY_ENABLE);
	} else {
		/* Allow beacons to pass through as long as we are not
		 * associated
		 */
		cmd->filter_flags |= cpu_to_le32(MAC_CFG_FILTER_ACCEPT_BEACON);
	}

	cmd->client.assoc_id = cpu_to_le16(vif->cfg.aid);

	if (ieee80211_vif_is_mld(vif)) {
		u16 esr_transition_timeout =
			u16_get_bits(vif->cfg.eml_cap,
				     IEEE80211_EML_CAP_TRANSITION_TIMEOUT);

		cmd->client.esr_transition_timeout =
			min_t(u16, IEEE80211_EML_CAP_TRANSITION_TIMEOUT_128TU,
			      esr_transition_timeout);
		cmd->client.medium_sync_delay =
			cpu_to_le16(vif->cfg.eml_med_sync_delay);
	}

	for_each_vif_active_link(vif, link, link_id) {
		if (!link->he_support)
			continue;

		if (link->twt_requester)
			twt_policy |= TWT_SUPPORTED;
		if (link->twt_protected)
			twt_policy |= PROTECTED_TWT_SUPPORTED;
		if (link->twt_broadcast)
			twt_policy |= BROADCAST_TWT_SUPPORTED;
	}

	if (!iwlwifi_mod_params.disable_11ax)
		cmd->client.data_policy |= cpu_to_le16(twt_policy);

	if (vif->probe_req_reg && vif->cfg.assoc && vif->p2p)
		cmd->filter_flags |=
			cpu_to_le32(MAC_CFG_FILTER_ACCEPT_PROBE_REQ);
}

static void iwl_mld_fill_mac_cmd_ap(struct iwl_mld *mld,
				    struct ieee80211_vif *vif,
				    struct iwl_mac_config_cmd *cmd)
{
	struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(vif);

	lockdep_assert_wiphy(mld->wiphy);

	WARN_ON(vif->type != NL80211_IFTYPE_AP);

	cmd->filter_flags |= cpu_to_le32(MAC_CFG_FILTER_ACCEPT_PROBE_REQ);

	/* in AP mode, pass beacons from other APs (needed for ht protection).
	 * When there're no any associated station, which means that we are not
	 * TXing anyway, don't ask FW to pass beacons to prevent unnecessary
	 * wake-ups.
	 */
	if (mld_vif->num_associated_stas)
		cmd->filter_flags |= cpu_to_le32(MAC_CFG_FILTER_ACCEPT_BEACON);
}

static void iwl_mld_go_iterator(void *_data, u8 *mac, struct ieee80211_vif *vif)
{
	bool *go_active = _data;

	if (ieee80211_vif_type_p2p(vif) == NL80211_IFTYPE_P2P_GO &&
	    iwl_mld_vif_from_mac80211(vif)->ap_ibss_active)
		*go_active = true;
}

static bool iwl_mld_p2p_dev_has_extended_disc(struct iwl_mld *mld)
{
	bool go_active = false;

	/* This flag should be set to true when the P2P Device is
	 * discoverable and there is at least a P2P GO. Setting
	 * this flag will allow the P2P Device to be discoverable on other
	 * channels in addition to its listen channel.
	 * Note that this flag should not be set in other cases as it opens the
	 * Rx filters on all MAC and increases the number of interrupts.
	 */
	ieee80211_iterate_active_interfaces(mld->hw,
					    IEEE80211_IFACE_ITER_RESUME_ALL,
					    iwl_mld_go_iterator, &go_active);

	return go_active;
}

static void iwl_mld_fill_mac_cmd_p2p_dev(struct iwl_mld *mld,
					 struct ieee80211_vif *vif,
					 struct iwl_mac_config_cmd *cmd)
{
	bool ext_disc = iwl_mld_p2p_dev_has_extended_disc(mld);

	lockdep_assert_wiphy(mld->wiphy);

	/* Override the filter flags to accept all management frames. This is
	 * needed to support both P2P device discovery using probe requests and
	 * P2P service discovery using action frames
	 */
	cmd->filter_flags = cpu_to_le32(MAC_CFG_FILTER_ACCEPT_CONTROL_AND_MGMT);

	if (ext_disc)
		cmd->p2p_dev.is_disc_extended = cpu_to_le32(1);
}

static void iwl_mld_fill_mac_cmd_ibss(struct iwl_mld *mld,
				      struct ieee80211_vif *vif,
				      struct iwl_mac_config_cmd *cmd)
{
	lockdep_assert_wiphy(mld->wiphy);

	WARN_ON(vif->type != NL80211_IFTYPE_ADHOC);

	cmd->filter_flags |= cpu_to_le32(MAC_CFG_FILTER_ACCEPT_BEACON |
					 MAC_CFG_FILTER_ACCEPT_PROBE_REQ |
					 MAC_CFG_FILTER_ACCEPT_GRP);
}

static int
iwl_mld_rm_mac_from_fw(struct iwl_mld *mld, struct ieee80211_vif *vif)
{
	struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(vif);
	struct iwl_mac_config_cmd cmd = {
		.action = cpu_to_le32(FW_CTXT_ACTION_REMOVE),
		.id_and_color = cpu_to_le32(mld_vif->fw_id),
	};

	return iwl_mld_send_mac_cmd(mld, &cmd);
}

int iwl_mld_mac_fw_action(struct iwl_mld *mld, struct ieee80211_vif *vif,
			  u32 action)
{
	struct iwl_mac_config_cmd cmd = {};

	lockdep_assert_wiphy(mld->wiphy);

	if (action == FW_CTXT_ACTION_REMOVE)
		return iwl_mld_rm_mac_from_fw(mld, vif);

	iwl_mld_mac_cmd_fill_common(mld, vif, &cmd, action);

	switch (vif->type) {
	case NL80211_IFTYPE_STATION:
		iwl_mld_fill_mac_cmd_sta(mld, vif, action, &cmd);
		break;
	case NL80211_IFTYPE_AP:
		iwl_mld_fill_mac_cmd_ap(mld, vif, &cmd);
		break;
	case NL80211_IFTYPE_MONITOR:
		cmd.filter_flags =
			cpu_to_le32(MAC_CFG_FILTER_PROMISC |
				    MAC_CFG_FILTER_ACCEPT_CONTROL_AND_MGMT |
				    MAC_CFG_FILTER_ACCEPT_BEACON |
				    MAC_CFG_FILTER_ACCEPT_PROBE_REQ |
				    MAC_CFG_FILTER_ACCEPT_GRP);
		break;
	case NL80211_IFTYPE_P2P_DEVICE:
		iwl_mld_fill_mac_cmd_p2p_dev(mld, vif, &cmd);
		break;
	case NL80211_IFTYPE_ADHOC:
		iwl_mld_fill_mac_cmd_ibss(mld, vif, &cmd);
		break;
	default:
		WARN(1, "not supported yet\n");
		return -EOPNOTSUPP;
	}

	return iwl_mld_send_mac_cmd(mld, &cmd);
}

static void iwl_mld_mlo_scan_start_wk(struct wiphy *wiphy,
				      struct wiphy_work *wk)
{
	struct iwl_mld_vif *mld_vif = container_of(wk, struct iwl_mld_vif,
						   mlo_scan_start_wk.work);
	struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
	struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw);

	iwl_mld_int_mlo_scan(mld, iwl_mld_vif_to_mac80211(mld_vif));
}

IWL_MLD_ALLOC_FN(vif, vif)

/* Constructor function for struct iwl_mld_vif */
static int
iwl_mld_init_vif(struct iwl_mld *mld, struct ieee80211_vif *vif)
{
	struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(vif);
	int ret;

	lockdep_assert_wiphy(mld->wiphy);

	mld_vif->mld = mld;
	mld_vif->roc_activity = ROC_NUM_ACTIVITIES;

	ret = iwl_mld_allocate_vif_fw_id(mld, &mld_vif->fw_id, vif);
	if (ret)
		return ret;

	if (!mld->fw_status.in_hw_restart) {
		wiphy_work_init(&mld_vif->emlsr.unblock_tpt_wk,
				iwl_mld_emlsr_unblock_tpt_wk);
		wiphy_delayed_work_init(&mld_vif->emlsr.check_tpt_wk,
					iwl_mld_emlsr_check_tpt);
		wiphy_delayed_work_init(&mld_vif->emlsr.prevent_done_wk,
					iwl_mld_emlsr_prevent_done_wk);
		wiphy_delayed_work_init(&mld_vif->emlsr.tmp_non_bss_done_wk,
					iwl_mld_emlsr_tmp_non_bss_done_wk);
		wiphy_delayed_work_init(&mld_vif->mlo_scan_start_wk,
					iwl_mld_mlo_scan_start_wk);
	}
	iwl_mld_init_internal_sta(&mld_vif->aux_sta);

	return 0;
}

int iwl_mld_add_vif(struct iwl_mld *mld, struct ieee80211_vif *vif)
{
	struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(vif);
	int ret;

	lockdep_assert_wiphy(mld->wiphy);

	ret = iwl_mld_init_vif(mld, vif);
	if (ret)
		return ret;

	ret = iwl_mld_mac_fw_action(mld, vif, FW_CTXT_ACTION_ADD);
	if (ret)
		RCU_INIT_POINTER(mld->fw_id_to_vif[mld_vif->fw_id], NULL);

	return ret;
}

int iwl_mld_rm_vif(struct iwl_mld *mld, struct ieee80211_vif *vif)
{
	struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(vif);
	int ret;

	lockdep_assert_wiphy(mld->wiphy);

	ret = iwl_mld_mac_fw_action(mld, vif, FW_CTXT_ACTION_REMOVE);

	if (WARN_ON(mld_vif->fw_id >= ARRAY_SIZE(mld->fw_id_to_vif)))
		return -EINVAL;

	RCU_INIT_POINTER(mld->fw_id_to_vif[mld_vif->fw_id], NULL);

	iwl_mld_cancel_notifications_of_object(mld, IWL_MLD_OBJECT_TYPE_VIF,
					       mld_vif->fw_id);

	return ret;
}

void iwl_mld_set_vif_associated(struct iwl_mld *mld,
				struct ieee80211_vif *vif)
{
	struct ieee80211_bss_conf *link;
	unsigned int link_id;

	for_each_vif_active_link(vif, link, link_id) {
		if (iwl_mld_link_set_associated(mld, vif, link))
			IWL_ERR(mld, "failed to update link %d\n", link_id);
	}

	iwl_mld_recalc_multicast_filter(mld);
}

static void iwl_mld_get_fw_id_bss_bitmap_iter(void *_data, u8 *mac,
					      struct ieee80211_vif *vif)
{
	u8 *fw_id_bitmap = _data;
	struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(vif);

	if (ieee80211_vif_type_p2p(vif) != NL80211_IFTYPE_STATION)
		return;

	*fw_id_bitmap |= BIT(mld_vif->fw_id);
}

u8 iwl_mld_get_fw_bss_vifs_ids(struct iwl_mld *mld)
{
	u8 fw_id_bitmap = 0;

	ieee80211_iterate_active_interfaces_mtx(mld->hw,
						IEEE80211_IFACE_SKIP_SDATA_NOT_IN_DRIVER,
						iwl_mld_get_fw_id_bss_bitmap_iter,
						&fw_id_bitmap);

	return fw_id_bitmap;
}

void iwl_mld_handle_probe_resp_data_notif(struct iwl_mld *mld,
					  struct iwl_rx_packet *pkt)
{
	const struct iwl_probe_resp_data_notif *notif = (void *)pkt->data;
	struct iwl_probe_resp_data *old_data, *new_data;
	struct ieee80211_vif *vif;
	struct iwl_mld_link *mld_link;

	IWL_DEBUG_INFO(mld, "Probe response data notif: noa %d, csa %d\n",
		       notif->noa_active, notif->csa_counter);

	if (IWL_FW_CHECK(mld, le32_to_cpu(notif->mac_id) >=
			 ARRAY_SIZE(mld->fw_id_to_vif),
			 "mac id is invalid: %d\n",
			 le32_to_cpu(notif->mac_id)))
		return;

	vif = wiphy_dereference(mld->wiphy,
				mld->fw_id_to_vif[le32_to_cpu(notif->mac_id)]);

	/* the firmware gives us the mac_id (and not the link_id), mac80211
	 * gets a vif and not a link, bottom line, this flow is not MLD ready
	 * yet.
	 */
	if (WARN_ON(!vif) || ieee80211_vif_is_mld(vif))
		return;

	if (notif->csa_counter != IWL_PROBE_RESP_DATA_NO_CSA &&
	    notif->csa_counter >= 1)
		ieee80211_beacon_set_cntdwn(vif, notif->csa_counter);

	if (!vif->p2p)
		return;

	mld_link = &iwl_mld_vif_from_mac80211(vif)->deflink;

	new_data = kzalloc(sizeof(*new_data), GFP_KERNEL);
	if (!new_data)
		return;

	memcpy(&new_data->notif, notif, sizeof(new_data->notif));

	/* noa_attr contains 1 reserved byte, need to substruct it */
	new_data->noa_len = sizeof(struct ieee80211_vendor_ie) +
			    sizeof(new_data->notif.noa_attr) - 1;

	/*
	 * If it's a one time NoA, only one descriptor is needed,
	 * adjust the length according to len_low.
	 */
	if (new_data->notif.noa_attr.len_low ==
	    sizeof(struct ieee80211_p2p_noa_desc) + 2)
		new_data->noa_len -= sizeof(struct ieee80211_p2p_noa_desc);

	old_data = wiphy_dereference(mld->wiphy, mld_link->probe_resp_data);
	rcu_assign_pointer(mld_link->probe_resp_data, new_data);

	if (old_data)
		kfree_rcu(old_data, rcu_head);
}

void iwl_mld_handle_uapsd_misbehaving_ap_notif(struct iwl_mld *mld,
					       struct iwl_rx_packet *pkt)
{
	struct iwl_uapsd_misbehaving_ap_notif *notif = (void *)pkt->data;
	struct ieee80211_vif *vif;

	if (IWL_FW_CHECK(mld, notif->mac_id >= ARRAY_SIZE(mld->fw_id_to_vif),
			 "mac id is invalid: %d\n", notif->mac_id))
		return;

	vif = wiphy_dereference(mld->wiphy, mld->fw_id_to_vif[notif->mac_id]);

	if (WARN_ON(!vif) || ieee80211_vif_is_mld(vif))
		return;

	IWL_WARN(mld, "uapsd misbehaving AP: %pM\n", vif->bss_conf.bssid);
}

void iwl_mld_handle_datapath_monitor_notif(struct iwl_mld *mld,
					   struct iwl_rx_packet *pkt)
{
	struct iwl_datapath_monitor_notif *notif = (void *)pkt->data;
	struct ieee80211_bss_conf *link;
	struct ieee80211_supported_band *sband;
	const struct ieee80211_sta_he_cap *he_cap;
	struct ieee80211_vif *vif;
	struct iwl_mld_vif *mld_vif;

	if (notif->type != cpu_to_le32(IWL_DP_MON_NOTIF_TYPE_EXT_CCA))
		return;

	link = iwl_mld_fw_id_to_link_conf(mld, notif->link_id);
	if (WARN_ON(!link))
		return;

	vif = link->vif;
	if (WARN_ON(!vif) || vif->type != NL80211_IFTYPE_STATION ||
	    !vif->cfg.assoc)
		return;

	if (!link->chanreq.oper.chan ||
	    link->chanreq.oper.chan->band != NL80211_BAND_2GHZ ||
	    link->chanreq.oper.width < NL80211_CHAN_WIDTH_40)
		return;

	mld_vif = iwl_mld_vif_from_mac80211(vif);

	/* this shouldn't happen *again*, ignore it */
	if (mld_vif->cca_40mhz_workaround != CCA_40_MHZ_WA_NONE)
		return;

	mld_vif->cca_40mhz_workaround = CCA_40_MHZ_WA_RECONNECT;

	/*
	 * This capability manipulation isn't really ideal, but it's the
	 * easiest choice - otherwise we'd have to do some major changes
	 * in mac80211 to support this, which isn't worth it. This does
	 * mean that userspace may have outdated information, but that's
	 * actually not an issue at all.
	 */
	sband = mld->wiphy->bands[NL80211_BAND_2GHZ];

	WARN_ON(!sband->ht_cap.ht_supported);
	WARN_ON(!(sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40));
	sband->ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;

	he_cap = ieee80211_get_he_iftype_cap_vif(sband, vif);

	if (he_cap) {
		/* we know that ours is writable */
		struct ieee80211_sta_he_cap *he = (void *)(uintptr_t)he_cap;

		WARN_ON(!he->has_he);
		WARN_ON(!(he->he_cap_elem.phy_cap_info[0] &
			  IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G));
		he->he_cap_elem.phy_cap_info[0] &=
			~IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G;
	}

	ieee80211_disconnect(vif, true);
}

void iwl_mld_reset_cca_40mhz_workaround(struct iwl_mld *mld,
					struct ieee80211_vif *vif)
{
	struct ieee80211_supported_band *sband;
	const struct ieee80211_sta_he_cap *he_cap;
	struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(vif);

	if (vif->type != NL80211_IFTYPE_STATION)
		return;

	if (mld_vif->cca_40mhz_workaround == CCA_40_MHZ_WA_NONE)
		return;

	/* Now we are just reconnecting with the new capabilities,
	 * but remember to reset the capabilities when we disconnect for real
	 */
	if (mld_vif->cca_40mhz_workaround == CCA_40_MHZ_WA_RECONNECT) {
		mld_vif->cca_40mhz_workaround = CCA_40_MHZ_WA_RESET;
		return;
	}

	/* Now cca_40mhz_workaround == CCA_40_MHZ_WA_RESET */

	sband = mld->wiphy->bands[NL80211_BAND_2GHZ];

	sband->ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;

	he_cap = ieee80211_get_he_iftype_cap_vif(sband, vif);

	if (he_cap) {
		/* we know that ours is writable */
		struct ieee80211_sta_he_cap *he = (void *)(uintptr_t)he_cap;

		he->he_cap_elem.phy_cap_info[0] |=
			IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G;
	}

	mld_vif->cca_40mhz_workaround = CCA_40_MHZ_WA_NONE;
}

struct ieee80211_vif *iwl_mld_get_bss_vif(struct iwl_mld *mld)
{
	unsigned long fw_id_bitmap = iwl_mld_get_fw_bss_vifs_ids(mld);
	int fw_id;

	if (hweight8(fw_id_bitmap) != 1)
		return NULL;

	fw_id = __ffs(fw_id_bitmap);

	return wiphy_dereference(mld->wiphy,
				 mld->fw_id_to_vif[fw_id]);
}
