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;