/*
 * Broadcom Dongle Host Driver (DHD), Generic work queue framework
 * Generic interface to handle dhd deferred work events
 *
 * Copyright (C) 1999-2019, 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.
 *
 *      Notwithstanding the above, under no circumstances may you combine this
 * software in any way with any other Broadcom software provided under a license
 * other than the GPL, without Broadcom's express prior written consent.
 *
 *
 * <<Broadcom-WL-IPTag/Open:>>
 *
 * $Id: dhd_linux_wq.c 815919 2019-04-22 09:06:50Z $
 */

#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>

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

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

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