/*
 * Copyright (c) 2012-2017 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.
 */

#include <adf_nbuf.h>         /* adf_nbuf_t, etc. */
#include <adf_os_atomic.h>    /* adf_os_atomic_add, etc. */
#include <ol_cfg.h>           /* ol_cfg_addba_retry */
#include <htt.h>              /* HTT_TX_EXT_TID_MGMT */
#include <ol_htt_tx_api.h>    /* htt_tx_desc_tid */
#include <ol_txrx_api.h>      /* ol_txrx_vdev_handle */
#include <ol_txrx_ctrl_api.h> /* ol_txrx_sync, ol_tx_addba_conf */
#include <ol_ctrl_txrx_api.h> /* ol_ctrl_addba_req */
#include <ol_txrx_internal.h> /* TXRX_ASSERT1, etc. */
#include <ol_txrx_types.h>    /* pdev stats */
#include <ol_tx_desc.h>       /* ol_tx_desc, ol_tx_desc_frame_list_free */
#include <ol_tx.h>            /* ol_tx_vdev_ll_pause_queue_send */
#include <ol_tx_sched.h>      /* ol_tx_sched_notify, etc. */
#include <ol_tx_queue.h>
#include <ol_txrx_dbg.h>      /* DEBUG_HL_LOGGING */
#include <ol_txrx.h>          /* ol_tx_desc_pool_size_hl */
#include <adf_os_types.h>     /* a_bool_t */
#include <ol_txrx_peer_find.h>
#include "adf_trace.h"


#if defined(CONFIG_HL_SUPPORT)

#ifndef offsetof
#define offsetof(type, field)   ((adf_os_size_t)(&((type *)0)->field))
#endif

/*--- function prototypes for optional queue log feature --------------------*/
#if defined(DEBUG_HL_LOGGING)

void
ol_tx_queue_log_enqueue(
    struct ol_txrx_pdev_t *pdev,
    struct ol_txrx_msdu_info_t *msdu_info,
    int frms, int bytes);
void
ol_tx_queue_log_dequeue(
    struct ol_txrx_pdev_t *pdev,
    struct ol_tx_frms_queue_t *txq,
    int frms, int bytes);
void
ol_tx_queue_log_free(
    struct ol_txrx_pdev_t *pdev,
    struct ol_tx_frms_queue_t *txq,
    int tid, int frms, int bytes, bool is_peer_txq);
#define OL_TX_QUEUE_LOG_ENQUEUE ol_tx_queue_log_enqueue
#define OL_TX_QUEUE_LOG_DEQUEUE ol_tx_queue_log_dequeue
#define OL_TX_QUEUE_LOG_FREE    ol_tx_queue_log_free

#else

#define OL_TX_QUEUE_LOG_ENQUEUE(pdev, msdu_info, frms, bytes) /* no-op */
#define OL_TX_QUEUE_LOG_DEQUEUE(pdev, txq, frms, bytes) /* no-op */
/* no-op */
#define OL_TX_QUEUE_LOG_FREE(pdev, txq, tid, frms, bytes, is_peer_txq)

#endif /* TXRX_DEBUG_LEVEL > 5 */


/*--- function prototypes for optional host ADDBA negotiation ---------------*/

#define OL_TX_QUEUE_ADDBA_CHECK(pdev, txq, tx_msdu_info) /* no-op */


#ifndef container_of
#define container_of(ptr, type, member) ((type *)( \
                (char *)(ptr) - (char *)(&((type *)0)->member) ) )
#endif
/*--- function definitions --------------------------------------------------*/

/*
 * Try to flush pending frames in the tx queues
 * no matter it's queued in the TX scheduler or not.
 */
static inline void
ol_tx_queue_vdev_flush(struct ol_txrx_pdev_t *pdev, struct ol_txrx_vdev_t *vdev)
{
#define PEER_ARRAY_COUNT        10
    struct ol_tx_frms_queue_t *txq;
    struct ol_txrx_peer_t *peer, *peers[PEER_ARRAY_COUNT];
    int i, j, peer_count;

    /* flush bundling queue */
    ol_tx_hl_queue_flush_all(vdev);

    /* flush del_ack queue */
    ol_tx_hl_del_ack_queue_flush_all(vdev);

    /* flush VDEV TX queues */
    for (i = 0; i < OL_TX_VDEV_NUM_QUEUES; i++) {
        txq = &vdev->txqs[i];
       /*
        * currently txqs of MCAST_BCAST/DEFAULT_MGMT packet are using tid
        * HTT_TX_EXT_TID_NON_QOS_MCAST_BCAST/HTT_TX_EXT_TID_MGMT when inserted
        * into scheduler, so use same tid when we flush them
        */
        if (i == OL_TX_VDEV_MCAST_BCAST)
            ol_tx_queue_free(pdev, txq, HTT_TX_EXT_TID_NON_QOS_MCAST_BCAST,
                             false);
        else if (i == OL_TX_VDEV_DEFAULT_MGMT)
            ol_tx_queue_free(pdev, txq, HTT_TX_EXT_TID_MGMT, false);
        else
            ol_tx_queue_free(pdev, txq, (i + OL_TX_NUM_TIDS), false);
    }
    /* flush PEER TX queues */
    do {
        peer_count = 0;
        /* select candidate peers */
        adf_os_spin_lock_bh(&pdev->peer_ref_mutex);
        TAILQ_FOREACH(peer, &vdev->peer_list, peer_list_elem) {
            for (i = 0; i < OL_TX_NUM_TIDS; i++) {
                txq = &peer->txqs[i];
                if (txq->frms) {
                    adf_os_atomic_inc(&peer->ref_cnt);
                    peers[peer_count++] = peer;
                    break;
                }
            }
            if (peer_count >= PEER_ARRAY_COUNT) {
                break;
            }
        }
        adf_os_spin_unlock_bh(&pdev->peer_ref_mutex);
        /* flush TX queues of candidate peers */
        for (i = 0; i < peer_count; i++) {
            for (j = 0; j < OL_TX_NUM_TIDS; j++) {
                txq = &peers[i]->txqs[j];
                if (txq->frms) {
                    ol_tx_queue_free(pdev, txq, j, true);
                }
            }
            TXRX_PRINT(TXRX_PRINT_LEVEL_ERR,
                      "%s: Delete Peer %pK\n", __func__, peer);
            ol_txrx_peer_unref_delete(peers[i]);
        }
    } while (peer_count >= PEER_ARRAY_COUNT);
}

static inline void
ol_tx_queue_flush(struct ol_txrx_pdev_t *pdev)
{
    struct ol_txrx_vdev_t *vdev;

    TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) {
        ol_tx_queue_vdev_flush(pdev, vdev);
    }
}

void
ol_tx_queue_discard(
    struct ol_txrx_pdev_t *pdev,
    a_bool_t flush_all,
    ol_tx_desc_list *tx_descs)
{
    u_int16_t num;
    u_int16_t discarded, actual_discarded = 0;

    adf_os_spin_lock_bh(&pdev->tx_queue_spinlock);

    if (flush_all == A_TRUE) {
        /* flush all the pending tx queues in the scheduler */
        num = ol_tx_desc_pool_size_hl(pdev->ctrl_pdev) -
            adf_os_atomic_read(&pdev->tx_queue.rsrc_cnt);
    } else {
        num = pdev->tx_queue.rsrc_threshold_hi -
            pdev->tx_queue.rsrc_threshold_lo;
    }
    TX_SCHED_DEBUG_PRINT("+%s : %u\n,", __FUNCTION__,
                            adf_os_atomic_read(&pdev->tx_queue.rsrc_cnt));
    while (num > 0) {
        discarded = ol_tx_sched_discard_select(
            pdev, (u_int16_t)num, tx_descs, flush_all);
        if (discarded == 0) {
             /*
              * No more packets could be discarded.
              * Probably tx queues are empty.
              */
             break;
        }
        num -= discarded;
        actual_discarded += discarded;
    }
    adf_os_atomic_add(actual_discarded, &pdev->tx_queue.rsrc_cnt);
    TX_SCHED_DEBUG_PRINT("-%s \n",__FUNCTION__);

    adf_os_spin_unlock_bh(&pdev->tx_queue_spinlock);

    if (flush_all == A_TRUE && num > 0) {
        /*
         * try to flush pending frames in the tx queues
         * which are not queued in the TX scheduler.
         */
        ol_tx_queue_flush(pdev);
    }
}

void
ol_tx_enqueue(
    struct ol_txrx_pdev_t *pdev,
    struct ol_tx_frms_queue_t *txq,
    struct ol_tx_desc_t *tx_desc,
    struct ol_txrx_msdu_info_t *tx_msdu_info)
{
    int bytes;
    struct ol_tx_sched_notify_ctx_t notify_ctx;
#if defined(CONFIG_PER_VDEV_TX_DESC_POOL)
    ol_txrx_vdev_handle vdev;
#endif

    TX_SCHED_DEBUG_PRINT("Enter %s\n", __func__);

