win-pvdrivers

changeset 212:6f57a4124ab7

Added user configurable options to control panel. Started looking at rx large send.
author James Harper <james.harper@bendigoit.com.au>
date Sat Mar 15 00:44:03 2008 +1100 (2008-03-15)
parents 8c5a5b5bc5f0
children 9ae143ae1f91 f315522a2a3e
files common.inc xennet/xennet.c xennet/xennet.h xennet/xennet.inx xennet/xennet_oid.c xennet/xennet_rx.c
line diff
     1.1 --- a/common.inc	Thu Mar 13 20:57:33 2008 +1100
     1.2 +++ b/common.inc	Sat Mar 15 00:44:03 2008 +1100
     1.3 @@ -1,4 +1,4 @@
     1.4 -VERSION=0.8.5.0
     1.5 +VERSION=0.8.5.9
     1.6  TARGETPATH=..\Target\$(DDK_TARGET_OS)
     1.7  KMDF_VERSION=1
     1.8  !IF $(_NT_TOOLS_VERSION) > 0x700
     2.1 --- a/xennet/xennet.c	Thu Mar 13 20:57:33 2008 +1100
     2.2 +++ b/xennet/xennet.c	Sat Mar 15 00:44:03 2008 +1100
     2.3 @@ -201,21 +201,21 @@ XenNet_Init(
     2.4      {"tx-ring-ref", 0},
     2.5      {"rx-ring-ref", 0},
     2.6      {"event-channel", 0},
     2.7 +    {"feature-no-csum-offload", 1},
     2.8 +    {"feature-sg", 1},
     2.9 +    {"feature-gso-tcpv4", 1},
    2.10      {"request-rx-copy", 1},
    2.11      {"feature-rx-notify", 1},
    2.12 -//    {"feature-no-csum-offload", 1},
    2.13 -    {"feature-sg", 1},
    2.14 -#if defined(OFFLOAD_LARGE_SEND)
    2.15 -    {"feature-gso-tcpv4", 1},
    2.16 -#endif
    2.17      {NULL, 0},
    2.18    };
    2.19    int retry = 0;
    2.20    char *err;
    2.21    xenbus_transaction_t xbt = 0;
    2.22 +  NDIS_HANDLE config_handle;
    2.23 +  NDIS_STRING config_param_name;
    2.24 +  PNDIS_CONFIGURATION_PARAMETER config_param;
    2.25  
    2.26    UNREFERENCED_PARAMETER(OpenErrorStatus);
    2.27 -  UNREFERENCED_PARAMETER(WrapperConfigurationContext);
    2.28  
    2.29    KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    2.30    KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));
    2.31 @@ -252,6 +252,70 @@ XenNet_Init(
    2.32    xi->rx_min_target = RX_DFL_MIN_TARGET;
    2.33    xi->rx_max_target = RX_MAX_TARGET;
    2.34  
    2.35 +  NdisOpenConfiguration(&status, &config_handle, WrapperConfigurationContext);
    2.36 +  if (!NT_SUCCESS(status))
    2.37 +  {
    2.38 +    KdPrint(("Could not open config in registry (%08x)\n", status));
    2.39 +    goto err;
    2.40 +  }
    2.41 +
    2.42 +  NdisInitUnicodeString(&config_param_name, L"ScatterGather");
    2.43 +  NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger);
    2.44 +  if (!NT_SUCCESS(status))
    2.45 +  {
    2.46 +    KdPrint(("Could not read ScatterGather value (%08x)\n", status));
    2.47 +    xi->config_sg = 1;
    2.48 +  }
    2.49 +  else
    2.50 +  {
    2.51 +    KdPrint(("ScatterGather = %d\n", config_param->ParameterData.IntegerData));
    2.52 +    xi->config_sg = config_param->ParameterData.IntegerData;
    2.53 +  }
    2.54 +  
    2.55 +  NdisInitUnicodeString(&config_param_name, L"LargeSendOffload");
    2.56 +  NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger);
    2.57 +  if (!NT_SUCCESS(status))
    2.58 +  {
    2.59 +    KdPrint(("Could not read LargeSendOffload value (%08x)\n", status));
    2.60 +    xi->config_gso = 1;
    2.61 +  }
    2.62 +  else
    2.63 +  {
    2.64 +    KdPrint(("LargeSendOffload = %d\n", config_param->ParameterData.IntegerData));
    2.65 +    xi->config_gso = config_param->ParameterData.IntegerData;
    2.66 +    ASSERT(xi->config_gso <= 61440);
    2.67 +  }
    2.68 +
    2.69 +  NdisInitUnicodeString(&config_param_name, L"ChecksumOffload");
    2.70 +  NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger);
    2.71 +  if (!NT_SUCCESS(status))
    2.72 +  {
    2.73 +    KdPrint(("Could not read ChecksumOffload value (%08x)\n", status));
    2.74 +    xi->config_csum = 1;
    2.75 +  }
    2.76 +  else
    2.77 +  {
    2.78 +    KdPrint(("ChecksumOffload = %d\n", config_param->ParameterData.IntegerData));
    2.79 +    xi->config_csum = config_param->ParameterData.IntegerData;
    2.80 +  }
    2.81 +
    2.82 +  NdisInitUnicodeString(&config_param_name, L"MTU");
    2.83 +  NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger);  
    2.84 +  if (!NT_SUCCESS(status))
    2.85 +  {
    2.86 +    KdPrint(("Could not read MTU value (%08x)\n", status));
    2.87 +    xi->config_mtu = 1500;
    2.88 +  }
    2.89 +  else
    2.90 +  {
    2.91 +    KdPrint(("MTU = %d\n", config_param->ParameterData.IntegerData));
    2.92 +    xi->config_mtu = config_param->ParameterData.IntegerData;
    2.93 +  }
    2.94 +
    2.95 +  xi->config_max_pkt_size = max(xi->config_mtu + XN_HDR_SIZE, xi->config_gso + XN_HDR_SIZE);
    2.96 +  
    2.97 +  NdisCloseConfiguration(config_handle);
    2.98 +
    2.99    xi->state = XenbusStateUnknown;
   2.100    xi->backend_state = XenbusStateUnknown;
   2.101  
   2.102 @@ -297,14 +361,16 @@ XenNet_Init(
   2.103      0, (NDIS_ATTRIBUTE_DESERIALIZE | NDIS_ATTRIBUTE_BUS_MASTER),
   2.104      NdisInterfaceInternal);
   2.105  
   2.106 -  status = NdisMInitializeScatterGatherDma(xi->adapter_handle, TRUE, XN_MAX_PKT_SIZE);
   2.107 -  if (!NT_SUCCESS(status))
   2.108 +  if (xi->config_sg)
   2.109    {
   2.110 -    KdPrint(("NdisMInitializeScatterGatherDma failed with 0x%x\n", status));
   2.111 -    status = NDIS_STATUS_FAILURE;
   2.112 -    goto err;
   2.113 +    status = NdisMInitializeScatterGatherDma(xi->adapter_handle, TRUE, xi->config_max_pkt_size);
   2.114 +    if (!NT_SUCCESS(status))
   2.115 +    {
   2.116 +      KdPrint(("NdisMInitializeScatterGatherDma failed with 0x%x\n", status));
   2.117 +      status = NDIS_STATUS_FAILURE;
   2.118 +      goto err;
   2.119 +    }
   2.120    }
   2.121 -
   2.122    WDF_OBJECT_ATTRIBUTES_INIT(&wdf_attrs);
   2.123  
   2.124    status = WdfDeviceMiniportCreate(WdfGetDriver(), &wdf_attrs, xi->fdo,
   2.125 @@ -371,6 +437,9 @@ XenNet_Init(
   2.126    params[0].value = xi->tx_ring_ref;
   2.127    params[1].value = xi->rx_ring_ref;
   2.128    params[2].value = xi->event_channel;
   2.129 +  params[3].value = !xi->config_csum;
   2.130 +  params[4].value = xi->config_sg;
   2.131 +  params[5].value = !!xi->config_gso;
   2.132    xi->XenInterface.XenBus_StartTransaction(
   2.133      xi->XenInterface.InterfaceHeader.Context, &xbt);
   2.134  
     3.1 --- a/xennet/xennet.h	Thu Mar 13 20:57:33 2008 +1100
     3.2 +++ b/xennet/xennet.h	Sat Mar 15 00:44:03 2008 +1100
     3.3 @@ -73,19 +73,19 @@ Foundation, Inc., 51 Franklin Street, Fi
     3.4  #pragma warning(disable: 4127) // conditional expression is constant
     3.5  
     3.6  //#define XEN_PROFILE
     3.7 -#define OFFLOAD_LARGE_SEND
     3.8  #define MIN_LARGE_SEND_SEGMENTS 4
     3.9 -#define MAX_LARGE_SEND_OFFLOAD 65535
    3.10  
    3.11  /* TODO: crank this up if we support higher mtus? */
    3.12  #define XN_DATA_SIZE 1500
    3.13  #define XN_HDR_SIZE 14
    3.14  #define XN_MIN_PKT_SIZE 60
    3.15 +/*
    3.16  #if !defined(OFFLOAD_LARGE_SEND)
    3.17    #define XN_MAX_PKT_SIZE (XN_HDR_SIZE + XN_DATA_SIZE)
    3.18  #else
    3.19    #define XN_MAX_PKT_SIZE MAX_LARGE_SEND_OFFLOAD
    3.20  #endif
    3.21 +*/
    3.22  
    3.23  #define XN_MAX_SEND_PKTS 16
    3.24  
    3.25 @@ -168,6 +168,15 @@ struct xennet_info
    3.26    LONG rx_outstanding;
    3.27    LONG tx_outstanding;
    3.28  
    3.29 +  /* config vars from registry */
    3.30 +  ULONG config_sg;
    3.31 +  ULONG config_csum;
    3.32 +  ULONG config_gso;
    3.33 +  ULONG config_mtu;
    3.34 +
    3.35 +  /* config stuff calculated from the above */
    3.36 +  ULONG config_max_pkt_size;
    3.37 +
    3.38    /* stats */
    3.39    ULONG64 stat_tx_ok;
    3.40    ULONG64 stat_rx_ok;
     4.1 --- a/xennet/xennet.inx	Thu Mar 13 20:57:33 2008 +1100
     4.2 +++ b/xennet/xennet.inx	Sat Mar 15 00:44:03 2008 +1100
     4.3 @@ -40,13 +40,43 @@ ExcludeFromSelect=*
     4.4  [XenNet_Inst.NT]
     4.5  CopyFiles=XenNet.CopyFiles
     4.6  Characteristics = 0x1 ; NCF_VIRTUAL
     4.7 -AddReg = XenNet_Reg
     4.8 +AddReg = XenNet_Reg, XenNet_Params
     4.9  
    4.10  [XenNet_Reg]
    4.11  HKR, Ndi, Service, 0, "XenNet"
    4.12  HKR, Ndi\Interfaces, UpperRange, 0, "ndis5"
    4.13  HKR, Ndi\Interfaces, LowerRange, 0, "ethernet"
    4.14  
    4.15 +[XenNet_Params]
    4.16 +HKR, Ndi\Params\MTU, ParamDesc, , "MTU"
    4.17 +HKR, Ndi\Params\MTU, default, , "1500"
    4.18 +HKR, Ndi\Params\MTU, type, , "dword"
    4.19 +HKR, Ndi\Params\MTU, min, , "1500"
    4.20 +HKR, Ndi\Params\MTU, max, , "9000"
    4.21 +HKR, Ndi\Params\MTU, step, , "500"
    4.22 +HKR, Ndi\Params\MTU, base, , "10"
    4.23 +
    4.24 +HKR, Ndi\Params\ChecksumOffload, ParamDesc, , "Checksum Offload"
    4.25 +HKR, Ndi\Params\ChecksumOffload, default, , "1"
    4.26 +HKR, Ndi\Params\ChecksumOffload, type, , "enum"
    4.27 +HKR, Ndi\Params\ChecksumOffload\enum, 0, , "Disabled"
    4.28 +HKR, Ndi\Params\ChecksumOffload\enum, 1, , "Enabled"
    4.29 +
    4.30 +HKR, Ndi\Params\LargeSendOffload, ParamDesc, , "Large Send Offload"
    4.31 +HKR, Ndi\Params\LargeSendOffload, default, , "65535"
    4.32 +HKR, Ndi\Params\LargeSendOffload, type, , "enum"
    4.33 +HKR, Ndi\Params\LargeSendOffload\enum, 0, , "Disabled"
    4.34 +HKR, Ndi\Params\LargeSendOffload\enum, 8192, , "8192"
    4.35 +HKR, Ndi\Params\LargeSendOffload\enum, 16384, , "16384"
    4.36 +HKR, Ndi\Params\LargeSendOffload\enum, 32768, , "32768"
    4.37 +HKR, Ndi\Params\LargeSendOffload\enum, 61440, , "61440"
    4.38 +
    4.39 +HKR, Ndi\Params\ScatterGather, ParamDesc, , "Scatter/Gather"
    4.40 +HKR, Ndi\Params\ScatterGather, default, , "1"
    4.41 +HKR, Ndi\Params\ScatterGather, type, , "enum"
    4.42 +HKR, Ndi\Params\ScatterGather\enum, 0, , "Disabled"
    4.43 +HKR, Ndi\Params\ScatterGather\enum, 1, , "Enabled"
    4.44 +
    4.45  [XenNet.CopyFiles]
    4.46  xennet.sys
    4.47  
     5.1 --- a/xennet/xennet_oid.c	Thu Mar 13 20:57:33 2008 +1100
     5.2 +++ b/xennet/xennet_oid.c	Sat Mar 15 00:44:03 2008 +1100
     5.3 @@ -87,9 +87,7 @@ XenNet_QueryInformation(
     5.4    PNDIS_TASK_OFFLOAD_HEADER ntoh;
     5.5    PNDIS_TASK_OFFLOAD nto;
     5.6    PNDIS_TASK_TCP_IP_CHECKSUM nttic;
     5.7 -#ifdef OFFLOAD_LARGE_SEND
     5.8    PNDIS_TASK_TCP_LARGE_SEND nttls;
     5.9 -#endif
    5.10  
    5.11  //  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    5.12  
    5.13 @@ -157,11 +155,7 @@ XenNet_QueryInformation(
    5.14        len = 2;
    5.15        break;
    5.16      case OID_GEN_MAXIMUM_TOTAL_SIZE:
    5.17 -#if !defined(OFFLOAD_LARGE_SEND)
    5.18 -      temp_data = XN_MAX_PKT_SIZE;
    5.19 -#else
    5.20 -      temp_data = MAX_LARGE_SEND_OFFLOAD;
    5.21 -#endif
    5.22 +      temp_data = xi->config_max_pkt_size;
    5.23        break;
    5.24      case OID_GEN_MAC_OPTIONS:
    5.25        temp_data = NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA | 
    5.26 @@ -219,10 +213,12 @@ XenNet_QueryInformation(
    5.27  
    5.28        len += FIELD_OFFSET(NDIS_TASK_OFFLOAD, TaskBuffer)
    5.29          + sizeof(NDIS_TASK_TCP_IP_CHECKSUM);
    5.30 -#ifdef OFFLOAD_LARGE_SEND
    5.31 -      len += FIELD_OFFSET(NDIS_TASK_OFFLOAD, TaskBuffer)
    5.32 -        + sizeof(NDIS_TASK_TCP_LARGE_SEND);
    5.33 -#endif
    5.34 +
    5.35 +      if (xi->config_gso)
    5.36 +      {
    5.37 +        len += FIELD_OFFSET(NDIS_TASK_OFFLOAD, TaskBuffer)
    5.38 +          + sizeof(NDIS_TASK_TCP_LARGE_SEND);
    5.39 +      }
    5.40  
    5.41        if (len > InformationBufferLength)
    5.42        {
    5.43 @@ -267,26 +263,28 @@ XenNet_QueryInformation(
    5.44        nttic->V6Receive.TcpChecksum = 0;
    5.45        nttic->V6Receive.UdpChecksum = 0;
    5.46  
    5.47 -#ifdef OFFLOAD_LARGE_SEND
    5.48 -      /* offset from start of current NTO to start of next NTO */
    5.49 -      nto->OffsetNextTask = FIELD_OFFSET(NDIS_TASK_OFFLOAD, TaskBuffer)
    5.50 -        + nto->TaskBufferLength;
    5.51 +      if (xi->config_gso)
    5.52 +      {
    5.53 +        /* offset from start of current NTO to start of next NTO */
    5.54 +        nto->OffsetNextTask = FIELD_OFFSET(NDIS_TASK_OFFLOAD, TaskBuffer)
    5.55 +          + nto->TaskBufferLength;
    5.56 +  
    5.57 +        /* fill in second nto */
    5.58 +        nto = (PNDIS_TASK_OFFLOAD)((PCHAR)(nto) + nto->OffsetNextTask);
    5.59 +        nto->Version = NDIS_TASK_OFFLOAD_VERSION;
    5.60 +        nto->Size = sizeof(NDIS_TASK_OFFLOAD);
    5.61 +        nto->Task = TcpLargeSendNdisTask;
    5.62 +        nto->TaskBufferLength = sizeof(NDIS_TASK_TCP_LARGE_SEND);
    5.63 +  
    5.64 +        /* fill in large send struct */
    5.65 +        nttls = (PNDIS_TASK_TCP_LARGE_SEND)nto->TaskBuffer;
    5.66 +        nttls->Version = 0;
    5.67 +        nttls->MaxOffLoadSize = xi->config_gso;
    5.68 +        nttls->MinSegmentCount = MIN_LARGE_SEND_SEGMENTS;
    5.69 +        nttls->TcpOptions = TRUE;
    5.70 +        nttls->IpOptions = TRUE;
    5.71 +      }
    5.72  
    5.73 -      /* fill in second nto */
    5.74 -      nto = (PNDIS_TASK_OFFLOAD)((PCHAR)(nto) + nto->OffsetNextTask);
    5.75 -      nto->Version = NDIS_TASK_OFFLOAD_VERSION;
    5.76 -      nto->Size = sizeof(NDIS_TASK_OFFLOAD);
    5.77 -      nto->Task = TcpLargeSendNdisTask;
    5.78 -      nto->TaskBufferLength = sizeof(NDIS_TASK_TCP_LARGE_SEND);
    5.79 -
    5.80 -      /* fill in large send struct */
    5.81 -      nttls = (PNDIS_TASK_TCP_LARGE_SEND)nto->TaskBuffer;
    5.82 -      nttls->Version = 0;
    5.83 -      nttls->MaxOffLoadSize = MAX_LARGE_SEND_OFFLOAD;
    5.84 -      nttls->MinSegmentCount = MIN_LARGE_SEND_SEGMENTS;
    5.85 -      nttls->TcpOptions = TRUE;
    5.86 -      nttls->IpOptions = TRUE;
    5.87 -#endif
    5.88        nto->OffsetNextTask = 0; /* last one */
    5.89  
    5.90        used_temp_buffer = FALSE;
    5.91 @@ -337,9 +335,7 @@ XenNet_SetInformation(
    5.92    PNDIS_TASK_OFFLOAD_HEADER ntoh;
    5.93    PNDIS_TASK_OFFLOAD nto;
    5.94    PNDIS_TASK_TCP_IP_CHECKSUM nttic;
    5.95 -#ifdef OFFLOAD_LARGE_SEND
    5.96    PNDIS_TASK_TCP_LARGE_SEND nttls;
    5.97 -#endif
    5.98    int offset;
    5.99  
   5.100  //  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
     6.1 --- a/xennet/xennet_rx.c	Thu Mar 13 20:57:33 2008 +1100
     6.2 +++ b/xennet/xennet_rx.c	Sat Mar 15 00:44:03 2008 +1100
     6.3 @@ -145,6 +145,48 @@ XenNet_RxBufferAlloc(struct xennet_info 
     6.4    return NDIS_STATUS_SUCCESS;
     6.5  }
     6.6  
     6.7 +static VOID
     6.8 +XenNet_SplitRxPacket(
     6.9 + PNDIS_PACKET *packets,
    6.10 + PULONG packet_count,
    6.11 + ULONG total_packet_length
    6.12 +)
    6.13 +{
    6.14 +  ULONG mss = PtrToUlong(NDIS_PER_PACKET_INFO_FROM_PACKET(packets[*packet_count], TcpLargeSendPacketInfo));
    6.15 +  ULONG header_length = 54; //TODO: actually calculate this from the TCP header
    6.16 +  ULONG tcp_length = total_packet_length - header_length;
    6.17 +  ULONG remaining = tcp_length;
    6.18 +
    6.19 +  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    6.20 +
    6.21 +  KdPrint((__DRIVER_NAME "     mss = %d\n", mss));
    6.22 +
    6.23 +/*
    6.24 +  while (remaining)
    6.25 +  {
    6.26 +    // take the buffers off of the current packet
    6.27 +    KdPrint((__DRIVER_NAME "     Remaining = %d\n", remaining));
    6.28 +
    6.29 +    if (remaining > mss)
    6.30 +    {
    6.31 +      // tcp length = mss;
    6.32 +      remaining -= mss;
    6.33 +    }
    6.34 +    else
    6.35 +    {
    6.36 +      // tcp length = remaining
    6.37 +      remaining = 0;
    6.38 +    }
    6.39 +    // do some creative stuff here... clone the header of the previous packet and update the various fields
    6.40 +    // append the remaining data buffers
    6.41 +    // increment the packet count
    6.42 +  }
    6.43 +*/  
    6.44 +  KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ "\n"));
    6.45 +
    6.46 +  return;
    6.47 +}
    6.48 +
    6.49  // Called at DISPATCH_LEVEL
    6.50  NDIS_STATUS
    6.51  XenNet_RxBufferCheck(struct xennet_info *xi)
    6.52 @@ -212,7 +254,7 @@ XenNet_RxBufferCheck(struct xennet_info 
    6.53            {
    6.54            case XEN_NETIF_GSO_TYPE_TCPV4:
    6.55  //KdPrint((__DRIVER_NAME "     GSO_TYPE_TCPV4 detected\n"));
    6.56 -//            NDIS_PER_PACKET_INFO_FROM_PACKET(packets[packet_count], TcpLargeSendPacketInfo) = (PVOID)(xen_ulong_t)(ei->u.gso.size);
    6.57 +            NDIS_PER_PACKET_INFO_FROM_PACKET(packets[packet_count], TcpLargeSendPacketInfo) = (PVOID)(xen_ulong_t)(ei->u.gso.size);
    6.58              break;
    6.59            default:
    6.60              KdPrint((__DRIVER_NAME "     Unknown GSO type (%d) detected\n", ei->u.gso.type));
    6.61 @@ -243,6 +285,7 @@ XenNet_RxBufferCheck(struct xennet_info 
    6.62            NdisAllocatePacket(&status, &packets[packet_count], xi->packet_pool);
    6.63            ASSERT(status == NDIS_STATUS_SUCCESS);
    6.64            NDIS_SET_PACKET_HEADER_SIZE(packets[packet_count], XN_HDR_SIZE);
    6.65 +          NDIS_PER_PACKET_INFO_FROM_PACKET(packets[packet_count], TcpLargeSendPacketInfo) = 0;
    6.66            if (rxrsp->flags & (NETRXF_csum_blank|NETRXF_data_validated)) // and we are enabled for offload...
    6.67            {
    6.68              csum_info = (PNDIS_TCP_IP_CHECKSUM_PACKET_INFO)&NDIS_PER_PACKET_INFO_FROM_PACKET(packets[packet_count], TcpIpChecksumPacketInfo);
    6.69 @@ -253,7 +296,6 @@ XenNet_RxBufferCheck(struct xennet_info 
    6.70              ProfCount_RxPacketsCsumOffload++;
    6.71  #endif
    6.72            }
    6.73 -          // we also need to manually split gso packets that we receive that originated on our side of the physical interface...
    6.74          }
    6.75          else
    6.76          {
    6.77 @@ -279,6 +321,13 @@ XenNet_RxBufferCheck(struct xennet_info 
    6.78  #endif
    6.79          xi->stat_rx_ok++;
    6.80          NDIS_SET_PACKET_STATUS(packets[packet_count], NDIS_STATUS_SUCCESS);
    6.81 +
    6.82 +        if (total_packet_length > xi->config_mtu + XN_HDR_SIZE)
    6.83 +        {
    6.84 +          KdPrint((__DRIVER_NAME "     total_packet_length %d, config_mtu = %d\n", total_packet_length, xi->config_mtu));
    6.85 +          XenNet_SplitRxPacket(packets, &packet_count, total_packet_length);
    6.86 +        }
    6.87 +
    6.88          packet_count++;
    6.89        }
    6.90      }