win-pvdrivers

view xennet/xennet.h @ 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 565483912dc0
children 1e47fb7bce04
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
87 #define MIN_LARGE_SEND_SEGMENTS 4
89 /* TODO: crank this up if we support higher mtus? */
90 #define XN_DATA_SIZE 1500
91 #define XN_HDR_SIZE 14
92 #define XN_MIN_PKT_SIZE 60
93 /*
94 #if !defined(OFFLOAD_LARGE_SEND)
95 #define XN_MAX_PKT_SIZE (XN_HDR_SIZE + XN_DATA_SIZE)
96 #else
97 #define XN_MAX_PKT_SIZE MAX_LARGE_SEND_OFFLOAD
98 #endif
99 */
101 #define XN_MAX_SEND_PKTS 16
103 #define XN_RX_QUEUE_LEN 256
104 #define XENSOURCE_MAC_HDR 0x00163E
105 #define XN_VENDOR_DESC "Xensource"
106 #define MAX_XENBUS_STR_LEN 128
108 #define RX_MIN_TARGET 8
109 #define RX_DFL_MIN_TARGET 128
110 #define RX_MAX_TARGET min(NET_RX_RING_SIZE, 256)
112 #define MAX_BUFFERS_PER_PACKET 32
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 struct xennet_info
139 {
140 /* Base device vars */
141 PDEVICE_OBJECT pdo;
142 PDEVICE_OBJECT fdo;
143 PDEVICE_OBJECT lower_do;
144 WDFDEVICE wdf_device;
145 WCHAR dev_desc[NAME_SIZE];
147 /* NDIS-related vars */
148 NDIS_HANDLE adapter_handle;
149 NDIS_HANDLE packet_pool;
150 NDIS_HANDLE buffer_pool;
151 ULONG packet_filter;
152 int connected;
153 UINT8 perm_mac_addr[ETH_ALEN];
154 UINT8 curr_mac_addr[ETH_ALEN];
156 /* Misc. Xen vars */
157 XEN_IFACE XenInterface;
158 PXENPCI_XEN_DEVICE_DATA pdo_data;
159 evtchn_port_t event_channel;
160 ULONG state;
161 KEVENT backend_state_change_event;
162 KEVENT shutdown_event;
163 char backend_path[MAX_XENBUS_STR_LEN];
164 ULONG backend_state;
166 /* Xen ring-related vars */
167 KSPIN_LOCK rx_lock;
169 /* tx related - protected by tx_lock */
170 KSPIN_LOCK tx_lock;
171 LIST_ENTRY tx_waiting_pkt_list;
172 struct netif_tx_front_ring tx;
173 grant_ref_t tx_ring_ref;
174 struct netif_tx_sring *tx_pgs;
175 PMDL tx_mdl;
176 ULONG tx_id_free;
177 ULONG tx_no_id_free;
178 USHORT tx_id_list[NET_TX_RING_SIZE];
179 ULONG tx_gref_free;
180 grant_ref_t tx_gref_list[NET_TX_RING_SIZE];
181 PNDIS_PACKET tx_pkts[NET_TX_RING_SIZE];
182 PNDIS_BUFFER tx_mdls[NET_TX_RING_SIZE];
183 grant_ref_t tx_grefs[NET_TX_RING_SIZE];
185 /* rx_related - protected by rx_lock */
186 struct netif_rx_front_ring rx;
187 grant_ref_t rx_ring_ref;
188 struct netif_rx_sring *rx_pgs;
189 PMDL rx_mdl;
190 ULONG rx_id_free;
191 PNDIS_BUFFER rx_buffers[NET_RX_RING_SIZE];
192 PMDL page_list[NET_RX_RING_SIZE];
193 ULONG page_free;
195 packet_info_t rxpi;
197 /* Receive-ring batched refills. */
198 ULONG rx_target;
199 ULONG rx_max_target;
200 ULONG rx_min_target;
202 /* how many packets are in the net stack atm */
203 LONG rx_outstanding;
204 LONG tx_outstanding;
206 /* config vars from registry */
207 ULONG config_sg;
208 ULONG config_csum;
209 ULONG config_gso;
210 ULONG config_mtu;
212 NDIS_TASK_TCP_IP_CHECKSUM setting_csum;
213 ULONG setting_max_offload;
215 /* config stuff calculated from the above */
216 ULONG config_max_pkt_size;
218 /* stats */
219 ULONG64 stat_tx_ok;
220 ULONG64 stat_rx_ok;
221 ULONG64 stat_tx_error;
222 ULONG64 stat_rx_error;
223 ULONG64 stat_rx_no_buffer;
224 } typedef xennet_info_t;
227 extern LARGE_INTEGER ProfTime_TxBufferGC;
228 extern LARGE_INTEGER ProfTime_TxBufferFree;
229 extern LARGE_INTEGER ProfTime_RxBufferAlloc;
230 extern LARGE_INTEGER ProfTime_RxBufferFree;
231 extern LARGE_INTEGER ProfTime_ReturnPacket;
232 extern LARGE_INTEGER ProfTime_RxBufferCheck;
233 extern LARGE_INTEGER ProfTime_RxBufferCheckTopHalf;
234 extern LARGE_INTEGER ProfTime_RxBufferCheckBotHalf;
235 extern LARGE_INTEGER ProfTime_Linearize;
236 extern LARGE_INTEGER ProfTime_SendPackets;
237 extern LARGE_INTEGER ProfTime_SendQueuedPackets;
239 extern int ProfCount_TxBufferGC;
240 extern int ProfCount_TxBufferFree;
241 extern int ProfCount_RxBufferAlloc;
242 extern int ProfCount_RxBufferFree;
243 extern int ProfCount_ReturnPacket;
244 extern int ProfCount_RxBufferCheck;
245 extern int ProfCount_Linearize;
246 extern int ProfCount_SendPackets;
247 extern int ProfCount_PacketsPerSendPackets;
248 extern int ProfCount_SendQueuedPackets;
250 extern int ProfCount_TxPacketsTotal;
251 extern int ProfCount_TxPacketsCsumOffload;
252 extern int ProfCount_TxPacketsLargeOffload;
253 extern int ProfCount_RxPacketsTotal;
254 extern int ProfCount_RxPacketsCsumOffload;
255 extern int ProfCount_CallsToIndicateReceive;
257 NDIS_STATUS
258 XenNet_RxBufferCheck(struct xennet_info *xi);
260 VOID
261 XenNet_ReturnPacket(
262 IN NDIS_HANDLE MiniportAdapterContext,
263 IN PNDIS_PACKET Packet
264 );
266 BOOLEAN
267 XenNet_RxInit(xennet_info_t *xi);
269 BOOLEAN
270 XenNet_RxShutdown(xennet_info_t *xi);
272 NDIS_STATUS
273 XenNet_TxBufferGC(struct xennet_info *xi);
275 VOID
276 XenNet_SendPackets(
277 IN NDIS_HANDLE MiniportAdapterContext,
278 IN PPNDIS_PACKET PacketArray,
279 IN UINT NumberOfPackets
280 );
282 BOOLEAN
283 XenNet_TxInit(xennet_info_t *xi);
285 BOOLEAN
286 XenNet_TxShutdown(xennet_info_t *xi);
288 NDIS_STATUS
289 XenNet_QueryInformation(
290 IN NDIS_HANDLE MiniportAdapterContext,
291 IN NDIS_OID Oid,
292 IN PVOID InformationBuffer,
293 IN ULONG InformationBufferLength,
294 OUT PULONG BytesWritten,
295 OUT PULONG BytesNeeded);
297 NDIS_STATUS
298 XenNet_SetInformation(
299 IN NDIS_HANDLE MiniportAdapterContext,
300 IN NDIS_OID Oid,
301 IN PVOID InformationBuffer,
302 IN ULONG InformationBufferLength,
303 OUT PULONG BytesRead,
304 OUT PULONG BytesNeeded
305 );
307 PUCHAR
308 XenNet_GetData(
309 packet_info_t *pi,
310 USHORT req_length,
311 PUSHORT length
312 );
315 /* return values */
316 #define PARSE_OK 0
317 #define PARSE_TOO_SMALL 1 /* first buffer is too small */
318 #define PARSE_UNKNOWN_TYPE 2
320 ULONG
321 XenNet_ParsePacketHeader(
322 packet_info_t *pi
323 );
325 VOID
326 XenNet_SumIpHeader(
327 PUCHAR header,
328 USHORT ip4_header_length
329 );