11a4e3449SJack F Vogel /******************************************************************************
27282444bSPedro F. Giffuni SPDX-License-Identifier: BSD-3-Clause
31a4e3449SJack F Vogel
48455e365SKevin Bowling Copyright (c) 2001-2020, Intel Corporation
51a4e3449SJack F Vogel All rights reserved.
61a4e3449SJack F Vogel
71a4e3449SJack F Vogel Redistribution and use in source and binary forms, with or without
81a4e3449SJack F Vogel modification, are permitted provided that the following conditions are met:
91a4e3449SJack F Vogel
101a4e3449SJack F Vogel 1. Redistributions of source code must retain the above copyright notice,
111a4e3449SJack F Vogel this list of conditions and the following disclaimer.
121a4e3449SJack F Vogel
131a4e3449SJack F Vogel 2. Redistributions in binary form must reproduce the above copyright
141a4e3449SJack F Vogel notice, this list of conditions and the following disclaimer in the
151a4e3449SJack F Vogel documentation and/or other materials provided with the distribution.
161a4e3449SJack F Vogel
171a4e3449SJack F Vogel 3. Neither the name of the Intel Corporation nor the names of its
181a4e3449SJack F Vogel contributors may be used to endorse or promote products derived from
191a4e3449SJack F Vogel this software without specific prior written permission.
201a4e3449SJack F Vogel
211a4e3449SJack F Vogel THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
221a4e3449SJack F Vogel AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
231a4e3449SJack F Vogel IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
241a4e3449SJack F Vogel ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
251a4e3449SJack F Vogel LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
261a4e3449SJack F Vogel CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
271a4e3449SJack F Vogel SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
281a4e3449SJack F Vogel INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
291a4e3449SJack F Vogel CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
301a4e3449SJack F Vogel ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
311a4e3449SJack F Vogel POSSIBILITY OF SUCH DAMAGE.
321a4e3449SJack F Vogel
331a4e3449SJack F Vogel ******************************************************************************/
341a4e3449SJack F Vogel
351a4e3449SJack F Vogel #include "ixgbe_type.h"
361a4e3449SJack F Vogel #include "ixgbe_mbx.h"
371a4e3449SJack F Vogel
387234c309SJakub Chylkowski static s32 ixgbe_poll_for_msg(struct ixgbe_hw *hw, u16 mbx_id);
397234c309SJakub Chylkowski static s32 ixgbe_poll_for_ack(struct ixgbe_hw *hw, u16 mbx_id);
407234c309SJakub Chylkowski
411a4e3449SJack F Vogel /**
423f66b96dSKevin Bowling * ixgbe_read_mbx - Reads a message from the mailbox
433f66b96dSKevin Bowling * @hw: pointer to the HW structure
443f66b96dSKevin Bowling * @msg: The message buffer
453f66b96dSKevin Bowling * @size: Length of buffer
463f66b96dSKevin Bowling * @mbx_id: id of mailbox to read
473f66b96dSKevin Bowling *
483f66b96dSKevin Bowling * returns SUCCESS if it successfully read message from buffer
493f66b96dSKevin Bowling **/
ixgbe_read_mbx(struct ixgbe_hw * hw,u32 * msg,u16 size,u16 mbx_id)503f66b96dSKevin Bowling s32 ixgbe_read_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id)
513f66b96dSKevin Bowling {
523f66b96dSKevin Bowling struct ixgbe_mbx_info *mbx = &hw->mbx;
533f66b96dSKevin Bowling
543f66b96dSKevin Bowling DEBUGFUNC("ixgbe_read_mbx");
553f66b96dSKevin Bowling
563f66b96dSKevin Bowling /* limit read to size of mailbox */
577234c309SJakub Chylkowski if (size > mbx->size) {
587234c309SJakub Chylkowski ERROR_REPORT3(IXGBE_ERROR_ARGUMENT,
597234c309SJakub Chylkowski "Invalid mailbox message size %u, changing to %u",
607234c309SJakub Chylkowski size, mbx->size);
613f66b96dSKevin Bowling size = mbx->size;
627234c309SJakub Chylkowski }
633f66b96dSKevin Bowling
647234c309SJakub Chylkowski if (mbx->ops[mbx_id].read)
657234c309SJakub Chylkowski return mbx->ops[mbx_id].read(hw, msg, size, mbx_id);
667234c309SJakub Chylkowski
677234c309SJakub Chylkowski return IXGBE_ERR_CONFIG;
687234c309SJakub Chylkowski }
697234c309SJakub Chylkowski
707234c309SJakub Chylkowski /**
717234c309SJakub Chylkowski * ixgbe_poll_mbx - Wait for message and read it from the mailbox
727234c309SJakub Chylkowski * @hw: pointer to the HW structure
737234c309SJakub Chylkowski * @msg: The message buffer
747234c309SJakub Chylkowski * @size: Length of buffer
757234c309SJakub Chylkowski * @mbx_id: id of mailbox to read
767234c309SJakub Chylkowski *
777234c309SJakub Chylkowski * returns SUCCESS if it successfully read message from buffer
787234c309SJakub Chylkowski **/
ixgbe_poll_mbx(struct ixgbe_hw * hw,u32 * msg,u16 size,u16 mbx_id)797234c309SJakub Chylkowski s32 ixgbe_poll_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id)
807234c309SJakub Chylkowski {
817234c309SJakub Chylkowski struct ixgbe_mbx_info *mbx = &hw->mbx;
827234c309SJakub Chylkowski s32 ret_val;
837234c309SJakub Chylkowski
847234c309SJakub Chylkowski DEBUGFUNC("ixgbe_poll_mbx");
857234c309SJakub Chylkowski
867234c309SJakub Chylkowski if (!mbx->ops[mbx_id].read || !mbx->ops[mbx_id].check_for_msg ||
877234c309SJakub Chylkowski !mbx->timeout)
887234c309SJakub Chylkowski return IXGBE_ERR_CONFIG;
897234c309SJakub Chylkowski
907234c309SJakub Chylkowski /* limit read to size of mailbox */
917234c309SJakub Chylkowski if (size > mbx->size) {
927234c309SJakub Chylkowski ERROR_REPORT3(IXGBE_ERROR_ARGUMENT,
937234c309SJakub Chylkowski "Invalid mailbox message size %u, changing to %u",
947234c309SJakub Chylkowski size, mbx->size);
957234c309SJakub Chylkowski size = mbx->size;
967234c309SJakub Chylkowski }
977234c309SJakub Chylkowski
987234c309SJakub Chylkowski ret_val = ixgbe_poll_for_msg(hw, mbx_id);
997234c309SJakub Chylkowski /* if ack received read message, otherwise we timed out */
1007234c309SJakub Chylkowski if (!ret_val)
1017234c309SJakub Chylkowski return mbx->ops[mbx_id].read(hw, msg, size, mbx_id);
1023f66b96dSKevin Bowling
1033f66b96dSKevin Bowling return ret_val;
1043f66b96dSKevin Bowling }
1053f66b96dSKevin Bowling
1063f66b96dSKevin Bowling /**
1077234c309SJakub Chylkowski * ixgbe_write_mbx - Write a message to the mailbox and wait for ACK
1083f66b96dSKevin Bowling * @hw: pointer to the HW structure
1093f66b96dSKevin Bowling * @msg: The message buffer
1103f66b96dSKevin Bowling * @size: Length of buffer
1113f66b96dSKevin Bowling * @mbx_id: id of mailbox to write
1123f66b96dSKevin Bowling *
1137234c309SJakub Chylkowski * returns SUCCESS if it successfully copied message into the buffer and
1147234c309SJakub Chylkowski * received an ACK to that message within specified period
1153f66b96dSKevin Bowling **/
ixgbe_write_mbx(struct ixgbe_hw * hw,u32 * msg,u16 size,u16 mbx_id)1163f66b96dSKevin Bowling s32 ixgbe_write_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id)
1173f66b96dSKevin Bowling {
1183f66b96dSKevin Bowling struct ixgbe_mbx_info *mbx = &hw->mbx;
1197234c309SJakub Chylkowski s32 ret_val = IXGBE_ERR_MBX;
1203f66b96dSKevin Bowling
1213f66b96dSKevin Bowling DEBUGFUNC("ixgbe_write_mbx");
1223f66b96dSKevin Bowling
1237234c309SJakub Chylkowski /*
1247234c309SJakub Chylkowski * exit if either we can't write, release
1257234c309SJakub Chylkowski * or there is no timeout defined
1267234c309SJakub Chylkowski */
1277234c309SJakub Chylkowski if (!mbx->ops[mbx_id].write || !mbx->ops[mbx_id].check_for_ack ||
1287234c309SJakub Chylkowski !mbx->ops[mbx_id].release || !mbx->timeout)
1297234c309SJakub Chylkowski return IXGBE_ERR_CONFIG;
1307234c309SJakub Chylkowski
1313f66b96dSKevin Bowling if (size > mbx->size) {
1327234c309SJakub Chylkowski ret_val = IXGBE_ERR_PARAM;
1333f66b96dSKevin Bowling ERROR_REPORT2(IXGBE_ERROR_ARGUMENT,
1347234c309SJakub Chylkowski "Invalid mailbox message size %u", size);
1357234c309SJakub Chylkowski } else {
1367234c309SJakub Chylkowski ret_val = mbx->ops[mbx_id].write(hw, msg, size, mbx_id);
1377234c309SJakub Chylkowski }
1383f66b96dSKevin Bowling
1393f66b96dSKevin Bowling return ret_val;
1403f66b96dSKevin Bowling }
1413f66b96dSKevin Bowling
1423f66b96dSKevin Bowling /**
1433f66b96dSKevin Bowling * ixgbe_check_for_msg - checks to see if someone sent us mail
1443f66b96dSKevin Bowling * @hw: pointer to the HW structure
1453f66b96dSKevin Bowling * @mbx_id: id of mailbox to check
1463f66b96dSKevin Bowling *
1473f66b96dSKevin Bowling * returns SUCCESS if the Status bit was found or else ERR_MBX
1483f66b96dSKevin Bowling **/
ixgbe_check_for_msg(struct ixgbe_hw * hw,u16 mbx_id)1493f66b96dSKevin Bowling s32 ixgbe_check_for_msg(struct ixgbe_hw *hw, u16 mbx_id)
1503f66b96dSKevin Bowling {
1513f66b96dSKevin Bowling struct ixgbe_mbx_info *mbx = &hw->mbx;
1527234c309SJakub Chylkowski s32 ret_val = IXGBE_ERR_CONFIG;
1533f66b96dSKevin Bowling
1543f66b96dSKevin Bowling DEBUGFUNC("ixgbe_check_for_msg");
1553f66b96dSKevin Bowling
1567234c309SJakub Chylkowski if (mbx->ops[mbx_id].check_for_msg)
1577234c309SJakub Chylkowski ret_val = mbx->ops[mbx_id].check_for_msg(hw, mbx_id);
1583f66b96dSKevin Bowling
1593f66b96dSKevin Bowling return ret_val;
1603f66b96dSKevin Bowling }
1613f66b96dSKevin Bowling
1623f66b96dSKevin Bowling /**
1633f66b96dSKevin Bowling * ixgbe_check_for_ack - checks to see if someone sent us ACK
1643f66b96dSKevin Bowling * @hw: pointer to the HW structure
1653f66b96dSKevin Bowling * @mbx_id: id of mailbox to check
1663f66b96dSKevin Bowling *
1673f66b96dSKevin Bowling * returns SUCCESS if the Status bit was found or else ERR_MBX
1683f66b96dSKevin Bowling **/
ixgbe_check_for_ack(struct ixgbe_hw * hw,u16 mbx_id)1693f66b96dSKevin Bowling s32 ixgbe_check_for_ack(struct ixgbe_hw *hw, u16 mbx_id)
1703f66b96dSKevin Bowling {
1713f66b96dSKevin Bowling struct ixgbe_mbx_info *mbx = &hw->mbx;
1727234c309SJakub Chylkowski s32 ret_val = IXGBE_ERR_CONFIG;
1733f66b96dSKevin Bowling
1743f66b96dSKevin Bowling DEBUGFUNC("ixgbe_check_for_ack");
1753f66b96dSKevin Bowling
1767234c309SJakub Chylkowski if (mbx->ops[mbx_id].check_for_ack)
1777234c309SJakub Chylkowski ret_val = mbx->ops[mbx_id].check_for_ack(hw, mbx_id);
1783f66b96dSKevin Bowling
1793f66b96dSKevin Bowling return ret_val;
1803f66b96dSKevin Bowling }
1813f66b96dSKevin Bowling
1823f66b96dSKevin Bowling /**
1833f66b96dSKevin Bowling * ixgbe_check_for_rst - checks to see if other side has reset
1843f66b96dSKevin Bowling * @hw: pointer to the HW structure
1853f66b96dSKevin Bowling * @mbx_id: id of mailbox to check
1863f66b96dSKevin Bowling *
1873f66b96dSKevin Bowling * returns SUCCESS if the Status bit was found or else ERR_MBX
1883f66b96dSKevin Bowling **/
ixgbe_check_for_rst(struct ixgbe_hw * hw,u16 mbx_id)1893f66b96dSKevin Bowling s32 ixgbe_check_for_rst(struct ixgbe_hw *hw, u16 mbx_id)
1903f66b96dSKevin Bowling {
1913f66b96dSKevin Bowling struct ixgbe_mbx_info *mbx = &hw->mbx;
1927234c309SJakub Chylkowski s32 ret_val = IXGBE_ERR_CONFIG;
1933f66b96dSKevin Bowling
1943f66b96dSKevin Bowling DEBUGFUNC("ixgbe_check_for_rst");
1953f66b96dSKevin Bowling
1967234c309SJakub Chylkowski if (mbx->ops[mbx_id].check_for_rst)
1977234c309SJakub Chylkowski ret_val = mbx->ops[mbx_id].check_for_rst(hw, mbx_id);
1983f66b96dSKevin Bowling
1993f66b96dSKevin Bowling return ret_val;
2003f66b96dSKevin Bowling }
2013f66b96dSKevin Bowling
2023f66b96dSKevin Bowling /**
203*0acea458SKevin Bowling * ixgbe_clear_mbx - Clear Mailbox Memory
204*0acea458SKevin Bowling * @hw: pointer to the HW structure
205*0acea458SKevin Bowling * @mbx_id: id of mailbox to write
206*0acea458SKevin Bowling *
207*0acea458SKevin Bowling * Set VFMBMEM of given VF to 0x0.
208*0acea458SKevin Bowling **/
ixgbe_clear_mbx(struct ixgbe_hw * hw,u16 mbx_id)209*0acea458SKevin Bowling s32 ixgbe_clear_mbx(struct ixgbe_hw *hw, u16 mbx_id)
210*0acea458SKevin Bowling {
211*0acea458SKevin Bowling struct ixgbe_mbx_info *mbx = &hw->mbx;
212*0acea458SKevin Bowling s32 ret_val = IXGBE_ERR_CONFIG;
213*0acea458SKevin Bowling
214*0acea458SKevin Bowling DEBUGFUNC("ixgbe_clear_mbx");
215*0acea458SKevin Bowling
216*0acea458SKevin Bowling if (mbx->ops[mbx_id].clear)
217*0acea458SKevin Bowling ret_val = mbx->ops[mbx_id].clear(hw, mbx_id);
218*0acea458SKevin Bowling
219*0acea458SKevin Bowling return ret_val;
220*0acea458SKevin Bowling }
221*0acea458SKevin Bowling
222*0acea458SKevin Bowling /**
2231a4e3449SJack F Vogel * ixgbe_poll_for_msg - Wait for message notification
2241a4e3449SJack F Vogel * @hw: pointer to the HW structure
2251a4e3449SJack F Vogel * @mbx_id: id of mailbox to write
2261a4e3449SJack F Vogel *
2271a4e3449SJack F Vogel * returns SUCCESS if it successfully received a message notification
2281a4e3449SJack F Vogel **/
ixgbe_poll_for_msg(struct ixgbe_hw * hw,u16 mbx_id)2291a4e3449SJack F Vogel static s32 ixgbe_poll_for_msg(struct ixgbe_hw *hw, u16 mbx_id)
2301a4e3449SJack F Vogel {
2311a4e3449SJack F Vogel struct ixgbe_mbx_info *mbx = &hw->mbx;
2321a4e3449SJack F Vogel int countdown = mbx->timeout;
2331a4e3449SJack F Vogel
2341a4e3449SJack F Vogel DEBUGFUNC("ixgbe_poll_for_msg");
2351a4e3449SJack F Vogel
2367234c309SJakub Chylkowski if (!countdown || !mbx->ops[mbx_id].check_for_msg)
2377234c309SJakub Chylkowski return IXGBE_ERR_CONFIG;
2381a4e3449SJack F Vogel
2397234c309SJakub Chylkowski while (countdown && mbx->ops[mbx_id].check_for_msg(hw, mbx_id)) {
2401a4e3449SJack F Vogel countdown--;
2411a4e3449SJack F Vogel if (!countdown)
2421a4e3449SJack F Vogel break;
2431a4e3449SJack F Vogel usec_delay(mbx->usec_delay);
2441a4e3449SJack F Vogel }
2451a4e3449SJack F Vogel
2467234c309SJakub Chylkowski if (countdown == 0) {
247758cc3dcSJack F Vogel ERROR_REPORT2(IXGBE_ERROR_POLLING,
2487234c309SJakub Chylkowski "Polling for VF%u mailbox message timedout", mbx_id);
2497234c309SJakub Chylkowski return IXGBE_ERR_TIMEOUT;
2507234c309SJakub Chylkowski }
251758cc3dcSJack F Vogel
2527234c309SJakub Chylkowski return IXGBE_SUCCESS;
2531a4e3449SJack F Vogel }
2541a4e3449SJack F Vogel
2551a4e3449SJack F Vogel /**
25646981e90SGuinan Sun * ixgbe_poll_for_ack - Wait for message acknowledgment
2571a4e3449SJack F Vogel * @hw: pointer to the HW structure
2581a4e3449SJack F Vogel * @mbx_id: id of mailbox to write
2591a4e3449SJack F Vogel *
26046981e90SGuinan Sun * returns SUCCESS if it successfully received a message acknowledgment
2611a4e3449SJack F Vogel **/
ixgbe_poll_for_ack(struct ixgbe_hw * hw,u16 mbx_id)2621a4e3449SJack F Vogel static s32 ixgbe_poll_for_ack(struct ixgbe_hw *hw, u16 mbx_id)
2631a4e3449SJack F Vogel {
2641a4e3449SJack F Vogel struct ixgbe_mbx_info *mbx = &hw->mbx;
2651a4e3449SJack F Vogel int countdown = mbx->timeout;
2661a4e3449SJack F Vogel
2671a4e3449SJack F Vogel DEBUGFUNC("ixgbe_poll_for_ack");
2681a4e3449SJack F Vogel
2697234c309SJakub Chylkowski if (!countdown || !mbx->ops[mbx_id].check_for_ack)
2707234c309SJakub Chylkowski return IXGBE_ERR_CONFIG;
2711a4e3449SJack F Vogel
2727234c309SJakub Chylkowski while (countdown && mbx->ops[mbx_id].check_for_ack(hw, mbx_id)) {
2731a4e3449SJack F Vogel countdown--;
2741a4e3449SJack F Vogel if (!countdown)
2751a4e3449SJack F Vogel break;
2761a4e3449SJack F Vogel usec_delay(mbx->usec_delay);
2771a4e3449SJack F Vogel }
2781a4e3449SJack F Vogel
2797234c309SJakub Chylkowski if (countdown == 0) {
280758cc3dcSJack F Vogel ERROR_REPORT2(IXGBE_ERROR_POLLING,
2817234c309SJakub Chylkowski "Polling for VF%u mailbox ack timedout", mbx_id);
2827234c309SJakub Chylkowski return IXGBE_ERR_TIMEOUT;
2837234c309SJakub Chylkowski }
284758cc3dcSJack F Vogel
2857234c309SJakub Chylkowski return IXGBE_SUCCESS;
2861a4e3449SJack F Vogel }
2871a4e3449SJack F Vogel
2881a4e3449SJack F Vogel /**
2897234c309SJakub Chylkowski * ixgbe_read_mailbox_vf - read VF's mailbox register
290d80c12baSKevin Bowling * @hw: pointer to the HW structure
291d80c12baSKevin Bowling *
2927234c309SJakub Chylkowski * This function is used to read the mailbox register dedicated for VF without
2937234c309SJakub Chylkowski * losing the read to clear status bits.
294d80c12baSKevin Bowling **/
ixgbe_read_mailbox_vf(struct ixgbe_hw * hw)2957234c309SJakub Chylkowski static u32 ixgbe_read_mailbox_vf(struct ixgbe_hw *hw)
296d80c12baSKevin Bowling {
2977234c309SJakub Chylkowski u32 vf_mailbox = IXGBE_READ_REG(hw, IXGBE_VFMAILBOX);
298d80c12baSKevin Bowling
2997234c309SJakub Chylkowski vf_mailbox |= hw->mbx.vf_mailbox;
3007234c309SJakub Chylkowski hw->mbx.vf_mailbox |= vf_mailbox % IXGBE_VFMAILBOX_R2C_BITS;
301d80c12baSKevin Bowling
3027234c309SJakub Chylkowski return vf_mailbox;
303d80c12baSKevin Bowling }
304d80c12baSKevin Bowling
ixgbe_clear_msg_vf(struct ixgbe_hw * hw)3057234c309SJakub Chylkowski static void ixgbe_clear_msg_vf(struct ixgbe_hw *hw)
306d80c12baSKevin Bowling {
3077234c309SJakub Chylkowski u32 vf_mailbox = ixgbe_read_mailbox_vf(hw);
308d80c12baSKevin Bowling
3097234c309SJakub Chylkowski if (vf_mailbox & IXGBE_VFMAILBOX_PFSTS) {
3107234c309SJakub Chylkowski hw->mbx.stats.reqs++;
3117234c309SJakub Chylkowski hw->mbx.vf_mailbox &= ~IXGBE_VFMAILBOX_PFSTS;
3127234c309SJakub Chylkowski }
313d80c12baSKevin Bowling }
314d80c12baSKevin Bowling
ixgbe_clear_ack_vf(struct ixgbe_hw * hw)3157234c309SJakub Chylkowski static void ixgbe_clear_ack_vf(struct ixgbe_hw *hw)
3161a4e3449SJack F Vogel {
3177234c309SJakub Chylkowski u32 vf_mailbox = ixgbe_read_mailbox_vf(hw);
3181a4e3449SJack F Vogel
3197234c309SJakub Chylkowski if (vf_mailbox & IXGBE_VFMAILBOX_PFACK) {
3207234c309SJakub Chylkowski hw->mbx.stats.acks++;
3217234c309SJakub Chylkowski hw->mbx.vf_mailbox &= ~IXGBE_VFMAILBOX_PFACK;
3227234c309SJakub Chylkowski }
3231a4e3449SJack F Vogel }
3241a4e3449SJack F Vogel
ixgbe_clear_rst_vf(struct ixgbe_hw * hw)3257234c309SJakub Chylkowski static void ixgbe_clear_rst_vf(struct ixgbe_hw *hw)
3261a4e3449SJack F Vogel {
3277234c309SJakub Chylkowski u32 vf_mailbox = ixgbe_read_mailbox_vf(hw);
3281a4e3449SJack F Vogel
3297234c309SJakub Chylkowski if (vf_mailbox & (IXGBE_VFMAILBOX_RSTI | IXGBE_VFMAILBOX_RSTD)) {
3307234c309SJakub Chylkowski hw->mbx.stats.rsts++;
3317234c309SJakub Chylkowski hw->mbx.vf_mailbox &= ~(IXGBE_VFMAILBOX_RSTI |
3327234c309SJakub Chylkowski IXGBE_VFMAILBOX_RSTD);
3337234c309SJakub Chylkowski }
3341a4e3449SJack F Vogel }
3351a4e3449SJack F Vogel
3361a4e3449SJack F Vogel /**
3371a4e3449SJack F Vogel * ixgbe_check_for_bit_vf - Determine if a status bit was set
3381a4e3449SJack F Vogel * @hw: pointer to the HW structure
3391a4e3449SJack F Vogel * @mask: bitmask for bits to be tested and cleared
3401a4e3449SJack F Vogel *
3411a4e3449SJack F Vogel * This function is used to check for the read to clear bits within
3421a4e3449SJack F Vogel * the V2P mailbox.
3431a4e3449SJack F Vogel **/
ixgbe_check_for_bit_vf(struct ixgbe_hw * hw,u32 mask)3441a4e3449SJack F Vogel static s32 ixgbe_check_for_bit_vf(struct ixgbe_hw *hw, u32 mask)
3451a4e3449SJack F Vogel {
3467234c309SJakub Chylkowski u32 vf_mailbox = ixgbe_read_mailbox_vf(hw);
3471a4e3449SJack F Vogel
3487234c309SJakub Chylkowski if (vf_mailbox & mask)
3497234c309SJakub Chylkowski return IXGBE_SUCCESS;
3501a4e3449SJack F Vogel
3517234c309SJakub Chylkowski return IXGBE_ERR_MBX;
3521a4e3449SJack F Vogel }
3531a4e3449SJack F Vogel
3541a4e3449SJack F Vogel /**
3551a4e3449SJack F Vogel * ixgbe_check_for_msg_vf - checks to see if the PF has sent mail
3561a4e3449SJack F Vogel * @hw: pointer to the HW structure
3571a4e3449SJack F Vogel * @mbx_id: id of mailbox to check
3581a4e3449SJack F Vogel *
3591a4e3449SJack F Vogel * returns SUCCESS if the PF has set the Status bit or else ERR_MBX
3601a4e3449SJack F Vogel **/
ixgbe_check_for_msg_vf(struct ixgbe_hw * hw,u16 mbx_id)3611a4e3449SJack F Vogel static s32 ixgbe_check_for_msg_vf(struct ixgbe_hw *hw, u16 mbx_id)
3621a4e3449SJack F Vogel {
36385d0a26eSJack F Vogel UNREFERENCED_1PARAMETER(mbx_id);
3641a4e3449SJack F Vogel DEBUGFUNC("ixgbe_check_for_msg_vf");
3651a4e3449SJack F Vogel
3667234c309SJakub Chylkowski if (!ixgbe_check_for_bit_vf(hw, IXGBE_VFMAILBOX_PFSTS))
3677234c309SJakub Chylkowski return IXGBE_SUCCESS;
3681a4e3449SJack F Vogel
3697234c309SJakub Chylkowski return IXGBE_ERR_MBX;
3701a4e3449SJack F Vogel }
3711a4e3449SJack F Vogel
3721a4e3449SJack F Vogel /**
3731a4e3449SJack F Vogel * ixgbe_check_for_ack_vf - checks to see if the PF has ACK'd
3741a4e3449SJack F Vogel * @hw: pointer to the HW structure
3751a4e3449SJack F Vogel * @mbx_id: id of mailbox to check
3761a4e3449SJack F Vogel *
3771a4e3449SJack F Vogel * returns SUCCESS if the PF has set the ACK bit or else ERR_MBX
3781a4e3449SJack F Vogel **/
ixgbe_check_for_ack_vf(struct ixgbe_hw * hw,u16 mbx_id)3791a4e3449SJack F Vogel static s32 ixgbe_check_for_ack_vf(struct ixgbe_hw *hw, u16 mbx_id)
3801a4e3449SJack F Vogel {
38185d0a26eSJack F Vogel UNREFERENCED_1PARAMETER(mbx_id);
3821a4e3449SJack F Vogel DEBUGFUNC("ixgbe_check_for_ack_vf");
3831a4e3449SJack F Vogel
3841a4e3449SJack F Vogel if (!ixgbe_check_for_bit_vf(hw, IXGBE_VFMAILBOX_PFACK)) {
3857234c309SJakub Chylkowski /* TODO: should this be autocleared? */
3867234c309SJakub Chylkowski ixgbe_clear_ack_vf(hw);
3877234c309SJakub Chylkowski return IXGBE_SUCCESS;
3881a4e3449SJack F Vogel }
3891a4e3449SJack F Vogel
3907234c309SJakub Chylkowski return IXGBE_ERR_MBX;
3911a4e3449SJack F Vogel }
3921a4e3449SJack F Vogel
3931a4e3449SJack F Vogel /**
3941a4e3449SJack F Vogel * ixgbe_check_for_rst_vf - checks to see if the PF has reset
3951a4e3449SJack F Vogel * @hw: pointer to the HW structure
3961a4e3449SJack F Vogel * @mbx_id: id of mailbox to check
3971a4e3449SJack F Vogel *
39879b36ec9SKevin Bowling * returns true if the PF has set the reset done bit or else false
3991a4e3449SJack F Vogel **/
ixgbe_check_for_rst_vf(struct ixgbe_hw * hw,u16 mbx_id)4001a4e3449SJack F Vogel static s32 ixgbe_check_for_rst_vf(struct ixgbe_hw *hw, u16 mbx_id)
4011a4e3449SJack F Vogel {
40285d0a26eSJack F Vogel UNREFERENCED_1PARAMETER(mbx_id);
4031a4e3449SJack F Vogel DEBUGFUNC("ixgbe_check_for_rst_vf");
4041a4e3449SJack F Vogel
4057234c309SJakub Chylkowski if (!ixgbe_check_for_bit_vf(hw, IXGBE_VFMAILBOX_RSTI |
4067234c309SJakub Chylkowski IXGBE_VFMAILBOX_RSTD)) {
4077234c309SJakub Chylkowski /* TODO: should this be autocleared? */
4087234c309SJakub Chylkowski ixgbe_clear_rst_vf(hw);
4097234c309SJakub Chylkowski return IXGBE_SUCCESS;
4101a4e3449SJack F Vogel }
4111a4e3449SJack F Vogel
4127234c309SJakub Chylkowski return IXGBE_ERR_MBX;
4131a4e3449SJack F Vogel }
4141a4e3449SJack F Vogel
4151a4e3449SJack F Vogel /**
4161a4e3449SJack F Vogel * ixgbe_obtain_mbx_lock_vf - obtain mailbox lock
4171a4e3449SJack F Vogel * @hw: pointer to the HW structure
4181a4e3449SJack F Vogel *
4191a4e3449SJack F Vogel * return SUCCESS if we obtained the mailbox lock
4201a4e3449SJack F Vogel **/
ixgbe_obtain_mbx_lock_vf(struct ixgbe_hw * hw)4211a4e3449SJack F Vogel static s32 ixgbe_obtain_mbx_lock_vf(struct ixgbe_hw *hw)
4221a4e3449SJack F Vogel {
4237234c309SJakub Chylkowski struct ixgbe_mbx_info *mbx = &hw->mbx;
4247234c309SJakub Chylkowski int countdown = mbx->timeout;
4251a4e3449SJack F Vogel s32 ret_val = IXGBE_ERR_MBX;
4267234c309SJakub Chylkowski u32 vf_mailbox;
4271a4e3449SJack F Vogel
4281a4e3449SJack F Vogel DEBUGFUNC("ixgbe_obtain_mbx_lock_vf");
4291a4e3449SJack F Vogel
4307234c309SJakub Chylkowski if (!mbx->timeout)
4317234c309SJakub Chylkowski return IXGBE_ERR_CONFIG;
4321a4e3449SJack F Vogel
4337234c309SJakub Chylkowski while (countdown--) {
4347234c309SJakub Chylkowski /* Reserve mailbox for VF use */
4357234c309SJakub Chylkowski vf_mailbox = ixgbe_read_mailbox_vf(hw);
4367234c309SJakub Chylkowski vf_mailbox |= IXGBE_VFMAILBOX_VFU;
4377234c309SJakub Chylkowski IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, vf_mailbox);
4387234c309SJakub Chylkowski
4397234c309SJakub Chylkowski /* Verify that VF is the owner of the lock */
4407234c309SJakub Chylkowski if (ixgbe_read_mailbox_vf(hw) & IXGBE_VFMAILBOX_VFU) {
4411a4e3449SJack F Vogel ret_val = IXGBE_SUCCESS;
4427234c309SJakub Chylkowski break;
4437234c309SJakub Chylkowski }
4447234c309SJakub Chylkowski
4457234c309SJakub Chylkowski /* Wait a bit before trying again */
4467234c309SJakub Chylkowski usec_delay(mbx->usec_delay);
4477234c309SJakub Chylkowski }
4487234c309SJakub Chylkowski
4497234c309SJakub Chylkowski if (ret_val != IXGBE_SUCCESS) {
4507234c309SJakub Chylkowski ERROR_REPORT1(IXGBE_ERROR_INVALID_STATE,
4517234c309SJakub Chylkowski "Failed to obtain mailbox lock");
4527234c309SJakub Chylkowski ret_val = IXGBE_ERR_TIMEOUT;
4537234c309SJakub Chylkowski }
4541a4e3449SJack F Vogel
4551a4e3449SJack F Vogel return ret_val;
4561a4e3449SJack F Vogel }
4571a4e3449SJack F Vogel
4581a4e3449SJack F Vogel /**
4597234c309SJakub Chylkowski * ixgbe_release_mbx_lock_dummy - release mailbox lock
4607234c309SJakub Chylkowski * @hw: pointer to the HW structure
4617234c309SJakub Chylkowski * @mbx_id: id of mailbox to read
4627234c309SJakub Chylkowski **/
ixgbe_release_mbx_lock_dummy(struct ixgbe_hw * hw,u16 mbx_id)4637234c309SJakub Chylkowski static void ixgbe_release_mbx_lock_dummy(struct ixgbe_hw *hw, u16 mbx_id)
4647234c309SJakub Chylkowski {
4657234c309SJakub Chylkowski UNREFERENCED_2PARAMETER(hw, mbx_id);
4667234c309SJakub Chylkowski
4677234c309SJakub Chylkowski DEBUGFUNC("ixgbe_release_mbx_lock_dummy");
4687234c309SJakub Chylkowski }
4697234c309SJakub Chylkowski
4707234c309SJakub Chylkowski /**
4717234c309SJakub Chylkowski * ixgbe_release_mbx_lock_vf - release mailbox lock
4727234c309SJakub Chylkowski * @hw: pointer to the HW structure
4737234c309SJakub Chylkowski * @mbx_id: id of mailbox to read
4747234c309SJakub Chylkowski **/
ixgbe_release_mbx_lock_vf(struct ixgbe_hw * hw,u16 mbx_id)4757234c309SJakub Chylkowski static void ixgbe_release_mbx_lock_vf(struct ixgbe_hw *hw, u16 mbx_id)
4767234c309SJakub Chylkowski {
4777234c309SJakub Chylkowski u32 vf_mailbox;
4787234c309SJakub Chylkowski
4797234c309SJakub Chylkowski UNREFERENCED_1PARAMETER(mbx_id);
4807234c309SJakub Chylkowski
4817234c309SJakub Chylkowski DEBUGFUNC("ixgbe_release_mbx_lock_vf");
4827234c309SJakub Chylkowski
4837234c309SJakub Chylkowski /* Return ownership of the buffer */
4847234c309SJakub Chylkowski vf_mailbox = ixgbe_read_mailbox_vf(hw);
4857234c309SJakub Chylkowski vf_mailbox &= ~IXGBE_VFMAILBOX_VFU;
4867234c309SJakub Chylkowski IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, vf_mailbox);
4877234c309SJakub Chylkowski }
4887234c309SJakub Chylkowski
4897234c309SJakub Chylkowski /**
4907234c309SJakub Chylkowski * ixgbe_write_mbx_vf_legacy - Write a message to the mailbox
4917234c309SJakub Chylkowski * @hw: pointer to the HW structure
4927234c309SJakub Chylkowski * @msg: The message buffer
4937234c309SJakub Chylkowski * @size: Length of buffer
4947234c309SJakub Chylkowski * @mbx_id: id of mailbox to write
4957234c309SJakub Chylkowski *
4967234c309SJakub Chylkowski * returns SUCCESS if it successfully copied message into the buffer
4977234c309SJakub Chylkowski **/
ixgbe_write_mbx_vf_legacy(struct ixgbe_hw * hw,u32 * msg,u16 size,u16 mbx_id)4987234c309SJakub Chylkowski static s32 ixgbe_write_mbx_vf_legacy(struct ixgbe_hw *hw, u32 *msg, u16 size,
4997234c309SJakub Chylkowski u16 mbx_id)
5007234c309SJakub Chylkowski {
5017234c309SJakub Chylkowski s32 ret_val;
5027234c309SJakub Chylkowski u16 i;
5037234c309SJakub Chylkowski
5047234c309SJakub Chylkowski UNREFERENCED_1PARAMETER(mbx_id);
5057234c309SJakub Chylkowski DEBUGFUNC("ixgbe_write_mbx_vf_legacy");
5067234c309SJakub Chylkowski
5077234c309SJakub Chylkowski /* lock the mailbox to prevent pf/vf race condition */
5087234c309SJakub Chylkowski ret_val = ixgbe_obtain_mbx_lock_vf(hw);
5097234c309SJakub Chylkowski if (ret_val)
5107234c309SJakub Chylkowski return ret_val;
5117234c309SJakub Chylkowski
5127234c309SJakub Chylkowski /* flush msg and acks as we are overwriting the message buffer */
5137234c309SJakub Chylkowski ixgbe_check_for_msg_vf(hw, 0);
5147234c309SJakub Chylkowski ixgbe_clear_msg_vf(hw);
5157234c309SJakub Chylkowski ixgbe_check_for_ack_vf(hw, 0);
5167234c309SJakub Chylkowski ixgbe_clear_ack_vf(hw);
5177234c309SJakub Chylkowski
5187234c309SJakub Chylkowski /* copy the caller specified message to the mailbox memory buffer */
5197234c309SJakub Chylkowski for (i = 0; i < size; i++)
5207234c309SJakub Chylkowski IXGBE_WRITE_REG_ARRAY(hw, IXGBE_VFMBMEM, i, msg[i]);
5217234c309SJakub Chylkowski
5227234c309SJakub Chylkowski /* update stats */
5237234c309SJakub Chylkowski hw->mbx.stats.msgs_tx++;
5247234c309SJakub Chylkowski
5257234c309SJakub Chylkowski /* interrupt the PF to tell it a message has been sent */
5267234c309SJakub Chylkowski IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_REQ);
5277234c309SJakub Chylkowski
5287234c309SJakub Chylkowski return IXGBE_SUCCESS;
5297234c309SJakub Chylkowski }
5307234c309SJakub Chylkowski
5317234c309SJakub Chylkowski /**
5321a4e3449SJack F Vogel * ixgbe_write_mbx_vf - Write a message to the mailbox
5331a4e3449SJack F Vogel * @hw: pointer to the HW structure
5341a4e3449SJack F Vogel * @msg: The message buffer
5351a4e3449SJack F Vogel * @size: Length of buffer
5361a4e3449SJack F Vogel * @mbx_id: id of mailbox to write
5371a4e3449SJack F Vogel *
5381a4e3449SJack F Vogel * returns SUCCESS if it successfully copied message into the buffer
5391a4e3449SJack F Vogel **/
ixgbe_write_mbx_vf(struct ixgbe_hw * hw,u32 * msg,u16 size,u16 mbx_id)5401a4e3449SJack F Vogel static s32 ixgbe_write_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size,
5411a4e3449SJack F Vogel u16 mbx_id)
5421a4e3449SJack F Vogel {
5437234c309SJakub Chylkowski u32 vf_mailbox;
5441a4e3449SJack F Vogel s32 ret_val;
5451a4e3449SJack F Vogel u16 i;
5461a4e3449SJack F Vogel
54785d0a26eSJack F Vogel UNREFERENCED_1PARAMETER(mbx_id);
5481a4e3449SJack F Vogel
5491a4e3449SJack F Vogel DEBUGFUNC("ixgbe_write_mbx_vf");
5501a4e3449SJack F Vogel
5511a4e3449SJack F Vogel /* lock the mailbox to prevent pf/vf race condition */
5521a4e3449SJack F Vogel ret_val = ixgbe_obtain_mbx_lock_vf(hw);
5531a4e3449SJack F Vogel if (ret_val)
5547234c309SJakub Chylkowski goto out;
5551a4e3449SJack F Vogel
5561a4e3449SJack F Vogel /* flush msg and acks as we are overwriting the message buffer */
5577234c309SJakub Chylkowski ixgbe_clear_msg_vf(hw);
5587234c309SJakub Chylkowski ixgbe_clear_ack_vf(hw);
5591a4e3449SJack F Vogel
5601a4e3449SJack F Vogel /* copy the caller specified message to the mailbox memory buffer */
5611a4e3449SJack F Vogel for (i = 0; i < size; i++)
5621a4e3449SJack F Vogel IXGBE_WRITE_REG_ARRAY(hw, IXGBE_VFMBMEM, i, msg[i]);
5631a4e3449SJack F Vogel
5641a4e3449SJack F Vogel /* update stats */
5651a4e3449SJack F Vogel hw->mbx.stats.msgs_tx++;
5661a4e3449SJack F Vogel
5677234c309SJakub Chylkowski /* interrupt the PF to tell it a message has been sent */
5687234c309SJakub Chylkowski vf_mailbox = ixgbe_read_mailbox_vf(hw);
5697234c309SJakub Chylkowski vf_mailbox |= IXGBE_VFMAILBOX_REQ;
5707234c309SJakub Chylkowski IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, vf_mailbox);
5711a4e3449SJack F Vogel
5727234c309SJakub Chylkowski /* if msg sent wait until we receive an ack */
5737234c309SJakub Chylkowski ixgbe_poll_for_ack(hw, mbx_id);
5747234c309SJakub Chylkowski
5757234c309SJakub Chylkowski out:
5767234c309SJakub Chylkowski hw->mbx.ops[mbx_id].release(hw, mbx_id);
5777234c309SJakub Chylkowski
5781a4e3449SJack F Vogel return ret_val;
5791a4e3449SJack F Vogel }
5801a4e3449SJack F Vogel
5811a4e3449SJack F Vogel /**
5827234c309SJakub Chylkowski * ixgbe_read_mbx_vf_legacy - Reads a message from the inbox intended for vf
5837234c309SJakub Chylkowski * @hw: pointer to the HW structure
5847234c309SJakub Chylkowski * @msg: The message buffer
5857234c309SJakub Chylkowski * @size: Length of buffer
5867234c309SJakub Chylkowski * @mbx_id: id of mailbox to read
5877234c309SJakub Chylkowski *
5887234c309SJakub Chylkowski * returns SUCCESS if it successfully read message from buffer
5897234c309SJakub Chylkowski **/
ixgbe_read_mbx_vf_legacy(struct ixgbe_hw * hw,u32 * msg,u16 size,u16 mbx_id)5907234c309SJakub Chylkowski static s32 ixgbe_read_mbx_vf_legacy(struct ixgbe_hw *hw, u32 *msg, u16 size,
5917234c309SJakub Chylkowski u16 mbx_id)
5927234c309SJakub Chylkowski {
5937234c309SJakub Chylkowski s32 ret_val;
5947234c309SJakub Chylkowski u16 i;
5957234c309SJakub Chylkowski
5967234c309SJakub Chylkowski DEBUGFUNC("ixgbe_read_mbx_vf_legacy");
5977234c309SJakub Chylkowski UNREFERENCED_1PARAMETER(mbx_id);
5987234c309SJakub Chylkowski
5997234c309SJakub Chylkowski /* lock the mailbox to prevent pf/vf race condition */
6007234c309SJakub Chylkowski ret_val = ixgbe_obtain_mbx_lock_vf(hw);
6017234c309SJakub Chylkowski if (ret_val)
6027234c309SJakub Chylkowski return ret_val;
6037234c309SJakub Chylkowski
6047234c309SJakub Chylkowski /* copy the message from the mailbox memory buffer */
6057234c309SJakub Chylkowski for (i = 0; i < size; i++)
6067234c309SJakub Chylkowski msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_VFMBMEM, i);
6077234c309SJakub Chylkowski
6087234c309SJakub Chylkowski /* Acknowledge receipt and release mailbox, then we're done */
6097234c309SJakub Chylkowski IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_ACK);
6107234c309SJakub Chylkowski
6117234c309SJakub Chylkowski /* update stats */
6127234c309SJakub Chylkowski hw->mbx.stats.msgs_rx++;
6137234c309SJakub Chylkowski
6147234c309SJakub Chylkowski return IXGBE_SUCCESS;
6157234c309SJakub Chylkowski }
6167234c309SJakub Chylkowski
6177234c309SJakub Chylkowski /**
6181a4e3449SJack F Vogel * ixgbe_read_mbx_vf - Reads a message from the inbox intended for vf
6191a4e3449SJack F Vogel * @hw: pointer to the HW structure
6201a4e3449SJack F Vogel * @msg: The message buffer
6211a4e3449SJack F Vogel * @size: Length of buffer
6221a4e3449SJack F Vogel * @mbx_id: id of mailbox to read
6231a4e3449SJack F Vogel *
624363089d8SPedro F. Giffuni * returns SUCCESS if it successfully read message from buffer
6251a4e3449SJack F Vogel **/
ixgbe_read_mbx_vf(struct ixgbe_hw * hw,u32 * msg,u16 size,u16 mbx_id)6261a4e3449SJack F Vogel static s32 ixgbe_read_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size,
6271a4e3449SJack F Vogel u16 mbx_id)
6281a4e3449SJack F Vogel {
6297234c309SJakub Chylkowski u32 vf_mailbox;
6307234c309SJakub Chylkowski s32 ret_val;
6311a4e3449SJack F Vogel u16 i;
6321a4e3449SJack F Vogel
6331a4e3449SJack F Vogel DEBUGFUNC("ixgbe_read_mbx_vf");
63485d0a26eSJack F Vogel UNREFERENCED_1PARAMETER(mbx_id);
6351a4e3449SJack F Vogel
6367234c309SJakub Chylkowski /* check if there is a message from PF */
6377234c309SJakub Chylkowski ret_val = ixgbe_check_for_msg_vf(hw, 0);
6387234c309SJakub Chylkowski if (ret_val != IXGBE_SUCCESS)
6397234c309SJakub Chylkowski return IXGBE_ERR_MBX_NOMSG;
6407234c309SJakub Chylkowski
6417234c309SJakub Chylkowski ixgbe_clear_msg_vf(hw);
6421a4e3449SJack F Vogel
6431a4e3449SJack F Vogel /* copy the message from the mailbox memory buffer */
6441a4e3449SJack F Vogel for (i = 0; i < size; i++)
6451a4e3449SJack F Vogel msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_VFMBMEM, i);
6461a4e3449SJack F Vogel
6477234c309SJakub Chylkowski /* Acknowledge receipt */
6487234c309SJakub Chylkowski vf_mailbox = ixgbe_read_mailbox_vf(hw);
6497234c309SJakub Chylkowski vf_mailbox |= IXGBE_VFMAILBOX_ACK;
6507234c309SJakub Chylkowski IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, vf_mailbox);
6511a4e3449SJack F Vogel
6521a4e3449SJack F Vogel /* update stats */
6531a4e3449SJack F Vogel hw->mbx.stats.msgs_rx++;
6541a4e3449SJack F Vogel
6557234c309SJakub Chylkowski return IXGBE_SUCCESS;
6561a4e3449SJack F Vogel }
6571a4e3449SJack F Vogel
6581a4e3449SJack F Vogel /**
6591a4e3449SJack F Vogel * ixgbe_init_mbx_params_vf - set initial values for vf mailbox
6601a4e3449SJack F Vogel * @hw: pointer to the HW structure
6611a4e3449SJack F Vogel *
6627234c309SJakub Chylkowski * Initializes single set the hw->mbx struct to correct values for vf mailbox
6637234c309SJakub Chylkowski * Set of legacy functions is being used here
6641a4e3449SJack F Vogel */
ixgbe_init_mbx_params_vf(struct ixgbe_hw * hw)6651a4e3449SJack F Vogel void ixgbe_init_mbx_params_vf(struct ixgbe_hw *hw)
6661a4e3449SJack F Vogel {
6671a4e3449SJack F Vogel struct ixgbe_mbx_info *mbx = &hw->mbx;
6681a4e3449SJack F Vogel
6697234c309SJakub Chylkowski mbx->timeout = IXGBE_VF_MBX_INIT_TIMEOUT;
6701a4e3449SJack F Vogel mbx->usec_delay = IXGBE_VF_MBX_INIT_DELAY;
6711a4e3449SJack F Vogel
6721a4e3449SJack F Vogel mbx->size = IXGBE_VFMAILBOX_SIZE;
6731a4e3449SJack F Vogel
6747234c309SJakub Chylkowski /* VF has only one mailbox connection, no need for more IDs */
6757234c309SJakub Chylkowski mbx->ops[0].release = ixgbe_release_mbx_lock_dummy;
6767234c309SJakub Chylkowski mbx->ops[0].read = ixgbe_read_mbx_vf_legacy;
6777234c309SJakub Chylkowski mbx->ops[0].write = ixgbe_write_mbx_vf_legacy;
6787234c309SJakub Chylkowski mbx->ops[0].check_for_msg = ixgbe_check_for_msg_vf;
6797234c309SJakub Chylkowski mbx->ops[0].check_for_ack = ixgbe_check_for_ack_vf;
6807234c309SJakub Chylkowski mbx->ops[0].check_for_rst = ixgbe_check_for_rst_vf;
681*0acea458SKevin Bowling mbx->ops[0].clear = NULL;
6821a4e3449SJack F Vogel
6831a4e3449SJack F Vogel mbx->stats.msgs_tx = 0;
6841a4e3449SJack F Vogel mbx->stats.msgs_rx = 0;
6851a4e3449SJack F Vogel mbx->stats.reqs = 0;
6861a4e3449SJack F Vogel mbx->stats.acks = 0;
6871a4e3449SJack F Vogel mbx->stats.rsts = 0;
6881a4e3449SJack F Vogel }
6891a4e3449SJack F Vogel
6907234c309SJakub Chylkowski /**
6917234c309SJakub Chylkowski * ixgbe_upgrade_mbx_params_vf - set initial values for vf mailbox
6927234c309SJakub Chylkowski * @hw: pointer to the HW structure
6937234c309SJakub Chylkowski *
6947234c309SJakub Chylkowski * Initializes the hw->mbx struct to correct values for vf mailbox
6957234c309SJakub Chylkowski */
ixgbe_upgrade_mbx_params_vf(struct ixgbe_hw * hw)6967234c309SJakub Chylkowski void ixgbe_upgrade_mbx_params_vf(struct ixgbe_hw *hw)
6977234c309SJakub Chylkowski {
6987234c309SJakub Chylkowski struct ixgbe_mbx_info *mbx = &hw->mbx;
6997234c309SJakub Chylkowski
7007234c309SJakub Chylkowski mbx->timeout = IXGBE_VF_MBX_INIT_TIMEOUT;
7017234c309SJakub Chylkowski mbx->usec_delay = IXGBE_VF_MBX_INIT_DELAY;
7027234c309SJakub Chylkowski
7037234c309SJakub Chylkowski mbx->size = IXGBE_VFMAILBOX_SIZE;
7047234c309SJakub Chylkowski
7057234c309SJakub Chylkowski /* VF has only one mailbox connection, no need for more IDs */
7067234c309SJakub Chylkowski mbx->ops[0].release = ixgbe_release_mbx_lock_vf;
7077234c309SJakub Chylkowski mbx->ops[0].read = ixgbe_read_mbx_vf;
7087234c309SJakub Chylkowski mbx->ops[0].write = ixgbe_write_mbx_vf;
7097234c309SJakub Chylkowski mbx->ops[0].check_for_msg = ixgbe_check_for_msg_vf;
7107234c309SJakub Chylkowski mbx->ops[0].check_for_ack = ixgbe_check_for_ack_vf;
7117234c309SJakub Chylkowski mbx->ops[0].check_for_rst = ixgbe_check_for_rst_vf;
7127234c309SJakub Chylkowski mbx->ops[0].clear = NULL;
7137234c309SJakub Chylkowski
7147234c309SJakub Chylkowski mbx->stats.msgs_tx = 0;
7157234c309SJakub Chylkowski mbx->stats.msgs_rx = 0;
7167234c309SJakub Chylkowski mbx->stats.reqs = 0;
7177234c309SJakub Chylkowski mbx->stats.acks = 0;
7187234c309SJakub Chylkowski mbx->stats.rsts = 0;
7197234c309SJakub Chylkowski }
7207234c309SJakub Chylkowski
ixgbe_clear_msg_pf(struct ixgbe_hw * hw,u16 vf_id)7217234c309SJakub Chylkowski static void ixgbe_clear_msg_pf(struct ixgbe_hw *hw, u16 vf_id)
7227234c309SJakub Chylkowski {
7237234c309SJakub Chylkowski u32 vf_shift = IXGBE_PFMBICR_SHIFT(vf_id);
7247234c309SJakub Chylkowski s32 index = IXGBE_PFMBICR_INDEX(vf_id);
7257234c309SJakub Chylkowski u32 pfmbicr;
7267234c309SJakub Chylkowski
7277234c309SJakub Chylkowski pfmbicr = IXGBE_READ_REG(hw, IXGBE_PFMBICR(index));
7287234c309SJakub Chylkowski
7297234c309SJakub Chylkowski if (pfmbicr & (IXGBE_PFMBICR_VFREQ_VF1 << vf_shift))
7307234c309SJakub Chylkowski hw->mbx.stats.reqs++;
7317234c309SJakub Chylkowski
7327234c309SJakub Chylkowski IXGBE_WRITE_REG(hw, IXGBE_PFMBICR(index),
7337234c309SJakub Chylkowski IXGBE_PFMBICR_VFREQ_VF1 << vf_shift);
7347234c309SJakub Chylkowski }
7357234c309SJakub Chylkowski
ixgbe_clear_ack_pf(struct ixgbe_hw * hw,u16 vf_id)7367234c309SJakub Chylkowski static void ixgbe_clear_ack_pf(struct ixgbe_hw *hw, u16 vf_id)
7377234c309SJakub Chylkowski {
7387234c309SJakub Chylkowski u32 vf_shift = IXGBE_PFMBICR_SHIFT(vf_id);
7397234c309SJakub Chylkowski s32 index = IXGBE_PFMBICR_INDEX(vf_id);
7407234c309SJakub Chylkowski u32 pfmbicr;
7417234c309SJakub Chylkowski
7427234c309SJakub Chylkowski pfmbicr = IXGBE_READ_REG(hw, IXGBE_PFMBICR(index));
7437234c309SJakub Chylkowski
7447234c309SJakub Chylkowski if (pfmbicr & (IXGBE_PFMBICR_VFACK_VF1 << vf_shift))
7457234c309SJakub Chylkowski hw->mbx.stats.acks++;
7467234c309SJakub Chylkowski
7477234c309SJakub Chylkowski IXGBE_WRITE_REG(hw, IXGBE_PFMBICR(index),
7487234c309SJakub Chylkowski IXGBE_PFMBICR_VFACK_VF1 << vf_shift);
7497234c309SJakub Chylkowski }
7507234c309SJakub Chylkowski
ixgbe_check_for_bit_pf(struct ixgbe_hw * hw,u32 mask,s32 index)7511a4e3449SJack F Vogel static s32 ixgbe_check_for_bit_pf(struct ixgbe_hw *hw, u32 mask, s32 index)
7521a4e3449SJack F Vogel {
753b3c7fde6SJakub Chylkowski u32 pfmbicr = IXGBE_READ_REG(hw, IXGBE_PFMBICR(index));
7541a4e3449SJack F Vogel
755b3c7fde6SJakub Chylkowski if (pfmbicr & mask) {
7567234c309SJakub Chylkowski return IXGBE_SUCCESS;
7571a4e3449SJack F Vogel }
7581a4e3449SJack F Vogel
7597234c309SJakub Chylkowski return IXGBE_ERR_MBX;
7601a4e3449SJack F Vogel }
7611a4e3449SJack F Vogel
7621a4e3449SJack F Vogel /**
7631a4e3449SJack F Vogel * ixgbe_check_for_msg_pf - checks to see if the VF has sent mail
7641a4e3449SJack F Vogel * @hw: pointer to the HW structure
7657234c309SJakub Chylkowski * @vf_id: the VF index
7661a4e3449SJack F Vogel *
7671a4e3449SJack F Vogel * returns SUCCESS if the VF has set the Status bit or else ERR_MBX
7681a4e3449SJack F Vogel **/
ixgbe_check_for_msg_pf(struct ixgbe_hw * hw,u16 vf_id)7697234c309SJakub Chylkowski static s32 ixgbe_check_for_msg_pf(struct ixgbe_hw *hw, u16 vf_id)
7701a4e3449SJack F Vogel {
7717234c309SJakub Chylkowski u32 vf_shift = IXGBE_PFMBICR_SHIFT(vf_id);
7727234c309SJakub Chylkowski s32 index = IXGBE_PFMBICR_INDEX(vf_id);
7731a4e3449SJack F Vogel
7741a4e3449SJack F Vogel DEBUGFUNC("ixgbe_check_for_msg_pf");
7751a4e3449SJack F Vogel
776b3c7fde6SJakub Chylkowski if (!ixgbe_check_for_bit_pf(hw, IXGBE_PFMBICR_VFREQ_VF1 << vf_shift,
7777234c309SJakub Chylkowski index))
7787234c309SJakub Chylkowski return IXGBE_SUCCESS;
7791a4e3449SJack F Vogel
7807234c309SJakub Chylkowski return IXGBE_ERR_MBX;
7811a4e3449SJack F Vogel }
7821a4e3449SJack F Vogel
7831a4e3449SJack F Vogel /**
7841a4e3449SJack F Vogel * ixgbe_check_for_ack_pf - checks to see if the VF has ACKed
7851a4e3449SJack F Vogel * @hw: pointer to the HW structure
7867234c309SJakub Chylkowski * @vf_id: the VF index
7871a4e3449SJack F Vogel *
7881a4e3449SJack F Vogel * returns SUCCESS if the VF has set the Status bit or else ERR_MBX
7891a4e3449SJack F Vogel **/
ixgbe_check_for_ack_pf(struct ixgbe_hw * hw,u16 vf_id)7907234c309SJakub Chylkowski static s32 ixgbe_check_for_ack_pf(struct ixgbe_hw *hw, u16 vf_id)
7911a4e3449SJack F Vogel {
7927234c309SJakub Chylkowski u32 vf_shift = IXGBE_PFMBICR_SHIFT(vf_id);
7937234c309SJakub Chylkowski s32 index = IXGBE_PFMBICR_INDEX(vf_id);
7941a4e3449SJack F Vogel s32 ret_val = IXGBE_ERR_MBX;
7951a4e3449SJack F Vogel
7961a4e3449SJack F Vogel DEBUGFUNC("ixgbe_check_for_ack_pf");
7971a4e3449SJack F Vogel
798b3c7fde6SJakub Chylkowski if (!ixgbe_check_for_bit_pf(hw, IXGBE_PFMBICR_VFACK_VF1 << vf_shift,
7991a4e3449SJack F Vogel index)) {
8001a4e3449SJack F Vogel ret_val = IXGBE_SUCCESS;
8017234c309SJakub Chylkowski /* TODO: should this be autocleared? */
8027234c309SJakub Chylkowski ixgbe_clear_ack_pf(hw, vf_id);
8031a4e3449SJack F Vogel }
8041a4e3449SJack F Vogel
8051a4e3449SJack F Vogel return ret_val;
8061a4e3449SJack F Vogel }
8071a4e3449SJack F Vogel
8081a4e3449SJack F Vogel /**
8091a4e3449SJack F Vogel * ixgbe_check_for_rst_pf - checks to see if the VF has reset
8101a4e3449SJack F Vogel * @hw: pointer to the HW structure
8117234c309SJakub Chylkowski * @vf_id: the VF index
8121a4e3449SJack F Vogel *
8131a4e3449SJack F Vogel * returns SUCCESS if the VF has set the Status bit or else ERR_MBX
8141a4e3449SJack F Vogel **/
ixgbe_check_for_rst_pf(struct ixgbe_hw * hw,u16 vf_id)8157234c309SJakub Chylkowski static s32 ixgbe_check_for_rst_pf(struct ixgbe_hw *hw, u16 vf_id)
8161a4e3449SJack F Vogel {
8177234c309SJakub Chylkowski u32 vf_shift = IXGBE_PFVFLRE_SHIFT(vf_id);
8187234c309SJakub Chylkowski u32 index = IXGBE_PFVFLRE_INDEX(vf_id);
8191a4e3449SJack F Vogel s32 ret_val = IXGBE_ERR_MBX;
820b3c7fde6SJakub Chylkowski u32 vflre = 0;
8211a4e3449SJack F Vogel
8221a4e3449SJack F Vogel DEBUGFUNC("ixgbe_check_for_rst_pf");
8231a4e3449SJack F Vogel
824182b3808SJack F Vogel switch (hw->mac.type) {
825182b3808SJack F Vogel case ixgbe_mac_82599EB:
826b3c7fde6SJakub Chylkowski vflre = IXGBE_READ_REG(hw, IXGBE_PFVFLRE(index));
827182b3808SJack F Vogel break;
828758cc3dcSJack F Vogel case ixgbe_mac_X550:
829758cc3dcSJack F Vogel case ixgbe_mac_X550EM_x:
8308eb6488eSEric Joyner case ixgbe_mac_X550EM_a:
83185d0a26eSJack F Vogel case ixgbe_mac_X540:
832b3c7fde6SJakub Chylkowski vflre = IXGBE_READ_REG(hw, IXGBE_PFVFLREC(index));
83385d0a26eSJack F Vogel break;
834182b3808SJack F Vogel default:
835182b3808SJack F Vogel break;
836182b3808SJack F Vogel }
8371a4e3449SJack F Vogel
8381a4e3449SJack F Vogel if (vflre & (1 << vf_shift)) {
8391a4e3449SJack F Vogel ret_val = IXGBE_SUCCESS;
840b3c7fde6SJakub Chylkowski IXGBE_WRITE_REG(hw, IXGBE_PFVFLREC(index), (1 << vf_shift));
8411a4e3449SJack F Vogel hw->mbx.stats.rsts++;
8421a4e3449SJack F Vogel }
8431a4e3449SJack F Vogel
8441a4e3449SJack F Vogel return ret_val;
8451a4e3449SJack F Vogel }
8461a4e3449SJack F Vogel
8471a4e3449SJack F Vogel /**
8481a4e3449SJack F Vogel * ixgbe_obtain_mbx_lock_pf - obtain mailbox lock
8491a4e3449SJack F Vogel * @hw: pointer to the HW structure
8507234c309SJakub Chylkowski * @vf_id: the VF index
8511a4e3449SJack F Vogel *
8521a4e3449SJack F Vogel * return SUCCESS if we obtained the mailbox lock
8531a4e3449SJack F Vogel **/
ixgbe_obtain_mbx_lock_pf(struct ixgbe_hw * hw,u16 vf_id)8547234c309SJakub Chylkowski static s32 ixgbe_obtain_mbx_lock_pf(struct ixgbe_hw *hw, u16 vf_id)
8551a4e3449SJack F Vogel {
8567234c309SJakub Chylkowski struct ixgbe_mbx_info *mbx = &hw->mbx;
8577234c309SJakub Chylkowski int countdown = mbx->timeout;
8581a4e3449SJack F Vogel s32 ret_val = IXGBE_ERR_MBX;
8597234c309SJakub Chylkowski u32 pf_mailbox;
8601a4e3449SJack F Vogel
8611a4e3449SJack F Vogel DEBUGFUNC("ixgbe_obtain_mbx_lock_pf");
8621a4e3449SJack F Vogel
8637234c309SJakub Chylkowski if (!mbx->timeout)
8647234c309SJakub Chylkowski return IXGBE_ERR_CONFIG;
8651a4e3449SJack F Vogel
8667234c309SJakub Chylkowski while (countdown--) {
8677234c309SJakub Chylkowski /* Reserve mailbox for PF use */
8687234c309SJakub Chylkowski pf_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_id));
8697234c309SJakub Chylkowski pf_mailbox |= IXGBE_PFMAILBOX_PFU;
8707234c309SJakub Chylkowski IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_id), pf_mailbox);
8717234c309SJakub Chylkowski
8727234c309SJakub Chylkowski /* Verify that PF is the owner of the lock */
8737234c309SJakub Chylkowski pf_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_id));
8747234c309SJakub Chylkowski if (pf_mailbox & IXGBE_PFMAILBOX_PFU) {
8751a4e3449SJack F Vogel ret_val = IXGBE_SUCCESS;
8767234c309SJakub Chylkowski break;
8777234c309SJakub Chylkowski }
878758cc3dcSJack F Vogel
8797234c309SJakub Chylkowski /* Wait a bit before trying again */
8807234c309SJakub Chylkowski usec_delay(mbx->usec_delay);
8817234c309SJakub Chylkowski }
8827234c309SJakub Chylkowski
8837234c309SJakub Chylkowski if (ret_val != IXGBE_SUCCESS) {
8847234c309SJakub Chylkowski ERROR_REPORT1(IXGBE_ERROR_INVALID_STATE,
8857234c309SJakub Chylkowski "Failed to obtain mailbox lock");
8867234c309SJakub Chylkowski ret_val = IXGBE_ERR_TIMEOUT;
8877234c309SJakub Chylkowski }
8881a4e3449SJack F Vogel
8891a4e3449SJack F Vogel return ret_val;
8901a4e3449SJack F Vogel }
8911a4e3449SJack F Vogel
8921a4e3449SJack F Vogel /**
8937234c309SJakub Chylkowski * ixgbe_release_mbx_lock_pf - release mailbox lock
8947234c309SJakub Chylkowski * @hw: pointer to the HW structure
8957234c309SJakub Chylkowski * @vf_id: the VF index
8967234c309SJakub Chylkowski **/
ixgbe_release_mbx_lock_pf(struct ixgbe_hw * hw,u16 vf_id)8977234c309SJakub Chylkowski static void ixgbe_release_mbx_lock_pf(struct ixgbe_hw *hw, u16 vf_id)
8987234c309SJakub Chylkowski {
8997234c309SJakub Chylkowski u32 pf_mailbox;
9007234c309SJakub Chylkowski
9017234c309SJakub Chylkowski DEBUGFUNC("ixgbe_release_mbx_lock_pf");
9027234c309SJakub Chylkowski
9037234c309SJakub Chylkowski /* Return ownership of the buffer */
9047234c309SJakub Chylkowski pf_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_id));
9057234c309SJakub Chylkowski pf_mailbox &= ~IXGBE_PFMAILBOX_PFU;
9067234c309SJakub Chylkowski IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_id), pf_mailbox);
9077234c309SJakub Chylkowski }
9087234c309SJakub Chylkowski
9097234c309SJakub Chylkowski /**
9107234c309SJakub Chylkowski * ixgbe_write_mbx_pf_legacy - Places a message in the mailbox
9117234c309SJakub Chylkowski * @hw: pointer to the HW structure
9127234c309SJakub Chylkowski * @msg: The message buffer
9137234c309SJakub Chylkowski * @size: Length of buffer
9147234c309SJakub Chylkowski * @vf_id: the VF index
9157234c309SJakub Chylkowski *
9167234c309SJakub Chylkowski * returns SUCCESS if it successfully copied message into the buffer
9177234c309SJakub Chylkowski **/
ixgbe_write_mbx_pf_legacy(struct ixgbe_hw * hw,u32 * msg,u16 size,u16 vf_id)9187234c309SJakub Chylkowski static s32 ixgbe_write_mbx_pf_legacy(struct ixgbe_hw *hw, u32 *msg, u16 size,
9197234c309SJakub Chylkowski u16 vf_id)
9207234c309SJakub Chylkowski {
9217234c309SJakub Chylkowski s32 ret_val;
9227234c309SJakub Chylkowski u16 i;
9237234c309SJakub Chylkowski
9247234c309SJakub Chylkowski DEBUGFUNC("ixgbe_write_mbx_pf_legacy");
9257234c309SJakub Chylkowski
9267234c309SJakub Chylkowski /* lock the mailbox to prevent pf/vf race condition */
9277234c309SJakub Chylkowski ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_id);
9287234c309SJakub Chylkowski if (ret_val)
9297234c309SJakub Chylkowski return ret_val;
9307234c309SJakub Chylkowski
9317234c309SJakub Chylkowski /* flush msg and acks as we are overwriting the message buffer */
9327234c309SJakub Chylkowski ixgbe_check_for_msg_pf(hw, vf_id);
9337234c309SJakub Chylkowski ixgbe_clear_msg_pf(hw, vf_id);
9347234c309SJakub Chylkowski ixgbe_check_for_ack_pf(hw, vf_id);
9357234c309SJakub Chylkowski ixgbe_clear_ack_pf(hw, vf_id);
9367234c309SJakub Chylkowski
9377234c309SJakub Chylkowski /* copy the caller specified message to the mailbox memory buffer */
9387234c309SJakub Chylkowski for (i = 0; i < size; i++)
9397234c309SJakub Chylkowski IXGBE_WRITE_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_id), i, msg[i]);
9407234c309SJakub Chylkowski
9417234c309SJakub Chylkowski /* Interrupt VF to tell it a message has been sent and release buffer*/
9427234c309SJakub Chylkowski IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_id), IXGBE_PFMAILBOX_STS);
9437234c309SJakub Chylkowski
9447234c309SJakub Chylkowski /* update stats */
9457234c309SJakub Chylkowski hw->mbx.stats.msgs_tx++;
9467234c309SJakub Chylkowski
9477234c309SJakub Chylkowski return IXGBE_SUCCESS;
9487234c309SJakub Chylkowski }
9497234c309SJakub Chylkowski
9507234c309SJakub Chylkowski /**
9511a4e3449SJack F Vogel * ixgbe_write_mbx_pf - Places a message in the mailbox
9521a4e3449SJack F Vogel * @hw: pointer to the HW structure
9531a4e3449SJack F Vogel * @msg: The message buffer
9541a4e3449SJack F Vogel * @size: Length of buffer
9557234c309SJakub Chylkowski * @vf_id: the VF index
9561a4e3449SJack F Vogel *
9571a4e3449SJack F Vogel * returns SUCCESS if it successfully copied message into the buffer
9581a4e3449SJack F Vogel **/
ixgbe_write_mbx_pf(struct ixgbe_hw * hw,u32 * msg,u16 size,u16 vf_id)9591a4e3449SJack F Vogel static s32 ixgbe_write_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size,
9607234c309SJakub Chylkowski u16 vf_id)
9611a4e3449SJack F Vogel {
9627234c309SJakub Chylkowski u32 pf_mailbox;
9631a4e3449SJack F Vogel s32 ret_val;
9641a4e3449SJack F Vogel u16 i;
9651a4e3449SJack F Vogel
9661a4e3449SJack F Vogel DEBUGFUNC("ixgbe_write_mbx_pf");
9671a4e3449SJack F Vogel
9681a4e3449SJack F Vogel /* lock the mailbox to prevent pf/vf race condition */
9697234c309SJakub Chylkowski ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_id);
9701a4e3449SJack F Vogel if (ret_val)
9717234c309SJakub Chylkowski goto out;
9721a4e3449SJack F Vogel
9731a4e3449SJack F Vogel /* flush msg and acks as we are overwriting the message buffer */
9747234c309SJakub Chylkowski ixgbe_clear_msg_pf(hw, vf_id);
9757234c309SJakub Chylkowski ixgbe_clear_ack_pf(hw, vf_id);
9761a4e3449SJack F Vogel
9771a4e3449SJack F Vogel /* copy the caller specified message to the mailbox memory buffer */
9781a4e3449SJack F Vogel for (i = 0; i < size; i++)
9797234c309SJakub Chylkowski IXGBE_WRITE_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_id), i, msg[i]);
9801a4e3449SJack F Vogel
9817234c309SJakub Chylkowski /* Interrupt VF to tell it a message has been sent */
9827234c309SJakub Chylkowski pf_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_id));
9837234c309SJakub Chylkowski pf_mailbox |= IXGBE_PFMAILBOX_STS;
9847234c309SJakub Chylkowski IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_id), pf_mailbox);
9857234c309SJakub Chylkowski
9867234c309SJakub Chylkowski /* if msg sent wait until we receive an ack */
9877234c309SJakub Chylkowski ixgbe_poll_for_ack(hw, vf_id);
9881a4e3449SJack F Vogel
9891a4e3449SJack F Vogel /* update stats */
9901a4e3449SJack F Vogel hw->mbx.stats.msgs_tx++;
9911a4e3449SJack F Vogel
9927234c309SJakub Chylkowski out:
9937234c309SJakub Chylkowski hw->mbx.ops[vf_id].release(hw, vf_id);
9947234c309SJakub Chylkowski
9951a4e3449SJack F Vogel return ret_val;
9961a4e3449SJack F Vogel
9971a4e3449SJack F Vogel }
9981a4e3449SJack F Vogel
9991a4e3449SJack F Vogel /**
10007234c309SJakub Chylkowski * ixgbe_read_mbx_pf_legacy - Read a message from the mailbox
10017234c309SJakub Chylkowski * @hw: pointer to the HW structure
10027234c309SJakub Chylkowski * @msg: The message buffer
10037234c309SJakub Chylkowski * @size: Length of buffer
10047234c309SJakub Chylkowski * @vf_id: the VF index
10057234c309SJakub Chylkowski *
10067234c309SJakub Chylkowski * This function copies a message from the mailbox buffer to the caller's
10077234c309SJakub Chylkowski * memory buffer. The presumption is that the caller knows that there was
10087234c309SJakub Chylkowski * a message due to a VF request so no polling for message is needed.
10097234c309SJakub Chylkowski **/
ixgbe_read_mbx_pf_legacy(struct ixgbe_hw * hw,u32 * msg,u16 size,u16 vf_id)10107234c309SJakub Chylkowski static s32 ixgbe_read_mbx_pf_legacy(struct ixgbe_hw *hw, u32 *msg, u16 size,
10117234c309SJakub Chylkowski u16 vf_id)
10127234c309SJakub Chylkowski {
10137234c309SJakub Chylkowski s32 ret_val;
10147234c309SJakub Chylkowski u16 i;
10157234c309SJakub Chylkowski
10167234c309SJakub Chylkowski DEBUGFUNC("ixgbe_read_mbx_pf_legacy");
10177234c309SJakub Chylkowski
10187234c309SJakub Chylkowski /* lock the mailbox to prevent pf/vf race condition */
10197234c309SJakub Chylkowski ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_id);
10207234c309SJakub Chylkowski if (ret_val != IXGBE_SUCCESS)
10217234c309SJakub Chylkowski return ret_val;
10227234c309SJakub Chylkowski
10237234c309SJakub Chylkowski /* copy the message to the mailbox memory buffer */
10247234c309SJakub Chylkowski for (i = 0; i < size; i++)
10257234c309SJakub Chylkowski msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_id), i);
10267234c309SJakub Chylkowski
10277234c309SJakub Chylkowski /* Acknowledge the message and release buffer */
10287234c309SJakub Chylkowski IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_id), IXGBE_PFMAILBOX_ACK);
10297234c309SJakub Chylkowski
10307234c309SJakub Chylkowski /* update stats */
10317234c309SJakub Chylkowski hw->mbx.stats.msgs_rx++;
10327234c309SJakub Chylkowski
10337234c309SJakub Chylkowski return IXGBE_SUCCESS;
10347234c309SJakub Chylkowski }
10357234c309SJakub Chylkowski
10367234c309SJakub Chylkowski /**
10371a4e3449SJack F Vogel * ixgbe_read_mbx_pf - Read a message from the mailbox
10381a4e3449SJack F Vogel * @hw: pointer to the HW structure
10391a4e3449SJack F Vogel * @msg: The message buffer
10401a4e3449SJack F Vogel * @size: Length of buffer
10417234c309SJakub Chylkowski * @vf_id: the VF index
10421a4e3449SJack F Vogel *
10431a4e3449SJack F Vogel * This function copies a message from the mailbox buffer to the caller's
10441a4e3449SJack F Vogel * memory buffer. The presumption is that the caller knows that there was
10451a4e3449SJack F Vogel * a message due to a VF request so no polling for message is needed.
10461a4e3449SJack F Vogel **/
ixgbe_read_mbx_pf(struct ixgbe_hw * hw,u32 * msg,u16 size,u16 vf_id)10471a4e3449SJack F Vogel static s32 ixgbe_read_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size,
10487234c309SJakub Chylkowski u16 vf_id)
10491a4e3449SJack F Vogel {
10507234c309SJakub Chylkowski u32 pf_mailbox;
10511a4e3449SJack F Vogel s32 ret_val;
10521a4e3449SJack F Vogel u16 i;
10531a4e3449SJack F Vogel
10541a4e3449SJack F Vogel DEBUGFUNC("ixgbe_read_mbx_pf");
10551a4e3449SJack F Vogel
10567234c309SJakub Chylkowski /* check if there is a message from VF */
10577234c309SJakub Chylkowski ret_val = ixgbe_check_for_msg_pf(hw, vf_id);
10587234c309SJakub Chylkowski if (ret_val != IXGBE_SUCCESS)
10597234c309SJakub Chylkowski return IXGBE_ERR_MBX_NOMSG;
10607234c309SJakub Chylkowski
10617234c309SJakub Chylkowski ixgbe_clear_msg_pf(hw, vf_id);
10621a4e3449SJack F Vogel
10631a4e3449SJack F Vogel /* copy the message to the mailbox memory buffer */
10641a4e3449SJack F Vogel for (i = 0; i < size; i++)
10657234c309SJakub Chylkowski msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_id), i);
10661a4e3449SJack F Vogel
10671a4e3449SJack F Vogel /* Acknowledge the message and release buffer */
10687234c309SJakub Chylkowski pf_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_id));
10697234c309SJakub Chylkowski pf_mailbox |= IXGBE_PFMAILBOX_ACK;
10707234c309SJakub Chylkowski IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_id), pf_mailbox);
10711a4e3449SJack F Vogel
10721a4e3449SJack F Vogel /* update stats */
10731a4e3449SJack F Vogel hw->mbx.stats.msgs_rx++;
10741a4e3449SJack F Vogel
10757234c309SJakub Chylkowski return IXGBE_SUCCESS;
10767234c309SJakub Chylkowski }
10777234c309SJakub Chylkowski
10787234c309SJakub Chylkowski /**
1079*0acea458SKevin Bowling * ixgbe_clear_mbx_pf - Clear Mailbox Memory
1080*0acea458SKevin Bowling * @hw: pointer to the HW structure
1081*0acea458SKevin Bowling * @vf_id: the VF index
1082*0acea458SKevin Bowling *
1083*0acea458SKevin Bowling * Set VFMBMEM of given VF to 0x0.
1084*0acea458SKevin Bowling **/
ixgbe_clear_mbx_pf(struct ixgbe_hw * hw,u16 vf_id)1085*0acea458SKevin Bowling static s32 ixgbe_clear_mbx_pf(struct ixgbe_hw *hw, u16 vf_id)
1086*0acea458SKevin Bowling {
1087*0acea458SKevin Bowling u16 mbx_size = hw->mbx.size;
1088*0acea458SKevin Bowling u16 i;
1089*0acea458SKevin Bowling
1090*0acea458SKevin Bowling if (vf_id > 63)
1091*0acea458SKevin Bowling return IXGBE_ERR_PARAM;
1092*0acea458SKevin Bowling
1093*0acea458SKevin Bowling for (i = 0; i < mbx_size; ++i)
1094*0acea458SKevin Bowling IXGBE_WRITE_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_id), i, 0x0);
1095*0acea458SKevin Bowling
1096*0acea458SKevin Bowling return IXGBE_SUCCESS;
1097*0acea458SKevin Bowling }
1098*0acea458SKevin Bowling
1099*0acea458SKevin Bowling /**
11007234c309SJakub Chylkowski * ixgbe_init_mbx_params_pf_id - set initial values for pf mailbox
11017234c309SJakub Chylkowski * @hw: pointer to the HW structure
11027234c309SJakub Chylkowski * @vf_id: the VF index
11037234c309SJakub Chylkowski *
11047234c309SJakub Chylkowski * Initializes single set of the hw->mbx struct to correct values for pf mailbox
11057234c309SJakub Chylkowski * Set of legacy functions is being used here
11067234c309SJakub Chylkowski */
ixgbe_init_mbx_params_pf_id(struct ixgbe_hw * hw,u16 vf_id)11077234c309SJakub Chylkowski void ixgbe_init_mbx_params_pf_id(struct ixgbe_hw *hw, u16 vf_id)
11087234c309SJakub Chylkowski {
11097234c309SJakub Chylkowski struct ixgbe_mbx_info *mbx = &hw->mbx;
11107234c309SJakub Chylkowski
11117234c309SJakub Chylkowski mbx->ops[vf_id].release = ixgbe_release_mbx_lock_dummy;
11127234c309SJakub Chylkowski mbx->ops[vf_id].read = ixgbe_read_mbx_pf_legacy;
11137234c309SJakub Chylkowski mbx->ops[vf_id].write = ixgbe_write_mbx_pf_legacy;
11147234c309SJakub Chylkowski mbx->ops[vf_id].check_for_msg = ixgbe_check_for_msg_pf;
11157234c309SJakub Chylkowski mbx->ops[vf_id].check_for_ack = ixgbe_check_for_ack_pf;
11167234c309SJakub Chylkowski mbx->ops[vf_id].check_for_rst = ixgbe_check_for_rst_pf;
1117*0acea458SKevin Bowling mbx->ops[vf_id].clear = ixgbe_clear_mbx_pf;
11181a4e3449SJack F Vogel }
11191a4e3449SJack F Vogel
11201a4e3449SJack F Vogel /**
11211a4e3449SJack F Vogel * ixgbe_init_mbx_params_pf - set initial values for pf mailbox
11221a4e3449SJack F Vogel * @hw: pointer to the HW structure
11231a4e3449SJack F Vogel *
11247234c309SJakub Chylkowski * Initializes all sets of the hw->mbx struct to correct values for pf
11257234c309SJakub Chylkowski * mailbox. One set corresponds to single VF. It also initializes counters
11267234c309SJakub Chylkowski * and general variables. A set of legacy functions is used by default.
11271a4e3449SJack F Vogel */
ixgbe_init_mbx_params_pf(struct ixgbe_hw * hw)11281a4e3449SJack F Vogel void ixgbe_init_mbx_params_pf(struct ixgbe_hw *hw)
11291a4e3449SJack F Vogel {
11307234c309SJakub Chylkowski u16 i;
11311a4e3449SJack F Vogel struct ixgbe_mbx_info *mbx = &hw->mbx;
11321a4e3449SJack F Vogel
11337234c309SJakub Chylkowski /* Ensure we are not calling this function from VF */
113485d0a26eSJack F Vogel if (hw->mac.type != ixgbe_mac_82599EB &&
1135758cc3dcSJack F Vogel hw->mac.type != ixgbe_mac_X550 &&
1136758cc3dcSJack F Vogel hw->mac.type != ixgbe_mac_X550EM_x &&
11378eb6488eSEric Joyner hw->mac.type != ixgbe_mac_X550EM_a &&
113885d0a26eSJack F Vogel hw->mac.type != ixgbe_mac_X540)
11391a4e3449SJack F Vogel return;
11401a4e3449SJack F Vogel
11417234c309SJakub Chylkowski /* Initialize common mailbox settings */
11427234c309SJakub Chylkowski mbx->timeout = IXGBE_VF_MBX_INIT_TIMEOUT;
11437234c309SJakub Chylkowski mbx->usec_delay = IXGBE_VF_MBX_INIT_DELAY;
11441a4e3449SJack F Vogel mbx->size = IXGBE_VFMAILBOX_SIZE;
11451a4e3449SJack F Vogel
11467234c309SJakub Chylkowski /* Initialize counters with zeroes */
11477234c309SJakub Chylkowski mbx->stats.msgs_tx = 0;
11487234c309SJakub Chylkowski mbx->stats.msgs_rx = 0;
11497234c309SJakub Chylkowski mbx->stats.reqs = 0;
11507234c309SJakub Chylkowski mbx->stats.acks = 0;
11517234c309SJakub Chylkowski mbx->stats.rsts = 0;
11527234c309SJakub Chylkowski
11537234c309SJakub Chylkowski /* No matter of VF number, we initialize params for all 64 VFs. */
11547234c309SJakub Chylkowski /* TODO: 1. Add a define for max VF and refactor SHARED to get rid
11557234c309SJakub Chylkowski * of magic number for that (63 or 64 depending on use case.)
11567234c309SJakub Chylkowski * 2. rewrite the code to dynamically allocate mbx->ops[vf_id] for
11577234c309SJakub Chylkowski * certain number of VFs instead of default maximum value of 64 (0..63)
11587234c309SJakub Chylkowski */
11597234c309SJakub Chylkowski for (i = 0; i < 64; i++)
11607234c309SJakub Chylkowski ixgbe_init_mbx_params_pf_id(hw, i);
11617234c309SJakub Chylkowski }
11627234c309SJakub Chylkowski
11637234c309SJakub Chylkowski /**
11647234c309SJakub Chylkowski * ixgbe_upgrade_mbx_params_pf - Upgrade initial values for pf mailbox
11657234c309SJakub Chylkowski * @hw: pointer to the HW structure
11667234c309SJakub Chylkowski * @vf_id: the VF index
11677234c309SJakub Chylkowski *
11687234c309SJakub Chylkowski * Initializes the hw->mbx struct to new function set for improved
11697234c309SJakub Chylkowski * stability and handling of messages.
11707234c309SJakub Chylkowski */
ixgbe_upgrade_mbx_params_pf(struct ixgbe_hw * hw,u16 vf_id)11717234c309SJakub Chylkowski void ixgbe_upgrade_mbx_params_pf(struct ixgbe_hw *hw, u16 vf_id)
11727234c309SJakub Chylkowski {
11737234c309SJakub Chylkowski struct ixgbe_mbx_info *mbx = &hw->mbx;
11747234c309SJakub Chylkowski
11757234c309SJakub Chylkowski /* Ensure we are not calling this function from VF */
11767234c309SJakub Chylkowski if (hw->mac.type != ixgbe_mac_82599EB &&
11777234c309SJakub Chylkowski hw->mac.type != ixgbe_mac_X550 &&
11787234c309SJakub Chylkowski hw->mac.type != ixgbe_mac_X550EM_x &&
11797234c309SJakub Chylkowski hw->mac.type != ixgbe_mac_X550EM_a &&
11807234c309SJakub Chylkowski hw->mac.type != ixgbe_mac_X540)
11817234c309SJakub Chylkowski return;
11827234c309SJakub Chylkowski
11837234c309SJakub Chylkowski mbx->timeout = IXGBE_VF_MBX_INIT_TIMEOUT;
11847234c309SJakub Chylkowski mbx->usec_delay = IXGBE_VF_MBX_INIT_DELAY;
11857234c309SJakub Chylkowski mbx->size = IXGBE_VFMAILBOX_SIZE;
11867234c309SJakub Chylkowski
11877234c309SJakub Chylkowski mbx->ops[vf_id].release = ixgbe_release_mbx_lock_pf;
11887234c309SJakub Chylkowski mbx->ops[vf_id].read = ixgbe_read_mbx_pf;
11897234c309SJakub Chylkowski mbx->ops[vf_id].write = ixgbe_write_mbx_pf;
11907234c309SJakub Chylkowski mbx->ops[vf_id].check_for_msg = ixgbe_check_for_msg_pf;
11917234c309SJakub Chylkowski mbx->ops[vf_id].check_for_ack = ixgbe_check_for_ack_pf;
11927234c309SJakub Chylkowski mbx->ops[vf_id].check_for_rst = ixgbe_check_for_rst_pf;
1193*0acea458SKevin Bowling mbx->ops[vf_id].clear = ixgbe_clear_mbx_pf;
11941a4e3449SJack F Vogel
11951a4e3449SJack F Vogel mbx->stats.msgs_tx = 0;
11961a4e3449SJack F Vogel mbx->stats.msgs_rx = 0;
11971a4e3449SJack F Vogel mbx->stats.reqs = 0;
11981a4e3449SJack F Vogel mbx->stats.acks = 0;
11991a4e3449SJack F Vogel mbx->stats.rsts = 0;
12001a4e3449SJack F Vogel }
1201