[BACK]Return to if_xennet_xenbus.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / arch / xen / xen

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/sys/arch/xen/xen/if_xennet_xenbus.c between version 1.3 and 1.3.4.7

version 1.3, 2006/03/06 22:10:28 version 1.3.4.7, 2006/08/11 15:43:16
Line 66  __KERNEL_RCSID(0, "$NetBSD$");
Line 66  __KERNEL_RCSID(0, "$NetBSD$");
 #include "opt_xen.h"  #include "opt_xen.h"
 #include "opt_nfs_boot.h"  #include "opt_nfs_boot.h"
 #include "rnd.h"  #include "rnd.h"
   #include "bpfilter.h"
   
 #include <sys/param.h>  #include <sys/param.h>
 #include <sys/device.h>  #include <sys/device.h>
Line 79  __KERNEL_RCSID(0, "$NetBSD$");
Line 80  __KERNEL_RCSID(0, "$NetBSD$");
 #include <net/if.h>  #include <net/if.h>
 #include <net/if_dl.h>  #include <net/if_dl.h>
 #include <net/if_ether.h>  #include <net/if_ether.h>
   #if NBPFILTER > 0
   #include <net/bpf.h>
   #include <net/bpfdesc.h>
   #endif
   
 #if defined(NFS_BOOT_BOOTSTATIC)  #if defined(NFS_BOOT_BOOTSTATIC)
 #include <sys/fstypes.h>  #include <sys/fstypes.h>
Line 93  __KERNEL_RCSID(0, "$NetBSD$");
Line 98  __KERNEL_RCSID(0, "$NetBSD$");
 #include <machine/if_xennetvar.h>  #include <machine/if_xennetvar.h>
 #endif /* defined(NFS_BOOT_BOOTSTATIC) */  #endif /* defined(NFS_BOOT_BOOTSTATIC) */
   
   #include <machine/xennet_checksum.h>
   
 #include <uvm/uvm.h>  #include <uvm/uvm.h>
   
 #include <machine/xen3-public/io/ring.h>  #include <machine/xen3-public/io/ring.h>
Line 117  int xennet_debug = 0xff;
Line 124  int xennet_debug = 0xff;
 #define DPRINTFN(n,x)  #define DPRINTFN(n,x)
 #endif  #endif
   
 #define GRANT_INVALID_REF -1  #define GRANT_INVALID_REF -1 /* entry is free */
   #define GRANT_STACK_REF   -2 /* entry owned by the network stack */
   
 #define NET_TX_RING_SIZE __RING_SIZE((netif_tx_sring_t *)0, PAGE_SIZE)  #define NET_TX_RING_SIZE __RING_SIZE((netif_tx_sring_t *)0, PAGE_SIZE)
 #define NET_RX_RING_SIZE __RING_SIZE((netif_rx_sring_t *)0, PAGE_SIZE)  #define NET_RX_RING_SIZE __RING_SIZE((netif_rx_sring_t *)0, PAGE_SIZE)
