win-pvdrivers

changeset 935:99023e044544

ndis5 driver now passes ndistest with only a call to DbgPrint marked as an error
author James Harper <james.harper@bendigoit.com.au>
date Mon Jun 20 23:16:14 2011 +1000 (2011-06-20)
parents 6d2ca0f1a48a
children 373c6b36220c
files xennet/xennet5.c xennet/xennet5.h xennet/xennet5_common.c xennet/xennet5_oid.c xennet/xennet5_rx.c
line diff
     1.1 --- a/xennet/xennet5.c	Sun Jun 12 16:16:02 2011 +1000
     1.2 +++ b/xennet/xennet5.c	Mon Jun 20 23:16:14 2011 +1000
     1.3 @@ -558,8 +558,7 @@ XenNet_Init(
     1.4      |NDIS_ATTRIBUTE_USES_SAFE_BUFFER_APIS
     1.5  #endif
     1.6      |NDIS_ATTRIBUTE_DESERIALIZE
     1.7 -    |NDIS_ATTRIBUTE_SURPRISE_REMOVE_OK
     1.8 -    |NDIS_ATTRIBUTE_BUS_MASTER,
     1.9 +    |NDIS_ATTRIBUTE_SURPRISE_REMOVE_OK,
    1.10      NdisInterfaceInternal); /* PnpBus option doesn't exist... */
    1.11    xi->multicast_list_size = 0;
    1.12    xi->current_lookahead = MIN_LOOKAHEAD_LENGTH;
     2.1 --- a/xennet/xennet5.h	Sun Jun 12 16:16:02 2011 +1000
     2.2 +++ b/xennet/xennet5.h	Mon Jun 20 23:16:14 2011 +1000
     2.3 @@ -188,7 +188,6 @@ struct _shared_buffer_t
     2.4    USHORT offset;
     2.5    PVOID virtual;
     2.6    PNDIS_BUFFER buffer;
     2.7 -  //USHORT id;
     2.8    volatile LONG ref_count;
     2.9  };
    2.10  
    2.11 @@ -220,6 +219,7 @@ typedef struct {
    2.12    ULONG total_length;
    2.13    USHORT ip4_header_length;
    2.14    USHORT ip4_length;
    2.15 +  BOOLEAN ip_has_options;
    2.16    USHORT tcp_header_length;
    2.17    BOOLEAN tcp_has_options;
    2.18    USHORT tcp_length;
    2.19 @@ -432,6 +432,12 @@ XenNet_SumIpHeader(
    2.20    USHORT ip4_header_length
    2.21  );
    2.22  
    2.23 +BOOLEAN
    2.24 +XenNet_CheckIpHeader(
    2.25 +  PUCHAR header,
    2.26 +  USHORT ip4_header_length
    2.27 +);
    2.28 +
    2.29  static __forceinline VOID
    2.30  XenNet_ClearPacketInfo(packet_info_t *pi)
    2.31  {
     3.1 --- a/xennet/xennet5_common.c	Sun Jun 12 16:16:02 2011 +1000
     3.2 +++ b/xennet/xennet5_common.c	Mon Jun 20 23:16:14 2011 +1000
     3.3 @@ -150,6 +150,7 @@ XenNet_ParsePacketHeader(packet_info_t *
     3.4        return PARSE_UNKNOWN_TYPE;
     3.5      }
     3.6      pi->ip4_header_length = (pi->header[XN_HDR_SIZE + 0] & 0x0F) << 2;
     3.7 +    pi->ip_has_options = (BOOLEAN)(pi->ip4_header_length > 20);
     3.8      if (pi->header_length < (ULONG)(XN_HDR_SIZE + pi->ip4_header_length + 20))
     3.9      {
    3.10        if (!XenNet_BuildHeader(pi, NULL, (ULONG)(XN_HDR_SIZE + pi->ip4_header_length + 20)))
    3.11 @@ -230,6 +231,27 @@ XenNet_SumIpHeader(
    3.12  }
    3.13  
    3.14  BOOLEAN
    3.15 +XenNet_CheckIpHeader(
    3.16 +  PUCHAR header,
    3.17 +  USHORT ip4_header_length
    3.18 +)
    3.19 +{
    3.20 +  ULONG csum = 0;
    3.21 +  USHORT i;
    3.22 +
    3.23 +  ASSERT(ip4_header_length > 12);
    3.24 +  ASSERT(!(ip4_header_length & 1));
    3.25 +
    3.26 +  for (i = 0; i < ip4_header_length; i += 2)
    3.27 +  {
    3.28 +    csum += GET_NET_PUSHORT(&header[XN_HDR_SIZE + i]);
    3.29 +  }
    3.30 +  while (csum & 0xFFFF0000)
    3.31 +    csum = (csum & 0xFFFF) + (csum >> 16);
    3.32 +  return csum == 0xFFFF;
    3.33 +}
    3.34 +
    3.35 +BOOLEAN
    3.36  XenNet_FilterAcceptPacket(struct xennet_info *xi,packet_info_t *pi)
    3.37  {
    3.38    BOOLEAN is_multicast = FALSE;
     4.1 --- a/xennet/xennet5_oid.c	Sun Jun 12 16:16:02 2011 +1000
     4.2 +++ b/xennet/xennet5_oid.c	Mon Jun 20 23:16:14 2011 +1000
     4.3 @@ -454,7 +454,7 @@ XenNet_SetInformation(
     4.4        break;
     4.5      case OID_GEN_MAXIMUM_LOOKAHEAD:
     4.6        status = NDIS_STATUS_NOT_SUPPORTED;
     4.7 -      KdPrint(("Unsupported set OID_GEN_MAXIMUM_LOOKAHEAD\n"));
     4.8 +      KdPrint(("Unsupported set OID_GEN_MAXIMUM_LOOKAHEAD %d\n", *(ULONG *)data));
     4.9        break;
    4.10      case OID_GEN_MAXIMUM_FRAME_SIZE:
    4.11        status = NDIS_STATUS_NOT_SUPPORTED;
     5.1 --- a/xennet/xennet5_rx.c	Sun Jun 12 16:16:02 2011 +1000
     5.2 +++ b/xennet/xennet5_rx.c	Mon Jun 20 23:16:14 2011 +1000
     5.3 @@ -181,7 +181,6 @@ put_packet_on_freelist(struct xennet_inf
     5.4  
     5.5    UNREFERENCED_PARAMETER(xi);
     5.6    NdisReinitializePacket(packet);
     5.7 -  RtlZeroMemory(NDIS_PACKET_EXTENSION_FROM_PACKET(packet), sizeof(NDIS_PACKET_EXTENSION));
     5.8    csum_info = (PNDIS_TCP_IP_CHECKSUM_PACKET_INFO)&NDIS_PER_PACKET_INFO_FROM_PACKET(
     5.9      packet, TcpIpChecksumPacketInfo);
    5.10    csum_info->Value = 0;
    5.11 @@ -212,6 +211,30 @@ XenNet_MakePacket(struct xennet_info *xi
    5.12      //FUNCTION_EXIT();
    5.13      return NULL;
    5.14    }
    5.15 +
    5.16 +  if (!pi->split_required && pi->mdl_count == 1)
    5.17 +  {
    5.18 +    /* shortcut for the single packet single mdl case */
    5.19 +    
    5.20 +    NDIS_SET_PACKET_STATUS(packet, NDIS_STATUS_SUCCESS);
    5.21 +    NdisCopyBuffer(&status, &out_buffer, xi->rx_buffer_pool, pi->first_buffer, 0, pi->total_length);
    5.22 +    if (status != STATUS_SUCCESS)
    5.23 +    {
    5.24 +      KdPrint((__DRIVER_NAME "     No free rx buffers\n"));
    5.25 +      put_packet_on_freelist(xi, packet);
    5.26 +      return NULL;
    5.27 +    } 
    5.28 +    NdisChainBufferAtBack(packet, out_buffer);
    5.29 +    *(shared_buffer_t **)&packet->MiniportReservedEx[0] = pi->first_pb;
    5.30 +    ref_pb(xi, pi->first_pb); /* so that the buffer doesn't get freed at the end of MakePackets*/
    5.31 +    //FUNCTION_EXIT();
    5.32 +    /* windows gets lazy about ack packets and holds on to them forever under high load situations. we don't like this */
    5.33 +    if (pi->ip_proto == 6 && pi->tcp_length == 0)
    5.34 +      NDIS_SET_PACKET_STATUS(packet, NDIS_STATUS_RESOURCES);
    5.35 +    else
    5.36 +      NDIS_SET_PACKET_STATUS(packet, NDIS_STATUS_SUCCESS);
    5.37 +    return packet;
    5.38 +  }
    5.39    
    5.40    header_buf = NdisAllocateFromNPagedLookasideList(&xi->rx_lookaside_list);
    5.41    if (!header_buf)
    5.42 @@ -223,9 +246,7 @@ XenNet_MakePacket(struct xennet_info *xi
    5.43    header_va = (PUCHAR)(header_buf + 1);
    5.44    NdisZeroMemory(header_buf, sizeof(shared_buffer_t));
    5.45    NdisMoveMemory(header_va, pi->header, pi->header_length);
    5.46 -  //KdPrint((__DRIVER_NAME "     header_length = %d, current_lookahead = %d\n", pi->header_length, xi->current_lookahead));
    5.47 -  //KdPrint((__DRIVER_NAME "     ip4_header_length = %d\n", pi->ip4_header_length));
    5.48 -  //KdPrint((__DRIVER_NAME "     tcp_header_length = %d\n", pi->tcp_header_length));
    5.49 +
    5.50    /* make sure we satisfy the lookahead requirement */
    5.51    
    5.52    if (pi->split_required)
    5.53 @@ -274,14 +295,12 @@ XenNet_MakePacket(struct xennet_info *xi
    5.54    }
    5.55    //KdPrint((__DRIVER_NAME "     before loop - out_remaining = %d\n", out_remaining));
    5.56  
    5.57 -  NDIS_SET_PACKET_STATUS(packet, NDIS_STATUS_RESOURCES); /* for packets only containing a header buffer - see Indicate*/
    5.58    while (out_remaining != 0)
    5.59    {
    5.60      ULONG in_buffer_offset;
    5.61      ULONG in_buffer_length;
    5.62      ULONG out_length;
    5.63      
    5.64 -    NDIS_SET_PACKET_STATUS(packet, NDIS_STATUS_SUCCESS); /* packet contains additional buffers */
    5.65      //KdPrint((__DRIVER_NAME "     in loop - out_remaining = %d, curr_buffer = %p, curr_pb = %p\n", out_remaining, pi->curr_buffer, pi->curr_pb));
    5.66      if (!pi->curr_buffer || !pi->curr_pb)
    5.67      {
    5.68 @@ -313,6 +332,11 @@ XenNet_MakePacket(struct xennet_info *xi
    5.69    if (header_extra > 0)
    5.70      pi->header_length -= header_extra;
    5.71    ASSERT(*(shared_buffer_t **)&packet->MiniportReservedEx[0]);
    5.72 +  /* windows gets lazy about ack packets and holds on to them forever under high load situations. we don't like this */
    5.73 +  if (pi->ip_proto == 6 && pi->tcp_length == 0)
    5.74 +    NDIS_SET_PACKET_STATUS(packet, NDIS_STATUS_RESOURCES);
    5.75 +  else
    5.76 +    NDIS_SET_PACKET_STATUS(packet, NDIS_STATUS_SUCCESS);
    5.77    //FUNCTION_EXIT();
    5.78    return packet;
    5.79  }
    5.80 @@ -499,18 +523,27 @@ XenNet_MakePackets(
    5.81        ASSERT(csum_info->Value == 0);
    5.82        if (pi->csum_blank || pi->data_validated)
    5.83        {
    5.84 +        /* we know this is IPv4, and we know Linux always validates the IPv4 checksum for us */
    5.85 +        if (xi->setting_csum.V4Receive.IpChecksum)
    5.86 +        {
    5.87 +          if (!pi->ip_has_options || xi->setting_csum.V4Receive.IpOptionsSupported)
    5.88 +          {
    5.89 +            if (XenNet_CheckIpHeader(pi->header, pi->ip4_header_length))
    5.90 +              csum_info->Receive.NdisPacketIpChecksumSucceeded = TRUE;
    5.91 +            else
    5.92 +              csum_info->Receive.NdisPacketIpChecksumFailed = TRUE;
    5.93 +          }
    5.94 +        }
    5.95          if (xi->setting_csum.V4Receive.TcpChecksum && pi->ip_proto == 6)
    5.96          {
    5.97            if (!pi->tcp_has_options || xi->setting_csum.V4Receive.TcpOptionsSupported)
    5.98            {
    5.99 -            csum_info->Receive.NdisPacketIpChecksumSucceeded = TRUE;
   5.100              csum_info->Receive.NdisPacketTcpChecksumSucceeded = TRUE;
   5.101              checksum_offload = TRUE;
   5.102            }
   5.103          }
   5.104          else if (xi->setting_csum.V4Receive.UdpChecksum && pi->ip_proto == 17)
   5.105          {
   5.106 -          csum_info->Receive.NdisPacketIpChecksumSucceeded = TRUE;
   5.107            csum_info->Receive.NdisPacketUdpChecksumSucceeded = TRUE;
   5.108            checksum_offload = TRUE;
   5.109          }
   5.110 @@ -519,19 +552,33 @@ XenNet_MakePackets(
   5.111            XenNet_SumPacketData(pi, packet, TRUE);
   5.112          }
   5.113        }
   5.114 -      else if (xi->config_csum_rx_check)
   5.115 +      else if (xi->config_csum_rx_check && pi->ip_version == 4)
   5.116        {
   5.117 +        if (xi->setting_csum.V4Receive.IpChecksum)
   5.118 +        {
   5.119 +          if (!pi->ip_has_options || xi->setting_csum.V4Receive.IpOptionsSupported)
   5.120 +          {
   5.121 +            if (XenNet_CheckIpHeader(pi->header, pi->ip4_header_length))
   5.122 +              csum_info->Receive.NdisPacketIpChecksumSucceeded = TRUE;
   5.123 +            else
   5.124 +              csum_info->Receive.NdisPacketIpChecksumFailed = TRUE;
   5.125 +          }
   5.126 +        }
   5.127          if (xi->setting_csum.V4Receive.TcpChecksum && pi->ip_proto == 6)
   5.128          {
   5.129 -          if (XenNet_SumPacketData(pi, packet, FALSE))
   5.130 +          if (!pi->tcp_has_options || xi->setting_csum.V4Receive.TcpOptionsSupported)
   5.131            {
   5.132 -            csum_info->Receive.NdisPacketTcpChecksumSucceeded = TRUE;
   5.133 +            if (XenNet_SumPacketData(pi, packet, FALSE))
   5.134 +            {
   5.135 +              csum_info->Receive.NdisPacketTcpChecksumSucceeded = TRUE;
   5.136 +            }
   5.137 +            else
   5.138 +            {
   5.139 +              csum_info->Receive.NdisPacketTcpChecksumFailed = TRUE;
   5.140 +            }
   5.141            }
   5.142 -          else
   5.143 -          {
   5.144 -            csum_info->Receive.NdisPacketTcpChecksumFailed = TRUE;
   5.145 -          }
   5.146 -        } else if (xi->setting_csum.V4Receive.UdpChecksum && pi->ip_proto == 17)
   5.147 +        }
   5.148 +        else if (xi->setting_csum.V4Receive.UdpChecksum && pi->ip_proto == 17)
   5.149          {
   5.150            if (XenNet_SumPacketData(pi, packet, FALSE))
   5.151            {
   5.152 @@ -675,7 +722,7 @@ XenNet_ReturnPacket(
   5.153  #endif
   5.154    //FUNCTION_EXIT();
   5.155  }
   5.156 -
   5.157 +  
   5.158  #define MAXIMUM_PACKETS_PER_INDICATE 32
   5.159  
   5.160  /* We limit the number of packets per interrupt so that acks get a chance
   5.161 @@ -958,6 +1005,7 @@ XenNet_RxBufferCheck(struct xennet_info 
   5.162      entry = RemoveHeadList(&rx_header_only_packet_list);
   5.163      XenNet_ReturnPacket(xi, packet);
   5.164    }
   5.165 +
   5.166    return dont_set_event;
   5.167    //FUNCTION_EXIT();
   5.168  }