win-pvdrivers

view xennet/xennet.h @ 266:b88529df8b60

More wdm updates
author James Harper <james.harper@bendigoit.com.au>
date Wed May 07 10:47:03 2008 +1000 (2008-05-07)
parents 253ec5052cb4
children da9b1e17fbc0
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 #include <wdm.h>
25 #include <wdf.h>
26 #include <wdfminiport.h>
27 #include <initguid.h>
28 #define NDIS_MINIPORT_DRIVER
29 #if NTDDI_VERSION < NTDDI_WINXP
30 # define NDIS50_MINIPORT 1
31 #else
32 # define NDIS51_MINIPORT 1
33 #endif
34 #include <ndis.h>
36 #define NTSTRSAFE_LIB
37 #include <ntstrsafe.h>
39 #define __DRIVER_NAME "XenNet"
41 #include <xen_windows.h>
42 #include <memory.h>
43 #include <grant_table.h>
44 #include <event_channel.h>
45 #include <hvm/params.h>
46 #include <hvm/hvm_op.h>
47 #include <xen_public.h>
48 #include <io/ring.h>
49 #include <io/netif.h>
50 #include <io/xenbus.h>
51 #include <stdlib.h>
52 #define XENNET_POOL_TAG (ULONG) 'XenN'
54 /* Xen macros use these, so they need to be redefined to Win equivs */
55 #define wmb() KeMemoryBarrier()
56 #define mb() KeMemoryBarrier()
58 #define GRANT_INVALID_REF 0
60 #define NAME_SIZE 64
62 #define ETH_ALEN 6
65 #define __NET_USHORT_BYTE_0(x) ((USHORT)(x & 0xFF))
66 #define __NET_USHORT_BYTE_1(x) ((USHORT)((PUCHAR)&x)[1] & 0xFF)
68 #define GET_NET_USHORT(x) ((__NET_USHORT_BYTE_0(x) << 8) | __NET_USHORT_BYTE_1(x))
69 #define SET_NET_USHORT(y, x) *((USHORT *)&(y)) = ((__NET_USHORT_BYTE_0(x) << 8) | __NET_USHORT_BYTE_1(x))
71 #define GET_NET_ULONG(x) ((GET_NET_USHORT(x) << 16) | GET_NET_USHORT(((PUCHAR)&x)[2]))
72 #define SET_NET_ULONG(y, x) *((ULONG *)&(y)) = ((GET_NET_USHORT(x) << 16) | GET_NET_USHORT(((PUCHAR)&x)[2]))
75 /* couldn't get regular xen ring macros to work...*/
76 #define __NET_RING_SIZE(type, _sz) \
77 (__RD32( \
78 (_sz - sizeof(struct type##_sring) + sizeof(union type##_sring_entry)) \
79 / sizeof(union type##_sring_entry)))
81 #define NET_TX_RING_SIZE __NET_RING_SIZE(netif_tx, PAGE_SIZE)
82 #define NET_RX_RING_SIZE __NET_RING_SIZE(netif_rx, PAGE_SIZE)
84 #pragma warning(disable: 4127) // conditional expression is constant
86 #define XEN_PROFILE
88 #define MIN_LARGE_SEND_SEGMENTS 4
90 /* TODO: crank this up if we support higher mtus? */
91 #define XN_DATA_SIZE 1500
92 #define XN_HDR_SIZE 14
93 #define XN_MIN_PKT_SIZE 60
94 /*
95 #if !defined(OFFLOAD_LARGE_SEND)
96 #define XN_MAX_PKT_SIZE (XN_HDR_SIZE + XN_DATA_SIZE)
97 #else
98 #define XN_MAX_PKT_SIZE MAX_LARGE_SEND_OFFLOAD
99 #endif
100 */
102 #define XN_MAX_SEND_PKTS 16
104 #define XN_RX_QUEUE_LEN 256
105 #define XENSOURCE_MAC_HDR 0x00163E
106 #define XN_VENDOR_DESC "Xensource"
107 #define MAX_XENBUS_STR_LEN 128
109 #define RX_MIN_TARGET 8
110 #define RX_DFL_MIN_TARGET 256
111 #define RX_MAX_TARGET min(NET_RX_RING_SIZE, 256)
113 #define MAX_BUFFERS_PER_PACKET 128
115 typedef struct {
116 PNDIS_BUFFER mdls[MAX_BUFFERS_PER_PACKET];
117 ULONG mdl_count;
118 USHORT curr_mdl;
119 USHORT curr_mdl_offset;
120 USHORT mss;
121 NDIS_TCP_IP_CHECKSUM_PACKET_INFO csum_info;
122 BOOLEAN csum_calc_required;
123 BOOLEAN split_required;
124 UCHAR ip_version;
125 PUCHAR header;
126 UCHAR ip_proto;
127 USHORT total_length;
128 USHORT ip4_header_length;
129 USHORT ip4_length;
130 USHORT tcp_header_length;
131 USHORT tcp_length;
132 USHORT tcp_remaining;
133 ULONG tcp_seq;
134 BOOLEAN extra_info;
135 BOOLEAN more_frags;
136 } packet_info_t;
138 typedef struct
139 {
140 struct xennet_info *xi;
141 PMDL page_list[NET_RX_RING_SIZE];
142 ULONG page_free;
143 ULONG page_free_lowest;
144 ULONG page_free_target;
145 NDIS_MINIPORT_TIMER timer;
146 PKSPIN_LOCK lock;
147 } freelist_t;
149 struct xennet_info
150 {
151 /* Base device vars */
152 PDEVICE_OBJECT pdo;
153 PDEVICE_OBJECT fdo;
154 PDEVICE_OBJECT lower_do;
155 WDFDEVICE wdf_device;
156 WCHAR dev_desc[NAME_SIZE];
158 /* NDIS-related vars */
159 NDIS_HANDLE adapter_handle;
160 NDIS_HANDLE packet_pool;
161 NDIS_HANDLE buffer_pool;
162 ULONG packet_filter;
163 int connected;
164 UINT8 perm_mac_addr[ETH_ALEN];
165 UINT8 curr_mac_addr[ETH_ALEN];
167 /* Misc. Xen vars */
168 XEN_IFACE XenInterface;
169 PXENPCI_XEN_DEVICE_DATA pdo_data;
170 evtchn_port_t event_channel;
171 ULONG state;
172 KEVENT backend_state_change_event;
173 KEVENT shutdown_event;
174 char backend_path[MAX_XENBUS_STR_LEN];
175 ULONG backend_state;
177 /* Xen ring-related vars */
178 KSPIN_LOCK rx_lock;
180 /* tx related - protected by tx_lock */
181 KSPIN_LOCK tx_lock;
182 LIST_ENTRY tx_waiting_pkt_list;
183 struct netif_tx_front_ring tx;
184 grant_ref_t tx_ring_ref;
185 struct netif_tx_sring *tx_pgs;
186 PMDL tx_mdl;
187 ULONG tx_id_free;
188 ULONG tx_no_id_used;
189 USHORT tx_id_list[NET_TX_RING_SIZE];
190 PNDIS_PACKET tx_pkts[NET_TX_RING_SIZE];
191 PNDIS_BUFFER tx_mdls[NET_TX_RING_SIZE];
192 freelist_t tx_freelist;
194 /* rx_related - protected by rx_lock */
195 struct netif_rx_front_ring rx;
196 grant_ref_t rx_ring_ref;
197 struct netif_rx_sring *rx_pgs;
198 PMDL rx_mdl;
199 ULONG rx_id_free;
200 PNDIS_BUFFER rx_buffers[NET_RX_RING_SIZE];
201 freelist_t rx_freelist;
202 packet_info_t rxpi;
203 PNDIS_PACKET rx_packet_list[NET_RX_RING_SIZE * 2];
204 ULONG rx_packet_free;
206 /* Receive-ring batched refills. */
207 ULONG rx_target;
208 ULONG rx_max_target;
209 ULONG rx_min_target;
211 /* how many packets are in the net stack atm */
212 LONG rx_outstanding;
214 /* config vars from registry */
215 ULONG config_sg;
216 ULONG config_csum;
217 ULONG config_gso;
218 ULONG config_mtu;
220 NDIS_TASK_TCP_IP_CHECKSUM setting_csum;
221 ULONG setting_max_offload;
223 /* config stuff calculated from the above */
224 ULONG config_max_pkt_size;
226 /* stats */
227 ULONG64 stat_tx_ok;
228 ULONG64 stat_rx_ok;
229 ULONG64 stat_tx_error;
230 ULONG64 stat_rx_error;
231 ULONG64 stat_rx_no_buffer;
232 } typedef xennet_info_t;
235 extern LARGE_INTEGER ProfTime_TxBufferGC;
236 extern LARGE_INTEGER ProfTime_TxBufferFree;
237 extern LARGE_INTEGER ProfTime_RxBufferAlloc;
238 extern LARGE_INTEGER ProfTime_RxBufferFree;
239 extern LARGE_INTEGER ProfTime_ReturnPacket;
240 extern LARGE_INTEGER ProfTime_RxBufferCheck;
241 extern LARGE_INTEGER ProfTime_RxBufferCheckTopHalf;
242 extern LARGE_INTEGER ProfTime_RxBufferCheckBotHalf;
243 extern LARGE_INTEGER ProfTime_Linearize;
244 extern LARGE_INTEGER ProfTime_SendPackets;
245 extern LARGE_INTEGER ProfTime_SendQueuedPackets;
247 extern int ProfCount_TxBufferGC;
248 extern int ProfCount_TxBufferFree;
249 extern int ProfCount_RxBufferAlloc;
250 extern int ProfCount_RxBufferFree;
251 extern int ProfCount_ReturnPacket;
252 extern int ProfCount_RxBufferCheck;
253 extern int ProfCount_Linearize;
254 extern int ProfCount_SendPackets;
255 extern int ProfCount_PacketsPerSendPackets;
256 extern int ProfCount_SendQueuedPackets;
258 extern int ProfCount_TxPacketsTotal;
259 extern int ProfCount_TxPacketsCsumOffload;
260 extern int ProfCount_TxPacketsLargeOffload;
261 extern int ProfCount_RxPacketsTotal;
262 extern int ProfCount_RxPacketsCsumOffload;
263 extern int ProfCount_CallsToIndicateReceive;
265 NDIS_STATUS
266 XenNet_RxBufferCheck(struct xennet_info *xi);
268 VOID
269 XenNet_ReturnPacket(
270 IN NDIS_HANDLE MiniportAdapterContext,
271 IN PNDIS_PACKET Packet
272 );
274 BOOLEAN
275 XenNet_RxInit(xennet_info_t *xi);
277 BOOLEAN
278 XenNet_RxShutdown(xennet_info_t *xi);
280 NDIS_STATUS
281 XenNet_TxBufferGC(struct xennet_info *xi);
283 VOID
284 XenNet_SendPackets(
285 IN NDIS_HANDLE MiniportAdapterContext,
286 IN PPNDIS_PACKET PacketArray,
287 IN UINT NumberOfPackets
288 );
290 BOOLEAN
291 XenNet_TxInit(xennet_info_t *xi);
293 BOOLEAN
294 XenNet_TxShutdown(xennet_info_t *xi);
296 NDIS_STATUS
297 XenNet_QueryInformation(
298 IN NDIS_HANDLE MiniportAdapterContext,
299 IN NDIS_OID Oid,
300 IN PVOID InformationBuffer,
301 IN ULONG InformationBufferLength,
302 OUT PULONG BytesWritten,
303 OUT PULONG BytesNeeded);
305 NDIS_STATUS
306 XenNet_SetInformation(
307 IN NDIS_HANDLE MiniportAdapterContext,
308 IN NDIS_OID Oid,
309 IN PVOID InformationBuffer,
310 IN ULONG InformationBufferLength,
311 OUT PULONG BytesRead,
312 OUT PULONG BytesNeeded
313 );
315 PUCHAR
316 XenNet_GetData(
317 packet_info_t *pi,
318 USHORT req_length,
319 PUSHORT length
320 );
323 /* return values */
324 #define PARSE_OK 0
325 #define PARSE_TOO_SMALL 1 /* first buffer is too small */
326 #define PARSE_UNKNOWN_TYPE 2
328 ULONG
329 XenNet_ParsePacketHeader(
330 packet_info_t *pi
331 );
333 VOID
334 XenNet_SumIpHeader(
335 PUCHAR header,
336 USHORT ip4_header_length
337 );
339 static __inline grant_ref_t
340 get_grant_ref(PMDL mdl)
341 {
342 return *(grant_ref_t *)(((UCHAR *)mdl) + MmSizeOfMdl(0, PAGE_SIZE));
343 }
345 VOID
346 XenFreelist_Init(struct xennet_info *xi, freelist_t *fl, PKSPIN_LOCK lock);
347 PMDL
348 XenFreelist_GetPage(freelist_t *fl);
349 VOID
350 XenFreelist_PutPage(freelist_t *fl, PMDL mdl);
351 VOID
352 XenFreelist_Dispose(freelist_t *fl);