示例#1
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)
                    {
                        var frame = new EthernetFrame(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();
                    }
            
                }
            }
        }
示例#2
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();
                    }
                }
            }
        }