VirtualBox

Changeset 27974 in vbox for trunk/src


Ignore:
Timestamp:
Apr 4, 2010 12:34:24 AM (15 years ago)
Author:
vboxsync
Message:

DevE1000: adding docs and some notes while reading specs.

File:
1 edited

Legend:

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

    r27298 r27974  
    3131 */
    3232
    33 
     33#define VBOX_WITH_TX_THREAD_IN_NET_DEVICES 1 //debug, bird, remove
    3434#define LOG_GROUP LOG_GROUP_DEV_E1000
    3535
     
    166166/*****************************************************************************/
    167167
     168/** Gets the specfieid bits from the register. */
    168169#define GET_BITS(reg, bits) ((reg & reg##_##bits##_MASK) >> reg##_##bits##_SHIFT)
    169170#define GET_BITS_V(val, reg, bits) ((val & reg##_##bits##_MASK) >> reg##_##bits##_SHIFT)
     
    216217#define RCTL_RDMTS_MASK  0x00000300
    217218#define RCTL_RDMTS_SHIFT 8
    218 #define RCTL_LBM_TCVR    3
     219#define RCTL_LBM_TCVR    3              /**< PHY or external SerDes loopback. */
    219220#define RCTL_MO_MASK     0x00003000
    220221#define RCTL_MO_SHIFT    12
     
    606607};
    607608
     609
    608610struct E1kRxDStatus
    609611{
    610     /* Descriptor Status field */
    611     unsigned fDD     : 1;
    612     unsigned fEOP    : 1;
    613     unsigned fIXSM   : 1;
    614     unsigned fVP     : 1;
     612    /** @name Descriptor Status field (3.2.3.1)
     613     * @{ */
     614    unsigned fDD     : 1;                             /**< Descriptor Done. */
     615    unsigned fEOP    : 1;                               /**< End of packet. */
     616    unsigned fIXSM   : 1;                  /**< Ignore checksum indication. */
     617    unsigned fVP     : 1;                           /**< VLAN, matches VET. */
    615618    unsigned         : 1;
    616     unsigned fTCPCS  : 1;
    617     unsigned fIPCS   : 1;
    618     unsigned fPIF    : 1;
    619     /* Descriptor Errors field */
    620     unsigned fCE     : 1;
    621     unsigned         : 4;
    622     unsigned fTCPE   : 1;
    623     unsigned fIPE    : 1;
    624     unsigned fRXE    : 1;
    625     /* Descriptor Special field */
    626     unsigned u12VLAN : 12;
    627     unsigned fCFI    : 1;
    628     unsigned u3PRI   : 3;
     619    unsigned fTCPCS  : 1;       /**< RCP Checksum calculated on the packet. */
     620    unsigned fIPCS   : 1;        /**< IP Checksum calculated on the packet. */
     621    unsigned fPIF    : 1;                       /**< Passed in-exact filter */
     622    /** @} */
     623    /** @name Descriptor Errors field (3.2.3.2)
     624     * (Only valid when fEOP and fDD are set.)
     625     * @{ */
     626    unsigned fCE     : 1;                      /**< CRC or alignment error. */
     627    unsigned         : 4;    /**< Reserved, varies with different models... */
     628    unsigned fTCPE   : 1;                      /**< TCP/UDP checksum error. */
     629    unsigned fIPE    : 1;                           /**< IP Checksum error. */
     630    unsigned fRXE    : 1;                               /**< RX Data error. */
     631    /** @} */
     632    /** @name Descriptor Special field (3.2.3.3)
     633     * @{  */
     634    unsigned u12VLAN : 12;                            /**< VLAN identifier. */
     635    unsigned fCFI    : 1;             /**< Canonical form indicator (VLAN). */
     636    unsigned u3PRI   : 3;                        /**< User priority (VLAN). */
     637    /** @} */
    629638};
    630639typedef struct E1kRxDStatus E1KRXDST;
     
    679688};
    680689
     690/**
     691 * TCP/IP Context Transmit Descriptor, section 3.3.6.
     692 */
    681693struct E1kTDContext
    682694{
    683695    struct CheckSum_st
    684696    {
     697        /** TSE: Header start. !TSE: Checksum start. */
    685698        unsigned u8CSS     : 8;
     699        /** Checksum offset - where to store it. */
    686700        unsigned u8CSO     : 8;
     701        /** Checksum ending (inclusive) offset, 0 = end of packet. */
    687702        unsigned u16CSE    : 16;
    688703    } ip;
     
    690705    struct TDCDw2_st
    691706    {
     707        /** TSE: The total number of payload bytes for this context. Sans header. */
    692708        unsigned u20PAYLEN : 20;
     709        /** The descriptor type - E1K_DTYP_CONTEXT (0). */
    693710        unsigned u4DTYP    : 4;
    694         /* CMD field       : 8 */
     711        /** TUCMD field, 8 bits
     712         * @{ */
     713        /** TSE: TCP (set) or UDP (clear). */
    695714        unsigned fTCP      : 1;
     715        /** TSE: IPv4 (set) or IPv6 (clear) - for finding the payload length field in
     716         * the IP header.  Does not affect the checksumming.
     717         * @remarks 82544GC/EI interprets a cleared field differently.  */
    696718        unsigned fIP       : 1;
     719        /** TSE: TCP segmentation enable.  When clear the context describes  */
    697720        unsigned fTSE      : 1;
     721        /** Report status (only applies to dw3.fDD for here). */
    698722        unsigned fRS       : 1;
     723        /** Reserved, MBZ. */
    699724        unsigned fRSV1     : 1;
     725        /** Descriptor extension, must be set for this descriptor type. */
    700726        unsigned fDEXT     : 1;
     727        /** Reserved, MBZ. */
    701728        unsigned fRSV2     : 1;
     729        /** Interrupt delay enable. */
    702730        unsigned fIDE      : 1;
     731        /** @} */
    703732    } dw2;
    704733    struct TDCDw3_st
    705734    {
     735        /** Descriptor Done. */
    706736        unsigned fDD       : 1;
     737        /** Reserved, MBZ. */
    707738        unsigned u7RSV     : 7;
     739        /** TSO: The header (prototype) length (Ethernet[, VLAN tag], IP, TCP/UDP. */
    708740        unsigned u8HDRLEN  : 8;
     741        /** TSO: Maximum segment size. */
    709742        unsigned u16MSS    : 16;
    710743    } dw3;
     
    712745typedef struct E1kTDContext E1KTXCTX;
    713746
     747/**
     748 * TCP/IP Data Transmit Descriptor, section 3.3.7.
     749 */
    714750struct E1kTDData
    715751{
    716     uint64_t u64BufAddr;                     /**< Address of data buffer */
     752    uint64_t u64BufAddr;                        /**< Address of data buffer */
    717753    struct TDDCmd_st
    718754    {
     755        /** The total length of data pointed to by this descriptor. */
    719756        unsigned u20DTALEN : 20;
     757        /** The descriptor type - E1K_DTYP_DATA (1). */
    720758        unsigned u4DTYP    : 4;
    721         /* DCMD field       : 8 */
     759        /** @name DCMD field, 8 bits (3.3.7.1).
     760         * @{ */
     761        /** End of packet.  Note TSCTFC update.  */
    722762        unsigned fEOP      : 1;
     763        /** Insert Ethernet FCS/CRC (requires fEOP to be set). */
    723764        unsigned fIFCS     : 1;
     765        /** Use the TSE context when set and the normal when clear. */
    724766        unsigned fTSE      : 1;
     767        /** Report status (dw3.STA). */
    725768        unsigned fRS       : 1;
     769        /** Reserved. 82544GC/EI defines this report packet set (RPS).  */
    726770        unsigned fRSV      : 1;
     771        /** Descriptor extension, must be set for this descriptor type. */
    727772        unsigned fDEXT     : 1;
     773        /** VLAN enable, requires CTRL.VME, auto enables FCS/CRC.
     774         *  Insert dw3.SPECIAL after ethernet header. */
    728775        unsigned fVLE      : 1;
     776        /** Interrupt delay enable. */
    729777        unsigned fIDE      : 1;
     778        /** @} */
    730779    } cmd;
    731780    struct TDDDw3_st
    732781    {
    733         /* STA field */
    734         unsigned fDD       : 1;
    735         unsigned fEC       : 1;
    736         unsigned fLC       : 1;
     782        /** @name STA field (3.3.7.2)
     783         * @{  */
     784        unsigned fDD       : 1;                       /**< Descriptor done. */
     785        unsigned fEC       : 1;                      /**< Excess collision. */
     786        unsigned fLC       : 1;                        /**< Late collision. */
     787        /** Reserved, except for the usual oddball (82544GC/EI) where it's called TU. */
    737788        unsigned fTURSV    : 1;
    738         /* RSV field */
    739         unsigned u4RSV     : 4;
    740         /* POPTS field */
    741         unsigned fIXSM     : 1;
    742         unsigned fTXSM     : 1;
    743         unsigned u6RSV     : 6;
    744         /* Special field*/
    745         unsigned u12VLAN   : 12;
    746         unsigned fCFI      : 1;
    747         unsigned u3PRI     : 3;
     789        /** @} */
     790        unsigned u4RSV     : 4;                   /**< Reserved field, MBZ. */
     791        /** @name POPTS (Packet Option) field (3.3.7.3)
     792         * @{  */
     793        unsigned fIXSM     : 1;                    /**< Insert IP checksum. */
     794        unsigned fTXSM     : 1;               /**< Insert TCP/UDP checksum. */
     795        unsigned u6RSV     : 6;                         /**< Reserved, MBZ. */
     796        /** @} */
     797        /** @name SPECIAL field - VLAN tag to be inserted after ethernet header.
     798         * Requires fEOP, fVLE and CTRL.VME to be set.
     799         * @{ */
     800        unsigned u12VLAN   : 12;                      /**< VLAN identifier. */
     801        unsigned fCFI      : 1;       /**< Canonical form indicator (VLAN). */
     802        unsigned u3PRI     : 3;                  /**< User priority (VLAN). */
     803        /** @}  */
    748804    } dw3;
    749805};
     
    889945#endif
    890946
     947#ifdef VBOX_WITH_TX_THREAD_IN_NET_DEVICES
    891948    PPDMTHREAD  pTxThread;                                    /**< Transmit thread. */
     949#endif
    892950    PDMCRITSECT cs;                  /**< Critical section - what is it protecting? */
    893951#ifndef E1K_GLOBAL_MUTEX
     
    9491007    /** TX: Context used for ordinary packets. */
    9501008    E1KTXCTX    contextNormal;
     1009#if 1 /** @todo bird/buffering: change this to a 240 bytes buffer of the headers when TSE=1. */
    9511010    /** TX: Transmit packet buffer. */
    9521011    uint8_t     aTxPacket[E1K_MAX_TX_PKT_SIZE];
     1012#endif
    9531013    /** TX: Number of bytes assembled in TX packet buffer. */
    9541014    uint16_t    u16TxPktLen;
     
    9981058    STAMPROFILEADV                      StatReceiveStore;
    9991059    STAMPROFILEADV                      StatTransmit;
    1000     STAMPROFILEADV                      StatTransmitSend;
     1060    STAMPROFILE                         StatTransmitSend;
    10011061    STAMPROFILE                         StatRxOverflow;
    10021062    STAMCOUNTER                         StatRxOverflowWakeup;
     
    14481508 * @thread  E1000_TX
    14491509 */
    1450 static DECLCALLBACK(uint16_t) e1kCSum16(const void *pvBuf, size_t cb)
     1510static uint16_t e1kCSum16(const void *pvBuf, size_t cb)
    14511511{
    14521512    uint32_t  csum = 0;
     
    14961556 * Determine the type of transmit descriptor.
    14971557 *
    1498  * @returns Descriptor type. See E1K_DTYPE_XXX defines.
     1558 * @returns Descriptor type. See E1K_DTYP_XXX defines.
    14991559 *
    15001560 * @param   pDesc       Pointer to descriptor union.
     
    19952055             * modifies RDT only.
    19962056             */
    1997             if(cb > pState->u16RxBSize)
     2057            if (cb > pState->u16RxBSize)
    19982058            {
    19992059                desc.status.fEOP = false;
     
    28432903
    28442904
     2905    int rc = VINF_SUCCESS;
    28452906    if (GET_BITS(RCTL, LBM) == RCTL_LBM_TCVR)
    28462907    {
     
    28552916        //e1kCsLeave(pState);
    28562917        e1kMutexRelease(pState);
    2857         STAM_PROFILE_ADV_START(&pState->StatTransmitSend, a);
    2858         int rc = pState->pDrv->pfnSendDeprecated(pState->pDrv, pFrame, u16FrameLen);
    2859         STAM_PROFILE_ADV_STOP(&pState->StatTransmitSend, a);
     2918        STAM_PROFILE_START(&pState->StatTransmitSend, a);
     2919        rc = pState->pDrv->pfnSendDeprecated(pState->pDrv, pFrame, u16FrameLen);
     2920        STAM_PROFILE_STOP(&pState->StatTransmitSend, a);
    28602921        if (rc != VINF_SUCCESS)
    28612922        {
     
    28652926        //e1kCsEnter(pState, RT_SRC_POS);
    28662927    }
     2928#if 0  /** @todo bird/buf: error handling. */
     2929    else
     2930        rc = VERR_NET_DOWN;
     2931    if (RT_FAILURE(rc))
     2932    {
     2933        /** @todo handle VERR_NET_DOWN and VERR_NET_NO_BUFFER_SPACE. Signal error. */
     2934        ;
     2935    }
     2936#endif
     2937
    28672938#ifdef E1K_LEDS_WITH_MUTEX
    28682939    if (RT_LIKELY(e1kCsEnter(pState, VERR_SEM_BUSY, RT_SRC_POS) == VINF_SUCCESS))
     
    28772948
    28782949/**
    2879  * Compute and write checksum at the specified offset.
     2950 * Compute and write internet checksum (e1kCSum16) at the specified offset.
    28802951 *
    28812952 * @param   pState      The device state structure.
     
    29002971    if (cse == 0)
    29012972        cse = u16PktLen - 1;
     2973    uint16_t u16ChkSum = e1kCSum16(pPkt + css, cse - css + 1);
    29022974    E1kLog2(("%s Inserting csum: %04X at %02X, old value: %04X\n", INSTANCE(pState),
    2903              e1kCSum16(pPkt + css, cse - css + 1), cso,
    2904                        *(uint16_t*)(pPkt + cso)));
    2905     *(uint16_t*)(pPkt + cso) = e1kCSum16(pPkt + css, cse - css + 1);
     2975             u16ChkSum, cso, *(uint16_t*)(pPkt + cso)));
     2976    *(uint16_t*)(pPkt + cso) = u16ChkSum;
    29062977}
    29072978
     
    29172988 * @param   u16Len      Length of buffer to the end of segment.
    29182989 * @param   fSend       Force packet sending.
     2990 * @param   pSgBuf      The current scatter gather buffer.
    29192991 * @thread  E1000_TX
    29202992 */
     
    29893061            E1K_INC_CNT32(TSCTC);
    29903062        }
     3063        /** @todo else: inc TSCTFC, see EOP description in 3.3.7.1. */
    29913064        /* Add TCP length to partial pseudo header sum */
    29923065        uint32_t csum = pState->u32SavedCsum
     
    30153088 *          and legacy descriptors since it is identical to
    30163089 *          legacy.u64BufAddr.
     3090 *
     3091 * @returns true if the frame should be transmitted, false if not.
    30173092 *
    30183093 * @param   pState      The device state structure.
     
    30573132        return false;
    30583133    }
    3059     else
    3060     {
    3061         if (u32PartLen + pState->u16TxPktLen > E1K_MAX_TX_PKT_SIZE)
    3062         {
    3063             E1kLog(("%s Transmit packet is too large: %d > %d(max)\n",
    3064                     INSTANCE(pState), u32PartLen + pState->u16TxPktLen, E1K_MAX_TX_PKT_SIZE));
    3065             return false;
    3066         }
    3067         else
    3068         {
    3069             PDMDevHlpPhysRead(pState->CTX_SUFF(pDevIns), pDesc->data.u64BufAddr, pState->aTxPacket + pState->u16TxPktLen, u32PartLen);
    3070             pState->u16TxPktLen += u32PartLen;
    3071         }
    3072     }
     3134
     3135    if (u32PartLen + pState->u16TxPktLen > E1K_MAX_TX_PKT_SIZE)
     3136    {
     3137        E1kLog(("%s Transmit packet is too large: %d > %d(max)\n",
     3138                INSTANCE(pState), u32PartLen + pState->u16TxPktLen, E1K_MAX_TX_PKT_SIZE));
     3139        return false;
     3140    }
     3141    PDMDevHlpPhysRead(pState->CTX_SUFF(pDevIns), pDesc->data.u64BufAddr, pState->aTxPacket + pState->u16TxPktLen, u32PartLen);
     3142    pState->u16TxPktLen += u32PartLen;
    30733143
    30743144    return true;
     
    31093179                /* Arm the timer to fire in TIVD usec (discard .024) */
    31103180                e1kArmTimer(pState, pState->CTX_SUFF(pTIDTimer), TIDV);
    3111 #ifndef E1K_NO_TAD
     3181# ifndef E1K_NO_TAD
    31123182                /* If absolute timer delay is enabled and the timer is not running yet, arm it. */
    31133183                E1kLog2(("%s Checking if TAD timer is running\n",
     
    31153185                if (TADV != 0 && !TMTimerIsActive(pState->CTX_SUFF(pTADTimer)))
    31163186                    e1kArmTimer(pState, pState->CTX_SUFF(pTADTimer), TADV);
    3117 #endif /* E1K_NO_TAD */
     3187# endif /* E1K_NO_TAD */
    31183188            }
    31193189            else
     
    31213191                E1kLog2(("%s No IDE set, cancel TAD timer and raise interrupt\n",
    31223192                        INSTANCE(pState)));
    3123 #ifndef E1K_NO_TAD
     3193# ifndef E1K_NO_TAD
    31243194                /* Cancel both timers if armed and fire immediately. */
    31253195                e1kCancelTimer(pState, pState->CTX_SUFF(pTADTimer));
    3126 #endif /* E1K_NO_TAD */
     3196# endif /* E1K_NO_TAD */
    31273197#endif /* E1K_USE_TX_TIMERS */
    31283198                E1K_INC_ISTAT_CNT(pState->uStatIntTx);
     
    32583328}
    32593329
     3330#ifdef VBOX_WITH_TX_THREAD_IN_NET_DEVICES
     3331
    32603332/**
    32613333 * Wake up callback for transmission thread.
     
    33253397}
    33263398
     3399#endif /* VBOX_WITH_TX_THREAD_IN_NET_DEVICES */
     3400
    33273401/**
    33283402 * Callback for consuming from transmit queue. It gets called in R3 whenever
     
    35893663 */
    35903664
    3591 static int e1kRegWriteUnimplemented(E1KSTATE* pState, uint32_t offset, uint32_t index, uint32_t value)
     3665 static int e1kRegWriteUnimplemented(E1KSTATE* pState, uint32_t offset, uint32_t index, uint32_t value)
    35923666{
    35933667    E1kLog(("%s At %08X write attempt (%08X) to  unimplemented register %s (%s)\n",
     
    52995373    e1kHardReset(pState);
    53005374
     5375#ifdef VBOX_WITH_TX_THREAD_IN_NET_DEVICES
    53015376    rc = PDMDevHlpThreadCreate(pDevIns, &pState->pTxThread, pState, e1kTxThread, e1kTxThreadWakeUp, 0, RTTHREADTYPE_IO, "E1000_TX");
    53025377    if (RT_FAILURE(rc))
    53035378        return rc;
     5379#endif
    53045380
    53055381#if defined(VBOX_WITH_STATISTICS) || defined(E1K_REL_STATS)
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