VirtualBox

Changeset 40992 in vbox for trunk/src/VBox/Devices/Network


Ignore:
Timestamp:
Apr 19, 2012 1:55:42 PM (13 years ago)
Author:
vboxsync
Message:

E1000: Removed unused global mutex, documented the options.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Network/DevE1000.cpp

    r40985 r40992  
    3131#define E1kLogRel(a)
    3232
    33 /* Options */
     33/* Options *******************************************************************/
     34/*
     35 * E1K_INIT_RA0 forces E1000 to set the first entry in Receive Address filter
     36 * table to MAC address obtained from CFGM. Most guests read MAC address from
     37 * EEPROM and write it to RA[0] explicitly, but Mac OS X seems to depend on it
     38 * being already set (see #4657).
     39 */
    3440#define E1K_INIT_RA0
     41/*
     42 * E1K_LSC_ON_SLU causes E1000 to generate Link Status Change interrupt when
     43 * the guest driver brings up the link via STATUS.LU bit. Again the only guest
     44 * that requires it is Mac OS X (see #4657).
     45 */
    3546#define E1K_LSC_ON_SLU
     47/*
     48 * E1K_ITR_ENABLED reduces the number of interrupts generated by E1000 if a
     49 * guest driver requested it by writing non-zero value to the Interrupt
     50 * Throttling Register (see section 13.4.18 in "8254x Family of Gigabit
     51 * Ethernet Controllers Software Developer’s Manual").
     52 */
    3653#define E1K_ITR_ENABLED
    37 //#define E1K_GLOBAL_MUTEX
     54/*
     55 * E1K_USE_TX_TIMERS aims to reduce the number of generated TX interrupts if a
     56 * guest driver set the delays via the Transmit Interrupt Delay Value (TIDV)
     57 * register. Enabling it showed no positive effects on existing guests so it
     58 * stays disabled. See sections 3.2.7.1 and 3.4.3.1 in "8254x Family of Gigabit
     59 * Ethernet Controllers Software Developer’s Manual" for more detailed
     60 * explanation.
     61 */
    3862//#define E1K_USE_TX_TIMERS
     63/*
     64 * E1K_NO_TAD disables one of two timers enabled by E1K_USE_TX_TIMERS, the
     65 * Transmit Absolute Delay time. This timer sets the maximum time interval
     66 * during which TX interrupts can be postponed (delayed). It has no effect
     67 * if E1K_USE_TX_TIMERS is not defined.
     68 */
    3969//#define E1K_NO_TAD
     70/*
     71 * E1K_REL_DEBUG enables debug logging of l1, l2, l3 in release build.
     72 */
    4073//#define E1K_REL_DEBUG
     74/*
     75 * E1K_INT_STATS enables collection of internal statistics used for
     76 * debugging of delayed interrupts, etc.
     77 */
    4178//#define E1K_INT_STATS
    42 //#define E1K_REL_STATS
    43 //#define E1K_USE_SUPLIB_SEMEVENT
     79/*
     80 * E1K_WITH_MSI enables rudimentary MSI support. Not implemented.
     81 */
    4482//#define E1K_WITH_MSI
     83/*
     84 * E1K_WITH_TXD_CACHE causes E1000 to fetch multiple TX descriptors in a
     85 * single physical memory read (or two if it wraps around the end of TX
     86 * descriptor ring). It is required for proper functioning of bandwidth
     87 * resource control as it allows to compute exact sizes of packets prior
     88 * to allocating their buffers (see #5582).
     89 */
    4590#define E1K_WITH_TXD_CACHE 1
     91/* End of Options ************************************************************/
    4692
    4793#ifdef E1K_WITH_TXD_CACHE
     94/*
     95 * E1K_TXD_CACHE_SIZE specifies the maximum number of TX descriptors stored
     96 * in the state structure. It limits the amount of descriptors loaded in one
     97 * batch read. For example, Windows XP guest uses about 5 descriptors per
     98 * TSE packet.
     99 */
    48100#define E1K_TXD_CACHE_SIZE 16u
    49101#endif /* E1K_WITH_TXD_CACHE */
     
    75127
    76128#ifndef DEBUG
    77 # ifdef E1K_REL_STATS
    78 #  undef STAM_COUNTER_INC
    79 #  undef STAM_PROFILE_ADV_START
    80 #  undef STAM_PROFILE_ADV_STOP
    81 #  define STAM_COUNTER_INC       STAM_REL_COUNTER_INC
    82 #  define STAM_PROFILE_ADV_START STAM_REL_PROFILE_ADV_START
    83 #  define STAM_PROFILE_ADV_STOP  STAM_REL_PROFILE_ADV_STOP
    84 # endif
    85129# ifdef E1K_REL_DEBUG
    86130#  define DEBUG
     
    9621006#endif
    9631007    PDMCRITSECT cs;                  /**< Critical section - what is it protecting? */
    964 #ifndef E1K_GLOBAL_MUTEX
    9651008    PDMCRITSECT csRx;                                     /**< RX Critical section. */
    9661009//    PDMCRITSECT csTx;                                     /**< TX Critical section. */
    967 #endif
    9681010    /** Base address of memory-mapped registers. */
    9691011    RTGCPHYS    addrMMReg;
     
    10811123    STAMCOUNTER                         StatReceiveBytes;
    10821124    STAMCOUNTER                         StatTransmitBytes;
    1083 #if defined(VBOX_WITH_STATISTICS) || defined(E1K_REL_STATS)
     1125#if defined(VBOX_WITH_STATISTICS)
    10841126    STAMPROFILEADV                      StatMMIOReadRZ;
    10851127    STAMPROFILEADV                      StatMMIOReadR3;
     
    11161158    STAMCOUNTER                         StatPHYAccesses;
    11171159
    1118 #endif /* VBOX_WITH_STATISTICS || E1K_REL_STATS */
     1160#endif /* VBOX_WITH_STATISTICS */
    11191161
    11201162#ifdef E1K_INT_STATS
     
    14371479}
    14381480
    1439 #ifdef E1K_GLOBAL_MUTEX
    1440 
    1441 DECLINLINE(int) e1kCsEnter(E1KSTATE *pState, int iBusyRc)
    1442 {
    1443     return VINF_SUCCESS;
    1444 }
    1445 
    1446 DECLINLINE(void) e1kCsLeave(E1KSTATE *pState)
    1447 {
    1448 }
    1449 
    1450 # define e1kCsRxEnter(ps, rc) VINF_SUCCESS
    1451 # define e1kCsRxLeave(ps) do { } while (0)
    1452 
    1453 # define e1kCsTxEnter(ps, rc) VINF_SUCCESS
    1454 # define e1kCsTxLeave(ps) do { } while (0)
    1455 
    1456 
    1457 DECLINLINE(int) e1kMutexAcquire(E1KSTATE *pState, int iBusyRc, RT_SRC_POS_DECL)
    1458 {
    1459     int rc = PDMCritSectEnter(&pState->cs, iBusyRc);
    1460     if (RT_UNLIKELY(rc != VINF_SUCCESS))
    1461     {
    1462         E1kLog2(("%s ==> FAILED to enter critical section at %s:%d:%s with rc=\n",
    1463                 INSTANCE(pState), RT_SRC_POS_ARGS, rc));
    1464         PDMDevHlpDBGFStop(pState->CTX_SUFF(pDevIns), RT_SRC_POS_ARGS,
    1465                           "%s Failed to enter critical section, rc=%Rrc\n",
    1466                           INSTANCE(pState), rc);
    1467     }
    1468     else
    1469     {
    1470         //E1kLog2(("%s ==> Mutex acquired at %s:%d:%s\n", INSTANCE(pState), RT_SRC_POS_ARGS));
    1471     }
    1472     return rc;
    1473 }
    1474 
    1475 DECLINLINE(void) e1kMutexRelease(E1KSTATE *pState)
    1476 {
    1477     //E1kLog2(("%s <== Releasing mutex...\n", INSTANCE(pState)));
    1478     PDMCritSectLeave(&pState->cs);
    1479 }
    1480 
    1481 #else /* !E1K_GLOBAL_MUTEX */
    1482 # define e1kCsEnter(ps, rc) PDMCritSectEnter(&ps->cs, rc)
    1483 # define e1kCsLeave(ps) PDMCritSectLeave(&ps->cs)
    1484 
    1485 # define e1kCsRxEnter(ps, rc) PDMCritSectEnter(&ps->csRx, rc)
    1486 # define e1kCsRxLeave(ps) PDMCritSectLeave(&ps->csRx)
    1487 
    1488 # define e1kCsTxEnter(ps, rc) VINF_SUCCESS
    1489 # define e1kCsTxLeave(ps) do { } while (0)
     1481#define e1kCsEnter(ps, rc) PDMCritSectEnter(&ps->cs, rc)
     1482#define e1kCsLeave(ps) PDMCritSectLeave(&ps->cs)
     1483
     1484#define e1kCsRxEnter(ps, rc) PDMCritSectEnter(&ps->csRx, rc)
     1485#define e1kCsRxLeave(ps) PDMCritSectLeave(&ps->csRx)
     1486
     1487#define e1kCsTxEnter(ps, rc) VINF_SUCCESS
     1488#define e1kCsTxLeave(ps) do { } while (0)
    14901489//# define e1kCsTxEnter(ps, rc) PDMCritSectEnter(&ps->csTx, rc)
    14911490//# define e1kCsTxLeave(ps) PDMCritSectLeave(&ps->csTx)
    14921491
    1493 # if 0
    1494 DECLINLINE(int) e1kCsEnter(E1KSTATE *pState, PPDMCRITSECT pCs, int iBusyRc, RT_SRC_POS_DECL)
    1495 {
    1496     int rc = PDMCritSectEnter(pCs, iBusyRc);
    1497     if (RT_FAILURE(rc))
    1498     {
    1499         E1kLog2(("%s ==> FAILED to enter critical section at %s:%d:%s with rc=%Rrc\n",
    1500                 INSTANCE(pState), RT_SRC_POS_ARGS, rc));
    1501         PDMDeviceDBGFStop(pState->CTX_SUFF(pDevIns), RT_SRC_POS_ARGS,
    1502                           "%s Failed to enter critical section, rc=%Rrc\n",
    1503                           INSTANCE(pState), rc);
    1504     }
    1505     else
    1506     {
    1507         //E1kLog2(("%s ==> Entered critical section at %s:%d:%s\n", INSTANCE(pState), RT_SRC_POS_ARGS));
    1508     }
    1509     return RT_SUCCESS(rc);
    1510 }
    1511 
    1512 DECLINLINE(void) e1kCsLeave(E1KSTATE *pState, PPDMCRITSECT pCs)
    1513 {
    1514     //E1kLog2(("%s <== Leaving critical section\n", INSTANCE(pState)));
    1515     PDMCritSectLeave(&pState->cs);
    1516 }
    1517 # endif
    1518 DECLINLINE(int) e1kMutexAcquire(E1KSTATE *pState, int iBusyRc, RT_SRC_POS_DECL)
    1519 {
    1520     return VINF_SUCCESS;
    1521 }
    1522 
    1523 DECLINLINE(void) e1kMutexRelease(E1KSTATE *pState)
    1524 {
    1525 }
    1526 
    1527 #endif /* !E1K_GLOBAL_MUTEX */
    15281492#ifdef IN_RING3
    15291493
     
    18211785                pState->fIntRaised = true;
    18221786                /* Raise(1) INTA(0) */
    1823                 //e1kMutexRelease(pState);
    18241787                E1kLogRel(("E1000: irq RAISED icr&mask=0x%x, icr=0x%x\n", ICR & IMS, ICR));
    18251788                PDMDevHlpPCISetIrq(pState->CTX_SUFF(pDevIns), 0, 1);
    1826                 //e1kMutexAcquire(pState, RT_SRC_POS);
    18271789                E1kLog(("%s e1kRaiseInterrupt: Raised. ICR&IMS=%08x\n",
    18281790                        INSTANCE(pState), ICR & IMS));
     
    20341996    uint8_t  *ptr = rxPacket;
    20351997
    2036 #ifndef E1K_GLOBAL_MUTEX
    20371998    int rc = e1kCsRxEnter(pState, VERR_SEM_BUSY);
    20381999    if (RT_UNLIKELY(rc != VINF_SUCCESS))
    20392000        return rc;
    2040 #endif
    20412001
    20422002    if (cb > 70) /* unqualified guess */
     
    25072467                pState->fIntRaised = false;
    25082468                /* Lower(0) INTA(0) */
    2509                 //e1kMutexRelease(pState);
    25102469                PDMDevHlpPCISetIrq(pState->CTX_SUFF(pDevIns), 0, 0);
    2511                 //e1kMutexAcquire(pState, RT_SRC_POS);
    25122470
    25132471                pState->u64AckedAt = TMTimerGet(pState->CTX_SUFF(pIntTimer));
     
    27792737    E1KSTATE *pState = (E1KSTATE *)pvUser;
    27802738
    2781     if (RT_LIKELY(e1kMutexAcquire(pState, VERR_SEM_BUSY, RT_SRC_POS) == VINF_SUCCESS))
    2782     {
    2783         E1K_INC_ISTAT_CNT(pState->uStatTID);
    2784         /* Cancel absolute delay timer as we have already got attention */
     2739    E1K_INC_ISTAT_CNT(pState->uStatTID);
     2740    /* Cancel absolute delay timer as we have already got attention */
    27852741#ifndef E1K_NO_TAD
    2786         e1kCancelTimer(pState, pState->CTX_SUFF(pTADTimer));
     2742    e1kCancelTimer(pState, pState->CTX_SUFF(pTADTimer));
    27872743#endif /* E1K_NO_TAD */
    2788         e1kRaiseInterrupt(pState, ICR_TXDW);
    2789         e1kMutexRelease(pState);
    2790     }
     2744    e1kRaiseInterrupt(pState, ICR_TXDW);
    27912745}
    27922746
     
    28052759    E1KSTATE *pState = (E1KSTATE *)pvUser;
    28062760
    2807     if (RT_LIKELY(e1kMutexAcquire(pState, VERR_SEM_BUSY, RT_SRC_POS) == VINF_SUCCESS))
    2808     {
    2809         E1K_INC_ISTAT_CNT(pState->uStatTAD);
    2810         /* Cancel interrupt delay timer as we have already got attention */
    2811         e1kCancelTimer(pState, pState->CTX_SUFF(pTIDTimer));
    2812         e1kRaiseInterrupt(pState, ICR_TXDW);
    2813         e1kMutexRelease(pState);
    2814     }
     2761    E1K_INC_ISTAT_CNT(pState->uStatTAD);
     2762    /* Cancel interrupt delay timer as we have already got attention */
     2763    e1kCancelTimer(pState, pState->CTX_SUFF(pTIDTimer));
     2764    e1kRaiseInterrupt(pState, ICR_TXDW);
    28152765}
    28162766
     
    28322782    E1KSTATE *pState = (E1KSTATE *)pvUser;
    28332783
    2834     if (RT_LIKELY(e1kMutexAcquire(pState, VERR_SEM_BUSY, RT_SRC_POS) == VINF_SUCCESS))
    2835     {
    2836         E1K_INC_ISTAT_CNT(pState->uStatRID);
    2837         /* Cancel absolute delay timer as we have already got attention */
    2838         e1kCancelTimer(pState, pState->CTX_SUFF(pRADTimer));
    2839         e1kRaiseInterrupt(pState, ICR_RXT0);
    2840         e1kMutexRelease(pState);
    2841     }
     2784    E1K_INC_ISTAT_CNT(pState->uStatRID);
     2785    /* Cancel absolute delay timer as we have already got attention */
     2786    e1kCancelTimer(pState, pState->CTX_SUFF(pRADTimer));
     2787    e1kRaiseInterrupt(pState, ICR_RXT0);
    28422788}
    28432789
     
    28562802    E1KSTATE *pState = (E1KSTATE *)pvUser;
    28572803
    2858     if (RT_LIKELY(e1kMutexAcquire(pState, VERR_SEM_BUSY, RT_SRC_POS) == VINF_SUCCESS))
    2859     {
    2860         E1K_INC_ISTAT_CNT(pState->uStatRAD);
    2861         /* Cancel interrupt delay timer as we have already got attention */
    2862         e1kCancelTimer(pState, pState->CTX_SUFF(pRIDTimer));
    2863         e1kRaiseInterrupt(pState, ICR_RXT0);
    2864         e1kMutexRelease(pState);
    2865     }
     2804    E1K_INC_ISTAT_CNT(pState->uStatRAD);
     2805    /* Cancel interrupt delay timer as we have already got attention */
     2806    e1kCancelTimer(pState, pState->CTX_SUFF(pRIDTimer));
     2807    e1kRaiseInterrupt(pState, ICR_RXT0);
    28662808}
    28672809
     
    28812823
    28822824    STAM_PROFILE_ADV_START(&pState->StatLateIntTimer, a);
    2883     if (RT_LIKELY(e1kMutexAcquire(pState, VERR_SEM_BUSY, RT_SRC_POS) == VINF_SUCCESS))
    2884     {
    2885         STAM_COUNTER_INC(&pState->StatLateInts);
    2886         E1K_INC_ISTAT_CNT(pState->uStatIntLate);
     2825    STAM_COUNTER_INC(&pState->StatLateInts);
     2826    E1K_INC_ISTAT_CNT(pState->uStatIntLate);
    28872827#if 0
    2888         if (pState->iStatIntLost > -100)
    2889             pState->iStatIntLost--;
     2828    if (pState->iStatIntLost > -100)
     2829        pState->iStatIntLost--;
    28902830#endif
    2891         e1kRaiseInterrupt(pState, VERR_SEM_BUSY, 0);
    2892         e1kMutexRelease(pState);
    2893     }
     2831    e1kRaiseInterrupt(pState, VERR_SEM_BUSY, 0);
    28942832    STAM_PROFILE_ADV_STOP(&pState->StatLateIntTimer, a);
    28952833}
     
    29152853        return;
    29162854
    2917     if (RT_LIKELY(e1kMutexAcquire(pState, VERR_SEM_BUSY, RT_SRC_POS) == VINF_SUCCESS))
    2918     {
    2919         STATUS |= STATUS_LU;
    2920         Phy::setLinkStatus(&pState->phy, true);
    2921         e1kRaiseInterrupt(pState, VERR_SEM_BUSY, ICR_LSC);
    2922         e1kMutexRelease(pState);
    2923     }
     2855    STATUS |= STATUS_LU;
     2856    Phy::setLinkStatus(&pState->phy, true);
     2857    e1kRaiseInterrupt(pState, VERR_SEM_BUSY, ICR_LSC);
    29242858}
    29252859
     
    34203354            /* Release critical section to avoid deadlock in CanReceive */
    34213355            //e1kCsLeave(pState);
    3422             e1kMutexRelease(pState);
    34233356            STAM_PROFILE_START(&pState->CTX_SUFF_Z(StatTransmitSend), a);
    34243357            rc = pDrv->pfnSendBuf(pDrv, pSg, fOnWorkerThread);
    34253358            STAM_PROFILE_STOP(&pState->CTX_SUFF_Z(StatTransmitSend), a);
    3426             e1kMutexAcquire(pState, VERR_SEM_BUSY, RT_SRC_POS);
    34273359            //e1kCsEnter(pState, RT_SRC_POS);
    34283360        }
     
    45814513            return rc;
    45824514    }
    4583     rc = e1kMutexAcquire(pState, VERR_TRY_AGAIN, RT_SRC_POS);
    4584     if (RT_SUCCESS(rc))
    4585     {
    4586         /*
    4587          * Process all pending descriptors.
    4588          * Note! Do not process descriptors in locked state
    4589          */
    4590         while (TDH != TDT && !pState->fLocked)
    4591         {
    4592             E1KTXDESC desc;
    4593             E1kLog3(("%s About to process new TX descriptor at %08x%08x, TDLEN=%08x, TDH=%08x, TDT=%08x\n",
    4594                      INSTANCE(pState), TDBAH, TDBAL + TDH * sizeof(desc), TDLEN, TDH, TDT));
    4595 
    4596             e1kLoadDesc(pState, &desc, ((uint64_t)TDBAH << 32) + TDBAL + TDH * sizeof(desc));
    4597             rc = e1kXmitDesc(pState, &desc, ((uint64_t)TDBAH << 32) + TDBAL + TDH * sizeof(desc), fOnWorkerThread);
    4598             /* If we failed to transmit descriptor we will try it again later */
    4599             if (RT_FAILURE(rc))
    4600                 break;
    4601             if (++TDH * sizeof(desc) >= TDLEN)
    4602                 TDH = 0;
    4603 
    4604             if (e1kGetTxLen(pState) <= GET_BITS(TXDCTL, LWTHRESH)*8)
    4605             {
    4606                 E1kLog2(("%s Low on transmit descriptors, raise ICR.TXD_LOW, len=%x thresh=%x\n",
    4607                          INSTANCE(pState), e1kGetTxLen(pState), GET_BITS(TXDCTL, LWTHRESH)*8));
    4608                 e1kRaiseInterrupt(pState, VERR_SEM_BUSY, ICR_TXD_LOW);
    4609             }
    4610 
    4611             STAM_PROFILE_ADV_STOP(&pState->CTX_SUFF_Z(StatTransmit), a);
    4612         }
    4613 
    4614         /// @todo: uncomment: pState->uStatIntTXQE++;
    4615         /// @todo: uncomment: e1kRaiseInterrupt(pState, ICR_TXQE);
    4616 
    4617         /*
    4618          * Release the locks.
    4619          */
    4620         e1kMutexRelease(pState);
    4621     }
     4515    /*
     4516     * Process all pending descriptors.
     4517     * Note! Do not process descriptors in locked state
     4518     */
     4519    while (TDH != TDT && !pState->fLocked)
     4520    {
     4521        E1KTXDESC desc;
     4522        E1kLog3(("%s About to process new TX descriptor at %08x%08x, TDLEN=%08x, TDH=%08x, TDT=%08x\n",
     4523                 INSTANCE(pState), TDBAH, TDBAL + TDH * sizeof(desc), TDLEN, TDH, TDT));
     4524
     4525        e1kLoadDesc(pState, &desc, ((uint64_t)TDBAH << 32) + TDBAL + TDH * sizeof(desc));
     4526        rc = e1kXmitDesc(pState, &desc, ((uint64_t)TDBAH << 32) + TDBAL + TDH * sizeof(desc), fOnWorkerThread);
     4527        /* If we failed to transmit descriptor we will try it again later */
     4528        if (RT_FAILURE(rc))
     4529            break;
     4530        if (++TDH * sizeof(desc) >= TDLEN)
     4531            TDH = 0;
     4532
     4533        if (e1kGetTxLen(pState) <= GET_BITS(TXDCTL, LWTHRESH)*8)
     4534        {
     4535            E1kLog2(("%s Low on transmit descriptors, raise ICR.TXD_LOW, len=%x thresh=%x\n",
     4536                     INSTANCE(pState), e1kGetTxLen(pState), GET_BITS(TXDCTL, LWTHRESH)*8));
     4537            e1kRaiseInterrupt(pState, VERR_SEM_BUSY, ICR_TXD_LOW);
     4538        }
     4539
     4540        STAM_PROFILE_ADV_STOP(&pState->CTX_SUFF_Z(StatTransmit), a);
     4541    }
     4542
     4543    /// @todo: uncomment: pState->uStatIntTXQE++;
     4544    /// @todo: uncomment: e1kRaiseInterrupt(pState, ICR_TXQE);
     4545
     4546    /*
     4547     * Release the lock.
     4548     */
    46224549    if (pDrv)
    46234550        pDrv->pfnEndXmit(pDrv);
     
    46474574            return rc;
    46484575    }
    4649     rc = e1kMutexAcquire(pState, VERR_TRY_AGAIN, RT_SRC_POS);
    4650     if (RT_SUCCESS(rc))
    4651     {
    4652         /*size_t cbPacket = 0;
    4653         int nDescInPacket = 0;
    4654         E1KTXDESC *pFirstDesc = pState->aTxDescriptors;*/
    4655         /*
    4656          * Process all pending descriptors.
    4657          * Note! Do not process descriptors in locked state
    4658          */
    4659         STAM_PROFILE_ADV_START(&pState->CTX_SUFF_Z(StatTransmit), a);
    4660         while (!pState->fLocked && e1kTxDLazyLoad(pState))
    4661         {
    4662             while (e1kLocateTxPacket(pState))
    4663             {
    4664                 // 1) packet located -- allocate it!
    4665                 rc = e1kXmitAllocBuf(pState, pState->fGSO);
    4666                 /* If we're out of bandwidth we'll come back later. */
    4667                 if (RT_FAILURE(rc))
    4668                     goto out;
    4669                 /* Copy the packet to allocated buffer and send it. */
    4670                 rc = e1kXmitPacket(pState, fOnWorkerThread);
    4671                 /* If we're out of bandwidth we'll come back later. */
    4672                 if (RT_FAILURE(rc))
    4673                     goto out;
    4674             }
    4675             uint8_t u8Remain = pState->nTxDFetched - pState->iTxDCurrent;
    4676             if (u8Remain > 0)
    4677             {
    4678                 /*
    4679                  * A packet was partially fetched. Move incomplete packet to
    4680                  * the beginning of cache buffer, then load more descriptors.
    4681                  */
    4682                 memmove(pState->aTxDescriptors,
    4683                         &pState->aTxDescriptors[pState->iTxDCurrent],
    4684                         u8Remain * sizeof(E1KTXDESC));
    4685                 pState->nTxDFetched = u8Remain;
    4686                 e1kTxDLoadMore(pState);
    4687             }
    4688             else
    4689                 pState->nTxDFetched = 0;
    4690             pState->iTxDCurrent = 0;
    4691         }
    4692         if (!pState->fLocked && GET_BITS(TXDCTL, LWTHRESH) == 0)
    4693         {
    4694             E1kLog2(("%s Out of transmit descriptors, raise ICR.TXD_LOW\n",
    4695                      INSTANCE(pState)));
    4696             e1kRaiseInterrupt(pState, VERR_SEM_BUSY, ICR_TXD_LOW);
    4697         }
     4576
     4577    /*
     4578     * Process all pending descriptors.
     4579     * Note! Do not process descriptors in locked state
     4580     */
     4581    STAM_PROFILE_ADV_START(&pState->CTX_SUFF_Z(StatTransmit), a);
     4582    while (!pState->fLocked && e1kTxDLazyLoad(pState))
     4583    {
     4584        while (e1kLocateTxPacket(pState))
     4585        {
     4586            /* Found a complete packet, allocate it. */
     4587            rc = e1kXmitAllocBuf(pState, pState->fGSO);
     4588            /* If we're out of bandwidth we'll come back later. */
     4589            if (RT_FAILURE(rc))
     4590                goto out;
     4591            /* Copy the packet to allocated buffer and send it. */
     4592            rc = e1kXmitPacket(pState, fOnWorkerThread);
     4593            /* If we're out of bandwidth we'll come back later. */
     4594            if (RT_FAILURE(rc))
     4595                goto out;
     4596        }
     4597        uint8_t u8Remain = pState->nTxDFetched - pState->iTxDCurrent;
     4598        if (u8Remain > 0)
     4599        {
     4600            /*
     4601             * A packet was partially fetched. Move incomplete packet to
     4602             * the beginning of cache buffer, then load more descriptors.
     4603             */
     4604            memmove(pState->aTxDescriptors,
     4605                    &pState->aTxDescriptors[pState->iTxDCurrent],
     4606                    u8Remain * sizeof(E1KTXDESC));
     4607            pState->nTxDFetched = u8Remain;
     4608            e1kTxDLoadMore(pState);
     4609        }
     4610        else
     4611            pState->nTxDFetched = 0;
     4612        pState->iTxDCurrent = 0;
     4613    }
     4614    if (!pState->fLocked && GET_BITS(TXDCTL, LWTHRESH) == 0)
     4615    {
     4616        E1kLog2(("%s Out of transmit descriptors, raise ICR.TXD_LOW\n",
     4617                 INSTANCE(pState)));
     4618        e1kRaiseInterrupt(pState, VERR_SEM_BUSY, ICR_TXD_LOW);
     4619    }
    46984620
    46994621out:
    4700         STAM_PROFILE_ADV_STOP(&pState->CTX_SUFF_Z(StatTransmit), a);
    4701 
    4702         /// @todo: uncomment: pState->uStatIntTXQE++;
    4703         /// @todo: uncomment: e1kRaiseInterrupt(pState, ICR_TXQE);
    4704 
    4705         /*
    4706          * Release the locks.
    4707          */
    4708         e1kMutexRelease(pState);
    4709     }
     4622    STAM_PROFILE_ADV_STOP(&pState->CTX_SUFF_Z(StatTransmit), a);
     4623
     4624    /// @todo: uncomment: pState->uStatIntTXQE++;
     4625    /// @todo: uncomment: e1kRaiseInterrupt(pState, ICR_TXQE);
     4626
     4627    /*
     4628     * Release the lock.
     4629     */
    47104630    if (pDrv)
    47114631        pDrv->pfnEndXmit(pDrv);
     
    51225042             * Mask out irrelevant bits.
    51235043             */
    5124 #ifdef E1K_GLOBAL_MUTEX
    5125             rc = e1kMutexAcquire(pState, VINF_IOM_R3_MMIO_READ, RT_SRC_POS);
    5126 #else
    51275044            //rc = e1kCsEnter(pState, VERR_SEM_BUSY, RT_SRC_POS);
    5128 #endif
    51295045            if (RT_UNLIKELY(rc != VINF_SUCCESS))
    51305046                return rc;
     
    51355051            u32 &= mask;
    51365052            //e1kCsLeave(pState);
    5137             e1kMutexRelease(pState);
    51385053            E1kLog2(("%s At %08X read  %s          from %s (%s)\n",
    51395054                    szInst, uOffset, e1kU32toHex(u32, mask, buf), s_e1kRegMap[index].abbrev, s_e1kRegMap[index].name));
     
    52055120            E1kLog2(("%s At %08X write          %08X  to  %s (%s)\n",
    52065121                     INSTANCE(pState), uOffset, u32, s_e1kRegMap[index].abbrev, s_e1kRegMap[index].name));
    5207 #ifdef E1K_GLOBAL_MUTEX
    5208             rc = e1kMutexAcquire(pState, VINF_IOM_R3_MMIO_WRITE, RT_SRC_POS);
    5209 #else
    52105122            //rc = e1kCsEnter(pState, VERR_SEM_BUSY, RT_SRC_POS);
    5211 #endif
    52125123            if (RT_UNLIKELY(rc != VINF_SUCCESS))
    52135124                return rc;
     
    52175128            rc = s_e1kRegMap[index].pfnWrite(pState, uOffset, index, u32);
    52185129            //e1kCsLeave(pState);
    5219             e1kMutexRelease(pState);
    52205130        }
    52215131        else
     
    55235433    size_t cb;
    55245434
    5525     if (RT_UNLIKELY(e1kMutexAcquire(pState, VERR_SEM_BUSY, RT_SRC_POS) != VINF_SUCCESS))
    5526         return VERR_NET_NO_BUFFER_SPACE;
    55275435    if (RT_UNLIKELY(e1kCsRxEnter(pState, VERR_SEM_BUSY) != VINF_SUCCESS))
    55285436        return VERR_NET_NO_BUFFER_SPACE;
     
    55515459
    55525460    e1kCsRxLeave(pState);
    5553     e1kMutexRelease(pState);
    55545461    return cb > 0 ? VINF_SUCCESS : VERR_NET_NO_BUFFER_SPACE;
    55555462}
     
    58015708
    58025709    STAM_PROFILE_ADV_START(&pState->StatReceive, a);
    5803     rc = e1kMutexAcquire(pState, VERR_SEM_BUSY, RT_SRC_POS);
    5804     if (RT_LIKELY(rc == VINF_SUCCESS))
    5805     {
    5806         //if (!e1kCsEnter(pState, RT_SRC_POS))
    5807         //    return VERR_PERMISSION_DENIED;
    5808 
    5809         e1kPacketDump(pState, (const uint8_t*)pvBuf, cb, "<-- Incoming");
    5810 
    5811         /* Update stats */
    5812         if (RT_LIKELY(e1kCsEnter(pState, VERR_SEM_BUSY) == VINF_SUCCESS))
    5813         {
    5814             E1K_INC_CNT32(TPR);
    5815             E1K_ADD_CNT64(TORL, TORH, cb < 64? 64 : cb);
    5816             e1kCsLeave(pState);
    5817         }
    5818         STAM_PROFILE_ADV_START(&pState->StatReceiveFilter, a);
    5819         E1KRXDST status;
    5820         RT_ZERO(status);
    5821         bool fPassed = e1kAddressFilter(pState, pvBuf, cb, &status);
    5822         STAM_PROFILE_ADV_STOP(&pState->StatReceiveFilter, a);
    5823         if (fPassed)
    5824         {
    5825             rc = e1kHandleRxPacket(pState, pvBuf, cb, status);
    5826         }
    5827         //e1kCsLeave(pState);
    5828         e1kMutexRelease(pState);
    5829     }
     5710
     5711    //if (!e1kCsEnter(pState, RT_SRC_POS))
     5712    //    return VERR_PERMISSION_DENIED;
     5713
     5714    e1kPacketDump(pState, (const uint8_t*)pvBuf, cb, "<-- Incoming");
     5715
     5716    /* Update stats */
     5717    if (RT_LIKELY(e1kCsEnter(pState, VERR_SEM_BUSY) == VINF_SUCCESS))
     5718    {
     5719        E1K_INC_CNT32(TPR);
     5720        E1K_ADD_CNT64(TORL, TORH, cb < 64? 64 : cb);
     5721        e1kCsLeave(pState);
     5722    }
     5723    STAM_PROFILE_ADV_START(&pState->StatReceiveFilter, a);
     5724    E1KRXDST status;
     5725    RT_ZERO(status);
     5726    bool fPassed = e1kAddressFilter(pState, pvBuf, cb, &status);
     5727    STAM_PROFILE_ADV_STOP(&pState->StatReceiveFilter, a);
     5728    if (fPassed)
     5729    {
     5730        rc = e1kHandleRxPacket(pState, pvBuf, cb, status);
     5731    }
     5732    //e1kCsLeave(pState);
    58305733    STAM_PROFILE_ADV_STOP(&pState->StatReceive, a);
    58315734
     
    59885891    return VINF_SUCCESS;
    59895892#if 0
    5990     int rc = e1kMutexAcquire(pState, VERR_SEM_BUSY, RT_SRC_POS);
    5991     if (RT_UNLIKELY(rc != VINF_SUCCESS))
    5992         return rc;
    59935893    /* 1) Prevent all threads from modifying the state and memory */
    59945894    //pState->fLocked = true;
     
    60075907    /* 3) Did I forget anything? */
    60085908    E1kLog(("%s Locked\n", INSTANCE(pState)));
    6009     e1kMutexRelease(pState);
    60105909    return VINF_SUCCESS;
    60115910#endif
     
    60705969    E1KSTATE* pState = PDMINS_2_DATA(pDevIns, E1KSTATE*);
    60715970
    6072     int rc = e1kMutexAcquire(pState, VERR_SEM_BUSY, RT_SRC_POS);
    6073     if (RT_UNLIKELY(rc != VINF_SUCCESS))
    6074         return rc;
    60755971    /* If VM is being powered off unlocking will result in assertions in PGM */
    60765972    if (PDMDevHlpGetVM(pDevIns)->enmVMState == VMSTATE_RUNNING)
     
    60795975        E1kLog(("%s VM is not running -- remain locked\n", INSTANCE(pState)));
    60805976    E1kLog(("%s Unlocked\n", INSTANCE(pState)));
    6081     e1kMutexRelease(pState);
    60825977    return VINF_SUCCESS;
    60835978}
     
    62066101    E1KSTATE* pState = PDMINS_2_DATA(pDevIns, E1KSTATE*);
    62076102
    6208     int rc = e1kMutexAcquire(pState, VERR_SEM_BUSY, RT_SRC_POS);
    6209     if (RT_UNLIKELY(rc != VINF_SUCCESS))
    6210         return rc;
    6211 
    62126103    /* Update promiscuous mode */
    62136104    if (pState->pDrvR3)
     
    62306121        e1kArmTimer(pState, pState->pLUTimerR3, 5000000);
    62316122    }
    6232     e1kMutexRelease(pState);
    62336123    return VINF_SUCCESS;
    62346124}
     
    64496339            pState->hEventMoreRxDescAvail = NIL_RTSEMEVENT;
    64506340        }
    6451 #ifndef E1K_GLOBAL_MUTEX
    64526341        PDMR3CritSectDelete(&pState->csRx);
    64536342        //PDMR3CritSectDelete(&pState->csTx);
    6454 #endif
    64556343        PDMR3CritSectDelete(&pState->cs);
    64566344    }
     
    67946682    if (RT_FAILURE(rc))
    67956683        return rc;
    6796 #ifndef E1K_GLOBAL_MUTEX
    67976684    rc = PDMDevHlpCritSectInit(pDevIns, &pState->csRx, RT_SRC_POS, "%sRX", pState->szInstance);
    67986685    if (RT_FAILURE(rc))
    67996686        return rc;
    6800 #endif
    68016687
    68026688    /* Set PCI config registers */
     
    68096695#ifdef E1K_WITH_MSI
    68106696    PDMMSIREG aMsiReg;
    6811     aMsiReg.cVectors = 1;
    6812     aMsiReg.iCapOffset = 0x80;
    6813     aMsiReg.iNextOffset = 0x0;
    6814     aMsiReg.iMsiFlags = 0;
     6697    aMsiReg.cMsiVectors = 1;
     6698    aMsiReg.iMsiCapOffset = 0x80;
     6699    aMsiReg.iMsiNextOffset = 0x0;
     6700    aMsiReg.fMsi64bit = false;
    68156701    rc = PDMDevHlpPCIRegisterMsi(pDevIns, &aMsiReg);
    68166702    AssertRC(rc);
     
    69496835    e1kHardReset(pState);
    69506836
    6951 #if defined(VBOX_WITH_STATISTICS) || defined(E1K_REL_STATS)
     6837#if defined(VBOX_WITH_STATISTICS)
    69526838    PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatMMIOReadRZ,         STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling MMIO reads in RZ",         "/Devices/E1k%d/MMIO/ReadRZ", iInstance);
    69536839    PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatMMIOReadR3,         STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling MMIO reads in R3",         "/Devices/E1k%d/MMIO/ReadR3", iInstance);
     
    69706856    PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatRxOverflow,         STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_OCCURENCE, "Profiling RX overflows",        "/Devices/E1k%d/RxOverflow", iInstance);
    69716857    PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatRxOverflowWakeup,   STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,     "Nr of RX overflow wakeups",          "/Devices/E1k%d/RxOverflowWakeup", iInstance);
    6972 #endif /* VBOX_WITH_STATISTICS || E1K_REL_STATS */
     6858#endif /* VBOX_WITH_STATISTICS */
    69736859    PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatReceiveBytes,       STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_BYTES,          "Amount of data received",            "/Devices/E1k%d/ReceiveBytes", iInstance);
    6974 #if defined(VBOX_WITH_STATISTICS) || defined(E1K_REL_STATS)
     6860#if defined(VBOX_WITH_STATISTICS)
    69756861    PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatTransmitRZ,         STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling transmits in RZ",          "/Devices/E1k%d/Transmit/TotalRZ", iInstance);
    69766862    PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatTransmitR3,         STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling transmits in R3",          "/Devices/E1k%d/Transmit/TotalR3", iInstance);
    6977 #endif /* VBOX_WITH_STATISTICS || E1K_REL_STATS */
     6863#endif /* VBOX_WITH_STATISTICS */
    69786864    PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatTransmitBytes,      STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_BYTES,          "Amount of data transmitted",         "/Devices/E1k%d/TransmitBytes", iInstance);
    6979 #if defined(VBOX_WITH_STATISTICS) || defined(E1K_REL_STATS)
     6865#if defined(VBOX_WITH_STATISTICS)
    69806866    PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatTransmitSendRZ,     STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling send transmit in RZ",      "/Devices/E1k%d/Transmit/SendRZ", iInstance);
    69816867    PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatTransmitSendR3,     STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling send transmit in R3",      "/Devices/E1k%d/Transmit/SendR3", iInstance);
     
    69906876    PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatTxPathRegular,      STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,     "Regular descriptor path",            "/Devices/E1k%d/TxPath/Normal", iInstance);
    69916877    PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatPHYAccesses,        STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,     "Number of PHY accesses",             "/Devices/E1k%d/PHYAccesses", iInstance);
    6992 #endif /* VBOX_WITH_STATISTICS || E1K_REL_STATS */
     6878#endif /* VBOX_WITH_STATISTICS */
    69936879
    69946880    return VINF_SUCCESS;
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette