win-pvdrivers

view xennet/xennet.h @ 595:63a4d934929f

renamed header buffer to coalesce buffer (hb -> cb etc) ready for changes to make xennet work without sg
author James Harper <james.harper@bendigoit.com.au>
date Thu Jun 25 21:09:37 2009 +1000 (2009-06-25)
parents dc0a293c870c
children 214866b0a8fd
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 UCHAR header_data[132]; /* maximum possible size of ETH + IP + TCP/UDP headers */
205 ULONG mdl_count;
206 USHORT curr_mdl_offset;
207 USHORT mss;
208 NDIS_TCP_IP_CHECKSUM_PACKET_INFO csum_info;
209 BOOLEAN csum_blank;
210 BOOLEAN data_validated;
211 BOOLEAN split_required;
212 UCHAR ip_version;
213 PUCHAR header;
214 ULONG first_buffer_length;
215 ULONG header_length;
216 UCHAR ip_proto;
217 ULONG total_length;
218 USHORT ip4_header_length;
219 USHORT ip4_length;
220 USHORT tcp_header_length;
221 BOOLEAN tcp_has_options;
222 USHORT tcp_length;
223 USHORT tcp_remaining;
224 ULONG tcp_seq;
225 BOOLEAN extra_info;
226 BOOLEAN more_frags;
227 } packet_info_t;
229 #define PAGE_LIST_SIZE (max(NET_RX_RING_SIZE, NET_TX_RING_SIZE) * 4)
230 #define MULTICAST_LIST_MAX_SIZE 32
232 struct xennet_info
233 {
234 BOOLEAN inactive;
236 /* Base device vars */
237 PDEVICE_OBJECT pdo;
238 PDEVICE_OBJECT fdo;
239 PDEVICE_OBJECT lower_do;
240 //WDFDEVICE wdf_device;
241 WCHAR dev_desc[NAME_SIZE];
243 /* NDIS-related vars */
244 NDIS_HANDLE adapter_handle;
245 NDIS_MINIPORT_INTERRUPT interrupt;
246 ULONG packet_filter;
247 BOOLEAN connected;
248 BOOLEAN shutting_down;
249 uint8_t perm_mac_addr[ETH_ALEN];
250 uint8_t curr_mac_addr[ETH_ALEN];
252 /* Misc. Xen vars */
253 XENPCI_VECTORS vectors;
254 PXENPCI_DEVICE_STATE device_state;
255 evtchn_port_t event_channel;
256 ULONG state;
257 char backend_path[MAX_XENBUS_STR_LEN];
258 ULONG backend_state;
259 PVOID config_page;
260 UCHAR multicast_list[MULTICAST_LIST_MAX_SIZE][6];
261 ULONG multicast_list_size;
262 KDPC suspend_dpc;
263 PIO_WORKITEM resume_work_item;
265 /* tx related - protected by tx_lock */
266 KSPIN_LOCK tx_lock;
267 LIST_ENTRY tx_waiting_pkt_list;
268 struct netif_tx_front_ring tx;
269 ULONG tx_ring_free;
270 tx_shadow_t tx_shadows[NET_TX_RING_SIZE];
271 NDIS_HANDLE tx_buffer_pool;
272 #define TX_HEADER_BUFFER_SIZE 512
273 //#define TX_COALESCE_BUFFERS (NET_TX_RING_SIZE >> 2)
274 #define TX_COALESCE_BUFFERS (NET_TX_RING_SIZE)
275 KEVENT tx_idle_event;
276 ULONG tx_outstanding;
277 ULONG tx_id_free;
278 USHORT tx_id_list[NET_TX_RING_SIZE];
279 ULONG tx_cb_free;
280 ULONG tx_cb_list[TX_COALESCE_BUFFERS];
281 shared_buffer_t tx_cbs[TX_COALESCE_BUFFERS];
282 KDPC tx_dpc;
284 /* rx_related - protected by rx_lock */
285 KSPIN_LOCK rx_lock;
286 struct netif_rx_front_ring rx;
287 ULONG rx_id_free;
288 packet_info_t rxpi;
289 PNDIS_PACKET rx_packet_list[NET_RX_RING_SIZE * 2];
290 ULONG rx_packet_free;
291 KEVENT packet_returned_event;
292 //NDIS_MINIPORT_TIMER rx_timer;
293 KDPC rx_dpc;
294 KTIMER rx_timer;
295 KDPC rx_timer_dpc;
296 NDIS_HANDLE rx_packet_pool;
297 NDIS_HANDLE rx_buffer_pool;
298 ULONG rx_pb_free;
299 #define RX_PAGE_BUFFERS (NET_RX_RING_SIZE * 2)
300 ULONG rx_pb_list[RX_PAGE_BUFFERS];
301 shared_buffer_t rx_pbs[RX_PAGE_BUFFERS];
302 USHORT rx_ring_pbs[NET_RX_RING_SIZE];
303 #define LOOKASIDE_LIST_ALLOC_SIZE 256
304 NPAGED_LOOKASIDE_LIST rx_lookaside_list;
305 /* Receive-ring batched refills. */
306 ULONG rx_target;
307 ULONG rx_max_target;
308 ULONG rx_min_target;
310 /* how many packets are in the net stack atm */
311 ULONG rx_outstanding;
313 /* config vars from registry */
314 ULONG config_sg;
315 ULONG config_csum;
316 ULONG config_csum_rx_check;
317 ULONG config_gso;
318 ULONG config_mtu;
319 ULONG config_rx_interrupt_moderation;
321 NDIS_TASK_TCP_IP_CHECKSUM setting_csum;
322 ULONG setting_max_offload;
324 /* config stuff calculated from the above */
325 ULONG config_max_pkt_size;
327 /* stats */
328 ULONG64 stat_tx_ok;
329 ULONG64 stat_rx_ok;
330 ULONG64 stat_tx_error;
331 ULONG64 stat_rx_error;
332 ULONG64 stat_rx_no_buffer;
334 } typedef xennet_info_t;
336 VOID DDKAPI
337 XenNet_ReturnPacket(
338 IN NDIS_HANDLE MiniportAdapterContext,
339 IN PNDIS_PACKET Packet
340 );
342 BOOLEAN
343 XenNet_RxInit(xennet_info_t *xi);
345 BOOLEAN
346 XenNet_RxShutdown(xennet_info_t *xi);
348 VOID
349 XenNet_RxResumeStart(xennet_info_t *xi);
351 VOID
352 XenNet_RxResumeEnd(xennet_info_t *xi);
354 VOID
355 XenNet_TxBufferGC(PKDPC dpc, PVOID context, PVOID arg1, PVOID arg2);
357 VOID
358 XenNet_TxResumeStart(xennet_info_t *xi);
360 VOID
361 XenNet_TxResumeEnd(xennet_info_t *xi);
363 VOID DDKAPI
364 XenNet_SendPackets(
365 IN NDIS_HANDLE MiniportAdapterContext,
366 IN PPNDIS_PACKET PacketArray,
367 IN UINT NumberOfPackets
368 );
370 BOOLEAN
371 XenNet_TxInit(xennet_info_t *xi);
373 BOOLEAN
374 XenNet_TxShutdown(xennet_info_t *xi);
376 NDIS_STATUS DDKAPI
377 XenNet_QueryInformation(
378 IN NDIS_HANDLE MiniportAdapterContext,
379 IN NDIS_OID Oid,
380 IN PVOID InformationBuffer,
381 IN ULONG InformationBufferLength,
382 OUT PULONG BytesWritten,
383 OUT PULONG BytesNeeded);
385 NDIS_STATUS DDKAPI
386 XenNet_SetInformation(
387 IN NDIS_HANDLE MiniportAdapterContext,
388 IN NDIS_OID Oid,
389 IN PVOID InformationBuffer,
390 IN ULONG InformationBufferLength,
391 OUT PULONG BytesRead,
392 OUT PULONG BytesNeeded
393 );
395 /* return values */
396 #define PARSE_OK 0
397 #define PARSE_TOO_SMALL 1 /* first buffer is too small */
398 #define PARSE_UNKNOWN_TYPE 2
400 ULONG
401 XenNet_ParsePacketHeader(packet_info_t *pi);
403 VOID
404 XenNet_SumIpHeader(
405 PUCHAR header,
406 USHORT ip4_header_length
407 );
409 static __forceinline VOID
410 XenNet_ClearPacketInfo(packet_info_t *pi)
411 {
412 #if 1
413 #if 0
414 RtlZeroMemory(&pi->mdl_count, sizeof(packet_info_t) - FIELD_OFFSET(packet_info_t, mdl_count));
415 #else
416 RtlZeroMemory(pi, sizeof(packet_info_t));
417 #endif
418 #else
419 pi->mdl_count = 0;
420 pi->curr_mdl_index = pi->curr_mdl_offset = 0;
421 pi->extra_info = pi->more_frags = pi->csum_blank =
422 pi->data_validated = pi->split_required = 0;
423 #endif
424 }