/*
 * ---------------------------------------------------------------------------
 *  FILE:     io.c
 *
 *  PURPOSE:
 *      This file contains routines that the SDIO driver can call when a
 *      UniFi card is first inserted (or detected) and removed.
 *
 *      When used with sdioemb, the udev scripts (at least on Ubuntu) don't
 *      recognise a UniFi being added to the system. This is because sdioemb
 *      does not register itself as a device_driver, it uses it's own code
 *      to handle insert and remove.
 *      To have Ubuntu recognise UniFi, edit /etc/udev/rules.d/85-ifupdown.rules
 *      to change this line:
 *          SUBSYSTEM=="net", DRIVERS=="?*", GOTO="net_start"
 *      to these:
 *          #SUBSYSTEM=="net", DRIVERS=="?*", GOTO="net_start"
 *          SUBSYSTEM=="net", GOTO="net_start"
 *
 *      Then you can add a stanza to /etc/network/interfaces like this:
 *          auto eth1
 *          iface eth1 inet dhcp
 *          wpa-conf /etc/wpa_supplicant.conf
 *      This will then automatically associate when a car dis inserted.
 *
 * Copyright (C) 2006-2009 by Cambridge Silicon Radio Ltd.
 *
 * Refer to LICENSE.txt included with this source code for details on
 * the license terms.
 *
 * ---------------------------------------------------------------------------
 */
#include <linux/proc_fs.h>

#include "csr_wifi_hip_unifi.h"
#include "csr_wifi_hip_unifiversion.h"
#include "csr_wifi_hip_unifi_udi.h"   /* for unifi_print_status() */
#include "unifiio.h"
#include "unifi_priv.h"

/*
 * Array of pointers to context structs for unifi devices that are present.
 * The index in the array corresponds to the wlan interface number
 * (if "wlan*" is used). If "eth*" is used, the eth* numbers are allocated
 * after any Ethernet cards.
 *
 * The Arasan PCI-SDIO controller card supported by this driver has 2 slots,
 * hence a max of 2 devices.
 */
static unifi_priv_t *Unifi_instances[MAX_UNIFI_DEVS];

/* Array of pointers to netdev objects used by the UniFi driver, as there
 * are now many per instance. This is used to determine which netdev events
 * are for UniFi as opposed to other net interfaces.
 */
static netInterface_priv_t *Unifi_netdev_instances[MAX_UNIFI_DEVS * CSR_WIFI_NUM_INTERFACES];

/*
 * Array to hold the status of each unifi device in each slot.
 * We only process an insert event when In_use[] for the slot is
 * UNIFI_DEV_NOT_IN_USE. Otherwise, it means that the slot is in use or
 * we are in the middle of a cleanup (the action on unplug).
 */
#define UNIFI_DEV_NOT_IN_USE    0
#define UNIFI_DEV_IN_USE        1
#define UNIFI_DEV_CLEANUP       2
static int In_use[MAX_UNIFI_DEVS];
/*
 * Mutex to prevent UDI clients to open the character device before the priv
 * is created and initialised.
 */
DEFINE_SEMAPHORE(Unifi_instance_mutex);
/*
 * When the device is removed, unregister waits on Unifi_cleanup_wq
 * until all the UDI clients release the character device.
 */
DECLARE_WAIT_QUEUE_HEAD(Unifi_cleanup_wq);


static int uf_read_proc(char *page, char **start, off_t offset, int count,
                        int *eof, void *data);

#ifdef CSR_WIFI_RX_PATH_SPLIT

static CsrResult signal_buffer_init(unifi_priv_t * priv, int size)
{
    int i;

    priv->rxSignalBuffer.writePointer =
    priv->rxSignalBuffer.readPointer = 0;
    priv->rxSignalBuffer.size = size;
    /* Allocating Memory for Signal primitive pointer */
    for(i=0; i<size; i++)
    {
         priv->rxSignalBuffer.rx_buff[i].sig_len=0;
         priv->rxSignalBuffer.rx_buff[i].bufptr = kmalloc(UNIFI_PACKED_SIGBUF_SIZE, GFP_KERNEL);
         if (priv->rxSignalBuffer.rx_buff[i].bufptr == NULL)
         {
             int j;
             unifi_error(priv,"signal_buffer_init:Failed to Allocate shared memory for T-H signals \n");
             for(j=0;j<i;j++)
             {
                 priv->rxSignalBuffer.rx_buff[j].sig_len=0;
                 kfree(priv->rxSignalBuffer.rx_buff[j].bufptr);
                 priv->rxSignalBuffer.rx_buff[j].bufptr = NULL;
             }
             return -1;
         }
    }
    return 0;
}


