/*
 * Copyright (c) 2012 Neratec Solutions AG
 *
 * 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/slab.h>
#include <linux/spinlock.h>

#include "ath.h"
#include "dfs_pattern_detector.h"
#include "dfs_pri_detector.h"

struct ath_dfs_pool_stats global_dfs_pool_stats = {};

#define DFS_POOL_STAT_INC(c) (global_dfs_pool_stats.c++)
#define DFS_POOL_STAT_DEC(c) (global_dfs_pool_stats.c--)
#define GET_PRI_TO_USE(MIN, MAX, RUNTIME) \
	(MIN + PRI_TOLERANCE == MAX - PRI_TOLERANCE ? \
	MIN + PRI_TOLERANCE : RUNTIME)

/*
 * struct pulse_elem - elements in pulse queue
 */
struct pulse_elem {
	struct list_head head;
	u64 ts;
};

/*
 * pde_get_multiple() - get number of multiples considering a given tolerance
 * Return value: factor if abs(val - factor*fraction) <= tolerance, 0 otherwise
 */
static u32 pde_get_multiple(u32 val, u32 fraction, u32 tolerance)
{
	u32 remainder;
	u32 factor;
	u32 delta;

	if (fraction == 0)
		return 0;

	delta = (val < fraction) ? (fraction - val) : (val - fraction);

	if (delta <= tolerance)
		/* val and fraction are within tolerance */
		return 1;

	factor = val / fraction;
	remainder = val % fraction;
	if (remainder > tolerance) {
		/* no exact match */
		if ((fraction - remainder) <= tolerance)
			/* remainder is within tolerance */
			factor++;
		else
			factor = 0;
	}
	return factor;
}

/*
 * DOC: Singleton Pulse and Sequence Pools
 *
 * Instances of pri_sequence and pulse_elem are kept in singleton pools to
 * reduce the number of dynamic allocations. They are shared between all
 * instances and grow up to the peak number of simultaneously used objects.
 *
 * Memory is freed after all references to the pools are released.
 */
static u32 singleton_pool_references;
static LIST_HEAD(pulse_pool);
static LIST_HEAD(pseq_pool);
static DEFINE_SPINLOCK(pool_lock);

static void pool_register_ref(void)
{
	spin_lock_bh(&pool_lock);
	singleton_pool_references++;
	DFS_POOL_STAT_INC(pool_reference);
	spin_unlock_bh(&pool_lock);
}

static void pool_deregister_ref(void)
{
	spin_lock_bh(&pool_lock);
	singleton_pool_references--;
	DFS_POOL_STAT_DEC(pool_reference);
	if (singleton_pool_references == 0) {
		/* free singleton pools with no references left */
		struct pri_sequence *ps, *ps0;
		struct pulse_elem *p, *p0;

		list_for_each_entry_safe(p, p0, &pulse_pool, head) {
			list_del(&p->head);
			DFS_POOL_STAT_DEC(pulse_allocated);
			kfree(p);
		}
		list_for_each_entry_safe(ps, ps0, &pseq_pool, head) {
			list_del(&ps->head);
			DFS_POOL_STAT_DEC(pseq_allocated);
			kfree(ps);
		}
	}
	spin_unlock_bh(&pool_lock);
}

static void pool_put_pulse_elem(struct pulse_elem *pe)
{
	spin_lock_bh(&pool_lock);
	list_add(&pe->head, &pulse_pool);
	DFS_POOL_STAT_DEC(pulse_used);
	spin_unlock_bh(&pool_lock);
}

static void pool_put_pseq_elem(struct pri_sequence *pse)
{
	spin_lock_bh(&pool_lock);
	list_add(&pse->head, &pseq_pool);
	DFS_POOL_STAT_DEC(pseq_used);
	spin_unlock_bh(&pool_lock);
}

static struct pri_sequence *pool_get_pseq_elem(void)
{
	struct pri_sequence *pse = NULL;
	spin_lock_bh(&pool_lock);
	if (!list_empty(&pseq_pool)) {
		pse = list_first_entry(&pseq_pool, struct pri_sequence, head);
		list_del(&pse->head);
		DFS_POOL_STAT_INC(pseq_used);
	}
	spin_unlock_bh(&pool_lock);
	return pse;
}

