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

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

File Facts

System
Linux kernel
Corpus path
drivers/net/wireless/mediatek/mt76/mt7996/mac.c
Extension
.c
Size
84425 bytes
Lines
3251
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_link = list_first_entry(&sta_poll_list,
					     struct mt7996_sta_link,
					     wcid.poll_list);
		msta = msta_link->sta;
		wcid = &msta_link->wcid;
		list_del_init(&wcid->poll_list);
		spin_unlock_bh(&dev->mt76.sta_poll_lock);

		idx = wcid->idx;

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

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

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

			tx_time[i] = msta_link->airtime_ac[i] - tx_last;
			rx_time[i] = msta_link->airtime_ac[i + 4] - rx_last;

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

			addr += 8;
		}

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

		if (!wcid->sta)
			continue;

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

			if (!tx_cur && !rx_cur)
				continue;

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

		/* get signal strength of resp frames (CTS/BA/ACK) */
		addr = mt7996_mac_wtbl_lmac_addr(dev, idx, 34);
		val = mt76_rr(dev, addr);

		rssi[0] = to_rssi(GENMASK(7, 0), val);
		rssi[1] = to_rssi(GENMASK(15, 8), val);
		rssi[2] = to_rssi(GENMASK(23, 16), val);
		rssi[3] = to_rssi(GENMASK(31, 14), val);

		mlink = rcu_dereference(msta->vif->mt76.link[wcid->link_id]);
		if (mlink) {
			struct mt76_phy *mphy = mt76_vif_link_phy(mlink);

			if (mphy)
				msta_link->ack_signal =
					mt76_rx_signal(mphy->antenna_mask,
						       rssi);
		}

		ewma_avg_signal_add(&msta_link->avg_ack_signal,
				    -msta_link->ack_signal);
	}

	rcu_read_unlock();
}

/* The HW does not translate the mac header to 802.3 for mesh point */
static int mt7996_reverse_frag0_hdr_trans(struct sk_buff *skb, u16 hdr_gap)
{
	struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb;
	struct ethhdr *eth_hdr = (struct ethhdr *)(skb->data + hdr_gap);
	struct mt7996_sta_link *msta_link = (void *)status->wcid;
	struct mt7996_sta *msta = msta_link->sta;

Annotation

Implementation Notes