- Timestamp:
- Apr 4, 2010 12:34:24 AM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Network/DevE1000.cpp
r27298 r27974 31 31 */ 32 32 33 33 #define VBOX_WITH_TX_THREAD_IN_NET_DEVICES 1 //debug, bird, remove 34 34 #define LOG_GROUP LOG_GROUP_DEV_E1000 35 35 … … 166 166 /*****************************************************************************/ 167 167 168 /** Gets the specfieid bits from the register. */ 168 169 #define GET_BITS(reg, bits) ((reg & reg##_##bits##_MASK) >> reg##_##bits##_SHIFT) 169 170 #define GET_BITS_V(val, reg, bits) ((val & reg##_##bits##_MASK) >> reg##_##bits##_SHIFT) … … 216 217 #define RCTL_RDMTS_MASK 0x00000300 217 218 #define RCTL_RDMTS_SHIFT 8 218 #define RCTL_LBM_TCVR 3 219 #define RCTL_LBM_TCVR 3 /**< PHY or external SerDes loopback. */ 219 220 #define RCTL_MO_MASK 0x00003000 220 221 #define RCTL_MO_SHIFT 12 … … 606 607 }; 607 608 609 608 610 struct E1kRxDStatus 609 611 { 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. */ 615 618 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 /** @} */ 629 638 }; 630 639 typedef struct E1kRxDStatus E1KRXDST; … … 679 688 }; 680 689 690 /** 691 * TCP/IP Context Transmit Descriptor, section 3.3.6. 692 */ 681 693 struct E1kTDContext 682 694 { 683 695 struct CheckSum_st 684 696 { 697 /** TSE: Header start. !TSE: Checksum start. */ 685 698 unsigned u8CSS : 8; 699 /** Checksum offset - where to store it. */ 686 700 unsigned u8CSO : 8; 701 /** Checksum ending (inclusive) offset, 0 = end of packet. */ 687 702 unsigned u16CSE : 16; 688 703 } ip; … … 690 705 struct TDCDw2_st 691 706 { 707 /** TSE: The total number of payload bytes for this context. Sans header. */ 692 708 unsigned u20PAYLEN : 20; 709 /** The descriptor type - E1K_DTYP_CONTEXT (0). */ 693 710 unsigned u4DTYP : 4; 694 /* CMD field : 8 */ 711 /** TUCMD field, 8 bits 712 * @{ */ 713 /** TSE: TCP (set) or UDP (clear). */ 695 714 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. */ 696 718 unsigned fIP : 1; 719 /** TSE: TCP segmentation enable. When clear the context describes */ 697 720 unsigned fTSE : 1; 721 /** Report status (only applies to dw3.fDD for here). */ 698 722 unsigned fRS : 1; 723 /** Reserved, MBZ. */ 699 724 unsigned fRSV1 : 1; 725 /** Descriptor extension, must be set for this descriptor type. */ 700 726 unsigned fDEXT : 1; 727 /** Reserved, MBZ. */ 701 728 unsigned fRSV2 : 1; 729 /** Interrupt delay enable. */ 702 730 unsigned fIDE : 1; 731 /** @} */ 703 732 } dw2; 704 733 struct TDCDw3_st 705 734 { 735 /** Descriptor Done. */ 706 736 unsigned fDD : 1; 737 /** Reserved, MBZ. */ 707 738 unsigned u7RSV : 7; 739 /** TSO: The header (prototype) length (Ethernet[, VLAN tag], IP, TCP/UDP. */ 708 740 unsigned u8HDRLEN : 8; 741 /** TSO: Maximum segment size. */ 709 742 unsigned u16MSS : 16; 710 743 } dw3; … … 712 745 typedef struct E1kTDContext E1KTXCTX; 713 746 747 /** 748 * TCP/IP Data Transmit Descriptor, section 3.3.7. 749 */ 714 750 struct E1kTDData 715 751 { 716 uint64_t u64BufAddr; /**< Address of data buffer */752 uint64_t u64BufAddr; /**< Address of data buffer */ 717 753 struct TDDCmd_st 718 754 { 755 /** The total length of data pointed to by this descriptor. */ 719 756 unsigned u20DTALEN : 20; 757 /** The descriptor type - E1K_DTYP_DATA (1). */ 720 758 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. */ 722 762 unsigned fEOP : 1; 763 /** Insert Ethernet FCS/CRC (requires fEOP to be set). */ 723 764 unsigned fIFCS : 1; 765 /** Use the TSE context when set and the normal when clear. */ 724 766 unsigned fTSE : 1; 767 /** Report status (dw3.STA). */ 725 768 unsigned fRS : 1; 769 /** Reserved. 82544GC/EI defines this report packet set (RPS). */ 726 770 unsigned fRSV : 1; 771 /** Descriptor extension, must be set for this descriptor type. */ 727 772 unsigned fDEXT : 1; 773 /** VLAN enable, requires CTRL.VME, auto enables FCS/CRC. 774 * Insert dw3.SPECIAL after ethernet header. */ 728 775 unsigned fVLE : 1; 776 /** Interrupt delay enable. */ 729 777 unsigned fIDE : 1; 778 /** @} */ 730 779 } cmd; 731 780 struct TDDDw3_st 732 781 { 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. */ 737 788 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 /** @} */ 748 804 } dw3; 749 805 }; … … 889 945 #endif 890 946 947 #ifdef VBOX_WITH_TX_THREAD_IN_NET_DEVICES 891 948 PPDMTHREAD pTxThread; /**< Transmit thread. */ 949 #endif 892 950 PDMCRITSECT cs; /**< Critical section - what is it protecting? */ 893 951 #ifndef E1K_GLOBAL_MUTEX … … 949 1007 /** TX: Context used for ordinary packets. */ 950 1008 E1KTXCTX contextNormal; 1009 #if 1 /** @todo bird/buffering: change this to a 240 bytes buffer of the headers when TSE=1. */ 951 1010 /** TX: Transmit packet buffer. */ 952 1011 uint8_t aTxPacket[E1K_MAX_TX_PKT_SIZE]; 1012 #endif 953 1013 /** TX: Number of bytes assembled in TX packet buffer. */ 954 1014 uint16_t u16TxPktLen; … … 998 1058 STAMPROFILEADV StatReceiveStore; 999 1059 STAMPROFILEADV StatTransmit; 1000 STAMPROFILE ADVStatTransmitSend;1060 STAMPROFILE StatTransmitSend; 1001 1061 STAMPROFILE StatRxOverflow; 1002 1062 STAMCOUNTER StatRxOverflowWakeup; … … 1448 1508 * @thread E1000_TX 1449 1509 */ 1450 static DECLCALLBACK(uint16_t)e1kCSum16(const void *pvBuf, size_t cb)1510 static uint16_t e1kCSum16(const void *pvBuf, size_t cb) 1451 1511 { 1452 1512 uint32_t csum = 0; … … 1496 1556 * Determine the type of transmit descriptor. 1497 1557 * 1498 * @returns Descriptor type. See E1K_DTYP E_XXX defines.1558 * @returns Descriptor type. See E1K_DTYP_XXX defines. 1499 1559 * 1500 1560 * @param pDesc Pointer to descriptor union. … … 1995 2055 * modifies RDT only. 1996 2056 */ 1997 if (cb > pState->u16RxBSize)2057 if (cb > pState->u16RxBSize) 1998 2058 { 1999 2059 desc.status.fEOP = false; … … 2843 2903 2844 2904 2905 int rc = VINF_SUCCESS; 2845 2906 if (GET_BITS(RCTL, LBM) == RCTL_LBM_TCVR) 2846 2907 { … … 2855 2916 //e1kCsLeave(pState); 2856 2917 e1kMutexRelease(pState); 2857 STAM_PROFILE_ ADV_START(&pState->StatTransmitSend, a);2858 intrc = 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); 2860 2921 if (rc != VINF_SUCCESS) 2861 2922 { … … 2865 2926 //e1kCsEnter(pState, RT_SRC_POS); 2866 2927 } 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 2867 2938 #ifdef E1K_LEDS_WITH_MUTEX 2868 2939 if (RT_LIKELY(e1kCsEnter(pState, VERR_SEM_BUSY, RT_SRC_POS) == VINF_SUCCESS)) … … 2877 2948 2878 2949 /** 2879 * Compute and write checksumat the specified offset.2950 * Compute and write internet checksum (e1kCSum16) at the specified offset. 2880 2951 * 2881 2952 * @param pState The device state structure. … … 2900 2971 if (cse == 0) 2901 2972 cse = u16PktLen - 1; 2973 uint16_t u16ChkSum = e1kCSum16(pPkt + css, cse - css + 1); 2902 2974 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; 2906 2977 } 2907 2978 … … 2917 2988 * @param u16Len Length of buffer to the end of segment. 2918 2989 * @param fSend Force packet sending. 2990 * @param pSgBuf The current scatter gather buffer. 2919 2991 * @thread E1000_TX 2920 2992 */ … … 2989 3061 E1K_INC_CNT32(TSCTC); 2990 3062 } 3063 /** @todo else: inc TSCTFC, see EOP description in 3.3.7.1. */ 2991 3064 /* Add TCP length to partial pseudo header sum */ 2992 3065 uint32_t csum = pState->u32SavedCsum … … 3015 3088 * and legacy descriptors since it is identical to 3016 3089 * legacy.u64BufAddr. 3090 * 3091 * @returns true if the frame should be transmitted, false if not. 3017 3092 * 3018 3093 * @param pState The device state structure. … … 3057 3132 return false; 3058 3133 } 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; 3073 3143 3074 3144 return true; … … 3109 3179 /* Arm the timer to fire in TIVD usec (discard .024) */ 3110 3180 e1kArmTimer(pState, pState->CTX_SUFF(pTIDTimer), TIDV); 3111 # ifndef E1K_NO_TAD3181 # ifndef E1K_NO_TAD 3112 3182 /* If absolute timer delay is enabled and the timer is not running yet, arm it. */ 3113 3183 E1kLog2(("%s Checking if TAD timer is running\n", … … 3115 3185 if (TADV != 0 && !TMTimerIsActive(pState->CTX_SUFF(pTADTimer))) 3116 3186 e1kArmTimer(pState, pState->CTX_SUFF(pTADTimer), TADV); 3117 # endif /* E1K_NO_TAD */3187 # endif /* E1K_NO_TAD */ 3118 3188 } 3119 3189 else … … 3121 3191 E1kLog2(("%s No IDE set, cancel TAD timer and raise interrupt\n", 3122 3192 INSTANCE(pState))); 3123 # ifndef E1K_NO_TAD3193 # ifndef E1K_NO_TAD 3124 3194 /* Cancel both timers if armed and fire immediately. */ 3125 3195 e1kCancelTimer(pState, pState->CTX_SUFF(pTADTimer)); 3126 # endif /* E1K_NO_TAD */3196 # endif /* E1K_NO_TAD */ 3127 3197 #endif /* E1K_USE_TX_TIMERS */ 3128 3198 E1K_INC_ISTAT_CNT(pState->uStatIntTx); … … 3258 3328 } 3259 3329 3330 #ifdef VBOX_WITH_TX_THREAD_IN_NET_DEVICES 3331 3260 3332 /** 3261 3333 * Wake up callback for transmission thread. … … 3325 3397 } 3326 3398 3399 #endif /* VBOX_WITH_TX_THREAD_IN_NET_DEVICES */ 3400 3327 3401 /** 3328 3402 * Callback for consuming from transmit queue. It gets called in R3 whenever … … 3589 3663 */ 3590 3664 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) 3592 3666 { 3593 3667 E1kLog(("%s At %08X write attempt (%08X) to unimplemented register %s (%s)\n", … … 5299 5373 e1kHardReset(pState); 5300 5374 5375 #ifdef VBOX_WITH_TX_THREAD_IN_NET_DEVICES 5301 5376 rc = PDMDevHlpThreadCreate(pDevIns, &pState->pTxThread, pState, e1kTxThread, e1kTxThreadWakeUp, 0, RTTHREADTYPE_IO, "E1000_TX"); 5302 5377 if (RT_FAILURE(rc)) 5303 5378 return rc; 5379 #endif 5304 5380 5305 5381 #if defined(VBOX_WITH_STATISTICS) || defined(E1K_REL_STATS)
Note:
See TracChangeset
for help on using the changeset viewer.