Page MenuHomeFreeBSD

D58738.id186093.diff
No OneTemporary

D58738.id186093.diff

diff --git a/sys/dev/bnxt/bnxt_en/bnxt.h b/sys/dev/bnxt/bnxt_en/bnxt.h
--- a/sys/dev/bnxt/bnxt_en/bnxt.h
+++ b/sys/dev/bnxt/bnxt_en/bnxt.h
@@ -528,6 +528,7 @@
uint16_t active_vfs;
uint16_t registered_vfs;
uint16_t max_vfs;
+ bool iov_attached;
uint16_t max_msix_vfs;
uint32_t max_encap_records;
uint32_t max_decap_records;
diff --git a/sys/dev/bnxt/bnxt_en/bnxt_sriov.h b/sys/dev/bnxt/bnxt_en/bnxt_sriov.h
--- a/sys/dev/bnxt/bnxt_en/bnxt_sriov.h
+++ b/sys/dev/bnxt/bnxt_en/bnxt_sriov.h
@@ -77,6 +77,7 @@
struct iflib_dma_info hwrm_cmd_req;
uint16_t trusted;
bool spoofchk;
+ bool configured;
};
struct bnxt_resc_map {
@@ -92,6 +93,8 @@
int bnxt_iov_init(if_ctx_t ctx, uint16_t num_vfs, const nvlist_t *params);
void bnxt_iov_uninit(if_ctx_t ctx);
int bnxt_iov_vf_add(if_ctx_t ctx, uint16_t vfnum, const nvlist_t *params);
+struct if_vf_status;
+int bnxt_vf_status(if_ctx_t ctx, struct if_vf_status **statusp);
int bnxt_hwrm_func_vf_resource_free(struct bnxt_softc *softc, int num_vfs);
void bnxt_free_vf_resources(struct bnxt_softc *softc);
int bnxt_create_trusted_vf_sysctls(struct bnxt_softc *softc, uint16_t num_vfs);
diff --git a/sys/dev/bnxt/bnxt_en/bnxt_sriov.c b/sys/dev/bnxt/bnxt_en/bnxt_sriov.c
--- a/sys/dev/bnxt/bnxt_en/bnxt_sriov.c
+++ b/sys/dev/bnxt/bnxt_en/bnxt_sriov.c
@@ -9,6 +9,8 @@
#ifdef PCI_IOV
+#include <net/if_vf_status.h>
+
static int
bnxt_set_vf_admin_mac(struct bnxt_softc *softc, struct bnxt_vf_info *vf,
const uint8_t *mac)
@@ -71,28 +73,127 @@
{
struct bnxt_softc *softc = iflib_get_softc(ctx);
struct bnxt_vf_info *vf = &softc->pf.vf[vfnum];
+ uint8_t admin_mac[ETHER_ADDR_LEN];
+ bool has_admin_mac;
int rc;
+ BNXT_SRIOV_LOCK(softc);
vf->fw_fid = softc->pf.first_vf_id + vfnum;
vf->vfnum = vfnum;
+ has_admin_mac = bnxt_vf_parse_schema(softc, vf, params);
+ memcpy(admin_mac, vf->mac_addr, sizeof(admin_mac));
+ BNXT_SRIOV_UNLOCK(softc);
/*
* If the schema provided a valid admin MAC, program it into firmware.
*/
- if (bnxt_vf_parse_schema(softc, vf, params)) {
- rc = bnxt_set_vf_admin_mac(softc, vf, vf->mac_addr);
- if (rc)
+ if (has_admin_mac) {
+ rc = bnxt_set_vf_admin_mac(softc, vf, admin_mac);
+ if (rc) {
device_printf(softc->dev,
"vf%u: PF-assigned MAC programming failed (rc=%d), falling back to firmware/default MAC\n",
vfnum, rc);
+ BNXT_SRIOV_LOCK(softc);
+ memset(vf->mac_addr, 0, ETHER_ADDR_LEN);
+ BNXT_SRIOV_UNLOCK(softc);
+ }
}
(void)bnxt_set_vf_trust(softc, vfnum, vf->trusted);
(void)bnxt_set_vf_spoofchk(softc, vfnum, vf->spoofchk);
+ BNXT_SRIOV_LOCK(softc);
+ if (softc->pf.num_vfs != 0 && vfnum < softc->pf.num_vfs)
+ softc->pf.vf[vfnum].configured = true;
+ BNXT_SRIOV_UNLOCK(softc);
+
return 0;
}
+int
+bnxt_vf_status(if_ctx_t ctx, struct if_vf_status **statusp)
+{
+ struct bnxt_vf_status {
+ u8 mac[ETHER_ADDR_LEN];
+ u16 tx_queue_count;
+ u16 rx_queue_count;
+ bool mac_valid;
+ bool configured;
+ bool allow_set_mac;
+ bool mac_anti_spoof;
+ bool allow_promisc;
+ } snapshot[BNXT_MAX_VFS];
+ struct bnxt_softc *softc;
+ struct bnxt_vf_info *vf;
+ struct if_vf_info *info;
+ struct if_vf_status *status;
+ u16 num_vfs;
+ int i;
+
+ softc = iflib_get_softc(ctx);
+ /* The iflib context lock serializes this with IOV init and uninit. */
+ if (!BNXT_PF(softc) || !softc->pf.iov_attached)
+ return (EOPNOTSUPP);
+ if (softc->pf.num_vfs == 0) {
+ status = if_vf_status_alloc(0);
+ if (status == NULL)
+ return (ENOMEM);
+ *statusp = status;
+ return (0);
+ }
+ BNXT_SRIOV_LOCK(softc);
+ num_vfs = softc->pf.num_vfs;
+ MPASS(num_vfs <= BNXT_MAX_VFS);
+ memset(snapshot, 0, sizeof(snapshot));
+ for (i = 0; i < num_vfs; i++) {
+ vf = &softc->pf.vf[i];
+ if (is_valid_ether_addr(vf->vf_mac_addr)) {
+ memcpy(snapshot[i].mac, vf->vf_mac_addr,
+ ETHER_ADDR_LEN);
+ snapshot[i].mac_valid = true;
+ } else if (is_valid_ether_addr(vf->mac_addr)) {
+ memcpy(snapshot[i].mac, vf->mac_addr, ETHER_ADDR_LEN);
+ snapshot[i].mac_valid = true;
+ }
+ snapshot[i].tx_queue_count = vf->min_tx_rings;
+ snapshot[i].rx_queue_count = vf->min_rx_rings;
+ snapshot[i].configured = vf->configured;
+ snapshot[i].allow_set_mac =
+ (vf->flags & BNXT_VF_TRUST) != 0 ||
+ !is_valid_ether_addr(vf->mac_addr);
+ snapshot[i].mac_anti_spoof =
+ (vf->flags & BNXT_VF_SPOOFCHK) != 0;
+ snapshot[i].allow_promisc =
+ (vf->flags & BNXT_VF_TRUST) != 0;
+ }
+ BNXT_SRIOV_UNLOCK(softc);
+
+ status = if_vf_status_alloc(num_vfs);
+ if (status == NULL)
+ return (ENOMEM);
+ for (i = 0; i < num_vfs; i++) {
+ info = &status->vfs[i];
+ info->fields = IFVF_F_CONFIGURED | IFVF_F_ALLOW_SET_MAC |
+ IFVF_F_MAC_ANTI_SPOOF |
+ IFVF_F_ALLOW_PROMISC;
+ info->index = i;
+ info->configured = snapshot[i].configured;
+ if (snapshot[i].mac_valid) {
+ memcpy(info->mac, snapshot[i].mac, sizeof(info->mac));
+ info->fields |= IFVF_F_MAC;
+ }
+ info->tx_queue_count = snapshot[i].tx_queue_count;
+ info->rx_queue_count = snapshot[i].rx_queue_count;
+ info->fields |= IFVF_F_NUM_TX_QUEUES |
+ IFVF_F_NUM_RX_QUEUES;
+ info->allow_set_mac = snapshot[i].allow_set_mac;
+ info->mac_anti_spoof = snapshot[i].mac_anti_spoof;
+ info->allow_promisc = snapshot[i].allow_promisc;
+ }
+ *statusp = status;
+ return (0);
+}
+
/* Free driver-side VF resources (called after hwrm_vf_resc_free) */
void bnxt_free_vf_resources(struct bnxt_softc *softc)
{
@@ -188,16 +289,22 @@
{
struct hwrm_func_cfg_input req = {0};
struct bnxt_vf_info *vf;
+ u32 flags;
int rc;
bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_FUNC_CFG);
+ BNXT_SRIOV_LOCK(softc);
vf = &softc->pf.vf[vf_id];
req.fid = cpu_to_le16(vf->fw_fid);
-
- if (is_valid_ether_addr(vf->mac_addr)) {
- req.enables |= cpu_to_le32(HWRM_FUNC_CFG_INPUT_ENABLES_DFLT_MAC_ADDR);
+ if (is_valid_ether_addr(vf->vf_mac_addr)) {
+ req.enables |= cpu_to_le32(
+ HWRM_FUNC_CFG_INPUT_ENABLES_DFLT_MAC_ADDR);
+ memcpy(req.dflt_mac_addr, vf->vf_mac_addr, ETHER_ADDR_LEN);
+ } else if (is_valid_ether_addr(vf->mac_addr)) {
+ req.enables |= cpu_to_le32(
+ HWRM_FUNC_CFG_INPUT_ENABLES_DFLT_MAC_ADDR);
memcpy(req.dflt_mac_addr, vf->mac_addr, ETHER_ADDR_LEN);
}
@@ -206,8 +313,19 @@
req.dflt_vlan = cpu_to_le16(vf->vlan);
}
- if (vf->flags & BNXT_VF_TRUST)
- req.flags = cpu_to_le32(HWRM_FUNC_CFG_INPUT_FLAGS_TRUSTED_VF_ENABLE);
+ flags = 0;
+ if (softc->fw_cap & BNXT_FW_CAP_TRUSTED_VF) {
+ flags |= vf->flags & BNXT_VF_TRUST ?
+ HWRM_FUNC_CFG_INPUT_FLAGS_TRUSTED_VF_ENABLE :
+ HWRM_FUNC_CFG_INPUT_FLAGS_TRUSTED_VF_DISABLE;
+ }
+ if (softc->hwrm_spec_code >= 0x10701) {
+ flags |= vf->flags & BNXT_VF_SPOOFCHK ?
+ HWRM_FUNC_CFG_INPUT_FLAGS_SRC_MAC_ADDR_CHECK_ENABLE :
+ HWRM_FUNC_CFG_INPUT_FLAGS_SRC_MAC_ADDR_CHECK_DISABLE;
+ }
+ BNXT_SRIOV_UNLOCK(softc);
+ req.flags = cpu_to_le32(flags);
BNXT_HWRM_LOCK(softc);
rc = _hwrm_send_message(softc, &req, sizeof(req));
@@ -363,7 +481,8 @@
}
static int
-bnxt_hwrm_set_trusted_vf(struct bnxt_softc *softc, struct bnxt_vf_info *vf)
+bnxt_hwrm_set_trusted_vf(struct bnxt_softc *softc, struct bnxt_vf_info *vf,
+ bool trusted)
{
struct hwrm_func_cfg_input req = {0};
int rc;
@@ -375,7 +494,7 @@
req.fid = htole16(vf->fw_fid);
- if (vf->flags & BNXT_VF_TRUST)
+ if (trusted)
req.flags = cpu_to_le32(HWRM_FUNC_CFG_INPUT_FLAGS_TRUSTED_VF_ENABLE);
else
req.flags = cpu_to_le32(HWRM_FUNC_CFG_INPUT_FLAGS_TRUSTED_VF_DISABLE);
@@ -402,14 +521,9 @@
}
vf = &softc->pf.vf[vf_id];
- if (trusted)
- vf->flags |= BNXT_VF_TRUST;
- else
- vf->flags &= ~BNXT_VF_TRUST;
-
BNXT_SRIOV_UNLOCK(softc);
- rc = bnxt_hwrm_set_trusted_vf(softc, vf);
+ rc = bnxt_hwrm_set_trusted_vf(softc, vf, trusted);
if (rc == 0) {
BNXT_SRIOV_LOCK(softc);
if (softc->pf.num_vfs != 0 && vf_id < softc->pf.num_vfs) {
@@ -430,6 +544,8 @@
u32 msg_size = sizeof(struct hwrm_func_vf_cfg_input);
struct hwrm_func_vf_cfg_input *req =
(struct hwrm_func_vf_cfg_input *)vf->hwrm_cmd_req_addr;
+ u8 mac[ETHER_ADDR_LEN];
+ int rc;
/* Allow VF to set a valid MAC address, if trust is set to on or
* if the PF assigned MAC address is zero
@@ -441,8 +557,14 @@
if (is_valid_ether_addr(req->dflt_mac_addr) &&
(trust || !is_valid_ether_addr(vf->mac_addr) ||
ether_addr_equal(req->dflt_mac_addr, vf->mac_addr))) {
- ether_addr_copy(vf->vf_mac_addr, req->dflt_mac_addr);
- return bnxt_hwrm_exec_fwd_resp(softc, vf, msg_size);
+ ether_addr_copy(mac, req->dflt_mac_addr);
+ rc = bnxt_hwrm_exec_fwd_resp(softc, vf, msg_size);
+ if (rc == 0) {
+ BNXT_SRIOV_LOCK(softc);
+ ether_addr_copy(vf->vf_mac_addr, mac);
+ BNXT_SRIOV_UNLOCK(softc);
+ }
+ return (rc);
}
return bnxt_hwrm_fwd_err_resp(softc, vf, msg_size);
}
@@ -607,6 +729,9 @@
struct hwrm_func_cfg_input req = {0};
int rc = 0;
+ if (sc->hwrm_spec_code < 0x10701)
+ return (EOPNOTSUPP);
+
bnxt_hwrm_cmd_hdr_init(sc, &req, HWRM_FUNC_CFG);
req.fid = htole16(vf->fw_fid);
@@ -973,6 +1098,8 @@
rc = pci_iov_attach(dev, pf_schema, vf_schema);
if (rc)
device_printf(dev, "Failed to initialize SR-IOV (error=%d)\n", rc);
+ else
+ softc->pf.iov_attached = true;
}
#else
diff --git a/sys/dev/bnxt/bnxt_en/if_bnxt.c b/sys/dev/bnxt/bnxt_en/if_bnxt.c
--- a/sys/dev/bnxt/bnxt_en/if_bnxt.c
+++ b/sys/dev/bnxt/bnxt_en/if_bnxt.c
@@ -377,6 +377,7 @@
DEVMETHOD(ifdi_iov_init, bnxt_iov_init),
DEVMETHOD(ifdi_iov_uninit, bnxt_iov_uninit),
DEVMETHOD(ifdi_iov_vf_add, bnxt_iov_vf_add),
+ DEVMETHOD(ifdi_vf_status, bnxt_vf_status),
#endif
DEVMETHOD_END
};

File Metadata

Mime Type
text/plain
Expires
Sun, Oct 4, 12:27 AM (4 h, 9 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
40053484
Default Alt Text
D58738.id186093.diff (9 KB)

Event Timeline