/*
 * Copyright (c) 2011-2018 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 <qdf_atomic.h>         /* qdf_atomic_inc, etc. */
#include <qdf_lock.h>           /* qdf_os_spinlock */
#include <qdf_time.h>           /* qdf_system_ticks, etc. */
#include <qdf_nbuf.h>           /* qdf_nbuf_t */
#include <qdf_net_types.h>      /* QDF_NBUF_TX_EXT_TID_INVALID */

#include <cds_queue.h>          /* TAILQ */
#ifdef QCA_COMPUTE_TX_DELAY
#include <enet.h>               /* ethernet_hdr_t, etc. */
#include <ipv6_defs.h>          /* ipv6_traffic_class */
#endif

#include <ol_txrx_api.h>        /* ol_txrx_vdev_handle, etc. */
#include <ol_htt_tx_api.h>      /* htt_tx_compl_desc_id */
#include <ol_txrx_htt_api.h>    /* htt_tx_status */

#include <ol_ctrl_txrx_api.h>
#include <cdp_txrx_tx_delay.h>
#include <ol_txrx_types.h>      /* ol_txrx_vdev_t, etc */
#include <ol_tx_desc.h>         /* ol_tx_desc_find, ol_tx_desc_frame_free */
#ifdef QCA_COMPUTE_TX_DELAY
#include <ol_tx_classify.h>     /* ol_tx_dest_addr_find */
#endif
#include <ol_txrx_internal.h>   /* OL_TX_DESC_NO_REFS, etc. */
#include <ol_osif_txrx_api.h>
#include <ol_tx.h>              /* ol_tx_reinject */
#include <ol_tx_send.h>

#include <ol_cfg.h>             /* ol_cfg_is_high_latency */
#include <ol_tx_sched.h>
#ifdef QCA_SUPPORT_SW_TXRX_ENCAP
#include <ol_txrx_encap.h>      /* OL_TX_RESTORE_HDR, etc */
#endif
#include <ol_tx_queue.h>
#include <ol_txrx.h>
#include <pktlog_ac_fmt.h>
#include <cdp_txrx_handle.h>

void ol_tx_init_pdev(ol_txrx_pdev_handle pdev)
{
	qdf_atomic_add(ol_cfg_target_tx_credit(pdev->ctrl_pdev),
		       &pdev->target_tx_credit);
}

qdf_nbuf_t ol_tx_reinject(struct ol_txrx_vdev_t *vdev,
			  qdf_nbuf_t msdu, uint16_t peer_id)
{
	struct ol_tx_desc_t *tx_desc = NULL;
	struct ol_txrx_msdu_info_t msdu_info;

	msdu_info.htt.info.l2_hdr_type = vdev->pdev->htt_pkt_type;
	msdu_info.htt.info.ext_tid = HTT_TX_EXT_TID_INVALID;
	msdu_info.peer = NULL;
	msdu_info.htt.action.tx_comp_req = 0;
	msdu_info.tso_info.is_tso = 0;

	tx_desc = ol_tx_prepare_ll(vdev, msdu, &msdu_info);
	if (!tx_desc)
		return msdu;

	HTT_TX_DESC_POSTPONED_SET(*((uint32_t *)(tx_desc->htt_tx_desc)), true);

	htt_tx_desc_set_peer_id(tx_desc->htt_tx_desc, peer_id);

	ol_tx_send(vdev->pdev, tx_desc, msdu, vdev->vdev_id);

	return NULL;
}

/*
 * The TXRX module doesn't accept tx frames unless the target has
 * enough descriptors for them.
 * For LL, the TXRX descriptor pool is sized to match the target's
 * descriptor pool.  Hence, if the descriptor allocation in TXRX
 * succeeds, that guarantees that the target has room to accept
 * the new tx frame.
 */
struct ol_tx_desc_t *
ol_tx_prepare_ll(ol_txrx_vdev_handle vdev,
		 qdf_nbuf_t msdu,
		 struct ol_txrx_msdu_info_t *msdu_info)
{
	struct ol_tx_desc_t *tx_desc;
	struct ol_txrx_pdev_t *pdev = vdev->pdev;

