summaryrefslogtreecommitdiff
path: root/network/netadaptercx/netvadapterlibrary/code/net/netpacketlibrary.h
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);
}