win-pvdrivers

changeset 218:c33404027885

Merge
author James Harper <james.harper@bendigoit.com.au>
date Fri Mar 21 20:40:03 2008 +1100 (2008-03-21)
parents f315522a2a3e 90fcd61a9cbb
children 6974a4ace9d3
files xennet/xennet_tx.c
line diff
     1.1 --- a/xenhide/xenhide.c	Fri Mar 21 17:51:32 2008 +1100
     1.2 +++ b/xenhide/xenhide.c	Fri Mar 21 20:40:03 2008 +1100
     1.3 @@ -159,28 +159,29 @@ XenHide_AddDevice(
     1.4    PDEVICE_OBJECT deviceObject = NULL;
     1.5    PDEVICE_EXTENSION DeviceExtension;
     1.6    ULONG Length;
     1.7 -  WCHAR Buffer[1000];
     1.8 +  WCHAR Buffer[256];
     1.9    size_t StrLen;
    1.10    int Match;
    1.11    PWCHAR Ptr;
    1.12  
    1.13  //  KdPrint((__DRIVER_NAME " --> " __FUNCTION__ "\n"));
    1.14  
    1.15 -  Length = 1000;
    1.16 +  Length = sizeof(Buffer);
    1.17    status = IoGetDeviceProperty(PhysicalDeviceObject, DevicePropertyHardwareID, Length, Buffer, &Length);
    1.18  //  KdPrint((__DRIVER_NAME " status = %08x, DevicePropertyHardwareID, = %ws\n", status, Buffer));
    1.19    if (!NT_SUCCESS(status))
    1.20      return STATUS_SUCCESS;
    1.21  
    1.22 +  /* does end of HwID match PNP0A03? */
    1.23    Match = 0;
    1.24 -  StrLen = 0;
    1.25 -  for (Ptr = Buffer; *Ptr != 0; Ptr += StrLen + 1)
    1.26 +  RtlStringCchLengthW(Buffer, Length/2, &StrLen); // get strlen in wchars
    1.27 +  if (StrLen >= 7)
    1.28    {
    1.29 -    if (wcscmp(Ptr, L"*PNP0A03") == 0) {
    1.30 +    Ptr = Buffer + (StrLen - 7);
    1.31 +    if (wcscmp(Ptr, L"PNP0A03") == 0)
    1.32 +    {
    1.33        Match = 1;
    1.34 -      break;
    1.35      }
    1.36 -    RtlStringCchLengthW(Ptr, Length, &StrLen);
    1.37    }
    1.38    if (!Match)
    1.39      return STATUS_SUCCESS;
    1.40 @@ -251,7 +252,7 @@ XenHide_IoCompletion(PDEVICE_OBJECT Devi
    1.41  {
    1.42    ULONG i, j;
    1.43    PDEVICE_RELATIONS Relations;
    1.44 -  WCHAR Buffer[1000];
    1.45 +  WCHAR Buffer[256];
    1.46    PWCHAR Ptr;
    1.47    ULONG Length;
    1.48    size_t StrLen;
     2.1 --- a/xennet/xennet_tx.c	Fri Mar 21 17:51:32 2008 +1100
     2.2 +++ b/xennet/xennet_tx.c	Fri Mar 21 20:40:03 2008 +1100
     2.3 @@ -71,9 +71,9 @@ put_gref_on_freelist(struct xennet_info 
     2.4  #define SWAP_USHORT(x) (USHORT)((((x & 0xFF) << 8)|((x >> 8) & 0xFF)))
     2.5  
     2.6  /*
     2.7 - Windows assumes that if we can do large send offload then we can
     2.8 - do IP header csum offload, so we have to fake it!
     2.9 -*/
    2.10 + * Windows assumes that if we can do large send offload then we can
    2.11 + * do IP header csum offload, so we have to fake it!
    2.12 + */
    2.13  VOID
    2.14  XenNet_SumHeader(
    2.15   PMDL mdl /* first buffer of the packet - containing the header */
    2.16 @@ -110,32 +110,197 @@ XenNet_SumHeader(
    2.17  
    2.18  /* Called at DISPATCH_LEVEL with tx_lock held */
    2.19  
    2.20 +static BOOLEAN
    2.21 +XenNet_HWSendPacket(struct xennet_info *xi, PNDIS_PACKET packet)
    2.22 +{
    2.23 +  struct netif_tx_request *tx;
    2.24 +  struct netif_extra_info *ei;
    2.25 +  unsigned short id;
    2.26 +#if defined(XEN_PROFILE)
    2.27 +  LARGE_INTEGER tsc, dummy;
    2.28 +#endif
    2.29 +  PNDIS_TCP_IP_CHECKSUM_PACKET_INFO csum_info;
    2.30 +  
    2.31 +  ULONG i = 0;
    2.32 +  PSCATTER_GATHER_LIST sg_list;
    2.33 +  UINT total_packet_length;
    2.34 +  USHORT remaining = 0;
    2.35 +  USHORT offset = 0;
    2.36 +  USHORT length;
    2.37 +  ULONGLONG curr_addr = 0;
    2.38 +  ULONG sg_num = 0;
    2.39 +  ULONG pfn;
    2.40 +  ULONG mss = 0;
    2.41 +  PMDL first_buffer;
    2.42 +  int cycles = 0;
    2.43 +
    2.44 +#if defined(XEN_PROFILE)
    2.45 +  tsc = KeQueryPerformanceCounter(&dummy);
    2.46 +#endif
    2.47 +
    2.48 +  NdisQueryPacket(packet, NULL, NULL, &first_buffer, &total_packet_length);
    2.49 +  sg_list = NDIS_PER_PACKET_INFO_FROM_PACKET(packet, ScatterGatherListPacketInfo);
    2.50 +
    2.51 +  while (sg_num < sg_list->NumberOfElements || remaining || (i == 1 && mss))
    2.52 +  {
    2.53 +    //KdPrint((__DRIVER_NAME "     i = %d\n", i));
    2.54 +    ASSERT(cycles++ < 256);
    2.55 +    if (i == 1 && mss)
    2.56 +    {
    2.57 +      //KdPrint((__DRIVER_NAME "     Start of loop - Large Send...\n"));
    2.58 +      length = 0;
    2.59 +    }
    2.60 +    else if (remaining == 0)
    2.61 +    {
    2.62 +      mss = PtrToUlong(NDIS_PER_PACKET_INFO_FROM_PACKET(packet, TcpLargeSendPacketInfo));
    2.63 +      if (total_packet_length <= mss)
    2.64 +      {
    2.65 +        mss = 0;
    2.66 +      }
    2.67 +      //if (mss)
    2.68 +      //KdPrint((__DRIVER_NAME "     Start of loop - First Frag in sg...\n"));
    2.69 +      curr_addr = sg_list->Elements[sg_num].Address.QuadPart;
    2.70 +      offset = (USHORT)(sg_list->Elements[sg_num].Address.QuadPart & (PAGE_SIZE - 1));
    2.71 +      remaining = (USHORT)sg_list->Elements[sg_num].Length;
    2.72 +      length = min(remaining, PAGE_SIZE - offset);
    2.73 +      //if (mss)
    2.74 +      //KdPrint((__DRIVER_NAME "     sg entry %d - start = %08x, length = %d\n", sg_num, (ULONG)curr_addr, length));
    2.75 +      sg_num++;
    2.76 +    }
    2.77 +    else
    2.78 +    {
    2.79 +      //if (mss)
    2.80 +      //KdPrint((__DRIVER_NAME "     Start of loop - Subsequent Frag in sg...\n"));
    2.81 +      offset = 0;
    2.82 +      length = min(remaining, PAGE_SIZE);
    2.83 +      //if (mss)
    2.84 +      //KdPrint((__DRIVER_NAME "     sg entry %d - start = %08x, length = %d\n", sg_num, (ULONG)curr_addr, length));
    2.85 +    }
    2.86 +    remaining = remaining - length;
    2.87 +    pfn = (ULONG)(curr_addr >> PAGE_SHIFT);
    2.88 +    curr_addr += length;
    2.89 +
    2.90 +    if (i++ < *(ULONG *)&packet->MiniportReservedEx)
    2.91 +      continue;
    2.92 +    if (length > 0)
    2.93 +    {
    2.94 +      id = get_id_from_freelist(xi);
    2.95 +      if (id == 0xFFFF)
    2.96 +      {
    2.97 +        KdPrint((__DRIVER_NAME "     Out of space...\n"));
    2.98 +        /* whups, out of space on the ring. requeue and get out */
    2.99 +        /* TODO: preallocate all ids so we can exit cleanly here? */
   2.100 +        return FALSE;
   2.101 +        //InsertHeadList(&xi->tx_waiting_pkt_list, entry);
   2.102 +        //break;
   2.103 +      }
   2.104 +      ASSERT(xi->tx_pkts[id] == NULL);
   2.105 +      (*(ULONG *)&packet->MiniportReservedEx)++;
   2.106 +      tx = RING_GET_REQUEST(&xi->tx, xi->tx.req_prod_pvt);
   2.107 +
   2.108 +      tx->gref = get_gref_from_freelist(xi);
   2.109 +      ASSERT(tx->gref != 0);
   2.110 +      ASSERT(xi->tx_grefs[id] == 0);
   2.111 +      xi->tx_grefs[id] = tx->gref;
   2.112 +
   2.113 +      xi->XenInterface.GntTbl_GrantAccess(
   2.114 +        xi->XenInterface.InterfaceHeader.Context, 0,
   2.115 +        pfn, FALSE, tx->gref);
   2.116 +      tx->id = id;
   2.117 +      tx->offset = offset;
   2.118 +      tx->flags = 0;
   2.119 +      if (i != 1)
   2.120 +      {
   2.121 +        //if (mss)
   2.122 +        //KdPrint((__DRIVER_NAME "     Subsequent Frag in packet...\n"));
   2.123 +        tx->size = length;
   2.124 +      }
   2.125 +      else // we have already incremented i!!!
   2.126 +      {
   2.127 +        //if (mss)
   2.128 +        //KdPrint((__DRIVER_NAME "     First Frag in packet...\n"));
   2.129 +        tx->size = (USHORT)total_packet_length;
   2.130 +#if defined(XEN_PROFILE)
   2.131 +        ProfCount_TxPacketsTotal++;
   2.132 +#endif
   2.133 +        csum_info = (PNDIS_TCP_IP_CHECKSUM_PACKET_INFO)&NDIS_PER_PACKET_INFO_FROM_PACKET(
   2.134 +          packet, TcpIpChecksumPacketInfo);
   2.135 +        if (csum_info->Transmit.NdisPacketTcpChecksum
   2.136 +          || csum_info->Transmit.NdisPacketUdpChecksum)
   2.137 +        {
   2.138 +          tx->flags |= NETTXF_csum_blank|NETTXF_data_validated;
   2.139 +#if defined(XEN_PROFILE)
   2.140 +          ProfCount_TxPacketsCsumOffload++;
   2.141 +#endif
   2.142 +        }
   2.143 +
   2.144 +        if (mss)
   2.145 +        {
   2.146 +          XenNet_SumHeader(first_buffer);
   2.147 +          //KdPrint((__DRIVER_NAME "     Large Send Offload - mss = %d, length = %d\n", mss, total_packet_length));
   2.148 +          tx->flags |= NETTXF_extra_info|NETTXF_csum_blank|NETTXF_data_validated;
   2.149 +#if defined(XEN_PROFILE)
   2.150 +          ProfCount_TxPacketsLargeOffload++;
   2.151 +#endif
   2.152 +        }
   2.153 +      }
   2.154 +
   2.155 +      if (sg_num == sg_list->NumberOfElements && remaining == 0)
   2.156 +      {
   2.157 +        //if (mss)
   2.158 +        //KdPrint((__DRIVER_NAME "     No more frags\n"));
   2.159 +        xi->tx_pkts[id] = packet; /* only set the packet on the last buffer */
   2.160 +      }
   2.161 +      else
   2.162 +      {
   2.163 +        //if (mss)
   2.164 +        //KdPrint((__DRIVER_NAME "     More frags\n"));
   2.165 +        tx->flags |= NETTXF_more_data;
   2.166 +      }
   2.167 +    }
   2.168 +    else
   2.169 +    {
   2.170 +      id = get_no_id_from_freelist(xi);
   2.171 +      if (id == 0xFFFF)
   2.172 +      {
   2.173 +        KdPrint((__DRIVER_NAME "     Out of space...\n"));
   2.174 +        /* whups, out of space on the ring. requeue and get out */
   2.175 +        /* TODO: preallocate all ids so we can exit cleanly here? */
   2.176 +        return FALSE;
   2.177 +        //InsertHeadList(&xi->tx_waiting_pkt_list, entry);
   2.178 +        //break;
   2.179 +      }
   2.180 +      //if (mss)
   2.181 +      //KdPrint((__DRIVER_NAME "     Extra Info...\n"));
   2.182 +      (*(ULONG *)&packet->MiniportReservedEx)++;
   2.183 +      ei = (struct netif_extra_info *)RING_GET_REQUEST(&xi->tx, xi->tx.req_prod_pvt);
   2.184 +      ei->type = XEN_NETIF_EXTRA_TYPE_GSO;
   2.185 +      ei->flags = 0;
   2.186 +      ei->u.gso.size = (USHORT)mss;
   2.187 +      ei->u.gso.type = XEN_NETIF_GSO_TYPE_TCPV4;
   2.188 +      ei->u.gso.pad = 0;
   2.189 +      ei->u.gso.features = 0;
   2.190 +    }
   2.191 +    xi->tx.req_prod_pvt++;
   2.192 +  }
   2.193 +
   2.194 +  return TRUE;
   2.195 +}
   2.196 +
   2.197 +/* Called at DISPATCH_LEVEL with tx_lock held */
   2.198 +
   2.199  static VOID
   2.200  XenNet_SendQueuedPackets(struct xennet_info *xi)
   2.201  {
   2.202    PLIST_ENTRY entry;
   2.203    PNDIS_PACKET packet;
   2.204 -  struct netif_tx_request *tx;
   2.205 -  struct netif_extra_info *ei;
   2.206 -  unsigned short id;
   2.207    int notify;
   2.208  #if defined(XEN_PROFILE)
   2.209    LARGE_INTEGER tsc, dummy;
   2.210  #endif
   2.211 -  PNDIS_TCP_IP_CHECKSUM_PACKET_INFO csum_info;
   2.212    
   2.213 -  ULONG i;
   2.214 -  PSCATTER_GATHER_LIST sg_list;
   2.215 -  UINT total_packet_length;
   2.216 -  USHORT remaining;
   2.217 -  USHORT offset;
   2.218 -  USHORT length;
   2.219 -  ULONGLONG curr_addr;
   2.220 -  ULONG sg_num;
   2.221 -  ULONG pfn;
   2.222 -  ULONG mss;
   2.223 -  PMDL first_buffer;
   2.224    int cycles = 0;
   2.225 +  BOOLEAN success;
   2.226  
   2.227  #if defined(XEN_PROFILE)
   2.228    tsc = KeQueryPerformanceCounter(&dummy);
   2.229 @@ -146,156 +311,10 @@ XenNet_SendQueuedPackets(struct xennet_i
   2.230    while (entry != &xi->tx_waiting_pkt_list)
   2.231    {
   2.232      ASSERT(cycles++ < 256);
   2.233 -//KdPrint((__DRIVER_NAME "     Packet ready to send\n"));
   2.234 +    //KdPrint((__DRIVER_NAME "     Packet ready to send\n"));
   2.235      packet = CONTAINING_RECORD(entry, NDIS_PACKET, MiniportReservedEx[sizeof(PVOID)]);
   2.236 -    NdisQueryPacket(packet, NULL, NULL, &first_buffer, &total_packet_length);
   2.237 -    sg_list = NDIS_PER_PACKET_INFO_FROM_PACKET(packet, ScatterGatherListPacketInfo);
   2.238 -/*
   2.239 -    for (i = 0; i < sg_list->NumberOfElements; i++)
   2.240 -    {
   2.241 -      KdPrint((__DRIVER_NAME "     sg entry %d - start = %08x, length = %d\n", i, sg_list->Elements[i].Address.LowPart, sg_list->Elements[i].Length));
   2.242 -    }
   2.243 -*/
   2.244 -    i = 0;
   2.245 -    sg_num = 0;
   2.246 -    remaining = 0;
   2.247 -    curr_addr = 0;
   2.248 -    id = 0;
   2.249 -    mss = 0;
   2.250 -    offset = 0;
   2.251 -    while (sg_num < sg_list->NumberOfElements || remaining || (i == 1 && mss))
   2.252 -    {
   2.253 -//KdPrint((__DRIVER_NAME "     i = %d\n", i));
   2.254 -      ASSERT(cycles++ < 256);
   2.255 -      if (i == 1 && mss)
   2.256 -      {
   2.257 -//KdPrint((__DRIVER_NAME "     Start of loop - Large Send...\n"));
   2.258 -        length = 0;
   2.259 -      }
   2.260 -      else if (remaining == 0)
   2.261 -      {
   2.262 -        mss = PtrToUlong(NDIS_PER_PACKET_INFO_FROM_PACKET(packet, TcpLargeSendPacketInfo));
   2.263 -        if (total_packet_length <= mss)
   2.264 -          mss = 0;
   2.265 -//if (mss)
   2.266 -//KdPrint((__DRIVER_NAME "     Start of loop - First Frag in sg...\n"));
   2.267 -        curr_addr = sg_list->Elements[sg_num].Address.QuadPart;
   2.268 -        offset = (USHORT)(sg_list->Elements[sg_num].Address.QuadPart & (PAGE_SIZE - 1));
   2.269 -        remaining = (USHORT)sg_list->Elements[sg_num].Length;
   2.270 -        length = min(remaining, PAGE_SIZE - offset);
   2.271 -//if (mss)
   2.272 -//KdPrint((__DRIVER_NAME "     sg entry %d - start = %08x, length = %d\n", sg_num, (ULONG)curr_addr, length));
   2.273 -        sg_num++;
   2.274 -      }
   2.275 -      else
   2.276 -      {
   2.277 -//if (mss)
   2.278 -//KdPrint((__DRIVER_NAME "     Start of loop - Subsequent Frag in sg...\n"));
   2.279 -        offset = 0;
   2.280 -        length = min(remaining, PAGE_SIZE);
   2.281 -//if (mss)
   2.282 -//KdPrint((__DRIVER_NAME "     sg entry %d - start = %08x, length = %d\n", sg_num, (ULONG)curr_addr, length));
   2.283 -      }
   2.284 -      remaining = remaining - length;
   2.285 -      pfn = (ULONG)(curr_addr >> PAGE_SHIFT);
   2.286 -      curr_addr += length;
   2.287 -
   2.288 -      if (i++ < *(ULONG *)&packet->MiniportReservedEx)
   2.289 -        continue;
   2.290 -      if (length > 0)
   2.291 -      {
   2.292 -        id = get_id_from_freelist(xi);
   2.293 -        if (id == 0xFFFF)
   2.294 -        {
   2.295 -KdPrint((__DRIVER_NAME "     Out of space...\n"));
   2.296 -          /* whups, out of space on the ring. requeue and get out */
   2.297 -          InsertHeadList(&xi->tx_waiting_pkt_list, entry);
   2.298 -          break;
   2.299 -        }
   2.300 -        ASSERT(xi->tx_pkts[id] == NULL);
   2.301 -        (*(ULONG *)&packet->MiniportReservedEx)++;
   2.302 -        tx = RING_GET_REQUEST(&xi->tx, xi->tx.req_prod_pvt);
   2.303 -
   2.304 -        tx->gref = get_gref_from_freelist(xi);
   2.305 -        ASSERT(tx->gref != 0);
   2.306 -        ASSERT(xi->tx_grefs[id] == 0);
   2.307 -        xi->tx_grefs[id] = tx->gref;
   2.308 -  
   2.309 -        xi->XenInterface.GntTbl_GrantAccess(
   2.310 -          xi->XenInterface.InterfaceHeader.Context, 0,
   2.311 -          pfn, FALSE, tx->gref);
   2.312 -        tx->id = id;
   2.313 -        tx->offset = offset;
   2.314 -        tx->flags = 0;
   2.315 -        if (i == 1) // we have already incremented i!!!
   2.316 -        {
   2.317 -//if (mss)
   2.318 -//KdPrint((__DRIVER_NAME "     First Frag in packet...\n"));
   2.319 -          tx->size = (USHORT)total_packet_length;
   2.320 -#if defined(XEN_PROFILE)
   2.321 -          ProfCount_TxPacketsTotal++;
   2.322 -#endif
   2.323 -          csum_info = (PNDIS_TCP_IP_CHECKSUM_PACKET_INFO)&NDIS_PER_PACKET_INFO_FROM_PACKET(packet, TcpIpChecksumPacketInfo);
   2.324 -          if (csum_info->Transmit.NdisPacketTcpChecksum || csum_info->Transmit.NdisPacketUdpChecksum)
   2.325 -          {
   2.326 -            tx->flags |= NETTXF_csum_blank|NETTXF_data_validated;
   2.327 -#if defined(XEN_PROFILE)
   2.328 -            ProfCount_TxPacketsCsumOffload++;
   2.329 -#endif
   2.330 -          }
   2.331 -          if (mss)
   2.332 -          {
   2.333 -            XenNet_SumHeader(first_buffer);
   2.334 -//KdPrint((__DRIVER_NAME "     Large Send Offload - mss = %d, length = %d\n", mss, total_packet_length));
   2.335 -            tx->flags |= NETTXF_extra_info|NETTXF_csum_blank|NETTXF_data_validated;
   2.336 -#if defined(XEN_PROFILE)
   2.337 -            ProfCount_TxPacketsLargeOffload++;
   2.338 -#endif
   2.339 -          }
   2.340 -        }
   2.341 -        else
   2.342 -        {
   2.343 -//if (mss)
   2.344 -//KdPrint((__DRIVER_NAME "     Subsequent Frag in packet...\n"));
   2.345 -          tx->size = length;
   2.346 -        }
   2.347 -        if (sg_num == sg_list->NumberOfElements && remaining == 0)
   2.348 -        {
   2.349 -//if (mss)
   2.350 -//KdPrint((__DRIVER_NAME "     No more frags\n"));
   2.351 -          xi->tx_pkts[id] = packet; /* only set the packet on the last buffer */
   2.352 -        }
   2.353 -        else
   2.354 -        {
   2.355 -//if (mss)
   2.356 -//KdPrint((__DRIVER_NAME "     More frags\n"));
   2.357 -          tx->flags |= NETTXF_more_data;
   2.358 -        }
   2.359 -      }
   2.360 -      else
   2.361 -      {
   2.362 -        id = get_no_id_from_freelist(xi);
   2.363 -        if (id == 0xFFFF)
   2.364 -        {
   2.365 -KdPrint((__DRIVER_NAME "     Out of space...\n"));
   2.366 -          /* whups, out of space on the ring. requeue and get out */
   2.367 -          InsertHeadList(&xi->tx_waiting_pkt_list, entry);
   2.368 -          break;
   2.369 -        }
   2.370 -//if (mss)
   2.371 -//KdPrint((__DRIVER_NAME "     Extra Info...\n"));
   2.372 -        (*(ULONG *)&packet->MiniportReservedEx)++;
   2.373 -        ei = (struct netif_extra_info *)RING_GET_REQUEST(&xi->tx, xi->tx.req_prod_pvt);
   2.374 -        ei->type = XEN_NETIF_EXTRA_TYPE_GSO;
   2.375 -        ei->flags = 0;
   2.376 -        ei->u.gso.size = (USHORT)mss;
   2.377 -        ei->u.gso.type = XEN_NETIF_GSO_TYPE_TCPV4;
   2.378 -        ei->u.gso.pad = 0;
   2.379 -        ei->u.gso.features = 0;
   2.380 -      }
   2.381 -      xi->tx.req_prod_pvt++;
   2.382 -    }
   2.383 -    if (id == 0xFFFF)
   2.384 +    success = XenNet_HWSendPacket(xi, packet);
   2.385 +    if (!success)
   2.386        break;
   2.387      entry = RemoveHeadList(&xi->tx_waiting_pkt_list);
   2.388    }
   2.389 @@ -376,7 +395,7 @@ XenNet_TxBufferGC(struct xennet_info *xi
   2.390        put_gref_on_freelist(xi, xi->tx_grefs[id]);
   2.391        xi->tx_grefs[id] = 0;
   2.392        put_id_on_freelist(xi, id);
   2.393 -      xi->tx_outstanding++;
   2.394 +      xi->tx_outstanding--;
   2.395      }
   2.396  
   2.397      xi->tx.rsp_cons = prod;
   2.398 @@ -438,7 +457,7 @@ XenNet_SendPackets(
   2.399      *(ULONG *)&packet->MiniportReservedEx = 0;
   2.400      entry = (PLIST_ENTRY)&packet->MiniportReservedEx[sizeof(PVOID)];
   2.401      InsertTailList(&xi->tx_waiting_pkt_list, entry);
   2.402 -    xi->tx_outstanding--;
   2.403 +    xi->tx_outstanding++;
   2.404  #if defined(XEN_PROFILE)
   2.405      ProfCount_PacketsPerSendPackets++;
   2.406  #endif