PageRenderTime 53ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 0ms

/verify/src/Checked/Drivers/Network/Intel/IntelTxRingBuffer.cs

#
C# | 150 lines | 89 code | 31 blank | 30 comment | 5 complexity | 0188271fa536d201f62edcf8e5cd83c1 MD5 | raw file
  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Microsoft Research Singularity
  4. //
  5. // Copyright (c) Microsoft Corporation. All rights reserved.
  6. //
  7. // Notes: Adaptor class for the Tx ring buffer.
  8. //
  9. using Microsoft.Contracts;
  10. using Microsoft.Singularity.Channels;
  11. using Microsoft.Singularity.Io;
  12. using Microsoft.Singularity.Io.Net;
  13. using Microsoft.Singularity.V1.Services;
  14. using Microsoft.SingSharp;
  15. using System;
  16. using ExRefPacketFifo = Microsoft.Singularity.NetStack2.Channels.Nic.ExRefPacketFifo;
  17. using ByteOrder = Drivers.Net.ByteOrder;
  18. namespace Microsoft.Singularity.Drivers.Network.Intel
  19. {
  20. internal class IntelTxRingBuffer
  21. {
  22. IntelRingBuffer txRingBuffer;
  23. ExRefPacketFifo txPacketsInDevice;
  24. internal System.Threading.MonitorLock thisLock = new System.Threading.MonitorLock();
  25. internal IntelTxRingBuffer(uint capacity)
  26. //requires capacity > 0 && IntelRingBuffer.IsPowerOf2(capacity);
  27. {
  28. this.txRingBuffer = new IntelRingBuffer(capacity);
  29. this.txPacketsInDevice = new ExRefPacketFifo(
  30. new PacketFifo((int) capacity),
  31. false
  32. );
  33. }
  34. internal void Reset()
  35. {
  36. txRingBuffer.Reset();
  37. }
  38. ///////////////////////////////////////////////////////////////////////
  39. //
  40. // Buffer Operations, should only be called when a lock is held
  41. // this ring buffer.
  42. //
  43. private void _LockedPushTsmtBuffer(Packet packet)
  44. {
  45. // (ARM only, not x86) PlatformService.CleanAndInvalidateDCache(packetVirtAddr, (UIntPtr)length);
  46. int length = packet.GetLength();
  47. ulong controlBits = (ulong) ByteOrder.HostToLittleEndian(length);
  48. // set necessary command fields
  49. controlBits |= (TxCmdFields.END_OF_PACKET | TxCmdFields.INSERT_FCS |
  50. TxCmdFields.REPORT_STATUS);
  51. DmaMemory mem = txRingBuffer.PeekHead();
  52. packet.CopyToBytes(mem.BytesRef());
  53. txRingBuffer.Push(controlBits);
  54. }
  55. internal void LockedPushTsmtBuffer(Packet packet)
  56. {
  57. DebugStub.Assert(packet.FragmentCount == 1);
  58. DebugStub.Assert(!txRingBuffer.IsFull);
  59. this._LockedPushTsmtBuffer(packet);
  60. PacketFifo liveFifo = this.txPacketsInDevice.Acquire();
  61. liveFifo.Push(packet);
  62. txPacketsInDevice.Release(liveFifo);
  63. }
  64. private Packet MakePacketFromDescriptor(ulong controlBits)
  65. {
  66. PacketFifo inDevPkts = txPacketsInDevice.Acquire();
  67. Packet packet = inDevPkts.Pop();
  68. // int length = (int) ((controlBits & TxDescriptor.LENGTH_MASK)
  69. // >> TxDescriptor.LENGTH_SHIFT);
  70. int stat_err = (int) ((controlBits & TxDescriptor.ERR_STAT_MASK)
  71. >> TxDescriptor.ERR_STAT_SHIFT);
  72. //DebugStub.Assert(packet.GetFragmentVirtualAddress(0) == fragmentVirtAddr);
  73. if (((TxStatErrFields.LATE_COLLISION |
  74. TxStatErrFields.EXCESS_COLLISIONS |
  75. TxStatErrFields.TRANSMIT_UNDERRUN) & stat_err) == 0) {
  76. packet.FromDeviceFlags = FromDeviceFlags.TransmitSuccess;
  77. } else {
  78. packet.FromDeviceFlags = FromDeviceFlags.TransmitError;
  79. }
  80. txPacketsInDevice.Release(inDevPkts);
  81. return packet;
  82. }
  83. internal void LockedDrainTsmtBuffer (PacketFifo toUser)
  84. {
  85. DmaMemory mem;
  86. ulong controlBits;
  87. while (txRingBuffer.Peek(out mem, out controlBits)) {
  88. Packet packet = MakePacketFromDescriptor(controlBits);
  89. toUser.Push(packet);
  90. txRingBuffer.Pop();
  91. }
  92. }
  93. ///////////////////////////////////////////////////////////////////////
  94. //
  95. // Ring buffer properties
  96. //
  97. internal UIntPtr BaseAddress
  98. {
  99. get { return txRingBuffer.BaseAddress; }
  100. }
  101. internal bool NewTransmitEvent() {
  102. return txRingBuffer.Peek();
  103. }
  104. //[Pure]
  105. internal uint Capacity { get { return txRingBuffer.Capacity; } }
  106. //[Pure]
  107. internal uint Free { get { return txRingBuffer.Free; } }
  108. //[Pure]
  109. internal bool IsFull { get { return txRingBuffer.IsFull; } }
  110. //[Pure]
  111. internal uint Count { get { return txRingBuffer.Count; } }
  112. //[Pure]
  113. internal uint Tail { get { return txRingBuffer.Tail; } }
  114. //[Pure]
  115. internal uint Head { get { return txRingBuffer.Head; } }
  116. //[Pure]
  117. internal uint DescLength { get { return txRingBuffer.DescLength; } }
  118. }
  119. }