/*
 * ---------------------------------------------------------------------------
 * FILE:     bh.c
 *
 * PURPOSE:
 *      Provides an implementation for the driver bottom-half.
 *      It is part of the porting exercise in Linux.
 *
 * Copyright (C) 2005-2009 by Cambridge Silicon Radio Ltd.
 *
 * Refer to LICENSE.txt included with this source code for details on
 * the license terms.
 *
 * ---------------------------------------------------------------------------
 */
#include "csr_wifi_hip_unifi.h"
#include "unifi_priv.h"
#include <linux/sched/rt.h>

/*
 * ---------------------------------------------------------------------------
 *  uf_start_thread
 *
 *      Helper function to start a new thread.
 *
 *  Arguments:
 *      priv            Pointer to OS driver structure for the device.
 *      thread          Pointer to the thread object
 *      func            The thread function
 *
 *  Returns:
 *      0 on success or else a Linux error code.
 * ---------------------------------------------------------------------------
 */
int uf_start_thread(unifi_priv_t *priv,
		    struct uf_thread *thread, int (*func)(void *))
{
	if (thread->thread_task != NULL) {
		unifi_error(priv, "%s thread already started\n", thread->name);
		return 0;
	}

	/* Start the kernel thread that handles all h/w accesses. */
	thread->thread_task = kthread_run(func, priv, "%s", thread->name);
	if (IS_ERR(thread->thread_task))
		return PTR_ERR(thread->thread_task);

	/* Module parameter overides the thread priority */
	if (bh_priority != -1) {
		if (bh_priority >= 0 && bh_priority <= MAX_RT_PRIO) {
			struct sched_param param;
			priv->bh_thread.prio = bh_priority;
			unifi_trace(priv, UDBG1,
				"%s thread (RT) priority = %d\n",
				thread->name, bh_priority);
			param.sched_priority = bh_priority;
			sched_setscheduler(thread->thread_task,
					   SCHED_FIFO, &param);
		} else if (bh_priority > MAX_RT_PRIO &&
			   bh_priority <= MAX_PRIO) {
			priv->bh_thread.prio = bh_priority;
			unifi_trace(priv, UDBG1, "%s thread priority = %d\n",
					thread->name,
					PRIO_TO_NICE(bh_priority));
			set_user_nice(thread->thread_task,
				      PRIO_TO_NICE(bh_priority));
		} else {
			priv->bh_thread.prio = DEFAULT_PRIO;
			unifi_warning(priv,
				      "%s thread unsupported (%d) priority\n",
				      thread->name, bh_priority);
		}
	} else
		priv->bh_thread.prio = DEFAULT_PRIO;
	unifi_trace(priv, UDBG2, "Started %s thread\n", thread->name);

	return 0;
} /* uf_start_thread() */


/*
 * ---------------------------------------------------------------------------
 *  uf_stop_thread
 *
 *      Helper function to stop a thread.
 *
 *  Arguments:
 *      priv            Pointer to OS driver structure for the device.
 *      thread          Pointer to the thread object
 *
 *  Returns:
 *
 * ---------------------------------------------------------------------------
 */
void uf_stop_thread(unifi_priv_t *priv, struct uf_thread *thread)
{
	if (!thread->thread_task) {
		unifi_notice(priv, "%s thread is already stopped\n",
							thread->name);
		return;
	}

	unifi_trace(priv, UDBG2, "Stopping %s thread\n", thread->name);

	kthread_stop(thread->thread_task);
	thread->thread_task = NULL;

} /* uf_stop_thread() */



/*
 * ---------------------------------------------------------------------------
 *  uf_wait_for_thread_to_stop
 *
 *      Helper function to wait until a thread is stopped.
 *
 *  Arguments:
 *      priv    Pointer to OS driver structure for the device.
 *
 *  Returns:
 *
 * ---------------------------------------------------------------------------
 */
void
uf_wait_for_thread_to_stop(unifi_priv_t *priv, struct uf_thread *thread)
{
	/*
	 * kthread_stop() cannot handle the thread exiting while
	 * kthread_should_stop() is false, so sleep until kthread_stop()
	 * wakes us up
	 */
	unifi_trace(priv, UDBG2, "%s waiting for the stop signal.\n",
							thread->name);
	set_current_state(TASK_INTERRUPTIBLE);
	if (!kthread_should_stop()) {
		unifi_trace(priv, UDBG2, "%s schedule....\n", thread->name);
		schedule();
	}

	thread->thread_task = NULL;
	unifi_trace(priv, UDBG2, "%s exiting....\n", thread->name);
} /* uf_wait_for_thread_to_stop() */


