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