/verify/src/Checked/Drivers/Network/Intel/IntelTxRingBuffer.cs
C# | 150 lines | 89 code | 31 blank | 30 comment | 5 complexity | 0188271fa536d201f62edcf8e5cd83c1 MD5 | raw file
- ///////////////////////////////////////////////////////////////////////////////
- //
- // Microsoft Research Singularity
- //
- // Copyright (c) Microsoft Corporation. All rights reserved.
- //
- // Notes: Adaptor class for the Tx ring buffer.
- //
-
- using Microsoft.Contracts;
- using Microsoft.Singularity.Channels;
- using Microsoft.Singularity.Io;
- using Microsoft.Singularity.Io.Net;
- using Microsoft.Singularity.V1.Services;
- using Microsoft.SingSharp;
-
- using System;
- using ExRefPacketFifo = Microsoft.Singularity.NetStack2.Channels.Nic.ExRefPacketFifo;
- using ByteOrder = Drivers.Net.ByteOrder;
-
- namespace Microsoft.Singularity.Drivers.Network.Intel
- {
- internal class IntelTxRingBuffer
- {
- IntelRingBuffer txRingBuffer;
- ExRefPacketFifo txPacketsInDevice;
- internal System.Threading.MonitorLock thisLock = new System.Threading.MonitorLock();
-
- internal IntelTxRingBuffer(uint capacity)
- //requires capacity > 0 && IntelRingBuffer.IsPowerOf2(capacity);
- {
- this.txRingBuffer = new IntelRingBuffer(capacity);
- this.txPacketsInDevice = new ExRefPacketFifo(
- new PacketFifo((int) capacity),
- false
- );
- }
-
- internal void Reset()
- {
- txRingBuffer.Reset();
- }
-
- ///////////////////////////////////////////////////////////////////////
- //
- // Buffer Operations, should only be called when a lock is held
- // this ring buffer.
- //
- private void _LockedPushTsmtBuffer(Packet packet)
- {
- // (ARM only, not x86) PlatformService.CleanAndInvalidateDCache(packetVirtAddr, (UIntPtr)length);
- int length = packet.GetLength();
-
- ulong controlBits = (ulong) ByteOrder.HostToLittleEndian(length);
-
- // set necessary command fields
- controlBits |= (TxCmdFields.END_OF_PACKET | TxCmdFields.INSERT_FCS |
- TxCmdFields.REPORT_STATUS);
-
- DmaMemory mem = txRingBuffer.PeekHead();
- packet.CopyToBytes(mem.BytesRef());
- txRingBuffer.Push(controlBits);
- }
-
- internal void LockedPushTsmtBuffer(Packet packet)
- {
- DebugStub.Assert(packet.FragmentCount == 1);
- DebugStub.Assert(!txRingBuffer.IsFull);
-
- this._LockedPushTsmtBuffer(packet);
-
- PacketFifo liveFifo = this.txPacketsInDevice.Acquire();
- liveFifo.Push(packet);
- txPacketsInDevice.Release(liveFifo);
- }
-
- private Packet MakePacketFromDescriptor(ulong controlBits)
- {
- PacketFifo inDevPkts = txPacketsInDevice.Acquire();
- Packet packet = inDevPkts.Pop();
-
- // int length = (int) ((controlBits & TxDescriptor.LENGTH_MASK)
- // >> TxDescriptor.LENGTH_SHIFT);
- int stat_err = (int) ((controlBits & TxDescriptor.ERR_STAT_MASK)
- >> TxDescriptor.ERR_STAT_SHIFT);
-
-
- //DebugStub.Assert(packet.GetFragmentVirtualAddress(0) == fragmentVirtAddr);
-
- if (((TxStatErrFields.LATE_COLLISION |
- TxStatErrFields.EXCESS_COLLISIONS |
- TxStatErrFields.TRANSMIT_UNDERRUN) & stat_err) == 0) {
- packet.FromDeviceFlags = FromDeviceFlags.TransmitSuccess;
- } else {
- packet.FromDeviceFlags = FromDeviceFlags.TransmitError;
- }
-
- txPacketsInDevice.Release(inDevPkts);
-
- return packet;
- }
-
- internal void LockedDrainTsmtBuffer (PacketFifo toUser)
- {
- DmaMemory mem;
- ulong controlBits;
-
- while (txRingBuffer.Peek(out mem, out controlBits)) {
- Packet packet = MakePacketFromDescriptor(controlBits);
- toUser.Push(packet);
- txRingBuffer.Pop();
- }
- }
-
-
- ///////////////////////////////////////////////////////////////////////
- //
- // Ring buffer properties
- //
- internal UIntPtr BaseAddress
- {
- get { return txRingBuffer.BaseAddress; }
- }
-
- internal bool NewTransmitEvent() {
- return txRingBuffer.Peek();
- }
-
- //[Pure]
- internal uint Capacity { get { return txRingBuffer.Capacity; } }
-
- //[Pure]
- internal uint Free { get { return txRingBuffer.Free; } }
-
- //[Pure]
- internal bool IsFull { get { return txRingBuffer.IsFull; } }
-
- //[Pure]
- internal uint Count { get { return txRingBuffer.Count; } }
-
- //[Pure]
- internal uint Tail { get { return txRingBuffer.Tail; } }
-
- //[Pure]
- internal uint Head { get { return txRingBuffer.Head; } }
-
- //[Pure]
- internal uint DescLength { get { return txRingBuffer.DescLength; } }
- }
- }