    /*
     * If too few tx descriptors are available, drop some currently-queued
     * tx frames, to provide enough tx descriptors for new frames, which
     * may be higher priority than the current frames.
     */
#if defined(CONFIG_PER_VDEV_TX_DESC_POOL)
    vdev = tx_desc->vdev;
    if (adf_os_atomic_read(&vdev->tx_desc_count) >
          ((ol_tx_desc_pool_size_hl(pdev->ctrl_pdev) >> 1)
           - TXRX_HL_TX_FLOW_CTRL_MGMT_RESERVED)) {
#else
    if (adf_os_atomic_read(&pdev->tx_queue.rsrc_cnt) <=
        pdev->tx_queue.rsrc_threshold_lo)
    {
#endif
        ol_tx_desc_list tx_descs;
        TAILQ_INIT(&tx_descs);
        ol_tx_queue_discard(pdev, A_FALSE, &tx_descs);
        //Discard Frames in Discard List
        ol_tx_desc_frame_list_free(pdev, &tx_descs, 1 /* error */);
    }
    adf_os_spin_lock_bh(&pdev->tx_queue_spinlock);
    TAILQ_INSERT_TAIL(&txq->head, tx_desc, tx_desc_list_elem);

    bytes = adf_nbuf_len(tx_desc->netbuf);
    txq->frms++;
    txq->bytes += bytes;
    OL_TX_QUEUE_LOG_ENQUEUE(pdev, tx_msdu_info, 1, bytes);

    if (txq->flag != ol_tx_queue_paused) {
        notify_ctx.event = OL_TX_ENQUEUE_FRAME;
        notify_ctx.frames = 1;
        notify_ctx.bytes = adf_nbuf_len(tx_desc->netbuf);
        notify_ctx.txq = txq;
        notify_ctx.info.tx_msdu_info = tx_msdu_info;
        ol_tx_sched_notify(pdev, &notify_ctx);
        txq->flag = ol_tx_queue_active;
    }

    if (!ETHERTYPE_IS_EAPOL_WAPI(tx_msdu_info->htt.info.ethertype)) {
        OL_TX_QUEUE_ADDBA_CHECK(pdev, txq, tx_msdu_info);
    }
    adf_os_spin_unlock_bh(&pdev->tx_queue_spinlock);
    TX_SCHED_DEBUG_PRINT("Leave %s\n", __func__);
}

u_int16_t
ol_tx_dequeue(
    struct ol_txrx_pdev_t *pdev,
    struct ol_tx_frms_queue_t *txq,
    ol_tx_desc_list *head,
    u_int16_t max_frames,
    u_int32_t *credit,
    int *bytes)
{
    u_int16_t num_frames;
    int bytes_sum;
    unsigned credit_sum;
    u_int16_t temp_frms;
    u_int32_t temp_bytes;
    bool flush_all = false;
    struct ol_tx_desc_t *tx_flush_desc;

    TXRX_ASSERT2(txq->flag != ol_tx_queue_paused);
    TX_SCHED_DEBUG_PRINT("Enter %s\n", __func__);
    temp_frms = txq->frms;
    temp_bytes = txq->bytes;

    if (txq->frms < max_frames) {
        max_frames = txq->frms;
    }
    bytes_sum = 0;
    credit_sum = 0;
    for (num_frames = 0; num_frames < max_frames; num_frames++) {
        unsigned frame_credit;
        struct ol_tx_desc_t *tx_desc;
        tx_desc = TAILQ_FIRST(&txq->head);
        if(!tx_desc) {
           flush_all = true;
           TXRX_PRINT(TXRX_PRINT_LEVEL_ERR,
                      "%s: flush frames: num_frames = %d, max_frames = %d\n",
                       __func__, num_frames, max_frames);
           break;
        }

        frame_credit = htt_tx_msdu_credit(tx_desc->netbuf);
        if (credit_sum + frame_credit > *credit) {
            break;
        }
        credit_sum += frame_credit;
        bytes_sum += adf_nbuf_len(tx_desc->netbuf);
        TAILQ_REMOVE(&txq->head, tx_desc, tx_desc_list_elem);
        TAILQ_INSERT_TAIL(head, tx_desc, tx_desc_list_elem);
    }
    txq->frms -= num_frames;
    txq->bytes -= bytes_sum;
    /* a paused queue remains paused, regardless of whether it has frames */
    if (txq->frms == 0 && txq->flag == ol_tx_queue_active) {
        txq->flag = ol_tx_queue_empty;
    }
    OL_TX_QUEUE_LOG_DEQUEUE(pdev, txq, num_frames, bytes_sum);
    TX_SCHED_DEBUG_PRINT("Leave %s\n", __func__);

    if (flush_all && bytes_sum) {
        *bytes = temp_bytes;
        *credit = 0;
        txq->frms = 0;
        txq->bytes = 0;
        while (num_frames) {
            tx_flush_desc = TAILQ_FIRST(head);
            TAILQ_REMOVE(head, tx_flush_desc, tx_desc_list_elem);
            ol_tx_desc_frame_free_nonstd(pdev, tx_flush_desc, 0);
            num_frames--;
        }

    } else {
        *bytes = bytes_sum;
        *credit = credit_sum;
    }
    return num_frames;
}

void
ol_tx_queue_free(
    struct ol_txrx_pdev_t *pdev,
    struct ol_tx_frms_queue_t *txq,
    int tid, bool is_peer_txq)
{
    int frms = 0, bytes = 0;
    struct ol_tx_desc_t *tx_desc;
    struct ol_tx_sched_notify_ctx_t notify_ctx;
    ol_tx_desc_list tx_tmp_list;

    TAILQ_INIT(&tx_tmp_list);
    TX_SCHED_DEBUG_PRINT("Enter %s\n", __func__);
    adf_os_spin_lock_bh(&pdev->tx_queue_spinlock);

    notify_ctx.event = OL_TX_DELETE_QUEUE;
    notify_ctx.txq = txq;
    notify_ctx.info.ext_tid = tid;
    ol_tx_sched_notify(pdev, &notify_ctx);

    frms = txq->frms;
    tx_desc = TAILQ_FIRST(&txq->head);
    while (txq->frms) {
        bytes += adf_nbuf_len(tx_desc->netbuf);
        txq->frms--;
        tx_desc = TAILQ_NEXT(tx_desc, tx_desc_list_elem);
    }
    OL_TX_QUEUE_LOG_FREE(pdev, txq, tid, frms, bytes, is_peer_txq);
    txq->bytes -= bytes;
    OL_TX_QUEUE_LOG_FREE(pdev, txq, tid, frms, bytes, is_peer_txq);
    txq->flag = ol_tx_queue_empty;
    /* txq->head gets reset during the TAILQ_CONCAT call */
    TAILQ_CONCAT(&tx_tmp_list, &txq->head, tx_desc_list_elem);

    adf_os_spin_unlock_bh(&pdev->tx_queue_spinlock);
    /* free tx frames without holding tx_queue_spinlock */
    adf_os_atomic_add(frms, &pdev->tx_queue.rsrc_cnt);
    while (frms) {
        tx_desc = TAILQ_FIRST(&tx_tmp_list);
        TAILQ_REMOVE(&tx_tmp_list, tx_desc, tx_desc_list_elem);
        ol_tx_desc_frame_free_nonstd(pdev, tx_desc, 0);
        frms--;
    }
    TX_SCHED_DEBUG_PRINT("Leave %s\n", __func__);
}


/*--- queue pause / unpause functions ---------------------------------------*/

static inline void
ol_txrx_peer_tid_pause_base(
    struct ol_txrx_pdev_t *pdev,
    struct ol_txrx_peer_t *peer,
    int tid)
{
    struct ol_tx_frms_queue_t *txq = &peer->txqs[tid];

    if (txq->paused_count.total++ == 0) {
        struct ol_tx_sched_notify_ctx_t notify_ctx;

        notify_ctx.event = OL_TX_PAUSE_QUEUE;
        notify_ctx.txq = txq;
        notify_ctx.info.ext_tid = tid;
        ol_tx_sched_notify(pdev, &notify_ctx);
        txq->flag = ol_tx_queue_paused;
    }
}

static inline void
ol_txrx_peer_pause_but_no_mgmt_q_base(
    struct ol_txrx_pdev_t *pdev,
    struct ol_txrx_peer_t *peer)
{
    int i;
    for (i = 0; i < OL_TX_MGMT_TID; i++) {
        ol_txrx_peer_tid_pause_base(pdev, peer, i);
    }
}

static inline void
ol_txrx_peer_pause_base(
    struct ol_txrx_pdev_t *pdev,
    struct ol_txrx_peer_t *peer)
{
    int i;
    for (i = 0; i < ARRAY_LEN(peer->txqs); i++) {
        ol_txrx_peer_tid_pause_base(pdev, peer, i);
    }
}

static inline void
ol_txrx_peer_tid_unpause_base(
    struct ol_txrx_pdev_t *pdev,
    struct ol_txrx_peer_t *peer,
    int tid)
{
    struct ol_tx_frms_queue_t *txq = &peer->txqs[tid];
    /*
     * Don't actually unpause the tx queue until all pause requests
     * have been removed.
     */
    TXRX_ASSERT2(txq->paused_count.total > 0);
    /* return, if not already paused */
    if (txq->paused_count.total == 0)
        return;

    if (--txq->paused_count.total == 0) {
        struct ol_tx_sched_notify_ctx_t notify_ctx;

        notify_ctx.event = OL_TX_UNPAUSE_QUEUE;
        notify_ctx.txq = txq;
        notify_ctx.info.ext_tid = tid;
        ol_tx_sched_notify(pdev, &notify_ctx);

        if (txq->frms == 0) {
            txq->flag = ol_tx_queue_empty;
        } else {
            txq->flag = ol_tx_queue_active;
            /*
             * Now that the are new tx frames available to download,
             * invoke the scheduling function, to see if it wants to
             * download the new frames.
             * Since the queue lock is currently held, and since
             * the scheduler function takes the lock, temporarily
             * release the lock.
             */
            adf_os_spin_unlock_bh(&pdev->tx_queue_spinlock);
            ol_tx_sched(pdev);
            adf_os_spin_lock_bh(&pdev->tx_queue_spinlock);
        }
    }
}

static inline void
ol_txrx_peer_unpause_but_no_mgmt_q_base(
    struct ol_txrx_pdev_t *pdev,
    struct ol_txrx_peer_t *peer)
{
    int i;
    for (i = 0; i < OL_TX_MGMT_TID; i++) {
        ol_txrx_peer_tid_unpause_base(pdev, peer, i);
    }
}

void
ol_txrx_peer_tid_unpause(ol_txrx_peer_handle peer, int tid)
{
    struct ol_txrx_pdev_t *pdev = peer->vdev->pdev;

    /* 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__);
    adf_os_spin_lock_bh(&pdev->tx_queue_spinlock);

    if (tid == -1) {
        int i;
        for (i = 0; i < ARRAY_LEN(peer->txqs); i++) {
            ol_txrx_peer_tid_unpause_base(pdev, peer, i);
        }
    } else {
        ol_txrx_peer_tid_unpause_base(pdev, peer, tid);
    }

    adf_os_spin_unlock_bh(&pdev->tx_queue_spinlock);
    TX_SCHED_DEBUG_PRINT("Leave %s\n", __func__);
}

void
ol_txrx_throttle_pause(ol_txrx_pdev_handle pdev)
{
#if defined(QCA_SUPPORT_TX_THROTTLE)
    adf_os_spin_lock_bh(&pdev->tx_throttle.mutex);

    if (pdev->tx_throttle.is_paused == TRUE) {
        adf_os_spin_unlock_bh(&pdev->tx_throttle.mutex);
        return;
    }

    pdev->tx_throttle.is_paused = TRUE;
    adf_os_spin_unlock_bh(&pdev->tx_throttle.mutex);
#endif
    ol_txrx_pdev_pause(pdev, OL_TXQ_PAUSE_REASON_THROTTLE);
}

void
ol_txrx_throttle_unpause(ol_txrx_pdev_handle pdev)
{
#if defined(QCA_SUPPORT_TX_THROTTLE)
    adf_os_spin_lock_bh(&pdev->tx_throttle.mutex);

    if (pdev->tx_throttle.is_paused == FALSE) {
        adf_os_spin_unlock_bh(&pdev->tx_throttle.mutex);
        return;
    }

    pdev->tx_throttle.is_paused = FALSE;
    adf_os_spin_unlock_bh(&pdev->tx_throttle.mutex);
#endif
    ol_txrx_pdev_unpause(pdev, OL_TXQ_PAUSE_REASON_THROTTLE);
}
#endif /* defined(CONFIG_HL_SUPPORT) */

#if defined(CONFIG_HL_SUPPORT) || defined(QCA_SUPPORT_TXRX_VDEV_PAUSE_LL)
/**
 * ol_txrx_pdev_pause() - Suspend all tx data for the specified physical device.
 * @data_pdev: the physical device being paused.
 * @reason:  pause reason.
 *
 * This function applies to HL systems -
 * in LL systems, applies when txrx_vdev_pause_all is enabled.
 * In some systems it is necessary to be able to temporarily
 * suspend all WLAN traffic, e.g. to allow another device such as bluetooth
 * to temporarily have exclusive access to shared RF chain resources.
 * This function suspends tx traffic within the specified physical device.
 *
 *
 * Return: None
 */
void
ol_txrx_pdev_pause(ol_txrx_pdev_handle pdev, u_int32_t reason)
{
	struct ol_txrx_vdev_t *vdev = NULL, *tmp;

	TAILQ_FOREACH_SAFE(vdev, &pdev->vdev_list, vdev_list_elem, tmp) {
		ol_txrx_vdev_pause(vdev, reason);
	}
}

/**
 * ol_txrx_pdev_unpause() - Resume tx for the specified physical device..
 * @data_pdev: the physical device being paused.
 * @reason:  pause reason.
 *
 *  This function applies to HL systems -
 *  in LL systems, applies when txrx_vdev_pause_all is enabled.
 *
 *
 * Return: None
 */
void
ol_txrx_pdev_unpause(ol_txrx_pdev_handle pdev, u_int32_t reason)
{
	struct ol_txrx_vdev_t *vdev = NULL, *tmp;

	TAILQ_FOREACH_SAFE(vdev, &pdev->vdev_list, vdev_list_elem, tmp) {
		ol_txrx_vdev_unpause(vdev, reason);
	}
}

#if defined(CONFIG_HL_SUPPORT)
/**
 * ol_txrx_pdev_pause_other_vdev() - Suspend all tx data for the specified physical device except
 * current vdev.
 * @data_pdev: the physical device being paused.
 * @reason:  pause reason.
 *		One can provide multiple line descriptions
 *		for arguments.
 * @current_id: do not pause this vdev id queues
 *
 * This function applies to HL systems -
 * in LL systems, applies when txrx_vdev_pause_all is enabled.
 * In some cases it is necessary to be able to temporarily
 * suspend other vdevs traffic, e.g. to avoid current EAPOL frames credit starvation
 *
 * Return: None
 */
void
ol_txrx_pdev_pause_other_vdev(ol_txrx_pdev_handle pdev, u_int32_t reason, u_int32_t current_id)
{
	struct ol_txrx_vdev_t *vdev = NULL, *tmp;

	TAILQ_FOREACH_SAFE(vdev, &pdev->vdev_list, vdev_list_elem, tmp) {
		if (vdev->vdev_id != current_id) {
			ol_txrx_vdev_pause(vdev, reason);
		}
	}
}

/**
 * ol_txrx_pdev_unpause_other_vdev() - Resume tx for the paused vdevs..
 * @data_pdev: the physical device being paused.
 * @reason:  pause reason.
 * @current_id: do not unpause this vdev
 *
 *  This function applies to HL systems -
 *  in LL systems, applies when txrx_vdev_pause_all is enabled.
 *
 *
 * Return: None
 */
void
ol_txrx_pdev_unpause_other_vdev(ol_txrx_pdev_handle pdev, u_int32_t reason, u_int32_t current_id)
{
	struct ol_txrx_vdev_t *vdev = NULL, *tmp;

	TAILQ_FOREACH_SAFE(vdev, &pdev->vdev_list, vdev_list_elem, tmp) {
		if (vdev->vdev_id != current_id) {
			ol_txrx_vdev_unpause(vdev, reason);
		}
	}
}
#endif

#ifdef QCA_BAD_PEER_TX_FLOW_CL

/**
 * ol_txrx_peer_bal_add_limit_peer() - add one peer into limit list
 * @pdev:		Pointer to PDEV structure.
 * @peer_id:	Peer Identifier.
 * @peer_limit	Peer limit threshold
 *
 * Add one peer into the limit list of pdev
 * Note that the peer limit info will be also updated
 * If it is the first time, start the timer
 *
 * Return: None
 */
void
ol_txrx_peer_bal_add_limit_peer(struct ol_txrx_pdev_t *pdev,
			u_int16_t peer_id, u_int16_t peer_limit)
{
	u_int16_t i, existed = 0;
	struct ol_txrx_peer_t *peer = NULL;

	for (i = 0; i < pdev->tx_peer_bal.peer_num; i++){
		if (pdev->tx_peer_bal.limit_list[i].peer_id == peer_id) {
			existed = 1;
			break;
		}
	}

	if (!existed) {
		u_int32_t peer_num = pdev->tx_peer_bal.peer_num;
		/* Check if peer_num has reached the capabilit */
		if (peer_num >= MAX_NO_PEERS_IN_LIMIT) {
			TX_SCHED_DEBUG_PRINT_ALWAYS(
				"reach the maxinum peer num %d\n",
				peer_num);
				return;
		}

		pdev->tx_peer_bal.limit_list[peer_num].peer_id = peer_id;
		pdev->tx_peer_bal.limit_list[peer_num].limit_flag = TRUE;
		pdev->tx_peer_bal.limit_list[peer_num].limit = peer_limit;
		pdev->tx_peer_bal.peer_num++;

		peer = ol_txrx_peer_find_by_id(pdev, peer_id);
		if (peer) {
			peer->tx_limit_flag = TRUE;
			peer->tx_limit = peer_limit;
		}

		TX_SCHED_DEBUG_PRINT_ALWAYS(
			"Add one peer into limit queue, peer_id %d, cur peer num %d\n",
			peer_id,
			pdev->tx_peer_bal.peer_num);
	}

	/* Only start the timer once */
	if (pdev->tx_peer_bal.peer_bal_timer_state ==
					ol_tx_peer_bal_timer_inactive) {
		adf_os_timer_start(&pdev->tx_peer_bal.peer_bal_timer,
				pdev->tx_peer_bal.peer_bal_period_ms);
		pdev->tx_peer_bal.peer_bal_timer_state =
				ol_tx_peer_bal_timer_active;
	}
}

/**
 * ol_txrx_peer_bal_remove_limit_peer() - remove one peer from limit list
 * @pdev:		Pointer to PDEV structure.
 * @peer_id:	Peer Identifier.
 *
 * Remove one peer from the limit list of pdev
 * Note that Only stop the timer if no peer in limit state
 *
 * Return: NULL
 */
void
ol_txrx_peer_bal_remove_limit_peer(struct ol_txrx_pdev_t *pdev,
			u_int16_t peer_id)
{
	u_int16_t i;
	struct ol_txrx_peer_t *peer = NULL;

	for (i = 0; i < pdev->tx_peer_bal.peer_num; i++) {
		if ( pdev->tx_peer_bal.limit_list[i].peer_id == peer_id) {
			pdev->tx_peer_bal.limit_list[i] =
				pdev->tx_peer_bal.limit_list[pdev->tx_peer_bal.peer_num - 1];
			pdev->tx_peer_bal.peer_num--;

			peer = ol_txrx_peer_find_by_id(pdev, peer_id);
			if (peer) {
				peer->tx_limit_flag = FALSE;
			}

			TX_SCHED_DEBUG_PRINT(
				"Remove one peer from limitq, peer_id %d, cur peer num %d\n",
				peer_id,
				pdev->tx_peer_bal.peer_num);
			break;
		}
	}

	/* Only stop the timer if no peer in limit state */
	if (pdev->tx_peer_bal.peer_num == 0) {
		adf_os_timer_cancel(&pdev->tx_peer_bal.peer_bal_timer);
		pdev->tx_peer_bal.peer_bal_timer_state =
				ol_tx_peer_bal_timer_inactive;
	}
}

void
ol_txrx_peer_pause_but_no_mgmt_q(ol_txrx_peer_handle peer)
{
	struct ol_txrx_pdev_t *pdev = peer->vdev->pdev;

	/* 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__);
	adf_os_spin_lock_bh(&pdev->tx_queue_spinlock);

	ol_txrx_peer_pause_but_no_mgmt_q_base(pdev, peer);

	adf_os_spin_unlock_bh(&pdev->tx_queue_spinlock);
	TX_SCHED_DEBUG_PRINT("Leave %s\n", __func__);
}

void
ol_txrx_peer_unpause_but_no_mgmt_q(ol_txrx_peer_handle peer)
{
	struct ol_txrx_pdev_t *pdev = peer->vdev->pdev;

	/* 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__);
	adf_os_spin_lock_bh(&pdev->tx_queue_spinlock);

	ol_txrx_peer_unpause_but_no_mgmt_q_base(pdev, peer);

	adf_os_spin_unlock_bh(&pdev->tx_queue_spinlock);
	TX_SCHED_DEBUG_PRINT("Leave %s\n", __func__);
}

u_int16_t
ol_tx_bad_peer_dequeue_check(struct ol_tx_frms_queue_t *txq,
	u_int16_t max_frames,
	u_int16_t *tx_limit_flag)
{
	if (txq && (txq->peer) && (txq->peer->tx_limit_flag)
			&& (txq->peer->tx_limit < max_frames)) {
		TX_SCHED_DEBUG_PRINT("Peer ID %d goes to limit, threshold is %d\n",
			txq->peer->peer_ids[0], txq->peer->tx_limit);
		*tx_limit_flag = 1;
		return txq->peer->tx_limit;
	} else {
		return max_frames;
	}
}

void
ol_tx_bad_peer_update_tx_limit(struct ol_txrx_pdev_t *pdev,
	struct ol_tx_frms_queue_t *txq,
	u_int16_t frames,
	u_int16_t tx_limit_flag)
{
    adf_os_spin_lock_bh(&pdev->tx_peer_bal.mutex);
    if (txq && tx_limit_flag && (txq->peer) && (txq->peer->tx_limit_flag)) {
        if (txq->peer->tx_limit < frames) {
            txq->peer->tx_limit = 0;
        } else {
            txq->peer->tx_limit -= frames;
        }
        TX_SCHED_DEBUG_PRINT_ALWAYS("Peer ID %d in limit, deque %d frms\n",
			txq->peer->peer_ids[0], frames);
    } else if (txq->peer) {
        TX_SCHED_DEBUG_PRINT("Download peer_id %d, num_frames %d\n",
			txq->peer->peer_ids[0], frames);
    }
    adf_os_spin_unlock_bh(&pdev->tx_peer_bal.mutex);
}

void
ol_txrx_bad_peer_txctl_set_setting(struct ol_txrx_pdev_t *pdev,
			int enable, int period, int txq_limit)
{
	if (enable) {
		pdev->tx_peer_bal.enabled = ol_tx_peer_bal_enable;
	} else {
		pdev->tx_peer_bal.enabled = ol_tx_peer_bal_disable;
	}
	/* Set the current settingl */
	pdev->tx_peer_bal.peer_bal_period_ms = period;
	pdev->tx_peer_bal.peer_bal_txq_limit = txq_limit;
}

void
ol_txrx_bad_peer_txctl_update_threshold(struct ol_txrx_pdev_t *pdev,
			int level, int tput_thresh, int tx_limit)
{
	/* Set the current settingl */
	pdev->tx_peer_bal.ctl_thresh[level].tput_thresh =
			tput_thresh;
	pdev->tx_peer_bal.ctl_thresh[level].tx_limit =
			tx_limit;
}

void
ol_tx_pdev_peer_bal_timer(void *context)
{
	int i;
	struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)context;

	adf_os_spin_lock_bh(&pdev->tx_peer_bal.mutex);

	for (i = 0; i < pdev->tx_peer_bal.peer_num; i++) {
		if (pdev->tx_peer_bal.limit_list[i].limit_flag) {
			u_int16_t peer_id =
				pdev->tx_peer_bal.limit_list[i].peer_id;
			u_int16_t tx_limit =
				pdev->tx_peer_bal.limit_list[i].limit;

			struct ol_txrx_peer_t *peer = NULL;
			peer = ol_txrx_peer_find_by_id(pdev, peer_id);
			TX_SCHED_DEBUG_PRINT("%s peer_id %d  peer = 0x%x tx limit %d\n",
					__FUNCTION__, peer_id,
					(int)peer, tx_limit);

			/* It is possible the peer limit is still not 0,
			   but it is the scenario should not be cared */
			if (peer) {
				peer->tx_limit = tx_limit;
			} else {
				ol_txrx_peer_bal_remove_limit_peer(pdev,
								peer_id);
				TX_SCHED_DEBUG_PRINT_ALWAYS("No such a peer, peer id = %d\n",
					peer_id);
			}
		}
	}

	adf_os_spin_unlock_bh(&pdev->tx_peer_bal.mutex);

	if (pdev->tx_peer_bal.peer_num) {
		ol_tx_sched(pdev);
		adf_os_timer_start(&pdev->tx_peer_bal.peer_bal_timer,
				pdev->tx_peer_bal.peer_bal_period_ms);
	}
}

void
ol_txrx_set_txq_peer(
	struct ol_tx_frms_queue_t *txq,
	struct ol_txrx_peer_t *peer)
{
	if (txq) {
		txq->peer = peer;
	}
}

void ol_tx_badpeer_flow_cl_init(struct ol_txrx_pdev_t *pdev)
{
	u_int32_t timer_period;

	adf_os_spinlock_init(&pdev->tx_peer_bal.mutex);
	pdev->tx_peer_bal.peer_num = 0;
	pdev->tx_peer_bal.peer_bal_timer_state
		= ol_tx_peer_bal_timer_inactive;

	timer_period = 2000;
	pdev->tx_peer_bal.peer_bal_period_ms = timer_period;

	adf_os_timer_init(
			pdev->osdev,
			&pdev->tx_peer_bal.peer_bal_timer,
			ol_tx_pdev_peer_bal_timer,
			pdev);
}

void ol_tx_badpeer_flow_cl_deinit(struct ol_txrx_pdev_t *pdev)
{
	adf_os_timer_cancel(&pdev->tx_peer_bal.peer_bal_timer);
	pdev->tx_peer_bal.peer_bal_timer_state =
					ol_tx_peer_bal_timer_inactive;
	adf_os_timer_free(&pdev->tx_peer_bal.peer_bal_timer);
	adf_os_spinlock_destroy(&pdev->tx_peer_bal.mutex);
}

void
ol_txrx_peer_link_status_handler(
    ol_txrx_pdev_handle pdev,
    u_int16_t peer_num,
    struct rate_report_t* peer_link_status)
{
	u_int16_t i = 0;
	struct ol_txrx_peer_t *peer = NULL;

