/** * @brief This function downloads firmware image, gets * HW spec from firmware and set basic parameters to * firmware. * * @param priv A pointer to wlan_private structure * @return WLAN_STATUS_SUCCESS or WLAN_STATUS_FAILURE */ int wlan_download_firmware(void) { int ret = WLAN_STATUS_SUCCESS; sbi_disable_host_int(); /* Download the helper */ // ret= sbi_prog_firmware_image((u8*)helpgspibin, sizeof(helpgspibin)); ret= sbi_prog_firmware_file("/helper.bin"); if (ret) { WlanDebug(WlanErr,"download helper failed!\n"); ret = WLAN_STATUS_FAILURE; goto done; } /* Download firmware */ // if (sbi_download_wlan_fw_image((u8*)gspi8686bin, sizeof(gspi8686bin))) ret = sbi_download_wlan_fw_file("/fw.bin"); if (ret) { WlanDebug(WlanErr,"download firmware failed\n"); ret = WLAN_STATUS_FAILURE; goto done; } /* check if the fimware is downloaded successfully or not */ if (sbi_verify_fw_download()) { WlanDebug(WlanErr, "FW failed to be active in time!\n"); ret = WLAN_STATUS_FAILURE; goto done; } sbi_enable_host_int(); ret = WLAN_STATUS_SUCCESS; done: return (ret); }
/** * @brief request_firmware callback * * @param fw_firmware A pointer to firmware structure * @param context A Pointer to bt_private structure * @return BT_STATUS_SUCCESS or BT_STATUS_FAILURE */ static int sd_request_fw_dpc(const struct firmware *fw_firmware, void *context) { int ret = BT_STATUS_SUCCESS; bt_private *priv = (bt_private *) context; struct sdio_mmc_card *card = NULL; struct hci_dev *hdev = NULL; struct timeval tstamp; ENTER(); if ((priv == NULL) || (priv->adapter == NULL) || (priv->bt_dev.card == NULL) || (priv->bt_dev.hcidev == NULL)) { LEAVE(); return BT_STATUS_FAILURE; } card = (struct sdio_mmc_card *) priv->bt_dev.card; hdev = priv->bt_dev.hcidev; if (!fw_firmware) { do_gettimeofday(&tstamp); if (tstamp.tv_sec > (priv->req_fw_time.tv_sec + REQUEST_FW_TIMEOUT)) { PRINTM(ERROR, "BT: No firmware image found. Skipping download\n"); ret = BT_STATUS_FAILURE; goto done; } PRINTM(ERROR, "BT: No firmware image found! Retrying download\n"); /* Wait a second here before calling the callback again */ os_sched_timeout(1000); sd_download_firmware_w_helper(priv); LEAVE(); return ret; } priv->firmware = fw_firmware; if (BT_STATUS_FAILURE == sd_init_fw_dpc(priv)) { PRINTM(ERROR, "BT: sd_init_fw_dpc failed (download fw with nowait: %d). Terminating download\n", req_fw_nowait); ret = BT_STATUS_FAILURE; goto done; } /* check if the fimware is downloaded successfully or not */ if (sd_verify_fw_download(priv, MAX_FIRMWARE_POLL_TRIES)) { PRINTM(ERROR, "BT: FW failed to be active in time!\n"); ret = BT_STATUS_FAILURE; goto done; } sdio_release_host(card->func); sbi_enable_host_int(priv); if (BT_STATUS_FAILURE == sd_register_conf_dpc(priv)) { PRINTM(ERROR, "BT: sd_register_conf_dpc failed. Terminating download\n"); ret = BT_STATUS_FAILURE; goto done; } if (fw_firmware) { #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32) if (!req_fw_nowait) #endif release_firmware(fw_firmware); } LEAVE(); return ret; done: if (fw_firmware) { #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32) if (!req_fw_nowait) #endif release_firmware(fw_firmware); } hdev->dev = *priv->hotplug_device; /* For synchronous download cleanup will be done in add_card */ if (!req_fw_nowait) return ret; sdio_release_host(card->func); PRINTM(INFO, "unregister device\n"); sbi_unregister_dev(priv); ((struct sdio_mmc_card *) card)->priv = NULL; /* Stop the thread servicing the interrupts */ priv->adapter->SurpriseRemoved = TRUE; wake_up_interruptible(&priv->MainThread.waitQ); while (priv->MainThread.pid) { os_sched_timeout(1); } if (hdev) hci_free_dev(hdev); if (priv->adapter) bt_free_adapter(priv); kfree(priv); LEAVE(); return ret; }
/** * @brief This function initializes firmware * * @param priv A pointer to bt_private structure * @return BT_STATUS_SUCCESS or BT_STATUS_FAILURE */ int sbi_download_fw(bt_private * priv) { struct sdio_mmc_card *card = priv->bt_dev.card; int ret = BT_STATUS_SUCCESS; int poll_num = MAX_FIRMWARE_POLL_TRIES; u8 winner = 0; ENTER(); if (!card || !card->func) { PRINTM(ERROR, "BT: card or function is NULL!\n"); ret = BT_STATUS_FAILURE; goto exit; } sdio_claim_host(card->func); if (BT_STATUS_SUCCESS == sd_verify_fw_download(priv, 1)) { PRINTM(MSG, "BT: FW already downloaded!\n"); sdio_release_host(card->func); sbi_enable_host_int(priv); if (BT_STATUS_FAILURE == sd_register_conf_dpc(priv)) { PRINTM(ERROR, "BT: sd_register_conf_dpc failed. Terminating download\n"); ret = BT_STATUS_FAILURE; } goto exit; } /* Check if other interface is downloading */ ret = sd_check_winner_status(priv, &winner); if (ret == BT_STATUS_FAILURE) { PRINTM(FATAL, "BT read winner status failed!\n"); goto done; } if (winner) { PRINTM(MSG, "BT is not the winner (0x%x). Skip FW download\n", winner); poll_num = MAX_MULTI_INTERFACE_POLL_TRIES; /* check if the fimware is downloaded successfully or not */ if (sd_verify_fw_download(priv, poll_num)) { PRINTM(FATAL, "BT: FW failed to be active in time!\n"); ret = BT_STATUS_FAILURE; goto done; } sdio_release_host(card->func); sbi_enable_host_int(priv); if (BT_STATUS_FAILURE == sd_register_conf_dpc(priv)) { PRINTM(ERROR, "BT: sd_register_conf_dpc failed. Terminating download\n"); ret = BT_STATUS_FAILURE; } goto exit; } do_gettimeofday(&priv->req_fw_time); /* Download the main firmware via the helper firmware */ if (sd_download_firmware_w_helper(priv)) { PRINTM(INFO, "BT: FW download failed!\n"); ret = BT_STATUS_FAILURE; goto done; } goto exit; done: sdio_release_host(card->func); exit: LEAVE(); return ret; }
/** * @brief This function initializes firmware * * @param priv A pointer to wlan_private structure * @return WLAN_STATUS_SUCCESS or WLAN_STATUS_FAILURE */ int wlan_init_fw(wlan_private * priv) { int ret = WLAN_STATUS_SUCCESS; wlan_adapter *Adapter = priv->adapter; ENTER(); sbi_disable_host_int(priv); /* Check if firmware is already running */ if (sbi_check_fw_status(priv, 1) == WLAN_STATUS_SUCCESS) { PRINTM(MSG, "WLAN FW already running! Skip FW download\n"); } else { if ((ret = request_firmware(&priv->fw_helper, helper_name, priv->hotplug_device)) < 0) { PRINTM(FATAL, "request_firmware() failed (helper), error code = %#x\n", ret); goto done; } /* Download the helper */ ret = sbi_prog_helper(priv); if (ret) { PRINTM(INFO, "Bootloader in invalid state! Helper download failed!\n"); ret = WLAN_STATUS_FAILURE; goto done; } if ((ret = request_firmware(&priv->firmware, fw_name, priv->hotplug_device)) < 0) { PRINTM(FATAL, "request_firmware() failed, error code = %#x\n", ret); goto done; } /* Download the main firmware via the helper firmware */ if (sbi_prog_fw_w_helper(priv)) { PRINTM(INFO, "Wlan FW download failed!\n"); ret = WLAN_STATUS_FAILURE; goto done; } /* Check if the firmware is downloaded successfully or not */ if (sbi_check_fw_status(priv, MAX_FIRMWARE_POLL_TRIES) == WLAN_STATUS_FAILURE) { PRINTM(FATAL, "FW failed to be active in time!\n"); ret = WLAN_STATUS_FAILURE; goto done; } PRINTM(MSG, "WLAN FW is active\n"); } #define RF_REG_OFFSET 0x07 #define RF_REG_VALUE 0xc8 sbi_enable_host_int(priv); #ifdef MFG_CMD_SUPPORT if (mfgmode == 0) { #endif ret = wlan_prepare_cmd(priv, HostCmd_CMD_FUNC_INIT, 0, HostCmd_OPTION_WAITFORRSP | HostCmd_OPTION_TIMEOUT, 0, NULL); /* * Read MAC address from HW */ memset(Adapter->CurrentAddr, 0xff, ETH_ALEN); ret = wlan_prepare_cmd(priv, HostCmd_CMD_GET_HW_SPEC, 0, HostCmd_OPTION_WAITFORRSP | HostCmd_OPTION_TIMEOUT, 0, NULL); if (ret) { ret = WLAN_STATUS_FAILURE; goto done; } ret = wlan_prepare_cmd(priv, HostCmd_CMD_MAC_CONTROL, 0, HostCmd_OPTION_WAITFORRSP | HostCmd_OPTION_TIMEOUT, 0, &Adapter->CurrentPacketFilter); if (ret) { ret = WLAN_STATUS_FAILURE; goto done; } ret = wlan_prepare_cmd(priv, HostCmd_CMD_802_11_RATE_ADAPT_RATESET, HostCmd_ACT_GEN_GET, HostCmd_OPTION_WAITFORRSP | HostCmd_OPTION_TIMEOUT, 0, NULL); if (ret) { ret = WLAN_STATUS_FAILURE; goto done; } priv->adapter->DataRate = 0; ret = wlan_prepare_cmd(priv, HostCmd_CMD_802_11_RF_TX_POWER, HostCmd_ACT_GEN_GET, HostCmd_OPTION_WAITFORRSP | HostCmd_OPTION_TIMEOUT, 0, NULL); if (ret) { ret = WLAN_STATUS_FAILURE; goto done; } #ifdef MFG_CMD_SUPPORT } #endif Adapter->HardwareStatus = WlanHardwareStatusReady; ret = WLAN_STATUS_SUCCESS; done: if (priv->fw_helper) release_firmware(priv->fw_helper); if (priv->firmware) release_firmware(priv->firmware); if (ret != WLAN_STATUS_SUCCESS) { Adapter->HardwareStatus = WlanHardwareStatusNotReady; ret = WLAN_STATUS_FAILURE; } LEAVE(); return ret; }
/** * @brief This function downloads firmware image, gets * HW spec from firmware and set basic parameters to * firmware. * * @param priv A pointer to wlan_private structure * @return WLAN_STATUS_SUCCESS or WLAN_STATUS_FAILURE */ int wlan_setup_station_hw(wlan_private * priv) { int ret = WLAN_STATUS_SUCCESS; wlan_adapter *adapter = priv->adapter; struct net_device *dev = priv->wlan_dev.netdev; ENTER(); if (netif_running(dev)) netif_device_detach(dev); sbi_disable_host_int(priv); /* Download the helper */ ret = sbi_prog_helper(priv); if (ret) { PRINTM(INFO, "Bootloader in invalid state!\n"); ret = WLAN_STATUS_FAILURE; goto done; } /* Download the main firmware via the helper firmware */ if (sbi_prog_firmware_w_helper(priv)) { PRINTM(INFO, "Wlan FW download failed!\n"); ret = WLAN_STATUS_FAILURE; goto done; } /* check if the fimware is downloaded successfully or not */ if (sbi_verify_fw_download(priv)) { PRINTM(INFO, "FW failed to be active in time!\n"); ret = WLAN_STATUS_FAILURE; goto done; } priv->adapter->fwstate = FW_STATE_READY; if (netif_running(dev)) netif_device_attach(dev); #define RF_REG_OFFSET 0x07 #define RF_REG_VALUE 0xc8 sbi_enable_host_int(priv); #ifdef MFG_CMD_SUPPORT if (mfgmode == 0) { #endif /* * Read MAC address from HW */ memset(adapter->CurrentAddr, 0xff, MRVDRV_ETH_ADDR_LEN); ret = PrepareAndSendCommand(priv, HostCmd_CMD_GET_HW_SPEC, 0, HostCmd_OPTION_WAITFORRSP, 0, NULL); if (ret) { ret = WLAN_STATUS_FAILURE; goto done; } SetMacPacketFilter(priv); ret = PrepareAndSendCommand(priv, HostCmd_CMD_802_11_FW_WAKEUP_METHOD, HostCmd_ACT_GET, HostCmd_OPTION_WAITFORRSP, 0, &priv->adapter->fwWakeupMethod); if (ret) { ret = WLAN_STATUS_FAILURE; goto done; } #ifdef MFG_CMD_SUPPORT } #endif #ifdef MFG_CMD_SUPPORT if (mfgmode == 0) { #endif ret = PrepareAndSendCommand(priv, HostCmd_CMD_802_11_RATE_ADAPT_RATESET, HostCmd_ACT_GEN_GET, HostCmd_OPTION_WAITFORRSP, 0, NULL); if (ret) { ret = WLAN_STATUS_FAILURE; goto done; } priv->adapter->DataRate = 0; ret = PrepareAndSendCommand(priv, HostCmd_CMD_802_11_RF_TX_POWER, HostCmd_ACT_GEN_GET, HostCmd_OPTION_WAITFORRSP, 0, NULL); if (ret) { ret = WLAN_STATUS_FAILURE; goto done; } #ifdef MFG_CMD_SUPPORT } #endif ret = WLAN_STATUS_SUCCESS; done: LEAVE(); return (ret); }