1 //
2 // Copyright (c) 2010-2025 Antmicro
3 //
4 //  This file is licensed under the MIT License.
5 //  Full license text is available in 'licenses/MIT.txt'.
6 //
7 using System;
8 using Antmicro.Renode.Core.Structure.Registers;
9 using Antmicro.Renode.Logging;
10 using Antmicro.Renode.Network;
11 using Antmicro.Renode.Peripherals.Bus;
12 using Antmicro.Renode.Peripherals.CPU;
13 using Antmicro.Renode.Utilities.Packets;
14 
15 namespace Antmicro.Renode.Peripherals.Network
16 {
17     public partial class SynopsysDWCEthernetQualityOfService
18     {
19         private abstract class Descriptor
20         {
Descriptor(IBusController bus, ulong address, ICPU cpuContext = null)21             public Descriptor(IBusController bus, ulong address, ICPU cpuContext = null)
22             {
23                 this.bus = bus;
24                 this.cpuContext = cpuContext;
25                 Address = address;
26                 this.data = new byte[Size];
27             }
28 
Fetch()29             public virtual void Fetch()
30             {
31                 bus.ReadBytes(Address, (int)Size, data, 0, true, cpuContext);
32                 var structure = Packet.Decode<MinimalCommonDescriptor>(data);
33                 UpdateProperties(structure);
34             }
35 
Write()36             public void Write()
37             {
38                 bus.WriteBytes(data, Address, context: cpuContext);
39             }
40 
41             public void SetDescriptor<T>(T structure) where T : IDescriptorStruct
42             {
43                 type = typeof(T);
44                 data = Packet.Encode<T>(structure);
45                 UpdateProperties(structure);
46             }
47 
UpdateProperties(IDescriptorStruct structure)48             protected void UpdateProperties(IDescriptorStruct structure)
49             {
50                 IsOwnedByDMA = structure.Owner == DescriptorOwner.DMA;
51                 isContextDescriptor = structure.ContextType;
52             }
53 
54             public Type Type => type;
55             public ulong Address { get; }
56             public bool? IsOwnedByDMA { get; protected set; }
57             public static uint Size => 0x10;
58 
59             protected bool? isContextDescriptor;
60             protected Type type;
61             protected byte[] data;
62 
63             private readonly IBusController bus;
64             private readonly ICPU cpuContext;
65 
66             public interface IDescriptorStruct
67             {
68                 bool ContextType { get; }
69                 DescriptorOwner Owner { get; }
70             }
71 
72             [LeastSignificantByteFirst]
73             private struct MinimalCommonDescriptor : IDescriptorStruct
74             {
75                 public bool ContextType => contextType;
76                 public DescriptorOwner Owner => owner;
77 
78 #pragma warning disable 649
79                 [PacketField, Offset(doubleWords: 3, bits: 30), Width(1)] // CTXT
80                 public bool contextType;
81                 [PacketField, Offset(doubleWords: 3, bits: 31), Width(1)] // OWN
82                 public DescriptorOwner owner;
83 #pragma warning restore 649
84             }
85         }
86 
87         private class RxDescriptor : Descriptor
88         {
RxDescriptor(IBusController bus, ulong address, ICPU cpuContext = null)89             public RxDescriptor(IBusController bus, ulong address, ICPU cpuContext = null) : base(bus, address, cpuContext)
90             {
91             }
92 
Fetch()93             public override void Fetch()
94             {
95                 base.Fetch();
96                 type = typeof(NormalReadDescriptor);
97             }
98 
GetNormalReadDescriptor()99             public NormalReadDescriptor GetNormalReadDescriptor()
100             {
101                 return Packet.Decode<NormalReadDescriptor>(data);
102             }
103 
GetAsNormalWriteBackDescriptor()104             public NormalWriteBackDescriptor GetAsNormalWriteBackDescriptor()
105             {
106                 return Packet.Decode<NormalWriteBackDescriptor>(data);
107             }
108 
GetAsContextDescriptor()109             public ContextDescriptor GetAsContextDescriptor()
110             {
111                 return Packet.Decode<ContextDescriptor>(data);
112             }
113 
114             [LeastSignificantByteFirst]
115             public struct NormalReadDescriptor : IDescriptorStruct
116             {
ToStringAntmicro.Renode.Peripherals.Network.SynopsysDWCEthernetQualityOfService.RxDescriptor.NormalReadDescriptor117                 public override string ToString()
118                 {
119                     return PrettyString;
120                 }
121 
122                 public string PrettyString => $@"NormalReadRxDescriptor {{
123     buffer1Address: 0x{buffer1Address:X},
124     buffer2Address: 0x{buffer2Address:X},
125     buffer1AddressValid: {buffer1AddressValid},
126     buffer2AddressValid: {buffer2AddressValid},
127     interruptOnCompletion: {interruptOnCompletion},
128     owner: {owner}
129 }}";
130                 public bool ContextType => false;
131                 public DescriptorOwner Owner => owner;
132 
133 #pragma warning disable 649
134                 [PacketField, Offset(doubleWords: 0, bits: 0), Width(32)] // BUF1AP
135                 public uint buffer1Address;
136                 // 2nd double word is reserved
137                 [PacketField, Offset(doubleWords: 2, bits: 0), Width(32)] // BUF2AP
138                 public uint buffer2Address;
139                 // bits 0:23 of 4th double word are reserved
140                 [PacketField, Offset(doubleWords: 3, bits: 24), Width(1)] // BUF1V
141                 public bool buffer1AddressValid;
142                 [PacketField, Offset(doubleWords: 3, bits: 25), Width(1)] // BUF2V
143                 public bool buffer2AddressValid;
144                 // bits 26:29 of 4th double word are reserved
145                 [PacketField, Offset(doubleWords: 3, bits: 30), Width(1)] // IOC
146                 public bool interruptOnCompletion;
147                 [PacketField, Offset(doubleWords: 3, bits: 31), Width(1)] // OWN
148                 public DescriptorOwner owner;
149 #pragma warning restore 649
150             }
151 
152             [LeastSignificantByteFirst]
153             public struct NormalWriteBackDescriptor : IDescriptorStruct
154             {
ToStringAntmicro.Renode.Peripherals.Network.SynopsysDWCEthernetQualityOfService.RxDescriptor.NormalWriteBackDescriptor155                 public override string ToString()
156                 {
157                     return PrettyString;
158                 }
159 
160                 public string PrettyString => $@"NormalWriteBackRxDescriptor {{
161     outerVlanTag: 0x{outerVlanTag:X},
162     innerVlanTag: 0x{innerVlanTag:X},
163     payloadType: {payloadType},
164     ipHeaderError: {ipHeaderError},
165     ipv4HeaderPresent: {ipv4HeaderPresent},
166     ipv6HeaderPresent: {ipv6HeaderPresent},
167     ipChecksumBypassed: {ipChecksumBypassed},
168     ipPayloadError: {ipPayloadError},
169     ptpMessageType: {ptpMessageType},
170     ptpPacketType: {ptpPacketType},
171     ptpVersion: {ptpVersion},
172     timestampAvailable: {timestampAvailable},
173     timestampDropped: {timestampDropped},
174     oamSubtypeCodeOrMACControlPacketOpcode: 0x{oamSubtypeCodeOrMACControlPacketOpcode:X} or {(EtherType)oamSubtypeCodeOrMACControlPacketOpcode},
175     arpReplyNotGenerated: {arpReplyNotGenerated},
176     vlanFiletrStatus: {vlanFiletrStatus},
177     sourceAddressFilterFail: {sourceAddressFilterFail},
178     destinaltionAddressFilterFail: {destinaltionAddressFilterFail},
179     hashFilterStatus: {hashFilterStatus},
180     macAddressMatchOrHashValue: {macAddressMatchOrHashValue},
181     layer3FilterMatch: {layer3FilterMatch},
182     layer4FilterMatch: {layer4FilterMatch},
183     matchedFilterNumber: {matchedFilterNumber},
184     packetLength: {packetLength},
185     errorSummary: {errorSummary},
186     lengthTypeField: {lengthTypeField},
187     dribbleBitError: {dribbleBitError},
188     receiveError: {receiveError},
189     overflowError: {overflowError},
190     receiveWatchdogTimeout: {receiveWatchdogTimeout},
191     giantPacket: {giantPacket},
192     crcError: {crcError},
193     receiveStatusSegment0Valid: {receiveStatusSegment0Valid},
194     receiveStatusSegment1Valid: {receiveStatusSegment1Valid},
195     receiveStatusSegment2Valid: {receiveStatusSegment2Valid},
196     lastDescriptor: {lastDescriptor},
197     firstDescriptor: {firstDescriptor},
198     contextType: {contextType},
199     owner: {owner}
200 }}";
201                 public bool ContextType => contextType;
202                 public DescriptorOwner Owner => owner;
203 
204 #pragma warning disable 649
205                 [PacketField, Offset(doubleWords: 0, bits: 0), Width(16)] // OVT
206                 public uint outerVlanTag;
207                 [PacketField, Offset(doubleWords: 0, bits: 16), Width(16)] // IVT
208                 public uint innerVlanTag;
209                 [PacketField, Offset(doubleWords: 1, bits: 0), Width(3)] // PT
210                 public PayloadType payloadType;
211                 [PacketField, Offset(doubleWords: 1, bits: 3), Width(1)] // IPHE
212                 public bool ipHeaderError;
213                 [PacketField, Offset(doubleWords: 1, bits: 4), Width(1)] // IPV4
214                 public bool ipv4HeaderPresent;
215                 [PacketField, Offset(doubleWords: 1, bits: 5), Width(1)] // IPV6
216                 public bool ipv6HeaderPresent;
217                 [PacketField, Offset(doubleWords: 1, bits: 6), Width(1)] // IPCB
218                 public bool ipChecksumBypassed;
219                 [PacketField, Offset(doubleWords: 1, bits: 7), Width(1)] // IPCE
220                 public bool ipPayloadError;
221                 [PacketField, Offset(doubleWords: 1, bits: 8), Width(4)] // PMT
222                 public PTPMessageType ptpMessageType;
223                 [PacketField, Offset(doubleWords: 1, bits: 12), Width(1)] // PFT
224                 public bool ptpPacketType;
225                 [PacketField, Offset(doubleWords: 1, bits: 13), Width(1)] // PV
226                 public PTPVersion ptpVersion;
227                 [PacketField, Offset(doubleWords: 1, bits: 14), Width(1)] // TSA
228                 public bool timestampAvailable;
229                 [PacketField, Offset(doubleWords: 1, bits: 15), Width(1)] // TD
230                 public bool timestampDropped;
231                 [PacketField, Offset(doubleWords: 1, bits: 16), Width(16)] // OPC
232                 public uint oamSubtypeCodeOrMACControlPacketOpcode;
233                 // bits 0:9 of 3rd double word are reserved
234                 [PacketField, Offset(doubleWords: 2, bits: 10), Width(1)] // ARPNR
235                 public bool arpReplyNotGenerated;
236                 // bits 11:14 of 3rd double word are reserved
237                 [PacketField, Offset(doubleWords: 2, bits: 15), Width(1)] // VF
238                 public bool vlanFiletrStatus;
239                 [PacketField, Offset(doubleWords: 2, bits: 16), Width(1)] // SAF
240                 public bool sourceAddressFilterFail;
241                 [PacketField, Offset(doubleWords: 2, bits: 17), Width(1)] // DAF
242                 public bool destinaltionAddressFilterFail;
243                 [PacketField, Offset(doubleWords: 2, bits: 18), Width(1)] // HF
244                 public bool hashFilterStatus;
245                 [PacketField, Offset(doubleWords: 2, bits: 19), Width(8)] // MADRM
246                 public bool macAddressMatchOrHashValue;
247                 [PacketField, Offset(doubleWords: 2, bits: 27), Width(1)] // L3FM
248                 public bool layer3FilterMatch;
249                 [PacketField, Offset(doubleWords: 2, bits: 28), Width(1)] // L4FM
250                 public bool layer4FilterMatch;
251                 [PacketField, Offset(doubleWords: 2, bits: 29), Width(3)] // L3L4FM
252                 public uint matchedFilterNumber;
253                 [PacketField, Offset(doubleWords: 3, bits: 0), Width(15)] // PL
254                 public uint packetLength;
255                 [PacketField, Offset(doubleWords: 3, bits: 15), Width(1)] // ES
256                 public bool errorSummary;
257                 [PacketField, Offset(doubleWords: 3, bits: 16), Width(3)] // LT
258                 public PacketKind lengthTypeField;
259                 [PacketField, Offset(doubleWords: 3, bits: 19), Width(1)] // DE
260                 public bool dribbleBitError;
261                 [PacketField, Offset(doubleWords: 3, bits: 20), Width(1)] // RE
262                 public bool receiveError;
263                 [PacketField, Offset(doubleWords: 3, bits: 21), Width(1)] // OE
264                 public bool overflowError;
265                 [PacketField, Offset(doubleWords: 3, bits: 22), Width(1)] // RWT
266                 public bool receiveWatchdogTimeout;
267                 [PacketField, Offset(doubleWords: 3, bits: 23), Width(1)] // GP
268                 public bool giantPacket;
269                 [PacketField, Offset(doubleWords: 3, bits: 24), Width(1)] // CE
270                 public bool crcError;
271                 [PacketField, Offset(doubleWords: 3, bits: 25), Width(1)] // RS0V
272                 public bool receiveStatusSegment0Valid;
273                 [PacketField, Offset(doubleWords: 3, bits: 26), Width(1)] // RS1V
274                 public bool receiveStatusSegment1Valid;
275                 [PacketField, Offset(doubleWords: 3, bits: 27), Width(1)] // RS2V
276                 public bool receiveStatusSegment2Valid;
277                 [PacketField, Offset(doubleWords: 3, bits: 28), Width(1)] // LD
278                 public bool lastDescriptor;
279                 [PacketField, Offset(doubleWords: 3, bits: 29), Width(1)] // FD
280                 public bool firstDescriptor;
281                 [PacketField, Offset(doubleWords: 3, bits: 30), Width(1)] // CTXT
282                 public bool contextType;
283                 [PacketField, Offset(doubleWords: 3, bits: 31), Width(1)] // OWN
284                 public DescriptorOwner owner;
285 #pragma warning restore 649
286             }
287 
288             [LeastSignificantByteFirst]
289             public struct ContextDescriptor : IDescriptorStruct
290             {
ToStringAntmicro.Renode.Peripherals.Network.SynopsysDWCEthernetQualityOfService.RxDescriptor.ContextDescriptor291                 public override string ToString()
292                 {
293                     return PrettyString;
294                 }
295 
296                 public string PrettyString => $@"ContextRxDescriptor {{
297     receivePacketTimestamp: 0x{receivePacketTimestamp:X},
298     contextType: {contextType},
299     owner: {owner}
300 }}";
301                 public bool ContextType => contextType;
302                 public DescriptorOwner Owner => owner;
303 
304 #pragma warning disable 649
305                 [PacketField, Offset(quadWords: 0), Width(64)] // RTS
306                 public ulong receivePacketTimestamp;
307                 // 3nd double word and bits 0:29 of 4th double word are reserved
308                 [PacketField, Offset(doubleWords: 3, bits: 30), Width(1)] // CTXT
309                 public bool contextType;
310                 [PacketField, Offset(doubleWords: 3, bits: 31), Width(1)] // OWN
311                 public DescriptorOwner owner;
312 #pragma warning restore 649
313             }
314         }
315 
316         private class TxDescriptor : Descriptor
317         {
TxDescriptor(IBusController bus, ulong address, ICPU cpuContext = null)318             public TxDescriptor(IBusController bus, ulong address, ICPU cpuContext = null) : base(bus, address, cpuContext)
319             {
320             }
321 
Fetch()322             public override void Fetch()
323             {
324                 base.Fetch();
325                 type = isContextDescriptor.Value ? typeof(ContextDescriptor) : typeof(NormalReadDescriptor);
326             }
327 
GetNormalReadDescriptor()328             public NormalReadDescriptor GetNormalReadDescriptor()
329             {
330                 return Packet.Decode<NormalReadDescriptor>(data);
331             }
332 
GetContextDescriptor()333             public ContextDescriptor GetContextDescriptor()
334             {
335                 return Packet.Decode<ContextDescriptor>(data);
336             }
337 
338             [LeastSignificantByteFirst]
339             public struct NormalReadDescriptor : IDescriptorStruct
340             {
ToStringAntmicro.Renode.Peripherals.Network.SynopsysDWCEthernetQualityOfService.TxDescriptor.NormalReadDescriptor341                 public override string ToString()
342                 {
343                     return PrettyString;
344                 }
345 
FetchBuffer1OrHeaderAntmicro.Renode.Peripherals.Network.SynopsysDWCEthernetQualityOfService.TxDescriptor.NormalReadDescriptor346                 public byte[] FetchBuffer1OrHeader(IBusController bus, ICPU cpuContext = null)
347                 {
348                     var data = new byte[headerOrBuffer1Length];
349                     bus.ReadBytes((ulong)buffer1OrHeaderAddress, (int)headerOrBuffer1Length, data, 0, true, cpuContext);
350                     return data;
351                 }
352 
FetchBuffer2OrBuffer1Antmicro.Renode.Peripherals.Network.SynopsysDWCEthernetQualityOfService.TxDescriptor.NormalReadDescriptor353                 public byte[] FetchBuffer2OrBuffer1(IBusController bus, ICPU cpuContext = null)
354                 {
355                     var data = new byte[buffer2Length];
356                     bus.ReadBytes((ulong)buffer2orBuffer1Address, (int)buffer2Length, data, 0, true, cpuContext);
357                     return data;
358                 }
359 
360                 public uint PayloadLength
361                 {
362                     get
363                     {
364                         return payloadLengthLower15bits | payloadLength15bit << 15 | (uint)checksumControl << 16;
365                     }
366                 }
367 
368                 public string PrettyString => $@"NormalReadTxDescriptor {{
369     buffer1OrHeaderAddress: 0x{buffer1OrHeaderAddress:X},
370     buffer2orBuffer1Address: 0x{buffer2orBuffer1Address:X},
371     headerOrBuffer1Length: 0x{headerOrBuffer1Length:X},
372     vlanTagControl: {vlanTagControl},
373     buffer2Length: 0x{buffer2Length:X},
374     transmitTimestampEnable: {transmitTimestampEnable},
375     interruptOnCompletion: {interruptOnCompletion},
376     payloadLengthLower15bits: {payloadLengthLower15bits},
377     payloadLength15bit: {payloadLength15bit},
378     checksumControl: {checksumControl},
379     tcpSegmentationEnable: {tcpSegmentationEnable},
380     headerLength: {headerLength},
381     sourceAddressControl: {sourceAddressControl},
382     crcPadControl: {crcPadControl},
383     lastDescriptor: {lastDescriptor},
384     firstDescriptor: {firstDescriptor},
385     contextType: {contextType},
386     owner: {owner}
387 }}";
388                 public bool ContextType => contextType;
389                 public DescriptorOwner Owner => owner;
390 
391 #pragma warning disable 649
392                 [PacketField, Offset(doubleWords: 0, bits: 0), Width(32)] // BUF1AP
393                 public uint buffer1OrHeaderAddress;
394                 [PacketField, Offset(doubleWords: 1, bits: 0), Width(32)] // BUF2AP
395                 public uint buffer2orBuffer1Address;
396                 [PacketField, Offset(doubleWords: 2, bits: 0), Width(14)] // HR/B1L
397                 public uint headerOrBuffer1Length;
398                 [PacketField, Offset(doubleWords: 2, bits: 14), Width(2)] // VTIR
399                 public VLANTagOperation vlanTagControl;
400                 [PacketField, Offset(doubleWords: 2, bits: 16), Width(14)] // B2L
401                 public uint buffer2Length;
402                 [PacketField, Offset(doubleWords: 2, bits: 30), Width(1)] // TTSE
403                 public bool transmitTimestampEnable;
404                 [PacketField, Offset(doubleWords: 2, bits: 31), Width(1)] // IOC
405                 public bool interruptOnCompletion;
406                 [PacketField, Offset(doubleWords: 3, bits: 0), Width(15)] // FL/TPL
407                 public uint payloadLengthLower15bits;
408                 [PacketField, Offset(doubleWords: 3, bits: 15), Width(1)] // TPL
409                 public uint payloadLength15bit;
410                 [PacketField, Offset(doubleWords: 3, bits: 16), Width(2)] // CIC/TPL
411                 public ChecksumOperation checksumControl;
412                 [PacketField, Offset(doubleWords: 3, bits: 18), Width(1)] // TSE
413                 public bool tcpSegmentationEnable;
414                 [PacketField, Offset(doubleWords: 3, bits: 19), Width(4)] // THL
415                 public uint headerLength;
416                 [PacketField, Offset(doubleWords: 3, bits: 23), Width(3)] // SAIC
417                 public DescriptorSourceAddressOperation sourceAddressControl;
418                 [PacketField, Offset(doubleWords: 3, bits: 26), Width(2)] // CPC
419                 public CRCPadOperation crcPadControl;
420                 [PacketField, Offset(doubleWords: 3, bits: 28), Width(1)] // LD
421                 public bool lastDescriptor;
422                 [PacketField, Offset(doubleWords: 3, bits: 29), Width(1)] // FD
423                 public bool firstDescriptor;
424                 [PacketField, Offset(doubleWords: 3, bits: 30), Width(1)] // CTXT
425                 public bool contextType;
426                 [PacketField, Offset(doubleWords: 3, bits: 31), Width(1)] // OWN
427                 public DescriptorOwner owner;
428 #pragma warning restore 649
429             }
430 
431             [LeastSignificantByteFirst]
432             public struct NormalWriteBackDescriptor : IDescriptorStruct
433             {
ToStringAntmicro.Renode.Peripherals.Network.SynopsysDWCEthernetQualityOfService.TxDescriptor.NormalWriteBackDescriptor434                 public override string ToString()
435                 {
436                     return PrettyString;
437                 }
438 
439                 public string PrettyString => $@"NormalWriteBackTxDescriptor {{
440     txPacketTimestamp: 0x{txPacketTimestamp:X},
441     ipHeaderError: {ipHeaderError},
442     deferredBit: {deferredBit},
443     underflowError: {underflowError},
444     excessiveDeferral: {excessiveDeferral},
445     collisionCount: {collisionCount},
446     excessiveCollision: {excessiveCollision},
447     lateCollision: {lateCollision},
448     noCarrier: {noCarrier},
449     lossOfCarrier: {lossOfCarrier},
450     payloadChecksumError: {payloadChecksumError},
451     packetFlushed: {packetFlushed},
452     jabberTimeout: {jabberTimeout},
453     errorSummary: {errorSummary},
454     txTimestampCaptured: {txTimestampCaptured},
455     lastDescriptor: {lastDescriptor},
456     firstDescriptor: {firstDescriptor},
457     contextType: {contextType},
458     owner: {owner}
459 }}";
460                 public bool ContextType => contextType;
461                 public DescriptorOwner Owner => owner;
462 
463 #pragma warning disable 649
464                 [PacketField, Offset(quadWords: 0), Width(64)] // TTS
465                 public ulong txPacketTimestamp;
466                 // 3nd double word is reserved
467                 [PacketField, Offset(doubleWords: 3, bits: 0), Width(1)] // IHE
468                 public bool ipHeaderError;
469                 [PacketField, Offset(doubleWords: 3, bits: 1), Width(1)] // DB
470                 public bool deferredBit;
471                 [PacketField, Offset(doubleWords: 3, bits: 2), Width(1)] // UF
472                 public bool underflowError;
473                 [PacketField, Offset(doubleWords: 3, bits: 3), Width(1)] // ED
474                 public bool excessiveDeferral;
475                 [PacketField, Offset(doubleWords: 3, bits: 4), Width(4)] // CC
476                 public bool collisionCount;
477                 [PacketField, Offset(doubleWords: 3, bits: 8), Width(1)] // EC
478                 public bool excessiveCollision;
479                 [PacketField, Offset(doubleWords: 3, bits: 9), Width(1)] // LC
480                 public bool lateCollision;
481                 [PacketField, Offset(doubleWords: 3, bits: 10), Width(1)] // NC
482                 public bool noCarrier;
483                 [PacketField, Offset(doubleWords: 3, bits: 11), Width(1)] // LoC
484                 public bool lossOfCarrier;
485                 [PacketField, Offset(doubleWords: 3, bits: 12), Width(1)] // PCE
486                 public bool payloadChecksumError;
487                 [PacketField, Offset(doubleWords: 3, bits: 13), Width(1)] // FF
488                 public bool packetFlushed;
489                 [PacketField, Offset(doubleWords: 3, bits: 14), Width(1)] // JT
490                 public bool jabberTimeout;
491                 [PacketField, Offset(doubleWords: 3, bits: 15), Width(1)] // ES
492                 public bool errorSummary;
493                 // bit 16 of 4th double word is reserved
494                 [PacketField, Offset(doubleWords: 3, bits: 17), Width(1)] // TTSS
495                 public bool txTimestampCaptured;
496                 // bits 18:27 of 4th double word are reserved
497                 [PacketField, Offset(doubleWords: 3, bits: 28), Width(1)] // LD
498                 public bool lastDescriptor;
499                 [PacketField, Offset(doubleWords: 3, bits: 29), Width(1)] // FD
500                 public bool firstDescriptor;
501                 [PacketField, Offset(doubleWords: 3, bits: 30), Width(1)] // CTXT
502                 public bool contextType;
503                 [PacketField, Offset(doubleWords: 3, bits: 31), Width(1)] // OWN
504                 public DescriptorOwner owner;
505 #pragma warning restore 649
506             }
507 
508             [LeastSignificantByteFirst]
509             public struct ContextDescriptor : IDescriptorStruct
510             {
ToStringAntmicro.Renode.Peripherals.Network.SynopsysDWCEthernetQualityOfService.TxDescriptor.ContextDescriptor511                 public override string ToString()
512                 {
513                     return PrettyString;
514                 }
515 
516                 public string PrettyString => $@"ContextTxDescriptor {{
517     txPacketTimestamp: {txPacketTimestamp},
518     maximumSegmentSize: {maximumSegmentSize},
519     innerVlanTag: {innerVlanTag},
520     vlanTag: {vlanTag},
521     vlanTagValid: {vlanTagValid},
522     innerVlanTagValid: {innerVlanTagValid},
523     innerVlanTagControl: {innerVlanTagControl},
524     contextDescriptorError: {contextDescriptorError},
525     oneStepTimestampCorrectionInputOrMaximumSegmentSizeValid: {oneStepTimestampCorrectionInputOrMaximumSegmentSizeValid},
526     oneStepTimestampCorrectionEnable: {oneStepTimestampCorrectionEnable},
527     contextType: {contextType},
528     owner: {owner}
529 }}";
530                 public bool ContextType => contextType;
531                 public DescriptorOwner Owner => owner;
532 
533 #pragma warning disable 649
534                 [PacketField, Offset(quadWords: 0), Width(64)] // TTS
535                 public ulong txPacketTimestamp;
536                 [PacketField, Offset(doubleWords: 2, bits: 0), Width(14)] // MSS
537                 public uint maximumSegmentSize;
538                 // bits 14:15 of 3rd double word are reserved
539                 [PacketField, Offset(doubleWords: 2, bits: 16), Width(16)] // IVT
540                 public uint innerVlanTag;
541                 [PacketField, Offset(doubleWords: 3, bits: 0), Width(16)] // VT
542                 public uint vlanTag;
543                 [PacketField, Offset(doubleWords: 3, bits: 16), Width(1)] // VLTV
544                 public bool vlanTagValid;
545                 [PacketField, Offset(doubleWords: 3, bits: 17), Width(1)] // IVLTV
546                 public bool innerVlanTagValid;
547                 [PacketField, Offset(doubleWords: 3, bits: 18), Width(2)] // IVTIR
548                 public VLANTagOperation innerVlanTagControl;
549                 // bits 20:22 of 4th double word are reserved
550                 [PacketField, Offset(doubleWords: 3, bits: 23), Width(1)] // CDE
551                 public bool contextDescriptorError;
552                 // bits 24:25 of 4th double word are reserved
553                 [PacketField, Offset(doubleWords: 3, bits: 26), Width(1)] // TCMSSV
554                 public bool oneStepTimestampCorrectionInputOrMaximumSegmentSizeValid;
555                 [PacketField, Offset(doubleWords: 3, bits: 27), Width(1)] // OSTC
556                 public bool oneStepTimestampCorrectionEnable;
557                 // bits 28:29 of 4th double word are reserved
558                 [PacketField, Offset(doubleWords: 3, bits: 30), Width(1)] // CTXT
559                 public bool contextType;
560                 [PacketField, Offset(doubleWords: 3, bits: 31), Width(1)] // OWN
561                 public DescriptorOwner owner;
562 #pragma warning restore 649
563             }
564         }
565 
566         private enum DescriptorOwner : byte
567         {
568             DMA = 1,
569             Application = 0,
570         }
571 
572         private enum PayloadType : byte
573         {
574             Unknown  = 0b000,
575             UDP      = 0b001,
576             TCP      = 0b010,
577             ICMP     = 0b011,
578             IGMPIPV4 = 0b100,
579         }
580 
581         private enum PTPMessageType : byte
582         {
583             NoPTPMessageReceived             = 0b0000,
584             Sync                             = 0b0001,
585             FollowUp                         = 0b0010,
586             DelayRequest                     = 0b0011,
587             DelayResponse                    = 0b0100,
588             PdelayRequest                    = 0b0101,
589             PdelayResponse                   = 0b0110,
590             PdelayResponseFollowUp           = 0b0111,
591             Announce                         = 0b1000,
592             Management                       = 0b1001,
593             Signaling                        = 0b1010,
594             // Reserved                      = 0b1011..0b1110,
595             PTPPacketWithReservedMessageType = 0b1111,
596         }
597 
598         private enum PTPVersion : byte
599         {
600             IEEE1588version2 = 1,
601             IEEE1588version1 = 0,
602         }
603 
604         private enum PacketKind : byte
605         {
606             LengthPacket                = 0b000,
607             TypePacket                  = 0b001,
608             // Reserved                 = 0b010,
609             ARPRequest                  = 0b011,
610             TypePacketWithVLANTag       = 0b100,
611             TypePacketWithDoubleVLANTag = 0b101,
612             MACControlPacket            = 0b110,
613             OAMPacket                   = 0b111,
614         }
615 
616         private enum VLANTagOperation : byte
617         {
618             None    = 0b00,
619             Remove  = 0b01,
620             Insert  = 0b10,
621             Replace = 0b11,
622         }
623 
624         private enum ChecksumOperation : byte
625         {
626             None                                       = 0b00,
627             InsertHeaderChecksum                       = 0b01,
628             InsertHeaderAndPayloadChecksum             = 0b10,
629             InsertHeaderPayloadAndPseudoHeaderChecksum = 0b11,
630         }
631 
632         private enum DescriptorSourceAddressOperation : byte
633         {
634             MACAddressRegister0None     = 0b000,
635             MACAddressRegister0Insert   = 0b001,
636             MACAddressRegister0Replace  = 0b010,
637             MACAddressRegister0Reserved = 0b011,
638             MACAddressRegister1None     = 0b100,
639             MACAddressRegister1Insert   = 0b101,
640             MACAddressRegister1Replace  = 0b110,
641             MACAddressRegister1Reserved = 0b111,
642         }
643 
644         private enum CRCPadOperation : byte
645         {
646             InsetCRCAndPad = 0b00,
647             InsertCRC      = 0b01,
648             None           = 0b10,
649             ReplaceCRC     = 0b11,
650         }
651     }
652 }
653