/*
 * Copyright (c) 2014-2016 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.
 */

/**
 *  DOC: wlan_hdd_green_ap.c
 *
 *  WLAN Host Device Driver Green AP implementation
 *
 */

/* Include Files */
#include <wlan_hdd_main.h>
#include <wlan_hdd_misc.h>
#include "wlan_hdd_green_ap.h"
#include "wma_api.h"
#include "cds_concurrency.h"

#define GREEN_AP_PS_ON_TIME        (0)
#define GREEN_AP_PS_DELAY_TIME     (20)

/**
 * enum hdd_green_ap_ps_state - Green-AP power save states
 * @GREEN_AP_PS_IDLE_STATE: the Green_AP is not enabled
 * @GREEN_AP_PS_OFF_STATE: in Power Saving OFF state
 * @GREEN_AP_PS_WAIT_STATE: in transition to Power Saving ON state
 * @GREEN_AP_PS_ON_STATE: in Power Saving ON state
 */
enum hdd_green_ap_ps_state {
	GREEN_AP_PS_IDLE_STATE = 1,
	GREEN_AP_PS_OFF_STATE,
	GREEN_AP_PS_WAIT_STATE,
	GREEN_AP_PS_ON_STATE,
};

/**
 * enum hdd_green_ap_event - Green-AP power save events
 * @GREEN_AP_PS_START_EVENT: event to indicate to enable Green_AP
 * @GREEN_AP_PS_START_EVENT: event to indicate to disable Green_AP
 * @GREEN_AP_ADD_STA_EVENT: event to indicate a new STA connected
 * @GREEN_AP_DEL_STA_EVENT: event to indicate a STA disconnected
 * @GREEN_AP_PS_ON_EVENT: event to indicate to enter Power Saving state
 * @GREEN_AP_PS_WAIT_EVENT: event to indicate in the transition to Power Saving
 */
enum hdd_green_ap_event {
	GREEN_AP_PS_START_EVENT = 1,
	GREEN_AP_PS_STOP_EVENT,
	GREEN_AP_ADD_STA_EVENT,
	GREEN_AP_DEL_STA_EVENT,
	GREEN_AP_PS_ON_EVENT,
	GREEN_AP_PS_WAIT_EVENT,
};

/**
 * struct hdd_green_ap_ctx - Green-AP context
 * @ps_enable: Whether or not Green AP is enabled
 * @ps_on_time: Amount of time to stay in Green AP power saving state
 * @ps_delay_time: Amount of time to delay when changing states
 * @num_nodes: Number of connected clients
 * @ps_state: Current state
 * @ps_event: Event to trigger when timer expires
 * @ps_timer: Event timer
 * @egap_support: Enhanced Green AP support flag
 */
struct hdd_green_ap_ctx {
	uint8_t ps_enable;
	uint32_t ps_on_time;
	uint32_t ps_delay_time;
	uint32_t num_nodes;

	enum hdd_green_ap_ps_state ps_state;
	enum hdd_green_ap_event ps_event;

	qdf_mc_timer_t ps_timer;

	bool egap_support;
};

/**
 * hdd_green_ap_update() - update the current State and Event
 * @hdd_ctx: Global HDD context
 * @state: New state
 * @event: New event
 *
 * Return: none
 */
static void hdd_green_ap_update(struct hdd_context_s *hdd_ctx,
				enum hdd_green_ap_ps_state state,
				enum hdd_green_ap_event event)
{
	struct hdd_green_ap_ctx *green_ap = hdd_ctx->green_ap_ctx;

	green_ap->ps_state = state;
	green_ap->ps_event = event;
}

/**
 * hdd_green_ap_enable() - Send Green AP configuration to firmware
 * @adapter: Adapter upon which Green AP is being configured
 * @enable: Flag which indicates if Green AP is being enabled or disabled
 *
 * Return: 0 upon success, non-zero upon failure
 */
static int hdd_green_ap_enable(hdd_adapter_t *adapter, uint8_t enable)
{
	int ret;

	hdd_notice("Set Green-AP val: %d", enable);

	ret = wma_cli_set_command(adapter->sessionId,
				  WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID,
				  enable, DBG_CMD);

	return ret;
}

