// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/*
 * Copyright (C) 2022-2023 Intel Corporation
 */
#include "mvm.h"
#include "time-sync.h"
#include "sta.h"

u32 iwl_mvm_sta_fw_id_mask(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
			   int filter_link_id)
{
	struct iwl_mvm_sta *mvmsta;
	unsigned int link_id;
	u32 result = 0;

	if (!sta)
		return 0;

	mvmsta = iwl_mvm_sta_from_mac80211(sta);

	/* it's easy when the STA is not an MLD */
	if (!sta->valid_links)
		return BIT(mvmsta->deflink.sta_id);

	/* but if it is an MLD, get the mask of all the FW STAs it has ... */
	for (link_id = 0; link_id < ARRAY_SIZE(mvmsta->link); link_id++) {
		struct iwl_mvm_link_sta *link_sta;

		/* unless we have a specific link in mind */
		if (filter_link_id >= 0 && link_id != filter_link_id)
			continue;

		link_sta =
			rcu_dereference_check(mvmsta->link[link_id],
					      lockdep_is_held(&mvm->mutex));
		if (!link_sta)
			continue;

		result |= BIT(link_sta->sta_id);
	}

	return result;
}

static int iwl_mvm_mld_send_sta_cmd(struct iwl_mvm *mvm,
				    struct iwl_mvm_sta_cfg_cmd *cmd)
{
	int ret = iwl_mvm_send_cmd_pdu(mvm,
				       WIDE_ID(MAC_CONF_GROUP, STA_CONFIG_CMD),
				       0, sizeof(*cmd), cmd);
	if (ret)
		IWL_ERR(mvm, "STA_CONFIG_CMD send failed, ret=0x%x\n", ret);
	return ret;
}

/*
 * Add an internal station to the FW table
 */
static int iwl_mvm_mld_add_int_sta_to_fw(struct iwl_mvm *mvm,
					 struct iwl_mvm_int_sta *sta,
					 const u8 *addr, int link_id)
{
	struct iwl_mvm_sta_cfg_cmd cmd;

	lockdep_assert_held(&mvm->mutex);

	memset(&cmd, 0, sizeof(cmd));
	cmd.sta_id = cpu_to_le32((u8)sta->sta_id);

	cmd.link_id = cpu_to_le32(link_id);

	cmd.station_type = cpu_to_le32(sta->type);

	if (fw_has_capa(&mvm->fw->ucode_capa,
			IWL_UCODE_TLV_CAPA_STA_EXP_MFP_SUPPORT) &&
	    sta->type == STATION_TYPE_BCAST_MGMT)
		cmd.mfp = cpu_to_le32(1);

	if (addr) {
		memcpy(cmd.peer_mld_address, addr, ETH_ALEN);
		memcpy(cmd.peer_link_address, addr, ETH_ALEN);
	}

	return iwl_mvm_mld_send_sta_cmd(mvm, &cmd);
}

/*
 * Remove a station from the FW table. Before sending the command to remove
 * the station validate that the station is indeed known to the driver (sanity
 * only).
 */
static int iwl_mvm_mld_rm_sta_from_fw(struct iwl_mvm *mvm, u32 sta_id)
{
	struct iwl_mvm_remove_sta_cmd rm_sta_cmd = {
		.sta_id = cpu_to_le32(sta_id),
	};
	int ret;

	/* Note: internal stations are marked as error values */
	if (!rcu_access_pointer(mvm->fw_id_to_mac_id[sta_id])) {
		IWL_ERR(mvm, "Invalid station id %d\n", sta_id);
		return -EINVAL;
	}

	ret = iwl_mvm_send_cmd_pdu(mvm, WIDE_ID(MAC_CONF_GROUP, STA_REMOVE_CMD),
				   0, sizeof(rm_sta_cmd), &rm_sta_cmd);
	if (ret) {
		IWL_ERR(mvm, "Failed to remove station. Id=%d\n", sta_id);
		return ret;
	}

	return 0;
}

static int iwl_mvm_add_aux_sta_to_fw(struct iwl_mvm *mvm,
				     struct iwl_mvm_int_sta *sta,
				     u32 lmac_id)
{
	int ret;

	struct iwl_mvm_aux_sta_cmd cmd = {
		.sta_id = cpu_to_le32(sta->sta_id),
		.lmac_id = cpu_to_le32(lmac_id),
	};

	ret = iwl_mvm_send_cmd_pdu(mvm, WIDE_ID(MAC_CONF_GROUP, AUX_STA_CMD),
				   0, sizeof(cmd), &cmd);
	if (ret)
		IWL_ERR(mvm, "Failed to send AUX_STA_CMD\n");
	return ret;
}

/*
 * Adds an internal sta to the FW table with its queues
 */
int iwl_mvm_mld_add_int_sta_with_queue(struct iwl_mvm *mvm,
				       struct iwl_mvm_int_sta *sta,
				       const u8 *addr, int link_id,
				       u16 *queue, u8 tid,
				       unsigned int *_wdg_timeout)
{
	int ret, txq;
	unsigned int wdg_timeout = _wdg_timeout ? *_wdg_timeout :
		mvm->trans->trans_cfg->base_params->wd_timeout;

	if (WARN_ON_ONCE(sta->sta_id == IWL_MVM_INVALID_STA))
		return -ENOSPC;

	if (sta->type == STATION_TYPE_AUX)
		ret = iwl_mvm_add_aux_sta_to_fw(mvm, sta, link_id);
	else
		ret = iwl_mvm_mld_add_int_sta_to_fw(mvm, sta, addr, link_id);
	if (ret)
		return ret;

	/*
	 * For 22000 firmware and on we cannot add queue to a station unknown
	 * to firmware so enable queue here - after the station was added
	 */
	txq = iwl_mvm_tvqm_enable_txq(mvm, NULL, sta->sta_id, tid,
				      wdg_timeout);
	if (txq < 0) {
		iwl_mvm_mld_rm_sta_from_fw(mvm, sta->sta_id);
		return txq;
	}
	*queue = txq;

	return 0;
}

