Apply by doing: cd /usr/src patch -p0 < 007_vio.patch Then build and install a new kernel. Index: sys/dev/pci/if_vio.c =================================================================== RCS file: /cvs/src/sys/dev/pci/if_vio.c,v retrieving revision 1.9 retrieving revision 1.9.2.2 diff -u -p -r1.9 -r1.9.2.2 --- sys/dev/pci/if_vio.c 5 Dec 2012 23:20:20 -0000 1.9 +++ sys/dev/pci/if_vio.c 30 May 2013 21:52:12 -0000 1.9.2.2 @@ -232,11 +232,13 @@ struct vio_softc { ((sc)->sc_hdr_size == sizeof(struct virtio_net_hdr)) #define VIRTIO_NET_TX_MAXNSEGS 16 /* for larger chains, defrag */ -#define VIRTIO_NET_CTRL_MAC_MAXENTRIES 64 /* for more entries, use ALLMULTI */ +#define VIRTIO_NET_CTRL_MAC_MC_ENTRIES 64 /* for more entries, use ALLMULTI */ +#define VIRTIO_NET_CTRL_MAC_UC_ENTRIES 1 /* one entry for own unicast addr */ #define VIO_CTRL_MAC_INFO_SIZE \ (2*sizeof(struct virtio_net_ctrl_mac_tbl) + \ - (VIRTIO_NET_CTRL_MAC_MAXENTRIES + 1) * ETHER_ADDR_LEN) + (VIRTIO_NET_CTRL_MAC_MC_ENTRIES + \ + VIRTIO_NET_CTRL_MAC_UC_ENTRIES) * ETHER_ADDR_LEN) /* cfattach interface functions */ int vio_match(struct device *, void *, void *); @@ -391,9 +393,7 @@ vio_alloc_mem(struct vio_softc *sc) allocsize += sizeof(struct virtio_net_ctrl_cmd) * 1; allocsize += sizeof(struct virtio_net_ctrl_status) * 1; allocsize += sizeof(struct virtio_net_ctrl_rx) * 1; - allocsize += sizeof(struct virtio_net_ctrl_mac_tbl) - + sizeof(struct virtio_net_ctrl_mac_tbl) - + ETHER_ADDR_LEN * VIRTIO_NET_CTRL_MAC_MAXENTRIES; + allocsize += VIO_CTRL_MAC_INFO_SIZE; } sc->sc_dma_size = allocsize; @@ -413,7 +413,8 @@ vio_alloc_mem(struct vio_softc *sc) sc->sc_ctrl_rx = (void*)(kva + offset); offset += sizeof(*sc->sc_ctrl_rx); sc->sc_ctrl_mac_tbl_uc = (void*)(kva + offset); - offset += sizeof(*sc->sc_ctrl_mac_tbl_uc); + offset += sizeof(*sc->sc_ctrl_mac_tbl_uc) + + ETHER_ADDR_LEN * VIRTIO_NET_CTRL_MAC_UC_ENTRIES; sc->sc_ctrl_mac_tbl_mc = (void*)(kva + offset); } @@ -742,6 +743,10 @@ again: break; } IFQ_DEQUEUE(&ifp->if_snd, m); + if (m != sc->sc_tx_mbufs[slot]) { + m_freem(m); + m = sc->sc_tx_mbufs[slot]; + } hdr = &sc->sc_tx_hdrs[slot]; memset(hdr, 0, sc->sc_hdr_size); @@ -1113,7 +1118,6 @@ vio_encap(struct vio_softc *sc, int slot r); return ENOBUFS; } - m_freem(m); *mnew = m0; return 0; } @@ -1342,7 +1346,7 @@ vio_iff(struct vio_softc *sc) } if (ifp->if_flags & IFF_PROMISC || ac->ac_multirangecnt > 0 || - ac->ac_multicnt >= VIRTIO_NET_CTRL_MAC_MAXENTRIES) { + ac->ac_multicnt >= VIRTIO_NET_CTRL_MAC_MC_ENTRIES) { ifp->if_flags |= IFF_ALLMULTI; if (ifp->if_flags & IFF_PROMISC) promisc = 1;