diff --git a/sys/dev/cxgbe/t4_iov.c b/sys/dev/cxgbe/t4_iov.c --- a/sys/dev/cxgbe/t4_iov.c +++ b/sys/dev/cxgbe/t4_iov.c @@ -29,8 +29,12 @@ #include #include #include +#include #include +#include #include +#include +#include #ifdef PCI_IOV #include @@ -257,6 +261,7 @@ pf_schema = pci_iov_schema_alloc_node(); vf_schema = pci_iov_schema_alloc_node(); pci_iov_schema_add_unicast_mac(vf_schema, "mac-addr", 0, NULL); + pci_iov_schema_add_vlan(vf_schema, "vlan", 0, 0); error = pci_iov_attach_name(dev, pf_schema, vf_schema, "%s", device_get_nameunit(pdev)); if (error) { @@ -336,14 +341,15 @@ size_t size; int rc; + sc = device_get_softc(dev); + MPASS(sc->sc_attached); + MPASS(sc->sc_main != NULL); + adap = device_get_softc(sc->sc_main); + if (nvlist_exists_binary(config, "mac-addr")) { mac = nvlist_get_binary(config, "mac-addr", &size); bcopy(mac, ma, ETHER_ADDR_LEN); - sc = device_get_softc(dev); - MPASS(sc->sc_attached); - MPASS(sc->sc_main != NULL); - adap = device_get_softc(sc->sc_main); if (begin_synchronized_op(adap, NULL, SLEEP_OK | INTR_OK, "t4vfma") != 0) return (ENXIO); @@ -358,6 +364,29 @@ } } + if (nvlist_exists_number(config, "vlan")) { + uint16_t vlan = nvlist_get_number(config, "vlan"); + + /* We can't restrict to VID 0 */ + if (vlan == DOT1Q_VID_NULL) + return (ENOTSUP); + + if (vlan == VF_VLAN_TRUNK) + vlan = DOT1Q_VID_NULL; + + if (begin_synchronized_op(adap, NULL, SLEEP_OK | INTR_OK, + "t4vfma") != 0) + return (ENXIO); + rc = t4_set_vlan_acl(adap, adap->mbox, vfnum + 1, vlan); + end_synchronized_op(adap, 0); + if (rc != 0) { + device_printf(dev, + "Failed to set VF%d VLAN to %d, rc = %d\n", + vfnum, vlan, rc); + return (rc); + } + } + return (0); } #endif