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.

MFC after:	2 weeks
Sponsored by:	Chelsio Communications
This commit is contained in:
Navdeep Parhar 2020-11-09 00:08:35 +00:00
parent b54ed68408
commit de0a3472d8
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=367502
3 changed files with 109 additions and 0 deletions

View File

@ -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);

View File

@ -10201,6 +10201,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

View File

@ -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);
}