/*
 * 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.
 */

/* OS abstraction libraries */
#include <qdf_nbuf.h>           /* qdf_nbuf_t, etc. */
#include <qdf_atomic.h>         /* qdf_atomic_read, etc. */
#include <qdf_util.h>           /* qdf_unlikely */

/* APIs for other modules */
#include <htt.h>                /* HTT_TX_EXT_TID_MGMT */
#include <ol_htt_tx_api.h>      /* htt_tx_desc_tid */

/* internal header files relevant for all systems */
#include <ol_txrx_internal.h>   /* TXRX_ASSERT1 */
#include <ol_tx_desc.h>         /* ol_tx_desc */
#include <ol_tx_send.h>         /* ol_tx_send */
#include <ol_txrx.h>            /* ol_txrx_get_vdev_from_vdev_id */

/* internal header files relevant only for HL systems */
#include <ol_tx_queue.h>        /* ol_tx_enqueue */

/* internal header files relevant only for specific systems (Pronto) */
#include <ol_txrx_encap.h>      /* OL_TX_ENCAP, etc */
#include <ol_tx.h>
#include <ol_cfg.h>
#include <cdp_txrx_handle.h>

/**
 * ol_txrx_vdev_pause- Suspend all tx data for the specified virtual device
 *
 * @data_vdev - the virtual device being paused
 * @reason - the reason for which vdev queue is getting paused
 *
 * This function applies primarily to HL systems, but also
 * applies to LL systems that use per-vdev tx queues for MCC or
 * thermal throttling. As an example, this function could be
 * used when a single-channel physical device supports multiple
 * channels by jumping back and forth between the channels in a
 * time-shared manner.  As the device is switched from channel A
 * to channel B, the virtual devices that operate on channel A
 * will be paused.
 *
 */
void ol_txrx_vdev_pause(struct cdp_vdev *pvdev, uint32_t reason)
{
	struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev;

	/* TO DO: log the queue pause */
	/* acquire the mutex lock, since we'll be modifying the queues */
	TX_SCHED_DEBUG_PRINT("Enter %s\n", __func__);

	qdf_spin_lock_bh(&vdev->ll_pause.mutex);
	vdev->ll_pause.paused_reason |= reason;
	vdev->ll_pause.q_pause_cnt++;
	vdev->ll_pause.is_q_paused = true;
	qdf_spin_unlock_bh(&vdev->ll_pause.mutex);

	TX_SCHED_DEBUG_PRINT("Leave %s\n", __func__);
}

/**
 * ol_txrx_vdev_unpause - Resume tx for the specified virtual device
 *
 * @data_vdev - the virtual device being unpaused
 * @reason - the reason for which vdev queue is getting unpaused
 *
 * This function applies primarily to HL systems, but also applies to
 * LL systems that use per-vdev tx queues for MCC or thermal throttling.
 *
 */
void ol_txrx_vdev_unpause(struct cdp_vdev *pvdev, uint32_t reason)
{
	struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev;
	/* TO DO: log the queue unpause */
	/* acquire the mutex lock, since we'll be modifying the queues */
	TX_SCHED_DEBUG_PRINT("Enter %s\n", __func__);

	qdf_spin_lock_bh(&vdev->ll_pause.mutex);
	if (vdev->ll_pause.paused_reason & reason) {
		vdev->ll_pause.paused_reason &= ~reason;
		if (!vdev->ll_pause.paused_reason) {
			vdev->ll_pause.is_q_paused = false;
			vdev->ll_pause.q_unpause_cnt++;
			qdf_spin_unlock_bh(&vdev->ll_pause.mutex);
			ol_tx_vdev_ll_pause_queue_send((void *)vdev);
		} else {
			qdf_spin_unlock_bh(&vdev->ll_pause.mutex);
		}
	} else {
		qdf_spin_unlock_bh(&vdev->ll_pause.mutex);
	}
	TX_SCHED_DEBUG_PRINT("Leave %s\n", __func__);
}

