// SPDX-License-Identifier: GPL-2.0-only
/*
 * spectrum management
 *
 * Copyright 2003, Jouni Malinen <jkmaline@cc.hut.fi>
 * Copyright 2002-2005, Instant802 Networks, Inc.
 * Copyright 2005-2006, Devicescape Software, Inc.
 * Copyright 2006-2007  Jiri Benc <jbenc@suse.cz>
 * Copyright 2007, Michael Wu <flamingice@sourmilk.net>
 * Copyright 2007-2008, Intel Corporation
 * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
 * Copyright (C) 2018, 2020, 2022-2024, 2026 Intel Corporation
 */

#include <linux/ieee80211.h>
#include <net/cfg80211.h>
#include <net/mac80211.h>
#include "ieee80211_i.h"
#include "sta_info.h"
#include "wme.h"

static bool
wbcs_elem_to_chandef(const struct ieee80211_wide_bw_chansw_ie *wbcs_elem,
		     struct cfg80211_chan_def *chandef)
{
	u8 ccfs0 = wbcs_elem->new_center_freq_seg0;
	u8 ccfs1 = wbcs_elem->new_center_freq_seg1;
	u32 cf0 = ieee80211_channel_to_frequency(ccfs0, chandef->chan->band);
	u32 cf1 = ieee80211_channel_to_frequency(ccfs1, chandef->chan->band);

	switch (wbcs_elem->new_channel_width) {
	case IEEE80211_VHT_CHANWIDTH_160MHZ:
		/* deprecated encoding */
		chandef->width = NL80211_CHAN_WIDTH_160;
		chandef->center_freq1 = cf0;
		break;
	case IEEE80211_VHT_CHANWIDTH_80P80MHZ:
		/* deprecated encoding */
		chandef->width = NL80211_CHAN_WIDTH_80P80;
		chandef->center_freq1 = cf0;
		chandef->center_freq2 = cf1;
		break;
	case IEEE80211_VHT_CHANWIDTH_80MHZ:
		chandef->width = NL80211_CHAN_WIDTH_80;
		chandef->center_freq1 = cf0;

		if (ccfs1) {
			u8 diff = abs(ccfs0 - ccfs1);

			if (diff == 8) {
				chandef->width = NL80211_CHAN_WIDTH_160;
				chandef->center_freq1 = cf1;
			} else if (diff > 8) {
				chandef->width = NL80211_CHAN_WIDTH_80P80;
				chandef->center_freq2 = cf1;
			}
		}
		break;
	case IEEE80211_VHT_CHANWIDTH_USE_HT:
	default:
		/* If the WBCS Element is present, new channel bandwidth is
		 * at least 40 MHz.
		 */
		chandef->width = NL80211_CHAN_WIDTH_40;
		chandef->center_freq1 = cf0;
		break;
	}

	return cfg80211_chandef_valid(chandef);
}

static void
validate_chandef_by_ht_vht_oper(struct ieee80211_sub_if_data *sdata,
				struct ieee80211_conn_settings *conn,
				u32 vht_cap_info,
				struct cfg80211_chan_def *chandef)
{
	u32 control_freq, center_freq1, center_freq2;
	enum nl80211_chan_width chan_width;
	struct ieee80211_ht_operation ht_oper;
	struct ieee80211_vht_operation vht_oper;

	if (conn->mode < IEEE80211_CONN_MODE_HT ||
	    conn->bw_limit < IEEE80211_CONN_BW_LIMIT_40) {
		chandef->chan = NULL;
		return;
	}

	control_freq = chandef->chan->center_freq;
	center_freq1 = chandef->center_freq1;
	center_freq2 = chandef->center_freq2;
	chan_width = chandef->width;

	ht_oper.primary_chan = ieee80211_frequency_to_channel(control_freq);
	if (control_freq != center_freq1)
		ht_oper.ht_param = control_freq > center_freq1 ?
			IEEE80211_HT_PARAM_CHA_SEC_BELOW :
			IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
	else
		ht_oper.ht_param = IEEE80211_HT_PARAM_CHA_SEC_NONE;

	ieee80211_chandef_ht_oper(&ht_oper, chandef);

	if (conn->mode < IEEE80211_CONN_MODE_VHT)
		return;

	vht_oper.center_freq_seg0_idx =
		ieee80211_frequency_to_channel(center_freq1);
	vht_oper.center_freq_seg1_idx = center_freq2 ?
		ieee80211_frequency_to_channel(center_freq2) : 0;

