win-pvdrivers

view xennet/xennet.h @ 668:cfee9cb572cc

rc version info
author James Harper <james.harper@bendigoit.com.au>
date Wed Sep 23 17:05:21 2009 +1000 (2009-09-23)
parents ee9c59a5a06c
children f1bb26495379
line source
1 /*
2 PV Drivers 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 #pragma warning(disable: 4201)
22 #pragma warning(disable: 4214)
24 #ifdef __MINGW32__
25 #include <ntddk.h>
26 #define NDIS50_MINIPORT 1
27 #include <ndis.h>
28 #include "../mingw/mingw_extras.h"
30 #else
31 #define DDKAPI
32 #include <ntddk.h>
33 #include <wdm.h>
34 #define NDIS_MINIPORT_DRIVER
35 #if NTDDI_VERSION < NTDDI_WINXP
36 # define NDIS50_MINIPORT 1
37 #else
38 # define NDIS51_MINIPORT 1
39 #endif
40 #include <ndis.h>
41 #define NTSTRSAFE_LIB
42 #include <ntstrsafe.h>
43 #endif
46 #define VENDOR_DRIVER_VERSION_MAJOR 0
47 #define VENDOR_DRIVER_VERSION_MINOR 9
49 #define VENDOR_DRIVER_VERSION (((VENDOR_DRIVER_VERSION_MAJOR) << 16) | (VENDOR_DRIVER_VERSION_MINOR))
51 #define __DRIVER_NAME "XenNet"
53 #include <xen_windows.h>
54 #include <memory.h>
55 #include <grant_table.h>
56 #include <event_channel.h>
57 #include <hvm/params.h>
58 #include <hvm/hvm_op.h>
59 #include <xen_public.h>
60 #include <io/ring.h>
61 #include <io/netif.h>
62 #include <io/xenbus.h>
63 #include <stdlib.h>
64 #define XENNET_POOL_TAG (ULONG) 'XenN'
67 /* Xen macros use these, so they need to be redefined to Win equivs */
68 #define wmb() KeMemoryBarrier()
69 #define mb() KeMemoryBarrier()
71 #define GRANT_INVALID_REF 0
73 #define NAME_SIZE 64
75 #define ETH_ALEN 6
77 /*
78 #define __NET_USHORT_BYTE_0(x) ((USHORT)(x & 0xFF))
79 #define __NET_USHORT_BYTE_1(x) ((USHORT)((PUCHAR)&x)[1] & 0xFF)
81 #define GET_NET_USHORT(x) ((__NET_USHORT_BYTE_0(x) << 8) | __NET_USHORT_BYTE_1(x))
82 #define SET_NET_USHORT(y, x) *((USHORT *)&(y)) = ((__NET_USHORT_BYTE_0(x) << 8) | __NET_USHORT_BYTE_1(x))
83 */
85 static FORCEINLINE USHORT
86 GET_NET_USHORT(USHORT data)
87 {
88 return (data << 8) | (data >> 8);
89 }
91 static FORCEINLINE USHORT
92 GET_NET_PUSHORT(PVOID pdata)
93 {
94 return (*((PUSHORT)pdata) << 8) | (*((PUSHORT)pdata) >> 8);
95 }
97 static FORCEINLINE VOID
98 SET_NET_USHORT(PVOID ptr, USHORT data)
99 {
100 *((PUSHORT)ptr) = GET_NET_USHORT(data);
101 }
103 static FORCEINLINE ULONG
104 GET_NET_ULONG(ULONG data)
105 {
106 ULONG tmp;
108 tmp = ((data & 0x00ff00ff) << 8) | ((data & 0xff00ff00) >> 8);
109 return (tmp << 16) | (tmp >> 16);
110 }
112 static FORCEINLINE ULONG
113 GET_NET_PULONG(PVOID pdata)
114 {
115 ULONG tmp;
117 tmp = ((*((PULONG)pdata) & 0x00ff00ff) << 8) | ((*((PULONG)pdata) & 0xff00ff00) >> 8);
118 return (tmp << 16) | (tmp >> 16);
119 }
121 static FORCEINLINE VOID
122 SET_NET_ULONG(PVOID ptr, ULONG data)
123 {
124 *((PULONG)ptr) = GET_NET_ULONG(data);
125 }
126 /*
127 #define GET_NET_ULONG(x) ((GET_NET_USHORT(x) << 16) | GET_NET_USHORT(((PUCHAR)&x)[2]))
128 #define SET_NET_ULONG(y, x) *((ULONG *)&(y)) = ((GET_NET_USHORT(x) << 16) | GET_NET_USHORT(((PUCHAR)&x)[2]))
129 */
131 #define SUPPORTED_PACKET_FILTERS (\
132 NDIS_PACKET_TYPE_DIRECTED | \
133 NDIS_PACKET_TYPE_MULTICAST | \
134 NDIS_PACKET_TYPE_BROADCAST | \
135 NDIS_PACKET_TYPE_PROMISCUOUS | \
136 NDIS_PACKET_TYPE_ALL_MULTICAST)
138 /* couldn't get regular xen ring macros to work...*/
139 #define __NET_RING_SIZE(type, _sz) \
140 (__RD32( \
141 (_sz - sizeof(struct type##_sring) + sizeof(union type##_sring_entry)) \
142 / sizeof(union type##_sring_entry)))
144 #define NET_TX_RING_SIZE __NET_RING_SIZE(netif_tx, PAGE_SIZE)
145 #define NET_RX_RING_SIZE __NET_RING_SIZE(netif_rx, PAGE_SIZE)
147 #pragma warning(disable: 4127) // conditional expression is constant
149 #define MIN_LARGE_SEND_SEGMENTS 4
151 /* TODO: crank this up if we support higher mtus? */
152 #define XN_HDR_SIZE 14
153 #define XN_MAX_DATA_SIZE 1500
154 #define XN_MIN_FRAME_SIZE 60
155 #define XN_MAX_FRAME_SIZE (XN_HDR_SIZE + XN_DATA_SIZE)
156 /*
157 #if !defined(OFFLOAD_LARGE_SEND)
158 #define XN_MAX_PKT_SIZE (XN_HDR_SIZE + XN_DATA_SIZE)
159 #else
160 #define XN_MAX_PKT_SIZE MAX_LARGE_SEND_OFFLOAD
161 #endif
162 */
164 #define XN_MAX_SEND_PKTS 16
166 #define XENSOURCE_MAC_HDR 0x00163E
167 #define XN_VENDOR_DESC "Xensource"
168 #define MAX_XENBUS_STR_LEN 128
170 #define RX_MIN_TARGET 8
171 #define RX_DFL_MIN_TARGET 256
172 #define RX_MAX_TARGET min(NET_RX_RING_SIZE, 256)
174 //#define MAX_BUFFERS_PER_PACKET NET_RX_RING_SIZE
176 #define MAX_ETH_HEADER_SIZE 14
177 #define MIN_IP4_HEADER_SIZE 20
178 #define MAX_IP4_HEADER_SIZE (15 * 4)
179 #define MIN_TCP_HEADER_SIZE 20
180 #define MAX_TCP_HEADER_SIZE (15 * 4)
181 #define MAX_PKT_HEADER_SIZE (MAX_ETH_HEADER_SIZE + MAX_IP_HEADER_SIZE + MAX_TCP_HEADER_SIZE)
183 typedef struct
184 {
185 PVOID next;
186 PHYSICAL_ADDRESS logical;
187 PVOID virtual;
188 PNDIS_BUFFER buffer;
189 USHORT id;
190 USHORT ref_count;
191 } shared_buffer_t;
193 typedef struct
194 {
195 PNDIS_PACKET packet; /* only set on the last packet */
196 shared_buffer_t *cb;
197 } tx_shadow_t;
199 typedef struct {
200 PNDIS_BUFFER first_buffer;
201 PNDIS_BUFFER curr_buffer;
202 shared_buffer_t *first_pb;
203 shared_buffer_t *curr_pb;
204 PUCHAR first_buffer_virtual;
205 UCHAR header_data[132]; /* maximum possible size of ETH + IP + TCP/UDP headers */
206 ULONG mdl_count;
207 USHORT curr_mdl_offset;
208 USHORT mss;
209 NDIS_TCP_IP_CHECKSUM_PACKET_INFO csum_info;
210 BOOLEAN csum_blank;
211 BOOLEAN data_validated;
212 BOOLEAN split_required;
213 UCHAR ip_version;
214 PUCHAR header;
215 ULONG first_buffer_length;
216 ULONG header_length;
217 UCHAR ip_proto;
218 ULONG total_length;
219 USHORT ip4_header_length;
220 USHORT ip4_length;
221 USHORT tcp_header_length;
222 BOOLEAN tcp_has_options;
223 USHORT tcp_length;
224 USHORT tcp_remaining;
225 ULONG tcp_seq;
226 BOOLEAN extra_info;
227 BOOLEAN more_frags;
228 } packet_info_t;
230 #define PAGE_LIST_SIZE (max(NET_RX_RING_SIZE, NET_TX_RING_SIZE) * 4)
231 #define MULTICAST_LIST_MAX_SIZE 32
233 struct xennet_info
234 {
235 BOOLEAN inactive;
237 /* Base device vars */
238 PDEVICE_OBJECT pdo;
239 PDEVICE_OBJECT fdo;
240 PDEVICE_OBJECT lower_do;
241 //WDFDEVICE wdf_device;
242 WCHAR dev_desc[NAME_SIZE];
244 /* NDIS-related vars */
245 NDIS_HANDLE adapter_handle;
246 NDIS_MINIPORT_INTERRUPT interrupt;
247 ULONG packet_filter;
248 BOOLEAN connected;
249 BOOLEAN shutting_down;
250 BOOLEAN tx_shutting_down;
251 BOOLEAN rx_shutting_down;
252 uint8_t perm_mac_addr[ETH_ALEN];
253 uint8_t curr_mac_addr[ETH_ALEN];
255 /* Misc. Xen vars */
256 XENPCI_VECTORS vectors;
257 PXENPCI_DEVICE_STATE device_state;
258 evtchn_port_t event_channel;
259 ULONG state;
260 char backend_path[MAX_XENBUS_STR_LEN];
261 ULONG backend_state;
262 PVOID config_page;
263 UCHAR multicast_list[MULTICAST_LIST_MAX_SIZE][6];
264 ULONG multicast_list_size;
265 KDPC suspend_dpc;
266 PIO_WORKITEM resume_work_item;
268 /* tx related - protected by tx_lock */
269 KSPIN_LOCK tx_lock;
270 LIST_ENTRY tx_waiting_pkt_list;
271 struct netif_tx_front_ring tx;
272 ULONG tx_ring_free;
273 tx_shadow_t tx_shadows[NET_TX_RING_SIZE];
274 NDIS_HANDLE tx_buffer_pool;
275 #define TX_HEADER_BUFFER_SIZE 512
276 //#define TX_COALESCE_BUFFERS (NET_TX_RING_SIZE >> 2)
277 #define TX_COALESCE_BUFFERS (NET_TX_RING_SIZE)
278 KEVENT tx_idle_event;
279 ULONG tx_outstanding;
280 ULONG tx_id_free;
281 USHORT tx_id_list[NET_TX_RING_SIZE];
282 ULONG tx_cb_free;
283 ULONG tx_cb_list[TX_COALESCE_BUFFERS];
284 shared_buffer_t tx_cbs[TX_COALESCE_BUFFERS];
285 KDPC tx_dpc;
287 /* rx_related - protected by rx_lock */
288 KSPIN_LOCK rx_lock;
289 struct netif_rx_front_ring rx;
290 ULONG rx_id_free;
291 packet_info_t rxpi;
292 PNDIS_PACKET rx_packet_list[NET_RX_RING_SIZE * 2];
293 ULONG rx_packet_free;
294 KEVENT packet_returned_event;
295 //NDIS_MINIPORT_TIMER rx_timer;
296 KDPC rx_dpc;
297 KTIMER rx_timer;
298 KDPC rx_timer_dpc;
299 NDIS_HANDLE rx_packet_pool;
300 NDIS_HANDLE rx_buffer_pool;
301 ULONG rx_pb_free;
302 #define RX_PAGE_BUFFERS (NET_RX_RING_SIZE * 2)
303 ULONG rx_pb_list[RX_PAGE_BUFFERS];
304 shared_buffer_t rx_pbs[RX_PAGE_BUFFERS];
305 USHORT rx_ring_pbs[NET_RX_RING_SIZE];
306 #define LOOKASIDE_LIST_ALLOC_SIZE 256
307 NPAGED_LOOKASIDE_LIST rx_lookaside_list;
308 /* Receive-ring batched refills. */
309 ULONG rx_target;
310 ULONG rx_max_target;
311 ULONG rx_min_target;
313 /* how many packets are in the net stack atm */
314 ULONG rx_outstanding;
316 /* config vars from registry */
317 ULONG config_sg;
318 ULONG config_csum;
319 ULONG config_csum_rx_check;
320 ULONG config_gso;
321 ULONG config_mtu;
322 ULONG config_rx_interrupt_moderation;
324 NDIS_TASK_TCP_IP_CHECKSUM setting_csum;
325 ULONG setting_max_offload;
327 /* config stuff calculated from the above */
328 ULONG config_max_pkt_size;
330 /* stats */
331 ULONG64 stat_tx_ok;
332 ULONG64 stat_rx_ok;
333 ULONG64 stat_tx_error;
334 ULONG64 stat_rx_error;
335 ULONG64 stat_rx_no_buffer;
337 } typedef xennet_info_t;
339 VOID DDKAPI
340 XenNet_ReturnPacket(
341 IN NDIS_HANDLE MiniportAdapterContext,
342 IN PNDIS_PACKET Packet
343 );
345 BOOLEAN
346 XenNet_RxInit(xennet_info_t *xi);
348 BOOLEAN
349 XenNet_RxShutdown(xennet_info_t *xi);
351 VOID
352 XenNet_RxResumeStart(xennet_info_t *xi);
354 VOID
355 XenNet_RxResumeEnd(xennet_info_t *xi);
357 VOID
358 XenNet_TxBufferGC(PKDPC dpc, PVOID context, PVOID arg1, PVOID arg2);
360 VOID
361 XenNet_TxResumeStart(xennet_info_t *xi);
363 VOID
364 XenNet_TxResumeEnd(xennet_info_t *xi);
366 VOID DDKAPI
367 XenNet_SendPackets(
368 IN NDIS_HANDLE MiniportAdapterContext,
369 IN PPNDIS_PACKET PacketArray,
370 IN UINT NumberOfPackets
371 );
373 VOID
374 XenNet_CancelSendPackets(
375 NDIS_HANDLE MiniportAdapterContext,
376 PVOID CancelId);
378 BOOLEAN
379 XenNet_TxInit(xennet_info_t *xi);
381 BOOLEAN
382 XenNet_TxShutdown(xennet_info_t *xi);
384 NDIS_STATUS DDKAPI
385 XenNet_QueryInformation(
386 IN NDIS_HANDLE MiniportAdapterContext,
387 IN NDIS_OID Oid,
388 IN PVOID InformationBuffer,
389 IN ULONG InformationBufferLength,
390 OUT PULONG BytesWritten,
391 OUT PULONG BytesNeeded);
393 NDIS_STATUS DDKAPI
394 XenNet_SetInformation(
395 IN NDIS_HANDLE MiniportAdapterContext,
396 IN NDIS_OID Oid,
397 IN PVOID InformationBuffer,
398 IN ULONG InformationBufferLength,
399 OUT PULONG BytesRead,
400 OUT PULONG BytesNeeded
401 );
403 /* return values */
404 #define PARSE_OK 0
405 #define PARSE_TOO_SMALL 1 /* first buffer is too small */
406 #define PARSE_UNKNOWN_TYPE 2
408 ULONG
409 XenNet_ParsePacketHeader(packet_info_t *pi, PUCHAR buffer, ULONG min_header_size);
411 VOID
412 XenNet_SumIpHeader(
413 PUCHAR header,
414 USHORT ip4_header_length
415 );
417 static __forceinline VOID
418 XenNet_ClearPacketInfo(packet_info_t *pi)
419 {
420 #if 1
421 #if 0
422 RtlZeroMemory(&pi->mdl_count, sizeof(packet_info_t) - FIELD_OFFSET(packet_info_t, mdl_count));
423 #else
424 RtlZeroMemory(pi, sizeof(packet_info_t));
425 #endif
426 #else
427 pi->mdl_count = 0;
428 pi->curr_mdl_index = pi->curr_mdl_offset = 0;
429 pi->extra_info = pi->more_frags = pi->csum_blank =
430 pi->data_validated = pi->split_required = 0;
431 #endif
432 }