static void signal_buffer_free(unifi_priv_t * priv, int size)
{
    int i;

    for(i=0; i<size; i++)
    {
         priv->rxSignalBuffer.rx_buff[i].sig_len=0;
         kfree(priv->rxSignalBuffer.rx_buff[i].bufptr);
         priv->rxSignalBuffer.rx_buff[i].bufptr = NULL;
    }
}
#endif
/*
 * ---------------------------------------------------------------------------
 *  uf_register_netdev
 *
 *      Registers the network interface, installes the qdisc,
 *      and registers the inet handler.
 *      In the porting exercise, register the driver to the network
 *      stack if necessary.
 *
 *  Arguments:
 *      priv          Pointer to driver context.
 *
 *  Returns:
 *      O on success, non-zero otherwise.
 *
 *  Notes:
 *      We will only unregister when the card is ejected, so we must
 *      only do it once.
 * ---------------------------------------------------------------------------
 */
int
uf_register_netdev(unifi_priv_t *priv, int interfaceTag)
{
    int r;
    netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];

    if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
        unifi_error(priv, "uf_register_netdev bad interfaceTag\n");
        return -EINVAL;
    }

    /*
     * Allocates a device number and registers device with the network
     * stack.
     */
    unifi_trace(priv, UDBG5, "uf_register_netdev: netdev %d - 0x%p\n",
            interfaceTag, priv->netdev[interfaceTag]);
    r = register_netdev(priv->netdev[interfaceTag]);
    if (r) {
        unifi_error(priv, "Failed to register net device\n");
        return -EINVAL;
    }

    /* The device is registed */
    interfacePriv->netdev_registered = 1;

#ifdef CSR_SUPPORT_SME
    /*
     * Register the inet handler; it notifies us for changes in the IP address.
     */
    uf_register_inet_notifier();
#endif /* CSR_SUPPORT_SME */

    unifi_notice(priv, "unifi%d is %s\n",
            priv->instance, priv->netdev[interfaceTag]->name);

    return 0;
} /* uf_register_netdev */


/*
 * ---------------------------------------------------------------------------
 *  uf_unregister_netdev
 *
 *      Unregisters the network interface and the inet handler.
 *
 *  Arguments:
 *      priv          Pointer to driver context.
 *
 *  Returns:
 *      None.
 *
 * ---------------------------------------------------------------------------
 */
void
uf_unregister_netdev(unifi_priv_t *priv)
{
    int i=0;

#ifdef CSR_SUPPORT_SME
    /* Unregister the inet handler... */
    uf_unregister_inet_notifier();
#endif /* CSR_SUPPORT_SME */

    for (i=0; i<CSR_WIFI_NUM_INTERFACES; i++) {
        netInterface_priv_t *interfacePriv = priv->interfacePriv[i];
        if (interfacePriv->netdev_registered) {
            unifi_trace(priv, UDBG5,
                    "uf_unregister_netdev: netdev %d - 0x%p\n",
                    i, priv->netdev[i]);

            /* ... and the netdev */
            unregister_netdev(priv->netdev[i]);
            interfacePriv->netdev_registered = 0;
        }

        interfacePriv->interfaceMode = 0;

        /* Enable all queues by default */
        interfacePriv->queueEnabled[0] = 1;
        interfacePriv->queueEnabled[1] = 1;
        interfacePriv->queueEnabled[2] = 1;
        interfacePriv->queueEnabled[3] = 1;
    }

    priv->totalInterfaceCount = 0;
} /* uf_unregister_netdev() */


/*
 * ---------------------------------------------------------------------------
 *  register_unifi_sdio
 *
 *      This function is called from the Probe (or equivalent) method of
 *      the SDIO driver when a UniFi card is detected.
 *      We allocate the Linux net_device struct, initialise the HIP core
 *      lib, create the char device nodes and start the userspace helper
 *      to initialise the device.
 *
 *  Arguments:
 *      sdio_dev        Pointer to SDIO context handle to use for all
 *                      SDIO ops.
 *      bus_id          A small number indicating the SDIO card position on the
 *                      bus. Typically this is the slot number, e.g. 0, 1 etc.
 *                      Valid values are 0 to MAX_UNIFI_DEVS-1.
 *      dev             Pointer to kernel device manager struct.
 *
 *  Returns:
 *      Pointer to the unifi instance, or NULL on error.
 * ---------------------------------------------------------------------------
 */
