/*
 * Copyright (c) 2015 The Linux Foundation. All rights reserved.
 *
 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
 *
 *
 * 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.
 */

/*
 * This file was originally distributed by Qualcomm Atheros, Inc.
 * under proprietary terms before Copyright ownership was assigned
 * to the Linux Foundation.
 */

/**
 * DOC: hif_napi.c
 *
 * HIF NAPI interface implementation
 */

#include <string.h> /* memset */

#include <cds_api.h>
#include <hif_napi.h>
#include <hif_debug.h>
#include <hif_io32.h>
#include <ce_api.h>

enum napi_decision_vector {
	HIF_NAPI_NOEVENT = 0,
	HIF_NAPI_INITED  = 1,
	HIF_NAPI_CONF_UP = 2
};
#define ENABLE_NAPI_MASK (HIF_NAPI_INITED | HIF_NAPI_CONF_UP)

/**
 * hif_napi_create() - creates the NAPI structures for a given CE
 * @hif    : pointer to hif context
 * @pipe_id: the CE id on which the instance will be created
 * @poll   : poll function to be used for this NAPI instance
 * @budget : budget to be registered with the NAPI instance
 * @scale  : scale factor on the weight (to scaler budget to 1000)
 *
 * Description:
 *    Creates NAPI instances. This function is called
 *    unconditionally during initialization. It creates
 *    napi structures through the proper HTC/HIF calls.
 *    The structures are disabled on creation.
 *    Note that for each NAPI instance a separate dummy netdev is used
 *
 * Return:
 * < 0: error
 * = 0: <should never happen>
 * > 0: id of the created object (for multi-NAPI, number of objects created)
 */
int hif_napi_create(struct ol_softc   *hif,
		    uint8_t            pipe_id,
		    int (*poll)(struct napi_struct *, int),
		    int                budget,
		    int                scale)
{
	struct qca_napi_data *napid;
	struct qca_napi_info *napii;

	NAPI_DEBUG("-->(pipe=%d, budget=%d, scale=%d)\n",
		   pipe_id, budget, scale);
	NAPI_DEBUG("hif->napi_data.state = 0x%08x\n",
		   hif->napi_data.state);
	NAPI_DEBUG("hif->napi_data.ce_map = 0x%08x\n",
		   hif->napi_data.ce_map);

	napid = &(hif->napi_data);
	if (0 == (napid->state &  HIF_NAPI_INITED)) {
		memset(napid, 0, sizeof(struct qca_napi_data));
		mutex_init(&(napid->mutex));

		init_dummy_netdev(&(napid->netdev));

		napid->state |= HIF_NAPI_INITED;
		HIF_INFO("%s: NAPI structures initialized\n", __func__);

		NAPI_DEBUG("NAPI structures initialized\n");
	}
	napii = &(napid->napis[pipe_id]);
	memset(napii, 0, sizeof(struct qca_napi_info));
	napii->scale = scale;
	napii->id    = NAPI_PIPE2ID(pipe_id);

	NAPI_DEBUG("adding napi=%p to netdev=%p (poll=%p, bdgt=%d)\n",
		   &(napii->napi), &(napid->netdev), poll, budget);
	netif_napi_add(&(napid->netdev), &(napii->napi), poll, budget);

	NAPI_DEBUG("after napi_add\n");
	NAPI_DEBUG("napi=0x%p, netdev=0x%p\n",
		   &(napii->napi), &(napid->netdev));
	NAPI_DEBUG("napi.dev_list.prev=0x%p, next=0x%p\n",
		   napii->napi.dev_list.prev, napii->napi.dev_list.next);
	NAPI_DEBUG("dev.napi_list.prev=0x%p, next=0x%p\n",
		   napid->netdev.napi_list.prev, napid->netdev.napi_list.next);

	/* It is OK to change the state variable below without protection
	   as there should be no-one around yet */
	napid->ce_map |= (0x01 << pipe_id);
	HIF_INFO("%s: NAPI id %d created for pipe %d\n", __func__,
		 napii->id, pipe_id);

	NAPI_DEBUG("NAPI id %d created for pipe %d\n", napii->id, pipe_id);
	NAPI_DEBUG("<--napi_id=%d]\n", napii->id);
	return napii->id;
}

