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 **/ 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 **/ 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 **/ 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 **/ 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 **/ 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 **/ 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 **/ 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 **/ 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 **/ 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 **/ 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 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 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 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 **/ 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 **/ 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 **/ 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 **/ 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 **/ 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 **/ 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 **/ 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 **/ 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 **/ 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 **/ 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 **/ 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 */ 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 */ 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 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 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 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 **/ 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 **/ 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 **/ 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 **/ 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 **/ 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 **/ 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 **/ 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 **/ 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 **/ 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 **/ 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 */ 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 */ 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 */ 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