/**
 * hdd_green_ap_mc() - Green AP state machine
 * @hdd_ctx: HDD global context
 * @event: New event being processed
 *
 * Return: none
 */
static void hdd_green_ap_mc(struct hdd_context_s *hdd_ctx,
			    enum hdd_green_ap_event event)
{
	struct hdd_green_ap_ctx *green_ap;
	hdd_adapter_t *adapter;

	green_ap = hdd_ctx->green_ap_ctx;
	if (green_ap == NULL)
		return;

	hdd_notice("Green-AP event: %d, state: %d, num_nodes: %d",
		   event, green_ap->ps_state, green_ap->num_nodes);

	/* handle the green ap ps event */
	switch (event) {
	case GREEN_AP_PS_START_EVENT:
		green_ap->ps_enable = 1;
		break;

	case GREEN_AP_PS_STOP_EVENT:
		green_ap->ps_enable = 0;
		break;

	case GREEN_AP_ADD_STA_EVENT:
		green_ap->num_nodes++;
		break;

	case GREEN_AP_DEL_STA_EVENT:
		if (green_ap->num_nodes)
			green_ap->num_nodes--;
		break;

	case GREEN_AP_PS_ON_EVENT:
	case GREEN_AP_PS_WAIT_EVENT:
		break;

	default:
		hdd_err("invalid event %d", event);
		break;
	}

	adapter = hdd_get_adapter(hdd_ctx, QDF_SAP_MODE);
	if (adapter == NULL) {
		hdd_err("Green-AP no SAP adapter");
		goto done;
	}

	/* Confirm that power save is enabled before doing state transitions */
	if (!green_ap->ps_enable) {
		hdd_notice("Green-AP is disabled");
		hdd_green_ap_update(hdd_ctx,
				    GREEN_AP_PS_OFF_STATE,
				    GREEN_AP_PS_WAIT_EVENT);
		if (hdd_green_ap_enable(adapter, 0))
			hdd_err("failed to set green ap mode");
		goto done;
	}

	/* handle the green ap ps state */
	switch (green_ap->ps_state) {
	case GREEN_AP_PS_IDLE_STATE:
		hdd_green_ap_update(hdd_ctx,
				    GREEN_AP_PS_OFF_STATE,
				    GREEN_AP_PS_WAIT_EVENT);
		break;

	case GREEN_AP_PS_OFF_STATE:
		if (!green_ap->num_nodes) {
			hdd_green_ap_update(hdd_ctx,
					    GREEN_AP_PS_WAIT_STATE,
					    GREEN_AP_PS_WAIT_EVENT);
			qdf_mc_timer_start(&green_ap->ps_timer,
					   green_ap->ps_delay_time);
		}
		break;

	case GREEN_AP_PS_WAIT_STATE:
		if (!green_ap->num_nodes) {
			hdd_green_ap_update(hdd_ctx,
					    GREEN_AP_PS_ON_STATE,
					    GREEN_AP_PS_WAIT_EVENT);

			hdd_green_ap_enable(adapter, 1);

			if (green_ap->ps_on_time) {
				hdd_green_ap_update(hdd_ctx,
						    0,
						    GREEN_AP_PS_WAIT_EVENT);
				qdf_mc_timer_start(&green_ap->ps_timer,
						   green_ap->ps_on_time);
			}
		} else {
			hdd_green_ap_update(hdd_ctx,
					    GREEN_AP_PS_OFF_STATE,
					    GREEN_AP_PS_WAIT_EVENT);
		}
		break;

	case GREEN_AP_PS_ON_STATE:
		if (green_ap->num_nodes) {
			if (hdd_green_ap_enable(adapter, 0)) {
				hdd_err("FAILED TO SET GREEN-AP mode");
				goto done;
			}
			hdd_green_ap_update(hdd_ctx,
					    GREEN_AP_PS_OFF_STATE,
					    GREEN_AP_PS_WAIT_EVENT);
		} else if ((green_ap->ps_event == GREEN_AP_PS_WAIT_EVENT)
			   && (green_ap->ps_on_time)) {

			/* ps_on_time timeout, switch to ps off */
			hdd_green_ap_update(hdd_ctx,
					    GREEN_AP_PS_WAIT_STATE,
					    GREEN_AP_PS_ON_EVENT);

			if (hdd_green_ap_enable(adapter, 0)) {
				hdd_err("FAILED TO SET GREEN-AP mode");
				goto done;
			}

			qdf_mc_timer_start(&green_ap->ps_timer,
					   green_ap->ps_delay_time);
		}
		break;

	default:
		hdd_err("invalid state %d", green_ap->ps_state);
		hdd_green_ap_update(hdd_ctx, GREEN_AP_PS_OFF_STATE,
				    GREEN_AP_PS_WAIT_EVENT);
		break;
	}

done:
	return;
}

