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