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