/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Copyright (C) 2018 - 2021, 2023 - 2024 Intel Corporation
 */
#include <net/cfg80211.h>
#include "core.h"
#include "nl80211.h"
#include "rdev-ops.h"

static int pmsr_parse_ftm(struct cfg80211_registered_device *rdev,
			  struct nlattr *ftmreq,
			  struct cfg80211_pmsr_request_peer *out,
			  struct genl_info *info)
{
	const struct cfg80211_pmsr_capabilities *capa = rdev->wiphy.pmsr_capa;
	struct nlattr *tb[NL80211_PMSR_FTM_REQ_ATTR_MAX + 1];
	u32 preamble = NL80211_PREAMBLE_DMG; /* only optional in DMG */

	/* validate existing data */
	if (!(rdev->wiphy.pmsr_capa->ftm.bandwidths & BIT(out->chandef.width))) {
		NL_SET_ERR_MSG(info->extack, "FTM: unsupported bandwidth");
		return -EINVAL;
	}

	/* no validation needed - was already done via nested policy */
	nla_parse_nested_deprecated(tb, NL80211_PMSR_FTM_REQ_ATTR_MAX, ftmreq,
				    NULL, NULL);

	if (tb[NL80211_PMSR_FTM_REQ_ATTR_PREAMBLE])
		preamble = nla_get_u32(tb[NL80211_PMSR_FTM_REQ_ATTR_PREAMBLE]);

	/* set up values - struct is 0-initialized */
	out->ftm.requested = true;

	switch (out->chandef.chan->band) {
	case NL80211_BAND_60GHZ:
		/* optional */
		break;
	default:
		if (!tb[NL80211_PMSR_FTM_REQ_ATTR_PREAMBLE]) {
			NL_SET_ERR_MSG(info->extack,
				       "FTM: must specify preamble");
			return -EINVAL;
		}
	}

	if (!(capa->ftm.preambles & BIT(preamble))) {
		NL_SET_ERR_MSG_ATTR(info->extack,
				    tb[NL80211_PMSR_FTM_REQ_ATTR_PREAMBLE],
				    "FTM: invalid preamble");
		return -EINVAL;
	}

	out->ftm.preamble = preamble;

	out->ftm.burst_period = 0;
	if (tb[NL80211_PMSR_FTM_REQ_ATTR_BURST_PERIOD])
		out->ftm.burst_period =
			nla_get_u16(tb[NL80211_PMSR_FTM_REQ_ATTR_BURST_PERIOD]);

	out->ftm.asap = !!tb[NL80211_PMSR_FTM_REQ_ATTR_ASAP];
	if (out->ftm.asap && !capa->ftm.asap) {
		NL_SET_ERR_MSG_ATTR(info->extack,
				    tb[NL80211_PMSR_FTM_REQ_ATTR_ASAP],
				    "FTM: ASAP mode not supported");
		return -EINVAL;
	}

	if (!out->ftm.asap && !capa->ftm.non_asap) {
		NL_SET_ERR_MSG(info->extack,
			       "FTM: non-ASAP mode not supported");
		return -EINVAL;
	}

	out->ftm.num_bursts_exp = 0;
	if (tb[NL80211_PMSR_FTM_REQ_ATTR_NUM_BURSTS_EXP])
		out->ftm.num_bursts_exp =
			nla_get_u8(tb[NL80211_PMSR_FTM_REQ_ATTR_NUM_BURSTS_EXP]);

	if (capa->ftm.max_bursts_exponent >= 0 &&
	    out->ftm.num_bursts_exp > capa->ftm.max_bursts_exponent) {
		NL_SET_ERR_MSG_ATTR(info->extack,
				    tb[NL80211_PMSR_FTM_REQ_ATTR_NUM_BURSTS_EXP],
				    "FTM: max NUM_BURSTS_EXP must be set lower than the device limit");
		return -EINVAL;
	}

	out->ftm.burst_duration = 15;
	if (tb[NL80211_PMSR_FTM_REQ_ATTR_BURST_DURATION])
		out->ftm.burst_duration =
			nla_get_u8(tb[NL80211_PMSR_FTM_REQ_ATTR_BURST_DURATION]);

	out->ftm.ftms_per_burst = 0;
	if (tb[NL80211_PMSR_FTM_REQ_ATTR_FTMS_PER_BURST])
		out->ftm.ftms_per_burst =
			nla_get_u32(tb[NL80211_PMSR_FTM_REQ_ATTR_FTMS_PER_BURST]);

