File Index
Files and directories
Sign in
FILE

mcu.c

File preview with syntax highlighting.

linux-6.19.14/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c C
   1// SPDX-License-Identifier: BSD-3-Clause-Clear
   2/* Copyright (C) 2020 MediaTek Inc. */
   3
   4#include <linux/fs.h>
   5#include <linux/firmware.h>
   6#include "mt7921.h"
   7#include "mcu.h"
   8#include "../mt76_connac2_mac.h"
   9#include "../mt792x_trace.h"
  10
  11#define MT_STA_BFER			BIT(0)
  12#define MT_STA_BFEE			BIT(1)
  13
  14static bool mt7921_disable_clc;
  15module_param_named(disable_clc, mt7921_disable_clc, bool, 0644);
  16MODULE_PARM_DESC(disable_clc, "disable CLC support");
  17
  18int mt7921_mcu_parse_response(struct mt76_dev *mdev, int cmd,
  19			      struct sk_buff *skb, int seq)
  20{
  21	int mcu_cmd = FIELD_GET(__MCU_CMD_FIELD_ID, cmd);
  22	struct mt76_connac2_mcu_rxd *rxd;
  23	int ret = 0;
  24
  25	if (!skb) {
  26		dev_err(mdev->dev, "Message %08x (seq %d) timeout\n",
  27			cmd, seq);
  28		mt792x_reset(mdev);
  29
  30		return -ETIMEDOUT;
  31	}
  32
  33	rxd = (struct mt76_connac2_mcu_rxd *)skb->data;
  34	if (seq != rxd->seq)
  35		return -EAGAIN;
  36
  37	if (cmd == MCU_CMD(PATCH_SEM_CONTROL) ||
  38	    cmd == MCU_CMD(PATCH_FINISH_REQ)) {
  39		skb_pull(skb, sizeof(*rxd) - 4);
  40		ret = *skb->data;
  41	} else if (cmd == MCU_EXT_CMD(THERMAL_CTRL)) {
  42		skb_pull(skb, sizeof(*rxd) + 4);
  43		ret = le32_to_cpu(*(__le32 *)skb->data);
  44	} else if (cmd == MCU_UNI_CMD(DEV_INFO_UPDATE) ||
  45		   cmd == MCU_UNI_CMD(BSS_INFO_UPDATE) ||
  46		   cmd == MCU_UNI_CMD(STA_REC_UPDATE) ||
  47		   cmd == MCU_UNI_CMD(HIF_CTRL) ||
  48		   cmd == MCU_UNI_CMD(OFFLOAD) ||
  49		   cmd == MCU_UNI_CMD(SUSPEND)) {
  50		struct mt76_connac_mcu_uni_event *event;
  51
  52		skb_pull(skb, sizeof(*rxd));
  53		event = (struct mt76_connac_mcu_uni_event *)skb->data;
  54		ret = le32_to_cpu(event->status);
  55		/* skip invalid event */
  56		if (mcu_cmd != event->cid)
  57			ret = -EAGAIN;
  58	} else if (cmd == MCU_CE_QUERY(REG_READ)) {
  59		struct mt76_connac_mcu_reg_event *event;
  60
  61		skb_pull(skb, sizeof(*rxd));
  62		event = (struct mt76_connac_mcu_reg_event *)skb->data;
  63		ret = (int)le32_to_cpu(event->val);
  64	} else if (cmd == MCU_EXT_CMD(WF_RF_PIN_CTRL)) {
  65		struct mt7921_wf_rf_pin_ctrl_event *event;
  66
  67		skb_pull(skb, sizeof(*rxd));
  68		event = (struct mt7921_wf_rf_pin_ctrl_event *)skb->data;
  69		ret = (int)event->result;
  70	} else {
  71		skb_pull(skb, sizeof(struct mt76_connac2_mcu_rxd));
  72	}
  73
  74	return ret;
  75}
  76EXPORT_SYMBOL_GPL(mt7921_mcu_parse_response);
  77
  78static int mt7921_mcu_read_eeprom(struct mt792x_dev *dev, u32 offset, u8 *val)
  79{
  80	struct mt7921_mcu_eeprom_info *res, req = {
  81		.addr = cpu_to_le32(round_down(offset,
  82				    MT7921_EEPROM_BLOCK_SIZE)),
  83	};
  84	struct sk_buff *skb;
  85	int ret;
  86
  87	ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_EXT_QUERY(EFUSE_ACCESS),
  88					&req, sizeof(req), true, &skb);
  89	if (ret)
  90		return ret;
  91
  92	res = (struct mt7921_mcu_eeprom_info *)skb->data;
  93	*val = res->data[offset % MT7921_EEPROM_BLOCK_SIZE];
  94	dev_kfree_skb(skb);
  95
  96	return 0;
  97}
  98
  99#ifdef CONFIG_PM
 100
 101static int
 102mt7921_mcu_set_ipv6_ns_filter(struct mt76_dev *dev,
 103			      struct ieee80211_vif *vif, bool suspend)
 104{
 105	struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv;
 106	struct {
 107		struct {
 108			u8 bss_idx;
 109			u8 pad[3];
 110		} __packed hdr;
 111		struct mt76_connac_arpns_tlv arpns;
 112	} req = {
 113		.hdr = {
 114			.bss_idx = mvif->bss_conf.mt76.idx,
 115		},
 116		.arpns = {
 117			.tag = cpu_to_le16(UNI_OFFLOAD_OFFLOAD_ND),
 118			.len = cpu_to_le16(sizeof(struct mt76_connac_arpns_tlv)),
 119			.mode = suspend,
 120		},
 121	};
 122
 123	return mt76_mcu_send_msg(dev, MCU_UNI_CMD_OFFLOAD, &req, sizeof(req),
 124				 true);
 125}
 126
 127void mt7921_mcu_set_suspend_iter(void *priv, u8 *mac, struct ieee80211_vif *vif)
 128{
 129	if (IS_ENABLED(CONFIG_IPV6)) {
 130		struct mt76_phy *phy = priv;
 131
 132		mt7921_mcu_set_ipv6_ns_filter(phy->dev, vif,
 133					      !test_bit(MT76_STATE_RUNNING,
 134					      &phy->state));
 135	}
 136
 137	mt76_connac_mcu_set_suspend_iter(priv, mac, vif);
 138}
 139
 140#endif /* CONFIG_PM */
 141
 142static void
 143mt7921_mcu_uni_roc_event(struct mt792x_dev *dev, struct sk_buff *skb)
 144{
 145	struct mt7921_roc_grant_tlv *grant;
 146	struct mt76_connac2_mcu_rxd *rxd;
 147	int duration;
 148
 149	rxd = (struct mt76_connac2_mcu_rxd *)skb->data;
 150	grant = (struct mt7921_roc_grant_tlv *)(rxd->tlv + 4);
 151
 152	/* should never happen */
 153	WARN_ON_ONCE((le16_to_cpu(grant->tag) != UNI_EVENT_ROC_GRANT));
 154
 155	if (grant->reqtype == MT7921_ROC_REQ_ROC)
 156		ieee80211_ready_on_channel(dev->mt76.phy.hw);
 157
 158	dev->phy.roc_grant = true;
 159	wake_up(&dev->phy.roc_wait);
 160	duration = le32_to_cpu(grant->max_interval);
 161	mod_timer(&dev->phy.roc_timer,
 162		  jiffies + msecs_to_jiffies(duration));
 163}
 164
 165static void
 166mt7921_mcu_scan_event(struct mt792x_dev *dev, struct sk_buff *skb)
 167{
 168	struct mt76_phy *mphy = &dev->mt76.phy;
 169	struct mt792x_phy *phy = mphy->priv;
 170
 171	spin_lock_bh(&dev->mt76.lock);
 172	__skb_queue_tail(&phy->scan_event_list, skb);
 173	spin_unlock_bh(&dev->mt76.lock);
 174
 175	ieee80211_queue_delayed_work(mphy->hw, &phy->scan_work,
 176				     MT792x_HW_SCAN_TIMEOUT);
 177}
 178
 179static void
 180mt7921_mcu_connection_loss_iter(void *priv, u8 *mac,
 181				struct ieee80211_vif *vif)
 182{
 183	struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv;
 184	struct mt76_connac_beacon_loss_event *event = priv;
 185
 186	if (mvif->idx != event->bss_idx)
 187		return;
 188
 189	if (!(vif->driver_flags & IEEE80211_VIF_BEACON_FILTER) ||
 190	    vif->type != NL80211_IFTYPE_STATION)
 191		return;
 192
 193	ieee80211_connection_loss(vif);
 194}
 195
 196static void
 197mt7921_mcu_connection_loss_event(struct mt792x_dev *dev, struct sk_buff *skb)
 198{
 199	struct mt76_connac_beacon_loss_event *event;
 200	struct mt76_phy *mphy = &dev->mt76.phy;
 201
 202	skb_pull(skb, sizeof(struct mt76_connac2_mcu_rxd));
 203	event = (struct mt76_connac_beacon_loss_event *)skb->data;
 204
 205	ieee80211_iterate_active_interfaces_atomic(mphy->hw,
 206					IEEE80211_IFACE_ITER_RESUME_ALL,
 207					mt7921_mcu_connection_loss_iter, event);
 208}
 209
 210static void
 211mt7921_mcu_debug_msg_event(struct mt792x_dev *dev, struct sk_buff *skb)
 212{
 213	struct mt7921_debug_msg {
 214		__le16 id;
 215		u8 type;
 216		u8 flag;
 217		__le32 value;
 218		__le16 len;
 219		u8 content[512];
 220	} __packed * msg;
 221
 222	skb_pull(skb, sizeof(struct mt76_connac2_mcu_rxd));
 223	msg = (struct mt7921_debug_msg *)skb->data;
 224
 225	if (msg->type == 3) { /* fw log */
 226		u16 len = min_t(u16, le16_to_cpu(msg->len), 512);
 227		int i;
 228
 229		for (i = 0 ; i < len; i++) {
 230			if (!msg->content[i])
 231				msg->content[i] = ' ';
 232		}
 233		wiphy_info(mt76_hw(dev)->wiphy, "%.*s", len, msg->content);
 234	}
 235}
 236
 237static void
 238mt7921_mcu_low_power_event(struct mt792x_dev *dev, struct sk_buff *skb)
 239{
 240	struct mt7921_mcu_lp_event {
 241		u8 state;
 242		u8 reserved[3];
 243	} __packed * event;
 244
 245	skb_pull(skb, sizeof(struct mt76_connac2_mcu_rxd));
 246	event = (struct mt7921_mcu_lp_event *)skb->data;
 247
 248	trace_lp_event(dev, event->state);
 249}
 250
 251static void
 252mt7921_mcu_tx_done_event(struct mt792x_dev *dev, struct sk_buff *skb)
 253{
 254	struct mt7921_mcu_tx_done_event *event;
 255
 256	skb_pull(skb, sizeof(struct mt76_connac2_mcu_rxd));
 257	event = (struct mt7921_mcu_tx_done_event *)skb->data;
 258
 259	mt7921_mac_add_txs(dev, event->txs);
 260}
 261
 262static void
 263mt7921_mcu_rssi_monitor_iter(void *priv, u8 *mac,
 264			     struct ieee80211_vif *vif)
 265{
 266	struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv;
 267	struct mt76_connac_rssi_notify_event *event = priv;
 268	enum nl80211_cqm_rssi_threshold_event nl_event;
 269	s32 rssi = le32_to_cpu(event->rssi[mvif->bss_conf.mt76.idx]);
 270
 271	if (!rssi)
 272		return;
 273
 274	if (!(vif->driver_flags & IEEE80211_VIF_SUPPORTS_CQM_RSSI))
 275		return;
 276
 277	if (rssi > vif->bss_conf.cqm_rssi_thold)
 278		nl_event = NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH;
 279	else
 280		nl_event = NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW;
 281
 282	ieee80211_cqm_rssi_notify(vif, nl_event, rssi, GFP_KERNEL);
 283}
 284
 285static void
 286mt7921_mcu_rssi_monitor_event(struct mt792x_dev *dev, struct sk_buff *skb)
 287{
 288	struct mt76_connac_rssi_notify_event *event;
 289
 290	skb_pull(skb, sizeof(struct mt76_connac2_mcu_rxd));
 291	event = (struct mt76_connac_rssi_notify_event *)skb->data;
 292
 293	ieee80211_iterate_active_interfaces_atomic(mt76_hw(dev),
 294						   IEEE80211_IFACE_ITER_RESUME_ALL,
 295						   mt7921_mcu_rssi_monitor_iter, event);
 296}
 297
 298static void
 299mt7921_mcu_rx_unsolicited_event(struct mt792x_dev *dev, struct sk_buff *skb)
 300{
 301	struct mt76_connac2_mcu_rxd *rxd;
 302
 303	rxd = (struct mt76_connac2_mcu_rxd *)skb->data;
 304	switch (rxd->eid) {
 305	case MCU_EVENT_BSS_BEACON_LOSS:
 306		mt7921_mcu_connection_loss_event(dev, skb);
 307		break;
 308	case MCU_EVENT_SCHED_SCAN_DONE:
 309	case MCU_EVENT_SCAN_DONE:
 310		mt7921_mcu_scan_event(dev, skb);
 311		return;
 312	case MCU_EVENT_DBG_MSG:
 313		mt7921_mcu_debug_msg_event(dev, skb);
 314		break;
 315	case MCU_EVENT_COREDUMP:
 316		dev->fw_assert = true;
 317		mt76_connac_mcu_coredump_event(&dev->mt76, skb,
 318					       &dev->coredump);
 319		return;
 320	case MCU_EVENT_LP_INFO:
 321		mt7921_mcu_low_power_event(dev, skb);
 322		break;
 323	case MCU_EVENT_TX_DONE:
 324		mt7921_mcu_tx_done_event(dev, skb);
 325		break;
 326	case MCU_EVENT_RSSI_NOTIFY:
 327		mt7921_mcu_rssi_monitor_event(dev, skb);
 328		break;
 329	default:
 330		break;
 331	}
 332	dev_kfree_skb(skb);
 333}
 334
 335static void
 336mt7921_mcu_uni_rx_unsolicited_event(struct mt792x_dev *dev,
 337				    struct sk_buff *skb)
 338{
 339	struct mt76_connac2_mcu_rxd *rxd;
 340
 341	rxd = (struct mt76_connac2_mcu_rxd *)skb->data;
 342
 343	switch (rxd->eid) {
 344	case MCU_UNI_EVENT_ROC:
 345		mt7921_mcu_uni_roc_event(dev, skb);
 346		break;
 347	default:
 348		break;
 349	}
 350	dev_kfree_skb(skb);
 351}
 352
 353void mt7921_mcu_rx_event(struct mt792x_dev *dev, struct sk_buff *skb)
 354{
 355	struct mt76_connac2_mcu_rxd *rxd;
 356
 357	if (skb_linearize(skb))
 358		return;
 359
 360	rxd = (struct mt76_connac2_mcu_rxd *)skb->data;
 361
 362	if (rxd->option & MCU_UNI_CMD_UNSOLICITED_EVENT) {
 363		mt7921_mcu_uni_rx_unsolicited_event(dev, skb);
 364		return;
 365	}
 366
 367	if (rxd->eid == 0x6) {
 368		mt76_mcu_rx_event(&dev->mt76, skb);
 369		return;
 370	}
 371
 372	if (rxd->ext_eid == MCU_EXT_EVENT_RATE_REPORT ||
 373	    rxd->eid == MCU_EVENT_BSS_BEACON_LOSS ||
 374	    rxd->eid == MCU_EVENT_SCHED_SCAN_DONE ||
 375	    rxd->eid == MCU_EVENT_RSSI_NOTIFY ||
 376	    rxd->eid == MCU_EVENT_SCAN_DONE ||
 377	    rxd->eid == MCU_EVENT_TX_DONE ||
 378	    rxd->eid == MCU_EVENT_DBG_MSG ||
 379	    rxd->eid == MCU_EVENT_COREDUMP ||
 380	    rxd->eid == MCU_EVENT_LP_INFO ||
 381	    !rxd->seq)
 382		mt7921_mcu_rx_unsolicited_event(dev, skb);
 383	else
 384		mt76_mcu_rx_event(&dev->mt76, skb);
 385}
 386
 387/** starec & wtbl **/
 388int mt7921_mcu_uni_tx_ba(struct mt792x_dev *dev,
 389			 struct ieee80211_ampdu_params *params,
 390			 bool enable)
 391{
 392	struct mt792x_sta *msta = (struct mt792x_sta *)params->sta->drv_priv;
 393
 394	if (enable && !params->amsdu)
 395		msta->deflink.wcid.amsdu = false;
 396
 397	return mt76_connac_mcu_sta_ba(&dev->mt76, &msta->vif->bss_conf.mt76, params,
 398				      MCU_UNI_CMD(STA_REC_UPDATE),
 399				      enable, true);
 400}
 401
 402int mt7921_mcu_uni_rx_ba(struct mt792x_dev *dev,
 403			 struct ieee80211_ampdu_params *params,
 404			 bool enable)
 405{
 406	struct mt792x_sta *msta = (struct mt792x_sta *)params->sta->drv_priv;
 407
 408	return mt76_connac_mcu_sta_ba(&dev->mt76, &msta->vif->bss_conf.mt76, params,
 409				      MCU_UNI_CMD(STA_REC_UPDATE),
 410				      enable, false);
 411}
 412
 413static int mt7921_load_clc(struct mt792x_dev *dev, const char *fw_name)
 414{
 415	const struct mt76_connac2_fw_trailer *hdr;
 416	const struct mt76_connac2_fw_region *region;
 417	const struct mt7921_clc *clc;
 418	struct mt76_dev *mdev = &dev->mt76;
 419	struct mt792x_phy *phy = &dev->phy;
 420	const struct firmware *fw;
 421	int ret, i, len, offset = 0;
 422	u8 *clc_base = NULL, hw_encap = 0;
 423
 424	dev->phy.clc_chan_conf = 0xff;
 425	if (mt7921_disable_clc ||
 426	    mt76_is_usb(&dev->mt76))
 427		return 0;
 428
 429	if (mt76_is_mmio(&dev->mt76)) {
 430		ret = mt7921_mcu_read_eeprom(dev, MT_EE_HW_TYPE, &hw_encap);
 431		if (ret)
 432			return ret;
 433		hw_encap = u8_get_bits(hw_encap, MT_EE_HW_TYPE_ENCAP);
 434	}
 435
 436	ret = request_firmware(&fw, fw_name, mdev->dev);
 437	if (ret)
 438		return ret;
 439
 440	if (!fw || !fw->data || fw->size < sizeof(*hdr)) {
 441		dev_err(mdev->dev, "Invalid firmware\n");
 442		ret = -EINVAL;
 443		goto out;
 444	}
 445
 446	hdr = (const void *)(fw->data + fw->size - sizeof(*hdr));
 447	for (i = 0; i < hdr->n_region; i++) {
 448		region = (const void *)((const u8 *)hdr -
 449					(hdr->n_region - i) * sizeof(*region));
 450		len = le32_to_cpu(region->len);
 451
 452		/* check if we have valid buffer size */
 453		if (offset + len > fw->size) {
 454			dev_err(mdev->dev, "Invalid firmware region\n");
 455			ret = -EINVAL;
 456			goto out;
 457		}
 458
 459		if ((region->feature_set & FW_FEATURE_NON_DL) &&
 460		    region->type == FW_TYPE_CLC) {
 461			clc_base = (u8 *)(fw->data + offset);
 462			break;
 463		}
 464		offset += len;
 465	}
 466
 467	if (!clc_base)
 468		goto out;
 469
 470	for (offset = 0; offset < len; offset += le32_to_cpu(clc->len)) {
 471		clc = (const struct mt7921_clc *)(clc_base + offset);
 472
 473		/* do not init buf again if chip reset triggered */
 474		if (phy->clc[clc->idx])
 475			continue;
 476
 477		/* header content sanity */
 478		if (clc->idx == MT7921_CLC_POWER &&
 479		    u8_get_bits(clc->type, MT_EE_HW_TYPE_ENCAP) != hw_encap)
 480			continue;
 481
 482		phy->clc[clc->idx] = devm_kmemdup(mdev->dev, clc,
 483						  le32_to_cpu(clc->len),
 484						  GFP_KERNEL);
 485
 486		if (!phy->clc[clc->idx]) {
 487			ret = -ENOMEM;
 488			goto out;
 489		}
 490	}
 491	ret = mt7921_mcu_set_clc(dev, "00", ENVIRON_INDOOR);
 492out:
 493	release_firmware(fw);
 494
 495	return ret;
 496}
 497
 498static void mt7921_mcu_parse_tx_resource(struct mt76_dev *dev,
 499					 struct sk_buff *skb)
 500{
 501	struct mt76_sdio *sdio = &dev->sdio;
 502	struct mt7921_tx_resource {
 503		__le32 version;
 504		__le32 pse_data_quota;
 505		__le32 pse_mcu_quota;
 506		__le32 ple_data_quota;
 507		__le32 ple_mcu_quota;
 508		__le16 pse_page_size;
 509		__le16 ple_page_size;
 510		u8 pp_padding;
 511		u8 pad[3];
 512	} __packed * tx_res;
 513
 514	tx_res = (struct mt7921_tx_resource *)skb->data;
 515	sdio->sched.pse_data_quota = le32_to_cpu(tx_res->pse_data_quota);
 516	sdio->pse_mcu_quota_max = le32_to_cpu(tx_res->pse_mcu_quota);
 517	/* The mcu quota usage of this function itself must be taken into consideration */
 518	sdio->sched.pse_mcu_quota =
 519		sdio->sched.pse_mcu_quota ? sdio->pse_mcu_quota_max : sdio->pse_mcu_quota_max - 1;
 520	sdio->sched.ple_data_quota = le32_to_cpu(tx_res->ple_data_quota);
 521	sdio->sched.pse_page_size = le16_to_cpu(tx_res->pse_page_size);
 522	sdio->sched.deficit = tx_res->pp_padding;
 523}
 524
 525static void mt7921_mcu_parse_phy_cap(struct mt76_dev *dev,
 526				     struct sk_buff *skb)
 527{
 528	struct mt7921_phy_cap {
 529		u8 ht;
 530		u8 vht;
 531		u8 _5g;
 532		u8 max_bw;
 533		u8 nss;
 534		u8 dbdc;
 535		u8 tx_ldpc;
 536		u8 rx_ldpc;
 537		u8 tx_stbc;
 538		u8 rx_stbc;
 539		u8 hw_path;
 540		u8 he;
 541	} __packed * cap;
 542
 543	enum {
 544		WF0_24G,
 545		WF0_5G
 546	};
 547
 548	cap = (struct mt7921_phy_cap *)skb->data;
 549
 550	dev->phy.antenna_mask = BIT(cap->nss) - 1;
 551	dev->phy.chainmask = dev->phy.antenna_mask;
 552	dev->phy.cap.has_2ghz = cap->hw_path & BIT(WF0_24G);
 553	dev->phy.cap.has_5ghz = cap->hw_path & BIT(WF0_5G);
 554}
 555
 556static int mt7921_mcu_get_nic_capability(struct mt792x_phy *mphy)
 557{
 558	struct mt76_connac_cap_hdr {
 559		__le16 n_element;
 560		u8 rsv[2];
 561	} __packed * hdr;
 562	struct sk_buff *skb;
 563	struct mt76_phy *phy = mphy->mt76;
 564	int ret, i;
 565
 566	ret = mt76_mcu_send_and_get_msg(phy->dev, MCU_CE_CMD(GET_NIC_CAPAB),
 567					NULL, 0, true, &skb);
 568	if (ret)
 569		return ret;
 570
 571	hdr = (struct mt76_connac_cap_hdr *)skb->data;
 572	if (skb->len < sizeof(*hdr)) {
 573		ret = -EINVAL;
 574		goto out;
 575	}
 576
 577	skb_pull(skb, sizeof(*hdr));
 578
 579	for (i = 0; i < le16_to_cpu(hdr->n_element); i++) {
 580		struct tlv_hdr {
 581			__le32 type;
 582			__le32 len;
 583		} __packed * tlv = (struct tlv_hdr *)skb->data;
 584		int len;
 585
 586		if (skb->len < sizeof(*tlv))
 587			break;
 588
 589		skb_pull(skb, sizeof(*tlv));
 590
 591		len = le32_to_cpu(tlv->len);
 592		if (skb->len < len)
 593			break;
 594
 595		switch (le32_to_cpu(tlv->type)) {
 596		case MT_NIC_CAP_6G:
 597			phy->cap.has_6ghz = skb->data[0];
 598			break;
 599		case MT_NIC_CAP_MAC_ADDR:
 600			memcpy(phy->macaddr, (void *)skb->data, ETH_ALEN);
 601			break;
 602		case MT_NIC_CAP_PHY:
 603			mt7921_mcu_parse_phy_cap(phy->dev, skb);
 604			break;
 605		case MT_NIC_CAP_TX_RESOURCE:
 606			if (mt76_is_sdio(phy->dev))
 607				mt7921_mcu_parse_tx_resource(phy->dev,
 608							     skb);
 609			break;
 610		case MT_NIC_CAP_CHIP_CAP:
 611			memcpy(&mphy->chip_cap, (void *)skb->data, sizeof(u64));
 612			break;
 613		default:
 614			break;
 615		}
 616		skb_pull(skb, len);
 617	}
 618out:
 619	dev_kfree_skb(skb);
 620
 621	return ret;
 622}
 623
 624int mt7921_mcu_fw_log_2_host(struct mt792x_dev *dev, u8 ctrl)
 625{
 626	struct {
 627		u8 ctrl_val;
 628		u8 pad[3];
 629	} data = {
 630		.ctrl_val = ctrl
 631	};
 632
 633	return mt76_mcu_send_msg(&dev->mt76, MCU_CE_CMD(FWLOG_2_HOST),
 634				 &data, sizeof(data), false);
 635}
 636
 637int mt7921_run_firmware(struct mt792x_dev *dev)
 638{
 639	int err;
 640
 641	err = mt792x_load_firmware(dev);
 642	if (err)
 643		return err;
 644
 645	err = mt7921_mcu_get_nic_capability(&dev->phy);
 646	if (err)
 647		return err;
 648
 649	err = mt7921_load_clc(dev, mt792x_ram_name(dev));
 650	if (err)
 651		return err;
 652	set_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state);
 653
 654	return mt7921_mcu_fw_log_2_host(dev, 1);
 655}
 656EXPORT_SYMBOL_GPL(mt7921_run_firmware);
 657
 658int mt7921_mcu_radio_led_ctrl(struct mt792x_dev *dev, u8 value)
 659{
 660	struct {
 661		u8 ctrlid;
 662		u8 rsv[3];
 663	} __packed req = {
 664		.ctrlid = value,
 665	};
 666
 667	return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(ID_RADIO_ON_OFF_CTRL),
 668				&req, sizeof(req), false);
 669}
 670EXPORT_SYMBOL_GPL(mt7921_mcu_radio_led_ctrl);
 671
 672int mt7921_mcu_set_tx(struct mt792x_dev *dev, struct ieee80211_vif *vif)
 673{
 674	struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv;
 675	struct edca {
 676		__le16 cw_min;
 677		__le16 cw_max;
 678		__le16 txop;
 679		__le16 aifs;
 680		u8 guardtime;
 681		u8 acm;
 682	} __packed;
 683	struct mt7921_mcu_tx {
 684		struct edca edca[IEEE80211_NUM_ACS];
 685		u8 bss_idx;
 686		u8 qos;
 687		u8 wmm_idx;
 688		u8 pad;
 689	} __packed req = {
 690		.bss_idx = mvif->bss_conf.mt76.idx,
 691		.qos = vif->bss_conf.qos,
 692		.wmm_idx = mvif->bss_conf.mt76.wmm_idx,
 693	};
 694	struct mu_edca {
 695		u8 cw_min;
 696		u8 cw_max;
 697		u8 aifsn;
 698		u8 acm;
 699		u8 timer;
 700		u8 padding[3];
 701	};
 702	struct mt7921_mcu_mu_tx {
 703		u8 ver;
 704		u8 pad0;
 705		__le16 len;
 706		u8 bss_idx;
 707		u8 qos;
 708		u8 wmm_idx;
 709		u8 pad1;
 710		struct mu_edca edca[IEEE80211_NUM_ACS];
 711		u8 pad3[32];
 712	} __packed req_mu = {
 713		.bss_idx = mvif->bss_conf.mt76.idx,
 714		.qos = vif->bss_conf.qos,
 715		.wmm_idx = mvif->bss_conf.mt76.wmm_idx,
 716	};
 717	static const int to_aci[] = { 1, 0, 2, 3 };
 718	int ac, ret;
 719
 720	for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
 721		struct ieee80211_tx_queue_params *q = &mvif->bss_conf.queue_params[ac];
 722		struct edca *e = &req.edca[to_aci[ac]];
 723
 724		e->aifs = cpu_to_le16(q->aifs);
 725		e->txop = cpu_to_le16(q->txop);
 726
 727		if (q->cw_min)
 728			e->cw_min = cpu_to_le16(q->cw_min);
 729		else
 730			e->cw_min = cpu_to_le16(5);
 731
 732		if (q->cw_max)
 733			e->cw_max = cpu_to_le16(q->cw_max);
 734		else
 735			e->cw_max = cpu_to_le16(10);
 736	}
 737
 738	ret = mt76_mcu_send_msg(&dev->mt76, MCU_CE_CMD(SET_EDCA_PARMS), &req,
 739				sizeof(req), false);
 740	if (ret)
 741		return ret;
 742
 743	if (!vif->bss_conf.he_support)
 744		return 0;
 745
 746	for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
 747		struct ieee80211_he_mu_edca_param_ac_rec *q;
 748		struct mu_edca *e;
 749
 750		if (!mvif->bss_conf.queue_params[ac].mu_edca)
 751			break;
 752
 753		q = &mvif->bss_conf.queue_params[ac].mu_edca_param_rec;
 754		e = &(req_mu.edca[to_aci[ac]]);
 755
 756		e->cw_min = q->ecw_min_max & 0xf;
 757		e->cw_max = (q->ecw_min_max & 0xf0) >> 4;
 758		e->aifsn = q->aifsn;
 759		e->timer = q->mu_edca_timer;
 760	}
 761
 762	return mt76_mcu_send_msg(&dev->mt76, MCU_CE_CMD(SET_MU_EDCA_PARMS),
 763				 &req_mu, sizeof(req_mu), false);
 764}
 765
 766int mt7921_mcu_set_roc(struct mt792x_phy *phy, struct mt792x_vif *vif,
 767		       struct ieee80211_channel *chan, int duration,
 768		       enum mt7921_roc_req type, u8 token_id)
 769{
 770	int center_ch = ieee80211_frequency_to_channel(chan->center_freq);
 771	struct mt792x_dev *dev = phy->dev;
 772	struct {
 773		struct {
 774			u8 rsv[4];
 775		} __packed hdr;
 776		struct roc_acquire_tlv {
 777			__le16 tag;
 778			__le16 len;
 779			u8 bss_idx;
 780			u8 tokenid;
 781			u8 control_channel;
 782			u8 sco;
 783			u8 band;
 784			u8 bw;
 785			u8 center_chan;
 786			u8 center_chan2;
 787			u8 bw_from_ap;
 788			u8 center_chan_from_ap;
 789			u8 center_chan2_from_ap;
 790			u8 reqtype;
 791			__le32 maxinterval;
 792			u8 dbdcband;
 793			u8 rsv[3];
 794		} __packed roc;
 795	} __packed req = {
 796		.roc = {
 797			.tag = cpu_to_le16(UNI_ROC_ACQUIRE),
 798			.len = cpu_to_le16(sizeof(struct roc_acquire_tlv)),
 799			.tokenid = token_id,
 800			.reqtype = type,
 801			.maxinterval = cpu_to_le32(duration),
 802			.bss_idx = vif->bss_conf.mt76.idx,
 803			.control_channel = chan->hw_value,
 804			.bw = CMD_CBW_20MHZ,
 805			.bw_from_ap = CMD_CBW_20MHZ,
 806			.center_chan = center_ch,
 807			.center_chan_from_ap = center_ch,
 808			.dbdcband = 0xff, /* auto */
 809		},
 810	};
 811
 812	if (chan->hw_value < center_ch)
 813		req.roc.sco = 1; /* SCA */
 814	else if (chan->hw_value > center_ch)
 815		req.roc.sco = 3; /* SCB */
 816
 817	switch (chan->band) {
 818	case NL80211_BAND_6GHZ:
 819		req.roc.band = 3;
 820		break;
 821	case NL80211_BAND_5GHZ:
 822		req.roc.band = 2;
 823		break;
 824	default:
 825		req.roc.band = 1;
 826		break;
 827	}
 828
 829	return mt76_mcu_send_msg(&dev->mt76, MCU_UNI_CMD(ROC),
 830				 &req, sizeof(req), false);
 831}
 832
 833int mt7921_mcu_abort_roc(struct mt792x_phy *phy, struct mt792x_vif *vif,
 834			 u8 token_id)
 835{
 836	struct mt792x_dev *dev = phy->dev;
 837	struct {
 838		struct {
 839			u8 rsv[4];
 840		} __packed hdr;
 841		struct roc_abort_tlv {
 842			__le16 tag;
 843			__le16 len;
 844			u8 bss_idx;
 845			u8 tokenid;
 846			u8 dbdcband;
 847			u8 rsv[5];
 848		} __packed abort;
 849	} __packed req = {
 850		.abort = {
 851			.tag = cpu_to_le16(UNI_ROC_ABORT),
 852			.len = cpu_to_le16(sizeof(struct roc_abort_tlv)),
 853			.tokenid = token_id,
 854			.bss_idx = vif->bss_conf.mt76.idx,
 855			.dbdcband = 0xff, /* auto*/
 856		},
 857	};
 858
 859	return mt76_mcu_send_msg(&dev->mt76, MCU_UNI_CMD(ROC),
 860				 &req, sizeof(req), false);
 861}
 862
 863int mt7921_mcu_set_chan_info(struct mt792x_phy *phy, int cmd)
 864{
 865	struct mt792x_dev *dev = phy->dev;
 866	struct cfg80211_chan_def *chandef = &phy->mt76->chandef;
 867	int freq1 = chandef->center_freq1;
 868	struct {
 869		u8 control_ch;
 870		u8 center_ch;
 871		u8 bw;
 872		u8 tx_streams_num;
 873		u8 rx_streams;	/* mask or num */
 874		u8 switch_reason;
 875		u8 band_idx;
 876		u8 center_ch2;	/* for 80+80 only */
 877		__le16 cac_case;
 878		u8 channel_band;
 879		u8 rsv0;
 880		__le32 outband_freq;
 881		u8 txpower_drop;
 882		u8 ap_bw;
 883		u8 ap_center_ch;
 884		u8 rsv1[57];
 885	} __packed req = {
 886		.control_ch = chandef->chan->hw_value,
 887		.center_ch = ieee80211_frequency_to_channel(freq1),
 888		.bw = mt76_connac_chan_bw(chandef),
 889		.tx_streams_num = hweight8(phy->mt76->antenna_mask),
 890		.rx_streams = phy->mt76->antenna_mask,
 891		.band_idx = phy != &dev->phy,
 892	};
 893
 894	if (chandef->chan->band == NL80211_BAND_6GHZ)
 895		req.channel_band = 2;
 896	else
 897		req.channel_band = chandef->chan->band;
 898
 899	if (cmd == MCU_EXT_CMD(SET_RX_PATH) ||
 900	    dev->mt76.hw->conf.flags & IEEE80211_CONF_MONITOR)
 901		req.switch_reason = CH_SWITCH_NORMAL;
 902	else if (phy->mt76->offchannel)
 903		req.switch_reason = CH_SWITCH_SCAN_BYPASS_DPD;
 904	else if (!cfg80211_reg_can_beacon(dev->mt76.hw->wiphy, chandef,
 905					  NL80211_IFTYPE_AP))
 906		req.switch_reason = CH_SWITCH_DFS;
 907	else
 908		req.switch_reason = CH_SWITCH_NORMAL;
 909
 910	if (cmd == MCU_EXT_CMD(CHANNEL_SWITCH))
 911		req.rx_streams = hweight8(req.rx_streams);
 912
 913	if (chandef->width == NL80211_CHAN_WIDTH_80P80) {
 914		int freq2 = chandef->center_freq2;
 915
 916		req.center_ch2 = ieee80211_frequency_to_channel(freq2);
 917	}
 918
 919	return mt76_mcu_send_msg(&dev->mt76, cmd, &req, sizeof(req), true);
 920}
 921
 922int mt7921_mcu_set_eeprom(struct mt792x_dev *dev)
 923{
 924	struct req_hdr {
 925		u8 buffer_mode;
 926		u8 format;
 927		__le16 len;
 928	} __packed req = {
 929		.buffer_mode = EE_MODE_EFUSE,
 930		.format = EE_FORMAT_WHOLE,
 931	};
 932
 933	return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(EFUSE_BUFFER_MODE),
 934				 &req, sizeof(req), true);
 935}
 936EXPORT_SYMBOL_GPL(mt7921_mcu_set_eeprom);
 937
 938int mt7921_mcu_uni_bss_ps(struct mt792x_dev *dev, struct ieee80211_vif *vif)
 939{
 940	struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv;
 941	struct {
 942		struct {
 943			u8 bss_idx;
 944			u8 pad[3];
 945		} __packed hdr;
 946		struct ps_tlv {
 947			__le16 tag;
 948			__le16 len;
 949			u8 ps_state; /* 0: device awake
 950				      * 1: static power save
 951				      * 2: dynamic power saving
 952				      * 3: enter TWT power saving
 953				      * 4: leave TWT power saving
 954				      */
 955			u8 pad[3];
 956		} __packed ps;
 957	} __packed ps_req = {
 958		.hdr = {
 959			.bss_idx = mvif->bss_conf.mt76.idx,
 960		},
 961		.ps = {
 962			.tag = cpu_to_le16(UNI_BSS_INFO_PS),
 963			.len = cpu_to_le16(sizeof(struct ps_tlv)),
 964			.ps_state = vif->cfg.ps ? 2 : 0,
 965		},
 966	};
 967
 968	if (vif->type != NL80211_IFTYPE_STATION)
 969		return -EOPNOTSUPP;
 970
 971	return mt76_mcu_send_msg(&dev->mt76, MCU_UNI_CMD(BSS_INFO_UPDATE),
 972				 &ps_req, sizeof(ps_req), true);
 973}
 974
 975static int
 976mt7921_mcu_uni_bss_bcnft(struct mt792x_dev *dev, struct ieee80211_vif *vif,
 977			 bool enable)
 978{
 979	struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv;
 980	struct {
 981		struct {
 982			u8 bss_idx;
 983			u8 pad[3];
 984		} __packed hdr;
 985		struct bcnft_tlv {
 986			__le16 tag;
 987			__le16 len;
 988			__le16 bcn_interval;
 989			u8 dtim_period;
 990			u8 pad;
 991		} __packed bcnft;
 992	} __packed bcnft_req = {
 993		.hdr = {
 994			.bss_idx = mvif->bss_conf.mt76.idx,
 995		},
 996		.bcnft = {
 997			.tag = cpu_to_le16(UNI_BSS_INFO_BCNFT),
 998			.len = cpu_to_le16(sizeof(struct bcnft_tlv)),
 999			.bcn_interval = cpu_to_le16(vif->bss_conf.beacon_int),
1000			.dtim_period = vif->bss_conf.dtim_period,
1001		},
1002	};
1003
1004	if (vif->type != NL80211_IFTYPE_STATION)
1005		return 0;
1006
1007	return mt76_mcu_send_msg(&dev->mt76, MCU_UNI_CMD(BSS_INFO_UPDATE),
1008				 &bcnft_req, sizeof(bcnft_req), true);
1009}
1010
1011int
1012mt7921_mcu_set_bss_pm(struct mt792x_dev *dev, struct ieee80211_vif *vif,
1013		      bool enable)
1014{
1015	struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv;
1016	struct {
1017		u8 bss_idx;
1018		u8 dtim_period;
1019		__le16 aid;
1020		__le16 bcn_interval;
1021		__le16 atim_window;
1022		u8 uapsd;
1023		u8 bmc_delivered_ac;
1024		u8 bmc_triggered_ac;
1025		u8 pad;
1026	} req = {
1027		.bss_idx = mvif->bss_conf.mt76.idx,
1028		.aid = cpu_to_le16(vif->cfg.aid),
1029		.dtim_period = vif->bss_conf.dtim_period,
1030		.bcn_interval = cpu_to_le16(vif->bss_conf.beacon_int),
1031	};
1032	struct {
1033		u8 bss_idx;
1034		u8 pad[3];
1035	} req_hdr = {
1036		.bss_idx = mvif->bss_conf.mt76.idx,
1037	};
1038	int err;
1039
1040	err = mt76_mcu_send_msg(&dev->mt76, MCU_CE_CMD(SET_BSS_ABORT),
1041				&req_hdr, sizeof(req_hdr), false);
1042	if (err < 0 || !enable)
1043		return err;
1044
1045	return mt76_mcu_send_msg(&dev->mt76, MCU_CE_CMD(SET_BSS_CONNECTED),
1046				 &req, sizeof(req), false);
1047}
1048
1049int mt7921_mcu_sta_update(struct mt792x_dev *dev, struct ieee80211_sta *sta,
1050			  struct ieee80211_vif *vif, bool enable,
1051			  enum mt76_sta_info_state state)
1052{
1053	struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv;
1054	int rssi = -ewma_rssi_read(&mvif->bss_conf.rssi);
1055	struct mt76_sta_cmd_info info = {
1056		.sta = sta,
1057		.vif = vif,
1058		.enable = enable,
1059		.cmd = MCU_UNI_CMD(STA_REC_UPDATE),
1060		.state = state,
1061		.offload_fw = true,
1062		.rcpi = to_rcpi(rssi),
1063	};
1064	struct mt792x_sta *msta;
1065
1066	msta = sta ? (struct mt792x_sta *)sta->drv_priv : NULL;
1067	info.wcid = msta ? &msta->deflink.wcid : &mvif->sta.deflink.wcid;
1068	info.newly = msta ? state != MT76_STA_INFO_STATE_ASSOC : true;
1069
1070	return mt76_connac_mcu_sta_cmd(&dev->mphy, &info);
1071}
1072
1073int mt7921_mcu_set_beacon_filter(struct mt792x_dev *dev,
1074				 struct ieee80211_vif *vif,
1075				 bool enable)
1076{
1077#define MT7921_FIF_BIT_CLR		BIT(1)
1078#define MT7921_FIF_BIT_SET		BIT(0)
1079	int err;
1080
1081	if (enable) {
1082		err = mt7921_mcu_uni_bss_bcnft(dev, vif, true);
1083		if (err)
1084			return err;
1085
1086		err = mt7921_mcu_set_rxfilter(dev, 0,
1087					      MT7921_FIF_BIT_SET,
1088					      MT_WF_RFCR_DROP_OTHER_BEACON);
1089		if (err)
1090			return err;
1091
1092		return 0;
1093	}
1094
1095	err = mt7921_mcu_set_bss_pm(dev, vif, false);
1096	if (err)
1097		return err;
1098
1099	err = mt7921_mcu_set_rxfilter(dev, 0,
1100				      MT7921_FIF_BIT_CLR,
1101				      MT_WF_RFCR_DROP_OTHER_BEACON);
1102	if (err)
1103		return err;
1104
1105	return 0;
1106}
1107
1108int mt7921_get_txpwr_info(struct mt792x_dev *dev, struct mt7921_txpwr *txpwr)
1109{
1110	struct mt7921_txpwr_event *event;
1111	struct mt7921_txpwr_req req = {
1112		.dbdc_idx = 0,
1113	};
1114	struct sk_buff *skb;
1115	int ret;
1116
1117	ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_CE_CMD(GET_TXPWR),
1118					&req, sizeof(req), true, &skb);
1119	if (ret)
1120		return ret;
1121
1122	event = (struct mt7921_txpwr_event *)skb->data;
1123	WARN_ON(skb->len != le16_to_cpu(event->len));
1124	memcpy(txpwr, &event->txpwr, sizeof(event->txpwr));
1125
1126	dev_kfree_skb(skb);
1127
1128	return 0;
1129}
1130
1131int mt7921_mcu_set_sniffer(struct mt792x_dev *dev, struct ieee80211_vif *vif,
1132			   bool enable)
1133{
1134	struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv;
1135	struct {
1136		struct {
1137			u8 band_idx;
1138			u8 pad[3];
1139		} __packed hdr;
1140		struct sniffer_enable_tlv {
1141			__le16 tag;
1142			__le16 len;
1143			u8 enable;
1144			u8 pad[3];
1145		} __packed enable;
1146	} req = {
1147		.hdr = {
1148			.band_idx = mvif->band_idx,
1149		},
1150		.enable = {
1151			.tag = cpu_to_le16(0),
1152			.len = cpu_to_le16(sizeof(struct sniffer_enable_tlv)),
1153			.enable = enable,
1154		},
1155	};
1156
1157	return mt76_mcu_send_msg(&dev->mt76, MCU_UNI_CMD(SNIFFER), &req, sizeof(req),
1158				 true);
1159}
1160
1161int mt7921_mcu_config_sniffer(struct mt792x_vif *vif,
1162			      struct ieee80211_chanctx_conf *ctx)
1163{
1164	struct cfg80211_chan_def *chandef = &ctx->def;
1165	int freq1 = chandef->center_freq1, freq2 = chandef->center_freq2;
1166	static const u8 ch_band[] = {
1167		[NL80211_BAND_2GHZ] = 1,
1168		[NL80211_BAND_5GHZ] = 2,
1169		[NL80211_BAND_6GHZ] = 3,
1170	};
1171	static const u8 ch_width[] = {
1172		[NL80211_CHAN_WIDTH_20_NOHT] = 0,
1173		[NL80211_CHAN_WIDTH_20] = 0,
1174		[NL80211_CHAN_WIDTH_40] = 0,
1175		[NL80211_CHAN_WIDTH_80] = 1,
1176		[NL80211_CHAN_WIDTH_160] = 2,
1177		[NL80211_CHAN_WIDTH_80P80] = 3,
1178		[NL80211_CHAN_WIDTH_5] = 4,
1179		[NL80211_CHAN_WIDTH_10] = 5,
1180		[NL80211_CHAN_WIDTH_320] = 6,
1181	};
1182	struct {
1183		struct {
1184			u8 band_idx;
1185			u8 pad[3];
1186		} __packed hdr;
1187		struct config_tlv {
1188			__le16 tag;
1189			__le16 len;
1190			u16 aid;
1191			u8 ch_band;
1192			u8 bw;
1193			u8 control_ch;
1194			u8 sco;
1195			u8 center_ch;
1196			u8 center_ch2;
1197			u8 drop_err;
1198			u8 pad[3];
1199		} __packed tlv;
1200	} __packed req = {
1201		.hdr = {
1202			.band_idx = vif->bss_conf.mt76.band_idx,
1203		},
1204		.tlv = {
1205			.tag = cpu_to_le16(1),
1206			.len = cpu_to_le16(sizeof(req.tlv)),
1207			.control_ch = chandef->chan->hw_value,
1208			.center_ch = ieee80211_frequency_to_channel(freq1),
1209			.drop_err = 1,
1210		},
1211	};
1212	if (chandef->chan->band < ARRAY_SIZE(ch_band))
1213		req.tlv.ch_band = ch_band[chandef->chan->band];
1214	if (chandef->width < ARRAY_SIZE(ch_width))
1215		req.tlv.bw = ch_width[chandef->width];
1216
1217	if (freq2)
1218		req.tlv.center_ch2 = ieee80211_frequency_to_channel(freq2);
1219
1220	if (req.tlv.control_ch < req.tlv.center_ch)
1221		req.tlv.sco = 1; /* SCA */
1222	else if (req.tlv.control_ch > req.tlv.center_ch)
1223		req.tlv.sco = 3; /* SCB */
1224
1225	return mt76_mcu_send_msg(vif->phy->mt76->dev, MCU_UNI_CMD(SNIFFER),
1226				 &req, sizeof(req), true);
1227}
1228
1229int
1230mt7921_mcu_uni_add_beacon_offload(struct mt792x_dev *dev,
1231				  struct ieee80211_hw *hw,
1232				  struct ieee80211_vif *vif,
1233				  bool enable)
1234{
1235	struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv;
1236	struct mt76_wcid *wcid = &dev->mt76.global_wcid;
1237	struct ieee80211_mutable_offsets offs;
1238	struct {
1239		struct req_hdr {
1240			u8 bss_idx;
1241			u8 pad[3];
1242		} __packed hdr;
1243		struct bcn_content_tlv {
1244			__le16 tag;
1245			__le16 len;
1246			__le16 tim_ie_pos;
1247			__le16 csa_ie_pos;
1248			__le16 bcc_ie_pos;
1249			/* 0: disable beacon offload
1250			 * 1: enable beacon offload
1251			 * 2: update probe respond offload
1252			 */
1253			u8 enable;
1254			/* 0: legacy format (TXD + payload)
1255			 * 1: only cap field IE
1256			 */
1257			u8 type;
1258			__le16 pkt_len;
1259			u8 pkt[512];
1260		} __packed beacon_tlv;
1261	} req = {
1262		.hdr = {
1263			.bss_idx = mvif->bss_conf.mt76.idx,
1264		},
1265		.beacon_tlv = {
1266			.tag = cpu_to_le16(UNI_BSS_INFO_BCN_CONTENT),
1267			.len = cpu_to_le16(sizeof(struct bcn_content_tlv)),
1268			.enable = enable,
1269		},
1270	};
1271	struct sk_buff *skb;
1272
1273	/* support enable/update process only
1274	 * disable flow would be handled in bss stop handler automatically
1275	 */
1276	if (!enable)
1277		return -EOPNOTSUPP;
1278
1279	skb = ieee80211_beacon_get_template(mt76_hw(dev), vif, &offs, 0);
1280	if (!skb)
1281		return -EINVAL;
1282
1283	if (skb->len > 512 - MT_TXD_SIZE) {
1284		dev_err(dev->mt76.dev, "beacon size limit exceed\n");
1285		dev_kfree_skb(skb);
1286		return -EINVAL;
1287	}
1288
1289	mt76_connac2_mac_write_txwi(&dev->mt76, (__le32 *)(req.beacon_tlv.pkt),
1290				    skb, wcid, NULL, 0, 0, BSS_CHANGED_BEACON);
1291	memcpy(req.beacon_tlv.pkt + MT_TXD_SIZE, skb->data, skb->len);
1292	req.beacon_tlv.pkt_len = cpu_to_le16(MT_TXD_SIZE + skb->len);
1293	req.beacon_tlv.tim_ie_pos = cpu_to_le16(MT_TXD_SIZE + offs.tim_offset);
1294
1295	if (offs.cntdwn_counter_offs[0]) {
1296		u16 csa_offs;
1297
1298		csa_offs = MT_TXD_SIZE + offs.cntdwn_counter_offs[0] - 4;
1299		req.beacon_tlv.csa_ie_pos = cpu_to_le16(csa_offs);
1300	}
1301	dev_kfree_skb(skb);
1302
1303	return mt76_mcu_send_msg(&dev->mt76, MCU_UNI_CMD(BSS_INFO_UPDATE),
1304				 &req, sizeof(req), true);
1305}
1306
1307static
1308int __mt7921_mcu_set_clc(struct mt792x_dev *dev, u8 *alpha2,
1309			 enum environment_cap env_cap,
1310			 struct mt7921_clc *clc,
1311			 u8 idx)
1312{
1313#define CLC_CAP_EVT_EN BIT(0)
1314#define CLC_CAP_DTS_EN BIT(1)
1315	struct sk_buff *skb, *ret_skb = NULL;
1316	struct {
1317		u8 ver;
1318		u8 pad0;
1319		__le16 len;
1320		u8 idx;
1321		u8 env;
1322		u8 acpi_conf;
1323		u8 cap;
1324		u8 alpha2[2];
1325		u8 type[2];
1326		u8 env_6g;
1327		u8 mtcl_conf;
1328		u8 rsvd[62];
1329	} __packed req = {
1330		.ver = 1,
1331		.idx = idx,
1332		.env = env_cap,
1333		.env_6g = dev->phy.power_type,
1334		.acpi_conf = mt792x_acpi_get_flags(&dev->phy),
1335		.mtcl_conf = mt792x_acpi_get_mtcl_conf(&dev->phy, alpha2),
1336	};
1337	int ret, valid_cnt = 0;
1338	u32 buf_len = 0;
1339	u8 *pos;
1340
1341	if (!clc)
1342		return 0;
1343
1344	if (dev->phy.chip_cap & MT792x_CHIP_CAP_CLC_EVT_EN)
1345		req.cap |= CLC_CAP_EVT_EN;
1346	if (mt76_find_power_limits_node(&dev->mt76))
1347		req.cap |= CLC_CAP_DTS_EN;
1348
1349	buf_len = le32_to_cpu(clc->len) - sizeof(*clc);
1350	pos = clc->data;
1351	while (buf_len > 16) {
1352		struct mt7921_clc_rule *rule = (struct mt7921_clc_rule *)pos;
1353		u16 len = le16_to_cpu(rule->len);
1354		u16 offset = len + sizeof(*rule);
1355
1356		pos += offset;
1357		buf_len -= offset;
1358		if (rule->alpha2[0] != alpha2[0] ||
1359		    rule->alpha2[1] != alpha2[1])
1360			continue;
1361
1362		memcpy(req.alpha2, rule->alpha2, 2);
1363		memcpy(req.type, rule->type, 2);
1364
1365		req.len = cpu_to_le16(sizeof(req) + len);
1366		skb = __mt76_mcu_msg_alloc(&dev->mt76, &req,
1367					   le16_to_cpu(req.len),
1368					   sizeof(req), GFP_KERNEL);
1369		if (!skb)
1370			return -ENOMEM;
1371		skb_put_data(skb, rule->data, len);
1372
1373		ret = mt76_mcu_skb_send_and_get_msg(&dev->mt76, skb,
1374						    MCU_CE_CMD(SET_CLC),
1375						    !!(req.cap & CLC_CAP_EVT_EN),
1376						    &ret_skb);
1377		if (ret < 0)
1378			return ret;
1379
1380		if (ret_skb) {
1381			struct mt7921_clc_info_tlv *info;
1382
1383			info = (struct mt7921_clc_info_tlv *)(ret_skb->data + 4);
1384			dev->phy.clc_chan_conf = info->chan_conf;
1385			dev_kfree_skb(ret_skb);
1386		}
1387
1388		valid_cnt++;
1389	}
1390
1391	if (!valid_cnt)
1392		return -ENOENT;
1393
1394	return 0;
1395}
1396
1397int mt7921_mcu_set_clc(struct mt792x_dev *dev, u8 *alpha2,
1398		       enum environment_cap env_cap)
1399{
1400	struct mt792x_phy *phy = (struct mt792x_phy *)&dev->phy;
1401	int i, ret;
1402
1403	/* submit all clc config */
1404	for (i = 0; i < ARRAY_SIZE(phy->clc); i++) {
1405		ret = __mt7921_mcu_set_clc(dev, alpha2, env_cap,
1406					   phy->clc[i], i);
1407
1408		/* If no country found, set "00" as default */
1409		if (ret == -ENOENT)
1410			ret = __mt7921_mcu_set_clc(dev, "00",
1411						   ENVIRON_INDOOR,
1412						   phy->clc[i], i);
1413		if (ret < 0)
1414			return ret;
1415	}
1416	return 0;
1417}
1418
1419int mt7921_mcu_get_temperature(struct mt792x_phy *phy)
1420{
1421	struct mt792x_dev *dev = phy->dev;
1422	struct {
1423		u8 ctrl_id;
1424		u8 action;
1425		u8 band_idx;
1426		u8 rsv[5];
1427	} req = {
1428		.ctrl_id = THERMAL_SENSOR_TEMP_QUERY,
1429		.band_idx = phy->mt76->band_idx,
1430	};
1431
1432	return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(THERMAL_CTRL), &req,
1433				 sizeof(req), true);
1434}
1435
1436int mt7921_mcu_wf_rf_pin_ctrl(struct mt792x_phy *phy, u8 action)
1437{
1438	struct mt792x_dev *dev = phy->dev;
1439	struct {
1440		u8 action;
1441		u8 value;
1442	} req = {
1443		.action = action,
1444		.value = 0,
1445	};
1446
1447	return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(WF_RF_PIN_CTRL), &req,
1448				 sizeof(req), action ? true : false);
1449}
1450
1451int mt7921_mcu_set_rxfilter(struct mt792x_dev *dev, u32 fif,
1452			    u8 bit_op, u32 bit_map)
1453{
1454	struct {
1455		u8 rsv[4];
1456		u8 mode;
1457		u8 rsv2[3];
1458		__le32 fif;
1459		__le32 bit_map; /* bit_* for bitmap update */
1460		u8 bit_op;
1461		u8 pad[51];
1462	} __packed data = {
1463		.mode = fif ? 1 : 2,
1464		.fif = cpu_to_le32(fif),
1465		.bit_map = cpu_to_le32(bit_map),
1466		.bit_op = bit_op,
1467	};
1468
1469	return mt76_mcu_send_msg(&dev->mt76, MCU_CE_CMD(SET_RX_FILTER),
1470				 &data, sizeof(data), false);
1471}
1472
1473int mt7921_mcu_set_rssimonitor(struct mt792x_dev *dev, struct ieee80211_vif *vif)
1474{
1475	struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv;
1476	struct {
1477		u8 enable;
1478		s8 cqm_rssi_high;
1479		s8 cqm_rssi_low;
1480		u8 bss_idx;
1481		u16 duration;
1482		u8 rsv2[2];
1483	} __packed data = {
1484		.enable = vif->cfg.assoc,
1485		.cqm_rssi_high = vif->bss_conf.cqm_rssi_thold + vif->bss_conf.cqm_rssi_hyst,
1486		.cqm_rssi_low = vif->bss_conf.cqm_rssi_thold - vif->bss_conf.cqm_rssi_hyst,
1487		.bss_idx = mvif->bss_conf.mt76.idx,
1488	};
1489
1490	return mt76_mcu_send_msg(&dev->mt76, MCU_CE_CMD(RSSI_MONITOR),
1491				 &data, sizeof(data), false);
1492}
~/ Read-only file preview.