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