	if (NULL == pdev) {
		TX_SCHED_DEBUG_PRINT_ALWAYS("Error: NULL pdev handler \n");
		return;
	}

	if (NULL == peer_link_status) {
		TX_SCHED_DEBUG_PRINT_ALWAYS(
			"Error:NULL link report message. peer num %d\n",
			peer_num);
		return;
	}

	/* Check if bad peer tx flow CL is enabled */
	if (pdev->tx_peer_bal.enabled != ol_tx_peer_bal_enable){
		TX_SCHED_DEBUG_PRINT_ALWAYS(
			"Bad peer tx flow CL is not enabled, ignore it\n");
		return;
	}

	/* Check peer_num is reasonable */
	if (peer_num > MAX_NO_PEERS_IN_LIMIT){
		TX_SCHED_DEBUG_PRINT_ALWAYS(
			"%s: Bad peer_num %d \n", __func__, peer_num);
		return;
	}

	VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_DEBUG,
		  "%s: peer_num %d", __func__, peer_num);

	for (i = 0; i < peer_num; i++) {
		u_int16_t peer_limit, peer_id;
		u_int16_t pause_flag, unpause_flag;
		u_int32_t peer_phy, peer_tput;

		peer_id = peer_link_status->id;
		peer_phy = peer_link_status->phy;
		peer_tput = peer_link_status->rate;

		TX_SCHED_DEBUG_PRINT("%s: peer id %d tput %d phy %d\n",
				__func__, peer_id, peer_tput, peer_phy);

		/* Sanity check for the PHY mode value */
		if (peer_phy > TXRX_IEEE11_AC) {
			TX_SCHED_DEBUG_PRINT_ALWAYS(
				"%s: PHY value is illegal: %d, and the peer_id %d \n",
				__func__, peer_link_status->phy, peer_id);
			continue;
		}
		pause_flag   = FALSE;
		unpause_flag = FALSE;
		peer_limit   = 0;

		/* From now on, PHY, PER info should be all fine */
		adf_os_spin_lock_bh(&pdev->tx_peer_bal.mutex);

		/* Update link status analysis for each peer */
		peer = ol_txrx_peer_find_by_id(pdev, peer_id);
		if (peer) {
			u_int32_t thresh, limit, phy;
			phy = peer_link_status->phy;
			thresh = pdev->tx_peer_bal.ctl_thresh[phy].tput_thresh;
			limit = pdev->tx_peer_bal.ctl_thresh[phy].tx_limit;

			if (((peer->tx_pause_flag) || (peer->tx_limit_flag))
				&& (peer_tput) && (peer_tput < thresh)) {
				peer_limit = limit;
			}

			if (peer_limit) {
				ol_txrx_peer_bal_add_limit_peer(pdev, peer_id,
					peer_limit);
			} else if (pdev->tx_peer_bal.peer_num) {
				TX_SCHED_DEBUG_PRINT("%s: Check if peer_id %d exit limit\n",
						__func__, peer_id);
				ol_txrx_peer_bal_remove_limit_peer(pdev, peer_id);
			}
			if ((peer_tput == 0) && (peer->tx_pause_flag == FALSE)) {
				peer->tx_pause_flag = TRUE;
				pause_flag = TRUE;
			} else if (peer->tx_pause_flag){
				unpause_flag = TRUE;
				peer->tx_pause_flag = FALSE;
			}
		} else {
			TX_SCHED_DEBUG_PRINT("%s: Remove peer_id %d from limit list\n",
						__func__, peer_id);
			ol_txrx_peer_bal_remove_limit_peer(pdev, peer_id);
		}

		peer_link_status++;
		adf_os_spin_unlock_bh(&pdev->tx_peer_bal.mutex);
		if (pause_flag) {
			ol_txrx_peer_pause_but_no_mgmt_q(peer);
		} else if (unpause_flag) {
			ol_txrx_peer_unpause_but_no_mgmt_q(peer);
		}
	}
}
#endif /* QCA_BAD_PEER_TX_FLOW_CL */

