version 1.10, 2006/05/27 19:54:59 |
version 1.10.4.3, 2006/12/30 20:47:25 |
Line 98 __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 174 struct xennet_xenbus_softc { |
|
Line 176 struct xennet_xenbus_softc { |
|
rndsource_element_t sc_rnd_source; |
rndsource_element_t sc_rnd_source; |
#endif |
#endif |
}; |
}; |
|
#define SC_NLIVEREQ(sc) ((sc)->sc_rx_ring.req_prod_pvt - \ |
|
(sc)->sc_rx_ring.sring->rsp_prod) |
|
|
/* too big to be on stack */ |
/* too big to be on stack */ |
static multicall_entry_t rx_mcl[NET_RX_RING_SIZE+1]; |
static multicall_entry_t rx_mcl[NET_RX_RING_SIZE+1]; |
Line 327 xennet_xenbus_attach(struct device *pare |
|
Line 331 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 511 xennet_alloc_rx_buffer(struct xennet_xen |
|
Line 516 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 648 xennet_rx_mbuf_free(struct mbuf *m, cadd |
|
Line 654 xennet_rx_mbuf_free(struct mbuf *m, cadd |
|
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++; |
|
|
req->rxreq_gntref = GRANT_INVALID_REF; |
req->rxreq_gntref = GRANT_INVALID_REF; |
if (sc->sc_free_rxreql >= NET_RX_RING_SIZE / 2 && |
if (sc->sc_free_rxreql >= SC_NLIVEREQ(sc) && |
__predict_true(sc->sc_backend_status == BEST_CONNECTED)) { |
__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); |
} |
} |
|
|
|
|
|
|
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")); |
DPRINTFN(XEDB_EVENT, ("xennet_handler ma == 0\n")); |
|
|
xennet_rx_mbuf_free(NULL, (void *)va, PAGE_SIZE, req); |
xennet_rx_mbuf_free(NULL, (void *)va, PAGE_SIZE, req); |
continue; |
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 != |
|
|
* 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); |
|
|
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 903 xennet_softstart(void *arg) |
|
Line 921 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 932 xennet_softstart(void *arg) |
|
Line 952 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 986 xennet_softstart(void *arg) |
|
Line 1013 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 1008 xennet_softstart(void *arg) |
|
Line 1036 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; |