Exemple #1
0
        public void ReceiveFrame(EthernetFrame frame)
        {
            /*if(machine.ElapsedTime < TimeSpan.FromSeconds(30))
             * {
             *  return;
             * }*/
            lock (receiveLock)
            {
                if ((dmaStatus & ReceiveStatus) != 0)
                {
                    queue.Enqueue(frame);
                    return;
                }
                if (!packetSent)
                {
                    this.Log(LogLevel.Error, "Dropping - no packets sent.");
                    return;
                }
                if (frame.Bytes.Length < 14)
                {
                    this.Log(LogLevel.Error, "DROPPING - packet too short.");
                    return;
                }
                if (this.machine.IsPaused)
                {
                    this.Log(LogLevel.Debug, "DROPPING - cpu is halted.");
                    return;
                }
                var destinationMac = frame.DestinationMAC;
                if (!destinationMac.IsBroadcast && !destinationMac.Equals(MAC))
                {
                    this.Log(LogLevel.Debug, "DROPPING - not for us.");
                    return;
                }

                /*
                 * if((dmaInterruptEnable & (ReceiveStatus)) == 0)
                 * {
                 *  this.Log(LogLevel.Debug, "DROPPING - rx irq is turned off.");
                 *  return;
                 * }
                 */
                this.Log(LogLevel.Noisy, Misc.DumpPacket(frame, false, machine));
                if (dmaReceiveDescriptorListAddress < 0x20000000)
                {
                    // TODO: not in ram
                    this.Log(LogLevel.Error, "DROPPING - descriptor is not valid.");
                    return;
                }
                var written = 0;
                var first   = true;
                var bytes   = frame.Bytes;

                if (!EthernetFrame.CheckCRC(bytes))
                {
                    if (!(crcStrippingForTypeFrames && bytes.Length > 1536) || !(automaticPadCRCStripping && bytes.Length < 1500))
                    {
                        this.Log(LogLevel.Info, "Invalid CRC, packet discarded");
                        return;
                    }
                }

                var receiveDescriptor = new RxDescriptor(machine.SystemBus);
                receiveDescriptor.Fetch(dmaReceiveDescriptorListAddress);
                if (receiveDescriptor.IsUsed)
                {
                    this.Log(LogLevel.Error, "DROPPING  - descriptor is used.");
                    return;
                }
                this.Log(LogLevel.Noisy, "DESCRIPTOR ADDR1={0:X}, ADDR2={1:X}", receiveDescriptor.Address1, receiveDescriptor.Address2);
                while (!receiveDescriptor.IsUsed)
                {
                    if (receiveDescriptor.Address1 < 0x20000000)
                    {
                        this.Log(LogLevel.Error, "Descriptor points outside of ram, aborting... This should not happen!");
                        break;
                    }
                    receiveDescriptor.IsUsed  = true;
                    receiveDescriptor.IsFirst = first;
                    first = false;
                    var howManyBytes = Math.Min(receiveDescriptor.Buffer1Length, frame.Bytes.Length - written);
                    var toWriteArray = new byte[howManyBytes];

                    Array.Copy(bytes, written, toWriteArray, 0, howManyBytes);
                    machine.SystemBus.WriteBytes(toWriteArray, receiveDescriptor.Address1);
                    written += howManyBytes;
                    //write second buffer
                    if (frame.Bytes.Length - written > 0 && !receiveDescriptor.IsNextDescriptorChained)
                    {
                        howManyBytes = Math.Min(receiveDescriptor.Buffer2Length, frame.Bytes.Length - written);
                        toWriteArray = new byte[howManyBytes];
                        Array.Copy(bytes, written, toWriteArray, 0, howManyBytes);
                        machine.SystemBus.WriteBytes(toWriteArray, receiveDescriptor.Address2);
                        written += howManyBytes;
                    }
                    if (frame.Bytes.Length - written <= 0)
                    {
                        receiveDescriptor.IsLast = true;
                        this.NoisyLog("Setting descriptor length to {0}", (uint)frame.Bytes.Length);
                        receiveDescriptor.FrameLength = (uint)frame.Bytes.Length;
                    }
                    this.NoisyLog("Writing descriptor at 0x{6:X}, first={0}, last={1}, written {2} of {3}. next_chained={4}, endofring={5}", receiveDescriptor.IsFirst, receiveDescriptor.IsLast, written, frame.Bytes.Length, receiveDescriptor.IsNextDescriptorChained, receiveDescriptor.IsEndOfRing, dmaReceiveDescriptorListAddress);
                    receiveDescriptor.WriteBack();
                    if (!receiveDescriptor.IsNextDescriptorChained)
                    {
                        dmaReceiveDescriptorListAddress += 8;
                    }
                    else if (receiveDescriptor.IsEndOfRing)
                    {
                        dmaReceiveDescriptorListAddress = dmaReceiveDescriptorListAddressBegin;
                    }
                    else
                    {
                        dmaReceiveDescriptorListAddress = receiveDescriptor.Address2;
                    }
                    if (frame.Bytes.Length - written <= 0)
                    {
                        if ((dmaInterruptEnable & (ReceiveStatus)) != 0)// receive interrupt
                        {
                            dmaStatus |= ReceiveStatus;
                            IRQ.Set();
                        }
                        else
                        {
                            this.DebugLog("Exiting but not scheduling an interrupt!");
                        }
                        break;
                    }
                    receiveDescriptor.Fetch(dmaReceiveDescriptorListAddress);
                }
                this.DebugLog("Packet of length {0} delivered.", frame.Bytes.Length);
                if (written < frame.Bytes.Length)
                {
                    this.Log(LogLevel.Error, "Delivered only {0} from {1} bytes!", written, frame.Bytes.Length);
                }
            }
        }
