void qtnf_pcie_fw_boot_done(struct qtnf_bus *bus, bool boot_success) { struct qtnf_pcie_bus_priv *priv = get_bus_priv(bus); struct pci_dev *pdev = priv->pdev; int ret; if (boot_success) { bus->fw_state = QTNF_FW_STATE_FW_DNLD_DONE; ret = qtnf_core_attach(bus); if (ret) { pr_err("failed to attach core\n"); boot_success = false; } } if (boot_success) { qtnf_debugfs_init(bus, DRV_NAME); qtnf_debugfs_add_entry(bus, "mps", qtnf_dbg_mps_show); qtnf_debugfs_add_entry(bus, "msi_enabled", qtnf_dbg_msi_show); qtnf_debugfs_add_entry(bus, "shm_stats", qtnf_dbg_shm_stats); } else { bus->fw_state = QTNF_FW_STATE_DETACHED; } put_device(&pdev->dev); }
static void qtnf_pearl_fw_work_handler(struct work_struct *work) { struct qtnf_bus *bus = container_of(work, struct qtnf_bus, fw_work); struct qtnf_pcie_pearl_state *ps = (void *)get_bus_priv(bus); u32 state = QTN_RC_FW_LOADRDY | QTN_RC_FW_QLINK; const char *fwname = QTN_PCI_PEARL_FW_NAME; struct pci_dev *pdev = ps->base.pdev; const struct firmware *fw; int ret; if (ps->base.flashboot) { state |= QTN_RC_FW_FLASHBOOT; } else { ret = request_firmware(&fw, fwname, &pdev->dev); if (ret < 0) { pr_err("failed to get firmware %s\n", fwname); goto fw_load_exit; } } qtnf_set_state(&ps->bda->bda_rc_state, state); if (qtnf_poll_state(&ps->bda->bda_ep_state, QTN_EP_FW_LOADRDY, QTN_FW_DL_TIMEOUT_MS)) { pr_err("card is not ready\n"); if (!ps->base.flashboot) release_firmware(fw); goto fw_load_exit; } qtnf_clear_state(&ps->bda->bda_ep_state, QTN_EP_FW_LOADRDY); if (ps->base.flashboot) { pr_info("booting firmware from flash\n"); } else { pr_info("starting firmware upload: %s\n", fwname); ret = qtnf_ep_fw_load(ps, fw->data, fw->size); release_firmware(fw); if (ret) { pr_err("firmware upload error\n"); goto fw_load_exit; } } if (qtnf_poll_state(&ps->bda->bda_ep_state, QTN_EP_FW_DONE, QTN_FW_DL_TIMEOUT_MS)) { pr_err("firmware bringup timed out\n"); goto fw_load_exit; } if (qtnf_poll_state(&ps->bda->bda_ep_state, QTN_EP_FW_QLINK_DONE, QTN_FW_QLINK_TIMEOUT_MS)) { pr_err("firmware runtime failure\n"); goto fw_load_exit; } pr_info("firmware is up and running\n"); ret = qtnf_pcie_fw_boot_done(bus); if (ret) goto fw_load_exit; qtnf_debugfs_add_entry(bus, "hdp_stats", qtnf_dbg_hdp_stats); qtnf_debugfs_add_entry(bus, "irq_stats", qtnf_dbg_irq_stats); fw_load_exit: put_device(&pdev->dev); }
static void qtnf_fw_work_handler(struct work_struct *work) { struct qtnf_bus *bus = container_of(work, struct qtnf_bus, fw_work); struct qtnf_pcie_bus_priv *priv = (void *)get_bus_priv(bus); struct pci_dev *pdev = priv->pdev; const struct firmware *fw; int ret; u32 state = QTN_RC_FW_LOADRDY | QTN_RC_FW_QLINK; if (flashboot) { state |= QTN_RC_FW_FLASHBOOT; } else { ret = request_firmware(&fw, bus->fwname, &pdev->dev); if (ret < 0) { pr_err("failed to get firmware %s\n", bus->fwname); goto fw_load_fail; } } qtnf_set_state(&priv->bda->bda_rc_state, state); if (qtnf_poll_state(&priv->bda->bda_ep_state, QTN_EP_FW_LOADRDY, QTN_FW_DL_TIMEOUT_MS)) { pr_err("card is not ready\n"); if (!flashboot) release_firmware(fw); goto fw_load_fail; } qtnf_clear_state(&priv->bda->bda_ep_state, QTN_EP_FW_LOADRDY); if (flashboot) { pr_info("booting firmware from flash\n"); } else { pr_info("starting firmware upload: %s\n", bus->fwname); ret = qtnf_ep_fw_load(priv, fw->data, fw->size); release_firmware(fw); if (ret) { pr_err("firmware upload error\n"); goto fw_load_fail; } } if (qtnf_poll_state(&priv->bda->bda_ep_state, QTN_EP_FW_DONE, QTN_FW_DL_TIMEOUT_MS)) { pr_err("firmware bringup timed out\n"); goto fw_load_fail; } bus->fw_state = QTNF_FW_STATE_FW_DNLD_DONE; pr_info("firmware is up and running\n"); if (qtnf_poll_state(&priv->bda->bda_ep_state, QTN_EP_FW_QLINK_DONE, QTN_FW_QLINK_TIMEOUT_MS)) { pr_err("firmware runtime failure\n"); goto fw_load_fail; } ret = qtnf_core_attach(bus); if (ret) { pr_err("failed to attach core\n"); goto fw_load_fail; } qtnf_debugfs_init(bus, DRV_NAME); qtnf_debugfs_add_entry(bus, "mps", qtnf_dbg_mps_show); qtnf_debugfs_add_entry(bus, "msi_enabled", qtnf_dbg_msi_show); qtnf_debugfs_add_entry(bus, "hdp_stats", qtnf_dbg_hdp_stats); qtnf_debugfs_add_entry(bus, "irq_stats", qtnf_dbg_irq_stats); qtnf_debugfs_add_entry(bus, "shm_stats", qtnf_dbg_shm_stats); goto fw_load_exit; fw_load_fail: bus->fw_state = QTNF_FW_STATE_DETACHED; fw_load_exit: complete(&bus->firmware_init_complete); put_device(&pdev->dev); }