summaryrefslogtreecommitdiff
path: root/sys/dev/pci/if_vmx.c
diff options
context:
space:
mode:
authorReyk Floeter <reyk@cvs.openbsd.org>2013-08-28 10:19:20 +0000
committerReyk Floeter <reyk@cvs.openbsd.org>2013-08-28 10:19:20 +0000
commit49ddd37de470ab2606c1d32aa5ed2cc3e1d11fd3 (patch)
treeb878179f9dc4b94ec636bb15fd9dedb2c8085fc3 /sys/dev/pci/if_vmx.c
parentcf6631bf64eaa81a326cf4d7941b6d2d15243c38 (diff)
vmx(4) uses 4 different types of 128bit descriptors in little-endian
format for Rx and Tx. Replace the bit fields in the descriptor structs with 32bit words to access them with traditional bit operations using shifts and masks. We try to avoid bit fields in OpenBSD. For consistence with other drivers, this change also uses letoh32/htole32 endianess conversions even if it is very unlikely that vmx will ever run on a big-endian VM/host. discussed with uebayasi@ and deraadt@
Diffstat (limited to 'sys/dev/pci/if_vmx.c')
-rw-r--r--sys/dev/pci/if_vmx.c90
1 files changed, 51 insertions, 39 deletions
diff --git a/sys/dev/pci/if_vmx.c b/sys/dev/pci/if_vmx.c
index 24f0ef75494..24d6997877b 100644
--- a/sys/dev/pci/if_vmx.c
+++ b/sys/dev/pci/if_vmx.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_vmx.c,v 1.11 2013/06/22 00:28:10 uebayasi Exp $ */
+/* $OpenBSD: if_vmx.c,v 1.12 2013/08/28 10:19:19 reyk Exp $ */
/*
* Copyright (c) 2013 Tsubai Masanari
@@ -645,7 +645,9 @@ vmxnet3_txintr(struct vmxnet3_softc *sc, struct vmxnet3_txqueue *tq)
for (;;) {
txcd = &comp_ring->txcd[comp_ring->next];
- if (txcd->gen != comp_ring->gen)
+
+ if (letoh32((txcd->txc_word3 >> VMXNET3_TXC_GEN_S) &
+ VMXNET3_TXC_GEN_M) != comp_ring->gen)
break;
comp_ring->next++;
@@ -660,7 +662,9 @@ vmxnet3_txintr(struct vmxnet3_softc *sc, struct vmxnet3_txqueue *tq)
m_freem(ring->m[sop]);
ring->m[sop] = NULL;
bus_dmamap_unload(sc->sc_dmat, ring->dmap[sop]);
- ring->next = (txcd->eop_idx + 1) % NTXDESC;
+ ring->next = (letoh32((txcd->txc_word0 >>
+ VMXNET3_TXC_EOPIDX_S) & VMXNET3_TXC_EOPIDX_M) + 1)
+ % NTXDESC;
ifp->if_flags &= ~IFF_OACTIVE;
}
@@ -682,7 +686,8 @@ vmxnet3_rxintr(struct vmxnet3_softc *sc, struct vmxnet3_rxqueue *rq)
for (;;) {
rxcd = &comp_ring->rxcd[comp_ring->next];
- if (rxcd->gen != comp_ring->gen)
+ if (letoh32((rxcd->rxc_word3 >> VMXNET3_RXC_GEN_S) &
+ VMXNET3_RXC_GEN_M) != comp_ring->gen)
break;
comp_ring->next++;
@@ -691,13 +696,16 @@ vmxnet3_rxintr(struct vmxnet3_softc *sc, struct vmxnet3_rxqueue *rq)
comp_ring->gen ^= 1;
}
- idx = rxcd->rxd_idx;
- if (rxcd->qid < NRXQUEUE)
+ idx = letoh32((rxcd->rxc_word0 >> VMXNET3_RXC_IDX_S) &
+ VMXNET3_RXC_IDX_M);
+ if (letoh32((rxcd->rxc_word0 >> VMXNET3_RXC_QID_S) &
+ VMXNET3_RXC_QID_M) < NRXQUEUE)
ring = &rq->cmd_ring[0];
else
ring = &rq->cmd_ring[1];
rxd = &ring->rxd[idx];
- len = rxcd->len;
+ len = letoh32((rxcd->rxc_word2 >> VMXNET3_RXC_LEN_S) &
+ VMXNET3_RXC_LEN_M);
m = ring->m[idx];
ring->m[idx] = NULL;
bus_dmamap_unload(sc->sc_dmat, ring->dmap[idx]);
@@ -705,11 +713,12 @@ vmxnet3_rxintr(struct vmxnet3_softc *sc, struct vmxnet3_rxqueue *rq)
if (m == NULL)
panic("NULL mbuf");
- if (rxd->btype != VMXNET3_BTYPE_HEAD) {
+ if (letoh32((rxd->rx_word2 >> VMXNET3_RX_BTYPE_S) &
+ VMXNET3_RX_BTYPE_M) != VMXNET3_BTYPE_HEAD) {
m_freem(m);
goto skip_buffer;
}
- if (rxcd->error) {
+ if (letoh32(rxcd->rxc_word2 & VMXNET3_RXC_ERROR)) {
ifp->if_ierrors++;
m_freem(m);
goto skip_buffer;
@@ -726,9 +735,10 @@ vmxnet3_rxintr(struct vmxnet3_softc *sc, struct vmxnet3_rxqueue *rq)
vmxnet3_rx_csum(rxcd, m);
m->m_pkthdr.rcvif = ifp;
m->m_pkthdr.len = m->m_len = len;
- if (rxcd->vlan) {
+ if (letoh32(rxcd->rxc_word2 & VMXNET3_RXC_VLAN)) {
m->m_flags |= M_VLANTAG;
- m->m_pkthdr.ether_vtag = rxcd->vtag;
+ m->m_pkthdr.ether_vtag = letoh32((rxcd->rxc_word2 >>
+ VMXNET3_RXC_VLANTAG_S) & VMXNET3_RXC_VLANTAG_M);
}
#if NBPFILTER > 0
@@ -742,7 +752,8 @@ skip_buffer:
vmxstat.rxdone = idx;
#endif
if (rq->rs->update_rxhead) {
- u_int qid = rxcd->qid;
+ u_int qid = letoh32((rxcd->rxc_word0 >>
+ VMXNET3_RXC_QID_S) & VMXNET3_RXC_QID_M);
idx = (idx + 1) % NRXDESC;
if (qid < NRXQUEUE) {
@@ -811,23 +822,24 @@ vmxnet3_iff(struct vmxnet3_softc *sc)
void
vmxnet3_rx_csum(struct vmxnet3_rxcompdesc *rxcd, struct mbuf *m)
{
- if (rxcd->no_csum)
+ if (letoh32(rxcd->rxc_word0 & VMXNET3_RXC_NOCSUM))
return;
- if (rxcd->ipv4 && rxcd->ipcsum_ok)
+ if ((rxcd->rxc_word3 & (VMXNET3_RXC_IPV4|VMXNET3_RXC_IPSUM_OK)) ==
+ (VMXNET3_RXC_IPV4|VMXNET3_RXC_IPSUM_OK))
m->m_pkthdr.csum_flags |= M_IPV4_CSUM_IN_OK;
- if (rxcd->fragment)
+ if (rxcd->rxc_word3 & VMXNET3_RXC_FRAGMENT)
return;
- if (rxcd->tcp) {
- if (rxcd->csum_ok)
+ if (rxcd->rxc_word3 & VMXNET3_RXC_TCP) {
+ if (rxcd->rxc_word3 & VMXNET3_RXC_CSUM_OK)
m->m_pkthdr.csum_flags |= M_TCP_CSUM_IN_OK;
else
m->m_pkthdr.csum_flags |= M_TCP_CSUM_IN_BAD;
}
- if (rxcd->udp) {
- if (rxcd->csum_ok)
+ if (rxcd->rxc_word3 & VMXNET3_RXC_UDP) {
+ if (rxcd->rxc_word3 & VMXNET3_RXC_CSUM_OK)
m->m_pkthdr.csum_flags |= M_UDP_CSUM_IN_OK;
else
m->m_pkthdr.csum_flags |= M_UDP_CSUM_IN_BAD;
@@ -873,10 +885,11 @@ vmxnet3_getbuf(struct vmxnet3_softc *sc, struct vmxnet3_rxring *ring)
if (bus_dmamap_load_mbuf(sc->sc_dmat, ring->dmap[idx], m,
BUS_DMA_NOWAIT))
panic("load mbuf");
- rxd->addr = DMAADDR(ring->dmap[idx]);
- rxd->btype = btype;
- rxd->len = m->m_pkthdr.len;
- rxd->gen = ring->gen;
+ rxd->rx_addr = htole64(DMAADDR(ring->dmap[idx]));
+ rxd->rx_word2 = htole32(((m->m_pkthdr.len & VMXNET3_RX_LEN_M) <<
+ VMXNET3_RX_LEN_S) | ((btype & VMXNET3_RX_BTYPE_M) <<
+ VMXNET3_RX_BTYPE_S) | ((ring->gen & VMXNET3_RX_GEN_M) <<
+ VMXNET3_RX_GEN_S));
idx++;
if (idx == NRXDESC) {
idx = 0;
@@ -1118,14 +1131,11 @@ vmxnet3_load_mbuf(struct vmxnet3_softc *sc, struct mbuf *m)
gen = ring->gen ^ 1; /* owned by cpu (yet) */
for (i = 0; i < map->dm_nsegs; i++) {
txd = &ring->txd[ring->head];
- txd->addr = map->dm_segs[i].ds_addr;
- txd->len = map->dm_segs[i].ds_len;
- txd->gen = gen;
- txd->dtype = 0;
- txd->offload_mode = VMXNET3_OM_NONE;
- txd->offload_pos = txd->hlen = 0;
- txd->eop = txd->compreq = 0;
- txd->vtag_mode = txd->vtag = 0;
+ txd->tx_addr = htole64(map->dm_segs[i].ds_addr);
+ txd->tx_word2 = htole32(((map->dm_segs[i].ds_len &
+ VMXNET3_TX_LEN_M) << VMXNET3_TX_LEN_S) |
+ ((gen & VMXNET3_TX_GEN_M) << VMXNET3_TX_GEN_S));
+ txd->tx_word3 = 0;
ring->head++;
if (ring->head == NTXDESC) {
ring->head = 0;
@@ -1133,20 +1143,22 @@ vmxnet3_load_mbuf(struct vmxnet3_softc *sc, struct mbuf *m)
}
gen = ring->gen;
}
- txd->eop = txd->compreq = 1;
+ txd->tx_word3 |= htole32(VMXNET3_TX_EOP | VMXNET3_TX_COMPREQ);
if (m->m_flags & M_VLANTAG) {
- sop->vtag_mode = 1;
- sop->vtag = m->m_pkthdr.ether_vtag;
+ sop->tx_word3 |= htole32(VMXNET3_TX_VTAG_MODE);
+ sop->tx_word3 |= htole32((m->m_pkthdr.ether_vtag &
+ VMXNET3_TX_VLANTAG_M) << VMXNET3_TX_VLANTAG_S);
}
if (m->m_pkthdr.csum_flags & (M_TCP_CSUM_OUT|M_UDP_CSUM_OUT)) {
- sop->offload_mode = VMXNET3_OM_CSUM;
- sop->hlen = hlen;
- sop->offload_pos = hlen + csum_off;
+ sop->tx_word2 |= htole32(((hlen + csum_off) &
+ VMXNET3_TX_OP_M) << VMXNET3_TX_OP_S);
+ sop->tx_word3 |= htole32(((hlen & VMXNET3_TX_HLEN_M) <<
+ VMXNET3_TX_HLEN_S) | (VMXNET3_OM_CSUM << VMXNET3_TX_OM_S));
}
- /* Change the ownership. */
- sop->gen ^= 1;
+ /* Change the ownership by flipping the "generation" bit */
+ sop->tx_word2 ^= htole32(VMXNET3_TX_GEN_M << VMXNET3_TX_GEN_S);
return (0);
}