drivers/net/wireless/st/cw1200/fwio.c

Source file repositories/reference/linux-study-clean/drivers/net/wireless/st/cw1200/fwio.c

File Facts

System
Linux kernel
Corpus path
drivers/net/wireless/st/cw1200/fwio.c
Extension
.c
Size
12377 bytes
Lines
524
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 (val32 != DOWNLOAD_PENDING) {
			pr_err("Bootloader reported error %d.\n", val32);
			ret = -EIO;
			goto free_buffer;
		}

		/* loop until put - get <= 24K */
		for (i = 0; i < 100; i++) {
			APB_READ(DOWNLOAD_GET_REG, get);
			if ((put - get) <=
			    (DOWNLOAD_FIFO_SIZE - DOWNLOAD_BLOCK_SIZE))
				break;
			mdelay(i);
		}

		if ((put - get) > (DOWNLOAD_FIFO_SIZE - DOWNLOAD_BLOCK_SIZE)) {
			pr_err("Timeout waiting for FIFO.\n");
			ret = -ETIMEDOUT;
			goto free_buffer;
		}

		/* calculate the block size */
		tx_size = block_size = min_t(size_t, firmware->size - put,
					DOWNLOAD_BLOCK_SIZE);

		memcpy(buf, &firmware->data[put], block_size);
		if (block_size < DOWNLOAD_BLOCK_SIZE) {
			memset(&buf[block_size], 0,
			       DOWNLOAD_BLOCK_SIZE - block_size);
			tx_size = DOWNLOAD_BLOCK_SIZE;
		}

		/* send the block to sram */
		ret = cw1200_apb_write(priv,
			CW1200_APB(DOWNLOAD_FIFO_OFFSET +
				   (put & (DOWNLOAD_FIFO_SIZE - 1))),
			buf, tx_size);
		if (ret < 0) {
			pr_err("Can't write firmware block @ %d!\n",
			       put & (DOWNLOAD_FIFO_SIZE - 1));
			goto free_buffer;
		}

		/* update the put register */
		put += block_size;
		APB_WRITE2(DOWNLOAD_PUT_REG, put);
	} /* End of firmware download loop */

	/* Wait for the download completion */
	for (i = 0; i < 300; i += 1 + i / 2) {
		APB_READ(DOWNLOAD_STATUS_REG, val32);
		if (val32 != DOWNLOAD_PENDING)
			break;
		mdelay(i);
	}
	if (val32 != DOWNLOAD_SUCCESS) {
		pr_err("Wait for download completion failed: 0x%.8X\n", val32);
		ret = -ETIMEDOUT;
		goto free_buffer;
	} else {
		pr_info("Firmware download completed.\n");
		ret = 0;
	}

free_buffer:
	kfree(buf);
firmware_release:
	release_firmware(firmware);
exit:
	return ret;

#undef APB_WRITE
#undef APB_WRITE2
#undef APB_READ
#undef REG_WRITE
#undef REG_READ
}


static int config_reg_read(struct cw1200_common *priv, u32 *val)
{
	switch (priv->hw_type) {
	case HIF_9000_SILICON_VERSATILE: {
		u16 val16;
		int ret = cw1200_reg_read_16(priv,
					     ST90TDS_CONFIG_REG_ID,
					     &val16);
		if (ret < 0)
			return ret;
		*val = val16;

Annotation

Implementation Notes