From 00c336c255ca94a1d52d927ad4ea3e105d0fb12c Mon Sep 17 00:00:00 2001 From: TomAwezome Date: Fri, 8 Jul 2022 04:49:34 -0400 Subject: [PATCH] Implement software loopback for PCNet driver. --- src/Home/Net/Drivers/PCNet.ZC | 14 +++++++++----- src/Home/Net/Protocols/ARP.ZC | 4 +++- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/Home/Net/Drivers/PCNet.ZC b/src/Home/Net/Drivers/PCNet.ZC index 65826a15..3cf9f465 100755 --- a/src/Home/Net/Drivers/PCNet.ZC +++ b/src/Home/Net/Drivers/PCNet.ZC @@ -501,12 +501,21 @@ I64 PCNetTransmitPacketAllocate(U8 **packet_buffer_out, I64 length) return de_index; } +U8 *EthernetMACGet() +{ + return pcnet.mac_address; +} + U0 PCNetTransmitPacketFinish(I64 de_index) {/* Release ownership of the packet to the PCNet card by setting the OWN bit to 1. */ CPCNetDescriptorEntry *entry = &pcnet.tx_de_buffer[de_index * sizeof(CPCNetDescriptorEntry)]; + // check the TX packet MAC against local MAC, if they match: software loopback the TX packet to RX NetQueue + if (!MemCompare(EthernetMACGet(), pcnet.tx_buffer_addr + de_index * ETHERNET_FRAME_SIZE, 6)) + NetQueuePush(pcnet.tx_buffer_addr + de_index * ETHERNET_FRAME_SIZE, U16_MAX - (entry->status1 & 0xFFFF) + 1); + Bts(&entry->status1, PCNET_DESCRIPTORf_OWN); NetLog("PCNET FINISH TX PACKET: TX DE index: %X, OWN bit of entry at entry: %b.", de_index, Bt(&entry->status1, PCNET_DESCRIPTORf_OWN)); @@ -742,11 +751,6 @@ I64 EthernetFrameAllocate(U8 **packet_buffer_out, return de_index; } -U8 *EthernetMACGet() -{ - return pcnet.mac_address; -} - U0 NetStop() { // Halt network activity by setting STOP bit on Status CSR. U32 csr = PCNetCSRRead(PCNET_CSR_CTRLSTATUS); diff --git a/src/Home/Net/Protocols/ARP.ZC b/src/Home/Net/Protocols/ARP.ZC index 1a80cfb7..347b470c 100755 --- a/src/Home/Net/Protocols/ARP.ZC +++ b/src/Home/Net/Protocols/ARP.ZC @@ -127,9 +127,11 @@ CARPHash *ARPCachePut(U32 ip_address, U8 *mac_address) } U0 ARPLocalIPV4Set(U32 ip_address) -{ // takes in little endian IP, stores into globals as Big Endian +{ // takes in little endian IP, stores into arp_globals as Big Endian and into ARP cache as Little Endian arp_globals.local_ipv4 = EndianU32(ip_address); + ARPCachePut(ip_address, EthernetMACGet); + ARPSend(ARP_REPLY, ethernet_globals.ethernet_broadcast, EthernetMACGet,