private void SendFrames() { this.Log(LogLevel.Noisy, "Sending frame"); var transmitDescriptor = new TxDescriptor(machine.SystemBus); var packetData = new List <byte>(); transmitDescriptor.Fetch(dmaTransmitDescriptorListAddress); while (!transmitDescriptor.IsUsed) { transmitDescriptor.IsUsed = true; this.Log(LogLevel.Noisy, "GOING TO READ FROM {0:X}, len={1}", transmitDescriptor.Address1, transmitDescriptor.Buffer1Length); packetData.AddRange(machine.SystemBus.ReadBytes(transmitDescriptor.Address1, transmitDescriptor.Buffer1Length)); if (!transmitDescriptor.IsNextDescriptorChained) { packetData.AddRange(machine.SystemBus.ReadBytes(transmitDescriptor.Address2, transmitDescriptor.Buffer2Length)); } transmitDescriptor.WriteBack(); if (transmitDescriptor.IsEndOfRing) { dmaTransmitDescriptorListAddress = dmaTransmitDescriptorListAddressBegin; } else if (transmitDescriptor.IsNextDescriptorChained) { dmaTransmitDescriptorListAddress = transmitDescriptor.Address2; } else { dmaTransmitDescriptorListAddress += 8; } if (transmitDescriptor.IsLast) { this.Log(LogLevel.Noisy, "Sending frame of {0} bytes.", packetData.Count); if (Link.IsConnected) { var frame = EthernetFrame.CreateEthernetFrameWithoutCRC(packetData.ToArray()); if (transmitDescriptor.ChecksumInstertionControl > 0) { this.Log(LogLevel.Noisy, "Calculating checksum (mode {0}).", transmitDescriptor.ChecksumInstertionControl); if (transmitDescriptor.ChecksumInstertionControl == 1) { //IP only frame.FillWithChecksums(supportedEtherChecksums, null); } else { //IP and payload frame.FillWithChecksums(supportedEtherChecksums, supportedIPChecksums); } } this.Log(LogLevel.Debug, Misc.DumpPacket(frame, true, machine)); packetSent = true; //We recreate the EthernetFrame because the CRC should be appended after creating inner checksums. var frameWithCrc = EthernetFrame.CreateEthernetFrameWithCRC(frame.Bytes); Link.TransmitFrameFromInterface(frameWithCrc); } } transmitDescriptor.Fetch(dmaTransmitDescriptorListAddress); } //set TransmitBufferUnavailable dmaStatus |= TransmitBufferUnavailableStatus; if ((dmaInterruptEnable & (StartStopTransmission)) == 0) { IRQ.Set(); } this.Log(LogLevel.Noisy, "Frame sent."); }
private void SendFrames() { this.Log(LogLevel.Noisy, "Sending frame"); var transmitDescriptor = new TxDescriptor(machine.SystemBus); var packetData = new List <byte>(); transmitDescriptor.Fetch(dmaTransmitDescriptorListAddress); while (!transmitDescriptor.IsUsed) { transmitDescriptor.IsUsed = true; this.Log(LogLevel.Noisy, "GOING TO READ FROM {0:X}, len={1}", transmitDescriptor.Address1, transmitDescriptor.Buffer1Length); packetData.AddRange(machine.SystemBus.ReadBytes(transmitDescriptor.Address1, transmitDescriptor.Buffer1Length)); if (!transmitDescriptor.IsNextDescriptorChained) { packetData.AddRange(machine.SystemBus.ReadBytes(transmitDescriptor.Address2, transmitDescriptor.Buffer2Length)); } transmitDescriptor.WriteBack(); if (transmitDescriptor.IsEndOfRing) { dmaTransmitDescriptorListAddress = dmaTransmitDescriptorListAddressBegin; } else if (transmitDescriptor.IsNextDescriptorChained) { dmaTransmitDescriptorListAddress = transmitDescriptor.Address2; } else { dmaTransmitDescriptorListAddress += 8; } if (transmitDescriptor.IsLast) { this.Log(LogLevel.Noisy, "Sending frame of {0} bytes.", packetData.Count); if (!Misc.TryCreateFrameOrLogWarning(this, packetData.ToArray(), out var frame, addCrc: false)) { continue; } if (transmitDescriptor.ChecksumInstertionControl > 0) { this.Log(LogLevel.Noisy, "Calculating checksum (mode {0}).", transmitDescriptor.ChecksumInstertionControl); if (transmitDescriptor.ChecksumInstertionControl == 1) { //IP only frame.FillWithChecksums(supportedEtherChecksums, null); } else { //IP and payload frame.FillWithChecksums(supportedEtherChecksums, supportedIPChecksums); } } this.Log(LogLevel.Debug, Misc.DumpPacket(frame, true, machine)); packetSent = true; FrameReady?.Invoke(frame); } transmitDescriptor.Fetch(dmaTransmitDescriptorListAddress); } //set TransmitBufferUnavailable dmaStatus |= TransmitBufferUnavailableStatus; dmaStatus |= TransmitStatus; if ((dmaInterruptEnable & (StartStopTransmission)) == 0) { IRQ.Set(); } this.Log(LogLevel.Noisy, "Frame sent."); }
private void SendFrames() { this.Log(LogLevel.Noisy, "Sending frame"); var transmitDescriptor = new TxDescriptor(machine.SystemBus); var packetData = new List<byte>(); transmitDescriptor.Fetch(dmaTransmitDescriptorListAddress); while(!transmitDescriptor.IsUsed) { transmitDescriptor.IsUsed = true; this.Log(LogLevel.Noisy, "GOING TO READ FROM {0:X}, len={1}", transmitDescriptor.Address1, transmitDescriptor.Buffer1Length); packetData.AddRange(machine.SystemBus.ReadBytes(transmitDescriptor.Address1, transmitDescriptor.Buffer1Length)); if(!transmitDescriptor.IsNextDescriptorChained) { packetData.AddRange(machine.SystemBus.ReadBytes(transmitDescriptor.Address2, transmitDescriptor.Buffer2Length)); } transmitDescriptor.WriteBack(); if(transmitDescriptor.IsEndOfRing) { dmaTransmitDescriptorListAddress = dmaTransmitDescriptorListAddressBegin; } else if(transmitDescriptor.IsNextDescriptorChained) { dmaTransmitDescriptorListAddress = transmitDescriptor.Address2; } else { dmaTransmitDescriptorListAddress += 8; } if(transmitDescriptor.IsLast) { this.Log(LogLevel.Noisy, "Sending frame of {0} bytes.", packetData.Count); if(Link.IsConnected) { var frame = new EthernetFrame(packetData.ToArray()); if(transmitDescriptor.ChecksumInstertionControl > 0) { this.Log(LogLevel.Noisy, "Calculating checksum (mode {0}).", transmitDescriptor.ChecksumInstertionControl); if(transmitDescriptor.ChecksumInstertionControl == 1) { //IP only frame.FillWithChecksums(supportedEtherChecksums, null); } else { //IP and payload frame.FillWithChecksums(supportedEtherChecksums, supportedIPChecksums); } } this.Log(LogLevel.Debug, Misc.DumpPacket(frame, true, machine)); packetSent = true; Link.TransmitFrameFromInterface(frame); } } transmitDescriptor.Fetch(dmaTransmitDescriptorListAddress); } //set TransmitBufferUnavailable dmaStatus |= TransmitBufferUnavailableStatus; if((dmaInterruptEnable & (StartStopTransmission)) == 0) { IRQ.Set(); } this.Log(LogLevel.Noisy, "Frame sent."); }