	(msdu_info)->htt.info.frame_type = pdev->htt_pkt_type;
	tx_desc = ol_tx_desc_ll(pdev, vdev, msdu, msdu_info);
	if (qdf_unlikely(!tx_desc)) {
		/*
		 * If TSO packet, free associated
		 * remaining TSO segment descriptors
		 */
		if (qdf_nbuf_is_tso(msdu))
			ol_free_remaining_tso_segs(
					vdev, msdu_info, true);
		TXRX_STATS_MSDU_LIST_INCR(
				pdev, tx.dropped.host_reject, msdu);
		return NULL;
	}

	return tx_desc;
}

qdf_nbuf_t
ol_tx_non_std_ll(struct ol_txrx_vdev_t *vdev,
		 enum ol_tx_spec tx_spec,
		 qdf_nbuf_t msdu_list)
{
	qdf_nbuf_t msdu = msdu_list;
	htt_pdev_handle htt_pdev = vdev->pdev->htt_pdev;
	struct ol_txrx_msdu_info_t msdu_info;

	msdu_info.htt.info.l2_hdr_type = vdev->pdev->htt_pkt_type;
	msdu_info.htt.action.tx_comp_req = 0;

	/*
	 * The msdu_list variable could be used instead of the msdu var,
	 * but just to clarify which operations are done on a single MSDU
	 * vs. a list of MSDUs, use a distinct variable for single MSDUs
	 * within the list.
	 */
	while (msdu) {
		qdf_nbuf_t next;
		struct ol_tx_desc_t *tx_desc = NULL;

		msdu_info.htt.info.ext_tid = qdf_nbuf_get_tid(msdu);
		msdu_info.peer = NULL;
		msdu_info.tso_info.is_tso = 0;

		tx_desc = ol_tx_prepare_ll(vdev, msdu, &msdu_info);
		if (!tx_desc)
			return msdu;

		/*
		 * The netbuf may get linked into a different list inside the
		 * ol_tx_send function, so store the next pointer before the
		 * tx_send call.
		 */
		next = qdf_nbuf_next(msdu);

		if (tx_spec != OL_TX_SPEC_STD) {
			if (tx_spec & OL_TX_SPEC_NO_FREE) {
				tx_desc->pkt_type = OL_TX_FRM_NO_FREE;
			} else if (tx_spec & OL_TX_SPEC_TSO) {
				tx_desc->pkt_type = OL_TX_FRM_TSO;
			} else if (tx_spec & OL_TX_SPEC_NWIFI_NO_ENCRYPT) {
				uint8_t sub_type =
					ol_txrx_tx_raw_subtype(tx_spec);
				htt_tx_desc_type(htt_pdev, tx_desc->htt_tx_desc,
						 htt_pkt_type_native_wifi,
						 sub_type);
			} else if (ol_txrx_tx_is_raw(tx_spec)) {
				/* different types of raw frames */
				uint8_t sub_type =
					ol_txrx_tx_raw_subtype(tx_spec);
				htt_tx_desc_type(htt_pdev, tx_desc->htt_tx_desc,
						 htt_pkt_type_raw, sub_type);
			}
		}
		/*
		 * If debug display is enabled, show the meta-data being
		 * downloaded to the target via the HTT tx descriptor.
		 */
		htt_tx_desc_display(tx_desc->htt_tx_desc);
		ol_tx_send(vdev->pdev, tx_desc, msdu, vdev->vdev_id);
		msdu = next;
	}
	return NULL;            /* all MSDUs were accepted */
}