/*
 * Adds a new int sta: allocate it in the driver, add it to the FW table,
 * and add its queues.
 */
static int iwl_mvm_mld_add_int_sta(struct iwl_mvm *mvm,
				   struct iwl_mvm_int_sta *int_sta, u16 *queue,
				   enum nl80211_iftype iftype,
				   enum iwl_fw_sta_type sta_type,
				   int link_id, const u8 *addr, u8 tid,
				   unsigned int *wdg_timeout)
{
	int ret;

	lockdep_assert_held(&mvm->mutex);

	/* qmask argument is not used in the new tx api, send a don't care */
	ret = iwl_mvm_allocate_int_sta(mvm, int_sta, 0, iftype,
				       sta_type);
	if (ret)
		return ret;

	ret = iwl_mvm_mld_add_int_sta_with_queue(mvm, int_sta, addr, link_id,
						 queue, tid, wdg_timeout);
	if (ret) {
		iwl_mvm_dealloc_int_sta(mvm, int_sta);
		return ret;
	}

	return 0;
}

/* Allocate a new station entry for the broadcast station to the given vif,
 * and send it to the FW.
 * Note that each P2P mac should have its own broadcast station.
 */
int iwl_mvm_mld_add_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
			      struct ieee80211_bss_conf *link_conf)
{
	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
	struct iwl_mvm_vif_link_info *mvm_link =
		mvmvif->link[link_conf->link_id];
	struct iwl_mvm_int_sta *bsta = &mvm_link->bcast_sta;
	static const u8 _baddr[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
	const u8 *baddr = _baddr;
	unsigned int wdg_timeout =
		iwl_mvm_get_wd_timeout(mvm, vif, false, false);
	u16 *queue;

	lockdep_assert_held(&mvm->mutex);

	if (vif->type == NL80211_IFTYPE_ADHOC)
		baddr = link_conf->bssid;

	if (vif->type == NL80211_IFTYPE_AP ||
	    vif->type == NL80211_IFTYPE_ADHOC) {
		queue = &mvm_link->mgmt_queue;
	} else if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
		queue = &mvm->p2p_dev_queue;
	} else {
		WARN(1, "Missing required TXQ for adding bcast STA\n");
		return -EINVAL;
	}

	return iwl_mvm_mld_add_int_sta(mvm, bsta, queue,
				       ieee80211_vif_type_p2p(vif),
				       STATION_TYPE_BCAST_MGMT,
				       mvm_link->fw_link_id, baddr,
				       IWL_MAX_TID_COUNT, &wdg_timeout);
}

/* Allocate a new station entry for the broadcast station to the given vif,
 * and send it to the FW.
 * Note that each AP/GO mac should have its own multicast station.
 */
int iwl_mvm_mld_add_mcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
			      struct ieee80211_bss_conf *link_conf)
{
	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
	struct iwl_mvm_vif_link_info *mvm_link =
		mvmvif->link[link_conf->link_id];
	struct iwl_mvm_int_sta *msta = &mvm_link->mcast_sta;
	static const u8 _maddr[] = {0x03, 0x00, 0x00, 0x00, 0x00, 0x00};
	const u8 *maddr = _maddr;
	unsigned int timeout = iwl_mvm_get_wd_timeout(mvm, vif, false, false);

	lockdep_assert_held(&mvm->mutex);

	if (WARN_ON(vif->type != NL80211_IFTYPE_AP &&
		    vif->type != NL80211_IFTYPE_ADHOC))
		return -EOPNOTSUPP;

	/* In IBSS, ieee80211_check_queues() sets the cab_queue to be
	 * invalid, so make sure we use the queue we want.
	 * Note that this is done here as we want to avoid making DQA
	 * changes in mac80211 layer.
	 */
	if (vif->type == NL80211_IFTYPE_ADHOC)
		mvm_link->cab_queue = IWL_MVM_DQA_GCAST_QUEUE;

	return iwl_mvm_mld_add_int_sta(mvm, msta, &mvm_link->cab_queue,
				       vif->type, STATION_TYPE_MCAST,
				       mvm_link->fw_link_id, maddr, 0,
				       &timeout);
}

/* Allocate a new station entry for the sniffer station to the given vif,
 * and send it to the FW.
 */
int iwl_mvm_mld_add_snif_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
			     struct ieee80211_bss_conf *link_conf)
{
	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
	struct iwl_mvm_vif_link_info *mvm_link =
		mvmvif->link[link_conf->link_id];

	lockdep_assert_held(&mvm->mutex);

	return iwl_mvm_mld_add_int_sta(mvm, &mvm->snif_sta, &mvm->snif_queue,
				       vif->type, STATION_TYPE_BCAST_MGMT,
				       mvm_link->fw_link_id, NULL,
				       IWL_MAX_TID_COUNT, NULL);
}