/**
 *
 * hif_napi_destroy() - destroys the NAPI structures for a given instance
 * @hif   : pointer to hif context
 * @ce_id : the CE id whose napi instance will be destroyed
 * @force : if set, will destroy even if entry is active (de-activates)
 *
 * Description:
 *    Destroy a given NAPI instance. This function is called
 *    unconditionally during cleanup.
 *    Refuses to destroy an entry of it is still enabled (unless force=1)
 *    Marks the whole napi_data invalid if all instances are destroyed.
 *
 * Return:
 * -EINVAL: specific entry has not been created
 * -EPERM : specific entry is still active
 * 0 <    : error
 * 0 =    : success
 */
int hif_napi_destroy(struct ol_softc *hif,
		     uint8_t          id,
		     int              force)
{
	uint8_t ce = NAPI_ID2PIPE(id);
	int rc = 0;

	NAPI_DEBUG("-->(id=%d, force=%d)\n", id, force);

	if (0 == (hif->napi_data.state & HIF_NAPI_INITED)) {
		HIF_ERROR("%s: NAPI not initialized or entry %d not created\n",
			  __func__, id);
		rc = -EINVAL;
	} else if (0 == (hif->napi_data.ce_map & (0x01 << ce))) {
		HIF_ERROR("%s: NAPI instance %d (pipe %d) not created\n",
			  __func__, id, ce);
		rc = -EINVAL;
	} else {
		struct qca_napi_data *napid;
		struct qca_napi_info *napii;
		napid = &(hif->napi_data);
		napii = &(napid->napis[ce]);

		if (hif->napi_data.state == HIF_NAPI_CONF_UP) {
			if (force) {
				napi_disable(&(napii->napi));
				HIF_INFO("%s: NAPI entry %d force disabled\n",
					 __func__, id);
				NAPI_DEBUG("NAPI %d force disabled\n", id);
			} else {
				HIF_ERROR("%s: Cannot destroy active NAPI %d\n",
					  __func__, id);
				rc = -EPERM;
			}
		}
		if (0 == rc) {
			NAPI_DEBUG("before napi_del\n");
			NAPI_DEBUG("napi.dlist.prv=0x%p, next=0x%p\n",
				  napii->napi.dev_list.prev,
				  napii->napi.dev_list.next);
			NAPI_DEBUG("dev.napi_l.prv=0x%p, next=0x%p\n",
				   napid->netdev.napi_list.prev,
				   napid->netdev.napi_list.next);

			netif_napi_del(&(napii->napi));

			napid->ce_map &= ~(0x01 << ce);
			napii->scale  = 0;
			HIF_INFO("%s: NAPI %d destroyed\n", __func__, id);

			/* if there are no active instances and
			   if they are all destroyed,
			   set the whole structure to uninitialized state */
			if (napid->ce_map == 0) {
				/* hif->napi_data.state = 0; */
				memset(napid,
				       0, sizeof(struct qca_napi_data));
				HIF_INFO("%s: no NAPI instances. Zapped.\n",
					 __func__);
			}
		}
	}

	return rc;
}

/**
 *
 * hif_napi_get_all() - returns the address of the whole HIF NAPI structure
 * @hif: pointer to hif context
 *
 * Description:
 *    Returns the address of the whole structure
 *
 * Return:
 *  <addr>: address of the whole HIF NAPI structure
 */
inline struct qca_napi_data *hif_napi_get_all(struct ol_softc   *hif)
{
	return &(hif->napi_data);
}

