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;
ret = wfx_sram_reg_write(wdev, WFX_DCA_PUT, offs); if (ret < 0) return ret;
} return0;
}
start = ktime_get();
ret = upload_firmware(wdev, fw->data + header_size, fw->size - header_size); if (ret) goto error;
dev_dbg(wdev->dev, "firmware load after %lldus\n",
ktime_us_delta(ktime_get(), start));
wfx_sram_reg_write(wdev, WFX_DCA_HOST_STATUS, HOST_UPLOAD_COMPLETE);
ret = wait_ncp_status(wdev, NCP_AUTH_OK); /* Legacy ROM support */ if (ret < 0)
ret = wait_ncp_status(wdev, NCP_PUB_KEY_RDY); if (ret < 0) goto error;
wfx_sram_reg_write(wdev, WFX_DCA_HOST_STATUS, HOST_OK_TO_JUMP);
error:
kfree(buf);
release_firmware(fw); if (ret)
print_boot_status(wdev); return ret;
}
for (i = 0; i < ARRAY_SIZE(gpr_init); i++) {
ret = wfx_igpr_reg_write(wdev, gpr_init[i].index, gpr_init[i].value); if (ret < 0) return ret;
dev_dbg(wdev->dev, " index %02x: %08x\n", gpr_init[i].index, gpr_init[i].value);
} return0;
}
int wfx_init_device(struct wfx_dev *wdev)
{ int ret; int hw_revision, hw_type; int wakeup_timeout = 50; /* ms */
ktime_t now, start;
u32 reg;
reg = CFG_DIRECT_ACCESS_MODE | CFG_CPU_RESET | CFG_BYTE_ORDER_ABCD; if (wdev->pdata.use_rising_clk)
reg |= CFG_CLK_RISE_EDGE;
ret = wfx_config_reg_write(wdev, reg); if (ret < 0) {
dev_err(wdev->dev, "bus returned an error during first write access. Host configuration error?\n"); return -EIO;
}
ret = wfx_config_reg_read(wdev, ®); if (ret < 0) {
dev_err(wdev->dev, "bus returned an error during first read access. Bus configuration error?\n"); return -EIO;
} if (reg == 0 || reg == ~0) {
dev_err(wdev->dev, "chip mute. Bus configuration error or chip wasn't reset?\n"); return -EIO;
}
dev_dbg(wdev->dev, "initial config register value: %08x\n", reg);
ret = wfx_control_reg_write(wdev, CTRL_WLAN_WAKEUP); if (ret < 0) return -EIO;
start = ktime_get(); for (;;) {
ret = wfx_control_reg_read(wdev, ®);
now = ktime_get(); if (reg & CTRL_WLAN_READY) break; if (ktime_after(now, ktime_add_ms(start, wakeup_timeout))) {
dev_err(wdev->dev, "chip didn't wake up. Chip wasn't reset?\n"); return -ETIMEDOUT;
}
}
dev_dbg(wdev->dev, "chip wake up after %lldus\n", ktime_us_delta(now, start));
ret = wfx_config_reg_write_bits(wdev, CFG_CPU_RESET, 0); if (ret < 0) return ret;
ret = load_firmware_secure(wdev); if (ret < 0) return ret; return wfx_config_reg_write_bits(wdev,
CFG_DIRECT_ACCESS_MODE |
CFG_IRQ_ENABLE_DATA |
CFG_IRQ_ENABLE_WRDY,
CFG_IRQ_ENABLE_DATA);
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.10 Sekunden
(vorverarbeitet am 2026-10-02)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.