static unifi_priv_t *
register_unifi_sdio(CsrSdioFunction *sdio_dev, int bus_id, struct device *dev)
{
    unifi_priv_t *priv = NULL;
    int r = -1;
    CsrResult csrResult;

    if ((bus_id < 0) || (bus_id >= MAX_UNIFI_DEVS)) {
        unifi_error(priv, "register_unifi_sdio: invalid device %d\n",
                bus_id);
        return NULL;
    }

    down(&Unifi_instance_mutex);

    if (In_use[bus_id] != UNIFI_DEV_NOT_IN_USE) {
        unifi_error(priv, "register_unifi_sdio: device %d is already in use\n",
                bus_id);
        goto failed0;
    }


    /* Allocate device private and net_device structs */
    priv = uf_alloc_netdevice(sdio_dev, bus_id);
    if (priv == NULL) {
        unifi_error(priv, "Failed to allocate driver private\n");
        goto failed0;
    }

    priv->unifi_device = dev;

    SET_NETDEV_DEV(priv->netdev[0], dev);

    /* We are not ready to send data yet. */
    netif_carrier_off(priv->netdev[0]);

    /* Allocate driver context. */
    priv->card = unifi_alloc_card(priv->sdio, priv);
    if (priv->card == NULL) {
        unifi_error(priv, "Failed to allocate UniFi driver card struct.\n");
        goto failed1;
    }

    if (Unifi_instances[bus_id]) {
        unifi_error(priv, "Internal error: instance for slot %d is already taken\n",
                bus_id);
    }
    Unifi_instances[bus_id] = priv;
    In_use[bus_id] = UNIFI_DEV_IN_USE;

    /* Save the netdev_priv for use by the netdev event callback mechanism */
    Unifi_netdev_instances[bus_id * CSR_WIFI_NUM_INTERFACES] = netdev_priv(priv->netdev[0]);

    /* Initialise the mini-coredump capture buffers */
    csrResult = unifi_coredump_init(priv->card, (u16)coredump_max);
    if (csrResult != CSR_RESULT_SUCCESS) {
        unifi_error(priv, "Couldn't allocate mini-coredump buffers\n");
    }

    /* Create the character device nodes */
    r = uf_create_device_nodes(priv, bus_id);
    if (r) {
        goto failed1;
    }

    /*
     * We use the slot number as unifi device index.
     */
    scnprintf(priv->proc_entry_name, 64, "driver/unifi%d", priv->instance);
    /*
     * The following complex casting is in place in order to eliminate 64-bit compilation warning
     * "cast to/from pointer from/to integer of different size"
     */
    if (!create_proc_read_entry(priv->proc_entry_name, 0, 0,
                uf_read_proc, (void *)(long)priv->instance))
    {
        unifi_error(priv, "unifi: can't create /proc/driver/unifi\n");
    }

    /* Allocate the net_device for interfaces other than 0. */
    {
        int i;
        priv->totalInterfaceCount =0;

        for(i=1;i<CSR_WIFI_NUM_INTERFACES;i++)
        {
            if( !uf_alloc_netdevice_for_other_interfaces(priv,i) )
            {
                /* error occured while allocating the net_device for interface[i]. The net_device are
                 * allocated for the interfaces with id<i. Dont worry, all the allocated net_device will
                 * be releasing chen the control goes to the label failed0.
                 */
                unifi_error(priv, "Failed to allocate driver private for interface[%d]\n",i);
                goto failed0;
            }
            else
            {
                SET_NETDEV_DEV(priv->netdev[i], dev);

                /* We are not ready to send data yet. */
                netif_carrier_off(priv->netdev[i]);

                /* Save the netdev_priv for use by the netdev event callback mechanism */
                Unifi_netdev_instances[bus_id * CSR_WIFI_NUM_INTERFACES + i] = netdev_priv(priv->netdev[i]);
            }
        }

        for(i=0;i<CSR_WIFI_NUM_INTERFACES;i++)
        {
            netInterface_priv_t *interfacePriv = priv->interfacePriv[i];
            interfacePriv->netdev_registered=0;
        }
    }

#ifdef CSR_WIFI_RX_PATH_SPLIT
    if (signal_buffer_init(priv, CSR_WIFI_RX_SIGNAL_BUFFER_SIZE))
    {
        unifi_error(priv,"Failed to allocate shared memory for T-H signals\n");
        goto failed2;
    }
    priv->rx_workqueue = create_singlethread_workqueue("rx_workq");
    if (priv->rx_workqueue == NULL) {
        unifi_error(priv,"create_singlethread_workqueue failed \n");
        goto failed3;
    }
    INIT_WORK(&priv->rx_work_struct, rx_wq_handler);
#endif

#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
    if (log_hip_signals)
    {
        uf_register_hip_offline_debug(priv);
    }
#endif

    /* Initialise the SME related threads and parameters */
    r = uf_sme_init(priv);
    if (r) {
        unifi_error(priv, "SME initialisation failed.\n");
        goto failed4;
    }

    /*
     * Run the userspace helper program (unififw) to perform
     * the device initialisation.
     */
    unifi_trace(priv, UDBG1, "run UniFi helper app...\n");
    r = uf_run_unifihelper(priv);
    if (r) {
        unifi_notice(priv, "unable to run UniFi helper app\n");
        /* Not a fatal error. */
    }

    up(&Unifi_instance_mutex);

    return priv;

failed4:
#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
if (log_hip_signals)
{
    uf_unregister_hip_offline_debug(priv);
}
#endif
#ifdef CSR_WIFI_RX_PATH_SPLIT
    flush_workqueue(priv->rx_workqueue);
    destroy_workqueue(priv->rx_workqueue);
failed3:
    signal_buffer_free(priv,CSR_WIFI_RX_SIGNAL_BUFFER_SIZE);
failed2:
#endif
    /* Remove the device nodes */
    uf_destroy_device_nodes(priv);
failed1:
    /* Deregister priv->netdev_client */
    ul_deregister_client(priv->netdev_client);

failed0:
    if (priv && priv->card) {
        unifi_coredump_free(priv->card);
        unifi_free_card(priv->card);
    }
    if (priv) {
        uf_free_netdevice(priv);
    }

    up(&Unifi_instance_mutex);

    return NULL;
} /* register_unifi_sdio() */


