/*
 * Broadcom Dongle Host Driver (DHD), Generic work queue framework
 * Generic interface to handle dhd deferred work events
 *
 * Copyright (C) 2020, Broadcom.
 *
 *      Unless you and Broadcom execute a separate written software license
 * agreement governing use of this software, this software is licensed to you
 * under the terms of the GNU General Public License version 2 (the "GPL"),
 * available at http://www.broadcom.com/licenses/GPLv2.php, with the
 * following added to such license:
 *
 *      As a special exception, the copyright holders of this software give you
 * permission to link this software with independent modules, and to copy and
 * distribute the resulting executable under terms of your choice, provided that
 * you also meet, for each linked independent module, the terms and conditions of
 * the license of that module.  An independent module is a module which is not
 * derived from this software.  The special exception does not apply to any
 * modifications of the software.
 *
 *
 * <<Broadcom-WL-IPTag/Open:>>
 *
 * $Id$
 */

#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/spinlock.h>
#include <linux/fcntl.h>
#include <linux/fs.h>
#include <linux/ip.h>
#include <linux/kfifo.h>

#include <linuxver.h>
#include <osl.h>
#include <bcmutils.h>
#include <bcmendian.h>
#include <bcmdevs.h>
#include <dngl_stats.h>
#include <dhd.h>
#include <dhd_dbg.h>
#include <dhd_linux_wq.h>

/*
 * XXX: always make sure that the size of this structure is aligned to
 * the power of 2 (2^n) i.e, if any new variable has to be added then
 * modify the padding accordingly
 */
typedef struct dhd_deferred_event {
	u8 event;		/* holds the event */
	void *event_data;	/* holds event specific data */
	event_handler_t event_handler;
	unsigned long pad;	/* for memory alignment to power of 2 */
} dhd_deferred_event_t;

#define DEFRD_EVT_SIZE	(sizeof(dhd_deferred_event_t))

/*
 * work events may occur simultaneously.
 * can hold upto 64 low priority events and 16 high priority events
 */
#define DHD_PRIO_WORK_FIFO_SIZE	(16 * DEFRD_EVT_SIZE)
#define DHD_WORK_FIFO_SIZE	(64 * DEFRD_EVT_SIZE)

#define DHD_FIFO_HAS_FREE_SPACE(fifo) \
	((fifo) && (kfifo_avail(fifo) >= DEFRD_EVT_SIZE))
#define DHD_FIFO_HAS_ENOUGH_DATA(fifo) \
	((fifo) && (kfifo_len(fifo) >= DEFRD_EVT_SIZE))

struct dhd_deferred_wq {
	struct work_struct deferred_work; /* should be the first member */

	struct kfifo *prio_fifo;
	struct kfifo			*work_fifo;
	u8				*prio_fifo_buf;
	u8				*work_fifo_buf;
	spinlock_t			work_lock;
	void				*dhd_info; /* review: does it require */
	u32				event_skip_mask;
};

static inline struct kfifo*
dhd_kfifo_init(u8 *buf, int size, spinlock_t *lock)
{
	struct kfifo *fifo;
	gfp_t flags = CAN_SLEEP()? GFP_KERNEL : GFP_ATOMIC;

	fifo = (struct kfifo *)kzalloc(sizeof(struct kfifo), flags);
	if (!fifo) {
		return NULL;
	}
	kfifo_init(fifo, buf, size);
	return fifo;
}

static inline void
dhd_kfifo_free(struct kfifo *fifo)
{
	kfifo_free(fifo);
	kfree(fifo);
}

/* deferred work functions */
static void dhd_deferred_work_handler(struct work_struct *data);