/**
 *
 * hif_napi_event() - Decision-maker to enable/disable NAPI.
 * @hif : pointer to hif context
 * @evnt: event that has been detected
 * @data: more data regarding the event
 *
 * Description:
 *   This function decides whether or not NAPI should be enabled.
 *   NAPI will be enabled, if all the following is satisfied.
 *    1- has been enabled administratively:
 *       the .ini file has the enabled setting and it has not been disabled
 *           by an vendor command override later
 *
 * Return:
 *  < 0: some error
 *  = 0: NAPI is now disabled
 *  = 1: NAPI is now enabled
 */
int hif_napi_event(struct ol_softc *hif, enum qca_napi_event event, void *data)
{
	int      rc;
	uint32_t prev_state;
	int      i;
	struct napi_struct *napi;

	NAPI_DEBUG("-->(event=%d, aux=%p)\n", event, data);

	mutex_lock(&(hif->napi_data.mutex));
	prev_state = hif->napi_data.state;
	switch (event) {
	case NAPI_EVT_INI_FILE:
	case NAPI_EVT_CMD_STATE: {
		int on = (data != ((void *)0));
		HIF_INFO("%s: received evnt: CONF %s; v = %d (state=0x%0x)\n",
			 __func__,
			 (event == NAPI_EVT_INI_FILE)?".ini file":"cmd",
			 on, prev_state);
		if (on)
			if (prev_state & HIF_NAPI_CONF_UP) {
				HIF_INFO("%s: duplicate NAPI conf ON msg\n",
					 __func__);
			} else {
				HIF_INFO("%s: setting configuration to ON\n",
					 __func__);
				hif->napi_data.state |= HIF_NAPI_CONF_UP;
			}
		else /* off request */
			if (prev_state & HIF_NAPI_CONF_UP) {
				HIF_INFO("%s: setting configuration to OFF\n",
				 __func__);
				hif->napi_data.state &= ~HIF_NAPI_CONF_UP;
			} else {
				HIF_INFO("%s: duplicate NAPI conf OFF msg\n",
					 __func__);
			}
		break;
	}
	/* case NAPI_INIT_FILE/CMD_STATE */
	default: {
		HIF_ERROR("%s: unknown event: %d (data=0x%0lx)\n",
			  __func__, event, (unsigned long) data);
		break;
	} /* default */
	}; /* switch */


	mutex_unlock(&(hif->napi_data.mutex));

	if (prev_state != hif->napi_data.state) {
		if (hif->napi_data.state == ENABLE_NAPI_MASK) {
			rc = 1;
			for (i = 0; i < CE_COUNT_MAX; i++)
				if ((hif->napi_data.ce_map & (0x01 << i))) {
					napi = &(hif->napi_data.napis[i].napi);
					NAPI_DEBUG("enabling NAPI %d\n", i);
					napi_enable(napi);
				}
		} else {
			rc = 0;
			for (i = 0; i < CE_COUNT_MAX; i++)
				if (hif->napi_data.ce_map & (0x01 << i)) {
					napi = &(hif->napi_data.napis[i].napi);
					NAPI_DEBUG("disabling NAPI %d\n", i);
					napi_disable(napi);
				}
		}
	} else {
		HIF_INFO("%s: no change in hif napi state (still %d)\n",
			 __func__, prev_state);
		rc = (hif->napi_data.state == ENABLE_NAPI_MASK);
	}

	NAPI_DEBUG("<--[rc=%d]\n", rc);
	return rc;
}

/**
 * hif_napi_enabled() - checks whether NAPI is enabled for given ce or not
 * @hif: hif context
 * @ce : CE instance (or -1, to check if any CEs are enabled)
 *
 * Return: bool
 */
inline int hif_napi_enabled(struct ol_softc *hif, int ce)
{
	int rc;
	if (-1 == ce)
		rc = ((hif->napi_data.state == ENABLE_NAPI_MASK));
	else
		rc = ((hif->napi_data.state == ENABLE_NAPI_MASK) &&
		      (hif->napi_data.ce_map & (0x01 << ce)));
	return rc;
};