static struct pulse_elem *pool_get_pulse_elem(void)
{
	struct pulse_elem *pe = NULL;
	spin_lock_bh(&pool_lock);
	if (!list_empty(&pulse_pool)) {
		pe = list_first_entry(&pulse_pool, struct pulse_elem, head);
		list_del(&pe->head);
		DFS_POOL_STAT_INC(pulse_used);
	}
	spin_unlock_bh(&pool_lock);
	return pe;
}

static struct pulse_elem *pulse_queue_get_tail(struct pri_detector *pde)
{
	struct list_head *l = &pde->pulses;
	if (list_empty(l))
		return NULL;
	return list_entry(l->prev, struct pulse_elem, head);
}

static bool pulse_queue_dequeue(struct pri_detector *pde)
{
	struct pulse_elem *p = pulse_queue_get_tail(pde);
	if (p != NULL) {
		list_del_init(&p->head);
		pde->count--;
		/* give it back to pool */
		pool_put_pulse_elem(p);
	}
	return (pde->count > 0);
}

/* remove pulses older than window */
static void pulse_queue_check_window(struct pri_detector *pde)
{
	u64 min_valid_ts;
	struct pulse_elem *p;

	/* there is no delta time with less than 2 pulses */
	if (pde->count < 2)
		return;

	if (pde->last_ts <= pde->window_size)
		return;

	min_valid_ts = pde->last_ts - pde->window_size;
	while ((p = pulse_queue_get_tail(pde)) != NULL) {
		if (p->ts >= min_valid_ts)
			return;
		pulse_queue_dequeue(pde);
	}
}

static bool pulse_queue_enqueue(struct pri_detector *pde, u64 ts)
{
	struct pulse_elem *p = pool_get_pulse_elem();
	if (p == NULL) {
		p = kmalloc(sizeof(*p), GFP_ATOMIC);
		if (p == NULL) {
			DFS_POOL_STAT_INC(pulse_alloc_error);
			return false;
		}
		DFS_POOL_STAT_INC(pulse_allocated);
		DFS_POOL_STAT_INC(pulse_used);
	}
	INIT_LIST_HEAD(&p->head);
	p->ts = ts;
	list_add(&p->head, &pde->pulses);
	pde->count++;
	pde->last_ts = ts;
	pulse_queue_check_window(pde);
	if (pde->count >= pde->max_count)
		pulse_queue_dequeue(pde);
	return true;
}

static bool pseq_handler_create_sequences(struct pri_detector *pde,
					  u64 ts, u32 min_count)
{
	struct pulse_elem *p;
	list_for_each_entry(p, &pde->pulses, head) {
		struct pri_sequence ps, *new_ps;
		struct pulse_elem *p2;
		u32 tmp_false_count;
		u64 min_valid_ts;
		u32 delta_ts = ts - p->ts;

		if (delta_ts < pde->rs->pri_min)
			/* ignore too small pri */
			continue;

		if (delta_ts > pde->rs->pri_max)
			/* stop on too large pri (sorted list) */
			break;

		/* build a new sequence with new potential pri */
		ps.count = 2;
		ps.count_falses = 0;
		ps.first_ts = p->ts;
		ps.last_ts = ts;
		ps.pri = GET_PRI_TO_USE(pde->rs->pri_min,
			pde->rs->pri_max, ts - p->ts);
		ps.dur = ps.pri * (pde->rs->ppb - 1)
				+ 2 * pde->rs->max_pri_tolerance;

		p2 = p;
		tmp_false_count = 0;
		min_valid_ts = ts - ps.dur;
		/* check which past pulses are candidates for new sequence */
		list_for_each_entry_continue(p2, &pde->pulses, head) {
			u32 factor;
			if (p2->ts < min_valid_ts)
				/* stop on crossing window border */
				break;
			/* check if pulse match (multi)PRI */
			factor = pde_get_multiple(ps.last_ts - p2->ts, ps.pri,
						  pde->rs->max_pri_tolerance);
			if (factor > 0) {
				ps.count++;
				ps.first_ts = p2->ts;
				/*
				 * on match, add the intermediate falses
				 * and reset counter
				 */
				ps.count_falses += tmp_false_count;
				tmp_false_count = 0;
			} else {
				/* this is a potential false one */
				tmp_false_count++;
			}
		}
		if (ps.count <= min_count)
			/* did not reach minimum count, drop sequence */
			continue;

		/* this is a valid one, add it */
		ps.deadline_ts = ps.first_ts + ps.dur;
		new_ps = pool_get_pseq_elem();
		if (new_ps == NULL) {
			new_ps = kmalloc(sizeof(*new_ps), GFP_ATOMIC);
			if (new_ps == NULL) {
				DFS_POOL_STAT_INC(pseq_alloc_error);
				return false;
			}
			DFS_POOL_STAT_INC(pseq_allocated);
			DFS_POOL_STAT_INC(pseq_used);
		}
		memcpy(new_ps, &ps, sizeof(ps));
		INIT_LIST_HEAD(&new_ps->head);
		list_add(&new_ps->head, &pde->sequences);
	}
	return true;
}