void
ol_txrx_vdev_pause(ol_txrx_vdev_handle vdev, u_int32_t reason)
{
    /* 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__);

    if (vdev->pdev->cfg.is_high_latency) {
#if defined(CONFIG_HL_SUPPORT)
        struct ol_txrx_pdev_t *pdev = vdev->pdev;
        struct ol_txrx_peer_t *peer;
        /* use peer_ref_mutex before accessing peer_list */
        adf_os_spin_lock_bh(&pdev->peer_ref_mutex);
        adf_os_spin_lock_bh(&pdev->tx_queue_spinlock);
        if((vdev->hl_paused_reason & reason) == 0) {
            vdev->hl_paused_reason |= reason;
            TAILQ_FOREACH(peer, &vdev->peer_list, peer_list_elem) {
                ol_txrx_peer_pause_base(pdev, peer);
            }
        }
        adf_os_spin_unlock_bh(&pdev->tx_queue_spinlock);
        adf_os_spin_unlock_bh(&pdev->peer_ref_mutex);
#endif /* defined(CONFIG_HL_SUPPORT) */
    } else {
        adf_os_spin_lock_bh(&vdev->ll_pause.mutex);
        vdev->ll_pause.paused_reason |= reason;
        vdev->ll_pause.pause_timestamp =
                        adf_os_gettimestamp();
        vdev->ll_pause.q_pause_cnt++;
        vdev->ll_pause.is_q_paused = TRUE;
        adf_os_spin_unlock_bh(&vdev->ll_pause.mutex);
    }

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