	if (capa->ftm.max_ftms_per_burst &&
	    (out->ftm.ftms_per_burst > capa->ftm.max_ftms_per_burst ||
	     out->ftm.ftms_per_burst == 0)) {
		NL_SET_ERR_MSG_ATTR(info->extack,
				    tb[NL80211_PMSR_FTM_REQ_ATTR_FTMS_PER_BURST],
				    "FTM: FTMs per burst must be set lower than the device limit but non-zero");
		return -EINVAL;
	}

	out->ftm.ftmr_retries = 3;
	if (tb[NL80211_PMSR_FTM_REQ_ATTR_NUM_FTMR_RETRIES])
		out->ftm.ftmr_retries =
			nla_get_u8(tb[NL80211_PMSR_FTM_REQ_ATTR_NUM_FTMR_RETRIES]);

	out->ftm.request_lci = !!tb[NL80211_PMSR_FTM_REQ_ATTR_REQUEST_LCI];
	if (out->ftm.request_lci && !capa->ftm.request_lci) {
		NL_SET_ERR_MSG_ATTR(info->extack,
				    tb[NL80211_PMSR_FTM_REQ_ATTR_REQUEST_LCI],
				    "FTM: LCI request not supported");
	}

	out->ftm.request_civicloc =
		!!tb[NL80211_PMSR_FTM_REQ_ATTR_REQUEST_CIVICLOC];
	if (out->ftm.request_civicloc && !capa->ftm.request_civicloc) {
		NL_SET_ERR_MSG_ATTR(info->extack,
				    tb[NL80211_PMSR_FTM_REQ_ATTR_REQUEST_CIVICLOC],
			    "FTM: civic location request not supported");
	}

	out->ftm.trigger_based =
		!!tb[NL80211_PMSR_FTM_REQ_ATTR_TRIGGER_BASED];
	if (out->ftm.trigger_based && !capa->ftm.trigger_based) {
		NL_SET_ERR_MSG_ATTR(info->extack,
				    tb[NL80211_PMSR_FTM_REQ_ATTR_TRIGGER_BASED],
				    "FTM: trigger based ranging is not supported");
		return -EINVAL;
	}

	out->ftm.non_trigger_based =
		!!tb[NL80211_PMSR_FTM_REQ_ATTR_NON_TRIGGER_BASED];
	if (out->ftm.non_trigger_based && !capa->ftm.non_trigger_based) {
		NL_SET_ERR_MSG_ATTR(info->extack,
				    tb[NL80211_PMSR_FTM_REQ_ATTR_NON_TRIGGER_BASED],
				    "FTM: trigger based ranging is not supported");
		return -EINVAL;
	}

	if (out->ftm.trigger_based && out->ftm.non_trigger_based) {
		NL_SET_ERR_MSG(info->extack,
			       "FTM: can't set both trigger based and non trigger based");
		return -EINVAL;
	}

	if (out->ftm.ftms_per_burst > 31 && !out->ftm.non_trigger_based &&
	    !out->ftm.trigger_based) {
		NL_SET_ERR_MSG_ATTR(info->extack,
				    tb[NL80211_PMSR_FTM_REQ_ATTR_FTMS_PER_BURST],
				    "FTM: FTMs per burst must be set lower than 31");
		return -ERANGE;
	}

	if ((out->ftm.trigger_based || out->ftm.non_trigger_based) &&
	    out->ftm.preamble != NL80211_PREAMBLE_HE) {
		NL_SET_ERR_MSG_ATTR(info->extack,
				    tb[NL80211_PMSR_FTM_REQ_ATTR_PREAMBLE],
				    "FTM: non EDCA based ranging must use HE preamble");
		return -EINVAL;
	}

	out->ftm.lmr_feedback =
		!!tb[NL80211_PMSR_FTM_REQ_ATTR_LMR_FEEDBACK];
	if (!out->ftm.trigger_based && !out->ftm.non_trigger_based &&
	    out->ftm.lmr_feedback) {
		NL_SET_ERR_MSG_ATTR(info->extack,
				    tb[NL80211_PMSR_FTM_REQ_ATTR_LMR_FEEDBACK],
				    "FTM: LMR feedback set for EDCA based ranging");
		return -EINVAL;
	}

