Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 24 Nov 2020 00:27:21 +0000 (UTC)
From:      Navdeep Parhar <np@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org
Subject:   svn commit: r367973 - in stable/12/sys/dev/cxgbe: . common
Message-ID:  <202011240027.0AO0RLAU069250@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
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);
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202011240027.0AO0RLAU069250>