#if defined(HELIUMPLUS)
void ol_txrx_dump_frag_desc(char *msg, struct ol_tx_desc_t *tx_desc)
{
	uint32_t                *frag_ptr_i_p;
	int                     i;

	ol_txrx_err("OL TX Descriptor 0x%pK msdu_id %d\n",
		    tx_desc, tx_desc->id);
	ol_txrx_err("HTT TX Descriptor vaddr: 0x%pK paddr: %pad",
		    tx_desc->htt_tx_desc, &tx_desc->htt_tx_desc_paddr);
	ol_txrx_err("Fragment Descriptor 0x%pK (paddr=%pad)",
		    tx_desc->htt_frag_desc, &tx_desc->htt_frag_desc_paddr);

	/*
	 * it looks from htt_tx_desc_frag() that tx_desc->htt_frag_desc
	 * is already de-referrable (=> in virtual address space)
	 */
	frag_ptr_i_p = tx_desc->htt_frag_desc;

	/* Dump 6 words of TSO flags */
	print_hex_dump(KERN_DEBUG, "MLE Desc:TSO Flags:  ",
		       DUMP_PREFIX_NONE, 8, 4,
		       frag_ptr_i_p, 24, true);

	frag_ptr_i_p += 6; /* Skip 6 words of TSO flags */

	i = 0;
	while (*frag_ptr_i_p) {
		print_hex_dump(KERN_DEBUG, "MLE Desc:Frag Ptr:  ",
			       DUMP_PREFIX_NONE, 8, 4,
			       frag_ptr_i_p, 8, true);
		i++;
		if (i > 5) /* max 6 times: frag_ptr0 to frag_ptr5 */
			break;
		/* jump to next  pointer - skip length */
		frag_ptr_i_p += 2;
	}
}
#endif /* HELIUMPLUS */

struct ol_tx_desc_t *
ol_txrx_mgmt_tx_desc_alloc(
	struct ol_txrx_pdev_t *pdev,
	struct ol_txrx_vdev_t *vdev,
	qdf_nbuf_t tx_mgmt_frm,
	struct ol_txrx_msdu_info_t *tx_msdu_info)
{
	struct ol_tx_desc_t *tx_desc;

	/* For LL tx_comp_req is not used so initialized to 0 */
	tx_msdu_info->htt.action.tx_comp_req = 0;
	tx_desc = ol_tx_desc_ll(pdev, vdev, tx_mgmt_frm, tx_msdu_info);
	/* FIX THIS -
	 * The FW currently has trouble using the host's fragments table
	 * for management frames.  Until this is fixed, rather than
	 * specifying the fragment table to the FW, specify just the
	 * address of the initial fragment.
	 */
#if defined(HELIUMPLUS)
	/* ol_txrx_dump_frag_desc("ol_txrx_mgmt_send(): after ol_tx_desc_ll",
	 *			  tx_desc);
	 */
#endif /* defined(HELIUMPLUS) */
	if (tx_desc) {
		/*
		 * Following the call to ol_tx_desc_ll, frag 0 is the
		 * HTT tx HW descriptor, and the frame payload is in
		 * frag 1.
		 */
		htt_tx_desc_frags_table_set(
				pdev->htt_pdev,
				tx_desc->htt_tx_desc,
				qdf_nbuf_get_frag_paddr(tx_mgmt_frm, 1),
				0, 0);
#if defined(HELIUMPLUS) && defined(HELIUMPLUS_DEBUG)
		ol_txrx_dump_frag_desc(
				"after htt_tx_desc_frags_table_set",
				tx_desc);
#endif /* defined(HELIUMPLUS) */
	}

	return tx_desc;
}

int ol_txrx_mgmt_send_frame(
	struct ol_txrx_vdev_t *vdev,
	struct ol_tx_desc_t *tx_desc,
	qdf_nbuf_t tx_mgmt_frm,
	struct ol_txrx_msdu_info_t *tx_msdu_info,
	uint16_t chanfreq)
{
	struct ol_txrx_pdev_t *pdev = vdev->pdev;

	htt_tx_desc_set_chanfreq(tx_desc->htt_tx_desc, chanfreq);
	QDF_NBUF_CB_TX_PACKET_TRACK(tx_desc->netbuf) =
					QDF_NBUF_TX_PKT_MGMT_TRACK;
	ol_tx_send_nonstd(pdev, tx_desc, tx_mgmt_frm,
			  htt_pkt_type_mgmt);

	return 0;
}

