/*
 * ---------------------------------------------------------------------------
 *  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/version.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;
    func_enter();

    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;
             }
             func_exit();
             return -1;
         }
    }
    func_exit();
    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;

    func_enter();

    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);

    func_exit();
    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);

    func_exit();
    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)
{
    func_enter();

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

    func_exit();

} /* 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}};

    func_enter();

    /* 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");

    func_exit();

} /* 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);
        func_exit();
        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() */

