brintos

brintos / linux-shallow public Read only

0
0
Text · 10.8 KiB · 1062739 Raw
388 lines · c
1// SPDX-License-Identifier: ISC2/* Copyright (C) 2023 MediaTek Inc. */3 4#include <linux/module.h>5 6#include "mt792x.h"7#include "mt792x_regs.h"8 9void mt792x_mac_work(struct work_struct *work)10{11	struct mt792x_phy *phy;12	struct mt76_phy *mphy;13 14	mphy = (struct mt76_phy *)container_of(work, struct mt76_phy,15					       mac_work.work);16	phy = mphy->priv;17 18	mt792x_mutex_acquire(phy->dev);19 20	mt76_update_survey(mphy);21	if (++mphy->mac_work_count == 2) {22		mphy->mac_work_count = 0;23 24		mt792x_mac_update_mib_stats(phy);25	}26 27	mt792x_mutex_release(phy->dev);28 29	mt76_tx_status_check(mphy->dev, false);30	ieee80211_queue_delayed_work(phy->mt76->hw, &mphy->mac_work,31				     MT792x_WATCHDOG_TIME);32}33EXPORT_SYMBOL_GPL(mt792x_mac_work);34 35void mt792x_mac_set_timeing(struct mt792x_phy *phy)36{37	s16 coverage_class = phy->coverage_class;38	struct mt792x_dev *dev = phy->dev;39	u32 val, reg_offset;40	u32 cck = FIELD_PREP(MT_TIMEOUT_VAL_PLCP, 231) |41		  FIELD_PREP(MT_TIMEOUT_VAL_CCA, 48);42	u32 ofdm = FIELD_PREP(MT_TIMEOUT_VAL_PLCP, 60) |43		   FIELD_PREP(MT_TIMEOUT_VAL_CCA, 28);44	bool is_2ghz = phy->mt76->chandef.chan->band == NL80211_BAND_2GHZ;45	int sifs = is_2ghz ? 10 : 16, offset;46 47	if (!test_bit(MT76_STATE_RUNNING, &phy->mt76->state))48		return;49 50	mt76_set(dev, MT_ARB_SCR(0),51		 MT_ARB_SCR_TX_DISABLE | MT_ARB_SCR_RX_DISABLE);52	udelay(1);53 54	offset = 3 * coverage_class;55	reg_offset = FIELD_PREP(MT_TIMEOUT_VAL_PLCP, offset) |56		     FIELD_PREP(MT_TIMEOUT_VAL_CCA, offset);57 58	mt76_wr(dev, MT_TMAC_CDTR(0), cck + reg_offset);59	mt76_wr(dev, MT_TMAC_ODTR(0), ofdm + reg_offset);60	mt76_wr(dev, MT_TMAC_ICR0(0),61		FIELD_PREP(MT_IFS_EIFS, 360) |62		FIELD_PREP(MT_IFS_RIFS, 2) |63		FIELD_PREP(MT_IFS_SIFS, sifs) |64		FIELD_PREP(MT_IFS_SLOT, phy->slottime));65 66	if (phy->slottime < 20 || !is_2ghz)67		val = MT792x_CFEND_RATE_DEFAULT;68	else69		val = MT792x_CFEND_RATE_11B;70 71	mt76_rmw_field(dev, MT_AGG_ACR0(0), MT_AGG_ACR_CFEND_RATE, val);72	mt76_clear(dev, MT_ARB_SCR(0),73		   MT_ARB_SCR_TX_DISABLE | MT_ARB_SCR_RX_DISABLE);74}75EXPORT_SYMBOL_GPL(mt792x_mac_set_timeing);76 77void mt792x_mac_update_mib_stats(struct mt792x_phy *phy)78{79	struct mt76_mib_stats *mib = &phy->mib;80	struct mt792x_dev *dev = phy->dev;81	int i, aggr0 = 0, aggr1;82	u32 val;83 84	mib->fcs_err_cnt += mt76_get_field(dev, MT_MIB_SDR3(0),85					   MT_MIB_SDR3_FCS_ERR_MASK);86	mib->ack_fail_cnt += mt76_get_field(dev, MT_MIB_MB_BSDR3(0),87					    MT_MIB_ACK_FAIL_COUNT_MASK);88	mib->ba_miss_cnt += mt76_get_field(dev, MT_MIB_MB_BSDR2(0),89					   MT_MIB_BA_FAIL_COUNT_MASK);90	mib->rts_cnt += mt76_get_field(dev, MT_MIB_MB_BSDR0(0),91				       MT_MIB_RTS_COUNT_MASK);92	mib->rts_retries_cnt += mt76_get_field(dev, MT_MIB_MB_BSDR1(0),93					       MT_MIB_RTS_FAIL_COUNT_MASK);94 95	mib->tx_ampdu_cnt += mt76_rr(dev, MT_MIB_SDR12(0));96	mib->tx_mpdu_attempts_cnt += mt76_rr(dev, MT_MIB_SDR14(0));97	mib->tx_mpdu_success_cnt += mt76_rr(dev, MT_MIB_SDR15(0));98 99	val = mt76_rr(dev, MT_MIB_SDR32(0));100	mib->tx_pkt_ebf_cnt += FIELD_GET(MT_MIB_SDR9_EBF_CNT_MASK, val);101	mib->tx_pkt_ibf_cnt += FIELD_GET(MT_MIB_SDR9_IBF_CNT_MASK, val);102 103	val = mt76_rr(dev, MT_ETBF_TX_APP_CNT(0));104	mib->tx_bf_ibf_ppdu_cnt += FIELD_GET(MT_ETBF_TX_IBF_CNT, val);105	mib->tx_bf_ebf_ppdu_cnt += FIELD_GET(MT_ETBF_TX_EBF_CNT, val);106 107	val = mt76_rr(dev, MT_ETBF_RX_FB_CNT(0));108	mib->tx_bf_rx_fb_all_cnt += FIELD_GET(MT_ETBF_RX_FB_ALL, val);109	mib->tx_bf_rx_fb_he_cnt += FIELD_GET(MT_ETBF_RX_FB_HE, val);110	mib->tx_bf_rx_fb_vht_cnt += FIELD_GET(MT_ETBF_RX_FB_VHT, val);111	mib->tx_bf_rx_fb_ht_cnt += FIELD_GET(MT_ETBF_RX_FB_HT, val);112 113	mib->rx_mpdu_cnt += mt76_rr(dev, MT_MIB_SDR5(0));114	mib->rx_ampdu_cnt += mt76_rr(dev, MT_MIB_SDR22(0));115	mib->rx_ampdu_bytes_cnt += mt76_rr(dev, MT_MIB_SDR23(0));116	mib->rx_ba_cnt += mt76_rr(dev, MT_MIB_SDR31(0));117 118	for (i = 0; i < ARRAY_SIZE(mib->tx_amsdu); i++) {119		val = mt76_rr(dev, MT_PLE_AMSDU_PACK_MSDU_CNT(i));120		mib->tx_amsdu[i] += val;121		mib->tx_amsdu_cnt += val;122	}123 124	for (i = 0, aggr1 = aggr0 + 8; i < 4; i++) {125		u32 val2;126 127		val = mt76_rr(dev, MT_TX_AGG_CNT(0, i));128		val2 = mt76_rr(dev, MT_TX_AGG_CNT2(0, i));129 130		phy->mt76->aggr_stats[aggr0++] += val & 0xffff;131		phy->mt76->aggr_stats[aggr0++] += val >> 16;132		phy->mt76->aggr_stats[aggr1++] += val2 & 0xffff;133		phy->mt76->aggr_stats[aggr1++] += val2 >> 16;134	}135}136EXPORT_SYMBOL_GPL(mt792x_mac_update_mib_stats);137 138struct mt76_wcid *mt792x_rx_get_wcid(struct mt792x_dev *dev, u16 idx,139				     bool unicast)140{141	struct mt792x_link_sta *link;142	struct mt792x_sta *sta;143	struct mt76_wcid *wcid;144 145	if (idx >= ARRAY_SIZE(dev->mt76.wcid))146		return NULL;147 148	wcid = rcu_dereference(dev->mt76.wcid[idx]);149	if (unicast || !wcid)150		return wcid;151 152	if (!wcid->sta)153		return NULL;154 155	link = container_of(wcid, struct mt792x_link_sta, wcid);156	sta = container_of(link, struct mt792x_sta, deflink);157	if (!sta->vif)158		return NULL;159 160	return &sta->vif->sta.deflink.wcid;161}162EXPORT_SYMBOL_GPL(mt792x_rx_get_wcid);163 164static void165mt792x_mac_rssi_iter(void *priv, u8 *mac, struct ieee80211_vif *vif)166{167	struct sk_buff *skb = priv;168	struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb;169	struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv;170	struct ieee80211_hdr *hdr = mt76_skb_get_hdr(skb);171 172	if (status->signal > 0)173		return;174 175	if (!ether_addr_equal(vif->addr, hdr->addr1))176		return;177 178	ewma_rssi_add(&mvif->bss_conf.rssi, -status->signal);179}180 181void mt792x_mac_assoc_rssi(struct mt792x_dev *dev, struct sk_buff *skb)182{183	struct ieee80211_hdr *hdr = mt76_skb_get_hdr(skb);184 185	if (!ieee80211_is_assoc_resp(hdr->frame_control) &&186	    !ieee80211_is_auth(hdr->frame_control))187		return;188 189	ieee80211_iterate_active_interfaces_atomic(mt76_hw(dev),190		IEEE80211_IFACE_ITER_RESUME_ALL,191		mt792x_mac_rssi_iter, skb);192}193EXPORT_SYMBOL_GPL(mt792x_mac_assoc_rssi);194 195void mt792x_mac_reset_counters(struct mt792x_phy *phy)196{197	struct mt792x_dev *dev = phy->dev;198	int i;199 200	for (i = 0; i < 4; i++) {201		mt76_rr(dev, MT_TX_AGG_CNT(0, i));202		mt76_rr(dev, MT_TX_AGG_CNT2(0, i));203	}204 205	dev->mt76.phy.survey_time = ktime_get_boottime();206	memset(phy->mt76->aggr_stats, 0, sizeof(phy->mt76->aggr_stats));207 208	/* reset airtime counters */209	mt76_rr(dev, MT_MIB_SDR9(0));210	mt76_rr(dev, MT_MIB_SDR36(0));211	mt76_rr(dev, MT_MIB_SDR37(0));212 213	mt76_set(dev, MT_WF_RMAC_MIB_TIME0(0), MT_WF_RMAC_MIB_RXTIME_CLR);214	mt76_set(dev, MT_WF_RMAC_MIB_AIRTIME0(0), MT_WF_RMAC_MIB_RXTIME_CLR);215}216EXPORT_SYMBOL_GPL(mt792x_mac_reset_counters);217 218static u8219mt792x_phy_get_nf(struct mt792x_phy *phy, int idx)220{221	return 0;222}223 224static void225mt792x_phy_update_channel(struct mt76_phy *mphy, int idx)226{227	struct mt792x_dev *dev = container_of(mphy->dev, struct mt792x_dev, mt76);228	struct mt792x_phy *phy = mphy->priv;229	struct mt76_channel_state *state;230	u64 busy_time, tx_time, rx_time, obss_time;231	int nf;232 233	busy_time = mt76_get_field(dev, MT_MIB_SDR9(idx),234				   MT_MIB_SDR9_BUSY_MASK);235	tx_time = mt76_get_field(dev, MT_MIB_SDR36(idx),236				 MT_MIB_SDR36_TXTIME_MASK);237	rx_time = mt76_get_field(dev, MT_MIB_SDR37(idx),238				 MT_MIB_SDR37_RXTIME_MASK);239	obss_time = mt76_get_field(dev, MT_WF_RMAC_MIB_AIRTIME14(idx),240				   MT_MIB_OBSSTIME_MASK);241 242	nf = mt792x_phy_get_nf(phy, idx);243	if (!phy->noise)244		phy->noise = nf << 4;245	else if (nf)246		phy->noise += nf - (phy->noise >> 4);247 248	state = mphy->chan_state;249	state->cc_busy += busy_time;250	state->cc_tx += tx_time;251	state->cc_rx += rx_time + obss_time;252	state->cc_bss_rx += rx_time;253	state->noise = -(phy->noise >> 4);254}255 256void mt792x_update_channel(struct mt76_phy *mphy)257{258	struct mt792x_dev *dev = container_of(mphy->dev, struct mt792x_dev, mt76);259 260	if (mt76_connac_pm_wake(mphy, &dev->pm))261		return;262 263	mt792x_phy_update_channel(mphy, 0);264	/* reset obss airtime */265	mt76_set(dev, MT_WF_RMAC_MIB_TIME0(0), MT_WF_RMAC_MIB_RXTIME_CLR);266	mt76_connac_power_save_sched(mphy, &dev->pm);267}268EXPORT_SYMBOL_GPL(mt792x_update_channel);269 270void mt792x_reset(struct mt76_dev *mdev)271{272	struct mt792x_dev *dev = container_of(mdev, struct mt792x_dev, mt76);273	struct mt76_connac_pm *pm = &dev->pm;274 275	if (!dev->hw_init_done)276		return;277 278	if (dev->hw_full_reset)279		return;280 281	if (pm->suspended)282		return;283 284	queue_work(dev->mt76.wq, &dev->reset_work);285}286EXPORT_SYMBOL_GPL(mt792x_reset);287 288void mt792x_mac_init_band(struct mt792x_dev *dev, u8 band)289{290	u32 mask, set;291 292	mt76_rmw_field(dev, MT_TMAC_CTCR0(band),293		       MT_TMAC_CTCR0_INS_DDLMT_REFTIME, 0x3f);294	mt76_set(dev, MT_TMAC_CTCR0(band),295		 MT_TMAC_CTCR0_INS_DDLMT_VHT_SMPDU_EN |296		 MT_TMAC_CTCR0_INS_DDLMT_EN);297 298	mt76_set(dev, MT_WF_RMAC_MIB_TIME0(band), MT_WF_RMAC_MIB_RXTIME_EN);299	mt76_set(dev, MT_WF_RMAC_MIB_AIRTIME0(band), MT_WF_RMAC_MIB_RXTIME_EN);300 301	/* enable MIB tx-rx time reporting */302	mt76_set(dev, MT_MIB_SCR1(band), MT_MIB_TXDUR_EN);303	mt76_set(dev, MT_MIB_SCR1(band), MT_MIB_RXDUR_EN);304 305	mt76_rmw_field(dev, MT_DMA_DCR0(band), MT_DMA_DCR0_MAX_RX_LEN, 1536);306	/* disable rx rate report by default due to hw issues */307	mt76_clear(dev, MT_DMA_DCR0(band), MT_DMA_DCR0_RXD_G5_EN);308 309	/* filter out non-resp frames and get instantaneous signal reporting */310	mask = MT_WTBLOFF_TOP_RSCR_RCPI_MODE | MT_WTBLOFF_TOP_RSCR_RCPI_PARAM;311	set = FIELD_PREP(MT_WTBLOFF_TOP_RSCR_RCPI_MODE, 0) |312	      FIELD_PREP(MT_WTBLOFF_TOP_RSCR_RCPI_PARAM, 0x3);313	mt76_rmw(dev, MT_WTBLOFF_TOP_RSCR(band), mask, set);314}315EXPORT_SYMBOL_GPL(mt792x_mac_init_band);316 317void mt792x_pm_wake_work(struct work_struct *work)318{319	struct mt792x_dev *dev;320	struct mt76_phy *mphy;321 322	dev = (struct mt792x_dev *)container_of(work, struct mt792x_dev,323						pm.wake_work);324	mphy = dev->phy.mt76;325 326	if (!mt792x_mcu_drv_pmctrl(dev)) {327		struct mt76_dev *mdev = &dev->mt76;328		int i;329 330		if (mt76_is_sdio(mdev)) {331			mt76_connac_pm_dequeue_skbs(mphy, &dev->pm);332			mt76_worker_schedule(&mdev->sdio.txrx_worker);333		} else {334			local_bh_disable();335			mt76_for_each_q_rx(mdev, i)336				napi_schedule(&mdev->napi[i]);337			local_bh_enable();338			mt76_connac_pm_dequeue_skbs(mphy, &dev->pm);339			mt76_connac_tx_cleanup(mdev);340		}341		if (test_bit(MT76_STATE_RUNNING, &mphy->state))342			ieee80211_queue_delayed_work(mphy->hw, &mphy->mac_work,343						     MT792x_WATCHDOG_TIME);344	}345 346	ieee80211_wake_queues(mphy->hw);347	wake_up(&dev->pm.wait);348}349EXPORT_SYMBOL_GPL(mt792x_pm_wake_work);350 351void mt792x_pm_power_save_work(struct work_struct *work)352{353	struct mt792x_dev *dev;354	unsigned long delta;355	struct mt76_phy *mphy;356 357	dev = (struct mt792x_dev *)container_of(work, struct mt792x_dev,358						pm.ps_work.work);359	mphy = dev->phy.mt76;360 361	delta = dev->pm.idle_timeout;362	if (test_bit(MT76_HW_SCANNING, &mphy->state) ||363	    test_bit(MT76_HW_SCHED_SCANNING, &mphy->state) ||364	    dev->fw_assert)365		goto out;366 367	if (mutex_is_locked(&dev->mt76.mutex))368		/* if mt76 mutex is held we should not put the device369		 * to sleep since we are currently accessing device370		 * register map. We need to wait for the next power_save371		 * trigger.372		 */373		goto out;374 375	if (time_is_after_jiffies(dev->pm.last_activity + delta)) {376		delta = dev->pm.last_activity + delta - jiffies;377		goto out;378	}379 380	if (!mt792x_mcu_fw_pmctrl(dev)) {381		cancel_delayed_work_sync(&mphy->mac_work);382		return;383	}384out:385	queue_delayed_work(dev->mt76.wq, &dev->pm.ps_work, delta);386}387EXPORT_SYMBOL_GPL(mt792x_pm_power_save_work);388