/**
 * hif_napi_enable_irq() - enables bus interrupts after napi_complete
 *
 * @hif: hif context
 * @id : id of NAPI instance calling this (used to determine the CE)
 *
 * Return: void
 */
inline void hif_napi_enable_irq(struct ol_softc *hif, int id)
{
	ce_irq_enable(hif, NAPI_ID2PIPE(id));
	return;
}


/**
 * hif_napi_schedule() - schedules napi, updates stats
 * @scn:  hif context
 * @ce_id: index of napi instance
 *
 * Return: void
 */
int hif_napi_schedule(struct ol_softc *scn, int ce_id)
{
	int cpu = smp_processor_id();

	scn->napi_data.napis[ce_id].stats[cpu].napi_schedules++;
	NAPI_DEBUG("scheduling napi %d (ce:%d)\n",
		   scn->napi_data.napis[ce_id].id, ce_id);
	napi_schedule(&(scn->napi_data.napis[ce_id].napi));

	return true;
}

/**
 * hif_napi_poll() - NAPI poll routine
 * @napi  : pointer to NAPI struct as kernel holds it
 * @budget:
 *
 * This is the body of the poll function.
 * The poll function is called by kernel. So, there is a wrapper
 * function in HDD, which in turn calls this function.
 * Two main reasons why the whole thing is not implemented in HDD:
 * a) references to things like ce_service that HDD is not aware of
 * b) proximity to the implementation of ce_tasklet, which the body
 *    of this function should be very close to.
 *
 * NOTE TO THE MAINTAINER:
 *  Consider this function and ce_tasklet very tightly coupled pairs.
 *  Any changes to ce_tasklet or this function may likely need to be
 *  reflected in the counterpart.
 *
 * Returns:
 *  int: the amount of work done in this poll ( <= budget)
 */
int hif_napi_poll(struct napi_struct *napi, int budget)
{
	int rc, normalized, bucket;
	int    cpu = smp_processor_id();
	struct ol_softc      *hif;
	struct qca_napi_info *napi_info;

	NAPI_DEBUG("%s -->(.., budget=%d)\n", budget);

	napi_info = (struct qca_napi_info *)
		container_of(napi, struct qca_napi_info, napi);
	napi_info->stats[cpu].napi_polls++;

	hif = (struct ol_softc *)cds_get_context(CDF_MODULE_ID_HIF);
	CDF_ASSERT(hif != NULL);
	rc = ce_per_engine_service(hif, NAPI_ID2PIPE(napi_info->id));
	HIF_INFO_HI("%s: ce_per_engine_service reports %d msgs processed",
		__func__, rc);
	napi_info->stats[cpu].napi_workdone += rc;
	normalized = (rc / napi_info->scale);
	/* do not return 0, if there was some work done,
	   even if it is below the scale   */
	if (rc)
		normalized++;
	bucket   = (normalized / QCA_NAPI_DEF_SCALE);
	napi_info->stats[cpu].napi_budget_uses[bucket]++;

	/* if ce_per engine reports 0, then we should make sure
	   poll is terminated */
	if (0 == rc)
		NAPI_DEBUG("%s:%d: nothing processed by CE. Completing NAPI\n",
			   __func__, __LINE__);

	if (rc <= HIF_NAPI_MAX_RECEIVES) {
		napi_info->stats[cpu].napi_completes++;
		/* enable interrupts */
		napi_complete(napi);
		hif_napi_enable_irq(hif, napi_info->id);

		/* support suspend/resume */
		cdf_atomic_dec(&(hif->active_tasklet_cnt));

		NAPI_DEBUG("%s:%d: napi_complete + enabling the interrupts\n",
			   __func__, __LINE__);
	}

	NAPI_DEBUG("%s <--[normalized=%d]\n", _func__, normalized);
	return normalized;
}
