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

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

File Facts

System
Linux kernel
Corpus path
drivers/net/wireless/mediatek/mt76/mt7996/main.c
Extension
.c
Size
67734 bytes
Lines
2575
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 mt7996_key_iter_data {
    enum set_key_cmd cmd;
    unsigned int link_id;
};

static void
mt7996_key_iter(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
		struct ieee80211_sta *sta, struct ieee80211_key_conf *key,
		void *data)
{
	struct mt7996_key_iter_data *it = data;

	if (sta)
		return;

	WARN_ON(mt7996_set_hw_key(hw, it->cmd, vif, NULL, it->link_id, key));
}

int mt7996_vif_link_add(struct mt76_phy *mphy, struct ieee80211_vif *vif,
			struct ieee80211_bss_conf *link_conf,
			struct mt76_vif_link *mlink)
{
	struct mt7996_vif_link *link = container_of(mlink, struct mt7996_vif_link, mt76);
	struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
	struct mt7996_sta_link *msta_link = &link->msta_link;
	struct mt7996_phy *phy = mphy->priv;
	struct mt7996_dev *dev = phy->dev;
	u8 band_idx = phy->mt76->band_idx;
	struct mt7996_key_iter_data it = {
		.cmd = SET_KEY,
		.link_id = link_conf->link_id,
	};
	int mld_idx, idx, ret;

	if ((mvif->mt76.valid_links & BIT(link_conf->link_id)) &&
	    !mlink->offchannel) {
		if (vif->type == NL80211_IFTYPE_AP)
			return mt7996_mcu_mld_link_oper(dev, link_conf, link,
							true);
		return 0;
	}

	mlink->idx = __ffs64(~dev->mt76.vif_mask);
	if (mlink->idx >= mt7996_max_interface_num(dev))
		return -ENOSPC;

	idx = get_omac_idx(vif->type, phy->omac_mask);
	if (idx < 0)
		return -ENOSPC;

	mld_idx = get_own_mld_idx(dev->mld_idx_mask, false);
	if (mld_idx < 0)
		return -ENOSPC;

	link->mld_idx = mld_idx;
	mlink->omac_idx = idx;
	mlink->band_idx = band_idx;
	mlink->wmm_idx = vif->type == NL80211_IFTYPE_AP ? 0 : 3;
	mlink->wcid = &msta_link->wcid;
	mlink->wcid->offchannel = mlink->offchannel;

	ret = mt7996_mcu_add_dev_info(phy, vif, link_conf, mlink, true);
	if (ret)
		return ret;

	dev->mt76.vif_mask |= BIT_ULL(mlink->idx);
	dev->mld_idx_mask |= BIT_ULL(link->mld_idx);
	phy->omac_mask |= BIT_ULL(mlink->omac_idx);

	idx = MT7996_WTBL_RESERVED - mlink->idx;

	INIT_LIST_HEAD(&msta_link->rc_list);
	msta_link->wcid.idx = idx;
	msta_link->wcid.link_id = link_conf->link_id;
	msta_link->wcid.link_valid = ieee80211_vif_is_mld(vif);
	msta_link->wcid.tx_info |= MT_WCID_TX_INFO_SET;
	mt76_wcid_init(&msta_link->wcid, band_idx);

	mt7996_mac_wtbl_update(dev, idx,
			       MT_WTBL_UPDATE_ADM_COUNT_CLEAR);

	if (vif->type != NL80211_IFTYPE_AP &&
	    (!mlink->omac_idx || mlink->omac_idx > 3))
		vif->offload_flags = 0;

	if (phy->mt76->chandef.chan->band != NL80211_BAND_2GHZ)
		mlink->basic_rates_idx = MT7996_BASIC_RATES_TBL + 4;
	else
		mlink->basic_rates_idx = MT7996_BASIC_RATES_TBL;

Annotation

Implementation Notes