	if (tb[NL80211_PMSR_FTM_REQ_ATTR_BSS_COLOR]) {
		if (!out->ftm.non_trigger_based && !out->ftm.trigger_based) {
			NL_SET_ERR_MSG_ATTR(info->extack,
					    tb[NL80211_PMSR_FTM_REQ_ATTR_BSS_COLOR],
					    "FTM: BSS color set for EDCA based ranging");
			return -EINVAL;
		}

		out->ftm.bss_color =
			nla_get_u8(tb[NL80211_PMSR_FTM_REQ_ATTR_BSS_COLOR]);
	}

	return 0;
}

static int pmsr_parse_peer(struct cfg80211_registered_device *rdev,
			   struct nlattr *peer,
			   struct cfg80211_pmsr_request_peer *out,
			   struct genl_info *info)
{
	struct nlattr *tb[NL80211_PMSR_PEER_ATTR_MAX + 1];
	struct nlattr *req[NL80211_PMSR_REQ_ATTR_MAX + 1];
	struct nlattr *treq;
	int err, rem;

	/* no validation needed - was already done via nested policy */
	nla_parse_nested_deprecated(tb, NL80211_PMSR_PEER_ATTR_MAX, peer,
				    NULL, NULL);

	if (!tb[NL80211_PMSR_PEER_ATTR_ADDR] ||
	    !tb[NL80211_PMSR_PEER_ATTR_CHAN] ||
	    !tb[NL80211_PMSR_PEER_ATTR_REQ]) {
		NL_SET_ERR_MSG_ATTR(info->extack, peer,
				    "insufficient peer data");
		return -EINVAL;
	}

	memcpy(out->addr, nla_data(tb[NL80211_PMSR_PEER_ATTR_ADDR]), ETH_ALEN);

	/* reuse info->attrs */
	memset(info->attrs, 0, sizeof(*info->attrs) * (NL80211_ATTR_MAX + 1));
	err = nla_parse_nested_deprecated(info->attrs, NL80211_ATTR_MAX,
					  tb[NL80211_PMSR_PEER_ATTR_CHAN],
					  NULL, info->extack);
	if (err)
		return err;

	err = nl80211_parse_chandef(rdev, info, &out->chandef);
	if (err)
		return err;

	/* no validation needed - was already done via nested policy */
	nla_parse_nested_deprecated(req, NL80211_PMSR_REQ_ATTR_MAX,
				    tb[NL80211_PMSR_PEER_ATTR_REQ], NULL,
				    NULL);

	if (!req[NL80211_PMSR_REQ_ATTR_DATA]) {
		NL_SET_ERR_MSG_ATTR(info->extack,
				    tb[NL80211_PMSR_PEER_ATTR_REQ],
				    "missing request type/data");
		return -EINVAL;
	}

	if (req[NL80211_PMSR_REQ_ATTR_GET_AP_TSF])
		out->report_ap_tsf = true;

	if (out->report_ap_tsf && !rdev->wiphy.pmsr_capa->report_ap_tsf) {
		NL_SET_ERR_MSG_ATTR(info->extack,
				    req[NL80211_PMSR_REQ_ATTR_GET_AP_TSF],
				    "reporting AP TSF is not supported");
		return -EINVAL;
	}

	nla_for_each_nested(treq, req[NL80211_PMSR_REQ_ATTR_DATA], rem) {
		switch (nla_type(treq)) {
		case NL80211_PMSR_TYPE_FTM:
			err = pmsr_parse_ftm(rdev, treq, out, info);
			break;
		default:
			NL_SET_ERR_MSG_ATTR(info->extack, treq,
					    "unsupported measurement type");
			err = -EINVAL;
		}
	}

	if (err)
		return err;

	return 0;
}

int nl80211_pmsr_start(struct sk_buff *skb, struct genl_info *info)
{
	struct nlattr *reqattr = info->attrs[NL80211_ATTR_PEER_MEASUREMENTS];
	struct cfg80211_registered_device *rdev = info->user_ptr[0];
	struct wireless_dev *wdev = info->user_ptr[1];
	struct cfg80211_pmsr_request *req;
	struct nlattr *peers, *peer;
	int count, rem, err, idx;

	if (!rdev->wiphy.pmsr_capa)
		return -EOPNOTSUPP;

	if (!reqattr)
		return -EINVAL;

	peers = nla_find(nla_data(reqattr), nla_len(reqattr),
			 NL80211_PMSR_ATTR_PEERS);
	if (!peers)
		return -EINVAL;

	count = 0;
	nla_for_each_nested(peer, peers, rem) {
		count++;

		if (count > rdev->wiphy.pmsr_capa->max_peers) {
			NL_SET_ERR_MSG_ATTR(info->extack, peer,
					    "Too many peers used");
			return -EINVAL;
		}
	}

	req = kzalloc(struct_size(req, peers, count), GFP_KERNEL);
	if (!req)
		return -ENOMEM;
	req->n_peers = count;

	if (info->attrs[NL80211_ATTR_TIMEOUT])
		req->timeout = nla_get_u32(info->attrs[NL80211_ATTR_TIMEOUT]);

	if (info->attrs[NL80211_ATTR_MAC]) {
		if (!rdev->wiphy.pmsr_capa->randomize_mac_addr) {
			NL_SET_ERR_MSG_ATTR(info->extack,
					    info->attrs[NL80211_ATTR_MAC],
					    "device cannot randomize MAC address");
			err = -EINVAL;
			goto out_err;
		}

		err = nl80211_parse_random_mac(info->attrs, req->mac_addr,
					       req->mac_addr_mask);
		if (err)
			goto out_err;
	} else {
		memcpy(req->mac_addr, wdev_address(wdev), ETH_ALEN);
		eth_broadcast_addr(req->mac_addr_mask);
	}

	idx = 0;
	nla_for_each_nested(peer, peers, rem) {
		/* NB: this reuses info->attrs, but we no longer need it */
		err = pmsr_parse_peer(rdev, peer, &req->peers[idx], info);
		if (err)
			goto out_err;
		idx++;
	}
	req->cookie = cfg80211_assign_cookie(rdev);
	req->nl_portid = info->snd_portid;

	err = rdev_start_pmsr(rdev, wdev, req);
	if (err)
		goto out_err;

	list_add_tail(&req->list, &wdev->pmsr_list);

	nl_set_extack_cookie_u64(info->extack, req->cookie);
	return 0;
out_err:
	kfree(req);
	return err;
}

void cfg80211_pmsr_complete(struct wireless_dev *wdev,
			    struct cfg80211_pmsr_request *req,
			    gfp_t gfp)
{
	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
	struct cfg80211_pmsr_request *tmp, *prev, *to_free = NULL;
	struct sk_buff *msg;
	void *hdr;

	trace_cfg80211_pmsr_complete(wdev->wiphy, wdev, req->cookie);

	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
	if (!msg)
		goto free_request;

	hdr = nl80211hdr_put(msg, 0, 0, 0,
			     NL80211_CMD_PEER_MEASUREMENT_COMPLETE);
	if (!hdr)
		goto free_msg;

	if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
	    nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
			      NL80211_ATTR_PAD))
		goto free_msg;

	if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, req->cookie,
			      NL80211_ATTR_PAD))
		goto free_msg;

	genlmsg_end(msg, hdr);
	genlmsg_unicast(wiphy_net(wdev->wiphy), msg, req->nl_portid);
	goto free_request;
free_msg:
	nlmsg_free(msg);
free_request:
	spin_lock_bh(&wdev->pmsr_lock);
	/*
	 * cfg80211_pmsr_process_abort() may have already moved this request
	 * to the free list, and will free it later. In this case, don't free
	 * it here.
	 */
	list_for_each_entry_safe(tmp, prev, &wdev->pmsr_list, list) {
		if (tmp == req) {
			list_del(&req->list);
			to_free = req;
			break;
		}
	}
	spin_unlock_bh(&wdev->pmsr_lock);
	kfree(to_free);
}
EXPORT_SYMBOL_GPL(cfg80211_pmsr_complete);

static int nl80211_pmsr_send_ftm_res(struct sk_buff *msg,
				     struct cfg80211_pmsr_result *res)
{
	if (res->status == NL80211_PMSR_STATUS_FAILURE) {
		if (nla_put_u32(msg, NL80211_PMSR_FTM_RESP_ATTR_FAIL_REASON,
				res->ftm.failure_reason))
			goto error;

		if (res->ftm.failure_reason ==
			NL80211_PMSR_FTM_FAILURE_PEER_BUSY &&
		    res->ftm.busy_retry_time &&
		    nla_put_u32(msg, NL80211_PMSR_FTM_RESP_ATTR_BUSY_RETRY_TIME,
				res->ftm.busy_retry_time))
			goto error;

		return 0;
	}

#define PUT(tp, attr, val)						\
	do {								\
		if (nla_put_##tp(msg,					\
				 NL80211_PMSR_FTM_RESP_ATTR_##attr,	\
				 res->ftm.val))				\
			goto error;					\
	} while (0)

