drivers/net/wireless/mediatek/mt76/mt7925/mcu.c

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

File Facts

System
Linux kernel
Corpus path
drivers/net/wireless/mediatek/mt76/mt7925/mcu.c
Extension
.c
Size
102526 bytes
Lines
4004
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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 uni_cmd_access_reg_basic {
				__le16 tag;
				__le16 len;
				__le32 idx;
				__le32 data;
			} __packed reg;
			struct uni_cmd_access_rf_reg_basic {
				__le16 tag;
				__le16 len;
				__le16 ant;
				u8 __rsv[2];
				__le32 idx;
				__le32 data;
			} __packed rf_reg;
		};
	} __packed * res, req;
	struct sk_buff *skb;
	int ret;

	if (u32_get_bits(regidx, MT_RF_REG_HDR) == RF_REG_PREFIX) {
		req.rf_reg.tag = cpu_to_le16(UNI_CMD_ACCESS_RF_REG_BASIC);
		req.rf_reg.len = cpu_to_le16(sizeof(req.rf_reg));
		req.rf_reg.ant = cpu_to_le16(u32_get_bits(regidx, MT_RF_REG_ANT));
		req.rf_reg.idx = cpu_to_le32(regidx);
		req.rf_reg.data = set ? cpu_to_le32(*val) : 0;
	} else {
		req.reg.tag = cpu_to_le16(UNI_CMD_ACCESS_REG_BASIC);
		req.reg.len = cpu_to_le16(sizeof(req.reg));
		req.reg.idx = cpu_to_le32(regidx);
		req.reg.data = set ? cpu_to_le32(*val) : 0;
	}

	if (set)
		return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(REG_ACCESS),
					 &req, sizeof(req), true);

	ret = mt76_mcu_send_and_get_msg(&dev->mt76,
					MCU_WM_UNI_CMD_QUERY(REG_ACCESS),
					&req, sizeof(req), true, &skb);
	if (ret)
		return ret;

	res = (void *)skb->data;
	if (u32_get_bits(regidx, MT_RF_REG_HDR) == RF_REG_PREFIX)
		*val = le32_to_cpu(res->rf_reg.data);
	else
		*val = le32_to_cpu(res->reg.data);

	dev_kfree_skb(skb);

	return 0;
}
EXPORT_SYMBOL_GPL(mt7925_mcu_regval);

int mt7925_mcu_update_arp_filter(struct mt76_dev *dev,
				 struct ieee80211_bss_conf *link_conf)
{
	struct mt792x_bss_conf *mconf = mt792x_link_conf_to_mconf(link_conf);
	struct ieee80211_vif *mvif = link_conf->vif;
	struct sk_buff *skb;
	int i, len = min_t(int, mvif->cfg.arp_addr_cnt,
			   IEEE80211_BSS_ARP_ADDR_LIST_LEN);
	struct {
		struct {
			u8 bss_idx;
			u8 pad[3];
		} __packed hdr;
		struct mt7925_arpns_tlv arp;
	} req = {
		.hdr = {
			.bss_idx = mconf->mt76.idx,
		},
		.arp = {
			.tag = cpu_to_le16(UNI_OFFLOAD_OFFLOAD_ARP),
			.len = cpu_to_le16(sizeof(req) - 4 + len * 2 * sizeof(__be32)),
			.ips_num = len,
			.enable = true,
		},
	};

	skb = mt76_mcu_msg_alloc(dev, NULL, sizeof(req) + len * 2 * sizeof(__be32));
	if (!skb)
		return -ENOMEM;

	skb_put_data(skb, &req, sizeof(req));
	for (i = 0; i < len; i++) {
		skb_put_data(skb, &mvif->cfg.arp_addr_list[i], sizeof(__be32));
		skb_put_zero(skb, sizeof(__be32));
	}

Annotation

Implementation Notes