#if defined(FEATURE_TSO)
void ol_free_remaining_tso_segs(ol_txrx_vdev_handle vdev,
				struct ol_txrx_msdu_info_t *msdu_info,
				bool is_tso_seg_mapping_done)
{
	struct qdf_tso_seg_elem_t *next_seg;
	struct qdf_tso_seg_elem_t *free_seg = msdu_info->tso_info.curr_seg;
	struct ol_txrx_pdev_t *pdev;
	bool is_last_seg = false;

	if (qdf_unlikely(!vdev)) {
		ol_txrx_err("vdev is null");
		return;
	}

	pdev = vdev->pdev;
	if (qdf_unlikely(!pdev)) {
		ol_txrx_err("pdev is null");
		return;
	}

	/*
	 * TSO segment are mapped already, therefore,
	 * 1. unmap the tso segments,
	 * 2. free tso num segment if it is a last segment, and
	 * 3. free the tso segments.
	 */

	if (is_tso_seg_mapping_done) {
		struct qdf_tso_num_seg_elem_t *tso_num_desc =
				msdu_info->tso_info.tso_num_seg_list;

		if (qdf_unlikely(!tso_num_desc)) {
			ol_txrx_err("TSO common info is NULL!");
			return;
		}

		while (free_seg) {
			qdf_spin_lock_bh(&pdev->tso_seg_pool.tso_mutex);
			tso_num_desc->num_seg.tso_cmn_num_seg--;

			is_last_seg = (tso_num_desc->num_seg.tso_cmn_num_seg ==
				       0) ? true : false;
			qdf_nbuf_unmap_tso_segment(pdev->osdev, free_seg,
						   is_last_seg);
			qdf_spin_unlock_bh(&pdev->tso_seg_pool.tso_mutex);

			if (is_last_seg) {
				ol_tso_num_seg_free(pdev,
						    msdu_info->tso_info.
						    tso_num_seg_list);
				msdu_info->tso_info.tso_num_seg_list = NULL;
			}

			next_seg = free_seg->next;
			free_seg->force_free = 1;
			ol_tso_free_segment(pdev, free_seg);
			free_seg = next_seg;
		}
	} else {
		/*
		 * TSO segment are not mapped therefore,
		 * free the tso segments only.
		 */
		while (free_seg) {
			next_seg = free_seg->next;
			free_seg->force_free = 1;
			ol_tso_free_segment(pdev, free_seg);
			free_seg = next_seg;
		}
	}
}

/**
 * ol_tx_prepare_tso() - Given a jumbo msdu, prepare the TSO
 * related information in the msdu_info meta data
 * @vdev: virtual device handle
 * @msdu: network buffer
 * @msdu_info: meta data associated with the msdu
 *
 * Return: 0 - success, >0 - error
 */
uint8_t ol_tx_prepare_tso(ol_txrx_vdev_handle vdev,
			  qdf_nbuf_t msdu,
			  struct ol_txrx_msdu_info_t *msdu_info)
{
	msdu_info->tso_info.curr_seg = NULL;
	if (qdf_nbuf_is_tso(msdu)) {
		int num_seg = qdf_nbuf_get_tso_num_seg(msdu);
		struct qdf_tso_num_seg_elem_t *tso_num_seg;

		msdu_info->tso_info.tso_num_seg_list = NULL;
		msdu_info->tso_info.tso_seg_list = NULL;
		msdu_info->tso_info.num_segs = num_seg;
		while (num_seg) {
			struct qdf_tso_seg_elem_t *tso_seg =
				ol_tso_alloc_segment(vdev->pdev);
			if (tso_seg) {
				qdf_tso_seg_dbg_record(tso_seg,
						       TSOSEG_LOC_PREPARETSO);
				tso_seg->next =
					msdu_info->tso_info.tso_seg_list;
				msdu_info->tso_info.tso_seg_list
					= tso_seg;
				num_seg--;
			} else {
				/* Free above alocated TSO segements till now */
				msdu_info->tso_info.curr_seg =
					msdu_info->tso_info.tso_seg_list;
				ol_free_remaining_tso_segs(vdev, msdu_info,
							   false);
				return 1;
			}
		}
		tso_num_seg = ol_tso_num_seg_alloc(vdev->pdev);
		if (tso_num_seg) {
			tso_num_seg->next = msdu_info->tso_info.
						tso_num_seg_list;
			msdu_info->tso_info.tso_num_seg_list = tso_num_seg;
		} else {
			/* Free the already allocated num of segments */
			msdu_info->tso_info.curr_seg =
				msdu_info->tso_info.tso_seg_list;
			ol_free_remaining_tso_segs(vdev, msdu_info, false);
			return 1;
		}

		if (qdf_unlikely(!qdf_nbuf_get_tso_info(vdev->pdev->osdev,
						msdu, &msdu_info->tso_info))) {
			/* Free the already allocated num of segments */
			msdu_info->tso_info.curr_seg =
				msdu_info->tso_info.tso_seg_list;
			ol_free_remaining_tso_segs(vdev, msdu_info, false);
			return 1;
		}

		msdu_info->tso_info.curr_seg =
			msdu_info->tso_info.tso_seg_list;
		num_seg = msdu_info->tso_info.num_segs;
	} else {
		msdu_info->tso_info.is_tso = 0;
		msdu_info->tso_info.num_segs = 1;
	}
	return 0;
}

