/*
 * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved.
 *
 * 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 "dp_cal_client_api.h"
#include "qdf_module.h"

/* dp_cal_client_attach - function to attach cal client timer
 * @cal_client_ctx: cal client timer context
 * @pdev: pdev handle
 * @osdev: device pointer
 * @dp_iterate_peer_list : function pointer to iterate and update peer stats
 *
 * return: void
 */
void dp_cal_client_attach(struct cdp_cal_client **cal_client_ctx,
			  struct cdp_pdev *pdev,
			  qdf_device_t osdev,
			  void (*dp_iterate_peer_list)(struct cdp_pdev *))
{
	struct cal_client *cal_cl;

	*cal_client_ctx = qdf_mem_malloc(sizeof(struct cal_client));

	if (!(*cal_client_ctx))
		return;

	cal_cl = (struct cal_client *)(*cal_client_ctx);
	cal_cl->iterate_update_peer_list = dp_iterate_peer_list;
	cal_cl->pdev_hdl = pdev;

	qdf_timer_init(osdev, &cal_cl->cal_client_timer,
		       dp_cal_client_stats_timer_fn, *cal_client_ctx,
		       QDF_TIMER_TYPE_WAKE_APPS);
}

qdf_export_symbol(dp_cal_client_attach);

/* dp_cal_client_detach - detach cal client timer
 * @cal_client_ctx: cal client timer context
 *
 * return: void
 */
void dp_cal_client_detach(struct cdp_cal_client **cal_client_ctx)
{
	struct cal_client *cal_cl;

	if (*cal_client_ctx) {
		cal_cl = (struct cal_client *)*cal_client_ctx;

		qdf_timer_stop(&cal_cl->cal_client_timer);
		qdf_timer_free(&cal_cl->cal_client_timer);
		qdf_mem_free(cal_cl);
		*cal_client_ctx = NULL;
	}
}

qdf_export_symbol(dp_cal_client_detach);

/* dp_cal_client_timer_start- api to start cal client timer
 * @ctx: cal client timer ctx
 *
 * return: void
 */
void dp_cal_client_timer_start(void *ctx)
{
	struct cal_client *cal_cl;

	if (ctx) {
		cal_cl  = (struct cal_client *)ctx;
		qdf_timer_start(&cal_cl->cal_client_timer, DP_CAL_CLIENT_TIME);
	}
}

qdf_export_symbol(dp_cal_client_timer_start);

/* dp_cal_client_timer_stop- api to stop cal client timer
 * @ctx: cal client timer ctx
 *
 * return: void
 */
void dp_cal_client_timer_stop(void *ctx)
{
	struct cal_client *cal_cl;

	if (ctx) {
		cal_cl = (struct cal_client *)ctx;
		qdf_timer_sync_cancel(&cal_cl->cal_client_timer);
		qdf_timer_stop(&cal_cl->cal_client_timer);
	}
}

qdf_export_symbol(dp_cal_client_timer_stop);

/* dp_cal_client_stats_timer_fn- function called on timer interval
 * @ctx: cal client timer ctx
 *
 * return: void
 */
void dp_cal_client_stats_timer_fn(void *ctx)
{
	struct cal_client *cal_cl = (struct cal_client *)ctx;

	if (!cal_cl)
		return;

	cal_cl->iterate_update_peer_list(cal_cl->pdev_hdl);
	qdf_timer_mod(&cal_cl->cal_client_timer, DP_CAL_CLIENT_TIME);
}

qdf_export_symbol(dp_cal_client_stats_timer_fn);

/*dp_cal_client_update_peer_stats - update peer stats in peer
 * @peer_stats: cdp peer stats pointer
 *
 * return: void
 */
void dp_cal_client_update_peer_stats(struct cdp_peer_stats *peer_stats)
{
	uint32_t temp_rx_bytes = peer_stats->rx.to_stack.bytes;
	uint32_t temp_rx_data = peer_stats->rx.to_stack.num;
	uint32_t temp_tx_bytes = peer_stats->tx.tx_success.bytes;
	uint32_t temp_tx_data = peer_stats->tx.tx_success.num;
	uint32_t temp_tx_ucast_pkts = peer_stats->tx.ucast.num;

	peer_stats->rx.rx_byte_rate = temp_rx_bytes -
					peer_stats->rx.rx_bytes_success_last;
	peer_stats->rx.rx_data_rate  = temp_rx_data -
					peer_stats->rx.rx_data_success_last;
	peer_stats->tx.tx_byte_rate = temp_tx_bytes -
					peer_stats->tx.tx_bytes_success_last;
	peer_stats->tx.tx_data_rate  = temp_tx_data -
					peer_stats->tx.tx_data_success_last;
	peer_stats->tx.tx_data_ucast_rate = temp_tx_ucast_pkts -
					peer_stats->tx.tx_data_ucast_last;

	/* Check tx and rx packets in last one second, and increment
	 * inactive time for peer
	 */
	if (peer_stats->tx.tx_data_rate || peer_stats->rx.rx_data_rate)
		peer_stats->tx.inactive_time = 0;
	else
		peer_stats->tx.inactive_time++;

	peer_stats->rx.rx_bytes_success_last = temp_rx_bytes;
	peer_stats->rx.rx_data_success_last = temp_rx_data;
	peer_stats->tx.tx_bytes_success_last = temp_tx_bytes;
	peer_stats->tx.tx_data_success_last = temp_tx_data;
	peer_stats->tx.tx_data_ucast_last = temp_tx_ucast_pkts;

	if (peer_stats->tx.tx_data_ucast_rate) {
		if (peer_stats->tx.tx_data_ucast_rate >
				peer_stats->tx.tx_data_rate)
			peer_stats->tx.last_per =
				((peer_stats->tx.tx_data_ucast_rate -
					peer_stats->tx.tx_data_rate) * 100) /
				peer_stats->tx.tx_data_ucast_rate;
		else
			peer_stats->tx.last_per = 0;
	}

}

qdf_export_symbol(dp_cal_client_update_peer_stats);

