/*
 * ---------------------------------------------------------------------------
 *  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 <linux/seq_file.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);

#ifdef CONFIG_PROC_FS
/*
 * seq_file wrappers for procfile show routines.
 */
static int uf_proc_show(struct seq_file *m, void *v);

#define UNIFI_DEBUG_TXT_BUFFER (8 * 1024)

static int uf_proc_open(struct inode *inode, struct file *file)
{
	return single_open_size(file, uf_proc_show, PDE_DATA(inode),
				UNIFI_DEBUG_TXT_BUFFER);
}

static const struct file_operations uf_proc_fops = {
	.open		= uf_proc_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= single_release,
};

#endif /* CONFIG_PROC_FS */

#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 (!proc_create_data(priv->proc_entry_name, 0, NULL,
			  &uf_proc_fops, (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_proc_show
 *
 *      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_proc_show(struct seq_file *m, void *v)
{
	unifi_priv_t *priv;
	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((long)m->private);
	if (!priv)
		return 0;

	seq_printf(m, "UniFi SDIO Driver: %s %s %s\n",
		   CSR_WIFI_VERSION, __DATE__, __TIME__);
#ifdef CSR_SME_USERSPACE
	seq_puts(m, "SME: CSR userspace ");
#ifdef CSR_SUPPORT_WEXT
	seq_puts(m, "with WEXT support\n");
#else
	seq_putc(m, '\n');
#endif /* CSR_SUPPORT_WEXT */
#endif /* CSR_SME_USERSPACE */
#ifdef CSR_NATIVE_LINUX
	seq_puts(m, "SME: native\n");
#endif

#ifdef CSR_SUPPORT_SME
	seq_printf(m, "Firmware (ROM) build:%u, Patch:%u\n",
		   priv->card_info.fw_build,
		   priv->sme_versions.firmwarePatch);
#endif

	unifi_print_status(priv->card, m);

	seq_printf(m, "Last dbg str: %s\n", priv->last_debug_string);

	seq_puts(m, "Last dbg16:");
	for (i = 0; i < 8; i++)
		seq_printf(m, " %04X", priv->last_debug_word16[i]);
	seq_putc(m, '\n');
	seq_puts(m, "           ");
	for (; i < 16; i++)
		seq_printf(m, " %04X", priv->last_debug_word16[i]);
	seq_putc(m, '\n');
	return 0;
}
#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() */

