third_party/virtualbox/src/VBox/Devices/Network/DevE1000.cpp
/**
 * Transmit pending descriptors.
 *
 * @returns VBox status code.  VERR_TRY_AGAIN is returned if we're busy.
 *
 * @param   pThis              The E1000 state.
 * @param   fOnWorkerThread     Whether we're on a worker thread or on an EMT.
 */
Transmit pending descriptors.
@returns VBox status code.  VERR_TRY_AGAIN is returned if we're busy.

@param   pThis              The E1000 state.
@param   fOnWorkerThread     Whether we're on a worker thread or on an EMT.
Transmit pending descriptors . @returns VBox status code . VERR_TRY_AGAIN is returned if we ' re busy . @param pThis The E1000 state . @param fOnWorkerThread Whether we ' re on a worker thread or on an EMT .
static int e1kXmitPending(PE1KSTATE pThis, bool fOnWorkerThread)
{
    int rc = VINF_SUCCESS;
    if (!(TCTL & TCTL_EN))
        return VINF_SUCCESS;
    rc = e1kCsTxEnter(pThis, VERR_SEM_BUSY);
    if (RT_LIKELY(rc == VINF_SUCCESS))
    {
        PPDMINETWORKUP pDrv = pThis->CTX_SUFF(pDrv);
        if (pDrv)
        {
            rc = pDrv->pfnBeginXmit(pDrv, fOnWorkerThread);
            if (RT_FAILURE(rc))
            {
                e1kCsTxLeave(pThis);
                return rc;
            }
        }
        while (TDH != TDT && !pThis->fLocked)
        {
            E1KTXDESC desc;
            E1kLog3(("%s About to process new TX descriptor at %08x%08x, TDLEN=%08x, TDH=%08x, TDT=%08x\n",
                     pThis->szPrf, TDBAH, TDBAL + TDH * sizeof(desc), TDLEN, TDH, TDT));
            e1kLoadDesc(pThis, &desc, ((uint64_t)TDBAH << 32) + TDBAL + TDH * sizeof(desc));
            rc = e1kXmitDesc(pThis, &desc, e1kDescAddr(TDBAH, TDBAL, TDH), fOnWorkerThread);
            if (RT_FAILURE(rc))
                break;
            if (++TDH * sizeof(desc) >= TDLEN)
                TDH = 0;
            if (e1kGetTxLen(pThis) <= GET_BITS(TXDCTL, LWTHRESH)*8)
            {
                E1kLog2(("%s Low on transmit descriptors, raise ICR.TXD_LOW, len=%x thresh=%x\n",
                         pThis->szPrf, e1kGetTxLen(pThis), GET_BITS(TXDCTL, LWTHRESH)*8));
                e1kRaiseInterrupt(pThis, VERR_SEM_BUSY, ICR_TXD_LOW);
            }
            STAM_PROFILE_ADV_STOP(&pThis->CTX_SUFF_Z(StatTransmit), a);
        }
        if (pDrv)
            pDrv->pfnEndXmit(pDrv);
        e1kCsTxLeave(pThis);
    }
    return rc;
}
static int e1kXmitPending ( PE1KSTATE pThis , bool fOnWorkerThread ) { int rc = VINF_SUCCESS ; if ( ! ( TCTL & TCTL_EN ) ) return VINF_SUCCESS ; rc = e1kCsTxEnter ( pThis , VERR_SEM_BUSY ) ; if ( RT_LIKELY ( rc == VINF_SUCCESS ) ) { PPDMINETWORKUP pDrv = pThis -> CTX_SUFF ( pDrv ) ; if ( pDrv ) { rc = pDrv -> pfnBeginXmit ( pDrv , fOnWorkerThread ) ; if ( RT_FAILURE ( rc ) ) { e1kCsTxLeave ( pThis ) ; return rc ; } } while ( TDH != TDT && ! pThis -> fLocked ) { E1KTXDESC desc ; E1kLog3 ( ( " \n " , pThis -> szPrf , TDBAH , TDBAL + TDH * sizeof ( desc ) , TDLEN , TDH , TDT ) ) ; e1kLoadDesc ( pThis , & desc , ( ( uint64_t ) TDBAH << 32 ) + TDBAL + TDH * sizeof ( desc ) ) ; rc = e1kXmitDesc ( pThis , & desc , e1kDescAddr ( TDBAH , TDBAL , TDH ) , fOnWorkerThread ) ; if ( RT_FAILURE ( rc ) ) break ; if ( ++ TDH * sizeof ( desc ) >= TDLEN ) TDH = 0 ; if ( e1kGetTxLen ( pThis ) <= GET_BITS ( TXDCTL , LWTHRESH ) * 8 ) { E1kLog2 ( ( " \n " , pThis -> szPrf , e1kGetTxLen ( pThis ) , GET_BITS ( TXDCTL , LWTHRESH ) * 8 ) ) ; e1kRaiseInterrupt ( pThis , VERR_SEM_BUSY , ICR_TXD_LOW ) ; } STAM_PROFILE_ADV_STOP ( & pThis -> CTX_SUFF_Z ( StatTransmit ) , a ) ; } if ( pDrv ) pDrv -> pfnEndXmit ( pDrv ) ; e1kCsTxLeave ( pThis ) ; } return rc ; }
Transmit pending descriptors.
Transmit pending descriptors .
/* Check if transmitter is enabled. */ /*
     * Grab the xmit lock of the driver as well as the E1K device state.
     */ /*
         * Process all pending descriptors.
         * Note! Do not process descriptors in locked state
         */ /* If we failed to transmit descriptor we will try it again later */ /// @todo uncomment: pThis->uStatIntTXQE++; /// @todo uncomment: e1kRaiseInterrupt(pThis, ICR_TXQE); /*
         * Release the lock.
         */