void
ol_txrx_vdev_unpause(ol_txrx_vdev_handle vdev, u_int32_t reason)
{
    /* 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__);

    if (vdev->pdev->cfg.is_high_latency) {
#if defined(CONFIG_HL_SUPPORT)
        struct ol_txrx_pdev_t *pdev = vdev->pdev;
        struct ol_txrx_peer_t *peer;

        /* take peer_ref_mutex before accessing peer_list */
        adf_os_spin_lock_bh(&pdev->peer_ref_mutex);
        adf_os_spin_lock_bh(&pdev->tx_queue_spinlock);
        if (vdev->hl_paused_reason & reason) {
            vdev->hl_paused_reason &= ~reason;

            TAILQ_FOREACH(peer, &vdev->peer_list, peer_list_elem) {
                int i;
                for (i = 0; i < ARRAY_LEN(peer->txqs); i++) {
                    ol_txrx_peer_tid_unpause_base(pdev, peer, i);
                }
            }
        }
        adf_os_spin_unlock_bh(&pdev->tx_queue_spinlock);
        adf_os_spin_unlock_bh(&pdev->peer_ref_mutex);
#endif /* defined(CONFIG_HL_SUPPORT) */
    } else {
        adf_os_spin_lock_bh(&vdev->ll_pause.mutex);
        if (vdev->ll_pause.paused_reason & reason)
        {
            vdev->ll_pause.paused_reason &= ~reason;
            vdev->ll_pause.is_q_paused = FALSE;
            vdev->ll_pause.q_unpause_cnt++;
#ifdef QCA_SUPPORT_TXRX_VDEV_LL_TXQ
            if (reason == OL_TXQ_PAUSE_REASON_VDEV_SUSPEND) {
                adf_os_spin_unlock_bh(&vdev->ll_pause.mutex);
                ol_tx_vdev_ll_pause_start_timer(vdev);
            }
            else
#endif
            if (!vdev->ll_pause.paused_reason) {
                adf_os_spin_unlock_bh(&vdev->ll_pause.mutex);
                ol_tx_vdev_ll_pause_queue_send(vdev);
            } else {
                adf_os_spin_unlock_bh(&vdev->ll_pause.mutex);
            }
        } else {
            adf_os_spin_unlock_bh(&vdev->ll_pause.mutex);
        }
    }

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

void
ol_txrx_vdev_flush(ol_txrx_vdev_handle vdev)
{
    if (vdev->pdev->cfg.is_high_latency) {
        #if defined(CONFIG_HL_SUPPORT)
        ol_tx_queue_vdev_flush(vdev->pdev, vdev);
        #endif
    } else {
        adf_os_spin_lock_bh(&vdev->ll_pause.mutex);
        adf_os_timer_cancel(&vdev->ll_pause.timer);
        vdev->ll_pause.is_q_timer_on = FALSE;
        while (vdev->ll_pause.txq.head) {
            adf_nbuf_t next = adf_nbuf_next(vdev->ll_pause.txq.head);
            adf_nbuf_set_next(vdev->ll_pause.txq.head, NULL);
            adf_nbuf_unmap(vdev->pdev->osdev, vdev->ll_pause.txq.head,
                           ADF_OS_DMA_TO_DEVICE);
            adf_nbuf_tx_free(vdev->ll_pause.txq.head, ADF_NBUF_PKT_ERROR);
            vdev->ll_pause.txq.head = next;
        }
        vdev->ll_pause.txq.tail = NULL;
        vdev->ll_pause.txq.depth = 0;
        adf_os_spin_unlock_bh(&vdev->ll_pause.mutex);
    }
}

#endif  // defined(CONFIG_HL_SUPPORT) || defined(QCA_SUPPORT_TXRX_VDEV_PAUSE_LL)

/*--- LL tx throttle queue code --------------------------------------------*/
#if defined(QCA_SUPPORT_TX_THROTTLE)
u_int8_t ol_tx_pdev_is_target_empty(void)
{
    /* TM TODO */
    return 1;
}

void ol_tx_pdev_throttle_phase_timer(void *context)
{
    struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)context;
    int ms = 0;
    throttle_level cur_level;
    throttle_phase cur_phase;

    /* update the phase */
    pdev->tx_throttle.current_throttle_phase++;

    if (pdev->tx_throttle.current_throttle_phase == THROTTLE_PHASE_MAX) {
        pdev->tx_throttle.current_throttle_phase = THROTTLE_PHASE_OFF;
    }

    if (pdev->tx_throttle.current_throttle_phase == THROTTLE_PHASE_OFF) {
        if (ol_tx_pdev_is_target_empty(/*pdev*/)) {
            TXRX_PRINT(TXRX_PRINT_LEVEL_WARN, "throttle phase --> OFF\n");

            if (pdev->cfg.is_high_latency)
                ol_txrx_throttle_pause(pdev);

            cur_level = pdev->tx_throttle.current_throttle_level;
            cur_phase = pdev->tx_throttle.current_throttle_phase;
            ms = pdev->tx_throttle.throttle_time_ms[cur_level][cur_phase];
            if (pdev->tx_throttle.current_throttle_level !=
                THROTTLE_LEVEL_0) {
                TXRX_PRINT(TXRX_PRINT_LEVEL_WARN, "start timer %d ms\n", ms);
                adf_os_timer_mod(&pdev->tx_throttle.phase_timer, ms);
            }
        }
    }
    else /* THROTTLE_PHASE_ON */
    {
        TXRX_PRINT(TXRX_PRINT_LEVEL_WARN, "throttle phase --> ON\n");

        if (pdev->cfg.is_high_latency)
            ol_txrx_throttle_unpause(pdev);
#ifdef QCA_SUPPORT_TXRX_VDEV_LL_TXQ
        else
            ol_tx_pdev_ll_pause_queue_send_all(pdev);
#endif

        cur_level = pdev->tx_throttle.current_throttle_level;
        cur_phase = pdev->tx_throttle.current_throttle_phase;
        ms = pdev->tx_throttle.throttle_time_ms[cur_level][cur_phase];
        if (pdev->tx_throttle.current_throttle_level != THROTTLE_LEVEL_0) {
            TXRX_PRINT(TXRX_PRINT_LEVEL_WARN, "start timer %d ms\n", ms);
            adf_os_timer_mod(&pdev->tx_throttle.phase_timer, ms);
        }
    }
}

#ifdef QCA_SUPPORT_TXRX_VDEV_LL_TXQ
void ol_tx_pdev_throttle_tx_timer(void *context)
{
    struct ol_txrx_pdev_t *pdev = (struct ol_txrx_pdev_t *)context;
    ol_tx_pdev_ll_pause_queue_send_all(pdev);
}
#endif

