win-pvdrivers
changeset 921:dc37dfde7673
NDIS6 appears to be working properly now. good speed in both directions
author | James Harper <james.harper@bendigoit.com.au> |
---|---|
date | Sat May 14 15:15:18 2011 +1000 (2011-05-14) |
parents | a61e4e452f43 |
children | 5604d7645acc |
files | xennet/xennet6.c xennet/xennet6.h xennet/xennet6_common.c xennet/xennet6_oid.c xennet/xennet6_rx.c xennet/xennet6_tx.c |
line diff
1.1 --- a/xennet/xennet6.c Sat May 14 15:14:52 2011 +1000 1.2 +++ b/xennet/xennet6.c Sat May 14 15:15:18 2011 +1000 1.3 @@ -135,13 +135,15 @@ XenNet_ConnectBackend(struct xennet_info 1.4 UCHAR type; 1.5 PCHAR setting, value, value2; 1.6 UINT i; 1.7 - ULONG backend_sg = 0; 1.8 - ULONG backend_gso = 0; 1.9 1.10 FUNCTION_ENTER(); 1.11 1.12 ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL); 1.13 1.14 + xi->backend_csum_supported = TRUE; /* just assume this */ 1.15 + xi->backend_gso_value = 0; 1.16 + xi->backend_sg_supported = FALSE; 1.17 + 1.18 ptr = xi->config_page; 1.19 while((type = GET_XEN_INIT_RSP(&ptr, (PVOID)&setting, (PVOID)&value, (PVOID)&value2)) != XEN_INIT_TYPE_END) 1.20 { 1.21 @@ -189,14 +191,14 @@ XenNet_ConnectBackend(struct xennet_info 1.22 { 1.23 if (atoi(value)) 1.24 { 1.25 - backend_sg = 1; 1.26 + xi->backend_sg_supported = TRUE; 1.27 } 1.28 } 1.29 else if (strcmp(setting, "feature-gso-tcpv4") == 0) 1.30 { 1.31 if (atoi(value)) 1.32 { 1.33 - backend_gso = 1; 1.34 + xi->backend_gso_value = xi->frontend_gso_value; 1.35 } 1.36 } 1.37 break; 1.38 @@ -222,20 +224,19 @@ XenNet_ConnectBackend(struct xennet_info 1.39 break; 1.40 } 1.41 } 1.42 - if (xi->config_sg && !backend_sg) 1.43 - { 1.44 - KdPrint((__DRIVER_NAME " SG not supported by backend - disabling\n")); 1.45 - xi->config_sg = 0; 1.46 - } 1.47 - if (xi->config_gso && !backend_gso) 1.48 - { 1.49 - KdPrint((__DRIVER_NAME " GSO not supported by backend - disabling\n")); 1.50 - xi->config_gso = 0; 1.51 - } 1.52 + if (!xi->backend_sg_supported) 1.53 + xi->backend_gso_value = min(xi->backend_gso_value, PAGE_SIZE - MAX_PKT_HEADER_LENGTH); 1.54 + 1.55 + xi->current_sg_supported = xi->frontend_sg_supported && xi->backend_sg_supported; 1.56 + xi->current_csum_supported = xi->frontend_csum_supported && xi->backend_csum_supported; 1.57 + xi->current_gso_value = min(xi->backend_gso_value, xi->backend_gso_value); 1.58 + xi->current_mtu_value = xi->frontend_mtu_value; 1.59 + xi->current_gso_rx_split_type = xi->frontend_gso_rx_split_type; 1.60 + 1.61 FUNCTION_EXIT(); 1.62 1.63 return NDIS_STATUS_SUCCESS; 1.64 -} 1.65 +} /* XenNet_ConnectBackend */ 1.66 1.67 static VOID 1.68 XenNet_ResumeWorkItem(PDEVICE_OBJECT device_object, PVOID context) 1.69 @@ -344,7 +345,6 @@ XenNet_HandleEvent(PVOID context) 1.70 { 1.71 struct xennet_info *xi = context; 1.72 ULONG suspend_resume_state_pdo; 1.73 - LARGE_INTEGER dpc_requeued; 1.74 1.75 //FUNCTION_ENTER(); 1.76 suspend_resume_state_pdo = xi->device_state->suspend_resume_state_pdo; 1.77 @@ -430,11 +430,11 @@ XenNet_D0Entry(struct xennet_info *xi) 1.78 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_READ_STRING_BACK, "feature-gso-tcpv4", NULL, NULL); 1.79 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_WRITE_STRING, "request-rx-copy", "1", NULL); 1.80 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_WRITE_STRING, "feature-rx-notify", "1", NULL); 1.81 - RtlStringCbPrintfA(buf, ARRAY_SIZE(buf), "%d", !xi->config_csum); 1.82 + RtlStringCbPrintfA(buf, ARRAY_SIZE(buf), "%d", !xi->frontend_csum_supported); 1.83 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_WRITE_STRING, "feature-no-csum-offload", buf, NULL); 1.84 - RtlStringCbPrintfA(buf, ARRAY_SIZE(buf), "%d", (int)xi->config_sg); 1.85 + RtlStringCbPrintfA(buf, ARRAY_SIZE(buf), "%d", (int)xi->frontend_sg_supported); 1.86 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_WRITE_STRING, "feature-sg", buf, NULL); 1.87 - RtlStringCbPrintfA(buf, ARRAY_SIZE(buf), "%d", !!xi->config_gso); 1.88 + RtlStringCbPrintfA(buf, ARRAY_SIZE(buf), "%d", !!xi->frontend_gso_value); 1.89 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_WRITE_STRING, "feature-gso-tcpv4", buf, NULL); 1.90 ADD_XEN_INIT_REQ(&ptr, XEN_INIT_TYPE_XB_STATE_MAP_PRE_CONNECT, NULL, NULL, NULL); 1.91 __ADD_XEN_INIT_UCHAR(&ptr, 0); /* no pre-connect required */ 1.92 @@ -471,12 +471,6 @@ XenNet_D0Entry(struct xennet_info *xi) 1.93 return status; 1.94 } 1.95 1.96 - if (!xi->config_sg) 1.97 - { 1.98 - /* without SG, GSO can be a maximum of PAGE_SIZE */ 1.99 - xi->config_gso = min(xi->config_gso, PAGE_SIZE); 1.100 - } 1.101 - 1.102 XenNet_TxInit(xi); 1.103 XenNet_RxInit(xi); 1.104 1.105 @@ -593,12 +587,14 @@ XenNet_Initialize(NDIS_HANDLE adapter_ha 1.106 xi->current_lookahead = MIN_LOOKAHEAD_LENGTH; 1.107 1.108 xi->event_channel = 0; 1.109 +#if 0 1.110 xi->config_csum = 1; 1.111 xi->config_csum_rx_check = 1; 1.112 xi->config_sg = 1; 1.113 xi->config_gso = 61440; 1.114 xi->config_page = NULL; 1.115 xi->config_rx_interrupt_moderation = 0; 1.116 +#endif 1.117 1.118 nrl = init_parameters->AllocatedResources; 1.119 for (i = 0; i < nrl->Count; i++) 1.120 @@ -714,12 +710,12 @@ XenNet_Initialize(NDIS_HANDLE adapter_ha 1.121 if (!NT_SUCCESS(status)) 1.122 { 1.123 KdPrint(("Could not read ScatterGather value (%08x)\n", status)); 1.124 - xi->config_sg = 1; 1.125 + xi->frontend_sg_supported = TRUE; 1.126 } 1.127 else 1.128 { 1.129 KdPrint(("ScatterGather = %d\n", config_param->ParameterData.IntegerData)); 1.130 - xi->config_sg = config_param->ParameterData.IntegerData; 1.131 + xi->frontend_sg_supported = !!config_param->ParameterData.IntegerData; 1.132 } 1.133 1.134 NdisInitUnicodeString(&config_param_name, L"LargeSendOffload"); 1.135 @@ -727,16 +723,45 @@ XenNet_Initialize(NDIS_HANDLE adapter_ha 1.136 if (!NT_SUCCESS(status)) 1.137 { 1.138 KdPrint(("Could not read LargeSendOffload value (%08x)\n", status)); 1.139 - xi->config_gso = 0; 1.140 + xi->frontend_gso_value = 0; 1.141 } 1.142 else 1.143 { 1.144 KdPrint(("LargeSendOffload = %d\n", config_param->ParameterData.IntegerData)); 1.145 - xi->config_gso = config_param->ParameterData.IntegerData; 1.146 - if (xi->config_gso > 61440) 1.147 + xi->frontend_gso_value = config_param->ParameterData.IntegerData; 1.148 + if (xi->frontend_gso_value > 61440) 1.149 { 1.150 - xi->config_gso = 61440; 1.151 - KdPrint(("(clipped to %d)\n", xi->config_gso)); 1.152 + xi->frontend_gso_value = 61440; 1.153 + KdPrint(("(clipped to %d)\n", xi->frontend_gso_value)); 1.154 + } 1.155 + if (!xi->frontend_sg_supported && xi->frontend_gso_value > PAGE_SIZE - MAX_PKT_HEADER_LENGTH) 1.156 + { 1.157 + /* without SG, GSO can be a maximum of PAGE_SIZE - MAX_PKT_HEADER_LENGTH */ 1.158 + xi->frontend_gso_value = min(xi->frontend_gso_value, PAGE_SIZE - MAX_PKT_HEADER_LENGTH); 1.159 + KdPrint(("(clipped to %d with sg disabled)\n", xi->frontend_gso_value)); 1.160 + } 1.161 + } 1.162 + 1.163 + NdisInitUnicodeString(&config_param_name, L"LargeSendOffloadRxSplitMTU"); 1.164 + NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger); 1.165 + if (!NT_SUCCESS(status)) 1.166 + { 1.167 + KdPrint(("Could not read LargeSendOffload value (%08x)\n", status)); 1.168 + xi->frontend_gso_rx_split_type = RX_LSO_SPLIT_HALF; 1.169 + } 1.170 + else 1.171 + { 1.172 + KdPrint(("LargeSendOffloadRxSplitMTU = %d\n", config_param->ParameterData.IntegerData)); 1.173 + switch (config_param->ParameterData.IntegerData) 1.174 + { 1.175 + case RX_LSO_SPLIT_MSS: 1.176 + case RX_LSO_SPLIT_HALF: 1.177 + case RX_LSO_SPLIT_NONE: 1.178 + xi->frontend_gso_rx_split_type = config_param->ParameterData.IntegerData; 1.179 + break; 1.180 + default: 1.181 + xi->frontend_gso_rx_split_type = RX_LSO_SPLIT_HALF; 1.182 + break; 1.183 } 1.184 } 1.185 1.186 @@ -745,64 +770,25 @@ XenNet_Initialize(NDIS_HANDLE adapter_ha 1.187 if (!NT_SUCCESS(status)) 1.188 { 1.189 KdPrint(("Could not read ChecksumOffload value (%08x)\n", status)); 1.190 - xi->config_csum = 1; 1.191 + xi->backend_csum_supported = TRUE; 1.192 } 1.193 else 1.194 { 1.195 KdPrint(("ChecksumOffload = %d\n", config_param->ParameterData.IntegerData)); 1.196 - xi->config_csum = !!config_param->ParameterData.IntegerData; 1.197 + xi->backend_csum_supported = !!config_param->ParameterData.IntegerData; 1.198 } 1.199 1.200 - NdisInitUnicodeString(&config_param_name, L"ChecksumOffloadRxCheck"); 1.201 - NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger); 1.202 - if (!NT_SUCCESS(status)) 1.203 - { 1.204 - KdPrint(("Could not read ChecksumOffloadRxCheck value (%08x)\n", status)); 1.205 - xi->config_csum_rx_check = 1; 1.206 - } 1.207 - else 1.208 - { 1.209 - KdPrint(("ChecksumOffloadRxCheck = %d\n", config_param->ParameterData.IntegerData)); 1.210 - xi->config_csum_rx_check = !!config_param->ParameterData.IntegerData; 1.211 - } 1.212 - 1.213 - NdisInitUnicodeString(&config_param_name, L"ChecksumOffloadDontFix"); 1.214 - NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger); 1.215 - if (!NT_SUCCESS(status)) 1.216 - { 1.217 - KdPrint(("Could not read ChecksumOffloadDontFix value (%08x)\n", status)); 1.218 - xi->config_csum_rx_dont_fix = 0; 1.219 - } 1.220 - else 1.221 - { 1.222 - KdPrint(("ChecksumOffloadDontFix = %d\n", config_param->ParameterData.IntegerData)); 1.223 - xi->config_csum_rx_dont_fix = !!config_param->ParameterData.IntegerData; 1.224 - } 1.225 - 1.226 NdisInitUnicodeString(&config_param_name, L"MTU"); 1.227 NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger); 1.228 if (!NT_SUCCESS(status)) 1.229 { 1.230 KdPrint(("Could not read MTU value (%08x)\n", status)); 1.231 - xi->config_mtu = 1500; 1.232 + xi->frontend_mtu_value = 1500; 1.233 } 1.234 else 1.235 { 1.236 KdPrint(("MTU = %d\n", config_param->ParameterData.IntegerData)); 1.237 - xi->config_mtu = config_param->ParameterData.IntegerData; 1.238 - } 1.239 - 1.240 - NdisInitUnicodeString(&config_param_name, L"RxInterruptModeration"); 1.241 - NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger); 1.242 - if (!NT_SUCCESS(status)) 1.243 - { 1.244 - KdPrint(("Could not read RxInterruptModeration value (%08x)\n", status)); 1.245 - xi->config_rx_interrupt_moderation = 1500; 1.246 - } 1.247 - else 1.248 - { 1.249 - KdPrint(("RxInterruptModeration = %d\n", config_param->ParameterData.IntegerData)); 1.250 - xi->config_rx_interrupt_moderation = config_param->ParameterData.IntegerData; 1.251 + xi->frontend_mtu_value = config_param->ParameterData.IntegerData; 1.252 } 1.253 1.254 NdisReadNetworkAddress(&status, &network_address, &network_address_length, config_handle); 1.255 @@ -819,8 +805,6 @@ XenNet_Initialize(NDIS_HANDLE adapter_ha 1.256 xi->curr_mac_addr[3], xi->curr_mac_addr[4], xi->curr_mac_addr[5])); 1.257 } 1.258 1.259 - xi->config_max_pkt_size = max(xi->config_mtu + XN_HDR_SIZE, xi->config_gso + XN_HDR_SIZE); 1.260 - 1.261 NdisCloseConfiguration(config_handle); 1.262 1.263 status = XenNet_D0Entry(xi); 1.264 @@ -829,10 +813,9 @@ XenNet_Initialize(NDIS_HANDLE adapter_ha 1.265 KdPrint(("Failed to go to D0 (%08x)\n", status)); 1.266 goto err; 1.267 } 1.268 - 1.269 - xi->current_csum_ipv4 = xi->config_csum; 1.270 - xi->current_lso_ipv4 = xi->config_gso; 1.271 1.272 + xi->config_max_pkt_size = max(xi->current_mtu_value + XN_HDR_SIZE, xi->current_gso_value + XN_HDR_SIZE); 1.273 + 1.274 registration_attributes.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES; 1.275 registration_attributes.Header.Revision = NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES_REVISION_1; 1.276 registration_attributes.Header.Size = NDIS_SIZEOF_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES_REVISION_1; 1.277 @@ -841,7 +824,7 @@ XenNet_Initialize(NDIS_HANDLE adapter_ha 1.278 registration_attributes.AttributeFlags |= NDIS_MINIPORT_ATTRIBUTES_HARDWARE_DEVICE; 1.279 registration_attributes.AttributeFlags |= NDIS_MINIPORT_ATTRIBUTES_SURPRISE_REMOVE_OK; 1.280 registration_attributes.CheckForHangTimeInSeconds = 0; /* use default */ 1.281 - registration_attributes.InterfaceType = NdisInterfacePNPBus; /* or PnP??? */ 1.282 + registration_attributes.InterfaceType = NdisInterfacePNPBus; 1.283 status = NdisMSetMiniportAttributes(xi->adapter_handle, (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)®istration_attributes); 1.284 if (!NT_SUCCESS(status)) 1.285 { 1.286 @@ -855,7 +838,7 @@ XenNet_Initialize(NDIS_HANDLE adapter_ha 1.287 general_attributes.Flags = 0; 1.288 general_attributes.MediaType = NdisMedium802_3; 1.289 general_attributes.PhysicalMediumType = NdisPhysicalMediumOther; 1.290 - general_attributes.MtuSize = xi->config_mtu; 1.291 + general_attributes.MtuSize = xi->current_mtu_value; 1.292 general_attributes.MaxXmitLinkSpeed = MAX_LINK_SPEED; 1.293 general_attributes.XmitLinkSpeed = MAX_LINK_SPEED; 1.294 general_attributes.MaxRcvLinkSpeed = MAX_LINK_SPEED; 1.295 @@ -923,64 +906,69 @@ XenNet_Initialize(NDIS_HANDLE adapter_ha 1.296 df_offload.Header.Type = NDIS_OBJECT_TYPE_OFFLOAD; 1.297 df_offload.Header.Revision = NDIS_OFFLOAD_REVISION_1; // revision 2 does exist 1.298 df_offload.Header.Size = NDIS_SIZEOF_NDIS_OFFLOAD_REVISION_1; 1.299 - df_offload.Checksum.IPv4Transmit.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3; 1.300 - df_offload.Checksum.IPv4Transmit.IpOptionsSupported = NDIS_OFFLOAD_SET_ON; 1.301 - df_offload.Checksum.IPv4Transmit.TcpOptionsSupported = NDIS_OFFLOAD_SET_ON; 1.302 - df_offload.Checksum.IPv4Transmit.TcpChecksum = NDIS_OFFLOAD_SET_ON; 1.303 - df_offload.Checksum.IPv4Transmit.UdpChecksum = NDIS_OFFLOAD_SET_ON; 1.304 - df_offload.Checksum.IPv4Transmit.IpChecksum = NDIS_OFFLOAD_SET_ON; 1.305 - df_offload.Checksum.IPv4Receive.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3; 1.306 - df_offload.Checksum.IPv4Receive.IpOptionsSupported = NDIS_OFFLOAD_SET_ON; 1.307 - df_offload.Checksum.IPv4Receive.TcpOptionsSupported = NDIS_OFFLOAD_SET_ON; 1.308 - df_offload.Checksum.IPv4Receive.TcpChecksum = NDIS_OFFLOAD_SET_ON; 1.309 - df_offload.Checksum.IPv4Receive.UdpChecksum = NDIS_OFFLOAD_SET_ON; 1.310 - df_offload.Checksum.IPv4Receive.IpChecksum = NDIS_OFFLOAD_SET_ON; 1.311 - /* offload.Checksum.IPv6Transmit is not supported */ 1.312 - /* offload.Checksum.IPv6Receive is not supported */ 1.313 - df_offload.LsoV1.IPv4.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3; 1.314 - df_offload.LsoV1.IPv4.MaxOffLoadSize = xi->config_gso; 1.315 - df_offload.LsoV1.IPv4.MinSegmentCount = MIN_LARGE_SEND_SEGMENTS; 1.316 - df_offload.LsoV1.IPv4.TcpOptions = NDIS_OFFLOAD_NOT_SUPPORTED; /* linux can't handle this */ 1.317 - df_offload.LsoV1.IPv4.IpOptions = NDIS_OFFLOAD_NOT_SUPPORTED; /* linux can't handle this */ 1.318 - df_offload.LsoV2.IPv4.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3; 1.319 - df_offload.LsoV2.IPv4.MaxOffLoadSize = xi->config_gso; 1.320 - df_offload.LsoV2.IPv4.MinSegmentCount = MIN_LARGE_SEND_SEGMENTS; 1.321 - /* df_offload.LsoV2.IPv6 is not supported */ 1.322 - /* df_offload.IPsecV1 is not supported */ 1.323 - df_offload.Flags = 0; 1.324 - /* df_offload.IPsecV2 is not supported */ 1.325 - 1.326 /* this is the supported offload state */ 1.327 RtlZeroMemory(&hw_offload, sizeof(hw_offload)); 1.328 hw_offload.Header.Type = NDIS_OBJECT_TYPE_OFFLOAD; 1.329 hw_offload.Header.Revision = NDIS_OFFLOAD_REVISION_1; // revision 2 does exist 1.330 hw_offload.Header.Size = NDIS_SIZEOF_NDIS_OFFLOAD_REVISION_1; 1.331 - hw_offload.Checksum.IPv4Transmit.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3; 1.332 - hw_offload.Checksum.IPv4Transmit.IpOptionsSupported = NDIS_OFFLOAD_SUPPORTED; 1.333 - hw_offload.Checksum.IPv4Transmit.TcpOptionsSupported = NDIS_OFFLOAD_SUPPORTED; 1.334 - hw_offload.Checksum.IPv4Transmit.TcpChecksum = NDIS_OFFLOAD_SUPPORTED; 1.335 - hw_offload.Checksum.IPv4Transmit.UdpChecksum = NDIS_OFFLOAD_SUPPORTED; 1.336 - hw_offload.Checksum.IPv4Transmit.IpChecksum = NDIS_OFFLOAD_SUPPORTED; 1.337 - hw_offload.Checksum.IPv4Receive.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3; 1.338 - hw_offload.Checksum.IPv4Receive.IpOptionsSupported = NDIS_OFFLOAD_SUPPORTED; 1.339 - hw_offload.Checksum.IPv4Receive.TcpOptionsSupported = NDIS_OFFLOAD_SUPPORTED; 1.340 - hw_offload.Checksum.IPv4Receive.TcpChecksum = NDIS_OFFLOAD_SUPPORTED; 1.341 - hw_offload.Checksum.IPv4Receive.UdpChecksum = NDIS_OFFLOAD_SUPPORTED; 1.342 - hw_offload.Checksum.IPv4Receive.IpChecksum = NDIS_OFFLOAD_SUPPORTED; 1.343 - /* hw_offload.Checksum.IPv6Transmit is not supported */ 1.344 - /* hw_offload.Checksum.IPv6Receive is not supported */ 1.345 - hw_offload.LsoV1.IPv4.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3; 1.346 - hw_offload.LsoV1.IPv4.MaxOffLoadSize = xi->config_gso; 1.347 - hw_offload.LsoV1.IPv4.MinSegmentCount = MIN_LARGE_SEND_SEGMENTS; 1.348 - hw_offload.LsoV1.IPv4.TcpOptions = NDIS_OFFLOAD_NOT_SUPPORTED; /* linux can't handle this */ 1.349 - hw_offload.LsoV1.IPv4.IpOptions = NDIS_OFFLOAD_NOT_SUPPORTED; /* linux can't handle this */ 1.350 - hw_offload.LsoV2.IPv4.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3; 1.351 - hw_offload.LsoV2.IPv4.MaxOffLoadSize = xi->config_gso; 1.352 - hw_offload.LsoV2.IPv4.MinSegmentCount = MIN_LARGE_SEND_SEGMENTS; 1.353 - /* hw_offload.LsoV2.IPv6 is not supported */ 1.354 + if (xi->current_csum_supported) 1.355 + { 1.356 + df_offload.Checksum.IPv4Transmit.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3; 1.357 + df_offload.Checksum.IPv4Transmit.IpOptionsSupported = NDIS_OFFLOAD_SET_ON; 1.358 + df_offload.Checksum.IPv4Transmit.TcpOptionsSupported = NDIS_OFFLOAD_SET_ON; 1.359 + df_offload.Checksum.IPv4Transmit.TcpChecksum = NDIS_OFFLOAD_SET_ON; 1.360 + df_offload.Checksum.IPv4Transmit.UdpChecksum = NDIS_OFFLOAD_SET_ON; 1.361 + df_offload.Checksum.IPv4Transmit.IpChecksum = NDIS_OFFLOAD_SET_ON; 1.362 + df_offload.Checksum.IPv4Receive.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3; 1.363 + df_offload.Checksum.IPv4Receive.IpOptionsSupported = NDIS_OFFLOAD_SET_ON; 1.364 + df_offload.Checksum.IPv4Receive.TcpOptionsSupported = NDIS_OFFLOAD_SET_ON; 1.365 + df_offload.Checksum.IPv4Receive.TcpChecksum = NDIS_OFFLOAD_SET_ON; 1.366 + df_offload.Checksum.IPv4Receive.UdpChecksum = NDIS_OFFLOAD_SET_ON; 1.367 + df_offload.Checksum.IPv4Receive.IpChecksum = NDIS_OFFLOAD_SET_ON; 1.368 + /* offload.Checksum.IPv6Transmit is not supported */ 1.369 + /* offload.Checksum.IPv6Receive is not supported */ 1.370 + hw_offload.Checksum.IPv4Transmit.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3; 1.371 + hw_offload.Checksum.IPv4Transmit.IpOptionsSupported = NDIS_OFFLOAD_SUPPORTED; 1.372 + hw_offload.Checksum.IPv4Transmit.TcpOptionsSupported = NDIS_OFFLOAD_SUPPORTED; 1.373 + hw_offload.Checksum.IPv4Transmit.TcpChecksum = NDIS_OFFLOAD_SUPPORTED; 1.374 + hw_offload.Checksum.IPv4Transmit.UdpChecksum = NDIS_OFFLOAD_SUPPORTED; 1.375 + hw_offload.Checksum.IPv4Transmit.IpChecksum = NDIS_OFFLOAD_SUPPORTED; 1.376 + hw_offload.Checksum.IPv4Receive.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3; 1.377 + hw_offload.Checksum.IPv4Receive.IpOptionsSupported = NDIS_OFFLOAD_SUPPORTED; 1.378 + hw_offload.Checksum.IPv4Receive.TcpOptionsSupported = NDIS_OFFLOAD_SUPPORTED; 1.379 + hw_offload.Checksum.IPv4Receive.TcpChecksum = NDIS_OFFLOAD_SUPPORTED; 1.380 + hw_offload.Checksum.IPv4Receive.UdpChecksum = NDIS_OFFLOAD_SUPPORTED; 1.381 + hw_offload.Checksum.IPv4Receive.IpChecksum = NDIS_OFFLOAD_SUPPORTED; 1.382 + /* hw_offload.Checksum.IPv6Transmit is not supported */ 1.383 + /* hw_offload.Checksum.IPv6Receive is not supported */ 1.384 + } 1.385 + if (xi->current_gso_value) 1.386 + { 1.387 + hw_offload.LsoV1.IPv4.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3; 1.388 + hw_offload.LsoV1.IPv4.MaxOffLoadSize = xi->current_gso_value; 1.389 + hw_offload.LsoV1.IPv4.MinSegmentCount = MIN_LARGE_SEND_SEGMENTS; 1.390 + hw_offload.LsoV1.IPv4.TcpOptions = NDIS_OFFLOAD_NOT_SUPPORTED; /* linux can't handle this */ 1.391 + hw_offload.LsoV1.IPv4.IpOptions = NDIS_OFFLOAD_NOT_SUPPORTED; /* linux can't handle this */ 1.392 + hw_offload.LsoV2.IPv4.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3; 1.393 + hw_offload.LsoV2.IPv4.MaxOffLoadSize = xi->current_gso_value; 1.394 + hw_offload.LsoV2.IPv4.MinSegmentCount = MIN_LARGE_SEND_SEGMENTS; 1.395 + /* hw_offload.LsoV2.IPv6 is not supported */ 1.396 + df_offload.LsoV1.IPv4.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3; 1.397 + df_offload.LsoV1.IPv4.MaxOffLoadSize = xi->current_gso_value; 1.398 + df_offload.LsoV1.IPv4.MinSegmentCount = MIN_LARGE_SEND_SEGMENTS; 1.399 + df_offload.LsoV1.IPv4.TcpOptions = NDIS_OFFLOAD_NOT_SUPPORTED; /* linux can't handle this */ 1.400 + df_offload.LsoV1.IPv4.IpOptions = NDIS_OFFLOAD_NOT_SUPPORTED; /* linux can't handle this */ 1.401 + df_offload.LsoV2.IPv4.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3; 1.402 + df_offload.LsoV2.IPv4.MaxOffLoadSize = xi->current_gso_value; 1.403 + df_offload.LsoV2.IPv4.MinSegmentCount = MIN_LARGE_SEND_SEGMENTS; 1.404 + /* df_offload.LsoV2.IPv6 is not supported */ 1.405 + } 1.406 /* hw_offload.IPsecV1 is not supported */ 1.407 + /* hw_offload.IPsecV2 is not supported */ 1.408 + /* df_offload.IPsecV1 is not supported */ 1.409 + /* df_offload.IPsecV2 is not supported */ 1.410 hw_offload.Flags = 0; 1.411 - /* hw_offload.IPsecV2 is not supported */ 1.412 + df_offload.Flags = 0; 1.413 1.414 RtlZeroMemory(&df_conn_offload, sizeof(df_conn_offload)); 1.415 df_conn_offload.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; 1.416 @@ -1015,7 +1003,6 @@ err: 1.417 return status; 1.418 } 1.419 1.420 -#if 0 1.421 NDIS_STATUS 1.422 XenNet_D0Exit(struct xennet_info *xi) 1.423 { 1.424 @@ -1037,7 +1024,6 @@ XenNet_D0Exit(struct xennet_info *xi) 1.425 1.426 return STATUS_SUCCESS; 1.427 } 1.428 -#endif 1.429 1.430 static VOID 1.431 XenNet_DevicePnPEventNotify(NDIS_HANDLE adapter_context, PNET_DEVICE_PNP_EVENT pnp_event) 1.432 @@ -1090,7 +1076,7 @@ XenNet_Halt(NDIS_HANDLE adapter_context, 1.433 1.434 FUNCTION_ENTER(); 1.435 1.436 - //XenNet_D0Exit(xi); 1.437 + XenNet_D0Exit(xi); 1.438 1.439 NdisFreeMemory(xi, 0, 0); 1.440
2.1 --- a/xennet/xennet6.h Sat May 14 15:14:52 2011 +1000 2.2 +++ b/xennet/xennet6.h Sat May 14 15:15:18 2011 +1000 2.3 @@ -48,11 +48,11 @@ Foundation, Inc., 51 Franklin Street, Fi 2.4 #define NB_HEADER_BUF(_nb) (*(shared_buffer_t **)&(_nb)->NB_HEADER_BUF_FIELD) 2.5 2.6 #define NBL_REF_FIELD MiniportReserved[0] // TX 2.7 -#define NBL_PACKET_COUNT_FIELD MiniportReserved[0] // RX 2.8 -#define NBL_LAST_NB_FIELD MiniportReserved[1] // RX 2.9 +//#define NBL_PACKET_COUNT_FIELD MiniportReserved[0] // RX 2.10 +//#define NBL_LAST_NB_FIELD MiniportReserved[1] // RX 2.11 #define NBL_REF(_nbl) (*(ULONG_PTR *)&(_nbl)->NBL_REF_FIELD) 2.12 -#define NBL_PACKET_COUNT(_nbl) (*(ULONG_PTR *)&(_nbl)->NBL_PACKET_COUNT_FIELD) 2.13 -#define NBL_LAST_NB(_nbl) (*(PNET_BUFFER *)&(_nbl)->NBL_LAST_NB_FIELD) 2.14 +//#define NBL_PACKET_COUNT(_nbl) (*(ULONG_PTR *)&(_nbl)->NBL_PACKET_COUNT_FIELD) 2.15 +//#define NBL_LAST_NB(_nbl) (*(PNET_BUFFER *)&(_nbl)->NBL_LAST_NB_FIELD) 2.16 2.17 #include <xen_windows.h> 2.18 #include <memory.h> 2.19 @@ -213,6 +213,7 @@ typedef struct 2.20 } tx_shadow_t; 2.21 2.22 typedef struct { 2.23 + ULONG parse_result; 2.24 PMDL first_mdl; 2.25 MDL first_mdl_storage; 2.26 PPFN_NUMBER first_mdl_pfns[17]; /* maximum possible packet size */ 2.27 @@ -248,6 +249,13 @@ typedef struct { 2.28 #define PAGE_LIST_SIZE (max(NET_RX_RING_SIZE, NET_TX_RING_SIZE) * 4) 2.29 #define MULTICAST_LIST_MAX_SIZE 32 2.30 2.31 +/* split incoming large packets into MSS sized chunks */ 2.32 +#define RX_LSO_SPLIT_MSS 0 2.33 +/* split incoming large packets in half, to not invoke the delayed ack timer */ 2.34 +#define RX_LSO_SPLIT_HALF 1 2.35 +/* don't split incoming large packets. not really useful */ 2.36 +#define RX_LSO_SPLIT_NONE 2 2.37 + 2.38 struct xennet_info 2.39 { 2.40 BOOLEAN inactive; 2.41 @@ -310,9 +318,6 @@ struct xennet_info 2.42 ULONG rx_id_free; 2.43 packet_info_t *rxpi; 2.44 KEVENT packet_returned_event; 2.45 - //NDIS_MINIPORT_TIMER rx_timer; 2.46 - KTIMER rx_timer; 2.47 - KDPC rx_timer_dpc; 2.48 NDIS_HANDLE rx_nbl_pool; 2.49 NDIS_HANDLE rx_nb_pool; 2.50 volatile LONG rx_pb_free; 2.51 @@ -333,16 +338,22 @@ struct xennet_info 2.52 LONG rx_outstanding; 2.53 2.54 /* config vars from registry */ 2.55 - ULONG config_sg; 2.56 - ULONG config_csum; 2.57 - ULONG config_csum_rx_check; 2.58 - ULONG config_csum_rx_dont_fix; 2.59 - ULONG config_gso; 2.60 - ULONG config_mtu; 2.61 - ULONG config_rx_interrupt_moderation; 2.62 + /* the frontend_* indicate our willingness to support */ 2.63 + BOOLEAN frontend_sg_supported; 2.64 + BOOLEAN frontend_csum_supported; 2.65 + ULONG frontend_gso_value; 2.66 + ULONG frontend_mtu_value; 2.67 + ULONG frontend_gso_rx_split_type; /* RX_LSO_SPLIT_* */ 2.68 2.69 - BOOLEAN current_csum_ipv4; 2.70 - ULONG current_lso_ipv4; 2.71 + BOOLEAN backend_sg_supported; 2.72 + BOOLEAN backend_csum_supported; 2.73 + ULONG backend_gso_value; 2.74 + 2.75 + BOOLEAN current_sg_supported; 2.76 + BOOLEAN current_csum_supported; 2.77 + ULONG current_gso_value; 2.78 + ULONG current_mtu_value; 2.79 + ULONG current_gso_rx_split_type; 2.80 2.81 /* config stuff calculated from the above */ 2.82 ULONG config_max_pkt_size; 2.83 @@ -410,7 +421,7 @@ XenNet_SetPower; 2.84 2.85 BOOLEAN 2.86 XenNet_BuildHeader(packet_info_t *pi, PVOID header, ULONG new_header_size); 2.87 -ULONG 2.88 +VOID 2.89 XenNet_ParsePacketHeader(packet_info_t *pi, PUCHAR buffer, ULONG min_header_size); 2.90 BOOLEAN 2.91 XenNet_FilterAcceptPacket(struct xennet_info *xi,packet_info_t *pi);
3.1 --- a/xennet/xennet6_common.c Sat May 14 15:14:52 2011 +1000 3.2 +++ b/xennet/xennet6_common.c Sat May 14 15:15:18 2011 +1000 3.3 @@ -112,7 +112,7 @@ XenNet_BuildHeader(packet_info_t *pi, PU 3.4 return TRUE; 3.5 } 3.6 3.7 -ULONG 3.8 +VOID 3.9 XenNet_ParsePacketHeader(packet_info_t *pi, PUCHAR alt_buffer, ULONG min_header_size) 3.10 { 3.11 //FUNCTION_ENTER(); 3.12 @@ -134,7 +134,8 @@ XenNet_ParsePacketHeader(packet_info_t * 3.13 if (!XenNet_BuildHeader(pi, NULL, (ULONG)XN_HDR_SIZE)) 3.14 { 3.15 //KdPrint((__DRIVER_NAME " packet too small (Ethernet Header)\n")); 3.16 - return PARSE_TOO_SMALL; 3.17 + pi->parse_result = PARSE_TOO_SMALL; 3.18 + return; 3.19 } 3.20 3.21 switch (GET_NET_PUSHORT(&pi->header[12])) // L2 protocol field 3.22 @@ -146,14 +147,16 @@ XenNet_ParsePacketHeader(packet_info_t * 3.23 if (!XenNet_BuildHeader(pi, NULL, (ULONG)(XN_HDR_SIZE + 20))) 3.24 { 3.25 KdPrint((__DRIVER_NAME " packet too small (IP Header)\n")); 3.26 - return PARSE_TOO_SMALL; 3.27 + pi->parse_result = PARSE_TOO_SMALL; 3.28 + return; 3.29 } 3.30 } 3.31 pi->ip_version = (pi->header[XN_HDR_SIZE + 0] & 0xF0) >> 4; 3.32 if (pi->ip_version != 4) 3.33 { 3.34 //KdPrint((__DRIVER_NAME " ip_version = %d\n", pi->ip_version)); 3.35 - return PARSE_UNKNOWN_TYPE; 3.36 + pi->parse_result = PARSE_UNKNOWN_TYPE; 3.37 + return; 3.38 } 3.39 pi->ip4_header_length = (pi->header[XN_HDR_SIZE + 0] & 0x0F) << 2; 3.40 if (pi->header_length < (ULONG)(XN_HDR_SIZE + pi->ip4_header_length + 20)) 3.41 @@ -161,17 +164,20 @@ XenNet_ParsePacketHeader(packet_info_t * 3.42 if (!XenNet_BuildHeader(pi, NULL, (ULONG)(XN_HDR_SIZE + pi->ip4_header_length + 20))) 3.43 { 3.44 //KdPrint((__DRIVER_NAME " packet too small (IP Header + IP Options + TCP Header)\n")); 3.45 - return PARSE_TOO_SMALL; 3.46 + pi->parse_result = PARSE_TOO_SMALL; 3.47 + return; 3.48 } 3.49 } 3.50 break; 3.51 case 0x86DD: /* IPv6 */ 3.52 //KdPrint((__DRIVER_NAME " IPv6\n")); 3.53 //KdPrint((__DRIVER_NAME " (not currently used)\n")); 3.54 - return PARSE_UNKNOWN_TYPE; 3.55 + pi->parse_result = PARSE_UNKNOWN_TYPE; 3.56 + return; 3.57 default: 3.58 //KdPrint((__DRIVER_NAME " Not IP (%04x)\n", GET_NET_PUSHORT(&pi->header[12]))); 3.59 - return PARSE_UNKNOWN_TYPE; 3.60 + pi->parse_result = PARSE_UNKNOWN_TYPE; 3.61 + return; 3.62 } 3.63 pi->ip_proto = pi->header[XN_HDR_SIZE + 9]; 3.64 switch (pi->ip_proto) 3.65 @@ -181,7 +187,8 @@ XenNet_ParsePacketHeader(packet_info_t * 3.66 break; 3.67 default: 3.68 //KdPrint((__DRIVER_NAME " Not TCP/UDP (%d)\n", pi->ip_proto)); 3.69 - return PARSE_UNKNOWN_TYPE; 3.70 + pi->parse_result = PARSE_UNKNOWN_TYPE; 3.71 + return; 3.72 } 3.73 pi->ip4_length = GET_NET_PUSHORT(&pi->header[XN_HDR_SIZE + 2]); 3.74 pi->tcp_header_length = (pi->header[XN_HDR_SIZE + pi->ip4_header_length + 12] & 0xf0) >> 2; 3.75 @@ -191,14 +198,16 @@ XenNet_ParsePacketHeader(packet_info_t * 3.76 if (!XenNet_BuildHeader(pi, NULL, (ULONG)(XN_HDR_SIZE + pi->ip4_header_length + pi->tcp_header_length))) 3.77 { 3.78 //KdPrint((__DRIVER_NAME " packet too small (IP Header + IP Options + TCP Header + TCP Options)\n")); 3.79 - return PARSE_TOO_SMALL; 3.80 + pi->parse_result = PARSE_TOO_SMALL; 3.81 + return; 3.82 } 3.83 } 3.84 3.85 if ((ULONG)XN_HDR_SIZE + pi->ip4_length > pi->total_length) 3.86 { 3.87 //KdPrint((__DRIVER_NAME " XN_HDR_SIZE + ip4_length (%d) > total_length (%d)\n", XN_HDR_SIZE + pi->ip4_length, pi->total_length)); 3.88 - return PARSE_UNKNOWN_TYPE; 3.89 + pi->parse_result = PARSE_UNKNOWN_TYPE; 3.90 + return; 3.91 } 3.92 3.93 pi->tcp_length = pi->ip4_length - pi->ip4_header_length - pi->tcp_header_length; 3.94 @@ -212,7 +221,7 @@ XenNet_ParsePacketHeader(packet_info_t * 3.95 //KdPrint((__DRIVER_NAME " tcp_length = %d\n", pi->tcp_length)); 3.96 //FUNCTION_EXIT(); 3.97 3.98 - return PARSE_OK; 3.99 + pi->parse_result = PARSE_OK; 3.100 } 3.101 3.102 VOID
4.1 --- a/xennet/xennet6_oid.c Sat May 14 15:14:52 2011 +1000 4.2 +++ b/xennet/xennet6_oid.c Sat May 14 15:15:18 2011 +1000 4.3 @@ -86,10 +86,10 @@ XenNet_QueryInformation( 4.4 temp_data = NdisMedium802_3; 4.5 break; 4.6 case OID_GEN_MAXIMUM_LOOKAHEAD: 4.7 - temp_data = MAX_LOOKAHEAD_LENGTH; //xi->config_mtu; 4.8 + temp_data = MAX_LOOKAHEAD_LENGTH; //xi->config_mtu_value; 4.9 break; 4.10 case OID_GEN_MAXIMUM_FRAME_SIZE: 4.11 - temp_data = xi->config_mtu; 4.12 + temp_data = xi->config_mtu_value; 4.13 break; 4.14 case OID_GEN_LINK_SPEED: 4.15 temp_data = 10000000; /* 1Gb */ 4.16 @@ -302,7 +302,7 @@ XenNet_QueryInformation( 4.17 4.18 #endif 4.19 case OID_GEN_MAXIMUM_TOTAL_SIZE: 4.20 - temp_data = xi->config_mtu + XN_HDR_SIZE; 4.21 + temp_data = xi->current_mtu_value + XN_HDR_SIZE; 4.22 break; 4.23 case OID_GEN_INTERRUPT_MODERATION: 4.24 SET_LEN_AND_BREAK_IF_SHORT(sizeof(NDIS_INTERRUPT_MODERATION_PARAMETERS)); 4.25 @@ -926,13 +926,13 @@ XenNet_SetInformation( 4.26 { 4.27 case NDIS_OFFLOAD_SET_ON: 4.28 FUNCTION_MSG(" IPv4.Enabled = NDIS_OFFLOAD_SET_ON\n"); 4.29 - xi->current_csum_ipv4 = TRUE; 4.30 - xi->current_lso_ipv4 = TRUE; 4.31 + xi->current_csum_supported = xi->backend_csum_supported && xi->frontend_csum_supported; 4.32 + xi->current_gso_value = min(xi->backend_csum_supported, xi->frontend_csum_supported); 4.33 break; 4.34 case NDIS_OFFLOAD_SET_OFF: 4.35 FUNCTION_MSG(" IPv4.Enabled = NDIS_OFFLOAD_SET_OFF\n"); 4.36 - xi->current_csum_ipv4 = FALSE; 4.37 - xi->current_lso_ipv4 = FALSE; 4.38 + xi->current_csum_supported = FALSE; 4.39 + xi->current_gso_value = 0; 4.40 break; 4.41 case NDIS_OFFLOAD_SET_NO_CHANGE: 4.42 FUNCTION_MSG(" IPv4.Enabled = NDIS_OFFLOAD_NO_CHANGE\n");
5.1 --- a/xennet/xennet6_rx.c Sat May 14 15:14:52 2011 +1000 5.2 +++ b/xennet/xennet6_rx.c Sat May 14 15:15:18 2011 +1000 5.3 @@ -184,23 +184,40 @@ XenNet_FillRing(struct xennet_info *xi) 5.4 return NDIS_STATUS_SUCCESS; 5.5 } 5.6 5.7 +typedef struct { 5.8 + PNET_BUFFER_LIST first_nbl; 5.9 + PNET_BUFFER_LIST last_nbl; 5.10 + ULONG packet_count; 5.11 +} rx_context_t; 5.12 + 5.13 static BOOLEAN 5.14 -XenNet_MakePacket(struct xennet_info *xi, PNET_BUFFER_LIST nbl, packet_info_t *pi) 5.15 +XenNet_MakePacket(struct xennet_info *xi, rx_context_t *rc, packet_info_t *pi) 5.16 { 5.17 + PNET_BUFFER_LIST nbl; 5.18 PNET_BUFFER nb; 5.19 PMDL mdl_head, mdl_tail, curr_mdl; 5.20 PUCHAR header_va; 5.21 ULONG out_remaining; 5.22 ULONG header_extra; 5.23 shared_buffer_t *header_buf; 5.24 + NDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO csum_info; 5.25 5.26 //FUNCTION_ENTER(); 5.27 5.28 + nbl = NdisAllocateNetBufferList(xi->rx_nbl_pool, 0, 0); 5.29 + if (!nbl) 5.30 + { 5.31 + /* buffers will be freed in MakePackets */ 5.32 + KdPrint((__DRIVER_NAME " No free nbl's\n")); 5.33 + //FUNCTION_EXIT(); 5.34 + return FALSE; 5.35 + } 5.36 + 5.37 nb = NdisAllocateNetBuffer(xi->rx_nb_pool, NULL, 0, 0); 5.38 if (!nb) 5.39 { 5.40 - /* buffers will be freed in MakePackets */ 5.41 - KdPrint((__DRIVER_NAME " No free packets\n")); 5.42 + KdPrint((__DRIVER_NAME " No free nb's\n")); 5.43 + NdisFreeNetBufferList(nbl); 5.44 //FUNCTION_EXIT(); 5.45 return FALSE; 5.46 } 5.47 @@ -209,6 +226,7 @@ XenNet_MakePacket(struct xennet_info *xi 5.48 if (!header_buf) 5.49 { 5.50 KdPrint((__DRIVER_NAME " No free header buffers\n")); 5.51 + NdisFreeNetBufferList(nbl); 5.52 NdisFreeNetBuffer(nb); 5.53 //FUNCTION_EXIT(); 5.54 return FALSE; 5.55 @@ -310,17 +328,48 @@ XenNet_MakePacket(struct xennet_info *xi 5.56 pi->header_length -= header_extra; 5.57 //ASSERT(*(shared_buffer_t **)&packet->MiniportReservedEx[0]); 5.58 5.59 - NBL_PACKET_COUNT(nbl)++; 5.60 - if (!NET_BUFFER_LIST_FIRST_NB(nbl)) 5.61 + rc->packet_count++; 5.62 + NET_BUFFER_LIST_FIRST_NB(nbl) = nb; 5.63 + //NET_BUFFER_NEXT_NB(nb) = NULL; /*is this already done for me? */ 5.64 + 5.65 + if (pi->parse_result == PARSE_OK) 5.66 { 5.67 - NET_BUFFER_LIST_FIRST_NB(nbl) = nb; 5.68 + BOOLEAN checksum_offload = FALSE; 5.69 + csum_info.Value = 0; 5.70 + if (pi->csum_blank || pi->data_validated || pi->mss) 5.71 + { 5.72 + if (pi->ip_proto == 6) // && xi->setting_csum.V4Receive.TcpChecksum) 5.73 + { 5.74 +// if (!pi->tcp_has_options || xi->setting_csum.V4Receive.TcpOptionsSupported) 5.75 +// { 5.76 + csum_info.Receive.IpChecksumSucceeded = TRUE; 5.77 + csum_info.Receive.TcpChecksumSucceeded = TRUE; 5.78 + checksum_offload = TRUE; 5.79 +// } 5.80 + } 5.81 + else if (pi->ip_proto == 17) // &&xi->setting_csum.V4Receive.UdpChecksum) 5.82 + { 5.83 + csum_info.Receive.IpChecksumSucceeded = TRUE; 5.84 + csum_info.Receive.UdpChecksumSucceeded = TRUE; 5.85 + checksum_offload = TRUE; 5.86 + } 5.87 + } 5.88 + NET_BUFFER_LIST_INFO(nbl, TcpIpChecksumNetBufferListInfo) = csum_info.Value; 5.89 + } 5.90 + 5.91 + //packet_count += NBL_PACKET_COUNT(nbl); 5.92 + if (!rc->first_nbl) 5.93 + { 5.94 + rc->first_nbl = nbl; 5.95 } 5.96 else 5.97 { 5.98 - NET_BUFFER_NEXT_NB(NBL_LAST_NB(nbl)) = nb; 5.99 + NET_BUFFER_LIST_NEXT_NBL(rc->last_nbl) = nbl; 5.100 } 5.101 - NBL_LAST_NB(nbl) = nb; 5.102 - NET_BUFFER_NEXT_NB(nb) = NULL; /*is this already done for me? */ 5.103 + rc->last_nbl = nbl; 5.104 + NET_BUFFER_LIST_NEXT_NBL(nbl) = NULL; 5.105 + InterlockedIncrement(&xi->rx_outstanding); 5.106 + 5.107 //FUNCTION_EXIT(); 5.108 return TRUE; 5.109 } 5.110 @@ -461,101 +510,52 @@ XenNet_SumPacketData( 5.111 } 5.112 #endif 5.113 5.114 -static PNET_BUFFER_LIST 5.115 -XenNet_MakePackets(struct xennet_info *xi, packet_info_t *pi) 5.116 +static VOID 5.117 +XenNet_MakePackets(struct xennet_info *xi, rx_context_t *rc, packet_info_t *pi) 5.118 { 5.119 - PNET_BUFFER_LIST nbl = NULL; 5.120 UCHAR psh; 5.121 - NDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO csum_info; 5.122 - ULONG parse_result; 5.123 //PNDIS_BUFFER buffer; 5.124 shared_buffer_t *page_buf; 5.125 5.126 //FUNCTION_ENTER(); 5.127 5.128 - parse_result = XenNet_ParsePacketHeader(pi, NULL, 0); 5.129 - pi->split_required = FALSE; 5.130 + XenNet_ParsePacketHeader(pi, NULL, 0); 5.131 + //pi->split_required = FALSE; 5.132 5.133 if (!XenNet_FilterAcceptPacket(xi, pi)) 5.134 { 5.135 goto done; 5.136 } 5.137 5.138 - nbl = NdisAllocateNetBufferList(xi->rx_nbl_pool, 0, 0); 5.139 - NBL_PACKET_COUNT(nbl) = 0; 5.140 + if (pi->split_required) 5.141 + { 5.142 + switch (xi->current_gso_rx_split_type) 5.143 + { 5.144 + case RX_LSO_SPLIT_HALF: 5.145 + pi->mss = (pi->tcp_length + 1) / 2; 5.146 + break; 5.147 + case RX_LSO_SPLIT_NONE: 5.148 + pi->mss = 65535; 5.149 + break; 5.150 + } 5.151 + } 5.152 5.153 switch (pi->ip_proto) 5.154 { 5.155 case 6: // TCP 5.156 if (pi->split_required) 5.157 break; 5.158 - // fallthrough 5.159 + /* fall through */ 5.160 case 17: // UDP 5.161 - if (!XenNet_MakePacket(xi, nbl, pi)) 5.162 + if (!XenNet_MakePacket(xi, rc, pi)) 5.163 { 5.164 KdPrint((__DRIVER_NAME " Ran out of packets\n")); 5.165 xi->stat_rx_no_buffer++; 5.166 goto done; 5.167 } 5.168 - if (parse_result == PARSE_OK) 5.169 - { 5.170 - BOOLEAN checksum_offload = FALSE; 5.171 - csum_info.Value = 0; 5.172 - if (pi->csum_blank || pi->data_validated) 5.173 - { 5.174 - if (pi->ip_proto == 6) // && xi->setting_csum.V4Receive.TcpChecksum) 5.175 - { 5.176 -// if (!pi->tcp_has_options || xi->setting_csum.V4Receive.TcpOptionsSupported) 5.177 -// { 5.178 - csum_info.Receive.IpChecksumSucceeded = TRUE; 5.179 - csum_info.Receive.TcpChecksumSucceeded = TRUE; 5.180 - checksum_offload = TRUE; 5.181 -// } 5.182 - } 5.183 - else if (pi->ip_proto == 17) // &&xi->setting_csum.V4Receive.UdpChecksum) 5.184 - { 5.185 - csum_info.Receive.IpChecksumSucceeded = TRUE; 5.186 - csum_info.Receive.UdpChecksumSucceeded = TRUE; 5.187 - checksum_offload = TRUE; 5.188 - } 5.189 -#if 0 5.190 - if (pi->csum_blank && (!xi->config_csum_rx_dont_fix || !checksum_offload)) 5.191 - { 5.192 - XenNet_SumPacketData(pi, packet, TRUE); 5.193 - } 5.194 -#endif 5.195 - } 5.196 -#if 0 5.197 - else if (xi->config_csum_rx_check) 5.198 - { 5.199 - if (xi->setting_csum.V4Receive.TcpChecksum && pi->ip_proto == 6) 5.200 - { 5.201 - if (XenNet_SumPacketData(pi, packet, FALSE)) 5.202 - { 5.203 - csum_info.Receive.NdisPacketTcpChecksumSucceeded = TRUE; 5.204 - } 5.205 - else 5.206 - { 5.207 - csum_info.Receive.NdisPacketTcpChecksumFailed = TRUE; 5.208 - } 5.209 - } else if (xi->setting_csum.V4Receive.UdpChecksum && pi->ip_proto == 17) 5.210 - { 5.211 - if (XenNet_SumPacketData(pi, packet, FALSE)) 5.212 - { 5.213 - csum_info.Receive.NdisPacketUdpChecksumSucceeded = TRUE; 5.214 - } 5.215 - else 5.216 - { 5.217 - csum_info.Receive.NdisPacketUdpChecksumFailed = TRUE; 5.218 - } 5.219 - } 5.220 - } 5.221 -#endif 5.222 - NET_BUFFER_LIST_INFO(nbl, TcpIpChecksumNetBufferListInfo) = csum_info.Value; 5.223 - } 5.224 goto done; 5.225 default: 5.226 - if (!XenNet_MakePacket(xi, nbl, pi)) 5.227 + if (!XenNet_MakePacket(xi, rc, pi)) 5.228 { 5.229 KdPrint((__DRIVER_NAME " Ran out of packets\n")); 5.230 xi->stat_rx_no_buffer++; 5.231 @@ -565,17 +565,13 @@ XenNet_MakePackets(struct xennet_info *x 5.232 } 5.233 5.234 /* this is the split_required code */ 5.235 - csum_info.Value = 0; 5.236 - csum_info.Receive.IpChecksumSucceeded = TRUE; 5.237 - csum_info.Receive.TcpChecksumSucceeded = TRUE; 5.238 - //checksum_offload = TRUE; 5.239 pi->tcp_remaining = pi->tcp_length; 5.240 5.241 /* we can make certain assumptions here as the following code is only for tcp4 */ 5.242 psh = pi->header[XN_HDR_SIZE + pi->ip4_header_length + 13] & 8; 5.243 while (pi->tcp_remaining) 5.244 { 5.245 - if (!XenNet_MakePacket(xi, nbl, pi)) 5.246 + if (!XenNet_MakePacket(xi, rc, pi)) 5.247 { 5.248 KdPrint((__DRIVER_NAME " Ran out of packets\n")); 5.249 xi->stat_rx_no_buffer++; 5.250 @@ -593,17 +589,7 @@ XenNet_MakePackets(struct xennet_info *x 5.251 //entry = (PLIST_ENTRY)&packet->MiniportReservedEx[sizeof(PVOID)]; 5.252 //InsertTailList(rx_packet_list, entry); 5.253 } 5.254 - /* we want to be a bit flexible here if some form of offload has been disabled */ 5.255 - csum_info.Value = 0; 5.256 - csum_info.Receive.IpChecksumSucceeded = TRUE; 5.257 - csum_info.Receive.TcpChecksumSucceeded = TRUE; 5.258 - NET_BUFFER_LIST_INFO(nbl, TcpIpChecksumNetBufferListInfo) = csum_info.Value; 5.259 done: 5.260 - if (nbl && !NBL_PACKET_COUNT(nbl)) 5.261 - { 5.262 - NdisFreeNetBufferList(nbl); 5.263 - nbl = NULL; 5.264 - } 5.265 page_buf = pi->first_pb; 5.266 while (page_buf) 5.267 { 5.268 @@ -613,7 +599,7 @@ done: 5.269 } 5.270 XenNet_ClearPacketInfo(pi); 5.271 //FUNCTION_EXIT(); 5.272 - return nbl; 5.273 + return; 5.274 } 5.275 5.276 /* called at <= DISPATCH_LEVEL */ 5.277 @@ -699,7 +685,6 @@ BOOLEAN 5.278 XenNet_RxBufferCheck(struct xennet_info *xi) 5.279 { 5.280 RING_IDX cons, prod; 5.281 - LIST_ENTRY rx_packet_list; 5.282 ULONG packet_count = 0; 5.283 ULONG packet_data = 0; 5.284 ULONG buffer_count = 0; 5.285 @@ -708,11 +693,10 @@ XenNet_RxBufferCheck(struct xennet_info 5.286 shared_buffer_t *page_buf; 5.287 //LIST_ENTRY rx_header_only_packet_list; 5.288 //PLIST_ENTRY entry; 5.289 - PNET_BUFFER_LIST nbl_head = NULL; 5.290 - PNET_BUFFER_LIST nbl_tail = NULL; 5.291 ULONG nbl_count = 0; 5.292 ULONG interim_packet_data = 0; 5.293 struct netif_extra_info *ei; 5.294 + rx_context_t rc; 5.295 packet_info_t *pi = &xi->rxpi[KeGetCurrentProcessorNumber() & 0xff]; 5.296 shared_buffer_t *head_buf = NULL; 5.297 shared_buffer_t *tail_buf = NULL; 5.298 @@ -720,18 +704,16 @@ XenNet_RxBufferCheck(struct xennet_info 5.299 BOOLEAN extra_info_flag = FALSE; 5.300 BOOLEAN more_data_flag = FALSE; 5.301 BOOLEAN dont_set_event; 5.302 - int ring_packets1 = 0; 5.303 - int ring_packets2 = 0; 5.304 - int indicate_packets = 0; 5.305 //FUNCTION_ENTER(); 5.306 5.307 if (!xi->connected) 5.308 return FALSE; /* a delayed DPC could let this come through... just do nothing */ 5.309 5.310 - InitializeListHead(&rx_packet_list); 5.311 - 5.312 + rc.first_nbl = NULL; 5.313 + rc.last_nbl = NULL; 5.314 + rc.packet_count = 0; 5.315 + 5.316 /* get all the buffers off the ring as quickly as possible so the lock is held for a minimum amount of time */ 5.317 - 5.318 KeAcquireSpinLockAtDpcLevel(&xi->rx_lock); 5.319 5.320 if (xi->rx_shutting_down) 5.321 @@ -807,8 +789,7 @@ XenNet_RxBufferCheck(struct xennet_info 5.322 packet_count++; 5.323 packet_data += interim_packet_data; 5.324 interim_packet_data = 0; 5.325 -ring_packets1++; 5.326 - } 5.327 + } 5.328 buffer_count++; 5.329 } 5.330 xi->rx.rsp_cons = cons; 5.331 @@ -934,26 +915,9 @@ ring_packets1++; 5.332 /* Packet done, add it to the list */ 5.333 if (!more_data_flag && !extra_info_flag) 5.334 { 5.335 - PNET_BUFFER_LIST nbl; 5.336 pi->curr_pb = pi->first_pb; 5.337 pi->curr_mdl = pi->first_mdl; 5.338 - nbl = XenNet_MakePackets(xi, pi); 5.339 - if (nbl) 5.340 - { 5.341 - packet_count += NBL_PACKET_COUNT(nbl); 5.342 - nbl_count++; 5.343 - if (!nbl_head) 5.344 - { 5.345 - nbl_head = nbl; 5.346 - } 5.347 - else 5.348 - { 5.349 - NET_BUFFER_LIST_NEXT_NBL(nbl_tail) = nbl; 5.350 - } 5.351 - NET_BUFFER_LIST_NEXT_NBL(nbl) = NULL; 5.352 - nbl_tail = nbl; 5.353 - } 5.354 -ring_packets2++; 5.355 + XenNet_MakePackets(xi, &rc, pi); 5.356 } 5.357 5.358 page_buf = next_buf; 5.359 @@ -962,19 +926,13 @@ ring_packets2++; 5.360 5.361 xi->stat_rx_ok += packet_count; 5.362 5.363 - if (nbl_head) 5.364 + if (rc.first_nbl) 5.365 { 5.366 - PNET_BUFFER_LIST nbl; 5.367 - for (nbl = nbl_head; nbl; nbl = NET_BUFFER_LIST_NEXT_NBL(nbl)) 5.368 - indicate_packets++; 5.369 - if (indicate_packets != ring_packets1 || indicate_packets != ring_packets2) 5.370 - KdPrint((__DRIVER_NAME " ring_packets1 = %d, ring_packets2 = %d, indicate_packets = %d\n", ring_packets1, ring_packets2, indicate_packets)); 5.371 - 5.372 - NdisMIndicateReceiveNetBufferLists(xi->adapter_handle, nbl_head, NDIS_DEFAULT_PORT_NUMBER, nbl_count, 5.373 + NdisMIndicateReceiveNetBufferLists(xi->adapter_handle, rc.first_nbl, NDIS_DEFAULT_PORT_NUMBER, nbl_count, 5.374 NDIS_RECEIVE_FLAGS_DISPATCH_LEVEL 5.375 //| NDIS_RECEIVE_FLAGS_SINGLE_ETHER_TYPE 5.376 | NDIS_RECEIVE_FLAGS_PERFECT_FILTERED); 5.377 - }; 5.378 + } 5.379 //FUNCTION_EXIT(); 5.380 return dont_set_event; 5.381 } 5.382 @@ -985,7 +943,7 @@ ring_packets2++; 5.383 */ 5.384 5.385 static VOID 5.386 -XenNet_PurgeRing(struct xennet_info *xi) 5.387 +XenNet_PurgeRing(xennet_info_t *xi) 5.388 { 5.389 int i; 5.390 for (i = 0; i < NET_RX_RING_SIZE; i++) 5.391 @@ -999,7 +957,7 @@ XenNet_PurgeRing(struct xennet_info *xi) 5.392 } 5.393 5.394 static VOID 5.395 -XenNet_BufferFree(struct xennet_info *xi) 5.396 +XenNet_BufferFree(xennet_info_t *xi) 5.397 { 5.398 shared_buffer_t *sb; 5.399 5.400 @@ -1011,13 +969,13 @@ XenNet_BufferFree(struct xennet_info *xi 5.401 xi->vectors.GntTbl_EndAccess(xi->vectors.context, 5.402 sb->gref, FALSE, (ULONG)'XNRX'); 5.403 IoFreeMdl(sb->mdl); 5.404 + NdisFreeMemory(sb->virtual, sizeof(shared_buffer_t), 0); 5.405 NdisFreeMemory(sb, PAGE_SIZE, 0); 5.406 - NdisFreeMemory(sb->virtual, sizeof(shared_buffer_t), 0); 5.407 } 5.408 while ((sb = get_hb_from_freelist(xi)) != NULL) 5.409 { 5.410 IoFreeMdl(sb->mdl); 5.411 - NdisFreeMemory(sb->virtual, sizeof(shared_buffer_t) + MAX_ETH_HEADER_LENGTH + MAX_LOOKAHEAD_LENGTH, 0); 5.412 + NdisFreeMemory(sb, sizeof(shared_buffer_t) + MAX_ETH_HEADER_LENGTH + MAX_LOOKAHEAD_LENGTH, 0); 5.413 } 5.414 } 5.415 5.416 @@ -1077,7 +1035,6 @@ XenNet_RxInit(xennet_info_t *xi) 5.417 xi->rx_shutting_down = FALSE; 5.418 KeInitializeSpinLock(&xi->rx_lock); 5.419 KeInitializeEvent(&xi->packet_returned_event, SynchronizationEvent, FALSE); 5.420 - KeInitializeTimer(&xi->rx_timer); 5.421 xi->rxpi = NdisAllocateMemoryWithTagPriority(xi->adapter_handle, sizeof(packet_info_t) * NdisSystemProcessorCount(), XENNET_POOL_TAG, NormalPoolPriority); 5.422 if (!xi->rxpi) 5.423 { 5.424 @@ -1130,22 +1087,16 @@ XenNet_RxInit(xennet_info_t *xi) 5.425 BOOLEAN 5.426 XenNet_RxShutdown(xennet_info_t *xi) 5.427 { 5.428 - //KIRQL old_irql; 5.429 + KIRQL old_irql; 5.430 //PNDIS_PACKET packet; 5.431 UNREFERENCED_PARAMETER(xi); 5.432 5.433 FUNCTION_ENTER(); 5.434 5.435 -#if 0 5.436 KeAcquireSpinLock(&xi->rx_lock, &old_irql); 5.437 xi->rx_shutting_down = TRUE; 5.438 KeReleaseSpinLock(&xi->rx_lock, old_irql); 5.439 5.440 - if (xi->config_rx_interrupt_moderation) 5.441 - { 5.442 - KeCancelTimer(&xi->rx_timer); 5.443 - } 5.444 - 5.445 KeFlushQueuedDpcs(); 5.446 5.447 while (xi->rx_outstanding) 5.448 @@ -1154,23 +1105,17 @@ XenNet_RxShutdown(xennet_info_t *xi) 5.449 KeWaitForSingleObject(&xi->packet_returned_event, Executive, KernelMode, FALSE, NULL); 5.450 } 5.451 5.452 - //KeAcquireSpinLock(&xi->rx_lock, &old_irql); 5.453 - 5.454 NdisFreeMemory(xi->rxpi, sizeof(packet_info_t) * NdisSystemProcessorCount(), 0); 5.455 5.456 XenNet_BufferFree(xi); 5.457 5.458 - /* this works because get_packet_from_freelist won't allocate new packets when rx_shutting_down */ 5.459 - while ((packet = get_packet_from_freelist(xi)) != NULL) 5.460 - NdisFreePacket(packet); 5.461 - //stack_delete(xi->rx_packet_stack, NULL, NULL); 5.462 - NdisFreePacketPool(xi->rx_packet_pool); 5.463 5.464 stack_delete(xi->rx_pb_stack, NULL, NULL); 5.465 stack_delete(xi->rx_hb_stack, NULL, NULL); 5.466 - //KeReleaseSpinLock(&xi->rx_lock, old_irql); 5.467 + 5.468 + NdisFreeNetBufferPool(xi->rx_nb_pool); 5.469 + NdisFreeNetBufferListPool(xi->rx_nbl_pool); 5.470 5.471 -#endif 5.472 FUNCTION_EXIT(); 5.473 5.474 return TRUE;
6.1 --- a/xennet/xennet6_tx.c Sat May 14 15:14:52 2011 +1000 6.2 +++ b/xennet/xennet6_tx.c Sat May 14 15:15:18 2011 +1000 6.3 @@ -76,7 +76,6 @@ XenNet_HWSendPacket(struct xennet_info * 6.4 BOOLEAN ndis_lso = FALSE; 6.5 BOOLEAN xen_gso = FALSE; 6.6 ULONG remaining; 6.7 - ULONG parse_result; 6.8 ULONG frags = 0; 6.9 BOOLEAN coalesce_required = FALSE; 6.10 PVOID coalesce_buf; 6.11 @@ -148,7 +147,7 @@ XenNet_HWSendPacket(struct xennet_info * 6.12 //KdPrint((__DRIVER_NAME " Full on send - ring full\n")); 6.13 return FALSE; 6.14 } 6.15 - parse_result = XenNet_ParsePacketHeader(&pi, coalesce_buf, PAGE_SIZE); 6.16 + XenNet_ParsePacketHeader(&pi, coalesce_buf, PAGE_SIZE); 6.17 remaining = pi.total_length - pi.header_length; 6.18 if (pi.ip_version == 4 && pi.ip_proto == 6 && pi.ip4_length == 0) 6.19 { 6.20 @@ -231,7 +230,7 @@ XenNet_HWSendPacket(struct xennet_info * 6.21 /* should make use of TcpHeaderOffset too... maybe just assert if it's not what we expect */ 6.22 break; 6.23 } 6.24 - if (mss && parse_result == PARSE_OK) 6.25 + if (mss && pi.parse_result == PARSE_OK) 6.26 { 6.27 //FUNCTION_MSG("lso mss = %d\n", mss); 6.28 //if (NDIS_GET_PACKET_PROTOCOL_TYPE(packet) != NDIS_PROTOCOL_ID_TCP_IP) 6.29 @@ -297,7 +296,7 @@ XenNet_HWSendPacket(struct xennet_info * 6.30 ei->u.gso.features = 0; 6.31 } 6.32 6.33 - ASSERT(xi->config_sg || !remaining); 6.34 + ASSERT(xi->current_sg_supported || !remaining); 6.35 6.36 /* (C) - only if data is remaining */ 6.37 coalesce_buf = NULL; 6.38 @@ -404,7 +403,7 @@ XenNet_HWSendPacket(struct xennet_info * 6.39 switch (lso_info.Transmit.Type) 6.40 { 6.41 case NDIS_TCP_LARGE_SEND_OFFLOAD_V1_TYPE: 6.42 - lso_info.LsoV1TransmitComplete.TcpPayload = UlongToPtr(tx_length - MAX_ETH_HEADER_LENGTH - pi.ip4_header_length - pi.tcp_header_length); 6.43 + lso_info.LsoV1TransmitComplete.TcpPayload = tx_length - MAX_ETH_HEADER_LENGTH - pi.ip4_header_length - pi.tcp_header_length; 6.44 break; 6.45 case NDIS_TCP_LARGE_SEND_OFFLOAD_V2_TYPE: 6.46 break; 6.47 @@ -749,15 +748,16 @@ XenNet_TxShutdown(xennet_info_t *xi) 6.48 //PNDIS_PACKET packet; 6.49 ////PMDL mdl; 6.50 ////ULONG i; 6.51 - //KIRQL OldIrql; 6.52 - UNREFERENCED_PARAMETER(xi); 6.53 + KIRQL old_irql; 6.54 + PNET_BUFFER nb; 6.55 + PNET_BUFFER_LIST nbl; 6.56 + PLIST_ENTRY nb_entry; 6.57 6.58 FUNCTION_ENTER(); 6.59 6.60 -#if 0 6.61 - KeAcquireSpinLock(&xi->tx_lock, &OldIrql); 6.62 + KeAcquireSpinLock(&xi->tx_lock, &old_irql); 6.63 xi->tx_shutting_down = TRUE; 6.64 - KeReleaseSpinLock(&xi->tx_lock, OldIrql); 6.65 + KeReleaseSpinLock(&xi->tx_lock, old_irql); 6.66 6.67 while (xi->tx_outstanding) 6.68 { 6.69 @@ -765,21 +765,24 @@ XenNet_TxShutdown(xennet_info_t *xi) 6.70 KeWaitForSingleObject(&xi->tx_idle_event, Executive, KernelMode, FALSE, NULL); 6.71 } 6.72 6.73 -#if (NTDDI_VERSION >= NTDDI_WINXP) 6.74 KeFlushQueuedDpcs(); 6.75 -#endif 6.76 6.77 /* Free packets in tx queue */ 6.78 nb_entry = RemoveHeadList(&xi->tx_waiting_pkt_list); 6.79 + /* if empty, the above returns head*, not NULL */ 6.80 while (nb_entry != &xi->tx_waiting_pkt_list) 6.81 { 6.82 - packet = CONTAINING_RECORD(nb_entry, NDIS_PACKET, MiniportReservedEx[sizeof(PVOID)]); 6.83 - NdisMSendComplete(xi->adapter_handle, packet, NDIS_STATUS_FAILURE); 6.84 + nb = CONTAINING_RECORD(nb_entry, NET_BUFFER, NB_LIST_ENTRY_FIELD); 6.85 + nbl = NB_NBL(nb); 6.86 + NBL_REF(nbl)--; 6.87 + if (!NBL_REF(nbl)) 6.88 + { 6.89 + nbl->Status = NDIS_STATUS_FAILURE; 6.90 + NdisMSendNetBufferListsComplete(xi->adapter_handle, nbl, NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL); 6.91 + } 6.92 nb_entry = RemoveHeadList(&xi->tx_waiting_pkt_list); 6.93 } 6.94 - 6.95 NdisDeleteNPagedLookasideList(&xi->tx_lookaside_list); 6.96 -#endif 6.97 6.98 FUNCTION_EXIT(); 6.99