int iwl_mvm_mld_add_aux_sta(struct iwl_mvm *mvm, u32 lmac_id)
{
	lockdep_assert_held(&mvm->mutex);

	/* In CDB NICs we need to specify which lmac to use for aux activity;
	 * use the link_id argument place to send lmac_id to the function.
	 */
	return iwl_mvm_mld_add_int_sta(mvm, &mvm->aux_sta, &mvm->aux_queue,
				       NL80211_IFTYPE_UNSPECIFIED,
				       STATION_TYPE_AUX, lmac_id, NULL,
				       IWL_MAX_TID_COUNT, NULL);
}

static int iwl_mvm_mld_disable_txq(struct iwl_mvm *mvm, u32 sta_mask,
				   u16 *queueptr, u8 tid)
{
	int queue = *queueptr;
	int ret = 0;

	if (tid == IWL_MAX_TID_COUNT)
		tid = IWL_MGMT_TID;

	if (mvm->sta_remove_requires_queue_remove) {
		u32 cmd_id = WIDE_ID(DATA_PATH_GROUP,
				     SCD_QUEUE_CONFIG_CMD);
		struct iwl_scd_queue_cfg_cmd remove_cmd = {
			.operation = cpu_to_le32(IWL_SCD_QUEUE_REMOVE),
			.u.remove.tid = cpu_to_le32(tid),
			.u.remove.sta_mask = cpu_to_le32(sta_mask),
		};

		ret = iwl_mvm_send_cmd_pdu(mvm, cmd_id, 0,
					   sizeof(remove_cmd),
					   &remove_cmd);
	}

	iwl_trans_txq_free(mvm->trans, queue);
	*queueptr = IWL_MVM_INVALID_QUEUE;

	return ret;
}

/* Removes a sta from the FW table, disable its queues, and dealloc it
 */
static int iwl_mvm_mld_rm_int_sta(struct iwl_mvm *mvm,
				  struct iwl_mvm_int_sta *int_sta,
				  bool flush, u8 tid, u16 *queuptr)
{
	int ret;

	lockdep_assert_held(&mvm->mutex);

	if (WARN_ON_ONCE(int_sta->sta_id == IWL_MVM_INVALID_STA))
		return -EINVAL;

	if (flush)
		iwl_mvm_flush_sta(mvm, int_sta->sta_id, int_sta->tfd_queue_msk);

	iwl_mvm_mld_disable_txq(mvm, BIT(int_sta->sta_id), queuptr, tid);

	ret = iwl_mvm_mld_rm_sta_from_fw(mvm, int_sta->sta_id);
	if (ret)
		IWL_WARN(mvm, "Failed sending remove station\n");

	iwl_mvm_dealloc_int_sta(mvm, int_sta);

	return ret;
}

int iwl_mvm_mld_rm_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
			     struct ieee80211_bss_conf *link_conf)
{
	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
	struct iwl_mvm_vif_link_info *link = mvmvif->link[link_conf->link_id];
	u16 *queueptr;

	lockdep_assert_held(&mvm->mutex);

	if (WARN_ON(!link))
		return -EIO;

	switch (vif->type) {
	case NL80211_IFTYPE_AP:
	case NL80211_IFTYPE_ADHOC:
		queueptr = &link->mgmt_queue;
		break;
	case NL80211_IFTYPE_P2P_DEVICE:
		queueptr = &mvm->p2p_dev_queue;
		break;
	default:
		WARN(1, "Can't free bcast queue on vif type %d\n",
		     vif->type);
		return -EINVAL;
	}

	return iwl_mvm_mld_rm_int_sta(mvm, &link->bcast_sta,
				      true, IWL_MAX_TID_COUNT, queueptr);
}

/* Send the FW a request to remove the station from it's internal data
 * structures, and in addition remove it from the local data structure.
 */
int iwl_mvm_mld_rm_mcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
			     struct ieee80211_bss_conf *link_conf)
{
	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
	struct iwl_mvm_vif_link_info *link = mvmvif->link[link_conf->link_id];

	lockdep_assert_held(&mvm->mutex);

	if (WARN_ON(!link))
		return -EIO;

	return iwl_mvm_mld_rm_int_sta(mvm, &link->mcast_sta, true, 0,
				      &link->cab_queue);
}

int iwl_mvm_mld_rm_snif_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
{
	lockdep_assert_held(&mvm->mutex);

	return iwl_mvm_mld_rm_int_sta(mvm, &mvm->snif_sta, false,
				      IWL_MAX_TID_COUNT, &mvm->snif_queue);
}

int iwl_mvm_mld_rm_aux_sta(struct iwl_mvm *mvm)
{
	lockdep_assert_held(&mvm->mutex);

	return iwl_mvm_mld_rm_int_sta(mvm, &mvm->aux_sta, false,
				      IWL_MAX_TID_COUNT, &mvm->aux_queue);
}

/* send a cfg sta command to add/update a sta in firmware */
static int iwl_mvm_mld_cfg_sta(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
			       struct ieee80211_vif *vif,
			       struct ieee80211_link_sta *link_sta,
			       struct ieee80211_bss_conf *link_conf,
			       struct iwl_mvm_link_sta *mvm_link_sta)
{
	struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
	struct iwl_mvm_vif *mvm_vif = iwl_mvm_vif_from_mac80211(vif);
	struct iwl_mvm_vif_link_info *link_info =
					mvm_vif->link[link_conf->link_id];
	struct iwl_mvm_sta_cfg_cmd cmd = {
		.sta_id = cpu_to_le32(mvm_link_sta->sta_id),
		.station_type = cpu_to_le32(mvm_sta->sta_type),
	};
	u32 agg_size = 0, mpdu_dens = 0;

	/* when adding sta, link should exist in FW */
	if (WARN_ON(link_info->fw_link_id == IWL_MVM_FW_LINK_ID_INVALID))
		return -EINVAL;