/**
 * ol_tx_tso_update_stats() - update TSO stats
 * @pdev: pointer to ol_txrx_pdev_t structure
 * @msdu_info: tso msdu_info for the msdu
 * @msdu: tso mdsu for which stats are updated
 * @tso_msdu_idx: stats index in the global TSO stats array where stats will be
 *                updated
 *
 * Return: None
 */
void ol_tx_tso_update_stats(struct ol_txrx_pdev_t *pdev,
			    struct qdf_tso_info_t  *tso_info, qdf_nbuf_t msdu,
			    uint32_t tso_msdu_idx)
{
	TXRX_STATS_TSO_HISTOGRAM(pdev, tso_info->num_segs);
	TXRX_STATS_TSO_GSO_SIZE_UPDATE(pdev, tso_msdu_idx,
				       qdf_nbuf_tcp_tso_size(msdu));
	TXRX_STATS_TSO_TOTAL_LEN_UPDATE(pdev,
					tso_msdu_idx, qdf_nbuf_len(msdu));
	TXRX_STATS_TSO_NUM_FRAGS_UPDATE(pdev, tso_msdu_idx,
					qdf_nbuf_get_nr_frags(msdu));
}

/**
 * ol_tx_tso_get_stats_idx() - retrieve global TSO stats index and increment it
 * @pdev: pointer to ol_txrx_pdev_t structure
 *
 * Retrieve  the current value of the global variable and increment it. This is
 * done in a spinlock as the global TSO stats may be accessed in parallel by
 * multiple TX streams.
 *
 * Return: The current value of TSO stats index.
 */
uint32_t ol_tx_tso_get_stats_idx(struct ol_txrx_pdev_t *pdev)
{
	uint32_t msdu_stats_idx = 0;

	qdf_spin_lock_bh(&pdev->stats.pub.tx.tso.tso_stats_lock);
	msdu_stats_idx = pdev->stats.pub.tx.tso.tso_info.tso_msdu_idx;
	pdev->stats.pub.tx.tso.tso_info.tso_msdu_idx++;
	pdev->stats.pub.tx.tso.tso_info.tso_msdu_idx &=
					NUM_MAX_TSO_MSDUS_MASK;
	qdf_spin_unlock_bh(&pdev->stats.pub.tx.tso.tso_stats_lock);

	TXRX_STATS_TSO_RESET_MSDU(pdev, msdu_stats_idx);

	return msdu_stats_idx;
}

/**
 * ol_tso_seg_list_init() - function to initialise the tso seg freelist
 * @pdev: the data physical device sending the data
 * @num_seg: number of segments needs to be intialised
 *
 * Return: none
 */