/*
 * ---------------------------------------------------------------------------
 *  handle_bh_error
 *
 *      This function reports an error returned from the HIP core bottom-half.
 *      Normally, implemented during the porting exercise, passing the error
 *      to the SME using unifi_sys_wifi_off_ind().
 *      The SME will try to reset the device and go through
 *      the initialisation of the UniFi.
 *
 *  Arguments:
 *      priv            Pointer to OS driver structure for the device.
 *
 *  Returns:
 *      None.
 * ---------------------------------------------------------------------------
 */
static void
handle_bh_error(unifi_priv_t *priv)
{
	netInterface_priv_t *interfacePriv;
	u8 conf_param = CONFIG_IND_ERROR;
	u8 interfaceTag;


	/* Block unifi_run_bh() until the error has been handled. */
	priv->bh_thread.block_thread = 1;

	/* Consider UniFi to be uninitialised */
	priv->init_progress = UNIFI_INIT_NONE;

	/* Stop the network traffic */
	for (interfaceTag = 0;
	     interfaceTag < CSR_WIFI_NUM_INTERFACES; interfaceTag++) {
		interfacePriv = priv->interfacePriv[interfaceTag];
		if (interfacePriv->netdev_registered)
			netif_carrier_off(priv->netdev[interfaceTag]);
	}

#ifdef CSR_NATIVE_LINUX
	/* Force any client waiting on an mlme_wait_for_reply() to abort. */
	uf_abort_mlme(priv);

	/* Cancel any pending workqueue tasks */
	flush_workqueue(priv->unifi_workqueue);

#endif /* CSR_NATIVE_LINUX */

	unifi_error(priv,
		"handle_bh_error: fatal error is reported to the SME.\n");
	/* Notify the clients (SME or unifi_manager) for the error. */
	ul_log_config_ind(priv, &conf_param, sizeof(u8));

} /* handle_bh_error() */



/*
 * ---------------------------------------------------------------------------
 *  bh_thread_function
 *
 *      All hardware access happens in this thread.
 *      This means there is no need for locks on the hardware and we don't need
 *      to worry about reentrancy with the SDIO library.
 *      Provides and example implementation on how to call unifi_bh(), which
 *      is part of the HIP core API.
 *
 *      It processes the events generated by unifi_run_bh() to serialise calls
 *      to unifi_bh(). It also demonstrates how the timeout parameter passed in
 *      and returned from unifi_bh() needs to be handled.
 *
 *  Arguments:
 *      arg             Pointer to OS driver structure for the device.
 *
 *  Returns:
 *      None.
 *
 *  Notes:
 *      When the bottom half of the driver needs to process signals, events,
 *      or simply the host status (i.e sleep mode), it invokes unifi_run_bh().
 *      Since we need all SDIO transaction to be in a single thread, the
 *      unifi_run_bh() will wake up this thread to process it.
 *
 * ---------------------------------------------------------------------------
 */
