10aeed3e9SJustin Hibbits /******************************************************************************
20aeed3e9SJustin Hibbits 
30aeed3e9SJustin Hibbits  � 1995-2003, 2004, 2005-2011 Freescale Semiconductor, Inc.
40aeed3e9SJustin Hibbits  All rights reserved.
50aeed3e9SJustin Hibbits 
60aeed3e9SJustin Hibbits  This is proprietary source code of Freescale Semiconductor Inc.,
70aeed3e9SJustin Hibbits  and its use is subject to the NetComm Device Drivers EULA.
80aeed3e9SJustin Hibbits  The copyright notice above does not evidence any actual or intended
90aeed3e9SJustin Hibbits  publication of such source code.
100aeed3e9SJustin Hibbits 
110aeed3e9SJustin Hibbits  ALTERNATIVELY, redistribution and use in source and binary forms, with
120aeed3e9SJustin Hibbits  or without modification, are permitted provided that the following
130aeed3e9SJustin Hibbits  conditions are met:
140aeed3e9SJustin Hibbits      * Redistributions of source code must retain the above copyright
150aeed3e9SJustin Hibbits        notice, this list of conditions and the following disclaimer.
160aeed3e9SJustin Hibbits      * Redistributions in binary form must reproduce the above copyright
170aeed3e9SJustin Hibbits        notice, this list of conditions and the following disclaimer in the
180aeed3e9SJustin Hibbits        documentation and/or other materials provided with the distribution.
190aeed3e9SJustin Hibbits      * Neither the name of Freescale Semiconductor nor the
200aeed3e9SJustin Hibbits        names of its contributors may be used to endorse or promote products
210aeed3e9SJustin Hibbits        derived from this software without specific prior written permission.
220aeed3e9SJustin Hibbits 
230aeed3e9SJustin Hibbits  THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
240aeed3e9SJustin Hibbits  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
250aeed3e9SJustin Hibbits  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
260aeed3e9SJustin Hibbits  DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
270aeed3e9SJustin Hibbits  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
280aeed3e9SJustin Hibbits  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
290aeed3e9SJustin Hibbits  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
300aeed3e9SJustin Hibbits  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
310aeed3e9SJustin Hibbits  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
320aeed3e9SJustin Hibbits  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
330aeed3e9SJustin Hibbits  *
340aeed3e9SJustin Hibbits 
350aeed3e9SJustin Hibbits  **************************************************************************/
360aeed3e9SJustin Hibbits /******************************************************************************
370aeed3e9SJustin Hibbits  @File          qm.c
380aeed3e9SJustin Hibbits 
390aeed3e9SJustin Hibbits  @Description   QM & Portal implementation
400aeed3e9SJustin Hibbits *//***************************************************************************/
41852ba100SJustin Hibbits #include <sys/cdefs.h>
42852ba100SJustin Hibbits #include <sys/types.h>
43852ba100SJustin Hibbits #include <machine/atomic.h>
44852ba100SJustin Hibbits 
450aeed3e9SJustin Hibbits #include "error_ext.h"
460aeed3e9SJustin Hibbits #include "std_ext.h"
470aeed3e9SJustin Hibbits #include "string_ext.h"
480aeed3e9SJustin Hibbits #include "mm_ext.h"
490aeed3e9SJustin Hibbits #include "qm.h"
500aeed3e9SJustin Hibbits #include "qman_low.h"
510aeed3e9SJustin Hibbits 
52852ba100SJustin Hibbits #include <machine/vmparam.h>
530aeed3e9SJustin Hibbits 
540aeed3e9SJustin Hibbits /****************************************/
550aeed3e9SJustin Hibbits /*       static functions               */
560aeed3e9SJustin Hibbits /****************************************/
570aeed3e9SJustin Hibbits 
580aeed3e9SJustin Hibbits #define SLOW_POLL_IDLE   1000
590aeed3e9SJustin Hibbits #define SLOW_POLL_BUSY   10
600aeed3e9SJustin Hibbits 
61852ba100SJustin Hibbits /*
62852ba100SJustin Hibbits  * Context entries are 32-bit.  The qman driver uses the pointer to the queue as
63852ba100SJustin Hibbits  * its context, and the pointer is 64-byte aligned, per the XX_MallocSmart()
64852ba100SJustin Hibbits  * call.  Take advantage of this fact to shove a 64-bit kernel pointer into a
65852ba100SJustin Hibbits  * 32-bit context integer, and back.
66852ba100SJustin Hibbits  *
67852ba100SJustin Hibbits  * XXX: This depends on the fact that VM_MAX_KERNEL_ADDRESS is less than 38-bit
68852ba100SJustin Hibbits  * count from VM_MIN_KERNEL_ADDRESS.  If this ever changes, this needs to be
69852ba100SJustin Hibbits  * updated.
70852ba100SJustin Hibbits  */
71852ba100SJustin Hibbits CTASSERT((VM_MAX_KERNEL_ADDRESS - VM_MIN_KERNEL_ADDRESS) < (1ULL << 35));
72852ba100SJustin Hibbits static inline uint32_t
aligned_int_from_ptr(const void * p)73852ba100SJustin Hibbits aligned_int_from_ptr(const void *p)
74852ba100SJustin Hibbits {
75852ba100SJustin Hibbits 	uintptr_t ctx;
76852ba100SJustin Hibbits 
77852ba100SJustin Hibbits 	ctx = (uintptr_t)p;
78852ba100SJustin Hibbits 	KASSERT(ctx >= VM_MIN_KERNEL_ADDRESS, ("%p is too low!\n", p));
79852ba100SJustin Hibbits 	ctx -= VM_MIN_KERNEL_ADDRESS;
80852ba100SJustin Hibbits 	KASSERT((ctx & 0x07) == 0, ("Pointer %p is not 8-byte aligned!\n", p));
81a32b5435SJustin Hibbits 
82852ba100SJustin Hibbits 	return (ctx >> 3);
83852ba100SJustin Hibbits }
84852ba100SJustin Hibbits 
85852ba100SJustin Hibbits static inline void *
ptr_from_aligned_int(uint32_t ctx)86852ba100SJustin Hibbits ptr_from_aligned_int(uint32_t ctx)
87852ba100SJustin Hibbits {
88852ba100SJustin Hibbits 	uintptr_t p;
89852ba100SJustin Hibbits 
90a32b5435SJustin Hibbits 	p = ctx;
91a32b5435SJustin Hibbits 	p = VM_MIN_KERNEL_ADDRESS + (p << 3);
92852ba100SJustin Hibbits 
93852ba100SJustin Hibbits 	return ((void *)p);
94852ba100SJustin Hibbits }
950aeed3e9SJustin Hibbits 
qman_volatile_dequeue(t_QmPortal * p_QmPortal,struct qman_fq * p_Fq,uint32_t vdqcr)960aeed3e9SJustin Hibbits static t_Error qman_volatile_dequeue(t_QmPortal     *p_QmPortal,
970aeed3e9SJustin Hibbits                                      struct qman_fq *p_Fq,
980aeed3e9SJustin Hibbits                                      uint32_t       vdqcr)
990aeed3e9SJustin Hibbits {
1000aeed3e9SJustin Hibbits     ASSERT_COND((p_Fq->state == qman_fq_state_parked) ||
1010aeed3e9SJustin Hibbits                 (p_Fq->state == qman_fq_state_retired));
1020aeed3e9SJustin Hibbits     ASSERT_COND(!(vdqcr & QM_VDQCR_FQID_MASK));
1030aeed3e9SJustin Hibbits     ASSERT_COND(!(p_Fq->flags & QMAN_FQ_STATE_VDQCR));
1040aeed3e9SJustin Hibbits 
1050aeed3e9SJustin Hibbits     vdqcr = (vdqcr & ~QM_VDQCR_FQID_MASK) | p_Fq->fqid;
1060aeed3e9SJustin Hibbits     NCSW_PLOCK(p_QmPortal);
1070aeed3e9SJustin Hibbits     FQLOCK(p_Fq);
1080aeed3e9SJustin Hibbits     p_Fq->flags |= QMAN_FQ_STATE_VDQCR;
1090aeed3e9SJustin Hibbits     qm_dqrr_vdqcr_set(p_QmPortal->p_LowQmPortal, vdqcr);
1100aeed3e9SJustin Hibbits     FQUNLOCK(p_Fq);
1110aeed3e9SJustin Hibbits     PUNLOCK(p_QmPortal);
1120aeed3e9SJustin Hibbits 
1130aeed3e9SJustin Hibbits     return E_OK;
1140aeed3e9SJustin Hibbits }
1150aeed3e9SJustin Hibbits 
mcr_result_str(uint8_t result)1160aeed3e9SJustin Hibbits static const char *mcr_result_str(uint8_t result)
1170aeed3e9SJustin Hibbits {
1180aeed3e9SJustin Hibbits     switch (result) {
1190aeed3e9SJustin Hibbits     case QM_MCR_RESULT_NULL:
1200aeed3e9SJustin Hibbits         return "QM_MCR_RESULT_NULL";
1210aeed3e9SJustin Hibbits     case QM_MCR_RESULT_OK:
1220aeed3e9SJustin Hibbits         return "QM_MCR_RESULT_OK";
1230aeed3e9SJustin Hibbits     case QM_MCR_RESULT_ERR_FQID:
1240aeed3e9SJustin Hibbits         return "QM_MCR_RESULT_ERR_FQID";
1250aeed3e9SJustin Hibbits     case QM_MCR_RESULT_ERR_FQSTATE:
1260aeed3e9SJustin Hibbits         return "QM_MCR_RESULT_ERR_FQSTATE";
1270aeed3e9SJustin Hibbits     case QM_MCR_RESULT_ERR_NOTEMPTY:
1280aeed3e9SJustin Hibbits         return "QM_MCR_RESULT_ERR_NOTEMPTY";
1290aeed3e9SJustin Hibbits     case QM_MCR_RESULT_PENDING:
1300aeed3e9SJustin Hibbits         return "QM_MCR_RESULT_PENDING";
1310aeed3e9SJustin Hibbits     }
1320aeed3e9SJustin Hibbits     return "<unknown MCR result>";
1330aeed3e9SJustin Hibbits }
1340aeed3e9SJustin Hibbits 
qman_create_fq(t_QmPortal * p_QmPortal,uint32_t fqid,uint32_t flags,struct qman_fq * p_Fq)1350aeed3e9SJustin Hibbits static t_Error qman_create_fq(t_QmPortal        *p_QmPortal,
1360aeed3e9SJustin Hibbits                               uint32_t          fqid,
1370aeed3e9SJustin Hibbits                               uint32_t          flags,
1380aeed3e9SJustin Hibbits                               struct qman_fq    *p_Fq)
1390aeed3e9SJustin Hibbits {
1400aeed3e9SJustin Hibbits     struct qm_fqd fqd;
1410aeed3e9SJustin Hibbits     struct qm_mcr_queryfq_np np;
1420aeed3e9SJustin Hibbits     struct qm_mc_command *p_Mcc;
1430aeed3e9SJustin Hibbits     struct qm_mc_result *p_Mcr;
1440aeed3e9SJustin Hibbits 
1450aeed3e9SJustin Hibbits     p_Fq->fqid = fqid;
1460aeed3e9SJustin Hibbits     p_Fq->flags = flags;
1470aeed3e9SJustin Hibbits     p_Fq->state = qman_fq_state_oos;
1480aeed3e9SJustin Hibbits     p_Fq->cgr_groupid = 0;
1490aeed3e9SJustin Hibbits     if (!(flags & QMAN_FQ_FLAG_RECOVER) ||
1500aeed3e9SJustin Hibbits             (flags & QMAN_FQ_FLAG_NO_MODIFY))
1510aeed3e9SJustin Hibbits         return E_OK;
1520aeed3e9SJustin Hibbits     /* Everything else is RECOVER support */
1530aeed3e9SJustin Hibbits     NCSW_PLOCK(p_QmPortal);
1540aeed3e9SJustin Hibbits     p_Mcc = qm_mc_start(p_QmPortal->p_LowQmPortal);
1550aeed3e9SJustin Hibbits     p_Mcc->queryfq.fqid = fqid;
1560aeed3e9SJustin Hibbits     qm_mc_commit(p_QmPortal->p_LowQmPortal, QM_MCC_VERB_QUERYFQ);
1570aeed3e9SJustin Hibbits     while (!(p_Mcr = qm_mc_result(p_QmPortal->p_LowQmPortal))) ;
1580aeed3e9SJustin Hibbits     ASSERT_COND((p_Mcr->verb & QM_MCR_VERB_MASK) == QM_MCC_VERB_QUERYFQ);
1590aeed3e9SJustin Hibbits     if (p_Mcr->result != QM_MCR_RESULT_OK) {
1600aeed3e9SJustin Hibbits         PUNLOCK(p_QmPortal);
1610aeed3e9SJustin Hibbits         RETURN_ERROR(MAJOR, E_INVALID_STATE, ("QUERYFQ failed: %s", mcr_result_str(p_Mcr->result)));
1620aeed3e9SJustin Hibbits     }
1630aeed3e9SJustin Hibbits     fqd = p_Mcr->queryfq.fqd;
1640aeed3e9SJustin Hibbits     p_Mcc = qm_mc_start(p_QmPortal->p_LowQmPortal);
1650aeed3e9SJustin Hibbits     p_Mcc->queryfq_np.fqid = fqid;
1660aeed3e9SJustin Hibbits     qm_mc_commit(p_QmPortal->p_LowQmPortal, QM_MCC_VERB_QUERYFQ_NP);
1670aeed3e9SJustin Hibbits     while (!(p_Mcr = qm_mc_result(p_QmPortal->p_LowQmPortal))) ;
1680aeed3e9SJustin Hibbits     ASSERT_COND((p_Mcr->verb & QM_MCR_VERB_MASK) == QM_MCC_VERB_QUERYFQ_NP);
1690aeed3e9SJustin Hibbits     if (p_Mcr->result != QM_MCR_RESULT_OK) {
1700aeed3e9SJustin Hibbits         PUNLOCK(p_QmPortal);
1710aeed3e9SJustin Hibbits         RETURN_ERROR(MAJOR, E_INVALID_STATE, ("UERYFQ_NP failed: %s", mcr_result_str(p_Mcr->result)));
1720aeed3e9SJustin Hibbits     }
1730aeed3e9SJustin Hibbits     np = p_Mcr->queryfq_np;
1740aeed3e9SJustin Hibbits     /* Phew, have queryfq and queryfq_np results, stitch together
1750aeed3e9SJustin Hibbits      * the FQ object from those. */
1760aeed3e9SJustin Hibbits     p_Fq->cgr_groupid = fqd.cgid;
1770aeed3e9SJustin Hibbits     switch (np.state & QM_MCR_NP_STATE_MASK) {
1780aeed3e9SJustin Hibbits     case QM_MCR_NP_STATE_OOS:
1790aeed3e9SJustin Hibbits         break;
1800aeed3e9SJustin Hibbits     case QM_MCR_NP_STATE_RETIRED:
1810aeed3e9SJustin Hibbits         p_Fq->state = qman_fq_state_retired;
1820aeed3e9SJustin Hibbits         if (np.frm_cnt)
1830aeed3e9SJustin Hibbits             p_Fq->flags |= QMAN_FQ_STATE_NE;
1840aeed3e9SJustin Hibbits         break;
1850aeed3e9SJustin Hibbits     case QM_MCR_NP_STATE_TEN_SCHED:
1860aeed3e9SJustin Hibbits     case QM_MCR_NP_STATE_TRU_SCHED:
1870aeed3e9SJustin Hibbits     case QM_MCR_NP_STATE_ACTIVE:
1880aeed3e9SJustin Hibbits         p_Fq->state = qman_fq_state_sched;
1890aeed3e9SJustin Hibbits         if (np.state & QM_MCR_NP_STATE_R)
1900aeed3e9SJustin Hibbits             p_Fq->flags |= QMAN_FQ_STATE_CHANGING;
1910aeed3e9SJustin Hibbits         break;
1920aeed3e9SJustin Hibbits     case QM_MCR_NP_STATE_PARKED:
1930aeed3e9SJustin Hibbits         p_Fq->state = qman_fq_state_parked;
1940aeed3e9SJustin Hibbits         break;
1950aeed3e9SJustin Hibbits     default:
1960aeed3e9SJustin Hibbits         ASSERT_COND(FALSE);
1970aeed3e9SJustin Hibbits     }
1980aeed3e9SJustin Hibbits     if (fqd.fq_ctrl & QM_FQCTRL_CGE)
1990aeed3e9SJustin Hibbits         p_Fq->state |= QMAN_FQ_STATE_CGR_EN;
2000aeed3e9SJustin Hibbits     PUNLOCK(p_QmPortal);
2010aeed3e9SJustin Hibbits 
2020aeed3e9SJustin Hibbits     return E_OK;
2030aeed3e9SJustin Hibbits }
2040aeed3e9SJustin Hibbits 
qman_destroy_fq(struct qman_fq * p_Fq,uint32_t flags)2050aeed3e9SJustin Hibbits static void qman_destroy_fq(struct qman_fq *p_Fq, uint32_t flags)
2060aeed3e9SJustin Hibbits {
2070aeed3e9SJustin Hibbits     /* We don't need to lock the FQ as it is a pre-condition that the FQ be
2080aeed3e9SJustin Hibbits      * quiesced. Instead, run some checks. */
2090aeed3e9SJustin Hibbits     UNUSED(flags);
2100aeed3e9SJustin Hibbits     switch (p_Fq->state) {
2110aeed3e9SJustin Hibbits     case qman_fq_state_parked:
2120aeed3e9SJustin Hibbits         ASSERT_COND(flags & QMAN_FQ_DESTROY_PARKED);
2130aeed3e9SJustin Hibbits     case qman_fq_state_oos:
2140aeed3e9SJustin Hibbits         return;
2150aeed3e9SJustin Hibbits     default:
2160aeed3e9SJustin Hibbits         break;
2170aeed3e9SJustin Hibbits     }
2180aeed3e9SJustin Hibbits     ASSERT_COND(FALSE);
2190aeed3e9SJustin Hibbits }
2200aeed3e9SJustin Hibbits 
qman_init_fq(t_QmPortal * p_QmPortal,struct qman_fq * p_Fq,uint32_t flags,struct qm_mcc_initfq * p_Opts)2210aeed3e9SJustin Hibbits static t_Error qman_init_fq(t_QmPortal          *p_QmPortal,
2220aeed3e9SJustin Hibbits                             struct qman_fq      *p_Fq,
2230aeed3e9SJustin Hibbits                             uint32_t            flags,
2240aeed3e9SJustin Hibbits                             struct qm_mcc_initfq *p_Opts)
2250aeed3e9SJustin Hibbits {
2260aeed3e9SJustin Hibbits     struct qm_mc_command    *p_Mcc;
2270aeed3e9SJustin Hibbits     struct qm_mc_result     *p_Mcr;
2280aeed3e9SJustin Hibbits     uint8_t res, myverb = (uint8_t)((flags & QMAN_INITFQ_FLAG_SCHED) ?
2290aeed3e9SJustin Hibbits         QM_MCC_VERB_INITFQ_SCHED : QM_MCC_VERB_INITFQ_PARKED);
2300aeed3e9SJustin Hibbits 
2310aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR((p_Fq->state == qman_fq_state_oos) ||
2320aeed3e9SJustin Hibbits                               (p_Fq->state == qman_fq_state_parked),
2330aeed3e9SJustin Hibbits                               E_INVALID_STATE);
2340aeed3e9SJustin Hibbits 
2350aeed3e9SJustin Hibbits     if (p_Fq->flags & QMAN_FQ_FLAG_NO_MODIFY)
2360aeed3e9SJustin Hibbits         return ERROR_CODE(E_INVALID_VALUE);
2370aeed3e9SJustin Hibbits     /* Issue an INITFQ_[PARKED|SCHED] management command */
2380aeed3e9SJustin Hibbits     NCSW_PLOCK(p_QmPortal);
2390aeed3e9SJustin Hibbits     FQLOCK(p_Fq);
2400aeed3e9SJustin Hibbits     if ((p_Fq->flags & QMAN_FQ_STATE_CHANGING) ||
2410aeed3e9SJustin Hibbits             ((p_Fq->state != qman_fq_state_oos) &&
2420aeed3e9SJustin Hibbits                 (p_Fq->state != qman_fq_state_parked))) {
2430aeed3e9SJustin Hibbits         FQUNLOCK(p_Fq);
2440aeed3e9SJustin Hibbits         PUNLOCK(p_QmPortal);
2450aeed3e9SJustin Hibbits         return ERROR_CODE(E_BUSY);
2460aeed3e9SJustin Hibbits     }
2470aeed3e9SJustin Hibbits     p_Mcc = qm_mc_start(p_QmPortal->p_LowQmPortal);
2480aeed3e9SJustin Hibbits     Mem2IOCpy32((void*)&p_Mcc->initfq, p_Opts, sizeof(struct qm_mcc_initfq));
2490aeed3e9SJustin Hibbits     qm_mc_commit(p_QmPortal->p_LowQmPortal, myverb);
2500aeed3e9SJustin Hibbits     while (!(p_Mcr = qm_mc_result(p_QmPortal->p_LowQmPortal))) ;
2510aeed3e9SJustin Hibbits     ASSERT_COND((p_Mcr->verb & QM_MCR_VERB_MASK) == myverb);
2520aeed3e9SJustin Hibbits     res = p_Mcr->result;
2530aeed3e9SJustin Hibbits     if (res != QM_MCR_RESULT_OK) {
2540aeed3e9SJustin Hibbits         FQUNLOCK(p_Fq);
2550aeed3e9SJustin Hibbits         PUNLOCK(p_QmPortal);
2560aeed3e9SJustin Hibbits         RETURN_ERROR(MINOR, E_INVALID_STATE,("INITFQ failed: %s", mcr_result_str(res)));
2570aeed3e9SJustin Hibbits     }
2580aeed3e9SJustin Hibbits 
2590aeed3e9SJustin Hibbits     if (p_Mcc->initfq.we_mask & QM_INITFQ_WE_FQCTRL) {
2600aeed3e9SJustin Hibbits         if (p_Mcc->initfq.fqd.fq_ctrl & QM_FQCTRL_CGE)
2610aeed3e9SJustin Hibbits             p_Fq->flags |= QMAN_FQ_STATE_CGR_EN;
2620aeed3e9SJustin Hibbits         else
2630aeed3e9SJustin Hibbits             p_Fq->flags &= ~QMAN_FQ_STATE_CGR_EN;
2640aeed3e9SJustin Hibbits     }
2650aeed3e9SJustin Hibbits     if (p_Mcc->initfq.we_mask & QM_INITFQ_WE_CGID)
2660aeed3e9SJustin Hibbits         p_Fq->cgr_groupid = p_Mcc->initfq.fqd.cgid;
2670aeed3e9SJustin Hibbits     p_Fq->state = (flags & QMAN_INITFQ_FLAG_SCHED) ?
2680aeed3e9SJustin Hibbits             qman_fq_state_sched : qman_fq_state_parked;
2690aeed3e9SJustin Hibbits     FQUNLOCK(p_Fq);
2700aeed3e9SJustin Hibbits     PUNLOCK(p_QmPortal);
2710aeed3e9SJustin Hibbits     return E_OK;
2720aeed3e9SJustin Hibbits }
2730aeed3e9SJustin Hibbits 
qman_retire_fq(t_QmPortal * p_QmPortal,struct qman_fq * p_Fq,uint32_t * p_Flags,bool drain)2740aeed3e9SJustin Hibbits static t_Error qman_retire_fq(t_QmPortal        *p_QmPortal,
2750aeed3e9SJustin Hibbits                               struct qman_fq    *p_Fq,
2760aeed3e9SJustin Hibbits                               uint32_t          *p_Flags,
2770aeed3e9SJustin Hibbits                               bool              drain)
2780aeed3e9SJustin Hibbits {
2790aeed3e9SJustin Hibbits     struct qm_mc_command    *p_Mcc;
2800aeed3e9SJustin Hibbits     struct qm_mc_result     *p_Mcr;
2810aeed3e9SJustin Hibbits     t_Error                 err = E_OK;
2820aeed3e9SJustin Hibbits     uint8_t                 res;
2830aeed3e9SJustin Hibbits 
2840aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR((p_Fq->state == qman_fq_state_parked) ||
2850aeed3e9SJustin Hibbits                               (p_Fq->state == qman_fq_state_sched),
2860aeed3e9SJustin Hibbits                               E_INVALID_STATE);
2870aeed3e9SJustin Hibbits 
2880aeed3e9SJustin Hibbits     if (p_Fq->flags & QMAN_FQ_FLAG_NO_MODIFY)
2890aeed3e9SJustin Hibbits         return E_INVALID_VALUE;
2900aeed3e9SJustin Hibbits     NCSW_PLOCK(p_QmPortal);
2910aeed3e9SJustin Hibbits     FQLOCK(p_Fq);
2920aeed3e9SJustin Hibbits     if ((p_Fq->flags & QMAN_FQ_STATE_CHANGING) ||
2930aeed3e9SJustin Hibbits             (p_Fq->state == qman_fq_state_retired) ||
2940aeed3e9SJustin Hibbits                 (p_Fq->state == qman_fq_state_oos)) {
2950aeed3e9SJustin Hibbits         err = E_BUSY;
2960aeed3e9SJustin Hibbits         goto out;
2970aeed3e9SJustin Hibbits     }
2980aeed3e9SJustin Hibbits     p_Mcc = qm_mc_start(p_QmPortal->p_LowQmPortal);
2990aeed3e9SJustin Hibbits     p_Mcc->alterfq.fqid = p_Fq->fqid;
3000aeed3e9SJustin Hibbits     if (drain)
301852ba100SJustin Hibbits         p_Mcc->alterfq.context_b = aligned_int_from_ptr(p_Fq);
3020aeed3e9SJustin Hibbits     qm_mc_commit(p_QmPortal->p_LowQmPortal,
3030aeed3e9SJustin Hibbits                  (uint8_t)((drain)?QM_MCC_VERB_ALTER_RETIRE_CTXB:QM_MCC_VERB_ALTER_RETIRE));
3040aeed3e9SJustin Hibbits     while (!(p_Mcr = qm_mc_result(p_QmPortal->p_LowQmPortal))) ;
3050aeed3e9SJustin Hibbits     ASSERT_COND((p_Mcr->verb & QM_MCR_VERB_MASK) ==
3060aeed3e9SJustin Hibbits                 (drain)?QM_MCR_VERB_ALTER_RETIRE_CTXB:QM_MCR_VERB_ALTER_RETIRE);
3070aeed3e9SJustin Hibbits     res = p_Mcr->result;
3080aeed3e9SJustin Hibbits     if (res == QM_MCR_RESULT_OK)
3090aeed3e9SJustin Hibbits     {
3100aeed3e9SJustin Hibbits         /* Process 'fq' right away, we'll ignore FQRNI */
3110aeed3e9SJustin Hibbits         if (p_Mcr->alterfq.fqs & QM_MCR_FQS_NOTEMPTY)
3120aeed3e9SJustin Hibbits             p_Fq->flags |= QMAN_FQ_STATE_NE;
3130aeed3e9SJustin Hibbits         if (p_Mcr->alterfq.fqs & QM_MCR_FQS_ORLPRESENT)
3140aeed3e9SJustin Hibbits             p_Fq->flags |= QMAN_FQ_STATE_ORL;
3150aeed3e9SJustin Hibbits         p_Fq->state = qman_fq_state_retired;
3160aeed3e9SJustin Hibbits     }
3170aeed3e9SJustin Hibbits     else if (res == QM_MCR_RESULT_PENDING)
3180aeed3e9SJustin Hibbits         p_Fq->flags |= QMAN_FQ_STATE_CHANGING;
3190aeed3e9SJustin Hibbits     else {
3200aeed3e9SJustin Hibbits         XX_Print("ALTER_RETIRE failed: %s\n",
3210aeed3e9SJustin Hibbits                 mcr_result_str(res));
3220aeed3e9SJustin Hibbits         err = E_INVALID_STATE;
3230aeed3e9SJustin Hibbits     }
3240aeed3e9SJustin Hibbits     if (p_Flags)
3250aeed3e9SJustin Hibbits         *p_Flags = p_Fq->flags;
3260aeed3e9SJustin Hibbits out:
3270aeed3e9SJustin Hibbits     FQUNLOCK(p_Fq);
3280aeed3e9SJustin Hibbits     PUNLOCK(p_QmPortal);
3290aeed3e9SJustin Hibbits     return err;
3300aeed3e9SJustin Hibbits }
3310aeed3e9SJustin Hibbits 
qman_oos_fq(t_QmPortal * p_QmPortal,struct qman_fq * p_Fq)3320aeed3e9SJustin Hibbits static t_Error qman_oos_fq(t_QmPortal *p_QmPortal, struct qman_fq *p_Fq)
3330aeed3e9SJustin Hibbits {
3340aeed3e9SJustin Hibbits     struct qm_mc_command    *p_Mcc;
3350aeed3e9SJustin Hibbits     struct qm_mc_result     *p_Mcr;
3360aeed3e9SJustin Hibbits     uint8_t                 res;
3370aeed3e9SJustin Hibbits 
3380aeed3e9SJustin Hibbits     ASSERT_COND(p_Fq->state == qman_fq_state_retired);
3390aeed3e9SJustin Hibbits     if (p_Fq->flags & QMAN_FQ_FLAG_NO_MODIFY)
3400aeed3e9SJustin Hibbits         return ERROR_CODE(E_INVALID_VALUE);
3410aeed3e9SJustin Hibbits     NCSW_PLOCK(p_QmPortal);
3420aeed3e9SJustin Hibbits     FQLOCK(p_Fq);
3430aeed3e9SJustin Hibbits     if ((p_Fq->flags & QMAN_FQ_STATE_BLOCKOOS) ||
3440aeed3e9SJustin Hibbits             (p_Fq->state != qman_fq_state_retired)) {
3450aeed3e9SJustin Hibbits         FQUNLOCK(p_Fq);
3460aeed3e9SJustin Hibbits         PUNLOCK(p_QmPortal);
3470aeed3e9SJustin Hibbits         return ERROR_CODE(E_BUSY);
3480aeed3e9SJustin Hibbits     }
3490aeed3e9SJustin Hibbits     p_Mcc = qm_mc_start(p_QmPortal->p_LowQmPortal);
3500aeed3e9SJustin Hibbits     p_Mcc->alterfq.fqid = p_Fq->fqid;
3510aeed3e9SJustin Hibbits     qm_mc_commit(p_QmPortal->p_LowQmPortal, QM_MCC_VERB_ALTER_OOS);
3520aeed3e9SJustin Hibbits     while (!(p_Mcr = qm_mc_result(p_QmPortal->p_LowQmPortal))) ;
3530aeed3e9SJustin Hibbits     ASSERT_COND((p_Mcr->verb & QM_MCR_VERB_MASK) == QM_MCR_VERB_ALTER_OOS);
3540aeed3e9SJustin Hibbits     res = p_Mcr->result;
3550aeed3e9SJustin Hibbits     if (res != QM_MCR_RESULT_OK) {
3560aeed3e9SJustin Hibbits         FQUNLOCK(p_Fq);
3570aeed3e9SJustin Hibbits         PUNLOCK(p_QmPortal);
3580aeed3e9SJustin Hibbits         RETURN_ERROR(MINOR, E_INVALID_STATE, ("ALTER_OOS failed: %s\n", mcr_result_str(res)));
3590aeed3e9SJustin Hibbits     }
3600aeed3e9SJustin Hibbits     p_Fq->state = qman_fq_state_oos;
3610aeed3e9SJustin Hibbits 
3620aeed3e9SJustin Hibbits     FQUNLOCK(p_Fq);
3630aeed3e9SJustin Hibbits     PUNLOCK(p_QmPortal);
3640aeed3e9SJustin Hibbits     return E_OK;
3650aeed3e9SJustin Hibbits }
3660aeed3e9SJustin Hibbits 
qman_schedule_fq(t_QmPortal * p_QmPortal,struct qman_fq * p_Fq)3670aeed3e9SJustin Hibbits static t_Error qman_schedule_fq(t_QmPortal *p_QmPortal, struct qman_fq *p_Fq)
3680aeed3e9SJustin Hibbits {
3690aeed3e9SJustin Hibbits     struct qm_mc_command    *p_Mcc;
3700aeed3e9SJustin Hibbits     struct qm_mc_result     *p_Mcr;
3710aeed3e9SJustin Hibbits     uint8_t                 res;
3720aeed3e9SJustin Hibbits 
3730aeed3e9SJustin Hibbits     ASSERT_COND(p_Fq->state == qman_fq_state_parked);
3740aeed3e9SJustin Hibbits     if (p_Fq->flags & QMAN_FQ_FLAG_NO_MODIFY)
3750aeed3e9SJustin Hibbits         return ERROR_CODE(E_INVALID_VALUE);
3760aeed3e9SJustin Hibbits     /* Issue a ALTERFQ_SCHED management command */
3770aeed3e9SJustin Hibbits     NCSW_PLOCK(p_QmPortal);
3780aeed3e9SJustin Hibbits     FQLOCK(p_Fq);
3790aeed3e9SJustin Hibbits     if ((p_Fq->flags & QMAN_FQ_STATE_CHANGING) ||
3800aeed3e9SJustin Hibbits             (p_Fq->state != qman_fq_state_parked)) {
3810aeed3e9SJustin Hibbits         FQUNLOCK(p_Fq);
3820aeed3e9SJustin Hibbits         PUNLOCK(p_QmPortal);
3830aeed3e9SJustin Hibbits         return ERROR_CODE(E_BUSY);
3840aeed3e9SJustin Hibbits     }
3850aeed3e9SJustin Hibbits     p_Mcc = qm_mc_start(p_QmPortal->p_LowQmPortal);
3860aeed3e9SJustin Hibbits     p_Mcc->alterfq.fqid = p_Fq->fqid;
3870aeed3e9SJustin Hibbits     qm_mc_commit(p_QmPortal->p_LowQmPortal, QM_MCC_VERB_ALTER_SCHED);
3880aeed3e9SJustin Hibbits     while (!(p_Mcr = qm_mc_result(p_QmPortal->p_LowQmPortal))) ;
3890aeed3e9SJustin Hibbits     ASSERT_COND((p_Mcr->verb & QM_MCR_VERB_MASK) == QM_MCR_VERB_ALTER_SCHED);
3900aeed3e9SJustin Hibbits     res = p_Mcr->result;
3910aeed3e9SJustin Hibbits     if (res != QM_MCR_RESULT_OK) {
3920aeed3e9SJustin Hibbits         FQUNLOCK(p_Fq);
3930aeed3e9SJustin Hibbits         PUNLOCK(p_QmPortal);
3940aeed3e9SJustin Hibbits         RETURN_ERROR(MINOR, E_INVALID_STATE, ("ALTER_SCHED failed: %s\n", mcr_result_str(res)));
3950aeed3e9SJustin Hibbits     }
3960aeed3e9SJustin Hibbits     p_Fq->state = qman_fq_state_sched;
3970aeed3e9SJustin Hibbits 
3980aeed3e9SJustin Hibbits     FQUNLOCK(p_Fq);
3990aeed3e9SJustin Hibbits     PUNLOCK(p_QmPortal);
4000aeed3e9SJustin Hibbits     return E_OK;
4010aeed3e9SJustin Hibbits }
4020aeed3e9SJustin Hibbits 
4030aeed3e9SJustin Hibbits /* Inline helper to reduce nesting in LoopMessageRing() */
fq_state_change(struct qman_fq * p_Fq,struct qm_mr_entry * p_Msg,uint8_t verb)4040aeed3e9SJustin Hibbits static __inline__ void fq_state_change(struct qman_fq *p_Fq,
4050aeed3e9SJustin Hibbits                                        struct qm_mr_entry *p_Msg,
4060aeed3e9SJustin Hibbits                                        uint8_t verb)
4070aeed3e9SJustin Hibbits {
4080aeed3e9SJustin Hibbits     FQLOCK(p_Fq);
4090aeed3e9SJustin Hibbits     switch(verb) {
4100aeed3e9SJustin Hibbits         case QM_MR_VERB_FQRL:
4110aeed3e9SJustin Hibbits             ASSERT_COND(p_Fq->flags & QMAN_FQ_STATE_ORL);
4120aeed3e9SJustin Hibbits             p_Fq->flags &= ~QMAN_FQ_STATE_ORL;
4130aeed3e9SJustin Hibbits             break;
4140aeed3e9SJustin Hibbits         case QM_MR_VERB_FQRN:
4150aeed3e9SJustin Hibbits             ASSERT_COND((p_Fq->state == qman_fq_state_parked) ||
4160aeed3e9SJustin Hibbits                 (p_Fq->state == qman_fq_state_sched));
4170aeed3e9SJustin Hibbits             ASSERT_COND(p_Fq->flags & QMAN_FQ_STATE_CHANGING);
4180aeed3e9SJustin Hibbits             p_Fq->flags &= ~QMAN_FQ_STATE_CHANGING;
4190aeed3e9SJustin Hibbits             if (p_Msg->fq.fqs & QM_MR_FQS_NOTEMPTY)
4200aeed3e9SJustin Hibbits                 p_Fq->flags |= QMAN_FQ_STATE_NE;
4210aeed3e9SJustin Hibbits             if (p_Msg->fq.fqs & QM_MR_FQS_ORLPRESENT)
4220aeed3e9SJustin Hibbits                 p_Fq->flags |= QMAN_FQ_STATE_ORL;
4230aeed3e9SJustin Hibbits             p_Fq->state = qman_fq_state_retired;
4240aeed3e9SJustin Hibbits             break;
4250aeed3e9SJustin Hibbits         case QM_MR_VERB_FQPN:
4260aeed3e9SJustin Hibbits             ASSERT_COND(p_Fq->state == qman_fq_state_sched);
4270aeed3e9SJustin Hibbits             ASSERT_COND(p_Fq->flags & QMAN_FQ_STATE_CHANGING);
4280aeed3e9SJustin Hibbits             p_Fq->state = qman_fq_state_parked;
4290aeed3e9SJustin Hibbits     }
4300aeed3e9SJustin Hibbits     FQUNLOCK(p_Fq);
4310aeed3e9SJustin Hibbits }
4320aeed3e9SJustin Hibbits 
freeDrainedFq(struct qman_fq * p_Fq)4330aeed3e9SJustin Hibbits static t_Error freeDrainedFq(struct qman_fq *p_Fq)
4340aeed3e9SJustin Hibbits {
4350aeed3e9SJustin Hibbits     t_QmFqr     *p_QmFqr;
4360aeed3e9SJustin Hibbits     uint32_t    i;
4370aeed3e9SJustin Hibbits 
4380aeed3e9SJustin Hibbits     ASSERT_COND(p_Fq);
4390aeed3e9SJustin Hibbits     p_QmFqr = (t_QmFqr *)p_Fq->h_QmFqr;
4400aeed3e9SJustin Hibbits     ASSERT_COND(p_QmFqr);
4410aeed3e9SJustin Hibbits 
4420aeed3e9SJustin Hibbits     ASSERT_COND(!p_QmFqr->p_DrainedFqs[p_Fq->fqidOffset]);
4430aeed3e9SJustin Hibbits     p_QmFqr->p_DrainedFqs[p_Fq->fqidOffset] = TRUE;
4440aeed3e9SJustin Hibbits     p_QmFqr->numOfDrainedFqids++;
4450aeed3e9SJustin Hibbits     if (p_QmFqr->numOfDrainedFqids == p_QmFqr->numOfFqids)
4460aeed3e9SJustin Hibbits     {
4470aeed3e9SJustin Hibbits         for (i=0;i<p_QmFqr->numOfFqids;i++)
4480aeed3e9SJustin Hibbits         {
4490aeed3e9SJustin Hibbits             if ((p_QmFqr->p_Fqs[i]->state == qman_fq_state_retired) &&
4500aeed3e9SJustin Hibbits                     (qman_oos_fq(p_QmFqr->h_QmPortal, p_QmFqr->p_Fqs[i]) != E_OK))
4510aeed3e9SJustin Hibbits                 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("qman_oos_fq() failed!"));
4520aeed3e9SJustin Hibbits             qman_destroy_fq(p_QmFqr->p_Fqs[i], 0);
4530aeed3e9SJustin Hibbits             XX_FreeSmart(p_QmFqr->p_Fqs[i]);
4540aeed3e9SJustin Hibbits         }
4550aeed3e9SJustin Hibbits         XX_Free(p_QmFqr->p_DrainedFqs);
4560aeed3e9SJustin Hibbits         p_QmFqr->p_DrainedFqs = NULL;
4570aeed3e9SJustin Hibbits 
4580aeed3e9SJustin Hibbits         if (p_QmFqr->f_CompletionCB)
4590aeed3e9SJustin Hibbits         {
4600aeed3e9SJustin Hibbits             p_QmFqr->f_CompletionCB(p_QmFqr->h_App, p_QmFqr);
4610aeed3e9SJustin Hibbits             XX_Free(p_QmFqr->p_Fqs);
4620aeed3e9SJustin Hibbits             if (p_QmFqr->fqidBase)
4630aeed3e9SJustin Hibbits                 QmFqidPut(p_QmFqr->h_Qm, p_QmFqr->fqidBase);
4640aeed3e9SJustin Hibbits             XX_Free(p_QmFqr);
4650aeed3e9SJustin Hibbits         }
4660aeed3e9SJustin Hibbits     }
4670aeed3e9SJustin Hibbits 
4680aeed3e9SJustin Hibbits     return E_OK;
4690aeed3e9SJustin Hibbits }
4700aeed3e9SJustin Hibbits 
drainRetiredFq(struct qman_fq * p_Fq)4710aeed3e9SJustin Hibbits static t_Error drainRetiredFq(struct qman_fq *p_Fq)
4720aeed3e9SJustin Hibbits {
4730aeed3e9SJustin Hibbits     t_QmFqr     *p_QmFqr;
4740aeed3e9SJustin Hibbits 
4750aeed3e9SJustin Hibbits     ASSERT_COND(p_Fq);
4760aeed3e9SJustin Hibbits     p_QmFqr = (t_QmFqr *)p_Fq->h_QmFqr;
4770aeed3e9SJustin Hibbits     ASSERT_COND(p_QmFqr);
4780aeed3e9SJustin Hibbits 
4790aeed3e9SJustin Hibbits     if (p_Fq->flags & QMAN_FQ_STATE_NE)
4800aeed3e9SJustin Hibbits     {
4810aeed3e9SJustin Hibbits         if (qman_volatile_dequeue(p_QmFqr->h_QmPortal, p_Fq,
4820aeed3e9SJustin Hibbits                                 (QM_VDQCR_PRECEDENCE_VDQCR | QM_VDQCR_NUMFRAMES_TILLEMPTY)) != E_OK)
4830aeed3e9SJustin Hibbits 
4840aeed3e9SJustin Hibbits             RETURN_ERROR(MAJOR, E_INVALID_STATE, ("drain with volatile failed"));
4850aeed3e9SJustin Hibbits         return E_OK;
4860aeed3e9SJustin Hibbits     }
4870aeed3e9SJustin Hibbits     else
4880aeed3e9SJustin Hibbits         return freeDrainedFq(p_Fq);
4890aeed3e9SJustin Hibbits }
4900aeed3e9SJustin Hibbits 
drainCB(t_Handle h_App,t_Handle h_QmFqr,t_Handle h_QmPortal,uint32_t fqidOffset,t_DpaaFD * p_Frame)4910aeed3e9SJustin Hibbits static e_RxStoreResponse drainCB(t_Handle h_App,
4920aeed3e9SJustin Hibbits                                  t_Handle h_QmFqr,
4930aeed3e9SJustin Hibbits                                  t_Handle h_QmPortal,
4940aeed3e9SJustin Hibbits                                  uint32_t fqidOffset,
4950aeed3e9SJustin Hibbits                                  t_DpaaFD *p_Frame)
4960aeed3e9SJustin Hibbits {
4970aeed3e9SJustin Hibbits     UNUSED(h_App);
4980aeed3e9SJustin Hibbits     UNUSED(h_QmFqr);
4990aeed3e9SJustin Hibbits     UNUSED(h_QmPortal);
5000aeed3e9SJustin Hibbits     UNUSED(fqidOffset);
5010aeed3e9SJustin Hibbits     UNUSED(p_Frame);
5020aeed3e9SJustin Hibbits 
5030aeed3e9SJustin Hibbits     DBG(TRACE,("got fd for fqid %d", ((t_QmFqr *)h_QmFqr)->fqidBase + fqidOffset));
5040aeed3e9SJustin Hibbits     return e_RX_STORE_RESPONSE_CONTINUE;
5050aeed3e9SJustin Hibbits }
5060aeed3e9SJustin Hibbits 
cb_ern_dcErn(t_Handle h_App,t_Handle h_QmPortal,struct qman_fq * p_Fq,const struct qm_mr_entry * p_Msg)5070aeed3e9SJustin Hibbits static void cb_ern_dcErn(t_Handle                   h_App,
5080aeed3e9SJustin Hibbits                          t_Handle                   h_QmPortal,
5090aeed3e9SJustin Hibbits                          struct qman_fq             *p_Fq,
5100aeed3e9SJustin Hibbits                          const struct qm_mr_entry   *p_Msg)
5110aeed3e9SJustin Hibbits {
5120aeed3e9SJustin Hibbits     static int cnt = 0;
5130aeed3e9SJustin Hibbits     UNUSED(p_Fq);
5140aeed3e9SJustin Hibbits     UNUSED(p_Msg);
5150aeed3e9SJustin Hibbits     UNUSED(h_App);
5160aeed3e9SJustin Hibbits     UNUSED(h_QmPortal);
5170aeed3e9SJustin Hibbits 
5180aeed3e9SJustin Hibbits     XX_Print("cb_ern_dcErn_fqs() unimplemented %d\n", ++cnt);
5190aeed3e9SJustin Hibbits }
5200aeed3e9SJustin Hibbits 
cb_fqs(t_Handle h_App,t_Handle h_QmPortal,struct qman_fq * p_Fq,const struct qm_mr_entry * p_Msg)5210aeed3e9SJustin Hibbits static void cb_fqs(t_Handle                   h_App,
5220aeed3e9SJustin Hibbits                    t_Handle                   h_QmPortal,
5230aeed3e9SJustin Hibbits                    struct qman_fq             *p_Fq,
5240aeed3e9SJustin Hibbits                    const struct qm_mr_entry   *p_Msg)
5250aeed3e9SJustin Hibbits {
5260aeed3e9SJustin Hibbits     UNUSED(p_Msg);
5270aeed3e9SJustin Hibbits     UNUSED(h_App);
5280aeed3e9SJustin Hibbits     UNUSED(h_QmPortal);
5290aeed3e9SJustin Hibbits 
5300aeed3e9SJustin Hibbits     if (p_Fq->state == qman_fq_state_retired &&
5310aeed3e9SJustin Hibbits         !(p_Fq->flags & QMAN_FQ_STATE_ORL))
5320aeed3e9SJustin Hibbits         drainRetiredFq(p_Fq);
5330aeed3e9SJustin Hibbits }
5340aeed3e9SJustin Hibbits 
null_cb_mr(t_Handle h_App,t_Handle h_QmPortal,struct qman_fq * p_Fq,const struct qm_mr_entry * p_Msg)5350aeed3e9SJustin Hibbits static void null_cb_mr(t_Handle                   h_App,
5360aeed3e9SJustin Hibbits                        t_Handle                   h_QmPortal,
5370aeed3e9SJustin Hibbits                        struct qman_fq             *p_Fq,
5380aeed3e9SJustin Hibbits                        const struct qm_mr_entry   *p_Msg)
5390aeed3e9SJustin Hibbits {
5400aeed3e9SJustin Hibbits     t_QmPortal      *p_QmPortal = (t_QmPortal *)h_QmPortal;
5410aeed3e9SJustin Hibbits 
5420aeed3e9SJustin Hibbits     UNUSED(p_Fq);UNUSED(h_App);
5430aeed3e9SJustin Hibbits 
5440aeed3e9SJustin Hibbits     if ((p_Msg->verb & QM_MR_VERB_DC_ERN) == QM_MR_VERB_DC_ERN)
5450aeed3e9SJustin Hibbits         XX_Print("Ignoring unowned MR frame on cpu %d, dc-portal 0x%02x.\n",
5460aeed3e9SJustin Hibbits                  p_QmPortal->p_LowQmPortal->config.cpu,p_Msg->dcern.portal);
5470aeed3e9SJustin Hibbits     else
5480aeed3e9SJustin Hibbits         XX_Print("Ignoring unowned MR frame on cpu %d, verb 0x%02x.\n",
5490aeed3e9SJustin Hibbits                  p_QmPortal->p_LowQmPortal->config.cpu,p_Msg->verb);
5500aeed3e9SJustin Hibbits }
5510aeed3e9SJustin Hibbits 
LoopMessageRing(t_QmPortal * p_QmPortal,uint32_t is)5520aeed3e9SJustin Hibbits static uint32_t LoopMessageRing(t_QmPortal *p_QmPortal, uint32_t is)
5530aeed3e9SJustin Hibbits {
5540aeed3e9SJustin Hibbits     struct qm_mr_entry          *p_Msg;
5550aeed3e9SJustin Hibbits 
5560aeed3e9SJustin Hibbits     if (is & QM_PIRQ_CSCI) {
5570aeed3e9SJustin Hibbits         struct qm_mc_result *p_Mcr;
5580aeed3e9SJustin Hibbits         struct qman_cgrs    tmp;
5590aeed3e9SJustin Hibbits         uint32_t            mask;
5600aeed3e9SJustin Hibbits         unsigned int        i, j;
5610aeed3e9SJustin Hibbits 
5620aeed3e9SJustin Hibbits         NCSW_PLOCK(p_QmPortal);
5630aeed3e9SJustin Hibbits         qm_mc_start(p_QmPortal->p_LowQmPortal);
5640aeed3e9SJustin Hibbits         qm_mc_commit(p_QmPortal->p_LowQmPortal, QM_MCC_VERB_QUERYCONGESTION);
5650aeed3e9SJustin Hibbits         while (!(p_Mcr = qm_mc_result(p_QmPortal->p_LowQmPortal))) ;
5660aeed3e9SJustin Hibbits 
5670aeed3e9SJustin Hibbits         /* cgrs[0] is the portal mask for its cg's, cgrs[1] is the
5680aeed3e9SJustin Hibbits            previous state of cg's */
5690aeed3e9SJustin Hibbits         for (i = 0; i < QM_MAX_NUM_OF_CGS/32; i++)
5700aeed3e9SJustin Hibbits         {
5710aeed3e9SJustin Hibbits             /* get curent state */
5720aeed3e9SJustin Hibbits             tmp.q.__state[i] = p_Mcr->querycongestion.state.__state[i];
5730aeed3e9SJustin Hibbits             /* keep only cg's that are registered for this portal */
5740aeed3e9SJustin Hibbits             tmp.q.__state[i] &= p_QmPortal->cgrs[0].q.__state[i];
5750aeed3e9SJustin Hibbits             /* handle only cg's that changed their state from previous exception */
5760aeed3e9SJustin Hibbits             tmp.q.__state[i] ^= p_QmPortal->cgrs[1].q.__state[i];
5770aeed3e9SJustin Hibbits             /* update previous */
5780aeed3e9SJustin Hibbits             p_QmPortal->cgrs[1].q.__state[i] = p_Mcr->querycongestion.state.__state[i];
5790aeed3e9SJustin Hibbits         }
5800aeed3e9SJustin Hibbits         PUNLOCK(p_QmPortal);
5810aeed3e9SJustin Hibbits 
5820aeed3e9SJustin Hibbits         /* if in interrupt */
5830aeed3e9SJustin Hibbits         /* call the callback routines for any CG with a changed state */
5840aeed3e9SJustin Hibbits         for (i = 0; i < QM_MAX_NUM_OF_CGS/32; i++)
5850aeed3e9SJustin Hibbits             for(j=0, mask = 0x80000000; j<32 ; j++, mask>>=1)
5860aeed3e9SJustin Hibbits             {
5870aeed3e9SJustin Hibbits                 if(tmp.q.__state[i] & mask)
5880aeed3e9SJustin Hibbits                 {
5890aeed3e9SJustin Hibbits                     t_QmCg *p_QmCg = (t_QmCg *)(p_QmPortal->cgsHandles[i*32 + j]);
5900aeed3e9SJustin Hibbits                     if(p_QmCg->f_Exception)
5910aeed3e9SJustin Hibbits                         p_QmCg->f_Exception(p_QmCg->h_App, e_QM_EX_CG_STATE_CHANGE);
5920aeed3e9SJustin Hibbits                 }
5930aeed3e9SJustin Hibbits             }
5940aeed3e9SJustin Hibbits 
5950aeed3e9SJustin Hibbits     }
5960aeed3e9SJustin Hibbits 
5970aeed3e9SJustin Hibbits 
5980aeed3e9SJustin Hibbits     if (is & QM_PIRQ_EQRI) {
5990aeed3e9SJustin Hibbits         NCSW_PLOCK(p_QmPortal);
6000aeed3e9SJustin Hibbits         qmPortalEqcrCceUpdate(p_QmPortal->p_LowQmPortal);
6010aeed3e9SJustin Hibbits         qm_eqcr_set_ithresh(p_QmPortal->p_LowQmPortal, 0);
6020aeed3e9SJustin Hibbits         PUNLOCK(p_QmPortal);
6030aeed3e9SJustin Hibbits     }
6040aeed3e9SJustin Hibbits 
6050aeed3e9SJustin Hibbits     if (is & QM_PIRQ_MRI) {
6060aeed3e9SJustin Hibbits mr_loop:
6070aeed3e9SJustin Hibbits         qmPortalMrPvbUpdate(p_QmPortal->p_LowQmPortal);
6080aeed3e9SJustin Hibbits         p_Msg = qm_mr_current(p_QmPortal->p_LowQmPortal);
6090aeed3e9SJustin Hibbits         if (p_Msg) {
610852ba100SJustin Hibbits             struct qman_fq  *p_FqFqs  = ptr_from_aligned_int(p_Msg->fq.contextB);
611852ba100SJustin Hibbits             struct qman_fq  *p_FqErn  = ptr_from_aligned_int(p_Msg->ern.tag);
6120aeed3e9SJustin Hibbits             uint8_t         verb    =(uint8_t)(p_Msg->verb & QM_MR_VERB_TYPE_MASK);
6130aeed3e9SJustin Hibbits             t_QmRejectedFrameInfo   rejectedFrameInfo;
6140aeed3e9SJustin Hibbits 
6150aeed3e9SJustin Hibbits             memset(&rejectedFrameInfo, 0, sizeof(t_QmRejectedFrameInfo));
6160aeed3e9SJustin Hibbits             if (!(verb & QM_MR_VERB_DC_ERN))
6170aeed3e9SJustin Hibbits             {
6180aeed3e9SJustin Hibbits                 switch(p_Msg->ern.rc)
6190aeed3e9SJustin Hibbits                 {
6200aeed3e9SJustin Hibbits                     case(QM_MR_RC_CGR_TAILDROP):
6210aeed3e9SJustin Hibbits                         rejectedFrameInfo.rejectionCode = e_QM_RC_CG_TAILDROP;
6220aeed3e9SJustin Hibbits                         rejectedFrameInfo.cg.cgId = (uint8_t)p_FqErn->cgr_groupid;
6230aeed3e9SJustin Hibbits                         break;
6240aeed3e9SJustin Hibbits                     case(QM_MR_RC_WRED):
6250aeed3e9SJustin Hibbits                         rejectedFrameInfo.rejectionCode = e_QM_RC_CG_WRED;
6260aeed3e9SJustin Hibbits                         rejectedFrameInfo.cg.cgId = (uint8_t)p_FqErn->cgr_groupid;
6270aeed3e9SJustin Hibbits                         break;
6280aeed3e9SJustin Hibbits                     case(QM_MR_RC_FQ_TAILDROP):
6290aeed3e9SJustin Hibbits                         rejectedFrameInfo.rejectionCode = e_QM_RC_FQ_TAILDROP;
6300aeed3e9SJustin Hibbits                         rejectedFrameInfo.cg.cgId = (uint8_t)p_FqErn->cgr_groupid;
6310aeed3e9SJustin Hibbits                         break;
6320aeed3e9SJustin Hibbits                     case(QM_MR_RC_ERROR):
6330aeed3e9SJustin Hibbits                         break;
6340aeed3e9SJustin Hibbits                     default:
6350aeed3e9SJustin Hibbits                         REPORT_ERROR(MINOR, E_NOT_SUPPORTED, ("Unknown rejection code"));
6360aeed3e9SJustin Hibbits                 }
6370aeed3e9SJustin Hibbits                 if (!p_FqErn)
6380aeed3e9SJustin Hibbits                     p_QmPortal->p_NullCB->ern(p_QmPortal->h_App, NULL, p_QmPortal, 0, (t_DpaaFD*)&p_Msg->ern.fd, &rejectedFrameInfo);
6390aeed3e9SJustin Hibbits                 else
6400aeed3e9SJustin Hibbits                     p_FqErn->cb.ern(p_FqErn->h_App, p_FqErn->h_QmFqr, p_QmPortal, p_FqErn->fqidOffset, (t_DpaaFD*)&p_Msg->ern.fd, &rejectedFrameInfo);
6410aeed3e9SJustin Hibbits             } else if (verb == QM_MR_VERB_DC_ERN)
6420aeed3e9SJustin Hibbits             {
6430aeed3e9SJustin Hibbits                 if (!p_FqErn)
6440aeed3e9SJustin Hibbits                     p_QmPortal->p_NullCB->dc_ern(NULL, p_QmPortal, NULL, p_Msg);
6450aeed3e9SJustin Hibbits                 else
6460aeed3e9SJustin Hibbits                     p_FqErn->cb.dc_ern(p_FqErn->h_App, p_QmPortal, p_FqErn, p_Msg);
6470aeed3e9SJustin Hibbits             } else
6480aeed3e9SJustin Hibbits             {
6490aeed3e9SJustin Hibbits                 if (verb == QM_MR_VERB_FQRNI)
6500aeed3e9SJustin Hibbits                     ; /* we drop FQRNIs on the floor */
6510aeed3e9SJustin Hibbits                 else if (!p_FqFqs)
6520aeed3e9SJustin Hibbits                             p_QmPortal->p_NullCB->fqs(NULL, p_QmPortal, NULL, p_Msg);
6530aeed3e9SJustin Hibbits                 else if ((verb == QM_MR_VERB_FQRN) ||
6540aeed3e9SJustin Hibbits                          (verb == QM_MR_VERB_FQRL) ||
6550aeed3e9SJustin Hibbits                          (verb == QM_MR_VERB_FQPN))
6560aeed3e9SJustin Hibbits                 {
6570aeed3e9SJustin Hibbits                     fq_state_change(p_FqFqs, p_Msg, verb);
6580aeed3e9SJustin Hibbits                     p_FqFqs->cb.fqs(p_FqFqs->h_App, p_QmPortal, p_FqFqs, p_Msg);
6590aeed3e9SJustin Hibbits                 }
6600aeed3e9SJustin Hibbits             }
6610aeed3e9SJustin Hibbits             qm_mr_next(p_QmPortal->p_LowQmPortal);
6620aeed3e9SJustin Hibbits             qmPortalMrCciConsume(p_QmPortal->p_LowQmPortal, 1);
6630aeed3e9SJustin Hibbits 
6640aeed3e9SJustin Hibbits             goto mr_loop;
6650aeed3e9SJustin Hibbits         }
6660aeed3e9SJustin Hibbits     }
6670aeed3e9SJustin Hibbits 
6680aeed3e9SJustin Hibbits     return is & (QM_PIRQ_CSCI | QM_PIRQ_EQCI | QM_PIRQ_EQRI | QM_PIRQ_MRI);
6690aeed3e9SJustin Hibbits }
6700aeed3e9SJustin Hibbits 
LoopDequeueRing(t_Handle h_QmPortal)6710aeed3e9SJustin Hibbits static void LoopDequeueRing(t_Handle h_QmPortal)
6720aeed3e9SJustin Hibbits {
6730aeed3e9SJustin Hibbits     struct qm_dqrr_entry        *p_Dq;
6740aeed3e9SJustin Hibbits     struct qman_fq              *p_Fq;
6750aeed3e9SJustin Hibbits     enum qman_cb_dqrr_result    res = qman_cb_dqrr_consume;
6760aeed3e9SJustin Hibbits     e_RxStoreResponse           tmpRes;
6770aeed3e9SJustin Hibbits     t_QmPortal                  *p_QmPortal = (t_QmPortal *)h_QmPortal;
6780aeed3e9SJustin Hibbits     int                         prefetch = !(p_QmPortal->options & QMAN_PORTAL_FLAG_RSTASH);
6790aeed3e9SJustin Hibbits 
6800aeed3e9SJustin Hibbits     while (res != qman_cb_dqrr_pause)
6810aeed3e9SJustin Hibbits     {
6820aeed3e9SJustin Hibbits         if (prefetch)
6830aeed3e9SJustin Hibbits             qmPortalDqrrPvbPrefetch(p_QmPortal->p_LowQmPortal);
6840aeed3e9SJustin Hibbits         qmPortalDqrrPvbUpdate(p_QmPortal->p_LowQmPortal);
6850aeed3e9SJustin Hibbits         p_Dq = qm_dqrr_current(p_QmPortal->p_LowQmPortal);
6860aeed3e9SJustin Hibbits         if (!p_Dq)
6870aeed3e9SJustin Hibbits             break;
688852ba100SJustin Hibbits 	p_Fq = ptr_from_aligned_int(p_Dq->contextB);
6890aeed3e9SJustin Hibbits         if (p_Dq->stat & QM_DQRR_STAT_UNSCHEDULED) {
6900aeed3e9SJustin Hibbits             /* We only set QMAN_FQ_STATE_NE when retiring, so we only need
6910aeed3e9SJustin Hibbits              * to check for clearing it when doing volatile dequeues. It's
6920aeed3e9SJustin Hibbits              * one less thing to check in the critical path (SDQCR). */
6930aeed3e9SJustin Hibbits             tmpRes = p_Fq->cb.dqrr(p_Fq->h_App, p_Fq->h_QmFqr, p_QmPortal, p_Fq->fqidOffset, (t_DpaaFD*)&p_Dq->fd);
6940aeed3e9SJustin Hibbits             if (tmpRes == e_RX_STORE_RESPONSE_PAUSE)
6950aeed3e9SJustin Hibbits                 res = qman_cb_dqrr_pause;
6960aeed3e9SJustin Hibbits             /* Check for VDQCR completion */
6970aeed3e9SJustin Hibbits             if (p_Dq->stat & QM_DQRR_STAT_DQCR_EXPIRED)
6980aeed3e9SJustin Hibbits                 p_Fq->flags &= ~QMAN_FQ_STATE_VDQCR;
6990aeed3e9SJustin Hibbits             if (p_Dq->stat & QM_DQRR_STAT_FQ_EMPTY)
7000aeed3e9SJustin Hibbits             {
7010aeed3e9SJustin Hibbits                 p_Fq->flags &= ~QMAN_FQ_STATE_NE;
7020aeed3e9SJustin Hibbits                 freeDrainedFq(p_Fq);
7030aeed3e9SJustin Hibbits             }
7040aeed3e9SJustin Hibbits         }
7050aeed3e9SJustin Hibbits         else
7060aeed3e9SJustin Hibbits         {
7070aeed3e9SJustin Hibbits             /* Interpret 'dq' from the owner's perspective. */
7080aeed3e9SJustin Hibbits             /* use portal default handlers */
7090aeed3e9SJustin Hibbits             ASSERT_COND(p_Dq->fqid);
7100aeed3e9SJustin Hibbits             if (p_Fq)
7110aeed3e9SJustin Hibbits             {
7120aeed3e9SJustin Hibbits                 tmpRes = p_Fq->cb.dqrr(p_Fq->h_App,
7130aeed3e9SJustin Hibbits                                        p_Fq->h_QmFqr,
7140aeed3e9SJustin Hibbits                                        p_QmPortal,
7150aeed3e9SJustin Hibbits                                        p_Fq->fqidOffset,
7160aeed3e9SJustin Hibbits                                        (t_DpaaFD*)&p_Dq->fd);
7170aeed3e9SJustin Hibbits                 if (tmpRes == e_RX_STORE_RESPONSE_PAUSE)
7180aeed3e9SJustin Hibbits                     res = qman_cb_dqrr_pause;
7190aeed3e9SJustin Hibbits                 else if (p_Fq->state == qman_fq_state_waiting_parked)
7200aeed3e9SJustin Hibbits                     res = qman_cb_dqrr_park;
7210aeed3e9SJustin Hibbits             }
7220aeed3e9SJustin Hibbits             else
7230aeed3e9SJustin Hibbits             {
7240aeed3e9SJustin Hibbits                 tmpRes = p_QmPortal->p_NullCB->dqrr(p_QmPortal->h_App,
7250aeed3e9SJustin Hibbits                                                     NULL,
7260aeed3e9SJustin Hibbits                                                     p_QmPortal,
7270aeed3e9SJustin Hibbits                                                     p_Dq->fqid,
7280aeed3e9SJustin Hibbits                                                     (t_DpaaFD*)&p_Dq->fd);
7290aeed3e9SJustin Hibbits                 if (tmpRes == e_RX_STORE_RESPONSE_PAUSE)
7300aeed3e9SJustin Hibbits                     res = qman_cb_dqrr_pause;
7310aeed3e9SJustin Hibbits             }
7320aeed3e9SJustin Hibbits         }
7330aeed3e9SJustin Hibbits 
7340aeed3e9SJustin Hibbits         /* Parking isn't possible unless HELDACTIVE was set. NB,
7350aeed3e9SJustin Hibbits          * FORCEELIGIBLE implies HELDACTIVE, so we only need to
7360aeed3e9SJustin Hibbits          * check for HELDACTIVE to cover both. */
7370aeed3e9SJustin Hibbits         ASSERT_COND((p_Dq->stat & QM_DQRR_STAT_FQ_HELDACTIVE) ||
7380aeed3e9SJustin Hibbits                     (res != qman_cb_dqrr_park));
7390aeed3e9SJustin Hibbits         if (p_QmPortal->options & QMAN_PORTAL_FLAG_DCA) {
7400aeed3e9SJustin Hibbits             /* Defer just means "skip it, I'll consume it myself later on" */
7410aeed3e9SJustin Hibbits             if (res != qman_cb_dqrr_defer)
7420aeed3e9SJustin Hibbits                 qmPortalDqrrDcaConsume1ptr(p_QmPortal->p_LowQmPortal,
7430aeed3e9SJustin Hibbits                                            p_Dq,
7440aeed3e9SJustin Hibbits                                            (res == qman_cb_dqrr_park));
7450aeed3e9SJustin Hibbits             qm_dqrr_next(p_QmPortal->p_LowQmPortal);
7460aeed3e9SJustin Hibbits         } else {
7470aeed3e9SJustin Hibbits             if (res == qman_cb_dqrr_park)
7480aeed3e9SJustin Hibbits                 /* The only thing to do for non-DCA is the park-request */
7490aeed3e9SJustin Hibbits                 qm_dqrr_park_ci(p_QmPortal->p_LowQmPortal);
7500aeed3e9SJustin Hibbits             qm_dqrr_next(p_QmPortal->p_LowQmPortal);
7510aeed3e9SJustin Hibbits             qmPortalDqrrCciConsume(p_QmPortal->p_LowQmPortal, 1);
7520aeed3e9SJustin Hibbits         }
7530aeed3e9SJustin Hibbits     }
7540aeed3e9SJustin Hibbits }
7550aeed3e9SJustin Hibbits 
LoopDequeueRingDcaOptimized(t_Handle h_QmPortal)7560aeed3e9SJustin Hibbits static void LoopDequeueRingDcaOptimized(t_Handle h_QmPortal)
7570aeed3e9SJustin Hibbits {
7580aeed3e9SJustin Hibbits     struct qm_dqrr_entry        *p_Dq;
7590aeed3e9SJustin Hibbits     struct qman_fq              *p_Fq;
7600aeed3e9SJustin Hibbits     enum qman_cb_dqrr_result    res = qman_cb_dqrr_consume;
7610aeed3e9SJustin Hibbits     e_RxStoreResponse           tmpRes;
7620aeed3e9SJustin Hibbits     t_QmPortal                  *p_QmPortal = (t_QmPortal *)h_QmPortal;
7630aeed3e9SJustin Hibbits 
7640aeed3e9SJustin Hibbits     while (res != qman_cb_dqrr_pause)
7650aeed3e9SJustin Hibbits     {
7660aeed3e9SJustin Hibbits         qmPortalDqrrPvbUpdate(p_QmPortal->p_LowQmPortal);
7670aeed3e9SJustin Hibbits         p_Dq = qm_dqrr_current(p_QmPortal->p_LowQmPortal);
7680aeed3e9SJustin Hibbits         if (!p_Dq)
7690aeed3e9SJustin Hibbits             break;
770852ba100SJustin Hibbits 	p_Fq = ptr_from_aligned_int(p_Dq->contextB);
7710aeed3e9SJustin Hibbits         if (p_Dq->stat & QM_DQRR_STAT_UNSCHEDULED) {
7720aeed3e9SJustin Hibbits             /* We only set QMAN_FQ_STATE_NE when retiring, so we only need
7730aeed3e9SJustin Hibbits              * to check for clearing it when doing volatile dequeues. It's
7740aeed3e9SJustin Hibbits              * one less thing to check in the critical path (SDQCR). */
7750aeed3e9SJustin Hibbits             tmpRes = p_Fq->cb.dqrr(p_Fq->h_App, p_Fq->h_QmFqr, p_QmPortal, p_Fq->fqidOffset, (t_DpaaFD*)&p_Dq->fd);
7760aeed3e9SJustin Hibbits             if (tmpRes == e_RX_STORE_RESPONSE_PAUSE)
7770aeed3e9SJustin Hibbits                 res = qman_cb_dqrr_pause;
7780aeed3e9SJustin Hibbits             /* Check for VDQCR completion */
7790aeed3e9SJustin Hibbits             if (p_Dq->stat & QM_DQRR_STAT_DQCR_EXPIRED)
7800aeed3e9SJustin Hibbits                 p_Fq->flags &= ~QMAN_FQ_STATE_VDQCR;
7810aeed3e9SJustin Hibbits             if (p_Dq->stat & QM_DQRR_STAT_FQ_EMPTY)
7820aeed3e9SJustin Hibbits             {
7830aeed3e9SJustin Hibbits                 p_Fq->flags &= ~QMAN_FQ_STATE_NE;
7840aeed3e9SJustin Hibbits                 freeDrainedFq(p_Fq);
7850aeed3e9SJustin Hibbits             }
7860aeed3e9SJustin Hibbits         }
7870aeed3e9SJustin Hibbits         else
7880aeed3e9SJustin Hibbits         {
7890aeed3e9SJustin Hibbits             /* Interpret 'dq' from the owner's perspective. */
7900aeed3e9SJustin Hibbits             /* use portal default handlers */
7910aeed3e9SJustin Hibbits             ASSERT_COND(p_Dq->fqid);
7920aeed3e9SJustin Hibbits             if (p_Fq)
7930aeed3e9SJustin Hibbits             {
7940aeed3e9SJustin Hibbits                 tmpRes = p_Fq->cb.dqrr(p_Fq->h_App,
7950aeed3e9SJustin Hibbits                                        p_Fq->h_QmFqr,
7960aeed3e9SJustin Hibbits                                        p_QmPortal,
7970aeed3e9SJustin Hibbits                                        p_Fq->fqidOffset,
7980aeed3e9SJustin Hibbits                                        (t_DpaaFD*)&p_Dq->fd);
7990aeed3e9SJustin Hibbits                 if (tmpRes == e_RX_STORE_RESPONSE_PAUSE)
8000aeed3e9SJustin Hibbits                     res = qman_cb_dqrr_pause;
8010aeed3e9SJustin Hibbits                 else if (p_Fq->state == qman_fq_state_waiting_parked)
8020aeed3e9SJustin Hibbits                     res = qman_cb_dqrr_park;
8030aeed3e9SJustin Hibbits             }
8040aeed3e9SJustin Hibbits             else
8050aeed3e9SJustin Hibbits             {
8060aeed3e9SJustin Hibbits                 tmpRes = p_QmPortal->p_NullCB->dqrr(p_QmPortal->h_App,
8070aeed3e9SJustin Hibbits                                                     NULL,
8080aeed3e9SJustin Hibbits                                                     p_QmPortal,
8090aeed3e9SJustin Hibbits                                                     p_Dq->fqid,
8100aeed3e9SJustin Hibbits                                                     (t_DpaaFD*)&p_Dq->fd);
8110aeed3e9SJustin Hibbits                 if (tmpRes == e_RX_STORE_RESPONSE_PAUSE)
8120aeed3e9SJustin Hibbits                     res = qman_cb_dqrr_pause;
8130aeed3e9SJustin Hibbits             }
8140aeed3e9SJustin Hibbits         }
8150aeed3e9SJustin Hibbits 
8160aeed3e9SJustin Hibbits         /* Parking isn't possible unless HELDACTIVE was set. NB,
8170aeed3e9SJustin Hibbits          * FORCEELIGIBLE implies HELDACTIVE, so we only need to
8180aeed3e9SJustin Hibbits          * check for HELDACTIVE to cover both. */
8190aeed3e9SJustin Hibbits         ASSERT_COND((p_Dq->stat & QM_DQRR_STAT_FQ_HELDACTIVE) ||
8200aeed3e9SJustin Hibbits                 (res != qman_cb_dqrr_park));
8210aeed3e9SJustin Hibbits         /* Defer just means "skip it, I'll consume it myself later on" */
8220aeed3e9SJustin Hibbits         if (res != qman_cb_dqrr_defer)
8230aeed3e9SJustin Hibbits             qmPortalDqrrDcaConsume1ptr(p_QmPortal->p_LowQmPortal,
8240aeed3e9SJustin Hibbits                                        p_Dq,
8250aeed3e9SJustin Hibbits                                        (res == qman_cb_dqrr_park));
8260aeed3e9SJustin Hibbits         qm_dqrr_next(p_QmPortal->p_LowQmPortal);
8270aeed3e9SJustin Hibbits     }
8280aeed3e9SJustin Hibbits }
8290aeed3e9SJustin Hibbits 
LoopDequeueRingOptimized(t_Handle h_QmPortal)8300aeed3e9SJustin Hibbits static void LoopDequeueRingOptimized(t_Handle h_QmPortal)
8310aeed3e9SJustin Hibbits {
8320aeed3e9SJustin Hibbits     struct qm_dqrr_entry        *p_Dq;
8330aeed3e9SJustin Hibbits     struct qman_fq              *p_Fq;
8340aeed3e9SJustin Hibbits     enum qman_cb_dqrr_result    res = qman_cb_dqrr_consume;
8350aeed3e9SJustin Hibbits     e_RxStoreResponse           tmpRes;
8360aeed3e9SJustin Hibbits     t_QmPortal                  *p_QmPortal = (t_QmPortal *)h_QmPortal;
8370aeed3e9SJustin Hibbits 
8380aeed3e9SJustin Hibbits     while (res != qman_cb_dqrr_pause)
8390aeed3e9SJustin Hibbits     {
8400aeed3e9SJustin Hibbits         qmPortalDqrrPvbUpdate(p_QmPortal->p_LowQmPortal);
8410aeed3e9SJustin Hibbits         p_Dq = qm_dqrr_current(p_QmPortal->p_LowQmPortal);
8420aeed3e9SJustin Hibbits         if (!p_Dq)
8430aeed3e9SJustin Hibbits             break;
844852ba100SJustin Hibbits 	p_Fq = ptr_from_aligned_int(p_Dq->contextB);
8450aeed3e9SJustin Hibbits         if (p_Dq->stat & QM_DQRR_STAT_UNSCHEDULED) {
8460aeed3e9SJustin Hibbits             /* We only set QMAN_FQ_STATE_NE when retiring, so we only need
8470aeed3e9SJustin Hibbits              * to check for clearing it when doing volatile dequeues. It's
8480aeed3e9SJustin Hibbits              * one less thing to check in the critical path (SDQCR). */
8490aeed3e9SJustin Hibbits             tmpRes = p_Fq->cb.dqrr(p_Fq->h_App, p_Fq->h_QmFqr, p_QmPortal, p_Fq->fqidOffset, (t_DpaaFD*)&p_Dq->fd);
8500aeed3e9SJustin Hibbits             if (tmpRes == e_RX_STORE_RESPONSE_PAUSE)
8510aeed3e9SJustin Hibbits                 res = qman_cb_dqrr_pause;
8520aeed3e9SJustin Hibbits             /* Check for VDQCR completion */
8530aeed3e9SJustin Hibbits             if (p_Dq->stat & QM_DQRR_STAT_DQCR_EXPIRED)
8540aeed3e9SJustin Hibbits                 p_Fq->flags &= ~QMAN_FQ_STATE_VDQCR;
8550aeed3e9SJustin Hibbits             if (p_Dq->stat & QM_DQRR_STAT_FQ_EMPTY)
8560aeed3e9SJustin Hibbits             {
8570aeed3e9SJustin Hibbits                 p_Fq->flags &= ~QMAN_FQ_STATE_NE;
8580aeed3e9SJustin Hibbits                 freeDrainedFq(p_Fq);
8590aeed3e9SJustin Hibbits             }
8600aeed3e9SJustin Hibbits         }
8610aeed3e9SJustin Hibbits         else
8620aeed3e9SJustin Hibbits         {
8630aeed3e9SJustin Hibbits             /* Interpret 'dq' from the owner's perspective. */
8640aeed3e9SJustin Hibbits             /* use portal default handlers */
8650aeed3e9SJustin Hibbits             ASSERT_COND(p_Dq->fqid);
8660aeed3e9SJustin Hibbits             if (p_Fq)
8670aeed3e9SJustin Hibbits             {
8680aeed3e9SJustin Hibbits                 tmpRes = p_Fq->cb.dqrr(p_Fq->h_App,
8690aeed3e9SJustin Hibbits                                        p_Fq->h_QmFqr,
8700aeed3e9SJustin Hibbits                                        p_QmPortal,
8710aeed3e9SJustin Hibbits                                        p_Fq->fqidOffset,
8720aeed3e9SJustin Hibbits                                        (t_DpaaFD*)&p_Dq->fd);
8730aeed3e9SJustin Hibbits                 if (tmpRes == e_RX_STORE_RESPONSE_PAUSE)
8740aeed3e9SJustin Hibbits                     res = qman_cb_dqrr_pause;
8750aeed3e9SJustin Hibbits                 else if (p_Fq->state == qman_fq_state_waiting_parked)
8760aeed3e9SJustin Hibbits                     res = qman_cb_dqrr_park;
8770aeed3e9SJustin Hibbits             }
8780aeed3e9SJustin Hibbits             else
8790aeed3e9SJustin Hibbits             {
8800aeed3e9SJustin Hibbits                 tmpRes = p_QmPortal->p_NullCB->dqrr(p_QmPortal->h_App,
8810aeed3e9SJustin Hibbits                                                     NULL,
8820aeed3e9SJustin Hibbits                                                     p_QmPortal,
8830aeed3e9SJustin Hibbits                                                     p_Dq->fqid,
8840aeed3e9SJustin Hibbits                                                     (t_DpaaFD*)&p_Dq->fd);
8850aeed3e9SJustin Hibbits                 if (tmpRes == e_RX_STORE_RESPONSE_PAUSE)
8860aeed3e9SJustin Hibbits                     res = qman_cb_dqrr_pause;
8870aeed3e9SJustin Hibbits             }
8880aeed3e9SJustin Hibbits         }
8890aeed3e9SJustin Hibbits 
8900aeed3e9SJustin Hibbits         /* Parking isn't possible unless HELDACTIVE was set. NB,
8910aeed3e9SJustin Hibbits          * FORCEELIGIBLE implies HELDACTIVE, so we only need to
8920aeed3e9SJustin Hibbits          * check for HELDACTIVE to cover both. */
8930aeed3e9SJustin Hibbits         ASSERT_COND((p_Dq->stat & QM_DQRR_STAT_FQ_HELDACTIVE) ||
8940aeed3e9SJustin Hibbits                 (res != qman_cb_dqrr_park));
8950aeed3e9SJustin Hibbits         if (res == qman_cb_dqrr_park)
8960aeed3e9SJustin Hibbits             /* The only thing to do for non-DCA is the park-request */
8970aeed3e9SJustin Hibbits             qm_dqrr_park_ci(p_QmPortal->p_LowQmPortal);
8980aeed3e9SJustin Hibbits         qm_dqrr_next(p_QmPortal->p_LowQmPortal);
8990aeed3e9SJustin Hibbits         qmPortalDqrrCciConsume(p_QmPortal->p_LowQmPortal, 1);
9000aeed3e9SJustin Hibbits     }
9010aeed3e9SJustin Hibbits }
9020aeed3e9SJustin Hibbits 
9030aeed3e9SJustin Hibbits /* Portal interrupt handler */
portal_isr(void * ptr)9040aeed3e9SJustin Hibbits static void portal_isr(void *ptr)
9050aeed3e9SJustin Hibbits {
9060aeed3e9SJustin Hibbits     t_QmPortal  *p_QmPortal = ptr;
9070aeed3e9SJustin Hibbits     uint32_t    event = 0;
9080aeed3e9SJustin Hibbits     uint32_t    enableEvents = qm_isr_enable_read(p_QmPortal->p_LowQmPortal);
9090aeed3e9SJustin Hibbits 
9100aeed3e9SJustin Hibbits     DBG(TRACE, ("software-portal %d got interrupt", p_QmPortal->p_LowQmPortal->config.cpu));
9110aeed3e9SJustin Hibbits 
9120aeed3e9SJustin Hibbits     event |= (qm_isr_status_read(p_QmPortal->p_LowQmPortal) &
9130aeed3e9SJustin Hibbits             enableEvents);
9140aeed3e9SJustin Hibbits 
9150aeed3e9SJustin Hibbits     qm_isr_status_clear(p_QmPortal->p_LowQmPortal, event);
9160aeed3e9SJustin Hibbits     /* Only do fast-path handling if it's required */
9170aeed3e9SJustin Hibbits     if (/*(event & QM_PIRQ_DQRI) &&*/
9180aeed3e9SJustin Hibbits         (p_QmPortal->options & QMAN_PORTAL_FLAG_IRQ_FAST))
9190aeed3e9SJustin Hibbits         p_QmPortal->f_LoopDequeueRingCB(p_QmPortal);
9200aeed3e9SJustin Hibbits     if (p_QmPortal->options & QMAN_PORTAL_FLAG_IRQ_SLOW)
9210aeed3e9SJustin Hibbits         LoopMessageRing(p_QmPortal, event);
9220aeed3e9SJustin Hibbits }
9230aeed3e9SJustin Hibbits 
9240aeed3e9SJustin Hibbits 
qman_query_fq_np(t_QmPortal * p_QmPortal,struct qman_fq * p_Fq,struct qm_mcr_queryfq_np * p_Np)9250aeed3e9SJustin Hibbits static t_Error qman_query_fq_np(t_QmPortal *p_QmPortal, struct qman_fq *p_Fq, struct qm_mcr_queryfq_np *p_Np)
9260aeed3e9SJustin Hibbits {
9270aeed3e9SJustin Hibbits     struct qm_mc_command    *p_Mcc;
9280aeed3e9SJustin Hibbits     struct qm_mc_result     *p_Mcr;
9290aeed3e9SJustin Hibbits     uint8_t                 res;
9300aeed3e9SJustin Hibbits 
9310aeed3e9SJustin Hibbits     NCSW_PLOCK(p_QmPortal);
9320aeed3e9SJustin Hibbits     p_Mcc = qm_mc_start(p_QmPortal->p_LowQmPortal);
9330aeed3e9SJustin Hibbits     p_Mcc->queryfq_np.fqid = p_Fq->fqid;
9340aeed3e9SJustin Hibbits     qm_mc_commit(p_QmPortal->p_LowQmPortal, QM_MCC_VERB_QUERYFQ_NP);
9350aeed3e9SJustin Hibbits     while (!(p_Mcr = qm_mc_result(p_QmPortal->p_LowQmPortal))) ;
9360aeed3e9SJustin Hibbits     ASSERT_COND((p_Mcr->verb & QM_MCR_VERB_MASK) == QM_MCR_VERB_QUERYFQ_NP);
9370aeed3e9SJustin Hibbits     res = p_Mcr->result;
9380aeed3e9SJustin Hibbits     if (res == QM_MCR_RESULT_OK)
9390aeed3e9SJustin Hibbits         *p_Np = p_Mcr->queryfq_np;
9400aeed3e9SJustin Hibbits     PUNLOCK(p_QmPortal);
9410aeed3e9SJustin Hibbits     if (res != QM_MCR_RESULT_OK)
9420aeed3e9SJustin Hibbits         RETURN_ERROR(MINOR, E_INVALID_STATE, ("QUERYFQ_NP failed: %s\n", mcr_result_str(res)));
9430aeed3e9SJustin Hibbits     return E_OK;
9440aeed3e9SJustin Hibbits }
9450aeed3e9SJustin Hibbits 
QmCgGetCgId(t_Handle h_QmCg)9460aeed3e9SJustin Hibbits static uint8_t QmCgGetCgId(t_Handle h_QmCg)
9470aeed3e9SJustin Hibbits {
9480aeed3e9SJustin Hibbits    t_QmCg *p_QmCg = (t_QmCg *)h_QmCg;
9490aeed3e9SJustin Hibbits 
9500aeed3e9SJustin Hibbits    return p_QmCg->id;
9510aeed3e9SJustin Hibbits 
9520aeed3e9SJustin Hibbits }
9530aeed3e9SJustin Hibbits 
qm_new_fq(t_QmPortal * p_QmPortal,uint32_t fqid,uint32_t fqidOffset,uint32_t channel,uint32_t wqid,uint16_t count,uint32_t flags,t_QmFqrCongestionAvoidanceParams * p_CgParams,t_QmContextA * p_ContextA,t_QmContextB * p_ContextB,bool initParked,t_Handle h_QmFqr,struct qman_fq ** p_Fqs)9540aeed3e9SJustin Hibbits static t_Error qm_new_fq(t_QmPortal                         *p_QmPortal,
9550aeed3e9SJustin Hibbits                          uint32_t                           fqid,
9560aeed3e9SJustin Hibbits                          uint32_t                           fqidOffset,
9570aeed3e9SJustin Hibbits                          uint32_t                           channel,
9580aeed3e9SJustin Hibbits                          uint32_t                           wqid,
9590aeed3e9SJustin Hibbits                          uint16_t                           count,
9600aeed3e9SJustin Hibbits                          uint32_t                           flags,
9610aeed3e9SJustin Hibbits                          t_QmFqrCongestionAvoidanceParams   *p_CgParams,
9620aeed3e9SJustin Hibbits                          t_QmContextA                       *p_ContextA,
9630aeed3e9SJustin Hibbits                          t_QmContextB                       *p_ContextB,
9640aeed3e9SJustin Hibbits                          bool                               initParked,
9650aeed3e9SJustin Hibbits                          t_Handle                           h_QmFqr,
9660aeed3e9SJustin Hibbits                          struct qman_fq                     **p_Fqs)
9670aeed3e9SJustin Hibbits {
9680aeed3e9SJustin Hibbits     struct qman_fq          *p_Fq = NULL;
9690aeed3e9SJustin Hibbits     struct qm_mcc_initfq    fq_opts;
9700aeed3e9SJustin Hibbits     uint32_t                i;
9710aeed3e9SJustin Hibbits     t_Error                 err = E_OK;
9720aeed3e9SJustin Hibbits     int         gap, tmp;
9730aeed3e9SJustin Hibbits     uint32_t    tmpA, tmpN, ta=0, tn=0, initFqFlag;
9740aeed3e9SJustin Hibbits 
9750aeed3e9SJustin Hibbits     ASSERT_COND(p_QmPortal);
9760aeed3e9SJustin Hibbits     ASSERT_COND(count);
9770aeed3e9SJustin Hibbits 
9780aeed3e9SJustin Hibbits     for(i=0;i<count;i++)
9790aeed3e9SJustin Hibbits     {
9800aeed3e9SJustin Hibbits         p_Fq = (struct qman_fq *)XX_MallocSmart(sizeof(struct qman_fq), 0, 64);
9810aeed3e9SJustin Hibbits         if (!p_Fq)
9820aeed3e9SJustin Hibbits             RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FQ obj!!!"));
9830aeed3e9SJustin Hibbits         memset(p_Fq, 0, sizeof(struct qman_fq));
9840aeed3e9SJustin Hibbits         p_Fq->cb.dqrr     = p_QmPortal->f_DfltFrame;
9850aeed3e9SJustin Hibbits         p_Fq->cb.ern      = p_QmPortal->f_RejectedFrame;
9860aeed3e9SJustin Hibbits         p_Fq->cb.dc_ern   = cb_ern_dcErn;
9870aeed3e9SJustin Hibbits         p_Fq->cb.fqs      = cb_fqs;
9880aeed3e9SJustin Hibbits         p_Fq->h_App       = p_QmPortal->h_App;
9890aeed3e9SJustin Hibbits         p_Fq->h_QmFqr     = h_QmFqr;
9900aeed3e9SJustin Hibbits         p_Fq->fqidOffset  = fqidOffset;
9910aeed3e9SJustin Hibbits         p_Fqs[i] = p_Fq;
9920aeed3e9SJustin Hibbits         if ((err = qman_create_fq(p_QmPortal,(uint32_t)(fqid + i), 0, p_Fqs[i])) != E_OK)
9930aeed3e9SJustin Hibbits             break;
9940aeed3e9SJustin Hibbits     }
9950aeed3e9SJustin Hibbits 
9960aeed3e9SJustin Hibbits     if (err != E_OK)
9970aeed3e9SJustin Hibbits     {
9980aeed3e9SJustin Hibbits         for(i=0;i<count;i++)
9990aeed3e9SJustin Hibbits             if (p_Fqs[i])
10000aeed3e9SJustin Hibbits             {
10010aeed3e9SJustin Hibbits                 XX_FreeSmart(p_Fqs[i]);
10020aeed3e9SJustin Hibbits                 p_Fqs[i] = NULL;
10030aeed3e9SJustin Hibbits             }
10040aeed3e9SJustin Hibbits         RETURN_ERROR(MINOR, err, ("Failed to create Fqs"));
10050aeed3e9SJustin Hibbits     }
10060aeed3e9SJustin Hibbits 
10070aeed3e9SJustin Hibbits     memset(&fq_opts,0,sizeof(fq_opts));
10080aeed3e9SJustin Hibbits     fq_opts.fqid = fqid;
10090aeed3e9SJustin Hibbits     fq_opts.count = (uint16_t)(count-1);
10100aeed3e9SJustin Hibbits     fq_opts.we_mask |= QM_INITFQ_WE_DESTWQ;
10110aeed3e9SJustin Hibbits     fq_opts.fqd.dest.channel = channel;
10120aeed3e9SJustin Hibbits     fq_opts.fqd.dest.wq = wqid;
10130aeed3e9SJustin Hibbits     fq_opts.we_mask |= QM_INITFQ_WE_FQCTRL;
10140aeed3e9SJustin Hibbits     fq_opts.fqd.fq_ctrl = (uint16_t)flags;
10150aeed3e9SJustin Hibbits 
10160aeed3e9SJustin Hibbits     if ((flags & QM_FQCTRL_CGE) || (flags & QM_FQCTRL_TDE))
10170aeed3e9SJustin Hibbits         ASSERT_COND(p_CgParams);
10180aeed3e9SJustin Hibbits 
10190aeed3e9SJustin Hibbits     if(flags & QM_FQCTRL_CGE)
10200aeed3e9SJustin Hibbits     {
10210aeed3e9SJustin Hibbits         ASSERT_COND(p_CgParams->h_QmCg);
10220aeed3e9SJustin Hibbits 
10230aeed3e9SJustin Hibbits         /* CG OAC and FQ TD may not be configured at the same time. if both are required,
10240aeed3e9SJustin Hibbits            than we configure CG first, and the FQ TD later - see below. */
10250aeed3e9SJustin Hibbits         fq_opts.fqd.cgid = QmCgGetCgId(p_CgParams->h_QmCg);
10260aeed3e9SJustin Hibbits         fq_opts.we_mask |= QM_INITFQ_WE_CGID;
10270aeed3e9SJustin Hibbits         if(p_CgParams->overheadAccountingLength)
10280aeed3e9SJustin Hibbits         {
10290aeed3e9SJustin Hibbits             fq_opts.we_mask |= QM_INITFQ_WE_OAC;
10300aeed3e9SJustin Hibbits             fq_opts.we_mask &= ~QM_INITFQ_WE_TDTHRESH;
10310aeed3e9SJustin Hibbits             fq_opts.fqd.td_thresh = (uint16_t)(QM_FQD_TD_THRESH_OAC_EN | p_CgParams->overheadAccountingLength);
10320aeed3e9SJustin Hibbits         }
10330aeed3e9SJustin Hibbits     }
10340aeed3e9SJustin Hibbits     if((flags & QM_FQCTRL_TDE) && (!p_CgParams->overheadAccountingLength))
10350aeed3e9SJustin Hibbits     {
10360aeed3e9SJustin Hibbits         ASSERT_COND(p_CgParams->fqTailDropThreshold);
10370aeed3e9SJustin Hibbits 
10380aeed3e9SJustin Hibbits         fq_opts.we_mask |= QM_INITFQ_WE_TDTHRESH;
10390aeed3e9SJustin Hibbits 
10400aeed3e9SJustin Hibbits             /* express thresh as ta*2^tn */
10410aeed3e9SJustin Hibbits             gap = (int)p_CgParams->fqTailDropThreshold;
10420aeed3e9SJustin Hibbits             for (tmpA=0 ; tmpA<256; tmpA++ )
10430aeed3e9SJustin Hibbits                 for (tmpN=0 ; tmpN<32; tmpN++ )
10440aeed3e9SJustin Hibbits                 {
10450aeed3e9SJustin Hibbits                     tmp = ABS((int)(p_CgParams->fqTailDropThreshold - tmpA*(1<<tmpN)));
10460aeed3e9SJustin Hibbits                     if (tmp < gap)
10470aeed3e9SJustin Hibbits                     {
10480aeed3e9SJustin Hibbits                        ta = tmpA;
10490aeed3e9SJustin Hibbits                        tn = tmpN;
10500aeed3e9SJustin Hibbits                        gap = tmp;
10510aeed3e9SJustin Hibbits                     }
10520aeed3e9SJustin Hibbits                 }
10530aeed3e9SJustin Hibbits             fq_opts.fqd.td.exp = tn;
10540aeed3e9SJustin Hibbits             fq_opts.fqd.td.mant = ta;
10550aeed3e9SJustin Hibbits     }
10560aeed3e9SJustin Hibbits 
10570aeed3e9SJustin Hibbits     if (p_ContextA)
10580aeed3e9SJustin Hibbits     {
10590aeed3e9SJustin Hibbits         fq_opts.we_mask |= QM_INITFQ_WE_CONTEXTA;
10600aeed3e9SJustin Hibbits         memcpy((void*)&fq_opts.fqd.context_a, p_ContextA, sizeof(t_QmContextA));
10610aeed3e9SJustin Hibbits     }
10620aeed3e9SJustin Hibbits     /* If this FQ will not be used for tx, we can use contextB field */
10630aeed3e9SJustin Hibbits     if (fq_opts.fqd.dest.channel < e_QM_FQ_CHANNEL_FMAN0_SP0)
10640aeed3e9SJustin Hibbits     {
10650aeed3e9SJustin Hibbits             fq_opts.we_mask |= QM_INITFQ_WE_CONTEXTB;
1066852ba100SJustin Hibbits             fq_opts.fqd.context_b = aligned_int_from_ptr(p_Fqs[0]);
10670aeed3e9SJustin Hibbits     }
10680aeed3e9SJustin Hibbits     else if (p_ContextB) /* Tx-Queue */
10690aeed3e9SJustin Hibbits     {
10700aeed3e9SJustin Hibbits         fq_opts.we_mask |= QM_INITFQ_WE_CONTEXTB;
10710aeed3e9SJustin Hibbits         memcpy((void*)&fq_opts.fqd.context_b, p_ContextB, sizeof(t_QmContextB));
10720aeed3e9SJustin Hibbits     }
10730aeed3e9SJustin Hibbits 
10740aeed3e9SJustin Hibbits     if((flags & QM_FQCTRL_TDE) && (p_CgParams->overheadAccountingLength))
10750aeed3e9SJustin Hibbits         initFqFlag = 0;
10760aeed3e9SJustin Hibbits     else
10770aeed3e9SJustin Hibbits         initFqFlag = (uint32_t)(initParked?0:QMAN_INITFQ_FLAG_SCHED);
10780aeed3e9SJustin Hibbits 
10790aeed3e9SJustin Hibbits     if ((err = qman_init_fq(p_QmPortal, p_Fqs[0], initFqFlag, &fq_opts)) != E_OK)
10800aeed3e9SJustin Hibbits     {
10810aeed3e9SJustin Hibbits         for(i=0;i<count;i++)
10820aeed3e9SJustin Hibbits             if (p_Fqs[i])
10830aeed3e9SJustin Hibbits             {
10840aeed3e9SJustin Hibbits                 XX_FreeSmart(p_Fqs[i]);
10850aeed3e9SJustin Hibbits                 p_Fqs[i] = NULL;
10860aeed3e9SJustin Hibbits             }
10870aeed3e9SJustin Hibbits         RETURN_ERROR(MINOR, err, ("Failed to init Fqs [%d-%d]", fqid, fqid+count-1));
10880aeed3e9SJustin Hibbits     }
10890aeed3e9SJustin Hibbits 
10900aeed3e9SJustin Hibbits     /* if both CG OAC and FQ TD are needed, we call qman_init_fq again, this time for the FQ TD only */
10910aeed3e9SJustin Hibbits     if((flags & QM_FQCTRL_TDE) && (p_CgParams->overheadAccountingLength))
10920aeed3e9SJustin Hibbits     {
10930aeed3e9SJustin Hibbits         ASSERT_COND(p_CgParams->fqTailDropThreshold);
10940aeed3e9SJustin Hibbits 
10950aeed3e9SJustin Hibbits         fq_opts.we_mask = QM_INITFQ_WE_TDTHRESH;
10960aeed3e9SJustin Hibbits 
10970aeed3e9SJustin Hibbits         /* express thresh as ta*2^tn */
10980aeed3e9SJustin Hibbits         gap = (int)p_CgParams->fqTailDropThreshold;
10990aeed3e9SJustin Hibbits         for (tmpA=0 ; tmpA<256; tmpA++ )
11000aeed3e9SJustin Hibbits             for (tmpN=0 ; tmpN<32; tmpN++ )
11010aeed3e9SJustin Hibbits             {
11020aeed3e9SJustin Hibbits                 tmp = ABS((int)(p_CgParams->fqTailDropThreshold - tmpA*(1<<tmpN)));
11030aeed3e9SJustin Hibbits                 if (tmp < gap)
11040aeed3e9SJustin Hibbits                 {
11050aeed3e9SJustin Hibbits                    ta = tmpA;
11060aeed3e9SJustin Hibbits                    tn = tmpN;
11070aeed3e9SJustin Hibbits                    gap = tmp;
11080aeed3e9SJustin Hibbits                 }
11090aeed3e9SJustin Hibbits             }
11100aeed3e9SJustin Hibbits         fq_opts.fqd.td.exp = tn;
11110aeed3e9SJustin Hibbits         fq_opts.fqd.td.mant = ta;
11120aeed3e9SJustin Hibbits         if ((err = qman_init_fq(p_QmPortal, p_Fqs[0], (uint32_t)(initParked?0:QMAN_INITFQ_FLAG_SCHED), &fq_opts)) != E_OK)
11130aeed3e9SJustin Hibbits         {
11140aeed3e9SJustin Hibbits             for(i=0;i<count;i++)
11150aeed3e9SJustin Hibbits                 if (p_Fqs[i])
11160aeed3e9SJustin Hibbits                 {
11170aeed3e9SJustin Hibbits                     XX_FreeSmart(p_Fqs[i]);
11180aeed3e9SJustin Hibbits                     p_Fqs[i] = NULL;
11190aeed3e9SJustin Hibbits                 }
11200aeed3e9SJustin Hibbits             RETURN_ERROR(MINOR, err, ("Failed to init Fqs"));
11210aeed3e9SJustin Hibbits         }
11220aeed3e9SJustin Hibbits     }
11230aeed3e9SJustin Hibbits 
11240aeed3e9SJustin Hibbits 
11250aeed3e9SJustin Hibbits     for(i=1;i<count;i++)
11260aeed3e9SJustin Hibbits     {
11270aeed3e9SJustin Hibbits         memcpy(p_Fqs[i], p_Fqs[0], sizeof(struct qman_fq));
11280aeed3e9SJustin Hibbits         p_Fqs[i]->fqid += i;
11290aeed3e9SJustin Hibbits     }
11300aeed3e9SJustin Hibbits 
11310aeed3e9SJustin Hibbits     return err;
11320aeed3e9SJustin Hibbits }
11330aeed3e9SJustin Hibbits 
11340aeed3e9SJustin Hibbits 
qm_free_fq(t_QmPortal * p_QmPortal,struct qman_fq * p_Fq)11350aeed3e9SJustin Hibbits static t_Error qm_free_fq(t_QmPortal *p_QmPortal, struct qman_fq *p_Fq)
11360aeed3e9SJustin Hibbits {
11370aeed3e9SJustin Hibbits     uint32_t flags=0;
11380aeed3e9SJustin Hibbits 
1139852ba100SJustin Hibbits     if (qman_retire_fq(p_QmPortal, p_Fq, &flags, false) != E_OK)
11400aeed3e9SJustin Hibbits         RETURN_ERROR(MAJOR, E_INVALID_STATE, ("qman_retire_fq() failed!"));
11410aeed3e9SJustin Hibbits 
11420aeed3e9SJustin Hibbits     if (flags & QMAN_FQ_STATE_CHANGING)
11430aeed3e9SJustin Hibbits         RETURN_ERROR(MAJOR, E_INVALID_STATE, ("fq %d currently in use, will be retired", p_Fq->fqid));
11440aeed3e9SJustin Hibbits 
11450aeed3e9SJustin Hibbits     if (flags & QMAN_FQ_STATE_NE)
11460aeed3e9SJustin Hibbits         RETURN_ERROR(MAJOR, E_INVALID_STATE, ("qman_retire_fq() failed;" \
11470aeed3e9SJustin Hibbits                                           "Frame Queue Not Empty, Need to dequeue"));
11480aeed3e9SJustin Hibbits 
11490aeed3e9SJustin Hibbits     if (qman_oos_fq(p_QmPortal, p_Fq) != E_OK)
11500aeed3e9SJustin Hibbits         RETURN_ERROR(MAJOR, E_INVALID_STATE, ("qman_oos_fq() failed!"));
11510aeed3e9SJustin Hibbits 
11520aeed3e9SJustin Hibbits     qman_destroy_fq(p_Fq,0);
11530aeed3e9SJustin Hibbits 
11540aeed3e9SJustin Hibbits     return E_OK;
11550aeed3e9SJustin Hibbits }
11560aeed3e9SJustin Hibbits 
qman_disable_portal(t_QmPortal * p_QmPortal)11570aeed3e9SJustin Hibbits static void qman_disable_portal(t_QmPortal *p_QmPortal)
11580aeed3e9SJustin Hibbits {
11590aeed3e9SJustin Hibbits     NCSW_PLOCK(p_QmPortal);
11600aeed3e9SJustin Hibbits     if (!(p_QmPortal->disable_count++))
11610aeed3e9SJustin Hibbits         qm_dqrr_set_maxfill(p_QmPortal->p_LowQmPortal, 0);
11620aeed3e9SJustin Hibbits     PUNLOCK(p_QmPortal);
11630aeed3e9SJustin Hibbits }
11640aeed3e9SJustin Hibbits 
11650aeed3e9SJustin Hibbits 
11660aeed3e9SJustin Hibbits /* quiesce SDQCR/VDQCR, then drain till h/w wraps up anything it
11670aeed3e9SJustin Hibbits  * was doing (5ms is more than enough to ensure it's done). */
clean_dqrr_mr(t_QmPortal * p_QmPortal)11680aeed3e9SJustin Hibbits static void clean_dqrr_mr(t_QmPortal *p_QmPortal)
11690aeed3e9SJustin Hibbits {
11700aeed3e9SJustin Hibbits     struct qm_dqrr_entry    *p_Dq;
11710aeed3e9SJustin Hibbits     struct qm_mr_entry      *p_Msg;
11720aeed3e9SJustin Hibbits     int                     idle = 0;
11730aeed3e9SJustin Hibbits 
11740aeed3e9SJustin Hibbits     qm_dqrr_sdqcr_set(p_QmPortal->p_LowQmPortal, 0);
11750aeed3e9SJustin Hibbits     qm_dqrr_vdqcr_set(p_QmPortal->p_LowQmPortal, 0);
11760aeed3e9SJustin Hibbits drain_loop:
11770aeed3e9SJustin Hibbits     qmPortalDqrrPvbPrefetch(p_QmPortal->p_LowQmPortal);
11780aeed3e9SJustin Hibbits     qmPortalDqrrPvbUpdate(p_QmPortal->p_LowQmPortal);
11790aeed3e9SJustin Hibbits     qmPortalMrPvbUpdate(p_QmPortal->p_LowQmPortal);
11800aeed3e9SJustin Hibbits     p_Dq = qm_dqrr_current(p_QmPortal->p_LowQmPortal);
11810aeed3e9SJustin Hibbits     p_Msg = qm_mr_current(p_QmPortal->p_LowQmPortal);
11820aeed3e9SJustin Hibbits     if (p_Dq) {
11830aeed3e9SJustin Hibbits         qm_dqrr_next(p_QmPortal->p_LowQmPortal);
11840aeed3e9SJustin Hibbits         qmPortalDqrrCciConsume(p_QmPortal->p_LowQmPortal, 1);
11850aeed3e9SJustin Hibbits     }
11860aeed3e9SJustin Hibbits     if (p_Msg) {
11870aeed3e9SJustin Hibbits     qm_mr_next(p_QmPortal->p_LowQmPortal);
11880aeed3e9SJustin Hibbits         qmPortalMrCciConsume(p_QmPortal->p_LowQmPortal, 1);
11890aeed3e9SJustin Hibbits     }
11900aeed3e9SJustin Hibbits     if (!p_Dq && !p_Msg) {
11910aeed3e9SJustin Hibbits     if (++idle < 5) {
11920aeed3e9SJustin Hibbits     XX_UDelay(1000);
11930aeed3e9SJustin Hibbits     goto drain_loop;
11940aeed3e9SJustin Hibbits     }
11950aeed3e9SJustin Hibbits     } else {
11960aeed3e9SJustin Hibbits     idle = 0;
11970aeed3e9SJustin Hibbits     goto drain_loop;
11980aeed3e9SJustin Hibbits     }
11990aeed3e9SJustin Hibbits }
12000aeed3e9SJustin Hibbits 
qman_create_portal(t_QmPortal * p_QmPortal,uint32_t flags,uint32_t sdqcrFlags,uint8_t dqrrSize)12010aeed3e9SJustin Hibbits static t_Error qman_create_portal(t_QmPortal *p_QmPortal,
12020aeed3e9SJustin Hibbits                                    uint32_t flags,
12030aeed3e9SJustin Hibbits                                    uint32_t sdqcrFlags,
12040aeed3e9SJustin Hibbits                                    uint8_t  dqrrSize)
12050aeed3e9SJustin Hibbits {
12060aeed3e9SJustin Hibbits     const struct qm_portal_config   *p_Config = &(p_QmPortal->p_LowQmPortal->config);
12070aeed3e9SJustin Hibbits     int                             ret = 0;
12080aeed3e9SJustin Hibbits     t_Error                         err;
12090aeed3e9SJustin Hibbits     uint32_t                        isdr;
12100aeed3e9SJustin Hibbits 
12110aeed3e9SJustin Hibbits     if ((err = qm_eqcr_init(p_QmPortal->p_LowQmPortal, e_QmPortalPVB, e_QmPortalEqcrCCE)) != E_OK)
12120aeed3e9SJustin Hibbits         RETURN_ERROR(MINOR, err, ("Qman EQCR initialization failed\n"));
12130aeed3e9SJustin Hibbits 
12140aeed3e9SJustin Hibbits     if (qm_dqrr_init(p_QmPortal->p_LowQmPortal,
12150aeed3e9SJustin Hibbits                      sdqcrFlags ? e_QmPortalDequeuePushMode : e_QmPortalDequeuePullMode,
12160aeed3e9SJustin Hibbits                      e_QmPortalPVB,
12170aeed3e9SJustin Hibbits                      (flags & QMAN_PORTAL_FLAG_DCA) ? e_QmPortalDqrrDCA : e_QmPortalDqrrCCI,
12180aeed3e9SJustin Hibbits                      dqrrSize,
12190aeed3e9SJustin Hibbits                      (flags & QMAN_PORTAL_FLAG_RSTASH) ? 1 : 0,
12200aeed3e9SJustin Hibbits                      (flags & QMAN_PORTAL_FLAG_DSTASH) ? 1 : 0)) {
12210aeed3e9SJustin Hibbits         REPORT_ERROR(MAJOR, E_INVALID_STATE, ("DQRR initialization failed"));
12220aeed3e9SJustin Hibbits         goto fail_dqrr;
12230aeed3e9SJustin Hibbits     }
12240aeed3e9SJustin Hibbits 
12250aeed3e9SJustin Hibbits     if (qm_mr_init(p_QmPortal->p_LowQmPortal, e_QmPortalPVB, e_QmPortalMrCCI)) {
12260aeed3e9SJustin Hibbits         REPORT_ERROR(MAJOR, E_INVALID_STATE, ("MR initialization failed"));
12270aeed3e9SJustin Hibbits         goto fail_mr;
12280aeed3e9SJustin Hibbits     }
12290aeed3e9SJustin Hibbits     if (qm_mc_init(p_QmPortal->p_LowQmPortal)) {
12300aeed3e9SJustin Hibbits         REPORT_ERROR(MAJOR, E_INVALID_STATE, ("MC initialization failed"));
12310aeed3e9SJustin Hibbits         goto fail_mc;
12320aeed3e9SJustin Hibbits     }
12330aeed3e9SJustin Hibbits     if (qm_isr_init(p_QmPortal->p_LowQmPortal)) {
12340aeed3e9SJustin Hibbits         REPORT_ERROR(MAJOR, E_INVALID_STATE, ("ISR initialization failed"));
12350aeed3e9SJustin Hibbits         goto fail_isr;
12360aeed3e9SJustin Hibbits     }
12370aeed3e9SJustin Hibbits     /* static interrupt-gating controls */
12380aeed3e9SJustin Hibbits     qm_dqrr_set_ithresh(p_QmPortal->p_LowQmPortal, 12);
12390aeed3e9SJustin Hibbits     qm_mr_set_ithresh(p_QmPortal->p_LowQmPortal, 4);
12400aeed3e9SJustin Hibbits     qm_isr_set_iperiod(p_QmPortal->p_LowQmPortal, 100);
12410aeed3e9SJustin Hibbits     p_QmPortal->options = flags;
12420aeed3e9SJustin Hibbits     isdr = 0xffffffff;
12430aeed3e9SJustin Hibbits     qm_isr_status_clear(p_QmPortal->p_LowQmPortal, 0xffffffff);
12440aeed3e9SJustin Hibbits     qm_isr_enable_write(p_QmPortal->p_LowQmPortal, DEFAULT_portalExceptions);
12450aeed3e9SJustin Hibbits     qm_isr_disable_write(p_QmPortal->p_LowQmPortal, isdr);
12460aeed3e9SJustin Hibbits     if (flags & QMAN_PORTAL_FLAG_IRQ)
12470aeed3e9SJustin Hibbits     {
12480aeed3e9SJustin Hibbits         XX_SetIntr(p_Config->irq, portal_isr, p_QmPortal);
12490aeed3e9SJustin Hibbits         XX_EnableIntr(p_Config->irq);
12500aeed3e9SJustin Hibbits         qm_isr_uninhibit(p_QmPortal->p_LowQmPortal);
12510aeed3e9SJustin Hibbits     } else
12520aeed3e9SJustin Hibbits         /* without IRQ, we can't block */
12530aeed3e9SJustin Hibbits         flags &= ~QMAN_PORTAL_FLAG_WAIT;
12540aeed3e9SJustin Hibbits     /* Need EQCR to be empty before continuing */
12550aeed3e9SJustin Hibbits     isdr ^= QM_PIRQ_EQCI;
12560aeed3e9SJustin Hibbits     qm_isr_disable_write(p_QmPortal->p_LowQmPortal, isdr);
12570aeed3e9SJustin Hibbits     ret = qm_eqcr_get_fill(p_QmPortal->p_LowQmPortal);
12580aeed3e9SJustin Hibbits     if (ret) {
12590aeed3e9SJustin Hibbits         REPORT_ERROR(MAJOR, E_INVALID_STATE, ("EQCR unclean"));
12600aeed3e9SJustin Hibbits         goto fail_eqcr_empty;
12610aeed3e9SJustin Hibbits     }
12620aeed3e9SJustin Hibbits     isdr ^= (QM_PIRQ_DQRI | QM_PIRQ_MRI);
12630aeed3e9SJustin Hibbits     qm_isr_disable_write(p_QmPortal->p_LowQmPortal, isdr);
12640aeed3e9SJustin Hibbits     if (qm_dqrr_current(p_QmPortal->p_LowQmPortal) != NULL)
12650aeed3e9SJustin Hibbits     {
12660aeed3e9SJustin Hibbits         REPORT_ERROR(MAJOR, E_INVALID_STATE, ("DQRR unclean"));
12670aeed3e9SJustin Hibbits goto fail_dqrr_mr_empty;
12680aeed3e9SJustin Hibbits     }
12690aeed3e9SJustin Hibbits     if (qm_mr_current(p_QmPortal->p_LowQmPortal) != NULL)
12700aeed3e9SJustin Hibbits     {
12710aeed3e9SJustin Hibbits         REPORT_ERROR(MAJOR, E_INVALID_STATE, ("MR unclean"));
12720aeed3e9SJustin Hibbits goto fail_dqrr_mr_empty;
12730aeed3e9SJustin Hibbits     }
12740aeed3e9SJustin Hibbits     qm_isr_disable_write(p_QmPortal->p_LowQmPortal, 0);
12750aeed3e9SJustin Hibbits     qm_dqrr_sdqcr_set(p_QmPortal->p_LowQmPortal, sdqcrFlags);
12760aeed3e9SJustin Hibbits     return E_OK;
12770aeed3e9SJustin Hibbits fail_dqrr_mr_empty:
12780aeed3e9SJustin Hibbits fail_eqcr_empty:
12790aeed3e9SJustin Hibbits     qm_isr_finish(p_QmPortal->p_LowQmPortal);
12800aeed3e9SJustin Hibbits fail_isr:
12810aeed3e9SJustin Hibbits     qm_mc_finish(p_QmPortal->p_LowQmPortal);
12820aeed3e9SJustin Hibbits fail_mc:
12830aeed3e9SJustin Hibbits     qm_mr_finish(p_QmPortal->p_LowQmPortal);
12840aeed3e9SJustin Hibbits fail_mr:
12850aeed3e9SJustin Hibbits     qm_dqrr_finish(p_QmPortal->p_LowQmPortal);
12860aeed3e9SJustin Hibbits fail_dqrr:
12870aeed3e9SJustin Hibbits     qm_eqcr_finish(p_QmPortal->p_LowQmPortal);
12880aeed3e9SJustin Hibbits     return ERROR_CODE(E_INVALID_STATE);
12890aeed3e9SJustin Hibbits }
12900aeed3e9SJustin Hibbits 
qman_destroy_portal(t_QmPortal * p_QmPortal)12910aeed3e9SJustin Hibbits static void qman_destroy_portal(t_QmPortal *p_QmPortal)
12920aeed3e9SJustin Hibbits {
12930aeed3e9SJustin Hibbits     /* NB we do this to "quiesce" EQCR. If we add enqueue-completions or
12940aeed3e9SJustin Hibbits      * something related to QM_PIRQ_EQCI, this may need fixing. */
12950aeed3e9SJustin Hibbits     qmPortalEqcrCceUpdate(p_QmPortal->p_LowQmPortal);
12960aeed3e9SJustin Hibbits     if (p_QmPortal->options & QMAN_PORTAL_FLAG_IRQ)
12970aeed3e9SJustin Hibbits     {
12980aeed3e9SJustin Hibbits         XX_DisableIntr(p_QmPortal->p_LowQmPortal->config.irq);
12990aeed3e9SJustin Hibbits         XX_FreeIntr(p_QmPortal->p_LowQmPortal->config.irq);
13000aeed3e9SJustin Hibbits     }
13010aeed3e9SJustin Hibbits     qm_isr_finish(p_QmPortal->p_LowQmPortal);
13020aeed3e9SJustin Hibbits     qm_mc_finish(p_QmPortal->p_LowQmPortal);
13030aeed3e9SJustin Hibbits     qm_mr_finish(p_QmPortal->p_LowQmPortal);
13040aeed3e9SJustin Hibbits     qm_dqrr_finish(p_QmPortal->p_LowQmPortal);
13050aeed3e9SJustin Hibbits     qm_eqcr_finish(p_QmPortal->p_LowQmPortal);
13060aeed3e9SJustin Hibbits }
13070aeed3e9SJustin Hibbits 
try_eq_start(t_QmPortal * p_QmPortal)13080aeed3e9SJustin Hibbits static inline struct qm_eqcr_entry *try_eq_start(t_QmPortal *p_QmPortal)
13090aeed3e9SJustin Hibbits {
13100aeed3e9SJustin Hibbits     struct qm_eqcr_entry    *p_Eq;
13110aeed3e9SJustin Hibbits     uint8_t                 avail;
13120aeed3e9SJustin Hibbits 
13130aeed3e9SJustin Hibbits     avail = qm_eqcr_get_avail(p_QmPortal->p_LowQmPortal);
13140aeed3e9SJustin Hibbits     if (avail == EQCR_THRESH)
13150aeed3e9SJustin Hibbits         qmPortalEqcrCcePrefetch(p_QmPortal->p_LowQmPortal);
13160aeed3e9SJustin Hibbits     else if (avail < EQCR_THRESH)
13170aeed3e9SJustin Hibbits             qmPortalEqcrCceUpdate(p_QmPortal->p_LowQmPortal);
13180aeed3e9SJustin Hibbits     p_Eq = qm_eqcr_start(p_QmPortal->p_LowQmPortal);
13190aeed3e9SJustin Hibbits 
13200aeed3e9SJustin Hibbits     return p_Eq;
13210aeed3e9SJustin Hibbits }
13220aeed3e9SJustin Hibbits 
13230aeed3e9SJustin Hibbits 
qman_orp_update(t_QmPortal * p_QmPortal,uint32_t orpId,uint16_t orpSeqnum,uint32_t flags)13240aeed3e9SJustin Hibbits static t_Error qman_orp_update(t_QmPortal   *p_QmPortal,
13250aeed3e9SJustin Hibbits                                uint32_t     orpId,
13260aeed3e9SJustin Hibbits                                uint16_t     orpSeqnum,
13270aeed3e9SJustin Hibbits                                uint32_t     flags)
13280aeed3e9SJustin Hibbits {
13290aeed3e9SJustin Hibbits     struct qm_eqcr_entry *p_Eq;
13300aeed3e9SJustin Hibbits 
13310aeed3e9SJustin Hibbits     NCSW_PLOCK(p_QmPortal);
13320aeed3e9SJustin Hibbits     p_Eq = try_eq_start(p_QmPortal);
13330aeed3e9SJustin Hibbits     if (!p_Eq)
13340aeed3e9SJustin Hibbits     {
13350aeed3e9SJustin Hibbits         PUNLOCK(p_QmPortal);
13360aeed3e9SJustin Hibbits         return ERROR_CODE(E_BUSY);
13370aeed3e9SJustin Hibbits     }
13380aeed3e9SJustin Hibbits 
13390aeed3e9SJustin Hibbits     if (flags & QMAN_ENQUEUE_FLAG_NESN)
13400aeed3e9SJustin Hibbits         orpSeqnum |= QM_EQCR_SEQNUM_NESN;
13410aeed3e9SJustin Hibbits     else
13420aeed3e9SJustin Hibbits         /* No need to check 4 QMAN_ENQUEUE_FLAG_HOLE */
13430aeed3e9SJustin Hibbits         orpSeqnum &= ~QM_EQCR_SEQNUM_NESN;
13440aeed3e9SJustin Hibbits     p_Eq->seqnum  = orpSeqnum;
13450aeed3e9SJustin Hibbits     p_Eq->orp     = orpId;
13460aeed3e9SJustin Hibbits qmPortalEqcrPvbCommit(p_QmPortal->p_LowQmPortal, (uint8_t)QM_EQCR_VERB_ORP);
13470aeed3e9SJustin Hibbits 
13480aeed3e9SJustin Hibbits     PUNLOCK(p_QmPortal);
13490aeed3e9SJustin Hibbits     return E_OK;
13500aeed3e9SJustin Hibbits }
13510aeed3e9SJustin Hibbits 
CheckStashParams(t_QmFqrParams * p_QmFqrParams)13520aeed3e9SJustin Hibbits static __inline__ t_Error CheckStashParams(t_QmFqrParams *p_QmFqrParams)
13530aeed3e9SJustin Hibbits {
13540aeed3e9SJustin Hibbits     ASSERT_COND(p_QmFqrParams);
13550aeed3e9SJustin Hibbits 
13560aeed3e9SJustin Hibbits     if (p_QmFqrParams->stashingParams.frameAnnotationSize > QM_CONTEXTA_MAX_STASH_SIZE)
13570aeed3e9SJustin Hibbits         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Frame Annotation Size Exceeded Max Stash Size(%d)", QM_CONTEXTA_MAX_STASH_SIZE));
13580aeed3e9SJustin Hibbits     if (p_QmFqrParams->stashingParams.frameDataSize > QM_CONTEXTA_MAX_STASH_SIZE)
13590aeed3e9SJustin Hibbits         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Frame Data Size Exceeded Max Stash Size(%d)", QM_CONTEXTA_MAX_STASH_SIZE));
13600aeed3e9SJustin Hibbits     if (p_QmFqrParams->stashingParams.fqContextSize > QM_CONTEXTA_MAX_STASH_SIZE)
13610aeed3e9SJustin Hibbits         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Frame Context Size Exceeded Max Stash Size(%d)", QM_CONTEXTA_MAX_STASH_SIZE));
13620aeed3e9SJustin Hibbits     if (p_QmFqrParams->stashingParams.fqContextSize)
13630aeed3e9SJustin Hibbits     {
13640aeed3e9SJustin Hibbits         if (!p_QmFqrParams->stashingParams.fqContextAddr)
13650aeed3e9SJustin Hibbits             RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("FQ Context Address Must be givven"));
13660aeed3e9SJustin Hibbits         if (!IS_ALIGNED(p_QmFqrParams->stashingParams.fqContextAddr, CACHELINE_SIZE))
13670aeed3e9SJustin Hibbits             RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("FQ Context Address Must be aligned to %d", CACHELINE_SIZE));
13680aeed3e9SJustin Hibbits         if (p_QmFqrParams->stashingParams.fqContextAddr & 0xffffff0000000000LL)
13690aeed3e9SJustin Hibbits             RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("FQ Context Address May be up to 40 bit"));
13700aeed3e9SJustin Hibbits     }
13710aeed3e9SJustin Hibbits 
13720aeed3e9SJustin Hibbits     return E_OK;
13730aeed3e9SJustin Hibbits }
13740aeed3e9SJustin Hibbits 
QmPortalRegisterCg(t_Handle h_QmPortal,t_Handle h_QmCg,uint8_t cgId)13750aeed3e9SJustin Hibbits static t_Error QmPortalRegisterCg(t_Handle h_QmPortal, t_Handle h_QmCg, uint8_t  cgId)
13760aeed3e9SJustin Hibbits {
13770aeed3e9SJustin Hibbits     t_QmPortal  *p_QmPortal = (t_QmPortal *)h_QmPortal;
13780aeed3e9SJustin Hibbits 
13790aeed3e9SJustin Hibbits     /* cgrs[0] is the mask of registered CG's*/
13800aeed3e9SJustin Hibbits     if(p_QmPortal->cgrs[0].q.__state[cgId/32] & (0x80000000 >> (cgId % 32)))
13810aeed3e9SJustin Hibbits         RETURN_ERROR(MINOR, E_BUSY, ("CG already used"));
13820aeed3e9SJustin Hibbits 
13830aeed3e9SJustin Hibbits     p_QmPortal->cgrs[0].q.__state[cgId/32] |=  0x80000000 >> (cgId % 32);
13840aeed3e9SJustin Hibbits     p_QmPortal->cgsHandles[cgId] = h_QmCg;
13850aeed3e9SJustin Hibbits 
13860aeed3e9SJustin Hibbits     return E_OK;
13870aeed3e9SJustin Hibbits }
13880aeed3e9SJustin Hibbits 
QmPortalUnregisterCg(t_Handle h_QmPortal,uint8_t cgId)13890aeed3e9SJustin Hibbits static t_Error QmPortalUnregisterCg(t_Handle h_QmPortal, uint8_t  cgId)
13900aeed3e9SJustin Hibbits {
13910aeed3e9SJustin Hibbits     t_QmPortal  *p_QmPortal = (t_QmPortal *)h_QmPortal;
13920aeed3e9SJustin Hibbits 
13930aeed3e9SJustin Hibbits     /* cgrs[0] is the mask of registered CG's*/
13940aeed3e9SJustin Hibbits     if(!(p_QmPortal->cgrs[0].q.__state[cgId/32] & (0x80000000 >> (cgId % 32))))
13950aeed3e9SJustin Hibbits         RETURN_ERROR(MINOR, E_BUSY, ("CG is not in use"));
13960aeed3e9SJustin Hibbits 
13970aeed3e9SJustin Hibbits     p_QmPortal->cgrs[0].q.__state[cgId/32] &=  ~0x80000000 >> (cgId % 32);
13980aeed3e9SJustin Hibbits     p_QmPortal->cgsHandles[cgId] = NULL;
13990aeed3e9SJustin Hibbits 
14000aeed3e9SJustin Hibbits     return E_OK;
14010aeed3e9SJustin Hibbits }
14020aeed3e9SJustin Hibbits 
QmPortalGetSwPortalId(t_Handle h_QmPortal)14030aeed3e9SJustin Hibbits static e_DpaaSwPortal QmPortalGetSwPortalId(t_Handle h_QmPortal)
14040aeed3e9SJustin Hibbits {
14050aeed3e9SJustin Hibbits     t_QmPortal *p_QmPortal = (t_QmPortal *)h_QmPortal;
14060aeed3e9SJustin Hibbits 
14070aeed3e9SJustin Hibbits     return (e_DpaaSwPortal)p_QmPortal->p_LowQmPortal->config.cpu;
14080aeed3e9SJustin Hibbits }
14090aeed3e9SJustin Hibbits 
CalcWredCurve(t_QmCgWredCurve * p_WredCurve,uint32_t * p_CurveWord)14100aeed3e9SJustin Hibbits static t_Error CalcWredCurve(t_QmCgWredCurve *p_WredCurve, uint32_t  *p_CurveWord)
14110aeed3e9SJustin Hibbits {
14120aeed3e9SJustin Hibbits     uint32_t    maxP, roundDown, roundUp, tmpA, tmpN;
14130aeed3e9SJustin Hibbits     uint32_t    ma=0, mn=0, slope, sa=0, sn=0, pn;
14140aeed3e9SJustin Hibbits     int         pres = 1000;
14150aeed3e9SJustin Hibbits     int         gap, tmp;
14160aeed3e9SJustin Hibbits 
14170aeed3e9SJustin Hibbits /*  TODO - change maxTh to uint64_t?
14180aeed3e9SJustin Hibbits    if(p_WredCurve->maxTh > (1<<39))
14190aeed3e9SJustin Hibbits         RETURN_ERROR(MINOR, E_INVALID_VALUE, ("maxTh is not in range"));*/
14200aeed3e9SJustin Hibbits 
14210aeed3e9SJustin Hibbits     /* express maxTh as ma*2^mn */
14220aeed3e9SJustin Hibbits      gap = (int)p_WredCurve->maxTh;
14230aeed3e9SJustin Hibbits      for (tmpA=0 ; tmpA<256; tmpA++ )
14240aeed3e9SJustin Hibbits          for (tmpN=0 ; tmpN<32; tmpN++ )
14250aeed3e9SJustin Hibbits          {
14260aeed3e9SJustin Hibbits              tmp = ABS((int)(p_WredCurve->maxTh - tmpA*(1<<tmpN)));
14270aeed3e9SJustin Hibbits              if (tmp < gap)
14280aeed3e9SJustin Hibbits              {
14290aeed3e9SJustin Hibbits                 ma = tmpA;
14300aeed3e9SJustin Hibbits                 mn = tmpN;
14310aeed3e9SJustin Hibbits                 gap = tmp;
14320aeed3e9SJustin Hibbits              }
14330aeed3e9SJustin Hibbits          }
14340aeed3e9SJustin Hibbits      ASSERT_COND(ma <256);
14350aeed3e9SJustin Hibbits      ASSERT_COND(mn <32);
14360aeed3e9SJustin Hibbits      p_WredCurve->maxTh = ma*(1<<mn);
14370aeed3e9SJustin Hibbits 
14380aeed3e9SJustin Hibbits      if(p_WredCurve->maxTh <= p_WredCurve->minTh)
14390aeed3e9SJustin Hibbits         RETURN_ERROR(MINOR, E_INVALID_VALUE, ("maxTh must be larger than minTh"));
14400aeed3e9SJustin Hibbits      if(p_WredCurve->probabilityDenominator > 64)
14410aeed3e9SJustin Hibbits         RETURN_ERROR(MINOR, E_INVALID_VALUE, ("probabilityDenominator mustn't be 1-64"));
14420aeed3e9SJustin Hibbits 
14430aeed3e9SJustin Hibbits     /* first we translate from Cisco probabilityDenominator
14440aeed3e9SJustin Hibbits        to 256 fixed denominator, result must be divisible by 4. */
14450aeed3e9SJustin Hibbits     /* we multiply by a fixed value to get better accuracy (without
14460aeed3e9SJustin Hibbits        using floating point) */
14470aeed3e9SJustin Hibbits     maxP = (uint32_t)(256*1000/p_WredCurve->probabilityDenominator);
14480aeed3e9SJustin Hibbits     if (maxP % 4*pres)
14490aeed3e9SJustin Hibbits     {
14500aeed3e9SJustin Hibbits         roundDown  = maxP + (maxP % (4*pres));
14510aeed3e9SJustin Hibbits         roundUp = roundDown + 4*pres;
14520aeed3e9SJustin Hibbits         if((roundUp - maxP) > (maxP - roundDown))
14530aeed3e9SJustin Hibbits             maxP = roundDown;
14540aeed3e9SJustin Hibbits         else
14550aeed3e9SJustin Hibbits             maxP = roundUp;
14560aeed3e9SJustin Hibbits     }
14570aeed3e9SJustin Hibbits     maxP = maxP/pres;
14580aeed3e9SJustin Hibbits     ASSERT_COND(maxP <= 256);
14590aeed3e9SJustin Hibbits     pn = (uint8_t)(maxP/4 - 1);
14600aeed3e9SJustin Hibbits 
14610aeed3e9SJustin Hibbits     if(maxP >= (p_WredCurve->maxTh - p_WredCurve->minTh))
14620aeed3e9SJustin Hibbits         RETURN_ERROR(MINOR, E_INVALID_VALUE, ("Due to probabilityDenominator selected, maxTh-minTh must be larger than %d", maxP));
14630aeed3e9SJustin Hibbits 
14640aeed3e9SJustin Hibbits     pres = 1000000;
14650aeed3e9SJustin Hibbits     slope = maxP*pres/(p_WredCurve->maxTh - p_WredCurve->minTh);
14660aeed3e9SJustin Hibbits     /* express slope as sa/2^sn */
14670aeed3e9SJustin Hibbits     gap = (int)slope;
14680aeed3e9SJustin Hibbits     for (tmpA=(uint32_t)(64*pres) ; tmpA<128*pres; tmpA += pres )
14690aeed3e9SJustin Hibbits         for (tmpN=7 ; tmpN<64; tmpN++ )
14700aeed3e9SJustin Hibbits         {
14713f791e31SGleb Popov             tmp = ABS((int)(slope - tmpA/(1UL<<(tmpN%32))));
14720aeed3e9SJustin Hibbits             if (tmp < gap)
14730aeed3e9SJustin Hibbits             {
14740aeed3e9SJustin Hibbits                sa = tmpA;
14750aeed3e9SJustin Hibbits                sn = tmpN;
14760aeed3e9SJustin Hibbits                gap = tmp;
14770aeed3e9SJustin Hibbits             }
14780aeed3e9SJustin Hibbits         }
14790aeed3e9SJustin Hibbits     sa = sa/pres;
14800aeed3e9SJustin Hibbits     ASSERT_COND(sa<128 && sa>=64);
14810aeed3e9SJustin Hibbits     ASSERT_COND(sn<64 && sn>=7);
14820aeed3e9SJustin Hibbits 
14830aeed3e9SJustin Hibbits     *p_CurveWord = ((ma << 24) |
14840aeed3e9SJustin Hibbits                     (mn << 19) |
14850aeed3e9SJustin Hibbits                     (sa << 12) |
14860aeed3e9SJustin Hibbits                     (sn << 6) |
14870aeed3e9SJustin Hibbits                     pn);
14880aeed3e9SJustin Hibbits 
14890aeed3e9SJustin Hibbits     return E_OK;
14900aeed3e9SJustin Hibbits }
14910aeed3e9SJustin Hibbits 
QmPortalPullFrame(t_Handle h_QmPortal,uint32_t pdqcr,t_DpaaFD * p_Frame)14920aeed3e9SJustin Hibbits static t_Error QmPortalPullFrame(t_Handle h_QmPortal, uint32_t pdqcr, t_DpaaFD *p_Frame)
14930aeed3e9SJustin Hibbits {
14940aeed3e9SJustin Hibbits     t_QmPortal              *p_QmPortal = (t_QmPortal *)h_QmPortal;
14950aeed3e9SJustin Hibbits     struct qm_dqrr_entry    *p_Dq;
14960aeed3e9SJustin Hibbits     int                     prefetch;
14970aeed3e9SJustin Hibbits     uint32_t                *p_Dst, *p_Src;
14980aeed3e9SJustin Hibbits 
14990aeed3e9SJustin Hibbits     ASSERT_COND(p_QmPortal);
15000aeed3e9SJustin Hibbits     ASSERT_COND(p_Frame);
15010aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR(p_QmPortal->pullMode, E_INVALID_STATE);
15020aeed3e9SJustin Hibbits 
15030aeed3e9SJustin Hibbits     NCSW_PLOCK(p_QmPortal);
15040aeed3e9SJustin Hibbits 
15050aeed3e9SJustin Hibbits     qm_dqrr_pdqcr_set(p_QmPortal->p_LowQmPortal, pdqcr);
1506852ba100SJustin Hibbits     mb();
15070aeed3e9SJustin Hibbits     while (qm_dqrr_pdqcr_get(p_QmPortal->p_LowQmPortal)) ;
15080aeed3e9SJustin Hibbits 
15090aeed3e9SJustin Hibbits     prefetch = !(p_QmPortal->options & QMAN_PORTAL_FLAG_RSTASH);
15100aeed3e9SJustin Hibbits     while(TRUE)
15110aeed3e9SJustin Hibbits     {
15120aeed3e9SJustin Hibbits         if (prefetch)
15130aeed3e9SJustin Hibbits             qmPortalDqrrPvbPrefetch(p_QmPortal->p_LowQmPortal);
15140aeed3e9SJustin Hibbits         qmPortalDqrrPvbUpdate(p_QmPortal->p_LowQmPortal);
15150aeed3e9SJustin Hibbits         p_Dq = qm_dqrr_current(p_QmPortal->p_LowQmPortal);
15160aeed3e9SJustin Hibbits         if (!p_Dq)
15170aeed3e9SJustin Hibbits             continue;
15180aeed3e9SJustin Hibbits         ASSERT_COND(p_Dq->fqid);
15190aeed3e9SJustin Hibbits         p_Dst = (uint32_t *)p_Frame;
15200aeed3e9SJustin Hibbits         p_Src = (uint32_t *)&p_Dq->fd;
15210aeed3e9SJustin Hibbits         p_Dst[0] = p_Src[0];
15220aeed3e9SJustin Hibbits         p_Dst[1] = p_Src[1];
15230aeed3e9SJustin Hibbits         p_Dst[2] = p_Src[2];
15240aeed3e9SJustin Hibbits         p_Dst[3] = p_Src[3];
15250aeed3e9SJustin Hibbits         if (p_QmPortal->options & QMAN_PORTAL_FLAG_DCA)
15260aeed3e9SJustin Hibbits         {
15270aeed3e9SJustin Hibbits             qmPortalDqrrDcaConsume1ptr(p_QmPortal->p_LowQmPortal,
15280aeed3e9SJustin Hibbits                                        p_Dq,
1529852ba100SJustin Hibbits                                        false);
15300aeed3e9SJustin Hibbits             qm_dqrr_next(p_QmPortal->p_LowQmPortal);
15310aeed3e9SJustin Hibbits         }
15320aeed3e9SJustin Hibbits         else
15330aeed3e9SJustin Hibbits         {
15340aeed3e9SJustin Hibbits             qm_dqrr_next(p_QmPortal->p_LowQmPortal);
15350aeed3e9SJustin Hibbits             qmPortalDqrrCciConsume(p_QmPortal->p_LowQmPortal, 1);
15360aeed3e9SJustin Hibbits         }
15370aeed3e9SJustin Hibbits         break;
15380aeed3e9SJustin Hibbits     }
15390aeed3e9SJustin Hibbits 
15400aeed3e9SJustin Hibbits     PUNLOCK(p_QmPortal);
15410aeed3e9SJustin Hibbits 
15420aeed3e9SJustin Hibbits     if (!(p_Dq->stat & QM_DQRR_STAT_FD_VALID))
15430aeed3e9SJustin Hibbits         return ERROR_CODE(E_EMPTY);
15440aeed3e9SJustin Hibbits 
15450aeed3e9SJustin Hibbits     return E_OK;
15460aeed3e9SJustin Hibbits }
15470aeed3e9SJustin Hibbits 
15480aeed3e9SJustin Hibbits 
15490aeed3e9SJustin Hibbits /****************************************/
15500aeed3e9SJustin Hibbits /*       API Init unit functions        */
15510aeed3e9SJustin Hibbits /****************************************/
QM_PORTAL_Config(t_QmPortalParam * p_QmPortalParam)15520aeed3e9SJustin Hibbits t_Handle QM_PORTAL_Config(t_QmPortalParam *p_QmPortalParam)
15530aeed3e9SJustin Hibbits {
15540aeed3e9SJustin Hibbits     t_QmPortal          *p_QmPortal;
15550aeed3e9SJustin Hibbits     uint32_t            i;
15560aeed3e9SJustin Hibbits 
15570aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_VALUE(p_QmPortalParam, E_INVALID_HANDLE, NULL);
15580aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_VALUE(p_QmPortalParam->swPortalId < DPAA_MAX_NUM_OF_SW_PORTALS, E_INVALID_VALUE, 0);
15590aeed3e9SJustin Hibbits 
15600aeed3e9SJustin Hibbits     p_QmPortal = (t_QmPortal *)XX_Malloc(sizeof(t_QmPortal));
15610aeed3e9SJustin Hibbits     if (!p_QmPortal)
15620aeed3e9SJustin Hibbits     {
15630aeed3e9SJustin Hibbits         REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Qm Portal obj!!!"));
15640aeed3e9SJustin Hibbits         return NULL;
15650aeed3e9SJustin Hibbits     }
15660aeed3e9SJustin Hibbits     memset(p_QmPortal, 0, sizeof(t_QmPortal));
15670aeed3e9SJustin Hibbits 
15680aeed3e9SJustin Hibbits     p_QmPortal->p_LowQmPortal = (struct qm_portal *)XX_Malloc(sizeof(struct qm_portal));
15690aeed3e9SJustin Hibbits     if (!p_QmPortal->p_LowQmPortal)
15700aeed3e9SJustin Hibbits     {
15710aeed3e9SJustin Hibbits         XX_Free(p_QmPortal);
15720aeed3e9SJustin Hibbits         REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Low qm p_QmPortal obj!!!"));
15730aeed3e9SJustin Hibbits         return NULL;
15740aeed3e9SJustin Hibbits     }
15750aeed3e9SJustin Hibbits     memset(p_QmPortal->p_LowQmPortal, 0, sizeof(struct qm_portal));
15760aeed3e9SJustin Hibbits 
15770aeed3e9SJustin Hibbits     p_QmPortal->p_QmPortalDriverParams = (t_QmPortalDriverParams *)XX_Malloc(sizeof(t_QmPortalDriverParams));
15780aeed3e9SJustin Hibbits     if (!p_QmPortal->p_QmPortalDriverParams)
15790aeed3e9SJustin Hibbits     {
15800aeed3e9SJustin Hibbits         XX_Free(p_QmPortal->p_LowQmPortal);
15810aeed3e9SJustin Hibbits         XX_Free(p_QmPortal);
15820aeed3e9SJustin Hibbits         REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Qm Portal driver parameters"));
15830aeed3e9SJustin Hibbits         return NULL;
15840aeed3e9SJustin Hibbits     }
15850aeed3e9SJustin Hibbits     memset(p_QmPortal->p_QmPortalDriverParams, 0, sizeof(t_QmPortalDriverParams));
15860aeed3e9SJustin Hibbits 
15870aeed3e9SJustin Hibbits     p_QmPortal->p_LowQmPortal->addr.addr_ce = UINT_TO_PTR(p_QmPortalParam->ceBaseAddress);
15880aeed3e9SJustin Hibbits     p_QmPortal->p_LowQmPortal->addr.addr_ci = UINT_TO_PTR(p_QmPortalParam->ciBaseAddress);
15890aeed3e9SJustin Hibbits     p_QmPortal->p_LowQmPortal->config.irq = p_QmPortalParam->irq;
15900aeed3e9SJustin Hibbits     p_QmPortal->p_LowQmPortal->config.bound = 0;
15910aeed3e9SJustin Hibbits     p_QmPortal->p_LowQmPortal->config.cpu = (int)p_QmPortalParam->swPortalId;
15920aeed3e9SJustin Hibbits     p_QmPortal->p_LowQmPortal->config.channel = (e_QmFQChannel)(e_QM_FQ_CHANNEL_SWPORTAL0 + p_QmPortalParam->swPortalId);
15930aeed3e9SJustin Hibbits     p_QmPortal->p_LowQmPortal->bind_lock = XX_InitSpinlock();
15940aeed3e9SJustin Hibbits 
15950aeed3e9SJustin Hibbits     p_QmPortal->h_Qm                = p_QmPortalParam->h_Qm;
15960aeed3e9SJustin Hibbits     p_QmPortal->f_DfltFrame         = p_QmPortalParam->f_DfltFrame;
15970aeed3e9SJustin Hibbits     p_QmPortal->f_RejectedFrame     = p_QmPortalParam->f_RejectedFrame;
15980aeed3e9SJustin Hibbits     p_QmPortal->h_App               = p_QmPortalParam->h_App;
15990aeed3e9SJustin Hibbits 
16000aeed3e9SJustin Hibbits     p_QmPortal->p_QmPortalDriverParams->fdLiodnOffset           = p_QmPortalParam->fdLiodnOffset;
16010aeed3e9SJustin Hibbits     p_QmPortal->p_QmPortalDriverParams->dequeueDcaMode          = DEFAULT_dequeueDcaMode;
16020aeed3e9SJustin Hibbits     p_QmPortal->p_QmPortalDriverParams->dequeueUpToThreeFrames  = DEFAULT_dequeueUpToThreeFrames;
16030aeed3e9SJustin Hibbits     p_QmPortal->p_QmPortalDriverParams->commandType             = DEFAULT_dequeueCommandType;
16040aeed3e9SJustin Hibbits     p_QmPortal->p_QmPortalDriverParams->userToken               = DEFAULT_dequeueUserToken;
16050aeed3e9SJustin Hibbits     p_QmPortal->p_QmPortalDriverParams->specifiedWq             = DEFAULT_dequeueSpecifiedWq;
16060aeed3e9SJustin Hibbits     p_QmPortal->p_QmPortalDriverParams->dedicatedChannel        = DEFAULT_dequeueDedicatedChannel;
16070aeed3e9SJustin Hibbits     p_QmPortal->p_QmPortalDriverParams->dedicatedChannelHasPrecedenceOverPoolChannels =
16080aeed3e9SJustin Hibbits         DEFAULT_dequeueDedicatedChannelHasPrecedenceOverPoolChannels;
16090aeed3e9SJustin Hibbits     p_QmPortal->p_QmPortalDriverParams->poolChannelId           = DEFAULT_dequeuePoolChannelId;
16100aeed3e9SJustin Hibbits     p_QmPortal->p_QmPortalDriverParams->wqId                    = DEFAULT_dequeueWqId;
16110aeed3e9SJustin Hibbits     for (i=0;i<QM_MAX_NUM_OF_POOL_CHANNELS;i++)
16120aeed3e9SJustin Hibbits         p_QmPortal->p_QmPortalDriverParams->poolChannels[i] = FALSE;
16130aeed3e9SJustin Hibbits     p_QmPortal->p_QmPortalDriverParams->dqrrSize                = DEFAULT_dqrrSize;
16140aeed3e9SJustin Hibbits     p_QmPortal->p_QmPortalDriverParams->pullMode                = DEFAULT_pullMode;
16150aeed3e9SJustin Hibbits 
16160aeed3e9SJustin Hibbits     return p_QmPortal;
16170aeed3e9SJustin Hibbits }
16180aeed3e9SJustin Hibbits 
QM_PORTAL_Init(t_Handle h_QmPortal)16190aeed3e9SJustin Hibbits t_Error QM_PORTAL_Init(t_Handle h_QmPortal)
16200aeed3e9SJustin Hibbits {
16210aeed3e9SJustin Hibbits     t_QmPortal                          *p_QmPortal = (t_QmPortal *)h_QmPortal;
16220aeed3e9SJustin Hibbits     uint32_t                            i, flags=0, sdqcrFlags=0;
16230aeed3e9SJustin Hibbits     t_Error                             err;
16240aeed3e9SJustin Hibbits     t_QmInterModulePortalInitParams     qmParams;
16250aeed3e9SJustin Hibbits 
16260aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR(p_QmPortal, E_INVALID_HANDLE);
16270aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR(p_QmPortal->p_QmPortalDriverParams, E_INVALID_HANDLE);
16280aeed3e9SJustin Hibbits 
16290aeed3e9SJustin Hibbits     memset(&qmParams, 0, sizeof(qmParams));
16300aeed3e9SJustin Hibbits     qmParams.portalId       = (uint8_t)p_QmPortal->p_LowQmPortal->config.cpu;
16310aeed3e9SJustin Hibbits     qmParams.liodn          = p_QmPortal->p_QmPortalDriverParams->fdLiodnOffset;
16320aeed3e9SJustin Hibbits     qmParams.dqrrLiodn      = p_QmPortal->p_QmPortalDriverParams->dqrrLiodn;
16330aeed3e9SJustin Hibbits     qmParams.fdFqLiodn      = p_QmPortal->p_QmPortalDriverParams->fdFqLiodn;
16340aeed3e9SJustin Hibbits     qmParams.stashDestQueue = p_QmPortal->p_QmPortalDriverParams->stashDestQueue;
16350aeed3e9SJustin Hibbits     if ((err = QmGetSetPortalParams(p_QmPortal->h_Qm, &qmParams)) != E_OK)
16360aeed3e9SJustin Hibbits         RETURN_ERROR(MAJOR, err, NO_MSG);
16370aeed3e9SJustin Hibbits 
16380aeed3e9SJustin Hibbits     flags = (uint32_t)(((p_QmPortal->p_LowQmPortal->config.irq == NO_IRQ) ?
16390aeed3e9SJustin Hibbits             0 :
16400aeed3e9SJustin Hibbits             (QMAN_PORTAL_FLAG_IRQ |
16410aeed3e9SJustin Hibbits              QMAN_PORTAL_FLAG_IRQ_FAST |
16420aeed3e9SJustin Hibbits              QMAN_PORTAL_FLAG_IRQ_SLOW)));
16430aeed3e9SJustin Hibbits     flags |= ((p_QmPortal->p_QmPortalDriverParams->dequeueDcaMode) ? QMAN_PORTAL_FLAG_DCA : 0);
16440aeed3e9SJustin Hibbits     flags |= (p_QmPortal->p_QmPortalDriverParams->dqrr)?QMAN_PORTAL_FLAG_RSTASH:0;
16450aeed3e9SJustin Hibbits     flags |= (p_QmPortal->p_QmPortalDriverParams->fdFq)?QMAN_PORTAL_FLAG_DSTASH:0;
16460aeed3e9SJustin Hibbits 
16470aeed3e9SJustin Hibbits     p_QmPortal->pullMode = p_QmPortal->p_QmPortalDriverParams->pullMode;
16480aeed3e9SJustin Hibbits     if (!p_QmPortal->pullMode)
16490aeed3e9SJustin Hibbits     {
16500aeed3e9SJustin Hibbits         sdqcrFlags |= (p_QmPortal->p_QmPortalDriverParams->dequeueUpToThreeFrames) ? QM_SDQCR_COUNT_UPTO3 : QM_SDQCR_COUNT_EXACT1;
16510aeed3e9SJustin Hibbits         sdqcrFlags |= QM_SDQCR_TOKEN_SET(p_QmPortal->p_QmPortalDriverParams->userToken);
16520aeed3e9SJustin Hibbits         sdqcrFlags |= QM_SDQCR_TYPE_SET(p_QmPortal->p_QmPortalDriverParams->commandType);
16530aeed3e9SJustin Hibbits         if (!p_QmPortal->p_QmPortalDriverParams->specifiedWq)
16540aeed3e9SJustin Hibbits         {
16550aeed3e9SJustin Hibbits             /* sdqcrFlags |= QM_SDQCR_SOURCE_CHANNELS;*/ /* removed as the macro is '0' */
16560aeed3e9SJustin Hibbits             sdqcrFlags |= (p_QmPortal->p_QmPortalDriverParams->dedicatedChannelHasPrecedenceOverPoolChannels) ? QM_SDQCR_DEDICATED_PRECEDENCE : 0;
16570aeed3e9SJustin Hibbits             sdqcrFlags |= (p_QmPortal->p_QmPortalDriverParams->dedicatedChannel) ? QM_SDQCR_CHANNELS_DEDICATED : 0;
16580aeed3e9SJustin Hibbits             for (i=0;i<QM_MAX_NUM_OF_POOL_CHANNELS;i++)
16590aeed3e9SJustin Hibbits                 sdqcrFlags |= ((p_QmPortal->p_QmPortalDriverParams->poolChannels[i]) ?
16600aeed3e9SJustin Hibbits                      QM_SDQCR_CHANNELS_POOL(i+1) : 0);
16610aeed3e9SJustin Hibbits         }
16620aeed3e9SJustin Hibbits         else
16630aeed3e9SJustin Hibbits         {
16640aeed3e9SJustin Hibbits             sdqcrFlags |= QM_SDQCR_SOURCE_SPECIFICWQ;
16650aeed3e9SJustin Hibbits             sdqcrFlags |= (p_QmPortal->p_QmPortalDriverParams->dedicatedChannel) ?
16660aeed3e9SJustin Hibbits                             QM_SDQCR_SPECIFICWQ_DEDICATED : QM_SDQCR_SPECIFICWQ_POOL(p_QmPortal->p_QmPortalDriverParams->poolChannelId);
16670aeed3e9SJustin Hibbits             sdqcrFlags |= QM_SDQCR_SPECIFICWQ_WQ(p_QmPortal->p_QmPortalDriverParams->wqId);
16680aeed3e9SJustin Hibbits         }
16690aeed3e9SJustin Hibbits     }
16700aeed3e9SJustin Hibbits     if ((flags & QMAN_PORTAL_FLAG_RSTASH) && (flags & QMAN_PORTAL_FLAG_DCA))
16710aeed3e9SJustin Hibbits         p_QmPortal->f_LoopDequeueRingCB = LoopDequeueRingDcaOptimized;
16720aeed3e9SJustin Hibbits     else if ((flags & QMAN_PORTAL_FLAG_RSTASH) && !(flags & QMAN_PORTAL_FLAG_DCA))
16730aeed3e9SJustin Hibbits         p_QmPortal->f_LoopDequeueRingCB = LoopDequeueRingOptimized;
16740aeed3e9SJustin Hibbits     else
16750aeed3e9SJustin Hibbits         p_QmPortal->f_LoopDequeueRingCB = LoopDequeueRing;
16760aeed3e9SJustin Hibbits 
16770aeed3e9SJustin Hibbits     if ((!p_QmPortal->f_RejectedFrame) || (!p_QmPortal->f_DfltFrame))
16780aeed3e9SJustin Hibbits         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("f_RejectedFrame or f_DfltFrame callback not provided"));
16790aeed3e9SJustin Hibbits 
16800aeed3e9SJustin Hibbits     p_QmPortal->p_NullCB = (struct qman_fq_cb *)XX_Malloc(sizeof(struct qman_fq_cb));
16810aeed3e9SJustin Hibbits     if (!p_QmPortal->p_NullCB)
16820aeed3e9SJustin Hibbits         RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FQ Null CB obj!!!"));
16830aeed3e9SJustin Hibbits     memset(p_QmPortal->p_NullCB, 0, sizeof(struct qman_fq_cb));
16840aeed3e9SJustin Hibbits 
16850aeed3e9SJustin Hibbits     p_QmPortal->p_NullCB->dqrr      = p_QmPortal->f_DfltFrame;
16860aeed3e9SJustin Hibbits     p_QmPortal->p_NullCB->ern       = p_QmPortal->f_RejectedFrame;
16870aeed3e9SJustin Hibbits     p_QmPortal->p_NullCB->dc_ern    = p_QmPortal->p_NullCB->fqs = null_cb_mr;
16880aeed3e9SJustin Hibbits 
16890aeed3e9SJustin Hibbits     if (qman_create_portal(p_QmPortal, flags, sdqcrFlags, p_QmPortal->p_QmPortalDriverParams->dqrrSize) != E_OK)
16900aeed3e9SJustin Hibbits     {
16910aeed3e9SJustin Hibbits         RETURN_ERROR(MAJOR, E_NO_MEMORY, ("create portal failed"));
16920aeed3e9SJustin Hibbits     }
16930aeed3e9SJustin Hibbits 
16940aeed3e9SJustin Hibbits     QmSetPortalHandle(p_QmPortal->h_Qm, (t_Handle)p_QmPortal, (e_DpaaSwPortal)p_QmPortal->p_LowQmPortal->config.cpu);
16950aeed3e9SJustin Hibbits     XX_Free(p_QmPortal->p_QmPortalDriverParams);
16960aeed3e9SJustin Hibbits     p_QmPortal->p_QmPortalDriverParams = NULL;
16970aeed3e9SJustin Hibbits 
16980aeed3e9SJustin Hibbits     DBG(TRACE, ("Qman-Portal %d @ %p:%p",
16990aeed3e9SJustin Hibbits                 p_QmPortal->p_LowQmPortal->config.cpu,
17000aeed3e9SJustin Hibbits                 p_QmPortal->p_LowQmPortal->addr.addr_ce,
17010aeed3e9SJustin Hibbits                 p_QmPortal->p_LowQmPortal->addr.addr_ci
17020aeed3e9SJustin Hibbits                 ));
17030aeed3e9SJustin Hibbits 
17040aeed3e9SJustin Hibbits     DBG(TRACE, ("Qman-Portal %d phys @ 0x%016llx:0x%016llx",
17050aeed3e9SJustin Hibbits                 p_QmPortal->p_LowQmPortal->config.cpu,
17060aeed3e9SJustin Hibbits                 (uint64_t)XX_VirtToPhys(p_QmPortal->p_LowQmPortal->addr.addr_ce),
17070aeed3e9SJustin Hibbits                 (uint64_t)XX_VirtToPhys(p_QmPortal->p_LowQmPortal->addr.addr_ci)
17080aeed3e9SJustin Hibbits                 ));
17090aeed3e9SJustin Hibbits 
17100aeed3e9SJustin Hibbits     return E_OK;
17110aeed3e9SJustin Hibbits }
17120aeed3e9SJustin Hibbits 
QM_PORTAL_Free(t_Handle h_QmPortal)17130aeed3e9SJustin Hibbits t_Error QM_PORTAL_Free(t_Handle h_QmPortal)
17140aeed3e9SJustin Hibbits {
17150aeed3e9SJustin Hibbits     t_QmPortal  *p_QmPortal = (t_QmPortal *)h_QmPortal;
17160aeed3e9SJustin Hibbits 
17170aeed3e9SJustin Hibbits     if (!p_QmPortal)
17180aeed3e9SJustin Hibbits        return ERROR_CODE(E_INVALID_HANDLE);
17190aeed3e9SJustin Hibbits 
17200aeed3e9SJustin Hibbits     ASSERT_COND(p_QmPortal->p_LowQmPortal);
17210aeed3e9SJustin Hibbits     QmSetPortalHandle(p_QmPortal->h_Qm, NULL, (e_DpaaSwPortal)p_QmPortal->p_LowQmPortal->config.cpu);
17220aeed3e9SJustin Hibbits     qman_destroy_portal(p_QmPortal);
17230aeed3e9SJustin Hibbits     if (p_QmPortal->p_NullCB)
17240aeed3e9SJustin Hibbits         XX_Free(p_QmPortal->p_NullCB);
17250aeed3e9SJustin Hibbits 
17260aeed3e9SJustin Hibbits     if (p_QmPortal->p_LowQmPortal->bind_lock)
17270aeed3e9SJustin Hibbits         XX_FreeSpinlock(p_QmPortal->p_LowQmPortal->bind_lock);
17280aeed3e9SJustin Hibbits     if(p_QmPortal->p_QmPortalDriverParams)
17290aeed3e9SJustin Hibbits         XX_Free(p_QmPortal->p_QmPortalDriverParams);
17300aeed3e9SJustin Hibbits     XX_Free(p_QmPortal->p_LowQmPortal);
17310aeed3e9SJustin Hibbits     XX_Free(p_QmPortal);
17320aeed3e9SJustin Hibbits 
17330aeed3e9SJustin Hibbits     return E_OK;
17340aeed3e9SJustin Hibbits }
17350aeed3e9SJustin Hibbits 
QM_PORTAL_ConfigDcaMode(t_Handle h_QmPortal,bool enable)17360aeed3e9SJustin Hibbits t_Error QM_PORTAL_ConfigDcaMode(t_Handle h_QmPortal, bool enable)
17370aeed3e9SJustin Hibbits {
17380aeed3e9SJustin Hibbits     t_QmPortal  *p_QmPortal = (t_QmPortal *)h_QmPortal;
17390aeed3e9SJustin Hibbits 
17400aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR(p_QmPortal, E_INVALID_HANDLE);
17410aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR(p_QmPortal->p_QmPortalDriverParams, E_INVALID_HANDLE);
17420aeed3e9SJustin Hibbits 
17430aeed3e9SJustin Hibbits     p_QmPortal->p_QmPortalDriverParams->dequeueDcaMode = enable;
17440aeed3e9SJustin Hibbits 
17450aeed3e9SJustin Hibbits     return E_OK;
17460aeed3e9SJustin Hibbits }
17470aeed3e9SJustin Hibbits 
QM_PORTAL_ConfigStash(t_Handle h_QmPortal,t_QmPortalStashParam * p_StashParams)17480aeed3e9SJustin Hibbits t_Error QM_PORTAL_ConfigStash(t_Handle h_QmPortal, t_QmPortalStashParam *p_StashParams)
17490aeed3e9SJustin Hibbits {
17500aeed3e9SJustin Hibbits     t_QmPortal  *p_QmPortal = (t_QmPortal *)h_QmPortal;
17510aeed3e9SJustin Hibbits 
17520aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR(p_QmPortal, E_INVALID_HANDLE);
17530aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR(p_QmPortal->p_QmPortalDriverParams, E_NULL_POINTER);
17540aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR(p_StashParams, E_NULL_POINTER);
17550aeed3e9SJustin Hibbits 
17560aeed3e9SJustin Hibbits     p_QmPortal->p_QmPortalDriverParams->stashDestQueue  = p_StashParams->stashDestQueue;
17570aeed3e9SJustin Hibbits     p_QmPortal->p_QmPortalDriverParams->dqrrLiodn       = p_StashParams->dqrrLiodn;
17580aeed3e9SJustin Hibbits     p_QmPortal->p_QmPortalDriverParams->fdFqLiodn       = p_StashParams->fdFqLiodn;
17590aeed3e9SJustin Hibbits     p_QmPortal->p_QmPortalDriverParams->eqcr            = p_StashParams->eqcr;
17600aeed3e9SJustin Hibbits     p_QmPortal->p_QmPortalDriverParams->eqcrHighPri     = p_StashParams->eqcrHighPri;
17610aeed3e9SJustin Hibbits     p_QmPortal->p_QmPortalDriverParams->dqrr            = p_StashParams->dqrr;
17620aeed3e9SJustin Hibbits     p_QmPortal->p_QmPortalDriverParams->dqrrHighPri     = p_StashParams->dqrrHighPri;
17630aeed3e9SJustin Hibbits     p_QmPortal->p_QmPortalDriverParams->fdFq            = p_StashParams->fdFq;
17640aeed3e9SJustin Hibbits     p_QmPortal->p_QmPortalDriverParams->fdFqHighPri     = p_StashParams->fdFqHighPri;
17650aeed3e9SJustin Hibbits     p_QmPortal->p_QmPortalDriverParams->fdFqDrop        = p_StashParams->fdFqDrop;
17660aeed3e9SJustin Hibbits 
17670aeed3e9SJustin Hibbits     return E_OK;
17680aeed3e9SJustin Hibbits }
17690aeed3e9SJustin Hibbits 
17700aeed3e9SJustin Hibbits 
QM_PORTAL_ConfigPullMode(t_Handle h_QmPortal,bool pullMode)17710aeed3e9SJustin Hibbits t_Error QM_PORTAL_ConfigPullMode(t_Handle h_QmPortal, bool pullMode)
17720aeed3e9SJustin Hibbits {
17730aeed3e9SJustin Hibbits     t_QmPortal  *p_QmPortal = (t_QmPortal *)h_QmPortal;
17740aeed3e9SJustin Hibbits 
17750aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR(p_QmPortal, E_INVALID_HANDLE);
17760aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR(p_QmPortal->p_QmPortalDriverParams, E_NULL_POINTER);
17770aeed3e9SJustin Hibbits 
17780aeed3e9SJustin Hibbits     p_QmPortal->p_QmPortalDriverParams->pullMode  = pullMode;
17790aeed3e9SJustin Hibbits 
17800aeed3e9SJustin Hibbits     return E_OK;
17810aeed3e9SJustin Hibbits }
17820aeed3e9SJustin Hibbits 
QM_PORTAL_AddPoolChannel(t_Handle h_QmPortal,uint8_t poolChannelId)17830aeed3e9SJustin Hibbits t_Error QM_PORTAL_AddPoolChannel(t_Handle h_QmPortal, uint8_t poolChannelId)
17840aeed3e9SJustin Hibbits {
17850aeed3e9SJustin Hibbits     t_QmPortal  *p_QmPortal = (t_QmPortal *)h_QmPortal;
17860aeed3e9SJustin Hibbits     uint32_t    sdqcrFlags;
17870aeed3e9SJustin Hibbits 
17880aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR(p_QmPortal, E_INVALID_HANDLE);
17890aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR((poolChannelId < QM_MAX_NUM_OF_POOL_CHANNELS), E_INVALID_VALUE);
17900aeed3e9SJustin Hibbits 
17910aeed3e9SJustin Hibbits     sdqcrFlags = qm_dqrr_sdqcr_get(p_QmPortal->p_LowQmPortal);
17920aeed3e9SJustin Hibbits     sdqcrFlags |= QM_SDQCR_CHANNELS_POOL(poolChannelId+1);
17930aeed3e9SJustin Hibbits     qm_dqrr_sdqcr_set(p_QmPortal->p_LowQmPortal, sdqcrFlags);
17940aeed3e9SJustin Hibbits 
17950aeed3e9SJustin Hibbits     return E_OK;
17960aeed3e9SJustin Hibbits }
17970aeed3e9SJustin Hibbits 
QM_PORTAL_Poll(t_Handle h_QmPortal,e_QmPortalPollSource source)17980aeed3e9SJustin Hibbits t_Error QM_PORTAL_Poll(t_Handle h_QmPortal, e_QmPortalPollSource source)
17990aeed3e9SJustin Hibbits {
18000aeed3e9SJustin Hibbits     t_QmPortal  *p_QmPortal = (t_QmPortal *)h_QmPortal;
18010aeed3e9SJustin Hibbits 
18020aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR(p_QmPortal, E_INVALID_HANDLE);
18030aeed3e9SJustin Hibbits 
18040aeed3e9SJustin Hibbits     NCSW_PLOCK(p_QmPortal);
18050aeed3e9SJustin Hibbits 
18060aeed3e9SJustin Hibbits     if ((source == e_QM_PORTAL_POLL_SOURCE_CONTROL_FRAMES) ||
18070aeed3e9SJustin Hibbits         (source == e_QM_PORTAL_POLL_SOURCE_BOTH))
18080aeed3e9SJustin Hibbits     {
18090aeed3e9SJustin Hibbits         uint32_t is = qm_isr_status_read(p_QmPortal->p_LowQmPortal);
18100aeed3e9SJustin Hibbits         uint32_t active = LoopMessageRing(p_QmPortal, is);
18110aeed3e9SJustin Hibbits         if (active)
18120aeed3e9SJustin Hibbits             qm_isr_status_clear(p_QmPortal->p_LowQmPortal, active);
18130aeed3e9SJustin Hibbits     }
18140aeed3e9SJustin Hibbits     if ((source == e_QM_PORTAL_POLL_SOURCE_DATA_FRAMES) ||
18150aeed3e9SJustin Hibbits         (source == e_QM_PORTAL_POLL_SOURCE_BOTH))
18160aeed3e9SJustin Hibbits         p_QmPortal->f_LoopDequeueRingCB((t_Handle)p_QmPortal);
18170aeed3e9SJustin Hibbits 
18180aeed3e9SJustin Hibbits     PUNLOCK(p_QmPortal);
18190aeed3e9SJustin Hibbits 
18200aeed3e9SJustin Hibbits     return E_OK;
18210aeed3e9SJustin Hibbits }
18220aeed3e9SJustin Hibbits 
QM_PORTAL_PollFrame(t_Handle h_QmPortal,t_QmPortalFrameInfo * p_frameInfo)18230aeed3e9SJustin Hibbits t_Error QM_PORTAL_PollFrame(t_Handle h_QmPortal, t_QmPortalFrameInfo *p_frameInfo)
18240aeed3e9SJustin Hibbits {
18250aeed3e9SJustin Hibbits     t_QmPortal              *p_QmPortal     = (t_QmPortal *)h_QmPortal;
18260aeed3e9SJustin Hibbits     struct qm_dqrr_entry    *p_Dq;
18270aeed3e9SJustin Hibbits     struct qman_fq          *p_Fq;
18280aeed3e9SJustin Hibbits     int                     prefetch;
18290aeed3e9SJustin Hibbits 
18300aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR(p_QmPortal, E_INVALID_HANDLE);
18310aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR(p_frameInfo, E_NULL_POINTER);
18320aeed3e9SJustin Hibbits 
18330aeed3e9SJustin Hibbits     NCSW_PLOCK(p_QmPortal);
18340aeed3e9SJustin Hibbits 
18350aeed3e9SJustin Hibbits     prefetch = !(p_QmPortal->options & QMAN_PORTAL_FLAG_RSTASH);
18360aeed3e9SJustin Hibbits     if (prefetch)
18370aeed3e9SJustin Hibbits         qmPortalDqrrPvbPrefetch(p_QmPortal->p_LowQmPortal);
18380aeed3e9SJustin Hibbits     qmPortalDqrrPvbUpdate(p_QmPortal->p_LowQmPortal);
18390aeed3e9SJustin Hibbits     p_Dq = qm_dqrr_current(p_QmPortal->p_LowQmPortal);
18400aeed3e9SJustin Hibbits     if (!p_Dq)
18410aeed3e9SJustin Hibbits     {
18420aeed3e9SJustin Hibbits         PUNLOCK(p_QmPortal);
18430aeed3e9SJustin Hibbits         return ERROR_CODE(E_EMPTY);
18440aeed3e9SJustin Hibbits     }
1845852ba100SJustin Hibbits     p_Fq = ptr_from_aligned_int(p_Dq->contextB);
18460aeed3e9SJustin Hibbits     ASSERT_COND(p_Dq->fqid);
18470aeed3e9SJustin Hibbits     if (p_Fq)
18480aeed3e9SJustin Hibbits     {
18490aeed3e9SJustin Hibbits         p_frameInfo->h_App = p_Fq->h_App;
18500aeed3e9SJustin Hibbits         p_frameInfo->h_QmFqr = p_Fq->h_QmFqr;
18510aeed3e9SJustin Hibbits         p_frameInfo->fqidOffset = p_Fq->fqidOffset;
18520aeed3e9SJustin Hibbits         memcpy((void*)&p_frameInfo->frame, (void*)&p_Dq->fd, sizeof(t_DpaaFD));
18530aeed3e9SJustin Hibbits     }
18540aeed3e9SJustin Hibbits     else
18550aeed3e9SJustin Hibbits     {
18560aeed3e9SJustin Hibbits         p_frameInfo->h_App = p_QmPortal->h_App;
18570aeed3e9SJustin Hibbits         p_frameInfo->h_QmFqr = NULL;
18580aeed3e9SJustin Hibbits         p_frameInfo->fqidOffset = p_Dq->fqid;
18590aeed3e9SJustin Hibbits         memcpy((void*)&p_frameInfo->frame, (void*)&p_Dq->fd, sizeof(t_DpaaFD));
18600aeed3e9SJustin Hibbits     }
18610aeed3e9SJustin Hibbits     if (p_QmPortal->options & QMAN_PORTAL_FLAG_DCA) {
18620aeed3e9SJustin Hibbits         qmPortalDqrrDcaConsume1ptr(p_QmPortal->p_LowQmPortal,
18630aeed3e9SJustin Hibbits                                    p_Dq,
1864852ba100SJustin Hibbits                                    false);
18650aeed3e9SJustin Hibbits         qm_dqrr_next(p_QmPortal->p_LowQmPortal);
18660aeed3e9SJustin Hibbits     } else {
18670aeed3e9SJustin Hibbits         qm_dqrr_next(p_QmPortal->p_LowQmPortal);
18680aeed3e9SJustin Hibbits         qmPortalDqrrCciConsume(p_QmPortal->p_LowQmPortal, 1);
18690aeed3e9SJustin Hibbits     }
18700aeed3e9SJustin Hibbits 
18710aeed3e9SJustin Hibbits     PUNLOCK(p_QmPortal);
18720aeed3e9SJustin Hibbits 
18730aeed3e9SJustin Hibbits     return E_OK;
18740aeed3e9SJustin Hibbits }
18750aeed3e9SJustin Hibbits 
18760aeed3e9SJustin Hibbits 
QM_FQR_Create(t_QmFqrParams * p_QmFqrParams)18770aeed3e9SJustin Hibbits t_Handle QM_FQR_Create(t_QmFqrParams *p_QmFqrParams)
18780aeed3e9SJustin Hibbits {
18790aeed3e9SJustin Hibbits     t_QmFqr             *p_QmFqr;
18800aeed3e9SJustin Hibbits     uint32_t            i, flags = 0;
18810aeed3e9SJustin Hibbits     u_QmFqdContextA     cnxtA;
18820aeed3e9SJustin Hibbits 
18830aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_VALUE(p_QmFqrParams, E_INVALID_HANDLE, NULL);
18840aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_VALUE(p_QmFqrParams->h_Qm, E_INVALID_HANDLE, NULL);
18850aeed3e9SJustin Hibbits 
18860aeed3e9SJustin Hibbits     if (p_QmFqrParams->shadowMode &&
18870aeed3e9SJustin Hibbits         (!p_QmFqrParams->useForce || p_QmFqrParams->numOfFqids != 1))
18880aeed3e9SJustin Hibbits     {
18890aeed3e9SJustin Hibbits         REPORT_ERROR(MAJOR, E_CONFLICT, ("shadowMode must be use with useForce and numOfFqids==1!!!"));
18900aeed3e9SJustin Hibbits         return NULL;
18910aeed3e9SJustin Hibbits     }
18920aeed3e9SJustin Hibbits 
18930aeed3e9SJustin Hibbits     p_QmFqr = (t_QmFqr *)XX_MallocSmart(sizeof(t_QmFqr), 0, 64);
18940aeed3e9SJustin Hibbits     if (!p_QmFqr)
18950aeed3e9SJustin Hibbits     {
18960aeed3e9SJustin Hibbits         REPORT_ERROR(MAJOR, E_NO_MEMORY, ("QM FQR obj!!!"));
18970aeed3e9SJustin Hibbits         return NULL;
18980aeed3e9SJustin Hibbits     }
18990aeed3e9SJustin Hibbits     memset(p_QmFqr, 0, sizeof(t_QmFqr));
19000aeed3e9SJustin Hibbits 
19010aeed3e9SJustin Hibbits     p_QmFqr->h_Qm       = p_QmFqrParams->h_Qm;
19020aeed3e9SJustin Hibbits     p_QmFqr->h_QmPortal = p_QmFqrParams->h_QmPortal;
19030aeed3e9SJustin Hibbits     p_QmFqr->shadowMode = p_QmFqrParams->shadowMode;
19040aeed3e9SJustin Hibbits     p_QmFqr->numOfFqids = (p_QmFqrParams->useForce && !p_QmFqrParams->numOfFqids) ?
19050aeed3e9SJustin Hibbits                               1 : p_QmFqrParams->numOfFqids;
19060aeed3e9SJustin Hibbits 
19070aeed3e9SJustin Hibbits     if (!p_QmFqr->h_QmPortal)
19080aeed3e9SJustin Hibbits     {
19090aeed3e9SJustin Hibbits         p_QmFqr->h_QmPortal = QmGetPortalHandle(p_QmFqr->h_Qm);
19100aeed3e9SJustin Hibbits         SANITY_CHECK_RETURN_VALUE(p_QmFqr->h_QmPortal, E_INVALID_HANDLE, NULL);
19110aeed3e9SJustin Hibbits     }
19120aeed3e9SJustin Hibbits 
19130aeed3e9SJustin Hibbits     p_QmFqr->p_Fqs = (struct qman_fq **)XX_Malloc(sizeof(struct qman_fq *) * p_QmFqr->numOfFqids);
19140aeed3e9SJustin Hibbits     if (!p_QmFqr->p_Fqs)
19150aeed3e9SJustin Hibbits     {
19160aeed3e9SJustin Hibbits         REPORT_ERROR(MAJOR, E_NO_MEMORY, ("QM FQs obj!!!"));
19170aeed3e9SJustin Hibbits         QM_FQR_Free(p_QmFqr);
19180aeed3e9SJustin Hibbits         return NULL;
19190aeed3e9SJustin Hibbits     }
19200aeed3e9SJustin Hibbits     memset(p_QmFqr->p_Fqs, 0, sizeof(struct qman_fq *) * p_QmFqr->numOfFqids);
19210aeed3e9SJustin Hibbits 
19220aeed3e9SJustin Hibbits     if (p_QmFqr->shadowMode)
19230aeed3e9SJustin Hibbits     {
19240aeed3e9SJustin Hibbits         struct qman_fq          *p_Fq = NULL;
19250aeed3e9SJustin Hibbits 
19260aeed3e9SJustin Hibbits         p_QmFqr->fqidBase = p_QmFqrParams->qs.frcQ.fqid;
19270aeed3e9SJustin Hibbits         p_Fq = (struct qman_fq *)XX_MallocSmart(sizeof(struct qman_fq), 0, 64);
19280aeed3e9SJustin Hibbits         if (!p_Fq)
19290aeed3e9SJustin Hibbits         {
19300aeed3e9SJustin Hibbits             REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FQ obj!!!"));
19310aeed3e9SJustin Hibbits             QM_FQR_Free(p_QmFqr);
19320aeed3e9SJustin Hibbits             return NULL;
19330aeed3e9SJustin Hibbits         }
19340aeed3e9SJustin Hibbits         memset(p_Fq, 0, sizeof(struct qman_fq));
19350aeed3e9SJustin Hibbits         p_Fq->cb.dqrr     = ((t_QmPortal*)p_QmFqr->h_QmPortal)->f_DfltFrame;
19360aeed3e9SJustin Hibbits         p_Fq->cb.ern      = ((t_QmPortal*)p_QmFqr->h_QmPortal)->f_RejectedFrame;
19370aeed3e9SJustin Hibbits         p_Fq->cb.dc_ern   = cb_ern_dcErn;
19380aeed3e9SJustin Hibbits         p_Fq->cb.fqs      = cb_fqs;
19390aeed3e9SJustin Hibbits         p_Fq->h_App       = ((t_QmPortal*)p_QmFqr->h_QmPortal)->h_App;
19400aeed3e9SJustin Hibbits         p_Fq->h_QmFqr     = p_QmFqr;
19410aeed3e9SJustin Hibbits         p_Fq->state       = qman_fq_state_sched;
19420aeed3e9SJustin Hibbits         p_Fq->fqid        = p_QmFqr->fqidBase;
19430aeed3e9SJustin Hibbits         p_QmFqr->p_Fqs[0] = p_Fq;
19440aeed3e9SJustin Hibbits     }
19450aeed3e9SJustin Hibbits     else
19460aeed3e9SJustin Hibbits     {
19470aeed3e9SJustin Hibbits         p_QmFqr->channel    = p_QmFqrParams->channel;
19480aeed3e9SJustin Hibbits         p_QmFqr->workQueue  = p_QmFqrParams->wq;
19490aeed3e9SJustin Hibbits 
19500aeed3e9SJustin Hibbits         p_QmFqr->fqidBase = QmFqidGet(p_QmFqr->h_Qm,
19510aeed3e9SJustin Hibbits                                       p_QmFqr->numOfFqids,
19520aeed3e9SJustin Hibbits                                       p_QmFqrParams->qs.nonFrcQs.align,
19530aeed3e9SJustin Hibbits                                       p_QmFqrParams->useForce,
19540aeed3e9SJustin Hibbits                                       p_QmFqrParams->qs.frcQ.fqid);
19550aeed3e9SJustin Hibbits         if (p_QmFqr->fqidBase == (uint32_t)ILLEGAL_BASE)
19560aeed3e9SJustin Hibbits         {
19570aeed3e9SJustin Hibbits             REPORT_ERROR(CRITICAL,E_INVALID_STATE,("can't allocate a fqid"));
19580aeed3e9SJustin Hibbits             QM_FQR_Free(p_QmFqr);
19590aeed3e9SJustin Hibbits             return NULL;
19600aeed3e9SJustin Hibbits         }
19610aeed3e9SJustin Hibbits 
19620aeed3e9SJustin Hibbits         if(p_QmFqrParams->congestionAvoidanceEnable &&
19630aeed3e9SJustin Hibbits             (p_QmFqrParams->congestionAvoidanceParams.h_QmCg == NULL) &&
19640aeed3e9SJustin Hibbits             (p_QmFqrParams->congestionAvoidanceParams.fqTailDropThreshold == 0))
19650aeed3e9SJustin Hibbits         {
19660aeed3e9SJustin Hibbits             REPORT_ERROR(CRITICAL,E_INVALID_STATE,("NULL congestion group handle and no FQ Threshold"));
19670aeed3e9SJustin Hibbits             QM_FQR_Free(p_QmFqr);
19680aeed3e9SJustin Hibbits             return NULL;
19690aeed3e9SJustin Hibbits         }
19700aeed3e9SJustin Hibbits         if(p_QmFqrParams->congestionAvoidanceEnable)
19710aeed3e9SJustin Hibbits         {
19720aeed3e9SJustin Hibbits             if(p_QmFqrParams->congestionAvoidanceParams.h_QmCg)
19730aeed3e9SJustin Hibbits                 flags |= QM_FQCTRL_CGE;
19740aeed3e9SJustin Hibbits             if(p_QmFqrParams->congestionAvoidanceParams.fqTailDropThreshold)
19750aeed3e9SJustin Hibbits                 flags |= QM_FQCTRL_TDE;
19760aeed3e9SJustin Hibbits         }
19770aeed3e9SJustin Hibbits 
19780aeed3e9SJustin Hibbits     /*
19790aeed3e9SJustin Hibbits         flags |= (p_QmFqrParams->holdActive)    ? QM_FQCTRL_ORP : 0;
19800aeed3e9SJustin Hibbits         flags |= (p_QmFqrParams->holdActive)    ? QM_FQCTRL_CPCSTASH : 0;
19810aeed3e9SJustin Hibbits         flags |= (p_QmFqrParams->holdActive)    ? QM_FQCTRL_FORCESFDR : 0;
19820aeed3e9SJustin Hibbits         flags |= (p_QmFqrParams->holdActive)    ? QM_FQCTRL_AVOIDBLOCK : 0;
19830aeed3e9SJustin Hibbits     */
19840aeed3e9SJustin Hibbits         flags |= (p_QmFqrParams->holdActive)    ? QM_FQCTRL_HOLDACTIVE : 0;
19850aeed3e9SJustin Hibbits         flags |= (p_QmFqrParams->preferInCache) ? QM_FQCTRL_LOCKINCACHE : 0;
19860aeed3e9SJustin Hibbits 
19870aeed3e9SJustin Hibbits         if (p_QmFqrParams->useContextAForStash)
19880aeed3e9SJustin Hibbits         {
19890aeed3e9SJustin Hibbits             if (CheckStashParams(p_QmFqrParams) != E_OK)
19900aeed3e9SJustin Hibbits             {
19910aeed3e9SJustin Hibbits                 REPORT_ERROR(CRITICAL,E_INVALID_STATE,NO_MSG);
19920aeed3e9SJustin Hibbits                 QM_FQR_Free(p_QmFqr);
19930aeed3e9SJustin Hibbits                 return NULL;
19940aeed3e9SJustin Hibbits             }
19950aeed3e9SJustin Hibbits 
19960aeed3e9SJustin Hibbits             memset(&cnxtA, 0, sizeof(cnxtA));
19970aeed3e9SJustin Hibbits             cnxtA.stashing.annotation_cl = DIV_CEIL(p_QmFqrParams->stashingParams.frameAnnotationSize, CACHELINE_SIZE);
19980aeed3e9SJustin Hibbits             cnxtA.stashing.data_cl = DIV_CEIL(p_QmFqrParams->stashingParams.frameDataSize, CACHELINE_SIZE);
19990aeed3e9SJustin Hibbits             cnxtA.stashing.context_cl = DIV_CEIL(p_QmFqrParams->stashingParams.fqContextSize, CACHELINE_SIZE);
20000aeed3e9SJustin Hibbits             cnxtA.context_hi = (uint8_t)((p_QmFqrParams->stashingParams.fqContextAddr >> 32) & 0xff);
20010aeed3e9SJustin Hibbits             cnxtA.context_lo = (uint32_t)(p_QmFqrParams->stashingParams.fqContextAddr);
20020aeed3e9SJustin Hibbits             flags |= QM_FQCTRL_CTXASTASHING;
20030aeed3e9SJustin Hibbits         }
20040aeed3e9SJustin Hibbits 
20050aeed3e9SJustin Hibbits         for(i=0;i<p_QmFqr->numOfFqids;i++)
20060aeed3e9SJustin Hibbits             if (qm_new_fq(p_QmFqr->h_QmPortal,
20070aeed3e9SJustin Hibbits                           p_QmFqr->fqidBase+i,
20080aeed3e9SJustin Hibbits                           i,
20090aeed3e9SJustin Hibbits                           p_QmFqr->channel,
20100aeed3e9SJustin Hibbits                           p_QmFqr->workQueue,
20110aeed3e9SJustin Hibbits                           1/*p_QmFqr->numOfFqids*/,
20120aeed3e9SJustin Hibbits                           flags,
20130aeed3e9SJustin Hibbits                           (p_QmFqrParams->congestionAvoidanceEnable ?
20140aeed3e9SJustin Hibbits                               &p_QmFqrParams->congestionAvoidanceParams : NULL),
20150aeed3e9SJustin Hibbits                           p_QmFqrParams->useContextAForStash ?
20160aeed3e9SJustin Hibbits                               (t_QmContextA *)&cnxtA : p_QmFqrParams->p_ContextA,
20170aeed3e9SJustin Hibbits                           p_QmFqrParams->p_ContextB,
20180aeed3e9SJustin Hibbits                           p_QmFqrParams->initParked,
20190aeed3e9SJustin Hibbits                           p_QmFqr,
20200aeed3e9SJustin Hibbits                           &p_QmFqr->p_Fqs[i]) != E_OK)
20210aeed3e9SJustin Hibbits             {
20220aeed3e9SJustin Hibbits                 QM_FQR_Free(p_QmFqr);
20230aeed3e9SJustin Hibbits                 return NULL;
20240aeed3e9SJustin Hibbits             }
20250aeed3e9SJustin Hibbits     }
20260aeed3e9SJustin Hibbits     return p_QmFqr;
20270aeed3e9SJustin Hibbits }
20280aeed3e9SJustin Hibbits 
QM_FQR_Free(t_Handle h_QmFqr)20290aeed3e9SJustin Hibbits t_Error  QM_FQR_Free(t_Handle h_QmFqr)
20300aeed3e9SJustin Hibbits {
20310aeed3e9SJustin Hibbits     t_QmFqr     *p_QmFqr    = (t_QmFqr *)h_QmFqr;
20320aeed3e9SJustin Hibbits     uint32_t    i;
20330aeed3e9SJustin Hibbits 
20340aeed3e9SJustin Hibbits     if (!p_QmFqr)
20350aeed3e9SJustin Hibbits         return ERROR_CODE(E_INVALID_HANDLE);
20360aeed3e9SJustin Hibbits 
20370aeed3e9SJustin Hibbits     if (p_QmFqr->p_Fqs)
20380aeed3e9SJustin Hibbits     {
20390aeed3e9SJustin Hibbits         for (i=0;i<p_QmFqr->numOfFqids;i++)
20400aeed3e9SJustin Hibbits             if (p_QmFqr->p_Fqs[i])
20410aeed3e9SJustin Hibbits             {
20420aeed3e9SJustin Hibbits                 if (!p_QmFqr->shadowMode)
20430aeed3e9SJustin Hibbits                     qm_free_fq(p_QmFqr->h_QmPortal, p_QmFqr->p_Fqs[i]);
20440aeed3e9SJustin Hibbits                 XX_FreeSmart(p_QmFqr->p_Fqs[i]);
20450aeed3e9SJustin Hibbits             }
20460aeed3e9SJustin Hibbits         XX_Free(p_QmFqr->p_Fqs);
20470aeed3e9SJustin Hibbits     }
20480aeed3e9SJustin Hibbits 
20490aeed3e9SJustin Hibbits     if (!p_QmFqr->shadowMode && p_QmFqr->fqidBase)
20500aeed3e9SJustin Hibbits         QmFqidPut(p_QmFqr->h_Qm, p_QmFqr->fqidBase);
20510aeed3e9SJustin Hibbits 
20520aeed3e9SJustin Hibbits     XX_FreeSmart(p_QmFqr);
20530aeed3e9SJustin Hibbits 
20540aeed3e9SJustin Hibbits     return E_OK;
20550aeed3e9SJustin Hibbits }
20560aeed3e9SJustin Hibbits 
QM_FQR_FreeWDrain(t_Handle h_QmFqr,t_QmFqrDrainedCompletionCB * f_CompletionCB,bool deliverFrame,t_QmReceivedFrameCallback * f_CallBack,t_Handle h_App)20570aeed3e9SJustin Hibbits t_Error  QM_FQR_FreeWDrain(t_Handle                     h_QmFqr,
20580aeed3e9SJustin Hibbits                            t_QmFqrDrainedCompletionCB   *f_CompletionCB,
20590aeed3e9SJustin Hibbits                            bool                         deliverFrame,
20600aeed3e9SJustin Hibbits                            t_QmReceivedFrameCallback    *f_CallBack,
20610aeed3e9SJustin Hibbits                            t_Handle                     h_App)
20620aeed3e9SJustin Hibbits {
20630aeed3e9SJustin Hibbits     t_QmFqr     *p_QmFqr    = (t_QmFqr *)h_QmFqr;
20640aeed3e9SJustin Hibbits     uint32_t    i;
20650aeed3e9SJustin Hibbits 
20660aeed3e9SJustin Hibbits     if (!p_QmFqr)
20670aeed3e9SJustin Hibbits         return ERROR_CODE(E_INVALID_HANDLE);
20680aeed3e9SJustin Hibbits 
20690aeed3e9SJustin Hibbits     if (p_QmFqr->shadowMode)
20700aeed3e9SJustin Hibbits         RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("QM_FQR_FreeWDrain can't be called to shadow FQR!!!. call QM_FQR_Free"));
20710aeed3e9SJustin Hibbits 
20720aeed3e9SJustin Hibbits     p_QmFqr->p_DrainedFqs = (bool *)XX_Malloc(sizeof(bool) * p_QmFqr->numOfFqids);
20730aeed3e9SJustin Hibbits     if (!p_QmFqr->p_DrainedFqs)
20740aeed3e9SJustin Hibbits         RETURN_ERROR(MAJOR, E_NO_MEMORY, ("QM Drained-FQs obj!!!. Try to Free without draining"));
20750aeed3e9SJustin Hibbits     memset(p_QmFqr->p_DrainedFqs, 0, sizeof(bool) * p_QmFqr->numOfFqids);
20760aeed3e9SJustin Hibbits 
20770aeed3e9SJustin Hibbits     if (f_CompletionCB)
20780aeed3e9SJustin Hibbits     {
20790aeed3e9SJustin Hibbits         p_QmFqr->f_CompletionCB = f_CompletionCB;
20800aeed3e9SJustin Hibbits         p_QmFqr->h_App          = h_App;
20810aeed3e9SJustin Hibbits     }
20820aeed3e9SJustin Hibbits 
20830aeed3e9SJustin Hibbits     if (deliverFrame)
20840aeed3e9SJustin Hibbits     {
20850aeed3e9SJustin Hibbits         if (!f_CallBack)
20860aeed3e9SJustin Hibbits         {
20870aeed3e9SJustin Hibbits             REPORT_ERROR(MAJOR, E_NULL_POINTER, ("f_CallBack must be given."));
20880aeed3e9SJustin Hibbits             XX_Free(p_QmFqr->p_DrainedFqs);
20890aeed3e9SJustin Hibbits             return ERROR_CODE(E_NULL_POINTER);
20900aeed3e9SJustin Hibbits         }
20910aeed3e9SJustin Hibbits         QM_FQR_RegisterCB(p_QmFqr, f_CallBack, h_App);
20920aeed3e9SJustin Hibbits     }
20930aeed3e9SJustin Hibbits     else
20940aeed3e9SJustin Hibbits         QM_FQR_RegisterCB(p_QmFqr, drainCB, h_App);
20950aeed3e9SJustin Hibbits 
20960aeed3e9SJustin Hibbits     for (i=0;i<p_QmFqr->numOfFqids;i++)
20970aeed3e9SJustin Hibbits     {
2098852ba100SJustin Hibbits         if (qman_retire_fq(p_QmFqr->h_QmPortal, p_QmFqr->p_Fqs[i], 0, true) != E_OK)
20990aeed3e9SJustin Hibbits             RETURN_ERROR(MAJOR, E_INVALID_STATE, ("qman_retire_fq() failed!"));
21000aeed3e9SJustin Hibbits 
21010aeed3e9SJustin Hibbits         if (p_QmFqr->p_Fqs[i]->flags & QMAN_FQ_STATE_CHANGING)
21020aeed3e9SJustin Hibbits             DBG(INFO, ("fq %d currently in use, will be retired", p_QmFqr->p_Fqs[i]->fqid));
21030aeed3e9SJustin Hibbits         else
21040aeed3e9SJustin Hibbits             drainRetiredFq(p_QmFqr->p_Fqs[i]);
21050aeed3e9SJustin Hibbits     }
21060aeed3e9SJustin Hibbits 
21070aeed3e9SJustin Hibbits     if (!p_QmFqr->f_CompletionCB)
21080aeed3e9SJustin Hibbits     {
21090aeed3e9SJustin Hibbits         while(p_QmFqr->p_DrainedFqs) ;
21100aeed3e9SJustin Hibbits         DBG(TRACE, ("QM-FQR with base %d completed", p_QmFqr->fqidBase));
21110aeed3e9SJustin Hibbits         XX_FreeSmart(p_QmFqr->p_Fqs);
21120aeed3e9SJustin Hibbits         if (p_QmFqr->fqidBase)
21130aeed3e9SJustin Hibbits             QmFqidPut(p_QmFqr->h_Qm, p_QmFqr->fqidBase);
21140aeed3e9SJustin Hibbits         XX_FreeSmart(p_QmFqr);
21150aeed3e9SJustin Hibbits     }
21160aeed3e9SJustin Hibbits 
21170aeed3e9SJustin Hibbits     return E_OK;
21180aeed3e9SJustin Hibbits }
21190aeed3e9SJustin Hibbits 
QM_FQR_RegisterCB(t_Handle h_QmFqr,t_QmReceivedFrameCallback * f_CallBack,t_Handle h_App)21200aeed3e9SJustin Hibbits t_Error QM_FQR_RegisterCB(t_Handle h_QmFqr, t_QmReceivedFrameCallback *f_CallBack, t_Handle h_App)
21210aeed3e9SJustin Hibbits {
21220aeed3e9SJustin Hibbits     t_QmFqr     *p_QmFqr = (t_QmFqr *)h_QmFqr;
21230aeed3e9SJustin Hibbits     int         i;
21240aeed3e9SJustin Hibbits 
21250aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR(p_QmFqr, E_INVALID_HANDLE);
21260aeed3e9SJustin Hibbits 
21270aeed3e9SJustin Hibbits     for (i=0;i<p_QmFqr->numOfFqids;i++)
21280aeed3e9SJustin Hibbits     {
21290aeed3e9SJustin Hibbits         p_QmFqr->p_Fqs[i]->cb.dqrr = f_CallBack;
21300aeed3e9SJustin Hibbits         p_QmFqr->p_Fqs[i]->h_App   = h_App;
21310aeed3e9SJustin Hibbits     }
21320aeed3e9SJustin Hibbits 
21330aeed3e9SJustin Hibbits     return E_OK;
21340aeed3e9SJustin Hibbits }
21350aeed3e9SJustin Hibbits 
QM_FQR_Enqueue(t_Handle h_QmFqr,t_Handle h_QmPortal,uint32_t fqidOffset,t_DpaaFD * p_Frame)21360aeed3e9SJustin Hibbits t_Error QM_FQR_Enqueue(t_Handle h_QmFqr, t_Handle h_QmPortal, uint32_t fqidOffset, t_DpaaFD *p_Frame)
21370aeed3e9SJustin Hibbits {
21380aeed3e9SJustin Hibbits     t_QmFqr                 *p_QmFqr = (t_QmFqr *)h_QmFqr;
21390aeed3e9SJustin Hibbits     t_QmPortal              *p_QmPortal;
21400aeed3e9SJustin Hibbits     struct qm_eqcr_entry    *p_Eq;
21410aeed3e9SJustin Hibbits     uint32_t                *p_Dst, *p_Src;
21420aeed3e9SJustin Hibbits     const struct qman_fq    *p_Fq;
21430aeed3e9SJustin Hibbits 
21440aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR(p_QmFqr, E_INVALID_HANDLE);
21450aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR((fqidOffset < p_QmFqr->numOfFqids), E_INVALID_VALUE);
21460aeed3e9SJustin Hibbits 
21470aeed3e9SJustin Hibbits     if (!h_QmPortal)
21480aeed3e9SJustin Hibbits     {
21490aeed3e9SJustin Hibbits         SANITY_CHECK_RETURN_ERROR(p_QmFqr->h_Qm, E_INVALID_HANDLE);
21500aeed3e9SJustin Hibbits         h_QmPortal = QmGetPortalHandle(p_QmFqr->h_Qm);
21510aeed3e9SJustin Hibbits         SANITY_CHECK_RETURN_ERROR(h_QmPortal, E_INVALID_HANDLE);
21520aeed3e9SJustin Hibbits     }
21530aeed3e9SJustin Hibbits     p_QmPortal = (t_QmPortal *)h_QmPortal;
21540aeed3e9SJustin Hibbits 
21550aeed3e9SJustin Hibbits     p_Fq = p_QmFqr->p_Fqs[fqidOffset];
21560aeed3e9SJustin Hibbits 
21570aeed3e9SJustin Hibbits #ifdef QM_CHECKING
21580aeed3e9SJustin Hibbits     if (p_Fq->flags & QMAN_FQ_FLAG_NO_ENQUEUE)
21590aeed3e9SJustin Hibbits         RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
21600aeed3e9SJustin Hibbits     if ((!(p_Fq->flags & QMAN_FQ_FLAG_NO_MODIFY)) &&
21610aeed3e9SJustin Hibbits         ((p_Fq->state == qman_fq_state_retired) ||
21620aeed3e9SJustin Hibbits          (p_Fq->state == qman_fq_state_oos)))
21630aeed3e9SJustin Hibbits         return ERROR_CODE(E_BUSY);
21640aeed3e9SJustin Hibbits #endif /* QM_CHECKING */
21650aeed3e9SJustin Hibbits 
21660aeed3e9SJustin Hibbits     NCSW_PLOCK(p_QmPortal);
21670aeed3e9SJustin Hibbits     p_Eq = try_eq_start(p_QmPortal);
21680aeed3e9SJustin Hibbits     if (!p_Eq)
21690aeed3e9SJustin Hibbits     {
21700aeed3e9SJustin Hibbits         PUNLOCK(p_QmPortal);
21710aeed3e9SJustin Hibbits         return ERROR_CODE(E_BUSY);
21720aeed3e9SJustin Hibbits     }
21730aeed3e9SJustin Hibbits 
21740aeed3e9SJustin Hibbits     p_Eq->fqid = p_Fq->fqid;
2175852ba100SJustin Hibbits     p_Eq->tag = aligned_int_from_ptr(p_Fq);
21760aeed3e9SJustin Hibbits     /* gcc does a dreadful job of the following;
21770aeed3e9SJustin Hibbits      *  eq->fd = *fd;
21780aeed3e9SJustin Hibbits      * It causes the entire function to save/restore a wider range of
21790aeed3e9SJustin Hibbits      * registers, and comes up with instruction-waste galore. This will do
21800aeed3e9SJustin Hibbits      * until we can rework the function for better code-generation. */
21810aeed3e9SJustin Hibbits     p_Dst = (uint32_t *)&p_Eq->fd;
21820aeed3e9SJustin Hibbits     p_Src = (uint32_t *)p_Frame;
21830aeed3e9SJustin Hibbits     p_Dst[0] = p_Src[0];
21840aeed3e9SJustin Hibbits     p_Dst[1] = p_Src[1];
21850aeed3e9SJustin Hibbits     p_Dst[2] = p_Src[2];
21860aeed3e9SJustin Hibbits     p_Dst[3] = p_Src[3];
21870aeed3e9SJustin Hibbits 
21880aeed3e9SJustin Hibbits     qmPortalEqcrPvbCommit(p_QmPortal->p_LowQmPortal,
21890aeed3e9SJustin Hibbits                           (uint8_t)(QM_EQCR_VERB_CMD_ENQUEUE/* |
21900aeed3e9SJustin Hibbits                           (flags & (QM_EQCR_VERB_COLOUR_MASK | QM_EQCR_VERB_INTERRUPT))*/));
21910aeed3e9SJustin Hibbits     PUNLOCK(p_QmPortal);
21920aeed3e9SJustin Hibbits 
21930aeed3e9SJustin Hibbits     return E_OK;
21940aeed3e9SJustin Hibbits }
21950aeed3e9SJustin Hibbits 
21960aeed3e9SJustin Hibbits 
QM_FQR_PullFrame(t_Handle h_QmFqr,t_Handle h_QmPortal,uint32_t fqidOffset,t_DpaaFD * p_Frame)21970aeed3e9SJustin Hibbits t_Error QM_FQR_PullFrame(t_Handle h_QmFqr, t_Handle h_QmPortal, uint32_t fqidOffset, t_DpaaFD *p_Frame)
21980aeed3e9SJustin Hibbits {
21990aeed3e9SJustin Hibbits     t_QmFqr                 *p_QmFqr = (t_QmFqr *)h_QmFqr;
22000aeed3e9SJustin Hibbits     uint32_t                pdqcr = 0;
22010aeed3e9SJustin Hibbits 
22020aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR(p_QmFqr, E_INVALID_HANDLE);
22030aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR((fqidOffset < p_QmFqr->numOfFqids), E_INVALID_VALUE);
22040aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR(p_Frame, E_NULL_POINTER);
22050aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR((p_QmFqr->p_Fqs[fqidOffset]->state == qman_fq_state_oos) ||
22060aeed3e9SJustin Hibbits                               (p_QmFqr->p_Fqs[fqidOffset]->state == qman_fq_state_parked),
22070aeed3e9SJustin Hibbits                               E_INVALID_STATE);
22080aeed3e9SJustin Hibbits     if (!h_QmPortal)
22090aeed3e9SJustin Hibbits     {
22100aeed3e9SJustin Hibbits         SANITY_CHECK_RETURN_ERROR(p_QmFqr->h_Qm, E_INVALID_HANDLE);
22110aeed3e9SJustin Hibbits         h_QmPortal = QmGetPortalHandle(p_QmFqr->h_Qm);
22120aeed3e9SJustin Hibbits         SANITY_CHECK_RETURN_ERROR(h_QmPortal, E_INVALID_HANDLE);
22130aeed3e9SJustin Hibbits     }
22140aeed3e9SJustin Hibbits 
22150aeed3e9SJustin Hibbits     pdqcr |= QM_PDQCR_MODE_UNSCHEDULED;
22160aeed3e9SJustin Hibbits     pdqcr |= QM_PDQCR_FQID(p_QmFqr->p_Fqs[fqidOffset]->fqid);
22170aeed3e9SJustin Hibbits     return QmPortalPullFrame(h_QmPortal, pdqcr, p_Frame);
22180aeed3e9SJustin Hibbits }
22190aeed3e9SJustin Hibbits 
QM_FQR_Resume(t_Handle h_QmFqr,t_Handle h_QmPortal,uint32_t fqidOffset)22200aeed3e9SJustin Hibbits t_Error QM_FQR_Resume(t_Handle h_QmFqr, t_Handle h_QmPortal, uint32_t fqidOffset)
22210aeed3e9SJustin Hibbits {
22220aeed3e9SJustin Hibbits     t_QmFqr     *p_QmFqr = (t_QmFqr *)h_QmFqr;
22230aeed3e9SJustin Hibbits 
22240aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR(p_QmFqr, E_INVALID_HANDLE);
22250aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR((fqidOffset < p_QmFqr->numOfFqids), E_INVALID_VALUE);
22260aeed3e9SJustin Hibbits 
22270aeed3e9SJustin Hibbits     if (!h_QmPortal)
22280aeed3e9SJustin Hibbits     {
22290aeed3e9SJustin Hibbits         SANITY_CHECK_RETURN_ERROR(p_QmFqr->h_Qm, E_INVALID_HANDLE);
22300aeed3e9SJustin Hibbits         h_QmPortal = QmGetPortalHandle(p_QmFqr->h_Qm);
22310aeed3e9SJustin Hibbits         SANITY_CHECK_RETURN_ERROR(h_QmPortal, E_INVALID_HANDLE);
22320aeed3e9SJustin Hibbits     }
22330aeed3e9SJustin Hibbits     return qman_schedule_fq(h_QmPortal, p_QmFqr->p_Fqs[fqidOffset]);
22340aeed3e9SJustin Hibbits }
22350aeed3e9SJustin Hibbits 
QM_FQR_Suspend(t_Handle h_QmFqr,t_Handle h_QmPortal,uint32_t fqidOffset)22360aeed3e9SJustin Hibbits t_Error  QM_FQR_Suspend(t_Handle h_QmFqr, t_Handle h_QmPortal, uint32_t fqidOffset)
22370aeed3e9SJustin Hibbits {
22380aeed3e9SJustin Hibbits     t_QmFqr     *p_QmFqr = (t_QmFqr *)h_QmFqr;
22390aeed3e9SJustin Hibbits 
22400aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR(p_QmFqr, E_INVALID_HANDLE);
22410aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR((fqidOffset < p_QmFqr->numOfFqids), E_INVALID_VALUE);
22420aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR((p_QmFqr->p_Fqs[fqidOffset]->flags & QM_FQCTRL_HOLDACTIVE), E_INVALID_STATE);
22430aeed3e9SJustin Hibbits 
22440aeed3e9SJustin Hibbits     UNUSED(h_QmPortal);
22450aeed3e9SJustin Hibbits     p_QmFqr->p_Fqs[fqidOffset]->state = qman_fq_state_waiting_parked;
22460aeed3e9SJustin Hibbits 
22470aeed3e9SJustin Hibbits     return E_OK;
22480aeed3e9SJustin Hibbits }
22490aeed3e9SJustin Hibbits 
QM_FQR_GetFqid(t_Handle h_QmFqr)22500aeed3e9SJustin Hibbits uint32_t QM_FQR_GetFqid(t_Handle h_QmFqr)
22510aeed3e9SJustin Hibbits {
22520aeed3e9SJustin Hibbits     t_QmFqr *p_QmFqr = (t_QmFqr *)h_QmFqr;
22530aeed3e9SJustin Hibbits 
22540aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_VALUE(p_QmFqr, E_INVALID_HANDLE, 0);
22550aeed3e9SJustin Hibbits 
22560aeed3e9SJustin Hibbits     return p_QmFqr->fqidBase;
22570aeed3e9SJustin Hibbits }
22580aeed3e9SJustin Hibbits 
QM_FQR_GetCounter(t_Handle h_QmFqr,t_Handle h_QmPortal,uint32_t fqidOffset,e_QmFqrCounters counter)22590aeed3e9SJustin Hibbits uint32_t QM_FQR_GetCounter(t_Handle h_QmFqr, t_Handle h_QmPortal, uint32_t fqidOffset, e_QmFqrCounters counter)
22600aeed3e9SJustin Hibbits {
22610aeed3e9SJustin Hibbits     t_QmFqr *p_QmFqr = (t_QmFqr *)h_QmFqr;
22620aeed3e9SJustin Hibbits     struct qm_mcr_queryfq_np    queryfq_np;
22630aeed3e9SJustin Hibbits 
22640aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_VALUE(p_QmFqr, E_INVALID_HANDLE, 0);
22650aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_VALUE((fqidOffset < p_QmFqr->numOfFqids), E_INVALID_VALUE, 0);
22660aeed3e9SJustin Hibbits 
22670aeed3e9SJustin Hibbits     if (!h_QmPortal)
22680aeed3e9SJustin Hibbits     {
22690aeed3e9SJustin Hibbits         SANITY_CHECK_RETURN_VALUE(p_QmFqr->h_Qm, E_INVALID_HANDLE, 0);
22700aeed3e9SJustin Hibbits         h_QmPortal = QmGetPortalHandle(p_QmFqr->h_Qm);
22710aeed3e9SJustin Hibbits         SANITY_CHECK_RETURN_VALUE(h_QmPortal, E_INVALID_HANDLE, 0);
22720aeed3e9SJustin Hibbits     }
22730aeed3e9SJustin Hibbits     if (qman_query_fq_np(h_QmPortal, p_QmFqr->p_Fqs[fqidOffset], &queryfq_np) != E_OK)
22740aeed3e9SJustin Hibbits         return 0;
22750aeed3e9SJustin Hibbits     switch (counter)
22760aeed3e9SJustin Hibbits     {
22770aeed3e9SJustin Hibbits         case e_QM_FQR_COUNTERS_FRAME :
22780aeed3e9SJustin Hibbits             return queryfq_np.frm_cnt;
22790aeed3e9SJustin Hibbits         case e_QM_FQR_COUNTERS_BYTE :
22800aeed3e9SJustin Hibbits             return queryfq_np.byte_cnt;
22810aeed3e9SJustin Hibbits         default :
22820aeed3e9SJustin Hibbits             break;
22830aeed3e9SJustin Hibbits     }
22840aeed3e9SJustin Hibbits     /* should never get here */
22850aeed3e9SJustin Hibbits     ASSERT_COND(FALSE);
22860aeed3e9SJustin Hibbits 
22870aeed3e9SJustin Hibbits     return 0;
22880aeed3e9SJustin Hibbits }
22890aeed3e9SJustin Hibbits 
22900aeed3e9SJustin Hibbits 
QM_CG_Create(t_QmCgParams * p_CgParams)22910aeed3e9SJustin Hibbits t_Handle QM_CG_Create(t_QmCgParams *p_CgParams)
22920aeed3e9SJustin Hibbits {
22930aeed3e9SJustin Hibbits     t_QmCg                          *p_QmCg;
22940aeed3e9SJustin Hibbits     t_QmPortal                      *p_QmPortal;
22950aeed3e9SJustin Hibbits     t_Error                         err;
22960aeed3e9SJustin Hibbits     uint32_t                        wredParams;
22970aeed3e9SJustin Hibbits     uint32_t                        tmpA, tmpN, ta=0, tn=0;
22980aeed3e9SJustin Hibbits     int                             gap, tmp;
22990aeed3e9SJustin Hibbits     struct qm_mc_command            *p_Mcc;
23000aeed3e9SJustin Hibbits     struct qm_mc_result             *p_Mcr;
23010aeed3e9SJustin Hibbits 
23020aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_VALUE(p_CgParams, E_INVALID_HANDLE, NULL);
23030aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_VALUE(p_CgParams->h_Qm, E_INVALID_HANDLE, NULL);
23040aeed3e9SJustin Hibbits 
23050aeed3e9SJustin Hibbits     if(p_CgParams->notifyDcPortal &&
23060aeed3e9SJustin Hibbits        ((p_CgParams->dcPortalId == e_DPAA_DCPORTAL2) || (p_CgParams->dcPortalId == e_DPAA_DCPORTAL3)))
23070aeed3e9SJustin Hibbits     {
23080aeed3e9SJustin Hibbits         REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("notifyDcPortal is invalid for this DC Portal"));
23090aeed3e9SJustin Hibbits         return NULL;
23100aeed3e9SJustin Hibbits     }
23110aeed3e9SJustin Hibbits 
23120aeed3e9SJustin Hibbits     if (!p_CgParams->h_QmPortal)
23130aeed3e9SJustin Hibbits     {
23140aeed3e9SJustin Hibbits         p_QmPortal = QmGetPortalHandle(p_CgParams->h_Qm);
23150aeed3e9SJustin Hibbits         SANITY_CHECK_RETURN_VALUE(p_QmPortal, E_INVALID_STATE, NULL);
23160aeed3e9SJustin Hibbits     }
23170aeed3e9SJustin Hibbits     else
23180aeed3e9SJustin Hibbits         p_QmPortal = p_CgParams->h_QmPortal;
23190aeed3e9SJustin Hibbits 
23200aeed3e9SJustin Hibbits     p_QmCg = (t_QmCg *)XX_Malloc(sizeof(t_QmCg));
23210aeed3e9SJustin Hibbits     if (!p_QmCg)
23220aeed3e9SJustin Hibbits     {
23230aeed3e9SJustin Hibbits         REPORT_ERROR(MAJOR, E_NO_MEMORY, ("QM CG obj!!!"));
23240aeed3e9SJustin Hibbits         return NULL;
23250aeed3e9SJustin Hibbits     }
23260aeed3e9SJustin Hibbits     memset(p_QmCg, 0, sizeof(t_QmCg));
23270aeed3e9SJustin Hibbits 
23280aeed3e9SJustin Hibbits     /* build CG struct */
23290aeed3e9SJustin Hibbits     p_QmCg->h_Qm        = p_CgParams->h_Qm;
23300aeed3e9SJustin Hibbits     p_QmCg->h_QmPortal  = p_QmPortal;
23310aeed3e9SJustin Hibbits     p_QmCg->h_App       = p_CgParams->h_App;
23320aeed3e9SJustin Hibbits     err = QmGetCgId(p_CgParams->h_Qm, &p_QmCg->id);
23330aeed3e9SJustin Hibbits     if (err)
23340aeed3e9SJustin Hibbits     {
23350aeed3e9SJustin Hibbits         XX_Free(p_QmCg);
23360aeed3e9SJustin Hibbits         REPORT_ERROR(MAJOR, E_INVALID_STATE, ("QmGetCgId failed"));
23370aeed3e9SJustin Hibbits         return NULL;
23380aeed3e9SJustin Hibbits     }
23390aeed3e9SJustin Hibbits 
23400aeed3e9SJustin Hibbits     NCSW_PLOCK(p_QmPortal);
23410aeed3e9SJustin Hibbits     p_Mcc = qm_mc_start(p_QmPortal->p_LowQmPortal);
23420aeed3e9SJustin Hibbits     p_Mcc->initcgr.cgid = p_QmCg->id;
23430aeed3e9SJustin Hibbits 
23440aeed3e9SJustin Hibbits     err = QmPortalRegisterCg(p_QmPortal, p_QmCg, p_QmCg->id);
23450aeed3e9SJustin Hibbits     if (err)
23460aeed3e9SJustin Hibbits     {
23470aeed3e9SJustin Hibbits         XX_Free(p_QmCg);
23480aeed3e9SJustin Hibbits         PUNLOCK(p_QmPortal);
23490aeed3e9SJustin Hibbits         REPORT_ERROR(MAJOR, E_INVALID_STATE, ("QmPortalRegisterCg failed"));
23500aeed3e9SJustin Hibbits         return NULL;
23510aeed3e9SJustin Hibbits     }
23520aeed3e9SJustin Hibbits 
23530aeed3e9SJustin Hibbits     /*  Build CGR command */
23540aeed3e9SJustin Hibbits     {
23550aeed3e9SJustin Hibbits #ifdef QM_CGS_NO_FRAME_MODE
23560aeed3e9SJustin Hibbits     t_QmRevisionInfo    revInfo;
23570aeed3e9SJustin Hibbits 
23580aeed3e9SJustin Hibbits     QmGetRevision(p_QmCg->h_Qm, &revInfo);
23590aeed3e9SJustin Hibbits 
23600aeed3e9SJustin Hibbits     if (!((revInfo.majorRev == 1) && (revInfo.minorRev == 0)))
23610aeed3e9SJustin Hibbits #endif /* QM_CGS_NO_FRAME_MODE */
23620aeed3e9SJustin Hibbits         if (p_CgParams->frameCount)
23630aeed3e9SJustin Hibbits         {
23640aeed3e9SJustin Hibbits             p_Mcc->initcgr.we_mask |= QM_CGR_WE_MODE;
23650aeed3e9SJustin Hibbits             p_Mcc->initcgr.cgr.frame_mode = QM_CGR_EN;
23660aeed3e9SJustin Hibbits         }
23670aeed3e9SJustin Hibbits     }
23680aeed3e9SJustin Hibbits 
23690aeed3e9SJustin Hibbits     if (p_CgParams->wredEnable)
23700aeed3e9SJustin Hibbits     {
23710aeed3e9SJustin Hibbits         if (p_CgParams->wredParams.enableGreen)
23720aeed3e9SJustin Hibbits         {
23730aeed3e9SJustin Hibbits             err = CalcWredCurve(&p_CgParams->wredParams.greenCurve, &wredParams);
23740aeed3e9SJustin Hibbits             if(err)
23750aeed3e9SJustin Hibbits             {
23760aeed3e9SJustin Hibbits                 XX_Free(p_QmCg);
23770aeed3e9SJustin Hibbits                 PUNLOCK(p_QmPortal);
23780aeed3e9SJustin Hibbits                 REPORT_ERROR(MAJOR, err, NO_MSG);
23790aeed3e9SJustin Hibbits                 return NULL;
23800aeed3e9SJustin Hibbits             }
23810aeed3e9SJustin Hibbits             p_Mcc->initcgr.we_mask |= QM_CGR_WE_WR_EN_G | QM_CGR_WE_WR_PARM_G;
23820aeed3e9SJustin Hibbits             p_Mcc->initcgr.cgr.wr_en_g = QM_CGR_EN;
23830aeed3e9SJustin Hibbits             p_Mcc->initcgr.cgr.wr_parm_g.word = wredParams;
23840aeed3e9SJustin Hibbits         }
23850aeed3e9SJustin Hibbits         if (p_CgParams->wredParams.enableYellow)
23860aeed3e9SJustin Hibbits         {
23870aeed3e9SJustin Hibbits             err = CalcWredCurve(&p_CgParams->wredParams.yellowCurve, &wredParams);
23880aeed3e9SJustin Hibbits             if(err)
23890aeed3e9SJustin Hibbits             {
23900aeed3e9SJustin Hibbits                 XX_Free(p_QmCg);
23910aeed3e9SJustin Hibbits                 PUNLOCK(p_QmPortal);
23920aeed3e9SJustin Hibbits                 REPORT_ERROR(MAJOR, err, NO_MSG);
23930aeed3e9SJustin Hibbits                 return NULL;
23940aeed3e9SJustin Hibbits             }
23950aeed3e9SJustin Hibbits             p_Mcc->initcgr.we_mask |= QM_CGR_WE_WR_EN_Y | QM_CGR_WE_WR_PARM_Y;
23960aeed3e9SJustin Hibbits             p_Mcc->initcgr.cgr.wr_en_y = QM_CGR_EN;
23970aeed3e9SJustin Hibbits             p_Mcc->initcgr.cgr.wr_parm_y.word = wredParams;
23980aeed3e9SJustin Hibbits         }
23990aeed3e9SJustin Hibbits         if (p_CgParams->wredParams.enableRed)
24000aeed3e9SJustin Hibbits         {
24010aeed3e9SJustin Hibbits             err = CalcWredCurve(&p_CgParams->wredParams.redCurve, &wredParams);
24020aeed3e9SJustin Hibbits             if(err)
24030aeed3e9SJustin Hibbits             {
24040aeed3e9SJustin Hibbits                 XX_Free(p_QmCg);
24050aeed3e9SJustin Hibbits                 PUNLOCK(p_QmPortal);
24060aeed3e9SJustin Hibbits                 REPORT_ERROR(MAJOR, err, NO_MSG);
24070aeed3e9SJustin Hibbits                 return NULL;
24080aeed3e9SJustin Hibbits             }
24090aeed3e9SJustin Hibbits             p_Mcc->initcgr.we_mask |= QM_CGR_WE_WR_EN_R | QM_CGR_WE_WR_PARM_R;
24100aeed3e9SJustin Hibbits             p_Mcc->initcgr.cgr.wr_en_r = QM_CGR_EN;
24110aeed3e9SJustin Hibbits             p_Mcc->initcgr.cgr.wr_parm_r.word = wredParams;
24120aeed3e9SJustin Hibbits         }
24130aeed3e9SJustin Hibbits     }
24140aeed3e9SJustin Hibbits 
24150aeed3e9SJustin Hibbits     if (p_CgParams->tailDropEnable)
24160aeed3e9SJustin Hibbits     {
24170aeed3e9SJustin Hibbits         if (!p_CgParams->threshold)
24180aeed3e9SJustin Hibbits         {
24190aeed3e9SJustin Hibbits             XX_Free(p_QmCg);
24200aeed3e9SJustin Hibbits             PUNLOCK(p_QmPortal);
24210aeed3e9SJustin Hibbits             REPORT_ERROR(MINOR, E_INVALID_STATE, ("tailDropThreshold must be configured if tailDropEnable "));
24220aeed3e9SJustin Hibbits             return NULL;
24230aeed3e9SJustin Hibbits         }
24240aeed3e9SJustin Hibbits         p_Mcc->initcgr.cgr.cstd_en = QM_CGR_EN;
24250aeed3e9SJustin Hibbits         p_Mcc->initcgr.we_mask |= QM_CGR_WE_CSTD_EN;
24260aeed3e9SJustin Hibbits     }
24270aeed3e9SJustin Hibbits 
24280aeed3e9SJustin Hibbits     if (p_CgParams->threshold)
24290aeed3e9SJustin Hibbits     {
24300aeed3e9SJustin Hibbits         p_Mcc->initcgr.we_mask |= QM_CGR_WE_CS_THRES;
24310aeed3e9SJustin Hibbits         p_QmCg->f_Exception = p_CgParams->f_Exception;
24320aeed3e9SJustin Hibbits         if (p_QmCg->f_Exception || p_CgParams->notifyDcPortal)
24330aeed3e9SJustin Hibbits         {
24340aeed3e9SJustin Hibbits             p_Mcc->initcgr.cgr.cscn_en = QM_CGR_EN;
24350aeed3e9SJustin Hibbits             p_Mcc->initcgr.we_mask |= QM_CGR_WE_CSCN_EN | QM_CGR_WE_CSCN_TARG;
24360aeed3e9SJustin Hibbits             /* if SW - set target, if HW - if FM, set HW target, otherwize, set SW target */
24370aeed3e9SJustin Hibbits             p_Mcc->initcgr.cgr.cscn_targ = 0;
24380aeed3e9SJustin Hibbits             if (p_QmCg->f_Exception)
24390aeed3e9SJustin Hibbits                 p_Mcc->initcgr.cgr.cscn_targ = (uint32_t)QM_CGR_TARGET_SWP(QmPortalGetSwPortalId(p_QmCg->h_QmPortal));
24400aeed3e9SJustin Hibbits             if (p_CgParams->notifyDcPortal)
24410aeed3e9SJustin Hibbits                 p_Mcc->initcgr.cgr.cscn_targ |= (uint32_t)QM_CGR_TARGET_DCP(p_CgParams->dcPortalId);
24420aeed3e9SJustin Hibbits         }
24430aeed3e9SJustin Hibbits 
24440aeed3e9SJustin Hibbits         /* express thresh as ta*2^tn */
24450aeed3e9SJustin Hibbits         gap = (int)p_CgParams->threshold;
24460aeed3e9SJustin Hibbits         for (tmpA=0 ; tmpA<256; tmpA++ )
24470aeed3e9SJustin Hibbits             for (tmpN=0 ; tmpN<32; tmpN++ )
24480aeed3e9SJustin Hibbits             {
24490aeed3e9SJustin Hibbits                 tmp = ABS((int)(p_CgParams->threshold - tmpA*(1<<tmpN)));
24500aeed3e9SJustin Hibbits                 if (tmp < gap)
24510aeed3e9SJustin Hibbits                 {
24520aeed3e9SJustin Hibbits                    ta = tmpA;
24530aeed3e9SJustin Hibbits                    tn = tmpN;
24540aeed3e9SJustin Hibbits                    gap = tmp;
24550aeed3e9SJustin Hibbits                 }
24560aeed3e9SJustin Hibbits             }
24570aeed3e9SJustin Hibbits         p_Mcc->initcgr.cgr.cs_thres.TA = ta;
24580aeed3e9SJustin Hibbits         p_Mcc->initcgr.cgr.cs_thres.Tn = tn;
24590aeed3e9SJustin Hibbits     }
24600aeed3e9SJustin Hibbits     else if(p_CgParams->f_Exception)
24610aeed3e9SJustin Hibbits     {
24620aeed3e9SJustin Hibbits         XX_Free(p_QmCg);
24630aeed3e9SJustin Hibbits         PUNLOCK(p_QmPortal);
24640aeed3e9SJustin Hibbits         REPORT_ERROR(MINOR, E_INVALID_STATE, ("No threshold configured, but f_Exception defined"));
24650aeed3e9SJustin Hibbits         return NULL;
24660aeed3e9SJustin Hibbits     }
24670aeed3e9SJustin Hibbits 
24680aeed3e9SJustin Hibbits     qm_mc_commit(p_QmPortal->p_LowQmPortal, QM_MCC_VERB_INITCGR);
24690aeed3e9SJustin Hibbits     while (!(p_Mcr = qm_mc_result(p_QmPortal->p_LowQmPortal))) ;
24700aeed3e9SJustin Hibbits     ASSERT_COND((p_Mcr->verb & QM_MCR_VERB_MASK) == QM_MCC_VERB_INITCGR);
24710aeed3e9SJustin Hibbits     if (p_Mcr->result != QM_MCR_RESULT_OK)
24720aeed3e9SJustin Hibbits     {
24730aeed3e9SJustin Hibbits         XX_Free(p_QmCg);
24740aeed3e9SJustin Hibbits         PUNLOCK(p_QmPortal);
24750aeed3e9SJustin Hibbits         REPORT_ERROR(MINOR, E_INVALID_STATE, ("INITCGR failed: %s", mcr_result_str(p_Mcr->result)));
24760aeed3e9SJustin Hibbits         return NULL;
24770aeed3e9SJustin Hibbits     }
24780aeed3e9SJustin Hibbits     PUNLOCK(p_QmPortal);
24790aeed3e9SJustin Hibbits 
24800aeed3e9SJustin Hibbits     return p_QmCg;
24810aeed3e9SJustin Hibbits }
24820aeed3e9SJustin Hibbits 
QM_CG_Free(t_Handle h_QmCg)24830aeed3e9SJustin Hibbits t_Error QM_CG_Free(t_Handle h_QmCg)
24840aeed3e9SJustin Hibbits {
24850aeed3e9SJustin Hibbits 
24860aeed3e9SJustin Hibbits     t_QmCg                  *p_QmCg = (t_QmCg *)h_QmCg;
24870aeed3e9SJustin Hibbits     t_Error                 err;
24880aeed3e9SJustin Hibbits     struct qm_mc_command    *p_Mcc;
24890aeed3e9SJustin Hibbits     struct qm_mc_result     *p_Mcr;
24900aeed3e9SJustin Hibbits     t_QmPortal              *p_QmPortal;
24910aeed3e9SJustin Hibbits 
24920aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR(p_QmCg, E_INVALID_HANDLE);
24930aeed3e9SJustin Hibbits 
24940aeed3e9SJustin Hibbits     p_QmPortal = (t_QmPortal *)p_QmCg->h_QmPortal;
24950aeed3e9SJustin Hibbits 
24960aeed3e9SJustin Hibbits     NCSW_PLOCK(p_QmPortal);
24970aeed3e9SJustin Hibbits     p_Mcc = qm_mc_start(p_QmPortal->p_LowQmPortal);
24980aeed3e9SJustin Hibbits     p_Mcc->initcgr.cgid = p_QmCg->id;
24990aeed3e9SJustin Hibbits     p_Mcc->initcgr.we_mask = QM_CGR_WE_MASK;
25000aeed3e9SJustin Hibbits 
25010aeed3e9SJustin Hibbits     err = QmFreeCgId(p_QmCg->h_Qm, p_QmCg->id);
25020aeed3e9SJustin Hibbits     if(err)
25030aeed3e9SJustin Hibbits     {
25040aeed3e9SJustin Hibbits         XX_Free(p_QmCg);
25050aeed3e9SJustin Hibbits         PUNLOCK(p_QmPortal);
25060aeed3e9SJustin Hibbits         RETURN_ERROR(MAJOR, E_INVALID_STATE, ("QmFreeCgId failed"));
25070aeed3e9SJustin Hibbits     }
25080aeed3e9SJustin Hibbits 
25090aeed3e9SJustin Hibbits     err = QmPortalUnregisterCg(p_QmCg->h_QmPortal, p_QmCg->id);
25100aeed3e9SJustin Hibbits     if(err)
25110aeed3e9SJustin Hibbits     {
25120aeed3e9SJustin Hibbits         XX_Free(p_QmCg);
25130aeed3e9SJustin Hibbits         PUNLOCK(p_QmPortal);
25140aeed3e9SJustin Hibbits         RETURN_ERROR(MAJOR, E_INVALID_STATE, ("QmPortalUnregisterCg failed"));
25150aeed3e9SJustin Hibbits     }
25160aeed3e9SJustin Hibbits 
25170aeed3e9SJustin Hibbits     qm_mc_commit(p_QmPortal->p_LowQmPortal, QM_MCC_VERB_MODIFYCGR);
25180aeed3e9SJustin Hibbits     while (!(p_Mcr = qm_mc_result(p_QmPortal->p_LowQmPortal))) ;
25190aeed3e9SJustin Hibbits     ASSERT_COND((p_Mcr->verb & QM_MCR_VERB_MASK) == QM_MCC_VERB_MODIFYCGR);
25200aeed3e9SJustin Hibbits     if (p_Mcr->result != QM_MCR_RESULT_OK)
25210aeed3e9SJustin Hibbits     {
25220aeed3e9SJustin Hibbits         PUNLOCK(p_QmPortal);
25230aeed3e9SJustin Hibbits         RETURN_ERROR(MINOR, E_INVALID_STATE, ("INITCGR failed: %s", mcr_result_str(p_Mcr->result)));
25240aeed3e9SJustin Hibbits     }
25250aeed3e9SJustin Hibbits     PUNLOCK(p_QmPortal);
25260aeed3e9SJustin Hibbits 
25270aeed3e9SJustin Hibbits     XX_Free(p_QmCg);
25280aeed3e9SJustin Hibbits 
25290aeed3e9SJustin Hibbits     return E_OK;
25300aeed3e9SJustin Hibbits }
25310aeed3e9SJustin Hibbits 
QM_CG_SetException(t_Handle h_QmCg,e_QmExceptions exception,bool enable)25320aeed3e9SJustin Hibbits t_Error QM_CG_SetException(t_Handle h_QmCg, e_QmExceptions exception, bool enable)
25330aeed3e9SJustin Hibbits {
25340aeed3e9SJustin Hibbits     t_QmCg                  *p_QmCg = (t_QmCg *)h_QmCg;
25350aeed3e9SJustin Hibbits     struct qm_mc_command    *p_Mcc;
25360aeed3e9SJustin Hibbits     struct qm_mc_result     *p_Mcr;
25370aeed3e9SJustin Hibbits     t_QmPortal              *p_QmPortal;
25380aeed3e9SJustin Hibbits 
25390aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR(p_QmCg, E_INVALID_HANDLE);
25400aeed3e9SJustin Hibbits 
25410aeed3e9SJustin Hibbits     p_QmPortal = (t_QmPortal *)p_QmCg->h_QmPortal;
25420aeed3e9SJustin Hibbits     if (!p_QmCg->f_Exception)
25430aeed3e9SJustin Hibbits         RETURN_ERROR(MINOR, E_INVALID_VALUE, ("Either threshold or exception callback was not configured."));
25440aeed3e9SJustin Hibbits 
25450aeed3e9SJustin Hibbits     NCSW_PLOCK(p_QmPortal);
25460aeed3e9SJustin Hibbits     p_Mcc = qm_mc_start(p_QmPortal->p_LowQmPortal);
25470aeed3e9SJustin Hibbits     p_Mcc->initcgr.cgid = p_QmCg->id;
25480aeed3e9SJustin Hibbits     p_Mcc->initcgr.we_mask = QM_CGR_WE_CSCN_EN;
25490aeed3e9SJustin Hibbits 
25500aeed3e9SJustin Hibbits     if(exception == e_QM_EX_CG_STATE_CHANGE)
25510aeed3e9SJustin Hibbits     {
25520aeed3e9SJustin Hibbits         if(enable)
25530aeed3e9SJustin Hibbits             p_Mcc->initcgr.cgr.cscn_en = QM_CGR_EN;
25540aeed3e9SJustin Hibbits     }
25550aeed3e9SJustin Hibbits     else
25560aeed3e9SJustin Hibbits     {
25570aeed3e9SJustin Hibbits         PUNLOCK(p_QmPortal);
25580aeed3e9SJustin Hibbits         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal exception"));
25590aeed3e9SJustin Hibbits     }
25600aeed3e9SJustin Hibbits 
25610aeed3e9SJustin Hibbits     qm_mc_commit(p_QmPortal->p_LowQmPortal, QM_MCC_VERB_MODIFYCGR);
25620aeed3e9SJustin Hibbits     while (!(p_Mcr = qm_mc_result(p_QmPortal->p_LowQmPortal))) ;
25630aeed3e9SJustin Hibbits     ASSERT_COND((p_Mcr->verb & QM_MCR_VERB_MASK) == QM_MCC_VERB_MODIFYCGR);
25640aeed3e9SJustin Hibbits     if (p_Mcr->result != QM_MCR_RESULT_OK)
25650aeed3e9SJustin Hibbits     {
25660aeed3e9SJustin Hibbits         PUNLOCK(p_QmPortal);
25670aeed3e9SJustin Hibbits         RETURN_ERROR(MINOR, E_INVALID_STATE, ("INITCGR failed: %s", mcr_result_str(p_Mcr->result)));
25680aeed3e9SJustin Hibbits     }
25690aeed3e9SJustin Hibbits     PUNLOCK(p_QmPortal);
25700aeed3e9SJustin Hibbits 
25710aeed3e9SJustin Hibbits     return E_OK;
25720aeed3e9SJustin Hibbits }
25730aeed3e9SJustin Hibbits 
QM_CG_ModifyWredCurve(t_Handle h_QmCg,t_QmCgModifyWredParams * p_QmCgModifyParams)25740aeed3e9SJustin Hibbits t_Error QM_CG_ModifyWredCurve(t_Handle h_QmCg, t_QmCgModifyWredParams *p_QmCgModifyParams)
25750aeed3e9SJustin Hibbits {
25760aeed3e9SJustin Hibbits     t_QmCg                  *p_QmCg = (t_QmCg *)h_QmCg;
25770aeed3e9SJustin Hibbits     uint32_t                wredParams;
25780aeed3e9SJustin Hibbits     struct qm_mc_command    *p_Mcc;
25790aeed3e9SJustin Hibbits     struct qm_mc_result     *p_Mcr;
25800aeed3e9SJustin Hibbits     t_QmPortal              *p_QmPortal;
25810aeed3e9SJustin Hibbits     t_Error                 err = E_OK;
25820aeed3e9SJustin Hibbits 
25830aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR(p_QmCg, E_INVALID_HANDLE);
25840aeed3e9SJustin Hibbits 
25850aeed3e9SJustin Hibbits     p_QmPortal = (t_QmPortal *)p_QmCg->h_QmPortal;
25860aeed3e9SJustin Hibbits 
25870aeed3e9SJustin Hibbits     NCSW_PLOCK(p_QmPortal);
25880aeed3e9SJustin Hibbits     p_Mcc = qm_mc_start(p_QmPortal->p_LowQmPortal);
25890aeed3e9SJustin Hibbits     p_Mcc->initcgr.cgid = p_QmCg->id;
25900aeed3e9SJustin Hibbits 
25910aeed3e9SJustin Hibbits     qm_mc_commit(p_QmPortal->p_LowQmPortal, QM_MCC_VERB_QUERYCGR);
25920aeed3e9SJustin Hibbits     while (!(p_Mcr = qm_mc_result(p_QmPortal->p_LowQmPortal))) ;
25930aeed3e9SJustin Hibbits     ASSERT_COND((p_Mcr->verb & QM_MCR_VERB_MASK) == QM_MCC_VERB_QUERYCGR);
25940aeed3e9SJustin Hibbits     if (p_Mcr->result != QM_MCR_RESULT_OK)
25950aeed3e9SJustin Hibbits     {
25960aeed3e9SJustin Hibbits         PUNLOCK(p_QmPortal);
25970aeed3e9SJustin Hibbits         RETURN_ERROR(MINOR, E_INVALID_STATE, ("QM_MCC_VERB_QUERYCGR failed: %s", mcr_result_str(p_Mcr->result)));
25980aeed3e9SJustin Hibbits     }
25990aeed3e9SJustin Hibbits 
26000aeed3e9SJustin Hibbits     switch(p_QmCgModifyParams->color)
26010aeed3e9SJustin Hibbits     {
26020aeed3e9SJustin Hibbits         case(e_QM_CG_COLOR_GREEN):
26030aeed3e9SJustin Hibbits             if(!p_Mcr->querycgr.cgr.wr_en_g)
26040aeed3e9SJustin Hibbits             {
26050aeed3e9SJustin Hibbits                 PUNLOCK(p_QmPortal);
26060aeed3e9SJustin Hibbits                 RETURN_ERROR(MINOR, E_INVALID_STATE, ("WRED is not enabled for green"));
26070aeed3e9SJustin Hibbits             }
26080aeed3e9SJustin Hibbits             break;
26090aeed3e9SJustin Hibbits         case(e_QM_CG_COLOR_YELLOW):
26100aeed3e9SJustin Hibbits             if(!p_Mcr->querycgr.cgr.wr_en_y)
26110aeed3e9SJustin Hibbits             {
26120aeed3e9SJustin Hibbits                 PUNLOCK(p_QmPortal);
26130aeed3e9SJustin Hibbits                 RETURN_ERROR(MINOR, E_INVALID_STATE, ("WRED is not enabled for yellow"));
26140aeed3e9SJustin Hibbits             }
26150aeed3e9SJustin Hibbits             break;
26160aeed3e9SJustin Hibbits         case(e_QM_CG_COLOR_RED):
26170aeed3e9SJustin Hibbits             if(!p_Mcr->querycgr.cgr.wr_en_r)
26180aeed3e9SJustin Hibbits             {
26190aeed3e9SJustin Hibbits                 PUNLOCK(p_QmPortal);
26200aeed3e9SJustin Hibbits                 RETURN_ERROR(MINOR, E_INVALID_STATE, ("WRED is not enabled for red"));
26210aeed3e9SJustin Hibbits             }
26220aeed3e9SJustin Hibbits             break;
26230aeed3e9SJustin Hibbits     }
26240aeed3e9SJustin Hibbits 
26250aeed3e9SJustin Hibbits     p_Mcc = qm_mc_start(p_QmPortal->p_LowQmPortal);
26260aeed3e9SJustin Hibbits     p_Mcc->initcgr.cgid = p_QmCg->id;
26270aeed3e9SJustin Hibbits 
26280aeed3e9SJustin Hibbits     switch(p_QmCgModifyParams->color)
26290aeed3e9SJustin Hibbits     {
26300aeed3e9SJustin Hibbits         case(e_QM_CG_COLOR_GREEN):
26310aeed3e9SJustin Hibbits             err = CalcWredCurve(&p_QmCgModifyParams->wredParams, &wredParams);
26320aeed3e9SJustin Hibbits             p_Mcc->initcgr.we_mask |= QM_CGR_WE_WR_EN_G | QM_CGR_WE_WR_PARM_G;
26330aeed3e9SJustin Hibbits             p_Mcc->initcgr.cgr.wr_en_g = QM_CGR_EN;
26340aeed3e9SJustin Hibbits             p_Mcc->initcgr.cgr.wr_parm_g.word = wredParams;
26350aeed3e9SJustin Hibbits             break;
26360aeed3e9SJustin Hibbits         case(e_QM_CG_COLOR_YELLOW):
26370aeed3e9SJustin Hibbits             err = CalcWredCurve(&p_QmCgModifyParams->wredParams, &wredParams);
26380aeed3e9SJustin Hibbits             p_Mcc->initcgr.we_mask |= QM_CGR_WE_WR_EN_Y | QM_CGR_WE_WR_PARM_Y;
26390aeed3e9SJustin Hibbits             p_Mcc->initcgr.cgr.wr_en_y = QM_CGR_EN;
26400aeed3e9SJustin Hibbits             p_Mcc->initcgr.cgr.wr_parm_y.word = wredParams;
26410aeed3e9SJustin Hibbits             break;
26420aeed3e9SJustin Hibbits         case(e_QM_CG_COLOR_RED):
26430aeed3e9SJustin Hibbits             err = CalcWredCurve(&p_QmCgModifyParams->wredParams, &wredParams);
26440aeed3e9SJustin Hibbits             p_Mcc->initcgr.we_mask |= QM_CGR_WE_WR_EN_R | QM_CGR_WE_WR_PARM_R;
26450aeed3e9SJustin Hibbits             p_Mcc->initcgr.cgr.wr_en_r = QM_CGR_EN;
26460aeed3e9SJustin Hibbits             p_Mcc->initcgr.cgr.wr_parm_r.word = wredParams;
26470aeed3e9SJustin Hibbits             break;
26480aeed3e9SJustin Hibbits     }
26490aeed3e9SJustin Hibbits     if (err)
26500aeed3e9SJustin Hibbits     {
26510aeed3e9SJustin Hibbits         PUNLOCK(p_QmPortal);
26520aeed3e9SJustin Hibbits         RETURN_ERROR(MINOR, err, NO_MSG);
26530aeed3e9SJustin Hibbits     }
26540aeed3e9SJustin Hibbits 
26550aeed3e9SJustin Hibbits     qm_mc_commit(p_QmPortal->p_LowQmPortal, QM_MCC_VERB_MODIFYCGR);
26560aeed3e9SJustin Hibbits     while (!(p_Mcr = qm_mc_result(p_QmPortal->p_LowQmPortal))) ;
26570aeed3e9SJustin Hibbits     ASSERT_COND((p_Mcr->verb & QM_MCR_VERB_MASK) == QM_MCC_VERB_MODIFYCGR);
26580aeed3e9SJustin Hibbits     if (p_Mcr->result != QM_MCR_RESULT_OK)
26590aeed3e9SJustin Hibbits     {
26600aeed3e9SJustin Hibbits         PUNLOCK(p_QmPortal);
26610aeed3e9SJustin Hibbits         RETURN_ERROR(MINOR, E_INVALID_STATE, ("INITCGR failed: %s", mcr_result_str(p_Mcr->result)));
26620aeed3e9SJustin Hibbits     }
26630aeed3e9SJustin Hibbits     PUNLOCK(p_QmPortal);
26640aeed3e9SJustin Hibbits 
26650aeed3e9SJustin Hibbits     return E_OK;
26660aeed3e9SJustin Hibbits }
26670aeed3e9SJustin Hibbits 
QM_CG_ModifyTailDropThreshold(t_Handle h_QmCg,uint32_t threshold)26680aeed3e9SJustin Hibbits t_Error QM_CG_ModifyTailDropThreshold(t_Handle h_QmCg, uint32_t threshold)
26690aeed3e9SJustin Hibbits {
26700aeed3e9SJustin Hibbits     t_QmCg                  *p_QmCg = (t_QmCg *)h_QmCg;
26710aeed3e9SJustin Hibbits     struct qm_mc_command    *p_Mcc;
26720aeed3e9SJustin Hibbits     struct qm_mc_result     *p_Mcr;
26730aeed3e9SJustin Hibbits     t_QmPortal              *p_QmPortal;
26740aeed3e9SJustin Hibbits     uint32_t                tmpA, tmpN, ta=0, tn=0;
26750aeed3e9SJustin Hibbits     int                     gap, tmp;
26760aeed3e9SJustin Hibbits 
26770aeed3e9SJustin Hibbits     SANITY_CHECK_RETURN_ERROR(p_QmCg, E_INVALID_HANDLE);
26780aeed3e9SJustin Hibbits 
26790aeed3e9SJustin Hibbits     p_QmPortal = (t_QmPortal *)p_QmCg->h_QmPortal;
26800aeed3e9SJustin Hibbits 
26810aeed3e9SJustin Hibbits     NCSW_PLOCK(p_QmPortal);
26820aeed3e9SJustin Hibbits     p_Mcc = qm_mc_start(p_QmPortal->p_LowQmPortal);
26830aeed3e9SJustin Hibbits     p_Mcc->initcgr.cgid = p_QmCg->id;
26840aeed3e9SJustin Hibbits 
26850aeed3e9SJustin Hibbits     qm_mc_commit(p_QmPortal->p_LowQmPortal, QM_MCC_VERB_QUERYCGR);
26860aeed3e9SJustin Hibbits     while (!(p_Mcr = qm_mc_result(p_QmPortal->p_LowQmPortal))) ;
26870aeed3e9SJustin Hibbits     ASSERT_COND((p_Mcr->verb & QM_MCR_VERB_MASK) == QM_MCC_VERB_QUERYCGR);
26880aeed3e9SJustin Hibbits     if (p_Mcr->result != QM_MCR_RESULT_OK)
26890aeed3e9SJustin Hibbits     {
26900aeed3e9SJustin Hibbits         PUNLOCK(p_QmPortal);
26910aeed3e9SJustin Hibbits         RETURN_ERROR(MINOR, E_INVALID_STATE, ("QM_MCC_VERB_QUERYCGR failed: %s", mcr_result_str(p_Mcr->result)));
26920aeed3e9SJustin Hibbits     }
26930aeed3e9SJustin Hibbits 
26940aeed3e9SJustin Hibbits     if(!p_Mcr->querycgr.cgr.cstd_en)
26950aeed3e9SJustin Hibbits     {
26960aeed3e9SJustin Hibbits         PUNLOCK(p_QmPortal);
26970aeed3e9SJustin Hibbits         RETURN_ERROR(MINOR, E_INVALID_STATE, ("Tail Drop is not enabled!"));
26980aeed3e9SJustin Hibbits     }
26990aeed3e9SJustin Hibbits 
27000aeed3e9SJustin Hibbits     p_Mcc = qm_mc_start(p_QmPortal->p_LowQmPortal);
27010aeed3e9SJustin Hibbits     p_Mcc->initcgr.cgid = p_QmCg->id;
27020aeed3e9SJustin Hibbits     p_Mcc->initcgr.we_mask |= QM_CGR_WE_CS_THRES;
27030aeed3e9SJustin Hibbits 
27040aeed3e9SJustin Hibbits     /* express thresh as ta*2^tn */
27050aeed3e9SJustin Hibbits     gap = (int)threshold;
27060aeed3e9SJustin Hibbits     for (tmpA=0 ; tmpA<256; tmpA++ )
27070aeed3e9SJustin Hibbits         for (tmpN=0 ; tmpN<32; tmpN++ )
27080aeed3e9SJustin Hibbits         {
27090aeed3e9SJustin Hibbits             tmp = ABS((int)(threshold - tmpA*(1<<tmpN)));
27100aeed3e9SJustin Hibbits             if (tmp < gap)
27110aeed3e9SJustin Hibbits             {
27120aeed3e9SJustin Hibbits                ta = tmpA;
27130aeed3e9SJustin Hibbits                tn = tmpN;
27140aeed3e9SJustin Hibbits                gap = tmp;
27150aeed3e9SJustin Hibbits             }
27160aeed3e9SJustin Hibbits         }
27170aeed3e9SJustin Hibbits     p_Mcc->initcgr.cgr.cs_thres.TA = ta;
27180aeed3e9SJustin Hibbits     p_Mcc->initcgr.cgr.cs_thres.Tn = tn;
27190aeed3e9SJustin Hibbits 
27200aeed3e9SJustin Hibbits     qm_mc_commit(p_QmPortal->p_LowQmPortal, QM_MCC_VERB_MODIFYCGR);
27210aeed3e9SJustin Hibbits     while (!(p_Mcr = qm_mc_result(p_QmPortal->p_LowQmPortal))) ;
27220aeed3e9SJustin Hibbits     ASSERT_COND((p_Mcr->verb & QM_MCR_VERB_MASK) == QM_MCC_VERB_MODIFYCGR);
27230aeed3e9SJustin Hibbits     if (p_Mcr->result != QM_MCR_RESULT_OK)
27240aeed3e9SJustin Hibbits     {
27250aeed3e9SJustin Hibbits         PUNLOCK(p_QmPortal);
27260aeed3e9SJustin Hibbits         RETURN_ERROR(MINOR, E_INVALID_STATE, ("INITCGR failed: %s", mcr_result_str(p_Mcr->result)));
27270aeed3e9SJustin Hibbits     }
27280aeed3e9SJustin Hibbits     PUNLOCK(p_QmPortal);
27290aeed3e9SJustin Hibbits 
27300aeed3e9SJustin Hibbits     return E_OK;
27310aeed3e9SJustin Hibbits }
27320aeed3e9SJustin Hibbits 
2733