drivers/net/wireless/mediatek/mt76/mt7915/mac.c

Source file repositories/reference/linux-study-clean/drivers/net/wireless/mediatek/mt76/mt7915/mac.c

File Facts

System
Linux kernel
Corpus path
drivers/net/wireless/mediatek/mt76/mt7915/mac.c
Extension
.c
Size
62869 bytes
Lines
2390
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (list_empty(&sta_poll_list)) {
			spin_unlock_bh(&dev->mt76.sta_poll_lock);
			break;
		}
		msta = list_first_entry(&sta_poll_list,
					struct mt7915_sta, wcid.poll_list);
		list_del_init(&msta->wcid.poll_list);
		spin_unlock_bh(&dev->mt76.sta_poll_lock);

		idx = msta->wcid.idx;

		/* refresh peer's airtime reporting */
		addr = mt7915_mac_wtbl_lmac_addr(dev, idx, 20);

		for (i = 0; i < IEEE80211_NUM_ACS; i++) {
			u32 tx_last = msta->airtime_ac[i];
			u32 rx_last = msta->airtime_ac[i + 4];

			msta->airtime_ac[i] = mt76_rr(dev, addr);
			msta->airtime_ac[i + 4] = mt76_rr(dev, addr + 4);

			if (msta->airtime_ac[i] <= tx_last)
				tx_time[i] = 0;
			else
				tx_time[i] = msta->airtime_ac[i] - tx_last;

			if (msta->airtime_ac[i + 4] <= rx_last)
				rx_time[i] = 0;
			else
				rx_time[i] = msta->airtime_ac[i + 4] - rx_last;

			if ((tx_last | rx_last) & BIT(30))
				clear = true;

			addr += 8;
		}

		if (clear) {
			mt7915_mac_wtbl_update(dev, idx,
					       MT_WTBL_UPDATE_ADM_COUNT_CLEAR);
			memset(msta->airtime_ac, 0, sizeof(msta->airtime_ac));
		}

		if (!msta->wcid.sta)
			continue;

		sta = container_of((void *)msta, struct ieee80211_sta,
				   drv_priv);
		for (i = 0; i < IEEE80211_NUM_ACS; i++) {
			u8 queue = mt76_connac_lmac_mapping(i);
			u32 tx_cur = tx_time[queue];
			u32 rx_cur = rx_time[queue];
			u8 tid = ac_to_tid[i];

			if (!tx_cur && !rx_cur)
				continue;

			ieee80211_sta_register_airtime(sta, tid, tx_cur,
						       rx_cur);
		}

		/*
		 * We don't support reading GI info from txs packets.
		 * For accurate tx status reporting and AQL improvement,
		 * we need to make sure that flags match so polling GI
		 * from per-sta counters directly.
		 */
		rate = &msta->wcid.rate;
		addr = mt7915_mac_wtbl_lmac_addr(dev, idx, 7);
		val = mt76_rr(dev, addr);

		switch (rate->bw) {
		case RATE_INFO_BW_160:
			bw = IEEE80211_STA_RX_BW_160;
			break;
		case RATE_INFO_BW_80:
			bw = IEEE80211_STA_RX_BW_80;
			break;
		case RATE_INFO_BW_40:
			bw = IEEE80211_STA_RX_BW_40;
			break;
		default:
			bw = IEEE80211_STA_RX_BW_20;
			break;
		}

		if (rate->flags & RATE_INFO_FLAGS_HE_MCS) {
			u8 offs = 24 + 2 * bw;

			rate->he_gi = (val & (0x3 << offs)) >> offs;

Annotation

Implementation Notes