/* * --------------------------------------------------------------------------- * FILE: init_hw.c * * PURPOSE: * Use the HIP core lib to initialise the UniFi chip. * It is part of the porting exercise in Linux. * * Copyright (C) 2009 by Cambridge Silicon Radio Ltd. * * Refer to LICENSE.txt included with this source code for details on * the license terms. * * --------------------------------------------------------------------------- */ #include "csr_wifi_hip_unifi.h" #include "unifi_priv.h" #define MAX_INIT_ATTEMPTS 4 extern int led_mask; /* * --------------------------------------------------------------------------- * uf_init_hw * * Resets hardware, downloads and initialises f/w. * This function demonstrates how to use the HIP core lib API * to implement the SME unifi_sys_wifi_on_req() part of the SYS API. * * In a simple implementation, all this function needs to do is call * unifi_init_card() and then unifi_card_info(). * In the Linux implementation, it will retry to initialise UniFi or * try to debug the reasons if unifi_init_card() returns an error. * * Arguments: * ospriv Pointer to OS driver structure for the device. * * Returns: * O on success, non-zero otherwise. * * --------------------------------------------------------------------------- */ int uf_init_hw(unifi_priv_t *priv) { int attempts = 0; int priv_instance; CsrResult csrResult = CSR_RESULT_FAILURE; priv_instance = uf_find_priv(priv); if (priv_instance == -1) { unifi_warning(priv, "uf_init_hw: Unknown priv instance, will use fw_init[0]\n"); priv_instance = 0; } while (1) { if (attempts > MAX_INIT_ATTEMPTS) { unifi_error(priv, "Failed to initialise UniFi after %d attempts, " "giving up.\n", attempts); break; } attempts++; unifi_info(priv, "Initialising UniFi, attempt %d\n", attempts); if (fw_init[priv_instance] > 0) { unifi_notice(priv, "f/w init prevented by module parameter\n"); break; } else if (fw_init[priv_instance] == 0) { fw_init[priv_instance] ++; } /* * Initialise driver core. This will perform a reset of UniFi * internals, but not the SDIO CCCR. */ CsrSdioClaim(priv->sdio); csrResult = unifi_init_card(priv->card, led_mask); CsrSdioRelease(priv->sdio); if (csrResult == CSR_WIFI_HIP_RESULT_NO_DEVICE) { return CsrHipResultToStatus(csrResult); } if (csrResult == CSR_WIFI_HIP_RESULT_NOT_FOUND) { unifi_error(priv, "Firmware file required, but not found.\n"); return CsrHipResultToStatus(csrResult); } if (csrResult != CSR_RESULT_SUCCESS) { /* failed. Reset h/w and try again */ unifi_error(priv, "Failed to initialise UniFi chip.\n"); continue; } /* Get the version information from the lib_hip */ unifi_card_info(priv->card, &priv->card_info); return CsrHipResultToStatus(csrResult); } return CsrHipResultToStatus(csrResult); } /* uf_init_hw */