cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

mcu.c (30097B)


      1// SPDX-License-Identifier: ISC
      2/* Copyright (C) 2020 MediaTek Inc. */
      3
      4#include <linux/firmware.h>
      5#include <linux/fs.h>
      6#include "mt7921.h"
      7#include "mt7921_trace.h"
      8#include "mcu.h"
      9#include "mac.h"
     10
     11struct mt7921_patch_hdr {
     12	char build_date[16];
     13	char platform[4];
     14	__be32 hw_sw_ver;
     15	__be32 patch_ver;
     16	__be16 checksum;
     17	u16 reserved;
     18	struct {
     19		__be32 patch_ver;
     20		__be32 subsys;
     21		__be32 feature;
     22		__be32 n_region;
     23		__be32 crc;
     24		u32 reserved[11];
     25	} desc;
     26} __packed;
     27
     28struct mt7921_patch_sec {
     29	__be32 type;
     30	__be32 offs;
     31	__be32 size;
     32	union {
     33		__be32 spec[13];
     34		struct {
     35			__be32 addr;
     36			__be32 len;
     37			__be32 sec_key_idx;
     38			__be32 align_len;
     39			u32 reserved[9];
     40		} info;
     41	};
     42} __packed;
     43
     44struct mt7921_fw_trailer {
     45	u8 chip_id;
     46	u8 eco_code;
     47	u8 n_region;
     48	u8 format_ver;
     49	u8 format_flag;
     50	u8 reserved[2];
     51	char fw_ver[10];
     52	char build_date[15];
     53	u32 crc;
     54} __packed;
     55
     56struct mt7921_fw_region {
     57	__le32 decomp_crc;
     58	__le32 decomp_len;
     59	__le32 decomp_blk_sz;
     60	u8 reserved[4];
     61	__le32 addr;
     62	__le32 len;
     63	u8 feature_set;
     64	u8 reserved1[15];
     65} __packed;
     66
     67#define MT_STA_BFER			BIT(0)
     68#define MT_STA_BFEE			BIT(1)
     69
     70#define PATCH_SEC_ENC_TYPE_MASK		GENMASK(31, 24)
     71#define PATCH_SEC_ENC_TYPE_PLAIN		0x00
     72#define PATCH_SEC_ENC_TYPE_AES			0x01
     73#define PATCH_SEC_ENC_TYPE_SCRAMBLE		0x02
     74#define PATCH_SEC_ENC_SCRAMBLE_INFO_MASK	GENMASK(15, 0)
     75#define PATCH_SEC_ENC_AES_KEY_MASK		GENMASK(7, 0)
     76
     77static int
     78mt7921_mcu_parse_eeprom(struct mt76_dev *dev, struct sk_buff *skb)
     79{
     80	struct mt7921_mcu_eeprom_info *res;
     81	u8 *buf;
     82
     83	if (!skb)
     84		return -EINVAL;
     85
     86	skb_pull(skb, sizeof(struct mt7921_mcu_rxd));
     87
     88	res = (struct mt7921_mcu_eeprom_info *)skb->data;
     89	buf = dev->eeprom.data + le32_to_cpu(res->addr);
     90	memcpy(buf, res->data, 16);
     91
     92	return 0;
     93}
     94
     95int mt7921_mcu_parse_response(struct mt76_dev *mdev, int cmd,
     96			      struct sk_buff *skb, int seq)
     97{
     98	int mcu_cmd = FIELD_GET(__MCU_CMD_FIELD_ID, cmd);
     99	struct mt7921_mcu_rxd *rxd;
    100	int ret = 0;
    101
    102	if (!skb) {
    103		dev_err(mdev->dev, "Message %08x (seq %d) timeout\n",
    104			cmd, seq);
    105		mt7921_reset(mdev);
    106
    107		return -ETIMEDOUT;
    108	}
    109
    110	rxd = (struct mt7921_mcu_rxd *)skb->data;
    111	if (seq != rxd->seq)
    112		return -EAGAIN;
    113
    114	if (cmd == MCU_CMD(PATCH_SEM_CONTROL)) {
    115		skb_pull(skb, sizeof(*rxd) - 4);
    116		ret = *skb->data;
    117	} else if (cmd == MCU_EXT_CMD(THERMAL_CTRL)) {
    118		skb_pull(skb, sizeof(*rxd) + 4);
    119		ret = le32_to_cpu(*(__le32 *)skb->data);
    120	} else if (cmd == MCU_EXT_CMD(EFUSE_ACCESS)) {
    121		ret = mt7921_mcu_parse_eeprom(mdev, skb);
    122	} else if (cmd == MCU_UNI_CMD(DEV_INFO_UPDATE) ||
    123		   cmd == MCU_UNI_CMD(BSS_INFO_UPDATE) ||
    124		   cmd == MCU_UNI_CMD(STA_REC_UPDATE) ||
    125		   cmd == MCU_UNI_CMD(HIF_CTRL) ||
    126		   cmd == MCU_UNI_CMD(OFFLOAD) ||
    127		   cmd == MCU_UNI_CMD(SUSPEND)) {
    128		struct mt7921_mcu_uni_event *event;
    129
    130		skb_pull(skb, sizeof(*rxd));
    131		event = (struct mt7921_mcu_uni_event *)skb->data;
    132		ret = le32_to_cpu(event->status);
    133		/* skip invalid event */
    134		if (mcu_cmd != event->cid)
    135			ret = -EAGAIN;
    136	} else if (cmd == MCU_CE_QUERY(REG_READ)) {
    137		struct mt7921_mcu_reg_event *event;
    138
    139		skb_pull(skb, sizeof(*rxd));
    140		event = (struct mt7921_mcu_reg_event *)skb->data;
    141		ret = (int)le32_to_cpu(event->val);
    142	} else {
    143		skb_pull(skb, sizeof(struct mt7921_mcu_rxd));
    144	}
    145
    146	return ret;
    147}
    148EXPORT_SYMBOL_GPL(mt7921_mcu_parse_response);
    149
    150int mt7921_mcu_fill_message(struct mt76_dev *mdev, struct sk_buff *skb,
    151			    int cmd, int *wait_seq)
    152{
    153	struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76);
    154	int txd_len, mcu_cmd = FIELD_GET(__MCU_CMD_FIELD_ID, cmd);
    155	struct mt7921_uni_txd *uni_txd;
    156	struct mt7921_mcu_txd *mcu_txd;
    157	__le32 *txd;
    158	u32 val;
    159	u8 seq;
    160
    161	if (cmd == MCU_UNI_CMD(HIF_CTRL) ||
    162	    cmd == MCU_UNI_CMD(SUSPEND) ||
    163	    cmd == MCU_UNI_CMD(OFFLOAD))
    164		mdev->mcu.timeout = HZ;
    165	else
    166		mdev->mcu.timeout = 3 * HZ;
    167
    168	seq = ++dev->mt76.mcu.msg_seq & 0xf;
    169	if (!seq)
    170		seq = ++dev->mt76.mcu.msg_seq & 0xf;
    171
    172	if (cmd == MCU_CMD(FW_SCATTER))
    173		goto exit;
    174
    175	txd_len = cmd & __MCU_CMD_FIELD_UNI ? sizeof(*uni_txd) : sizeof(*mcu_txd);
    176	txd = (__le32 *)skb_push(skb, txd_len);
    177
    178	val = FIELD_PREP(MT_TXD0_TX_BYTES, skb->len) |
    179	      FIELD_PREP(MT_TXD0_PKT_FMT, MT_TX_TYPE_CMD) |
    180	      FIELD_PREP(MT_TXD0_Q_IDX, MT_TX_MCU_PORT_RX_Q0);
    181	txd[0] = cpu_to_le32(val);
    182
    183	val = MT_TXD1_LONG_FORMAT |
    184	      FIELD_PREP(MT_TXD1_HDR_FORMAT, MT_HDR_FORMAT_CMD);
    185	txd[1] = cpu_to_le32(val);
    186
    187	if (cmd & __MCU_CMD_FIELD_UNI) {
    188		uni_txd = (struct mt7921_uni_txd *)txd;
    189		uni_txd->len = cpu_to_le16(skb->len - sizeof(uni_txd->txd));
    190		uni_txd->option = MCU_CMD_UNI_EXT_ACK;
    191		uni_txd->cid = cpu_to_le16(mcu_cmd);
    192		uni_txd->s2d_index = MCU_S2D_H2N;
    193		uni_txd->pkt_type = MCU_PKT_ID;
    194		uni_txd->seq = seq;
    195
    196		goto exit;
    197	}
    198
    199	mcu_txd = (struct mt7921_mcu_txd *)txd;
    200	mcu_txd->len = cpu_to_le16(skb->len - sizeof(mcu_txd->txd));
    201	mcu_txd->pq_id = cpu_to_le16(MCU_PQ_ID(MT_TX_PORT_IDX_MCU,
    202					       MT_TX_MCU_PORT_RX_Q0));
    203	mcu_txd->pkt_type = MCU_PKT_ID;
    204	mcu_txd->seq = seq;
    205	mcu_txd->cid = mcu_cmd;
    206	mcu_txd->s2d_index = MCU_S2D_H2N;
    207	mcu_txd->ext_cid = FIELD_GET(__MCU_CMD_FIELD_EXT_ID, cmd);
    208
    209	if (mcu_txd->ext_cid || (cmd & __MCU_CMD_FIELD_CE)) {
    210		if (cmd & __MCU_CMD_FIELD_QUERY)
    211			mcu_txd->set_query = MCU_Q_QUERY;
    212		else
    213			mcu_txd->set_query = MCU_Q_SET;
    214		mcu_txd->ext_cid_ack = !!mcu_txd->ext_cid;
    215	} else {
    216		mcu_txd->set_query = MCU_Q_NA;
    217	}
    218
    219exit:
    220	if (wait_seq)
    221		*wait_seq = seq;
    222
    223	return 0;
    224}
    225EXPORT_SYMBOL_GPL(mt7921_mcu_fill_message);
    226
    227#ifdef CONFIG_PM
    228
    229static int
    230mt7921_mcu_set_ipv6_ns_filter(struct mt76_dev *dev,
    231			      struct ieee80211_vif *vif, bool suspend)
    232{
    233	struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv;
    234	struct {
    235		struct {
    236			u8 bss_idx;
    237			u8 pad[3];
    238		} __packed hdr;
    239		struct mt76_connac_arpns_tlv arpns;
    240	} req = {
    241		.hdr = {
    242			.bss_idx = mvif->mt76.idx,
    243		},
    244		.arpns = {
    245			.tag = cpu_to_le16(UNI_OFFLOAD_OFFLOAD_ND),
    246			.len = cpu_to_le16(sizeof(struct mt76_connac_arpns_tlv)),
    247			.mode = suspend,
    248		},
    249	};
    250
    251	return mt76_mcu_send_msg(dev, MCU_UNI_CMD_OFFLOAD, &req, sizeof(req),
    252				 true);
    253}
    254
    255void mt7921_mcu_set_suspend_iter(void *priv, u8 *mac, struct ieee80211_vif *vif)
    256{
    257	if (IS_ENABLED(CONFIG_IPV6)) {
    258		struct mt76_phy *phy = priv;
    259
    260		mt7921_mcu_set_ipv6_ns_filter(phy->dev, vif,
    261					      !test_bit(MT76_STATE_RUNNING,
    262					      &phy->state));
    263	}
    264
    265	mt76_connac_mcu_set_suspend_iter(priv, mac, vif);
    266}
    267
    268#endif /* CONFIG_PM */
    269
    270static void
    271mt7921_mcu_scan_event(struct mt7921_dev *dev, struct sk_buff *skb)
    272{
    273	struct mt76_phy *mphy = &dev->mt76.phy;
    274	struct mt7921_phy *phy = (struct mt7921_phy *)mphy->priv;
    275
    276	spin_lock_bh(&dev->mt76.lock);
    277	__skb_queue_tail(&phy->scan_event_list, skb);
    278	spin_unlock_bh(&dev->mt76.lock);
    279
    280	ieee80211_queue_delayed_work(mphy->hw, &phy->scan_work,
    281				     MT7921_HW_SCAN_TIMEOUT);
    282}
    283
    284static void
    285mt7921_mcu_connection_loss_iter(void *priv, u8 *mac,
    286				struct ieee80211_vif *vif)
    287{
    288	struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
    289	struct mt76_connac_beacon_loss_event *event = priv;
    290
    291	if (mvif->idx != event->bss_idx)
    292		return;
    293
    294	if (!(vif->driver_flags & IEEE80211_VIF_BEACON_FILTER) ||
    295	    vif->type != NL80211_IFTYPE_STATION)
    296		return;
    297
    298	ieee80211_connection_loss(vif);
    299}
    300
    301static void
    302mt7921_mcu_connection_loss_event(struct mt7921_dev *dev, struct sk_buff *skb)
    303{
    304	struct mt76_connac_beacon_loss_event *event;
    305	struct mt76_phy *mphy = &dev->mt76.phy;
    306
    307	skb_pull(skb, sizeof(struct mt7921_mcu_rxd));
    308	event = (struct mt76_connac_beacon_loss_event *)skb->data;
    309
    310	ieee80211_iterate_active_interfaces_atomic(mphy->hw,
    311					IEEE80211_IFACE_ITER_RESUME_ALL,
    312					mt7921_mcu_connection_loss_iter, event);
    313}
    314
    315static void
    316mt7921_mcu_bss_event(struct mt7921_dev *dev, struct sk_buff *skb)
    317{
    318	struct mt76_phy *mphy = &dev->mt76.phy;
    319	struct mt76_connac_mcu_bss_event *event;
    320
    321	skb_pull(skb, sizeof(struct mt7921_mcu_rxd));
    322	event = (struct mt76_connac_mcu_bss_event *)skb->data;
    323	if (event->is_absent)
    324		ieee80211_stop_queues(mphy->hw);
    325	else
    326		ieee80211_wake_queues(mphy->hw);
    327}
    328
    329static void
    330mt7921_mcu_debug_msg_event(struct mt7921_dev *dev, struct sk_buff *skb)
    331{
    332	struct mt7921_debug_msg {
    333		__le16 id;
    334		u8 type;
    335		u8 flag;
    336		__le32 value;
    337		__le16 len;
    338		u8 content[512];
    339	} __packed * msg;
    340
    341	skb_pull(skb, sizeof(struct mt7921_mcu_rxd));
    342	msg = (struct mt7921_debug_msg *)skb->data;
    343
    344	if (msg->type == 3) { /* fw log */
    345		u16 len = min_t(u16, le16_to_cpu(msg->len), 512);
    346		int i;
    347
    348		for (i = 0 ; i < len; i++) {
    349			if (!msg->content[i])
    350				msg->content[i] = ' ';
    351		}
    352		wiphy_info(mt76_hw(dev)->wiphy, "%.*s", len, msg->content);
    353	}
    354}
    355
    356static void
    357mt7921_mcu_low_power_event(struct mt7921_dev *dev, struct sk_buff *skb)
    358{
    359	struct mt7921_mcu_lp_event {
    360		u8 state;
    361		u8 reserved[3];
    362	} __packed * event;
    363
    364	skb_pull(skb, sizeof(struct mt7921_mcu_rxd));
    365	event = (struct mt7921_mcu_lp_event *)skb->data;
    366
    367	trace_lp_event(dev, event->state);
    368}
    369
    370static void
    371mt7921_mcu_tx_done_event(struct mt7921_dev *dev, struct sk_buff *skb)
    372{
    373	struct mt7921_mcu_tx_done_event *event;
    374
    375	skb_pull(skb, sizeof(struct mt7921_mcu_rxd));
    376	event = (struct mt7921_mcu_tx_done_event *)skb->data;
    377
    378	mt7921_mac_add_txs(dev, event->txs);
    379}
    380
    381static void
    382mt7921_mcu_rx_unsolicited_event(struct mt7921_dev *dev, struct sk_buff *skb)
    383{
    384	struct mt7921_mcu_rxd *rxd = (struct mt7921_mcu_rxd *)skb->data;
    385
    386	switch (rxd->eid) {
    387	case MCU_EVENT_BSS_BEACON_LOSS:
    388		mt7921_mcu_connection_loss_event(dev, skb);
    389		break;
    390	case MCU_EVENT_SCHED_SCAN_DONE:
    391	case MCU_EVENT_SCAN_DONE:
    392		mt7921_mcu_scan_event(dev, skb);
    393		return;
    394	case MCU_EVENT_BSS_ABSENCE:
    395		mt7921_mcu_bss_event(dev, skb);
    396		break;
    397	case MCU_EVENT_DBG_MSG:
    398		mt7921_mcu_debug_msg_event(dev, skb);
    399		break;
    400	case MCU_EVENT_COREDUMP:
    401		dev->fw_assert = true;
    402		mt76_connac_mcu_coredump_event(&dev->mt76, skb,
    403					       &dev->coredump);
    404		return;
    405	case MCU_EVENT_LP_INFO:
    406		mt7921_mcu_low_power_event(dev, skb);
    407		break;
    408	case MCU_EVENT_TX_DONE:
    409		mt7921_mcu_tx_done_event(dev, skb);
    410		break;
    411	default:
    412		break;
    413	}
    414	dev_kfree_skb(skb);
    415}
    416
    417void mt7921_mcu_rx_event(struct mt7921_dev *dev, struct sk_buff *skb)
    418{
    419	struct mt7921_mcu_rxd *rxd;
    420
    421	if (skb_linearize(skb))
    422		return;
    423
    424	rxd = (struct mt7921_mcu_rxd *)skb->data;
    425
    426	if (rxd->eid == 0x6) {
    427		mt76_mcu_rx_event(&dev->mt76, skb);
    428		return;
    429	}
    430
    431	if (rxd->ext_eid == MCU_EXT_EVENT_RATE_REPORT ||
    432	    rxd->eid == MCU_EVENT_BSS_BEACON_LOSS ||
    433	    rxd->eid == MCU_EVENT_SCHED_SCAN_DONE ||
    434	    rxd->eid == MCU_EVENT_BSS_ABSENCE ||
    435	    rxd->eid == MCU_EVENT_SCAN_DONE ||
    436	    rxd->eid == MCU_EVENT_TX_DONE ||
    437	    rxd->eid == MCU_EVENT_DBG_MSG ||
    438	    rxd->eid == MCU_EVENT_COREDUMP ||
    439	    rxd->eid == MCU_EVENT_LP_INFO ||
    440	    !rxd->seq)
    441		mt7921_mcu_rx_unsolicited_event(dev, skb);
    442	else
    443		mt76_mcu_rx_event(&dev->mt76, skb);
    444}
    445
    446/** starec & wtbl **/
    447int mt7921_mcu_uni_tx_ba(struct mt7921_dev *dev,
    448			 struct ieee80211_ampdu_params *params,
    449			 bool enable)
    450{
    451	struct mt7921_sta *msta = (struct mt7921_sta *)params->sta->drv_priv;
    452
    453	if (enable && !params->amsdu)
    454		msta->wcid.amsdu = false;
    455
    456	return mt76_connac_mcu_sta_ba(&dev->mt76, &msta->vif->mt76, params,
    457				      MCU_UNI_CMD(STA_REC_UPDATE),
    458				      enable, true);
    459}
    460
    461int mt7921_mcu_uni_rx_ba(struct mt7921_dev *dev,
    462			 struct ieee80211_ampdu_params *params,
    463			 bool enable)
    464{
    465	struct mt7921_sta *msta = (struct mt7921_sta *)params->sta->drv_priv;
    466
    467	return mt76_connac_mcu_sta_ba(&dev->mt76, &msta->vif->mt76, params,
    468				      MCU_UNI_CMD(STA_REC_UPDATE),
    469				      enable, false);
    470}
    471
    472static u32 mt7921_get_data_mode(struct mt7921_dev *dev, u32 info)
    473{
    474	u32 mode = DL_MODE_NEED_RSP;
    475
    476	if (info == PATCH_SEC_NOT_SUPPORT)
    477		return mode;
    478
    479	switch (FIELD_GET(PATCH_SEC_ENC_TYPE_MASK, info)) {
    480	case PATCH_SEC_ENC_TYPE_PLAIN:
    481		break;
    482	case PATCH_SEC_ENC_TYPE_AES:
    483		mode |= DL_MODE_ENCRYPT;
    484		mode |= FIELD_PREP(DL_MODE_KEY_IDX,
    485				(info & PATCH_SEC_ENC_AES_KEY_MASK)) & DL_MODE_KEY_IDX;
    486		mode |= DL_MODE_RESET_SEC_IV;
    487		break;
    488	case PATCH_SEC_ENC_TYPE_SCRAMBLE:
    489		mode |= DL_MODE_ENCRYPT;
    490		mode |= DL_CONFIG_ENCRY_MODE_SEL;
    491		mode |= DL_MODE_RESET_SEC_IV;
    492		break;
    493	default:
    494		dev_err(dev->mt76.dev, "Encryption type not support!\n");
    495	}
    496
    497	return mode;
    498}
    499
    500static char *mt7921_patch_name(struct mt7921_dev *dev)
    501{
    502	char *ret;
    503
    504	if (is_mt7922(&dev->mt76))
    505		ret = MT7922_ROM_PATCH;
    506	else
    507		ret = MT7921_ROM_PATCH;
    508
    509	return ret;
    510}
    511
    512static int mt7921_load_patch(struct mt7921_dev *dev)
    513{
    514	const struct mt7921_patch_hdr *hdr;
    515	const struct firmware *fw = NULL;
    516	int i, ret, sem, max_len;
    517
    518	max_len = mt76_is_sdio(&dev->mt76) ? 2048 : 4096;
    519
    520	sem = mt76_connac_mcu_patch_sem_ctrl(&dev->mt76, true);
    521	switch (sem) {
    522	case PATCH_IS_DL:
    523		return 0;
    524	case PATCH_NOT_DL_SEM_SUCCESS:
    525		break;
    526	default:
    527		dev_err(dev->mt76.dev, "Failed to get patch semaphore\n");
    528		return -EAGAIN;
    529	}
    530
    531	ret = request_firmware(&fw, mt7921_patch_name(dev), dev->mt76.dev);
    532	if (ret)
    533		goto out;
    534
    535	if (!fw || !fw->data || fw->size < sizeof(*hdr)) {
    536		dev_err(dev->mt76.dev, "Invalid firmware\n");
    537		ret = -EINVAL;
    538		goto out;
    539	}
    540
    541	hdr = (const struct mt7921_patch_hdr *)(fw->data);
    542
    543	dev_info(dev->mt76.dev, "HW/SW Version: 0x%x, Build Time: %.16s\n",
    544		 be32_to_cpu(hdr->hw_sw_ver), hdr->build_date);
    545
    546	for (i = 0; i < be32_to_cpu(hdr->desc.n_region); i++) {
    547		struct mt7921_patch_sec *sec;
    548		const u8 *dl;
    549		u32 len, addr, mode;
    550		u32 sec_info = 0;
    551
    552		sec = (struct mt7921_patch_sec *)(fw->data + sizeof(*hdr) +
    553						  i * sizeof(*sec));
    554		if ((be32_to_cpu(sec->type) & PATCH_SEC_TYPE_MASK) !=
    555		    PATCH_SEC_TYPE_INFO) {
    556			ret = -EINVAL;
    557			goto out;
    558		}
    559
    560		addr = be32_to_cpu(sec->info.addr);
    561		len = be32_to_cpu(sec->info.len);
    562		dl = fw->data + be32_to_cpu(sec->offs);
    563		sec_info = be32_to_cpu(sec->info.sec_key_idx);
    564		mode = mt7921_get_data_mode(dev, sec_info);
    565
    566		ret = mt76_connac_mcu_init_download(&dev->mt76, addr, len,
    567						    mode);
    568		if (ret) {
    569			dev_err(dev->mt76.dev, "Download request failed\n");
    570			goto out;
    571		}
    572
    573		ret = __mt76_mcu_send_firmware(&dev->mt76, MCU_CMD(FW_SCATTER),
    574					       dl, len, max_len);
    575		if (ret) {
    576			dev_err(dev->mt76.dev, "Failed to send patch\n");
    577			goto out;
    578		}
    579	}
    580
    581	ret = mt76_connac_mcu_start_patch(&dev->mt76);
    582	if (ret)
    583		dev_err(dev->mt76.dev, "Failed to start patch\n");
    584
    585	if (mt76_is_sdio(&dev->mt76)) {
    586		/* activate again */
    587		ret = __mt7921_mcu_fw_pmctrl(dev);
    588		if (!ret)
    589			ret = __mt7921_mcu_drv_pmctrl(dev);
    590	}
    591
    592out:
    593	sem = mt76_connac_mcu_patch_sem_ctrl(&dev->mt76, false);
    594	switch (sem) {
    595	case PATCH_REL_SEM_SUCCESS:
    596		break;
    597	default:
    598		ret = -EAGAIN;
    599		dev_err(dev->mt76.dev, "Failed to release patch semaphore\n");
    600		break;
    601	}
    602	release_firmware(fw);
    603
    604	return ret;
    605}
    606
    607static int
    608mt7921_mcu_send_ram_firmware(struct mt7921_dev *dev,
    609			     const struct mt7921_fw_trailer *hdr,
    610			     const u8 *data, bool is_wa)
    611{
    612	int i, offset = 0, max_len;
    613	u32 override = 0, option = 0;
    614
    615	max_len = mt76_is_sdio(&dev->mt76) ? 2048 : 4096;
    616
    617	for (i = 0; i < hdr->n_region; i++) {
    618		const struct mt7921_fw_region *region;
    619		int err;
    620		u32 len, addr, mode;
    621
    622		region = (const struct mt7921_fw_region *)((const u8 *)hdr -
    623			 (hdr->n_region - i) * sizeof(*region));
    624		mode = mt76_connac_mcu_gen_dl_mode(&dev->mt76,
    625						   region->feature_set, is_wa);
    626		len = le32_to_cpu(region->len);
    627		addr = le32_to_cpu(region->addr);
    628
    629		if (region->feature_set & FW_FEATURE_OVERRIDE_ADDR)
    630			override = addr;
    631
    632		err = mt76_connac_mcu_init_download(&dev->mt76, addr, len,
    633						    mode);
    634		if (err) {
    635			dev_err(dev->mt76.dev, "Download request failed\n");
    636			return err;
    637		}
    638
    639		err = __mt76_mcu_send_firmware(&dev->mt76, MCU_CMD(FW_SCATTER),
    640					       data + offset, len, max_len);
    641		if (err) {
    642			dev_err(dev->mt76.dev, "Failed to send firmware.\n");
    643			return err;
    644		}
    645
    646		offset += len;
    647	}
    648
    649	if (override)
    650		option |= FW_START_OVERRIDE;
    651
    652	if (is_wa)
    653		option |= FW_START_WORKING_PDA_CR4;
    654
    655	return mt76_connac_mcu_start_firmware(&dev->mt76, override, option);
    656}
    657
    658static char *mt7921_ram_name(struct mt7921_dev *dev)
    659{
    660	char *ret;
    661
    662	if (is_mt7922(&dev->mt76))
    663		ret = MT7922_FIRMWARE_WM;
    664	else
    665		ret = MT7921_FIRMWARE_WM;
    666
    667	return ret;
    668}
    669
    670static int mt7921_load_ram(struct mt7921_dev *dev)
    671{
    672	const struct mt7921_fw_trailer *hdr;
    673	const struct firmware *fw;
    674	int ret;
    675
    676	ret = request_firmware(&fw, mt7921_ram_name(dev), dev->mt76.dev);
    677	if (ret)
    678		return ret;
    679
    680	if (!fw || !fw->data || fw->size < sizeof(*hdr)) {
    681		dev_err(dev->mt76.dev, "Invalid firmware\n");
    682		ret = -EINVAL;
    683		goto out;
    684	}
    685
    686	hdr = (const struct mt7921_fw_trailer *)(fw->data + fw->size -
    687					sizeof(*hdr));
    688
    689	dev_info(dev->mt76.dev, "WM Firmware Version: %.10s, Build Time: %.15s\n",
    690		 hdr->fw_ver, hdr->build_date);
    691
    692	ret = mt7921_mcu_send_ram_firmware(dev, hdr, fw->data, false);
    693	if (ret) {
    694		dev_err(dev->mt76.dev, "Failed to start WM firmware\n");
    695		goto out;
    696	}
    697
    698	snprintf(dev->mt76.hw->wiphy->fw_version,
    699		 sizeof(dev->mt76.hw->wiphy->fw_version),
    700		 "%.10s-%.15s", hdr->fw_ver, hdr->build_date);
    701
    702out:
    703	release_firmware(fw);
    704
    705	return ret;
    706}
    707
    708static int mt7921_load_firmware(struct mt7921_dev *dev)
    709{
    710	int ret;
    711
    712	ret = mt76_get_field(dev, MT_CONN_ON_MISC, MT_TOP_MISC2_FW_N9_RDY);
    713	if (ret && mt76_is_mmio(&dev->mt76)) {
    714		dev_dbg(dev->mt76.dev, "Firmware is already download\n");
    715		goto fw_loaded;
    716	}
    717
    718	ret = mt7921_load_patch(dev);
    719	if (ret)
    720		return ret;
    721
    722	ret = mt7921_load_ram(dev);
    723	if (ret)
    724		return ret;
    725
    726	if (!mt76_poll_msec(dev, MT_CONN_ON_MISC, MT_TOP_MISC2_FW_N9_RDY,
    727			    MT_TOP_MISC2_FW_N9_RDY, 1500)) {
    728		dev_err(dev->mt76.dev, "Timeout for initializing firmware\n");
    729
    730		return -EIO;
    731	}
    732
    733fw_loaded:
    734
    735#ifdef CONFIG_PM
    736	dev->mt76.hw->wiphy->wowlan = &mt76_connac_wowlan_support;
    737#endif /* CONFIG_PM */
    738
    739	dev_dbg(dev->mt76.dev, "Firmware init done\n");
    740
    741	return 0;
    742}
    743
    744int mt7921_mcu_fw_log_2_host(struct mt7921_dev *dev, u8 ctrl)
    745{
    746	struct {
    747		u8 ctrl_val;
    748		u8 pad[3];
    749	} data = {
    750		.ctrl_val = ctrl
    751	};
    752
    753	return mt76_mcu_send_msg(&dev->mt76, MCU_CE_CMD(FWLOG_2_HOST),
    754				 &data, sizeof(data), false);
    755}
    756
    757int mt7921_run_firmware(struct mt7921_dev *dev)
    758{
    759	int err;
    760
    761	err = mt7921_load_firmware(dev);
    762	if (err)
    763		return err;
    764
    765	err = mt76_connac_mcu_get_nic_capability(&dev->mphy);
    766	if (err)
    767		return err;
    768
    769	set_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state);
    770	return mt7921_mcu_fw_log_2_host(dev, 1);
    771}
    772EXPORT_SYMBOL_GPL(mt7921_run_firmware);
    773
    774void mt7921_mcu_exit(struct mt7921_dev *dev)
    775{
    776	skb_queue_purge(&dev->mt76.mcu.res_q);
    777}
    778EXPORT_SYMBOL_GPL(mt7921_mcu_exit);
    779
    780int mt7921_mcu_set_tx(struct mt7921_dev *dev, struct ieee80211_vif *vif)
    781{
    782	struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv;
    783	struct edca {
    784		__le16 cw_min;
    785		__le16 cw_max;
    786		__le16 txop;
    787		__le16 aifs;
    788		u8 guardtime;
    789		u8 acm;
    790	} __packed;
    791	struct mt7921_mcu_tx {
    792		struct edca edca[IEEE80211_NUM_ACS];
    793		u8 bss_idx;
    794		u8 qos;
    795		u8 wmm_idx;
    796		u8 pad;
    797	} __packed req = {
    798		.bss_idx = mvif->mt76.idx,
    799		.qos = vif->bss_conf.qos,
    800		.wmm_idx = mvif->mt76.wmm_idx,
    801	};
    802	struct mu_edca {
    803		u8 cw_min;
    804		u8 cw_max;
    805		u8 aifsn;
    806		u8 acm;
    807		u8 timer;
    808		u8 padding[3];
    809	};
    810	struct mt7921_mcu_mu_tx {
    811		u8 ver;
    812		u8 pad0;
    813		__le16 len;
    814		u8 bss_idx;
    815		u8 qos;
    816		u8 wmm_idx;
    817		u8 pad1;
    818		struct mu_edca edca[IEEE80211_NUM_ACS];
    819		u8 pad3[32];
    820	} __packed req_mu = {
    821		.bss_idx = mvif->mt76.idx,
    822		.qos = vif->bss_conf.qos,
    823		.wmm_idx = mvif->mt76.wmm_idx,
    824	};
    825	static const int to_aci[] = { 1, 0, 2, 3 };
    826	int ac, ret;
    827
    828	for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
    829		struct ieee80211_tx_queue_params *q = &mvif->queue_params[ac];
    830		struct edca *e = &req.edca[to_aci[ac]];
    831
    832		e->aifs = cpu_to_le16(q->aifs);
    833		e->txop = cpu_to_le16(q->txop);
    834
    835		if (q->cw_min)
    836			e->cw_min = cpu_to_le16(q->cw_min);
    837		else
    838			e->cw_min = cpu_to_le16(5);
    839
    840		if (q->cw_max)
    841			e->cw_max = cpu_to_le16(q->cw_max);
    842		else
    843			e->cw_max = cpu_to_le16(10);
    844	}
    845
    846	ret = mt76_mcu_send_msg(&dev->mt76, MCU_CE_CMD(SET_EDCA_PARMS), &req,
    847				sizeof(req), false);
    848	if (ret)
    849		return ret;
    850
    851	if (!vif->bss_conf.he_support)
    852		return 0;
    853
    854	for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
    855		struct ieee80211_he_mu_edca_param_ac_rec *q;
    856		struct mu_edca *e;
    857
    858		if (!mvif->queue_params[ac].mu_edca)
    859			break;
    860
    861		q = &mvif->queue_params[ac].mu_edca_param_rec;
    862		e = &(req_mu.edca[to_aci[ac]]);
    863
    864		e->cw_min = q->ecw_min_max & 0xf;
    865		e->cw_max = (q->ecw_min_max & 0xf0) >> 4;
    866		e->aifsn = q->aifsn;
    867		e->timer = q->mu_edca_timer;
    868	}
    869
    870	return mt76_mcu_send_msg(&dev->mt76, MCU_CE_CMD(SET_MU_EDCA_PARMS),
    871				 &req_mu, sizeof(req_mu), false);
    872}
    873
    874int mt7921_mcu_set_chan_info(struct mt7921_phy *phy, int cmd)
    875{
    876	struct mt7921_dev *dev = phy->dev;
    877	struct cfg80211_chan_def *chandef = &phy->mt76->chandef;
    878	int freq1 = chandef->center_freq1;
    879	struct {
    880		u8 control_ch;
    881		u8 center_ch;
    882		u8 bw;
    883		u8 tx_streams_num;
    884		u8 rx_streams;	/* mask or num */
    885		u8 switch_reason;
    886		u8 band_idx;
    887		u8 center_ch2;	/* for 80+80 only */
    888		__le16 cac_case;
    889		u8 channel_band;
    890		u8 rsv0;
    891		__le32 outband_freq;
    892		u8 txpower_drop;
    893		u8 ap_bw;
    894		u8 ap_center_ch;
    895		u8 rsv1[57];
    896	} __packed req = {
    897		.control_ch = chandef->chan->hw_value,
    898		.center_ch = ieee80211_frequency_to_channel(freq1),
    899		.bw = mt76_connac_chan_bw(chandef),
    900		.tx_streams_num = hweight8(phy->mt76->antenna_mask),
    901		.rx_streams = phy->mt76->antenna_mask,
    902		.band_idx = phy != &dev->phy,
    903	};
    904
    905	if (chandef->chan->band == NL80211_BAND_6GHZ)
    906		req.channel_band = 2;
    907	else
    908		req.channel_band = chandef->chan->band;
    909
    910	if (cmd == MCU_EXT_CMD(SET_RX_PATH) ||
    911	    dev->mt76.hw->conf.flags & IEEE80211_CONF_MONITOR)
    912		req.switch_reason = CH_SWITCH_NORMAL;
    913	else if (dev->mt76.hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)
    914		req.switch_reason = CH_SWITCH_SCAN_BYPASS_DPD;
    915	else if (!cfg80211_reg_can_beacon(dev->mt76.hw->wiphy, chandef,
    916					  NL80211_IFTYPE_AP))
    917		req.switch_reason = CH_SWITCH_DFS;
    918	else
    919		req.switch_reason = CH_SWITCH_NORMAL;
    920
    921	if (cmd == MCU_EXT_CMD(CHANNEL_SWITCH))
    922		req.rx_streams = hweight8(req.rx_streams);
    923
    924	if (chandef->width == NL80211_CHAN_WIDTH_80P80) {
    925		int freq2 = chandef->center_freq2;
    926
    927		req.center_ch2 = ieee80211_frequency_to_channel(freq2);
    928	}
    929
    930	return mt76_mcu_send_msg(&dev->mt76, cmd, &req, sizeof(req), true);
    931}
    932
    933int mt7921_mcu_set_eeprom(struct mt7921_dev *dev)
    934{
    935	struct req_hdr {
    936		u8 buffer_mode;
    937		u8 format;
    938		__le16 len;
    939	} __packed req = {
    940		.buffer_mode = EE_MODE_EFUSE,
    941		.format = EE_FORMAT_WHOLE,
    942	};
    943
    944	return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(EFUSE_BUFFER_MODE),
    945				 &req, sizeof(req), true);
    946}
    947EXPORT_SYMBOL_GPL(mt7921_mcu_set_eeprom);
    948
    949int mt7921_mcu_uni_bss_ps(struct mt7921_dev *dev, struct ieee80211_vif *vif)
    950{
    951	struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv;
    952	struct {
    953		struct {
    954			u8 bss_idx;
    955			u8 pad[3];
    956		} __packed hdr;
    957		struct ps_tlv {
    958			__le16 tag;
    959			__le16 len;
    960			u8 ps_state; /* 0: device awake
    961				      * 1: static power save
    962				      * 2: dynamic power saving
    963				      * 3: enter TWT power saving
    964				      * 4: leave TWT power saving
    965				      */
    966			u8 pad[3];
    967		} __packed ps;
    968	} __packed ps_req = {
    969		.hdr = {
    970			.bss_idx = mvif->mt76.idx,
    971		},
    972		.ps = {
    973			.tag = cpu_to_le16(UNI_BSS_INFO_PS),
    974			.len = cpu_to_le16(sizeof(struct ps_tlv)),
    975			.ps_state = vif->bss_conf.ps ? 2 : 0,
    976		},
    977	};
    978
    979	if (vif->type != NL80211_IFTYPE_STATION)
    980		return -EOPNOTSUPP;
    981
    982	return mt76_mcu_send_msg(&dev->mt76, MCU_UNI_CMD(BSS_INFO_UPDATE),
    983				 &ps_req, sizeof(ps_req), true);
    984}
    985
    986static int
    987mt7921_mcu_uni_bss_bcnft(struct mt7921_dev *dev, struct ieee80211_vif *vif,
    988			 bool enable)
    989{
    990	struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv;
    991	struct {
    992		struct {
    993			u8 bss_idx;
    994			u8 pad[3];
    995		} __packed hdr;
    996		struct bcnft_tlv {
    997			__le16 tag;
    998			__le16 len;
    999			__le16 bcn_interval;
   1000			u8 dtim_period;
   1001			u8 pad;
   1002		} __packed bcnft;
   1003	} __packed bcnft_req = {
   1004		.hdr = {
   1005			.bss_idx = mvif->mt76.idx,
   1006		},
   1007		.bcnft = {
   1008			.tag = cpu_to_le16(UNI_BSS_INFO_BCNFT),
   1009			.len = cpu_to_le16(sizeof(struct bcnft_tlv)),
   1010			.bcn_interval = cpu_to_le16(vif->bss_conf.beacon_int),
   1011			.dtim_period = vif->bss_conf.dtim_period,
   1012		},
   1013	};
   1014
   1015	if (vif->type != NL80211_IFTYPE_STATION)
   1016		return 0;
   1017
   1018	return mt76_mcu_send_msg(&dev->mt76, MCU_UNI_CMD(BSS_INFO_UPDATE),
   1019				 &bcnft_req, sizeof(bcnft_req), true);
   1020}
   1021
   1022static int
   1023mt7921_mcu_set_bss_pm(struct mt7921_dev *dev, struct ieee80211_vif *vif,
   1024		      bool enable)
   1025{
   1026	struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv;
   1027	struct {
   1028		u8 bss_idx;
   1029		u8 dtim_period;
   1030		__le16 aid;
   1031		__le16 bcn_interval;
   1032		__le16 atim_window;
   1033		u8 uapsd;
   1034		u8 bmc_delivered_ac;
   1035		u8 bmc_triggered_ac;
   1036		u8 pad;
   1037	} req = {
   1038		.bss_idx = mvif->mt76.idx,
   1039		.aid = cpu_to_le16(vif->bss_conf.aid),
   1040		.dtim_period = vif->bss_conf.dtim_period,
   1041		.bcn_interval = cpu_to_le16(vif->bss_conf.beacon_int),
   1042	};
   1043	struct {
   1044		u8 bss_idx;
   1045		u8 pad[3];
   1046	} req_hdr = {
   1047		.bss_idx = mvif->mt76.idx,
   1048	};
   1049	int err;
   1050
   1051	if (vif->type != NL80211_IFTYPE_STATION)
   1052		return 0;
   1053
   1054	err = mt76_mcu_send_msg(&dev->mt76, MCU_CE_CMD(SET_BSS_ABORT),
   1055				&req_hdr, sizeof(req_hdr), false);
   1056	if (err < 0 || !enable)
   1057		return err;
   1058
   1059	return mt76_mcu_send_msg(&dev->mt76, MCU_CE_CMD(SET_BSS_CONNECTED),
   1060				 &req, sizeof(req), false);
   1061}
   1062
   1063int mt7921_mcu_sta_update(struct mt7921_dev *dev, struct ieee80211_sta *sta,
   1064			  struct ieee80211_vif *vif, bool enable,
   1065			  enum mt76_sta_info_state state)
   1066{
   1067	struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv;
   1068	int rssi = -ewma_rssi_read(&mvif->rssi);
   1069	struct mt76_sta_cmd_info info = {
   1070		.sta = sta,
   1071		.vif = vif,
   1072		.enable = enable,
   1073		.cmd = MCU_UNI_CMD(STA_REC_UPDATE),
   1074		.state = state,
   1075		.offload_fw = true,
   1076		.rcpi = to_rcpi(rssi),
   1077	};
   1078	struct mt7921_sta *msta;
   1079
   1080	msta = sta ? (struct mt7921_sta *)sta->drv_priv : NULL;
   1081	info.wcid = msta ? &msta->wcid : &mvif->sta.wcid;
   1082	info.newly = msta ? state != MT76_STA_INFO_STATE_ASSOC : true;
   1083
   1084	return mt76_connac_mcu_sta_cmd(&dev->mphy, &info);
   1085}
   1086
   1087int mt7921_mcu_drv_pmctrl(struct mt7921_dev *dev)
   1088{
   1089	struct mt76_phy *mphy = &dev->mt76.phy;
   1090	struct mt76_connac_pm *pm = &dev->pm;
   1091	int err = 0;
   1092
   1093	mutex_lock(&pm->mutex);
   1094
   1095	if (!test_bit(MT76_STATE_PM, &mphy->state))
   1096		goto out;
   1097
   1098	err = __mt7921_mcu_drv_pmctrl(dev);
   1099out:
   1100	mutex_unlock(&pm->mutex);
   1101
   1102	if (err)
   1103		mt7921_reset(&dev->mt76);
   1104
   1105	return err;
   1106}
   1107EXPORT_SYMBOL_GPL(mt7921_mcu_drv_pmctrl);
   1108
   1109int mt7921_mcu_fw_pmctrl(struct mt7921_dev *dev)
   1110{
   1111	struct mt76_phy *mphy = &dev->mt76.phy;
   1112	struct mt76_connac_pm *pm = &dev->pm;
   1113	int err = 0;
   1114
   1115	mutex_lock(&pm->mutex);
   1116
   1117	if (mt76_connac_skip_fw_pmctrl(mphy, pm))
   1118		goto out;
   1119
   1120	err = __mt7921_mcu_fw_pmctrl(dev);
   1121out:
   1122	mutex_unlock(&pm->mutex);
   1123
   1124	if (err)
   1125		mt7921_reset(&dev->mt76);
   1126
   1127	return err;
   1128}
   1129EXPORT_SYMBOL_GPL(mt7921_mcu_fw_pmctrl);
   1130
   1131int mt7921_mcu_set_beacon_filter(struct mt7921_dev *dev,
   1132				 struct ieee80211_vif *vif,
   1133				 bool enable)
   1134{
   1135	struct ieee80211_hw *hw = mt76_hw(dev);
   1136	int err;
   1137
   1138	if (enable) {
   1139		err = mt7921_mcu_uni_bss_bcnft(dev, vif, true);
   1140		if (err)
   1141			return err;
   1142
   1143		vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER;
   1144		ieee80211_hw_set(hw, CONNECTION_MONITOR);
   1145		mt76_set(dev, MT_WF_RFCR(0), MT_WF_RFCR_DROP_OTHER_BEACON);
   1146
   1147		return 0;
   1148	}
   1149
   1150	err = mt7921_mcu_set_bss_pm(dev, vif, false);
   1151	if (err)
   1152		return err;
   1153
   1154	vif->driver_flags &= ~IEEE80211_VIF_BEACON_FILTER;
   1155	__clear_bit(IEEE80211_HW_CONNECTION_MONITOR, hw->flags);
   1156	mt76_clear(dev, MT_WF_RFCR(0), MT_WF_RFCR_DROP_OTHER_BEACON);
   1157
   1158	return 0;
   1159}
   1160
   1161int mt7921_get_txpwr_info(struct mt7921_dev *dev, struct mt7921_txpwr *txpwr)
   1162{
   1163	struct mt7921_txpwr_event *event;
   1164	struct mt7921_txpwr_req req = {
   1165		.dbdc_idx = 0,
   1166	};
   1167	struct sk_buff *skb;
   1168	int ret;
   1169
   1170	ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_CE_CMD(GET_TXPWR),
   1171					&req, sizeof(req), true, &skb);
   1172	if (ret)
   1173		return ret;
   1174
   1175	event = (struct mt7921_txpwr_event *)skb->data;
   1176	WARN_ON(skb->len != le16_to_cpu(event->len));
   1177	memcpy(txpwr, &event->txpwr, sizeof(event->txpwr));
   1178
   1179	dev_kfree_skb(skb);
   1180
   1181	return 0;
   1182}
   1183
   1184int mt7921_mcu_set_sniffer(struct mt7921_dev *dev, struct ieee80211_vif *vif,
   1185			   bool enable)
   1186{
   1187	struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
   1188	struct {
   1189		struct {
   1190			u8 band_idx;
   1191			u8 pad[3];
   1192		} __packed hdr;
   1193		struct sniffer_enable_tlv {
   1194			__le16 tag;
   1195			__le16 len;
   1196			u8 enable;
   1197			u8 pad[3];
   1198		} __packed enable;
   1199	} req = {
   1200		.hdr = {
   1201			.band_idx = mvif->band_idx,
   1202		},
   1203		.enable = {
   1204			.tag = cpu_to_le16(0),
   1205			.len = cpu_to_le16(sizeof(struct sniffer_enable_tlv)),
   1206			.enable = enable,
   1207		},
   1208	};
   1209
   1210	return mt76_mcu_send_msg(&dev->mt76, MCU_UNI_CMD(SNIFFER), &req, sizeof(req),
   1211				 true);
   1212}
   1213
   1214int
   1215mt7921_mcu_uni_add_beacon_offload(struct mt7921_dev *dev,
   1216				  struct ieee80211_hw *hw,
   1217				  struct ieee80211_vif *vif,
   1218				  bool enable)
   1219{
   1220	struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv;
   1221	struct mt76_wcid *wcid = &dev->mt76.global_wcid;
   1222	struct ieee80211_mutable_offsets offs;
   1223	struct {
   1224		struct req_hdr {
   1225			u8 bss_idx;
   1226			u8 pad[3];
   1227		} __packed hdr;
   1228		struct bcn_content_tlv {
   1229			__le16 tag;
   1230			__le16 len;
   1231			__le16 tim_ie_pos;
   1232			__le16 csa_ie_pos;
   1233			__le16 bcc_ie_pos;
   1234			/* 0: disable beacon offload
   1235			 * 1: enable beacon offload
   1236			 * 2: update probe respond offload
   1237			 */
   1238			u8 enable;
   1239			/* 0: legacy format (TXD + payload)
   1240			 * 1: only cap field IE
   1241			 */
   1242			u8 type;
   1243			__le16 pkt_len;
   1244			u8 pkt[512];
   1245		} __packed beacon_tlv;
   1246	} req = {
   1247		.hdr = {
   1248			.bss_idx = mvif->mt76.idx,
   1249		},
   1250		.beacon_tlv = {
   1251			.tag = cpu_to_le16(UNI_BSS_INFO_BCN_CONTENT),
   1252			.len = cpu_to_le16(sizeof(struct bcn_content_tlv)),
   1253			.enable = enable,
   1254		},
   1255	};
   1256	struct sk_buff *skb;
   1257
   1258	if (!enable)
   1259		goto out;
   1260
   1261	skb = ieee80211_beacon_get_template(mt76_hw(dev), vif, &offs);
   1262	if (!skb)
   1263		return -EINVAL;
   1264
   1265	if (skb->len > 512 - MT_TXD_SIZE) {
   1266		dev_err(dev->mt76.dev, "beacon size limit exceed\n");
   1267		dev_kfree_skb(skb);
   1268		return -EINVAL;
   1269	}
   1270
   1271	mt7921_mac_write_txwi(dev, (__le32 *)(req.beacon_tlv.pkt), skb,
   1272			      wcid, NULL, 0, true);
   1273	memcpy(req.beacon_tlv.pkt + MT_TXD_SIZE, skb->data, skb->len);
   1274	req.beacon_tlv.pkt_len = cpu_to_le16(MT_TXD_SIZE + skb->len);
   1275	req.beacon_tlv.tim_ie_pos = cpu_to_le16(MT_TXD_SIZE + offs.tim_offset);
   1276
   1277	if (offs.cntdwn_counter_offs[0]) {
   1278		u16 csa_offs;
   1279
   1280		csa_offs = MT_TXD_SIZE + offs.cntdwn_counter_offs[0] - 4;
   1281		req.beacon_tlv.csa_ie_pos = cpu_to_le16(csa_offs);
   1282	}
   1283	dev_kfree_skb(skb);
   1284
   1285out:
   1286	return mt76_mcu_send_msg(&dev->mt76, MCU_UNI_CMD(BSS_INFO_UPDATE),
   1287				 &req, sizeof(req), true);
   1288}