drivers/net/wireless/purelifi/plfxlc/firmware.c

Source file repositories/reference/linux-study-clean/drivers/net/wireless/purelifi/plfxlc/firmware.c

File Facts

System
Linux kernel
Corpus path
drivers/net/wireless/purelifi/plfxlc/firmware.c
Extension
.c
Size
7060 bytes
Lines
277
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

if (!fw_data) {
			r = -ENOMEM;
			goto error_free_fw;
		}

		for (tbuf_idx = 0; tbuf_idx < blk_tran_len; tbuf_idx++) {
			/* u8 bit reverse */
			fw_data[tbuf_idx] = bitrev8(fw_data[tbuf_idx]);
		}
		r = usb_bulk_msg(udev,
				 usb_sndbulkpipe(interface_to_usbdev(intf),
						 fpga_dmabuff[0] & 0xff),
				 fw_data,
				 blk_tran_len,
				 &actual_length,
				 2 * PLF_USB_TIMEOUT);

		if (r)
			dev_err(&intf->dev, "Bulk msg failed (%d)\n", r);

		kfree(fw_data);
		fw_data_i += blk_tran_len;
	}

	kfree(fpga_dmabuff);
	fpga_dmabuff = kmalloc(PLF_FPGA_STATE_LEN, GFP_KERNEL);
	if (!fpga_dmabuff) {
		r = -ENOMEM;
		goto error_free_fw;
	}
	memset(fpga_dmabuff, 0xff, PLF_FPGA_STATE_LEN);

	send_vendor_request(udev, PLF_VNDR_FPGA_STATE_REQ, fpga_dmabuff,
			    PLF_FPGA_STATE_LEN);

	dev_dbg(&intf->dev, "%*ph\n", 8, fpga_dmabuff);

	if (fpga_dmabuff[0] != 0) {
		r = -EINVAL;
		goto error_free_fw;
	}

	send_vendor_command(udev, PLF_VNDR_FPGA_STATE_CMD, NULL, 0);

	msleep(PLF_MSLEEP_TIME);

error_free_fw:
	kfree(fpga_dmabuff);
	release_firmware(fw);
error:
	return r;
}

int plfxlc_download_xl_firmware(struct usb_interface *intf)
{
	struct usb_device *udev = interface_to_usbdev(intf);
	const struct firmware *fwp = NULL;
	struct plfxlc_firmware_file file = {0};
	const char *fw_pack;
	int s, r;
	u8 *buf;
	u32 i;

	r = send_vendor_command(udev, PLF_VNDR_XL_FW_CMD, NULL, 0);
	msleep(PLF_MSLEEP_TIME);

	if (r) {
		dev_err(&intf->dev, "vendor command failed (%d)\n", r);
		return -EINVAL;
	}
	/* Code for single pack file download */

	fw_pack = "plfxlc/lifi-xl.bin";

	r = request_firmware(&fwp, fw_pack, &intf->dev);
	if (r) {
		dev_err(&intf->dev, "Request_firmware failed (%d)\n", r);
		return -EINVAL;
	}
	file.total_files = get_unaligned_le32(&fwp->data[0]);
	file.total_size = get_unaligned_le32(&fwp->size);

	dev_dbg(&intf->dev, "XL Firmware (%d, %d)\n",
		file.total_files, file.total_size);

	buf = kzalloc(PLF_XL_BUF_LEN, GFP_KERNEL);
	if (!buf) {
		release_firmware(fwp);
		return -ENOMEM;
	}

Annotation

Implementation Notes