The branch main has been updated by kbowling: URL: https://cgit.FreeBSD.org/src/commit/?id=505e6bb93f80fa3a7799cd88b0d0cafcaa468491
commit 505e6bb93f80fa3a7799cd88b0d0cafcaa468491 Author: Kevin Bowling <[email protected]> AuthorDate: 2026-08-11 17:38:15 +0000 Commit: Kevin Bowling <[email protected]> CommitDate: 2026-08-11 20:59:32 +0000 igbv: Accept reset NACKs when no MAC is assigned A reset NACK from a Linux PF means that the reset completed but no permanent MAC address was assigned. Treat that response as a successful reset with a zero permanent address so attach can generate a local address instead of retrying a live mailbox. FreeBSD PFs also use a one-dword reset NACK while retained queues are being sanitized. Seed the otherwise unused request payload and accept only the three-dword, zero-filled NACK used by Linux, preserving the FreeBSD retry contract. MFC after: 2 weeks --- sys/dev/e1000/e1000_vf.c | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/sys/dev/e1000/e1000_vf.c b/sys/dev/e1000/e1000_vf.c index 70c5f23fea0b..9528ab6009cb 100644 --- a/sys/dev/e1000/e1000_vf.c +++ b/sys/dev/e1000/e1000_vf.c @@ -260,7 +260,7 @@ static s32 e1000_reset_hw_vf(struct e1000_hw *hw) struct e1000_mbx_info *mbx = &hw->mbx; u32 timeout = E1000_VF_INIT_TIMEOUT; s32 ret_val = -E1000_ERR_MAC_INIT; - u32 ctrl, msgbuf[3]; + u32 ctrl, msgbuf[3] = { E1000_VF_RESET, ~0U, ~0U }; u8 *addr = (u8 *)(&msgbuf[1]); DEBUGFUNC("e1000_reset_hw_vf"); @@ -281,8 +281,13 @@ static s32 e1000_reset_hw_vf(struct e1000_hw *hw) /* mailbox timeout can now become active */ mbx->timeout = E1000_VF_MBX_INIT_TIMEOUT; - msgbuf[0] = E1000_VF_RESET; - ret_val = mbx->ops.write_posted(hw, msgbuf, 1, 0); + /* + * Linux PFs return a three-dword, zero-filled NACK when the reset + * completed without an assigned MAC address. FreeBSD PFs also use a + * one-dword NACK while retained queues are still being sanitized. Seed + * the unused request payload so the two responses remain distinguishable. + */ + ret_val = mbx->ops.write_posted(hw, msgbuf, 3, 0); if (ret_val) return ret_val; @@ -291,10 +296,20 @@ static s32 e1000_reset_hw_vf(struct e1000_hw *hw) /* set our "perm_addr" based on info provided by PF */ ret_val = mbx->ops.read_posted(hw, msgbuf, 3, 0); if (!ret_val) { - if (msgbuf[0] == (E1000_VF_RESET | E1000_VT_MSGTYPE_ACK)) - memcpy(hw->mac.perm_addr, addr, 6); - else + switch (msgbuf[0]) { + case E1000_VF_RESET | E1000_VT_MSGTYPE_ACK: + memcpy(hw->mac.perm_addr, addr, ETHER_ADDR_LEN); + break; + case E1000_VF_RESET | E1000_VT_MSGTYPE_NACK: + if (msgbuf[1] == 0 && msgbuf[2] == 0) + memset(hw->mac.perm_addr, 0, ETHER_ADDR_LEN); + else + ret_val = -E1000_ERR_MAC_INIT; + break; + default: ret_val = -E1000_ERR_MAC_INIT; + break; + } } return ret_val;