	switch (chan_width) {
	case NL80211_CHAN_WIDTH_320:
		WARN_ON(1);
		break;
	case NL80211_CHAN_WIDTH_160:
		vht_oper.chan_width = IEEE80211_VHT_CHANWIDTH_80MHZ;
		vht_oper.center_freq_seg1_idx = vht_oper.center_freq_seg0_idx;
		vht_oper.center_freq_seg0_idx +=
			control_freq < center_freq1 ? -8 : 8;
		break;
	case NL80211_CHAN_WIDTH_80P80:
		vht_oper.chan_width = IEEE80211_VHT_CHANWIDTH_80MHZ;
		break;
	case NL80211_CHAN_WIDTH_80:
		vht_oper.chan_width = IEEE80211_VHT_CHANWIDTH_80MHZ;
		break;
	default:
		vht_oper.chan_width = IEEE80211_VHT_CHANWIDTH_USE_HT;
		break;
	}

	ht_oper.operation_mode =
		le16_encode_bits(vht_oper.center_freq_seg1_idx,
				 IEEE80211_HT_OP_MODE_CCFS2_MASK);

	if (!ieee80211_chandef_vht_oper(&sdata->local->hw, vht_cap_info,
					&vht_oper, &ht_oper, chandef))
		chandef->chan = NULL;
}

static void
validate_chandef_by_6ghz_he_eht_oper(struct ieee80211_sub_if_data *sdata,
				     struct ieee80211_conn_settings *conn,
				     struct cfg80211_chan_def *chandef)
{
	struct ieee80211_local *local = sdata->local;
	u32 control_freq, center_freq1, center_freq2;
	enum nl80211_chan_width chan_width;
	DEFINE_RAW_FLEX(struct ieee80211_he_operation, he, optional,
			sizeof(struct ieee80211_he_6ghz_oper));
	struct ieee80211_he_6ghz_oper *_6ghz_oper =
				(struct ieee80211_he_6ghz_oper *)he->optional;
	DEFINE_RAW_FLEX(struct ieee80211_eht_operation, eht, optional,
			sizeof(struct ieee80211_eht_operation_info));
	struct ieee80211_eht_operation_info *_oper_info =
			(struct ieee80211_eht_operation_info *)eht->optional;
	const struct ieee80211_eht_operation *eht_oper;

	if (conn->mode < IEEE80211_CONN_MODE_HE) {
		chandef->chan = NULL;
		return;
	}

	control_freq = chandef->chan->center_freq;
	center_freq1 = chandef->center_freq1;
	center_freq2 = chandef->center_freq2;
	chan_width = chandef->width;

	he->he_oper_params =
		le32_encode_bits(1, IEEE80211_HE_OPERATION_6GHZ_OP_INFO);
	_6ghz_oper->primary =
		ieee80211_frequency_to_channel(control_freq);
	_6ghz_oper->ccfs0 = ieee80211_frequency_to_channel(center_freq1);
	_6ghz_oper->ccfs1 = center_freq2 ?
		ieee80211_frequency_to_channel(center_freq2) : 0;

	switch (chan_width) {
	case NL80211_CHAN_WIDTH_320:
		_6ghz_oper->ccfs1 = _6ghz_oper->ccfs0;
		_6ghz_oper->ccfs0 += control_freq < center_freq1 ? -16 : 16;
		_6ghz_oper->control = IEEE80211_EHT_OPER_CHAN_WIDTH_320MHZ;
		break;
	case NL80211_CHAN_WIDTH_160:
		_6ghz_oper->ccfs1 = _6ghz_oper->ccfs0;
		_6ghz_oper->ccfs0 += control_freq < center_freq1 ? -8 : 8;
		fallthrough;
	case NL80211_CHAN_WIDTH_80P80:
		_6ghz_oper->control =
			IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_160MHZ;
		break;
	case NL80211_CHAN_WIDTH_80:
		_6ghz_oper->control =
			IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_80MHZ;
		break;
	case NL80211_CHAN_WIDTH_40:
		_6ghz_oper->control =
			IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_40MHZ;
		break;
	default:
		_6ghz_oper->control =
			IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_20MHZ;
		break;
	}

	if (conn->mode < IEEE80211_CONN_MODE_EHT) {
		eht_oper = NULL;
	} else {
		eht->params = IEEE80211_EHT_OPER_INFO_PRESENT;
		_oper_info->control = _6ghz_oper->control;
		_oper_info->ccfs0 = _6ghz_oper->ccfs0;
		_oper_info->ccfs1 = _6ghz_oper->ccfs1;
		eht_oper = eht;
	}

	if (!ieee80211_chandef_he_6ghz_oper(local, he, eht_oper, chandef))
		chandef->chan = NULL;
}