	cmd.link_id = cpu_to_le32(link_info->fw_link_id);

	memcpy(&cmd.peer_mld_address, sta->addr, ETH_ALEN);
	memcpy(&cmd.peer_link_address, link_sta->addr, ETH_ALEN);

	if (mvm_sta->sta_state >= IEEE80211_STA_ASSOC)
		cmd.assoc_id = cpu_to_le32(sta->aid);

	if (fw_has_capa(&mvm->fw->ucode_capa,
			IWL_UCODE_TLV_CAPA_STA_EXP_MFP_SUPPORT) &&
	    (sta->mfp || mvm_sta->sta_state < IEEE80211_STA_AUTHORIZED))
		cmd.mfp = cpu_to_le32(1);

	switch (link_sta->rx_nss) {
	case 1:
		cmd.mimo = cpu_to_le32(0);
		break;
	case 2 ... 8:
		cmd.mimo = cpu_to_le32(1);
		break;
	}

	switch (sta->deflink.smps_mode) {
	case IEEE80211_SMPS_AUTOMATIC:
	case IEEE80211_SMPS_NUM_MODES:
		WARN_ON(1);
		break;
	case IEEE80211_SMPS_STATIC:
		/* override NSS */
		cmd.mimo = cpu_to_le32(0);
		break;
	case IEEE80211_SMPS_DYNAMIC:
		cmd.mimo_protection = cpu_to_le32(1);
		break;
	case IEEE80211_SMPS_OFF:
		/* nothing */
		break;
	}

	mpdu_dens = iwl_mvm_get_sta_ampdu_dens(link_sta, link_conf, &agg_size);
	cmd.tx_ampdu_spacing = cpu_to_le32(mpdu_dens);
	cmd.tx_ampdu_max_size = cpu_to_le32(agg_size);

	if (sta->wme) {
		cmd.sp_length =
			cpu_to_le32(sta->max_sp ? sta->max_sp * 2 : 128);
		cmd.uapsd_acs = cpu_to_le32(iwl_mvm_get_sta_uapsd_acs(sta));
	}

	if (link_sta->he_cap.has_he) {
		cmd.trig_rnd_alloc =
			cpu_to_le32(link_conf->uora_exists ? 1 : 0);

		/* PPE Thresholds */
		iwl_mvm_set_sta_pkt_ext(mvm, link_sta, &cmd.pkt_ext);

		/* HTC flags */
		cmd.htc_flags = iwl_mvm_get_sta_htc_flags(sta, link_sta);

		if (link_sta->he_cap.he_cap_elem.mac_cap_info[2] &
		    IEEE80211_HE_MAC_CAP2_ACK_EN)
			cmd.ack_enabled = cpu_to_le32(1);
	}

	return iwl_mvm_mld_send_sta_cmd(mvm, &cmd);
}

static void iwl_mvm_mld_free_sta_link(struct iwl_mvm *mvm,
				      struct iwl_mvm_sta *mvm_sta,
				      struct iwl_mvm_link_sta *mvm_sta_link,
				      unsigned int link_id,
				      bool is_in_fw)
{
	RCU_INIT_POINTER(mvm->fw_id_to_mac_id[mvm_sta_link->sta_id],
			 is_in_fw ? ERR_PTR(-EINVAL) : NULL);
	RCU_INIT_POINTER(mvm->fw_id_to_link_sta[mvm_sta_link->sta_id], NULL);
	RCU_INIT_POINTER(mvm_sta->link[link_id], NULL);

	if (mvm_sta_link != &mvm_sta->deflink)
		kfree_rcu(mvm_sta_link, rcu_head);
}

static void iwl_mvm_mld_sta_rm_all_sta_links(struct iwl_mvm *mvm,
					     struct iwl_mvm_sta *mvm_sta)
{
	unsigned int link_id;

	for (link_id = 0; link_id < ARRAY_SIZE(mvm_sta->link); link_id++) {
		struct iwl_mvm_link_sta *link =
			rcu_dereference_protected(mvm_sta->link[link_id],
						  lockdep_is_held(&mvm->mutex));

		if (!link)
			continue;

		iwl_mvm_mld_free_sta_link(mvm, mvm_sta, link, link_id, false);
	}
}

static int iwl_mvm_mld_alloc_sta_link(struct iwl_mvm *mvm,
				      struct ieee80211_vif *vif,
				      struct ieee80211_sta *sta,
				      unsigned int link_id)
{
	struct ieee80211_link_sta *link_sta =
		link_sta_dereference_protected(sta, link_id);
	struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
	struct iwl_mvm_link_sta *link;
	u32 sta_id = iwl_mvm_find_free_sta_id(mvm,
					  ieee80211_vif_type_p2p(vif));

	if (sta_id == IWL_MVM_INVALID_STA)
		return -ENOSPC;

	if (rcu_access_pointer(sta->link[link_id]) == &sta->deflink) {
		link = &mvm_sta->deflink;
	} else {
		link = kzalloc(sizeof(*link), GFP_KERNEL);
		if (!link)
			return -ENOMEM;
	}

	link->sta_id = sta_id;
	rcu_assign_pointer(mvm_sta->link[link_id], link);
	rcu_assign_pointer(mvm->fw_id_to_mac_id[link->sta_id], sta);
	rcu_assign_pointer(mvm->fw_id_to_link_sta[link->sta_id],
			   link_sta);

	return 0;
}

