-/* $OpenBSD: if_rge.c,v 1.31 2024/08/21 00:56:58 dlg Exp $ */
+/* $OpenBSD: if_rge.c,v 1.32 2024/08/21 01:12:52 dlg Exp $ */
/*
* Copyright (c) 2019, 2020, 2023, 2024
ifq_barrier(&ifp->if_snd);
ifq_clr_oactive(&ifp->if_snd);
+ if (q->q_rx.rge_head != NULL) {
+ m_freem(q->q_rx.rge_head);
+ q->q_rx.rge_head = NULL;
+ q->q_rx.rge_tail = &q->q_rx.rge_head;
+ }
+
/* Free the TX list buffers. */
for (i = 0; i < RGE_TX_LIST_CNT; i++) {
if (q->q_tx.rge_txq[i].txq_mbuf != NULL) {
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 = 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 - 1);
rge_fill_rx_ring(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;
i = cons = q->q_rx.rge_rxq_considx;
if_rxr_put(rxr, 1);
rx = 1;
- total_len = rxstat & RGE_RDCMDSTS_FRAGLEN;
+ 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;
+ }
- /* We only handle a packet per rx descriptor at the moment */
- if ((rxstat & (RGE_RDCMDSTS_SOF | RGE_RDCMDSTS_EOF)) !=
- (RGE_RDCMDSTS_SOF | RGE_RDCMDSTS_EOF)) {
- ifp->if_ierrors++;
+ m->m_pkthdr.len = 0;
+ } else if (q->q_rx.rge_head == NULL) {
m_freem(m);
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++;
m_freem(m);
+ q->q_rx.rge_head = NULL;
+ q->q_rx.rge_tail = &q->q_rx.rge_head;
continue;
}
- 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);
-/* $OpenBSD: if_rgereg.h,v 1.12 2024/08/20 00:09:12 dlg Exp $ */
+/* $OpenBSD: if_rgereg.h,v 1.13 2024/08/21 01:12:52 dlg Exp $ */
/*
* Copyright (c) 2019, 2020 Kevin Lo <kevlo@openbsd.org>
uint32_t rsvd8;
} rx_ptp;
} hi_qword1;
-};
+} __packed __aligned(16);
#define RGE_RDCMDSTS_RXERRSUM 0x00100000
#define RGE_RDCMDSTS_EOF 0x01000000
struct rge_rx_desc *rge_rx_list;
struct mbuf *rge_head;
- struct mbuf *rge_tail;
+ struct mbuf **rge_tail;
};
struct rge_queues {