int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata,
				 struct ieee802_11_elems *elems,
				 enum nl80211_band current_band,
				 u32 vht_cap_info,
				 struct ieee80211_conn_settings *conn,
				 u8 *bssid, bool unprot_action,
				 struct ieee80211_csa_ie *csa_ie)
{
	enum nl80211_band new_band = current_band;
	int new_freq;
	u8 new_chan_no = 0, new_op_class = 0;
	struct ieee80211_channel *new_chan;
	struct cfg80211_chan_def new_chandef = {};
	const struct ieee80211_sec_chan_offs_ie *sec_chan_offs;
	const struct ieee80211_wide_bw_chansw_ie *wide_bw_chansw_ie;
	const struct ieee80211_bandwidth_indication *bwi;
	const struct ieee80211_ext_chansw_ie *ext_chansw_elem;
	int secondary_channel_offset = -1;

	memset(csa_ie, 0, sizeof(*csa_ie));

	sec_chan_offs = elems->sec_chan_offs;
	wide_bw_chansw_ie = elems->wide_bw_chansw_ie;
	bwi = elems->bandwidth_indication;
	ext_chansw_elem = elems->ext_chansw_ie;

	if (conn->mode < IEEE80211_CONN_MODE_HT ||
	    conn->bw_limit < IEEE80211_CONN_BW_LIMIT_40) {
		sec_chan_offs = NULL;
		wide_bw_chansw_ie = NULL;
	}

	if (conn->mode < IEEE80211_CONN_MODE_VHT)
		wide_bw_chansw_ie = NULL;

	if (ext_chansw_elem) {
		new_op_class = ext_chansw_elem->new_operating_class;

		if (!ieee80211_operating_class_to_band(new_op_class, &new_band)) {
			new_op_class = 0;
			if (!unprot_action)
				sdata_info(sdata,
					   "cannot understand ECSA IE operating class, %d, ignoring\n",
					   ext_chansw_elem->new_operating_class);
		} else {
			new_chan_no = ext_chansw_elem->new_ch_num;
			csa_ie->count = ext_chansw_elem->count;
			csa_ie->mode = ext_chansw_elem->mode;
		}
	}

	if (!new_op_class && elems->ch_switch_ie) {
		new_chan_no = elems->ch_switch_ie->new_ch_num;
		csa_ie->count = elems->ch_switch_ie->count;
		csa_ie->mode = elems->ch_switch_ie->mode;
	}

	/* nothing here we understand */
	if (!new_chan_no)
		return 1;

	/* Mesh Channel Switch Parameters Element */
	if (elems->mesh_chansw_params_ie) {
		csa_ie->ttl = elems->mesh_chansw_params_ie->mesh_ttl;
		csa_ie->mode = elems->mesh_chansw_params_ie->mesh_flags;
		csa_ie->pre_value = le16_to_cpu(
				elems->mesh_chansw_params_ie->mesh_pre_value);

		if (elems->mesh_chansw_params_ie->mesh_flags &
				WLAN_EID_CHAN_SWITCH_PARAM_REASON)
			csa_ie->reason_code = le16_to_cpu(
				elems->mesh_chansw_params_ie->mesh_reason);
	}

	new_freq = ieee80211_channel_to_frequency(new_chan_no, new_band);
	new_chan = ieee80211_get_channel(sdata->local->hw.wiphy, new_freq);
	if (!new_chan || new_chan->flags & IEEE80211_CHAN_DISABLED) {
		if (!unprot_action)
			sdata_info(sdata,
				   "BSS %pM switches to unsupported channel (%d MHz), disconnecting\n",
				   bssid, new_freq);
		return -EINVAL;
	}

	if (sec_chan_offs) {
		secondary_channel_offset = sec_chan_offs->sec_chan_offs;
	} else if (conn->mode >= IEEE80211_CONN_MODE_HT) {
		/* If the secondary channel offset IE is not present,
		 * we can't know what's the post-CSA offset, so the
		 * best we can do is use 20MHz.
		*/
		secondary_channel_offset = IEEE80211_HT_PARAM_CHA_SEC_NONE;
	}

	switch (secondary_channel_offset) {
	default:
		/* secondary_channel_offset was present but is invalid */
	case IEEE80211_HT_PARAM_CHA_SEC_NONE:
		cfg80211_chandef_create(&csa_ie->chanreq.oper, new_chan,
					NL80211_CHAN_HT20);
		break;
	case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
		cfg80211_chandef_create(&csa_ie->chanreq.oper, new_chan,
					NL80211_CHAN_HT40PLUS);
		break;
	case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
		cfg80211_chandef_create(&csa_ie->chanreq.oper, new_chan,
					NL80211_CHAN_HT40MINUS);
		break;
	case -1:
		cfg80211_chandef_create(&csa_ie->chanreq.oper, new_chan,
					NL80211_CHAN_NO_HT);
		break;
	}

