win-pvdrivers

view xennet/xennet.h @ 370:d76831a77d19

merge
author Andy Grover <andy.grover@oracle.com>
date Wed Jul 09 00:26:05 2008 -0700 (2008-07-09)
parents 5a762fd1fba9
children b9028997f48b
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 __DRIVER_NAME "XenNet"
48 #include <xen_windows.h>
49 #include <memory.h>
50 #include <grant_table.h>
51 #include <event_channel.h>
52 #include <hvm/params.h>
53 #include <hvm/hvm_op.h>
54 #include <xen_public.h>
55 #include <io/ring.h>
56 #include <io/netif.h>
57 #include <io/xenbus.h>
58 #include <stdlib.h>
59 #define XENNET_POOL_TAG (ULONG) 'XenN'
62 /* Xen macros use these, so they need to be redefined to Win equivs */
63 #define wmb() KeMemoryBarrier()
64 #define mb() KeMemoryBarrier()
66 #define GRANT_INVALID_REF 0
68 #define NAME_SIZE 64
70 #define ETH_ALEN 6
73 #define __NET_USHORT_BYTE_0(x) ((USHORT)(x & 0xFF))
74 #define __NET_USHORT_BYTE_1(x) ((USHORT)((PUCHAR)&x)[1] & 0xFF)
76 #define GET_NET_USHORT(x) ((__NET_USHORT_BYTE_0(x) << 8) | __NET_USHORT_BYTE_1(x))
77 #define SET_NET_USHORT(y, x) *((USHORT *)&(y)) = ((__NET_USHORT_BYTE_0(x) << 8) | __NET_USHORT_BYTE_1(x))
79 #define GET_NET_ULONG(x) ((GET_NET_USHORT(x) << 16) | GET_NET_USHORT(((PUCHAR)&x)[2]))
80 #define SET_NET_ULONG(y, x) *((ULONG *)&(y)) = ((GET_NET_USHORT(x) << 16) | GET_NET_USHORT(((PUCHAR)&x)[2]))
83 /* couldn't get regular xen ring macros to work...*/
84 #define __NET_RING_SIZE(type, _sz) \
85 (__RD32( \
86 (_sz - sizeof(struct type##_sring) + sizeof(union type##_sring_entry)) \
87 / sizeof(union type##_sring_entry)))
89 #define NET_TX_RING_SIZE __NET_RING_SIZE(netif_tx, PAGE_SIZE)
90 #define NET_RX_RING_SIZE __NET_RING_SIZE(netif_rx, PAGE_SIZE)
92 #pragma warning(disable: 4127) // conditional expression is constant
94 //#define XEN_PROFILE
96 #define MIN_LARGE_SEND_SEGMENTS 4
98 /* TODO: crank this up if we support higher mtus? */
99 #define XN_DATA_SIZE 1500
100 #define XN_HDR_SIZE 14
101 #define XN_MIN_PKT_SIZE 60
102 /*
103 #if !defined(OFFLOAD_LARGE_SEND)
104 #define XN_MAX_PKT_SIZE (XN_HDR_SIZE + XN_DATA_SIZE)
105 #else
106 #define XN_MAX_PKT_SIZE MAX_LARGE_SEND_OFFLOAD
107 #endif
108 */
110 #define XN_MAX_SEND_PKTS 16
112 #define XN_RX_QUEUE_LEN 256
113 #define XENSOURCE_MAC_HDR 0x00163E
114 #define XN_VENDOR_DESC "Xensource"
115 #define MAX_XENBUS_STR_LEN 128
117 #define RX_MIN_TARGET 8
118 #define RX_DFL_MIN_TARGET 256
119 #define RX_MAX_TARGET min(NET_RX_RING_SIZE, 256)
121 #define MAX_BUFFERS_PER_PACKET 128
123 typedef struct {
124 PNDIS_BUFFER mdls[MAX_BUFFERS_PER_PACKET];
125 ULONG mdl_count;
126 USHORT curr_mdl;
127 USHORT curr_mdl_offset;
128 USHORT mss;
129 NDIS_TCP_IP_CHECKSUM_PACKET_INFO csum_info;
130 BOOLEAN csum_calc_required;
131 BOOLEAN split_required;
132 UCHAR ip_version;
133 PUCHAR header;
134 UCHAR ip_proto;
135 USHORT total_length;
136 USHORT ip4_header_length;
137 USHORT ip4_length;
138 USHORT tcp_header_length;
139 USHORT tcp_length;
140 USHORT tcp_remaining;
141 ULONG tcp_seq;
142 BOOLEAN extra_info;
143 BOOLEAN more_frags;
144 } packet_info_t;
146 #define PAGE_LIST_SIZE (max(NET_RX_RING_SIZE, NET_TX_RING_SIZE) * 4)
147 typedef struct
148 {
149 struct xennet_info *xi;
150 PMDL page_list[PAGE_LIST_SIZE];
151 ULONG page_free;
152 ULONG page_free_lowest;
153 ULONG page_free_target;
154 NDIS_MINIPORT_TIMER timer;
155 PKSPIN_LOCK lock;
156 BOOLEAN grants_resumed;
157 } freelist_t;
159 struct xennet_info
160 {
161 /* Base device vars */
162 PDEVICE_OBJECT pdo;
163 PDEVICE_OBJECT fdo;
164 PDEVICE_OBJECT lower_do;
165 //WDFDEVICE wdf_device;
166 WCHAR dev_desc[NAME_SIZE];
168 /* NDIS-related vars */
169 NDIS_HANDLE adapter_handle;
170 NDIS_HANDLE packet_pool;
171 NDIS_HANDLE buffer_pool;
172 NDIS_MINIPORT_INTERRUPT interrupt;
173 ULONG packet_filter;
174 int connected;
175 uint8_t perm_mac_addr[ETH_ALEN];
176 uint8_t curr_mac_addr[ETH_ALEN];
178 /* Misc. Xen vars */
179 XENPCI_VECTORS vectors;
180 PXENPCI_DEVICE_STATE device_state;
181 evtchn_port_t event_channel;
182 ULONG state;
183 KEVENT shutdown_event;
184 char backend_path[MAX_XENBUS_STR_LEN];
185 ULONG backend_state;
186 PVOID config_page;
188 /* Xen ring-related vars */
189 KSPIN_LOCK rx_lock;
191 /* tx related - protected by tx_lock */
192 KSPIN_LOCK tx_lock;
193 LIST_ENTRY tx_waiting_pkt_list;
194 struct netif_tx_front_ring tx;
195 ULONG tx_id_free;
196 ULONG tx_no_id_used;
197 USHORT tx_id_list[NET_TX_RING_SIZE];
198 PNDIS_PACKET tx_pkts[NET_TX_RING_SIZE];
199 PNDIS_BUFFER tx_mdls[NET_TX_RING_SIZE];
200 freelist_t tx_freelist;
202 /* rx_related - protected by rx_lock */
203 struct netif_rx_front_ring rx;
204 ULONG rx_id_free;
205 PNDIS_BUFFER rx_mdls[NET_RX_RING_SIZE];
206 freelist_t rx_freelist;
207 packet_info_t rxpi;
208 PNDIS_PACKET rx_packet_list[NET_RX_RING_SIZE * 2];
209 ULONG rx_packet_free;
211 /* Receive-ring batched refills. */
212 ULONG rx_target;
213 ULONG rx_max_target;
214 ULONG rx_min_target;
216 /* how many packets are in the net stack atm */
217 LONG rx_outstanding;
219 /* config vars from registry */
220 ULONG config_sg;
221 ULONG config_csum;
222 ULONG config_gso;
223 ULONG config_mtu;
225 NDIS_TASK_TCP_IP_CHECKSUM setting_csum;
226 ULONG setting_max_offload;
228 /* config stuff calculated from the above */
229 ULONG config_max_pkt_size;
231 NDIS_MINIPORT_TIMER resume_timer;
233 /* stats */
234 ULONG64 stat_tx_ok;
235 ULONG64 stat_rx_ok;
236 ULONG64 stat_tx_error;
237 ULONG64 stat_rx_error;
238 ULONG64 stat_rx_no_buffer;
239 } typedef xennet_info_t;
242 extern LARGE_INTEGER ProfTime_TxBufferGC;
243 extern LARGE_INTEGER ProfTime_TxBufferFree;
244 extern LARGE_INTEGER ProfTime_RxBufferAlloc;
245 extern LARGE_INTEGER ProfTime_RxBufferFree;
246 extern LARGE_INTEGER ProfTime_ReturnPacket;
247 extern LARGE_INTEGER ProfTime_RxBufferCheck;
248 extern LARGE_INTEGER ProfTime_RxBufferCheckTopHalf;
249 extern LARGE_INTEGER ProfTime_RxBufferCheckBotHalf;
250 extern LARGE_INTEGER ProfTime_Linearize;
251 extern LARGE_INTEGER ProfTime_SendPackets;
252 extern LARGE_INTEGER ProfTime_SendQueuedPackets;
254 extern int ProfCount_TxBufferGC;
255 extern int ProfCount_TxBufferFree;
256 extern int ProfCount_RxBufferAlloc;
257 extern int ProfCount_RxBufferFree;
258 extern int ProfCount_ReturnPacket;
259 extern int ProfCount_RxBufferCheck;
260 extern int ProfCount_Linearize;
261 extern int ProfCount_SendPackets;
262 extern int ProfCount_PacketsPerSendPackets;
263 extern int ProfCount_SendQueuedPackets;
265 extern int ProfCount_TxPacketsTotal;
266 extern int ProfCount_TxPacketsCsumOffload;
267 extern int ProfCount_TxPacketsLargeOffload;
268 extern int ProfCount_RxPacketsTotal;
269 extern int ProfCount_RxPacketsCsumOffload;
270 extern int ProfCount_CallsToIndicateReceive;
272 NDIS_STATUS
273 XenNet_RxBufferCheck(struct xennet_info *xi);
275 VOID DDKAPI
276 XenNet_ReturnPacket(
277 IN NDIS_HANDLE MiniportAdapterContext,
278 IN PNDIS_PACKET Packet
279 );
281 BOOLEAN
282 XenNet_RxInit(xennet_info_t *xi);
284 BOOLEAN
285 XenNet_RxShutdown(xennet_info_t *xi);
287 VOID
288 XenNet_RxResumeStart(xennet_info_t *xi);
290 VOID
291 XenNet_RxResumeEnd(xennet_info_t *xi);
293 NDIS_STATUS
294 XenNet_TxBufferGC(struct xennet_info *xi);
296 VOID
297 XenNet_TxResumeStart(xennet_info_t *xi);
299 VOID
300 XenNet_TxResumeEnd(xennet_info_t *xi);
302 VOID DDKAPI
303 XenNet_SendPackets(
304 IN NDIS_HANDLE MiniportAdapterContext,
305 IN PPNDIS_PACKET PacketArray,
306 IN UINT NumberOfPackets
307 );
309 BOOLEAN
310 XenNet_TxInit(xennet_info_t *xi);
312 BOOLEAN
313 XenNet_TxShutdown(xennet_info_t *xi);
315 NDIS_STATUS DDKAPI
316 XenNet_QueryInformation(
317 IN NDIS_HANDLE MiniportAdapterContext,
318 IN NDIS_OID Oid,
319 IN PVOID InformationBuffer,
320 IN ULONG InformationBufferLength,
321 OUT PULONG BytesWritten,
322 OUT PULONG BytesNeeded);
324 NDIS_STATUS DDKAPI
325 XenNet_SetInformation(
326 IN NDIS_HANDLE MiniportAdapterContext,
327 IN NDIS_OID Oid,
328 IN PVOID InformationBuffer,
329 IN ULONG InformationBufferLength,
330 OUT PULONG BytesRead,
331 OUT PULONG BytesNeeded
332 );
334 PUCHAR
335 XenNet_GetData(
336 packet_info_t *pi,
337 USHORT req_length,
338 PUSHORT length
339 );
342 /* return values */
343 #define PARSE_OK 0
344 #define PARSE_TOO_SMALL 1 /* first buffer is too small */
345 #define PARSE_UNKNOWN_TYPE 2
347 ULONG
348 XenNet_ParsePacketHeader(
349 packet_info_t *pi
350 );
352 VOID
353 XenNet_SumIpHeader(
354 PUCHAR header,
355 USHORT ip4_header_length
356 );
358 static __inline grant_ref_t
359 get_grant_ref(PMDL mdl)
360 {
361 return *(grant_ref_t *)(((UCHAR *)mdl) + MmSizeOfMdl(0, PAGE_SIZE));
362 }
364 VOID
365 XenFreelist_Init(struct xennet_info *xi, freelist_t *fl, PKSPIN_LOCK lock);
366 PMDL
367 XenFreelist_GetPage(freelist_t *fl);
368 VOID
369 XenFreelist_PutPage(freelist_t *fl, PMDL mdl);
370 VOID
371 XenFreelist_Dispose(freelist_t *fl);
372 VOID
373 XenFreelist_ResumeStart(freelist_t *fl);
374 VOID
375 XenFreelist_ResumeEnd(freelist_t *fl);