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