Exemple #2
0
 private void ReceiveFrameInner(EthernetFrame frame)
 {
     /*if(machine.ElapsedTime < TimeSpan.FromSeconds(30))
     {
         return;
     }*/
     lock(receiveLock)
     {
         if((dmaStatus & ReceiveStatus) != 0)
         {
             queue.Enqueue(frame);
             return;
         }
         if(!packetSent)
         {
             this.Log(LogLevel.Error, "Dropping - no packets sent.");
             return;
         }
         if(frame.Length < 14)
         {
             this.Log(LogLevel.Error, "DROPPING - packet too short.");
             return;
         }
         if(this.machine.IsPaused)
         {
             this.Log(LogLevel.Debug, "DROPPING - cpu is halted.");
             return;
         }
         var destinationMac = frame.DestinationMAC.Value;
         if(!destinationMac.IsBroadcast && !destinationMac.Equals(MAC))
         {
             this.Log(LogLevel.Debug, "DROPPING - not for us.");
             return;
         }
         if((dmaInterruptEnable & (ReceiveStatus)) == 0)
         {
             this.Log(LogLevel.Debug, "DROPPING - rx irq is turned off.");
             return;
         }
         this.Log(LogLevel.Noisy, Misc.DumpPacket(frame, false, machine));
         if(dmaReceiveDescriptorListAddress < 0x20000000)
         {
             // TODO: not in ram
             this.Log(LogLevel.Error, "DROPPING - descriptor is not valid.");
             return;
         }
         var written = 0;
         var first = true;
         var receiveDescriptor = new RxDescriptor(machine.SystemBus);
         receiveDescriptor.Fetch(dmaReceiveDescriptorListAddress);
         if(receiveDescriptor.IsUsed)
         {
             this.Log(LogLevel.Error, "DROPPING  - descriptor is used.");
             return;
         }
         this.Log(LogLevel.Noisy, "DESCRIPTOR ADDR1={0:X}, ADDR2={1:X}", receiveDescriptor.Address1, receiveDescriptor.Address2);
         while(!receiveDescriptor.IsUsed)
         {
             if(receiveDescriptor.Address1 < 0x20000000)
             {
                 this.Log(LogLevel.Error, "Descriptor points outside of ram, aborting... This should not happen!");
                 break;
             }
             receiveDescriptor.IsUsed = true;
             receiveDescriptor.IsFirst = first;
             first = false;
             var howManyBytes = Math.Min(receiveDescriptor.Buffer1Length, frame.Length - written);
             var toWriteArray = new byte[howManyBytes];
             var bytes = frame.Bytes;
             Array.Copy(bytes, written, toWriteArray, 0, howManyBytes);
             machine.SystemBus.WriteBytes(toWriteArray, receiveDescriptor.Address1);
             written += howManyBytes;
             //write second buffer
             if(frame.Length - written > 0 && !receiveDescriptor.IsNextDescriptorChained)
             {
                 howManyBytes = Math.Min(receiveDescriptor.Buffer2Length, frame.Length - written);
                 toWriteArray = new byte[howManyBytes];
                 Array.Copy(bytes, written, toWriteArray, 0, howManyBytes);
                 machine.SystemBus.WriteBytes(toWriteArray, receiveDescriptor.Address2);
                 written += howManyBytes;
             }
             if(frame.Length - written <= 0)
             {
                 receiveDescriptor.IsLast = true;
                 this.NoisyLog("Setting descriptor length to {0}", (uint)frame.Length + 4);
                 receiveDescriptor.FrameLength = (uint)frame.Length + 4;
                 //with CRC
             }
             this.NoisyLog("Writing descriptor at 0x{6:X}, first={0}, last={1}, written {2} of {3}. next_chained={4}, endofring={5}", receiveDescriptor.IsFirst, receiveDescriptor.IsLast, written, frame.Length, receiveDescriptor.IsNextDescriptorChained, receiveDescriptor.IsEndOfRing, dmaReceiveDescriptorListAddress);
             receiveDescriptor.WriteBack();
             if(!receiveDescriptor.IsNextDescriptorChained)
             {
                 dmaReceiveDescriptorListAddress += 8;
             }
             else if(receiveDescriptor.IsEndOfRing)
             {
                 dmaReceiveDescriptorListAddress = dmaReceiveDescriptorListAddressBegin;
             }
             else
             {
                 dmaReceiveDescriptorListAddress = receiveDescriptor.Address2;
             }
             if(frame.Length - written <= 0)
             {
                 if((dmaInterruptEnable & (ReceiveStatus)) != 0)// receive interrupt
                 {
                     dmaStatus |= ReceiveStatus;
                     IRQ.Set();
                 }
                 else
                 {
                     this.DebugLog("Exiting but not scheduling an interrupt!");
                 }
                 break;
             }
             receiveDescriptor.Fetch(dmaReceiveDescriptorListAddress);
         }
         this.DebugLog("Packet of length {0} delivered.", frame.Length);
         if(written < frame.Length)
         {
             this.Log(LogLevel.Error, "Delivered only {0} from {1} bytes!", written, frame.Length);
         }
     }
 }