void*
dhd_deferred_work_init(void *dhd_info)
{
	struct dhd_deferred_wq	*work = NULL;
	u8*	buf;
	unsigned long	fifo_size = 0;
	gfp_t	flags = CAN_SLEEP()? GFP_KERNEL : GFP_ATOMIC;

	if (!dhd_info) {
		DHD_ERROR(("%s: dhd info not initialized\n", __FUNCTION__));
		goto return_null;
	}

	work = (struct dhd_deferred_wq *)kzalloc(sizeof(struct dhd_deferred_wq),
		flags);
	if (!work) {
		DHD_ERROR(("%s: work queue creation failed\n", __FUNCTION__));
		goto return_null;
	}

	INIT_WORK((struct work_struct *)work, dhd_deferred_work_handler);

	/* initialize event fifo */
	spin_lock_init(&work->work_lock);

	/* allocate buffer to hold prio events */
	fifo_size = DHD_PRIO_WORK_FIFO_SIZE;
	fifo_size = is_power_of_2(fifo_size) ? fifo_size :
			roundup_pow_of_two(fifo_size);
	buf = (u8*)kzalloc(fifo_size, flags);
	if (!buf) {
		DHD_ERROR(("%s: prio work fifo allocation failed\n",
			__FUNCTION__));
		goto return_null;
	}

	/* Initialize prio event fifo */
	work->prio_fifo = dhd_kfifo_init(buf, fifo_size, &work->work_lock);
	if (!work->prio_fifo) {
		kfree(buf);
		goto return_null;
	}

	/* allocate buffer to hold work events */
	fifo_size = DHD_WORK_FIFO_SIZE;
	fifo_size = is_power_of_2(fifo_size) ? fifo_size :
			roundup_pow_of_two(fifo_size);
	buf = (u8*)kzalloc(fifo_size, flags);
	if (!buf) {
		DHD_ERROR(("%s: work fifo allocation failed\n", __FUNCTION__));
		goto return_null;
	}

	/* Initialize event fifo */
	work->work_fifo = dhd_kfifo_init(buf, fifo_size, &work->work_lock);
	if (!work->work_fifo) {
		kfree(buf);
		goto return_null;
	}

	work->dhd_info = dhd_info;
	work->event_skip_mask = 0;
	DHD_ERROR(("%s: work queue initialized\n", __FUNCTION__));
	return work;

return_null:
	if (work) {
		dhd_deferred_work_deinit(work);
	}

	return NULL;
}

void
dhd_deferred_work_deinit(void *work)
{
	struct dhd_deferred_wq *deferred_work = work;

	if (!deferred_work) {
		DHD_ERROR(("%s: deferred work has been freed already\n",
			__FUNCTION__));
		return;
	}

	/* cancel the deferred work handling */
	cancel_work_sync((struct work_struct *)deferred_work);

	/*
	 * free work event fifo.
	 * kfifo_free frees locally allocated fifo buffer
	 */
	if (deferred_work->prio_fifo) {
		dhd_kfifo_free(deferred_work->prio_fifo);
	}

	if (deferred_work->work_fifo) {
		dhd_kfifo_free(deferred_work->work_fifo);
	}

	kfree(deferred_work);
}

/* select kfifo according to priority */
static inline struct kfifo *
dhd_deferred_work_select_kfifo(struct dhd_deferred_wq *deferred_wq,
	u8 priority)
{
	if (priority == DHD_WQ_WORK_PRIORITY_HIGH) {
		return deferred_wq->prio_fifo;
	} else if (priority == DHD_WQ_WORK_PRIORITY_LOW) {
		return deferred_wq->work_fifo;
	} else {
		return NULL;
	}
}

/*
 *	Prepares event to be queued
 *	Schedules the event
 */
int
dhd_deferred_schedule_work(void *workq, void *event_data, u8 event,
	event_handler_t event_handler, u8 priority)
{
	struct dhd_deferred_wq *deferred_wq = (struct dhd_deferred_wq *)workq;
	struct kfifo *fifo;
	dhd_deferred_event_t deferred_event;
	int bytes_copied = 0;

	if (!deferred_wq) {
		DHD_ERROR(("%s: work queue not initialized\n", __FUNCTION__));
		ASSERT(0);
		return DHD_WQ_STS_UNINITIALIZED;
	}

	if (!event || (event >= DHD_MAX_WQ_EVENTS)) {
		DHD_ERROR(("%s: unknown event, event=%d\n", __FUNCTION__,
			event));
		return DHD_WQ_STS_UNKNOWN_EVENT;
	}

	if (!priority || (priority >= DHD_WQ_MAX_PRIORITY)) {
		DHD_ERROR(("%s: unknown priority, priority=%d\n",
			__FUNCTION__, priority));
		return DHD_WQ_STS_UNKNOWN_PRIORITY;
	}

	if ((deferred_wq->event_skip_mask & (1 << event))) {
		DHD_ERROR(("%s: Skip event requested. Mask = 0x%x\n",
			__FUNCTION__, deferred_wq->event_skip_mask));
		return DHD_WQ_STS_EVENT_SKIPPED;
	}

	/*
	 * default element size is 1, which can be changed
	 * using kfifo_esize(). Older kernel(FC11) doesn't support
	 * changing element size. For compatibility changing
	 * element size is not prefered
	 */
	ASSERT(kfifo_esize(deferred_wq->prio_fifo) == 1);
	ASSERT(kfifo_esize(deferred_wq->work_fifo) == 1);

	deferred_event.event = event;
	deferred_event.event_data = event_data;
	deferred_event.event_handler = event_handler;

	fifo = dhd_deferred_work_select_kfifo(deferred_wq, priority);
	if (DHD_FIFO_HAS_FREE_SPACE(fifo)) {
		bytes_copied = kfifo_in_spinlocked(fifo, &deferred_event,
			DEFRD_EVT_SIZE, &deferred_wq->work_lock);
	}
	if (bytes_copied != DEFRD_EVT_SIZE) {
		DHD_ERROR(("%s: failed to schedule deferred work, "
			"priority=%d, bytes_copied=%d\n", __FUNCTION__,
			priority, bytes_copied));
		return DHD_WQ_STS_SCHED_FAILED;
	}
	schedule_work((struct work_struct *)deferred_wq);
	return DHD_WQ_STS_OK;
}