void ol_tso_seg_list_init(struct ol_txrx_pdev_t *pdev, uint32_t num_seg)
{
	int i = 0;
	struct qdf_tso_seg_elem_t *c_element;

	/* Host should not allocate any c_element. */
	if (num_seg <= 0) {
		ol_txrx_err("Pool size passed is 0");
		QDF_BUG(0);
		pdev->tso_seg_pool.pool_size = i;
		qdf_spinlock_create(&pdev->tso_seg_pool.tso_mutex);
		return;
	}

	c_element = qdf_mem_malloc(sizeof(struct qdf_tso_seg_elem_t));
	pdev->tso_seg_pool.freelist = c_element;
	for (i = 0; i < (num_seg - 1); i++) {
		if (qdf_unlikely(!c_element)) {
			ol_txrx_err("c_element NULL for seg %d", i);
			QDF_BUG(0);
			pdev->tso_seg_pool.pool_size = i;
			pdev->tso_seg_pool.num_free = i;
			qdf_spinlock_create(&pdev->tso_seg_pool.tso_mutex);
			return;
		}
		/* set the freelist bit and magic cookie*/
		c_element->on_freelist = 1;
		c_element->cookie = TSO_SEG_MAGIC_COOKIE;
#ifdef TSOSEG_DEBUG
		c_element->dbg.txdesc = NULL;
		qdf_atomic_init(&c_element->dbg.cur); /* history empty */
		qdf_tso_seg_dbg_record(c_element, TSOSEG_LOC_INIT1);
#endif /* TSOSEG_DEBUG */
		c_element->next =
			qdf_mem_malloc(sizeof(struct qdf_tso_seg_elem_t));
		c_element = c_element->next;
	}
	/*
	 * NULL check for the last c_element of the list or
	 * first c_element if num_seg is equal to 1.
	 */
	if (qdf_unlikely(!c_element)) {
		ol_txrx_err("c_element NULL for seg %d", i);
		QDF_BUG(0);
		pdev->tso_seg_pool.pool_size = i;
		pdev->tso_seg_pool.num_free = i;
		qdf_spinlock_create(&pdev->tso_seg_pool.tso_mutex);
		return;
	}
	c_element->on_freelist = 1;
	c_element->cookie = TSO_SEG_MAGIC_COOKIE;
#ifdef TSOSEG_DEBUG
	qdf_tso_seg_dbg_init(c_element);
	qdf_tso_seg_dbg_record(c_element, TSOSEG_LOC_INIT2);
#endif /* TSOSEG_DEBUG */
	c_element->next = NULL;
	pdev->tso_seg_pool.pool_size = num_seg;
	pdev->tso_seg_pool.num_free = num_seg;
	qdf_spinlock_create(&pdev->tso_seg_pool.tso_mutex);
}

/**
 * ol_tso_seg_list_deinit() - function to de-initialise the tso seg freelist
 * @pdev: the data physical device sending the data
 *
 * Return: none
 */
void ol_tso_seg_list_deinit(struct ol_txrx_pdev_t *pdev)
{
	int i;
	struct qdf_tso_seg_elem_t *c_element;
	struct qdf_tso_seg_elem_t *temp;

	/* pool size 0 implies that tso seg list is not initialised*/
	if (!pdev->tso_seg_pool.freelist &&
	    pdev->tso_seg_pool.pool_size == 0)
		return;

	qdf_spin_lock_bh(&pdev->tso_seg_pool.tso_mutex);
	c_element = pdev->tso_seg_pool.freelist;
	i = pdev->tso_seg_pool.pool_size;

	pdev->tso_seg_pool.freelist = NULL;
	pdev->tso_seg_pool.num_free = 0;
	pdev->tso_seg_pool.pool_size = 0;

	qdf_spin_unlock_bh(&pdev->tso_seg_pool.tso_mutex);
	qdf_spinlock_destroy(&pdev->tso_seg_pool.tso_mutex);

	while (i-- > 0 && c_element) {
		temp = c_element->next;
		if (c_element->on_freelist != 1) {
			qdf_tso_seg_dbg_bug("seg already freed (double?)");
			return;
		} else if (c_element->cookie != TSO_SEG_MAGIC_COOKIE) {
			qdf_tso_seg_dbg_bug("seg cookie is bad (corruption?)");
			return;
		}
		/* free this seg, so reset the cookie value*/
		c_element->cookie = 0;
		qdf_mem_free(c_element);
		c_element = temp;
	}
}

/**
 * ol_tso_num_seg_list_init() - function to initialise the freelist of elements
 *				use to count the num of tso segments in jumbo
 *				skb packet freelist
 * @pdev: the data physical device sending the data
 * @num_seg: number of elements needs to be intialised
 *
 * Return: none
 */
