Changeset 7374 in vbox
- Timestamp:
- Mar 7, 2008 3:41:17 PM (17 years ago)
- svn:sync-xref-src-repo-rev:
- 28798
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Network/DevPCNet.cpp
r7358 r7374 71 71 #define PCNET_GC_ENABLED 72 72 73 /* Experimental: queue TX packets */ 74 //#define PCNET_QUEUE_SEND_PACKETS 75 73 76 #if defined(LOG_ENABLED) 74 77 #define PCNET_DEBUG_IO … … 95 98 #define MAX_FRAME 1536 96 99 97 /* Frame cache */98 typedef struct PCNETFRAME99 {100 /** The current frame size. Starts at -1. Only the top frame can be expanded. */101 int32_t cb;102 #if HC_ARCH_BITS == 64103 uint32_t Alignment;104 #endif105 /** The virtual address of the frame (copied or direct pointer) */106 RTR3PTR pvBuf;107 } PCNETFRAME;108 /* Pointer to PCNETFRAME */109 typedef PCNETFRAME *PPCNETFRAME;110 100 111 101 typedef struct PCNetState_st PCNetState; … … 149 139 uint64_t u64LastPoll; 150 140 151 /** Array of frames. */ 152 PCNETFRAME SendFrame; 141 /** Size of current send frame */ 142 uint32_t cbSendFrame; 143 /** Buffer address of current send frame */ 144 uint8_t *pvSendFrame; 153 145 /** The xmit buffer. */ 154 146 uint8_t abSendBuf[4096]; … … 239 231 uint32_t u32LinkSpeed; 240 232 241 //#define PCNET_QUEUE_SEND_PACKETS242 233 #ifdef PCNET_QUEUE_SEND_PACKETS 243 234 #define PCNET_MAX_XMIT_SLOTS 128 244 235 #define PCNET_MAX_XMIT_SLOTS_MASK (PCNET_MAX_XMIT_SLOTS-1) 245 236 246 uint32_t ulXmitRingBufProd; 247 uint32_t ulXmitRingBufCons; 237 uint32_t iXmitRingBufProd; 238 uint32_t iXmitRingBufCons; 239 /* XXX currently atomic operations on this variable are overkill */ 240 volatile int32_t cXmitRingBufPending; 248 241 uint16_t cbXmitRingBuffer[PCNET_MAX_XMIT_SLOTS]; 249 R3PTRTYPE( char *)pXmitRingBuffer[PCNET_MAX_XMIT_SLOTS];242 R3PTRTYPE(uint8_t *) apXmitRingBuffer[PCNET_MAX_XMIT_SLOTS]; 250 243 #endif 251 244 … … 579 572 (R)->rmd2.zeros)) 580 573 581 #if def PCNET_QUEUE_SEND_PACKETS574 #if defined(PCNET_QUEUE_SEND_PACKETS) && defined(IN_RING3) 582 575 static int pcnetSyncTransmit(PCNetState *pData); 583 576 #endif … … 1833 1826 ASMAtomicAndU32(&pData->cPendingSends, 0); 1834 1827 #ifdef PCNET_QUEUE_SEND_PACKETS 1828 int rc = PDMCritSectEnter(&pData->CritSect, VERR_SEM_BUSY); 1829 AssertReleaseRC(rc); 1835 1830 pcnetSyncTransmit(pData); 1831 PDMCritSectLeave(&pData->CritSect); 1836 1832 #else 1837 1833 int rc = RTSemEventSignal(pData->hSendEventSem); … … 1848 1844 DECLINLINE(void) pcnetXmitScrapFrame(PCNetState *pData) 1849 1845 { 1850 pData->SendFrame.pvBuf = NULL; 1851 pData->SendFrame.cb = -1; 1852 } 1853 1854 1855 /** 1856 * If we are in RING3 don't copy the frame from GC here but only store the address. We 1857 * don't need to buffer the frames because a direct address translation was possible. 1858 */ 1859 DECLINLINE(void) pcnetXmitZeroCopyFrame(PCNetState *pData, RTR3PTR pv, const unsigned cbFrame) 1860 { 1861 pData->SendFrame.pvBuf = pv; 1862 pData->SendFrame.cb = cbFrame; 1846 pData->pvSendFrame = NULL; 1847 pData->cbSendFrame = 0; 1863 1848 } 1864 1849 … … 1869 1854 DECLINLINE(void) pcnetXmitRead1st(PCNetState *pData, RTGCPHYS32 GCPhysFrame, const unsigned cbFrame) 1870 1855 { 1856 Assert(PDMCritSectIsOwner(&pData->CritSect)); 1871 1857 Assert(cbFrame < sizeof(pData->abSendBuf)); 1872 1858 1873 PDMDevHlpPhysRead(pData->CTXSUFF(pDevIns), GCPhysFrame, &pData->abSendBuf[0], cbFrame); 1874 pData->SendFrame.pvBuf = pData->abSendBuf; 1875 pData->SendFrame.cb = cbFrame; 1859 #ifdef PCNET_QUEUE_SEND_PACKETS 1860 AssertRelease(pData->cXmitRingBufPending < PCNET_MAX_XMIT_SLOTS-1); 1861 pData->pvSendFrame = pData->apXmitRingBuffer[pData->iXmitRingBufProd]; 1862 #else 1863 pData->pvSendFrame = pData->abSendBuf; 1864 #endif 1865 PDMDevHlpPhysRead(pData->CTXSUFF(pDevIns), GCPhysFrame, pData->pvSendFrame, cbFrame); 1866 pData->cbSendFrame = cbFrame; 1876 1867 } 1877 1868 … … 1882 1873 DECLINLINE(void) pcnetXmitReadMore(PCNetState *pData, RTGCPHYS32 GCPhysFrame, const unsigned cbFrame) 1883 1874 { 1884 Assert(pData-> SendFrame.cb + cbFrame < sizeof(pData->abSendBuf));1885 PDMDevHlpPhysRead(pData->CTXSUFF(pDevIns), GCPhysFrame, &pData->abSendBuf[pData->SendFrame.cb], cbFrame);1886 pData-> SendFrame.cb+= cbFrame;1875 Assert(pData->cbSendFrame + cbFrame <= MAX_FRAME); 1876 PDMDevHlpPhysRead(pData->CTXSUFF(pDevIns), GCPhysFrame, pData->pvSendFrame + pData->cbSendFrame, cbFrame); 1877 pData->cbSendFrame += cbFrame; 1887 1878 } 1888 1879 … … 1895 1886 { 1896 1887 #ifdef PCNET_QUEUE_SEND_PACKETS 1897 Assert(!pData->cbXmitRingBuffer[pData->ulXmitRingBufProd]); 1898 memcpy(pData->pXmitRingBuffer[pData->ulXmitRingBufProd], pData->SendFrame.pvBuf, pData->SendFrame.cb); 1899 pData->cbXmitRingBuffer[pData->ulXmitRingBufProd] = (uint16_t)pData->SendFrame.cb; 1900 pData->ulXmitRingBufProd = (pData->ulXmitRingBufProd+1) & PCNET_MAX_XMIT_SLOTS_MASK; 1888 Assert(PDMCritSectIsOwner(&pData->CritSect)); 1889 AssertRelease(pData->cXmitRingBufPending < PCNET_MAX_XMIT_SLOTS-1); 1890 Assert(!pData->cbXmitRingBuffer[pData->iXmitRingBufProd]); 1891 1892 pData->cbXmitRingBuffer[pData->iXmitRingBufProd] = (uint16_t)pData->cbSendFrame; 1893 pData->iXmitRingBufProd = (pData->iXmitRingBufProd+1) & PCNET_MAX_XMIT_SLOTS_MASK; 1894 ASMAtomicIncS32(&pData->cXmitRingBufPending); 1901 1895 1902 1896 int rc = RTSemEventSignal(pData->hSendEventSem); … … 1910 1904 1911 1905 STAM_PROFILE_ADV_START(&pData->StatTransmitSend, a); 1912 if (pData-> SendFrame.cb> 70) /* unqualified guess */1906 if (pData->cbSendFrame > 70) /* unqualified guess */ 1913 1907 pData->Led.Asserted.s.fWriting = pData->Led.Actual.s.fWriting = 1; 1914 1908 1915 pData->pDrv->pfnSend(pData->pDrv, pData-> SendFrame.pvBuf, pData->SendFrame.cb);1916 STAM_REL_COUNTER_ADD(&pData->StatTransmitBytes, pData-> SendFrame.cb);1909 pData->pDrv->pfnSend(pData->pDrv, pData->pvSendFrame, pData->cbSendFrame); 1910 STAM_REL_COUNTER_ADD(&pData->StatTransmitBytes, pData->cbSendFrame); 1917 1911 pData->Led.Actual.s.fWriting = 0; 1918 1912 STAM_PROFILE_ADV_STOP(&pData->StatTransmitSend, a); … … 1960 1954 pcnetRdtePoll(pData); 1961 1955 1962 Assert(pData-> SendFrame.pvBuf);1963 pcnetReceiveNoSync(pData, (const uint8_t *)pData-> SendFrame.pvBuf, pData->SendFrame.cb);1956 Assert(pData->pvSendFrame); 1957 pcnetReceiveNoSync(pData, (const uint8_t *)pData->pvSendFrame, pData->cbSendFrame); 1964 1958 pcnetXmitScrapFrame(pData); 1965 1959 pData->Led.Actual.s.fReading = 0; … … 2031 2025 { 2032 2026 Assert(PDMCritSectIsOwner(&pData->CritSect)); 2033 2034 while (pData->cbXmitRingBuffer[pData->ulXmitRingBufCons]) 2035 { 2027 size_t cb; 2028 2029 while ((pData->cXmitRingBufPending > 0)) 2030 { 2031 cb = pData->cbXmitRingBuffer[pData->iXmitRingBufCons]; 2032 2036 2033 /* Don't hold the critical section while transmitting data. */ 2037 2034 /** @note also avoids deadlocks with NAT as it can call us right back. */ … … 2039 2036 2040 2037 STAM_PROFILE_ADV_START(&pData->StatTransmitSend, a); 2041 if ( pData->SendFrame.cb > 70) /* unqualified guess */2038 if (cb > 70) /* unqualified guess */ 2042 2039 pData->Led.Asserted.s.fWriting = pData->Led.Actual.s.fWriting = 1; 2043 2040 2044 pData->pDrv->pfnSend(pData->pDrv, pData-> pXmitRingBuffer[pData->ulXmitRingBufCons], pData->cbXmitRingBuffer[pData->ulXmitRingBufCons]);2045 STAM_REL_COUNTER_ADD(&pData->StatTransmitBytes, pData->cbXmitRingBuffer[pData->ulXmitRingBufCons]);2041 pData->pDrv->pfnSend(pData->pDrv, pData->apXmitRingBuffer[pData->iXmitRingBufCons], cb); 2042 STAM_REL_COUNTER_ADD(&pData->StatTransmitBytes, cb); 2046 2043 pData->Led.Actual.s.fWriting = 0; 2047 2044 STAM_PROFILE_ADV_STOP(&pData->StatTransmitSend, a); 2048 2045 2049 PDMCritSectEnter(&pData->CritSect, VERR_SEM_BUSY); 2050 2051 pData->cbXmitRingBuffer[pData->ulXmitRingBufCons] = 0; 2052 pData->ulXmitRingBufCons = (pData->ulXmitRingBufCons+1) & PCNET_MAX_XMIT_SLOTS_MASK; 2046 int rc = PDMCritSectEnter(&pData->CritSect, VERR_SEM_BUSY); 2047 AssertReleaseRC(rc); 2048 2049 pData->cbXmitRingBuffer[pData->iXmitRingBufCons] = 0; 2050 pData->iXmitRingBufCons = (pData->iXmitRingBufCons+1) & PCNET_MAX_XMIT_SLOTS_MASK; 2051 ASMAtomicDecS32(&pData->cXmitRingBufPending); 2053 2052 } 2054 2053 return VINF_SUCCESS; … … 2206 2205 pcnetTmdLoad(pData, &tmd, PHYSADDR(pData, CSR_CXDA(pData)), false); 2207 2206 cb = 4096 - tmd.tmd1.bcnt; 2208 if ( pData-> SendFrame.cb+ cb < MAX_FRAME2207 if ( pData->cbSendFrame + cb < MAX_FRAME 2209 2208 && !fDropFrame) 2210 2209 pcnetXmitReadMore(pData, PHYSADDR(pData, tmd.tmd0.tbadr), cb); … … 2212 2211 { 2213 2212 AssertMsg(fDropFrame, ("pcnetTransmit: Frame is too big!!! %d bytes\n", 2214 pData-> SendFrame.cb+ cb));2213 pData->cbSendFrame + cb)); 2215 2214 fDropFrame = true; 2216 2215 } … … 2218 2217 { 2219 2218 Log(("#%d pcnetTransmit: stp: cb=%d xmtrc=%#x-%#x\n", PCNET_INST_NR, 2220 pData-> SendFrame.cb, iStart, CSR_XMTRC(pData)));2219 pData->cbSendFrame, iStart, CSR_XMTRC(pData))); 2221 2220 if (pcnetIsLinkUp(pData) && !fDropFrame) 2222 2221 { … … 3528 3527 3529 3528 STAM_PROFILE_ADV_START(&pData->StatTimer, a); 3530 rc = PDMCritSectEnter(&pData->CritSect, VERR_ PERMISSION_DENIED);3529 rc = PDMCritSectEnter(&pData->CritSect, VERR_SEM_BUSY); 3531 3530 AssertReleaseRC(rc); 3532 3531 … … 3568 3567 { 3569 3568 PCNetState *pData = PDMINS2DATA(pDevIns, PCNetState *); 3570 int rc = PDMCritSectEnter(&pData->CritSect, VERR_ PERMISSION_DENIED);3569 int rc = PDMCritSectEnter(&pData->CritSect, VERR_SEM_BUSY); 3571 3570 AssertReleaseRC(rc); 3572 3571 … … 3925 3924 PCNetState *pData = PDMINS2DATA(pDevIns, PCNetState *); 3926 3925 3927 PDMCritSectEnter(&pData->CritSect, VERR_PERMISSION_DENIED); 3926 int rc = PDMCritSectEnter(&pData->CritSect, VERR_SEM_BUSY); 3927 AssertRC(rc); 3928 3928 3929 3929 pData->fSaving = true; … … 3987 3987 PCNetState *pData = PDMINS2DATA(pDevIns, PCNetState *); 3988 3988 3989 PDMCritSectEnter(&pData->CritSect, VERR_PERMISSION_DENIED); 3989 int rc = PDMCritSectEnter(&pData->CritSect, VERR_SEM_BUSY); 3990 AssertRC(rc); 3990 3991 pData->fSaving = false; 3991 3992 PDMCritSectLeave(&pData->CritSect); … … 4111 4112 PCNetState *pData = INETWORKPORT_2_DATA(pInterface); 4112 4113 4113 rc = PDMCritSectEnter(&pData->CritSect, VERR_ PERMISSION_DENIED);4114 rc = PDMCritSectEnter(&pData->CritSect, VERR_SEM_BUSY); 4114 4115 AssertReleaseRC(rc); 4115 4116 … … 4136 4137 4137 4138 STAM_PROFILE_ADV_START(&pData->StatReceive, a); 4138 rc = PDMCritSectEnter(&pData->CritSect, VERR_ PERMISSION_DENIED);4139 rc = PDMCritSectEnter(&pData->CritSect, VERR_SEM_BUSY); 4139 4140 AssertReleaseRC(rc); 4140 4141 … … 4321 4322 } 4322 4323 #ifdef PCNET_QUEUE_SEND_PACKETS 4323 if (pData-> pXmitRingBuffer)4324 RTMemFree(pData-> pXmitRingBuffer[0]);4324 if (pData->apXmitRingBuffer) 4325 RTMemFree(pData->apXmitRingBuffer[0]); 4325 4326 #endif 4326 4327 return VINF_SUCCESS; … … 4618 4619 4619 4620 #ifdef PCNET_QUEUE_SEND_PACKETS 4620 pData->ulXmitRingBufProd = 0; 4621 pData->ulXmitRingBufCons = 0; 4622 pData->pXmitRingBuffer[0] = (char *)RTMemAlloc(PCNET_MAX_XMIT_SLOTS * MAX_FRAME); 4623 pData->cbXmitRingBuffer[0] = 0; 4621 pData->apXmitRingBuffer[0] = (uint8_t *)RTMemAlloc(PCNET_MAX_XMIT_SLOTS * MAX_FRAME); 4624 4622 for (i = 1; i < PCNET_MAX_XMIT_SLOTS; i++) 4625 { 4626 pData->pXmitRingBuffer[i] = pData->pXmitRingBuffer[i-1] + MAX_FRAME; 4627 pData->cbXmitRingBuffer[i] = 0; 4628 } 4623 pData->apXmitRingBuffer[i] = pData->apXmitRingBuffer[0] + i*MAX_FRAME; 4629 4624 #endif 4630 4625
Note:
See TracChangeset
for help on using the changeset viewer.