/**
 * hdd_green_ap_timer_fn() - Green AP Timer handler
 * @ctx: Global HDD context
 *
 * Return: none
 */
static void hdd_green_ap_timer_fn(void *ctx)
{
	struct hdd_context_s *hdd_ctx = ctx;
	struct hdd_green_ap_ctx *green_ap;

	if (wlan_hdd_validate_context(hdd_ctx))
		return;

	green_ap = hdd_ctx->green_ap_ctx;
	if (green_ap)
		hdd_green_ap_mc(hdd_ctx, green_ap->ps_event);
}

/**
 * hdd_green_ap_attach() - Attach Green AP context to HDD context
 * @hdd_ctx: Global HDD contect
 *
 * Return: QDF_STATUS_SUCCESS on success, otherwise QDF_STATUS_E_** error
 */
static QDF_STATUS hdd_green_ap_attach(struct hdd_context_s *hdd_ctx)
{
	struct hdd_green_ap_ctx *green_ap;
	QDF_STATUS status = QDF_STATUS_SUCCESS;

	ENTER();

	green_ap = qdf_mem_malloc(sizeof(*green_ap));
	if (!green_ap) {
		hdd_alert("Memory allocation for Green-AP failed!");
		status = QDF_STATUS_E_NOMEM;
		goto error;
	}

	green_ap->ps_state = GREEN_AP_PS_OFF_STATE;
	green_ap->ps_event = 0;
	green_ap->num_nodes = 0;
	green_ap->ps_on_time = GREEN_AP_PS_ON_TIME;
	green_ap->ps_delay_time = GREEN_AP_PS_DELAY_TIME;

	qdf_mc_timer_init(&green_ap->ps_timer,
			  QDF_TIMER_TYPE_SW,
			  hdd_green_ap_timer_fn, hdd_ctx);

error:
	hdd_ctx->green_ap_ctx = green_ap;

	EXIT();
	return status;
}

/**
 * hdd_green_ap_deattach() - Detach Green AP context from HDD context
 * @hdd_ctx: Global HDD contect
 *
 * Return: QDF_STATUS_SUCCESS on success, otherwise QDF_STATUS_E_** error
 */
static QDF_STATUS hdd_green_ap_deattach(struct hdd_context_s *hdd_ctx)
{
	struct hdd_green_ap_ctx *green_ap = hdd_ctx->green_ap_ctx;
	QDF_STATUS status = QDF_STATUS_SUCCESS;

	ENTER();

	if (green_ap == NULL) {
		hdd_notice("Green-AP is not enabled");
		status = QDF_STATUS_E_NOSUPPORT;
		goto done;
	}

	/* check if the timer status is destroyed */
	if (QDF_TIMER_STATE_RUNNING ==
	    qdf_mc_timer_get_current_state(&green_ap->ps_timer))
		qdf_mc_timer_stop(&green_ap->ps_timer);

	/* Destroy the Green AP timer */
	if (!QDF_IS_STATUS_SUCCESS(qdf_mc_timer_destroy(&green_ap->ps_timer)))
		hdd_notice("Cannot deallocate Green-AP's timer");

	/* release memory */
	qdf_mem_zero(green_ap, sizeof(*green_ap));
	qdf_mem_free(green_ap);
	hdd_ctx->green_ap_ctx = NULL;

done:

	EXIT();
	return status;
}