/*
 * ---------------------------------------------------------------------------
 *  ask_unifi_sdio_cleanup
 *
 *      We can not free our private context, until all the char device
 *      clients have closed the file handles. unregister_unifi_sdio() which
 *      is called when a card is removed, waits on Unifi_cleanup_wq until
 *      the reference count becomes zero. It is time to wake it up now.
 *
 *  Arguments:
 *      priv          Pointer to driver context.
 *
 *  Returns:
 *      None.
 * ---------------------------------------------------------------------------
 */
static void
ask_unifi_sdio_cleanup(unifi_priv_t *priv)
{

    /*
     * Now clear the flag that says the old instance is in use.
     * This is used to prevent a new instance being started before old
     * one has finshed closing down, for example if bounce makes the card
     * appear to be ejected and re-inserted quickly.
     */
    In_use[priv->instance] = UNIFI_DEV_CLEANUP;

    unifi_trace(NULL, UDBG5, "ask_unifi_sdio_cleanup: wake up cleanup workqueue.\n");
    wake_up(&Unifi_cleanup_wq);

} /* ask_unifi_sdio_cleanup() */


/*
 * ---------------------------------------------------------------------------
 *  cleanup_unifi_sdio
 *
 *      Release any resources owned by a unifi instance.
 *
 *  Arguments:
 *      priv          Pointer to the instance to free.
 *
 *  Returns:
 *      None.
 * ---------------------------------------------------------------------------
 */