/* allocate all the links of a sta, called when the station is first added */
static int iwl_mvm_mld_alloc_sta_links(struct iwl_mvm *mvm,
				       struct ieee80211_vif *vif,
				       struct ieee80211_sta *sta)
{
	struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
	unsigned int link_id;
	int ret;

	lockdep_assert_held(&mvm->mutex);

	for (link_id = 0; link_id < ARRAY_SIZE(sta->link); link_id++) {
		if (!rcu_access_pointer(sta->link[link_id]) ||
		    mvm_sta->link[link_id])
			continue;

		ret = iwl_mvm_mld_alloc_sta_link(mvm, vif, sta, link_id);
		if (ret)
			goto err;
	}

	return 0;

err:
	iwl_mvm_mld_sta_rm_all_sta_links(mvm, mvm_sta);
	return ret;
}

static void iwl_mvm_mld_set_ap_sta_id(struct ieee80211_sta *sta,
				      struct iwl_mvm_vif_link_info *vif_link,
				      struct iwl_mvm_link_sta *sta_link)
{
	if (!sta->tdls) {
		WARN_ON(vif_link->ap_sta_id != IWL_MVM_INVALID_STA);
		vif_link->ap_sta_id = sta_link->sta_id;
	} else {
		WARN_ON(vif_link->ap_sta_id == IWL_MVM_INVALID_STA);
	}
}

/* FIXME: consider waiting for mac80211 to add the STA instead of allocating
 * queues here
 */
static int iwl_mvm_alloc_sta_after_restart(struct iwl_mvm *mvm,
					   struct ieee80211_vif *vif,
					   struct ieee80211_sta *sta)
{
	struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
	struct ieee80211_link_sta *link_sta;
	unsigned int link_id;
	/* no active link found */
	int ret = -EINVAL;
	int sta_id;

	/* First add an empty station since allocating a queue requires
	 * a valid station. Since we need a link_id to allocate a station,
	 * pick up the first valid one.
	 */
	for_each_sta_active_link(vif, sta, link_sta, link_id) {
		struct iwl_mvm_vif_link_info *mvm_link;
		struct ieee80211_bss_conf *link_conf =
			link_conf_dereference_protected(vif, link_id);
		struct iwl_mvm_link_sta *mvm_link_sta =
			rcu_dereference_protected(mvm_sta->link[link_id],
						  lockdep_is_held(&mvm->mutex));

		if (!link_conf)
			continue;

		mvm_link = mvmvif->link[link_conf->link_id];

		if (!mvm_link || !mvm_link_sta)
			continue;

		sta_id = mvm_link_sta->sta_id;
		ret = iwl_mvm_mld_cfg_sta(mvm, sta, vif, link_sta,
					  link_conf, mvm_link_sta);
		if (ret)
			return ret;

		rcu_assign_pointer(mvm->fw_id_to_mac_id[sta_id], sta);
		rcu_assign_pointer(mvm->fw_id_to_link_sta[sta_id], link_sta);
		ret = 0;
	}

	iwl_mvm_realloc_queues_after_restart(mvm, sta);

	return ret;
}

int iwl_mvm_mld_add_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
			struct ieee80211_sta *sta)
{
	struct iwl_mvm_vif *mvm_vif = iwl_mvm_vif_from_mac80211(vif);
	struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
	unsigned long link_sta_added_to_fw = 0;
	struct ieee80211_link_sta *link_sta;
	int ret = 0;
	unsigned int link_id;

	lockdep_assert_held(&mvm->mutex);

	if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) {
		ret = iwl_mvm_mld_alloc_sta_links(mvm, vif, sta);
		if (ret)
			return ret;

		spin_lock_init(&mvm_sta->lock);

		ret = iwl_mvm_sta_init(mvm, vif, sta, IWL_MVM_INVALID_STA,
				       STATION_TYPE_PEER);
	} else {
		ret = iwl_mvm_alloc_sta_after_restart(mvm, vif, sta);
	}

	if (ret)
		goto err;

	/* at this stage sta link pointers are already allocated */
	ret = iwl_mvm_mld_update_sta(mvm, vif, sta);
	if (ret)
		goto err;

	for_each_sta_active_link(vif, sta, link_sta, link_id) {
		struct ieee80211_bss_conf *link_conf =
			link_conf_dereference_protected(vif, link_id);
		struct iwl_mvm_link_sta *mvm_link_sta =
			rcu_dereference_protected(mvm_sta->link[link_id],
						  lockdep_is_held(&mvm->mutex));

		if (WARN_ON(!link_conf || !mvm_link_sta)) {
			ret = -EINVAL;
			goto err;
		}

		ret = iwl_mvm_mld_cfg_sta(mvm, sta, vif, link_sta, link_conf,
					  mvm_link_sta);
		if (ret)
			goto err;

		link_sta_added_to_fw |= BIT(link_id);

		if (vif->type == NL80211_IFTYPE_STATION)
			iwl_mvm_mld_set_ap_sta_id(sta, mvm_vif->link[link_id],
						  mvm_link_sta);
	}

	return 0;

err:
	/* remove all already allocated stations in FW */
	for_each_set_bit(link_id, &link_sta_added_to_fw,
			 IEEE80211_MLD_MAX_NUM_LINKS) {
		struct iwl_mvm_link_sta *mvm_link_sta =
			rcu_dereference_protected(mvm_sta->link[link_id],
						  lockdep_is_held(&mvm->mutex));

		iwl_mvm_mld_rm_sta_from_fw(mvm, mvm_link_sta->sta_id);
	}

	/* free all sta resources in the driver */
	iwl_mvm_mld_sta_rm_all_sta_links(mvm, mvm_sta);
	return ret;
}

