win-pvdrivers

changeset 559:b0b8be2d30c0 0.10.0.50

Fixed up a bug where packets with too many SG elements were corrupted.
author James Harper <james.harper@bendigoit.com.au>
date Sun Apr 12 19:15:14 2009 +1000 (2009-04-12)
parents bbac251831a8
children 369502736dfd
files xennet/xennet.c xennet/xennet.h xennet/xennet_oid.c xennet/xennet_rx.c xennet/xennet_tx.c
line diff
     1.1 --- a/xennet/xennet.c	Sun Apr 12 19:14:39 2009 +1000
     1.2 +++ b/xennet/xennet.c	Sun Apr 12 19:15:14 2009 +1000
     1.3 @@ -208,6 +208,10 @@ XenNet_Resume(PDEVICE_OBJECT device_obje
     1.4    
     1.5    FUNCTION_ENTER();
     1.6    
     1.7 +  ASSERT(xi->resume_work_item);
     1.8 +  IoFreeWorkItem(xi->resume_work_item);
     1.9 +  xi->resume_work_item = NULL;
    1.10 +  
    1.11    XenNet_TxResumeStart(xi);
    1.12    XenNet_RxResumeStart(xi);
    1.13    XenNet_ConnectBackend(xi);
    1.14 @@ -226,7 +230,6 @@ static VOID
    1.15  XenNet_SuspendResume(PKDPC dpc, PVOID context, PVOID arg1, PVOID arg2)
    1.16  {
    1.17    struct xennet_info *xi = context;
    1.18 -  PIO_WORKITEM work_item;
    1.19    KIRQL old_irql;
    1.20  
    1.21    UNREFERENCED_PARAMETER(dpc);
    1.22 @@ -250,8 +253,9 @@ XenNet_SuspendResume(PKDPC dpc, PVOID co
    1.23      break;
    1.24    case SR_STATE_RESUMING:
    1.25      KdPrint((__DRIVER_NAME "     New state SR_STATE_RESUMING\n"));
    1.26 -    work_item = IoAllocateWorkItem(xi->fdo);
    1.27 -    IoQueueWorkItem(work_item, XenNet_Resume, DelayedWorkQueue, xi);
    1.28 +    ASSERT(!xi->resume_work_item);
    1.29 +    xi->resume_work_item = IoAllocateWorkItem(xi->fdo);
    1.30 +    IoQueueWorkItem(xi->resume_work_item, XenNet_Resume, DelayedWorkQueue, xi);
    1.31      break;
    1.32    default:
    1.33      KdPrint((__DRIVER_NAME "     New state %d\n", xi->device_state->suspend_resume_state_fdo));
    1.34 @@ -717,6 +721,8 @@ XenNet_Reset(
    1.35    return NDIS_STATUS_SUCCESS;
    1.36  }
    1.37  
    1.38 +dma_driver_extension_t *dma_driver_extension;
    1.39 +
    1.40  NTSTATUS DDKAPI
    1.41  DriverEntry(
    1.42    PDRIVER_OBJECT DriverObject,
    1.43 @@ -729,6 +735,11 @@ DriverEntry(
    1.44  
    1.45    FUNCTION_ENTER();
    1.46  
    1.47 +  IoAllocateDriverObjectExtension(DriverObject, UlongToPtr(XEN_DMA_DRIVER_EXTENSION_MAGIC), sizeof(dma_driver_extension_t), &dma_driver_extension);  
    1.48 +  dma_driver_extension->need_virtual_address = NULL;
    1.49 +  dma_driver_extension->get_alignment = NULL;
    1.50 +  dma_driver_extension->max_sg_elements = 17;
    1.51 +
    1.52    KdPrint((__DRIVER_NAME "     DriverObject = %p, RegistryPath = %p\n", DriverObject, RegistryPath));
    1.53    RtlZeroMemory(&mini_chars, sizeof(mini_chars));
    1.54  
     2.1 --- a/xennet/xennet.h	Sun Apr 12 19:14:39 2009 +1000
     2.2 +++ b/xennet/xennet.h	Sun Apr 12 19:15:14 2009 +1000
     2.3 @@ -259,6 +259,7 @@ struct xennet_info
     2.4    UCHAR multicast_list[MULTICAST_LIST_MAX_SIZE][6];
     2.5    ULONG multicast_list_size;
     2.6    KDPC suspend_dpc;
     2.7 +  PIO_WORKITEM resume_work_item;
     2.8  
     2.9    /* tx related - protected by tx_lock */
    2.10    KSPIN_LOCK tx_lock;
     3.1 --- a/xennet/xennet_oid.c	Sun Apr 12 19:14:39 2009 +1000
     3.2 +++ b/xennet/xennet_oid.c	Sun Apr 12 19:15:14 2009 +1000
     3.3 @@ -348,6 +348,11 @@ XenNet_QueryInformation(
     3.4  
     3.5        used_temp_buffer = FALSE;
     3.6        break;
     3.7 +    case OID_IP4_OFFLOAD_STATS:
     3.8 +    case OID_IP6_OFFLOAD_STATS:
     3.9 +      /* these are called often so just ignore then quietly */
    3.10 +      status = NDIS_STATUS_NOT_SUPPORTED;
    3.11 +      break;
    3.12      default:
    3.13        KdPrint(("Get Unknown OID 0x%x\n", Oid));
    3.14        status = NDIS_STATUS_NOT_SUPPORTED;
     4.1 --- a/xennet/xennet_rx.c	Sun Apr 12 19:14:39 2009 +1000
     4.2 +++ b/xennet/xennet_rx.c	Sun Apr 12 19:15:14 2009 +1000
     4.3 @@ -665,7 +665,7 @@ XenNet_RxBufferCheck(PKDPC dpc, PVOID co
     4.4      for (cons = xi->rx.rsp_cons; cons != prod && packet_count < MAX_PACKETS_PER_INTERRUPT; cons++)
     4.5      {
     4.6        id = (USHORT)(cons & (NET_RX_RING_SIZE - 1));
     4.7 -      ASSERT(xi->rx_ring_pbs[id]);
     4.8 +      ASSERT(xi->rx_ring_pbs[id] != (USHORT)0xFFFF);
     4.9        page_buf = &xi->rx_pbs[xi->rx_ring_pbs[id]];
    4.10        xi->rx_ring_pbs[id] = 0xFFFF;
    4.11        xi->rx_id_free++;
     5.1 --- a/xennet/xennet_tx.c	Sun Apr 12 19:14:39 2009 +1000
     5.2 +++ b/xennet/xennet_tx.c	Sun Apr 12 19:15:14 2009 +1000
     5.3 @@ -41,21 +41,32 @@ get_hb_from_freelist(struct xennet_info 
     5.4  {
     5.5    shared_buffer_t *hb;
     5.6    
     5.7 +  //FUNCTION_ENTER();
     5.8    if (xi->tx_hb_free == 0)
     5.9    {
    5.10 +    //FUNCTION_EXIT();
    5.11      return NULL;
    5.12    }
    5.13    xi->tx_hb_free--;
    5.14 -
    5.15 +  //KdPrint((__DRIVER_NAME "     xi->tx_hb_free = %d\n", xi->tx_hb_free));
    5.16 +  //KdPrint((__DRIVER_NAME "     xi->tx_hb_list[xi->tx_hb_free] = %d\n", xi->tx_hb_list[xi->tx_hb_free]));
    5.17    hb = &xi->tx_hbs[xi->tx_hb_list[xi->tx_hb_free]];
    5.18 +  //KdPrint((__DRIVER_NAME "     hb = %p\n", hb));
    5.19 +  //FUNCTION_EXIT();
    5.20    return hb;
    5.21  }
    5.22  
    5.23  static __inline VOID
    5.24  put_hb_on_freelist(struct xennet_info *xi, shared_buffer_t *hb)
    5.25  {
    5.26 +  //FUNCTION_ENTER();
    5.27 +  
    5.28 +  //KdPrint((__DRIVER_NAME "     hb = %p\n", hb));
    5.29 +  //KdPrint((__DRIVER_NAME "     xi->tx_hb_free = %d\n", xi->tx_hb_free));
    5.30 +  ASSERT(hb);
    5.31    xi->tx_hb_list[xi->tx_hb_free] = hb->id;
    5.32    xi->tx_hb_free++;
    5.33 +  //FUNCTION_EXIT();
    5.34  }
    5.35  
    5.36  #define SWAP_USHORT(x) (USHORT)((((x & 0xFF) << 8)|((x >> 8) & 0xFF)))
    5.37 @@ -83,6 +94,7 @@ XenNet_HWSendPacket(struct xennet_info *
    5.38    ULONG sg_offset = 0;
    5.39    ULONG parse_result;
    5.40    shared_buffer_t *header_buf = NULL;
    5.41 +  ULONG chunks = 0;
    5.42    
    5.43    //FUNCTION_ENTER();
    5.44    
    5.45 @@ -93,6 +105,9 @@ XenNet_HWSendPacket(struct xennet_info *
    5.46    parse_result = XenNet_ParsePacketHeader(&pi);  
    5.47    //KdPrint((__DRIVER_NAME "     B\n"));
    5.48  
    5.49 +  if (pi.header && *((PUCHAR)pi.header + 12) != 0x08)
    5.50 +    KdPrint((__DRIVER_NAME "     %02x %02x\n", (int)*((PUCHAR)pi.header + 12), (int)*((PUCHAR)pi.header + 13)));
    5.51 +
    5.52    if (NDIS_GET_PACKET_PROTOCOL_TYPE(packet) == NDIS_PROTOCOL_ID_TCP_IP)
    5.53    {
    5.54      csum_info = (PNDIS_TCP_IP_CHECKSUM_PACKET_INFO)&NDIS_PER_PACKET_INFO_FROM_PACKET(
    5.55 @@ -170,7 +185,6 @@ XenNet_HWSendPacket(struct xennet_info *
    5.56  
    5.57    if (ndis_lso || (pi.header_length && pi.header_length > sg->Elements[sg_element].Length && pi.header == pi.header_data))
    5.58    {
    5.59 -    // why is a hb being used for icmp???
    5.60      header_buf = get_hb_from_freelist(xi);
    5.61      if (!header_buf)
    5.62      {
    5.63 @@ -209,6 +223,8 @@ XenNet_HWSendPacket(struct xennet_info *
    5.64    /* (A) */
    5.65  // if we coalesced the header then we want to put that on first, otherwise we put on the first sg element
    5.66    tx0 = RING_GET_REQUEST(&xi->tx, xi->tx.req_prod_pvt);
    5.67 +  chunks++;
    5.68 +  xi->tx_ring_free--;
    5.69    tx0->id = 0xFFFF;
    5.70    if (header_buf)
    5.71    {
    5.72 @@ -217,7 +233,10 @@ XenNet_HWSendPacket(struct xennet_info *
    5.73      //KdPrint((__DRIVER_NAME "     D - header_length = %d\n", pi.header_length));
    5.74      memcpy(header_buf->virtual, pi.header, pi.header_length);
    5.75      /* even though we haven't reported that we are capable of it, LSO demands that we calculate the IP Header checksum */
    5.76 -    XenNet_SumIpHeader(header_buf->virtual, pi.ip4_header_length);
    5.77 +    if (ndis_lso)
    5.78 +    {
    5.79 +      XenNet_SumIpHeader(header_buf->virtual, pi.ip4_header_length);
    5.80 +    }
    5.81      tx0->gref = (grant_ref_t)(header_buf->logical.QuadPart >> PAGE_SHIFT);
    5.82      tx0->offset = (USHORT)header_buf->logical.LowPart & (PAGE_SIZE - 1);
    5.83      tx0->size = (USHORT)pi.header_length;
    5.84 @@ -259,8 +278,11 @@ XenNet_HWSendPacket(struct xennet_info *
    5.85    /* (B) */
    5.86    if (xen_gso)
    5.87    {
    5.88 +    //KdPrint((__DRIVER_NAME "     Using extra_info\n"));
    5.89      ASSERT(flags & NETTXF_extra_info);
    5.90      ei = (struct netif_extra_info *)RING_GET_REQUEST(&xi->tx, xi->tx.req_prod_pvt);
    5.91 +    chunks++;
    5.92 +    xi->tx_ring_free--;
    5.93      ei->type = XEN_NETIF_EXTRA_TYPE_GSO;
    5.94      ei->flags = 0;
    5.95      ei->u.gso.size = (USHORT)mss;
    5.96 @@ -278,21 +300,27 @@ XenNet_HWSendPacket(struct xennet_info *
    5.97      //KdPrint((__DRIVER_NAME "     H - address = %p, length = %d\n",
    5.98      //  sg->Elements[sg_element].Address.LowPart + sg_offset, sg->Elements[sg_element].Length - sg_offset));
    5.99      txN = RING_GET_REQUEST(&xi->tx, xi->tx.req_prod_pvt);
   5.100 +    xi->tx_ring_free--;
   5.101      txN->id = 0xFFFF;
   5.102      txN->gref = (grant_ref_t)(sg->Elements[sg_element].Address.QuadPart >> PAGE_SHIFT);
   5.103 +    ASSERT((sg->Elements[sg_element].Address.LowPart & (PAGE_SIZE - 1)) + sg_offset <= PAGE_SIZE);
   5.104      txN->offset = (USHORT)(sg->Elements[sg_element].Address.LowPart + sg_offset) & (PAGE_SIZE - 1);
   5.105 +    ASSERT(sg->Elements[sg_element].Length > sg_offset);
   5.106      txN->size = (USHORT)(sg->Elements[sg_element].Length - sg_offset);
   5.107      ASSERT(txN->offset + txN->size <= PAGE_SIZE);
   5.108      ASSERT(txN->size);
   5.109      tx0->size = tx0->size + txN->size;
   5.110      txN->flags = NETTXF_more_data;
   5.111 +    sg_offset = 0;
   5.112      sg_element++;
   5.113 -    sg_offset = 0;
   5.114      xi->tx.req_prod_pvt++;
   5.115    }
   5.116    txN->flags &= ~NETTXF_more_data;
   5.117    txN->id = get_id_from_freelist(xi);
   5.118  //KdPrint((__DRIVER_NAME "     send - id = %d\n", tx0->id));
   5.119 +  //KdPrint((__DRIVER_NAME "     TX: id = %d, hb = %p, xi->tx_shadows[txN->id].hb = %p\n", txN->id, header_buf, xi->tx_shadows[txN->id].hb));
   5.120 +  ASSERT(!xi->tx_shadows[txN->id].hb);
   5.121 +  ASSERT(!xi->tx_shadows[txN->id].packet);
   5.122    xi->tx_shadows[txN->id].packet = packet;
   5.123    xi->tx_shadows[txN->id].hb = header_buf;
   5.124  
   5.125 @@ -302,6 +330,10 @@ XenNet_HWSendPacket(struct xennet_info *
   5.126      NDIS_PER_PACKET_INFO_FROM_PACKET(packet, TcpLargeSendPacketInfo) = UlongToPtr(pi.tcp_length);
   5.127    }
   5.128  
   5.129 +  if (chunks > 12)
   5.130 +  {
   5.131 +    KdPrint((__DRIVER_NAME "     chunks = %d\n", chunks));
   5.132 +  }
   5.133    xi->stat_tx_ok++;
   5.134  
   5.135    //NDIS_SET_PACKET_STATUS(packet, NDIS_STATUS_SUCCESS);
   5.136 @@ -375,9 +407,13 @@ XenNet_TxBufferGC(PKDPC dpc, PVOID conte
   5.137      {
   5.138        struct netif_tx_response *txrsp;
   5.139        txrsp = RING_GET_RESPONSE(&xi->tx, cons);
   5.140 +      
   5.141 +      xi->tx_ring_free++;
   5.142 +      
   5.143        if (txrsp->status == NETIF_RSP_NULL || txrsp->id == 0xFFFF)
   5.144          continue;
   5.145  
   5.146 +      //KdPrint((__DRIVER_NAME "     GC: id = %d, hb = %p\n", txrsp->id, xi->tx_shadows[txrsp->id].hb));
   5.147        if (xi->tx_shadows[txrsp->id].hb)
   5.148        {
   5.149          put_hb_on_freelist(xi, xi->tx_shadows[txrsp->id].hb);