void ol_tx_throttle_set_level(struct ol_txrx_pdev_t *pdev, int level)
{
    int ms = 0;

    if (level >= THROTTLE_LEVEL_MAX) {
        TXRX_PRINT(TXRX_PRINT_LEVEL_WARN,
                    "%s invalid throttle level set %d, ignoring\n",
                    __func__, level);
        return;
    }

    TXRX_PRINT(TXRX_PRINT_LEVEL_WARN, "Setting throttle level %d\n", level);

    /* Set the current throttle level */
    pdev->tx_throttle.current_throttle_level = (throttle_level)level;

    if (pdev->cfg.is_high_latency) {

        adf_os_timer_cancel(&pdev->tx_throttle.phase_timer);

        /* Set the phase */
        if (level != THROTTLE_LEVEL_0) {
            pdev->tx_throttle.current_throttle_phase = THROTTLE_PHASE_OFF;
            ms = pdev->tx_throttle.throttle_time_ms[level][THROTTLE_PHASE_OFF];
            /* pause all */
            ol_txrx_throttle_pause(pdev);
            adf_os_timer_mod(&pdev->tx_throttle.phase_timer, ms);
        } else {
            pdev->tx_throttle.current_throttle_phase = THROTTLE_PHASE_ON;
            ms = pdev->tx_throttle.throttle_time_ms[level][THROTTLE_PHASE_ON];
            /* unpause all */
            ol_txrx_throttle_unpause(pdev);
        }
    } else {
        /* Reset the phase */
        pdev->tx_throttle.current_throttle_phase = THROTTLE_PHASE_OFF;

        /* Start with the new time */
        ms = pdev->tx_throttle.throttle_time_ms[level][THROTTLE_PHASE_OFF];

        adf_os_timer_cancel(&pdev->tx_throttle.phase_timer);
        adf_os_timer_mod(&pdev->tx_throttle.phase_timer, ms);
    }
}

void ol_tx_throttle_init_period(struct ol_txrx_pdev_t *pdev, int period,
    u_int8_t *dutycycle_level)
{
    int i;

    /* Set the current throttle level */
    pdev->tx_throttle.throttle_period_ms = period;

    TXRX_PRINT(TXRX_PRINT_LEVEL_WARN, "level  OFF  ON\n");
    for (i = 0; i < THROTTLE_LEVEL_MAX; i++) {
        pdev->tx_throttle.throttle_time_ms[i][THROTTLE_PHASE_ON] =
            pdev->tx_throttle.throttle_period_ms -
                ((dutycycle_level[i] * pdev->tx_throttle.throttle_period_ms)
                 /100);
        pdev->tx_throttle.throttle_time_ms[i][THROTTLE_PHASE_OFF] =
            pdev->tx_throttle.throttle_period_ms -
            pdev->tx_throttle.throttle_time_ms[i][THROTTLE_PHASE_ON];
        TXRX_PRINT(TXRX_PRINT_LEVEL_WARN, "%d      %d    %d\n", i,
                   pdev->tx_throttle.throttle_time_ms[i][THROTTLE_PHASE_OFF],
                   pdev->tx_throttle.throttle_time_ms[i][THROTTLE_PHASE_ON]);
    }
}

void ol_tx_throttle_init(struct ol_txrx_pdev_t *pdev)
{
    u_int32_t throttle_period;
    u_int8_t dutycycle_level[THROTTLE_LEVEL_MAX];
    int i;

    pdev->tx_throttle.current_throttle_level = THROTTLE_LEVEL_0;
    pdev->tx_throttle.current_throttle_phase = THROTTLE_PHASE_OFF;
    adf_os_spinlock_init(&pdev->tx_throttle.mutex);

    throttle_period = ol_cfg_throttle_period_ms(pdev->ctrl_pdev);

    for (i = 0; i < THROTTLE_LEVEL_MAX; i++)
        dutycycle_level[i] = ol_cfg_throttle_duty_cycle_level(pdev->ctrl_pdev,
                                                              i);

    ol_tx_throttle_init_period(pdev, throttle_period, &dutycycle_level[0]);

    adf_os_timer_init(
            pdev->osdev,
            &pdev->tx_throttle.phase_timer,
            ol_tx_pdev_throttle_phase_timer,
            pdev, ADF_DEFERRABLE_TIMER);

#ifdef QCA_SUPPORT_TXRX_VDEV_LL_TXQ
    adf_os_timer_init(
            pdev->osdev,
            &pdev->tx_throttle.tx_timer,
            ol_tx_pdev_throttle_tx_timer,
            pdev, ADF_DEFERRABLE_TIMER);
#endif

    pdev->tx_throttle.tx_threshold = THROTTLE_TX_THRESHOLD;
}
#endif /* QCA_SUPPORT_TX_THROTTLE */
/*--- End of LL tx throttle queue code ---------------------------------------*/

#if defined(CONFIG_HL_SUPPORT)

/*--- ADDBA triggering functions --------------------------------------------*/


/*=== debug functions =======================================================*/

/*--- queue event log -------------------------------------------------------*/

#if defined(DEBUG_HL_LOGGING)

static void
ol_tx_queue_log_entry_type_info(
    u_int8_t *type, int *size, int *align, int var_size)
{
    switch (*type) {
    case ol_tx_log_entry_type_enqueue:
    case ol_tx_log_entry_type_dequeue:
    case ol_tx_log_entry_type_queue_free:
        *size = sizeof(struct ol_tx_log_queue_add_t);
        *align = 2;
        break;

    case ol_tx_log_entry_type_queue_state:
        *size = offsetof(struct ol_tx_log_queue_state_var_sz_t, data);
        *align = 4;
        if (var_size) {
            /* read the variable-sized record, to see how large it is */
            int align_pad;
            struct ol_tx_log_queue_state_var_sz_t *record;

            align_pad =
               (*align - (uint32_t)(((unsigned long) type) + 1)) & (*align - 1);
            record = (struct ol_tx_log_queue_state_var_sz_t *)
                (type + 1 + align_pad);
            *size += record->num_cats_active *
                (sizeof(u_int32_t) /* bytes */ + sizeof(u_int16_t) /* frms */);
        }
        break;

    //case ol_tx_log_entry_type_drop:
    default:
        *size = 0;
        *align = 0;
    };
}

static void
ol_tx_queue_log_oldest_update(struct ol_txrx_pdev_t *pdev, int offset)
{
    int oldest_record_offset;

    /*
     * If the offset of the oldest record is between the current and
     * new values of the offset of the newest record, then the oldest
     * record has to be dropped from the log to provide room for the
     * newest record.
     * Advance the offset of the oldest record until it points to a
     * record that is beyond the new value of the offset of the newest
     * record.
     */
    if (!pdev->txq_log.wrapped) {
        /*
         * The log has not even filled up yet - no need to remove
         * the oldest record to make room for a new record.
         */
        return;
    }

    if (offset > pdev->txq_log.offset) {
        /*
         * not wraparound -
         * The oldest record offset may have already wrapped around,
         * even if the newest record has not.  In this case, then
         * the oldest record offset is fine where it is.
         */
        if (pdev->txq_log.oldest_record_offset == 0) {
            return;
        }
        oldest_record_offset = pdev->txq_log.oldest_record_offset;
    } else {
        /* wraparound */
        oldest_record_offset = 0;
    }

    while (oldest_record_offset < offset) {
        int size, align, align_pad;
        u_int8_t type;

        type = pdev->txq_log.data[oldest_record_offset];
        if (type == ol_tx_log_entry_type_wrap) {
            oldest_record_offset = 0;
            break;
        }
        ol_tx_queue_log_entry_type_info(
            &pdev->txq_log.data[oldest_record_offset], &size, &align, 1);
        align_pad =
            (align - ((oldest_record_offset + 1/*type*/))) & (align - 1);
        /*
        VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO_LOW,
            "TXQ LOG old alloc: offset %d, type %d, size %d (%d)\n",
            oldest_record_offset, type, size, size + 1 + align_pad);
         */
        oldest_record_offset += size + 1 + align_pad;
    }
    if (oldest_record_offset >= pdev->txq_log.size) {
        oldest_record_offset = 0;
    }
    pdev->txq_log.oldest_record_offset = oldest_record_offset;
}

void*
ol_tx_queue_log_alloc(
    struct ol_txrx_pdev_t *pdev,
    u_int8_t type /* ol_tx_log_entry_type */,
    int extra_bytes)
{
    int size, align, align_pad;
    int offset;

    ol_tx_queue_log_entry_type_info(&type, &size, &align, 0);
    size += extra_bytes;

    offset = pdev->txq_log.offset;
    align_pad = (align - ((offset + 1/*type*/))) & (align - 1);

    if (pdev->txq_log.size - offset >= size + 1 + align_pad) {
        /* no need to wrap around */
        goto alloc_found;
    }
    if (! pdev->txq_log.allow_wrap) {
        return NULL; /* log is full and can't wrap */
    }
    /* handle wrap-around */
    pdev->txq_log.wrapped = 1;
    offset = 0;
    align_pad = (align - ((offset + 1/*type*/))) & (align - 1);
    /* sanity check that the log is large enough to hold this entry */
    if (pdev->txq_log.size <= size + 1 + align_pad) {
        return NULL;
    }

alloc_found:
    ol_tx_queue_log_oldest_update(pdev, offset + size + 1 + align_pad);
    if (offset == 0)  {
        pdev->txq_log.data[pdev->txq_log.offset] = ol_tx_log_entry_type_wrap;
    }
    /*
    VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO_LOW,
    "TXQ LOG new alloc: offset %d, type %d, size %d (%d)\n",
        offset, type, size, size + 1 + align_pad);
     */
    pdev->txq_log.data[offset] = type;
    pdev->txq_log.offset = offset + size + 1 + align_pad;
    if (pdev->txq_log.offset >= pdev->txq_log.size) {
        pdev->txq_log.offset = 0;
        pdev->txq_log.wrapped = 1;
    }
    return &pdev->txq_log.data[offset + 1 + align_pad];
}

