third_party/virtualbox/src/VBox/Devices/Network/DevE1000.cpp
/**
 * Write the descriptor back to guest memory and notify the guest.
 *
 * @param   pThis       The device state structure.
 * @param   pDesc       Pointer to the descriptor have been transmitted.
 * @param   addr        Physical address of the descriptor in guest memory.
 * @thread  E1000_TX
 */
Write the descriptor back to guest memory and notify the guest.
@param   pThis       The device state structure.
@param   pDesc       Pointer to the descriptor have been transmitted.
@param   addr        Physical address of the descriptor in guest memory.
Write the descriptor back to guest memory and notify the guest . @param pThis The device state structure . @param pDesc Pointer to the descriptor have been transmitted . @param addr Physical address of the descriptor in guest memory .
static void e1kDescReport(PE1KSTATE pThis, E1KTXDESC *pDesc, RTGCPHYS addr)
{
    if (pDesc->legacy.cmd.fRS || pDesc->legacy.cmd.fRPS)
    {
        pDesc->legacy.dw3.fDD = 1; 
        e1kWriteBackDesc(pThis, pDesc, addr);
        if (pDesc->legacy.cmd.fEOP)
        {
            if (pThis->fTidEnabled && pDesc->legacy.cmd.fIDE)
            {
                E1K_INC_ISTAT_CNT(pThis->uStatTxIDE);
                e1kArmTimer(pThis, pThis->CTX_SUFF(pTIDTimer), TIDV);
# ifndef E1K_NO_TAD
                E1kLog2(("%s Checking if TAD timer is running\n",
                         pThis->szPrf));
                if (TADV != 0 && !TMTimerIsActive(pThis->CTX_SUFF(pTADTimer)))
                    e1kArmTimer(pThis, pThis->CTX_SUFF(pTADTimer), TADV);
# endif 
            }
            else
            {
                if (pThis->fTidEnabled)
                {
                    E1kLog2(("%s No IDE set, cancel TAD timer and raise interrupt\n",
                             pThis->szPrf));
# ifndef E1K_NO_TAD
                    TMTimerStop(pThis->CTX_SUFF(pTADTimer));
# endif
                    TMTimerStop(pThis->CTX_SUFF(pTIDTimer));
                }
                E1K_INC_ISTAT_CNT(pThis->uStatIntTx);
                e1kRaiseInterrupt(pThis, VERR_SEM_BUSY, ICR_TXDW);
            }
        }
    }
    else
    {
        E1K_INC_ISTAT_CNT(pThis->uStatTxNoRS);
    }
}
static void e1kDescReport ( PE1KSTATE pThis , E1KTXDESC * pDesc , RTGCPHYS addr ) { if ( pDesc -> legacy . cmd . fRS || pDesc -> legacy . cmd . fRPS ) { pDesc -> legacy . dw3 . fDD = 1 ; e1kWriteBackDesc ( pThis , pDesc , addr ) ; if ( pDesc -> legacy . cmd . fEOP ) { if ( pThis -> fTidEnabled && pDesc -> legacy . cmd . fIDE ) { E1K_INC_ISTAT_CNT ( pThis -> uStatTxIDE ) ; e1kArmTimer ( pThis , pThis -> CTX_SUFF ( pTIDTimer ) , TIDV ) ; # ifndef E1K_NO_TAD E1kLog2 ( ( " \n " , pThis -> szPrf ) ) ; if ( TADV != 0 && ! TMTimerIsActive ( pThis -> CTX_SUFF ( pTADTimer ) ) ) e1kArmTimer ( pThis , pThis -> CTX_SUFF ( pTADTimer ) , TADV ) ; # endif } else { if ( pThis -> fTidEnabled ) { E1kLog2 ( ( " \n " , pThis -> szPrf ) ) ; # ifndef E1K_NO_TAD TMTimerStop ( pThis -> CTX_SUFF ( pTADTimer ) ) ; # endif TMTimerStop ( pThis -> CTX_SUFF ( pTIDTimer ) ) ; } E1K_INC_ISTAT_CNT ( pThis -> uStatIntTx ) ; e1kRaiseInterrupt ( pThis , VERR_SEM_BUSY , ICR_TXDW ) ; } } } else { E1K_INC_ISTAT_CNT ( pThis -> uStatTxNoRS ) ; } }
Write the descriptor back to guest memory and notify the guest.
Write the descriptor back to guest memory and notify the guest .
/*
     * We fake descriptor write-back bursting. Descriptors are written back as they are
     * processed.
     */ /* Let's pretend we process descriptors. Write back with DD set. */ /*
     * Prior to r71586 we tried to accomodate the case when write-back bursts
     * are enabled without actually implementing bursting by writing back all
     * descriptors, even the ones that do not have RS set. This caused kernel
     * panics with Linux SMP kernels, as the e1000 driver tried to free up skb
     * associated with written back descriptor if it happened to be a context
     * descriptor since context descriptors do not have skb associated to them.
     * Starting from r71586 we write back only the descriptors with RS set,
     * which is a little bit different from what the real hardware does in
     * case there is a chain of data descritors where some of them have RS set
     * and others do not. It is very uncommon scenario imho.
     * We need to check RPS as well since some legacy drivers use it instead of
     * RS even with newer cards.
     */ /* Descriptor Done */ //#ifdef E1K_USE_TX_TIMERS //if (pThis->fIntRaised) //{ //    /* Interrupt is already pending, no need for timers */ //    ICR |= ICR_TXDW; //} //else { /* Arm the timer to fire in TIVD usec (discard .024) */ /* If absolute timer delay is enabled and the timer is not running yet, arm it. */ /* E1K_NO_TAD */ /* Cancel both timers if armed and fire immediately. */ //#endif /* E1K_USE_TX_TIMERS */ //#ifdef E1K_USE_TX_TIMERS //#endif /* E1K_USE_TX_TIMERS */