21a771678edcab7b5403692f7ecbe780243f31a7
[people/xl0/gpxe.git] / src / include / gpxe / pkbuff.h
1 #ifndef _GPXE_PKBUFF_H
2 #define _GPXE_PKBUFF_H
3
4 /** @file
5  *
6  * Packet buffers
7  *
8  * Packet buffers are used to contain network packets.  Methods are
9  * provided for appending, prepending, etc. data.
10  *
11  */
12
13 #include <stdint.h>
14 #include <assert.h>
15 #include <gpxe/list.h>
16
17 /**
18  * Packet buffer alignment
19  *
20  * Packet buffers allocated via alloc_pkb() are guaranteed to be
21  * physically aligned to this boundary.  Some cards cannot DMA across
22  * a 4kB boundary.  With a standard Ethernet MTU, aligning to a 2kB
23  * boundary is sufficient to guarantee no 4kB boundary crossings.  For
24  * a jumbo Ethernet MTU, a packet may be larger than 4kB anyway.
25  */
26 #define PKBUFF_ALIGN 2048
27
28 /**
29  * Minimum packet buffer length
30  *
31  * alloc_pkb() will round up the allocated length to this size if
32  * necessary.  This is used on behalf of hardware that is not capable
33  * of auto-padding.
34  */
35 #define PKB_ZLEN 64
36
37 /** A packet buffer
38  *
39  * This structure is used to represent a network packet within gPXE.
40  */
41 struct pk_buff {
42         /** List of which this buffer is a member */
43         struct list_head list;
44
45         /** Start of the buffer */
46         void *head;
47         /** Start of data */
48         void *data;
49         /** End of data */
50         void *tail;
51         /** End of the buffer */
52         void *end;
53 };
54
55 /**
56  * Reserve space at start of packet buffer
57  *
58  * @v pkb       Packet buffer
59  * @v len       Length to reserve
60  * @ret data    Pointer to new start of buffer
61  */
62 static inline void * pkb_reserve ( struct pk_buff *pkb, size_t len ) {
63         pkb->data += len;
64         pkb->tail += len;
65         assert ( pkb->tail <= pkb->end );
66         return pkb->data;
67 }
68
69 /**
70  * Add data to start of packet buffer
71  *
72  * @v pkb       Packet buffer
73  * @v len       Length to add
74  * @ret data    Pointer to new start of buffer
75  */
76 static inline void * pkb_push ( struct pk_buff *pkb, size_t len ) {
77         pkb->data -= len;
78         assert ( pkb->data >= pkb->head );
79         return pkb->data;
80 }
81
82 /**
83  * Remove data from start of packet buffer
84  *
85  * @v pkb       Packet buffer
86  * @v len       Length to remove
87  * @ret data    Pointer to new start of buffer
88  */
89 static inline void * pkb_pull ( struct pk_buff *pkb, size_t len ) {
90         pkb->data += len;
91         assert ( pkb->data <= pkb->tail );
92         return pkb->data;
93 }
94
95 /**
96  * Add data to end of packet buffer
97  *
98  * @v pkb       Packet buffer
99  * @v len       Length to add
100  * @ret data    Pointer to newly added space
101  */
102 static inline void * pkb_put ( struct pk_buff *pkb, size_t len ) {
103         void *old_tail = pkb->tail;
104         pkb->tail += len;
105         assert ( pkb->tail <= pkb->end );
106         return old_tail;
107 }
108
109 /**
110  * Remove data from end of packet buffer
111  *
112  * @v pkb       Packet buffer
113  * @v len       Length to remove
114  */
115 static inline void pkb_unput ( struct pk_buff *pkb, size_t len ) {
116         pkb->tail -= len;
117         assert ( pkb->tail >= pkb->data );
118 }
119
120 /**
121  * Empty a packet buffer
122  *
123  * @v pkb       Packet buffer
124  */
125 static inline void pkb_empty ( struct pk_buff *pkb ) {
126         pkb->tail = pkb->data;
127 }
128
129 /**
130  * Calculate length of data in a packet buffer
131  *
132  * @v pkb       Packet buffer
133  * @ret len     Length of data in buffer
134  */
135 static inline size_t pkb_len ( struct pk_buff *pkb ) {
136         return ( pkb->tail - pkb->data );
137 }
138
139 /**
140  * Calculate available space in a packet buffer
141  *
142  * @v pkb       Packet buffer
143  * @ret len     Length of data available in buffer
144  */
145 static inline size_t pkb_available ( struct pk_buff *pkb ) {
146         return ( pkb->end - pkb->tail );
147 }
148
149 extern struct pk_buff * alloc_pkb ( size_t len );
150 extern void free_pkb ( struct pk_buff *pkb );
151
152 #endif /* _GPXE_PKBUFF_H */