From d80c12ba682a6f23791f3d6e657f9e603b152aa2 Mon Sep 17 00:00:00 2001 From: Kevin Bowling Date: Thu, 19 Sep 2024 19:18:25 -0700 Subject: [PATCH] Revert "ixgbe: introduce new mailbox API" This is missing the ixgbe_mbx.h changes, revert so it can be committed atomically. This reverts commit 68ba3eabd4869577bf11c03a6ec6f472502be07d. --- sys/dev/ixgbe/if_ix.c | 7 +- sys/dev/ixgbe/ixgbe_82599.c | 4 +- sys/dev/ixgbe/ixgbe_mbx.c | 859 ++++++++++-------------------------- sys/dev/ixgbe/ixgbe_type.h | 32 +- sys/dev/ixgbe/ixgbe_vf.c | 42 +- sys/dev/ixgbe/ixgbe_x540.c | 4 +- 6 files changed, 288 insertions(+), 660 deletions(-) diff --git a/sys/dev/ixgbe/if_ix.c b/sys/dev/ixgbe/if_ix.c index ed41f6b66e0..17f1f73a526 100644 --- a/sys/dev/ixgbe/if_ix.c +++ b/sys/dev/ixgbe/if_ix.c @@ -879,7 +879,6 @@ ixgbe_if_attach_pre(if_ctx_t ctx) struct ixgbe_hw *hw; int error = 0; u32 ctrl_ext; - size_t i; INIT_DEBUGOUT("ixgbe_attach: begin"); @@ -929,10 +928,8 @@ ixgbe_if_attach_pre(if_ctx_t ctx) goto err_pci; } - if (hw->mbx.ops[0].init_params) { - for (i = 0; i < sc->num_vfs; i++) - hw->mbx.ops[i].init_params(hw); - } + if (hw->mbx.ops.init_params) + hw->mbx.ops.init_params(hw); hw->allow_unsupported_sfp = allow_unsupported_sfp; diff --git a/sys/dev/ixgbe/ixgbe_82599.c b/sys/dev/ixgbe/ixgbe_82599.c index 70b4cdc5c6c..8c3df0fd4f5 100644 --- a/sys/dev/ixgbe/ixgbe_82599.c +++ b/sys/dev/ixgbe/ixgbe_82599.c @@ -324,7 +324,6 @@ s32 ixgbe_init_ops_82599(struct ixgbe_hw *hw) struct ixgbe_phy_info *phy = &hw->phy; struct ixgbe_eeprom_info *eeprom = &hw->eeprom; s32 ret_val; - u16 i; DEBUGFUNC("ixgbe_init_ops_82599"); @@ -386,8 +385,7 @@ s32 ixgbe_init_ops_82599(struct ixgbe_hw *hw) mac->arc_subsystem_valid = !!(IXGBE_READ_REG(hw, IXGBE_FWSM_BY_MAC(hw)) & IXGBE_FWSM_MODE_MASK); - for (i = 0; i < 64; i++) - hw->mbx.ops[i].init_params = ixgbe_init_mbx_params_pf; + hw->mbx.ops.init_params = ixgbe_init_mbx_params_pf; /* EEPROM */ eeprom->ops.read = ixgbe_read_eeprom_82599; diff --git a/sys/dev/ixgbe/ixgbe_mbx.c b/sys/dev/ixgbe/ixgbe_mbx.c index 0a0c5abde15..c8f839fce85 100644 --- a/sys/dev/ixgbe/ixgbe_mbx.c +++ b/sys/dev/ixgbe/ixgbe_mbx.c @@ -35,9 +35,6 @@ #include "ixgbe_type.h" #include "ixgbe_mbx.h" -static s32 ixgbe_poll_for_msg(struct ixgbe_hw *hw, u16 mbx_id); -static s32 ixgbe_poll_for_ack(struct ixgbe_hw *hw, u16 mbx_id); - /** * ixgbe_read_mbx - Reads a message from the mailbox * @hw: pointer to the HW structure @@ -50,91 +47,42 @@ static s32 ixgbe_poll_for_ack(struct ixgbe_hw *hw, u16 mbx_id); s32 ixgbe_read_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id) { struct ixgbe_mbx_info *mbx = &hw->mbx; + s32 ret_val = IXGBE_ERR_MBX; DEBUGFUNC("ixgbe_read_mbx"); /* limit read to size of mailbox */ - if (size > mbx->size) { - ERROR_REPORT3(IXGBE_ERROR_ARGUMENT, - "Invalid mailbox message size %u, changing to %u", - size, mbx->size); + if (size > mbx->size) size = mbx->size; - } - if (mbx->ops[mbx_id].read) - return mbx->ops[mbx_id].read(hw, msg, size, mbx_id); - - return IXGBE_ERR_CONFIG; -} - -/** - * ixgbe_poll_mbx - Wait for message and read it from the mailbox - * @hw: pointer to the HW structure - * @msg: The message buffer - * @size: Length of buffer - * @mbx_id: id of mailbox to read - * - * returns SUCCESS if it successfully read message from buffer - **/ -s32 ixgbe_poll_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id) -{ - struct ixgbe_mbx_info *mbx = &hw->mbx; - s32 ret_val; - - DEBUGFUNC("ixgbe_poll_mbx"); - - if (!mbx->ops[mbx_id].read || !mbx->ops[mbx_id].check_for_msg || - !mbx->timeout) - return IXGBE_ERR_CONFIG; - - /* limit read to size of mailbox */ - if (size > mbx->size) { - ERROR_REPORT3(IXGBE_ERROR_ARGUMENT, - "Invalid mailbox message size %u, changing to %u", - size, mbx->size); - size = mbx->size; - } - - ret_val = ixgbe_poll_for_msg(hw, mbx_id); - /* if ack received read message, otherwise we timed out */ - if (!ret_val) - return mbx->ops[mbx_id].read(hw, msg, size, mbx_id); + if (mbx->ops.read) + ret_val = mbx->ops.read(hw, msg, size, mbx_id); return ret_val; } /** - * ixgbe_write_mbx - Write a message to the mailbox and wait for ACK + * ixgbe_write_mbx - Write a message to the mailbox * @hw: pointer to the HW structure * @msg: The message buffer * @size: Length of buffer * @mbx_id: id of mailbox to write * - * returns SUCCESS if it successfully copied message into the buffer and - * received an ACK to that message within specified period + * returns SUCCESS if it successfully copied message into the buffer **/ s32 ixgbe_write_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id) { struct ixgbe_mbx_info *mbx = &hw->mbx; - s32 ret_val = IXGBE_ERR_MBX; + s32 ret_val = IXGBE_SUCCESS; DEBUGFUNC("ixgbe_write_mbx"); - /* - * exit if either we can't write, release - * or there is no timeout defined - */ - if (!mbx->ops[mbx_id].write || !mbx->ops[mbx_id].check_for_ack || - !mbx->ops[mbx_id].release || !mbx->timeout) - return IXGBE_ERR_CONFIG; - if (size > mbx->size) { - ret_val = IXGBE_ERR_PARAM; + ret_val = IXGBE_ERR_MBX; ERROR_REPORT2(IXGBE_ERROR_ARGUMENT, - "Invalid mailbox message size %u", size); - } else { - ret_val = mbx->ops[mbx_id].write(hw, msg, size, mbx_id); - } + "Invalid mailbox message size %d", size); + } else if (mbx->ops.write) + ret_val = mbx->ops.write(hw, msg, size, mbx_id); return ret_val; } @@ -149,12 +97,12 @@ s32 ixgbe_write_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id) s32 ixgbe_check_for_msg(struct ixgbe_hw *hw, u16 mbx_id) { struct ixgbe_mbx_info *mbx = &hw->mbx; - s32 ret_val = IXGBE_ERR_CONFIG; + s32 ret_val = IXGBE_ERR_MBX; DEBUGFUNC("ixgbe_check_for_msg"); - if (mbx->ops[mbx_id].check_for_msg) - ret_val = mbx->ops[mbx_id].check_for_msg(hw, mbx_id); + if (mbx->ops.check_for_msg) + ret_val = mbx->ops.check_for_msg(hw, mbx_id); return ret_val; } @@ -169,12 +117,12 @@ s32 ixgbe_check_for_msg(struct ixgbe_hw *hw, u16 mbx_id) s32 ixgbe_check_for_ack(struct ixgbe_hw *hw, u16 mbx_id) { struct ixgbe_mbx_info *mbx = &hw->mbx; - s32 ret_val = IXGBE_ERR_CONFIG; + s32 ret_val = IXGBE_ERR_MBX; DEBUGFUNC("ixgbe_check_for_ack"); - if (mbx->ops[mbx_id].check_for_ack) - ret_val = mbx->ops[mbx_id].check_for_ack(hw, mbx_id); + if (mbx->ops.check_for_ack) + ret_val = mbx->ops.check_for_ack(hw, mbx_id); return ret_val; } @@ -189,12 +137,12 @@ s32 ixgbe_check_for_ack(struct ixgbe_hw *hw, u16 mbx_id) s32 ixgbe_check_for_rst(struct ixgbe_hw *hw, u16 mbx_id) { struct ixgbe_mbx_info *mbx = &hw->mbx; - s32 ret_val = IXGBE_ERR_CONFIG; + s32 ret_val = IXGBE_ERR_MBX; DEBUGFUNC("ixgbe_check_for_rst"); - if (mbx->ops[mbx_id].check_for_rst) - ret_val = mbx->ops[mbx_id].check_for_rst(hw, mbx_id); + if (mbx->ops.check_for_rst) + ret_val = mbx->ops.check_for_rst(hw, mbx_id); return ret_val; } @@ -213,23 +161,22 @@ static s32 ixgbe_poll_for_msg(struct ixgbe_hw *hw, u16 mbx_id) DEBUGFUNC("ixgbe_poll_for_msg"); - if (!countdown || !mbx->ops[mbx_id].check_for_msg) - return IXGBE_ERR_CONFIG; + if (!countdown || !mbx->ops.check_for_msg) + goto out; - while (countdown && mbx->ops[mbx_id].check_for_msg(hw, mbx_id)) { + while (countdown && mbx->ops.check_for_msg(hw, mbx_id)) { countdown--; if (!countdown) break; usec_delay(mbx->usec_delay); } - if (countdown == 0) { + if (countdown == 0) ERROR_REPORT2(IXGBE_ERROR_POLLING, - "Polling for VF%u mailbox message timedout", mbx_id); - return IXGBE_ERR_TIMEOUT; - } + "Polling for VF%d mailbox message timedout", mbx_id); - return IXGBE_SUCCESS; +out: + return countdown ? IXGBE_SUCCESS : IXGBE_ERR_MBX; } /** @@ -246,71 +193,115 @@ static s32 ixgbe_poll_for_ack(struct ixgbe_hw *hw, u16 mbx_id) DEBUGFUNC("ixgbe_poll_for_ack"); - if (!countdown || !mbx->ops[mbx_id].check_for_ack) - return IXGBE_ERR_CONFIG; + if (!countdown || !mbx->ops.check_for_ack) + goto out; - while (countdown && mbx->ops[mbx_id].check_for_ack(hw, mbx_id)) { + while (countdown && mbx->ops.check_for_ack(hw, mbx_id)) { countdown--; if (!countdown) break; usec_delay(mbx->usec_delay); } - if (countdown == 0) { + if (countdown == 0) ERROR_REPORT2(IXGBE_ERROR_POLLING, - "Polling for VF%u mailbox ack timedout", mbx_id); - return IXGBE_ERR_TIMEOUT; - } + "Polling for VF%d mailbox ack timedout", mbx_id); - return IXGBE_SUCCESS; +out: + return countdown ? IXGBE_SUCCESS : IXGBE_ERR_MBX; } /** - * ixgbe_read_mailbox_vf - read VF's mailbox register + * ixgbe_read_posted_mbx - Wait for message notification and receive message + * @hw: pointer to the HW structure + * @msg: The message buffer + * @size: Length of buffer + * @mbx_id: id of mailbox to write + * + * returns SUCCESS if it successfully received a message notification and + * copied it into the receive buffer. + **/ +s32 ixgbe_read_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, + u16 mbx_id) +{ + struct ixgbe_mbx_info *mbx = &hw->mbx; + s32 ret_val = IXGBE_ERR_MBX; + + DEBUGFUNC("ixgbe_read_posted_mbx"); + + if (!mbx->ops.read) + goto out; + + ret_val = ixgbe_poll_for_msg(hw, mbx_id); + + /* if ack received read message, otherwise we timed out */ + if (!ret_val) + ret_val = mbx->ops.read(hw, msg, size, mbx_id); +out: + return ret_val; +} + +/** + * ixgbe_write_posted_mbx - Write a message to the mailbox, wait for ack + * @hw: pointer to the HW structure + * @msg: The message buffer + * @size: Length of buffer + * @mbx_id: id of mailbox to write + * + * returns SUCCESS if it successfully copied message into the buffer and + * received an ack to that message within delay * timeout period + **/ +s32 ixgbe_write_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, + u16 mbx_id) +{ + struct ixgbe_mbx_info *mbx = &hw->mbx; + s32 ret_val = IXGBE_ERR_MBX; + + DEBUGFUNC("ixgbe_write_posted_mbx"); + + /* exit if either we can't write or there isn't a defined timeout */ + if (!mbx->ops.write || !mbx->timeout) + goto out; + + /* send msg */ + ret_val = mbx->ops.write(hw, msg, size, mbx_id); + + /* if msg sent wait until we receive an ack */ + if (!ret_val) + ret_val = ixgbe_poll_for_ack(hw, mbx_id); +out: + return ret_val; +} + +/** + * ixgbe_init_mbx_ops_generic - Initialize MB function pointers * @hw: pointer to the HW structure * - * This function is used to read the mailbox register dedicated for VF without - * losing the read to clear status bits. + * Setups up the mailbox read and write message function pointers **/ -static u32 ixgbe_read_mailbox_vf(struct ixgbe_hw *hw) +void ixgbe_init_mbx_ops_generic(struct ixgbe_hw *hw) { - u32 vf_mailbox = IXGBE_READ_REG(hw, IXGBE_VFMAILBOX); + struct ixgbe_mbx_info *mbx = &hw->mbx; - vf_mailbox |= hw->mbx.vf_mailbox; - hw->mbx.vf_mailbox |= vf_mailbox % IXGBE_VFMAILBOX_R2C_BITS; - - return vf_mailbox; + mbx->ops.read_posted = ixgbe_read_posted_mbx; + mbx->ops.write_posted = ixgbe_write_posted_mbx; } -static void ixgbe_clear_msg_vf(struct ixgbe_hw *hw) +/** + * ixgbe_read_v2p_mailbox - read v2p mailbox + * @hw: pointer to the HW structure + * + * This function is used to read the v2p mailbox without losing the read to + * clear status bits. + **/ +static u32 ixgbe_read_v2p_mailbox(struct ixgbe_hw *hw) { - u32 vf_mailbox = ixgbe_read_mailbox_vf(hw); + u32 v2p_mailbox = IXGBE_READ_REG(hw, IXGBE_VFMAILBOX); - if (vf_mailbox & IXGBE_VFMAILBOX_PFSTS) { - hw->mbx.stats.reqs++; - hw->mbx.vf_mailbox &= ~IXGBE_VFMAILBOX_PFSTS; - } -} + v2p_mailbox |= hw->mbx.v2p_mailbox; + hw->mbx.v2p_mailbox |= v2p_mailbox & IXGBE_VFMAILBOX_R2C_BITS; -static void ixgbe_clear_ack_vf(struct ixgbe_hw *hw) -{ - u32 vf_mailbox = ixgbe_read_mailbox_vf(hw); - - if (vf_mailbox & IXGBE_VFMAILBOX_PFACK) { - hw->mbx.stats.acks++; - hw->mbx.vf_mailbox &= ~IXGBE_VFMAILBOX_PFACK; - } -} - -static void ixgbe_clear_rst_vf(struct ixgbe_hw *hw) -{ - u32 vf_mailbox = ixgbe_read_mailbox_vf(hw); - - if (vf_mailbox & (IXGBE_VFMAILBOX_RSTI | IXGBE_VFMAILBOX_RSTD)) { - hw->mbx.stats.rsts++; - hw->mbx.vf_mailbox &= ~(IXGBE_VFMAILBOX_RSTI | - IXGBE_VFMAILBOX_RSTD); - } + return v2p_mailbox; } /** @@ -323,12 +314,15 @@ static void ixgbe_clear_rst_vf(struct ixgbe_hw *hw) **/ static s32 ixgbe_check_for_bit_vf(struct ixgbe_hw *hw, u32 mask) { - u32 vf_mailbox = ixgbe_read_mailbox_vf(hw); + u32 v2p_mailbox = ixgbe_read_v2p_mailbox(hw); + s32 ret_val = IXGBE_ERR_MBX; - if (vf_mailbox & mask) - return IXGBE_SUCCESS; + if (v2p_mailbox & mask) + ret_val = IXGBE_SUCCESS; - return IXGBE_ERR_MBX; + hw->mbx.v2p_mailbox &= ~mask; + + return ret_val; } /** @@ -340,13 +334,17 @@ static s32 ixgbe_check_for_bit_vf(struct ixgbe_hw *hw, u32 mask) **/ static s32 ixgbe_check_for_msg_vf(struct ixgbe_hw *hw, u16 mbx_id) { + s32 ret_val = IXGBE_ERR_MBX; + UNREFERENCED_1PARAMETER(mbx_id); DEBUGFUNC("ixgbe_check_for_msg_vf"); - if (!ixgbe_check_for_bit_vf(hw, IXGBE_VFMAILBOX_PFSTS)) - return IXGBE_SUCCESS; + if (!ixgbe_check_for_bit_vf(hw, IXGBE_VFMAILBOX_PFSTS)) { + ret_val = IXGBE_SUCCESS; + hw->mbx.stats.reqs++; + } - return IXGBE_ERR_MBX; + return ret_val; } /** @@ -358,16 +356,17 @@ static s32 ixgbe_check_for_msg_vf(struct ixgbe_hw *hw, u16 mbx_id) **/ static s32 ixgbe_check_for_ack_vf(struct ixgbe_hw *hw, u16 mbx_id) { + s32 ret_val = IXGBE_ERR_MBX; + UNREFERENCED_1PARAMETER(mbx_id); DEBUGFUNC("ixgbe_check_for_ack_vf"); if (!ixgbe_check_for_bit_vf(hw, IXGBE_VFMAILBOX_PFACK)) { - /* TODO: should this be autocleared? */ - ixgbe_clear_ack_vf(hw); - return IXGBE_SUCCESS; + ret_val = IXGBE_SUCCESS; + hw->mbx.stats.acks++; } - return IXGBE_ERR_MBX; + return ret_val; } /** @@ -379,17 +378,18 @@ static s32 ixgbe_check_for_ack_vf(struct ixgbe_hw *hw, u16 mbx_id) **/ static s32 ixgbe_check_for_rst_vf(struct ixgbe_hw *hw, u16 mbx_id) { + s32 ret_val = IXGBE_ERR_MBX; + UNREFERENCED_1PARAMETER(mbx_id); DEBUGFUNC("ixgbe_check_for_rst_vf"); - if (!ixgbe_check_for_bit_vf(hw, IXGBE_VFMAILBOX_RSTI | - IXGBE_VFMAILBOX_RSTD)) { - /* TODO: should this be autocleared? */ - ixgbe_clear_rst_vf(hw); - return IXGBE_SUCCESS; + if (!ixgbe_check_for_bit_vf(hw, (IXGBE_VFMAILBOX_RSTD | + IXGBE_VFMAILBOX_RSTI))) { + ret_val = IXGBE_SUCCESS; + hw->mbx.stats.rsts++; } - return IXGBE_ERR_MBX; + return ret_val; } /** @@ -400,114 +400,20 @@ static s32 ixgbe_check_for_rst_vf(struct ixgbe_hw *hw, u16 mbx_id) **/ static s32 ixgbe_obtain_mbx_lock_vf(struct ixgbe_hw *hw) { - struct ixgbe_mbx_info *mbx = &hw->mbx; - int countdown = mbx->timeout; s32 ret_val = IXGBE_ERR_MBX; - u32 vf_mailbox; DEBUGFUNC("ixgbe_obtain_mbx_lock_vf"); - if (!mbx->timeout) - return IXGBE_ERR_CONFIG; + /* Take ownership of the buffer */ + IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_VFU); - while (countdown--) { - /* Reserve mailbox for VF use */ - vf_mailbox = ixgbe_read_mailbox_vf(hw); - vf_mailbox |= IXGBE_VFMAILBOX_VFU; - IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, vf_mailbox); - - /* Verify that VF is the owner of the lock */ - if (ixgbe_read_mailbox_vf(hw) & IXGBE_VFMAILBOX_VFU) { - ret_val = IXGBE_SUCCESS; - break; - } - - /* Wait a bit before trying again */ - usec_delay(mbx->usec_delay); - } - - if (ret_val != IXGBE_SUCCESS) { - ERROR_REPORT1(IXGBE_ERROR_INVALID_STATE, - "Failed to obtain mailbox lock"); - ret_val = IXGBE_ERR_TIMEOUT; - } + /* reserve mailbox for vf use */ + if (ixgbe_read_v2p_mailbox(hw) & IXGBE_VFMAILBOX_VFU) + ret_val = IXGBE_SUCCESS; return ret_val; } -/** - * ixgbe_release_mbx_lock_dummy - release mailbox lock - * @hw: pointer to the HW structure - * @mbx_id: id of mailbox to read - **/ -static void ixgbe_release_mbx_lock_dummy(struct ixgbe_hw *hw, u16 mbx_id) -{ - UNREFERENCED_2PARAMETER(hw, mbx_id); - - DEBUGFUNC("ixgbe_release_mbx_lock_dummy"); -} - -/** - * ixgbe_release_mbx_lock_vf - release mailbox lock - * @hw: pointer to the HW structure - * @mbx_id: id of mailbox to read - **/ -static void ixgbe_release_mbx_lock_vf(struct ixgbe_hw *hw, u16 mbx_id) -{ - u32 vf_mailbox; - - UNREFERENCED_1PARAMETER(mbx_id); - - DEBUGFUNC("ixgbe_release_mbx_lock_vf"); - - /* Return ownership of the buffer */ - vf_mailbox = ixgbe_read_mailbox_vf(hw); - vf_mailbox &= ~IXGBE_VFMAILBOX_VFU; - IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, vf_mailbox); -} - -/** - * ixgbe_write_mbx_vf_legacy - Write a message to the mailbox - * @hw: pointer to the HW structure - * @msg: The message buffer - * @size: Length of buffer - * @mbx_id: id of mailbox to write - * - * returns SUCCESS if it successfully copied message into the buffer - **/ -static s32 ixgbe_write_mbx_vf_legacy(struct ixgbe_hw *hw, u32 *msg, u16 size, - u16 mbx_id) -{ - s32 ret_val; - u16 i; - - UNREFERENCED_1PARAMETER(mbx_id); - DEBUGFUNC("ixgbe_write_mbx_vf_legacy"); - - /* lock the mailbox to prevent pf/vf race condition */ - ret_val = ixgbe_obtain_mbx_lock_vf(hw); - if (ret_val) - return ret_val; - - /* flush msg and acks as we are overwriting the message buffer */ - ixgbe_check_for_msg_vf(hw, 0); - ixgbe_clear_msg_vf(hw); - ixgbe_check_for_ack_vf(hw, 0); - ixgbe_clear_ack_vf(hw); - - /* copy the caller specified message to the mailbox memory buffer */ - for (i = 0; i < size; i++) - IXGBE_WRITE_REG_ARRAY(hw, IXGBE_VFMBMEM, i, msg[i]); - - /* update stats */ - hw->mbx.stats.msgs_tx++; - - /* interrupt the PF to tell it a message has been sent */ - IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_REQ); - - return IXGBE_SUCCESS; -} - /** * ixgbe_write_mbx_vf - Write a message to the mailbox * @hw: pointer to the HW structure @@ -520,7 +426,6 @@ static s32 ixgbe_write_mbx_vf_legacy(struct ixgbe_hw *hw, u32 *msg, u16 size, static s32 ixgbe_write_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id) { - u32 vf_mailbox; s32 ret_val; u16 i; @@ -531,11 +436,11 @@ static s32 ixgbe_write_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size, /* lock the mailbox to prevent pf/vf race condition */ ret_val = ixgbe_obtain_mbx_lock_vf(hw); if (ret_val) - goto out; + goto out_no_write; /* flush msg and acks as we are overwriting the message buffer */ - ixgbe_clear_msg_vf(hw); - ixgbe_clear_ack_vf(hw); + ixgbe_check_for_msg_vf(hw, 0); + ixgbe_check_for_ack_vf(hw, 0); /* copy the caller specified message to the mailbox memory buffer */ for (i = 0; i < size; i++) @@ -544,56 +449,13 @@ static s32 ixgbe_write_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size, /* update stats */ hw->mbx.stats.msgs_tx++; - /* interrupt the PF to tell it a message has been sent */ - vf_mailbox = ixgbe_read_mailbox_vf(hw); - vf_mailbox |= IXGBE_VFMAILBOX_REQ; - IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, vf_mailbox); - - /* if msg sent wait until we receive an ack */ - ixgbe_poll_for_ack(hw, mbx_id); - -out: - hw->mbx.ops[mbx_id].release(hw, mbx_id); + /* Drop VFU and interrupt the PF to tell it a message has been sent */ + IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_REQ); +out_no_write: return ret_val; } -/** - * ixgbe_read_mbx_vf_legacy - Reads a message from the inbox intended for vf - * @hw: pointer to the HW structure - * @msg: The message buffer - * @size: Length of buffer - * @mbx_id: id of mailbox to read - * - * returns SUCCESS if it successfully read message from buffer - **/ -static s32 ixgbe_read_mbx_vf_legacy(struct ixgbe_hw *hw, u32 *msg, u16 size, - u16 mbx_id) -{ - s32 ret_val; - u16 i; - - DEBUGFUNC("ixgbe_read_mbx_vf_legacy"); - UNREFERENCED_1PARAMETER(mbx_id); - - /* lock the mailbox to prevent pf/vf race condition */ - ret_val = ixgbe_obtain_mbx_lock_vf(hw); - if (ret_val) - return ret_val; - - /* copy the message from the mailbox memory buffer */ - for (i = 0; i < size; i++) - msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_VFMBMEM, i); - - /* Acknowledge receipt and release mailbox, then we're done */ - IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_ACK); - - /* update stats */ - hw->mbx.stats.msgs_rx++; - - return IXGBE_SUCCESS; -} - /** * ixgbe_read_mbx_vf - Reads a message from the inbox intended for vf * @hw: pointer to the HW structure @@ -606,58 +468,55 @@ static s32 ixgbe_read_mbx_vf_legacy(struct ixgbe_hw *hw, u32 *msg, u16 size, static s32 ixgbe_read_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id) { - u32 vf_mailbox; - s32 ret_val; + s32 ret_val = IXGBE_SUCCESS; u16 i; DEBUGFUNC("ixgbe_read_mbx_vf"); UNREFERENCED_1PARAMETER(mbx_id); - /* check if there is a message from PF */ - ret_val = ixgbe_check_for_msg_vf(hw, 0); - if (ret_val != IXGBE_SUCCESS) - return IXGBE_ERR_MBX_NOMSG; - - ixgbe_clear_msg_vf(hw); + /* lock the mailbox to prevent pf/vf race condition */ + ret_val = ixgbe_obtain_mbx_lock_vf(hw); + if (ret_val) + goto out_no_read; /* copy the message from the mailbox memory buffer */ for (i = 0; i < size; i++) msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_VFMBMEM, i); - /* Acknowledge receipt */ - vf_mailbox = ixgbe_read_mailbox_vf(hw); - vf_mailbox |= IXGBE_VFMAILBOX_ACK; - IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, vf_mailbox); + /* Acknowledge receipt and release mailbox, then we're done */ + IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_ACK); /* update stats */ hw->mbx.stats.msgs_rx++; - return IXGBE_SUCCESS; +out_no_read: + return ret_val; } /** * ixgbe_init_mbx_params_vf - set initial values for vf mailbox * @hw: pointer to the HW structure * - * Initializes single set the hw->mbx struct to correct values for vf mailbox - * Set of legacy functions is being used here + * Initializes the hw->mbx struct to correct values for vf mailbox */ void ixgbe_init_mbx_params_vf(struct ixgbe_hw *hw) { struct ixgbe_mbx_info *mbx = &hw->mbx; - mbx->timeout = IXGBE_VF_MBX_INIT_TIMEOUT; + /* start mailbox as timed out and let the reset_hw call set the timeout + * value to begin communications */ + mbx->timeout = 0; mbx->usec_delay = IXGBE_VF_MBX_INIT_DELAY; mbx->size = IXGBE_VFMAILBOX_SIZE; - /* VF has only one mailbox connection, no need for more IDs */ - mbx->ops[0].release = ixgbe_release_mbx_lock_dummy; - mbx->ops[0].read = ixgbe_read_mbx_vf_legacy; - mbx->ops[0].write = ixgbe_write_mbx_vf_legacy; - mbx->ops[0].check_for_msg = ixgbe_check_for_msg_vf; - mbx->ops[0].check_for_ack = ixgbe_check_for_ack_vf; - mbx->ops[0].check_for_rst = ixgbe_check_for_rst_vf; + mbx->ops.read = ixgbe_read_mbx_vf; + mbx->ops.write = ixgbe_write_mbx_vf; + mbx->ops.read_posted = ixgbe_read_posted_mbx; + mbx->ops.write_posted = ixgbe_write_posted_mbx; + mbx->ops.check_for_msg = ixgbe_check_for_msg_vf; + mbx->ops.check_for_ack = ixgbe_check_for_ack_vf; + mbx->ops.check_for_rst = ixgbe_check_for_rst_vf; mbx->stats.msgs_tx = 0; mbx->stats.msgs_rx = 0; @@ -666,110 +525,54 @@ void ixgbe_init_mbx_params_vf(struct ixgbe_hw *hw) mbx->stats.rsts = 0; } -/** - * ixgbe_upgrade_mbx_params_vf - set initial values for vf mailbox - * @hw: pointer to the HW structure - * - * Initializes the hw->mbx struct to correct values for vf mailbox - */ -void ixgbe_upgrade_mbx_params_vf(struct ixgbe_hw *hw) -{ - struct ixgbe_mbx_info *mbx = &hw->mbx; - - mbx->timeout = IXGBE_VF_MBX_INIT_TIMEOUT; - mbx->usec_delay = IXGBE_VF_MBX_INIT_DELAY; - - mbx->size = IXGBE_VFMAILBOX_SIZE; - - /* VF has only one mailbox connection, no need for more IDs */ - mbx->ops[0].release = ixgbe_release_mbx_lock_vf; - mbx->ops[0].read = ixgbe_read_mbx_vf; - mbx->ops[0].write = ixgbe_write_mbx_vf; - mbx->ops[0].check_for_msg = ixgbe_check_for_msg_vf; - mbx->ops[0].check_for_ack = ixgbe_check_for_ack_vf; - mbx->ops[0].check_for_rst = ixgbe_check_for_rst_vf; - mbx->ops[0].clear = NULL; - - mbx->stats.msgs_tx = 0; - mbx->stats.msgs_rx = 0; - mbx->stats.reqs = 0; - mbx->stats.acks = 0; - mbx->stats.rsts = 0; -} - -static void ixgbe_clear_msg_pf(struct ixgbe_hw *hw, u16 vf_id) -{ - u32 vf_shift = IXGBE_PFMBICR_SHIFT(vf_id); - s32 index = IXGBE_PFMBICR_INDEX(vf_id); - u32 pfmbicr; - - pfmbicr = IXGBE_READ_REG(hw, IXGBE_PFMBICR(index)); - - if (pfmbicr & (IXGBE_PFMBICR_VFREQ_VF1 << vf_shift)) - hw->mbx.stats.reqs++; - - IXGBE_WRITE_REG(hw, IXGBE_PFMBICR(index), - IXGBE_PFMBICR_VFREQ_VF1 << vf_shift); -} - -static void ixgbe_clear_ack_pf(struct ixgbe_hw *hw, u16 vf_id) -{ - u32 vf_shift = IXGBE_PFMBICR_SHIFT(vf_id); - s32 index = IXGBE_PFMBICR_INDEX(vf_id); - u32 pfmbicr; - - pfmbicr = IXGBE_READ_REG(hw, IXGBE_PFMBICR(index)); - - if (pfmbicr & (IXGBE_PFMBICR_VFACK_VF1 << vf_shift)) - hw->mbx.stats.acks++; - - IXGBE_WRITE_REG(hw, IXGBE_PFMBICR(index), - IXGBE_PFMBICR_VFACK_VF1 << vf_shift); -} - static s32 ixgbe_check_for_bit_pf(struct ixgbe_hw *hw, u32 mask, s32 index) { u32 pfmbicr = IXGBE_READ_REG(hw, IXGBE_PFMBICR(index)); + s32 ret_val = IXGBE_ERR_MBX; if (pfmbicr & mask) { - return IXGBE_SUCCESS; + ret_val = IXGBE_SUCCESS; + IXGBE_WRITE_REG(hw, IXGBE_PFMBICR(index), mask); } - return IXGBE_ERR_MBX; + return ret_val; } /** * ixgbe_check_for_msg_pf - checks to see if the VF has sent mail * @hw: pointer to the HW structure - * @vf_id: the VF index + * @vf_number: the VF index * * returns SUCCESS if the VF has set the Status bit or else ERR_MBX **/ -static s32 ixgbe_check_for_msg_pf(struct ixgbe_hw *hw, u16 vf_id) +static s32 ixgbe_check_for_msg_pf(struct ixgbe_hw *hw, u16 vf_number) { - u32 vf_shift = IXGBE_PFMBICR_SHIFT(vf_id); - s32 index = IXGBE_PFMBICR_INDEX(vf_id); + u32 vf_shift = IXGBE_PFMBICR_SHIFT(vf_number); + s32 index = IXGBE_PFMBICR_INDEX(vf_number); + s32 ret_val = IXGBE_ERR_MBX; DEBUGFUNC("ixgbe_check_for_msg_pf"); if (!ixgbe_check_for_bit_pf(hw, IXGBE_PFMBICR_VFREQ_VF1 << vf_shift, - index)) - return IXGBE_SUCCESS; + index)) { + ret_val = IXGBE_SUCCESS; + hw->mbx.stats.reqs++; + } - return IXGBE_ERR_MBX; + return ret_val; } /** * ixgbe_check_for_ack_pf - checks to see if the VF has ACKed * @hw: pointer to the HW structure - * @vf_id: the VF index + * @vf_number: the VF index * * returns SUCCESS if the VF has set the Status bit or else ERR_MBX **/ -static s32 ixgbe_check_for_ack_pf(struct ixgbe_hw *hw, u16 vf_id) +static s32 ixgbe_check_for_ack_pf(struct ixgbe_hw *hw, u16 vf_number) { - u32 vf_shift = IXGBE_PFMBICR_SHIFT(vf_id); - s32 index = IXGBE_PFMBICR_INDEX(vf_id); + u32 vf_shift = IXGBE_PFMBICR_SHIFT(vf_number); + s32 index = IXGBE_PFMBICR_INDEX(vf_number); s32 ret_val = IXGBE_ERR_MBX; DEBUGFUNC("ixgbe_check_for_ack_pf"); @@ -777,8 +580,7 @@ static s32 ixgbe_check_for_ack_pf(struct ixgbe_hw *hw, u16 vf_id) if (!ixgbe_check_for_bit_pf(hw, IXGBE_PFMBICR_VFACK_VF1 << vf_shift, index)) { ret_val = IXGBE_SUCCESS; - /* TODO: should this be autocleared? */ - ixgbe_clear_ack_pf(hw, vf_id); + hw->mbx.stats.acks++; } return ret_val; @@ -787,14 +589,14 @@ static s32 ixgbe_check_for_ack_pf(struct ixgbe_hw *hw, u16 vf_id) /** * ixgbe_check_for_rst_pf - checks to see if the VF has reset * @hw: pointer to the HW structure - * @vf_id: the VF index + * @vf_number: the VF index * * returns SUCCESS if the VF has set the Status bit or else ERR_MBX **/ -static s32 ixgbe_check_for_rst_pf(struct ixgbe_hw *hw, u16 vf_id) +static s32 ixgbe_check_for_rst_pf(struct ixgbe_hw *hw, u16 vf_number) { - u32 vf_shift = IXGBE_PFVFLRE_SHIFT(vf_id); - u32 index = IXGBE_PFVFLRE_INDEX(vf_id); + u32 vf_shift = IXGBE_PFVFLRE_SHIFT(vf_number); + u32 index = IXGBE_PFVFLRE_INDEX(vf_number); s32 ret_val = IXGBE_ERR_MBX; u32 vflre = 0; @@ -826,268 +628,121 @@ static s32 ixgbe_check_for_rst_pf(struct ixgbe_hw *hw, u16 vf_id) /** * ixgbe_obtain_mbx_lock_pf - obtain mailbox lock * @hw: pointer to the HW structure - * @vf_id: the VF index + * @vf_number: the VF index * * return SUCCESS if we obtained the mailbox lock **/ -static s32 ixgbe_obtain_mbx_lock_pf(struct ixgbe_hw *hw, u16 vf_id) +static s32 ixgbe_obtain_mbx_lock_pf(struct ixgbe_hw *hw, u16 vf_number) { - struct ixgbe_mbx_info *mbx = &hw->mbx; - int countdown = mbx->timeout; s32 ret_val = IXGBE_ERR_MBX; - u32 pf_mailbox; + u32 p2v_mailbox; DEBUGFUNC("ixgbe_obtain_mbx_lock_pf"); - if (!mbx->timeout) - return IXGBE_ERR_CONFIG; + /* Take ownership of the buffer */ + IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_PFU); - while (countdown--) { - /* Reserve mailbox for PF use */ - pf_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_id)); - pf_mailbox |= IXGBE_PFMAILBOX_PFU; - IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_id), pf_mailbox); + /* reserve mailbox for vf use */ + p2v_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_number)); + if (p2v_mailbox & IXGBE_PFMAILBOX_PFU) + ret_val = IXGBE_SUCCESS; + else + ERROR_REPORT2(IXGBE_ERROR_POLLING, + "Failed to obtain mailbox lock for VF%d", vf_number); - /* Verify that PF is the owner of the lock */ - pf_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_id)); - if (pf_mailbox & IXGBE_PFMAILBOX_PFU) { - ret_val = IXGBE_SUCCESS; - break; - } - - /* Wait a bit before trying again */ - usec_delay(mbx->usec_delay); - } - - if (ret_val != IXGBE_SUCCESS) { - ERROR_REPORT1(IXGBE_ERROR_INVALID_STATE, - "Failed to obtain mailbox lock"); - ret_val = IXGBE_ERR_TIMEOUT; - } return ret_val; } -/** - * ixgbe_release_mbx_lock_pf - release mailbox lock - * @hw: pointer to the HW structure - * @vf_id: the VF index - **/ -static void ixgbe_release_mbx_lock_pf(struct ixgbe_hw *hw, u16 vf_id) -{ - u32 pf_mailbox; - - DEBUGFUNC("ixgbe_release_mbx_lock_pf"); - - /* Return ownership of the buffer */ - pf_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_id)); - pf_mailbox &= ~IXGBE_PFMAILBOX_PFU; - IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_id), pf_mailbox); -} - -/** - * ixgbe_write_mbx_pf_legacy - Places a message in the mailbox - * @hw: pointer to the HW structure - * @msg: The message buffer - * @size: Length of buffer - * @vf_id: the VF index - * - * returns SUCCESS if it successfully copied message into the buffer - **/ -static s32 ixgbe_write_mbx_pf_legacy(struct ixgbe_hw *hw, u32 *msg, u16 size, - u16 vf_id) -{ - s32 ret_val; - u16 i; - - DEBUGFUNC("ixgbe_write_mbx_pf_legacy"); - - /* lock the mailbox to prevent pf/vf race condition */ - ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_id); - if (ret_val) - return ret_val; - - /* flush msg and acks as we are overwriting the message buffer */ - ixgbe_check_for_msg_pf(hw, vf_id); - ixgbe_clear_msg_pf(hw, vf_id); - ixgbe_check_for_ack_pf(hw, vf_id); - ixgbe_clear_ack_pf(hw, vf_id); - - /* copy the caller specified message to the mailbox memory buffer */ - for (i = 0; i < size; i++) - IXGBE_WRITE_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_id), i, msg[i]); - - /* Interrupt VF to tell it a message has been sent and release buffer*/ - IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_id), IXGBE_PFMAILBOX_STS); - - /* update stats */ - hw->mbx.stats.msgs_tx++; - - return IXGBE_SUCCESS; -} - /** * ixgbe_write_mbx_pf - Places a message in the mailbox * @hw: pointer to the HW structure * @msg: The message buffer * @size: Length of buffer - * @vf_id: the VF index + * @vf_number: the VF index * * returns SUCCESS if it successfully copied message into the buffer **/ static s32 ixgbe_write_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size, - u16 vf_id) + u16 vf_number) { - u32 pf_mailbox; s32 ret_val; u16 i; DEBUGFUNC("ixgbe_write_mbx_pf"); /* lock the mailbox to prevent pf/vf race condition */ - ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_id); + ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_number); if (ret_val) - goto out; + goto out_no_write; /* flush msg and acks as we are overwriting the message buffer */ - ixgbe_clear_msg_pf(hw, vf_id); - ixgbe_clear_ack_pf(hw, vf_id); + ixgbe_check_for_msg_pf(hw, vf_number); + ixgbe_check_for_ack_pf(hw, vf_number); /* copy the caller specified message to the mailbox memory buffer */ for (i = 0; i < size; i++) - IXGBE_WRITE_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_id), i, msg[i]); + IXGBE_WRITE_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_number), i, msg[i]); - /* Interrupt VF to tell it a message has been sent */ - pf_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_id)); - pf_mailbox |= IXGBE_PFMAILBOX_STS; - IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_id), pf_mailbox); - - /* if msg sent wait until we receive an ack */ - ixgbe_poll_for_ack(hw, vf_id); + /* Interrupt VF to tell it a message has been sent and release buffer*/ + IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_STS); /* update stats */ hw->mbx.stats.msgs_tx++; -out: - hw->mbx.ops[vf_id].release(hw, vf_id); - +out_no_write: return ret_val; } -/** - * ixgbe_read_mbx_pf_legacy - Read a message from the mailbox - * @hw: pointer to the HW structure - * @msg: The message buffer - * @size: Length of buffer - * @vf_id: the VF index - * - * This function copies a message from the mailbox buffer to the caller's - * memory buffer. The presumption is that the caller knows that there was - * a message due to a VF request so no polling for message is needed. - **/ -static s32 ixgbe_read_mbx_pf_legacy(struct ixgbe_hw *hw, u32 *msg, u16 size, - u16 vf_id) -{ - s32 ret_val; - u16 i; - - DEBUGFUNC("ixgbe_read_mbx_pf_legacy"); - - /* lock the mailbox to prevent pf/vf race condition */ - ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_id); - if (ret_val != IXGBE_SUCCESS) - return ret_val; - - /* copy the message to the mailbox memory buffer */ - for (i = 0; i < size; i++) - msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_id), i); - - /* Acknowledge the message and release buffer */ - IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_id), IXGBE_PFMAILBOX_ACK); - - /* update stats */ - hw->mbx.stats.msgs_rx++; - - return IXGBE_SUCCESS; -} - /** * ixgbe_read_mbx_pf - Read a message from the mailbox * @hw: pointer to the HW structure * @msg: The message buffer * @size: Length of buffer - * @vf_id: the VF index + * @vf_number: the VF index * * This function copies a message from the mailbox buffer to the caller's * memory buffer. The presumption is that the caller knows that there was * a message due to a VF request so no polling for message is needed. **/ static s32 ixgbe_read_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size, - u16 vf_id) + u16 vf_number) { - u32 pf_mailbox; s32 ret_val; u16 i; DEBUGFUNC("ixgbe_read_mbx_pf"); - /* check if there is a message from VF */ - ret_val = ixgbe_check_for_msg_pf(hw, vf_id); - if (ret_val != IXGBE_SUCCESS) - return IXGBE_ERR_MBX_NOMSG; - - ixgbe_clear_msg_pf(hw, vf_id); + /* lock the mailbox to prevent pf/vf race condition */ + ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_number); + if (ret_val) + goto out_no_read; /* copy the message to the mailbox memory buffer */ for (i = 0; i < size; i++) - msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_id), i); + msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_number), i); /* Acknowledge the message and release buffer */ - pf_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_id)); - pf_mailbox |= IXGBE_PFMAILBOX_ACK; - IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_id), pf_mailbox); + IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_ACK); /* update stats */ hw->mbx.stats.msgs_rx++; - return IXGBE_SUCCESS; -} - -/** - * ixgbe_init_mbx_params_pf_id - set initial values for pf mailbox - * @hw: pointer to the HW structure - * @vf_id: the VF index - * - * Initializes single set of the hw->mbx struct to correct values for pf mailbox - * Set of legacy functions is being used here - */ -void ixgbe_init_mbx_params_pf_id(struct ixgbe_hw *hw, u16 vf_id) -{ - struct ixgbe_mbx_info *mbx = &hw->mbx; - - mbx->ops[vf_id].release = ixgbe_release_mbx_lock_dummy; - mbx->ops[vf_id].read = ixgbe_read_mbx_pf_legacy; - mbx->ops[vf_id].write = ixgbe_write_mbx_pf_legacy; - mbx->ops[vf_id].check_for_msg = ixgbe_check_for_msg_pf; - mbx->ops[vf_id].check_for_ack = ixgbe_check_for_ack_pf; - mbx->ops[vf_id].check_for_rst = ixgbe_check_for_rst_pf; +out_no_read: + return ret_val; } /** * ixgbe_init_mbx_params_pf - set initial values for pf mailbox * @hw: pointer to the HW structure * - * Initializes all sets of the hw->mbx struct to correct values for pf - * mailbox. One set corresponds to single VF. It also initializes counters - * and general variables. A set of legacy functions is used by default. + * Initializes the hw->mbx struct to correct values for pf mailbox */ void ixgbe_init_mbx_params_pf(struct ixgbe_hw *hw) { - u16 i; struct ixgbe_mbx_info *mbx = &hw->mbx; - /* Ensure we are not calling this function from VF */ if (hw->mac.type != ixgbe_mac_82599EB && hw->mac.type != ixgbe_mac_X550 && hw->mac.type != ixgbe_mac_X550EM_x && @@ -1095,58 +750,18 @@ void ixgbe_init_mbx_params_pf(struct ixgbe_hw *hw) hw->mac.type != ixgbe_mac_X540) return; - /* Initialize common mailbox settings */ - mbx->timeout = IXGBE_VF_MBX_INIT_TIMEOUT; - mbx->usec_delay = IXGBE_VF_MBX_INIT_DELAY; + mbx->timeout = 0; + mbx->usec_delay = 0; + mbx->size = IXGBE_VFMAILBOX_SIZE; - /* Initialize counters with zeroes */ - mbx->stats.msgs_tx = 0; - mbx->stats.msgs_rx = 0; - mbx->stats.reqs = 0; - mbx->stats.acks = 0; - mbx->stats.rsts = 0; - - /* No matter of VF number, we initialize params for all 64 VFs. */ - /* TODO: 1. Add a define for max VF and refactor SHARED to get rid - * of magic number for that (63 or 64 depending on use case.) - * 2. rewrite the code to dynamically allocate mbx->ops[vf_id] for - * certain number of VFs instead of default maximum value of 64 (0..63) - */ - for (i = 0; i < 64; i++) - ixgbe_init_mbx_params_pf_id(hw, i); -} - -/** - * ixgbe_upgrade_mbx_params_pf - Upgrade initial values for pf mailbox - * @hw: pointer to the HW structure - * @vf_id: the VF index - * - * Initializes the hw->mbx struct to new function set for improved - * stability and handling of messages. - */ -void ixgbe_upgrade_mbx_params_pf(struct ixgbe_hw *hw, u16 vf_id) -{ - struct ixgbe_mbx_info *mbx = &hw->mbx; - - /* Ensure we are not calling this function from VF */ - if (hw->mac.type != ixgbe_mac_82599EB && - hw->mac.type != ixgbe_mac_X550 && - hw->mac.type != ixgbe_mac_X550EM_x && - hw->mac.type != ixgbe_mac_X550EM_a && - hw->mac.type != ixgbe_mac_X540) - return; - - mbx->timeout = IXGBE_VF_MBX_INIT_TIMEOUT; - mbx->usec_delay = IXGBE_VF_MBX_INIT_DELAY; - mbx->size = IXGBE_VFMAILBOX_SIZE; - - mbx->ops[vf_id].release = ixgbe_release_mbx_lock_pf; - mbx->ops[vf_id].read = ixgbe_read_mbx_pf; - mbx->ops[vf_id].write = ixgbe_write_mbx_pf; - mbx->ops[vf_id].check_for_msg = ixgbe_check_for_msg_pf; - mbx->ops[vf_id].check_for_ack = ixgbe_check_for_ack_pf; - mbx->ops[vf_id].check_for_rst = ixgbe_check_for_rst_pf; + mbx->ops.read = ixgbe_read_mbx_pf; + mbx->ops.write = ixgbe_write_mbx_pf; + mbx->ops.read_posted = ixgbe_read_posted_mbx; + mbx->ops.write_posted = ixgbe_write_posted_mbx; + mbx->ops.check_for_msg = ixgbe_check_for_msg_pf; + mbx->ops.check_for_ack = ixgbe_check_for_ack_pf; + mbx->ops.check_for_rst = ixgbe_check_for_rst_pf; mbx->stats.msgs_tx = 0; mbx->stats.msgs_rx = 0; diff --git a/sys/dev/ixgbe/ixgbe_type.h b/sys/dev/ixgbe/ixgbe_type.h index ccfce45500d..2fc500c9329 100644 --- a/sys/dev/ixgbe/ixgbe_type.h +++ b/sys/dev/ixgbe/ixgbe_type.h @@ -4178,6 +4178,35 @@ struct ixgbe_phy_info { #include "ixgbe_mbx.h" +struct ixgbe_mbx_operations { + void (*init_params)(struct ixgbe_hw *hw); + s32 (*read)(struct ixgbe_hw *, u32 *, u16, u16); + s32 (*write)(struct ixgbe_hw *, u32 *, u16, u16); + s32 (*read_posted)(struct ixgbe_hw *, u32 *, u16, u16); + s32 (*write_posted)(struct ixgbe_hw *, u32 *, u16, u16); + s32 (*check_for_msg)(struct ixgbe_hw *, u16); + s32 (*check_for_ack)(struct ixgbe_hw *, u16); + s32 (*check_for_rst)(struct ixgbe_hw *, u16); +}; + +struct ixgbe_mbx_stats { + u32 msgs_tx; + u32 msgs_rx; + + u32 acks; + u32 reqs; + u32 rsts; +}; + +struct ixgbe_mbx_info { + struct ixgbe_mbx_operations ops; + struct ixgbe_mbx_stats stats; + u32 timeout; + u32 usec_delay; + u32 v2p_mailbox; + u16 size; +}; + struct ixgbe_hw { u8 IOMEM *hw_addr; void *back; @@ -4248,9 +4277,6 @@ struct ixgbe_hw { #define IXGBE_ERR_FDIR_CMD_INCOMPLETE -38 #define IXGBE_ERR_FW_RESP_INVALID -39 #define IXGBE_ERR_TOKEN_RETRY -40 -#define IXGBE_ERR_MBX -41 -#define IXGBE_ERR_MBX_NOMSG -42 -#define IXGBE_ERR_TIMEOUT -43 #define IXGBE_NOT_IMPLEMENTED 0x7FFFFFFF diff --git a/sys/dev/ixgbe/ixgbe_vf.c b/sys/dev/ixgbe/ixgbe_vf.c index cac3c6b5e5e..4624c2b5c0a 100644 --- a/sys/dev/ixgbe/ixgbe_vf.c +++ b/sys/dev/ixgbe/ixgbe_vf.c @@ -49,8 +49,6 @@ **/ s32 ixgbe_init_ops_vf(struct ixgbe_hw *hw) { - u16 i; - /* MAC */ hw->mac.ops.init_hw = ixgbe_init_hw_vf; hw->mac.ops.reset_hw = ixgbe_reset_hw_vf; @@ -84,8 +82,7 @@ s32 ixgbe_init_ops_vf(struct ixgbe_hw *hw) hw->mac.max_tx_queues = 1; hw->mac.max_rx_queues = 1; - for (i = 0; i < 64; i++) - hw->mbx.ops[i].init_params = ixgbe_init_mbx_params_vf; + hw->mbx.ops.init_params = ixgbe_init_mbx_params_vf; return IXGBE_SUCCESS; } @@ -188,7 +185,6 @@ s32 ixgbe_reset_hw_vf(struct ixgbe_hw *hw) /* reset the api version */ hw->api_version = ixgbe_mbox_api_10; - ixgbe_init_mbx_params_vf(hw); DEBUGOUT("Issuing a function level reset to MAC\n"); @@ -198,7 +194,7 @@ s32 ixgbe_reset_hw_vf(struct ixgbe_hw *hw) msec_delay(50); /* we cannot reset while the RSTI / RSTD bits are asserted */ - while (!mbx->ops[0].check_for_rst(hw, 0) && timeout) { + while (!mbx->ops.check_for_rst(hw, 0) && timeout) { timeout--; usec_delay(5); } @@ -213,7 +209,7 @@ s32 ixgbe_reset_hw_vf(struct ixgbe_hw *hw) mbx->timeout = IXGBE_VF_MBX_INIT_TIMEOUT; msgbuf[0] = IXGBE_VF_RESET; - ixgbe_write_mbx(hw, msgbuf, 1, 0); + mbx->ops.write_posted(hw, msgbuf, 1, 0); msec_delay(10); @@ -222,8 +218,8 @@ s32 ixgbe_reset_hw_vf(struct ixgbe_hw *hw) * also set up the mc_filter_type which is piggy backed * on the mac address in word 3 */ - ret_val = ixgbe_poll_mbx(hw, msgbuf, - IXGBE_VF_PERMADDR_MSG_LEN, 0); + ret_val = mbx->ops.read_posted(hw, msgbuf, + IXGBE_VF_PERMADDR_MSG_LEN, 0); if (ret_val) return ret_val; @@ -328,12 +324,13 @@ static s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr) static s32 ixgbevf_write_msg_read_ack(struct ixgbe_hw *hw, u32 *msg, u32 *retmsg, u16 size) { - s32 retval = ixgbe_write_mbx(hw, msg, size, 0); + struct ixgbe_mbx_info *mbx = &hw->mbx; + s32 retval = mbx->ops.write_posted(hw, msg, size, 0); if (retval) return retval; - return ixgbe_poll_mbx(hw, retmsg, size, 0); + return mbx->ops.read_posted(hw, retmsg, size, 0); } /** @@ -383,6 +380,7 @@ s32 ixgbe_update_mc_addr_list_vf(struct ixgbe_hw *hw, u8 *mc_addr_list, u32 mc_addr_count, ixgbe_mc_addr_itr next, bool clear) { + struct ixgbe_mbx_info *mbx = &hw->mbx; u32 msgbuf[IXGBE_VFMAILBOX_SIZE]; u16 *vector_list = (u16 *)&msgbuf[1]; u32 vector; @@ -414,7 +412,7 @@ s32 ixgbe_update_mc_addr_list_vf(struct ixgbe_hw *hw, u8 *mc_addr_list, vector_list[i] = (u16)vector; } - return ixgbevf_write_msg_read_ack(hw, msgbuf, msgbuf, IXGBE_VFMAILBOX_SIZE); + return mbx->ops.write_posted(hw, msgbuf, IXGBE_VFMAILBOX_SIZE, 0); } /** @@ -436,7 +434,6 @@ s32 ixgbevf_update_xcast_mode(struct ixgbe_hw *hw, int xcast_mode) return IXGBE_ERR_FEATURE_NOT_SUPPORTED; /* Fall through */ case ixgbe_mbox_api_13: - case ixgbe_mbox_api_15: break; default: return IXGBE_ERR_FEATURE_NOT_SUPPORTED; @@ -611,13 +608,12 @@ s32 ixgbe_check_mac_link_vf(struct ixgbe_hw *hw, ixgbe_link_speed *speed, struct ixgbe_mbx_info *mbx = &hw->mbx; struct ixgbe_mac_info *mac = &hw->mac; s32 ret_val = IXGBE_SUCCESS; - u32 in_msg = 0; u32 links_reg; - + u32 in_msg = 0; UNREFERENCED_1PARAMETER(autoneg_wait_to_complete); /* If we were hit with a reset drop the link */ - if (!mbx->ops[0].check_for_rst(hw, 0) || !mbx->timeout) + if (!mbx->ops.check_for_rst(hw, 0) || !mbx->timeout) mac->get_link_status = true; if (!mac->get_link_status) @@ -674,22 +670,21 @@ s32 ixgbe_check_mac_link_vf(struct ixgbe_hw *hw, ixgbe_link_speed *speed, /* if the read failed it could just be a mailbox collision, best wait * until we are called again and don't report an error */ - if (ixgbe_read_mbx(hw, &in_msg, 1, 0)) { - if (hw->api_version >= ixgbe_mbox_api_15) - mac->get_link_status = false; + if (mbx->ops.read(hw, &in_msg, 1, 0)) goto out; - } if (!(in_msg & IXGBE_VT_MSGTYPE_CTS)) { - /* msg is not CTS and is FAILURE we must have lost CTS status */ + /* msg is not CTS and is FAILURE, + * we must have lost CTS status. + */ if (in_msg & IXGBE_VT_MSGTYPE_FAILURE) - ret_val = IXGBE_ERR_MBX; + ret_val = -1; goto out; } /* the pf is talking, if we timed out in the past we reinit */ if (!mbx->timeout) { - ret_val = IXGBE_ERR_TIMEOUT; + ret_val = -1; goto out; } @@ -768,7 +763,6 @@ int ixgbevf_get_queues(struct ixgbe_hw *hw, unsigned int *num_tcs, case ixgbe_mbox_api_11: case ixgbe_mbox_api_12: case ixgbe_mbox_api_13: - case ixgbe_mbox_api_15: break; default: return 0; diff --git a/sys/dev/ixgbe/ixgbe_x540.c b/sys/dev/ixgbe/ixgbe_x540.c index 57cec5b52e1..c06a19555a8 100644 --- a/sys/dev/ixgbe/ixgbe_x540.c +++ b/sys/dev/ixgbe/ixgbe_x540.c @@ -62,7 +62,6 @@ s32 ixgbe_init_ops_X540(struct ixgbe_hw *hw) struct ixgbe_phy_info *phy = &hw->phy; struct ixgbe_eeprom_info *eeprom = &hw->eeprom; s32 ret_val; - u16 i; DEBUGFUNC("ixgbe_init_ops_X540"); @@ -146,8 +145,7 @@ s32 ixgbe_init_ops_X540(struct ixgbe_hw *hw) mac->arc_subsystem_valid = !!(IXGBE_READ_REG(hw, IXGBE_FWSM_BY_MAC(hw)) & IXGBE_FWSM_MODE_MASK); - for (i = 0; i < 64; i++) - hw->mbx.ops[i].init_params = ixgbe_init_mbx_params_pf; + hw->mbx.ops.init_params = ixgbe_init_mbx_params_pf; /* LEDs */ mac->ops.blink_led_start = ixgbe_blink_led_start_X540;