/*
 * hdd_green_ap_init() - Initialize Green AP feature
 * (public function documented in wlan_hdd_green_ap.h)
 */
void hdd_green_ap_init(struct hdd_context_s *hdd_ctx)
{
	if (!QDF_IS_STATUS_SUCCESS(hdd_green_ap_attach(hdd_ctx)))
		hdd_err("Failed to allocate Green-AP resource");
}

/*
 * hdd_green_ap_deinit() - De-initialize Green AP feature
 * (public function documented in wlan_hdd_green_ap.h)
 */
void hdd_green_ap_deinit(struct hdd_context_s *hdd_ctx)
{
	if (!QDF_IS_STATUS_SUCCESS(hdd_green_ap_deattach(hdd_ctx)))
		hdd_err("Cannot deallocate Green-AP resource");
}

/*
 * hdd_is_egap_enabled() - Get Enhance Green AP feature status
 * @fw_egap_support: flag whether firmware supports egap or not
 * @cfg: pointer to the struct hdd_config
 *
 * Return: true if firmware, feature_flag and ini are all enabled the egap
 */
static bool hdd_is_egap_enabled(bool fw_egap_support, struct hdd_config *cfg)
{
	/* check if the firmware and ini are both enabled the egap,
	 * and also the feature_flag enable.
	 */
	if (fw_egap_support && cfg->enable_egap &&
			cfg->egap_feature_flag)
		return true;
	return false;
}

/*
 * hdd_enable_egap() - Enable Enhance Green AP
 * @hdd_ctx: HDD global context
 *
 * Return: 0 on success, negative errno on failure
 */
int hdd_enable_egap(struct hdd_context_s *hdd_ctx)
{
	struct hdd_config *cfg;

	if (!hdd_ctx) {
		hdd_err("hdd context is NULL");
		return -EINVAL;
	}

	cfg = hdd_ctx->config;

	if (!cfg) {
		hdd_err("hdd cfg is NULL");
		return -EINVAL;
	}

	if (!hdd_ctx->green_ap_ctx) {
		hdd_err("green ap context is NULL");
		return -EINVAL;
	}

	if (!hdd_is_egap_enabled(hdd_ctx->green_ap_ctx->egap_support,
			hdd_ctx->config))
		return -ENOTSUPP;

	if (QDF_STATUS_SUCCESS != sme_send_egap_conf_params(cfg->enable_egap,
			cfg->egap_inact_time,
			cfg->egap_wait_time,
			cfg->egap_feature_flag))
		return -EINVAL;
	return 0;
}

/*
 * hdd_green_ap_start_bss() - Notify Green AP of Start BSS event
 * (public function documented in wlan_hdd_green_ap.h)
 */
void hdd_green_ap_start_bss(struct hdd_context_s *hdd_ctx)
{
	struct hdd_config *cfg;

	if (!hdd_ctx) {
		hdd_err("hdd context is NULL");
		return;
	}

	cfg = hdd_ctx->config;

	if (!cfg) {
		hdd_err("hdd cfg is NULL");
		return;
	}

	if (!hdd_ctx->green_ap_ctx) {
		hdd_err("Green AP is not enabled. green_ap_ctx = NULL");
		return;
	}

	if (hdd_is_egap_enabled(hdd_ctx->green_ap_ctx->egap_support,
			hdd_ctx->config))
		return;

	if ((hdd_ctx->concurrency_mode & QDF_SAP_MASK) &&
			!(hdd_ctx->concurrency_mode & (QDF_SAP_MASK)) &&
			cfg->enable2x2 && cfg->enableGreenAP) {
		hdd_notice("Green AP enabled - sta_con: %d, 2x2: %d, GAP: %d",
			QDF_STA_MASK & hdd_ctx->concurrency_mode,
			cfg->enable2x2, cfg->enableGreenAP);
		hdd_green_ap_mc(hdd_ctx, GREEN_AP_PS_START_EVENT);
	} else {
		hdd_green_ap_mc(hdd_ctx, GREEN_AP_PS_STOP_EVENT);
		hdd_notice("Green-AP: is disabled, due to sta_concurrency: %d, enable2x2: %d, enableGreenAP: %d",
			   QDF_STA_MASK & hdd_ctx->concurrency_mode,
			   cfg->enable2x2, cfg->enableGreenAP);
	}
}