void ol_tso_num_seg_list_init(struct ol_txrx_pdev_t *pdev, uint32_t num_seg)
{
	int i = 0;
	struct qdf_tso_num_seg_elem_t *c_element;

	/* Host should not allocate any c_element. */
	if (num_seg <= 0) {
		ol_txrx_err("Pool size passed is 0");
		QDF_BUG(0);
		pdev->tso_num_seg_pool.num_seg_pool_size = i;
		qdf_spinlock_create(&pdev->tso_num_seg_pool.tso_num_seg_mutex);
		return;
	}

	c_element = qdf_mem_malloc(sizeof(struct qdf_tso_num_seg_elem_t));
	pdev->tso_num_seg_pool.freelist = c_element;
	for (i = 0; i < (num_seg - 1); i++) {
		if (qdf_unlikely(!c_element)) {
			ol_txrx_err("c_element NULL for num of seg %d", i);
			QDF_BUG(0);
			pdev->tso_num_seg_pool.num_seg_pool_size = i;
			pdev->tso_num_seg_pool.num_free = i;
			qdf_spinlock_create(&pdev->tso_num_seg_pool.
							tso_num_seg_mutex);
			return;
		}
		c_element->next =
			qdf_mem_malloc(sizeof(struct qdf_tso_num_seg_elem_t));
		c_element = c_element->next;
	}
	/*
	 * NULL check for the last c_element of the list or
	 * first c_element if num_seg is equal to 1.
	 */
	if (qdf_unlikely(!c_element)) {
		ol_txrx_err("c_element NULL for num of seg %d", i);
		QDF_BUG(0);
		pdev->tso_num_seg_pool.num_seg_pool_size = i;
		pdev->tso_num_seg_pool.num_free = i;
		qdf_spinlock_create(&pdev->tso_num_seg_pool.tso_num_seg_mutex);
		return;
	}
	c_element->next = NULL;
	pdev->tso_num_seg_pool.num_seg_pool_size = num_seg;
	pdev->tso_num_seg_pool.num_free = num_seg;
	qdf_spinlock_create(&pdev->tso_num_seg_pool.tso_num_seg_mutex);
}

/**
 * ol_tso_num_seg_list_deinit() - function to de-initialise the freelist of
 *				  elements use to count the num of tso segment
 *				  in a jumbo skb packet freelist
 * @pdev: the data physical device sending the data
 *
 * Return: none
 */
void ol_tso_num_seg_list_deinit(struct ol_txrx_pdev_t *pdev)
{
	int i;
	struct qdf_tso_num_seg_elem_t *c_element;
	struct qdf_tso_num_seg_elem_t *temp;

	/* pool size 0 implies that tso num seg list is not initialised*/
	if (!pdev->tso_num_seg_pool.freelist &&
	    pdev->tso_num_seg_pool.num_seg_pool_size == 0)
		return;

	qdf_spin_lock_bh(&pdev->tso_num_seg_pool.tso_num_seg_mutex);
	c_element = pdev->tso_num_seg_pool.freelist;
	i = pdev->tso_num_seg_pool.num_seg_pool_size;

	pdev->tso_num_seg_pool.freelist = NULL;
	pdev->tso_num_seg_pool.num_free = 0;
	pdev->tso_num_seg_pool.num_seg_pool_size = 0;

	qdf_spin_unlock_bh(&pdev->tso_num_seg_pool.tso_num_seg_mutex);
	qdf_spinlock_destroy(&pdev->tso_num_seg_pool.tso_num_seg_mutex);

	while (i-- > 0 && c_element) {
		temp = c_element->next;
		qdf_mem_free(c_element);
		c_element = temp;
	}
}
#endif /* FEATURE_TSO */

#if defined(FEATURE_TSO) && defined(FEATURE_TSO_DEBUG)
void ol_txrx_tso_stats_init(ol_txrx_pdev_handle pdev)
{
	qdf_spinlock_create(&pdev->stats.pub.tx.tso.tso_stats_lock);
}

void ol_txrx_tso_stats_deinit(ol_txrx_pdev_handle pdev)
{
	qdf_spinlock_destroy(&pdev->stats.pub.tx.tso.tso_stats_lock);
}