static int bh_thread_function(void *arg)
{
	unifi_priv_t *priv = (unifi_priv_t *)arg;
	CsrResult csrResult;
	long ret;
	u32 timeout, t;
	struct uf_thread *this_thread;

	unifi_trace(priv, UDBG2, "bh_thread_function starting\n");

	this_thread = &priv->bh_thread;

	t = timeout = 0;
    while (!kthread_should_stop()) {
        /* wait until an error occurs, or we need to process something. */
        unifi_trace(priv, UDBG3, "bh_thread goes to sleep.\n");

        if (timeout > 0) {
            /* Convert t in ms to jiffies */
            t = msecs_to_jiffies(timeout);
            ret = wait_event_interruptible_timeout(this_thread->wakeup_q,
                    (this_thread->wakeup_flag && !this_thread->block_thread) ||
                    kthread_should_stop(),
                    t);
            timeout = (ret > 0) ? jiffies_to_msecs(ret) : 0;
        } else {
            ret = wait_event_interruptible(this_thread->wakeup_q,
                    (this_thread->wakeup_flag && !this_thread->block_thread) ||
                    kthread_should_stop());
        }

        if (kthread_should_stop()) {
            unifi_trace(priv, UDBG2, "bh_thread: signalled to exit\n");
            break;
        }

        if (ret < 0) {
            unifi_notice(priv,
                    "bh_thread: wait_event returned %d, thread will exit\n",
                    ret);
            uf_wait_for_thread_to_stop(priv, this_thread);
            break;
        }

        this_thread->wakeup_flag = 0;

        unifi_trace(priv, UDBG3, "bh_thread calls unifi_bh().\n");

        CsrSdioClaim(priv->sdio);
        csrResult = unifi_bh(priv->card, &timeout);
        if(csrResult != CSR_RESULT_SUCCESS) {
            if (csrResult == CSR_WIFI_HIP_RESULT_NO_DEVICE) {
                CsrSdioRelease(priv->sdio);
                uf_wait_for_thread_to_stop(priv, this_thread);
                break;
            }
            /* Errors must be delivered to the error task */
            handle_bh_error(priv);
        }
        CsrSdioRelease(priv->sdio);
    }

    /*
     * I would normally try to call csr_sdio_remove_irq() here to make sure
     * that we do not get any interrupts while this thread is not running.
     * However, the MMC/SDIO driver tries to kill its' interrupt thread.
     * The kernel threads implementation does not allow to kill threads
     * from a signalled to stop thread.
     * So, instead call csr_sdio_linux_remove_irq() always after calling
     * uf_stop_thread() to kill this thread.
     */

    unifi_trace(priv, UDBG2, "bh_thread exiting....\n");
    return 0;
} /* bh_thread_function() */


/*
 * ---------------------------------------------------------------------------
 *  uf_init_bh
 *
 *      Helper function to start the bottom half of the driver.
 *      All we need to do here is start the I/O bh thread.
 *
 *  Arguments:
 *      priv            Pointer to OS driver structure for the device.
 *
 *  Returns:
 *      0 on success or else a Linux error code.
 * ---------------------------------------------------------------------------
 */
    int
uf_init_bh(unifi_priv_t *priv)
{
    int r;

    /* Enable mlme interface. */
    priv->io_aborted = 0;


    /* Start the BH thread */
    r = uf_start_thread(priv, &priv->bh_thread, bh_thread_function);
    if (r) {
        unifi_error(priv,
                "uf_init_bh: failed to start the BH thread.\n");
        return r;
    }

    /* Allow interrupts */
    r = csr_sdio_linux_install_irq(priv->sdio);
    if (r) {
        unifi_error(priv,
                "uf_init_bh: failed to install the IRQ.\n");

        uf_stop_thread(priv, &priv->bh_thread);
    }

    return r;
} /* uf_init_bh() */


/*
 * ---------------------------------------------------------------------------
 *  unifi_run_bh
 *
 *      Part of the HIP core lib API, implemented in the porting exercise.
 *      The bottom half of the driver calls this function when
 *      it wants to process anything that requires access to unifi.
 *      We need to call unifi_bh() which in this implementation is done
 *      by waking up the I/O thread.
 *
 *  Arguments:
 *      ospriv          Pointer to OS driver structure for the device.
 *
 *  Returns:
 *      0 on success or else a Linux error code.
 *
 *  Notes:
 * ---------------------------------------------------------------------------
 */
CsrResult unifi_run_bh(void *ospriv)
{
    unifi_priv_t *priv = ospriv;

    /*
     * If an error has occurred, we discard silently all messages from the bh
     * until the error has been processed and the unifi has been reinitialised.
     */
    if (priv->bh_thread.block_thread == 1) {
        unifi_trace(priv, UDBG3, "unifi_run_bh: discard message.\n");
        /*
         * Do not try to acknowledge a pending interrupt here.
         * This function is called by unifi_send_signal() which in turn can be
         * running in an atomic or 'disabled irq' level if a signal is sent
         * from a workqueue task (i.e multicass addresses set).
         * We can not hold the SDIO lock because it might sleep.
         */
        return CSR_RESULT_FAILURE;
    }

    priv->bh_thread.wakeup_flag = 1;
    /* wake up I/O thread */
    wake_up_interruptible(&priv->bh_thread.wakeup_q);

    return CSR_RESULT_SUCCESS;
} /* unifi_run_bh() */

