Changeset 24705 in vbox for trunk/src/VBox/Devices/Network
- Timestamp:
- Nov 16, 2009 5:13:52 PM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Network/DevVirtioNet.cpp
r24652 r24705 227 227 228 228 /*****************************************************************************/ 229 RT_C_DECLS_BEGIN 229 #define virtioGetHostFeatures vnetGetHostFeatures 230 #define virtioGetHostMinimalFeatures vnetGetHostMinimalFeatures 231 #define virtioSetHostFeatures vnetSetHostFeatures 232 #define virtioGetConfig vnetGetConfig 233 #define virtioSetConfig vnetSetConfig 234 #define virtioReset vnetReset 235 #define virtioReady vnetReady 236 230 237 PDMBOTHCBDECL(uint32_t) vnetGetHostFeatures(void *pState); 231 238 PDMBOTHCBDECL(uint32_t) vnetGetHostMinimalFeatures(void *pState); … … 235 242 PDMBOTHCBDECL(void) vnetReset(void *pState); 236 243 PDMBOTHCBDECL(void) vnetReady(void *pState); 237 RT_C_DECLS_END238 244 239 245 /*****************************************************************************/ … … 242 248 243 249 #ifdef IN_RING3 244 const struct VirtioPCIDevices 245 { 246 uint16_t uPCIVendorId; 247 uint16_t uPCIDeviceId; 248 uint16_t uPCISubsystemVendorId; 249 uint16_t uPCISubsystemId; 250 uint16_t uPCIClass; 251 unsigned nQueues; 252 const char *pcszName; 253 const char *pcszNameFmt; 254 uint32_t (*pfnGetHostFeatures)(void *pvState); 255 uint32_t (*pfnGetHostMinimalFeatures)(void *pvState); 256 void (*pfnSetHostFeatures)(void *pvState, uint32_t uFeatures); 257 int (*pfnGetConfig)(void *pvState, uint32_t port, uint32_t cb, void *data); 258 int (*pfnSetConfig)(void *pvState, uint32_t port, uint32_t cb, void *data); 259 void (*pfnReset)(void *pvState); 260 void (*pfnReady)(void *pvState); 261 } g_VPCIDevices[] = 262 { 263 /* Vendor Device SSVendor SubSys Class NQ Name Instance */ 264 { /* Virtio Network Device */ 265 0x1AF4, 0x1000, 0x1AF4, 1 + VIRTIO_NET_ID, 0x0200, VNET_NQUEUES, 266 "virtio-net", "vnet%d", 267 vnetGetHostFeatures, vnetGetHostMinimalFeatures, vnetSetHostFeatures, 268 vnetGetConfig, vnetSetConfig, vnetReset, vnetReady 269 }, 250 251 #define DEVICE_PCI_VENDOR_ID 0x1AF4 252 #define DEVICE_PCI_DEVICE_ID 0x1000 253 #define DEVICE_PCI_SUBSYSTEM_VENDOR_ID 0x1AF4 254 #define DEVICE_PCI_SUBSYSTEM_ID 1 + VIRTIO_NET_ID 255 #define DEVICE_PCI_CLASS 0x0200 256 #define DEVICE_N_QUEUES 3 257 #define DEVICE_NAME "virtio-net" 258 #define DEVICE_NAME_FMT "vnet%d" 259 #if 0 270 260 { /* Virtio Block Device */ 271 261 0x1AF4, 0x1001, 0x1AF4, 1 + VIRTIO_BLK_ID, 0x0180, 2, "virtio-blk", "vblk%d", 272 262 NULL, NULL, NULL, NULL, NULL, NULL, NULL 273 263 }, 274 }; 264 #endif 265 275 266 #endif 276 267 … … 295 286 #define VPCI_STATUS_DRV_OK 0x04 296 287 #define VPCI_STATUS_FAILED 0x80 297 298 /** @todo use+extend RTNETIPV4 */299 300 /** @todo use+extend RTNETTCP */301 288 302 289 #ifndef VBOX_DEVICE_STRUCT_TESTCASE … … 519 506 } 520 507 521 #ifdef IN_RING3522 508 void vpciReset(PVPCISTATE pState) 523 509 { … … 530 516 vqueueReset(&pState->Queues[i]); 531 517 } 532 #endif533 518 534 519 … … 556 541 return rc; 557 542 543 STAM_COUNTER_INC(&pState->StatIntsRaised); 558 544 LogFlow(("%s vpciRaiseInterrupt: u8IntCause=%x\n", 559 545 INSTANCE(pState), u8IntCause)); … … 576 562 } 577 563 578 #ifdef IN_RING3579 564 DECLINLINE(uint32_t) vpciGetHostFeatures(PVPCISTATE pState) 580 565 { 581 return g_VPCIDevices[pState->enmDevType].pfnGetHostFeatures(pState)566 return virtioGetHostFeatures(pState) 582 567 | VPCI_F_NOTIFY_ON_EMPTY; 583 568 } 584 #endif585 569 586 570 /** … … 609 593 case VPCI_HOST_FEATURES: 610 594 /* Tell the guest what features we support. */ 611 #ifdef IN_RING3612 595 *pu32 = vpciGetHostFeatures(pState) | VPCI_F_BAD_FEATURE; 613 #else614 rc = VINF_IOM_HC_IOPORT_READ;615 #endif616 596 break; 617 597 … … 649 629 if (port >= VPCI_CONFIG) 650 630 { 651 #ifdef IN_RING3 652 rc = g_VPCIDevices[pState->enmDevType].pfnGetConfig(pState, port - VPCI_CONFIG, cb, pu32); 653 #else 654 rc = VINF_IOM_HC_IOPORT_READ; 655 #endif 631 rc = virtioGetConfig(pState, port - VPCI_CONFIG, cb, pu32); 656 632 } 657 633 else … … 696 672 case VPCI_GUEST_FEATURES: 697 673 /* Check if the guest negotiates properly, fall back to basics if it does not. */ 698 #ifdef IN_RING3699 674 if (VPCI_F_BAD_FEATURE & u32) 700 675 { 701 676 Log(("%s WARNING! Guest failed to negotiate properly (guest=%x)\n", 702 677 INSTANCE(pState), u32)); 703 pState->uGuestFeatures = g_VPCIDevices[pState->enmDevType].pfnGetHostMinimalFeatures(pState);678 pState->uGuestFeatures = virtioGetHostMinimalFeatures(pState); 704 679 } 705 680 /* The guest may potentially desire features we don't support! */ … … 712 687 else 713 688 pState->uGuestFeatures = u32; 714 g_VPCIDevices[pState->enmDevType].pfnSetHostFeatures(pState, pState->uGuestFeatures); 715 #else 716 rc = VINF_IOM_HC_IOPORT_WRITE; 717 #endif 689 virtioSetHostFeatures(pState, pState->uGuestFeatures); 718 690 break; 719 691 720 692 case VPCI_QUEUE_PFN: 721 #ifdef IN_RING3722 693 /* 723 694 * The guest is responsible for allocating the pages for queues, … … 730 701 vqueueInit(&pState->Queues[pState->uQueueSelector], u32); 731 702 else 732 g_VPCIDevices[pState->enmDevType].pfnReset(pState); 733 #else 734 rc = VINF_IOM_HC_IOPORT_WRITE; 735 #endif 703 virtioReset(pState); 736 704 break; 737 705 … … 763 731 764 732 case VPCI_STATUS: 765 #ifdef IN_RING3766 733 Assert(cb == 1); 767 734 u32 &= 0xFF; … … 770 737 /* Writing 0 to the status port triggers device reset. */ 771 738 if (u32 == 0) 772 g_VPCIDevices[pState->enmDevType].pfnReset(pState);739 virtioReset(pState); 773 740 else if (fHasBecomeReady) 774 g_VPCIDevices[pState->enmDevType].pfnReady(pState); 775 #else 776 rc = VINF_IOM_HC_IOPORT_WRITE; 777 #endif 741 virtioReady(pState); 778 742 break; 779 743 780 744 default: 781 #ifdef IN_RING3782 745 if (port >= VPCI_CONFIG) 783 rc = g_VPCIDevices[pState->enmDevType].pfnSetConfig(pState, port - VPCI_CONFIG, cb, &u32);746 rc = virtioSetConfig(pState, port - VPCI_CONFIG, cb, &u32); 784 747 else 785 748 rc = PDMDeviceDBGFStop(pDevIns, RT_SRC_POS, "%s virtioIOPortOut: no valid port at offset port=%RTiop cb=%08x\n", szInst, port, cb); 786 #else787 rc = VINF_IOM_HC_IOPORT_WRITE;788 #endif789 749 break; 790 750 } … … 1062 1022 } 1063 1023 else 1064 pState->nQueues = g_VPCIDevices[pState->enmDevType].nQueues;1024 pState->nQueues = DEVICE_N_QUEUES; 1065 1025 for (unsigned i = 0; i < pState->nQueues; i++) 1066 1026 { … … 1093 1053 static DECLCALLBACK(void) vpciConfigure(PCIDEVICE& pci, VirtioDeviceType enmType) 1094 1054 { 1095 Assert(enmType < (int)RT_ELEMENTS(g_VPCIDevices));1096 1055 /* Configure PCI Device, assume 32-bit mode ******************************/ 1097 PCIDevSetVendorId(&pci, g_VPCIDevices[enmType].uPCIVendorId);1098 PCIDevSetDeviceId(&pci, g_VPCIDevices[enmType].uPCIDeviceId);1099 vpciCfgSetU16(pci, VBOX_PCI_SUBSYSTEM_VENDOR_ID, g_VPCIDevices[enmType].uPCISubsystemVendorId);1100 vpciCfgSetU16(pci, VBOX_PCI_SUBSYSTEM_ID, g_VPCIDevices[enmType].uPCISubsystemId);1056 PCIDevSetVendorId(&pci, DEVICE_PCI_VENDOR_ID); 1057 PCIDevSetDeviceId(&pci, DEVICE_PCI_DEVICE_ID); 1058 vpciCfgSetU16(pci, VBOX_PCI_SUBSYSTEM_VENDOR_ID, DEVICE_PCI_SUBSYSTEM_VENDOR_ID); 1059 vpciCfgSetU16(pci, VBOX_PCI_SUBSYSTEM_ID, DEVICE_PCI_SUBSYSTEM_ID); 1101 1060 1102 1061 /* ABI version, must be equal 0 as of 2.6.30 kernel. */ … … 1104 1063 /* Ethernet adapter */ 1105 1064 vpciCfgSetU8( pci, VBOX_PCI_CLASS_PROG, 0x00); 1106 vpciCfgSetU16(pci, VBOX_PCI_CLASS_DEVICE, g_VPCIDevices[enmType].uPCIClass);1065 vpciCfgSetU16(pci, VBOX_PCI_CLASS_DEVICE, DEVICE_PCI_CLASS); 1107 1066 /* Interrupt Pin: INTA# */ 1108 1067 vpciCfgSetU8( pci, VBOX_PCI_INTERRUPT_PIN, 0x01); … … 1116 1075 int rc = VINF_SUCCESS; 1117 1076 /* Init handles and log related stuff. */ 1118 RTStrPrintf(pState->szInstance, sizeof(pState->szInstance), g_VPCIDevices[enmDevType].pcszNameFmt, iInstance);1077 RTStrPrintf(pState->szInstance, sizeof(pState->szInstance), DEVICE_NAME_FMT, iInstance); 1119 1078 pState->enmDevType = enmDevType; 1120 1079 … … 1151 1110 pState->pLedsConnector = (PPDMILEDCONNECTORS)pBase->pfnQueryInterface(pBase, PDMINTERFACE_LED_CONNECTORS); 1152 1111 1153 pState->nQueues = g_VPCIDevices[pState->enmDevType].nQueues;1112 pState->nQueues = DEVICE_N_QUEUES; 1154 1113 1155 1114 #if defined(VBOX_WITH_STATISTICS) … … 1440 1399 } 1441 1400 1442 #ifdef IN_RING31443 1401 /** 1444 1402 * Hardware reset. Revert all registers to initial values. … … 1458 1416 } 1459 1417 1418 #ifdef IN_RING3 1460 1419 /** 1461 1420 * Wakeup the RX thread. … … 1722 1681 return rc; 1723 1682 1683 STAM_PROFILE_ADV_START(&pState->StatReceive, a); 1724 1684 vpciSetReadLed(&pState->VPCI, true); 1725 1685 if (vnetAddressFilter(pState, pvBuf, cb)) … … 1729 1689 } 1730 1690 vpciSetReadLed(&pState->VPCI, false); 1691 STAM_PROFILE_ADV_STOP(&pState->StatReceive, a); 1731 1692 1732 1693 return rc; … … 1828 1789 else 1829 1790 { 1791 STAM_PROFILE_ADV_START(&pState->StatTransmit, a); 1830 1792 /* Assemble a complete frame. */ 1831 1793 for (unsigned int i = 1; i < elem.nOut && uOffset < VNET_MAX_FRAME_SIZE; i++) … … 1848 1810 vqueuePut(&pState->VPCI, pQueue, &elem, sizeof(VNETHDR) + uOffset); 1849 1811 vqueueSync(&pState->VPCI, pQueue); 1812 STAM_PROFILE_ADV_STOP(&pState->StatTransmit, a); 1850 1813 } 1851 1814 vpciSetWriteLed(&pState->VPCI, false);
Note:
See TracChangeset
for help on using the changeset viewer.