From 1389314d53531e06c7ec02406b0addf7d77e7db7 Mon Sep 17 00:00:00 2001 From: Kristof Provost Date: Thu, 30 May 2024 15:59:09 +0200 Subject: [PATCH] cxgbe: handle vlan PF restrictions Co-Authored-by: Navdeep Parhar MFC after: 2 weeks Sponsored by: Orange Business Services Differential Revision: https://reviews.freebsd.org/D45428 --- sys/dev/cxgbe/common/t4_hw.c | 7 ++++--- sys/dev/cxgbe/t4_iov.c | 37 ++++++++++++++++++++++++++++++++---- 2 files changed, 37 insertions(+), 7 deletions(-) diff --git a/sys/dev/cxgbe/common/t4_hw.c b/sys/dev/cxgbe/common/t4_hw.c index 3d22673d34c1..07940a44f66e 100644 --- a/sys/dev/cxgbe/common/t4_hw.c +++ b/sys/dev/cxgbe/common/t4_hw.c @@ -11377,7 +11377,7 @@ int t4_configure_ringbb(struct adapter *adap) * @vlan: The vlanid to be set * */ -int t4_set_vlan_acl(struct adapter *adap, unsigned int mbox, unsigned int vf, +int t4_set_vlan_acl(struct adapter *adap, unsigned int pf, unsigned int vf, u16 vlan) { struct fw_acl_vlan_cmd vlan_cmd; @@ -11389,9 +11389,10 @@ int t4_set_vlan_acl(struct adapter *adap, unsigned int mbox, unsigned int vf, F_FW_CMD_REQUEST | F_FW_CMD_WRITE | F_FW_CMD_EXEC | - V_FW_ACL_VLAN_CMD_PFN(adap->pf) | + V_FW_ACL_VLAN_CMD_PFN(pf) | V_FW_ACL_VLAN_CMD_VFN(vf)); - vlan_cmd.en_to_len16 = cpu_to_be32(enable | FW_LEN16(vlan_cmd)); + vlan_cmd.en_to_len16 = cpu_to_be32(enable | FW_LEN16(vlan_cmd) | + V_FW_ACL_VLAN_CMD_PMASK(1 << pf)); /* Drop all packets that donot match vlan id */ vlan_cmd.dropnovlan_fm = (enable ? (F_FW_ACL_VLAN_CMD_DROPNOVLAN | diff --git a/sys/dev/cxgbe/t4_iov.c b/sys/dev/cxgbe/t4_iov.c index 7b5e0cb1af4e..eef41d6398df 100644 --- 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 @@ t4iov_attach_child(device_t dev) 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 @@ t4iov_add_vf(device_t dev, uint16_t vfnum, const struct nvlist *config) 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 @@ t4iov_add_vf(device_t dev, uint16_t vfnum, const struct nvlist *config) } } + 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, + "t4vfvl") != 0) + return (ENXIO); + rc = t4_set_vlan_acl(adap, sc->pf, 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