static void
cleanup_unifi_sdio(unifi_priv_t *priv)
{
    int priv_instance;
    int i;
    static const CsrWifiMacAddress broadcast_address = {{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}};

    /* Remove the device nodes */
    uf_destroy_device_nodes(priv);

    /* Mark this device as gone away by NULLing the entry in Unifi_instances */
    Unifi_instances[priv->instance] = NULL;

    unifi_trace(priv, UDBG5, "cleanup_unifi_sdio: remove_proc_entry\n");
    /*
     * Free the children of priv before unifi_free_netdevice() frees
     * the priv struct
     */
    remove_proc_entry(priv->proc_entry_name, 0);


    /* Unregister netdev as a client. */
    if (priv->netdev_client) {
        unifi_trace(priv, UDBG2, "Netdev client (id:%d s:0x%X) is unregistered\n",
                priv->netdev_client->client_id, priv->netdev_client->sender_id);
        ul_deregister_client(priv->netdev_client);
    }

    /* Destroy the SME related threads and parameters */
    uf_sme_deinit(priv);

#ifdef CSR_SME_USERSPACE
    priv->smepriv = NULL;
#endif

#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
    if (log_hip_signals)
    {
        uf_unregister_hip_offline_debug(priv);
    }
#endif

    /* Free any packets left in the Rx queues */
    for(i=0;i<CSR_WIFI_NUM_INTERFACES;i++)
    {
        uf_free_pending_rx_packets(priv, UF_UNCONTROLLED_PORT_Q, broadcast_address,i);
        uf_free_pending_rx_packets(priv, UF_CONTROLLED_PORT_Q, broadcast_address,i);
    }
    /*
     * We need to free the resources held by the core, which include tx skbs,
     * otherwise we can not call unregister_netdev().
     */
    if (priv->card) {
        unifi_trace(priv, UDBG5, "cleanup_unifi_sdio: free card\n");
        unifi_coredump_free(priv->card);
        unifi_free_card(priv->card);
        priv->card = NULL;
    }

    /*
     * Unregister the network device.
     * We can not unregister the netdev before we release
     * all pending packets in the core.
     */
    uf_unregister_netdev(priv);
    priv->totalInterfaceCount = 0;

    /* Clear the table of registered netdev_priv's */
    for (i = 0; i < CSR_WIFI_NUM_INTERFACES; i++) {
        Unifi_netdev_instances[priv->instance * CSR_WIFI_NUM_INTERFACES + i] = NULL;
    }

    unifi_trace(priv, UDBG5, "cleanup_unifi_sdio: uf_free_netdevice\n");
    /*
     * When uf_free_netdevice() returns, the priv is invalid
     * so we need to remember the instance to clear the global flag later.
     */
    priv_instance = priv->instance;

#ifdef CSR_WIFI_RX_PATH_SPLIT
    flush_workqueue(priv->rx_workqueue);
    destroy_workqueue(priv->rx_workqueue);
    signal_buffer_free(priv,CSR_WIFI_RX_SIGNAL_BUFFER_SIZE);
#endif

    /* Priv is freed as part of the net_device */
    uf_free_netdevice(priv);

    /*
     * Now clear the flag that says the old instance is in use.
     * This is used to prevent a new instance being started before old
     * one has finshed closing down, for example if bounce makes the card
     * appear to be ejected and re-inserted quickly.
     */
    In_use[priv_instance] = UNIFI_DEV_NOT_IN_USE;

    unifi_trace(NULL, UDBG5, "cleanup_unifi_sdio: DONE.\n");

} /* cleanup_unifi_sdio() */


/*
 * ---------------------------------------------------------------------------
 *  unregister_unifi_sdio
 *
 *      Call from SDIO driver when it detects that UniFi has been removed.
 *
 *  Arguments:
 *      bus_id          Number of the card that was ejected.
 *
 *  Returns:
 *      None.
 * ---------------------------------------------------------------------------
 */
static void
unregister_unifi_sdio(int bus_id)
{
    unifi_priv_t *priv;
    int interfaceTag=0;
    u8 reason = CONFIG_IND_EXIT;

    if ((bus_id < 0) || (bus_id >= MAX_UNIFI_DEVS)) {
        unifi_error(NULL, "unregister_unifi_sdio: invalid device %d\n",
                bus_id);
        return;
    }

    priv = Unifi_instances[bus_id];
    if (priv == NULL) {
        unifi_error(priv, "unregister_unifi_sdio: device %d is not registered\n",
                bus_id);
        return;
    }

    /* Stop the network traffic before freeing the core. */
    for(interfaceTag=0;interfaceTag<priv->totalInterfaceCount;interfaceTag++)
    {
        netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
        if(interfacePriv->netdev_registered)
        {
            netif_carrier_off(priv->netdev[interfaceTag]);
            netif_tx_stop_all_queues(priv->netdev[interfaceTag]);
        }
    }

#ifdef CSR_NATIVE_LINUX
    /*
     * If the unifi thread was started, signal it to stop.  This
     * should cause any userspace processes with open unifi device to
     * close them.
     */
    uf_stop_thread(priv, &priv->bh_thread);

    /* Unregister the interrupt handler */
    if (csr_sdio_linux_remove_irq(priv->sdio)) {
        unifi_notice(priv,
                "csr_sdio_linux_remove_irq failed to talk to card.\n");
    }

    /* Ensure no MLME functions are waiting on a the mlme_event semaphore. */
    uf_abort_mlme(priv);
#endif /* CSR_NATIVE_LINUX */

    ul_log_config_ind(priv, &reason, sizeof(u8));

    /* Deregister the UDI hook from the core. */
    unifi_remove_udi_hook(priv->card, logging_handler);

    uf_put_instance(bus_id);

    /*
     * Wait until the device is cleaned up. i.e., when all userspace
     * processes have closed any open unifi devices.
     */
    wait_event(Unifi_cleanup_wq, In_use[bus_id] == UNIFI_DEV_CLEANUP);
    unifi_trace(NULL, UDBG5, "Received clean up event\n");

    /* Now we can free the private context and the char device nodes */
    cleanup_unifi_sdio(priv);

} /* unregister_unifi_sdio() */


