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