static int
ol_tx_queue_log_record_display(struct ol_txrx_pdev_t *pdev, int offset)
{
    int size, align, align_pad;
    u_int8_t type;
    struct ol_txrx_peer_t *peer;

    adf_os_spin_lock_bh(&pdev->txq_log_spinlock);
    type = pdev->txq_log.data[offset];
    ol_tx_queue_log_entry_type_info(
        &pdev->txq_log.data[offset], &size, &align, 1);
    align_pad = (align - ((offset + 1/*type*/))) & (align - 1);

    switch (type) {
    case ol_tx_log_entry_type_enqueue:
        {
            struct ol_tx_log_queue_add_t record;
            adf_os_mem_copy(&record,
                            &pdev->txq_log.data[offset + 1 + align_pad],
                            sizeof(struct ol_tx_log_queue_add_t));
            adf_os_spin_unlock_bh(&pdev->txq_log_spinlock);

            if (record.peer_id != 0xffff) {
                peer = ol_txrx_peer_find_by_id(pdev, record.peer_id);
                if (peer != NULL)
                    VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_ERROR,
                        "       Q: %6d  %5d  %3d  %4d (%02x:%02x:%02x:%02x:%02x:%02x)",
                        record.num_frms, record.num_bytes, record.tid,
                        record.peer_id,
                        peer->mac_addr.raw[0], peer->mac_addr.raw[1],
                        peer->mac_addr.raw[2], peer->mac_addr.raw[3],
                        peer->mac_addr.raw[4], peer->mac_addr.raw[5]);
               else
                    VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_ERROR,
                        "       Q: %6d  %5d  %3d  %4d",
                        record.num_frms, record.num_bytes,
                        record.tid, record.peer_id);
            } else {
                VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO,
                    "       Q: %6d  %5d  %3d  from vdev",
                    record.num_frms, record.num_bytes, record.tid);
            }
            break;
        }
    case ol_tx_log_entry_type_dequeue:
        {
            struct ol_tx_log_queue_add_t record;
            adf_os_mem_copy(&record,
                            &pdev->txq_log.data[offset + 1 + align_pad],
                            sizeof(struct ol_tx_log_queue_add_t));
            adf_os_spin_unlock_bh(&pdev->txq_log_spinlock);

            if (record.peer_id != 0xffff) {
                peer = ol_txrx_peer_find_by_id(pdev, record.peer_id);
                if (peer != NULL)
                    VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_ERROR,
                        "      DQ: %6d  %5d  %3d  %4d (%02x:%02x:%02x:%02x:%02x:%02x)",
                        record.num_frms, record.num_bytes, record.tid,
                        record.peer_id,
                        peer->mac_addr.raw[0], peer->mac_addr.raw[1],
                        peer->mac_addr.raw[2], peer->mac_addr.raw[3],
                        peer->mac_addr.raw[4], peer->mac_addr.raw[5]);
                else
                    VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_ERROR,
                        "      DQ: %6d  %5d  %3d  %4d",
                        record.num_frms, record.num_bytes,
                        record.tid, record.peer_id);
            } else {
                VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO,
                    "      DQ: %6d  %5d  %3d  from vdev",
                    record.num_frms, record.num_bytes, record.tid);
            }
            break;
        }
    case ol_tx_log_entry_type_queue_free:
        {
            struct ol_tx_log_queue_add_t record;
            adf_os_mem_copy(&record,
                            &pdev->txq_log.data[offset + 1 + align_pad],
                            sizeof(struct ol_tx_log_queue_add_t));
            adf_os_spin_unlock_bh(&pdev->txq_log_spinlock);

            if (record.peer_id != 0xffff) {
                peer = ol_txrx_peer_find_by_id(pdev, record.peer_id);
                if (peer != NULL)
                    VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_ERROR,
                        "     F: %6d  %5d  %3d  %4d (%02x:%02x:%02x:%02x:%02x:%02x)",
                        record.num_frms, record.num_bytes, record.tid,
                        record.peer_id,
                        peer->mac_addr.raw[0], peer->mac_addr.raw[1],
                        peer->mac_addr.raw[2], peer->mac_addr.raw[3],
                        peer->mac_addr.raw[4], peer->mac_addr.raw[5]);
                else
                    VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_ERROR,
                        "      F: %6d  %5d  %3d  %4d",
                        record.num_frms, record.num_bytes,
                        record.tid, record.peer_id);
            } else {
                /* shouldn't happen */
                VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO,
                    "Unexpected vdev queue removal\n");
            }
            break;
        }

    case ol_tx_log_entry_type_queue_state:
        {
            int i, j;
            u_int32_t active_bitmap;
            struct ol_tx_log_queue_state_var_sz_t record;
            u_int8_t *data;

            adf_os_mem_copy(&record,
                            &pdev->txq_log.data[offset + 1 + align_pad],
                            sizeof(struct ol_tx_log_queue_state_var_sz_t));
            adf_os_spin_unlock_bh(&pdev->txq_log_spinlock);

            VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_ERROR,
                "       S: bitmap = %#x",
                 record.active_bitmap);
            data = &record.data[0];
            j = 0;
            i = 0;
            active_bitmap = record.active_bitmap;
            while (active_bitmap) {
                if (active_bitmap & 0x1) {
                    u_int16_t frms;
                    u_int32_t bytes;

                    frms = data[0] | (data[1] << 8);
                    bytes = (data[2] <<  0) | (data[3] <<  8) |
                            (data[4] << 16) | (data[5] << 24);
                    VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_ERROR,
                        "  cat %2d: %6d  %5d",
                        i, frms, bytes);
                    data += 6;
                    j++;
                }
                i++;
                active_bitmap >>= 1;
            }
            break;
        }

    //case ol_tx_log_entry_type_drop:

    case ol_tx_log_entry_type_wrap:
        adf_os_spin_unlock_bh(&pdev->txq_log_spinlock);
        return -1 * offset; /* go back to the top */

    default:
        adf_os_spin_unlock_bh(&pdev->txq_log_spinlock);
        VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_ERROR,
            "  *** invalid tx log entry type (%d)\n", type);
        return 0; /* error */
    };

    return size + 1 + align_pad;
}

void
ol_tx_queue_log_display(struct ol_txrx_pdev_t *pdev)
{
    int offset;
    int unwrap;

    adf_os_spin_lock_bh(&pdev->txq_log_spinlock);
    offset = pdev->txq_log.oldest_record_offset;
    unwrap = pdev->txq_log.wrapped;
    adf_os_spin_unlock_bh(&pdev->txq_log_spinlock);
    /*
     * In theory, this should use mutex to guard against the offset
     * being changed while in use, but since this is just for debugging,
     * don't bother.
     */
    VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_ERROR,
        "Current target credit: %d",
        adf_os_atomic_read(&pdev->target_tx_credit));
    VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_ERROR,
        "Tx queue log:");
    VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_ERROR,
        "      : Frames  Bytes  TID  PEER");

    while (unwrap || offset != pdev->txq_log.offset) {
        int delta = ol_tx_queue_log_record_display(pdev, offset);
        if (delta == 0) {
            return; /* error */
        }
        if (delta < 0) {
            unwrap = 0;
        }
        offset += delta;
    }
}

void
ol_tx_queue_log_enqueue(
    struct ol_txrx_pdev_t *pdev,
    struct ol_txrx_msdu_info_t *msdu_info,
    int frms, int bytes)
{
    int tid;
    u_int16_t peer_id = msdu_info->htt.info.peer_id;
    struct ol_tx_log_queue_add_t *log_elem;
    tid = msdu_info->htt.info.ext_tid;

    adf_os_spin_lock_bh(&pdev->txq_log_spinlock);
    log_elem = ol_tx_queue_log_alloc(pdev, ol_tx_log_entry_type_enqueue, 0);
    if (!log_elem) {
        adf_os_spin_unlock_bh(&pdev->txq_log_spinlock);
        return;
    }

    log_elem->num_frms = frms;
    log_elem->num_bytes = bytes;
    log_elem->peer_id = peer_id;
    log_elem->tid = tid;
    adf_os_spin_unlock_bh(&pdev->txq_log_spinlock);
}

void
ol_tx_queue_log_dequeue(
    struct ol_txrx_pdev_t *pdev,
    struct ol_tx_frms_queue_t *txq,
    int frms, int bytes)
{
    int ext_tid;
    u_int16_t peer_id;
    struct ol_tx_log_queue_add_t *log_elem;

    ext_tid = txq->ext_tid;
    adf_os_spin_lock_bh(&pdev->txq_log_spinlock);
    log_elem = ol_tx_queue_log_alloc(pdev, ol_tx_log_entry_type_dequeue, 0);
    if (!log_elem) {
        adf_os_spin_unlock_bh(&pdev->txq_log_spinlock);
        return;
    }

    if (ext_tid < OL_TX_NUM_TIDS) {
        struct ol_txrx_peer_t *peer;
        struct ol_tx_frms_queue_t *txq_base;

        txq_base = txq - ext_tid;
        peer = container_of(txq_base, struct ol_txrx_peer_t, txqs[0]);
        peer_id = peer->peer_ids[0];
    } else {
        peer_id = ~0;
    }

    log_elem->num_frms = frms;
    log_elem->num_bytes = bytes;
    log_elem->peer_id = peer_id;
    log_elem->tid = ext_tid;
    adf_os_spin_unlock_bh(&pdev->txq_log_spinlock);
}

