Author: np
Date: Tue Nov 24 00:27:21 2020
New Revision: 367973
URL: https://svnweb.freebsd.org/changeset/base/367973

Log:
  MFC r367502:
  
  cxgbe(4): Allow the PF driver to set a VF's MAC address.
  
  The MAC address can be set with the optional mac-addr property in the VF
  section of the iovctl.conf(5) used to instantiate the VFs.
  
  Sponsored by: Chelsio Communications

Modified:
  stable/12/sys/dev/cxgbe/common/common.h
  stable/12/sys/dev/cxgbe/common/t4_hw.c
  stable/12/sys/dev/cxgbe/t4_iov.c
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/sys/dev/cxgbe/common/common.h
==============================================================================
--- stable/12/sys/dev/cxgbe/common/common.h     Tue Nov 24 00:25:03 2020        
(r367972)
+++ stable/12/sys/dev/cxgbe/common/common.h     Tue Nov 24 00:27:21 2020        
(r367973)
@@ -691,6 +691,8 @@ void t4_idma_monitor_init(struct adapter *adapter,
 void t4_idma_monitor(struct adapter *adapter,
                     struct sge_idma_monitor_state *idma,
                     int hz, int ticks);
+int t4_set_vf_mac(struct adapter *adapter, unsigned int pf, unsigned int vf,
+                 unsigned int naddr, u8 *addr);
 
 unsigned int t4_get_regs_len(struct adapter *adapter);
 void t4_get_regs(struct adapter *adap, u8 *buf, size_t buf_size);

Modified: stable/12/sys/dev/cxgbe/common/t4_hw.c
==============================================================================
--- stable/12/sys/dev/cxgbe/common/t4_hw.c      Tue Nov 24 00:25:03 2020        
(r367972)
+++ stable/12/sys/dev/cxgbe/common/t4_hw.c      Tue Nov 24 00:27:21 2020        
(r367973)
@@ -10202,6 +10202,48 @@ void t4_idma_monitor(struct adapter *adapter,
 }
 
 /**
+ *     t4_set_vf_mac - Set MAC address for the specified VF
+ *     @adapter: The adapter
+ *     @pf: the PF used to instantiate the VFs
+ *     @vf: one of the VFs instantiated by the specified PF
+ *     @naddr: the number of MAC addresses
+ *     @addr: the MAC address(es) to be set to the specified VF
+ */
+int t4_set_vf_mac(struct adapter *adapter, unsigned int pf, unsigned int vf,
+                 unsigned int naddr, u8 *addr)
+{
+       struct fw_acl_mac_cmd cmd;
+
+       memset(&cmd, 0, sizeof(cmd));
+       cmd.op_to_vfn = cpu_to_be32(V_FW_CMD_OP(FW_ACL_MAC_CMD) |
+                                   F_FW_CMD_REQUEST |
+                                   F_FW_CMD_WRITE |
+                                   V_FW_ACL_MAC_CMD_PFN(pf) |
+                                   V_FW_ACL_MAC_CMD_VFN(vf));
+
+       /* Note: Do not enable the ACL */
+       cmd.en_to_len16 = cpu_to_be32((unsigned int)FW_LEN16(cmd));
+       cmd.nmac = naddr;
+
+       switch (pf) {
+       case 3:
+               memcpy(cmd.macaddr3, addr, sizeof(cmd.macaddr3));
+               break;
+       case 2:
+               memcpy(cmd.macaddr2, addr, sizeof(cmd.macaddr2));
+               break;
+       case 1:
+               memcpy(cmd.macaddr1, addr, sizeof(cmd.macaddr1));
+               break;
+       case 0:
+               memcpy(cmd.macaddr0, addr, sizeof(cmd.macaddr0));
+               break;
+       }
+
+       return t4_wr_mbox(adapter, adapter->mbox, &cmd, sizeof(cmd), &cmd);
+}
+
+/**
  *     t4_read_pace_tbl - read the pace table
  *     @adap: the adapter
  *     @pace_vals: holds the returned values

Modified: stable/12/sys/dev/cxgbe/t4_iov.c
==============================================================================
--- stable/12/sys/dev/cxgbe/t4_iov.c    Tue Nov 24 00:25:03 2020        
(r367972)
+++ stable/12/sys/dev/cxgbe/t4_iov.c    Tue Nov 24 00:27:21 2020        
(r367973)
@@ -42,12 +42,19 @@ __FBSDID("$FreeBSD$");
 #endif
 
 #include "common/common.h"
+#include "common/t4_regs.h"
 #include "t4_if.h"
 
 struct t4iov_softc {
        device_t sc_dev;
        device_t sc_main;
        bool sc_attached;
+
+       int pf;
+       int regs_rid;
+       struct resource *regs_res;
+       bus_space_handle_t bh;
+       bus_space_tag_t bt;
 };
 
 struct {
@@ -113,6 +120,13 @@ struct {
        {0x6087, "Chelsio T6225-CR 87"},
 };
 
+static inline uint32_t
+t4iov_read_reg(struct t4iov_softc *sc, uint32_t reg)
+{
+
+       return bus_space_read_4(sc->bt, sc->bh, reg);
+}
+
 static int     t4iov_attach_child(device_t dev);
 
 static int
@@ -179,10 +193,28 @@ static int
 t4iov_attach(device_t dev)
 {
        struct t4iov_softc *sc;
+       uint32_t pl_rev, whoami;
 
        sc = device_get_softc(dev);
        sc->sc_dev = dev;
 
+       sc->regs_rid = PCIR_BAR(0);
+       sc->regs_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
+           &sc->regs_rid, RF_ACTIVE);
+       if (sc->regs_res == NULL) {
+               device_printf(dev, "cannot map registers.\n");
+               return (ENXIO);
+       }
+       sc->bt = rman_get_bustag(sc->regs_res);
+       sc->bh = rman_get_bushandle(sc->regs_res);
+
+       pl_rev = t4iov_read_reg(sc, A_PL_REV);
+       whoami = t4iov_read_reg(sc, A_PL_WHOAMI);
+       if (G_CHIPID(pl_rev) <= CHELSIO_T5)
+               sc->pf = G_SOURCEPF(whoami);
+       else
+               sc->pf = G_T6_SOURCEPF(whoami);
+
        sc->sc_main = pci_find_dbsf(pci_get_domain(dev), pci_get_bus(dev),
            pci_get_slot(dev), 4);
        if (sc->sc_main == NULL)
@@ -218,6 +250,7 @@ t4iov_attach_child(device_t dev)
 #ifdef PCI_IOV
        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);
        error = pci_iov_attach_name(dev, pf_schema, vf_schema, "%s",
            device_get_nameunit(pdev));
        if (error) {
@@ -266,6 +299,10 @@ t4iov_detach(device_t dev)
                if (error)
                        return (error);
        }
+       if (sc->regs_res) {
+               bus_release_resource(dev, SYS_RES_MEMORY, sc->regs_rid,
+                   sc->regs_res);
+       }
        return (0);
 }
 
@@ -286,6 +323,34 @@ t4iov_iov_uninit(device_t dev)
 static int
 t4iov_add_vf(device_t dev, uint16_t vfnum, const struct nvlist *config)
 {
+       const void *mac;
+       struct t4iov_softc *sc;
+       struct adapter *adap;
+       uint8_t ma[ETHER_ADDR_LEN];
+       size_t size;
+       int rc;
+
+       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);
+               rc = -t4_set_vf_mac(adap, sc->pf, vfnum + 1, 1, ma);
+               end_synchronized_op(adap, 0);
+               if (rc != 0) {
+                       device_printf(dev,
+                           "Failed to set VF%d MAC address to "
+                           "%02x:%02x:%02x:%02x:%02x:%02x, rc = %d\n", vfnum,
+                           ma[0], ma[1], ma[2], ma[3], ma[4], ma[5], rc);
+                       return (rc);
+               }
+       }
 
        return (0);
 }
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to