sync with OpenBSD -current
This commit is contained in:
parent
f36b410006
commit
df7f961280
37 changed files with 741 additions and 712 deletions
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: if_rge.c,v 1.30 2024/08/20 00:09:12 dlg Exp $ */
|
||||
/* $OpenBSD: if_rge.c,v 1.34 2024/08/21 01:22:31 dlg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2019, 2020, 2023, 2024
|
||||
|
@ -74,7 +74,6 @@ int rge_ifmedia_upd(struct ifnet *);
|
|||
void rge_ifmedia_sts(struct ifnet *, struct ifmediareq *);
|
||||
int rge_allocmem(struct rge_softc *);
|
||||
int rge_newbuf(struct rge_queues *);
|
||||
void rge_discard_rxbuf(struct rge_queues *, int);
|
||||
void rge_rx_list_init(struct rge_queues *);
|
||||
void rge_tx_list_init(struct rge_queues *);
|
||||
void rge_fill_rx_ring(struct rge_queues *);
|
||||
|
@ -567,7 +566,7 @@ rge_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
|||
break;
|
||||
case SIOCGIFRXR:
|
||||
error = if_rxr_ioctl((struct if_rxrinfo *)ifr->ifr_data,
|
||||
NULL, RGE_JUMBO_FRAMELEN, &sc->sc_queues->q_rx.rge_rx_ring);
|
||||
NULL, MCLBYTES, &sc->sc_queues->q_rx.rge_rx_ring);
|
||||
break;
|
||||
default:
|
||||
error = ether_ioctl(ifp, &sc->sc_arpcom, cmd, data);
|
||||
|
@ -886,7 +885,8 @@ rge_stop(struct ifnet *ifp)
|
|||
|
||||
if (q->q_rx.rge_head != NULL) {
|
||||
m_freem(q->q_rx.rge_head);
|
||||
q->q_rx.rge_head = q->q_rx.rge_tail = NULL;
|
||||
q->q_rx.rge_head = NULL;
|
||||
q->q_rx.rge_tail = &q->q_rx.rge_head;
|
||||
}
|
||||
|
||||
/* Free the TX list buffers. */
|
||||
|
@ -1141,13 +1141,15 @@ rge_newbuf(struct rge_queues *q)
|
|||
struct rge_rx_desc *r;
|
||||
struct rge_rxq *rxq;
|
||||
bus_dmamap_t rxmap;
|
||||
uint32_t cmdsts;
|
||||
int idx;
|
||||
|
||||
m = MCLGETL(NULL, M_DONTWAIT, RGE_JUMBO_FRAMELEN);
|
||||
m = MCLGETL(NULL, M_DONTWAIT, MCLBYTES);
|
||||
if (m == NULL)
|
||||
return (ENOBUFS);
|
||||
|
||||
m->m_len = m->m_pkthdr.len = RGE_JUMBO_FRAMELEN;
|
||||
m->m_len = m->m_pkthdr.len = MCLBYTES;
|
||||
m_adj(m, ETHER_ALIGN);
|
||||
|
||||
idx = q->q_rx.rge_rxq_prodidx;
|
||||
rxq = &q->q_rx.rge_rxq[idx];
|
||||
|
@ -1166,15 +1168,23 @@ rge_newbuf(struct rge_queues *q)
|
|||
|
||||
rxq->rxq_mbuf = m;
|
||||
|
||||
r->hi_qword1.rx_qword4.rge_extsts = 0;
|
||||
cmdsts = rxmap->dm_segs[0].ds_len;
|
||||
if (idx == RGE_RX_LIST_CNT - 1)
|
||||
cmdsts |= RGE_RDCMDSTS_EOR;
|
||||
|
||||
r->hi_qword1.rx_qword4.rge_cmdsts = htole32(cmdsts);
|
||||
r->hi_qword1.rx_qword4.rge_extsts = htole32(0);
|
||||
r->hi_qword0.rge_addr = htole64(rxmap->dm_segs[0].ds_addr);
|
||||
|
||||
r->hi_qword1.rx_qword4.rge_cmdsts = htole32(rxmap->dm_segs[0].ds_len);
|
||||
if (idx == RGE_RX_LIST_CNT - 1)
|
||||
r->hi_qword1.rx_qword4.rge_cmdsts |= htole32(RGE_RDCMDSTS_EOR);
|
||||
|
||||
r->hi_qword1.rx_qword4.rge_cmdsts |= htole32(RGE_RDCMDSTS_OWN);
|
||||
bus_dmamap_sync(sc->sc_dmat, q->q_rx.rge_rx_list_map,
|
||||
idx * sizeof(struct rge_rx_desc), sizeof(struct rge_rx_desc),
|
||||
BUS_DMASYNC_PREWRITE);
|
||||
|
||||
bus_dmamap_sync(sc->sc_dmat, q->q_rx.rge_rx_list_map,
|
||||
idx * sizeof(struct rge_rx_desc), sizeof(struct rge_rx_desc),
|
||||
BUS_DMASYNC_POSTWRITE);
|
||||
cmdsts |= RGE_RDCMDSTS_OWN;
|
||||
r->hi_qword1.rx_qword4.rge_cmdsts = htole32(cmdsts);
|
||||
bus_dmamap_sync(sc->sc_dmat, q->q_rx.rge_rx_list_map,
|
||||
idx * sizeof(struct rge_rx_desc), sizeof(struct rge_rx_desc),
|
||||
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
|
||||
|
@ -1184,34 +1194,16 @@ rge_newbuf(struct rge_queues *q)
|
|||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
rge_discard_rxbuf(struct rge_queues *q, int idx)
|
||||
{
|
||||
struct rge_softc *sc = q->q_sc;
|
||||
struct rge_rx_desc *r;
|
||||
|
||||
r = &q->q_rx.rge_rx_list[idx];
|
||||
|
||||
r->hi_qword1.rx_qword4.rge_cmdsts = htole32(RGE_JUMBO_FRAMELEN);
|
||||
r->hi_qword1.rx_qword4.rge_extsts = 0;
|
||||
if (idx == RGE_RX_LIST_CNT - 1)
|
||||
r->hi_qword1.rx_qword4.rge_cmdsts |= htole32(RGE_RDCMDSTS_EOR);
|
||||
r->hi_qword1.rx_qword4.rge_cmdsts |= htole32(RGE_RDCMDSTS_OWN);
|
||||
|
||||
bus_dmamap_sync(sc->sc_dmat, q->q_rx.rge_rx_list_map,
|
||||
idx * sizeof(struct rge_rx_desc), sizeof(struct rge_rx_desc),
|
||||
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
|
||||
}
|
||||
|
||||
void
|
||||
rge_rx_list_init(struct rge_queues *q)
|
||||
{
|
||||
memset(q->q_rx.rge_rx_list, 0, RGE_RX_LIST_SZ);
|
||||
|
||||
q->q_rx.rge_rxq_prodidx = q->q_rx.rge_rxq_considx = 0;
|
||||
q->q_rx.rge_head = q->q_rx.rge_tail = NULL;
|
||||
q->q_rx.rge_head = NULL;
|
||||
q->q_rx.rge_tail = &q->q_rx.rge_head;
|
||||
|
||||
if_rxr_init(&q->q_rx.rge_rx_ring, 32, RGE_RX_LIST_CNT);
|
||||
if_rxr_init(&q->q_rx.rge_rx_ring, 32, RGE_RX_LIST_CNT - 1);
|
||||
rge_fill_rx_ring(q);
|
||||
}
|
||||
|
||||
|
@ -1261,80 +1253,76 @@ rge_rxeof(struct rge_queues *q)
|
|||
struct rge_rx_desc *cur_rx;
|
||||
struct rge_rxq *rxq;
|
||||
uint32_t rxstat, extsts;
|
||||
int i, total_len, rx = 0;
|
||||
int i, mlen, rx = 0;
|
||||
int cons;
|
||||
|
||||
for (i = q->q_rx.rge_rxq_considx; if_rxr_inuse(rxr) > 0;
|
||||
i = RGE_NEXT_RX_DESC(i)) {
|
||||
/* Invalidate the descriptor memory. */
|
||||
bus_dmamap_sync(sc->sc_dmat, q->q_rx.rge_rx_list_map,
|
||||
i * sizeof(struct rge_rx_desc), sizeof(struct rge_rx_desc),
|
||||
BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
|
||||
i = cons = q->q_rx.rge_rxq_considx;
|
||||
|
||||
while (if_rxr_inuse(rxr) > 0) {
|
||||
cur_rx = &q->q_rx.rge_rx_list[i];
|
||||
|
||||
bus_dmamap_sync(sc->sc_dmat, q->q_rx.rge_rx_list_map,
|
||||
i * sizeof(*cur_rx), sizeof(*cur_rx),
|
||||
BUS_DMASYNC_POSTREAD);
|
||||
rxstat = letoh32(cur_rx->hi_qword1.rx_qword4.rge_cmdsts);
|
||||
extsts = letoh32(cur_rx->hi_qword1.rx_qword4.rge_extsts);
|
||||
|
||||
if (rxstat & RGE_RDCMDSTS_OWN)
|
||||
if (rxstat & RGE_RDCMDSTS_OWN) {
|
||||
bus_dmamap_sync(sc->sc_dmat, q->q_rx.rge_rx_list_map,
|
||||
i * sizeof(*cur_rx), sizeof(*cur_rx),
|
||||
BUS_DMASYNC_PREREAD);
|
||||
break;
|
||||
}
|
||||
|
||||
total_len = rxstat & RGE_RDCMDSTS_FRAGLEN;
|
||||
rxq = &q->q_rx.rge_rxq[i];
|
||||
m = rxq->rxq_mbuf;
|
||||
rxq->rxq_mbuf = NULL;
|
||||
if_rxr_put(rxr, 1);
|
||||
rx = 1;
|
||||
|
||||
/* Invalidate the RX mbuf and unload its map. */
|
||||
bus_dmamap_sync(sc->sc_dmat, rxq->rxq_dmamap, 0,
|
||||
rxq->rxq_dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD);
|
||||
bus_dmamap_unload(sc->sc_dmat, rxq->rxq_dmamap);
|
||||
m = rxq->rxq_mbuf;
|
||||
rxq->rxq_mbuf = NULL;
|
||||
|
||||
if ((rxstat & (RGE_RDCMDSTS_SOF | RGE_RDCMDSTS_EOF)) !=
|
||||
(RGE_RDCMDSTS_SOF | RGE_RDCMDSTS_EOF)) {
|
||||
ifp->if_ierrors++;
|
||||
i = RGE_NEXT_RX_DESC(i);
|
||||
if_rxr_put(rxr, 1);
|
||||
rx = 1;
|
||||
|
||||
if (ISSET(rxstat, RGE_RDCMDSTS_SOF)) {
|
||||
if (q->q_rx.rge_head != NULL) {
|
||||
ifp->if_ierrors++;
|
||||
m_freem(q->q_rx.rge_head);
|
||||
q->q_rx.rge_tail = &q->q_rx.rge_head;
|
||||
}
|
||||
|
||||
m->m_pkthdr.len = 0;
|
||||
} else if (q->q_rx.rge_head == NULL) {
|
||||
m_freem(m);
|
||||
rge_discard_rxbuf(q, i);
|
||||
continue;
|
||||
}
|
||||
} else
|
||||
CLR(m->m_flags, M_PKTHDR);
|
||||
|
||||
*q->q_rx.rge_tail = m;
|
||||
q->q_rx.rge_tail = &m->m_next;
|
||||
|
||||
mlen = rxstat & RGE_RDCMDSTS_FRAGLEN;
|
||||
m->m_len = mlen;
|
||||
|
||||
m = q->q_rx.rge_head;
|
||||
m->m_pkthdr.len += mlen;
|
||||
|
||||
if (rxstat & RGE_RDCMDSTS_RXERRSUM) {
|
||||
ifp->if_ierrors++;
|
||||
/*
|
||||
* If this is part of a multi-fragment packet,
|
||||
* discard all the pieces.
|
||||
*/
|
||||
if (q->q_rx.rge_head != NULL) {
|
||||
m_freem(q->q_rx.rge_head);
|
||||
q->q_rx.rge_head = q->q_rx.rge_tail = NULL;
|
||||
}
|
||||
m_freem(m);
|
||||
rge_discard_rxbuf(q, i);
|
||||
q->q_rx.rge_head = NULL;
|
||||
q->q_rx.rge_tail = &q->q_rx.rge_head;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (q->q_rx.rge_head != NULL) {
|
||||
m->m_len = total_len;
|
||||
/*
|
||||
* Special case: if there's 4 bytes or less
|
||||
* in this buffer, the mbuf can be discarded:
|
||||
* the last 4 bytes is the CRC, which we don't
|
||||
* care about anyway.
|
||||
*/
|
||||
if (m->m_len <= ETHER_CRC_LEN) {
|
||||
q->q_rx.rge_tail->m_len -=
|
||||
(ETHER_CRC_LEN - m->m_len);
|
||||
m_freem(m);
|
||||
} else {
|
||||
m->m_len -= ETHER_CRC_LEN;
|
||||
m->m_flags &= ~M_PKTHDR;
|
||||
q->q_rx.rge_tail->m_next = m;
|
||||
}
|
||||
m = q->q_rx.rge_head;
|
||||
q->q_rx.rge_head = q->q_rx.rge_tail = NULL;
|
||||
m->m_pkthdr.len = total_len - ETHER_CRC_LEN;
|
||||
} else
|
||||
m->m_pkthdr.len = m->m_len =
|
||||
(total_len - ETHER_CRC_LEN);
|
||||
if (!ISSET(rxstat, RGE_RDCMDSTS_EOF))
|
||||
continue;
|
||||
|
||||
q->q_rx.rge_head = NULL;
|
||||
q->q_rx.rge_tail = &q->q_rx.rge_head;
|
||||
|
||||
m_adj(m, -ETHER_CRC_LEN);
|
||||
|
||||
extsts = letoh32(cur_rx->hi_qword1.rx_qword4.rge_extsts);
|
||||
|
||||
/* Check IP header checksum. */
|
||||
if (!(extsts & RGE_RDEXTSTS_IPCSUMERR) &&
|
||||
|
@ -1361,13 +1349,32 @@ rge_rxeof(struct rge_queues *q)
|
|||
ml_enqueue(&ml, m);
|
||||
}
|
||||
|
||||
if (!rx)
|
||||
return (0);
|
||||
|
||||
if (i >= cons) {
|
||||
bus_dmamap_sync(sc->sc_dmat, q->q_rx.rge_rx_list_map,
|
||||
cons * sizeof(*cur_rx), (i - cons) * sizeof(*cur_rx),
|
||||
BUS_DMASYNC_POSTWRITE);
|
||||
} else {
|
||||
bus_dmamap_sync(sc->sc_dmat, q->q_rx.rge_rx_list_map,
|
||||
cons * sizeof(*cur_rx),
|
||||
(RGE_RX_LIST_CNT - cons) * sizeof(*cur_rx),
|
||||
BUS_DMASYNC_POSTWRITE);
|
||||
if (i > 0) {
|
||||
bus_dmamap_sync(sc->sc_dmat, q->q_rx.rge_rx_list_map,
|
||||
0, i * sizeof(*cur_rx),
|
||||
BUS_DMASYNC_POSTWRITE);
|
||||
}
|
||||
}
|
||||
|
||||
if (ifiq_input(&ifp->if_rcv, &ml))
|
||||
if_rxr_livelocked(rxr);
|
||||
|
||||
q->q_rx.rge_rxq_considx = i;
|
||||
rge_fill_rx_ring(q);
|
||||
|
||||
return (rx);
|
||||
return (1);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue