win-pvdrivers

changeset 110:ae2b8983f881

Updates to allow fragmentation of the xen buffers on rx
author James Harper <james.harper@bendigoit.com.au>
date Fri Jan 11 23:46:10 2008 +1100 (2008-01-11)
parents f45e6538a5e2
children f565bdc4f522
files xennet/sources xennet/xennet.c
line diff
     1.1 --- a/xennet/sources	Fri Jan 11 20:58:56 2008 +1100
     1.2 +++ b/xennet/sources	Fri Jan 11 23:46:10 2008 +1100
     1.3 @@ -1,7 +1,7 @@
     1.4  TARGETNAME=XENNET
     1.5  TARGETTYPE=DRIVER
     1.6  TARGETPATH=..\Target\$(DDK_TARGET_OS)
     1.7 -VERSION=0.5.0.69
     1.8 +VERSION=0.5.0.75
     1.9  KMDF_VERSION=1
    1.10  MSC_WARNING_LEVEL=/W4
    1.11  INF_NAME=xennet
     2.1 --- a/xennet/xennet.c	Fri Jan 11 20:58:56 2008 +1100
     2.2 +++ b/xennet/xennet.c	Fri Jan 11 23:46:10 2008 +1100
     2.3 @@ -94,7 +94,7 @@ struct xennet_info
     2.4     * is an index into a chain of free entries. */
     2.5    int tx_pkt_ids_used;
     2.6    PNDIS_PACKET tx_pkts[NET_TX_RING_SIZE+1];
     2.7 -  PNDIS_PACKET rx_pkts[NET_RX_RING_SIZE];
     2.8 +  PNDIS_PACKET rx_buffers[NET_RX_RING_SIZE];
     2.9  
    2.10    grant_ref_t gref_tx_head;
    2.11    grant_ref_t grant_tx_ref[NET_TX_RING_SIZE+1];
    2.12 @@ -270,7 +270,6 @@ static NDIS_STATUS
    2.13  XenNet_RxBufferAlloc(struct xennet_info *xi)
    2.14  {
    2.15    unsigned short id;
    2.16 -  PNDIS_PACKET packet;
    2.17    PNDIS_BUFFER buffer;
    2.18    int i, batch_target, notify;
    2.19    RING_IDX req_prod = xi->rx.req_prod_pvt;
    2.20 @@ -300,21 +299,10 @@ XenNet_RxBufferAlloc(struct xennet_info 
    2.21        NdisFreeMemory(start, 0, 0);
    2.22        break;
    2.23      }
    2.24 -    NdisAllocatePacket(&status, &packet, xi->packet_pool);
    2.25 -    if (status != NDIS_STATUS_SUCCESS)
    2.26 -    {
    2.27 -      KdPrint(("NdisAllocatePacket Failed! status = 0x%x\n", status));
    2.28 -      NdisFreeMemory(start, 0, 0);
    2.29 -      NdisFreeBuffer(buffer);
    2.30 -      break;
    2.31 -    }
    2.32 -    NdisChainBufferAtBack(packet, buffer);
    2.33 -    NDIS_SET_PACKET_HEADER_SIZE(packet, XN_HDR_SIZE);
    2.34 -
    2.35      /* Give to netback */
    2.36      id = (unsigned short)(req_prod + i) & (NET_RX_RING_SIZE - 1);
    2.37 -    ASSERT(!xi->rx_pkts[id]);
    2.38 -    xi->rx_pkts[id] = packet;
    2.39 +//    ASSERT(!xi->rx_pkts[id]);
    2.40 +    xi->rx_buffers[id] = buffer;
    2.41      req = RING_GET_REQUEST(&xi->rx, req_prod + i);
    2.42      /* an NDIS_BUFFER is just a MDL, so we can get its pfn array */
    2.43      ref = xi->XenInterface.GntTbl_GrantAccess(
    2.44 @@ -345,7 +333,6 @@ XenNet_RxBufferFree(struct xennet_info *
    2.45  {
    2.46    int i;
    2.47    grant_ref_t ref;
    2.48 -  PNDIS_PACKET packet;
    2.49    PNDIS_BUFFER buffer;
    2.50    PVOID buff_va;
    2.51    UINT buff_len;
    2.52 @@ -358,22 +345,17 @@ XenNet_RxBufferFree(struct xennet_info *
    2.53  
    2.54    for (i = 0; i < NET_RX_RING_SIZE; i++)
    2.55    {
    2.56 -    if (!xi->rx_pkts[i])
    2.57 +    if (!xi->rx_buffers[i])
    2.58        continue;
    2.59  
    2.60 -    packet = xi->rx_pkts[i];
    2.61 +    buffer = xi->rx_buffers[i];
    2.62      ref = xi->grant_rx_ref[i];
    2.63  
    2.64      /* don't check return, what can we do about it on failure? */
    2.65      xi->XenInterface.GntTbl_EndAccess(xi->XenInterface.InterfaceHeader.Context, ref);
    2.66  
    2.67 -    NdisGetFirstBufferFromPacketSafe(packet, &buffer, &buff_va, &buff_len,
    2.68 -      &tot_buff_len, NormalPagePriority);
    2.69 -    ASSERT(buff_len == tot_buff_len);
    2.70 -
    2.71 -    NdisFreeMemory(buff_va, 0, 0);
    2.72 +    NdisFreeMemory(NdisBufferVirtualAddressSafe(buffer, NormalPagePriority), 0, 0);
    2.73      NdisFreeBuffer(buffer);
    2.74 -    NdisFreePacket(packet);
    2.75    }
    2.76  
    2.77    KeReleaseSpinLock(&xi->rx_lock, OldIrql);
    2.78 @@ -382,7 +364,9 @@ XenNet_RxBufferFree(struct xennet_info *
    2.79  static VOID
    2.80  XenNet_ProcessReceivedTcpPacket(PNDIS_PACKET packet, PUCHAR buf, ULONG len)
    2.81  {
    2.82 -  USHORT checksum = (buf[28] << 8) | buf[29];
    2.83 +  USHORT checksum = (buf[16] << 8) | buf[17];
    2.84 +  buf[16] = 0;
    2.85 +  buf[17] = 0;
    2.86  }
    2.87  
    2.88  static VOID
    2.89 @@ -405,6 +389,10 @@ XenNet_ProcessReceivedIpPacket(PNDIS_PAC
    2.90      return;
    2.91    }
    2.92  
    2.93 +  KdPrint((__DRIVER_NAME "     %d.%d.%d.%d -> %d.%d.%d.%d\n",
    2.94 +    buf[12], buf[13], buf[14], buf[15],
    2.95 +    buf[16], buf[17], buf[18], buf[19]));
    2.96 +
    2.97    header_len = (buf[0] & 15) * 4;
    2.98    total_len = (buf[2] << 8) | buf[3];
    2.99  
   2.100 @@ -420,11 +408,11 @@ XenNet_ProcessReceivedIpPacket(PNDIS_PAC
   2.101  
   2.102    switch (proto)
   2.103    {
   2.104 -  case 0x06: //tcp
   2.105 +  case 6: //tcp
   2.106      KdPrint((__DRIVER_NAME "     IP Proto = TCP\n"));
   2.107      XenNet_ProcessReceivedTcpPacket(packet, buf + header_len, len - header_len);
   2.108      break;
   2.109 -  case 0x17: //udp
   2.110 +  case 17: //udp
   2.111      KdPrint((__DRIVER_NAME "     IP Proto = UDP\n"));
   2.112      break;
   2.113    default:
   2.114 @@ -440,9 +428,11 @@ XenNet_ProcessReceivedEthernetPacket(PND
   2.115  
   2.116    if (len < 14)
   2.117    {
   2.118 -    KdPrint((__DRIVER_NAME "     Ethernet packet header too small.\n"));
   2.119 +    KdPrint((__DRIVER_NAME "     Ethernet packet header too small (%d).\n", len));
   2.120      return;
   2.121    }
   2.122 +  if (ethertype < 0x600)
   2.123 +    return; // not Ethernet II
   2.124    switch (ethertype)
   2.125    {
   2.126    case 0x0800:
   2.127 @@ -467,7 +457,7 @@ XenNet_RxBufferCheck(struct xennet_info 
   2.128  {
   2.129    RING_IDX cons, prod;
   2.130  
   2.131 -  PNDIS_PACKET packet;
   2.132 +  PNDIS_PACKET packet = NULL;
   2.133    PNDIS_BUFFER buffer;
   2.134    PVOID buff_va;
   2.135    UINT buff_len;
   2.136 @@ -475,8 +465,10 @@ XenNet_RxBufferCheck(struct xennet_info 
   2.137    int moretodo;
   2.138    KIRQL OldIrql;
   2.139    PNDIS_TCP_IP_CHECKSUM_PACKET_INFO csum_info;
   2.140 -
   2.141 +  struct netif_rx_response *rxrsp = NULL;
   2.142 +  int more_frags = 0;
   2.143  //  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
   2.144 +  PNDIS_STATUS status;
   2.145  
   2.146    ASSERT(xi->connected);
   2.147  
   2.148 @@ -487,52 +479,76 @@ XenNet_RxBufferCheck(struct xennet_info 
   2.149      KeMemoryBarrier(); /* Ensure we see responses up to 'rp'. */
   2.150  
   2.151      for (cons = xi->rx.rsp_cons; cons != prod; cons++) {
   2.152 -      struct netif_rx_response *rxrsp;
   2.153 -
   2.154        rxrsp = RING_GET_RESPONSE(&xi->rx, cons);
   2.155        if (rxrsp->status == NETIF_RSP_NULL)
   2.156          continue;
   2.157  
   2.158      //  KdPrint((__DRIVER_NAME "     Got a packet\n"));
   2.159  
   2.160 -      packet = xi->rx_pkts[rxrsp->id];
   2.161 -      xi->rx_pkts[rxrsp->id] = NULL;
   2.162 +      if (!more_frags) // !more_frags means this buffer is the first for the packet
   2.163 +      {
   2.164 +        // we might be able to set up an IP and an Other pool and select as appropriate here...
   2.165 +        NdisAllocatePacket(&status, &packet, xi->packet_pool);
   2.166 +        if (status != NDIS_STATUS_SUCCESS)
   2.167 +        {
   2.168 +          KdPrint(("NdisAllocatePacket Failed! status = 0x%x\n", status));
   2.169 +/* we are going to fail horribly here right now!!! */
   2.170 +/*
   2.171 +          NdisFreeMemory(start, 0, 0);
   2.172 +          NdisFreeBuffer(buffer);
   2.173 +          break;
   2.174 +*/
   2.175 +        }
   2.176 +        NDIS_SET_PACKET_HEADER_SIZE(packet, XN_HDR_SIZE);
   2.177 +/*
   2.178 +        if (NDIS_GET_PACKET_PROTOCOL_TYPE(packet) == NDIS_PROTOCOL_ID_TCP_IP
   2.179 +          && (rxrsp->flags & (NETRXF_csum_blank|NETRXF_data_validated)))
   2.180 +        {
   2.181 +          csum_info = (PNDIS_TCP_IP_CHECKSUM_PACKET_INFO)&NDIS_PER_PACKET_INFO_FROM_PACKET(packet, TcpIpChecksumPacketInfo);
   2.182 +          csum_info->Receive.NdisPacketTcpChecksumSucceeded = 1;
   2.183 +          csum_info->Receive.NdisPacketUdpChecksumSucceeded = 1;
   2.184 +          csum_info->Receive.NdisPacketIpChecksumSucceeded = 1;
   2.185 +//          KdPrint((__DRIVER_NAME "     Offload = %08x\n", NDIS_PER_PACKET_INFO_FROM_PACKET(packet, TcpIpChecksumPacketInfo)));
   2.186 +        }
   2.187 +*/
   2.188 +      }
   2.189 +      buffer = xi->rx_buffers[rxrsp->id];
   2.190 +      xi->rx_buffers[rxrsp->id] = NULL;
   2.191 +      NdisAdjustBufferLength(buffer, rxrsp->status);
   2.192 +
   2.193 +      NdisChainBufferAtBack(packet, buffer);
   2.194 +
   2.195        xi->XenInterface.GntTbl_EndAccess(xi->XenInterface.InterfaceHeader.Context,
   2.196          xi->grant_rx_ref[rxrsp->id]);
   2.197        xi->grant_rx_ref[rxrsp->id] = GRANT_INVALID_REF;
   2.198  
   2.199 +/*
   2.200        NdisGetFirstBufferFromPacketSafe(packet, &buffer, &buff_va, &buff_len,
   2.201          &tot_buff_len, NormalPagePriority);
   2.202        ASSERT(rxrsp->offset == 0);
   2.203        ASSERT(rxrsp->status > 0);
   2.204 -      NdisAdjustBufferLength(buffer, rxrsp->status);
   2.205 +*/
   2.206  
   2.207 -#if 0
   2.208 +#if 1
   2.209        KdPrint((__DRIVER_NAME "     Flags = %sNETRXF_data_validated|%sNETRXF_csum_blank|%sNETRXF_more_data|%sNETRXF_extra_info\n",
   2.210          (rxrsp->flags&NETRXF_data_validated)?"":"!",
   2.211          (rxrsp->flags&NETRXF_csum_blank)?"":"!",
   2.212          (rxrsp->flags&NETRXF_more_data)?"":"!",
   2.213          (rxrsp->flags&NETRXF_extra_info)?"":"!"));
   2.214  #endif
   2.215 -      XenNet_ProcessReceivedEthernetPacket(packet, buff_va, rxrsp->status);
   2.216 +      //XenNet_ProcessReceivedEthernetPacket(packet, buff_va, rxrsp->status);
   2.217  
   2.218 -      if (NDIS_GET_PACKET_PROTOCOL_TYPE(packet) == NDIS_PROTOCOL_ID_TCP_IP
   2.219 -        && (rxrsp->flags & (NETRXF_csum_blank|NETRXF_data_validated)))
   2.220 +      more_frags = rxrsp->flags & NETRXF_more_data;
   2.221 +
   2.222 +      if (!more_frags)
   2.223        {
   2.224 -        csum_info = (PNDIS_TCP_IP_CHECKSUM_PACKET_INFO)&NDIS_PER_PACKET_INFO_FROM_PACKET(packet, TcpIpChecksumPacketInfo);
   2.225 -        csum_info->Receive.NdisPacketTcpChecksumSucceeded = 1;
   2.226 -        csum_info->Receive.NdisPacketUdpChecksumSucceeded = 1;
   2.227 -        csum_info->Receive.NdisPacketIpChecksumSucceeded = 1;
   2.228 -//        KdPrint((__DRIVER_NAME "     Offload = %08x\n", NDIS_PER_PACKET_INFO_FROM_PACKET(packet, TcpIpChecksumPacketInfo)));
   2.229 -      }
   2.230 +        ASSERT(packet != NULL);
   2.231 +        xi->stat_rx_ok++;
   2.232 +        NDIS_SET_PACKET_STATUS(packet, NDIS_STATUS_SUCCESS);
   2.233  
   2.234 -      xi->stat_rx_ok++;
   2.235 -      NDIS_SET_PACKET_STATUS(packet, NDIS_STATUS_SUCCESS);
   2.236 -
   2.237 -      /* just indicate 1 packet for now */
   2.238 -    //  KdPrint((__DRIVER_NAME "     Indicating Received\n"));
   2.239 -      NdisMIndicateReceivePacket(xi->adapter_handle, &packet, 1);
   2.240 -    //  KdPrint((__DRIVER_NAME "     Done Indicating Received\n"));
   2.241 +        /* just indicate 1 packet for now */
   2.242 +        NdisMIndicateReceivePacket(xi->adapter_handle, &packet, 1);
   2.243 +      }
   2.244      }
   2.245  
   2.246      xi->rx.rsp_cons = prod;
   2.247 @@ -540,6 +556,17 @@ XenNet_RxBufferCheck(struct xennet_info 
   2.248      RING_FINAL_CHECK_FOR_RESPONSES(&xi->rx, moretodo);
   2.249    } while (moretodo);
   2.250  
   2.251 +  if (more_frags)
   2.252 +  {
   2.253 +    KdPrint((__DRIVER_NAME "     Missing fragments\n"));
   2.254 +    // free our packet and buffer(s) (may be more than one buffer...) here, as nobody else will!
   2.255 +/*
   2.256 +    NdisFreeMemory(buff_va, 0, 0);
   2.257 +    NdisFreeBuffer(buffer);
   2.258 +    NdisFreePacket(packet);
   2.259 +*/
   2.260 +  }
   2.261 +
   2.262    /* Give netback more buffers */
   2.263    XenNet_RxBufferAlloc(xi);
   2.264  
   2.265 @@ -827,7 +854,7 @@ XenNet_Init(
   2.266    }
   2.267  
   2.268    for (i = 0; i < NET_RX_RING_SIZE; i++) {
   2.269 -    xi->rx_pkts[i] = NULL;
   2.270 +    xi->rx_buffers[i] = NULL;
   2.271      xi->grant_rx_ref[i] = GRANT_INVALID_REF;
   2.272    }
   2.273  
   2.274 @@ -887,7 +914,7 @@ XenNet_Init(
   2.275    res = xi->XenInterface.XenBus_Read(xi->XenInterface.InterfaceHeader.Context,
   2.276        XBT_NIL, TmpPath, &Value);
   2.277  
   2.278 -#if 0
   2.279 +#if 1
   2.280    if (res || strcmp(Value, "netfront") != 0)
   2.281    {
   2.282      KdPrint((__DRIVER_NAME "    Backend type is not 'netfront'\n"));
   2.283 @@ -1467,9 +1494,7 @@ XenNet_ReturnPacket(
   2.284  
   2.285    NdisGetFirstBufferFromPacketSafe(Packet, &buffer, &buff_va, &buff_len,
   2.286      &tot_buff_len, NormalPagePriority);
   2.287 -  ASSERT(buff_len == tot_buff_len);
   2.288 -
   2.289 -  /* TODO: reuse returned packets */
   2.290 +  //ASSERT(buff_len == tot_buff_len);
   2.291  
   2.292    NdisFreeMemory(buff_va, 0, 0);
   2.293    NdisFreeBuffer(buffer);