git: 6f940ca879cb - main - ixgbe: clear VF head write-back state on reset
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 31 Jul 2026 12:14:50 UTC
The branch main has been updated by kbowling:
URL: https://cgit.FreeBSD.org/src/commit/?id=6f940ca879cbf691ddf5605d852770cef27847b2
commit 6f940ca879cbf691ddf5605d852770cef27847b2
Author: Kevin Bowling <kbowling@FreeBSD.org>
AuthorDate: 2026-07-28 11:26:28 +0000
Commit: Kevin Bowling <kbowling@FreeBSD.org>
CommitDate: 2026-07-31 12:14:36 +0000
ixgbe: clear VF head write-back state on reset
VF reset and FLR do not clear the transmit head write-back address
registers. A previous VF driver can therefore leave DMA write-back
enabled with a stale address for the next driver instance.
After consuming the reset request and disabling the VF queues, clear the
address registers for each queue belonging to that VF. Derive the queue
count from the active IOV mode so peer queue state is not touched.
Linux commit dbf231af81a7 documents the hardware behavior. The FreeBSD
implementation follows the local queue mapping and register interfaces.
MFC after: 1 week
---
sys/dev/ixgbe/if_sriov.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/sys/dev/ixgbe/if_sriov.c b/sys/dev/ixgbe/if_sriov.c
index 8d4e20fcf8bf..b9e5205cf1b9 100644
--- a/sys/dev/ixgbe/if_sriov.c
+++ b/sys/dev/ixgbe/if_sriov.c
@@ -353,6 +353,7 @@ ixgbe_vf_reset_msg(struct ixgbe_softc *sc, struct ixgbe_vf *vf, uint32_t *msg)
struct ixgbe_hw *hw;
uint32_t ack;
uint32_t resp[IXGBE_VF_PERMADDR_MSG_LEN];
+ int i, queue_count;
hw = &sc->hw;
@@ -363,6 +364,18 @@ ixgbe_vf_reset_msg(struct ixgbe_softc *sc, struct ixgbe_vf *vf, uint32_t *msg)
*/
ixgbe_clear_mbx(hw, vf->pool);
+ /*
+ * VF reset does not clear the transmit head write-back addresses.
+ * The queues were disabled by ixgbe_process_vf_reset().
+ */
+ queue_count = ixgbe_vf_queues(sc->iov_mode);
+ for (i = 0; i < queue_count; i++) {
+ IXGBE_WRITE_REG(hw,
+ IXGBE_PVFTDWBAHn(queue_count, vf->pool, i), 0);
+ IXGBE_WRITE_REG(hw,
+ IXGBE_PVFTDWBALn(queue_count, vf->pool, i), 0);
+ }
+
if (ixgbe_validate_mac_addr(vf->ether_addr) == 0) {
ixgbe_set_rar(&sc->hw, vf->rar_index, vf->ether_addr,
vf->pool, true);