/**
 * ol_txrx_vdev_flush - Drop all tx data for the specified virtual device
 *
 * @data_vdev - the virtual device being flushed
 *
 *  This function applies primarily to HL systems, but also applies to
 *  LL systems that use per-vdev tx queues for MCC or thermal throttling.
 *  This function would typically be used by the ctrl SW after it parks
 *  a STA vdev and then resumes it, but to a new AP.  In this case, though
 *  the same vdev can be used, any old tx frames queued inside it would be
 *  stale, and would need to be discarded.
 *
 */
void ol_txrx_vdev_flush(struct cdp_vdev *pvdev)
{
	struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev;

	qdf_spin_lock_bh(&vdev->ll_pause.mutex);
	qdf_timer_stop(&vdev->ll_pause.timer);
	vdev->ll_pause.is_q_timer_on = false;
	while (vdev->ll_pause.txq.head) {
		qdf_nbuf_t next =
			qdf_nbuf_next(vdev->ll_pause.txq.head);
		qdf_nbuf_set_next(vdev->ll_pause.txq.head, NULL);
		if (QDF_NBUF_CB_PADDR(vdev->ll_pause.txq.head) &&
		    !qdf_nbuf_ipa_owned_get(vdev->ll_pause.txq.head)) {
			qdf_nbuf_unmap(vdev->pdev->osdev,
				       vdev->ll_pause.txq.head,
				       QDF_DMA_TO_DEVICE);
		}
		qdf_nbuf_tx_free(vdev->ll_pause.txq.head,
				 QDF_NBUF_PKT_ERROR);
		vdev->ll_pause.txq.head = next;
	}
	vdev->ll_pause.txq.tail = NULL;
	vdev->ll_pause.txq.depth = 0;
	qdf_spin_unlock_bh(&vdev->ll_pause.mutex);
}

#define OL_TX_VDEV_PAUSE_QUEUE_SEND_MARGIN 400
#define OL_TX_VDEV_PAUSE_QUEUE_SEND_PERIOD_MS 5

static void ol_tx_vdev_ll_pause_queue_send_base(struct ol_txrx_vdev_t *vdev)
{
	int max_to_accept;

	qdf_spin_lock_bh(&vdev->ll_pause.mutex);
	if (vdev->ll_pause.paused_reason) {
		qdf_spin_unlock_bh(&vdev->ll_pause.mutex);
		return;
	}

	/*
	 * Send as much of the backlog as possible, but leave some margin
	 * of unallocated tx descriptors that can be used for new frames
	 * being transmitted by other vdevs.
	 * Ideally there would be a scheduler, which would not only leave
	 * some margin for new frames for other vdevs, but also would
	 * fairly apportion the tx descriptors between multiple vdevs that
	 * have backlogs in their pause queues.
	 * However, the fairness benefit of having a scheduler for frames
	 * from multiple vdev's pause queues is not sufficient to outweigh
	 * the extra complexity.
	 */
	max_to_accept = vdev->pdev->tx_desc.num_free -
		OL_TX_VDEV_PAUSE_QUEUE_SEND_MARGIN;
	while (max_to_accept > 0 && vdev->ll_pause.txq.depth) {
		qdf_nbuf_t tx_msdu;

		max_to_accept--;
		vdev->ll_pause.txq.depth--;
		tx_msdu = vdev->ll_pause.txq.head;
		if (tx_msdu) {
			vdev->ll_pause.txq.head = qdf_nbuf_next(tx_msdu);
			if (!vdev->ll_pause.txq.head)
				vdev->ll_pause.txq.tail = NULL;
			qdf_nbuf_set_next(tx_msdu, NULL);
			QDF_NBUF_UPDATE_TX_PKT_COUNT(tx_msdu,
						QDF_NBUF_TX_PKT_TXRX_DEQUEUE);
			tx_msdu = ol_tx_ll_wrapper(vdev, tx_msdu);
			/*
			 * It is unexpected that ol_tx_ll would reject the frame
			 * since we checked that there's room for it, though
			 * there's an infinitesimal possibility that between the
			 * time we checked the room available and now, a
			 * concurrent batch of tx frames used up all the room.
			 * For simplicity, just drop the frame.
			 */
			if (tx_msdu) {
				qdf_nbuf_unmap(vdev->pdev->osdev, tx_msdu,
					       QDF_DMA_TO_DEVICE);
				qdf_nbuf_tx_free(tx_msdu, QDF_NBUF_PKT_ERROR);
			}
		}
	}
	if (vdev->ll_pause.txq.depth) {
		qdf_timer_stop(&vdev->ll_pause.timer);
		if (!qdf_atomic_read(&vdev->delete.detaching)) {
			qdf_timer_start(&vdev->ll_pause.timer,
					OL_TX_VDEV_PAUSE_QUEUE_SEND_PERIOD_MS);
			vdev->ll_pause.is_q_timer_on = true;
		}
		if (vdev->ll_pause.txq.depth >= vdev->ll_pause.max_q_depth)
			vdev->ll_pause.q_overflow_cnt++;
	}

	qdf_spin_unlock_bh(&vdev->ll_pause.mutex);
}

