From nobody Fri Sep 27 03:36:11 2024 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4XFGMw3crcz5XPxQ; Fri, 27 Sep 2024 03:36:12 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R11" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4XFGMw3JHRz4nSd; Fri, 27 Sep 2024 03:36:12 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1727408172; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=ByA/cbrOwigKbSYdDcRQ53mF1dxuGn8fi6xViKFSITk=; b=klD+26wxh0oXl/2TjHr711zzpb2+GldBKQeA+jSpEaUEKjAI+Yw9pdiexCrmKb7sDYdGBe 3Z7LPFKhUANFYzHBx/W0LmrsS5NJZjizeDWjQlGyGiz6pcwJh0LPxFh3jw1MhwcgpkIzQL W4RhP1pbAzz9IZ/BHohMg3Z2BRKdZyzWFMl+XEACVUL4d7vi5zZAD1NFPym+4qOliJ4/p+ NCbmNQ/1EJ3cL6UnsKwJddV1JLkzzf73VTlFumwDac3bwOxFLf9OTbPsA3JSXw5jpyP4EM jKijd0EGGrGxNJfwkCgtCgDYndmuEjEW8Qk/d5WceGOojPMyleKEarWCqnqQvg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1727408172; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=ByA/cbrOwigKbSYdDcRQ53mF1dxuGn8fi6xViKFSITk=; b=RZ3UZmOEgKrnbRhuS4mG/ygyOrshjL9419kZ9Xh/5UVEU8w1WmQnzCbFmQPynTd7OOgLro ptjGStoylk7jT2Yw7G7wJA9Ziur2WgI2SW3U8wgFg2y7Z8TxSElRVvkE7wpoAOcrM1OOtI bEXQ3FxeXF7z0Pbkow1EwuNyK4yNRSoWm4SQlyQuDAVEoNBc81xNb/SRcUkAvOEkYB1hlC Xpa/sQSgEHgt5567iHp153/DOcbgi87FYD8Zs85QGN7zaYEkFLwawUztEKWWQoVRk/O82w AVrwlA1DzeDmAxEeqT29xbhBwcdkcgfz3W0Leaj5raN68XQnXsrcm8iVU/Hl6A== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1727408172; a=rsa-sha256; cv=none; b=J9gtmmoaUAoo4FbJCccc6qvQ7Eifwx5MjTsurDt4ZdLttK9y+HV8+slRYWBHKd0ofOhc9l ilctkUteweBmsvtye4RcD20icaQMl6vAEavKRBw7gMZx50M4ha+d+pS0qf/Xg/x7ziQIgZ DZOAiyfy5fuXOOEmcD9Ny4M3cjAVMLIqLeht1mL7ezUybA3kpTUGwlUyqdyVijRaBib8DM X5+MoLTHyTTGg4Kohixd4vOJouez6DaxjnKQH68AAmMvkMJGSwJ7HzGvT3W9IWm786NGSp PUh9O3kw02ZflmkJbYrdBEnKRiCPcNlQ5Kyq1rCBagNPaHVxGPix+wZypz1LHg== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4XFGMw2v8czNx1; Fri, 27 Sep 2024 03:36:12 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 48R3aBgI038780; Fri, 27 Sep 2024 03:36:11 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 48R3aBPD038777; Fri, 27 Sep 2024 03:36:11 GMT (envelope-from git) Date: Fri, 27 Sep 2024 03:36:11 GMT Message-Id: <202409270336.48R3aBPD038777@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Kevin Bowling Subject: git: 8abae0be0fce - stable/14 - ixgbe: introduce new mailbox API List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kbowling X-Git-Repository: src X-Git-Refname: refs/heads/stable/14 X-Git-Reftype: branch X-Git-Commit: 8abae0be0fcec059dba0682def252995f38bc300 Auto-Submitted: auto-generated The branch stable/14 has been updated by kbowling: URL: https://cgit.FreeBSD.org/src/commit/?id=8abae0be0fcec059dba0682def252995f38bc300 commit 8abae0be0fcec059dba0682def252995f38bc300 Author: Jakub Chylkowski AuthorDate: 2024-09-20 02:30:39 +0000 Commit: Kevin Bowling CommitDate: 2024-09-27 03:32:06 +0000 ixgbe: introduce new mailbox API DPDK commit message Current mailbox API does not work as described in documentation and is prone to errors (for example, it is doing locks on read). Introduce new mailbox API and provide compatibility functions with old API. New error codes have been introduced: - IXGBE_ERR_CONFIG - ixgbe_mbx_operations is not correctly set - IXGBE_ERR_TIMEOUT - mailbox operation, e.g. poll for message, timedout - IXGBE_ERR_MBX_NOMSG - no message available on read In addition, some refactoring has been done: mailbox structures were defined twice: in ixgbe_type.h and ixgbe_vf.h. Move them into ixgbe_mbx.h as this header is dedicated for mailbox. Signed-off-by: Jakub Chylkowski Reviewed-by: Alice Michael Reviewed-by: Piotr Pietruszewski Tested-by: Alice Michael Tested-by: Piotr Skajewski Obtained from: DPDK (6d243d2) Reapply message This reverts commit d80c12ba682a6f23791f3d6e657f9e603b152aa2. (cherry picked from commit 7234c3099947d202702e98d844ecd2d649c834d2) --- sys/dev/ixgbe/if_ix.c | 8 +- sys/dev/ixgbe/ixgbe_82599.c | 4 +- sys/dev/ixgbe/ixgbe_mbx.c | 839 ++++++++++++++++++++++++++++++++------------ sys/dev/ixgbe/ixgbe_mbx.h | 59 +++- sys/dev/ixgbe/ixgbe_type.h | 32 +- sys/dev/ixgbe/ixgbe_vf.c | 42 ++- sys/dev/ixgbe/ixgbe_x540.c | 4 +- 7 files changed, 699 insertions(+), 289 deletions(-) diff --git a/sys/dev/ixgbe/if_ix.c b/sys/dev/ixgbe/if_ix.c index 17f1f73a526e..f2b41e19a15e 100644 --- a/sys/dev/ixgbe/if_ix.c +++ b/sys/dev/ixgbe/if_ix.c @@ -879,6 +879,7 @@ 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"); @@ -928,8 +929,11 @@ ixgbe_if_attach_pre(if_ctx_t ctx) goto err_pci; } - if (hw->mbx.ops.init_params) - hw->mbx.ops.init_params(hw); + /* 82598 Does not support SR-IOV, initialize everything else */ + if (hw->mac.type >= ixgbe_mac_82599_vf) { + for (i = 0; i < sc->num_vfs; i++) + hw->mbx.ops[i].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 8c3df0fd4f59..70b4cdc5c6ca 100644 --- a/sys/dev/ixgbe/ixgbe_82599.c +++ b/sys/dev/ixgbe/ixgbe_82599.c @@ -324,6 +324,7 @@ 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"); @@ -385,7 +386,8 @@ 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); - hw->mbx.ops.init_params = ixgbe_init_mbx_params_pf; + for (i = 0; i < 64; i++) + hw->mbx.ops[i].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 c8f839fce85a..0a0c5abde157 100644 --- a/sys/dev/ixgbe/ixgbe_mbx.c +++ b/sys/dev/ixgbe/ixgbe_mbx.c @@ -35,6 +35,9 @@ #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 @@ -47,42 +50,91 @@ 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) + if (size > mbx->size) { + ERROR_REPORT3(IXGBE_ERROR_ARGUMENT, + "Invalid mailbox message size %u, changing to %u", + 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; + } - if (mbx->ops.read) - ret_val = mbx->ops.read(hw, msg, size, mbx_id); + 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); return ret_val; } /** - * ixgbe_write_mbx - Write a message to the mailbox + * ixgbe_write_mbx - Write a message to the mailbox and 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 + * returns SUCCESS if it successfully copied message into the buffer and + * received an ACK to that message within specified period **/ 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_SUCCESS; + s32 ret_val = IXGBE_ERR_MBX; 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_MBX; + ret_val = IXGBE_ERR_PARAM; ERROR_REPORT2(IXGBE_ERROR_ARGUMENT, - "Invalid mailbox message size %d", size); - } else if (mbx->ops.write) - ret_val = mbx->ops.write(hw, msg, size, mbx_id); + "Invalid mailbox message size %u", size); + } else { + ret_val = mbx->ops[mbx_id].write(hw, msg, size, mbx_id); + } return ret_val; } @@ -97,12 +149,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_MBX; + s32 ret_val = IXGBE_ERR_CONFIG; DEBUGFUNC("ixgbe_check_for_msg"); - if (mbx->ops.check_for_msg) - ret_val = mbx->ops.check_for_msg(hw, mbx_id); + if (mbx->ops[mbx_id].check_for_msg) + ret_val = mbx->ops[mbx_id].check_for_msg(hw, mbx_id); return ret_val; } @@ -117,12 +169,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_MBX; + s32 ret_val = IXGBE_ERR_CONFIG; DEBUGFUNC("ixgbe_check_for_ack"); - if (mbx->ops.check_for_ack) - ret_val = mbx->ops.check_for_ack(hw, mbx_id); + if (mbx->ops[mbx_id].check_for_ack) + ret_val = mbx->ops[mbx_id].check_for_ack(hw, mbx_id); return ret_val; } @@ -137,12 +189,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_MBX; + s32 ret_val = IXGBE_ERR_CONFIG; DEBUGFUNC("ixgbe_check_for_rst"); - if (mbx->ops.check_for_rst) - ret_val = mbx->ops.check_for_rst(hw, mbx_id); + if (mbx->ops[mbx_id].check_for_rst) + ret_val = mbx->ops[mbx_id].check_for_rst(hw, mbx_id); return ret_val; } @@ -161,22 +213,23 @@ static s32 ixgbe_poll_for_msg(struct ixgbe_hw *hw, u16 mbx_id) DEBUGFUNC("ixgbe_poll_for_msg"); - if (!countdown || !mbx->ops.check_for_msg) - goto out; + if (!countdown || !mbx->ops[mbx_id].check_for_msg) + return IXGBE_ERR_CONFIG; - while (countdown && mbx->ops.check_for_msg(hw, mbx_id)) { + while (countdown && mbx->ops[mbx_id].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%d mailbox message timedout", mbx_id); + "Polling for VF%u mailbox message timedout", mbx_id); + return IXGBE_ERR_TIMEOUT; + } -out: - return countdown ? IXGBE_SUCCESS : IXGBE_ERR_MBX; + return IXGBE_SUCCESS; } /** @@ -193,115 +246,71 @@ static s32 ixgbe_poll_for_ack(struct ixgbe_hw *hw, u16 mbx_id) DEBUGFUNC("ixgbe_poll_for_ack"); - if (!countdown || !mbx->ops.check_for_ack) - goto out; + if (!countdown || !mbx->ops[mbx_id].check_for_ack) + return IXGBE_ERR_CONFIG; - while (countdown && mbx->ops.check_for_ack(hw, mbx_id)) { + while (countdown && mbx->ops[mbx_id].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%d mailbox ack timedout", mbx_id); + "Polling for VF%u mailbox ack timedout", mbx_id); + return IXGBE_ERR_TIMEOUT; + } -out: - return countdown ? IXGBE_SUCCESS : IXGBE_ERR_MBX; + return IXGBE_SUCCESS; } /** - * ixgbe_read_posted_mbx - Wait for message notification and receive message + * ixgbe_read_mailbox_vf - read VF's mailbox register * @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. + * This function is used to read the mailbox register dedicated for VF without + * losing the read to clear status bits. **/ -s32 ixgbe_read_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, - u16 mbx_id) +static u32 ixgbe_read_mailbox_vf(struct ixgbe_hw *hw) { - struct ixgbe_mbx_info *mbx = &hw->mbx; - s32 ret_val = IXGBE_ERR_MBX; - - DEBUGFUNC("ixgbe_read_posted_mbx"); - - if (!mbx->ops.read) - goto out; + u32 vf_mailbox = IXGBE_READ_REG(hw, IXGBE_VFMAILBOX); - ret_val = ixgbe_poll_for_msg(hw, mbx_id); + vf_mailbox |= hw->mbx.vf_mailbox; + hw->mbx.vf_mailbox |= vf_mailbox % IXGBE_VFMAILBOX_R2C_BITS; - /* 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; + return vf_mailbox; } -/** - * 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) +static void ixgbe_clear_msg_vf(struct ixgbe_hw *hw) { - 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); + u32 vf_mailbox = ixgbe_read_mailbox_vf(hw); - /* 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; + if (vf_mailbox & IXGBE_VFMAILBOX_PFSTS) { + hw->mbx.stats.reqs++; + hw->mbx.vf_mailbox &= ~IXGBE_VFMAILBOX_PFSTS; + } } -/** - * ixgbe_init_mbx_ops_generic - Initialize MB function pointers - * @hw: pointer to the HW structure - * - * Setups up the mailbox read and write message function pointers - **/ -void ixgbe_init_mbx_ops_generic(struct ixgbe_hw *hw) +static void ixgbe_clear_ack_vf(struct ixgbe_hw *hw) { - struct ixgbe_mbx_info *mbx = &hw->mbx; + u32 vf_mailbox = ixgbe_read_mailbox_vf(hw); - mbx->ops.read_posted = ixgbe_read_posted_mbx; - mbx->ops.write_posted = ixgbe_write_posted_mbx; + if (vf_mailbox & IXGBE_VFMAILBOX_PFACK) { + hw->mbx.stats.acks++; + hw->mbx.vf_mailbox &= ~IXGBE_VFMAILBOX_PFACK; + } } -/** - * 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) +static void ixgbe_clear_rst_vf(struct ixgbe_hw *hw) { - u32 v2p_mailbox = IXGBE_READ_REG(hw, IXGBE_VFMAILBOX); - - v2p_mailbox |= hw->mbx.v2p_mailbox; - hw->mbx.v2p_mailbox |= v2p_mailbox & IXGBE_VFMAILBOX_R2C_BITS; + u32 vf_mailbox = ixgbe_read_mailbox_vf(hw); - return v2p_mailbox; + if (vf_mailbox & (IXGBE_VFMAILBOX_RSTI | IXGBE_VFMAILBOX_RSTD)) { + hw->mbx.stats.rsts++; + hw->mbx.vf_mailbox &= ~(IXGBE_VFMAILBOX_RSTI | + IXGBE_VFMAILBOX_RSTD); + } } /** @@ -314,15 +323,12 @@ static u32 ixgbe_read_v2p_mailbox(struct ixgbe_hw *hw) **/ static s32 ixgbe_check_for_bit_vf(struct ixgbe_hw *hw, u32 mask) { - u32 v2p_mailbox = ixgbe_read_v2p_mailbox(hw); - s32 ret_val = IXGBE_ERR_MBX; + u32 vf_mailbox = ixgbe_read_mailbox_vf(hw); - if (v2p_mailbox & mask) - ret_val = IXGBE_SUCCESS; + if (vf_mailbox & mask) + return IXGBE_SUCCESS; - hw->mbx.v2p_mailbox &= ~mask; - - return ret_val; + return IXGBE_ERR_MBX; } /** @@ -334,17 +340,13 @@ 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)) { - ret_val = IXGBE_SUCCESS; - hw->mbx.stats.reqs++; - } + if (!ixgbe_check_for_bit_vf(hw, IXGBE_VFMAILBOX_PFSTS)) + return IXGBE_SUCCESS; - return ret_val; + return IXGBE_ERR_MBX; } /** @@ -356,17 +358,16 @@ 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)) { - ret_val = IXGBE_SUCCESS; - hw->mbx.stats.acks++; + /* TODO: should this be autocleared? */ + ixgbe_clear_ack_vf(hw); + return IXGBE_SUCCESS; } - return ret_val; + return IXGBE_ERR_MBX; } /** @@ -378,18 +379,17 @@ 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_RSTD | - IXGBE_VFMAILBOX_RSTI))) { - ret_val = IXGBE_SUCCESS; - hw->mbx.stats.rsts++; + 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; } - return ret_val; + return IXGBE_ERR_MBX; } /** @@ -400,20 +400,114 @@ 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"); - /* Take ownership of the buffer */ - IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_VFU); + if (!mbx->timeout) + return IXGBE_ERR_CONFIG; - /* reserve mailbox for vf use */ - if (ixgbe_read_v2p_mailbox(hw) & IXGBE_VFMAILBOX_VFU) - ret_val = IXGBE_SUCCESS; + 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; + } 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 @@ -426,6 +520,7 @@ static s32 ixgbe_obtain_mbx_lock_vf(struct ixgbe_hw *hw) 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; @@ -436,11 +531,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_no_write; + goto out; /* flush msg and acks as we are overwriting the message buffer */ - ixgbe_check_for_msg_vf(hw, 0); - ixgbe_check_for_ack_vf(hw, 0); + ixgbe_clear_msg_vf(hw); + ixgbe_clear_ack_vf(hw); /* copy the caller specified message to the mailbox memory buffer */ for (i = 0; i < size; i++) @@ -449,15 +544,22 @@ static s32 ixgbe_write_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size, /* update stats */ hw->mbx.stats.msgs_tx++; - /* Drop VFU and interrupt the PF to tell it a message has been sent */ - IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_REQ); + /* 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); -out_no_write: return ret_val; } /** - * ixgbe_read_mbx_vf - Reads a message from the inbox intended for vf + * 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 @@ -465,19 +567,19 @@ out_no_write: * * returns SUCCESS if it successfully read message from buffer **/ -static s32 ixgbe_read_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size, - u16 mbx_id) +static s32 ixgbe_read_mbx_vf_legacy(struct ixgbe_hw *hw, u32 *msg, u16 size, + u16 mbx_id) { - s32 ret_val = IXGBE_SUCCESS; + s32 ret_val; u16 i; - DEBUGFUNC("ixgbe_read_mbx_vf"); + 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) - goto out_no_read; + return ret_val; /* copy the message from the mailbox memory buffer */ for (i = 0; i < size; i++) @@ -489,34 +591,73 @@ static s32 ixgbe_read_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size, /* update stats */ hw->mbx.stats.msgs_rx++; -out_no_read: - return ret_val; + return IXGBE_SUCCESS; +} + +/** + * ixgbe_read_mbx_vf - 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(struct ixgbe_hw *hw, u32 *msg, u16 size, + u16 mbx_id) +{ + u32 vf_mailbox; + s32 ret_val; + 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); + + /* 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); + + /* update stats */ + hw->mbx.stats.msgs_rx++; + + return IXGBE_SUCCESS; } /** * ixgbe_init_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 + * Initializes single set the hw->mbx struct to correct values for vf mailbox + * Set of legacy functions is being used here */ void ixgbe_init_mbx_params_vf(struct ixgbe_hw *hw) { struct ixgbe_mbx_info *mbx = &hw->mbx; - /* start mailbox as timed out and let the reset_hw call set the timeout - * value to begin communications */ - mbx->timeout = 0; + mbx->timeout = IXGBE_VF_MBX_INIT_TIMEOUT; mbx->usec_delay = IXGBE_VF_MBX_INIT_DELAY; mbx->size = IXGBE_VFMAILBOX_SIZE; - 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; + /* 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->stats.msgs_tx = 0; mbx->stats.msgs_rx = 0; @@ -525,54 +666,110 @@ 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) { - ret_val = IXGBE_SUCCESS; - IXGBE_WRITE_REG(hw, IXGBE_PFMBICR(index), mask); + return IXGBE_SUCCESS; } - return ret_val; + return IXGBE_ERR_MBX; } /** * ixgbe_check_for_msg_pf - checks to see if the VF has sent mail * @hw: pointer to the HW structure - * @vf_number: the VF index + * @vf_id: 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_number) +static s32 ixgbe_check_for_msg_pf(struct ixgbe_hw *hw, u16 vf_id) { - u32 vf_shift = IXGBE_PFMBICR_SHIFT(vf_number); - s32 index = IXGBE_PFMBICR_INDEX(vf_number); - s32 ret_val = IXGBE_ERR_MBX; + u32 vf_shift = IXGBE_PFMBICR_SHIFT(vf_id); + s32 index = IXGBE_PFMBICR_INDEX(vf_id); DEBUGFUNC("ixgbe_check_for_msg_pf"); if (!ixgbe_check_for_bit_pf(hw, IXGBE_PFMBICR_VFREQ_VF1 << vf_shift, - index)) { - ret_val = IXGBE_SUCCESS; - hw->mbx.stats.reqs++; - } + index)) + return IXGBE_SUCCESS; - return ret_val; + return IXGBE_ERR_MBX; } /** * ixgbe_check_for_ack_pf - checks to see if the VF has ACKed * @hw: pointer to the HW structure - * @vf_number: the VF index + * @vf_id: 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_number) +static s32 ixgbe_check_for_ack_pf(struct ixgbe_hw *hw, u16 vf_id) { - u32 vf_shift = IXGBE_PFMBICR_SHIFT(vf_number); - s32 index = IXGBE_PFMBICR_INDEX(vf_number); + u32 vf_shift = IXGBE_PFMBICR_SHIFT(vf_id); + s32 index = IXGBE_PFMBICR_INDEX(vf_id); s32 ret_val = IXGBE_ERR_MBX; DEBUGFUNC("ixgbe_check_for_ack_pf"); @@ -580,7 +777,8 @@ static s32 ixgbe_check_for_ack_pf(struct ixgbe_hw *hw, u16 vf_number) if (!ixgbe_check_for_bit_pf(hw, IXGBE_PFMBICR_VFACK_VF1 << vf_shift, index)) { ret_val = IXGBE_SUCCESS; - hw->mbx.stats.acks++; + /* TODO: should this be autocleared? */ + ixgbe_clear_ack_pf(hw, vf_id); } return ret_val; @@ -589,14 +787,14 @@ static s32 ixgbe_check_for_ack_pf(struct ixgbe_hw *hw, u16 vf_number) /** * ixgbe_check_for_rst_pf - checks to see if the VF has reset * @hw: pointer to the HW structure - * @vf_number: the VF index + * @vf_id: 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_number) +static s32 ixgbe_check_for_rst_pf(struct ixgbe_hw *hw, u16 vf_id) { - u32 vf_shift = IXGBE_PFVFLRE_SHIFT(vf_number); - u32 index = IXGBE_PFVFLRE_INDEX(vf_number); + u32 vf_shift = IXGBE_PFVFLRE_SHIFT(vf_id); + u32 index = IXGBE_PFVFLRE_INDEX(vf_id); s32 ret_val = IXGBE_ERR_MBX; u32 vflre = 0; @@ -628,121 +826,268 @@ static s32 ixgbe_check_for_rst_pf(struct ixgbe_hw *hw, u16 vf_number) /** * ixgbe_obtain_mbx_lock_pf - obtain mailbox lock * @hw: pointer to the HW structure - * @vf_number: the VF index + * @vf_id: the VF index * * return SUCCESS if we obtained the mailbox lock **/ -static s32 ixgbe_obtain_mbx_lock_pf(struct ixgbe_hw *hw, u16 vf_number) +static s32 ixgbe_obtain_mbx_lock_pf(struct ixgbe_hw *hw, u16 vf_id) { + struct ixgbe_mbx_info *mbx = &hw->mbx; *** 667 LINES SKIPPED ***