/*
 * hdd_green_ap_stop_bss() - Notify Green AP of Stop BSS event
 * (public function documented in wlan_hdd_green_ap.h)
 */
void hdd_green_ap_stop_bss(struct hdd_context_s *hdd_ctx)
{
	struct hdd_config *cfg;

	if (!hdd_ctx) {
		hdd_err("hdd context is NULL");
		return;
	}

	cfg = hdd_ctx->config;

	if (!cfg) {
		hdd_err("hdd cfg is NULL");
		return;
	}

	if (!hdd_ctx->green_ap_ctx) {
		hdd_err("Green AP is not enabled. green_ap_ctx = NULL");
		return;
	}

	if (hdd_is_egap_enabled(hdd_ctx->green_ap_ctx->egap_support,
			hdd_ctx->config))
		return;

	/* For AP+AP mode, only trigger GREEN_AP_PS_STOP_EVENT, when the
	 * last AP stops.
	 */

	if (1 == (hdd_ctx->no_of_open_sessions[QDF_SAP_MODE]))
		hdd_green_ap_mc(hdd_ctx, GREEN_AP_PS_STOP_EVENT);
}

/*
 * hdd_green_ap_add_sta() - Notify Green AP of Add Station event
 * (public function documented in wlan_hdd_green_ap.h)
 */
void hdd_green_ap_add_sta(struct hdd_context_s *hdd_ctx)
{
	struct hdd_config *cfg;

	if (!hdd_ctx) {
		hdd_err("hdd context is NULL");
		return;
	}

	cfg = hdd_ctx->config;

	if (!cfg) {
		hdd_err("hdd cfg is NULL");
		return;
	}

	if (!hdd_ctx->green_ap_ctx) {
		hdd_err("Green AP is not enabled. green_ap_ctx = NULL");
		return;
	}

	if (hdd_is_egap_enabled(hdd_ctx->green_ap_ctx->egap_support,
			hdd_ctx->config))
		return;

	hdd_green_ap_mc(hdd_ctx, GREEN_AP_ADD_STA_EVENT);
}

/*
 * hdd_green_ap_del_sta() - Notify Green AP of Delete Station event
 * (public function documented in wlan_hdd_green_ap.h)
 */
void hdd_green_ap_del_sta(struct hdd_context_s *hdd_ctx)
{
	struct hdd_config *cfg;

	if (!hdd_ctx) {
		hdd_err("hdd context is NULL");
		return;
	}

	cfg = hdd_ctx->config;

	if (!cfg) {
		hdd_err("hdd cfg is NULL");
		return;
	}

	if (!hdd_ctx->green_ap_ctx) {
		hdd_err("Green AP is not enabled. green_ap_ctx = NULL");
		return;
	}

	if (hdd_is_egap_enabled(hdd_ctx->green_ap_ctx->egap_support,
			hdd_ctx->config))
		return;

	hdd_green_ap_mc(hdd_ctx, GREEN_AP_DEL_STA_EVENT);
}

/*
 * hdd_green_ap_target_config() - Handle Green AP target configuration
 * (public function documented in wlan_hdd_green_ap.h)
 *
 * Implementation notes:
 * Target indicates whether or not Enhanced Green AP (EGAP) is supported
 */
void hdd_green_ap_target_config(struct hdd_context_s *hdd_ctx,
				struct wma_tgt_cfg *target_config)
{
	struct hdd_green_ap_ctx *green_ap = hdd_ctx->green_ap_ctx;

	green_ap->egap_support = target_config->egap_support;
}