static qdf_nbuf_t
ol_tx_vdev_pause_queue_append(struct ol_txrx_vdev_t *vdev,
			      qdf_nbuf_t msdu_list, uint8_t start_timer)
{
	qdf_spin_lock_bh(&vdev->ll_pause.mutex);
	while (msdu_list &&
	       vdev->ll_pause.txq.depth < vdev->ll_pause.max_q_depth) {
		qdf_nbuf_t next = qdf_nbuf_next(msdu_list);

		QDF_NBUF_UPDATE_TX_PKT_COUNT(msdu_list,
					     QDF_NBUF_TX_PKT_TXRX_ENQUEUE);
		DPTRACE(qdf_dp_trace(msdu_list,
			QDF_DP_TRACE_TXRX_QUEUE_PACKET_PTR_RECORD,
			QDF_TRACE_DEFAULT_PDEV_ID,
			qdf_nbuf_data_addr(msdu_list),
			sizeof(qdf_nbuf_data(msdu_list)), QDF_TX));

		vdev->ll_pause.txq.depth++;
		if (!vdev->ll_pause.txq.head) {
			vdev->ll_pause.txq.head = msdu_list;
			vdev->ll_pause.txq.tail = msdu_list;
		} else {
			qdf_nbuf_set_next(vdev->ll_pause.txq.tail, msdu_list);
		}
		vdev->ll_pause.txq.tail = msdu_list;

		msdu_list = next;
	}
	if (vdev->ll_pause.txq.tail)
		qdf_nbuf_set_next(vdev->ll_pause.txq.tail, NULL);

	if (start_timer) {
		qdf_timer_stop(&vdev->ll_pause.timer);
		if (!qdf_atomic_read(&vdev->delete.detaching)) {
			qdf_timer_start(&vdev->ll_pause.timer,
					OL_TX_VDEV_PAUSE_QUEUE_SEND_PERIOD_MS);
			vdev->ll_pause.is_q_timer_on = true;
		}
	}
	qdf_spin_unlock_bh(&vdev->ll_pause.mutex);

	return msdu_list;
}

/*
 * Store up the tx frame in the vdev's tx queue if the vdev is paused.
 * If there are too many frames in the tx queue, reject it.
 */
qdf_nbuf_t ol_tx_ll_queue(ol_txrx_vdev_handle vdev, qdf_nbuf_t msdu_list)
{
	uint16_t eth_type;
	uint32_t paused_reason;

	if (!msdu_list)
		return NULL;

	paused_reason = vdev->ll_pause.paused_reason;
	if (paused_reason) {
		if (qdf_unlikely((paused_reason &
				  OL_TXQ_PAUSE_REASON_PEER_UNAUTHORIZED) ==
				 paused_reason)) {
			eth_type = (((struct ethernet_hdr_t *)
				     qdf_nbuf_data(msdu_list))->
				    ethertype[0] << 8) |
				   (((struct ethernet_hdr_t *)
				     qdf_nbuf_data(msdu_list))->ethertype[1]);
			if (ETHERTYPE_IS_EAPOL_WAPI(eth_type)) {
				msdu_list = ol_tx_ll_wrapper(vdev, msdu_list);
				return msdu_list;
			}
		}
		msdu_list = ol_tx_vdev_pause_queue_append(vdev, msdu_list, 1);
	} else {
		if (vdev->ll_pause.txq.depth > 0 ||
		    vdev->pdev->tx_throttle.current_throttle_level !=
		    THROTTLE_LEVEL_0) {
			/*
			 * not paused, but there is a backlog of frms
			 * from a prior pause or throttle off phase
			 */
			msdu_list = ol_tx_vdev_pause_queue_append(
				vdev, msdu_list, 0);
			/*
			 * if throttle is disabled or phase is "on",
			 * send the frame
			 */
			if (vdev->pdev->tx_throttle.current_throttle_level ==
			    THROTTLE_LEVEL_0 ||
			    vdev->pdev->tx_throttle.current_throttle_phase ==
			    THROTTLE_PHASE_ON) {
				/*
				 * send as many frames as possible
				 * from the vdevs backlog
				 */
				ol_tx_vdev_ll_pause_queue_send_base(vdev);
			}
		} else {
			/*
			 * not paused, no throttle and no backlog -
			 * send the new frames
			 */
			msdu_list = ol_tx_ll_wrapper(vdev, msdu_list);
		}
	}
	return msdu_list;
}

