The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/contrib/ncsw/Peripherals/BM/bm_portal.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /******************************************************************************
    2 
    3  © 1995-2003, 2004, 2005-2011 Freescale Semiconductor, Inc.
    4  All rights reserved.
    5 
    6  This is proprietary source code of Freescale Semiconductor Inc.,
    7  and its use is subject to the NetComm Device Drivers EULA.
    8  The copyright notice above does not evidence any actual or intended
    9  publication of such source code.
   10 
   11  ALTERNATIVELY, redistribution and use in source and binary forms, with
   12  or without modification, are permitted provided that the following
   13  conditions are met:
   14      * Redistributions of source code must retain the above copyright
   15        notice, this list of conditions and the following disclaimer.
   16      * Redistributions in binary form must reproduce the above copyright
   17        notice, this list of conditions and the following disclaimer in the
   18        documentation and/or other materials provided with the distribution.
   19      * Neither the name of Freescale Semiconductor nor the
   20        names of its contributors may be used to endorse or promote products
   21        derived from this software without specific prior written permission.
   22 
   23  THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
   24  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
   25  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   26  DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
   27  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
   28  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   29  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   30  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   31  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   32  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   33  *
   34 
   35  **************************************************************************/
   36 /******************************************************************************
   37  @File          bm.c
   38 
   39  @Description   BM
   40 *//***************************************************************************/
   41 #include "error_ext.h"
   42 #include "std_ext.h"
   43 #include "string_ext.h"
   44 #include "mem_ext.h"
   45 #include "core_ext.h"
   46 
   47 #include "bm.h"
   48 
   49 
   50 #define __ERR_MODULE__  MODULE_BM
   51 
   52 
   53 /****************************************/
   54 /*       static functions               */
   55 /****************************************/
   56 
   57 static uint32_t __poll_portal_slow(t_BmPortal *p);
   58 static void __poll_portal_fast(t_BmPortal *p);
   59 
   60 /* Portal interrupt handler */
   61 static void portal_isr(void *ptr)
   62 {
   63     t_BmPortal *portal = ptr;
   64         /* Only do fast-path handling if it's required */
   65     if (portal->flags & BMAN_PORTAL_FLAG_IRQ_FAST)
   66         __poll_portal_fast(portal);
   67     __poll_portal_slow(portal);
   68 
   69 }
   70 
   71 /**
   72  * bman_create_portal - Manage a Bman s/w portal
   73  * @portal: the s/w corenet portal to use
   74  * @flags: bit-mask of BMAN_PORTAL_FLAG_*** options
   75  * @pools: bit-array of buffer pools available to this portal
   76  * @portal_ctx: opaque user-supplied data to be associated with the portal
   77  *
   78  * Creates a managed portal object. @irq is only used if @flags specifies
   79  * BMAN_PORTAL_FLAG_IRQ. @pools is copied, so the caller can do as they please
   80  * with it after the function returns. It will only be possible to configure
   81  * buffer pool objects as "suppliers" if they are specified in @pools, and the
   82  * driver will only track depletion state changes to the same subset of buffer
   83  * pools. If @pools is NULL, buffer pool depletion state will not be tracked.
   84  * If the BMAN_PORTAL_FLAG_RECOVER flag is specified, then the function will
   85  * attempt to expire any existing RCR entries, otherwise the function will fail
   86  * if RCR is non-empty. If the BMAN_PORTAL_FLAG_WAIT flag is set, the function
   87  * is allowed to block waiting for expiration of RCR. BMAN_PORTAL_FLAG_WAIT_INT
   88  * makes any blocking interruptible.
   89  */
   90 
   91 static t_Error bman_create_portal(t_BmPortal *p_BmPortal,
   92                                   uint32_t flags,
   93                                   const struct bman_depletion *pools)
   94 {
   95     int                             ret = 0;
   96     uint8_t                         bpid = 0;
   97     e_BmPortalRcrConsumeMode        rcr_cmode;
   98     e_BmPortalProduceMode           pmode;
   99 
  100     pmode     = e_BmPortalPVB;
  101     rcr_cmode = (flags & BMAN_PORTAL_FLAG_CACHE) ? e_BmPortalRcrCCE : e_BmPortalRcrCCI;
  102 
  103     switch (pmode)
  104     {
  105         case e_BmPortalPCI:
  106             p_BmPortal->cbs[BM_RCR_RING].f_BmCommitCb = bm_rcr_pci_commit;
  107             break;
  108         case e_BmPortalPCE:
  109             p_BmPortal->cbs[BM_RCR_RING].f_BmCommitCb = bm_rcr_pce_commit;
  110             break;
  111         case e_BmPortalPVB:
  112             p_BmPortal->cbs[BM_RCR_RING].f_BmCommitCb = bm_rcr_pvb_commit;
  113             break;
  114     }
  115     switch (rcr_cmode)
  116     {
  117         case e_BmPortalRcrCCI:
  118             p_BmPortal->cbs[BM_RCR_RING].f_BmUpdateCb      = bm_rcr_cci_update;
  119             p_BmPortal->cbs[BM_RCR_RING].f_BmPrefetchCb    = NULL;
  120             break;
  121         case e_BmPortalRcrCCE:
  122             p_BmPortal->cbs[BM_RCR_RING].f_BmUpdateCb      = bm_rcr_cce_update;
  123             p_BmPortal->cbs[BM_RCR_RING].f_BmPrefetchCb    = bm_rcr_cce_prefetch;
  124             break;
  125     }
  126 
  127     if (bm_rcr_init(p_BmPortal->p_BmPortalLow, pmode, rcr_cmode)) {
  128         REPORT_ERROR(MAJOR, E_INVALID_STATE, ("RCR initialization failed"));
  129         goto fail_rcr;
  130     }
  131     if (bm_mc_init(p_BmPortal->p_BmPortalLow)) {
  132         REPORT_ERROR(MAJOR, E_INVALID_STATE, ("MC initialization failed"));
  133         goto fail_mc;
  134     }
  135     p_BmPortal->pools[0] = *pools;
  136     bman_depletion_init(&p_BmPortal->pools[1]);
  137     while (bpid < BM_MAX_NUM_OF_POOLS) {
  138         /* Default to all BPIDs disabled, we enable as required
  139          * at run-time. */
  140         bm_isr_bscn_mask(p_BmPortal->p_BmPortalLow, bpid, 0);
  141         bpid++;
  142     }
  143     p_BmPortal->flags = flags;
  144     p_BmPortal->slowpoll = 0;
  145     p_BmPortal->rcrProd = p_BmPortal->rcrCons = 0;
  146     memset(&p_BmPortal->depletionPoolsTable, 0, sizeof(p_BmPortal->depletionPoolsTable));
  147     /* Write-to-clear any stale interrupt status bits */
  148     bm_isr_disable_write(p_BmPortal->p_BmPortalLow, 0xffffffff);
  149     bm_isr_status_clear(p_BmPortal->p_BmPortalLow, 0xffffffff);
  150     bm_isr_enable_write(p_BmPortal->p_BmPortalLow, BM_PIRQ_RCRI | BM_PIRQ_BSCN);
  151     if (flags & BMAN_PORTAL_FLAG_IRQ)
  152     {
  153         XX_SetIntr(p_BmPortal->irq, portal_isr, p_BmPortal);
  154         XX_EnableIntr(p_BmPortal->irq);
  155         /* Enable the bits that make sense */
  156         bm_isr_uninhibit(p_BmPortal->p_BmPortalLow);
  157     } else
  158         /* without IRQ, we can't block */
  159         flags &= ~BMAN_PORTAL_FLAG_WAIT;
  160     /* Need RCR to be empty before continuing */
  161     bm_isr_disable_write(p_BmPortal->p_BmPortalLow, (uint32_t)~BM_PIRQ_RCRI);
  162     if (!(flags & BMAN_PORTAL_FLAG_RECOVER) ||
  163         !(flags & BMAN_PORTAL_FLAG_WAIT))
  164         ret = bm_rcr_get_fill(p_BmPortal->p_BmPortalLow);
  165     if (ret) {
  166         REPORT_ERROR(MAJOR, E_INVALID_STATE, ("RCR unclean, need recovery"));
  167         goto fail_rcr_empty;
  168     }
  169     bm_isr_disable_write(p_BmPortal->p_BmPortalLow, 0);
  170     return E_OK;
  171 fail_rcr_empty:
  172     bm_mc_finish(p_BmPortal->p_BmPortalLow);
  173 fail_mc:
  174     bm_rcr_finish(p_BmPortal->p_BmPortalLow);
  175 fail_rcr:
  176     XX_Free(p_BmPortal);
  177     return ERROR_CODE(E_INVALID_STATE);
  178 }
  179 
  180 static void bman_destroy_portal(t_BmPortal* p_BmPortal)
  181 {
  182     BmUpdate(p_BmPortal, BM_RCR_RING);
  183     if (p_BmPortal->flags & BMAN_PORTAL_FLAG_IRQ)
  184     {
  185         XX_DisableIntr(p_BmPortal->irq);
  186         XX_FreeIntr(p_BmPortal->irq);
  187     }
  188     bm_mc_finish(p_BmPortal->p_BmPortalLow);
  189     bm_rcr_finish(p_BmPortal->p_BmPortalLow);
  190     XX_Free(p_BmPortal->p_BmPortalLow);
  191 }
  192 
  193 /* When release logic waits on available RCR space, we need a global waitqueue
  194  * in the case of "affine" use (as the waits wake on different cpus which means
  195  * different portals - so we can't wait on any per-portal waitqueue). */
  196 
  197 static uint32_t __poll_portal_slow(t_BmPortal* p_BmPortal)
  198 {
  199     struct bman_depletion tmp;
  200     t_BmPool              *p_BmPool;
  201     uint32_t ret,is = bm_isr_status_read(p_BmPortal->p_BmPortalLow);
  202     ret = is;
  203 
  204     /* There is a gotcha to be aware of. If we do the query before clearing
  205      * the status register, we may miss state changes that occur between the
  206      * two. If we write to clear the status register before the query, the
  207      * cache-enabled query command may overtake the status register write
  208      * unless we use a heavyweight sync (which we don't want). Instead, we
  209      * write-to-clear the status register then *read it back* before doing
  210      * the query, hence the odd while loop with the 'is' accumulation. */
  211     if (is & BM_PIRQ_BSCN) {
  212         uint32_t i, j;
  213         uint32_t __is;
  214         bm_isr_status_clear(p_BmPortal->p_BmPortalLow, BM_PIRQ_BSCN);
  215         while ((__is = bm_isr_status_read(p_BmPortal->p_BmPortalLow)) & BM_PIRQ_BSCN) {
  216             is |= __is;
  217             bm_isr_status_clear(p_BmPortal->p_BmPortalLow, BM_PIRQ_BSCN);
  218         }
  219         is &= ~BM_PIRQ_BSCN;
  220         BmPortalQuery(p_BmPortal, &tmp, TRUE);
  221         for (i = 0; i < 2; i++) {
  222             uint32_t idx = i * 32;
  223             /* tmp is a mask of currently-depleted pools.
  224              * pools[0] is mask of those we care about.
  225              * pools[1] is our previous view (we only want to
  226              * be told about changes). */
  227             tmp.__state[i] &= p_BmPortal->pools[0].__state[i];
  228             if (tmp.__state[i] == p_BmPortal->pools[1].__state[i])
  229                 /* fast-path, nothing to see, move along */
  230                 continue;
  231             for (j = 0; j <= 31; j++, idx++) {
  232                 int b4 = bman_depletion_get(&p_BmPortal->pools[1], (uint8_t)idx);
  233                 int af = bman_depletion_get(&tmp, (uint8_t)idx);
  234                 if (b4 == af)
  235                     continue;
  236                 p_BmPool = p_BmPortal->depletionPoolsTable[idx];
  237                 ASSERT_COND(p_BmPool->f_Depletion);
  238                 p_BmPool->f_Depletion(p_BmPool->h_App, (bool)af);
  239             }
  240         }
  241         p_BmPortal->pools[1] = tmp;
  242     }
  243 
  244     if (is & BM_PIRQ_RCRI) {
  245         NCSW_PLOCK(p_BmPortal);
  246         p_BmPortal->rcrCons += BmUpdate(p_BmPortal, BM_RCR_RING);
  247         bm_rcr_set_ithresh(p_BmPortal->p_BmPortalLow, 0);
  248         PUNLOCK(p_BmPortal);
  249         bm_isr_status_clear(p_BmPortal->p_BmPortalLow, BM_PIRQ_RCRI);
  250         is &= ~BM_PIRQ_RCRI;
  251     }
  252 
  253     /* There should be no status register bits left undefined */
  254     ASSERT_COND(!is);
  255     return ret;
  256 }
  257 
  258 static void __poll_portal_fast(t_BmPortal* p_BmPortal)
  259 {
  260     UNUSED(p_BmPortal);
  261     /* nothing yet, this is where we'll put optimised RCR consumption
  262      * tracking */
  263 }
  264 
  265 
  266 static __inline__ void rel_set_thresh(t_BmPortal *p_BmPortal, int check)
  267 {
  268     if (!check || !bm_rcr_get_ithresh(p_BmPortal->p_BmPortalLow))
  269         bm_rcr_set_ithresh(p_BmPortal->p_BmPortalLow, RCR_ITHRESH);
  270 }
  271 
  272 /* Used as a wait_event() expression. If it returns non-NULL, any lock will
  273  * remain held. */
  274 static struct bm_rcr_entry *try_rel_start(t_BmPortal *p_BmPortal)
  275 {
  276     struct bm_rcr_entry *r;
  277 
  278     NCSW_PLOCK(p_BmPortal);
  279     if (bm_rcr_get_avail((p_BmPortal)->p_BmPortalLow) < RCR_THRESH)
  280         BmUpdate(p_BmPortal, BM_RCR_RING);
  281     r = bm_rcr_start((p_BmPortal)->p_BmPortalLow);
  282     if (!r) {
  283         rel_set_thresh(p_BmPortal, 1);
  284         PUNLOCK(p_BmPortal);
  285     }
  286     return r;
  287 }
  288 
  289 static __inline__ t_Error wait_rel_start(t_BmPortal             *p_BmPortal,
  290                                          struct bm_rcr_entry    **rel,
  291                                          uint32_t               flags)
  292 {
  293     int tries = 100;
  294 
  295     UNUSED(flags);
  296     do {
  297         *rel = try_rel_start(p_BmPortal);
  298         XX_Sleep(1);
  299     } while (!*rel && --tries);
  300 
  301     if (!(*rel))
  302         return ERROR_CODE(E_BUSY);
  303 
  304     return E_OK;
  305 }
  306 
  307 /* This copies Qman's eqcr_completed() routine, see that for details */
  308 static int rel_completed(t_BmPortal *p_BmPortal, uint32_t rcr_poll)
  309 {
  310     uint32_t tr_cons = p_BmPortal->rcrCons;
  311     if (rcr_poll & 0xc0000000) {
  312         rcr_poll &= 0x7fffffff;
  313         tr_cons ^= 0x80000000;
  314     }
  315     if (tr_cons >= rcr_poll)
  316         return 1;
  317     if ((rcr_poll - tr_cons) > BM_RCR_SIZE)
  318         return 1;
  319     if (!bm_rcr_get_fill(p_BmPortal->p_BmPortalLow))
  320         /* If RCR is empty, we must have completed */
  321         return 1;
  322     rel_set_thresh(p_BmPortal, 0);
  323     return 0;
  324 }
  325 
  326 static __inline__ void rel_commit(t_BmPortal *p_BmPortal, uint32_t flags,uint8_t num)
  327 {
  328     uint32_t rcr_poll;
  329 
  330     BmCommit(p_BmPortal, BM_RCR_RING, (uint8_t)(BM_RCR_VERB_CMD_BPID_SINGLE | (num & BM_RCR_VERB_BUFCOUNT_MASK)));
  331     /* increment the producer count and capture it for SYNC */
  332     rcr_poll = ++p_BmPortal->rcrProd;
  333     if ((flags & BMAN_RELEASE_FLAG_WAIT_SYNC) ==
  334         BMAN_RELEASE_FLAG_WAIT_SYNC)
  335         rel_set_thresh(p_BmPortal, 1);
  336     PUNLOCK(p_BmPortal);
  337     if ((flags & BMAN_RELEASE_FLAG_WAIT_SYNC) !=
  338         BMAN_RELEASE_FLAG_WAIT_SYNC)
  339         return;
  340     rel_completed(p_BmPortal, rcr_poll);
  341 }
  342 
  343 
  344 /****************************************/
  345 /*       Inter-Module functions        */
  346 /****************************************/
  347 
  348 /**
  349  * bman_release - Release buffer(s) to the buffer pool
  350  * @p_BmPool: the buffer pool object to release to
  351  * @bufs: an array of buffers to release
  352  * @num: the number of buffers in @bufs (1-8)
  353  * @flags: bit-mask of BMAN_RELEASE_FLAG_*** options
  354  *
  355  * Adds the given buffers to RCR entries. If the portal @p_BmPortal was created with the
  356  * "COMPACT" flag, then it will be using a compaction algorithm to improve
  357  * utilization of RCR. As such, these buffers may join an existing ring entry
  358  * and/or it may not be issued right away so as to allow future releases to join
  359  * the same ring entry. Use the BMAN_RELEASE_FLAG_NOW flag to override this
  360  * behavior by committing the RCR entry (or entries) right away. If the RCR
  361  * ring is full, the function will return -EBUSY unless BMAN_RELEASE_FLAG_WAIT
  362  * is selected, in which case it will sleep waiting for space to become
  363  * available in RCR. If the function receives a signal before such time (and
  364  * BMAN_RELEASE_FLAG_WAIT_INT is set), the function returns -EINTR. Otherwise,
  365  * it returns zero.
  366  */
  367 
  368 t_Error BmPortalRelease(t_Handle h_BmPortal,
  369                         uint8_t bpid,
  370                         struct bm_buffer *bufs,
  371                         uint8_t num,
  372                         uint32_t flags)
  373 {
  374     t_BmPortal          *p_BmPortal = (t_BmPortal *)h_BmPortal;
  375     struct bm_rcr_entry *r;
  376     uint8_t i;
  377 
  378     SANITY_CHECK_RETURN_ERROR(p_BmPortal, E_INVALID_HANDLE);
  379     /* TODO: I'm ignoring BMAN_PORTAL_FLAG_COMPACT for now. */
  380     r = try_rel_start(p_BmPortal);
  381     if (!r) {
  382         if (flags & BMAN_RELEASE_FLAG_WAIT) {
  383             t_Error ret = wait_rel_start(p_BmPortal, &r, flags);
  384             if (ret)
  385                 return ret;
  386         } else
  387             return ERROR_CODE(E_BUSY);
  388         ASSERT_COND(r != NULL);
  389     }
  390     r->bpid = bpid;
  391     for (i = 0; i < num; i++) {
  392         r->bufs[i].hi = bufs[i].hi;
  393         r->bufs[i].lo = bufs[i].lo;
  394     }
  395     /* Issue the release command and wait for sync if requested. NB: the
  396      * commit can't fail, only waiting can. Don't propagate any failure if a
  397      * signal arrives, otherwise the caller can't distinguish whether the
  398      * release was issued or not. Code for user-space can check
  399      * signal_pending() after we return. */
  400     rel_commit(p_BmPortal, flags, num);
  401     return E_OK;
  402 }
  403 
  404 uint8_t BmPortalAcquire(t_Handle h_BmPortal,
  405                         uint8_t  bpid,
  406                         struct bm_buffer *bufs,
  407                         uint8_t num)
  408 {
  409     t_BmPortal          *p_BmPortal = (t_BmPortal *)h_BmPortal;
  410     struct bm_mc_command *mcc;
  411     struct bm_mc_result *mcr;
  412     uint8_t ret = 0;
  413 
  414     SANITY_CHECK_RETURN_VALUE(p_BmPortal, E_INVALID_HANDLE, 0);
  415     NCSW_PLOCK(p_BmPortal);
  416     mcc = bm_mc_start(p_BmPortal->p_BmPortalLow);
  417     mcc->acquire.bpid = bpid;
  418     bm_mc_commit(p_BmPortal->p_BmPortalLow,
  419                  (uint8_t)(BM_MCC_VERB_CMD_ACQUIRE |
  420                            (num & BM_MCC_VERB_ACQUIRE_BUFCOUNT)));
  421     while (!(mcr = bm_mc_result(p_BmPortal->p_BmPortalLow))) ;
  422     ret = num = (uint8_t)(mcr->verb & BM_MCR_VERB_ACQUIRE_BUFCOUNT);
  423     ASSERT_COND(num <= 8);
  424     while (num--) {
  425         bufs[num].bpid = bpid;
  426         bufs[num].hi = mcr->acquire.bufs[num].hi;
  427         bufs[num].lo = mcr->acquire.bufs[num].lo;
  428     }
  429     PUNLOCK(p_BmPortal);
  430     return ret;
  431 }
  432 
  433 t_Error BmPortalQuery(t_Handle h_BmPortal, struct bman_depletion *p_Pools, bool depletion)
  434 {
  435     t_BmPortal          *p_BmPortal = (t_BmPortal *)h_BmPortal;
  436     struct bm_mc_result *mcr;
  437 
  438     SANITY_CHECK_RETURN_ERROR(p_BmPortal, E_INVALID_HANDLE);
  439 
  440     NCSW_PLOCK(p_BmPortal);
  441     bm_mc_start(p_BmPortal->p_BmPortalLow);
  442     bm_mc_commit(p_BmPortal->p_BmPortalLow, BM_MCC_VERB_CMD_QUERY);
  443     while (!(mcr = bm_mc_result(p_BmPortal->p_BmPortalLow))) ;
  444     if (depletion)
  445         *p_Pools = mcr->query.ds.state;
  446     else
  447         *p_Pools = mcr->query.as.state;
  448     PUNLOCK(p_BmPortal);
  449     return E_OK;
  450 }
  451 
  452 /****************************************/
  453 /*       API Init unit functions        */
  454 /****************************************/
  455 
  456 t_Handle BM_PORTAL_Config(t_BmPortalParam *p_BmPortalParam)
  457 {
  458     t_BmPortal          *p_BmPortal;
  459 
  460     SANITY_CHECK_RETURN_VALUE(p_BmPortalParam, E_INVALID_HANDLE, NULL);
  461     SANITY_CHECK_RETURN_VALUE(p_BmPortalParam->h_Bm, E_INVALID_HANDLE, NULL);
  462 
  463     p_BmPortal = (t_BmPortal *)XX_Malloc(sizeof(t_BmPortal));
  464     if (!p_BmPortal)
  465     {
  466         REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Bm Portal obj!!!"));
  467         return NULL;
  468     }
  469     memset(p_BmPortal, 0, sizeof(t_BmPortal));
  470 
  471     p_BmPortal->p_BmPortalLow = (struct bm_portal *)XX_Malloc(sizeof(struct bm_portal));
  472     if (!p_BmPortal->p_BmPortalLow)
  473     {
  474         XX_Free(p_BmPortal);
  475         REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Low bm portal obj!!!"));
  476         return NULL;
  477     }
  478     memset(p_BmPortal->p_BmPortalLow, 0, sizeof(struct bm_portal));
  479 
  480     p_BmPortal->p_BmPortalDriverParams = (t_BmPortalDriverParams *)XX_Malloc(sizeof(t_BmPortalDriverParams));
  481     if (!p_BmPortal->p_BmPortalDriverParams)
  482     {
  483         XX_Free(p_BmPortal);
  484         XX_Free(p_BmPortal->p_BmPortalLow);
  485         REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Bm Portal driver parameters"));
  486         return NULL;
  487     }
  488     memset(p_BmPortal->p_BmPortalDriverParams, 0, sizeof(t_BmPortalDriverParams));
  489 
  490     p_BmPortal->p_BmPortalLow->addr.addr_ce = UINT_TO_PTR(p_BmPortalParam->ceBaseAddress);
  491     p_BmPortal->p_BmPortalLow->addr.addr_ci = UINT_TO_PTR(p_BmPortalParam->ciBaseAddress);
  492     p_BmPortal->cpu   = (int)p_BmPortalParam->swPortalId;
  493     p_BmPortal->irq   = p_BmPortalParam->irq;
  494 
  495     p_BmPortal->h_Bm    = p_BmPortalParam->h_Bm;
  496 
  497     p_BmPortal->p_BmPortalDriverParams->hwExtStructsMemAttr     = DEFAULT_memAttr;
  498     bman_depletion_fill(&p_BmPortal->p_BmPortalDriverParams->mask);
  499 
  500     return p_BmPortal;
  501 }
  502 
  503 t_Error BM_PORTAL_Init(t_Handle h_BmPortal)
  504 {
  505     t_BmPortal          *p_BmPortal = (t_BmPortal *)h_BmPortal;
  506     uint32_t            flags;
  507 
  508     SANITY_CHECK_RETURN_ERROR(p_BmPortal, E_INVALID_HANDLE);
  509 
  510     flags = (uint32_t)((p_BmPortal->irq != NO_IRQ) ? BMAN_PORTAL_FLAG_IRQ : 0);
  511     flags |= ((p_BmPortal->p_BmPortalDriverParams->hwExtStructsMemAttr & MEMORY_ATTR_CACHEABLE) ?
  512            BMAN_PORTAL_FLAG_CACHE : 0);
  513 
  514     if (bman_create_portal(p_BmPortal,flags,&p_BmPortal->p_BmPortalDriverParams->mask)!=E_OK)
  515     {
  516         BM_PORTAL_Free(p_BmPortal);
  517         RETURN_ERROR(MAJOR, E_NULL_POINTER, ("create portal failed"));
  518     }
  519     BmSetPortalHandle(p_BmPortal->h_Bm, (t_Handle)p_BmPortal, (e_DpaaSwPortal)p_BmPortal->cpu);
  520 
  521     XX_Free(p_BmPortal->p_BmPortalDriverParams);
  522     p_BmPortal->p_BmPortalDriverParams = NULL;
  523 
  524     DBG(TRACE,("Bman-Portal (%d) @ %p:%p\n",
  525                p_BmPortal->cpu,
  526                p_BmPortal->p_BmPortalLow->addr.addr_ce,
  527                p_BmPortal->p_BmPortalLow->addr.addr_ci
  528                ));
  529 
  530     DBG(TRACE,("Bman-Portal (%d) @ 0x%016llx:0x%016llx",
  531                p_BmPortal->cpu,
  532                (uint64_t)XX_VirtToPhys(p_BmPortal->p_BmPortalLow->addr.addr_ce),
  533                (uint64_t)XX_VirtToPhys(p_BmPortal->p_BmPortalLow->addr.addr_ci)
  534                ));
  535 
  536     return E_OK;
  537 }
  538 
  539 t_Error BM_PORTAL_Free(t_Handle h_BmPortal)
  540 {
  541     t_BmPortal  *p_BmPortal = (t_BmPortal *)h_BmPortal;
  542 
  543     if (!p_BmPortal)
  544        return ERROR_CODE(E_INVALID_HANDLE);
  545     BmSetPortalHandle(p_BmPortal->h_Bm, NULL, (e_DpaaSwPortal)p_BmPortal->cpu);
  546     bman_destroy_portal(p_BmPortal);
  547     XX_Free(p_BmPortal);
  548     return E_OK;
  549 }
  550 
  551 t_Error BM_PORTAL_ConfigMemAttr(t_Handle h_BmPortal, uint32_t hwExtStructsMemAttr)
  552 {
  553     t_BmPortal  *p_BmPortal = (t_BmPortal *)h_BmPortal;
  554 
  555     SANITY_CHECK_RETURN_ERROR(p_BmPortal, E_INVALID_HANDLE);
  556     SANITY_CHECK_RETURN_ERROR(p_BmPortal->p_BmPortalDriverParams, E_INVALID_HANDLE);
  557 
  558     p_BmPortal->p_BmPortalDriverParams->hwExtStructsMemAttr = hwExtStructsMemAttr;
  559 
  560     return E_OK;
  561 }

Cache object: e55a3611555463f5f44a1423453d7739


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.