linux/drivers/staging/csr/init_hw.c
<<
>>
Prefs
   1/*
   2 * ---------------------------------------------------------------------------
   3 * FILE:     init_hw.c
   4 *
   5 * PURPOSE:
   6 *      Use the HIP core lib to initialise the UniFi chip.
   7 *      It is part of the porting exercise in Linux.
   8 *
   9 * Copyright (C) 2009 by Cambridge Silicon Radio Ltd.
  10 *
  11 * Refer to LICENSE.txt included with this source code for details on
  12 * the license terms.
  13 *
  14 * ---------------------------------------------------------------------------
  15 */
  16#include "csr_wifi_hip_unifi.h"
  17#include "unifi_priv.h"
  18
  19
  20#define MAX_INIT_ATTEMPTS        4
  21
  22extern int led_mask;
  23
  24
  25/*
  26 * ---------------------------------------------------------------------------
  27 *  uf_init_hw
  28 *
  29 *      Resets hardware, downloads and initialises f/w.
  30 *      This function demonstrates how to use the HIP core lib API
  31 *      to implement the SME unifi_sys_wifi_on_req() part of the SYS API.
  32 *
  33 *      In a simple implementation, all this function needs to do is call
  34 *      unifi_init_card() and then unifi_card_info().
  35 *      In the Linux implementation, it will retry to initialise UniFi or
  36 *      try to debug the reasons if unifi_init_card() returns an error.
  37 *
  38 *  Arguments:
  39 *      ospriv          Pointer to OS driver structure for the device.
  40 *
  41 *  Returns:
  42 *      O on success, non-zero otherwise.
  43 *
  44 * ---------------------------------------------------------------------------
  45 */
  46int
  47uf_init_hw(unifi_priv_t *priv)
  48{
  49    int attempts = 0;
  50    int priv_instance;
  51    CsrResult csrResult = CSR_RESULT_FAILURE;
  52
  53    priv_instance = uf_find_priv(priv);
  54    if (priv_instance == -1) {
  55        unifi_warning(priv, "uf_init_hw: Unknown priv instance, will use fw_init[0]\n");
  56        priv_instance = 0;
  57    }
  58
  59    while (1) {
  60        if (attempts > MAX_INIT_ATTEMPTS) {
  61            unifi_error(priv, "Failed to initialise UniFi after %d attempts, "
  62                        "giving up.\n",
  63                        attempts);
  64            break;
  65        }
  66        attempts++;
  67
  68        unifi_info(priv, "Initialising UniFi, attempt %d\n", attempts);
  69
  70        if (fw_init[priv_instance] > 0) {
  71            unifi_notice(priv, "f/w init prevented by module parameter\n");
  72            break;
  73        } else if (fw_init[priv_instance] == 0) {
  74            fw_init[priv_instance] ++;
  75        }
  76
  77        /*
  78         * Initialise driver core. This will perform a reset of UniFi
  79         * internals, but not the SDIO CCCR.
  80         */
  81        CsrSdioClaim(priv->sdio);
  82        csrResult = unifi_init_card(priv->card, led_mask);
  83        CsrSdioRelease(priv->sdio);
  84
  85        if (csrResult == CSR_WIFI_HIP_RESULT_NO_DEVICE) {
  86            return CsrHipResultToStatus(csrResult);
  87        }
  88        if (csrResult == CSR_WIFI_HIP_RESULT_NOT_FOUND) {
  89            unifi_error(priv, "Firmware file required, but not found.\n");
  90            return CsrHipResultToStatus(csrResult);
  91        }
  92        if (csrResult != CSR_RESULT_SUCCESS) {
  93            /* failed. Reset h/w and try again */
  94            unifi_error(priv, "Failed to initialise UniFi chip.\n");
  95            continue;
  96        }
  97
  98        /* Get the version information from the lib_hip */
  99        unifi_card_info(priv->card, &priv->card_info);
 100
 101        return CsrHipResultToStatus(csrResult);
 102    }
 103
 104    return CsrHipResultToStatus(csrResult);
 105
 106} /* uf_init_hw */
 107
 108
 109