// 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-2023 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((int)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;
	struct {
		struct ieee80211_he_operation _oper;
		struct ieee80211_he_6ghz_oper _6ghz_oper;
	} __packed he;
	struct {
		struct ieee80211_eht_operation _oper;
		struct ieee80211_eht_operation_info _oper_info;
	} __packed eht;

	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._oper.he_oper_params =
		le32_encode_bits(1, IEEE80211_HE_OPERATION_6GHZ_OP_INFO);
	he._6ghz_oper.primary =
		ieee80211_frequency_to_channel(control_freq);
	he._6ghz_oper.ccfs0 = ieee80211_frequency_to_channel(center_freq1);
	he._6ghz_oper.ccfs1 = center_freq2 ?
		ieee80211_frequency_to_channel(center_freq2) : 0;

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

	if (conn->mode < IEEE80211_CONN_MODE_EHT) {
		if (!ieee80211_chandef_he_6ghz_oper(local, &he._oper,
						    NULL, chandef))
			chandef->chan = NULL;
	} else {
		eht._oper.params = IEEE80211_EHT_OPER_INFO_PRESENT;
		eht._oper_info.control = he._6ghz_oper.control;
		eht._oper_info.ccfs0 = he._6ghz_oper.ccfs0;
		eht._oper_info.ccfs1 = he._6ghz_oper.ccfs1;

		if (!ieee80211_chandef_he_6ghz_oper(local, &he._oper,
						    &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,
				 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;
			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) {
		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);
		/* keep width for 5/10 MHz channels */
		switch (sdata->vif.bss_conf.chanreq.oper.width) {
		case NL80211_CHAN_WIDTH_5:
		case NL80211_CHAN_WIDTH_10:
			csa_ie->chanreq.oper.width =
				sdata->vif.bss_conf.chanreq.oper.width;
			break;
		default:
			break;
		}
		break;
	}

	/* 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);
	} 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) {
		if (conn->bw_limit < IEEE80211_CONN_BW_LIMIT_320 &&
		    new_chandef.width == NL80211_CHAN_WIDTH_320)
			ieee80211_chandef_downgrade(&new_chandef, NULL);

		if (conn->bw_limit < IEEE80211_CONN_BW_LIMIT_160 &&
		    (new_chandef.width == NL80211_CHAN_WIDTH_80P80 ||
		     new_chandef.width == NL80211_CHAN_WIDTH_160))
			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(sizeof(*msr_report) + local->hw.extra_tx_headroom +
				sizeof(struct ieee80211_msrment_ie));
	if (!skb)
		return;

	skb_reserve(skb, local->hw.extra_tx_headroom);
	msr_report = skb_put_zero(skb, 24);
	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);

	skb_put(skb, 1 + sizeof(msr_report->u.action.u.measurement));
	msr_report->u.action.category = WLAN_CATEGORY_SPECTRUM_MGMT;
	msr_report->u.action.u.measurement.action_code =
				WLAN_ACTION_SPCT_MSR_RPRT;
	msr_report->u.action.u.measurement.dialog_token = dialog_token;

	msr_report->u.action.u.measurement.element_id = WLAN_EID_MEASURE_REPORT;
	msr_report->u.action.u.measurement.length =
			sizeof(struct ieee80211_msrment_ie);

	memset(&msr_report->u.action.u.measurement.msr_elem, 0,
		sizeof(struct ieee80211_msrment_ie));
	msr_report->u.action.u.measurement.msr_elem.token = request_ie->token;
	msr_report->u.action.u.measurement.msr_elem.mode |=
			IEEE80211_SPCT_MSR_RPRT_MODE_REFUSED;
	msr_report->u.action.u.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.u.measurement.msr_elem,
			mgmt->sa, mgmt->bssid,
			mgmt->u.action.u.measurement.dialog_token);
}
