blob: b5e3451808cc3b51e1a9d76c028b06e0a533ea04 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
|
// Copyright (C) Microsoft Corporation. All rights reserved.
#pragma once
#include <net/virtualaddress.h>
//
// Following are some helper APIs for common ring manipulations.
// They are all implemented using iterator
//
inline
SIZE_T
GetTxPacketDataLength(
_In_ NET_RING_PACKET_ITERATOR const* Iterator
)
{
SIZE_T length = 0;
for (NET_RING_FRAGMENT_ITERATOR fi = NetPacketIteratorGetFragments(Iterator);
NetFragmentIteratorHasAny(&fi);
NetFragmentIteratorAdvance(&fi))
{
NET_FRAGMENT* fragment = NetFragmentIteratorGetFragment(&fi);
length += (SIZE_T)fragment->ValidLength;
}
return length;
}
inline
VOID
CompleteTxPacketsBatch(
_In_ NET_RING_COLLECTION const* Rings,
_In_ UINT32 BatchSize
)
{
UINT32 packetCount = 0;
NET_RING_PACKET_ITERATOR pi = NetRingGetDrainPackets(Rings);
while (NetPacketIteratorHasAny(&pi))
{
NET_PACKET* packet = NetPacketIteratorGetPacket(&pi);
// this function uses Scratch field as the bit for testing completion
if (!packet->Scratch)
{
break;
}
packetCount++;
NET_RING_FRAGMENT_ITERATOR fi = NetPacketIteratorGetFragments(&pi);
NetFragmentIteratorAdvanceToTheEnd(&fi);
NetPacketIteratorAdvance(&pi);
if (packetCount >= BatchSize)
{
NetPacketIteratorSet(&pi);
Rings->Rings[NetRingTypeFragment]->BeginIndex = NetFragmentIteratorGetIndex(&fi);
}
}
}
inline
void
CancelRxPackets(
_In_ NET_RING_COLLECTION const* Rings
)
{
NET_RING_PACKET_ITERATOR pi = NetRingGetAllPackets(Rings);
for (; NetPacketIteratorHasAny(&pi); NetPacketIteratorAdvance(&pi))
{
NetPacketIteratorGetPacket(&pi)->Ignore = 1;
}
NetPacketIteratorSet(&pi);
NET_RING_FRAGMENT_ITERATOR fi = NetRingGetAllFragments(Rings);
NetFragmentIteratorAdvanceToTheEnd(&fi);
NetFragmentIteratorSet(&fi);
}
|