/*
 * Run through the transmit queues for all the vdevs and
 * send the pending frames
 */
void ol_tx_pdev_ll_pause_queue_send_all(struct ol_txrx_pdev_t *pdev)
{
	int max_to_send;        /* tracks how many frames have been sent */
	qdf_nbuf_t tx_msdu;
	struct ol_txrx_vdev_t *vdev = NULL;
	uint8_t more;

	if (!pdev)
		return;

	if (pdev->tx_throttle.current_throttle_phase == THROTTLE_PHASE_OFF)
		return;

	/* ensure that we send no more than tx_threshold frames at once */
	max_to_send = pdev->tx_throttle.tx_threshold;

	/* round robin through the vdev queues for the given pdev */

	/*
	 * Potential improvement: download several frames from the same vdev
	 * at a time, since it is more likely that those frames could be
	 * aggregated together, remember which vdev was serviced last,
	 * so the next call this function can resume the round-robin
	 * traversing where the current invocation left off
	 */
	do {
		more = 0;
		TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) {
			qdf_spin_lock_bh(&vdev->ll_pause.mutex);
			if (vdev->ll_pause.txq.depth) {
				if (vdev->ll_pause.paused_reason) {
					qdf_spin_unlock_bh(&vdev->ll_pause.
							   mutex);
					continue;
				}

				tx_msdu = vdev->ll_pause.txq.head;
				if (!tx_msdu) {
					qdf_spin_unlock_bh(&vdev->ll_pause.
							   mutex);
					continue;
				}

				max_to_send--;
				vdev->ll_pause.txq.depth--;

				vdev->ll_pause.txq.head =
					qdf_nbuf_next(tx_msdu);

				if (!vdev->ll_pause.txq.head)
					vdev->ll_pause.txq.tail = NULL;

				qdf_nbuf_set_next(tx_msdu, NULL);
				tx_msdu = ol_tx_ll_wrapper(vdev, tx_msdu);
				/*
				 * It is unexpected that ol_tx_ll would reject
				 * the frame, since we checked that there's
				 * room for it, though there's an infinitesimal
				 * possibility that between the time we checked
				 * the room available and now, a concurrent
				 * batch of tx frames used up all the room.
				 * For simplicity, just drop the frame.
				 */
				if (tx_msdu) {
					qdf_nbuf_unmap(pdev->osdev, tx_msdu,
						       QDF_DMA_TO_DEVICE);
					qdf_nbuf_tx_free(tx_msdu,
							 QDF_NBUF_PKT_ERROR);
				}
			}
			/*check if there are more msdus to transmit */
			if (vdev->ll_pause.txq.depth)
				more = 1;
			qdf_spin_unlock_bh(&vdev->ll_pause.mutex);
		}
	} while (more && max_to_send);

	vdev = NULL;
	TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) {
		qdf_spin_lock_bh(&vdev->ll_pause.mutex);
		if (vdev->ll_pause.txq.depth) {
			qdf_timer_stop(&pdev->tx_throttle.tx_timer);
			qdf_timer_start(
				&pdev->tx_throttle.tx_timer,
				OL_TX_VDEV_PAUSE_QUEUE_SEND_PERIOD_MS);
			qdf_spin_unlock_bh(&vdev->ll_pause.mutex);
			return;
		}
		qdf_spin_unlock_bh(&vdev->ll_pause.mutex);
	}
}

