brintos

brintos / linux-shallow public Read only

0
0
Text · 61.6 KiB · 96e3427 Raw
2565 lines · c
1// SPDX-License-Identifier: ISC2/* Copyright (C) 2019 MediaTek Inc.3 *4 * Author: Roy Luo <royluo@google.com>5 *         Ryder Lee <ryder.lee@mediatek.com>6 */7 8#include <linux/firmware.h>9#include "mt7615.h"10#include "mcu.h"11#include "mac.h"12#include "eeprom.h"13 14static bool prefer_offload_fw = true;15module_param(prefer_offload_fw, bool, 0644);16MODULE_PARM_DESC(prefer_offload_fw,17		 "Prefer client mode offload firmware (MT7663)");18 19struct mt7615_patch_hdr {20	char build_date[16];21	char platform[4];22	__be32 hw_sw_ver;23	__be32 patch_ver;24	__be16 checksum;25} __packed;26 27struct mt7615_fw_trailer {28	__le32 addr;29	u8 chip_id;30	u8 feature_set;31	u8 eco_code;32	char fw_ver[10];33	char build_date[15];34	__le32 len;35} __packed;36 37#define FW_V3_COMMON_TAILER_SIZE	3638#define FW_V3_REGION_TAILER_SIZE	4039#define FW_START_OVERRIDE		BIT(0)40#define FW_START_DLYCAL                 BIT(1)41#define FW_START_WORKING_PDA_CR4	BIT(2)42 43struct mt7663_fw_buf {44	__le32 crc;45	__le32 d_img_size;46	__le32 block_size;47	u8 rsv[4];48	__le32 img_dest_addr;49	__le32 img_size;50	u8 feature_set;51};52 53#define MT7615_PATCH_ADDRESS		0x8000054#define MT7622_PATCH_ADDRESS		0x9c00055#define MT7663_PATCH_ADDRESS		0xdc00056 57#define N9_REGION_NUM			258#define CR4_REGION_NUM			159 60#define IMG_CRC_LEN			461 62void mt7615_mcu_fill_msg(struct mt7615_dev *dev, struct sk_buff *skb,63			 int cmd, int *wait_seq)64{65	int txd_len, mcu_cmd = FIELD_GET(__MCU_CMD_FIELD_ID, cmd);66	struct mt7615_uni_txd *uni_txd;67	struct mt7615_mcu_txd *mcu_txd;68	u8 seq, q_idx, pkt_fmt;69	__le32 *txd;70	u32 val;71 72	/* TODO: make dynamic based on msg type */73	dev->mt76.mcu.timeout = 20 * HZ;74 75	seq = ++dev->mt76.mcu.msg_seq & 0xf;76	if (!seq)77		seq = ++dev->mt76.mcu.msg_seq & 0xf;78	if (wait_seq)79		*wait_seq = seq;80 81	txd_len = cmd & __MCU_CMD_FIELD_UNI ? sizeof(*uni_txd) : sizeof(*mcu_txd);82	txd = (__le32 *)skb_push(skb, txd_len);83 84	if (cmd != MCU_CMD(FW_SCATTER)) {85		q_idx = MT_TX_MCU_PORT_RX_Q0;86		pkt_fmt = MT_TX_TYPE_CMD;87	} else {88		q_idx = MT_TX_MCU_PORT_RX_FWDL;89		pkt_fmt = MT_TX_TYPE_FW;90	}91 92	val = FIELD_PREP(MT_TXD0_TX_BYTES, skb->len) |93	      FIELD_PREP(MT_TXD0_P_IDX, MT_TX_PORT_IDX_MCU) |94	      FIELD_PREP(MT_TXD0_Q_IDX, q_idx);95	txd[0] = cpu_to_le32(val);96 97	val = MT_TXD1_LONG_FORMAT |98	      FIELD_PREP(MT_TXD1_HDR_FORMAT, MT_HDR_FORMAT_CMD) |99	      FIELD_PREP(MT_TXD1_PKT_FMT, pkt_fmt);100	txd[1] = cpu_to_le32(val);101 102	if (cmd & __MCU_CMD_FIELD_UNI) {103		uni_txd = (struct mt7615_uni_txd *)txd;104		uni_txd->len = cpu_to_le16(skb->len - sizeof(uni_txd->txd));105		uni_txd->option = MCU_CMD_UNI_EXT_ACK;106		uni_txd->cid = cpu_to_le16(mcu_cmd);107		uni_txd->s2d_index = MCU_S2D_H2N;108		uni_txd->pkt_type = MCU_PKT_ID;109		uni_txd->seq = seq;110 111		return;112	}113 114	mcu_txd = (struct mt7615_mcu_txd *)txd;115	mcu_txd->len = cpu_to_le16(skb->len - sizeof(mcu_txd->txd));116	mcu_txd->pq_id = cpu_to_le16(MCU_PQ_ID(MT_TX_PORT_IDX_MCU, q_idx));117	mcu_txd->s2d_index = MCU_S2D_H2N;118	mcu_txd->pkt_type = MCU_PKT_ID;119	mcu_txd->seq = seq;120	mcu_txd->cid = mcu_cmd;121	mcu_txd->ext_cid = FIELD_GET(__MCU_CMD_FIELD_EXT_ID, cmd);122 123	if (mcu_txd->ext_cid || (cmd & __MCU_CMD_FIELD_CE)) {124		if (cmd & __MCU_CMD_FIELD_QUERY)125			mcu_txd->set_query = MCU_Q_QUERY;126		else127			mcu_txd->set_query = MCU_Q_SET;128		mcu_txd->ext_cid_ack = !!mcu_txd->ext_cid;129	} else {130		mcu_txd->set_query = MCU_Q_NA;131	}132}133EXPORT_SYMBOL_GPL(mt7615_mcu_fill_msg);134 135int mt7615_mcu_parse_response(struct mt76_dev *mdev, int cmd,136			      struct sk_buff *skb, int seq)137{138	struct mt7615_mcu_rxd *rxd;139	int ret = 0;140 141	if (!skb) {142		dev_err(mdev->dev, "Message %08x (seq %d) timeout\n",143			cmd, seq);144		return -ETIMEDOUT;145	}146 147	rxd = (struct mt7615_mcu_rxd *)skb->data;148	if (seq != rxd->seq)149		return -EAGAIN;150 151	if (cmd == MCU_CMD(PATCH_SEM_CONTROL)) {152		skb_pull(skb, sizeof(*rxd) - 4);153		ret = *skb->data;154	} else if (cmd == MCU_EXT_CMD(THERMAL_CTRL)) {155		skb_pull(skb, sizeof(*rxd));156		ret = le32_to_cpu(*(__le32 *)skb->data);157	} else if (cmd == MCU_EXT_QUERY(RF_REG_ACCESS)) {158		skb_pull(skb, sizeof(*rxd));159		ret = le32_to_cpu(*(__le32 *)&skb->data[8]);160	} else if (cmd == MCU_UNI_CMD(DEV_INFO_UPDATE) ||161		   cmd == MCU_UNI_CMD(BSS_INFO_UPDATE) ||162		   cmd == MCU_UNI_CMD(STA_REC_UPDATE) ||163		   cmd == MCU_UNI_CMD(HIF_CTRL) ||164		   cmd == MCU_UNI_CMD(OFFLOAD) ||165		   cmd == MCU_UNI_CMD(SUSPEND)) {166		struct mt76_connac_mcu_uni_event *event;167 168		skb_pull(skb, sizeof(*rxd));169		event = (struct mt76_connac_mcu_uni_event *)skb->data;170		ret = le32_to_cpu(event->status);171	} else if (cmd == MCU_CE_QUERY(REG_READ)) {172		struct mt76_connac_mcu_reg_event *event;173 174		skb_pull(skb, sizeof(*rxd));175		event = (struct mt76_connac_mcu_reg_event *)skb->data;176		ret = (int)le32_to_cpu(event->val);177	}178 179	return ret;180}181EXPORT_SYMBOL_GPL(mt7615_mcu_parse_response);182 183static int184mt7615_mcu_send_message(struct mt76_dev *mdev, struct sk_buff *skb,185			int cmd, int *seq)186{187	struct mt7615_dev *dev = container_of(mdev, struct mt7615_dev, mt76);188	enum mt76_mcuq_id qid;189 190	mt7615_mcu_fill_msg(dev, skb, cmd, seq);191	if (test_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state))192		qid = MT_MCUQ_WM;193	else194		qid = MT_MCUQ_FWDL;195 196	return mt76_tx_queue_skb_raw(dev, dev->mt76.q_mcu[qid], skb, 0);197}198 199u32 mt7615_rf_rr(struct mt7615_dev *dev, u32 wf, u32 reg)200{201	struct {202		__le32 wifi_stream;203		__le32 address;204		__le32 data;205	} req = {206		.wifi_stream = cpu_to_le32(wf),207		.address = cpu_to_le32(reg),208	};209 210	return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_QUERY(RF_REG_ACCESS),211				 &req, sizeof(req), true);212}213 214int mt7615_rf_wr(struct mt7615_dev *dev, u32 wf, u32 reg, u32 val)215{216	struct {217		__le32 wifi_stream;218		__le32 address;219		__le32 data;220	} req = {221		.wifi_stream = cpu_to_le32(wf),222		.address = cpu_to_le32(reg),223		.data = cpu_to_le32(val),224	};225 226	return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(RF_REG_ACCESS),227				 &req, sizeof(req), false);228}229 230void mt7622_trigger_hif_int(struct mt7615_dev *dev, bool en)231{232	if (!is_mt7622(&dev->mt76))233		return;234 235	regmap_update_bits(dev->infracfg, MT_INFRACFG_MISC,236			   MT_INFRACFG_MISC_AP2CONN_WAKE,237			   !en * MT_INFRACFG_MISC_AP2CONN_WAKE);238}239EXPORT_SYMBOL_GPL(mt7622_trigger_hif_int);240 241static int mt7615_mcu_drv_pmctrl(struct mt7615_dev *dev)242{243	struct mt76_phy *mphy = &dev->mt76.phy;244	struct mt76_connac_pm *pm = &dev->pm;245	struct mt76_dev *mdev = &dev->mt76;246	u32 addr;247	int err;248 249	if (is_mt7663(mdev)) {250		/* Clear firmware own via N9 eint */251		mt76_wr(dev, MT_PCIE_DOORBELL_PUSH, MT_CFG_LPCR_HOST_DRV_OWN);252		mt76_poll(dev, MT_CONN_ON_MISC, MT_CFG_LPCR_HOST_FW_OWN, 0, 3000);253 254		addr = MT_CONN_HIF_ON_LPCTL;255	} else {256		addr = MT_CFG_LPCR_HOST;257	}258 259	mt76_wr(dev, addr, MT_CFG_LPCR_HOST_DRV_OWN);260 261	mt7622_trigger_hif_int(dev, true);262 263	err = !mt76_poll_msec(dev, addr, MT_CFG_LPCR_HOST_FW_OWN, 0, 3000);264 265	mt7622_trigger_hif_int(dev, false);266 267	if (err) {268		dev_err(mdev->dev, "driver own failed\n");269		return -ETIMEDOUT;270	}271 272	clear_bit(MT76_STATE_PM, &mphy->state);273 274	pm->stats.last_wake_event = jiffies;275	pm->stats.doze_time += pm->stats.last_wake_event -276			       pm->stats.last_doze_event;277 278	return 0;279}280 281static int mt7615_mcu_lp_drv_pmctrl(struct mt7615_dev *dev)282{283	struct mt76_phy *mphy = &dev->mt76.phy;284	struct mt76_connac_pm *pm = &dev->pm;285	int i, err = 0;286 287	mutex_lock(&pm->mutex);288 289	if (!test_bit(MT76_STATE_PM, &mphy->state))290		goto out;291 292	for (i = 0; i < MT7615_DRV_OWN_RETRY_COUNT; i++) {293		mt76_wr(dev, MT_PCIE_DOORBELL_PUSH, MT_CFG_LPCR_HOST_DRV_OWN);294		if (mt76_poll_msec(dev, MT_CONN_HIF_ON_LPCTL,295				   MT_CFG_LPCR_HOST_FW_OWN, 0, 50))296			break;297	}298 299	if (i == MT7615_DRV_OWN_RETRY_COUNT) {300		dev_err(dev->mt76.dev, "driver own failed\n");301		err = -EIO;302		goto out;303	}304	clear_bit(MT76_STATE_PM, &mphy->state);305 306	pm->stats.last_wake_event = jiffies;307	pm->stats.doze_time += pm->stats.last_wake_event -308			       pm->stats.last_doze_event;309out:310	mutex_unlock(&pm->mutex);311 312	return err;313}314 315static int mt7615_mcu_fw_pmctrl(struct mt7615_dev *dev)316{317	struct mt76_phy *mphy = &dev->mt76.phy;318	struct mt76_connac_pm *pm = &dev->pm;319	int err = 0;320	u32 addr;321 322	mutex_lock(&pm->mutex);323 324	if (mt76_connac_skip_fw_pmctrl(mphy, pm))325		goto out;326 327	mt7622_trigger_hif_int(dev, true);328 329	addr = is_mt7663(&dev->mt76) ? MT_CONN_HIF_ON_LPCTL : MT_CFG_LPCR_HOST;330	mt76_wr(dev, addr, MT_CFG_LPCR_HOST_FW_OWN);331 332	if (is_mt7622(&dev->mt76) &&333	    !mt76_poll_msec(dev, addr, MT_CFG_LPCR_HOST_FW_OWN,334			    MT_CFG_LPCR_HOST_FW_OWN, 3000)) {335		dev_err(dev->mt76.dev, "Timeout for firmware own\n");336		clear_bit(MT76_STATE_PM, &mphy->state);337		err = -EIO;338	}339 340	mt7622_trigger_hif_int(dev, false);341	if (!err) {342		pm->stats.last_doze_event = jiffies;343		pm->stats.awake_time += pm->stats.last_doze_event -344					pm->stats.last_wake_event;345	}346out:347	mutex_unlock(&pm->mutex);348 349	return err;350}351 352static void353mt7615_mcu_csa_finish(void *priv, u8 *mac, struct ieee80211_vif *vif)354{355	if (vif->bss_conf.csa_active)356		ieee80211_csa_finish(vif, 0);357}358 359static void360mt7615_mcu_rx_csa_notify(struct mt7615_dev *dev, struct sk_buff *skb)361{362	struct mt7615_phy *ext_phy = mt7615_ext_phy(dev);363	struct mt76_phy *mphy = &dev->mt76.phy;364	struct mt7615_mcu_csa_notify *c;365 366	c = (struct mt7615_mcu_csa_notify *)skb->data;367 368	if (c->omac_idx > EXT_BSSID_MAX)369		return;370 371	if (ext_phy && ext_phy->omac_mask & BIT_ULL(c->omac_idx))372		mphy = dev->mt76.phys[MT_BAND1];373 374	ieee80211_iterate_active_interfaces_atomic(mphy->hw,375			IEEE80211_IFACE_ITER_RESUME_ALL,376			mt7615_mcu_csa_finish, mphy->hw);377}378 379static void380mt7615_mcu_rx_radar_detected(struct mt7615_dev *dev, struct sk_buff *skb)381{382	struct mt76_phy *mphy = &dev->mt76.phy;383	struct mt7615_mcu_rdd_report *r;384 385	r = (struct mt7615_mcu_rdd_report *)skb->data;386 387	if (!dev->radar_pattern.n_pulses && !r->long_detected &&388	    !r->constant_prf_detected && !r->staggered_prf_detected)389		return;390 391	if (r->band_idx && dev->mt76.phys[MT_BAND1])392		mphy = dev->mt76.phys[MT_BAND1];393 394	if (mt76_phy_dfs_state(mphy) < MT_DFS_STATE_CAC)395		return;396 397	ieee80211_radar_detected(mphy->hw, NULL);398	dev->hw_pattern++;399}400 401static void402mt7615_mcu_rx_log_message(struct mt7615_dev *dev, struct sk_buff *skb)403{404	struct mt7615_mcu_rxd *rxd = (struct mt7615_mcu_rxd *)skb->data;405	const char *data = (char *)&rxd[1];406	const char *type;407 408	switch (rxd->s2d_index) {409	case 0:410		type = "N9";411		break;412	case 2:413		type = "CR4";414		break;415	default:416		type = "unknown";417		break;418	}419 420	wiphy_info(mt76_hw(dev)->wiphy, "%s: %.*s", type,421		   (int)(skb->len - sizeof(*rxd)), data);422}423 424static void425mt7615_mcu_rx_ext_event(struct mt7615_dev *dev, struct sk_buff *skb)426{427	struct mt7615_mcu_rxd *rxd = (struct mt7615_mcu_rxd *)skb->data;428 429	switch (rxd->ext_eid) {430	case MCU_EXT_EVENT_RDD_REPORT:431		mt7615_mcu_rx_radar_detected(dev, skb);432		break;433	case MCU_EXT_EVENT_CSA_NOTIFY:434		mt7615_mcu_rx_csa_notify(dev, skb);435		break;436	case MCU_EXT_EVENT_FW_LOG_2_HOST:437		mt7615_mcu_rx_log_message(dev, skb);438		break;439	default:440		break;441	}442}443 444static void445mt7615_mcu_scan_event(struct mt7615_dev *dev, struct sk_buff *skb)446{447	u8 *seq_num = skb->data + sizeof(struct mt7615_mcu_rxd);448	struct mt7615_phy *phy;449	struct mt76_phy *mphy;450 451	if (*seq_num & BIT(7) && dev->mt76.phys[MT_BAND1])452		mphy = dev->mt76.phys[MT_BAND1];453	else454		mphy = &dev->mt76.phy;455 456	phy = mphy->priv;457 458	spin_lock_bh(&dev->mt76.lock);459	__skb_queue_tail(&phy->scan_event_list, skb);460	spin_unlock_bh(&dev->mt76.lock);461 462	ieee80211_queue_delayed_work(mphy->hw, &phy->scan_work,463				     MT7615_HW_SCAN_TIMEOUT);464}465 466static void467mt7615_mcu_roc_event(struct mt7615_dev *dev, struct sk_buff *skb)468{469	struct mt7615_roc_tlv *event;470	struct mt7615_phy *phy;471	struct mt76_phy *mphy;472	int duration;473 474	skb_pull(skb, sizeof(struct mt7615_mcu_rxd));475	event = (struct mt7615_roc_tlv *)skb->data;476 477	if (event->dbdc_band && dev->mt76.phys[MT_BAND1])478		mphy = dev->mt76.phys[MT_BAND1];479	else480		mphy = &dev->mt76.phy;481 482	ieee80211_ready_on_channel(mphy->hw);483 484	phy = mphy->priv;485	phy->roc_grant = true;486	wake_up(&phy->roc_wait);487 488	duration = le32_to_cpu(event->max_interval);489	mod_timer(&phy->roc_timer,490		  round_jiffies_up(jiffies + msecs_to_jiffies(duration)));491}492 493static void494mt7615_mcu_beacon_loss_event(struct mt7615_dev *dev, struct sk_buff *skb)495{496	struct mt76_connac_beacon_loss_event *event;497	struct mt76_phy *mphy;498	u8 band_idx = 0; /* DBDC support */499 500	skb_pull(skb, sizeof(struct mt7615_mcu_rxd));501	event = (struct mt76_connac_beacon_loss_event *)skb->data;502	if (band_idx && dev->mt76.phys[MT_BAND1])503		mphy = dev->mt76.phys[MT_BAND1];504	else505		mphy = &dev->mt76.phy;506 507	ieee80211_iterate_active_interfaces_atomic(mphy->hw,508					IEEE80211_IFACE_ITER_RESUME_ALL,509					mt76_connac_mcu_beacon_loss_iter,510					event);511}512 513static void514mt7615_mcu_bss_event(struct mt7615_dev *dev, struct sk_buff *skb)515{516	struct mt76_connac_mcu_bss_event *event;517	struct mt76_phy *mphy;518	u8 band_idx = 0; /* DBDC support */519 520	skb_pull(skb, sizeof(struct mt7615_mcu_rxd));521	event = (struct mt76_connac_mcu_bss_event *)skb->data;522 523	if (band_idx && dev->mt76.phys[MT_BAND1])524		mphy = dev->mt76.phys[MT_BAND1];525	else526		mphy = &dev->mt76.phy;527 528	if (event->is_absent)529		ieee80211_stop_queues(mphy->hw);530	else531		ieee80211_wake_queues(mphy->hw);532}533 534static void535mt7615_mcu_rx_unsolicited_event(struct mt7615_dev *dev, struct sk_buff *skb)536{537	struct mt7615_mcu_rxd *rxd = (struct mt7615_mcu_rxd *)skb->data;538 539	switch (rxd->eid) {540	case MCU_EVENT_EXT:541		mt7615_mcu_rx_ext_event(dev, skb);542		break;543	case MCU_EVENT_BSS_BEACON_LOSS:544		mt7615_mcu_beacon_loss_event(dev, skb);545		break;546	case MCU_EVENT_ROC:547		mt7615_mcu_roc_event(dev, skb);548		break;549	case MCU_EVENT_SCHED_SCAN_DONE:550	case MCU_EVENT_SCAN_DONE:551		mt7615_mcu_scan_event(dev, skb);552		return;553	case MCU_EVENT_BSS_ABSENCE:554		mt7615_mcu_bss_event(dev, skb);555		break;556	case MCU_EVENT_COREDUMP:557		mt76_connac_mcu_coredump_event(&dev->mt76, skb,558					       &dev->coredump);559		return;560	default:561		break;562	}563	dev_kfree_skb(skb);564}565 566void mt7615_mcu_rx_event(struct mt7615_dev *dev, struct sk_buff *skb)567{568	struct mt7615_mcu_rxd *rxd = (struct mt7615_mcu_rxd *)skb->data;569 570	if (rxd->ext_eid == MCU_EXT_EVENT_THERMAL_PROTECT ||571	    rxd->ext_eid == MCU_EXT_EVENT_FW_LOG_2_HOST ||572	    rxd->ext_eid == MCU_EXT_EVENT_ASSERT_DUMP ||573	    rxd->ext_eid == MCU_EXT_EVENT_PS_SYNC ||574	    rxd->eid == MCU_EVENT_BSS_BEACON_LOSS ||575	    rxd->eid == MCU_EVENT_SCHED_SCAN_DONE ||576	    rxd->eid == MCU_EVENT_BSS_ABSENCE ||577	    rxd->eid == MCU_EVENT_SCAN_DONE ||578	    rxd->eid == MCU_EVENT_COREDUMP ||579	    rxd->eid == MCU_EVENT_ROC ||580	    !rxd->seq)581		mt7615_mcu_rx_unsolicited_event(dev, skb);582	else583		mt76_mcu_rx_event(&dev->mt76, skb);584}585 586static int587mt7615_mcu_muar_config(struct mt7615_dev *dev, struct ieee80211_vif *vif,588		       bool bssid, bool enable)589{590	struct mt7615_vif *mvif = (struct mt7615_vif *)vif->drv_priv;591	u32 idx = mvif->mt76.omac_idx - REPEATER_BSSID_START;592	u32 mask = dev->omac_mask >> 32 & ~BIT(idx);593	const u8 *addr = vif->addr;594	struct {595		u8 mode;596		u8 force_clear;597		u8 clear_bitmap[8];598		u8 entry_count;599		u8 write;600 601		u8 index;602		u8 bssid;603		u8 addr[ETH_ALEN];604	} __packed req = {605		.mode = !!mask || enable,606		.entry_count = 1,607		.write = 1,608 609		.index = idx * 2 + bssid,610	};611 612	if (bssid)613		addr = vif->bss_conf.bssid;614 615	if (enable)616		ether_addr_copy(req.addr, addr);617 618	return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(MUAR_UPDATE),619				 &req, sizeof(req), true);620}621 622static int623mt7615_mcu_add_dev(struct mt7615_phy *phy, struct ieee80211_vif *vif,624		   bool enable)625{626	struct mt7615_vif *mvif = (struct mt7615_vif *)vif->drv_priv;627	struct mt7615_dev *dev = phy->dev;628	struct {629		struct req_hdr {630			u8 omac_idx;631			u8 band_idx;632			__le16 tlv_num;633			u8 is_tlv_append;634			u8 rsv[3];635		} __packed hdr;636		struct req_tlv {637			__le16 tag;638			__le16 len;639			u8 active;640			u8 band_idx;641			u8 omac_addr[ETH_ALEN];642		} __packed tlv;643	} data = {644		.hdr = {645			.omac_idx = mvif->mt76.omac_idx,646			.band_idx = mvif->mt76.band_idx,647			.tlv_num = cpu_to_le16(1),648			.is_tlv_append = 1,649		},650		.tlv = {651			.tag = cpu_to_le16(DEV_INFO_ACTIVE),652			.len = cpu_to_le16(sizeof(struct req_tlv)),653			.active = enable,654			.band_idx = mvif->mt76.band_idx,655		},656	};657 658	if (mvif->mt76.omac_idx >= REPEATER_BSSID_START)659		return mt7615_mcu_muar_config(dev, vif, false, enable);660 661	memcpy(data.tlv.omac_addr, vif->addr, ETH_ALEN);662	return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(DEV_INFO_UPDATE),663				 &data, sizeof(data), true);664}665 666static int667mt7615_mcu_add_beacon_offload(struct mt7615_dev *dev,668			      struct ieee80211_hw *hw,669			      struct ieee80211_vif *vif, bool enable)670{671	struct mt7615_vif *mvif = (struct mt7615_vif *)vif->drv_priv;672	struct mt76_wcid *wcid = &dev->mt76.global_wcid;673	struct ieee80211_mutable_offsets offs;674	struct ieee80211_tx_info *info;675	struct req {676		u8 omac_idx;677		u8 enable;678		u8 wlan_idx;679		u8 band_idx;680		u8 pkt_type;681		u8 need_pre_tbtt_int;682		__le16 csa_ie_pos;683		__le16 pkt_len;684		__le16 tim_ie_pos;685		u8 pkt[512];686		u8 csa_cnt;687		/* bss color change */688		u8 bcc_cnt;689		__le16 bcc_ie_pos;690	} __packed req = {691		.omac_idx = mvif->mt76.omac_idx,692		.enable = enable,693		.wlan_idx = wcid->idx,694		.band_idx = mvif->mt76.band_idx,695	};696	struct sk_buff *skb;697 698	if (!enable)699		goto out;700 701	skb = ieee80211_beacon_get_template(hw, vif, &offs, 0);702	if (!skb)703		return -EINVAL;704 705	if (skb->len > 512 - MT_TXD_SIZE) {706		dev_err(dev->mt76.dev, "Bcn size limit exceed\n");707		dev_kfree_skb(skb);708		return -EINVAL;709	}710 711	info = IEEE80211_SKB_CB(skb);712	info->hw_queue |= FIELD_PREP(MT_TX_HW_QUEUE_PHY, mvif->mt76.band_idx);713 714	mt7615_mac_write_txwi(dev, (__le32 *)(req.pkt), skb, wcid, NULL,715			      0, NULL, 0, true);716	memcpy(req.pkt + MT_TXD_SIZE, skb->data, skb->len);717	req.pkt_len = cpu_to_le16(MT_TXD_SIZE + skb->len);718	req.tim_ie_pos = cpu_to_le16(MT_TXD_SIZE + offs.tim_offset);719	if (offs.cntdwn_counter_offs[0]) {720		u16 csa_offs;721 722		csa_offs = MT_TXD_SIZE + offs.cntdwn_counter_offs[0] - 4;723		req.csa_ie_pos = cpu_to_le16(csa_offs);724		req.csa_cnt = skb->data[offs.cntdwn_counter_offs[0]];725	}726	dev_kfree_skb(skb);727 728out:729	return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(BCN_OFFLOAD), &req,730				 sizeof(req), true);731}732 733static int734mt7615_mcu_ctrl_pm_state(struct mt7615_dev *dev, int band, int state)735{736	return mt76_connac_mcu_set_pm(&dev->mt76, band, state);737}738 739static int740mt7615_mcu_add_bss(struct mt7615_phy *phy, struct ieee80211_vif *vif,741		   struct ieee80211_sta *sta, bool enable)742{743	struct mt7615_vif *mvif = (struct mt7615_vif *)vif->drv_priv;744	struct mt7615_dev *dev = phy->dev;745	struct sk_buff *skb;746 747	if (mvif->mt76.omac_idx >= REPEATER_BSSID_START)748		mt7615_mcu_muar_config(dev, vif, true, enable);749 750	skb = mt76_connac_mcu_alloc_sta_req(&dev->mt76, &mvif->mt76, NULL);751	if (IS_ERR(skb))752		return PTR_ERR(skb);753 754	if (enable)755		mt76_connac_mcu_bss_omac_tlv(skb, vif);756 757	mt76_connac_mcu_bss_basic_tlv(skb, vif, sta, phy->mt76,758				      mvif->sta.wcid.idx, enable);759 760	if (enable && mvif->mt76.omac_idx >= EXT_BSSID_START &&761	    mvif->mt76.omac_idx < REPEATER_BSSID_START)762		mt76_connac_mcu_bss_ext_tlv(skb, &mvif->mt76);763 764	return mt76_mcu_skb_send_msg(&dev->mt76, skb,765				     MCU_EXT_CMD(BSS_INFO_UPDATE), true);766}767 768static int769mt7615_mcu_wtbl_tx_ba(struct mt7615_dev *dev,770		      struct ieee80211_ampdu_params *params,771		      bool enable)772{773	struct mt7615_sta *msta = (struct mt7615_sta *)params->sta->drv_priv;774	struct mt7615_vif *mvif = msta->vif;775	struct wtbl_req_hdr *wtbl_hdr;776	struct sk_buff *skb = NULL;777	int err;778 779	wtbl_hdr = mt76_connac_mcu_alloc_wtbl_req(&dev->mt76, &msta->wcid,780						  WTBL_SET, NULL, &skb);781	if (IS_ERR(wtbl_hdr))782		return PTR_ERR(wtbl_hdr);783 784	mt76_connac_mcu_wtbl_ba_tlv(&dev->mt76, skb, params, enable, true,785				    NULL, wtbl_hdr);786 787	err = mt76_mcu_skb_send_msg(&dev->mt76, skb,788				    MCU_EXT_CMD(WTBL_UPDATE), true);789	if (err < 0)790		return err;791 792	skb = mt76_connac_mcu_alloc_sta_req(&dev->mt76, &mvif->mt76,793					    &msta->wcid);794	if (IS_ERR(skb))795		return PTR_ERR(skb);796 797	mt76_connac_mcu_sta_ba_tlv(skb, params, enable, true);798 799	return mt76_mcu_skb_send_msg(&dev->mt76, skb,800				     MCU_EXT_CMD(STA_REC_UPDATE), true);801}802 803static int804mt7615_mcu_wtbl_rx_ba(struct mt7615_dev *dev,805		      struct ieee80211_ampdu_params *params,806		      bool enable)807{808	struct mt7615_sta *msta = (struct mt7615_sta *)params->sta->drv_priv;809	struct mt7615_vif *mvif = msta->vif;810	struct wtbl_req_hdr *wtbl_hdr;811	struct sk_buff *skb;812	int err;813 814	skb = mt76_connac_mcu_alloc_sta_req(&dev->mt76, &mvif->mt76,815					    &msta->wcid);816	if (IS_ERR(skb))817		return PTR_ERR(skb);818 819	mt76_connac_mcu_sta_ba_tlv(skb, params, enable, false);820 821	err = mt76_mcu_skb_send_msg(&dev->mt76, skb,822				    MCU_EXT_CMD(STA_REC_UPDATE), true);823	if (err < 0 || !enable)824		return err;825 826	skb = NULL;827	wtbl_hdr = mt76_connac_mcu_alloc_wtbl_req(&dev->mt76, &msta->wcid,828						  WTBL_SET, NULL, &skb);829	if (IS_ERR(wtbl_hdr))830		return PTR_ERR(wtbl_hdr);831 832	mt76_connac_mcu_wtbl_ba_tlv(&dev->mt76, skb, params, enable, false,833				    NULL, wtbl_hdr);834 835	return mt76_mcu_skb_send_msg(&dev->mt76, skb,836				     MCU_EXT_CMD(WTBL_UPDATE), true);837}838 839static int840mt7615_mcu_wtbl_sta_add(struct mt7615_phy *phy, struct ieee80211_vif *vif,841			struct ieee80211_sta *sta, bool enable)842{843	struct mt7615_vif *mvif = (struct mt7615_vif *)vif->drv_priv;844	struct sk_buff *skb, *sskb, *wskb = NULL;845	struct ieee80211_link_sta *link_sta;846	struct mt7615_dev *dev = phy->dev;847	struct wtbl_req_hdr *wtbl_hdr;848	struct mt7615_sta *msta;849	bool new_entry = true;850	int conn_state;851	int cmd, err;852 853	msta = sta ? (struct mt7615_sta *)sta->drv_priv : &mvif->sta;854	link_sta = sta ? &sta->deflink : NULL;855 856	sskb = mt76_connac_mcu_alloc_sta_req(&dev->mt76, &mvif->mt76,857					     &msta->wcid);858	if (IS_ERR(sskb))859		return PTR_ERR(sskb);860 861	if (!sta) {862		if (mvif->sta_added)863			new_entry = false;864		else865			mvif->sta_added = true;866	}867	conn_state = enable ? CONN_STATE_PORT_SECURE : CONN_STATE_DISCONNECT;868	mt76_connac_mcu_sta_basic_tlv(&dev->mt76, sskb, vif, link_sta,869				      conn_state, new_entry);870	if (enable && sta)871		mt76_connac_mcu_sta_tlv(phy->mt76, sskb, sta, vif, 0,872					MT76_STA_INFO_STATE_ASSOC);873 874	wtbl_hdr = mt76_connac_mcu_alloc_wtbl_req(&dev->mt76, &msta->wcid,875						  WTBL_RESET_AND_SET, NULL,876						  &wskb);877	if (IS_ERR(wtbl_hdr))878		return PTR_ERR(wtbl_hdr);879 880	if (enable) {881		mt76_connac_mcu_wtbl_generic_tlv(&dev->mt76, wskb, vif, sta,882						 NULL, wtbl_hdr);883		if (sta)884			mt76_connac_mcu_wtbl_ht_tlv(&dev->mt76, wskb, sta,885						    NULL, wtbl_hdr, true, true);886		mt76_connac_mcu_wtbl_hdr_trans_tlv(wskb, vif, &msta->wcid,887						   NULL, wtbl_hdr);888	}889 890	cmd = enable ? MCU_EXT_CMD(WTBL_UPDATE) : MCU_EXT_CMD(STA_REC_UPDATE);891	skb = enable ? wskb : sskb;892 893	err = mt76_mcu_skb_send_msg(&dev->mt76, skb, cmd, true);894	if (err < 0) {895		skb = enable ? sskb : wskb;896		dev_kfree_skb(skb);897 898		return err;899	}900 901	cmd = enable ? MCU_EXT_CMD(STA_REC_UPDATE) : MCU_EXT_CMD(WTBL_UPDATE);902	skb = enable ? sskb : wskb;903 904	return mt76_mcu_skb_send_msg(&dev->mt76, skb, cmd, true);905}906 907static int908mt7615_mcu_wtbl_update_hdr_trans(struct mt7615_dev *dev,909				 struct ieee80211_vif *vif,910				 struct ieee80211_sta *sta)911{912	return mt76_connac_mcu_wtbl_update_hdr_trans(&dev->mt76, vif, sta);913}914 915static const struct mt7615_mcu_ops wtbl_update_ops = {916	.add_beacon_offload = mt7615_mcu_add_beacon_offload,917	.set_pm_state = mt7615_mcu_ctrl_pm_state,918	.add_dev_info = mt7615_mcu_add_dev,919	.add_bss_info = mt7615_mcu_add_bss,920	.add_tx_ba = mt7615_mcu_wtbl_tx_ba,921	.add_rx_ba = mt7615_mcu_wtbl_rx_ba,922	.sta_add = mt7615_mcu_wtbl_sta_add,923	.set_drv_ctrl = mt7615_mcu_drv_pmctrl,924	.set_fw_ctrl = mt7615_mcu_fw_pmctrl,925	.set_sta_decap_offload = mt7615_mcu_wtbl_update_hdr_trans,926};927 928static int929mt7615_mcu_sta_ba(struct mt7615_dev *dev,930		  struct ieee80211_ampdu_params *params,931		  bool enable, bool tx)932{933	struct mt7615_sta *msta = (struct mt7615_sta *)params->sta->drv_priv;934	struct mt7615_vif *mvif = msta->vif;935	struct wtbl_req_hdr *wtbl_hdr;936	struct tlv *sta_wtbl;937	struct sk_buff *skb;938 939	skb = mt76_connac_mcu_alloc_sta_req(&dev->mt76, &mvif->mt76,940					    &msta->wcid);941	if (IS_ERR(skb))942		return PTR_ERR(skb);943 944	mt76_connac_mcu_sta_ba_tlv(skb, params, enable, tx);945 946	sta_wtbl = mt76_connac_mcu_add_tlv(skb, STA_REC_WTBL, sizeof(struct tlv));947 948	wtbl_hdr = mt76_connac_mcu_alloc_wtbl_req(&dev->mt76, &msta->wcid,949						  WTBL_SET, sta_wtbl, &skb);950	if (IS_ERR(wtbl_hdr))951		return PTR_ERR(wtbl_hdr);952 953	mt76_connac_mcu_wtbl_ba_tlv(&dev->mt76, skb, params, enable, tx,954				    sta_wtbl, wtbl_hdr);955 956	return mt76_mcu_skb_send_msg(&dev->mt76, skb,957				     MCU_EXT_CMD(STA_REC_UPDATE), true);958}959 960static int961mt7615_mcu_sta_tx_ba(struct mt7615_dev *dev,962		     struct ieee80211_ampdu_params *params,963		     bool enable)964{965	return mt7615_mcu_sta_ba(dev, params, enable, true);966}967 968static int969mt7615_mcu_sta_rx_ba(struct mt7615_dev *dev,970		     struct ieee80211_ampdu_params *params,971		     bool enable)972{973	return mt7615_mcu_sta_ba(dev, params, enable, false);974}975 976static int977__mt7615_mcu_add_sta(struct mt76_phy *phy, struct ieee80211_vif *vif,978		     struct ieee80211_sta *sta, bool enable, int cmd,979		     bool offload_fw)980{981	struct mt7615_vif *mvif = (struct mt7615_vif *)vif->drv_priv;982	struct mt76_sta_cmd_info info = {983		.sta = sta,984		.vif = vif,985		.offload_fw = offload_fw,986		.enable = enable,987		.newly = true,988		.cmd = cmd,989	};990 991	info.wcid = sta ? (struct mt76_wcid *)sta->drv_priv : &mvif->sta.wcid;992	return mt76_connac_mcu_sta_cmd(phy, &info);993}994 995static int996mt7615_mcu_add_sta(struct mt7615_phy *phy, struct ieee80211_vif *vif,997		   struct ieee80211_sta *sta, bool enable)998{999	return __mt7615_mcu_add_sta(phy->mt76, vif, sta, enable,1000				    MCU_EXT_CMD(STA_REC_UPDATE), false);1001}1002 1003static int1004mt7615_mcu_sta_update_hdr_trans(struct mt7615_dev *dev,1005				struct ieee80211_vif *vif,1006				struct ieee80211_sta *sta)1007{1008	struct mt7615_sta *msta = (struct mt7615_sta *)sta->drv_priv;1009 1010	return mt76_connac_mcu_sta_update_hdr_trans(&dev->mt76,1011						    vif, &msta->wcid,1012						    MCU_EXT_CMD(STA_REC_UPDATE));1013}1014 1015static const struct mt7615_mcu_ops sta_update_ops = {1016	.add_beacon_offload = mt7615_mcu_add_beacon_offload,1017	.set_pm_state = mt7615_mcu_ctrl_pm_state,1018	.add_dev_info = mt7615_mcu_add_dev,1019	.add_bss_info = mt7615_mcu_add_bss,1020	.add_tx_ba = mt7615_mcu_sta_tx_ba,1021	.add_rx_ba = mt7615_mcu_sta_rx_ba,1022	.sta_add = mt7615_mcu_add_sta,1023	.set_drv_ctrl = mt7615_mcu_drv_pmctrl,1024	.set_fw_ctrl = mt7615_mcu_fw_pmctrl,1025	.set_sta_decap_offload = mt7615_mcu_sta_update_hdr_trans,1026};1027 1028static int1029mt7615_mcu_uni_ctrl_pm_state(struct mt7615_dev *dev, int band, int state)1030{1031	return 0;1032}1033 1034static int1035mt7615_mcu_uni_add_beacon_offload(struct mt7615_dev *dev,1036				  struct ieee80211_hw *hw,1037				  struct ieee80211_vif *vif,1038				  bool enable)1039{1040	struct mt7615_vif *mvif = (struct mt7615_vif *)vif->drv_priv;1041	struct mt76_wcid *wcid = &dev->mt76.global_wcid;1042	struct ieee80211_mutable_offsets offs;1043	struct {1044		struct req_hdr {1045			u8 bss_idx;1046			u8 pad[3];1047		} __packed hdr;1048		struct bcn_content_tlv {1049			__le16 tag;1050			__le16 len;1051			__le16 tim_ie_pos;1052			__le16 csa_ie_pos;1053			__le16 bcc_ie_pos;1054			/* 0: disable beacon offload1055			 * 1: enable beacon offload1056			 * 2: update probe respond offload1057			 */1058			u8 enable;1059			/* 0: legacy format (TXD + payload)1060			 * 1: only cap field IE1061			 */1062			u8 type;1063			__le16 pkt_len;1064			u8 pkt[512];1065		} __packed beacon_tlv;1066	} req = {1067		.hdr = {1068			.bss_idx = mvif->mt76.idx,1069		},1070		.beacon_tlv = {1071			.tag = cpu_to_le16(UNI_BSS_INFO_BCN_CONTENT),1072			.len = cpu_to_le16(sizeof(struct bcn_content_tlv)),1073			.enable = enable,1074		},1075	};1076	struct sk_buff *skb;1077 1078	if (!enable)1079		goto out;1080 1081	skb = ieee80211_beacon_get_template(mt76_hw(dev), vif, &offs, 0);1082	if (!skb)1083		return -EINVAL;1084 1085	if (skb->len > 512 - MT_TXD_SIZE) {1086		dev_err(dev->mt76.dev, "beacon size limit exceed\n");1087		dev_kfree_skb(skb);1088		return -EINVAL;1089	}1090 1091	mt7615_mac_write_txwi(dev, (__le32 *)(req.beacon_tlv.pkt), skb,1092			      wcid, NULL, 0, NULL, 0, true);1093	memcpy(req.beacon_tlv.pkt + MT_TXD_SIZE, skb->data, skb->len);1094	req.beacon_tlv.pkt_len = cpu_to_le16(MT_TXD_SIZE + skb->len);1095	req.beacon_tlv.tim_ie_pos = cpu_to_le16(MT_TXD_SIZE + offs.tim_offset);1096 1097	if (offs.cntdwn_counter_offs[0]) {1098		u16 csa_offs;1099 1100		csa_offs = MT_TXD_SIZE + offs.cntdwn_counter_offs[0] - 4;1101		req.beacon_tlv.csa_ie_pos = cpu_to_le16(csa_offs);1102	}1103	dev_kfree_skb(skb);1104 1105out:1106	return mt76_mcu_send_msg(&dev->mt76, MCU_UNI_CMD(BSS_INFO_UPDATE),1107				 &req, sizeof(req), true);1108}1109 1110static int1111mt7615_mcu_uni_add_dev(struct mt7615_phy *phy, struct ieee80211_vif *vif,1112		       bool enable)1113{1114	struct mt7615_vif *mvif = (struct mt7615_vif *)vif->drv_priv;1115 1116	return mt76_connac_mcu_uni_add_dev(phy->mt76, &vif->bss_conf,1117					   &mvif->sta.wcid, enable);1118}1119 1120static int1121mt7615_mcu_uni_add_bss(struct mt7615_phy *phy, struct ieee80211_vif *vif,1122		       struct ieee80211_sta *sta, bool enable)1123{1124	struct mt7615_vif *mvif = (struct mt7615_vif *)vif->drv_priv;1125 1126	return mt76_connac_mcu_uni_add_bss(phy->mt76, vif, &mvif->sta.wcid,1127					   enable, NULL);1128}1129 1130static inline int1131mt7615_mcu_uni_add_sta(struct mt7615_phy *phy, struct ieee80211_vif *vif,1132		       struct ieee80211_sta *sta, bool enable)1133{1134	return __mt7615_mcu_add_sta(phy->mt76, vif, sta, enable,1135				    MCU_UNI_CMD(STA_REC_UPDATE), true);1136}1137 1138static int1139mt7615_mcu_uni_tx_ba(struct mt7615_dev *dev,1140		     struct ieee80211_ampdu_params *params,1141		     bool enable)1142{1143	struct mt7615_sta *sta = (struct mt7615_sta *)params->sta->drv_priv;1144 1145	return mt76_connac_mcu_sta_ba(&dev->mt76, &sta->vif->mt76, params,1146				      MCU_UNI_CMD(STA_REC_UPDATE), enable,1147				      true);1148}1149 1150static int1151mt7615_mcu_uni_rx_ba(struct mt7615_dev *dev,1152		     struct ieee80211_ampdu_params *params,1153		     bool enable)1154{1155	struct mt7615_sta *msta = (struct mt7615_sta *)params->sta->drv_priv;1156	struct mt7615_vif *mvif = msta->vif;1157	struct wtbl_req_hdr *wtbl_hdr;1158	struct tlv *sta_wtbl;1159	struct sk_buff *skb;1160	int err;1161 1162	skb = mt76_connac_mcu_alloc_sta_req(&dev->mt76, &mvif->mt76,1163					    &msta->wcid);1164	if (IS_ERR(skb))1165		return PTR_ERR(skb);1166 1167	mt76_connac_mcu_sta_ba_tlv(skb, params, enable, false);1168 1169	err = mt76_mcu_skb_send_msg(&dev->mt76, skb,1170				    MCU_UNI_CMD(STA_REC_UPDATE), true);1171	if (err < 0 || !enable)1172		return err;1173 1174	skb = mt76_connac_mcu_alloc_sta_req(&dev->mt76, &mvif->mt76,1175					    &msta->wcid);1176	if (IS_ERR(skb))1177		return PTR_ERR(skb);1178 1179	sta_wtbl = mt76_connac_mcu_add_tlv(skb, STA_REC_WTBL,1180					   sizeof(struct tlv));1181 1182	wtbl_hdr = mt76_connac_mcu_alloc_wtbl_req(&dev->mt76, &msta->wcid,1183						  WTBL_SET, sta_wtbl, &skb);1184	if (IS_ERR(wtbl_hdr))1185		return PTR_ERR(wtbl_hdr);1186 1187	mt76_connac_mcu_wtbl_ba_tlv(&dev->mt76, skb, params, enable, false,1188				    sta_wtbl, wtbl_hdr);1189 1190	return mt76_mcu_skb_send_msg(&dev->mt76, skb,1191				     MCU_UNI_CMD(STA_REC_UPDATE), true);1192}1193 1194static int1195mt7615_mcu_sta_uni_update_hdr_trans(struct mt7615_dev *dev,1196				    struct ieee80211_vif *vif,1197				    struct ieee80211_sta *sta)1198{1199	struct mt7615_sta *msta = (struct mt7615_sta *)sta->drv_priv;1200 1201	return mt76_connac_mcu_sta_update_hdr_trans(&dev->mt76,1202						    vif, &msta->wcid,1203						    MCU_UNI_CMD(STA_REC_UPDATE));1204}1205 1206static const struct mt7615_mcu_ops uni_update_ops = {1207	.add_beacon_offload = mt7615_mcu_uni_add_beacon_offload,1208	.set_pm_state = mt7615_mcu_uni_ctrl_pm_state,1209	.add_dev_info = mt7615_mcu_uni_add_dev,1210	.add_bss_info = mt7615_mcu_uni_add_bss,1211	.add_tx_ba = mt7615_mcu_uni_tx_ba,1212	.add_rx_ba = mt7615_mcu_uni_rx_ba,1213	.sta_add = mt7615_mcu_uni_add_sta,1214	.set_drv_ctrl = mt7615_mcu_lp_drv_pmctrl,1215	.set_fw_ctrl = mt7615_mcu_fw_pmctrl,1216	.set_sta_decap_offload = mt7615_mcu_sta_uni_update_hdr_trans,1217};1218 1219int mt7615_mcu_restart(struct mt76_dev *dev)1220{1221	return mt76_mcu_send_msg(dev, MCU_CMD(RESTART_DL_REQ), NULL, 0, true);1222}1223EXPORT_SYMBOL_GPL(mt7615_mcu_restart);1224 1225static int mt7615_load_patch(struct mt7615_dev *dev, u32 addr, const char *name)1226{1227	const struct mt7615_patch_hdr *hdr;1228	const struct firmware *fw = NULL;1229	int len, ret, sem;1230 1231	ret = firmware_request_nowarn(&fw, name, dev->mt76.dev);1232	if (ret)1233		return ret;1234 1235	if (!fw || !fw->data || fw->size < sizeof(*hdr)) {1236		dev_err(dev->mt76.dev, "Invalid firmware\n");1237		ret = -EINVAL;1238		goto release_fw;1239	}1240 1241	sem = mt76_connac_mcu_patch_sem_ctrl(&dev->mt76, true);1242	switch (sem) {1243	case PATCH_IS_DL:1244		goto release_fw;1245	case PATCH_NOT_DL_SEM_SUCCESS:1246		break;1247	default:1248		dev_err(dev->mt76.dev, "Failed to get patch semaphore\n");1249		ret = -EAGAIN;1250		goto release_fw;1251	}1252 1253	hdr = (const struct mt7615_patch_hdr *)(fw->data);1254 1255	dev_info(dev->mt76.dev, "HW/SW Version: 0x%x, Build Time: %.16s\n",1256		 be32_to_cpu(hdr->hw_sw_ver), hdr->build_date);1257 1258	len = fw->size - sizeof(*hdr);1259 1260	ret = mt76_connac_mcu_init_download(&dev->mt76, addr, len,1261					    DL_MODE_NEED_RSP);1262	if (ret) {1263		dev_err(dev->mt76.dev, "Download request failed\n");1264		goto out;1265	}1266 1267	ret = mt76_mcu_send_firmware(&dev->mt76, MCU_CMD(FW_SCATTER),1268				     fw->data + sizeof(*hdr), len);1269	if (ret) {1270		dev_err(dev->mt76.dev, "Failed to send firmware to device\n");1271		goto out;1272	}1273 1274	ret = mt76_connac_mcu_start_patch(&dev->mt76);1275	if (ret)1276		dev_err(dev->mt76.dev, "Failed to start patch\n");1277 1278out:1279	sem = mt76_connac_mcu_patch_sem_ctrl(&dev->mt76, false);1280	switch (sem) {1281	case PATCH_REL_SEM_SUCCESS:1282		break;1283	default:1284		ret = -EAGAIN;1285		dev_err(dev->mt76.dev, "Failed to release patch semaphore\n");1286		break;1287	}1288 1289release_fw:1290	release_firmware(fw);1291 1292	return ret;1293}1294 1295static int1296mt7615_mcu_send_ram_firmware(struct mt7615_dev *dev,1297			     const struct mt7615_fw_trailer *hdr,1298			     const u8 *data, bool is_cr4)1299{1300	int n_region = is_cr4 ? CR4_REGION_NUM : N9_REGION_NUM;1301	int err, i, offset = 0;1302	u32 len, addr, mode;1303 1304	for (i = 0; i < n_region; i++) {1305		mode = mt76_connac_mcu_gen_dl_mode(&dev->mt76,1306						   hdr[i].feature_set, is_cr4);1307		len = le32_to_cpu(hdr[i].len) + IMG_CRC_LEN;1308		addr = le32_to_cpu(hdr[i].addr);1309 1310		err = mt76_connac_mcu_init_download(&dev->mt76, addr, len,1311						    mode);1312		if (err) {1313			dev_err(dev->mt76.dev, "Download request failed\n");1314			return err;1315		}1316 1317		err = mt76_mcu_send_firmware(&dev->mt76, MCU_CMD(FW_SCATTER),1318					     data + offset, len);1319		if (err) {1320			dev_err(dev->mt76.dev, "Failed to send firmware to device\n");1321			return err;1322		}1323 1324		offset += len;1325	}1326 1327	return 0;1328}1329 1330static int mt7615_load_n9(struct mt7615_dev *dev, const char *name)1331{1332	const struct mt7615_fw_trailer *hdr;1333	const struct firmware *fw;1334	int ret;1335 1336	ret = request_firmware(&fw, name, dev->mt76.dev);1337	if (ret)1338		return ret;1339 1340	if (!fw || !fw->data || fw->size < N9_REGION_NUM * sizeof(*hdr)) {1341		dev_err(dev->mt76.dev, "Invalid firmware\n");1342		ret = -EINVAL;1343		goto out;1344	}1345 1346	hdr = (const struct mt7615_fw_trailer *)(fw->data + fw->size -1347					N9_REGION_NUM * sizeof(*hdr));1348 1349	dev_info(dev->mt76.dev, "N9 Firmware Version: %.10s, Build Time: %.15s\n",1350		 hdr->fw_ver, hdr->build_date);1351 1352	ret = mt7615_mcu_send_ram_firmware(dev, hdr, fw->data, false);1353	if (ret)1354		goto out;1355 1356	ret = mt76_connac_mcu_start_firmware(&dev->mt76,1357					     le32_to_cpu(hdr->addr),1358					     FW_START_OVERRIDE);1359	if (ret) {1360		dev_err(dev->mt76.dev, "Failed to start N9 firmware\n");1361		goto out;1362	}1363 1364	snprintf(dev->mt76.hw->wiphy->fw_version,1365		 sizeof(dev->mt76.hw->wiphy->fw_version),1366		 "%.10s-%.15s", hdr->fw_ver, hdr->build_date);1367 1368	if (!is_mt7615(&dev->mt76)) {1369		dev->fw_ver = MT7615_FIRMWARE_V2;1370		dev->mcu_ops = &sta_update_ops;1371	} else {1372		dev->fw_ver = MT7615_FIRMWARE_V1;1373		dev->mcu_ops = &wtbl_update_ops;1374	}1375 1376out:1377	release_firmware(fw);1378	return ret;1379}1380 1381static int mt7615_load_cr4(struct mt7615_dev *dev, const char *name)1382{1383	const struct mt7615_fw_trailer *hdr;1384	const struct firmware *fw;1385	int ret;1386 1387	ret = request_firmware(&fw, name, dev->mt76.dev);1388	if (ret)1389		return ret;1390 1391	if (!fw || !fw->data || fw->size < CR4_REGION_NUM * sizeof(*hdr)) {1392		dev_err(dev->mt76.dev, "Invalid firmware\n");1393		ret = -EINVAL;1394		goto out;1395	}1396 1397	hdr = (const struct mt7615_fw_trailer *)(fw->data + fw->size -1398					CR4_REGION_NUM * sizeof(*hdr));1399 1400	dev_info(dev->mt76.dev, "CR4 Firmware Version: %.10s, Build Time: %.15s\n",1401		 hdr->fw_ver, hdr->build_date);1402 1403	ret = mt7615_mcu_send_ram_firmware(dev, hdr, fw->data, true);1404	if (ret)1405		goto out;1406 1407	ret = mt76_connac_mcu_start_firmware(&dev->mt76, 0,1408					     FW_START_WORKING_PDA_CR4);1409	if (ret) {1410		dev_err(dev->mt76.dev, "Failed to start CR4 firmware\n");1411		goto out;1412	}1413 1414out:1415	release_firmware(fw);1416 1417	return ret;1418}1419 1420static int mt7615_load_ram(struct mt7615_dev *dev)1421{1422	int ret;1423 1424	ret = mt7615_load_n9(dev, MT7615_FIRMWARE_N9);1425	if (ret)1426		return ret;1427 1428	return mt7615_load_cr4(dev, MT7615_FIRMWARE_CR4);1429}1430 1431static int mt7615_load_firmware(struct mt7615_dev *dev)1432{1433	int ret;1434	u32 val;1435 1436	val = mt76_get_field(dev, MT_TOP_MISC2, MT_TOP_MISC2_FW_STATE);1437 1438	if (val != FW_STATE_FW_DOWNLOAD) {1439		dev_err(dev->mt76.dev, "Firmware is not ready for download\n");1440		return -EIO;1441	}1442 1443	ret = mt7615_load_patch(dev, MT7615_PATCH_ADDRESS, MT7615_ROM_PATCH);1444	if (ret)1445		return ret;1446 1447	ret = mt7615_load_ram(dev);1448	if (ret)1449		return ret;1450 1451	if (!mt76_poll_msec(dev, MT_TOP_MISC2, MT_TOP_MISC2_FW_STATE,1452			    FIELD_PREP(MT_TOP_MISC2_FW_STATE,1453				       FW_STATE_RDY), 500)) {1454		dev_err(dev->mt76.dev, "Timeout for initializing firmware\n");1455		return -EIO;1456	}1457 1458	return 0;1459}1460 1461static int mt7622_load_firmware(struct mt7615_dev *dev)1462{1463	int ret;1464	u32 val;1465 1466	mt76_set(dev, MT_WPDMA_GLO_CFG, MT_WPDMA_GLO_CFG_BYPASS_TX_SCH);1467 1468	val = mt76_get_field(dev, MT_TOP_OFF_RSV, MT_TOP_OFF_RSV_FW_STATE);1469	if (val != FW_STATE_FW_DOWNLOAD) {1470		dev_err(dev->mt76.dev, "Firmware is not ready for download\n");1471		return -EIO;1472	}1473 1474	ret = mt7615_load_patch(dev, MT7622_PATCH_ADDRESS, MT7622_ROM_PATCH);1475	if (ret)1476		return ret;1477 1478	ret = mt7615_load_n9(dev, MT7622_FIRMWARE_N9);1479	if (ret)1480		return ret;1481 1482	if (!mt76_poll_msec(dev, MT_TOP_OFF_RSV, MT_TOP_OFF_RSV_FW_STATE,1483			    FIELD_PREP(MT_TOP_OFF_RSV_FW_STATE,1484				       FW_STATE_NORMAL_TRX), 1500)) {1485		dev_err(dev->mt76.dev, "Timeout for initializing firmware\n");1486		return -EIO;1487	}1488 1489	mt76_clear(dev, MT_WPDMA_GLO_CFG, MT_WPDMA_GLO_CFG_BYPASS_TX_SCH);1490 1491	return 0;1492}1493 1494int mt7615_mcu_fw_log_2_host(struct mt7615_dev *dev, u8 ctrl)1495{1496	struct {1497		u8 ctrl_val;1498		u8 pad[3];1499	} data = {1500		.ctrl_val = ctrl1501	};1502 1503	return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(FW_LOG_2_HOST),1504				 &data, sizeof(data), true);1505}1506 1507static int mt7615_mcu_cal_cache_apply(struct mt7615_dev *dev)1508{1509	struct {1510		bool cache_enable;1511		u8 pad[3];1512	} data = {1513		.cache_enable = true1514	};1515 1516	return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(CAL_CACHE), &data,1517				 sizeof(data), false);1518}1519 1520static int mt7663_load_n9(struct mt7615_dev *dev, const char *name)1521{1522	u32 offset = 0, override_addr = 0, flag = FW_START_DLYCAL;1523	const struct mt76_connac2_fw_trailer *hdr;1524	const struct mt7663_fw_buf *buf;1525	const struct firmware *fw;1526	const u8 *base_addr;1527	int i, ret;1528 1529	ret = request_firmware(&fw, name, dev->mt76.dev);1530	if (ret)1531		return ret;1532 1533	if (!fw || !fw->data || fw->size < FW_V3_COMMON_TAILER_SIZE) {1534		dev_err(dev->mt76.dev, "Invalid firmware\n");1535		ret = -EINVAL;1536		goto out;1537	}1538 1539	hdr = (const void *)(fw->data + fw->size - FW_V3_COMMON_TAILER_SIZE);1540	dev_info(dev->mt76.dev, "N9 Firmware Version: %.10s, Build Time: %.15s\n",1541		 hdr->fw_ver, hdr->build_date);1542	dev_info(dev->mt76.dev, "Region number: 0x%x\n", hdr->n_region);1543 1544	base_addr = fw->data + fw->size - FW_V3_COMMON_TAILER_SIZE;1545	for (i = 0; i < hdr->n_region; i++) {1546		u32 shift = (hdr->n_region - i) * FW_V3_REGION_TAILER_SIZE;1547		u32 len, addr, mode;1548 1549		dev_info(dev->mt76.dev, "Parsing tailer Region: %d\n", i);1550 1551		buf = (const struct mt7663_fw_buf *)(base_addr - shift);1552		mode = mt76_connac_mcu_gen_dl_mode(&dev->mt76,1553						   buf->feature_set, false);1554		addr = le32_to_cpu(buf->img_dest_addr);1555		len = le32_to_cpu(buf->img_size);1556 1557		ret = mt76_connac_mcu_init_download(&dev->mt76, addr, len,1558						    mode);1559		if (ret) {1560			dev_err(dev->mt76.dev, "Download request failed\n");1561			goto out;1562		}1563 1564		ret = mt76_mcu_send_firmware(&dev->mt76, MCU_CMD(FW_SCATTER),1565					     fw->data + offset, len);1566		if (ret) {1567			dev_err(dev->mt76.dev, "Failed to send firmware\n");1568			goto out;1569		}1570 1571		offset += le32_to_cpu(buf->img_size);1572		if (buf->feature_set & DL_MODE_VALID_RAM_ENTRY) {1573			override_addr = le32_to_cpu(buf->img_dest_addr);1574			dev_info(dev->mt76.dev, "Region %d, override_addr = 0x%08x\n",1575				 i, override_addr);1576		}1577	}1578 1579	if (override_addr)1580		flag |= FW_START_OVERRIDE;1581 1582	dev_info(dev->mt76.dev, "override_addr = 0x%08x, option = %d\n",1583		 override_addr, flag);1584 1585	ret = mt76_connac_mcu_start_firmware(&dev->mt76, override_addr, flag);1586	if (ret) {1587		dev_err(dev->mt76.dev, "Failed to start N9 firmware\n");1588		goto out;1589	}1590 1591	snprintf(dev->mt76.hw->wiphy->fw_version,1592		 sizeof(dev->mt76.hw->wiphy->fw_version),1593		 "%.10s-%.15s", hdr->fw_ver, hdr->build_date);1594 1595out:1596	release_firmware(fw);1597 1598	return ret;1599}1600 1601static int1602mt7663_load_rom_patch(struct mt7615_dev *dev, const char **n9_firmware)1603{1604	const char *selected_rom, *secondary_rom = MT7663_ROM_PATCH;1605	const char *primary_rom = MT7663_OFFLOAD_ROM_PATCH;1606	int ret;1607 1608	if (!prefer_offload_fw) {1609		secondary_rom = MT7663_OFFLOAD_ROM_PATCH;1610		primary_rom = MT7663_ROM_PATCH;1611	}1612	selected_rom = primary_rom;1613 1614	ret = mt7615_load_patch(dev, MT7663_PATCH_ADDRESS, primary_rom);1615	if (ret) {1616		dev_info(dev->mt76.dev, "%s not found, switching to %s",1617			 primary_rom, secondary_rom);1618		ret = mt7615_load_patch(dev, MT7663_PATCH_ADDRESS,1619					secondary_rom);1620		if (ret) {1621			dev_err(dev->mt76.dev, "failed to load %s",1622				secondary_rom);1623			return ret;1624		}1625		selected_rom = secondary_rom;1626	}1627 1628	if (!strcmp(selected_rom, MT7663_OFFLOAD_ROM_PATCH)) {1629		*n9_firmware = MT7663_OFFLOAD_FIRMWARE_N9;1630		dev->fw_ver = MT7615_FIRMWARE_V3;1631		dev->mcu_ops = &uni_update_ops;1632	} else {1633		*n9_firmware = MT7663_FIRMWARE_N9;1634		dev->fw_ver = MT7615_FIRMWARE_V2;1635		dev->mcu_ops = &sta_update_ops;1636	}1637 1638	return 0;1639}1640 1641int __mt7663_load_firmware(struct mt7615_dev *dev)1642{1643	const char *n9_firmware;1644	int ret;1645 1646	ret = mt76_get_field(dev, MT_CONN_ON_MISC, MT_TOP_MISC2_FW_N9_RDY);1647	if (ret) {1648		dev_dbg(dev->mt76.dev, "Firmware is already download\n");1649		return -EIO;1650	}1651 1652	ret = mt7663_load_rom_patch(dev, &n9_firmware);1653	if (ret)1654		return ret;1655 1656	ret = mt7663_load_n9(dev, n9_firmware);1657	if (ret)1658		return ret;1659 1660	if (!mt76_poll_msec(dev, MT_CONN_ON_MISC, MT_TOP_MISC2_FW_N9_RDY,1661			    MT_TOP_MISC2_FW_N9_RDY, 1500)) {1662		ret = mt76_get_field(dev, MT_CONN_ON_MISC,1663				     MT7663_TOP_MISC2_FW_STATE);1664		dev_err(dev->mt76.dev, "Timeout for initializing firmware\n");1665		return -EIO;1666	}1667 1668#ifdef CONFIG_PM1669	if (mt7615_firmware_offload(dev))1670		dev->mt76.hw->wiphy->wowlan = &mt76_connac_wowlan_support;1671#endif /* CONFIG_PM */1672 1673	dev_dbg(dev->mt76.dev, "Firmware init done\n");1674 1675	return 0;1676}1677EXPORT_SYMBOL_GPL(__mt7663_load_firmware);1678 1679static int mt7663_load_firmware(struct mt7615_dev *dev)1680{1681	int ret;1682 1683	mt76_set(dev, MT_WPDMA_GLO_CFG, MT_WPDMA_GLO_CFG_BYPASS_TX_SCH);1684 1685	ret = __mt7663_load_firmware(dev);1686	if (ret)1687		return ret;1688 1689	mt76_clear(dev, MT_WPDMA_GLO_CFG, MT_WPDMA_GLO_CFG_BYPASS_TX_SCH);1690 1691	return 0;1692}1693 1694int mt7615_mcu_init(struct mt7615_dev *dev)1695{1696	static const struct mt76_mcu_ops mt7615_mcu_ops = {1697		.headroom = sizeof(struct mt7615_mcu_txd),1698		.mcu_skb_send_msg = mt7615_mcu_send_message,1699		.mcu_parse_response = mt7615_mcu_parse_response,1700	};1701	int ret;1702 1703	dev->mt76.mcu_ops = &mt7615_mcu_ops,1704 1705	ret = mt7615_mcu_drv_pmctrl(dev);1706	if (ret)1707		return ret;1708 1709	switch (mt76_chip(&dev->mt76)) {1710	case 0x7622:1711		ret = mt7622_load_firmware(dev);1712		break;1713	case 0x7663:1714		ret = mt7663_load_firmware(dev);1715		break;1716	default:1717		ret = mt7615_load_firmware(dev);1718		break;1719	}1720	if (ret)1721		return ret;1722 1723	mt76_queue_tx_cleanup(dev, dev->mt76.q_mcu[MT_MCUQ_FWDL], false);1724	dev_dbg(dev->mt76.dev, "Firmware init done\n");1725	set_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state);1726 1727	if (dev->dbdc_support) {1728		ret = mt7615_mcu_cal_cache_apply(dev);1729		if (ret)1730			return ret;1731	}1732 1733	return mt7615_mcu_fw_log_2_host(dev, 0);1734}1735EXPORT_SYMBOL_GPL(mt7615_mcu_init);1736 1737void mt7615_mcu_exit(struct mt7615_dev *dev)1738{1739	mt7615_mcu_restart(&dev->mt76);1740	mt7615_mcu_set_fw_ctrl(dev);1741	skb_queue_purge(&dev->mt76.mcu.res_q);1742}1743EXPORT_SYMBOL_GPL(mt7615_mcu_exit);1744 1745int mt7615_mcu_set_eeprom(struct mt7615_dev *dev)1746{1747	struct {1748		u8 buffer_mode;1749		u8 content_format;1750		__le16 len;1751	} __packed req_hdr = {1752		.buffer_mode = 1,1753	};1754	u8 *eep = (u8 *)dev->mt76.eeprom.data;1755	struct sk_buff *skb;1756	int eep_len, offset;1757 1758	switch (mt76_chip(&dev->mt76)) {1759	case 0x7622:1760		eep_len = MT7622_EE_MAX - MT_EE_NIC_CONF_0;1761		offset = MT_EE_NIC_CONF_0;1762		break;1763	case 0x7663:1764		eep_len = MT7663_EE_MAX - MT_EE_CHIP_ID;1765		req_hdr.content_format = 1;1766		offset = MT_EE_CHIP_ID;1767		break;1768	default:1769		eep_len = MT7615_EE_MAX - MT_EE_NIC_CONF_0;1770		offset = MT_EE_NIC_CONF_0;1771		break;1772	}1773 1774	req_hdr.len = cpu_to_le16(eep_len);1775 1776	skb = mt76_mcu_msg_alloc(&dev->mt76, NULL, sizeof(req_hdr) + eep_len);1777	if (!skb)1778		return -ENOMEM;1779 1780	skb_put_data(skb, &req_hdr, sizeof(req_hdr));1781	skb_put_data(skb, eep + offset, eep_len);1782 1783	return mt76_mcu_skb_send_msg(&dev->mt76, skb,1784				     MCU_EXT_CMD(EFUSE_BUFFER_MODE), true);1785}1786 1787int mt7615_mcu_set_wmm(struct mt7615_dev *dev, u8 queue,1788		       const struct ieee80211_tx_queue_params *params)1789{1790#define WMM_AIFS_SET	BIT(0)1791#define WMM_CW_MIN_SET	BIT(1)1792#define WMM_CW_MAX_SET	BIT(2)1793#define WMM_TXOP_SET	BIT(3)1794#define WMM_PARAM_SET	(WMM_AIFS_SET | WMM_CW_MIN_SET | \1795			 WMM_CW_MAX_SET | WMM_TXOP_SET)1796	struct req_data {1797		u8 number;1798		u8 rsv[3];1799		u8 queue;1800		u8 valid;1801		u8 aifs;1802		u8 cw_min;1803		__le16 cw_max;1804		__le16 txop;1805	} __packed req = {1806		.number = 1,1807		.queue = queue,1808		.valid = WMM_PARAM_SET,1809		.aifs = params->aifs,1810		.cw_min = 5,1811		.cw_max = cpu_to_le16(10),1812		.txop = cpu_to_le16(params->txop),1813	};1814 1815	if (params->cw_min)1816		req.cw_min = fls(params->cw_min);1817	if (params->cw_max)1818		req.cw_max = cpu_to_le16(fls(params->cw_max));1819 1820	return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(EDCA_UPDATE),1821				 &req, sizeof(req), true);1822}1823 1824int mt7615_mcu_set_dbdc(struct mt7615_dev *dev)1825{1826	struct mt7615_phy *ext_phy = mt7615_ext_phy(dev);1827	struct dbdc_entry {1828		u8 type;1829		u8 index;1830		u8 band;1831		u8 _rsv;1832	};1833	struct {1834		u8 enable;1835		u8 num;1836		u8 _rsv[2];1837		struct dbdc_entry entry[64];1838	} req = {1839		.enable = !!ext_phy,1840	};1841	int i;1842 1843	if (!ext_phy)1844		goto out;1845 1846#define ADD_DBDC_ENTRY(_type, _idx, _band)		\1847	do { \1848		req.entry[req.num].type = _type;		\1849		req.entry[req.num].index = _idx;		\1850		req.entry[req.num++].band = _band;		\1851	} while (0)1852 1853	for (i = 0; i < 4; i++) {1854		bool band = !!(ext_phy->omac_mask & BIT_ULL(i));1855 1856		ADD_DBDC_ENTRY(DBDC_TYPE_BSS, i, band);1857	}1858 1859	for (i = 0; i < 14; i++) {1860		bool band = !!(ext_phy->omac_mask & BIT_ULL(0x11 + i));1861 1862		ADD_DBDC_ENTRY(DBDC_TYPE_MBSS, i, band);1863	}1864 1865	ADD_DBDC_ENTRY(DBDC_TYPE_MU, 0, 1);1866 1867	for (i = 0; i < 3; i++)1868		ADD_DBDC_ENTRY(DBDC_TYPE_BF, i, 1);1869 1870	ADD_DBDC_ENTRY(DBDC_TYPE_WMM, 0, 0);1871	ADD_DBDC_ENTRY(DBDC_TYPE_WMM, 1, 0);1872	ADD_DBDC_ENTRY(DBDC_TYPE_WMM, 2, 1);1873	ADD_DBDC_ENTRY(DBDC_TYPE_WMM, 3, 1);1874 1875	ADD_DBDC_ENTRY(DBDC_TYPE_MGMT, 0, 0);1876	ADD_DBDC_ENTRY(DBDC_TYPE_MGMT, 1, 1);1877 1878out:1879	return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(DBDC_CTRL), &req,1880				 sizeof(req), true);1881}1882 1883int mt7615_mcu_set_fcc5_lpn(struct mt7615_dev *dev, int val)1884{1885	struct {1886		__le16 tag;1887		__le16 min_lpn;1888	} req = {1889		.tag = cpu_to_le16(0x1),1890		.min_lpn = cpu_to_le16(val),1891	};1892 1893	return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(SET_RADAR_TH),1894				 &req, sizeof(req), true);1895}1896 1897int mt7615_mcu_set_pulse_th(struct mt7615_dev *dev,1898			    const struct mt7615_dfs_pulse *pulse)1899{1900	struct {1901		__le16 tag;1902		__le32 max_width;	/* us */1903		__le32 max_pwr;		/* dbm */1904		__le32 min_pwr;		/* dbm */1905		__le32 min_stgr_pri;	/* us */1906		__le32 max_stgr_pri;	/* us */1907		__le32 min_cr_pri;	/* us */1908		__le32 max_cr_pri;	/* us */1909	} req = {1910		.tag = cpu_to_le16(0x3),1911#define __req_field(field) .field = cpu_to_le32(pulse->field)1912		__req_field(max_width),1913		__req_field(max_pwr),1914		__req_field(min_pwr),1915		__req_field(min_stgr_pri),1916		__req_field(max_stgr_pri),1917		__req_field(min_cr_pri),1918		__req_field(max_cr_pri),1919#undef  __req_field1920	};1921 1922	return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(SET_RADAR_TH),1923				 &req, sizeof(req), true);1924}1925 1926int mt7615_mcu_set_radar_th(struct mt7615_dev *dev, int index,1927			    const struct mt7615_dfs_pattern *pattern)1928{1929	struct {1930		__le16 tag;1931		__le16 radar_type;1932		u8 enb;1933		u8 stgr;1934		u8 min_crpn;1935		u8 max_crpn;1936		u8 min_crpr;1937		u8 min_pw;1938		u8 max_pw;1939		__le32 min_pri;1940		__le32 max_pri;1941		u8 min_crbn;1942		u8 max_crbn;1943		u8 min_stgpn;1944		u8 max_stgpn;1945		u8 min_stgpr;1946	} req = {1947		.tag = cpu_to_le16(0x2),1948		.radar_type = cpu_to_le16(index),1949#define __req_field_u8(field) .field = pattern->field1950#define __req_field_u32(field) .field = cpu_to_le32(pattern->field)1951		__req_field_u8(enb),1952		__req_field_u8(stgr),1953		__req_field_u8(min_crpn),1954		__req_field_u8(max_crpn),1955		__req_field_u8(min_crpr),1956		__req_field_u8(min_pw),1957		__req_field_u8(max_pw),1958		__req_field_u32(min_pri),1959		__req_field_u32(max_pri),1960		__req_field_u8(min_crbn),1961		__req_field_u8(max_crbn),1962		__req_field_u8(min_stgpn),1963		__req_field_u8(max_stgpn),1964		__req_field_u8(min_stgpr),1965#undef __req_field_u81966#undef __req_field_u321967	};1968 1969	return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(SET_RADAR_TH),1970				 &req, sizeof(req), true);1971}1972 1973int mt7615_mcu_rdd_send_pattern(struct mt7615_dev *dev)1974{1975	struct {1976		u8 pulse_num;1977		u8 rsv[3];1978		struct {1979			__le32 start_time;1980			__le16 width;1981			__le16 power;1982		} pattern[32];1983	} req = {1984		.pulse_num = dev->radar_pattern.n_pulses,1985	};1986	u32 start_time = ktime_to_ms(ktime_get_boottime());1987	int i;1988 1989	if (dev->radar_pattern.n_pulses > ARRAY_SIZE(req.pattern))1990		return -EINVAL;1991 1992	/* TODO: add some noise here */1993	for (i = 0; i < dev->radar_pattern.n_pulses; i++) {1994		u32 ts = start_time + i * dev->radar_pattern.period;1995 1996		req.pattern[i].width = cpu_to_le16(dev->radar_pattern.width);1997		req.pattern[i].power = cpu_to_le16(dev->radar_pattern.power);1998		req.pattern[i].start_time = cpu_to_le32(ts);1999	}2000 2001	return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(SET_RDD_PATTERN),2002				 &req, sizeof(req), false);2003}2004 2005static void mt7615_mcu_set_txpower_sku(struct mt7615_phy *phy, u8 *sku)2006{2007	struct mt76_phy *mphy = phy->mt76;2008	struct ieee80211_hw *hw = mphy->hw;2009	struct mt76_power_limits limits;2010	s8 *limits_array = (s8 *)&limits;2011	int n_chains = hweight8(mphy->antenna_mask);2012	int tx_power = hw->conf.power_level * 2;2013	int i;2014	static const u8 sku_mapping[] = {2015#define SKU_FIELD(_type, _field) \2016		[MT_SKU_##_type] = offsetof(struct mt76_power_limits, _field)2017		SKU_FIELD(CCK_1_2, cck[0]),2018		SKU_FIELD(CCK_55_11, cck[2]),2019		SKU_FIELD(OFDM_6_9, ofdm[0]),2020		SKU_FIELD(OFDM_12_18, ofdm[2]),2021		SKU_FIELD(OFDM_24_36, ofdm[4]),2022		SKU_FIELD(OFDM_48, ofdm[6]),2023		SKU_FIELD(OFDM_54, ofdm[7]),2024		SKU_FIELD(HT20_0_8, mcs[0][0]),2025		SKU_FIELD(HT20_32, ofdm[0]),2026		SKU_FIELD(HT20_1_2_9_10, mcs[0][1]),2027		SKU_FIELD(HT20_3_4_11_12, mcs[0][3]),2028		SKU_FIELD(HT20_5_13, mcs[0][5]),2029		SKU_FIELD(HT20_6_14, mcs[0][6]),2030		SKU_FIELD(HT20_7_15, mcs[0][7]),2031		SKU_FIELD(HT40_0_8, mcs[1][0]),2032		SKU_FIELD(HT40_32, ofdm[0]),2033		SKU_FIELD(HT40_1_2_9_10, mcs[1][1]),2034		SKU_FIELD(HT40_3_4_11_12, mcs[1][3]),2035		SKU_FIELD(HT40_5_13, mcs[1][5]),2036		SKU_FIELD(HT40_6_14, mcs[1][6]),2037		SKU_FIELD(HT40_7_15, mcs[1][7]),2038		SKU_FIELD(VHT20_0, mcs[0][0]),2039		SKU_FIELD(VHT20_1_2, mcs[0][1]),2040		SKU_FIELD(VHT20_3_4, mcs[0][3]),2041		SKU_FIELD(VHT20_5_6, mcs[0][5]),2042		SKU_FIELD(VHT20_7, mcs[0][7]),2043		SKU_FIELD(VHT20_8, mcs[0][8]),2044		SKU_FIELD(VHT20_9, mcs[0][9]),2045		SKU_FIELD(VHT40_0, mcs[1][0]),2046		SKU_FIELD(VHT40_1_2, mcs[1][1]),2047		SKU_FIELD(VHT40_3_4, mcs[1][3]),2048		SKU_FIELD(VHT40_5_6, mcs[1][5]),2049		SKU_FIELD(VHT40_7, mcs[1][7]),2050		SKU_FIELD(VHT40_8, mcs[1][8]),2051		SKU_FIELD(VHT40_9, mcs[1][9]),2052		SKU_FIELD(VHT80_0, mcs[2][0]),2053		SKU_FIELD(VHT80_1_2, mcs[2][1]),2054		SKU_FIELD(VHT80_3_4, mcs[2][3]),2055		SKU_FIELD(VHT80_5_6, mcs[2][5]),2056		SKU_FIELD(VHT80_7, mcs[2][7]),2057		SKU_FIELD(VHT80_8, mcs[2][8]),2058		SKU_FIELD(VHT80_9, mcs[2][9]),2059		SKU_FIELD(VHT160_0, mcs[3][0]),2060		SKU_FIELD(VHT160_1_2, mcs[3][1]),2061		SKU_FIELD(VHT160_3_4, mcs[3][3]),2062		SKU_FIELD(VHT160_5_6, mcs[3][5]),2063		SKU_FIELD(VHT160_7, mcs[3][7]),2064		SKU_FIELD(VHT160_8, mcs[3][8]),2065		SKU_FIELD(VHT160_9, mcs[3][9]),2066#undef SKU_FIELD2067	};2068 2069	tx_power = mt76_get_sar_power(mphy, mphy->chandef.chan, tx_power);2070	tx_power -= mt76_tx_power_nss_delta(n_chains);2071	tx_power = mt76_get_rate_power_limits(mphy, mphy->chandef.chan,2072					      &limits, tx_power);2073	mphy->txpower_cur = tx_power;2074 2075	if (is_mt7663(mphy->dev)) {2076		memset(sku, tx_power, MT_SKU_4SS_DELTA + 1);2077		return;2078	}2079 2080	for (i = 0; i < MT_SKU_1SS_DELTA; i++)2081		sku[i] = limits_array[sku_mapping[i]];2082 2083	for (i = 0; i < 4; i++) {2084		int delta = 0;2085 2086		if (i < n_chains - 1)2087			delta = mt76_tx_power_nss_delta(n_chains) -2088				mt76_tx_power_nss_delta(i + 1);2089		sku[MT_SKU_1SS_DELTA + i] = delta;2090	}2091}2092 2093static u8 mt7615_mcu_chan_bw(struct cfg80211_chan_def *chandef)2094{2095	static const u8 width_to_bw[] = {2096		[NL80211_CHAN_WIDTH_40] = CMD_CBW_40MHZ,2097		[NL80211_CHAN_WIDTH_80] = CMD_CBW_80MHZ,2098		[NL80211_CHAN_WIDTH_80P80] = CMD_CBW_8080MHZ,2099		[NL80211_CHAN_WIDTH_160] = CMD_CBW_160MHZ,2100		[NL80211_CHAN_WIDTH_5] = CMD_CBW_5MHZ,2101		[NL80211_CHAN_WIDTH_10] = CMD_CBW_10MHZ,2102		[NL80211_CHAN_WIDTH_20] = CMD_CBW_20MHZ,2103		[NL80211_CHAN_WIDTH_20_NOHT] = CMD_CBW_20MHZ,2104	};2105 2106	if (chandef->width >= ARRAY_SIZE(width_to_bw))2107		return 0;2108 2109	return width_to_bw[chandef->width];2110}2111 2112int mt7615_mcu_set_chan_info(struct mt7615_phy *phy, int cmd)2113{2114	struct mt7615_dev *dev = phy->dev;2115	struct cfg80211_chan_def *chandef = &phy->mt76->chandef;2116	int freq1 = chandef->center_freq1, freq2 = chandef->center_freq2;2117	struct {2118		u8 control_chan;2119		u8 center_chan;2120		u8 bw;2121		u8 tx_streams;2122		u8 rx_streams_mask;2123		u8 switch_reason;2124		u8 band_idx;2125		/* for 80+80 only */2126		u8 center_chan2;2127		__le16 cac_case;2128		u8 channel_band;2129		u8 rsv0;2130		__le32 outband_freq;2131		u8 txpower_drop;2132		u8 rsv1[3];2133		u8 txpower_sku[53];2134		u8 rsv2[3];2135	} req = {2136		.control_chan = chandef->chan->hw_value,2137		.center_chan = ieee80211_frequency_to_channel(freq1),2138		.tx_streams = hweight8(phy->mt76->antenna_mask),2139		.rx_streams_mask = phy->mt76->chainmask,2140		.center_chan2 = ieee80211_frequency_to_channel(freq2),2141	};2142 2143	if (cmd == MCU_EXT_CMD(SET_RX_PATH) ||2144	    phy->mt76->hw->conf.flags & IEEE80211_CONF_MONITOR)2145		req.switch_reason = CH_SWITCH_NORMAL;2146	else if (phy->mt76->offchannel)2147		req.switch_reason = CH_SWITCH_SCAN_BYPASS_DPD;2148	else if (!cfg80211_reg_can_beacon(phy->mt76->hw->wiphy, chandef,2149					  NL80211_IFTYPE_AP))2150		req.switch_reason = CH_SWITCH_DFS;2151	else2152		req.switch_reason = CH_SWITCH_NORMAL;2153 2154	req.band_idx = phy != &dev->phy;2155	req.bw = mt7615_mcu_chan_bw(chandef);2156 2157	if (mt76_testmode_enabled(phy->mt76))2158		memset(req.txpower_sku, 0x3f, 49);2159	else2160		mt7615_mcu_set_txpower_sku(phy, req.txpower_sku);2161 2162	return mt76_mcu_send_msg(&dev->mt76, cmd, &req, sizeof(req), true);2163}2164 2165int mt7615_mcu_get_temperature(struct mt7615_dev *dev)2166{2167	struct {2168		u8 action;2169		u8 rsv[3];2170	} req = {};2171 2172	return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(THERMAL_CTRL),2173				 &req, sizeof(req), true);2174}2175 2176int mt7615_mcu_set_test_param(struct mt7615_dev *dev, u8 param, bool test_mode,2177			      u32 val)2178{2179	struct {2180		u8 test_mode_en;2181		u8 param_idx;2182		u8 _rsv[2];2183 2184		__le32 value;2185 2186		u8 pad[8];2187	} req = {2188		.test_mode_en = test_mode,2189		.param_idx = param,2190		.value = cpu_to_le32(val),2191	};2192 2193	return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(ATE_CTRL),2194				 &req, sizeof(req), false);2195}2196 2197int mt7615_mcu_set_sku_en(struct mt7615_phy *phy, bool enable)2198{2199	struct mt7615_dev *dev = phy->dev;2200	struct {2201		u8 format_id;2202		u8 sku_enable;2203		u8 band_idx;2204		u8 rsv;2205	} req = {2206		.format_id = 0,2207		.band_idx = phy != &dev->phy,2208		.sku_enable = enable,2209	};2210 2211	return mt76_mcu_send_msg(&dev->mt76,2212				 MCU_EXT_CMD(TX_POWER_FEATURE_CTRL),2213				 &req, sizeof(req), true);2214}2215 2216static int mt7615_find_freq_idx(const u16 *freqs, int n_freqs, u16 cur)2217{2218	int i;2219 2220	for (i = 0; i < n_freqs; i++)2221		if (cur == freqs[i])2222			return i;2223 2224	return -1;2225}2226 2227static int mt7615_dcoc_freq_idx(u16 freq, u8 bw)2228{2229	static const u16 freq_list[] = {2230		4980, 5805, 5905, 5190,2231		5230, 5270, 5310, 5350,2232		5390, 5430, 5470, 5510,2233		5550, 5590, 5630, 5670,2234		5710, 5755, 5795, 5835,2235		5875, 5210, 5290, 5370,2236		5450, 5530, 5610, 5690,2237		5775, 58552238	};2239	static const u16 freq_bw40[] = {2240		5190, 5230, 5270, 5310,2241		5350, 5390, 5430, 5470,2242		5510, 5550, 5590, 5630,2243		5670, 5710, 5755, 5795,2244		5835, 58752245	};2246	int offset_2g = ARRAY_SIZE(freq_list);2247	int idx;2248 2249	if (freq < 4000) {2250		if (freq < 2427)2251			return offset_2g;2252		if (freq < 2442)2253			return offset_2g + 1;2254		if (freq < 2457)2255			return offset_2g + 2;2256 2257		return offset_2g + 3;2258	}2259 2260	switch (bw) {2261	case NL80211_CHAN_WIDTH_80:2262	case NL80211_CHAN_WIDTH_80P80:2263	case NL80211_CHAN_WIDTH_160:2264		break;2265	default:2266		idx = mt7615_find_freq_idx(freq_bw40, ARRAY_SIZE(freq_bw40),2267					   freq + 10);2268		if (idx >= 0) {2269			freq = freq_bw40[idx];2270			break;2271		}2272 2273		idx = mt7615_find_freq_idx(freq_bw40, ARRAY_SIZE(freq_bw40),2274					   freq - 10);2275		if (idx >= 0) {2276			freq = freq_bw40[idx];2277			break;2278		}2279		fallthrough;2280	case NL80211_CHAN_WIDTH_40:2281		idx = mt7615_find_freq_idx(freq_bw40, ARRAY_SIZE(freq_bw40),2282					   freq);2283		if (idx >= 0)2284			break;2285 2286		return -1;2287 2288	}2289 2290	return mt7615_find_freq_idx(freq_list, ARRAY_SIZE(freq_list), freq);2291}2292 2293int mt7615_mcu_apply_rx_dcoc(struct mt7615_phy *phy)2294{2295	struct mt7615_dev *dev = phy->dev;2296	struct cfg80211_chan_def *chandef = &phy->mt76->chandef;2297	int freq2 = chandef->center_freq2;2298	int ret;2299	struct {2300		u8 direction;2301		u8 runtime_calibration;2302		u8 _rsv[2];2303 2304		__le16 center_freq;2305		u8 bw;2306		u8 band;2307		u8 is_freq2;2308		u8 success;2309		u8 dbdc_en;2310 2311		u8 _rsv2;2312 2313		struct {2314			__le32 sx0_i_lna[4];2315			__le32 sx0_q_lna[4];2316 2317			__le32 sx2_i_lna[4];2318			__le32 sx2_q_lna[4];2319		} dcoc_data[4];2320	} req = {2321		.direction = 1,2322 2323		.bw = mt7615_mcu_chan_bw(chandef),2324		.band = chandef->center_freq1 > 4000,2325		.dbdc_en = !!dev->mt76.phys[MT_BAND1],2326	};2327	u16 center_freq = chandef->center_freq1;2328	int freq_idx;2329	u8 *eep = dev->mt76.eeprom.data;2330 2331	if (!(eep[MT_EE_CALDATA_FLASH] & MT_EE_CALDATA_FLASH_RX_CAL))2332		return 0;2333 2334	if (chandef->width == NL80211_CHAN_WIDTH_160) {2335		freq2 = center_freq + 40;2336		center_freq -= 40;2337	}2338 2339again:2340	req.runtime_calibration = 1;2341	freq_idx = mt7615_dcoc_freq_idx(center_freq, chandef->width);2342	if (freq_idx < 0)2343		goto out;2344 2345	memcpy(req.dcoc_data, eep + MT7615_EEPROM_DCOC_OFFSET +2346			      freq_idx * MT7615_EEPROM_DCOC_SIZE,2347	       sizeof(req.dcoc_data));2348	req.runtime_calibration = 0;2349 2350out:2351	req.center_freq = cpu_to_le16(center_freq);2352	ret = mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(RXDCOC_CAL), &req,2353				sizeof(req), true);2354 2355	if ((chandef->width == NL80211_CHAN_WIDTH_80P80 ||2356	     chandef->width == NL80211_CHAN_WIDTH_160) && !req.is_freq2) {2357		req.is_freq2 = true;2358		center_freq = freq2;2359		goto again;2360	}2361 2362	return ret;2363}2364 2365static int mt7615_dpd_freq_idx(u16 freq, u8 bw)2366{2367	static const u16 freq_list[] = {2368		4920, 4940, 4960, 4980,2369		5040, 5060, 5080, 5180,2370		5200, 5220, 5240, 5260,2371		5280, 5300, 5320, 5340,2372		5360, 5380, 5400, 5420,2373		5440, 5460, 5480, 5500,2374		5520, 5540, 5560, 5580,2375		5600, 5620, 5640, 5660,2376		5680, 5700, 5720, 5745,2377		5765, 5785, 5805, 5825,2378		5845, 5865, 5885, 59052379	};2380	int offset_2g = ARRAY_SIZE(freq_list);2381	int idx;2382 2383	if (freq < 4000) {2384		if (freq < 2432)2385			return offset_2g;2386		if (freq < 2457)2387			return offset_2g + 1;2388 2389		return offset_2g + 2;2390	}2391 2392	if (bw != NL80211_CHAN_WIDTH_20) {2393		idx = mt7615_find_freq_idx(freq_list, ARRAY_SIZE(freq_list),2394					   freq + 10);2395		if (idx >= 0)2396			return idx;2397 2398		idx = mt7615_find_freq_idx(freq_list, ARRAY_SIZE(freq_list),2399					   freq - 10);2400		if (idx >= 0)2401			return idx;2402	}2403 2404	return mt7615_find_freq_idx(freq_list, ARRAY_SIZE(freq_list), freq);2405}2406 2407 2408int mt7615_mcu_apply_tx_dpd(struct mt7615_phy *phy)2409{2410	struct mt7615_dev *dev = phy->dev;2411	struct cfg80211_chan_def *chandef = &phy->mt76->chandef;2412	int freq2 = chandef->center_freq2;2413	int ret;2414	struct {2415		u8 direction;2416		u8 runtime_calibration;2417		u8 _rsv[2];2418 2419		__le16 center_freq;2420		u8 bw;2421		u8 band;2422		u8 is_freq2;2423		u8 success;2424		u8 dbdc_en;2425 2426		u8 _rsv2;2427 2428		struct {2429			struct {2430				u32 dpd_g0;2431				u8 data[32];2432			} wf0, wf1;2433 2434			struct {2435				u32 dpd_g0_prim;2436				u32 dpd_g0_sec;2437				u8 data_prim[32];2438				u8 data_sec[32];2439			} wf2, wf3;2440		} dpd_data;2441	} req = {2442		.direction = 1,2443 2444		.bw = mt7615_mcu_chan_bw(chandef),2445		.band = chandef->center_freq1 > 4000,2446		.dbdc_en = !!dev->mt76.phys[MT_BAND1],2447	};2448	u16 center_freq = chandef->center_freq1;2449	int freq_idx;2450	u8 *eep = dev->mt76.eeprom.data;2451 2452	if (!(eep[MT_EE_CALDATA_FLASH] & MT_EE_CALDATA_FLASH_TX_DPD))2453		return 0;2454 2455	if (chandef->width == NL80211_CHAN_WIDTH_160) {2456		freq2 = center_freq + 40;2457		center_freq -= 40;2458	}2459 2460again:2461	req.runtime_calibration = 1;2462	freq_idx = mt7615_dpd_freq_idx(center_freq, chandef->width);2463	if (freq_idx < 0)2464		goto out;2465 2466	memcpy(&req.dpd_data, eep + MT7615_EEPROM_TXDPD_OFFSET +2467			      freq_idx * MT7615_EEPROM_TXDPD_SIZE,2468	       sizeof(req.dpd_data));2469	req.runtime_calibration = 0;2470 2471out:2472	req.center_freq = cpu_to_le16(center_freq);2473	ret = mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(TXDPD_CAL),2474				&req, sizeof(req), true);2475 2476	if ((chandef->width == NL80211_CHAN_WIDTH_80P80 ||2477	     chandef->width == NL80211_CHAN_WIDTH_160) && !req.is_freq2) {2478		req.is_freq2 = true;2479		center_freq = freq2;2480		goto again;2481	}2482 2483	return ret;2484}2485 2486int mt7615_mcu_set_rx_hdr_trans_blacklist(struct mt7615_dev *dev)2487{2488	struct {2489		u8 operation;2490		u8 count;2491		u8 _rsv[2];2492		u8 index;2493		u8 enable;2494		__le16 etype;2495	} req = {2496		.operation = 1,2497		.count = 1,2498		.enable = 1,2499		.etype = cpu_to_le16(ETH_P_PAE),2500	};2501 2502	return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(RX_HDR_TRANS),2503				 &req, sizeof(req), false);2504}2505 2506int mt7615_mcu_set_bss_pm(struct mt7615_dev *dev, struct ieee80211_vif *vif,2507			  bool enable)2508{2509	struct mt7615_vif *mvif = (struct mt7615_vif *)vif->drv_priv;2510	struct {2511		u8 bss_idx;2512		u8 dtim_period;2513		__le16 aid;2514		__le16 bcn_interval;2515		__le16 atim_window;2516		u8 uapsd;2517		u8 bmc_delivered_ac;2518		u8 bmc_triggered_ac;2519		u8 pad;2520	} req = {2521		.bss_idx = mvif->mt76.idx,2522		.aid = cpu_to_le16(vif->cfg.aid),2523		.dtim_period = vif->bss_conf.dtim_period,2524		.bcn_interval = cpu_to_le16(vif->bss_conf.beacon_int),2525	};2526	struct {2527		u8 bss_idx;2528		u8 pad[3];2529	} req_hdr = {2530		.bss_idx = mvif->mt76.idx,2531	};2532	int err;2533 2534	if (vif->type != NL80211_IFTYPE_STATION)2535		return 0;2536 2537	err = mt76_mcu_send_msg(&dev->mt76, MCU_CE_CMD(SET_BSS_ABORT),2538				&req_hdr, sizeof(req_hdr), false);2539	if (err < 0 || !enable)2540		return err;2541 2542	return mt76_mcu_send_msg(&dev->mt76, MCU_CE_CMD(SET_BSS_CONNECTED),2543				 &req, sizeof(req), false);2544}2545 2546int mt7615_mcu_set_roc(struct mt7615_phy *phy, struct ieee80211_vif *vif,2547		       struct ieee80211_channel *chan, int duration)2548{2549	struct mt7615_vif *mvif = (struct mt7615_vif *)vif->drv_priv;2550	struct mt7615_dev *dev = phy->dev;2551	struct mt7615_roc_tlv req = {2552		.bss_idx = mvif->mt76.idx,2553		.active = !chan,2554		.max_interval = cpu_to_le32(duration),2555		.primary_chan = chan ? chan->hw_value : 0,2556		.band = chan ? chan->band : 0,2557		.req_type = 2,2558	};2559 2560	phy->roc_grant = false;2561 2562	return mt76_mcu_send_msg(&dev->mt76, MCU_CE_CMD(SET_ROC),2563				 &req, sizeof(req), false);2564}2565