int iwl_mvm_mld_update_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
			   struct ieee80211_sta *sta)
{
	struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
	struct ieee80211_link_sta *link_sta;
	unsigned int link_id;
	int ret = -EINVAL;

	lockdep_assert_held(&mvm->mutex);

	for_each_sta_active_link(vif, sta, link_sta, link_id) {
		struct ieee80211_bss_conf *link_conf =
			link_conf_dereference_protected(vif, link_id);
		struct iwl_mvm_link_sta *mvm_link_sta =
			rcu_dereference_protected(mvm_sta->link[link_id],
						  lockdep_is_held(&mvm->mutex));

		if (WARN_ON(!link_conf || !mvm_link_sta))
			return -EINVAL;

		ret = iwl_mvm_mld_cfg_sta(mvm, sta, vif, link_sta, link_conf,
					  mvm_link_sta);

		if (ret) {
			IWL_ERR(mvm, "Failed to update sta link %d\n", link_id);
			break;
		}
	}

	return ret;
}

static void iwl_mvm_mld_disable_sta_queues(struct iwl_mvm *mvm,
					   struct ieee80211_vif *vif,
					   struct ieee80211_sta *sta)
{
	struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
	u32 sta_mask = iwl_mvm_sta_fw_id_mask(mvm, sta, -1);
	int i;

	lockdep_assert_held(&mvm->mutex);

	for (i = 0; i < ARRAY_SIZE(mvm_sta->tid_data); i++) {
		if (mvm_sta->tid_data[i].txq_id == IWL_MVM_INVALID_QUEUE)
			continue;

		iwl_mvm_mld_disable_txq(mvm, sta_mask,
					&mvm_sta->tid_data[i].txq_id, i);
		mvm_sta->tid_data[i].txq_id = IWL_MVM_INVALID_QUEUE;
	}

	for (i = 0; i < ARRAY_SIZE(sta->txq); i++) {
		struct iwl_mvm_txq *mvmtxq =
			iwl_mvm_txq_from_mac80211(sta->txq[i]);

		mvmtxq->txq_id = IWL_MVM_INVALID_QUEUE;
	}
}

int iwl_mvm_mld_rm_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
		       struct ieee80211_sta *sta)
{
	struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
	struct ieee80211_link_sta *link_sta;
	unsigned int link_id;
	int ret;

	lockdep_assert_held(&mvm->mutex);

	/* flush its queues here since we are freeing mvm_sta */
	for_each_sta_active_link(vif, sta, link_sta, link_id) {
		struct iwl_mvm_link_sta *mvm_link_sta =
			rcu_dereference_protected(mvm_sta->link[link_id],
						  lockdep_is_held(&mvm->mutex));

		if (WARN_ON(!mvm_link_sta))
			return -EINVAL;

		ret = iwl_mvm_flush_sta_tids(mvm, mvm_link_sta->sta_id,
					     0xffff);
		if (ret)
			return ret;
	}

	ret = iwl_mvm_wait_sta_queues_empty(mvm, mvm_sta);
	if (ret)
		return ret;

	iwl_mvm_mld_disable_sta_queues(mvm, vif, sta);

	for_each_sta_active_link(vif, sta, link_sta, link_id) {
		struct iwl_mvm_link_sta *mvm_link_sta =
			rcu_dereference_protected(mvm_sta->link[link_id],
						  lockdep_is_held(&mvm->mutex));
		bool stay_in_fw;

		stay_in_fw = iwl_mvm_sta_del(mvm, vif, sta, link_sta, &ret);
		if (ret)
			break;

		if (!stay_in_fw)
			ret = iwl_mvm_mld_rm_sta_from_fw(mvm,
							 mvm_link_sta->sta_id);

		iwl_mvm_mld_free_sta_link(mvm, mvm_sta, mvm_link_sta,
					  link_id, stay_in_fw);
	}

	return ret;
}

int iwl_mvm_mld_rm_sta_id(struct iwl_mvm *mvm, u8 sta_id)
{
	int ret;

	lockdep_assert_held(&mvm->mutex);

	if (WARN_ON(sta_id == IWL_MVM_INVALID_STA))
		return 0;

	ret = iwl_mvm_mld_rm_sta_from_fw(mvm, sta_id);

	RCU_INIT_POINTER(mvm->fw_id_to_mac_id[sta_id], NULL);
	RCU_INIT_POINTER(mvm->fw_id_to_link_sta[sta_id], NULL);
	return ret;
}

void iwl_mvm_mld_sta_modify_disable_tx(struct iwl_mvm *mvm,
				       struct iwl_mvm_sta *mvmsta,
				       bool disable)
{
	struct iwl_mvm_sta_disable_tx_cmd cmd;
	int ret;

	cmd.sta_id = cpu_to_le32(mvmsta->deflink.sta_id);
	cmd.disable = cpu_to_le32(disable);

	if (WARN_ON(iwl_mvm_has_no_host_disable_tx(mvm)))
		return;

	ret = iwl_mvm_send_cmd_pdu(mvm,
				   WIDE_ID(MAC_CONF_GROUP, STA_DISABLE_TX_CMD),
				   CMD_ASYNC, sizeof(cmd), &cmd);
	if (ret)
		IWL_ERR(mvm,
			"Failed to send STA_DISABLE_TX_CMD command (%d)\n",
			ret);
}

