Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F174411810
D58738.id186093.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
9 KB
Referenced Files
None
Subscribers
None
D58738.id186093.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D58738: bnxt: Report SR-IOV VF status
Attached
Detach File
Event Timeline
Log In to Comment