void ol_tx_vdev_ll_pause_queue_send(void *context)
{
	struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)context;
	struct ol_txrx_pdev_t *pdev = vdev->pdev;

	if (pdev &&
	    pdev->tx_throttle.current_throttle_level != THROTTLE_LEVEL_0 &&
	    pdev->tx_throttle.current_throttle_phase == THROTTLE_PHASE_OFF)
		return;
	ol_tx_vdev_ll_pause_queue_send_base(vdev);
}

/**
 * ol_txrx_get_vdev_from_sta_id() - get vdev from sta_id
 * @sta_id: sta_id
 *
 * Return: vdev handle
 *            NULL if not found.
 */
static ol_txrx_vdev_handle ol_txrx_get_vdev_from_sta_id(uint8_t sta_id)
{
	struct ol_txrx_peer_t *peer = NULL;
	ol_txrx_pdev_handle pdev = NULL;

	if (sta_id >= WLAN_MAX_STA_COUNT) {
		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
			  "Invalid sta id passed");
		return NULL;
	}

	pdev = cds_get_context(QDF_MODULE_ID_TXRX);
	if (!pdev) {
		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
			  "PDEV not found for sta_id [%d]", sta_id);
		return NULL;
	}

	peer = ol_txrx_peer_find_by_local_id((struct cdp_pdev *)pdev, sta_id);

	if (!peer) {
		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_HIGH,
			  "PEER [%d] not found", sta_id);
		return NULL;
	}

	return peer->vdev;
}

/**
 * ol_txrx_register_tx_flow_control() - register tx flow control callback
 * @vdev_id: vdev_id
 * @flowControl: flow control callback
 * @osif_fc_ctx: callback context
 * @flow_control_is_pause: is vdev paused by flow control
 *
 * Return: 0 for success or error code
 */
int ol_txrx_register_tx_flow_control(uint8_t vdev_id,
				     ol_txrx_tx_flow_control_fp flowControl,
				     void *osif_fc_ctx,
				     ol_txrx_tx_flow_control_is_pause_fp
				     flow_control_is_pause)
{
	struct ol_txrx_vdev_t *vdev =
		(struct ol_txrx_vdev_t *)ol_txrx_get_vdev_from_vdev_id(vdev_id);

	if (!vdev) {
		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
			  "%s: Invalid vdev_id %d", __func__, vdev_id);
		return -EINVAL;
	}

	qdf_spin_lock_bh(&vdev->flow_control_lock);
	vdev->osif_flow_control_cb = flowControl;
	vdev->osif_flow_control_is_pause = flow_control_is_pause;
	vdev->osif_fc_ctx = osif_fc_ctx;
	qdf_spin_unlock_bh(&vdev->flow_control_lock);
	return 0;
}

/**
 * ol_txrx_de_register_tx_flow_control_cb() - deregister tx flow control
 *                                            callback
 * @vdev_id: vdev_id
 *
 * Return: 0 for success or error code
 */
int ol_txrx_deregister_tx_flow_control_cb(uint8_t vdev_id)
{
	struct ol_txrx_vdev_t *vdev =
		(struct ol_txrx_vdev_t *)ol_txrx_get_vdev_from_vdev_id(vdev_id);

	if (!vdev) {
		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
			  "%s: Invalid vdev_id", __func__);
		return -EINVAL;
	}

	qdf_spin_lock_bh(&vdev->flow_control_lock);
	vdev->osif_flow_control_cb = NULL;
	vdev->osif_flow_control_is_pause = NULL;
	vdev->osif_fc_ctx = NULL;
	qdf_spin_unlock_bh(&vdev->flow_control_lock);
	return 0;
}

/**
 * ol_txrx_get_tx_resource() - if tx resource less than low_watermark
 * @sta_id: sta id
 * @low_watermark: low watermark
 * @high_watermark_offset: high watermark offset value
 *
 * Return: true/false
 */