void iwl_mvm_mld_sta_modify_disable_tx_ap(struct iwl_mvm *mvm,
					  struct ieee80211_sta *sta,
					  bool disable)
{
	struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);

	spin_lock_bh(&mvm_sta->lock);

	if (mvm_sta->disable_tx == disable) {
		spin_unlock_bh(&mvm_sta->lock);
		return;
	}

	iwl_mvm_mld_sta_modify_disable_tx(mvm, mvm_sta, disable);

	spin_unlock_bh(&mvm_sta->lock);
}

void iwl_mvm_mld_modify_all_sta_disable_tx(struct iwl_mvm *mvm,
					   struct iwl_mvm_vif *mvmvif,
					   bool disable)
{
	struct ieee80211_sta *sta;
	struct iwl_mvm_sta *mvm_sta;
	int i;

	rcu_read_lock();

	/* Block/unblock all the stations of the given mvmvif */
	for (i = 0; i < mvm->fw->ucode_capa.num_stations; i++) {
		sta = rcu_dereference(mvm->fw_id_to_mac_id[i]);
		if (IS_ERR_OR_NULL(sta))
			continue;

		mvm_sta = iwl_mvm_sta_from_mac80211(sta);
		if (mvm_sta->mac_id_n_color !=
		    FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color))
			continue;

		iwl_mvm_mld_sta_modify_disable_tx(mvm, mvm_sta, disable);
	}

	rcu_read_unlock();
}

static int iwl_mvm_mld_update_sta_queues(struct iwl_mvm *mvm,
					 struct ieee80211_sta *sta,
					 u32 old_sta_mask,
					 u32 new_sta_mask)
{
	struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
	struct iwl_scd_queue_cfg_cmd cmd = {
		.operation = cpu_to_le32(IWL_SCD_QUEUE_MODIFY),
		.u.modify.old_sta_mask = cpu_to_le32(old_sta_mask),
		.u.modify.new_sta_mask = cpu_to_le32(new_sta_mask),
	};
	struct iwl_host_cmd hcmd = {
		.id = WIDE_ID(DATA_PATH_GROUP, SCD_QUEUE_CONFIG_CMD),
		.len[0] = sizeof(cmd),
		.data[0] = &cmd
	};
	int tid;
	int ret;

	lockdep_assert_held(&mvm->mutex);

	for (tid = 0; tid <= IWL_MAX_TID_COUNT; tid++) {
		struct iwl_mvm_tid_data *tid_data = &mvm_sta->tid_data[tid];
		int txq_id = tid_data->txq_id;

		if (txq_id == IWL_MVM_INVALID_QUEUE)
			continue;

		if (tid == IWL_MAX_TID_COUNT)
			cmd.u.modify.tid = cpu_to_le32(IWL_MGMT_TID);
		else
			cmd.u.modify.tid = cpu_to_le32(tid);

		ret = iwl_mvm_send_cmd(mvm, &hcmd);
		if (ret)
			return ret;
	}

	return 0;
}

static int iwl_mvm_mld_update_sta_baids(struct iwl_mvm *mvm,
					u32 old_sta_mask,
					u32 new_sta_mask)
{
	struct iwl_rx_baid_cfg_cmd cmd = {
		.action = cpu_to_le32(IWL_RX_BAID_ACTION_MODIFY),
		.modify.old_sta_id_mask = cpu_to_le32(old_sta_mask),
		.modify.new_sta_id_mask = cpu_to_le32(new_sta_mask),
	};
	u32 cmd_id = WIDE_ID(DATA_PATH_GROUP, RX_BAID_ALLOCATION_CONFIG_CMD);
	int baid;

	BUILD_BUG_ON(sizeof(struct iwl_rx_baid_cfg_resp) != sizeof(baid));

	for (baid = 0; baid < ARRAY_SIZE(mvm->baid_map); baid++) {
		struct iwl_mvm_baid_data *data;
		int ret;

		data = rcu_dereference_protected(mvm->baid_map[baid],
						 lockdep_is_held(&mvm->mutex));
		if (!data)
			continue;

		if (!(data->sta_mask & old_sta_mask))
			continue;

		WARN_ONCE(data->sta_mask != old_sta_mask,
			  "BAID data for %d corrupted - expected 0x%x found 0x%x\n",
			  baid, old_sta_mask, data->sta_mask);

		cmd.modify.tid = cpu_to_le32(data->tid);

		ret = iwl_mvm_send_cmd_pdu(mvm, cmd_id, 0, sizeof(cmd), &cmd);
		data->sta_mask = new_sta_mask;
		if (ret)
			return ret;
	}

	return 0;
}

static int iwl_mvm_mld_update_sta_resources(struct iwl_mvm *mvm,
					    struct ieee80211_vif *vif,
					    struct ieee80211_sta *sta,
					    u32 old_sta_mask,
					    u32 new_sta_mask)
{
	int ret;

	ret = iwl_mvm_mld_update_sta_queues(mvm, sta,
					    old_sta_mask,
					    new_sta_mask);
	if (ret)
		return ret;

	ret = iwl_mvm_mld_update_sta_keys(mvm, vif, sta,
					  old_sta_mask,
					  new_sta_mask);
	if (ret)
		return ret;

	return iwl_mvm_mld_update_sta_baids(mvm, old_sta_mask, new_sta_mask);
}

