Home | History | Annotate | Line # | Download | only in ixgbe
ixgbe_mbx.c revision 1.9
      1  1.9  msaitoh /* $NetBSD: ixgbe_mbx.c,v 1.9 2017/12/06 04:08:50 msaitoh Exp $ */
      2  1.7  msaitoh 
      3  1.1   dyoung /******************************************************************************
      4  1.9  msaitoh   SPDX-License-Identifier: BSD-3-Clause
      5  1.1   dyoung 
      6  1.7  msaitoh   Copyright (c) 2001-2017, Intel Corporation
      7  1.1   dyoung   All rights reserved.
      8  1.7  msaitoh 
      9  1.7  msaitoh   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.7  msaitoh 
     12  1.7  msaitoh    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.7  msaitoh 
     15  1.7  msaitoh    2. Redistributions in binary form must reproduce the above copyright
     16  1.7  msaitoh       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.7  msaitoh 
     19  1.7  msaitoh    3. Neither the name of the Intel Corporation nor the names of its
     20  1.7  msaitoh       contributors may be used to endorse or promote products derived from
     21  1.1   dyoung       this software without specific prior written permission.
     22  1.7  msaitoh 
     23  1.1   dyoung   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     24  1.7  msaitoh   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     25  1.7  msaitoh   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     26  1.7  msaitoh   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
     27  1.7  msaitoh   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     28  1.7  msaitoh   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     29  1.7  msaitoh   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     30  1.7  msaitoh   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     31  1.7  msaitoh   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.7  msaitoh /*$FreeBSD: head/sys/dev/ixgbe/ixgbe_mbx.c 320688 2017-07-05 17:27:03Z erj $*/
     37  1.1   dyoung 
     38  1.1   dyoung #include "ixgbe_type.h"
     39  1.1   dyoung #include "ixgbe_mbx.h"
     40  1.1   dyoung 
     41  1.1   dyoung /**
     42  1.1   dyoung  *  ixgbe_poll_for_msg - Wait for message notification
     43  1.1   dyoung  *  @hw: pointer to the HW structure
     44  1.1   dyoung  *  @mbx_id: id of mailbox to write
     45  1.1   dyoung  *
     46  1.1   dyoung  *  returns SUCCESS if it successfully received a message notification
     47  1.1   dyoung  **/
     48  1.1   dyoung static s32 ixgbe_poll_for_msg(struct ixgbe_hw *hw, u16 mbx_id)
     49  1.1   dyoung {
     50  1.1   dyoung 	struct ixgbe_mbx_info *mbx = &hw->mbx;
     51  1.1   dyoung 	int countdown = mbx->timeout;
     52  1.1   dyoung 
     53  1.1   dyoung 	DEBUGFUNC("ixgbe_poll_for_msg");
     54  1.1   dyoung 
     55  1.1   dyoung 	if (!countdown || !mbx->ops.check_for_msg)
     56  1.1   dyoung 		goto out;
     57  1.1   dyoung 
     58  1.1   dyoung 	while (countdown && mbx->ops.check_for_msg(hw, mbx_id)) {
     59  1.1   dyoung 		countdown--;
     60  1.1   dyoung 		if (!countdown)
     61  1.1   dyoung 			break;
     62  1.1   dyoung 		usec_delay(mbx->usec_delay);
     63  1.1   dyoung 	}
     64  1.1   dyoung 
     65  1.4  msaitoh 	if (countdown == 0)
     66  1.4  msaitoh 		ERROR_REPORT2(IXGBE_ERROR_POLLING,
     67  1.4  msaitoh 			   "Polling for VF%d mailbox message timedout", mbx_id);
     68  1.4  msaitoh 
     69  1.1   dyoung out:
     70  1.1   dyoung 	return countdown ? IXGBE_SUCCESS : IXGBE_ERR_MBX;
     71  1.1   dyoung }
     72  1.1   dyoung 
     73  1.1   dyoung /**
     74  1.1   dyoung  *  ixgbe_poll_for_ack - Wait for message acknowledgement
     75  1.1   dyoung  *  @hw: pointer to the HW structure
     76  1.1   dyoung  *  @mbx_id: id of mailbox to write
     77  1.1   dyoung  *
     78  1.1   dyoung  *  returns SUCCESS if it successfully received a message acknowledgement
     79  1.1   dyoung  **/
     80  1.1   dyoung static s32 ixgbe_poll_for_ack(struct ixgbe_hw *hw, u16 mbx_id)
     81  1.1   dyoung {
     82  1.1   dyoung 	struct ixgbe_mbx_info *mbx = &hw->mbx;
     83  1.1   dyoung 	int countdown = mbx->timeout;
     84  1.1   dyoung 
     85  1.1   dyoung 	DEBUGFUNC("ixgbe_poll_for_ack");
     86  1.1   dyoung 
     87  1.1   dyoung 	if (!countdown || !mbx->ops.check_for_ack)
     88  1.1   dyoung 		goto out;
     89  1.1   dyoung 
     90  1.1   dyoung 	while (countdown && mbx->ops.check_for_ack(hw, mbx_id)) {
     91  1.1   dyoung 		countdown--;
     92  1.1   dyoung 		if (!countdown)
     93  1.1   dyoung 			break;
     94  1.1   dyoung 		usec_delay(mbx->usec_delay);
     95  1.1   dyoung 	}
     96  1.1   dyoung 
     97  1.4  msaitoh 	if (countdown == 0)
     98  1.4  msaitoh 		ERROR_REPORT2(IXGBE_ERROR_POLLING,
     99  1.4  msaitoh 			     "Polling for VF%d mailbox ack timedout", mbx_id);
    100  1.4  msaitoh 
    101  1.1   dyoung out:
    102  1.1   dyoung 	return countdown ? IXGBE_SUCCESS : IXGBE_ERR_MBX;
    103  1.1   dyoung }
    104  1.1   dyoung 
    105  1.1   dyoung /**
    106  1.1   dyoung  *  ixgbe_read_posted_mbx - Wait for message notification and receive message
    107  1.1   dyoung  *  @hw: pointer to the HW structure
    108  1.1   dyoung  *  @msg: The message buffer
    109  1.1   dyoung  *  @size: Length of buffer
    110  1.1   dyoung  *  @mbx_id: id of mailbox to write
    111  1.1   dyoung  *
    112  1.1   dyoung  *  returns SUCCESS if it successfully received a message notification and
    113  1.1   dyoung  *  copied it into the receive buffer.
    114  1.1   dyoung  **/
    115  1.7  msaitoh static s32 ixgbe_read_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size,
    116  1.7  msaitoh 				 u16 mbx_id)
    117  1.1   dyoung {
    118  1.1   dyoung 	struct ixgbe_mbx_info *mbx = &hw->mbx;
    119  1.1   dyoung 	s32 ret_val = IXGBE_ERR_MBX;
    120  1.1   dyoung 
    121  1.1   dyoung 	DEBUGFUNC("ixgbe_read_posted_mbx");
    122  1.1   dyoung 
    123  1.1   dyoung 	if (!mbx->ops.read)
    124  1.1   dyoung 		goto out;
    125  1.1   dyoung 
    126  1.1   dyoung 	ret_val = ixgbe_poll_for_msg(hw, mbx_id);
    127  1.1   dyoung 
    128  1.1   dyoung 	/* if ack received read message, otherwise we timed out */
    129  1.1   dyoung 	if (!ret_val)
    130  1.1   dyoung 		ret_val = mbx->ops.read(hw, msg, size, mbx_id);
    131  1.1   dyoung out:
    132  1.1   dyoung 	return ret_val;
    133  1.1   dyoung }
    134  1.1   dyoung 
    135  1.1   dyoung /**
    136  1.1   dyoung  *  ixgbe_write_posted_mbx - Write a message to the mailbox, wait for ack
    137  1.1   dyoung  *  @hw: pointer to the HW structure
    138  1.1   dyoung  *  @msg: The message buffer
    139  1.1   dyoung  *  @size: Length of buffer
    140  1.1   dyoung  *  @mbx_id: id of mailbox to write
    141  1.1   dyoung  *
    142  1.1   dyoung  *  returns SUCCESS if it successfully copied message into the buffer and
    143  1.1   dyoung  *  received an ack to that message within delay * timeout period
    144  1.1   dyoung  **/
    145  1.7  msaitoh static s32 ixgbe_write_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size,
    146  1.7  msaitoh 				  u16 mbx_id)
    147  1.1   dyoung {
    148  1.1   dyoung 	struct ixgbe_mbx_info *mbx = &hw->mbx;
    149  1.1   dyoung 	s32 ret_val = IXGBE_ERR_MBX;
    150  1.1   dyoung 
    151  1.1   dyoung 	DEBUGFUNC("ixgbe_write_posted_mbx");
    152  1.1   dyoung 
    153  1.1   dyoung 	/* exit if either we can't write or there isn't a defined timeout */
    154  1.1   dyoung 	if (!mbx->ops.write || !mbx->timeout)
    155  1.1   dyoung 		goto out;
    156  1.1   dyoung 
    157  1.1   dyoung 	/* send msg */
    158  1.1   dyoung 	ret_val = mbx->ops.write(hw, msg, size, mbx_id);
    159  1.1   dyoung 
    160  1.1   dyoung 	/* if msg sent wait until we receive an ack */
    161  1.1   dyoung 	if (!ret_val)
    162  1.1   dyoung 		ret_val = ixgbe_poll_for_ack(hw, mbx_id);
    163  1.1   dyoung out:
    164  1.1   dyoung 	return ret_val;
    165  1.1   dyoung }
    166  1.1   dyoung 
    167  1.1   dyoung /**
    168  1.1   dyoung  *  ixgbe_init_mbx_ops_generic - Initialize MB function pointers
    169  1.1   dyoung  *  @hw: pointer to the HW structure
    170  1.1   dyoung  *
    171  1.1   dyoung  *  Setups up the mailbox read and write message function pointers
    172  1.1   dyoung  **/
    173  1.1   dyoung void ixgbe_init_mbx_ops_generic(struct ixgbe_hw *hw)
    174  1.1   dyoung {
    175  1.1   dyoung 	struct ixgbe_mbx_info *mbx = &hw->mbx;
    176  1.1   dyoung 
    177  1.1   dyoung 	mbx->ops.read_posted = ixgbe_read_posted_mbx;
    178  1.1   dyoung 	mbx->ops.write_posted = ixgbe_write_posted_mbx;
    179  1.1   dyoung }
    180  1.1   dyoung 
    181  1.1   dyoung /**
    182  1.1   dyoung  *  ixgbe_read_v2p_mailbox - read v2p mailbox
    183  1.1   dyoung  *  @hw: pointer to the HW structure
    184  1.1   dyoung  *
    185  1.1   dyoung  *  This function is used to read the v2p mailbox without losing the read to
    186  1.1   dyoung  *  clear status bits.
    187  1.1   dyoung  **/
    188  1.1   dyoung static u32 ixgbe_read_v2p_mailbox(struct ixgbe_hw *hw)
    189  1.1   dyoung {
    190  1.1   dyoung 	u32 v2p_mailbox = IXGBE_READ_REG(hw, IXGBE_VFMAILBOX);
    191  1.1   dyoung 
    192  1.1   dyoung 	v2p_mailbox |= hw->mbx.v2p_mailbox;
    193  1.1   dyoung 	hw->mbx.v2p_mailbox |= v2p_mailbox & IXGBE_VFMAILBOX_R2C_BITS;
    194  1.1   dyoung 
    195  1.1   dyoung 	return v2p_mailbox;
    196  1.1   dyoung }
    197  1.1   dyoung 
    198  1.1   dyoung /**
    199  1.1   dyoung  *  ixgbe_check_for_bit_vf - Determine if a status bit was set
    200  1.1   dyoung  *  @hw: pointer to the HW structure
    201  1.1   dyoung  *  @mask: bitmask for bits to be tested and cleared
    202  1.1   dyoung  *
    203  1.1   dyoung  *  This function is used to check for the read to clear bits within
    204  1.1   dyoung  *  the V2P mailbox.
    205  1.1   dyoung  **/
    206  1.1   dyoung static s32 ixgbe_check_for_bit_vf(struct ixgbe_hw *hw, u32 mask)
    207  1.1   dyoung {
    208  1.1   dyoung 	u32 v2p_mailbox = ixgbe_read_v2p_mailbox(hw);
    209  1.1   dyoung 	s32 ret_val = IXGBE_ERR_MBX;
    210  1.1   dyoung 
    211  1.1   dyoung 	if (v2p_mailbox & mask)
    212  1.1   dyoung 		ret_val = IXGBE_SUCCESS;
    213  1.1   dyoung 
    214  1.1   dyoung 	hw->mbx.v2p_mailbox &= ~mask;
    215  1.1   dyoung 
    216  1.1   dyoung 	return ret_val;
    217  1.1   dyoung }
    218  1.1   dyoung 
    219  1.1   dyoung /**
    220  1.1   dyoung  *  ixgbe_check_for_msg_vf - checks to see if the PF has sent mail
    221  1.1   dyoung  *  @hw: pointer to the HW structure
    222  1.1   dyoung  *  @mbx_id: id of mailbox to check
    223  1.1   dyoung  *
    224  1.1   dyoung  *  returns SUCCESS if the PF has set the Status bit or else ERR_MBX
    225  1.1   dyoung  **/
    226  1.1   dyoung static s32 ixgbe_check_for_msg_vf(struct ixgbe_hw *hw, u16 mbx_id)
    227  1.1   dyoung {
    228  1.1   dyoung 	s32 ret_val = IXGBE_ERR_MBX;
    229  1.1   dyoung 
    230  1.2  msaitoh 	UNREFERENCED_1PARAMETER(mbx_id);
    231  1.1   dyoung 	DEBUGFUNC("ixgbe_check_for_msg_vf");
    232  1.1   dyoung 
    233  1.1   dyoung 	if (!ixgbe_check_for_bit_vf(hw, IXGBE_VFMAILBOX_PFSTS)) {
    234  1.1   dyoung 		ret_val = IXGBE_SUCCESS;
    235  1.8  msaitoh 		hw->mbx.stats.reqs.ev_count++;
    236  1.1   dyoung 	}
    237  1.1   dyoung 
    238  1.1   dyoung 	return ret_val;
    239  1.1   dyoung }
    240  1.1   dyoung 
    241  1.1   dyoung /**
    242  1.1   dyoung  *  ixgbe_check_for_ack_vf - checks to see if the PF has ACK'd
    243  1.1   dyoung  *  @hw: pointer to the HW structure
    244  1.1   dyoung  *  @mbx_id: id of mailbox to check
    245  1.1   dyoung  *
    246  1.1   dyoung  *  returns SUCCESS if the PF has set the ACK bit or else ERR_MBX
    247  1.1   dyoung  **/
    248  1.1   dyoung static s32 ixgbe_check_for_ack_vf(struct ixgbe_hw *hw, u16 mbx_id)
    249  1.1   dyoung {
    250  1.1   dyoung 	s32 ret_val = IXGBE_ERR_MBX;
    251  1.1   dyoung 
    252  1.2  msaitoh 	UNREFERENCED_1PARAMETER(mbx_id);
    253  1.1   dyoung 	DEBUGFUNC("ixgbe_check_for_ack_vf");
    254  1.1   dyoung 
    255  1.1   dyoung 	if (!ixgbe_check_for_bit_vf(hw, IXGBE_VFMAILBOX_PFACK)) {
    256  1.1   dyoung 		ret_val = IXGBE_SUCCESS;
    257  1.8  msaitoh 		hw->mbx.stats.acks.ev_count++;
    258  1.1   dyoung 	}
    259  1.1   dyoung 
    260  1.1   dyoung 	return ret_val;
    261  1.1   dyoung }
    262  1.1   dyoung 
    263  1.1   dyoung /**
    264  1.1   dyoung  *  ixgbe_check_for_rst_vf - checks to see if the PF has reset
    265  1.1   dyoung  *  @hw: pointer to the HW structure
    266  1.1   dyoung  *  @mbx_id: id of mailbox to check
    267  1.1   dyoung  *
    268  1.1   dyoung  *  returns TRUE if the PF has set the reset done bit or else FALSE
    269  1.1   dyoung  **/
    270  1.1   dyoung static s32 ixgbe_check_for_rst_vf(struct ixgbe_hw *hw, u16 mbx_id)
    271  1.1   dyoung {
    272  1.1   dyoung 	s32 ret_val = IXGBE_ERR_MBX;
    273  1.1   dyoung 
    274  1.2  msaitoh 	UNREFERENCED_1PARAMETER(mbx_id);
    275  1.1   dyoung 	DEBUGFUNC("ixgbe_check_for_rst_vf");
    276  1.1   dyoung 
    277  1.1   dyoung 	if (!ixgbe_check_for_bit_vf(hw, (IXGBE_VFMAILBOX_RSTD |
    278  1.2  msaitoh 	    IXGBE_VFMAILBOX_RSTI))) {
    279  1.1   dyoung 		ret_val = IXGBE_SUCCESS;
    280  1.8  msaitoh 		hw->mbx.stats.rsts.ev_count++;
    281  1.1   dyoung 	}
    282  1.1   dyoung 
    283  1.1   dyoung 	return ret_val;
    284  1.1   dyoung }
    285  1.1   dyoung 
    286  1.1   dyoung /**
    287  1.1   dyoung  *  ixgbe_obtain_mbx_lock_vf - obtain mailbox lock
    288  1.1   dyoung  *  @hw: pointer to the HW structure
    289  1.1   dyoung  *
    290  1.1   dyoung  *  return SUCCESS if we obtained the mailbox lock
    291  1.1   dyoung  **/
    292  1.1   dyoung static s32 ixgbe_obtain_mbx_lock_vf(struct ixgbe_hw *hw)
    293  1.1   dyoung {
    294  1.1   dyoung 	s32 ret_val = IXGBE_ERR_MBX;
    295  1.1   dyoung 
    296  1.1   dyoung 	DEBUGFUNC("ixgbe_obtain_mbx_lock_vf");
    297  1.1   dyoung 
    298  1.1   dyoung 	/* Take ownership of the buffer */
    299  1.1   dyoung 	IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_VFU);
    300  1.1   dyoung 
    301  1.1   dyoung 	/* reserve mailbox for vf use */
    302  1.1   dyoung 	if (ixgbe_read_v2p_mailbox(hw) & IXGBE_VFMAILBOX_VFU)
    303  1.1   dyoung 		ret_val = IXGBE_SUCCESS;
    304  1.1   dyoung 
    305  1.1   dyoung 	return ret_val;
    306  1.1   dyoung }
    307  1.1   dyoung 
    308  1.1   dyoung /**
    309  1.1   dyoung  *  ixgbe_write_mbx_vf - Write a message to the mailbox
    310  1.1   dyoung  *  @hw: pointer to the HW structure
    311  1.1   dyoung  *  @msg: The message buffer
    312  1.1   dyoung  *  @size: Length of buffer
    313  1.1   dyoung  *  @mbx_id: id of mailbox to write
    314  1.1   dyoung  *
    315  1.1   dyoung  *  returns SUCCESS if it successfully copied message into the buffer
    316  1.1   dyoung  **/
    317  1.1   dyoung static s32 ixgbe_write_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size,
    318  1.2  msaitoh 			      u16 mbx_id)
    319  1.1   dyoung {
    320  1.1   dyoung 	s32 ret_val;
    321  1.1   dyoung 	u16 i;
    322  1.1   dyoung 
    323  1.2  msaitoh 	UNREFERENCED_1PARAMETER(mbx_id);
    324  1.1   dyoung 
    325  1.1   dyoung 	DEBUGFUNC("ixgbe_write_mbx_vf");
    326  1.1   dyoung 
    327  1.1   dyoung 	/* lock the mailbox to prevent pf/vf race condition */
    328  1.1   dyoung 	ret_val = ixgbe_obtain_mbx_lock_vf(hw);
    329  1.1   dyoung 	if (ret_val)
    330  1.1   dyoung 		goto out_no_write;
    331  1.1   dyoung 
    332  1.1   dyoung 	/* flush msg and acks as we are overwriting the message buffer */
    333  1.1   dyoung 	ixgbe_check_for_msg_vf(hw, 0);
    334  1.1   dyoung 	ixgbe_check_for_ack_vf(hw, 0);
    335  1.1   dyoung 
    336  1.1   dyoung 	/* copy the caller specified message to the mailbox memory buffer */
    337  1.1   dyoung 	for (i = 0; i < size; i++)
    338  1.1   dyoung 		IXGBE_WRITE_REG_ARRAY(hw, IXGBE_VFMBMEM, i, msg[i]);
    339  1.1   dyoung 
    340  1.1   dyoung 	/* update stats */
    341  1.8  msaitoh 	hw->mbx.stats.msgs_tx.ev_count++;
    342  1.1   dyoung 
    343  1.1   dyoung 	/* Drop VFU and interrupt the PF to tell it a message has been sent */
    344  1.1   dyoung 	IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_REQ);
    345  1.1   dyoung 
    346  1.1   dyoung out_no_write:
    347  1.1   dyoung 	return ret_val;
    348  1.1   dyoung }
    349  1.1   dyoung 
    350  1.1   dyoung /**
    351  1.1   dyoung  *  ixgbe_read_mbx_vf - Reads a message from the inbox intended for vf
    352  1.1   dyoung  *  @hw: pointer to the HW structure
    353  1.1   dyoung  *  @msg: The message buffer
    354  1.1   dyoung  *  @size: Length of buffer
    355  1.1   dyoung  *  @mbx_id: id of mailbox to read
    356  1.1   dyoung  *
    357  1.6  msaitoh  *  returns SUCCESS if it successfully read message from buffer
    358  1.1   dyoung  **/
    359  1.1   dyoung static s32 ixgbe_read_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size,
    360  1.2  msaitoh 			     u16 mbx_id)
    361  1.1   dyoung {
    362  1.1   dyoung 	s32 ret_val = IXGBE_SUCCESS;
    363  1.1   dyoung 	u16 i;
    364  1.1   dyoung 
    365  1.1   dyoung 	DEBUGFUNC("ixgbe_read_mbx_vf");
    366  1.2  msaitoh 	UNREFERENCED_1PARAMETER(mbx_id);
    367  1.1   dyoung 
    368  1.1   dyoung 	/* lock the mailbox to prevent pf/vf race condition */
    369  1.1   dyoung 	ret_val = ixgbe_obtain_mbx_lock_vf(hw);
    370  1.1   dyoung 	if (ret_val)
    371  1.1   dyoung 		goto out_no_read;
    372  1.1   dyoung 
    373  1.1   dyoung 	/* copy the message from the mailbox memory buffer */
    374  1.1   dyoung 	for (i = 0; i < size; i++)
    375  1.1   dyoung 		msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_VFMBMEM, i);
    376  1.1   dyoung 
    377  1.1   dyoung 	/* Acknowledge receipt and release mailbox, then we're done */
    378  1.1   dyoung 	IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_ACK);
    379  1.1   dyoung 
    380  1.1   dyoung 	/* update stats */
    381  1.8  msaitoh 	hw->mbx.stats.msgs_rx.ev_count++;
    382  1.1   dyoung 
    383  1.1   dyoung out_no_read:
    384  1.1   dyoung 	return ret_val;
    385  1.1   dyoung }
    386  1.1   dyoung 
    387  1.1   dyoung /**
    388  1.1   dyoung  *  ixgbe_init_mbx_params_vf - set initial values for vf mailbox
    389  1.1   dyoung  *  @hw: pointer to the HW structure
    390  1.1   dyoung  *
    391  1.1   dyoung  *  Initializes the hw->mbx struct to correct values for vf mailbox
    392  1.1   dyoung  */
    393  1.1   dyoung void ixgbe_init_mbx_params_vf(struct ixgbe_hw *hw)
    394  1.1   dyoung {
    395  1.1   dyoung 	struct ixgbe_mbx_info *mbx = &hw->mbx;
    396  1.1   dyoung 
    397  1.1   dyoung 	/* start mailbox as timed out and let the reset_hw call set the timeout
    398  1.1   dyoung 	 * value to begin communications */
    399  1.1   dyoung 	mbx->timeout = 0;
    400  1.1   dyoung 	mbx->usec_delay = IXGBE_VF_MBX_INIT_DELAY;
    401  1.1   dyoung 
    402  1.1   dyoung 	mbx->size = IXGBE_VFMAILBOX_SIZE;
    403  1.1   dyoung 
    404  1.1   dyoung 	mbx->ops.read = ixgbe_read_mbx_vf;
    405  1.1   dyoung 	mbx->ops.write = ixgbe_write_mbx_vf;
    406  1.1   dyoung 	mbx->ops.read_posted = ixgbe_read_posted_mbx;
    407  1.1   dyoung 	mbx->ops.write_posted = ixgbe_write_posted_mbx;
    408  1.1   dyoung 	mbx->ops.check_for_msg = ixgbe_check_for_msg_vf;
    409  1.1   dyoung 	mbx->ops.check_for_ack = ixgbe_check_for_ack_vf;
    410  1.1   dyoung 	mbx->ops.check_for_rst = ixgbe_check_for_rst_vf;
    411  1.1   dyoung 
    412  1.8  msaitoh 	mbx->stats.msgs_tx.ev_count = 0;
    413  1.8  msaitoh 	mbx->stats.msgs_rx.ev_count = 0;
    414  1.8  msaitoh 	mbx->stats.reqs.ev_count = 0;
    415  1.8  msaitoh 	mbx->stats.acks.ev_count = 0;
    416  1.8  msaitoh 	mbx->stats.rsts.ev_count = 0;
    417  1.1   dyoung }
    418  1.1   dyoung 
    419  1.1   dyoung static s32 ixgbe_check_for_bit_pf(struct ixgbe_hw *hw, u32 mask, s32 index)
    420  1.1   dyoung {
    421  1.1   dyoung 	u32 mbvficr = IXGBE_READ_REG(hw, IXGBE_MBVFICR(index));
    422  1.1   dyoung 	s32 ret_val = IXGBE_ERR_MBX;
    423  1.1   dyoung 
    424  1.1   dyoung 	if (mbvficr & mask) {
    425  1.1   dyoung 		ret_val = IXGBE_SUCCESS;
    426  1.1   dyoung 		IXGBE_WRITE_REG(hw, IXGBE_MBVFICR(index), mask);
    427  1.1   dyoung 	}
    428  1.1   dyoung 
    429  1.1   dyoung 	return ret_val;
    430  1.1   dyoung }
    431  1.1   dyoung 
    432  1.1   dyoung /**
    433  1.1   dyoung  *  ixgbe_check_for_msg_pf - checks to see if the VF has sent mail
    434  1.1   dyoung  *  @hw: pointer to the HW structure
    435  1.1   dyoung  *  @vf_number: the VF index
    436  1.1   dyoung  *
    437  1.1   dyoung  *  returns SUCCESS if the VF has set the Status bit or else ERR_MBX
    438  1.1   dyoung  **/
    439  1.1   dyoung static s32 ixgbe_check_for_msg_pf(struct ixgbe_hw *hw, u16 vf_number)
    440  1.1   dyoung {
    441  1.1   dyoung 	s32 ret_val = IXGBE_ERR_MBX;
    442  1.1   dyoung 	s32 index = IXGBE_MBVFICR_INDEX(vf_number);
    443  1.1   dyoung 	u32 vf_bit = vf_number % 16;
    444  1.1   dyoung 
    445  1.1   dyoung 	DEBUGFUNC("ixgbe_check_for_msg_pf");
    446  1.1   dyoung 
    447  1.1   dyoung 	if (!ixgbe_check_for_bit_pf(hw, IXGBE_MBVFICR_VFREQ_VF1 << vf_bit,
    448  1.2  msaitoh 				    index)) {
    449  1.1   dyoung 		ret_val = IXGBE_SUCCESS;
    450  1.8  msaitoh 		hw->mbx.stats.reqs.ev_count++;
    451  1.1   dyoung 	}
    452  1.1   dyoung 
    453  1.1   dyoung 	return ret_val;
    454  1.1   dyoung }
    455  1.1   dyoung 
    456  1.1   dyoung /**
    457  1.1   dyoung  *  ixgbe_check_for_ack_pf - checks to see if the VF has ACKed
    458  1.1   dyoung  *  @hw: pointer to the HW structure
    459  1.1   dyoung  *  @vf_number: the VF index
    460  1.1   dyoung  *
    461  1.1   dyoung  *  returns SUCCESS if the VF has set the Status bit or else ERR_MBX
    462  1.1   dyoung  **/
    463  1.1   dyoung static s32 ixgbe_check_for_ack_pf(struct ixgbe_hw *hw, u16 vf_number)
    464  1.1   dyoung {
    465  1.1   dyoung 	s32 ret_val = IXGBE_ERR_MBX;
    466  1.1   dyoung 	s32 index = IXGBE_MBVFICR_INDEX(vf_number);
    467  1.1   dyoung 	u32 vf_bit = vf_number % 16;
    468  1.1   dyoung 
    469  1.1   dyoung 	DEBUGFUNC("ixgbe_check_for_ack_pf");
    470  1.1   dyoung 
    471  1.1   dyoung 	if (!ixgbe_check_for_bit_pf(hw, IXGBE_MBVFICR_VFACK_VF1 << vf_bit,
    472  1.2  msaitoh 				    index)) {
    473  1.1   dyoung 		ret_val = IXGBE_SUCCESS;
    474  1.8  msaitoh 		hw->mbx.stats.acks.ev_count++;
    475  1.1   dyoung 	}
    476  1.1   dyoung 
    477  1.1   dyoung 	return ret_val;
    478  1.1   dyoung }
    479  1.1   dyoung 
    480  1.1   dyoung /**
    481  1.1   dyoung  *  ixgbe_check_for_rst_pf - checks to see if the VF has reset
    482  1.1   dyoung  *  @hw: pointer to the HW structure
    483  1.1   dyoung  *  @vf_number: the VF index
    484  1.1   dyoung  *
    485  1.1   dyoung  *  returns SUCCESS if the VF has set the Status bit or else ERR_MBX
    486  1.1   dyoung  **/
    487  1.1   dyoung static s32 ixgbe_check_for_rst_pf(struct ixgbe_hw *hw, u16 vf_number)
    488  1.1   dyoung {
    489  1.1   dyoung 	u32 reg_offset = (vf_number < 32) ? 0 : 1;
    490  1.1   dyoung 	u32 vf_shift = vf_number % 32;
    491  1.1   dyoung 	u32 vflre = 0;
    492  1.1   dyoung 	s32 ret_val = IXGBE_ERR_MBX;
    493  1.1   dyoung 
    494  1.1   dyoung 	DEBUGFUNC("ixgbe_check_for_rst_pf");
    495  1.1   dyoung 
    496  1.1   dyoung 	switch (hw->mac.type) {
    497  1.1   dyoung 	case ixgbe_mac_82599EB:
    498  1.1   dyoung 		vflre = IXGBE_READ_REG(hw, IXGBE_VFLRE(reg_offset));
    499  1.1   dyoung 		break;
    500  1.4  msaitoh 	case ixgbe_mac_X550:
    501  1.4  msaitoh 	case ixgbe_mac_X550EM_x:
    502  1.7  msaitoh 	case ixgbe_mac_X550EM_a:
    503  1.2  msaitoh 	case ixgbe_mac_X540:
    504  1.2  msaitoh 		vflre = IXGBE_READ_REG(hw, IXGBE_VFLREC(reg_offset));
    505  1.2  msaitoh 		break;
    506  1.1   dyoung 	default:
    507  1.1   dyoung 		break;
    508  1.1   dyoung 	}
    509  1.1   dyoung 
    510  1.1   dyoung 	if (vflre & (1 << vf_shift)) {
    511  1.1   dyoung 		ret_val = IXGBE_SUCCESS;
    512  1.1   dyoung 		IXGBE_WRITE_REG(hw, IXGBE_VFLREC(reg_offset), (1 << vf_shift));
    513  1.8  msaitoh 		hw->mbx.stats.rsts.ev_count++;
    514  1.1   dyoung 	}
    515  1.1   dyoung 
    516  1.1   dyoung 	return ret_val;
    517  1.1   dyoung }
    518  1.1   dyoung 
    519  1.1   dyoung /**
    520  1.1   dyoung  *  ixgbe_obtain_mbx_lock_pf - obtain mailbox lock
    521  1.1   dyoung  *  @hw: pointer to the HW structure
    522  1.1   dyoung  *  @vf_number: the VF index
    523  1.1   dyoung  *
    524  1.1   dyoung  *  return SUCCESS if we obtained the mailbox lock
    525  1.1   dyoung  **/
    526  1.1   dyoung static s32 ixgbe_obtain_mbx_lock_pf(struct ixgbe_hw *hw, u16 vf_number)
    527  1.1   dyoung {
    528  1.1   dyoung 	s32 ret_val = IXGBE_ERR_MBX;
    529  1.1   dyoung 	u32 p2v_mailbox;
    530  1.1   dyoung 
    531  1.1   dyoung 	DEBUGFUNC("ixgbe_obtain_mbx_lock_pf");
    532  1.1   dyoung 
    533  1.1   dyoung 	/* Take ownership of the buffer */
    534  1.1   dyoung 	IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_PFU);
    535  1.1   dyoung 
    536  1.1   dyoung 	/* reserve mailbox for vf use */
    537  1.1   dyoung 	p2v_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_number));
    538  1.1   dyoung 	if (p2v_mailbox & IXGBE_PFMAILBOX_PFU)
    539  1.1   dyoung 		ret_val = IXGBE_SUCCESS;
    540  1.4  msaitoh 	else
    541  1.4  msaitoh 		ERROR_REPORT2(IXGBE_ERROR_POLLING,
    542  1.4  msaitoh 			   "Failed to obtain mailbox lock for VF%d", vf_number);
    543  1.4  msaitoh 
    544  1.1   dyoung 
    545  1.1   dyoung 	return ret_val;
    546  1.1   dyoung }
    547  1.1   dyoung 
    548  1.1   dyoung /**
    549  1.1   dyoung  *  ixgbe_write_mbx_pf - Places a message in the mailbox
    550  1.1   dyoung  *  @hw: pointer to the HW structure
    551  1.1   dyoung  *  @msg: The message buffer
    552  1.1   dyoung  *  @size: Length of buffer
    553  1.1   dyoung  *  @vf_number: the VF index
    554  1.1   dyoung  *
    555  1.1   dyoung  *  returns SUCCESS if it successfully copied message into the buffer
    556  1.1   dyoung  **/
    557  1.1   dyoung static s32 ixgbe_write_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size,
    558  1.2  msaitoh 			      u16 vf_number)
    559  1.1   dyoung {
    560  1.1   dyoung 	s32 ret_val;
    561  1.1   dyoung 	u16 i;
    562  1.1   dyoung 
    563  1.1   dyoung 	DEBUGFUNC("ixgbe_write_mbx_pf");
    564  1.1   dyoung 
    565  1.1   dyoung 	/* lock the mailbox to prevent pf/vf race condition */
    566  1.1   dyoung 	ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_number);
    567  1.1   dyoung 	if (ret_val)
    568  1.1   dyoung 		goto out_no_write;
    569  1.1   dyoung 
    570  1.1   dyoung 	/* flush msg and acks as we are overwriting the message buffer */
    571  1.1   dyoung 	ixgbe_check_for_msg_pf(hw, vf_number);
    572  1.1   dyoung 	ixgbe_check_for_ack_pf(hw, vf_number);
    573  1.1   dyoung 
    574  1.1   dyoung 	/* copy the caller specified message to the mailbox memory buffer */
    575  1.1   dyoung 	for (i = 0; i < size; i++)
    576  1.1   dyoung 		IXGBE_WRITE_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_number), i, msg[i]);
    577  1.1   dyoung 
    578  1.1   dyoung 	/* Interrupt VF to tell it a message has been sent and release buffer*/
    579  1.1   dyoung 	IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_STS);
    580  1.1   dyoung 
    581  1.1   dyoung 	/* update stats */
    582  1.8  msaitoh 	hw->mbx.stats.msgs_tx.ev_count++;
    583  1.1   dyoung 
    584  1.1   dyoung out_no_write:
    585  1.1   dyoung 	return ret_val;
    586  1.1   dyoung 
    587  1.1   dyoung }
    588  1.1   dyoung 
    589  1.1   dyoung /**
    590  1.1   dyoung  *  ixgbe_read_mbx_pf - Read a message from the mailbox
    591  1.1   dyoung  *  @hw: pointer to the HW structure
    592  1.1   dyoung  *  @msg: The message buffer
    593  1.1   dyoung  *  @size: Length of buffer
    594  1.1   dyoung  *  @vf_number: the VF index
    595  1.1   dyoung  *
    596  1.1   dyoung  *  This function copies a message from the mailbox buffer to the caller's
    597  1.1   dyoung  *  memory buffer.  The presumption is that the caller knows that there was
    598  1.1   dyoung  *  a message due to a VF request so no polling for message is needed.
    599  1.1   dyoung  **/
    600  1.1   dyoung static s32 ixgbe_read_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size,
    601  1.2  msaitoh 			     u16 vf_number)
    602  1.1   dyoung {
    603  1.1   dyoung 	s32 ret_val;
    604  1.1   dyoung 	u16 i;
    605  1.1   dyoung 
    606  1.1   dyoung 	DEBUGFUNC("ixgbe_read_mbx_pf");
    607  1.1   dyoung 
    608  1.1   dyoung 	/* lock the mailbox to prevent pf/vf race condition */
    609  1.1   dyoung 	ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_number);
    610  1.1   dyoung 	if (ret_val)
    611  1.1   dyoung 		goto out_no_read;
    612  1.1   dyoung 
    613  1.1   dyoung 	/* copy the message to the mailbox memory buffer */
    614  1.1   dyoung 	for (i = 0; i < size; i++)
    615  1.1   dyoung 		msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_number), i);
    616  1.1   dyoung 
    617  1.1   dyoung 	/* Acknowledge the message and release buffer */
    618  1.1   dyoung 	IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_ACK);
    619  1.1   dyoung 
    620  1.1   dyoung 	/* update stats */
    621  1.8  msaitoh 	hw->mbx.stats.msgs_rx.ev_count++;
    622  1.1   dyoung 
    623  1.1   dyoung out_no_read:
    624  1.1   dyoung 	return ret_val;
    625  1.1   dyoung }
    626  1.1   dyoung 
    627  1.1   dyoung /**
    628  1.1   dyoung  *  ixgbe_init_mbx_params_pf - set initial values for pf mailbox
    629  1.1   dyoung  *  @hw: pointer to the HW structure
    630  1.1   dyoung  *
    631  1.1   dyoung  *  Initializes the hw->mbx struct to correct values for pf mailbox
    632  1.1   dyoung  */
    633  1.1   dyoung void ixgbe_init_mbx_params_pf(struct ixgbe_hw *hw)
    634  1.1   dyoung {
    635  1.1   dyoung 	struct ixgbe_mbx_info *mbx = &hw->mbx;
    636  1.1   dyoung 
    637  1.2  msaitoh 	if (hw->mac.type != ixgbe_mac_82599EB &&
    638  1.4  msaitoh 	    hw->mac.type != ixgbe_mac_X550 &&
    639  1.4  msaitoh 	    hw->mac.type != ixgbe_mac_X550EM_x &&
    640  1.7  msaitoh 	    hw->mac.type != ixgbe_mac_X550EM_a &&
    641  1.2  msaitoh 	    hw->mac.type != ixgbe_mac_X540)
    642  1.1   dyoung 		return;
    643  1.1   dyoung 
    644  1.1   dyoung 	mbx->timeout = 0;
    645  1.1   dyoung 	mbx->usec_delay = 0;
    646  1.1   dyoung 
    647  1.1   dyoung 	mbx->size = IXGBE_VFMAILBOX_SIZE;
    648  1.1   dyoung 
    649  1.1   dyoung 	mbx->ops.read = ixgbe_read_mbx_pf;
    650  1.1   dyoung 	mbx->ops.write = ixgbe_write_mbx_pf;
    651  1.1   dyoung 	mbx->ops.read_posted = ixgbe_read_posted_mbx;
    652  1.1   dyoung 	mbx->ops.write_posted = ixgbe_write_posted_mbx;
    653  1.1   dyoung 	mbx->ops.check_for_msg = ixgbe_check_for_msg_pf;
    654  1.1   dyoung 	mbx->ops.check_for_ack = ixgbe_check_for_ack_pf;
    655  1.1   dyoung 	mbx->ops.check_for_rst = ixgbe_check_for_rst_pf;
    656  1.1   dyoung 
    657  1.8  msaitoh 	mbx->stats.msgs_tx.ev_count = 0;
    658  1.8  msaitoh 	mbx->stats.msgs_rx.ev_count = 0;
    659  1.8  msaitoh 	mbx->stats.reqs.ev_count = 0;
    660  1.8  msaitoh 	mbx->stats.acks.ev_count = 0;
    661  1.8  msaitoh 	mbx->stats.rsts.ev_count = 0;
    662  1.1   dyoung }
    663