win-pvdrivers

changeset 247:565483912dc0

Fix for fragmented headers and offload
author James Harper <james.harper@bendigoit.com.au>
date Sat Apr 05 22:20:00 2008 +1100 (2008-04-05)
parents 402fb735ce45
children 7c395bd04ec1
files common.inc xennet/xennet.h xennet/xennet_rx.c xennet/xennet_tx.c
line diff
     1.1 --- a/common.inc	Sat Apr 05 14:34:28 2008 +1100
     1.2 +++ b/common.inc	Sat Apr 05 22:20:00 2008 +1100
     1.3 @@ -1,4 +1,4 @@
     1.4 -VERSION=0.8.8.14
     1.5 +VERSION=0.8.8.22
     1.6  TARGETPATH=..\Target\$(DDK_TARGET_OS)
     1.7  KMDF_VERSION=1
     1.8  !IF $(_NT_TOOLS_VERSION) > 0x700
     2.1 --- a/xennet/xennet.h	Sat Apr 05 14:34:28 2008 +1100
     2.2 +++ b/xennet/xennet.h	Sat Apr 05 22:20:00 2008 +1100
     2.3 @@ -179,6 +179,7 @@ struct xennet_info
     2.4    ULONG tx_gref_free;
     2.5    grant_ref_t tx_gref_list[NET_TX_RING_SIZE];
     2.6    PNDIS_PACKET tx_pkts[NET_TX_RING_SIZE];
     2.7 +  PNDIS_BUFFER tx_mdls[NET_TX_RING_SIZE];
     2.8    grant_ref_t tx_grefs[NET_TX_RING_SIZE];
     2.9  
    2.10    /* rx_related - protected by rx_lock */
     3.1 --- a/xennet/xennet_rx.c	Sat Apr 05 14:34:28 2008 +1100
     3.2 +++ b/xennet/xennet_rx.c	Sat Apr 05 22:20:00 2008 +1100
     3.3 @@ -301,13 +301,13 @@ XenNet_MakePacket(
     3.4      do 
     3.5      {
     3.6        ASSERT(xi->rxpi.curr_mdl < xi->rxpi.mdl_count);
     3.7 -      in_buffer = XenNet_GetData(xi, out_remaining, &length);
     3.8 +      in_buffer = XenNet_GetData(&xi->rxpi, out_remaining, &length);
     3.9        memcpy(&out_buffer[out_offset], in_buffer, length);
    3.10        out_remaining = out_remaining - length;
    3.11        out_offset = out_offset + length;
    3.12      } while (out_remaining != 0); // && in_buffer != NULL);
    3.13      NdisChainBufferAtBack(packet, out_mdl);
    3.14 -    XenNet_SumIpHeader(xi, packet);
    3.15 +    XenNet_SumIpHeader(&xi->rxpi, packet);
    3.16      NDIS_SET_PACKET_STATUS(packet, NDIS_STATUS_SUCCESS);
    3.17    }
    3.18  
    3.19 @@ -326,7 +326,7 @@ XenNet_MakePackets(
    3.20  
    3.21  //  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "(packets = %p, packet_count = %d)\n", packets, *packet_count_p));
    3.22  
    3.23 -  XenNet_ParsePacketHeader(xi);
    3.24 +  XenNet_ParsePacketHeader(&xi->rxpi);
    3.25    switch (xi->rxpi.ip_proto)
    3.26    {
    3.27    case 6:  // TCP
    3.28 @@ -336,7 +336,7 @@ XenNet_MakePackets(
    3.29    case 17:  // UDP
    3.30      packets[*packet_count_p] = XenNet_MakePacket(xi);
    3.31      if (xi->rxpi.csum_calc_required)
    3.32 -      XenNet_SumPacketData(xi, packets[*packet_count_p]);
    3.33 +      XenNet_SumPacketData(&xi->rxpi, packets[*packet_count_p]);
    3.34      (*packet_count_p)++;
    3.35  //    KdPrint((__DRIVER_NAME " <-- " __FUNCTION__ " (TCP/UDP)\n"));
    3.36      return;
    3.37 @@ -357,7 +357,7 @@ XenNet_MakePackets(
    3.38    {
    3.39  //    KdPrint((__DRIVER_NAME "     tcp_remaining = %d\n", xi->rxpi.tcp_remaining));
    3.40      packets[*packet_count_p] = XenNet_MakePacket(xi);
    3.41 -    XenNet_SumPacketData(xi, packets[*packet_count_p]);
    3.42 +    XenNet_SumPacketData(&xi->rxpi, packets[*packet_count_p]);
    3.43      (*packet_count_p)++;
    3.44    }
    3.45    ASSERT(xi->rxpi.curr_mdl == xi->rxpi.mdl_count);
     4.1 --- a/xennet/xennet_tx.c	Sat Apr 05 14:34:28 2008 +1100
     4.2 +++ b/xennet/xennet_tx.c	Sat Apr 05 22:20:00 2008 +1100
     4.3 @@ -142,52 +142,35 @@ typedef struct
     4.4  } page_element_t;
     4.5  
     4.6  static VOID
     4.7 -XenNet_BuildPageList(PNDIS_PACKET packet, page_element_t *elements, PUSHORT num_elements)
     4.8 +XenNet_BuildPageList(packet_info_t *pi, page_element_t *elements, PUSHORT num_elements)
     4.9  {
    4.10    USHORT element_num = 0;
    4.11    UINT offset;
    4.12    UINT remaining;
    4.13    ULONG pages;
    4.14    USHORT page;
    4.15 -  PMDL buffer;
    4.16    PPFN_NUMBER pfns;
    4.17 -
    4.18 -  buffer = NDIS_PACKET_FIRST_NDIS_BUFFER(packet);
    4.19 +  ULONG i;
    4.20  
    4.21 -  while (buffer != NULL)
    4.22 +  for (i = 0; i < pi->mdl_count; i++)
    4.23    {
    4.24 -    offset = MmGetMdlByteOffset(buffer);
    4.25 -    remaining = MmGetMdlByteCount(buffer);
    4.26 -    pages = ADDRESS_AND_SIZE_TO_SPAN_PAGES(MmGetMdlVirtualAddress(buffer), remaining);
    4.27 -    pfns = MmGetMdlPfnArray(buffer);
    4.28 +    offset = MmGetMdlByteOffset(pi->mdls[i]);
    4.29 +    remaining = MmGetMdlByteCount(pi->mdls[i]);
    4.30 +    pages = ADDRESS_AND_SIZE_TO_SPAN_PAGES(MmGetMdlVirtualAddress(pi->mdls[i]), remaining);
    4.31 +    pfns = MmGetMdlPfnArray(pi->mdls[i]);
    4.32      for (page = 0; page < pages; page++, element_num++)
    4.33      {
    4.34        ASSERT(element_num < *num_elements);
    4.35        elements[element_num].pfn = pfns[page];
    4.36        elements[element_num].offset = (USHORT)offset;
    4.37        elements[element_num].length = (USHORT)min(remaining, PAGE_SIZE - offset);
    4.38 +//KdPrint((__DRIVER_NAME "     adding to page list size = %d, pfn = %08x, offset = %04x\n", elements[element_num].length, elements[element_num].pfn, elements[element_num].offset));
    4.39        offset = 0;
    4.40        remaining -= elements[element_num].length;
    4.41      }
    4.42      ASSERT(remaining == 0);
    4.43 -    NdisGetNextBuffer(buffer, &buffer);
    4.44    }
    4.45    *num_elements = element_num;
    4.46 -#if 0
    4.47 -  if (is_csum_offload && elements[0].length < 54)
    4.48 -  {
    4.49 -    element_num = 0;
    4.50 -    if (min(remaining, PAGE_SIZE - offset) < 54) /* first page must contain full header */
    4.51 -    {
    4.52 -      // allocate a new page
    4.53 -      first_page_len = 0;
    4.54 -      do {
    4.55 -        page_len = 
    4.56 -        // copy data to 
    4.57 -      } while (first_page_len <= 54)
    4.58 -    }
    4.59 -  }
    4.60 -#endif
    4.61  }
    4.62  
    4.63  /* Place a buffer on tx ring. */
    4.64 @@ -236,11 +219,15 @@ XenNet_HWSendPacket(struct xennet_info *
    4.65    PNDIS_TCP_IP_CHECKSUM_PACKET_INFO csum_info;
    4.66    UINT total_packet_length;
    4.67    ULONG mss; // 0 if not using large send
    4.68 -  PMDL first_buffer;
    4.69 +  PMDL buffer;
    4.70    uint16_t flags = NETTXF_more_data;
    4.71    page_element_t elements[NET_TX_RING_SIZE];
    4.72    USHORT num_elements;
    4.73    USHORT element_num;
    4.74 +  packet_info_t pi;
    4.75 +  PUCHAR address = NULL;
    4.76 +  PMDL merged_buffer = NULL;
    4.77 +  ULONG length = 0;
    4.78    
    4.79  #if defined(XEN_PROFILE)
    4.80    LARGE_INTEGER tsc, dummy;
    4.81 @@ -248,21 +235,51 @@ XenNet_HWSendPacket(struct xennet_info *
    4.82    tsc = KeQueryPerformanceCounter(&dummy);
    4.83  #endif
    4.84  
    4.85 -  NdisQueryPacket(packet, NULL, NULL, &first_buffer, &total_packet_length);
    4.86 +  RtlZeroMemory(&pi, sizeof(pi));
    4.87  
    4.88 +  csum_info = (PNDIS_TCP_IP_CHECKSUM_PACKET_INFO)&NDIS_PER_PACKET_INFO_FROM_PACKET(
    4.89 +    packet, TcpIpChecksumPacketInfo);
    4.90 +
    4.91 +  NdisQueryPacket(packet, NULL, NULL, &buffer, &total_packet_length);
    4.92 +
    4.93 +  pi.mdls[0] = buffer;
    4.94 +  pi.mdl_count = 1;
    4.95 +  // only if csum offload
    4.96 +  if ((csum_info->Transmit.NdisPacketTcpChecksum
    4.97 +    || csum_info->Transmit.NdisPacketUdpChecksum)
    4.98 +    && XenNet_ParsePacketHeader(&pi) == PARSE_TOO_SMALL)
    4.99 +  {
   4.100 +    pi.mdls[0] = merged_buffer = AllocatePage();
   4.101 +    address = MmGetMdlVirtualAddress(pi.mdls[0]);
   4.102 +    memcpy(address, MmGetSystemAddressForMdlSafe(buffer, NormalPagePriority), MmGetMdlByteCount(buffer));
   4.103 +    length = MmGetMdlByteCount(buffer);
   4.104 +    NdisAdjustBufferLength(pi.mdls[0], length); /* do this here so that ParsePacketHeader works */
   4.105 +    while (buffer->Next != NULL && XenNet_ParsePacketHeader(&pi) == PARSE_TOO_SMALL)
   4.106 +    {
   4.107 +      buffer = buffer->Next;
   4.108 +      ASSERT(length + MmGetMdlByteCount(buffer) <= PAGE_SIZE); // I think this could happen
   4.109 +      memcpy(&address[length], MmGetSystemAddressForMdlSafe(buffer, NormalPagePriority), MmGetMdlByteCount(buffer));
   4.110 +      length += MmGetMdlByteCount(buffer);
   4.111 +      NdisAdjustBufferLength(pi.mdls[0], length); /* do this here so that ParsePacketHeader works */
   4.112 +    }
   4.113 +  }
   4.114 +  NdisGetNextBuffer(buffer, &buffer);
   4.115 +  while (buffer != NULL)
   4.116 +  {
   4.117 +    pi.mdls[pi.mdl_count++] = buffer;
   4.118 +    NdisGetNextBuffer(buffer, &buffer);
   4.119 +  }
   4.120 +  
   4.121    num_elements = NET_TX_RING_SIZE;
   4.122 -  XenNet_BuildPageList(packet, elements, &num_elements);
   4.123 +  XenNet_BuildPageList(&pi, elements, &num_elements);
   4.124    mss = PtrToUlong(NDIS_PER_PACKET_INFO_FROM_PACKET(packet, TcpLargeSendPacketInfo));
   4.125  
   4.126    if (num_elements + !!mss > (int)free_requests(xi))
   4.127      return FALSE;
   4.128  
   4.129 -  csum_info = (PNDIS_TCP_IP_CHECKSUM_PACKET_INFO)&NDIS_PER_PACKET_INFO_FROM_PACKET(
   4.130 -    packet, TcpIpChecksumPacketInfo);
   4.131    if (csum_info->Transmit.NdisPacketTcpChecksum
   4.132      || csum_info->Transmit.NdisPacketUdpChecksum)
   4.133    {
   4.134 -KdPrint((__DRIVER_NAME "     TxCsumOffload - size = %d, pfn = %08x, offset = %04x\n", elements[0].length, elements[0].pfn, elements[0].offset));
   4.135      flags |= NETTXF_csum_blank | NETTXF_data_validated;
   4.136      PC_INC(ProfCount_TxPacketsCsumOffload);
   4.137    }
   4.138 @@ -300,8 +317,8 @@ KdPrint((__DRIVER_NAME "     TxCsumOfflo
   4.139    /* (C) */
   4.140    for (element_num = 1; element_num < num_elements; element_num++)
   4.141    {
   4.142 -if (csum_info->Transmit.NdisPacketTcpChecksum || csum_info->Transmit.NdisPacketUdpChecksum)
   4.143 -KdPrint((__DRIVER_NAME "                   - size = %d, pfn = %08x, offset = %04x\n", elements[element_num].length, elements[element_num].pfn, elements[element_num].offset));
   4.144 +//if (csum_info->Transmit.NdisPacketTcpChecksum || csum_info->Transmit.NdisPacketUdpChecksum)
   4.145 +//KdPrint((__DRIVER_NAME "                   - size = %d, pfn = %08x, offset = %04x\n", elements[element_num].length, elements[element_num].pfn, elements[element_num].offset));
   4.146      //KdPrint((__DRIVER_NAME "     i = %d\n", i));
   4.147      tx = XenNet_PutOnTxRing(xi, elements[element_num].pfn,
   4.148        elements[element_num].offset, elements[element_num].length,
   4.149 @@ -312,6 +329,7 @@ KdPrint((__DRIVER_NAME "                
   4.150    /* only set the packet on the last buffer, clear more_data */
   4.151    ASSERT(tx);
   4.152    xi->tx_pkts[tx->id] = packet;
   4.153 +  xi->tx_mdls[tx->id] = merged_buffer;
   4.154    tx->flags &= ~NETTXF_more_data;
   4.155  
   4.156    return TRUE;
   4.157 @@ -422,6 +440,11 @@ XenNet_TxBufferGC(struct xennet_info *xi
   4.158          packet_count++;
   4.159          xi->stat_tx_ok++;
   4.160        }
   4.161 +      if (xi->tx_mdls[id])
   4.162 +      {
   4.163 +        FreePages(xi->tx_mdls[id]);
   4.164 +        xi->tx_mdls[id] = NULL;
   4.165 +      }
   4.166        put_gref_on_freelist(xi, xi->tx_grefs[id]);
   4.167        xi->tx_grefs[id] = 0;
   4.168        put_id_on_freelist(xi, id);