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

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

File Facts

System
Linux kernel
Corpus path
drivers/net/wireless/mediatek/mt76/mt7603/mcu.c
Extension
.c
Size
10316 bytes
Lines
433
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 mt7603_fw_trailer {
	char fw_ver[10];
	char build_date[15];
	__le32 dl_len;
} __packed;

static int
mt7603_mcu_parse_response(struct mt76_dev *mdev, int cmd,
			  struct sk_buff *skb, int seq)
{
	struct mt7603_dev *dev = container_of(mdev, struct mt7603_dev, mt76);
	struct mt7603_mcu_rxd *rxd;

	if (!skb) {
		dev_err(mdev->dev, "MCU message %02x (seq %d) timed out\n",
			abs(cmd), seq);
		dev->mcu_hang = MT7603_WATCHDOG_TIMEOUT;
		return -ETIMEDOUT;
	}

	rxd = (struct mt7603_mcu_rxd *)skb->data;
	if (seq != rxd->seq)
		return -EAGAIN;

	return 0;
}

static int
mt7603_mcu_skb_send_msg(struct mt76_dev *mdev, struct sk_buff *skb,
			int cmd, int *wait_seq)
{
	struct mt7603_dev *dev = container_of(mdev, struct mt7603_dev, mt76);
	int hdrlen = dev->mcu_running ? sizeof(struct mt7603_mcu_txd) : 12;
	struct mt7603_mcu_txd *txd;
	u8 seq;

	mdev->mcu.timeout = 3 * HZ;

	seq = ++mdev->mcu.msg_seq & 0xf;
	if (!seq)
		seq = ++mdev->mcu.msg_seq & 0xf;

	txd = (struct mt7603_mcu_txd *)skb_push(skb, hdrlen);

	txd->len = cpu_to_le16(skb->len);
	if (cmd == -MCU_CMD_FW_SCATTER)
		txd->pq_id = cpu_to_le16(MCU_PORT_QUEUE_FW);
	else
		txd->pq_id = cpu_to_le16(MCU_PORT_QUEUE);
	txd->pkt_type = MCU_PKT_ID;
	txd->seq = seq;

	if (cmd < 0) {
		txd->cid = -cmd;
		txd->set_query = MCU_Q_NA;
	} else {
		txd->cid = MCU_CMD_EXT_CID;
		txd->ext_cid = cmd;
		txd->set_query = MCU_Q_SET;
		txd->ext_cid_ack = 1;
	}

	if (wait_seq)
		*wait_seq = seq;

	return mt76_tx_queue_skb_raw(dev, mdev->q_mcu[MT_MCUQ_WM], skb, 0);
}

static int
mt7603_mcu_init_download(struct mt7603_dev *dev, u32 addr, u32 len)
{
	struct {
		__le32 addr;
		__le32 len;
		__le32 mode;
	} req = {
		.addr = cpu_to_le32(addr),
		.len = cpu_to_le32(len),
		.mode = cpu_to_le32(BIT(31)),
	};

	return mt76_mcu_send_msg(&dev->mt76, -MCU_CMD_TARGET_ADDRESS_LEN_REQ,
				 &req, sizeof(req), true);
}

static int
mt7603_mcu_start_firmware(struct mt7603_dev *dev, u32 addr)
{
	struct {
		__le32 override;

Annotation

Implementation Notes