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