win-pvdrivers

view xennet/xennet_common.c @ 248:7c395bd04ec1

Some tweaking to get gso working properly again.
author James Harper <james.harper@bendigoit.com.au>
date Sat Apr 05 23:32:53 2008 +1100 (2008-04-05)
parents 402fb735ce45
children 7e3bcd88515c
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], &pi->header, &header_length, NormalPagePriority);
36 if (header_length < XN_HDR_SIZE + 20 + 20) // minimum size of first buffer is ETH + IP + TCP header
37 {
38 return PARSE_TOO_SMALL;
39 }
41 switch (GET_NET_USHORT(pi->header[12])) // L2 protocol field
42 {
43 case 0x0800:
44 pi->ip_version = (pi->header[XN_HDR_SIZE + 0] & 0xF0) >> 4;
45 if (pi->ip_version != 4)
46 {
47 KdPrint((__DRIVER_NAME " ip_version = %d\n", pi->ip_version));
48 return PARSE_UNKNOWN_TYPE;
49 }
50 pi->ip4_header_length = (pi->header[XN_HDR_SIZE + 0] & 0x0F) << 2;
51 if (header_length < (ULONG)(pi->ip4_header_length + 20))
52 {
53 KdPrint((__DRIVER_NAME " first packet is only %d long, must be >= %d\n", XN_HDR_SIZE + header_length, (ULONG)(XN_HDR_SIZE + pi->ip4_header_length + 20)));
54 // we need to do something conclusive here...
55 return PARSE_TOO_SMALL;
56 }
57 break;
58 default:
59 // KdPrint((__DRIVER_NAME " Not IP\n"));
60 return PARSE_UNKNOWN_TYPE;
61 }
62 pi->ip_proto = pi->header[XN_HDR_SIZE + 9];
63 switch (pi->ip_proto)
64 {
65 case 6: // TCP
66 case 17: // UDP
67 break;
68 default:
69 return PARSE_UNKNOWN_TYPE;
70 }
71 pi->ip4_length = GET_NET_USHORT(pi->header[XN_HDR_SIZE + 2]);
72 pi->tcp_header_length = (pi->header[XN_HDR_SIZE + pi->ip4_header_length + 12] & 0xf0) >> 2;
73 pi->tcp_length = pi->ip4_length - pi->ip4_header_length - pi->tcp_header_length;
74 pi->tcp_remaining = pi->tcp_length;
75 pi->tcp_seq = GET_NET_ULONG(pi->header[XN_HDR_SIZE + pi->ip4_header_length + 4]);
76 if (pi->mss > 0 && pi->tcp_length > pi->mss)
77 pi->split_required = TRUE;
78 // KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
79 return PARSE_OK;
80 }
82 VOID
83 XenNet_SumIpHeader(
84 PUCHAR header,
85 USHORT ip4_header_length
86 )
87 {
88 ULONG csum = 0;
89 USHORT i;
91 header[XN_HDR_SIZE + 10] = 0;
92 header[XN_HDR_SIZE + 11] = 0;
93 for (i = 0; i < ip4_header_length; i += 2)
94 {
95 csum += GET_NET_USHORT(header[XN_HDR_SIZE + i]);
96 }
97 while (csum & 0xFFFF0000)
98 csum = (csum & 0xFFFF) + (csum >> 16);
99 csum = ~csum;
100 SET_NET_USHORT(header[XN_HDR_SIZE + 10], csum);
101 }
103 PUCHAR
104 XenNet_GetData(
105 packet_info_t *pi,
106 USHORT req_length,
107 PUSHORT length
108 )
109 {
110 PNDIS_BUFFER mdl = pi->mdls[pi->curr_mdl];
111 PUCHAR buffer = (PUCHAR)MmGetMdlVirtualAddress(mdl) + pi->curr_mdl_offset;
113 // KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
115 *length = (USHORT)min(req_length, MmGetMdlByteCount(mdl) - pi->curr_mdl_offset);
117 // KdPrint((__DRIVER_NAME " req_length = %d, length = %d\n", req_length, *length));
119 pi->curr_mdl_offset = pi->curr_mdl_offset + *length;
120 if (pi->curr_mdl_offset == MmGetMdlByteCount(mdl))
121 {
122 pi->curr_mdl++;
123 pi->curr_mdl_offset = 0;
124 }
126 // KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
128 return buffer;
129 }