#define PUTOPT(tp, attr, val)						\
	do {								\
		if (res->ftm.val##_valid)				\
			PUT(tp, attr, val);				\
	} while (0)

#define PUT_U64(attr, val)						\
	do {								\
		if (nla_put_u64_64bit(msg,				\
				      NL80211_PMSR_FTM_RESP_ATTR_##attr,\
				      res->ftm.val,			\
				      NL80211_PMSR_FTM_RESP_ATTR_PAD))	\
			goto error;					\
	} while (0)

#define PUTOPT_U64(attr, val)						\
	do {								\
		if (res->ftm.val##_valid)				\
			PUT_U64(attr, val);				\
	} while (0)

	if (res->ftm.burst_index >= 0)
		PUT(u32, BURST_INDEX, burst_index);
	PUTOPT(u32, NUM_FTMR_ATTEMPTS, num_ftmr_attempts);
	PUTOPT(u32, NUM_FTMR_SUCCESSES, num_ftmr_successes);
	PUT(u8, NUM_BURSTS_EXP, num_bursts_exp);
	PUT(u8, BURST_DURATION, burst_duration);
	PUT(u8, FTMS_PER_BURST, ftms_per_burst);
	PUTOPT(s32, RSSI_AVG, rssi_avg);
	PUTOPT(s32, RSSI_SPREAD, rssi_spread);
	if (res->ftm.tx_rate_valid &&
	    !nl80211_put_sta_rate(msg, &res->ftm.tx_rate,
				  NL80211_PMSR_FTM_RESP_ATTR_TX_RATE))
		goto error;
	if (res->ftm.rx_rate_valid &&
	    !nl80211_put_sta_rate(msg, &res->ftm.rx_rate,
				  NL80211_PMSR_FTM_RESP_ATTR_RX_RATE))
		goto error;
	PUTOPT_U64(RTT_AVG, rtt_avg);
	PUTOPT_U64(RTT_VARIANCE, rtt_variance);
	PUTOPT_U64(RTT_SPREAD, rtt_spread);
	PUTOPT_U64(DIST_AVG, dist_avg);
	PUTOPT_U64(DIST_VARIANCE, dist_variance);
	PUTOPT_U64(DIST_SPREAD, dist_spread);
	if (res->ftm.lci && res->ftm.lci_len &&
	    nla_put(msg, NL80211_PMSR_FTM_RESP_ATTR_LCI,
		    res->ftm.lci_len, res->ftm.lci))
		goto error;
	if (res->ftm.civicloc && res->ftm.civicloc_len &&
	    nla_put(msg, NL80211_PMSR_FTM_RESP_ATTR_CIVICLOC,
		    res->ftm.civicloc_len, res->ftm.civicloc))
		goto error;
#undef PUT
#undef PUTOPT
#undef PUT_U64
#undef PUTOPT_U64

	return 0;
error:
	return -ENOSPC;
}

static int nl80211_pmsr_send_result(struct sk_buff *msg,
				    struct cfg80211_pmsr_result *res)
{
	struct nlattr *pmsr, *peers, *peer, *resp, *data, *typedata;

	pmsr = nla_nest_start_noflag(msg, NL80211_ATTR_PEER_MEASUREMENTS);
	if (!pmsr)
		goto error;

	peers = nla_nest_start_noflag(msg, NL80211_PMSR_ATTR_PEERS);
	if (!peers)
		goto error;

	peer = nla_nest_start_noflag(msg, 1);
	if (!peer)
		goto error;

	if (nla_put(msg, NL80211_PMSR_PEER_ATTR_ADDR, ETH_ALEN, res->addr))
		goto error;

	resp = nla_nest_start_noflag(msg, NL80211_PMSR_PEER_ATTR_RESP);
	if (!resp)
		goto error;

	if (nla_put_u32(msg, NL80211_PMSR_RESP_ATTR_STATUS, res->status) ||
	    nla_put_u64_64bit(msg, NL80211_PMSR_RESP_ATTR_HOST_TIME,
			      res->host_time, NL80211_PMSR_RESP_ATTR_PAD))
		goto error;

	if (res->ap_tsf_valid &&
	    nla_put_u64_64bit(msg, NL80211_PMSR_RESP_ATTR_AP_TSF,
			      res->ap_tsf, NL80211_PMSR_RESP_ATTR_PAD))
		goto error;

	if (res->final && nla_put_flag(msg, NL80211_PMSR_RESP_ATTR_FINAL))
		goto error;

	data = nla_nest_start_noflag(msg, NL80211_PMSR_RESP_ATTR_DATA);
	if (!data)
		goto error;

	typedata = nla_nest_start_noflag(msg, res->type);
	if (!typedata)
		goto error;

	switch (res->type) {
	case NL80211_PMSR_TYPE_FTM:
		if (nl80211_pmsr_send_ftm_res(msg, res))
			goto error;
		break;
	default:
		WARN_ON(1);
	}

	nla_nest_end(msg, typedata);
	nla_nest_end(msg, data);
	nla_nest_end(msg, resp);
	nla_nest_end(msg, peer);
	nla_nest_end(msg, peers);
	nla_nest_end(msg, pmsr);

	return 0;
error:
	return -ENOSPC;
}

void cfg80211_pmsr_report(struct wireless_dev *wdev,
			  struct cfg80211_pmsr_request *req,
			  struct cfg80211_pmsr_result *result,
			  gfp_t gfp)
{
	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
	struct sk_buff *msg;
	void *hdr;
	int err;

	trace_cfg80211_pmsr_report(wdev->wiphy, wdev, req->cookie,
				   result->addr);

	/*
	 * Currently, only variable items are LCI and civic location,
	 * both of which are reasonably short so we don't need to
	 * worry about them here for the allocation.
	 */
	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
	if (!msg)
		return;

	hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_PEER_MEASUREMENT_RESULT);
	if (!hdr)
		goto free;

	if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
	    nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
			      NL80211_ATTR_PAD))
		goto free;

	if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, req->cookie,
			      NL80211_ATTR_PAD))
		goto free;

	err = nl80211_pmsr_send_result(msg, result);
	if (err) {
		pr_err_ratelimited("peer measurement result: message didn't fit!");
		goto free;
	}

	genlmsg_end(msg, hdr);
	genlmsg_unicast(wiphy_net(wdev->wiphy), msg, req->nl_portid);
	return;
