/*
 * Copyright (c) 2010 Broadcom Corporation
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include <linux/kernel.h>
#include <bcmdefs.h>
#include <linuxver.h>
#include <bcmutils.h>
#include <siutils.h>
#include <wlioctl.h>
#include <wlc_cfg.h>
#include <wlc_pub.h>
#include <wlc_key.h>
#include <wl_export.h>
#include <wlc_event.h>

#include <d11.h>
#include <wlc_rate.h>
#include <wlc_mac80211.h>
#ifdef MSGTRACE
#include <msgtrace.h>
#endif

/* Local prototypes */
static void wlc_timer_cb(void *arg);

/* Private data structures */
struct wlc_eventq {
	wlc_event_t *head;
	wlc_event_t *tail;
	struct wlc_info *wlc;
	void *wl;
	wlc_pub_t *pub;
	bool tpending;
	bool workpending;
	struct wl_timer *timer;
	wlc_eventq_cb_t cb;
	u8 event_inds_mask[roundup(WLC_E_LAST, NBBY) / NBBY];
};

/*
 * Export functions
 */
wlc_eventq_t *wlc_eventq_attach(wlc_pub_t *pub, struct wlc_info *wlc, void *wl,
				wlc_eventq_cb_t cb)
{
	wlc_eventq_t *eq;

	eq = kzalloc(sizeof(wlc_eventq_t), GFP_ATOMIC);
	if (eq == NULL)
		return NULL;

	eq->cb = cb;
	eq->wlc = wlc;
	eq->wl = wl;
	eq->pub = pub;

	eq->timer = wl_init_timer(eq->wl, wlc_timer_cb, eq, "eventq");
	if (!eq->timer) {
		WL_ERROR(("wl%d: wlc_eventq_attach: timer failed\n",
			  pub->unit));
		kfree(eq);
		return NULL;
	}

	return eq;
}

int wlc_eventq_detach(wlc_eventq_t *eq)
{
	/* Clean up pending events */
	wlc_eventq_down(eq);

	if (eq->timer) {
		if (eq->tpending) {
			wl_del_timer(eq->wl, eq->timer);
			eq->tpending = false;
		}
		wl_free_timer(eq->wl, eq->timer);
		eq->timer = NULL;
	}

	ASSERT(wlc_eventq_avail(eq) == false);
	kfree(eq);
	return 0;
}

int wlc_eventq_down(wlc_eventq_t *eq)
{
	int callbacks = 0;
	if (eq->tpending && !eq->workpending) {
		if (!wl_del_timer(eq->wl, eq->timer))
			callbacks++;

		ASSERT(wlc_eventq_avail(eq) == true);
		ASSERT(eq->workpending == false);
		eq->workpending = true;
		if (eq->cb)
			eq->cb(eq->wlc);

		ASSERT(eq->workpending == true);
		eq->workpending = false;
		eq->tpending = false;
	} else {
		ASSERT(eq->workpending || wlc_eventq_avail(eq) == false);
	}
	return callbacks;
}

wlc_event_t *wlc_event_alloc(wlc_eventq_t *eq)
{
	wlc_event_t *e;

	e = kzalloc(sizeof(wlc_event_t), GFP_ATOMIC);

	if (e == NULL)
		return NULL;

	return e;
}

void wlc_event_free(wlc_eventq_t *eq, wlc_event_t *e)
{
	ASSERT(e->data == NULL);
	ASSERT(e->next == NULL);
	kfree(e);
}

void wlc_eventq_enq(wlc_eventq_t *eq, wlc_event_t *e)
{
	ASSERT(e->next == NULL);
	e->next = NULL;

	if (eq->tail) {
		eq->tail->next = e;
		eq->tail = e;
	} else
		eq->head = eq->tail = e;

	if (!eq->tpending) {
		eq->tpending = true;
		/* Use a zero-delay timer to trigger
		 * delayed processing of the event.
		 */
		wl_add_timer(eq->wl, eq->timer, 0, 0);
	}
}

wlc_event_t *wlc_eventq_deq(wlc_eventq_t *eq)
{
	wlc_event_t *e;

	e = eq->head;
	if (e) {
		eq->head = e->next;
		e->next = NULL;

		if (eq->head == NULL)
			eq->tail = eq->head;
	}
	return e;
}

wlc_event_t *wlc_eventq_next(wlc_eventq_t *eq, wlc_event_t *e)
{
#ifdef BCMDBG
	wlc_event_t *etmp;

	for (etmp = eq->head; etmp; etmp = etmp->next) {
		if (etmp == e)
			break;
	}
	ASSERT(etmp != NULL);
#endif

	return e->next;
}

int wlc_eventq_cnt(wlc_eventq_t *eq)
{
	wlc_event_t *etmp;
	int cnt = 0;

	for (etmp = eq->head; etmp; etmp = etmp->next)
		cnt++;

	return cnt;
}

bool wlc_eventq_avail(wlc_eventq_t *eq)
{
	return (eq->head != NULL);
}

/*
 * Local Functions
 */
static void wlc_timer_cb(void *arg)
{
	struct wlc_eventq *eq = (struct wlc_eventq *)arg;

	ASSERT(eq->tpending == true);
	ASSERT(wlc_eventq_avail(eq) == true);
	ASSERT(eq->workpending == false);
	eq->workpending = true;

	if (eq->cb)
		eq->cb(eq->wlc);

	ASSERT(wlc_eventq_avail(eq) == false);
	ASSERT(eq->tpending == true);
	eq->workpending = false;
	eq->tpending = false;
}