void ol_txrx_stats_display_tso(ol_txrx_pdev_handle pdev)
{
	int msdu_idx;
	int seg_idx;

	txrx_nofl_info("TSO Statistics:");
	txrx_nofl_info("TSO pkts %lld, bytes %lld\n",
		       pdev->stats.pub.tx.tso.tso_pkts.pkts,
		       pdev->stats.pub.tx.tso.tso_pkts.bytes);

	txrx_nofl_info("TSO Histogram for numbers of segments:\n"
		       "Single segment	%d\n"
		       "  2-5 segments	%d\n"
		       " 6-10 segments	%d\n"
		       "11-15 segments	%d\n"
		       "16-20 segments	%d\n"
		       "  20+ segments	%d\n",
		       pdev->stats.pub.tx.tso.tso_hist.pkts_1,
		       pdev->stats.pub.tx.tso.tso_hist.pkts_2_5,
		       pdev->stats.pub.tx.tso.tso_hist.pkts_6_10,
		       pdev->stats.pub.tx.tso.tso_hist.pkts_11_15,
		       pdev->stats.pub.tx.tso.tso_hist.pkts_16_20,
		       pdev->stats.pub.tx.tso.tso_hist.pkts_20_plus);

	txrx_nofl_info("TSO History Buffer: Total size %d, current_index %d",
		       NUM_MAX_TSO_MSDUS,
		       TXRX_STATS_TSO_MSDU_IDX(pdev));

	for (msdu_idx = 0; msdu_idx < NUM_MAX_TSO_MSDUS; msdu_idx++) {
		if (TXRX_STATS_TSO_MSDU_TOTAL_LEN(pdev, msdu_idx) == 0)
			continue;
		txrx_nofl_info("jumbo pkt idx: %d num segs %d gso_len %d total_len %d nr_frags %d",
			       msdu_idx,
			       TXRX_STATS_TSO_MSDU_NUM_SEG(pdev, msdu_idx),
			       TXRX_STATS_TSO_MSDU_GSO_SIZE(pdev, msdu_idx),
			       TXRX_STATS_TSO_MSDU_TOTAL_LEN(pdev, msdu_idx),
			       TXRX_STATS_TSO_MSDU_NR_FRAGS(pdev, msdu_idx));

		for (seg_idx = 0;
			 ((seg_idx < TXRX_STATS_TSO_MSDU_NUM_SEG(pdev,
			   msdu_idx)) && (seg_idx < NUM_MAX_TSO_SEGS));
			 seg_idx++) {
			struct qdf_tso_seg_t tso_seg =
				 TXRX_STATS_TSO_SEG(pdev, msdu_idx, seg_idx);

			txrx_nofl_info("seg idx: %d", seg_idx);
			txrx_nofl_info("tso_enable: %d",
				       tso_seg.tso_flags.tso_enable);
			txrx_nofl_info("fin %d syn %d rst %d psh %d ack %d urg %d ece %d cwr %d ns %d",
				       tso_seg.tso_flags.fin,
				       tso_seg.tso_flags.syn,
				       tso_seg.tso_flags.rst,
				       tso_seg.tso_flags.psh,
				       tso_seg.tso_flags.ack,
				       tso_seg.tso_flags.urg,
				       tso_seg.tso_flags.ece,
				       tso_seg.tso_flags.cwr,
				       tso_seg.tso_flags.ns);
			txrx_nofl_info("tcp_seq_num: 0x%x ip_id: %d",
				       tso_seg.tso_flags.tcp_seq_num,
				       tso_seg.tso_flags.ip_id);
		}
	}
}

void ol_txrx_tso_stats_clear(ol_txrx_pdev_handle pdev)
{
	qdf_mem_zero(&pdev->stats.pub.tx.tso.tso_pkts,
		     sizeof(struct ol_txrx_stats_elem));
#if defined(FEATURE_TSO)
	qdf_mem_zero(&pdev->stats.pub.tx.tso.tso_info,
		     sizeof(struct ol_txrx_stats_tso_info));
	qdf_mem_zero(&pdev->stats.pub.tx.tso.tso_hist,
		     sizeof(struct ol_txrx_tso_histogram));
#endif
}
#endif /* defined(FEATURE_TSO) && defined(FEATURE_TSO_DEBUG) */
