brintos

brintos / linux-shallow public Read only

0
0
Text · 45.9 KiB · d75e8de Raw
1754 lines · c
1// SPDX-License-Identifier: ISC2/* Copyright (C) 2020 MediaTek Inc. */3 4#include <linux/etherdevice.h>5#include <linux/platform_device.h>6#include <linux/pci.h>7#include <linux/module.h>8#include "mt7915.h"9#include "mcu.h"10 11static bool mt7915_dev_running(struct mt7915_dev *dev)12{13	struct mt7915_phy *phy;14 15	if (test_bit(MT76_STATE_RUNNING, &dev->mphy.state))16		return true;17 18	phy = mt7915_ext_phy(dev);19 20	return phy && test_bit(MT76_STATE_RUNNING, &phy->mt76->state);21}22 23int mt7915_run(struct ieee80211_hw *hw)24{25	struct mt7915_dev *dev = mt7915_hw_dev(hw);26	struct mt7915_phy *phy = mt7915_hw_phy(hw);27	bool running;28	int ret;29 30	running = mt7915_dev_running(dev);31 32	if (!running) {33		ret = mt76_connac_mcu_set_pm(&dev->mt76,34					     dev->phy.mt76->band_idx, 0);35		if (ret)36			goto out;37 38		ret = mt7915_mcu_set_mac(dev, dev->phy.mt76->band_idx,39					 true, true);40		if (ret)41			goto out;42 43		mt7915_mac_enable_nf(dev, dev->phy.mt76->band_idx);44	}45 46	if (phy != &dev->phy) {47		ret = mt76_connac_mcu_set_pm(&dev->mt76,48					     phy->mt76->band_idx, 0);49		if (ret)50			goto out;51 52		ret = mt7915_mcu_set_mac(dev, phy->mt76->band_idx,53					 true, true);54		if (ret)55			goto out;56 57		mt7915_mac_enable_nf(dev, phy->mt76->band_idx);58	}59 60	ret = mt7915_mcu_set_thermal_throttling(phy,61						MT7915_THERMAL_THROTTLE_MAX);62 63	if (ret)64		goto out;65 66	ret = mt7915_mcu_set_thermal_protect(phy);67 68	if (ret)69		goto out;70 71	ret = mt76_connac_mcu_set_rts_thresh(&dev->mt76, 0x92b,72					     phy->mt76->band_idx);73	if (ret)74		goto out;75 76	ret = mt7915_mcu_set_sku_en(phy, true);77	if (ret)78		goto out;79 80	ret = mt7915_mcu_set_chan_info(phy, MCU_EXT_CMD(SET_RX_PATH));81	if (ret)82		goto out;83 84	set_bit(MT76_STATE_RUNNING, &phy->mt76->state);85 86	if (!mt76_testmode_enabled(phy->mt76))87		ieee80211_queue_delayed_work(hw, &phy->mt76->mac_work,88					     MT7915_WATCHDOG_TIME);89 90	if (!running)91		mt7915_mac_reset_counters(phy);92 93out:94	return ret;95}96 97static int mt7915_start(struct ieee80211_hw *hw)98{99	struct mt7915_dev *dev = mt7915_hw_dev(hw);100	int ret;101 102	flush_work(&dev->init_work);103 104	mutex_lock(&dev->mt76.mutex);105	ret = mt7915_run(hw);106	mutex_unlock(&dev->mt76.mutex);107 108	return ret;109}110 111static void mt7915_stop(struct ieee80211_hw *hw, bool suspend)112{113	struct mt7915_dev *dev = mt7915_hw_dev(hw);114	struct mt7915_phy *phy = mt7915_hw_phy(hw);115 116	cancel_delayed_work_sync(&phy->mt76->mac_work);117 118	mutex_lock(&dev->mt76.mutex);119 120	mt76_testmode_reset(phy->mt76, true);121 122	clear_bit(MT76_STATE_RUNNING, &phy->mt76->state);123 124	if (phy != &dev->phy) {125		mt76_connac_mcu_set_pm(&dev->mt76, phy->mt76->band_idx, 1);126		mt7915_mcu_set_mac(dev, phy->mt76->band_idx, false, false);127	}128 129	if (!mt7915_dev_running(dev)) {130		mt76_connac_mcu_set_pm(&dev->mt76, dev->phy.mt76->band_idx, 1);131		mt7915_mcu_set_mac(dev, dev->phy.mt76->band_idx, false, false);132	}133 134	mutex_unlock(&dev->mt76.mutex);135}136 137static inline int get_free_idx(u32 mask, u8 start, u8 end)138{139	return ffs(~mask & GENMASK(end, start));140}141 142static int get_omac_idx(enum nl80211_iftype type, u64 mask)143{144	int i;145 146	switch (type) {147	case NL80211_IFTYPE_MESH_POINT:148	case NL80211_IFTYPE_ADHOC:149	case NL80211_IFTYPE_STATION:150		/* prefer hw bssid slot 1-3 */151		i = get_free_idx(mask, HW_BSSID_1, HW_BSSID_3);152		if (i)153			return i - 1;154 155		if (type != NL80211_IFTYPE_STATION)156			break;157 158		i = get_free_idx(mask, EXT_BSSID_1, EXT_BSSID_MAX);159		if (i)160			return i - 1;161 162		if (~mask & BIT(HW_BSSID_0))163			return HW_BSSID_0;164 165		break;166	case NL80211_IFTYPE_MONITOR:167	case NL80211_IFTYPE_AP:168		/* ap uses hw bssid 0 and ext bssid */169		if (~mask & BIT(HW_BSSID_0))170			return HW_BSSID_0;171 172		i = get_free_idx(mask, EXT_BSSID_1, EXT_BSSID_MAX);173		if (i)174			return i - 1;175 176		break;177	default:178		WARN_ON(1);179		break;180	}181 182	return -1;183}184 185static void mt7915_init_bitrate_mask(struct ieee80211_vif *vif)186{187	struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;188	int i;189 190	for (i = 0; i < ARRAY_SIZE(mvif->bitrate_mask.control); i++) {191		mvif->bitrate_mask.control[i].gi = NL80211_TXRATE_DEFAULT_GI;192		mvif->bitrate_mask.control[i].he_gi = 0xff;193		mvif->bitrate_mask.control[i].he_ltf = 0xff;194		mvif->bitrate_mask.control[i].legacy = GENMASK(31, 0);195		memset(mvif->bitrate_mask.control[i].ht_mcs, 0xff,196		       sizeof(mvif->bitrate_mask.control[i].ht_mcs));197		memset(mvif->bitrate_mask.control[i].vht_mcs, 0xff,198		       sizeof(mvif->bitrate_mask.control[i].vht_mcs));199		memset(mvif->bitrate_mask.control[i].he_mcs, 0xff,200		       sizeof(mvif->bitrate_mask.control[i].he_mcs));201	}202}203 204static int mt7915_add_interface(struct ieee80211_hw *hw,205				struct ieee80211_vif *vif)206{207	struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;208	struct mt7915_dev *dev = mt7915_hw_dev(hw);209	struct mt7915_phy *phy = mt7915_hw_phy(hw);210	struct mt76_txq *mtxq;211	bool ext_phy = phy != &dev->phy;212	int idx, ret = 0;213 214	mutex_lock(&dev->mt76.mutex);215 216	mt76_testmode_reset(phy->mt76, true);217 218	if (vif->type == NL80211_IFTYPE_MONITOR &&219	    is_zero_ether_addr(vif->addr))220		phy->monitor_vif = vif;221 222	mvif->mt76.idx = __ffs64(~dev->mt76.vif_mask);223	if (mvif->mt76.idx >= (MT7915_MAX_INTERFACES << dev->dbdc_support)) {224		ret = -ENOSPC;225		goto out;226	}227 228	idx = get_omac_idx(vif->type, phy->omac_mask);229	if (idx < 0) {230		ret = -ENOSPC;231		goto out;232	}233	mvif->mt76.omac_idx = idx;234	mvif->phy = phy;235	mvif->mt76.band_idx = phy->mt76->band_idx;236 237	mvif->mt76.wmm_idx = vif->type != NL80211_IFTYPE_AP;238	if (ext_phy)239		mvif->mt76.wmm_idx += 2;240 241	ret = mt7915_mcu_add_dev_info(phy, vif, true);242	if (ret)243		goto out;244 245	dev->mt76.vif_mask |= BIT_ULL(mvif->mt76.idx);246	phy->omac_mask |= BIT_ULL(mvif->mt76.omac_idx);247 248	idx = mt76_wcid_alloc(dev->mt76.wcid_mask, mt7915_wtbl_size(dev));249	if (idx < 0)250		return -ENOSPC;251 252	INIT_LIST_HEAD(&mvif->sta.rc_list);253	INIT_LIST_HEAD(&mvif->sta.wcid.poll_list);254	mvif->sta.wcid.idx = idx;255	mvif->sta.wcid.phy_idx = ext_phy;256	mvif->sta.wcid.hw_key_idx = -1;257	mvif->sta.wcid.tx_info |= MT_WCID_TX_INFO_SET;258	mt76_wcid_init(&mvif->sta.wcid);259 260	mt7915_mac_wtbl_update(dev, idx,261			       MT_WTBL_UPDATE_ADM_COUNT_CLEAR);262 263	if (vif->txq) {264		mtxq = (struct mt76_txq *)vif->txq->drv_priv;265		mtxq->wcid = idx;266	}267 268	if (vif->type != NL80211_IFTYPE_AP &&269	    (!mvif->mt76.omac_idx || mvif->mt76.omac_idx > 3))270		vif->offload_flags = 0;271	vif->offload_flags |= IEEE80211_OFFLOAD_ENCAP_4ADDR;272 273	mt7915_init_bitrate_mask(vif);274	memset(&mvif->cap, -1, sizeof(mvif->cap));275 276	mt7915_mcu_add_bss_info(phy, vif, true);277	mt7915_mcu_add_sta(dev, vif, NULL, CONN_STATE_PORT_SECURE, true);278	rcu_assign_pointer(dev->mt76.wcid[idx], &mvif->sta.wcid);279 280out:281	mutex_unlock(&dev->mt76.mutex);282 283	return ret;284}285 286static void mt7915_remove_interface(struct ieee80211_hw *hw,287				    struct ieee80211_vif *vif)288{289	struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;290	struct mt7915_sta *msta = &mvif->sta;291	struct mt7915_dev *dev = mt7915_hw_dev(hw);292	struct mt7915_phy *phy = mt7915_hw_phy(hw);293	int idx = msta->wcid.idx;294 295	mt7915_mcu_add_bss_info(phy, vif, false);296	mt7915_mcu_add_sta(dev, vif, NULL, CONN_STATE_DISCONNECT, false);297	mt76_wcid_mask_clear(dev->mt76.wcid_mask, mvif->sta.wcid.idx);298 299	mutex_lock(&dev->mt76.mutex);300	mt76_testmode_reset(phy->mt76, true);301	mutex_unlock(&dev->mt76.mutex);302 303	if (vif == phy->monitor_vif)304		phy->monitor_vif = NULL;305 306	mt7915_mcu_add_dev_info(phy, vif, false);307 308	rcu_assign_pointer(dev->mt76.wcid[idx], NULL);309 310	mutex_lock(&dev->mt76.mutex);311	dev->mt76.vif_mask &= ~BIT_ULL(mvif->mt76.idx);312	phy->omac_mask &= ~BIT_ULL(mvif->mt76.omac_idx);313	mutex_unlock(&dev->mt76.mutex);314 315	spin_lock_bh(&dev->mt76.sta_poll_lock);316	if (!list_empty(&msta->wcid.poll_list))317		list_del_init(&msta->wcid.poll_list);318	spin_unlock_bh(&dev->mt76.sta_poll_lock);319 320	mt76_wcid_cleanup(&dev->mt76, &msta->wcid);321}322 323int mt7915_set_channel(struct mt76_phy *mphy)324{325	struct mt7915_phy *phy = mphy->priv;326	struct mt7915_dev *dev = phy->dev;327	int ret;328 329	if (dev->cal) {330		ret = mt7915_mcu_apply_tx_dpd(phy);331		if (ret)332			goto out;333	}334 335	ret = mt7915_mcu_set_chan_info(phy, MCU_EXT_CMD(CHANNEL_SWITCH));336	if (ret)337		goto out;338 339	mt7915_mac_set_timing(phy);340	ret = mt7915_dfs_init_radar_detector(phy);341	mt7915_mac_cca_stats_reset(phy);342 343	mt7915_mac_reset_counters(phy);344	phy->noise = 0;345 346out:347	if (!mt76_testmode_enabled(phy->mt76))348		ieee80211_queue_delayed_work(phy->mt76->hw,349					     &phy->mt76->mac_work,350					     MT7915_WATCHDOG_TIME);351 352	return ret;353}354 355static int mt7915_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,356			  struct ieee80211_vif *vif, struct ieee80211_sta *sta,357			  struct ieee80211_key_conf *key)358{359	struct mt7915_dev *dev = mt7915_hw_dev(hw);360	struct mt7915_phy *phy = mt7915_hw_phy(hw);361	struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;362	struct mt7915_sta *msta = sta ? (struct mt7915_sta *)sta->drv_priv :363				  &mvif->sta;364	struct mt76_wcid *wcid = &msta->wcid;365	u8 *wcid_keyidx = &wcid->hw_key_idx;366	int idx = key->keyidx;367	int err = 0;368 369	if (sta && !wcid->sta)370		return -EOPNOTSUPP;371 372	/* The hardware does not support per-STA RX GTK, fallback373	 * to software mode for these.374	 */375	if ((vif->type == NL80211_IFTYPE_ADHOC ||376	     vif->type == NL80211_IFTYPE_MESH_POINT) &&377	    (key->cipher == WLAN_CIPHER_SUITE_TKIP ||378	     key->cipher == WLAN_CIPHER_SUITE_CCMP) &&379	    !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE))380		return -EOPNOTSUPP;381 382	/* fall back to sw encryption for unsupported ciphers */383	switch (key->cipher) {384	case WLAN_CIPHER_SUITE_AES_CMAC:385		wcid_keyidx = &wcid->hw_key_idx2;386		key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIE;387		break;388	case WLAN_CIPHER_SUITE_TKIP:389	case WLAN_CIPHER_SUITE_CCMP:390	case WLAN_CIPHER_SUITE_CCMP_256:391	case WLAN_CIPHER_SUITE_GCMP:392	case WLAN_CIPHER_SUITE_GCMP_256:393	case WLAN_CIPHER_SUITE_SMS4:394		break;395	case WLAN_CIPHER_SUITE_WEP40:396	case WLAN_CIPHER_SUITE_WEP104:397	default:398		return -EOPNOTSUPP;399	}400 401	mutex_lock(&dev->mt76.mutex);402 403	if (cmd == SET_KEY && !sta && !mvif->mt76.cipher) {404		mvif->mt76.cipher = mt76_connac_mcu_get_cipher(key->cipher);405		mt7915_mcu_add_bss_info(phy, vif, true);406	}407 408	if (cmd == SET_KEY) {409		*wcid_keyidx = idx;410	} else {411		if (idx == *wcid_keyidx)412			*wcid_keyidx = -1;413		goto out;414	}415 416	mt76_wcid_key_setup(&dev->mt76, wcid, key);417	err = mt76_connac_mcu_add_key(&dev->mt76, vif, &msta->bip,418				      key, MCU_EXT_CMD(STA_REC_UPDATE),419				      &msta->wcid, cmd);420out:421	mutex_unlock(&dev->mt76.mutex);422 423	return err;424}425 426static int mt7915_set_sar_specs(struct ieee80211_hw *hw,427				const struct cfg80211_sar_specs *sar)428{429	struct mt7915_phy *phy = mt7915_hw_phy(hw);430	struct mt7915_dev *dev = mt7915_hw_dev(hw);431	int err = -EINVAL;432 433	mutex_lock(&dev->mt76.mutex);434	if (!cfg80211_chandef_valid(&phy->mt76->chandef))435		goto out;436 437	err = mt76_init_sar_power(hw, sar);438	if (err)439		goto out;440 441	err = mt7915_mcu_set_txpower_sku(phy);442out:443	mutex_unlock(&dev->mt76.mutex);444 445	return err;446}447 448static int mt7915_config(struct ieee80211_hw *hw, u32 changed)449{450	struct mt7915_dev *dev = mt7915_hw_dev(hw);451	struct mt7915_phy *phy = mt7915_hw_phy(hw);452	int ret;453 454	if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {455#ifdef CONFIG_NL80211_TESTMODE456		if (phy->mt76->test.state != MT76_TM_STATE_OFF) {457			mutex_lock(&dev->mt76.mutex);458			mt76_testmode_reset(phy->mt76, false);459			mutex_unlock(&dev->mt76.mutex);460		}461#endif462		ret = mt76_update_channel(phy->mt76);463		if (ret)464			return ret;465	}466 467	if (changed & (IEEE80211_CONF_CHANGE_POWER |468		       IEEE80211_CONF_CHANGE_CHANNEL)) {469		ret = mt7915_mcu_set_txpower_sku(phy);470		if (ret)471			return ret;472	}473 474	mutex_lock(&dev->mt76.mutex);475 476	if (changed & IEEE80211_CONF_CHANGE_MONITOR) {477		bool enabled = !!(hw->conf.flags & IEEE80211_CONF_MONITOR);478		bool band = phy->mt76->band_idx;479		u32 rxfilter = phy->rxfilter;480 481		if (!enabled) {482			rxfilter |= MT_WF_RFCR_DROP_OTHER_UC;483			dev->monitor_mask &= ~BIT(band);484		} else {485			rxfilter &= ~MT_WF_RFCR_DROP_OTHER_UC;486			dev->monitor_mask |= BIT(band);487		}488 489		mt76_rmw_field(dev, MT_DMA_DCR0(band), MT_DMA_DCR0_RXD_G5_EN,490			       enabled);491		mt76_rmw_field(dev, MT_DMA_DCR0(band), MT_MDP_DCR0_RX_HDR_TRANS_EN,492			       !dev->monitor_mask);493		mt76_testmode_reset(phy->mt76, true);494		mt76_wr(dev, MT_WF_RFCR(band), rxfilter);495	}496 497	mutex_unlock(&dev->mt76.mutex);498 499	return 0;500}501 502static int503mt7915_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif,504	       unsigned int link_id, u16 queue,505	       const struct ieee80211_tx_queue_params *params)506{507	struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;508 509	/* no need to update right away, we'll get BSS_CHANGED_QOS */510	queue = mt76_connac_lmac_mapping(queue);511	mvif->queue_params[queue] = *params;512 513	return 0;514}515 516static void mt7915_configure_filter(struct ieee80211_hw *hw,517				    unsigned int changed_flags,518				    unsigned int *total_flags,519				    u64 multicast)520{521	struct mt7915_dev *dev = mt7915_hw_dev(hw);522	struct mt7915_phy *phy = mt7915_hw_phy(hw);523	bool band = phy->mt76->band_idx;524	u32 ctl_flags = MT_WF_RFCR1_DROP_ACK |525			MT_WF_RFCR1_DROP_BF_POLL |526			MT_WF_RFCR1_DROP_BA |527			MT_WF_RFCR1_DROP_CFEND |528			MT_WF_RFCR1_DROP_CFACK;529	u32 rxfilter;530	u32 flags = 0;531 532#define MT76_FILTER(_flag, _hw) do {					\533		flags |= *total_flags & FIF_##_flag;			\534		phy->rxfilter &= ~(_hw);				\535		phy->rxfilter |= !(flags & FIF_##_flag) * (_hw);	\536	} while (0)537 538	mutex_lock(&dev->mt76.mutex);539 540	phy->rxfilter &= ~(MT_WF_RFCR_DROP_OTHER_BSS |541			   MT_WF_RFCR_DROP_OTHER_BEACON |542			   MT_WF_RFCR_DROP_FRAME_REPORT |543			   MT_WF_RFCR_DROP_PROBEREQ |544			   MT_WF_RFCR_DROP_MCAST_FILTERED |545			   MT_WF_RFCR_DROP_MCAST |546			   MT_WF_RFCR_DROP_BCAST |547			   MT_WF_RFCR_DROP_DUPLICATE |548			   MT_WF_RFCR_DROP_A2_BSSID |549			   MT_WF_RFCR_DROP_UNWANTED_CTL |550			   MT_WF_RFCR_DROP_STBC_MULTI);551 552	MT76_FILTER(OTHER_BSS, MT_WF_RFCR_DROP_OTHER_TIM |553			       MT_WF_RFCR_DROP_A3_MAC |554			       MT_WF_RFCR_DROP_A3_BSSID);555 556	MT76_FILTER(FCSFAIL, MT_WF_RFCR_DROP_FCSFAIL);557 558	MT76_FILTER(CONTROL, MT_WF_RFCR_DROP_CTS |559			     MT_WF_RFCR_DROP_RTS |560			     MT_WF_RFCR_DROP_CTL_RSV);561 562	*total_flags = flags;563	rxfilter = phy->rxfilter;564	if (hw->conf.flags & IEEE80211_CONF_MONITOR)565		rxfilter &= ~MT_WF_RFCR_DROP_OTHER_UC;566	else567		rxfilter |= MT_WF_RFCR_DROP_OTHER_UC;568	mt76_wr(dev, MT_WF_RFCR(band), rxfilter);569 570	if (*total_flags & FIF_CONTROL)571		mt76_clear(dev, MT_WF_RFCR1(band), ctl_flags);572	else573		mt76_set(dev, MT_WF_RFCR1(band), ctl_flags);574 575	mutex_unlock(&dev->mt76.mutex);576}577 578static void579mt7915_update_bss_color(struct ieee80211_hw *hw,580			struct ieee80211_vif *vif,581			struct cfg80211_he_bss_color *bss_color)582{583	struct mt7915_dev *dev = mt7915_hw_dev(hw);584 585	switch (vif->type) {586	case NL80211_IFTYPE_AP: {587		struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;588 589		if (mvif->mt76.omac_idx > HW_BSSID_MAX)590			return;591		fallthrough;592	}593	case NL80211_IFTYPE_STATION:594		mt7915_mcu_update_bss_color(dev, vif, bss_color);595		break;596	default:597		break;598	}599}600 601static void mt7915_bss_info_changed(struct ieee80211_hw *hw,602				    struct ieee80211_vif *vif,603				    struct ieee80211_bss_conf *info,604				    u64 changed)605{606	struct mt7915_phy *phy = mt7915_hw_phy(hw);607	struct mt7915_dev *dev = mt7915_hw_dev(hw);608	int set_bss_info = -1, set_sta = -1;609 610	mutex_lock(&dev->mt76.mutex);611 612	/*613	 * station mode uses BSSID to map the wlan entry to a peer,614	 * and then peer references bss_info_rfch to set bandwidth cap.615	 */616	if (changed & BSS_CHANGED_BSSID &&617	    vif->type == NL80211_IFTYPE_STATION)618		set_bss_info = set_sta = !is_zero_ether_addr(info->bssid);619	if (changed & BSS_CHANGED_ASSOC)620		set_bss_info = vif->cfg.assoc;621	if (changed & BSS_CHANGED_BEACON_ENABLED &&622	    vif->type != NL80211_IFTYPE_AP)623		set_bss_info = set_sta = info->enable_beacon;624 625	if (set_bss_info == 1)626		mt7915_mcu_add_bss_info(phy, vif, true);627	if (set_sta == 1)628		mt7915_mcu_add_sta(dev, vif, NULL, CONN_STATE_PORT_SECURE, false);629 630	if (changed & BSS_CHANGED_ERP_CTS_PROT)631		mt7915_mac_enable_rtscts(dev, vif, info->use_cts_prot);632 633	if (changed & BSS_CHANGED_ERP_SLOT) {634		int slottime = info->use_short_slot ? 9 : 20;635 636		if (slottime != phy->slottime) {637			phy->slottime = slottime;638			mt7915_mac_set_timing(phy);639		}640	}641 642	/* ensure that enable txcmd_mode after bss_info */643	if (changed & (BSS_CHANGED_QOS | BSS_CHANGED_BEACON_ENABLED))644		mt7915_mcu_set_tx(dev, vif);645 646	if (changed & BSS_CHANGED_HE_OBSS_PD)647		mt7915_mcu_add_obss_spr(phy, vif, &info->he_obss_pd);648 649	if (changed & BSS_CHANGED_HE_BSS_COLOR)650		mt7915_update_bss_color(hw, vif, &info->he_bss_color);651 652	if (changed & (BSS_CHANGED_BEACON |653		       BSS_CHANGED_BEACON_ENABLED))654		mt7915_mcu_add_beacon(hw, vif, info->enable_beacon, changed);655 656	if (changed & (BSS_CHANGED_UNSOL_BCAST_PROBE_RESP |657		       BSS_CHANGED_FILS_DISCOVERY))658		mt7915_mcu_add_inband_discov(dev, vif, changed);659 660	if (set_bss_info == 0)661		mt7915_mcu_add_bss_info(phy, vif, false);662	if (set_sta == 0)663		mt7915_mcu_add_sta(dev, vif, NULL, CONN_STATE_DISCONNECT, false);664 665	mutex_unlock(&dev->mt76.mutex);666}667 668static void669mt7915_vif_check_caps(struct mt7915_phy *phy, struct ieee80211_vif *vif)670{671	struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;672	struct mt7915_vif_cap *vc = &mvif->cap;673 674	vc->ht_ldpc = vif->bss_conf.ht_ldpc;675	vc->vht_ldpc = vif->bss_conf.vht_ldpc;676	vc->vht_su_ebfer = vif->bss_conf.vht_su_beamformer;677	vc->vht_su_ebfee = vif->bss_conf.vht_su_beamformee;678	vc->vht_mu_ebfer = vif->bss_conf.vht_mu_beamformer;679	vc->vht_mu_ebfee = vif->bss_conf.vht_mu_beamformee;680	vc->he_ldpc = vif->bss_conf.he_ldpc;681	vc->he_su_ebfer = vif->bss_conf.he_su_beamformer;682	vc->he_su_ebfee = vif->bss_conf.he_su_beamformee;683	vc->he_mu_ebfer = vif->bss_conf.he_mu_beamformer;684}685 686static int687mt7915_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif,688		struct ieee80211_bss_conf *link_conf)689{690	struct mt7915_phy *phy = mt7915_hw_phy(hw);691	struct mt7915_dev *dev = mt7915_hw_dev(hw);692	int err;693 694	mutex_lock(&dev->mt76.mutex);695 696	mt7915_vif_check_caps(phy, vif);697 698	err = mt7915_mcu_add_bss_info(phy, vif, true);699	if (err)700		goto out;701	err = mt7915_mcu_add_sta(dev, vif, NULL, CONN_STATE_PORT_SECURE, false);702out:703	mutex_unlock(&dev->mt76.mutex);704 705	return err;706}707 708static void709mt7915_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif,710	       struct ieee80211_bss_conf *link_conf)711{712	struct mt7915_dev *dev = mt7915_hw_dev(hw);713 714	mutex_lock(&dev->mt76.mutex);715	mt7915_mcu_add_sta(dev, vif, NULL, CONN_STATE_DISCONNECT, false);716	mutex_unlock(&dev->mt76.mutex);717}718 719static void720mt7915_channel_switch_beacon(struct ieee80211_hw *hw,721			     struct ieee80211_vif *vif,722			     struct cfg80211_chan_def *chandef)723{724	struct mt7915_dev *dev = mt7915_hw_dev(hw);725 726	mutex_lock(&dev->mt76.mutex);727	mt7915_mcu_add_beacon(hw, vif, true, BSS_CHANGED_BEACON);728	mutex_unlock(&dev->mt76.mutex);729}730 731int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,732		       struct ieee80211_sta *sta)733{734	struct mt7915_dev *dev = container_of(mdev, struct mt7915_dev, mt76);735	struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;736	struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;737	bool ext_phy = mvif->phy != &dev->phy;738	int idx;739 740	idx = mt76_wcid_alloc(dev->mt76.wcid_mask, MT7915_WTBL_STA);741	if (idx < 0)742		return -ENOSPC;743 744	INIT_LIST_HEAD(&msta->rc_list);745	INIT_LIST_HEAD(&msta->wcid.poll_list);746	msta->vif = mvif;747	msta->wcid.sta_disabled = 1;748	msta->wcid.idx = idx;749	msta->wcid.phy_idx = ext_phy;750	msta->jiffies = jiffies;751 752	ewma_avg_signal_init(&msta->avg_ack_signal);753 754	mt7915_mac_wtbl_update(dev, idx,755			       MT_WTBL_UPDATE_ADM_COUNT_CLEAR);756	mt7915_mcu_add_sta(dev, vif, sta, CONN_STATE_DISCONNECT, true);757 758	return 0;759}760 761int mt7915_mac_sta_event(struct mt76_dev *mdev, struct ieee80211_vif *vif,762			 struct ieee80211_sta *sta, enum mt76_sta_event ev)763{764	struct mt7915_dev *dev = container_of(mdev, struct mt7915_dev, mt76);765	struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;766	int i, ret;767	u32 addr;768 769	switch (ev) {770	case MT76_STA_EVENT_ASSOC:771		ret = mt7915_mcu_add_sta(dev, vif, sta, CONN_STATE_CONNECT, true);772		if (ret)773			return ret;774 775		addr = mt7915_mac_wtbl_lmac_addr(dev, msta->wcid.idx, 30);776		mt76_rmw_field(dev, addr, GENMASK(7, 0), 0xa0);777 778		ret = mt7915_mcu_add_rate_ctrl(dev, vif, sta, false);779		if (ret)780			return ret;781 782		msta->wcid.tx_info |= MT_WCID_TX_INFO_SET;783		msta->wcid.sta = 1;784		msta->wcid.sta_disabled = 0;785 786		return 0;787 788	case MT76_STA_EVENT_AUTHORIZE:789		return mt7915_mcu_add_sta(dev, vif, sta, CONN_STATE_PORT_SECURE, false);790 791	case MT76_STA_EVENT_DISASSOC:792		for (i = 0; i < ARRAY_SIZE(msta->twt.flow); i++)793			mt7915_mac_twt_teardown_flow(dev, msta, i);794 795		mt7915_mcu_add_sta(dev, vif, sta, CONN_STATE_DISCONNECT, false);796		msta->wcid.sta_disabled = 1;797		msta->wcid.sta = 0;798		return 0;799	}800 801	return 0;802}803 804void mt7915_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,805			   struct ieee80211_sta *sta)806{807	struct mt7915_dev *dev = container_of(mdev, struct mt7915_dev, mt76);808	struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;809 810	mt7915_mac_wtbl_update(dev, msta->wcid.idx,811			       MT_WTBL_UPDATE_ADM_COUNT_CLEAR);812 813	spin_lock_bh(&mdev->sta_poll_lock);814	if (!list_empty(&msta->wcid.poll_list))815		list_del_init(&msta->wcid.poll_list);816	if (!list_empty(&msta->rc_list))817		list_del_init(&msta->rc_list);818	spin_unlock_bh(&mdev->sta_poll_lock);819}820 821static void mt7915_tx(struct ieee80211_hw *hw,822		      struct ieee80211_tx_control *control,823		      struct sk_buff *skb)824{825	struct mt7915_dev *dev = mt7915_hw_dev(hw);826	struct mt76_phy *mphy = hw->priv;827	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);828	struct ieee80211_vif *vif = info->control.vif;829	struct mt76_wcid *wcid = &dev->mt76.global_wcid;830 831	if (control->sta) {832		struct mt7915_sta *sta;833 834		sta = (struct mt7915_sta *)control->sta->drv_priv;835		wcid = &sta->wcid;836	}837 838	if (vif && !control->sta) {839		struct mt7915_vif *mvif;840 841		mvif = (struct mt7915_vif *)vif->drv_priv;842		wcid = &mvif->sta.wcid;843	}844 845	mt76_tx(mphy, control->sta, wcid, skb);846}847 848static int mt7915_set_rts_threshold(struct ieee80211_hw *hw, u32 val)849{850	struct mt7915_dev *dev = mt7915_hw_dev(hw);851	struct mt7915_phy *phy = mt7915_hw_phy(hw);852	int ret;853 854	mutex_lock(&dev->mt76.mutex);855	ret = mt76_connac_mcu_set_rts_thresh(&dev->mt76, val,856					     phy->mt76->band_idx);857	mutex_unlock(&dev->mt76.mutex);858 859	return ret;860}861 862static int863mt7915_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,864		    struct ieee80211_ampdu_params *params)865{866	enum ieee80211_ampdu_mlme_action action = params->action;867	struct mt7915_dev *dev = mt7915_hw_dev(hw);868	struct ieee80211_sta *sta = params->sta;869	struct ieee80211_txq *txq = sta->txq[params->tid];870	struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;871	u16 tid = params->tid;872	u16 ssn = params->ssn;873	struct mt76_txq *mtxq;874	int ret = 0;875 876	if (!txq)877		return -EINVAL;878 879	mtxq = (struct mt76_txq *)txq->drv_priv;880 881	mutex_lock(&dev->mt76.mutex);882	switch (action) {883	case IEEE80211_AMPDU_RX_START:884		mt76_rx_aggr_start(&dev->mt76, &msta->wcid, tid, ssn,885				   params->buf_size);886		ret = mt7915_mcu_add_rx_ba(dev, params, true);887		break;888	case IEEE80211_AMPDU_RX_STOP:889		mt76_rx_aggr_stop(&dev->mt76, &msta->wcid, tid);890		ret = mt7915_mcu_add_rx_ba(dev, params, false);891		break;892	case IEEE80211_AMPDU_TX_OPERATIONAL:893		mtxq->aggr = true;894		mtxq->send_bar = false;895		ret = mt7915_mcu_add_tx_ba(dev, params, true);896		break;897	case IEEE80211_AMPDU_TX_STOP_FLUSH:898	case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:899		mtxq->aggr = false;900		clear_bit(tid, &msta->wcid.ampdu_state);901		ret = mt7915_mcu_add_tx_ba(dev, params, false);902		break;903	case IEEE80211_AMPDU_TX_START:904		set_bit(tid, &msta->wcid.ampdu_state);905		ret = IEEE80211_AMPDU_TX_START_IMMEDIATE;906		break;907	case IEEE80211_AMPDU_TX_STOP_CONT:908		mtxq->aggr = false;909		clear_bit(tid, &msta->wcid.ampdu_state);910		ret = mt7915_mcu_add_tx_ba(dev, params, false);911		ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);912		break;913	}914	mutex_unlock(&dev->mt76.mutex);915 916	return ret;917}918 919static int920mt7915_get_stats(struct ieee80211_hw *hw,921		 struct ieee80211_low_level_stats *stats)922{923	struct mt7915_phy *phy = mt7915_hw_phy(hw);924	struct mt7915_dev *dev = mt7915_hw_dev(hw);925	struct mt76_mib_stats *mib = &phy->mib;926 927	mutex_lock(&dev->mt76.mutex);928 929	stats->dot11RTSSuccessCount = mib->rts_cnt;930	stats->dot11RTSFailureCount = mib->rts_retries_cnt;931	stats->dot11FCSErrorCount = mib->fcs_err_cnt;932	stats->dot11ACKFailureCount = mib->ack_fail_cnt;933 934	mutex_unlock(&dev->mt76.mutex);935 936	return 0;937}938 939u64 __mt7915_get_tsf(struct ieee80211_hw *hw, struct mt7915_vif *mvif)940{941	struct mt7915_dev *dev = mt7915_hw_dev(hw);942	struct mt7915_phy *phy = mt7915_hw_phy(hw);943	bool band = phy->mt76->band_idx;944	union {945		u64 t64;946		u32 t32[2];947	} tsf;948	u16 n;949 950	lockdep_assert_held(&dev->mt76.mutex);951 952	n = mvif->mt76.omac_idx > HW_BSSID_MAX ? HW_BSSID_0953					       : mvif->mt76.omac_idx;954	/* TSF software read */955	if (is_mt7915(&dev->mt76))956		mt76_rmw(dev, MT_LPON_TCR(band, n), MT_LPON_TCR_SW_MODE,957			 MT_LPON_TCR_SW_READ);958	else959		mt76_rmw(dev, MT_LPON_TCR_MT7916(band, n), MT_LPON_TCR_SW_MODE,960			 MT_LPON_TCR_SW_READ);961	tsf.t32[0] = mt76_rr(dev, MT_LPON_UTTR0(band));962	tsf.t32[1] = mt76_rr(dev, MT_LPON_UTTR1(band));963 964	return tsf.t64;965}966 967static u64968mt7915_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)969{970	struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;971	struct mt7915_dev *dev = mt7915_hw_dev(hw);972	u64 ret;973 974	mutex_lock(&dev->mt76.mutex);975	ret = __mt7915_get_tsf(hw, mvif);976	mutex_unlock(&dev->mt76.mutex);977 978	return ret;979}980 981static void982mt7915_set_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif,983	       u64 timestamp)984{985	struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;986	struct mt7915_dev *dev = mt7915_hw_dev(hw);987	struct mt7915_phy *phy = mt7915_hw_phy(hw);988	bool band = phy->mt76->band_idx;989	union {990		u64 t64;991		u32 t32[2];992	} tsf = { .t64 = timestamp, };993	u16 n;994 995	mutex_lock(&dev->mt76.mutex);996 997	n = mvif->mt76.omac_idx > HW_BSSID_MAX ? HW_BSSID_0998					       : mvif->mt76.omac_idx;999	mt76_wr(dev, MT_LPON_UTTR0(band), tsf.t32[0]);1000	mt76_wr(dev, MT_LPON_UTTR1(band), tsf.t32[1]);1001	/* TSF software overwrite */1002	if (is_mt7915(&dev->mt76))1003		mt76_rmw(dev, MT_LPON_TCR(band, n), MT_LPON_TCR_SW_MODE,1004			 MT_LPON_TCR_SW_WRITE);1005	else1006		mt76_rmw(dev, MT_LPON_TCR_MT7916(band, n), MT_LPON_TCR_SW_MODE,1007			 MT_LPON_TCR_SW_WRITE);1008 1009	mutex_unlock(&dev->mt76.mutex);1010}1011 1012static void1013mt7915_offset_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif,1014		  s64 timestamp)1015{1016	struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;1017	struct mt7915_dev *dev = mt7915_hw_dev(hw);1018	struct mt7915_phy *phy = mt7915_hw_phy(hw);1019	bool band = phy->mt76->band_idx;1020	union {1021		u64 t64;1022		u32 t32[2];1023	} tsf = { .t64 = timestamp, };1024	u16 n;1025 1026	mutex_lock(&dev->mt76.mutex);1027 1028	n = mvif->mt76.omac_idx > HW_BSSID_MAX ? HW_BSSID_01029					       : mvif->mt76.omac_idx;1030	mt76_wr(dev, MT_LPON_UTTR0(band), tsf.t32[0]);1031	mt76_wr(dev, MT_LPON_UTTR1(band), tsf.t32[1]);1032	/* TSF software adjust*/1033	if (is_mt7915(&dev->mt76))1034		mt76_rmw(dev, MT_LPON_TCR(band, n), MT_LPON_TCR_SW_MODE,1035			 MT_LPON_TCR_SW_ADJUST);1036	else1037		mt76_rmw(dev, MT_LPON_TCR_MT7916(band, n), MT_LPON_TCR_SW_MODE,1038			 MT_LPON_TCR_SW_ADJUST);1039 1040	mutex_unlock(&dev->mt76.mutex);1041}1042 1043static void1044mt7915_set_coverage_class(struct ieee80211_hw *hw, s16 coverage_class)1045{1046	struct mt7915_phy *phy = mt7915_hw_phy(hw);1047	struct mt7915_dev *dev = phy->dev;1048 1049	mutex_lock(&dev->mt76.mutex);1050	phy->coverage_class = max_t(s16, coverage_class, 0);1051	mt7915_mac_set_timing(phy);1052	mutex_unlock(&dev->mt76.mutex);1053}1054 1055static int1056mt7915_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)1057{1058	struct mt7915_dev *dev = mt7915_hw_dev(hw);1059	struct mt7915_phy *phy = mt7915_hw_phy(hw);1060	int max_nss = hweight8(hw->wiphy->available_antennas_tx);1061	u8 chainshift = dev->chainshift;1062	u8 band = phy->mt76->band_idx;1063 1064	if (!tx_ant || tx_ant != rx_ant || ffs(tx_ant) > max_nss)1065		return -EINVAL;1066 1067	mutex_lock(&dev->mt76.mutex);1068 1069	phy->mt76->antenna_mask = tx_ant;1070 1071	/* handle a variant of mt7916/mt7981 which has 3T3R but nss2 on 5 GHz band */1072	if ((is_mt7916(&dev->mt76) || is_mt7981(&dev->mt76)) &&1073	    band && hweight8(tx_ant) == max_nss)1074		phy->mt76->chainmask = (dev->chainmask >> chainshift) << chainshift;1075	else1076		phy->mt76->chainmask = tx_ant << (chainshift * band);1077 1078	mt76_set_stream_caps(phy->mt76, true);1079	mt7915_set_stream_vht_txbf_caps(phy);1080	mt7915_set_stream_he_caps(phy);1081 1082	mutex_unlock(&dev->mt76.mutex);1083 1084	return 0;1085}1086 1087static void mt7915_sta_statistics(struct ieee80211_hw *hw,1088				  struct ieee80211_vif *vif,1089				  struct ieee80211_sta *sta,1090				  struct station_info *sinfo)1091{1092	struct mt7915_phy *phy = mt7915_hw_phy(hw);1093	struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;1094	struct rate_info *txrate = &msta->wcid.rate;1095	struct rate_info rxrate = {};1096 1097	if (!mt7915_mcu_get_rx_rate(phy, vif, sta, &rxrate)) {1098		sinfo->rxrate = rxrate;1099		sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_BITRATE);1100	}1101 1102	if (txrate->legacy || txrate->flags) {1103		if (txrate->legacy) {1104			sinfo->txrate.legacy = txrate->legacy;1105		} else {1106			sinfo->txrate.mcs = txrate->mcs;1107			sinfo->txrate.nss = txrate->nss;1108			sinfo->txrate.bw = txrate->bw;1109			sinfo->txrate.he_gi = txrate->he_gi;1110			sinfo->txrate.he_dcm = txrate->he_dcm;1111			sinfo->txrate.he_ru_alloc = txrate->he_ru_alloc;1112		}1113		sinfo->txrate.flags = txrate->flags;1114		sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);1115	}1116 1117	/* offloading flows bypass networking stack, so driver counts and1118	 * reports sta statistics via NL80211_STA_INFO when WED is active.1119	 */1120	if (mtk_wed_device_active(&phy->dev->mt76.mmio.wed)) {1121		sinfo->tx_bytes = msta->wcid.stats.tx_bytes;1122		sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BYTES64);1123 1124		if (!mt7915_mcu_wed_wa_tx_stats(phy->dev, msta->wcid.idx)) {1125			sinfo->tx_packets = msta->wcid.stats.tx_packets;1126			sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_PACKETS);1127		}1128 1129		if (mtk_wed_get_rx_capa(&phy->dev->mt76.mmio.wed)) {1130			sinfo->rx_bytes = msta->wcid.stats.rx_bytes;1131			sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_BYTES64);1132 1133			sinfo->rx_packets = msta->wcid.stats.rx_packets;1134			sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_PACKETS);1135		}1136	}1137 1138	sinfo->tx_failed = msta->wcid.stats.tx_failed;1139	sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED);1140 1141	sinfo->tx_retries = msta->wcid.stats.tx_retries;1142	sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_RETRIES);1143 1144	sinfo->ack_signal = (s8)msta->ack_signal;1145	sinfo->filled |= BIT_ULL(NL80211_STA_INFO_ACK_SIGNAL);1146 1147	sinfo->avg_ack_signal = -(s8)ewma_avg_signal_read(&msta->avg_ack_signal);1148	sinfo->filled |= BIT_ULL(NL80211_STA_INFO_ACK_SIGNAL_AVG);1149}1150 1151static void mt7915_sta_rc_work(void *data, struct ieee80211_sta *sta)1152{1153	struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;1154	struct mt7915_dev *dev = msta->vif->phy->dev;1155	u32 *changed = data;1156 1157	spin_lock_bh(&dev->mt76.sta_poll_lock);1158	msta->changed |= *changed;1159	if (list_empty(&msta->rc_list))1160		list_add_tail(&msta->rc_list, &dev->sta_rc_list);1161	spin_unlock_bh(&dev->mt76.sta_poll_lock);1162}1163 1164static void mt7915_sta_rc_update(struct ieee80211_hw *hw,1165				 struct ieee80211_vif *vif,1166				 struct ieee80211_sta *sta,1167				 u32 changed)1168{1169	struct mt7915_phy *phy = mt7915_hw_phy(hw);1170	struct mt7915_dev *dev = phy->dev;1171	struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;1172 1173	if (!msta->wcid.sta)1174		return;1175 1176	mt7915_sta_rc_work(&changed, sta);1177	ieee80211_queue_work(hw, &dev->rc_work);1178}1179 1180static int1181mt7915_set_bitrate_mask(struct ieee80211_hw *hw, struct ieee80211_vif *vif,1182			const struct cfg80211_bitrate_mask *mask)1183{1184	struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;1185	struct mt7915_phy *phy = mt7915_hw_phy(hw);1186	struct mt7915_dev *dev = phy->dev;1187	u32 changed = IEEE80211_RC_SUPP_RATES_CHANGED;1188 1189	mvif->bitrate_mask = *mask;1190 1191	/* if multiple rates across different preambles are given we can1192	 * reconfigure this info with all peers using sta_rec command with1193	 * the below exception cases.1194	 * - single rate : if a rate is passed along with different preambles,1195	 * we select the highest one as fixed rate. i.e VHT MCS for VHT peers.1196	 * - multiple rates: if it's not in range format i.e 0-{7,8,9} for VHT1197	 * then multiple MCS setting (MCS 4,5,6) is not supported.1198	 */1199	ieee80211_iterate_stations_atomic(hw, mt7915_sta_rc_work, &changed);1200	ieee80211_queue_work(hw, &dev->rc_work);1201 1202	return 0;1203}1204 1205static void mt7915_sta_set_4addr(struct ieee80211_hw *hw,1206				 struct ieee80211_vif *vif,1207				 struct ieee80211_sta *sta,1208				 bool enabled)1209{1210	struct mt7915_dev *dev = mt7915_hw_dev(hw);1211	struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;1212 1213	if (enabled)1214		set_bit(MT_WCID_FLAG_4ADDR, &msta->wcid.flags);1215	else1216		clear_bit(MT_WCID_FLAG_4ADDR, &msta->wcid.flags);1217 1218	if (!msta->wcid.sta)1219		return;1220 1221	mt76_connac_mcu_wtbl_update_hdr_trans(&dev->mt76, vif, sta);1222}1223 1224static void mt7915_sta_set_decap_offload(struct ieee80211_hw *hw,1225				 struct ieee80211_vif *vif,1226				 struct ieee80211_sta *sta,1227				 bool enabled)1228{1229	struct mt7915_dev *dev = mt7915_hw_dev(hw);1230	struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;1231 1232	if (enabled)1233		set_bit(MT_WCID_FLAG_HDR_TRANS, &msta->wcid.flags);1234	else1235		clear_bit(MT_WCID_FLAG_HDR_TRANS, &msta->wcid.flags);1236 1237	if (!msta->wcid.sta)1238		return;1239 1240	mt76_connac_mcu_wtbl_update_hdr_trans(&dev->mt76, vif, sta);1241}1242 1243static int mt7915_sta_set_txpwr(struct ieee80211_hw *hw,1244				struct ieee80211_vif *vif,1245				struct ieee80211_sta *sta)1246{1247	struct mt7915_phy *phy = mt7915_hw_phy(hw);1248	struct mt7915_dev *dev = mt7915_hw_dev(hw);1249	s16 txpower = sta->deflink.txpwr.power;1250	int ret;1251 1252	if (sta->deflink.txpwr.type == NL80211_TX_POWER_AUTOMATIC)1253		txpower = 0;1254 1255	mutex_lock(&dev->mt76.mutex);1256 1257	/* NOTE: temporarily use 0 as minimum limit, which is a1258	 * global setting and will be applied to all stations.1259	 */1260	ret = mt7915_mcu_set_txpower_frame_min(phy, 0);1261	if (ret)1262		goto out;1263 1264	/* This only applies to data frames while pushing traffic,1265	 * whereas the management frames or other packets that are1266	 * using fixed rate can be configured via TxD.1267	 */1268	ret = mt7915_mcu_set_txpower_frame(phy, vif, sta, txpower);1269 1270out:1271	mutex_unlock(&dev->mt76.mutex);1272 1273	return ret;1274}1275 1276static const char mt7915_gstrings_stats[][ETH_GSTRING_LEN] = {1277	"tx_ampdu_cnt",1278	"tx_stop_q_empty_cnt",1279	"tx_mpdu_attempts",1280	"tx_mpdu_success",1281	"tx_rwp_fail_cnt",1282	"tx_rwp_need_cnt",1283	"tx_pkt_ebf_cnt",1284	"tx_pkt_ibf_cnt",1285	"tx_ampdu_len:0-1",1286	"tx_ampdu_len:2-10",1287	"tx_ampdu_len:11-19",1288	"tx_ampdu_len:20-28",1289	"tx_ampdu_len:29-37",1290	"tx_ampdu_len:38-46",1291	"tx_ampdu_len:47-55",1292	"tx_ampdu_len:56-79",1293	"tx_ampdu_len:80-103",1294	"tx_ampdu_len:104-127",1295	"tx_ampdu_len:128-151",1296	"tx_ampdu_len:152-175",1297	"tx_ampdu_len:176-199",1298	"tx_ampdu_len:200-223",1299	"tx_ampdu_len:224-247",1300	"ba_miss_count",1301	"tx_beamformer_ppdu_iBF",1302	"tx_beamformer_ppdu_eBF",1303	"tx_beamformer_rx_feedback_all",1304	"tx_beamformer_rx_feedback_he",1305	"tx_beamformer_rx_feedback_vht",1306	"tx_beamformer_rx_feedback_ht",1307	"tx_beamformer_rx_feedback_bw", /* zero based idx: 20, 40, 80, 160 */1308	"tx_beamformer_rx_feedback_nc",1309	"tx_beamformer_rx_feedback_nr",1310	"tx_beamformee_ok_feedback_pkts",1311	"tx_beamformee_feedback_trig",1312	"tx_mu_beamforming",1313	"tx_mu_mpdu",1314	"tx_mu_successful_mpdu",1315	"tx_su_successful_mpdu",1316	"tx_msdu_pack_1",1317	"tx_msdu_pack_2",1318	"tx_msdu_pack_3",1319	"tx_msdu_pack_4",1320	"tx_msdu_pack_5",1321	"tx_msdu_pack_6",1322	"tx_msdu_pack_7",1323	"tx_msdu_pack_8",1324 1325	/* rx counters */1326	"rx_fifo_full_cnt",1327	"rx_mpdu_cnt",1328	"channel_idle_cnt",1329	"primary_cca_busy_time",1330	"secondary_cca_busy_time",1331	"primary_energy_detect_time",1332	"cck_mdrdy_time",1333	"ofdm_mdrdy_time",1334	"green_mdrdy_time",1335	"rx_vector_mismatch_cnt",1336	"rx_delimiter_fail_cnt",1337	"rx_mrdy_cnt",1338	"rx_len_mismatch_cnt",1339	"rx_ampdu_cnt",1340	"rx_ampdu_bytes_cnt",1341	"rx_ampdu_valid_subframe_cnt",1342	"rx_ampdu_valid_subframe_b_cnt",1343	"rx_pfdrop_cnt",1344	"rx_vec_queue_overflow_drop_cnt",1345	"rx_ba_cnt",1346 1347	/* muru mu-mimo and ofdma related stats */1348	"dl_cck_cnt",1349	"dl_ofdm_cnt",1350	"dl_htmix_cnt",1351	"dl_htgf_cnt",1352	"dl_vht_su_cnt",1353	"dl_vht_2mu_cnt",1354	"dl_vht_3mu_cnt",1355	"dl_vht_4mu_cnt",1356	"dl_he_su_cnt",1357	"dl_he_ext_su_cnt",1358	"dl_he_2ru_cnt",1359	"dl_he_2mu_cnt",1360	"dl_he_3ru_cnt",1361	"dl_he_3mu_cnt",1362	"dl_he_4ru_cnt",1363	"dl_he_4mu_cnt",1364	"dl_he_5to8ru_cnt",1365	"dl_he_9to16ru_cnt",1366	"dl_he_gtr16ru_cnt",1367 1368	"ul_hetrig_su_cnt",1369	"ul_hetrig_2ru_cnt",1370	"ul_hetrig_3ru_cnt",1371	"ul_hetrig_4ru_cnt",1372	"ul_hetrig_5to8ru_cnt",1373	"ul_hetrig_9to16ru_cnt",1374	"ul_hetrig_gtr16ru_cnt",1375	"ul_hetrig_2mu_cnt",1376	"ul_hetrig_3mu_cnt",1377	"ul_hetrig_4mu_cnt",1378 1379	/* per vif counters */1380	"v_tx_mode_cck",1381	"v_tx_mode_ofdm",1382	"v_tx_mode_ht",1383	"v_tx_mode_ht_gf",1384	"v_tx_mode_vht",1385	"v_tx_mode_he_su",1386	"v_tx_mode_he_ext_su",1387	"v_tx_mode_he_tb",1388	"v_tx_mode_he_mu",1389	"v_tx_bw_20",1390	"v_tx_bw_40",1391	"v_tx_bw_80",1392	"v_tx_bw_160",1393	"v_tx_mcs_0",1394	"v_tx_mcs_1",1395	"v_tx_mcs_2",1396	"v_tx_mcs_3",1397	"v_tx_mcs_4",1398	"v_tx_mcs_5",1399	"v_tx_mcs_6",1400	"v_tx_mcs_7",1401	"v_tx_mcs_8",1402	"v_tx_mcs_9",1403	"v_tx_mcs_10",1404	"v_tx_mcs_11",1405	"v_tx_nss_1",1406	"v_tx_nss_2",1407	"v_tx_nss_3",1408	"v_tx_nss_4",1409};1410 1411#define MT7915_SSTATS_LEN ARRAY_SIZE(mt7915_gstrings_stats)1412 1413/* Ethtool related API */1414static1415void mt7915_get_et_strings(struct ieee80211_hw *hw,1416			   struct ieee80211_vif *vif,1417			   u32 sset, u8 *data)1418{1419	if (sset != ETH_SS_STATS)1420		return;1421 1422	memcpy(data, mt7915_gstrings_stats, sizeof(mt7915_gstrings_stats));1423	data += sizeof(mt7915_gstrings_stats);1424	page_pool_ethtool_stats_get_strings(data);1425}1426 1427static1428int mt7915_get_et_sset_count(struct ieee80211_hw *hw,1429			     struct ieee80211_vif *vif, int sset)1430{1431	if (sset != ETH_SS_STATS)1432		return 0;1433 1434	return MT7915_SSTATS_LEN + page_pool_ethtool_stats_get_count();1435}1436 1437static void mt7915_ethtool_worker(void *wi_data, struct ieee80211_sta *sta)1438{1439	struct mt76_ethtool_worker_info *wi = wi_data;1440	struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;1441 1442	if (msta->vif->mt76.idx != wi->idx)1443		return;1444 1445	mt76_ethtool_worker(wi, &msta->wcid.stats, false);1446}1447 1448static1449void mt7915_get_et_stats(struct ieee80211_hw *hw,1450			 struct ieee80211_vif *vif,1451			 struct ethtool_stats *stats, u64 *data)1452{1453	struct mt7915_dev *dev = mt7915_hw_dev(hw);1454	struct mt7915_phy *phy = mt7915_hw_phy(hw);1455	struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;1456	struct mt76_mib_stats *mib = &phy->mib;1457	struct mt76_ethtool_worker_info wi = {1458		.data = data,1459		.idx = mvif->mt76.idx,1460	};1461	/* See mt7915_ampdu_stat_read_phy, etc */1462	int i, ei = 0, stats_size;1463 1464	mutex_lock(&dev->mt76.mutex);1465 1466	mt7915_mac_update_stats(phy);1467 1468	data[ei++] = mib->tx_ampdu_cnt;1469	data[ei++] = mib->tx_stop_q_empty_cnt;1470	data[ei++] = mib->tx_mpdu_attempts_cnt;1471	data[ei++] = mib->tx_mpdu_success_cnt;1472	data[ei++] = mib->tx_rwp_fail_cnt;1473	data[ei++] = mib->tx_rwp_need_cnt;1474	data[ei++] = mib->tx_pkt_ebf_cnt;1475	data[ei++] = mib->tx_pkt_ibf_cnt;1476 1477	/* Tx ampdu stat */1478	for (i = 0; i < 15 /*ARRAY_SIZE(bound)*/; i++)1479		data[ei++] = phy->mt76->aggr_stats[i];1480 1481	data[ei++] = phy->mib.ba_miss_cnt;1482 1483	/* Tx Beamformer monitor */1484	data[ei++] = mib->tx_bf_ibf_ppdu_cnt;1485	data[ei++] = mib->tx_bf_ebf_ppdu_cnt;1486 1487	/* Tx Beamformer Rx feedback monitor */1488	data[ei++] = mib->tx_bf_rx_fb_all_cnt;1489	data[ei++] = mib->tx_bf_rx_fb_he_cnt;1490	data[ei++] = mib->tx_bf_rx_fb_vht_cnt;1491	data[ei++] = mib->tx_bf_rx_fb_ht_cnt;1492 1493	data[ei++] = mib->tx_bf_rx_fb_bw;1494	data[ei++] = mib->tx_bf_rx_fb_nc_cnt;1495	data[ei++] = mib->tx_bf_rx_fb_nr_cnt;1496 1497	/* Tx Beamformee Rx NDPA & Tx feedback report */1498	data[ei++] = mib->tx_bf_fb_cpl_cnt;1499	data[ei++] = mib->tx_bf_fb_trig_cnt;1500 1501	/* Tx SU & MU counters */1502	data[ei++] = mib->tx_bf_cnt;1503	data[ei++] = mib->tx_mu_mpdu_cnt;1504	data[ei++] = mib->tx_mu_acked_mpdu_cnt;1505	data[ei++] = mib->tx_su_acked_mpdu_cnt;1506 1507	/* Tx amsdu info (pack-count histogram) */1508	for (i = 0; i < ARRAY_SIZE(mib->tx_amsdu); i++)1509		data[ei++] = mib->tx_amsdu[i];1510 1511	/* rx counters */1512	data[ei++] = mib->rx_fifo_full_cnt;1513	data[ei++] = mib->rx_mpdu_cnt;1514	data[ei++] = mib->channel_idle_cnt;1515	data[ei++] = mib->primary_cca_busy_time;1516	data[ei++] = mib->secondary_cca_busy_time;1517	data[ei++] = mib->primary_energy_detect_time;1518	data[ei++] = mib->cck_mdrdy_time;1519	data[ei++] = mib->ofdm_mdrdy_time;1520	data[ei++] = mib->green_mdrdy_time;1521	data[ei++] = mib->rx_vector_mismatch_cnt;1522	data[ei++] = mib->rx_delimiter_fail_cnt;1523	data[ei++] = mib->rx_mrdy_cnt;1524	data[ei++] = mib->rx_len_mismatch_cnt;1525	data[ei++] = mib->rx_ampdu_cnt;1526	data[ei++] = mib->rx_ampdu_bytes_cnt;1527	data[ei++] = mib->rx_ampdu_valid_subframe_cnt;1528	data[ei++] = mib->rx_ampdu_valid_subframe_bytes_cnt;1529	data[ei++] = mib->rx_pfdrop_cnt;1530	data[ei++] = mib->rx_vec_queue_overflow_drop_cnt;1531	data[ei++] = mib->rx_ba_cnt;1532 1533	data[ei++] = mib->dl_cck_cnt;1534	data[ei++] = mib->dl_ofdm_cnt;1535	data[ei++] = mib->dl_htmix_cnt;1536	data[ei++] = mib->dl_htgf_cnt;1537	data[ei++] = mib->dl_vht_su_cnt;1538	data[ei++] = mib->dl_vht_2mu_cnt;1539	data[ei++] = mib->dl_vht_3mu_cnt;1540	data[ei++] = mib->dl_vht_4mu_cnt;1541	data[ei++] = mib->dl_he_su_cnt;1542	data[ei++] = mib->dl_he_ext_su_cnt;1543	data[ei++] = mib->dl_he_2ru_cnt;1544	data[ei++] = mib->dl_he_2mu_cnt;1545	data[ei++] = mib->dl_he_3ru_cnt;1546	data[ei++] = mib->dl_he_3mu_cnt;1547	data[ei++] = mib->dl_he_4ru_cnt;1548	data[ei++] = mib->dl_he_4mu_cnt;1549	data[ei++] = mib->dl_he_5to8ru_cnt;1550	data[ei++] = mib->dl_he_9to16ru_cnt;1551	data[ei++] = mib->dl_he_gtr16ru_cnt;1552 1553	data[ei++] = mib->ul_hetrig_su_cnt;1554	data[ei++] = mib->ul_hetrig_2ru_cnt;1555	data[ei++] = mib->ul_hetrig_3ru_cnt;1556	data[ei++] = mib->ul_hetrig_4ru_cnt;1557	data[ei++] = mib->ul_hetrig_5to8ru_cnt;1558	data[ei++] = mib->ul_hetrig_9to16ru_cnt;1559	data[ei++] = mib->ul_hetrig_gtr16ru_cnt;1560	data[ei++] = mib->ul_hetrig_2mu_cnt;1561	data[ei++] = mib->ul_hetrig_3mu_cnt;1562	data[ei++] = mib->ul_hetrig_4mu_cnt;1563 1564	/* Add values for all stations owned by this vif */1565	wi.initial_stat_idx = ei;1566	ieee80211_iterate_stations_atomic(hw, mt7915_ethtool_worker, &wi);1567 1568	mutex_unlock(&dev->mt76.mutex);1569 1570	if (wi.sta_count == 0)1571		return;1572 1573	ei += wi.worker_stat_count;1574 1575	mt76_ethtool_page_pool_stats(&dev->mt76, &data[ei], &ei);1576 1577	stats_size = MT7915_SSTATS_LEN + page_pool_ethtool_stats_get_count();1578	if (ei != stats_size)1579		dev_err(dev->mt76.dev, "ei: %d size: %d", ei, stats_size);1580}1581 1582static void1583mt7915_twt_teardown_request(struct ieee80211_hw *hw,1584			    struct ieee80211_sta *sta,1585			    u8 flowid)1586{1587	struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;1588	struct mt7915_dev *dev = mt7915_hw_dev(hw);1589 1590	mutex_lock(&dev->mt76.mutex);1591	mt7915_mac_twt_teardown_flow(dev, msta, flowid);1592	mutex_unlock(&dev->mt76.mutex);1593}1594 1595static int1596mt7915_set_frag_threshold(struct ieee80211_hw *hw, u32 val)1597{1598	return 0;1599}1600 1601static int1602mt7915_set_radar_background(struct ieee80211_hw *hw,1603			    struct cfg80211_chan_def *chandef)1604{1605	struct mt7915_phy *phy = mt7915_hw_phy(hw);1606	struct mt7915_dev *dev = phy->dev;1607	int ret = -EINVAL;1608	bool running;1609 1610	mutex_lock(&dev->mt76.mutex);1611 1612	if (dev->mt76.region == NL80211_DFS_UNSET)1613		goto out;1614 1615	if (dev->rdd2_phy && dev->rdd2_phy != phy) {1616		/* rdd2 is already locked */1617		ret = -EBUSY;1618		goto out;1619	}1620 1621	/* rdd2 already configured on a radar channel */1622	running = dev->rdd2_phy &&1623		  cfg80211_chandef_valid(&dev->rdd2_chandef) &&1624		  !!(dev->rdd2_chandef.chan->flags & IEEE80211_CHAN_RADAR);1625 1626	if (!chandef || running ||1627	    !(chandef->chan->flags & IEEE80211_CHAN_RADAR)) {1628		ret = mt7915_mcu_rdd_background_enable(phy, NULL);1629		if (ret)1630			goto out;1631 1632		if (!running)1633			goto update_phy;1634	}1635 1636	ret = mt7915_mcu_rdd_background_enable(phy, chandef);1637	if (ret)1638		goto out;1639 1640update_phy:1641	dev->rdd2_phy = chandef ? phy : NULL;1642	if (chandef)1643		dev->rdd2_chandef = *chandef;1644out:1645	mutex_unlock(&dev->mt76.mutex);1646 1647	return ret;1648}1649 1650#ifdef CONFIG_NET_MEDIATEK_SOC_WED1651static int1652mt7915_net_fill_forward_path(struct ieee80211_hw *hw,1653			     struct ieee80211_vif *vif,1654			     struct ieee80211_sta *sta,1655			     struct net_device_path_ctx *ctx,1656			     struct net_device_path *path)1657{1658	struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;1659	struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;1660	struct mt7915_dev *dev = mt7915_hw_dev(hw);1661	struct mt7915_phy *phy = mt7915_hw_phy(hw);1662	struct mtk_wed_device *wed = &dev->mt76.mmio.wed;1663 1664	if (!mtk_wed_device_active(wed))1665		return -ENODEV;1666 1667	if (msta->wcid.idx > 0xff)1668		return -EIO;1669 1670	path->type = DEV_PATH_MTK_WDMA;1671	path->dev = ctx->dev;1672	path->mtk_wdma.wdma_idx = wed->wdma_idx;1673	path->mtk_wdma.bss = mvif->mt76.idx;1674	path->mtk_wdma.wcid = is_mt7915(&dev->mt76) ? msta->wcid.idx : 0x3ff;1675	path->mtk_wdma.queue = phy != &dev->phy;1676 1677	ctx->dev = NULL;1678 1679	return 0;1680}1681#endif1682 1683static void1684mt7915_reconfig_complete(struct ieee80211_hw *hw,1685			 enum ieee80211_reconfig_type reconfig_type)1686{1687	struct mt7915_phy *phy = mt7915_hw_phy(hw);1688 1689	ieee80211_wake_queues(hw);1690	ieee80211_queue_delayed_work(hw, &phy->mt76->mac_work,1691				     MT7915_WATCHDOG_TIME);1692}1693 1694const struct ieee80211_ops mt7915_ops = {1695	.add_chanctx = ieee80211_emulate_add_chanctx,1696	.remove_chanctx = ieee80211_emulate_remove_chanctx,1697	.change_chanctx = ieee80211_emulate_change_chanctx,1698	.switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx,1699	.tx = mt7915_tx,1700	.start = mt7915_start,1701	.stop = mt7915_stop,1702	.add_interface = mt7915_add_interface,1703	.remove_interface = mt7915_remove_interface,1704	.config = mt7915_config,1705	.conf_tx = mt7915_conf_tx,1706	.configure_filter = mt7915_configure_filter,1707	.bss_info_changed = mt7915_bss_info_changed,1708	.start_ap = mt7915_start_ap,1709	.stop_ap = mt7915_stop_ap,1710	.sta_state = mt76_sta_state,1711	.sta_pre_rcu_remove = mt76_sta_pre_rcu_remove,1712	.sta_rc_update = mt7915_sta_rc_update,1713	.set_key = mt7915_set_key,1714	.ampdu_action = mt7915_ampdu_action,1715	.set_rts_threshold = mt7915_set_rts_threshold,1716	.wake_tx_queue = mt76_wake_tx_queue,1717	.sw_scan_start = mt76_sw_scan,1718	.sw_scan_complete = mt76_sw_scan_complete,1719	.release_buffered_frames = mt76_release_buffered_frames,1720	.get_txpower = mt76_get_txpower,1721	.set_sar_specs = mt7915_set_sar_specs,1722	.channel_switch_beacon = mt7915_channel_switch_beacon,1723	.get_stats = mt7915_get_stats,1724	.get_et_sset_count = mt7915_get_et_sset_count,1725	.get_et_stats = mt7915_get_et_stats,1726	.get_et_strings = mt7915_get_et_strings,1727	.get_tsf = mt7915_get_tsf,1728	.set_tsf = mt7915_set_tsf,1729	.offset_tsf = mt7915_offset_tsf,1730	.get_survey = mt76_get_survey,1731	.get_antenna = mt76_get_antenna,1732	.set_antenna = mt7915_set_antenna,1733	.set_bitrate_mask = mt7915_set_bitrate_mask,1734	.set_coverage_class = mt7915_set_coverage_class,1735	.sta_statistics = mt7915_sta_statistics,1736	.sta_set_txpwr = mt7915_sta_set_txpwr,1737	.sta_set_4addr = mt7915_sta_set_4addr,1738	.sta_set_decap_offload = mt7915_sta_set_decap_offload,1739	.add_twt_setup = mt7915_mac_add_twt_setup,1740	.twt_teardown_request = mt7915_twt_teardown_request,1741	.set_frag_threshold = mt7915_set_frag_threshold,1742	CFG80211_TESTMODE_CMD(mt76_testmode_cmd)1743	CFG80211_TESTMODE_DUMP(mt76_testmode_dump)1744#ifdef CONFIG_MAC80211_DEBUGFS1745	.sta_add_debugfs = mt7915_sta_add_debugfs,1746#endif1747	.set_radar_background = mt7915_set_radar_background,1748#ifdef CONFIG_NET_MEDIATEK_SOC_WED1749	.net_fill_forward_path = mt7915_net_fill_forward_path,1750	.net_setup_tc = mt76_wed_net_setup_tc,1751#endif1752	.reconfig_complete = mt7915_reconfig_complete,1753};1754