drivers/net/wireless/silabs/wfx/fwio.c
Source file repositories/reference/linux-study-clean/drivers/net/wireless/silabs/wfx/fwio.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/net/wireless/silabs/wfx/fwio.c- Extension
.c- Size
- 11444 bytes
- Lines
- 390
- 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.
- 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.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/firmware.hlinux/hex.hlinux/slab.hlinux/mm.hlinux/bitfield.hfwio.hwfx.hhwio.h
Detected Declarations
function runtimefunction get_firmwarefunction wait_ncp_statusfunction upload_firmwarefunction print_boot_statusfunction load_firmware_securefunction init_gprfunction wfx_init_device
Annotated Snippet
if (ret) {
dev_err(wdev->dev, "can't load %s\n", filename);
*fw = NULL;
return ret;
}
}
data = (*fw)->data;
if (memcmp(data, "KEYSET", 6) != 0) {
/* Legacy firmware format */
*file_offset = 0;
keyset_file = 0x90;
} else {
*file_offset = 8;
keyset_file = (hex_to_bin(data[6]) * 16) | hex_to_bin(data[7]);
if (keyset_file < 0) {
dev_err(wdev->dev, "%s corrupted\n", filename);
release_firmware(*fw);
*fw = NULL;
return -EINVAL;
}
}
if (keyset_file != keyset_chip) {
dev_err(wdev->dev, "firmware keyset is incompatible with chip (file: 0x%02X, chip: 0x%02X)\n",
keyset_file, keyset_chip);
release_firmware(*fw);
*fw = NULL;
return -ENODEV;
}
wdev->keyset = keyset_file;
return 0;
}
static int wait_ncp_status(struct wfx_dev *wdev, u32 status)
{
ktime_t now, start;
u32 reg;
int ret;
start = ktime_get();
for (;;) {
ret = wfx_sram_reg_read(wdev, WFX_DCA_NCP_STATUS, ®);
if (ret < 0)
return -EIO;
now = ktime_get();
if (reg == status)
break;
if (ktime_after(now, ktime_add_ms(start, DCA_TIMEOUT)))
return -ETIMEDOUT;
}
if (ktime_compare(now, start))
dev_dbg(wdev->dev, "chip answer after %lldus\n", ktime_us_delta(now, start));
else
dev_dbg(wdev->dev, "chip answer immediately\n");
return 0;
}
static int upload_firmware(struct wfx_dev *wdev, const u8 *data, size_t len)
{
int ret;
u32 offs, bytes_done = 0;
ktime_t now, start;
if (len % DNLD_BLOCK_SIZE) {
dev_err(wdev->dev, "firmware size is not aligned. Buffer overrun will occur\n");
return -EIO;
}
offs = 0;
while (offs < len) {
start = ktime_get();
for (;;) {
now = ktime_get();
if (offs + DNLD_BLOCK_SIZE - bytes_done < DNLD_FIFO_SIZE)
break;
if (ktime_after(now, ktime_add_ms(start, DCA_TIMEOUT)))
return -ETIMEDOUT;
ret = wfx_sram_reg_read(wdev, WFX_DCA_GET, &bytes_done);
if (ret < 0)
return ret;
}
if (ktime_compare(now, start))
dev_dbg(wdev->dev, "answer after %lldus\n", ktime_us_delta(now, start));
ret = wfx_sram_write_dma_safe(wdev, WFX_DNLD_FIFO + (offs % DNLD_FIFO_SIZE),
data + offs, DNLD_BLOCK_SIZE);
if (ret < 0)
return ret;
/* The device seems to not support writing 0 in this register during first loop */
offs += DNLD_BLOCK_SIZE;
Annotation
- Immediate include surface: `linux/firmware.h`, `linux/hex.h`, `linux/slab.h`, `linux/mm.h`, `linux/bitfield.h`, `fwio.h`, `wfx.h`, `hwio.h`.
- Detected declarations: `function runtime`, `function get_firmware`, `function wait_ncp_status`, `function upload_firmware`, `function print_boot_status`, `function load_firmware_secure`, `function init_gpr`, `function wfx_init_device`.
- Atlas domain: Driver Families / drivers/net.
- Implementation status: source implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.