bool
ol_txrx_get_tx_resource(uint8_t sta_id,
			unsigned int low_watermark,
			unsigned int high_watermark_offset)
{
	ol_txrx_vdev_handle vdev = ol_txrx_get_vdev_from_sta_id(sta_id);

	if (!vdev) {
		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_HIGH,
			  "%s: Invalid sta_id %d", __func__, sta_id);
		/* Return true so caller do not understand that resource
		 * is less than low_watermark.
		 * sta_id validation will be done in ol_tx_send_data_frame
		 * and if sta_id is not registered then host will drop
		 * packet.
		 */
		return true;
	}

	qdf_spin_lock_bh(&vdev->pdev->tx_mutex);

	if (vdev->pdev->tx_desc.num_free < (uint16_t)low_watermark) {
		vdev->tx_fl_lwm = (uint16_t)low_watermark;
		vdev->tx_fl_hwm =
			(uint16_t)(low_watermark + high_watermark_offset);
		/* Not enough free resource, stop TX OS Q */
		qdf_atomic_set(&vdev->os_q_paused, 1);
		qdf_spin_unlock_bh(&vdev->pdev->tx_mutex);
		return false;
	}
	qdf_spin_unlock_bh(&vdev->pdev->tx_mutex);
	return true;
}

/**
 * ol_txrx_ll_set_tx_pause_q_depth() - set pause queue depth
 * @vdev_id: vdev id
 * @pause_q_depth: pause queue depth
 *
 * Return: 0 for success or error code
 */
int ol_txrx_ll_set_tx_pause_q_depth(uint8_t vdev_id, int pause_q_depth)
{
	struct ol_txrx_vdev_t *vdev =
		(struct ol_txrx_vdev_t *)ol_txrx_get_vdev_from_vdev_id(vdev_id);

	if (!vdev) {
		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
			  "%s: Invalid vdev_id %d", __func__, vdev_id);
		return -EINVAL;
	}

	qdf_spin_lock_bh(&vdev->ll_pause.mutex);
	vdev->ll_pause.max_q_depth = pause_q_depth;
	qdf_spin_unlock_bh(&vdev->ll_pause.mutex);

	return 0;
}

void ol_txrx_flow_control_cb(struct cdp_vdev *pvdev, bool tx_resume)
{
	struct ol_txrx_vdev_t *vdev = (struct ol_txrx_vdev_t *)pvdev;

	qdf_spin_lock_bh(&vdev->flow_control_lock);
	if ((vdev->osif_flow_control_cb) && (vdev->osif_fc_ctx))
		vdev->osif_flow_control_cb(vdev->osif_fc_ctx, tx_resume);
	qdf_spin_unlock_bh(&vdev->flow_control_lock);
}

/**
 * ol_txrx_flow_control_is_pause() - is osif paused by flow control
 * @vdev: vdev handle
 *
 * Return: true if osif is paused by flow control
 */
static bool ol_txrx_flow_control_is_pause(ol_txrx_vdev_handle vdev)
{
	bool is_pause = false;

	if ((vdev->osif_flow_control_is_pause) && (vdev->osif_fc_ctx))
		is_pause = vdev->osif_flow_control_is_pause(vdev->osif_fc_ctx);

	return is_pause;
}

/**
 * ol_tx_flow_ct_unpause_os_q() - Unpause OS Q
 * @pdev: physical device object
 *
 *
 * Return: None
 */
void ol_tx_flow_ct_unpause_os_q(ol_txrx_pdev_handle pdev)
{
	struct ol_txrx_vdev_t *vdev;

	TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) {
		if ((qdf_atomic_read(&vdev->os_q_paused) &&
		     (vdev->tx_fl_hwm != 0)) ||
		     ol_txrx_flow_control_is_pause(vdev)) {
			qdf_spin_lock(&pdev->tx_mutex);
			if (pdev->tx_desc.num_free > vdev->tx_fl_hwm) {
				qdf_atomic_set(&vdev->os_q_paused, 0);
				qdf_spin_unlock(&pdev->tx_mutex);
				ol_txrx_flow_control_cb((struct cdp_vdev *)vdev,
							true);
			} else {
				qdf_spin_unlock(&pdev->tx_mutex);
			}
		}
	}
}

