drivers/vdpa/solidrun/snet_ctrl.c

Source file repositories/reference/linux-study-clean/drivers/vdpa/solidrun/snet_ctrl.c

File Facts

System
Linux kernel
Corpus path
drivers/vdpa/solidrun/snet_ctrl.c
Extension
.c
Size
8530 bytes
Lines
337
Domain
Driver Families
Bucket
drivers/vdpa
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 snet_ctrl_reg_ctrl {
	/* Chunk size in 4B words */
	u16 data_size;
	/* We are in the middle of a command */
	u16 in_process:1;
	/* A data chunk is ready and can be consumed */
	u16 chunk_ready:1;
	/* Error code */
	u16 error:10;
	/* Saved for future usage */
	u16 rsvd:4;
};

/* Opcode register */
struct snet_ctrl_reg_op {
	u16 opcode;
	/* Only if VQ index is relevant for the command */
	u16 vq_idx;
};

struct snet_ctrl_regs {
	struct snet_ctrl_reg_op op;
	struct snet_ctrl_reg_ctrl ctrl;
	u32 rsvd;
	u32 data[];
};

static struct snet_ctrl_regs __iomem *snet_get_ctrl(struct snet *snet)
{
	return snet->bar + snet->psnet->cfg.ctrl_off;
}

static int snet_wait_for_empty_ctrl(struct snet_ctrl_regs __iomem *regs)
{
	u32 val;

	return readx_poll_timeout(ioread32, &regs->ctrl, val, SNET_EMPTY_CTRL(val), 10,
				  SNET_CTRL_TIMEOUT);
}

static int snet_wait_for_empty_op(struct snet_ctrl_regs __iomem *regs)
{
	u32 val;

	return readx_poll_timeout(ioread32, &regs->op, val, !val, 10, SNET_CTRL_TIMEOUT);
}

static int snet_wait_for_data(struct snet_ctrl_regs __iomem *regs)
{
	u32 val;

	return readx_poll_timeout(ioread32, &regs->ctrl, val, SNET_DATA_READY(val), 10,
				  SNET_CTRL_TIMEOUT);
}

static u32 snet_read32_word(struct snet_ctrl_regs __iomem *ctrl_regs, u16 word_idx)
{
	return ioread32(&ctrl_regs->data[word_idx]);
}

static u32 snet_read_ctrl(struct snet_ctrl_regs __iomem *ctrl_regs)
{
	return ioread32(&ctrl_regs->ctrl);
}

static void snet_write_ctrl(struct snet_ctrl_regs __iomem *ctrl_regs, u32 val)
{
	iowrite32(val, &ctrl_regs->ctrl);
}

static void snet_write_op(struct snet_ctrl_regs __iomem *ctrl_regs, u32 val)
{
	iowrite32(val, &ctrl_regs->op);
}

static int snet_wait_for_dpu_completion(struct snet_ctrl_regs __iomem *ctrl_regs)
{
	/* Wait until the DPU finishes completely.
	 * It will clear the opcode register.
	 */
	return snet_wait_for_empty_op(ctrl_regs);
}

/* Reading ctrl from the DPU:
 * buf_size must be 4B aligned
 *
 * Steps:
 *
 * (1) Verify that the DPU is not in the middle of another operation by
 *     reading the in_process and error bits in the control register.

Annotation

Implementation Notes