int iwl_mvm_mld_update_sta_links(struct iwl_mvm *mvm,
				 struct ieee80211_vif *vif,
				 struct ieee80211_sta *sta,
				 u16 old_links, u16 new_links)
{
	struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
	struct iwl_mvm_vif *mvm_vif = iwl_mvm_vif_from_mac80211(vif);
	struct iwl_mvm_link_sta *mvm_sta_link;
	struct iwl_mvm_vif_link_info *mvm_vif_link;
	unsigned long links_to_add = ~old_links & new_links;
	unsigned long links_to_rem = old_links & ~new_links;
	unsigned long old_links_long = old_links;
	u32 current_sta_mask = 0, sta_mask_added = 0, sta_mask_to_rem = 0;
	unsigned long link_sta_added_to_fw = 0, link_sta_allocated = 0;
	unsigned int link_id;
	int ret;

	lockdep_assert_held(&mvm->mutex);

	for_each_set_bit(link_id, &old_links_long,
			 IEEE80211_MLD_MAX_NUM_LINKS) {
		mvm_sta_link =
			rcu_dereference_protected(mvm_sta->link[link_id],
						  lockdep_is_held(&mvm->mutex));

		if (WARN_ON(!mvm_sta_link)) {
			ret = -EINVAL;
			goto err;
		}

		current_sta_mask |= BIT(mvm_sta_link->sta_id);
		if (links_to_rem & BIT(link_id))
			sta_mask_to_rem |= BIT(mvm_sta_link->sta_id);
	}

	if (sta_mask_to_rem) {
		ret = iwl_mvm_mld_update_sta_resources(mvm, vif, sta,
						       current_sta_mask,
						       current_sta_mask &
							~sta_mask_to_rem);
		if (WARN_ON(ret))
			goto err;

		current_sta_mask &= ~sta_mask_to_rem;
	}

	for_each_set_bit(link_id, &links_to_rem, IEEE80211_MLD_MAX_NUM_LINKS) {
		mvm_sta_link =
			rcu_dereference_protected(mvm_sta->link[link_id],
						  lockdep_is_held(&mvm->mutex));
		mvm_vif_link = mvm_vif->link[link_id];

		if (WARN_ON(!mvm_sta_link || !mvm_vif_link)) {
			ret = -EINVAL;
			goto err;
		}

		ret = iwl_mvm_mld_rm_sta_from_fw(mvm, mvm_sta_link->sta_id);
		if (WARN_ON(ret))
			goto err;

		if (vif->type == NL80211_IFTYPE_STATION)
			mvm_vif_link->ap_sta_id = IWL_MVM_INVALID_STA;

		iwl_mvm_mld_free_sta_link(mvm, mvm_sta, mvm_sta_link, link_id,
					  false);
	}

	for_each_set_bit(link_id, &links_to_add, IEEE80211_MLD_MAX_NUM_LINKS) {
		struct ieee80211_bss_conf *link_conf =
			link_conf_dereference_protected(vif, link_id);
		struct ieee80211_link_sta *link_sta =
			link_sta_dereference_protected(sta, link_id);
		mvm_vif_link = mvm_vif->link[link_id];

		if (WARN_ON(!mvm_vif_link || !link_conf || !link_sta)) {
			ret = -EINVAL;
			goto err;
		}

		if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) {
			if (WARN_ON(!mvm_sta->link[link_id])) {
				ret = -EINVAL;
				goto err;
			}
		} else {
			if (WARN_ON(mvm_sta->link[link_id])) {
				ret = -EINVAL;
				goto err;
			}
			ret = iwl_mvm_mld_alloc_sta_link(mvm, vif, sta,
							 link_id);
			if (WARN_ON(ret))
				goto err;
		}

		link_sta->agg.max_rc_amsdu_len = 1;
		ieee80211_sta_recalc_aggregates(sta);

		mvm_sta_link =
			rcu_dereference_protected(mvm_sta->link[link_id],
						  lockdep_is_held(&mvm->mutex));

		if (WARN_ON(!mvm_sta_link)) {
			ret = -EINVAL;
			goto err;
		}

		if (vif->type == NL80211_IFTYPE_STATION)
			iwl_mvm_mld_set_ap_sta_id(sta, mvm_vif_link,
						  mvm_sta_link);

		link_sta_allocated |= BIT(link_id);

		sta_mask_added |= BIT(mvm_sta_link->sta_id);

		ret = iwl_mvm_mld_cfg_sta(mvm, sta, vif, link_sta, link_conf,
					  mvm_sta_link);
		if (WARN_ON(ret))
			goto err;

		link_sta_added_to_fw |= BIT(link_id);

		iwl_mvm_rs_add_sta_link(mvm, mvm_sta_link);
	}

	if (sta_mask_added) {
		ret = iwl_mvm_mld_update_sta_resources(mvm, vif, sta,
						       current_sta_mask,
						       current_sta_mask |
							sta_mask_added);
		if (WARN_ON(ret))
			goto err;
	}

	return 0;

err:
	/* remove all already allocated stations in FW */
	for_each_set_bit(link_id, &link_sta_added_to_fw,
			 IEEE80211_MLD_MAX_NUM_LINKS) {
		mvm_sta_link =
			rcu_dereference_protected(mvm_sta->link[link_id],
						  lockdep_is_held(&mvm->mutex));

		iwl_mvm_mld_rm_sta_from_fw(mvm, mvm_sta_link->sta_id);
	}

	/* remove all already allocated station links in driver */
	for_each_set_bit(link_id, &link_sta_allocated,
			 IEEE80211_MLD_MAX_NUM_LINKS) {
		mvm_sta_link =
			rcu_dereference_protected(mvm_sta->link[link_id],
						  lockdep_is_held(&mvm->mutex));

		iwl_mvm_mld_free_sta_link(mvm, mvm_sta, mvm_sta_link, link_id,
					  false);
	}

	return ret;
}