Line 175  static paddr_t xennet_pages[NET_RX_RING_
Line 183  static paddr_t xennet_pages[NET_RX_RING_
   
 static int  xennet_xenbus_match(struct device *, struct cfdata *, void *);  static int  xennet_xenbus_match(struct device *, struct cfdata *, void *);
 static void xennet_xenbus_attach(struct device *, struct device *, void *);  static void xennet_xenbus_attach(struct device *, struct device *, void *);
   static int  xennet_xenbus_detach(struct device *, int);
   static void xennet_backend_changed(void *, XenbusState);
   
 static int  xennet_xenbus_resume(void *);  static int  xennet_xenbus_resume(void *);
 static void xennet_alloc_rx_buffer(struct xennet_xenbus_softc *);  static void xennet_alloc_rx_buffer(struct xennet_xenbus_softc *);
   static void xennet_free_rx_buffer(struct xennet_xenbus_softc *);
 static void xennet_tx_complete(struct xennet_xenbus_softc *);  static void xennet_tx_complete(struct xennet_xenbus_softc *);
 static void xennet_rx_mbuf_free(struct mbuf *, caddr_t, size_t, void *);  static void xennet_rx_mbuf_free(struct mbuf *, caddr_t, size_t, void *);
 static int  xennet_handler(void *);  static int  xennet_handler(void *);
Line 194  static int  xennet_ioctl(struct ifnet *,
Line 205  static int  xennet_ioctl(struct ifnet *,
 static void xennet_watchdog(struct ifnet *);  static void xennet_watchdog(struct ifnet *);
   
 CFATTACH_DECL(xennet_xenbus, sizeof(struct xennet_xenbus_softc),  CFATTACH_DECL(xennet_xenbus, sizeof(struct xennet_xenbus_softc),
    xennet_xenbus_match, xennet_xenbus_attach, NULL, NULL);     xennet_xenbus_match, xennet_xenbus_attach, xennet_xenbus_detach, NULL);
   
 static int  static int
 xennet_xenbus_match(struct device *parent, struct cfdata *match, void *aux)  xennet_xenbus_match(struct device *parent, struct cfdata *match, void *aux)
Line 222  xennet_xenbus_attach(struct device *pare
Line 233  xennet_xenbus_attach(struct device *pare
         char *val, *e, *p;          char *val, *e, *p;
         int s;          int s;
         extern int ifqmaxlen; /* XXX */          extern int ifqmaxlen; /* XXX */
   #ifdef XENNET_DEBUG
           char **dir;
           int dir_n = 0;
           char id_str[20];
   #endif
   
         aprint_normal(": Xen Virtual Network Interface\n");          aprint_normal(": Xen Virtual Network Interface\n");
   #ifdef XENNET_DEBUG
           printf("path: %s\n", xa->xa_xbusd->xbusd_path);
           snprintf(id_str, sizeof(id_str), "%d", xa->xa_id);
           err = xenbus_directory(NULL, "device/vif", id_str, &dir_n, &dir);
           if (err) {
                   printf("%s: xenbus_directory err %d\n",
                       sc->sc_dev.dv_xname, err);
           } else {
                   printf("%s/\n", xa->xa_xbusd->xbusd_path);
                   for (i = 0; i < dir_n; i++) {
                           printf("\t/%s", dir[i]);
                           err = xenbus_read(NULL, xa->xa_xbusd->xbusd_path, dir[i],
                               NULL, &val);
                           if (err) {
                                   printf("%s: xenbus_read err %d\n",
                                   sc->sc_dev.dv_xname, err);
                           } else {
                                   printf(" = %s\n", val);
                                   free(val, M_DEVBUF);
                           }
                   }
           }
   #endif /* XENNET_DEBUG */
         sc->sc_xbusd = xa->xa_xbusd;          sc->sc_xbusd = xa->xa_xbusd;
           sc->sc_xbusd->xbusd_otherend_changed = xennet_backend_changed;
   
         /* initialize free RX and RX request lists */          /* initialize free RX and RX request lists */
         SLIST_INIT(&sc->sc_txreq_head);          SLIST_INIT(&sc->sc_txreq_head);
         for (i = 0; i < NET_TX_RING_SIZE; i++) {          for (i = 0; i < NET_TX_RING_SIZE; i++) {
Line 245  xennet_xenbus_attach(struct device *pare
Line 286  xennet_xenbus_attach(struct device *pare
                 if (!pmap_extract(pmap_kernel(), rxreq->rxreq_va,                  if (!pmap_extract(pmap_kernel(), rxreq->rxreq_va,
                     &rxreq->rxreq_pa))                      &rxreq->rxreq_pa))
                         panic("xennet: no pa for mapped va ?");                          panic("xennet: no pa for mapped va ?");
                   rxreq->rxreq_gntref = GRANT_INVALID_REF;
                 SLIST_INSERT_HEAD(&sc->sc_rxreq_head, rxreq, rxreq_next);                  SLIST_INSERT_HEAD(&sc->sc_rxreq_head, rxreq, rxreq_next);
         }          }
         splx(s);          splx(s);
Line 288  xennet_xenbus_attach(struct device *pare
Line 329  xennet_xenbus_attach(struct device *pare
         ifp->if_flags = IFF_BROADCAST|IFF_SIMPLEX|IFF_NOTRAILERS|IFF_MULTICAST;          ifp->if_flags = IFF_BROADCAST|IFF_SIMPLEX|IFF_NOTRAILERS|IFF_MULTICAST;
         ifp->if_timer = 0;          ifp->if_timer = 0;
         ifp->if_snd.ifq_maxlen = max(ifqmaxlen, NET_TX_RING_SIZE * 2);          ifp->if_snd.ifq_maxlen = max(ifqmaxlen, NET_TX_RING_SIZE * 2);
           ifp->if_capabilities = IFCAP_CSUM_TCPv4_Tx | IFCAP_CSUM_UDPv4_Tx;
         IFQ_SET_READY(&ifp->if_snd);          IFQ_SET_READY(&ifp->if_snd);
         if_attach(ifp);          if_attach(ifp);
         ether_ifattach(ifp, sc->sc_enaddr);          ether_ifattach(ifp, sc->sc_enaddr);
Line 300  xennet_xenbus_attach(struct device *pare
Line 342  xennet_xenbus_attach(struct device *pare
 }  }
   
 static int  static int
   xennet_xenbus_detach(struct device *self, int flags)
   {
           struct xennet_xenbus_softc *sc = (void *)self;
           struct ifnet *ifp = &sc->sc_ethercom.ec_if;
           int s0, s1;
           RING_IDX i;
   
           DPRINTF(("%s: xennet_xenbus_detach\n", sc->sc_dev.dv_xname));
           s0 = splnet();
           xennet_stop(ifp, 1);
           /* wait for pending TX to complete, and collect pending RX packets */
           xennet_handler(sc);
           while (sc->sc_tx_ring.sring->rsp_prod != sc->sc_tx_ring.rsp_cons) {
                   tsleep(xennet_xenbus_detach, PRIBIO, "xnet_detach", hz/2);
                   xennet_handler(sc);
           }
           xennet_free_rx_buffer(sc);
   
           s1 = splvm();
           for (i = 0; i < NET_RX_RING_SIZE; i++) {
                   struct xennet_rxreq *rxreq = &sc->sc_rxreqs[i];
                   uvm_km_free(kernel_map, rxreq->rxreq_va, PAGE_SIZE,
                       UVM_KMF_WIRED);
           }
           splx(s1);
   
           ether_ifdetach(ifp);
           if_detach(ifp);
           while (xengnt_status(sc->sc_tx_ring_gntref)) {
                   tsleep(xennet_xenbus_detach, PRIBIO, "xnet_txref", hz/2);
           }
           xengnt_revoke_access(sc->sc_tx_ring_gntref);
           uvm_km_free(kernel_map, (vaddr_t)sc->sc_tx_ring.sring, PAGE_SIZE,
               UVM_KMF_WIRED);
           while (xengnt_status(sc->sc_rx_ring_gntref)) {
                   tsleep(xennet_xenbus_detach, PRIBIO, "xnet_rxref", hz/2);
           }
           xengnt_revoke_access(sc->sc_rx_ring_gntref);
           uvm_km_free(kernel_map, (vaddr_t)sc->sc_rx_ring.sring, PAGE_SIZE,
               UVM_KMF_WIRED);
           softintr_disestablish(sc->sc_softintr);
           event_remove_handler(sc->sc_evtchn, &xennet_handler, sc);
           splx(s0);
           DPRINTF(("%s: xennet_xenbus_detach done\n", sc->sc_dev.dv_xname));
           return 0;
   }
   
   static int
 xennet_xenbus_resume(void *p)  xennet_xenbus_resume(void *p)
 {  {
         struct xennet_xenbus_softc *sc = p;          struct xennet_xenbus_softc *sc = p;
Line 378  again:
Line 468  again:
                 xenbus_dev_fatal(sc->sc_xbusd, error, "completing transaction");                  xenbus_dev_fatal(sc->sc_xbusd, error, "completing transaction");
                 return -1;                  return -1;
         }          }
           xennet_alloc_rx_buffer(sc);
         sc->sc_backend_status = BEST_CONNECTED;          sc->sc_backend_status = BEST_CONNECTED;
         return 0;          return 0;
   
Line 387  abort_transaction:
Line 478  abort_transaction:
         return error;          return error;
 }  }
   
   static void xennet_backend_changed(void *arg, XenbusState new_state)
   {
           struct xennet_xenbus_softc *sc = arg;
           DPRINTF(("%s: new backend state %d\n", sc->sc_dev.dv_xname, new_state));
   
           switch (new_state) {
           case XenbusStateInitialising:
           case XenbusStateInitWait:
           case XenbusStateInitialised:
                   break;
           case XenbusStateClosing:
                   sc->sc_backend_status = BEST_CLOSED;
                   xenbus_switch_state(sc->sc_xbusd, NULL, XenbusStateClosed);
                   break;
           case XenbusStateConnected:
                   break;
           case XenbusStateUnknown:
           default:
                   panic("bad backend state %d", new_state);
           }
   }
   
 static void  static void
 xennet_alloc_rx_buffer(struct xennet_xenbus_softc *sc)  xennet_alloc_rx_buffer(struct xennet_xenbus_softc *sc)
 {  {
Line 401  xennet_alloc_rx_buffer(struct xennet_xen
Line 514  xennet_alloc_rx_buffer(struct xennet_xen
         for (i = 0; sc->sc_free_rxreql != 0; i++) {          for (i = 0; sc->sc_free_rxreql != 0; i++) {
                 req  = SLIST_FIRST(&sc->sc_rxreq_head);                  req  = SLIST_FIRST(&sc->sc_rxreq_head);
                 KASSERT(req != NULL);                  KASSERT(req != NULL);
                   KASSERT(req == &sc->sc_rxreqs[req->rxreq_id]);
                 RING_GET_REQUEST(&sc->sc_rx_ring, req_prod + i)->id =                  RING_GET_REQUEST(&sc->sc_rx_ring, req_prod + i)->id =
                     req->rxreq_id;                      req->rxreq_id;
                 if (xengnt_grant_transfer(sc->sc_xbusd->xbusd_otherend_id,                  if (xengnt_grant_transfer(sc->sc_xbusd->xbusd_otherend_id,
Line 458  xennet_alloc_rx_buffer(struct xennet_xen
Line 572  xennet_alloc_rx_buffer(struct xennet_xen
 }  }
   
 static void  static void
   xennet_free_rx_buffer(struct xennet_xenbus_softc *sc)
   {
           paddr_t ma, pa;
           vaddr_t va;
           RING_IDX i;
           mmu_update_t mmu[1];
           multicall_entry_t mcl[2];
   
           int s = splbio();
   
           DPRINTF(("%s: xennet_free_rx_buffer\n", sc->sc_dev.dv_xname));
           /* get back memory from RX ring */
           for (i = 0; i < NET_RX_RING_SIZE; i++) {
                   struct xennet_rxreq *rxreq = &sc->sc_rxreqs[i];
   
                   /*
                    * if the buffer is in transit in the network stack, wait for
                    * the network stack to free it.
                    */
                   while ((volatile grant_ref_t)rxreq->rxreq_gntref ==
                       GRANT_STACK_REF)
                           tsleep(xennet_xenbus_detach, PRIBIO, "xnet_free", hz/2);
   
                   if (rxreq->rxreq_gntref != GRANT_INVALID_REF) {
                           /*
                            * this req is still granted. Get back the page or
                            * allocate a new one, and remap it.
                            */
                           SLIST_INSERT_HEAD(&sc->sc_rxreq_head, rxreq,
                               rxreq_next);
                           sc->sc_free_rxreql++;
                           ma = xengnt_revoke_transfer(rxreq->rxreq_gntref);
                           rxreq->rxreq_gntref = GRANT_INVALID_REF;
                           if (ma == 0) {
                                   struct xen_memory_reservation xenres;
                                   /*
                                    * transfer not complete, we lost the page.
                                    * Get one from hypervisor
                                    */
                                   xenres.extent_start = &ma;
                                   xenres.nr_extents = 1;
                                   xenres.extent_order = 0;
                                   xenres.address_bits = 31;
                                   xenres.domid = DOMID_SELF;
                                   if (HYPERVISOR_memory_op(
                                       XENMEM_increase_reservation, &xenres) < 0) {
                                           panic("xennet_free_rx_buffer: "
                                               "can't get memory back");
                                   }
                                   KASSERT(ma != 0);
                           }
                           pa = rxreq->rxreq_pa;
                           va = rxreq->rxreq_va;
                           /* remap the page */
                           mmu[0].ptr = (ma << PAGE_SHIFT) | MMU_MACHPHYS_UPDATE;
                           mmu[0].val = ((pa - XPMAP_OFFSET) >> PAGE_SHIFT);
                           MULTI_update_va_mapping(&mcl[0], va,
                               (ma << PAGE_SHIFT) | PG_V | PG_KW,
                               UVMF_TLB_FLUSH|UVMF_ALL);
                           xpmap_phys_to_machine_mapping[
                               (pa - XPMAP_OFFSET) >> PAGE_SHIFT] = ma;
                           mcl[1].op = __HYPERVISOR_mmu_update;
                           mcl[1].args[0] = (unsigned long)mmu;
                           mcl[1].args[1] = 1;
                           mcl[1].args[2] = 0;
                           mcl[1].args[3] = DOMID_SELF;
                           HYPERVISOR_multicall(mcl, 2);
                   }
   
           }
           splx(s);
           DPRINTF(("%s: xennet_free_rx_buffer done\n", sc->sc_dev.dv_xname));
   }
   
   static void
 xennet_rx_mbuf_free(struct mbuf *m, caddr_t buf, size_t size, void *arg)  xennet_rx_mbuf_free(struct mbuf *m, caddr_t buf, size_t size, void *arg)
 {  {
         struct xennet_rxreq *req = arg;          struct xennet_rxreq *req = arg;
         struct xennet_xenbus_softc *sc = req->rxreq_sc;          struct xennet_xenbus_softc *sc = req->rxreq_sc;
   
           int s = splnet();
   
         SLIST_INSERT_HEAD(&sc->sc_rxreq_head, req, rxreq_next);          SLIST_INSERT_HEAD(&sc->sc_rxreq_head, req, rxreq_next);
         sc->sc_free_rxreql++;          sc->sc_free_rxreql++;
   
         if (sc->sc_free_rxreql >= NET_RX_RING_SIZE / 2)          req->rxreq_gntref = GRANT_INVALID_REF;
           if (sc->sc_free_rxreql >= NET_RX_RING_SIZE / 2 &&
               __predict_true(sc->sc_backend_status == BEST_CONNECTED)) {
                 xennet_alloc_rx_buffer(sc);                  xennet_alloc_rx_buffer(sc);
           }
   
         if (m)          if (m)
                 pool_cache_put(&mbpool_cache, m);                  pool_cache_put(&mbpool_cache, m);
           splx(s);
 }  }
   
   
 static void  static void
 xennet_tx_complete(struct xennet_xenbus_softc * sc)  xennet_tx_complete(struct xennet_xenbus_softc *sc)
 {  {
         struct xennet_txreq *req;          struct xennet_txreq *req;
         struct ifnet *ifp = &sc->sc_ethercom.ec_if;          struct ifnet *ifp = &sc->sc_ethercom.ec_if;
Line 497  again:
Line 692  again:
                         sc->sc_tx_ring.rsp_cons = i;                          sc->sc_tx_ring.rsp_cons = i;
                         goto end;                          goto end;
                 }                  }
                   if (__predict_false(
                       RING_GET_RESPONSE(&sc->sc_tx_ring, i)->status !=
                       NETIF_RSP_OKAY))
                           ifp->if_oerrors++;
                   else
                           ifp->if_opackets++;
                 xengnt_revoke_access(req->txreq_gntref);                  xengnt_revoke_access(req->txreq_gntref);
                 m_freem(req->txreq_m);                  m_freem(req->txreq_m);
                 SLIST_INSERT_HEAD(&sc->sc_txreq_head, req, txreq_next);                  SLIST_INSERT_HEAD(&sc->sc_txreq_head, req, txreq_next);
Line 546  again:
Line 747  again:
                 netif_rx_response_t *rx = RING_GET_RESPONSE(&sc->sc_rx_ring, i);                  netif_rx_response_t *rx = RING_GET_RESPONSE(&sc->sc_rx_ring, i);
                 req = &sc->sc_rxreqs[rx->id];                  req = &sc->sc_rxreqs[rx->id];
                 KASSERT(req->rxreq_gntref != GRANT_INVALID_REF);                  KASSERT(req->rxreq_gntref != GRANT_INVALID_REF);
                   KASSERT(req->rxreq_id == rx->id);
                 ma = xengnt_revoke_transfer(req->rxreq_gntref);                  ma = xengnt_revoke_transfer(req->rxreq_gntref);
                 if (ma == 0) {                  if (ma == 0) {
                           DPRINTFN(XEDB_EVENT, ("xennet_handler ma == 0\n"));
                         /*                          /*
                          * the remote could't send us a packet.                           * the remote could't send us a packet.
                          * we can't free this rxreq as no page will be mapped                           * we can't free this rxreq as no page will be mapped
Line 563  again:
Line 766  again:
                         RING_PUSH_REQUESTS(&sc->sc_rx_ring);                          RING_PUSH_REQUESTS(&sc->sc_rx_ring);
                         continue;                          continue;
                 }                  }
                   req->rxreq_gntref = GRANT_INVALID_REF;
                 MGETHDR(m, M_DONTWAIT, MT_DATA);  
                 if (__predict_false(m == NULL)) {  
                         printf("xennet: rx no mbuf\n");  
                         ifp->if_ierrors++;  
                         sc->sc_rx_ring.rsp_cons = i;  
                         return 1;  
                 }  
   
                 pa = req->rxreq_pa;                  pa = req->rxreq_pa;
                 va = req->rxreq_va;                  va = req->rxreq_va;
Line 596  again:
Line 792  again:
                         if (ETHER_IS_MULTICAST(eh->ether_dhost) == 0 &&                          if (ETHER_IS_MULTICAST(eh->ether_dhost) == 0 &&
                             memcmp(LLADDR(ifp->if_sadl), eh->ether_dhost,                              memcmp(LLADDR(ifp->if_sadl), eh->ether_dhost,
                             ETHER_ADDR_LEN) != 0) {                              ETHER_ADDR_LEN) != 0) {
                                   DPRINTFN(XEDB_EVENT,
                                       ("xennet_handler bad dest\n"));
                                 /* packet not for us */                                  /* packet not for us */
                                 xennet_rx_mbuf_free(NULL, (void *)va, PAGE_SIZE,                                  xennet_rx_mbuf_free(NULL, (void *)va, PAGE_SIZE,
                                     req);                                      req);
                                 m_freem(m);  
                                 continue;                                  continue;
                         }                          }
                 }                  }
                   MGETHDR(m, M_DONTWAIT, MT_DATA);
                   if (__predict_false(m == NULL)) {
                           printf("xennet: rx no mbuf\n");
                           ifp->if_ierrors++;
                           xennet_rx_mbuf_free(NULL, (void *)va, PAGE_SIZE, req);
                           continue;
                   }
                   MCLAIM(m, &sc->sc_ethercom.ec_rx_mowner);
   
                 m->m_pkthdr.rcvif = ifp;                  m->m_pkthdr.rcvif = ifp;
                 if (__predict_true(sc->sc_rx_ring.req_prod_pvt !=                  if (__predict_true(sc->sc_rx_ring.req_prod_pvt !=
                     sc->sc_rx_ring.sring->rsp_prod)) {                      sc->sc_rx_ring.sring->rsp_prod)) {
                         m->m_len = m->m_pkthdr.len = rx->status;                          m->m_len = m->m_pkthdr.len = rx->status;
                         MEXTADD(m, pktp, rx->status,                          MEXTADD(m, pktp, rx->status,
                             M_DEVBUF, xennet_rx_mbuf_free, req);                              M_DEVBUF, xennet_rx_mbuf_free, req);
                           m->m_flags |= M_EXT_RW; /* we own the buffer */
                           req->rxreq_gntref = GRANT_STACK_REF;
                 } else {                  } else {
                         /*                          /*
                          * This was our last receive buffer, allocate                           * This was our last receive buffer, allocate
                          * memory, copy data and push the receive                           * memory, copy data and push the receive
                          * buffer back to the hypervisor.                           * buffer back to the hypervisor.
                          */                           */
                         m->m_len = MHLEN;                          m->m_len = min(MHLEN, rx->status);
                         m->m_pkthdr.len = 0;                          m->m_pkthdr.len = 0;
                         m_copyback(m, 0, rx->status, pktp);                          m_copyback(m, 0, rx->status, pktp);
                         xennet_rx_mbuf_free(NULL, (void *)va, PAGE_SIZE, req);                          xennet_rx_mbuf_free(NULL, (void *)va, PAGE_SIZE, req);
Line 626  again:
Line 834  again:
                                 continue;                                  continue;
                         }                          }
                 }                  }
                   if ((rx->flags & NETRXF_csum_blank) != 0) {
                           xennet_checksum_fill(&m);
                           if (m == NULL) {
                                   ifp->if_ierrors++;
                                   continue;
                           }
                   }
 #if NBPFILTER > 0  #if NBPFILTER > 0
                 /*                  /*
                  * Pass packet to bpf if there is a listener.                   * Pass packet to bpf if there is a listener.
Line 704  xennet_softstart(void *arg)
Line 919  xennet_softstart(void *arg)
   
         req_prod = sc->sc_tx_ring.req_prod_pvt;          req_prod = sc->sc_tx_ring.req_prod_pvt;
         while (/*CONSTCOND*/1) {          while (/*CONSTCOND*/1) {
                   uint16_t txflags;
   
                 req = SLIST_FIRST(&sc->sc_txreq_head);                  req = SLIST_FIRST(&sc->sc_txreq_head);
                 if (__predict_false(req == NULL)) {                  if (__predict_false(req == NULL)) {
                         ifp->if_flags |= IFF_OACTIVE;                          ifp->if_flags |= IFF_OACTIVE;
Line 733  xennet_softstart(void *arg)
Line 950  xennet_softstart(void *arg)
                         break;                          break;
                 }                  }
   
                   if ((m->m_pkthdr.csum_flags &
                       (M_CSUM_TCPv4 | M_CSUM_UDPv4)) != 0) {
                           txflags = NETTXF_csum_blank;
                   } else {
                           txflags = 0;
                   }
   
                 if (m->m_pkthdr.len != m->m_len ||                  if (m->m_pkthdr.len != m->m_len ||
                     (pa ^ (pa + m->m_pkthdr.len - 1)) & PG_FRAME) {                      (pa ^ (pa + m->m_pkthdr.len - 1)) & PG_FRAME) {
   
Line 787  xennet_softstart(void *arg)
Line 1011  xennet_softstart(void *arg)
                         /* we will be able to send m */                          /* we will be able to send m */
                         IFQ_DEQUEUE(&ifp->if_snd, m);                          IFQ_DEQUEUE(&ifp->if_snd, m);
                 }                  }
                   MCLAIM(m, &sc->sc_ethercom.ec_tx_mowner);
   
                 KASSERT(((pa ^ (pa + m->m_pkthdr.len -  1)) & PG_FRAME) == 0);                  KASSERT(((pa ^ (pa + m->m_pkthdr.len -  1)) & PG_FRAME) == 0);
   
Line 809  xennet_softstart(void *arg)
Line 1034  xennet_softstart(void *arg)
                 txreq->gref = req->txreq_gntref;                  txreq->gref = req->txreq_gntref;
                 txreq->offset = pa & ~PG_FRAME;                  txreq->offset = pa & ~PG_FRAME;
                 txreq->size = m->m_pkthdr.len;                  txreq->size = m->m_pkthdr.len;
                 txreq->flags = 0;                  txreq->flags = txflags;
   
                 req_prod++;                  req_prod++;
                 sc->sc_tx_ring.req_prod_pvt = req_prod;                  sc->sc_tx_ring.req_prod_pvt = req_prod;
Line 888  xennet_init(struct ifnet *ifp)
Line 1113  xennet_init(struct ifnet *ifp)
   
         DPRINTFN(XEDB_FOLLOW, ("%s: xennet_init()\n", sc->sc_dev.dv_xname));          DPRINTFN(XEDB_FOLLOW, ("%s: xennet_init()\n", sc->sc_dev.dv_xname));
   
         if (ifp->if_flags & IFF_UP) {          if ((ifp->if_flags & IFF_RUNNING) == 0) {
                 if ((ifp->if_flags & IFF_RUNNING) == 0) {                  sc->sc_rx_ring.sring->rsp_event =
                         xennet_alloc_rx_buffer(sc);                      sc->sc_rx_ring.rsp_cons + 1;
                         sc->sc_rx_ring.sring->rsp_event =                  hypervisor_enable_event(sc->sc_evtchn);
                             sc->sc_rx_ring.rsp_cons + 1;                  hypervisor_notify_via_evtchn(sc->sc_evtchn);
                         hypervisor_enable_event(sc->sc_evtchn);  
                         hypervisor_notify_via_evtchn(sc->sc_evtchn);  
                         xennet_reset(sc);  
                 }  
                 ifp->if_flags |= IFF_RUNNING;  
                 ifp->if_flags &= ~IFF_OACTIVE;  
                 ifp->if_timer = 0;  
         } else {  
                 ifp->if_flags &= ~IFF_RUNNING;  
                 xennet_reset(sc);                  xennet_reset(sc);
         }          }
           ifp->if_flags |= IFF_RUNNING;
           ifp->if_flags &= ~IFF_OACTIVE;
           ifp->if_timer = 0;
         splx(s);          splx(s);
         return 0;          return 0;
 }  }
Line 911  xennet_init(struct ifnet *ifp)
Line 1130  xennet_init(struct ifnet *ifp)
 void  void
 xennet_stop(struct ifnet *ifp, int disable)  xennet_stop(struct ifnet *ifp, int disable)
 {  {
           struct xennet_xenbus_softc *sc = ifp->if_softc;
           int s = splnet();
   
         ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);          ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
           hypervisor_mask_event(sc->sc_evtchn);
           xennet_reset(sc);
           splx(s);
 }  }
   
 void  void

Legend:
Removed from v.1.3  
changed lines
  Added in v.1.3.4.7

CVSweb <webmaster@jp.NetBSD.org>