/*
 * ---------------------------------------------------------------------------
 *  uf_find_instance
 *
 *      Find the context structure for a given UniFi device instance.
 *
 *  Arguments:
 *      inst            The instance number to look for.
 *
 *  Returns:
 *      None.
 * ---------------------------------------------------------------------------
 */
unifi_priv_t *
uf_find_instance(int inst)
{
    if ((inst < 0) || (inst >= MAX_UNIFI_DEVS)) {
        return NULL;
    }
    return Unifi_instances[inst];
} /* uf_find_instance() */


/*
 * ---------------------------------------------------------------------------
 *  uf_find_priv
 *
 *      Find the device instance for a given context structure.
 *
 *  Arguments:
 *      priv            The context structure pointer to look for.
 *
 *  Returns:
 *      index of instance, -1 otherwise.
 * ---------------------------------------------------------------------------
 */
int
uf_find_priv(unifi_priv_t *priv)
{
    int inst;

    if (!priv) {
        return -1;
    }

    for (inst = 0; inst < MAX_UNIFI_DEVS; inst++) {
        if (Unifi_instances[inst] == priv) {
            return inst;
        }
    }

    return -1;
} /* uf_find_priv() */

/*
 * ---------------------------------------------------------------------------
 *  uf_find_netdev_priv
 *
 *      Find the device instance for a given netdev context structure.
 *
 *  Arguments:
 *      priv            The context structure pointer to look for.
 *
 *  Returns:
 *      index of instance, -1 otherwise.
 * ---------------------------------------------------------------------------
 */
int
uf_find_netdev_priv(netInterface_priv_t *priv)
{
    int inst;

    if (!priv) {
        return -1;
    }

    for (inst = 0; inst < MAX_UNIFI_DEVS * CSR_WIFI_NUM_INTERFACES; inst++) {
        if (Unifi_netdev_instances[inst] == priv) {
            return inst;
        }
    }

    return -1;
} /* uf_find_netdev_priv() */

/*
 * ---------------------------------------------------------------------------
 *  uf_get_instance
 *
 *      Find the context structure for a given UniFi device instance
 *      and increment the reference count.
 *
 *  Arguments:
 *      inst            The instance number to look for.
 *
 *  Returns:
 *      Pointer to the instance or NULL if no instance exists.
 * ---------------------------------------------------------------------------
 */
unifi_priv_t *
uf_get_instance(int inst)
{
    unifi_priv_t *priv;

    down(&Unifi_instance_mutex);

    priv = uf_find_instance(inst);
    if (priv) {
        priv->ref_count++;
    }

    up(&Unifi_instance_mutex);

    return priv;
}

/*
 * ---------------------------------------------------------------------------
 *  uf_put_instance
 *
 *      Decrement the context reference count, freeing resources and
 *      shutting down the driver when the count reaches zero.
 *
 *  Arguments:
 *      inst            The instance number to look for.
 *
 *  Returns:
 *      Pointer to the instance or NULL if no instance exists.
 * ---------------------------------------------------------------------------
 */
void
uf_put_instance(int inst)
{
    unifi_priv_t *priv;

    down(&Unifi_instance_mutex);

    priv = uf_find_instance(inst);
    if (priv) {
        priv->ref_count--;
        if (priv->ref_count == 0) {
            ask_unifi_sdio_cleanup(priv);
        }
    }

    up(&Unifi_instance_mutex);
}


/*
 * ---------------------------------------------------------------------------
 *  uf_read_proc
 *
 *      Read method for driver node in /proc/driver/unifi0
 *
 *  Arguments:
 *      page
 *      start
 *      offset
 *      count
 *      eof
 *      data
 *
 *  Returns:
 *      None.
 * ---------------------------------------------------------------------------
 */
