win-pvdrivers

view xennet/xennet_common.c @ 382:ecfd4ddaaf3d

remove dead code
author Andy Grover <andy.grover@oracle.com>
date Wed Jul 09 12:35:41 2008 -0700 (2008-07-09)
parents 5a762fd1fba9
children 7259dad4e96c
line source
1 /*
2 PV Net Driver for Windows Xen HVM Domains
3 Copyright (C) 2007 James Harper
4 Copyright (C) 2007 Andrew Grover <andy.grover@oracle.com>
6 This program is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License
8 as published by the Free Software Foundation; either version 2
9 of the License, or (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
21 #include "xennet.h"
23 ULONG
24 XenNet_ParsePacketHeader(
25 packet_info_t *pi
26 )
27 {
28 UINT header_length;
30 // KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
32 ASSERT(pi->mdls[0]);
34 NdisQueryBufferSafe(pi->mdls[0], (PVOID) &pi->header, &header_length, NormalPagePriority);
36 // what about if the buffer isn't completely on one page???
37 if (ADDRESS_AND_SIZE_TO_SPAN_PAGES(MmGetMdlVirtualAddress(pi->mdls[0]), header_length) != 1)
38 KdPrint((__DRIVER_NAME " header crosses a page!\n"));
41 if (header_length < XN_HDR_SIZE + 20 + 20) // minimum size of first buffer is ETH + IP + TCP header
42 {
43 return PARSE_TOO_SMALL;
44 }
46 switch (GET_NET_USHORT(pi->header[12])) // L2 protocol field
47 {
48 case 0x0800:
49 pi->ip_version = (pi->header[XN_HDR_SIZE + 0] & 0xF0) >> 4;
50 if (pi->ip_version != 4)
51 {
52 KdPrint((__DRIVER_NAME " ip_version = %d\n", pi->ip_version));
53 return PARSE_UNKNOWN_TYPE;
54 }
55 pi->ip4_header_length = (pi->header[XN_HDR_SIZE + 0] & 0x0F) << 2;
56 if (header_length < (ULONG)(pi->ip4_header_length + 20))
57 {
58 KdPrint((__DRIVER_NAME " first buffer is only %d bytes long, must be >= %d\n", XN_HDR_SIZE + header_length, (ULONG)(XN_HDR_SIZE + pi->ip4_header_length + 20)));
59 // we need to do something conclusive here...
60 return PARSE_TOO_SMALL;
61 }
62 break;
63 default:
64 // KdPrint((__DRIVER_NAME " Not IP\n"));
65 return PARSE_UNKNOWN_TYPE;
66 }
67 pi->ip_proto = pi->header[XN_HDR_SIZE + 9];
68 switch (pi->ip_proto)
69 {
70 case 6: // TCP
71 case 17: // UDP
72 break;
73 default:
74 return PARSE_UNKNOWN_TYPE;
75 }
76 pi->ip4_length = GET_NET_USHORT(pi->header[XN_HDR_SIZE + 2]);
77 pi->tcp_header_length = (pi->header[XN_HDR_SIZE + pi->ip4_header_length + 12] & 0xf0) >> 2;
79 if (header_length < (ULONG)(pi->ip4_header_length + pi->tcp_header_length))
80 {
81 KdPrint((__DRIVER_NAME " first buffer is only %d bytes long, must be >= %d\n", XN_HDR_SIZE + header_length, (ULONG)(XN_HDR_SIZE + pi->ip4_header_length + pi->tcp_header_length)));
82 return PARSE_TOO_SMALL;
83 }
85 pi->tcp_length = pi->ip4_length - pi->ip4_header_length - pi->tcp_header_length;
86 pi->tcp_remaining = pi->tcp_length;
87 pi->tcp_seq = GET_NET_ULONG(pi->header[XN_HDR_SIZE + pi->ip4_header_length + 4]);
88 if (pi->mss > 0 && pi->tcp_length > pi->mss)
89 pi->split_required = TRUE;
90 // KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
91 return PARSE_OK;
92 }
94 VOID
95 XenNet_SumIpHeader(
96 PUCHAR header,
97 USHORT ip4_header_length
98 )
99 {
100 ULONG csum = 0;
101 USHORT i;
103 ASSERT(ip4_header_length > 12);
104 ASSERT(!(ip4_header_length & 1));
106 header[XN_HDR_SIZE + 10] = 0;
107 header[XN_HDR_SIZE + 11] = 0;
108 for (i = 0; i < ip4_header_length; i += 2)
109 {
110 csum += GET_NET_USHORT(header[XN_HDR_SIZE + i]);
111 }
112 while (csum & 0xFFFF0000)
113 csum = (csum & 0xFFFF) + (csum >> 16);
114 csum = ~csum;
115 SET_NET_USHORT(header[XN_HDR_SIZE + 10], csum);
116 }
118 PUCHAR
119 XenNet_GetData(
120 packet_info_t *pi,
121 USHORT req_length,
122 PUSHORT length
123 )
124 {
125 PNDIS_BUFFER mdl = pi->mdls[pi->curr_mdl];
126 PUCHAR buffer = (PUCHAR)MmGetMdlVirtualAddress(mdl) + pi->curr_mdl_offset;
128 // KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
130 *length = (USHORT)min(req_length, MmGetMdlByteCount(mdl) - pi->curr_mdl_offset);
132 // KdPrint((__DRIVER_NAME " req_length = %d, length = %d\n", req_length, *length));
134 pi->curr_mdl_offset = pi->curr_mdl_offset + *length;
135 if (pi->curr_mdl_offset == MmGetMdlByteCount(mdl))
136 {
137 pi->curr_mdl++;
138 pi->curr_mdl_offset = 0;
139 }
141 // KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
143 return buffer;
144 }
146 /* Called at DISPATCH LEVEL */
147 static VOID DDKAPI
148 XenFreelist_Timer(
149 PVOID SystemSpecific1,
150 PVOID FunctionContext,
151 PVOID SystemSpecific2,
152 PVOID SystemSpecific3
153 )
154 {
155 freelist_t *fl = (freelist_t *)FunctionContext;
156 PMDL mdl;
157 int i;
159 UNREFERENCED_PARAMETER(SystemSpecific1);
160 UNREFERENCED_PARAMETER(SystemSpecific2);
161 UNREFERENCED_PARAMETER(SystemSpecific3);
163 if (fl->xi->device_state->resume_state != RESUME_STATE_RUNNING && !fl->grants_resumed)
164 return;
166 KeAcquireSpinLockAtDpcLevel(fl->lock);
168 //KdPrint((__DRIVER_NAME " --- timer - page_free_lowest = %d\n", fl->page_free_lowest));
169 // KdPrint((__DRIVER_NAME " --- rx_outstanding = %d, rx_id_free = %d\n", xi->rx_outstanding, xi->rx_id_free));
171 if (fl->page_free_lowest > fl->page_free_target) // lots of potential for tuning here
172 {
173 for (i = 0; i < (int)min(16, fl->page_free_lowest - fl->page_free_target); i++)
174 {
175 mdl = XenFreelist_GetPage(fl);
176 fl->xi->vectors.GntTbl_EndAccess(fl->xi->vectors.context,
177 *(grant_ref_t *)(((UCHAR *)mdl) + MmSizeOfMdl(0, PAGE_SIZE)), 0);
178 FreePages(mdl);
179 }
180 //KdPrint((__DRIVER_NAME " --- timer - freed %d pages\n", i));
181 }
183 fl->page_free_lowest = fl->page_free;
185 KeReleaseSpinLockFromDpcLevel(fl->lock);
187 return;
188 }
190 VOID
191 XenFreelist_Init(struct xennet_info *xi, freelist_t *fl, PKSPIN_LOCK lock)
192 {
193 fl->xi = xi;
194 fl->lock = lock;
195 fl->page_free = 0;
196 fl->page_free_lowest = 0;
197 fl->page_free_target = 16; /* tune this */
198 fl->grants_resumed = FALSE;
199 NdisMInitializeTimer(&fl->timer, fl->xi->adapter_handle, XenFreelist_Timer, fl);
200 NdisMSetPeriodicTimer(&fl->timer, 1000);
201 }
203 PMDL
204 XenFreelist_GetPage(freelist_t *fl)
205 {
206 PMDL mdl;
207 PFN_NUMBER pfn;
209 if (fl->page_free == 0)
210 {
211 mdl = AllocatePagesExtra(1, sizeof(grant_ref_t));
212 pfn = *MmGetMdlPfnArray(mdl);
213 *(grant_ref_t *)(((UCHAR *)mdl) + MmSizeOfMdl(0, PAGE_SIZE)) = fl->xi->vectors.GntTbl_GrantAccess(
214 fl->xi->vectors.context, 0,
215 (uint32_t)pfn, FALSE, 0);
216 /* we really should check if our grant was successful... */
217 }
218 else
219 {
220 fl->page_free--;
221 if (fl->page_free < fl->page_free_lowest)
222 fl->page_free_lowest = fl->page_free;
223 mdl = fl->page_list[fl->page_free];
224 }
226 return mdl;
227 }
229 VOID
230 XenFreelist_PutPage(freelist_t *fl, PMDL mdl)
231 {
232 fl->page_list[fl->page_free] = mdl;
233 fl->page_free++;
234 }
236 VOID
237 XenFreelist_Dispose(freelist_t *fl)
238 {
239 PMDL mdl;
240 BOOLEAN TimerCancelled;
242 NdisMCancelTimer(&fl->timer, &TimerCancelled);
244 while(fl->page_free != 0)
245 {
246 fl->page_free--;
247 mdl = fl->page_list[fl->page_free];
248 fl->xi->vectors.GntTbl_EndAccess(fl->xi->vectors.context,
249 *(grant_ref_t *)(((UCHAR *)mdl) + MmSizeOfMdl(0, PAGE_SIZE)), 0);
250 FreePages(mdl);
251 }
252 }
254 static VOID
255 XenFreelist_ReGrantMdl(freelist_t *fl, PMDL mdl)
256 {
257 PFN_NUMBER pfn;
258 pfn = *MmGetMdlPfnArray(mdl);
259 *(grant_ref_t *)(((UCHAR *)mdl) + MmSizeOfMdl(0, PAGE_SIZE)) = fl->xi->vectors.GntTbl_GrantAccess(
260 fl->xi->vectors.context, 0,
261 (uint32_t)pfn, FALSE, 0);
262 }
264 /* re-grant all the pages, as the grant table was wiped on resume */
265 VOID
266 XenFreelist_ResumeStart(freelist_t *fl)
267 {
268 ULONG i;
270 for (i = 0; i < fl->page_free; i++)
271 {
272 XenFreelist_ReGrantMdl(fl, fl->page_list[i]);
273 }
274 fl->grants_resumed = TRUE;
275 }
277 VOID
278 XenFreelist_ResumeEnd(freelist_t *fl)
279 {
280 fl->grants_resumed = FALSE;
281 }