From: Alexander Bluhm Subject: Re: igc(4): fix recv. jumbo frames To: David Gwynne Cc: Jan Klemkow , tech@openbsd.org, Theo de Raadt Date: Fri, 9 Aug 2024 20:38:37 +0200 On Fri, Aug 09, 2024 at 08:19:30PM +1000, David Gwynne wrote: > you could try this. it compiles at least... Works well on amd64 with and without jumbo frames. On sparc64 it does not panic. Jumbo frames are not well supported on this machine, I guess some bugs in the IOMMU implementation. Other drivers also have problems with jumbo on sparc64. Only part of my tests pass. This is not a regression. OK bluhm@ > Index: if_igc.c > =================================================================== > RCS file: /cvs/src/sys/dev/pci/if_igc.c,v > diff -u -p -r1.26 if_igc.c > --- if_igc.c 8 Aug 2024 14:58:49 -0000 1.26 > +++ if_igc.c 9 Aug 2024 10:08:29 -0000 > @@ -202,6 +202,7 @@ igc_attach(struct device *parent, struct > /* Determine hardware and mac info */ > igc_identify_hardware(sc); > > + sc->rx_mbuf_sz = MCLBYTES; > sc->num_tx_desc = IGC_DEFAULT_TXD; > sc->num_rx_desc = IGC_DEFAULT_RXD; > > @@ -881,7 +882,6 @@ igc_init(void *arg) > } > igc_initialize_transmit_unit(sc); > > - sc->rx_mbuf_sz = MCLBYTES; > /* Prepare receive descriptors and buffers. */ > if (igc_setup_receive_structures(sc)) { > printf("%s: Could not setup receive structures\n", > @@ -1232,7 +1232,7 @@ igc_rxrinfo(struct igc_softc *sc, struct > > for (i = 0; i < sc->sc_nqueues; i++) { > rxr = &sc->rx_rings[i]; > - ifr[n].ifr_size = MCLBYTES; > + ifr[n].ifr_size = sc->rx_mbuf_sz; > snprintf(ifr[n].ifr_name, sizeof(ifr[n].ifr_name), "%d", i); > ifr[n].ifr_info = rxr->rx_ring; > n++; > @@ -1673,11 +1673,11 @@ igc_get_buf(struct igc_rxring *rxr, int > return ENOBUFS; > } > > - m = MCLGETL(NULL, M_DONTWAIT, sc->rx_mbuf_sz); > + m = MCLGETL(NULL, M_DONTWAIT, sc->rx_mbuf_sz + ETHER_ALIGN); > if (!m) > return ENOBUFS; > > - m->m_data += (m->m_ext.ext_size - sc->rx_mbuf_sz); > + m->m_data += ETHER_ALIGN; > m->m_len = m->m_pkthdr.len = sc->rx_mbuf_sz; > > error = bus_dmamap_load_mbuf(rxr->rxdma.dma_tag, rxbuf->map, m, > @@ -2159,7 +2159,7 @@ igc_allocate_receive_buffers(struct igc_ > rxbuf = rxr->rx_buffers; > for (i = 0; i < sc->num_rx_desc; i++, rxbuf++) { > error = bus_dmamap_create(rxr->rxdma.dma_tag, > - MAX_JUMBO_FRAME_SIZE, IGC_MAX_SCATTER, MCLBYTES, 0, > + sc->rx_mbuf_sz, 1, sc->rx_mbuf_sz, 0, > BUS_DMA_NOWAIT, &rxbuf->map); > if (error) { > printf("%s: Unable to create RX DMA map\n", > @@ -2223,7 +2223,8 @@ igc_setup_receive_ring(struct igc_rxring > rxr->next_to_check = 0; > rxr->last_desc_filled = sc->num_rx_desc - 1; > > - if_rxr_init(&rxr->rx_ring, 2 * ((ifp->if_hardmtu / MCLBYTES) + 1), > + if_rxr_init(&rxr->rx_ring, > + 2 * howmany(ifp->if_hardmtu, sc->rx_mbuf_sz) + 1, > sc->num_rx_desc - 1); > > return 0;