Index: sys/dev/bge/if_bgereg.h =================================================================== --- sys/dev/bge/if_bgereg.h (revision 219453) +++ sys/dev/bge/if_bgereg.h (working copy) @@ -2748,6 +2748,7 @@ uint32_t bge_flags; #define BGE_FLAG_TBI 0x00000001 #define BGE_FLAG_JUMBO 0x00000002 +#define BGE_FLAG_JUMBO_STD 0x00000004 #define BGE_FLAG_EADDR 0x00000008 #define BGE_FLAG_MII_SERDES 0x00000010 #define BGE_FLAG_CPMU_PRESENT 0x00000020 Index: sys/dev/bge/if_bge.c =================================================================== --- sys/dev/bge/if_bge.c (revision 219453) +++ sys/dev/bge/if_bge.c (working copy) @@ -943,10 +943,19 @@ bus_dmamap_t map; int error, nsegs; - m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); - if (m == NULL) - return (ENOBUFS); - m->m_len = m->m_pkthdr.len = MCLBYTES; + if (sc->bge_flags & BGE_FLAG_JUMBO_STD && + (sc->bge_ifp->if_mtu + ETHER_HDR_LEN + ETHER_CRC_LEN + + ETHER_VLAN_ENCAP_LEN > (MCLBYTES - ETHER_ALIGN))) { + m = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, MJUM9BYTES); + if (m == NULL) + return (ENOBUFS); + m->m_len = m->m_pkthdr.len = MJUM9BYTES; + } else { + m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); + if (m == NULL) + return (ENOBUFS); + m->m_len = m->m_pkthdr.len = MCLBYTES; + } if ((sc->bge_flags & BGE_FLAG_RX_ALIGNBUG) == 0) m_adj(m, ETHER_ALIGN); @@ -2385,7 +2394,7 @@ bge_dma_alloc(struct bge_softc *sc) { bus_addr_t lowaddr; - bus_size_t boundary, sbsz, txsegsz, txmaxsegsz; + bus_size_t boundary, sbsz, rxmaxsegsz, txsegsz, txmaxsegsz; int i, error; lowaddr = BUS_SPACE_MAXADDR; @@ -2513,9 +2522,13 @@ } /* Create tag for Rx mbufs. */ + if (sc->bge_flags & BGE_FLAG_JUMBO_STD) + rxmaxsegsz = MJUM9BYTES; + else + rxmaxsegsz = MCLBYTES; error = bus_dma_tag_create(sc->bge_cdata.bge_buffer_tag, 1, 0, - BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL, MCLBYTES, 1, - MCLBYTES, 0, NULL, NULL, &sc->bge_cdata.bge_rx_mtag); + BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL, rxmaxsegsz, 1, + rxmaxsegsz, 0, NULL, NULL, &sc->bge_cdata.bge_rx_mtag); if (error) { device_printf(sc->bge_dev, "could not allocate RX dma tag\n"); @@ -2759,7 +2772,7 @@ case BGE_ASICREV_BCM5714_A0: case BGE_ASICREV_BCM5780: case BGE_ASICREV_BCM5714: - sc->bge_flags |= BGE_FLAG_5714_FAMILY /* | BGE_FLAG_JUMBO */; + sc->bge_flags |= BGE_FLAG_5714_FAMILY | BGE_FLAG_JUMBO_STD; /* FALLTHROUGH */ case BGE_ASICREV_BCM5750: case BGE_ASICREV_BCM5752: @@ -3560,7 +3573,8 @@ sc->bge_cdata.bge_rx_return_ring_map, BUS_DMASYNC_POSTREAD); bus_dmamap_sync(sc->bge_cdata.bge_rx_std_ring_tag, sc->bge_cdata.bge_rx_std_ring_map, BUS_DMASYNC_POSTWRITE); - if (ifp->if_mtu + ETHER_HDR_LEN + ETHER_CRC_LEN + ETHER_VLAN_ENCAP_LEN > + if (BGE_IS_JUMBO_CAPABLE(sc) && + ifp->if_mtu + ETHER_HDR_LEN + ETHER_CRC_LEN + ETHER_VLAN_ENCAP_LEN > (MCLBYTES - ETHER_ALIGN)) bus_dmamap_sync(sc->bge_cdata.bge_rx_jumbo_ring_tag, sc->bge_cdata.bge_rx_jumbo_ring_map, BUS_DMASYNC_POSTWRITE); @@ -4689,7 +4703,8 @@ } /* Init jumbo RX ring. */ - if (ifp->if_mtu + ETHER_HDR_LEN + ETHER_CRC_LEN + ETHER_VLAN_ENCAP_LEN > + if (BGE_IS_JUMBO_CAPABLE(sc) && + ifp->if_mtu + ETHER_HDR_LEN + ETHER_CRC_LEN + ETHER_VLAN_ENCAP_LEN > (MCLBYTES - ETHER_ALIGN)) { if (bge_init_rx_ring_jumbo(sc) != 0) { device_printf(sc->bge_dev, @@ -4914,14 +4929,19 @@ switch (command) { case SIOCSIFMTU: + if (BGE_IS_JUMBO_CAPABLE(sc) || + (sc->bge_flags & BGE_FLAG_JUMBO_STD)) { + if (ifr->ifr_mtu < ETHERMIN || + ifr->ifr_mtu > BGE_JUMBO_MTU) { + error = EINVAL; + break; + } + } else if (ifr->ifr_mtu < ETHERMIN || ifr->ifr_mtu > ETHERMTU) { + error = EINVAL; + break; + } BGE_LOCK(sc); - if (ifr->ifr_mtu < ETHERMIN || - ((BGE_IS_JUMBO_CAPABLE(sc)) && - ifr->ifr_mtu > BGE_JUMBO_MTU) || - ((!BGE_IS_JUMBO_CAPABLE(sc)) && - ifr->ifr_mtu > ETHERMTU)) - error = EINVAL; - else if (ifp->if_mtu != ifr->ifr_mtu) { + if (ifp->if_mtu != ifr->ifr_mtu) { ifp->if_mtu = ifr->ifr_mtu; if (ifp->if_drv_flags & IFF_DRV_RUNNING) { ifp->if_drv_flags &= ~IFF_DRV_RUNNING;