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:
parent
b54ed68408
commit
de0a3472d8
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=367502
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user