win-pvdrivers

changeset 919:ebffcc1112a3

ndis6 xennet now working except for poor performance in the rx direction
author James Harper <james.harper@bendigoit.com.au>
date Tue May 10 19:50:46 2011 +1000 (2011-05-10)
parents 20d89c3113ec
children a61e4e452f43
files xennet/xennet.inx xennet/xennet6.c xennet/xennet6_common.c xennet/xennet6_rx.c xennet/xennet6_tx.c
line diff
     1.1 --- a/xennet/xennet.inx	Thu May 05 22:39:13 2011 +1000
     1.2 +++ b/xennet/xennet.inx	Tue May 10 19:50:46 2011 +1000
     1.3 @@ -61,6 +61,12 @@ HKR, Ndi\Params\ChecksumOffloadDontFix, 
     1.4  HKR, Ndi\Params\ChecksumOffloadDontFix\enum, 0, , "Disabled"
     1.5  HKR, Ndi\Params\ChecksumOffloadDontFix\enum, 1, , "Enabled"
     1.6  
     1.7 +HKR, Ndi\Params\LargeSendOffloadRxSplitMTU, ParamDesc, , "Allow received packets larger than MTU"
     1.8 +HKR, Ndi\Params\LargeSendOffloadRxSplitMTU, default, , "0"
     1.9 +HKR, Ndi\Params\LargeSendOffloadRxSplitMTU, type, , "enum"
    1.10 +HKR, Ndi\Params\LargeSendOffloadRxSplitMTU\enum, 0, , "Disabled"
    1.11 +HKR, Ndi\Params\LargeSendOffloadRxSplitMTU\enum, 1, , "Enabled"
    1.12 +
    1.13  HKR, Ndi\Params\LargeSendOffload, ParamDesc, , "Large Send Offload"
    1.14  HKR, Ndi\Params\LargeSendOffload, default, , "61440"
    1.15  HKR, Ndi\Params\LargeSendOffload, type, , "enum"
     2.1 --- a/xennet/xennet6.c	Thu May 05 22:39:13 2011 +1000
     2.2 +++ b/xennet/xennet6.c	Tue May 10 19:50:46 2011 +1000
     2.3 @@ -344,6 +344,7 @@ XenNet_HandleEvent(PVOID context)
     2.4  {
     2.5    struct xennet_info *xi = context;
     2.6    ULONG suspend_resume_state_pdo;
     2.7 +  LARGE_INTEGER dpc_requeued;
     2.8    
     2.9    //FUNCTION_ENTER();
    2.10    suspend_resume_state_pdo = xi->device_state->suspend_resume_state_pdo;
     3.1 --- a/xennet/xennet6_common.c	Thu May 05 22:39:13 2011 +1000
     3.2 +++ b/xennet/xennet6_common.c	Tue May 10 19:50:46 2011 +1000
     3.3 @@ -275,7 +275,7 @@ XenNet_FilterAcceptPacket(struct xennet_
     3.4    if (is_directed && (xi->packet_filter & NDIS_PACKET_TYPE_DIRECTED))
     3.5    {
     3.6      return TRUE;
     3.7 -  }  
     3.8 +  }
     3.9    if (is_my_multicast && (xi->packet_filter & NDIS_PACKET_TYPE_MULTICAST))
    3.10    {
    3.11      return TRUE;
    3.12 @@ -292,5 +292,6 @@ XenNet_FilterAcceptPacket(struct xennet_
    3.13    {
    3.14      return TRUE;
    3.15    }
    3.16 -  return FALSE;
    3.17 +  return TRUE;
    3.18 +  //return FALSE;
    3.19  }
     4.1 --- a/xennet/xennet6_rx.c	Thu May 05 22:39:13 2011 +1000
     4.2 +++ b/xennet/xennet6_rx.c	Tue May 10 19:50:46 2011 +1000
     4.3 @@ -184,72 +184,18 @@ XenNet_FillRing(struct xennet_info *xi)
     4.4    return NDIS_STATUS_SUCCESS;
     4.5  }
     4.6  
     4.7 -#if 0
     4.8 -/* lock free */
     4.9 -static PNDIS_PACKET
    4.10 -get_packet_from_freelist(struct xennet_info *xi)
    4.11 -{
    4.12 -  NDIS_STATUS status;
    4.13 -  PNDIS_PACKET packet;
    4.14 -  PVOID ptr_ref;
    4.15 -
    4.16 -  if (stack_pop(xi->rx_packet_stack, &ptr_ref))
    4.17 -  {
    4.18 -    packet = ptr_ref;
    4.19 -    InterlockedIncrement(&total_allocated_packets);
    4.20 -    return packet;
    4.21 -  }
    4.22 -  
    4.23 -  if (xi->rx_shutting_down) /* don't keep allocating new packets on shutdown */
    4.24 -    return NULL;
    4.25 -
    4.26 -  NdisAllocatePacket(&status, &packet, xi->rx_packet_pool);
    4.27 -  if (status != NDIS_STATUS_SUCCESS)
    4.28 -  {
    4.29 -    KdPrint((__DRIVER_NAME "     cannot allocate packet\n"));
    4.30 -    return NULL;
    4.31 -  }
    4.32 -  NDIS_SET_PACKET_HEADER_SIZE(packet, XN_HDR_SIZE);
    4.33 -  NdisZeroMemory(packet->MiniportReservedEx, sizeof(packet->MiniportReservedEx));
    4.34 -  InterlockedIncrement(&total_allocated_packets);
    4.35 -  return packet;
    4.36 -}
    4.37 -
    4.38 -/* lock free */
    4.39 -static VOID
    4.40 -put_packet_on_freelist(struct xennet_info *xi, PNDIS_PACKET packet)
    4.41 -{
    4.42 -  PNDIS_TCP_IP_CHECKSUM_PACKET_INFO csum_info;
    4.43 -
    4.44 -  UNREFERENCED_PARAMETER(xi);
    4.45 -  
    4.46 -  InterlockedDecrement(&total_allocated_packets);
    4.47 -
    4.48 -  NdisReinitializePacket(packet);
    4.49 -  RtlZeroMemory(NDIS_PACKET_EXTENSION_FROM_PACKET(packet), sizeof(NDIS_PACKET_EXTENSION));
    4.50 -  csum_info = (PNDIS_TCP_IP_CHECKSUM_PACKET_INFO)&NDIS_PER_PACKET_INFO_FROM_PACKET(
    4.51 -    packet, TcpIpChecksumPacketInfo);
    4.52 -  csum_info->Value = 0;
    4.53 -
    4.54 -  stack_push(xi->rx_packet_stack, packet);
    4.55 -}
    4.56 -#endif
    4.57 -
    4.58  static BOOLEAN
    4.59  XenNet_MakePacket(struct xennet_info *xi, PNET_BUFFER_LIST nbl, packet_info_t *pi)
    4.60  {
    4.61    PNET_BUFFER nb;
    4.62    PMDL mdl_head, mdl_tail, curr_mdl;
    4.63 -  USHORT new_ip4_length;
    4.64    PUCHAR header_va;
    4.65    ULONG out_remaining;
    4.66 -  ULONG tcp_length;
    4.67    ULONG header_extra;
    4.68    shared_buffer_t *header_buf;
    4.69  
    4.70    //FUNCTION_ENTER();
    4.71    
    4.72 -  ASSERT(!pi->split_required);
    4.73    nb = NdisAllocateNetBuffer(xi->rx_nb_pool, NULL, 0, 0);
    4.74    if (!nb)
    4.75    {
    4.76 @@ -275,10 +221,8 @@ XenNet_MakePacket(struct xennet_info *xi
    4.77    /* make sure we satisfy the lookahead requirement */
    4.78    if (pi->split_required)
    4.79    {
    4.80 -#if 0  
    4.81      /* for split packets we need to make sure the 'header' is no bigger than header+mss bytes */
    4.82      XenNet_BuildHeader(pi, header_va, min((ULONG)MAX_ETH_HEADER_LENGTH + pi->ip4_header_length + pi->tcp_header_length + pi->mss, MAX_ETH_HEADER_LENGTH + max(MIN_LOOKAHEAD_LENGTH, xi->current_lookahead)));
    4.83 -#endif
    4.84    }
    4.85    else
    4.86    {
    4.87 @@ -300,6 +244,8 @@ XenNet_MakePacket(struct xennet_info *xi
    4.88  
    4.89    if (pi->split_required)
    4.90    {
    4.91 +    ULONG tcp_length;
    4.92 +    USHORT new_ip4_length;
    4.93      tcp_length = (USHORT)min(pi->mss, pi->tcp_remaining);
    4.94      new_ip4_length = (USHORT)(pi->ip4_header_length + pi->tcp_header_length + tcp_length);
    4.95      //KdPrint((__DRIVER_NAME "     new_ip4_length = %d\n", new_ip4_length));
    4.96 @@ -328,7 +274,7 @@ XenNet_MakePacket(struct xennet_info *xi
    4.97      //KdPrint((__DRIVER_NAME "     in loop - out_remaining = %d, curr_buffer = %p, curr_pb = %p\n", out_remaining, pi->curr_mdl, pi->curr_pb));
    4.98      if (!pi->curr_mdl || !pi->curr_pb)
    4.99      {
   4.100 -      //KdPrint((__DRIVER_NAME "     out of buffers for packet\n"));
   4.101 +      KdPrint((__DRIVER_NAME "     out of buffers for packet\n"));
   4.102        //KdPrint((__DRIVER_NAME "     out_remaining = %d, curr_buffer = %p, curr_pb = %p\n", out_remaining, pi->curr_mdl, pi->curr_pb));
   4.103        // TODO: free some stuff or we'll leak
   4.104        /* unchain buffers then free packet */
   4.105 @@ -336,10 +282,8 @@ XenNet_MakePacket(struct xennet_info *xi
   4.106        return FALSE;
   4.107      }
   4.108  
   4.109 -    //NdisQueryBufferOffset(pi->curr_buffer, &in_buffer_offset, &in_buffer_length);
   4.110      in_buffer_length = MmGetMdlByteCount(pi->curr_mdl);
   4.111      out_length = min(out_remaining, in_buffer_length - pi->curr_mdl_offset);
   4.112 -    //NdisCopyBuffer(&status, &out_buffer, xi->rx_buffer_pool, pi->curr_buffer, pi->curr_mdl_offset, out_length);
   4.113      curr_mdl = IoAllocateMdl((PUCHAR)MmGetMdlVirtualAddress(pi->curr_mdl) + pi->curr_mdl_offset, out_length, FALSE, FALSE, NULL);
   4.114      ASSERT(curr_mdl);
   4.115      IoBuildPartialMdl(pi->curr_mdl, curr_mdl, (PUCHAR)MmGetMdlVirtualAddress(pi->curr_mdl) + pi->curr_mdl_offset, out_length);
   4.116 @@ -359,6 +303,7 @@ XenNet_MakePacket(struct xennet_info *xi
   4.117    }
   4.118    if (pi->split_required)
   4.119    {
   4.120 +    // TODO: only if Ip checksum is disabled...
   4.121      //XenNet_SumIpHeader(header_va, pi->ip4_header_length);
   4.122    }
   4.123    if (header_extra > 0)
   4.124 @@ -520,7 +465,7 @@ static PNET_BUFFER_LIST
   4.125  XenNet_MakePackets(struct xennet_info *xi, packet_info_t *pi)
   4.126  {
   4.127    PNET_BUFFER_LIST nbl = NULL;
   4.128 -  //UCHAR psh;
   4.129 +  UCHAR psh;
   4.130    NDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO csum_info;
   4.131    ULONG parse_result;  
   4.132    //PNDIS_BUFFER buffer;
   4.133 @@ -529,6 +474,7 @@ XenNet_MakePackets(struct xennet_info *x
   4.134    //FUNCTION_ENTER();
   4.135  
   4.136    parse_result = XenNet_ParsePacketHeader(pi, NULL, 0);
   4.137 +  pi->split_required = FALSE;
   4.138  
   4.139    if (!XenNet_FilterAcceptPacket(xi, pi))
   4.140    {
   4.141 @@ -617,46 +563,41 @@ XenNet_MakePackets(struct xennet_info *x
   4.142      }
   4.143      goto done;
   4.144    }
   4.145 -  KdPrint((__DRIVER_NAME "     What are we doing here???\n"));
   4.146 -#if 0  
   4.147 +
   4.148 +  /* this is the split_required code */
   4.149 +  csum_info.Value = 0;
   4.150 +  csum_info.Receive.IpChecksumSucceeded = TRUE;
   4.151 +  csum_info.Receive.TcpChecksumSucceeded = TRUE;
   4.152 +  //checksum_offload = TRUE;
   4.153    pi->tcp_remaining = pi->tcp_length;
   4.154  
   4.155    /* we can make certain assumptions here as the following code is only for tcp4 */
   4.156    psh = pi->header[XN_HDR_SIZE + pi->ip4_header_length + 13] & 8;
   4.157    while (pi->tcp_remaining)
   4.158    {
   4.159 -    PUCHAR header_va;
   4.160 -    PMDL mdl;
   4.161 -    UINT total_length;
   4.162 -    UINT buffer_length;
   4.163 -    packet = XenNet_MakePacket(xi, nbl, pi);
   4.164 -    if (!packet)
   4.165 +    if (!XenNet_MakePacket(xi, nbl, pi))
   4.166      {
   4.167 -      //KdPrint((__DRIVER_NAME "     Ran out of packets\n"));
   4.168 +      KdPrint((__DRIVER_NAME "     Ran out of packets\n"));
   4.169        xi->stat_rx_no_buffer++;
   4.170        break; /* we are out of memory - just drop the packets */
   4.171      }
   4.172 -    if (xi->setting_csum.V4Receive.TcpChecksum)
   4.173 -    {
   4.174 -      csum_info = (PNDIS_TCP_IP_CHECKSUM_PACKET_INFO)&NDIS_PER_PACKET_INFO_FROM_PACKET(
   4.175 -        packet, TcpIpChecksumPacketInfo);
   4.176 -      csum_info->Receive.NdisPacketIpChecksumSucceeded = TRUE;
   4.177 -      csum_info->Receive.NdisPacketTcpChecksumSucceeded = TRUE;
   4.178 -    }
   4.179      if (psh)
   4.180      {
   4.181 -      NdisGetFirstBufferFromPacketSafe(packet, &mdl, &header_va, &buffer_length, &total_length, NormalPagePriority);
   4.182 +      //NdisGetFirstBufferFromPacketSafe(packet, &mdl, &header_va, &buffer_length, &total_length, NormalPagePriority);
   4.183        if (pi->tcp_remaining)
   4.184 -        header_va[XN_HDR_SIZE + pi->ip4_header_length + 13] &= ~8;
   4.185 +        pi->header[XN_HDR_SIZE + pi->ip4_header_length + 13] &= ~8;
   4.186        else
   4.187 -        header_va[XN_HDR_SIZE + pi->ip4_header_length + 13] |= 8;
   4.188 +        pi->header[XN_HDR_SIZE + pi->ip4_header_length + 13] |= 8;
   4.189      }
   4.190 -    XenNet_SumPacketData(pi, packet, TRUE);
   4.191 -    entry = (PLIST_ENTRY)&packet->MiniportReservedEx[sizeof(PVOID)];
   4.192 -    InsertTailList(rx_packet_list, entry);
   4.193 -    packet_count++;
   4.194 +    //XenNet_SumPacketData(pi, packet, TRUE);
   4.195 +    //entry = (PLIST_ENTRY)&packet->MiniportReservedEx[sizeof(PVOID)];
   4.196 +    //InsertTailList(rx_packet_list, entry);
   4.197    }
   4.198 -#endif
   4.199 +  /* we want to be a bit flexible here if some form of offload has been disabled */
   4.200 +  csum_info.Value = 0;
   4.201 +  csum_info.Receive.IpChecksumSucceeded = TRUE;
   4.202 +  csum_info.Receive.TcpChecksumSucceeded = TRUE;
   4.203 +  NET_BUFFER_LIST_INFO(nbl, TcpIpChecksumNetBufferListInfo) = csum_info.Value;
   4.204  done:
   4.205    if (nbl && !NBL_PACKET_COUNT(nbl))
   4.206    {
   4.207 @@ -745,11 +686,12 @@ XenNet_ReturnNetBufferLists(NDIS_HANDLE 
   4.208    //FUNCTION_EXIT();
   4.209  }
   4.210  
   4.211 -#define MAXIMUM_PACKETS_PER_INDICATE 32
   4.212 -
   4.213  /* We limit the number of packets per interrupt so that acks get a chance
   4.214  under high rx load. The DPC is immediately re-scheduled */
   4.215 -#define MAXIMUM_PACKETS_PER_INTERRUPT 32 /* this is calculated before large packet split */
   4.216 +//#define MAXIMUM_PACKETS_PER_INTERRUPT 32 /* this is calculated before large packet split */
   4.217 +//#define MAXIMUM_DATA_PER_INTERRUPT (MAXIMUM_PACKETS_PER_INTERRUPT * 1500) /* help account for large packets */
   4.218 +
   4.219 +#define MAXIMUM_PACKETS_PER_INTERRUPT 2560 /* this is calculated before large packet split */
   4.220  #define MAXIMUM_DATA_PER_INTERRUPT (MAXIMUM_PACKETS_PER_INTERRUPT * 1500) /* help account for large packets */
   4.221  
   4.222  // Called at DISPATCH_LEVEL
   4.223 @@ -778,7 +720,9 @@ XenNet_RxBufferCheck(struct xennet_info 
   4.224    BOOLEAN extra_info_flag = FALSE;
   4.225    BOOLEAN more_data_flag = FALSE;
   4.226    BOOLEAN dont_set_event;
   4.227 -
   4.228 +  int ring_packets1 = 0;
   4.229 +  int ring_packets2 = 0;
   4.230 +  int indicate_packets = 0;
   4.231    //FUNCTION_ENTER();
   4.232  
   4.233    if (!xi->connected)
   4.234 @@ -863,6 +807,7 @@ XenNet_RxBufferCheck(struct xennet_info 
   4.235          packet_count++;
   4.236          packet_data += interim_packet_data;
   4.237          interim_packet_data = 0;
   4.238 +ring_packets1++;
   4.239        }
   4.240        buffer_count++;
   4.241      }
   4.242 @@ -898,9 +843,9 @@ XenNet_RxBufferCheck(struct xennet_info 
   4.243    if (packet_count >= MAXIMUM_PACKETS_PER_INTERRUPT || packet_data >= MAXIMUM_DATA_PER_INTERRUPT)
   4.244    {
   4.245      /* fire again immediately */
   4.246 -    //KdPrint((__DRIVER_NAME "     Dpc Duration Exceeded\n"));
   4.247 +    KdPrint((__DRIVER_NAME "     Dpc Duration Exceeded\n"));
   4.248      /* we want the Dpc on the end of the queue. By definition we are already on the right CPU so we know the Dpc queue will be run immediately */
   4.249 -    KeSetImportanceDpc(&xi->rxtx_dpc, MediumImportance);
   4.250 +//    KeSetImportanceDpc(&xi->rxtx_dpc, MediumImportance);
   4.251      KeInsertQueueDpc(&xi->rxtx_dpc, NULL, NULL);
   4.252      /* dont set an event in TX path */
   4.253      dont_set_event = TRUE;
   4.254 @@ -908,7 +853,7 @@ XenNet_RxBufferCheck(struct xennet_info 
   4.255    else
   4.256    {
   4.257      /* make sure the Dpc queue is run immediately next interrupt */
   4.258 -    KeSetImportanceDpc(&xi->rxtx_dpc, HighImportance);
   4.259 +//    KeSetImportanceDpc(&xi->rxtx_dpc, HighImportance);
   4.260      /* set an event in TX path */
   4.261      dont_set_event = FALSE;
   4.262    }
   4.263 @@ -1000,14 +945,15 @@ XenNet_RxBufferCheck(struct xennet_info 
   4.264          if (!nbl_head)
   4.265          {
   4.266            nbl_head = nbl;
   4.267 -          nbl_tail = nbl;
   4.268          }
   4.269          else
   4.270          {
   4.271            NET_BUFFER_LIST_NEXT_NBL(nbl_tail) = nbl;
   4.272          }
   4.273          NET_BUFFER_LIST_NEXT_NBL(nbl) = NULL;
   4.274 +        nbl_tail = nbl;
   4.275        }
   4.276 +ring_packets2++;
   4.277      }
   4.278  
   4.279      page_buf = next_buf;
   4.280 @@ -1018,60 +964,17 @@ XenNet_RxBufferCheck(struct xennet_info 
   4.281  
   4.282    if (nbl_head)
   4.283    {
   4.284 -#if 0
   4.285 -KdPrint((__DRIVER_NAME "     I %d %p\n", nbl_count, nbl_head));
   4.286 -KdPrint((__DRIVER_NAME "     nbl_head->Context = %p\n", nbl_head->Context));
   4.287 -KdPrint((__DRIVER_NAME "     nbl_head->ParentNetBufferList = %p\n", nbl_head->ParentNetBufferList));
   4.288 -KdPrint((__DRIVER_NAME "     nbl_head->NdisPoolHandle = %p\n", nbl_head->NdisPoolHandle));
   4.289 -KdPrint((__DRIVER_NAME "     nbl_head->NblFlags = %p\n", nbl_head->NblFlags));
   4.290 -KdPrint((__DRIVER_NAME "     nbl_head->ChildRefCount = %p\n", nbl_head->ChildRefCount));
   4.291 -KdPrint((__DRIVER_NAME "     nbl_head->Flags = %p\n", nbl_head->Flags));
   4.292 -KdPrint((__DRIVER_NAME "     nbl_head->Status = %p\n", nbl_head->Status));
   4.293 -KdPrint((__DRIVER_NAME "     nbl_head->Context = %p\n", nbl_head->Context));
   4.294 -KdPrint((__DRIVER_NAME "     NET_BUFFER_LIST_FIRST_NB(nbl_head) = %p\n", NET_BUFFER_LIST_FIRST_NB(nbl_head)));
   4.295 -KdPrint((__DRIVER_NAME "     NET_BUFFER_FIRST_MDL(nb) = %p\n", NET_BUFFER_FIRST_MDL(NET_BUFFER_LIST_FIRST_NB((nbl_head)))));
   4.296 -KdPrint((__DRIVER_NAME "     NET_BUFFER_FIRST_MDL(nb)->Next = %p\n", NET_BUFFER_FIRST_MDL(NET_BUFFER_LIST_FIRST_NB((nbl_head)))->Next));
   4.297 -#endif
   4.298 +    PNET_BUFFER_LIST nbl;
   4.299 +    for (nbl = nbl_head; nbl; nbl = NET_BUFFER_LIST_NEXT_NBL(nbl))
   4.300 +      indicate_packets++;
   4.301 +    if (indicate_packets != ring_packets1 || indicate_packets != ring_packets2)
   4.302 +      KdPrint((__DRIVER_NAME "     ring_packets1 = %d, ring_packets2 = %d, indicate_packets = %d\n", ring_packets1, ring_packets2, indicate_packets));
   4.303  
   4.304      NdisMIndicateReceiveNetBufferLists(xi->adapter_handle, nbl_head, NDIS_DEFAULT_PORT_NUMBER, nbl_count,
   4.305        NDIS_RECEIVE_FLAGS_DISPATCH_LEVEL
   4.306 -      | NDIS_RECEIVE_FLAGS_SINGLE_ETHER_TYPE 
   4.307 +      //| NDIS_RECEIVE_FLAGS_SINGLE_ETHER_TYPE 
   4.308        | NDIS_RECEIVE_FLAGS_PERFECT_FILTERED);
   4.309    };
   4.310 -#if 0
   4.311 -  /* indicate packets to NDIS */
   4.312 -  entry = RemoveHeadList(&rx_packet_list);
   4.313 -  InitializeListHead(&rx_header_only_packet_list);
   4.314 -  packet_count = 0;
   4.315 -
   4.316 -  while (entry != &rx_packet_list) {
   4.317 -    PNDIS_PACKET packet = CONTAINING_RECORD(entry, NDIS_PACKET, MiniportReservedEx[sizeof(PVOID)]);
   4.318 -    NDIS_STATUS status;
   4.319 -    ASSERT(*(shared_buffer_t **)&packet->MiniportReservedEx[0]);
   4.320 -    status = NDIS_GET_PACKET_STATUS(packet);
   4.321 -    if (status == NDIS_STATUS_RESOURCES)
   4.322 -      InsertTailList(&rx_header_only_packet_list, entry);
   4.323 -    packets[packet_count++] = packet;
   4.324 -    InterlockedIncrement(&xi->rx_outstanding);
   4.325 -    entry = RemoveHeadList(&rx_packet_list);
   4.326 -    /* if we indicate a packet with NDIS_STATUS_RESOURCES  then any following packet can't be NDIS_STATUS_SUCCESS */
   4.327 -    if (packet_count == MAXIMUM_PACKETS_PER_INDICATE || entry == &rx_packet_list
   4.328 -        || (NDIS_GET_PACKET_STATUS(CONTAINING_RECORD(entry, NDIS_PACKET, MiniportReservedEx[sizeof(PVOID)])) == NDIS_STATUS_SUCCESS
   4.329 -            && status == NDIS_STATUS_RESOURCES))
   4.330 -    {
   4.331 -      NdisMIndicateReceivePacket(xi->adapter_handle, packets, packet_count);
   4.332 -      packet_count = 0;
   4.333 -    }
   4.334 -  }
   4.335 -  /* now return the packets for which we indicated NDIS_STATUS_RESOURCES */
   4.336 -  entry = RemoveHeadList(&rx_header_only_packet_list);
   4.337 -  while (entry != &rx_header_only_packet_list) {
   4.338 -    PNDIS_PACKET packet = CONTAINING_RECORD(entry, NDIS_PACKET, MiniportReservedEx[sizeof(PVOID)]);
   4.339 -    entry = RemoveHeadList(&rx_header_only_packet_list);
   4.340 -    InterlockedIncrement(&resource_packets);
   4.341 -    XenNet_ReturnPacket(xi, packet);
   4.342 -  }
   4.343 -#endif
   4.344    //FUNCTION_EXIT();
   4.345    return dont_set_event;
   4.346  }
     5.1 --- a/xennet/xennet6_tx.c	Thu May 05 22:39:13 2011 +1000
     5.2 +++ b/xennet/xennet6_tx.c	Tue May 10 19:50:46 2011 +1000
     5.3 @@ -89,14 +89,14 @@ XenNet_HWSendPacket(struct xennet_info *
     5.4    gref = xi->vectors.GntTbl_GetRef(xi->vectors.context, (ULONG)'XNTX');
     5.5    if (gref == INVALID_GRANT_REF)
     5.6    {
     5.7 -    KdPrint((__DRIVER_NAME "     out of grefs\n"));
     5.8 +    FUNCTION_MSG("out of grefs\n");
     5.9      return FALSE;
    5.10    }
    5.11    coalesce_buf = NdisAllocateFromNPagedLookasideList(&xi->tx_lookaside_list);
    5.12    if (!coalesce_buf)
    5.13    {
    5.14      xi->vectors.GntTbl_PutRef(xi->vectors.context, gref, (ULONG)'XNTX');
    5.15 -    KdPrint((__DRIVER_NAME "     out of memory\n"));
    5.16 +    FUNCTION_MSG("out of memory\n");
    5.17      return FALSE;
    5.18    }
    5.19    XenNet_ClearPacketInfo(&pi);
    5.20 @@ -145,7 +145,7 @@ XenNet_HWSendPacket(struct xennet_info *
    5.21    {
    5.22      xi->vectors.GntTbl_PutRef(xi->vectors.context, gref, (ULONG)'XNTX');
    5.23      NdisFreeToNPagedLookasideList(&xi->tx_lookaside_list, coalesce_buf);
    5.24 -    KdPrint((__DRIVER_NAME "     Full on send - ring full\n"));
    5.25 +    //KdPrint((__DRIVER_NAME "     Full on send - ring full\n"));
    5.26      return FALSE;
    5.27    }
    5.28    parse_result = XenNet_ParsePacketHeader(&pi, coalesce_buf, PAGE_SIZE);
    5.29 @@ -157,11 +157,11 @@ XenNet_HWSendPacket(struct xennet_info *
    5.30      PUCHAR my_va;
    5.31      FUNCTION_MSG("total_length == 0, CurrentMdlOffset == %d\n", nb->CurrentMdlOffset);
    5.32      my_va = MmGetMdlVirtualAddress(pi.first_mdl);
    5.33 -    FUNCTION_MSG("  first mdl va = %p, offset = %d, length = %d\n", MmGetMdlVirtualAddress(pi.first_mdl), MmGetMdlByteOffset(pi.first_mdl), MmGetMdlByteCount(pi.first_mdl));      
    5.34 +    FUNCTION_MSG("  first mdl va = %p, offset = %d, length = %d\n", MmGetMdlVirtualAddress(pi.first_mdl), MmGetMdlByteOffset(pi.first_mdl), MmGetMdlByteCount(pi.first_mdl));
    5.35      FUNCTION_MSG("    0010: %02x%02x\n", my_va[0x10], my_va[0x11]);
    5.36      for (tmp_mdl = nb->CurrentMdl; tmp_mdl; tmp_mdl = tmp_mdl->Next)
    5.37      {
    5.38 -      FUNCTION_MSG("  mdl = %p, va = %p, offset = %d, length = %d\n", tmp_mdl, MmGetMdlVirtualAddress(tmp_mdl), MmGetMdlByteOffset(tmp_mdl), MmGetMdlByteCount(tmp_mdl));      
    5.39 +      FUNCTION_MSG("  mdl = %p, va = %p, offset = %d, length = %d\n", tmp_mdl, MmGetMdlVirtualAddress(tmp_mdl), MmGetMdlByteOffset(tmp_mdl), MmGetMdlByteCount(tmp_mdl));
    5.40        if (tmp_mdl == nb->CurrentMdl)
    5.41        {
    5.42          my_va = MmGetSystemAddressForMdlSafe(tmp_mdl, HighPagePriority);
    5.43 @@ -401,10 +401,13 @@ XenNet_HWSendPacket(struct xennet_info *
    5.44    ASSERT(!xi->tx_shadows[txN->id].nb);
    5.45    xi->tx_shadows[txN->id].nb = nb;
    5.46  
    5.47 -  if (ndis_lso)
    5.48 +  switch (lso_info.Transmit.Type)
    5.49    {
    5.50 -    //KdPrint((__DRIVER_NAME "     TcpLargeSendPacketInfo = %d\n", pi.tcp_length));
    5.51 -    NET_BUFFER_LIST_INFO(NB_NBL(nb), TcpOffloadBytesTransferred) = UlongToPtr(tx_length - MAX_ETH_HEADER_LENGTH - pi.ip4_header_length - pi.tcp_header_length);
    5.52 +  case NDIS_TCP_LARGE_SEND_OFFLOAD_V1_TYPE:
    5.53 +    lso_info.LsoV1TransmitComplete.TcpPayload = UlongToPtr(tx_length - MAX_ETH_HEADER_LENGTH - pi.ip4_header_length - pi.tcp_header_length);
    5.54 +    break;
    5.55 +  case NDIS_TCP_LARGE_SEND_OFFLOAD_V2_TYPE:
    5.56 +    break;
    5.57    }
    5.58  
    5.59    xi->stat_tx_ok++;
    5.60 @@ -412,6 +415,8 @@ XenNet_HWSendPacket(struct xennet_info *
    5.61    //NDIS_SET_PACKET_STATUS(packet, NDIS_STATUS_SUCCESS);
    5.62    //FUNCTION_EXIT();
    5.63    xi->tx_outstanding++;
    5.64 +//total_sent++;
    5.65 +//FUNCTION_MSG("sent packet\n");
    5.66    return TRUE;
    5.67  }
    5.68  
    5.69 @@ -436,7 +441,7 @@ XenNet_SendQueuedPackets(struct xennet_i
    5.70      
    5.71      if (!XenNet_HWSendPacket(xi, nb))
    5.72      {
    5.73 -      KdPrint((__DRIVER_NAME "     No room for packet\n"));
    5.74 +      //KdPrint((__DRIVER_NAME "     No room for packet\n"));
    5.75        InsertHeadList(&xi->tx_waiting_pkt_list, nb_entry);
    5.76        break;
    5.77      }