#ifdef CONFIG_PROC_FS
static int
uf_read_proc(char *page, char **start, off_t offset, int count,
        int *eof, void *data)
{
#define UNIFI_DEBUG_TXT_BUFFER 8*1024
    unifi_priv_t *priv;
    int actual_amount_to_copy;
    char *p, *orig_p;
    s32 remain = UNIFI_DEBUG_TXT_BUFFER;
    s32 written;
    int i;

    /*
    * The following complex casting is in place in order to eliminate 64-bit compilation warning
    * "cast to/from pointer from/to integer of different size"
    */
    priv = uf_find_instance((int)(long)data);
    if (!priv) {
        return 0;
    }

    p = kmalloc( UNIFI_DEBUG_TXT_BUFFER, GFP_KERNEL );

    orig_p = p;

    written = scnprintf(p, remain, "UniFi SDIO Driver: %s %s %s\n",
            CSR_WIFI_VERSION, __DATE__, __TIME__);
    UNIFI_SNPRINTF_RET(p, remain, written);
#ifdef CSR_SME_USERSPACE
    written = scnprintf(p, remain, "SME: CSR userspace ");
    UNIFI_SNPRINTF_RET(p, remain, written);
#ifdef CSR_SUPPORT_WEXT
    written = scnprintf(p, remain, "with WEXT support\n");
#else
    written = scnprintf(p, remain, "\n");
#endif /* CSR_SUPPORT_WEXT */
    UNIFI_SNPRINTF_RET(p, remain, written);
#endif /* CSR_SME_USERSPACE */
#ifdef CSR_NATIVE_LINUX
    written = scnprintf(p, remain, "SME: native\n");
    UNIFI_SNPRINTF_RET(p, remain, written);
#endif

#ifdef CSR_SUPPORT_SME
    written = scnprintf(p, remain,
            "Firmware (ROM) build:%u, Patch:%u\n",
            priv->card_info.fw_build,
            priv->sme_versions.firmwarePatch);
    UNIFI_SNPRINTF_RET(p, remain, written);
#endif
    p += unifi_print_status(priv->card, p, &remain);

    written = scnprintf(p, remain, "Last dbg str: %s\n",
            priv->last_debug_string);
    UNIFI_SNPRINTF_RET(p, remain, written);

    written = scnprintf(p, remain, "Last dbg16:");
    UNIFI_SNPRINTF_RET(p, remain, written);
    for (i = 0; i < 8; i++) {
        written = scnprintf(p, remain, " %04X",
                priv->last_debug_word16[i]);
        UNIFI_SNPRINTF_RET(p, remain, written);
    }
    written = scnprintf(p, remain, "\n");
    UNIFI_SNPRINTF_RET(p, remain, written);
    written = scnprintf(p, remain, "           ");
    UNIFI_SNPRINTF_RET(p, remain, written);
    for (; i < 16; i++) {
        written = scnprintf(p, remain, " %04X",
                priv->last_debug_word16[i]);
        UNIFI_SNPRINTF_RET(p, remain, written);
    }
    written = scnprintf(p, remain, "\n");
    UNIFI_SNPRINTF_RET(p, remain, written);
    *start = page;

    written = UNIFI_DEBUG_TXT_BUFFER - remain;

    if( offset >= written )
    {
        *eof = 1;
        kfree( orig_p );
        return(0);
    }

    if( offset + count > written )
    {
        actual_amount_to_copy = written - offset;
        *eof = 1;
    }
    else
    {
        actual_amount_to_copy = count;
    }

    memcpy( page, &(orig_p[offset]), actual_amount_to_copy );

    kfree( orig_p );

    return( actual_amount_to_copy );
} /* uf_read_proc() */
#endif




static void
uf_lx_suspend(CsrSdioFunction *sdio_ctx)
{
    unifi_priv_t *priv = sdio_ctx->driverData;
    unifi_suspend(priv);

    CsrSdioSuspendAcknowledge(sdio_ctx, CSR_RESULT_SUCCESS);
}

static void
uf_lx_resume(CsrSdioFunction *sdio_ctx)
{
    unifi_priv_t *priv = sdio_ctx->driverData;
    unifi_resume(priv);

    CsrSdioResumeAcknowledge(sdio_ctx, CSR_RESULT_SUCCESS);
}

static int active_slot = MAX_UNIFI_DEVS;
static struct device *os_devices[MAX_UNIFI_DEVS];

void
uf_add_os_device(int bus_id, struct device *os_device)
{
    if ((bus_id < 0) || (bus_id >= MAX_UNIFI_DEVS)) {
        unifi_error(NULL, "uf_add_os_device: invalid device %d\n",
                bus_id);
        return;
    }

    active_slot = bus_id;
    os_devices[bus_id] = os_device;
} /* uf_add_os_device() */

