win-pvdrivers

changeset 32:d5df0038627d

xennet: rough-in sendPackets

currently allocates an extra page per packet
not seeing interrupts, why not?
updated copyright notices with my work email address
author Andy Grover <andy.grover@oracle.com>
date Tue Dec 04 17:29:26 2007 -0800 (2007-12-04)
parents f56c47274c37
children b0870e38eaab
files xennet/xennet.c xennet/xennet.h
line diff
     1.1 --- a/xennet/xennet.c	Mon Dec 03 23:05:02 2007 -0800
     1.2 +++ b/xennet/xennet.c	Tue Dec 04 17:29:26 2007 -0800
     1.3 @@ -1,7 +1,7 @@
     1.4  /*
     1.5  PV Net Driver for Windows Xen HVM Domains
     1.6  Copyright (C) 2007 James Harper
     1.7 -Copyright (C) 2007 Andrew Grover
     1.8 +Copyright (C) 2007 Andrew Grover <andy.grover@oracle.com>
     1.9  
    1.10  This program is free software; you can redistribute it and/or
    1.11  modify it under the terms of the GNU General Public License
    1.12 @@ -22,6 +22,9 @@ Foundation, Inc., 51 Franklin Street, Fi
    1.13  #include <io/xenbus.h>
    1.14  #include "xennet.h"
    1.15  
    1.16 +#define wmb() KeMemoryBarrier()
    1.17 +#define mb() KeMemoryBarrier()
    1.18 +
    1.19  #if !defined (NDIS51_MINIPORT)
    1.20  #error requires NDIS 5.1 compilation environment
    1.21  #endif
    1.22 @@ -37,7 +40,7 @@ Foundation, Inc., 51 Franklin Street, Fi
    1.23  #define NET_TX_RING_SIZE __NET_RING_SIZE(netif_tx, PAGE_SIZE)
    1.24  #define NET_RX_RING_SIZE __NET_RING_SIZE(netif_rx, PAGE_SIZE)
    1.25  
    1.26 -#pragma warning(disable: 4127)
    1.27 +#pragma warning(disable: 4127) // conditional expression is constant
    1.28  
    1.29  struct xennet_info
    1.30  {
    1.31 @@ -172,7 +175,8 @@ AllocatePage()
    1.32  static NDIS_STATUS
    1.33  XenNet_TxBufGC(struct xennet_info *xi)
    1.34  {
    1.35 -  RING_IDX cons, prod;
    1.36 +//  RING_IDX cons, prod;
    1.37 +  UNREFERENCED_PARAMETER(xi);
    1.38  #if 0
    1.39    unsigned short id;
    1.40    struct sk_buff *skb;
    1.41 @@ -244,6 +248,8 @@ XenNet_Interrupt(
    1.42  
    1.43    UNREFERENCED_PARAMETER(Interrupt);
    1.44  
    1.45 +  KdPrint((__DRIVER_NAME "     ***XenNet Interrupt***\n"));  
    1.46 +
    1.47    if (xi->connected)
    1.48    {
    1.49      XenNet_TxBufGC(xi);
    1.50 @@ -269,6 +275,22 @@ XenNet_BackEndStateHandler(char *Path, P
    1.51    xenbus_transaction_t xbt = 0;
    1.52    int retry = 0;
    1.53    char *err;
    1.54 +  int i;
    1.55 +
    1.56 +  struct set_params {
    1.57 +    char *name;
    1.58 +    int value;
    1.59 +  } params[] = {
    1.60 +    {"tx-ring-ref", 0},
    1.61 +    {"rx-ring-ref", 0},
    1.62 +    {"event-channel", 0},
    1.63 +    {"request-rx-copy", 1},
    1.64 +    {"feature-rx-notify", 1},
    1.65 +    {"feature-no-csum-offload", 1},
    1.66 +    {"feature-sg", 1},
    1.67 +    {"feature-gso-tcpv4", 0},
    1.68 +    {NULL, 0},
    1.69 +  };
    1.70  
    1.71    xi->XenBusInterface.Read(xi->XenBusInterface.InterfaceHeader.Context,
    1.72      XBT_NIL, Path, &Value);
    1.73 @@ -313,60 +335,26 @@ XenNet_BackEndStateHandler(char *Path, P
    1.74        xi->GntTblInterface.InterfaceHeader.Context, 0,
    1.75        *MmGetMdlPfnArray(xi->rx_mdl), FALSE);
    1.76  
    1.77 -    xi->XenBusInterface.StartTransaction(xi->XenBusInterface.InterfaceHeader.Context,
    1.78 -      &xbt);
    1.79 -
    1.80 -    RtlStringCbPrintfA(TmpPath, ARRAY_SIZE(TmpPath), "%s/tx-ring-ref", xi->Path);
    1.81 -    err = xi->XenBusInterface.Printf(xi->XenBusInterface.InterfaceHeader.Context,
    1.82 -      XBT_NIL, TmpPath, "%d", xi->tx_ring_ref);
    1.83 -    if (err)
    1.84 -      goto trouble;
    1.85 -
    1.86 -    RtlStringCbPrintfA(TmpPath, ARRAY_SIZE(TmpPath), "%s/rx-ring-ref", xi->Path);
    1.87 -    err = xi->XenBusInterface.Printf(xi->XenBusInterface.InterfaceHeader.Context,
    1.88 -      XBT_NIL, TmpPath, "%d", xi->rx_ring_ref);
    1.89 -    if (err)
    1.90 -      goto trouble;
    1.91 -
    1.92 -    RtlStringCbPrintfA(TmpPath, ARRAY_SIZE(TmpPath), "%s/event-channel", xi->Path);
    1.93 -    err = xi->XenBusInterface.Printf(xi->XenBusInterface.InterfaceHeader.Context,
    1.94 -      XBT_NIL, TmpPath, "%d", xi->event_channel);
    1.95 -    if (err)
    1.96 -      goto trouble;
    1.97 -
    1.98 -    RtlStringCbPrintfA(TmpPath, ARRAY_SIZE(TmpPath), "%s/request-rx-copy", xi->Path);
    1.99 -    err = xi->XenBusInterface.Printf(xi->XenBusInterface.InterfaceHeader.Context,
   1.100 -      XBT_NIL, TmpPath, "%d", 1);
   1.101 -    if (err)
   1.102 -      goto trouble;
   1.103 +    /* fixup array for dynamic values */
   1.104 +    params[0].value = xi->tx_ring_ref;
   1.105 +    params[1].value = xi->rx_ring_ref;
   1.106 +    params[2].value = xi->event_channel;
   1.107  
   1.108 -    RtlStringCbPrintfA(TmpPath, ARRAY_SIZE(TmpPath), "%s/feature-rx-notify",
   1.109 -      xi->Path);
   1.110 -    err = xi->XenBusInterface.Printf(xi->XenBusInterface.InterfaceHeader.Context,
   1.111 -      XBT_NIL, TmpPath, "%d", 1);
   1.112 -    if (err)
   1.113 -      goto trouble;
   1.114 +    xi->XenBusInterface.StartTransaction(
   1.115 +      xi->XenBusInterface.InterfaceHeader.Context, &xbt);
   1.116  
   1.117 -    RtlStringCbPrintfA(TmpPath, ARRAY_SIZE(TmpPath),
   1.118 -      "%s/feature-no-csum-offload", xi->Path);
   1.119 -    err = xi->XenBusInterface.Printf(xi->XenBusInterface.InterfaceHeader.Context,
   1.120 -      XBT_NIL, TmpPath, "%d", 1);
   1.121 -    if (err)
   1.122 -      goto trouble;
   1.123 -
   1.124 -    RtlStringCbPrintfA(TmpPath, ARRAY_SIZE(TmpPath),
   1.125 -      "%s/feature-sg", xi->Path);
   1.126 -    err = xi->XenBusInterface.Printf(xi->XenBusInterface.InterfaceHeader.Context,
   1.127 -      XBT_NIL, TmpPath, "%d", 0);
   1.128 -    if (err)
   1.129 -      goto trouble;
   1.130 -
   1.131 -    RtlStringCbPrintfA(TmpPath, ARRAY_SIZE(TmpPath),
   1.132 -      "%s/feature-gso-tcpv4", xi->Path);
   1.133 -    err = xi->XenBusInterface.Printf(xi->XenBusInterface.InterfaceHeader.Context,
   1.134 -      XBT_NIL, TmpPath, "%d", 0);
   1.135 -    if (err)
   1.136 -      goto trouble;
   1.137 +    for (i = 0; params[i].name; i++)
   1.138 +    {
   1.139 +      RtlStringCbPrintfA(TmpPath, ARRAY_SIZE(TmpPath), "%s/%s",
   1.140 +        xi->Path, params[i].name);
   1.141 +      err = xi->XenBusInterface.Printf(xi->XenBusInterface.InterfaceHeader.Context,
   1.142 +        XBT_NIL, TmpPath, "%d", params[i].value);
   1.143 +      if (err)
   1.144 +      {
   1.145 +        KdPrint(("setting %s failed, err = %s\n", params[i].name, err));
   1.146 +        goto trouble;
   1.147 +      }
   1.148 +    }
   1.149  
   1.150      /* commit transaction */
   1.151      xi->XenBusInterface.EndTransaction(xi->XenBusInterface.InterfaceHeader.Context,
   1.152 @@ -411,6 +399,8 @@ XenNet_BackEndStateHandler(char *Path, P
   1.153      break;
   1.154    }
   1.155  
   1.156 +  return;
   1.157 +
   1.158  trouble:
   1.159    KdPrint((__DRIVER_NAME __FUNCTION__ ": Should never happen!\n"));
   1.160    xi->XenBusInterface.EndTransaction(xi->XenBusInterface.InterfaceHeader.Context,
   1.161 @@ -503,7 +493,17 @@ XenNet_Init(
   1.162    }
   1.163  
   1.164    NdisMSetAttributesEx(xi->adapter_handle, (NDIS_HANDLE) xi,
   1.165 -      0, NDIS_ATTRIBUTE_DESERIALIZE, NdisInterfaceInternal);
   1.166 +    0, (NDIS_ATTRIBUTE_DESERIALIZE /*| NDIS_ATTRIBUTE_BUS_MASTER*/),
   1.167 +    NdisInterfaceInternal);
   1.168 +
   1.169 +  // status = NdisMInitializeScatterGatherDma(xi->adapter_handle, TRUE,
   1.170 +    // XN_MAX_PKT_SIZE);
   1.171 +  // if (!NT_SUCCESS(status))
   1.172 +  // {
   1.173 +    // KdPrint(("NdisMInitializeScatterGatherDma failed with 0x%x\n", status));
   1.174 +    // status = NDIS_STATUS_FAILURE;
   1.175 +    // goto err;
   1.176 +  // }
   1.177  
   1.178    WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&wdf_attrs, wdf_device_info);
   1.179  
   1.180 @@ -516,9 +516,6 @@ XenNet_Init(
   1.181      goto err;
   1.182    }
   1.183  
   1.184 -  /* TODO: NdisMInitializeScatterGatherDma? */
   1.185 -  // NDIS_PER_PACKET_INFO_FROM_PACKET(ndis_packet, ScatterGatherListPacketInfo)
   1.186 -
   1.187    GetWdfDeviceInfo(xi->wdf_device)->xennet_info = xi;
   1.188  
   1.189    /* get lower (Xen) interfaces */
   1.190 @@ -834,6 +831,39 @@ XenNet_ReturnPacket(
   1.191    KdPrint((__FUNCTION__ " called\n"));
   1.192  }
   1.193  
   1.194 +PMDL
   1.195 +XenNet_Linearize(PNDIS_PACKET Packet)
   1.196 +{
   1.197 +  PMDL pmdl;
   1.198 +  char *start;
   1.199 +  PNDIS_BUFFER buffer;
   1.200 +  PVOID buff_va;
   1.201 +  UINT buff_len;
   1.202 +  UINT tot_buff_len;
   1.203 +
   1.204 +  pmdl = AllocatePage();
   1.205 +
   1.206 +  start = MmGetSystemAddressForMdlSafe(pmdl, NormalPagePriority);
   1.207 +  if (!start)
   1.208 +  {
   1.209 +    return NULL;
   1.210 +  }
   1.211 +
   1.212 +  NdisGetFirstBufferFromPacketSafe(Packet, &buffer, &buff_va, &buff_len,
   1.213 +    &tot_buff_len, NormalPagePriority);
   1.214 +  ASSERT(tot_buff_len <= PAGE_SIZE);
   1.215 +
   1.216 +  while (buffer)
   1.217 +  {
   1.218 +    NdisQueryBufferSafe(buffer, &buff_va, &buff_len, NormalPagePriority);
   1.219 +    RtlCopyMemory(start, buff_va, buff_len);
   1.220 +    start += buff_len;
   1.221 +    NdisGetNextBuffer(buffer, &buffer);
   1.222 +  }
   1.223 +
   1.224 +  return pmdl;
   1.225 +}
   1.226 +
   1.227  VOID
   1.228  XenNet_SendPackets(
   1.229    IN NDIS_HANDLE MiniportAdapterContext,
   1.230 @@ -856,14 +886,13 @@ XenNet_SendPackets(
   1.231      */
   1.232    struct xennet_info *xi = MiniportAdapterContext;
   1.233    PNDIS_PACKET curr_packet;
   1.234 -  PNDIS_BUFFER curr_buff;
   1.235 -  PVOID curr_buff_vaddr;
   1.236 -  UINT curr_buff_len;
   1.237 -  UINT tot_buff_len;
   1.238    UINT i;
   1.239    struct netif_tx_request *tx;
   1.240    unsigned short id;
   1.241 -  grant_ref_t ref;
   1.242 +  PFN_NUMBER pfn;
   1.243 +  int notify;
   1.244 +  PMDL pmdl;
   1.245 +  UINT pkt_size;
   1.246  
   1.247    KdPrint((__FUNCTION__ " called, sending %d pkts\n", NumberOfPackets));
   1.248  
   1.249 @@ -872,33 +901,44 @@ XenNet_SendPackets(
   1.250      curr_packet = PacketArray[i];
   1.251      ASSERT(curr_packet);
   1.252  
   1.253 -    NdisGetFirstBufferFromPacketSafe(curr_packet, &curr_buff, &curr_buff_vaddr,
   1.254 -      &curr_buff_len, &tot_buff_len, NormalPagePriority);
   1.255 -
   1.256 -    while (curr_buff)
   1.257 -    {
   1.258 -      NdisQueryBufferSafe(curr_buff, &curr_buff_vaddr, &curr_buff_len,
   1.259 -        NormalPagePriority);
   1.260 -
   1.261 -      id = get_id_from_freelist(xi->tx_pkts);
   1.262 -      xi->tx_pkts[id] = curr_packet;
   1.263 +    NdisQueryPacket(curr_packet, NULL, NULL, NULL, &pkt_size);
   1.264  
   1.265 -      // TODO: get pfn/offset for buffer
   1.266 -      // buffers attached to packets with NdisChainBufferAtBack
   1.267 +    pmdl = XenNet_Linearize(curr_packet);
   1.268 +    if (!pmdl)
   1.269 +    {
   1.270 +      KdPrint((__DRIVER_NAME "Couldn't linearize packet!\n"));
   1.271 +      NdisMSendComplete(xi, curr_packet, NDIS_STATUS_FAILURE);
   1.272 +      break;
   1.273 +    }
   1.274 +    pfn = *MmGetMdlPfnArray(pmdl);
   1.275  
   1.276 -      tx = RING_GET_REQUEST(&xi->tx, xi->tx.req_prod_pvt);
   1.277 -      tx->id = id;
   1.278 -      tx->gref = xi->GntTblInterface.GrantAccess(
   1.279 -        xi->GntTblInterface.InterfaceHeader.Context,
   1.280 -        0,
   1.281 -        0, //FIXME
   1.282 -        FALSE);
   1.283 +    id = get_id_from_freelist(xi->tx_pkts);
   1.284 +    *((PMDL *)curr_packet->MiniportReservedEx) = pmdl;
   1.285 +    xi->tx_pkts[id] = curr_packet;
   1.286  
   1.287 +    tx = RING_GET_REQUEST(&xi->tx, xi->tx.req_prod_pvt);
   1.288 +    tx->id = id;
   1.289 +    tx->gref = xi->GntTblInterface.GrantAccess(
   1.290 +      xi->GntTblInterface.InterfaceHeader.Context,
   1.291 +      0,
   1.292 +      pfn,
   1.293 +      TRUE);
   1.294 +    tx->offset = 0;
   1.295 +    tx->size = (UINT16)pkt_size;
   1.296 +    tx->flags = NETTXF_csum_blank;
   1.297  
   1.298 -      NdisGetNextBuffer(curr_buff, &curr_buff);
   1.299 -    }
   1.300 +    xi->tx.req_prod_pvt++;
   1.301 +
   1.302 +    // NDIS_SET_PACKET_STATUS(curr_packet, NDIS_STATUS_SUCCESS);
   1.303 +    // NdisMSendComplete(xi, curr_packet, NDIS_STATUS_SUCCESS);
   1.304    }
   1.305  
   1.306 +  RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&xi->tx, notify);
   1.307 +  if (notify)
   1.308 +  {
   1.309 +    xi->EvtChnInterface.Notify(xi->EvtChnInterface.InterfaceHeader.Context,
   1.310 +      xi->event_channel);
   1.311 +  }
   1.312  }
   1.313  
   1.314  VOID
     2.1 --- a/xennet/xennet.h	Mon Dec 03 23:05:02 2007 -0800
     2.2 +++ b/xennet/xennet.h	Tue Dec 04 17:29:26 2007 -0800
     2.3 @@ -1,7 +1,7 @@
     2.4  /*
     2.5  PV Drivers for Windows Xen HVM Domains
     2.6  Copyright (C) 2007 James Harper
     2.7 -Copyright (C) 2007 Andrew Grover
     2.8 +Copyright (C) 2007 Andrew Grover <andy.grover@oracle.com>
     2.9  
    2.10  This program is free software; you can redistribute it and/or
    2.11  modify it under the terms of the GNU General Public License