	/* capture the AP configuration */
	csa_ie->chanreq.ap = csa_ie->chanreq.oper;

	/* parse one of the Elements to build a new chandef */
	memset(&new_chandef, 0, sizeof(new_chandef));
	new_chandef.chan = new_chan;
	if (bwi) {
		/* start with the CSA one */
		new_chandef = csa_ie->chanreq.oper;
		/* and update the width accordingly */
		ieee80211_chandef_eht_oper(&bwi->info, &new_chandef);

		if (bwi->params & IEEE80211_BW_IND_DIS_SUBCH_PRESENT)
			new_chandef.punctured =
				get_unaligned_le16(bwi->info.optional);
	} else if (!wide_bw_chansw_ie || !wbcs_elem_to_chandef(wide_bw_chansw_ie,
							       &new_chandef)) {
		if (!ieee80211_operating_class_to_chandef(new_op_class, new_chan,
							  &new_chandef))
			new_chandef = csa_ie->chanreq.oper;
	}

	/* check if the new chandef fits the capabilities */
	if (new_band == NL80211_BAND_6GHZ)
		validate_chandef_by_6ghz_he_eht_oper(sdata, conn, &new_chandef);
	else
		validate_chandef_by_ht_vht_oper(sdata, conn, vht_cap_info,
						&new_chandef);

	/* if data is there validate the bandwidth & use it */
	if (new_chandef.chan) {
		/* capture the AP chandef before (potential) downgrading */
		csa_ie->chanreq.ap = new_chandef;

		while (conn->bw_limit <
			       ieee80211_min_bw_limit_from_chandef(&new_chandef))
			ieee80211_chandef_downgrade(&new_chandef, NULL);

		if (!cfg80211_chandef_compatible(&new_chandef,
						 &csa_ie->chanreq.oper)) {
			sdata_info(sdata,
				   "BSS %pM: CSA has inconsistent channel data, disconnecting\n",
				   bssid);
			return -EINVAL;
		}

		csa_ie->chanreq.oper = new_chandef;
	}

	if (elems->max_channel_switch_time)
		csa_ie->max_switch_time =
			(elems->max_channel_switch_time[0] << 0) |
			(elems->max_channel_switch_time[1] <<  8) |
			(elems->max_channel_switch_time[2] << 16);

	return 0;
}

static void ieee80211_send_refuse_measurement_request(struct ieee80211_sub_if_data *sdata,
					struct ieee80211_msrment_ie *request_ie,
					const u8 *da, const u8 *bssid,
					u8 dialog_token)
{
	struct ieee80211_local *local = sdata->local;
	struct sk_buff *skb;
	struct ieee80211_mgmt *msr_report;

	skb = dev_alloc_skb(IEEE80211_MIN_ACTION_SIZE(measurement) +
			    local->hw.extra_tx_headroom);
	if (!skb)
		return;

	skb_reserve(skb, local->hw.extra_tx_headroom);
	msr_report = skb_put_zero(skb, IEEE80211_MIN_ACTION_SIZE(measurement));
	memcpy(msr_report->da, da, ETH_ALEN);
	memcpy(msr_report->sa, sdata->vif.addr, ETH_ALEN);
	memcpy(msr_report->bssid, bssid, ETH_ALEN);
	msr_report->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
						IEEE80211_STYPE_ACTION);

	msr_report->u.action.category = WLAN_CATEGORY_SPECTRUM_MGMT;
	msr_report->u.action.action_code = WLAN_ACTION_SPCT_MSR_RPRT;

	msr_report->u.action.measurement.dialog_token = dialog_token;
	msr_report->u.action.measurement.element_id = WLAN_EID_MEASURE_REPORT;
	msr_report->u.action.measurement.length =
			sizeof(struct ieee80211_msrment_ie);
	msr_report->u.action.measurement.msr_elem.token = request_ie->token;
	msr_report->u.action.measurement.msr_elem.mode |=
			IEEE80211_SPCT_MSR_RPRT_MODE_REFUSED;
	msr_report->u.action.measurement.msr_elem.type = request_ie->type;

	ieee80211_tx_skb(sdata, skb);
}

void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata,
				       struct ieee80211_mgmt *mgmt,
				       size_t len)
{
	/*
	 * Ignoring measurement request is spec violation.
	 * Mandatory measurements must be reported optional
	 * measurements might be refused or reported incapable
	 * For now just refuse
	 * TODO: Answer basic measurement as unmeasured
	 */
	ieee80211_send_refuse_measurement_request(sdata,
			&mgmt->u.action.measurement.msr_elem,
			mgmt->sa, mgmt->bssid,
			mgmt->u.action.measurement.dialog_token);
}
