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

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

File Facts

System
Linux kernel
Corpus path
drivers/net/wireless/mediatek/mt76/mt7915/main.c
Extension
.c
Size
48688 bytes
Lines
1825
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

struct drop_sta_iter {
	struct mt7915_dev *dev;
	struct ieee80211_hw *hw;
	struct ieee80211_vif *vif;
	u8 sta_addr[ETH_ALEN];
};

static void
__mt7915_drop_sta(void *ptr, u8 *mac, struct ieee80211_vif *vif)
{
	struct drop_sta_iter *data = ptr;
	struct ieee80211_sta *sta;
	struct mt7915_sta *msta;

	if (vif == data->vif || vif->type != NL80211_IFTYPE_AP)
		return;

	sta = ieee80211_find_sta_by_ifaddr(data->hw, data->sta_addr, mac);
	if (!sta)
		return;

	msta = (struct mt7915_sta *)sta->drv_priv;
	mt7915_mcu_add_sta(data->dev, vif, sta, CONN_STATE_DISCONNECT, false);
	msta->wcid.sta_disabled = 1;
	msta->wcid.sta = 0;
}

static void
mt7915_drop_other_sta(struct mt7915_dev *dev, struct ieee80211_vif *vif,
		      struct ieee80211_sta *sta)
{
	struct mt76_phy *ext_phy = dev->mt76.phys[MT_BAND1];
	struct drop_sta_iter data = {
		.dev = dev,
		.hw = dev->mphy.hw,
		.vif = vif,
	};

	if (vif->type != NL80211_IFTYPE_AP)
		return;

	memcpy(data.sta_addr, sta->addr, ETH_ALEN);
	ieee80211_iterate_active_interfaces(data.hw, 0, __mt7915_drop_sta, &data);

	if (!ext_phy)
		return;

	data.hw = ext_phy->hw;
	ieee80211_iterate_active_interfaces(data.hw, 0, __mt7915_drop_sta, &data);
}

int mt7915_mac_sta_event(struct mt76_dev *mdev, struct ieee80211_vif *vif,
			 struct ieee80211_sta *sta, enum mt76_sta_event ev)
{
	struct mt7915_dev *dev = container_of(mdev, struct mt7915_dev, mt76);
	struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;
	int i, ret;
	u32 addr;

	switch (ev) {
	case MT76_STA_EVENT_ASSOC:
		ret = mt7915_mcu_add_sta(dev, vif, sta, CONN_STATE_CONNECT, true);
		if (ret)
			return ret;

		addr = mt7915_mac_wtbl_lmac_addr(dev, msta->wcid.idx, 30);
		mt76_rmw_field(dev, addr, GENMASK(7, 0), 0xa0);

		ret = mt7915_mcu_add_rate_ctrl(dev, vif, sta, false);
		if (ret)
			return ret;

		msta->wcid.tx_info |= MT_WCID_TX_INFO_SET;
		msta->wcid.sta = 1;
		msta->wcid.sta_disabled = 0;

		return 0;

	case MT76_STA_EVENT_AUTHORIZE:
		mt7915_drop_other_sta(dev, vif, sta);
		return mt7915_mcu_add_sta(dev, vif, sta, CONN_STATE_PORT_SECURE, false);

	case MT76_STA_EVENT_DISASSOC:
		mutex_lock(&dev->mt76.mutex);
		for (i = 0; i < ARRAY_SIZE(msta->twt.flow); i++)
			mt7915_mac_twt_teardown_flow(dev, msta, i);
		mutex_unlock(&dev->mt76.mutex);

		mt7915_mcu_add_sta(dev, vif, sta, CONN_STATE_DISCONNECT, false);
		msta->wcid.sta_disabled = 1;

Annotation

Implementation Notes