drivers/net/ethernet/netronome/nfp/nfp_asm.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/netronome/nfp/nfp_asm.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/netronome/nfp/nfp_asm.c
Extension
.c
Size
7495 bytes
Lines
321
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

FIELD_GET(OP_IMMED_WIDTH, instr) != IMMED_WIDTH_ALL) {
		pr_err("Can't decode/encode immed!\n");
		return false;
	}
	return true;
}

u16 immed_get_value(u64 instr)
{
	u16 reg;

	if (!immed_can_modify(instr))
		return 0;

	reg = FIELD_GET(OP_IMMED_A_SRC, instr);
	if (!unreg_is_imm(reg))
		reg = FIELD_GET(OP_IMMED_B_SRC, instr);

	return (reg & 0xff) | FIELD_GET(OP_IMMED_IMM, instr) << 8;
}

void immed_set_value(u64 *instr, u16 immed)
{
	if (!immed_can_modify(*instr))
		return;

	if (unreg_is_imm(FIELD_GET(OP_IMMED_A_SRC, *instr))) {
		*instr &= ~FIELD_PREP(OP_IMMED_A_SRC, 0xff);
		*instr |= FIELD_PREP(OP_IMMED_A_SRC, immed & 0xff);
	} else {
		*instr &= ~FIELD_PREP(OP_IMMED_B_SRC, 0xff);
		*instr |= FIELD_PREP(OP_IMMED_B_SRC, immed & 0xff);
	}

	*instr &= ~OP_IMMED_IMM;
	*instr |= FIELD_PREP(OP_IMMED_IMM, immed >> 8);
}

void immed_add_value(u64 *instr, u16 offset)
{
	u16 val;

	if (!immed_can_modify(*instr))
		return;

	val = immed_get_value(*instr);
	immed_set_value(instr, val + offset);
}

static u16 nfp_swreg_to_unreg(swreg reg, bool is_dst)
{
	bool lm_id, lm_dec = false;
	u16 val = swreg_value(reg);

	switch (swreg_type(reg)) {
	case NN_REG_GPR_A:
	case NN_REG_GPR_B:
	case NN_REG_GPR_BOTH:
		return val;
	case NN_REG_NNR:
		return UR_REG_NN | val;
	case NN_REG_XFER:
		return UR_REG_XFR | val;
	case NN_REG_LMEM:
		lm_id = swreg_lm_idx(reg);

		switch (swreg_lm_mode(reg)) {
		case NN_LM_MOD_NONE:
			if (val & ~UR_REG_LM_IDX_MAX) {
				pr_err("LM offset too large\n");
				return 0;
			}
			return UR_REG_LM | FIELD_PREP(UR_REG_LM_IDX, lm_id) |
				val;
		case NN_LM_MOD_DEC:
			lm_dec = true;
			fallthrough;
		case NN_LM_MOD_INC:
			if (val) {
				pr_err("LM offset in inc/dev mode\n");
				return 0;
			}
			return UR_REG_LM | UR_REG_LM_POST_MOD |
				FIELD_PREP(UR_REG_LM_IDX, lm_id) |
				FIELD_PREP(UR_REG_LM_POST_MOD_DEC, lm_dec);
		default:
			pr_err("bad LM mode for unrestricted operands %d\n",
			       swreg_lm_mode(reg));
			return 0;
		}

Annotation

Implementation Notes