drivers/soc/ixp4xx/ixp4xx-npe.c

Source file repositories/reference/linux-study-clean/drivers/soc/ixp4xx/ixp4xx-npe.c

File Facts

System
Linux kernel
Corpus path
drivers/soc/ixp4xx/ixp4xx-npe.c
Extension
.c
Size
22705 bytes
Lines
781
Domain
Driver Families
Bucket
drivers/soc
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 dl_block {
		u32 type;
		u32 offset;
	} *blk;

	struct dl_image {
		u32 magic;
		u32 id;
		u32 size;
		union {
			DECLARE_FLEX_ARRAY(u32, data);
			DECLARE_FLEX_ARRAY(struct dl_block, blocks);
		};
	} *image;

	struct dl_codeblock {
		u32 npe_addr;
		u32 size;
		u32 data[];
	} *cb;

	int i, j, err, data_size, instr_size, blocks, table_end;
	u32 cmd;

	if ((err = request_firmware(&fw_entry, name, dev)) != 0)
		return err;

	err = -EINVAL;
	if (fw_entry->size < sizeof(struct dl_image)) {
		print_npe(KERN_ERR, npe, "incomplete firmware file\n");
		goto err;
	}
	image = (struct dl_image*)fw_entry->data;

#if DEBUG_FW
	print_npe(KERN_DEBUG, npe, "firmware: %08X %08X %08X (0x%X bytes)\n",
		  image->magic, image->id, image->size, image->size * 4);
#endif

	if (image->magic == swab32(FW_MAGIC)) { /* swapped file */
		image->id = swab32(image->id);
		image->size = swab32(image->size);
	} else if (image->magic != FW_MAGIC) {
		print_npe(KERN_ERR, npe, "bad firmware file magic: 0x%X\n",
			  image->magic);
		goto err;
	}
	if ((image->size * 4 + sizeof(struct dl_image)) != fw_entry->size) {
		print_npe(KERN_ERR, npe,
			  "inconsistent size of firmware file\n");
		goto err;
	}
	if (((image->id >> 24) & 0xF /* NPE ID */) != npe->id) {
		print_npe(KERN_ERR, npe, "firmware file NPE ID mismatch\n");
		goto err;
	}
	if (image->magic == swab32(FW_MAGIC))
		for (i = 0; i < image->size; i++)
			image->data[i] = swab32(image->data[i]);

	if (cpu_is_ixp42x() && ((image->id >> 28) & 0xF /* device ID */)) {
		print_npe(KERN_INFO, npe, "IXP43x/IXP46x firmware ignored on "
			  "IXP42x\n");
		goto err;
	}

	if (npe_running(npe)) {
		print_npe(KERN_INFO, npe, "unable to load firmware, NPE is "
			  "already running\n");
		err = -EBUSY;
		goto err;
	}
#if 0
	npe_stop(npe);
	npe_reset(npe);
#endif

	print_npe(KERN_INFO, npe, "firmware functionality 0x%X, "
		  "revision 0x%X:%X\n", (image->id >> 16) & 0xFF,
		  (image->id >> 8) & 0xFF, image->id & 0xFF);

	if (cpu_is_ixp42x()) {
		if (!npe->id)
			instr_size = NPE_A_42X_INSTR_SIZE;
		else
			instr_size = NPE_B_AND_C_42X_INSTR_SIZE;
		data_size = NPE_42X_DATA_SIZE;
	} else {
		instr_size = NPE_46X_INSTR_SIZE;
		data_size = NPE_46X_DATA_SIZE;

Annotation

Implementation Notes