diff options
author | Navdeep Parhar <np@FreeBSD.org> | 2020-11-09 00:01:13 +0000 |
---|---|---|
committer | Navdeep Parhar <np@FreeBSD.org> | 2020-11-09 00:01:13 +0000 |
commit | dc0800a9ad8e63d15d6d6a67d5ae3c923bc0f56f (patch) | |
tree | fc7be161c68192369f3b835d3bdd174c5aca1bad | |
parent | 8801df34f0f3a0655d8952be97f22faaf9a5253d (diff) | |
download | src-dc0800a9ad8e63d15d6d6a67d5ae3c923bc0f56f.tar.gz src-dc0800a9ad8e63d15d6d6a67d5ae3c923bc0f56f.zip |
cxgbev(4): Use the MAC address set by the the PF if there is one.
Query the firmware for the MAC address set by the PF for the VF and use
it instead of the firmware generated MAC if it's available.
MFC after: 2 weeks
Sponsored by: Chelsio Communications
Notes
Notes:
svn path=/head/; revision=367497
-rw-r--r-- | sys/dev/cxgbe/common/common.h | 2 | ||||
-rw-r--r-- | sys/dev/cxgbe/common/t4vf_hw.c | 46 | ||||
-rw-r--r-- | sys/dev/cxgbe/t4_vf.c | 13 |
3 files changed, 60 insertions, 1 deletions
diff --git a/sys/dev/cxgbe/common/common.h b/sys/dev/cxgbe/common/common.h index 820e4e10daff..c502d068f0f7 100644 --- a/sys/dev/cxgbe/common/common.h +++ b/sys/dev/cxgbe/common/common.h @@ -912,6 +912,8 @@ int t4vf_get_sge_params(struct adapter *adapter); int t4vf_get_rss_glb_config(struct adapter *adapter); int t4vf_get_vfres(struct adapter *adapter); int t4vf_prep_adapter(struct adapter *adapter); +int t4vf_get_vf_mac(struct adapter *adapter, unsigned int port, + unsigned int *naddr, u8 *addr); int t4_bar2_sge_qregs(struct adapter *adapter, unsigned int qid, enum t4_bar2_qtype qtype, int user, u64 *pbar2_qoffset, unsigned int *pbar2_qid); diff --git a/sys/dev/cxgbe/common/t4vf_hw.c b/sys/dev/cxgbe/common/t4vf_hw.c index 009f34b63eeb..171c4512e4c3 100644 --- a/sys/dev/cxgbe/common/t4vf_hw.c +++ b/sys/dev/cxgbe/common/t4vf_hw.c @@ -382,3 +382,49 @@ int t4vf_prep_adapter(struct adapter *adapter) return 0; } + +/* + * t4vf_get_vf_mac - Get the MAC address to be set to the VI of this VF. + * @adapter: The adapter + * @port: The port associated with vf + * @naddr: the number of ACL MAC addresses returned in addr + * @addr: Placeholder for MAC addresses + * + * Find the MAC address to be set to the VF's VI. The requested MAC address + * is from the host OS via callback in the PF driver. + */ +int t4vf_get_vf_mac(struct adapter *adapter, unsigned int port, + unsigned int *naddr, u8 *addr) +{ + struct fw_acl_mac_cmd cmd; + int ret; + + 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_READ); + cmd.en_to_len16 = cpu_to_be32((unsigned int)FW_LEN16(cmd)); + ret = t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), &cmd); + if (ret) + return ret; + + if (cmd.nmac < *naddr) + *naddr = cmd.nmac; + + switch (port) { + case 3: + memcpy(addr, cmd.macaddr3, sizeof(cmd.macaddr3)); + break; + case 2: + memcpy(addr, cmd.macaddr2, sizeof(cmd.macaddr2)); + break; + case 1: + memcpy(addr, cmd.macaddr1, sizeof(cmd.macaddr1)); + break; + case 0: + memcpy(addr, cmd.macaddr0, sizeof(cmd.macaddr0)); + break; + } + + return ret; +} diff --git a/sys/dev/cxgbe/t4_vf.c b/sys/dev/cxgbe/t4_vf.c index ec5d528184f3..4c51f89d36ba 100644 --- a/sys/dev/cxgbe/t4_vf.c +++ b/sys/dev/cxgbe/t4_vf.c @@ -481,7 +481,7 @@ static int t4vf_attach(device_t dev) { struct adapter *sc; - int rc = 0, i, j, rqidx, tqidx; + int rc = 0, i, j, rqidx, tqidx, n, p, pmask; struct make_dev_args mda; struct intrs_and_queues iaq; struct sge *s; @@ -618,8 +618,10 @@ t4vf_attach(device_t dev) * First pass over all the ports - allocate VIs and initialize some * basic parameters like mac address, port type, etc. */ + pmask = sc->params.vfres.pmask; for_each_port(sc, i) { struct port_info *pi; + uint8_t mac[ETHER_ADDR_LEN]; pi = malloc(sizeof(*pi), M_CXGBE, M_ZERO | M_WAITOK); sc->port[i] = pi; @@ -645,6 +647,15 @@ t4vf_attach(device_t dev) goto done; } + /* Prefer the MAC address set by the PF, if there is one. */ + n = 1; + p = ffs(pmask) - 1; + MPASS(p >= 0); + rc = t4vf_get_vf_mac(sc, p, &n, mac); + if (rc == 0 && n == 1) + t4_os_set_hw_addr(pi, mac); + pmask &= ~(1 << p); + /* No t4_link_start. */ snprintf(pi->lockname, sizeof(pi->lockname), "%sp%d", |