static bool
dhd_get_scheduled_work(struct dhd_deferred_wq *deferred_wq,
	dhd_deferred_event_t *event)
{
	int bytes_copied = 0;

	if (!deferred_wq) {
		DHD_ERROR(("%s: work queue not initialized\n", __FUNCTION__));
		return DHD_WQ_STS_UNINITIALIZED;
	}

	/*
	 * default element size is 1 byte, which can be changed
	 * using kfifo_esize(). Older kernel(FC11) doesn't support
	 * changing element size. For compatibility changing
	 * element size is not prefered
	 */
	ASSERT(kfifo_esize(deferred_wq->prio_fifo) == 1);
	ASSERT(kfifo_esize(deferred_wq->work_fifo) == 1);

	/* handle priority work */
	if (DHD_FIFO_HAS_ENOUGH_DATA(deferred_wq->prio_fifo)) {
		bytes_copied = kfifo_out_spinlocked(deferred_wq->prio_fifo,
			event, DEFRD_EVT_SIZE, &deferred_wq->work_lock);
	}

	/* handle normal work if priority work doesn't have enough data */
	if ((bytes_copied != DEFRD_EVT_SIZE) &&
		DHD_FIFO_HAS_ENOUGH_DATA(deferred_wq->work_fifo)) {
		bytes_copied = kfifo_out_spinlocked(deferred_wq->work_fifo,
			event, DEFRD_EVT_SIZE, &deferred_wq->work_lock);
	}

	return (bytes_copied == DEFRD_EVT_SIZE);
}

static inline void
dhd_deferred_dump_work_event(dhd_deferred_event_t *work_event)
{
	if (!work_event) {
		DHD_ERROR(("%s: work_event is null\n", __FUNCTION__));
		return;
	}

	DHD_ERROR(("%s: work_event->event = %d\n", __FUNCTION__,
		work_event->event));
	DHD_ERROR(("%s: work_event->event_data = %p\n", __FUNCTION__,
		work_event->event_data));
	DHD_ERROR(("%s: work_event->event_handler = %p\n", __FUNCTION__,
		work_event->event_handler));
}

/*
 *	Called when work is scheduled
 */
static void
dhd_deferred_work_handler(struct work_struct *work)
{
	struct dhd_deferred_wq *deferred_work = (struct dhd_deferred_wq *)work;
	dhd_deferred_event_t work_event;

	if (!deferred_work) {
		DHD_ERROR(("%s: work queue not initialized\n", __FUNCTION__));
		return;
	}

	do {
		if (!dhd_get_scheduled_work(deferred_work, &work_event)) {
			DHD_TRACE(("%s: no event to handle\n", __FUNCTION__));
			break;
		}

		if (work_event.event >= DHD_MAX_WQ_EVENTS) {
			DHD_ERROR(("%s: unknown event\n", __FUNCTION__));
			dhd_deferred_dump_work_event(&work_event);
			ASSERT(work_event.event < DHD_MAX_WQ_EVENTS);
			continue;
		}

		/*
		 * XXX: don't do NULL check for 'work_event.event_data'
		 * as for some events like DHD_WQ_WORK_DHD_LOG_DUMP the
		 * event data is always NULL even though rest of the
		 * event parameters are valid
		 */

		if (work_event.event_handler) {
			work_event.event_handler(deferred_work->dhd_info,
				work_event.event_data, work_event.event);
		} else {
			DHD_ERROR(("%s: event handler is null\n",
				__FUNCTION__));
			dhd_deferred_dump_work_event(&work_event);
			ASSERT(work_event.event_handler != NULL);
		}
	} while (1);

	return;
}

void
dhd_deferred_work_set_skip(void *work, u8 event, bool set)
{
	struct dhd_deferred_wq *deferred_wq = (struct dhd_deferred_wq *)work;

	if (!deferred_wq || !event || (event >= DHD_MAX_WQ_EVENTS)) {
		DHD_ERROR(("%s: Invalid!!\n", __FUNCTION__));
		return;
	}

	if (set) {
		/* Set */
		deferred_wq->event_skip_mask |= (1 << event);
	} else {
		/* Clear */
		deferred_wq->event_skip_mask &= ~(1 << event);
	}
}
