brintos

brintos / linux-shallow public Read only

0
0
Text · 113.4 KiB · 6c445a9 Raw
4561 lines · c
1// SPDX-License-Identifier: ISC2/*3 * Copyright (C) 2022 MediaTek Inc.4 */5 6#include <linux/firmware.h>7#include <linux/fs.h>8#include "mt7996.h"9#include "mcu.h"10#include "mac.h"11#include "eeprom.h"12 13#define fw_name(_dev, name, ...)	({			\14	char *_fw;						\15	switch (mt76_chip(&(_dev)->mt76)) {			\16	case 0x7992:						\17		_fw = MT7992_##name;				\18		break;						\19	case 0x7990:						\20	default:						\21		_fw = MT7996_##name;				\22		break;						\23	}							\24	_fw;							\25})26 27struct mt7996_patch_hdr {28	char build_date[16];29	char platform[4];30	__be32 hw_sw_ver;31	__be32 patch_ver;32	__be16 checksum;33	u16 reserved;34	struct {35		__be32 patch_ver;36		__be32 subsys;37		__be32 feature;38		__be32 n_region;39		__be32 crc;40		u32 reserved[11];41	} desc;42} __packed;43 44struct mt7996_patch_sec {45	__be32 type;46	__be32 offs;47	__be32 size;48	union {49		__be32 spec[13];50		struct {51			__be32 addr;52			__be32 len;53			__be32 sec_key_idx;54			__be32 align_len;55			u32 reserved[9];56		} info;57	};58} __packed;59 60struct mt7996_fw_trailer {61	u8 chip_id;62	u8 eco_code;63	u8 n_region;64	u8 format_ver;65	u8 format_flag;66	u8 reserved[2];67	char fw_ver[10];68	char build_date[15];69	u32 crc;70} __packed;71 72struct mt7996_fw_region {73	__le32 decomp_crc;74	__le32 decomp_len;75	__le32 decomp_blk_sz;76	u8 reserved[4];77	__le32 addr;78	__le32 len;79	u8 feature_set;80	u8 reserved1[15];81} __packed;82 83#define MCU_PATCH_ADDRESS		0x20000084 85#define HE_PHY(p, c)			u8_get_bits(c, IEEE80211_HE_PHY_##p)86#define HE_MAC(m, c)			u8_get_bits(c, IEEE80211_HE_MAC_##m)87#define EHT_PHY(p, c)			u8_get_bits(c, IEEE80211_EHT_PHY_##p)88 89static bool sr_scene_detect = true;90module_param(sr_scene_detect, bool, 0644);91MODULE_PARM_DESC(sr_scene_detect, "Enable firmware scene detection algorithm");92 93static u894mt7996_mcu_get_sta_nss(u16 mcs_map)95{96	u8 nss;97 98	for (nss = 8; nss > 0; nss--) {99		u8 nss_mcs = (mcs_map >> (2 * (nss - 1))) & 3;100 101		if (nss_mcs != IEEE80211_VHT_MCS_NOT_SUPPORTED)102			break;103	}104 105	return nss - 1;106}107 108static void109mt7996_mcu_set_sta_he_mcs(struct ieee80211_sta *sta, __le16 *he_mcs,110			  u16 mcs_map)111{112	struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv;113	enum nl80211_band band = msta->vif->phy->mt76->chandef.chan->band;114	const u16 *mask = msta->vif->bitrate_mask.control[band].he_mcs;115	int nss, max_nss = sta->deflink.rx_nss > 3 ? 4 : sta->deflink.rx_nss;116 117	for (nss = 0; nss < max_nss; nss++) {118		int mcs;119 120		switch ((mcs_map >> (2 * nss)) & 0x3) {121		case IEEE80211_HE_MCS_SUPPORT_0_11:122			mcs = GENMASK(11, 0);123			break;124		case IEEE80211_HE_MCS_SUPPORT_0_9:125			mcs = GENMASK(9, 0);126			break;127		case IEEE80211_HE_MCS_SUPPORT_0_7:128			mcs = GENMASK(7, 0);129			break;130		default:131			mcs = 0;132		}133 134		mcs = mcs ? fls(mcs & mask[nss]) - 1 : -1;135 136		switch (mcs) {137		case 0 ... 7:138			mcs = IEEE80211_HE_MCS_SUPPORT_0_7;139			break;140		case 8 ... 9:141			mcs = IEEE80211_HE_MCS_SUPPORT_0_9;142			break;143		case 10 ... 11:144			mcs = IEEE80211_HE_MCS_SUPPORT_0_11;145			break;146		default:147			mcs = IEEE80211_HE_MCS_NOT_SUPPORTED;148			break;149		}150		mcs_map &= ~(0x3 << (nss * 2));151		mcs_map |= mcs << (nss * 2);152	}153 154	*he_mcs = cpu_to_le16(mcs_map);155}156 157static void158mt7996_mcu_set_sta_vht_mcs(struct ieee80211_sta *sta, __le16 *vht_mcs,159			   const u16 *mask)160{161	u16 mcs, mcs_map = le16_to_cpu(sta->deflink.vht_cap.vht_mcs.rx_mcs_map);162	int nss, max_nss = sta->deflink.rx_nss > 3 ? 4 : sta->deflink.rx_nss;163 164	for (nss = 0; nss < max_nss; nss++, mcs_map >>= 2) {165		switch (mcs_map & 0x3) {166		case IEEE80211_VHT_MCS_SUPPORT_0_9:167			mcs = GENMASK(9, 0);168			break;169		case IEEE80211_VHT_MCS_SUPPORT_0_8:170			mcs = GENMASK(8, 0);171			break;172		case IEEE80211_VHT_MCS_SUPPORT_0_7:173			mcs = GENMASK(7, 0);174			break;175		default:176			mcs = 0;177		}178 179		vht_mcs[nss] = cpu_to_le16(mcs & mask[nss]);180	}181}182 183static void184mt7996_mcu_set_sta_ht_mcs(struct ieee80211_sta *sta, u8 *ht_mcs,185			  const u8 *mask)186{187	int nss, max_nss = sta->deflink.rx_nss > 3 ? 4 : sta->deflink.rx_nss;188 189	for (nss = 0; nss < max_nss; nss++)190		ht_mcs[nss] = sta->deflink.ht_cap.mcs.rx_mask[nss] & mask[nss];191}192 193static int194mt7996_mcu_parse_response(struct mt76_dev *mdev, int cmd,195			  struct sk_buff *skb, int seq)196{197	struct mt7996_mcu_rxd *rxd;198	struct mt7996_mcu_uni_event *event;199	int mcu_cmd = FIELD_GET(__MCU_CMD_FIELD_ID, cmd);200	int ret = 0;201 202	if (!skb) {203		dev_err(mdev->dev, "Message %08x (seq %d) timeout\n",204			cmd, seq);205		return -ETIMEDOUT;206	}207 208	rxd = (struct mt7996_mcu_rxd *)skb->data;209	if (seq != rxd->seq)210		return -EAGAIN;211 212	if (cmd == MCU_CMD(PATCH_SEM_CONTROL)) {213		skb_pull(skb, sizeof(*rxd) - 4);214		ret = *skb->data;215	} else if ((rxd->option & MCU_UNI_CMD_EVENT) &&216		    rxd->eid == MCU_UNI_EVENT_RESULT) {217		skb_pull(skb, sizeof(*rxd));218		event = (struct mt7996_mcu_uni_event *)skb->data;219		ret = le32_to_cpu(event->status);220		/* skip invalid event */221		if (mcu_cmd != event->cid)222			ret = -EAGAIN;223	} else {224		skb_pull(skb, sizeof(struct mt7996_mcu_rxd));225	}226 227	return ret;228}229 230static int231mt7996_mcu_send_message(struct mt76_dev *mdev, struct sk_buff *skb,232			int cmd, int *wait_seq)233{234	struct mt7996_dev *dev = container_of(mdev, struct mt7996_dev, mt76);235	int txd_len, mcu_cmd = FIELD_GET(__MCU_CMD_FIELD_ID, cmd);236	struct mt76_connac2_mcu_uni_txd *uni_txd;237	struct mt76_connac2_mcu_txd *mcu_txd;238	enum mt76_mcuq_id qid;239	__le32 *txd;240	u32 val;241	u8 seq;242 243	mdev->mcu.timeout = 20 * HZ;244 245	seq = ++dev->mt76.mcu.msg_seq & 0xf;246	if (!seq)247		seq = ++dev->mt76.mcu.msg_seq & 0xf;248 249	if (cmd == MCU_CMD(FW_SCATTER)) {250		qid = MT_MCUQ_FWDL;251		goto exit;252	}253 254	txd_len = cmd & __MCU_CMD_FIELD_UNI ? sizeof(*uni_txd) : sizeof(*mcu_txd);255	txd = (__le32 *)skb_push(skb, txd_len);256	if (test_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state))257		qid = MT_MCUQ_WA;258	else259		qid = MT_MCUQ_WM;260 261	val = FIELD_PREP(MT_TXD0_TX_BYTES, skb->len) |262	      FIELD_PREP(MT_TXD0_PKT_FMT, MT_TX_TYPE_CMD) |263	      FIELD_PREP(MT_TXD0_Q_IDX, MT_TX_MCU_PORT_RX_Q0);264	txd[0] = cpu_to_le32(val);265 266	val = FIELD_PREP(MT_TXD1_HDR_FORMAT, MT_HDR_FORMAT_CMD);267	txd[1] = cpu_to_le32(val);268 269	if (cmd & __MCU_CMD_FIELD_UNI) {270		uni_txd = (struct mt76_connac2_mcu_uni_txd *)txd;271		uni_txd->len = cpu_to_le16(skb->len - sizeof(uni_txd->txd));272		uni_txd->cid = cpu_to_le16(mcu_cmd);273		uni_txd->s2d_index = MCU_S2D_H2CN;274		uni_txd->pkt_type = MCU_PKT_ID;275		uni_txd->seq = seq;276 277		if (cmd & __MCU_CMD_FIELD_QUERY)278			uni_txd->option = MCU_CMD_UNI_QUERY_ACK;279		else280			uni_txd->option = MCU_CMD_UNI_EXT_ACK;281 282		if ((cmd & __MCU_CMD_FIELD_WA) && (cmd & __MCU_CMD_FIELD_WM))283			uni_txd->s2d_index = MCU_S2D_H2CN;284		else if (cmd & __MCU_CMD_FIELD_WA)285			uni_txd->s2d_index = MCU_S2D_H2C;286		else if (cmd & __MCU_CMD_FIELD_WM)287			uni_txd->s2d_index = MCU_S2D_H2N;288 289		goto exit;290	}291 292	mcu_txd = (struct mt76_connac2_mcu_txd *)txd;293	mcu_txd->len = cpu_to_le16(skb->len - sizeof(mcu_txd->txd));294	mcu_txd->pq_id = cpu_to_le16(MCU_PQ_ID(MT_TX_PORT_IDX_MCU,295					       MT_TX_MCU_PORT_RX_Q0));296	mcu_txd->pkt_type = MCU_PKT_ID;297	mcu_txd->seq = seq;298 299	mcu_txd->cid = FIELD_GET(__MCU_CMD_FIELD_ID, cmd);300	mcu_txd->set_query = MCU_Q_NA;301	mcu_txd->ext_cid = FIELD_GET(__MCU_CMD_FIELD_EXT_ID, cmd);302	if (mcu_txd->ext_cid) {303		mcu_txd->ext_cid_ack = 1;304 305		if (cmd & __MCU_CMD_FIELD_QUERY)306			mcu_txd->set_query = MCU_Q_QUERY;307		else308			mcu_txd->set_query = MCU_Q_SET;309	}310 311	if (cmd & __MCU_CMD_FIELD_WA)312		mcu_txd->s2d_index = MCU_S2D_H2C;313	else314		mcu_txd->s2d_index = MCU_S2D_H2N;315 316exit:317	if (wait_seq)318		*wait_seq = seq;319 320	return mt76_tx_queue_skb_raw(dev, mdev->q_mcu[qid], skb, 0);321}322 323int mt7996_mcu_wa_cmd(struct mt7996_dev *dev, int cmd, u32 a1, u32 a2, u32 a3)324{325	struct {326		__le32 args[3];327	} req = {328		.args = {329			cpu_to_le32(a1),330			cpu_to_le32(a2),331			cpu_to_le32(a3),332		},333	};334 335	return mt76_mcu_send_msg(&dev->mt76, cmd, &req, sizeof(req), false);336}337 338static void339mt7996_mcu_csa_finish(void *priv, u8 *mac, struct ieee80211_vif *vif)340{341	if (!vif->bss_conf.csa_active || vif->type == NL80211_IFTYPE_STATION)342		return;343 344	ieee80211_csa_finish(vif, 0);345}346 347static void348mt7996_mcu_rx_radar_detected(struct mt7996_dev *dev, struct sk_buff *skb)349{350	struct mt76_phy *mphy = &dev->mt76.phy;351	struct mt7996_mcu_rdd_report *r;352 353	r = (struct mt7996_mcu_rdd_report *)skb->data;354 355	if (r->band_idx >= ARRAY_SIZE(dev->mt76.phys))356		return;357 358	if (r->band_idx == MT_RX_SEL2 && !dev->rdd2_phy)359		return;360 361	if (r->band_idx == MT_RX_SEL2)362		mphy = dev->rdd2_phy->mt76;363	else364		mphy = dev->mt76.phys[r->band_idx];365 366	if (!mphy)367		return;368 369	if (r->band_idx == MT_RX_SEL2)370		cfg80211_background_radar_event(mphy->hw->wiphy,371						&dev->rdd2_chandef,372						GFP_ATOMIC);373	else374		ieee80211_radar_detected(mphy->hw, NULL);375	dev->hw_pattern++;376}377 378static void379mt7996_mcu_rx_log_message(struct mt7996_dev *dev, struct sk_buff *skb)380{381#define UNI_EVENT_FW_LOG_FORMAT 0382	struct mt7996_mcu_rxd *rxd = (struct mt7996_mcu_rxd *)skb->data;383	const char *data = (char *)&rxd[1] + 4, *type;384	struct tlv *tlv = (struct tlv *)data;385	int len;386 387	if (!(rxd->option & MCU_UNI_CMD_EVENT)) {388		len = skb->len - sizeof(*rxd);389		data = (char *)&rxd[1];390		goto out;391	}392 393	if (le16_to_cpu(tlv->tag) != UNI_EVENT_FW_LOG_FORMAT)394		return;395 396	data += sizeof(*tlv) + 4;397	len = le16_to_cpu(tlv->len) - sizeof(*tlv) - 4;398 399out:400	switch (rxd->s2d_index) {401	case 0:402		if (mt7996_debugfs_rx_log(dev, data, len))403			return;404 405		type = "WM";406		break;407	case 2:408		type = "WA";409		break;410	default:411		type = "unknown";412		break;413	}414 415	wiphy_info(mt76_hw(dev)->wiphy, "%s: %.*s", type, len, data);416}417 418static void419mt7996_mcu_cca_finish(void *priv, u8 *mac, struct ieee80211_vif *vif)420{421	if (!vif->bss_conf.color_change_active || vif->type == NL80211_IFTYPE_STATION)422		return;423 424	ieee80211_color_change_finish(vif, 0);425}426 427static void428mt7996_mcu_ie_countdown(struct mt7996_dev *dev, struct sk_buff *skb)429{430#define UNI_EVENT_IE_COUNTDOWN_CSA 0431#define UNI_EVENT_IE_COUNTDOWN_BCC 1432	struct header {433		u8 band;434		u8 rsv[3];435	};436	struct mt76_phy *mphy = &dev->mt76.phy;437	struct mt7996_mcu_rxd *rxd = (struct mt7996_mcu_rxd *)skb->data;438	const char *data = (char *)&rxd[1], *tail;439	struct header *hdr = (struct header *)data;440	struct tlv *tlv = (struct tlv *)(data + 4);441 442	if (hdr->band >= ARRAY_SIZE(dev->mt76.phys))443		return;444 445	if (hdr->band && dev->mt76.phys[hdr->band])446		mphy = dev->mt76.phys[hdr->band];447 448	tail = skb->data + skb->len;449	data += sizeof(struct header);450	while (data + sizeof(struct tlv) < tail && le16_to_cpu(tlv->len)) {451		switch (le16_to_cpu(tlv->tag)) {452		case UNI_EVENT_IE_COUNTDOWN_CSA:453			ieee80211_iterate_active_interfaces_atomic(mphy->hw,454					IEEE80211_IFACE_ITER_RESUME_ALL,455					mt7996_mcu_csa_finish, mphy->hw);456			break;457		case UNI_EVENT_IE_COUNTDOWN_BCC:458			ieee80211_iterate_active_interfaces_atomic(mphy->hw,459					IEEE80211_IFACE_ITER_RESUME_ALL,460					mt7996_mcu_cca_finish, mphy->hw);461			break;462		}463 464		data += le16_to_cpu(tlv->len);465		tlv = (struct tlv *)data;466	}467}468 469static int470mt7996_mcu_update_tx_gi(struct rate_info *rate, struct all_sta_trx_rate *mcu_rate)471{472	switch (mcu_rate->tx_mode) {473	case MT_PHY_TYPE_CCK:474	case MT_PHY_TYPE_OFDM:475		break;476	case MT_PHY_TYPE_HT:477	case MT_PHY_TYPE_HT_GF:478	case MT_PHY_TYPE_VHT:479		if (mcu_rate->tx_gi)480			rate->flags |= RATE_INFO_FLAGS_SHORT_GI;481		else482			rate->flags &= ~RATE_INFO_FLAGS_SHORT_GI;483		break;484	case MT_PHY_TYPE_HE_SU:485	case MT_PHY_TYPE_HE_EXT_SU:486	case MT_PHY_TYPE_HE_TB:487	case MT_PHY_TYPE_HE_MU:488		if (mcu_rate->tx_gi > NL80211_RATE_INFO_HE_GI_3_2)489			return -EINVAL;490		rate->he_gi = mcu_rate->tx_gi;491		break;492	case MT_PHY_TYPE_EHT_SU:493	case MT_PHY_TYPE_EHT_TRIG:494	case MT_PHY_TYPE_EHT_MU:495		if (mcu_rate->tx_gi > NL80211_RATE_INFO_EHT_GI_3_2)496			return -EINVAL;497		rate->eht_gi = mcu_rate->tx_gi;498		break;499	default:500		return -EINVAL;501	}502 503	return 0;504}505 506static void507mt7996_mcu_rx_all_sta_info_event(struct mt7996_dev *dev, struct sk_buff *skb)508{509	struct mt7996_mcu_all_sta_info_event *res;510	u16 i;511 512	skb_pull(skb, sizeof(struct mt7996_mcu_rxd));513 514	res = (struct mt7996_mcu_all_sta_info_event *)skb->data;515 516	for (i = 0; i < le16_to_cpu(res->sta_num); i++) {517		u8 ac;518		u16 wlan_idx;519		struct mt76_wcid *wcid;520 521		switch (le16_to_cpu(res->tag)) {522		case UNI_ALL_STA_TXRX_RATE:523			wlan_idx = le16_to_cpu(res->rate[i].wlan_idx);524			wcid = rcu_dereference(dev->mt76.wcid[wlan_idx]);525 526			if (!wcid)527				break;528 529			if (mt7996_mcu_update_tx_gi(&wcid->rate, &res->rate[i]))530				dev_err(dev->mt76.dev, "Failed to update TX GI\n");531			break;532		case UNI_ALL_STA_TXRX_ADM_STAT:533			wlan_idx = le16_to_cpu(res->adm_stat[i].wlan_idx);534			wcid = rcu_dereference(dev->mt76.wcid[wlan_idx]);535 536			if (!wcid)537				break;538 539			for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {540				wcid->stats.tx_bytes +=541					le32_to_cpu(res->adm_stat[i].tx_bytes[ac]);542				wcid->stats.rx_bytes +=543					le32_to_cpu(res->adm_stat[i].rx_bytes[ac]);544			}545			break;546		case UNI_ALL_STA_TXRX_MSDU_COUNT:547			wlan_idx = le16_to_cpu(res->msdu_cnt[i].wlan_idx);548			wcid = rcu_dereference(dev->mt76.wcid[wlan_idx]);549 550			if (!wcid)551				break;552 553			wcid->stats.tx_packets +=554				le32_to_cpu(res->msdu_cnt[i].tx_msdu_cnt);555			wcid->stats.rx_packets +=556				le32_to_cpu(res->msdu_cnt[i].rx_msdu_cnt);557			break;558		default:559			break;560		}561	}562}563 564static void565mt7996_mcu_rx_thermal_notify(struct mt7996_dev *dev, struct sk_buff *skb)566{567#define THERMAL_NOTIFY_TAG 0x4568#define THERMAL_NOTIFY 0x2569	struct mt76_phy *mphy = &dev->mt76.phy;570	struct mt7996_mcu_thermal_notify *n;571	struct mt7996_phy *phy;572 573	n = (struct mt7996_mcu_thermal_notify *)skb->data;574 575	if (le16_to_cpu(n->tag) != THERMAL_NOTIFY_TAG)576		return;577 578	if (n->event_id != THERMAL_NOTIFY)579		return;580 581	if (n->band_idx > MT_BAND2)582		return;583 584	mphy = dev->mt76.phys[n->band_idx];585	if (!mphy)586		return;587 588	phy = (struct mt7996_phy *)mphy->priv;589	phy->throttle_state = n->duty_percent;590}591 592static void593mt7996_mcu_rx_ext_event(struct mt7996_dev *dev, struct sk_buff *skb)594{595	struct mt7996_mcu_rxd *rxd = (struct mt7996_mcu_rxd *)skb->data;596 597	switch (rxd->ext_eid) {598	case MCU_EXT_EVENT_FW_LOG_2_HOST:599		mt7996_mcu_rx_log_message(dev, skb);600		break;601	default:602		break;603	}604}605 606static void607mt7996_mcu_rx_unsolicited_event(struct mt7996_dev *dev, struct sk_buff *skb)608{609	struct mt7996_mcu_rxd *rxd = (struct mt7996_mcu_rxd *)skb->data;610 611	switch (rxd->eid) {612	case MCU_EVENT_EXT:613		mt7996_mcu_rx_ext_event(dev, skb);614		break;615	case MCU_UNI_EVENT_THERMAL:616		mt7996_mcu_rx_thermal_notify(dev, skb);617		break;618	default:619		break;620	}621	dev_kfree_skb(skb);622}623 624static void625mt7996_mcu_wed_rro_event(struct mt7996_dev *dev, struct sk_buff *skb)626{627	struct mt7996_mcu_wed_rro_event *event = (void *)skb->data;628 629	if (!dev->has_rro)630		return;631 632	skb_pull(skb, sizeof(struct mt7996_mcu_rxd) + 4);633 634	switch (le16_to_cpu(event->tag)) {635	case UNI_WED_RRO_BA_SESSION_STATUS: {636		struct mt7996_mcu_wed_rro_ba_event *e;637 638		while (skb->len >= sizeof(*e)) {639			struct mt76_rx_tid *tid;640			struct mt76_wcid *wcid;641			u16 idx;642 643			e = (void *)skb->data;644			idx = le16_to_cpu(e->wlan_id);645			if (idx >= ARRAY_SIZE(dev->mt76.wcid))646				break;647 648			wcid = rcu_dereference(dev->mt76.wcid[idx]);649			if (!wcid || !wcid->sta)650				break;651 652			if (e->tid >= ARRAY_SIZE(wcid->aggr))653				break;654 655			tid = rcu_dereference(wcid->aggr[e->tid]);656			if (!tid)657				break;658 659			tid->id = le16_to_cpu(e->id);660			skb_pull(skb, sizeof(*e));661		}662		break;663	}664	case UNI_WED_RRO_BA_SESSION_DELETE: {665		struct mt7996_mcu_wed_rro_ba_delete_event *e;666 667		while (skb->len >= sizeof(*e)) {668			struct mt7996_wed_rro_session_id *session;669 670			e = (void *)skb->data;671			session = kzalloc(sizeof(*session), GFP_ATOMIC);672			if (!session)673				break;674 675			session->id = le16_to_cpu(e->session_id);676 677			spin_lock_bh(&dev->wed_rro.lock);678			list_add_tail(&session->list, &dev->wed_rro.poll_list);679			spin_unlock_bh(&dev->wed_rro.lock);680 681			ieee80211_queue_work(mt76_hw(dev), &dev->wed_rro.work);682			skb_pull(skb, sizeof(*e));683		}684		break;685	}686	default:687		break;688	}689}690 691static void692mt7996_mcu_uni_rx_unsolicited_event(struct mt7996_dev *dev, struct sk_buff *skb)693{694	struct mt7996_mcu_rxd *rxd = (struct mt7996_mcu_rxd *)skb->data;695 696	switch (rxd->eid) {697	case MCU_UNI_EVENT_FW_LOG_2_HOST:698		mt7996_mcu_rx_log_message(dev, skb);699		break;700	case MCU_UNI_EVENT_IE_COUNTDOWN:701		mt7996_mcu_ie_countdown(dev, skb);702		break;703	case MCU_UNI_EVENT_RDD_REPORT:704		mt7996_mcu_rx_radar_detected(dev, skb);705		break;706	case MCU_UNI_EVENT_ALL_STA_INFO:707		mt7996_mcu_rx_all_sta_info_event(dev, skb);708		break;709	case MCU_UNI_EVENT_WED_RRO:710		mt7996_mcu_wed_rro_event(dev, skb);711		break;712	default:713		break;714	}715	dev_kfree_skb(skb);716}717 718void mt7996_mcu_rx_event(struct mt7996_dev *dev, struct sk_buff *skb)719{720	struct mt7996_mcu_rxd *rxd = (struct mt7996_mcu_rxd *)skb->data;721 722	if (rxd->option & MCU_UNI_CMD_UNSOLICITED_EVENT) {723		mt7996_mcu_uni_rx_unsolicited_event(dev, skb);724		return;725	}726 727	/* WA still uses legacy event*/728	if (rxd->ext_eid == MCU_EXT_EVENT_FW_LOG_2_HOST ||729	    !rxd->seq)730		mt7996_mcu_rx_unsolicited_event(dev, skb);731	else732		mt76_mcu_rx_event(&dev->mt76, skb);733}734 735static struct tlv *736mt7996_mcu_add_uni_tlv(struct sk_buff *skb, u16 tag, u16 len)737{738	struct tlv *ptlv = skb_put_zero(skb, len);739 740	ptlv->tag = cpu_to_le16(tag);741	ptlv->len = cpu_to_le16(len);742 743	return ptlv;744}745 746static void747mt7996_mcu_bss_rfch_tlv(struct sk_buff *skb, struct ieee80211_vif *vif,748			struct mt7996_phy *phy)749{750	static const u8 rlm_ch_band[] = {751		[NL80211_BAND_2GHZ] = 1,752		[NL80211_BAND_5GHZ] = 2,753		[NL80211_BAND_6GHZ] = 3,754	};755	struct cfg80211_chan_def *chandef = &phy->mt76->chandef;756	struct bss_rlm_tlv *ch;757	struct tlv *tlv;758	int freq1 = chandef->center_freq1;759 760	tlv = mt7996_mcu_add_uni_tlv(skb, UNI_BSS_INFO_RLM, sizeof(*ch));761 762	ch = (struct bss_rlm_tlv *)tlv;763	ch->control_channel = chandef->chan->hw_value;764	ch->center_chan = ieee80211_frequency_to_channel(freq1);765	ch->bw = mt76_connac_chan_bw(chandef);766	ch->tx_streams = hweight8(phy->mt76->antenna_mask);767	ch->rx_streams = hweight8(phy->mt76->antenna_mask);768	ch->band = rlm_ch_band[chandef->chan->band];769 770	if (chandef->width == NL80211_CHAN_WIDTH_80P80) {771		int freq2 = chandef->center_freq2;772 773		ch->center_chan2 = ieee80211_frequency_to_channel(freq2);774	}775}776 777static void778mt7996_mcu_bss_ra_tlv(struct sk_buff *skb, struct ieee80211_vif *vif,779		      struct mt7996_phy *phy)780{781	struct bss_ra_tlv *ra;782	struct tlv *tlv;783 784	tlv = mt7996_mcu_add_uni_tlv(skb, UNI_BSS_INFO_RA, sizeof(*ra));785 786	ra = (struct bss_ra_tlv *)tlv;787	ra->short_preamble = true;788}789 790static void791mt7996_mcu_bss_he_tlv(struct sk_buff *skb, struct ieee80211_vif *vif,792		      struct mt7996_phy *phy)793{794#define DEFAULT_HE_PE_DURATION		4795#define DEFAULT_HE_DURATION_RTS_THRES	1023796	const struct ieee80211_sta_he_cap *cap;797	struct bss_info_uni_he *he;798	struct tlv *tlv;799 800	cap = mt76_connac_get_he_phy_cap(phy->mt76, vif);801 802	tlv = mt7996_mcu_add_uni_tlv(skb, UNI_BSS_INFO_HE_BASIC, sizeof(*he));803 804	he = (struct bss_info_uni_he *)tlv;805	he->he_pe_duration = vif->bss_conf.htc_trig_based_pkt_ext;806	if (!he->he_pe_duration)807		he->he_pe_duration = DEFAULT_HE_PE_DURATION;808 809	he->he_rts_thres = cpu_to_le16(vif->bss_conf.frame_time_rts_th);810	if (!he->he_rts_thres)811		he->he_rts_thres = cpu_to_le16(DEFAULT_HE_DURATION_RTS_THRES);812 813	he->max_nss_mcs[CMD_HE_MCS_BW80] = cap->he_mcs_nss_supp.tx_mcs_80;814	he->max_nss_mcs[CMD_HE_MCS_BW160] = cap->he_mcs_nss_supp.tx_mcs_160;815	he->max_nss_mcs[CMD_HE_MCS_BW8080] = cap->he_mcs_nss_supp.tx_mcs_80p80;816}817 818static void819mt7996_mcu_bss_mbssid_tlv(struct sk_buff *skb, struct ieee80211_vif *vif,820			  struct mt7996_phy *phy, int enable)821{822	struct bss_info_uni_mbssid *mbssid;823	struct tlv *tlv;824 825	if (!vif->bss_conf.bssid_indicator && enable)826		return;827 828	tlv = mt7996_mcu_add_uni_tlv(skb, UNI_BSS_INFO_11V_MBSSID, sizeof(*mbssid));829 830	mbssid = (struct bss_info_uni_mbssid *)tlv;831 832	if (enable) {833		mbssid->max_indicator = vif->bss_conf.bssid_indicator;834		mbssid->mbss_idx = vif->bss_conf.bssid_index;835		mbssid->tx_bss_omac_idx = 0;836	}837}838 839static void840mt7996_mcu_bss_bmc_tlv(struct sk_buff *skb, struct ieee80211_vif *vif,841		       struct mt7996_phy *phy)842{843	struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;844	struct bss_rate_tlv *bmc;845	struct cfg80211_chan_def *chandef = &phy->mt76->chandef;846	enum nl80211_band band = chandef->chan->band;847	struct tlv *tlv;848	u8 idx = mvif->mcast_rates_idx ?849		 mvif->mcast_rates_idx : mvif->basic_rates_idx;850 851	tlv = mt7996_mcu_add_uni_tlv(skb, UNI_BSS_INFO_RATE, sizeof(*bmc));852 853	bmc = (struct bss_rate_tlv *)tlv;854 855	bmc->short_preamble = (band == NL80211_BAND_2GHZ);856	bmc->bc_fixed_rate = idx;857	bmc->mc_fixed_rate = idx;858}859 860static void861mt7996_mcu_bss_txcmd_tlv(struct sk_buff *skb, bool en)862{863	struct bss_txcmd_tlv *txcmd;864	struct tlv *tlv;865 866	tlv = mt7996_mcu_add_uni_tlv(skb, UNI_BSS_INFO_TXCMD, sizeof(*txcmd));867 868	txcmd = (struct bss_txcmd_tlv *)tlv;869	txcmd->txcmd_mode = en;870}871 872static void873mt7996_mcu_bss_mld_tlv(struct sk_buff *skb, struct ieee80211_vif *vif)874{875	struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;876	struct bss_mld_tlv *mld;877	struct tlv *tlv;878 879	tlv = mt7996_mcu_add_uni_tlv(skb, UNI_BSS_INFO_MLD, sizeof(*mld));880 881	mld = (struct bss_mld_tlv *)tlv;882	mld->group_mld_id = 0xff;883	mld->own_mld_id = mvif->mt76.idx;884	mld->remap_idx = 0xff;885}886 887static void888mt7996_mcu_bss_sec_tlv(struct sk_buff *skb, struct ieee80211_vif *vif)889{890	struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;891	struct bss_sec_tlv *sec;892	struct tlv *tlv;893 894	tlv = mt7996_mcu_add_uni_tlv(skb, UNI_BSS_INFO_SEC, sizeof(*sec));895 896	sec = (struct bss_sec_tlv *)tlv;897	sec->cipher = mvif->cipher;898}899 900static int901mt7996_mcu_muar_config(struct mt7996_phy *phy, struct ieee80211_vif *vif,902		       bool bssid, bool enable)903{904#define UNI_MUAR_ENTRY 2905	struct mt7996_dev *dev = phy->dev;906	struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;907	u32 idx = mvif->mt76.omac_idx - REPEATER_BSSID_START;908	const u8 *addr = vif->addr;909 910	struct {911		struct {912			u8 band;913			u8 __rsv[3];914		} hdr;915 916		__le16 tag;917		__le16 len;918 919		bool smesh;920		u8 bssid;921		u8 index;922		u8 entry_add;923		u8 addr[ETH_ALEN];924		u8 __rsv[2];925	} __packed req = {926		.hdr.band = phy->mt76->band_idx,927		.tag = cpu_to_le16(UNI_MUAR_ENTRY),928		.len = cpu_to_le16(sizeof(req) - sizeof(req.hdr)),929		.smesh = false,930		.index = idx * 2 + bssid,931		.entry_add = true,932	};933 934	if (bssid)935		addr = vif->bss_conf.bssid;936 937	if (enable)938		memcpy(req.addr, addr, ETH_ALEN);939 940	return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(REPT_MUAR), &req,941				 sizeof(req), true);942}943 944static void945mt7996_mcu_bss_ifs_timing_tlv(struct sk_buff *skb, struct ieee80211_vif *vif)946{947	struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;948	struct mt7996_phy *phy = mvif->phy;949	struct bss_ifs_time_tlv *ifs_time;950	struct tlv *tlv;951	bool is_2ghz = phy->mt76->chandef.chan->band == NL80211_BAND_2GHZ;952 953	tlv = mt7996_mcu_add_uni_tlv(skb, UNI_BSS_INFO_IFS_TIME, sizeof(*ifs_time));954 955	ifs_time = (struct bss_ifs_time_tlv *)tlv;956	ifs_time->slot_valid = true;957	ifs_time->sifs_valid = true;958	ifs_time->rifs_valid = true;959	ifs_time->eifs_valid = true;960 961	ifs_time->slot_time = cpu_to_le16(phy->slottime);962	ifs_time->sifs_time = cpu_to_le16(10);963	ifs_time->rifs_time = cpu_to_le16(2);964	ifs_time->eifs_time = cpu_to_le16(is_2ghz ? 78 : 84);965 966	if (is_2ghz) {967		ifs_time->eifs_cck_valid = true;968		ifs_time->eifs_cck_time = cpu_to_le16(314);969	}970}971 972static int973mt7996_mcu_bss_basic_tlv(struct sk_buff *skb,974			 struct ieee80211_vif *vif,975			 struct ieee80211_sta *sta,976			 struct mt76_phy *phy, u16 wlan_idx,977			 bool enable)978{979	struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;980	struct cfg80211_chan_def *chandef = &phy->chandef;981	struct mt76_connac_bss_basic_tlv *bss;982	u32 type = CONNECTION_INFRA_AP;983	u16 sta_wlan_idx = wlan_idx;984	struct tlv *tlv;985	int idx;986 987	switch (vif->type) {988	case NL80211_IFTYPE_MESH_POINT:989	case NL80211_IFTYPE_AP:990	case NL80211_IFTYPE_MONITOR:991		break;992	case NL80211_IFTYPE_STATION:993		if (enable) {994			rcu_read_lock();995			if (!sta)996				sta = ieee80211_find_sta(vif,997							 vif->bss_conf.bssid);998			/* TODO: enable BSS_INFO_UAPSD & BSS_INFO_PM */999			if (sta) {1000				struct mt76_wcid *wcid;1001 1002				wcid = (struct mt76_wcid *)sta->drv_priv;1003				sta_wlan_idx = wcid->idx;1004			}1005			rcu_read_unlock();1006		}1007		type = CONNECTION_INFRA_STA;1008		break;1009	case NL80211_IFTYPE_ADHOC:1010		type = CONNECTION_IBSS_ADHOC;1011		break;1012	default:1013		WARN_ON(1);1014		break;1015	}1016 1017	tlv = mt7996_mcu_add_uni_tlv(skb, UNI_BSS_INFO_BASIC, sizeof(*bss));1018 1019	bss = (struct mt76_connac_bss_basic_tlv *)tlv;1020	bss->bcn_interval = cpu_to_le16(vif->bss_conf.beacon_int);1021	bss->dtim_period = vif->bss_conf.dtim_period;1022	bss->bmc_tx_wlan_idx = cpu_to_le16(wlan_idx);1023	bss->sta_idx = cpu_to_le16(sta_wlan_idx);1024	bss->conn_type = cpu_to_le32(type);1025	bss->omac_idx = mvif->omac_idx;1026	bss->band_idx = mvif->band_idx;1027	bss->wmm_idx = mvif->wmm_idx;1028	bss->conn_state = !enable;1029	bss->active = enable;1030 1031	idx = mvif->omac_idx > EXT_BSSID_START ? HW_BSSID_0 : mvif->omac_idx;1032	bss->hw_bss_idx = idx;1033 1034	if (vif->type == NL80211_IFTYPE_MONITOR) {1035		memcpy(bss->bssid, phy->macaddr, ETH_ALEN);1036		return 0;1037	}1038 1039	memcpy(bss->bssid, vif->bss_conf.bssid, ETH_ALEN);1040	bss->bcn_interval = cpu_to_le16(vif->bss_conf.beacon_int);1041	bss->dtim_period = vif->bss_conf.dtim_period;1042	bss->phymode = mt76_connac_get_phy_mode(phy, vif,1043						chandef->chan->band, NULL);1044	bss->phymode_ext = mt76_connac_get_phy_mode_ext(phy, vif,1045							chandef->chan->band);1046 1047	return 0;1048}1049 1050static struct sk_buff *1051__mt7996_mcu_alloc_bss_req(struct mt76_dev *dev, struct mt76_vif *mvif, int len)1052{1053	struct bss_req_hdr hdr = {1054		.bss_idx = mvif->idx,1055	};1056	struct sk_buff *skb;1057 1058	skb = mt76_mcu_msg_alloc(dev, NULL, len);1059	if (!skb)1060		return ERR_PTR(-ENOMEM);1061 1062	skb_put_data(skb, &hdr, sizeof(hdr));1063 1064	return skb;1065}1066 1067int mt7996_mcu_add_bss_info(struct mt7996_phy *phy,1068			    struct ieee80211_vif *vif, int enable)1069{1070	struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;1071	struct mt7996_dev *dev = phy->dev;1072	struct sk_buff *skb;1073 1074	if (mvif->mt76.omac_idx >= REPEATER_BSSID_START) {1075		mt7996_mcu_muar_config(phy, vif, false, enable);1076		mt7996_mcu_muar_config(phy, vif, true, enable);1077	}1078 1079	skb = __mt7996_mcu_alloc_bss_req(&dev->mt76, &mvif->mt76,1080					 MT7996_BSS_UPDATE_MAX_SIZE);1081	if (IS_ERR(skb))1082		return PTR_ERR(skb);1083 1084	/* bss_basic must be first */1085	mt7996_mcu_bss_basic_tlv(skb, vif, NULL, phy->mt76,1086				 mvif->sta.wcid.idx, enable);1087	mt7996_mcu_bss_sec_tlv(skb, vif);1088 1089	if (vif->type == NL80211_IFTYPE_MONITOR)1090		goto out;1091 1092	if (enable) {1093		mt7996_mcu_bss_rfch_tlv(skb, vif, phy);1094		mt7996_mcu_bss_bmc_tlv(skb, vif, phy);1095		mt7996_mcu_bss_ra_tlv(skb, vif, phy);1096		mt7996_mcu_bss_txcmd_tlv(skb, true);1097		mt7996_mcu_bss_ifs_timing_tlv(skb, vif);1098 1099		if (vif->bss_conf.he_support)1100			mt7996_mcu_bss_he_tlv(skb, vif, phy);1101 1102		/* this tag is necessary no matter if the vif is MLD */1103		mt7996_mcu_bss_mld_tlv(skb, vif);1104	}1105 1106	mt7996_mcu_bss_mbssid_tlv(skb, vif, phy, enable);1107 1108out:1109	return mt76_mcu_skb_send_msg(&dev->mt76, skb,1110				     MCU_WMWA_UNI_CMD(BSS_INFO_UPDATE), true);1111}1112 1113int mt7996_mcu_set_timing(struct mt7996_phy *phy, struct ieee80211_vif *vif)1114{1115	struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;1116	struct mt7996_dev *dev = phy->dev;1117	struct sk_buff *skb;1118 1119	skb = __mt7996_mcu_alloc_bss_req(&dev->mt76, &mvif->mt76,1120					 MT7996_BSS_UPDATE_MAX_SIZE);1121	if (IS_ERR(skb))1122		return PTR_ERR(skb);1123 1124	mt7996_mcu_bss_ifs_timing_tlv(skb, vif);1125 1126	return mt76_mcu_skb_send_msg(&dev->mt76, skb,1127				     MCU_WMWA_UNI_CMD(BSS_INFO_UPDATE), true);1128}1129 1130static int1131mt7996_mcu_sta_ba(struct mt7996_dev *dev, struct mt76_vif *mvif,1132		  struct ieee80211_ampdu_params *params,1133		  bool enable, bool tx)1134{1135	struct mt76_wcid *wcid = (struct mt76_wcid *)params->sta->drv_priv;1136	struct sta_rec_ba_uni *ba;1137	struct sk_buff *skb;1138	struct tlv *tlv;1139 1140	skb = __mt76_connac_mcu_alloc_sta_req(&dev->mt76, mvif, wcid,1141					      MT7996_STA_UPDATE_MAX_SIZE);1142	if (IS_ERR(skb))1143		return PTR_ERR(skb);1144 1145	tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_BA, sizeof(*ba));1146 1147	ba = (struct sta_rec_ba_uni *)tlv;1148	ba->ba_type = tx ? MT_BA_TYPE_ORIGINATOR : MT_BA_TYPE_RECIPIENT;1149	ba->winsize = cpu_to_le16(params->buf_size);1150	ba->ssn = cpu_to_le16(params->ssn);1151	ba->ba_en = enable << params->tid;1152	ba->amsdu = params->amsdu;1153	ba->tid = params->tid;1154	ba->ba_rdd_rro = !tx && enable && dev->has_rro;1155 1156	return mt76_mcu_skb_send_msg(&dev->mt76, skb,1157				     MCU_WMWA_UNI_CMD(STA_REC_UPDATE), true);1158}1159 1160/** starec & wtbl **/1161int mt7996_mcu_add_tx_ba(struct mt7996_dev *dev,1162			 struct ieee80211_ampdu_params *params,1163			 bool enable)1164{1165	struct mt7996_sta *msta = (struct mt7996_sta *)params->sta->drv_priv;1166	struct mt7996_vif *mvif = msta->vif;1167 1168	if (enable && !params->amsdu)1169		msta->wcid.amsdu = false;1170 1171	return mt7996_mcu_sta_ba(dev, &mvif->mt76, params, enable, true);1172}1173 1174int mt7996_mcu_add_rx_ba(struct mt7996_dev *dev,1175			 struct ieee80211_ampdu_params *params,1176			 bool enable)1177{1178	struct mt7996_sta *msta = (struct mt7996_sta *)params->sta->drv_priv;1179	struct mt7996_vif *mvif = msta->vif;1180 1181	return mt7996_mcu_sta_ba(dev, &mvif->mt76, params, enable, false);1182}1183 1184static void1185mt7996_mcu_sta_he_tlv(struct sk_buff *skb, struct ieee80211_sta *sta)1186{1187	struct ieee80211_he_cap_elem *elem = &sta->deflink.he_cap.he_cap_elem;1188	struct ieee80211_he_mcs_nss_supp mcs_map;1189	struct sta_rec_he_v2 *he;1190	struct tlv *tlv;1191	int i = 0;1192 1193	if (!sta->deflink.he_cap.has_he)1194		return;1195 1196	tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_HE_V2, sizeof(*he));1197 1198	he = (struct sta_rec_he_v2 *)tlv;1199	for (i = 0; i < 11; i++) {1200		if (i < 6)1201			he->he_mac_cap[i] = elem->mac_cap_info[i];1202		he->he_phy_cap[i] = elem->phy_cap_info[i];1203	}1204 1205	mcs_map = sta->deflink.he_cap.he_mcs_nss_supp;1206	switch (sta->deflink.bandwidth) {1207	case IEEE80211_STA_RX_BW_160:1208		if (elem->phy_cap_info[0] &1209		    IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G)1210			mt7996_mcu_set_sta_he_mcs(sta,1211						  &he->max_nss_mcs[CMD_HE_MCS_BW8080],1212						  le16_to_cpu(mcs_map.rx_mcs_80p80));1213 1214		mt7996_mcu_set_sta_he_mcs(sta,1215					  &he->max_nss_mcs[CMD_HE_MCS_BW160],1216					  le16_to_cpu(mcs_map.rx_mcs_160));1217		fallthrough;1218	default:1219		mt7996_mcu_set_sta_he_mcs(sta,1220					  &he->max_nss_mcs[CMD_HE_MCS_BW80],1221					  le16_to_cpu(mcs_map.rx_mcs_80));1222		break;1223	}1224 1225	he->pkt_ext = 2;1226}1227 1228static void1229mt7996_mcu_sta_he_6g_tlv(struct sk_buff *skb, struct ieee80211_sta *sta)1230{1231	struct sta_rec_he_6g_capa *he_6g;1232	struct tlv *tlv;1233 1234	if (!sta->deflink.he_6ghz_capa.capa)1235		return;1236 1237	tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_HE_6G, sizeof(*he_6g));1238 1239	he_6g = (struct sta_rec_he_6g_capa *)tlv;1240	he_6g->capa = sta->deflink.he_6ghz_capa.capa;1241}1242 1243static void1244mt7996_mcu_sta_eht_tlv(struct sk_buff *skb, struct ieee80211_sta *sta)1245{1246	struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv;1247	struct ieee80211_vif *vif = container_of((void *)msta->vif,1248						 struct ieee80211_vif, drv_priv);1249	struct ieee80211_eht_mcs_nss_supp *mcs_map;1250	struct ieee80211_eht_cap_elem_fixed *elem;1251	struct sta_rec_eht *eht;1252	struct tlv *tlv;1253 1254	if (!sta->deflink.eht_cap.has_eht)1255		return;1256 1257	mcs_map = &sta->deflink.eht_cap.eht_mcs_nss_supp;1258	elem = &sta->deflink.eht_cap.eht_cap_elem;1259 1260	tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_EHT, sizeof(*eht));1261 1262	eht = (struct sta_rec_eht *)tlv;1263	eht->tid_bitmap = 0xff;1264	eht->mac_cap = cpu_to_le16(*(u16 *)elem->mac_cap_info);1265	eht->phy_cap = cpu_to_le64(*(u64 *)elem->phy_cap_info);1266	eht->phy_cap_ext = cpu_to_le64(elem->phy_cap_info[8]);1267 1268	if (vif->type != NL80211_IFTYPE_STATION &&1269	    (sta->deflink.he_cap.he_cap_elem.phy_cap_info[0] &1270	     (IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G |1271	      IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G |1272	      IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G |1273	      IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G)) == 0) {1274		memcpy(eht->mcs_map_bw20, &mcs_map->only_20mhz,1275		       sizeof(eht->mcs_map_bw20));1276		return;1277	}1278 1279	memcpy(eht->mcs_map_bw80, &mcs_map->bw._80, sizeof(eht->mcs_map_bw80));1280	memcpy(eht->mcs_map_bw160, &mcs_map->bw._160, sizeof(eht->mcs_map_bw160));1281	memcpy(eht->mcs_map_bw320, &mcs_map->bw._320, sizeof(eht->mcs_map_bw320));1282}1283 1284static void1285mt7996_mcu_sta_ht_tlv(struct sk_buff *skb, struct ieee80211_sta *sta)1286{1287	struct sta_rec_ht_uni *ht;1288	struct tlv *tlv;1289 1290	if (!sta->deflink.ht_cap.ht_supported)1291		return;1292 1293	tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_HT, sizeof(*ht));1294 1295	ht = (struct sta_rec_ht_uni *)tlv;1296	ht->ht_cap = cpu_to_le16(sta->deflink.ht_cap.cap);1297	ht->ampdu_param = u8_encode_bits(sta->deflink.ht_cap.ampdu_factor,1298					 IEEE80211_HT_AMPDU_PARM_FACTOR) |1299			  u8_encode_bits(sta->deflink.ht_cap.ampdu_density,1300					 IEEE80211_HT_AMPDU_PARM_DENSITY);1301}1302 1303static void1304mt7996_mcu_sta_vht_tlv(struct sk_buff *skb, struct ieee80211_sta *sta)1305{1306	struct sta_rec_vht *vht;1307	struct tlv *tlv;1308 1309	/* For 6G band, this tlv is necessary to let hw work normally */1310	if (!sta->deflink.he_6ghz_capa.capa && !sta->deflink.vht_cap.vht_supported)1311		return;1312 1313	tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_VHT, sizeof(*vht));1314 1315	vht = (struct sta_rec_vht *)tlv;1316	vht->vht_cap = cpu_to_le32(sta->deflink.vht_cap.cap);1317	vht->vht_rx_mcs_map = sta->deflink.vht_cap.vht_mcs.rx_mcs_map;1318	vht->vht_tx_mcs_map = sta->deflink.vht_cap.vht_mcs.tx_mcs_map;1319}1320 1321static void1322mt7996_mcu_sta_amsdu_tlv(struct mt7996_dev *dev, struct sk_buff *skb,1323			 struct ieee80211_vif *vif, struct ieee80211_sta *sta)1324{1325	struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv;1326	struct sta_rec_amsdu *amsdu;1327	struct tlv *tlv;1328 1329	if (vif->type != NL80211_IFTYPE_STATION &&1330	    vif->type != NL80211_IFTYPE_MESH_POINT &&1331	    vif->type != NL80211_IFTYPE_AP)1332		return;1333 1334	if (!sta->deflink.agg.max_amsdu_len)1335		return;1336 1337	tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_HW_AMSDU, sizeof(*amsdu));1338	amsdu = (struct sta_rec_amsdu *)tlv;1339	amsdu->max_amsdu_num = 8;1340	amsdu->amsdu_en = true;1341	msta->wcid.amsdu = true;1342 1343	switch (sta->deflink.agg.max_amsdu_len) {1344	case IEEE80211_MAX_MPDU_LEN_VHT_11454:1345		amsdu->max_mpdu_size =1346			IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454;1347		return;1348	case IEEE80211_MAX_MPDU_LEN_HT_7935:1349	case IEEE80211_MAX_MPDU_LEN_VHT_7991:1350		amsdu->max_mpdu_size = IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991;1351		return;1352	default:1353		amsdu->max_mpdu_size = IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895;1354		return;1355	}1356}1357 1358static void1359mt7996_mcu_sta_muru_tlv(struct mt7996_dev *dev, struct sk_buff *skb,1360			struct ieee80211_vif *vif, struct ieee80211_sta *sta)1361{1362	struct ieee80211_he_cap_elem *elem = &sta->deflink.he_cap.he_cap_elem;1363	struct sta_rec_muru *muru;1364	struct tlv *tlv;1365 1366	if (vif->type != NL80211_IFTYPE_STATION &&1367	    vif->type != NL80211_IFTYPE_AP)1368		return;1369 1370	tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_MURU, sizeof(*muru));1371 1372	muru = (struct sta_rec_muru *)tlv;1373	muru->cfg.mimo_dl_en = vif->bss_conf.eht_mu_beamformer ||1374			       vif->bss_conf.he_mu_beamformer ||1375			       vif->bss_conf.vht_mu_beamformer ||1376			       vif->bss_conf.vht_mu_beamformee;1377	muru->cfg.ofdma_dl_en = true;1378 1379	if (sta->deflink.vht_cap.vht_supported)1380		muru->mimo_dl.vht_mu_bfee =1381			!!(sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE);1382 1383	if (!sta->deflink.he_cap.has_he)1384		return;1385 1386	muru->mimo_dl.partial_bw_dl_mimo =1387		HE_PHY(CAP6_PARTIAL_BANDWIDTH_DL_MUMIMO, elem->phy_cap_info[6]);1388 1389	muru->mimo_ul.full_ul_mimo =1390		HE_PHY(CAP2_UL_MU_FULL_MU_MIMO, elem->phy_cap_info[2]);1391	muru->mimo_ul.partial_ul_mimo =1392		HE_PHY(CAP2_UL_MU_PARTIAL_MU_MIMO, elem->phy_cap_info[2]);1393 1394	muru->ofdma_dl.punc_pream_rx =1395		HE_PHY(CAP1_PREAMBLE_PUNC_RX_MASK, elem->phy_cap_info[1]);1396	muru->ofdma_dl.he_20m_in_40m_2g =1397		HE_PHY(CAP8_20MHZ_IN_40MHZ_HE_PPDU_IN_2G, elem->phy_cap_info[8]);1398	muru->ofdma_dl.he_20m_in_160m =1399		HE_PHY(CAP8_20MHZ_IN_160MHZ_HE_PPDU, elem->phy_cap_info[8]);1400	muru->ofdma_dl.he_80m_in_160m =1401		HE_PHY(CAP8_80MHZ_IN_160MHZ_HE_PPDU, elem->phy_cap_info[8]);1402 1403	muru->ofdma_ul.t_frame_dur =1404		HE_MAC(CAP1_TF_MAC_PAD_DUR_MASK, elem->mac_cap_info[1]);1405	muru->ofdma_ul.mu_cascading =1406		HE_MAC(CAP2_MU_CASCADING, elem->mac_cap_info[2]);1407	muru->ofdma_ul.uo_ra =1408		HE_MAC(CAP3_OFDMA_RA, elem->mac_cap_info[3]);1409	muru->ofdma_ul.rx_ctrl_frame_to_mbss =1410		HE_MAC(CAP3_RX_CTRL_FRAME_TO_MULTIBSS, elem->mac_cap_info[3]);1411}1412 1413static inline bool1414mt7996_is_ebf_supported(struct mt7996_phy *phy, struct ieee80211_vif *vif,1415			struct ieee80211_sta *sta, bool bfee)1416{1417	int sts = hweight16(phy->mt76->chainmask);1418 1419	if (vif->type != NL80211_IFTYPE_STATION &&1420	    vif->type != NL80211_IFTYPE_AP)1421		return false;1422 1423	if (!bfee && sts < 2)1424		return false;1425 1426	if (sta->deflink.eht_cap.has_eht) {1427		struct ieee80211_sta_eht_cap *pc = &sta->deflink.eht_cap;1428		struct ieee80211_eht_cap_elem_fixed *pe = &pc->eht_cap_elem;1429 1430		if (bfee)1431			return vif->bss_conf.eht_su_beamformee &&1432			       EHT_PHY(CAP0_SU_BEAMFORMER, pe->phy_cap_info[0]);1433		else1434			return vif->bss_conf.eht_su_beamformer &&1435			       EHT_PHY(CAP0_SU_BEAMFORMEE, pe->phy_cap_info[0]);1436	}1437 1438	if (sta->deflink.he_cap.has_he) {1439		struct ieee80211_he_cap_elem *pe = &sta->deflink.he_cap.he_cap_elem;1440 1441		if (bfee)1442			return vif->bss_conf.he_su_beamformee &&1443			       HE_PHY(CAP3_SU_BEAMFORMER, pe->phy_cap_info[3]);1444		else1445			return vif->bss_conf.he_su_beamformer &&1446			       HE_PHY(CAP4_SU_BEAMFORMEE, pe->phy_cap_info[4]);1447	}1448 1449	if (sta->deflink.vht_cap.vht_supported) {1450		u32 cap = sta->deflink.vht_cap.cap;1451 1452		if (bfee)1453			return vif->bss_conf.vht_su_beamformee &&1454			       (cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE);1455		else1456			return vif->bss_conf.vht_su_beamformer &&1457			       (cap & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE);1458	}1459 1460	return false;1461}1462 1463static void1464mt7996_mcu_sta_sounding_rate(struct sta_rec_bf *bf)1465{1466	bf->sounding_phy = MT_PHY_TYPE_OFDM;1467	bf->ndp_rate = 0;				/* mcs0 */1468	bf->ndpa_rate = MT7996_CFEND_RATE_DEFAULT;	/* ofdm 24m */1469	bf->rept_poll_rate = MT7996_CFEND_RATE_DEFAULT;	/* ofdm 24m */1470}1471 1472static void1473mt7996_mcu_sta_bfer_ht(struct ieee80211_sta *sta, struct mt7996_phy *phy,1474		       struct sta_rec_bf *bf)1475{1476	struct ieee80211_mcs_info *mcs = &sta->deflink.ht_cap.mcs;1477	u8 n = 0;1478 1479	bf->tx_mode = MT_PHY_TYPE_HT;1480 1481	if ((mcs->tx_params & IEEE80211_HT_MCS_TX_RX_DIFF) &&1482	    (mcs->tx_params & IEEE80211_HT_MCS_TX_DEFINED))1483		n = FIELD_GET(IEEE80211_HT_MCS_TX_MAX_STREAMS_MASK,1484			      mcs->tx_params);1485	else if (mcs->rx_mask[3])1486		n = 3;1487	else if (mcs->rx_mask[2])1488		n = 2;1489	else if (mcs->rx_mask[1])1490		n = 1;1491 1492	bf->nrow = hweight8(phy->mt76->antenna_mask) - 1;1493	bf->ncol = min_t(u8, bf->nrow, n);1494	bf->ibf_ncol = n;1495}1496 1497static void1498mt7996_mcu_sta_bfer_vht(struct ieee80211_sta *sta, struct mt7996_phy *phy,1499			struct sta_rec_bf *bf, bool explicit)1500{1501	struct ieee80211_sta_vht_cap *pc = &sta->deflink.vht_cap;1502	struct ieee80211_sta_vht_cap *vc = &phy->mt76->sband_5g.sband.vht_cap;1503	u16 mcs_map = le16_to_cpu(pc->vht_mcs.rx_mcs_map);1504	u8 nss_mcs = mt7996_mcu_get_sta_nss(mcs_map);1505	u8 tx_ant = hweight8(phy->mt76->antenna_mask) - 1;1506 1507	bf->tx_mode = MT_PHY_TYPE_VHT;1508 1509	if (explicit) {1510		u8 sts, snd_dim;1511 1512		mt7996_mcu_sta_sounding_rate(bf);1513 1514		sts = FIELD_GET(IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK,1515				pc->cap);1516		snd_dim = FIELD_GET(IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK,1517				    vc->cap);1518		bf->nrow = min_t(u8, min_t(u8, snd_dim, sts), tx_ant);1519		bf->ncol = min_t(u8, nss_mcs, bf->nrow);1520		bf->ibf_ncol = bf->ncol;1521 1522		if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_160)1523			bf->nrow = 1;1524	} else {1525		bf->nrow = tx_ant;1526		bf->ncol = min_t(u8, nss_mcs, bf->nrow);1527		bf->ibf_ncol = nss_mcs;1528 1529		if (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_160)1530			bf->ibf_nrow = 1;1531	}1532}1533 1534static void1535mt7996_mcu_sta_bfer_he(struct ieee80211_sta *sta, struct ieee80211_vif *vif,1536		       struct mt7996_phy *phy, struct sta_rec_bf *bf)1537{1538	struct ieee80211_sta_he_cap *pc = &sta->deflink.he_cap;1539	struct ieee80211_he_cap_elem *pe = &pc->he_cap_elem;1540	const struct ieee80211_sta_he_cap *vc =1541		mt76_connac_get_he_phy_cap(phy->mt76, vif);1542	const struct ieee80211_he_cap_elem *ve = &vc->he_cap_elem;1543	u16 mcs_map = le16_to_cpu(pc->he_mcs_nss_supp.rx_mcs_80);1544	u8 nss_mcs = mt7996_mcu_get_sta_nss(mcs_map);1545	u8 snd_dim, sts;1546 1547	if (!vc)1548		return;1549 1550	bf->tx_mode = MT_PHY_TYPE_HE_SU;1551 1552	mt7996_mcu_sta_sounding_rate(bf);1553 1554	bf->trigger_su = HE_PHY(CAP6_TRIG_SU_BEAMFORMING_FB,1555				pe->phy_cap_info[6]);1556	bf->trigger_mu = HE_PHY(CAP6_TRIG_MU_BEAMFORMING_PARTIAL_BW_FB,1557				pe->phy_cap_info[6]);1558	snd_dim = HE_PHY(CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_MASK,1559			 ve->phy_cap_info[5]);1560	sts = HE_PHY(CAP4_BEAMFORMEE_MAX_STS_UNDER_80MHZ_MASK,1561		     pe->phy_cap_info[4]);1562	bf->nrow = min_t(u8, snd_dim, sts);1563	bf->ncol = min_t(u8, nss_mcs, bf->nrow);1564	bf->ibf_ncol = bf->ncol;1565 1566	if (sta->deflink.bandwidth != IEEE80211_STA_RX_BW_160)1567		return;1568 1569	/* go over for 160MHz and 80p80 */1570	if (pe->phy_cap_info[0] &1571	    IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G) {1572		mcs_map = le16_to_cpu(pc->he_mcs_nss_supp.rx_mcs_160);1573		nss_mcs = mt7996_mcu_get_sta_nss(mcs_map);1574 1575		bf->ncol_gt_bw80 = nss_mcs;1576	}1577 1578	if (pe->phy_cap_info[0] &1579	    IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G) {1580		mcs_map = le16_to_cpu(pc->he_mcs_nss_supp.rx_mcs_80p80);1581		nss_mcs = mt7996_mcu_get_sta_nss(mcs_map);1582 1583		if (bf->ncol_gt_bw80)1584			bf->ncol_gt_bw80 = min_t(u8, bf->ncol_gt_bw80, nss_mcs);1585		else1586			bf->ncol_gt_bw80 = nss_mcs;1587	}1588 1589	snd_dim = HE_PHY(CAP5_BEAMFORMEE_NUM_SND_DIM_ABOVE_80MHZ_MASK,1590			 ve->phy_cap_info[5]);1591	sts = HE_PHY(CAP4_BEAMFORMEE_MAX_STS_ABOVE_80MHZ_MASK,1592		     pe->phy_cap_info[4]);1593 1594	bf->nrow_gt_bw80 = min_t(int, snd_dim, sts);1595}1596 1597static void1598mt7996_mcu_sta_bfer_eht(struct ieee80211_sta *sta, struct ieee80211_vif *vif,1599			struct mt7996_phy *phy, struct sta_rec_bf *bf)1600{1601	struct ieee80211_sta_eht_cap *pc = &sta->deflink.eht_cap;1602	struct ieee80211_eht_cap_elem_fixed *pe = &pc->eht_cap_elem;1603	struct ieee80211_eht_mcs_nss_supp *eht_nss = &pc->eht_mcs_nss_supp;1604	const struct ieee80211_sta_eht_cap *vc =1605		mt76_connac_get_eht_phy_cap(phy->mt76, vif);1606	const struct ieee80211_eht_cap_elem_fixed *ve = &vc->eht_cap_elem;1607	u8 nss_mcs = u8_get_bits(eht_nss->bw._80.rx_tx_mcs9_max_nss,1608				 IEEE80211_EHT_MCS_NSS_RX) - 1;1609	u8 snd_dim, sts;1610 1611	bf->tx_mode = MT_PHY_TYPE_EHT_MU;1612 1613	mt7996_mcu_sta_sounding_rate(bf);1614 1615	bf->trigger_su = EHT_PHY(CAP3_TRIG_SU_BF_FDBK, pe->phy_cap_info[3]);1616	bf->trigger_mu = EHT_PHY(CAP3_TRIG_MU_BF_PART_BW_FDBK, pe->phy_cap_info[3]);1617	snd_dim = EHT_PHY(CAP2_SOUNDING_DIM_80MHZ_MASK, ve->phy_cap_info[2]);1618	sts = EHT_PHY(CAP0_BEAMFORMEE_SS_80MHZ_MASK, pe->phy_cap_info[0]) +1619	      (EHT_PHY(CAP1_BEAMFORMEE_SS_80MHZ_MASK, pe->phy_cap_info[1]) << 1);1620	bf->nrow = min_t(u8, snd_dim, sts);1621	bf->ncol = min_t(u8, nss_mcs, bf->nrow);1622	bf->ibf_ncol = bf->ncol;1623 1624	if (sta->deflink.bandwidth < IEEE80211_STA_RX_BW_160)1625		return;1626 1627	switch (sta->deflink.bandwidth) {1628	case IEEE80211_STA_RX_BW_160:1629		snd_dim = EHT_PHY(CAP2_SOUNDING_DIM_160MHZ_MASK, ve->phy_cap_info[2]);1630		sts = EHT_PHY(CAP1_BEAMFORMEE_SS_160MHZ_MASK, pe->phy_cap_info[1]);1631		nss_mcs = u8_get_bits(eht_nss->bw._160.rx_tx_mcs9_max_nss,1632				      IEEE80211_EHT_MCS_NSS_RX) - 1;1633 1634		bf->nrow_gt_bw80 = min_t(u8, snd_dim, sts);1635		bf->ncol_gt_bw80 = nss_mcs;1636		break;1637	case IEEE80211_STA_RX_BW_320:1638		snd_dim = EHT_PHY(CAP2_SOUNDING_DIM_320MHZ_MASK, ve->phy_cap_info[2]) +1639			  (EHT_PHY(CAP3_SOUNDING_DIM_320MHZ_MASK,1640				   ve->phy_cap_info[3]) << 1);1641		sts = EHT_PHY(CAP1_BEAMFORMEE_SS_320MHZ_MASK, pe->phy_cap_info[1]);1642		nss_mcs = u8_get_bits(eht_nss->bw._320.rx_tx_mcs9_max_nss,1643				      IEEE80211_EHT_MCS_NSS_RX) - 1;1644 1645		bf->nrow_gt_bw80 = min_t(u8, snd_dim, sts) << 4;1646		bf->ncol_gt_bw80 = nss_mcs << 4;1647		break;1648	default:1649		break;1650	}1651}1652 1653static void1654mt7996_mcu_sta_bfer_tlv(struct mt7996_dev *dev, struct sk_buff *skb,1655			struct ieee80211_vif *vif, struct ieee80211_sta *sta)1656{1657	struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;1658	struct mt7996_phy *phy = mvif->phy;1659	int tx_ant = hweight16(phy->mt76->chainmask) - 1;1660	struct sta_rec_bf *bf;1661	struct tlv *tlv;1662	static const u8 matrix[4][4] = {1663		{0, 0, 0, 0},1664		{1, 1, 0, 0},	/* 2x1, 2x2, 2x3, 2x4 */1665		{2, 4, 4, 0},	/* 3x1, 3x2, 3x3, 3x4 */1666		{3, 5, 6, 0}	/* 4x1, 4x2, 4x3, 4x4 */1667	};1668	bool ebf;1669 1670	if (!(sta->deflink.ht_cap.ht_supported || sta->deflink.he_cap.has_he))1671		return;1672 1673	ebf = mt7996_is_ebf_supported(phy, vif, sta, false);1674	if (!ebf && !dev->ibf)1675		return;1676 1677	tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_BF, sizeof(*bf));1678	bf = (struct sta_rec_bf *)tlv;1679 1680	/* he/eht: eBF only, in accordance with spec1681	 * vht: support eBF and iBF1682	 * ht: iBF only, since mac80211 lacks of eBF support1683	 */1684	if (sta->deflink.eht_cap.has_eht && ebf)1685		mt7996_mcu_sta_bfer_eht(sta, vif, phy, bf);1686	else if (sta->deflink.he_cap.has_he && ebf)1687		mt7996_mcu_sta_bfer_he(sta, vif, phy, bf);1688	else if (sta->deflink.vht_cap.vht_supported)1689		mt7996_mcu_sta_bfer_vht(sta, phy, bf, ebf);1690	else if (sta->deflink.ht_cap.ht_supported)1691		mt7996_mcu_sta_bfer_ht(sta, phy, bf);1692	else1693		return;1694 1695	bf->bf_cap = ebf ? ebf : dev->ibf << 1;1696	bf->bw = sta->deflink.bandwidth;1697	bf->ibf_dbw = sta->deflink.bandwidth;1698	bf->ibf_nrow = tx_ant;1699 1700	if (!ebf && sta->deflink.bandwidth <= IEEE80211_STA_RX_BW_40 && !bf->ncol)1701		bf->ibf_timeout = 0x48;1702	else1703		bf->ibf_timeout = 0x18;1704 1705	if (ebf && bf->nrow != tx_ant)1706		bf->mem_20m = matrix[tx_ant][bf->ncol];1707	else1708		bf->mem_20m = matrix[bf->nrow][bf->ncol];1709 1710	switch (sta->deflink.bandwidth) {1711	case IEEE80211_STA_RX_BW_160:1712	case IEEE80211_STA_RX_BW_80:1713		bf->mem_total = bf->mem_20m * 2;1714		break;1715	case IEEE80211_STA_RX_BW_40:1716		bf->mem_total = bf->mem_20m;1717		break;1718	case IEEE80211_STA_RX_BW_20:1719	default:1720		break;1721	}1722}1723 1724static void1725mt7996_mcu_sta_bfee_tlv(struct mt7996_dev *dev, struct sk_buff *skb,1726			struct ieee80211_vif *vif, struct ieee80211_sta *sta)1727{1728	struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;1729	struct mt7996_phy *phy = mvif->phy;1730	int tx_ant = hweight8(phy->mt76->antenna_mask) - 1;1731	struct sta_rec_bfee *bfee;1732	struct tlv *tlv;1733	u8 nrow = 0;1734 1735	if (!(sta->deflink.vht_cap.vht_supported || sta->deflink.he_cap.has_he))1736		return;1737 1738	if (!mt7996_is_ebf_supported(phy, vif, sta, true))1739		return;1740 1741	tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_BFEE, sizeof(*bfee));1742	bfee = (struct sta_rec_bfee *)tlv;1743 1744	if (sta->deflink.he_cap.has_he) {1745		struct ieee80211_he_cap_elem *pe = &sta->deflink.he_cap.he_cap_elem;1746 1747		nrow = HE_PHY(CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_MASK,1748			      pe->phy_cap_info[5]);1749	} else if (sta->deflink.vht_cap.vht_supported) {1750		struct ieee80211_sta_vht_cap *pc = &sta->deflink.vht_cap;1751 1752		nrow = FIELD_GET(IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK,1753				 pc->cap);1754	}1755 1756	/* reply with identity matrix to avoid 2x2 BF negative gain */1757	bfee->fb_identity_matrix = (nrow == 1 && tx_ant == 2);1758}1759 1760static void1761mt7996_mcu_sta_tx_proc_tlv(struct sk_buff *skb)1762{1763	struct sta_rec_tx_proc *tx_proc;1764	struct tlv *tlv;1765 1766	tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_TX_PROC, sizeof(*tx_proc));1767 1768	tx_proc = (struct sta_rec_tx_proc *)tlv;1769	tx_proc->flag = cpu_to_le32(0);1770}1771 1772static void1773mt7996_mcu_sta_hdrt_tlv(struct mt7996_dev *dev, struct sk_buff *skb)1774{1775	struct sta_rec_hdrt *hdrt;1776	struct tlv *tlv;1777 1778	tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_HDRT, sizeof(*hdrt));1779 1780	hdrt = (struct sta_rec_hdrt *)tlv;1781	hdrt->hdrt_mode = 1;1782}1783 1784static void1785mt7996_mcu_sta_hdr_trans_tlv(struct mt7996_dev *dev, struct sk_buff *skb,1786			     struct ieee80211_vif *vif,1787			     struct ieee80211_sta *sta)1788{1789	struct sta_rec_hdr_trans *hdr_trans;1790	struct mt76_wcid *wcid;1791	struct tlv *tlv;1792 1793	tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_HDR_TRANS, sizeof(*hdr_trans));1794	hdr_trans = (struct sta_rec_hdr_trans *)tlv;1795	hdr_trans->dis_rx_hdr_tran = true;1796 1797	if (vif->type == NL80211_IFTYPE_STATION)1798		hdr_trans->to_ds = true;1799	else1800		hdr_trans->from_ds = true;1801 1802	if (!sta)1803		return;1804 1805	wcid = (struct mt76_wcid *)sta->drv_priv;1806	hdr_trans->dis_rx_hdr_tran = !test_bit(MT_WCID_FLAG_HDR_TRANS, &wcid->flags);1807	if (test_bit(MT_WCID_FLAG_4ADDR, &wcid->flags)) {1808		hdr_trans->to_ds = true;1809		hdr_trans->from_ds = true;1810	}1811 1812	if (vif->type == NL80211_IFTYPE_MESH_POINT) {1813		hdr_trans->to_ds = true;1814		hdr_trans->from_ds = true;1815		hdr_trans->mesh = true;1816	}1817}1818 1819static enum mcu_mmps_mode1820mt7996_mcu_get_mmps_mode(enum ieee80211_smps_mode smps)1821{1822	switch (smps) {1823	case IEEE80211_SMPS_OFF:1824		return MCU_MMPS_DISABLE;1825	case IEEE80211_SMPS_STATIC:1826		return MCU_MMPS_STATIC;1827	case IEEE80211_SMPS_DYNAMIC:1828		return MCU_MMPS_DYNAMIC;1829	default:1830		return MCU_MMPS_DISABLE;1831	}1832}1833 1834int mt7996_mcu_set_fixed_rate_ctrl(struct mt7996_dev *dev,1835				   void *data, u16 version)1836{1837	struct ra_fixed_rate *req;1838	struct uni_header hdr;1839	struct sk_buff *skb;1840	struct tlv *tlv;1841	int len;1842 1843	len = sizeof(hdr) + sizeof(*req);1844 1845	skb = mt76_mcu_msg_alloc(&dev->mt76, NULL, len);1846	if (!skb)1847		return -ENOMEM;1848 1849	skb_put_data(skb, &hdr, sizeof(hdr));1850 1851	tlv = mt7996_mcu_add_uni_tlv(skb, UNI_RA_FIXED_RATE, sizeof(*req));1852	req = (struct ra_fixed_rate *)tlv;1853	req->version = cpu_to_le16(version);1854	memcpy(&req->rate, data, sizeof(req->rate));1855 1856	return mt76_mcu_skb_send_msg(&dev->mt76, skb,1857				     MCU_WM_UNI_CMD(RA), true);1858}1859 1860int mt7996_mcu_set_fixed_field(struct mt7996_dev *dev, struct ieee80211_vif *vif,1861			       struct ieee80211_sta *sta, void *data, u32 field)1862{1863	struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;1864	struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv;1865	struct sta_phy_uni *phy = data;1866	struct sta_rec_ra_fixed_uni *ra;1867	struct sk_buff *skb;1868	struct tlv *tlv;1869 1870	skb = __mt76_connac_mcu_alloc_sta_req(&dev->mt76, &mvif->mt76,1871					      &msta->wcid,1872					      MT7996_STA_UPDATE_MAX_SIZE);1873	if (IS_ERR(skb))1874		return PTR_ERR(skb);1875 1876	tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_RA_UPDATE, sizeof(*ra));1877	ra = (struct sta_rec_ra_fixed_uni *)tlv;1878 1879	switch (field) {1880	case RATE_PARAM_AUTO:1881		break;1882	case RATE_PARAM_FIXED:1883	case RATE_PARAM_FIXED_MCS:1884	case RATE_PARAM_FIXED_GI:1885	case RATE_PARAM_FIXED_HE_LTF:1886		if (phy)1887			ra->phy = *phy;1888		break;1889	case RATE_PARAM_MMPS_UPDATE:1890		ra->mmps_mode = mt7996_mcu_get_mmps_mode(sta->deflink.smps_mode);1891		break;1892	default:1893		break;1894	}1895	ra->field = cpu_to_le32(field);1896 1897	return mt76_mcu_skb_send_msg(&dev->mt76, skb,1898				     MCU_WMWA_UNI_CMD(STA_REC_UPDATE), true);1899}1900 1901static int1902mt7996_mcu_add_rate_ctrl_fixed(struct mt7996_dev *dev, struct ieee80211_vif *vif,1903			       struct ieee80211_sta *sta)1904{1905	struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;1906	struct cfg80211_chan_def *chandef = &mvif->phy->mt76->chandef;1907	struct cfg80211_bitrate_mask *mask = &mvif->bitrate_mask;1908	enum nl80211_band band = chandef->chan->band;1909	struct sta_phy_uni phy = {};1910	int ret, nrates = 0;1911 1912#define __sta_phy_bitrate_mask_check(_mcs, _gi, _ht, _he)			\1913	do {									\1914		u8 i, gi = mask->control[band]._gi;				\1915		gi = (_he) ? gi : gi == NL80211_TXRATE_FORCE_SGI;		\1916		phy.sgi = gi;							\1917		phy.he_ltf = mask->control[band].he_ltf;			\1918		for (i = 0; i < ARRAY_SIZE(mask->control[band]._mcs); i++) {	\1919			if (!mask->control[band]._mcs[i])			\1920				continue;					\1921			nrates += hweight16(mask->control[band]._mcs[i]);	\1922			phy.mcs = ffs(mask->control[band]._mcs[i]) - 1;		\1923			if (_ht)						\1924				phy.mcs += 8 * i;				\1925		}								\1926	} while (0)1927 1928	if (sta->deflink.he_cap.has_he) {1929		__sta_phy_bitrate_mask_check(he_mcs, he_gi, 0, 1);1930	} else if (sta->deflink.vht_cap.vht_supported) {1931		__sta_phy_bitrate_mask_check(vht_mcs, gi, 0, 0);1932	} else if (sta->deflink.ht_cap.ht_supported) {1933		__sta_phy_bitrate_mask_check(ht_mcs, gi, 1, 0);1934	} else {1935		nrates = hweight32(mask->control[band].legacy);1936		phy.mcs = ffs(mask->control[band].legacy) - 1;1937	}1938#undef __sta_phy_bitrate_mask_check1939 1940	/* fall back to auto rate control */1941	if (mask->control[band].gi == NL80211_TXRATE_DEFAULT_GI &&1942	    mask->control[band].he_gi == GENMASK(7, 0) &&1943	    mask->control[band].he_ltf == GENMASK(7, 0) &&1944	    nrates != 1)1945		return 0;1946 1947	/* fixed single rate */1948	if (nrates == 1) {1949		ret = mt7996_mcu_set_fixed_field(dev, vif, sta, &phy,1950						 RATE_PARAM_FIXED_MCS);1951		if (ret)1952			return ret;1953	}1954 1955	/* fixed GI */1956	if (mask->control[band].gi != NL80211_TXRATE_DEFAULT_GI ||1957	    mask->control[band].he_gi != GENMASK(7, 0)) {1958		struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv;1959		u32 addr;1960 1961		/* firmware updates only TXCMD but doesn't take WTBL into1962		 * account, so driver should update here to reflect the1963		 * actual txrate hardware sends out.1964		 */1965		addr = mt7996_mac_wtbl_lmac_addr(dev, msta->wcid.idx, 7);1966		if (sta->deflink.he_cap.has_he)1967			mt76_rmw_field(dev, addr, GENMASK(31, 24), phy.sgi);1968		else1969			mt76_rmw_field(dev, addr, GENMASK(15, 12), phy.sgi);1970 1971		ret = mt7996_mcu_set_fixed_field(dev, vif, sta, &phy,1972						 RATE_PARAM_FIXED_GI);1973		if (ret)1974			return ret;1975	}1976 1977	/* fixed HE_LTF */1978	if (mask->control[band].he_ltf != GENMASK(7, 0)) {1979		ret = mt7996_mcu_set_fixed_field(dev, vif, sta, &phy,1980						 RATE_PARAM_FIXED_HE_LTF);1981		if (ret)1982			return ret;1983	}1984 1985	return 0;1986}1987 1988static void1989mt7996_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7996_dev *dev,1990			     struct ieee80211_vif *vif, struct ieee80211_sta *sta)1991{1992#define INIT_RCPI 1801993	struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;1994	struct mt76_phy *mphy = mvif->phy->mt76;1995	struct cfg80211_chan_def *chandef = &mphy->chandef;1996	struct cfg80211_bitrate_mask *mask = &mvif->bitrate_mask;1997	enum nl80211_band band = chandef->chan->band;1998	struct sta_rec_ra_uni *ra;1999	struct tlv *tlv;2000	u32 supp_rate = sta->deflink.supp_rates[band];2001	u32 cap = sta->wme ? STA_CAP_WMM : 0;2002 2003	tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_RA, sizeof(*ra));2004	ra = (struct sta_rec_ra_uni *)tlv;2005 2006	ra->valid = true;2007	ra->auto_rate = true;2008	ra->phy_mode = mt76_connac_get_phy_mode(mphy, vif, band, &sta->deflink);2009	ra->channel = chandef->chan->hw_value;2010	ra->bw = (sta->deflink.bandwidth == IEEE80211_STA_RX_BW_320) ?2011		 CMD_CBW_320MHZ : sta->deflink.bandwidth;2012	ra->phy.bw = ra->bw;2013	ra->mmps_mode = mt7996_mcu_get_mmps_mode(sta->deflink.smps_mode);2014 2015	if (supp_rate) {2016		supp_rate &= mask->control[band].legacy;2017		ra->rate_len = hweight32(supp_rate);2018 2019		if (band == NL80211_BAND_2GHZ) {2020			ra->supp_mode = MODE_CCK;2021			ra->supp_cck_rate = supp_rate & GENMASK(3, 0);2022 2023			if (ra->rate_len > 4) {2024				ra->supp_mode |= MODE_OFDM;2025				ra->supp_ofdm_rate = supp_rate >> 4;2026			}2027		} else {2028			ra->supp_mode = MODE_OFDM;2029			ra->supp_ofdm_rate = supp_rate;2030		}2031	}2032 2033	if (sta->deflink.ht_cap.ht_supported) {2034		ra->supp_mode |= MODE_HT;2035		ra->af = sta->deflink.ht_cap.ampdu_factor;2036		ra->ht_gf = !!(sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD);2037 2038		cap |= STA_CAP_HT;2039		if (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20)2040			cap |= STA_CAP_SGI_20;2041		if (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_40)2042			cap |= STA_CAP_SGI_40;2043		if (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_TX_STBC)2044			cap |= STA_CAP_TX_STBC;2045		if (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_RX_STBC)2046			cap |= STA_CAP_RX_STBC;2047		if (vif->bss_conf.ht_ldpc &&2048		    (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_LDPC_CODING))2049			cap |= STA_CAP_LDPC;2050 2051		mt7996_mcu_set_sta_ht_mcs(sta, ra->ht_mcs,2052					  mask->control[band].ht_mcs);2053		ra->supp_ht_mcs = *(__le32 *)ra->ht_mcs;2054	}2055 2056	if (sta->deflink.vht_cap.vht_supported) {2057		u8 af;2058 2059		ra->supp_mode |= MODE_VHT;2060		af = FIELD_GET(IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK,2061			       sta->deflink.vht_cap.cap);2062		ra->af = max_t(u8, ra->af, af);2063 2064		cap |= STA_CAP_VHT;2065		if (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_80)2066			cap |= STA_CAP_VHT_SGI_80;2067		if (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_160)2068			cap |= STA_CAP_VHT_SGI_160;2069		if (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_TXSTBC)2070			cap |= STA_CAP_VHT_TX_STBC;2071		if (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_RXSTBC_1)2072			cap |= STA_CAP_VHT_RX_STBC;2073		if (vif->bss_conf.vht_ldpc &&2074		    (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC))2075			cap |= STA_CAP_VHT_LDPC;2076 2077		mt7996_mcu_set_sta_vht_mcs(sta, ra->supp_vht_mcs,2078					   mask->control[band].vht_mcs);2079	}2080 2081	if (sta->deflink.he_cap.has_he) {2082		ra->supp_mode |= MODE_HE;2083		cap |= STA_CAP_HE;2084 2085		if (sta->deflink.he_6ghz_capa.capa)2086			ra->af = le16_get_bits(sta->deflink.he_6ghz_capa.capa,2087					       IEEE80211_HE_6GHZ_CAP_MAX_AMPDU_LEN_EXP);2088	}2089	ra->sta_cap = cpu_to_le32(cap);2090 2091	memset(ra->rx_rcpi, INIT_RCPI, sizeof(ra->rx_rcpi));2092}2093 2094int mt7996_mcu_add_rate_ctrl(struct mt7996_dev *dev, struct ieee80211_vif *vif,2095			     struct ieee80211_sta *sta, bool changed)2096{2097	struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;2098	struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv;2099	struct sk_buff *skb;2100	int ret;2101 2102	skb = __mt76_connac_mcu_alloc_sta_req(&dev->mt76, &mvif->mt76,2103					      &msta->wcid,2104					      MT7996_STA_UPDATE_MAX_SIZE);2105	if (IS_ERR(skb))2106		return PTR_ERR(skb);2107 2108	/* firmware rc algorithm refers to sta_rec_he for HE control.2109	 * once dev->rc_work changes the settings driver should also2110	 * update sta_rec_he here.2111	 */2112	if (changed)2113		mt7996_mcu_sta_he_tlv(skb, sta);2114 2115	/* sta_rec_ra accommodates BW, NSS and only MCS range format2116	 * i.e 0-{7,8,9} for VHT.2117	 */2118	mt7996_mcu_sta_rate_ctrl_tlv(skb, dev, vif, sta);2119 2120	ret = mt76_mcu_skb_send_msg(&dev->mt76, skb,2121				    MCU_WMWA_UNI_CMD(STA_REC_UPDATE), true);2122	if (ret)2123		return ret;2124 2125	return mt7996_mcu_add_rate_ctrl_fixed(dev, vif, sta);2126}2127 2128static int2129mt7996_mcu_add_group(struct mt7996_dev *dev, struct ieee80211_vif *vif,2130		     struct ieee80211_sta *sta)2131{2132#define MT_STA_BSS_GROUP		12133	struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;2134	struct mt7996_sta *msta;2135	struct {2136		u8 __rsv1[4];2137 2138		__le16 tag;2139		__le16 len;2140		__le16 wlan_idx;2141		u8 __rsv2[2];2142		__le32 action;2143		__le32 val;2144		u8 __rsv3[8];2145	} __packed req = {2146		.tag = cpu_to_le16(UNI_VOW_DRR_CTRL),2147		.len = cpu_to_le16(sizeof(req) - 4),2148		.action = cpu_to_le32(MT_STA_BSS_GROUP),2149		.val = cpu_to_le32(mvif->mt76.idx % 16),2150	};2151 2152	msta = sta ? (struct mt7996_sta *)sta->drv_priv : &mvif->sta;2153	req.wlan_idx = cpu_to_le16(msta->wcid.idx);2154 2155	return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(VOW), &req,2156				 sizeof(req), true);2157}2158 2159int mt7996_mcu_add_sta(struct mt7996_dev *dev, struct ieee80211_vif *vif,2160		       struct ieee80211_sta *sta, bool enable, bool newly)2161{2162	struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;2163	struct ieee80211_link_sta *link_sta;2164	struct mt7996_sta *msta;2165	struct sk_buff *skb;2166	int conn_state;2167	int ret;2168 2169	msta = sta ? (struct mt7996_sta *)sta->drv_priv : &mvif->sta;2170	link_sta = sta ? &sta->deflink : NULL;2171 2172	skb = __mt76_connac_mcu_alloc_sta_req(&dev->mt76, &mvif->mt76,2173					      &msta->wcid,2174					      MT7996_STA_UPDATE_MAX_SIZE);2175	if (IS_ERR(skb))2176		return PTR_ERR(skb);2177 2178	/* starec basic */2179	conn_state = enable ? CONN_STATE_PORT_SECURE : CONN_STATE_DISCONNECT;2180	mt76_connac_mcu_sta_basic_tlv(&dev->mt76, skb, vif, link_sta,2181				      conn_state, newly);2182 2183	if (!enable)2184		goto out;2185 2186	/* starec hdr trans */2187	mt7996_mcu_sta_hdr_trans_tlv(dev, skb, vif, sta);2188	/* starec tx proc */2189	mt7996_mcu_sta_tx_proc_tlv(skb);2190 2191	/* tag order is in accordance with firmware dependency. */2192	if (sta) {2193		/* starec hdrt mode */2194		mt7996_mcu_sta_hdrt_tlv(dev, skb);2195		/* starec bfer */2196		mt7996_mcu_sta_bfer_tlv(dev, skb, vif, sta);2197		/* starec ht */2198		mt7996_mcu_sta_ht_tlv(skb, sta);2199		/* starec vht */2200		mt7996_mcu_sta_vht_tlv(skb, sta);2201		/* starec uapsd */2202		mt76_connac_mcu_sta_uapsd(skb, vif, sta);2203		/* starec amsdu */2204		mt7996_mcu_sta_amsdu_tlv(dev, skb, vif, sta);2205		/* starec he */2206		mt7996_mcu_sta_he_tlv(skb, sta);2207		/* starec he 6g*/2208		mt7996_mcu_sta_he_6g_tlv(skb, sta);2209		/* starec eht */2210		mt7996_mcu_sta_eht_tlv(skb, sta);2211		/* starec muru */2212		mt7996_mcu_sta_muru_tlv(dev, skb, vif, sta);2213		/* starec bfee */2214		mt7996_mcu_sta_bfee_tlv(dev, skb, vif, sta);2215	}2216 2217	ret = mt7996_mcu_add_group(dev, vif, sta);2218	if (ret) {2219		dev_kfree_skb(skb);2220		return ret;2221	}2222out:2223	return mt76_mcu_skb_send_msg(&dev->mt76, skb,2224				     MCU_WMWA_UNI_CMD(STA_REC_UPDATE), true);2225}2226 2227static int2228mt7996_mcu_sta_key_tlv(struct mt76_wcid *wcid,2229		       struct sk_buff *skb,2230		       struct ieee80211_key_conf *key,2231		       enum set_key_cmd cmd)2232{2233	struct sta_rec_sec_uni *sec;2234	struct tlv *tlv;2235 2236	tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_KEY_V2, sizeof(*sec));2237	sec = (struct sta_rec_sec_uni *)tlv;2238	sec->add = cmd;2239 2240	if (cmd == SET_KEY) {2241		struct sec_key_uni *sec_key;2242		u8 cipher;2243 2244		cipher = mt76_connac_mcu_get_cipher(key->cipher);2245		if (cipher == MCU_CIPHER_NONE)2246			return -EOPNOTSUPP;2247 2248		sec_key = &sec->key[0];2249		sec_key->wlan_idx = cpu_to_le16(wcid->idx);2250		sec_key->mgmt_prot = 0;2251		sec_key->cipher_id = cipher;2252		sec_key->cipher_len = sizeof(*sec_key);2253		sec_key->key_id = key->keyidx;2254		sec_key->key_len = key->keylen;2255		sec_key->need_resp = 0;2256		memcpy(sec_key->key, key->key, key->keylen);2257 2258		if (cipher == MCU_CIPHER_TKIP) {2259			/* Rx/Tx MIC keys are swapped */2260			memcpy(sec_key->key + 16, key->key + 24, 8);2261			memcpy(sec_key->key + 24, key->key + 16, 8);2262		}2263 2264		sec->n_cipher = 1;2265	} else {2266		sec->n_cipher = 0;2267	}2268 2269	return 0;2270}2271 2272int mt7996_mcu_add_key(struct mt76_dev *dev, struct ieee80211_vif *vif,2273		       struct ieee80211_key_conf *key, int mcu_cmd,2274		       struct mt76_wcid *wcid, enum set_key_cmd cmd)2275{2276	struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;2277	struct sk_buff *skb;2278	int ret;2279 2280	skb = __mt76_connac_mcu_alloc_sta_req(dev, mvif, wcid,2281					      MT7996_STA_UPDATE_MAX_SIZE);2282	if (IS_ERR(skb))2283		return PTR_ERR(skb);2284 2285	ret = mt7996_mcu_sta_key_tlv(wcid, skb, key, cmd);2286	if (ret)2287		return ret;2288 2289	return mt76_mcu_skb_send_msg(dev, skb, mcu_cmd, true);2290}2291 2292static int mt7996_mcu_get_pn(struct mt7996_dev *dev, struct ieee80211_vif *vif,2293			     u8 *pn)2294{2295#define TSC_TYPE_BIGTK_PN 22296	struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;2297	struct sta_rec_pn_info *pn_info;2298	struct sk_buff *skb, *rskb;2299	struct tlv *tlv;2300	int ret;2301 2302	skb = mt76_connac_mcu_alloc_sta_req(&dev->mt76, &mvif->mt76, &mvif->sta.wcid);2303	if (IS_ERR(skb))2304		return PTR_ERR(skb);2305 2306	tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_PN_INFO, sizeof(*pn_info));2307	pn_info = (struct sta_rec_pn_info *)tlv;2308 2309	pn_info->tsc_type = TSC_TYPE_BIGTK_PN;2310	ret = mt76_mcu_skb_send_and_get_msg(&dev->mt76, skb,2311					    MCU_WM_UNI_CMD_QUERY(STA_REC_UPDATE),2312					    true, &rskb);2313	if (ret)2314		return ret;2315 2316	skb_pull(rskb, 4);2317 2318	pn_info = (struct sta_rec_pn_info *)rskb->data;2319	if (le16_to_cpu(pn_info->tag) == STA_REC_PN_INFO)2320		memcpy(pn, pn_info->pn, 6);2321 2322	dev_kfree_skb(rskb);2323	return 0;2324}2325 2326int mt7996_mcu_bcn_prot_enable(struct mt7996_dev *dev, struct ieee80211_vif *vif,2327			       struct ieee80211_key_conf *key)2328{2329	struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;2330	struct mt7996_mcu_bcn_prot_tlv *bcn_prot;2331	struct sk_buff *skb;2332	struct tlv *tlv;2333	u8 pn[6] = {};2334	int len = sizeof(struct bss_req_hdr) +2335		  sizeof(struct mt7996_mcu_bcn_prot_tlv);2336	int ret;2337 2338	skb = __mt7996_mcu_alloc_bss_req(&dev->mt76, &mvif->mt76, len);2339	if (IS_ERR(skb))2340		return PTR_ERR(skb);2341 2342	tlv = mt76_connac_mcu_add_tlv(skb, UNI_BSS_INFO_BCN_PROT, sizeof(*bcn_prot));2343 2344	bcn_prot = (struct mt7996_mcu_bcn_prot_tlv *)tlv;2345 2346	ret = mt7996_mcu_get_pn(dev, vif, pn);2347	if (ret) {2348		dev_kfree_skb(skb);2349		return ret;2350	}2351 2352	switch (key->cipher) {2353	case WLAN_CIPHER_SUITE_AES_CMAC:2354		bcn_prot->cipher_id = MCU_CIPHER_BCN_PROT_CMAC_128;2355		break;2356	case WLAN_CIPHER_SUITE_BIP_GMAC_128:2357		bcn_prot->cipher_id = MCU_CIPHER_BCN_PROT_GMAC_128;2358		break;2359	case WLAN_CIPHER_SUITE_BIP_GMAC_256:2360		bcn_prot->cipher_id = MCU_CIPHER_BCN_PROT_GMAC_256;2361		break;2362	case WLAN_CIPHER_SUITE_BIP_CMAC_256:2363	default:2364		dev_err(dev->mt76.dev, "Not supported Bigtk Cipher\n");2365		dev_kfree_skb(skb);2366		return -EOPNOTSUPP;2367	}2368 2369	pn[0]++;2370	memcpy(bcn_prot->pn, pn, 6);2371	bcn_prot->enable = BP_SW_MODE;2372	memcpy(bcn_prot->key, key->key, WLAN_MAX_KEY_LEN);2373	bcn_prot->key_id = key->keyidx;2374 2375	return mt76_mcu_skb_send_msg(&dev->mt76, skb,2376				     MCU_WMWA_UNI_CMD(BSS_INFO_UPDATE), true);2377}2378int mt7996_mcu_add_dev_info(struct mt7996_phy *phy,2379			    struct ieee80211_vif *vif, bool enable)2380{2381	struct mt7996_dev *dev = phy->dev;2382	struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;2383	struct {2384		struct req_hdr {2385			u8 omac_idx;2386			u8 band_idx;2387			u8 __rsv[2];2388		} __packed hdr;2389		struct req_tlv {2390			__le16 tag;2391			__le16 len;2392			u8 active;2393			u8 __rsv;2394			u8 omac_addr[ETH_ALEN];2395		} __packed tlv;2396	} data = {2397		.hdr = {2398			.omac_idx = mvif->mt76.omac_idx,2399			.band_idx = mvif->mt76.band_idx,2400		},2401		.tlv = {2402			.tag = cpu_to_le16(DEV_INFO_ACTIVE),2403			.len = cpu_to_le16(sizeof(struct req_tlv)),2404			.active = enable,2405		},2406	};2407 2408	if (mvif->mt76.omac_idx >= REPEATER_BSSID_START)2409		return mt7996_mcu_muar_config(phy, vif, false, enable);2410 2411	memcpy(data.tlv.omac_addr, vif->addr, ETH_ALEN);2412	return mt76_mcu_send_msg(&dev->mt76, MCU_WMWA_UNI_CMD(DEV_INFO_UPDATE),2413				 &data, sizeof(data), true);2414}2415 2416static void2417mt7996_mcu_beacon_cntdwn(struct ieee80211_vif *vif, struct sk_buff *rskb,2418			 struct sk_buff *skb,2419			 struct ieee80211_mutable_offsets *offs)2420{2421	struct bss_bcn_cntdwn_tlv *info;2422	struct tlv *tlv;2423	u16 tag;2424 2425	if (!offs->cntdwn_counter_offs[0])2426		return;2427 2428	tag = vif->bss_conf.csa_active ? UNI_BSS_INFO_BCN_CSA : UNI_BSS_INFO_BCN_BCC;2429 2430	tlv = mt7996_mcu_add_uni_tlv(rskb, tag, sizeof(*info));2431 2432	info = (struct bss_bcn_cntdwn_tlv *)tlv;2433	info->cnt = skb->data[offs->cntdwn_counter_offs[0]];2434}2435 2436static void2437mt7996_mcu_beacon_mbss(struct sk_buff *rskb, struct sk_buff *skb,2438		       struct ieee80211_vif *vif, struct bss_bcn_content_tlv *bcn,2439		       struct ieee80211_mutable_offsets *offs)2440{2441	struct bss_bcn_mbss_tlv *mbss;2442	const struct element *elem;2443	struct tlv *tlv;2444 2445	if (!vif->bss_conf.bssid_indicator)2446		return;2447 2448	tlv = mt7996_mcu_add_uni_tlv(rskb, UNI_BSS_INFO_BCN_MBSSID, sizeof(*mbss));2449 2450	mbss = (struct bss_bcn_mbss_tlv *)tlv;2451	mbss->offset[0] = cpu_to_le16(offs->tim_offset);2452	mbss->bitmap = cpu_to_le32(1);2453 2454	for_each_element_id(elem, WLAN_EID_MULTIPLE_BSSID,2455			    &skb->data[offs->mbssid_off],2456			    skb->len - offs->mbssid_off) {2457		const struct element *sub_elem;2458 2459		if (elem->datalen < 2)2460			continue;2461 2462		for_each_element(sub_elem, elem->data + 1, elem->datalen - 1) {2463			const struct ieee80211_bssid_index *idx;2464			const u8 *idx_ie;2465 2466			/* not a valid BSS profile */2467			if (sub_elem->id || sub_elem->datalen < 4)2468				continue;2469 2470			/* Find WLAN_EID_MULTI_BSSID_IDX2471			 * in the merged nontransmitted profile2472			 */2473			idx_ie = cfg80211_find_ie(WLAN_EID_MULTI_BSSID_IDX,2474						  sub_elem->data, sub_elem->datalen);2475			if (!idx_ie || idx_ie[1] < sizeof(*idx))2476				continue;2477 2478			idx = (void *)(idx_ie + 2);2479			if (!idx->bssid_index || idx->bssid_index > 31)2480				continue;2481 2482			mbss->offset[idx->bssid_index] = cpu_to_le16(idx_ie -2483								     skb->data);2484			mbss->bitmap |= cpu_to_le32(BIT(idx->bssid_index));2485		}2486	}2487}2488 2489static void2490mt7996_mcu_beacon_cont(struct mt7996_dev *dev, struct ieee80211_vif *vif,2491		       struct sk_buff *rskb, struct sk_buff *skb,2492		       struct bss_bcn_content_tlv *bcn,2493		       struct ieee80211_mutable_offsets *offs)2494{2495	struct mt76_wcid *wcid = &dev->mt76.global_wcid;2496	u8 *buf;2497 2498	bcn->pkt_len = cpu_to_le16(MT_TXD_SIZE + skb->len);2499	bcn->tim_ie_pos = cpu_to_le16(offs->tim_offset);2500 2501	if (offs->cntdwn_counter_offs[0]) {2502		u16 offset = offs->cntdwn_counter_offs[0];2503 2504		if (vif->bss_conf.csa_active)2505			bcn->csa_ie_pos = cpu_to_le16(offset - 4);2506		if (vif->bss_conf.color_change_active)2507			bcn->bcc_ie_pos = cpu_to_le16(offset - 3);2508	}2509 2510	buf = (u8 *)bcn + sizeof(*bcn);2511	mt7996_mac_write_txwi(dev, (__le32 *)buf, skb, wcid, NULL, 0, 0,2512			      BSS_CHANGED_BEACON);2513 2514	memcpy(buf + MT_TXD_SIZE, skb->data, skb->len);2515}2516 2517int mt7996_mcu_add_beacon(struct ieee80211_hw *hw,2518			  struct ieee80211_vif *vif, int en)2519{2520	struct mt7996_dev *dev = mt7996_hw_dev(hw);2521	struct mt7996_phy *phy = mt7996_hw_phy(hw);2522	struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;2523	struct ieee80211_mutable_offsets offs;2524	struct ieee80211_tx_info *info;2525	struct sk_buff *skb, *rskb;2526	struct tlv *tlv;2527	struct bss_bcn_content_tlv *bcn;2528	int len;2529 2530	if (vif->bss_conf.nontransmitted)2531		return 0;2532 2533	rskb = __mt7996_mcu_alloc_bss_req(&dev->mt76, &mvif->mt76,2534					  MT7996_MAX_BSS_OFFLOAD_SIZE);2535	if (IS_ERR(rskb))2536		return PTR_ERR(rskb);2537 2538	skb = ieee80211_beacon_get_template(hw, vif, &offs, 0);2539	if (!skb) {2540		dev_kfree_skb(rskb);2541		return -EINVAL;2542	}2543 2544	if (skb->len > MT7996_MAX_BEACON_SIZE) {2545		dev_err(dev->mt76.dev, "Bcn size limit exceed\n");2546		dev_kfree_skb(rskb);2547		dev_kfree_skb(skb);2548		return -EINVAL;2549	}2550 2551	info = IEEE80211_SKB_CB(skb);2552	info->hw_queue |= FIELD_PREP(MT_TX_HW_QUEUE_PHY, phy->mt76->band_idx);2553 2554	len = ALIGN(sizeof(*bcn) + MT_TXD_SIZE + skb->len, 4);2555	tlv = mt7996_mcu_add_uni_tlv(rskb, UNI_BSS_INFO_BCN_CONTENT, len);2556	bcn = (struct bss_bcn_content_tlv *)tlv;2557	bcn->enable = en;2558	if (!en)2559		goto out;2560 2561	mt7996_mcu_beacon_cont(dev, vif, rskb, skb, bcn, &offs);2562	mt7996_mcu_beacon_mbss(rskb, skb, vif, bcn, &offs);2563	mt7996_mcu_beacon_cntdwn(vif, rskb, skb, &offs);2564out:2565	dev_kfree_skb(skb);2566	return mt76_mcu_skb_send_msg(&phy->dev->mt76, rskb,2567				     MCU_WMWA_UNI_CMD(BSS_INFO_UPDATE), true);2568}2569 2570int mt7996_mcu_beacon_inband_discov(struct mt7996_dev *dev,2571				    struct ieee80211_vif *vif, u32 changed)2572{2573#define OFFLOAD_TX_MODE_SU	BIT(0)2574#define OFFLOAD_TX_MODE_MU	BIT(1)2575	struct ieee80211_hw *hw = mt76_hw(dev);2576	struct mt7996_phy *phy = mt7996_hw_phy(hw);2577	struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;2578	struct cfg80211_chan_def *chandef = &mvif->phy->mt76->chandef;2579	enum nl80211_band band = chandef->chan->band;2580	struct mt76_wcid *wcid = &dev->mt76.global_wcid;2581	struct bss_inband_discovery_tlv *discov;2582	struct ieee80211_tx_info *info;2583	struct sk_buff *rskb, *skb = NULL;2584	struct tlv *tlv;2585	u8 *buf, interval;2586	int len;2587 2588	if (vif->bss_conf.nontransmitted)2589		return 0;2590 2591	rskb = __mt7996_mcu_alloc_bss_req(&dev->mt76, &mvif->mt76,2592					  MT7996_MAX_BSS_OFFLOAD_SIZE);2593	if (IS_ERR(rskb))2594		return PTR_ERR(rskb);2595 2596	if (changed & BSS_CHANGED_FILS_DISCOVERY &&2597	    vif->bss_conf.fils_discovery.max_interval) {2598		interval = vif->bss_conf.fils_discovery.max_interval;2599		skb = ieee80211_get_fils_discovery_tmpl(hw, vif);2600	} else if (changed & BSS_CHANGED_UNSOL_BCAST_PROBE_RESP &&2601		   vif->bss_conf.unsol_bcast_probe_resp_interval) {2602		interval = vif->bss_conf.unsol_bcast_probe_resp_interval;2603		skb = ieee80211_get_unsol_bcast_probe_resp_tmpl(hw, vif);2604	}2605 2606	if (!skb) {2607		dev_kfree_skb(rskb);2608		return -EINVAL;2609	}2610 2611	if (skb->len > MT7996_MAX_BEACON_SIZE) {2612		dev_err(dev->mt76.dev, "inband discovery size limit exceed\n");2613		dev_kfree_skb(rskb);2614		dev_kfree_skb(skb);2615		return -EINVAL;2616	}2617 2618	info = IEEE80211_SKB_CB(skb);2619	info->control.vif = vif;2620	info->band = band;2621	info->hw_queue |= FIELD_PREP(MT_TX_HW_QUEUE_PHY, phy->mt76->band_idx);2622 2623	len = ALIGN(sizeof(*discov) + MT_TXD_SIZE + skb->len, 4);2624	tlv = mt7996_mcu_add_uni_tlv(rskb, UNI_BSS_INFO_OFFLOAD, len);2625 2626	discov = (struct bss_inband_discovery_tlv *)tlv;2627	discov->tx_mode = OFFLOAD_TX_MODE_SU;2628	/* 0: UNSOL PROBE RESP, 1: FILS DISCOV */2629	discov->tx_type = !!(changed & BSS_CHANGED_FILS_DISCOVERY);2630	discov->tx_interval = interval;2631	discov->prob_rsp_len = cpu_to_le16(MT_TXD_SIZE + skb->len);2632	discov->enable = true;2633	discov->wcid = cpu_to_le16(MT7996_WTBL_RESERVED);2634 2635	buf = (u8 *)tlv + sizeof(*discov);2636 2637	mt7996_mac_write_txwi(dev, (__le32 *)buf, skb, wcid, NULL, 0, 0, changed);2638 2639	memcpy(buf + MT_TXD_SIZE, skb->data, skb->len);2640 2641	dev_kfree_skb(skb);2642 2643	return mt76_mcu_skb_send_msg(&dev->mt76, rskb,2644				     MCU_WMWA_UNI_CMD(BSS_INFO_UPDATE), true);2645}2646 2647static int mt7996_driver_own(struct mt7996_dev *dev, u8 band)2648{2649	mt76_wr(dev, MT_TOP_LPCR_HOST_BAND(band), MT_TOP_LPCR_HOST_DRV_OWN);2650	if (!mt76_poll_msec(dev, MT_TOP_LPCR_HOST_BAND(band),2651			    MT_TOP_LPCR_HOST_FW_OWN_STAT, 0, 500)) {2652		dev_err(dev->mt76.dev, "Timeout for driver own\n");2653		return -EIO;2654	}2655 2656	/* clear irq when the driver own success */2657	mt76_wr(dev, MT_TOP_LPCR_HOST_BAND_IRQ_STAT(band),2658		MT_TOP_LPCR_HOST_BAND_STAT);2659 2660	return 0;2661}2662 2663static u32 mt7996_patch_sec_mode(u32 key_info)2664{2665	u32 sec = u32_get_bits(key_info, MT7996_PATCH_SEC), key = 0;2666 2667	if (key_info == GENMASK(31, 0) || sec == MT7996_SEC_MODE_PLAIN)2668		return 0;2669 2670	if (sec == MT7996_SEC_MODE_AES)2671		key = u32_get_bits(key_info, MT7996_PATCH_AES_KEY);2672	else2673		key = u32_get_bits(key_info, MT7996_PATCH_SCRAMBLE_KEY);2674 2675	return MT7996_SEC_ENCRYPT | MT7996_SEC_IV |2676	       u32_encode_bits(key, MT7996_SEC_KEY_IDX);2677}2678 2679static int mt7996_load_patch(struct mt7996_dev *dev)2680{2681	const struct mt7996_patch_hdr *hdr;2682	const struct firmware *fw = NULL;2683	int i, ret, sem;2684 2685	sem = mt76_connac_mcu_patch_sem_ctrl(&dev->mt76, 1);2686	switch (sem) {2687	case PATCH_IS_DL:2688		return 0;2689	case PATCH_NOT_DL_SEM_SUCCESS:2690		break;2691	default:2692		dev_err(dev->mt76.dev, "Failed to get patch semaphore\n");2693		return -EAGAIN;2694	}2695 2696	ret = request_firmware(&fw, fw_name(dev, ROM_PATCH), dev->mt76.dev);2697	if (ret)2698		goto out;2699 2700	if (!fw || !fw->data || fw->size < sizeof(*hdr)) {2701		dev_err(dev->mt76.dev, "Invalid firmware\n");2702		ret = -EINVAL;2703		goto out;2704	}2705 2706	hdr = (const struct mt7996_patch_hdr *)(fw->data);2707 2708	dev_info(dev->mt76.dev, "HW/SW Version: 0x%x, Build Time: %.16s\n",2709		 be32_to_cpu(hdr->hw_sw_ver), hdr->build_date);2710 2711	for (i = 0; i < be32_to_cpu(hdr->desc.n_region); i++) {2712		struct mt7996_patch_sec *sec;2713		const u8 *dl;2714		u32 len, addr, sec_key_idx, mode = DL_MODE_NEED_RSP;2715 2716		sec = (struct mt7996_patch_sec *)(fw->data + sizeof(*hdr) +2717						  i * sizeof(*sec));2718		if ((be32_to_cpu(sec->type) & PATCH_SEC_TYPE_MASK) !=2719		    PATCH_SEC_TYPE_INFO) {2720			ret = -EINVAL;2721			goto out;2722		}2723 2724		addr = be32_to_cpu(sec->info.addr);2725		len = be32_to_cpu(sec->info.len);2726		sec_key_idx = be32_to_cpu(sec->info.sec_key_idx);2727		dl = fw->data + be32_to_cpu(sec->offs);2728 2729		mode |= mt7996_patch_sec_mode(sec_key_idx);2730 2731		ret = mt76_connac_mcu_init_download(&dev->mt76, addr, len,2732						    mode);2733		if (ret) {2734			dev_err(dev->mt76.dev, "Download request failed\n");2735			goto out;2736		}2737 2738		ret = __mt76_mcu_send_firmware(&dev->mt76, MCU_CMD(FW_SCATTER),2739					       dl, len, 4096);2740		if (ret) {2741			dev_err(dev->mt76.dev, "Failed to send patch\n");2742			goto out;2743		}2744	}2745 2746	ret = mt76_connac_mcu_start_patch(&dev->mt76);2747	if (ret)2748		dev_err(dev->mt76.dev, "Failed to start patch\n");2749 2750out:2751	sem = mt76_connac_mcu_patch_sem_ctrl(&dev->mt76, 0);2752	switch (sem) {2753	case PATCH_REL_SEM_SUCCESS:2754		break;2755	default:2756		ret = -EAGAIN;2757		dev_err(dev->mt76.dev, "Failed to release patch semaphore\n");2758		break;2759	}2760	release_firmware(fw);2761 2762	return ret;2763}2764 2765static int2766mt7996_mcu_send_ram_firmware(struct mt7996_dev *dev,2767			     const struct mt7996_fw_trailer *hdr,2768			     const u8 *data, enum mt7996_ram_type type)2769{2770	int i, offset = 0;2771	u32 override = 0, option = 0;2772 2773	for (i = 0; i < hdr->n_region; i++) {2774		const struct mt7996_fw_region *region;2775		int err;2776		u32 len, addr, mode;2777 2778		region = (const struct mt7996_fw_region *)((const u8 *)hdr -2779			 (hdr->n_region - i) * sizeof(*region));2780		/* DSP and WA use same mode */2781		mode = mt76_connac_mcu_gen_dl_mode(&dev->mt76,2782						   region->feature_set,2783						   type != MT7996_RAM_TYPE_WM);2784		len = le32_to_cpu(region->len);2785		addr = le32_to_cpu(region->addr);2786 2787		if (region->feature_set & FW_FEATURE_OVERRIDE_ADDR)2788			override = addr;2789 2790		err = mt76_connac_mcu_init_download(&dev->mt76, addr, len,2791						    mode);2792		if (err) {2793			dev_err(dev->mt76.dev, "Download request failed\n");2794			return err;2795		}2796 2797		err = __mt76_mcu_send_firmware(&dev->mt76, MCU_CMD(FW_SCATTER),2798					       data + offset, len, 4096);2799		if (err) {2800			dev_err(dev->mt76.dev, "Failed to send firmware.\n");2801			return err;2802		}2803 2804		offset += len;2805	}2806 2807	if (override)2808		option |= FW_START_OVERRIDE;2809 2810	if (type == MT7996_RAM_TYPE_WA)2811		option |= FW_START_WORKING_PDA_CR4;2812	else if (type == MT7996_RAM_TYPE_DSP)2813		option |= FW_START_WORKING_PDA_DSP;2814 2815	return mt76_connac_mcu_start_firmware(&dev->mt76, override, option);2816}2817 2818static int __mt7996_load_ram(struct mt7996_dev *dev, const char *fw_type,2819			     const char *fw_file, enum mt7996_ram_type ram_type)2820{2821	const struct mt7996_fw_trailer *hdr;2822	const struct firmware *fw;2823	int ret;2824 2825	ret = request_firmware(&fw, fw_file, dev->mt76.dev);2826	if (ret)2827		return ret;2828 2829	if (!fw || !fw->data || fw->size < sizeof(*hdr)) {2830		dev_err(dev->mt76.dev, "Invalid firmware\n");2831		ret = -EINVAL;2832		goto out;2833	}2834 2835	hdr = (const void *)(fw->data + fw->size - sizeof(*hdr));2836	dev_info(dev->mt76.dev, "%s Firmware Version: %.10s, Build Time: %.15s\n",2837		 fw_type, hdr->fw_ver, hdr->build_date);2838 2839	ret = mt7996_mcu_send_ram_firmware(dev, hdr, fw->data, ram_type);2840	if (ret) {2841		dev_err(dev->mt76.dev, "Failed to start %s firmware\n", fw_type);2842		goto out;2843	}2844 2845	snprintf(dev->mt76.hw->wiphy->fw_version,2846		 sizeof(dev->mt76.hw->wiphy->fw_version),2847		 "%.10s-%.15s", hdr->fw_ver, hdr->build_date);2848 2849out:2850	release_firmware(fw);2851 2852	return ret;2853}2854 2855static int mt7996_load_ram(struct mt7996_dev *dev)2856{2857	int ret;2858 2859	ret = __mt7996_load_ram(dev, "WM", fw_name(dev, FIRMWARE_WM),2860				MT7996_RAM_TYPE_WM);2861	if (ret)2862		return ret;2863 2864	ret = __mt7996_load_ram(dev, "DSP", fw_name(dev, FIRMWARE_DSP),2865				MT7996_RAM_TYPE_DSP);2866	if (ret)2867		return ret;2868 2869	return __mt7996_load_ram(dev, "WA", fw_name(dev, FIRMWARE_WA),2870				 MT7996_RAM_TYPE_WA);2871}2872 2873static int2874mt7996_firmware_state(struct mt7996_dev *dev, bool wa)2875{2876	u32 state = FIELD_PREP(MT_TOP_MISC_FW_STATE,2877			       wa ? FW_STATE_RDY : FW_STATE_FW_DOWNLOAD);2878 2879	if (!mt76_poll_msec(dev, MT_TOP_MISC, MT_TOP_MISC_FW_STATE,2880			    state, 1000)) {2881		dev_err(dev->mt76.dev, "Timeout for initializing firmware\n");2882		return -EIO;2883	}2884	return 0;2885}2886 2887static int2888mt7996_mcu_restart(struct mt76_dev *dev)2889{2890	struct {2891		u8 __rsv1[4];2892 2893		__le16 tag;2894		__le16 len;2895		u8 power_mode;2896		u8 __rsv2[3];2897	} __packed req = {2898		.tag = cpu_to_le16(UNI_POWER_OFF),2899		.len = cpu_to_le16(sizeof(req) - 4),2900		.power_mode = 1,2901	};2902 2903	return mt76_mcu_send_msg(dev, MCU_WM_UNI_CMD(POWER_CTRL), &req,2904				 sizeof(req), false);2905}2906 2907static int mt7996_load_firmware(struct mt7996_dev *dev)2908{2909	int ret;2910 2911	/* make sure fw is download state */2912	if (mt7996_firmware_state(dev, false)) {2913		/* restart firmware once */2914		mt7996_mcu_restart(&dev->mt76);2915		ret = mt7996_firmware_state(dev, false);2916		if (ret) {2917			dev_err(dev->mt76.dev,2918				"Firmware is not ready for download\n");2919			return ret;2920		}2921	}2922 2923	ret = mt7996_load_patch(dev);2924	if (ret)2925		return ret;2926 2927	ret = mt7996_load_ram(dev);2928	if (ret)2929		return ret;2930 2931	ret = mt7996_firmware_state(dev, true);2932	if (ret)2933		return ret;2934 2935	mt76_queue_tx_cleanup(dev, dev->mt76.q_mcu[MT_MCUQ_FWDL], false);2936 2937	dev_dbg(dev->mt76.dev, "Firmware init done\n");2938 2939	return 0;2940}2941 2942int mt7996_mcu_fw_log_2_host(struct mt7996_dev *dev, u8 type, u8 ctrl)2943{2944	struct {2945		u8 _rsv[4];2946 2947		__le16 tag;2948		__le16 len;2949		u8 ctrl;2950		u8 interval;2951		u8 _rsv2[2];2952	} __packed data = {2953		.tag = cpu_to_le16(UNI_WSYS_CONFIG_FW_LOG_CTRL),2954		.len = cpu_to_le16(sizeof(data) - 4),2955		.ctrl = ctrl,2956	};2957 2958	if (type == MCU_FW_LOG_WA)2959		return mt76_mcu_send_msg(&dev->mt76, MCU_WA_UNI_CMD(WSYS_CONFIG),2960					 &data, sizeof(data), true);2961 2962	return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(WSYS_CONFIG), &data,2963				 sizeof(data), true);2964}2965 2966int mt7996_mcu_fw_dbg_ctrl(struct mt7996_dev *dev, u32 module, u8 level)2967{2968	struct {2969		u8 _rsv[4];2970 2971		__le16 tag;2972		__le16 len;2973		__le32 module_idx;2974		u8 level;2975		u8 _rsv2[3];2976	} data = {2977		.tag = cpu_to_le16(UNI_WSYS_CONFIG_FW_DBG_CTRL),2978		.len = cpu_to_le16(sizeof(data) - 4),2979		.module_idx = cpu_to_le32(module),2980		.level = level,2981	};2982 2983	return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(WSYS_CONFIG), &data,2984				 sizeof(data), false);2985}2986 2987static int mt7996_mcu_set_mwds(struct mt7996_dev *dev, bool enabled)2988{2989	struct {2990		u8 enable;2991		u8 _rsv[3];2992	} __packed req = {2993		.enable = enabled2994	};2995 2996	return mt76_mcu_send_msg(&dev->mt76, MCU_WA_EXT_CMD(MWDS_SUPPORT), &req,2997				 sizeof(req), false);2998}2999 3000static void mt7996_add_rx_airtime_tlv(struct sk_buff *skb, u8 band_idx)3001{3002	struct vow_rx_airtime *req;3003	struct tlv *tlv;3004 3005	tlv = mt7996_mcu_add_uni_tlv(skb, UNI_VOW_RX_AT_AIRTIME_CLR_EN, sizeof(*req));3006	req = (struct vow_rx_airtime *)tlv;3007	req->enable = true;3008	req->band = band_idx;3009 3010	tlv = mt7996_mcu_add_uni_tlv(skb, UNI_VOW_RX_AT_AIRTIME_EN, sizeof(*req));3011	req = (struct vow_rx_airtime *)tlv;3012	req->enable = true;3013	req->band = band_idx;3014}3015 3016static int3017mt7996_mcu_init_rx_airtime(struct mt7996_dev *dev)3018{3019	struct uni_header hdr = {};3020	struct sk_buff *skb;3021	int len, num, i;3022 3023	num = 2 + 2 * (mt7996_band_valid(dev, MT_BAND1) +3024		       mt7996_band_valid(dev, MT_BAND2));3025	len = sizeof(hdr) + num * sizeof(struct vow_rx_airtime);3026	skb = mt76_mcu_msg_alloc(&dev->mt76, NULL, len);3027	if (!skb)3028		return -ENOMEM;3029 3030	skb_put_data(skb, &hdr, sizeof(hdr));3031 3032	for (i = 0; i < __MT_MAX_BAND; i++) {3033		if (mt7996_band_valid(dev, i))3034			mt7996_add_rx_airtime_tlv(skb, i);3035	}3036 3037	return mt76_mcu_skb_send_msg(&dev->mt76, skb,3038				     MCU_WM_UNI_CMD(VOW), true);3039}3040 3041int mt7996_mcu_init_firmware(struct mt7996_dev *dev)3042{3043	int ret;3044 3045	/* force firmware operation mode into normal state,3046	 * which should be set before firmware download stage.3047	 */3048	mt76_wr(dev, MT_SWDEF_MODE, MT_SWDEF_NORMAL_MODE);3049 3050	ret = mt7996_driver_own(dev, 0);3051	if (ret)3052		return ret;3053	/* set driver own for band1 when two hif exist */3054	if (dev->hif2) {3055		ret = mt7996_driver_own(dev, 1);3056		if (ret)3057			return ret;3058	}3059 3060	ret = mt7996_load_firmware(dev);3061	if (ret)3062		return ret;3063 3064	set_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state);3065	ret = mt7996_mcu_fw_log_2_host(dev, MCU_FW_LOG_WM, 0);3066	if (ret)3067		return ret;3068 3069	ret = mt7996_mcu_fw_log_2_host(dev, MCU_FW_LOG_WA, 0);3070	if (ret)3071		return ret;3072 3073	ret = mt7996_mcu_set_mwds(dev, 1);3074	if (ret)3075		return ret;3076 3077	ret = mt7996_mcu_init_rx_airtime(dev);3078	if (ret)3079		return ret;3080 3081	return mt7996_mcu_wa_cmd(dev, MCU_WA_PARAM_CMD(SET),3082				 MCU_WA_PARAM_RED, 0, 0);3083}3084 3085int mt7996_mcu_init(struct mt7996_dev *dev)3086{3087	static const struct mt76_mcu_ops mt7996_mcu_ops = {3088		.headroom = sizeof(struct mt76_connac2_mcu_txd), /* reuse */3089		.mcu_skb_send_msg = mt7996_mcu_send_message,3090		.mcu_parse_response = mt7996_mcu_parse_response,3091	};3092 3093	dev->mt76.mcu_ops = &mt7996_mcu_ops;3094 3095	return mt7996_mcu_init_firmware(dev);3096}3097 3098void mt7996_mcu_exit(struct mt7996_dev *dev)3099{3100	mt7996_mcu_restart(&dev->mt76);3101	if (mt7996_firmware_state(dev, false)) {3102		dev_err(dev->mt76.dev, "Failed to exit mcu\n");3103		goto out;3104	}3105 3106	mt76_wr(dev, MT_TOP_LPCR_HOST_BAND(0), MT_TOP_LPCR_HOST_FW_OWN);3107	if (dev->hif2)3108		mt76_wr(dev, MT_TOP_LPCR_HOST_BAND(1),3109			MT_TOP_LPCR_HOST_FW_OWN);3110out:3111	skb_queue_purge(&dev->mt76.mcu.res_q);3112}3113 3114int mt7996_mcu_set_hdr_trans(struct mt7996_dev *dev, bool hdr_trans)3115{3116	struct {3117		u8 __rsv[4];3118	} __packed hdr;3119	struct hdr_trans_blacklist *req_blacklist;3120	struct hdr_trans_en *req_en;3121	struct sk_buff *skb;3122	struct tlv *tlv;3123	int len = MT7996_HDR_TRANS_MAX_SIZE + sizeof(hdr);3124 3125	skb = mt76_mcu_msg_alloc(&dev->mt76, NULL, len);3126	if (!skb)3127		return -ENOMEM;3128 3129	skb_put_data(skb, &hdr, sizeof(hdr));3130 3131	tlv = mt7996_mcu_add_uni_tlv(skb, UNI_HDR_TRANS_EN, sizeof(*req_en));3132	req_en = (struct hdr_trans_en *)tlv;3133	req_en->enable = hdr_trans;3134 3135	tlv = mt7996_mcu_add_uni_tlv(skb, UNI_HDR_TRANS_VLAN,3136				     sizeof(struct hdr_trans_vlan));3137 3138	if (hdr_trans) {3139		tlv = mt7996_mcu_add_uni_tlv(skb, UNI_HDR_TRANS_BLACKLIST,3140					     sizeof(*req_blacklist));3141		req_blacklist = (struct hdr_trans_blacklist *)tlv;3142		req_blacklist->enable = 1;3143		req_blacklist->type = cpu_to_le16(ETH_P_PAE);3144	}3145 3146	return mt76_mcu_skb_send_msg(&dev->mt76, skb,3147				     MCU_WM_UNI_CMD(RX_HDR_TRANS), true);3148}3149 3150int mt7996_mcu_set_tx(struct mt7996_dev *dev, struct ieee80211_vif *vif)3151{3152#define MCU_EDCA_AC_PARAM	03153#define WMM_AIFS_SET		BIT(0)3154#define WMM_CW_MIN_SET		BIT(1)3155#define WMM_CW_MAX_SET		BIT(2)3156#define WMM_TXOP_SET		BIT(3)3157#define WMM_PARAM_SET		(WMM_AIFS_SET | WMM_CW_MIN_SET | \3158				 WMM_CW_MAX_SET | WMM_TXOP_SET)3159	struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;3160	struct {3161		u8 bss_idx;3162		u8 __rsv[3];3163	} __packed hdr = {3164		.bss_idx = mvif->mt76.idx,3165	};3166	struct sk_buff *skb;3167	int len = sizeof(hdr) + IEEE80211_NUM_ACS * sizeof(struct edca);3168	int ac;3169 3170	skb = mt76_mcu_msg_alloc(&dev->mt76, NULL, len);3171	if (!skb)3172		return -ENOMEM;3173 3174	skb_put_data(skb, &hdr, sizeof(hdr));3175 3176	for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {3177		struct ieee80211_tx_queue_params *q = &mvif->queue_params[ac];3178		struct edca *e;3179		struct tlv *tlv;3180 3181		tlv = mt7996_mcu_add_uni_tlv(skb, MCU_EDCA_AC_PARAM, sizeof(*e));3182 3183		e = (struct edca *)tlv;3184		e->set = WMM_PARAM_SET;3185		e->queue = ac;3186		e->aifs = q->aifs;3187		e->txop = cpu_to_le16(q->txop);3188 3189		if (q->cw_min)3190			e->cw_min = fls(q->cw_min);3191		else3192			e->cw_min = 5;3193 3194		if (q->cw_max)3195			e->cw_max = fls(q->cw_max);3196		else3197			e->cw_max = 10;3198	}3199 3200	return mt76_mcu_skb_send_msg(&dev->mt76, skb,3201				     MCU_WM_UNI_CMD(EDCA_UPDATE), true);3202}3203 3204int mt7996_mcu_set_fcc5_lpn(struct mt7996_dev *dev, int val)3205{3206	struct {3207		u8 _rsv[4];3208 3209		__le16 tag;3210		__le16 len;3211 3212		__le32 ctrl;3213		__le16 min_lpn;3214		u8 rsv[2];3215	} __packed req = {3216		.tag = cpu_to_le16(UNI_RDD_CTRL_SET_TH),3217		.len = cpu_to_le16(sizeof(req) - 4),3218 3219		.ctrl = cpu_to_le32(0x1),3220		.min_lpn = cpu_to_le16(val),3221	};3222 3223	return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(RDD_CTRL),3224				 &req, sizeof(req), true);3225}3226 3227int mt7996_mcu_set_pulse_th(struct mt7996_dev *dev,3228			    const struct mt7996_dfs_pulse *pulse)3229{3230	struct {3231		u8 _rsv[4];3232 3233		__le16 tag;3234		__le16 len;3235 3236		__le32 ctrl;3237 3238		__le32 max_width;		/* us */3239		__le32 max_pwr;			/* dbm */3240		__le32 min_pwr;			/* dbm */3241		__le32 min_stgr_pri;		/* us */3242		__le32 max_stgr_pri;		/* us */3243		__le32 min_cr_pri;		/* us */3244		__le32 max_cr_pri;		/* us */3245	} __packed req = {3246		.tag = cpu_to_le16(UNI_RDD_CTRL_SET_TH),3247		.len = cpu_to_le16(sizeof(req) - 4),3248 3249		.ctrl = cpu_to_le32(0x3),3250 3251#define __req_field(field) .field = cpu_to_le32(pulse->field)3252		__req_field(max_width),3253		__req_field(max_pwr),3254		__req_field(min_pwr),3255		__req_field(min_stgr_pri),3256		__req_field(max_stgr_pri),3257		__req_field(min_cr_pri),3258		__req_field(max_cr_pri),3259#undef __req_field3260	};3261 3262	return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(RDD_CTRL),3263				 &req, sizeof(req), true);3264}3265 3266int mt7996_mcu_set_radar_th(struct mt7996_dev *dev, int index,3267			    const struct mt7996_dfs_pattern *pattern)3268{3269	struct {3270		u8 _rsv[4];3271 3272		__le16 tag;3273		__le16 len;3274 3275		__le32 ctrl;3276		__le16 radar_type;3277 3278		u8 enb;3279		u8 stgr;3280		u8 min_crpn;3281		u8 max_crpn;3282		u8 min_crpr;3283		u8 min_pw;3284		__le32 min_pri;3285		__le32 max_pri;3286		u8 max_pw;3287		u8 min_crbn;3288		u8 max_crbn;3289		u8 min_stgpn;3290		u8 max_stgpn;3291		u8 min_stgpr;3292		u8 rsv[2];3293		__le32 min_stgpr_diff;3294	} __packed req = {3295		.tag = cpu_to_le16(UNI_RDD_CTRL_SET_TH),3296		.len = cpu_to_le16(sizeof(req) - 4),3297 3298		.ctrl = cpu_to_le32(0x2),3299		.radar_type = cpu_to_le16(index),3300 3301#define __req_field_u8(field) .field = pattern->field3302#define __req_field_u32(field) .field = cpu_to_le32(pattern->field)3303		__req_field_u8(enb),3304		__req_field_u8(stgr),3305		__req_field_u8(min_crpn),3306		__req_field_u8(max_crpn),3307		__req_field_u8(min_crpr),3308		__req_field_u8(min_pw),3309		__req_field_u32(min_pri),3310		__req_field_u32(max_pri),3311		__req_field_u8(max_pw),3312		__req_field_u8(min_crbn),3313		__req_field_u8(max_crbn),3314		__req_field_u8(min_stgpn),3315		__req_field_u8(max_stgpn),3316		__req_field_u8(min_stgpr),3317		__req_field_u32(min_stgpr_diff),3318#undef __req_field_u83319#undef __req_field_u323320	};3321 3322	return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(RDD_CTRL),3323				 &req, sizeof(req), true);3324}3325 3326static int3327mt7996_mcu_background_chain_ctrl(struct mt7996_phy *phy,3328				 struct cfg80211_chan_def *chandef,3329				 int cmd)3330{3331	struct mt7996_dev *dev = phy->dev;3332	struct mt76_phy *mphy = phy->mt76;3333	struct ieee80211_channel *chan = mphy->chandef.chan;3334	int freq = mphy->chandef.center_freq1;3335	struct mt7996_mcu_background_chain_ctrl req = {3336		.tag = cpu_to_le16(0),3337		.len = cpu_to_le16(sizeof(req) - 4),3338		.monitor_scan_type = 2, /* simple rx */3339	};3340 3341	if (!chandef && cmd != CH_SWITCH_BACKGROUND_SCAN_STOP)3342		return -EINVAL;3343 3344	if (!cfg80211_chandef_valid(&mphy->chandef))3345		return -EINVAL;3346 3347	switch (cmd) {3348	case CH_SWITCH_BACKGROUND_SCAN_START: {3349		req.chan = chan->hw_value;3350		req.central_chan = ieee80211_frequency_to_channel(freq);3351		req.bw = mt76_connac_chan_bw(&mphy->chandef);3352		req.monitor_chan = chandef->chan->hw_value;3353		req.monitor_central_chan =3354			ieee80211_frequency_to_channel(chandef->center_freq1);3355		req.monitor_bw = mt76_connac_chan_bw(chandef);3356		req.band_idx = phy->mt76->band_idx;3357		req.scan_mode = 1;3358		break;3359	}3360	case CH_SWITCH_BACKGROUND_SCAN_RUNNING:3361		req.monitor_chan = chandef->chan->hw_value;3362		req.monitor_central_chan =3363			ieee80211_frequency_to_channel(chandef->center_freq1);3364		req.band_idx = phy->mt76->band_idx;3365		req.scan_mode = 2;3366		break;3367	case CH_SWITCH_BACKGROUND_SCAN_STOP:3368		req.chan = chan->hw_value;3369		req.central_chan = ieee80211_frequency_to_channel(freq);3370		req.bw = mt76_connac_chan_bw(&mphy->chandef);3371		req.tx_stream = hweight8(mphy->antenna_mask);3372		req.rx_stream = mphy->antenna_mask;3373		break;3374	default:3375		return -EINVAL;3376	}3377	req.band = chandef ? chandef->chan->band == NL80211_BAND_5GHZ : 1;3378 3379	return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(OFFCH_SCAN_CTRL),3380				 &req, sizeof(req), false);3381}3382 3383int mt7996_mcu_rdd_background_enable(struct mt7996_phy *phy,3384				     struct cfg80211_chan_def *chandef)3385{3386	struct mt7996_dev *dev = phy->dev;3387	int err, region;3388 3389	if (!chandef) { /* disable offchain */3390		err = mt7996_mcu_rdd_cmd(dev, RDD_STOP, MT_RX_SEL2,3391					 0, 0);3392		if (err)3393			return err;3394 3395		return mt7996_mcu_background_chain_ctrl(phy, NULL,3396				CH_SWITCH_BACKGROUND_SCAN_STOP);3397	}3398 3399	err = mt7996_mcu_background_chain_ctrl(phy, chandef,3400					       CH_SWITCH_BACKGROUND_SCAN_START);3401	if (err)3402		return err;3403 3404	switch (dev->mt76.region) {3405	case NL80211_DFS_ETSI:3406		region = 0;3407		break;3408	case NL80211_DFS_JP:3409		region = 2;3410		break;3411	case NL80211_DFS_FCC:3412	default:3413		region = 1;3414		break;3415	}3416 3417	return mt7996_mcu_rdd_cmd(dev, RDD_START, MT_RX_SEL2,3418				  0, region);3419}3420 3421int mt7996_mcu_set_chan_info(struct mt7996_phy *phy, u16 tag)3422{3423	static const u8 ch_band[] = {3424		[NL80211_BAND_2GHZ] = 0,3425		[NL80211_BAND_5GHZ] = 1,3426		[NL80211_BAND_6GHZ] = 2,3427	};3428	struct mt7996_dev *dev = phy->dev;3429	struct cfg80211_chan_def *chandef = &phy->mt76->chandef;3430	int freq1 = chandef->center_freq1;3431	u8 band_idx = phy->mt76->band_idx;3432	struct {3433		/* fixed field */3434		u8 __rsv[4];3435 3436		__le16 tag;3437		__le16 len;3438		u8 control_ch;3439		u8 center_ch;3440		u8 bw;3441		u8 tx_path_num;3442		u8 rx_path;	/* mask or num */3443		u8 switch_reason;3444		u8 band_idx;3445		u8 center_ch2;	/* for 80+80 only */3446		__le16 cac_case;3447		u8 channel_band;3448		u8 rsv0;3449		__le32 outband_freq;3450		u8 txpower_drop;3451		u8 ap_bw;3452		u8 ap_center_ch;3453		u8 rsv1[53];3454	} __packed req = {3455		.tag = cpu_to_le16(tag),3456		.len = cpu_to_le16(sizeof(req) - 4),3457		.control_ch = chandef->chan->hw_value,3458		.center_ch = ieee80211_frequency_to_channel(freq1),3459		.bw = mt76_connac_chan_bw(chandef),3460		.tx_path_num = hweight16(phy->mt76->chainmask),3461		.rx_path = mt7996_rx_chainmask(phy) >> dev->chainshift[band_idx],3462		.band_idx = band_idx,3463		.channel_band = ch_band[chandef->chan->band],3464	};3465 3466	if (phy->mt76->hw->conf.flags & IEEE80211_CONF_MONITOR)3467		req.switch_reason = CH_SWITCH_NORMAL;3468	else if (phy->mt76->offchannel ||3469		 phy->mt76->hw->conf.flags & IEEE80211_CONF_IDLE)3470		req.switch_reason = CH_SWITCH_SCAN_BYPASS_DPD;3471	else if (!cfg80211_reg_can_beacon(phy->mt76->hw->wiphy, chandef,3472					  NL80211_IFTYPE_AP))3473		req.switch_reason = CH_SWITCH_DFS;3474	else3475		req.switch_reason = CH_SWITCH_NORMAL;3476 3477	if (tag == UNI_CHANNEL_SWITCH)3478		req.rx_path = hweight8(req.rx_path);3479 3480	if (chandef->width == NL80211_CHAN_WIDTH_80P80) {3481		int freq2 = chandef->center_freq2;3482 3483		req.center_ch2 = ieee80211_frequency_to_channel(freq2);3484	}3485 3486	return mt76_mcu_send_msg(&dev->mt76, MCU_WMWA_UNI_CMD(CHANNEL_SWITCH),3487				 &req, sizeof(req), true);3488}3489 3490static int mt7996_mcu_set_eeprom_flash(struct mt7996_dev *dev)3491{3492#define MAX_PAGE_IDX_MASK	GENMASK(7, 5)3493#define PAGE_IDX_MASK		GENMASK(4, 2)3494#define PER_PAGE_SIZE		0x4003495	struct mt7996_mcu_eeprom req = {3496		.tag = cpu_to_le16(UNI_EFUSE_BUFFER_MODE),3497		.buffer_mode = EE_MODE_BUFFER3498	};3499	u16 eeprom_size = MT7996_EEPROM_SIZE;3500	u8 total = DIV_ROUND_UP(eeprom_size, PER_PAGE_SIZE);3501	u8 *eep = (u8 *)dev->mt76.eeprom.data;3502	int eep_len, i;3503 3504	for (i = 0; i < total; i++, eep += eep_len) {3505		struct sk_buff *skb;3506		int ret, msg_len;3507 3508		if (i == total - 1 && !!(eeprom_size % PER_PAGE_SIZE))3509			eep_len = eeprom_size % PER_PAGE_SIZE;3510		else3511			eep_len = PER_PAGE_SIZE;3512 3513		msg_len = sizeof(req) + eep_len;3514		skb = mt76_mcu_msg_alloc(&dev->mt76, NULL, msg_len);3515		if (!skb)3516			return -ENOMEM;3517 3518		req.len = cpu_to_le16(msg_len - 4);3519		req.format = FIELD_PREP(MAX_PAGE_IDX_MASK, total - 1) |3520			     FIELD_PREP(PAGE_IDX_MASK, i) | EE_FORMAT_WHOLE;3521		req.buf_len = cpu_to_le16(eep_len);3522 3523		skb_put_data(skb, &req, sizeof(req));3524		skb_put_data(skb, eep, eep_len);3525 3526		ret = mt76_mcu_skb_send_msg(&dev->mt76, skb,3527					    MCU_WM_UNI_CMD(EFUSE_CTRL), true);3528		if (ret)3529			return ret;3530	}3531 3532	return 0;3533}3534 3535int mt7996_mcu_set_eeprom(struct mt7996_dev *dev)3536{3537	struct mt7996_mcu_eeprom req = {3538		.tag = cpu_to_le16(UNI_EFUSE_BUFFER_MODE),3539		.len = cpu_to_le16(sizeof(req) - 4),3540		.buffer_mode = EE_MODE_EFUSE,3541		.format = EE_FORMAT_WHOLE3542	};3543 3544	if (dev->flash_mode)3545		return mt7996_mcu_set_eeprom_flash(dev);3546 3547	return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(EFUSE_CTRL),3548				 &req, sizeof(req), true);3549}3550 3551int mt7996_mcu_get_eeprom(struct mt7996_dev *dev, u32 offset)3552{3553	struct {3554		u8 _rsv[4];3555 3556		__le16 tag;3557		__le16 len;3558		__le32 addr;3559		__le32 valid;3560		u8 data[16];3561	} __packed req = {3562		.tag = cpu_to_le16(UNI_EFUSE_ACCESS),3563		.len = cpu_to_le16(sizeof(req) - 4),3564		.addr = cpu_to_le32(round_down(offset,3565				    MT7996_EEPROM_BLOCK_SIZE)),3566	};3567	struct sk_buff *skb;3568	bool valid;3569	int ret;3570 3571	ret = mt76_mcu_send_and_get_msg(&dev->mt76,3572					MCU_WM_UNI_CMD_QUERY(EFUSE_CTRL),3573					&req, sizeof(req), true, &skb);3574	if (ret)3575		return ret;3576 3577	valid = le32_to_cpu(*(__le32 *)(skb->data + 16));3578	if (valid) {3579		u32 addr = le32_to_cpu(*(__le32 *)(skb->data + 12));3580		u8 *buf = (u8 *)dev->mt76.eeprom.data + addr;3581 3582		skb_pull(skb, 48);3583		memcpy(buf, skb->data, MT7996_EEPROM_BLOCK_SIZE);3584	}3585 3586	dev_kfree_skb(skb);3587 3588	return 0;3589}3590 3591int mt7996_mcu_get_eeprom_free_block(struct mt7996_dev *dev, u8 *block_num)3592{3593	struct {3594		u8 _rsv[4];3595 3596		__le16 tag;3597		__le16 len;3598		u8 num;3599		u8 version;3600		u8 die_idx;3601		u8 _rsv2;3602	} __packed req = {3603		.tag = cpu_to_le16(UNI_EFUSE_FREE_BLOCK),3604		.len = cpu_to_le16(sizeof(req) - 4),3605		.version = 2,3606	};3607	struct sk_buff *skb;3608	int ret;3609 3610	ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_WM_UNI_CMD_QUERY(EFUSE_CTRL), &req,3611					sizeof(req), true, &skb);3612	if (ret)3613		return ret;3614 3615	*block_num = *(u8 *)(skb->data + 8);3616	dev_kfree_skb(skb);3617 3618	return 0;3619}3620 3621int mt7996_mcu_get_chip_config(struct mt7996_dev *dev, u32 *cap)3622{3623#define NIC_CAP	33624#define UNI_EVENT_CHIP_CONFIG_EFUSE_VERSION	0x213625	struct {3626		u8 _rsv[4];3627 3628		__le16 tag;3629		__le16 len;3630	} __packed req = {3631		.tag = cpu_to_le16(NIC_CAP),3632		.len = cpu_to_le16(sizeof(req) - 4),3633	};3634	struct sk_buff *skb;3635	u8 *buf;3636	int ret;3637 3638	ret = mt76_mcu_send_and_get_msg(&dev->mt76,3639					MCU_WM_UNI_CMD_QUERY(CHIP_CONFIG), &req,3640					sizeof(req), true, &skb);3641	if (ret)3642		return ret;3643 3644	/* fixed field */3645	skb_pull(skb, 4);3646 3647	buf = skb->data;3648	while (buf - skb->data < skb->len) {3649		struct tlv *tlv = (struct tlv *)buf;3650 3651		switch (le16_to_cpu(tlv->tag)) {3652		case UNI_EVENT_CHIP_CONFIG_EFUSE_VERSION:3653			*cap = le32_to_cpu(*(__le32 *)(buf + sizeof(*tlv)));3654			break;3655		default:3656			break;3657		}3658 3659		buf += le16_to_cpu(tlv->len);3660	}3661 3662	dev_kfree_skb(skb);3663 3664	return 0;3665}3666 3667int mt7996_mcu_get_chan_mib_info(struct mt7996_phy *phy, bool chan_switch)3668{3669	struct {3670		struct {3671			u8 band;3672			u8 __rsv[3];3673		} hdr;3674		struct {3675			__le16 tag;3676			__le16 len;3677			__le32 offs;3678		} data[4];3679	} __packed req = {3680		.hdr.band = phy->mt76->band_idx,3681	};3682	/* strict order */3683	static const u32 offs[] = {3684		UNI_MIB_TX_TIME,3685		UNI_MIB_RX_TIME,3686		UNI_MIB_OBSS_AIRTIME,3687		UNI_MIB_NON_WIFI_TIME,3688	};3689	struct mt76_channel_state *state = phy->mt76->chan_state;3690	struct mt76_channel_state *state_ts = &phy->state_ts;3691	struct mt7996_dev *dev = phy->dev;3692	struct mt7996_mcu_mib *res;3693	struct sk_buff *skb;3694	int i, ret;3695 3696	for (i = 0; i < 4; i++) {3697		req.data[i].tag = cpu_to_le16(UNI_CMD_MIB_DATA);3698		req.data[i].len = cpu_to_le16(sizeof(req.data[i]));3699		req.data[i].offs = cpu_to_le32(offs[i]);3700	}3701 3702	ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_WM_UNI_CMD_QUERY(GET_MIB_INFO),3703					&req, sizeof(req), true, &skb);3704	if (ret)3705		return ret;3706 3707	skb_pull(skb, sizeof(req.hdr));3708 3709	res = (struct mt7996_mcu_mib *)(skb->data);3710 3711	if (chan_switch)3712		goto out;3713 3714#define __res_u64(s) le64_to_cpu(res[s].data)3715	state->cc_tx += __res_u64(1) - state_ts->cc_tx;3716	state->cc_bss_rx += __res_u64(2) - state_ts->cc_bss_rx;3717	state->cc_rx += __res_u64(2) + __res_u64(3) - state_ts->cc_rx;3718	state->cc_busy += __res_u64(0) + __res_u64(1) + __res_u64(2) + __res_u64(3) -3719			  state_ts->cc_busy;3720 3721out:3722	state_ts->cc_tx = __res_u64(1);3723	state_ts->cc_bss_rx = __res_u64(2);3724	state_ts->cc_rx = __res_u64(2) + __res_u64(3);3725	state_ts->cc_busy = __res_u64(0) + __res_u64(1) + __res_u64(2) + __res_u64(3);3726#undef __res_u643727 3728	dev_kfree_skb(skb);3729 3730	return 0;3731}3732 3733int mt7996_mcu_get_temperature(struct mt7996_phy *phy)3734{3735#define TEMPERATURE_QUERY 03736#define GET_TEMPERATURE 03737	struct {3738		u8 _rsv[4];3739 3740		__le16 tag;3741		__le16 len;3742 3743		u8 rsv1;3744		u8 action;3745		u8 band_idx;3746		u8 rsv2;3747	} req = {3748		.tag = cpu_to_le16(TEMPERATURE_QUERY),3749		.len = cpu_to_le16(sizeof(req) - 4),3750		.action = GET_TEMPERATURE,3751		.band_idx = phy->mt76->band_idx,3752	};3753	struct mt7996_mcu_thermal {3754		u8 _rsv[4];3755 3756		__le16 tag;3757		__le16 len;3758 3759		__le32 rsv;3760		__le32 temperature;3761	} __packed * res;3762	struct sk_buff *skb;3763	int ret;3764	u32 temp;3765 3766	ret = mt76_mcu_send_and_get_msg(&phy->dev->mt76, MCU_WM_UNI_CMD(THERMAL),3767					&req, sizeof(req), true, &skb);3768	if (ret)3769		return ret;3770 3771	res = (void *)skb->data;3772	temp = le32_to_cpu(res->temperature);3773	dev_kfree_skb(skb);3774 3775	return temp;3776}3777 3778int mt7996_mcu_set_thermal_throttling(struct mt7996_phy *phy, u8 state)3779{3780	struct {3781		u8 _rsv[4];3782 3783		__le16 tag;3784		__le16 len;3785 3786		struct mt7996_mcu_thermal_ctrl ctrl;3787	} __packed req = {3788		.tag = cpu_to_le16(UNI_CMD_THERMAL_PROTECT_DUTY_CONFIG),3789		.len = cpu_to_le16(sizeof(req) - 4),3790		.ctrl = {3791			.band_idx = phy->mt76->band_idx,3792		},3793	};3794	int level, ret;3795 3796	/* set duty cycle and level */3797	for (level = 0; level < 4; level++) {3798		req.ctrl.duty.duty_level = level;3799		req.ctrl.duty.duty_cycle = state;3800		state /= 2;3801 3802		ret = mt76_mcu_send_msg(&phy->dev->mt76, MCU_WM_UNI_CMD(THERMAL),3803					&req, sizeof(req), false);3804		if (ret)3805			return ret;3806	}3807 3808	return 0;3809}3810 3811int mt7996_mcu_set_thermal_protect(struct mt7996_phy *phy, bool enable)3812{3813#define SUSTAIN_PERIOD		103814	struct {3815		u8 _rsv[4];3816 3817		__le16 tag;3818		__le16 len;3819 3820		struct mt7996_mcu_thermal_ctrl ctrl;3821		struct mt7996_mcu_thermal_enable enable;3822	} __packed req = {3823		.len = cpu_to_le16(sizeof(req) - 4 - sizeof(req.enable)),3824		.ctrl = {3825			.band_idx = phy->mt76->band_idx,3826			.type.protect_type = 1,3827			.type.trigger_type = 1,3828		},3829	};3830	int ret;3831 3832	req.tag = cpu_to_le16(UNI_CMD_THERMAL_PROTECT_DISABLE);3833 3834	ret = mt76_mcu_send_msg(&phy->dev->mt76, MCU_WM_UNI_CMD(THERMAL),3835				&req, sizeof(req) - sizeof(req.enable), false);3836	if (ret || !enable)3837		return ret;3838 3839	/* set high-temperature trigger threshold */3840	req.tag = cpu_to_le16(UNI_CMD_THERMAL_PROTECT_ENABLE);3841	req.enable.restore_temp = cpu_to_le32(phy->throttle_temp[0]);3842	req.enable.trigger_temp = cpu_to_le32(phy->throttle_temp[1]);3843	req.enable.sustain_time = cpu_to_le16(SUSTAIN_PERIOD);3844 3845	req.len = cpu_to_le16(sizeof(req) - 4);3846 3847	return mt76_mcu_send_msg(&phy->dev->mt76, MCU_WM_UNI_CMD(THERMAL),3848				 &req, sizeof(req), false);3849}3850 3851int mt7996_mcu_set_ser(struct mt7996_dev *dev, u8 action, u8 val, u8 band)3852{3853	struct {3854		u8 rsv[4];3855 3856		__le16 tag;3857		__le16 len;3858 3859		union {3860			struct {3861				__le32 mask;3862			} __packed set;3863 3864			struct {3865				u8 method;3866				u8 band;3867				u8 rsv2[2];3868			} __packed trigger;3869		};3870	} __packed req = {3871		.tag = cpu_to_le16(action),3872		.len = cpu_to_le16(sizeof(req) - 4),3873	};3874 3875	switch (action) {3876	case UNI_CMD_SER_SET:3877		req.set.mask = cpu_to_le32(val);3878		break;3879	case UNI_CMD_SER_TRIGGER:3880		req.trigger.method = val;3881		req.trigger.band = band;3882		break;3883	default:3884		return -EINVAL;3885	}3886 3887	return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(SER),3888				 &req, sizeof(req), false);3889}3890 3891int mt7996_mcu_set_txbf(struct mt7996_dev *dev, u8 action)3892{3893#define MT7996_BF_MAX_SIZE	sizeof(union bf_tag_tlv)3894#define BF_PROCESSING	43895	struct uni_header hdr;3896	struct sk_buff *skb;3897	struct tlv *tlv;3898	int len = sizeof(hdr) + MT7996_BF_MAX_SIZE;3899 3900	memset(&hdr, 0, sizeof(hdr));3901 3902	skb = mt76_mcu_msg_alloc(&dev->mt76, NULL, len);3903	if (!skb)3904		return -ENOMEM;3905 3906	skb_put_data(skb, &hdr, sizeof(hdr));3907 3908	switch (action) {3909	case BF_SOUNDING_ON: {3910		struct bf_sounding_on *req_snd_on;3911 3912		tlv = mt7996_mcu_add_uni_tlv(skb, action, sizeof(*req_snd_on));3913		req_snd_on = (struct bf_sounding_on *)tlv;3914		req_snd_on->snd_mode = BF_PROCESSING;3915		break;3916	}3917	case BF_HW_EN_UPDATE: {3918		struct bf_hw_en_status_update *req_hw_en;3919 3920		tlv = mt7996_mcu_add_uni_tlv(skb, action, sizeof(*req_hw_en));3921		req_hw_en = (struct bf_hw_en_status_update *)tlv;3922		req_hw_en->ebf = true;3923		req_hw_en->ibf = dev->ibf;3924		break;3925	}3926	case BF_MOD_EN_CTRL: {3927		struct bf_mod_en_ctrl *req_mod_en;3928 3929		tlv = mt7996_mcu_add_uni_tlv(skb, action, sizeof(*req_mod_en));3930		req_mod_en = (struct bf_mod_en_ctrl *)tlv;3931		req_mod_en->bf_num = mt7996_band_valid(dev, MT_BAND2) ? 3 : 2;3932		req_mod_en->bf_bitmap = mt7996_band_valid(dev, MT_BAND2) ?3933					GENMASK(2, 0) : GENMASK(1, 0);3934		break;3935	}3936	default:3937		return -EINVAL;3938	}3939 3940	return mt76_mcu_skb_send_msg(&dev->mt76, skb, MCU_WM_UNI_CMD(BF), true);3941}3942 3943static int3944mt7996_mcu_enable_obss_spr(struct mt7996_phy *phy, u16 action, u8 val)3945{3946	struct mt7996_dev *dev = phy->dev;3947	struct {3948		u8 band_idx;3949		u8 __rsv[3];3950 3951		__le16 tag;3952		__le16 len;3953 3954		__le32 val;3955	} __packed req = {3956		.band_idx = phy->mt76->band_idx,3957		.tag = cpu_to_le16(action),3958		.len = cpu_to_le16(sizeof(req) - 4),3959		.val = cpu_to_le32(val),3960	};3961 3962	return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(SR),3963				 &req, sizeof(req), true);3964}3965 3966static int3967mt7996_mcu_set_obss_spr_pd(struct mt7996_phy *phy,3968			   struct ieee80211_he_obss_pd *he_obss_pd)3969{3970	struct mt7996_dev *dev = phy->dev;3971	u8 max_th = 82, non_srg_max_th = 62;3972	struct {3973		u8 band_idx;3974		u8 __rsv[3];3975 3976		__le16 tag;3977		__le16 len;3978 3979		u8 pd_th_non_srg;3980		u8 pd_th_srg;3981		u8 period_offs;3982		u8 rcpi_src;3983		__le16 obss_pd_min;3984		__le16 obss_pd_min_srg;3985		u8 resp_txpwr_mode;3986		u8 txpwr_restrict_mode;3987		u8 txpwr_ref;3988		u8 __rsv2[3];3989	} __packed req = {3990		.band_idx = phy->mt76->band_idx,3991		.tag = cpu_to_le16(UNI_CMD_SR_SET_PARAM),3992		.len = cpu_to_le16(sizeof(req) - 4),3993		.obss_pd_min = cpu_to_le16(max_th),3994		.obss_pd_min_srg = cpu_to_le16(max_th),3995		.txpwr_restrict_mode = 2,3996		.txpwr_ref = 213997	};3998	int ret;3999 4000	/* disable firmware dynamical PD asjustment */4001	ret = mt7996_mcu_enable_obss_spr(phy, UNI_CMD_SR_ENABLE_DPD, false);4002	if (ret)4003		return ret;4004 4005	if (he_obss_pd->sr_ctrl &4006	    IEEE80211_HE_SPR_NON_SRG_OBSS_PD_SR_DISALLOWED)4007		req.pd_th_non_srg = max_th;4008	else if (he_obss_pd->sr_ctrl & IEEE80211_HE_SPR_NON_SRG_OFFSET_PRESENT)4009		req.pd_th_non_srg  = max_th - he_obss_pd->non_srg_max_offset;4010	else4011		req.pd_th_non_srg  = non_srg_max_th;4012 4013	if (he_obss_pd->sr_ctrl & IEEE80211_HE_SPR_SRG_INFORMATION_PRESENT)4014		req.pd_th_srg = max_th - he_obss_pd->max_offset;4015 4016	return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(SR),4017				 &req, sizeof(req), true);4018}4019 4020static int4021mt7996_mcu_set_obss_spr_siga(struct mt7996_phy *phy, struct ieee80211_vif *vif,4022			     struct ieee80211_he_obss_pd *he_obss_pd)4023{4024	struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;4025	struct mt7996_dev *dev = phy->dev;4026	u8 omac = mvif->mt76.omac_idx;4027	struct {4028		u8 band_idx;4029		u8 __rsv[3];4030 4031		__le16 tag;4032		__le16 len;4033 4034		u8 omac;4035		u8 __rsv2[3];4036		u8 flag[20];4037	} __packed req = {4038		.band_idx = phy->mt76->band_idx,4039		.tag = cpu_to_le16(UNI_CMD_SR_SET_SIGA),4040		.len = cpu_to_le16(sizeof(req) - 4),4041		.omac = omac > HW_BSSID_MAX ? omac - 12 : omac,4042	};4043	int ret;4044 4045	if (he_obss_pd->sr_ctrl & IEEE80211_HE_SPR_HESIGA_SR_VAL15_ALLOWED)4046		req.flag[req.omac] = 0xf;4047	else4048		return 0;4049 4050	/* switch to normal AP mode */4051	ret = mt7996_mcu_enable_obss_spr(phy, UNI_CMD_SR_ENABLE_MODE, 0);4052	if (ret)4053		return ret;4054 4055	return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(SR),4056				 &req, sizeof(req), true);4057}4058 4059static int4060mt7996_mcu_set_obss_spr_bitmap(struct mt7996_phy *phy,4061			       struct ieee80211_he_obss_pd *he_obss_pd)4062{4063	struct mt7996_dev *dev = phy->dev;4064	struct {4065		u8 band_idx;4066		u8 __rsv[3];4067 4068		__le16 tag;4069		__le16 len;4070 4071		__le32 color_l[2];4072		__le32 color_h[2];4073		__le32 bssid_l[2];4074		__le32 bssid_h[2];4075	} __packed req = {4076		.band_idx = phy->mt76->band_idx,4077		.tag = cpu_to_le16(UNI_CMD_SR_SET_SRG_BITMAP),4078		.len = cpu_to_le16(sizeof(req) - 4),4079	};4080	u32 bitmap;4081 4082	memcpy(&bitmap, he_obss_pd->bss_color_bitmap, sizeof(bitmap));4083	req.color_l[req.band_idx] = cpu_to_le32(bitmap);4084 4085	memcpy(&bitmap, he_obss_pd->bss_color_bitmap + 4, sizeof(bitmap));4086	req.color_h[req.band_idx] = cpu_to_le32(bitmap);4087 4088	memcpy(&bitmap, he_obss_pd->partial_bssid_bitmap, sizeof(bitmap));4089	req.bssid_l[req.band_idx] = cpu_to_le32(bitmap);4090 4091	memcpy(&bitmap, he_obss_pd->partial_bssid_bitmap + 4, sizeof(bitmap));4092	req.bssid_h[req.band_idx] = cpu_to_le32(bitmap);4093 4094	return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(SR), &req,4095				 sizeof(req), true);4096}4097 4098int mt7996_mcu_add_obss_spr(struct mt7996_phy *phy, struct ieee80211_vif *vif,4099			    struct ieee80211_he_obss_pd *he_obss_pd)4100{4101	int ret;4102 4103	/* enable firmware scene detection algorithms */4104	ret = mt7996_mcu_enable_obss_spr(phy, UNI_CMD_SR_ENABLE_SD,4105					 sr_scene_detect);4106	if (ret)4107		return ret;4108 4109	/* firmware dynamically adjusts PD threshold so skip manual control */4110	if (sr_scene_detect && !he_obss_pd->enable)4111		return 0;4112 4113	/* enable spatial reuse */4114	ret = mt7996_mcu_enable_obss_spr(phy, UNI_CMD_SR_ENABLE,4115					 he_obss_pd->enable);4116	if (ret)4117		return ret;4118 4119	if (sr_scene_detect || !he_obss_pd->enable)4120		return 0;4121 4122	ret = mt7996_mcu_enable_obss_spr(phy, UNI_CMD_SR_ENABLE_TX, true);4123	if (ret)4124		return ret;4125 4126	/* set SRG/non-SRG OBSS PD threshold */4127	ret = mt7996_mcu_set_obss_spr_pd(phy, he_obss_pd);4128	if (ret)4129		return ret;4130 4131	/* Set SR prohibit */4132	ret = mt7996_mcu_set_obss_spr_siga(phy, vif, he_obss_pd);4133	if (ret)4134		return ret;4135 4136	/* set SRG BSS color/BSSID bitmap */4137	return mt7996_mcu_set_obss_spr_bitmap(phy, he_obss_pd);4138}4139 4140int mt7996_mcu_update_bss_color(struct mt7996_dev *dev, struct ieee80211_vif *vif,4141				struct cfg80211_he_bss_color *he_bss_color)4142{4143	int len = sizeof(struct bss_req_hdr) + sizeof(struct bss_color_tlv);4144	struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;4145	struct bss_color_tlv *bss_color;4146	struct sk_buff *skb;4147	struct tlv *tlv;4148 4149	skb = __mt7996_mcu_alloc_bss_req(&dev->mt76, &mvif->mt76, len);4150	if (IS_ERR(skb))4151		return PTR_ERR(skb);4152 4153	tlv = mt76_connac_mcu_add_tlv(skb, UNI_BSS_INFO_BSS_COLOR,4154				      sizeof(*bss_color));4155	bss_color = (struct bss_color_tlv *)tlv;4156	bss_color->enable = he_bss_color->enabled;4157	bss_color->color = he_bss_color->color;4158 4159	return mt76_mcu_skb_send_msg(&dev->mt76, skb,4160				     MCU_WMWA_UNI_CMD(BSS_INFO_UPDATE), true);4161}4162 4163#define TWT_AGRT_TRIGGER	BIT(0)4164#define TWT_AGRT_ANNOUNCE	BIT(1)4165#define TWT_AGRT_PROTECT	BIT(2)4166 4167int mt7996_mcu_twt_agrt_update(struct mt7996_dev *dev,4168			       struct mt7996_vif *mvif,4169			       struct mt7996_twt_flow *flow,4170			       int cmd)4171{4172	struct {4173		/* fixed field */4174		u8 bss;4175		u8 _rsv[3];4176 4177		__le16 tag;4178		__le16 len;4179		u8 tbl_idx;4180		u8 cmd;4181		u8 own_mac_idx;4182		u8 flowid; /* 0xff for group id */4183		__le16 peer_id; /* specify the peer_id (msb=0)4184				 * or group_id (msb=1)4185				 */4186		u8 duration; /* 256 us */4187		u8 bss_idx;4188		__le64 start_tsf;4189		__le16 mantissa;4190		u8 exponent;4191		u8 is_ap;4192		u8 agrt_params;4193		u8 __rsv2[23];4194	} __packed req = {4195		.tag = cpu_to_le16(UNI_CMD_TWT_ARGT_UPDATE),4196		.len = cpu_to_le16(sizeof(req) - 4),4197		.tbl_idx = flow->table_id,4198		.cmd = cmd,4199		.own_mac_idx = mvif->mt76.omac_idx,4200		.flowid = flow->id,4201		.peer_id = cpu_to_le16(flow->wcid),4202		.duration = flow->duration,4203		.bss = mvif->mt76.idx,4204		.bss_idx = mvif->mt76.idx,4205		.start_tsf = cpu_to_le64(flow->tsf),4206		.mantissa = flow->mantissa,4207		.exponent = flow->exp,4208		.is_ap = true,4209	};4210 4211	if (flow->protection)4212		req.agrt_params |= TWT_AGRT_PROTECT;4213	if (!flow->flowtype)4214		req.agrt_params |= TWT_AGRT_ANNOUNCE;4215	if (flow->trigger)4216		req.agrt_params |= TWT_AGRT_TRIGGER;4217 4218	return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(TWT),4219				 &req, sizeof(req), true);4220}4221 4222int mt7996_mcu_set_rts_thresh(struct mt7996_phy *phy, u32 val)4223{4224	struct {4225		u8 band_idx;4226		u8 _rsv[3];4227 4228		__le16 tag;4229		__le16 len;4230		__le32 len_thresh;4231		__le32 pkt_thresh;4232	} __packed req = {4233		.band_idx = phy->mt76->band_idx,4234		.tag = cpu_to_le16(UNI_BAND_CONFIG_RTS_THRESHOLD),4235		.len = cpu_to_le16(sizeof(req) - 4),4236		.len_thresh = cpu_to_le32(val),4237		.pkt_thresh = cpu_to_le32(0x2),4238	};4239 4240	return mt76_mcu_send_msg(&phy->dev->mt76, MCU_WM_UNI_CMD(BAND_CONFIG),4241				 &req, sizeof(req), true);4242}4243 4244int mt7996_mcu_set_radio_en(struct mt7996_phy *phy, bool enable)4245{4246	struct {4247		u8 band_idx;4248		u8 _rsv[3];4249 4250		__le16 tag;4251		__le16 len;4252		u8 enable;4253		u8 _rsv2[3];4254	} __packed req = {4255		.band_idx = phy->mt76->band_idx,4256		.tag = cpu_to_le16(UNI_BAND_CONFIG_RADIO_ENABLE),4257		.len = cpu_to_le16(sizeof(req) - 4),4258		.enable = enable,4259	};4260 4261	return mt76_mcu_send_msg(&phy->dev->mt76, MCU_WM_UNI_CMD(BAND_CONFIG),4262				 &req, sizeof(req), true);4263}4264 4265int mt7996_mcu_rdd_cmd(struct mt7996_dev *dev, int cmd, u8 index,4266		       u8 rx_sel, u8 val)4267{4268	struct {4269		u8 _rsv[4];4270 4271		__le16 tag;4272		__le16 len;4273 4274		u8 ctrl;4275		u8 rdd_idx;4276		u8 rdd_rx_sel;4277		u8 val;4278		u8 rsv[4];4279	} __packed req = {4280		.tag = cpu_to_le16(UNI_RDD_CTRL_PARM),4281		.len = cpu_to_le16(sizeof(req) - 4),4282		.ctrl = cmd,4283		.rdd_idx = index,4284		.rdd_rx_sel = rx_sel,4285		.val = val,4286	};4287 4288	return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(RDD_CTRL),4289				 &req, sizeof(req), true);4290}4291 4292int mt7996_mcu_wtbl_update_hdr_trans(struct mt7996_dev *dev,4293				     struct ieee80211_vif *vif,4294				     struct ieee80211_sta *sta)4295{4296	struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;4297	struct mt7996_sta *msta;4298	struct sk_buff *skb;4299 4300	msta = sta ? (struct mt7996_sta *)sta->drv_priv : &mvif->sta;4301 4302	skb = __mt76_connac_mcu_alloc_sta_req(&dev->mt76, &mvif->mt76,4303					      &msta->wcid,4304					      MT7996_STA_UPDATE_MAX_SIZE);4305	if (IS_ERR(skb))4306		return PTR_ERR(skb);4307 4308	/* starec hdr trans */4309	mt7996_mcu_sta_hdr_trans_tlv(dev, skb, vif, sta);4310	return mt76_mcu_skb_send_msg(&dev->mt76, skb,4311				     MCU_WMWA_UNI_CMD(STA_REC_UPDATE), true);4312}4313 4314int mt7996_mcu_set_fixed_rate_table(struct mt7996_phy *phy, u8 table_idx,4315				    u16 rate_idx, bool beacon)4316{4317#define UNI_FIXED_RATE_TABLE_SET	04318#define SPE_IXD_SELECT_TXD		04319#define SPE_IXD_SELECT_BMC_WTBL		14320	struct mt7996_dev *dev = phy->dev;4321	struct fixed_rate_table_ctrl req = {4322		.tag = cpu_to_le16(UNI_FIXED_RATE_TABLE_SET),4323		.len = cpu_to_le16(sizeof(req) - 4),4324		.table_idx = table_idx,4325		.rate_idx = cpu_to_le16(rate_idx),4326		.gi = 1,4327		.he_ltf = 1,4328	};4329	u8 band_idx = phy->mt76->band_idx;4330 4331	if (beacon) {4332		req.spe_idx_sel = SPE_IXD_SELECT_TXD;4333		req.spe_idx = 24 + band_idx;4334		phy->beacon_rate = rate_idx;4335	} else {4336		req.spe_idx_sel = SPE_IXD_SELECT_BMC_WTBL;4337	}4338 4339	return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(FIXED_RATE_TABLE),4340				 &req, sizeof(req), false);4341}4342 4343int mt7996_mcu_rf_regval(struct mt7996_dev *dev, u32 regidx, u32 *val, bool set)4344{4345	struct {4346		u8 __rsv1[4];4347 4348		__le16 tag;4349		__le16 len;4350		__le16 idx;4351		u8 __rsv2[2];4352		__le32 ofs;4353		__le32 data;4354	} __packed *res, req = {4355		.tag = cpu_to_le16(UNI_CMD_ACCESS_RF_REG_BASIC),4356		.len = cpu_to_le16(sizeof(req) - 4),4357 4358		.idx = cpu_to_le16(u32_get_bits(regidx, GENMASK(31, 24))),4359		.ofs = cpu_to_le32(u32_get_bits(regidx, GENMASK(23, 0))),4360		.data = set ? cpu_to_le32(*val) : 0,4361	};4362	struct sk_buff *skb;4363	int ret;4364 4365	if (set)4366		return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(REG_ACCESS),4367					 &req, sizeof(req), true);4368 4369	ret = mt76_mcu_send_and_get_msg(&dev->mt76,4370					MCU_WM_UNI_CMD_QUERY(REG_ACCESS),4371					&req, sizeof(req), true, &skb);4372	if (ret)4373		return ret;4374 4375	res = (void *)skb->data;4376	*val = le32_to_cpu(res->data);4377	dev_kfree_skb(skb);4378 4379	return 0;4380}4381 4382int mt7996_mcu_trigger_assert(struct mt7996_dev *dev)4383{4384	struct {4385		__le16 tag;4386		__le16 len;4387		u8 enable;4388		u8 rsv[3];4389	} __packed req = {4390		.len = cpu_to_le16(sizeof(req) - 4),4391		.enable = true,4392	};4393 4394	return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(ASSERT_DUMP),4395				 &req, sizeof(req), false);4396}4397 4398int mt7996_mcu_set_rro(struct mt7996_dev *dev, u16 tag, u16 val)4399{4400	struct {4401		u8 __rsv1[4];4402		__le16 tag;4403		__le16 len;4404		union {4405			struct {4406				u8 type;4407				u8 __rsv2[3];4408			} __packed platform_type;4409			struct {4410				u8 type;4411				u8 dest;4412				u8 __rsv2[2];4413			} __packed bypass_mode;4414			struct {4415				u8 path;4416				u8 __rsv2[3];4417			} __packed txfree_path;4418			struct {4419				__le16 flush_one;4420				__le16 flush_all;4421				u8 __rsv2[4];4422			} __packed timeout;4423		};4424	} __packed req = {4425		.tag = cpu_to_le16(tag),4426		.len = cpu_to_le16(sizeof(req) - 4),4427	};4428 4429	switch (tag) {4430	case UNI_RRO_SET_PLATFORM_TYPE:4431		req.platform_type.type = val;4432		break;4433	case UNI_RRO_SET_BYPASS_MODE:4434		req.bypass_mode.type = val;4435		break;4436	case UNI_RRO_SET_TXFREE_PATH:4437		req.txfree_path.path = val;4438		break;4439	case UNI_RRO_SET_FLUSH_TIMEOUT:4440		req.timeout.flush_one = cpu_to_le16(val);4441		req.timeout.flush_all = cpu_to_le16(2 * val);4442		break;4443	default:4444		return -EINVAL;4445	}4446 4447	return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(RRO), &req,4448				 sizeof(req), true);4449}4450 4451int mt7996_mcu_get_all_sta_info(struct mt7996_phy *phy, u16 tag)4452{4453	struct mt7996_dev *dev = phy->dev;4454	struct {4455		u8 _rsv[4];4456 4457		__le16 tag;4458		__le16 len;4459	} __packed req = {4460		.tag = cpu_to_le16(tag),4461		.len = cpu_to_le16(sizeof(req) - 4),4462	};4463 4464	return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(ALL_STA_INFO),4465				 &req, sizeof(req), false);4466}4467 4468int mt7996_mcu_wed_rro_reset_sessions(struct mt7996_dev *dev, u16 id)4469{4470	struct {4471		u8 __rsv[4];4472 4473		__le16 tag;4474		__le16 len;4475		__le16 session_id;4476		u8 pad[4];4477	} __packed req = {4478		.tag = cpu_to_le16(UNI_RRO_DEL_BA_SESSION),4479		.len = cpu_to_le16(sizeof(req) - 4),4480		.session_id = cpu_to_le16(id),4481	};4482 4483	return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(RRO), &req,4484				 sizeof(req), true);4485}4486 4487int mt7996_mcu_set_txpower_sku(struct mt7996_phy *phy)4488{4489#define TX_POWER_LIMIT_TABLE_RATE	04490	struct mt7996_dev *dev = phy->dev;4491	struct mt76_phy *mphy = phy->mt76;4492	struct ieee80211_hw *hw = mphy->hw;4493	struct tx_power_limit_table_ctrl {4494		u8 __rsv1[4];4495 4496		__le16 tag;4497		__le16 len;4498		u8 power_ctrl_id;4499		u8 power_limit_type;4500		u8 band_idx;4501	} __packed req = {4502		.tag = cpu_to_le16(UNI_TXPOWER_POWER_LIMIT_TABLE_CTRL),4503		.len = cpu_to_le16(sizeof(req) + MT7996_SKU_PATH_NUM - 4),4504		.power_ctrl_id = UNI_TXPOWER_POWER_LIMIT_TABLE_CTRL,4505		.power_limit_type = TX_POWER_LIMIT_TABLE_RATE,4506		.band_idx = phy->mt76->band_idx,4507	};4508	struct mt76_power_limits la = {};4509	struct sk_buff *skb;4510	int i, tx_power;4511 4512	tx_power = mt7996_get_power_bound(phy, hw->conf.power_level);4513	tx_power = mt76_get_rate_power_limits(mphy, mphy->chandef.chan,4514					      &la, tx_power);4515	mphy->txpower_cur = tx_power;4516 4517	skb = mt76_mcu_msg_alloc(&dev->mt76, NULL,4518				 sizeof(req) + MT7996_SKU_PATH_NUM);4519	if (!skb)4520		return -ENOMEM;4521 4522	skb_put_data(skb, &req, sizeof(req));4523	/* cck and ofdm */4524	skb_put_data(skb, &la.cck, sizeof(la.cck));4525	skb_put_data(skb, &la.ofdm, sizeof(la.ofdm));4526	/* ht20 */4527	skb_put_data(skb, &la.mcs[0], 8);4528	/* ht40 */4529	skb_put_data(skb, &la.mcs[1], 9);4530 4531	/* vht */4532	for (i = 0; i < 4; i++) {4533		skb_put_data(skb, &la.mcs[i], sizeof(la.mcs[i]));4534		skb_put_zero(skb, 2);  /* padding */4535	}4536 4537	/* he */4538	skb_put_data(skb, &la.ru[0], sizeof(la.ru));4539	/* eht */4540	skb_put_data(skb, &la.eht[0], sizeof(la.eht));4541 4542	/* padding */4543	skb_put_zero(skb, MT7996_SKU_PATH_NUM - MT7996_SKU_RATE_NUM);4544 4545	return mt76_mcu_skb_send_msg(&dev->mt76, skb,4546				     MCU_WM_UNI_CMD(TXPOWER), true);4547}4548 4549int mt7996_mcu_cp_support(struct mt7996_dev *dev, u8 mode)4550{4551	__le32 cp_mode;4552 4553	if (mode < mt76_connac_lmac_mapping(IEEE80211_AC_BE) ||4554	    mode > mt76_connac_lmac_mapping(IEEE80211_AC_VO))4555		return -EINVAL;4556 4557	cp_mode = cpu_to_le32(mode);4558	return mt76_mcu_send_msg(&dev->mt76, MCU_WA_EXT_CMD(CP_SUPPORT),4559				 &cp_mode, sizeof(cp_mode), true);4560}4561