void
ol_tx_queue_log_free(
    struct ol_txrx_pdev_t *pdev,
    struct ol_tx_frms_queue_t *txq,
    int tid, int frms, int bytes, bool is_peer_txq)
{
    u_int16_t peer_id;
    struct ol_tx_log_queue_add_t *log_elem;

    adf_os_spin_lock_bh(&pdev->txq_log_spinlock);
    log_elem = ol_tx_queue_log_alloc(pdev, ol_tx_log_entry_type_queue_free, 0);
    if (!log_elem) {
        adf_os_spin_unlock_bh(&pdev->txq_log_spinlock);
        return;
    }

    if ((tid < OL_TX_NUM_TIDS) && is_peer_txq) {
        struct ol_txrx_peer_t *peer;
        struct ol_tx_frms_queue_t *txq_base;

        txq_base = txq - tid;
        peer = container_of(txq_base, struct ol_txrx_peer_t, txqs[0]);
        peer_id = peer->peer_ids[0];
    } else {
        peer_id = ~0;
    }

    log_elem->num_frms = frms;
    log_elem->num_bytes = bytes;
    log_elem->peer_id = peer_id;
    log_elem->tid = tid;
    adf_os_spin_unlock_bh(&pdev->txq_log_spinlock);
}

void
ol_tx_queue_log_sched(
    struct ol_txrx_pdev_t *pdev,
    int credit,
    int *num_cats,
    u_int32_t **active_bitmap,
    u_int8_t  **data)
{
    int data_size;
    struct ol_tx_log_queue_state_var_sz_t *log_elem;

    data_size = sizeof(u_int32_t) /* bytes */ + sizeof(u_int16_t) /* frms */;
    data_size *= *num_cats;

    adf_os_spin_lock_bh(&pdev->txq_log_spinlock);
    log_elem = ol_tx_queue_log_alloc(
        pdev, ol_tx_log_entry_type_queue_state, data_size);
    if (!log_elem) {
        *num_cats = 0;
        adf_os_spin_unlock_bh(&pdev->txq_log_spinlock);
        return;
    }
    log_elem->num_cats_active = *num_cats;
    log_elem->active_bitmap = 0;
    log_elem->credit = credit;

    *active_bitmap = &log_elem->active_bitmap;
    *data = &log_elem->data[0];
    adf_os_spin_unlock_bh(&pdev->txq_log_spinlock);
}

void
ol_tx_queue_log_clear(struct ol_txrx_pdev_t *pdev)
{
    adf_os_spin_lock_bh(&pdev->txq_log_spinlock);
    adf_os_mem_zero(&pdev->txq_log, sizeof(pdev->txq_log));
    pdev->txq_log.size = OL_TXQ_LOG_SIZE;
    pdev->txq_log.oldest_record_offset = 0;
    pdev->txq_log.offset = 0;
    pdev->txq_log.allow_wrap = 1;
    pdev->txq_log.wrapped = 0;
    adf_os_spin_unlock_bh(&pdev->txq_log_spinlock);
}
#endif /* defined(DEBUG_HL_LOGGING) */

/*--- queue state printouts -------------------------------------------------*/

#if TXRX_DEBUG_LEVEL > 5

void
ol_tx_queue_display(struct ol_tx_frms_queue_t *txq, int indent)
{
    char *state;

    state = (txq->flag == ol_tx_queue_active) ? "active" : "paused";
    VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO_LOW,
        "%*stxq %pK (%s): %d frms, %d bytes\n",
        indent, " ", txq, state, txq->frms, txq->bytes);
}

void
ol_tx_queues_display(struct ol_txrx_pdev_t *pdev)
{
    struct ol_txrx_vdev_t *vdev;

    VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO_LOW,
        "pdev %pK tx queues:\n", pdev);
    TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) {
        struct ol_txrx_peer_t *peer;
        int i;
        for (i = 0; i < ARRAY_LEN(vdev->txqs); i++) {
            if (vdev->txqs[i].frms == 0) {
                continue;
            }
            VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO_LOW,
                "  vdev %d (%pK), txq %d\n", vdev->vdev_id, vdev, i);
            ol_tx_queue_display(&vdev->txqs[i], 4);
        }
        TAILQ_FOREACH(peer, &vdev->peer_list, peer_list_elem) {
            for (i = 0; i < ARRAY_LEN(peer->txqs); i++) {
                if (peer->txqs[i].frms == 0) {
                    continue;
                }
                VOS_TRACE(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_INFO_LOW,
                    "    peer %d (%pK), txq %d\n",
                    peer->peer_ids[0], vdev, i);
                ol_tx_queue_display(&peer->txqs[i], 6);
            }
        }
    }
}

#endif

#endif /* defined(CONFIG_HL_SUPPORT) */

#ifdef FEATURE_HL_GROUP_CREDIT_FLOW_CONTROL
static a_bool_t
ol_tx_vdev_has_tx_queue_group(
    struct ol_tx_queue_group_t* group,
    u_int8_t vdev_id)
{
    u_int16_t vdev_bitmap;
    vdev_bitmap = OL_TXQ_GROUP_VDEV_ID_MASK_GET(group->membership);
    if (OL_TXQ_GROUP_VDEV_ID_BIT_MASK_GET(vdev_bitmap, vdev_id)) {
        return A_TRUE;
    }
    return A_FALSE;
}

static a_bool_t
ol_tx_ac_has_tx_queue_group(
    struct ol_tx_queue_group_t* group,
    u_int8_t ac)
{
    u_int16_t ac_bitmap;
    ac_bitmap = OL_TXQ_GROUP_AC_MASK_GET(group->membership);
    if (OL_TXQ_GROUP_AC_BIT_MASK_GET(ac_bitmap, ac)) {
        return A_TRUE;
    }
    return A_FALSE;
}

u_int32_t ol_tx_txq_group_credit_limit(
    struct ol_txrx_pdev_t *pdev,
    struct ol_tx_frms_queue_t *txq,
    u_int32_t credit)
{
    u_int8_t i;
    int updated_credit = credit;
    /*
     * If this tx queue belongs to a group, check whether the group's
     * credit limit is more stringent than the global credit limit.
     */
    for (i = 0; i < OL_TX_MAX_GROUPS_PER_QUEUE; i++) {
        if (txq->group_ptrs[i]) {
            int group_credit;
            group_credit = adf_os_atomic_read(&txq->group_ptrs[i]->credit);
            updated_credit = MIN(updated_credit, group_credit);
        }
    }

    credit = (updated_credit < 0) ? 0 : updated_credit;

    return credit;
}

void ol_tx_txq_group_credit_update(
    struct ol_txrx_pdev_t *pdev,
    struct ol_tx_frms_queue_t *txq,
    int32_t credit,
    u_int8_t absolute)
{
    u_int8_t i;
    /*
     * If this tx queue belongs to a group then
     * update group credit
     */
    for (i = 0; i < OL_TX_MAX_GROUPS_PER_QUEUE; i++) {
        if (txq->group_ptrs[i]) {
            ol_txrx_update_group_credit(txq->group_ptrs[i], credit, absolute);
        }
    }
    OL_TX_UPDATE_GROUP_CREDIT_STATS(pdev);
}

void
ol_tx_set_vdev_group_ptr(
    ol_txrx_pdev_handle pdev,
    u_int8_t vdev_id,
    struct ol_tx_queue_group_t *grp_ptr)
{
    struct ol_txrx_vdev_t *vdev = NULL;
    struct ol_txrx_peer_t *peer = NULL;

    TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) {
        if (vdev->vdev_id == vdev_id) {
            u_int8_t i, j;
            /* update vdev queues group pointers */
            for (i = 0; i < OL_TX_VDEV_NUM_QUEUES; i++) {
                for (j = 0; j < OL_TX_MAX_GROUPS_PER_QUEUE; j++) {
                    vdev->txqs[i].group_ptrs[j] = grp_ptr;
                }
            }
            adf_os_spin_lock_bh(&pdev->peer_ref_mutex);
            /* Update peer queue group pointers */
            TAILQ_FOREACH(peer, &vdev->peer_list, peer_list_elem) {
                for (i = 0; i < OL_TX_NUM_TIDS; i++) {
                    for (j = 0; j < OL_TX_MAX_GROUPS_PER_QUEUE; j++) {
                        peer->txqs[i].group_ptrs[j] = grp_ptr;
                    }
                }
            }
            adf_os_spin_unlock_bh(&pdev->peer_ref_mutex);
            break;
        }
    }
}

void
ol_tx_txq_set_group_ptr(
    struct ol_tx_frms_queue_t *txq,
    struct ol_tx_queue_group_t *grp_ptr)
{
    u_int8_t i;
    for (i = 0; i < OL_TX_MAX_GROUPS_PER_QUEUE; i++) {
        txq->group_ptrs[i] = grp_ptr;
    }
}

void
ol_tx_set_peer_group_ptr(
    ol_txrx_pdev_handle pdev,
    struct ol_txrx_peer_t *peer,
    u_int8_t vdev_id,
    u_int8_t tid)
{
    u_int8_t i, j = 0;
    struct ol_tx_queue_group_t *group = NULL;

    for (i = 0; i < OL_TX_MAX_GROUPS_PER_QUEUE; i++) {
        peer->txqs[tid].group_ptrs[i] = NULL;
    }
    for (i = 0; i < OL_TX_MAX_TXQ_GROUPS; i++) {
        group = &pdev->txq_grps[i];
        if (ol_tx_vdev_has_tx_queue_group(group, vdev_id)) {
            if (tid < OL_TX_NUM_QOS_TIDS) {
                if (ol_tx_ac_has_tx_queue_group(
                    group, TXRX_TID_TO_WMM_AC(tid))) {
                    peer->txqs[tid].group_ptrs[j] = group;
                    j++;
                }
            } else {
                peer->txqs[tid].group_ptrs[j] = group;
                j++;
            }
        }
        if (j >= OL_TX_MAX_GROUPS_PER_QUEUE) {
            break;
        }
    }
}

u_int32_t ol_tx_get_max_tx_groups_supported(struct ol_txrx_pdev_t *pdev)
{
#ifdef HIF_SDIO
    return OL_TX_MAX_TXQ_GROUPS;
#else
    return 0;
#endif
}
#endif
