Home | History | Annotate | Line # | Download | only in ixgbe
ixgbe_mbx.c revision 1.6.8.7
      1  1.6.8.7   martin /* $NetBSD: ixgbe_mbx.c,v 1.6.8.7 2022/06/03 12:31:10 martin Exp $ */
      2  1.6.8.1      snj 
      3      1.1   dyoung /******************************************************************************
      4  1.6.8.1      snj   SPDX-License-Identifier: BSD-3-Clause
      5      1.1   dyoung 
      6  1.6.8.5   martin   Copyright (c) 2001-2020, Intel Corporation
      7      1.1   dyoung   All rights reserved.
      8  1.6.8.1      snj 
      9  1.6.8.1      snj   Redistribution and use in source and binary forms, with or without
     10      1.1   dyoung   modification, are permitted provided that the following conditions are met:
     11  1.6.8.1      snj 
     12  1.6.8.1      snj    1. Redistributions of source code must retain the above copyright notice,
     13      1.1   dyoung       this list of conditions and the following disclaimer.
     14  1.6.8.1      snj 
     15  1.6.8.1      snj    2. Redistributions in binary form must reproduce the above copyright
     16  1.6.8.1      snj       notice, this list of conditions and the following disclaimer in the
     17      1.1   dyoung       documentation and/or other materials provided with the distribution.
     18  1.6.8.1      snj 
     19  1.6.8.1      snj    3. Neither the name of the Intel Corporation nor the names of its
     20  1.6.8.1      snj       contributors may be used to endorse or promote products derived from
     21      1.1   dyoung       this software without specific prior written permission.
     22  1.6.8.1      snj 
     23      1.1   dyoung   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     24  1.6.8.1      snj   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     25  1.6.8.1      snj   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     26  1.6.8.1      snj   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
     27  1.6.8.1      snj   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     28  1.6.8.1      snj   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     29  1.6.8.1      snj   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     30  1.6.8.1      snj   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     31  1.6.8.1      snj   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     32      1.1   dyoung   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     33      1.1   dyoung   POSSIBILITY OF SUCH DAMAGE.
     34      1.1   dyoung 
     35      1.1   dyoung ******************************************************************************/
     36  1.6.8.2   martin /*$FreeBSD: head/sys/dev/ixgbe/ixgbe_mbx.c 326022 2017-11-20 19:36:21Z pfg $*/
     37      1.1   dyoung 
     38  1.6.8.4   martin #include <sys/cdefs.h>
     39  1.6.8.7   martin __KERNEL_RCSID(0, "$NetBSD: ixgbe_mbx.c,v 1.6.8.7 2022/06/03 12:31:10 martin Exp $");
     40  1.6.8.4   martin 
     41      1.1   dyoung #include "ixgbe_type.h"
     42  1.6.8.7   martin #include "ixgbe_netbsd.h"
     43      1.1   dyoung #include "ixgbe_mbx.h"
     44      1.1   dyoung 
     45  1.6.8.6   martin static s32 ixgbe_poll_for_msg(struct ixgbe_hw *hw, u16 mbx_id);
     46  1.6.8.6   martin static s32 ixgbe_poll_for_ack(struct ixgbe_hw *hw, u16 mbx_id);
     47  1.6.8.6   martin 
     48      1.1   dyoung /**
     49  1.6.8.5   martin  * ixgbe_read_mbx - Reads a message from the mailbox
     50  1.6.8.5   martin  * @hw: pointer to the HW structure
     51  1.6.8.5   martin  * @msg: The message buffer
     52  1.6.8.5   martin  * @size: Length of buffer
     53  1.6.8.5   martin  * @mbx_id: id of mailbox to read
     54  1.6.8.3   martin  *
     55  1.6.8.5   martin  * returns SUCCESS if it successfully read message from buffer
     56  1.6.8.5   martin  **/
     57  1.6.8.5   martin s32 ixgbe_read_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id)
     58  1.6.8.5   martin {
     59  1.6.8.5   martin 	struct ixgbe_mbx_info *mbx = &hw->mbx;
     60  1.6.8.5   martin 
     61  1.6.8.5   martin 	DEBUGFUNC("ixgbe_read_mbx");
     62  1.6.8.5   martin 
     63  1.6.8.5   martin 	/* limit read to size of mailbox */
     64  1.6.8.6   martin 	if (size > mbx->size) {
     65  1.6.8.6   martin 		ERROR_REPORT3(IXGBE_ERROR_ARGUMENT,
     66  1.6.8.6   martin 			      "Invalid mailbox message size %u, changing to %u",
     67  1.6.8.6   martin 			      size, mbx->size);
     68  1.6.8.5   martin 		size = mbx->size;
     69  1.6.8.6   martin 	}
     70  1.6.8.6   martin 
     71  1.6.8.6   martin 	if (mbx->ops[mbx_id].read)
     72  1.6.8.6   martin 		return mbx->ops[mbx_id].read(hw, msg, size, mbx_id);
     73  1.6.8.6   martin 
     74  1.6.8.6   martin 	return IXGBE_ERR_CONFIG;
     75  1.6.8.6   martin }
     76  1.6.8.6   martin 
     77  1.6.8.6   martin /**
     78  1.6.8.6   martin  * ixgbe_poll_mbx - Wait for message and read it from the mailbox
     79  1.6.8.6   martin  * @hw: pointer to the HW structure
     80  1.6.8.6   martin  * @msg: The message buffer
     81  1.6.8.6   martin  * @size: Length of buffer
     82  1.6.8.6   martin  * @mbx_id: id of mailbox to read
     83  1.6.8.6   martin  *
     84  1.6.8.6   martin  * returns SUCCESS if it successfully read message from buffer
     85  1.6.8.6   martin  **/
     86  1.6.8.6   martin s32 ixgbe_poll_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id)
     87  1.6.8.6   martin {
     88  1.6.8.6   martin 	struct ixgbe_mbx_info *mbx = &hw->mbx;
     89  1.6.8.6   martin 	s32 ret_val;
     90  1.6.8.6   martin 
     91  1.6.8.6   martin 	DEBUGFUNC("ixgbe_poll_mbx");
     92  1.6.8.5   martin 
     93  1.6.8.6   martin 	if (!mbx->ops[mbx_id].read || !mbx->ops[mbx_id].check_for_msg ||
     94  1.6.8.6   martin 	    !mbx->timeout)
     95  1.6.8.6   martin 		return IXGBE_ERR_CONFIG;
     96  1.6.8.6   martin 
     97  1.6.8.6   martin 	/* limit read to size of mailbox */
     98  1.6.8.6   martin 	if (size > mbx->size) {
     99  1.6.8.6   martin 		ERROR_REPORT3(IXGBE_ERROR_ARGUMENT,
    100  1.6.8.6   martin 			      "Invalid mailbox message size %u, changing to %u",
    101  1.6.8.6   martin 			      size, mbx->size);
    102  1.6.8.6   martin 		size = mbx->size;
    103  1.6.8.6   martin 	}
    104  1.6.8.6   martin 
    105  1.6.8.6   martin 	ret_val = ixgbe_poll_for_msg(hw, mbx_id);
    106  1.6.8.6   martin 	/* if ack received read message, otherwise we timed out */
    107  1.6.8.6   martin 	if (!ret_val)
    108  1.6.8.6   martin 		return mbx->ops[mbx_id].read(hw, msg, size, mbx_id);
    109  1.6.8.5   martin 
    110  1.6.8.5   martin 	return ret_val;
    111  1.6.8.5   martin }
    112  1.6.8.5   martin 
    113  1.6.8.5   martin /**
    114  1.6.8.6   martin  * ixgbe_write_mbx - Write a message to the mailbox and wait for ACK
    115  1.6.8.5   martin  * @hw: pointer to the HW structure
    116  1.6.8.5   martin  * @msg: The message buffer
    117  1.6.8.5   martin  * @size: Length of buffer
    118  1.6.8.5   martin  * @mbx_id: id of mailbox to write
    119  1.6.8.5   martin  *
    120  1.6.8.6   martin  * returns SUCCESS if it successfully copied message into the buffer and
    121  1.6.8.6   martin  * received an ACK to that message within specified period
    122  1.6.8.5   martin  **/
    123  1.6.8.5   martin s32 ixgbe_write_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id)
    124  1.6.8.5   martin {
    125  1.6.8.5   martin 	struct ixgbe_mbx_info *mbx = &hw->mbx;
    126  1.6.8.6   martin 	s32 ret_val = IXGBE_ERR_MBX;
    127  1.6.8.5   martin 
    128  1.6.8.5   martin 	DEBUGFUNC("ixgbe_write_mbx");
    129  1.6.8.5   martin 
    130  1.6.8.6   martin 	/*
    131  1.6.8.6   martin 	 * exit if either we can't write, release
    132  1.6.8.6   martin 	 * or there is no timeout defined
    133  1.6.8.6   martin 	 */
    134  1.6.8.6   martin 	if (!mbx->ops[mbx_id].write || !mbx->ops[mbx_id].check_for_ack ||
    135  1.6.8.6   martin 	    !mbx->ops[mbx_id].release || !mbx->timeout)
    136  1.6.8.6   martin 		return IXGBE_ERR_CONFIG;
    137  1.6.8.6   martin 
    138  1.6.8.5   martin 	if (size > mbx->size) {
    139  1.6.8.6   martin 		ret_val = IXGBE_ERR_PARAM;
    140  1.6.8.5   martin 		ERROR_REPORT2(IXGBE_ERROR_ARGUMENT,
    141  1.6.8.6   martin 			     "Invalid mailbox message size %u", size);
    142  1.6.8.6   martin 	} else {
    143  1.6.8.6   martin 		ret_val = mbx->ops[mbx_id].write(hw, msg, size, mbx_id);
    144  1.6.8.6   martin 	}
    145  1.6.8.5   martin 
    146  1.6.8.5   martin 	return ret_val;
    147  1.6.8.5   martin }
    148  1.6.8.5   martin 
    149  1.6.8.5   martin /**
    150  1.6.8.5   martin  * ixgbe_check_for_msg - checks to see if someone sent us mail
    151  1.6.8.5   martin  * @hw: pointer to the HW structure
    152  1.6.8.5   martin  * @mbx_id: id of mailbox to check
    153  1.6.8.5   martin  *
    154  1.6.8.5   martin  * returns SUCCESS if the Status bit was found or else ERR_MBX
    155  1.6.8.5   martin  **/
    156  1.6.8.5   martin s32 ixgbe_check_for_msg(struct ixgbe_hw *hw, u16 mbx_id)
    157  1.6.8.5   martin {
    158  1.6.8.5   martin 	struct ixgbe_mbx_info *mbx = &hw->mbx;
    159  1.6.8.6   martin 	s32 ret_val = IXGBE_ERR_CONFIG;
    160  1.6.8.5   martin 
    161  1.6.8.5   martin 	DEBUGFUNC("ixgbe_check_for_msg");
    162  1.6.8.5   martin 
    163  1.6.8.6   martin 	if (mbx->ops[mbx_id].check_for_msg)
    164  1.6.8.6   martin 		ret_val = mbx->ops[mbx_id].check_for_msg(hw, mbx_id);
    165  1.6.8.5   martin 
    166  1.6.8.5   martin 	return ret_val;
    167  1.6.8.5   martin }
    168  1.6.8.5   martin 
    169  1.6.8.5   martin /**
    170  1.6.8.5   martin  * ixgbe_check_for_ack - checks to see if someone sent us ACK
    171  1.6.8.5   martin  * @hw: pointer to the HW structure
    172  1.6.8.5   martin  * @mbx_id: id of mailbox to check
    173  1.6.8.5   martin  *
    174  1.6.8.5   martin  * returns SUCCESS if the Status bit was found or else ERR_MBX
    175  1.6.8.5   martin  **/
    176  1.6.8.5   martin s32 ixgbe_check_for_ack(struct ixgbe_hw *hw, u16 mbx_id)
    177  1.6.8.5   martin {
    178  1.6.8.5   martin 	struct ixgbe_mbx_info *mbx = &hw->mbx;
    179  1.6.8.6   martin 	s32 ret_val = IXGBE_ERR_CONFIG;
    180  1.6.8.5   martin 
    181  1.6.8.5   martin 	DEBUGFUNC("ixgbe_check_for_ack");
    182  1.6.8.5   martin 
    183  1.6.8.6   martin 	if (mbx->ops[mbx_id].check_for_ack)
    184  1.6.8.6   martin 		ret_val = mbx->ops[mbx_id].check_for_ack(hw, mbx_id);
    185  1.6.8.5   martin 
    186  1.6.8.5   martin 	return ret_val;
    187  1.6.8.5   martin }
    188  1.6.8.5   martin 
    189  1.6.8.5   martin /**
    190  1.6.8.5   martin  * ixgbe_check_for_rst - checks to see if other side has reset
    191  1.6.8.5   martin  * @hw: pointer to the HW structure
    192  1.6.8.5   martin  * @mbx_id: id of mailbox to check
    193  1.6.8.5   martin  *
    194  1.6.8.5   martin  * returns SUCCESS if the Status bit was found or else ERR_MBX
    195  1.6.8.5   martin  **/
    196  1.6.8.5   martin s32 ixgbe_check_for_rst(struct ixgbe_hw *hw, u16 mbx_id)
    197  1.6.8.5   martin {
    198  1.6.8.5   martin 	struct ixgbe_mbx_info *mbx = &hw->mbx;
    199  1.6.8.6   martin 	s32 ret_val = IXGBE_ERR_CONFIG;
    200  1.6.8.5   martin 
    201  1.6.8.5   martin 	DEBUGFUNC("ixgbe_check_for_rst");
    202  1.6.8.5   martin 
    203  1.6.8.6   martin 	if (mbx->ops[mbx_id].check_for_rst)
    204  1.6.8.6   martin 		ret_val = mbx->ops[mbx_id].check_for_rst(hw, mbx_id);
    205  1.6.8.5   martin 
    206  1.6.8.5   martin 	return ret_val;
    207  1.6.8.5   martin }
    208  1.6.8.5   martin 
    209  1.6.8.5   martin /**
    210  1.6.8.5   martin  * ixgbe_clear_mbx - Clear Mailbox Memory
    211  1.6.8.5   martin  * @hw: pointer to the HW structure
    212  1.6.8.6   martin  * @mbx_id: id of mailbox to write
    213  1.6.8.5   martin  *
    214  1.6.8.5   martin  * Set VFMBMEM of given VF to 0x0.
    215  1.6.8.3   martin  **/
    216  1.6.8.6   martin s32 ixgbe_clear_mbx(struct ixgbe_hw *hw, u16 mbx_id)
    217  1.6.8.3   martin {
    218  1.6.8.3   martin 	struct ixgbe_mbx_info *mbx = &hw->mbx;
    219  1.6.8.6   martin 	s32 ret_val = IXGBE_ERR_CONFIG;
    220  1.6.8.3   martin 
    221  1.6.8.3   martin 	DEBUGFUNC("ixgbe_clear_mbx");
    222  1.6.8.3   martin 
    223  1.6.8.6   martin 	if (mbx->ops[mbx_id].clear)
    224  1.6.8.6   martin 		ret_val = mbx->ops[mbx_id].clear(hw, mbx_id);
    225  1.6.8.3   martin 
    226  1.6.8.3   martin 	return ret_val;
    227  1.6.8.3   martin }
    228  1.6.8.3   martin 
    229  1.6.8.3   martin /**
    230  1.6.8.5   martin  * ixgbe_poll_for_msg - Wait for message notification
    231  1.6.8.5   martin  * @hw: pointer to the HW structure
    232  1.6.8.5   martin  * @mbx_id: id of mailbox to write
    233      1.1   dyoung  *
    234  1.6.8.5   martin  * returns SUCCESS if it successfully received a message notification
    235      1.1   dyoung  **/
    236      1.1   dyoung static s32 ixgbe_poll_for_msg(struct ixgbe_hw *hw, u16 mbx_id)
    237      1.1   dyoung {
    238      1.1   dyoung 	struct ixgbe_mbx_info *mbx = &hw->mbx;
    239      1.1   dyoung 	int countdown = mbx->timeout;
    240      1.1   dyoung 
    241      1.1   dyoung 	DEBUGFUNC("ixgbe_poll_for_msg");
    242      1.1   dyoung 
    243  1.6.8.6   martin 	if (!countdown || !mbx->ops[mbx_id].check_for_msg)
    244  1.6.8.6   martin 		return IXGBE_ERR_CONFIG;
    245      1.1   dyoung 
    246  1.6.8.6   martin 	while (countdown && mbx->ops[mbx_id].check_for_msg(hw, mbx_id)) {
    247      1.1   dyoung 		countdown--;
    248      1.1   dyoung 		if (!countdown)
    249      1.1   dyoung 			break;
    250      1.1   dyoung 		usec_delay(mbx->usec_delay);
    251      1.1   dyoung 	}
    252      1.1   dyoung 
    253  1.6.8.6   martin 	if (countdown == 0) {
    254      1.4  msaitoh 		ERROR_REPORT2(IXGBE_ERROR_POLLING,
    255  1.6.8.6   martin 			   "Polling for VF%u mailbox message timedout", mbx_id);
    256  1.6.8.6   martin 		return IXGBE_ERR_TIMEOUT;
    257  1.6.8.6   martin 	}
    258      1.4  msaitoh 
    259  1.6.8.6   martin 	return IXGBE_SUCCESS;
    260      1.1   dyoung }
    261      1.1   dyoung 
    262      1.1   dyoung /**
    263  1.6.8.5   martin  * ixgbe_poll_for_ack - Wait for message acknowledgment
    264  1.6.8.5   martin  * @hw: pointer to the HW structure
    265  1.6.8.5   martin  * @mbx_id: id of mailbox to write
    266      1.1   dyoung  *
    267  1.6.8.5   martin  * returns SUCCESS if it successfully received a message acknowledgment
    268      1.1   dyoung  **/
    269      1.1   dyoung static s32 ixgbe_poll_for_ack(struct ixgbe_hw *hw, u16 mbx_id)
    270      1.1   dyoung {
    271      1.1   dyoung 	struct ixgbe_mbx_info *mbx = &hw->mbx;
    272      1.1   dyoung 	int countdown = mbx->timeout;
    273      1.1   dyoung 
    274      1.1   dyoung 	DEBUGFUNC("ixgbe_poll_for_ack");
    275      1.1   dyoung 
    276  1.6.8.6   martin 	if (!countdown || !mbx->ops[mbx_id].check_for_ack)
    277  1.6.8.6   martin 		return IXGBE_ERR_CONFIG;
    278      1.1   dyoung 
    279  1.6.8.6   martin 	while (countdown && mbx->ops[mbx_id].check_for_ack(hw, mbx_id)) {
    280      1.1   dyoung 		countdown--;
    281      1.1   dyoung 		if (!countdown)
    282      1.1   dyoung 			break;
    283      1.1   dyoung 		usec_delay(mbx->usec_delay);
    284      1.1   dyoung 	}
    285      1.1   dyoung 
    286  1.6.8.6   martin 	if (countdown == 0) {
    287      1.4  msaitoh 		ERROR_REPORT2(IXGBE_ERROR_POLLING,
    288  1.6.8.6   martin 			     "Polling for VF%u mailbox ack timedout", mbx_id);
    289  1.6.8.6   martin 		return IXGBE_ERR_TIMEOUT;
    290  1.6.8.6   martin 	}
    291      1.4  msaitoh 
    292  1.6.8.6   martin 	return IXGBE_SUCCESS;
    293      1.1   dyoung }
    294      1.1   dyoung 
    295  1.6.8.6   martin 
    296      1.1   dyoung /**
    297  1.6.8.6   martin  * ixgbe_read_mailbox_vf - read VF's mailbox register
    298  1.6.8.5   martin  * @hw: pointer to the HW structure
    299      1.1   dyoung  *
    300  1.6.8.6   martin  * This function is used to read the mailbox register dedicated for VF without
    301  1.6.8.6   martin  * losing the read to clear status bits.
    302      1.1   dyoung  **/
    303  1.6.8.6   martin static u32 ixgbe_read_mailbox_vf(struct ixgbe_hw *hw)
    304      1.1   dyoung {
    305  1.6.8.6   martin 	u32 vf_mailbox = IXGBE_READ_REG(hw, IXGBE_VFMAILBOX);
    306      1.1   dyoung 
    307  1.6.8.6   martin 	vf_mailbox |= hw->mbx.vf_mailbox;
    308  1.6.8.6   martin 	hw->mbx.vf_mailbox |= vf_mailbox & IXGBE_VFMAILBOX_R2C_BITS;
    309      1.1   dyoung 
    310  1.6.8.6   martin 	return vf_mailbox;
    311      1.1   dyoung }
    312      1.1   dyoung 
    313  1.6.8.6   martin static void ixgbe_clear_msg_vf(struct ixgbe_hw *hw)
    314      1.1   dyoung {
    315  1.6.8.6   martin 	u32 vf_mailbox = ixgbe_read_mailbox_vf(hw);
    316      1.1   dyoung 
    317  1.6.8.6   martin 	if (vf_mailbox & IXGBE_VFMAILBOX_PFSTS) {
    318  1.6.8.7   martin 		IXGBE_EVC_ADD(&hw->mbx.stats.reqs, 1);
    319  1.6.8.6   martin 		hw->mbx.vf_mailbox &= ~IXGBE_VFMAILBOX_PFSTS;
    320  1.6.8.6   martin 	}
    321      1.1   dyoung }
    322      1.1   dyoung 
    323  1.6.8.6   martin static void ixgbe_clear_ack_vf(struct ixgbe_hw *hw)
    324      1.1   dyoung {
    325  1.6.8.6   martin 	u32 vf_mailbox = ixgbe_read_mailbox_vf(hw);
    326      1.1   dyoung 
    327  1.6.8.6   martin 	if (vf_mailbox & IXGBE_VFMAILBOX_PFACK) {
    328  1.6.8.7   martin 		IXGBE_EVC_ADD(&hw->mbx.stats.acks, 1);
    329  1.6.8.6   martin 		hw->mbx.vf_mailbox &= ~IXGBE_VFMAILBOX_PFACK;
    330  1.6.8.6   martin 	}
    331      1.1   dyoung }
    332      1.1   dyoung 
    333  1.6.8.6   martin static void ixgbe_clear_rst_vf(struct ixgbe_hw *hw)
    334      1.1   dyoung {
    335  1.6.8.6   martin 	u32 vf_mailbox = ixgbe_read_mailbox_vf(hw);
    336      1.1   dyoung 
    337  1.6.8.6   martin 	if (vf_mailbox & (IXGBE_VFMAILBOX_RSTI | IXGBE_VFMAILBOX_RSTD)) {
    338  1.6.8.7   martin 		IXGBE_EVC_ADD(&hw->mbx.stats.rsts, 1);
    339  1.6.8.6   martin 		hw->mbx.vf_mailbox &= ~(IXGBE_VFMAILBOX_RSTI |
    340  1.6.8.6   martin 					IXGBE_VFMAILBOX_RSTD);
    341  1.6.8.6   martin 	}
    342      1.1   dyoung }
    343      1.1   dyoung 
    344      1.1   dyoung /**
    345  1.6.8.5   martin  * ixgbe_check_for_bit_vf - Determine if a status bit was set
    346  1.6.8.5   martin  * @hw: pointer to the HW structure
    347  1.6.8.5   martin  * @mask: bitmask for bits to be tested and cleared
    348      1.1   dyoung  *
    349  1.6.8.5   martin  * This function is used to check for the read to clear bits within
    350  1.6.8.5   martin  * the V2P mailbox.
    351      1.1   dyoung  **/
    352      1.1   dyoung static s32 ixgbe_check_for_bit_vf(struct ixgbe_hw *hw, u32 mask)
    353      1.1   dyoung {
    354  1.6.8.6   martin 	u32 vf_mailbox = ixgbe_read_mailbox_vf(hw);
    355      1.1   dyoung 
    356  1.6.8.6   martin 	if (vf_mailbox & mask)
    357  1.6.8.6   martin 		return IXGBE_SUCCESS;
    358      1.1   dyoung 
    359  1.6.8.6   martin 	return IXGBE_ERR_MBX;
    360      1.1   dyoung }
    361      1.1   dyoung 
    362      1.1   dyoung /**
    363  1.6.8.5   martin  * ixgbe_check_for_msg_vf - checks to see if the PF has sent mail
    364  1.6.8.5   martin  * @hw: pointer to the HW structure
    365  1.6.8.5   martin  * @mbx_id: id of mailbox to check
    366      1.1   dyoung  *
    367  1.6.8.5   martin  * returns SUCCESS if the PF has set the Status bit or else ERR_MBX
    368      1.1   dyoung  **/
    369      1.1   dyoung static s32 ixgbe_check_for_msg_vf(struct ixgbe_hw *hw, u16 mbx_id)
    370      1.1   dyoung {
    371      1.2  msaitoh 	UNREFERENCED_1PARAMETER(mbx_id);
    372      1.1   dyoung 	DEBUGFUNC("ixgbe_check_for_msg_vf");
    373      1.1   dyoung 
    374      1.1   dyoung 	if (!ixgbe_check_for_bit_vf(hw, IXGBE_VFMAILBOX_PFSTS)) {
    375  1.6.8.7   martin 		IXGBE_EVC_ADD(&hw->mbx.stats.reqs, 1);
    376  1.6.8.6   martin 		return IXGBE_SUCCESS;
    377      1.1   dyoung 	}
    378      1.1   dyoung 
    379  1.6.8.6   martin 	return IXGBE_ERR_MBX;
    380      1.1   dyoung }
    381      1.1   dyoung 
    382      1.1   dyoung /**
    383  1.6.8.5   martin  * ixgbe_check_for_ack_vf - checks to see if the PF has ACK'd
    384  1.6.8.5   martin  * @hw: pointer to the HW structure
    385  1.6.8.5   martin  * @mbx_id: id of mailbox to check
    386      1.1   dyoung  *
    387  1.6.8.5   martin  * returns SUCCESS if the PF has set the ACK bit or else ERR_MBX
    388      1.1   dyoung  **/
    389      1.1   dyoung static s32 ixgbe_check_for_ack_vf(struct ixgbe_hw *hw, u16 mbx_id)
    390      1.1   dyoung {
    391      1.2  msaitoh 	UNREFERENCED_1PARAMETER(mbx_id);
    392      1.1   dyoung 	DEBUGFUNC("ixgbe_check_for_ack_vf");
    393      1.1   dyoung 
    394      1.1   dyoung 	if (!ixgbe_check_for_bit_vf(hw, IXGBE_VFMAILBOX_PFACK)) {
    395  1.6.8.6   martin 		/* TODO: should this be autocleared? */
    396  1.6.8.6   martin 		ixgbe_clear_ack_vf(hw);
    397  1.6.8.7   martin 		IXGBE_EVC_ADD(&hw->mbx.stats.acks, 1);
    398  1.6.8.6   martin 		return IXGBE_SUCCESS;
    399      1.1   dyoung 	}
    400      1.1   dyoung 
    401  1.6.8.6   martin 	return IXGBE_ERR_MBX;
    402      1.1   dyoung }
    403      1.1   dyoung 
    404      1.1   dyoung /**
    405  1.6.8.5   martin  * ixgbe_check_for_rst_vf - checks to see if the PF has reset
    406  1.6.8.5   martin  * @hw: pointer to the HW structure
    407  1.6.8.5   martin  * @mbx_id: id of mailbox to check
    408      1.1   dyoung  *
    409  1.6.8.5   martin  * returns TRUE if the PF has set the reset done bit or else FALSE
    410      1.1   dyoung  **/
    411      1.1   dyoung static s32 ixgbe_check_for_rst_vf(struct ixgbe_hw *hw, u16 mbx_id)
    412      1.1   dyoung {
    413      1.2  msaitoh 	UNREFERENCED_1PARAMETER(mbx_id);
    414      1.1   dyoung 	DEBUGFUNC("ixgbe_check_for_rst_vf");
    415      1.1   dyoung 
    416  1.6.8.6   martin 	if (!ixgbe_check_for_bit_vf(hw, IXGBE_VFMAILBOX_RSTI |
    417  1.6.8.6   martin 					  IXGBE_VFMAILBOX_RSTD)) {
    418  1.6.8.6   martin 		/* TODO: should this be autocleared? */
    419  1.6.8.6   martin 		ixgbe_clear_rst_vf(hw);
    420  1.6.8.7   martin 		IXGBE_EVC_ADD(&hw->mbx.stats.rsts, 1);
    421  1.6.8.6   martin 		return IXGBE_SUCCESS;
    422      1.1   dyoung 	}
    423      1.1   dyoung 
    424  1.6.8.6   martin 	return IXGBE_ERR_MBX;
    425      1.1   dyoung }
    426      1.1   dyoung 
    427      1.1   dyoung /**
    428  1.6.8.5   martin  * ixgbe_obtain_mbx_lock_vf - obtain mailbox lock
    429  1.6.8.5   martin  * @hw: pointer to the HW structure
    430      1.1   dyoung  *
    431  1.6.8.5   martin  * return SUCCESS if we obtained the mailbox lock
    432      1.1   dyoung  **/
    433      1.1   dyoung static s32 ixgbe_obtain_mbx_lock_vf(struct ixgbe_hw *hw)
    434      1.1   dyoung {
    435  1.6.8.6   martin 	struct ixgbe_mbx_info *mbx = &hw->mbx;
    436  1.6.8.6   martin 	int countdown = mbx->timeout;
    437      1.1   dyoung 	s32 ret_val = IXGBE_ERR_MBX;
    438  1.6.8.6   martin 	u32 vf_mailbox;
    439      1.1   dyoung 
    440      1.1   dyoung 	DEBUGFUNC("ixgbe_obtain_mbx_lock_vf");
    441      1.1   dyoung 
    442  1.6.8.6   martin 	if (!mbx->timeout)
    443  1.6.8.6   martin 		return IXGBE_ERR_CONFIG;
    444      1.1   dyoung 
    445  1.6.8.6   martin 	while (countdown--) {
    446  1.6.8.6   martin 		/* Reserve mailbox for VF use */
    447  1.6.8.6   martin 		vf_mailbox = ixgbe_read_mailbox_vf(hw);
    448  1.6.8.6   martin 		vf_mailbox |= IXGBE_VFMAILBOX_VFU;
    449  1.6.8.6   martin 		IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, vf_mailbox);
    450  1.6.8.6   martin 
    451  1.6.8.6   martin 		/* Verify that VF is the owner of the lock */
    452  1.6.8.6   martin 		if (ixgbe_read_mailbox_vf(hw) & IXGBE_VFMAILBOX_VFU) {
    453  1.6.8.6   martin 			ret_val = IXGBE_SUCCESS;
    454  1.6.8.6   martin 			break;
    455  1.6.8.6   martin 		}
    456  1.6.8.6   martin 
    457  1.6.8.6   martin 		/* Wait a bit before trying again */
    458  1.6.8.6   martin 		usec_delay(mbx->usec_delay);
    459  1.6.8.6   martin 	}
    460  1.6.8.6   martin 
    461  1.6.8.6   martin 	if (ret_val != IXGBE_SUCCESS) {
    462  1.6.8.6   martin 		ERROR_REPORT1(IXGBE_ERROR_INVALID_STATE,
    463  1.6.8.6   martin 				"Failed to obtain mailbox lock");
    464  1.6.8.6   martin 		ret_val = IXGBE_ERR_TIMEOUT;
    465  1.6.8.6   martin 	}
    466      1.1   dyoung 
    467      1.1   dyoung 	return ret_val;
    468      1.1   dyoung }
    469      1.1   dyoung 
    470      1.1   dyoung /**
    471  1.6.8.6   martin  * ixgbe_release_mbx_lock_dummy - release mailbox lock
    472  1.6.8.6   martin  * @hw: pointer to the HW structure
    473  1.6.8.6   martin  * @mbx_id: id of mailbox to read
    474  1.6.8.6   martin  **/
    475  1.6.8.6   martin static void ixgbe_release_mbx_lock_dummy(struct ixgbe_hw *hw, u16 mbx_id)
    476  1.6.8.6   martin {
    477  1.6.8.6   martin 	UNREFERENCED_2PARAMETER(hw, mbx_id);
    478  1.6.8.6   martin 
    479  1.6.8.6   martin 	DEBUGFUNC("ixgbe_release_mbx_lock_dummy");
    480  1.6.8.6   martin }
    481  1.6.8.6   martin 
    482  1.6.8.6   martin /**
    483  1.6.8.6   martin  * ixgbe_release_mbx_lock_vf - release mailbox lock
    484  1.6.8.6   martin  * @hw: pointer to the HW structure
    485  1.6.8.6   martin  * @mbx_id: id of mailbox to read
    486  1.6.8.6   martin  **/
    487  1.6.8.6   martin static void ixgbe_release_mbx_lock_vf(struct ixgbe_hw *hw, u16 mbx_id)
    488  1.6.8.6   martin {
    489  1.6.8.6   martin 	u32 vf_mailbox;
    490  1.6.8.6   martin 
    491  1.6.8.6   martin 	UNREFERENCED_1PARAMETER(mbx_id);
    492  1.6.8.6   martin 
    493  1.6.8.6   martin 	DEBUGFUNC("ixgbe_release_mbx_lock_vf");
    494  1.6.8.6   martin 
    495  1.6.8.6   martin 	/* Return ownership of the buffer */
    496  1.6.8.6   martin 	vf_mailbox = ixgbe_read_mailbox_vf(hw);
    497  1.6.8.6   martin 	vf_mailbox &= ~IXGBE_VFMAILBOX_VFU;
    498  1.6.8.6   martin 	IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, vf_mailbox);
    499  1.6.8.6   martin }
    500  1.6.8.6   martin 
    501  1.6.8.6   martin /**
    502  1.6.8.6   martin  * ixgbe_write_mbx_vf_legacy - Write a message to the mailbox
    503  1.6.8.6   martin  * @hw: pointer to the HW structure
    504  1.6.8.6   martin  * @msg: The message buffer
    505  1.6.8.6   martin  * @size: Length of buffer
    506  1.6.8.6   martin  * @mbx_id: id of mailbox to write
    507  1.6.8.6   martin  *
    508  1.6.8.6   martin  * returns SUCCESS if it successfully copied message into the buffer
    509  1.6.8.6   martin  **/
    510  1.6.8.6   martin static s32 ixgbe_write_mbx_vf_legacy(struct ixgbe_hw *hw, u32 *msg, u16 size,
    511  1.6.8.6   martin 				     u16 mbx_id)
    512  1.6.8.6   martin {
    513  1.6.8.6   martin 	s32 ret_val;
    514  1.6.8.6   martin 	u16 i;
    515  1.6.8.6   martin 
    516  1.6.8.6   martin 	UNREFERENCED_1PARAMETER(mbx_id);
    517  1.6.8.6   martin 	DEBUGFUNC("ixgbe_write_mbx_vf_legacy");
    518  1.6.8.6   martin 
    519  1.6.8.6   martin 	/* lock the mailbox to prevent pf/vf race condition */
    520  1.6.8.6   martin 	ret_val = ixgbe_obtain_mbx_lock_vf(hw);
    521  1.6.8.6   martin 	if (ret_val)
    522  1.6.8.6   martin 		return ret_val;
    523  1.6.8.6   martin 
    524  1.6.8.6   martin 	/* flush msg and acks as we are overwriting the message buffer */
    525  1.6.8.6   martin 	ixgbe_check_for_msg_vf(hw, 0);
    526  1.6.8.6   martin 	ixgbe_clear_msg_vf(hw);
    527  1.6.8.6   martin 	ixgbe_check_for_ack_vf(hw, 0);
    528  1.6.8.6   martin 	ixgbe_clear_ack_vf(hw);
    529  1.6.8.6   martin 
    530  1.6.8.6   martin 	/* copy the caller specified message to the mailbox memory buffer */
    531  1.6.8.6   martin 	for (i = 0; i < size; i++)
    532  1.6.8.6   martin 		IXGBE_WRITE_REG_ARRAY(hw, IXGBE_VFMBMEM, i, msg[i]);
    533  1.6.8.6   martin 
    534  1.6.8.6   martin 	/* update stats */
    535  1.6.8.7   martin 	IXGBE_EVC_ADD(&hw->mbx.stats.msgs_tx, 1);
    536  1.6.8.6   martin 
    537  1.6.8.6   martin 	/* interrupt the PF to tell it a message has been sent */
    538  1.6.8.6   martin 	IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_REQ);
    539  1.6.8.6   martin 
    540  1.6.8.6   martin 	return IXGBE_SUCCESS;
    541  1.6.8.6   martin }
    542  1.6.8.6   martin 
    543  1.6.8.6   martin /**
    544  1.6.8.5   martin  * ixgbe_write_mbx_vf - Write a message to the mailbox
    545  1.6.8.5   martin  * @hw: pointer to the HW structure
    546  1.6.8.5   martin  * @msg: The message buffer
    547  1.6.8.5   martin  * @size: Length of buffer
    548  1.6.8.5   martin  * @mbx_id: id of mailbox to write
    549      1.1   dyoung  *
    550  1.6.8.5   martin  * returns SUCCESS if it successfully copied message into the buffer
    551      1.1   dyoung  **/
    552      1.1   dyoung static s32 ixgbe_write_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size,
    553      1.2  msaitoh 			      u16 mbx_id)
    554      1.1   dyoung {
    555  1.6.8.6   martin 	u32 vf_mailbox;
    556      1.1   dyoung 	s32 ret_val;
    557      1.1   dyoung 	u16 i;
    558      1.1   dyoung 
    559      1.2  msaitoh 	UNREFERENCED_1PARAMETER(mbx_id);
    560      1.1   dyoung 
    561      1.1   dyoung 	DEBUGFUNC("ixgbe_write_mbx_vf");
    562      1.1   dyoung 
    563      1.1   dyoung 	/* lock the mailbox to prevent pf/vf race condition */
    564      1.1   dyoung 	ret_val = ixgbe_obtain_mbx_lock_vf(hw);
    565      1.1   dyoung 	if (ret_val)
    566  1.6.8.6   martin 		goto out;
    567      1.1   dyoung 
    568      1.1   dyoung 	/* flush msg and acks as we are overwriting the message buffer */
    569  1.6.8.6   martin 	ixgbe_clear_msg_vf(hw);
    570  1.6.8.6   martin 	ixgbe_clear_ack_vf(hw);
    571      1.1   dyoung 
    572      1.1   dyoung 	/* copy the caller specified message to the mailbox memory buffer */
    573      1.1   dyoung 	for (i = 0; i < size; i++)
    574      1.1   dyoung 		IXGBE_WRITE_REG_ARRAY(hw, IXGBE_VFMBMEM, i, msg[i]);
    575      1.1   dyoung 
    576      1.1   dyoung 	/* update stats */
    577  1.6.8.7   martin 	IXGBE_EVC_ADD(&hw->mbx.stats.msgs_tx, 1);
    578      1.1   dyoung 
    579  1.6.8.6   martin 	/* interrupt the PF to tell it a message has been sent */
    580  1.6.8.6   martin 	vf_mailbox = ixgbe_read_mailbox_vf(hw);
    581  1.6.8.6   martin 	vf_mailbox |= IXGBE_VFMAILBOX_REQ;
    582  1.6.8.6   martin 	IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, vf_mailbox);
    583  1.6.8.6   martin 
    584  1.6.8.6   martin 	/* if msg sent wait until we receive an ack */
    585  1.6.8.6   martin 	ixgbe_poll_for_ack(hw, mbx_id);
    586  1.6.8.6   martin 
    587  1.6.8.6   martin out:
    588  1.6.8.6   martin 	hw->mbx.ops[mbx_id].release(hw, mbx_id);
    589      1.1   dyoung 
    590      1.1   dyoung 	return ret_val;
    591      1.1   dyoung }
    592      1.1   dyoung 
    593      1.1   dyoung /**
    594  1.6.8.6   martin  * ixgbe_read_mbx_vf_legacy - Reads a message from the inbox intended for vf
    595  1.6.8.5   martin  * @hw: pointer to the HW structure
    596  1.6.8.5   martin  * @msg: The message buffer
    597  1.6.8.5   martin  * @size: Length of buffer
    598  1.6.8.5   martin  * @mbx_id: id of mailbox to read
    599      1.1   dyoung  *
    600  1.6.8.5   martin  * returns SUCCESS if it successfully read message from buffer
    601      1.1   dyoung  **/
    602  1.6.8.6   martin static s32 ixgbe_read_mbx_vf_legacy(struct ixgbe_hw *hw, u32 *msg, u16 size,
    603  1.6.8.6   martin 				    u16 mbx_id)
    604      1.1   dyoung {
    605  1.6.8.6   martin 	s32 ret_val;
    606      1.1   dyoung 	u16 i;
    607      1.1   dyoung 
    608  1.6.8.6   martin 	DEBUGFUNC("ixgbe_read_mbx_vf_legacy");
    609      1.2  msaitoh 	UNREFERENCED_1PARAMETER(mbx_id);
    610      1.1   dyoung 
    611      1.1   dyoung 	/* lock the mailbox to prevent pf/vf race condition */
    612      1.1   dyoung 	ret_val = ixgbe_obtain_mbx_lock_vf(hw);
    613      1.1   dyoung 	if (ret_val)
    614  1.6.8.6   martin 		return ret_val;
    615      1.1   dyoung 
    616      1.1   dyoung 	/* copy the message from the mailbox memory buffer */
    617      1.1   dyoung 	for (i = 0; i < size; i++)
    618      1.1   dyoung 		msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_VFMBMEM, i);
    619      1.1   dyoung 
    620      1.1   dyoung 	/* Acknowledge receipt and release mailbox, then we're done */
    621      1.1   dyoung 	IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_ACK);
    622      1.1   dyoung 
    623      1.1   dyoung 	/* update stats */
    624  1.6.8.7   martin 	IXGBE_EVC_ADD(&hw->mbx.stats.msgs_rx, 1);
    625      1.1   dyoung 
    626  1.6.8.6   martin 	return IXGBE_SUCCESS;
    627  1.6.8.6   martin }
    628  1.6.8.6   martin 
    629  1.6.8.6   martin /**
    630  1.6.8.6   martin  * ixgbe_read_mbx_vf - Reads a message from the inbox intended for vf
    631  1.6.8.6   martin  * @hw: pointer to the HW structure
    632  1.6.8.6   martin  * @msg: The message buffer
    633  1.6.8.6   martin  * @size: Length of buffer
    634  1.6.8.6   martin  * @mbx_id: id of mailbox to read
    635  1.6.8.6   martin  *
    636  1.6.8.6   martin  * returns SUCCESS if it successfully read message from buffer
    637  1.6.8.6   martin  **/
    638  1.6.8.6   martin static s32 ixgbe_read_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size,
    639  1.6.8.6   martin 			     u16 mbx_id)
    640  1.6.8.6   martin {
    641  1.6.8.6   martin 	u32 vf_mailbox;
    642  1.6.8.6   martin 	s32 ret_val;
    643  1.6.8.6   martin 	u16 i;
    644  1.6.8.6   martin 
    645  1.6.8.6   martin 	DEBUGFUNC("ixgbe_read_mbx_vf");
    646  1.6.8.6   martin 	UNREFERENCED_1PARAMETER(mbx_id);
    647  1.6.8.6   martin 
    648  1.6.8.6   martin 	/* check if there is a message from PF */
    649  1.6.8.6   martin 	ret_val = ixgbe_check_for_msg_vf(hw, 0);
    650  1.6.8.6   martin 	if (ret_val != IXGBE_SUCCESS)
    651  1.6.8.6   martin 		return IXGBE_ERR_MBX_NOMSG;
    652  1.6.8.6   martin 
    653  1.6.8.6   martin 	ixgbe_clear_msg_vf(hw);
    654  1.6.8.6   martin 
    655  1.6.8.6   martin 	/* copy the message from the mailbox memory buffer */
    656  1.6.8.6   martin 	for (i = 0; i < size; i++)
    657  1.6.8.6   martin 		msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_VFMBMEM, i);
    658  1.6.8.6   martin 
    659  1.6.8.6   martin 	/* Acknowledge receipt */
    660  1.6.8.6   martin 	vf_mailbox = ixgbe_read_mailbox_vf(hw);
    661  1.6.8.6   martin 	vf_mailbox |= IXGBE_VFMAILBOX_ACK;
    662  1.6.8.6   martin 	IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, vf_mailbox);
    663  1.6.8.6   martin 
    664  1.6.8.6   martin 	/* update stats */
    665  1.6.8.7   martin 	IXGBE_EVC_ADD(&hw->mbx.stats.msgs_rx, 1);
    666  1.6.8.6   martin 
    667  1.6.8.6   martin 	return IXGBE_SUCCESS;
    668      1.1   dyoung }
    669      1.1   dyoung 
    670      1.1   dyoung /**
    671  1.6.8.5   martin  * ixgbe_init_mbx_params_vf - set initial values for vf mailbox
    672  1.6.8.5   martin  * @hw: pointer to the HW structure
    673      1.1   dyoung  *
    674  1.6.8.6   martin  * Initializes single set the hw->mbx struct to correct values for vf mailbox
    675  1.6.8.6   martin  * Set of legacy functions is being used here
    676      1.1   dyoung  */
    677      1.1   dyoung void ixgbe_init_mbx_params_vf(struct ixgbe_hw *hw)
    678      1.1   dyoung {
    679      1.1   dyoung 	struct ixgbe_mbx_info *mbx = &hw->mbx;
    680      1.1   dyoung 
    681  1.6.8.6   martin 	mbx->timeout = IXGBE_VF_MBX_INIT_TIMEOUT;
    682      1.1   dyoung 	mbx->usec_delay = IXGBE_VF_MBX_INIT_DELAY;
    683      1.1   dyoung 
    684      1.1   dyoung 	mbx->size = IXGBE_VFMAILBOX_SIZE;
    685      1.1   dyoung 
    686  1.6.8.6   martin 	/* VF has only one mailbox connection, no need for more IDs */
    687  1.6.8.6   martin 	mbx->ops[0].release = ixgbe_release_mbx_lock_dummy;
    688  1.6.8.6   martin 	mbx->ops[0].read = ixgbe_read_mbx_vf_legacy;
    689  1.6.8.6   martin 	mbx->ops[0].write = ixgbe_write_mbx_vf_legacy;
    690  1.6.8.6   martin 	mbx->ops[0].check_for_msg = ixgbe_check_for_msg_vf;
    691  1.6.8.6   martin 	mbx->ops[0].check_for_ack = ixgbe_check_for_ack_vf;
    692  1.6.8.6   martin 	mbx->ops[0].check_for_rst = ixgbe_check_for_rst_vf;
    693  1.6.8.6   martin 	mbx->ops[0].clear = NULL;
    694      1.1   dyoung 
    695  1.6.8.7   martin 	IXGBE_EVC_STORE(&mbx->stats.msgs_tx, 0);
    696  1.6.8.7   martin 	IXGBE_EVC_STORE(&mbx->stats.msgs_rx, 0);
    697  1.6.8.7   martin 	IXGBE_EVC_STORE(&mbx->stats.reqs, 0);
    698  1.6.8.7   martin 	IXGBE_EVC_STORE(&mbx->stats.acks, 0);
    699  1.6.8.7   martin 	IXGBE_EVC_STORE(&mbx->stats.rsts, 0);
    700      1.1   dyoung }
    701      1.1   dyoung 
    702  1.6.8.6   martin /**
    703  1.6.8.6   martin  * ixgbe_upgrade_mbx_params_vf - set initial values for vf mailbox
    704  1.6.8.6   martin  * @hw: pointer to the HW structure
    705  1.6.8.6   martin  *
    706  1.6.8.6   martin  * Initializes the hw->mbx struct to correct values for vf mailbox
    707  1.6.8.6   martin  */
    708  1.6.8.6   martin void ixgbe_upgrade_mbx_params_vf(struct ixgbe_hw *hw)
    709  1.6.8.6   martin {
    710  1.6.8.6   martin 	struct ixgbe_mbx_info *mbx = &hw->mbx;
    711  1.6.8.6   martin 
    712  1.6.8.6   martin 	mbx->timeout = IXGBE_VF_MBX_INIT_TIMEOUT;
    713  1.6.8.6   martin 	mbx->usec_delay = IXGBE_VF_MBX_INIT_DELAY;
    714  1.6.8.6   martin 
    715  1.6.8.6   martin 	mbx->size = IXGBE_VFMAILBOX_SIZE;
    716  1.6.8.6   martin 
    717  1.6.8.6   martin 	/* VF has only one mailbox connection, no need for more IDs */
    718  1.6.8.6   martin 	mbx->ops[0].release = ixgbe_release_mbx_lock_vf;
    719  1.6.8.6   martin 	mbx->ops[0].read = ixgbe_read_mbx_vf;
    720  1.6.8.6   martin 	mbx->ops[0].write = ixgbe_write_mbx_vf;
    721  1.6.8.6   martin 	mbx->ops[0].check_for_msg = ixgbe_check_for_msg_vf;
    722  1.6.8.6   martin 	mbx->ops[0].check_for_ack = ixgbe_check_for_ack_vf;
    723  1.6.8.6   martin 	mbx->ops[0].check_for_rst = ixgbe_check_for_rst_vf;
    724  1.6.8.6   martin 	mbx->ops[0].clear = NULL;
    725  1.6.8.6   martin }
    726  1.6.8.6   martin 
    727  1.6.8.6   martin static void ixgbe_clear_msg_pf(struct ixgbe_hw *hw, u16 vf_id)
    728  1.6.8.6   martin {
    729  1.6.8.6   martin 	u32 vf_shift = IXGBE_PFMBICR_SHIFT(vf_id);
    730  1.6.8.6   martin 	s32 index = IXGBE_PFMBICR_INDEX(vf_id);
    731  1.6.8.6   martin 	u32 pfmbicr;
    732  1.6.8.6   martin 
    733  1.6.8.6   martin 	pfmbicr = IXGBE_READ_REG(hw, IXGBE_PFMBICR(index));
    734  1.6.8.6   martin 
    735  1.6.8.6   martin 	if (pfmbicr & (IXGBE_PFMBICR_VFREQ_VF1 << vf_shift))
    736  1.6.8.7   martin 		IXGBE_EVC_ADD(&hw->mbx.stats.reqs, 1);
    737  1.6.8.6   martin 
    738  1.6.8.6   martin 	IXGBE_WRITE_REG(hw, IXGBE_PFMBICR(index),
    739  1.6.8.6   martin 			IXGBE_PFMBICR_VFREQ_VF1 << vf_shift);
    740  1.6.8.6   martin }
    741  1.6.8.6   martin 
    742  1.6.8.6   martin static void ixgbe_clear_ack_pf(struct ixgbe_hw *hw, u16 vf_id)
    743  1.6.8.6   martin {
    744  1.6.8.6   martin 	u32 vf_shift = IXGBE_PFMBICR_SHIFT(vf_id);
    745  1.6.8.6   martin 	s32 index = IXGBE_PFMBICR_INDEX(vf_id);
    746  1.6.8.6   martin 	u32 pfmbicr;
    747  1.6.8.6   martin 
    748  1.6.8.6   martin 	pfmbicr = IXGBE_READ_REG(hw, IXGBE_PFMBICR(index));
    749  1.6.8.6   martin 
    750  1.6.8.6   martin 	if (pfmbicr & (IXGBE_PFMBICR_VFACK_VF1 << vf_shift))
    751  1.6.8.7   martin 		IXGBE_EVC_ADD(&hw->mbx.stats.acks, 1);
    752  1.6.8.6   martin 
    753  1.6.8.6   martin 	IXGBE_WRITE_REG(hw, IXGBE_PFMBICR(index),
    754  1.6.8.6   martin 			IXGBE_PFMBICR_VFACK_VF1 << vf_shift);
    755  1.6.8.6   martin }
    756  1.6.8.6   martin 
    757      1.1   dyoung static s32 ixgbe_check_for_bit_pf(struct ixgbe_hw *hw, u32 mask, s32 index)
    758      1.1   dyoung {
    759  1.6.8.6   martin 	u32 pfmbicr = IXGBE_READ_REG(hw, IXGBE_PFMBICR(index));
    760      1.1   dyoung 
    761  1.6.8.6   martin 	if (pfmbicr & mask)
    762  1.6.8.6   martin 		return IXGBE_SUCCESS;
    763      1.1   dyoung 
    764  1.6.8.6   martin 	return IXGBE_ERR_MBX;
    765      1.1   dyoung }
    766      1.1   dyoung 
    767      1.1   dyoung /**
    768  1.6.8.5   martin  * ixgbe_check_for_msg_pf - checks to see if the VF has sent mail
    769  1.6.8.5   martin  * @hw: pointer to the HW structure
    770  1.6.8.6   martin  * @vf_id: the VF index
    771      1.1   dyoung  *
    772  1.6.8.5   martin  * returns SUCCESS if the VF has set the Status bit or else ERR_MBX
    773      1.1   dyoung  **/
    774  1.6.8.6   martin static s32 ixgbe_check_for_msg_pf(struct ixgbe_hw *hw, u16 vf_id)
    775      1.1   dyoung {
    776  1.6.8.6   martin 	u32 vf_shift = IXGBE_PFMBICR_SHIFT(vf_id);
    777  1.6.8.6   martin 	s32 index = IXGBE_PFMBICR_INDEX(vf_id);
    778      1.1   dyoung 
    779      1.1   dyoung 	DEBUGFUNC("ixgbe_check_for_msg_pf");
    780      1.1   dyoung 
    781  1.6.8.6   martin 	if (!ixgbe_check_for_bit_pf(hw, IXGBE_PFMBICR_VFREQ_VF1 << vf_shift,
    782  1.6.8.6   martin 				    index))
    783  1.6.8.6   martin 		return IXGBE_SUCCESS;
    784      1.1   dyoung 
    785  1.6.8.6   martin 	return IXGBE_ERR_MBX;
    786      1.1   dyoung }
    787      1.1   dyoung 
    788      1.1   dyoung /**
    789  1.6.8.5   martin  * ixgbe_check_for_ack_pf - checks to see if the VF has ACKed
    790  1.6.8.5   martin  * @hw: pointer to the HW structure
    791  1.6.8.6   martin  * @vf_id: the VF index
    792      1.1   dyoung  *
    793  1.6.8.5   martin  * returns SUCCESS if the VF has set the Status bit or else ERR_MBX
    794      1.1   dyoung  **/
    795  1.6.8.6   martin static s32 ixgbe_check_for_ack_pf(struct ixgbe_hw *hw, u16 vf_id)
    796      1.1   dyoung {
    797  1.6.8.6   martin 	u32 vf_shift = IXGBE_PFMBICR_SHIFT(vf_id);
    798  1.6.8.6   martin 	s32 index = IXGBE_PFMBICR_INDEX(vf_id);
    799      1.1   dyoung 	s32 ret_val = IXGBE_ERR_MBX;
    800      1.1   dyoung 
    801      1.1   dyoung 	DEBUGFUNC("ixgbe_check_for_ack_pf");
    802      1.1   dyoung 
    803  1.6.8.6   martin 	if (!ixgbe_check_for_bit_pf(hw, IXGBE_PFMBICR_VFACK_VF1 << vf_shift,
    804      1.2  msaitoh 				    index)) {
    805      1.1   dyoung 		ret_val = IXGBE_SUCCESS;
    806  1.6.8.6   martin 		/* TODO: should this be autocleared? */
    807  1.6.8.6   martin 		ixgbe_clear_ack_pf(hw, vf_id);
    808      1.1   dyoung 	}
    809      1.1   dyoung 
    810      1.1   dyoung 	return ret_val;
    811      1.1   dyoung }
    812      1.1   dyoung 
    813      1.1   dyoung /**
    814  1.6.8.5   martin  * ixgbe_check_for_rst_pf - checks to see if the VF has reset
    815  1.6.8.5   martin  * @hw: pointer to the HW structure
    816  1.6.8.6   martin  * @vf_id: the VF index
    817      1.1   dyoung  *
    818  1.6.8.5   martin  * returns SUCCESS if the VF has set the Status bit or else ERR_MBX
    819      1.1   dyoung  **/
    820  1.6.8.6   martin static s32 ixgbe_check_for_rst_pf(struct ixgbe_hw *hw, u16 vf_id)
    821      1.1   dyoung {
    822  1.6.8.6   martin 	u32 vf_shift = IXGBE_PFVFLRE_SHIFT(vf_id);
    823  1.6.8.6   martin 	u32 index = IXGBE_PFVFLRE_INDEX(vf_id);
    824      1.1   dyoung 	s32 ret_val = IXGBE_ERR_MBX;
    825  1.6.8.6   martin 	u32 vflre = 0;
    826      1.1   dyoung 
    827      1.1   dyoung 	DEBUGFUNC("ixgbe_check_for_rst_pf");
    828      1.1   dyoung 
    829      1.1   dyoung 	switch (hw->mac.type) {
    830      1.1   dyoung 	case ixgbe_mac_82599EB:
    831  1.6.8.6   martin 		vflre = IXGBE_READ_REG(hw, IXGBE_PFVFLRE(index));
    832      1.1   dyoung 		break;
    833      1.4  msaitoh 	case ixgbe_mac_X550:
    834      1.4  msaitoh 	case ixgbe_mac_X550EM_x:
    835  1.6.8.1      snj 	case ixgbe_mac_X550EM_a:
    836      1.2  msaitoh 	case ixgbe_mac_X540:
    837  1.6.8.6   martin 		vflre = IXGBE_READ_REG(hw, IXGBE_PFVFLREC(index));
    838      1.2  msaitoh 		break;
    839      1.1   dyoung 	default:
    840      1.1   dyoung 		break;
    841      1.1   dyoung 	}
    842      1.1   dyoung 
    843      1.1   dyoung 	if (vflre & (1 << vf_shift)) {
    844      1.1   dyoung 		ret_val = IXGBE_SUCCESS;
    845  1.6.8.6   martin 		IXGBE_WRITE_REG(hw, IXGBE_PFVFLREC(index), (1 << vf_shift));
    846  1.6.8.7   martin 		IXGBE_EVC_ADD(&hw->mbx.stats.rsts, 1);
    847      1.1   dyoung 	}
    848      1.1   dyoung 
    849      1.1   dyoung 	return ret_val;
    850      1.1   dyoung }
    851      1.1   dyoung 
    852      1.1   dyoung /**
    853  1.6.8.5   martin  * ixgbe_obtain_mbx_lock_pf - obtain mailbox lock
    854  1.6.8.5   martin  * @hw: pointer to the HW structure
    855  1.6.8.6   martin  * @vf_id: the VF index
    856      1.1   dyoung  *
    857  1.6.8.5   martin  * return SUCCESS if we obtained the mailbox lock
    858      1.1   dyoung  **/
    859  1.6.8.6   martin static s32 ixgbe_obtain_mbx_lock_pf(struct ixgbe_hw *hw, u16 vf_id)
    860      1.1   dyoung {
    861  1.6.8.6   martin 	struct ixgbe_mbx_info *mbx = &hw->mbx;
    862  1.6.8.6   martin 	int countdown = mbx->timeout;
    863      1.1   dyoung 	s32 ret_val = IXGBE_ERR_MBX;
    864  1.6.8.6   martin 	u32 pf_mailbox;
    865      1.1   dyoung 
    866      1.1   dyoung 	DEBUGFUNC("ixgbe_obtain_mbx_lock_pf");
    867      1.1   dyoung 
    868  1.6.8.6   martin 	if (!mbx->timeout)
    869  1.6.8.6   martin 		return IXGBE_ERR_CONFIG;
    870      1.1   dyoung 
    871  1.6.8.6   martin 	while (countdown--) {
    872  1.6.8.6   martin 		/* Reserve mailbox for PF use */
    873  1.6.8.6   martin 		pf_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_id));
    874  1.6.8.6   martin 		pf_mailbox |= IXGBE_PFMAILBOX_PFU;
    875  1.6.8.6   martin 		IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_id), pf_mailbox);
    876  1.6.8.6   martin 
    877  1.6.8.6   martin 		/* Verify that PF is the owner of the lock */
    878  1.6.8.6   martin 		pf_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_id));
    879  1.6.8.6   martin 		if (pf_mailbox & IXGBE_PFMAILBOX_PFU) {
    880  1.6.8.6   martin 			ret_val = IXGBE_SUCCESS;
    881  1.6.8.6   martin 			break;
    882  1.6.8.6   martin 		}
    883      1.4  msaitoh 
    884  1.6.8.6   martin 		/* Wait a bit before trying again */
    885  1.6.8.6   martin 		usec_delay(mbx->usec_delay);
    886  1.6.8.6   martin 	}
    887  1.6.8.6   martin 
    888  1.6.8.6   martin 	if (ret_val != IXGBE_SUCCESS) {
    889  1.6.8.6   martin 		ERROR_REPORT1(IXGBE_ERROR_INVALID_STATE,
    890  1.6.8.6   martin 			      "Failed to obtain mailbox lock");
    891  1.6.8.6   martin 		ret_val = IXGBE_ERR_TIMEOUT;
    892  1.6.8.6   martin 	}
    893      1.1   dyoung 
    894      1.1   dyoung 	return ret_val;
    895      1.1   dyoung }
    896      1.1   dyoung 
    897      1.1   dyoung /**
    898  1.6.8.6   martin  * ixgbe_release_mbx_lock_pf - release mailbox lock
    899  1.6.8.6   martin  * @hw: pointer to the HW structure
    900  1.6.8.6   martin  * @vf_id: the VF index
    901  1.6.8.6   martin  **/
    902  1.6.8.6   martin static void ixgbe_release_mbx_lock_pf(struct ixgbe_hw *hw, u16 vf_id)
    903  1.6.8.6   martin {
    904  1.6.8.6   martin 	u32 pf_mailbox;
    905  1.6.8.6   martin 
    906  1.6.8.6   martin 	DEBUGFUNC("ixgbe_release_mbx_lock_pf");
    907  1.6.8.6   martin 
    908  1.6.8.6   martin 	/* Return ownership of the buffer */
    909  1.6.8.6   martin 	pf_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_id));
    910  1.6.8.6   martin 	pf_mailbox &= ~IXGBE_PFMAILBOX_PFU;
    911  1.6.8.6   martin 	IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_id), pf_mailbox);
    912  1.6.8.6   martin }
    913  1.6.8.6   martin 
    914  1.6.8.6   martin /**
    915  1.6.8.6   martin  * ixgbe_write_mbx_pf_legacy - Places a message in the mailbox
    916  1.6.8.6   martin  * @hw: pointer to the HW structure
    917  1.6.8.6   martin  * @msg: The message buffer
    918  1.6.8.6   martin  * @size: Length of buffer
    919  1.6.8.6   martin  * @vf_id: the VF index
    920  1.6.8.6   martin  *
    921  1.6.8.6   martin  * returns SUCCESS if it successfully copied message into the buffer
    922  1.6.8.6   martin  **/
    923  1.6.8.6   martin static s32 ixgbe_write_mbx_pf_legacy(struct ixgbe_hw *hw, u32 *msg, u16 size,
    924  1.6.8.6   martin 				     u16 vf_id)
    925  1.6.8.6   martin {
    926  1.6.8.6   martin 	s32 ret_val;
    927  1.6.8.6   martin 	u16 i;
    928  1.6.8.6   martin 
    929  1.6.8.6   martin 	DEBUGFUNC("ixgbe_write_mbx_pf_legacy");
    930  1.6.8.6   martin 
    931  1.6.8.6   martin 	/* lock the mailbox to prevent pf/vf race condition */
    932  1.6.8.6   martin 	ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_id);
    933  1.6.8.6   martin 	if (ret_val)
    934  1.6.8.6   martin 		return ret_val;
    935  1.6.8.6   martin 
    936  1.6.8.6   martin 	/* flush msg and acks as we are overwriting the message buffer */
    937  1.6.8.6   martin 	ixgbe_check_for_msg_pf(hw, vf_id);
    938  1.6.8.6   martin 	ixgbe_clear_msg_pf(hw, vf_id);
    939  1.6.8.6   martin 	ixgbe_check_for_ack_pf(hw, vf_id);
    940  1.6.8.6   martin 	ixgbe_clear_ack_pf(hw, vf_id);
    941  1.6.8.6   martin 
    942  1.6.8.6   martin 	/* copy the caller specified message to the mailbox memory buffer */
    943  1.6.8.6   martin 	for (i = 0; i < size; i++)
    944  1.6.8.6   martin 		IXGBE_WRITE_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_id), i, msg[i]);
    945  1.6.8.6   martin 
    946  1.6.8.6   martin 	/* Interrupt VF to tell it a message has been sent and release buffer*/
    947  1.6.8.6   martin 	IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_id), IXGBE_PFMAILBOX_STS);
    948  1.6.8.6   martin 
    949  1.6.8.6   martin 	/* update stats */
    950  1.6.8.7   martin 	IXGBE_EVC_ADD(&hw->mbx.stats.msgs_tx, 1);
    951  1.6.8.6   martin 
    952  1.6.8.6   martin 	return IXGBE_SUCCESS;
    953  1.6.8.6   martin }
    954  1.6.8.6   martin 
    955  1.6.8.6   martin /**
    956  1.6.8.5   martin  * ixgbe_write_mbx_pf - Places a message in the mailbox
    957  1.6.8.5   martin  * @hw: pointer to the HW structure
    958  1.6.8.5   martin  * @msg: The message buffer
    959  1.6.8.5   martin  * @size: Length of buffer
    960  1.6.8.6   martin  * @vf_id: the VF index
    961      1.1   dyoung  *
    962  1.6.8.5   martin  * returns SUCCESS if it successfully copied message into the buffer
    963      1.1   dyoung  **/
    964      1.1   dyoung static s32 ixgbe_write_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size,
    965  1.6.8.6   martin 			      u16 vf_id)
    966      1.1   dyoung {
    967  1.6.8.6   martin 	u32 pf_mailbox;
    968      1.1   dyoung 	s32 ret_val;
    969      1.1   dyoung 	u16 i;
    970      1.1   dyoung 
    971      1.1   dyoung 	DEBUGFUNC("ixgbe_write_mbx_pf");
    972      1.1   dyoung 
    973      1.1   dyoung 	/* lock the mailbox to prevent pf/vf race condition */
    974  1.6.8.6   martin 	ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_id);
    975      1.1   dyoung 	if (ret_val)
    976  1.6.8.6   martin 		goto out;
    977      1.1   dyoung 
    978      1.1   dyoung 	/* flush msg and acks as we are overwriting the message buffer */
    979  1.6.8.6   martin 	ixgbe_clear_msg_pf(hw, vf_id);
    980  1.6.8.6   martin 	ixgbe_clear_ack_pf(hw, vf_id);
    981      1.1   dyoung 
    982      1.1   dyoung 	/* copy the caller specified message to the mailbox memory buffer */
    983      1.1   dyoung 	for (i = 0; i < size; i++)
    984  1.6.8.6   martin 		IXGBE_WRITE_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_id), i, msg[i]);
    985      1.1   dyoung 
    986  1.6.8.6   martin 	/* Interrupt VF to tell it a message has been sent */
    987  1.6.8.6   martin 	pf_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_id));
    988  1.6.8.6   martin 	pf_mailbox |= IXGBE_PFMAILBOX_STS;
    989  1.6.8.6   martin 	IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_id), pf_mailbox);
    990  1.6.8.6   martin 
    991  1.6.8.6   martin 	/* if msg sent wait until we receive an ack */
    992  1.6.8.6   martin 	ixgbe_poll_for_ack(hw, vf_id);
    993      1.1   dyoung 
    994      1.1   dyoung 	/* update stats */
    995  1.6.8.7   martin 	IXGBE_EVC_ADD(&hw->mbx.stats.msgs_tx, 1);
    996      1.1   dyoung 
    997  1.6.8.6   martin out:
    998  1.6.8.6   martin 	hw->mbx.ops[vf_id].release(hw, vf_id);
    999  1.6.8.6   martin 
   1000      1.1   dyoung 	return ret_val;
   1001      1.1   dyoung 
   1002      1.1   dyoung }
   1003      1.1   dyoung 
   1004      1.1   dyoung /**
   1005  1.6.8.6   martin  * ixgbe_read_mbx_pf_legacy - Read a message from the mailbox
   1006  1.6.8.6   martin  * @hw: pointer to the HW structure
   1007  1.6.8.6   martin  * @msg: The message buffer
   1008  1.6.8.6   martin  * @size: Length of buffer
   1009  1.6.8.6   martin  * @vf_id: the VF index
   1010  1.6.8.6   martin  *
   1011  1.6.8.6   martin  * This function copies a message from the mailbox buffer to the caller's
   1012  1.6.8.6   martin  * memory buffer.  The presumption is that the caller knows that there was
   1013  1.6.8.6   martin  * a message due to a VF request so no polling for message is needed.
   1014  1.6.8.6   martin  **/
   1015  1.6.8.6   martin static s32 ixgbe_read_mbx_pf_legacy(struct ixgbe_hw *hw, u32 *msg, u16 size,
   1016  1.6.8.6   martin 				    u16 vf_id)
   1017  1.6.8.6   martin {
   1018  1.6.8.6   martin 	s32 ret_val;
   1019  1.6.8.6   martin 	u16 i;
   1020  1.6.8.6   martin 
   1021  1.6.8.6   martin 	DEBUGFUNC("ixgbe_read_mbx_pf_legacy");
   1022  1.6.8.6   martin 
   1023  1.6.8.6   martin 	/* lock the mailbox to prevent pf/vf race condition */
   1024  1.6.8.6   martin 	ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_id);
   1025  1.6.8.6   martin 	if (ret_val != IXGBE_SUCCESS)
   1026  1.6.8.6   martin 		return ret_val;
   1027  1.6.8.6   martin 
   1028  1.6.8.6   martin 	/* copy the message to the mailbox memory buffer */
   1029  1.6.8.6   martin 	for (i = 0; i < size; i++)
   1030  1.6.8.6   martin 		msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_id), i);
   1031  1.6.8.6   martin 
   1032  1.6.8.6   martin 	/* Acknowledge the message and release buffer */
   1033  1.6.8.6   martin 	IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_id), IXGBE_PFMAILBOX_ACK);
   1034  1.6.8.6   martin 
   1035  1.6.8.6   martin 	/* update stats */
   1036  1.6.8.7   martin 	IXGBE_EVC_ADD(&hw->mbx.stats.msgs_rx, 1);
   1037  1.6.8.6   martin 
   1038  1.6.8.6   martin 	return IXGBE_SUCCESS;
   1039  1.6.8.6   martin }
   1040  1.6.8.6   martin 
   1041  1.6.8.6   martin /**
   1042  1.6.8.5   martin  * ixgbe_read_mbx_pf - Read a message from the mailbox
   1043  1.6.8.5   martin  * @hw: pointer to the HW structure
   1044  1.6.8.5   martin  * @msg: The message buffer
   1045  1.6.8.5   martin  * @size: Length of buffer
   1046  1.6.8.6   martin  * @vf_id: the VF index
   1047  1.6.8.5   martin  *
   1048  1.6.8.5   martin  * This function copies a message from the mailbox buffer to the caller's
   1049  1.6.8.5   martin  * memory buffer.  The presumption is that the caller knows that there was
   1050  1.6.8.5   martin  * a message due to a VF request so no polling for message is needed.
   1051      1.1   dyoung  **/
   1052      1.1   dyoung static s32 ixgbe_read_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size,
   1053  1.6.8.6   martin 			     u16 vf_id)
   1054      1.1   dyoung {
   1055  1.6.8.6   martin 	u32 pf_mailbox;
   1056      1.1   dyoung 	s32 ret_val;
   1057      1.1   dyoung 	u16 i;
   1058      1.1   dyoung 
   1059      1.1   dyoung 	DEBUGFUNC("ixgbe_read_mbx_pf");
   1060      1.1   dyoung 
   1061  1.6.8.6   martin 	/* check if there is a message from VF */
   1062  1.6.8.6   martin 	ret_val = ixgbe_check_for_msg_pf(hw, vf_id);
   1063  1.6.8.6   martin 	if (ret_val != IXGBE_SUCCESS)
   1064  1.6.8.6   martin 		return IXGBE_ERR_MBX_NOMSG;
   1065  1.6.8.6   martin 
   1066  1.6.8.6   martin 	ixgbe_clear_msg_pf(hw, vf_id);
   1067      1.1   dyoung 
   1068      1.1   dyoung 	/* copy the message to the mailbox memory buffer */
   1069      1.1   dyoung 	for (i = 0; i < size; i++)
   1070  1.6.8.6   martin 		msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_id), i);
   1071      1.1   dyoung 
   1072      1.1   dyoung 	/* Acknowledge the message and release buffer */
   1073  1.6.8.6   martin 	pf_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_id));
   1074  1.6.8.6   martin 	pf_mailbox |= IXGBE_PFMAILBOX_ACK;
   1075  1.6.8.6   martin 	IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_id), pf_mailbox);
   1076      1.1   dyoung 
   1077      1.1   dyoung 	/* update stats */
   1078  1.6.8.7   martin 	IXGBE_EVC_ADD(&hw->mbx.stats.msgs_rx, 1);
   1079      1.1   dyoung 
   1080  1.6.8.6   martin 	return IXGBE_SUCCESS;
   1081      1.1   dyoung }
   1082      1.1   dyoung 
   1083      1.1   dyoung /**
   1084  1.6.8.5   martin  * ixgbe_clear_mbx_pf - Clear Mailbox Memory
   1085  1.6.8.5   martin  * @hw: pointer to the HW structure
   1086  1.6.8.6   martin  * @vf_id: the VF index
   1087  1.6.8.3   martin  *
   1088  1.6.8.5   martin  * Set VFMBMEM of given VF to 0x0.
   1089  1.6.8.3   martin  **/
   1090  1.6.8.6   martin static s32 ixgbe_clear_mbx_pf(struct ixgbe_hw *hw, u16 vf_id)
   1091  1.6.8.3   martin {
   1092  1.6.8.3   martin 	u16 mbx_size = hw->mbx.size;
   1093  1.6.8.3   martin 	u16 i;
   1094  1.6.8.3   martin 
   1095  1.6.8.6   martin 	if (vf_id > 63)
   1096  1.6.8.3   martin 		return IXGBE_ERR_PARAM;
   1097  1.6.8.3   martin 
   1098  1.6.8.3   martin 	for (i = 0; i < mbx_size; ++i)
   1099  1.6.8.6   martin 		IXGBE_WRITE_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_id), i, 0x0);
   1100  1.6.8.3   martin 
   1101  1.6.8.3   martin 	return IXGBE_SUCCESS;
   1102  1.6.8.3   martin }
   1103  1.6.8.3   martin 
   1104  1.6.8.3   martin /**
   1105  1.6.8.6   martin  * ixgbe_init_mbx_params_pf_id - set initial values for pf mailbox
   1106  1.6.8.6   martin  * @hw: pointer to the HW structure
   1107  1.6.8.6   martin  * @vf_id: the VF index
   1108  1.6.8.6   martin  *
   1109  1.6.8.6   martin  * Initializes single set of the hw->mbx struct to correct values for pf mailbox
   1110  1.6.8.6   martin  * Set of legacy functions is being used here
   1111  1.6.8.6   martin  */
   1112  1.6.8.6   martin void ixgbe_init_mbx_params_pf_id(struct ixgbe_hw *hw, u16 vf_id)
   1113  1.6.8.6   martin {
   1114  1.6.8.6   martin 	struct ixgbe_mbx_info *mbx = &hw->mbx;
   1115  1.6.8.6   martin 
   1116  1.6.8.6   martin 	mbx->ops[vf_id].release = ixgbe_release_mbx_lock_dummy;
   1117  1.6.8.6   martin 	mbx->ops[vf_id].read = ixgbe_read_mbx_pf_legacy;
   1118  1.6.8.6   martin 	mbx->ops[vf_id].write = ixgbe_write_mbx_pf_legacy;
   1119  1.6.8.6   martin 	mbx->ops[vf_id].check_for_msg = ixgbe_check_for_msg_pf;
   1120  1.6.8.6   martin 	mbx->ops[vf_id].check_for_ack = ixgbe_check_for_ack_pf;
   1121  1.6.8.6   martin 	mbx->ops[vf_id].check_for_rst = ixgbe_check_for_rst_pf;
   1122  1.6.8.6   martin 	mbx->ops[vf_id].clear = ixgbe_clear_mbx_pf;
   1123  1.6.8.6   martin }
   1124  1.6.8.6   martin 
   1125  1.6.8.6   martin /**
   1126  1.6.8.5   martin  * ixgbe_init_mbx_params_pf - set initial values for pf mailbox
   1127  1.6.8.5   martin  * @hw: pointer to the HW structure
   1128      1.1   dyoung  *
   1129  1.6.8.6   martin  * Initializes all sets of the hw->mbx struct to correct values for pf
   1130  1.6.8.6   martin  * mailbox. One set corresponds to single VF. It also initializes counters
   1131  1.6.8.6   martin  * and general variables. A set of legacy functions is used by default.
   1132      1.1   dyoung  */
   1133      1.1   dyoung void ixgbe_init_mbx_params_pf(struct ixgbe_hw *hw)
   1134      1.1   dyoung {
   1135  1.6.8.6   martin 	u16 i;
   1136      1.1   dyoung 	struct ixgbe_mbx_info *mbx = &hw->mbx;
   1137      1.1   dyoung 
   1138  1.6.8.6   martin 	/* Ensure we are not calling this function from VF */
   1139      1.2  msaitoh 	if (hw->mac.type != ixgbe_mac_82599EB &&
   1140      1.4  msaitoh 	    hw->mac.type != ixgbe_mac_X550 &&
   1141      1.4  msaitoh 	    hw->mac.type != ixgbe_mac_X550EM_x &&
   1142  1.6.8.1      snj 	    hw->mac.type != ixgbe_mac_X550EM_a &&
   1143      1.2  msaitoh 	    hw->mac.type != ixgbe_mac_X540)
   1144      1.1   dyoung 		return;
   1145      1.1   dyoung 
   1146  1.6.8.6   martin 	/* Initialize common mailbox settings */
   1147  1.6.8.6   martin 	mbx->timeout = IXGBE_VF_MBX_INIT_TIMEOUT;
   1148  1.6.8.6   martin 	mbx->usec_delay = IXGBE_VF_MBX_INIT_DELAY;
   1149      1.1   dyoung 	mbx->size = IXGBE_VFMAILBOX_SIZE;
   1150      1.1   dyoung 
   1151  1.6.8.6   martin 	/* Initialize counters with zeroes */
   1152  1.6.8.7   martin 	IXGBE_EVC_STORE(&mbx->stats.msgs_tx, 0);
   1153  1.6.8.7   martin 	IXGBE_EVC_STORE(&mbx->stats.msgs_rx, 0);
   1154  1.6.8.7   martin 	IXGBE_EVC_STORE(&mbx->stats.reqs, 0);
   1155  1.6.8.7   martin 	IXGBE_EVC_STORE(&mbx->stats.acks, 0);
   1156  1.6.8.7   martin 	IXGBE_EVC_STORE(&mbx->stats.rsts, 0);
   1157  1.6.8.6   martin 
   1158  1.6.8.6   martin 	/* No matter of VF number, we initialize params for all 64 VFs. */
   1159  1.6.8.6   martin 	/* TODO: 1. Add a define for max VF and refactor SHARED to get rid
   1160  1.6.8.6   martin 	 * of magic number for that (63 or 64 depending on use case.)
   1161  1.6.8.6   martin 	 * 2. rewrite the code to dynamically allocate mbx->ops[vf_id] for
   1162  1.6.8.6   martin 	 * certain number of VFs instead of default maximum value of 64 (0..63)
   1163  1.6.8.6   martin 	 */
   1164  1.6.8.6   martin 	for (i = 0; i < 64; i++)
   1165  1.6.8.6   martin 		ixgbe_init_mbx_params_pf_id(hw, i);
   1166  1.6.8.6   martin }
   1167  1.6.8.6   martin 
   1168  1.6.8.6   martin /**
   1169  1.6.8.6   martin  * ixgbe_upgrade_mbx_params_pf - Upgrade initial values for pf mailbox
   1170  1.6.8.6   martin  * @hw: pointer to the HW structure
   1171  1.6.8.6   martin  * @vf_id: the VF index
   1172  1.6.8.6   martin  *
   1173  1.6.8.6   martin  * Initializes the hw->mbx struct to new function set for improved
   1174  1.6.8.6   martin  * stability and handling of messages.
   1175  1.6.8.6   martin  */
   1176  1.6.8.6   martin void ixgbe_upgrade_mbx_params_pf(struct ixgbe_hw *hw, u16 vf_id)
   1177  1.6.8.6   martin {
   1178  1.6.8.6   martin 	struct ixgbe_mbx_info *mbx = &hw->mbx;
   1179  1.6.8.6   martin 
   1180  1.6.8.6   martin    /* Ensure we are not calling this function from VF */
   1181  1.6.8.6   martin 	if (hw->mac.type != ixgbe_mac_82599EB &&
   1182  1.6.8.6   martin 	    hw->mac.type != ixgbe_mac_X550 &&
   1183  1.6.8.6   martin 	    hw->mac.type != ixgbe_mac_X550EM_x &&
   1184  1.6.8.6   martin 	    hw->mac.type != ixgbe_mac_X550EM_a &&
   1185  1.6.8.6   martin 	    hw->mac.type != ixgbe_mac_X540)
   1186  1.6.8.6   martin 		return;
   1187  1.6.8.6   martin 
   1188  1.6.8.6   martin 	mbx->timeout = IXGBE_VF_MBX_INIT_TIMEOUT;
   1189  1.6.8.6   martin 	mbx->usec_delay = IXGBE_VF_MBX_INIT_DELAY;
   1190  1.6.8.6   martin 	mbx->size = IXGBE_VFMAILBOX_SIZE;
   1191  1.6.8.6   martin 
   1192  1.6.8.6   martin 	mbx->ops[vf_id].release = ixgbe_release_mbx_lock_pf;
   1193  1.6.8.6   martin 	mbx->ops[vf_id].read = ixgbe_read_mbx_pf;
   1194  1.6.8.6   martin 	mbx->ops[vf_id].write = ixgbe_write_mbx_pf;
   1195  1.6.8.6   martin 	mbx->ops[vf_id].check_for_msg = ixgbe_check_for_msg_pf;
   1196  1.6.8.6   martin 	mbx->ops[vf_id].check_for_ack = ixgbe_check_for_ack_pf;
   1197  1.6.8.6   martin 	mbx->ops[vf_id].check_for_rst = ixgbe_check_for_rst_pf;
   1198  1.6.8.6   martin 	mbx->ops[vf_id].clear = ixgbe_clear_mbx_pf;
   1199      1.1   dyoung }
   1200