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