void
uf_remove_os_device(int bus_id)
{
    if ((bus_id < 0) || (bus_id >= MAX_UNIFI_DEVS)) {
        unifi_error(NULL, "uf_remove_os_device: invalid device %d\n",
                bus_id);
        return;
    }

    active_slot = bus_id;
    os_devices[bus_id] = NULL;
} /* uf_remove_os_device() */

static void
uf_sdio_inserted(CsrSdioFunction *sdio_ctx)
{
	unifi_priv_t *priv;

	unifi_trace(NULL, UDBG5, "uf_sdio_inserted(0x%p), slot_id=%d, dev=%p\n",
		      sdio_ctx, active_slot, os_devices[active_slot]);

	priv = register_unifi_sdio(sdio_ctx, active_slot, os_devices[active_slot]);
	if (priv == NULL) {
		CsrSdioInsertedAcknowledge(sdio_ctx, CSR_RESULT_FAILURE);
		return;
	}

	sdio_ctx->driverData = priv;

	CsrSdioInsertedAcknowledge(sdio_ctx, CSR_RESULT_SUCCESS);
} /* uf_sdio_inserted() */


static void
uf_sdio_removed(CsrSdioFunction *sdio_ctx)
{
	unregister_unifi_sdio(active_slot);
	CsrSdioRemovedAcknowledge(sdio_ctx);
} /* uf_sdio_removed() */


static void
uf_sdio_dsr_handler(CsrSdioFunction *sdio_ctx)
{
	unifi_priv_t *priv = sdio_ctx->driverData;

	unifi_sdio_interrupt_handler(priv->card);
} /* uf_sdio_dsr_handler() */

/*
 * ---------------------------------------------------------------------------
 *  uf_sdio_int_handler
 *
 *      Interrupt callback function for SDIO interrupts.
 *      This is called in kernel context (i.e. not interrupt context).
 *      We retrieve the unifi context pointer and call the main UniFi
 *      interrupt handler.
 *
 *  Arguments:
 *      fdev      SDIO context pointer
 *
 *  Returns:
 *      None.
 * ---------------------------------------------------------------------------
 */
static CsrSdioInterruptDsrCallback
uf_sdio_int_handler(CsrSdioFunction *sdio_ctx)
{
	return uf_sdio_dsr_handler;
} /* uf_sdio_int_handler() */




static CsrSdioFunctionId unifi_ids[] =
{
	{
		.manfId = SDIO_MANF_ID_CSR,
		.cardId = SDIO_CARD_ID_UNIFI_3,
		.sdioFunction = SDIO_WLAN_FUNC_ID_UNIFI_3,
		.sdioInterface = CSR_SDIO_ANY_SDIO_INTERFACE,
	},
	{
		.manfId = SDIO_MANF_ID_CSR,
		.cardId = SDIO_CARD_ID_UNIFI_4,
		.sdioFunction = SDIO_WLAN_FUNC_ID_UNIFI_4,
		.sdioInterface = CSR_SDIO_ANY_SDIO_INTERFACE,
	}
};


/*
 * Structure to register with the glue layer.
 */
static CsrSdioFunctionDriver unifi_sdioFunction_drv =
{
	.inserted = uf_sdio_inserted,
	.removed = uf_sdio_removed,
	.intr = uf_sdio_int_handler,
	.suspend = uf_lx_suspend,
	.resume = uf_lx_resume,

	.ids = unifi_ids,
	.idsCount = sizeof(unifi_ids) / sizeof(unifi_ids[0])
};


/*
 * ---------------------------------------------------------------------------
 *  uf_sdio_load
 *  uf_sdio_unload
 *
 *      These functions are called from the main module load and unload
 *      functions. They perform the appropriate operations for the monolithic
 *      driver.
 *
 *  Arguments:
 *      None.
 *
 *  Returns:
 *      None.
 * ---------------------------------------------------------------------------
 */
int __init
uf_sdio_load(void)
{
	CsrResult csrResult;

	csrResult = CsrSdioFunctionDriverRegister(&unifi_sdioFunction_drv);
	if (csrResult != CSR_RESULT_SUCCESS) {
		unifi_error(NULL, "Failed to register UniFi SDIO driver: csrResult=%d\n", csrResult);
		return -EIO;
	}

	return 0;
} /* uf_sdio_load() */



void __exit
uf_sdio_unload(void)
{
	CsrSdioFunctionDriverUnregister(&unifi_sdioFunction_drv);
} /* uf_sdio_unload() */