/* check new ts and add to all matching existing sequences */
static u32
pseq_handler_add_to_existing_seqs(struct pri_detector *pde, u64 ts)
{
	u32 max_count = 0;
	struct pri_sequence *ps, *ps2;
	list_for_each_entry_safe(ps, ps2, &pde->sequences, head) {
		u32 delta_ts;
		u32 factor;

		/* first ensure that sequence is within window */
		if (ts > ps->deadline_ts) {
			list_del_init(&ps->head);
			pool_put_pseq_elem(ps);
			continue;
		}

		delta_ts = ts - ps->last_ts;
		factor = pde_get_multiple(delta_ts, ps->pri,
					  pde->rs->max_pri_tolerance);
		if (factor > 0) {
			ps->last_ts = ts;
			ps->count++;

			if (max_count < ps->count)
				max_count = ps->count;
		} else {
			ps->count_falses++;
		}
	}
	return max_count;
}

static struct pri_sequence *
pseq_handler_check_detection(struct pri_detector *pde)
{
	struct pri_sequence *ps;

	if (list_empty(&pde->sequences))
		return NULL;

	list_for_each_entry(ps, &pde->sequences, head) {
		/*
		 * we assume to have enough matching confidence if we
		 * 1) have enough pulses
		 * 2) have more matching than false pulses
		 */
		if ((ps->count >= pde->rs->ppb_thresh) &&
		    (ps->count * pde->rs->num_pri >= ps->count_falses))
			return ps;
	}
	return NULL;
}


/* free pulse queue and sequences list and give objects back to pools */
static void pri_detector_reset(struct pri_detector *pde, u64 ts)
{
	struct pri_sequence *ps, *ps0;
	struct pulse_elem *p, *p0;
	list_for_each_entry_safe(ps, ps0, &pde->sequences, head) {
		list_del_init(&ps->head);
		pool_put_pseq_elem(ps);
	}
	list_for_each_entry_safe(p, p0, &pde->pulses, head) {
		list_del_init(&p->head);
		pool_put_pulse_elem(p);
	}
	pde->count = 0;
	pde->last_ts = ts;
}

static void pri_detector_exit(struct pri_detector *de)
{
	pri_detector_reset(de, 0);
	pool_deregister_ref();
	kfree(de);
}

static struct pri_sequence *pri_detector_add_pulse(struct pri_detector *de,
						   struct pulse_event *event)
{
	u32 max_updated_seq;
	struct pri_sequence *ps;
	u64 ts = event->ts;
	const struct radar_detector_specs *rs = de->rs;

	/* ignore pulses not within width range */
	if ((rs->width_min > event->width) || (rs->width_max < event->width))
		return NULL;

	if ((ts - de->last_ts) < rs->max_pri_tolerance)
		/* if delta to last pulse is too short, don't use this pulse */
		return NULL;
	/* radar detector spec needs chirp, but not detected */
	if (rs->chirp && rs->chirp != event->chirp)
		return NULL;

	de->last_ts = ts;

	max_updated_seq = pseq_handler_add_to_existing_seqs(de, ts);

	if (!pseq_handler_create_sequences(de, ts, max_updated_seq)) {
		pri_detector_reset(de, ts);
		return NULL;
	}

	ps = pseq_handler_check_detection(de);

	if (ps == NULL)
		pulse_queue_enqueue(de, ts);

	return ps;
}

struct pri_detector *pri_detector_init(const struct radar_detector_specs *rs)
{
	struct pri_detector *de;

	de = kzalloc(sizeof(*de), GFP_ATOMIC);
	if (de == NULL)
		return NULL;
	de->exit = pri_detector_exit;
	de->add_pulse = pri_detector_add_pulse;
	de->reset = pri_detector_reset;

	INIT_LIST_HEAD(&de->sequences);
	INIT_LIST_HEAD(&de->pulses);
	de->window_size = rs->pri_max * rs->ppb * rs->num_pri;
	de->max_count = rs->ppb * 2;
	de->rs = rs;

	pool_register_ref();
	return de;
}
