win-pvdrivers
changeset 1070:05ece536b204
Fix LSO bug on FIN packets. Add RxCoalesce option (default on) to work around Cisco VPN issues
author | James Harper <james.harper@bendigoit.com.au> |
---|---|
date | Wed Nov 13 07:56:13 2013 +1100 (2013-11-13) |
parents | 1b80cc14ee6d |
children | 83201dc2ea3f |
files | xennet/xennet.c xennet/xennet.h xennet/xennet.inx xennet/xennet_common.c xennet/xennet_rx.c |
line diff
1.1 --- a/xennet/xennet.c Tue Nov 12 21:17:26 2013 +1100 1.2 +++ b/xennet/xennet.c Wed Nov 13 07:56:13 2013 +1100 1.3 @@ -180,7 +180,7 @@ XenNet_Initialize(NDIS_HANDLE adapter_ha 1.4 1.5 NdisInitUnicodeString(&config_param_name, L"ScatterGather"); 1.6 NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger); 1.7 - if (!NT_SUCCESS(status)) 1.8 + if (!NT_SUCCESS(status)) 1.9 { 1.10 FUNCTION_MSG("Could not read ScatterGather value (%08x)\n", status); 1.11 xi->frontend_sg_supported = TRUE; 1.12 @@ -192,6 +192,16 @@ XenNet_Initialize(NDIS_HANDLE adapter_ha 1.13 FUNCTION_MSG("No support for SG with NDIS 6.0, disabled\n"); 1.14 xi->frontend_sg_supported = FALSE; 1.15 } 1.16 + 1.17 + NdisInitUnicodeString(&config_param_name, L"RxCoalesce"); 1.18 + NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger); 1.19 + if (!NT_SUCCESS(status)) { 1.20 + FUNCTION_MSG("Could not read RxCoalesce value (%08x)\n", status); 1.21 + xi->config_rx_coalesce = TRUE; 1.22 + } else { 1.23 + FUNCTION_MSG("RxCoalesce = %d\n", config_param->ParameterData.IntegerData); 1.24 + xi->config_rx_coalesce = (BOOLEAN)!!config_param->ParameterData.IntegerData; 1.25 + } 1.26 1.27 NdisInitUnicodeString(&config_param_name, L"LargeSendOffload"); 1.28 NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger);
2.1 --- a/xennet/xennet.h Tue Nov 12 21:17:26 2013 +1100 2.2 +++ b/xennet/xennet.h Wed Nov 13 07:56:13 2013 +1100 2.3 @@ -186,7 +186,9 @@ SET_NET_ULONG(PVOID ptr, ULONG data) { 2.4 #define MAX_PKT_HEADER_LENGTH (MAX_ETH_HEADER_LENGTH + MAX_IP4_HEADER_LENGTH + MAX_TCP_HEADER_LENGTH) 2.5 2.6 #define MIN_LOOKAHEAD_LENGTH (MAX_IP4_HEADER_LENGTH + MAX_TCP_HEADER_LENGTH) 2.7 -#define MAX_LOOKAHEAD_LENGTH PAGE_SIZE 2.8 +//#define MAX_LOOKAHEAD_LENGTH PAGE_SIZE 2.9 +/* optimise the size of header buffers */ 2.10 +#define MAX_LOOKAHEAD_LENGTH (512 - sizeof(shared_buffer_t) - MAX_ETH_HEADER_LENGTH) 2.11 2.12 #define LINUX_MAX_SG_ELEMENTS 18 2.13 2.14 @@ -361,6 +363,7 @@ struct xennet_info 2.15 2.16 BOOLEAN config_csum_rx_check; 2.17 BOOLEAN config_csum_rx_dont_fix; 2.18 + BOOLEAN config_rx_coalesce; 2.19 2.20 #if NTDDI_VERSION < NTDDI_VISTA 2.21 NDIS_TASK_TCP_IP_CHECKSUM setting_csum;
3.1 --- a/xennet/xennet.inx Tue Nov 12 21:17:26 2013 +1100 3.2 +++ b/xennet/xennet.inx Wed Nov 13 07:56:13 2013 +1100 3.3 @@ -74,6 +74,12 @@ HKR, Ndi\Params\ScatterGather, type, , " 3.4 HKR, Ndi\Params\ScatterGather\enum, 0, , "Disabled" 3.5 HKR, Ndi\Params\ScatterGather\enum, 1, , "Enabled" 3.6 3.7 +HKR, Ndi\Params\RxCoalesce, ParamDesc, , "Rx Coalesce" 3.8 +HKR, Ndi\Params\RxCoalesce, default, , "1" 3.9 +HKR, Ndi\Params\RxCoalesce, type, , "enum" 3.10 +HKR, Ndi\Params\RxCoalesce\enum, 0, , "Disabled" 3.11 +HKR, Ndi\Params\RxCoalesce\enum, 1, , "Enabled" 3.12 + 3.13 HKR, Ndi\Params\NetworkAddress, ParamDesc, , "Locally Administered Address" 3.14 HKR, Ndi\Params\NetworkAddress, Type, , "edit" 3.15 HKR, Ndi\Params\NetworkAddress, LimitText, , "12"
4.1 --- a/xennet/xennet_common.c Tue Nov 12 21:17:26 2013 +1100 4.2 +++ b/xennet/xennet_common.c Wed Nov 13 07:56:13 2013 +1100 4.3 @@ -41,8 +41,10 @@ XenNet_BuildHeader(packet_info_t *pi, PU 4.4 } 4.5 4.6 if (header == pi->first_mdl_virtual) { 4.7 + ASSERT(new_header_size <= PAGE_SIZE); 4.8 /* still working in the first buffer */ 4.9 if (new_header_size <= pi->first_mdl_length) { 4.10 + /* Trivially expand header_length */ 4.11 pi->header_length = new_header_size; 4.12 if (pi->header_length == pi->first_mdl_length) { 4.13 #if NTDDI_VERSION < NTDDI_VISTA 4.14 @@ -56,16 +58,12 @@ XenNet_BuildHeader(packet_info_t *pi, PU 4.15 } else { 4.16 pi->curr_mdl_offset = (USHORT)new_header_size; 4.17 } 4.18 - //FUNCTION_EXIT(); 4.19 - return TRUE; 4.20 - } else { 4.21 - memcpy(pi->header_data, header, pi->header_length); 4.22 - header = pi->header = pi->header_data; 4.23 } 4.24 + } else { 4.25 + ASSERT(new_header_size <= MAX_LOOKAHEAD_LENGTH + MAX_ETH_HEADER_LENGTH); 4.26 } 4.27 4.28 bytes_remaining = new_header_size - pi->header_length; 4.29 - // TODO: if there are only a small number of bytes left in the current buffer then increase to consume that too... it would have to be no more than the size of header+mss though 4.30 4.31 while (bytes_remaining && pi->curr_mdl) { 4.32 ULONG copy_size;
5.1 --- a/xennet/xennet_rx.c Tue Nov 12 21:17:26 2013 +1100 5.2 +++ b/xennet/xennet_rx.c Wed Nov 13 07:56:13 2013 +1100 5.3 @@ -376,10 +376,11 @@ XenNet_MakePacket(struct xennet_info *xi 5.4 } 5.5 #endif 5.6 5.7 - if (!pi->first_mdl->Next && !pi->split_required) { 5.8 + if ((!pi->first_mdl->Next || (xi->config_rx_coalesce && pi->total_length <= PAGE_SIZE)) && !pi->split_required) { 5.9 /* a single buffer <= MTU */ 5.10 header_buf = NULL; 5.11 - XenNet_BuildHeader(pi, pi->first_mdl_virtual, pi->first_mdl_length); 5.12 + /* get all the packet into the header */ 5.13 + XenNet_BuildHeader(pi, pi->first_mdl_virtual, PAGE_SIZE); 5.14 #if NTDDI_VERSION < NTDDI_VISTA 5.15 NdisChainBufferAtBack(packet, pi->first_mdl); 5.16 PACKET_FIRST_PB(packet) = pi->first_pb; 5.17 @@ -629,7 +630,7 @@ XenNet_MakePacket(struct xennet_info *xi 5.18 static VOID 5.19 XenNet_MakePackets(struct xennet_info *xi, rx_context_t *rc, packet_info_t *pi) 5.20 { 5.21 - UCHAR psh; 5.22 + UCHAR tcp_flags; 5.23 shared_buffer_t *page_buf; 5.24 5.25 XenNet_ParsePacketHeader(pi, NULL, XN_HDR_SIZE + xi->current_lookahead); 5.26 @@ -686,8 +687,14 @@ XenNet_MakePackets(struct xennet_info *x 5.27 pi->tcp_remaining = pi->tcp_length; 5.28 5.29 /* we can make certain assumptions here as the following code is only for tcp4 */ 5.30 - psh = pi->header[XN_HDR_SIZE + pi->ip4_header_length + 13] & 8; 5.31 + tcp_flags = pi->header[XN_HDR_SIZE + pi->ip4_header_length + 13]; 5.32 + /* clear all tcp flags except ack except for the last packet */ 5.33 + pi->header[XN_HDR_SIZE + pi->ip4_header_length + 13] &= 0x10; 5.34 while (pi->tcp_remaining) { 5.35 + if (pi->tcp_remaining <= pi->mss) { 5.36 + /* restore tcp flags for the last packet */ 5.37 + pi->header[XN_HDR_SIZE + pi->ip4_header_length + 13] = tcp_flags; 5.38 + } 5.39 if (!XenNet_MakePacket(xi, rc, pi)) { 5.40 FUNCTION_MSG("Failed to make packet\n"); 5.41 #if NTDDI_VERSION < NTDDI_VISTA 5.42 @@ -697,12 +704,6 @@ XenNet_MakePackets(struct xennet_info *x 5.43 #endif 5.44 break; /* we are out of memory - just drop the packets */ 5.45 } 5.46 - if (psh) { 5.47 - if (pi->tcp_remaining) 5.48 - pi->header[XN_HDR_SIZE + pi->ip4_header_length + 13] &= ~8; 5.49 - else 5.50 - pi->header[XN_HDR_SIZE + pi->ip4_header_length + 13] |= 8; 5.51 - } 5.52 } 5.53 done: 5.54 page_buf = pi->first_pb;