free:
	nlmsg_free(msg);
}
EXPORT_SYMBOL_GPL(cfg80211_pmsr_report);

static void cfg80211_pmsr_process_abort(struct wireless_dev *wdev)
{
	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
	struct cfg80211_pmsr_request *req, *tmp;
	LIST_HEAD(free_list);

	lockdep_assert_wiphy(wdev->wiphy);

	spin_lock_bh(&wdev->pmsr_lock);
	list_for_each_entry_safe(req, tmp, &wdev->pmsr_list, list) {
		if (req->nl_portid)
			continue;
		list_move_tail(&req->list, &free_list);
	}
	spin_unlock_bh(&wdev->pmsr_lock);

	list_for_each_entry_safe(req, tmp, &free_list, list) {
		rdev_abort_pmsr(rdev, wdev, req);

		kfree(req);
	}
}

void cfg80211_pmsr_free_wk(struct work_struct *work)
{
	struct wireless_dev *wdev = container_of(work, struct wireless_dev,
						 pmsr_free_wk);

	wiphy_lock(wdev->wiphy);
	cfg80211_pmsr_process_abort(wdev);
	wiphy_unlock(wdev->wiphy);
}

void cfg80211_pmsr_wdev_down(struct wireless_dev *wdev)
{
	struct cfg80211_pmsr_request *req;
	bool found = false;

	spin_lock_bh(&wdev->pmsr_lock);
	list_for_each_entry(req, &wdev->pmsr_list, list) {
		found = true;
		req->nl_portid = 0;
	}
	spin_unlock_bh(&wdev->pmsr_lock);

	if (found)
		cfg80211_pmsr_process_abort(wdev);

	WARN_ON(!list_empty(&wdev->pmsr_list));
}

void cfg80211_release_pmsr(struct wireless_dev *wdev, u32 portid)
{
	struct cfg80211_pmsr_request *req;

	spin_lock_bh(&wdev->pmsr_lock);
	list_for_each_entry(req, &wdev->pmsr_list, list) {
		if (req->nl_portid == portid) {
			req->nl_portid = 0;
			schedule_work(&wdev->pmsr_free_wk);
		}
	}
	spin_unlock_bh(&wdev->pmsr_lock);
}
