Example #1
0
        private void Finished()
        {
            if (mode == Mode.WaitingForPacket)
            {
                this.DebugLog("Packet received, LEN {7} {0:x} {1:x} {2:x} {3:x} (...) {4:x} {5:x} {6:x}", request[0], request[1], request[2], request[3], request[currentLength - 5], request[currentLength - 4], request[currentLength - 3], currentLength);
                var frame = new byte[currentLength];
                Array.Copy(request, 0, frame, 0, currentLength);
                //TODO: CRC handling
                var ethernetFrame = EthernetFrame.CreateEthernetFrameWithoutCRC(frame);
                Link.TransmitFrameFromInterface(ethernetFrame);
                mode              = Mode.Standard;
                currentLength     = 4;
                transmissionEnded = true;
                if (interruptAfterTransmision)
                {
                    SignalInterrupt();
                }
            }
            if (mode == Mode.SendingPacket)
            {
                mode          = Mode.Standard;
                currentLength = 4;
                lock (packetQueue)
                {
                    if (packetQueue.Count > 0)
                    {
                        SignalInterrupt();
                    }
                }
            }
            if (mode == Mode.Special)
            {
                currentLength = 4;
                mode          = Mode.Standard;
                return;
            }
            switch (lastPacketType)
            {
            case 0xC0:
                mode = Mode.WaitingForPacket;
                var encodedLength = request[3] + (request[4] << 8);
                this.DebugLog("Encoded length is 0x{0:X}.", encodedLength);
                currentLength     = Align(encodedLength + 1 + 1);
                transmissionEnded = false;
                break;

            case 0xF:
                lastPacketType = 0;
                break;
            }
        }
        private void SendSingleFrame(IEnumerable <byte> bytes, bool isCRCIncluded)
        {
            var frame = EthernetFrame.CreateEthernetFrameWithoutCRC(bytes.ToArray());

            if (!isCRCIncluded)
            {
                if (checksumGeneratorEnabled.Value)
                {
                    this.Log(LogLevel.Noisy, "Generating checksum for the frame");
                    frame.FillWithChecksums(new [] { EtherType.IpV4 }, new [] { IPProtocolType.TCP, IPProtocolType.UDP });
                }
                else
                {
                    this.Log(LogLevel.Warning, "The frame has no CRC, but the automatic checksum generation is disabled");
                }
            }

            this.Log(LogLevel.Noisy, "Sending packet, length {0}", frame.Bytes.Length);
            FrameReady?.Invoke(frame);
        }
        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.");
        }
Example #4
0
        private void SendFrames()
        {
            lock (sync)
            {
                txBufferDescriptor txBD = new txBufferDescriptor(machine.SystemBus);
                bool        interrupt   = false;
                List <byte> packet      = new List <byte>();


                txBD.Fetch(registers.TxQueueBaseAddr);

                while (!txBD.Used)
                {
                    while (!txBD.Last)
                    {
                        packet.AddRange(machine.SystemBus.ReadBytes(txBD.Word0, txBD.Length));
                        txBD.Used = true;
                        txBD.WriteBack();
                        if (txBD.Wrap)
                        {
                            registers.TxQueueBaseAddr = txBufferBase;
                        }
                        else
                        {
                            registers.TxQueueBaseAddr += 8;
                        }
                        txBD.Fetch(registers.TxQueueBaseAddr);
                    }
                    interrupt = false;
                    txBD.Used = true;

                    packet.AddRange(machine.SystemBus.ReadBytes(txBD.Word0, txBD.Length));

                    if ((registers.DMAConfig & 1u << 11) != 0) //if checksum offload enable
                    {
                        if ((packet[14] & 0xF0) == 0x40)       //IP packet
                        {
                            ushort cksum;
                            IPHeaderLength = (ushort)((packet[14] & 0x0F) * 4);
                            if (packet[23] == 0x06) // TCP packet
                            {
                                IPpacket tcpPacket = new IPpacket(IPHeaderLength, IPpacket.PacketType.TCP);
                                tcpPacket.ReadFromBuffer(packet.ToArray());
                                cksum  = tcpPacket.GetChecksum();
                                cksum -= 1;
                                packet[MACHeaderLegth + IPHeaderLength + 16] = (byte)((cksum >> 8) & 0xFF);
                                packet[MACHeaderLegth + IPHeaderLength + 17] = (byte)((cksum) & 0xFF);
                            }
                            else if (packet[23] == 0x11) // UDP packet
                            {
                                IPpacket udpPacket = new IPpacket(IPHeaderLength, IPpacket.PacketType.UDP);
                                udpPacket.ReadFromBuffer(packet.ToArray());
                                cksum  = udpPacket.GetChecksum();
                                cksum -= 1;
                                packet[MACHeaderLegth + IPHeaderLength + 6] = (byte)((cksum >> 8) & 0xFF);
                                packet[MACHeaderLegth + IPHeaderLength + 7] = (byte)((cksum) & 0xFF);
                            }
                        }
                    }

                    if (Link.IsConnected)
                    {
                        EthernetFrame frame;

                        if (!txBD.NoCRC)
                        {
                            frame = EthernetFrame.CreateEthernetFrameWithCRC(packet.ToArray());
                        }
                        else
                        {
                            frame = EthernetFrame.CreateEthernetFrameWithoutCRC(packet.ToArray());
                        }

                        this.Log(LogLevel.Noisy, "Sending packet length {0}", packet.ToArray().Length);
                        Link.TransmitFrameFromInterface(frame);
                    }

                    txBD.WriteBack();

                    if (txBD.Wrap)
                    {
                        registers.TxQueueBaseAddr = txBufferBase;
                    }
                    else
                    {
                        registers.TxQueueBaseAddr += 8;
                    }

                    registers.TxStatus |= 1u << 5; //tx complete
                    txBD.Fetch(registers.TxQueueBaseAddr);

                    if (txBD.Used)
                    {
                        registers.TxStatus |= 0x01;
                        if ((registers.InterruptMask & (1u << 3)) == 0)
                        {
                            registers.InterruptStatus |= 1u << 3;
                            interrupt = true;
                        }
                    }

                    if ((registers.InterruptMask & (1u << 7)) == 0)
                    {
                        registers.InterruptStatus |= 1u << 7;
                        interrupt = true;
                    }

                    if (interrupt)
                    {
                        IRQ.Set();
                    }
                }
            }
        }